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