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