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