1/****************************************************************************** 2 * 3 * Copyright (C) 2009-2012 Broadcom Corporation 4 * 5 * Licensed under the Apache License, Version 2.0 (the "License"); 6 * you may not use this file except in compliance with the License. 7 * You may obtain a copy of the License at: 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 * 17 ******************************************************************************/ 18 19/******************************************************************************* 20 * 21 * Filename: btif_hf.c 22 * 23 * Description: Handsfree Profile Bluetooth Interface 24 * 25 * 26 ******************************************************************************/ 27 28#define LOG_TAG "bt_btif_hf" 29 30#include <stdlib.h> 31#include <string.h> 32#include <time.h> 33 34#include <hardware/bluetooth.h> 35#include <hardware/bt_hf.h> 36 37#include "bta/include/utl.h" 38#include "bta_ag_api.h" 39#include "btcore/include/bdaddr.h" 40#include "btif_common.h" 41#include "btif_hf.h" 42#include "btif_profile_queue.h" 43#include "btif_util.h" 44#include "osi/include/properties.h" 45 46/******************************************************************************* 47 * Constants & Macros 48 ******************************************************************************/ 49#ifndef BTIF_HSAG_SERVICE_NAME 50#define BTIF_HSAG_SERVICE_NAME ("Headset Gateway") 51#endif 52 53#ifndef BTIF_HFAG_SERVICE_NAME 54#define BTIF_HFAG_SERVICE_NAME ("Handsfree Gateway") 55#endif 56 57#ifndef BTIF_HF_SERVICES 58#define BTIF_HF_SERVICES (BTA_HSP_SERVICE_MASK | BTA_HFP_SERVICE_MASK) 59#endif 60 61#ifndef BTIF_HF_SERVICE_NAMES 62#define BTIF_HF_SERVICE_NAMES \ 63 { BTIF_HSAG_SERVICE_NAME, BTIF_HFAG_SERVICE_NAME } 64#endif 65 66#ifndef BTIF_HF_SECURITY 67#define BTIF_HF_SECURITY (BTA_SEC_AUTHENTICATE | BTA_SEC_ENCRYPT) 68#endif 69 70#ifndef BTIF_HF_FEATURES 71#define BTIF_HF_FEATURES \ 72 (BTA_AG_FEAT_3WAY | BTA_AG_FEAT_ECNR | BTA_AG_FEAT_REJECT | \ 73 BTA_AG_FEAT_ECS | BTA_AG_FEAT_EXTERR | BTA_AG_FEAT_VREC | \ 74 BTA_AG_FEAT_CODEC | BTA_AG_FEAT_HF_IND | BTA_AG_FEAT_ESCO | \ 75 BTA_AG_FEAT_UNAT) 76#endif 77 78/* HF features supported at runtime */ 79static uint32_t btif_hf_features = BTIF_HF_FEATURES; 80 81#define BTIF_HF_CALL_END_TIMEOUT 6 82 83#define BTIF_HF_INVALID_IDX (-1) 84 85/* Number of BTIF-HF control blocks */ 86#define BTIF_HF_NUM_CB 2 87 88/* Max HF clients supported from App */ 89uint16_t btif_max_hf_clients = 1; 90 91/* HF app ids for service registration */ 92typedef enum { 93 BTIF_HF_ID_1 = 0, 94 BTIF_HF_ID_2, 95#if (BTIF_HF_NUM_CB == 3) 96 BTIF_HF_ID_3 97#endif 98} bthf_hf_id_t; 99 100uint16_t bthf_hf_id[BTIF_HF_NUM_CB] = {BTIF_HF_ID_1, BTIF_HF_ID_2, 101#if (BTIF_HF_NUM_CB == 3) 102 BTIF_HF_ID_3 103#endif 104}; 105 106/******************************************************************************* 107 * Local type definitions 108 ******************************************************************************/ 109 110/******************************************************************************* 111 * Static variables 112 ******************************************************************************/ 113static bthf_callbacks_t* bt_hf_callbacks = NULL; 114static int hf_idx = BTIF_HF_INVALID_IDX; 115 116#define CHECK_BTHF_INIT() \ 117 do { \ 118 if (bt_hf_callbacks == NULL) { \ 119 BTIF_TRACE_WARNING("BTHF: %s: BTHF not initialized", __func__); \ 120 return BT_STATUS_NOT_READY; \ 121 } else { \ 122 BTIF_TRACE_EVENT("BTHF: %s", __func__); \ 123 } \ 124 } while (0) 125 126/* BTIF-HF control block to map bdaddr to BTA handle */ 127typedef struct _btif_hf_cb { 128 uint16_t handle; 129 bt_bdaddr_t connected_bda; 130 bthf_connection_state_t state; 131 bthf_vr_state_t vr_state; 132 tBTA_AG_PEER_FEAT peer_feat; 133 int num_active; 134 int num_held; 135 struct timespec call_end_timestamp; 136 struct timespec connected_timestamp; 137 bthf_call_state_t call_setup_state; 138} btif_hf_cb_t; 139 140static btif_hf_cb_t btif_hf_cb[BTIF_HF_NUM_CB]; 141 142/******************************************************************************* 143 * Static functions 144 ******************************************************************************/ 145 146/******************************************************************************* 147 * Externs 148 ******************************************************************************/ 149/* By default, even though codec negotiation is enabled, we will not use WBS as 150* the default 151* codec unless this variable is set to true. 152*/ 153#ifndef BTIF_HF_WBS_PREFERRED 154#define BTIF_HF_WBS_PREFERRED false 155#endif 156 157bool btif_conf_hf_force_wbs = BTIF_HF_WBS_PREFERRED; 158 159/******************************************************************************* 160 * Functions 161 ******************************************************************************/ 162 163/******************************************************************************* 164 * 165 * Function is_connected 166 * 167 * Description Internal function to check if HF is connected 168 * 169 * Returns true if connected 170 * 171 ******************************************************************************/ 172static bool is_connected(bt_bdaddr_t* bd_addr) { 173 int i; 174 for (i = 0; i < btif_max_hf_clients; ++i) { 175 if (((btif_hf_cb[i].state == BTHF_CONNECTION_STATE_CONNECTED) || 176 (btif_hf_cb[i].state == BTHF_CONNECTION_STATE_SLC_CONNECTED)) && 177 ((bd_addr == NULL) || 178 (bdcmp(bd_addr->address, btif_hf_cb[i].connected_bda.address) == 0))) 179 return true; 180 } 181 return false; 182} 183 184/******************************************************************************* 185 * 186 * Function btif_hf_idx_by_bdaddr 187 * 188 * Description Internal function to get idx by bdaddr 189 * 190 * Returns idx 191 * 192 ******************************************************************************/ 193static int btif_hf_idx_by_bdaddr(bt_bdaddr_t* bd_addr) { 194 int i; 195 for (i = 0; i < btif_max_hf_clients; ++i) { 196 if ((bdcmp(bd_addr->address, btif_hf_cb[i].connected_bda.address) == 0)) 197 return i; 198 } 199 return BTIF_HF_INVALID_IDX; 200} 201 202/******************************************************************************* 203 * 204 * Function callstate_to_callsetup 205 * 206 * Description Converts HAL call state to BTA call setup indicator value 207 * 208 * Returns BTA call indicator value 209 * 210 ******************************************************************************/ 211static uint8_t callstate_to_callsetup(bthf_call_state_t call_state) { 212 uint8_t call_setup = 0; 213 if (call_state == BTHF_CALL_STATE_INCOMING) call_setup = 1; 214 if (call_state == BTHF_CALL_STATE_DIALING) call_setup = 2; 215 if (call_state == BTHF_CALL_STATE_ALERTING) call_setup = 3; 216 217 return call_setup; 218} 219 220/******************************************************************************* 221 * 222 * Function send_at_result 223 * 224 * Description Send AT result code (OK/ERROR) 225 * 226 * Returns void 227 * 228 ******************************************************************************/ 229static void send_at_result(uint8_t ok_flag, uint16_t errcode, int idx) { 230 tBTA_AG_RES_DATA ag_res; 231 memset(&ag_res, 0, sizeof(ag_res)); 232 233 ag_res.ok_flag = ok_flag; 234 if (ok_flag == BTA_AG_OK_ERROR) { 235 ag_res.errcode = errcode; 236 } 237 238 BTA_AgResult(btif_hf_cb[idx].handle, BTA_AG_UNAT_RES, &ag_res); 239} 240 241/******************************************************************************* 242 * 243 * Function send_indicator_update 244 * 245 * Description Send indicator update (CIEV) 246 * 247 * Returns void 248 * 249 ******************************************************************************/ 250static void send_indicator_update(uint16_t indicator, uint16_t value) { 251 tBTA_AG_RES_DATA ag_res; 252 253 memset(&ag_res, 0, sizeof(tBTA_AG_RES_DATA)); 254 ag_res.ind.id = indicator; 255 ag_res.ind.value = value; 256 257 BTA_AgResult(BTA_AG_HANDLE_ALL, BTA_AG_IND_RES, &ag_res); 258} 259 260void clear_phone_state_multihf(int idx) { 261 btif_hf_cb[idx].call_setup_state = BTHF_CALL_STATE_IDLE; 262 btif_hf_cb[idx].num_active = btif_hf_cb[idx].num_held = 0; 263} 264 265/******************************************************************************* 266 * 267 * Function btif_hf_latest_connected_idx 268 * 269 * Description Returns idx for latest connected HF 270 * 271 * Returns int 272 * 273 ******************************************************************************/ 274static int btif_hf_latest_connected_idx() { 275 struct timespec now, conn_time_delta; 276 int latest_conn_idx = BTIF_HF_INVALID_IDX, i; 277 278 clock_gettime(CLOCK_MONOTONIC, &now); 279 conn_time_delta.tv_sec = now.tv_sec; 280 281 for (i = 0; i < btif_max_hf_clients; i++) { 282 if (btif_hf_cb[i].state == BTHF_CONNECTION_STATE_SLC_CONNECTED) { 283 if ((now.tv_sec - btif_hf_cb[i].connected_timestamp.tv_sec) < 284 conn_time_delta.tv_sec) { 285 conn_time_delta.tv_sec = 286 now.tv_sec - btif_hf_cb[i].connected_timestamp.tv_sec; 287 latest_conn_idx = i; 288 } 289 } 290 } 291 return latest_conn_idx; 292} 293 294/******************************************************************************* 295 * 296 * Function btif_hf_check_if_slc_connected 297 * 298 * Description Returns BT_STATUS_SUCCESS if SLC is up for any HF 299 * 300 * Returns bt_status_t 301 * 302 ******************************************************************************/ 303static bt_status_t btif_hf_check_if_slc_connected() { 304 if (bt_hf_callbacks == NULL) { 305 BTIF_TRACE_WARNING("BTHF: %s: BTHF not initialized", __func__); 306 return BT_STATUS_NOT_READY; 307 } else { 308 int i; 309 for (i = 0; i < btif_max_hf_clients; i++) { 310 if (btif_hf_cb[i].state == BTHF_CONNECTION_STATE_SLC_CONNECTED) { 311 BTIF_TRACE_EVENT("BTHF: %s: slc connected for idx = %d", __func__, i); 312 return BT_STATUS_SUCCESS; 313 } 314 } 315 BTIF_TRACE_WARNING("BTHF: %s: No SLC connection up", __func__); 316 return BT_STATUS_NOT_READY; 317 } 318} 319 320/***************************************************************************** 321 * Section name (Group of functions) 322 ****************************************************************************/ 323 324/***************************************************************************** 325 * 326 * btif hf api functions (no context switch) 327 * 328 ****************************************************************************/ 329 330/******************************************************************************* 331 * 332 * Function btif_hf_upstreams_evt 333 * 334 * Description Executes HF UPSTREAMS events in btif context 335 * 336 * Returns void 337 * 338 ******************************************************************************/ 339static void btif_hf_upstreams_evt(uint16_t event, char* p_param) { 340 tBTA_AG* p_data = (tBTA_AG*)p_param; 341 bdstr_t bdstr; 342 int idx = p_data->hdr.handle - 1; 343 344 BTIF_TRACE_DEBUG("%s: event=%s", __func__, dump_hf_event(event)); 345 346 if ((idx < 0) || (idx >= BTIF_HF_NUM_CB)) { 347 BTIF_TRACE_ERROR("%s: Invalid index %d", __func__, idx); 348 return; 349 } 350 351 switch (event) { 352 case BTA_AG_ENABLE_EVT: 353 case BTA_AG_DISABLE_EVT: 354 break; 355 356 case BTA_AG_REGISTER_EVT: 357 btif_hf_cb[idx].handle = p_data->reg.hdr.handle; 358 BTIF_TRACE_DEBUG( 359 "%s: BTA_AG_REGISTER_EVT," 360 "btif_hf_cb.handle = %d", 361 __func__, btif_hf_cb[idx].handle); 362 break; 363 364 case BTA_AG_OPEN_EVT: 365 if (p_data->open.status == BTA_AG_SUCCESS) { 366 bdcpy(btif_hf_cb[idx].connected_bda.address, p_data->open.bd_addr); 367 btif_hf_cb[idx].state = BTHF_CONNECTION_STATE_CONNECTED; 368 btif_hf_cb[idx].peer_feat = 0; 369 clear_phone_state_multihf(idx); 370 } else if (btif_hf_cb[idx].state == BTHF_CONNECTION_STATE_CONNECTING) { 371 btif_hf_cb[idx].state = BTHF_CONNECTION_STATE_DISCONNECTED; 372 } else { 373 BTIF_TRACE_WARNING( 374 "%s: AG open failed, but another device connected. status=%d " 375 "state=%d connected device=%s", 376 __func__, p_data->open.status, btif_hf_cb[idx].state, 377 bdaddr_to_string(&btif_hf_cb[idx].connected_bda, bdstr, 378 sizeof(bdstr))); 379 break; 380 } 381 382 HAL_CBACK(bt_hf_callbacks, connection_state_cb, btif_hf_cb[idx].state, 383 &btif_hf_cb[idx].connected_bda); 384 385 if (btif_hf_cb[idx].state == BTHF_CONNECTION_STATE_DISCONNECTED) 386 bdsetany(btif_hf_cb[idx].connected_bda.address); 387 388 if (p_data->open.status != BTA_AG_SUCCESS) btif_queue_advance(); 389 break; 390 391 case BTA_AG_CLOSE_EVT: 392 btif_hf_cb[idx].connected_timestamp.tv_sec = 0; 393 btif_hf_cb[idx].state = BTHF_CONNECTION_STATE_DISCONNECTED; 394 BTIF_TRACE_DEBUG( 395 "%s: BTA_AG_CLOSE_EVT," 396 "idx = %d, btif_hf_cb.handle = %d", 397 __func__, idx, btif_hf_cb[idx].handle); 398 HAL_CBACK(bt_hf_callbacks, connection_state_cb, btif_hf_cb[idx].state, 399 &btif_hf_cb[idx].connected_bda); 400 bdsetany(btif_hf_cb[idx].connected_bda.address); 401 btif_hf_cb[idx].peer_feat = 0; 402 clear_phone_state_multihf(idx); 403 hf_idx = btif_hf_latest_connected_idx(); 404 /* If AG_OPEN was received but SLC was not setup in a specified time (10 405 *seconds), 406 ** then AG_CLOSE may be received. We need to advance the queue here 407 */ 408 btif_queue_advance(); 409 break; 410 411 case BTA_AG_CONN_EVT: 412 clock_gettime(CLOCK_MONOTONIC, &btif_hf_cb[idx].connected_timestamp); 413 BTIF_TRACE_DEBUG("%s: BTA_AG_CONN_EVT, idx = %d ", __func__, idx); 414 btif_hf_cb[idx].peer_feat = p_data->conn.peer_feat; 415 btif_hf_cb[idx].state = BTHF_CONNECTION_STATE_SLC_CONNECTED; 416 hf_idx = btif_hf_latest_connected_idx(); 417 418 HAL_CBACK(bt_hf_callbacks, connection_state_cb, btif_hf_cb[idx].state, 419 &btif_hf_cb[idx].connected_bda); 420 btif_queue_advance(); 421 break; 422 423 case BTA_AG_AUDIO_OPEN_EVT: 424 hf_idx = idx; 425 HAL_CBACK(bt_hf_callbacks, audio_state_cb, BTHF_AUDIO_STATE_CONNECTED, 426 &btif_hf_cb[idx].connected_bda); 427 break; 428 429 case BTA_AG_AUDIO_CLOSE_EVT: 430 HAL_CBACK(bt_hf_callbacks, audio_state_cb, BTHF_AUDIO_STATE_DISCONNECTED, 431 &btif_hf_cb[idx].connected_bda); 432 break; 433 434 /* BTA auto-responds, silently discard */ 435 case BTA_AG_SPK_EVT: 436 case BTA_AG_MIC_EVT: 437 HAL_CBACK(bt_hf_callbacks, volume_cmd_cb, 438 (event == BTA_AG_SPK_EVT) ? BTHF_VOLUME_TYPE_SPK 439 : BTHF_VOLUME_TYPE_MIC, 440 p_data->val.num, &btif_hf_cb[idx].connected_bda); 441 break; 442 443 case BTA_AG_AT_A_EVT: 444 if ((btif_hf_cb[0].num_held + btif_hf_cb[0].num_active) == 0) 445 hf_idx = idx; 446 else 447 BTIF_TRACE_DEBUG("Donot set hf_idx for ATA since already in a call"); 448 449 HAL_CBACK(bt_hf_callbacks, answer_call_cmd_cb, 450 &btif_hf_cb[idx].connected_bda); 451 break; 452 453 /* Java needs to send OK/ERROR for these commands */ 454 case BTA_AG_AT_BLDN_EVT: 455 case BTA_AG_AT_D_EVT: 456 if ((btif_hf_cb[0].num_held + btif_hf_cb[0].num_active) == 0) 457 hf_idx = idx; 458 else 459 BTIF_TRACE_DEBUG("Donot set hf_idx for BLDN/D since already in a call"); 460 461 HAL_CBACK(bt_hf_callbacks, dial_call_cmd_cb, 462 (event == BTA_AG_AT_D_EVT) ? p_data->val.str : NULL, 463 &btif_hf_cb[idx].connected_bda); 464 break; 465 466 case BTA_AG_AT_CHUP_EVT: 467 HAL_CBACK(bt_hf_callbacks, hangup_call_cmd_cb, 468 &btif_hf_cb[idx].connected_bda); 469 break; 470 471 case BTA_AG_AT_CIND_EVT: 472 HAL_CBACK(bt_hf_callbacks, cind_cmd_cb, &btif_hf_cb[idx].connected_bda); 473 break; 474 475 case BTA_AG_AT_VTS_EVT: 476 HAL_CBACK(bt_hf_callbacks, dtmf_cmd_cb, p_data->val.str[0], 477 &btif_hf_cb[idx].connected_bda); 478 break; 479 480 case BTA_AG_AT_BVRA_EVT: 481 HAL_CBACK(bt_hf_callbacks, vr_cmd_cb, 482 (p_data->val.num == 1) ? BTHF_VR_STATE_STARTED 483 : BTHF_VR_STATE_STOPPED, 484 &btif_hf_cb[idx].connected_bda); 485 break; 486 487 case BTA_AG_AT_NREC_EVT: 488 HAL_CBACK(bt_hf_callbacks, nrec_cmd_cb, 489 (p_data->val.num == 1) ? BTHF_NREC_START : BTHF_NREC_STOP, 490 &btif_hf_cb[idx].connected_bda); 491 break; 492 493 /* TODO: Add a callback for CBC */ 494 case BTA_AG_AT_CBC_EVT: 495 break; 496 497 case BTA_AG_AT_CKPD_EVT: 498 HAL_CBACK(bt_hf_callbacks, key_pressed_cmd_cb, 499 &btif_hf_cb[idx].connected_bda); 500 break; 501 502 case BTA_AG_WBS_EVT: 503 BTIF_TRACE_DEBUG( 504 "BTA_AG_WBS_EVT Set codec status %d codec %d 1=CVSD 2=MSBC", 505 p_data->val.hdr.status, p_data->val.num); 506 if (p_data->val.num == BTA_AG_CODEC_CVSD) { 507 HAL_CBACK(bt_hf_callbacks, wbs_cb, BTHF_WBS_NO, 508 &btif_hf_cb[idx].connected_bda); 509 } else if (p_data->val.num == BTA_AG_CODEC_MSBC) { 510 HAL_CBACK(bt_hf_callbacks, wbs_cb, BTHF_WBS_YES, 511 &btif_hf_cb[idx].connected_bda); 512 } else { 513 HAL_CBACK(bt_hf_callbacks, wbs_cb, BTHF_WBS_NONE, 514 &btif_hf_cb[idx].connected_bda); 515 } 516 break; 517 518 /* Java needs to send OK/ERROR for these commands */ 519 case BTA_AG_AT_CHLD_EVT: 520 HAL_CBACK(bt_hf_callbacks, chld_cmd_cb, 521 (bthf_chld_type_t)atoi(p_data->val.str), 522 &btif_hf_cb[idx].connected_bda); 523 break; 524 525 case BTA_AG_AT_CLCC_EVT: 526 HAL_CBACK(bt_hf_callbacks, clcc_cmd_cb, &btif_hf_cb[idx].connected_bda); 527 break; 528 529 case BTA_AG_AT_COPS_EVT: 530 HAL_CBACK(bt_hf_callbacks, cops_cmd_cb, &btif_hf_cb[idx].connected_bda); 531 break; 532 533 case BTA_AG_AT_UNAT_EVT: 534 HAL_CBACK(bt_hf_callbacks, unknown_at_cmd_cb, p_data->val.str, 535 &btif_hf_cb[idx].connected_bda); 536 break; 537 538 case BTA_AG_AT_CNUM_EVT: 539 HAL_CBACK(bt_hf_callbacks, cnum_cmd_cb, &btif_hf_cb[idx].connected_bda); 540 break; 541 542 /* TODO: Some of these commands may need to be sent to app. For now respond 543 * with error */ 544 case BTA_AG_AT_BINP_EVT: 545 case BTA_AG_AT_BTRH_EVT: 546 send_at_result(BTA_AG_OK_ERROR, BTA_AG_ERR_OP_NOT_SUPPORTED, idx); 547 break; 548 case BTA_AG_AT_BAC_EVT: 549 BTIF_TRACE_DEBUG("AG Bitmap of peer-codecs %d", p_data->val.num); 550 /* If the peer supports mSBC and the BTIF preferred codec is also mSBC, 551 then 552 we should set the BTA AG Codec to mSBC. This would trigger a +BCS to mSBC 553 at the time 554 of SCO connection establishment */ 555 if ((btif_conf_hf_force_wbs == true) && 556 (p_data->val.num & BTA_AG_CODEC_MSBC)) { 557 BTIF_TRACE_EVENT("%s: btif_hf override-Preferred Codec to MSBC", 558 __func__); 559 BTA_AgSetCodec(btif_hf_cb[idx].handle, BTA_AG_CODEC_MSBC); 560 } else { 561 BTIF_TRACE_EVENT("%s btif_hf override-Preferred Codec to CVSD", 562 __func__); 563 BTA_AgSetCodec(btif_hf_cb[idx].handle, BTA_AG_CODEC_CVSD); 564 } 565 break; 566 case BTA_AG_AT_BCS_EVT: 567 BTIF_TRACE_DEBUG("%s: AG final selected codec is 0x%02x 1=CVSD 2=MSBC", 568 __func__, p_data->val.num); 569 /* No BTHF_WBS_NONE case, because HF1.6 supported device can send BCS */ 570 /* Only CVSD is considered narrow band speech */ 571 HAL_CBACK( 572 bt_hf_callbacks, wbs_cb, 573 (p_data->val.num == BTA_AG_CODEC_CVSD) ? BTHF_WBS_NO : BTHF_WBS_YES, 574 &btif_hf_cb[idx].connected_bda); 575 break; 576 577 case BTA_AG_AT_BIND_EVT: 578 if (p_data->val.hdr.status == BTA_AG_SUCCESS) { 579 HAL_CBACK(bt_hf_callbacks, bind_cb, p_data->val.str, 580 &btif_hf_cb[idx].connected_bda); 581 } 582 break; 583 584 case BTA_AG_AT_BIEV_EVT: 585 if (p_data->val.hdr.status == BTA_AG_SUCCESS) { 586 HAL_CBACK(bt_hf_callbacks, biev_cb, 587 (bthf_hf_ind_type_t)p_data->val.lidx, (int)p_data->val.num, 588 &btif_hf_cb[idx].connected_bda); 589 } 590 break; 591 default: 592 BTIF_TRACE_WARNING("%s: Unhandled event: %d", __func__, event); 593 break; 594 } 595} 596 597/******************************************************************************* 598 * 599 * Function bte_hf_evt 600 * 601 * Description Switches context from BTE to BTIF for all HF events 602 * 603 * Returns void 604 * 605 ******************************************************************************/ 606 607static void bte_hf_evt(tBTA_AG_EVT event, tBTA_AG* p_data) { 608 bt_status_t status; 609 int param_len = 0; 610 611 /* TODO: BTA sends the union members and not tBTA_AG. If using 612 * param_len=sizeof(tBTA_AG), we get a crash on memcpy */ 613 if (BTA_AG_REGISTER_EVT == event) 614 param_len = sizeof(tBTA_AG_REGISTER); 615 else if (BTA_AG_OPEN_EVT == event) 616 param_len = sizeof(tBTA_AG_OPEN); 617 else if (BTA_AG_CONN_EVT == event) 618 param_len = sizeof(tBTA_AG_CONN); 619 else if ((BTA_AG_CLOSE_EVT == event) || (BTA_AG_AUDIO_OPEN_EVT == event) || 620 (BTA_AG_AUDIO_CLOSE_EVT == event)) 621 param_len = sizeof(tBTA_AG_HDR); 622 else if (p_data) 623 param_len = sizeof(tBTA_AG_VAL); 624 625 /* switch context to btif task context (copy full union size for convenience) 626 */ 627 status = btif_transfer_context(btif_hf_upstreams_evt, (uint16_t)event, 628 (char*)p_data, param_len, NULL); 629 630 /* catch any failed context transfers */ 631 ASSERTC(status == BT_STATUS_SUCCESS, "context transfer failed", status); 632} 633 634/******************************************************************************* 635 * 636 * Function btif_in_hf_generic_evt 637 * 638 * Description Processes generic events to be sent to JNI that are not 639 * triggered from the BTA. 640 * Always runs in BTIF context 641 * 642 * Returns void 643 * 644 ******************************************************************************/ 645static void btif_in_hf_generic_evt(uint16_t event, char* p_param) { 646 int idx = btif_hf_idx_by_bdaddr((bt_bdaddr_t*)p_param); 647 648 BTIF_TRACE_EVENT("%s: event=%d", __func__, event); 649 650 if ((idx < 0) || (idx >= BTIF_HF_NUM_CB)) { 651 BTIF_TRACE_ERROR("%s: Invalid index %d", __func__, idx); 652 return; 653 } 654 655 switch (event) { 656 case BTIF_HFP_CB_AUDIO_CONNECTING: { 657 HAL_CBACK(bt_hf_callbacks, audio_state_cb, BTHF_AUDIO_STATE_CONNECTING, 658 &btif_hf_cb[idx].connected_bda); 659 } break; 660 default: { 661 BTIF_TRACE_WARNING("%s : Unknown event 0x%x", __func__, event); 662 } break; 663 } 664} 665 666static bool inband_ringing_property_enabled() { 667 char inband_ringing_flag[PROPERTY_VALUE_MAX] = {0}; 668 osi_property_get("persist.bluetooth.enableinbandringing", inband_ringing_flag, 669 "false"); 670 if (strncmp(inband_ringing_flag, "true", 4) == 0) { 671 BTIF_TRACE_DEBUG("%s: In-band ringing enabled by property", __func__); 672 return true; 673 } 674 return false; 675} 676 677/******************************************************************************* 678 * 679 * Function btif_hf_init 680 * 681 * Description initializes the hf interface 682 * 683 * Returns bt_status_t 684 * 685 ******************************************************************************/ 686static bt_status_t init(bthf_callbacks_t* callbacks, int max_hf_clients, 687 bool inband_ringing_supported) { 688 bool inband_ringing_property_enable = inband_ringing_property_enabled(); 689 if (inband_ringing_supported && inband_ringing_property_enable) { 690 btif_hf_features |= BTA_AG_FEAT_INBAND; 691 } else { 692 btif_hf_features &= ~BTA_AG_FEAT_INBAND; 693 } 694 btif_max_hf_clients = max_hf_clients; 695 BTIF_TRACE_DEBUG( 696 "%s: btif_hf_features=%zu, max_hf_clients=%d, " 697 "inband_ringing=[supported=%d, enabled=%d]", 698 __func__, btif_hf_features, btif_max_hf_clients, inband_ringing_supported, 699 inband_ringing_property_enable); 700 bt_hf_callbacks = callbacks; 701 memset(&btif_hf_cb, 0, sizeof(btif_hf_cb)); 702 703/* Invoke the enable service API to the core to set the appropriate service_id 704 * Internally, the HSP_SERVICE_ID shall also be enabled if HFP is enabled 705 * (phone) 706 * othwerwise only HSP is enabled (tablet) 707*/ 708#if (defined(BTIF_HF_SERVICES) && (BTIF_HF_SERVICES & BTA_HFP_SERVICE_MASK)) 709 btif_enable_service(BTA_HFP_SERVICE_ID); 710#else 711 btif_enable_service(BTA_HSP_SERVICE_ID); 712#endif 713 714 for (int i = 0; i < btif_max_hf_clients; i++) clear_phone_state_multihf(i); 715 716 return BT_STATUS_SUCCESS; 717} 718 719/******************************************************************************* 720 * 721 * Function connect 722 * 723 * Description connect to headset 724 * 725 * Returns bt_status_t 726 * 727 ******************************************************************************/ 728static bt_status_t connect_int(bt_bdaddr_t* bd_addr, uint16_t uuid) { 729 CHECK_BTHF_INIT(); 730 int i; 731 for (i = 0; i < btif_max_hf_clients;) { 732 if (((btif_hf_cb[i].state == BTHF_CONNECTION_STATE_CONNECTED) || 733 (btif_hf_cb[i].state == BTHF_CONNECTION_STATE_SLC_CONNECTED))) 734 i++; 735 else 736 break; 737 } 738 739 if (i == btif_max_hf_clients) return BT_STATUS_BUSY; 740 741 if (!is_connected(bd_addr)) { 742 btif_hf_cb[i].state = BTHF_CONNECTION_STATE_CONNECTING; 743 bdcpy(btif_hf_cb[i].connected_bda.address, bd_addr->address); 744 745 BTA_AgOpen(btif_hf_cb[i].handle, btif_hf_cb[i].connected_bda.address, 746 BTIF_HF_SECURITY, BTIF_HF_SERVICES); 747 return BT_STATUS_SUCCESS; 748 } 749 750 return BT_STATUS_BUSY; 751} 752 753static bt_status_t connect(bt_bdaddr_t* bd_addr) { 754 CHECK_BTHF_INIT(); 755 return btif_queue_connect(UUID_SERVCLASS_AG_HANDSFREE, bd_addr, connect_int); 756} 757 758/******************************************************************************* 759 * 760 * Function disconnect 761 * 762 * Description disconnect from headset 763 * 764 * Returns bt_status_t 765 * 766 ******************************************************************************/ 767static bt_status_t disconnect(bt_bdaddr_t* bd_addr) { 768 CHECK_BTHF_INIT(); 769 770 int idx = btif_hf_idx_by_bdaddr(bd_addr); 771 772 if ((idx < 0) || (idx >= BTIF_HF_NUM_CB)) { 773 BTIF_TRACE_ERROR("%s: Invalid index %d", __func__, idx); 774 return BT_STATUS_FAIL; 775 } 776 777 if (is_connected(bd_addr) && (idx != BTIF_HF_INVALID_IDX)) { 778 BTA_AgClose(btif_hf_cb[idx].handle); 779 return BT_STATUS_SUCCESS; 780 } 781 782 return BT_STATUS_FAIL; 783} 784 785/******************************************************************************* 786 * 787 * Function connect_audio 788 * 789 * Description create an audio connection 790 * 791 * Returns bt_status_t 792 * 793 ******************************************************************************/ 794static bt_status_t connect_audio(bt_bdaddr_t* bd_addr) { 795 CHECK_BTHF_INIT(); 796 797 int idx = btif_hf_idx_by_bdaddr(bd_addr); 798 799 if ((idx < 0) || (idx >= BTIF_HF_NUM_CB)) { 800 BTIF_TRACE_ERROR("%s: Invalid index %d", __func__, idx); 801 return BT_STATUS_FAIL; 802 } 803 804 /* Check if SLC is connected */ 805 if (btif_hf_check_if_slc_connected() != BT_STATUS_SUCCESS) 806 return BT_STATUS_NOT_READY; 807 808 if (is_connected(bd_addr) && (idx != BTIF_HF_INVALID_IDX)) { 809 BTA_AgAudioOpen(btif_hf_cb[idx].handle); 810 811 /* Inform the application that the audio connection has been initiated 812 * successfully */ 813 btif_transfer_context(btif_in_hf_generic_evt, BTIF_HFP_CB_AUDIO_CONNECTING, 814 (char*)bd_addr, sizeof(bt_bdaddr_t), NULL); 815 return BT_STATUS_SUCCESS; 816 } 817 818 return BT_STATUS_FAIL; 819} 820 821/******************************************************************************* 822 * 823 * Function disconnect_audio 824 * 825 * Description close the audio connection 826 * 827 * Returns bt_status_t 828 * 829 ******************************************************************************/ 830static bt_status_t disconnect_audio(bt_bdaddr_t* bd_addr) { 831 CHECK_BTHF_INIT(); 832 833 int idx = btif_hf_idx_by_bdaddr(bd_addr); 834 835 if ((idx < 0) || (idx >= BTIF_HF_NUM_CB)) { 836 BTIF_TRACE_ERROR("%s: Invalid index %d", __func__, idx); 837 return BT_STATUS_FAIL; 838 } 839 840 if (is_connected(bd_addr) && (idx != BTIF_HF_INVALID_IDX)) { 841 BTA_AgAudioClose(btif_hf_cb[idx].handle); 842 return BT_STATUS_SUCCESS; 843 } 844 845 return BT_STATUS_FAIL; 846} 847 848/******************************************************************************* 849 * 850 * Function start_voice_recognition 851 * 852 * Description start voice recognition 853 * 854 * Returns bt_status_t 855 * 856 ******************************************************************************/ 857static bt_status_t start_voice_recognition(bt_bdaddr_t* bd_addr) { 858 CHECK_BTHF_INIT(); 859 860 int idx = btif_hf_idx_by_bdaddr(bd_addr); 861 862 if ((idx < 0) || (idx >= BTIF_HF_NUM_CB)) { 863 BTIF_TRACE_ERROR("%s: Invalid index %d", __func__, idx); 864 return BT_STATUS_FAIL; 865 } 866 867 if (is_connected(bd_addr) && (idx != BTIF_HF_INVALID_IDX)) { 868 if (btif_hf_cb[idx].peer_feat & BTA_AG_PEER_FEAT_VREC) { 869 tBTA_AG_RES_DATA ag_res; 870 memset(&ag_res, 0, sizeof(ag_res)); 871 ag_res.state = 1; 872 BTA_AgResult(btif_hf_cb[idx].handle, BTA_AG_BVRA_RES, &ag_res); 873 874 return BT_STATUS_SUCCESS; 875 } else { 876 return BT_STATUS_UNSUPPORTED; 877 } 878 } 879 880 return BT_STATUS_NOT_READY; 881} 882 883/******************************************************************************* 884 * 885 * Function stop_voice_recognition 886 * 887 * Description stop voice recognition 888 * 889 * Returns bt_status_t 890 * 891 ******************************************************************************/ 892static bt_status_t stop_voice_recognition(bt_bdaddr_t* bd_addr) { 893 CHECK_BTHF_INIT(); 894 895 int idx = btif_hf_idx_by_bdaddr(bd_addr); 896 897 if ((idx < 0) || (idx >= BTIF_HF_NUM_CB)) { 898 BTIF_TRACE_ERROR("%s: Invalid index %d", __func__, idx); 899 return BT_STATUS_FAIL; 900 } 901 902 if (is_connected(bd_addr) && (idx != BTIF_HF_INVALID_IDX)) { 903 if (btif_hf_cb[idx].peer_feat & BTA_AG_PEER_FEAT_VREC) { 904 tBTA_AG_RES_DATA ag_res; 905 memset(&ag_res, 0, sizeof(ag_res)); 906 ag_res.state = 0; 907 BTA_AgResult(btif_hf_cb[idx].handle, BTA_AG_BVRA_RES, &ag_res); 908 909 return BT_STATUS_SUCCESS; 910 } else { 911 return BT_STATUS_UNSUPPORTED; 912 } 913 } 914 915 return BT_STATUS_NOT_READY; 916} 917 918/******************************************************************************* 919 * 920 * Function volume_control 921 * 922 * Description volume control 923 * 924 * Returns bt_status_t 925 * 926 ******************************************************************************/ 927static bt_status_t volume_control(bthf_volume_type_t type, int volume, 928 bt_bdaddr_t* bd_addr) { 929 CHECK_BTHF_INIT(); 930 931 int idx = btif_hf_idx_by_bdaddr(bd_addr); 932 933 if ((idx < 0) || (idx >= BTIF_HF_NUM_CB)) { 934 BTIF_TRACE_ERROR("%s: Invalid index %d", __func__, idx); 935 return BT_STATUS_FAIL; 936 } 937 938 tBTA_AG_RES_DATA ag_res; 939 memset(&ag_res, 0, sizeof(tBTA_AG_RES_DATA)); 940 if (is_connected(bd_addr) && (idx != BTIF_HF_INVALID_IDX)) { 941 ag_res.num = volume; 942 BTA_AgResult( 943 btif_hf_cb[idx].handle, 944 (type == BTHF_VOLUME_TYPE_SPK) ? BTA_AG_SPK_RES : BTA_AG_MIC_RES, 945 &ag_res); 946 return BT_STATUS_SUCCESS; 947 } 948 949 return BT_STATUS_FAIL; 950} 951 952/******************************************************************************* 953 * 954 * Function device_status_notification 955 * 956 * Description Combined device status change notification 957 * 958 * Returns bt_status_t 959 * 960 ******************************************************************************/ 961static bt_status_t device_status_notification(bthf_network_state_t ntk_state, 962 bthf_service_type_t svc_type, 963 int signal, int batt_chg) { 964 CHECK_BTHF_INIT(); 965 966 if (is_connected(NULL)) { 967 /* send all indicators to BTA. 968 ** BTA will make sure no duplicates are sent out 969 */ 970 send_indicator_update(BTA_AG_IND_SERVICE, 971 (ntk_state == BTHF_NETWORK_STATE_AVAILABLE) ? 1 : 0); 972 send_indicator_update(BTA_AG_IND_ROAM, 973 (svc_type == BTHF_SERVICE_TYPE_HOME) ? 0 : 1); 974 send_indicator_update(BTA_AG_IND_SIGNAL, signal); 975 send_indicator_update(BTA_AG_IND_BATTCHG, batt_chg); 976 return BT_STATUS_SUCCESS; 977 } 978 979 return BT_STATUS_SUCCESS; 980} 981 982/******************************************************************************* 983 * 984 * Function cops_response 985 * 986 * Description Response for COPS command 987 * 988 * Returns bt_status_t 989 * 990 ******************************************************************************/ 991static bt_status_t cops_response(const char* cops, bt_bdaddr_t* bd_addr) { 992 CHECK_BTHF_INIT(); 993 994 int idx = btif_hf_idx_by_bdaddr(bd_addr); 995 996 if ((idx < 0) || (idx >= BTIF_HF_NUM_CB)) { 997 BTIF_TRACE_ERROR("%s: Invalid index %d", __func__, idx); 998 return BT_STATUS_FAIL; 999 } 1000 1001 if (is_connected(bd_addr) && (idx != BTIF_HF_INVALID_IDX)) { 1002 tBTA_AG_RES_DATA ag_res; 1003 1004 /* Format the response */ 1005 snprintf(ag_res.str, sizeof(ag_res.str), "0,0,\"%.16s\"", cops); 1006 ag_res.ok_flag = BTA_AG_OK_DONE; 1007 1008 BTA_AgResult(btif_hf_cb[idx].handle, BTA_AG_COPS_RES, &ag_res); 1009 return BT_STATUS_SUCCESS; 1010 } 1011 return BT_STATUS_FAIL; 1012} 1013 1014/******************************************************************************* 1015 * 1016 * Function cind_response 1017 * 1018 * Description Response for CIND command 1019 * 1020 * Returns bt_status_t 1021 * 1022 ******************************************************************************/ 1023static bt_status_t cind_response(int svc, int num_active, int num_held, 1024 bthf_call_state_t call_setup_state, int signal, 1025 int roam, int batt_chg, bt_bdaddr_t* bd_addr) { 1026 CHECK_BTHF_INIT(); 1027 1028 int idx = btif_hf_idx_by_bdaddr(bd_addr); 1029 1030 if ((idx < 0) || (idx >= BTIF_HF_NUM_CB)) { 1031 BTIF_TRACE_ERROR("%s: Invalid index %d", __func__, idx); 1032 return BT_STATUS_FAIL; 1033 } 1034 1035 if (is_connected(bd_addr) && (idx != BTIF_HF_INVALID_IDX)) { 1036 tBTA_AG_RES_DATA ag_res; 1037 1038 memset(&ag_res, 0, sizeof(ag_res)); 1039 /* per the errata 2043, call=1 implies atleast one call is in progress 1040 *(active/held) 1041 ** https://www.bluetooth.org/errata/errata_view.cfm?errata_id=2043 1042 **/ 1043 snprintf( 1044 ag_res.str, sizeof(ag_res.str), "%d,%d,%d,%d,%d,%d,%d", 1045 (num_active + num_held) ? 1 : 0, /* Call state */ 1046 callstate_to_callsetup(call_setup_state), /* Callsetup state */ 1047 svc, /* network service */ 1048 signal, /* Signal strength */ 1049 roam, /* Roaming indicator */ 1050 batt_chg, /* Battery level */ 1051 ((num_held == 0) ? 0 : ((num_active == 0) ? 2 : 1))); /* Call held */ 1052 1053 BTA_AgResult(btif_hf_cb[idx].handle, BTA_AG_CIND_RES, &ag_res); 1054 1055 return BT_STATUS_SUCCESS; 1056 } 1057 1058 return BT_STATUS_FAIL; 1059} 1060 1061/******************************************************************************* 1062 * 1063 * Function bind_response 1064 * 1065 * Description Send +BIND response 1066 * 1067 * Returns bt_status_t 1068 * 1069 ******************************************************************************/ 1070static bt_status_t bind_response(bthf_hf_ind_type_t ind_id, 1071 bthf_hf_ind_status_t ind_status, 1072 bt_bdaddr_t* bd_addr) { 1073 CHECK_BTHF_INIT(); 1074 1075 int index = btif_hf_idx_by_bdaddr(bd_addr); 1076 if (!is_connected(bd_addr) || index == BTIF_HF_INVALID_IDX) 1077 return BT_STATUS_FAIL; 1078 1079 tBTA_AG_RES_DATA ag_res; 1080 memset(&ag_res, 0, sizeof(ag_res)); 1081 ag_res.ind.id = ind_id; 1082 ag_res.ind.on_demand = (ind_status == BTHF_HF_IND_ENABLED); 1083 1084 BTA_AgResult(btif_hf_cb[index].handle, BTA_AG_BIND_RES, &ag_res); 1085 return BT_STATUS_SUCCESS; 1086} 1087 1088/******************************************************************************* 1089 * 1090 * Function formatted_at_response 1091 * 1092 * Description Pre-formatted AT response, typically in response to unknown 1093 * AT cmd 1094 * 1095 * Returns bt_status_t 1096 * 1097 ******************************************************************************/ 1098static bt_status_t formatted_at_response(const char* rsp, 1099 bt_bdaddr_t* bd_addr) { 1100 CHECK_BTHF_INIT(); 1101 tBTA_AG_RES_DATA ag_res; 1102 int idx = btif_hf_idx_by_bdaddr(bd_addr); 1103 1104 if ((idx < 0) || (idx >= BTIF_HF_NUM_CB)) { 1105 BTIF_TRACE_ERROR("%s: Invalid index %d", __func__, idx); 1106 return BT_STATUS_FAIL; 1107 } 1108 1109 if (is_connected(bd_addr) && (idx != BTIF_HF_INVALID_IDX)) { 1110 /* Format the response and send */ 1111 memset(&ag_res, 0, sizeof(ag_res)); 1112 strncpy(ag_res.str, rsp, BTA_AG_AT_MAX_LEN); 1113 BTA_AgResult(btif_hf_cb[idx].handle, BTA_AG_UNAT_RES, &ag_res); 1114 1115 return BT_STATUS_SUCCESS; 1116 } 1117 1118 return BT_STATUS_FAIL; 1119} 1120 1121/******************************************************************************* 1122 * 1123 * Function at_response 1124 * 1125 * Description ok/error response 1126 * 1127 * Returns bt_status_t 1128 * 1129 ******************************************************************************/ 1130static bt_status_t at_response(bthf_at_response_t response_code, int error_code, 1131 bt_bdaddr_t* bd_addr) { 1132 CHECK_BTHF_INIT(); 1133 1134 int idx = btif_hf_idx_by_bdaddr(bd_addr); 1135 1136 if ((idx < 0) || (idx >= BTIF_HF_NUM_CB)) { 1137 BTIF_TRACE_ERROR("%s: Invalid index %d", __func__, idx); 1138 return BT_STATUS_FAIL; 1139 } 1140 1141 if (is_connected(bd_addr) && (idx != BTIF_HF_INVALID_IDX)) { 1142 send_at_result((response_code == BTHF_AT_RESPONSE_OK) ? BTA_AG_OK_DONE 1143 : BTA_AG_OK_ERROR, 1144 error_code, idx); 1145 return BT_STATUS_SUCCESS; 1146 } 1147 1148 return BT_STATUS_FAIL; 1149} 1150 1151/******************************************************************************* 1152 * 1153 * Function clcc_response 1154 * 1155 * Description response for CLCC command 1156 * Can be iteratively called for each call index. Call index 1157 * of 0 will be treated as NULL termination (Completes 1158 * response) 1159 * 1160 * Returns bt_status_t 1161 * 1162 ******************************************************************************/ 1163static bt_status_t clcc_response(int index, bthf_call_direction_t dir, 1164 bthf_call_state_t state, bthf_call_mode_t mode, 1165 bthf_call_mpty_type_t mpty, const char* number, 1166 bthf_call_addrtype_t type, 1167 bt_bdaddr_t* bd_addr) { 1168 CHECK_BTHF_INIT(); 1169 1170 int idx = btif_hf_idx_by_bdaddr(bd_addr); 1171 1172 if ((idx < 0) || (idx >= BTIF_HF_NUM_CB)) { 1173 BTIF_TRACE_ERROR("%s: Invalid index %d", __func__, idx); 1174 return BT_STATUS_FAIL; 1175 } 1176 1177 if (is_connected(bd_addr) && (idx != BTIF_HF_INVALID_IDX)) { 1178 tBTA_AG_RES_DATA ag_res; 1179 memset(&ag_res, 0, sizeof(ag_res)); 1180 1181 /* Format the response */ 1182 if (index == 0) { 1183 ag_res.ok_flag = BTA_AG_OK_DONE; 1184 } else { 1185 BTIF_TRACE_EVENT( 1186 "clcc_response: [%d] dir %d state %d mode %d number = %s type = %d", 1187 index, dir, state, mode, number, type); 1188 int res_strlen = 1189 snprintf(ag_res.str, sizeof(ag_res.str), "%d,%d,%d,%d,%d", index, dir, 1190 state, mode, mpty); 1191 1192 if (number) { 1193 size_t rem_bytes = sizeof(ag_res.str) - res_strlen; 1194 char dialnum[sizeof(ag_res.str)]; 1195 size_t newidx = 0; 1196 if (type == BTHF_CALL_ADDRTYPE_INTERNATIONAL && *number != '+') { 1197 dialnum[newidx++] = '+'; 1198 } 1199 for (size_t i = 0; number[i] != 0; i++) { 1200 if (utl_isdialchar(number[i])) { 1201 dialnum[newidx++] = number[i]; 1202 } 1203 } 1204 dialnum[newidx] = 0; 1205 snprintf(&ag_res.str[res_strlen], rem_bytes, ",\"%s\",%d", dialnum, 1206 type); 1207 } 1208 } 1209 BTA_AgResult(btif_hf_cb[idx].handle, BTA_AG_CLCC_RES, &ag_res); 1210 1211 return BT_STATUS_SUCCESS; 1212 } 1213 1214 return BT_STATUS_FAIL; 1215} 1216 1217/******************************************************************************* 1218 * 1219 * Function phone_state_change 1220 * 1221 * Description notify of a call state change 1222 * number & type: valid only for incoming & waiting call 1223 * 1224 * Returns bt_status_t 1225 * 1226 ******************************************************************************/ 1227 1228static bt_status_t phone_state_change(int num_active, int num_held, 1229 bthf_call_state_t call_setup_state, 1230 const char* number, 1231 bthf_call_addrtype_t type) { 1232 tBTA_AG_RES res = 0xff; 1233 tBTA_AG_RES_DATA ag_res; 1234 bt_status_t status = BT_STATUS_SUCCESS; 1235 bool activeCallUpdated = false; 1236 int idx, i; 1237 1238 /* hf_idx is index of connected HS that sent ATA/BLDN, 1239 otherwise index of latest connected HS */ 1240 if (hf_idx != BTIF_HF_INVALID_IDX) 1241 idx = hf_idx; 1242 else 1243 idx = btif_hf_latest_connected_idx(); 1244 1245 BTIF_TRACE_DEBUG("phone_state_change: idx = %d", idx); 1246 1247 /* Check if SLC is connected */ 1248 if (btif_hf_check_if_slc_connected() != BT_STATUS_SUCCESS) 1249 return BT_STATUS_NOT_READY; 1250 1251 BTIF_TRACE_DEBUG( 1252 "phone_state_change: num_active=%d [prev: %d] num_held=%d[prev: %d]" 1253 " call_setup=%s [prev: %s]", 1254 num_active, btif_hf_cb[idx].num_active, num_held, 1255 btif_hf_cb[idx].num_held, dump_hf_call_state(call_setup_state), 1256 dump_hf_call_state(btif_hf_cb[idx].call_setup_state)); 1257 1258 /* if all indicators are 0, send end call and return */ 1259 if (num_active == 0 && num_held == 0 && 1260 call_setup_state == BTHF_CALL_STATE_IDLE) { 1261 BTIF_TRACE_DEBUG("%s: Phone on hook", __func__); 1262 1263 /* record call termination timestamp if there was an active/held call or 1264 callsetup state > BTHF_CALL_STATE_IDLE */ 1265 if ((btif_hf_cb[idx].call_setup_state != BTHF_CALL_STATE_IDLE) || 1266 (btif_hf_cb[idx].num_active) || (btif_hf_cb[idx].num_held)) { 1267 BTIF_TRACE_DEBUG("%s: Record call termination timestamp", __func__); 1268 clock_gettime(CLOCK_MONOTONIC, &btif_hf_cb[0].call_end_timestamp); 1269 } 1270 BTA_AgResult(BTA_AG_HANDLE_ALL, BTA_AG_END_CALL_RES, NULL); 1271 hf_idx = BTIF_HF_INVALID_IDX; 1272 1273 /* if held call was present, reset that as well */ 1274 if (btif_hf_cb[idx].num_held) send_indicator_update(BTA_AG_IND_CALLHELD, 0); 1275 1276 goto update_call_states; 1277 } 1278 1279 /* active state can change when: 1280 ** 1. an outgoing/incoming call was answered 1281 ** 2. an held was resumed 1282 ** 3. without callsetup notifications, call became active 1283 ** (3) can happen if call is active and a headset connects to us 1284 ** 1285 ** In the case of (3), we will have to notify the stack of an active 1286 ** call, instead of sending an indicator update. This will also 1287 ** force the SCO to be setup. Handle this special case here prior to 1288 ** call setup handling 1289 */ 1290 if (((num_active + num_held) > 0) && (btif_hf_cb[idx].num_active == 0) && 1291 (btif_hf_cb[idx].num_held == 0) && 1292 (btif_hf_cb[idx].call_setup_state == BTHF_CALL_STATE_IDLE)) { 1293 BTIF_TRACE_DEBUG( 1294 "%s: Active/Held call notification received without call setup update", 1295 __func__); 1296 1297 memset(&ag_res, 0, sizeof(tBTA_AG_RES_DATA)); 1298 ag_res.audio_handle = BTA_AG_HANDLE_SCO_NO_CHANGE; 1299 /* Addition call setup with the Active call 1300 ** CIND response should have been updated. 1301 ** just open SCO connection. 1302 */ 1303 if (call_setup_state != BTHF_CALL_STATE_IDLE) 1304 res = BTA_AG_MULTI_CALL_RES; 1305 else 1306 res = BTA_AG_OUT_CALL_CONN_RES; 1307 BTA_AgResult(BTA_AG_HANDLE_ALL, res, &ag_res); 1308 activeCallUpdated = true; 1309 } 1310 1311 /* Ringing call changed? */ 1312 if (call_setup_state != btif_hf_cb[idx].call_setup_state) { 1313 BTIF_TRACE_DEBUG("%s: Call setup states changed. old: %s new: %s", __func__, 1314 dump_hf_call_state(btif_hf_cb[idx].call_setup_state), 1315 dump_hf_call_state(call_setup_state)); 1316 memset(&ag_res, 0, sizeof(tBTA_AG_RES_DATA)); 1317 1318 switch (call_setup_state) { 1319 case BTHF_CALL_STATE_IDLE: { 1320 switch (btif_hf_cb[idx].call_setup_state) { 1321 case BTHF_CALL_STATE_INCOMING: 1322 if (num_active > btif_hf_cb[idx].num_active) { 1323 res = BTA_AG_IN_CALL_CONN_RES; 1324 ag_res.audio_handle = btif_hf_cb[idx].handle; 1325 } else if (num_held > btif_hf_cb[idx].num_held) 1326 res = BTA_AG_IN_CALL_HELD_RES; 1327 else 1328 res = BTA_AG_CALL_CANCEL_RES; 1329 break; 1330 case BTHF_CALL_STATE_DIALING: 1331 case BTHF_CALL_STATE_ALERTING: 1332 if (num_active > btif_hf_cb[idx].num_active) { 1333 ag_res.audio_handle = BTA_AG_HANDLE_SCO_NO_CHANGE; 1334 res = BTA_AG_OUT_CALL_CONN_RES; 1335 } else 1336 res = BTA_AG_CALL_CANCEL_RES; 1337 break; 1338 default: 1339 BTIF_TRACE_ERROR("%s: Incorrect Call setup state transition", 1340 __func__); 1341 status = BT_STATUS_PARM_INVALID; 1342 break; 1343 } 1344 } break; 1345 1346 case BTHF_CALL_STATE_INCOMING: 1347 if (num_active || num_held) { 1348 res = BTA_AG_CALL_WAIT_RES; 1349 } else { 1350 res = BTA_AG_IN_CALL_RES; 1351 } 1352 if (number) { 1353 int xx = 0; 1354 if ((type == BTHF_CALL_ADDRTYPE_INTERNATIONAL) && (*number != '+')) 1355 xx = snprintf(ag_res.str, sizeof(ag_res.str), "\"+%s\"", number); 1356 else 1357 xx = snprintf(ag_res.str, sizeof(ag_res.str), "\"%s\"", number); 1358 ag_res.num = type; 1359 1360 if (res == BTA_AG_CALL_WAIT_RES) 1361 snprintf(&ag_res.str[xx], sizeof(ag_res.str) - xx, ",%d", type); 1362 } 1363 break; 1364 case BTHF_CALL_STATE_DIALING: 1365 if (!(num_active + num_held)) 1366 ag_res.audio_handle = btif_hf_cb[idx].handle; 1367 res = BTA_AG_OUT_CALL_ORIG_RES; 1368 break; 1369 case BTHF_CALL_STATE_ALERTING: 1370 /* if we went from idle->alert, force SCO setup here. dialing usually 1371 * triggers it */ 1372 if ((btif_hf_cb[idx].call_setup_state == BTHF_CALL_STATE_IDLE) && 1373 !(num_active + num_held)) 1374 ag_res.audio_handle = btif_hf_cb[idx].handle; 1375 res = BTA_AG_OUT_CALL_ALERT_RES; 1376 break; 1377 default: 1378 BTIF_TRACE_ERROR("%s: Incorrect new ringing call state", __func__); 1379 status = BT_STATUS_PARM_INVALID; 1380 break; 1381 } 1382 BTIF_TRACE_DEBUG("%s: Call setup state changed. res=%d, audio_handle=%d", 1383 __func__, res, ag_res.audio_handle); 1384 1385 if (res) BTA_AgResult(BTA_AG_HANDLE_ALL, res, &ag_res); 1386 1387 /* if call setup is idle, we have already updated call indicator, jump out 1388 */ 1389 if (call_setup_state == BTHF_CALL_STATE_IDLE) { 1390 /* check & update callheld */ 1391 if ((num_held > 0) && (num_active > 0)) 1392 send_indicator_update(BTA_AG_IND_CALLHELD, 1); 1393 goto update_call_states; 1394 } 1395 } 1396 1397 memset(&ag_res, 0, sizeof(tBTA_AG_RES_DATA)); 1398 1399 /* per the errata 2043, call=1 implies atleast one call is in progress 1400 *(active/held) 1401 ** https://www.bluetooth.org/errata/errata_view.cfm?errata_id=2043 1402 ** Handle call indicator change 1403 **/ 1404 if (!activeCallUpdated && 1405 ((num_active + num_held) != 1406 (btif_hf_cb[idx].num_active + btif_hf_cb[idx].num_held))) { 1407 BTIF_TRACE_DEBUG("%s: Active call states changed. old: %d new: %d", 1408 __func__, btif_hf_cb[idx].num_active, num_active); 1409 send_indicator_update(BTA_AG_IND_CALL, 1410 ((num_active + num_held) > 0) ? 1 : 0); 1411 } 1412 1413 /* Held Changed? */ 1414 if (num_held != btif_hf_cb[idx].num_held || 1415 ((num_active == 0) && ((num_held + btif_hf_cb[idx].num_held) > 1))) { 1416 BTIF_TRACE_DEBUG("%s: Held call states changed. old: %d new: %d", __func__, 1417 btif_hf_cb[idx].num_held, num_held); 1418 send_indicator_update(BTA_AG_IND_CALLHELD, 1419 ((num_held == 0) ? 0 : ((num_active == 0) ? 2 : 1))); 1420 } 1421 1422 /* Calls Swapped? */ 1423 if ((call_setup_state == btif_hf_cb[idx].call_setup_state) && 1424 (num_active && num_held) && (num_active == btif_hf_cb[idx].num_active) && 1425 (num_held == btif_hf_cb[idx].num_held)) { 1426 BTIF_TRACE_DEBUG("%s: Calls swapped", __func__); 1427 send_indicator_update(BTA_AG_IND_CALLHELD, 1); 1428 } 1429 1430update_call_states: 1431 for (i = 0; i < btif_max_hf_clients; i++) { 1432 if (btif_hf_cb[i].state == BTHF_CONNECTION_STATE_SLC_CONNECTED) { 1433 btif_hf_cb[i].num_active = num_active; 1434 btif_hf_cb[i].num_held = num_held; 1435 btif_hf_cb[i].call_setup_state = call_setup_state; 1436 } 1437 } 1438 return status; 1439} 1440 1441/******************************************************************************* 1442 * 1443 * Function btif_hf_is_call_idle 1444 * 1445 * Description returns true if no call is in progress 1446 * 1447 * Returns bt_status_t 1448 * 1449 ******************************************************************************/ 1450bool btif_hf_is_call_idle(void) { 1451 if (bt_hf_callbacks == NULL) return true; 1452 1453 for (int i = 0; i < btif_max_hf_clients; ++i) { 1454 if ((btif_hf_cb[i].call_setup_state != BTHF_CALL_STATE_IDLE) || 1455 ((btif_hf_cb[i].num_held + btif_hf_cb[i].num_active) > 0)) 1456 return false; 1457 } 1458 1459 return true; 1460} 1461 1462/******************************************************************************* 1463 * 1464 * Function btif_hf_call_terminated_recently 1465 * 1466 * Description Checks if a call has been terminated 1467 * 1468 * Returns bt_status_t 1469 * 1470 ******************************************************************************/ 1471bool btif_hf_call_terminated_recently() { 1472 struct timespec now; 1473 1474 clock_gettime(CLOCK_MONOTONIC, &now); 1475 if (now.tv_sec < 1476 btif_hf_cb[0].call_end_timestamp.tv_sec + BTIF_HF_CALL_END_TIMEOUT) { 1477 return true; 1478 } else { 1479 btif_hf_cb[0].call_end_timestamp.tv_sec = 0; 1480 return false; 1481 } 1482} 1483 1484/******************************************************************************* 1485 * 1486 * Function cleanup 1487 * 1488 * Description Closes the HF interface 1489 * 1490 * Returns bt_status_t 1491 * 1492 ******************************************************************************/ 1493static void cleanup(void) { 1494 BTIF_TRACE_EVENT("%s", __func__); 1495 1496 if (bt_hf_callbacks) { 1497#if (defined(BTIF_HF_SERVICES) && (BTIF_HF_SERVICES & BTA_HFP_SERVICE_MASK)) 1498 btif_disable_service(BTA_HFP_SERVICE_ID); 1499#else 1500 btif_disable_service(BTA_HSP_SERVICE_ID); 1501#endif 1502 bt_hf_callbacks = NULL; 1503 } 1504} 1505 1506/******************************************************************************* 1507 * 1508 * Function configure_wbs 1509 * 1510 * Description set to over-ride the current WBS configuration. 1511 * It will not send codec setting cmd to the controller now. 1512 * It just change the configure. 1513 * 1514 * Returns bt_status_t 1515 * 1516 ******************************************************************************/ 1517static bt_status_t configure_wbs(bt_bdaddr_t* bd_addr, 1518 bthf_wbs_config_t config) { 1519 CHECK_BTHF_INIT(); 1520 1521 int idx = btif_hf_idx_by_bdaddr(bd_addr); 1522 1523 if ((idx < 0) || (idx >= BTIF_HF_NUM_CB)) { 1524 BTIF_TRACE_ERROR("%s: Invalid index %d", __func__, idx); 1525 return BT_STATUS_FAIL; 1526 } 1527 1528 BTIF_TRACE_EVENT("%s config is %d", __func__, config); 1529 if (config == BTHF_WBS_YES) 1530 BTA_AgSetCodec(btif_hf_cb[idx].handle, BTA_AG_CODEC_MSBC); 1531 else if (config == BTHF_WBS_NO) 1532 BTA_AgSetCodec(btif_hf_cb[idx].handle, BTA_AG_CODEC_CVSD); 1533 else 1534 BTA_AgSetCodec(btif_hf_cb[idx].handle, BTA_AG_CODEC_NONE); 1535 1536 return BT_STATUS_SUCCESS; 1537} 1538 1539static const bthf_interface_t bthfInterface = { 1540 sizeof(bthfInterface), 1541 init, 1542 connect, 1543 disconnect, 1544 connect_audio, 1545 disconnect_audio, 1546 start_voice_recognition, 1547 stop_voice_recognition, 1548 volume_control, 1549 device_status_notification, 1550 cops_response, 1551 cind_response, 1552 formatted_at_response, 1553 at_response, 1554 clcc_response, 1555 phone_state_change, 1556 cleanup, 1557 configure_wbs, 1558 bind_response, 1559}; 1560 1561/******************************************************************************* 1562 * 1563 * Function btif_hf_execute_service 1564 * 1565 * Description Initializes/Shuts down the service 1566 * 1567 * Returns BT_STATUS_SUCCESS on success, BT_STATUS_FAIL otherwise 1568 * 1569 ******************************************************************************/ 1570bt_status_t btif_hf_execute_service(bool b_enable) { 1571 const char* p_service_names[] = BTIF_HF_SERVICE_NAMES; 1572 int i; 1573 if (b_enable) { 1574 /* Enable and register with BTA-AG */ 1575 BTA_AgEnable(BTA_AG_PARSE, bte_hf_evt); 1576 for (i = 0; i < btif_max_hf_clients; i++) { 1577 BTA_AgRegister(BTIF_HF_SERVICES, BTIF_HF_SECURITY, btif_hf_features, 1578 p_service_names, bthf_hf_id[i]); 1579 } 1580 } else { 1581 /* De-register AG */ 1582 for (i = 0; i < btif_max_hf_clients; i++) { 1583 BTA_AgDeregister(btif_hf_cb[i].handle); 1584 } 1585 /* Disable AG */ 1586 BTA_AgDisable(); 1587 } 1588 return BT_STATUS_SUCCESS; 1589} 1590 1591/******************************************************************************* 1592 * 1593 * Function btif_hf_get_interface 1594 * 1595 * Description Get the hf callback interface 1596 * 1597 * Returns bthf_interface_t 1598 * 1599 ******************************************************************************/ 1600const bthf_interface_t* btif_hf_get_interface() { 1601 BTIF_TRACE_EVENT("%s", __func__); 1602 return &bthfInterface; 1603} 1604