1 /*
2  * SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #include "string.h"
8 #include "esp_gatt_defs.h"
9 #include "esp_gatts_api.h"
10 #include "esp_bt_main.h"
11 #include "btc/btc_manage.h"
12 #include "btc_gatts.h"
13 #include "btc_gatt_util.h"
14 #include "common/bt_target.h"
15 #include "stack/l2cdefs.h"
16 #include "stack/l2c_api.h"
17 #include "gatt_int.h"
18 
19 #if (GATTS_INCLUDED == TRUE)
20 #define COPY_TO_GATTS_ARGS(_gatt_args, _arg, _arg_type) memcpy(_gatt_args, _arg, sizeof(_arg_type))
21 
22 static esp_err_t esp_ble_gatts_add_char_desc_param_check(esp_attr_value_t *char_val, esp_attr_control_t *control);
23 
24 
esp_ble_gatts_register_callback(esp_gatts_cb_t callback)25 esp_err_t esp_ble_gatts_register_callback(esp_gatts_cb_t callback)
26 {
27     ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
28 
29     return (btc_profile_cb_set(BTC_PID_GATTS, callback) == 0 ? ESP_OK : ESP_FAIL);
30 }
31 
esp_ble_gatts_get_callback(void)32 esp_gatts_cb_t esp_ble_gatts_get_callback(void)
33 {
34     return (esp_gatts_cb_t) btc_profile_cb_get(BTC_PID_GATTS);
35 }
36 
esp_ble_gatts_app_register(uint16_t app_id)37 esp_err_t esp_ble_gatts_app_register(uint16_t app_id)
38 {
39     btc_msg_t msg = {0};
40     btc_ble_gatts_args_t arg;
41 
42     ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
43 
44     //if (app_id < ESP_APP_ID_MIN || app_id > ESP_APP_ID_MAX) {
45     if (app_id > ESP_APP_ID_MAX) {
46         return ESP_ERR_INVALID_ARG;
47     }
48 
49     msg.sig = BTC_SIG_API_CALL;
50     msg.pid = BTC_PID_GATTS;
51     msg.act = BTC_GATTS_ACT_APP_REGISTER;
52     arg.app_reg.app_id = app_id;
53 
54     return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_gatts_args_t), NULL, NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
55 }
56 
57 
esp_ble_gatts_app_unregister(esp_gatt_if_t gatts_if)58 esp_err_t esp_ble_gatts_app_unregister(esp_gatt_if_t gatts_if)
59 {
60     btc_msg_t msg = {0};
61     btc_ble_gatts_args_t arg;
62 
63     ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
64 
65     msg.sig = BTC_SIG_API_CALL;
66     msg.pid = BTC_PID_GATTS;
67     msg.act = BTC_GATTS_ACT_APP_UNREGISTER;
68     arg.app_unreg.gatts_if = gatts_if;
69 
70     return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_gatts_args_t), NULL, NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
71 }
72 
esp_ble_gatts_create_service(esp_gatt_if_t gatts_if,esp_gatt_srvc_id_t * service_id,uint16_t num_handle)73 esp_err_t esp_ble_gatts_create_service(esp_gatt_if_t gatts_if,
74                                        esp_gatt_srvc_id_t *service_id, uint16_t num_handle)
75 {
76     btc_msg_t msg = {0};
77     btc_ble_gatts_args_t arg;
78 
79     ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
80 
81     msg.sig = BTC_SIG_API_CALL;
82     msg.pid = BTC_PID_GATTS;
83     msg.act = BTC_GATTS_ACT_CREATE_SERVICE;
84     arg.create_srvc.gatts_if = gatts_if;
85     arg.create_srvc.num_handle = num_handle;
86     memcpy(&arg.create_srvc.service_id, service_id, sizeof(esp_gatt_srvc_id_t));
87 
88     return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_gatts_args_t), NULL, NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
89 }
90 
esp_ble_gatts_create_attr_tab(const esp_gatts_attr_db_t * gatts_attr_db,esp_gatt_if_t gatts_if,uint16_t max_nb_attr,uint8_t srvc_inst_id)91 esp_err_t esp_ble_gatts_create_attr_tab(const esp_gatts_attr_db_t *gatts_attr_db,
92                                         esp_gatt_if_t gatts_if,
93                                         uint16_t max_nb_attr,
94                                         uint8_t srvc_inst_id)
95 {
96     btc_msg_t msg = {0};
97     btc_ble_gatts_args_t arg;
98 
99     ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
100 
101     if (max_nb_attr > ESP_GATT_ATTR_HANDLE_MAX) {
102         LOG_ERROR("The number of attribute should not be greater than CONFIG_BT_GATT_MAX_SR_ATTRIBUTES\n");
103         return ESP_ERR_INVALID_ARG;
104     }
105 
106     msg.sig = BTC_SIG_API_CALL;
107     msg.pid = BTC_PID_GATTS;
108     msg.act = BTC_GATTS_ACT_CREATE_ATTR_TAB;
109     arg.create_attr_tab.gatts_if = gatts_if;
110     arg.create_attr_tab.max_nb_attr = max_nb_attr;
111     arg.create_attr_tab.srvc_inst_id = srvc_inst_id;
112     arg.create_attr_tab.gatts_attr_db = (esp_gatts_attr_db_t *)gatts_attr_db;
113 
114     return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_gatts_args_t), btc_gatts_arg_deep_copy,
115                 btc_gatts_arg_deep_free) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
116 }
117 
118 
esp_ble_gatts_add_included_service(uint16_t service_handle,uint16_t included_service_handle)119 esp_err_t esp_ble_gatts_add_included_service(uint16_t service_handle, uint16_t included_service_handle)
120 {
121     btc_msg_t msg = {0};
122     btc_ble_gatts_args_t arg;
123 
124     ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
125 
126     msg.sig = BTC_SIG_API_CALL;
127     msg.pid = BTC_PID_GATTS;
128     msg.act = BTC_GATTS_ACT_ADD_INCLUDE_SERVICE;
129     arg.add_incl_srvc.service_handle = service_handle;
130     arg.add_incl_srvc.included_service_handle = included_service_handle;
131 
132     return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_gatts_args_t), NULL, NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
133 }
134 
135 
esp_ble_gatts_add_char(uint16_t service_handle,esp_bt_uuid_t * char_uuid,esp_gatt_perm_t perm,esp_gatt_char_prop_t property,esp_attr_value_t * char_val,esp_attr_control_t * control)136 esp_err_t esp_ble_gatts_add_char(uint16_t service_handle,  esp_bt_uuid_t  *char_uuid,
137                                  esp_gatt_perm_t perm, esp_gatt_char_prop_t property, esp_attr_value_t *char_val,
138                                  esp_attr_control_t *control)
139 {
140     btc_msg_t msg = {0};
141     btc_ble_gatts_args_t arg;
142     esp_err_t status;
143 
144     ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
145 
146     /* parameter validation check */
147     status = esp_ble_gatts_add_char_desc_param_check(char_val, control);
148     if (status != ESP_OK){
149         return status;
150     }
151 
152     memset(&arg, 0, sizeof(btc_ble_gatts_args_t));
153     msg.sig = BTC_SIG_API_CALL;
154     msg.pid = BTC_PID_GATTS;
155     msg.act = BTC_GATTS_ACT_ADD_CHAR;
156     arg.add_char.service_handle = service_handle;
157     arg.add_char.perm = perm;
158     arg.add_char.property = property;
159     if (char_val != NULL) {
160         arg.add_char.char_val.attr_max_len = char_val->attr_max_len;
161         arg.add_char.char_val.attr_len = char_val->attr_len;
162         arg.add_char.char_val.attr_value = char_val->attr_value;
163     }
164 
165     if (control != NULL) {
166         arg.add_char.attr_control.auto_rsp = control->auto_rsp;
167     }
168     memcpy(&arg.add_char.char_uuid, char_uuid, sizeof(esp_bt_uuid_t));
169 
170     return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_gatts_args_t), btc_gatts_arg_deep_copy,
171                 btc_gatts_arg_deep_free) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
172 }
173 
174 
esp_ble_gatts_add_char_descr(uint16_t service_handle,esp_bt_uuid_t * descr_uuid,esp_gatt_perm_t perm,esp_attr_value_t * char_descr_val,esp_attr_control_t * control)175 esp_err_t esp_ble_gatts_add_char_descr (uint16_t service_handle,
176                                         esp_bt_uuid_t   *descr_uuid,
177                                         esp_gatt_perm_t perm, esp_attr_value_t *char_descr_val,
178                                         esp_attr_control_t *control)
179 {
180     btc_msg_t msg = {0};
181     btc_ble_gatts_args_t arg;
182     esp_err_t status;
183 
184     ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
185 
186     /* parameter validation check */
187     status = esp_ble_gatts_add_char_desc_param_check(char_descr_val, control);
188     if (status != ESP_OK){
189         return status;
190     }
191 
192     memset(&arg, 0, sizeof(btc_ble_gatts_args_t));
193     msg.sig = BTC_SIG_API_CALL;
194     msg.pid = BTC_PID_GATTS;
195     msg.act = BTC_GATTS_ACT_ADD_CHAR_DESCR;
196     arg.add_descr.service_handle = service_handle;
197     arg.add_descr.perm = perm;
198 
199     if (char_descr_val != NULL) {
200         arg.add_descr.descr_val.attr_max_len = char_descr_val->attr_max_len;
201         arg.add_descr.descr_val.attr_len = char_descr_val->attr_len;
202         arg.add_descr.descr_val.attr_value = char_descr_val->attr_value;
203     }
204 
205     if (control != NULL) {
206         arg.add_descr.attr_control.auto_rsp = control->auto_rsp;
207     }
208     memcpy(&arg.add_descr.descr_uuid, descr_uuid, sizeof(esp_bt_uuid_t));
209 
210     return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_gatts_args_t), btc_gatts_arg_deep_copy,
211                 btc_gatts_arg_deep_free) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
212 }
213 
esp_ble_gatts_delete_service(uint16_t service_handle)214 esp_err_t esp_ble_gatts_delete_service(uint16_t service_handle)
215 {
216     btc_msg_t msg = {0};
217     btc_ble_gatts_args_t arg;
218 
219     ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
220 
221     msg.sig = BTC_SIG_API_CALL;
222     msg.pid = BTC_PID_GATTS;
223     msg.act = BTC_GATTS_ACT_DELETE_SERVICE;
224     arg.delete_srvc.service_handle = service_handle;
225 
226     return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_gatts_args_t), NULL, NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
227 }
228 
esp_ble_gatts_start_service(uint16_t service_handle)229 esp_err_t esp_ble_gatts_start_service(uint16_t service_handle)
230 {
231     btc_msg_t msg = {0};
232     btc_ble_gatts_args_t arg;
233 
234     ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
235 
236     msg.sig = BTC_SIG_API_CALL;
237     msg.pid = BTC_PID_GATTS;
238     msg.act = BTC_GATTS_ACT_START_SERVICE;
239     arg.start_srvc.service_handle = service_handle;
240 
241     return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_gatts_args_t), NULL, NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
242 }
243 
esp_ble_gatts_stop_service(uint16_t service_handle)244 esp_err_t esp_ble_gatts_stop_service(uint16_t service_handle)
245 {
246     btc_msg_t msg = {0};
247     btc_ble_gatts_args_t arg;
248 
249     ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
250 
251     msg.sig = BTC_SIG_API_CALL;
252     msg.pid = BTC_PID_GATTS;
253     msg.act = BTC_GATTS_ACT_STOP_SERVICE;
254     arg.stop_srvc.service_handle = service_handle;
255 
256     return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_gatts_args_t), NULL, NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
257 }
258 
259 
esp_ble_gatts_send_indicate(esp_gatt_if_t gatts_if,uint16_t conn_id,uint16_t attr_handle,uint16_t value_len,uint8_t * value,bool need_confirm)260 esp_err_t esp_ble_gatts_send_indicate(esp_gatt_if_t gatts_if, uint16_t conn_id, uint16_t attr_handle,
261                                       uint16_t value_len, uint8_t *value, bool need_confirm)
262 {
263     btc_msg_t msg = {0};
264     btc_ble_gatts_args_t arg;
265 
266     ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
267 
268     tGATT_TCB       *p_tcb = gatt_get_tcb_by_idx(conn_id);
269     if (!gatt_check_connection_state_by_tcb(p_tcb)) {
270         LOG_WARN("%s, The connection not created.", __func__);
271         return ESP_ERR_INVALID_STATE;
272     }
273 
274     if (L2CA_CheckIsCongest(L2CAP_ATT_CID, p_tcb->peer_bda)) {
275         LOG_DEBUG("%s, the l2cap chanel is congest.", __func__);
276         return ESP_FAIL;
277     }
278 
279     msg.sig = BTC_SIG_API_CALL;
280     msg.pid = BTC_PID_GATTS;
281     msg.act = BTC_GATTS_ACT_SEND_INDICATE;
282     arg.send_ind.conn_id = BTC_GATT_CREATE_CONN_ID(gatts_if, conn_id);
283     arg.send_ind.attr_handle = attr_handle;
284     arg.send_ind.need_confirm = need_confirm;
285     arg.send_ind.value_len = value_len;
286     arg.send_ind.value = value;
287     if(need_confirm == false){
288         l2ble_update_att_acl_pkt_num(L2CA_ADD_BTC_NUM, NULL);
289     }
290     return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_gatts_args_t), btc_gatts_arg_deep_copy,
291                 btc_gatts_arg_deep_free) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
292 }
293 
esp_ble_gatts_send_response(esp_gatt_if_t gatts_if,uint16_t conn_id,uint32_t trans_id,esp_gatt_status_t status,esp_gatt_rsp_t * rsp)294 esp_err_t esp_ble_gatts_send_response(esp_gatt_if_t gatts_if, uint16_t conn_id, uint32_t trans_id,
295                                       esp_gatt_status_t status, esp_gatt_rsp_t *rsp)
296 {
297     btc_msg_t msg = {0};
298     btc_ble_gatts_args_t arg;
299 
300     ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
301 
302     tGATT_TCB       *p_tcb = gatt_get_tcb_by_idx(conn_id);
303     if (!gatt_check_connection_state_by_tcb(p_tcb)) {
304         LOG_WARN("%s, The connection not created.", __func__);
305         return ESP_ERR_INVALID_STATE;
306     }
307 
308     msg.sig = BTC_SIG_API_CALL;
309     msg.pid = BTC_PID_GATTS;
310     msg.act = BTC_GATTS_ACT_SEND_RESPONSE;
311     arg.send_rsp.conn_id = BTC_GATT_CREATE_CONN_ID(gatts_if, conn_id);
312     arg.send_rsp.trans_id = trans_id;
313     arg.send_rsp.status = status;
314     arg.send_rsp.rsp = rsp;
315 
316     return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_gatts_args_t), btc_gatts_arg_deep_copy,
317                 btc_gatts_arg_deep_free) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
318 }
319 
esp_ble_gatts_set_attr_value(uint16_t attr_handle,uint16_t length,const uint8_t * value)320 esp_err_t esp_ble_gatts_set_attr_value(uint16_t attr_handle, uint16_t length, const uint8_t *value)
321 {
322     btc_msg_t msg = {0};
323     btc_ble_gatts_args_t arg;
324 
325     ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
326 
327     msg.sig = BTC_SIG_API_CALL;
328     msg.pid = BTC_PID_GATTS;
329     msg.act = BTC_GATTS_ACT_SET_ATTR_VALUE;
330     arg.set_attr_val.handle = attr_handle;
331     arg.set_attr_val.length = length;
332     arg.set_attr_val.value  = (uint8_t *)value;
333 
334     return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_gatts_args_t), btc_gatts_arg_deep_copy,
335                 btc_gatts_arg_deep_free) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
336 }
337 
esp_ble_gatts_get_attr_value(uint16_t attr_handle,uint16_t * length,const uint8_t ** value)338 esp_gatt_status_t esp_ble_gatts_get_attr_value(uint16_t attr_handle, uint16_t *length, const uint8_t **value)
339 {
340     ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
341 
342     if (attr_handle == ESP_GATT_ILLEGAL_HANDLE) {
343         *length = 0;
344         return ESP_GATT_INVALID_HANDLE;
345     }
346 
347     return btc_gatts_get_attr_value(attr_handle, length, (uint8_t **)value);
348 }
349 
esp_ble_gatts_open(esp_gatt_if_t gatts_if,esp_bd_addr_t remote_bda,bool is_direct)350 esp_err_t esp_ble_gatts_open(esp_gatt_if_t gatts_if, esp_bd_addr_t remote_bda, bool is_direct)
351 {
352     btc_msg_t msg = {0};
353     btc_ble_gatts_args_t arg;
354 
355     ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
356 
357     msg.sig = BTC_SIG_API_CALL;
358     msg.pid = BTC_PID_GATTS;
359     msg.act = BTC_GATTS_ACT_OPEN;
360     arg.open.gatts_if = gatts_if;
361     arg.open.is_direct = is_direct;
362     memcpy(&arg.open.remote_bda, remote_bda, sizeof(esp_bd_addr_t));
363 
364     return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_gatts_args_t), NULL, NULL)
365             == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
366 }
367 
esp_ble_gatts_close(esp_gatt_if_t gatts_if,uint16_t conn_id)368 esp_err_t esp_ble_gatts_close(esp_gatt_if_t gatts_if, uint16_t conn_id)
369 {
370     btc_msg_t msg = {0};
371     btc_ble_gatts_args_t arg;
372 
373     ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
374 
375     msg.sig = BTC_SIG_API_CALL;
376     msg.pid = BTC_PID_GATTS;
377     msg.act = BTC_GATTS_ACT_CLOSE;
378     arg.close.conn_id = BTC_GATT_CREATE_CONN_ID(gatts_if, conn_id);
379 
380     return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_gatts_args_t), NULL, NULL)
381             == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
382 }
383 
esp_ble_gatts_send_service_change_indication(esp_gatt_if_t gatts_if,esp_bd_addr_t remote_bda)384 esp_err_t esp_ble_gatts_send_service_change_indication(esp_gatt_if_t gatts_if, esp_bd_addr_t remote_bda)
385 {
386     btc_msg_t msg = {0};
387     btc_ble_gatts_args_t arg;
388 
389     ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
390 
391     msg.sig = BTC_SIG_API_CALL;
392     msg.pid = BTC_PID_GATTS;
393     msg.act = BTC_GATTS_ACT_SEND_SERVICE_CHANGE;
394     arg.send_service_change.gatts_if = gatts_if;
395     if(remote_bda) {
396         memcpy(&arg.send_service_change.remote_bda, remote_bda, sizeof(esp_bd_addr_t));
397     } else {
398         memset(arg.send_service_change.remote_bda, 0, sizeof(esp_bd_addr_t));
399     }
400 
401 
402     return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_gatts_args_t), NULL, NULL)
403             == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
404 }
405 
esp_ble_gatts_add_char_desc_param_check(esp_attr_value_t * char_val,esp_attr_control_t * control)406 static esp_err_t esp_ble_gatts_add_char_desc_param_check(esp_attr_value_t *char_val, esp_attr_control_t *control)
407 {
408     if ((control != NULL) && ((control->auto_rsp != ESP_GATT_AUTO_RSP) && (control->auto_rsp != ESP_GATT_RSP_BY_APP))){
409             LOG_ERROR("Error in %s, line=%d, control->auto_rsp should be set to ESP_GATT_AUTO_RSP or ESP_GATT_RSP_BY_APP\n",\
410                             __func__, __LINE__);
411             return ESP_ERR_INVALID_ARG;
412     }
413 
414     if ((control != NULL) && (control->auto_rsp == ESP_GATT_AUTO_RSP)){
415         if (char_val == NULL){
416             LOG_ERROR("Error in %s, line=%d, for stack respond attribute, char_val should not be NULL here\n",\
417                             __func__, __LINE__);
418             return ESP_ERR_INVALID_ARG;
419         } else if (char_val->attr_max_len == 0){
420             LOG_ERROR("Error in %s, line=%d, for stack respond attribute,  attribute max length should not be 0\n",\
421                             __func__, __LINE__);
422             return ESP_ERR_INVALID_ARG;
423         }
424     }
425 
426     return ESP_OK;
427 }
428 
esp_ble_gatts_show_local_database(void)429 esp_err_t esp_ble_gatts_show_local_database(void)
430 {
431     btc_msg_t msg = {0};
432 
433     ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
434 
435     msg.sig = BTC_SIG_API_CALL;
436     msg.pid = BTC_PID_GATTS;
437     msg.act = BTC_GATTS_ACT_SHOW_LOCAL_DATABASE;
438 
439     return (btc_transfer_context(&msg, NULL, 0, NULL, NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
440 }
441 
442 #endif  ///GATTS_INCLUDED
443