1/****************************************************************************** 2 * 3 * Copyright (c) 2014 The Android Open Source Project 4 * Copyright (C) 2003-2012 Broadcom Corporation 5 * 6 * Licensed under the Apache License, Version 2.0 (the "License"); 7 * you may not use this file except in compliance with the License. 8 * You may obtain a copy of the License at: 9 * 10 * http://www.apache.org/licenses/LICENSE-2.0 11 * 12 * Unless required by applicable law or agreed to in writing, software 13 * distributed under the License is distributed on an "AS IS" BASIS, 14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 * See the License for the specific language governing permissions and 16 * limitations under the License. 17 * 18 ******************************************************************************/ 19 20/****************************************************************************** 21 * 22 * This file contains action functions for the handsfree client. 23 * 24 ******************************************************************************/ 25 26#include "bta_api.h" 27#include "bta_hf_client_api.h" 28#include "bta_hf_client_int.h" 29#include "bta_dm_int.h" 30#include "l2c_api.h" 31#include "port_api.h" 32#include "bta_sys.h" 33#include "utl.h" 34#include "bt_utils.h" 35#include "osi/include/compat.h" 36#include <string.h> 37 38/***************************************************************************** 39** Constants 40*****************************************************************************/ 41 42/* maximum length of data to read from RFCOMM */ 43#define BTA_HF_CLIENT_RFC_READ_MAX 512 44 45/******************************************************************************* 46** 47** Function bta_hf_client_register 48** 49** Description This function initializes values of the scb and sets up 50** the SDP record for the services. 51** 52** 53** Returns void 54** 55*******************************************************************************/ 56void bta_hf_client_register(tBTA_HF_CLIENT_DATA *p_data) 57{ 58 tBTA_HF_CLIENT evt; 59 tBTA_UTL_COD cod; 60 61 memset(&evt, 0, sizeof(evt)); 62 63 /* initialize control block */ 64 bta_hf_client_scb_init(); 65 66 bta_hf_client_cb.scb.serv_sec_mask = p_data->api_register.sec_mask; 67 bta_hf_client_cb.scb.features = p_data->api_register.features; 68 69 /* initialize AT control block */ 70 bta_hf_client_at_init(); 71 72 /* create SDP records */ 73 bta_hf_client_create_record(p_data); 74 75 /* Set the Audio service class bit */ 76 cod.service = BTM_COD_SERVICE_AUDIO; 77 utl_set_device_class(&cod, BTA_UTL_SET_COD_SERVICE_CLASS); 78 79 /* start RFCOMM server */ 80 bta_hf_client_start_server(); 81 82 /* call app callback with register event */ 83 evt.reg.status = BTA_HF_CLIENT_SUCCESS; 84 (*bta_hf_client_cb.p_cback)(BTA_HF_CLIENT_REGISTER_EVT, &evt); 85} 86 87/******************************************************************************* 88** 89** Function bta_hf_client_deregister 90** 91** Description This function removes the sdp records, closes the RFCOMM 92** servers, and deallocates the service control block. 93** 94** 95** Returns void 96** 97*******************************************************************************/ 98void bta_hf_client_deregister(tBTA_HF_CLIENT_DATA *p_data) 99{ 100 bta_hf_client_cb.scb.deregister = TRUE; 101 102 /* remove sdp record */ 103 bta_hf_client_del_record(p_data); 104 105 /* remove rfcomm server */ 106 bta_hf_client_close_server(); 107 108 /* disable */ 109 bta_hf_client_scb_disable(); 110} 111 112/******************************************************************************* 113** 114** Function bta_hf_client_start_dereg 115** 116** Description Start a deregister event. 117** 118** 119** Returns void 120** 121*******************************************************************************/ 122void bta_hf_client_start_dereg(tBTA_HF_CLIENT_DATA *p_data) 123{ 124 bta_hf_client_cb.scb.deregister = TRUE; 125 126 /* remove sdp record */ 127 bta_hf_client_del_record(p_data); 128} 129 130/******************************************************************************* 131** 132** Function bta_hf_client_start_close 133** 134** Description Start the process of closing SCO and RFCOMM connection. 135** 136** 137** Returns void 138** 139*******************************************************************************/ 140void bta_hf_client_start_close(tBTA_HF_CLIENT_DATA *p_data) 141{ 142 /* Take the link out of sniff and set L2C idle time to 0 */ 143 bta_dm_pm_active(bta_hf_client_cb.scb.peer_addr); 144 L2CA_SetIdleTimeoutByBdAddr(bta_hf_client_cb.scb.peer_addr, 0, BT_TRANSPORT_BR_EDR); 145 146 /* if SCO is open close SCO and wait on RFCOMM close */ 147 if (bta_hf_client_cb.scb.sco_state == BTA_HF_CLIENT_SCO_OPEN_ST) 148 { 149 bta_hf_client_cb.scb.sco_close_rfc = TRUE; 150 } 151 else 152 { 153 bta_hf_client_rfc_do_close(p_data); 154 } 155 156 /* always do SCO shutdown to handle all SCO corner cases */ 157 bta_hf_client_sco_shutdown(NULL); 158} 159 160/******************************************************************************* 161** 162** Function bta_hf_client_start_open 163** 164** Description This starts an HF Client open. 165** 166** 167** Returns void 168** 169*******************************************************************************/ 170void bta_hf_client_start_open(tBTA_HF_CLIENT_DATA *p_data) 171{ 172 BD_ADDR pending_bd_addr; 173 174 /* store parameters */ 175 if (p_data) 176 { 177 bdcpy(bta_hf_client_cb.scb.peer_addr, p_data->api_open.bd_addr); 178 bta_hf_client_cb.scb.cli_sec_mask = p_data->api_open.sec_mask; 179 } 180 181 /* Check if RFCOMM has any incoming connection to avoid collision. */ 182 if (PORT_IsOpening (pending_bd_addr)) 183 { 184 /* Let the incoming connection goes through. */ 185 /* Issue collision for now. */ 186 /* We will decide what to do when we find incoming connection later.*/ 187 bta_hf_client_collision_cback (0, BTA_ID_HS, 0, bta_hf_client_cb.scb.peer_addr); 188 return; 189 } 190 191 /* close server */ 192 bta_hf_client_close_server(); 193 194 /* set role */ 195 bta_hf_client_cb.scb.role = BTA_HF_CLIENT_INT; 196 197 /* do service search */ 198 bta_hf_client_do_disc(); 199} 200 201/******************************************************************************* 202** 203** Function bta_hf_client_cback_open 204** 205** Description Send open callback event to application. 206** 207** 208** Returns void 209** 210*******************************************************************************/ 211static void bta_hf_client_cback_open(tBTA_HF_CLIENT_DATA *p_data, tBTA_HF_CLIENT_STATUS status) 212{ 213 tBTA_HF_CLIENT evt; 214 215 memset(&evt, 0, sizeof(evt)); 216 217 /* call app callback with open event */ 218 evt.open.status = status; 219 if(p_data) 220 { 221 /* if p_data is provided then we need to pick the bd address from the open api structure */ 222 bdcpy(evt.open.bd_addr, p_data->api_open.bd_addr); 223 } 224 else 225 { 226 bdcpy(evt.open.bd_addr, bta_hf_client_cb.scb.peer_addr); 227 } 228 229 (*bta_hf_client_cb.p_cback)(BTA_HF_CLIENT_OPEN_EVT, &evt); 230} 231 232/******************************************************************************* 233** 234** Function bta_hf_client_rfc_open 235** 236** Description Handle RFCOMM channel open. 237** 238** 239** Returns void 240** 241*******************************************************************************/ 242void bta_hf_client_rfc_open(tBTA_HF_CLIENT_DATA *p_data) 243{ 244 UNUSED(p_data); 245 246 bta_sys_conn_open(BTA_ID_HS, 1, bta_hf_client_cb.scb.peer_addr); 247 248 bta_hf_client_cback_open(NULL, BTA_HF_CLIENT_SUCCESS); 249 250 /* start SLC procedure */ 251 bta_hf_client_slc_seq(FALSE); 252} 253 254/******************************************************************************* 255** 256** Function bta_hf_client_rfc_acp_open 257** 258** Description Handle RFCOMM channel open when accepting connection. 259** 260** 261** Returns void 262** 263*******************************************************************************/ 264void bta_hf_client_rfc_acp_open(tBTA_HF_CLIENT_DATA *p_data) 265{ 266 UINT16 lcid; 267 BD_ADDR dev_addr; 268 int status; 269 270 /* set role */ 271 bta_hf_client_cb.scb.role = BTA_HF_CLIENT_ACP; 272 273 APPL_TRACE_DEBUG ("bta_hf_client_rfc_acp_open: serv_handle = %d rfc.port_handle = %d", 274 bta_hf_client_cb.scb.serv_handle, p_data->rfc.port_handle); 275 276 /* get bd addr of peer */ 277 if (PORT_SUCCESS != (status=PORT_CheckConnection(p_data->rfc.port_handle, dev_addr, &lcid))) 278 { 279 APPL_TRACE_DEBUG ("bta_hf_client_rfc_acp_open error PORT_CheckConnection returned status %d", status); 280 } 281 282 /* Collision Handling */ 283 if (bta_hf_client_cb.scb.colli_tmr_on) 284 { 285 /* stop collision timer */ 286 bta_hf_client_cb.scb.colli_tmr_on = FALSE; 287 bta_sys_stop_timer (&bta_hf_client_cb.scb.colli_timer); 288 289 if (bdcmp (dev_addr, bta_hf_client_cb.scb.peer_addr) == 0) 290 { 291 /* If incoming and outgoing device are same, nothing more to do. */ 292 /* Outgoing conn will be aborted because we have successful incoming conn. */ 293 } 294 else 295 { 296 /* Resume outgoing connection. */ 297 bta_hf_client_resume_open (); 298 } 299 } 300 301 bdcpy (bta_hf_client_cb.scb.peer_addr, dev_addr); 302 bta_hf_client_cb.scb.conn_handle = p_data->rfc.port_handle; 303 304 /* do service discovery to get features */ 305 bta_hf_client_do_disc(); 306 307 /* continue with open processing */ 308 bta_hf_client_rfc_open(p_data); 309} 310 311/******************************************************************************* 312** 313** Function bta_hf_client_rfc_fail 314** 315** Description RFCOMM connection failed. 316** 317** 318** Returns void 319** 320*******************************************************************************/ 321void bta_hf_client_rfc_fail(tBTA_HF_CLIENT_DATA *p_data) 322{ 323 UNUSED(p_data); 324 325 /* reinitialize stuff */ 326 bta_hf_client_cb.scb.conn_handle = 0; 327 bta_hf_client_cb.scb.peer_features = 0; 328 bta_hf_client_cb.scb.chld_features = 0; 329 bta_hf_client_cb.scb.role = BTA_HF_CLIENT_ACP; 330 bta_hf_client_cb.scb.svc_conn = FALSE; 331 bta_hf_client_cb.scb.send_at_reply = FALSE; 332 bta_hf_client_cb.scb.negotiated_codec = BTM_SCO_CODEC_CVSD; 333 334 bta_hf_client_at_reset(); 335 336 /* reopen server */ 337 bta_hf_client_start_server(); 338 339 /* call open cback w. failure */ 340 bta_hf_client_cback_open(NULL, BTA_HF_CLIENT_FAIL_RFCOMM); 341} 342 343/******************************************************************************* 344** 345** Function bta_hf_client_disc_fail 346** 347** Description This function handles a discovery failure. 348** 349** 350** Returns void 351** 352*******************************************************************************/ 353void bta_hf_client_disc_fail(tBTA_HF_CLIENT_DATA *p_data) 354{ 355 UNUSED(p_data); 356 357 /* reopen server */ 358 bta_hf_client_start_server(); 359 360 /* reinitialize stuff */ 361 362 /* call open cback w. failure */ 363 bta_hf_client_cback_open(NULL, BTA_HF_CLIENT_FAIL_SDP); 364} 365 366/******************************************************************************* 367** 368** Function bta_hf_client_open_fail 369** 370** Description open connection failed. 371** 372** 373** Returns void 374** 375*******************************************************************************/ 376void bta_hf_client_open_fail(tBTA_HF_CLIENT_DATA *p_data) 377{ 378 /* call open cback w. failure */ 379 bta_hf_client_cback_open(p_data, BTA_HF_CLIENT_FAIL_RESOURCES); 380} 381 382/******************************************************************************* 383** 384** Function bta_hf_client_rfc_close 385** 386** Description RFCOMM connection closed. 387** 388** 389** Returns void 390** 391*******************************************************************************/ 392void bta_hf_client_rfc_close(tBTA_HF_CLIENT_DATA *p_data) 393{ 394 UNUSED(p_data); 395 396 /* reinitialize stuff */ 397 bta_hf_client_cb.scb.peer_features = 0; 398 bta_hf_client_cb.scb.chld_features = 0; 399 bta_hf_client_cb.scb.role = BTA_HF_CLIENT_ACP; 400 bta_hf_client_cb.scb.svc_conn = FALSE; 401 bta_hf_client_cb.scb.send_at_reply = FALSE; 402 bta_hf_client_cb.scb.negotiated_codec = BTM_SCO_CODEC_CVSD; 403 404 bta_hf_client_at_reset(); 405 406 bta_sys_conn_close(BTA_ID_HS, 1, bta_hf_client_cb.scb.peer_addr); 407 408 /* call close cback */ 409 (*bta_hf_client_cb.p_cback)(BTA_HF_CLIENT_CLOSE_EVT, NULL); 410 411 /* if not deregistering reopen server */ 412 if (bta_hf_client_cb.scb.deregister == FALSE) 413 { 414 /* Clear peer bd_addr so instance can be reused */ 415 bdcpy(bta_hf_client_cb.scb.peer_addr, bd_addr_null); 416 417 /* start server as it might got closed on open*/ 418 bta_hf_client_start_server(); 419 420 bta_hf_client_cb.scb.conn_handle = 0; 421 422 /* Make sure SCO is shutdown */ 423 bta_hf_client_sco_shutdown(NULL); 424 425 bta_sys_sco_unuse(BTA_ID_HS, 1, bta_hf_client_cb.scb.peer_addr); 426 } 427 /* else close port and deallocate scb */ 428 else 429 { 430 bta_hf_client_close_server(); 431 bta_hf_client_scb_disable(); 432 } 433} 434 435/******************************************************************************* 436** 437** Function bta_hf_client_disc_int_res 438** 439** Description This function handles a discovery result when initiator. 440** 441** 442** Returns void 443** 444*******************************************************************************/ 445void bta_hf_client_disc_int_res(tBTA_HF_CLIENT_DATA *p_data) 446{ 447 UINT16 event = BTA_HF_CLIENT_DISC_FAIL_EVT; 448 449 APPL_TRACE_DEBUG ("bta_hf_client_disc_int_res: Status: %d", p_data->disc_result.status); 450 451 /* if found service */ 452 if (p_data->disc_result.status == SDP_SUCCESS || 453 p_data->disc_result.status == SDP_DB_FULL) 454 { 455 /* get attributes */ 456 if (bta_hf_client_sdp_find_attr()) 457 { 458 event = BTA_HF_CLIENT_DISC_OK_EVT; 459 } 460 } 461 462 /* free discovery db */ 463 bta_hf_client_free_db(p_data); 464 465 /* send ourselves sdp ok/fail event */ 466 bta_hf_client_sm_execute(event, p_data); 467} 468 469/******************************************************************************* 470** 471** Function bta_hf_client_disc_acp_res 472** 473** Description This function handles a discovery result when acceptor. 474** 475** 476** Returns void 477** 478*******************************************************************************/ 479void bta_hf_client_disc_acp_res(tBTA_HF_CLIENT_DATA *p_data) 480{ 481 /* if found service */ 482 if (p_data->disc_result.status == SDP_SUCCESS || 483 p_data->disc_result.status == SDP_DB_FULL) 484 { 485 /* get attributes */ 486 bta_hf_client_sdp_find_attr(); 487 } 488 489 /* free discovery db */ 490 bta_hf_client_free_db(p_data); 491} 492 493/******************************************************************************* 494** 495** Function bta_hf_client_rfc_data 496** 497** Description Read and process data from RFCOMM. 498** 499** 500** Returns void 501** 502*******************************************************************************/ 503void bta_hf_client_rfc_data(tBTA_HF_CLIENT_DATA *p_data) 504{ 505 UINT16 len; 506 char buf[BTA_HF_CLIENT_RFC_READ_MAX]; 507 UNUSED(p_data); 508 509 memset(buf, 0, sizeof(buf)); 510 511 /* read data from rfcomm; if bad status, we're done */ 512 while (PORT_ReadData(bta_hf_client_cb.scb.conn_handle, buf, BTA_HF_CLIENT_RFC_READ_MAX, &len) == PORT_SUCCESS) 513 { 514 /* if no data, we're done */ 515 if (len == 0) 516 { 517 break; 518 } 519 520 bta_hf_client_at_parse(buf, len); 521 522 /* no more data to read, we're done */ 523 if (len < BTA_HF_CLIENT_RFC_READ_MAX) 524 { 525 break; 526 } 527 } 528} 529 530/******************************************************************************* 531** 532** Function bta_hf_client_svc_conn_open 533** 534** Description Service level connection opened 535** 536** 537** Returns void 538** 539*******************************************************************************/ 540void bta_hf_client_svc_conn_open(tBTA_HF_CLIENT_DATA *p_data) 541{ 542 tBTA_HF_CLIENT evt; 543 UNUSED(p_data); 544 545 memset(&evt, 0, sizeof(evt)); 546 547 if (!bta_hf_client_cb.scb.svc_conn) 548 { 549 /* set state variable */ 550 bta_hf_client_cb.scb.svc_conn = TRUE; 551 552 /* call callback */ 553 evt.conn.peer_feat = bta_hf_client_cb.scb.peer_features; 554 evt.conn.chld_feat = bta_hf_client_cb.scb.chld_features; 555 556 (*bta_hf_client_cb.p_cback)(BTA_HF_CLIENT_CONN_EVT, &evt); 557 } 558} 559 560/******************************************************************************* 561** 562** Function bta_hf_client_cback_ind 563** 564** Description Send indicator callback event to application. 565** 566** Returns void 567** 568*******************************************************************************/ 569void bta_hf_client_ind(tBTA_HF_CLIENT_IND_TYPE type, UINT16 value) 570{ 571 tBTA_HF_CLIENT evt; 572 573 memset(&evt, 0, sizeof(evt)); 574 575 evt.ind.type = type; 576 evt.ind.value = value; 577 578 (*bta_hf_client_cb.p_cback)(BTA_HF_CLIENT_IND_EVT, &evt); 579} 580 581/******************************************************************************* 582** 583** Function bta_hf_client_evt_val 584** 585** Description Send event to application. 586** This is a generic helper for events with common data. 587** 588** 589** Returns void 590** 591*******************************************************************************/ 592void bta_hf_client_evt_val(tBTA_HF_CLIENT_EVT type, UINT16 value) 593{ 594 tBTA_HF_CLIENT evt; 595 596 memset(&evt, 0, sizeof(evt)); 597 598 evt.val.value = value; 599 600 (*bta_hf_client_cb.p_cback)(type, &evt); 601} 602 603/******************************************************************************* 604** 605** Function bta_hf_client_operator_name 606** 607** Description Send operator name event to application. 608** 609** 610** Returns void 611** 612*******************************************************************************/ 613void bta_hf_client_operator_name(char *name) 614{ 615 tBTA_HF_CLIENT evt; 616 617 memset(&evt, 0, sizeof(evt)); 618 619 strlcpy(evt.operator.name, name, BTA_HF_CLIENT_OPERATOR_NAME_LEN + 1); 620 evt.operator.name[BTA_HF_CLIENT_OPERATOR_NAME_LEN] = '\0'; 621 622 (*bta_hf_client_cb.p_cback)(BTA_HF_CLIENT_OPERATOR_NAME_EVT, &evt); 623} 624 625 626/******************************************************************************* 627** 628** Function bta_hf_client_clip 629** 630** Description Send CLIP event to application. 631** 632** 633** Returns void 634** 635*******************************************************************************/ 636void bta_hf_client_clip(char *number) 637{ 638 tBTA_HF_CLIENT evt; 639 640 memset(&evt, 0, sizeof(evt)); 641 642 strlcpy(evt.number.number, number, BTA_HF_CLIENT_NUMBER_LEN + 1); 643 evt.number.number[BTA_HF_CLIENT_NUMBER_LEN] = '\0'; 644 645 (*bta_hf_client_cb.p_cback)(BTA_HF_CLIENT_CLIP_EVT, &evt); 646} 647 648/******************************************************************************* 649** 650** Function bta_hf_client_ccwa 651** 652** Description Send CLIP event to application. 653** 654** 655** Returns void 656** 657*******************************************************************************/ 658void bta_hf_client_ccwa(char *number) 659{ 660 tBTA_HF_CLIENT evt; 661 662 memset(&evt, 0, sizeof(evt)); 663 664 strlcpy(evt.number.number, number, BTA_HF_CLIENT_NUMBER_LEN + 1); 665 evt.number.number[BTA_HF_CLIENT_NUMBER_LEN] = '\0'; 666 667 (*bta_hf_client_cb.p_cback)(BTA_HF_CLIENT_CCWA_EVT, &evt); 668} 669 670/******************************************************************************* 671** 672** Function bta_hf_client_at_result 673** 674** Description Send AT result event to application. 675** 676** 677** Returns void 678** 679*******************************************************************************/ 680void bta_hf_client_at_result(tBTA_HF_CLIENT_AT_RESULT_TYPE type, UINT16 cme) 681{ 682 tBTA_HF_CLIENT evt; 683 684 memset(&evt, 0, sizeof(evt)); 685 686 evt.result.type = type; 687 evt.result.cme = cme; 688 689 (*bta_hf_client_cb.p_cback)(BTA_HF_CLIENT_AT_RESULT_EVT, &evt); 690} 691 692/******************************************************************************* 693** 694** Function bta_hf_client_clcc 695** 696** Description Send clcc event to application. 697** 698** 699** Returns void 700** 701*******************************************************************************/ 702void bta_hf_client_clcc(UINT32 idx, BOOLEAN incoming, UINT8 status, BOOLEAN mpty, char *number) 703{ 704 tBTA_HF_CLIENT evt; 705 706 memset(&evt, 0, sizeof(evt)); 707 708 evt.clcc.idx = idx; 709 evt.clcc.inc = incoming; 710 evt.clcc.status = status; 711 evt.clcc.mpty = mpty; 712 713 if (number) 714 { 715 evt.clcc.number_present = TRUE; 716 strlcpy(evt.clcc.number, number, BTA_HF_CLIENT_NUMBER_LEN + 1); 717 evt.clcc.number[BTA_HF_CLIENT_NUMBER_LEN] = '\0'; 718 } 719 720 (*bta_hf_client_cb.p_cback)(BTA_HF_CLIENT_CLCC_EVT, &evt); 721} 722 723/******************************************************************************* 724** 725** Function bta_hf_client_cnum 726** 727** Description Send cnum event to application. 728** 729** 730** Returns void 731** 732*******************************************************************************/ 733void bta_hf_client_cnum(char *number, UINT16 service) 734{ 735 tBTA_HF_CLIENT evt; 736 737 memset(&evt, 0, sizeof(evt)); 738 739 evt.cnum.service = service; 740 strlcpy(evt.cnum.number, number, BTA_HF_CLIENT_NUMBER_LEN + 1); 741 evt.cnum.number[BTA_HF_CLIENT_NUMBER_LEN] = '\0'; 742 743 (*bta_hf_client_cb.p_cback)(BTA_HF_CLIENT_CNUM_EVT, &evt); 744} 745 746/******************************************************************************* 747** 748** Function bta_hf_client_binp 749** 750** Description Send BINP event to application. 751** 752** 753** Returns void 754** 755*******************************************************************************/ 756void bta_hf_client_binp(char *number) 757{ 758 tBTA_HF_CLIENT evt; 759 760 memset(&evt, 0, sizeof(evt)); 761 762 strlcpy(evt.number.number, number, BTA_HF_CLIENT_NUMBER_LEN + 1); 763 evt.number.number[BTA_HF_CLIENT_NUMBER_LEN] = '\0'; 764 765 (*bta_hf_client_cb.p_cback)(BTA_HF_CLIENT_BINP_EVT, &evt); 766} 767