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