1f4854a5eSMatthias Ringwald /* 2f4854a5eSMatthias Ringwald * Copyright (C) 2019 BlueKitchen GmbH 3f4854a5eSMatthias Ringwald * 4f4854a5eSMatthias Ringwald * Redistribution and use in source and binary forms, with or without 5f4854a5eSMatthias Ringwald * modification, are permitted provided that the following conditions 6f4854a5eSMatthias Ringwald * are met: 7f4854a5eSMatthias Ringwald * 8f4854a5eSMatthias Ringwald * 1. Redistributions of source code must retain the above copyright 9f4854a5eSMatthias Ringwald * notice, this list of conditions and the following disclaimer. 10f4854a5eSMatthias Ringwald * 2. Redistributions in binary form must reproduce the above copyright 11f4854a5eSMatthias Ringwald * notice, this list of conditions and the following disclaimer in the 12f4854a5eSMatthias Ringwald * documentation and/or other materials provided with the distribution. 13f4854a5eSMatthias Ringwald * 3. Neither the name of the copyright holders nor the names of 14f4854a5eSMatthias Ringwald * contributors may be used to endorse or promote products derived 15f4854a5eSMatthias Ringwald * from this software without specific prior written permission. 16f4854a5eSMatthias Ringwald * 4. Any redistribution, use, or modification is done solely for 17f4854a5eSMatthias Ringwald * personal benefit and not for any commercial purpose or for 18f4854a5eSMatthias Ringwald * monetary gain. 19f4854a5eSMatthias Ringwald * 20f4854a5eSMatthias Ringwald * THIS SOFTWARE IS PROVIDED BY BLUEKITCHEN GMBH AND CONTRIBUTORS 21f4854a5eSMatthias Ringwald * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 22f4854a5eSMatthias Ringwald * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 23f4854a5eSMatthias Ringwald * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL MATTHIAS 24f4854a5eSMatthias Ringwald * RINGWALD OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 25f4854a5eSMatthias Ringwald * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 26f4854a5eSMatthias Ringwald * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS 27f4854a5eSMatthias Ringwald * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 28f4854a5eSMatthias Ringwald * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 29f4854a5eSMatthias Ringwald * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF 30f4854a5eSMatthias Ringwald * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31f4854a5eSMatthias Ringwald * SUCH DAMAGE. 32f4854a5eSMatthias Ringwald * 33f4854a5eSMatthias Ringwald * Please inquire about commercial licensing options at 34f4854a5eSMatthias Ringwald * [email protected] 35f4854a5eSMatthias Ringwald * 36f4854a5eSMatthias Ringwald */ 37f4854a5eSMatthias Ringwald 382d4000d1SMatthias Ringwald #define BTSTACK_FILE__ "mesh_keys.c" 39f4854a5eSMatthias Ringwald 40f4854a5eSMatthias Ringwald #include <string.h> 41f4854a5eSMatthias Ringwald #include <stdio.h> 42f4854a5eSMatthias Ringwald 43f4854a5eSMatthias Ringwald #include "mesh/mesh_keys.h" 44f4854a5eSMatthias Ringwald 45f4854a5eSMatthias Ringwald #include "btstack_util.h" 46f4854a5eSMatthias Ringwald #include "btstack_memory.h" 47f4854a5eSMatthias Ringwald #include "btstack_config.h" 48f4854a5eSMatthias Ringwald 49f4854a5eSMatthias Ringwald // network key list 50f4854a5eSMatthias Ringwald static btstack_linked_list_t network_keys; 51f4854a5eSMatthias Ringwald static uint8_t mesh_network_key_used[MAX_NR_MESH_NETWORK_KEYS]; 52f4854a5eSMatthias Ringwald 53f4854a5eSMatthias Ringwald void mesh_network_key_init(void){ 54f4854a5eSMatthias Ringwald network_keys = NULL; 55f4854a5eSMatthias Ringwald } 56f4854a5eSMatthias Ringwald 57f4854a5eSMatthias Ringwald uint16_t mesh_network_key_get_free_index(void){ 58f4854a5eSMatthias Ringwald uint16_t i; 590500a934SMatthias Ringwald for (i=0;i < MAX_NR_MESH_NETWORK_KEYS ; i++){ 60f4854a5eSMatthias Ringwald if (mesh_network_key_used[i] == 0){ 61f4854a5eSMatthias Ringwald return i; 62f4854a5eSMatthias Ringwald } 63f4854a5eSMatthias Ringwald } 640500a934SMatthias Ringwald return MESH_KEYS_INVALID_INDEX; 65f4854a5eSMatthias Ringwald } 66f4854a5eSMatthias Ringwald 67f4854a5eSMatthias Ringwald void mesh_network_key_add(mesh_network_key_t * network_key){ 68f4854a5eSMatthias Ringwald mesh_network_key_used[network_key->internal_index] = 1; 69f4854a5eSMatthias Ringwald btstack_linked_list_add_tail(&network_keys, (btstack_linked_item_t *) network_key); 70f4854a5eSMatthias Ringwald } 71f4854a5eSMatthias Ringwald 72*d58a1b5fSMatthias Ringwald bool mesh_network_key_remove(mesh_network_key_t * network_key){ 735d07e701SMatthias Ringwald mesh_network_key_used[network_key->internal_index] = 0; 74f4854a5eSMatthias Ringwald return btstack_linked_list_remove(&network_keys, (btstack_linked_item_t *) network_key); 75f4854a5eSMatthias Ringwald } 76f4854a5eSMatthias Ringwald 77f4854a5eSMatthias Ringwald mesh_network_key_t * mesh_network_key_list_get(uint16_t netkey_index){ 78f4854a5eSMatthias Ringwald btstack_linked_list_iterator_t it; 79f4854a5eSMatthias Ringwald btstack_linked_list_iterator_init(&it, &network_keys); 80f4854a5eSMatthias Ringwald while (btstack_linked_list_iterator_has_next(&it)){ 81f4854a5eSMatthias Ringwald mesh_network_key_t * item = (mesh_network_key_t *) btstack_linked_list_iterator_next(&it); 82f4854a5eSMatthias Ringwald if (item->netkey_index == netkey_index) return item; 83f4854a5eSMatthias Ringwald } 84f4854a5eSMatthias Ringwald return NULL; 85f4854a5eSMatthias Ringwald } 86f4854a5eSMatthias Ringwald 87f4854a5eSMatthias Ringwald int mesh_network_key_list_count(void){ 88f4854a5eSMatthias Ringwald return btstack_linked_list_count(&network_keys); 89f4854a5eSMatthias Ringwald } 90f4854a5eSMatthias Ringwald 91f4854a5eSMatthias Ringwald // mesh network key iterator over all keys 92f4854a5eSMatthias Ringwald void mesh_network_key_iterator_init(mesh_network_key_iterator_t *it){ 93f4854a5eSMatthias Ringwald btstack_linked_list_iterator_init(&it->it, &network_keys); 94f4854a5eSMatthias Ringwald } 95f4854a5eSMatthias Ringwald 96f4854a5eSMatthias Ringwald int mesh_network_key_iterator_has_more(mesh_network_key_iterator_t *it){ 97f4854a5eSMatthias Ringwald return btstack_linked_list_iterator_has_next(&it->it); 98f4854a5eSMatthias Ringwald } 99f4854a5eSMatthias Ringwald 100f4854a5eSMatthias Ringwald mesh_network_key_t * mesh_network_key_iterator_get_next(mesh_network_key_iterator_t *it){ 101f4854a5eSMatthias Ringwald return (mesh_network_key_t *) btstack_linked_list_iterator_next(&it->it); 102f4854a5eSMatthias Ringwald } 103f4854a5eSMatthias Ringwald 104f4854a5eSMatthias Ringwald // mesh network key iterator for a given nid 105f4854a5eSMatthias Ringwald void mesh_network_key_nid_iterator_init(mesh_network_key_iterator_t *it, uint8_t nid){ 106f4854a5eSMatthias Ringwald btstack_linked_list_iterator_init(&it->it, &network_keys); 107f4854a5eSMatthias Ringwald it->key = NULL; 108f4854a5eSMatthias Ringwald it->nid = nid; 109f4854a5eSMatthias Ringwald } 110f4854a5eSMatthias Ringwald 111f4854a5eSMatthias Ringwald int mesh_network_key_nid_iterator_has_more(mesh_network_key_iterator_t *it){ 112f4854a5eSMatthias Ringwald // find next matching key 113f4854a5eSMatthias Ringwald while (1){ 114f4854a5eSMatthias Ringwald if (it->key && it->key->nid == it->nid) return 1; 115f4854a5eSMatthias Ringwald if (!btstack_linked_list_iterator_has_next(&it->it)) break; 116f4854a5eSMatthias Ringwald it->key = (mesh_network_key_t *) btstack_linked_list_iterator_next(&it->it); 117f4854a5eSMatthias Ringwald } 118f4854a5eSMatthias Ringwald return 0; 119f4854a5eSMatthias Ringwald } 120f4854a5eSMatthias Ringwald 121f4854a5eSMatthias Ringwald mesh_network_key_t * mesh_network_key_nid_iterator_get_next(mesh_network_key_iterator_t *it){ 122f4854a5eSMatthias Ringwald mesh_network_key_t * key = it->key; 123f4854a5eSMatthias Ringwald it->key = NULL; 124f4854a5eSMatthias Ringwald return key; 125f4854a5eSMatthias Ringwald } 126f4854a5eSMatthias Ringwald 127f4854a5eSMatthias Ringwald 128f4854a5eSMatthias Ringwald // application key list 129f4854a5eSMatthias Ringwald 130f4854a5eSMatthias Ringwald // key management 131f4854a5eSMatthias Ringwald static mesh_transport_key_t mesh_transport_device_key; 132f4854a5eSMatthias Ringwald static btstack_linked_list_t application_keys; 133f4854a5eSMatthias Ringwald 134f4854a5eSMatthias Ringwald static uint8_t mesh_transport_key_used[MAX_NR_MESH_TRANSPORT_KEYS]; 135f4854a5eSMatthias Ringwald 136f4854a5eSMatthias Ringwald void mesh_transport_set_device_key(const uint8_t * device_key){ 137f4854a5eSMatthias Ringwald mesh_transport_device_key.appkey_index = MESH_DEVICE_KEY_INDEX; 138f4854a5eSMatthias Ringwald mesh_transport_device_key.aid = 0; 139f4854a5eSMatthias Ringwald mesh_transport_device_key.akf = 0; 140f4854a5eSMatthias Ringwald mesh_transport_device_key.netkey_index = 0; // unused 141f4854a5eSMatthias Ringwald memcpy(mesh_transport_device_key.key, device_key, 16); 142f4854a5eSMatthias Ringwald 143f4854a5eSMatthias Ringwald // use internal slot #0 144f4854a5eSMatthias Ringwald mesh_transport_device_key.internal_index = 0; 145f4854a5eSMatthias Ringwald mesh_transport_key_used[0] = 1; 146f4854a5eSMatthias Ringwald } 147f4854a5eSMatthias Ringwald 148f4854a5eSMatthias Ringwald uint16_t mesh_transport_key_get_free_index(void){ 149f4854a5eSMatthias Ringwald // find empty slot, skip slot #0 reserved for device key 150f4854a5eSMatthias Ringwald uint16_t i; 151f4854a5eSMatthias Ringwald for (i=1;i < MAX_NR_MESH_TRANSPORT_KEYS ; i++){ 152f4854a5eSMatthias Ringwald if (mesh_transport_key_used[i] == 0){ 153f4854a5eSMatthias Ringwald return i; 154f4854a5eSMatthias Ringwald } 155f4854a5eSMatthias Ringwald } 156f4854a5eSMatthias Ringwald return 0; 157f4854a5eSMatthias Ringwald } 158f4854a5eSMatthias Ringwald 159f4854a5eSMatthias Ringwald void mesh_transport_key_add(mesh_transport_key_t * transport_key){ 160f4854a5eSMatthias Ringwald mesh_transport_key_used[transport_key->internal_index] = 1; 161f4854a5eSMatthias Ringwald btstack_linked_list_add_tail(&application_keys, (btstack_linked_item_t *) transport_key); 162f4854a5eSMatthias Ringwald } 163f4854a5eSMatthias Ringwald 164*d58a1b5fSMatthias Ringwald bool mesh_transport_key_remove(mesh_transport_key_t * transport_key){ 165f4854a5eSMatthias Ringwald mesh_transport_key_used[transport_key->internal_index] = 0; 166f4854a5eSMatthias Ringwald return btstack_linked_list_remove(&application_keys, (btstack_linked_item_t *) transport_key); 167f4854a5eSMatthias Ringwald } 168f4854a5eSMatthias Ringwald 169f4854a5eSMatthias Ringwald mesh_transport_key_t * mesh_transport_key_get(uint16_t appkey_index){ 170f4854a5eSMatthias Ringwald if (appkey_index == MESH_DEVICE_KEY_INDEX){ 171f4854a5eSMatthias Ringwald return &mesh_transport_device_key; 172f4854a5eSMatthias Ringwald } 173f4854a5eSMatthias Ringwald btstack_linked_list_iterator_t it; 174f4854a5eSMatthias Ringwald btstack_linked_list_iterator_init(&it, &application_keys); 175f4854a5eSMatthias Ringwald while (btstack_linked_list_iterator_has_next(&it)){ 176f4854a5eSMatthias Ringwald mesh_transport_key_t * item = (mesh_transport_key_t *) btstack_linked_list_iterator_next(&it); 177f4854a5eSMatthias Ringwald if (item->appkey_index == appkey_index) return item; 178f4854a5eSMatthias Ringwald } 179f4854a5eSMatthias Ringwald return NULL; 180f4854a5eSMatthias Ringwald } 181f4854a5eSMatthias Ringwald 182f4854a5eSMatthias Ringwald // key iterator 183f4854a5eSMatthias Ringwald void mesh_transport_key_iterator_init(mesh_transport_key_iterator_t *it, uint16_t netkey_index){ 184f4854a5eSMatthias Ringwald btstack_linked_list_iterator_init(&it->it, &application_keys); 185f4854a5eSMatthias Ringwald it->netkey_index = netkey_index; 186f4854a5eSMatthias Ringwald it->key = NULL; 187f4854a5eSMatthias Ringwald } 188f4854a5eSMatthias Ringwald 189f4854a5eSMatthias Ringwald int mesh_transport_key_iterator_has_more(mesh_transport_key_iterator_t *it){ 190f4854a5eSMatthias Ringwald // find next matching key 191f4854a5eSMatthias Ringwald while (1){ 192f4854a5eSMatthias Ringwald if (it->key && it->key->netkey_index == it->netkey_index) return 1; 193f4854a5eSMatthias Ringwald if (!btstack_linked_list_iterator_has_next(&it->it)) break; 194f4854a5eSMatthias Ringwald it->key = (mesh_transport_key_t *) btstack_linked_list_iterator_next(&it->it); 195f4854a5eSMatthias Ringwald } 196f4854a5eSMatthias Ringwald return 0; 197f4854a5eSMatthias Ringwald } 198f4854a5eSMatthias Ringwald 199f4854a5eSMatthias Ringwald mesh_transport_key_t * mesh_transport_key_iterator_get_next(mesh_transport_key_iterator_t *it){ 200f4854a5eSMatthias Ringwald mesh_transport_key_t * key = it->key; 201f4854a5eSMatthias Ringwald it->key = NULL; 202f4854a5eSMatthias Ringwald return key; 203f4854a5eSMatthias Ringwald } 204f4854a5eSMatthias Ringwald 205f4854a5eSMatthias Ringwald void 206f4854a5eSMatthias Ringwald mesh_transport_key_aid_iterator_init(mesh_transport_key_iterator_t *it, uint16_t netkey_index, uint8_t akf, uint8_t aid) { 207f4854a5eSMatthias Ringwald btstack_linked_list_iterator_init(&it->it, &application_keys); 208f4854a5eSMatthias Ringwald it->netkey_index = netkey_index; 209f4854a5eSMatthias Ringwald it->aid = aid; 210f4854a5eSMatthias Ringwald it->akf = akf; 211f4854a5eSMatthias Ringwald if (it->akf){ 212f4854a5eSMatthias Ringwald it->key = NULL; 213f4854a5eSMatthias Ringwald } else { 214f4854a5eSMatthias Ringwald it->key = &mesh_transport_device_key; 215f4854a5eSMatthias Ringwald } 216f4854a5eSMatthias Ringwald } 217f4854a5eSMatthias Ringwald 218f4854a5eSMatthias Ringwald int mesh_transport_key_aid_iterator_has_more(mesh_transport_key_iterator_t *it){ 219f4854a5eSMatthias Ringwald if (it->akf == 0){ 220f4854a5eSMatthias Ringwald return it->key != NULL; 221f4854a5eSMatthias Ringwald } 222f4854a5eSMatthias Ringwald // find next matching key 223f4854a5eSMatthias Ringwald while (1){ 224f4854a5eSMatthias Ringwald if (it->key && it->key->aid == it->aid && it->key->netkey_index == it->netkey_index) return 1; 225f4854a5eSMatthias Ringwald if (!btstack_linked_list_iterator_has_next(&it->it)) break; 226f4854a5eSMatthias Ringwald it->key = (mesh_transport_key_t *) btstack_linked_list_iterator_next(&it->it); 227f4854a5eSMatthias Ringwald } 228f4854a5eSMatthias Ringwald return 0; 229f4854a5eSMatthias Ringwald } 230f4854a5eSMatthias Ringwald 231f4854a5eSMatthias Ringwald mesh_transport_key_t * mesh_transport_key_aid_iterator_get_next(mesh_transport_key_iterator_t *it){ 232f4854a5eSMatthias Ringwald mesh_transport_key_t * key = it->key; 233f4854a5eSMatthias Ringwald it->key = NULL; 234f4854a5eSMatthias Ringwald return key; 235f4854a5eSMatthias Ringwald } 236