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