From 9a0448ab613f351d0bdbb456be43683886d6a8cd Mon Sep 17 00:00:00 2001 From: Anupam Roy Date: Fri, 17 Jul 2020 15:44:19 +0530 Subject: [PATCH] Mesh: Management of Keys in a local Network This patch adds Local Key Management methods. Some of the key methods are following. - Create & manage Netkeys & appkeys - Get NetKey list in a Network - Get AppKey list bound to a NetKey in a network - Get new Netkey and Appkey indecesMesh: Management of Keys in a local Network This patch adds Local Key Management methods. Some of the key methods are following. - Create & manage Netkeys & appkeys - Get NetKey list in a Network - Get AppKey list bound to a NetKey in a network - Get new Netkey and Appkey indeces Change-Id: Ib752432f4908f33c260177956a2b15b15fccf316 Signed-off-by: Anupam Roy --- bt-service/CMakeLists.txt | 1 + bt-service/services/include/bt-service-mesh-keys.h | 61 ++++ bt-service/services/mesh/bt-service-mesh-keys.c | 348 +++++++++++++++++++++ 3 files changed, 410 insertions(+) create mode 100644 bt-service/services/include/bt-service-mesh-keys.h create mode 100644 bt-service/services/mesh/bt-service-mesh-keys.c diff --git a/bt-service/CMakeLists.txt b/bt-service/CMakeLists.txt index 0bac7a4..a3cc685 100644 --- a/bt-service/CMakeLists.txt +++ b/bt-service/CMakeLists.txt @@ -32,6 +32,7 @@ SET(SRCS ./services/gatt/bt-service-gatt.c ./services/audio/hf/bt-service-hf-client.c ./services/mesh/bt-service-mesh-util.c +./services/mesh/bt-service-mesh-keys.c ) IF("$ENV{CFLAGS}" MATCHES "-DTIZEN_FEATURE_BT_OBEX") diff --git a/bt-service/services/include/bt-service-mesh-keys.h b/bt-service/services/include/bt-service-mesh-keys.h new file mode 100644 index 0000000..d6cd042 --- /dev/null +++ b/bt-service/services/include/bt-service-mesh-keys.h @@ -0,0 +1,61 @@ +/* + * Bluetooth-frwk + * + * Copyright (c) 2020 Samsung Electronics Co., Ltd. + * + * @author: Anupam Roy + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#ifndef BT_SERVICE_MESH_KEYS_H_ +#define BT_SERVICE_MESH_KEYS_H_ + +#include +#include +#include "bluetooth-api.h" +#include "bluetooth-mesh-api.h" +#include + +#ifdef __cplusplus +extern "C" { +#endif + +void _bt_mesh_keys_load_net(uint8_t net_uuid[]); +void _bt_mesh_keys_add_net_key(uint8_t net_uuid[], + uint16_t net_idx); +void _bt_mesh_keys_add_app_key(uint8_t net_uuid[], + uint16_t net_idx, uint16_t app_idx); +void _bt_mesh_keys_del_app_key(uint8_t net_uuid[], + uint16_t app_idx); +uint16_t _bt_mesh_keys_get_bound_key(uint8_t net_uuid[], + uint16_t app_idx); +bool _bt_mesh_keys_subnet_exists(uint8_t net_uuid[], + uint16_t idx); +void _bt_mesh_keys_print_keys(uint8_t net_uuid[]); +bool _bt_mesh_keys_get_new_netkey_index(uint8_t net_uuid[], + uint16_t *net_idx); +bool _bt_mesh_keys_get_new_appkey_index(uint8_t net_uuid[], + uint16_t *app_idx); +bool _bt_mesh_keys_is_netkey_present(uint8_t net_uuid[], + uint16_t net_idx); +bool _bt_mesh_keys_get_netkey_list(uint8_t net_uuid[], + GArray **out); +bool _bt_mesh_keys_get_appkey_list(uint8_t net_uuid[], + uint16_t net_idx, GArray **out); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif /* BT_SERVICE_MESH_KEYS_H_ */ diff --git a/bt-service/services/mesh/bt-service-mesh-keys.c b/bt-service/services/mesh/bt-service-mesh-keys.c new file mode 100644 index 0000000..0b54fb4 --- /dev/null +++ b/bt-service/services/mesh/bt-service-mesh-keys.c @@ -0,0 +1,348 @@ +/* + * Bluetooth-frwk + * + * Copyright (c) 2020 Samsung Electronics Co., Ltd. + * + * @author: Anupam Roy + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +#include +#include +#include "bt-service-common.h" +#include "bluetooth-api.h" + +#include "bluetooth-mesh-api.h" +#include "bt-internal-types.h" +#include "bt-service-util.h" +#include "bt-service-common.h" +#include "bt-service-event.h" +#include "bt-service-mesh-keys.h" +#include "bt-service-mesh-util.h" + +#include "bt-internal-types.h" + +#include + +/* An instance of a Mesh Network Key */ +struct mesh_net_key_t { + struct l_queue *app_keys; + uint16_t idx; + uint8_t phase; +}; + +/* An instance of a Mesh network */ +struct mesh_network_t { + uint8_t net_uuid[16]; + struct l_queue *net_keys; +}; + +static struct l_queue *networks; + +static bool __mesh_net_uuid_match(const void *a, const void *b) +{ + const struct mesh_network_t *net = a; + uint8_t* uuid = (uint8_t*)b; + + if (memcmp(net->net_uuid, uuid, 16) == 0) { + BT_INFO("Mesh: Found network with given Net UUID"); + return true; + } + + return false; +} + +static bool __mesh_app_key_present(const struct mesh_net_key_t *key, + uint16_t app_idx) +{ + const struct l_queue_entry *l; + + for (l = l_queue_get_entries(key->app_keys); l; l = l->next) { + uint16_t idx = L_PTR_TO_UINT(l->data); + + if (idx == app_idx) + return true; + } + + return false; +} + +static bool __mesh_net_idx_match(const void *a, const void *b) +{ + const struct mesh_net_key_t *key = a; + uint32_t idx = L_PTR_TO_UINT(b); + + return key->idx == idx; +} + +void _bt_mesh_keys_load_net(uint8_t net_uuid[]) +{ + struct mesh_network_t *network; + BT_INFO("Mesh:Keys: Create new network"); + + if (l_queue_find(networks, __mesh_net_uuid_match, net_uuid)) + return; + + if (!networks) + networks = l_queue_new(); + + network = l_new(struct mesh_network_t, 1); + memcpy(network->net_uuid, net_uuid, 16); + network->net_keys = l_queue_new(); + l_queue_push_tail(networks, network); +} + +void _bt_mesh_keys_add_net_key(uint8_t net_uuid[], uint16_t net_idx) +{ + struct mesh_net_key_t *key; + struct mesh_network_t *network; + BT_INFO("Mesh:Keys: Create new netkey for Network KeyIDx [%u]", + net_idx); + + network = l_queue_find(networks, __mesh_net_uuid_match, net_uuid); + if (!network) + return; + + if (l_queue_find(network->net_keys, __mesh_net_idx_match, + L_UINT_TO_PTR(net_idx))) + return; + + key = l_new(struct mesh_net_key_t , 1); + key->idx = net_idx; + key->phase = MESH_KEY_REFRESH_PHASE_NONE; + + l_queue_push_tail(network->net_keys, key); +} + +bool _bt_mesh_keys_is_netkey_present(uint8_t net_uuid[], uint16_t net_idx) +{ + struct mesh_network_t *network; + + network = l_queue_find(networks, __mesh_net_uuid_match, net_uuid); + if (!network) + return false; + if (!l_queue_find(network->net_keys, __mesh_net_idx_match, + L_UINT_TO_PTR(net_idx))) + return false; + return true; +} + +bool _bt_mesh_keys_get_netkey_list(uint8_t net_uuid[], GArray **out) +{ + struct mesh_network_t *network; + const struct l_queue_entry *l; + + network = l_queue_find(networks, __mesh_net_uuid_match, net_uuid); + if (!network) + return false; + + for (l = l_queue_get_entries(network->net_keys); l; l = l->next) { + const struct mesh_net_key_t *key = l->data; + + g_array_append_vals(*out, &key->idx, sizeof(uint16_t)); + } + + return true; +} + +bool _bt_mesh_keys_get_appkey_list(uint8_t net_uuid[], + uint16_t net_idx, GArray **out) +{ + struct mesh_network_t *network; + struct mesh_net_key_t *netkey; + const struct l_queue_entry *l; + + network = l_queue_find(networks, __mesh_net_uuid_match, net_uuid); + if (!network) + return false; + + netkey = l_queue_find(network->net_keys, + __mesh_net_idx_match, L_UINT_TO_PTR(net_idx)); + if (!netkey) + return false; + + for (l = l_queue_get_entries(netkey->app_keys); l; l = l->next) { + uint16_t app_idx = L_PTR_TO_UINT(l->data); + + g_array_append_vals(*out, &app_idx, sizeof(uint16_t)); + } + + return true; +} + +bool _bt_mesh_keys_get_new_netkey_index(uint8_t net_uuid[], + uint16_t *net_idx) +{ + struct mesh_net_key_t *key; + struct mesh_network_t *network; + + network = l_queue_find(networks, + __mesh_net_uuid_match, net_uuid); + if (!network) + return false; + + if (l_queue_length(network->net_keys)) { + key = l_queue_peek_tail(network->net_keys); + if (!key) + return false; + *net_idx = key->idx + 1; + } else + return false; + + return true; +} + +bool _bt_mesh_keys_get_new_appkey_index(uint8_t net_uuid[], + uint16_t *app_idx) +{ + const struct l_queue_entry *l; + struct mesh_network_t *network; + int maxkey = -1; + + network = l_queue_find(networks, __mesh_net_uuid_match, net_uuid); + if (!network) + return false; + + if (!network->net_keys) + return false; + + for (l = l_queue_get_entries(network->net_keys); l; l = l->next) { + struct mesh_net_key_t *key = l->data; + + if (!key->app_keys) + continue; + + for (l = l_queue_get_entries(key->app_keys); l; l = l->next) { + uint16_t app_idx = L_PTR_TO_UINT(l->data); + if (app_idx > maxkey) + maxkey = app_idx; + } + } + *app_idx = maxkey + 1; + + return true; +} + +bool _bt_mesh_keys_get_net_key_phase(uint8_t net_uuid[], + uint16_t net_idx, uint8_t *phase) +{ + struct mesh_net_key_t *key; + struct mesh_network_t *network; + + network = l_queue_find(networks, + __mesh_net_uuid_match, net_uuid); + if (!network) + return false; + + if (!phase || !network->net_keys) + return false; + + key = l_queue_find(network->net_keys, __mesh_net_idx_match, + L_UINT_TO_PTR(net_idx)); + if (!key) + return false; + + *phase = key->phase; + return true; +} + +void _bt_mesh_keys_add_app_key(uint8_t net_uuid[], + uint16_t net_idx, uint16_t app_idx) +{ + struct mesh_net_key_t *key; + struct mesh_network_t *network; + + network = l_queue_find(networks, __mesh_net_uuid_match, net_uuid); + if (!network) + return; + + if (!network->net_keys) + return; + + key = l_queue_find(network->net_keys, __mesh_net_idx_match, + L_UINT_TO_PTR(net_idx)); + if (!key) + return; + + if (!key->app_keys) + key->app_keys = l_queue_new(); + + if (__mesh_app_key_present(key, app_idx)) + return; + + l_queue_push_tail(key->app_keys, L_UINT_TO_PTR(app_idx)); +} + +void _bt_mesh_keys_del_app_key(uint8_t net_uuid[], uint16_t app_idx) +{ + const struct l_queue_entry *l; + struct mesh_network_t *network; + + network = l_queue_find(networks, __mesh_net_uuid_match, net_uuid); + if (!network) + return; + + if (!network->net_keys) + return; + + for (l = l_queue_get_entries(network->net_keys); l; l = l->next) { + struct mesh_net_key_t *key = l->data; + + if (!key->app_keys) + continue; + + if (l_queue_remove(key->app_keys, L_UINT_TO_PTR(app_idx))) + return; + } +} + +uint16_t _bt_mesh_keys_get_bound_key(uint8_t net_uuid[], uint16_t app_idx) +{ + const struct l_queue_entry *l; + struct mesh_network_t *network; + + network = l_queue_find(networks, __mesh_net_uuid_match, net_uuid); + if (!network) + return MESH_NET_IDX_INVALID; + + if (!network->net_keys) + return MESH_NET_IDX_INVALID; + + for (l = l_queue_get_entries(network->net_keys); l; l = l->next) { + struct mesh_net_key_t *key = l->data; + + if (!key->app_keys) + continue; + + if (__mesh_app_key_present(key, app_idx)) + return key->idx; + } + + return MESH_NET_IDX_INVALID; +} + +bool _bt_mesh_keys_subnet_exists(uint8_t net_uuid[], uint16_t idx) +{ + struct mesh_network_t *network; + + network = l_queue_find(networks, __mesh_net_uuid_match, net_uuid); + if (!network) + return false; + + if (!l_queue_find(network->net_keys, __mesh_net_idx_match, + L_UINT_TO_PTR(idx))) + return false; + + return true; +} -- 2.7.4