1/****************************************************************************** 2 * 3 * Copyright (c) 2014 The Android Open Source Project 4 * Copyright (C) 2009-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 * Filename: btif_hf_client.c 23 * 24 * Description: Handsfree Profile (HF role) Bluetooth Interface 25 * 26 * 27 ***********************************************************************************/ 28 29#include <hardware/bluetooth.h> 30#include <hardware/bt_hf_client.h> 31#include <stdlib.h> 32#include <cutils/properties.h> 33 34#define LOG_TAG "BTIF_HF_CLIENT" 35#include "btif_common.h" 36#include "btif_util.h" 37#include "btif_profile_queue.h" 38#include "bt_utils.h" 39#include "bd.h" 40#include "bta_hf_client_api.h" 41 42/************************************************************************************ 43** Constants & Macros 44************************************************************************************/ 45 46#ifndef BTIF_HF_CLIENT_SERVICE_NAME 47#define BTIF_HF_CLIENT_SERVICE_NAME ("Handsfree") 48#endif 49 50#ifndef BTIF_HF_CLIENT_SECURITY 51#define BTIF_HF_CLIENT_SECURITY (BTA_SEC_AUTHENTICATE | BTA_SEC_ENCRYPT) 52#endif 53 54#ifndef BTIF_HF_CLIENT_FEATURES 55#define BTIF_HF_CLIENT_FEATURES ( BTA_HF_CLIENT_FEAT_ECNR | \ 56 BTA_HF_CLIENT_FEAT_3WAY | \ 57 BTA_HF_CLIENT_FEAT_CLI | \ 58 BTA_HF_CLIENT_FEAT_VREC | \ 59 BTA_HF_CLIENT_FEAT_VOL | \ 60 BTA_HF_CLIENT_FEAT_ECS | \ 61 BTA_HF_CLIENT_FEAT_ECC | \ 62 BTA_HF_CLIENT_FEAT_CODEC) 63#endif 64 65/************************************************************************************ 66** Local type definitions 67************************************************************************************/ 68 69/************************************************************************************ 70** Static variables 71************************************************************************************/ 72static bthf_client_callbacks_t *bt_hf_client_callbacks = NULL; 73char btif_hf_client_version[PROPERTY_VALUE_MAX]; 74static UINT32 btif_hf_client_features = 0; 75 76 77#define CHECK_BTHF_CLIENT_INIT() if (bt_hf_client_callbacks == NULL)\ 78 {\ 79 BTIF_TRACE_WARNING("BTHF CLIENT: %s: not initialized", __FUNCTION__);\ 80 return BT_STATUS_NOT_READY;\ 81 }\ 82 else\ 83 {\ 84 BTIF_TRACE_EVENT("BTHF CLIENT: %s", __FUNCTION__);\ 85 } 86 87#define CHECK_BTHF_CLIENT_SLC_CONNECTED() if (bt_hf_client_callbacks == NULL)\ 88 {\ 89 BTIF_TRACE_WARNING("BTHF CLIENT: %s: not initialized", __FUNCTION__);\ 90 return BT_STATUS_NOT_READY;\ 91 }\ 92 else if (btif_hf_client_cb.state != BTHF_CLIENT_CONNECTION_STATE_SLC_CONNECTED)\ 93 {\ 94 BTIF_TRACE_WARNING("BTHF CLIENT: %s: SLC connection not up. state=%s",\ 95 __FUNCTION__, \ 96 dump_hf_conn_state(btif_hf_client_cb.state));\ 97 return BT_STATUS_NOT_READY;\ 98 }\ 99 else\ 100 {\ 101 BTIF_TRACE_EVENT("BTHF CLIENT: %s", __FUNCTION__);\ 102 } 103 104/* BTIF-HF control block to map bdaddr to BTA handle */ 105typedef struct 106{ 107 UINT16 handle; 108 bt_bdaddr_t connected_bda; 109 bthf_client_connection_state_t state; 110 bthf_client_vr_state_t vr_state; 111 tBTA_HF_CLIENT_PEER_FEAT peer_feat; 112 tBTA_HF_CLIENT_CHLD_FEAT chld_feat; 113} btif_hf_client_cb_t; 114 115static btif_hf_client_cb_t btif_hf_client_cb; 116 117 118/************************************************************************************ 119** Static functions 120************************************************************************************/ 121 122/******************************************************************************* 123** 124** Function btif_in_hf_client_generic_evt 125** 126** Description Processes generic events to be sent to JNI that are not triggered from the BTA. 127** Always runs in BTIF context 128** 129** Returns void 130** 131*******************************************************************************/ 132static void btif_in_hf_client_generic_evt(UINT16 event, char *p_param) 133{ 134 UNUSED(p_param); 135 136 BTIF_TRACE_EVENT("%s: event=%d", __FUNCTION__, event); 137 switch (event) { 138 case BTIF_HF_CLIENT_CB_AUDIO_CONNECTING: 139 { 140 HAL_CBACK(bt_hf_client_callbacks, audio_state_cb, BTHF_AUDIO_STATE_CONNECTING, 141 &btif_hf_client_cb.connected_bda); 142 } break; 143 default: 144 { 145 BTIF_TRACE_WARNING("%s : Unknown event 0x%x", __FUNCTION__, event); 146 } 147 break; 148 } 149} 150 151/************************************************************************************ 152** Externs 153************************************************************************************/ 154 155/************************************************************************************ 156** Functions 157************************************************************************************/ 158 159static void clear_state(void) 160{ 161 memset(&btif_hf_client_cb, 0, sizeof(btif_hf_client_cb_t)); 162} 163 164static BOOLEAN is_connected(bt_bdaddr_t *bd_addr) 165{ 166 if (((btif_hf_client_cb.state == BTHF_CLIENT_CONNECTION_STATE_CONNECTED) || 167 (btif_hf_client_cb.state == BTHF_CLIENT_CONNECTION_STATE_SLC_CONNECTED))&& 168 ((bd_addr == NULL) || (bdcmp(bd_addr->address, btif_hf_client_cb.connected_bda.address) == 0))) 169 return TRUE; 170 return FALSE; 171} 172 173/***************************************************************************** 174** Section name (Group of functions) 175*****************************************************************************/ 176 177/***************************************************************************** 178** 179** btif hf api functions (no context switch) 180** 181*****************************************************************************/ 182 183/******************************************************************************* 184** 185** Function btif_hf_client_init 186** 187** Description initializes the hf interface 188** 189** Returns bt_status_t 190** 191*******************************************************************************/ 192static bt_status_t init( bthf_client_callbacks_t* callbacks ) 193{ 194 BTIF_TRACE_EVENT("%s", __FUNCTION__); 195 196 bt_hf_client_callbacks = callbacks; 197 198 btif_enable_service(BTA_HFP_HS_SERVICE_ID); 199 200 clear_state(); 201 202 return BT_STATUS_SUCCESS; 203} 204 205/******************************************************************************* 206** 207** Function connect 208** 209** Description connect to audio gateway 210** 211** Returns bt_status_t 212** 213*******************************************************************************/ 214static bt_status_t connect_int( bt_bdaddr_t *bd_addr, uint16_t uuid ) 215{ 216 if (is_connected(bd_addr)) 217 return BT_STATUS_BUSY; 218 219 btif_hf_client_cb.state = BTHF_CLIENT_CONNECTION_STATE_CONNECTING; 220 bdcpy(btif_hf_client_cb.connected_bda.address, bd_addr->address); 221 222 BTA_HfClientOpen(btif_hf_client_cb.handle, btif_hf_client_cb.connected_bda.address, 223 BTIF_HF_CLIENT_SECURITY); 224 225 return BT_STATUS_SUCCESS; 226} 227 228static bt_status_t connect( bt_bdaddr_t *bd_addr ) 229{ 230 BTIF_TRACE_EVENT("HFP Client version is %s", btif_hf_client_version); 231 CHECK_BTHF_CLIENT_INIT(); 232 return btif_queue_connect(UUID_SERVCLASS_HF_HANDSFREE, bd_addr, connect_int); 233 234} 235 236/******************************************************************************* 237** 238** Function disconnect 239** 240** Description disconnect from audio gateway 241** 242** Returns bt_status_t 243** 244*******************************************************************************/ 245static bt_status_t disconnect( bt_bdaddr_t *bd_addr ) 246{ 247 CHECK_BTHF_CLIENT_INIT(); 248 249 if (is_connected(bd_addr)) 250 { 251 BTA_HfClientClose(btif_hf_client_cb.handle); 252 return BT_STATUS_SUCCESS; 253 } 254 255 return BT_STATUS_FAIL; 256} 257 258/******************************************************************************* 259** 260** Function connect_audio 261** 262** Description create an audio connection 263** 264** Returns bt_status_t 265** 266*******************************************************************************/ 267static bt_status_t connect_audio( bt_bdaddr_t *bd_addr ) 268{ 269 CHECK_BTHF_CLIENT_SLC_CONNECTED(); 270 271 if (is_connected(bd_addr)) 272 { 273 if (btif_hf_client_cb.peer_feat & BTA_HF_CLIENT_PEER_CODEC) 274 { 275 BTA_HfClientSendAT(btif_hf_client_cb.handle, BTA_HF_CLIENT_AT_CMD_BCC, 0, 0, NULL); 276 } 277 else 278 { 279 BTA_HfClientAudioOpen(btif_hf_client_cb.handle); 280 } 281 282 /* Inform the application that the audio connection has been initiated successfully */ 283 btif_transfer_context(btif_in_hf_client_generic_evt, BTIF_HF_CLIENT_CB_AUDIO_CONNECTING, 284 (char *)bd_addr, sizeof(bt_bdaddr_t), NULL); 285 return BT_STATUS_SUCCESS; 286 } 287 288 return BT_STATUS_FAIL; 289} 290 291/******************************************************************************* 292** 293** Function disconnect_audio 294** 295** Description close the audio connection 296** 297** Returns bt_status_t 298** 299*******************************************************************************/ 300static bt_status_t disconnect_audio( bt_bdaddr_t *bd_addr ) 301{ 302 CHECK_BTHF_CLIENT_SLC_CONNECTED(); 303 304 if (is_connected(bd_addr)) 305 { 306 BTA_HfClientAudioClose(btif_hf_client_cb.handle); 307 return BT_STATUS_SUCCESS; 308 } 309 310 return BT_STATUS_FAIL; 311} 312 313/******************************************************************************* 314** 315** Function start_voice_recognition 316** 317** Description start voice recognition 318** 319** Returns bt_status_t 320** 321*******************************************************************************/ 322static bt_status_t start_voice_recognition() 323{ 324 CHECK_BTHF_CLIENT_SLC_CONNECTED(); 325 326 if (btif_hf_client_cb.peer_feat & BTA_HF_CLIENT_PEER_FEAT_VREC) 327 { 328 BTA_HfClientSendAT(btif_hf_client_cb.handle, BTA_HF_CLIENT_AT_CMD_BVRA, 1, 0, NULL); 329 330 return BT_STATUS_SUCCESS; 331 } 332 333 return BT_STATUS_UNSUPPORTED; 334} 335 336/******************************************************************************* 337** 338** Function stop_voice_recognition 339** 340** Description stop voice recognition 341** 342** Returns bt_status_t 343** 344*******************************************************************************/ 345static bt_status_t stop_voice_recognition() 346{ 347 CHECK_BTHF_CLIENT_SLC_CONNECTED(); 348 349 if (btif_hf_client_cb.peer_feat & BTA_HF_CLIENT_PEER_FEAT_VREC) 350 { 351 BTA_HfClientSendAT(btif_hf_client_cb.handle, BTA_HF_CLIENT_AT_CMD_BVRA, 0, 0, NULL); 352 353 return BT_STATUS_SUCCESS; 354 } 355 356 return BT_STATUS_UNSUPPORTED; 357} 358 359/******************************************************************************* 360** 361** Function volume_control 362** 363** Description volume control 364** 365** Returns bt_status_t 366** 367*******************************************************************************/ 368static bt_status_t volume_control(bthf_client_volume_type_t type, int volume) 369{ 370 BOOLEAN speaker; 371 372 CHECK_BTHF_CLIENT_SLC_CONNECTED(); 373 374 switch (type) 375 { 376 case BTHF_CLIENT_VOLUME_TYPE_SPK: 377 BTA_HfClientSendAT(btif_hf_client_cb.handle, BTA_HF_CLIENT_AT_CMD_VGS, volume, 0, NULL); 378 break; 379 case BTHF_CLIENT_VOLUME_TYPE_MIC: 380 BTA_HfClientSendAT(btif_hf_client_cb.handle, BTA_HF_CLIENT_AT_CMD_VGM, volume, 0, NULL); 381 break; 382 default: 383 return BT_STATUS_UNSUPPORTED; 384 } 385 386 return BT_STATUS_SUCCESS; 387} 388 389/******************************************************************************* 390** 391** Function dial 392** 393** Description place a call 394** 395** Returns bt_status_t 396** 397*******************************************************************************/ 398static bt_status_t dial(const char *number) 399{ 400 CHECK_BTHF_CLIENT_SLC_CONNECTED(); 401 402 if (number) 403 { 404 BTA_HfClientSendAT(btif_hf_client_cb.handle, BTA_HF_CLIENT_AT_CMD_ATD, 0, 0, number); 405 } 406 else 407 { 408 BTA_HfClientSendAT(btif_hf_client_cb.handle, BTA_HF_CLIENT_AT_CMD_BLDN, 0, 0, NULL); 409 } 410 411 return BT_STATUS_SUCCESS; 412} 413 414/******************************************************************************* 415** 416** Function dial_memory 417** 418** Description place a call with number specified by location (speed dial) 419** 420** Returns bt_status_t 421** 422*******************************************************************************/ 423static bt_status_t dial_memory(int location) 424{ 425 CHECK_BTHF_CLIENT_SLC_CONNECTED(); 426 427 BTA_HfClientSendAT(btif_hf_client_cb.handle, BTA_HF_CLIENT_AT_CMD_ATD, location, 0, NULL); 428 429 return BT_STATUS_SUCCESS; 430} 431 432/******************************************************************************* 433** 434** Function handle_call_action 435** 436** Description handle specified call related action 437** 438** Returns bt_status_t 439** 440*******************************************************************************/ 441static bt_status_t handle_call_action(bthf_client_call_action_t action, int idx) 442{ 443 CHECK_BTHF_CLIENT_SLC_CONNECTED(); 444 445 switch (action) 446 { 447 case BTHF_CLIENT_CALL_ACTION_CHLD_0: 448 if (btif_hf_client_cb.chld_feat & BTA_HF_CLIENT_CHLD_REL) 449 { 450 BTA_HfClientSendAT(btif_hf_client_cb.handle, BTA_HF_CLIENT_AT_CMD_CHLD, 0, 0, NULL); 451 break; 452 } 453 return BT_STATUS_UNSUPPORTED; 454 case BTHF_CLIENT_CALL_ACTION_CHLD_1: 455 // CHLD 1 is mandatory for 3 way calling 456 if (btif_hf_client_cb.peer_feat & BTA_HF_CLIENT_PEER_FEAT_3WAY) 457 { 458 BTA_HfClientSendAT(btif_hf_client_cb.handle, BTA_HF_CLIENT_AT_CMD_CHLD, 1, 0, NULL); 459 break; 460 } 461 return BT_STATUS_UNSUPPORTED; 462 case BTHF_CLIENT_CALL_ACTION_CHLD_2: 463 // CHLD 2 is mandatory for 3 way calling 464 if (btif_hf_client_cb.peer_feat & BTA_HF_CLIENT_PEER_FEAT_3WAY) 465 { 466 BTA_HfClientSendAT(btif_hf_client_cb.handle, BTA_HF_CLIENT_AT_CMD_CHLD, 2, 0, NULL); 467 break; 468 } 469 return BT_STATUS_UNSUPPORTED; 470 case BTHF_CLIENT_CALL_ACTION_CHLD_3: 471 if (btif_hf_client_cb.chld_feat & BTA_HF_CLIENT_CHLD_MERGE) 472 { 473 BTA_HfClientSendAT(btif_hf_client_cb.handle, BTA_HF_CLIENT_AT_CMD_CHLD, 3, 0, NULL); 474 break; 475 } 476 return BT_STATUS_UNSUPPORTED; 477 case BTHF_CLIENT_CALL_ACTION_CHLD_4: 478 if (btif_hf_client_cb.chld_feat & BTA_HF_CLIENT_CHLD_MERGE_DETACH) 479 { 480 BTA_HfClientSendAT(btif_hf_client_cb.handle, BTA_HF_CLIENT_AT_CMD_CHLD, 4, 0, NULL); 481 break; 482 } 483 return BT_STATUS_UNSUPPORTED; 484 case BTHF_CLIENT_CALL_ACTION_CHLD_1x: 485 if (btif_hf_client_cb.peer_feat & BTA_HF_CLIENT_PEER_ECC) 486 { 487 if (idx < 1) 488 { 489 return BT_STATUS_FAIL; 490 } 491 BTA_HfClientSendAT(btif_hf_client_cb.handle, BTA_HF_CLIENT_AT_CMD_CHLD, 1, idx, NULL); 492 break; 493 } 494 return BT_STATUS_UNSUPPORTED; 495 case BTHF_CLIENT_CALL_ACTION_CHLD_2x: 496 if (btif_hf_client_cb.peer_feat & BTA_HF_CLIENT_PEER_ECC) 497 { 498 if (idx < 1) 499 { 500 return BT_STATUS_FAIL; 501 } 502 BTA_HfClientSendAT(btif_hf_client_cb.handle, BTA_HF_CLIENT_AT_CMD_CHLD, 2, idx, NULL); 503 break; 504 } 505 return BT_STATUS_UNSUPPORTED; 506 case BTHF_CLIENT_CALL_ACTION_ATA: 507 BTA_HfClientSendAT(btif_hf_client_cb.handle, BTA_HF_CLIENT_AT_CMD_ATA, 0, 0, NULL); 508 break; 509 case BTHF_CLIENT_CALL_ACTION_CHUP: 510 BTA_HfClientSendAT(btif_hf_client_cb.handle, BTA_HF_CLIENT_AT_CMD_CHUP, 0, 0, NULL); 511 break; 512 case BTHF_CLIENT_CALL_ACTION_BTRH_0: 513 BTA_HfClientSendAT(btif_hf_client_cb.handle, BTA_HF_CLIENT_AT_CMD_BTRH, 0, 0, NULL); 514 break; 515 case BTHF_CLIENT_CALL_ACTION_BTRH_1: 516 BTA_HfClientSendAT(btif_hf_client_cb.handle, BTA_HF_CLIENT_AT_CMD_BTRH, 1, 0, NULL); 517 break; 518 case BTHF_CLIENT_CALL_ACTION_BTRH_2: 519 BTA_HfClientSendAT(btif_hf_client_cb.handle, BTA_HF_CLIENT_AT_CMD_BTRH, 2, 0, NULL); 520 break; 521 default: 522 return BT_STATUS_FAIL; 523 524 } 525 526 return BT_STATUS_SUCCESS; 527} 528 529/******************************************************************************* 530** 531** Function query_current_calls 532** 533** Description query list of current calls 534** 535** Returns bt_status_t 536** 537*******************************************************************************/ 538static bt_status_t query_current_calls(void) 539{ 540 CHECK_BTHF_CLIENT_SLC_CONNECTED(); 541 542 if (btif_hf_client_cb.peer_feat & BTA_HF_CLIENT_PEER_ECS) 543 { 544 BTA_HfClientSendAT(btif_hf_client_cb.handle, BTA_HF_CLIENT_AT_CMD_CLCC, 0, 0, NULL); 545 546 return BT_STATUS_SUCCESS; 547 } 548 549 return BT_STATUS_UNSUPPORTED; 550} 551 552/******************************************************************************* 553** 554** Function query_current_operator_name 555** 556** Description query current selected operator name 557** 558** Returns bt_status_t 559** 560*******************************************************************************/ 561static bt_status_t query_current_operator_name(void) 562{ 563 CHECK_BTHF_CLIENT_SLC_CONNECTED(); 564 565 BTA_HfClientSendAT(btif_hf_client_cb.handle, BTA_HF_CLIENT_AT_CMD_COPS, 0, 0, NULL); 566 567 return BT_STATUS_SUCCESS; 568} 569 570/******************************************************************************* 571** 572** Function retieve_subscriber_info 573** 574** Description retrieve subscriber number information 575** 576** Returns bt_status_t 577** 578*******************************************************************************/ 579static bt_status_t retrieve_subscriber_info(void) 580{ 581 CHECK_BTHF_CLIENT_SLC_CONNECTED(); 582 583 BTA_HfClientSendAT(btif_hf_client_cb.handle, BTA_HF_CLIENT_AT_CMD_CNUM, 0, 0, NULL); 584 585 return BT_STATUS_SUCCESS; 586} 587 588/******************************************************************************* 589** 590** Function send_dtmf 591** 592** Description send dtmf 593** 594** Returns bt_status_t 595** 596*******************************************************************************/ 597static bt_status_t send_dtmf(char code) 598{ 599 CHECK_BTHF_CLIENT_SLC_CONNECTED(); 600 601 BTA_HfClientSendAT(btif_hf_client_cb.handle, BTA_HF_CLIENT_AT_CMD_VTS, code, 0, NULL); 602 603 return BT_STATUS_SUCCESS; 604} 605 606/******************************************************************************* 607** 608** Function request_last_voice_tag_number 609** 610** Description Request number from AG for VR purposes 611** 612** Returns bt_status_t 613** 614*******************************************************************************/ 615static bt_status_t request_last_voice_tag_number(void) 616{ 617 CHECK_BTHF_CLIENT_SLC_CONNECTED(); 618 619 if (btif_hf_client_cb.peer_feat & BTA_HF_CLIENT_PEER_VTAG) 620 { 621 BTA_HfClientSendAT(btif_hf_client_cb.handle, BTA_HF_CLIENT_AT_CMD_BINP, 1, 0, NULL); 622 623 return BT_STATUS_SUCCESS; 624 } 625 626 return BT_STATUS_UNSUPPORTED; 627} 628 629/******************************************************************************* 630** 631** Function cleanup 632** 633** Description Closes the HF interface 634** 635** Returns bt_status_t 636** 637*******************************************************************************/ 638static void cleanup( void ) 639{ 640 BTIF_TRACE_EVENT("%s", __FUNCTION__); 641 642 if (bt_hf_client_callbacks) 643 { 644 btif_disable_service(BTA_HFP_HS_SERVICE_ID); 645 bt_hf_client_callbacks = NULL; 646 } 647} 648 649/******************************************************************************* 650** 651** Function send_at_cmd 652** 653** Description Send requested AT command to rempte device. 654** 655** Returns bt_status_t 656** 657*******************************************************************************/ 658static bt_status_t send_at_cmd(int cmd,int val1,int val2,const char *arg) 659{ 660 CHECK_BTHF_CLIENT_SLC_CONNECTED(); 661 BTIF_TRACE_EVENT("%s Cmd %d val1 %d val2 %d arg %s", 662 __FUNCTION__,cmd,val1,val2,arg); 663 BTA_HfClientSendAT(btif_hf_client_cb.handle, cmd, val1, val2, arg); 664 665 return BT_STATUS_SUCCESS; 666} 667 668static const bthf_client_interface_t bthfClientInterface = { 669 sizeof(bthf_client_interface_t), 670 .init = init, 671 .connect = connect, 672 .disconnect = disconnect, 673 .connect_audio = connect_audio, 674 .disconnect_audio = disconnect_audio, 675 .start_voice_recognition = start_voice_recognition, 676 .stop_voice_recognition = stop_voice_recognition, 677 .volume_control = volume_control, 678 .dial = dial, 679 .dial_memory = dial_memory, 680 .handle_call_action = handle_call_action, 681 .query_current_calls = query_current_calls, 682 .query_current_operator_name = query_current_operator_name, 683 .retrieve_subscriber_info = retrieve_subscriber_info, 684 .send_dtmf = send_dtmf, 685 .request_last_voice_tag_number = request_last_voice_tag_number, 686 .cleanup = cleanup, 687 .send_at_cmd = send_at_cmd, 688}; 689 690static void process_ind_evt(tBTA_HF_CLIENT_IND *ind) 691{ 692 switch (ind->type) 693 { 694 case BTA_HF_CLIENT_IND_CALL: 695 HAL_CBACK(bt_hf_client_callbacks, call_cb, ind->value); 696 break; 697 698 case BTA_HF_CLIENT_IND_CALLSETUP: 699 HAL_CBACK(bt_hf_client_callbacks, callsetup_cb, ind->value); 700 break; 701 case BTA_HF_CLIENT_IND_CALLHELD: 702 HAL_CBACK(bt_hf_client_callbacks, callheld_cb, ind->value); 703 break; 704 705 case BTA_HF_CLIENT_IND_SERVICE: 706 HAL_CBACK(bt_hf_client_callbacks, network_state_cb, ind->value); 707 break; 708 709 case BTA_HF_CLIENT_IND_SIGNAL: 710 HAL_CBACK(bt_hf_client_callbacks, network_signal_cb, ind->value); 711 break; 712 713 case BTA_HF_CLIENT_IND_ROAM: 714 HAL_CBACK(bt_hf_client_callbacks, network_roaming_cb, ind->value); 715 break; 716 717 case BTA_HF_CLIENT_IND_BATTCH: 718 HAL_CBACK(bt_hf_client_callbacks, battery_level_cb, ind->value); 719 break; 720 721 default: 722 break; 723 } 724} 725 726/******************************************************************************* 727** 728** Function btif_hf_client_upstreams_evt 729** 730** Description Executes HF CLIENT UPSTREAMS events in btif context 731** 732** Returns void 733** 734*******************************************************************************/ 735static void btif_hf_client_upstreams_evt(UINT16 event, char* p_param) 736{ 737 tBTA_HF_CLIENT *p_data = (tBTA_HF_CLIENT *)p_param; 738 bdstr_t bdstr; 739 740 BTIF_TRACE_DEBUG("%s: event=%s (%u)", __FUNCTION__, dump_hf_client_event(event), event); 741 742 switch (event) 743 { 744 case BTA_HF_CLIENT_ENABLE_EVT: 745 case BTA_HF_CLIENT_DISABLE_EVT: 746 break; 747 748 case BTA_HF_CLIENT_REGISTER_EVT: 749 btif_hf_client_cb.handle = p_data->reg.handle; 750 break; 751 752 case BTA_HF_CLIENT_OPEN_EVT: 753 if (p_data->open.status == BTA_HF_CLIENT_SUCCESS) 754 { 755 bdcpy(btif_hf_client_cb.connected_bda.address, p_data->open.bd_addr); 756 btif_hf_client_cb.state = BTHF_CLIENT_CONNECTION_STATE_CONNECTED; 757 btif_hf_client_cb.peer_feat = 0; 758 btif_hf_client_cb.chld_feat = 0; 759 //clear_phone_state(); 760 } 761 else if (btif_hf_client_cb.state == BTHF_CLIENT_CONNECTION_STATE_CONNECTING) 762 { 763 btif_hf_client_cb.state = BTHF_CLIENT_CONNECTION_STATE_DISCONNECTED; 764 } 765 else 766 { 767 BTIF_TRACE_WARNING("%s: HF CLient open failed, but another device connected. status=%d state=%d connected device=%s", 768 __FUNCTION__, p_data->open.status, btif_hf_client_cb.state, bd2str(&btif_hf_client_cb.connected_bda, &bdstr)); 769 break; 770 } 771 772 HAL_CBACK(bt_hf_client_callbacks, connection_state_cb, btif_hf_client_cb.state, 773 0, 0, &btif_hf_client_cb.connected_bda); 774 775 if (btif_hf_client_cb.state == BTHF_CLIENT_CONNECTION_STATE_DISCONNECTED) 776 bdsetany(btif_hf_client_cb.connected_bda.address); 777 778 if (p_data->open.status != BTA_HF_CLIENT_SUCCESS) 779 btif_queue_advance(); 780 break; 781 782 case BTA_HF_CLIENT_CONN_EVT: 783 btif_hf_client_cb.peer_feat = p_data->conn.peer_feat; 784 btif_hf_client_cb.chld_feat = p_data->conn.chld_feat; 785 btif_hf_client_cb.state = BTHF_CLIENT_CONNECTION_STATE_SLC_CONNECTED; 786 787 HAL_CBACK(bt_hf_client_callbacks, connection_state_cb, btif_hf_client_cb.state, 788 btif_hf_client_cb.peer_feat, btif_hf_client_cb.chld_feat, 789 &btif_hf_client_cb.connected_bda); 790 791 /* Inform the application about in-band ringtone */ 792 if (btif_hf_client_cb.peer_feat & BTA_HF_CLIENT_PEER_INBAND) 793 { 794 HAL_CBACK(bt_hf_client_callbacks, in_band_ring_tone_cb, BTHF_CLIENT_IN_BAND_RINGTONE_PROVIDED); 795 } 796 797 btif_queue_advance(); 798 break; 799 800 case BTA_HF_CLIENT_CLOSE_EVT: 801 btif_hf_client_cb.state = BTHF_CLIENT_CONNECTION_STATE_DISCONNECTED; 802 HAL_CBACK(bt_hf_client_callbacks, connection_state_cb, btif_hf_client_cb.state, 803 0, 0, &btif_hf_client_cb.connected_bda); 804 bdsetany(btif_hf_client_cb.connected_bda.address); 805 btif_hf_client_cb.peer_feat = 0; 806 btif_hf_client_cb.chld_feat = 0; 807 btif_queue_advance(); 808 break; 809 810 case BTA_HF_CLIENT_IND_EVT: 811 process_ind_evt(&p_data->ind); 812 break; 813 814 case BTA_HF_CLIENT_MIC_EVT: 815 HAL_CBACK(bt_hf_client_callbacks, volume_change_cb, BTHF_CLIENT_VOLUME_TYPE_MIC, p_data->val.value); 816 break; 817 818 case BTA_HF_CLIENT_SPK_EVT: 819 HAL_CBACK(bt_hf_client_callbacks, volume_change_cb, BTHF_CLIENT_VOLUME_TYPE_SPK, p_data->val.value); 820 break; 821 822 case BTA_HF_CLIENT_VOICE_REC_EVT: 823 HAL_CBACK(bt_hf_client_callbacks, vr_cmd_cb, p_data->val.value); 824 break; 825 826 case BTA_HF_CLIENT_OPERATOR_NAME_EVT: 827 HAL_CBACK(bt_hf_client_callbacks, current_operator_cb, p_data->operator.name); 828 break; 829 830 case BTA_HF_CLIENT_CLIP_EVT: 831 HAL_CBACK(bt_hf_client_callbacks, clip_cb, p_data->number.number); 832 break; 833 834 case BTA_HF_CLIENT_BINP_EVT: 835 HAL_CBACK(bt_hf_client_callbacks, last_voice_tag_number_callback, p_data->number.number); 836 break; 837 838 case BTA_HF_CLIENT_CCWA_EVT: 839 HAL_CBACK(bt_hf_client_callbacks, call_waiting_cb, p_data->number.number); 840 break; 841 842 case BTA_HF_CLIENT_AT_RESULT_EVT: 843 HAL_CBACK(bt_hf_client_callbacks, cmd_complete_cb, p_data->result.type, p_data->result.cme); 844 break; 845 846 case BTA_HF_CLIENT_CLCC_EVT: 847 HAL_CBACK(bt_hf_client_callbacks, current_calls_cb, p_data->clcc.idx, 848 p_data->clcc.inc ? BTHF_CLIENT_CALL_DIRECTION_INCOMING : BTHF_CLIENT_CALL_DIRECTION_OUTGOING, 849 p_data->clcc.status, 850 p_data->clcc.mpty ? BTHF_CLIENT_CALL_MPTY_TYPE_MULTI : BTHF_CLIENT_CALL_MPTY_TYPE_SINGLE, 851 p_data->clcc.number_present ? p_data->clcc.number : NULL); 852 break; 853 854 case BTA_HF_CLIENT_CNUM_EVT: 855 if (p_data->cnum.service == 4) 856 { 857 HAL_CBACK(bt_hf_client_callbacks, subscriber_info_cb, p_data->cnum.number, BTHF_CLIENT_SERVICE_VOICE); 858 } 859 else if (p_data->cnum.service == 5) 860 { 861 HAL_CBACK(bt_hf_client_callbacks, subscriber_info_cb, p_data->cnum.number, BTHF_CLIENT_SERVICE_FAX); 862 } 863 else 864 { 865 HAL_CBACK(bt_hf_client_callbacks, subscriber_info_cb, p_data->cnum.number, BTHF_CLIENT_SERVICE_UNKNOWN); 866 } 867 break; 868 869 case BTA_HF_CLIENT_BTRH_EVT: 870 if (p_data->val.value <= BTRH_CLIENT_RESP_AND_HOLD_REJECT) 871 { 872 HAL_CBACK(bt_hf_client_callbacks, resp_and_hold_cb, p_data->val.value); 873 } 874 break; 875 876 case BTA_HF_CLIENT_BSIR_EVT: 877 if (p_data->val.value != 0) 878 { 879 HAL_CBACK(bt_hf_client_callbacks, in_band_ring_tone_cb, BTHF_CLIENT_IN_BAND_RINGTONE_PROVIDED); 880 } 881 else 882 { 883 HAL_CBACK(bt_hf_client_callbacks, in_band_ring_tone_cb, BTHF_CLIENT_IN_BAND_RINGTONE_NOT_PROVIDED); 884 } 885 break; 886 887 case BTA_HF_CLIENT_AUDIO_OPEN_EVT: 888 HAL_CBACK(bt_hf_client_callbacks, audio_state_cb, BTHF_CLIENT_AUDIO_STATE_CONNECTED, &btif_hf_client_cb.connected_bda); 889 break; 890 891 case BTA_HF_CLIENT_AUDIO_MSBC_OPEN_EVT: 892 HAL_CBACK(bt_hf_client_callbacks, audio_state_cb, BTHF_CLIENT_AUDIO_STATE_CONNECTED_MSBC, &btif_hf_client_cb.connected_bda); 893 break; 894 895 case BTA_HF_CLIENT_AUDIO_CLOSE_EVT: 896 HAL_CBACK(bt_hf_client_callbacks, audio_state_cb, BTHF_CLIENT_AUDIO_STATE_DISCONNECTED, &btif_hf_client_cb.connected_bda); 897 break; 898 case BTA_HF_CLIENT_RING_INDICATION: 899 HAL_CBACK(bt_hf_client_callbacks, ring_indication_cb); 900 break; 901 default: 902 BTIF_TRACE_WARNING("%s: Unhandled event: %d", __FUNCTION__, event); 903 break; 904 } 905} 906 907/******************************************************************************* 908** 909** Function bte_hf_client_evt 910** 911** Description Switches context from BTE to BTIF for all HF Client events 912** 913** Returns void 914** 915*******************************************************************************/ 916 917static void bte_hf_client_evt(tBTA_HF_CLIENT_EVT event, tBTA_HF_CLIENT *p_data) 918{ 919 bt_status_t status; 920 921 /* switch context to btif task context (copy full union size for convenience) */ 922 status = btif_transfer_context(btif_hf_client_upstreams_evt, (uint16_t)event, (void*)p_data, sizeof(*p_data), NULL); 923 924 /* catch any failed context transfers */ 925 ASSERTC(status == BT_STATUS_SUCCESS, "context transfer failed", status); 926} 927 928/******************************************************************************* 929** 930** Function btif_hf_client_execute_service 931** 932** Description Initializes/Shuts down the service 933** 934** Returns BT_STATUS_SUCCESS on success, BT_STATUS_FAIL otherwise 935** 936*******************************************************************************/ 937bt_status_t btif_hf_client_execute_service(BOOLEAN b_enable) 938{ 939 BTIF_TRACE_EVENT("%s enable:%d", __FUNCTION__, b_enable); 940 941 property_get("ro.bluetooth.hfp.ver", btif_hf_client_version, "1.5"); 942 943 if (b_enable) 944 { 945 /* Enable and register with BTA-HFClient */ 946 BTA_HfClientEnable(bte_hf_client_evt); 947 if (strcmp(btif_hf_client_version, "1.6") == 0) 948 { 949 BTIF_TRACE_EVENT("Support Codec Nego. %d ", BTIF_HF_CLIENT_FEATURES); 950 BTA_HfClientRegister(BTIF_HF_CLIENT_SECURITY, BTIF_HF_CLIENT_FEATURES, 951 BTIF_HF_CLIENT_SERVICE_NAME); 952 } 953 else 954 { 955 BTIF_TRACE_EVENT("No Codec Nego Supported"); 956 btif_hf_client_features = BTIF_HF_CLIENT_FEATURES; 957 btif_hf_client_features = btif_hf_client_features & (~BTA_HF_CLIENT_FEAT_CODEC); 958 BTIF_TRACE_EVENT("btif_hf_client_features is %d", btif_hf_client_features); 959 BTA_HfClientRegister(BTIF_HF_CLIENT_SECURITY, btif_hf_client_features, 960 BTIF_HF_CLIENT_SERVICE_NAME); 961 } 962 963 } 964 else 965 { 966 BTA_HfClientDeregister(btif_hf_client_cb.handle); 967 BTA_HfClientDisable(); 968 } 969 return BT_STATUS_SUCCESS; 970} 971 972/******************************************************************************* 973** 974** Function btif_hf_get_interface 975** 976** Description Get the hf callback interface 977** 978** Returns bthf_interface_t 979** 980*******************************************************************************/ 981const bthf_client_interface_t *btif_hf_client_get_interface(void) 982{ 983 BTIF_TRACE_EVENT("%s", __FUNCTION__); 984 return &bthfClientInterface; 985} 986