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