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 #ifndef LOG_TAG
46 #define LOG_TAG "bt_btif_hfc"
47 #endif
48 
49 #include <bluetooth/log.h>
50 #include <hardware/bluetooth.h>
51 #include <hardware/bt_hf_client.h>
52 #include <string.h>
53 
54 #include "bta_hf_client_api.h"
55 #include "btif_common.h"
56 #include "btif_profile_queue.h"
57 #include "btif_util.h"
58 #include "osi/include/properties.h"
59 #include "stack/btm/btm_sco_hfp_hal.h"
60 #include "stack/include/bt_uuid16.h"
61 #include "types/raw_address.h"
62 
63 /*******************************************************************************
64  *  Constants & Macros
65  ******************************************************************************/
66 
67 #ifndef BTIF_HF_CLIENT_SERVICE_NAME
68 #define BTIF_HF_CLIENT_SERVICE_NAME ("Handsfree")
69 #endif
70 
71 using namespace bluetooth;
72 
73 /*******************************************************************************
74  *  Local type definitions
75  ******************************************************************************/
76 /* BTIF-HF control block to map bdaddr to BTA handle */
77 typedef struct {
78   uint16_t handle;                       // Handle obtained frm the BTA
79   RawAddress peer_bda;                   // Device corresponding to handle
80   bthf_client_connection_state_t state;  // State of current connection
81   tBTA_HF_CLIENT_PEER_FEAT peer_feat;    // HF features
82   tBTA_HF_CLIENT_CHLD_FEAT chld_feat;    // AT+CHLD=<> command features
83 } btif_hf_client_cb_t;
84 
85 /* Max devices supported by BTIF (useful to match the value in BTA) */
86 #define HF_CLIENT_MAX_DEVICES 10
87 typedef struct {
88   btif_hf_client_cb_t cb[HF_CLIENT_MAX_DEVICES];
89 } btif_hf_client_cb_arr_t;
90 
91 /******************************************************************************
92  * Local function declarations
93  ******************************************************************************/
94 btif_hf_client_cb_t* btif_hf_client_get_cb_by_handle(uint16_t handle);
95 btif_hf_client_cb_t* btif_hf_client_get_cb_by_bda(const RawAddress& addr);
96 bool is_connected(const btif_hf_client_cb_t* cb);
97 
98 /*******************************************************************************
99  *  Static variables
100  ******************************************************************************/
101 static bthf_client_callbacks_t* bt_hf_client_callbacks = NULL;
102 
103 char btif_hf_client_version[PROPERTY_VALUE_MAX];
104 
dump_hf_client_conn_state(uint16_t event)105 static const char* dump_hf_client_conn_state(uint16_t event) {
106   switch (event) {
107     CASE_RETURN_STR(BTHF_CLIENT_CONNECTION_STATE_DISCONNECTED)
108     CASE_RETURN_STR(BTHF_CLIENT_CONNECTION_STATE_CONNECTING)
109     CASE_RETURN_STR(BTHF_CLIENT_CONNECTION_STATE_CONNECTED)
110     CASE_RETURN_STR(BTHF_CLIENT_CONNECTION_STATE_SLC_CONNECTED)
111     CASE_RETURN_STR(BTHF_CLIENT_CONNECTION_STATE_DISCONNECTING)
112     default:
113       return "UNKNOWN MSG ID";
114   }
115 }
116 
117 #define CHECK_BTHF_CLIENT_INIT()                 \
118   do {                                           \
119     if (bt_hf_client_callbacks == NULL) {        \
120       log::warn("BTHF CLIENT: not initialized"); \
121       return BT_STATUS_NOT_READY;                \
122     } else {                                     \
123       log::verbose("BTHF CLIENT: ok");           \
124     }                                            \
125   } while (0)
126 
127 #define CHECK_BTHF_CLIENT_SLC_CONNECTED(cb)                                 \
128   do {                                                                      \
129     if (bt_hf_client_callbacks == NULL) {                                   \
130       log::warn("BTHF CLIENT: not initialized");                            \
131       return BT_STATUS_NOT_READY;                                           \
132     } else if ((cb)->state != BTHF_CLIENT_CONNECTION_STATE_SLC_CONNECTED) { \
133       log::warn("BTHF CLIENT: SLC connection not up. state={}",             \
134                 dump_hf_client_conn_state((cb)->state));                    \
135       return BT_STATUS_NOT_READY;                                           \
136     } else {                                                                \
137       log::verbose("BTHF CLIENT: ok");                                      \
138     }                                                                       \
139   } while (0)
140 
141 static btif_hf_client_cb_arr_t btif_hf_client_cb_arr;
142 
143 /*******************************************************************************
144  *  Static functions
145  ******************************************************************************/
146 
147 /*******************************************************************************
148  *
149  * Function        btif_in_hf_client_generic_evt
150  *
151  * Description     Processes generic events to be sent to JNI that are not
152  *                 triggered from the BTA.
153  *                 Always runs in BTIF context
154  *
155  * Returns          void
156  *
157  ******************************************************************************/
158 constexpr uint16_t BTIF_HF_CLIENT_CB_AUDIO_CONNECTING = 0x8501;
btif_in_hf_client_generic_evt(uint16_t event,char * p_param)159 static void btif_in_hf_client_generic_evt(uint16_t event, char* p_param) {
160   log::verbose("");
161   RawAddress* bd_addr = (RawAddress*)p_param;
162   btif_hf_client_cb_t* cb = btif_hf_client_get_cb_by_bda(*bd_addr);
163   if (cb == NULL || !is_connected(cb)) {
164     log::error("failed to find block for bda");
165     return;
166   }
167 
168   log::verbose("event={}", event);
169   switch (event) {
170     case BTIF_HF_CLIENT_CB_AUDIO_CONNECTING: {
171       HAL_CBACK(bt_hf_client_callbacks, audio_state_cb, &cb->peer_bda,
172                 (bthf_client_audio_state_t)BTHF_CLIENT_AUDIO_STATE_CONNECTING);
173     } break;
174     default: {
175       log::warn(": Unknown event 0x{:x}", event);
176     } break;
177   }
178 }
179 
180 /*******************************************************************************
181  *  Functions
182  ******************************************************************************/
is_connected(const btif_hf_client_cb_t * cb)183 bool is_connected(const btif_hf_client_cb_t* cb) {
184   if ((cb->state == BTHF_CLIENT_CONNECTION_STATE_CONNECTED) ||
185       (cb->state == BTHF_CLIENT_CONNECTION_STATE_SLC_CONNECTED))
186     return true;
187 
188   log::error("not connected!");
189   return false;
190 }
191 
192 /*******************************************************************************
193  *
194  * Function        btif_hf_client_get_cb_by_handle
195  *
196  * Description     Get control block by handle
197  *
198  * Returns         btif_hf_client_cb_t pointer if available NULL otherwise
199  *
200  ******************************************************************************/
btif_hf_client_get_cb_by_handle(uint16_t handle)201 btif_hf_client_cb_t* btif_hf_client_get_cb_by_handle(uint16_t handle) {
202   log::verbose("cb by handle {}", handle);
203   for (int i = 0; i < HF_CLIENT_MAX_DEVICES; i++) {
204     // Block is valid only if it is allocated i.e. state is not DISCONNECTED
205     if (btif_hf_client_cb_arr.cb[i].state !=
206             BTHF_CLIENT_CONNECTION_STATE_DISCONNECTED &&
207         btif_hf_client_cb_arr.cb[i].handle == handle) {
208       return &btif_hf_client_cb_arr.cb[i];
209     }
210   }
211   log::error("could not find block for handle {}", handle);
212   return NULL;
213 }
214 
215 /*******************************************************************************
216  *
217  * Function        btif_hf_client_get_cb_by_bda
218  *
219  * Description     Get control block by bda
220  *
221  * Returns         btif_hf_client_cb_t pointer if available NULL otherwise
222  *
223  ******************************************************************************/
btif_hf_client_get_cb_by_bda(const RawAddress & bd_addr)224 btif_hf_client_cb_t* btif_hf_client_get_cb_by_bda(const RawAddress& bd_addr) {
225   log::verbose("incoming addr {}", bd_addr);
226 
227   for (int i = 0; i < HF_CLIENT_MAX_DEVICES; i++) {
228     // Block is valid only if it is allocated i.e. state is not DISCONNECTED
229     if (btif_hf_client_cb_arr.cb[i].state !=
230             BTHF_CLIENT_CONNECTION_STATE_DISCONNECTED &&
231         btif_hf_client_cb_arr.cb[i].peer_bda == bd_addr) {
232       return &btif_hf_client_cb_arr.cb[i];
233     }
234   }
235   log::error("could not find block for bdaddr");
236   return NULL;
237 }
238 
239 /*******************************************************************************
240  *
241  * Function        btif_hf_client_allocate_cb
242  *
243  * Description     Get control block by bda
244  *
245  * Returns         btif_hf_client_cb_t pointer if available NULL otherwise
246  *
247  ******************************************************************************/
btif_hf_client_allocate_cb()248 btif_hf_client_cb_t* btif_hf_client_allocate_cb() {
249   for (int i = 0; i < HF_CLIENT_MAX_DEVICES; i++) {
250     btif_hf_client_cb_t* cb = &btif_hf_client_cb_arr.cb[i];
251     if (cb->state == BTHF_CLIENT_CONNECTION_STATE_DISCONNECTED) {
252       return cb;
253     }
254   }
255   log::error("unable to allocate control block");
256   return NULL;
257 }
258 
259 /*****************************************************************************
260  *
261  *   btif hf api functions (no context switch)
262  *
263  ****************************************************************************/
264 
265 /*******************************************************************************
266  *
267  * Function         btif_hf_client_init
268  *
269  * Description     initializes the hf interface
270  *
271  * Returns         bt_status_t
272  *
273  ******************************************************************************/
init(bthf_client_callbacks_t * callbacks)274 static bt_status_t init(bthf_client_callbacks_t* callbacks) {
275   log::verbose("");
276 
277   bt_hf_client_callbacks = callbacks;
278 
279   btif_enable_service(BTA_HFP_HS_SERVICE_ID);
280 
281   memset(&btif_hf_client_cb_arr, 0, sizeof(btif_hf_client_cb_arr_t));
282 
283   return BT_STATUS_SUCCESS;
284 }
285 
286 /*******************************************************************************
287  *
288  * Function         connect
289  *
290  * Description     connect to audio gateway
291  *
292  * Returns         bt_status_t
293  *
294  ******************************************************************************/
connect_int(RawAddress * bd_addr,uint16_t uuid)295 static bt_status_t connect_int(RawAddress* bd_addr, uint16_t uuid) {
296   btif_hf_client_cb_t* cb = btif_hf_client_allocate_cb();
297   if (cb == NULL) {
298     log::error("could not allocate block!");
299     return BT_STATUS_BUSY;
300   }
301 
302   cb->peer_bda = *bd_addr;
303   if (is_connected(cb)) return BT_STATUS_BUSY;
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_cb_by_bda(*bd_addr);
353   if (cb == NULL || !is_connected(cb)) return BT_STATUS_DEVICE_NOT_FOUND;
354 
355   CHECK_BTHF_CLIENT_SLC_CONNECTED(cb);
356 
357   if ((get_default_hf_client_features() & BTA_HF_CLIENT_FEAT_CODEC) &&
358       (cb->peer_feat & BTA_HF_CLIENT_PEER_CODEC)) {
359     BTA_HfClientSendAT(cb->handle, BTA_HF_CLIENT_AT_CMD_BCC, 0, 0, NULL);
360   } else {
361     BTA_HfClientAudioOpen(cb->handle);
362   }
363 
364   /* Inform the application that the audio connection has been initiated
365    * successfully */
366   btif_transfer_context(btif_in_hf_client_generic_evt,
367                         BTIF_HF_CLIENT_CB_AUDIO_CONNECTING, (char*)bd_addr,
368                         sizeof(RawAddress), NULL);
369   return BT_STATUS_SUCCESS;
370 }
371 
372 /*******************************************************************************
373  *
374  * Function         disconnect_audio
375  *
376  * Description      close the audio connection
377  *
378  * Returns         bt_status_t
379  *
380  ******************************************************************************/
disconnect_audio(const RawAddress * bd_addr)381 static bt_status_t disconnect_audio(const RawAddress* bd_addr) {
382   btif_hf_client_cb_t* cb = btif_hf_client_get_cb_by_bda(*bd_addr);
383   if (cb == NULL || !is_connected(cb)) return BT_STATUS_DEVICE_NOT_FOUND;
384 
385   CHECK_BTHF_CLIENT_SLC_CONNECTED(cb);
386 
387   BTA_HfClientAudioClose(cb->handle);
388   return BT_STATUS_SUCCESS;
389 }
390 
391 /*******************************************************************************
392  *
393  * Function         start_voice_recognition
394  *
395  * Description      start voice recognition
396  *
397  * Returns          bt_status_t
398  *
399  ******************************************************************************/
start_voice_recognition(const RawAddress * bd_addr)400 static bt_status_t start_voice_recognition(const RawAddress* bd_addr) {
401   btif_hf_client_cb_t* cb = btif_hf_client_get_cb_by_bda(*bd_addr);
402   if (cb == NULL || !is_connected(cb)) return BT_STATUS_DEVICE_NOT_FOUND;
403 
404   CHECK_BTHF_CLIENT_SLC_CONNECTED(cb);
405 
406   if (cb->peer_feat & BTA_HF_CLIENT_PEER_FEAT_VREC) {
407     BTA_HfClientSendAT(cb->handle, BTA_HF_CLIENT_AT_CMD_BVRA, 1, 0, NULL);
408     return BT_STATUS_SUCCESS;
409   }
410   return BT_STATUS_UNSUPPORTED;
411 }
412 
413 /*******************************************************************************
414  *
415  * Function         stop_voice_recognition
416  *
417  * Description      stop voice recognition
418  *
419  * Returns          bt_status_t
420  *
421  ******************************************************************************/
stop_voice_recognition(const RawAddress * bd_addr)422 static bt_status_t stop_voice_recognition(const RawAddress* bd_addr) {
423   btif_hf_client_cb_t* cb = btif_hf_client_get_cb_by_bda(*bd_addr);
424   if (cb == NULL || !is_connected(cb)) return BT_STATUS_DEVICE_NOT_FOUND;
425 
426   CHECK_BTHF_CLIENT_SLC_CONNECTED(cb);
427 
428   if (cb->peer_feat & BTA_HF_CLIENT_PEER_FEAT_VREC) {
429     BTA_HfClientSendAT(cb->handle, BTA_HF_CLIENT_AT_CMD_BVRA, 0, 0, NULL);
430     return BT_STATUS_SUCCESS;
431   }
432   return BT_STATUS_UNSUPPORTED;
433 }
434 
435 /*******************************************************************************
436  *
437  * Function         volume_control
438  *
439  * Description      volume control
440  *
441  * Returns          bt_status_t
442  *
443  ******************************************************************************/
volume_control(const RawAddress * bd_addr,bthf_client_volume_type_t type,int volume)444 static bt_status_t volume_control(const RawAddress* bd_addr,
445                                   bthf_client_volume_type_t type, int volume) {
446   btif_hf_client_cb_t* cb = btif_hf_client_get_cb_by_bda(*bd_addr);
447   if (cb == NULL || !is_connected(cb)) return BT_STATUS_DEVICE_NOT_FOUND;
448 
449   CHECK_BTHF_CLIENT_SLC_CONNECTED(cb);
450 
451   switch (type) {
452     case BTHF_CLIENT_VOLUME_TYPE_SPK:
453       BTA_HfClientSendAT(cb->handle, BTA_HF_CLIENT_AT_CMD_VGS, volume, 0, NULL);
454       break;
455     case BTHF_CLIENT_VOLUME_TYPE_MIC:
456       BTA_HfClientSendAT(cb->handle, BTA_HF_CLIENT_AT_CMD_VGM, volume, 0, NULL);
457       break;
458     default:
459       return BT_STATUS_UNSUPPORTED;
460   }
461 
462   return BT_STATUS_SUCCESS;
463 }
464 
465 /*******************************************************************************
466  *
467  * Function         dial
468  *
469  * Description      place a call
470  *
471  * Returns          bt_status_t
472  *
473  ******************************************************************************/
dial(const RawAddress * bd_addr,const char * number)474 static bt_status_t dial(const RawAddress* bd_addr, const char* number) {
475   btif_hf_client_cb_t* cb = btif_hf_client_get_cb_by_bda(*bd_addr);
476   if (cb == NULL || !is_connected(cb)) return BT_STATUS_DEVICE_NOT_FOUND;
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  ******************************************************************************/
dial_memory(const RawAddress * bd_addr,int location)497 static bt_status_t dial_memory(const RawAddress* bd_addr, int location) {
498   btif_hf_client_cb_t* cb = btif_hf_client_get_cb_by_bda(*bd_addr);
499   if (cb == NULL || !is_connected(cb)) return BT_STATUS_DEVICE_NOT_FOUND;
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  ******************************************************************************/
handle_call_action(const RawAddress * bd_addr,bthf_client_call_action_t action,int idx)516 static bt_status_t handle_call_action(const RawAddress* 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);
520   if (cb == NULL || !is_connected(cb)) return BT_STATUS_DEVICE_NOT_FOUND;
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_UNHANDLED;
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_UNHANDLED;
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_UNHANDLED;
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  ******************************************************************************/
query_current_calls(const RawAddress * bd_addr)606 static bt_status_t query_current_calls(const RawAddress* bd_addr) {
607   btif_hf_client_cb_t* cb = btif_hf_client_get_cb_by_bda(*bd_addr);
608   if (cb == NULL || !is_connected(cb)) return BT_STATUS_DEVICE_NOT_FOUND;
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  ******************************************************************************/
query_current_operator_name(const RawAddress * bd_addr)629 static bt_status_t query_current_operator_name(const RawAddress* bd_addr) {
630   btif_hf_client_cb_t* cb = btif_hf_client_get_cb_by_bda(*bd_addr);
631   if (cb == NULL || !is_connected(cb)) return BT_STATUS_DEVICE_NOT_FOUND;
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)) return BT_STATUS_DEVICE_NOT_FOUND;
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  ******************************************************************************/
send_dtmf(const RawAddress * bd_addr,char code)667 static bt_status_t send_dtmf(const RawAddress* bd_addr, char code) {
668   btif_hf_client_cb_t* cb = btif_hf_client_get_cb_by_bda(*bd_addr);
669   if (cb == NULL || !is_connected(cb)) return BT_STATUS_DEVICE_NOT_FOUND;
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  ******************************************************************************/
request_last_voice_tag_number(const RawAddress * bd_addr)686 static bt_status_t request_last_voice_tag_number(const RawAddress* bd_addr) {
687   btif_hf_client_cb_t* cb = btif_hf_client_get_cb_by_bda(*bd_addr);
688   if (cb == NULL || !is_connected(cb)) return BT_STATUS_DEVICE_NOT_FOUND;
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  ******************************************************************************/
cleanup(void)708 static void cleanup(void) {
709   log::verbose("");
710 
711   btif_queue_cleanup(UUID_SERVCLASS_HF_HANDSFREE);
712   if (bt_hf_client_callbacks) {
713     btif_disable_service(BTA_HFP_HS_SERVICE_ID);
714     bt_hf_client_callbacks = NULL;
715   }
716 }
717 
718 /*******************************************************************************
719  *
720  * Function         send_at_cmd
721  *
722  * Description      Send requested AT command to rempte device.
723  *
724  * Returns          bt_status_t
725  *
726  ******************************************************************************/
send_at_cmd(const RawAddress * bd_addr,int cmd,int val1,int val2,const char * arg)727 static bt_status_t send_at_cmd(const RawAddress* bd_addr, int cmd, int val1,
728                                int val2, const char* arg) {
729   btif_hf_client_cb_t* cb = btif_hf_client_get_cb_by_bda(*bd_addr);
730   if (cb == NULL || !is_connected(cb)) return BT_STATUS_DEVICE_NOT_FOUND;
731 
732   CHECK_BTHF_CLIENT_SLC_CONNECTED(cb);
733 
734   log::verbose("Cmd {} val1 {} val2 {} arg {}", cmd, val1, val2,
735                (arg != NULL) ? arg : "<null>");
736   BTA_HfClientSendAT(cb->handle, cmd, val1, val2, arg);
737 
738   return BT_STATUS_SUCCESS;
739 }
740 
741 /*******************************************************************************
742  *
743  * Function         send_hfp_audio_policy
744  *
745  * Description      Send requested audio policies to remote device.
746  *
747  * Returns          bt_status_t
748  *
749  ******************************************************************************/
send_android_at(const RawAddress * bd_addr,const char * arg)750 static bt_status_t send_android_at(const RawAddress* bd_addr, const char* arg) {
751   btif_hf_client_cb_t* cb = btif_hf_client_get_cb_by_bda(*bd_addr);
752   if (cb == NULL || !is_connected(cb)) return BT_STATUS_DEVICE_NOT_FOUND;
753 
754   CHECK_BTHF_CLIENT_SLC_CONNECTED(cb);
755 
756   log::verbose("val1 {}", arg);
757   BTA_HfClientSendAT(cb->handle, BTA_HF_CLIENT_AT_CMD_ANDROID, 0, 0, arg);
758 
759   return BT_STATUS_SUCCESS;
760 }
761 
762 static const bthf_client_interface_t bthfClientInterface = {
763     .size = sizeof(bthf_client_interface_t),
764     .init = init,
765     .connect = connect,
766     .disconnect = disconnect,
767     .connect_audio = connect_audio,
768     .disconnect_audio = disconnect_audio,
769     .start_voice_recognition = start_voice_recognition,
770     .stop_voice_recognition = stop_voice_recognition,
771     .volume_control = volume_control,
772     .dial = dial,
773     .dial_memory = dial_memory,
774     .handle_call_action = handle_call_action,
775     .query_current_calls = query_current_calls,
776     .query_current_operator_name = query_current_operator_name,
777     .retrieve_subscriber_info = retrieve_subscriber_info,
778     .send_dtmf = send_dtmf,
779     .request_last_voice_tag_number = request_last_voice_tag_number,
780     .cleanup = cleanup,
781     .send_at_cmd = send_at_cmd,
782     .send_android_at = send_android_at,
783 };
784 
process_ind_evt(tBTA_HF_CLIENT_IND * ind)785 static void process_ind_evt(tBTA_HF_CLIENT_IND* ind) {
786   log::verbose("");
787 
788   btif_hf_client_cb_t* cb = btif_hf_client_get_cb_by_bda(ind->bd_addr);
789   if (cb == NULL || !is_connected(cb)) return;
790 
791   switch (ind->type) {
792     case BTA_HF_CLIENT_IND_CALL:
793       HAL_CBACK(bt_hf_client_callbacks, call_cb, &cb->peer_bda,
794                 (bthf_client_call_t)ind->value);
795       break;
796 
797     case BTA_HF_CLIENT_IND_CALLSETUP:
798       HAL_CBACK(bt_hf_client_callbacks, callsetup_cb, &cb->peer_bda,
799                 (bthf_client_callsetup_t)ind->value);
800       break;
801     case BTA_HF_CLIENT_IND_CALLHELD:
802       HAL_CBACK(bt_hf_client_callbacks, callheld_cb, &cb->peer_bda,
803                 (bthf_client_callheld_t)ind->value);
804       break;
805 
806     case BTA_HF_CLIENT_IND_SERVICE:
807       HAL_CBACK(bt_hf_client_callbacks, network_state_cb, &cb->peer_bda,
808                 (bthf_client_network_state_t)ind->value);
809       break;
810 
811     case BTA_HF_CLIENT_IND_SIGNAL:
812       HAL_CBACK(bt_hf_client_callbacks, network_signal_cb, &cb->peer_bda,
813                 ind->value);
814       break;
815 
816     case BTA_HF_CLIENT_IND_ROAM:
817       HAL_CBACK(bt_hf_client_callbacks, network_roaming_cb, &cb->peer_bda,
818                 (bthf_client_service_type_t)ind->value);
819       break;
820 
821     case BTA_HF_CLIENT_IND_BATTCH:
822       HAL_CBACK(bt_hf_client_callbacks, battery_level_cb, &cb->peer_bda,
823                 ind->value);
824       break;
825 
826     default:
827       break;
828   }
829 }
830 
831 /*******************************************************************************
832  *
833  * Function         btif_hf_client_upstreams_evt
834  *
835  * Description      Executes HF CLIENT UPSTREAMS events in btif context
836  *
837  * Returns          void
838  *
839  ******************************************************************************/
btif_hf_client_upstreams_evt(uint16_t event,char * p_param)840 static void btif_hf_client_upstreams_evt(uint16_t event, char* p_param) {
841   tBTA_HF_CLIENT* p_data = (tBTA_HF_CLIENT*)p_param;
842 
843   btif_hf_client_cb_t* cb = btif_hf_client_get_cb_by_bda(p_data->bd_addr);
844   if (cb == NULL && event == BTA_HF_CLIENT_OPEN_EVT) {
845     log::verbose("event BTA_HF_CLIENT_OPEN_EVT allocating block");
846     cb = btif_hf_client_allocate_cb();
847     if (cb == NULL) {
848       log::error("event BTA_HF_CLIENT_OPEN_EVT failed to allocate cb");
849       return;
850     }
851     cb->handle = p_data->open.handle;
852     cb->peer_bda = p_data->open.bd_addr;
853   } else if (cb == NULL) {
854     log::error("event {} but not allocating block: cb not found", event);
855     return;
856   }
857 
858   log::verbose("event={} ({})", dump_hf_client_event(event), event);
859 
860   switch (event) {
861     case BTA_HF_CLIENT_OPEN_EVT:
862       if (p_data->open.status == BTA_HF_CLIENT_SUCCESS) {
863         cb->state = BTHF_CLIENT_CONNECTION_STATE_CONNECTED;
864         cb->peer_feat = 0;
865         cb->chld_feat = 0;
866         cb->handle = p_data->open.handle;
867       } else if (cb->state == BTHF_CLIENT_CONNECTION_STATE_CONNECTING) {
868         cb->state = BTHF_CLIENT_CONNECTION_STATE_DISCONNECTED;
869       } else {
870         log::warn(
871             "HF CLient open failed, but another device connected. status={} "
872             "state={} connected device={}",
873             p_data->open.status, cb->state, cb->peer_bda);
874         break;
875       }
876 
877       HAL_CBACK(bt_hf_client_callbacks, connection_state_cb, &cb->peer_bda,
878                 cb->state, 0, /* peer feat */
879                 0 /* AT+CHLD feat */);
880 
881       if (cb->state == BTHF_CLIENT_CONNECTION_STATE_DISCONNECTED)
882         cb->peer_bda = RawAddress::kAny;
883 
884       if (p_data->open.status != BTA_HF_CLIENT_SUCCESS) btif_queue_advance();
885       break;
886 
887     case BTA_HF_CLIENT_CONN_EVT:
888       cb->peer_feat = p_data->conn.peer_feat;
889       cb->chld_feat = p_data->conn.chld_feat;
890       cb->state = BTHF_CLIENT_CONNECTION_STATE_SLC_CONNECTED;
891 
892       HAL_CBACK(bt_hf_client_callbacks, connection_state_cb, &cb->peer_bda,
893                 cb->state, cb->peer_feat, cb->chld_feat);
894 
895       /* Inform the application about in-band ringtone */
896       if (cb->peer_feat & BTA_HF_CLIENT_PEER_INBAND) {
897         HAL_CBACK(bt_hf_client_callbacks, in_band_ring_tone_cb, &cb->peer_bda,
898                   BTHF_CLIENT_IN_BAND_RINGTONE_PROVIDED);
899       }
900 
901       btif_queue_advance();
902       break;
903 
904     case BTA_HF_CLIENT_CLOSE_EVT:
905       cb->state = BTHF_CLIENT_CONNECTION_STATE_DISCONNECTED;
906       HAL_CBACK(bt_hf_client_callbacks, connection_state_cb, &cb->peer_bda,
907                 cb->state, 0, 0);
908       cb->peer_bda = RawAddress::kAny;
909       cb->peer_feat = 0;
910       cb->chld_feat = 0;
911       cb->handle = 0;
912 
913       /* Clean up any btif_hf_client_cb for the same disconnected bd_addr.
914        * when there is an Incoming hf_client connection is in progress and
915        * at the same time, outgoing hf_client connection is initiated then
916        * due to race condition two btif_hf_client_cb is created. This creates
917        * problem for successive connections
918        */
919       while ((cb = btif_hf_client_get_cb_by_bda(p_data->bd_addr)) != NULL) {
920         cb->state = BTHF_CLIENT_CONNECTION_STATE_DISCONNECTED;
921         cb->peer_bda = RawAddress::kAny;
922         cb->peer_feat = 0;
923         cb->chld_feat = 0;
924         cb->handle = 0;
925       }
926 
927       btif_queue_advance();
928       break;
929 
930     case BTA_HF_CLIENT_IND_EVT:
931       process_ind_evt(&p_data->ind);
932       break;
933 
934     case BTA_HF_CLIENT_MIC_EVT:
935       HAL_CBACK(bt_hf_client_callbacks, volume_change_cb, &cb->peer_bda,
936                 BTHF_CLIENT_VOLUME_TYPE_MIC, p_data->val.value);
937       break;
938 
939     case BTA_HF_CLIENT_SPK_EVT:
940       HAL_CBACK(bt_hf_client_callbacks, volume_change_cb, &cb->peer_bda,
941                 BTHF_CLIENT_VOLUME_TYPE_SPK, p_data->val.value);
942       break;
943 
944     case BTA_HF_CLIENT_VOICE_REC_EVT:
945       HAL_CBACK(bt_hf_client_callbacks, vr_cmd_cb, &cb->peer_bda,
946                 (bthf_client_vr_state_t)p_data->val.value);
947       break;
948 
949     case BTA_HF_CLIENT_OPERATOR_NAME_EVT:
950       HAL_CBACK(bt_hf_client_callbacks, current_operator_cb, &cb->peer_bda,
951                 p_data->operator_name.name);
952       break;
953 
954     case BTA_HF_CLIENT_CLIP_EVT:
955       HAL_CBACK(bt_hf_client_callbacks, clip_cb, &cb->peer_bda,
956                 p_data->number.number);
957       break;
958 
959     case BTA_HF_CLIENT_BINP_EVT:
960       HAL_CBACK(bt_hf_client_callbacks, last_voice_tag_number_callback,
961                 &cb->peer_bda, p_data->number.number);
962       break;
963 
964     case BTA_HF_CLIENT_CCWA_EVT:
965       HAL_CBACK(bt_hf_client_callbacks, call_waiting_cb, &cb->peer_bda,
966                 p_data->number.number);
967       break;
968 
969     case BTA_HF_CLIENT_AT_RESULT_EVT:
970       HAL_CBACK(bt_hf_client_callbacks, cmd_complete_cb, &cb->peer_bda,
971                 (bthf_client_cmd_complete_t)p_data->result.type,
972                 p_data->result.cme);
973       break;
974 
975     case BTA_HF_CLIENT_CLCC_EVT:
976       HAL_CBACK(bt_hf_client_callbacks, current_calls_cb, &cb->peer_bda,
977                 p_data->clcc.idx,
978                 p_data->clcc.inc ? BTHF_CLIENT_CALL_DIRECTION_INCOMING
979                                  : BTHF_CLIENT_CALL_DIRECTION_OUTGOING,
980                 (bthf_client_call_state_t)p_data->clcc.status,
981                 p_data->clcc.mpty ? BTHF_CLIENT_CALL_MPTY_TYPE_MULTI
982                                   : BTHF_CLIENT_CALL_MPTY_TYPE_SINGLE,
983                 p_data->clcc.number_present ? p_data->clcc.number : "");
984       break;
985 
986     case BTA_HF_CLIENT_CNUM_EVT:
987       if (p_data->cnum.service == 4) {
988         HAL_CBACK(bt_hf_client_callbacks, subscriber_info_cb, &cb->peer_bda,
989                   p_data->cnum.number, BTHF_CLIENT_SERVICE_VOICE);
990       } else if (p_data->cnum.service == 5) {
991         HAL_CBACK(bt_hf_client_callbacks, subscriber_info_cb, &cb->peer_bda,
992                   p_data->cnum.number, BTHF_CLIENT_SERVICE_FAX);
993       } else {
994         HAL_CBACK(bt_hf_client_callbacks, subscriber_info_cb, &cb->peer_bda,
995                   p_data->cnum.number, BTHF_CLIENT_SERVICE_UNKNOWN);
996       }
997       break;
998 
999     case BTA_HF_CLIENT_BTRH_EVT:
1000       if (p_data->val.value <= BTRH_CLIENT_RESP_AND_HOLD_REJECT) {
1001         HAL_CBACK(bt_hf_client_callbacks, resp_and_hold_cb, &cb->peer_bda,
1002                   (bthf_client_resp_and_hold_t)p_data->val.value);
1003       }
1004       break;
1005 
1006     case BTA_HF_CLIENT_BSIR_EVT:
1007       if (p_data->val.value != 0) {
1008         HAL_CBACK(bt_hf_client_callbacks, in_band_ring_tone_cb, &cb->peer_bda,
1009                   BTHF_CLIENT_IN_BAND_RINGTONE_PROVIDED);
1010       } else {
1011         HAL_CBACK(bt_hf_client_callbacks, in_band_ring_tone_cb, &cb->peer_bda,
1012                   BTHF_CLIENT_IN_BAND_RINGTONE_NOT_PROVIDED);
1013       }
1014       break;
1015 
1016     case BTA_HF_CLIENT_AUDIO_OPEN_EVT:
1017       HAL_CBACK(bt_hf_client_callbacks, audio_state_cb, &cb->peer_bda,
1018                 BTHF_CLIENT_AUDIO_STATE_CONNECTED);
1019       break;
1020 
1021     case BTA_HF_CLIENT_AUDIO_MSBC_OPEN_EVT:
1022       HAL_CBACK(bt_hf_client_callbacks, audio_state_cb, &cb->peer_bda,
1023                 BTHF_CLIENT_AUDIO_STATE_CONNECTED_MSBC);
1024       break;
1025     case BTA_HF_CLIENT_AUDIO_LC3_OPEN_EVT:
1026       HAL_CBACK(bt_hf_client_callbacks, audio_state_cb, &cb->peer_bda,
1027                 BTHF_CLIENT_AUDIO_STATE_CONNECTED_LC3);
1028       break;
1029     case BTA_HF_CLIENT_AUDIO_CLOSE_EVT:
1030       HAL_CBACK(bt_hf_client_callbacks, audio_state_cb, &cb->peer_bda,
1031                 BTHF_CLIENT_AUDIO_STATE_DISCONNECTED);
1032       break;
1033     case BTA_HF_CLIENT_RING_INDICATION:
1034       HAL_CBACK(bt_hf_client_callbacks, ring_indication_cb, &cb->peer_bda);
1035       break;
1036     case BTA_HF_CLIENT_UNKNOWN_EVT:
1037       HAL_CBACK(bt_hf_client_callbacks, unknown_event_cb, &cb->peer_bda,
1038                 p_data->unknown.event_string);
1039       break;
1040     default:
1041       log::warn("Unhandled event: {}", event);
1042       break;
1043   }
1044 }
1045 
1046 /*******************************************************************************
1047  *
1048  * Function         bta_hf_client_evt
1049  *
1050  * Description      Switches context from BTA to BTIF for all HF Client events
1051  *
1052  * Returns          void
1053  *
1054  ******************************************************************************/
1055 
bta_hf_client_evt(tBTA_HF_CLIENT_EVT event,tBTA_HF_CLIENT * p_data)1056 static void bta_hf_client_evt(tBTA_HF_CLIENT_EVT event,
1057                               tBTA_HF_CLIENT* p_data) {
1058   bt_status_t status;
1059 
1060   /* switch context to btif task context (copy full union size for convenience)
1061    */
1062   status = btif_transfer_context(btif_hf_client_upstreams_evt, (uint16_t)event,
1063                                  (char*)p_data, sizeof(*p_data), NULL);
1064 
1065   /* catch any failed context transfers */
1066   ASSERTC(status == BT_STATUS_SUCCESS, "context transfer failed", status);
1067 }
1068 
1069 /*******************************************************************************
1070  *
1071  * Function         btif_hf_client_execute_service
1072  *
1073  * Description      Initializes/Shuts down the service
1074  *
1075  * Returns          BT_STATUS_SUCCESS on success, BT_STATUS_FAIL otherwise
1076  *
1077  ******************************************************************************/
btif_hf_client_execute_service(bool b_enable)1078 bt_status_t btif_hf_client_execute_service(bool b_enable) {
1079   log::verbose("enable: {}", b_enable);
1080 
1081   tBTA_HF_CLIENT_FEAT features = get_default_hf_client_features();
1082   uint16_t hfp_version = get_default_hfp_version();
1083   if (hfp_version >= HFP_VERSION_1_9 &&
1084       hfp_hal_interface::get_swb_supported()) {
1085     features |= BTA_HF_CLIENT_FEAT_SWB;
1086   }
1087   if (hfp_version >= HFP_VERSION_1_7) {
1088     features |= BTA_HF_CLIENT_FEAT_ESCO_S4;
1089   }
1090 
1091   if (b_enable) {
1092     /* Enable and register with BTA-HFClient */
1093     log::verbose("support codec negotiation {}", features);
1094     BTA_HfClientEnable(bta_hf_client_evt, features,
1095                        BTIF_HF_CLIENT_SERVICE_NAME);
1096   } else {
1097     BTA_HfClientDisable();
1098   }
1099   return BT_STATUS_SUCCESS;
1100 }
1101 
1102 /*******************************************************************************
1103  *
1104  * Function         btif_hf_get_interface
1105  *
1106  * Description      Get the hf callback interface
1107  *
1108  * Returns          bthf_interface_t
1109  *
1110  ******************************************************************************/
btif_hf_client_get_interface(void)1111 const bthf_client_interface_t* btif_hf_client_get_interface(void) {
1112   log::verbose("");
1113   return &bthfClientInterface;
1114 }
1115