xref: /btstack/platform/posix/le_device_db_fs.c (revision f33ad81deb2faaa3f569f41c4d3fff7c7a7b5de2)
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  */
379ed01c36SMatthias Ringwald 
389ed01c36SMatthias Ringwald #include "ble/le_device_db.h"
399ed01c36SMatthias Ringwald 
409ed01c36SMatthias Ringwald #include "ble/core.h"
419ed01c36SMatthias Ringwald 
429ed01c36SMatthias Ringwald #include <stdio.h>
439ed01c36SMatthias Ringwald #include <string.h>
449ed01c36SMatthias Ringwald #include "btstack_debug.h"
459ed01c36SMatthias Ringwald 
469ed01c36SMatthias Ringwald // Central Device db implemenation using static memory
479ed01c36SMatthias Ringwald typedef struct le_device_memory_db {
489ed01c36SMatthias Ringwald 
499ed01c36SMatthias Ringwald     // Identification
509ed01c36SMatthias Ringwald     int addr_type;
519ed01c36SMatthias Ringwald     bd_addr_t addr;
529ed01c36SMatthias Ringwald     sm_key_t irk;
539ed01c36SMatthias Ringwald 
549ed01c36SMatthias Ringwald     // Stored pairing information allows to re-establish an enncrypted connection
559ed01c36SMatthias Ringwald     // with a peripheral that doesn't have any persistent memory
569ed01c36SMatthias Ringwald     sm_key_t ltk;
579ed01c36SMatthias Ringwald     uint16_t ediv;
589ed01c36SMatthias Ringwald     uint8_t  rand[8];
599ed01c36SMatthias Ringwald     uint8_t  key_size;
609ed01c36SMatthias Ringwald     uint8_t  authenticated;
619ed01c36SMatthias Ringwald     uint8_t  authorized;
629ed01c36SMatthias Ringwald 
639ed01c36SMatthias Ringwald     // Signed Writes by remote
649ed01c36SMatthias Ringwald     sm_key_t remote_csrk;
659ed01c36SMatthias Ringwald     uint32_t remote_counter;
669ed01c36SMatthias Ringwald 
679ed01c36SMatthias Ringwald     // Signed Writes by us
689ed01c36SMatthias Ringwald     sm_key_t local_csrk;
699ed01c36SMatthias Ringwald     uint32_t local_counter;
709ed01c36SMatthias Ringwald 
719ed01c36SMatthias Ringwald } le_device_memory_db_t;
729ed01c36SMatthias Ringwald 
739ed01c36SMatthias Ringwald #define LE_DEVICE_MEMORY_SIZE 20
749ed01c36SMatthias Ringwald #define INVALID_ENTRY_ADDR_TYPE 0xff
75*f33ad81dSMatthias Ringwald #define DB_PATH_TEMPLATE "/tmp/btstack_at_%s_le_device_db.txt"
769ed01c36SMatthias 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";
77*f33ad81dSMatthias Ringwald static char db_path[sizeof(DB_PATH_TEMPLATE) - 2 + 17 + 1];
789ed01c36SMatthias Ringwald 
799ed01c36SMatthias Ringwald static le_device_memory_db_t le_devices[LE_DEVICE_MEMORY_SIZE];
809ed01c36SMatthias Ringwald 
81*f33ad81dSMatthias Ringwald static char bd_addr_to_dash_str_buffer[6*3];  // 12-45-78-01-34-67\0
82*f33ad81dSMatthias Ringwald static char * bd_addr_to_dash_str(bd_addr_t addr){
83*f33ad81dSMatthias Ringwald     char * p = bd_addr_to_dash_str_buffer;
84*f33ad81dSMatthias Ringwald     int i;
85*f33ad81dSMatthias Ringwald     for (i = 0; i < 6 ; i++) {
86*f33ad81dSMatthias Ringwald         *p++ = char_for_nibble((addr[i] >> 4) & 0x0F);
87*f33ad81dSMatthias Ringwald         *p++ = char_for_nibble((addr[i] >> 0) & 0x0F);
88*f33ad81dSMatthias Ringwald         *p++ = '-';
89*f33ad81dSMatthias Ringwald     }
90*f33ad81dSMatthias Ringwald     *--p = 0;
91*f33ad81dSMatthias Ringwald     return (char *) bd_addr_to_dash_str_buffer;
92*f33ad81dSMatthias Ringwald }
93*f33ad81dSMatthias Ringwald 
949ed01c36SMatthias Ringwald static inline void write_delimiter(FILE * wFile){
959ed01c36SMatthias Ringwald     fwrite(", ", 1, 1, wFile);
969ed01c36SMatthias Ringwald }
979ed01c36SMatthias Ringwald static inline void write_hex_byte(FILE * wFile, uint8_t value){
989ed01c36SMatthias Ringwald     char buffer[2];
999ed01c36SMatthias Ringwald     buffer[0] = char_for_nibble(value >>   4);
1009ed01c36SMatthias Ringwald     buffer[1] = char_for_nibble(value & 0x0f);
1019ed01c36SMatthias Ringwald     fwrite(buffer, 2, 1, wFile);
1029ed01c36SMatthias Ringwald }
1039ed01c36SMatthias Ringwald 
1049ed01c36SMatthias Ringwald static inline void write_str(FILE * wFile, const char * str){
1059ed01c36SMatthias Ringwald     fwrite(str, strlen(str), 1, wFile);
1069ed01c36SMatthias Ringwald     write_delimiter(wFile);
1079ed01c36SMatthias Ringwald }
1089ed01c36SMatthias Ringwald static void write_hex(FILE * wFile, const uint8_t * value, int len){
1099ed01c36SMatthias Ringwald     int i;
1109ed01c36SMatthias Ringwald     for (i = 0; i < len; i++){
1119ed01c36SMatthias Ringwald         write_hex_byte(wFile, value[i]);
1129ed01c36SMatthias Ringwald     }
1139ed01c36SMatthias Ringwald     write_delimiter(wFile);
1149ed01c36SMatthias Ringwald }
1159ed01c36SMatthias Ringwald static void write_value(FILE * wFile, uint32_t value, int len){
1169ed01c36SMatthias Ringwald     switch (len){
1179ed01c36SMatthias Ringwald         case 4:
1189ed01c36SMatthias Ringwald             write_hex_byte(wFile, value >> 24);
1199ed01c36SMatthias Ringwald         case 3:
1209ed01c36SMatthias Ringwald             write_hex_byte(wFile, value >> 16);
1219ed01c36SMatthias Ringwald         case 2:
1229ed01c36SMatthias Ringwald             write_hex_byte(wFile, value >> 8);
1239ed01c36SMatthias Ringwald         case 1:
1249ed01c36SMatthias Ringwald         default:
1259ed01c36SMatthias Ringwald             write_hex_byte(wFile, value);
1269ed01c36SMatthias Ringwald     }
1279ed01c36SMatthias Ringwald     write_delimiter(wFile);
1289ed01c36SMatthias Ringwald }
1299ed01c36SMatthias Ringwald 
1309ed01c36SMatthias Ringwald static void le_device_db_store(void) {
1319ed01c36SMatthias Ringwald     int i;
1329ed01c36SMatthias Ringwald     // open file
1339ed01c36SMatthias Ringwald     FILE * wFile = fopen(db_path,"w+");
1349ed01c36SMatthias Ringwald     if (wFile == NULL) return;
1359ed01c36SMatthias Ringwald     fwrite(csv_header, strlen(csv_header), 1, wFile);
1369ed01c36SMatthias Ringwald     fwrite("\n", 1, 1, wFile);
1379ed01c36SMatthias Ringwald     for (i=0;i<LE_DEVICE_MEMORY_SIZE;i++){
1389ed01c36SMatthias Ringwald         if (le_devices[i].addr_type == INVALID_ENTRY_ADDR_TYPE) continue;
1399ed01c36SMatthias Ringwald         write_value(wFile, le_devices[i].addr_type, 1);
1409ed01c36SMatthias Ringwald         write_str(wFile,   bd_addr_to_str(le_devices[i].addr));
1419ed01c36SMatthias Ringwald         write_hex(wFile,   le_devices[i].irk, 16);
1429ed01c36SMatthias Ringwald         write_hex(wFile,   le_devices[i].ltk, 16);
1439ed01c36SMatthias Ringwald         write_value(wFile, le_devices[i].ediv, 2);
1449ed01c36SMatthias Ringwald         write_hex(wFile,   le_devices[i].rand, 8);
1459ed01c36SMatthias Ringwald         write_value(wFile, le_devices[i].key_size, 1);
1469ed01c36SMatthias Ringwald         write_value(wFile, le_devices[i].authenticated, 1);
1479ed01c36SMatthias Ringwald         write_value(wFile, le_devices[i].authorized, 1);
1489ed01c36SMatthias Ringwald         write_hex(wFile,   le_devices[i].remote_csrk, 16);
1499ed01c36SMatthias Ringwald         write_value(wFile, le_devices[i].remote_counter, 2);
1509ed01c36SMatthias Ringwald         write_hex(wFile,   le_devices[i].local_csrk, 16);
1519ed01c36SMatthias Ringwald         write_value(wFile, le_devices[i].local_counter, 2);
1529ed01c36SMatthias Ringwald         fwrite("\n", 1, 1, wFile);
1539ed01c36SMatthias Ringwald     }
1549ed01c36SMatthias Ringwald     fclose(wFile);
1559ed01c36SMatthias Ringwald }
1569ed01c36SMatthias Ringwald static void read_delimiter(FILE * wFile){
1579ed01c36SMatthias Ringwald     fgetc(wFile);
1589ed01c36SMatthias Ringwald }
1599ed01c36SMatthias Ringwald 
1609ed01c36SMatthias Ringwald static uint8_t read_hex_byte(FILE * wFile){
1619ed01c36SMatthias Ringwald     int c = fgetc(wFile);
1629ed01c36SMatthias Ringwald     if (c == ':') {
1639ed01c36SMatthias Ringwald         c = fgetc(wFile);
1649ed01c36SMatthias Ringwald     }
1659ed01c36SMatthias Ringwald     int d = fgetc(wFile);
1669ed01c36SMatthias Ringwald     return nibble_for_char(c) << 4 | nibble_for_char(d);
1679ed01c36SMatthias Ringwald }
1689ed01c36SMatthias Ringwald 
1699ed01c36SMatthias Ringwald static void read_hex(FILE * wFile, uint8_t * buffer, int len){
1709ed01c36SMatthias Ringwald     int i;
1719ed01c36SMatthias Ringwald     for (i=0;i<len;i++){
1729ed01c36SMatthias Ringwald         buffer[i] = read_hex_byte(wFile);
1739ed01c36SMatthias Ringwald     }
1749ed01c36SMatthias Ringwald     read_delimiter(wFile);
1759ed01c36SMatthias Ringwald }
1769ed01c36SMatthias Ringwald 
1779ed01c36SMatthias Ringwald static uint32_t read_value(FILE * wFile, int len){
1789ed01c36SMatthias Ringwald     uint32_t res = 0;
1799ed01c36SMatthias Ringwald     int i;
1809ed01c36SMatthias Ringwald     for (i=0;i<len;i++){
1819ed01c36SMatthias Ringwald         res = res << 8 | read_hex_byte(wFile);
1829ed01c36SMatthias Ringwald     }
1839ed01c36SMatthias Ringwald     read_delimiter(wFile);
1849ed01c36SMatthias Ringwald     return res;
1859ed01c36SMatthias Ringwald }
1869ed01c36SMatthias Ringwald 
1879ed01c36SMatthias Ringwald static void le_device_db_read(void){
1889ed01c36SMatthias Ringwald     // open file
1899ed01c36SMatthias Ringwald     FILE * wFile = fopen(db_path,"r");
1909ed01c36SMatthias Ringwald     if (wFile == NULL) return;
1919ed01c36SMatthias Ringwald     // skip header
1929ed01c36SMatthias Ringwald     while (1) {
1939ed01c36SMatthias Ringwald         int c = fgetc(wFile);
1949ed01c36SMatthias Ringwald         if (feof(wFile)) goto exit;
1959ed01c36SMatthias Ringwald         if (c == '\n') break;
1969ed01c36SMatthias Ringwald     }
1979ed01c36SMatthias Ringwald     // read entries
1989ed01c36SMatthias Ringwald     int i;
1999ed01c36SMatthias Ringwald     for (i=0;i<LE_DEVICE_MEMORY_SIZE && !feof(wFile);i++){
2009ed01c36SMatthias Ringwald         le_devices[i].addr_type = read_value(wFile, 1);
2019ed01c36SMatthias Ringwald         read_hex(wFile,   le_devices[i].addr, 6);
2029ed01c36SMatthias Ringwald         read_hex(wFile,   le_devices[i].irk, 16);
2039ed01c36SMatthias Ringwald         read_hex(wFile,   le_devices[i].ltk, 16);
2049ed01c36SMatthias Ringwald         le_devices[i].ediv = read_value(wFile, 2);
2059ed01c36SMatthias Ringwald         read_hex(wFile,   le_devices[i].rand, 8);
2069ed01c36SMatthias Ringwald         le_devices[i].key_size      = read_value(wFile, 1);
2079ed01c36SMatthias Ringwald         le_devices[i].authenticated = read_value(wFile, 1);
2089ed01c36SMatthias Ringwald         le_devices[i].authorized    = read_value(wFile, 1);
2099ed01c36SMatthias Ringwald         read_hex(wFile,   le_devices[i].remote_csrk, 16);
2109ed01c36SMatthias Ringwald         le_devices[i].remote_counter = read_value(wFile, 2);
2119ed01c36SMatthias Ringwald         read_hex(wFile,   le_devices[i].local_csrk, 16);
2129ed01c36SMatthias Ringwald         le_devices[i].local_counter = read_value(wFile, 2);
2139ed01c36SMatthias Ringwald         // read newling
2149ed01c36SMatthias Ringwald         fgetc(wFile);
2159ed01c36SMatthias Ringwald     }
2169ed01c36SMatthias Ringwald exit:
2179ed01c36SMatthias Ringwald     fclose(wFile);
2189ed01c36SMatthias Ringwald }
2199ed01c36SMatthias Ringwald 
2209ed01c36SMatthias Ringwald void le_device_db_init(void){
2219ed01c36SMatthias Ringwald     int i;
2229ed01c36SMatthias Ringwald     for (i=0;i<LE_DEVICE_MEMORY_SIZE;i++){
2239ed01c36SMatthias Ringwald         le_devices[i].addr_type = INVALID_ENTRY_ADDR_TYPE;
2249ed01c36SMatthias Ringwald     }
225*f33ad81dSMatthias Ringwald     sprintf(db_path, DB_PATH_TEMPLATE, "00-00-00-00-00-00");
226*f33ad81dSMatthias Ringwald }
227*f33ad81dSMatthias Ringwald 
228*f33ad81dSMatthias Ringwald void le_device_db_set_local_bd_addr(bd_addr_t addr){
229*f33ad81dSMatthias Ringwald     sprintf(db_path, DB_PATH_TEMPLATE, bd_addr_to_dash_str(addr));
230*f33ad81dSMatthias Ringwald     log_info("le_device_db_fs: path %s", db_path);
2319ed01c36SMatthias Ringwald     le_device_db_read();
2329ed01c36SMatthias Ringwald     le_device_db_dump();
2339ed01c36SMatthias Ringwald }
2349ed01c36SMatthias Ringwald 
2359ed01c36SMatthias Ringwald // @returns number of device in db
2369ed01c36SMatthias Ringwald int le_device_db_count(void){
2379ed01c36SMatthias Ringwald     int i;
2389ed01c36SMatthias Ringwald     int counter = 0;
2399ed01c36SMatthias Ringwald     for (i=0;i<LE_DEVICE_MEMORY_SIZE;i++){
2409ed01c36SMatthias Ringwald         if (le_devices[i].addr_type != INVALID_ENTRY_ADDR_TYPE) counter++;
2419ed01c36SMatthias Ringwald     }
2429ed01c36SMatthias Ringwald     return counter;
2439ed01c36SMatthias Ringwald }
2449ed01c36SMatthias Ringwald 
2459ed01c36SMatthias Ringwald // free device
2469ed01c36SMatthias Ringwald void le_device_db_remove(int index){
2479ed01c36SMatthias Ringwald     le_devices[index].addr_type = INVALID_ENTRY_ADDR_TYPE;
2489ed01c36SMatthias Ringwald     le_device_db_store();
2499ed01c36SMatthias Ringwald }
2509ed01c36SMatthias Ringwald 
2519ed01c36SMatthias Ringwald int le_device_db_add(int addr_type, bd_addr_t addr, sm_key_t irk){
2529ed01c36SMatthias Ringwald     int i;
2539ed01c36SMatthias Ringwald     int index = -1;
2549ed01c36SMatthias Ringwald     for (i=0;i<LE_DEVICE_MEMORY_SIZE;i++){
2559ed01c36SMatthias Ringwald          if (le_devices[i].addr_type == INVALID_ENTRY_ADDR_TYPE){
2569ed01c36SMatthias Ringwald             index = i;
2579ed01c36SMatthias Ringwald             break;
2589ed01c36SMatthias Ringwald          }
2599ed01c36SMatthias Ringwald     }
2609ed01c36SMatthias Ringwald 
2619ed01c36SMatthias Ringwald     if (index < 0) return -1;
2629ed01c36SMatthias Ringwald 
2639ed01c36SMatthias Ringwald     log_info("Central Device DB adding type %u - %s", addr_type, bd_addr_to_str(addr));
2649ed01c36SMatthias Ringwald     log_info_key("irk", irk);
2659ed01c36SMatthias Ringwald 
2669ed01c36SMatthias Ringwald     le_devices[index].addr_type = addr_type;
2679ed01c36SMatthias Ringwald     memcpy(le_devices[index].addr, addr, 6);
2689ed01c36SMatthias Ringwald     memcpy(le_devices[index].irk, irk, 16);
2699ed01c36SMatthias Ringwald     le_devices[index].remote_counter = 0;
2709ed01c36SMatthias Ringwald 
2719ed01c36SMatthias Ringwald     le_device_db_store();
2729ed01c36SMatthias Ringwald 
2739ed01c36SMatthias Ringwald     return index;
2749ed01c36SMatthias Ringwald }
2759ed01c36SMatthias Ringwald 
2769ed01c36SMatthias Ringwald 
2779ed01c36SMatthias Ringwald // get device information: addr type and address
2789ed01c36SMatthias Ringwald void le_device_db_info(int index, int * addr_type, bd_addr_t addr, sm_key_t irk){
2799ed01c36SMatthias Ringwald     if (addr_type) *addr_type = le_devices[index].addr_type;
2809ed01c36SMatthias Ringwald     if (addr) memcpy(addr, le_devices[index].addr, 6);
2819ed01c36SMatthias Ringwald     if (irk) memcpy(irk, le_devices[index].irk, 16);
2829ed01c36SMatthias Ringwald }
2839ed01c36SMatthias Ringwald 
2849ed01c36SMatthias 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){
2859ed01c36SMatthias Ringwald     log_info("Central Device DB set encryption for %u, ediv x%04x, key size %u, authenticated %u, authorized %u",
2869ed01c36SMatthias Ringwald         index, ediv, key_size, authenticated, authorized);
2879ed01c36SMatthias Ringwald     le_device_memory_db_t * device = &le_devices[index];
2889ed01c36SMatthias Ringwald     device->ediv = ediv;
2899ed01c36SMatthias Ringwald     if (rand) memcpy(device->rand, rand, 8);
2909ed01c36SMatthias Ringwald     if (ltk) memcpy(device->ltk, ltk, 16);
2919ed01c36SMatthias Ringwald     device->key_size = key_size;
2929ed01c36SMatthias Ringwald     device->authenticated = authenticated;
2939ed01c36SMatthias Ringwald     device->authorized = authorized;
2949ed01c36SMatthias Ringwald 
2959ed01c36SMatthias Ringwald     le_device_db_store();
2969ed01c36SMatthias Ringwald }
2979ed01c36SMatthias Ringwald 
2989ed01c36SMatthias 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){
2999ed01c36SMatthias Ringwald     le_device_memory_db_t * device = &le_devices[index];
3009ed01c36SMatthias Ringwald     log_info("Central Device DB encryption for %u, ediv x%04x, keysize %u, authenticated %u, authorized %u",
3019ed01c36SMatthias Ringwald         index, device->ediv, device->key_size, device->authenticated, device->authorized);
3029ed01c36SMatthias Ringwald     if (ediv) *ediv = device->ediv;
3039ed01c36SMatthias Ringwald     if (rand) memcpy(rand, device->rand, 8);
3049ed01c36SMatthias Ringwald     if (ltk)  memcpy(ltk, device->ltk, 16);
3059ed01c36SMatthias Ringwald     if (key_size) *key_size = device->key_size;
3069ed01c36SMatthias Ringwald     if (authenticated) *authenticated = device->authenticated;
3079ed01c36SMatthias Ringwald     if (authorized) *authorized = device->authorized;
3089ed01c36SMatthias Ringwald }
3099ed01c36SMatthias Ringwald 
3109ed01c36SMatthias Ringwald // get signature key
3119ed01c36SMatthias Ringwald void le_device_db_remote_csrk_get(int index, sm_key_t csrk){
3129ed01c36SMatthias Ringwald     if (index < 0 || index >= LE_DEVICE_MEMORY_SIZE){
3139ed01c36SMatthias Ringwald         log_error("le_device_db_remote_csrk_get called with invalid index %d", index);
3149ed01c36SMatthias Ringwald         return;
3159ed01c36SMatthias Ringwald     }
3169ed01c36SMatthias Ringwald     if (csrk) memcpy(csrk, le_devices[index].remote_csrk, 16);
3179ed01c36SMatthias Ringwald }
3189ed01c36SMatthias Ringwald 
3199ed01c36SMatthias Ringwald void le_device_db_remote_csrk_set(int index, sm_key_t csrk){
3209ed01c36SMatthias Ringwald     if (index < 0 || index >= LE_DEVICE_MEMORY_SIZE){
3219ed01c36SMatthias Ringwald         log_error("le_device_db_remote_csrk_set called with invalid index %d", index);
3229ed01c36SMatthias Ringwald         return;
3239ed01c36SMatthias Ringwald     }
3249ed01c36SMatthias Ringwald     if (csrk) memcpy(le_devices[index].remote_csrk, csrk, 16);
3259ed01c36SMatthias Ringwald 
3269ed01c36SMatthias Ringwald     le_device_db_store();
3279ed01c36SMatthias Ringwald }
3289ed01c36SMatthias Ringwald 
3299ed01c36SMatthias Ringwald void le_device_db_local_csrk_get(int index, sm_key_t csrk){
3309ed01c36SMatthias Ringwald     if (index < 0 || index >= LE_DEVICE_MEMORY_SIZE){
3319ed01c36SMatthias Ringwald         log_error("le_device_db_local_csrk_get called with invalid index %d", index);
3329ed01c36SMatthias Ringwald         return;
3339ed01c36SMatthias Ringwald     }
3349ed01c36SMatthias Ringwald     if (csrk) memcpy(csrk, le_devices[index].local_csrk, 16);
3359ed01c36SMatthias Ringwald }
3369ed01c36SMatthias Ringwald 
3379ed01c36SMatthias Ringwald void le_device_db_local_csrk_set(int index, sm_key_t csrk){
3389ed01c36SMatthias Ringwald     if (index < 0 || index >= LE_DEVICE_MEMORY_SIZE){
3399ed01c36SMatthias Ringwald         log_error("le_device_db_local_csrk_set called with invalid index %d", index);
3409ed01c36SMatthias Ringwald         return;
3419ed01c36SMatthias Ringwald     }
3429ed01c36SMatthias Ringwald     if (csrk) memcpy(le_devices[index].local_csrk, csrk, 16);
3439ed01c36SMatthias Ringwald 
3449ed01c36SMatthias Ringwald     le_device_db_store();
3459ed01c36SMatthias Ringwald }
3469ed01c36SMatthias Ringwald 
3479ed01c36SMatthias Ringwald // query last used/seen signing counter
3489ed01c36SMatthias Ringwald uint32_t le_device_db_remote_counter_get(int index){
3499ed01c36SMatthias Ringwald     return le_devices[index].remote_counter;
3509ed01c36SMatthias Ringwald }
3519ed01c36SMatthias Ringwald 
3529ed01c36SMatthias Ringwald // update signing counter
3539ed01c36SMatthias Ringwald void le_device_db_remote_counter_set(int index, uint32_t counter){
3549ed01c36SMatthias Ringwald     le_devices[index].remote_counter = counter;
3559ed01c36SMatthias Ringwald 
3569ed01c36SMatthias Ringwald     le_device_db_store();
3579ed01c36SMatthias Ringwald }
3589ed01c36SMatthias Ringwald 
3599ed01c36SMatthias Ringwald // query last used/seen signing counter
3609ed01c36SMatthias Ringwald uint32_t le_device_db_local_counter_get(int index){
3619ed01c36SMatthias Ringwald     return le_devices[index].local_counter;
3629ed01c36SMatthias Ringwald }
3639ed01c36SMatthias Ringwald 
3649ed01c36SMatthias Ringwald // update signing counter
3659ed01c36SMatthias Ringwald void le_device_db_local_counter_set(int index, uint32_t counter){
3669ed01c36SMatthias Ringwald     le_devices[index].local_counter = counter;
3679ed01c36SMatthias Ringwald 
3689ed01c36SMatthias Ringwald     le_device_db_store();
3699ed01c36SMatthias Ringwald }
3709ed01c36SMatthias Ringwald 
3719ed01c36SMatthias Ringwald void le_device_db_dump(void){
3729ed01c36SMatthias Ringwald     log_info("Central Device DB dump, devices: %d", le_device_db_count());
3739ed01c36SMatthias Ringwald     int i;
3749ed01c36SMatthias Ringwald     for (i=0;i<LE_DEVICE_MEMORY_SIZE;i++){
3759ed01c36SMatthias Ringwald         if (le_devices[i].addr_type == INVALID_ENTRY_ADDR_TYPE) continue;
3769ed01c36SMatthias Ringwald         log_info("%u: %u %s", i, le_devices[i].addr_type, bd_addr_to_str(le_devices[i].addr));
3779ed01c36SMatthias Ringwald         log_info_key("ltk", le_devices[i].ltk);
3789ed01c36SMatthias Ringwald         log_info_key("irk", le_devices[i].irk);
3799ed01c36SMatthias Ringwald         log_info_key("local csrk", le_devices[i].local_csrk);
3809ed01c36SMatthias Ringwald         log_info_key("remote csrk", le_devices[i].remote_csrk);
3819ed01c36SMatthias Ringwald     }
3829ed01c36SMatthias Ringwald }
383