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