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