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