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