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 "bta_api.h" 26 #include "bta_ag_api.h" 27 #include "bta_ag_co.h" 28 #if (BTM_SCO_HCI_INCLUDED == TRUE ) 29 #include "bta_dm_co.h" 30 #endif 31 #include "bta_ag_int.h" 32 #include "btm_api.h" 33 #include "gki.h" 34 #include "utl.h" 35 36 #ifndef BTA_AG_SCO_DEBUG 37 #define BTA_AG_SCO_DEBUG FALSE 38 #endif 39 40 #ifndef BTA_AG_CODEC_NEGO_TIMEOUT 41 #define BTA_AG_CODEC_NEGO_TIMEOUT 3000 42 #endif 43 44 #if BTA_AG_SCO_DEBUG == TRUE 45 static char *bta_ag_sco_evt_str(UINT8 event); 46 static char *bta_ag_sco_state_str(UINT8 state); 47 #endif 48 49 #define BTA_AG_NO_EDR_ESCO (BTM_SCO_PKT_TYPES_MASK_NO_2_EV3 | \ 50 BTM_SCO_PKT_TYPES_MASK_NO_3_EV3 | \ 51 BTM_SCO_PKT_TYPES_MASK_NO_2_EV5 | \ 52 BTM_SCO_PKT_TYPES_MASK_NO_3_EV5) 53 54 /* sco events */ 55 enum 56 { 57 BTA_AG_SCO_LISTEN_E, /* listen request */ 58 BTA_AG_SCO_OPEN_E, /* open request */ 59 BTA_AG_SCO_XFER_E, /* transfer request */ 60 #if (BTM_WBS_INCLUDED == TRUE ) 61 BTA_AG_SCO_CN_DONE_E, /* codec negotiation done */ 62 BTA_AG_SCO_REOPEN_E, /* Retry with other codec when failed */ 63 #endif 64 BTA_AG_SCO_CLOSE_E, /* close request */ 65 BTA_AG_SCO_SHUTDOWN_E, /* shutdown request */ 66 BTA_AG_SCO_CONN_OPEN_E, /* sco open */ 67 BTA_AG_SCO_CONN_CLOSE_E, /* sco closed */ 68 BTA_AG_SCO_CI_DATA_E /* SCO data ready */ 69 }; 70 71 #if (BTM_WBS_INCLUDED == TRUE ) 72 #define BTA_AG_NUM_CODECS 3 73 #define BTA_AG_ESCO_SETTING_IDX_CVSD 0 /* eSCO setting for CVSD */ 74 #define BTA_AG_ESCO_SETTING_IDX_T1 1 /* eSCO setting for mSBC T1 */ 75 #define BTA_AG_ESCO_SETTING_IDX_T2 2 /* eSCO setting for mSBC T2 */ 76 77 static const tBTM_ESCO_PARAMS bta_ag_esco_params[BTA_AG_NUM_CODECS] = 78 { 79 /* CVSD */ 80 { 81 BTM_64KBITS_RATE, /* TX Bandwidth (64 kbits/sec) */ 82 BTM_64KBITS_RATE, /* RX Bandwidth (64 kbits/sec) */ 83 0x000a, /* 10 ms (HS/HF can use EV3, 2-EV3, 3-EV3) */ 84 BTM_VOICE_SETTING_CVSD, /* Inp Linear, Air CVSD, 2s Comp, 16bit */ 85 (BTM_SCO_PKT_TYPES_MASK_HV1 + /* Packet Types */ 86 BTM_SCO_PKT_TYPES_MASK_HV2 + 87 BTM_SCO_PKT_TYPES_MASK_HV3 + 88 BTM_SCO_PKT_TYPES_MASK_EV3 + 89 BTM_SCO_PKT_TYPES_MASK_EV4 + 90 BTM_SCO_PKT_TYPES_MASK_EV5 + 91 BTM_SCO_PKT_TYPES_MASK_NO_2_EV5 + 92 BTM_SCO_PKT_TYPES_MASK_NO_3_EV5), 93 BTM_ESCO_RETRANS_POWER /* Retransmission effort */ 94 }, 95 /* mSBC T1 */ 96 { 97 BTM_64KBITS_RATE, /* TX Bandwidth (64 kbits/sec), 8000 */ 98 BTM_64KBITS_RATE, /* RX Bandwidth (64 kbits/sec), 8000 */ 99 8, /* 8 ms */ 100 BTM_VOICE_SETTING_TRANS, /* Inp Linear, Transparent, 2s Comp, 16bit */ 101 (BTM_SCO_PKT_TYPES_MASK_EV3 | /* Packet Types : EV3 + NO_2_EV3 */ 102 BTM_SCO_PKT_TYPES_MASK_NO_3_EV3 | 103 BTM_SCO_PKT_TYPES_MASK_NO_2_EV5 | 104 BTM_SCO_PKT_TYPES_MASK_NO_3_EV5 | 105 BTM_SCO_PKT_TYPES_MASK_NO_2_EV3 ), 106 BTM_ESCO_RETRANS_QUALITY /* Retransmission effort */ 107 }, 108 /* mSBC T2*/ 109 { 110 BTM_64KBITS_RATE, /* TX Bandwidth (64 kbits/sec), 8000 */ 111 BTM_64KBITS_RATE, /* RX Bandwidth (64 kbits/sec), 8000 */ 112 13, /* 13 ms */ 113 BTM_VOICE_SETTING_TRANS, /* Inp Linear, Transparent, 2s Comp, 16bit */ 114 (BTM_SCO_PKT_TYPES_MASK_EV3 | /* Packet Types : EV3 + 2-EV3 */ 115 BTM_SCO_PKT_TYPES_MASK_NO_3_EV3 | 116 BTM_SCO_PKT_TYPES_MASK_NO_2_EV5 | 117 BTM_SCO_PKT_TYPES_MASK_NO_3_EV5), 118 BTM_ESCO_RETRANS_QUALITY /* Retransmission effort */ 119 } 120 }; 121 #else 122 /* WBS not included, CVSD by default */ 123 static const tBTM_ESCO_PARAMS bta_ag_esco_params = 124 { 125 BTM_64KBITS_RATE, /* TX Bandwidth (64 kbits/sec) */ 126 BTM_64KBITS_RATE, /* RX Bandwidth (64 kbits/sec) */ 127 0x000a, /* 10 ms (HS/HF can use EV3, 2-EV3, 3-EV3) */ 128 0x0060, /* Inp Linear, Air CVSD, 2s Comp, 16bit */ 129 (BTM_SCO_PKT_TYPES_MASK_HV1 + /* Packet Types */ 130 BTM_SCO_PKT_TYPES_MASK_HV2 + 131 BTM_SCO_PKT_TYPES_MASK_HV3 + 132 BTM_SCO_PKT_TYPES_MASK_EV3 + 133 BTM_SCO_PKT_TYPES_MASK_EV4 + 134 BTM_SCO_PKT_TYPES_MASK_EV5 + 135 BTM_SCO_PKT_TYPES_MASK_NO_2_EV5 + 136 BTM_SCO_PKT_TYPES_MASK_NO_3_EV5), 137 BTM_ESCO_RETRANS_POWER /* Retransmission effort */ 138 }; 139 #endif 140 141 /******************************************************************************* 142 ** 143 ** Function bta_ag_sco_conn_cback 144 ** 145 ** Description BTM SCO connection callback. 146 ** 147 ** 148 ** Returns void 149 ** 150 *******************************************************************************/ 151 static void bta_ag_sco_conn_cback(UINT16 sco_idx) 152 { 153 UINT16 handle; 154 BT_HDR *p_buf; 155 tBTA_AG_SCB *p_scb; 156 157 /* match callback to scb; first check current sco scb */ 158 if (bta_ag_cb.sco.p_curr_scb != NULL && bta_ag_cb.sco.p_curr_scb->in_use) 159 { 160 handle = bta_ag_scb_to_idx(bta_ag_cb.sco.p_curr_scb); 161 } 162 /* then check for scb connected to this peer */ 163 else 164 { 165 /* Check if SLC is up */ 166 handle = bta_ag_idx_by_bdaddr(BTM_ReadScoBdAddr(sco_idx)); 167 p_scb = bta_ag_scb_by_idx(handle); 168 if(p_scb && !p_scb->svc_conn) 169 handle = 0; 170 } 171 172 if (handle != 0) 173 { 174 if ((p_buf = (BT_HDR *) GKI_getbuf(sizeof(BT_HDR))) != NULL) 175 { 176 p_buf->event = BTA_AG_SCO_OPEN_EVT; 177 p_buf->layer_specific = handle; 178 bta_sys_sendmsg(p_buf); 179 } 180 } 181 /* no match found; disconnect sco, init sco variables */ 182 else 183 { 184 bta_ag_cb.sco.p_curr_scb = NULL; 185 bta_ag_cb.sco.state = BTA_AG_SCO_SHUTDOWN_ST; 186 BTM_RemoveSco(sco_idx); 187 } 188 } 189 190 /******************************************************************************* 191 ** 192 ** Function bta_ag_sco_disc_cback 193 ** 194 ** Description BTM SCO disconnection callback. 195 ** 196 ** 197 ** Returns void 198 ** 199 *******************************************************************************/ 200 static void bta_ag_sco_disc_cback(UINT16 sco_idx) 201 { 202 BT_HDR *p_buf; 203 UINT16 handle = 0; 204 205 APPL_TRACE_DEBUG ("bta_ag_sco_disc_cback(): sco_idx: 0x%x p_cur_scb: 0x%08x sco.state: %d", sco_idx, bta_ag_cb.sco.p_curr_scb, bta_ag_cb.sco.state); 206 207 APPL_TRACE_DEBUG ("bta_ag_sco_disc_cback(): scb[0] addr: 0x%08x in_use: %u sco_idx: 0x%x sco state: %u", 208 &bta_ag_cb.scb[0], bta_ag_cb.scb[0].in_use, bta_ag_cb.scb[0].sco_idx, bta_ag_cb.scb[0].state); 209 APPL_TRACE_DEBUG ("bta_ag_sco_disc_cback(): scb[1] addr: 0x%08x in_use: %u sco_idx: 0x%x sco state: %u", 210 &bta_ag_cb.scb[1], bta_ag_cb.scb[1].in_use, bta_ag_cb.scb[1].sco_idx, bta_ag_cb.scb[1].state); 211 212 /* match callback to scb */ 213 if (bta_ag_cb.sco.p_curr_scb != NULL && bta_ag_cb.sco.p_curr_scb->in_use) 214 { 215 /* We only care about callbacks for the active SCO */ 216 if (bta_ag_cb.sco.p_curr_scb->sco_idx != sco_idx) 217 { 218 if (bta_ag_cb.sco.p_curr_scb->sco_idx != 0xFFFF) 219 return; 220 } 221 handle = bta_ag_scb_to_idx(bta_ag_cb.sco.p_curr_scb); 222 } 223 224 if (handle != 0) 225 { 226 #if (BTM_SCO_HCI_INCLUDED == TRUE ) 227 tBTM_STATUS status = BTM_ConfigScoPath(BTM_SCO_ROUTE_PCM, NULL, NULL, TRUE); 228 APPL_TRACE_DEBUG("bta_ag_sco_disc_cback sco close config status = %d", status); 229 /* SCO clean up here */ 230 bta_dm_sco_co_close(); 231 #endif 232 233 #if (BTM_WBS_INCLUDED == TRUE ) 234 /* Restore settings */ 235 if(bta_ag_cb.sco.p_curr_scb->inuse_codec == BTA_AG_CODEC_MSBC) 236 { 237 /* set_sco_codec(BTM_SCO_CODEC_NONE); we should get a close */ 238 BTM_WriteVoiceSettings (BTM_VOICE_SETTING_CVSD); 239 240 /* If SCO open was initiated by AG and failed for mSBC, then attempt 241 mSBC with T1 settings i.e. 'Safe Settings'. If this fails, then switch to CVSD */ 242 if (bta_ag_sco_is_opening (bta_ag_cb.sco.p_curr_scb)) 243 { 244 if (bta_ag_cb.sco.p_curr_scb->codec_msbc_settings == BTA_AG_SCO_MSBC_SETTINGS_T2) 245 { 246 APPL_TRACE_DEBUG("Fallback to mSBC T1 settings"); 247 bta_ag_cb.sco.p_curr_scb->codec_msbc_settings = BTA_AG_SCO_MSBC_SETTINGS_T1; 248 } 249 else 250 { 251 APPL_TRACE_DEBUG("Fallback to CVSD settings"); 252 bta_ag_cb.sco.p_curr_scb->codec_fallback = TRUE; 253 } 254 } 255 } 256 257 bta_ag_cb.sco.p_curr_scb->inuse_codec = BTA_AG_CODEC_NONE; 258 #endif 259 260 if ((p_buf = (BT_HDR *) GKI_getbuf(sizeof(BT_HDR))) != NULL) 261 { 262 p_buf->event = BTA_AG_SCO_CLOSE_EVT; 263 p_buf->layer_specific = handle; 264 bta_sys_sendmsg(p_buf); 265 } 266 } 267 /* no match found */ 268 else 269 { 270 APPL_TRACE_DEBUG("no scb for ag_sco_disc_cback"); 271 272 /* sco could be closed after scb dealloc'ed */ 273 if (bta_ag_cb.sco.p_curr_scb != NULL) 274 { 275 bta_ag_cb.sco.p_curr_scb->sco_idx = BTM_INVALID_SCO_INDEX; 276 bta_ag_cb.sco.p_curr_scb = NULL; 277 bta_ag_cb.sco.state = BTA_AG_SCO_SHUTDOWN_ST; 278 } 279 } 280 } 281 #if (BTM_SCO_HCI_INCLUDED == TRUE ) 282 /******************************************************************************* 283 ** 284 ** Function bta_ag_sco_read_cback 285 ** 286 ** Description Callback function is the callback function for incoming 287 ** SCO data over HCI. 288 ** 289 ** Returns void 290 ** 291 *******************************************************************************/ 292 static void bta_ag_sco_read_cback (UINT16 sco_inx, BT_HDR *p_data, tBTM_SCO_DATA_FLAG status) 293 { 294 if (status != BTM_SCO_DATA_CORRECT) 295 { 296 APPL_TRACE_DEBUG("bta_ag_sco_read_cback: status(%d)", status); 297 } 298 299 /* Callout function must free the data. */ 300 bta_dm_sco_co_in_data (p_data, status); 301 } 302 #endif 303 /******************************************************************************* 304 ** 305 ** Function bta_ag_remove_sco 306 ** 307 ** Description Removes the specified SCO from the system. 308 ** If only_active is TRUE, then SCO is only removed if connected 309 ** 310 ** Returns BOOLEAN - TRUE if Sco removal was started 311 ** 312 *******************************************************************************/ 313 static BOOLEAN bta_ag_remove_sco(tBTA_AG_SCB *p_scb, BOOLEAN only_active) 314 { 315 BOOLEAN removed_started = FALSE; 316 tBTM_STATUS status; 317 318 if (p_scb->sco_idx != BTM_INVALID_SCO_INDEX) 319 { 320 if (!only_active || p_scb->sco_idx == bta_ag_cb.sco.cur_idx) 321 { 322 status = BTM_RemoveSco(p_scb->sco_idx); 323 324 APPL_TRACE_DEBUG("ag remove sco: inx 0x%04x, status:0x%x", p_scb->sco_idx, status); 325 326 if (status == BTM_CMD_STARTED) 327 { 328 /* Sco is connected; set current control block */ 329 bta_ag_cb.sco.p_curr_scb = p_scb; 330 331 removed_started = TRUE; 332 } 333 /* If no connection reset the sco handle */ 334 else if ( (status == BTM_SUCCESS) || (status == BTM_UNKNOWN_ADDR) ) 335 { 336 p_scb->sco_idx = BTM_INVALID_SCO_INDEX; 337 } 338 } 339 } 340 return removed_started; 341 } 342 343 344 /******************************************************************************* 345 ** 346 ** Function bta_ag_esco_connreq_cback 347 ** 348 ** Description BTM eSCO connection requests and eSCO change requests 349 ** Only the connection requests are processed by BTA. 350 ** 351 ** Returns void 352 ** 353 *******************************************************************************/ 354 static void bta_ag_esco_connreq_cback(tBTM_ESCO_EVT event, tBTM_ESCO_EVT_DATA *p_data) 355 { 356 tBTA_AG_SCB *p_scb; 357 UINT16 handle; 358 UINT16 sco_inx = p_data->conn_evt.sco_inx; 359 360 /* Only process connection requests */ 361 if (event == BTM_ESCO_CONN_REQ_EVT) 362 { 363 if ((handle = bta_ag_idx_by_bdaddr(BTM_ReadScoBdAddr(sco_inx))) != 0 && 364 ((p_scb = bta_ag_scb_by_idx(handle)) != NULL) && p_scb->svc_conn) 365 { 366 p_scb->sco_idx = sco_inx; 367 368 /* If no other SCO active, allow this one */ 369 if (!bta_ag_cb.sco.p_curr_scb) 370 { 371 APPL_TRACE_EVENT("bta_ag_esco_connreq_cback: Accept Conn Request (sco_inx 0x%04x)", sco_inx); 372 bta_ag_sco_conn_rsp(p_scb, &p_data->conn_evt); 373 374 bta_ag_cb.sco.state = BTA_AG_SCO_OPENING_ST; 375 bta_ag_cb.sco.p_curr_scb = p_scb; 376 bta_ag_cb.sco.cur_idx = p_scb->sco_idx; 377 } 378 else /* Begin a transfer: Close current SCO before responding */ 379 { 380 APPL_TRACE_DEBUG("bta_ag_esco_connreq_cback: Begin XFER"); 381 bta_ag_cb.sco.p_xfer_scb = p_scb; 382 bta_ag_cb.sco.conn_data = p_data->conn_evt; 383 bta_ag_cb.sco.state = BTA_AG_SCO_OPEN_XFER_ST; 384 385 if (!bta_ag_remove_sco(bta_ag_cb.sco.p_curr_scb, TRUE)) 386 { 387 APPL_TRACE_ERROR("bta_ag_esco_connreq_cback: Nothing to remove so accept Conn Request (sco_inx 0x%04x)", sco_inx); 388 bta_ag_cb.sco.p_xfer_scb = NULL; 389 bta_ag_cb.sco.state = BTA_AG_SCO_LISTEN_ST; 390 391 bta_ag_sco_conn_rsp(p_scb, &p_data->conn_evt); 392 } 393 } 394 } 395 /* If error occurred send reject response immediately */ 396 else 397 { 398 APPL_TRACE_WARNING("no scb for bta_ag_esco_connreq_cback or no resources"); 399 BTM_EScoConnRsp(p_data->conn_evt.sco_inx, HCI_ERR_HOST_REJECT_RESOURCES, NULL); 400 } 401 } 402 /* Received a change in the esco link */ 403 else if (event == BTM_ESCO_CHG_EVT) 404 { 405 APPL_TRACE_EVENT("eSCO change event (inx %d): rtrans %d, rxlen %d, txlen %d, txint %d", 406 p_data->chg_evt.sco_inx, 407 p_data->chg_evt.retrans_window, p_data->chg_evt.rx_pkt_len, 408 p_data->chg_evt.tx_pkt_len, p_data->chg_evt.tx_interval); 409 } 410 } 411 412 /******************************************************************************* 413 ** 414 ** Function bta_ag_cback_sco 415 ** 416 ** Description Call application callback function with SCO event. 417 ** 418 ** 419 ** Returns void 420 ** 421 *******************************************************************************/ 422 static void bta_ag_cback_sco(tBTA_AG_SCB *p_scb, UINT8 event) 423 { 424 tBTA_AG_HDR sco; 425 426 sco.handle = bta_ag_scb_to_idx(p_scb); 427 sco.app_id = p_scb->app_id; 428 429 /* call close cback */ 430 (*bta_ag_cb.p_cback)(event, (tBTA_AG *) &sco); 431 } 432 433 /******************************************************************************* 434 ** 435 ** Function bta_ag_create_sco 436 ** 437 ** Description 438 ** 439 ** 440 ** Returns void 441 ** 442 *******************************************************************************/ 443 static void bta_ag_create_sco(tBTA_AG_SCB *p_scb, BOOLEAN is_orig) 444 { 445 tBTM_STATUS status; 446 UINT8 *p_bd_addr = NULL; 447 tBTM_ESCO_PARAMS params; 448 #if (BTM_WBS_INCLUDED == TRUE ) 449 tBTA_AG_PEER_CODEC esco_codec = BTM_SCO_CODEC_CVSD; 450 int codec_index = 0; 451 #endif 452 #if (BTM_SCO_HCI_INCLUDED == TRUE ) 453 tBTM_SCO_ROUTE_TYPE sco_route; 454 tBTA_CODEC_INFO codec_info = {BTA_SCO_CODEC_PCM}; 455 UINT32 pcm_sample_rate; 456 #endif 457 458 /* Make sure this sco handle is not already in use */ 459 if (p_scb->sco_idx != BTM_INVALID_SCO_INDEX) 460 { 461 APPL_TRACE_WARNING("bta_ag_create_sco: Index 0x%04x Already In Use!", 462 p_scb->sco_idx); 463 return; 464 } 465 466 #if (BTM_WBS_INCLUDED == TRUE ) 467 if ((p_scb->sco_codec == BTM_SCO_CODEC_MSBC) && 468 !p_scb->codec_fallback && 469 !p_scb->retry_with_sco_only) 470 esco_codec = BTM_SCO_CODEC_MSBC; 471 472 if (p_scb->codec_fallback) 473 { 474 p_scb->codec_fallback = FALSE; 475 476 /* Force AG to send +BCS for the next audio connection. */ 477 p_scb->codec_updated = TRUE; 478 } 479 480 /* If WBS included, use CVSD by default, index is 0 for CVSD by initialization */ 481 /* If eSCO codec is mSBC, index is T2 or T1 */ 482 if (esco_codec == BTM_SCO_CODEC_MSBC) 483 { 484 if (p_scb->codec_msbc_settings == BTA_AG_SCO_MSBC_SETTINGS_T2) 485 { 486 codec_index = BTA_AG_ESCO_SETTING_IDX_T2; 487 } 488 else 489 { 490 codec_index = BTA_AG_ESCO_SETTING_IDX_T1; 491 } 492 } 493 494 params = bta_ag_esco_params[codec_index]; 495 #else 496 /* When WBS is not included, use CVSD by default */ 497 params = bta_ag_esco_params; 498 #endif 499 500 if(bta_ag_cb.sco.param_updated) /* If we do not use the default parameters */ 501 params = bta_ag_cb.sco.params; 502 503 if(!bta_ag_cb.sco.param_updated) 504 { 505 #if (BTM_WBS_INCLUDED == TRUE) 506 if (esco_codec == BTM_SCO_CODEC_CVSD) /* For CVSD */ 507 #endif 508 { 509 /* Use the application packet types (5 slot EV packets not allowed) */ 510 params.packet_types = p_bta_ag_cfg->sco_pkt_types | 511 BTM_SCO_PKT_TYPES_MASK_NO_2_EV5 | 512 BTM_SCO_PKT_TYPES_MASK_NO_3_EV5; 513 } 514 } 515 516 /* if initiating set current scb and peer bd addr */ 517 if (is_orig) 518 { 519 /* Attempt to use eSCO if remote host supports HFP >= 1.5 */ 520 /* Need to find out from SIG if HSP can use eSCO; for now use SCO */ 521 if (p_scb->conn_service == BTA_AG_HFP && p_scb->peer_version >= HFP_VERSION_1_5 && !p_scb->retry_with_sco_only) 522 { 523 524 BTM_SetEScoMode(BTM_LINK_TYPE_ESCO, ¶ms); 525 /* If ESCO or EDR ESCO, retry with SCO only in case of failure */ 526 if((params.packet_types & BTM_ESCO_LINK_ONLY_MASK) 527 ||!((params.packet_types & ~(BTM_ESCO_LINK_ONLY_MASK | BTM_SCO_LINK_ONLY_MASK)) ^ BTA_AG_NO_EDR_ESCO)) 528 { 529 #if (BTM_WBS_INCLUDED == TRUE ) 530 if (esco_codec != BTA_AG_CODEC_MSBC) 531 { 532 p_scb->retry_with_sco_only = TRUE; 533 APPL_TRACE_API("Setting retry_with_sco_only to TRUE"); 534 } 535 else /* Do not use SCO when using mSBC */ 536 { 537 p_scb->retry_with_sco_only = FALSE; 538 APPL_TRACE_API("Setting retry_with_sco_only to FALSE"); 539 } 540 #else 541 p_scb->retry_with_sco_only = TRUE; 542 APPL_TRACE_API("Setting retry_with_sco_only to TRUE"); 543 #endif 544 } 545 } 546 else 547 { 548 if(p_scb->retry_with_sco_only) 549 APPL_TRACE_API("retrying with SCO only"); 550 p_scb->retry_with_sco_only = FALSE; 551 552 BTM_SetEScoMode(BTM_LINK_TYPE_SCO, ¶ms); 553 } 554 555 bta_ag_cb.sco.p_curr_scb = p_scb; 556 557 /* tell sys to stop av if any */ 558 bta_sys_sco_use(BTA_ID_AG, p_scb->app_id, p_scb->peer_addr); 559 560 #if (BTM_WBS_INCLUDED == TRUE ) 561 /* Allow any platform specific pre-SCO set up to take place */ 562 bta_ag_co_audio_state(bta_ag_scb_to_idx(p_scb), p_scb->app_id, BTA_AG_CO_AUD_STATE_SETUP,\ 563 esco_codec); 564 565 /* This setting may not be necessary */ 566 /* To be verified with stable 2049 boards */ 567 if (esco_codec == BTA_AG_CODEC_MSBC) 568 BTM_WriteVoiceSettings (BTM_VOICE_SETTING_TRANS); 569 else 570 BTM_WriteVoiceSettings (BTM_VOICE_SETTING_CVSD); 571 /* save the current codec because sco_codec can be updated while SCO is open. */ 572 p_scb->inuse_codec = esco_codec; 573 #else 574 /* Allow any platform specific pre-SCO set up to take place */ 575 bta_ag_co_audio_state(bta_ag_scb_to_idx(p_scb), p_scb->app_id, BTA_AG_CO_AUD_STATE_SETUP); 576 #endif 577 578 #if (BTM_SCO_HCI_INCLUDED == TRUE ) 579 #if (BTM_WBS_INCLUDED == TRUE) 580 if (esco_codec == BTA_AG_CODEC_MSBC) 581 pcm_sample_rate = BTA_DM_SCO_SAMP_RATE_16K; 582 else 583 #endif 584 pcm_sample_rate = BTA_DM_SCO_SAMP_RATE_8K; 585 586 sco_route = bta_dm_sco_co_init(pcm_sample_rate, pcm_sample_rate, &codec_info, p_scb->app_id); 587 #endif 588 589 590 #if (BTM_SCO_HCI_INCLUDED == TRUE ) 591 /* initialize SCO setup, no voice setting for AG, data rate <==> sample rate */ 592 BTM_ConfigScoPath(sco_route, bta_ag_sco_read_cback, NULL, TRUE); 593 #endif 594 bta_ag_cb.sco.cur_idx = p_scb->sco_idx; 595 } 596 else 597 p_scb->retry_with_sco_only = FALSE; 598 599 p_bd_addr = p_scb->peer_addr; 600 601 status = BTM_CreateSco(p_bd_addr, is_orig, params.packet_types, 602 &p_scb->sco_idx, bta_ag_sco_conn_cback, 603 bta_ag_sco_disc_cback); 604 if (status == BTM_CMD_STARTED) 605 { 606 if (!is_orig) 607 { 608 BTM_RegForEScoEvts(p_scb->sco_idx, bta_ag_esco_connreq_cback); 609 } 610 else /* Initiating the connection, set the current sco handle */ 611 { 612 bta_ag_cb.sco.cur_idx = p_scb->sco_idx; 613 } 614 } 615 616 APPL_TRACE_API("ag create sco: orig %d, inx 0x%04x, status 0x%x, pkt types 0x%04x", 617 is_orig, p_scb->sco_idx, status, params.packet_types); 618 } 619 620 #if (BTM_WBS_INCLUDED == TRUE ) 621 /******************************************************************************* 622 ** 623 ** Function bta_ag_attempt_msbc_safe_settings 624 ** 625 ** Description Checks if ESCO connection needs to be attempted using mSBC T1(safe) settings 626 ** 627 ** 628 ** Returns TRUE if T1 settings has to be used, FALSE otherwise 629 ** 630 *******************************************************************************/ 631 BOOLEAN bta_ag_attempt_msbc_safe_settings(tBTA_AG_SCB *p_scb) 632 { 633 if (p_scb->svc_conn && p_scb->sco_codec == BTM_SCO_CODEC_MSBC && 634 p_scb->codec_msbc_settings == BTA_AG_SCO_MSBC_SETTINGS_T1) 635 return TRUE; 636 else 637 return FALSE; 638 } 639 640 /******************************************************************************* 641 ** 642 ** Function bta_ag_cn_timer_cback 643 ** 644 ** Description 645 ** 646 ** 647 ** Returns void 648 ** 649 *******************************************************************************/ 650 static void bta_ag_cn_timer_cback (TIMER_LIST_ENT *p_tle) 651 { 652 tBTA_AG_SCB *p_scb; 653 654 if (p_tle) 655 { 656 p_scb = (tBTA_AG_SCB *)p_tle->param; 657 658 if (p_scb) 659 { 660 /* Announce that codec negotiation failed. */ 661 bta_ag_sco_codec_nego(p_scb, FALSE); 662 663 /* call app callback */ 664 bta_ag_cback_sco(p_scb, BTA_AG_AUDIO_CLOSE_EVT); 665 } 666 } 667 } 668 669 /******************************************************************************* 670 ** 671 ** Function bta_ag_codec_negotiate 672 ** 673 ** Description Initiate codec negotiation by sending AT command. 674 ** If not necessary, skip negotiation. 675 ** 676 ** Returns void 677 ** 678 *******************************************************************************/ 679 void bta_ag_codec_negotiate(tBTA_AG_SCB *p_scb) 680 { 681 bta_ag_cb.sco.p_curr_scb = p_scb; 682 683 if ((p_scb->codec_updated || p_scb->codec_fallback || 684 bta_ag_attempt_msbc_safe_settings(p_scb)) && 685 (p_scb->peer_features & BTA_AG_PEER_FEAT_CODEC)) 686 { 687 /* Change the power mode to Active until sco open is completed. */ 688 bta_sys_busy(BTA_ID_AG, p_scb->app_id, p_scb->peer_addr); 689 690 /* Send +BCS to the peer */ 691 bta_ag_send_bcs(p_scb, NULL); 692 693 /* Start timer to handle timeout */ 694 p_scb->cn_timer.p_cback = (TIMER_CBACK*)&bta_ag_cn_timer_cback; 695 p_scb->cn_timer.param = (INT32)p_scb; 696 bta_sys_start_timer(&p_scb->cn_timer, 0, BTA_AG_CODEC_NEGO_TIMEOUT); 697 } 698 else 699 { 700 /* use same codec type as previous SCO connection, skip codec negotiation */ 701 APPL_TRACE_DEBUG("use same codec type as previous SCO connection,skip codec negotiation"); 702 bta_ag_sco_codec_nego(p_scb, TRUE); 703 } 704 } 705 #endif /* (BTM_WBS_INCLUDED == TRUE ) */ 706 707 /******************************************************************************* 708 ** 709 ** Function bta_ag_sco_event 710 ** 711 ** Description 712 ** 713 ** 714 ** Returns void 715 ** 716 *******************************************************************************/ 717 static void bta_ag_sco_event(tBTA_AG_SCB *p_scb, UINT8 event) 718 { 719 tBTA_AG_SCO_CB *p_sco = &bta_ag_cb.sco; 720 #if (BTM_WBS_INCLUDED == TRUE ) 721 tBTA_AG_SCB *p_cn_scb = NULL; /* For codec negotiation */ 722 #endif 723 #if (BTM_SCO_HCI_INCLUDED == TRUE ) 724 BT_HDR *p_buf; 725 #endif 726 #if BTA_AG_SCO_DEBUG == TRUE 727 UINT8 in_state = p_sco->state; 728 729 APPL_TRACE_EVENT("BTA ag sco evt (hdl 0x%04x): State %d (%s), Event %d (%s)", 730 p_scb->sco_idx, 731 p_sco->state, bta_ag_sco_state_str(p_sco->state), 732 event, bta_ag_sco_evt_str(event)); 733 #else 734 APPL_TRACE_EVENT("BTA ag sco evt (hdl 0x%04x): State %d, Event %d", 735 p_scb->sco_idx, p_sco->state, event); 736 #endif 737 738 #if (BTM_SCO_HCI_INCLUDED == TRUE ) 739 if (event == BTA_AG_SCO_CI_DATA_E) 740 { 741 while (TRUE) 742 { 743 bta_dm_sco_co_out_data(&p_buf); 744 if (p_buf) 745 { 746 if (p_sco->state == BTA_AG_SCO_OPEN_ST) 747 BTM_WriteScoData(p_sco->p_curr_scb->sco_idx, p_buf); 748 else 749 GKI_freebuf(p_buf); 750 } 751 else 752 break; 753 } 754 755 return; 756 } 757 #endif 758 759 switch (p_sco->state) 760 { 761 case BTA_AG_SCO_SHUTDOWN_ST: 762 switch (event) 763 { 764 case BTA_AG_SCO_LISTEN_E: 765 /* create sco listen connection */ 766 bta_ag_create_sco(p_scb, FALSE); 767 p_sco->state = BTA_AG_SCO_LISTEN_ST; 768 break; 769 770 default: 771 APPL_TRACE_WARNING("BTA_AG_SCO_SHUTDOWN_ST: Ignoring event %d", event); 772 break; 773 } 774 break; 775 776 case BTA_AG_SCO_LISTEN_ST: 777 switch (event) 778 { 779 case BTA_AG_SCO_LISTEN_E: 780 /* create sco listen connection (Additional channel) */ 781 bta_ag_create_sco(p_scb, FALSE); 782 break; 783 784 case BTA_AG_SCO_OPEN_E: 785 /* remove listening connection */ 786 bta_ag_remove_sco(p_scb, FALSE); 787 788 #if (BTM_WBS_INCLUDED == TRUE ) 789 /* start codec negotiation */ 790 p_sco->state = BTA_AG_SCO_CODEC_ST; 791 p_cn_scb = p_scb; 792 #else 793 /* create sco connection to peer */ 794 bta_ag_create_sco(p_scb, TRUE); 795 p_sco->state = BTA_AG_SCO_OPENING_ST; 796 #endif 797 break; 798 799 case BTA_AG_SCO_SHUTDOWN_E: 800 /* remove listening connection */ 801 bta_ag_remove_sco(p_scb, FALSE); 802 803 if (p_scb == p_sco->p_curr_scb) 804 p_sco->p_curr_scb = NULL; 805 806 /* If last SCO instance then finish shutting down */ 807 if (!bta_ag_other_scb_open(p_scb)) 808 { 809 p_sco->state = BTA_AG_SCO_SHUTDOWN_ST; 810 } 811 break; 812 813 case BTA_AG_SCO_CLOSE_E: 814 /* remove listening connection */ 815 /* Ignore the event. We need to keep listening SCO for the active SLC */ 816 APPL_TRACE_WARNING("BTA_AG_SCO_LISTEN_ST: Ignoring event %d", event); 817 break; 818 819 case BTA_AG_SCO_CONN_CLOSE_E: 820 /* sco failed; create sco listen connection */ 821 bta_ag_create_sco(p_scb, FALSE); 822 p_sco->state = BTA_AG_SCO_LISTEN_ST; 823 break; 824 825 default: 826 APPL_TRACE_WARNING("BTA_AG_SCO_LISTEN_ST: Ignoring event %d", event); 827 break; 828 } 829 break; 830 831 #if (BTM_WBS_INCLUDED == TRUE ) 832 case BTA_AG_SCO_CODEC_ST: 833 switch (event) 834 { 835 case BTA_AG_SCO_LISTEN_E: 836 /* create sco listen connection (Additional channel) */ 837 bta_ag_create_sco(p_scb, FALSE); 838 break; 839 840 case BTA_AG_SCO_CN_DONE_E: 841 /* create sco connection to peer */ 842 bta_ag_create_sco(p_scb, TRUE); 843 p_sco->state = BTA_AG_SCO_OPENING_ST; 844 break; 845 846 case BTA_AG_SCO_XFER_E: 847 /* save xfer scb */ 848 p_sco->p_xfer_scb = p_scb; 849 p_sco->state = BTA_AG_SCO_CLOSE_XFER_ST; 850 break; 851 852 case BTA_AG_SCO_SHUTDOWN_E: 853 /* remove listening connection */ 854 bta_ag_remove_sco(p_scb, FALSE); 855 856 if (p_scb == p_sco->p_curr_scb) 857 p_sco->p_curr_scb = NULL; 858 859 /* If last SCO instance then finish shutting down */ 860 if (!bta_ag_other_scb_open(p_scb)) 861 { 862 p_sco->state = BTA_AG_SCO_SHUTDOWN_ST; 863 } 864 break; 865 866 case BTA_AG_SCO_CLOSE_E: 867 /* sco open is not started yet. just go back to listening */ 868 p_sco->state = BTA_AG_SCO_LISTEN_ST; 869 break; 870 871 case BTA_AG_SCO_CONN_CLOSE_E: 872 /* sco failed; create sco listen connection */ 873 bta_ag_create_sco(p_scb, FALSE); 874 p_sco->state = BTA_AG_SCO_LISTEN_ST; 875 break; 876 877 default: 878 APPL_TRACE_WARNING("BTA_AG_SCO_CODEC_ST: Ignoring event %d", event); 879 break; 880 } 881 break; 882 #endif 883 884 case BTA_AG_SCO_OPENING_ST: 885 switch (event) 886 { 887 case BTA_AG_SCO_LISTEN_E: 888 /* second headset has now joined */ 889 /* create sco listen connection (Additional channel) */ 890 if (p_scb != p_sco->p_curr_scb) 891 { 892 bta_ag_create_sco(p_scb, FALSE); 893 } 894 break; 895 896 #if (BTM_WBS_INCLUDED == TRUE) 897 case BTA_AG_SCO_REOPEN_E: 898 /* start codec negotiation */ 899 p_sco->state = BTA_AG_SCO_CODEC_ST; 900 p_cn_scb = p_scb; 901 break; 902 #endif 903 904 case BTA_AG_SCO_XFER_E: 905 /* save xfer scb */ 906 p_sco->p_xfer_scb = p_scb; 907 p_sco->state = BTA_AG_SCO_CLOSE_XFER_ST; 908 break; 909 910 case BTA_AG_SCO_CLOSE_E: 911 p_sco->state = BTA_AG_SCO_OPEN_CL_ST; 912 break; 913 914 case BTA_AG_SCO_SHUTDOWN_E: 915 /* If not opening scb, just close it */ 916 if (p_scb != p_sco->p_curr_scb) 917 { 918 /* remove listening connection */ 919 bta_ag_remove_sco(p_scb, FALSE); 920 } 921 else 922 p_sco->state = BTA_AG_SCO_SHUTTING_ST; 923 924 break; 925 926 case BTA_AG_SCO_CONN_OPEN_E: 927 p_sco->state = BTA_AG_SCO_OPEN_ST; 928 break; 929 930 case BTA_AG_SCO_CONN_CLOSE_E: 931 /* sco failed; create sco listen connection */ 932 bta_ag_create_sco(p_scb, FALSE); 933 p_sco->state = BTA_AG_SCO_LISTEN_ST; 934 break; 935 936 default: 937 APPL_TRACE_WARNING("BTA_AG_SCO_OPENING_ST: Ignoring event %d", event); 938 break; 939 } 940 break; 941 942 case BTA_AG_SCO_OPEN_CL_ST: 943 switch (event) 944 { 945 case BTA_AG_SCO_XFER_E: 946 /* save xfer scb */ 947 p_sco->p_xfer_scb = p_scb; 948 949 p_sco->state = BTA_AG_SCO_CLOSE_XFER_ST; 950 break; 951 952 case BTA_AG_SCO_OPEN_E: 953 p_sco->state = BTA_AG_SCO_OPENING_ST; 954 break; 955 956 case BTA_AG_SCO_SHUTDOWN_E: 957 /* If not opening scb, just close it */ 958 if (p_scb != p_sco->p_curr_scb) 959 { 960 /* remove listening connection */ 961 bta_ag_remove_sco(p_scb, FALSE); 962 } 963 else 964 p_sco->state = BTA_AG_SCO_SHUTTING_ST; 965 966 break; 967 968 case BTA_AG_SCO_CONN_OPEN_E: 969 /* close sco connection */ 970 bta_ag_remove_sco(p_scb, TRUE); 971 972 p_sco->state = BTA_AG_SCO_CLOSING_ST; 973 break; 974 975 case BTA_AG_SCO_CONN_CLOSE_E: 976 /* sco failed; create sco listen connection */ 977 978 p_sco->state = BTA_AG_SCO_LISTEN_ST; 979 break; 980 981 default: 982 APPL_TRACE_WARNING("BTA_AG_SCO_OPEN_CL_ST: Ignoring event %d", event); 983 break; 984 } 985 break; 986 987 case BTA_AG_SCO_OPEN_XFER_ST: 988 switch (event) 989 { 990 case BTA_AG_SCO_CLOSE_E: 991 /* close sco connection */ 992 bta_ag_remove_sco(p_scb, TRUE); 993 994 p_sco->state = BTA_AG_SCO_CLOSING_ST; 995 break; 996 997 case BTA_AG_SCO_SHUTDOWN_E: 998 /* remove all connection */ 999 bta_ag_remove_sco(p_scb, FALSE); 1000 p_sco->state = BTA_AG_SCO_SHUTTING_ST; 1001 1002 break; 1003 1004 case BTA_AG_SCO_CONN_CLOSE_E: 1005 /* closed sco; place in listen mode and 1006 accept the transferred connection */ 1007 bta_ag_create_sco(p_scb, FALSE); /* Back into listen mode */ 1008 1009 /* Accept sco connection with xfer scb */ 1010 bta_ag_sco_conn_rsp(p_sco->p_xfer_scb, &p_sco->conn_data); 1011 p_sco->state = BTA_AG_SCO_OPENING_ST; 1012 p_sco->p_curr_scb = p_sco->p_xfer_scb; 1013 p_sco->cur_idx = p_sco->p_xfer_scb->sco_idx; 1014 p_sco->p_xfer_scb = NULL; 1015 break; 1016 1017 default: 1018 APPL_TRACE_WARNING("BTA_AG_SCO_OPEN_XFER_ST: Ignoring event %d", event); 1019 break; 1020 } 1021 break; 1022 1023 case BTA_AG_SCO_OPEN_ST: 1024 switch (event) 1025 { 1026 case BTA_AG_SCO_LISTEN_E: 1027 /* second headset has now joined */ 1028 /* create sco listen connection (Additional channel) */ 1029 if (p_scb != p_sco->p_curr_scb) 1030 { 1031 bta_ag_create_sco(p_scb, FALSE); 1032 } 1033 break; 1034 1035 case BTA_AG_SCO_XFER_E: 1036 /* close current sco connection */ 1037 bta_ag_remove_sco(p_sco->p_curr_scb, TRUE); 1038 1039 /* save xfer scb */ 1040 p_sco->p_xfer_scb = p_scb; 1041 1042 p_sco->state = BTA_AG_SCO_CLOSE_XFER_ST; 1043 break; 1044 1045 case BTA_AG_SCO_CLOSE_E: 1046 /* close sco connection if active */ 1047 if (bta_ag_remove_sco(p_scb, TRUE)) 1048 { 1049 p_sco->state = BTA_AG_SCO_CLOSING_ST; 1050 } 1051 break; 1052 1053 case BTA_AG_SCO_SHUTDOWN_E: 1054 /* remove all listening connections */ 1055 bta_ag_remove_sco(p_scb, FALSE); 1056 1057 /* If SCO was active on this scb, close it */ 1058 if (p_scb == p_sco->p_curr_scb) 1059 { 1060 p_sco->state = BTA_AG_SCO_SHUTTING_ST; 1061 } 1062 break; 1063 1064 case BTA_AG_SCO_CONN_CLOSE_E: 1065 /* peer closed sco; create sco listen connection */ 1066 bta_ag_create_sco(p_scb, FALSE); 1067 p_sco->state = BTA_AG_SCO_LISTEN_ST; 1068 break; 1069 1070 default: 1071 APPL_TRACE_WARNING("BTA_AG_SCO_OPEN_ST: Ignoring event %d", event); 1072 break; 1073 } 1074 break; 1075 1076 case BTA_AG_SCO_CLOSING_ST: 1077 switch (event) 1078 { 1079 case BTA_AG_SCO_LISTEN_E: 1080 /* create sco listen connection (Additional channel) */ 1081 if (p_scb != p_sco->p_curr_scb) 1082 { 1083 bta_ag_create_sco(p_scb, FALSE); 1084 } 1085 break; 1086 1087 case BTA_AG_SCO_OPEN_E: 1088 p_sco->state = BTA_AG_SCO_CLOSE_OP_ST; 1089 break; 1090 1091 case BTA_AG_SCO_XFER_E: 1092 /* save xfer scb */ 1093 p_sco->p_xfer_scb = p_scb; 1094 1095 p_sco->state = BTA_AG_SCO_CLOSE_XFER_ST; 1096 break; 1097 1098 case BTA_AG_SCO_SHUTDOWN_E: 1099 /* If not closing scb, just close it */ 1100 if (p_scb != p_sco->p_curr_scb) 1101 { 1102 /* remove listening connection */ 1103 bta_ag_remove_sco(p_scb, FALSE); 1104 } 1105 else 1106 p_sco->state = BTA_AG_SCO_SHUTTING_ST; 1107 1108 break; 1109 1110 case BTA_AG_SCO_CONN_CLOSE_E: 1111 /* peer closed sco; create sco listen connection */ 1112 bta_ag_create_sco(p_scb, FALSE); 1113 1114 p_sco->state = BTA_AG_SCO_LISTEN_ST; 1115 break; 1116 1117 default: 1118 APPL_TRACE_WARNING("BTA_AG_SCO_CLOSING_ST: Ignoring event %d", event); 1119 break; 1120 } 1121 break; 1122 1123 case BTA_AG_SCO_CLOSE_OP_ST: 1124 switch (event) 1125 { 1126 case BTA_AG_SCO_CLOSE_E: 1127 p_sco->state = BTA_AG_SCO_CLOSING_ST; 1128 break; 1129 1130 case BTA_AG_SCO_SHUTDOWN_E: 1131 p_sco->state = BTA_AG_SCO_SHUTTING_ST; 1132 break; 1133 1134 case BTA_AG_SCO_CONN_CLOSE_E: 1135 #if (BTM_WBS_INCLUDED == TRUE ) 1136 /* start codec negotiation */ 1137 p_sco->state = BTA_AG_SCO_CODEC_ST; 1138 p_cn_scb = p_scb; 1139 #else 1140 /* open sco connection */ 1141 bta_ag_create_sco(p_scb, TRUE); 1142 p_sco->state = BTA_AG_SCO_OPENING_ST; 1143 #endif 1144 break; 1145 1146 case BTA_AG_SCO_LISTEN_E: 1147 /* create sco listen connection (Additional channel) */ 1148 if (p_scb != p_sco->p_curr_scb) 1149 { 1150 bta_ag_create_sco(p_scb, FALSE); 1151 } 1152 break; 1153 1154 default: 1155 APPL_TRACE_WARNING("BTA_AG_SCO_CLOSE_OP_ST: Ignoring event %d", event); 1156 break; 1157 } 1158 break; 1159 1160 case BTA_AG_SCO_CLOSE_XFER_ST: 1161 switch (event) 1162 { 1163 case BTA_AG_SCO_CONN_OPEN_E: 1164 /* close sco connection so headset can be transferred 1165 Probably entered this state from "opening state" */ 1166 bta_ag_remove_sco(p_scb, TRUE); 1167 break; 1168 1169 case BTA_AG_SCO_CLOSE_E: 1170 /* clear xfer scb */ 1171 p_sco->p_xfer_scb = NULL; 1172 1173 p_sco->state = BTA_AG_SCO_CLOSING_ST; 1174 break; 1175 1176 case BTA_AG_SCO_SHUTDOWN_E: 1177 /* clear xfer scb */ 1178 p_sco->p_xfer_scb = NULL; 1179 1180 p_sco->state = BTA_AG_SCO_SHUTTING_ST; 1181 break; 1182 1183 case BTA_AG_SCO_CONN_CLOSE_E: 1184 /* closed sco; place old sco in listen mode, 1185 take current sco out of listen, and 1186 create originating sco for current */ 1187 bta_ag_create_sco(p_scb, FALSE); 1188 bta_ag_remove_sco(p_sco->p_xfer_scb, FALSE); 1189 1190 #if (BTM_WBS_INCLUDED == TRUE ) 1191 /* start codec negotiation */ 1192 p_sco->state = BTA_AG_SCO_CODEC_ST; 1193 p_cn_scb = p_sco->p_xfer_scb; 1194 p_sco->p_xfer_scb = NULL; 1195 #else 1196 /* create sco connection to peer */ 1197 bta_ag_create_sco(p_sco->p_xfer_scb, TRUE); 1198 p_sco->p_xfer_scb = NULL; 1199 p_sco->state = BTA_AG_SCO_OPENING_ST; 1200 #endif 1201 break; 1202 1203 default: 1204 APPL_TRACE_WARNING("BTA_AG_SCO_CLOSE_XFER_ST: Ignoring event %d", event); 1205 break; 1206 } 1207 break; 1208 1209 case BTA_AG_SCO_SHUTTING_ST: 1210 switch (event) 1211 { 1212 case BTA_AG_SCO_CONN_OPEN_E: 1213 /* close sco connection; wait for conn close event */ 1214 bta_ag_remove_sco(p_scb, TRUE); 1215 break; 1216 1217 case BTA_AG_SCO_CONN_CLOSE_E: 1218 /* If last SCO instance then finish shutting down */ 1219 if (!bta_ag_other_scb_open(p_scb)) 1220 { 1221 p_sco->state = BTA_AG_SCO_SHUTDOWN_ST; 1222 } 1223 else /* Other instance is still listening */ 1224 { 1225 p_sco->state = BTA_AG_SCO_LISTEN_ST; 1226 } 1227 1228 if (p_scb == p_sco->p_curr_scb) 1229 { 1230 p_sco->p_curr_scb->sco_idx = BTM_INVALID_SCO_INDEX; 1231 p_sco->p_curr_scb = NULL; 1232 } 1233 break; 1234 1235 case BTA_AG_SCO_LISTEN_E: 1236 /* create sco listen connection (Additional channel) */ 1237 if (p_scb != p_sco->p_curr_scb) 1238 { 1239 bta_ag_create_sco(p_scb, FALSE); 1240 } 1241 break; 1242 1243 case BTA_AG_SCO_SHUTDOWN_E: 1244 if (!bta_ag_other_scb_open(p_scb)) 1245 { 1246 p_sco->state = BTA_AG_SCO_SHUTDOWN_ST; 1247 } 1248 else /* Other instance is still listening */ 1249 { 1250 p_sco->state = BTA_AG_SCO_LISTEN_ST; 1251 } 1252 1253 if (p_scb == p_sco->p_curr_scb) 1254 { 1255 p_sco->p_curr_scb->sco_idx = BTM_INVALID_SCO_INDEX; 1256 p_sco->p_curr_scb = NULL; 1257 } 1258 break; 1259 1260 default: 1261 APPL_TRACE_WARNING("BTA_AG_SCO_SHUTTING_ST: Ignoring event %d", event); 1262 break; 1263 } 1264 break; 1265 1266 default: 1267 break; 1268 } 1269 #if BTA_AG_SCO_DEBUG == TRUE 1270 if (p_sco->state != in_state) 1271 { 1272 APPL_TRACE_EVENT("BTA AG SCO State Change: [%s] -> [%s] after Event [%s]", 1273 bta_ag_sco_state_str(in_state), 1274 bta_ag_sco_state_str(p_sco->state), 1275 bta_ag_sco_evt_str(event)); 1276 } 1277 #endif 1278 1279 #if (BTM_WBS_INCLUDED == TRUE ) 1280 if (p_cn_scb) 1281 { 1282 bta_ag_codec_negotiate(p_cn_scb); 1283 } 1284 #endif 1285 } 1286 1287 /******************************************************************************* 1288 ** 1289 ** Function bta_ag_sco_is_open 1290 ** 1291 ** Description Check if sco is open for this scb. 1292 ** 1293 ** 1294 ** Returns TRUE if sco open for this scb, FALSE otherwise. 1295 ** 1296 *******************************************************************************/ 1297 BOOLEAN bta_ag_sco_is_open(tBTA_AG_SCB *p_scb) 1298 { 1299 return ((bta_ag_cb.sco.state == BTA_AG_SCO_OPEN_ST) && 1300 (bta_ag_cb.sco.p_curr_scb == p_scb)); 1301 } 1302 1303 /******************************************************************************* 1304 ** 1305 ** Function bta_ag_sco_is_opening 1306 ** 1307 ** Description Check if sco is in Opening state. 1308 ** 1309 ** 1310 ** Returns TRUE if sco is in Opening state for this scb, FALSE otherwise. 1311 ** 1312 *******************************************************************************/ 1313 BOOLEAN bta_ag_sco_is_opening(tBTA_AG_SCB *p_scb) 1314 { 1315 #if (BTM_WBS_INCLUDED == TRUE ) 1316 return (((bta_ag_cb.sco.state == BTA_AG_SCO_OPENING_ST) || 1317 (bta_ag_cb.sco.state == BTA_AG_SCO_OPENING_ST)) && 1318 (bta_ag_cb.sco.p_curr_scb == p_scb)); 1319 #else 1320 return ((bta_ag_cb.sco.state == BTA_AG_SCO_OPENING_ST) && 1321 (bta_ag_cb.sco.p_curr_scb == p_scb)); 1322 #endif 1323 } 1324 1325 /******************************************************************************* 1326 ** 1327 ** Function bta_ag_sco_listen 1328 ** 1329 ** Description 1330 ** 1331 ** 1332 ** Returns void 1333 ** 1334 *******************************************************************************/ 1335 void bta_ag_sco_listen(tBTA_AG_SCB *p_scb, tBTA_AG_DATA *p_data) 1336 { 1337 UNUSED(p_data); 1338 bta_ag_sco_event(p_scb, BTA_AG_SCO_LISTEN_E); 1339 } 1340 1341 /******************************************************************************* 1342 ** 1343 ** Function bta_ag_sco_open 1344 ** 1345 ** Description 1346 ** 1347 ** 1348 ** Returns void 1349 ** 1350 *******************************************************************************/ 1351 void bta_ag_sco_open(tBTA_AG_SCB *p_scb, tBTA_AG_DATA *p_data) 1352 { 1353 UINT8 event; 1354 UNUSED(p_data); 1355 1356 /* if another scb using sco, this is a transfer */ 1357 if (bta_ag_cb.sco.p_curr_scb != NULL && bta_ag_cb.sco.p_curr_scb != p_scb) 1358 { 1359 event = BTA_AG_SCO_XFER_E; 1360 } 1361 /* else it is an open */ 1362 else 1363 { 1364 event = BTA_AG_SCO_OPEN_E; 1365 } 1366 1367 bta_ag_sco_event(p_scb, event); 1368 } 1369 1370 /******************************************************************************* 1371 ** 1372 ** Function bta_ag_sco_close 1373 ** 1374 ** Description 1375 ** 1376 ** 1377 ** Returns void 1378 ** 1379 *******************************************************************************/ 1380 void bta_ag_sco_close(tBTA_AG_SCB *p_scb, tBTA_AG_DATA *p_data) 1381 { 1382 UNUSED(p_data); 1383 1384 /* if scb is in use */ 1385 #if (BTM_WBS_INCLUDED == TRUE ) 1386 /* sco_idx is not allocated in SCO_CODEC_ST, we still need to move to listening state. */ 1387 if ((p_scb->sco_idx != BTM_INVALID_SCO_INDEX) || (bta_ag_cb.sco.state == BTA_AG_SCO_CODEC_ST)) 1388 #else 1389 if (p_scb->sco_idx != BTM_INVALID_SCO_INDEX) 1390 #endif 1391 { 1392 APPL_TRACE_DEBUG("bta_ag_sco_close: sco_inx = %d", p_scb->sco_idx); 1393 bta_ag_sco_event(p_scb, BTA_AG_SCO_CLOSE_E); 1394 } 1395 } 1396 1397 #if (BTM_WBS_INCLUDED == TRUE ) 1398 1399 /******************************************************************************* 1400 ** 1401 ** Function bta_ag_sco_codec_nego 1402 ** 1403 ** Description 1404 ** 1405 ** 1406 ** Returns void 1407 ** 1408 *******************************************************************************/ 1409 void bta_ag_sco_codec_nego(tBTA_AG_SCB *p_scb, BOOLEAN result) 1410 { 1411 if(result == TRUE) 1412 { 1413 /* Subsequent sco connection will skip codec negotiation */ 1414 p_scb->codec_updated = FALSE; 1415 1416 bta_ag_sco_event(p_scb, BTA_AG_SCO_CN_DONE_E); 1417 } 1418 else /* codec negotiation failed */ 1419 bta_ag_sco_event(p_scb, BTA_AG_SCO_CLOSE_E); 1420 } 1421 #endif 1422 1423 /******************************************************************************* 1424 ** 1425 ** Function bta_ag_sco_shutdown 1426 ** 1427 ** Description 1428 ** 1429 ** 1430 ** Returns void 1431 ** 1432 *******************************************************************************/ 1433 void bta_ag_sco_shutdown(tBTA_AG_SCB *p_scb, tBTA_AG_DATA *p_data) 1434 { 1435 UNUSED(p_data); 1436 1437 bta_ag_sco_event(p_scb, BTA_AG_SCO_SHUTDOWN_E); 1438 } 1439 1440 /******************************************************************************* 1441 ** 1442 ** Function bta_ag_sco_conn_open 1443 ** 1444 ** Description 1445 ** 1446 ** 1447 ** Returns void 1448 ** 1449 *******************************************************************************/ 1450 void bta_ag_sco_conn_open(tBTA_AG_SCB *p_scb, tBTA_AG_DATA *p_data) 1451 { 1452 UNUSED(p_data); 1453 1454 bta_ag_sco_event(p_scb, BTA_AG_SCO_CONN_OPEN_E); 1455 1456 bta_sys_sco_open(BTA_ID_AG, p_scb->app_id, p_scb->peer_addr); 1457 1458 #if (BTM_WBS_INCLUDED == TRUE) 1459 bta_ag_co_audio_state(bta_ag_scb_to_idx(p_scb), p_scb->app_id, BTA_AG_CO_AUD_STATE_ON, 1460 p_scb->inuse_codec); 1461 #else 1462 bta_ag_co_audio_state(bta_ag_scb_to_idx(p_scb), p_scb->app_id, BTA_AG_CO_AUD_STATE_ON); 1463 #endif 1464 1465 #if (BTM_SCO_HCI_INCLUDED == TRUE ) 1466 /* open SCO codec if SCO is routed through transport */ 1467 bta_dm_sco_co_open(bta_ag_scb_to_idx(p_scb), BTA_SCO_OUT_PKT_SIZE, BTA_AG_CI_SCO_DATA_EVT); 1468 #endif 1469 1470 /* call app callback */ 1471 bta_ag_cback_sco(p_scb, BTA_AG_AUDIO_OPEN_EVT); 1472 1473 p_scb->retry_with_sco_only = FALSE; 1474 #if (BTM_WBS_INCLUDED == TRUE) 1475 /* reset to mSBC T2 settings as the preferred */ 1476 p_scb->codec_msbc_settings = BTA_AG_SCO_MSBC_SETTINGS_T2; 1477 #endif 1478 } 1479 1480 /******************************************************************************* 1481 ** 1482 ** Function bta_ag_sco_conn_close 1483 ** 1484 ** Description 1485 ** 1486 ** 1487 ** Returns void 1488 ** 1489 *******************************************************************************/ 1490 void bta_ag_sco_conn_close(tBTA_AG_SCB *p_scb, tBTA_AG_DATA *p_data) 1491 { 1492 UINT16 handle = bta_ag_scb_to_idx(p_scb); 1493 UNUSED(p_data); 1494 1495 /* clear current scb */ 1496 bta_ag_cb.sco.p_curr_scb = NULL; 1497 p_scb->sco_idx = BTM_INVALID_SCO_INDEX; 1498 1499 #if (BTM_WBS_INCLUDED == TRUE) 1500 /* codec_fallback is set when AG is initiator and connection failed for mSBC. */ 1501 /* OR if codec is msbc and T2 settings failed, then retry Safe T1 settings */ 1502 if ((p_scb->codec_fallback && p_scb->svc_conn) || 1503 bta_ag_attempt_msbc_safe_settings(p_scb)) 1504 { 1505 bta_ag_sco_event(p_scb, BTA_AG_SCO_REOPEN_E); 1506 } 1507 else if (p_scb->retry_with_sco_only && p_scb->svc_conn) 1508 { 1509 /* retry_with_sco_only is set when AG is initiator and connection failed for eSCO */ 1510 bta_ag_create_sco(p_scb, TRUE); 1511 } 1512 #else 1513 /* retry_with_sco_only, will be set only when AG is initiator 1514 ** and AG is first trying to establish an eSCO connection */ 1515 if (p_scb->retry_with_sco_only && p_scb->svc_conn) 1516 { 1517 bta_ag_create_sco(p_scb, TRUE); 1518 } 1519 #endif 1520 else 1521 { 1522 #if (BTM_WBS_INCLUDED == TRUE) 1523 /* Indicate if the closing of audio is because of transfer */ 1524 bta_ag_co_audio_state(handle, p_scb->app_id,(bta_ag_cb.sco.p_xfer_scb)?\ 1525 BTA_AG_CO_AUD_STATE_OFF_XFER:BTA_AG_CO_AUD_STATE_OFF,p_scb->inuse_codec); 1526 #else 1527 /* Indicate if the closing of audio is because of transfer */ 1528 bta_ag_co_audio_state(handle, p_scb->app_id,(bta_ag_cb.sco.p_xfer_scb)?\ 1529 BTA_AG_CO_AUD_STATE_OFF_XFER:BTA_AG_CO_AUD_STATE_OFF); 1530 #endif 1531 bta_ag_sco_event(p_scb, BTA_AG_SCO_CONN_CLOSE_E); 1532 1533 bta_sys_sco_close(BTA_ID_AG, p_scb->app_id, p_scb->peer_addr); 1534 1535 /* if av got suspended by this call, let it resume. */ 1536 /* In case call stays alive regardless of sco, av should not be affected. */ 1537 if(((p_scb->call_ind == BTA_AG_CALL_INACTIVE) && (p_scb->callsetup_ind == BTA_AG_CALLSETUP_NONE)) 1538 || (p_scb->post_sco == BTA_AG_POST_SCO_CALL_END)) 1539 { 1540 bta_sys_sco_unuse(BTA_ID_AG, p_scb->app_id, p_scb->peer_addr); 1541 } 1542 1543 /* call app callback */ 1544 bta_ag_cback_sco(p_scb, BTA_AG_AUDIO_CLOSE_EVT); 1545 #if (BTM_WBS_INCLUDED == TRUE) 1546 p_scb->codec_msbc_settings = BTA_AG_SCO_MSBC_SETTINGS_T2; 1547 #endif 1548 } 1549 p_scb->retry_with_sco_only = FALSE; 1550 } 1551 1552 /******************************************************************************* 1553 ** 1554 ** Function bta_ag_sco_conn_rsp 1555 ** 1556 ** Description Process the SCO connection request 1557 ** 1558 ** 1559 ** Returns void 1560 ** 1561 *******************************************************************************/ 1562 void bta_ag_sco_conn_rsp(tBTA_AG_SCB *p_scb, tBTM_ESCO_CONN_REQ_EVT_DATA *p_data) 1563 { 1564 tBTM_ESCO_PARAMS resp; 1565 UINT8 hci_status = HCI_SUCCESS; 1566 #if (BTM_SCO_HCI_INCLUDED == TRUE ) 1567 tBTA_CODEC_INFO codec_info = {BTA_SCO_CODEC_PCM}; 1568 UINT32 pcm_sample_rate; 1569 #endif 1570 1571 if (bta_ag_cb.sco.state == BTA_AG_SCO_LISTEN_ST || 1572 bta_ag_cb.sco.state == BTA_AG_SCO_CLOSE_XFER_ST || 1573 bta_ag_cb.sco.state == BTA_AG_SCO_OPEN_XFER_ST) 1574 { 1575 /* If script overrided sco parameter by BTA_CMD_SET_ESCO_PARAM */ 1576 if (bta_ag_cb.sco.param_updated) 1577 { 1578 resp = bta_ag_cb.sco.params; 1579 } 1580 else 1581 { 1582 resp.rx_bw = BTM_64KBITS_RATE; 1583 resp.tx_bw = BTM_64KBITS_RATE; 1584 resp.max_latency = 10; 1585 resp.voice_contfmt = 0x60; 1586 resp.retrans_effort = BTM_ESCO_RETRANS_POWER; 1587 1588 if (p_data->link_type == BTM_LINK_TYPE_SCO) 1589 { 1590 resp.packet_types = (BTM_SCO_LINK_ONLY_MASK | 1591 BTM_SCO_PKT_TYPES_MASK_NO_2_EV3 | 1592 BTM_SCO_PKT_TYPES_MASK_NO_3_EV3 | 1593 BTM_SCO_PKT_TYPES_MASK_NO_2_EV5 | 1594 BTM_SCO_PKT_TYPES_MASK_NO_3_EV5); 1595 } 1596 else /* Allow controller to use all types available except 5-slot EDR */ 1597 { 1598 resp.packet_types = (BTM_SCO_LINK_ALL_PKT_MASK | 1599 BTM_SCO_PKT_TYPES_MASK_NO_2_EV5 | 1600 BTM_SCO_PKT_TYPES_MASK_NO_3_EV5); 1601 } 1602 } 1603 1604 /* tell sys to stop av if any */ 1605 bta_sys_sco_use(BTA_ID_AG, p_scb->app_id, p_scb->peer_addr); 1606 1607 #if (BTM_WBS_INCLUDED == FALSE ) 1608 /* Allow any platform specific pre-SCO set up to take place */ 1609 bta_ag_co_audio_state(bta_ag_scb_to_idx(p_scb), p_scb->app_id, BTA_AG_CO_AUD_STATE_SETUP); 1610 #else 1611 /* When HS initiated SCO, it cannot be WBS. */ 1612 /* Allow any platform specific pre-SCO set up to take place */ 1613 bta_ag_co_audio_state(bta_ag_scb_to_idx(p_scb), p_scb->app_id, BTA_AG_CO_AUD_STATE_SETUP, 1614 BTA_AG_CODEC_CVSD); 1615 #endif 1616 1617 #if (BTM_SCO_HCI_INCLUDED == TRUE ) 1618 pcm_sample_rate = BTA_DM_SCO_SAMP_RATE_8K; 1619 1620 /* initialize SCO setup, no voice setting for AG, data rate <==> sample rate */ 1621 BTM_ConfigScoPath(bta_dm_sco_co_init(pcm_sample_rate, pcm_sample_rate, &codec_info, p_scb->app_id), 1622 bta_ag_sco_read_cback, NULL, TRUE); 1623 #endif 1624 } 1625 else 1626 hci_status = HCI_ERR_HOST_REJECT_DEVICE; 1627 1628 #if (BTM_WBS_INCLUDED == TRUE ) 1629 /* If SCO open was initiated from HS, it must be CVSD */ 1630 p_scb->inuse_codec = BTA_AG_CODEC_NONE; 1631 #endif 1632 1633 BTM_EScoConnRsp(p_data->sco_inx, hci_status, &resp); 1634 } 1635 1636 /******************************************************************************* 1637 ** 1638 ** Function bta_ag_ci_sco_data 1639 ** 1640 ** Description Process the SCO data ready callin event 1641 ** 1642 ** 1643 ** Returns void 1644 ** 1645 *******************************************************************************/ 1646 void bta_ag_ci_sco_data(tBTA_AG_SCB *p_scb, tBTA_AG_DATA *p_data) 1647 { 1648 UNUSED(p_scb); 1649 UNUSED(p_data); 1650 1651 #if (BTM_SCO_HCI_INCLUDED == TRUE ) 1652 bta_ag_sco_event(p_scb, BTA_AG_SCO_CI_DATA_E); 1653 #endif 1654 } 1655 1656 /******************************************************************************* 1657 ** 1658 ** Function bta_ag_set_esco_param 1659 ** 1660 ** Description Update esco parameters from script wrapper. 1661 ** 1662 ** 1663 ** Returns void 1664 ** 1665 *******************************************************************************/ 1666 void bta_ag_set_esco_param(BOOLEAN set_reset, tBTM_ESCO_PARAMS *param) 1667 { 1668 if(set_reset == FALSE) /* reset the parameters to default */ 1669 { 1670 bta_ag_cb.sco.param_updated = FALSE; 1671 APPL_TRACE_DEBUG("bta_ag_set_esco_param : Resetting ESCO parameters to default"); 1672 } 1673 else 1674 { 1675 bta_ag_cb.sco.param_updated = TRUE; 1676 bta_ag_cb.sco.params = *param; 1677 APPL_TRACE_DEBUG("bta_ag_set_esco_param : Setting ESCO parameters"); 1678 } 1679 } 1680 1681 /******************************************************************************* 1682 ** Debugging functions 1683 *******************************************************************************/ 1684 1685 #if BTA_AG_SCO_DEBUG == TRUE 1686 static char *bta_ag_sco_evt_str(UINT8 event) 1687 { 1688 switch (event) 1689 { 1690 case BTA_AG_SCO_LISTEN_E: 1691 return "Listen Request"; 1692 case BTA_AG_SCO_OPEN_E: 1693 return "Open Request"; 1694 case BTA_AG_SCO_XFER_E: 1695 return "Transfer Request"; 1696 #if (BTM_WBS_INCLUDED == TRUE ) 1697 case BTA_AG_SCO_CN_DONE_E: 1698 return "Codec Negotiation Done"; 1699 case BTA_AG_SCO_REOPEN_E: 1700 return "Reopen Request"; 1701 #endif 1702 case BTA_AG_SCO_CLOSE_E: 1703 return "Close Request"; 1704 case BTA_AG_SCO_SHUTDOWN_E: 1705 return "Shutdown Request"; 1706 case BTA_AG_SCO_CONN_OPEN_E: 1707 return "Opened"; 1708 case BTA_AG_SCO_CONN_CLOSE_E: 1709 return "Closed"; 1710 case BTA_AG_SCO_CI_DATA_E : 1711 return "Sco Data"; 1712 default: 1713 return "Unknown SCO Event"; 1714 } 1715 } 1716 1717 static char *bta_ag_sco_state_str(UINT8 state) 1718 { 1719 switch (state) 1720 { 1721 case BTA_AG_SCO_SHUTDOWN_ST: 1722 return "Shutdown"; 1723 case BTA_AG_SCO_LISTEN_ST: 1724 return "Listening"; 1725 #if (BTM_WBS_INCLUDED == TRUE ) 1726 case BTA_AG_SCO_CODEC_ST: 1727 return "Codec Negotiation"; 1728 #endif 1729 case BTA_AG_SCO_OPENING_ST: 1730 return "Opening"; 1731 case BTA_AG_SCO_OPEN_CL_ST: 1732 return "Open while closing"; 1733 case BTA_AG_SCO_OPEN_XFER_ST: 1734 return "Opening while Transferring"; 1735 case BTA_AG_SCO_OPEN_ST: 1736 return "Open"; 1737 case BTA_AG_SCO_CLOSING_ST: 1738 return "Closing"; 1739 case BTA_AG_SCO_CLOSE_OP_ST: 1740 return "Close while Opening"; 1741 case BTA_AG_SCO_CLOSE_XFER_ST: 1742 return "Close while Transferring"; 1743 case BTA_AG_SCO_SHUTTING_ST: 1744 return "Shutting Down"; 1745 default: 1746 return "Unknown SCO State"; 1747 } 1748 } 1749 1750 #endif 1751