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