1 /******************************************************************************
3 * Copyright (C) 2009-2012 Broadcom Corporation
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:
9 * http://www.apache.org/licenses/LICENSE-2.0
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.
17 ******************************************************************************/
19 /************************************************************************************
23 * Description: Handsfree Profile Bluetooth Interface
26 ***********************************************************************************/
28 #define LOG_TAG "bt_btif_hf"
33 #include <cutils/properties.h>
35 #include <hardware/bluetooth.h>
36 #include <hardware/bt_hf.h>
38 #include "bta_ag_api.h"
39 #include "btcore/include/bdaddr.h"
40 #include "btif_common.h"
41 #include "btif_profile_queue.h"
42 #include "btif_util.h"
43 #include "device/include/controller.h"
45 /************************************************************************************
47 ************************************************************************************/
48 #ifndef BTIF_HSAG_SERVICE_NAME
49 #define BTIF_HSAG_SERVICE_NAME ("Headset Gateway")
52 #ifndef BTIF_HFAG_SERVICE_NAME
53 #define BTIF_HFAG_SERVICE_NAME ("Handsfree Gateway")
56 #ifndef BTIF_HF_SERVICES
57 #define BTIF_HF_SERVICES (BTA_HSP_SERVICE_MASK | BTA_HFP_SERVICE_MASK )
60 #ifndef BTIF_HF_SERVICE_NAMES
61 #define BTIF_HF_SERVICE_NAMES {BTIF_HSAG_SERVICE_NAME , BTIF_HFAG_SERVICE_NAME}
64 #ifndef BTIF_HF_SECURITY
65 #define BTIF_HF_SECURITY (BTA_SEC_AUTHENTICATE | BTA_SEC_ENCRYPT)
68 #ifndef BTIF_HF_FEATURES
69 #define BTIF_HF_FEATURES ( BTA_AG_FEAT_3WAY | \
71 BTA_AG_FEAT_REJECT | \
73 BTA_AG_FEAT_EXTERR | \
81 #define BTIF_HF_CALL_END_TIMEOUT 6
83 #define BTIF_HF_INVALID_IDX -1
85 /* Number of BTIF-HF control blocks */
86 #define BTIF_HF_NUM_CB 2
88 /* Assigned number for mSBC codec */
89 #define BTA_AG_MSBC_CODEC 5
91 /* Max HF clients supported from App */
92 UINT16 btif_max_hf_clients = 1;
94 /* HF app ids for service registration */
98 #if (BTIF_HF_NUM_CB == 3)
103 UINT16 bthf_hf_id[BTIF_HF_NUM_CB] = {BTIF_HF_ID_1, BTIF_HF_ID_2,
104 #if (BTIF_HF_NUM_CB == 3)
109 /************************************************************************************
110 ** Local type definitions
111 ************************************************************************************/
113 /************************************************************************************
115 ************************************************************************************/
116 static bthf_callbacks_t *bt_hf_callbacks = NULL;
117 static int hf_idx = BTIF_HF_INVALID_IDX;
118 static UINT32 btif_features = BTIF_HF_FEATURES;
120 #define CHECK_BTHF_INIT() if (bt_hf_callbacks == NULL)\
122 BTIF_TRACE_WARNING("BTHF: %s: BTHF not initialized", __FUNCTION__);\
123 return BT_STATUS_NOT_READY;\
127 BTIF_TRACE_IMP("BTHF: %s", __FUNCTION__);\
130 #define CHECK_BTHF_SLC_CONNECTED() if (bt_hf_callbacks == NULL)\
132 BTIF_TRACE_WARNING("BTHF: %s: BTHF not initialized", __FUNCTION__);\
133 return BT_STATUS_NOT_READY;\
135 else if (btif_hf_cb.state != BTHF_CONNECTION_STATE_SLC_CONNECTED)\
137 BTIF_TRACE_WARNING("BTHF: %s: SLC connection not up. state=%s", __FUNCTION__, dump_hf_conn_state(btif_hf_cb.state));\
138 return BT_STATUS_NOT_READY;\
142 BTIF_TRACE_EVENT("BTHF: %s", __FUNCTION__);\
145 /* BTIF-HF control block to map bdaddr to BTA handle */
146 typedef struct _btif_hf_cb
149 bt_bdaddr_t connected_bda;
150 bthf_connection_state_t state;
151 bthf_vr_state_t vr_state;
152 tBTA_AG_PEER_FEAT peer_feat;
155 struct timespec call_end_timestamp;
156 struct timespec connected_timestamp;
157 bthf_call_state_t call_setup_state;
160 static btif_hf_cb_t btif_hf_cb[BTIF_HF_NUM_CB];
162 /************************************************************************************
164 ************************************************************************************/
166 /************************************************************************************
168 ************************************************************************************/
169 /* By default, even though codec negotiation is enabled, we will not use WBS as the default
170 * codec unless this variable is set to TRUE.
172 #ifndef BTIF_HF_WBS_PREFERRED
173 #define BTIF_HF_WBS_PREFERRED TRUE
176 BOOLEAN btif_conf_hf_force_wbs = BTIF_HF_WBS_PREFERRED;
177 BOOLEAN send_bvra_other_index = FALSE;
178 int bvra_other_index_state = 0;
180 /************************************************************************************
182 ************************************************************************************/
184 /*******************************************************************************
186 ** Function is_connected
188 ** Description Internal function to check if HF is connected
190 ** Returns TRUE if connected
192 *******************************************************************************/
193 static BOOLEAN is_connected(bt_bdaddr_t *bd_addr)
196 for (i = 0; i < btif_max_hf_clients; ++i)
198 if (((btif_hf_cb[i].state == BTHF_CONNECTION_STATE_CONNECTED) ||
199 (btif_hf_cb[i].state == BTHF_CONNECTION_STATE_SLC_CONNECTED)) &&
200 ((bd_addr == NULL) || (bdcmp(bd_addr->address,
201 btif_hf_cb[i].connected_bda.address) == 0)))
207 /*******************************************************************************
209 ** Function btif_hf_is_connected_on_other_idx
211 ** Description Checks if any other AV SCB is connected
215 *******************************************************************************/
217 BOOLEAN btif_hf_is_connected_on_other_idx(int current_index)
220 for (i = 0; i < btif_max_hf_clients; i++)
222 if (i != current_index)
224 if ((btif_hf_cb[i].state == BTHF_CONNECTION_STATE_CONNECTED) ||
225 (btif_hf_cb[i].state == BTHF_CONNECTION_STATE_SLC_CONNECTED))
232 /*******************************************************************************
234 ** Function btif_hf_get_other_connected_index
236 ** Description Checks for other connected index
238 ** Returns Other connected index
240 *******************************************************************************/
242 int btif_hf_get_other_connected_index(int current_index)
245 for (i = 0; i < btif_max_hf_clients; i++)
247 if (i != current_index)
249 if ((btif_hf_cb[i].state == BTHF_CONNECTION_STATE_CONNECTED) ||
250 (btif_hf_cb[i].state == BTHF_CONNECTION_STATE_SLC_CONNECTED))
254 return btif_max_hf_clients;
256 /*******************************************************************************
258 ** Function send_bvra_update
260 ** Description Internal function to updated other connected HS for BVRA state
264 *******************************************************************************/
265 static void send_bvra_update(int index)
267 BTIF_TRACE_EVENT("connected %d",btif_hf_is_connected_on_other_idx(index));
268 if (btif_hf_is_connected_on_other_idx(index))
270 int other_idx = btif_hf_get_other_connected_index(index);
271 BTIF_TRACE_EVENT("other_idx %d",other_idx);
272 if (other_idx < btif_max_hf_clients &&
273 (btif_hf_cb[other_idx].peer_feat & BTA_AG_PEER_FEAT_VREC))
275 tBTA_AG_RES_DATA ag_res;
276 memset(&ag_res, 0, sizeof(ag_res));
277 ag_res.state = bvra_other_index_state;
278 BTIF_TRACE_EVENT("sending on idex %d",other_idx);
279 BTA_AgResult (btif_hf_cb[other_idx].handle,
280 BTA_AG_BVRA_RES, &ag_res);
284 BTIF_TRACE_EVENT("Invalid connected index");
289 /*******************************************************************************
291 ** Function btif_hf_idx_by_bdaddr
293 ** Description Internal function to get idx by bdaddr
297 *******************************************************************************/
298 static int btif_hf_idx_by_bdaddr(bt_bdaddr_t *bd_addr)
301 for (i = 0; i < btif_max_hf_clients; ++i)
303 if (is_connected(bd_addr) && (bdcmp(bd_addr->address,
304 btif_hf_cb[i].connected_bda.address) == 0))
307 return BTIF_HF_INVALID_IDX;
310 /*******************************************************************************
312 ** Function callstate_to_callsetup
314 ** Description Converts HAL call state to BTA call setup indicator value
316 ** Returns BTA call indicator value
318 *******************************************************************************/
319 static UINT8 callstate_to_callsetup(bthf_call_state_t call_state)
321 UINT8 call_setup = 0;
322 if (call_state == BTHF_CALL_STATE_INCOMING)
324 if (call_state == BTHF_CALL_STATE_DIALING)
326 if (call_state == BTHF_CALL_STATE_ALERTING)
332 /*******************************************************************************
334 ** Function send_at_result
336 ** Description Send AT result code (OK/ERROR)
340 *******************************************************************************/
341 static void send_at_result(UINT8 ok_flag, UINT16 errcode, int idx)
343 tBTA_AG_RES_DATA ag_res;
344 memset (&ag_res, 0, sizeof (ag_res));
346 ag_res.ok_flag = ok_flag;
347 if (ok_flag == BTA_AG_OK_ERROR)
349 ag_res.errcode = errcode;
352 BTA_AgResult (btif_hf_cb[idx].handle, BTA_AG_UNAT_RES, &ag_res);
355 /*******************************************************************************
357 ** Function send_indicator_update
359 ** Description Send indicator update (CIEV)
363 *******************************************************************************/
364 static void send_indicator_update (UINT16 indicator, UINT16 value)
366 tBTA_AG_RES_DATA ag_res;
368 memset(&ag_res, 0, sizeof(tBTA_AG_RES_DATA));
369 ag_res.ind.id = indicator;
370 ag_res.ind.value = value;
372 BTA_AgResult(BTA_AG_HANDLE_ALL, BTA_AG_IND_RES, &ag_res);
375 void clear_phone_state_multihf(int idx)
377 btif_hf_cb[idx].call_setup_state = BTHF_CALL_STATE_IDLE;
378 btif_hf_cb[idx].num_active = btif_hf_cb[idx].num_held = 0;
381 /*******************************************************************************
383 ** Function btif_hf_latest_connected_idx
385 ** Description Returns idx for latest connected HF
389 *******************************************************************************/
390 static int btif_hf_latest_connected_idx()
392 struct timespec now, conn_time_delta;
393 int latest_conn_idx = BTIF_HF_INVALID_IDX, i;
395 clock_gettime(CLOCK_MONOTONIC, &now);
396 conn_time_delta.tv_sec = now.tv_sec;
398 for (i = 0; i < btif_max_hf_clients; i++)
400 if (btif_hf_cb[i].state == BTHF_CONNECTION_STATE_SLC_CONNECTED)
402 if ((now.tv_sec - btif_hf_cb[i].connected_timestamp.tv_sec)
403 < conn_time_delta.tv_sec)
405 conn_time_delta.tv_sec =
406 now.tv_sec - btif_hf_cb[i].connected_timestamp.tv_sec;
411 return latest_conn_idx;
414 /*******************************************************************************
416 ** Function btif_hf_check_if_slc_connected
418 ** Description Returns BT_STATUS_SUCCESS if SLC is up for any HF
420 ** Returns bt_status_t
422 *******************************************************************************/
423 static bt_status_t btif_hf_check_if_slc_connected()
425 if (bt_hf_callbacks == NULL)
427 BTIF_TRACE_WARNING("BTHF: %s: BTHF not initialized", __FUNCTION__);
428 return BT_STATUS_NOT_READY;
433 for (i = 0; i < btif_max_hf_clients; i++)
435 if (btif_hf_cb[i].state == BTHF_CONNECTION_STATE_SLC_CONNECTED)
437 BTIF_TRACE_EVENT("BTHF: %s: slc connected for idx = %d",
439 return BT_STATUS_SUCCESS;
442 BTIF_TRACE_WARNING("BTHF: %s: No SLC connection up", __FUNCTION__);
443 return BT_STATUS_NOT_READY;
447 /*****************************************************************************
448 ** Section name (Group of functions)
449 *****************************************************************************/
451 /*****************************************************************************
453 ** btif hf api functions (no context switch)
455 *****************************************************************************/
457 /*******************************************************************************
459 ** Function btif_hf_upstreams_evt
461 ** Description Executes HF UPSTREAMS events in btif context
465 *******************************************************************************/
466 static void btif_hf_upstreams_evt(UINT16 event, char* p_param)
468 tBTA_AG *p_data = (tBTA_AG *)p_param;
470 int idx = p_data->hdr.handle - 1;
471 BOOLEAN ignore_rfc_fail = false;
473 BTIF_TRACE_IMP("%s: event=%s", __FUNCTION__, dump_hf_event(event));
475 if ((idx < 0) || (idx >= BTIF_HF_NUM_CB))
477 BTIF_TRACE_ERROR("%s: Invalid index %d", __FUNCTION__, idx);
483 case BTA_AG_ENABLE_EVT:
484 case BTA_AG_DISABLE_EVT:
487 case BTA_AG_REGISTER_EVT:
488 btif_hf_cb[idx].handle = p_data->reg.hdr.handle;
489 BTIF_TRACE_DEBUG("%s: BTA_AG_REGISTER_EVT,"
490 "btif_hf_cb.handle = %d", __FUNCTION__, btif_hf_cb[idx].handle);
493 case BTA_AG_OPEN_EVT:
494 if (p_data->open.status == BTA_AG_SUCCESS)
496 bdcpy(btif_hf_cb[idx].connected_bda.address,
497 p_data->open.bd_addr);
498 btif_hf_cb[idx].state = BTHF_CONNECTION_STATE_CONNECTED;
499 btif_hf_cb[idx].peer_feat = 0;
500 clear_phone_state_multihf(idx);
502 else if (btif_hf_cb[idx].state == BTHF_CONNECTION_STATE_CONNECTING)
504 /* In Multi-hf, if outgoing RFCOMM connection fails due to collision,
505 * ignore the failure if HF is already connected.
507 if ( (btif_max_hf_clients > 1) &&
508 (p_data->open.status == BTA_AG_FAIL_RFCOMM) &&
509 (is_connected(&btif_hf_cb[idx].connected_bda)) )
511 BTIF_TRACE_WARNING("%s: Ignoring RFCOMM failure due to collision for dev %s",
512 __FUNCTION__, bdaddr_to_string(&btif_hf_cb[idx].connected_bda, bdstr, sizeof(bdstr)));
513 ignore_rfc_fail = true;
516 btif_hf_cb[idx].state = BTHF_CONNECTION_STATE_DISCONNECTED;
520 BTIF_TRACE_WARNING("%s: AG open failed, but another device connected. status=%d state=%d connected device=%s",
521 __FUNCTION__, p_data->open.status, btif_hf_cb[idx].state,
522 bdaddr_to_string(&btif_hf_cb[idx].connected_bda, bdstr, sizeof(bdstr)));
526 if (ignore_rfc_fail != true)
528 HAL_CBACK(bt_hf_callbacks, connection_state_cb, btif_hf_cb[idx].state,
529 &btif_hf_cb[idx].connected_bda);
532 if (btif_hf_cb[idx].state == BTHF_CONNECTION_STATE_DISCONNECTED)
533 bdsetany(btif_hf_cb[idx].connected_bda.address);
535 btif_queue_advance();
539 case BTA_AG_CLOSE_EVT:
540 btif_hf_cb[idx].connected_timestamp.tv_sec = 0;
541 btif_hf_cb[idx].state = BTHF_CONNECTION_STATE_DISCONNECTED;
542 BTIF_TRACE_DEBUG("%s: BTA_AG_CLOSE_EVT,"
543 "idx = %d, btif_hf_cb.handle = %d", __FUNCTION__, idx,
544 btif_hf_cb[idx].handle);
545 HAL_CBACK(bt_hf_callbacks, connection_state_cb, btif_hf_cb[idx].state,
546 &btif_hf_cb[idx].connected_bda);
547 bdsetany(btif_hf_cb[idx].connected_bda.address);
548 btif_hf_cb[idx].peer_feat = 0;
549 clear_phone_state_multihf(idx);
550 hf_idx = btif_hf_latest_connected_idx();
551 /* If AG_OPEN was received but SLC was not setup in a specified time (10 seconds),
552 ** then AG_CLOSE may be received. We need to advance the queue here
554 btif_queue_advance();
557 case BTA_AG_CONN_EVT:
558 clock_gettime(CLOCK_MONOTONIC,
559 &btif_hf_cb[idx].connected_timestamp);
560 BTIF_TRACE_DEBUG("%s: BTA_AG_CONN_EVT, idx = %d ",
562 btif_hf_cb[idx].peer_feat = p_data->conn.peer_feat;
563 btif_hf_cb[idx].state = BTHF_CONNECTION_STATE_SLC_CONNECTED;
564 hf_idx = btif_hf_latest_connected_idx();
566 HAL_CBACK(bt_hf_callbacks, connection_state_cb, btif_hf_cb[idx].state,
567 &btif_hf_cb[idx].connected_bda);
570 case BTA_AG_AUDIO_OPEN_EVT:
572 HAL_CBACK(bt_hf_callbacks, audio_state_cb, BTHF_AUDIO_STATE_CONNECTED,
573 &btif_hf_cb[idx].connected_bda);
576 case BTA_AG_AUDIO_CLOSE_EVT:
577 HAL_CBACK(bt_hf_callbacks, audio_state_cb, BTHF_AUDIO_STATE_DISCONNECTED,
578 &btif_hf_cb[idx].connected_bda);
581 /* BTA auto-responds, silently discard */
584 HAL_CBACK(bt_hf_callbacks, volume_cmd_cb,
585 (event == BTA_AG_SPK_EVT) ? BTHF_VOLUME_TYPE_SPK :
586 BTHF_VOLUME_TYPE_MIC, p_data->val.num,
587 &btif_hf_cb[idx].connected_bda);
590 case BTA_AG_AT_A_EVT:
591 if ((btif_hf_cb[0].num_held + btif_hf_cb[0].num_active) == 0)
594 BTIF_TRACE_DEBUG("Donot set hf_idx for ATA since already in a call");
596 HAL_CBACK(bt_hf_callbacks, answer_call_cmd_cb,
597 &btif_hf_cb[idx].connected_bda);
600 /* Java needs to send OK/ERROR for these commands */
601 case BTA_AG_AT_BLDN_EVT:
602 case BTA_AG_AT_D_EVT:
603 if ((btif_hf_cb[0].num_held + btif_hf_cb[0].num_active) == 0)
606 BTIF_TRACE_DEBUG("Donot set hf_idx for BLDN/D since already in a call");
608 HAL_CBACK(bt_hf_callbacks, dial_call_cmd_cb,
609 (event == BTA_AG_AT_D_EVT) ? p_data->val.str : NULL,
610 &btif_hf_cb[idx].connected_bda);
613 case BTA_AG_AT_CHUP_EVT:
614 HAL_CBACK(bt_hf_callbacks, hangup_call_cmd_cb,
615 &btif_hf_cb[idx].connected_bda);
618 case BTA_AG_AT_CIND_EVT:
619 HAL_CBACK(bt_hf_callbacks, cind_cmd_cb,
620 &btif_hf_cb[idx].connected_bda);
623 case BTA_AG_AT_VTS_EVT:
624 HAL_CBACK(bt_hf_callbacks, dtmf_cmd_cb, p_data->val.str[0],
625 &btif_hf_cb[idx].connected_bda);
628 case BTA_AG_AT_BVRA_EVT:
629 HAL_CBACK(bt_hf_callbacks, vr_cmd_cb,
630 (p_data->val.num == 1) ? BTHF_VR_STATE_STARTED :
631 BTHF_VR_STATE_STOPPED, &btif_hf_cb[idx].connected_bda);
632 send_bvra_other_index = TRUE;
633 bvra_other_index_state = p_data->val.num;
637 case BTA_AG_AT_NREC_EVT:
638 HAL_CBACK(bt_hf_callbacks, nrec_cmd_cb,
639 (p_data->val.num == 1) ? BTHF_NREC_START : BTHF_NREC_STOP,
640 &btif_hf_cb[idx].connected_bda);
643 /* TODO: Add a callback for CBC */
644 case BTA_AG_AT_CBC_EVT:
647 case BTA_AG_AT_CKPD_EVT:
648 HAL_CBACK(bt_hf_callbacks, key_pressed_cmd_cb,
649 &btif_hf_cb[idx].connected_bda);
652 #if (BTM_WBS_INCLUDED == TRUE )
654 BTIF_TRACE_DEBUG("BTA_AG_WBS_EVT Set codec status %d codec %d 1=CVSD 2=MSBC", \
655 p_data->val.hdr.status, p_data->val.num);
656 if(p_data->val.num == BTA_AG_CODEC_CVSD)
657 { HAL_CBACK(bt_hf_callbacks, wbs_cb, BTHF_WBS_NO, &btif_hf_cb[idx].connected_bda);}
658 else if(p_data->val.num == BTA_AG_CODEC_MSBC)
659 {HAL_CBACK(bt_hf_callbacks, wbs_cb, BTHF_WBS_YES, &btif_hf_cb[idx].connected_bda);}
661 {HAL_CBACK(bt_hf_callbacks, wbs_cb, BTHF_WBS_NONE, &btif_hf_cb[idx].connected_bda);}
664 /* Java needs to send OK/ERROR for these commands */
665 case BTA_AG_AT_CHLD_EVT:
666 HAL_CBACK(bt_hf_callbacks, chld_cmd_cb, atoi(p_data->val.str),
667 &btif_hf_cb[idx].connected_bda);
670 case BTA_AG_AT_CLCC_EVT:
671 HAL_CBACK(bt_hf_callbacks, clcc_cmd_cb,
672 &btif_hf_cb[idx].connected_bda);
675 case BTA_AG_AT_COPS_EVT:
676 HAL_CBACK(bt_hf_callbacks, cops_cmd_cb,
677 &btif_hf_cb[idx].connected_bda);
680 case BTA_AG_AT_UNAT_EVT:
681 HAL_CBACK(bt_hf_callbacks, unknown_at_cmd_cb, p_data->val.str,
682 &btif_hf_cb[idx].connected_bda);
685 case BTA_AG_AT_CNUM_EVT:
686 HAL_CBACK(bt_hf_callbacks, cnum_cmd_cb,
687 &btif_hf_cb[idx].connected_bda);
690 /* TODO: Some of these commands may need to be sent to app. For now respond with error */
691 case BTA_AG_AT_BINP_EVT:
692 case BTA_AG_AT_BTRH_EVT:
693 send_at_result(BTA_AG_OK_ERROR, BTA_AG_ERR_OP_NOT_SUPPORTED, idx);
695 case BTA_AG_AT_BAC_EVT:
696 BTIF_TRACE_DEBUG("AG Bitmap of peer-codecs %d", p_data->val.num);
697 #if (BTM_WBS_INCLUDED == TRUE )
698 /* If the peer supports mSBC and the BTIF prefferred codec is also mSBC, then
699 we should set the BTA AG Codec to mSBC. This would trigger a +BCS to mSBC at the time
700 of SCO connection establishment */
701 if ((btif_conf_hf_force_wbs == TRUE) && (p_data->val.num & BTA_AG_CODEC_MSBC))
703 BTIF_TRACE_EVENT("%s btif_hf override-Preferred Codec to MSBC", __FUNCTION__);
704 BTA_AgSetCodec(btif_hf_cb[idx].handle,BTA_AG_CODEC_MSBC);
708 BTIF_TRACE_EVENT("%s btif_hf override-Preferred Codec to CVSD", __FUNCTION__);
709 BTA_AgSetCodec(btif_hf_cb[idx].handle,BTA_AG_CODEC_CVSD);
713 case BTA_AG_AT_BCS_EVT:
714 BTIF_TRACE_DEBUG("AG final seleded codec is %d 1=CVSD 2=MSBC", p_data->val.num);
715 /* no BTHF_WBS_NONE case, becuase HF1.6 supported device can send BCS */
716 HAL_CBACK(bt_hf_callbacks, wbs_cb,(p_data->val.num == BTA_AG_CODEC_MSBC) ? \
717 BTHF_WBS_YES : BTHF_WBS_NO, &btif_hf_cb[idx].connected_bda);
720 case BTA_AG_AT_BIND_EVT:
721 switch(p_data->val.num)
724 HAL_CBACK(bt_hf_callbacks, bind_cmd_cb, p_data->val.str, BTHF_BIND_SET,
725 &btif_hf_cb[idx].connected_bda);
728 HAL_CBACK(bt_hf_callbacks, bind_cmd_cb, p_data->val.str, BTHF_BIND_READ,
729 &btif_hf_cb[idx].connected_bda);
732 HAL_CBACK(bt_hf_callbacks, bind_cmd_cb, p_data->val.str, BTHF_BIND_TEST,
733 &btif_hf_cb[idx].connected_bda);
737 case BTA_AG_AT_BIEV_EVT:
738 HAL_CBACK(bt_hf_callbacks, biev_cmd_cb, p_data->val.str,
739 &btif_hf_cb[idx].connected_bda);
743 BTIF_TRACE_WARNING("%s: Unhandled event: %d", __FUNCTION__, event);
748 /*******************************************************************************
750 ** Function bte_hf_evt
752 ** Description Switches context from BTE to BTIF for all HF events
756 *******************************************************************************/
758 static void bte_hf_evt(tBTA_AG_EVT event, tBTA_AG *p_data)
763 /* TODO: BTA sends the union members and not tBTA_AG. If using param_len=sizeof(tBTA_AG), we get a crash on memcpy */
764 if (BTA_AG_REGISTER_EVT == event)
765 param_len = sizeof(tBTA_AG_REGISTER);
766 else if (BTA_AG_OPEN_EVT == event)
767 param_len = sizeof(tBTA_AG_OPEN);
768 else if (BTA_AG_CONN_EVT == event)
769 param_len = sizeof(tBTA_AG_CONN);
770 else if ( (BTA_AG_CLOSE_EVT == event) || (BTA_AG_AUDIO_OPEN_EVT == event) || (BTA_AG_AUDIO_CLOSE_EVT == event))
771 param_len = sizeof(tBTA_AG_HDR);
773 param_len = sizeof(tBTA_AG_VAL);
775 /* switch context to btif task context (copy full union size for convenience) */
776 status = btif_transfer_context(btif_hf_upstreams_evt, (uint16_t)event, (void*)p_data, param_len, NULL);
778 /* catch any failed context transfers */
779 ASSERTC(status == BT_STATUS_SUCCESS, "context transfer failed", status);
782 /*******************************************************************************
784 ** Function btif_in_hf_generic_evt
786 ** Description Processes generic events to be sent to JNI that are not triggered from the BTA.
787 ** Always runs in BTIF context
791 *******************************************************************************/
792 static void btif_in_hf_generic_evt(UINT16 event, char *p_param)
794 int idx = btif_hf_idx_by_bdaddr((bt_bdaddr_t *)p_param);
796 BTIF_TRACE_EVENT("%s: event=%d", __FUNCTION__, event);
798 if ((idx < 0) || (idx >= BTIF_HF_NUM_CB))
800 BTIF_TRACE_ERROR("%s: Invalid index %d", __FUNCTION__, idx);
805 case BTIF_HFP_CB_AUDIO_CONNECTING:
807 HAL_CBACK(bt_hf_callbacks, audio_state_cb, BTHF_AUDIO_STATE_CONNECTING,
808 &btif_hf_cb[idx].connected_bda);
812 BTIF_TRACE_WARNING("%s : Unknown event 0x%x", __FUNCTION__, event);
818 /*******************************************************************************
820 ** Function btif_hf_init
822 ** Description initializes the hf interface
824 ** Returns bt_status_t
826 *******************************************************************************/
827 static bt_status_t init( bthf_callbacks_t* callbacks, int max_hf_clients)
829 btif_max_hf_clients = max_hf_clients;
830 BTIF_TRACE_DEBUG("%s - max_hf_clients=%d", __func__, btif_max_hf_clients);
832 bt_hf_callbacks = callbacks;
833 memset(&btif_hf_cb, 0, sizeof(btif_hf_cb));
835 /* Invoke the enable service API to the core to set the appropriate service_id
836 * Internally, the HSP_SERVICE_ID shall also be enabled if HFP is enabled (phone)
837 * othwerwise only HSP is enabled (tablet)
839 #if (defined(BTIF_HF_SERVICES) && (BTIF_HF_SERVICES & BTA_HFP_SERVICE_MASK))
840 btif_enable_service(BTA_HFP_SERVICE_ID);
842 btif_enable_service(BTA_HSP_SERVICE_ID);
845 for (int i = 0; i < btif_max_hf_clients; i++)
846 clear_phone_state_multihf(i);
848 return BT_STATUS_SUCCESS;
851 /*******************************************************************************
855 ** Description connect to headset
857 ** Returns bt_status_t
859 *******************************************************************************/
860 static bt_status_t connect_int(bt_bdaddr_t *bd_addr, uint16_t uuid)
864 for (i = 0; i < btif_max_hf_clients;)
866 if (((btif_hf_cb[i].state == BTHF_CONNECTION_STATE_CONNECTED) ||
867 (btif_hf_cb[i].state == BTHF_CONNECTION_STATE_SLC_CONNECTED)))
873 if (i == btif_max_hf_clients)
874 return BT_STATUS_BUSY;
876 if (!is_connected(bd_addr))
878 btif_hf_cb[i].state = BTHF_CONNECTION_STATE_CONNECTING;
879 bdcpy(btif_hf_cb[i].connected_bda.address, bd_addr->address);
881 BTA_AgOpen(btif_hf_cb[i].handle, btif_hf_cb[i].connected_bda.address,
882 BTIF_HF_SECURITY, BTIF_HF_SERVICES);
883 return BT_STATUS_SUCCESS;
886 return BT_STATUS_BUSY;
889 static bt_status_t connect( bt_bdaddr_t *bd_addr )
892 return btif_queue_connect(UUID_SERVCLASS_AG_HANDSFREE, bd_addr, connect_int);
895 /*******************************************************************************
897 ** Function disconnect
899 ** Description disconnect from headset
901 ** Returns bt_status_t
903 *******************************************************************************/
904 static bt_status_t disconnect( bt_bdaddr_t *bd_addr )
908 int idx = btif_hf_idx_by_bdaddr(bd_addr);
910 if ((idx < 0) || (idx >= BTIF_HF_NUM_CB))
912 BTIF_TRACE_ERROR("%s: Invalid index %d", __FUNCTION__, idx);
913 return BT_STATUS_FAIL;
916 if (idx != BTIF_HF_INVALID_IDX)
918 BTA_AgClose(btif_hf_cb[idx].handle);
919 return BT_STATUS_SUCCESS;
922 return BT_STATUS_FAIL;
925 /*******************************************************************************
927 ** Function connect_audio
929 ** Description create an audio connection
931 ** Returns bt_status_t
933 *******************************************************************************/
934 static bt_status_t connect_audio( bt_bdaddr_t *bd_addr )
938 int idx = btif_hf_idx_by_bdaddr(bd_addr);
940 if ((idx < 0) || (idx >= BTIF_HF_NUM_CB))
942 BTIF_TRACE_ERROR("%s: Invalid index %d", __FUNCTION__, idx);
943 return BT_STATUS_FAIL;
946 /* Check if SLC is connected */
947 if (btif_hf_check_if_slc_connected() != BT_STATUS_SUCCESS)
948 return BT_STATUS_NOT_READY;
950 if (idx != BTIF_HF_INVALID_IDX)
952 BTA_AgAudioOpen(btif_hf_cb[idx].handle);
954 /* Inform the application that the audio connection has been initiated successfully */
955 btif_transfer_context(btif_in_hf_generic_evt, BTIF_HFP_CB_AUDIO_CONNECTING,
956 (char *)bd_addr, sizeof(bt_bdaddr_t), NULL);
957 return BT_STATUS_SUCCESS;
960 return BT_STATUS_FAIL;
963 /*******************************************************************************
965 ** Function disconnect_audio
967 ** Description close the audio connection
969 ** Returns bt_status_t
971 *******************************************************************************/
972 static bt_status_t disconnect_audio( bt_bdaddr_t *bd_addr )
976 int idx = btif_hf_idx_by_bdaddr(bd_addr);
978 if ((idx < 0) || (idx >= BTIF_HF_NUM_CB))
980 BTIF_TRACE_ERROR("%s: Invalid index %d", __FUNCTION__, idx);
981 return BT_STATUS_FAIL;
984 if (idx != BTIF_HF_INVALID_IDX)
986 BTA_AgAudioClose(btif_hf_cb[idx].handle);
987 return BT_STATUS_SUCCESS;
990 return BT_STATUS_FAIL;
993 /*******************************************************************************
995 ** Function start_voice_recognition
997 ** Description start voice recognition
999 ** Returns bt_status_t
1001 *******************************************************************************/
1002 static bt_status_t start_voice_recognition(bt_bdaddr_t *bd_addr)
1005 BOOLEAN is_success = FALSE;
1006 for (int i = 0; i < btif_max_hf_clients; i++)
1008 if (((btif_hf_cb[i].state == BTHF_CONNECTION_STATE_CONNECTED) ||
1009 (btif_hf_cb[i].state == BTHF_CONNECTION_STATE_SLC_CONNECTED)) &&
1010 btif_hf_cb[i].peer_feat & BTA_AG_PEER_FEAT_VREC)
1012 tBTA_AG_RES_DATA ag_res;
1013 memset(&ag_res, 0, sizeof(ag_res));
1015 BTA_AgResult (btif_hf_cb[i].handle, BTA_AG_BVRA_RES, &ag_res);
1022 return BT_STATUS_SUCCESS;
1026 return BT_STATUS_NOT_READY;
1030 /*******************************************************************************
1032 ** Function stop_voice_recognition
1034 ** Description stop voice recognition
1036 ** Returns bt_status_t
1038 *******************************************************************************/
1039 static bt_status_t stop_voice_recognition(bt_bdaddr_t *bd_addr)
1042 BOOLEAN is_success = FALSE;
1043 for (int i = 0; i < btif_max_hf_clients; i++)
1045 if (((btif_hf_cb[i].state == BTHF_CONNECTION_STATE_CONNECTED) ||
1046 (btif_hf_cb[i].state == BTHF_CONNECTION_STATE_SLC_CONNECTED)) &&
1047 btif_hf_cb[i].peer_feat & BTA_AG_PEER_FEAT_VREC)
1049 tBTA_AG_RES_DATA ag_res;
1050 memset(&ag_res, 0, sizeof(ag_res));
1052 BTA_AgResult (btif_hf_cb[i].handle, BTA_AG_BVRA_RES, &ag_res);
1059 return BT_STATUS_SUCCESS;
1063 return BT_STATUS_NOT_READY;
1067 /*******************************************************************************
1069 ** Function volume_control
1071 ** Description volume control
1073 ** Returns bt_status_t
1075 *******************************************************************************/
1076 static bt_status_t volume_control(bthf_volume_type_t type, int volume,
1077 bt_bdaddr_t *bd_addr)
1081 int idx = btif_hf_idx_by_bdaddr(bd_addr);
1083 if ((idx < 0) || (idx >= BTIF_HF_NUM_CB))
1085 BTIF_TRACE_ERROR("%s: Invalid index %d", __FUNCTION__, idx);
1086 return BT_STATUS_FAIL;
1089 tBTA_AG_RES_DATA ag_res;
1090 memset(&ag_res, 0, sizeof(tBTA_AG_RES_DATA));
1091 if (idx != BTIF_HF_INVALID_IDX)
1093 ag_res.num = volume;
1094 BTA_AgResult(btif_hf_cb[idx].handle,
1095 (type == BTHF_VOLUME_TYPE_SPK) ? BTA_AG_SPK_RES : BTA_AG_MIC_RES,
1097 return BT_STATUS_SUCCESS;
1100 return BT_STATUS_FAIL;
1103 /*******************************************************************************
1105 ** Function device_status_notification
1107 ** Description Combined device status change notification
1109 ** Returns bt_status_t
1111 *******************************************************************************/
1112 static bt_status_t device_status_notification(bthf_network_state_t ntk_state,
1113 bthf_service_type_t svc_type, int signal, int batt_chg)
1117 if (is_connected(NULL))
1119 /* send all indicators to BTA.
1120 ** BTA will make sure no duplicates are sent out
1122 send_indicator_update(BTA_AG_IND_SERVICE,
1123 (ntk_state == BTHF_NETWORK_STATE_AVAILABLE) ? 1 : 0);
1124 send_indicator_update(BTA_AG_IND_ROAM,
1125 (svc_type == BTHF_SERVICE_TYPE_HOME) ? 0 : 1);
1126 send_indicator_update(BTA_AG_IND_SIGNAL, signal);
1127 send_indicator_update(BTA_AG_IND_BATTCHG, batt_chg);
1128 return BT_STATUS_SUCCESS;
1131 return BT_STATUS_SUCCESS;
1134 /*******************************************************************************
1136 ** Function cops_response
1138 ** Description Response for COPS command
1140 ** Returns bt_status_t
1142 *******************************************************************************/
1143 static bt_status_t cops_response(const char *cops, bt_bdaddr_t *bd_addr)
1147 int idx = btif_hf_idx_by_bdaddr(bd_addr);
1149 if ((idx < 0) || (idx >= BTIF_HF_NUM_CB))
1151 BTIF_TRACE_ERROR("%s: Invalid index %d", __FUNCTION__, idx);
1152 return BT_STATUS_FAIL;
1155 if (idx != BTIF_HF_INVALID_IDX)
1157 tBTA_AG_RES_DATA ag_res;
1159 /* Format the response */
1160 sprintf (ag_res.str, "0,0,\"%.16s\"", cops);
1161 ag_res.ok_flag = BTA_AG_OK_DONE;
1163 BTA_AgResult (btif_hf_cb[idx].handle, BTA_AG_COPS_RES, &ag_res);
1164 return BT_STATUS_SUCCESS;
1166 return BT_STATUS_FAIL;
1169 /*******************************************************************************
1171 ** Function cind_response
1173 ** Description Response for CIND command
1175 ** Returns bt_status_t
1177 *******************************************************************************/
1178 static bt_status_t cind_response(int svc, int num_active, int num_held,
1179 bthf_call_state_t call_setup_state,
1180 int signal, int roam, int batt_chg,
1181 bt_bdaddr_t *bd_addr)
1185 int idx = btif_hf_idx_by_bdaddr(bd_addr);
1187 if ((idx < 0) || (idx >= BTIF_HF_NUM_CB))
1189 BTIF_TRACE_ERROR("%s: Invalid index %d", __FUNCTION__, idx);
1190 return BT_STATUS_FAIL;
1193 if (idx != BTIF_HF_INVALID_IDX)
1195 tBTA_AG_RES_DATA ag_res;
1197 memset (&ag_res, 0, sizeof (ag_res));
1198 /* per the errata 2043, call=1 implies atleast one call is in progress (active/held)
1199 ** https://www.bluetooth.org/errata/errata_view.cfm?errata_id=2043
1201 sprintf (ag_res.str, "%d,%d,%d,%d,%d,%d,%d",
1202 (num_active + num_held) ? 1 : 0, /* Call state */
1203 callstate_to_callsetup(call_setup_state), /* Callsetup state */
1204 svc, /* network service */
1205 signal, /* Signal strength */
1206 roam, /* Roaming indicator */
1207 batt_chg, /* Battery level */
1208 ((num_held == 0) ? 0 : ((num_active == 0) ? 2 : 1))); /* Call held */
1210 BTA_AgResult (btif_hf_cb[idx].handle, BTA_AG_CIND_RES, &ag_res);
1212 return BT_STATUS_SUCCESS;
1215 return BT_STATUS_FAIL;
1218 /*******************************************************************************
1220 ** Function formatted_at_response
1222 ** Description Pre-formatted AT response, typically in response to unknown AT cmd
1224 ** Returns bt_status_t
1226 *******************************************************************************/
1227 static bt_status_t formatted_at_response(const char *rsp, bt_bdaddr_t *bd_addr)
1230 tBTA_AG_RES_DATA ag_res;
1231 int idx = btif_hf_idx_by_bdaddr(bd_addr);
1233 if ((idx < 0) || (idx >= BTIF_HF_NUM_CB))
1235 BTIF_TRACE_ERROR("%s: Invalid index %d", __FUNCTION__, idx);
1236 return BT_STATUS_FAIL;
1239 if (idx != BTIF_HF_INVALID_IDX)
1241 /* Format the response and send */
1242 memset (&ag_res, 0, sizeof (ag_res));
1243 strncpy(ag_res.str, rsp, BTA_AG_AT_MAX_LEN);
1244 BTA_AgResult (btif_hf_cb[idx].handle, BTA_AG_UNAT_RES, &ag_res);
1246 return BT_STATUS_SUCCESS;
1249 return BT_STATUS_FAIL;
1252 /*******************************************************************************
1254 ** Function at_response
1256 ** Description ok/error response
1258 ** Returns bt_status_t
1260 *******************************************************************************/
1261 static bt_status_t at_response(bthf_at_response_t response_code,
1262 int error_code, bt_bdaddr_t *bd_addr)
1266 int idx = btif_hf_idx_by_bdaddr(bd_addr);
1268 if ((idx < 0) || (idx >= BTIF_HF_NUM_CB))
1270 BTIF_TRACE_ERROR("%s: Invalid index %d", __FUNCTION__, idx);
1271 return BT_STATUS_FAIL;
1274 if (idx != BTIF_HF_INVALID_IDX)
1276 send_at_result((response_code == BTHF_AT_RESPONSE_OK) ? BTA_AG_OK_DONE
1277 : BTA_AG_OK_ERROR, error_code, idx);
1278 if (response_code == BTHF_AT_RESPONSE_OK && send_bvra_other_index)
1280 send_bvra_update(idx);
1281 send_bvra_other_index = FALSE;
1283 return BT_STATUS_SUCCESS;
1286 return BT_STATUS_FAIL;
1289 /*******************************************************************************
1291 ** Function clcc_response
1293 ** Description response for CLCC command
1294 ** Can be iteratively called for each call index. Call index
1295 ** of 0 will be treated as NULL termination (Completes response)
1297 ** Returns bt_status_t
1299 *******************************************************************************/
1300 static bt_status_t clcc_response(int index, bthf_call_direction_t dir,
1301 bthf_call_state_t state, bthf_call_mode_t mode,
1302 bthf_call_mpty_type_t mpty, const char *number,
1303 bthf_call_addrtype_t type, bt_bdaddr_t *bd_addr)
1307 int idx = btif_hf_idx_by_bdaddr(bd_addr);
1309 if ((idx < 0) || (idx >= BTIF_HF_NUM_CB))
1311 BTIF_TRACE_ERROR("%s: Invalid index %d", __FUNCTION__, idx);
1312 return BT_STATUS_FAIL;
1315 if (idx != BTIF_HF_INVALID_IDX)
1317 tBTA_AG_RES_DATA ag_res;
1320 memset (&ag_res, 0, sizeof (ag_res));
1322 /* Format the response */
1325 ag_res.ok_flag = BTA_AG_OK_DONE;
1329 BTIF_TRACE_EVENT("clcc_response: [%d] dir %d state %d mode %d number = %s type = %d",
1330 index, dir, state, mode, number, type);
1331 xx = sprintf (ag_res.str, "%d,%d,%d,%d,%d",
1332 index, dir, state, mode, mpty);
1336 if ((type == BTHF_CALL_ADDRTYPE_INTERNATIONAL) && (*number != '+'))
1337 sprintf (&ag_res.str[xx], ",\"+%s\",%d", number, type);
1339 sprintf (&ag_res.str[xx], ",\"%s\",%d", number, type);
1342 BTA_AgResult (btif_hf_cb[idx].handle, BTA_AG_CLCC_RES, &ag_res);
1344 return BT_STATUS_SUCCESS;
1347 return BT_STATUS_FAIL;
1350 /*******************************************************************************
1352 ** Function phone_state_change
1354 ** Description notify of a call state change
1355 ** number & type: valid only for incoming & waiting call
1357 ** Returns bt_status_t
1359 *******************************************************************************/
1361 static bt_status_t phone_state_change(int num_active, int num_held, bthf_call_state_t call_setup_state,
1362 const char *number, bthf_call_addrtype_t type)
1364 tBTA_AG_RES res = 0xff;
1365 tBTA_AG_RES_DATA ag_res;
1366 bt_status_t status = BT_STATUS_SUCCESS;
1367 BOOLEAN activeCallUpdated = FALSE;
1370 /* hf_idx is index of connected HS that sent ATA/BLDN,
1371 otherwise index of latest connected HS */
1372 if (hf_idx != BTIF_HF_INVALID_IDX)
1375 idx = btif_hf_latest_connected_idx();
1377 BTIF_TRACE_IMP("phone_state_change: idx = %d", idx);
1379 /* Check if SLC is connected */
1380 if (btif_hf_check_if_slc_connected() != BT_STATUS_SUCCESS)
1381 return BT_STATUS_NOT_READY;
1383 BTIF_TRACE_IMP("phone_state_change: num_active=%d [prev: %d] num_held=%d[prev: %d]"
1384 " call_setup=%s [prev: %s]", num_active, btif_hf_cb[idx].num_active,
1385 num_held, btif_hf_cb[idx].num_held, dump_hf_call_state(call_setup_state),
1386 dump_hf_call_state(btif_hf_cb[idx].call_setup_state));
1388 /* if all indicators are 0, send end call and return */
1389 if (num_active == 0 && num_held == 0 && call_setup_state == BTHF_CALL_STATE_IDLE)
1391 BTIF_TRACE_DEBUG("%s: Phone on hook", __FUNCTION__);
1393 /* record call termination timestamp if there was an active/held call or
1394 callsetup state > BTHF_CALL_STATE_IDLE */
1395 if ((btif_hf_cb[idx].call_setup_state != BTHF_CALL_STATE_IDLE ) ||
1396 (btif_hf_cb[idx].num_active) ||(btif_hf_cb[idx].num_held))
1398 BTIF_TRACE_DEBUG("%s: Record call termination timestamp", __FUNCTION__);
1399 clock_gettime(CLOCK_MONOTONIC, &btif_hf_cb[0].call_end_timestamp);
1401 BTA_AgResult (BTA_AG_HANDLE_ALL, BTA_AG_END_CALL_RES, NULL);
1402 hf_idx = BTIF_HF_INVALID_IDX;
1404 /* if held call was present, reset that as well */
1405 if (btif_hf_cb[idx].num_held)
1406 send_indicator_update(BTA_AG_IND_CALLHELD, 0);
1408 goto update_call_states;
1411 /* active state can change when:
1412 ** 1. an outgoing/incoming call was answered
1413 ** 2. an held was resumed
1414 ** 3. without callsetup notifications, call became active
1415 ** (3) can happen if call is active and a headset connects to us
1417 ** In the case of (3), we will have to notify the stack of an active
1418 ** call, instead of sending an indicator update. This will also
1419 ** force the SCO to be setup. Handle this special case here prior to
1420 ** call setup handling
1422 if ( ((num_active + num_held) > 0) && (btif_hf_cb[idx].num_active == 0) && (btif_hf_cb[idx].num_held == 0) &&
1423 (btif_hf_cb[idx].call_setup_state == BTHF_CALL_STATE_IDLE) )
1425 BTIF_TRACE_IMP("%s: Active/Held call notification received without call setup update",
1428 memset(&ag_res, 0, sizeof(tBTA_AG_RES_DATA));
1429 ag_res.audio_handle = btif_hf_cb[idx].handle;
1430 /* Addition call setup with the Active call
1431 ** CIND response should have been updated.
1432 ** just open SCO conenction.
1434 if (call_setup_state != BTHF_CALL_STATE_IDLE)
1435 res = BTA_AG_MULTI_CALL_RES;
1437 res = BTA_AG_OUT_CALL_CONN_RES;
1438 BTA_AgResult(BTA_AG_HANDLE_ALL, res, &ag_res);
1439 activeCallUpdated = TRUE;
1442 /* Ringing call changed? */
1443 if (call_setup_state != btif_hf_cb[idx].call_setup_state)
1445 BTIF_TRACE_IMP("%s: Call setup states changed. old: %s new: %s",
1446 __FUNCTION__, dump_hf_call_state(btif_hf_cb[idx].call_setup_state),
1447 dump_hf_call_state(call_setup_state));
1448 memset(&ag_res, 0, sizeof(tBTA_AG_RES_DATA));
1450 switch (call_setup_state)
1452 case BTHF_CALL_STATE_IDLE:
1454 switch (btif_hf_cb[idx].call_setup_state)
1456 case BTHF_CALL_STATE_INCOMING:
1457 if (num_active > btif_hf_cb[idx].num_active)
1459 res = BTA_AG_IN_CALL_CONN_RES;
1460 ag_res.audio_handle = btif_hf_cb[idx].handle;
1462 else if (num_held > btif_hf_cb[idx].num_held)
1463 res = BTA_AG_IN_CALL_HELD_RES;
1465 res = BTA_AG_CALL_CANCEL_RES;
1467 case BTHF_CALL_STATE_DIALING:
1468 case BTHF_CALL_STATE_ALERTING:
1469 if (num_active > btif_hf_cb[idx].num_active)
1471 ag_res.audio_handle = BTA_AG_HANDLE_SCO_NO_CHANGE;
1472 res = BTA_AG_OUT_CALL_CONN_RES;
1475 res = BTA_AG_CALL_CANCEL_RES;
1478 BTIF_TRACE_ERROR("%s: Incorrect Call setup state transition", __FUNCTION__);
1479 status = BT_STATUS_PARM_INVALID;
1484 case BTHF_CALL_STATE_INCOMING:
1485 if (num_active || num_held)
1486 res = BTA_AG_CALL_WAIT_RES;
1488 res = BTA_AG_IN_CALL_RES;
1492 if ((type == BTHF_CALL_ADDRTYPE_INTERNATIONAL) && (*number != '+'))
1493 xx = sprintf (ag_res.str, "\"+%s\"", number);
1495 xx = sprintf (ag_res.str, "\"%s\"", number);
1498 if (res == BTA_AG_CALL_WAIT_RES)
1499 sprintf(&ag_res.str[xx], ",%d", type);
1502 case BTHF_CALL_STATE_DIALING:
1503 if (!(num_active + num_held))
1505 ag_res.audio_handle = btif_hf_cb[idx].handle;
1509 BTIF_TRACE_DEBUG("%s: Already in a call, don't set audio handle", __FUNCTION__);
1511 res = BTA_AG_OUT_CALL_ORIG_RES;
1513 case BTHF_CALL_STATE_ALERTING:
1514 /* if we went from idle->alert, force SCO setup here. dialing usually triggers it */
1515 if ((btif_hf_cb[idx].call_setup_state == BTHF_CALL_STATE_IDLE) &&
1516 !(num_active + num_held))
1518 ag_res.audio_handle = btif_hf_cb[idx].handle;
1522 BTIF_TRACE_DEBUG("%s: Already in a call or prev call state was dialing,"
1523 " don't set audio handle", __FUNCTION__);
1525 res = BTA_AG_OUT_CALL_ALERT_RES;
1528 BTIF_TRACE_ERROR("%s: Incorrect new ringing call state", __FUNCTION__);
1529 status = BT_STATUS_PARM_INVALID;
1532 BTIF_TRACE_IMP("%s: Call setup state changed. res=%d, audio_handle=%d", __FUNCTION__, res, ag_res.audio_handle);
1535 BTA_AgResult(BTA_AG_HANDLE_ALL, res, &ag_res);
1537 /* if call setup is idle, we have already updated call indicator, jump out */
1538 if (call_setup_state == BTHF_CALL_STATE_IDLE)
1540 /* check & update callheld */
1541 if ((num_held > 0) && (num_active > 0))
1542 send_indicator_update(BTA_AG_IND_CALLHELD, 1);
1543 goto update_call_states;
1547 memset(&ag_res, 0, sizeof(tBTA_AG_RES_DATA));
1549 /* per the errata 2043, call=1 implies atleast one call is in progress (active/held)
1550 ** https://www.bluetooth.org/errata/errata_view.cfm?errata_id=2043
1551 ** Handle call indicator change
1553 if (!activeCallUpdated && ((num_active + num_held) !=
1554 (btif_hf_cb[idx].num_active + btif_hf_cb[idx].num_held)) )
1556 BTIF_TRACE_IMP("%s: Active call states changed. old: %d new: %d", __FUNCTION__, btif_hf_cb[idx].num_active, num_active);
1557 send_indicator_update(BTA_AG_IND_CALL, ((num_active + num_held) > 0) ? 1 : 0);
1561 if (num_held != btif_hf_cb[idx].num_held ||
1562 ((num_active == 0) && ((num_held + btif_hf_cb[idx].num_held) > 1)))
1564 BTIF_TRACE_IMP("%s: Held call states changed. old: %d new: %d",
1565 __FUNCTION__, btif_hf_cb[idx].num_held, num_held);
1566 send_indicator_update(BTA_AG_IND_CALLHELD, ((num_held == 0) ? 0 : ((num_active == 0) ? 2 : 1)));
1569 /* Calls Swapped? */
1570 if ( (call_setup_state == btif_hf_cb[idx].call_setup_state) &&
1571 (num_active && num_held) &&
1572 (num_active == btif_hf_cb[idx].num_active) &&
1573 (num_held == btif_hf_cb[idx].num_held) )
1575 BTIF_TRACE_IMP("%s: Calls swapped", __FUNCTION__);
1576 send_indicator_update(BTA_AG_IND_CALLHELD, 1);
1580 for (i = 0; i < btif_max_hf_clients; i++)
1582 if (btif_hf_cb[i].state == BTHF_CONNECTION_STATE_SLC_CONNECTED) {
1583 btif_hf_cb[i].num_active = num_active;
1584 btif_hf_cb[i].num_held = num_held;
1585 btif_hf_cb[i].call_setup_state = call_setup_state;
1591 /*******************************************************************************
1593 ** Function btif_hf_is_call_idle
1595 ** Description returns true if no call is in progress
1597 ** Returns bt_status_t
1599 *******************************************************************************/
1600 BOOLEAN btif_hf_is_call_idle()
1604 if (bt_hf_callbacks == NULL)
1608 for (i = 0; i < btif_max_hf_clients; i++)
1610 BTIF_TRACE_EVENT("%s: call_setup_state: %d for handle: %d",
1611 __FUNCTION__, btif_hf_cb[i].call_setup_state, btif_hf_cb[i].handle);
1612 BTIF_TRACE_EVENT("num_held: %d, num_active: %d for handle: %d",
1613 btif_hf_cb[i].num_held, btif_hf_cb[i].num_active, btif_hf_cb[i].handle);
1614 j &= ((btif_hf_cb[i].call_setup_state == BTHF_CALL_STATE_IDLE) &&
1615 ((btif_hf_cb[i].num_held + btif_hf_cb[i].num_active) == 0));
1620 BTIF_TRACE_EVENT("%s: call state idle ", __FUNCTION__);
1631 /*******************************************************************************
1633 ** Function btif_hf_call_terminated_recently
1635 ** Description Checks if a call has been terminated
1637 ** Returns bt_status_t
1639 *******************************************************************************/
1640 BOOLEAN btif_hf_call_terminated_recently()
1642 struct timespec now;
1644 clock_gettime(CLOCK_MONOTONIC, &now);
1645 if (now.tv_sec < btif_hf_cb[0].call_end_timestamp.tv_sec +
1646 BTIF_HF_CALL_END_TIMEOUT)
1652 btif_hf_cb[0].call_end_timestamp.tv_sec = 0;
1657 /*******************************************************************************
1661 ** Description Closes the HF interface
1663 ** Returns bt_status_t
1665 *******************************************************************************/
1666 static void cleanup( void )
1668 BTIF_TRACE_IMP("%s", __FUNCTION__);
1670 #if (defined(BTIF_HF_SERVICES) && (BTIF_HF_SERVICES & BTA_HFP_SERVICE_MASK))
1671 btif_disable_service(BTA_HFP_SERVICE_ID);
1673 btif_disable_service(BTA_HSP_SERVICE_ID);
1677 /*******************************************************************************
1679 ** Function configure_wbs
1681 ** Description set to over-ride the current WBS configuration.
1682 ** It will not send codec setting cmd to the controller now.
1683 ** It just change the configure.
1685 ** Returns bt_status_t
1687 *******************************************************************************/
1688 static bt_status_t configure_wbs( bt_bdaddr_t *bd_addr , bthf_wbs_config_t config )
1692 int idx = btif_hf_idx_by_bdaddr(bd_addr);
1694 if ((idx < 0) || (idx >= BTIF_HF_NUM_CB))
1696 BTIF_TRACE_ERROR("%s: Invalid index %d", __FUNCTION__, idx);
1697 return BT_STATUS_FAIL;
1700 BTIF_TRACE_EVENT("%s config is %d", __FUNCTION__,config);
1701 if (config == BTHF_WBS_YES)
1702 BTA_AgSetCodec(btif_hf_cb[idx].handle,BTA_AG_CODEC_MSBC);
1703 else if(config == BTHF_WBS_NO)
1704 BTA_AgSetCodec(btif_hf_cb[idx].handle,BTA_AG_CODEC_CVSD);
1706 BTA_AgSetCodec(btif_hf_cb[idx].handle,BTA_AG_CODEC_NONE);
1708 return BT_STATUS_SUCCESS;
1711 /*******************************************************************************
1713 ** Function bind_response
1715 ** Description response for BIND READ command
1716 ** Can be iteratively called for each Hf indicator.
1718 ** Returns bt_status_t
1720 *******************************************************************************/
1721 static bt_status_t bind_response(int anum, bthf_hf_indicator_status_t status,
1722 bt_bdaddr_t *bd_addr)
1726 int idx = btif_hf_idx_by_bdaddr(bd_addr);
1728 if ((idx < 0) || (idx >= BTIF_HF_NUM_CB))
1730 BTIF_TRACE_ERROR("%s: Invalid index %d", __FUNCTION__, idx);
1731 return BT_STATUS_FAIL;
1734 if (idx != BTIF_HF_INVALID_IDX)
1736 tBTA_AG_RES_DATA ag_res;
1739 memset (&ag_res, 0, sizeof (ag_res));
1741 /* Format the response */
1742 BTIF_TRACE_EVENT("bind_response: anum : [%d] status %d ", anum, status);
1743 xx = snprintf (ag_res.str, sizeof(ag_res.str), "%d,%d", anum, status);
1745 BTA_AgResult (btif_hf_cb[idx].handle, BTA_AG_BIND_RES, &ag_res);
1747 return BT_STATUS_SUCCESS;
1750 return BT_STATUS_FAIL;
1753 /*******************************************************************************
1755 ** Function bind_string_response
1757 ** Description response for BIND TEST command
1759 ** Returns bt_status_t
1761 *******************************************************************************/
1762 static bt_status_t bind_string_response(const char* res,
1763 bt_bdaddr_t *bd_addr)
1767 int idx = btif_hf_idx_by_bdaddr(bd_addr);
1769 if ((idx < 0) || (idx >= BTIF_HF_NUM_CB))
1771 BTIF_TRACE_ERROR("%s: Invalid index %d", __FUNCTION__, idx);
1772 return BT_STATUS_FAIL;
1775 if (idx != BTIF_HF_INVALID_IDX)
1777 tBTA_AG_RES_DATA ag_res;
1780 memset (&ag_res, 0, sizeof (ag_res));
1782 /* Format the response */
1783 xx = snprintf (ag_res.str, sizeof(ag_res.str), "%s", res);
1785 BTA_AgResult (btif_hf_cb[idx].handle, BTA_AG_BIND_RES, &ag_res);
1787 return BT_STATUS_SUCCESS;
1790 return BT_STATUS_FAIL;
1793 static void set_voip_network_type_wifi_hci_cmd_complete(tBTM_VSC_CMPL* p_data)
1795 UINT8 *stream, status, subcmd;
1796 UINT16 opcode, length;
1798 if (p_data && (stream = (UINT8*)p_data->p_param_buf))
1800 opcode = p_data->opcode;
1801 length = p_data->param_len;
1802 STREAM_TO_UINT8(status, stream);
1803 STREAM_TO_UINT8(subcmd, stream);
1804 BTIF_TRACE_DEBUG("%s opcode = 0x%04X, length = %d, status = %d, subcmd = %d",
1805 __FUNCTION__, opcode, length, status, subcmd);
1806 if (status == HCI_SUCCESS)
1808 BTIF_TRACE_DEBUG("btm_SetVoipNetworkTypeWifi status success");
1813 /*******************************************************************************
1815 ** Function voip_network_type_wifi
1817 ** Description BT app updates the connectivity network used for VOIP as Wifi
1819 ** Returns bt_status_t
1821 *******************************************************************************/
1822 static bt_status_t voip_network_type_wifi(bthf_voip_state_t isVoipStarted,
1823 bthf_voip_call_network_type_t isNetworkWifi)
1825 UINT8 cmd[3], *p_cursor;
1826 UINT8 sub_cmd = HCI_VSC_SUBCODE_VOIP_NETWORK_WIFI;
1827 tBTM_STATUS status = BTM_NO_RESOURCES;
1828 int idx = btif_hf_latest_connected_idx();
1832 if ((idx < 0) || (idx >= BTIF_HF_NUM_CB))
1834 BTIF_TRACE_ERROR("%s: Invalid index %d", __FUNCTION__, idx);
1835 return BT_STATUS_FAIL;
1841 *p_cursor++ = sub_cmd;
1842 *p_cursor++ = isVoipStarted;
1843 *p_cursor++ = isNetworkWifi;
1845 if ((status = BTM_VendorSpecificCommand(HCI_VSC_VOIP_NETWORK_WIFI_OCF, sizeof(cmd),
1846 cmd, set_voip_network_type_wifi_hci_cmd_complete)) != BTM_CMD_STARTED)
1848 BTIF_TRACE_ERROR("%s: status %d", __FUNCTION__, status);
1849 return BT_STATUS_FAIL;
1852 return BT_STATUS_SUCCESS;
1856 static const bthf_interface_t bthfInterface = {
1857 sizeof(bthfInterface),
1863 start_voice_recognition,
1864 stop_voice_recognition,
1866 device_status_notification,
1869 formatted_at_response,
1876 bind_string_response,
1877 voip_network_type_wifi,
1880 /*******************************************************************************
1882 ** Function btif_hf_execute_service
1884 ** Description Initializes/Shuts down the service
1886 ** Returns BT_STATUS_SUCCESS on success, BT_STATUS_FAIL otherwise
1888 *******************************************************************************/
1889 bt_status_t btif_hf_execute_service(BOOLEAN b_enable)
1891 char * p_service_names[] = BTIF_HF_SERVICE_NAMES;
1893 uint8_t no_of_codecs = 0;
1895 char value[PROPERTY_VALUE_MAX];
1897 BTIF_TRACE_IMP("%s: enable: %d", __FUNCTION__, b_enable);
1901 /* Enable and register with BTA-AG */
1902 BTA_AgEnable (BTA_AG_PARSE, bte_hf_evt);
1903 codecs = controller_get_interface()->get_local_supported_codecs(&no_of_codecs);
1906 for (i = 0; i < no_of_codecs; i++)
1908 if (codecs[i] == BTA_AG_MSBC_CODEC)
1910 btif_features |= BTA_AG_FEAT_CODEC;
1917 /* Read the property if local supported codecs commands is not supported */
1918 if (property_get("ro.bluetooth.hfp.ver", value, "1.5") &&
1919 (!strcmp(value, "1.6") || !strcmp(value, "1.7")) )
1920 btif_features |= BTA_AG_FEAT_CODEC;
1923 for (i = 0; i < btif_max_hf_clients; i++)
1925 BTA_AgRegister(BTIF_HF_SERVICES, BTIF_HF_SECURITY,
1926 btif_features, p_service_names, bthf_hf_id[i]);
1930 if (bt_hf_callbacks)
1932 BTIF_TRACE_IMP("%s: setting call backs to NULL", __FUNCTION__);
1933 bt_hf_callbacks = NULL;
1935 /* De-register AG */
1936 for (i = 0; i < btif_max_hf_clients; i++)
1938 BTA_AgDeregister(btif_hf_cb[i].handle);
1943 BTIF_TRACE_IMP("%s: enable: %d completed", __FUNCTION__, b_enable);
1944 return BT_STATUS_SUCCESS;
1947 /*******************************************************************************
1949 ** Function btif_hf_get_interface
1951 ** Description Get the hf callback interface
1953 ** Returns bthf_interface_t
1955 *******************************************************************************/
1956 const bthf_interface_t *btif_hf_get_interface()
1958 BTIF_TRACE_EVENT("%s", __FUNCTION__);
1959 return &bthfInterface;