• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021 Chipsea Technologies (Shenzhen) Corp., Ltd. All rights reserved.
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 #ifndef _HAL_ATTM_H
16 #define _HAL_ATTM_H
17 
18 #include "ble_ip_config.h"
19 #include <string.h>
20 #include <stdbool.h>
21 
22 #include "hal_att.h"
23 #include "ble_ke_task.h"
24 
25 /// update attribute permission on specific handle
26 #define ATTMDB_UPDATE_PERM(handle, access, right)\
27     attm_att_update_perm(handle, (PERM_MASK_ ## access), PERM(access, right))
28 
29 #define ATTMDB_UPDATE_PERM_VAL(handle, access, val)\
30     attm_att_update_perm(handle, (PERM_MASK_ ## access), ((val) << (PERM_POS_ ## access)))
31 
32 
33 
34 /*
35  * DATA STRUCTURES
36  ****************************************************************************************
37  */
38 
39 /// Internal 16bits UUID service description
40 struct attm_desc
41 {
42     /// 16 bits UUID LSB First
43     uint16_t uuid;
44     /// Attribute Permissions (@see enum attm_perm_mask)
45     uint16_t perm;
46     /// Attribute Extended Permissions (@see enum attm_value_perm_mask)
47     uint16_t ext_perm;
48     /// Attribute Max Size
49     /// note: for characteristic declaration contains handle offset
50     /// note: for included service, contains target service handle
51     uint16_t max_size;
52 };
53 
54 
55 /// Internal 128bits UUID service description
56 struct attm_desc_128
57 {
58     /// 128 bits UUID LSB First
59     uint8_t uuid[ATT_UUID_128_LEN];
60     /// Attribute Permissions (@see enum attm_perm_mask)
61     uint16_t perm;
62     /// Attribute Extended Permissions (@see enum attm_value_perm_mask)
63     uint16_t ext_perm;
64     /// Attribute Max Size
65     /// note: for characteristic declaration contains handle offset
66     /// note: for included service, contains target service handle
67     uint16_t max_size;
68 };
69 
70 
71 
72 #if (BLE_CENTRAL || BLE_PERIPHERAL)
73 /*
74  * GLOBAL VARIABLE DECLARATIONS
75  ****************************************************************************************
76  */
77 
78 /*
79  * FUNCTION DECLARATIONS
80  ****************************************************************************************
81  */
82 
83 
84 /**
85  ****************************************************************************************
86  * @brief Compare if two UUIDs matches
87  *
88  * @param[in]  uuid_a      UUID A value
89  * @param[in]  uuid_a_len  UUID A length
90  * @param[in]  uuid_b      UUID B value
91  * @param[in]  uuid_b_len  UUID B length
92  *
93  * @return true if UUIDs matches, false otherwise
94  ****************************************************************************************
95  */
96 bool attm_uuid_comp(uint8_t *uuid_a, uint8_t uuid_a_len,
97                       uint8_t *uuid_b, uint8_t uuid_b_len);
98 
99 
100 /**
101  ****************************************************************************************
102  * @brief Check if two UUIDs matches (2nd UUID is a 16 bits UUID with LSB First)
103  *
104  * @param[in]  uuid_a      UUID A value
105  * @param[in]  uuid_a_len  UUID A length
106  * @param[in]  uuid_b      UUID B 16 bit value
107  *
108  * @return true if UUIDs matches, false otherwise
109  ****************************************************************************************
110  */
111 bool attm_uuid16_comp(uint8_t *uuid_a, uint8_t uuid_a_len, uint16_t uuid_b);
112 
113 
114 /**
115  ****************************************************************************************
116  * @brief Convert UUID value to 128 bit UUID
117  *
118  * @param[out] uuid128   converted 32-bit Bluetooth UUID to 128-bit UUID
119  * @param[in]  uuid      UUID to convert to 128-bit UUID
120  * @param[in]  uuid_len  UUID length
121  *
122  ****************************************************************************************
123  */
124 void attm_convert_to128(uint8_t *uuid128, uint8_t *uuid, uint8_t uuid_len);
125 
126 /**
127  ****************************************************************************************
128  * @brief Check if it's a Bluetooth 16-bits UUID for 128-bit input
129  *
130  * @param[in]  uuid      128-bit UUID
131  *
132  * @return true if uuid  is a Bluetooth 16-bit UUID, false else.
133  ****************************************************************************************
134  */
135 bool attm_is_bt16_uuid(uint8_t *uuid);
136 
137 /**
138  ****************************************************************************************
139  * @brief Check if it's a Bluetooth 32 bits UUID for 128-bit input
140  *
141  * @param[in]  uuid      128-bit UUID
142  *
143  * @return true if uuid  is a Bluetooth 32-bits UUID, false else.
144  ****************************************************************************************
145  */
146 bool attm_is_bt32_uuid(uint8_t *uuid);
147 
148 
149 #if (BLE_ATTS)
150 /**
151  ****************************************************************************************
152  * @brief Function use to ease service database creation.
153  * Use @see attmdb_add_service function of attmdb module to create service database,
154  * then use @see attmdb_add_attribute function of attmdb module to create attributes
155  * according to database description array given in parameter.
156  *
157  * @note: database description array shall be const to reduce memory consumption (only ROM)
158  * @note: It supports only 16 bits UUIDs
159  *
160  * @note: If shdl = 0, it return handle using first available handle (shdl is
161  * modified); else it verifies if start handle given can be used to allocates handle range.
162  *
163  * @param[in|out] shdl          Service start handle.
164  * @param[in]     uuid          Service UUID
165  * @param[in|out] cfg_flag      Configuration Flag, each bit matches with an attribute of
166  *                              att_db (Max: 32 attributes); if the bit is set to 1, the
167  *                              attribute will be added in the service.
168  * @param[in]     max_nb_att    Number of attributes in the service
169  * @param[in|out] att_tbl       Array which will be fulfilled with the difference between
170  *                              each characteristic handle and the service start handle.
171  *                              This array is useful if several characteristics are optional
172  *                              within the service, can be set to NULL if not needed.
173  * @param[in]     dest_id       Task ID linked to the service. This task will be notified
174  *                              each time the service content is modified by a peer device.
175  * @param[in|out] att_db        Table containing all attributes information
176  * @param[in]     svc_perm      Service permission (@see enum attm_svc_perm_mask)
177  *
178  * @return Command status code:
179  *  - @ref ATT_ERR_NO_ERROR: If database creation succeeds.
180  *  - @ref ATT_ERR_INVALID_HANDLE: If start_hdl given in parameter + nb of attribute override
181  *                            some existing services handles.
182  *  - @ref ATT_ERR_INSUFF_RESOURCE: There is not enough memory to allocate service buffer.
183  *                           or of new attribute cannot be added because all expected
184  *                           attributes already added or buffer overflow detected during
185  *                           allocation
186  ****************************************************************************************
187  */
188 uint8_t attm_svc_create_db(uint16_t *shdl, uint16_t uuid, uint8_t *cfg_flag, uint8_t max_nb_att,
189                            uint8_t *att_tbl, ke_task_id_t const dest_id,
190                            const struct attm_desc *att_db, uint8_t svc_perm);
191 
192 
193 /**
194  ****************************************************************************************
195  * @brief Function use to ease service database creation.
196  * Use @see attmdb_add_service function of attmdb module to create service database,
197  * then use @see attmdb_add_attribute function of attmdb module to create attributes
198  * according to database description array given in parameter.
199  *
200  * @note: database description array shall be const to reduce memory consumption (only ROM)
201  * @note: It supports 128, 32 and 16 bits UUIDs
202  *
203  * @note: If shdl = 0, it return handle using first available handle (shdl is
204  * modified); else it verifies if start handle given can be used to allocates handle range.
205  *
206  * @param[in|out] shdl          Service start handle.
207  * @param[in]     uuid          Service UUID
208  * @param[in|out] cfg_flag      Configuration Flag, each bit matches with an attribute of
209  *                              att_db (Max: 32 attributes); if the bit is set to 1, the
210  *                              attribute will be added in the service.
211  * @param[in]     max_nb_att    Number of attributes in the service
212  * @param[in|out] att_tbl       Array which will be fulfilled with the difference between
213  *                              each characteristic handle and the service start handle.
214  *                              This array is useful if several characteristics are optional
215  *                              within the service, can be set to NULL if not needed.
216  * @param[in]     dest_id       Task ID linked to the service. This task will be notified
217  *                              each time the service content is modified by a peer device.
218  * @param[in|out] att_db        Table containing all attributes information
219  * @param[in]     svc_perm      Service permission (@see enum attm_svc_perm_mask)
220  *
221  * @return Command status code:
222  *  - @ref ATT_ERR_NO_ERROR: If database creation succeeds.
223  *  - @ref ATT_ERR_INVALID_HANDLE: If start_hdl given in parameter + nb of attribute override
224  *                            some existing services handles.
225  *  - @ref ATT_ERR_INSUFF_RESOURCE: There is not enough memory to allocate service buffer.
226  *                           or of new attribute cannot be added because all expected
227  *                           attributes already added or buffer overflow detected during
228  *                           allocation
229  ****************************************************************************************
230  */
231 uint8_t attm_svc_create_db_128(uint16_t *shdl, const uint8_t* uuid, uint8_t *cfg_flag, uint8_t max_nb_att,
232                                uint8_t *att_tbl, ke_task_id_t const dest_id,
233                                const struct attm_desc_128 *att_db, uint8_t svc_perm);
234 
235 /**
236  ****************************************************************************************
237  * @brief Control visibility of a service from peer device. service present in database
238  *        but cannot be access by a peer device.
239  *
240  * @param[in] handle Service handle.
241  * @param[in] hide   True to hide the service, False to restore visibility
242  *
243  * @return Command status code:
244  *  - @ref ATT_ERR_NO_ERROR: If service allocation succeeds.
245  *  - @ref ATT_ERR_INVALID_HANDLE: If start_hdl given in parameter or UUIDs value invalid
246  ****************************************************************************************
247  */
248 uint8_t attmdb_svc_visibility_set(uint16_t handle, bool hide);
249 
250 /**
251  ****************************************************************************************
252  * @brief Function use to verify if several services can be allocated on a contiguous
253  * handle range. If this command succeed, it means that service allocation will succeed.
254  *
255  * If start_hdl = 0, it return handle using first available handle (start_hdl is
256  * modified); else it verifies if start handle given can be used to allocates handle range.
257  *
258  * @param[in|out] start_hdl     Service start handle.
259  * @param[in]     nb_att        Number of handle to allocate (containing service handles)
260  *
261  * @return Command status code:
262  *  - @ref ATT_ERR_NO_ERROR: If service allocation succeeds.
263  *  - @ref ATT_ERR_INVALID_HANDLE: If start_hdl given in parameter or UUIDs value invalid
264  ****************************************************************************************
265  */
266 uint8_t attm_reserve_handle_range(uint16_t* start_hdl, uint8_t nb_att);
267 
268 
269 
270 /**
271  ****************************************************************************************
272  * @brief Update attribute value
273  *
274  * Updating attribute value do not trigger any notification or indication, this shall be
275  * handled by GATT task.
276  *
277  * @param[in] handle Attribute handle.
278  * @param[in] length Size of new attribute value
279  * @param[in] offset Data offset of in the payload to set
280  * @param[in] value  Attribute value payload
281  *
282  * @return Command status code:
283  *  - @ref ATT_ERR_NO_ERROR: If attribute value update succeeds
284  *  - @ref ATT_ERR_INVALID_HANDLE: If handle doesn't exist in database
285  *  - @ref ATT_ERR_REQUEST_NOT_SUPPORTED: If attribute data not present in database or
286  *                                        cannot be modified
287  *  - @ref ATT_ERR_INVALID_ATTRIBUTE_VAL_LEN: If new value length exceeds maximum attribute
288  *                              value length.
289  *
290  ****************************************************************************************
291  */
292 uint8_t attm_att_set_value(uint16_t handle, att_size_t length, att_size_t offset, uint8_t* value);
293 
294 /**
295  ****************************************************************************************
296  * @brief Retrieve attribute value
297 
298  *
299  * @param[in]  handle Attribute handle.
300  * @param[out] length Size of attribute value
301  * @param[out] value  Pointer to attribute value payload
302  *
303  * @return Command status code:
304  *  - @ref ATT_ERR_NO_ERROR: If request succeeds
305  *  - @ref ATT_ERR_INVALID_HANDLE: If handle doesn't exist in database
306  *  - @ref ATT_ERR_REQUEST_NOT_SUPPORTED: If attribute data not present in database
307  ****************************************************************************************
308  */
309 uint8_t attm_get_value(uint16_t handle, att_size_t* length, uint8_t** value);
310 
311 
312 /**
313  ****************************************************************************************
314  * @brief Update attribute permission
315  *
316  * @param[in] handle Attribute handle.
317  *  - @ref ATT_ERR_REQUEST_NOT_SUPPORTED: If attribute data not present in database
318  * @param[in] perm       New attribute permission
319  * @param[in] ext_perm   New attribute extended permission
320  *
321  * @return Command status code:
322  *  - @ref ATT_ERR_NO_ERROR: If request succeeds
323  *  - @ref ATT_ERR_INVALID_HANDLE: If handle doesn't exist in database
324  *  - @ref ATT_ERR_REQUEST_NOT_SUPPORTED: If attribute permission is fixed
325  ****************************************************************************************
326  */
327 uint8_t attm_att_set_permission(uint16_t handle, uint16_t perm, uint16_t ext_perm);
328 
329 
330 /**
331  ****************************************************************************************
332  * @brief Reset some permissions bit in the Handle passed as parameter.
333  *
334  * @param[in] handle      Attribute handle.
335  * @param[in] access_mask Access mask of permission to update
336  * @param[in] perm        New value of the permission to update
337  *
338  *
339  * @return Command status code:
340  *  - @ref ATT_ERR_NO_ERROR: If request succeeds
341  *  - @ref ATT_ERR_INVALID_HANDLE: If handle doesn't exist in database
342  *  - @ref ATT_ERR_REQUEST_NOT_SUPPORTED: If attribute permission is fixed
343  ****************************************************************************************
344  */
345 uint8_t attm_att_update_perm(uint16_t handle, uint16_t access_mask, uint16_t perm);
346 
347 /**
348  ****************************************************************************************
349  * @brief Update attribute service permission
350  *
351  * @param[in] handle Attribute handle.
352  * @param[in] perm   New attribute permission
353  *
354  * @return Command status code:
355  *  - @ref ATT_ERR_NO_ERROR: If request succeeds
356  *  - @ref ATT_ERR_INVALID_HANDLE: If handle doesn't exist in database
357  ****************************************************************************************
358  */
359 uint8_t attm_svc_set_permission(uint16_t handle, uint8_t perm);
360 
361 
362 /**
363  ****************************************************************************************
364  * @brief Retrieve attribute service permission
365  *
366  * @param[in]  handle Attribute handle.
367  * @param[out] perm   Permission value to return
368  *
369  * @return Command status code:
370  *  - @ref ATT_ERR_NO_ERROR: If request succeeds
371  *  - @ref ATT_ERR_INVALID_HANDLE: If handle doesn't exist in database
372  ****************************************************************************************
373  */
374 uint8_t attm_svc_get_permission(uint16_t handle, uint8_t* perm);
375 
376 
377 /**
378  ****************************************************************************************
379  * @brief Clear database
380  *
381  * For debug purpose only, this function clear the database and unalloc all services
382  * within database.
383  *
384  * This function shall be used only for qualification and tests in order to manually
385  * change database without modifying software.
386  ****************************************************************************************
387  */
388 void attmdb_destroy(void);
389 
390 /**
391  ****************************************************************************************
392  * @brief Initialize Attribute Database (clear it)
393  *
394  * @param[in] init_type  Type of initialization (@see enum rwip_init_type)
395  ****************************************************************************************
396  */
397 void attm_init(uint8_t init_type);
398 #endif // (BLE_ATTS)
399 
400 #endif // #if (BLE_CENTRAL || BLE_PERIPHERAL)
401 
402 #endif // _HAL_ATTM_H
403