1 /****************************************************************************** 2 * 3 * Copyright (C) 2003-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 action functions for the audio gateway. 22 * 23 ******************************************************************************/ 24 25 #include <string.h> 26 27 #include "bta_ag_api.h" 28 #include "bta_ag_co.h" 29 #include "bta_ag_int.h" 30 #include "bta_api.h" 31 #include "bta_dm_api.h" 32 #include "bta_sys.h" 33 #include "l2c_api.h" 34 #include "osi/include/osi.h" 35 #include "port_api.h" 36 #include "utl.h" 37 38 /***************************************************************************** 39 * Constants 40 ****************************************************************************/ 41 42 /* maximum length of data to read from RFCOMM */ 43 #define BTA_AG_RFC_READ_MAX 512 44 45 /* maximum AT command length */ 46 #define BTA_AG_CMD_MAX 512 47 48 const uint16_t bta_ag_uuid[BTA_AG_NUM_IDX] = { 49 UUID_SERVCLASS_HEADSET_AUDIO_GATEWAY, UUID_SERVCLASS_AG_HANDSFREE}; 50 51 const uint8_t bta_ag_sec_id[BTA_AG_NUM_IDX] = {BTM_SEC_SERVICE_HEADSET_AG, 52 BTM_SEC_SERVICE_AG_HANDSFREE}; 53 54 const tBTA_SERVICE_ID bta_ag_svc_id[BTA_AG_NUM_IDX] = {BTA_HSP_SERVICE_ID, 55 BTA_HFP_SERVICE_ID}; 56 57 const tBTA_SERVICE_MASK bta_ag_svc_mask[BTA_AG_NUM_IDX] = { 58 BTA_HSP_SERVICE_MASK, BTA_HFP_SERVICE_MASK}; 59 60 typedef void (*tBTA_AG_ATCMD_CBACK)(tBTA_AG_SCB* p_scb, uint16_t cmd, 61 uint8_t arg_type, char* p_arg, 62 int16_t int_arg); 63 64 const tBTA_AG_ATCMD_CBACK bta_ag_at_cback_tbl[BTA_AG_NUM_IDX] = { 65 bta_ag_at_hsp_cback, bta_ag_at_hfp_cback}; 66 67 /******************************************************************************* 68 * 69 * Function bta_ag_cback_open 70 * 71 * Description Send open callback event to application. 72 * 73 * 74 * Returns void 75 * 76 ******************************************************************************/ 77 static void bta_ag_cback_open(tBTA_AG_SCB* p_scb, tBTA_AG_DATA* p_data, 78 tBTA_AG_STATUS status) { 79 tBTA_AG_OPEN open; 80 81 /* call app callback with open event */ 82 open.hdr.handle = bta_ag_scb_to_idx(p_scb); 83 open.hdr.app_id = p_scb->app_id; 84 open.status = status; 85 open.service_id = bta_ag_svc_id[p_scb->conn_service]; 86 if (p_data) { 87 /* if p_data is provided then we need to pick the bd address from the open 88 * api structure */ 89 open.bd_addr = p_data->api_open.bd_addr; 90 } else { 91 open.bd_addr = p_scb->peer_addr; 92 } 93 94 (*bta_ag_cb.p_cback)(BTA_AG_OPEN_EVT, (tBTA_AG*)&open); 95 } 96 97 /******************************************************************************* 98 * 99 * Function bta_ag_register 100 * 101 * Description This function initializes values of the AG cb and sets up 102 * the SDP record for the services. 103 * 104 * 105 * Returns void 106 * 107 ******************************************************************************/ 108 void bta_ag_register(tBTA_AG_SCB* p_scb, tBTA_AG_DATA* p_data) { 109 tBTA_AG_REGISTER reg; 110 111 /* initialize control block */ 112 p_scb->reg_services = p_data->api_register.services; 113 p_scb->serv_sec_mask = p_data->api_register.sec_mask; 114 p_scb->features = p_data->api_register.features; 115 p_scb->app_id = p_data->api_register.app_id; 116 117 /* create SDP records */ 118 bta_ag_create_records(p_scb, p_data); 119 120 /* start RFCOMM servers */ 121 bta_ag_start_servers(p_scb, p_scb->reg_services); 122 123 /* call app callback with register event */ 124 reg.hdr.handle = bta_ag_scb_to_idx(p_scb); 125 reg.hdr.app_id = p_scb->app_id; 126 reg.status = BTA_AG_SUCCESS; 127 (*bta_ag_cb.p_cback)(BTA_AG_REGISTER_EVT, (tBTA_AG*)®); 128 } 129 130 /******************************************************************************* 131 * 132 * Function bta_ag_deregister 133 * 134 * Description This function removes the sdp records, closes the RFCOMM 135 * servers, and deallocates the service control block. 136 * 137 * 138 * Returns void 139 * 140 ******************************************************************************/ 141 void bta_ag_deregister(tBTA_AG_SCB* p_scb, tBTA_AG_DATA* p_data) { 142 /* set dealloc */ 143 p_scb->dealloc = true; 144 145 /* remove sdp records */ 146 bta_ag_del_records(p_scb, p_data); 147 148 /* remove rfcomm servers */ 149 bta_ag_close_servers(p_scb, p_scb->reg_services); 150 151 /* dealloc */ 152 bta_ag_scb_dealloc(p_scb); 153 } 154 155 /******************************************************************************* 156 * 157 * Function bta_ag_start_dereg 158 * 159 * Description Start a deregister event. 160 * 161 * 162 * Returns void 163 * 164 ******************************************************************************/ 165 void bta_ag_start_dereg(tBTA_AG_SCB* p_scb, tBTA_AG_DATA* p_data) { 166 /* set dealloc */ 167 p_scb->dealloc = true; 168 169 /* remove sdp records */ 170 bta_ag_del_records(p_scb, p_data); 171 } 172 173 /******************************************************************************* 174 * 175 * Function bta_ag_start_open 176 * 177 * Description This starts an AG open. 178 * 179 * 180 * Returns void 181 * 182 ******************************************************************************/ 183 void bta_ag_start_open(tBTA_AG_SCB* p_scb, tBTA_AG_DATA* p_data) { 184 RawAddress pending_bd_addr; 185 186 /* store parameters */ 187 if (p_data) { 188 p_scb->peer_addr = p_data->api_open.bd_addr; 189 p_scb->open_services = p_data->api_open.services; 190 p_scb->cli_sec_mask = p_data->api_open.sec_mask; 191 } 192 193 /* Check if RFCOMM has any incoming connection to avoid collision. */ 194 if (PORT_IsOpening(pending_bd_addr)) { 195 /* Let the incoming connection goes through. */ 196 /* Issue collision for this scb for now. */ 197 /* We will decide what to do when we find incoming connetion later. */ 198 bta_ag_collision_cback(0, BTA_ID_AG, 0, &p_scb->peer_addr); 199 return; 200 } 201 202 /* close servers */ 203 bta_ag_close_servers(p_scb, p_scb->reg_services); 204 205 /* set role */ 206 p_scb->role = BTA_AG_INT; 207 208 /* do service search */ 209 bta_ag_do_disc(p_scb, p_scb->open_services); 210 } 211 212 /******************************************************************************* 213 * 214 * Function bta_ag_disc_int_res 215 * 216 * Description This function handles a discovery result when initiator. 217 * 218 * 219 * Returns void 220 * 221 ******************************************************************************/ 222 void bta_ag_disc_int_res(tBTA_AG_SCB* p_scb, tBTA_AG_DATA* p_data) { 223 uint16_t event = BTA_AG_DISC_FAIL_EVT; 224 225 APPL_TRACE_DEBUG("bta_ag_disc_int_res: Status: %d", 226 p_data->disc_result.status); 227 228 /* if found service */ 229 if (p_data->disc_result.status == SDP_SUCCESS || 230 p_data->disc_result.status == SDP_DB_FULL) { 231 /* get attributes */ 232 if (bta_ag_sdp_find_attr(p_scb, p_scb->open_services)) { 233 /* set connected service */ 234 p_scb->conn_service = bta_ag_service_to_idx(p_scb->open_services); 235 236 /* send ourselves sdp ok event */ 237 event = BTA_AG_DISC_OK_EVT; 238 } 239 } 240 241 /* free discovery db */ 242 bta_ag_free_db(p_scb, p_data); 243 244 /* if service not found check if we should search for other service */ 245 if ((event == BTA_AG_DISC_FAIL_EVT) && 246 (p_data->disc_result.status == SDP_SUCCESS || 247 p_data->disc_result.status == SDP_DB_FULL || 248 p_data->disc_result.status == SDP_NO_RECS_MATCH)) { 249 if ((p_scb->open_services & BTA_HFP_SERVICE_MASK) && 250 (p_scb->open_services & BTA_HSP_SERVICE_MASK)) { 251 /* search for HSP */ 252 p_scb->open_services &= ~BTA_HFP_SERVICE_MASK; 253 bta_ag_do_disc(p_scb, p_scb->open_services); 254 } else if ((p_scb->open_services & BTA_HSP_SERVICE_MASK) && 255 (p_scb->hsp_version == HSP_VERSION_1_2)) { 256 /* search for UUID_SERVCLASS_HEADSET instead */ 257 p_scb->hsp_version = HSP_VERSION_1_0; 258 bta_ag_do_disc(p_scb, p_scb->open_services); 259 } else { 260 /* send ourselves sdp ok/fail event */ 261 bta_ag_sm_execute(p_scb, event, p_data); 262 } 263 } else { 264 /* send ourselves sdp ok/fail event */ 265 bta_ag_sm_execute(p_scb, event, p_data); 266 } 267 } 268 269 /******************************************************************************* 270 * 271 * Function bta_ag_disc_acp_res 272 * 273 * Description This function handles a discovery result when acceptor. 274 * 275 * 276 * Returns void 277 * 278 ******************************************************************************/ 279 void bta_ag_disc_acp_res(tBTA_AG_SCB* p_scb, tBTA_AG_DATA* p_data) { 280 /* if found service */ 281 if (p_data->disc_result.status == SDP_SUCCESS || 282 p_data->disc_result.status == SDP_DB_FULL) { 283 /* get attributes */ 284 bta_ag_sdp_find_attr(p_scb, bta_ag_svc_mask[p_scb->conn_service]); 285 } 286 287 /* free discovery db */ 288 bta_ag_free_db(p_scb, p_data); 289 } 290 291 /******************************************************************************* 292 * 293 * Function bta_ag_disc_fail 294 * 295 * Description This function handles a discovery failure. 296 * 297 * 298 * Returns void 299 * 300 ******************************************************************************/ 301 void bta_ag_disc_fail(tBTA_AG_SCB* p_scb, UNUSED_ATTR tBTA_AG_DATA* p_data) { 302 /* reopen registered servers */ 303 bta_ag_start_servers(p_scb, p_scb->reg_services); 304 305 /* reinitialize stuff */ 306 307 /* clear the remote BD address */ 308 p_scb->peer_addr = RawAddress::kEmpty; 309 310 /* call open cback w. failure */ 311 bta_ag_cback_open(p_scb, NULL, BTA_AG_FAIL_SDP); 312 } 313 314 /******************************************************************************* 315 * 316 * Function bta_ag_open_fail 317 * 318 * Description open connection failed. 319 * 320 * 321 * Returns void 322 * 323 ******************************************************************************/ 324 void bta_ag_open_fail(tBTA_AG_SCB* p_scb, tBTA_AG_DATA* p_data) { 325 /* call open cback w. failure */ 326 bta_ag_cback_open(p_scb, p_data, BTA_AG_FAIL_RESOURCES); 327 } 328 329 /******************************************************************************* 330 * 331 * Function bta_ag_rfc_fail 332 * 333 * Description RFCOMM connection failed. 334 * 335 * 336 * Returns void 337 * 338 ******************************************************************************/ 339 void bta_ag_rfc_fail(tBTA_AG_SCB* p_scb, UNUSED_ATTR tBTA_AG_DATA* p_data) { 340 /* reinitialize stuff */ 341 p_scb->conn_handle = 0; 342 p_scb->conn_service = 0; 343 p_scb->peer_features = 0; 344 p_scb->peer_codecs = BTA_AG_CODEC_CVSD; 345 p_scb->sco_codec = BTA_AG_CODEC_CVSD; 346 p_scb->role = 0; 347 p_scb->svc_conn = false; 348 p_scb->hsp_version = HSP_VERSION_1_2; 349 /*Clear the BD address*/ 350 p_scb->peer_addr = RawAddress::kEmpty; 351 352 /* reopen registered servers */ 353 bta_ag_start_servers(p_scb, p_scb->reg_services); 354 355 /* call open cback w. failure */ 356 bta_ag_cback_open(p_scb, NULL, BTA_AG_FAIL_RFCOMM); 357 } 358 359 /******************************************************************************* 360 * 361 * Function bta_ag_rfc_close 362 * 363 * Description RFCOMM connection closed. 364 * 365 * 366 * Returns void 367 * 368 ******************************************************************************/ 369 void bta_ag_rfc_close(tBTA_AG_SCB* p_scb, UNUSED_ATTR tBTA_AG_DATA* p_data) { 370 tBTA_AG_CLOSE close; 371 tBTA_SERVICE_MASK services; 372 int i, num_active_conn = 0; 373 374 /* reinitialize stuff */ 375 p_scb->conn_service = 0; 376 p_scb->peer_features = 0; 377 p_scb->peer_codecs = BTA_AG_CODEC_CVSD; 378 p_scb->sco_codec = BTA_AG_CODEC_CVSD; 379 /* Clear these flags upon SLC teardown */ 380 p_scb->codec_updated = false; 381 p_scb->codec_fallback = false; 382 p_scb->codec_msbc_settings = BTA_AG_SCO_MSBC_SETTINGS_T2; 383 p_scb->role = 0; 384 p_scb->post_sco = BTA_AG_POST_SCO_NONE; 385 p_scb->svc_conn = false; 386 p_scb->hsp_version = HSP_VERSION_1_2; 387 bta_ag_at_reinit(&p_scb->at_cb); 388 389 memset(&(p_scb->peer_hf_indicators), 0, sizeof(p_scb->peer_hf_indicators)); 390 memset(&(p_scb->local_hf_indicators), 0, sizeof(p_scb->local_hf_indicators)); 391 392 /* stop timers */ 393 alarm_cancel(p_scb->ring_timer); 394 alarm_cancel(p_scb->codec_negotiation_timer); 395 396 close.hdr.handle = bta_ag_scb_to_idx(p_scb); 397 close.hdr.app_id = p_scb->app_id; 398 close.bd_addr = p_scb->peer_addr; 399 400 bta_sys_conn_close(BTA_ID_AG, p_scb->app_id, p_scb->peer_addr); 401 402 /* call close call-out */ 403 bta_ag_co_data_close(close.hdr.handle); 404 405 /* call close cback */ 406 (*bta_ag_cb.p_cback)(BTA_AG_CLOSE_EVT, (tBTA_AG*)&close); 407 408 /* if not deregistering (deallocating) reopen registered servers */ 409 if (p_scb->dealloc == false) { 410 /* Clear peer bd_addr so instance can be reused */ 411 p_scb->peer_addr = RawAddress::kEmpty; 412 413 /* start only unopened server */ 414 services = p_scb->reg_services; 415 for (i = 0; i < BTA_AG_NUM_IDX && services != 0; i++) { 416 if (p_scb->serv_handle[i]) 417 services &= ~((tBTA_SERVICE_MASK)1 << (BTA_HSP_SERVICE_ID + i)); 418 } 419 bta_ag_start_servers(p_scb, services); 420 421 p_scb->conn_handle = 0; 422 423 /* Make sure SCO state is BTA_AG_SCO_SHUTDOWN_ST */ 424 bta_ag_sco_shutdown(p_scb, NULL); 425 426 /* Check if all the SLCs are down */ 427 for (i = 0; i < BTA_AG_NUM_SCB; i++) { 428 if (bta_ag_cb.scb[i].in_use && bta_ag_cb.scb[i].svc_conn) 429 num_active_conn++; 430 } 431 432 if (!num_active_conn) { 433 bta_sys_sco_unuse(BTA_ID_AG, p_scb->app_id, p_scb->peer_addr); 434 } 435 436 } 437 /* else close port and deallocate scb */ 438 else { 439 RFCOMM_RemoveServer(p_scb->conn_handle); 440 bta_ag_scb_dealloc(p_scb); 441 } 442 } 443 444 /******************************************************************************* 445 * 446 * Function bta_ag_rfc_open 447 * 448 * Description Handle RFCOMM channel open. 449 * 450 * 451 * Returns void 452 * 453 ******************************************************************************/ 454 void bta_ag_rfc_open(tBTA_AG_SCB* p_scb, tBTA_AG_DATA* p_data) { 455 /* initialize AT feature variables */ 456 p_scb->clip_enabled = false; 457 p_scb->ccwa_enabled = false; 458 p_scb->cmer_enabled = false; 459 p_scb->cmee_enabled = false; 460 p_scb->inband_enabled = 461 ((p_scb->features & BTA_AG_FEAT_INBAND) == BTA_AG_FEAT_INBAND); 462 463 /* set up AT command interpreter */ 464 p_scb->at_cb.p_at_tbl = (tBTA_AG_AT_CMD*)bta_ag_at_tbl[p_scb->conn_service]; 465 p_scb->at_cb.p_cmd_cback = 466 (tBTA_AG_AT_CMD_CBACK*)bta_ag_at_cback_tbl[p_scb->conn_service]; 467 p_scb->at_cb.p_err_cback = (tBTA_AG_AT_ERR_CBACK*)bta_ag_at_err_cback; 468 p_scb->at_cb.p_user = p_scb; 469 p_scb->at_cb.cmd_max_len = BTA_AG_CMD_MAX; 470 bta_ag_at_init(&p_scb->at_cb); 471 472 /* call app open call-out */ 473 bta_ag_co_data_open(bta_ag_scb_to_idx(p_scb), 474 bta_ag_svc_id[p_scb->conn_service]); 475 476 bta_sys_conn_open(BTA_ID_AG, p_scb->app_id, p_scb->peer_addr); 477 478 bta_ag_cback_open(p_scb, NULL, BTA_AG_SUCCESS); 479 480 if (p_scb->conn_service == BTA_AG_HFP) { 481 /* if hfp start timer for service level conn */ 482 bta_sys_start_timer(p_scb->ring_timer, p_bta_ag_cfg->conn_tout, 483 BTA_AG_SVC_TIMEOUT_EVT, bta_ag_scb_to_idx(p_scb)); 484 } else { 485 /* else service level conn is open */ 486 bta_ag_svc_conn_open(p_scb, p_data); 487 } 488 } 489 490 /******************************************************************************* 491 * 492 * Function bta_ag_rfc_acp_open 493 * 494 * Description Handle RFCOMM channel open when accepting connection. 495 * 496 * 497 * Returns void 498 * 499 ******************************************************************************/ 500 void bta_ag_rfc_acp_open(tBTA_AG_SCB* p_scb, tBTA_AG_DATA* p_data) { 501 uint16_t lcid; 502 int i; 503 tBTA_AG_SCB *ag_scb, *other_scb; 504 RawAddress dev_addr; 505 int status; 506 507 /* set role */ 508 p_scb->role = BTA_AG_ACP; 509 510 APPL_TRACE_DEBUG("bta_ag_rfc_acp_open: serv_handle0 = %d serv_handle1 = %d", 511 p_scb->serv_handle[0], p_scb->serv_handle[1]); 512 513 /* get bd addr of peer */ 514 if (PORT_SUCCESS != (status = PORT_CheckConnection(p_data->rfc.port_handle, 515 dev_addr, &lcid))) { 516 APPL_TRACE_DEBUG( 517 "bta_ag_rfc_acp_open error PORT_CheckConnection returned status %d", 518 status); 519 } 520 521 /* Collision Handling */ 522 for (i = 0, ag_scb = &bta_ag_cb.scb[0]; i < BTA_AG_NUM_SCB; i++, ag_scb++) { 523 if (ag_scb->in_use && alarm_is_scheduled(ag_scb->collision_timer)) { 524 alarm_cancel(ag_scb->collision_timer); 525 526 if (dev_addr == ag_scb->peer_addr) { 527 /* If incoming and outgoing device are same, nothing more to do. */ 528 /* Outgoing conn will be aborted because we have successful incoming 529 * conn. */ 530 } else { 531 /* Resume outgoing connection. */ 532 other_scb = bta_ag_get_other_idle_scb(p_scb); 533 if (other_scb) { 534 other_scb->peer_addr = ag_scb->peer_addr; 535 other_scb->open_services = ag_scb->open_services; 536 other_scb->cli_sec_mask = ag_scb->cli_sec_mask; 537 538 bta_ag_resume_open(other_scb); 539 } 540 } 541 542 break; 543 } 544 } 545 546 p_scb->peer_addr = dev_addr; 547 548 /* determine connected service from port handle */ 549 for (i = 0; i < BTA_AG_NUM_IDX; i++) { 550 APPL_TRACE_DEBUG( 551 "bta_ag_rfc_acp_open: i = %d serv_handle = %d port_handle = %d", i, 552 p_scb->serv_handle[i], p_data->rfc.port_handle); 553 554 if (p_scb->serv_handle[i] == p_data->rfc.port_handle) { 555 p_scb->conn_service = i; 556 p_scb->conn_handle = p_data->rfc.port_handle; 557 break; 558 } 559 } 560 561 APPL_TRACE_DEBUG("bta_ag_rfc_acp_open: conn_service = %d conn_handle = %d", 562 p_scb->conn_service, p_scb->conn_handle); 563 564 /* close any unopened server */ 565 bta_ag_close_servers( 566 p_scb, (p_scb->reg_services & ~bta_ag_svc_mask[p_scb->conn_service])); 567 568 /* do service discovery to get features */ 569 bta_ag_do_disc(p_scb, bta_ag_svc_mask[p_scb->conn_service]); 570 571 /* continue with common open processing */ 572 bta_ag_rfc_open(p_scb, p_data); 573 } 574 575 /******************************************************************************* 576 * 577 * Function bta_ag_rfc_data 578 * 579 * Description Read and process data from RFCOMM. 580 * 581 * 582 * Returns void 583 * 584 ******************************************************************************/ 585 void bta_ag_rfc_data(tBTA_AG_SCB* p_scb, UNUSED_ATTR tBTA_AG_DATA* p_data) { 586 uint16_t len; 587 char buf[BTA_AG_RFC_READ_MAX]; 588 589 memset(buf, 0, BTA_AG_RFC_READ_MAX); 590 591 APPL_TRACE_DEBUG("%s", __func__); 592 593 /* do the following */ 594 for (;;) { 595 /* read data from rfcomm; if bad status, we're done */ 596 if (PORT_ReadData(p_scb->conn_handle, buf, BTA_AG_RFC_READ_MAX, &len) != 597 PORT_SUCCESS) { 598 break; 599 } 600 601 /* if no data, we're done */ 602 if (len == 0) { 603 break; 604 } 605 606 /* run AT command interpreter on data */ 607 bta_sys_busy(BTA_ID_AG, p_scb->app_id, p_scb->peer_addr); 608 bta_ag_at_parse(&p_scb->at_cb, buf, len); 609 if ((p_scb->sco_idx != BTM_INVALID_SCO_INDEX) && 610 bta_ag_sco_is_open(p_scb)) { 611 APPL_TRACE_DEBUG("%s change link policy for SCO", __func__); 612 bta_sys_sco_open(BTA_ID_AG, p_scb->app_id, p_scb->peer_addr); 613 } else { 614 bta_sys_idle(BTA_ID_AG, p_scb->app_id, p_scb->peer_addr); 615 } 616 617 /* no more data to read, we're done */ 618 if (len < BTA_AG_RFC_READ_MAX) { 619 break; 620 } 621 } 622 } 623 624 /******************************************************************************* 625 * 626 * Function bta_ag_start_close 627 * 628 * Description Start the process of closing SCO and RFCOMM connection. 629 * 630 * 631 * Returns void 632 * 633 ******************************************************************************/ 634 void bta_ag_start_close(tBTA_AG_SCB* p_scb, tBTA_AG_DATA* p_data) { 635 /* Take the link out of sniff and set L2C idle time to 0 */ 636 bta_dm_pm_active(p_scb->peer_addr); 637 L2CA_SetIdleTimeoutByBdAddr(p_scb->peer_addr, 0, BT_TRANSPORT_BR_EDR); 638 639 /* if SCO is open close SCO and wait on RFCOMM close */ 640 if (bta_ag_sco_is_open(p_scb)) { 641 p_scb->post_sco = BTA_AG_POST_SCO_CLOSE_RFC; 642 } else { 643 p_scb->post_sco = BTA_AG_POST_SCO_NONE; 644 bta_ag_rfc_do_close(p_scb, p_data); 645 } 646 647 /* always do SCO shutdown to handle all SCO corner cases */ 648 bta_ag_sco_shutdown(p_scb, p_data); 649 } 650 651 /******************************************************************************* 652 * 653 * Function bta_ag_post_sco_open 654 * 655 * Description Perform post-SCO open action, if any 656 * 657 * 658 * Returns void 659 * 660 ******************************************************************************/ 661 void bta_ag_post_sco_open(tBTA_AG_SCB* p_scb, tBTA_AG_DATA* p_data) { 662 switch (p_scb->post_sco) { 663 case BTA_AG_POST_SCO_RING: 664 bta_ag_send_ring(p_scb, p_data); 665 p_scb->post_sco = BTA_AG_POST_SCO_NONE; 666 break; 667 668 case BTA_AG_POST_SCO_CALL_CONN: 669 bta_ag_send_call_inds(p_scb, BTA_AG_IN_CALL_CONN_RES); 670 p_scb->post_sco = BTA_AG_POST_SCO_NONE; 671 break; 672 673 default: 674 break; 675 } 676 } 677 678 /******************************************************************************* 679 * 680 * Function bta_ag_post_sco_close 681 * 682 * Description Perform post-SCO close action, if any 683 * 684 * 685 * Returns void 686 * 687 ******************************************************************************/ 688 void bta_ag_post_sco_close(tBTA_AG_SCB* p_scb, tBTA_AG_DATA* p_data) { 689 switch (p_scb->post_sco) { 690 case BTA_AG_POST_SCO_CLOSE_RFC: 691 bta_ag_rfc_do_close(p_scb, p_data); 692 p_scb->post_sco = BTA_AG_POST_SCO_NONE; 693 break; 694 695 case BTA_AG_POST_SCO_CALL_CONN: 696 bta_ag_send_call_inds(p_scb, BTA_AG_IN_CALL_CONN_RES); 697 p_scb->post_sco = BTA_AG_POST_SCO_NONE; 698 break; 699 700 case BTA_AG_POST_SCO_CALL_ORIG: 701 bta_ag_send_call_inds(p_scb, BTA_AG_OUT_CALL_ORIG_RES); 702 p_scb->post_sco = BTA_AG_POST_SCO_NONE; 703 break; 704 705 case BTA_AG_POST_SCO_CALL_END: 706 bta_ag_send_call_inds(p_scb, BTA_AG_END_CALL_RES); 707 p_scb->post_sco = BTA_AG_POST_SCO_NONE; 708 break; 709 710 case BTA_AG_POST_SCO_CALL_END_INCALL: 711 bta_ag_send_call_inds(p_scb, BTA_AG_END_CALL_RES); 712 713 /* Sending callsetup IND and Ring were defered to after SCO close. */ 714 bta_ag_send_call_inds(p_scb, BTA_AG_IN_CALL_RES); 715 716 if (bta_ag_inband_enabled(p_scb) && 717 !(p_scb->features & BTA_AG_FEAT_NOSCO)) { 718 p_scb->post_sco = BTA_AG_POST_SCO_RING; 719 bta_ag_sco_open(p_scb, p_data); 720 } else { 721 p_scb->post_sco = BTA_AG_POST_SCO_NONE; 722 bta_ag_send_ring(p_scb, p_data); 723 } 724 break; 725 726 default: 727 break; 728 } 729 } 730 731 /******************************************************************************* 732 * 733 * Function bta_ag_svc_conn_open 734 * 735 * Description Service level connection opened 736 * 737 * 738 * Returns void 739 * 740 ******************************************************************************/ 741 void bta_ag_svc_conn_open(tBTA_AG_SCB* p_scb, 742 UNUSED_ATTR tBTA_AG_DATA* p_data) { 743 tBTA_AG_CONN evt; 744 745 if (!p_scb->svc_conn) { 746 /* set state variable */ 747 p_scb->svc_conn = true; 748 749 /* Clear AT+BIA mask from previous SLC if any. */ 750 p_scb->bia_masked_out = 0; 751 752 alarm_cancel(p_scb->ring_timer); 753 754 /* call callback */ 755 evt.hdr.handle = bta_ag_scb_to_idx(p_scb); 756 evt.hdr.app_id = p_scb->app_id; 757 evt.peer_feat = p_scb->peer_features; 758 evt.bd_addr = p_scb->peer_addr; 759 evt.peer_codec = p_scb->peer_codecs; 760 761 if ((p_scb->call_ind != BTA_AG_CALL_INACTIVE) || 762 (p_scb->callsetup_ind != BTA_AG_CALLSETUP_NONE)) { 763 bta_sys_sco_use(BTA_ID_AG, p_scb->app_id, p_scb->peer_addr); 764 } 765 766 (*bta_ag_cb.p_cback)(BTA_AG_CONN_EVT, (tBTA_AG*)&evt); 767 } 768 } 769 770 /******************************************************************************* 771 * 772 * Function bta_ag_ci_rx_data 773 * 774 * Description Send result code 775 * 776 * Returns void 777 * 778 ******************************************************************************/ 779 void bta_ag_ci_rx_data(tBTA_AG_SCB* p_scb, tBTA_AG_DATA* p_data) { 780 uint16_t len; 781 tBTA_AG_CI_RX_WRITE* p_rx_write_msg = (tBTA_AG_CI_RX_WRITE*)p_data; 782 char* p_data_area = 783 (char*)(p_rx_write_msg + 1); /* Point to data area after header */ 784 785 APPL_TRACE_DEBUG("bta_ag_ci_rx_data:"); 786 /* send to RFCOMM */ 787 bta_sys_busy(BTA_ID_AG, p_scb->app_id, p_scb->peer_addr); 788 PORT_WriteData(p_scb->conn_handle, p_data_area, strlen(p_data_area), &len); 789 if ((p_scb->sco_idx != BTM_INVALID_SCO_INDEX) && bta_ag_sco_is_open(p_scb)) { 790 APPL_TRACE_DEBUG("bta_ag_rfc_data, change link policy for SCO"); 791 bta_sys_sco_open(BTA_ID_AG, p_scb->app_id, p_scb->peer_addr); 792 } else { 793 bta_sys_idle(BTA_ID_AG, p_scb->app_id, p_scb->peer_addr); 794 } 795 } 796 797 /******************************************************************************* 798 * 799 * Function bta_ag_rcvd_slc_ready 800 * 801 * Description Handles SLC ready call-in in case of pass-through mode. 802 * 803 * Returns void 804 * 805 ******************************************************************************/ 806 void bta_ag_rcvd_slc_ready(tBTA_AG_SCB* p_scb, 807 UNUSED_ATTR tBTA_AG_DATA* p_data) { 808 APPL_TRACE_DEBUG("bta_ag_rcvd_slc_ready: handle = %d", 809 bta_ag_scb_to_idx(p_scb)); 810 811 if (bta_ag_cb.parse_mode == BTA_AG_PASS_THROUGH) { 812 /* In pass-through mode, BTA knows that SLC is ready only through call-in. 813 */ 814 bta_ag_svc_conn_open(p_scb, NULL); 815 } 816 } 817 818 /******************************************************************************* 819 * 820 * Function bta_ag_setcodec 821 * 822 * Description Handle API SetCodec 823 * 824 * 825 * Returns void 826 * 827 ******************************************************************************/ 828 void bta_ag_setcodec(tBTA_AG_SCB* p_scb, tBTA_AG_DATA* p_data) { 829 tBTA_AG_PEER_CODEC codec_type = p_data->api_setcodec.codec; 830 tBTA_AG_VAL val; 831 832 /* Check if the requested codec type is valid */ 833 if ((codec_type != BTA_AG_CODEC_NONE) && (codec_type != BTA_AG_CODEC_CVSD) && 834 (codec_type != BTA_AG_CODEC_MSBC)) { 835 val.num = codec_type; 836 val.hdr.status = BTA_AG_FAIL_RESOURCES; 837 APPL_TRACE_ERROR("bta_ag_setcodec error: unsupported codec type %d", 838 codec_type); 839 (*bta_ag_cb.p_cback)(BTA_AG_WBS_EVT, (tBTA_AG*)&val); 840 return; 841 } 842 843 if ((p_scb->peer_codecs & codec_type) || (codec_type == BTA_AG_CODEC_NONE) || 844 (codec_type == BTA_AG_CODEC_CVSD)) { 845 p_scb->sco_codec = codec_type; 846 p_scb->codec_updated = true; 847 val.num = codec_type; 848 val.hdr.status = BTA_AG_SUCCESS; 849 APPL_TRACE_DEBUG("bta_ag_setcodec: Updated codec type %d", codec_type); 850 } else { 851 val.num = codec_type; 852 val.hdr.status = BTA_AG_FAIL_RESOURCES; 853 APPL_TRACE_ERROR("bta_ag_setcodec error: unsupported codec type %d", 854 codec_type); 855 } 856 857 (*bta_ag_cb.p_cback)(BTA_AG_WBS_EVT, (tBTA_AG*)&val); 858 } 859