1 /*
2  * SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #include <string.h>
8 #include "esp_bt_defs.h"
9 #include "esp_gap_bt_api.h"
10 #include "btc_gap_bt.h"
11 #include "btc/btc_storage.h"
12 #include "bta/bta_api.h"
13 #include "common/bt_trace.h"
14 #include "common/bt_target.h"
15 #include "btc/btc_manage.h"
16 #include "btc/btc_util.h"
17 #include "osi/allocator.h"
18 #include "bta/bta_dm_co.h"
19 
20 #if (BTC_GAP_BT_INCLUDED == TRUE)
21 
22 #define COD_UNCLASSIFIED ((0x1F) << 8)
23 
24 #define BTC_STORAGE_FILL_PROPERTY(p_prop, t, l, p_v) \
25          (p_prop)->type = t;(p_prop)->len = l; (p_prop)->val = (p_v);
26 
27 static void bte_search_devices_evt(tBTA_DM_SEARCH_EVT event, tBTA_DM_SEARCH *p_data);
28 static void bte_dm_search_services_evt(tBTA_DM_SEARCH_EVT event, tBTA_DM_SEARCH *p_data);
29 static void bte_dm_remote_service_record_evt(tBTA_DM_SEARCH_EVT event, tBTA_DM_SEARCH *p_data);
30 static void search_services_copy_cb(btc_msg_t *msg, void *p_dest, void *p_src);
31 static void search_service_record_copy_cb(btc_msg_t *msg, void *p_dest, void *p_src);
32 
33 static bool btc_gap_bt_inquiry_in_progress = false;
34 
btc_gap_bt_cb_to_app(esp_bt_gap_cb_event_t event,esp_bt_gap_cb_param_t * param)35 static inline void btc_gap_bt_cb_to_app(esp_bt_gap_cb_event_t event, esp_bt_gap_cb_param_t *param)
36 {
37     esp_bt_gap_cb_t cb = (esp_bt_gap_cb_t)btc_profile_cb_get(BTC_PID_GAP_BT);
38     if (cb) {
39         cb(event, param);
40     }
41 }
42 
btc_bt_set_scan_mode(esp_bt_connection_mode_t c_mode,esp_bt_discovery_mode_t d_mode)43 static void btc_bt_set_scan_mode(esp_bt_connection_mode_t c_mode, esp_bt_discovery_mode_t d_mode)
44 {
45     tBTA_DM_DISC disc_mode;
46     tBTA_DM_CONN conn_mode;
47 
48     switch (c_mode) {
49     case ESP_BT_NON_CONNECTABLE:
50         conn_mode = BTA_DM_NON_CONN;
51         break;
52     case ESP_BT_CONNECTABLE:
53         conn_mode = BTA_DM_CONN;
54         break;
55     default:
56         BTC_TRACE_WARNING("invalid connection mode (0x%x)", c_mode);
57         return;
58     }
59 
60     switch (d_mode) {
61     case ESP_BT_NON_DISCOVERABLE:
62         disc_mode = BTA_DM_NON_DISC;
63         break;
64     case ESP_BT_LIMITED_DISCOVERABLE:
65         disc_mode = BTA_DM_LIMITED_DISC;
66         break;
67     case ESP_BT_GENERAL_DISCOVERABLE:
68         disc_mode = BTA_DM_GENERAL_DISC;
69         break;
70     default:
71         BTC_TRACE_WARNING("invalid discovery mode (0x%x)", d_mode);
72         return;
73     }
74 
75     BTA_DmSetVisibility(disc_mode, conn_mode, BTA_DM_IGNORE, BTA_DM_IGNORE);
76     return;
77 }
78 
btc_gap_bt_start_discovery(btc_gap_bt_args_t * arg)79 static void btc_gap_bt_start_discovery(btc_gap_bt_args_t *arg)
80 {
81     tBTA_DM_INQ inq_params;
82     tBTA_SERVICE_MASK services = 0;
83 
84     BTIF_TRACE_EVENT("%s", __FUNCTION__);
85 
86     inq_params.mode = (arg->start_disc.mode == ESP_BT_INQ_MODE_GENERAL_INQUIRY) ?
87                       BTA_DM_GENERAL_INQUIRY : BTA_DM_LIMITED_INQUIRY;
88     inq_params.duration = arg->start_disc.inq_len;
89     inq_params.max_resps = arg->start_disc.num_rsps;
90 
91     inq_params.report_dup = TRUE;
92     inq_params.filter_type = BTA_DM_INQ_CLR;
93     /* TODO: Filter device by BDA needs to be implemented here */
94 
95     /* Will be enabled to TRUE once inquiry busy level has been received */
96     btc_gap_bt_inquiry_in_progress = FALSE;
97     /* find nearby devices */
98     BTA_DmSearch(&inq_params, services, bte_search_devices_evt);
99 
100     return;
101 }
102 
btc_gap_bt_cancel_discovery(void)103 static void btc_gap_bt_cancel_discovery(void)
104 {
105     BTA_DmSearchCancel();
106 }
107 
btc_gap_bt_get_remote_services(bt_bdaddr_t * remote_bda)108 static void btc_gap_bt_get_remote_services(bt_bdaddr_t *remote_bda)
109 {
110     BTA_DmDiscover(remote_bda->address, BTA_ALL_SERVICE_MASK,
111                    bte_dm_search_services_evt, TRUE);
112 }
113 
btc_gap_bt_get_remote_service_record(btc_gap_bt_args_t * arg)114 static void btc_gap_bt_get_remote_service_record(btc_gap_bt_args_t *arg)
115 {
116     esp_bt_uuid_t *uuid = &arg->get_rmt_srv_rcd.uuid;
117     bt_bdaddr_t *remote_bda = &arg->get_rmt_srv_rcd.bda;
118 
119     tSDP_UUID sdp_uuid;
120 
121     sdp_uuid.len = uuid->len;
122     memcpy(&sdp_uuid.uu, &uuid->uuid, uuid->len);
123 
124     BTA_DmDiscoverUUID(remote_bda->address, &sdp_uuid,
125                        bte_dm_remote_service_record_evt, TRUE);
126 }
127 
128 
129 /*******************************************************************************
130 **
131 ** Function         search_devices_copy_cb
132 **
133 ** Description      Deep copy callback for search devices event
134 **
135 ** Returns          void
136 **
137 *******************************************************************************/
search_devices_copy_cb(btc_msg_t * msg,void * p_dest,void * p_src)138 static void search_devices_copy_cb(btc_msg_t *msg, void *p_dest, void *p_src)
139 {
140     tBTA_DM_SEARCH_PARAM *p_dest_data =  (tBTA_DM_SEARCH_PARAM *) p_dest;
141     tBTA_DM_SEARCH_PARAM *p_src_data =  (tBTA_DM_SEARCH_PARAM *) p_src;
142     if (!p_src) {
143         return;
144     }
145     p_dest_data->p_data = (void *)osi_malloc(p_dest_data->len);
146     memset(p_dest_data->p_data, 0x00, p_dest_data->len);
147     memcpy(p_dest_data->p_data, p_src_data->p_data, p_dest_data->len);
148 
149     if ( p_dest_data->len > sizeof(tBTA_DM_SEARCH)){
150         switch (p_dest_data->event) {
151         case BTA_DM_INQ_RES_EVT: {
152             if (p_src_data->p_data->inq_res.p_eir) {
153                 p_dest_data->p_data->inq_res.p_eir = (UINT8 *)(p_dest_data->p_data) + sizeof(tBTA_DM_SEARCH);
154                 memcpy(p_dest_data->p_data->inq_res.p_eir, p_src_data->p_data->inq_res.p_eir, HCI_EXT_INQ_RESPONSE_LEN);
155             }
156         }
157         break;
158 
159         case BTA_DM_DISC_RES_EVT: {
160             if (p_src_data->p_data->disc_res.raw_data_size && p_src_data->p_data->disc_res.p_raw_data) {
161                 p_dest_data->p_data->disc_res.p_raw_data = (UINT8 *)(p_dest_data->p_data) + sizeof(tBTA_DM_SEARCH);
162                 memcpy(p_dest_data->p_data->disc_res.p_raw_data,
163                        p_src_data->p_data->disc_res.p_raw_data,
164                        p_src_data->p_data->disc_res.raw_data_size);
165             }
166         }
167         break;
168         }
169     }
170 }
171 
172 /*******************************************************************************
173 **
174 ** Function         search_service_record_copy_cb
175 **
176 ** Description      Deep copy callback for search service record event
177 **
178 ** Returns          void
179 **
180 *******************************************************************************/
search_service_record_copy_cb(btc_msg_t * msg,void * p_dest,void * p_src)181 static void search_service_record_copy_cb(btc_msg_t *msg, void *p_dest, void *p_src)
182 {
183     tBTA_DM_SEARCH_PARAM *p_dest_data =  (tBTA_DM_SEARCH_PARAM *) p_dest;
184     tBTA_DM_SEARCH_PARAM *p_src_data =  (tBTA_DM_SEARCH_PARAM *) p_src;
185 
186     if (!p_src) {
187         return;
188     }
189     p_dest_data->p_data = osi_malloc(p_dest_data->len);
190     memset(p_dest_data->p_data, 0x00, p_dest_data->len);
191     memcpy(p_dest_data->p_data, p_src_data->p_data, p_dest_data->len);
192     if ( p_dest_data->len > sizeof(tBTA_DM_SEARCH)){
193         switch (p_dest_data->event) {
194         case BTA_DM_DISC_RES_EVT: {
195             if (p_src_data->p_data->disc_res.p_raw_data && p_src_data->p_data->disc_res.raw_data_size > 0) {
196                 p_dest_data->p_data->disc_res.p_raw_data = (UINT8 *)(p_dest_data->p_data) + sizeof(tBTA_DM_SEARCH);
197                 memcpy(p_dest_data->p_data->disc_res.p_raw_data,
198                        p_src_data->p_data->disc_res.p_raw_data,
199                        p_src_data->p_data->disc_res.raw_data_size);
200             }
201         }
202         break;
203 
204         default:
205             break;
206         }
207     }
208 }
209 
210 /*******************************************************************************
211 **
212 ** Function         check_eir_remote_name
213 **
214 ** Description      Check if remote name is in the EIR data
215 **
216 ** Returns          TRUE if remote name found
217 **                  Populate p_remote_name, if provided and remote name found
218 **
219 *******************************************************************************/
check_eir_remote_name(tBTA_DM_SEARCH * p_search_data,UINT8 * p_remote_name,UINT8 * p_remote_name_len)220 static BOOLEAN check_eir_remote_name(tBTA_DM_SEARCH *p_search_data,
221                                      UINT8 *p_remote_name, UINT8 *p_remote_name_len)
222 {
223     UINT8 *p_eir_remote_name = NULL;
224     UINT8 remote_name_len = 0;
225 
226     /* Check EIR for remote name and services */
227     if (p_search_data->inq_res.p_eir) {
228         p_eir_remote_name = BTM_CheckEirData(p_search_data->inq_res.p_eir,
229                                              BTM_EIR_COMPLETE_LOCAL_NAME_TYPE, &remote_name_len);
230         if (!p_eir_remote_name) {
231             p_eir_remote_name = BTM_CheckEirData(p_search_data->inq_res.p_eir,
232                                                  BTM_EIR_SHORTENED_LOCAL_NAME_TYPE, &remote_name_len);
233         }
234 
235         if (p_eir_remote_name) {
236             if (remote_name_len > BD_NAME_LEN) {
237                 remote_name_len = BD_NAME_LEN;
238             }
239 
240             if (p_remote_name && p_remote_name_len) {
241                 memcpy(p_remote_name, p_eir_remote_name, remote_name_len);
242                 *(p_remote_name + remote_name_len) = 0;
243                 *p_remote_name_len = remote_name_len;
244             }
245 
246             return TRUE;
247         }
248     }
249 
250     return FALSE;
251 
252 }
253 
254 /*******************************************************************************
255 **
256 ** Function         bte_search_devices_evt
257 **
258 ** Description      Switches context from BTE to BTIF for DM search events
259 **
260 ** Returns          void
261 **
262 *******************************************************************************/
bte_search_devices_evt(tBTA_DM_SEARCH_EVT event,tBTA_DM_SEARCH * p_data)263 static void bte_search_devices_evt(tBTA_DM_SEARCH_EVT event, tBTA_DM_SEARCH *p_data)
264 {
265     tBTA_DM_SEARCH_PARAM search;
266     search.event = event;
267     search.p_data = p_data;
268 
269     UINT16 param_len = 0;
270 
271     if (p_data) {
272         param_len += sizeof(tBTA_DM_SEARCH);
273     }
274     /* Allocate buffer to hold the pointers (deep copy). The pointers will point to the end of the tBTA_DM_SEARCH */
275     switch (event) {
276     case BTA_DM_INQ_RES_EVT: {
277         if (p_data->inq_res.p_eir) {
278             param_len += HCI_EXT_INQ_RESPONSE_LEN;
279         }
280     }
281     break;
282 
283     case BTA_DM_DISC_RES_EVT: {
284         if (p_data->disc_res.raw_data_size && p_data->disc_res.p_raw_data) {
285             param_len += p_data->disc_res.raw_data_size;
286         }
287     }
288     break;
289     }
290 
291     /* if remote name is available in EIR, set the flag so that stack doesn't trigger RNR */
292     if (event == BTA_DM_INQ_RES_EVT) {
293         p_data->inq_res.remt_name_not_required = check_eir_remote_name(p_data, NULL, NULL);
294     }
295 
296     search.len = param_len;
297     do {
298         btc_msg_t msg;
299         msg.sig = BTC_SIG_API_CB;
300         msg.pid = BTC_PID_GAP_BT;
301         msg.act = BTC_GAP_BT_SEARCH_DEVICES_EVT;
302 
303         btc_transfer_context(&msg, &search, sizeof(tBTA_DM_SEARCH_PARAM), search_devices_copy_cb, NULL);
304     } while (0);
305 }
306 
btc_gap_bt_search_devices_evt(tBTA_DM_SEARCH_PARAM * p_data)307 static void btc_gap_bt_search_devices_evt(tBTA_DM_SEARCH_PARAM *p_data)
308 {
309     switch (p_data->event) {
310     case BTA_DM_DISC_RES_EVT: {
311         /* remote name update */
312         uint32_t bdname_len = strlen((const char *)p_data->p_data->disc_res.bd_name);
313         if (bdname_len) {
314             esp_bt_gap_dev_prop_t prop[1];
315 
316             BTC_STORAGE_FILL_PROPERTY(&prop[0], ESP_BT_GAP_DEV_PROP_BDNAME, bdname_len + 1, p_data->p_data->disc_res.bd_name);
317 
318             esp_bt_gap_cb_param_t param;
319             bdcpy(param.disc_res.bda, p_data->p_data->disc_res.bd_addr);
320             param.disc_res.num_prop = 1;
321             param.disc_res.prop = prop;
322             btc_gap_bt_cb_to_app(ESP_BT_GAP_DISC_RES_EVT, &param);
323         }
324         break;
325     }
326     case BTA_DM_INQ_RES_EVT: {
327         /* inquiry result */
328         uint32_t cod = devclass2uint (p_data->p_data->inq_res.dev_class);
329 
330         if (cod == 0) {
331             BTC_TRACE_DEBUG("%s cod is 0, set as unclassified", __func__);
332             cod = COD_UNCLASSIFIED;
333         }
334 
335         do {
336             esp_bt_gap_dev_prop_t prop[3];
337             int num_prop = 0;
338 
339             memset(prop, 0, sizeof(prop));
340             BTC_STORAGE_FILL_PROPERTY(&prop[0], ESP_BT_GAP_DEV_PROP_COD, sizeof(cod), &cod);
341             num_prop++;
342 
343             BTC_STORAGE_FILL_PROPERTY(&prop[1], ESP_BT_GAP_DEV_PROP_RSSI, 1, &(p_data->p_data->inq_res.rssi));
344             num_prop++;
345 
346             if (p_data->p_data->inq_res.p_eir) {
347                 BTC_STORAGE_FILL_PROPERTY(&prop[2], ESP_BT_GAP_DEV_PROP_EIR, HCI_EXT_INQ_RESPONSE_LEN, p_data->p_data->inq_res.p_eir);
348                 num_prop++;
349             }
350 
351             /* Callback to notify upper layer of device */
352             esp_bt_gap_cb_param_t param;
353             bdcpy(param.disc_res.bda, p_data->p_data->inq_res.bd_addr);
354             param.disc_res.num_prop = num_prop;
355             param.disc_res.prop = prop;
356             btc_gap_bt_cb_to_app(ESP_BT_GAP_DISC_RES_EVT, &param);
357         } while (0);
358     }
359     break;
360 
361     case BTA_DM_INQ_CMPL_EVT:
362         break;
363     case BTA_DM_DISC_CMPL_EVT: {
364         esp_bt_gap_cb_param_t param;
365         param.disc_st_chg.state = ESP_BT_GAP_DISCOVERY_STOPPED;
366         btc_gap_bt_cb_to_app(ESP_BT_GAP_DISC_STATE_CHANGED_EVT, &param);
367         break;
368     }
369     case BTA_DM_SEARCH_CANCEL_CMPL_EVT: {
370         /* if inquiry is not in progress and we get a cancel event, then
371          * it means we are done with inquiry, but remote_name fetches are in
372          * progress
373          *
374          * if inquiry is in progress, then we don't want to act on this cancel_cmpl_evt
375          * but instead wait for the cancel_cmpl_evt_via the busy level
376          */
377         if (btc_gap_bt_inquiry_in_progress == false) {
378             esp_bt_gap_cb_param_t param;
379             param.disc_st_chg.state = ESP_BT_GAP_DISCOVERY_STOPPED;
380             btc_gap_bt_cb_to_app(ESP_BT_GAP_DISC_STATE_CHANGED_EVT, &param);
381         }
382         break;
383     }
384     }
385 }
386 /*******************************************************************************
387 **
388 ** Function         btc_gap_bt_search_service_record
389 **
390 ** Description      Executes search service record event in btif context
391 **
392 ** Returns          void
393 **
394 *******************************************************************************/
btc_gap_bt_search_service_record(char * p_param)395 static void btc_gap_bt_search_service_record(char *p_param)
396 {
397     tBTA_DM_SEARCH_PARAM *p_data = (tBTA_DM_SEARCH_PARAM *)p_param;
398 
399     switch (p_data->event) {
400     case BTA_DM_DISC_RES_EVT: {
401         esp_bt_gap_cb_param_t param;
402         memcpy(param.rmt_srvcs.bda, p_data->p_data->disc_res.bd_addr, BD_ADDR_LEN);
403         if (p_data->p_data->disc_res.p_raw_data && p_data->p_data->disc_res.raw_data_size > 0) {
404             param.rmt_srvc_rec.stat = ESP_BT_STATUS_SUCCESS;
405             // param.rmt_srvc_rec.raw_data_size = p_data->p_data->disc_res.raw_data_size;
406             // param.rmt_srvc_rec.raw_data = p_data->p_data->disc_res.p_raw_data;
407         } else {
408             param.rmt_srvc_rec.stat = ESP_BT_STATUS_FAIL;
409             // param.rmt_srvc_rec.raw_data_size = 0;
410             // param.rmt_srvc_rec.raw_data = NULL;
411         }
412         btc_gap_bt_cb_to_app(ESP_BT_GAP_RMT_SRVC_REC_EVT, &param);
413     }
414     break;
415     case BTA_DM_DISC_CMPL_EVT:
416     default:
417         break;
418     }
419 }
420 
421 
422 /*******************************************************************************
423 **
424 ** Function         bte_dm_remote_service_record_evt
425 **
426 ** Description      Switches context from BTE to BTC for DM search service
427 **                  record event
428 **
429 ** Returns          void
430 **
431 *******************************************************************************/
bte_dm_remote_service_record_evt(tBTA_DM_SEARCH_EVT event,tBTA_DM_SEARCH * p_data)432 static void bte_dm_remote_service_record_evt(tBTA_DM_SEARCH_EVT event, tBTA_DM_SEARCH *p_data)
433 {
434     tBTA_DM_SEARCH_PARAM search;
435     search.event = event;
436     search.p_data = p_data;
437     UINT16 param_len = 0;
438 
439     if (p_data) {
440         param_len += sizeof(tBTA_DM_SEARCH);
441     }
442     /* Allocate buffer to hold the pointers (deep copy). The pointers will point to the end of the tBTA_DM_SEARCH */
443     if (event == BTA_DM_DISC_RES_EVT) {
444         if (p_data->disc_res.raw_data_size && p_data->disc_res.p_raw_data) {
445             param_len += p_data->disc_res.raw_data_size;
446         }
447     }
448     search.len = param_len;
449     do {
450         btc_msg_t msg;
451         msg.sig = BTC_SIG_API_CB;
452         msg.pid = BTC_PID_GAP_BT;
453         msg.act = BTC_GAP_BT_SEARCH_SERVICE_RECORD_EVT;
454         btc_transfer_context(&msg, &search, sizeof(tBTA_DM_SEARCH_PARAM), search_service_record_copy_cb, NULL);
455     } while (0);
456 
457 }
458 
459 /*******************************************************************************
460 **
461 ** Function         btc_gap_bt_search_services
462 **
463 ** Description      Executes search services event in btc context
464 **
465 ** Returns          void
466 **
467 *******************************************************************************/
btc_gap_bt_search_services(char * p_param)468 static void btc_gap_bt_search_services(char *p_param)
469 {
470     tBTA_DM_SEARCH_PARAM *p_data = (tBTA_DM_SEARCH_PARAM *)p_param;
471 
472     switch (p_data->event) {
473     case BTA_DM_DISC_RES_EVT: {
474         esp_bt_gap_cb_param_t param;
475         esp_bt_uuid_t *uuid_list = NULL;
476         memcpy(param.rmt_srvcs.bda, p_data->p_data->disc_res.bd_addr, BD_ADDR_LEN);
477 
478         param.rmt_srvcs.stat = ESP_BT_STATUS_FAIL;
479         if (p_data->p_data->disc_res.result == BTA_SUCCESS) {
480             uuid_list = osi_malloc(sizeof(esp_bt_uuid_t) * p_data->p_data->disc_res.num_uuids);
481             if (uuid_list) {
482                 param.rmt_srvcs.stat = ESP_BT_STATUS_SUCCESS;
483                 param.rmt_srvcs.num_uuids = p_data->p_data->disc_res.num_uuids;
484                 param.rmt_srvcs.uuid_list = uuid_list;
485                 // copy UUID list
486                 uint8_t *i_uu = (uint8_t *)p_data->p_data->disc_res.p_uuid_list;
487                 esp_bt_uuid_t *o_uu = uuid_list;
488                 for (int i = 0; i < p_data->p_data->disc_res.num_uuids; i++, i_uu += ESP_UUID_LEN_128, o_uu++) {
489                     uuid128_be_to_esp_uuid(o_uu, i_uu);
490                 }
491             }
492         }
493 
494         if (param.rmt_srvcs.stat == ESP_BT_STATUS_FAIL) {
495             param.rmt_srvcs.num_uuids = 0;
496             param.rmt_srvcs.uuid_list = NULL;
497         }
498         btc_gap_bt_cb_to_app(ESP_BT_GAP_RMT_SRVCS_EVT, &param);
499 
500         if (uuid_list) {
501             osi_free(uuid_list);
502         }
503     }
504     break;
505 
506     case BTA_DM_DISC_BLE_RES_EVT:
507     case BTA_DM_DISC_CMPL_EVT:
508     default:
509         break;
510     }
511 }
512 
513 /*******************************************************************************
514 **
515 ** Function         bte_dm_search_services_evt
516 **
517 ** Description      Switches context from BTE to BTIF for DM search services
518 **                  event
519 **
520 ** Returns          void
521 **
522 *******************************************************************************/
bte_dm_search_services_evt(tBTA_DM_SEARCH_EVT event,tBTA_DM_SEARCH * p_data)523 static void bte_dm_search_services_evt(tBTA_DM_SEARCH_EVT event, tBTA_DM_SEARCH *p_data)
524 {
525     tBTA_DM_SEARCH_PARAM search;
526     search.event = event;
527     search.p_data = p_data;
528 
529     UINT16 param_len = 0;
530     if (p_data) {
531         param_len += sizeof(tBTA_DM_SEARCH);
532     }
533 
534     switch (event) {
535     case BTA_DM_DISC_RES_EVT: {
536         if ((p_data->disc_res.result == BTA_SUCCESS) && (p_data->disc_res.num_uuids > 0)) {
537             param_len += (p_data->disc_res.num_uuids * MAX_UUID_SIZE);
538         }
539     } break;
540     }
541     search.len = param_len;
542     do {
543         btc_msg_t msg;
544         msg.sig = BTC_SIG_API_CB;
545         msg.pid = BTC_PID_GAP_BT;
546         msg.act = BTC_GAP_BT_SEARCH_SERVICES_EVT;
547         btc_transfer_context(&msg, &search, sizeof(tBTA_DM_SEARCH_PARAM), search_services_copy_cb, NULL);
548     } while (0);
549 }
550 
search_services_copy_cb(btc_msg_t * msg,void * p_dest,void * p_src)551 static void search_services_copy_cb(btc_msg_t *msg, void *p_dest, void *p_src)
552 {
553     tBTA_DM_SEARCH_PARAM *p_dest_data =  (tBTA_DM_SEARCH_PARAM *) p_dest;
554     tBTA_DM_SEARCH_PARAM *p_src_data =  (tBTA_DM_SEARCH_PARAM *) p_src;
555 
556     if (!p_src) {
557         return;
558     }
559     p_dest_data->p_data = osi_malloc(p_dest_data->len);
560     memset(p_dest_data->p_data, 0x00, p_dest_data->len);
561     memcpy(p_dest_data->p_data, p_src_data->p_data, p_dest_data->len);
562 
563     if ( p_dest_data->len > sizeof(tBTA_DM_SEARCH)){
564         switch (p_dest_data->event) {
565         case BTA_DM_DISC_RES_EVT: {
566             if (p_src_data->p_data->disc_res.result == BTA_SUCCESS) {
567                 if (p_src_data->p_data->disc_res.num_uuids > 0) {
568                     p_dest_data->p_data->disc_res.p_uuid_list = (UINT8 *)(p_dest_data->p_data) + sizeof(tBTA_DM_SEARCH);
569                     memcpy(p_dest_data->p_data->disc_res.p_uuid_list, p_src_data->p_data->disc_res.p_uuid_list,
570                            p_src_data->p_data->disc_res.num_uuids * MAX_UUID_SIZE);
571                     osi_free(p_src_data->p_data->disc_res.p_uuid_list);
572                     p_src_data->p_data->disc_res.p_uuid_list = NULL;
573                 }
574                 if (p_src_data->p_data->disc_res.p_raw_data != NULL) {
575                     osi_free(p_src_data->p_data->disc_res.p_raw_data);
576                     p_src_data->p_data->disc_res.p_raw_data = NULL;
577                 }
578             }
579         } break;
580         }
581     }
582 }
583 
btc_gap_bt_set_cod(btc_gap_bt_args_t * arg)584 static void btc_gap_bt_set_cod(btc_gap_bt_args_t *arg)
585 {
586     tBTA_UTL_COD p_cod;
587     esp_bt_cod_t *cod = &(arg->set_cod.cod);
588     p_cod.reserved_2 = cod->reserved_2;
589     p_cod.minor = cod->minor << 2;
590     p_cod.major = cod->major;
591     p_cod.service = cod->service << 5;
592     bool ret = utl_set_device_class(&p_cod, arg->set_cod.mode);
593     if (!ret){
594         BTC_TRACE_ERROR("%s set class of device failed!",__func__);
595     }
596 }
597 
btc_gap_bt_get_cod(esp_bt_cod_t * cod)598 esp_err_t btc_gap_bt_get_cod(esp_bt_cod_t *cod)
599 {
600     tBTA_UTL_COD p_cod;
601     bool ret = utl_get_device_class(&p_cod);
602     if (!ret){
603         BTC_TRACE_ERROR("%s get class of device failed!",__func__);
604         return ESP_BT_STATUS_FAIL;
605     }
606     cod->reserved_2 = p_cod.reserved_2;
607     cod->minor = p_cod.minor >> 2;
608     cod->major = p_cod.major;
609     cod->service = p_cod.service >> 5;
610     return ESP_BT_STATUS_SUCCESS;
611 }
612 
btc_gap_bt_read_rssi_delta_cmpl_callback(void * p_data)613 static void btc_gap_bt_read_rssi_delta_cmpl_callback(void *p_data)
614 {
615     tBTA_RSSI_RESULTS *result = (tBTA_RSSI_RESULTS *)p_data;
616     esp_bt_gap_cb_param_t param;
617     bt_status_t ret;
618     btc_msg_t msg;
619     msg.sig = BTC_SIG_API_CB;
620     msg.pid = BTC_PID_GAP_BT;
621     msg.act = BTC_GAP_BT_READ_RSSI_DELTA_EVT;
622     memcpy(param.read_rssi_delta.bda, result->rem_bda, sizeof(BD_ADDR));
623     param.read_rssi_delta.stat = btc_btm_status_to_esp_status(result->status);
624     param.read_rssi_delta.rssi_delta = result->rssi;
625 
626     ret = btc_transfer_context(&msg, &param,
627                                sizeof(esp_bt_gap_cb_param_t), NULL, NULL);
628 
629     if (ret != BT_STATUS_SUCCESS) {
630         BTC_TRACE_ERROR("%s btc_transfer_context failed\n", __func__);
631     }
632 }
633 
btc_gap_bt_read_rssi_delta(btc_gap_bt_args_t * arg)634 static void btc_gap_bt_read_rssi_delta(btc_gap_bt_args_t *arg)
635 {
636     BTA_DmReadRSSI(arg->read_rssi_delta.bda.address, BTA_TRANSPORT_BR_EDR, btc_gap_bt_read_rssi_delta_cmpl_callback);
637 }
638 
btc_gap_bt_remove_bond_device(btc_gap_bt_args_t * arg)639 static esp_err_t btc_gap_bt_remove_bond_device(btc_gap_bt_args_t *arg)
640 {
641     BD_ADDR bd_addr;
642     memcpy(bd_addr, arg->rm_bond_device.bda.address, sizeof(BD_ADDR));
643     if(BTA_DmRemoveDevice(bd_addr, BT_TRANSPORT_BR_EDR) == BTA_SUCCESS){
644         return ESP_BT_STATUS_SUCCESS;
645     }
646     return ESP_BT_STATUS_FAIL;
647 }
648 
btc_gap_bt_set_pin_type(btc_gap_bt_args_t * arg)649 static void btc_gap_bt_set_pin_type(btc_gap_bt_args_t *arg){
650     BTA_DMSetPinType (arg->set_pin_type.pin_type, arg->set_pin_type.pin_code, arg->set_pin_type.pin_code_len);
651 }
652 
btc_gap_bt_pin_reply(btc_gap_bt_args_t * arg)653 static void btc_gap_bt_pin_reply(btc_gap_bt_args_t *arg){
654     BTA_DmPinReply(arg->pin_reply.bda.address, arg->pin_reply.accept, arg->pin_reply.pin_code_len, arg->pin_reply.pin_code);
655 }
656 
657 #if (BT_SSP_INCLUDED == TRUE)
btc_gap_bt_set_security_param(btc_gap_bt_args_t * arg)658 static esp_err_t btc_gap_bt_set_security_param(btc_gap_bt_args_t *arg)
659 {
660     esp_err_t ret;
661     switch(arg->set_security_param.param_type) {
662     case ESP_BT_SP_IOCAP_MODE:{
663         uint8_t iocap = 0;
664         uint8_t *p = arg->set_security_param.value;
665         STREAM_TO_UINT8(iocap, p);
666         ret = bta_dm_co_bt_set_io_cap(iocap);
667         break;
668     }
669     default:
670         ret = ESP_BT_STATUS_FAIL;
671         break;
672     }
673     return ret;
674 }
675 
btc_gap_bt_ssp_passkey_reply(btc_gap_bt_args_t * arg)676 static void btc_gap_bt_ssp_passkey_reply(btc_gap_bt_args_t *arg)
677 {
678     BTA_DmPasskeyReqReply(arg->passkey_reply.accept, arg->passkey_reply.bda.address, arg->passkey_reply.passkey);
679 }
680 
btc_gap_bt_ssp_confirm(btc_gap_bt_args_t * arg)681 static void btc_gap_bt_ssp_confirm(btc_gap_bt_args_t *arg)
682 {
683     BTA_DmConfirm(arg->confirm_reply.bda.address, arg->confirm_reply.accept);
684 }
685 
686 #endif ///BT_SSP_INCLUDED == TRUE
687 
btc_gap_bt_config_eir(btc_gap_bt_args_t * arg)688 static void btc_gap_bt_config_eir(btc_gap_bt_args_t *arg)
689 {
690     tBTA_DM_EIR_CONF eir_config;
691     esp_bt_eir_data_t *eir_data = &arg->config_eir.eir_data;
692 
693     eir_config.bta_dm_eir_fec_required = eir_data->fec_required;
694     eir_config.bta_dm_eir_included_name = eir_data->include_name;
695     eir_config.bta_dm_eir_included_tx_power = eir_data->include_txpower;
696     eir_config.bta_dm_eir_included_uuid = eir_data->include_uuid;
697     eir_config.bta_dm_eir_flags = eir_data->flag;
698     eir_config.bta_dm_eir_manufac_spec_len = eir_data->manufacturer_len;
699     eir_config.bta_dm_eir_manufac_spec = eir_data->p_manufacturer_data;
700     eir_config.bta_dm_eir_url_len = eir_data->url_len;
701     eir_config.bta_dm_eir_url = eir_data->p_url;
702 
703     BTA_DmConfigEir(&eir_config);
704 }
705 
btc_gap_bt_set_afh_channels_cmpl_callback(void * p_data)706 static void btc_gap_bt_set_afh_channels_cmpl_callback(void *p_data)
707 {
708     tBTA_SET_AFH_CHANNELS_RESULTS *result = (tBTA_SET_AFH_CHANNELS_RESULTS *)p_data;
709     esp_bt_gap_cb_param_t param;
710     bt_status_t ret;
711     btc_msg_t msg;
712     msg.sig = BTC_SIG_API_CB;
713     msg.pid = BTC_PID_GAP_BT;
714     msg.act = BTC_GAP_BT_SET_AFH_CHANNELS_EVT;
715 
716     param.set_afh_channels.stat = btc_btm_status_to_esp_status(result->status);
717 
718     ret = btc_transfer_context(&msg, &param,
719                                sizeof(esp_bt_gap_cb_param_t), NULL, NULL);
720 
721     if (ret != BT_STATUS_SUCCESS) {
722         BTC_TRACE_ERROR("%s btc_transfer_context failed\n", __func__);
723     }
724 }
725 
btc_gap_bt_set_afh_channels(btc_gap_bt_args_t * arg)726 static void btc_gap_bt_set_afh_channels(btc_gap_bt_args_t *arg)
727 {
728     BTA_DmSetAfhChannels(arg->set_afh_channels.channels, btc_gap_bt_set_afh_channels_cmpl_callback);
729 }
730 
btc_gap_bt_set_acl_pkt_types_cmpl_callback(void * p_data)731 static void btc_gap_bt_set_acl_pkt_types_cmpl_callback(void *p_data)
732 {
733     tBTA_SET_ACL_PKT_TYPES_RESULTS *result = (tBTA_SET_ACL_PKT_TYPES_RESULTS *)p_data;
734     esp_bt_gap_cb_param_t param;
735     bt_status_t ret;
736     btc_msg_t msg;
737     msg.sig = BTC_SIG_API_CB;
738     msg.pid = BTC_PID_GAP_BT;
739     msg.act = BTC_GAP_BT_SET_ACL_PKT_TYPES_EVT;
740 
741     param.set_acl_pkt_types.status = btc_btm_status_to_esp_status(result->status);
742     memcpy(param.set_acl_pkt_types.bda, result->rem_bda, sizeof(esp_bd_addr_t));
743     param.set_acl_pkt_types.pkt_types = result->pkt_types;
744 
745     ret = btc_transfer_context(&msg, &param, sizeof(esp_bt_gap_cb_param_t), NULL, NULL);
746     if (ret != BT_STATUS_SUCCESS) {
747         BTC_TRACE_ERROR("%s btc_transfer_context failed\n", __func__);
748     }
749 }
750 
btc_gap_set_acl_pkt_types(btc_gap_bt_args_t * arg)751 static void btc_gap_set_acl_pkt_types(btc_gap_bt_args_t *arg)
752 {
753     BTA_DmSetAclPktTypes(arg->set_acl_pkt_types.bda.address,
754                          arg->set_acl_pkt_types.pkt_types,
755                          btc_gap_bt_set_acl_pkt_types_cmpl_callback);
756 }
757 
btc_gap_bt_read_remote_name_cmpl_callback(void * p_data)758 static void btc_gap_bt_read_remote_name_cmpl_callback(void *p_data)
759 {
760     tBTA_REMOTE_DEV_NAME *result = (tBTA_REMOTE_DEV_NAME *)p_data;
761     esp_bt_gap_cb_param_t param;
762     btc_msg_t msg;
763     bt_status_t ret;
764     msg.sig = BTC_SIG_API_CB;
765     msg.pid = BTC_PID_GAP_BT;
766     msg.act = BTC_GAP_BT_READ_REMOTE_NAME_EVT;
767 
768     memcpy(param.read_rmt_name.bda,result->bd_addr,BD_ADDR_LEN);
769     param.read_rmt_name.stat = btc_btm_status_to_esp_status(result->status);
770     memcpy(param.read_rmt_name.rmt_name,result->remote_bd_name,ESP_BT_GAP_MAX_BDNAME_LEN);
771 
772     ret = btc_transfer_context(&msg, &param, sizeof(esp_bt_gap_cb_param_t), NULL, NULL);
773     if (ret != BT_STATUS_SUCCESS) {
774         BTC_TRACE_ERROR("%s btc_transfer_context failed\n", __func__);
775     }
776 }
777 
btc_gap_bt_read_remote_name(btc_gap_bt_args_t * arg)778 static void btc_gap_bt_read_remote_name(btc_gap_bt_args_t *arg)
779 {
780     BTA_DmGetRemoteName(arg->rmt_name_bda.address, btc_gap_bt_read_remote_name_cmpl_callback);
781 }
782 
783 #if (BTA_DM_QOS_INCLUDED == TRUE)
btc_gap_bt_set_qos_cmpl_callback(void * p_data)784 static void btc_gap_bt_set_qos_cmpl_callback(void *p_data)
785 {
786     tBTM_QOS_SETUP_CMPL *result = (tBTM_QOS_SETUP_CMPL *)p_data;
787     esp_bt_gap_cb_param_t param;
788     btc_msg_t msg;
789     bt_status_t ret;
790     msg.sig = BTC_SIG_API_CB;
791     msg.pid = BTC_PID_GAP_BT;
792     msg.act = BTC_GAP_BT_QOS_EVT;
793 
794     param.qos_cmpl.stat = btc_btm_status_to_esp_status(result->status);
795     param.qos_cmpl.t_poll = result->flow.latency / 625;
796     memcpy(param.qos_cmpl.bda,result->rem_bda,BD_ADDR_LEN);
797 
798     ret = btc_transfer_context(&msg, &param, sizeof(esp_bt_gap_cb_param_t), NULL, NULL);
799     if (ret != BT_STATUS_SUCCESS) {
800         BTC_TRACE_ERROR("%s btc_transfer_context failed\n", __func__);
801     }
802 }
803 #endif /// (BTA_DM_QOS_INCLUDED == TRUE)
804 
btc_gap_bt_set_qos(btc_gap_bt_args_t * arg)805 static void btc_gap_bt_set_qos(btc_gap_bt_args_t *arg)
806 {
807 #if (BTA_DM_QOS_INCLUDED == TRUE)
808     BTA_DmSetQos(arg->set_qos.bda.address, arg->set_qos.t_poll, btc_gap_bt_set_qos_cmpl_callback);
809 #else
810     BTC_TRACE_ERROR("%s: QoS is not supported.\n",__func__);
811 #endif /// (BTA_DM_QOS_INCLUDED == TRUE)
812 }
813 
btc_gap_bt_arg_deep_copy(btc_msg_t * msg,void * p_dest,void * p_src)814 void btc_gap_bt_arg_deep_copy(btc_msg_t *msg, void *p_dest, void *p_src)
815 {
816     switch (msg->act) {
817     case BTC_GAP_BT_ACT_SET_SCAN_MODE:
818     case BTC_GAP_BT_ACT_START_DISCOVERY:
819     case BTC_GAP_BT_ACT_CANCEL_DISCOVERY:
820     case BTC_GAP_BT_ACT_GET_REMOTE_SERVICES:
821     case BTC_GAP_BT_ACT_GET_REMOTE_SERVICE_RECORD:
822     case BTC_GAP_BT_ACT_SET_COD:
823     case BTC_GAP_BT_ACT_READ_RSSI_DELTA:
824     case BTC_GAP_BT_ACT_REMOVE_BOND_DEVICE:
825     case BTC_GAP_BT_ACT_PIN_REPLY:
826     case BTC_GAP_BT_ACT_SET_PIN_TYPE:
827     case BTC_GAP_BT_ACT_SET_AFH_CHANNELS:
828     case BTC_GAP_BT_ACT_READ_REMOTE_NAME:
829     case BTC_GAP_BT_ACT_SET_QOS:
830     case BTC_GAP_BT_ACT_SET_ACL_PKT_TYPES:
831         break;
832 #if (BT_SSP_INCLUDED == TRUE)
833     case BTC_GAP_BT_ACT_PASSKEY_REPLY:
834     case BTC_GAP_BT_ACT_CONFIRM_REPLY:
835         break;
836     case BTC_GAP_BT_ACT_SET_SECURITY_PARAM:{
837         btc_gap_bt_args_t *src = (btc_gap_bt_args_t *)p_src;
838         btc_gap_bt_args_t *dst = (btc_gap_bt_args_t *)p_dest;
839         if (src->set_security_param.value) {
840             dst->set_security_param.value = osi_malloc(src->set_security_param.len);
841             if (dst->set_security_param.value != NULL) {
842                 memcpy(dst->set_security_param.value, src->set_security_param.value, src->set_security_param.len);
843             } else {
844                 BTC_TRACE_ERROR("%s %d no mem\n",__func__, msg->act);
845             }
846         }
847         break;
848     }
849 #endif ///BT_SSP_INCLUDED == TRUE
850 
851     case BTC_GAP_BT_ACT_CONFIG_EIR:{
852         btc_gap_bt_args_t *src = (btc_gap_bt_args_t *)p_src;
853         btc_gap_bt_args_t *dst = (btc_gap_bt_args_t *)p_dest;
854         if (src->config_eir.eir_data.p_manufacturer_data) {
855             dst->config_eir.eir_data.p_manufacturer_data = osi_malloc(src->config_eir.eir_data.manufacturer_len);
856             if (dst->config_eir.eir_data.p_manufacturer_data != NULL) {
857                 memcpy(dst->config_eir.eir_data.p_manufacturer_data, src->config_eir.eir_data.p_manufacturer_data, src->config_eir.eir_data.manufacturer_len);
858             } else {
859                 dst->config_eir.eir_data.manufacturer_len = 0;
860                 BTC_TRACE_ERROR("%s %d no mem\n",__func__, msg->act);
861             }
862         }
863         if (src->config_eir.eir_data.p_url) {
864             dst->config_eir.eir_data.p_url = osi_malloc(src->config_eir.eir_data.url_len);
865             if (dst->config_eir.eir_data.p_url != NULL) {
866                 memcpy(dst->config_eir.eir_data.p_url, src->config_eir.eir_data.p_url, src->config_eir.eir_data.url_len);
867             } else {
868                 dst->config_eir.eir_data.url_len = 0;
869                 BTC_TRACE_ERROR("%s %d no mem\n",__func__, msg->act);
870             }
871         }
872         break;
873     }
874     default:
875         BTC_TRACE_ERROR("Unhandled deep copy %d\n", msg->act);
876         break;
877     }
878 }
879 
btc_gap_bt_arg_deep_free(btc_msg_t * msg)880 void btc_gap_bt_arg_deep_free(btc_msg_t *msg)
881 {
882     btc_gap_bt_args_t *arg = (btc_gap_bt_args_t *)msg->arg;
883     switch (msg->act) {
884     case BTC_GAP_BT_ACT_SET_SCAN_MODE:
885     case BTC_GAP_BT_ACT_START_DISCOVERY:
886     case BTC_GAP_BT_ACT_CANCEL_DISCOVERY:
887     case BTC_GAP_BT_ACT_GET_REMOTE_SERVICES:
888     case BTC_GAP_BT_ACT_GET_REMOTE_SERVICE_RECORD:
889     case BTC_GAP_BT_ACT_SET_COD:
890     case BTC_GAP_BT_ACT_READ_RSSI_DELTA:
891     case BTC_GAP_BT_ACT_REMOVE_BOND_DEVICE:
892     case BTC_GAP_BT_ACT_PIN_REPLY:
893     case BTC_GAP_BT_ACT_SET_PIN_TYPE:
894     case BTC_GAP_BT_ACT_SET_AFH_CHANNELS:
895     case BTC_GAP_BT_ACT_READ_REMOTE_NAME:
896     case BTC_GAP_BT_ACT_SET_QOS:
897     case BTC_GAP_BT_ACT_SET_ACL_PKT_TYPES:
898         break;
899 #if (BT_SSP_INCLUDED == TRUE)
900     case BTC_GAP_BT_ACT_PASSKEY_REPLY:
901     case BTC_GAP_BT_ACT_CONFIRM_REPLY:
902         break;
903     case BTC_GAP_BT_ACT_SET_SECURITY_PARAM:
904         if (arg->set_security_param.value) {
905             osi_free(arg->set_security_param.value);
906         }
907         break;
908 #endif ///BT_SSP_INCLUDED == TRUE
909 
910     case BTC_GAP_BT_ACT_CONFIG_EIR:
911         if (arg->config_eir.eir_data.p_manufacturer_data) {
912             osi_free(arg->config_eir.eir_data.p_manufacturer_data);
913         }
914         if (arg->config_eir.eir_data.p_url) {
915             osi_free(arg->config_eir.eir_data.p_url);
916         }
917         break;
918     default:
919         BTC_TRACE_ERROR("Unhandled deep copy %d, arg: %p\n", msg->act, arg);
920         break;
921     }
922 }
923 
btc_gap_bt_call_handler(btc_msg_t * msg)924 void btc_gap_bt_call_handler(btc_msg_t *msg)
925 {
926     btc_gap_bt_args_t *arg = (btc_gap_bt_args_t *)msg->arg;
927     BTC_TRACE_DEBUG("%s act %d\n", __func__, msg->act);
928     switch (msg->act) {
929     case BTC_GAP_BT_ACT_SET_SCAN_MODE: {
930         btc_bt_set_scan_mode(arg->set_scan_mode.c_mode, arg->set_scan_mode.d_mode);
931         break;
932     }
933     case BTC_GAP_BT_ACT_START_DISCOVERY: {
934         btc_gap_bt_start_discovery(arg);
935         break;
936     }
937     case BTC_GAP_BT_ACT_CANCEL_DISCOVERY: {
938         btc_gap_bt_cancel_discovery();
939         break;
940     }
941     case BTC_GAP_BT_ACT_GET_REMOTE_SERVICES: {
942         btc_gap_bt_get_remote_services((bt_bdaddr_t *)msg->arg);
943         break;
944     }
945     case BTC_GAP_BT_ACT_GET_REMOTE_SERVICE_RECORD: {
946         btc_gap_bt_get_remote_service_record(arg);
947         break;
948     }
949     case BTC_GAP_BT_ACT_SET_COD: {
950         btc_gap_bt_set_cod(arg);
951         break;
952     }
953     case BTC_GAP_BT_ACT_READ_RSSI_DELTA: {
954         btc_gap_bt_read_rssi_delta(arg);
955         break;
956     }
957     case BTC_GAP_BT_ACT_REMOVE_BOND_DEVICE:{
958         btc_gap_bt_remove_bond_device(arg);
959         break;
960     }
961     case BTC_GAP_BT_ACT_SET_PIN_TYPE:{
962         btc_gap_bt_set_pin_type(arg);
963         break;
964     }
965     case BTC_GAP_BT_ACT_PIN_REPLY: {
966         btc_gap_bt_pin_reply(arg);
967         break;
968     }
969 #if (BT_SSP_INCLUDED == TRUE)
970     case BTC_GAP_BT_ACT_SET_SECURITY_PARAM:{
971         btc_gap_bt_set_security_param(arg);
972         break;
973     }
974     case BTC_GAP_BT_ACT_PASSKEY_REPLY:{
975         btc_gap_bt_ssp_passkey_reply(arg);
976         break;
977     }
978     case BTC_GAP_BT_ACT_CONFIRM_REPLY:{
979         btc_gap_bt_ssp_confirm(arg);
980         break;
981     }
982 #endif ///BT_SSP_INCLUDED == TRUE
983     case BTC_GAP_BT_ACT_CONFIG_EIR: {
984         btc_gap_bt_config_eir(arg);
985         break;
986     }
987 
988     case BTC_GAP_BT_ACT_SET_AFH_CHANNELS: {
989         btc_gap_bt_set_afh_channels(arg);
990         break;
991     }
992     case BTC_GAP_BT_ACT_READ_REMOTE_NAME: {
993         btc_gap_bt_read_remote_name(arg);
994         break;
995     }
996     case BTC_GAP_BT_ACT_SET_QOS: {
997         btc_gap_bt_set_qos(arg);
998         break;
999     }
1000     case BTC_GAP_BT_ACT_SET_ACL_PKT_TYPES: {
1001         btc_gap_set_acl_pkt_types(arg);
1002         break;
1003     }
1004     default:
1005         break;
1006     }
1007     btc_gap_bt_arg_deep_free(msg);
1008     return;
1009 }
1010 
btc_gap_bt_busy_level_updated(uint8_t bl_flags)1011 void btc_gap_bt_busy_level_updated(uint8_t bl_flags)
1012 {
1013     esp_bt_gap_cb_param_t param;
1014 
1015     if (bl_flags == BTM_BL_INQUIRY_STARTED) {
1016         param.disc_st_chg.state = ESP_BT_GAP_DISCOVERY_STARTED;
1017         btc_gap_bt_cb_to_app(ESP_BT_GAP_DISC_STATE_CHANGED_EVT, &param);
1018         btc_gap_bt_inquiry_in_progress = true;
1019     } else if (bl_flags == BTM_BL_INQUIRY_CANCELLED) {
1020         param.disc_st_chg.state = ESP_BT_GAP_DISCOVERY_STOPPED;
1021         btc_gap_bt_cb_to_app(ESP_BT_GAP_DISC_STATE_CHANGED_EVT, &param);
1022         btc_gap_bt_inquiry_in_progress = false;
1023     } else if (bl_flags == BTM_BL_INQUIRY_COMPLETE) {
1024         /* The Inquiry Complete event is not transported to app layer,
1025         since the app only cares about the Name Discovery Complete event */
1026         btc_gap_bt_inquiry_in_progress = false;
1027     }
1028 }
1029 
btc_gap_bt_cb_deep_free(btc_msg_t * msg)1030 void btc_gap_bt_cb_deep_free(btc_msg_t *msg)
1031 {
1032     switch (msg->act) {
1033     case BTC_GAP_BT_SEARCH_DEVICES_EVT:
1034     case BTC_GAP_BT_SEARCH_SERVICES_EVT:
1035     case BTC_GAP_BT_SEARCH_SERVICE_RECORD_EVT:
1036         osi_free(((tBTA_DM_SEARCH_PARAM *) (msg->arg)) ->p_data);
1037         break;
1038     case BTC_GAP_BT_READ_RSSI_DELTA_EVT:
1039     case BTC_GAP_BT_CONFIG_EIR_DATA_EVT:
1040     case BTC_GAP_BT_AUTH_CMPL_EVT:
1041     case BTC_GAP_BT_PIN_REQ_EVT:
1042     case BTC_GAP_BT_SET_AFH_CHANNELS_EVT:
1043     case BTC_GAP_BT_READ_REMOTE_NAME_EVT:
1044     case BTC_GAP_BT_REMOVE_BOND_DEV_COMPLETE_EVT:
1045     case BTC_GAP_BT_QOS_EVT:
1046 #if (BT_SSP_INCLUDED == TRUE)
1047     case BTC_GAP_BT_SET_ACL_PKT_TYPES_EVT:
1048     case BTC_GAP_BT_CFM_REQ_EVT:
1049     case BTC_GAP_BT_KEY_NOTIF_EVT:
1050     case BTC_GAP_BT_KEY_REQ_EVT:
1051 #endif ///BT_SSP_INCLUDED == TRUE
1052 #if (BTC_DM_PM_INCLUDED == TRUE)
1053     case BTC_GAP_BT_MODE_CHG_EVT:
1054 #endif /// BTC_DM_PM_INCLUDED == TRUE
1055         break;
1056     default:
1057         BTC_TRACE_ERROR("%s: Unhandled event (%d)!\n", __FUNCTION__, msg->act);
1058         break;
1059     }
1060 }
1061 
btc_gap_bt_cb_handler(btc_msg_t * msg)1062 void btc_gap_bt_cb_handler(btc_msg_t *msg)
1063 {
1064     switch (msg->act) {
1065     case BTC_GAP_BT_SEARCH_DEVICES_EVT: {
1066         btc_gap_bt_search_devices_evt((tBTA_DM_SEARCH_PARAM *)msg->arg);
1067         break;
1068     }
1069     case BTC_GAP_BT_SEARCH_SERVICES_EVT: {
1070         btc_gap_bt_search_services((char *)msg->arg);
1071         break;
1072     }
1073     case BTC_GAP_BT_SEARCH_SERVICE_RECORD_EVT: {
1074         btc_gap_bt_search_service_record((char *)msg->arg);
1075         break;
1076     }
1077     case BTC_GAP_BT_READ_RSSI_DELTA_EVT:{
1078         btc_gap_bt_cb_to_app(ESP_BT_GAP_READ_RSSI_DELTA_EVT, (esp_bt_gap_cb_param_t *)msg->arg);
1079         break;
1080     }
1081     case BTC_GAP_BT_CONFIG_EIR_DATA_EVT: {
1082         btc_gap_bt_cb_to_app(ESP_BT_GAP_CONFIG_EIR_DATA_EVT, (esp_bt_gap_cb_param_t *)msg->arg);
1083         break;
1084     }
1085     case BTC_GAP_BT_AUTH_CMPL_EVT:{
1086         btc_gap_bt_cb_to_app(ESP_BT_GAP_AUTH_CMPL_EVT, (esp_bt_gap_cb_param_t *)msg->arg);
1087         break;
1088     }
1089     case BTC_GAP_BT_PIN_REQ_EVT:{
1090         btc_gap_bt_cb_to_app(ESP_BT_GAP_PIN_REQ_EVT, (esp_bt_gap_cb_param_t *)msg->arg);
1091         break;
1092     }
1093 #if (BT_SSP_INCLUDED == TRUE)
1094     case BTC_GAP_BT_CFM_REQ_EVT:{
1095         btc_gap_bt_cb_to_app(ESP_BT_GAP_CFM_REQ_EVT, (esp_bt_gap_cb_param_t *)msg->arg);
1096         break;
1097     }
1098     case BTC_GAP_BT_KEY_NOTIF_EVT:{
1099         btc_gap_bt_cb_to_app(ESP_BT_GAP_KEY_NOTIF_EVT, (esp_bt_gap_cb_param_t *)msg->arg);
1100         break;
1101     }
1102     case BTC_GAP_BT_KEY_REQ_EVT:{
1103         btc_gap_bt_cb_to_app(ESP_BT_GAP_KEY_REQ_EVT, (esp_bt_gap_cb_param_t *)msg->arg);
1104         break;
1105     }
1106 #endif ///BT_SSP_INCLUDED == TRUE
1107     case BTC_GAP_BT_SET_AFH_CHANNELS_EVT:{
1108         btc_gap_bt_cb_to_app(ESP_BT_GAP_SET_AFH_CHANNELS_EVT, (esp_bt_gap_cb_param_t *)msg->arg);
1109         break;
1110     }
1111 #if (SDP_INCLUDED == TRUE)
1112     case BTC_GAP_BT_READ_REMOTE_NAME_EVT:{
1113         btc_gap_bt_cb_to_app(ESP_BT_GAP_READ_REMOTE_NAME_EVT,(esp_bt_gap_cb_param_t *)msg->arg);
1114         break;
1115     }
1116 #endif
1117 
1118 #if (BTC_DM_PM_INCLUDED == TRUE)
1119     case BTC_GAP_BT_MODE_CHG_EVT:
1120         btc_gap_bt_cb_to_app(ESP_BT_GAP_MODE_CHG_EVT,(esp_bt_gap_cb_param_t *)msg->arg);
1121         break;
1122 #endif /// BTC_DM_PM_INCLUDED == TRUE
1123     case BTC_GAP_BT_REMOVE_BOND_DEV_COMPLETE_EVT:{
1124         btc_gap_bt_cb_to_app(ESP_BT_GAP_REMOVE_BOND_DEV_COMPLETE_EVT,(esp_bt_gap_cb_param_t *)msg->arg);
1125         break;
1126     }
1127 
1128     case BTC_GAP_BT_QOS_EVT:{
1129         btc_gap_bt_cb_to_app(ESP_BT_GAP_QOS_CMPL_EVT, (esp_bt_gap_cb_param_t *)msg->arg);
1130         break;
1131     }
1132     case BTC_GAP_BT_SET_ACL_PKT_TYPES_EVT: {
1133         btc_gap_bt_cb_to_app(ESP_BT_GAP_ACL_PKT_TYPE_CHANGED_EVT, (esp_bt_gap_cb_param_t *)msg->arg);
1134         break;
1135     }
1136     default:
1137         BTC_TRACE_ERROR("%s: Unhandled event (%d)!\n", __FUNCTION__, msg->act);
1138         break;
1139     }
1140     btc_gap_bt_cb_deep_free(msg);
1141 }
1142 #endif /* (BTC_GAP_BT_INCLUDED == TRUE) */
1143