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