1 /*
2  * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #include <string.h>
8 
9 #include "bta/bta_gatt_api.h"
10 
11 #include "btc/btc_task.h"
12 #include "btc/btc_manage.h"
13 #include "btc_gatts.h"
14 #include "btc_gatt_util.h"
15 #include "osi/future.h"
16 #include "osi/allocator.h"
17 #include "btc/btc_main.h"
18 #include "esp_gatts_api.h"
19 #include "btc/btc_storage.h"
20 #include "common/bt_defs.h"
21 
22 #if (GATTS_INCLUDED == TRUE)
23 
24 #define A2C_GATTS_EVT(_bta_event) (_bta_event) //BTA TO BTC EVT
25 #define C2A_GATTS_EVT(_btc_event) (_btc_event) //BTC TO BTA EVT
26 
27 #if GATT_DYNAMIC_MEMORY == FALSE
28 static esp_btc_creat_tab_t btc_creat_tab_env;
29 #else
30 esp_btc_creat_tab_t *btc_creat_tab_env_ptr;
31 #endif
32 
33 static esp_gatt_status_t btc_gatts_check_valid_attr_tab(esp_gatts_attr_db_t *gatts_attr_db,
34                                                                           uint8_t max_nb_attr);
35 
btc_gatts_cb_to_app(esp_gatts_cb_event_t event,esp_gatt_if_t gatts_if,esp_ble_gatts_cb_param_t * param)36 static inline void btc_gatts_cb_to_app(esp_gatts_cb_event_t event, esp_gatt_if_t gatts_if, esp_ble_gatts_cb_param_t *param)
37 {
38     esp_gatts_cb_t btc_gatts_cb = (esp_gatts_cb_t)btc_profile_cb_get(BTC_PID_GATTS);
39     if (btc_gatts_cb) {
40         btc_gatts_cb(event, gatts_if, param);
41     }
42 }
43 
btc_gatts_uuid_format_convert(esp_bt_uuid_t * dest_uuid,uint16_t src_uuid_len,uint8_t * src_uuid_p)44 static inline void btc_gatts_uuid_format_convert(esp_bt_uuid_t* dest_uuid, uint16_t src_uuid_len, uint8_t* src_uuid_p)
45 {
46     dest_uuid->len = src_uuid_len;
47     if(src_uuid_len == ESP_UUID_LEN_16){
48         dest_uuid->uuid.uuid16 = src_uuid_p[0] + (src_uuid_p[1]<<8);
49     }
50     else if(src_uuid_len == ESP_UUID_LEN_32){
51         dest_uuid->uuid.uuid32 = src_uuid_p[0] + (src_uuid_p[1]<<8) + (src_uuid_p[2]<<16) + (src_uuid_p[3]<<24);
52     }
53     else if(src_uuid_len == ESP_UUID_LEN_128){
54         memcpy(dest_uuid->uuid.uuid128, src_uuid_p, src_uuid_len);
55     }
56     else{
57         BTC_TRACE_ERROR("%s wrong uuid length %d\n", __func__, src_uuid_len);
58     }
59 
60 }
61 
62 
btc_gatts_arg_deep_copy(btc_msg_t * msg,void * p_dest,void * p_src)63 void btc_gatts_arg_deep_copy(btc_msg_t *msg, void *p_dest, void *p_src)
64 {
65     btc_ble_gatts_args_t *dst = (btc_ble_gatts_args_t *) p_dest;
66     btc_ble_gatts_args_t *src = (btc_ble_gatts_args_t *)p_src;
67 
68     switch (msg->act) {
69     case BTC_GATTS_ACT_SEND_INDICATE: {
70         if (src->send_ind.value && (src->send_ind.value_len > 0)) {
71             dst->send_ind.value = (uint8_t *) osi_malloc(src->send_ind.value_len);
72             if (dst->send_ind.value) {
73                 memcpy(dst->send_ind.value, src->send_ind.value, src->send_ind.value_len);
74             } else {
75                 BTC_TRACE_ERROR("%s %d no mem\n", __func__, msg->act);
76             }
77         } else {
78             dst->send_ind.value = NULL;
79             if (src->send_ind.value) {
80                 BTC_TRACE_ERROR("%s %d, invalid length", __func__, msg->act);
81             }
82         }
83         break;
84     }
85     case BTC_GATTS_ACT_SEND_RESPONSE: {
86         if (src->send_rsp.rsp) {
87             dst->send_rsp.rsp = (esp_gatt_rsp_t *) osi_malloc(sizeof(esp_gatt_rsp_t));
88             if (dst->send_rsp.rsp) {
89                 memcpy(dst->send_rsp.rsp, src->send_rsp.rsp, sizeof(esp_gatt_rsp_t));
90             } else {
91                 BTC_TRACE_ERROR("%s %d no mem\n", __func__, msg->act);
92             }
93         }
94         break;
95 
96     }
97     case BTC_GATTS_ACT_ADD_CHAR: {
98         if (src->add_char.char_val.attr_value && (src->add_char.char_val.attr_len > 0)) {
99             dst->add_char.char_val.attr_value = (uint8_t *) osi_malloc(src->add_char.char_val.attr_len);
100             if (dst->add_char.char_val.attr_value) {
101                 memcpy(dst->add_char.char_val.attr_value, src->add_char.char_val.attr_value,
102                         src->add_char.char_val.attr_len);
103             } else {
104                 BTC_TRACE_ERROR("%s %d no mem\n", __func__, msg->act);
105             }
106         } else {
107             dst->add_char.char_val.attr_value = NULL;
108             if (src->add_char.char_val.attr_value) {
109                 BTC_TRACE_ERROR("%s %d, invalid length", __func__, msg->act);
110             }
111         }
112         break;
113     }
114     case BTC_GATTS_ACT_ADD_CHAR_DESCR: {
115         if (src->add_descr.descr_val.attr_value && (src->add_descr.descr_val.attr_len > 0)) {
116             dst->add_descr.descr_val.attr_value = (uint8_t *) osi_malloc(src->add_descr.descr_val.attr_len);
117             if (dst->add_descr.descr_val.attr_value) {
118                 memcpy(dst->add_descr.descr_val.attr_value, src->add_descr.descr_val.attr_value,
119                         src->add_descr.descr_val.attr_len);
120             } else {
121                 BTC_TRACE_ERROR("%s %d no mem\n", __func__, msg->act);
122             }
123         } else {
124             dst->add_descr.descr_val.attr_value = NULL;
125             if (src->add_descr.descr_val.attr_value) {
126                 BTC_TRACE_ERROR("%s %d, invalid length", __func__, msg->act);
127             }
128         }
129         break;
130     }
131     case BTC_GATTS_ACT_CREATE_ATTR_TAB: {
132         uint16_t num_attr = src->create_attr_tab.max_nb_attr;
133         if (src->create_attr_tab.gatts_attr_db && (num_attr > 0)) {
134             dst->create_attr_tab.gatts_attr_db = (esp_gatts_attr_db_t *) osi_malloc(sizeof(esp_gatts_attr_db_t) * num_attr);
135             if (dst->create_attr_tab.gatts_attr_db) {
136                 memcpy(dst->create_attr_tab.gatts_attr_db, src->create_attr_tab.gatts_attr_db,
137                         sizeof(esp_gatts_attr_db_t) * num_attr);
138             } else {
139                 BTC_TRACE_ERROR("%s %d no mem\n",__func__, msg->act);
140             }
141         } else {
142             BTC_TRACE_ERROR("%s %d, NULL data", __func__, msg->act);
143         }
144         break;
145     }
146    case BTC_GATTS_ACT_SET_ATTR_VALUE: {
147         if (src->set_attr_val.value && (src->set_attr_val.length > 0)) {
148             dst->set_attr_val.value = (uint8_t *) osi_malloc(src->set_attr_val.length);
149             if (dst->set_attr_val.value) {
150                 memcpy(dst->set_attr_val.value, src->set_attr_val.value, src->set_attr_val.length);
151             } else {
152                 BTC_TRACE_ERROR("%s %d no mem\n",__func__, msg->act);
153             }
154         } else {
155             dst->set_attr_val.value = NULL;
156             if (src->set_attr_val.value) {
157                 BTC_TRACE_ERROR("%s %d, invalid length", __func__, msg->act);
158             } else {
159                 BTC_TRACE_WARNING("%s %d, NULL value", __func__, msg->act);
160             }
161         }
162         break;
163     }
164     default:
165         BTC_TRACE_DEBUG("%s Unhandled deep copy %d\n", __func__, msg->act);
166         break;
167     }
168 
169 }
170 
btc_gatts_arg_deep_free(btc_msg_t * msg)171 void btc_gatts_arg_deep_free(btc_msg_t *msg)
172 {
173     btc_ble_gatts_args_t *arg = (btc_ble_gatts_args_t *)msg->arg;
174 
175     switch (msg->act) {
176     case BTC_GATTS_ACT_SEND_INDICATE: {
177         if (arg->send_ind.value) {
178             osi_free(arg->send_ind.value);
179         }
180         break;
181     }
182     case BTC_GATTS_ACT_SEND_RESPONSE: {
183         if (arg->send_rsp.rsp) {
184             osi_free(arg->send_rsp.rsp);
185         }
186         break;
187     }
188     case BTC_GATTS_ACT_ADD_CHAR:{
189         if (arg->add_char.char_val.attr_value != NULL) {
190             osi_free(arg->add_char.char_val.attr_value);
191         }
192         break;
193     }
194     case BTC_GATTS_ACT_ADD_CHAR_DESCR:{
195         if (arg->add_descr.descr_val.attr_value != NULL){
196             osi_free(arg->add_descr.descr_val.attr_value);
197         }
198         break;
199     }
200     case BTC_GATTS_ACT_CREATE_ATTR_TAB:{
201         if (arg->create_attr_tab.gatts_attr_db != NULL){
202             osi_free(arg->create_attr_tab.gatts_attr_db);
203         }
204         break;
205     }
206     case BTC_GATTS_ACT_SET_ATTR_VALUE:{
207         if (arg->set_attr_val.value != NULL){
208             osi_free(arg->set_attr_val.value);
209         }
210     }
211         break;
212 
213     default:
214         BTC_TRACE_DEBUG("%s Unhandled deep free %d\n", __func__, msg->act);
215         break;
216     }
217 
218 }
219 
btc_gatts_act_create_attr_tab(esp_gatts_attr_db_t * gatts_attr_db,esp_gatt_if_t gatts_if,uint16_t max_nb_attr,uint8_t srvc_inst_id)220 static void btc_gatts_act_create_attr_tab(esp_gatts_attr_db_t *gatts_attr_db,
221                                                         esp_gatt_if_t gatts_if,
222                                                         uint16_t max_nb_attr,
223                                                         uint8_t srvc_inst_id)
224 {
225     uint16_t uuid = 0;
226     future_t *future_p;
227     esp_ble_gatts_cb_param_t param;
228     param.add_attr_tab.status = ESP_GATT_OK;
229     param.add_attr_tab.num_handle = max_nb_attr;
230 
231     if (param.add_attr_tab.status != ESP_GATT_OK) {
232         btc_gatts_cb_to_app(ESP_GATTS_CREAT_ATTR_TAB_EVT, gatts_if, &param);
233         //reset the env after sent the data to app
234         memset(&btc_creat_tab_env, 0, sizeof(esp_btc_creat_tab_t));
235         return;
236     }
237 
238     // Check the attribute table is valid or not
239     if ((param.add_attr_tab.status = btc_gatts_check_valid_attr_tab(gatts_attr_db, max_nb_attr)) != ESP_GATT_OK) {
240         //sent the callback event to the application
241         btc_gatts_cb_to_app(ESP_GATTS_CREAT_ATTR_TAB_EVT, gatts_if, &param);
242         return;
243     }
244 
245 
246     //set the attribute table create service flag to true
247     btc_creat_tab_env.is_tab_creat_svc = true;
248     btc_creat_tab_env.num_handle = max_nb_attr;
249     for(int i = 0; i < max_nb_attr; i++){
250         if(gatts_attr_db[i].att_desc.uuid_length == ESP_UUID_LEN_16){
251             uuid = (gatts_attr_db[i].att_desc.uuid_p[1] << 8) + (gatts_attr_db[i].att_desc.uuid_p[0]);
252         }
253         else{
254             continue;
255         }
256         future_p = future_new();
257         if (future_p == NULL) {
258                 BTC_TRACE_ERROR("%s failed:no mem\n", __func__);
259                 return ;
260             }
261         btc_creat_tab_env.complete_future = future_p;
262         btc_creat_tab_env.handle_idx = i;
263         switch(uuid)
264         {
265             case ESP_GATT_UUID_PRI_SERVICE:{
266                 tBTA_GATT_SRVC_ID srvc_id;
267                 esp_gatt_srvc_id_t        esp_srvc_id;
268 
269                 esp_srvc_id.id.inst_id = srvc_inst_id;
270                 btc_gatts_uuid_format_convert(&esp_srvc_id.id.uuid,gatts_attr_db[i].att_desc.length,
271                                               gatts_attr_db[i].att_desc.value);
272 
273                 btc_to_bta_srvc_id(&srvc_id, &esp_srvc_id);
274                 if (btc_creat_tab_env.is_use_svc != true) {
275                     BTA_GATTS_CreateService(gatts_if, &srvc_id.id.uuid,
276                                             srvc_inst_id, max_nb_attr, true);
277                     btc_creat_tab_env.is_use_svc = true;
278                 } else {
279                     BTC_TRACE_ERROR("Each service table can only created one primary service.");
280                     param.add_attr_tab.status = ESP_GATT_ERROR;
281                     btc_gatts_cb_to_app(ESP_GATTS_CREAT_ATTR_TAB_EVT, gatts_if, &param);
282                     //reset the env after sent the data to app
283                     memset(&btc_creat_tab_env, 0, sizeof(esp_btc_creat_tab_t));
284                     return;
285                 }
286 
287                  if (future_await(future_p) == FUTURE_FAIL) {
288                         BTC_TRACE_ERROR("%s failed\n", __func__);
289                         return;
290                         }
291                     break;
292             }
293             case ESP_GATT_UUID_SEC_SERVICE:{
294                 tBTA_GATT_SRVC_ID srvc_id = {0};
295                 esp_gatt_srvc_id_t        esp_srvc_id;
296 
297                 esp_srvc_id.id.inst_id = srvc_inst_id;
298                 btc_gatts_uuid_format_convert(&esp_srvc_id.id.uuid,gatts_attr_db[i].att_desc.length,
299                                               gatts_attr_db[i].att_desc.value);
300                 btc_to_bta_srvc_id(&srvc_id, &esp_srvc_id);
301                 if (btc_creat_tab_env.is_use_svc != true) {
302                     BTA_GATTS_CreateService(gatts_if, &srvc_id.id.uuid,
303                                             srvc_inst_id, max_nb_attr, false);
304                     btc_creat_tab_env.is_use_svc = true;
305                 } else {
306                     BTC_TRACE_ERROR("Each service table can only created one secondary service.");
307                     param.add_attr_tab.status = ESP_GATT_ERROR;
308                     btc_gatts_cb_to_app(ESP_GATTS_CREAT_ATTR_TAB_EVT, gatts_if, &param);
309                     //reset the env after sent the data to app
310                     memset(&btc_creat_tab_env, 0, sizeof(esp_btc_creat_tab_t));
311                     return;
312                 }
313                 if (future_await(future_p) == FUTURE_FAIL) {
314                         BTC_TRACE_ERROR("%s failed\n", __func__);
315                         return;
316                         }
317                 break;
318             }
319             case ESP_GATT_UUID_INCLUDE_SERVICE:{
320                 esp_gatts_incl_svc_desc_t *incl_svc_desc = (esp_gatts_incl_svc_desc_t *)gatts_attr_db[i].att_desc.value;
321 
322                 if(incl_svc_desc!= NULL){
323                     if(btc_creat_tab_env.svc_start_hdl != 0){
324                         BTA_GATTS_AddIncludeService(btc_creat_tab_env.svc_start_hdl,
325                             incl_svc_desc->start_hdl);
326 
327                         if (future_await(future_p) == FUTURE_FAIL) {
328                                 BTC_TRACE_ERROR("%s failed\n", __func__);
329                                 return;
330                             }
331                     }
332                 }
333                 break;
334             }
335             case ESP_GATT_UUID_CHAR_DECLARE:{
336                 uint16_t svc_hal = 0;
337                 tBT_UUID bta_char_uuid;
338                 tGATT_ATTR_VAL attr_val;
339                 esp_bt_uuid_t uuid_temp;
340                 tBTA_GATT_PERM perm;
341                 tBTA_GATTS_ATTR_CONTROL control;
342                 uint8_t char_property;
343 
344                 if(btc_creat_tab_env.svc_start_hdl != 0){
345                     svc_hal = btc_creat_tab_env.svc_start_hdl;
346                     if((gatts_attr_db[i].att_desc.value) == NULL){
347                         BTC_TRACE_ERROR("%s Characteristic declaration should not be NULL\n", __func__);
348                     }
349                     else{
350                         char_property = (uint8_t)(*(uint8_t*)(gatts_attr_db[i].att_desc.value));
351                         perm = gatts_attr_db[i+1].att_desc.perm;
352                         attr_val.attr_len = gatts_attr_db[i+1].att_desc.length;
353                         attr_val.attr_max_len = gatts_attr_db[i+1].att_desc.max_length;
354                         btc_gatts_uuid_format_convert(&uuid_temp, gatts_attr_db[i+1].att_desc.uuid_length,gatts_attr_db[i+1].att_desc.uuid_p);
355                         btc_to_bta_uuid(&bta_char_uuid, &uuid_temp);
356                         attr_val.attr_val = gatts_attr_db[i+1].att_desc.value;
357                         control.auto_rsp = gatts_attr_db[i+1].attr_control.auto_rsp;
358                         BTA_GATTS_AddCharacteristic (svc_hal, &bta_char_uuid,
359                                          perm, char_property, &attr_val, &control);
360 
361                         if (future_await(future_p) == FUTURE_FAIL) {
362                                 BTC_TRACE_ERROR("%s failed\n", __func__);
363                                 return;
364                                 }
365                     }
366                 }
367 
368                 break;
369             }
370             case ESP_GATT_UUID_CHAR_EXT_PROP:
371             case ESP_GATT_UUID_CHAR_DESCRIPTION:
372             case ESP_GATT_UUID_CHAR_CLIENT_CONFIG:
373             case ESP_GATT_UUID_CHAR_SRVR_CONFIG:
374             case ESP_GATT_UUID_CHAR_PRESENT_FORMAT:
375             case ESP_GATT_UUID_CHAR_AGG_FORMAT:
376             case ESP_GATT_UUID_CHAR_VALID_RANGE:
377             case ESP_GATT_UUID_EXT_RPT_REF_DESCR:
378             case ESP_GATT_UUID_RPT_REF_DESCR:
379             case ESP_GATT_UUID_NUM_DIGITALS_DESCR:
380             case ESP_GATT_UUID_VALUE_TRIGGER_DESCR:
381             case ESP_GATT_UUID_ENV_SENSING_CONFIG_DESCR:
382             case ESP_GATT_UUID_ENV_SENSING_MEASUREMENT_DESCR:
383             case ESP_GATT_UUID_ENV_SENSING_TRIGGER_DESCR:
384             case ESP_GATT_UUID_TIME_TRIGGER_DESCR: {
385                 uint16_t svc_hal = btc_creat_tab_env.svc_start_hdl;
386                 tBT_UUID bta_char_uuid;
387                 esp_bt_uuid_t uuid_temp;
388                 tGATT_ATTR_VAL attr_val;
389                 tBTA_GATT_PERM perm = gatts_attr_db[i].att_desc.perm;
390                 tBTA_GATTS_ATTR_CONTROL control;
391 
392                 if(svc_hal != 0){
393                     attr_val.attr_len = gatts_attr_db[i].att_desc.length;
394                     attr_val.attr_max_len = gatts_attr_db[i].att_desc.max_length;
395                     attr_val.attr_val = gatts_attr_db[i].att_desc.value;
396                     btc_gatts_uuid_format_convert(&uuid_temp, gatts_attr_db[i].att_desc.uuid_length,
397                                                   gatts_attr_db[i].att_desc.uuid_p);
398                     btc_to_bta_uuid(&bta_char_uuid, &uuid_temp);
399                     control.auto_rsp = gatts_attr_db[i].attr_control.auto_rsp;
400                     BTA_GATTS_AddCharDescriptor(svc_hal, perm, &bta_char_uuid, &attr_val, &control);
401 
402                     if (future_await(future_p) == FUTURE_FAIL) {
403                         BTC_TRACE_ERROR("%s failed\n", __func__);
404                         return;
405                         }
406                 }
407                 break;
408             }
409             default:
410                 future_free(future_p);
411                 break;
412         }
413 
414 
415     }
416 
417     param.add_attr_tab.handles = btc_creat_tab_env.handles;
418     memcpy(&param.add_attr_tab.svc_uuid, &btc_creat_tab_env.svc_uuid, sizeof(esp_bt_uuid_t));
419 
420     param.add_attr_tab.svc_inst_id = srvc_inst_id;
421 
422     btc_gatts_cb_to_app(ESP_GATTS_CREAT_ATTR_TAB_EVT, gatts_if, &param);
423     //reset the env after sent the data to app
424     memset(&btc_creat_tab_env, 0, sizeof(esp_btc_creat_tab_t));
425 
426     //set the flag value to false after the service is created.
427     btc_creat_tab_env.is_tab_creat_svc = false;
428 }
429 
btc_gatts_check_valid_attr_tab(esp_gatts_attr_db_t * gatts_attr_db,uint8_t max_nb_attr)430 static esp_gatt_status_t btc_gatts_check_valid_attr_tab(esp_gatts_attr_db_t *gatts_attr_db,
431                                                                           uint8_t max_nb_attr)
432 {
433     uint8_t svc_num = 0;
434     uint16_t uuid = 0;
435 
436     for(int i = 0; i < max_nb_attr; i++) {
437         if(gatts_attr_db[i].att_desc.uuid_length != ESP_UUID_LEN_16) {
438             continue;
439         }
440 
441         uuid = (gatts_attr_db[i].att_desc.uuid_p[1] << 8) + (gatts_attr_db[i].att_desc.uuid_p[0]);
442         switch(uuid) {
443             case ESP_GATT_UUID_PRI_SERVICE:
444             case ESP_GATT_UUID_SEC_SERVICE:
445                 if (++svc_num > 1) {
446                     BTC_TRACE_ERROR("Each service table can only created one primary service or secondary service.");
447                     return ESP_GATT_ERROR;
448                 }
449                 break;
450             case ESP_GATT_UUID_INCLUDE_SERVICE: {
451                 esp_gatts_incl_svc_desc_t *svc_desc = (esp_gatts_incl_svc_desc_t *)gatts_attr_db[i].att_desc.value;
452                 if(svc_desc == NULL) {
453                     BTC_TRACE_ERROR("%s, The include service attribute should not be NULL.", __func__);
454                     return ESP_GATT_INVALID_PDU;
455                 } else if((svc_desc->start_hdl == 0) || (svc_desc->end_hdl == 0) ||
456                           (svc_desc->start_hdl == svc_desc->end_hdl)) {
457                     BTC_TRACE_ERROR("%s, The include service attribute handle is invalid, start_hanlde = %d, end_handle = %d",\
458                               __func__, svc_desc->start_hdl, svc_desc->end_hdl);
459                     return ESP_GATT_INVALID_HANDLE;
460                 }
461                 break;
462             }
463             case ESP_GATT_UUID_CHAR_DECLARE:
464                 if((gatts_attr_db[i].att_desc.value) == NULL) {
465                     BTC_TRACE_ERROR("%s, Characteristic declaration should not be NULL.", __func__);
466                     return ESP_GATT_INVALID_PDU;
467                 }
468 
469                 if(gatts_attr_db[i+1].att_desc.uuid_length != ESP_UUID_LEN_16 &&
470                    gatts_attr_db[i+1].att_desc.uuid_length != ESP_UUID_LEN_32 &&
471                    gatts_attr_db[i+1].att_desc.uuid_length != ESP_UUID_LEN_128) {
472                     BTC_TRACE_ERROR("%s, The Characteristic uuid length = %d is invalid", __func__,\
473                         gatts_attr_db[i+1].att_desc.uuid_length);
474                     return ESP_GATT_INVALID_ATTR_LEN;
475                 }
476 
477                 if(gatts_attr_db[i+1].att_desc.uuid_length == ESP_UUID_LEN_16) {
478                     uuid = (gatts_attr_db[i+1].att_desc.uuid_p[1] << 8) + (gatts_attr_db[i+1].att_desc.uuid_p[0]);
479                     if(uuid == ESP_GATT_UUID_CHAR_DECLARE || uuid == ESP_GATT_UUID_CHAR_EXT_PROP ||
480                         uuid == ESP_GATT_UUID_CHAR_DESCRIPTION || uuid == ESP_GATT_UUID_CHAR_CLIENT_CONFIG ||
481                         uuid == ESP_GATT_UUID_CHAR_SRVR_CONFIG || uuid == ESP_GATT_UUID_CHAR_PRESENT_FORMAT ||
482                         uuid == ESP_GATT_UUID_CHAR_AGG_FORMAT || uuid == ESP_GATT_UUID_CHAR_VALID_RANGE ||
483                         uuid == ESP_GATT_UUID_EXT_RPT_REF_DESCR || uuid == ESP_GATT_UUID_RPT_REF_DESCR) {
484                         BTC_TRACE_ERROR("%s, The characteristic value uuid = %d is invalid", __func__, uuid);
485                         return ESP_GATT_INVALID_PDU;
486                     }
487                 }
488                 break;
489             default:
490                 break;
491         }
492     }
493 
494     return ESP_GATT_OK;
495 }
496 
btc_gatts_get_attr_value(uint16_t attr_handle,uint16_t * length,uint8_t ** value)497 esp_gatt_status_t btc_gatts_get_attr_value(uint16_t attr_handle, uint16_t *length, uint8_t **value)
498 {
499 
500      return BTA_GetAttributeValue(attr_handle, length, value);
501 }
502 
btc_gatts_show_local_database(void)503 esp_gatt_status_t btc_gatts_show_local_database(void)
504 {
505     BTA_GATTS_ShowLocalDatabase();
506     return ESP_GATT_OK;
507 }
508 
btc_gatts_cb_param_copy_req(btc_msg_t * msg,void * p_dest,void * p_src)509 static void btc_gatts_cb_param_copy_req(btc_msg_t *msg, void *p_dest, void *p_src)
510 {
511     uint16_t event = msg->act;
512 
513     tBTA_GATTS *p_dest_data = (tBTA_GATTS *) p_dest;
514     tBTA_GATTS *p_src_data = (tBTA_GATTS *) p_src;
515 
516     if (!p_src_data || !p_dest_data) {
517         return;
518     }
519 
520     // Copy basic structure first
521     memcpy(p_dest_data, p_src_data, sizeof(tBTA_GATTS));
522 
523     // Allocate buffer for request data if necessary
524     switch (event) {
525     case BTA_GATTS_READ_EVT:
526     case BTA_GATTS_WRITE_EVT:
527     case BTA_GATTS_EXEC_WRITE_EVT:
528     case BTA_GATTS_MTU_EVT:
529         p_dest_data->req_data.p_data = osi_malloc(sizeof(tBTA_GATTS_REQ_DATA));
530         if (p_dest_data->req_data.p_data != NULL) {
531             memcpy(p_dest_data->req_data.p_data, p_src_data->req_data.p_data,
532                    sizeof(tBTA_GATTS_REQ_DATA));
533         } else {
534             BTC_TRACE_ERROR("%s %d no mem\n", __func__, msg->act);
535         }
536         break;
537 
538     default:
539         break;
540     }
541 }
542 
btc_gatts_cb_param_copy_free(btc_msg_t * msg)543 static void btc_gatts_cb_param_copy_free(btc_msg_t *msg)
544 {
545     uint16_t event = msg->act;
546     tBTA_GATTS *p_data = (tBTA_GATTS *)msg->arg;
547 
548     switch (event) {
549     case BTA_GATTS_READ_EVT:
550     case BTA_GATTS_WRITE_EVT:
551     case BTA_GATTS_EXEC_WRITE_EVT:
552     case BTA_GATTS_MTU_EVT:
553         if (p_data && p_data->req_data.p_data) {
554             osi_free(p_data->req_data.p_data);
555         }
556         break;
557     case BTA_GATTS_CONF_EVT:
558         break;
559     default:
560         break;
561     }
562 }
563 
564 
btc_gatts_inter_cb(tBTA_GATTS_EVT event,tBTA_GATTS * p_data)565 static void btc_gatts_inter_cb(tBTA_GATTS_EVT event, tBTA_GATTS *p_data)
566 {
567     bt_status_t status;
568     btc_msg_t msg = {0};
569 
570     msg.sig = BTC_SIG_API_CB;
571     msg.pid = BTC_PID_GATTS;
572     msg.act = event;
573     if(btc_creat_tab_env.is_tab_creat_svc && btc_creat_tab_env.complete_future) {
574         switch(event) {
575             case BTA_GATTS_CREATE_EVT: {
576                 //save the service handle to the btc module after used
577                 //the attribute table method to creat a service
578                 bta_to_btc_uuid(&btc_creat_tab_env.svc_uuid, &p_data->create.uuid);
579                 uint16_t index = btc_creat_tab_env.handle_idx;
580                 btc_creat_tab_env.svc_start_hdl = p_data->create.service_id;
581                 btc_creat_tab_env.handles[index] = p_data->create.service_id;
582                 break;
583             }
584             case BTA_GATTS_ADD_INCL_SRVC_EVT: {
585                 uint16_t index = btc_creat_tab_env.handle_idx;
586                 btc_creat_tab_env.handles[index] = p_data->add_result.attr_id;
587                 break;
588             }
589             case BTA_GATTS_ADD_CHAR_EVT: {
590                 uint16_t index = btc_creat_tab_env.handle_idx;
591                 btc_creat_tab_env.handles[index] = p_data->add_result.attr_id - 1;
592                 btc_creat_tab_env.handles[index+1] = p_data->add_result.attr_id;
593                 break;
594             }
595             case BTA_GATTS_ADD_CHAR_DESCR_EVT: {
596                 uint16_t index = btc_creat_tab_env.handle_idx;
597                 btc_creat_tab_env.handles[index] = p_data->add_result.attr_id;
598                 break;
599             }
600             default:
601                 break;
602         }
603 
604         future_ready(btc_creat_tab_env.complete_future, FUTURE_SUCCESS);
605         return;
606     }
607     status = btc_transfer_context(&msg, p_data, sizeof(tBTA_GATTS),
608                                     btc_gatts_cb_param_copy_req, btc_gatts_cb_param_copy_free);
609 
610     if (status != BT_STATUS_SUCCESS) {
611         BTC_TRACE_ERROR("%s btc_transfer_context failed\n", __func__);
612     }
613 }
614 
btc_gatts_call_handler(btc_msg_t * msg)615 void btc_gatts_call_handler(btc_msg_t *msg)
616 {
617     btc_ble_gatts_args_t *arg = (btc_ble_gatts_args_t *)msg->arg;
618 
619     switch (msg->act) {
620     case BTC_GATTS_ACT_APP_REGISTER: {
621         tBT_UUID uuid;
622 
623         uuid.len = LEN_UUID_16;
624         uuid.uu.uuid16 = arg->app_reg.app_id;
625 
626         BTA_GATTS_AppRegister(&uuid, btc_gatts_inter_cb);
627 
628         break;
629     }
630     case BTC_GATTS_ACT_APP_UNREGISTER:
631         BTA_GATTS_AppDeregister(arg->app_unreg.gatts_if);
632         break;
633     case BTC_GATTS_ACT_CREATE_SERVICE: {
634         tBTA_GATT_SRVC_ID srvc_id;
635         btc_to_bta_srvc_id(&srvc_id, &arg->create_srvc.service_id);
636         BTA_GATTS_CreateService(arg->create_srvc.gatts_if, &srvc_id.id.uuid,
637                                 srvc_id.id.inst_id, arg->create_srvc.num_handle,
638                                 srvc_id.is_primary);
639         break;
640     }
641    case BTC_GATTS_ACT_CREATE_ATTR_TAB:
642     btc_gatts_act_create_attr_tab(arg->create_attr_tab.gatts_attr_db,
643                                          arg->create_attr_tab.gatts_if,
644                                          arg->create_attr_tab.max_nb_attr,
645                                          arg->create_attr_tab.srvc_inst_id);
646     break;
647     case BTC_GATTS_ACT_DELETE_SERVICE:
648         BTA_GATTS_DeleteService(arg->delete_srvc.service_handle);
649         break;
650     case BTC_GATTS_ACT_START_SERVICE:
651         BTA_GATTS_StartService(arg->start_srvc.service_handle, BTA_GATT_TRANSPORT_LE);
652         break;
653     case BTC_GATTS_ACT_STOP_SERVICE:
654         BTA_GATTS_StopService(arg->stop_srvc.service_handle);
655         break;
656     case BTC_GATTS_ACT_ADD_INCLUDE_SERVICE:
657         BTA_GATTS_AddIncludeService(arg->add_incl_srvc.service_handle, arg->add_incl_srvc.included_service_handle);
658         break;
659     case BTC_GATTS_ACT_ADD_CHAR: {
660         tBT_UUID uuid;
661         btc_to_bta_uuid(&uuid, &arg->add_char.char_uuid);
662 
663         BTA_GATTS_AddCharacteristic(arg->add_char.service_handle, &uuid,
664                                     arg->add_char.perm, arg->add_char.property,
665                                     (tGATT_ATTR_VAL *)&arg->add_char.char_val,
666                                     (tBTA_GATTS_ATTR_CONTROL *)&arg->add_char.attr_control);
667         break;
668     }
669     case BTC_GATTS_ACT_ADD_CHAR_DESCR: {
670         tBT_UUID uuid;
671         btc_to_bta_uuid(&uuid, &arg->add_descr.descr_uuid);
672         BTA_GATTS_AddCharDescriptor(arg->add_descr.service_handle, arg->add_descr.perm, &uuid,
673                                    (tBTA_GATT_ATTR_VAL *)&arg->add_descr.descr_val,
674                                    (tBTA_GATTS_ATTR_CONTROL *)&arg->add_descr.attr_control);
675         break;
676     }
677     case BTC_GATTS_ACT_SEND_INDICATE:
678         BTA_GATTS_HandleValueIndication(arg->send_ind.conn_id, arg->send_ind.attr_handle,
679                                         arg->send_ind.value_len, arg->send_ind.value, arg->send_ind.need_confirm);
680         break;
681     case BTC_GATTS_ACT_SEND_RESPONSE: {
682         esp_ble_gatts_cb_param_t param;
683         esp_gatt_rsp_t *p_rsp = arg->send_rsp.rsp;
684 
685         if (p_rsp) {
686             tBTA_GATTS_RSP rsp_struct;
687             btc_to_bta_response(&rsp_struct, p_rsp);
688             BTA_GATTS_SendRsp(arg->send_rsp.conn_id, arg->send_rsp.trans_id,
689                               arg->send_rsp.status, &rsp_struct);
690             param.rsp.handle = rsp_struct.attr_value.handle;
691         } else {
692             BTA_GATTS_SendRsp(arg->send_rsp.conn_id, arg->send_rsp.trans_id,
693                               arg->send_rsp.status, NULL);
694         }
695 
696         param.rsp.status = 0;
697         param.rsp.conn_id = BTC_GATT_GET_CONN_ID(arg->send_rsp.conn_id);
698         btc_gatts_cb_to_app(ESP_GATTS_RESPONSE_EVT, BTC_GATT_GET_GATT_IF(arg->send_rsp.conn_id), &param);
699         break;
700     }
701     case BTC_GATTS_ACT_SET_ATTR_VALUE:
702         BTA_SetAttributeValue(arg->set_attr_val.handle, arg->set_attr_val.length,
703                               arg->set_attr_val.value);
704     break;
705     case BTC_GATTS_ACT_OPEN: {
706         // Ensure device is in inquiry database
707         tBTA_GATT_TRANSPORT transport = BTA_GATT_TRANSPORT_LE;
708 
709         //TODO : implement address type and device type
710 #if  0
711         if (_get_address_type(arg->remote_bda, &addr_type) &&
712                 btif_get_device_type(arg->remote_bda, &device_type) &&
713                 device_type != BT_DEVICE_TYPE_BREDR) {
714             BTA_DmAddBleDevice(p_cb->bd_addr.address, addr_type, device_type);
715         }
716 #else
717         //BTA_DmAddBleDevice(p_cb->bd_addr.address, addr_type, device_type);
718 #endif
719         /*
720          not support background connection
721         // Mark background connections
722         if (!arg->open.is_direct) {
723             BTA_DmBleSetBgConnType(BTM_BLE_CONN_AUTO, NULL);
724         }
725         */
726 
727         transport = BTA_GATT_TRANSPORT_LE;
728 
729         // Connect!
730         BTA_GATTS_Open(arg->open.gatts_if, arg->open.remote_bda,
731                        arg->open.is_direct, transport);
732         break;
733     }
734     case BTC_GATTS_ACT_CLOSE:
735         // TODO : implement cancel open
736         // Cancel pending foreground/background connections
737         //BTA_GATTS_CancelOpen(p_cb->server_if, p_cb->bd_addr.address, TRUE);
738         //BTA_GATTS_CancelOpen(p_cb->server_if, p_cb->bd_addr.address, FALSE);
739 
740         // Close active connection
741         if (arg->close.conn_id != 0) {
742             BTA_GATTS_Close(arg->close.conn_id);
743         }
744 
745         break;
746     case BTC_GATTS_ACT_SEND_SERVICE_CHANGE: {
747         BD_ADDR remote_bda;
748         memcpy(remote_bda, arg->send_service_change.remote_bda, BD_ADDR_LEN);
749         BTA_GATTS_SendServiceChangeIndication(arg->send_service_change.gatts_if, remote_bda);
750         break;
751     }
752     case BTC_GATTS_ACT_SHOW_LOCAL_DATABASE:
753         BTA_GATTS_ShowLocalDatabase();
754         break;
755     default:
756         break;
757     }
758     btc_gatts_arg_deep_free(msg);
759 }
760 
btc_gatts_cb_handler(btc_msg_t * msg)761 void btc_gatts_cb_handler(btc_msg_t *msg)
762 {
763     esp_ble_gatts_cb_param_t param;
764     tBTA_GATTS *p_data = (tBTA_GATTS *)msg->arg;
765     esp_gatt_if_t gatts_if;
766 
767     switch (msg->act) {
768     case BTA_GATTS_REG_EVT: {
769         gatts_if = p_data->reg_oper.server_if;
770         param.reg.status = p_data->reg_oper.status;
771         param.reg.app_id = p_data->reg_oper.uuid.uu.uuid16;
772 
773         btc_gatts_cb_to_app(ESP_GATTS_REG_EVT, gatts_if, &param);
774         break;
775     }
776     case BTA_GATTS_DEREG_EVT: {
777         gatts_if = p_data->reg_oper.server_if;
778         btc_gatts_cb_to_app(ESP_GATTS_UNREG_EVT, gatts_if, NULL);
779         break;
780     }
781     case BTA_GATTS_READ_EVT: {
782         gatts_if = BTC_GATT_GET_GATT_IF(p_data->req_data.conn_id);
783         param.read.conn_id = BTC_GATT_GET_CONN_ID(p_data->req_data.conn_id);
784         param.read.trans_id = p_data->req_data.trans_id;
785         memcpy(param.read.bda, p_data->req_data.remote_bda, ESP_BD_ADDR_LEN);
786         param.read.handle = p_data->req_data.p_data->read_req.handle;
787         param.read.offset = p_data->req_data.p_data->read_req.offset;
788         param.read.is_long = p_data->req_data.p_data->read_req.is_long;
789 
790         param.read.need_rsp = p_data->req_data.p_data->read_req.need_rsp;
791         btc_gatts_cb_to_app(ESP_GATTS_READ_EVT, gatts_if, &param);
792         break;
793     }
794     case BTA_GATTS_WRITE_EVT: {
795         gatts_if = BTC_GATT_GET_GATT_IF(p_data->req_data.conn_id);
796         param.write.conn_id = BTC_GATT_GET_CONN_ID(p_data->req_data.conn_id);
797         param.write.trans_id = p_data->req_data.trans_id;
798         memcpy(param.write.bda, p_data->req_data.remote_bda, ESP_BD_ADDR_LEN);
799         if (p_data->req_data.p_data == NULL) {
800             break;
801         }
802         param.write.handle = p_data->req_data.p_data->write_req.handle;
803         param.write.offset = p_data->req_data.p_data->write_req.offset;
804         param.write.need_rsp = p_data->req_data.p_data->write_req.need_rsp;
805         param.write.is_prep = p_data->req_data.p_data->write_req.is_prep;
806         param.write.len = p_data->req_data.p_data->write_req.len;
807         param.write.value = p_data->req_data.p_data->write_req.value;
808 
809         btc_gatts_cb_to_app(ESP_GATTS_WRITE_EVT, gatts_if, &param);
810 
811         break;
812     }
813     case BTA_GATTS_EXEC_WRITE_EVT: {
814         gatts_if = BTC_GATT_GET_GATT_IF(p_data->req_data.conn_id);
815         param.exec_write.conn_id = BTC_GATT_GET_CONN_ID(p_data->req_data.conn_id);
816         param.exec_write.trans_id = p_data->req_data.trans_id;
817         memcpy(param.exec_write.bda, p_data->req_data.remote_bda, ESP_BD_ADDR_LEN);
818         if (p_data->req_data.p_data == NULL) {
819             break;
820         }
821         param.exec_write.exec_write_flag = p_data->req_data.p_data->exec_write;
822 
823         btc_gatts_cb_to_app(ESP_GATTS_EXEC_WRITE_EVT, gatts_if, &param);
824         break;
825     }
826     case BTA_GATTS_MTU_EVT:
827         gatts_if = BTC_GATT_GET_GATT_IF(p_data->req_data.conn_id);
828         param.mtu.conn_id = BTC_GATT_GET_CONN_ID(p_data->req_data.conn_id);
829         param.mtu.mtu = p_data->req_data.p_data->mtu;
830 
831         btc_gatts_cb_to_app(ESP_GATTS_MTU_EVT, gatts_if, &param);
832         break;
833     case BTA_GATTS_CONF_EVT:
834         gatts_if = BTC_GATT_GET_GATT_IF(p_data->req_data.conn_id);
835         param.conf.conn_id = BTC_GATT_GET_CONN_ID(p_data->req_data.conn_id);
836         param.conf.status = p_data->req_data.status;
837         param.conf.handle = p_data->req_data.handle;
838 
839         if (p_data->req_data.status != ESP_GATT_OK && p_data->req_data.value){
840             param.conf.len = p_data->req_data.data_len;
841             param.conf.value = p_data->req_data.value;
842         }else{
843             param.conf.len = 0;
844         }
845         btc_gatts_cb_to_app(ESP_GATTS_CONF_EVT, gatts_if, &param);
846         break;
847     case BTA_GATTS_CREATE_EVT:
848         gatts_if = p_data->create.server_if;
849         param.create.status = p_data->create.status;
850         param.create.service_handle = p_data->create.service_id;
851         param.create.service_id.is_primary = p_data->create.is_primary;
852         param.create.service_id.id.inst_id = p_data->create.svc_instance;
853         bta_to_btc_uuid(&param.create.service_id.id.uuid, &p_data->create.uuid);
854 
855         btc_gatts_cb_to_app(ESP_GATTS_CREATE_EVT, gatts_if, &param);
856         break;
857     case BTA_GATTS_ADD_INCL_SRVC_EVT:
858         gatts_if = p_data->add_result.server_if;
859         param.add_incl_srvc.status = p_data->add_result.status;
860         param.add_incl_srvc.attr_handle = p_data->add_result.attr_id;
861         param.add_incl_srvc.service_handle = p_data->add_result.service_id;
862 
863         btc_gatts_cb_to_app(ESP_GATTS_ADD_INCL_SRVC_EVT, gatts_if, &param);
864         break;
865     case BTA_GATTS_ADD_CHAR_EVT:
866         gatts_if = p_data->add_result.server_if;
867         param.add_char.status = p_data->add_result.status;
868         param.add_char.attr_handle = p_data->add_result.attr_id;
869         param.add_char.service_handle = p_data->add_result.service_id;
870         bta_to_btc_uuid(&param.add_char.char_uuid, &p_data->add_result.char_uuid);
871 
872         btc_gatts_cb_to_app(ESP_GATTS_ADD_CHAR_EVT, gatts_if, &param);
873         break;
874     case BTA_GATTS_ADD_CHAR_DESCR_EVT:
875         gatts_if = p_data->add_result.server_if;
876         param.add_char_descr.status = p_data->add_result.status;
877         param.add_char_descr.attr_handle = p_data->add_result.attr_id;
878         param.add_char_descr.service_handle = p_data->add_result.service_id;
879         bta_to_btc_uuid(&param.add_char_descr.descr_uuid, &p_data->add_result.char_uuid);
880 
881         btc_gatts_cb_to_app(ESP_GATTS_ADD_CHAR_DESCR_EVT, gatts_if, &param);
882         break;
883     case BTA_GATTS_DELELTE_EVT:
884         gatts_if = p_data->srvc_oper.server_if;
885         param.del.status = p_data->srvc_oper.status;
886         param.del.service_handle = p_data->srvc_oper.service_id;
887 
888         btc_gatts_cb_to_app(ESP_GATTS_DELETE_EVT, gatts_if, &param);
889         break;
890     case BTA_GATTS_START_EVT:
891         gatts_if = p_data->srvc_oper.server_if;
892         param.start.status = p_data->srvc_oper.status;
893         param.start.service_handle = p_data->srvc_oper.service_id;
894 
895         btc_gatts_cb_to_app(ESP_GATTS_START_EVT, gatts_if, &param);
896         break;
897     case BTA_GATTS_STOP_EVT:
898         gatts_if = p_data->srvc_oper.server_if;
899         param.stop.status = p_data->srvc_oper.status;
900         param.stop.service_handle = p_data->srvc_oper.service_id;
901 
902         btc_gatts_cb_to_app(ESP_GATTS_STOP_EVT, gatts_if, &param);
903         break;
904     case BTA_GATTS_CONNECT_EVT: {
905 #if (SMP_INCLUDED == TRUE)
906         bt_bdaddr_t bt_addr;
907         memcpy(bt_addr.address, p_data->conn.remote_bda, sizeof(bt_addr.address));
908         if (btc_storage_update_active_device(&bt_addr)) {
909             BTC_TRACE_EVENT("Device: %02x:%02x:%02x:%02x:%02x:%02x, is not in bond list",
910                             bt_addr.address[0], bt_addr.address[1],
911                             bt_addr.address[2], bt_addr.address[3],
912                             bt_addr.address[4], bt_addr.address[5]);
913         }
914 #endif  ///SMP_INCLUDED == TRUE
915         gatts_if = p_data->conn.server_if;
916         param.connect.conn_id = BTC_GATT_GET_CONN_ID(p_data->conn.conn_id);
917         param.connect.link_role = p_data->conn.link_role;
918         memcpy(param.connect.remote_bda, p_data->conn.remote_bda, ESP_BD_ADDR_LEN);
919         param.connect.conn_params.interval = p_data->conn.conn_params.interval;
920         param.connect.conn_params.latency = p_data->conn.conn_params.latency;
921         param.connect.conn_params.timeout = p_data->conn.conn_params.timeout;
922         param.connect.ble_addr_type = p_data->conn.ble_addr_type;
923         param.connect.conn_handle = p_data->conn.conn_handle;
924         btc_gatts_cb_to_app(ESP_GATTS_CONNECT_EVT, gatts_if, &param);
925         break;
926     }
927     case BTA_GATTS_DISCONNECT_EVT:
928         gatts_if = p_data->conn.server_if;
929         param.disconnect.conn_id = BTC_GATT_GET_CONN_ID(p_data->conn.conn_id);
930         param.disconnect.reason = p_data->conn.reason;
931         memcpy(param.disconnect.remote_bda, p_data->conn.remote_bda, ESP_BD_ADDR_LEN);
932 
933         btc_gatts_cb_to_app(ESP_GATTS_DISCONNECT_EVT, gatts_if, &param);
934         break;
935     case BTA_GATTS_OPEN_EVT:
936         gatts_if = p_data->open.server_if;
937         param.open.status = p_data->open.status;
938 
939         btc_gatts_cb_to_app(BTA_GATTS_OPEN_EVT, gatts_if, &param);
940         break;
941     case BTA_GATTS_CANCEL_OPEN_EVT:
942         gatts_if = p_data->cancel_open.server_if;
943         param.cancel_open.status = p_data->cancel_open.status;
944 
945         btc_gatts_cb_to_app(BTA_GATTS_CANCEL_OPEN_EVT, gatts_if, &param);
946         break;
947 
948     case BTA_GATTS_CLOSE_EVT:
949         gatts_if = BTC_GATT_GET_GATT_IF(p_data->close.conn_id);
950         param.close.status = p_data->close.status;
951         param.close.conn_id = BTC_GATT_GET_CONN_ID(p_data->close.conn_id);
952 
953         btc_gatts_cb_to_app(BTA_GATTS_CLOSE_EVT, gatts_if, &param);
954         break;
955     case BTA_GATTS_SEND_SERVICE_CHANGE_EVT:
956         gatts_if = p_data->service_change.server_if;
957         param.service_change.status = p_data->service_change.status;
958         btc_gatts_cb_to_app(ESP_GATTS_SEND_SERVICE_CHANGE_EVT, gatts_if, &param);
959         break;
960     case BTA_GATTS_LISTEN_EVT:
961         // do nothing
962         break;
963     case BTA_GATTS_CONGEST_EVT:
964         gatts_if = BTC_GATT_GET_GATT_IF(p_data->congest.conn_id);
965         param.congest.conn_id = BTC_GATT_GET_CONN_ID(p_data->congest.conn_id);
966         param.congest.congested = p_data->congest.congested;
967         btc_gatts_cb_to_app(ESP_GATTS_CONGEST_EVT, gatts_if, &param);
968         break;
969     case BTA_GATTS_SET_ATTR_VAL_EVT:
970         gatts_if = p_data->attr_val.server_if;
971         param.set_attr_val.srvc_handle = p_data->attr_val.service_id;
972         param.set_attr_val.attr_handle = p_data->attr_val.attr_id;
973         param.set_attr_val.status = p_data->attr_val.status;
974         btc_gatts_cb_to_app(ESP_GATTS_SET_ATTR_VAL_EVT, gatts_if, &param);
975         break;
976     default:
977         // do nothing
978         break;
979     }
980 
981     btc_gatts_cb_param_copy_free(msg);
982 }
983 
btc_congest_callback(tBTA_GATTS * param)984 void btc_congest_callback(tBTA_GATTS *param)
985 {
986     esp_ble_gatts_cb_param_t esp_param;
987     esp_gatt_if_t gatts_if = BTC_GATT_GET_GATT_IF(param->congest.conn_id);
988     esp_param.congest.conn_id = BTC_GATT_GET_CONN_ID(param->congest.conn_id);
989     esp_param.congest.congested = param->congest.congested;
990     btc_gatts_cb_to_app(ESP_GATTS_CONGEST_EVT, gatts_if, &esp_param);
991 }
992 
993 #endif  ///GATTS_INCLUDED
994