| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215 |
- // SPDX-License-Identifier: LGPL-2.1-or-later
- /*
- *
- * BlueZ - Bluetooth protocol stack for Linux
- *
- * Copyright (C) 2019 Intel Corporation. All rights reserved.
- *
- *
- */
- #ifdef HAVE_CONFIG_H
- #include <config.h>
- #endif
- #include <ell/ell.h>
- #include "src/shared/shell.h"
- #include "mesh/mesh-defs.h"
- #include "tools/mesh/mesh-db.h"
- #include "tools/mesh/keys.h"
- struct net_key {
- struct l_queue *app_keys;
- uint16_t idx;
- uint8_t phase;
- };
- static struct l_queue *net_keys;
- static bool app_key_present(const struct net_key *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 net_idx_match(const void *a, const void *b)
- {
- const struct net_key *key = a;
- uint32_t idx = L_PTR_TO_UINT(b);
- return key->idx == idx;
- }
- static void delete_bound_appkey(void *a)
- {
- uint32_t idx = L_PTR_TO_UINT(a);
- mesh_db_del_app_key(idx);
- }
- void keys_add_net_key(uint16_t net_idx)
- {
- struct net_key *key;
- if (!net_keys)
- net_keys = l_queue_new();
- if (l_queue_find(net_keys, net_idx_match, L_UINT_TO_PTR(net_idx)))
- return;
- key = l_new(struct net_key, 1);
- key->idx = net_idx;
- key->phase = KEY_REFRESH_PHASE_NONE;
- l_queue_push_tail(net_keys, key);
- }
- void keys_del_net_key(uint16_t idx)
- {
- struct net_key *key;
- if (!net_keys)
- return;
- key = l_queue_remove_if(net_keys, net_idx_match, L_UINT_TO_PTR(idx));
- if (!key)
- return;
- l_queue_destroy(key->app_keys, delete_bound_appkey);
- l_free(key);
- }
- void keys_set_net_key_phase(uint16_t net_idx, uint8_t phase, bool save)
- {
- struct net_key *key;
- if (!net_keys)
- return;
- key = l_queue_find(net_keys, net_idx_match, L_UINT_TO_PTR(net_idx));
- if (!key)
- return;
- key->phase = phase;
- if (save && !mesh_db_set_net_key_phase(net_idx, phase))
- bt_shell_printf("Failed to save updated KR phase\n");
- }
- bool keys_get_net_key_phase(uint16_t net_idx, uint8_t *phase)
- {
- struct net_key *key;
- if (!phase || !net_keys)
- return false;
- key = l_queue_find(net_keys, net_idx_match, L_UINT_TO_PTR(net_idx));
- if (!key)
- return false;
- *phase = key->phase;
- return true;
- }
- void keys_add_app_key(uint16_t net_idx, uint16_t app_idx)
- {
- struct net_key *key;
- if (!net_keys)
- return;
- key = l_queue_find(net_keys, net_idx_match, L_UINT_TO_PTR(net_idx));
- if (!key)
- return;
- if (!key->app_keys)
- key->app_keys = l_queue_new();
- if (app_key_present(key, app_idx))
- return;
- l_queue_push_tail(key->app_keys, L_UINT_TO_PTR(app_idx));
- }
- void keys_del_app_key(uint16_t app_idx)
- {
- const struct l_queue_entry *l;
- if (!net_keys)
- return;
- for (l = l_queue_get_entries(net_keys); l; l = l->next) {
- struct net_key *key = l->data;
- if (!key->app_keys)
- continue;
- if (l_queue_remove(key->app_keys, L_UINT_TO_PTR(app_idx)))
- return;
- }
- }
- uint16_t keys_get_bound_key(uint16_t app_idx)
- {
- const struct l_queue_entry *l;
- if (!net_keys)
- return NET_IDX_INVALID;
- for (l = l_queue_get_entries(net_keys); l; l = l->next) {
- struct net_key *key = l->data;
- if (!key->app_keys)
- continue;
- if (app_key_present(key, app_idx))
- return key->idx;
- }
- return NET_IDX_INVALID;
- }
- static void print_appkey(void *app_key, void *user_data)
- {
- uint16_t app_idx = L_PTR_TO_UINT(app_key);
- bt_shell_printf("%u (0x%3.3x), ", app_idx, app_idx);
- }
- static void print_netkey(void *net_key, void *user_data)
- {
- struct net_key *key = net_key;
- bt_shell_printf(COLOR_YELLOW "NetKey: %u (0x%3.3x), phase: %u\n"
- COLOR_OFF, key->idx, key->idx, key->phase);
- if (!key->app_keys || l_queue_isempty(key->app_keys))
- return;
- bt_shell_printf("\t" COLOR_GREEN "app_keys = ");
- l_queue_foreach(key->app_keys, print_appkey, NULL);
- bt_shell_printf("\n" COLOR_OFF);
- }
- void keys_print_keys(void)
- {
- l_queue_foreach(net_keys, print_netkey, NULL);
- }
- bool keys_subnet_exists(uint16_t idx)
- {
- if (!l_queue_find(net_keys, net_idx_match, L_UINT_TO_PTR(idx)))
- return false;
- return true;
- }
|