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