1 /*
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 <inttypes.h>
10 #include <sys/atomic.h>
11 
12 #ifdef __cplusplus
13 extern "C" {
14 #endif
15 
16 #if defined(CONFIG_BT_MESH_CDB)
17 #define NODE_COUNT    CONFIG_BT_MESH_CDB_NODE_COUNT
18 #define SUBNET_COUNT  CONFIG_BT_MESH_CDB_SUBNET_COUNT
19 #define APP_KEY_COUNT CONFIG_BT_MESH_CDB_APP_KEY_COUNT
20 #else
21 #define NODE_COUNT    0
22 #define SUBNET_COUNT  0
23 #define APP_KEY_COUNT 0
24 #endif
25 
26 enum {
27 	BT_MESH_CDB_NODE_CONFIGURED,
28 
29 	BT_MESH_CDB_NODE_FLAG_COUNT
30 };
31 
32 struct bt_mesh_cdb_node {
33 	uint8_t  uuid[16];
34 	uint16_t addr;
35 	uint16_t net_idx;
36 	uint8_t  num_elem;
37 	uint8_t  dev_key[16];
38 
39 	ATOMIC_DEFINE(flags, BT_MESH_CDB_NODE_FLAG_COUNT);
40 };
41 
42 struct bt_mesh_cdb_subnet {
43 	uint16_t net_idx;
44 
45 	uint8_t kr_phase;
46 
47 	struct {
48 		uint8_t net_key[16];
49 	} keys[2];
50 };
51 
52 struct bt_mesh_cdb_app_key {
53 	uint16_t net_idx;
54 	uint16_t app_idx;
55 
56 	struct {
57 		uint8_t app_key[16];
58 	} keys[2];
59 };
60 
61 enum {
62 	BT_MESH_CDB_VALID,
63 	BT_MESH_CDB_SUBNET_PENDING,
64 	BT_MESH_CDB_KEYS_PENDING,
65 	BT_MESH_CDB_NODES_PENDING,
66 	BT_MESH_CDB_IVU_IN_PROGRESS,
67 
68 	BT_MESH_CDB_FLAG_COUNT,
69 };
70 
71 struct bt_mesh_cdb {
72 	uint32_t iv_index;
73 
74 	ATOMIC_DEFINE(flags, BT_MESH_CDB_FLAG_COUNT);
75 
76 	struct bt_mesh_cdb_node nodes[NODE_COUNT];
77 	struct bt_mesh_cdb_subnet subnets[SUBNET_COUNT];
78 	struct bt_mesh_cdb_app_key app_keys[APP_KEY_COUNT];
79 };
80 
81 extern struct bt_mesh_cdb bt_mesh_cdb;
82 
83 /** @brief Create the Mesh Configuration Database.
84  *
85  *  Create and initialize the Mesh Configuration Database. A primary subnet,
86  *  ie one with NetIdx 0, will be added and the provided key will be used as
87  *  NetKey for that subnet.
88  *
89  *  @param key The NetKey to be used for the primary subnet.
90  *
91  *  @return 0 on success or negative error code on failure.
92  */
93 int bt_mesh_cdb_create(const uint8_t key[16]);
94 
95 /** @brief Clear the Mesh Configuration Database.
96  *
97  *  Remove all nodes, subnets and app-keys stored in the database and mark
98  *  the database as invalid. The data will be cleared from persistent storage
99  *  if CONFIG_BT_SETTINGS is enabled.
100  */
101 void bt_mesh_cdb_clear(void);
102 
103 /** @brief Set and store the IV Index and IV Update flag.
104  *
105  *  The IV Index stored in the CDB will be the one used during provisioning
106  *  of new nodes. This function is generally only used from inside the stack.
107  *
108  *  This function will store the data to persistent storage if
109  *  CONFIG_BT_SETTINGS is enabled.
110  *
111  *  @param iv_index The new IV Index to use.
112  *  @param iv_update True if there is an ongoing IV Update procedure.
113  */
114 void bt_mesh_cdb_iv_update(uint32_t iv_index, bool iv_update);
115 
116 /** @brief Allocate a node.
117  *
118  *  Allocate a new node in the CDB.
119  *
120  *  @param uuid UUID of the node.
121  *  @param addr Address of the node's primary element. If 0, the lowest
122  *              possible address available will be assigned to the node.
123  *  @param num_elem Number of elements that the node has.
124  *  @param net_idx NetIdx that the node was provisioned to.
125  *
126  *  @return The new node or NULL if it cannot be allocated.
127  */
128 struct bt_mesh_cdb_node *bt_mesh_cdb_node_alloc(const uint8_t uuid[16], uint16_t addr,
129 						uint8_t num_elem, uint16_t net_idx);
130 
131 /** @brief Delete a node.
132  *
133  *  Delete a node from the CDB.
134  *
135  *  @param node The node to be deleted.
136  *  @param store If true, the node will be cleared from persistent storage.
137  */
138 void bt_mesh_cdb_node_del(struct bt_mesh_cdb_node *node, bool store);
139 
140 /** @brief Get a node by address.
141  *
142  *  Try to find the node that has the provided address assigned to one of its
143  *  elements.
144  *
145  *  @param addr Address of the element to look for.
146  *
147  *  @return The node that has an element with address addr or NULL if no such
148  *          node exists.
149  */
150 struct bt_mesh_cdb_node *bt_mesh_cdb_node_get(uint16_t addr);
151 
152 /** @brief Store node to persistent storage.
153  *
154  *  @param node Node to be stored.
155  */
156 void bt_mesh_cdb_node_store(const struct bt_mesh_cdb_node *node);
157 
158 enum {
159 	BT_MESH_CDB_ITER_STOP = 0,
160 	BT_MESH_CDB_ITER_CONTINUE,
161 };
162 
163 /** @typedef bt_mesh_cdb_node_func_t
164  *  @brief Node iterator callback.
165  *
166  *  @param node Node found.
167  *  @param user_data Data given.
168  *
169  *  @return BT_MESH_CDB_ITER_CONTINUE to continue to iterate through the nodes
170  *          or BT_MESH_CDB_ITER_STOP to stop.
171  */
172 typedef uint8_t (*bt_mesh_cdb_node_func_t)(struct bt_mesh_cdb_node *node,
173 					void *user_data);
174 
175 /** @brief Node iterator.
176  *
177  *  Iterate nodes in the Mesh Configuration Database. The callback function
178  *  will only be called for valid, ie allocated, nodes.
179  *
180  *  @param func Callback function.
181  *  @param user_data Data to pass to the callback.
182  */
183 void bt_mesh_cdb_node_foreach(bt_mesh_cdb_node_func_t func, void *user_data);
184 
185 /** @brief Allocate a subnet.
186  *
187  *  Allocate a new subnet in the CDB.
188  *
189  *  @param net_idx NetIdx of the subnet.
190  *
191  *  @return The new subnet or NULL if it cannot be allocated.
192  */
193 struct bt_mesh_cdb_subnet *bt_mesh_cdb_subnet_alloc(uint16_t net_idx);
194 
195 /** @brief Delete a subnet.
196  *
197  *  Delete a subnet from the CDB.
198  *
199  *  @param sub The subnet to be deleted.
200  *  @param store If true, the subnet will be cleared from persistent storage.
201  */
202 void bt_mesh_cdb_subnet_del(struct bt_mesh_cdb_subnet *sub, bool store);
203 
204 /** @brief Get a subnet by NetIdx
205  *
206  *  Try to find the subnet with the specified NetIdx.
207  *
208  *  @param net_idx NetIdx of the subnet to look for.
209  *
210  *  @return The subnet with the specified NetIdx or NULL if no such subnet
211  *          exists.
212  */
213 struct bt_mesh_cdb_subnet *bt_mesh_cdb_subnet_get(uint16_t net_idx);
214 
215 /** @brief Store subnet to persistent storage.
216  *
217  *  @param sub Subnet to be stored.
218  */
219 void bt_mesh_cdb_subnet_store(const struct bt_mesh_cdb_subnet *sub);
220 
221 /** @brief Get the flags for a subnet
222  *
223  *  @param sub The subnet to get flags for.
224  *
225  *  @return The flags for the subnet.
226  */
227 uint8_t bt_mesh_cdb_subnet_flags(const struct bt_mesh_cdb_subnet *sub);
228 
229 
230 /** @brief Allocate an application key.
231  *
232  *  Allocate a new application key in the CDB.
233  *
234  *  @param net_idx NetIdx of NetKey that the application key is bound to.
235  *  @param app_idx AppIdx of the application key.
236  *
237  *  @return The new application key or NULL if it cannot be allocated.
238  */
239 struct bt_mesh_cdb_app_key *bt_mesh_cdb_app_key_alloc(uint16_t net_idx,
240 						      uint16_t app_idx);
241 
242 /** @brief Delete an application key.
243  *
244  *  Delete an application key from the CDB.
245  *
246  *  @param key The application key to be deleted.
247  *  @param store If true, the key will be cleared from persistent storage.
248  */
249 void bt_mesh_cdb_app_key_del(struct bt_mesh_cdb_app_key *key, bool store);
250 
251 /** @brief Get an application key by AppIdx
252  *
253  *  Try to find the application key with the specified AppIdx.
254  *
255  *  @param app_idx AppIdx of the application key to look for.
256  *
257  *  @return The application key with the specified AppIdx or NULL if no such key
258  *          exists.
259  */
260 struct bt_mesh_cdb_app_key *bt_mesh_cdb_app_key_get(uint16_t app_idx);
261 
262 /** @brief Store application key to persistent storage.
263  *
264  *  @param key Application key to be stored.
265  */
266 void bt_mesh_cdb_app_key_store(const struct bt_mesh_cdb_app_key *key);
267 
268 #ifdef __cplusplus
269 }
270 #endif
271 
272 #endif /* ZEPHYR_INCLUDE_BLUETOOTH_MESH_CDB_H_ */
273