Line data Source code
1 0 : /*
2 : * Copyright (c) 2019 Tobias Svehagen
3 : *
4 : * SPDX-License-Identifier: Apache-2.0
5 : */
6 : #ifndef ZEPHYR_INCLUDE_BLUETOOTH_MESH_CDB_H_
7 : #define ZEPHYR_INCLUDE_BLUETOOTH_MESH_CDB_H_
8 :
9 : #include <stdbool.h>
10 : #include <stdint.h>
11 :
12 : #include <zephyr/sys/atomic.h>
13 : #include <zephyr/bluetooth/mesh.h>
14 :
15 : #ifdef __cplusplus
16 : extern "C" {
17 : #endif
18 :
19 : #if defined(CONFIG_BT_MESH_CDB)
20 : #define NODE_COUNT CONFIG_BT_MESH_CDB_NODE_COUNT
21 : #define SUBNET_COUNT CONFIG_BT_MESH_CDB_SUBNET_COUNT
22 : #define APP_KEY_COUNT CONFIG_BT_MESH_CDB_APP_KEY_COUNT
23 : #else
24 0 : #define NODE_COUNT 0
25 0 : #define SUBNET_COUNT 0
26 0 : #define APP_KEY_COUNT 0
27 : #endif
28 :
29 0 : enum {
30 : BT_MESH_CDB_NODE_CONFIGURED,
31 :
32 : BT_MESH_CDB_NODE_FLAG_COUNT
33 : };
34 :
35 0 : struct bt_mesh_cdb_node {
36 0 : uint8_t uuid[16];
37 0 : uint16_t addr;
38 0 : uint16_t net_idx;
39 0 : uint8_t num_elem;
40 0 : struct bt_mesh_key dev_key;
41 :
42 0 : ATOMIC_DEFINE(flags, BT_MESH_CDB_NODE_FLAG_COUNT);
43 : };
44 :
45 0 : struct bt_mesh_cdb_subnet {
46 0 : uint16_t net_idx;
47 :
48 0 : uint8_t kr_phase;
49 :
50 : struct {
51 0 : struct bt_mesh_key net_key;
52 0 : } keys[2];
53 : };
54 :
55 0 : struct bt_mesh_cdb_app_key {
56 0 : uint16_t net_idx;
57 0 : uint16_t app_idx;
58 :
59 : struct {
60 0 : struct bt_mesh_key app_key;
61 0 : } keys[2];
62 : };
63 :
64 0 : enum {
65 : BT_MESH_CDB_VALID,
66 : BT_MESH_CDB_SUBNET_PENDING,
67 : BT_MESH_CDB_KEYS_PENDING,
68 : BT_MESH_CDB_NODES_PENDING,
69 : BT_MESH_CDB_IVU_IN_PROGRESS,
70 :
71 : BT_MESH_CDB_FLAG_COUNT,
72 : };
73 :
74 0 : struct bt_mesh_cdb {
75 0 : uint32_t iv_index;
76 0 : uint16_t lowest_avail_addr;
77 :
78 0 : ATOMIC_DEFINE(flags, BT_MESH_CDB_FLAG_COUNT);
79 :
80 0 : struct bt_mesh_cdb_node nodes[NODE_COUNT];
81 0 : struct bt_mesh_cdb_subnet subnets[SUBNET_COUNT];
82 0 : struct bt_mesh_cdb_app_key app_keys[APP_KEY_COUNT];
83 : };
84 :
85 0 : extern struct bt_mesh_cdb bt_mesh_cdb;
86 :
87 : /** @brief Create the Mesh Configuration Database.
88 : *
89 : * Create and initialize the Mesh Configuration Database. A primary subnet,
90 : * ie one with NetIdx 0, will be added and the provided key will be used as
91 : * NetKey for that subnet.
92 : *
93 : * @param key The NetKey to be used for the primary subnet.
94 : *
95 : * @return 0 on success or negative error code on failure.
96 : */
97 1 : int bt_mesh_cdb_create(const uint8_t key[16]);
98 :
99 : /** @brief Clear the Mesh Configuration Database.
100 : *
101 : * Remove all nodes, subnets and app-keys stored in the database and mark
102 : * the database as invalid. The data will be cleared from persistent storage
103 : * if CONFIG_BT_SETTINGS is enabled.
104 : */
105 1 : void bt_mesh_cdb_clear(void);
106 :
107 : /** @brief Set and store the IV Index and IV Update flag.
108 : *
109 : * The IV Index stored in the CDB will be the one used during provisioning
110 : * of new nodes. This function is generally only used from inside the stack.
111 : *
112 : * This function will store the data to persistent storage if
113 : * CONFIG_BT_SETTINGS is enabled.
114 : *
115 : * @param iv_index The new IV Index to use.
116 : * @param iv_update True if there is an ongoing IV Update procedure.
117 : */
118 1 : void bt_mesh_cdb_iv_update(uint32_t iv_index, bool iv_update);
119 :
120 : /** @brief Allocate a node.
121 : *
122 : * Allocate a new node in the CDB.
123 : *
124 : * If @c addr is 0, @ref bt_mesh_cdb_free_addr_get will be used to allocate
125 : * a free address.
126 : *
127 : * @param uuid UUID of the node.
128 : * @param addr Address of the node's primary element. If 0, the lowest
129 : * possible address available will be assigned to the node.
130 : * @param num_elem Number of elements that the node has.
131 : * @param net_idx NetIdx that the node was provisioned to.
132 : *
133 : * @return The new node or NULL if CDB has already allocated
134 : * :kconfig:option:`CONFIG_BT_MESH_CDB_NODE_COUNT` nodes, or reached the
135 : * end of the unicast address range, or if @c addr is non-zero and less
136 : * than the lowest available address or collide with the allocated addresses.
137 : */
138 1 : struct bt_mesh_cdb_node *bt_mesh_cdb_node_alloc(const uint8_t uuid[16], uint16_t addr,
139 : uint8_t num_elem, uint16_t net_idx);
140 :
141 : /** @brief Get the first available address for the given element count.
142 : *
143 : * @param num_elem Number of elements to accommodate.
144 : *
145 : * @return The first unicast address in an address range that allows a node
146 : * with the given number of elements to fit.
147 : */
148 1 : uint16_t bt_mesh_cdb_free_addr_get(uint8_t num_elem);
149 :
150 : /** @brief Delete a node.
151 : *
152 : * Delete a node from the CDB. When deleting the node and the address of the
153 : * last element of the deleted node is greater than the lowest available
154 : * address, CDB will update the lowest available address. The lowest
155 : * available address is reset and the deleted addresses can be reused only
156 : * after IV Index update.
157 : *
158 : * @param node The node to be deleted.
159 : * @param store If true, the node will be cleared from persistent storage.
160 : */
161 1 : void bt_mesh_cdb_node_del(struct bt_mesh_cdb_node *node, bool store);
162 :
163 : /** @brief Update a node.
164 : *
165 : * Assigns the node a new address and clears the previous persistent storage
166 : * entry.
167 : *
168 : * @param node The node to be deleted.
169 : * @param addr New unicast address for the node.
170 : * @param num_elem Updated number of elements in the node.
171 : */
172 1 : void bt_mesh_cdb_node_update(struct bt_mesh_cdb_node *node, uint16_t addr,
173 : uint8_t num_elem);
174 :
175 : /** @brief Get a node by address.
176 : *
177 : * Try to find the node that has the provided address assigned to one of its
178 : * elements.
179 : *
180 : * @param addr Address of the element to look for.
181 : *
182 : * @return The node that has an element with address addr or NULL if no such
183 : * node exists.
184 : */
185 1 : struct bt_mesh_cdb_node *bt_mesh_cdb_node_get(uint16_t addr);
186 :
187 : /** @brief Store node to persistent storage.
188 : *
189 : * @param node Node to be stored.
190 : */
191 1 : void bt_mesh_cdb_node_store(const struct bt_mesh_cdb_node *node);
192 :
193 : /** @brief Import device key for selected node.
194 : *
195 : * Using security library with PSA implementation access to the key by pointer
196 : * will not give a valid value since the key is hidden in the library.
197 : * The application has to import the key.
198 : *
199 : * @param node Selected node.
200 : * @param in key value.
201 : *
202 : * @return 0 on success or negative error code on failure.
203 : */
204 1 : int bt_mesh_cdb_node_key_import(struct bt_mesh_cdb_node *node, const uint8_t in[16]);
205 :
206 : /** @brief Export device key from selected node.
207 : *
208 : * Using security library with PSA implementation access to the key by pointer
209 : * will not give a valid value since the key is hidden in the library.
210 : * The application has to export the key.
211 : *
212 : * @param node Selected node.
213 : * @param out key value.
214 : *
215 : * @return 0 on success or negative error code on failure.
216 : */
217 1 : int bt_mesh_cdb_node_key_export(const struct bt_mesh_cdb_node *node, uint8_t out[16]);
218 :
219 0 : enum {
220 : BT_MESH_CDB_ITER_STOP = 0,
221 : BT_MESH_CDB_ITER_CONTINUE,
222 : };
223 :
224 : /** @typedef bt_mesh_cdb_node_func_t
225 : * @brief Node iterator callback.
226 : *
227 : * @param node Node found.
228 : * @param user_data Data given.
229 : *
230 : * @return BT_MESH_CDB_ITER_CONTINUE to continue to iterate through the nodes
231 : * or BT_MESH_CDB_ITER_STOP to stop.
232 : */
233 1 : typedef uint8_t (*bt_mesh_cdb_node_func_t)(struct bt_mesh_cdb_node *node,
234 : void *user_data);
235 :
236 : /** @brief Node iterator.
237 : *
238 : * Iterate nodes in the Mesh Configuration Database. The callback function
239 : * will only be called for valid, ie allocated, nodes.
240 : *
241 : * @param func Callback function.
242 : * @param user_data Data to pass to the callback.
243 : */
244 1 : void bt_mesh_cdb_node_foreach(bt_mesh_cdb_node_func_t func, void *user_data);
245 :
246 : /** @brief Allocate a subnet.
247 : *
248 : * Allocate a new subnet in the CDB.
249 : *
250 : * @param net_idx NetIdx of the subnet.
251 : *
252 : * @return The new subnet or NULL if it cannot be allocated due to
253 : * lack of resources or the subnet has been already allocated.
254 : */
255 1 : struct bt_mesh_cdb_subnet *bt_mesh_cdb_subnet_alloc(uint16_t net_idx);
256 :
257 : /** @brief Delete a subnet.
258 : *
259 : * Delete a subnet from the CDB.
260 : *
261 : * @param sub The subnet to be deleted.
262 : * @param store If true, the subnet will be cleared from persistent storage.
263 : */
264 1 : void bt_mesh_cdb_subnet_del(struct bt_mesh_cdb_subnet *sub, bool store);
265 :
266 : /** @brief Get a subnet by NetIdx
267 : *
268 : * Try to find the subnet with the specified NetIdx.
269 : *
270 : * @param net_idx NetIdx of the subnet to look for.
271 : *
272 : * @return The subnet with the specified NetIdx or NULL if no such subnet
273 : * exists.
274 : */
275 1 : struct bt_mesh_cdb_subnet *bt_mesh_cdb_subnet_get(uint16_t net_idx);
276 :
277 : /** @brief Store subnet to persistent storage.
278 : *
279 : * @param sub Subnet to be stored.
280 : */
281 1 : void bt_mesh_cdb_subnet_store(const struct bt_mesh_cdb_subnet *sub);
282 :
283 : /** @brief Get the flags for a subnet
284 : *
285 : * @param sub The subnet to get flags for.
286 : *
287 : * @return The flags for the subnet.
288 : */
289 1 : uint8_t bt_mesh_cdb_subnet_flags(const struct bt_mesh_cdb_subnet *sub);
290 :
291 : /** @brief Import network key for selected subnetwork.
292 : *
293 : * Using security library with PSA implementation access to the key by pointer
294 : * will not give a valid value since the key is hidden in the library.
295 : * The application has to import the key.
296 : *
297 : * @param sub Selected subnetwork.
298 : * @param key_idx 0 or 1. If Key Refresh procedure is in progress then two keys are available.
299 : * The old key has an index 0 and the new one has an index 1.
300 : * Otherwise, the only key with index 0 exists.
301 : * @param in key value.
302 : *
303 : * @return 0 on success or negative error code on failure.
304 : */
305 1 : int bt_mesh_cdb_subnet_key_import(struct bt_mesh_cdb_subnet *sub, int key_idx,
306 : const uint8_t in[16]);
307 :
308 : /** @brief Export network key from selected subnetwork.
309 : *
310 : * Using security library with PSA implementation access to the key by pointer
311 : * will not give a valid value since the key is hidden in the library.
312 : * The application has to export the key.
313 : *
314 : * @param sub Selected subnetwork.
315 : * @param key_idx 0 or 1. If Key Refresh procedure is in progress then two keys are available.
316 : * The old key has an index 0 and the new one has an index 1.
317 : * Otherwise, the only key with index 0 exists.
318 : * @param out key value.
319 : *
320 : * @return 0 on success or negative error code on failure.
321 : */
322 1 : int bt_mesh_cdb_subnet_key_export(const struct bt_mesh_cdb_subnet *sub, int key_idx,
323 : uint8_t out[16]);
324 :
325 : /** @brief Allocate an application key.
326 : *
327 : * Allocate a new application key in the CDB.
328 : *
329 : * @param net_idx NetIdx of NetKey that the application key is bound to.
330 : * @param app_idx AppIdx of the application key.
331 : *
332 : * @return The new application key or NULL if it cannot be allocated due to
333 : * lack of resources or the key has been already allocated.
334 : */
335 1 : struct bt_mesh_cdb_app_key *bt_mesh_cdb_app_key_alloc(uint16_t net_idx,
336 : uint16_t app_idx);
337 :
338 : /** @brief Delete an application key.
339 : *
340 : * Delete an application key from the CDB.
341 : *
342 : * @param key The application key to be deleted.
343 : * @param store If true, the key will be cleared from persistent storage.
344 : */
345 1 : void bt_mesh_cdb_app_key_del(struct bt_mesh_cdb_app_key *key, bool store);
346 :
347 : /** @brief Get an application key by AppIdx
348 : *
349 : * Try to find the application key with the specified AppIdx.
350 : *
351 : * @param app_idx AppIdx of the application key to look for.
352 : *
353 : * @return The application key with the specified AppIdx or NULL if no such key
354 : * exists.
355 : */
356 1 : struct bt_mesh_cdb_app_key *bt_mesh_cdb_app_key_get(uint16_t app_idx);
357 :
358 : /** @brief Store application key to persistent storage.
359 : *
360 : * @param key Application key to be stored.
361 : */
362 1 : void bt_mesh_cdb_app_key_store(const struct bt_mesh_cdb_app_key *key);
363 :
364 : /** @brief Import application key.
365 : *
366 : * Using security library with PSA implementation access to the key by pointer
367 : * will not give a valid value since the key is hidden in the library.
368 : * The application has to import the key.
369 : *
370 : * @param key cdb application key structure.
371 : * @param key_idx 0 or 1. If Key Refresh procedure is in progress then two keys are available.
372 : * The old key has an index 0 and the new one has an index 1.
373 : * Otherwise, the only key with index 0 exists.
374 : * @param in key value.
375 : *
376 : * @return 0 on success or negative error code on failure.
377 : */
378 1 : int bt_mesh_cdb_app_key_import(struct bt_mesh_cdb_app_key *key, int key_idx, const uint8_t in[16]);
379 :
380 : /** @brief Export application key.
381 : *
382 : * Using security library with PSA implementation access to the key by pointer
383 : * will not give a valid value since the key is hidden in the library.
384 : * The application has to export the key.
385 : *
386 : * @param key cdb application key structure.
387 : * @param key_idx 0 or 1. If Key Refresh procedure is in progress then two keys are available.
388 : * The old key has an index 0 and the new one has an index 1.
389 : * Otherwise, the only key with index 0 exists.
390 : * @param out key value.
391 : *
392 : * @return 0 on success or negative error code on failure.
393 : */
394 1 : int bt_mesh_cdb_app_key_export(const struct bt_mesh_cdb_app_key *key, int key_idx, uint8_t out[16]);
395 :
396 : #ifdef __cplusplus
397 : }
398 : #endif
399 :
400 : #endif /* ZEPHYR_INCLUDE_BLUETOOTH_MESH_CDB_H_ */
|