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