xref: /btstack/platform/posix/le_device_db_fs.c (revision ab2c6ae4b737d5e801d3defe4117331eb244ebb7)
19ed01c36SMatthias Ringwald /*
29ed01c36SMatthias Ringwald  * Copyright (C) 2014 BlueKitchen GmbH
39ed01c36SMatthias Ringwald  *
49ed01c36SMatthias Ringwald  * Redistribution and use in source and binary forms, with or without
59ed01c36SMatthias Ringwald  * modification, are permitted provided that the following conditions
69ed01c36SMatthias Ringwald  * are met:
79ed01c36SMatthias Ringwald  *
89ed01c36SMatthias Ringwald  * 1. Redistributions of source code must retain the above copyright
99ed01c36SMatthias Ringwald  *    notice, this list of conditions and the following disclaimer.
109ed01c36SMatthias Ringwald  * 2. Redistributions in binary form must reproduce the above copyright
119ed01c36SMatthias Ringwald  *    notice, this list of conditions and the following disclaimer in the
129ed01c36SMatthias Ringwald  *    documentation and/or other materials provided with the distribution.
139ed01c36SMatthias Ringwald  * 3. Neither the name of the copyright holders nor the names of
149ed01c36SMatthias Ringwald  *    contributors may be used to endorse or promote products derived
159ed01c36SMatthias Ringwald  *    from this software without specific prior written permission.
169ed01c36SMatthias Ringwald  * 4. Any redistribution, use, or modification is done solely for
179ed01c36SMatthias Ringwald  *    personal benefit and not for any commercial purpose or for
189ed01c36SMatthias Ringwald  *    monetary gain.
199ed01c36SMatthias Ringwald  *
209ed01c36SMatthias Ringwald  * THIS SOFTWARE IS PROVIDED BY BLUEKITCHEN GMBH AND CONTRIBUTORS
219ed01c36SMatthias Ringwald  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
229ed01c36SMatthias Ringwald  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
239ed01c36SMatthias Ringwald  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL MATTHIAS
249ed01c36SMatthias Ringwald  * RINGWALD OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
259ed01c36SMatthias Ringwald  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
269ed01c36SMatthias Ringwald  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
279ed01c36SMatthias Ringwald  * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
289ed01c36SMatthias Ringwald  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
299ed01c36SMatthias Ringwald  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
309ed01c36SMatthias Ringwald  * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
319ed01c36SMatthias Ringwald  * SUCH DAMAGE.
329ed01c36SMatthias Ringwald  *
339ed01c36SMatthias Ringwald  * Please inquire about commercial licensing options at
349ed01c36SMatthias Ringwald  * [email protected]
359ed01c36SMatthias Ringwald  *
369ed01c36SMatthias Ringwald  */
37*ab2c6ae4SMatthias Ringwald 
38*ab2c6ae4SMatthias Ringwald #define __BTSTACK_FILE__ "le_device_db_fs.c"
399ed01c36SMatthias Ringwald 
409ed01c36SMatthias Ringwald #include "ble/le_device_db.h"
419ed01c36SMatthias Ringwald 
429ed01c36SMatthias Ringwald #include "ble/core.h"
439ed01c36SMatthias Ringwald 
449ed01c36SMatthias Ringwald #include <stdio.h>
459ed01c36SMatthias Ringwald #include <string.h>
469ed01c36SMatthias Ringwald #include "btstack_debug.h"
479ed01c36SMatthias Ringwald 
489ed01c36SMatthias Ringwald // Central Device db implemenation using static memory
499ed01c36SMatthias Ringwald typedef struct le_device_memory_db {
509ed01c36SMatthias Ringwald 
519ed01c36SMatthias Ringwald     // Identification
529ed01c36SMatthias Ringwald     int addr_type;
539ed01c36SMatthias Ringwald     bd_addr_t addr;
549ed01c36SMatthias Ringwald     sm_key_t irk;
559ed01c36SMatthias Ringwald 
569ed01c36SMatthias Ringwald     // Stored pairing information allows to re-establish an enncrypted connection
579ed01c36SMatthias Ringwald     // with a peripheral that doesn't have any persistent memory
589ed01c36SMatthias Ringwald     sm_key_t ltk;
599ed01c36SMatthias Ringwald     uint16_t ediv;
609ed01c36SMatthias Ringwald     uint8_t  rand[8];
619ed01c36SMatthias Ringwald     uint8_t  key_size;
629ed01c36SMatthias Ringwald     uint8_t  authenticated;
639ed01c36SMatthias Ringwald     uint8_t  authorized;
649ed01c36SMatthias Ringwald 
65eda85fbfSMatthias Ringwald #ifdef ENABLE_LE_SIGNED_WRITE
669ed01c36SMatthias Ringwald     // Signed Writes by remote
679ed01c36SMatthias Ringwald     sm_key_t remote_csrk;
689ed01c36SMatthias Ringwald     uint32_t remote_counter;
699ed01c36SMatthias Ringwald 
709ed01c36SMatthias Ringwald     // Signed Writes by us
719ed01c36SMatthias Ringwald     sm_key_t local_csrk;
729ed01c36SMatthias Ringwald     uint32_t local_counter;
73eda85fbfSMatthias Ringwald #endif
749ed01c36SMatthias Ringwald 
759ed01c36SMatthias Ringwald } le_device_memory_db_t;
769ed01c36SMatthias Ringwald 
779ed01c36SMatthias Ringwald #define LE_DEVICE_MEMORY_SIZE 20
789ed01c36SMatthias Ringwald #define INVALID_ENTRY_ADDR_TYPE 0xff
79f33ad81dSMatthias Ringwald #define DB_PATH_TEMPLATE "/tmp/btstack_at_%s_le_device_db.txt"
809ed01c36SMatthias Ringwald const  char * csv_header = "# addr_type, addr, irk, ltk, ediv, rand[8], key_size, authenticated, authorized, remote_csrk, remote_counter, local_csrk, local_counter";
81f33ad81dSMatthias Ringwald static char db_path[sizeof(DB_PATH_TEMPLATE) - 2 + 17 + 1];
829ed01c36SMatthias Ringwald 
839ed01c36SMatthias Ringwald static le_device_memory_db_t le_devices[LE_DEVICE_MEMORY_SIZE];
849ed01c36SMatthias Ringwald 
85f33ad81dSMatthias Ringwald static char bd_addr_to_dash_str_buffer[6*3];  // 12-45-78-01-34-67\0
86f33ad81dSMatthias Ringwald static char * bd_addr_to_dash_str(bd_addr_t addr){
87f33ad81dSMatthias Ringwald     char * p = bd_addr_to_dash_str_buffer;
88f33ad81dSMatthias Ringwald     int i;
89f33ad81dSMatthias Ringwald     for (i = 0; i < 6 ; i++) {
90f33ad81dSMatthias Ringwald         *p++ = char_for_nibble((addr[i] >> 4) & 0x0F);
91f33ad81dSMatthias Ringwald         *p++ = char_for_nibble((addr[i] >> 0) & 0x0F);
92f33ad81dSMatthias Ringwald         *p++ = '-';
93f33ad81dSMatthias Ringwald     }
94f33ad81dSMatthias Ringwald     *--p = 0;
95f33ad81dSMatthias Ringwald     return (char *) bd_addr_to_dash_str_buffer;
96f33ad81dSMatthias Ringwald }
97f33ad81dSMatthias Ringwald 
989ed01c36SMatthias Ringwald static inline void write_delimiter(FILE * wFile){
999ed01c36SMatthias Ringwald     fwrite(", ", 1, 1, wFile);
1009ed01c36SMatthias Ringwald }
1019ed01c36SMatthias Ringwald static inline void write_hex_byte(FILE * wFile, uint8_t value){
1029ed01c36SMatthias Ringwald     char buffer[2];
1039ed01c36SMatthias Ringwald     buffer[0] = char_for_nibble(value >>   4);
1049ed01c36SMatthias Ringwald     buffer[1] = char_for_nibble(value & 0x0f);
1059ed01c36SMatthias Ringwald     fwrite(buffer, 2, 1, wFile);
1069ed01c36SMatthias Ringwald }
1079ed01c36SMatthias Ringwald 
1089ed01c36SMatthias Ringwald static inline void write_str(FILE * wFile, const char * str){
1099ed01c36SMatthias Ringwald     fwrite(str, strlen(str), 1, wFile);
1109ed01c36SMatthias Ringwald     write_delimiter(wFile);
1119ed01c36SMatthias Ringwald }
1129ed01c36SMatthias Ringwald static void write_hex(FILE * wFile, const uint8_t * value, int len){
1139ed01c36SMatthias Ringwald     int i;
1149ed01c36SMatthias Ringwald     for (i = 0; i < len; i++){
1159ed01c36SMatthias Ringwald         write_hex_byte(wFile, value[i]);
1169ed01c36SMatthias Ringwald     }
1179ed01c36SMatthias Ringwald     write_delimiter(wFile);
1189ed01c36SMatthias Ringwald }
1199ed01c36SMatthias Ringwald static void write_value(FILE * wFile, uint32_t value, int len){
1209ed01c36SMatthias Ringwald     switch (len){
1219ed01c36SMatthias Ringwald         case 4:
1229ed01c36SMatthias Ringwald             write_hex_byte(wFile, value >> 24);
1239ed01c36SMatthias Ringwald         case 3:
1249ed01c36SMatthias Ringwald             write_hex_byte(wFile, value >> 16);
1259ed01c36SMatthias Ringwald         case 2:
1269ed01c36SMatthias Ringwald             write_hex_byte(wFile, value >> 8);
1279ed01c36SMatthias Ringwald         case 1:
1289ed01c36SMatthias Ringwald         default:
1299ed01c36SMatthias Ringwald             write_hex_byte(wFile, value);
1309ed01c36SMatthias Ringwald     }
1319ed01c36SMatthias Ringwald     write_delimiter(wFile);
1329ed01c36SMatthias Ringwald }
1339ed01c36SMatthias Ringwald 
1349ed01c36SMatthias Ringwald static void le_device_db_store(void) {
1359ed01c36SMatthias Ringwald     int i;
1369ed01c36SMatthias Ringwald     // open file
1379ed01c36SMatthias Ringwald     FILE * wFile = fopen(db_path,"w+");
1389ed01c36SMatthias Ringwald     if (wFile == NULL) return;
1399ed01c36SMatthias Ringwald     fwrite(csv_header, strlen(csv_header), 1, wFile);
1409ed01c36SMatthias Ringwald     fwrite("\n", 1, 1, wFile);
1419ed01c36SMatthias Ringwald     for (i=0;i<LE_DEVICE_MEMORY_SIZE;i++){
1429ed01c36SMatthias Ringwald         if (le_devices[i].addr_type == INVALID_ENTRY_ADDR_TYPE) continue;
1439ed01c36SMatthias Ringwald         write_value(wFile, le_devices[i].addr_type, 1);
1449ed01c36SMatthias Ringwald         write_str(wFile,   bd_addr_to_str(le_devices[i].addr));
1459ed01c36SMatthias Ringwald         write_hex(wFile,   le_devices[i].irk, 16);
1469ed01c36SMatthias Ringwald         write_hex(wFile,   le_devices[i].ltk, 16);
1479ed01c36SMatthias Ringwald         write_value(wFile, le_devices[i].ediv, 2);
1489ed01c36SMatthias Ringwald         write_hex(wFile,   le_devices[i].rand, 8);
1499ed01c36SMatthias Ringwald         write_value(wFile, le_devices[i].key_size, 1);
1509ed01c36SMatthias Ringwald         write_value(wFile, le_devices[i].authenticated, 1);
1519ed01c36SMatthias Ringwald         write_value(wFile, le_devices[i].authorized, 1);
152eda85fbfSMatthias Ringwald #ifdef ENABLE_LE_SIGNED_WRITE
1539ed01c36SMatthias Ringwald         write_hex(wFile,   le_devices[i].remote_csrk, 16);
1549ed01c36SMatthias Ringwald         write_value(wFile, le_devices[i].remote_counter, 2);
1559ed01c36SMatthias Ringwald         write_hex(wFile,   le_devices[i].local_csrk, 16);
1569ed01c36SMatthias Ringwald         write_value(wFile, le_devices[i].local_counter, 2);
157eda85fbfSMatthias Ringwald #endif
1589ed01c36SMatthias Ringwald         fwrite("\n", 1, 1, wFile);
1599ed01c36SMatthias Ringwald     }
1609ed01c36SMatthias Ringwald     fclose(wFile);
1619ed01c36SMatthias Ringwald }
1629ed01c36SMatthias Ringwald static void read_delimiter(FILE * wFile){
1639ed01c36SMatthias Ringwald     fgetc(wFile);
1649ed01c36SMatthias Ringwald }
1659ed01c36SMatthias Ringwald 
1669ed01c36SMatthias Ringwald static uint8_t read_hex_byte(FILE * wFile){
1679ed01c36SMatthias Ringwald     int c = fgetc(wFile);
1689ed01c36SMatthias Ringwald     if (c == ':') {
1699ed01c36SMatthias Ringwald         c = fgetc(wFile);
1709ed01c36SMatthias Ringwald     }
1719ed01c36SMatthias Ringwald     int d = fgetc(wFile);
1729ed01c36SMatthias Ringwald     return nibble_for_char(c) << 4 | nibble_for_char(d);
1739ed01c36SMatthias Ringwald }
1749ed01c36SMatthias Ringwald 
1759ed01c36SMatthias Ringwald static void read_hex(FILE * wFile, uint8_t * buffer, int len){
1769ed01c36SMatthias Ringwald     int i;
1779ed01c36SMatthias Ringwald     for (i=0;i<len;i++){
1789ed01c36SMatthias Ringwald         buffer[i] = read_hex_byte(wFile);
1799ed01c36SMatthias Ringwald     }
1809ed01c36SMatthias Ringwald     read_delimiter(wFile);
1819ed01c36SMatthias Ringwald }
1829ed01c36SMatthias Ringwald 
1839ed01c36SMatthias Ringwald static uint32_t read_value(FILE * wFile, int len){
1849ed01c36SMatthias Ringwald     uint32_t res = 0;
1859ed01c36SMatthias Ringwald     int i;
1869ed01c36SMatthias Ringwald     for (i=0;i<len;i++){
1879ed01c36SMatthias Ringwald         res = res << 8 | read_hex_byte(wFile);
1889ed01c36SMatthias Ringwald     }
1899ed01c36SMatthias Ringwald     read_delimiter(wFile);
1909ed01c36SMatthias Ringwald     return res;
1919ed01c36SMatthias Ringwald }
1929ed01c36SMatthias Ringwald 
1939ed01c36SMatthias Ringwald static void le_device_db_read(void){
1949ed01c36SMatthias Ringwald     // open file
1959ed01c36SMatthias Ringwald     FILE * wFile = fopen(db_path,"r");
1969ed01c36SMatthias Ringwald     if (wFile == NULL) return;
1979ed01c36SMatthias Ringwald     // skip header
1989ed01c36SMatthias Ringwald     while (1) {
1999ed01c36SMatthias Ringwald         int c = fgetc(wFile);
2009ed01c36SMatthias Ringwald         if (feof(wFile)) goto exit;
2019ed01c36SMatthias Ringwald         if (c == '\n') break;
2029ed01c36SMatthias Ringwald     }
2039ed01c36SMatthias Ringwald     // read entries
2049ed01c36SMatthias Ringwald     int i;
2059ed01c36SMatthias Ringwald     for (i=0;i<LE_DEVICE_MEMORY_SIZE && !feof(wFile);i++){
2069ed01c36SMatthias Ringwald         le_devices[i].addr_type = read_value(wFile, 1);
2079ed01c36SMatthias Ringwald         read_hex(wFile,   le_devices[i].addr, 6);
2089ed01c36SMatthias Ringwald         read_hex(wFile,   le_devices[i].irk, 16);
2099ed01c36SMatthias Ringwald         read_hex(wFile,   le_devices[i].ltk, 16);
2109ed01c36SMatthias Ringwald         le_devices[i].ediv = read_value(wFile, 2);
2119ed01c36SMatthias Ringwald         read_hex(wFile,   le_devices[i].rand, 8);
2129ed01c36SMatthias Ringwald         le_devices[i].key_size      = read_value(wFile, 1);
2139ed01c36SMatthias Ringwald         le_devices[i].authenticated = read_value(wFile, 1);
2149ed01c36SMatthias Ringwald         le_devices[i].authorized    = read_value(wFile, 1);
215eda85fbfSMatthias Ringwald #ifdef ENABLE_LE_SIGNED_WRITE
2169ed01c36SMatthias Ringwald         read_hex(wFile,   le_devices[i].remote_csrk, 16);
2179ed01c36SMatthias Ringwald         le_devices[i].remote_counter = read_value(wFile, 2);
2189ed01c36SMatthias Ringwald         read_hex(wFile,   le_devices[i].local_csrk, 16);
2199ed01c36SMatthias Ringwald         le_devices[i].local_counter = read_value(wFile, 2);
220eda85fbfSMatthias Ringwald #endif
2219ed01c36SMatthias Ringwald         // read newling
2229ed01c36SMatthias Ringwald         fgetc(wFile);
2239ed01c36SMatthias Ringwald     }
2249ed01c36SMatthias Ringwald exit:
2259ed01c36SMatthias Ringwald     fclose(wFile);
2269ed01c36SMatthias Ringwald }
2279ed01c36SMatthias Ringwald 
2289ed01c36SMatthias Ringwald void le_device_db_init(void){
2299ed01c36SMatthias Ringwald     int i;
2309ed01c36SMatthias Ringwald     for (i=0;i<LE_DEVICE_MEMORY_SIZE;i++){
2319ed01c36SMatthias Ringwald         le_devices[i].addr_type = INVALID_ENTRY_ADDR_TYPE;
2329ed01c36SMatthias Ringwald     }
233f33ad81dSMatthias Ringwald     sprintf(db_path, DB_PATH_TEMPLATE, "00-00-00-00-00-00");
234f33ad81dSMatthias Ringwald }
235f33ad81dSMatthias Ringwald 
236f33ad81dSMatthias Ringwald void le_device_db_set_local_bd_addr(bd_addr_t addr){
237f33ad81dSMatthias Ringwald     sprintf(db_path, DB_PATH_TEMPLATE, bd_addr_to_dash_str(addr));
238f33ad81dSMatthias Ringwald     log_info("le_device_db_fs: path %s", db_path);
2399ed01c36SMatthias Ringwald     le_device_db_read();
2409ed01c36SMatthias Ringwald     le_device_db_dump();
2419ed01c36SMatthias Ringwald }
2429ed01c36SMatthias Ringwald 
2439ed01c36SMatthias Ringwald // @returns number of device in db
2449ed01c36SMatthias Ringwald int le_device_db_count(void){
2459ed01c36SMatthias Ringwald     int i;
2469ed01c36SMatthias Ringwald     int counter = 0;
2479ed01c36SMatthias Ringwald     for (i=0;i<LE_DEVICE_MEMORY_SIZE;i++){
2489ed01c36SMatthias Ringwald         if (le_devices[i].addr_type != INVALID_ENTRY_ADDR_TYPE) counter++;
2499ed01c36SMatthias Ringwald     }
2509ed01c36SMatthias Ringwald     return counter;
2519ed01c36SMatthias Ringwald }
2529ed01c36SMatthias Ringwald 
2539ed01c36SMatthias Ringwald // free device
2549ed01c36SMatthias Ringwald void le_device_db_remove(int index){
2559ed01c36SMatthias Ringwald     le_devices[index].addr_type = INVALID_ENTRY_ADDR_TYPE;
2569ed01c36SMatthias Ringwald     le_device_db_store();
2579ed01c36SMatthias Ringwald }
2589ed01c36SMatthias Ringwald 
2599ed01c36SMatthias Ringwald int le_device_db_add(int addr_type, bd_addr_t addr, sm_key_t irk){
2609ed01c36SMatthias Ringwald     int i;
2619ed01c36SMatthias Ringwald     int index = -1;
2629ed01c36SMatthias Ringwald     for (i=0;i<LE_DEVICE_MEMORY_SIZE;i++){
2639ed01c36SMatthias Ringwald          if (le_devices[i].addr_type == INVALID_ENTRY_ADDR_TYPE){
2649ed01c36SMatthias Ringwald             index = i;
2659ed01c36SMatthias Ringwald             break;
2669ed01c36SMatthias Ringwald          }
2679ed01c36SMatthias Ringwald     }
2689ed01c36SMatthias Ringwald 
2699ed01c36SMatthias Ringwald     if (index < 0) return -1;
2709ed01c36SMatthias Ringwald 
2719ed01c36SMatthias Ringwald     log_info("Central Device DB adding type %u - %s", addr_type, bd_addr_to_str(addr));
2729ed01c36SMatthias Ringwald     log_info_key("irk", irk);
2739ed01c36SMatthias Ringwald 
2749ed01c36SMatthias Ringwald     le_devices[index].addr_type = addr_type;
2759ed01c36SMatthias Ringwald     memcpy(le_devices[index].addr, addr, 6);
2769ed01c36SMatthias Ringwald     memcpy(le_devices[index].irk, irk, 16);
277eda85fbfSMatthias Ringwald #ifdef ENABLE_LE_SIGNED_WRITE
2789ed01c36SMatthias Ringwald     le_devices[index].remote_counter = 0;
279eda85fbfSMatthias Ringwald #endif
2809ed01c36SMatthias Ringwald     le_device_db_store();
2819ed01c36SMatthias Ringwald 
2829ed01c36SMatthias Ringwald     return index;
2839ed01c36SMatthias Ringwald }
2849ed01c36SMatthias Ringwald 
2859ed01c36SMatthias Ringwald 
2869ed01c36SMatthias Ringwald // get device information: addr type and address
2879ed01c36SMatthias Ringwald void le_device_db_info(int index, int * addr_type, bd_addr_t addr, sm_key_t irk){
2889ed01c36SMatthias Ringwald     if (addr_type) *addr_type = le_devices[index].addr_type;
2899ed01c36SMatthias Ringwald     if (addr) memcpy(addr, le_devices[index].addr, 6);
2909ed01c36SMatthias Ringwald     if (irk) memcpy(irk, le_devices[index].irk, 16);
2919ed01c36SMatthias Ringwald }
2929ed01c36SMatthias Ringwald 
2939ed01c36SMatthias Ringwald void le_device_db_encryption_set(int index, uint16_t ediv, uint8_t rand[8], sm_key_t ltk, int key_size, int authenticated, int authorized){
2949ed01c36SMatthias Ringwald     log_info("Central Device DB set encryption for %u, ediv x%04x, key size %u, authenticated %u, authorized %u",
2959ed01c36SMatthias Ringwald         index, ediv, key_size, authenticated, authorized);
2969ed01c36SMatthias Ringwald     le_device_memory_db_t * device = &le_devices[index];
2979ed01c36SMatthias Ringwald     device->ediv = ediv;
2989ed01c36SMatthias Ringwald     if (rand) memcpy(device->rand, rand, 8);
2999ed01c36SMatthias Ringwald     if (ltk) memcpy(device->ltk, ltk, 16);
3009ed01c36SMatthias Ringwald     device->key_size = key_size;
3019ed01c36SMatthias Ringwald     device->authenticated = authenticated;
3029ed01c36SMatthias Ringwald     device->authorized = authorized;
3039ed01c36SMatthias Ringwald 
3049ed01c36SMatthias Ringwald     le_device_db_store();
3059ed01c36SMatthias Ringwald }
3069ed01c36SMatthias Ringwald 
3079ed01c36SMatthias Ringwald void le_device_db_encryption_get(int index, uint16_t * ediv, uint8_t rand[8], sm_key_t ltk, int * key_size, int * authenticated, int * authorized){
3089ed01c36SMatthias Ringwald     le_device_memory_db_t * device = &le_devices[index];
3099ed01c36SMatthias Ringwald     log_info("Central Device DB encryption for %u, ediv x%04x, keysize %u, authenticated %u, authorized %u",
3109ed01c36SMatthias Ringwald         index, device->ediv, device->key_size, device->authenticated, device->authorized);
3119ed01c36SMatthias Ringwald     if (ediv) *ediv = device->ediv;
3129ed01c36SMatthias Ringwald     if (rand) memcpy(rand, device->rand, 8);
3139ed01c36SMatthias Ringwald     if (ltk)  memcpy(ltk, device->ltk, 16);
3149ed01c36SMatthias Ringwald     if (key_size) *key_size = device->key_size;
3159ed01c36SMatthias Ringwald     if (authenticated) *authenticated = device->authenticated;
3169ed01c36SMatthias Ringwald     if (authorized) *authorized = device->authorized;
3179ed01c36SMatthias Ringwald }
3189ed01c36SMatthias Ringwald 
319eda85fbfSMatthias Ringwald #ifdef ENABLE_LE_SIGNED_WRITE
320eda85fbfSMatthias Ringwald 
3219ed01c36SMatthias Ringwald // get signature key
3229ed01c36SMatthias Ringwald void le_device_db_remote_csrk_get(int index, sm_key_t csrk){
3239ed01c36SMatthias Ringwald     if (index < 0 || index >= LE_DEVICE_MEMORY_SIZE){
3249ed01c36SMatthias Ringwald         log_error("le_device_db_remote_csrk_get called with invalid index %d", index);
3259ed01c36SMatthias Ringwald         return;
3269ed01c36SMatthias Ringwald     }
3279ed01c36SMatthias Ringwald     if (csrk) memcpy(csrk, le_devices[index].remote_csrk, 16);
3289ed01c36SMatthias Ringwald }
3299ed01c36SMatthias Ringwald 
3309ed01c36SMatthias Ringwald void le_device_db_remote_csrk_set(int index, sm_key_t csrk){
3319ed01c36SMatthias Ringwald     if (index < 0 || index >= LE_DEVICE_MEMORY_SIZE){
3329ed01c36SMatthias Ringwald         log_error("le_device_db_remote_csrk_set called with invalid index %d", index);
3339ed01c36SMatthias Ringwald         return;
3349ed01c36SMatthias Ringwald     }
3359ed01c36SMatthias Ringwald     if (csrk) memcpy(le_devices[index].remote_csrk, csrk, 16);
3369ed01c36SMatthias Ringwald 
3379ed01c36SMatthias Ringwald     le_device_db_store();
3389ed01c36SMatthias Ringwald }
3399ed01c36SMatthias Ringwald 
3409ed01c36SMatthias Ringwald void le_device_db_local_csrk_get(int index, sm_key_t csrk){
3419ed01c36SMatthias Ringwald     if (index < 0 || index >= LE_DEVICE_MEMORY_SIZE){
3429ed01c36SMatthias Ringwald         log_error("le_device_db_local_csrk_get called with invalid index %d", index);
3439ed01c36SMatthias Ringwald         return;
3449ed01c36SMatthias Ringwald     }
3459ed01c36SMatthias Ringwald     if (csrk) memcpy(csrk, le_devices[index].local_csrk, 16);
3469ed01c36SMatthias Ringwald }
3479ed01c36SMatthias Ringwald 
3489ed01c36SMatthias Ringwald void le_device_db_local_csrk_set(int index, sm_key_t csrk){
3499ed01c36SMatthias Ringwald     if (index < 0 || index >= LE_DEVICE_MEMORY_SIZE){
3509ed01c36SMatthias Ringwald         log_error("le_device_db_local_csrk_set called with invalid index %d", index);
3519ed01c36SMatthias Ringwald         return;
3529ed01c36SMatthias Ringwald     }
3539ed01c36SMatthias Ringwald     if (csrk) memcpy(le_devices[index].local_csrk, csrk, 16);
3549ed01c36SMatthias Ringwald 
3559ed01c36SMatthias Ringwald     le_device_db_store();
3569ed01c36SMatthias Ringwald }
3579ed01c36SMatthias Ringwald 
3589ed01c36SMatthias Ringwald // query last used/seen signing counter
3599ed01c36SMatthias Ringwald uint32_t le_device_db_remote_counter_get(int index){
3609ed01c36SMatthias Ringwald     return le_devices[index].remote_counter;
3619ed01c36SMatthias Ringwald }
3629ed01c36SMatthias Ringwald 
3639ed01c36SMatthias Ringwald // update signing counter
3649ed01c36SMatthias Ringwald void le_device_db_remote_counter_set(int index, uint32_t counter){
3659ed01c36SMatthias Ringwald     le_devices[index].remote_counter = counter;
3669ed01c36SMatthias Ringwald 
3679ed01c36SMatthias Ringwald     le_device_db_store();
3689ed01c36SMatthias Ringwald }
3699ed01c36SMatthias Ringwald 
3709ed01c36SMatthias Ringwald // query last used/seen signing counter
3719ed01c36SMatthias Ringwald uint32_t le_device_db_local_counter_get(int index){
3729ed01c36SMatthias Ringwald     return le_devices[index].local_counter;
3739ed01c36SMatthias Ringwald }
3749ed01c36SMatthias Ringwald 
3759ed01c36SMatthias Ringwald // update signing counter
3769ed01c36SMatthias Ringwald void le_device_db_local_counter_set(int index, uint32_t counter){
3779ed01c36SMatthias Ringwald     le_devices[index].local_counter = counter;
3789ed01c36SMatthias Ringwald 
3799ed01c36SMatthias Ringwald     le_device_db_store();
3809ed01c36SMatthias Ringwald }
381eda85fbfSMatthias Ringwald #endif
3829ed01c36SMatthias Ringwald 
3839ed01c36SMatthias Ringwald void le_device_db_dump(void){
3849ed01c36SMatthias Ringwald     log_info("Central Device DB dump, devices: %d", le_device_db_count());
3859ed01c36SMatthias Ringwald     int i;
3869ed01c36SMatthias Ringwald     for (i=0;i<LE_DEVICE_MEMORY_SIZE;i++){
3879ed01c36SMatthias Ringwald         if (le_devices[i].addr_type == INVALID_ENTRY_ADDR_TYPE) continue;
3889ed01c36SMatthias Ringwald         log_info("%u: %u %s", i, le_devices[i].addr_type, bd_addr_to_str(le_devices[i].addr));
3899ed01c36SMatthias Ringwald         log_info_key("ltk", le_devices[i].ltk);
3909ed01c36SMatthias Ringwald         log_info_key("irk", le_devices[i].irk);
391eda85fbfSMatthias Ringwald #ifdef ENABLE_LE_SIGNED_WRITE
3929ed01c36SMatthias Ringwald         log_info_key("local csrk", le_devices[i].local_csrk);
3939ed01c36SMatthias Ringwald         log_info_key("remote csrk", le_devices[i].remote_csrk);
394eda85fbfSMatthias Ringwald #endif
3959ed01c36SMatthias Ringwald     }
3969ed01c36SMatthias Ringwald }
397