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 void _bt_mesh_keys_load_net(uint8_t net_uuid[])
91 struct mesh_network_t *network;
92 BT_INFO("Mesh:Keys: Create new network");
94 if (l_queue_find(networks, __mesh_net_uuid_match, net_uuid))
98 networks = l_queue_new();
100 network = l_new(struct mesh_network_t, 1);
101 memcpy(network->net_uuid, net_uuid, 16);
102 network->net_keys = l_queue_new();
103 l_queue_push_tail(networks, network);
106 void _bt_mesh_keys_add_net_key(uint8_t net_uuid[], uint16_t net_idx)
108 struct mesh_net_key_t *key;
109 struct mesh_network_t *network;
110 BT_INFO("Mesh:Keys: Create new netkey for Network KeyIDx [%u]",
113 network = l_queue_find(networks, __mesh_net_uuid_match, net_uuid);
117 if (l_queue_find(network->net_keys, __mesh_net_idx_match,
118 L_UINT_TO_PTR(net_idx)))
121 key = l_new(struct mesh_net_key_t , 1);
123 key->phase = MESH_KEY_REFRESH_PHASE_NONE;
125 l_queue_push_tail(network->net_keys, key);
128 bool _bt_mesh_keys_is_netkey_present(uint8_t net_uuid[], uint16_t net_idx)
130 struct mesh_network_t *network;
132 network = l_queue_find(networks, __mesh_net_uuid_match, net_uuid);
135 if (!l_queue_find(network->net_keys, __mesh_net_idx_match,
136 L_UINT_TO_PTR(net_idx)))
141 bool _bt_mesh_keys_get_netkey_list(uint8_t net_uuid[], GArray **out)
143 struct mesh_network_t *network;
144 const struct l_queue_entry *l;
146 network = l_queue_find(networks, __mesh_net_uuid_match, net_uuid);
150 for (l = l_queue_get_entries(network->net_keys); l; l = l->next) {
151 const struct mesh_net_key_t *key = l->data;
153 g_array_append_vals(*out, &key->idx, sizeof(uint16_t));
159 bool _bt_mesh_keys_get_appkey_list(uint8_t net_uuid[],
160 uint16_t net_idx, GArray **out)
162 struct mesh_network_t *network;
163 struct mesh_net_key_t *netkey;
164 const struct l_queue_entry *l;
166 network = l_queue_find(networks, __mesh_net_uuid_match, net_uuid);
170 netkey = l_queue_find(network->net_keys,
171 __mesh_net_idx_match, L_UINT_TO_PTR(net_idx));
175 for (l = l_queue_get_entries(netkey->app_keys); l; l = l->next) {
176 uint16_t app_idx = L_PTR_TO_UINT(l->data);
178 g_array_append_vals(*out, &app_idx, sizeof(uint16_t));
184 bool _bt_mesh_keys_get_new_netkey_index(uint8_t net_uuid[],
187 struct mesh_net_key_t *key;
188 struct mesh_network_t *network;
190 network = l_queue_find(networks,
191 __mesh_net_uuid_match, net_uuid);
195 if (l_queue_length(network->net_keys)) {
196 key = l_queue_peek_tail(network->net_keys);
199 *net_idx = key->idx + 1;
206 bool _bt_mesh_keys_get_new_appkey_index(uint8_t net_uuid[],
209 const struct l_queue_entry *l;
210 struct mesh_network_t *network;
213 network = l_queue_find(networks, __mesh_net_uuid_match, net_uuid);
217 if (!network->net_keys)
220 for (l = l_queue_get_entries(network->net_keys); l; l = l->next) {
221 struct mesh_net_key_t *key = l->data;
226 for (l = l_queue_get_entries(key->app_keys); l; l = l->next) {
227 uint16_t app_idx = L_PTR_TO_UINT(l->data);
228 if (app_idx > maxkey)
232 *app_idx = maxkey + 1;
237 bool _bt_mesh_keys_get_net_key_phase(uint8_t net_uuid[],
238 uint16_t net_idx, uint8_t *phase)
240 struct mesh_net_key_t *key;
241 struct mesh_network_t *network;
243 network = l_queue_find(networks,
244 __mesh_net_uuid_match, net_uuid);
248 if (!phase || !network->net_keys)
251 key = l_queue_find(network->net_keys, __mesh_net_idx_match,
252 L_UINT_TO_PTR(net_idx));
260 void _bt_mesh_keys_add_app_key(uint8_t net_uuid[],
261 uint16_t net_idx, uint16_t app_idx)
263 struct mesh_net_key_t *key;
264 struct mesh_network_t *network;
266 network = l_queue_find(networks, __mesh_net_uuid_match, net_uuid);
270 if (!network->net_keys)
273 key = l_queue_find(network->net_keys, __mesh_net_idx_match,
274 L_UINT_TO_PTR(net_idx));
279 key->app_keys = l_queue_new();
281 if (__mesh_app_key_present(key, app_idx))
284 l_queue_push_tail(key->app_keys, L_UINT_TO_PTR(app_idx));
287 void _bt_mesh_keys_del_app_key(uint8_t net_uuid[], uint16_t app_idx)
289 const struct l_queue_entry *l;
290 struct mesh_network_t *network;
292 network = l_queue_find(networks, __mesh_net_uuid_match, net_uuid);
296 if (!network->net_keys)
299 for (l = l_queue_get_entries(network->net_keys); l; l = l->next) {
300 struct mesh_net_key_t *key = l->data;
305 if (l_queue_remove(key->app_keys, L_UINT_TO_PTR(app_idx)))
310 uint16_t _bt_mesh_keys_get_bound_key(uint8_t net_uuid[], uint16_t app_idx)
312 const struct l_queue_entry *l;
313 struct mesh_network_t *network;
315 network = l_queue_find(networks, __mesh_net_uuid_match, net_uuid);
317 return MESH_NET_IDX_INVALID;
319 if (!network->net_keys)
320 return MESH_NET_IDX_INVALID;
322 for (l = l_queue_get_entries(network->net_keys); l; l = l->next) {
323 struct mesh_net_key_t *key = l->data;
328 if (__mesh_app_key_present(key, app_idx))
332 return MESH_NET_IDX_INVALID;
335 bool _bt_mesh_keys_subnet_exists(uint8_t net_uuid[], uint16_t idx)
337 struct mesh_network_t *network;
339 network = l_queue_find(networks, __mesh_net_uuid_match, net_uuid);
343 if (!l_queue_find(network->net_keys, __mesh_net_idx_match,