Mesh: Management of Keys in a local Network
authorAnupam Roy <anupam.r@samsung.com>
Fri, 17 Jul 2020 10:14:19 +0000 (15:44 +0530)
committerAnupam Roy <anupam.r@samsung.com>
Fri, 17 Jul 2020 10:14:19 +0000 (15:44 +0530)
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 <anupam.r@samsung.com>
bt-service/CMakeLists.txt
bt-service/services/include/bt-service-mesh-keys.h [new file with mode: 0644]
bt-service/services/mesh/bt-service-mesh-keys.c [new file with mode: 0644]

index 0bac7a4..a3cc685 100644 (file)
@@ -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 (file)
index 0000000..d6cd042
--- /dev/null
@@ -0,0 +1,61 @@
+/*
+ * Bluetooth-frwk
+ *
+ * Copyright (c) 2020 Samsung Electronics Co., Ltd.
+ *
+ * @author: Anupam Roy <anupam.r@samsung.com>
+ *
+ * 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 <glib.h>
+#include <sys/types.h>
+#include "bluetooth-api.h"
+#include "bluetooth-mesh-api.h"
+#include <json-c/json.h>
+
+#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 (file)
index 0000000..0b54fb4
--- /dev/null
@@ -0,0 +1,348 @@
+/*
+ * Bluetooth-frwk
+ *
+ * Copyright (c) 2020 Samsung Electronics Co., Ltd.
+ *
+ * @author: Anupam Roy <anupam.r@samsung.com>
+ *
+ * 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 <glib.h>
+#include <dlog.h>
+#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 <ell/ell.h>
+
+/* 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;
+}