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