1 /*
2  * Copyright (C) 2017 C-SKY Microsystems Co., Ltd. All rights reserved.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *   http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #ifndef __GATT_H__
18 #define __GATT_H__
19 
20 #include <aos/uuid.h>
21 #include <ble_config.h>
22 
23 #define ARRAY_SIZES(array) (sizeof(array)/sizeof(array[0]))
24 
25 #ifdef __cplusplus
26 extern "C" {
27 #endif
28 
29 typedef enum {
30     CCC_VALUE_NONE     = 0,
31     CCC_VALUE_NOTIFY   = 1,
32     CCC_VALUE_INDICATE = 2
33 } ccc_value_en;
34 
35 /* GATT attribute permission bit field values */
36 typedef enum {
37     /** No operations supported, e.g. for notify-only */
38     GATT_PERM_NONE = 0,
39 
40     /** Attribute read permission. */
41     GATT_PERM_READ = BLE_BIT(0),
42 
43     /** Attribute write permission. */
44     GATT_PERM_WRITE = BLE_BIT(1),
45 
46     /** Attribute read permission with encryption.
47      *
48      *  If set, requires encryption for read access.
49      */
50     GATT_PERM_READ_ENCRYPT = BLE_BIT(2),
51 
52     /** Attribute write permission with encryption.
53      *
54      *  If set, requires encryption for write access.
55      */
56     GATT_PERM_WRITE_ENCRYPT = BLE_BIT(3),
57 
58     /** Attribute read permission with authentication.
59      *
60      *  If set, requires encryption using authenticated link-key for read
61      *  access.
62      */
63     GATT_PERM_READ_AUTHEN = BLE_BIT(4),
64 
65     /** Attribute write permission with authentication.
66      *
67      *  If set, requires encryption using authenticated link-key for write
68      *  access.
69      */
70     GATT_PERM_WRITE_AUTHEN = BLE_BIT(5),
71 
72     /** Attribute prepare write permission.
73      *
74      *  If set, allows prepare writes with use of GATT_WRITE_FLAG_PREPARE
75      *  passed to write callback.
76      */
77     GATT_PERM_PREPARE_WRITE = BLE_BIT(6),
78 } gatt_perm_en;
79 
80 
81 /* Characteristic Properties Bit field values */
82 typedef enum {
83     /** @def BT_GATT_CHRC_BROADCAST
84      *  @brief Characteristic broadcast property.
85      *
86      *  If set, permits broadcasts of the Characteristic Value using Server
87      *  Characteristic Configuration Descriptor.
88      */
89     GATT_CHRC_PROP_BROADCAST =  BLE_BIT(0),
90     /** @def BT_GATT_CHRC_READ
91      *  @brief Characteristic read property.
92      *
93      *  If set, permits reads of the Characteristic Value.
94      */
95     GATT_CHRC_PROP_READ =   BLE_BIT(1),
96     /** @def BT_GATT_CHRC_WRITE_WITHOUT_RESP
97      *  @brief Characteristic write without response property.
98      *
99      *  If set, permits write of the Characteristic Value without response.
100      */
101     GATT_CHRC_PROP_WRITE_WITHOUT_RESP = BLE_BIT(2),
102     /** @def BT_GATT_CHRC_WRITE
103      *  @brief Characteristic write with response property.
104      *
105      *  If set, permits write of the Characteristic Value with response.
106      */
107     GATT_CHRC_PROP_WRITE =  BLE_BIT(3),
108     /** @def BT_GATT_CHRC_NOTIFY
109      *  @brief Characteristic notify property.
110      *
111      *  If set, permits notifications of a Characteristic Value without
112      *  acknowledgment.
113      */
114     GATT_CHRC_PROP_NOTIFY =     BLE_BIT(4),
115     /** @def BT_GATT_CHRC_INDICATE
116      *  @brief Characteristic indicate property.
117      *
118      * If set, permits indications of a Characteristic Value with acknowledgment.
119      */
120     GATT_CHRC_PROP_INDICATE =   BLE_BIT(5),
121     /** @def BT_GATT_CHRC_AUTH
122      *  @brief Characteristic Authenticated Signed Writes property.
123      *
124      *  If set, permits signed writes to the Characteristic Value.
125      */
126     GATT_CHRC_PROP_AUTH =   BLE_BIT(6),
127     /** @def BT_GATT_CHRC_EXT_PROP
128      *  @brief Characteristic Extended Properties property.
129      *
130      * If set, additional characteristic properties are defined in the
131      * Characteristic Extended Properties Descriptor.
132      */
133     GATT_CHRC_PROP_EXT_PROP =   BLE_BIT(7),
134 } gatt_prop_en;
135 
136 /* Error codes for Error response PDU */
137 #define ATT_ERR_INVALID_HANDLE          0x01
138 #define ATT_ERR_READ_NOT_PERMITTED      0x02
139 #define ATT_ERR_WRITE_NOT_PERMITTED     0x03
140 #define ATT_ERR_INVALID_PDU             0x04
141 #define ATT_ERR_AUTHENTICATION          0x05
142 #define ATT_ERR_NOT_SUPPORTED           0x06
143 #define ATT_ERR_INVALID_OFFSET          0x07
144 #define ATT_ERR_AUTHORIZATION           0x08
145 #define ATT_ERR_PREPARE_QUEUE_FULL      0x09
146 #define ATT_ERR_ATTRIBUTE_NOT_FOUND     0x0a
147 #define ATT_ERR_ATTRIBUTE_NOT_LONG      0x0b
148 #define ATT_ERR_ENCRYPTION_KEY_SIZE     0x0c
149 #define ATT_ERR_INVALID_ATTRIBUTE_LEN   0x0d
150 #define ATT_ERR_UNLIKELY                0x0e
151 #define ATT_ERR_INSUFFICIENT_ENCRYPTION 0x0f
152 #define ATT_ERR_UNSUPPORTED_GROUP_TYPE  0x10
153 #define ATT_ERR_INSUFFICIENT_RESOURCES  0x11
154 
155 typedef int (*char_read_func_t)(uint16_t conn_handle, uint16_t char_handle, void *buf, uint16_t len, uint16_t offset);
156 typedef int (*char_write_func_t)(uint16_t conn_handle, uint16_t char_handle, void *buf, uint16_t len, uint16_t offset);
157 typedef void (*char_ccc_change_func_t)(ccc_value_en value);
158 
159 struct gatt_char_t {
160 
161     /** Characteristic UUID. */
162     const uuid_t    *uuid;
163     /** Characteristic Value handle. */
164 	uint16_t			value_handle;
165     /** Characteristic properties. */
166     uint8_t         properties;
167 };
168 
169 typedef struct _gatt_cep_t {
170     uint16_t  ext_props;
171 } gatt_cep_t;
172 
173 typedef struct _gatt_cud_t {
174     char *user_des; /* User Description */
175 } gatt_cud_t;
176 
177 typedef struct _gatt_cpf_t {
178     /** Format of the value of the characteristic */
179     uint8_t format;
180     /** Exponent field to determine how the value of this characteristic is further formatted */
181     int8_t exponent;
182     /** Unit of the characteristic */
183     uint16_t unit;
184     /** Name space of the description */
185     uint8_t name_space;
186     /** Description of the characteristic as defined in a higher layer profile */
187     uint16_t description;
188 } gatt_cpf_t;
189 
190 #if 0
191 typedef struct _gatt_att_t {
192     uuid_t *uuid;
193 
194     uint8_t perm;  /* for Characteristic Value Declaration*/
195 
196     union {
197         void *value;
198         gatt_char_t *char_def;
199         gatt_cep_t *cep;
200         gatt_cud_t *cud;
201         gatt_cpf_t *cpf;
202     };
203 
204     char_read_func_t read;
205 
206     char_write_func_t write;
207 
208 } gatt_att_t;
209 #endif
210 
211 
212 typedef struct _gatt_attr_t {
213     /** Attribute UUID */
214     uuid_t *uuid;
215 
216     char_read_func_t read;
217 
218     char_write_func_t write;
219 
220     /** Attribute user data */
221     void            *user_data;
222     /** Attribute handle */
223     uint16_t            handle;
224     /** Attribute permissions */
225     uint8_t         perm;
226 } gatt_attr_t;
227 
228 typedef struct {
229     uint8_t  val[6];
230 } bt_addr;
231 
232 typedef struct {
233     uint8_t      type;
234     bt_addr a;
235 } bt_addr_le;
236 
237 struct bt_gatt_ccc_cfg_t {
238     uint8_t                    id;
239     bt_addr_le      peer;
240     uint16_t            value;
241 };
242 
243 #define BT_RTL
244 struct bt_gatt_ccc_t {
245 #ifndef BT_RTL
246     struct bt_gatt_ccc_cfg_t    cfg[CONFIG_BT_MAX_PAIRED + CONFIG_BT_MAX_CONN];
247 #else
248     struct bt_gatt_ccc_cfg_t    cfg[2];
249 #endif
250     uint16_t            value;
251     void (*cfg_changed)(const gatt_attr_t *attr,  uint16_t value);
252     int (*cfg_write)(void *conn, gatt_attr_t *attr, uint16_t value);
253 	int (*cfg_match)(void *conn, gatt_attr_t *attr);
254 };
255 
256 #define GATT_ATT_DEFINE(_uuid, _perm, _read, _write,_value)     \
257     {                                   \
258         .uuid = _uuid,                          \
259                 .perm = _perm,                          \
260                         .read = _read,                          \
261                                 .write = _write,                        \
262         .user_data =(void *){ _value},                      \
263     }
264 #define GATT_PRIMARY_SERVICE_DEFINE(_uuid) \
265     GATT_ATT_DEFINE(UUID_GATT_PRIMARY, GATT_PERM_READ, NULL, NULL,_uuid)
266 
267 #define GATT_SECONDARY_SERVICE_DEFINE(_uuid) \
268     GATT_ATT_DEFINE(UUID_GATT_SECONDARY, GATT_PERM_READ, NULL, NULL, _uuid)
269 
270 #define GATT_CHAR_DEFINE(_uuid, _props) \
271     GATT_ATT_DEFINE(UUID_GATT_CHRC, GATT_PERM_READ,  \
272     NULL, NULL,(&(struct gatt_char_t){.uuid= _uuid,.value_handle = 0,.properties = _props,}))
273 
274 #define GATT_CHAR_VAL_DEFINE(_uuid, _perm) \
275     GATT_ATT_DEFINE(_uuid, _perm, NULL, NULL, NULL)
276 
277 #define GATT_CHAR_DESCRIPTOR_DEFINE(_uuid, _perm) \
278     GATT_ATT_DEFINE(_uuid, _perm, NULL, NULL, NULL)
279 
280 #define GATT_CHAR_CCC_DEFINE() \
281     GATT_ATT_DEFINE(UUID_GATT_CCC, GATT_PERM_READ | GATT_PERM_WRITE,  \
282     NULL, NULL,(&(struct bt_gatt_ccc_t){.cfg= {{0}}}))
283 
284 #define GATT_CHAR_CUD_DEFINE(_value, _perm) \
285     GATT_ATT_DEFINE(UUID_GATT_CUD, _perm, NULL, NULL,(&(gatt_cud_t) {.user_des = _value}))
286 
287 #define GATT_CHAR_CPF_DEFINE(_value, _perm) \
288     GATT_ATT_DEFINE(UUID_GATT_CPF, _perm, NULL, NULL,(&(gatt_cep_t) {.ext_props = _value}))
289 
290 
291 typedef enum {
292     GATT_SERVER_TYPE_PRIMARY = 0,
293     GATT_SERVER_TYPE_SECONDARY,
294     GATT_SERVER_TYPE_INCLUDE,
295 } gatt_service_type_en;
296 
297 typedef struct _gatt_service_param_t {
298     uuid_t *uuid;
299     gatt_service_type_en type;
300 } gatt_service_param;
301 
302 #if 0
303 typedef struct _gatt_char_param_t {
304     uuid_t *uuid;
305     void *value;
306     char_read_func_t read;
307     char_write_func_t write;
308     uint8_t props;
309     uint8_t perm;
310 } gatt_char_param;
311 
312 typedef struct _gatt_char_des_param_t {
313     uuid_t *uuid;
314     void *value;
315     char_read_func_t read;
316     char_write_func_t write;
317     uint8_t perm;
318 } gatt_char_des_param_t;
319 
320 #endif
321 
322 typedef enum {
323     GATT_FIND_PRIMARY_SERVICE,
324     GATT_FIND_INC_SERVICE,
325     GATT_FIND_CHAR,
326     GATT_FIND_CHAR_DESCRIPTOR,
327 } gatt_discovery_type_en;
328 
329 struct _snode_ {
330     struct _snode_ *next;
331 };
332 
333 typedef struct _snode_ sys_snode;
334 
335 /** @brief GATT Service structure */
336 typedef struct _gatt_service_ {
337     /** Service Attributes */
338     struct bt_gatt_attr *attrs;
339     /** Service Attribute count */
340     uint32_t            attr_count;
341     sys_snode       node;
342 } gatt_service;
343 
344 
345 int ble_stack_gatt_registe_service(gatt_service *s, gatt_attr_t attrs[], uint16_t attr_num);
346 
347 int ble_stack_gatt_notificate(int16_t conn_handle, uint16_t char_handle, const uint8_t *data, uint16_t len);
348 int ble_stack_gatt_indicate(int16_t conn_handle, int16_t char_handle, const uint8_t *data, uint16_t len);
349 int ble_stack_gatt_mtu_get(int16_t conn_handle);
350 int ble_stack_gatt_mtu_exchange(int16_t conn_handle);
351 
352 int ble_stack_gatt_service_discovery(int16_t conn_handle);
353 int ble_stack_gatt_discovery(int16_t conn_handle, gatt_discovery_type_en type, uuid_t *uuid, uint16_t start_handle, uint16_t end_handle);
354 #define ble_stack_gatt_discovery_all(conn_handle) \
355     ble_stack_gatt_discovery(conn_handle, GATT_FIND_PRIMARY_SERVICE, 0, 0x0001, 0xffff)
356 
357 #define ble_stack_gatt_discovery_primary(conn_handle, uuid, start_handle, end_handle) \
358     ble_stack_gatt_discovery(conn_handle, GATT_FIND_PRIMARY_SERVICE, uuid, start_handle, end_handle)
359 
360 #define ble_stack_gatt_discovery_include(conn_handle, uuid, start_handle, end_handle) \
361     ble_stack_gatt_discovery(conn_handle, GATT_FIND_INC_SERVICE, uuid, start_handle, end_handle)
362 
363 #define ble_stack_gatt_discovery_char_all(conn_handle, start_handle, end_handle) \
364     ble_stack_gatt_discovery(conn_handle, GATT_FIND_CHAR, 0, start_handle, end_handle)
365 
366 #define ble_stack_gatt_discovery_char(conn_handle, uuid, start_handle, end_handle) \
367     ble_stack_gatt_discovery(conn_handle, GATT_FIND_CHAR, uuid, start_handle, end_handle)
368 
369 #define ble_stack_gatt_discovery_descriptor(conn_handle, uuid,start_handle, end_handle) \
370     ble_stack_gatt_discovery(conn_handle, GATT_FIND_CHAR_DESCRIPTOR, uuid, start_handle, end_handle)
371 
372 #define ble_stack_gatt_discovery_descriptor_all(conn_handle, start_handle, end_handle) \
373     ble_stack_gatt_discovery(conn_handle, GATT_FIND_CHAR_DESCRIPTOR, 0, start_handle, end_handle)
374 
375 typedef enum {
376     GATT_WRITE,
377     GATT_WRITE_WITHOUT_RESPONSE,
378     GATT_WRITE_SINGED,
379 } gatt_write_en;
380 
381 int ble_stack_gatt_write(int16_t conn_handle, uint16_t attr_handle, uint8_t *data, uint16_t len, uint16_t offset, gatt_write_en type);
382 
383 #define ble_stack_gatt_write_response(conn_handle, attr_handle, data, len, offset) \
384     ble_stack_gatt_write(conn_handle, attr_handle, (uint8_t *)data, len, offset, GATT_WRITE)
385 
386 #define ble_stack_gatt_write_no_response(conn_handle, attr_handle, data, len, offset) \
387     ble_stack_gatt_write(conn_handle, attr_handle, (uint8_t *)data, len, offset, GATT_WRITE_WITHOUT_RESPONSE)
388 
389 #define ble_stack_gatt_write_signed(conn_handle, attr_handle, data, len, offset) \
390     ble_stack_gatt_write(conn_handle, attr_handle, (uint8_t *)data, len, offset, GATT_WRITE_SINGED)
391 
392 int ble_stack_gatt_read(int16_t conn_handle, uint16_t attr_handle, uint16_t offset);
393 int ble_stack_gatt_read_multiple(int16_t conn_handle, uint16_t attr_count, uint16_t attr_handle[]);
394 
395 #ifdef __cplusplus
396 }
397 #endif
398 
399 #endif  /* __BLE_H__ */
400 
401