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