1 /******************************************************************************
2  *
3  *  Copyright (c) 2016 The Android Open Source Project
4  *  Copyright 2003-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 #include <bluetooth/log.h>
21 
22 #include <cstdint>
23 #include <cstdio>
24 
25 #include "bta/hf_client/bta_hf_client_int.h"
26 #include "bta/include/utl.h"
27 #include "internal_include/bt_target.h"
28 #include "osi/include/allocator.h"
29 #include "stack/include/bt_hdr.h"
30 #include "stack/include/btm_api.h"
31 #include "stack/include/sdp_api.h"
32 #include "types/raw_address.h"
33 
34 using namespace bluetooth::legacy::stack::sdp;
35 using namespace bluetooth;
36 
37 static const char* bta_hf_client_evt_str(uint16_t event);
38 static const char* bta_hf_client_state_str(uint8_t state);
39 void bta_hf_client_cb_init(tBTA_HF_CLIENT_CB* client_cb, uint16_t handle);
40 
41 /* state machine states */
42 enum {
43   BTA_HF_CLIENT_INIT_ST,
44   BTA_HF_CLIENT_OPENING_ST,
45   BTA_HF_CLIENT_OPEN_ST,
46   BTA_HF_CLIENT_CLOSING_ST
47 };
48 
49 /* state machine action enumeration list */
50 enum {
51   BTA_HF_CLIENT_RFC_DO_CLOSE,
52   BTA_HF_CLIENT_START_CLOSE,
53   BTA_HF_CLIENT_START_OPEN,
54   BTA_HF_CLIENT_RFC_ACP_OPEN,
55   BTA_HF_CLIENT_SCO_LISTEN,
56   BTA_HF_CLIENT_SCO_CONN_OPEN,
57   BTA_HF_CLIENT_SCO_CONN_CLOSE,
58   BTA_HF_CLIENT_SCO_OPEN,
59   BTA_HF_CLIENT_SCO_CLOSE,
60   BTA_HF_CLIENT_FREE_DB,
61   BTA_HF_CLIENT_OPEN_FAIL,
62   BTA_HF_CLIENT_RFC_OPEN,
63   BTA_HF_CLIENT_RFC_FAIL,
64   BTA_HF_CLIENT_DISC_INT_RES,
65   BTA_HF_CLIENT_RFC_DO_OPEN,
66   BTA_HF_CLIENT_DISC_FAIL,
67   BTA_HF_CLIENT_RFC_CLOSE,
68   BTA_HF_CLIENT_RFC_DATA,
69   BTA_HF_CLIENT_DISC_ACP_RES,
70   BTA_HF_CLIENT_SVC_CONN_OPEN,
71   BTA_HF_CLIENT_SEND_AT_CMD,
72   BTA_HF_CLIENT_NUM_ACTIONS,
73 };
74 
75 #define BTA_HF_CLIENT_IGNORE BTA_HF_CLIENT_NUM_ACTIONS
76 
77 /* type for action functions */
78 typedef void (*tBTA_HF_CLIENT_ACTION)(tBTA_HF_CLIENT_DATA* p_data);
79 
80 /* action functions table, indexed with action enum */
81 const tBTA_HF_CLIENT_ACTION bta_hf_client_action[] = {
82     /* BTA_HF_CLIENT_RFC_DO_CLOSE */ bta_hf_client_rfc_do_close,
83     /* BTA_HF_CLIENT_START_CLOSE */ bta_hf_client_start_close,
84     /* BTA_HF_CLIENT_START_OPEN */ bta_hf_client_start_open,
85     /* BTA_HF_CLIENT_RFC_ACP_OPEN */ bta_hf_client_rfc_acp_open,
86     /* BTA_HF_CLIENT_SCO_LISTEN */ NULL,
87     /* BTA_HF_CLIENT_SCO_CONN_OPEN */ bta_hf_client_sco_conn_open,
88     /* BTA_HF_CLIENT_SCO_CONN_CLOSE*/ bta_hf_client_sco_conn_close,
89     /* BTA_HF_CLIENT_SCO_OPEN */ bta_hf_client_sco_open,
90     /* BTA_HF_CLIENT_SCO_CLOSE */ bta_hf_client_sco_close,
91     /* BTA_HF_CLIENT_FREE_DB */ bta_hf_client_free_db,
92     /* BTA_HF_CLIENT_OPEN_FAIL */ bta_hf_client_open_fail,
93     /* BTA_HF_CLIENT_RFC_OPEN */ bta_hf_client_rfc_open,
94     /* BTA_HF_CLIENT_RFC_FAIL */ bta_hf_client_rfc_fail,
95     /* BTA_HF_CLIENT_DISC_INT_RES */ bta_hf_client_disc_int_res,
96     /* BTA_HF_CLIENT_RFC_DO_OPEN */ bta_hf_client_rfc_do_open,
97     /* BTA_HF_CLIENT_DISC_FAIL */ bta_hf_client_disc_fail,
98     /* BTA_HF_CLIENT_RFC_CLOSE */ bta_hf_client_rfc_close,
99     /* BTA_HF_CLIENT_RFC_DATA */ bta_hf_client_rfc_data,
100     /* BTA_HF_CLIENT_DISC_ACP_RES */ bta_hf_client_disc_acp_res,
101     /* BTA_HF_CLIENT_SVC_CONN_OPEN */ bta_hf_client_svc_conn_open,
102     /* BTA_HF_CLIENT_SEND_AT_CMD */ bta_hf_client_send_at_cmd,
103 };
104 
105 /* state table information */
106 #define BTA_HF_CLIENT_ACTIONS 2    /* number of actions */
107 #define BTA_HF_CLIENT_NEXT_STATE 2 /* position of next state */
108 #define BTA_HF_CLIENT_NUM_COLS 3   /* number of columns in state tables */
109 
110 /* state table for init state */
111 const uint8_t bta_hf_client_st_init[][BTA_HF_CLIENT_NUM_COLS] = {
112     /* Event                    Action 1                       Action 2
113        Next state */
114     /* API_OPEN_EVT */ {BTA_HF_CLIENT_START_OPEN, BTA_HF_CLIENT_IGNORE,
115                         BTA_HF_CLIENT_OPENING_ST},
116     /* API_CLOSE_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE,
117                          BTA_HF_CLIENT_INIT_ST},
118     /* API_AUDIO_OPEN_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE,
119                               BTA_HF_CLIENT_INIT_ST},
120     /* API_AUDIO_CLOSE_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE,
121                                BTA_HF_CLIENT_INIT_ST},
122     /* RFC_OPEN_EVT */ {BTA_HF_CLIENT_RFC_ACP_OPEN, BTA_HF_CLIENT_IGNORE,
123                         BTA_HF_CLIENT_OPEN_ST},
124     /* RFC_CLOSE_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE,
125                          BTA_HF_CLIENT_INIT_ST},
126     /* RFC_SRV_CLOSE_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE,
127                              BTA_HF_CLIENT_INIT_ST},
128     /* RFC_DATA_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE,
129                         BTA_HF_CLIENT_INIT_ST},
130     /* DISC_ACP_RES_EVT */ {BTA_HF_CLIENT_FREE_DB, BTA_HF_CLIENT_IGNORE,
131                             BTA_HF_CLIENT_INIT_ST},
132     /* DISC_INT_RES_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE,
133                             BTA_HF_CLIENT_INIT_ST},
134     /* DISC_OK_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE,
135                        BTA_HF_CLIENT_INIT_ST},
136     /* DISC_FAIL_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE,
137                          BTA_HF_CLIENT_INIT_ST},
138     /* SCO_OPEN_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE,
139                         BTA_HF_CLIENT_INIT_ST},
140     /* SCO_CLOSE_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE,
141                          BTA_HF_CLIENT_INIT_ST},
142     /* SEND_AT_CMD_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE,
143                            BTA_HF_CLIENT_INIT_ST},
144 };
145 
146 /* state table for opening state */
147 const uint8_t bta_hf_client_st_opening[][BTA_HF_CLIENT_NUM_COLS] = {
148     /* Event                    Action 1                       Action 2
149        Next state */
150     /* API_OPEN_EVT */ {BTA_HF_CLIENT_OPEN_FAIL, BTA_HF_CLIENT_IGNORE,
151                         BTA_HF_CLIENT_OPENING_ST},
152     /* API_CLOSE_EVT */ {BTA_HF_CLIENT_RFC_DO_CLOSE, BTA_HF_CLIENT_IGNORE,
153                          BTA_HF_CLIENT_CLOSING_ST},
154     /* API_AUDIO_OPEN_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE,
155                               BTA_HF_CLIENT_OPENING_ST},
156     /* API_AUDIO_CLOSE_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE,
157                                BTA_HF_CLIENT_OPENING_ST},
158     /* RFC_OPEN_EVT */ {BTA_HF_CLIENT_RFC_OPEN, BTA_HF_CLIENT_IGNORE,
159                         BTA_HF_CLIENT_OPEN_ST},
160     /* RFC_CLOSE_EVT */ {BTA_HF_CLIENT_RFC_FAIL, BTA_HF_CLIENT_IGNORE,
161                          BTA_HF_CLIENT_INIT_ST},
162     /* RFC_SRV_CLOSE_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE,
163                              BTA_HF_CLIENT_OPENING_ST},
164     /* RFC_DATA_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE,
165                         BTA_HF_CLIENT_OPENING_ST},
166     /* DISC_ACP_RES_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE,
167                             BTA_HF_CLIENT_OPENING_ST},
168     /* DISC_INT_RES_EVT */ {BTA_HF_CLIENT_DISC_INT_RES, BTA_HF_CLIENT_IGNORE,
169                             BTA_HF_CLIENT_OPENING_ST},
170     /* DISC_OK_EVT */ {BTA_HF_CLIENT_RFC_DO_OPEN, BTA_HF_CLIENT_IGNORE,
171                        BTA_HF_CLIENT_OPENING_ST},
172     /* DISC_FAIL_EVT */ {BTA_HF_CLIENT_DISC_FAIL, BTA_HF_CLIENT_IGNORE,
173                          BTA_HF_CLIENT_INIT_ST},
174     /* SCO_OPEN_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE,
175                         BTA_HF_CLIENT_OPENING_ST},
176     /* SCO_CLOSE_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE,
177                          BTA_HF_CLIENT_OPENING_ST},
178     /* SEND_AT_CMD_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE,
179                            BTA_HF_CLIENT_OPENING_ST},
180 };
181 
182 /* state table for open state */
183 const uint8_t bta_hf_client_st_open[][BTA_HF_CLIENT_NUM_COLS] = {
184     /* Event                    Action 1                       Action 2
185        Next state */
186     /* API_OPEN_EVT */ {BTA_HF_CLIENT_OPEN_FAIL, BTA_HF_CLIENT_IGNORE,
187                         BTA_HF_CLIENT_OPEN_ST},
188     /* API_CLOSE_EVT */ {BTA_HF_CLIENT_START_CLOSE, BTA_HF_CLIENT_IGNORE,
189                          BTA_HF_CLIENT_CLOSING_ST},
190     /* API_AUDIO_OPEN_EVT */ {BTA_HF_CLIENT_SCO_OPEN, BTA_HF_CLIENT_IGNORE,
191                               BTA_HF_CLIENT_OPEN_ST},
192     /* API_AUDIO_CLOSE_EVT */ {BTA_HF_CLIENT_SCO_CLOSE, BTA_HF_CLIENT_IGNORE,
193                                BTA_HF_CLIENT_OPEN_ST},
194     /* RFC_OPEN_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE,
195                         BTA_HF_CLIENT_OPEN_ST},
196     /* RFC_CLOSE_EVT */ {BTA_HF_CLIENT_RFC_CLOSE, BTA_HF_CLIENT_IGNORE,
197                          BTA_HF_CLIENT_INIT_ST},
198     /* RFC_SRV_CLOSE_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE,
199                              BTA_HF_CLIENT_OPEN_ST},
200     /* RFC_DATA_EVT */ {BTA_HF_CLIENT_RFC_DATA, BTA_HF_CLIENT_IGNORE,
201                         BTA_HF_CLIENT_OPEN_ST},
202     /* DISC_ACP_RES_EVT */ {BTA_HF_CLIENT_DISC_ACP_RES, BTA_HF_CLIENT_IGNORE,
203                             BTA_HF_CLIENT_OPEN_ST},
204     /* DISC_INT_RES_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE,
205                             BTA_HF_CLIENT_OPEN_ST},
206     /* DISC_OK_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE,
207                        BTA_HF_CLIENT_OPEN_ST},
208     /* DISC_FAIL_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE,
209                          BTA_HF_CLIENT_OPEN_ST},
210     /* SCO_OPEN_EVT */ {BTA_HF_CLIENT_SCO_CONN_OPEN, BTA_HF_CLIENT_IGNORE,
211                         BTA_HF_CLIENT_OPEN_ST},
212     /* SCO_CLOSE_EVT */ {BTA_HF_CLIENT_SCO_CONN_CLOSE, BTA_HF_CLIENT_IGNORE,
213                          BTA_HF_CLIENT_OPEN_ST},
214     /* SEND_AT_CMD_EVT */ {BTA_HF_CLIENT_SEND_AT_CMD, BTA_HF_CLIENT_IGNORE,
215                            BTA_HF_CLIENT_OPEN_ST},
216 };
217 
218 /* state table for closing state */
219 const uint8_t bta_hf_client_st_closing[][BTA_HF_CLIENT_NUM_COLS] = {
220     /* Event                    Action 1                       Action 2
221        Next state */
222     /* API_OPEN_EVT */ {BTA_HF_CLIENT_OPEN_FAIL, BTA_HF_CLIENT_IGNORE,
223                         BTA_HF_CLIENT_CLOSING_ST},
224     /* API_CLOSE_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE,
225                          BTA_HF_CLIENT_CLOSING_ST},
226     /* API_AUDIO_OPEN_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE,
227                               BTA_HF_CLIENT_CLOSING_ST},
228     /* API_AUDIO_CLOSE_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE,
229                                BTA_HF_CLIENT_CLOSING_ST},
230     /* RFC_OPEN_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE,
231                         BTA_HF_CLIENT_CLOSING_ST},
232     /* RFC_CLOSE_EVT */ {BTA_HF_CLIENT_RFC_CLOSE, BTA_HF_CLIENT_IGNORE,
233                          BTA_HF_CLIENT_INIT_ST},
234     /* RFC_SRV_CLOSE_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE,
235                              BTA_HF_CLIENT_CLOSING_ST},
236     /* RFC_DATA_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE,
237                         BTA_HF_CLIENT_CLOSING_ST},
238     /* DISC_ACP_RES_EVT */ {BTA_HF_CLIENT_FREE_DB, BTA_HF_CLIENT_IGNORE,
239                             BTA_HF_CLIENT_CLOSING_ST},
240     /* DISC_INT_RES_EVT */ {BTA_HF_CLIENT_FREE_DB, BTA_HF_CLIENT_IGNORE,
241                             BTA_HF_CLIENT_INIT_ST},
242     /* DISC_OK_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE,
243                        BTA_HF_CLIENT_CLOSING_ST},
244     /* DISC_FAIL_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE,
245                          BTA_HF_CLIENT_CLOSING_ST},
246     /* SCO_OPEN_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE,
247                         BTA_HF_CLIENT_CLOSING_ST},
248     /* SCO_CLOSE_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE,
249                          BTA_HF_CLIENT_CLOSING_ST},
250     /* SEND_AT_CMD_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE,
251                            BTA_HF_CLIENT_CLOSING_ST},
252 };
253 
254 /* type for state table */
255 typedef const uint8_t (*tBTA_HF_CLIENT_ST_TBL)[BTA_HF_CLIENT_NUM_COLS];
256 
257 /* state table */
258 const tBTA_HF_CLIENT_ST_TBL bta_hf_client_st_tbl[] = {
259     bta_hf_client_st_init, bta_hf_client_st_opening, bta_hf_client_st_open,
260     bta_hf_client_st_closing};
261 
262 /* HF Client control block */
263 tBTA_HF_CLIENT_CB_ARR bta_hf_client_cb_arr;
264 
265 /* Event handler for the state machine */
266 static const tBTA_SYS_REG bta_hf_client_reg = {bta_hf_client_hdl_event,
267                                                BTA_HfClientDisable};
268 
269 /*******************************************************************************
270  *
271  * Function         bta_hf_client_cb_arr_init
272  *
273  * Description      Initialize entire control block array set
274  *
275  *
276  * Returns          void
277  *
278  ******************************************************************************/
bta_hf_client_cb_arr_init()279 void bta_hf_client_cb_arr_init() {
280   memset(&bta_hf_client_cb_arr, 0, sizeof(tBTA_HF_CLIENT_CB_ARR));
281 
282   // reset the handles and make the CBs non-allocated
283   for (int i = 0; i < HF_CLIENT_MAX_DEVICES; i++) {
284     // Allocate the handles in increasing order of indices
285     bta_hf_client_cb_init(&(bta_hf_client_cb_arr.cb[i]), i);
286     bta_hf_client_cb_arr.cb[i].handle = BTA_HF_CLIENT_CB_FIRST_HANDLE + i;
287   }
288 }
289 
290 /*******************************************************************************
291  *
292  * Function         bta_hf_client_cb_init
293  *
294  * Description      Initialize an HF_Client service control block. Assign the
295  *                  handle to cb->handle.
296  *
297  *
298  *
299  * Returns          void
300  *
301  ******************************************************************************/
bta_hf_client_cb_init(tBTA_HF_CLIENT_CB * client_cb,uint16_t handle)302 void bta_hf_client_cb_init(tBTA_HF_CLIENT_CB* client_cb, uint16_t handle) {
303   log::verbose("");
304 
305   // Free any memory we need to explicity release
306   alarm_free(client_cb->collision_timer);
307 
308   // release unique pointers
309   client_cb->enabled_hf_indicators.clear();
310   client_cb->peer_hf_indicators.clear();
311 
312   // Memset the rest of the block
313   // memset(client_cb, 0, sizeof(tBTA_HF_CLIENT_CB));
314   *client_cb = {};
315 
316   // Re allocate any variables required
317   client_cb->collision_timer = alarm_new("bta_hf_client.scb_collision_timer");
318   client_cb->handle = handle;
319   client_cb->sco_idx = BTM_INVALID_SCO_INDEX;
320 }
321 
322 /*******************************************************************************
323  *
324  * Function         bta_hf_client_resume_open
325  *
326  * Description      Resume opening process.
327  *
328  *
329  * Returns          void
330  *
331  ******************************************************************************/
bta_hf_client_resume_open(tBTA_HF_CLIENT_CB * client_cb)332 void bta_hf_client_resume_open(tBTA_HF_CLIENT_CB* client_cb) {
333   log::verbose("");
334 
335   /* resume opening process.  */
336   if (client_cb->state == BTA_HF_CLIENT_INIT_ST) {
337     client_cb->state = BTA_HF_CLIENT_OPENING_ST;
338     tBTA_HF_CLIENT_DATA msg;
339     msg.hdr.layer_specific = client_cb->handle;
340     msg.api_open.bd_addr = client_cb->peer_addr;
341     bta_hf_client_start_open(&msg);
342   }
343 }
344 
345 /*******************************************************************************
346  *
347  * Function         bta_hf_client_collision_timer_cback
348  *
349  * Description      HF Client connection collision timer callback
350  *
351  *
352  * Returns          void
353  *
354  ******************************************************************************/
bta_hf_client_collision_timer_cback(void * data)355 static void bta_hf_client_collision_timer_cback(void* data) {
356   log::verbose("");
357   tBTA_HF_CLIENT_CB* client_cb = (tBTA_HF_CLIENT_CB*)data;
358 
359   /* If the peer haven't opened connection, restart opening process */
360   bta_hf_client_resume_open(client_cb);
361 }
362 
363 /*******************************************************************************
364  *
365  * Function         bta_hf_client_collision_cback
366  *
367  * Description      Get notified about collision.
368  *
369  *
370  * Returns          void
371  *
372  ******************************************************************************/
bta_hf_client_collision_cback(tBTA_SYS_CONN_STATUS,tBTA_SYS_ID id,uint8_t,const RawAddress & peer_addr)373 void bta_hf_client_collision_cback(tBTA_SYS_CONN_STATUS /* status */,
374                                    tBTA_SYS_ID id, uint8_t /* app_id */,
375                                    const RawAddress& peer_addr) {
376   tBTA_HF_CLIENT_CB* client_cb = bta_hf_client_find_cb_by_bda(peer_addr);
377   if (client_cb != NULL && client_cb->state == BTA_HF_CLIENT_OPENING_ST) {
378     if (id == BTA_ID_SYS) /* ACL collision */
379     {
380       log::warn("HF Client found collision (ACL) ...");
381     } else if (id == BTA_ID_HS) /* RFCOMM collision */
382     {
383       log::warn("HF Client found collision (RFCOMM) ...");
384     } else {
385       log::warn("HF Client found collision (\?\?\?) ...");
386     }
387 
388     client_cb->state = BTA_HF_CLIENT_INIT_ST;
389 
390     /* Cancel SDP if it had been started. */
391     if (client_cb->p_disc_db) {
392       if (!get_legacy_stack_sdp_api()->service.SDP_CancelServiceSearch(
393               client_cb->p_disc_db)) {
394         log::warn("Unable to cancel SDP service discovery peer:{}", peer_addr);
395       }
396       osi_free_and_reset((void**)&client_cb->p_disc_db);
397     }
398 
399     /* reopen registered server */
400     /* Collision may be detected before or after we close servers. */
401     bta_hf_client_start_server();
402 
403     /* Start timer to handle connection opening restart */
404     alarm_set_on_mloop(client_cb->collision_timer,
405                        BTA_HF_CLIENT_COLLISION_TIMER_MS,
406                        bta_hf_client_collision_timer_cback, (void*)client_cb);
407   }
408 }
409 
410 /*******************************************************************************
411  *
412  * Function         bta_hf_client_api_enable
413  *
414  * Description      Handle an API enable event.
415  *
416  *
417  * Returns          void
418  *
419  ******************************************************************************/
bta_hf_client_api_enable(tBTA_HF_CLIENT_CBACK * p_cback,tBTA_HF_CLIENT_FEAT features,const char * p_service_name)420 tBTA_STATUS bta_hf_client_api_enable(tBTA_HF_CLIENT_CBACK* p_cback,
421                                      tBTA_HF_CLIENT_FEAT features,
422                                      const char* p_service_name) {
423   /* If already registered then return error */
424   if (bta_sys_is_register(BTA_ID_HS)) {
425     log::error("BTA HF Client is already enabled, ignoring ...");
426     return BTA_FAILURE;
427   }
428 
429   /* register with BTA system manager */
430   bta_sys_register(BTA_ID_HS, &bta_hf_client_reg);
431 
432   /* reset the control blocks */
433   bta_hf_client_cb_arr_init();
434 
435   bta_hf_client_cb_arr.p_cback = p_cback;
436   bta_hf_client_cb_arr.features = features;
437   bta_hf_client_cb_arr.is_support_lc3 = features & BTA_HF_CLIENT_FEAT_SWB;
438 
439   /* create SDP records */
440   bta_hf_client_create_record(&bta_hf_client_cb_arr, p_service_name);
441 
442   /* set same setting as AG does */
443   BTM_WriteVoiceSettings(AG_VOICE_SETTINGS);
444 
445   bta_sys_collision_register(BTA_ID_HS, bta_hf_client_collision_cback);
446 
447   /* Set the Audio service class bit */
448   tBTA_UTL_COD cod = {
449     .minor = BTM_COD_MINOR_UNCLASSIFIED,
450     .major = BTM_COD_MAJOR_UNCLASSIFIED,
451     .service = BTM_COD_SERVICE_AUDIO,
452   };
453   utl_set_device_class(&cod, BTA_UTL_SET_COD_SERVICE_CLASS);
454 
455   /* start RFCOMM server */
456   bta_hf_client_start_server();
457 
458   return BTA_SUCCESS;
459 }
460 
461 /*******************************************************************************
462  *
463  * Function         bta_hf_client_find_cb_by_handle
464  *
465  * Description      Finds the control block by handle provided
466  *
467  *                  handle: Handle as obtained from BTA_HfClientOpen call
468  *
469  *
470  * Returns          Control block corresponding to the handle and NULL if
471  *                  none exists
472  *
473  ******************************************************************************/
bta_hf_client_find_cb_by_handle(uint16_t handle)474 tBTA_HF_CLIENT_CB* bta_hf_client_find_cb_by_handle(uint16_t handle) {
475   // Handles are limited from 1 through HF_CLIENT_MAX_DEVICES
476   if (handle < 1 || handle > HF_CLIENT_MAX_DEVICES) {
477     log::error("handle out of range ({}, {}) {}", 1, HF_CLIENT_MAX_DEVICES,
478                handle);
479     return NULL;
480   }
481 
482   // Check if the associated index is allocated. Index is (handle - 1).
483   if (bta_hf_client_cb_arr.cb[handle - 1].is_allocated)
484     return &(bta_hf_client_cb_arr.cb[handle - 1]);
485 
486   log::error("block not found for handle {}", handle);
487   return NULL;
488 }
489 
490 /*******************************************************************************
491  *
492  * Function         bta_hf_client_find_cb_by_bda
493  *
494  * Description      Finds the control block by handle provided
495  *
496  *                  bda: address of the device to find the handle for.
497  *                  Since there can only be one HF connection for a device
498  *                  we should always find a unique block
499  *
500  * Returns          Control block corresponding to the address and NULL if
501  *                  none exists
502  *
503  ******************************************************************************/
bta_hf_client_find_cb_by_bda(const RawAddress & peer_addr)504 tBTA_HF_CLIENT_CB* bta_hf_client_find_cb_by_bda(const RawAddress& peer_addr) {
505   for (int i = 0; i < HF_CLIENT_MAX_DEVICES; i++) {
506     // Check if the associated index is allocated and that BD ADDR matches
507     tBTA_HF_CLIENT_CB* client_cb = &bta_hf_client_cb_arr.cb[i];
508     if (client_cb->is_allocated && peer_addr == client_cb->peer_addr) {
509       return client_cb;
510     } else {
511       log::warn("bdaddr mismatch for handle {} alloc {}", i,
512                 client_cb->is_allocated);
513     }
514   }
515   log::error("block not found");
516   return NULL;
517 }
518 
519 /*******************************************************************************
520  *
521  * Function         bta_hf_client_find_cb_by_rfc_handle
522  *
523  * Description      Finds the control block by RFC handle provided.
524  *
525  *                  handle: RFC handle for the established connection
526  *
527  *
528  * Returns          Control block corresponding to the handle and NULL if none
529  *                  exists
530  *
531  ******************************************************************************/
bta_hf_client_find_cb_by_rfc_handle(uint16_t handle)532 tBTA_HF_CLIENT_CB* bta_hf_client_find_cb_by_rfc_handle(uint16_t handle) {
533   for (int i = 0; i < HF_CLIENT_MAX_DEVICES; i++) {
534     tBTA_HF_CLIENT_CB* client_cb = &bta_hf_client_cb_arr.cb[i];
535     bool is_allocated = client_cb->is_allocated;
536     uint16_t conn_handle = client_cb->conn_handle;
537 
538     log::verbose("cb rfc_handle {} alloc {} conn_handle {}", handle,
539                  is_allocated, conn_handle);
540 
541     if (is_allocated && conn_handle == handle) {
542       return client_cb;
543     }
544 
545     log::warn("no cb yet {} alloc {} conn_handle {}", handle, is_allocated,
546               conn_handle);
547   }
548 
549   log::error("no cb found for rfc handle {}", handle);
550   return NULL;
551 }
552 
553 /*******************************************************************************
554  *
555  * Function         bta_hf_client_find_cb_by_sco_handle
556  *
557  * Description      Finds the control block by sco handle provided
558  *
559  *                  handle: sco handle
560  *
561  *
562  * Returns          Control block corresponding to the sco handle and
563  *                  none if none exists
564  *
565  ******************************************************************************/
bta_hf_client_find_cb_by_sco_handle(uint16_t handle)566 tBTA_HF_CLIENT_CB* bta_hf_client_find_cb_by_sco_handle(uint16_t handle) {
567   for (int i = 0; i < HF_CLIENT_MAX_DEVICES; i++) {
568     tBTA_HF_CLIENT_CB* client_cb = &bta_hf_client_cb_arr.cb[i];
569     if (client_cb->is_allocated && client_cb->sco_idx == handle) {
570       return client_cb;
571     }
572   }
573   log::error("block not found for handle {}", handle);
574   return NULL;
575 }
576 
577 /*******************************************************************************
578  *
579  * Function         bta_hf_client_allocate_handle
580  *
581  * Description      Allocates a handle for the new BD ADDR that needs a new RF
582  *                  channel for HF connection. If the channel cannot be created
583  *                  for a reason then false is returned
584  *
585  *                  bd_addr: Address of the device for which this block is
586  *                  being created. Single device can only have one block.
587  *                  p_handle: OUT variable to store the outcome of allocate. If
588  *                  allocate failed then value is not valid
589  *
590  *
591  * Returns          true if the creation of p_handle succeeded, false otherwise
592  *
593  ******************************************************************************/
bta_hf_client_allocate_handle(const RawAddress & bd_addr,uint16_t * p_handle)594 bool bta_hf_client_allocate_handle(const RawAddress& bd_addr,
595                                    uint16_t* p_handle) {
596   tBTA_HF_CLIENT_CB* existing_cb = bta_hf_client_find_cb_by_bda(bd_addr);
597   if (existing_cb != NULL) {
598     log::error("cannot allocate handle since BDADDR already exists");
599     return false;
600   }
601   /* Check that we do not have a request to for same device in the control
602    * blocks */
603   for (int i = 0; i < HF_CLIENT_MAX_DEVICES; i++) {
604     tBTA_HF_CLIENT_CB* client_cb = &bta_hf_client_cb_arr.cb[i];
605     if (client_cb->is_allocated) {
606       log::warn("control block already used index {}", i);
607       continue;
608     }
609 
610     // Reset the client control block
611     bta_hf_client_cb_init(client_cb, client_cb->handle);
612 
613     *p_handle = client_cb->handle;
614     log::verbose("marking CB handle {} to true", client_cb->handle);
615 
616     client_cb->is_allocated = true;
617     client_cb->peer_addr = bd_addr;
618     bta_hf_client_at_init(client_cb);
619     return true;
620   }
621 
622   return false;
623   log::error("all control blocks in use!");
624 }
625 
626 /*******************************************************************************
627  *
628  * Function         bta_hf_client_app_callback
629  *
630  * Description      Calls the application callback
631  *
632  *
633  * Returns          Void
634  *
635  ******************************************************************************/
bta_hf_client_app_callback(uint16_t event,tBTA_HF_CLIENT * data)636 void bta_hf_client_app_callback(uint16_t event, tBTA_HF_CLIENT* data) {
637   if (bta_hf_client_cb_arr.p_cback != NULL) {
638     bta_hf_client_cb_arr.p_cback(event, data);
639   }
640 }
641 
642 /*******************************************************************************
643  *
644  * Function         bta_hf_client_api_disable
645  *
646  * Description      Handle an API disable event.
647  *
648  *
649  * Returns          void
650  *
651  ******************************************************************************/
bta_hf_client_api_disable()652 void bta_hf_client_api_disable() {
653   if (!bta_sys_is_register(BTA_ID_HS)) {
654     log::warn("BTA HF Client is already disabled, ignoring ...");
655     return;
656   }
657 
658   /* Remove the collision handler */
659   bta_sys_collision_register(BTA_ID_HS, NULL);
660 
661   bta_hf_client_cb_arr.deregister = true;
662 
663   /* remove sdp record */
664   bta_hf_client_del_record(&bta_hf_client_cb_arr);
665 
666   /* remove rfcomm server */
667   bta_hf_client_close_server();
668 
669   /* reinit the control block */
670   for (int i = 0; i < HF_CLIENT_MAX_DEVICES; i++) {
671     if (bta_hf_client_cb_arr.cb[i].is_allocated) {
672       bta_hf_client_cb_init(&(bta_hf_client_cb_arr.cb[i]), i);
673     }
674   }
675 
676   /* De-register with BTA system manager */
677   bta_sys_deregister(BTA_ID_HS);
678 }
679 
680 /*******************************************************************************
681  *
682  * Function         bta_hf_client_hdl_event
683  *
684  * Description      Data HF Client main event handling function.
685  *
686  *
687  * Returns          bool
688  *
689  ******************************************************************************/
bta_hf_client_hdl_event(const BT_HDR_RIGID * p_msg)690 bool bta_hf_client_hdl_event(const BT_HDR_RIGID* p_msg) {
691   log::verbose("{} (0x{:x})", bta_hf_client_evt_str(p_msg->event),
692                p_msg->event);
693   bta_hf_client_sm_execute(p_msg->event, (tBTA_HF_CLIENT_DATA*)p_msg);
694   return true;
695 }
696 
697 /*******************************************************************************
698  *
699  * Function         bta_hf_client_sm_execute
700  *
701  * Description      State machine event handling function for HF Client
702  *
703  *
704  * Returns          void
705  *
706  ******************************************************************************/
bta_hf_client_sm_execute(uint16_t event,tBTA_HF_CLIENT_DATA * p_data)707 void bta_hf_client_sm_execute(uint16_t event, tBTA_HF_CLIENT_DATA* p_data) {
708   tBTA_HF_CLIENT_CB* client_cb =
709       bta_hf_client_find_cb_by_handle(p_data->hdr.layer_specific);
710   if (client_cb == NULL) {
711     log::error("cb not found for handle {}", p_data->hdr.layer_specific);
712     return;
713   }
714 
715   tBTA_HF_CLIENT_ST_TBL state_table;
716   uint8_t action;
717   int i;
718 
719   uint16_t in_event = event;
720   uint8_t in_state = client_cb->state;
721 
722   /* Ignore displaying of AT results when not connected (Ignored in state
723    * machine) */
724   if (client_cb->state == BTA_HF_CLIENT_OPEN_ST) {
725     log::verbose("HF Client evt : State {} ({}), Event 0x{:04x} ({})",
726                  client_cb->state, bta_hf_client_state_str(client_cb->state),
727                  event, bta_hf_client_evt_str(event));
728   }
729 
730   event &= 0x00FF;
731   if (event >= (BTA_HF_CLIENT_MAX_EVT & 0x00FF)) {
732     log::error("HF Client evt out of range, ignoring...");
733     return;
734   }
735 
736   /* look up the state table for the current state */
737   state_table = bta_hf_client_st_tbl[client_cb->state];
738 
739   /* set next state */
740   client_cb->state = state_table[event][BTA_HF_CLIENT_NEXT_STATE];
741 
742   /* execute action functions */
743   for (i = 0; i < BTA_HF_CLIENT_ACTIONS; i++) {
744     action = state_table[event][i];
745     if (action != BTA_HF_CLIENT_IGNORE) {
746       (*bta_hf_client_action[action])(p_data);
747     } else {
748       break;
749     }
750   }
751 
752   /* If the state has changed then notify the app of the corresponding change */
753   if (in_state != client_cb->state) {
754     log::verbose("notifying state change to {} -> {} device {}", in_state,
755                  client_cb->state, client_cb->peer_addr);
756     tBTA_HF_CLIENT evt;
757     memset(&evt, 0, sizeof(evt));
758     evt.bd_addr = client_cb->peer_addr;
759     if (client_cb->state == BTA_HF_CLIENT_INIT_ST) {
760       bta_hf_client_app_callback(BTA_HF_CLIENT_CLOSE_EVT, &evt);
761       log::verbose("marking CB handle {} to false", client_cb->handle);
762       client_cb->is_allocated = false;
763     } else if (client_cb->state == BTA_HF_CLIENT_OPEN_ST) {
764       evt.open.handle = client_cb->handle;
765       bta_hf_client_app_callback(BTA_HF_CLIENT_OPEN_EVT, &evt);
766     }
767   }
768 
769   log::verbose("device {} state change: [{}] -> [{}] after Event [{}]",
770                client_cb->peer_addr, bta_hf_client_state_str(in_state),
771                bta_hf_client_state_str(client_cb->state),
772                bta_hf_client_evt_str(in_event));
773 }
774 
send_post_slc_cmd(tBTA_HF_CLIENT_CB * client_cb)775 static void send_post_slc_cmd(tBTA_HF_CLIENT_CB* client_cb) {
776   client_cb->at_cb.current_cmd = BTA_HF_CLIENT_AT_NONE;
777 
778   tBTA_HF_CLIENT_DATA p_data;
779   p_data.hdr.layer_specific = client_cb->handle;
780   bta_hf_client_sco_listen(&p_data);
781   bta_hf_client_send_at_bia(client_cb);
782   bta_hf_client_send_at_ccwa(client_cb, true);
783   bta_hf_client_send_at_cmee(client_cb, true);
784   bta_hf_client_send_at_cops(client_cb, false);
785   bta_hf_client_send_at_btrh(client_cb, true, 0);
786   bta_hf_client_send_at_clip(client_cb, true);
787 }
788 
789 /*******************************************************************************
790  *
791  * Function         bta_hf_client_slc_seq
792  *
793  * Description      Handles AT commands sequence required for SLC creation
794  *
795  *
796  * Returns          void
797  *
798  ******************************************************************************/
bta_hf_client_slc_seq(tBTA_HF_CLIENT_CB * client_cb,bool error)799 void bta_hf_client_slc_seq(tBTA_HF_CLIENT_CB* client_cb, bool error) {
800   log::verbose("bta_hf_client_slc_seq cmd: {}", client_cb->at_cb.current_cmd);
801 
802   if (error) {
803     /* SLC establishment error, sent close rfcomm event */
804     log::error(
805         "HFPClient: Failed to create SLC due to AT error, disconnecting ({})",
806         client_cb->at_cb.current_cmd);
807 
808     tBTA_HF_CLIENT_DATA msg;
809     msg.hdr.layer_specific = client_cb->handle;
810     bta_hf_client_sm_execute(BTA_HF_CLIENT_API_CLOSE_EVT, &msg);
811     return;
812   }
813 
814   if (client_cb->svc_conn) {
815     log::warn("SLC already connected for CB handle {}", client_cb->handle);
816     return;
817   }
818 
819   switch (client_cb->at_cb.current_cmd) {
820     case BTA_HF_CLIENT_AT_NONE:
821       bta_hf_client_send_at_brsf(client_cb, bta_hf_client_cb_arr.features);
822       break;
823 
824     case BTA_HF_CLIENT_AT_BRSF:
825       if ((bta_hf_client_cb_arr.features & BTA_HF_CLIENT_FEAT_CODEC) &&
826           (client_cb->peer_features & BTA_HF_CLIENT_PEER_CODEC)) {
827         bta_hf_client_send_at_bac(client_cb);
828         break;
829       }
830 
831       bta_hf_client_send_at_cind(client_cb, false);
832       break;
833 
834     case BTA_HF_CLIENT_AT_BAC:
835       bta_hf_client_send_at_cind(client_cb, false);
836       break;
837 
838     case BTA_HF_CLIENT_AT_CIND:
839       bta_hf_client_send_at_cind(client_cb, true);
840       break;
841 
842     case BTA_HF_CLIENT_AT_CIND_STATUS:
843       bta_hf_client_send_at_cmer(client_cb, true);
844       break;
845 
846     case BTA_HF_CLIENT_AT_CMER:
847       if (client_cb->peer_features & BTA_HF_CLIENT_PEER_FEAT_3WAY &&
848           bta_hf_client_cb_arr.features & BTA_HF_CLIENT_FEAT_3WAY) {
849         bta_hf_client_send_at_chld(client_cb, '?', 0);
850       } else if (bta_hf_client_cb_arr.features & BTA_HF_CLIENT_FEAT_HF_IND &&
851                  client_cb->peer_features & BTA_HF_CLIENT_PEER_HF_IND) {
852         bta_hf_client_send_at_bind(client_cb, 0);
853       } else {
854         tBTA_HF_CLIENT_DATA msg;
855         msg.hdr.layer_specific = client_cb->handle;
856         bta_hf_client_svc_conn_open(&msg);
857         send_post_slc_cmd(client_cb);
858       }
859       break;
860 
861     case BTA_HF_CLIENT_AT_CHLD:
862       if (bta_hf_client_cb_arr.features & BTA_HF_CLIENT_FEAT_HF_IND &&
863           client_cb->peer_features & BTA_HF_CLIENT_PEER_HF_IND) {
864         bta_hf_client_send_at_bind(client_cb, 0);
865       } else {
866         tBTA_HF_CLIENT_DATA msg;
867         msg.hdr.layer_specific = client_cb->handle;
868         bta_hf_client_svc_conn_open(&msg);
869         send_post_slc_cmd(client_cb);
870       }
871       break;
872 
873     case BTA_HF_CLIENT_AT_BIND_SET_IND:
874       bta_hf_client_send_at_bind(client_cb, 1);
875       break;
876 
877     case BTA_HF_CLIENT_AT_BIND_READ_SUPPORTED_IND:
878       bta_hf_client_send_at_bind(client_cb, 2);
879       break;
880 
881     case BTA_HF_CLIENT_AT_BIND_READ_ENABLED_IND:
882       tBTA_HF_CLIENT_DATA msg;
883       msg.hdr.layer_specific = client_cb->handle;
884       bta_hf_client_svc_conn_open(&msg);
885       send_post_slc_cmd(client_cb);
886       break;
887 
888     default: {
889       /* If happen there is a bug in SLC creation procedure... */
890       log::error(
891           "HFPClient: Failed to create SLCdue to unexpected AT command, "
892           "disconnecting ({})",
893           client_cb->at_cb.current_cmd);
894 
895       tBTA_HF_CLIENT_DATA msg;
896       msg.hdr.layer_specific = client_cb->handle;
897       bta_hf_client_sm_execute(BTA_HF_CLIENT_API_CLOSE_EVT, &msg);
898       break;
899     }
900   }
901 }
902 
903 #ifndef CASE_RETURN_STR
904 #define CASE_RETURN_STR(const) \
905   case const:                  \
906     return #const;
907 #endif
908 
bta_hf_client_evt_str(uint16_t event)909 static const char* bta_hf_client_evt_str(uint16_t event) {
910   switch (event) {
911     CASE_RETURN_STR(BTA_HF_CLIENT_API_OPEN_EVT)
912     CASE_RETURN_STR(BTA_HF_CLIENT_API_CLOSE_EVT)
913     CASE_RETURN_STR(BTA_HF_CLIENT_API_AUDIO_OPEN_EVT)
914     CASE_RETURN_STR(BTA_HF_CLIENT_API_AUDIO_CLOSE_EVT)
915     CASE_RETURN_STR(BTA_HF_CLIENT_RFC_OPEN_EVT)
916     CASE_RETURN_STR(BTA_HF_CLIENT_RFC_CLOSE_EVT)
917     CASE_RETURN_STR(BTA_HF_CLIENT_RFC_SRV_CLOSE_EVT)
918     CASE_RETURN_STR(BTA_HF_CLIENT_RFC_DATA_EVT)
919     CASE_RETURN_STR(BTA_HF_CLIENT_DISC_ACP_RES_EVT)
920     CASE_RETURN_STR(BTA_HF_CLIENT_DISC_INT_RES_EVT)
921     CASE_RETURN_STR(BTA_HF_CLIENT_DISC_OK_EVT)
922     CASE_RETURN_STR(BTA_HF_CLIENT_DISC_FAIL_EVT)
923     CASE_RETURN_STR(BTA_HF_CLIENT_API_ENABLE_EVT)
924     CASE_RETURN_STR(BTA_HF_CLIENT_API_DISABLE_EVT)
925     CASE_RETURN_STR(BTA_HF_CLIENT_SCO_OPEN_EVT)
926     CASE_RETURN_STR(BTA_HF_CLIENT_SCO_CLOSE_EVT)
927     CASE_RETURN_STR(BTA_HF_CLIENT_SEND_AT_CMD_EVT)
928     default:
929       return "Unknown HF Client Event";
930   }
931 }
932 
bta_hf_client_state_str(uint8_t state)933 static const char* bta_hf_client_state_str(uint8_t state) {
934   switch (state) {
935     CASE_RETURN_STR(BTA_HF_CLIENT_INIT_ST)
936     CASE_RETURN_STR(BTA_HF_CLIENT_OPENING_ST)
937     CASE_RETURN_STR(BTA_HF_CLIENT_OPEN_ST)
938     CASE_RETURN_STR(BTA_HF_CLIENT_CLOSING_ST)
939     default:
940       return "Unknown HF Client State";
941   }
942 }
943 
bta_hf_client_dump_statistics(int fd)944 void bta_hf_client_dump_statistics(int fd) {
945   dprintf(fd, "\nBluetooth HF Client BTA Statistics\n");
946 
947   // We dump statistics for all control blocks
948   for (int i = 0; i < HF_CLIENT_MAX_DEVICES; i++) {
949     tBTA_HF_CLIENT_CB* client_cb = &bta_hf_client_cb_arr.cb[i];
950     if (!client_cb->is_allocated) {
951       // Skip the blocks which are not allocated
952       continue;
953     }
954 
955     dprintf(fd, "  Control block #%d\n", i + 1);
956 
957     uint8_t* a = client_cb->peer_addr.address;
958     // Device name
959     dprintf(fd, "    Peer Device: %02x:%02x:%02x:%02x:%02x:%02x\n", a[0], a[1],
960             a[2], a[3], a[4], a[5]);
961 
962     // State machine state
963     dprintf(fd, "    State Machine State: %s\n",
964             bta_hf_client_state_str(client_cb->state));
965 
966     // Local RFC channelfor communication
967     dprintf(fd, "    RFCOMM Channel (local) %d\n", client_cb->conn_handle);
968 
969     // BTA Handle shared between BTA and client (ex BTIF)
970     dprintf(fd, "    BTA Generated handle %d\n", client_cb->handle);
971   }
972 }
973