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