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