4 * Copyright (c) 2020 Samsung Electronics Co., Ltd.
6 * @author: Anupam Roy <anupam.r@samsung.com>
8 * Licensed under the Apache License, Version 2.0 (the "License");
9 * you may not use this file except in compliance with the License.
10 * You may obtain a copy of the License at
12 * http://www.apache.org/licenses/LICENSE-2.0
14 * Unless required by applicable law or agreed to in writing, software
15 * distributed under the License is distributed on an "AS IS" BASIS,
16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 * See the License for the specific language governing permissions and
18 * limitations under the License.
23 #include "bt-service-common.h"
24 #include "bluetooth-api.h"
26 #include "bluetooth-mesh-api.h"
27 #include "bt-internal-types.h"
28 #include "bt-service-util.h"
29 #include "bt-service-common.h"
30 #include "bt-service-event.h"
31 #include "bt-service-mesh-keys.h"
32 #include "bt-service-mesh-util.h"
34 #include "bt-internal-types.h"
38 /* An instance of a Mesh Network Key */
39 struct mesh_net_key_t {
40 struct l_queue *app_keys;
45 /* An instance of a Mesh network */
46 struct mesh_network_t {
48 struct l_queue *net_keys;
51 static struct l_queue *networks;
53 static bool __mesh_net_uuid_match(const void *a, const void *b)
55 const struct mesh_network_t *net = a;
56 uint8_t* uuid = (uint8_t*)b;
58 if (memcmp(net->net_uuid, uuid, 16) == 0) {
59 BT_INFO("Mesh: Found network with given Net UUID");
66 static bool __mesh_app_key_present(const struct mesh_net_key_t *key,
69 const struct l_queue_entry *l;
71 for (l = l_queue_get_entries(key->app_keys); l; l = l->next) {
72 uint16_t idx = L_PTR_TO_UINT(l->data);
81 static bool __mesh_net_idx_match(const void *a, const void *b)
83 const struct mesh_net_key_t *key = a;
84 uint32_t idx = L_PTR_TO_UINT(b);
86 return key->idx == idx;
89 static bool __mesh_delete_bound_appkey(void *a, void *b)
91 uint32_t idx = L_PTR_TO_UINT(a);
92 _bt_mesh_cdb_t *cfg = (_bt_mesh_cdb_t*) b;
94 if (!_bt_mesh_conf_delete_application_key(cfg, idx))
100 static bool __mesh_remove_netkey_entry(void *a, void *b)
102 struct mesh_net_key_t *key = (struct mesh_net_key_t*) a;
104 /* Only cleanup local keys from the network object:
105 DONT touch configuration file */
106 l_queue_destroy(key->app_keys, l_free);
111 void _bt_mesh_keys_unload_net(_bt_mesh_cdb_t *cfg)
113 struct mesh_network_t *network;
115 BT_INFO("Mesh:Keys: Unload network with all Keys");
117 network = l_queue_find(networks, __mesh_net_uuid_match, cfg->uuid);
118 if (!network || !network->net_keys)
121 numkeys = l_queue_foreach_remove(network->net_keys,
122 __mesh_remove_netkey_entry, network);
123 BT_INFO("Mesh:Nodes: Unloadeded [%d] Keys from the network",
128 void _bt_mesh_keys_load_net(uint8_t net_uuid[])
130 struct mesh_network_t *network;
131 BT_INFO("Mesh:Keys: Create new network");
133 if (l_queue_find(networks, __mesh_net_uuid_match, net_uuid))
137 networks = l_queue_new();
139 network = l_new(struct mesh_network_t, 1);
140 memcpy(network->net_uuid, net_uuid, 16);
141 network->net_keys = l_queue_new();
142 l_queue_push_tail(networks, network);
145 void _bt_mesh_keys_add_net_key(uint8_t net_uuid[],
148 struct mesh_net_key_t *key;
149 struct mesh_network_t *network;
150 BT_INFO("Mesh:Keys: Create new netkey for Network KeyIDx [%u]",
153 network = l_queue_find(networks,
154 __mesh_net_uuid_match, net_uuid);
158 if (l_queue_find(network->net_keys, __mesh_net_idx_match,
159 L_UINT_TO_PTR(net_idx)))
162 key = l_new(struct mesh_net_key_t , 1);
164 key->phase = MESH_KEY_REFRESH_PHASE_NONE;
166 l_queue_push_tail(network->net_keys, key);
169 bool _bt_mesh_keys_is_netkey_present(uint8_t net_uuid[], uint16_t net_idx)
171 struct mesh_network_t *network;
173 network = l_queue_find(networks, __mesh_net_uuid_match, net_uuid);
176 if (!l_queue_find(network->net_keys, __mesh_net_idx_match,
177 L_UINT_TO_PTR(net_idx)))
182 bool _bt_mesh_keys_get_netkey_list(uint8_t net_uuid[], GArray **out)
184 struct mesh_network_t *network;
185 const struct l_queue_entry *l;
187 network = l_queue_find(networks, __mesh_net_uuid_match, net_uuid);
191 for (l = l_queue_get_entries(network->net_keys); l; l = l->next) {
192 const struct mesh_net_key_t *key = l->data;
194 g_array_append_vals(*out, &key->idx, sizeof(uint16_t));
200 bool _bt_mesh_keys_get_appkey_list(uint8_t net_uuid[],
201 uint16_t net_idx, GArray **out)
203 struct mesh_network_t *network;
204 struct mesh_net_key_t *netkey;
205 const struct l_queue_entry *l;
207 network = l_queue_find(networks, __mesh_net_uuid_match, net_uuid);
211 netkey = l_queue_find(network->net_keys,
212 __mesh_net_idx_match, L_UINT_TO_PTR(net_idx));
216 for (l = l_queue_get_entries(netkey->app_keys); l; l = l->next) {
217 uint16_t app_idx = L_PTR_TO_UINT(l->data);
219 g_array_append_vals(*out, &app_idx, sizeof(uint16_t));
225 bool _bt_mesh_keys_get_new_netkey_index(uint8_t net_uuid[],
228 struct mesh_net_key_t *key;
229 struct mesh_network_t *network;
231 network = l_queue_find(networks,
232 __mesh_net_uuid_match, net_uuid);
236 if (l_queue_length(network->net_keys)) {
237 key = l_queue_peek_tail(network->net_keys);
240 *net_idx = key->idx + 1;
247 bool _bt_mesh_keys_get_new_appkey_index(uint8_t net_uuid[],
250 const struct l_queue_entry *l;
251 struct mesh_network_t *network;
254 network = l_queue_find(networks, __mesh_net_uuid_match, net_uuid);
258 if (!network->net_keys)
261 for (l = l_queue_get_entries(network->net_keys); l; l = l->next) {
262 struct mesh_net_key_t *key = l->data;
267 for (l = l_queue_get_entries(key->app_keys); l; l = l->next) {
268 uint16_t app_idx = L_PTR_TO_UINT(l->data);
269 if (app_idx > maxkey)
273 *app_idx = maxkey + 1;
278 bool _bt_mesh_keys_get_net_key_phase(uint8_t net_uuid[],
279 uint16_t net_idx, uint8_t *phase)
281 struct mesh_net_key_t *key;
282 struct mesh_network_t *network;
284 network = l_queue_find(networks,
285 __mesh_net_uuid_match, net_uuid);
289 if (!phase || !network->net_keys)
292 key = l_queue_find(network->net_keys, __mesh_net_idx_match,
293 L_UINT_TO_PTR(net_idx));
301 void _bt_mesh_keys_set_net_key_phase(_bt_mesh_cdb_t *cfg,
302 uint16_t net_idx, uint8_t phase, bool save)
304 struct mesh_net_key_t *key;
305 struct mesh_network_t *network;
307 network = l_queue_find(networks, __mesh_net_uuid_match, cfg->uuid);
311 if (!network->net_keys)
314 key = l_queue_find(network->net_keys,
315 __mesh_net_idx_match, L_UINT_TO_PTR(net_idx));
321 if (save && !_bt_mesh_conf_set_phase_network_key(cfg,
323 BT_INFO("Failed to save updated KR phase\n");
326 void _bt_mesh_keys_del_net_key(uint8_t net_uuid[],
327 uint16_t idx, _bt_mesh_cdb_t *cfg)
329 struct mesh_net_key_t *key;
330 struct mesh_network_t *network;
331 BT_INFO("Mesh:Keys: Delete new netkey for Network KeyIDx [%u]",
334 network = l_queue_find(networks, __mesh_net_uuid_match, net_uuid);
338 if (!network->net_keys)
341 key = l_queue_remove_if(network->net_keys,
342 __mesh_net_idx_match, L_UINT_TO_PTR(idx));
346 l_queue_foreach_remove(key->app_keys,
347 __mesh_delete_bound_appkey, cfg);
351 void _bt_mesh_keys_add_app_key(uint8_t net_uuid[],
352 uint16_t net_idx, uint16_t app_idx)
354 struct mesh_net_key_t *key;
355 struct mesh_network_t *network;
357 network = l_queue_find(networks, __mesh_net_uuid_match, net_uuid);
361 if (!network->net_keys)
364 key = l_queue_find(network->net_keys, __mesh_net_idx_match,
365 L_UINT_TO_PTR(net_idx));
370 key->app_keys = l_queue_new();
372 if (__mesh_app_key_present(key, app_idx))
375 l_queue_push_tail(key->app_keys, L_UINT_TO_PTR(app_idx));
378 void _bt_mesh_keys_del_app_key(uint8_t net_uuid[], uint16_t app_idx)
380 const struct l_queue_entry *l;
381 struct mesh_network_t *network;
383 network = l_queue_find(networks, __mesh_net_uuid_match, net_uuid);
387 if (!network->net_keys)
390 for (l = l_queue_get_entries(network->net_keys); l; l = l->next) {
391 struct mesh_net_key_t *key = l->data;
396 if (l_queue_remove(key->app_keys, L_UINT_TO_PTR(app_idx)))
401 uint16_t _bt_mesh_keys_get_bound_key(uint8_t net_uuid[], uint16_t app_idx)
403 const struct l_queue_entry *l;
404 struct mesh_network_t *network;
406 network = l_queue_find(networks, __mesh_net_uuid_match, net_uuid);
408 return MESH_NET_IDX_INVALID;
410 if (!network->net_keys)
411 return MESH_NET_IDX_INVALID;
413 for (l = l_queue_get_entries(network->net_keys); l; l = l->next) {
414 struct mesh_net_key_t *key = l->data;
419 if (__mesh_app_key_present(key, app_idx))
423 return MESH_NET_IDX_INVALID;
426 bool _bt_mesh_keys_subnet_exists(uint8_t net_uuid[], uint16_t idx)
428 struct mesh_network_t *network;
430 network = l_queue_find(networks, __mesh_net_uuid_match, net_uuid);
434 if (!l_queue_find(network->net_keys, __mesh_net_idx_match,