1/******************************************************************************
2 *
3 *  Copyright (c) 2014 The Android Open Source Project
4 *  Copyright (C) 2009-2012 Broadcom Corporation
5 *
6 *  Licensed under the Apache License, Version 2.0 (the "License");
7 *  you may not use this file except in compliance with the License.
8 *  You may obtain a copy of the License at:
9 *
10 *  http://www.apache.org/licenses/LICENSE-2.0
11 *
12 *  Unless required by applicable law or agreed to in writing, software
13 *  distributed under the License is distributed on an "AS IS" BASIS,
14 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 *  See the License for the specific language governing permissions and
16 *  limitations under the License.
17 *
18 ******************************************************************************/
19
20/*******************************************************************************
21 *
22 *  Filename:      btif_hf_client.c
23 *
24 *  Description:   Handsfree Profile (HF role) Bluetooth Interface
25 *
26 *  Notes:
27 *  a) Lifecycle of a control block
28 *  Control block handles the lifecycle for a particular remote device's
29 *  connection. The connection can go via the classic phases but more
30 *  importantly there's only two messages from BTA that affect this.
31 *  BTA_HF_CLIENT_OPEN_EVT and BTA_HF_CLIENT_CLOSE_EVT. Since the API between
32 *  BTIF and BTA is controlled entirely by handles it's important to know where
33 *  the handles are created and destroyed. Handles can be created at two
34 *  locations:
35 *  -- While connect() is called from BTIF. This is an outgoing connection
36 *  -- While accepting an incoming connection (see BTA_HF_CLIENT_OPEN_EVT
37 *  handling).
38 *
39 *  The destruction or rather reuse of handles can be done when
40 *  BTA_HF_CLIENT_CLOSE_EVT is called. Refer to the event handling for details
41 *  of this.
42 *
43 ******************************************************************************/
44
45#define LOG_TAG "bt_btif_hfc"
46
47#include <stdlib.h>
48#include <string.h>
49
50#include <hardware/bluetooth.h>
51#include <hardware/bt_hf_client.h>
52
53#include "bt_utils.h"
54#include "bta_hf_client_api.h"
55#include "btcore/include/bdaddr.h"
56#include "btif_common.h"
57#include "btif_profile_queue.h"
58#include "btif_util.h"
59#include "osi/include/osi.h"
60#include "osi/include/properties.h"
61
62/*******************************************************************************
63 *  Constants & Macros
64 ******************************************************************************/
65
66#ifndef BTIF_HF_CLIENT_SERVICE_NAME
67#define BTIF_HF_CLIENT_SERVICE_NAME ("Handsfree")
68#endif
69
70#ifndef BTIF_HF_CLIENT_SECURITY
71#define BTIF_HF_CLIENT_SECURITY (BTA_SEC_AUTHENTICATE | BTA_SEC_ENCRYPT)
72#endif
73
74#ifndef BTIF_HF_CLIENT_FEATURES
75#define BTIF_HF_CLIENT_FEATURES                                                \
76  (BTA_HF_CLIENT_FEAT_ECNR | BTA_HF_CLIENT_FEAT_3WAY |                         \
77   BTA_HF_CLIENT_FEAT_CLI | BTA_HF_CLIENT_FEAT_VREC | BTA_HF_CLIENT_FEAT_VOL | \
78   BTA_HF_CLIENT_FEAT_ECS | BTA_HF_CLIENT_FEAT_ECC | BTA_HF_CLIENT_FEAT_CODEC)
79#endif
80
81/*******************************************************************************
82 *  Local type definitions
83 ******************************************************************************/
84/* BTIF-HF control block to map bdaddr to BTA handle */
85typedef struct {
86  uint16_t handle;                       // Handle obtained frm the BTA
87  bt_bdaddr_t peer_bda;                  // Device corresponding to handle
88  bthf_client_connection_state_t state;  // State of current connection
89  tBTA_HF_CLIENT_PEER_FEAT peer_feat;    // HF features
90  tBTA_HF_CLIENT_CHLD_FEAT chld_feat;    // AT+CHLD=<> command features
91} btif_hf_client_cb_t;
92
93/* Max devices supported by BTIF (useful to match the value in BTA) */
94#define HF_CLIENT_MAX_DEVICES 10
95typedef struct {
96  btif_hf_client_cb_t cb[HF_CLIENT_MAX_DEVICES];
97} btif_hf_client_cb_arr_t;
98
99/******************************************************************************
100 * Local function declarations
101 ******************************************************************************/
102btif_hf_client_cb_t* btif_hf_client_get_cb_by_handle(uint16_t handle);
103btif_hf_client_cb_t* btif_hf_client_get_cb_by_bda(const uint8_t* addr);
104bool is_connected(const btif_hf_client_cb_t* cb);
105
106/*******************************************************************************
107 *  Static variables
108 ******************************************************************************/
109static bthf_client_callbacks_t* bt_hf_client_callbacks = NULL;
110
111char btif_hf_client_version[PROPERTY_VALUE_MAX];
112
113#define CHECK_BTHF_CLIENT_INIT()                                        \
114  do {                                                                  \
115    if (bt_hf_client_callbacks == NULL) {                               \
116      BTIF_TRACE_WARNING("BTHF CLIENT: %s: not initialized", __func__); \
117      return BT_STATUS_NOT_READY;                                       \
118    } else {                                                            \
119      BTIF_TRACE_EVENT("BTHF CLIENT: %s", __func__);                    \
120    }                                                                   \
121  } while (0)
122
123#define CHECK_BTHF_CLIENT_SLC_CONNECTED(cb)                                  \
124  do {                                                                       \
125    if (bt_hf_client_callbacks == NULL) {                                    \
126      BTIF_TRACE_WARNING("BTHF CLIENT: %s: not initialized", __func__);      \
127      return BT_STATUS_NOT_READY;                                            \
128    } else if ((cb)->state != BTHF_CLIENT_CONNECTION_STATE_SLC_CONNECTED) {  \
129      BTIF_TRACE_WARNING("BTHF CLIENT: %s: SLC connection not up. state=%s", \
130                         __func__, dump_hf_conn_state((cb)->state));         \
131      return BT_STATUS_NOT_READY;                                            \
132    } else {                                                                 \
133      BTIF_TRACE_EVENT("BTHF CLIENT: %s", __func__);                         \
134    }                                                                        \
135  } while (0)
136
137static btif_hf_client_cb_arr_t btif_hf_client_cb_arr;
138
139/*******************************************************************************
140 *  Static functions
141 ******************************************************************************/
142
143/*******************************************************************************
144 *
145 * Function        btif_in_hf_client_generic_evt
146 *
147 * Description     Processes generic events to be sent to JNI that are not
148 *                 triggered from the BTA.
149 *                 Always runs in BTIF context
150 *
151 * Returns          void
152 *
153 ******************************************************************************/
154static void btif_in_hf_client_generic_evt(uint16_t event, char* p_param) {
155  BTIF_TRACE_DEBUG("%s", __func__);
156  bt_bdaddr_t* bd_addr = (bt_bdaddr_t*)p_param;
157  btif_hf_client_cb_t* cb = btif_hf_client_get_cb_by_bda(bd_addr->address);
158  if (cb == NULL || !is_connected(cb)) {
159    BTIF_TRACE_ERROR("%s: failed to find block for bda", __func__);
160  }
161
162  BTIF_TRACE_EVENT("%s: event=%d", __func__, event);
163  switch (event) {
164    case BTIF_HF_CLIENT_CB_AUDIO_CONNECTING: {
165      HAL_CBACK(bt_hf_client_callbacks, audio_state_cb, &cb->peer_bda,
166                (bthf_client_audio_state_t)BTHF_AUDIO_STATE_CONNECTING);
167    } break;
168    default: {
169      BTIF_TRACE_WARNING("%s: : Unknown event 0x%x", __func__, event);
170    } break;
171  }
172}
173
174/*******************************************************************************
175 *  Functions
176 ******************************************************************************/
177bool is_connected(const btif_hf_client_cb_t* cb) {
178  if ((cb->state == BTHF_CLIENT_CONNECTION_STATE_CONNECTED) ||
179      (cb->state == BTHF_CLIENT_CONNECTION_STATE_SLC_CONNECTED))
180    return true;
181
182  BTIF_TRACE_ERROR("%s: not connected!", __func__);
183  return false;
184}
185
186/*******************************************************************************
187 *
188 * Function        btif_hf_client_get_cb_by_handle
189 *
190 * Description     Get control block by handle
191 *
192 * Returns         btif_hf_client_cb_t pointer if available NULL otherwise
193 *
194 ******************************************************************************/
195btif_hf_client_cb_t* btif_hf_client_get_cb_by_handle(uint16_t handle) {
196  BTIF_TRACE_DEBUG("%s: cb by handle %d", __func__, handle);
197  for (int i = 0; i < HF_CLIENT_MAX_DEVICES; i++) {
198    // Block is valid only if it is allocated i.e. state is not DISCONNECTED
199    if (btif_hf_client_cb_arr.cb[i].state !=
200            BTHF_CLIENT_CONNECTION_STATE_DISCONNECTED &&
201        btif_hf_client_cb_arr.cb[i].handle == handle) {
202      return &btif_hf_client_cb_arr.cb[i];
203    }
204  }
205  BTIF_TRACE_ERROR("%s: could not find block for handle %d", __func__, handle);
206  return NULL;
207}
208
209/*******************************************************************************
210 *
211 * Function        btif_hf_client_get_cb_by_bda
212 *
213 * Description     Get control block by bda
214 *
215 * Returns         btif_hf_client_cb_t pointer if available NULL otherwise
216 *
217 ******************************************************************************/
218btif_hf_client_cb_t* btif_hf_client_get_cb_by_bda(const uint8_t* bd_addr) {
219  BTIF_TRACE_DEBUG("%s incoming addr %02x:%02x:%02x:%02x:%02x:%02x", __func__,
220                   bd_addr[0], bd_addr[1], bd_addr[2], bd_addr[3], bd_addr[4],
221                   bd_addr[5]);
222
223  for (int i = 0; i < HF_CLIENT_MAX_DEVICES; i++) {
224    // Block is valid only if it is allocated i.e. state is not DISCONNECTED
225    if (btif_hf_client_cb_arr.cb[i].state !=
226            BTHF_CLIENT_CONNECTION_STATE_DISCONNECTED &&
227        !bdcmp(btif_hf_client_cb_arr.cb[i].peer_bda.address, bd_addr)) {
228      return &btif_hf_client_cb_arr.cb[i];
229    }
230  }
231  BTIF_TRACE_ERROR("%s: could not find block for bdaddr", __func__);
232  return NULL;
233}
234
235/*******************************************************************************
236 *
237 * Function        btif_hf_client_allocate_cb
238 *
239 * Description     Get control block by bda
240 *
241 * Returns         btif_hf_client_cb_t pointer if available NULL otherwise
242 *
243 ******************************************************************************/
244btif_hf_client_cb_t* btif_hf_client_allocate_cb() {
245  for (int i = 0; i < HF_CLIENT_MAX_DEVICES; i++) {
246    btif_hf_client_cb_t* cb = &btif_hf_client_cb_arr.cb[i];
247    if (cb->state == BTHF_CLIENT_CONNECTION_STATE_DISCONNECTED) {
248      return cb;
249    }
250  }
251  BTIF_TRACE_ERROR("%s: unable to allocate control block", __func__);
252  return NULL;
253}
254
255
256/*****************************************************************************
257 *
258 *   btif hf api functions (no context switch)
259 *
260 ****************************************************************************/
261
262/*******************************************************************************
263 *
264 * Function         btif_hf_client_init
265 *
266 * Description     initializes the hf interface
267 *
268 * Returns         bt_status_t
269 *
270 ******************************************************************************/
271static bt_status_t init(bthf_client_callbacks_t* callbacks) {
272  BTIF_TRACE_EVENT("%s", __func__);
273
274  bt_hf_client_callbacks = callbacks;
275
276  btif_enable_service(BTA_HFP_HS_SERVICE_ID);
277
278  memset(&btif_hf_client_cb_arr, 0, sizeof(btif_hf_client_cb_arr_t));
279
280  return BT_STATUS_SUCCESS;
281}
282
283/*******************************************************************************
284 *
285 * Function         connect
286 *
287 * Description     connect to audio gateway
288 *
289 * Returns         bt_status_t
290 *
291 ******************************************************************************/
292static bt_status_t connect_int(bt_bdaddr_t* bd_addr, uint16_t uuid) {
293  btif_hf_client_cb_t* cb = btif_hf_client_allocate_cb();
294  if (cb == NULL) {
295    BTIF_TRACE_ERROR("%s: could not allocate block!", __func__);
296    return BT_STATUS_BUSY;
297  }
298
299  bdcpy(cb->peer_bda.address, bd_addr->address);
300  if (is_connected(cb)) return BT_STATUS_BUSY;
301
302  cb->state = BTHF_CLIENT_CONNECTION_STATE_CONNECTING;
303  bdcpy(cb->peer_bda.address, bd_addr->address);
304
305  /* Open HF connection to remote device and get the relevant handle.
306   * The handle is valid until we have called BTA_HfClientClose or the LL
307   * has notified us of channel close due to remote closing, error etc.
308   */
309  BTA_HfClientOpen(cb->peer_bda.address, BTIF_HF_CLIENT_SECURITY, &cb->handle);
310
311  return BT_STATUS_SUCCESS;
312}
313
314static bt_status_t connect(bt_bdaddr_t* bd_addr) {
315  BTIF_TRACE_EVENT("HFP Client version is  %s", btif_hf_client_version);
316  CHECK_BTHF_CLIENT_INIT();
317  return btif_queue_connect(UUID_SERVCLASS_HF_HANDSFREE, bd_addr, connect_int);
318}
319
320/*******************************************************************************
321 *
322 * Function         disconnect
323 *
324 * Description      disconnect from audio gateway
325 *
326 * Returns         bt_status_t
327 *
328 ******************************************************************************/
329static bt_status_t disconnect(const bt_bdaddr_t* bd_addr) {
330  CHECK_BTHF_CLIENT_INIT();
331
332  btif_hf_client_cb_t* cb = btif_hf_client_get_cb_by_bda(bd_addr->address);
333  if (cb != NULL) {
334    BTA_HfClientClose(cb->handle);
335    return BT_STATUS_SUCCESS;
336  } else {
337    return BT_STATUS_BUSY;
338  }
339}
340
341/*******************************************************************************
342 *
343 * Function         connect_audio
344 *
345 * Description     create an audio connection
346 *
347 * Returns         bt_status_t
348 *
349 ******************************************************************************/
350static bt_status_t connect_audio(const bt_bdaddr_t* bd_addr) {
351  btif_hf_client_cb_t* cb = btif_hf_client_get_cb_by_bda(bd_addr->address);
352  if (cb == NULL || !is_connected(cb)) return BT_STATUS_FAIL;
353
354  CHECK_BTHF_CLIENT_SLC_CONNECTED(cb);
355
356  if ((BTIF_HF_CLIENT_FEATURES & BTA_HF_CLIENT_FEAT_CODEC) &&
357      (cb->peer_feat & BTA_HF_CLIENT_PEER_CODEC)) {
358    BTA_HfClientSendAT(cb->handle, BTA_HF_CLIENT_AT_CMD_BCC, 0, 0, NULL);
359  } else {
360    BTA_HfClientAudioOpen(cb->handle);
361  }
362
363  /* Inform the application that the audio connection has been initiated
364   * successfully */
365  btif_transfer_context(btif_in_hf_client_generic_evt,
366                        BTIF_HF_CLIENT_CB_AUDIO_CONNECTING, (char*)bd_addr,
367                        sizeof(bt_bdaddr_t), NULL);
368  return BT_STATUS_SUCCESS;
369}
370
371/*******************************************************************************
372 *
373 * Function         disconnect_audio
374 *
375 * Description      close the audio connection
376 *
377 * Returns         bt_status_t
378 *
379 ******************************************************************************/
380static bt_status_t disconnect_audio(const bt_bdaddr_t* bd_addr) {
381  btif_hf_client_cb_t* cb = btif_hf_client_get_cb_by_bda(bd_addr->address);
382  if (cb == NULL || !is_connected(cb)) return BT_STATUS_FAIL;
383
384  CHECK_BTHF_CLIENT_SLC_CONNECTED(cb);
385
386  BTA_HfClientAudioClose(cb->handle);
387  return BT_STATUS_SUCCESS;
388}
389
390/*******************************************************************************
391 *
392 * Function         start_voice_recognition
393 *
394 * Description      start voice recognition
395 *
396 * Returns          bt_status_t
397 *
398 ******************************************************************************/
399static bt_status_t start_voice_recognition(const bt_bdaddr_t* bd_addr) {
400  btif_hf_client_cb_t* cb = btif_hf_client_get_cb_by_bda(bd_addr->address);
401  if (cb == NULL || !is_connected(cb)) return BT_STATUS_FAIL;
402
403  CHECK_BTHF_CLIENT_SLC_CONNECTED(cb);
404
405  if (cb->peer_feat & BTA_HF_CLIENT_PEER_FEAT_VREC) {
406    BTA_HfClientSendAT(cb->handle, BTA_HF_CLIENT_AT_CMD_BVRA, 1, 0, NULL);
407    return BT_STATUS_SUCCESS;
408  }
409  return BT_STATUS_UNSUPPORTED;
410}
411
412/*******************************************************************************
413 *
414 * Function         stop_voice_recognition
415 *
416 * Description      stop voice recognition
417 *
418 * Returns          bt_status_t
419 *
420 ******************************************************************************/
421static bt_status_t stop_voice_recognition(const bt_bdaddr_t* bd_addr) {
422  btif_hf_client_cb_t* cb = btif_hf_client_get_cb_by_bda(bd_addr->address);
423  if (cb == NULL || !is_connected(cb)) return BT_STATUS_FAIL;
424
425  CHECK_BTHF_CLIENT_SLC_CONNECTED(cb);
426
427  if (cb->peer_feat & BTA_HF_CLIENT_PEER_FEAT_VREC) {
428    BTA_HfClientSendAT(cb->handle, BTA_HF_CLIENT_AT_CMD_BVRA, 0, 0, NULL);
429    return BT_STATUS_SUCCESS;
430  }
431  return BT_STATUS_UNSUPPORTED;
432}
433
434/*******************************************************************************
435 *
436 * Function         volume_control
437 *
438 * Description      volume control
439 *
440 * Returns          bt_status_t
441 *
442 ******************************************************************************/
443static bt_status_t volume_control(const bt_bdaddr_t* bd_addr,
444                                  bthf_client_volume_type_t type, int volume) {
445  btif_hf_client_cb_t* cb = btif_hf_client_get_cb_by_bda(bd_addr->address);
446  if (cb == NULL || !is_connected(cb)) return BT_STATUS_FAIL;
447
448  CHECK_BTHF_CLIENT_SLC_CONNECTED(cb);
449
450  switch (type) {
451    case BTHF_CLIENT_VOLUME_TYPE_SPK:
452      BTA_HfClientSendAT(cb->handle, BTA_HF_CLIENT_AT_CMD_VGS, volume, 0, NULL);
453      break;
454    case BTHF_CLIENT_VOLUME_TYPE_MIC:
455      BTA_HfClientSendAT(cb->handle, BTA_HF_CLIENT_AT_CMD_VGM, volume, 0, NULL);
456      break;
457    default:
458      return BT_STATUS_UNSUPPORTED;
459  }
460
461  return BT_STATUS_SUCCESS;
462}
463
464/*******************************************************************************
465 *
466 * Function         dial
467 *
468 * Description      place a call
469 *
470 * Returns          bt_status_t
471 *
472 ******************************************************************************/
473static bt_status_t dial(UNUSED_ATTR const bt_bdaddr_t* bd_addr,
474                        const char* number) {
475  btif_hf_client_cb_t* cb = btif_hf_client_get_cb_by_bda(bd_addr->address);
476  if (cb == NULL || !is_connected(cb)) return BT_STATUS_FAIL;
477
478  CHECK_BTHF_CLIENT_SLC_CONNECTED(cb);
479
480  if (number) {
481    BTA_HfClientSendAT(cb->handle, BTA_HF_CLIENT_AT_CMD_ATD, 0, 0, number);
482  } else {
483    BTA_HfClientSendAT(cb->handle, BTA_HF_CLIENT_AT_CMD_BLDN, 0, 0, NULL);
484  }
485  return BT_STATUS_SUCCESS;
486}
487
488/*******************************************************************************
489 *
490 * Function         dial_memory
491 *
492 * Description      place a call with number specified by location (speed dial)
493 *
494 * Returns          bt_status_t
495 *
496 ******************************************************************************/
497static bt_status_t dial_memory(const bt_bdaddr_t* bd_addr, int location) {
498  btif_hf_client_cb_t* cb = btif_hf_client_get_cb_by_bda(bd_addr->address);
499  if (cb == NULL || !is_connected(cb)) return BT_STATUS_FAIL;
500
501  CHECK_BTHF_CLIENT_SLC_CONNECTED(cb);
502
503  BTA_HfClientSendAT(cb->handle, BTA_HF_CLIENT_AT_CMD_ATD, location, 0, NULL);
504  return BT_STATUS_SUCCESS;
505}
506
507/*******************************************************************************
508 *
509 * Function         handle_call_action
510 *
511 * Description      handle specified call related action
512 *
513 * Returns          bt_status_t
514 *
515 ******************************************************************************/
516static bt_status_t handle_call_action(const bt_bdaddr_t* bd_addr,
517                                      bthf_client_call_action_t action,
518                                      int idx) {
519  btif_hf_client_cb_t* cb = btif_hf_client_get_cb_by_bda(bd_addr->address);
520  if (cb == NULL || !is_connected(cb)) return BT_STATUS_FAIL;
521
522  CHECK_BTHF_CLIENT_SLC_CONNECTED(cb);
523
524  switch (action) {
525    case BTHF_CLIENT_CALL_ACTION_CHLD_0:
526      if (cb->chld_feat & BTA_HF_CLIENT_CHLD_REL) {
527        BTA_HfClientSendAT(cb->handle, BTA_HF_CLIENT_AT_CMD_CHLD, 0, 0, NULL);
528        break;
529      }
530      return BT_STATUS_UNSUPPORTED;
531    case BTHF_CLIENT_CALL_ACTION_CHLD_1:
532      // CHLD 1 is mandatory for 3 way calling
533      if (cb->peer_feat & BTA_HF_CLIENT_PEER_FEAT_3WAY) {
534        BTA_HfClientSendAT(cb->handle, BTA_HF_CLIENT_AT_CMD_CHLD, 1, 0, NULL);
535        break;
536      }
537      return BT_STATUS_UNSUPPORTED;
538    case BTHF_CLIENT_CALL_ACTION_CHLD_2:
539      // CHLD 2 is mandatory for 3 way calling
540      if (cb->peer_feat & BTA_HF_CLIENT_PEER_FEAT_3WAY) {
541        BTA_HfClientSendAT(cb->handle, BTA_HF_CLIENT_AT_CMD_CHLD, 2, 0, NULL);
542        break;
543      }
544      return BT_STATUS_UNSUPPORTED;
545    case BTHF_CLIENT_CALL_ACTION_CHLD_3:
546      if (cb->chld_feat & BTA_HF_CLIENT_CHLD_MERGE) {
547        BTA_HfClientSendAT(cb->handle, BTA_HF_CLIENT_AT_CMD_CHLD, 3, 0, NULL);
548        break;
549      }
550      return BT_STATUS_UNSUPPORTED;
551    case BTHF_CLIENT_CALL_ACTION_CHLD_4:
552      if (cb->chld_feat & BTA_HF_CLIENT_CHLD_MERGE_DETACH) {
553        BTA_HfClientSendAT(cb->handle, BTA_HF_CLIENT_AT_CMD_CHLD, 4, 0, NULL);
554        break;
555      }
556      return BT_STATUS_UNSUPPORTED;
557    case BTHF_CLIENT_CALL_ACTION_CHLD_1x:
558      if (cb->peer_feat & BTA_HF_CLIENT_PEER_ECC) {
559        if (idx < 1) {
560          return BT_STATUS_FAIL;
561        }
562        BTA_HfClientSendAT(cb->handle, BTA_HF_CLIENT_AT_CMD_CHLD, 1, idx, NULL);
563        break;
564      }
565      return BT_STATUS_UNSUPPORTED;
566    case BTHF_CLIENT_CALL_ACTION_CHLD_2x:
567      if (cb->peer_feat & BTA_HF_CLIENT_PEER_ECC) {
568        if (idx < 1) {
569          return BT_STATUS_FAIL;
570        }
571        BTA_HfClientSendAT(cb->handle, BTA_HF_CLIENT_AT_CMD_CHLD, 2, idx, NULL);
572        break;
573      }
574      return BT_STATUS_UNSUPPORTED;
575    case BTHF_CLIENT_CALL_ACTION_ATA:
576      BTA_HfClientSendAT(cb->handle, BTA_HF_CLIENT_AT_CMD_ATA, 0, 0, NULL);
577      break;
578    case BTHF_CLIENT_CALL_ACTION_CHUP:
579      BTA_HfClientSendAT(cb->handle, BTA_HF_CLIENT_AT_CMD_CHUP, 0, 0, NULL);
580      break;
581    case BTHF_CLIENT_CALL_ACTION_BTRH_0:
582      BTA_HfClientSendAT(cb->handle, BTA_HF_CLIENT_AT_CMD_BTRH, 0, 0, NULL);
583      break;
584    case BTHF_CLIENT_CALL_ACTION_BTRH_1:
585      BTA_HfClientSendAT(cb->handle, BTA_HF_CLIENT_AT_CMD_BTRH, 1, 0, NULL);
586      break;
587    case BTHF_CLIENT_CALL_ACTION_BTRH_2:
588      BTA_HfClientSendAT(cb->handle, BTA_HF_CLIENT_AT_CMD_BTRH, 2, 0, NULL);
589      break;
590    default:
591      return BT_STATUS_FAIL;
592  }
593
594  return BT_STATUS_SUCCESS;
595}
596
597/*******************************************************************************
598 *
599 * Function         query_current_calls
600 *
601 * Description      query list of current calls
602 *
603 * Returns          bt_status_t
604 *
605 ******************************************************************************/
606static bt_status_t query_current_calls(UNUSED_ATTR const bt_bdaddr_t* bd_addr) {
607  btif_hf_client_cb_t* cb = btif_hf_client_get_cb_by_bda(bd_addr->address);
608  if (cb == NULL || !is_connected(cb)) return BT_STATUS_FAIL;
609
610  CHECK_BTHF_CLIENT_SLC_CONNECTED(cb);
611
612  if (cb->peer_feat & BTA_HF_CLIENT_PEER_ECS) {
613    BTA_HfClientSendAT(cb->handle, BTA_HF_CLIENT_AT_CMD_CLCC, 0, 0, NULL);
614    return BT_STATUS_SUCCESS;
615  }
616
617  return BT_STATUS_UNSUPPORTED;
618}
619
620/*******************************************************************************
621 *
622 * Function         query_current_operator_name
623 *
624 * Description      query current selected operator name
625 *
626 * Returns          bt_status_t
627 *
628 ******************************************************************************/
629static bt_status_t query_current_operator_name(const bt_bdaddr_t* bd_addr) {
630  btif_hf_client_cb_t* cb = btif_hf_client_get_cb_by_bda(bd_addr->address);
631  if (cb == NULL || !is_connected(cb)) return BT_STATUS_FAIL;
632
633  CHECK_BTHF_CLIENT_SLC_CONNECTED(cb);
634
635  BTA_HfClientSendAT(cb->handle, BTA_HF_CLIENT_AT_CMD_COPS, 0, 0, NULL);
636  return BT_STATUS_SUCCESS;
637}
638
639/*******************************************************************************
640 *
641 * Function         retieve_subscriber_info
642 *
643 * Description      retrieve subscriber number information
644 *
645 * Returns          bt_status_t
646 *
647 ******************************************************************************/
648static bt_status_t retrieve_subscriber_info(const bt_bdaddr_t* bd_addr) {
649  btif_hf_client_cb_t* cb = btif_hf_client_get_cb_by_bda(bd_addr->address);
650  if (cb == NULL || !is_connected(cb)) return BT_STATUS_FAIL;
651
652  CHECK_BTHF_CLIENT_SLC_CONNECTED(cb);
653
654  BTA_HfClientSendAT(cb->handle, BTA_HF_CLIENT_AT_CMD_CNUM, 0, 0, NULL);
655  return BT_STATUS_SUCCESS;
656}
657
658/*******************************************************************************
659 *
660 * Function         send_dtmf
661 *
662 * Description      send dtmf
663 *
664 * Returns          bt_status_t
665 *
666 ******************************************************************************/
667static bt_status_t send_dtmf(const bt_bdaddr_t* bd_addr, char code) {
668  btif_hf_client_cb_t* cb = btif_hf_client_get_cb_by_bda(bd_addr->address);
669  if (cb == NULL || !is_connected(cb)) return BT_STATUS_FAIL;
670
671  CHECK_BTHF_CLIENT_SLC_CONNECTED(cb);
672
673  BTA_HfClientSendAT(cb->handle, BTA_HF_CLIENT_AT_CMD_VTS, code, 0, NULL);
674  return BT_STATUS_SUCCESS;
675}
676
677/*******************************************************************************
678 *
679 * Function         request_last_voice_tag_number
680 *
681 * Description      Request number from AG for VR purposes
682 *
683 * Returns          bt_status_t
684 *
685 ******************************************************************************/
686static bt_status_t request_last_voice_tag_number(const bt_bdaddr_t* bd_addr) {
687  btif_hf_client_cb_t* cb = btif_hf_client_get_cb_by_bda(bd_addr->address);
688  if (cb == NULL || !is_connected(cb)) return BT_STATUS_FAIL;
689
690  CHECK_BTHF_CLIENT_SLC_CONNECTED(cb);
691
692  if (cb->peer_feat & BTA_HF_CLIENT_PEER_VTAG) {
693    BTA_HfClientSendAT(cb->handle, BTA_HF_CLIENT_AT_CMD_BINP, 1, 0, NULL);
694    return BT_STATUS_SUCCESS;
695  }
696  return BT_STATUS_UNSUPPORTED;
697}
698
699/*******************************************************************************
700 *
701 * Function         cleanup
702 *
703 * Description      Closes the HF interface
704 *
705 * Returns          bt_status_t
706 *
707 ******************************************************************************/
708static void cleanup(void) {
709  BTIF_TRACE_EVENT("%s", __func__);
710
711  if (bt_hf_client_callbacks) {
712    btif_disable_service(BTA_HFP_HS_SERVICE_ID);
713    bt_hf_client_callbacks = NULL;
714  }
715}
716
717/*******************************************************************************
718 *
719 * Function         send_at_cmd
720 *
721 * Description      Send requested AT command to rempte device.
722 *
723 * Returns          bt_status_t
724 *
725 ******************************************************************************/
726static bt_status_t send_at_cmd(const bt_bdaddr_t* bd_addr, int cmd, int val1,
727                               int val2, const char* arg) {
728  btif_hf_client_cb_t* cb = btif_hf_client_get_cb_by_bda(bd_addr->address);
729  if (cb == NULL || !is_connected(cb)) return BT_STATUS_FAIL;
730
731  CHECK_BTHF_CLIENT_SLC_CONNECTED(cb);
732
733  BTIF_TRACE_EVENT("%s: Cmd %d val1 %d val2 %d arg %s", __func__, cmd, val1,
734                   val2, (arg != NULL) ? arg : "<null>");
735  BTA_HfClientSendAT(cb->handle, cmd, val1, val2, arg);
736
737  return BT_STATUS_SUCCESS;
738}
739
740static const bthf_client_interface_t bthfClientInterface = {
741    sizeof(bthf_client_interface_t),
742    .init = init,
743    .connect = connect,
744    .disconnect = disconnect,
745    .connect_audio = connect_audio,
746    .disconnect_audio = disconnect_audio,
747    .start_voice_recognition = start_voice_recognition,
748    .stop_voice_recognition = stop_voice_recognition,
749    .volume_control = volume_control,
750    .dial = dial,
751    .dial_memory = dial_memory,
752    .handle_call_action = handle_call_action,
753    .query_current_calls = query_current_calls,
754    .query_current_operator_name = query_current_operator_name,
755    .retrieve_subscriber_info = retrieve_subscriber_info,
756    .send_dtmf = send_dtmf,
757    .request_last_voice_tag_number = request_last_voice_tag_number,
758    .cleanup = cleanup,
759    .send_at_cmd = send_at_cmd,
760};
761
762static void process_ind_evt(tBTA_HF_CLIENT_IND* ind) {
763  BTIF_TRACE_DEBUG("%s", __func__);
764
765  btif_hf_client_cb_t* cb = btif_hf_client_get_cb_by_bda(ind->bd_addr);
766  if (cb == NULL || !is_connected(cb)) return;
767
768  switch (ind->type) {
769    case BTA_HF_CLIENT_IND_CALL:
770      HAL_CBACK(bt_hf_client_callbacks, call_cb, &cb->peer_bda,
771                (bthf_client_call_t)ind->value);
772      break;
773
774    case BTA_HF_CLIENT_IND_CALLSETUP:
775      HAL_CBACK(bt_hf_client_callbacks, callsetup_cb, &cb->peer_bda,
776                (bthf_client_callsetup_t)ind->value);
777      break;
778    case BTA_HF_CLIENT_IND_CALLHELD:
779      HAL_CBACK(bt_hf_client_callbacks, callheld_cb, &cb->peer_bda,
780                (bthf_client_callheld_t)ind->value);
781      break;
782
783    case BTA_HF_CLIENT_IND_SERVICE:
784      HAL_CBACK(bt_hf_client_callbacks, network_state_cb, &cb->peer_bda,
785                (bthf_client_network_state_t)ind->value);
786      break;
787
788    case BTA_HF_CLIENT_IND_SIGNAL:
789      HAL_CBACK(bt_hf_client_callbacks, network_signal_cb, &cb->peer_bda,
790                ind->value);
791      break;
792
793    case BTA_HF_CLIENT_IND_ROAM:
794      HAL_CBACK(bt_hf_client_callbacks, network_roaming_cb, &cb->peer_bda,
795                (bthf_client_service_type_t)ind->value);
796      break;
797
798    case BTA_HF_CLIENT_IND_BATTCH:
799      HAL_CBACK(bt_hf_client_callbacks, battery_level_cb, &cb->peer_bda,
800                ind->value);
801      break;
802
803    default:
804      break;
805  }
806}
807
808/*******************************************************************************
809 *
810 * Function         btif_hf_client_upstreams_evt
811 *
812 * Description      Executes HF CLIENT UPSTREAMS events in btif context
813 *
814 * Returns          void
815 *
816 ******************************************************************************/
817static void btif_hf_client_upstreams_evt(uint16_t event, char* p_param) {
818  tBTA_HF_CLIENT* p_data = (tBTA_HF_CLIENT*)p_param;
819  bdstr_t bdstr;
820
821  btif_hf_client_cb_t* cb = btif_hf_client_get_cb_by_bda(p_data->bd_addr);
822  if (cb == NULL && event == BTA_HF_CLIENT_OPEN_EVT) {
823    BTIF_TRACE_DEBUG("%s: event BTA_HF_CLIENT_OPEN_EVT allocating block",
824                     __func__);
825    cb = btif_hf_client_allocate_cb();
826    cb->handle = p_data->open.handle;
827    bdcpy(cb->peer_bda.address, p_data->open.bd_addr);
828  } else if (cb == NULL) {
829    BTIF_TRACE_ERROR("%s: event %d but not allocating block: cb not found",
830                     __func__, event);
831    return;
832  }
833
834  BTIF_TRACE_DEBUG("%s: event=%s (%u)", __func__, dump_hf_client_event(event),
835                   event);
836
837  switch (event) {
838    case BTA_HF_CLIENT_OPEN_EVT:
839      if (p_data->open.status == BTA_HF_CLIENT_SUCCESS) {
840        cb->state = BTHF_CLIENT_CONNECTION_STATE_CONNECTED;
841        cb->peer_feat = 0;
842        cb->chld_feat = 0;
843      } else if (cb->state == BTHF_CLIENT_CONNECTION_STATE_CONNECTING) {
844        cb->state = BTHF_CLIENT_CONNECTION_STATE_DISCONNECTED;
845      } else {
846        BTIF_TRACE_WARNING(
847            "%s: HF CLient open failed, but another device connected. "
848            "status=%d state=%d connected device=%s",
849            __func__, p_data->open.status, cb->state,
850            bdaddr_to_string(&cb->peer_bda, bdstr, sizeof(bdstr)));
851        break;
852      }
853
854      HAL_CBACK(bt_hf_client_callbacks, connection_state_cb, &cb->peer_bda,
855                cb->state, 0, /* peer feat */
856                0 /* AT+CHLD feat */);
857
858      if (cb->state == BTHF_CLIENT_CONNECTION_STATE_DISCONNECTED)
859        bdsetany(cb->peer_bda.address);
860
861      if (p_data->open.status != BTA_HF_CLIENT_SUCCESS) btif_queue_advance();
862      break;
863
864    case BTA_HF_CLIENT_CONN_EVT:
865      cb->peer_feat = p_data->conn.peer_feat;
866      cb->chld_feat = p_data->conn.chld_feat;
867      cb->state = BTHF_CLIENT_CONNECTION_STATE_SLC_CONNECTED;
868
869      HAL_CBACK(bt_hf_client_callbacks, connection_state_cb, &cb->peer_bda,
870                cb->state, cb->peer_feat, cb->chld_feat);
871
872      /* Inform the application about in-band ringtone */
873      if (cb->peer_feat & BTA_HF_CLIENT_PEER_INBAND) {
874        HAL_CBACK(bt_hf_client_callbacks, in_band_ring_tone_cb, &cb->peer_bda,
875                  BTHF_CLIENT_IN_BAND_RINGTONE_PROVIDED);
876      }
877
878      btif_queue_advance();
879      break;
880
881    case BTA_HF_CLIENT_CLOSE_EVT:
882      cb->state = BTHF_CLIENT_CONNECTION_STATE_DISCONNECTED;
883      HAL_CBACK(bt_hf_client_callbacks, connection_state_cb, &cb->peer_bda,
884                cb->state, 0, 0);
885      bdsetany(cb->peer_bda.address);
886      cb->peer_feat = 0;
887      cb->chld_feat = 0;
888      btif_queue_advance();
889      break;
890
891    case BTA_HF_CLIENT_IND_EVT:
892      process_ind_evt(&p_data->ind);
893      break;
894
895    case BTA_HF_CLIENT_MIC_EVT:
896      HAL_CBACK(bt_hf_client_callbacks, volume_change_cb, &cb->peer_bda,
897                BTHF_CLIENT_VOLUME_TYPE_MIC, p_data->val.value);
898      break;
899
900    case BTA_HF_CLIENT_SPK_EVT:
901      HAL_CBACK(bt_hf_client_callbacks, volume_change_cb, &cb->peer_bda,
902                BTHF_CLIENT_VOLUME_TYPE_SPK, p_data->val.value);
903      break;
904
905    case BTA_HF_CLIENT_VOICE_REC_EVT:
906      HAL_CBACK(bt_hf_client_callbacks, vr_cmd_cb, &cb->peer_bda,
907                (bthf_client_vr_state_t)p_data->val.value);
908      break;
909
910    case BTA_HF_CLIENT_OPERATOR_NAME_EVT:
911      HAL_CBACK(bt_hf_client_callbacks, current_operator_cb, &cb->peer_bda,
912                p_data->operator_name.name);
913      break;
914
915    case BTA_HF_CLIENT_CLIP_EVT:
916      HAL_CBACK(bt_hf_client_callbacks, clip_cb, &cb->peer_bda,
917                p_data->number.number);
918      break;
919
920    case BTA_HF_CLIENT_BINP_EVT:
921      HAL_CBACK(bt_hf_client_callbacks, last_voice_tag_number_callback,
922                &cb->peer_bda, p_data->number.number);
923      break;
924
925    case BTA_HF_CLIENT_CCWA_EVT:
926      HAL_CBACK(bt_hf_client_callbacks, call_waiting_cb, &cb->peer_bda,
927                p_data->number.number);
928      break;
929
930    case BTA_HF_CLIENT_AT_RESULT_EVT:
931      HAL_CBACK(bt_hf_client_callbacks, cmd_complete_cb, &cb->peer_bda,
932                (bthf_client_cmd_complete_t)p_data->result.type,
933                p_data->result.cme);
934      break;
935
936    case BTA_HF_CLIENT_CLCC_EVT:
937      HAL_CBACK(bt_hf_client_callbacks, current_calls_cb, &cb->peer_bda,
938                p_data->clcc.idx,
939                p_data->clcc.inc ? BTHF_CLIENT_CALL_DIRECTION_INCOMING
940                                 : BTHF_CLIENT_CALL_DIRECTION_OUTGOING,
941                (bthf_client_call_state_t)p_data->clcc.status,
942                p_data->clcc.mpty ? BTHF_CLIENT_CALL_MPTY_TYPE_MULTI
943                                  : BTHF_CLIENT_CALL_MPTY_TYPE_SINGLE,
944                p_data->clcc.number_present ? p_data->clcc.number : NULL);
945      break;
946
947    case BTA_HF_CLIENT_CNUM_EVT:
948      if (p_data->cnum.service == 4) {
949        HAL_CBACK(bt_hf_client_callbacks, subscriber_info_cb, &cb->peer_bda,
950                  p_data->cnum.number, BTHF_CLIENT_SERVICE_VOICE);
951      } else if (p_data->cnum.service == 5) {
952        HAL_CBACK(bt_hf_client_callbacks, subscriber_info_cb, &cb->peer_bda,
953                  p_data->cnum.number, BTHF_CLIENT_SERVICE_FAX);
954      } else {
955        HAL_CBACK(bt_hf_client_callbacks, subscriber_info_cb, &cb->peer_bda,
956                  p_data->cnum.number, BTHF_CLIENT_SERVICE_UNKNOWN);
957      }
958      break;
959
960    case BTA_HF_CLIENT_BTRH_EVT:
961      if (p_data->val.value <= BTRH_CLIENT_RESP_AND_HOLD_REJECT) {
962        HAL_CBACK(bt_hf_client_callbacks, resp_and_hold_cb, &cb->peer_bda,
963                  (bthf_client_resp_and_hold_t)p_data->val.value);
964      }
965      break;
966
967    case BTA_HF_CLIENT_BSIR_EVT:
968      if (p_data->val.value != 0) {
969        HAL_CBACK(bt_hf_client_callbacks, in_band_ring_tone_cb, &cb->peer_bda,
970                  BTHF_CLIENT_IN_BAND_RINGTONE_PROVIDED);
971      } else {
972        HAL_CBACK(bt_hf_client_callbacks, in_band_ring_tone_cb, &cb->peer_bda,
973                  BTHF_CLIENT_IN_BAND_RINGTONE_NOT_PROVIDED);
974      }
975      break;
976
977    case BTA_HF_CLIENT_AUDIO_OPEN_EVT:
978      HAL_CBACK(bt_hf_client_callbacks, audio_state_cb, &cb->peer_bda,
979                BTHF_CLIENT_AUDIO_STATE_CONNECTED);
980      break;
981
982    case BTA_HF_CLIENT_AUDIO_MSBC_OPEN_EVT:
983      HAL_CBACK(bt_hf_client_callbacks, audio_state_cb, &cb->peer_bda,
984                BTHF_CLIENT_AUDIO_STATE_CONNECTED_MSBC);
985      break;
986
987    case BTA_HF_CLIENT_AUDIO_CLOSE_EVT:
988      HAL_CBACK(bt_hf_client_callbacks, audio_state_cb, &cb->peer_bda,
989                BTHF_CLIENT_AUDIO_STATE_DISCONNECTED);
990      break;
991    case BTA_HF_CLIENT_RING_INDICATION:
992      HAL_CBACK(bt_hf_client_callbacks, ring_indication_cb, &cb->peer_bda);
993      break;
994    default:
995      BTIF_TRACE_WARNING("%s: Unhandled event: %d", __func__, event);
996      break;
997  }
998}
999
1000/*******************************************************************************
1001 *
1002 * Function         bta_hf_client_evt
1003 *
1004 * Description      Switches context from BTA to BTIF for all HF Client events
1005 *
1006 * Returns          void
1007 *
1008 ******************************************************************************/
1009
1010static void bta_hf_client_evt(tBTA_HF_CLIENT_EVT event,
1011                              tBTA_HF_CLIENT* p_data) {
1012  bt_status_t status;
1013
1014  /* switch context to btif task context (copy full union size for convenience)
1015   */
1016  status = btif_transfer_context(btif_hf_client_upstreams_evt, (uint16_t)event,
1017                                 (char*)p_data, sizeof(*p_data), NULL);
1018
1019  /* catch any failed context transfers */
1020  ASSERTC(status == BT_STATUS_SUCCESS, "context transfer failed", status);
1021}
1022
1023/*******************************************************************************
1024 *
1025 * Function         btif_hf_client_execute_service
1026 *
1027 * Description      Initializes/Shuts down the service
1028 *
1029 * Returns          BT_STATUS_SUCCESS on success, BT_STATUS_FAIL otherwise
1030 *
1031 ******************************************************************************/
1032bt_status_t btif_hf_client_execute_service(bool b_enable) {
1033  BTIF_TRACE_EVENT("%s: enable: %d", __func__, b_enable);
1034
1035  if (b_enable) {
1036    /* Enable and register with BTA-HFClient */
1037    BTIF_TRACE_EVENT("%s: support codec negotiation %d ", __func__,
1038                     BTIF_HF_CLIENT_FEATURES);
1039    BTA_HfClientEnable(bta_hf_client_evt, BTIF_HF_CLIENT_SECURITY,
1040                       BTIF_HF_CLIENT_FEATURES, BTIF_HF_CLIENT_SERVICE_NAME);
1041  } else {
1042    BTA_HfClientDisable();
1043  }
1044  return BT_STATUS_SUCCESS;
1045}
1046
1047/*******************************************************************************
1048 *
1049 * Function         btif_hf_get_interface
1050 *
1051 * Description      Get the hf callback interface
1052 *
1053 * Returns          bthf_interface_t
1054 *
1055 ******************************************************************************/
1056const bthf_client_interface_t* btif_hf_client_get_interface(void) {
1057  BTIF_TRACE_EVENT("%s", __func__);
1058  return &bthfClientInterface;
1059}
1060