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