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))
97 BT_INFO("Mesh: freed Appkey index [%u]", 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(uint8_t net_uuid[])
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, net_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: Unloaded [%d] Keys from the network",
125 l_queue_remove(networks, network);
127 BT_INFO("Mesh: Current Number of networks [%d]",
128 l_queue_length(networks));
131 void _bt_mesh_keys_load_net(uint8_t net_uuid[])
133 struct mesh_network_t *network;
134 BT_INFO("Mesh:Keys: Create new network");
136 if (l_queue_find(networks, __mesh_net_uuid_match, net_uuid))
140 networks = l_queue_new();
142 network = l_new(struct mesh_network_t, 1);
143 memcpy(network->net_uuid, net_uuid, 16);
144 network->net_keys = l_queue_new();
145 l_queue_push_tail(networks, network);
148 void _bt_mesh_keys_add_net_key(uint8_t net_uuid[],
151 struct mesh_net_key_t *key;
152 struct mesh_network_t *network;
153 BT_INFO("Mesh:Keys: Create new netkey for Network KeyIDx [%u]",
156 network = l_queue_find(networks,
157 __mesh_net_uuid_match, net_uuid);
161 if (l_queue_find(network->net_keys, __mesh_net_idx_match,
162 L_UINT_TO_PTR(net_idx)))
165 key = l_new(struct mesh_net_key_t , 1);
167 key->phase = MESH_KEY_REFRESH_PHASE_NONE;
169 l_queue_push_tail(network->net_keys, key);
172 bool _bt_mesh_keys_is_netkey_present(uint8_t net_uuid[], uint16_t net_idx)
174 struct mesh_network_t *network;
176 network = l_queue_find(networks, __mesh_net_uuid_match, net_uuid);
179 if (!l_queue_find(network->net_keys, __mesh_net_idx_match,
180 L_UINT_TO_PTR(net_idx)))
185 bool _bt_mesh_keys_get_netkey_list(uint8_t net_uuid[], GArray **out)
187 struct mesh_network_t *network;
188 const struct l_queue_entry *l;
190 network = l_queue_find(networks, __mesh_net_uuid_match, net_uuid);
194 for (l = l_queue_get_entries(network->net_keys); l; l = l->next) {
195 const struct mesh_net_key_t *key = l->data;
197 g_array_append_vals(*out, &key->idx, sizeof(uint16_t));
203 bool _bt_mesh_keys_get_appkey_list(uint8_t net_uuid[],
204 uint16_t net_idx, GArray **out)
206 struct mesh_network_t *network;
207 struct mesh_net_key_t *netkey;
208 const struct l_queue_entry *l;
210 network = l_queue_find(networks, __mesh_net_uuid_match, net_uuid);
214 netkey = l_queue_find(network->net_keys,
215 __mesh_net_idx_match, L_UINT_TO_PTR(net_idx));
219 for (l = l_queue_get_entries(netkey->app_keys); l; l = l->next) {
220 uint16_t app_idx = L_PTR_TO_UINT(l->data);
222 g_array_append_vals(*out, &app_idx, sizeof(uint16_t));
228 bool _bt_mesh_keys_get_new_netkey_index(uint8_t net_uuid[],
231 struct mesh_net_key_t *key;
232 struct mesh_network_t *network;
234 network = l_queue_find(networks,
235 __mesh_net_uuid_match, net_uuid);
239 if (l_queue_length(network->net_keys)) {
240 key = l_queue_peek_tail(network->net_keys);
243 *net_idx = key->idx + 1;
250 bool _bt_mesh_keys_get_new_appkey_index(uint8_t net_uuid[],
253 const struct l_queue_entry *l, *l1;
254 struct mesh_network_t *network;
256 BT_INFO("Mesh: Find New appkey index");
257 network = l_queue_find(networks, __mesh_net_uuid_match, net_uuid);
261 BT_INFO("Mesh: Found network, number of netkeys present [%d]",
262 l_queue_length(network->net_keys));
264 if (!network->net_keys)
267 /* TODO: Save max appkey index in Network to avoid looping */
268 for (l = l_queue_get_entries(network->net_keys); l; l = l->next) {
269 struct mesh_net_key_t *key = l->data;
271 BT_INFO("Mesh: Number of Appkeys in current netkey is [%d]",
272 l_queue_length(key->app_keys));
277 for (l1 = l_queue_get_entries(key->app_keys); l1; l1 = l1->next) {
278 uint16_t app_idx = L_PTR_TO_UINT(l1->data);
279 BT_INFO("Mesh: Current AppKey Index [0x%2.2x]", app_idx);
280 if (app_idx > maxkey)
284 *app_idx = maxkey + 1;
289 bool _bt_mesh_keys_get_net_key_phase(uint8_t net_uuid[],
290 uint16_t net_idx, uint8_t *phase)
292 struct mesh_net_key_t *key;
293 struct mesh_network_t *network;
295 network = l_queue_find(networks,
296 __mesh_net_uuid_match, net_uuid);
300 if (!phase || !network->net_keys)
303 key = l_queue_find(network->net_keys, __mesh_net_idx_match,
304 L_UINT_TO_PTR(net_idx));
312 void _bt_mesh_keys_set_net_key_phase(_bt_mesh_cdb_t *cfg,
313 uint16_t net_idx, uint8_t phase, bool save)
315 struct mesh_net_key_t *key;
316 struct mesh_network_t *network;
318 network = l_queue_find(networks, __mesh_net_uuid_match, cfg->uuid);
322 if (!network->net_keys)
325 key = l_queue_find(network->net_keys,
326 __mesh_net_idx_match, L_UINT_TO_PTR(net_idx));
332 if (save && !_bt_mesh_conf_set_phase_network_key(cfg,
334 BT_INFO("Failed to save updated KR phase\n");
337 void _bt_mesh_keys_del_net_key(uint8_t net_uuid[],
338 uint16_t idx, _bt_mesh_cdb_t *cfg)
340 struct mesh_net_key_t *key;
341 struct mesh_network_t *network;
342 BT_INFO("Mesh:Keys: Delete new netkey for Network KeyIDx [%u]",
345 network = l_queue_find(networks, __mesh_net_uuid_match, net_uuid);
349 if (!network->net_keys)
352 key = l_queue_remove_if(network->net_keys,
353 __mesh_net_idx_match, L_UINT_TO_PTR(idx));
357 l_queue_foreach_remove(key->app_keys,
358 __mesh_delete_bound_appkey, cfg);
360 BT_INFO("Mesh: NetKey deleted");
363 void _bt_mesh_keys_add_app_key(uint8_t net_uuid[],
364 uint16_t net_idx, uint16_t app_idx)
366 struct mesh_net_key_t *key;
367 struct mesh_network_t *network;
369 BT_INFO("Mesh: Add Appkey in Netkey");
370 network = l_queue_find(networks, __mesh_net_uuid_match, net_uuid);
374 if (!network->net_keys)
377 key = l_queue_find(network->net_keys, __mesh_net_idx_match,
378 L_UINT_TO_PTR(net_idx));
383 key->app_keys = l_queue_new();
385 if (__mesh_app_key_present(key, app_idx))
388 l_queue_push_tail(key->app_keys, L_UINT_TO_PTR(app_idx));
389 BT_INFO("Mesh: Appkey with index [0x%2.2x] added to Netkey [0x%2.2x]",
393 void _bt_mesh_keys_del_app_key(uint8_t net_uuid[], uint16_t app_idx)
395 const struct l_queue_entry *l;
396 struct mesh_network_t *network;
398 network = l_queue_find(networks, __mesh_net_uuid_match, net_uuid);
402 if (!network->net_keys)
405 for (l = l_queue_get_entries(network->net_keys); l; l = l->next) {
406 struct mesh_net_key_t *key = l->data;
410 BT_INFO("Mesh: Delete AppKey index [%u]", app_idx);
411 if (l_queue_remove(key->app_keys, L_UINT_TO_PTR(app_idx)))
416 uint16_t _bt_mesh_keys_get_bound_key(uint8_t net_uuid[], uint16_t app_idx)
418 const struct l_queue_entry *l;
419 struct mesh_network_t *network;
421 network = l_queue_find(networks, __mesh_net_uuid_match, net_uuid);
423 return MESH_NET_IDX_INVALID;
425 if (!network->net_keys)
426 return MESH_NET_IDX_INVALID;
428 for (l = l_queue_get_entries(network->net_keys); l; l = l->next) {
429 struct mesh_net_key_t *key = l->data;
434 if (__mesh_app_key_present(key, app_idx))
438 return MESH_NET_IDX_INVALID;
441 bool _bt_mesh_keys_subnet_exists(uint8_t net_uuid[], uint16_t idx)
443 struct mesh_network_t *network;
445 network = l_queue_find(networks, __mesh_net_uuid_match, net_uuid);
449 if (!l_queue_find(network->net_keys, __mesh_net_idx_match,