1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217
|
// 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 <time.h>
#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;
}
|