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