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