OSDN Git Service

AVRCP: Check number of text attribute values in response
[android-x86/system-bt.git] / btif / src / btif_hf.c
1 /******************************************************************************
2  *
3  *  Copyright (C) 2009-2012 Broadcom Corporation
4  *
5  *  Licensed under the Apache License, Version 2.0 (the "License");
6  *  you may not use this file except in compliance with the License.
7  *  You may obtain a copy of the License at:
8  *
9  *  http://www.apache.org/licenses/LICENSE-2.0
10  *
11  *  Unless required by applicable law or agreed to in writing, software
12  *  distributed under the License is distributed on an "AS IS" BASIS,
13  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  *  See the License for the specific language governing permissions and
15  *  limitations under the License.
16  *
17  ******************************************************************************/
18
19 /************************************************************************************
20  *
21  *  Filename:      btif_hf.c
22  *
23  *  Description:   Handsfree Profile Bluetooth Interface
24  *
25  *
26  ***********************************************************************************/
27
28 #define LOG_TAG "bt_btif_hf"
29
30 #include <stdlib.h>
31 #include <string.h>
32 #include <time.h>
33 #include <cutils/properties.h>
34
35 #include <hardware/bluetooth.h>
36 #include <hardware/bt_hf.h>
37
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"
44
45 /************************************************************************************
46 **  Constants & Macros
47 ************************************************************************************/
48 #ifndef BTIF_HSAG_SERVICE_NAME
49 #define BTIF_HSAG_SERVICE_NAME ("Headset Gateway")
50 #endif
51
52 #ifndef BTIF_HFAG_SERVICE_NAME
53 #define BTIF_HFAG_SERVICE_NAME ("Handsfree Gateway")
54 #endif
55
56 #ifndef BTIF_HF_SERVICES
57 #define BTIF_HF_SERVICES    (BTA_HSP_SERVICE_MASK | BTA_HFP_SERVICE_MASK )
58 #endif
59
60 #ifndef BTIF_HF_SERVICE_NAMES
61 #define BTIF_HF_SERVICE_NAMES {BTIF_HSAG_SERVICE_NAME , BTIF_HFAG_SERVICE_NAME}
62 #endif
63
64 #ifndef BTIF_HF_SECURITY
65 #define BTIF_HF_SECURITY    (BTA_SEC_AUTHENTICATE | BTA_SEC_ENCRYPT)
66 #endif
67
68 #ifndef BTIF_HF_FEATURES
69 #define BTIF_HF_FEATURES   ( BTA_AG_FEAT_3WAY | \
70                              BTA_AG_FEAT_ECNR   | \
71                              BTA_AG_FEAT_REJECT | \
72                              BTA_AG_FEAT_ECS    | \
73                              BTA_AG_FEAT_EXTERR | \
74                              BTA_AG_FEAT_BTRH   | \
75                              BTA_AG_FEAT_VREC   | \
76                              BTA_AG_FEAT_HFIND  | \
77                              BTA_AG_FEAT_S4     | \
78                              BTA_AG_FEAT_UNAT)
79 #endif
80
81 #define BTIF_HF_CALL_END_TIMEOUT       6
82
83 #define BTIF_HF_INVALID_IDX       -1
84
85 /* Number of BTIF-HF control blocks */
86 #define BTIF_HF_NUM_CB       2
87
88 /* Assigned number for mSBC codec */
89 #define BTA_AG_MSBC_CODEC 5
90
91 /* Max HF clients supported from App */
92 UINT16 btif_max_hf_clients = 1;
93
94 /* HF app ids for service registration */
95 typedef enum {
96     BTIF_HF_ID_1 = 0,
97     BTIF_HF_ID_2,
98 #if (BTIF_HF_NUM_CB == 3)
99     BTIF_HF_ID_3
100 #endif
101 } bthf_hf_id_t;
102
103 UINT16 bthf_hf_id[BTIF_HF_NUM_CB] = {BTIF_HF_ID_1, BTIF_HF_ID_2,
104                                     #if (BTIF_HF_NUM_CB == 3)
105                                         BTIF_HF_ID_3
106                                     #endif
107                                     };
108
109 /************************************************************************************
110 **  Local type definitions
111 ************************************************************************************/
112
113 /************************************************************************************
114 **  Static variables
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;
119
120 #define CHECK_BTHF_INIT() if (bt_hf_callbacks == NULL)\
121     {\
122         BTIF_TRACE_WARNING("BTHF: %s: BTHF not initialized", __FUNCTION__);\
123         return BT_STATUS_NOT_READY;\
124     }\
125     else\
126     {\
127         BTIF_TRACE_IMP("BTHF: %s", __FUNCTION__);\
128     }
129
130 #define CHECK_BTHF_SLC_CONNECTED() if (bt_hf_callbacks == NULL)\
131     {\
132         BTIF_TRACE_WARNING("BTHF: %s: BTHF not initialized", __FUNCTION__);\
133         return BT_STATUS_NOT_READY;\
134     }\
135     else if (btif_hf_cb.state != BTHF_CONNECTION_STATE_SLC_CONNECTED)\
136     {\
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;\
139     }\
140     else\
141     {\
142         BTIF_TRACE_EVENT("BTHF: %s", __FUNCTION__);\
143     }
144
145 /* BTIF-HF control block to map bdaddr to BTA handle */
146 typedef struct _btif_hf_cb
147 {
148     UINT16                  handle;
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;
153     int                     num_active;
154     int                     num_held;
155     struct timespec         call_end_timestamp;
156     struct timespec         connected_timestamp;
157     bthf_call_state_t       call_setup_state;
158 } btif_hf_cb_t;
159
160 static btif_hf_cb_t btif_hf_cb[BTIF_HF_NUM_CB];
161
162 /************************************************************************************
163 **  Static functions
164 ************************************************************************************/
165
166 /************************************************************************************
167 **  Externs
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.
171 */
172 #ifndef BTIF_HF_WBS_PREFERRED
173 #define BTIF_HF_WBS_PREFERRED  TRUE
174 #endif
175
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;
179
180 /************************************************************************************
181 **  Functions
182 ************************************************************************************/
183
184 /*******************************************************************************
185 **
186 ** Function         is_connected
187 **
188 ** Description      Internal function to check if HF is connected
189 **
190 ** Returns          TRUE if connected
191 **
192 *******************************************************************************/
193 static BOOLEAN is_connected(bt_bdaddr_t *bd_addr)
194 {
195         int i;
196         for (i = 0; i < btif_max_hf_clients; ++i)
197         {
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)))
202                 return TRUE;
203         }
204         return FALSE;
205 }
206
207 /*******************************************************************************
208 **
209 ** Function         btif_hf_is_connected_on_other_idx
210 **
211 ** Description      Checks if any other AV SCB is connected
212 **
213 ** Returns          BOOLEAN
214 **
215 *******************************************************************************/
216
217 BOOLEAN btif_hf_is_connected_on_other_idx(int current_index)
218 {
219     int i;
220     for (i = 0; i < btif_max_hf_clients; i++)
221     {
222         if (i != current_index)
223         {
224             if ((btif_hf_cb[i].state == BTHF_CONNECTION_STATE_CONNECTED) ||
225                  (btif_hf_cb[i].state == BTHF_CONNECTION_STATE_SLC_CONNECTED))
226                 return TRUE;
227         }
228     }
229     return FALSE;
230 }
231
232 /*******************************************************************************
233 **
234 ** Function         btif_hf_get_other_connected_index
235 **
236 ** Description      Checks for other connected index
237 **
238 ** Returns          Other connected index
239 **
240 *******************************************************************************/
241
242 int btif_hf_get_other_connected_index(int current_index)
243 {
244     int i;
245     for (i = 0; i < btif_max_hf_clients; i++)
246     {
247         if (i != current_index)
248         {
249             if ((btif_hf_cb[i].state == BTHF_CONNECTION_STATE_CONNECTED) ||
250                  (btif_hf_cb[i].state == BTHF_CONNECTION_STATE_SLC_CONNECTED))
251                 return i;
252         }
253     }
254     return btif_max_hf_clients;
255 }
256 /*******************************************************************************
257 **
258 ** Function         send_bvra_update
259 **
260 ** Description      Internal function to updated other connected HS for BVRA state
261 **
262 ** Returns          void
263 **
264 *******************************************************************************/
265 static void send_bvra_update(int index)
266 {
267     BTIF_TRACE_EVENT("connected %d",btif_hf_is_connected_on_other_idx(index));
268     if (btif_hf_is_connected_on_other_idx(index))
269     {
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))
274         {
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);
281         }
282         else
283         {
284             BTIF_TRACE_EVENT("Invalid connected index");
285         }
286     }
287
288 }
289 /*******************************************************************************
290 **
291 ** Function         btif_hf_idx_by_bdaddr
292 **
293 ** Description      Internal function to get idx by bdaddr
294 **
295 ** Returns          idx
296 **
297 *******************************************************************************/
298 static int btif_hf_idx_by_bdaddr(bt_bdaddr_t *bd_addr)
299 {
300         int i;
301         for (i = 0; i < btif_max_hf_clients; ++i)
302         {
303             if (is_connected(bd_addr) && (bdcmp(bd_addr->address,
304                                   btif_hf_cb[i].connected_bda.address) == 0))
305                 return i;
306         }
307         return BTIF_HF_INVALID_IDX;
308 }
309
310 /*******************************************************************************
311 **
312 ** Function         callstate_to_callsetup
313 **
314 ** Description      Converts HAL call state to BTA call setup indicator value
315 **
316 ** Returns          BTA call indicator value
317 **
318 *******************************************************************************/
319 static UINT8 callstate_to_callsetup(bthf_call_state_t call_state)
320 {
321     UINT8 call_setup = 0;
322     if (call_state == BTHF_CALL_STATE_INCOMING)
323         call_setup = 1;
324     if (call_state == BTHF_CALL_STATE_DIALING)
325         call_setup = 2;
326     if (call_state == BTHF_CALL_STATE_ALERTING)
327         call_setup = 3;
328
329     return call_setup;
330 }
331
332 /*******************************************************************************
333 **
334 ** Function         send_at_result
335 **
336 ** Description      Send AT result code (OK/ERROR)
337 **
338 ** Returns          void
339 **
340 *******************************************************************************/
341 static void send_at_result(UINT8 ok_flag, UINT16 errcode, int idx)
342 {
343     tBTA_AG_RES_DATA    ag_res;
344     memset (&ag_res, 0, sizeof (ag_res));
345
346     ag_res.ok_flag = ok_flag;
347     if (ok_flag == BTA_AG_OK_ERROR)
348     {
349         ag_res.errcode = errcode;
350     }
351
352     BTA_AgResult (btif_hf_cb[idx].handle, BTA_AG_UNAT_RES, &ag_res);
353 }
354
355 /*******************************************************************************
356 **
357 ** Function         send_indicator_update
358 **
359 ** Description      Send indicator update (CIEV)
360 **
361 ** Returns          void
362 **
363 *******************************************************************************/
364 static void send_indicator_update (UINT16 indicator, UINT16 value)
365 {
366     tBTA_AG_RES_DATA ag_res;
367
368     memset(&ag_res, 0, sizeof(tBTA_AG_RES_DATA));
369     ag_res.ind.id = indicator;
370     ag_res.ind.value = value;
371
372     BTA_AgResult(BTA_AG_HANDLE_ALL, BTA_AG_IND_RES, &ag_res);
373 }
374
375 void clear_phone_state_multihf(int idx)
376 {
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;
379 }
380
381 /*******************************************************************************
382 **
383 ** Function         btif_hf_latest_connected_idx
384 **
385 ** Description      Returns idx for latest connected HF
386 **
387 ** Returns          int
388 **
389 *******************************************************************************/
390 static int btif_hf_latest_connected_idx()
391 {
392       struct timespec         now, conn_time_delta;
393       int latest_conn_idx = BTIF_HF_INVALID_IDX, i;
394
395       clock_gettime(CLOCK_MONOTONIC, &now);
396       conn_time_delta.tv_sec = now.tv_sec;
397
398       for (i = 0; i < btif_max_hf_clients; i++)
399       {
400           if (btif_hf_cb[i].state == BTHF_CONNECTION_STATE_SLC_CONNECTED)
401           {
402               if ((now.tv_sec - btif_hf_cb[i].connected_timestamp.tv_sec)
403                                             < conn_time_delta.tv_sec)
404               {
405                   conn_time_delta.tv_sec =
406                        now.tv_sec - btif_hf_cb[i].connected_timestamp.tv_sec;
407                   latest_conn_idx = i;
408               }
409           }
410       }
411       return latest_conn_idx;
412 }
413
414 /*******************************************************************************
415 **
416 ** Function         btif_hf_check_if_slc_connected
417 **
418 ** Description      Returns BT_STATUS_SUCCESS if SLC is up for any HF
419 **
420 ** Returns          bt_status_t
421 **
422 *******************************************************************************/
423 static bt_status_t btif_hf_check_if_slc_connected()
424 {
425     if (bt_hf_callbacks == NULL)
426     {
427         BTIF_TRACE_WARNING("BTHF: %s: BTHF not initialized", __FUNCTION__);
428         return BT_STATUS_NOT_READY;
429     }
430     else
431     {
432         int i;
433         for (i = 0; i < btif_max_hf_clients; i++)
434         {
435             if (btif_hf_cb[i].state == BTHF_CONNECTION_STATE_SLC_CONNECTED)
436             {
437                 BTIF_TRACE_EVENT("BTHF: %s: slc connected for idx = %d",
438                                          __FUNCTION__, i);
439                 return BT_STATUS_SUCCESS;
440             }
441         }
442         BTIF_TRACE_WARNING("BTHF: %s: No SLC connection up", __FUNCTION__);
443         return BT_STATUS_NOT_READY;
444     }
445 }
446
447 /*****************************************************************************
448 **   Section name (Group of functions)
449 *****************************************************************************/
450
451 /*****************************************************************************
452 **
453 **   btif hf api functions (no context switch)
454 **
455 *****************************************************************************/
456
457 /*******************************************************************************
458 **
459 ** Function         btif_hf_upstreams_evt
460 **
461 ** Description      Executes HF UPSTREAMS events in btif context
462 **
463 ** Returns          void
464 **
465 *******************************************************************************/
466 static void btif_hf_upstreams_evt(UINT16 event, char* p_param)
467 {
468     tBTA_AG *p_data = (tBTA_AG *)p_param;
469     bdstr_t bdstr;
470     int idx = p_data->hdr.handle - 1;
471     BOOLEAN ignore_rfc_fail = false;
472
473     BTIF_TRACE_IMP("%s: event=%s", __FUNCTION__, dump_hf_event(event));
474
475     if ((idx < 0) || (idx >= BTIF_HF_NUM_CB))
476     {
477         BTIF_TRACE_ERROR("%s: Invalid index %d", __FUNCTION__, idx);
478         return;
479     }
480
481     switch (event)
482     {
483         case BTA_AG_ENABLE_EVT:
484         case BTA_AG_DISABLE_EVT:
485             break;
486
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);
491             break;
492
493         case BTA_AG_OPEN_EVT:
494             if (p_data->open.status == BTA_AG_SUCCESS)
495             {
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);
501             }
502             else if (btif_hf_cb[idx].state == BTHF_CONNECTION_STATE_CONNECTING)
503             {
504                 /* In Multi-hf, if outgoing RFCOMM connection fails due to collision,
505                  * ignore the failure if HF is already connected.
506                  */
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)) )
510                 {
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;
514                 }
515
516                 btif_hf_cb[idx].state = BTHF_CONNECTION_STATE_DISCONNECTED;
517             }
518             else
519             {
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)));
523                 break;
524             }
525
526             if (ignore_rfc_fail != true)
527             {
528                 HAL_CBACK(bt_hf_callbacks, connection_state_cb, btif_hf_cb[idx].state,
529                                                         &btif_hf_cb[idx].connected_bda);
530             }
531
532             if (btif_hf_cb[idx].state == BTHF_CONNECTION_STATE_DISCONNECTED)
533                 bdsetany(btif_hf_cb[idx].connected_bda.address);
534
535             btif_queue_advance();
536
537             break;
538
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
553             */
554             btif_queue_advance();
555             break;
556
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 ",
561                                                 __FUNCTION__, idx);
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();
565
566             HAL_CBACK(bt_hf_callbacks, connection_state_cb, btif_hf_cb[idx].state,
567                              &btif_hf_cb[idx].connected_bda);
568             break;
569
570         case BTA_AG_AUDIO_OPEN_EVT:
571             hf_idx = idx;
572             HAL_CBACK(bt_hf_callbacks, audio_state_cb, BTHF_AUDIO_STATE_CONNECTED,
573                                                         &btif_hf_cb[idx].connected_bda);
574             break;
575
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);
579             break;
580
581         /* BTA auto-responds, silently discard */
582         case BTA_AG_SPK_EVT:
583         case BTA_AG_MIC_EVT:
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);
588             break;
589
590         case BTA_AG_AT_A_EVT:
591             if ((btif_hf_cb[0].num_held + btif_hf_cb[0].num_active) == 0)
592                 hf_idx = idx;
593             else
594                 BTIF_TRACE_DEBUG("Donot set hf_idx for ATA since already in a call");
595
596             HAL_CBACK(bt_hf_callbacks, answer_call_cmd_cb,
597                               &btif_hf_cb[idx].connected_bda);
598             break;
599
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)
604                 hf_idx = idx;
605             else
606                 BTIF_TRACE_DEBUG("Donot set hf_idx for BLDN/D since already in a call");
607
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);
611             break;
612
613         case BTA_AG_AT_CHUP_EVT:
614             HAL_CBACK(bt_hf_callbacks, hangup_call_cmd_cb,
615                               &btif_hf_cb[idx].connected_bda);
616             break;
617
618         case BTA_AG_AT_CIND_EVT:
619             HAL_CBACK(bt_hf_callbacks, cind_cmd_cb,
620                               &btif_hf_cb[idx].connected_bda);
621             break;
622
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);
626             break;
627
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;
634
635             break;
636
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);
641             break;
642
643         /* TODO: Add a callback for CBC */
644         case BTA_AG_AT_CBC_EVT:
645             break;
646
647         case BTA_AG_AT_CKPD_EVT:
648             HAL_CBACK(bt_hf_callbacks, key_pressed_cmd_cb,
649                               &btif_hf_cb[idx].connected_bda);
650             break;
651
652 #if (BTM_WBS_INCLUDED == TRUE )
653         case BTA_AG_WBS_EVT:
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);}
660             else
661              {HAL_CBACK(bt_hf_callbacks, wbs_cb, BTHF_WBS_NONE, &btif_hf_cb[idx].connected_bda);}
662             break;
663 #endif
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);
668             break;
669
670         case BTA_AG_AT_CLCC_EVT:
671             HAL_CBACK(bt_hf_callbacks, clcc_cmd_cb,
672                               &btif_hf_cb[idx].connected_bda);
673             break;
674
675         case BTA_AG_AT_COPS_EVT:
676             HAL_CBACK(bt_hf_callbacks, cops_cmd_cb,
677                               &btif_hf_cb[idx].connected_bda);
678             break;
679
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);
683             break;
684
685         case BTA_AG_AT_CNUM_EVT:
686             HAL_CBACK(bt_hf_callbacks, cnum_cmd_cb,
687                               &btif_hf_cb[idx].connected_bda);
688             break;
689
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);
694             break;
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))
702             {
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);
705             }
706             else
707             {
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);
710             }
711 #endif
712             break;
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);
718             break;
719
720         case BTA_AG_AT_BIND_EVT:
721             switch(p_data->val.num)
722             {
723                 case BTA_AG_AT_SET:
724                     HAL_CBACK(bt_hf_callbacks, bind_cmd_cb, p_data->val.str, BTHF_BIND_SET,
725                                                &btif_hf_cb[idx].connected_bda);
726                     break;
727                 case BTA_AG_AT_READ:
728                     HAL_CBACK(bt_hf_callbacks, bind_cmd_cb, p_data->val.str, BTHF_BIND_READ,
729                                                &btif_hf_cb[idx].connected_bda);
730                     break;
731                 case BTA_AG_AT_TEST:
732                     HAL_CBACK(bt_hf_callbacks, bind_cmd_cb, p_data->val.str, BTHF_BIND_TEST,
733                                                &btif_hf_cb[idx].connected_bda);
734                     break;
735             }
736             break;
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);
740
741             break;
742         default:
743             BTIF_TRACE_WARNING("%s: Unhandled event: %d", __FUNCTION__, event);
744             break;
745     }
746 }
747
748 /*******************************************************************************
749 **
750 ** Function         bte_hf_evt
751 **
752 ** Description      Switches context from BTE to BTIF for all HF events
753 **
754 ** Returns          void
755 **
756 *******************************************************************************/
757
758 static void bte_hf_evt(tBTA_AG_EVT event, tBTA_AG *p_data)
759 {
760     bt_status_t status;
761     int param_len = 0;
762
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);
772     else if (p_data)
773         param_len = sizeof(tBTA_AG_VAL);
774
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);
777
778     /* catch any failed context transfers */
779     ASSERTC(status == BT_STATUS_SUCCESS, "context transfer failed", status);
780 }
781
782 /*******************************************************************************
783 **
784 ** Function         btif_in_hf_generic_evt
785 **
786 ** Description     Processes generic events to be sent to JNI that are not triggered from the BTA.
787 **                      Always runs in BTIF context
788 **
789 ** Returns          void
790 **
791 *******************************************************************************/
792 static void btif_in_hf_generic_evt(UINT16 event, char *p_param)
793 {
794     int idx = btif_hf_idx_by_bdaddr((bt_bdaddr_t *)p_param);
795
796     BTIF_TRACE_EVENT("%s: event=%d", __FUNCTION__, event);
797
798     if ((idx < 0) || (idx >= BTIF_HF_NUM_CB))
799     {
800         BTIF_TRACE_ERROR("%s: Invalid index %d", __FUNCTION__, idx);
801         return;
802     }
803
804     switch (event) {
805         case BTIF_HFP_CB_AUDIO_CONNECTING:
806         {
807             HAL_CBACK(bt_hf_callbacks, audio_state_cb, BTHF_AUDIO_STATE_CONNECTING,
808                       &btif_hf_cb[idx].connected_bda);
809         } break;
810         default:
811         {
812             BTIF_TRACE_WARNING("%s : Unknown event 0x%x", __FUNCTION__, event);
813         }
814         break;
815     }
816 }
817
818 /*******************************************************************************
819 **
820 ** Function         btif_hf_init
821 **
822 ** Description     initializes the hf interface
823 **
824 ** Returns         bt_status_t
825 **
826 *******************************************************************************/
827 static bt_status_t init( bthf_callbacks_t* callbacks, int max_hf_clients)
828 {
829     btif_max_hf_clients = max_hf_clients;
830     BTIF_TRACE_DEBUG("%s - max_hf_clients=%d", __func__, btif_max_hf_clients);
831
832     bt_hf_callbacks = callbacks;
833     memset(&btif_hf_cb, 0, sizeof(btif_hf_cb));
834
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)
838     */
839 #if (defined(BTIF_HF_SERVICES) && (BTIF_HF_SERVICES & BTA_HFP_SERVICE_MASK))
840     btif_enable_service(BTA_HFP_SERVICE_ID);
841 #else
842     btif_enable_service(BTA_HSP_SERVICE_ID);
843 #endif
844
845     for (int i = 0; i < btif_max_hf_clients; i++)
846         clear_phone_state_multihf(i);
847
848     return BT_STATUS_SUCCESS;
849 }
850
851 /*******************************************************************************
852 **
853 ** Function         connect
854 **
855 ** Description     connect to headset
856 **
857 ** Returns         bt_status_t
858 **
859 *******************************************************************************/
860 static bt_status_t connect_int(bt_bdaddr_t *bd_addr, uint16_t uuid)
861 {
862     CHECK_BTHF_INIT();
863     int i;
864     for (i = 0; i < btif_max_hf_clients;)
865     {
866        if (((btif_hf_cb[i].state == BTHF_CONNECTION_STATE_CONNECTED) ||
867               (btif_hf_cb[i].state == BTHF_CONNECTION_STATE_SLC_CONNECTED)))
868            i++;
869        else
870            break;
871     }
872
873     if (i == btif_max_hf_clients)
874         return BT_STATUS_BUSY;
875
876     if (!is_connected(bd_addr))
877     {
878         btif_hf_cb[i].state = BTHF_CONNECTION_STATE_CONNECTING;
879         bdcpy(btif_hf_cb[i].connected_bda.address, bd_addr->address);
880
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;
884     }
885
886     return BT_STATUS_BUSY;
887 }
888
889 static bt_status_t connect( bt_bdaddr_t *bd_addr )
890 {
891     CHECK_BTHF_INIT();
892     return btif_queue_connect(UUID_SERVCLASS_AG_HANDSFREE, bd_addr, connect_int);
893 }
894
895 /*******************************************************************************
896 **
897 ** Function         disconnect
898 **
899 ** Description      disconnect from headset
900 **
901 ** Returns         bt_status_t
902 **
903 *******************************************************************************/
904 static bt_status_t disconnect( bt_bdaddr_t *bd_addr )
905 {
906     CHECK_BTHF_INIT();
907
908     int idx = btif_hf_idx_by_bdaddr(bd_addr);
909
910     if ((idx < 0) || (idx >= BTIF_HF_NUM_CB))
911     {
912         BTIF_TRACE_ERROR("%s: Invalid index %d", __FUNCTION__, idx);
913         return BT_STATUS_FAIL;
914     }
915
916     if (idx != BTIF_HF_INVALID_IDX)
917     {
918         BTA_AgClose(btif_hf_cb[idx].handle);
919         return BT_STATUS_SUCCESS;
920     }
921
922     return BT_STATUS_FAIL;
923 }
924
925 /*******************************************************************************
926 **
927 ** Function         connect_audio
928 **
929 ** Description     create an audio connection
930 **
931 ** Returns         bt_status_t
932 **
933 *******************************************************************************/
934 static bt_status_t connect_audio( bt_bdaddr_t *bd_addr )
935 {
936     CHECK_BTHF_INIT();
937
938     int idx = btif_hf_idx_by_bdaddr(bd_addr);
939
940     if ((idx < 0) || (idx >= BTIF_HF_NUM_CB))
941     {
942         BTIF_TRACE_ERROR("%s: Invalid index %d", __FUNCTION__, idx);
943         return BT_STATUS_FAIL;
944     }
945
946     /* Check if SLC is connected */
947     if (btif_hf_check_if_slc_connected() != BT_STATUS_SUCCESS)
948         return BT_STATUS_NOT_READY;
949
950     if (idx != BTIF_HF_INVALID_IDX)
951     {
952         BTA_AgAudioOpen(btif_hf_cb[idx].handle);
953
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;
958     }
959
960     return BT_STATUS_FAIL;
961 }
962
963 /*******************************************************************************
964 **
965 ** Function         disconnect_audio
966 **
967 ** Description      close the audio connection
968 **
969 ** Returns         bt_status_t
970 **
971 *******************************************************************************/
972 static bt_status_t disconnect_audio( bt_bdaddr_t *bd_addr )
973 {
974     CHECK_BTHF_INIT();
975
976     int idx = btif_hf_idx_by_bdaddr(bd_addr);
977
978     if ((idx < 0) || (idx >= BTIF_HF_NUM_CB))
979     {
980         BTIF_TRACE_ERROR("%s: Invalid index %d", __FUNCTION__, idx);
981         return BT_STATUS_FAIL;
982     }
983
984     if (idx != BTIF_HF_INVALID_IDX)
985     {
986         BTA_AgAudioClose(btif_hf_cb[idx].handle);
987         return BT_STATUS_SUCCESS;
988     }
989
990     return BT_STATUS_FAIL;
991 }
992
993 /*******************************************************************************
994 **
995 ** Function         start_voice_recognition
996 **
997 ** Description      start voice recognition
998 **
999 ** Returns          bt_status_t
1000 **
1001 *******************************************************************************/
1002 static bt_status_t start_voice_recognition(bt_bdaddr_t *bd_addr)
1003 {
1004     CHECK_BTHF_INIT();
1005     BOOLEAN is_success = FALSE;
1006     for (int i = 0; i < btif_max_hf_clients; i++)
1007     {
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)
1011         {
1012             tBTA_AG_RES_DATA ag_res;
1013             memset(&ag_res, 0, sizeof(ag_res));
1014             ag_res.state = 1;
1015             BTA_AgResult (btif_hf_cb[i].handle, BTA_AG_BVRA_RES, &ag_res);
1016             is_success = TRUE;
1017         }
1018     }
1019
1020     if (is_success)
1021     {
1022         return BT_STATUS_SUCCESS;
1023     }
1024     else
1025     {
1026         return BT_STATUS_NOT_READY;
1027     }
1028 }
1029
1030 /*******************************************************************************
1031 **
1032 ** Function         stop_voice_recognition
1033 **
1034 ** Description      stop voice recognition
1035 **
1036 ** Returns          bt_status_t
1037 **
1038 *******************************************************************************/
1039 static bt_status_t stop_voice_recognition(bt_bdaddr_t *bd_addr)
1040 {
1041     CHECK_BTHF_INIT();
1042     BOOLEAN is_success = FALSE;
1043     for (int i = 0; i < btif_max_hf_clients; i++)
1044     {
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)
1048         {
1049             tBTA_AG_RES_DATA ag_res;
1050             memset(&ag_res, 0, sizeof(ag_res));
1051             ag_res.state = 0;
1052             BTA_AgResult (btif_hf_cb[i].handle, BTA_AG_BVRA_RES, &ag_res);
1053             is_success = TRUE;
1054         }
1055     }
1056
1057     if (is_success)
1058     {
1059         return BT_STATUS_SUCCESS;
1060     }
1061     else
1062     {
1063         return BT_STATUS_NOT_READY;
1064     }
1065 }
1066
1067 /*******************************************************************************
1068 **
1069 ** Function         volume_control
1070 **
1071 ** Description      volume control
1072 **
1073 ** Returns          bt_status_t
1074 **
1075 *******************************************************************************/
1076 static bt_status_t volume_control(bthf_volume_type_t type, int volume,
1077                                                        bt_bdaddr_t *bd_addr)
1078 {
1079     CHECK_BTHF_INIT();
1080
1081     int idx = btif_hf_idx_by_bdaddr(bd_addr);
1082
1083     if ((idx < 0) || (idx >= BTIF_HF_NUM_CB))
1084     {
1085         BTIF_TRACE_ERROR("%s: Invalid index %d", __FUNCTION__, idx);
1086         return BT_STATUS_FAIL;
1087     }
1088
1089     tBTA_AG_RES_DATA ag_res;
1090     memset(&ag_res, 0, sizeof(tBTA_AG_RES_DATA));
1091     if (idx != BTIF_HF_INVALID_IDX)
1092     {
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,
1096                      &ag_res);
1097         return BT_STATUS_SUCCESS;
1098     }
1099
1100     return BT_STATUS_FAIL;
1101 }
1102
1103 /*******************************************************************************
1104 **
1105 ** Function         device_status_notification
1106 **
1107 ** Description      Combined device status change notification
1108 **
1109 ** Returns          bt_status_t
1110 **
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)
1114 {
1115     CHECK_BTHF_INIT();
1116
1117     if (is_connected(NULL))
1118     {
1119         /* send all indicators to BTA.
1120         ** BTA will make sure no duplicates are sent out
1121         */
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;
1129     }
1130
1131     return BT_STATUS_SUCCESS;
1132 }
1133
1134 /*******************************************************************************
1135 **
1136 ** Function         cops_response
1137 **
1138 ** Description      Response for COPS command
1139 **
1140 ** Returns          bt_status_t
1141 **
1142 *******************************************************************************/
1143 static bt_status_t cops_response(const char *cops, bt_bdaddr_t *bd_addr)
1144 {
1145     CHECK_BTHF_INIT();
1146
1147     int idx = btif_hf_idx_by_bdaddr(bd_addr);
1148
1149     if ((idx < 0) || (idx >= BTIF_HF_NUM_CB))
1150     {
1151         BTIF_TRACE_ERROR("%s: Invalid index %d", __FUNCTION__, idx);
1152         return BT_STATUS_FAIL;
1153     }
1154
1155     if (idx != BTIF_HF_INVALID_IDX)
1156     {
1157         tBTA_AG_RES_DATA    ag_res;
1158
1159         /* Format the response */
1160         sprintf (ag_res.str, "0,0,\"%.16s\"", cops);
1161         ag_res.ok_flag = BTA_AG_OK_DONE;
1162
1163         BTA_AgResult (btif_hf_cb[idx].handle, BTA_AG_COPS_RES, &ag_res);
1164         return BT_STATUS_SUCCESS;
1165     }
1166     return BT_STATUS_FAIL;
1167 }
1168
1169 /*******************************************************************************
1170 **
1171 ** Function         cind_response
1172 **
1173 ** Description      Response for CIND command
1174 **
1175 ** Returns          bt_status_t
1176 **
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)
1182 {
1183     CHECK_BTHF_INIT();
1184
1185     int idx = btif_hf_idx_by_bdaddr(bd_addr);
1186
1187     if ((idx < 0) || (idx >= BTIF_HF_NUM_CB))
1188     {
1189         BTIF_TRACE_ERROR("%s: Invalid index %d", __FUNCTION__, idx);
1190         return BT_STATUS_FAIL;
1191     }
1192
1193     if (idx != BTIF_HF_INVALID_IDX)
1194     {
1195         tBTA_AG_RES_DATA    ag_res;
1196
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
1200         **/
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 */
1209
1210         BTA_AgResult (btif_hf_cb[idx].handle, BTA_AG_CIND_RES, &ag_res);
1211
1212         return BT_STATUS_SUCCESS;
1213     }
1214
1215     return BT_STATUS_FAIL;
1216 }
1217
1218 /*******************************************************************************
1219 **
1220 ** Function         formatted_at_response
1221 **
1222 ** Description      Pre-formatted AT response, typically in response to unknown AT cmd
1223 **
1224 ** Returns          bt_status_t
1225 **
1226 *******************************************************************************/
1227 static bt_status_t formatted_at_response(const char *rsp, bt_bdaddr_t *bd_addr)
1228 {
1229     CHECK_BTHF_INIT();
1230     tBTA_AG_RES_DATA    ag_res;
1231     int idx = btif_hf_idx_by_bdaddr(bd_addr);
1232
1233     if ((idx < 0) || (idx >= BTIF_HF_NUM_CB))
1234     {
1235         BTIF_TRACE_ERROR("%s: Invalid index %d", __FUNCTION__, idx);
1236         return BT_STATUS_FAIL;
1237     }
1238
1239     if (idx != BTIF_HF_INVALID_IDX)
1240     {
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);
1245
1246         return BT_STATUS_SUCCESS;
1247     }
1248
1249     return BT_STATUS_FAIL;
1250 }
1251
1252 /*******************************************************************************
1253 **
1254 ** Function         at_response
1255 **
1256 ** Description      ok/error response
1257 **
1258 ** Returns          bt_status_t
1259 **
1260 *******************************************************************************/
1261 static bt_status_t at_response(bthf_at_response_t response_code,
1262                                     int error_code, bt_bdaddr_t *bd_addr)
1263 {
1264     CHECK_BTHF_INIT();
1265
1266     int idx = btif_hf_idx_by_bdaddr(bd_addr);
1267
1268     if ((idx < 0) || (idx >= BTIF_HF_NUM_CB))
1269     {
1270         BTIF_TRACE_ERROR("%s: Invalid index %d", __FUNCTION__, idx);
1271         return BT_STATUS_FAIL;
1272     }
1273
1274     if (idx != BTIF_HF_INVALID_IDX)
1275     {
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)
1279         {
1280             send_bvra_update(idx);
1281             send_bvra_other_index = FALSE;
1282         }
1283         return BT_STATUS_SUCCESS;
1284     }
1285
1286     return BT_STATUS_FAIL;
1287 }
1288
1289 /*******************************************************************************
1290 **
1291 ** Function         clcc_response
1292 **
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)
1296 **
1297 ** Returns          bt_status_t
1298 **
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)
1304 {
1305     CHECK_BTHF_INIT();
1306
1307     int idx = btif_hf_idx_by_bdaddr(bd_addr);
1308
1309     if ((idx < 0) || (idx >= BTIF_HF_NUM_CB))
1310     {
1311         BTIF_TRACE_ERROR("%s: Invalid index %d", __FUNCTION__, idx);
1312         return BT_STATUS_FAIL;
1313     }
1314
1315     if (idx != BTIF_HF_INVALID_IDX)
1316     {
1317         tBTA_AG_RES_DATA    ag_res;
1318         int                 xx;
1319
1320         memset (&ag_res, 0, sizeof (ag_res));
1321
1322         /* Format the response */
1323         if (index == 0)
1324         {
1325             ag_res.ok_flag = BTA_AG_OK_DONE;
1326         }
1327         else
1328         {
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);
1333
1334             if (number)
1335             {
1336                 if ((type == BTHF_CALL_ADDRTYPE_INTERNATIONAL) && (*number != '+'))
1337                     sprintf (&ag_res.str[xx], ",\"+%s\",%d", number, type);
1338                 else
1339                     sprintf (&ag_res.str[xx], ",\"%s\",%d", number, type);
1340             }
1341         }
1342         BTA_AgResult (btif_hf_cb[idx].handle, BTA_AG_CLCC_RES, &ag_res);
1343
1344         return BT_STATUS_SUCCESS;
1345     }
1346
1347     return BT_STATUS_FAIL;
1348 }
1349
1350 /*******************************************************************************
1351 **
1352 ** Function         phone_state_change
1353 **
1354 ** Description      notify of a call state change
1355 **                  number & type: valid only for incoming & waiting call
1356 **
1357 ** Returns          bt_status_t
1358 **
1359 *******************************************************************************/
1360
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)
1363 {
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;
1368     int idx, i;
1369
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)
1373         idx = hf_idx;
1374     else
1375         idx = btif_hf_latest_connected_idx();
1376
1377     BTIF_TRACE_IMP("phone_state_change: idx = %d", idx);
1378
1379     /* Check if SLC is connected */
1380     if (btif_hf_check_if_slc_connected() != BT_STATUS_SUCCESS)
1381         return BT_STATUS_NOT_READY;
1382
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));
1387
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)
1390     {
1391         BTIF_TRACE_DEBUG("%s: Phone on hook", __FUNCTION__);
1392
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))
1397         {
1398             BTIF_TRACE_DEBUG("%s: Record call termination timestamp", __FUNCTION__);
1399             clock_gettime(CLOCK_MONOTONIC, &btif_hf_cb[0].call_end_timestamp);
1400         }
1401         BTA_AgResult (BTA_AG_HANDLE_ALL, BTA_AG_END_CALL_RES, NULL);
1402         hf_idx = BTIF_HF_INVALID_IDX;
1403
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);
1407
1408         goto update_call_states;
1409     }
1410
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
1416     **
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
1421     */
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) )
1424     {
1425         BTIF_TRACE_IMP("%s: Active/Held call notification received without call setup update",
1426                           __FUNCTION__);
1427
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.
1433         */
1434         if (call_setup_state != BTHF_CALL_STATE_IDLE)
1435            res = BTA_AG_MULTI_CALL_RES;
1436         else
1437            res = BTA_AG_OUT_CALL_CONN_RES;
1438         BTA_AgResult(BTA_AG_HANDLE_ALL, res, &ag_res);
1439         activeCallUpdated = TRUE;
1440     }
1441
1442     /* Ringing call changed? */
1443     if (call_setup_state != btif_hf_cb[idx].call_setup_state)
1444     {
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));
1449
1450         switch (call_setup_state)
1451         {
1452             case BTHF_CALL_STATE_IDLE:
1453             {
1454                 switch (btif_hf_cb[idx].call_setup_state)
1455                 {
1456                     case BTHF_CALL_STATE_INCOMING:
1457                         if (num_active > btif_hf_cb[idx].num_active)
1458                         {
1459                             res = BTA_AG_IN_CALL_CONN_RES;
1460                             ag_res.audio_handle = btif_hf_cb[idx].handle;
1461                         }
1462                         else if (num_held > btif_hf_cb[idx].num_held)
1463                             res = BTA_AG_IN_CALL_HELD_RES;
1464                         else
1465                             res = BTA_AG_CALL_CANCEL_RES;
1466                         break;
1467                     case BTHF_CALL_STATE_DIALING:
1468                     case BTHF_CALL_STATE_ALERTING:
1469                         if (num_active > btif_hf_cb[idx].num_active)
1470                         {
1471                             ag_res.audio_handle = BTA_AG_HANDLE_SCO_NO_CHANGE;
1472                             res = BTA_AG_OUT_CALL_CONN_RES;
1473                         }
1474                         else
1475                             res = BTA_AG_CALL_CANCEL_RES;
1476                         break;
1477                     default:
1478                         BTIF_TRACE_ERROR("%s: Incorrect Call setup state transition", __FUNCTION__);
1479                         status = BT_STATUS_PARM_INVALID;
1480                         break;
1481                 }
1482             } break;
1483
1484             case BTHF_CALL_STATE_INCOMING:
1485                 if (num_active || num_held)
1486                     res = BTA_AG_CALL_WAIT_RES;
1487                 else
1488                     res = BTA_AG_IN_CALL_RES;
1489                 if (number)
1490                 {
1491                     int xx = 0;
1492                     if ((type == BTHF_CALL_ADDRTYPE_INTERNATIONAL) && (*number != '+'))
1493                         xx = sprintf (ag_res.str, "\"+%s\"", number);
1494                     else
1495                         xx = sprintf (ag_res.str, "\"%s\"", number);
1496                     ag_res.num = type;
1497
1498                     if (res == BTA_AG_CALL_WAIT_RES)
1499                         sprintf(&ag_res.str[xx], ",%d", type);
1500                 }
1501                 break;
1502             case BTHF_CALL_STATE_DIALING:
1503                 if (!(num_active + num_held))
1504                 {
1505                     ag_res.audio_handle = btif_hf_cb[idx].handle;
1506                 }
1507                 else
1508                 {
1509                     BTIF_TRACE_DEBUG("%s: Already in a call, don't set audio handle", __FUNCTION__);
1510                 }
1511                 res = BTA_AG_OUT_CALL_ORIG_RES;
1512                 break;
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))
1517                 {
1518                     ag_res.audio_handle = btif_hf_cb[idx].handle;
1519                 }
1520                 else
1521                 {
1522                     BTIF_TRACE_DEBUG("%s: Already in a call or prev call state was dialing,"
1523                                                            " don't set audio handle", __FUNCTION__);
1524                 }
1525                 res = BTA_AG_OUT_CALL_ALERT_RES;
1526                 break;
1527             default:
1528                 BTIF_TRACE_ERROR("%s: Incorrect new ringing call state", __FUNCTION__);
1529                 status = BT_STATUS_PARM_INVALID;
1530                 break;
1531         }
1532         BTIF_TRACE_IMP("%s: Call setup state changed. res=%d, audio_handle=%d", __FUNCTION__, res, ag_res.audio_handle);
1533
1534         if (res)
1535             BTA_AgResult(BTA_AG_HANDLE_ALL, res, &ag_res);
1536
1537         /* if call setup is idle, we have already updated call indicator, jump out */
1538         if (call_setup_state == BTHF_CALL_STATE_IDLE)
1539         {
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;
1544         }
1545     }
1546
1547     memset(&ag_res, 0, sizeof(tBTA_AG_RES_DATA));
1548
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
1552     **/
1553     if (!activeCallUpdated && ((num_active + num_held) !=
1554                  (btif_hf_cb[idx].num_active + btif_hf_cb[idx].num_held)) )
1555     {
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);
1558     }
1559
1560     /* Held Changed? */
1561     if (num_held != btif_hf_cb[idx].num_held  ||
1562         ((num_active == 0) && ((num_held + btif_hf_cb[idx].num_held) > 1)))
1563     {
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)));
1567     }
1568
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) )
1574     {
1575         BTIF_TRACE_IMP("%s: Calls swapped", __FUNCTION__);
1576         send_indicator_update(BTA_AG_IND_CALLHELD, 1);
1577     }
1578
1579 update_call_states:
1580     for (i = 0; i < btif_max_hf_clients; i++)
1581     {
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;
1586         }
1587     }
1588     return status;
1589 }
1590
1591 /*******************************************************************************
1592 **
1593 ** Function         btif_hf_is_call_idle
1594 **
1595 ** Description      returns true if no call is in progress
1596 **
1597 ** Returns          bt_status_t
1598 **
1599 *******************************************************************************/
1600 BOOLEAN btif_hf_is_call_idle()
1601 {
1602     int i, j = 1;
1603
1604     if (bt_hf_callbacks == NULL)
1605     {
1606         return TRUE;
1607     }
1608     for (i = 0; i < btif_max_hf_clients; i++)
1609     {
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));
1616     }
1617
1618     if (j)
1619     {
1620         BTIF_TRACE_EVENT("%s: call state idle ", __FUNCTION__);
1621         return TRUE;
1622     }
1623     else
1624     {
1625         return FALSE;
1626     }
1627
1628     return TRUE;
1629 }
1630
1631 /*******************************************************************************
1632 **
1633 ** Function         btif_hf_call_terminated_recently
1634 **
1635 ** Description      Checks if a call has been terminated
1636 **
1637 ** Returns          bt_status_t
1638 **
1639 *******************************************************************************/
1640 BOOLEAN btif_hf_call_terminated_recently()
1641 {
1642       struct timespec         now;
1643
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)
1647       {
1648           return TRUE;
1649       }
1650       else
1651       {
1652           btif_hf_cb[0].call_end_timestamp.tv_sec = 0;
1653           return FALSE;
1654       }
1655 }
1656
1657 /*******************************************************************************
1658 **
1659 ** Function         cleanup
1660 **
1661 ** Description      Closes the HF interface
1662 **
1663 ** Returns          bt_status_t
1664 **
1665 *******************************************************************************/
1666 static void  cleanup( void )
1667 {
1668     BTIF_TRACE_IMP("%s", __FUNCTION__);
1669
1670 #if (defined(BTIF_HF_SERVICES) && (BTIF_HF_SERVICES & BTA_HFP_SERVICE_MASK))
1671     btif_disable_service(BTA_HFP_SERVICE_ID);
1672 #else
1673     btif_disable_service(BTA_HSP_SERVICE_ID);
1674 #endif
1675 }
1676
1677 /*******************************************************************************
1678 **
1679 ** Function         configure_wbs
1680 **
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.
1684 **
1685 ** Returns          bt_status_t
1686 **
1687 *******************************************************************************/
1688 static bt_status_t  configure_wbs( bt_bdaddr_t *bd_addr , bthf_wbs_config_t config )
1689 {
1690     CHECK_BTHF_INIT();
1691
1692     int idx = btif_hf_idx_by_bdaddr(bd_addr);
1693
1694     if ((idx < 0) || (idx >= BTIF_HF_NUM_CB))
1695     {
1696         BTIF_TRACE_ERROR("%s: Invalid index %d", __FUNCTION__, idx);
1697         return BT_STATUS_FAIL;
1698     }
1699
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);
1705     else
1706         BTA_AgSetCodec(btif_hf_cb[idx].handle,BTA_AG_CODEC_NONE);
1707
1708     return BT_STATUS_SUCCESS;
1709 }
1710
1711 /*******************************************************************************
1712 **
1713 ** Function         bind_response
1714 **
1715 ** Description      response for BIND READ command
1716 **                  Can be iteratively called for each Hf indicator.
1717 **
1718 ** Returns          bt_status_t
1719 **
1720 *******************************************************************************/
1721 static bt_status_t bind_response(int anum, bthf_hf_indicator_status_t status,
1722                                bt_bdaddr_t *bd_addr)
1723 {
1724     CHECK_BTHF_INIT();
1725
1726     int idx = btif_hf_idx_by_bdaddr(bd_addr);
1727
1728     if ((idx < 0) || (idx >= BTIF_HF_NUM_CB))
1729     {
1730         BTIF_TRACE_ERROR("%s: Invalid index %d", __FUNCTION__, idx);
1731         return BT_STATUS_FAIL;
1732     }
1733
1734     if (idx != BTIF_HF_INVALID_IDX)
1735     {
1736         tBTA_AG_RES_DATA    ag_res;
1737         int                 xx;
1738
1739         memset (&ag_res, 0, sizeof (ag_res));
1740
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);
1744
1745         BTA_AgResult (btif_hf_cb[idx].handle, BTA_AG_BIND_RES, &ag_res);
1746
1747         return BT_STATUS_SUCCESS;
1748     }
1749
1750     return BT_STATUS_FAIL;
1751 }
1752
1753 /*******************************************************************************
1754 **
1755 ** Function         bind_string_response
1756 **
1757 ** Description      response for BIND TEST command
1758 **
1759 ** Returns          bt_status_t
1760 **
1761 *******************************************************************************/
1762 static bt_status_t bind_string_response(const char* res,
1763                                bt_bdaddr_t *bd_addr)
1764 {
1765     CHECK_BTHF_INIT();
1766
1767     int idx = btif_hf_idx_by_bdaddr(bd_addr);
1768
1769     if ((idx < 0) || (idx >= BTIF_HF_NUM_CB))
1770     {
1771         BTIF_TRACE_ERROR("%s: Invalid index %d", __FUNCTION__, idx);
1772         return BT_STATUS_FAIL;
1773     }
1774
1775     if (idx != BTIF_HF_INVALID_IDX)
1776     {
1777         tBTA_AG_RES_DATA    ag_res;
1778         int                 xx;
1779
1780         memset (&ag_res, 0, sizeof (ag_res));
1781
1782         /* Format the response */
1783         xx = snprintf (ag_res.str, sizeof(ag_res.str), "%s", res);
1784
1785         BTA_AgResult (btif_hf_cb[idx].handle, BTA_AG_BIND_RES, &ag_res);
1786
1787         return BT_STATUS_SUCCESS;
1788     }
1789
1790     return BT_STATUS_FAIL;
1791 }
1792
1793 static void set_voip_network_type_wifi_hci_cmd_complete(tBTM_VSC_CMPL* p_data)
1794 {
1795     UINT8         *stream,  status, subcmd;
1796     UINT16        opcode, length;
1797
1798     if (p_data && (stream = (UINT8*)p_data->p_param_buf))
1799     {
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)
1807         {
1808             BTIF_TRACE_DEBUG("btm_SetVoipNetworkTypeWifi status success");
1809         }
1810     }
1811 }
1812
1813 /*******************************************************************************
1814 **
1815 ** Function         voip_network_type_wifi
1816 **
1817 ** Description      BT app updates the connectivity network used for VOIP as Wifi
1818 **
1819 ** Returns          bt_status_t
1820 **
1821 *******************************************************************************/
1822 static bt_status_t voip_network_type_wifi(bthf_voip_state_t isVoipStarted,
1823                                           bthf_voip_call_network_type_t isNetworkWifi)
1824 {
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();
1829
1830     CHECK_BTHF_INIT();
1831
1832     if ((idx < 0) || (idx >= BTIF_HF_NUM_CB))
1833     {
1834         BTIF_TRACE_ERROR("%s: Invalid index %d", __FUNCTION__, idx);
1835         return BT_STATUS_FAIL;
1836     }
1837
1838     p_cursor = cmd;
1839     memset(cmd, 0, 3);
1840
1841     *p_cursor++ = sub_cmd;
1842     *p_cursor++ = isVoipStarted;
1843     *p_cursor++ = isNetworkWifi;
1844
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)
1847     {
1848         BTIF_TRACE_ERROR("%s: status %d", __FUNCTION__, status);
1849         return BT_STATUS_FAIL;
1850     }
1851
1852     return BT_STATUS_SUCCESS;
1853
1854 }
1855
1856 static const bthf_interface_t bthfInterface = {
1857     sizeof(bthfInterface),
1858     init,
1859     connect,
1860     disconnect,
1861     connect_audio,
1862     disconnect_audio,
1863     start_voice_recognition,
1864     stop_voice_recognition,
1865     volume_control,
1866     device_status_notification,
1867     cops_response,
1868     cind_response,
1869     formatted_at_response,
1870     at_response,
1871     clcc_response,
1872     phone_state_change,
1873     cleanup,
1874     configure_wbs,
1875     bind_response,
1876     bind_string_response,
1877     voip_network_type_wifi,
1878 };
1879
1880 /*******************************************************************************
1881 **
1882 ** Function         btif_hf_execute_service
1883 **
1884 ** Description      Initializes/Shuts down the service
1885 **
1886 ** Returns          BT_STATUS_SUCCESS on success, BT_STATUS_FAIL otherwise
1887 **
1888 *******************************************************************************/
1889 bt_status_t btif_hf_execute_service(BOOLEAN b_enable)
1890 {
1891     char * p_service_names[] = BTIF_HF_SERVICE_NAMES;
1892     int i;
1893     uint8_t no_of_codecs = 0;
1894     uint8_t* codecs;
1895     char value[PROPERTY_VALUE_MAX];
1896
1897     BTIF_TRACE_IMP("%s: enable: %d", __FUNCTION__, b_enable);
1898
1899     if (b_enable)
1900     {
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);
1904         if (codecs != NULL)
1905         {
1906             for (i = 0; i < no_of_codecs; i++)
1907             {
1908                 if (codecs[i] == BTA_AG_MSBC_CODEC)
1909                 {
1910                     btif_features |= BTA_AG_FEAT_CODEC;
1911                     break;
1912                 }
1913             }
1914         }
1915         else
1916         {
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;
1921         }
1922
1923         for (i = 0; i < btif_max_hf_clients; i++)
1924         {
1925             BTA_AgRegister(BTIF_HF_SERVICES, BTIF_HF_SECURITY,
1926                 btif_features, p_service_names, bthf_hf_id[i]);
1927         }
1928     }
1929     else {
1930         if (bt_hf_callbacks)
1931         {
1932             BTIF_TRACE_IMP("%s: setting call backs to NULL", __FUNCTION__);
1933             bt_hf_callbacks = NULL;
1934         }
1935         /* De-register AG */
1936         for (i = 0; i < btif_max_hf_clients; i++)
1937         {
1938             BTA_AgDeregister(btif_hf_cb[i].handle);
1939         }
1940         /* Disable AG */
1941         BTA_AgDisable();
1942     }
1943     BTIF_TRACE_IMP("%s: enable: %d completed", __FUNCTION__, b_enable);
1944     return BT_STATUS_SUCCESS;
1945 }
1946
1947 /*******************************************************************************
1948 **
1949 ** Function         btif_hf_get_interface
1950 **
1951 ** Description      Get the hf callback interface
1952 **
1953 ** Returns          bthf_interface_t
1954 **
1955 *******************************************************************************/
1956 const bthf_interface_t *btif_hf_get_interface()
1957 {
1958     BTIF_TRACE_EVENT("%s", __FUNCTION__);
1959     return &bthfInterface;
1960 }