1 /****************************************************************************** 2 * 3 * Copyright (C) 2004-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 for managing the SCO connection used in AG. 22 * 23 ******************************************************************************/ 24 25 #include <stddef.h> 26 27 #include "bt_common.h" 28 #include "bta_ag_api.h" 29 #include "bta_ag_co.h" 30 #include "bta_ag_int.h" 31 #include "bta_api.h" 32 #if (BTM_SCO_HCI_INCLUDED == TRUE) 33 #include "bta_dm_co.h" 34 #endif 35 #include "btm_api.h" 36 #include "device/include/controller.h" 37 #include "device/include/esco_parameters.h" 38 #include "osi/include/osi.h" 39 #include "utl.h" 40 41 #ifndef BTA_AG_SCO_DEBUG 42 #define BTA_AG_SCO_DEBUG FALSE 43 #endif 44 45 /* Codec negotiation timeout */ 46 #ifndef BTA_AG_CODEC_NEGOTIATION_TIMEOUT_MS 47 #define BTA_AG_CODEC_NEGOTIATION_TIMEOUT_MS (3 * 1000) /* 3 seconds */ 48 #endif 49 50 #if (BTA_AG_SCO_DEBUG == TRUE) 51 static char* bta_ag_sco_evt_str(uint8_t event); 52 static char* bta_ag_sco_state_str(uint8_t state); 53 #endif 54 55 static bool sco_allowed = true; 56 57 #define BTA_AG_NO_EDR_ESCO \ 58 (ESCO_PKT_TYPES_MASK_NO_2_EV3 | ESCO_PKT_TYPES_MASK_NO_3_EV3 | \ 59 ESCO_PKT_TYPES_MASK_NO_2_EV5 | ESCO_PKT_TYPES_MASK_NO_3_EV5) 60 61 /* sco events */ 62 enum { 63 BTA_AG_SCO_LISTEN_E, /* listen request */ 64 BTA_AG_SCO_OPEN_E, /* open request */ 65 BTA_AG_SCO_XFER_E, /* transfer request */ 66 BTA_AG_SCO_CN_DONE_E, /* codec negotiation done */ 67 BTA_AG_SCO_REOPEN_E, /* Retry with other codec when failed */ 68 BTA_AG_SCO_CLOSE_E, /* close request */ 69 BTA_AG_SCO_SHUTDOWN_E, /* shutdown request */ 70 BTA_AG_SCO_CONN_OPEN_E, /* sco open */ 71 BTA_AG_SCO_CONN_CLOSE_E, /* sco closed */ 72 BTA_AG_SCO_CI_DATA_E /* SCO data ready */ 73 }; 74 75 static void bta_ag_create_pending_sco(tBTA_AG_SCB* p_scb, bool is_local); 76 77 /******************************************************************************* 78 * 79 * Function bta_ag_sco_conn_cback 80 * 81 * Description BTM SCO connection callback. 82 * 83 * 84 * Returns void 85 * 86 ******************************************************************************/ 87 static void bta_ag_sco_conn_cback(uint16_t sco_idx) { 88 uint16_t handle; 89 tBTA_AG_SCB* p_scb; 90 91 /* match callback to scb; first check current sco scb */ 92 if (bta_ag_cb.sco.p_curr_scb != NULL && bta_ag_cb.sco.p_curr_scb->in_use) { 93 handle = bta_ag_scb_to_idx(bta_ag_cb.sco.p_curr_scb); 94 } 95 /* then check for scb connected to this peer */ 96 else { 97 /* Check if SLC is up */ 98 handle = bta_ag_idx_by_bdaddr(BTM_ReadScoBdAddr(sco_idx)); 99 p_scb = bta_ag_scb_by_idx(handle); 100 if (p_scb && !p_scb->svc_conn) handle = 0; 101 } 102 103 if (handle != 0) { 104 BT_HDR* p_buf = (BT_HDR*)osi_malloc(sizeof(BT_HDR)); 105 p_buf->event = BTA_AG_SCO_OPEN_EVT; 106 p_buf->layer_specific = handle; 107 bta_sys_sendmsg(p_buf); 108 } else { 109 /* no match found; disconnect sco, init sco variables */ 110 bta_ag_cb.sco.p_curr_scb = NULL; 111 bta_ag_cb.sco.state = BTA_AG_SCO_SHUTDOWN_ST; 112 BTM_RemoveSco(sco_idx); 113 } 114 } 115 116 /******************************************************************************* 117 * 118 * Function bta_ag_sco_disc_cback 119 * 120 * Description BTM SCO disconnection callback. 121 * 122 * 123 * Returns void 124 * 125 ******************************************************************************/ 126 static void bta_ag_sco_disc_cback(uint16_t sco_idx) { 127 uint16_t handle = 0; 128 129 APPL_TRACE_DEBUG( 130 "bta_ag_sco_disc_cback(): sco_idx: 0x%x p_cur_scb: 0x%08x sco.state: " 131 "%d", 132 sco_idx, bta_ag_cb.sco.p_curr_scb, bta_ag_cb.sco.state); 133 134 APPL_TRACE_DEBUG( 135 "bta_ag_sco_disc_cback(): scb[0] addr: 0x%08x in_use: %u sco_idx: 0x%x " 136 " sco state: %u", 137 &bta_ag_cb.scb[0], bta_ag_cb.scb[0].in_use, bta_ag_cb.scb[0].sco_idx, 138 bta_ag_cb.scb[0].state); 139 APPL_TRACE_DEBUG( 140 "bta_ag_sco_disc_cback(): scb[1] addr: 0x%08x in_use: %u sco_idx: 0x%x " 141 " sco state: %u", 142 &bta_ag_cb.scb[1], bta_ag_cb.scb[1].in_use, bta_ag_cb.scb[1].sco_idx, 143 bta_ag_cb.scb[1].state); 144 145 /* match callback to scb */ 146 if (bta_ag_cb.sco.p_curr_scb != NULL && bta_ag_cb.sco.p_curr_scb->in_use) { 147 /* We only care about callbacks for the active SCO */ 148 if (bta_ag_cb.sco.p_curr_scb->sco_idx != sco_idx) { 149 if (bta_ag_cb.sco.p_curr_scb->sco_idx != 0xFFFF) return; 150 } 151 handle = bta_ag_scb_to_idx(bta_ag_cb.sco.p_curr_scb); 152 } 153 154 if (handle != 0) { 155 #if (BTM_SCO_HCI_INCLUDED == TRUE) 156 157 tBTM_STATUS status = 158 BTM_ConfigScoPath(ESCO_DATA_PATH_PCM, NULL, NULL, true); 159 APPL_TRACE_DEBUG("%s: sco close config status = %d", __func__, status); 160 /* SCO clean up here */ 161 bta_dm_sco_co_close(); 162 #endif 163 164 /* Restore settings */ 165 if (bta_ag_cb.sco.p_curr_scb->inuse_codec == BTA_AG_CODEC_MSBC) { 166 /* Bypass vendor specific and voice settings if enhanced eSCO supported */ 167 if (!(controller_get_interface() 168 ->supports_enhanced_setup_synchronous_connection())) { 169 BTM_WriteVoiceSettings(BTM_VOICE_SETTING_CVSD); 170 } 171 172 /* If SCO open was initiated by AG and failed for mSBC T2, try mSBC T1 173 * 'Safe setting' first. If T1 also fails, try CVSD */ 174 if (bta_ag_sco_is_opening(bta_ag_cb.sco.p_curr_scb)) { 175 bta_ag_cb.sco.p_curr_scb->state = BTA_AG_SCO_CODEC_ST; 176 if (bta_ag_cb.sco.p_curr_scb->codec_msbc_settings == 177 BTA_AG_SCO_MSBC_SETTINGS_T2) { 178 APPL_TRACE_WARNING( 179 "%s: eSCO/SCO failed to open, falling back to mSBC T1 settings", 180 __func__); 181 bta_ag_cb.sco.p_curr_scb->codec_msbc_settings = 182 BTA_AG_SCO_MSBC_SETTINGS_T1; 183 } else { 184 APPL_TRACE_WARNING( 185 "%s: eSCO/SCO failed to open, falling back to CVSD", __func__); 186 bta_ag_cb.sco.p_curr_scb->codec_fallback = true; 187 } 188 } 189 } else if (bta_ag_sco_is_opening(bta_ag_cb.sco.p_curr_scb)) { 190 APPL_TRACE_ERROR("%s: eSCO/SCO failed to open, no more fall back", 191 __func__); 192 } 193 194 bta_ag_cb.sco.p_curr_scb->inuse_codec = BTA_AG_CODEC_NONE; 195 196 BT_HDR* p_buf = (BT_HDR*)osi_malloc(sizeof(BT_HDR)); 197 p_buf->event = BTA_AG_SCO_CLOSE_EVT; 198 p_buf->layer_specific = handle; 199 bta_sys_sendmsg(p_buf); 200 } else { 201 /* no match found */ 202 APPL_TRACE_DEBUG("no scb for ag_sco_disc_cback"); 203 204 /* sco could be closed after scb dealloc'ed */ 205 if (bta_ag_cb.sco.p_curr_scb != NULL) { 206 bta_ag_cb.sco.p_curr_scb->sco_idx = BTM_INVALID_SCO_INDEX; 207 bta_ag_cb.sco.p_curr_scb = NULL; 208 bta_ag_cb.sco.state = BTA_AG_SCO_SHUTDOWN_ST; 209 } 210 } 211 } 212 #if (BTM_SCO_HCI_INCLUDED == TRUE) 213 /******************************************************************************* 214 * 215 * Function bta_ag_sco_read_cback 216 * 217 * Description Callback function is the callback function for incoming 218 * SCO data over HCI. 219 * 220 * Returns void 221 * 222 ******************************************************************************/ 223 static void bta_ag_sco_read_cback(uint16_t sco_inx, BT_HDR* p_data, 224 tBTM_SCO_DATA_FLAG status) { 225 if (status != BTM_SCO_DATA_CORRECT) { 226 APPL_TRACE_DEBUG("%s: status %d", __func__, status); 227 } 228 229 /* Callout function must free the data. */ 230 bta_dm_sco_co_in_data(p_data, status); 231 } 232 #endif 233 /******************************************************************************* 234 * 235 * Function bta_ag_remove_sco 236 * 237 * Description Removes the specified SCO from the system. 238 * If only_active is true, then SCO is only removed if 239 * connected 240 * 241 * Returns bool - true if SCO removal was started 242 * 243 ******************************************************************************/ 244 static bool bta_ag_remove_sco(tBTA_AG_SCB* p_scb, bool only_active) { 245 if (p_scb->sco_idx != BTM_INVALID_SCO_INDEX) { 246 if (!only_active || p_scb->sco_idx == bta_ag_cb.sco.cur_idx) { 247 tBTM_STATUS status = BTM_RemoveSco(p_scb->sco_idx); 248 APPL_TRACE_DEBUG("%s: SCO index 0x%04x, status %d", __func__, 249 p_scb->sco_idx, status); 250 if (status == BTM_CMD_STARTED) { 251 /* SCO is connected; set current control block */ 252 bta_ag_cb.sco.p_curr_scb = p_scb; 253 return true; 254 } else if ((status == BTM_SUCCESS) || (status == BTM_UNKNOWN_ADDR)) { 255 /* If no connection reset the SCO handle */ 256 p_scb->sco_idx = BTM_INVALID_SCO_INDEX; 257 } 258 } 259 } 260 return false; 261 } 262 263 /******************************************************************************* 264 * 265 * Function bta_ag_esco_connreq_cback 266 * 267 * Description BTM eSCO connection requests and eSCO change requests 268 * Only the connection requests are processed by BTA. 269 * 270 * Returns void 271 * 272 ******************************************************************************/ 273 static void bta_ag_esco_connreq_cback(tBTM_ESCO_EVT event, 274 tBTM_ESCO_EVT_DATA* p_data) { 275 tBTA_AG_SCB* p_scb; 276 uint16_t handle; 277 uint16_t sco_inx = p_data->conn_evt.sco_inx; 278 279 /* Only process connection requests */ 280 if (event == BTM_ESCO_CONN_REQ_EVT) { 281 if ((handle = bta_ag_idx_by_bdaddr(BTM_ReadScoBdAddr(sco_inx))) != 0 && 282 ((p_scb = bta_ag_scb_by_idx(handle)) != NULL) && p_scb->svc_conn) { 283 p_scb->sco_idx = sco_inx; 284 285 /* If no other SCO active, allow this one */ 286 if (!bta_ag_cb.sco.p_curr_scb) { 287 APPL_TRACE_EVENT("%s: Accept Conn Request (sco_inx 0x%04x)", __func__, 288 sco_inx); 289 bta_ag_sco_conn_rsp(p_scb, &p_data->conn_evt); 290 291 bta_ag_cb.sco.state = BTA_AG_SCO_OPENING_ST; 292 bta_ag_cb.sco.p_curr_scb = p_scb; 293 bta_ag_cb.sco.cur_idx = p_scb->sco_idx; 294 } else { 295 /* Begin a transfer: Close current SCO before responding */ 296 APPL_TRACE_DEBUG("bta_ag_esco_connreq_cback: Begin XFER"); 297 bta_ag_cb.sco.p_xfer_scb = p_scb; 298 bta_ag_cb.sco.conn_data = p_data->conn_evt; 299 bta_ag_cb.sco.state = BTA_AG_SCO_OPEN_XFER_ST; 300 301 if (!bta_ag_remove_sco(bta_ag_cb.sco.p_curr_scb, true)) { 302 APPL_TRACE_ERROR( 303 "%s: Nothing to remove,so accept Conn Request(sco_inx 0x%04x)", 304 __func__, sco_inx); 305 bta_ag_cb.sco.p_xfer_scb = NULL; 306 bta_ag_cb.sco.state = BTA_AG_SCO_LISTEN_ST; 307 308 bta_ag_sco_conn_rsp(p_scb, &p_data->conn_evt); 309 } 310 } 311 } else { 312 /* If error occurred send reject response immediately */ 313 APPL_TRACE_WARNING( 314 "no scb for bta_ag_esco_connreq_cback or no resources"); 315 BTM_EScoConnRsp(p_data->conn_evt.sco_inx, HCI_ERR_HOST_REJECT_RESOURCES, 316 (enh_esco_params_t*)NULL); 317 } 318 } else if (event == BTM_ESCO_CHG_EVT) { 319 /* Received a change in the esco link */ 320 APPL_TRACE_EVENT( 321 "%s: eSCO change event (inx %d): rtrans %d, " 322 "rxlen %d, txlen %d, txint %d", 323 __func__, p_data->chg_evt.sco_inx, p_data->chg_evt.retrans_window, 324 p_data->chg_evt.rx_pkt_len, p_data->chg_evt.tx_pkt_len, 325 p_data->chg_evt.tx_interval); 326 } 327 } 328 329 /******************************************************************************* 330 * 331 * Function bta_ag_cback_sco 332 * 333 * Description Call application callback function with SCO event. 334 * 335 * 336 * Returns void 337 * 338 ******************************************************************************/ 339 static void bta_ag_cback_sco(tBTA_AG_SCB* p_scb, uint8_t event) { 340 tBTA_AG_HDR sco; 341 342 sco.handle = bta_ag_scb_to_idx(p_scb); 343 sco.app_id = p_scb->app_id; 344 345 /* call close cback */ 346 (*bta_ag_cb.p_cback)(event, (tBTA_AG*)&sco); 347 } 348 349 /******************************************************************************* 350 * 351 * Function bta_ag_create_sco 352 * 353 * Description Create a SCO connection for a given control block 354 * p_scb : Pointer to the target AG control block 355 * is_orig : Whether to initiate or listen for SCO connection 356 * 357 * Returns void 358 * 359 ******************************************************************************/ 360 static void bta_ag_create_sco(tBTA_AG_SCB* p_scb, bool is_orig) { 361 APPL_TRACE_DEBUG( 362 "%s: BEFORE codec_updated=%d, codec_fallback=%d, " 363 "sco_codec=%d, peer_codec=%d, msbc_settings=%d", 364 __func__, p_scb->codec_updated, p_scb->codec_fallback, p_scb->sco_codec, 365 p_scb->peer_codecs, p_scb->codec_msbc_settings); 366 tBTA_AG_PEER_CODEC esco_codec = BTA_AG_CODEC_CVSD; 367 368 /* Make sure this SCO handle is not already in use */ 369 if (p_scb->sco_idx != BTM_INVALID_SCO_INDEX) { 370 APPL_TRACE_ERROR("%s: Index 0x%04x already in use!", __func__, 371 p_scb->sco_idx); 372 return; 373 } 374 375 if ((p_scb->sco_codec == BTA_AG_CODEC_MSBC) && !p_scb->codec_fallback) 376 esco_codec = BTA_AG_CODEC_MSBC; 377 378 if (p_scb->codec_fallback) { 379 p_scb->codec_fallback = false; 380 /* Force AG to send +BCS for the next audio connection. */ 381 p_scb->codec_updated = true; 382 /* Reset mSBC settings to T2 for the next audio connection */ 383 p_scb->codec_msbc_settings = BTA_AG_SCO_MSBC_SETTINGS_T2; 384 } 385 386 esco_codec_t codec_index = ESCO_CODEC_CVSD; 387 /* If WBS included, use CVSD by default, index is 0 for CVSD by 388 * initialization. If eSCO codec is mSBC, index is T2 or T1 */ 389 if (esco_codec == BTA_AG_CODEC_MSBC) { 390 if (p_scb->codec_msbc_settings == BTA_AG_SCO_MSBC_SETTINGS_T2) { 391 codec_index = ESCO_CODEC_MSBC_T2; 392 } else { 393 codec_index = ESCO_CODEC_MSBC_T1; 394 } 395 } 396 397 /* Initialize eSCO parameters */ 398 enh_esco_params_t params = esco_parameters_for_codec(codec_index); 399 /* For CVSD */ 400 if (esco_codec == BTM_SCO_CODEC_CVSD) { 401 /* Use the applicable packet types 402 (3-EV3 not allowed due to errata 2363) */ 403 params.packet_types = 404 p_bta_ag_cfg->sco_pkt_types | ESCO_PKT_TYPES_MASK_NO_3_EV3; 405 if ((!(p_scb->features & BTA_AG_FEAT_ESCO)) || 406 (!(p_scb->peer_features & BTA_AG_PEER_FEAT_ESCO))) { 407 params.max_latency_ms = 10; 408 params.retransmission_effort = ESCO_RETRANSMISSION_POWER; 409 } 410 } 411 412 /* If initiating, setup parameters to start SCO/eSCO connection */ 413 if (is_orig) { 414 bta_ag_cb.sco.is_local = true; 415 /* Set eSCO Mode */ 416 BTM_SetEScoMode(¶ms); 417 bta_ag_cb.sco.p_curr_scb = p_scb; 418 /* save the current codec as sco_codec can be updated while SCO is open. */ 419 p_scb->inuse_codec = esco_codec; 420 421 /* tell sys to stop av if any */ 422 bta_sys_sco_use(BTA_ID_AG, p_scb->app_id, p_scb->peer_addr); 423 424 /* Send pending commands to create SCO connection to peer */ 425 bta_ag_create_pending_sco(p_scb, bta_ag_cb.sco.is_local); 426 } else { 427 /* Not initiating, go to listen mode */ 428 tBTM_STATUS status = BTM_CreateSco( 429 &p_scb->peer_addr, false, params.packet_types, &p_scb->sco_idx, 430 bta_ag_sco_conn_cback, bta_ag_sco_disc_cback); 431 if (status == BTM_CMD_STARTED) 432 BTM_RegForEScoEvts(p_scb->sco_idx, bta_ag_esco_connreq_cback); 433 434 APPL_TRACE_API("%s: orig %d, inx 0x%04x, status 0x%x, pkt types 0x%04x", 435 __func__, is_orig, p_scb->sco_idx, status, 436 params.packet_types); 437 } 438 APPL_TRACE_DEBUG( 439 "%s: AFTER codec_updated=%d, codec_fallback=%d, " 440 "sco_codec=%d, peer_codec=%d, msbc_settings=%d", 441 __func__, p_scb->codec_updated, p_scb->codec_fallback, p_scb->sco_codec, 442 p_scb->peer_codecs, p_scb->codec_msbc_settings); 443 } 444 445 /******************************************************************************* 446 * 447 * Function bta_ag_create_pending_sco 448 * 449 * Description This Function is called after the pre-SCO vendor setup is 450 * done for the BTA to continue and send the HCI Commands for 451 * creating/accepting SCO connection with peer based on the 452 * is_local parameter. 453 * 454 * Returns void 455 * 456 ******************************************************************************/ 457 static void bta_ag_create_pending_sco(tBTA_AG_SCB* p_scb, bool is_local) { 458 tBTA_AG_PEER_CODEC esco_codec = p_scb->inuse_codec; 459 enh_esco_params_t params; 460 bta_ag_cb.sco.p_curr_scb = p_scb; 461 bta_ag_cb.sco.cur_idx = p_scb->sco_idx; 462 463 /* Local device requested SCO connection to peer */ 464 if (is_local) { 465 if (esco_codec == BTA_AG_CODEC_MSBC) { 466 if (p_scb->codec_msbc_settings == BTA_AG_SCO_MSBC_SETTINGS_T2) { 467 params = esco_parameters_for_codec(ESCO_CODEC_MSBC_T2); 468 } else 469 params = esco_parameters_for_codec(ESCO_CODEC_MSBC_T1); 470 } else { 471 params = esco_parameters_for_codec(ESCO_CODEC_CVSD); 472 if ((!(p_scb->features & BTA_AG_FEAT_ESCO)) || 473 (!(p_scb->peer_features & BTA_AG_PEER_FEAT_ESCO))) { 474 params.max_latency_ms = 10; 475 params.retransmission_effort = ESCO_RETRANSMISSION_POWER; 476 } 477 } 478 479 /* Bypass voice settings if enhanced SCO setup command is supported */ 480 if (!(controller_get_interface() 481 ->supports_enhanced_setup_synchronous_connection())) { 482 if (esco_codec == BTA_AG_CODEC_MSBC) 483 BTM_WriteVoiceSettings(BTM_VOICE_SETTING_TRANS); 484 else 485 BTM_WriteVoiceSettings(BTM_VOICE_SETTING_CVSD); 486 } 487 488 #if (BTM_SCO_HCI_INCLUDED == TRUE) 489 /* initialize SCO setup, no voice setting for AG, data rate <==> sample 490 * rate */ 491 BTM_ConfigScoPath(params.input_data_path, bta_ag_sco_read_cback, NULL, 492 TRUE); 493 #endif 494 495 tBTM_STATUS status = BTM_CreateSco( 496 &p_scb->peer_addr, true, params.packet_types, &p_scb->sco_idx, 497 bta_ag_sco_conn_cback, bta_ag_sco_disc_cback); 498 if (status == BTM_CMD_STARTED) { 499 /* Initiating the connection, set the current sco handle */ 500 bta_ag_cb.sco.cur_idx = p_scb->sco_idx; 501 } 502 } else { 503 /* Local device accepted SCO connection from peer */ 504 params = esco_parameters_for_codec(ESCO_CODEC_CVSD); 505 if ((!(p_scb->features & BTA_AG_FEAT_ESCO)) || 506 (!(p_scb->peer_features & BTA_AG_PEER_FEAT_ESCO))) { 507 params.max_latency_ms = 10; 508 params.retransmission_effort = ESCO_RETRANSMISSION_POWER; 509 } 510 511 BTM_EScoConnRsp(p_scb->sco_idx, HCI_SUCCESS, ¶ms); 512 } 513 } 514 515 /******************************************************************************* 516 * 517 * Function bta_ag_codec_negotiation_timer_cback 518 * 519 * Description 520 * 521 * 522 * Returns void 523 * 524 ******************************************************************************/ 525 static void bta_ag_codec_negotiation_timer_cback(void* data) { 526 APPL_TRACE_DEBUG("%s", __func__); 527 tBTA_AG_SCB* p_scb = (tBTA_AG_SCB*)data; 528 529 /* Announce that codec negotiation failed. */ 530 bta_ag_sco_codec_nego(p_scb, false); 531 532 /* call app callback */ 533 bta_ag_cback_sco(p_scb, BTA_AG_AUDIO_CLOSE_EVT); 534 } 535 536 /******************************************************************************* 537 * 538 * Function bta_ag_codec_negotiate 539 * 540 * Description Initiate codec negotiation by sending AT command. 541 * If not necessary, skip negotiation. 542 * 543 * Returns void 544 * 545 ******************************************************************************/ 546 void bta_ag_codec_negotiate(tBTA_AG_SCB* p_scb) { 547 APPL_TRACE_DEBUG("%s", __func__); 548 bta_ag_cb.sco.p_curr_scb = p_scb; 549 550 if ((p_scb->codec_updated || p_scb->codec_fallback) && 551 (p_scb->peer_features & BTA_AG_PEER_FEAT_CODEC)) { 552 /* Change the power mode to Active until SCO open is completed. */ 553 bta_sys_busy(BTA_ID_AG, p_scb->app_id, p_scb->peer_addr); 554 555 /* Send +BCS to the peer */ 556 bta_ag_send_bcs(p_scb, NULL); 557 558 /* Start timer to handle timeout */ 559 alarm_set_on_mloop(p_scb->codec_negotiation_timer, 560 BTA_AG_CODEC_NEGOTIATION_TIMEOUT_MS, 561 bta_ag_codec_negotiation_timer_cback, p_scb); 562 } else { 563 /* use same codec type as previous SCO connection, skip codec negotiation */ 564 APPL_TRACE_DEBUG( 565 "use same codec type as previous SCO connection,skip codec " 566 "negotiation"); 567 bta_ag_sco_codec_nego(p_scb, true); 568 } 569 } 570 571 /******************************************************************************* 572 * 573 * Function bta_ag_sco_event 574 * 575 * Description 576 * 577 * 578 * Returns void 579 * 580 ******************************************************************************/ 581 static void bta_ag_sco_event(tBTA_AG_SCB* p_scb, uint8_t event) { 582 tBTA_AG_SCO_CB* p_sco = &bta_ag_cb.sco; 583 #if (BTM_SCO_HCI_INCLUDED == TRUE) 584 BT_HDR* p_buf; 585 #endif 586 587 #if (BTA_AG_SCO_DEBUG == TRUE) 588 uint8_t in_state = p_sco->state; 589 590 if (event != BTA_AG_SCO_CI_DATA_E) { 591 APPL_TRACE_EVENT("%s: SCO Index 0x%04x, State %d (%s), Event %d (%s)", 592 __func__, p_scb->sco_idx, p_sco->state, 593 bta_ag_sco_state_str(p_sco->state), event, 594 bta_ag_sco_evt_str(event)); 595 } 596 #else 597 if (event != BTA_AG_SCO_CI_DATA_E) { 598 APPL_TRACE_EVENT("%s: SCO Index 0x%04x, State %d, Event %d", __func__, 599 p_scb->sco_idx, p_sco->state, event); 600 } 601 #endif 602 603 #if (BTM_SCO_HCI_INCLUDED == TRUE) 604 if (event == BTA_AG_SCO_CI_DATA_E) { 605 while (true) { 606 bta_dm_sco_co_out_data(&p_buf); 607 if (p_buf) { 608 if (p_sco->state == BTA_AG_SCO_OPEN_ST) 609 BTM_WriteScoData(p_sco->p_curr_scb->sco_idx, p_buf); 610 else 611 osi_free(p_buf); 612 } else 613 break; 614 } 615 616 return; 617 } 618 #endif 619 620 switch (p_sco->state) { 621 case BTA_AG_SCO_SHUTDOWN_ST: 622 switch (event) { 623 case BTA_AG_SCO_LISTEN_E: 624 /* create sco listen connection */ 625 bta_ag_create_sco(p_scb, false); 626 p_sco->state = BTA_AG_SCO_LISTEN_ST; 627 break; 628 629 default: 630 APPL_TRACE_WARNING("%s: BTA_AG_SCO_SHUTDOWN_ST: Ignoring event %d", 631 __func__, event); 632 break; 633 } 634 break; 635 636 case BTA_AG_SCO_LISTEN_ST: 637 switch (event) { 638 case BTA_AG_SCO_LISTEN_E: 639 /* create sco listen connection (Additional channel) */ 640 bta_ag_create_sco(p_scb, false); 641 break; 642 643 case BTA_AG_SCO_OPEN_E: 644 /* remove listening connection */ 645 bta_ag_remove_sco(p_scb, false); 646 647 /* start codec negotiation */ 648 p_sco->state = BTA_AG_SCO_CODEC_ST; 649 bta_ag_codec_negotiate(p_scb); 650 break; 651 652 case BTA_AG_SCO_SHUTDOWN_E: 653 /* remove listening connection */ 654 bta_ag_remove_sco(p_scb, false); 655 656 if (p_scb == p_sco->p_curr_scb) p_sco->p_curr_scb = NULL; 657 658 /* If last SCO instance then finish shutting down */ 659 if (!bta_ag_other_scb_open(p_scb)) { 660 p_sco->state = BTA_AG_SCO_SHUTDOWN_ST; 661 } 662 break; 663 664 case BTA_AG_SCO_CLOSE_E: 665 /* remove listening connection */ 666 /* Ignore the event. Keep listening SCO for the active SLC 667 */ 668 APPL_TRACE_WARNING("%s: BTA_AG_SCO_LISTEN_ST: Ignoring event %d", 669 __func__, event); 670 break; 671 672 case BTA_AG_SCO_CONN_CLOSE_E: 673 /* sco failed; create sco listen connection */ 674 bta_ag_create_sco(p_scb, false); 675 p_sco->state = BTA_AG_SCO_LISTEN_ST; 676 break; 677 678 default: 679 APPL_TRACE_WARNING("%s: BTA_AG_SCO_LISTEN_ST: Ignoring event %d", 680 __func__, event); 681 break; 682 } 683 break; 684 685 case BTA_AG_SCO_CODEC_ST: 686 switch (event) { 687 case BTA_AG_SCO_LISTEN_E: 688 /* create sco listen connection (Additional channel) */ 689 bta_ag_create_sco(p_scb, false); 690 break; 691 692 case BTA_AG_SCO_CN_DONE_E: 693 /* create sco connection to peer */ 694 bta_ag_create_sco(p_scb, true); 695 p_sco->state = BTA_AG_SCO_OPENING_ST; 696 break; 697 698 case BTA_AG_SCO_XFER_E: 699 /* save xfer scb */ 700 p_sco->p_xfer_scb = p_scb; 701 p_sco->state = BTA_AG_SCO_CLOSE_XFER_ST; 702 break; 703 704 case BTA_AG_SCO_SHUTDOWN_E: 705 /* remove listening connection */ 706 bta_ag_remove_sco(p_scb, false); 707 708 if (p_scb == p_sco->p_curr_scb) p_sco->p_curr_scb = NULL; 709 710 /* If last SCO instance then finish shutting down */ 711 if (!bta_ag_other_scb_open(p_scb)) { 712 p_sco->state = BTA_AG_SCO_SHUTDOWN_ST; 713 } 714 break; 715 716 case BTA_AG_SCO_CLOSE_E: 717 /* sco open is not started yet. just go back to listening */ 718 p_sco->state = BTA_AG_SCO_LISTEN_ST; 719 break; 720 721 case BTA_AG_SCO_CONN_CLOSE_E: 722 /* sco failed; create sco listen connection */ 723 bta_ag_create_sco(p_scb, false); 724 p_sco->state = BTA_AG_SCO_LISTEN_ST; 725 break; 726 727 default: 728 APPL_TRACE_WARNING("%s: BTA_AG_SCO_CODEC_ST: Ignoring event %d", 729 __func__, event); 730 break; 731 } 732 break; 733 734 case BTA_AG_SCO_OPENING_ST: 735 switch (event) { 736 case BTA_AG_SCO_LISTEN_E: 737 /* second headset has now joined */ 738 /* create sco listen connection (Additional channel) */ 739 if (p_scb != p_sco->p_curr_scb) { 740 bta_ag_create_sco(p_scb, false); 741 } 742 break; 743 744 case BTA_AG_SCO_REOPEN_E: 745 /* start codec negotiation */ 746 p_sco->state = BTA_AG_SCO_CODEC_ST; 747 bta_ag_codec_negotiate(p_scb); 748 break; 749 750 case BTA_AG_SCO_XFER_E: 751 /* save xfer scb */ 752 p_sco->p_xfer_scb = p_scb; 753 p_sco->state = BTA_AG_SCO_CLOSE_XFER_ST; 754 break; 755 756 case BTA_AG_SCO_CLOSE_E: 757 p_sco->state = BTA_AG_SCO_OPEN_CL_ST; 758 break; 759 760 case BTA_AG_SCO_SHUTDOWN_E: 761 /* If not opening scb, just close it */ 762 if (p_scb != p_sco->p_curr_scb) { 763 /* remove listening connection */ 764 bta_ag_remove_sco(p_scb, false); 765 } else 766 p_sco->state = BTA_AG_SCO_SHUTTING_ST; 767 768 break; 769 770 case BTA_AG_SCO_CONN_OPEN_E: 771 p_sco->state = BTA_AG_SCO_OPEN_ST; 772 break; 773 774 case BTA_AG_SCO_CONN_CLOSE_E: 775 /* sco failed; create sco listen connection */ 776 bta_ag_create_sco(p_scb, false); 777 p_sco->state = BTA_AG_SCO_LISTEN_ST; 778 break; 779 780 default: 781 APPL_TRACE_WARNING("%s: BTA_AG_SCO_OPENING_ST: Ignoring event %d", 782 __func__, event); 783 break; 784 } 785 break; 786 787 case BTA_AG_SCO_OPEN_CL_ST: 788 switch (event) { 789 case BTA_AG_SCO_XFER_E: 790 /* save xfer scb */ 791 p_sco->p_xfer_scb = p_scb; 792 793 p_sco->state = BTA_AG_SCO_CLOSE_XFER_ST; 794 break; 795 796 case BTA_AG_SCO_OPEN_E: 797 p_sco->state = BTA_AG_SCO_OPENING_ST; 798 break; 799 800 case BTA_AG_SCO_SHUTDOWN_E: 801 /* If not opening scb, just close it */ 802 if (p_scb != p_sco->p_curr_scb) { 803 /* remove listening connection */ 804 bta_ag_remove_sco(p_scb, false); 805 } else 806 p_sco->state = BTA_AG_SCO_SHUTTING_ST; 807 808 break; 809 810 case BTA_AG_SCO_CONN_OPEN_E: 811 /* close sco connection */ 812 bta_ag_remove_sco(p_scb, true); 813 814 p_sco->state = BTA_AG_SCO_CLOSING_ST; 815 break; 816 817 case BTA_AG_SCO_CONN_CLOSE_E: 818 /* sco failed; create sco listen connection */ 819 820 p_sco->state = BTA_AG_SCO_LISTEN_ST; 821 break; 822 823 default: 824 APPL_TRACE_WARNING("%s: BTA_AG_SCO_OPEN_CL_ST: Ignoring event %d", 825 __func__, event); 826 break; 827 } 828 break; 829 830 case BTA_AG_SCO_OPEN_XFER_ST: 831 switch (event) { 832 case BTA_AG_SCO_CLOSE_E: 833 /* close sco connection */ 834 bta_ag_remove_sco(p_scb, true); 835 836 p_sco->state = BTA_AG_SCO_CLOSING_ST; 837 break; 838 839 case BTA_AG_SCO_SHUTDOWN_E: 840 /* remove all connection */ 841 bta_ag_remove_sco(p_scb, false); 842 p_sco->state = BTA_AG_SCO_SHUTTING_ST; 843 844 break; 845 846 case BTA_AG_SCO_CONN_CLOSE_E: 847 /* closed sco; place in listen mode and 848 accept the transferred connection */ 849 bta_ag_create_sco(p_scb, false); /* Back into listen mode */ 850 851 /* Accept sco connection with xfer scb */ 852 bta_ag_sco_conn_rsp(p_sco->p_xfer_scb, &p_sco->conn_data); 853 p_sco->state = BTA_AG_SCO_OPENING_ST; 854 p_sco->p_curr_scb = p_sco->p_xfer_scb; 855 p_sco->cur_idx = p_sco->p_xfer_scb->sco_idx; 856 p_sco->p_xfer_scb = NULL; 857 break; 858 859 default: 860 APPL_TRACE_WARNING("%s: BTA_AG_SCO_OPEN_XFER_ST: Ignoring event %d", 861 __func__, event); 862 break; 863 } 864 break; 865 866 case BTA_AG_SCO_OPEN_ST: 867 switch (event) { 868 case BTA_AG_SCO_LISTEN_E: 869 /* second headset has now joined */ 870 /* create sco listen connection (Additional channel) */ 871 if (p_scb != p_sco->p_curr_scb) { 872 bta_ag_create_sco(p_scb, false); 873 } 874 break; 875 876 case BTA_AG_SCO_XFER_E: 877 /* close current sco connection */ 878 bta_ag_remove_sco(p_sco->p_curr_scb, true); 879 880 /* save xfer scb */ 881 p_sco->p_xfer_scb = p_scb; 882 883 p_sco->state = BTA_AG_SCO_CLOSE_XFER_ST; 884 break; 885 886 case BTA_AG_SCO_CLOSE_E: 887 /* close sco connection if active */ 888 if (bta_ag_remove_sco(p_scb, true)) { 889 p_sco->state = BTA_AG_SCO_CLOSING_ST; 890 } 891 break; 892 893 case BTA_AG_SCO_SHUTDOWN_E: 894 /* remove all listening connections */ 895 bta_ag_remove_sco(p_scb, false); 896 897 /* If SCO was active on this scb, close it */ 898 if (p_scb == p_sco->p_curr_scb) { 899 p_sco->state = BTA_AG_SCO_SHUTTING_ST; 900 } 901 break; 902 903 case BTA_AG_SCO_CONN_CLOSE_E: 904 /* peer closed sco; create sco listen connection */ 905 bta_ag_create_sco(p_scb, false); 906 p_sco->state = BTA_AG_SCO_LISTEN_ST; 907 break; 908 909 default: 910 APPL_TRACE_WARNING("%s: BTA_AG_SCO_OPEN_ST: Ignoring event %d", 911 __func__, event); 912 break; 913 } 914 break; 915 916 case BTA_AG_SCO_CLOSING_ST: 917 switch (event) { 918 case BTA_AG_SCO_LISTEN_E: 919 /* create sco listen connection (Additional channel) */ 920 if (p_scb != p_sco->p_curr_scb) { 921 bta_ag_create_sco(p_scb, false); 922 } 923 break; 924 925 case BTA_AG_SCO_OPEN_E: 926 p_sco->state = BTA_AG_SCO_CLOSE_OP_ST; 927 break; 928 929 case BTA_AG_SCO_XFER_E: 930 /* save xfer scb */ 931 p_sco->p_xfer_scb = p_scb; 932 933 p_sco->state = BTA_AG_SCO_CLOSE_XFER_ST; 934 break; 935 936 case BTA_AG_SCO_SHUTDOWN_E: 937 /* If not closing scb, just close it */ 938 if (p_scb != p_sco->p_curr_scb) { 939 /* remove listening connection */ 940 bta_ag_remove_sco(p_scb, false); 941 } else 942 p_sco->state = BTA_AG_SCO_SHUTTING_ST; 943 944 break; 945 946 case BTA_AG_SCO_CONN_CLOSE_E: 947 /* peer closed sco; create sco listen connection */ 948 bta_ag_create_sco(p_scb, false); 949 950 p_sco->state = BTA_AG_SCO_LISTEN_ST; 951 break; 952 953 default: 954 APPL_TRACE_WARNING("%s: BTA_AG_SCO_CLOSING_ST: Ignoring event %d", 955 __func__, event); 956 break; 957 } 958 break; 959 960 case BTA_AG_SCO_CLOSE_OP_ST: 961 switch (event) { 962 case BTA_AG_SCO_CLOSE_E: 963 p_sco->state = BTA_AG_SCO_CLOSING_ST; 964 break; 965 966 case BTA_AG_SCO_SHUTDOWN_E: 967 p_sco->state = BTA_AG_SCO_SHUTTING_ST; 968 break; 969 970 case BTA_AG_SCO_CONN_CLOSE_E: 971 /* start codec negotiation */ 972 p_sco->state = BTA_AG_SCO_CODEC_ST; 973 bta_ag_codec_negotiate(p_scb); 974 break; 975 976 case BTA_AG_SCO_LISTEN_E: 977 /* create sco listen connection (Additional channel) */ 978 if (p_scb != p_sco->p_curr_scb) { 979 bta_ag_create_sco(p_scb, false); 980 } 981 break; 982 983 default: 984 APPL_TRACE_WARNING("%s: BTA_AG_SCO_CLOSE_OP_ST: Ignoring event %d", 985 __func__, event); 986 break; 987 } 988 break; 989 990 case BTA_AG_SCO_CLOSE_XFER_ST: 991 switch (event) { 992 case BTA_AG_SCO_CONN_OPEN_E: 993 /* close sco connection so headset can be transferred 994 Probably entered this state from "opening state" */ 995 bta_ag_remove_sco(p_scb, true); 996 break; 997 998 case BTA_AG_SCO_CLOSE_E: 999 /* clear xfer scb */ 1000 p_sco->p_xfer_scb = NULL; 1001 1002 p_sco->state = BTA_AG_SCO_CLOSING_ST; 1003 break; 1004 1005 case BTA_AG_SCO_SHUTDOWN_E: 1006 /* clear xfer scb */ 1007 p_sco->p_xfer_scb = NULL; 1008 1009 p_sco->state = BTA_AG_SCO_SHUTTING_ST; 1010 break; 1011 1012 case BTA_AG_SCO_CONN_CLOSE_E: { 1013 /* closed sco; place old sco in listen mode, 1014 take current sco out of listen, and 1015 create originating sco for current */ 1016 bta_ag_create_sco(p_scb, false); 1017 bta_ag_remove_sco(p_sco->p_xfer_scb, false); 1018 1019 /* start codec negotiation */ 1020 p_sco->state = BTA_AG_SCO_CODEC_ST; 1021 tBTA_AG_SCB* p_cn_scb = p_sco->p_xfer_scb; 1022 p_sco->p_xfer_scb = NULL; 1023 bta_ag_codec_negotiate(p_cn_scb); 1024 break; 1025 } 1026 1027 default: 1028 APPL_TRACE_WARNING("%s: BTA_AG_SCO_CLOSE_XFER_ST: Ignoring event %d", 1029 __func__, event); 1030 break; 1031 } 1032 break; 1033 1034 case BTA_AG_SCO_SHUTTING_ST: 1035 switch (event) { 1036 case BTA_AG_SCO_CONN_OPEN_E: 1037 /* close sco connection; wait for conn close event */ 1038 bta_ag_remove_sco(p_scb, true); 1039 break; 1040 1041 case BTA_AG_SCO_CONN_CLOSE_E: 1042 /* If last SCO instance then finish shutting down */ 1043 if (!bta_ag_other_scb_open(p_scb)) { 1044 p_sco->state = BTA_AG_SCO_SHUTDOWN_ST; 1045 } else /* Other instance is still listening */ 1046 { 1047 p_sco->state = BTA_AG_SCO_LISTEN_ST; 1048 } 1049 1050 /* If SCO closed for other HS which is not being disconnected, 1051 then create listen sco connection for it as scb still open */ 1052 if (bta_ag_scb_open(p_scb)) { 1053 bta_ag_create_sco(p_scb, false); 1054 p_sco->state = BTA_AG_SCO_LISTEN_ST; 1055 } 1056 1057 if (p_scb == p_sco->p_curr_scb) { 1058 p_sco->p_curr_scb->sco_idx = BTM_INVALID_SCO_INDEX; 1059 p_sco->p_curr_scb = NULL; 1060 } 1061 break; 1062 1063 case BTA_AG_SCO_LISTEN_E: 1064 /* create sco listen connection (Additional channel) */ 1065 if (p_scb != p_sco->p_curr_scb) { 1066 bta_ag_create_sco(p_scb, false); 1067 } 1068 break; 1069 1070 case BTA_AG_SCO_SHUTDOWN_E: 1071 if (!bta_ag_other_scb_open(p_scb)) { 1072 p_sco->state = BTA_AG_SCO_SHUTDOWN_ST; 1073 } else /* Other instance is still listening */ 1074 { 1075 p_sco->state = BTA_AG_SCO_LISTEN_ST; 1076 } 1077 1078 if (p_scb == p_sco->p_curr_scb) { 1079 p_sco->p_curr_scb->sco_idx = BTM_INVALID_SCO_INDEX; 1080 p_sco->p_curr_scb = NULL; 1081 } 1082 break; 1083 1084 default: 1085 APPL_TRACE_WARNING("%s: BTA_AG_SCO_SHUTTING_ST: Ignoring event %d", 1086 __func__, event); 1087 break; 1088 } 1089 break; 1090 1091 default: 1092 break; 1093 } 1094 #if (BTA_AG_SCO_DEBUG == TRUE) 1095 if (p_sco->state != in_state) { 1096 APPL_TRACE_EVENT("BTA AG SCO State Change: [%s] -> [%s] after Event [%s]", 1097 bta_ag_sco_state_str(in_state), 1098 bta_ag_sco_state_str(p_sco->state), 1099 bta_ag_sco_evt_str(event)); 1100 } 1101 #endif 1102 } 1103 1104 /******************************************************************************* 1105 * 1106 * Function bta_ag_sco_is_open 1107 * 1108 * Description Check if sco is open for this scb. 1109 * 1110 * 1111 * Returns true if sco open for this scb, false otherwise. 1112 * 1113 ******************************************************************************/ 1114 bool bta_ag_sco_is_open(tBTA_AG_SCB* p_scb) { 1115 return ((bta_ag_cb.sco.state == BTA_AG_SCO_OPEN_ST) && 1116 (bta_ag_cb.sco.p_curr_scb == p_scb)); 1117 } 1118 1119 /******************************************************************************* 1120 * 1121 * Function bta_ag_sco_is_opening 1122 * 1123 * Description Check if sco is in Opening state. 1124 * 1125 * 1126 * Returns true if sco is in Opening state for this scb, false 1127 * otherwise. 1128 * 1129 ******************************************************************************/ 1130 bool bta_ag_sco_is_opening(tBTA_AG_SCB* p_scb) { 1131 return ((bta_ag_cb.sco.state == BTA_AG_SCO_OPENING_ST) && 1132 (bta_ag_cb.sco.p_curr_scb == p_scb)); 1133 } 1134 1135 /******************************************************************************* 1136 * 1137 * Function bta_ag_sco_listen 1138 * 1139 * Description 1140 * 1141 * 1142 * Returns void 1143 * 1144 ******************************************************************************/ 1145 void bta_ag_sco_listen(tBTA_AG_SCB* p_scb, UNUSED_ATTR tBTA_AG_DATA* p_data) { 1146 bta_ag_sco_event(p_scb, BTA_AG_SCO_LISTEN_E); 1147 } 1148 1149 /******************************************************************************* 1150 * 1151 * Function bta_ag_sco_open 1152 * 1153 * Description 1154 * 1155 * 1156 * Returns void 1157 * 1158 ******************************************************************************/ 1159 void bta_ag_sco_open(tBTA_AG_SCB* p_scb, UNUSED_ATTR tBTA_AG_DATA* p_data) { 1160 uint8_t event; 1161 1162 if (!sco_allowed) { 1163 APPL_TRACE_DEBUG("%s not opening sco, by policy", __func__); 1164 return; 1165 } 1166 1167 /* if another scb using sco, this is a transfer */ 1168 if (bta_ag_cb.sco.p_curr_scb != NULL && bta_ag_cb.sco.p_curr_scb != p_scb) { 1169 event = BTA_AG_SCO_XFER_E; 1170 } 1171 /* else it is an open */ 1172 else { 1173 event = BTA_AG_SCO_OPEN_E; 1174 } 1175 1176 bta_ag_sco_event(p_scb, event); 1177 } 1178 1179 /******************************************************************************* 1180 * 1181 * Function bta_ag_sco_close 1182 * 1183 * Description 1184 * 1185 * 1186 * Returns void 1187 * 1188 ******************************************************************************/ 1189 void bta_ag_sco_close(tBTA_AG_SCB* p_scb, UNUSED_ATTR tBTA_AG_DATA* p_data) { 1190 /* if scb is in use */ 1191 /* sco_idx is not allocated in SCO_CODEC_ST, still need to move to listen 1192 * state. */ 1193 if ((p_scb->sco_idx != BTM_INVALID_SCO_INDEX) || 1194 (bta_ag_cb.sco.state == BTA_AG_SCO_CODEC_ST)) 1195 { 1196 APPL_TRACE_DEBUG("bta_ag_sco_close: sco_inx = %d", p_scb->sco_idx); 1197 bta_ag_sco_event(p_scb, BTA_AG_SCO_CLOSE_E); 1198 } 1199 } 1200 1201 /******************************************************************************* 1202 * 1203 * Function bta_ag_sco_codec_nego 1204 * 1205 * Description Handles result of eSCO codec negotiation 1206 * 1207 * 1208 * Returns void 1209 * 1210 ******************************************************************************/ 1211 void bta_ag_sco_codec_nego(tBTA_AG_SCB* p_scb, bool result) { 1212 if (result == true) { 1213 /* Subsequent SCO connection will skip codec negotiation */ 1214 APPL_TRACE_DEBUG("%s: Succeeded for index 0x%04x", __func__, 1215 p_scb->sco_idx); 1216 p_scb->codec_updated = false; 1217 bta_ag_sco_event(p_scb, BTA_AG_SCO_CN_DONE_E); 1218 } else { 1219 /* codec negotiation failed */ 1220 APPL_TRACE_ERROR("%s: Failed for index 0x%04x", __func__, p_scb->sco_idx); 1221 bta_ag_sco_event(p_scb, BTA_AG_SCO_CLOSE_E); 1222 } 1223 } 1224 1225 /******************************************************************************* 1226 * 1227 * Function bta_ag_sco_shutdown 1228 * 1229 * Description 1230 * 1231 * 1232 * Returns void 1233 * 1234 ******************************************************************************/ 1235 void bta_ag_sco_shutdown(tBTA_AG_SCB* p_scb, UNUSED_ATTR tBTA_AG_DATA* p_data) { 1236 bta_ag_sco_event(p_scb, BTA_AG_SCO_SHUTDOWN_E); 1237 } 1238 1239 /******************************************************************************* 1240 * 1241 * Function bta_ag_sco_conn_open 1242 * 1243 * Description 1244 * 1245 * 1246 * Returns void 1247 * 1248 ******************************************************************************/ 1249 void bta_ag_sco_conn_open(tBTA_AG_SCB* p_scb, 1250 UNUSED_ATTR tBTA_AG_DATA* p_data) { 1251 bta_ag_sco_event(p_scb, BTA_AG_SCO_CONN_OPEN_E); 1252 1253 bta_sys_sco_open(BTA_ID_AG, p_scb->app_id, p_scb->peer_addr); 1254 1255 #if (BTM_SCO_HCI_INCLUDED == TRUE) 1256 /* open SCO codec if SCO is routed through transport */ 1257 bta_dm_sco_co_open(bta_ag_scb_to_idx(p_scb), BTA_SCO_OUT_PKT_SIZE, 1258 BTA_AG_CI_SCO_DATA_EVT); 1259 #endif 1260 1261 /* call app callback */ 1262 bta_ag_cback_sco(p_scb, BTA_AG_AUDIO_OPEN_EVT); 1263 1264 /* reset to mSBC T2 settings as the preferred */ 1265 p_scb->codec_msbc_settings = BTA_AG_SCO_MSBC_SETTINGS_T2; 1266 } 1267 1268 /******************************************************************************* 1269 * 1270 * Function bta_ag_sco_conn_close 1271 * 1272 * Description 1273 * 1274 * 1275 * Returns void 1276 * 1277 ******************************************************************************/ 1278 void bta_ag_sco_conn_close(tBTA_AG_SCB* p_scb, 1279 UNUSED_ATTR tBTA_AG_DATA* p_data) { 1280 /* clear current scb */ 1281 bta_ag_cb.sco.p_curr_scb = NULL; 1282 p_scb->sco_idx = BTM_INVALID_SCO_INDEX; 1283 1284 /* codec_fallback is set when AG is initiator and connection failed for mSBC. 1285 * OR if codec is msbc and T2 settings failed, then retry Safe T1 settings */ 1286 if (p_scb->svc_conn && 1287 (p_scb->codec_fallback || 1288 (p_scb->sco_codec == BTM_SCO_CODEC_MSBC && 1289 p_scb->codec_msbc_settings == BTA_AG_SCO_MSBC_SETTINGS_T1))) { 1290 bta_ag_sco_event(p_scb, BTA_AG_SCO_REOPEN_E); 1291 } else { 1292 /* Indicate if the closing of audio is because of transfer */ 1293 bta_ag_sco_event(p_scb, BTA_AG_SCO_CONN_CLOSE_E); 1294 1295 bta_sys_sco_close(BTA_ID_AG, p_scb->app_id, p_scb->peer_addr); 1296 1297 /* if av got suspended by this call, let it resume. */ 1298 /* In case call stays alive regardless of sco, av should not be affected. */ 1299 if (((p_scb->call_ind == BTA_AG_CALL_INACTIVE) && 1300 (p_scb->callsetup_ind == BTA_AG_CALLSETUP_NONE)) || 1301 (p_scb->post_sco == BTA_AG_POST_SCO_CALL_END)) { 1302 bta_sys_sco_unuse(BTA_ID_AG, p_scb->app_id, p_scb->peer_addr); 1303 } 1304 1305 /* call app callback */ 1306 bta_ag_cback_sco(p_scb, BTA_AG_AUDIO_CLOSE_EVT); 1307 p_scb->codec_msbc_settings = BTA_AG_SCO_MSBC_SETTINGS_T2; 1308 } 1309 } 1310 1311 /******************************************************************************* 1312 * 1313 * Function bta_ag_sco_conn_rsp 1314 * 1315 * Description Process the SCO connection request 1316 * 1317 * 1318 * Returns void 1319 * 1320 ******************************************************************************/ 1321 void bta_ag_sco_conn_rsp(tBTA_AG_SCB* p_scb, 1322 tBTM_ESCO_CONN_REQ_EVT_DATA* p_data) { 1323 bta_ag_cb.sco.is_local = false; 1324 1325 APPL_TRACE_DEBUG("%s: eSCO %d, state %d", __func__, 1326 controller_get_interface() 1327 ->supports_enhanced_setup_synchronous_connection(), 1328 bta_ag_cb.sco.state); 1329 1330 if (bta_ag_cb.sco.state == BTA_AG_SCO_LISTEN_ST || 1331 bta_ag_cb.sco.state == BTA_AG_SCO_CLOSE_XFER_ST || 1332 bta_ag_cb.sco.state == BTA_AG_SCO_OPEN_XFER_ST) { 1333 /* tell sys to stop av if any */ 1334 bta_sys_sco_use(BTA_ID_AG, p_scb->app_id, p_scb->peer_addr); 1335 /* When HS initiated SCO, it cannot be WBS. */ 1336 #if (BTM_SCO_HCI_INCLUDED == TRUE) 1337 /* Configure the transport being used */ 1338 BTM_ConfigScoPath(resp.input_data_path, bta_ag_sco_read_cback, NULL, TRUE); 1339 #endif 1340 } 1341 1342 /* If SCO open was initiated from HS, it must be CVSD */ 1343 p_scb->inuse_codec = BTA_AG_CODEC_NONE; 1344 /* Send pending commands to create SCO connection to peer */ 1345 bta_ag_create_pending_sco(p_scb, bta_ag_cb.sco.is_local); 1346 } 1347 1348 /******************************************************************************* 1349 * 1350 * Function bta_ag_ci_sco_data 1351 * 1352 * Description Process the SCO data ready callin event 1353 * 1354 * 1355 * Returns void 1356 * 1357 ******************************************************************************/ 1358 void bta_ag_ci_sco_data(UNUSED_ATTR tBTA_AG_SCB* p_scb, 1359 UNUSED_ATTR tBTA_AG_DATA* p_data) { 1360 #if (BTM_SCO_HCI_INCLUDED == TRUE) 1361 bta_ag_sco_event(p_scb, BTA_AG_SCO_CI_DATA_E); 1362 #endif 1363 } 1364 1365 void bta_ag_set_sco_allowed(tBTA_AG_DATA* p_data) { 1366 sco_allowed = ((tBTA_AG_API_SET_SCO_ALLOWED*)p_data)->value; 1367 APPL_TRACE_DEBUG(sco_allowed ? "sco now allowed" : "sco now not allowed"); 1368 } 1369 1370 /******************************************************************************* 1371 * Debugging functions 1372 ******************************************************************************/ 1373 1374 #if (BTA_AG_SCO_DEBUG == TRUE) 1375 static char* bta_ag_sco_evt_str(uint8_t event) { 1376 switch (event) { 1377 case BTA_AG_SCO_LISTEN_E: 1378 return "Listen Request"; 1379 case BTA_AG_SCO_OPEN_E: 1380 return "Open Request"; 1381 case BTA_AG_SCO_XFER_E: 1382 return "Transfer Request"; 1383 case BTA_AG_SCO_CN_DONE_E: 1384 return "Codec Negotiation Done"; 1385 case BTA_AG_SCO_REOPEN_E: 1386 return "Reopen Request"; 1387 case BTA_AG_SCO_CLOSE_E: 1388 return "Close Request"; 1389 case BTA_AG_SCO_SHUTDOWN_E: 1390 return "Shutdown Request"; 1391 case BTA_AG_SCO_CONN_OPEN_E: 1392 return "Opened"; 1393 case BTA_AG_SCO_CONN_CLOSE_E: 1394 return "Closed"; 1395 case BTA_AG_SCO_CI_DATA_E: 1396 return "Sco Data"; 1397 default: 1398 return "Unknown SCO Event"; 1399 } 1400 } 1401 1402 static char* bta_ag_sco_state_str(uint8_t state) { 1403 switch (state) { 1404 case BTA_AG_SCO_SHUTDOWN_ST: 1405 return "Shutdown"; 1406 case BTA_AG_SCO_LISTEN_ST: 1407 return "Listening"; 1408 case BTA_AG_SCO_CODEC_ST: 1409 return "Codec Negotiation"; 1410 case BTA_AG_SCO_OPENING_ST: 1411 return "Opening"; 1412 case BTA_AG_SCO_OPEN_CL_ST: 1413 return "Open while closing"; 1414 case BTA_AG_SCO_OPEN_XFER_ST: 1415 return "Opening while Transferring"; 1416 case BTA_AG_SCO_OPEN_ST: 1417 return "Open"; 1418 case BTA_AG_SCO_CLOSING_ST: 1419 return "Closing"; 1420 case BTA_AG_SCO_CLOSE_OP_ST: 1421 return "Close while Opening"; 1422 case BTA_AG_SCO_CLOSE_XFER_ST: 1423 return "Close while Transferring"; 1424 case BTA_AG_SCO_SHUTTING_ST: 1425 return "Shutting Down"; 1426 default: 1427 return "Unknown SCO State"; 1428 } 1429 } 1430 1431 #endif /* (BTA_AG_SCO_DEBUG) */ 1432