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