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