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