1 #ifndef ATTM_DB_H_
2 #define ATTM_DB_H_
3 
4 /**
5  ****************************************************************************************
6  * @addtogroup ATTDB Database
7  * @ingroup ATTM
8  * @brief Attribute Protocol Database
9  *
10  * The ATTDB module is responsible for providing different sets of attribute databases
11  * for Attribute Profile server.
12  *
13  * This module can be tailored by client, to match the requirement of the desired database.
14  *
15  * @{
16  *
17  ****************************************************************************************
18  */
19 
20 /*
21  * INCLUDE FILES
22  ****************************************************************************************
23  */
24 #include "rwip_config.h"
25 #if (BLE_ATTS)
26 #include <string.h>
27 #include "rwip_config.h"
28 #include "ke_task.h"
29 #include "attm.h"
30 #include "gattm_task.h"
31 
32 /*
33  * DEFINES
34  ****************************************************************************************
35  */
36 
37 
38 /*
39  * TYPE DEFINITION
40  ****************************************************************************************
41  */
42 #if(BLE_ATTS)
43 
44 /**
45  * Attribute Description
46  */
47 struct attm_att_desc
48 {
49     /**
50      * 16 bits UUID or data offset used to retrieve 32 or 128 bits UUID in service memory block
51      */
52     uint16_t uuid;
53 
54     /**
55      *  Attribute Permission (@see attm_perm_mask)
56      */
57     uint16_t perm;
58 
59     /**
60      * value information (@see attm_value_perm_mask)
61      */
62     union att_info
63     {
64         /// attribute max length (RI = 1)
65         uint16_t max_length;
66 
67         /// attribute value offset pointer (RI = 0)
68         uint16_t offset;
69     } info;
70 };
71 
72 /// attribute value if present in database
73 struct attm_att_value
74 {
75     /// Maximum attribute length
76     uint16_t max_length;
77     /// currrent attribute length that can be read.
78     uint16_t length;
79     ///value data pointer
80     uint8_t  value[__ARRAY_EMPTY];
81 };
82 
83 /// service description
84 struct attm_svc_desc
85 {
86     /// Service Start Handle
87     uint16_t start_hdl;
88     /// Service End Handle
89     uint16_t end_hdl;
90     /// Task identifier that manages service
91     uint16_t task_id;
92 
93     /**
94      * Service Permission (@see attm_svc_perm_mask)
95      */
96     uint8_t perm;
97 
98     /// number of attributes present in service (end_hdl - start_hdl - 1)
99     uint8_t nb_att;
100 
101     /// Service 16 bits UUID (LSB First) or data offset used to retrieve 32 or 128 bits
102     /// UUID in service memory block
103     uint16_t uuid;
104 };
105 
106 /**
107  * Service description present in attribute database
108  */
109 struct attm_svc
110 {
111     /// Next Service
112     struct attm_svc* next;
113 
114     /// service description
115     struct attm_svc_desc svc;
116 
117     /**
118      * List of attribute description present in service.
119      */
120     struct attm_att_desc atts[__ARRAY_EMPTY];
121 };
122 
123 /// Attribute element information
124 struct attm_elmt
125 {
126     /// element info
127     union elem_info
128     {
129         /// attribute info pointer
130         struct attm_att_desc* att;
131 
132         /// service info pointer
133         struct attm_svc_desc* svc;
134     } info;
135 
136     /// use to know if current element is a service or an attribute
137     bool service;
138 };
139 
140 /// ATTM General Information Manager
141 struct attm_db
142 {
143     /**
144      * **************************************************************************************
145      * @brief Attribute database
146      *
147      * The Attribute database is a list of attribute services sorted by handle number.
148      * This database shall be initiate by GAP, GATT, profiles and application process at
149      * startup and must not change during runtime.
150      *
151      * Database initialization shall be deterministic in order to always have service handle
152      * at same position in database during all product life-cycle. This is required since
153      * database client can save position of services in database to not perform service
154      * discovery at each connection.
155      ***************************************************************************************
156      */
157     struct attm_svc * svcs;
158 
159     /**
160      ***************************************************************************************
161      * Last attribute service searched.
162      *
163      * Used as a cached variable, it's used to reduce handle search duration.
164      ***************************************************************************************
165      */
166     struct attm_svc * cache;
167 
168     /**
169      * Temporary value used for read operation on service and characteristics attributes
170      */
171     uint8_t  temp_val[ATT_UUID_128_LEN + ATT_HANDLE_LEN + ATT_HANDLE_LEN];
172 };
173 
174 
175 
176 
177 
178 #endif //(BLE_ATTS)
179 
180 /*
181  * FUNCTION DECLARATIONS
182  ****************************************************************************************
183  */
184 
185 /**
186  * Check if Service handle Range can be allocated in Database, and if handle should be
187  * dynamically allocated, calculate first available handle range.
188  *
189  * @param[in|out] svc_desc Service information to add in DB
190  *
191  * @return status of operation
192  */
193 uint8_t attmdb_svc_check_hdl(struct gattm_svc_desc* svc_desc);
194 
195 /**
196  ****************************************************************************************
197  * @brief Add a service in database.
198  *
199  * According to service start handle and number of attribute, ATTM DB allocate a set of
200  * attribute handles, then using other parameters it allocate a buffer used to describe
201  * service, and allocate attributes + their values.
202  *
203  * If start_hdl = 0, it allocated service using first available handle (start_hdl is
204  * modified); else it will allocate service according to given start handle.
205  *
206  *
207  * @param[in|out] svc_desc Service description.
208  *
209  * @return Command status code:
210  *  - @ref ATT_ERR_NO_ERROR: If service allocation succeeds.
211  *  - @ref ATT_ERR_INVALID_HANDLE: If start_hdl given in parameter or UUIDs value invalid
212  *  - @ref ATT_ERR_INSUFF_RESOURCE: There is not enough memory to allocate service buffer.
213  ****************************************************************************************
214  */
215 uint8_t attmdb_add_service(struct gattm_svc_desc* svc_desc);
216 
217 uint8_t attmdb_delete_service(struct attm_svc* svc_desc);
218 
219 /**
220  ****************************************************************************************
221  *  @brief Search in database from which service attribute handle comes from.
222  *
223  * @param[in] handle Attribute handle.
224  *
225  * @return Services that contains attribute handle; NULL if handle not available in
226  *         database.
227  ****************************************************************************************
228  */
229 struct attm_svc * attmdb_get_service(uint16_t handle);
230 
231 /**
232  ****************************************************************************************
233  *  @brief Search in database Attribute pointer using attribute handle.
234  *
235  * @param[in]  handle   Attribute handle.
236  * @param[out] elmt     Attribute element to fill
237  *
238  * @return Command status code:
239  *  - @ref ATT_ERR_NO_ERROR: If attribute found.
240  *  - @ref ATT_ERR_INVALID_HANDLE: If No Attribute found
241  ****************************************************************************************
242  */
243 uint8_t attmdb_get_attribute(uint16_t handle, struct attm_elmt*elmt);
244 
245 /**
246  ****************************************************************************************
247  * @brief Retrieve attribute at or after specified handle
248  *
249  * Retrieve first attribute with handle >= parameter handle.
250  * Parameter handle is updated according found attribute.
251  *
252  * @param[in|out] handle   Attribute handle.
253  * @param[out]    elmt     Attribute element to fill
254  *
255  * @return Command status code:
256  *  - @ref ATT_ERR_NO_ERROR: If attribute found.
257  *  - @ref ATT_ERR_INVALID_HANDLE: If No Attribute found
258  ****************************************************************************************
259  */
260 uint8_t attmdb_get_next_att(uint16_t * handle, struct attm_elmt*elmt);
261 
262 /**
263  ****************************************************************************************
264  * Check if attribute element UUID is equals to uuid given in parameter.
265  *
266  * @param elmt     Attribute element that can be a UUID 16 or 128 bits
267  * @param uuid16   UUID 16 bits to compare
268  *
269  * @return True if UUIDs matches, False else.
270  ****************************************************************************************
271  */
272 bool attmdb_uuid16_comp(struct attm_elmt *elmt, uint16_t uuid16);
273 
274 /**
275  ****************************************************************************************
276  * @brief Retrieve attribute value Max Length
277  *
278  * @param[in]  elmt    Attribute element information
279  * @param[out] length  Max length Size of attribute value
280  *
281  * @return Command status code:
282  *  - @ref ATT_ERR_NO_ERROR: If request succeeds
283  *  - @ref ATT_ERR_REQUEST_NOT_SUPPORTED: If attribute is read only
284  ****************************************************************************************
285  */
286 uint8_t attmdb_get_max_len(struct attm_elmt* elmt, att_size_t* length);
287 
288 
289 /**
290  ****************************************************************************************
291  * @brief Retrieve attribute UUID
292  *
293  * @param[in]  elmt     Attribute information.
294  * @param[out] uuid_len Size of attribute UUID
295  * @param[out] uuid     UUID value to update
296  * @param[in]  srv_uuid For a service, if set, return service UUID
297  * @param[in]  air      Prepare UUID for the air (For a 32 bit UUID, returns a 128 bit UUID)
298  *
299  * @return Command status code:
300  *  - @ref ATT_ERR_NO_ERROR: If request succeeds
301  *  - @ref ATT_ERR_INVALID_HANDLE: If handle doesn't exist in database
302  ****************************************************************************************
303  */
304 uint8_t attmdb_get_uuid(struct attm_elmt *elmt, uint8_t* uuid_len, uint8_t* uuid, bool srv_uuid, bool air);
305 
306 /**
307  ****************************************************************************************
308  * @brief Retrieve attribute permission
309  * If access mask is set, service authentication or encryption key size value can be loaded.
310  *
311  * @param[in]  handle      Attribute handle.
312  * @param[out] perm        Permission value to return
313  * @param[in]  mode_mask   Mode Access mask to check type of access
314  *                         parameter (0 return full attribute permission)
315  * @param[in]  perm_mask   Permission Access mask to check only specific permission
316  * @param[in|out] elmt     Attribute information
317  *
318  * @return Command status code:
319  *  - @ref ATT_ERR_NO_ERROR: If request succeeds
320  *  - @ref ATT_ERR_INVALID_HANDLE: If handle doesn't exist in database.
321  *  - @ref ATT_ERR_REQUEST_NOT_SUPPORTED: If mode is disabled.
322  *  - @ref ATT_ERR_INSUFF_AUTHOR: when service is disabled.
323  *  - @ref ATT_ERR_INSUFF_ENC_KEY_SIZE:
324  ****************************************************************************************
325  */
326 uint8_t attmdb_att_get_permission(uint16_t handle, uint16_t* perm, uint16_t mode_mask,
327                                   uint16_t perm_mask, struct attm_elmt *elmt);
328 
329 uint8_t attmdb_update_svc_uuid(uint16_t handle, uint16_t uuid);
330 
331 #if (RW_DEBUG)
332 
333 /**
334  ****************************************************************************************
335  * @brief Retrieve number of services.
336  *
337  * @return number of services
338  ****************************************************************************************
339  */
340 uint8_t attmdb_get_nb_svc(void);
341 
342 /**
343  ****************************************************************************************
344  * @brief Retrieve services informations
345  *
346  * @param[in] svc_info Services information array to update
347  ****************************************************************************************
348  */
349 void attmdb_get_svc_info(struct gattm_svc_info* svc_info);
350 #endif /* (RW_DEBUG) */
351 
352 #endif // #if (BLE_ATTS)
353 
354 /// @} ATTDB
355 #endif // ATTM_DB_H_
356