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