1 /****************************************************************************** 2 * 3 * Copyright (C) 2000-2012 Broadcom Corporation 4 * 5 * Licensed under the Apache License, Version 2.0 (the "License"); 6 * you may not use this file except in compliance with the License. 7 * You may obtain a copy of the License at: 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 * 17 ******************************************************************************/ 18 19 /****************************************************************************** 20 * 21 * This file contains functions that handle SCO connections. This includes 22 * operations such as connect, disconnect, change supported packet types. 23 * 24 ******************************************************************************/ 25 26 #include <string.h> 27 #include "bt_types.h" 28 #include "bt_target.h" 29 #include "gki.h" 30 #include "bt_types.h" 31 #include "hcimsgs.h" 32 #include "btu.h" 33 #include "btm_api.h" 34 #include "btm_int.h" 35 #include "hcidefs.h" 36 37 #if BTM_SCO_INCLUDED == TRUE 38 39 /********************************************************************************/ 40 /* L O C A L D A T A D E F I N I T I O N S */ 41 /********************************************************************************/ 42 43 #define SCO_ST_UNUSED 0 44 #define SCO_ST_LISTENING 1 45 #define SCO_ST_W4_CONN_RSP 2 46 #define SCO_ST_CONNECTING 3 47 #define SCO_ST_CONNECTED 4 48 #define SCO_ST_DISCONNECTING 5 49 #define SCO_ST_PEND_UNPARK 6 50 #define SCO_ST_PEND_ROLECHANGE 7 51 52 /********************************************************************************/ 53 /* L O C A L F U N C T I O N P R O T O T Y P E S */ 54 /********************************************************************************/ 55 56 static const tBTM_ESCO_PARAMS btm_esco_defaults = 57 { 58 BTM_64KBITS_RATE, /* TX Bandwidth (64 kbits/sec) */ 59 BTM_64KBITS_RATE, /* RX Bandwidth (64 kbits/sec) */ 60 0x000a, /* 10 ms (HS/HF can use EV3, 2-EV3, 3-EV3) */ 61 0x0060, /* Inp Linear, Air CVSD, 2s Comp, 16bit */ 62 (BTM_SCO_PKT_TYPES_MASK_HV1 + /* Packet Types */ 63 BTM_SCO_PKT_TYPES_MASK_HV2 + 64 BTM_SCO_PKT_TYPES_MASK_HV3 + 65 BTM_SCO_PKT_TYPES_MASK_EV3 + 66 BTM_SCO_PKT_TYPES_MASK_EV4 + 67 BTM_SCO_PKT_TYPES_MASK_EV5), 68 BTM_ESCO_RETRANS_POWER /* Retransmission Effort (Power) */ 69 }; 70 71 /******************************************************************************* 72 ** 73 ** Function btm_sco_flush_sco_data 74 ** 75 ** Description This function is called to flush the SCO data for this channel. 76 ** 77 ** Returns void 78 ** 79 *******************************************************************************/ 80 void btm_sco_flush_sco_data(UINT16 sco_inx) 81 { 82 #if BTM_SCO_HCI_INCLUDED == TRUE 83 #if (BTM_MAX_SCO_LINKS>0) 84 tSCO_CONN *p ; 85 BT_HDR *p_buf; 86 87 if (sco_inx < BTM_MAX_SCO_LINKS) 88 { 89 p = &btm_cb.sco_cb.sco_db[sco_inx]; 90 while (p->xmit_data_q.p_first) 91 { 92 if ((p_buf = (BT_HDR *)GKI_dequeue (&p->xmit_data_q)) != NULL) 93 GKI_freebuf (p_buf); 94 } 95 } 96 #endif 97 #endif 98 } 99 /******************************************************************************* 100 ** 101 ** Function btm_sco_init 102 ** 103 ** Description This function is called at BTM startup to initialize 104 ** 105 ** Returns void 106 ** 107 *******************************************************************************/ 108 void btm_sco_init (void) 109 { 110 #if 0 /* cleared in btm_init; put back in if called from anywhere else! */ 111 memset (&btm_cb.sco_cb, 0, sizeof(tSCO_CB)); 112 #endif 113 /* Initialize nonzero defaults */ 114 btm_cb.sco_cb.sco_disc_reason = BTM_INVALID_SCO_DISC_REASON; 115 116 btm_cb.sco_cb.def_esco_parms = btm_esco_defaults; /* Initialize with defaults */ 117 btm_cb.sco_cb.desired_sco_mode = BTM_DEFAULT_SCO_MODE; 118 } 119 120 /******************************************************************************* 121 ** 122 ** Function btm_esco_conn_rsp 123 ** 124 ** Description This function is called upon receipt of an (e)SCO connection 125 ** request event (BTM_ESCO_CONN_REQ_EVT) to accept or reject 126 ** the request. Parameters used to negotiate eSCO links. 127 ** If p_parms is NULL, then default values are used. 128 ** If the link type of the incoming request is SCO, then only 129 ** the tx_bw, max_latency, content format, and packet_types are 130 ** valid. The hci_status parameter should be 131 ** ([0x0] to accept, [0x0d..0x0f] to reject) 132 ** 133 ** Returns void 134 ** 135 *******************************************************************************/ 136 static void btm_esco_conn_rsp (UINT16 sco_inx, UINT8 hci_status, BD_ADDR bda, 137 tBTM_ESCO_PARAMS *p_parms) 138 { 139 #if (BTM_MAX_SCO_LINKS>0) 140 tSCO_CONN *p_sco = NULL; 141 tBTM_ESCO_PARAMS *p_setup; 142 UINT16 temp_pkt_types; 143 144 if (sco_inx < BTM_MAX_SCO_LINKS) 145 p_sco = &btm_cb.sco_cb.sco_db[sco_inx]; 146 147 /* Reject the connect request if refused by caller or wrong state */ 148 if (hci_status != HCI_SUCCESS || p_sco == NULL) 149 { 150 if (p_sco) 151 { 152 p_sco->state = (p_sco->state == SCO_ST_W4_CONN_RSP) ? SCO_ST_LISTENING 153 : SCO_ST_UNUSED; 154 } 155 156 if (!btm_cb.sco_cb.esco_supported) 157 { 158 if (!btsnd_hcic_reject_conn (bda, hci_status)) 159 { 160 BTM_TRACE_ERROR0("Could not reject (e)SCO conn: No Buffer!!!"); 161 } 162 } 163 else 164 { 165 if (!btsnd_hcic_reject_esco_conn (bda, hci_status)) 166 { 167 BTM_TRACE_ERROR0("Could not reject (e)SCO conn: No Buffer!!!"); 168 } 169 } 170 } 171 else /* Connection is being accepted */ 172 { 173 p_sco->state = SCO_ST_CONNECTING; 174 if (btm_cb.devcb.local_version.hci_version >= HCI_PROTO_VERSION_1_2) 175 { 176 p_setup = &p_sco->esco.setup; 177 /* If parameters not specified use the default */ 178 if (p_parms) 179 *p_setup = *p_parms; 180 else /* Use the last setup passed thru BTM_SetEscoMode (or defaults) */ 181 { 182 *p_setup = btm_cb.sco_cb.def_esco_parms; 183 } 184 185 temp_pkt_types = (p_setup->packet_types & 186 BTM_SCO_SUPPORTED_PKTS_MASK & 187 btm_cb.btm_sco_pkt_types_supported); 188 189 /* Make sure at least one eSCO packet type is sent, else might confuse peer */ 190 /* Taking this out to confirm with BQB tests 191 ** Real application would like to include this though, as many devices 192 ** do not retry with SCO only if an eSCO connection fails. 193 if (!(temp_pkt_types & BTM_ESCO_LINK_ONLY_MASK)) 194 { 195 temp_pkt_types |= BTM_SCO_PKT_TYPES_MASK_EV3; 196 } 197 */ 198 /* If SCO request, remove eSCO packet types (conformance) */ 199 if (p_sco->esco.data.link_type == BTM_LINK_TYPE_SCO) 200 { 201 temp_pkt_types &= BTM_SCO_LINK_ONLY_MASK; 202 203 if (btm_cb.devcb.local_version.hci_version >= HCI_PROTO_VERSION_2_0) 204 { 205 temp_pkt_types |= BTM_SCO_EXCEPTION_PKTS_MASK; 206 } 207 } 208 /* OR in any exception packet types if at least 2.0 version of spec */ 209 else if (btm_cb.devcb.local_version.hci_version >= HCI_PROTO_VERSION_2_0) 210 { 211 temp_pkt_types |= ((p_setup->packet_types & BTM_SCO_EXCEPTION_PKTS_MASK) | 212 (btm_cb.btm_sco_pkt_types_supported & BTM_SCO_EXCEPTION_PKTS_MASK)); 213 } 214 215 if (btsnd_hcic_accept_esco_conn (bda, p_setup->tx_bw, p_setup->rx_bw, 216 p_setup->max_latency, p_setup->voice_contfmt, 217 p_setup->retrans_effort, temp_pkt_types)) 218 { 219 p_setup->packet_types = temp_pkt_types; 220 } 221 else 222 { 223 BTM_TRACE_ERROR0("Could not accept SCO conn: No Buffer!!!"); 224 } 225 } 226 else /* Controller is version 1.1 or earlier */ 227 { 228 btsnd_hcic_accept_conn (bda, 0); 229 } 230 } 231 #endif 232 } 233 234 235 #if BTM_SCO_HCI_INCLUDED == TRUE 236 /******************************************************************************* 237 ** 238 ** Function btm_sco_check_send_pkts 239 ** 240 ** Description This function is called to check if it can send packets 241 ** to the Host Controller. 242 ** 243 ** Returns void 244 ** 245 *******************************************************************************/ 246 void btm_sco_check_send_pkts (UINT16 sco_inx) 247 { 248 BT_HDR *p_buf; 249 tSCO_CB *p_cb = &btm_cb.sco_cb; 250 tSCO_CONN *p_ccb = &p_cb->sco_db[sco_inx]; 251 252 /* If there is data to send, send it now */ 253 while (p_ccb->xmit_data_q.p_first != NULL) 254 { 255 p_buf = NULL; 256 257 #if BTM_SCO_HCI_DEBUG 258 BTM_TRACE_DEBUG1 ("btm: [%d] buf in xmit_data_q", p_ccb->xmit_data_q.count ); 259 #endif 260 p_buf = (BT_HDR *)GKI_dequeue (&p_ccb->xmit_data_q); 261 262 HCI_SCO_DATA_TO_LOWER (p_buf); 263 } 264 } 265 #endif /* BTM_SCO_HCI_INCLUDED == TRUE */ 266 267 /******************************************************************************* 268 ** 269 ** Function btm_route_sco_data 270 ** 271 ** Description Route received SCO data. 272 ** 273 ** Returns void 274 ** 275 *******************************************************************************/ 276 void btm_route_sco_data(BT_HDR *p_msg) 277 { 278 #if BTM_SCO_HCI_INCLUDED == TRUE 279 UINT16 sco_inx, handle; 280 UINT8 *p = (UINT8 *)(p_msg + 1) + p_msg->offset; 281 UINT8 pkt_size = 0; 282 UINT8 pkt_status = 0; 283 284 /* Extract Packet_Status_Flag and handle */ 285 STREAM_TO_UINT16 (handle, p); 286 pkt_status = HCID_GET_EVENT(handle); 287 handle = HCID_GET_HANDLE (handle); 288 289 STREAM_TO_UINT8 (pkt_size, p); 290 291 if ((sco_inx = btm_find_scb_by_handle(handle)) != BTM_MAX_SCO_LINKS ) 292 { 293 /* send data callback */ 294 if (!btm_cb.sco_cb.p_data_cb ) 295 /* if no data callback registered, just free the buffer */ 296 GKI_freebuf (p_msg); 297 else 298 { 299 (*btm_cb.sco_cb.p_data_cb)(sco_inx, p_msg, (tBTM_SCO_DATA_FLAG) pkt_status); 300 } 301 } 302 else /* no mapping handle SCO connection is active, free the buffer */ 303 { 304 GKI_freebuf (p_msg); 305 } 306 #else 307 GKI_freebuf(p_msg); 308 #endif 309 } 310 311 312 313 /******************************************************************************* 314 ** 315 ** Function BTM_WriteScoData 316 ** 317 ** Description This function write SCO data to a specified instance. The data 318 ** to be written p_buf needs to carry an offset of 319 ** HCI_SCO_PREAMBLE_SIZE bytes, and the data length can not 320 ** exceed BTM_SCO_DATA_SIZE_MAX bytes, whose default value is set 321 ** to 60 and is configurable. Data longer than the maximum bytes 322 ** will be truncated. 323 ** 324 ** Returns BTM_SUCCESS: data write is successful 325 ** BTM_ILLEGAL_VALUE: SCO data contains illegal offset value. 326 ** BTM_SCO_BAD_LENGTH: SCO data length exceeds the max SCO packet 327 ** size. 328 ** BTM_NO_RESOURCES: no resources. 329 ** BTM_UNKNOWN_ADDR: unknown SCO connection handle, or SCO is not 330 ** routed via HCI. 331 ** 332 ** 333 *******************************************************************************/ 334 tBTM_STATUS BTM_WriteScoData (UINT16 sco_inx, BT_HDR *p_buf) 335 { 336 #if (BTM_SCO_HCI_INCLUDED == TRUE) && (BTM_MAX_SCO_LINKS>0) 337 tSCO_CONN *p_ccb = &btm_cb.sco_cb.sco_db[sco_inx]; 338 UINT8 *p; 339 tBTM_STATUS status = BTM_SUCCESS; 340 341 if (sco_inx < BTM_MAX_SCO_LINKS && btm_cb.sco_cb.p_data_cb && 342 p_ccb->state == SCO_ST_CONNECTED) 343 { 344 /* Ensure we have enough space in the buffer for the SCO and HCI headers */ 345 if (p_buf->offset < HCI_SCO_PREAMBLE_SIZE) 346 { 347 BTM_TRACE_ERROR1 ("BTM SCO - cannot send buffer, offset: %d", p_buf->offset); 348 GKI_freebuf (p_buf); 349 status = BTM_ILLEGAL_VALUE; 350 } 351 else /* write HCI header */ 352 { 353 /* Step back 3 bytes to add the headers */ 354 p_buf->offset -= HCI_SCO_PREAMBLE_SIZE; 355 /* Set the pointer to the beginning of the data */ 356 p = (UINT8 *)(p_buf + 1) + p_buf->offset; 357 /* add HCI handle */ 358 UINT16_TO_STREAM (p, p_ccb->hci_handle); 359 /* only sent the first BTM_SCO_DATA_SIZE_MAX bytes data if more than max, 360 and set warning status */ 361 if (p_buf->len > BTM_SCO_DATA_SIZE_MAX) 362 { 363 p_buf->len = BTM_SCO_DATA_SIZE_MAX; 364 status = BTM_SCO_BAD_LENGTH; 365 } 366 367 UINT8_TO_STREAM (p, (UINT8)p_buf->len); 368 p_buf->len += HCI_SCO_PREAMBLE_SIZE; 369 370 GKI_enqueue (&p_ccb->xmit_data_q, p_buf); 371 372 btm_sco_check_send_pkts (sco_inx); 373 } 374 } 375 else 376 { 377 GKI_freebuf(p_buf); 378 379 BTM_TRACE_WARNING2 ("BTM_WriteScoData, invalid sco index: %d at state [%d]", 380 sco_inx, btm_cb.sco_cb.sco_db[sco_inx].state); 381 status = BTM_UNKNOWN_ADDR; 382 } 383 384 return (status); 385 386 #else 387 return (BTM_NO_RESOURCES); 388 #endif 389 } 390 391 #if (BTM_MAX_SCO_LINKS>0) 392 /******************************************************************************* 393 ** 394 ** Function btm_send_connect_request 395 ** 396 ** Description This function is called to respond to SCO connect indications 397 ** 398 ** Returns void 399 ** 400 *******************************************************************************/ 401 static tBTM_STATUS btm_send_connect_request(UINT16 acl_handle, 402 tBTM_ESCO_PARAMS *p_setup) 403 { 404 UINT16 temp_pkt_types; 405 UINT8 xx; 406 tACL_CONN *p_acl; 407 408 /* Send connect request depending on version of spec */ 409 if (!btm_cb.sco_cb.esco_supported) 410 { 411 if (!btsnd_hcic_add_SCO_conn (acl_handle, BTM_ESCO_2_SCO(p_setup->packet_types))) 412 return (BTM_NO_RESOURCES); 413 } 414 else 415 { 416 temp_pkt_types = (p_setup->packet_types & BTM_SCO_SUPPORTED_PKTS_MASK & 417 btm_cb.btm_sco_pkt_types_supported); 418 419 /* OR in any exception packet types if at least 2.0 version of spec */ 420 if (btm_cb.devcb.local_version.hci_version >= HCI_PROTO_VERSION_2_0) 421 { 422 temp_pkt_types |= ((p_setup->packet_types & BTM_SCO_EXCEPTION_PKTS_MASK) | 423 (btm_cb.btm_sco_pkt_types_supported & BTM_SCO_EXCEPTION_PKTS_MASK)); 424 } 425 426 /* Finally, remove EDR eSCO if the remote device doesn't support it */ 427 /* UPF25: Only SCO was brought up in this case */ 428 btm_handle_to_acl_index(acl_handle); 429 if ((xx = btm_handle_to_acl_index(acl_handle)) < MAX_L2CAP_LINKS) 430 { 431 p_acl = &btm_cb.acl_db[xx]; 432 if (!HCI_EDR_ESCO_2MPS_SUPPORTED(p_acl->features)) 433 { 434 435 BTM_TRACE_WARNING0("BTM Remote does not support 2-EDR eSCO"); 436 temp_pkt_types |= (HCI_ESCO_PKT_TYPES_MASK_NO_2_EV3 | 437 HCI_ESCO_PKT_TYPES_MASK_NO_2_EV5); 438 } 439 if (!HCI_EDR_ESCO_3MPS_SUPPORTED(p_acl->features)) 440 { 441 442 BTM_TRACE_WARNING0("BTM Remote does not support 3-EDR eSCO"); 443 temp_pkt_types |= (HCI_ESCO_PKT_TYPES_MASK_NO_3_EV3 | 444 HCI_ESCO_PKT_TYPES_MASK_NO_3_EV5); 445 } 446 } 447 448 449 BTM_TRACE_API6(" txbw 0x%x, rxbw 0x%x, lat 0x%x, voice 0x%x, retrans 0x%02x, pkt 0x%04x", 450 p_setup->tx_bw, p_setup->rx_bw, 451 p_setup->max_latency, p_setup->voice_contfmt, 452 p_setup->retrans_effort, temp_pkt_types); 453 454 if (!btsnd_hcic_setup_esco_conn(acl_handle, 455 p_setup->tx_bw, 456 p_setup->rx_bw, 457 p_setup->max_latency, 458 p_setup->voice_contfmt, 459 p_setup->retrans_effort, 460 temp_pkt_types)) 461 return (BTM_NO_RESOURCES); 462 else 463 p_setup->packet_types = temp_pkt_types; 464 } 465 466 return (BTM_CMD_STARTED); 467 } 468 #endif 469 470 /******************************************************************************* 471 ** 472 ** Function btm_set_sco_ind_cback 473 ** 474 ** Description This function is called to register for TCS SCO connect 475 ** indications. 476 ** 477 ** Returns void 478 ** 479 *******************************************************************************/ 480 void btm_set_sco_ind_cback( tBTM_SCO_IND_CBACK *sco_ind_cb ) 481 { 482 btm_cb.sco_cb.app_sco_ind_cb = sco_ind_cb; 483 } 484 485 /******************************************************************************* 486 ** 487 ** Function btm_accept_sco_link 488 ** 489 ** Description This function is called to respond to TCS SCO connect 490 ** indications 491 ** 492 ** Returns void 493 ** 494 *******************************************************************************/ 495 void btm_accept_sco_link(UINT16 sco_inx, tBTM_ESCO_PARAMS *p_setup, 496 tBTM_SCO_CB *p_conn_cb, tBTM_SCO_CB *p_disc_cb) 497 { 498 #if (BTM_MAX_SCO_LINKS>0) 499 tSCO_CONN *p_sco; 500 501 if (sco_inx >= BTM_MAX_SCO_LINKS) 502 { 503 BTM_TRACE_ERROR1("btm_accept_sco_link: Invalid sco_inx(%d)", sco_inx); 504 return; 505 } 506 507 /* Link role is ignored in for this message */ 508 p_sco = &btm_cb.sco_cb.sco_db[sco_inx]; 509 p_sco->p_conn_cb = p_conn_cb; 510 p_sco->p_disc_cb = p_disc_cb; 511 p_sco->esco.data.link_type = BTM_LINK_TYPE_ESCO; /* Accept with all supported types */ 512 513 BTM_TRACE_DEBUG1("TCS accept SCO: Packet Types 0x%04x", p_setup->packet_types); 514 515 btm_esco_conn_rsp(sco_inx, HCI_SUCCESS, p_sco->esco.data.bd_addr, p_setup); 516 #else 517 btm_reject_sco_link(sco_inx); 518 #endif 519 } 520 521 /******************************************************************************* 522 ** 523 ** Function btm_reject_sco_link 524 ** 525 ** Description This function is called to respond to SCO connect indications 526 ** 527 ** Returns void 528 ** 529 *******************************************************************************/ 530 void btm_reject_sco_link( UINT16 sco_inx ) 531 { 532 btm_esco_conn_rsp(sco_inx, HCI_ERR_HOST_REJECT_RESOURCES, 533 btm_cb.sco_cb.sco_db[sco_inx].esco.data.bd_addr, NULL); 534 } 535 536 /******************************************************************************* 537 ** 538 ** Function BTM_CreateSco 539 ** 540 ** Description This function is called to create an SCO connection. If the 541 ** "is_orig" flag is TRUE, the connection will be originated, 542 ** otherwise BTM will wait for the other side to connect. 543 ** 544 ** NOTE: If BTM_IGNORE_SCO_PKT_TYPE is passed in the pkt_types 545 ** parameter the default packet types is used. 546 ** 547 ** Returns BTM_UNKNOWN_ADDR if the ACL connection is not up 548 ** BTM_BUSY if another SCO being set up to 549 ** the same BD address 550 ** BTM_NO_RESOURCES if the max SCO limit has been reached 551 ** BTM_CMD_STARTED if the connection establishment is started. 552 ** In this case, "*p_sco_inx" is filled in 553 ** with the sco index used for the connection. 554 ** 555 *******************************************************************************/ 556 tBTM_STATUS BTM_CreateSco (BD_ADDR remote_bda, BOOLEAN is_orig, UINT16 pkt_types, 557 UINT16 *p_sco_inx, tBTM_SCO_CB *p_conn_cb, 558 tBTM_SCO_CB *p_disc_cb) 559 { 560 #if (BTM_MAX_SCO_LINKS > 0) 561 tBTM_ESCO_PARAMS *p_setup; 562 tSCO_CONN *p = &btm_cb.sco_cb.sco_db[0]; 563 UINT16 xx; 564 UINT16 acl_handle = 0; 565 UINT16 temp_pkt_types; 566 tACL_CONN *p_acl; 567 568 #if (BTM_PWR_MGR_INCLUDED == TRUE) && (BTM_SCO_WAKE_PARKED_LINK == TRUE) 569 tBTM_PM_MODE md; 570 tBTM_PM_PWR_MD pm; 571 #else 572 UINT8 mode; 573 #endif 574 575 *p_sco_inx = BTM_INVALID_SCO_INDEX; 576 577 /* If originating, ensure that there is an ACL connection to the BD Address */ 578 if (is_orig) 579 { 580 if ((!remote_bda) || ((acl_handle = BTM_GetHCIConnHandle (remote_bda)) == 0xFFFF)) 581 return (BTM_UNKNOWN_ADDR); 582 } 583 584 if (remote_bda) 585 { 586 /* If any SCO is being established to the remote BD address, refuse this */ 587 for (xx = 0; xx < BTM_MAX_SCO_LINKS; xx++, p++) 588 { 589 if (((p->state == SCO_ST_CONNECTING) || (p->state == SCO_ST_LISTENING) 590 || (p->state == SCO_ST_PEND_UNPARK)) 591 && (!memcmp (p->esco.data.bd_addr, remote_bda, BD_ADDR_LEN))) 592 { 593 return (BTM_BUSY); 594 } 595 } 596 } 597 else 598 { 599 /* Support only 1 wildcard BD address at a time */ 600 for (xx = 0; xx < BTM_MAX_SCO_LINKS; xx++, p++) 601 { 602 if ((p->state == SCO_ST_LISTENING) && (!p->rem_bd_known)) 603 return (BTM_BUSY); 604 } 605 } 606 607 /* Now, try to find an unused control block, and kick off the SCO establishment */ 608 for (xx = 0, p = &btm_cb.sco_cb.sco_db[0]; xx < BTM_MAX_SCO_LINKS; xx++, p++) 609 { 610 if (p->state == SCO_ST_UNUSED) 611 { 612 if (remote_bda) 613 { 614 if (is_orig) 615 { 616 /* can not create SCO link if in park mode */ 617 #if (BTM_PWR_MGR_INCLUDED == TRUE) && (BTM_SCO_WAKE_PARKED_LINK == TRUE) 618 if(BTM_ReadPowerMode(remote_bda, &md) == BTM_SUCCESS) 619 { 620 if (md == BTM_PM_MD_PARK || md == BTM_PM_MD_SNIFF) 621 { 622 /* Coverity: FALSE-POSITIVE error from Coverity tool. Please do NOT remove following comment. */ 623 /* coverity[uninit_use_in_call] False-positive: setting the mode to BTM_PM_MD_ACTIVE only uses settings.mode 624 the other data members of tBTM_PM_PWR_MD are ignored 625 */ 626 pm.mode = BTM_PM_MD_ACTIVE; 627 BTM_SetPowerMode(BTM_PM_SET_ONLY_ID, remote_bda, &pm); 628 p->state = SCO_ST_PEND_UNPARK; 629 } 630 } 631 #elif BTM_PWR_MGR_INCLUDED == TRUE 632 if( (BTM_ReadPowerMode(remote_bda, &mode) == BTM_SUCCESS) && (mode == BTM_PM_MD_PARK) ) 633 return (BTM_WRONG_MODE); 634 #else 635 if( (BTM_ReadAclMode(remote_bda, &mode) == BTM_SUCCESS) && (mode == BTM_ACL_MODE_PARK) ) 636 return (BTM_WRONG_MODE); 637 #endif 638 } 639 memcpy (p->esco.data.bd_addr, remote_bda, BD_ADDR_LEN); 640 p->rem_bd_known = TRUE; 641 } 642 else 643 p->rem_bd_known = FALSE; 644 645 /* Link role is ignored in for this message */ 646 if (pkt_types == BTM_IGNORE_SCO_PKT_TYPE) 647 pkt_types = btm_cb.sco_cb.def_esco_parms.packet_types; 648 649 p_setup = &p->esco.setup; 650 *p_setup = btm_cb.sco_cb.def_esco_parms; 651 p_setup->packet_types = (btm_cb.sco_cb.desired_sco_mode == BTM_LINK_TYPE_SCO) 652 ? (pkt_types & BTM_SCO_LINK_ONLY_MASK) : pkt_types; 653 654 temp_pkt_types = (p_setup->packet_types & BTM_SCO_SUPPORTED_PKTS_MASK & 655 btm_cb.btm_sco_pkt_types_supported); 656 657 /* OR in any exception packet types if at least 2.0 version of spec */ 658 if (btm_cb.devcb.local_version.hci_version >= HCI_PROTO_VERSION_2_0) 659 { 660 if (btm_cb.sco_cb.desired_sco_mode == HCI_LINK_TYPE_ESCO) 661 { 662 temp_pkt_types |= ((p_setup->packet_types & BTM_SCO_EXCEPTION_PKTS_MASK) | 663 (btm_cb.btm_sco_pkt_types_supported & BTM_SCO_EXCEPTION_PKTS_MASK)); 664 } 665 else /* Only using SCO packet types; turn off EDR also */ 666 { 667 temp_pkt_types |= BTM_SCO_EXCEPTION_PKTS_MASK; 668 } 669 } 670 671 p_setup->packet_types = temp_pkt_types; 672 p->p_conn_cb = p_conn_cb; 673 p->p_disc_cb = p_disc_cb; 674 p->hci_handle = BTM_INVALID_HCI_HANDLE; 675 p->is_orig = is_orig; 676 677 if( p->state != SCO_ST_PEND_UNPARK ) 678 { 679 if (is_orig) 680 { 681 /* If role change is in progress, do not proceed with SCO setup 682 * Wait till role change is complete */ 683 p_acl = btm_bda_to_acl(remote_bda); 684 if (p_acl && p_acl->switch_role_state != BTM_ACL_SWKEY_STATE_IDLE) 685 { 686 BTM_TRACE_API1("Role Change is in progress for ACL handle 0x%04x",acl_handle); 687 p->state = SCO_ST_PEND_ROLECHANGE; 688 689 } 690 } 691 } 692 693 if( p->state != SCO_ST_PEND_UNPARK && p->state != SCO_ST_PEND_ROLECHANGE ) 694 { 695 if (is_orig) 696 { 697 BTM_TRACE_API2("BTM_CreateSco -> (e)SCO Link for ACL handle 0x%04x, Desired Type %d", 698 acl_handle, btm_cb.sco_cb.desired_sco_mode); 699 700 if ((btm_send_connect_request(acl_handle, p_setup)) != BTM_CMD_STARTED) 701 return (BTM_NO_RESOURCES); 702 703 p->state = SCO_ST_CONNECTING; 704 } 705 else 706 p->state = SCO_ST_LISTENING; 707 } 708 709 *p_sco_inx = xx; 710 711 return (BTM_CMD_STARTED); 712 } 713 } 714 715 #endif 716 /* If here, all SCO blocks in use */ 717 return (BTM_NO_RESOURCES); 718 } 719 720 #if (BTM_PWR_MGR_INCLUDED == TRUE) && (BTM_SCO_WAKE_PARKED_LINK == TRUE) 721 /******************************************************************************* 722 ** 723 ** Function btm_sco_chk_pend_unpark 724 ** 725 ** Description This function is called by BTIF when there is a mode change 726 ** event to see if there are SCO commands waiting for the unpark. 727 ** 728 ** Returns void 729 ** 730 *******************************************************************************/ 731 void btm_sco_chk_pend_unpark (UINT8 hci_status, UINT16 hci_handle) 732 { 733 #if (BTM_MAX_SCO_LINKS>0) 734 UINT16 xx; 735 UINT16 acl_handle; 736 tSCO_CONN *p = &btm_cb.sco_cb.sco_db[0]; 737 738 for (xx = 0; xx < BTM_MAX_SCO_LINKS; xx++, p++) 739 { 740 if ((p->state == SCO_ST_PEND_UNPARK) && 741 ((acl_handle = BTM_GetHCIConnHandle (p->esco.data.bd_addr)) == hci_handle)) 742 743 { 744 BTM_TRACE_API3("btm_sco_chk_pend_unpark -> (e)SCO Link for ACL handle 0x%04x, Desired Type %d, hci_status 0x%02x", 745 acl_handle, btm_cb.sco_cb.desired_sco_mode, hci_status); 746 747 if ((btm_send_connect_request(acl_handle, &p->esco.setup)) == BTM_CMD_STARTED) 748 p->state = SCO_ST_CONNECTING; 749 } 750 } 751 #endif 752 } 753 #endif 754 755 /******************************************************************************* 756 ** 757 ** Function btm_sco_chk_pend_rolechange 758 ** 759 ** Description This function is called by BTIF when there is a role change 760 ** event to see if there are SCO commands waiting for the role change. 761 ** 762 ** Returns void 763 ** 764 *******************************************************************************/ 765 void btm_sco_chk_pend_rolechange (UINT16 hci_handle) 766 { 767 #if (BTM_MAX_SCO_LINKS>0) 768 UINT16 xx; 769 UINT16 acl_handle; 770 tSCO_CONN *p = &btm_cb.sco_cb.sco_db[0]; 771 772 for (xx = 0; xx < BTM_MAX_SCO_LINKS; xx++, p++) 773 { 774 if ((p->state == SCO_ST_PEND_ROLECHANGE) && 775 ((acl_handle = BTM_GetHCIConnHandle (p->esco.data.bd_addr)) == hci_handle)) 776 777 { 778 BTM_TRACE_API1("btm_sco_chk_pend_rolechange -> (e)SCO Link for ACL handle 0x%04x", acl_handle); 779 780 if ((btm_send_connect_request(acl_handle, &p->esco.setup)) == BTM_CMD_STARTED) 781 p->state = SCO_ST_CONNECTING; 782 } 783 } 784 #endif 785 } 786 787 /******************************************************************************* 788 ** 789 ** Function btm_sco_conn_req 790 ** 791 ** Description This function is called by BTIF when an SCO connection 792 ** request is received from a remote. 793 ** 794 ** Returns void 795 ** 796 *******************************************************************************/ 797 void btm_sco_conn_req (BD_ADDR bda, DEV_CLASS dev_class, UINT8 link_type) 798 { 799 #if (BTM_MAX_SCO_LINKS>0) 800 tSCO_CB *p_sco = &btm_cb.sco_cb; 801 tSCO_CONN *p = &p_sco->sco_db[0]; 802 UINT16 xx; 803 tBTM_ESCO_CONN_REQ_EVT_DATA evt_data; 804 805 for (xx = 0; xx < BTM_MAX_SCO_LINKS; xx++, p++) 806 { 807 /* 808 * If the sco state is in the SCO_ST_CONNECTING state, we still need 809 * to return accept sco to avoid race conditon for sco creation 810 */ 811 if (((p->state == SCO_ST_LISTENING && p->rem_bd_known) || p->state == SCO_ST_CONNECTING) 812 && (!memcmp (p->esco.data.bd_addr, bda, BD_ADDR_LEN))) 813 { 814 /* If this guy was a wildcard, he is not one any more */ 815 p->rem_bd_known = TRUE; 816 p->esco.data.link_type = link_type; 817 p->state = SCO_ST_W4_CONN_RSP; 818 memcpy (p->esco.data.bd_addr, bda, BD_ADDR_LEN); 819 820 /* If no callback, auto-accept the connection if packet types match */ 821 if (!p->esco.p_esco_cback) 822 { 823 /* If requesting eSCO reject if default parameters are SCO only */ 824 if ((link_type == BTM_LINK_TYPE_ESCO 825 && !(p_sco->def_esco_parms.packet_types & BTM_ESCO_LINK_ONLY_MASK) 826 && ((p_sco->def_esco_parms.packet_types & BTM_SCO_EXCEPTION_PKTS_MASK) 827 == BTM_SCO_EXCEPTION_PKTS_MASK)) 828 829 /* Reject request if SCO is desired but no SCO packets delected */ 830 || (link_type == BTM_LINK_TYPE_SCO 831 && !(p_sco->def_esco_parms.packet_types & BTM_SCO_LINK_ONLY_MASK))) 832 { 833 btm_esco_conn_rsp(xx, HCI_ERR_HOST_REJECT_RESOURCES, bda, NULL); 834 } 835 else /* Accept the request */ 836 { 837 btm_esco_conn_rsp(xx, HCI_SUCCESS, bda, NULL); 838 } 839 } 840 else /* Notify upper layer of connect indication */ 841 { 842 memcpy(evt_data.bd_addr, bda, BD_ADDR_LEN); 843 memcpy(evt_data.dev_class, dev_class, DEV_CLASS_LEN); 844 evt_data.link_type = link_type; 845 evt_data.sco_inx = xx; 846 p->esco.p_esco_cback(BTM_ESCO_CONN_REQ_EVT, (tBTM_ESCO_EVT_DATA *)&evt_data); 847 } 848 849 return; 850 } 851 } 852 853 /* TCS usage */ 854 if (btm_cb.sco_cb.app_sco_ind_cb) 855 { 856 /* Now, try to find an unused control block */ 857 for (xx = 0, p = &btm_cb.sco_cb.sco_db[0]; xx < BTM_MAX_SCO_LINKS; xx++, p++) 858 { 859 if (p->state == SCO_ST_UNUSED) 860 { 861 p->is_orig = FALSE; 862 p->state = SCO_ST_LISTENING; 863 864 p->esco.data.link_type = link_type; 865 memcpy (p->esco.data.bd_addr, bda, BD_ADDR_LEN); 866 p->rem_bd_known = TRUE; 867 break; 868 } 869 } 870 if( xx < BTM_MAX_SCO_LINKS) 871 { 872 btm_cb.sco_cb.app_sco_ind_cb(xx); 873 return; 874 } 875 } 876 877 #endif 878 /* If here, no one wants the SCO connection. Reject it */ 879 BTM_TRACE_WARNING0("btm_sco_conn_req: No one wants this SCO connection; rejecting it"); 880 btm_esco_conn_rsp(BTM_MAX_SCO_LINKS, HCI_ERR_HOST_REJECT_RESOURCES, bda, NULL); 881 } 882 883 /******************************************************************************* 884 ** 885 ** Function btm_sco_connected 886 ** 887 ** Description This function is called by BTIF when an (e)SCO connection 888 ** is connected. 889 ** 890 ** Returns void 891 ** 892 *******************************************************************************/ 893 void btm_sco_connected (UINT8 hci_status, BD_ADDR bda, UINT16 hci_handle, 894 tBTM_ESCO_DATA *p_esco_data) 895 { 896 #if (BTM_MAX_SCO_LINKS>0) 897 tSCO_CONN *p = &btm_cb.sco_cb.sco_db[0]; 898 UINT16 xx; 899 BOOLEAN spt = FALSE; 900 tBTM_CHG_ESCO_PARAMS parms; 901 #endif 902 903 btm_cb.sco_cb.sco_disc_reason = hci_status; 904 905 #if (BTM_MAX_SCO_LINKS>0) 906 for (xx = 0; xx < BTM_MAX_SCO_LINKS; xx++, p++) 907 { 908 if (((p->state == SCO_ST_CONNECTING) || 909 (p->state == SCO_ST_LISTENING) || 910 (p->state == SCO_ST_W4_CONN_RSP)) 911 && (p->rem_bd_known) 912 && (!bda || !memcmp (p->esco.data.bd_addr, bda, BD_ADDR_LEN))) 913 { 914 if (hci_status != HCI_SUCCESS) 915 { 916 /* Report the error if originator, otherwise remain in Listen mode */ 917 if (p->is_orig) 918 { 919 /* If role switch is pending, we need try again after role switch is complete */ 920 if(hci_status == HCI_ERR_ROLE_SWITCH_PENDING) 921 { 922 BTM_TRACE_API1("Role Change pending for HCI handle 0x%04x",hci_handle); 923 p->state = SCO_ST_PEND_ROLECHANGE; 924 } 925 /* avoid calling disconnect callback because of sco creation race */ 926 else if (hci_status != HCI_ERR_LMP_ERR_TRANS_COLLISION) 927 { 928 p->state = SCO_ST_UNUSED; 929 (*p->p_disc_cb)(xx); 930 } 931 } 932 else 933 { 934 /* Notify the upper layer that incoming sco connection has failed. */ 935 if (p->state == SCO_ST_CONNECTING) 936 { 937 p->state = SCO_ST_UNUSED; 938 (*p->p_disc_cb)(xx); 939 } 940 else 941 p->state = SCO_ST_LISTENING; 942 } 943 944 return; 945 } 946 947 if (p->state == SCO_ST_LISTENING) 948 spt = TRUE; 949 950 p->state = SCO_ST_CONNECTED; 951 p->hci_handle = hci_handle; 952 953 if (!btm_cb.sco_cb.esco_supported) 954 { 955 p->esco.data.link_type = BTM_LINK_TYPE_SCO; 956 if (spt) 957 { 958 parms.packet_types = p->esco.setup.packet_types; 959 /* Keep the other parameters the same for SCO */ 960 parms.max_latency = p->esco.setup.max_latency; 961 parms.retrans_effort = p->esco.setup.retrans_effort; 962 963 BTM_ChangeEScoLinkParms(xx, &parms); 964 } 965 } 966 else 967 { 968 if (p_esco_data) 969 p->esco.data = *p_esco_data; 970 } 971 972 (*p->p_conn_cb)(xx); 973 974 return; 975 } 976 } 977 #endif 978 } 979 980 981 /******************************************************************************* 982 ** 983 ** Function btm_find_scb_by_handle 984 ** 985 ** Description Look through all active SCO connection for a match based on the 986 ** HCI handle. 987 ** 988 ** Returns index to matched SCO connection CB, or BTM_MAX_SCO_LINKS if 989 ** no match. 990 ** 991 *******************************************************************************/ 992 UINT16 btm_find_scb_by_handle (UINT16 handle) 993 { 994 int xx; 995 tSCO_CONN *p = &btm_cb.sco_cb.sco_db[0]; 996 997 for (xx = 0; xx < BTM_MAX_SCO_LINKS; xx++, p++) 998 { 999 if ((p->state == SCO_ST_CONNECTED) && (p->hci_handle == handle)) 1000 { 1001 return (xx); 1002 } 1003 } 1004 1005 /* If here, no match found */ 1006 return (xx); 1007 } 1008 1009 /******************************************************************************* 1010 ** 1011 ** Function BTM_RemoveSco 1012 ** 1013 ** Description This function is called to remove a specific SCO connection. 1014 ** 1015 ** Returns status of the operation 1016 ** 1017 *******************************************************************************/ 1018 tBTM_STATUS BTM_RemoveSco (UINT16 sco_inx) 1019 { 1020 #if (BTM_MAX_SCO_LINKS>0) 1021 tSCO_CONN *p = &btm_cb.sco_cb.sco_db[sco_inx]; 1022 UINT16 tempstate; 1023 1024 /* Validity check */ 1025 if ((sco_inx >= BTM_MAX_SCO_LINKS) || (p->state == SCO_ST_UNUSED)) 1026 return (BTM_UNKNOWN_ADDR); 1027 1028 /* If no HCI handle, simply drop the connection and return */ 1029 if (p->hci_handle == BTM_INVALID_HCI_HANDLE || p->state == SCO_ST_PEND_UNPARK) 1030 { 1031 p->hci_handle = BTM_INVALID_HCI_HANDLE; 1032 p->state = SCO_ST_UNUSED; 1033 p->esco.p_esco_cback = NULL; /* Deregister the eSCO event callback */ 1034 return (BTM_SUCCESS); 1035 } 1036 1037 tempstate = p->state; 1038 p->state = SCO_ST_DISCONNECTING; 1039 1040 if (!btsnd_hcic_disconnect (p->hci_handle, HCI_ERR_PEER_USER)) 1041 { 1042 p->state = tempstate; 1043 return (BTM_NO_RESOURCES); 1044 } 1045 1046 return (BTM_CMD_STARTED); 1047 #else 1048 return (BTM_NO_RESOURCES); 1049 #endif 1050 } 1051 1052 /******************************************************************************* 1053 ** 1054 ** Function btm_remove_sco_links 1055 ** 1056 ** Description This function is called to remove all sco links for an ACL link. 1057 ** 1058 ** Returns void 1059 ** 1060 *******************************************************************************/ 1061 void btm_remove_sco_links (BD_ADDR bda) 1062 { 1063 #if (BTM_MAX_SCO_LINKS>0) 1064 tSCO_CONN *p = &btm_cb.sco_cb.sco_db[0]; 1065 UINT16 xx; 1066 1067 for (xx = 0; xx < BTM_MAX_SCO_LINKS; xx++, p++) 1068 { 1069 if (p->rem_bd_known && (!memcmp (p->esco.data.bd_addr, bda, BD_ADDR_LEN))) 1070 { 1071 BTM_RemoveSco(xx); 1072 } 1073 } 1074 #endif 1075 } 1076 1077 /******************************************************************************* 1078 ** 1079 ** Function btm_sco_removed 1080 ** 1081 ** Description This function is called by BTIF when an SCO connection 1082 ** is removed. 1083 ** 1084 ** Returns void 1085 ** 1086 *******************************************************************************/ 1087 void btm_sco_removed (UINT16 hci_handle, UINT8 reason) 1088 { 1089 #if (BTM_MAX_SCO_LINKS>0) 1090 tSCO_CONN *p = &btm_cb.sco_cb.sco_db[0]; 1091 UINT16 xx; 1092 #endif 1093 1094 btm_cb.sco_cb.sco_disc_reason = reason; 1095 1096 #if (BTM_MAX_SCO_LINKS>0) 1097 p = &btm_cb.sco_cb.sco_db[0]; 1098 for (xx = 0; xx < BTM_MAX_SCO_LINKS; xx++, p++) 1099 { 1100 if ((p->state != SCO_ST_UNUSED) && (p->state != SCO_ST_LISTENING) && (p->hci_handle == hci_handle)) 1101 { 1102 btm_sco_flush_sco_data(xx); 1103 1104 p->state = SCO_ST_UNUSED; 1105 p->hci_handle = BTM_INVALID_HCI_HANDLE; 1106 p->rem_bd_known = FALSE; 1107 p->esco.p_esco_cback = NULL; /* Deregister eSCO callback */ 1108 (*p->p_disc_cb)(xx); 1109 1110 return; 1111 } 1112 } 1113 #endif 1114 } 1115 1116 1117 /******************************************************************************* 1118 ** 1119 ** Function btm_sco_acl_removed 1120 ** 1121 ** Description This function is called when an ACL connection is 1122 ** removed. If the BD address is NULL, it is assumed that 1123 ** the local device is down, and all SCO links are removed. 1124 ** If a specific BD address is passed, only SCO connections 1125 ** to that BD address are removed. 1126 ** 1127 ** Returns void 1128 ** 1129 *******************************************************************************/ 1130 void btm_sco_acl_removed (BD_ADDR bda) 1131 { 1132 #if (BTM_MAX_SCO_LINKS>0) 1133 tSCO_CONN *p = &btm_cb.sco_cb.sco_db[0]; 1134 UINT16 xx; 1135 1136 for (xx = 0; xx < BTM_MAX_SCO_LINKS; xx++, p++) 1137 { 1138 if (p->state != SCO_ST_UNUSED) 1139 { 1140 if ((!bda) || (!memcmp (p->esco.data.bd_addr, bda, BD_ADDR_LEN) && p->rem_bd_known)) 1141 { 1142 btm_sco_flush_sco_data(xx); 1143 1144 p->state = SCO_ST_UNUSED; 1145 p->esco.p_esco_cback = NULL; /* Deregister eSCO callback */ 1146 (*p->p_disc_cb)(xx); 1147 } 1148 } 1149 } 1150 #endif 1151 } 1152 1153 1154 /******************************************************************************* 1155 ** 1156 ** Function BTM_SetScoPacketTypes 1157 ** 1158 ** Description This function is called to set the packet types used for 1159 ** a specific SCO connection, 1160 ** 1161 ** Parameters pkt_types - One or more of the following 1162 ** BTM_SCO_PKT_TYPES_MASK_HV1 1163 ** BTM_SCO_PKT_TYPES_MASK_HV2 1164 ** BTM_SCO_PKT_TYPES_MASK_HV3 1165 ** BTM_SCO_PKT_TYPES_MASK_EV3 1166 ** BTM_SCO_PKT_TYPES_MASK_EV4 1167 ** BTM_SCO_PKT_TYPES_MASK_EV5 1168 ** BTM_SCO_PKT_TYPES_MASK_NO_2_EV3 1169 ** BTM_SCO_PKT_TYPES_MASK_NO_3_EV3 1170 ** BTM_SCO_PKT_TYPES_MASK_NO_2_EV5 1171 ** BTM_SCO_PKT_TYPES_MASK_NO_3_EV5 1172 ** 1173 ** BTM_SCO_LINK_ALL_MASK - enables all supported types 1174 ** 1175 ** Returns status of the operation 1176 ** 1177 *******************************************************************************/ 1178 tBTM_STATUS BTM_SetScoPacketTypes (UINT16 sco_inx, UINT16 pkt_types) 1179 { 1180 #if (BTM_MAX_SCO_LINKS>0) 1181 tBTM_CHG_ESCO_PARAMS parms; 1182 tSCO_CONN *p; 1183 1184 /* Validity check */ 1185 if (sco_inx >= BTM_MAX_SCO_LINKS) 1186 return (BTM_UNKNOWN_ADDR); 1187 1188 p = &btm_cb.sco_cb.sco_db[sco_inx]; 1189 parms.packet_types = pkt_types; 1190 1191 /* Keep the other parameters the same for SCO */ 1192 parms.max_latency = p->esco.setup.max_latency; 1193 parms.retrans_effort = p->esco.setup.retrans_effort; 1194 1195 return (BTM_ChangeEScoLinkParms(sco_inx, &parms)); 1196 #else 1197 return (BTM_UNKNOWN_ADDR); 1198 #endif 1199 } 1200 1201 1202 /******************************************************************************* 1203 ** 1204 ** Function BTM_ReadScoPacketTypes 1205 ** 1206 ** Description This function is read the packet types used for a specific 1207 ** SCO connection. 1208 ** 1209 ** Returns Packet types supported for the connection 1210 ** One or more of the following (bitmask): 1211 ** BTM_SCO_PKT_TYPES_MASK_HV1 1212 ** BTM_SCO_PKT_TYPES_MASK_HV2 1213 ** BTM_SCO_PKT_TYPES_MASK_HV3 1214 ** BTM_SCO_PKT_TYPES_MASK_EV3 1215 ** BTM_SCO_PKT_TYPES_MASK_EV4 1216 ** BTM_SCO_PKT_TYPES_MASK_EV5 1217 ** BTM_SCO_PKT_TYPES_MASK_NO_2_EV3 1218 ** BTM_SCO_PKT_TYPES_MASK_NO_3_EV3 1219 ** BTM_SCO_PKT_TYPES_MASK_NO_2_EV5 1220 ** BTM_SCO_PKT_TYPES_MASK_NO_3_EV5 1221 ** 1222 *******************************************************************************/ 1223 UINT16 BTM_ReadScoPacketTypes (UINT16 sco_inx) 1224 { 1225 #if (BTM_MAX_SCO_LINKS>0) 1226 tSCO_CONN *p = &btm_cb.sco_cb.sco_db[sco_inx]; 1227 1228 /* Validity check */ 1229 if ((sco_inx < BTM_MAX_SCO_LINKS) && (p->state == SCO_ST_CONNECTED)) 1230 return (p->esco.setup.packet_types); 1231 else 1232 return (0); 1233 #else 1234 return (0); 1235 #endif 1236 } 1237 1238 /******************************************************************************* 1239 ** 1240 ** Function BTM_ReadScoDiscReason 1241 ** 1242 ** Description This function is returns the reason why an (e)SCO connection 1243 ** has been removed. It contains the value until read, or until 1244 ** another (e)SCO connection has disconnected. 1245 ** 1246 ** Returns HCI reason or BTM_INVALID_SCO_DISC_REASON if not set. 1247 ** 1248 *******************************************************************************/ 1249 UINT16 BTM_ReadScoDiscReason (void) 1250 { 1251 UINT16 res = btm_cb.sco_cb.sco_disc_reason; 1252 btm_cb.sco_cb.sco_disc_reason = BTM_INVALID_SCO_DISC_REASON; 1253 return (res); 1254 } 1255 1256 /******************************************************************************* 1257 ** 1258 ** Function BTM_ReadDeviceScoPacketTypes 1259 ** 1260 ** Description This function is read the SCO packet types that 1261 ** the device supports. 1262 ** 1263 ** Returns Packet types supported by the device. 1264 ** One or more of the following (bitmask): 1265 ** BTM_SCO_PKT_TYPES_MASK_HV1 1266 ** BTM_SCO_PKT_TYPES_MASK_HV2 1267 ** BTM_SCO_PKT_TYPES_MASK_HV3 1268 ** BTM_SCO_PKT_TYPES_MASK_EV3 1269 ** BTM_SCO_PKT_TYPES_MASK_EV4 1270 ** BTM_SCO_PKT_TYPES_MASK_EV5 1271 ** BTM_SCO_PKT_TYPES_MASK_NO_2_EV3 1272 ** BTM_SCO_PKT_TYPES_MASK_NO_3_EV3 1273 ** BTM_SCO_PKT_TYPES_MASK_NO_2_EV5 1274 ** BTM_SCO_PKT_TYPES_MASK_NO_3_EV5 1275 ** 1276 *******************************************************************************/ 1277 UINT16 BTM_ReadDeviceScoPacketTypes (void) 1278 { 1279 return (btm_cb.btm_sco_pkt_types_supported); 1280 } 1281 1282 /******************************************************************************* 1283 ** 1284 ** Function BTM_ReadScoHandle 1285 ** 1286 ** Description This function is used to read the HCI handle used for a specific 1287 ** SCO connection, 1288 ** 1289 ** Returns handle for the connection, or 0xFFFF if invalid SCO index. 1290 ** 1291 *******************************************************************************/ 1292 UINT16 BTM_ReadScoHandle (UINT16 sco_inx) 1293 { 1294 #if (BTM_MAX_SCO_LINKS>0) 1295 tSCO_CONN *p = &btm_cb.sco_cb.sco_db[sco_inx]; 1296 1297 /* Validity check */ 1298 if ((sco_inx < BTM_MAX_SCO_LINKS) && (p->state == SCO_ST_CONNECTED)) 1299 return (p->hci_handle); 1300 else 1301 return (BTM_INVALID_HCI_HANDLE); 1302 #else 1303 return (BTM_INVALID_HCI_HANDLE); 1304 #endif 1305 } 1306 1307 /******************************************************************************* 1308 ** 1309 ** Function BTM_ReadScoBdAddr 1310 ** 1311 ** Description This function is read the remote BD Address for a specific 1312 ** SCO connection, 1313 ** 1314 ** Returns pointer to BD address or NULL if not known 1315 ** 1316 *******************************************************************************/ 1317 UINT8 *BTM_ReadScoBdAddr (UINT16 sco_inx) 1318 { 1319 #if (BTM_MAX_SCO_LINKS>0) 1320 tSCO_CONN *p = &btm_cb.sco_cb.sco_db[sco_inx]; 1321 1322 /* Validity check */ 1323 if ((sco_inx < BTM_MAX_SCO_LINKS) && (p->rem_bd_known)) 1324 return (p->esco.data.bd_addr); 1325 else 1326 return (NULL); 1327 #else 1328 return (NULL); 1329 #endif 1330 } 1331 1332 /******************************************************************************* 1333 ** 1334 ** Function BTM_SetEScoMode 1335 ** 1336 ** Description This function sets up the negotiated parameters for SCO or 1337 ** eSCO, and sets as the default mode used for outgoing calls to 1338 ** BTM_CreateSco. It does not change any currently active (e)SCO links. 1339 ** Note: Incoming (e)SCO connections will always use packet types 1340 ** supported by the controller. If eSCO is not desired the 1341 ** feature should be disabled in the controller's feature mask. 1342 ** 1343 ** Returns BTM_SUCCESS if the successful. 1344 ** BTM_BUSY if there are one or more active (e)SCO links. 1345 ** 1346 *******************************************************************************/ 1347 tBTM_STATUS BTM_SetEScoMode (tBTM_SCO_TYPE sco_mode, tBTM_ESCO_PARAMS *p_parms) 1348 { 1349 tSCO_CB *p_esco = &btm_cb.sco_cb; 1350 tBTM_ESCO_PARAMS *p_def = &p_esco->def_esco_parms; 1351 1352 if (p_esco->esco_supported) 1353 { 1354 if (p_parms) 1355 { 1356 if (sco_mode == BTM_LINK_TYPE_ESCO) 1357 *p_def = *p_parms; /* Save as the default parameters */ 1358 else /* Load only the SCO packet types */ 1359 { 1360 p_def->packet_types = p_parms->packet_types; 1361 p_def->tx_bw = BTM_64KBITS_RATE; 1362 p_def->rx_bw = BTM_64KBITS_RATE; 1363 p_def->max_latency = 0x000a; 1364 p_def->voice_contfmt = 0x0060; 1365 p_def->retrans_effort = 0; 1366 1367 /* OR in any exception packet types if at least 2.0 version of spec */ 1368 if (btm_cb.devcb.local_version.hci_version >= HCI_PROTO_VERSION_2_0) 1369 { 1370 p_def->packet_types |= BTM_SCO_EXCEPTION_PKTS_MASK; 1371 } 1372 } 1373 } 1374 p_esco->desired_sco_mode = sco_mode; 1375 BTM_TRACE_API1("BTM_SetEScoMode -> mode %d", sco_mode); 1376 } 1377 else 1378 { 1379 p_esco->desired_sco_mode = BTM_LINK_TYPE_SCO; 1380 p_def->packet_types &= BTM_SCO_LINK_ONLY_MASK; 1381 p_def->retrans_effort = 0; 1382 BTM_TRACE_API0("BTM_SetEScoMode -> mode SCO (eSCO not supported)"); 1383 } 1384 1385 BTM_TRACE_DEBUG6(" txbw 0x%08x, rxbw 0x%08x, max_lat 0x%04x, voice 0x%04x, pkt 0x%04x, rtx effort 0x%02x", 1386 p_def->tx_bw, p_def->rx_bw, p_def->max_latency, 1387 p_def->voice_contfmt, p_def->packet_types, 1388 p_def->retrans_effort); 1389 1390 return (BTM_SUCCESS); 1391 } 1392 1393 1394 1395 /******************************************************************************* 1396 ** 1397 ** Function BTM_RegForEScoEvts 1398 ** 1399 ** Description This function registers a SCO event callback with the 1400 ** specified instance. It should be used to received 1401 ** connection indication events and change of link parameter 1402 ** events. 1403 ** 1404 ** Returns BTM_SUCCESS if the successful. 1405 ** BTM_ILLEGAL_VALUE if there is an illegal sco_inx 1406 ** BTM_MODE_UNSUPPORTED if controller version is not BT1.2 or 1407 ** later or does not support eSCO. 1408 ** 1409 *******************************************************************************/ 1410 tBTM_STATUS BTM_RegForEScoEvts (UINT16 sco_inx, tBTM_ESCO_CBACK *p_esco_cback) 1411 { 1412 #if (BTM_MAX_SCO_LINKS>0) 1413 if (!btm_cb.sco_cb.esco_supported) 1414 { 1415 btm_cb.sco_cb.sco_db[sco_inx].esco.p_esco_cback = NULL; 1416 return (BTM_MODE_UNSUPPORTED); 1417 } 1418 1419 if (sco_inx < BTM_MAX_SCO_LINKS && 1420 btm_cb.sco_cb.sco_db[sco_inx].state != SCO_ST_UNUSED) 1421 { 1422 btm_cb.sco_cb.sco_db[sco_inx].esco.p_esco_cback = p_esco_cback; 1423 return (BTM_SUCCESS); 1424 } 1425 return (BTM_ILLEGAL_VALUE); 1426 #else 1427 return (BTM_MODE_UNSUPPORTED); 1428 #endif 1429 } 1430 1431 /******************************************************************************* 1432 ** 1433 ** Function BTM_ReadEScoLinkParms 1434 ** 1435 ** Description This function returns the current eSCO link parameters for 1436 ** the specified handle. This can be called anytime a connection 1437 ** is active, but is typically called after receiving the SCO 1438 ** opened callback. 1439 ** 1440 ** Note: If called over a 1.1 controller, only the packet types 1441 ** field has meaning. 1442 ** 1443 ** Returns BTM_SUCCESS if returned data is valid connection. 1444 ** BTM_WRONG_MODE if no connection with a peer device or bad sco_inx. 1445 ** 1446 *******************************************************************************/ 1447 tBTM_STATUS BTM_ReadEScoLinkParms (UINT16 sco_inx, tBTM_ESCO_DATA *p_parms) 1448 { 1449 #if (BTM_MAX_SCO_LINKS>0) 1450 BTM_TRACE_API1("BTM_ReadEScoLinkParms -> sco_inx 0x%04x", sco_inx); 1451 1452 if (sco_inx < BTM_MAX_SCO_LINKS && 1453 btm_cb.sco_cb.sco_db[sco_inx].state >= SCO_ST_CONNECTED) 1454 { 1455 *p_parms = btm_cb.sco_cb.sco_db[sco_inx].esco.data; 1456 return (BTM_SUCCESS); 1457 } 1458 #endif 1459 1460 memset(p_parms, 0, sizeof(tBTM_ESCO_DATA)); 1461 return (BTM_WRONG_MODE); 1462 } 1463 1464 /******************************************************************************* 1465 ** 1466 ** Function BTM_ChangeEScoLinkParms 1467 ** 1468 ** Description This function requests renegotiation of the parameters on 1469 ** the current eSCO Link. If any of the changes are accepted 1470 ** by the controllers, the BTM_ESCO_CHG_EVT event is sent in 1471 ** the tBTM_ESCO_CBACK function with the current settings of 1472 ** the link. The callback is registered through the call to 1473 ** BTM_SetEScoMode. 1474 ** 1475 ** Note: If called over a SCO link (including 1.1 controller), 1476 ** a change packet type request is sent out instead. 1477 ** 1478 ** Returns BTM_CMD_STARTED if command is successfully initiated. 1479 ** BTM_NO_RESOURCES - not enough resources to initiate command. 1480 ** BTM_WRONG_MODE if no connection with a peer device or bad sco_inx. 1481 ** 1482 *******************************************************************************/ 1483 tBTM_STATUS BTM_ChangeEScoLinkParms (UINT16 sco_inx, tBTM_CHG_ESCO_PARAMS *p_parms) 1484 { 1485 #if (BTM_MAX_SCO_LINKS>0) 1486 tBTM_ESCO_PARAMS *p_setup; 1487 tSCO_CONN *p_sco; 1488 UINT16 temp_pkt_types; 1489 1490 /* Make sure sco handle is valid and on an active link */ 1491 if (sco_inx >= BTM_MAX_SCO_LINKS || 1492 btm_cb.sco_cb.sco_db[sco_inx].state != SCO_ST_CONNECTED) 1493 return (BTM_WRONG_MODE); 1494 1495 p_sco = &btm_cb.sco_cb.sco_db[sco_inx]; 1496 p_setup = &p_sco->esco.setup; 1497 1498 /* If SCO connection OR eSCO not supported just send change packet types */ 1499 if (p_sco->esco.data.link_type == BTM_LINK_TYPE_SCO || 1500 !btm_cb.sco_cb.esco_supported) 1501 { 1502 p_setup->packet_types = p_parms->packet_types & 1503 (btm_cb.btm_sco_pkt_types_supported & BTM_SCO_LINK_ONLY_MASK); 1504 1505 1506 BTM_TRACE_API2("BTM_ChangeEScoLinkParms -> SCO Link for handle 0x%04x, pkt 0x%04x", 1507 p_sco->hci_handle, p_setup->packet_types); 1508 1509 if (!btsnd_hcic_change_conn_type (p_sco->hci_handle, 1510 BTM_ESCO_2_SCO(p_setup->packet_types))) 1511 return (BTM_NO_RESOURCES); 1512 } 1513 else 1514 { 1515 temp_pkt_types = (p_parms->packet_types & BTM_SCO_SUPPORTED_PKTS_MASK & 1516 btm_cb.btm_sco_pkt_types_supported); 1517 1518 /* OR in any exception packet types if at least 2.0 version of spec */ 1519 if (btm_cb.devcb.local_version.hci_version >= HCI_PROTO_VERSION_2_0) 1520 { 1521 temp_pkt_types |= ((p_parms->packet_types & BTM_SCO_EXCEPTION_PKTS_MASK) | 1522 (btm_cb.btm_sco_pkt_types_supported & BTM_SCO_EXCEPTION_PKTS_MASK)); 1523 } 1524 1525 BTM_TRACE_API1("BTM_ChangeEScoLinkParms -> eSCO Link for handle 0x%04x", p_sco->hci_handle); 1526 BTM_TRACE_API6(" txbw 0x%x, rxbw 0x%x, lat 0x%x, voice 0x%x, retrans 0x%02x, pkt 0x%04x", 1527 p_setup->tx_bw, p_setup->rx_bw, p_parms->max_latency, 1528 p_setup->voice_contfmt, p_parms->retrans_effort, temp_pkt_types); 1529 1530 /* When changing an existing link, only change latency, retrans, and pkts */ 1531 if (!btsnd_hcic_setup_esco_conn(p_sco->hci_handle, p_setup->tx_bw, 1532 p_setup->rx_bw, p_parms->max_latency, 1533 p_setup->voice_contfmt, 1534 p_parms->retrans_effort, 1535 temp_pkt_types)) 1536 return (BTM_NO_RESOURCES); 1537 else 1538 p_parms->packet_types = temp_pkt_types; 1539 } 1540 1541 return (BTM_CMD_STARTED); 1542 #else 1543 return (BTM_WRONG_MODE); 1544 #endif 1545 } 1546 1547 /******************************************************************************* 1548 ** 1549 ** Function BTM_EScoConnRsp 1550 ** 1551 ** Description This function is called upon receipt of an (e)SCO connection 1552 ** request event (BTM_ESCO_CONN_REQ_EVT) to accept or reject 1553 ** the request. Parameters used to negotiate eSCO links. 1554 ** If p_parms is NULL, then values set through BTM_SetEScoMode 1555 ** are used. 1556 ** If the link type of the incoming request is SCO, then only 1557 ** the tx_bw, max_latency, content format, and packet_types are 1558 ** valid. The hci_status parameter should be 1559 ** ([0x0] to accept, [0x0d..0x0f] to reject) 1560 ** 1561 ** 1562 ** Returns void 1563 ** 1564 *******************************************************************************/ 1565 void BTM_EScoConnRsp (UINT16 sco_inx, UINT8 hci_status, tBTM_ESCO_PARAMS *p_parms) 1566 { 1567 #if (BTM_MAX_SCO_LINKS>0) 1568 if (sco_inx < BTM_MAX_SCO_LINKS && 1569 btm_cb.sco_cb.sco_db[sco_inx].state == SCO_ST_W4_CONN_RSP) 1570 { 1571 btm_esco_conn_rsp(sco_inx, hci_status, 1572 btm_cb.sco_cb.sco_db[sco_inx].esco.data.bd_addr, 1573 p_parms); 1574 } 1575 #endif 1576 } 1577 1578 /******************************************************************************* 1579 ** 1580 ** Function btm_read_def_esco_mode 1581 ** 1582 ** Description This function copies the current default esco settings into 1583 ** the return buffer. 1584 ** 1585 ** Returns tBTM_SCO_TYPE 1586 ** 1587 *******************************************************************************/ 1588 tBTM_SCO_TYPE btm_read_def_esco_mode (tBTM_ESCO_PARAMS *p_parms) 1589 { 1590 #if (BTM_MAX_SCO_LINKS>0) 1591 *p_parms = btm_cb.sco_cb.def_esco_parms; 1592 return btm_cb.sco_cb.desired_sco_mode; 1593 #else 1594 return BTM_LINK_TYPE_SCO; 1595 #endif 1596 } 1597 1598 /******************************************************************************* 1599 ** 1600 ** Function btm_esco_proc_conn_chg 1601 ** 1602 ** Description This function is called by BTIF when an SCO connection 1603 ** is changed. 1604 ** 1605 ** Returns void 1606 ** 1607 *******************************************************************************/ 1608 void btm_esco_proc_conn_chg (UINT8 status, UINT16 handle, UINT8 tx_interval, 1609 UINT8 retrans_window, UINT16 rx_pkt_len, 1610 UINT16 tx_pkt_len) 1611 { 1612 #if (BTM_MAX_SCO_LINKS>0) 1613 tSCO_CONN *p = &btm_cb.sco_cb.sco_db[0]; 1614 tBTM_CHG_ESCO_EVT_DATA data; 1615 UINT16 xx; 1616 1617 BTM_TRACE_EVENT2("btm_esco_proc_conn_chg -> handle 0x%04x, status 0x%02x", 1618 handle, status); 1619 1620 for (xx = 0; xx < BTM_MAX_SCO_LINKS; xx++, p++) 1621 { 1622 if (p->state == SCO_ST_CONNECTED && handle == p->hci_handle) 1623 { 1624 /* If upper layer wants notification */ 1625 if (p->esco.p_esco_cback) 1626 { 1627 memcpy(data.bd_addr, p->esco.data.bd_addr, BD_ADDR_LEN); 1628 data.hci_status = status; 1629 data.sco_inx = xx; 1630 data.rx_pkt_len = p->esco.data.rx_pkt_len = rx_pkt_len; 1631 data.tx_pkt_len = p->esco.data.tx_pkt_len = tx_pkt_len; 1632 data.tx_interval = p->esco.data.tx_interval = tx_interval; 1633 data.retrans_window = p->esco.data.retrans_window = retrans_window; 1634 1635 (*p->esco.p_esco_cback)(BTM_ESCO_CHG_EVT, 1636 (tBTM_ESCO_EVT_DATA *)&data); 1637 } 1638 return; 1639 } 1640 } 1641 #endif 1642 } 1643 1644 /******************************************************************************* 1645 ** 1646 ** Function btm_is_sco_active 1647 ** 1648 ** Description This function is called to see if a SCO handle is already in 1649 ** use. 1650 ** 1651 ** Returns BOOLEAN 1652 ** 1653 *******************************************************************************/ 1654 BOOLEAN btm_is_sco_active (UINT16 handle) 1655 { 1656 #if (BTM_MAX_SCO_LINKS>0) 1657 UINT16 xx; 1658 tSCO_CONN *p = &btm_cb.sco_cb.sco_db[0]; 1659 1660 for (xx = 0; xx < BTM_MAX_SCO_LINKS; xx++, p++) 1661 { 1662 if (handle == p->hci_handle && p->state == SCO_ST_CONNECTED) 1663 return (TRUE); 1664 } 1665 #endif 1666 return (FALSE); 1667 } 1668 1669 /******************************************************************************* 1670 ** 1671 ** Function BTM_GetNumScoLinks 1672 ** 1673 ** Description This function returns the number of active sco links. 1674 ** 1675 ** Returns UINT8 1676 ** 1677 *******************************************************************************/ 1678 UINT8 BTM_GetNumScoLinks (void) 1679 { 1680 #if (BTM_MAX_SCO_LINKS>0) 1681 tSCO_CONN *p = &btm_cb.sco_cb.sco_db[0]; 1682 UINT16 xx; 1683 UINT8 num_scos = 0; 1684 1685 for (xx = 0; xx < BTM_MAX_SCO_LINKS; xx++, p++) 1686 { 1687 switch (p->state) 1688 { 1689 case SCO_ST_W4_CONN_RSP: 1690 case SCO_ST_CONNECTING: 1691 case SCO_ST_CONNECTED: 1692 case SCO_ST_DISCONNECTING: 1693 case SCO_ST_PEND_UNPARK: 1694 num_scos++; 1695 } 1696 } 1697 return (num_scos); 1698 #else 1699 return (0); 1700 #endif 1701 } 1702 1703 1704 /******************************************************************************* 1705 ** 1706 ** Function btm_is_sco_active_by_bdaddr 1707 ** 1708 ** Description This function is called to see if a SCO active to a bd address. 1709 ** 1710 ** Returns BOOLEAN 1711 ** 1712 *******************************************************************************/ 1713 BOOLEAN btm_is_sco_active_by_bdaddr (BD_ADDR remote_bda) 1714 { 1715 #if (BTM_MAX_SCO_LINKS>0) 1716 UINT8 xx; 1717 tSCO_CONN *p = &btm_cb.sco_cb.sco_db[0]; 1718 1719 /* If any SCO is being established to the remote BD address, refuse this */ 1720 for (xx = 0; xx < BTM_MAX_SCO_LINKS; xx++, p++) 1721 { 1722 if ((!memcmp (p->esco.data.bd_addr, remote_bda, BD_ADDR_LEN)) && (p->state == SCO_ST_CONNECTED)) 1723 { 1724 return (TRUE); 1725 } 1726 } 1727 #endif 1728 return (FALSE); 1729 } 1730 #else /* SCO_EXCLUDED == TRUE (Link in stubs) */ 1731 1732 tBTM_STATUS BTM_CreateSco (BD_ADDR remote_bda, BOOLEAN is_orig, 1733 UINT16 pkt_types, UINT16 *p_sco_inx, 1734 tBTM_SCO_CB *p_conn_cb, 1735 tBTM_SCO_CB *p_disc_cb) {return (BTM_NO_RESOURCES);} 1736 tBTM_STATUS BTM_RemoveSco (UINT16 sco_inx) {return (BTM_NO_RESOURCES);} 1737 tBTM_STATUS BTM_SetScoPacketTypes (UINT16 sco_inx, UINT16 pkt_types) {return (BTM_NO_RESOURCES);} 1738 UINT16 BTM_ReadScoPacketTypes (UINT16 sco_inx) {return (0);} 1739 UINT16 BTM_ReadDeviceScoPacketTypes (void) {return (0);} 1740 UINT16 BTM_ReadScoHandle (UINT16 sco_inx) {return (BTM_INVALID_HCI_HANDLE);} 1741 UINT8 *BTM_ReadScoBdAddr(UINT16 sco_inx) {return((UINT8 *) NULL);} 1742 UINT16 BTM_ReadScoDiscReason (void) {return (BTM_INVALID_SCO_DISC_REASON);} 1743 tBTM_STATUS BTM_SetEScoMode (tBTM_SCO_TYPE sco_mode, tBTM_ESCO_PARAMS *p_parms) {return (BTM_MODE_UNSUPPORTED);} 1744 tBTM_STATUS BTM_RegForEScoEvts (UINT16 sco_inx, tBTM_ESCO_CBACK *p_esco_cback) { return (BTM_ILLEGAL_VALUE);} 1745 tBTM_STATUS BTM_ReadEScoLinkParms (UINT16 sco_inx, tBTM_ESCO_DATA *p_parms) { return (BTM_MODE_UNSUPPORTED);} 1746 tBTM_STATUS BTM_ChangeEScoLinkParms (UINT16 sco_inx, tBTM_CHG_ESCO_PARAMS *p_parms) { return (BTM_MODE_UNSUPPORTED);} 1747 void BTM_EScoConnRsp (UINT16 sco_inx, UINT8 hci_status, tBTM_ESCO_PARAMS *p_parms) {} 1748 UINT8 BTM_GetNumScoLinks (void) {return (0);} 1749 1750 #endif /* If SCO is being used */ 1751