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, ¶m);
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, ¶m);
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, ¶m);
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, ¶m);
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(¶m.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, ¶m);
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), ¶m);
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, ¶m);
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, ¶m);
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, ¶m);
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, ¶m);
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, ¶m);
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, ¶m);
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(¶m.create.service_id.id.uuid, &p_data->create.uuid);
854
855 btc_gatts_cb_to_app(ESP_GATTS_CREATE_EVT, gatts_if, ¶m);
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, ¶m);
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(¶m.add_char.char_uuid, &p_data->add_result.char_uuid);
871
872 btc_gatts_cb_to_app(ESP_GATTS_ADD_CHAR_EVT, gatts_if, ¶m);
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(¶m.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, ¶m);
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, ¶m);
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, ¶m);
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, ¶m);
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, ¶m);
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, ¶m);
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, ¶m);
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, ¶m);
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, ¶m);
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, ¶m);
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, ¶m);
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, ¶m);
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