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