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