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 ************************************************************************************/ 72 static bthf_client_callbacks_t *bt_hf_client_callbacks = NULL; 73 char btif_hf_client_version[PROPERTY_VALUE_MAX]; 74 static 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 */ 105 typedef 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 115 static 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 *******************************************************************************/ 132 static 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 159 static void clear_state(void) 160 { 161 memset(&btif_hf_client_cb, 0, sizeof(btif_hf_client_cb_t)); 162 } 163 164 static 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 *******************************************************************************/ 192 static 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 *******************************************************************************/ 214 static 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 228 static 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 *******************************************************************************/ 245 static 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 *******************************************************************************/ 267 static 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 *******************************************************************************/ 300 static 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 *******************************************************************************/ 322 static 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 *******************************************************************************/ 345 static 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 *******************************************************************************/ 368 static 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 *******************************************************************************/ 398 static 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 *******************************************************************************/ 423 static 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 *******************************************************************************/ 441 static 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 *******************************************************************************/ 538 static 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 *******************************************************************************/ 561 static 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 *******************************************************************************/ 579 static 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 *******************************************************************************/ 597 static 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 *******************************************************************************/ 615 static 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 *******************************************************************************/ 638 static 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 *******************************************************************************/ 658 static 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 668 static 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 690 static 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 *******************************************************************************/ 735 static 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 917 static 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 *******************************************************************************/ 937 bt_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 *******************************************************************************/ 981 const bthf_client_interface_t *btif_hf_client_get_interface(void) 982 { 983 BTIF_TRACE_EVENT("%s", __FUNCTION__); 984 return &bthfClientInterface; 985 } 986