xref: /btstack/platform/posix/le_device_db_fs.c (revision 21a309a4d79a7150c9635bf2e88a0b47447fd8db)
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  */
37ab2c6ae4SMatthias Ringwald 
38e501bae0SMatthias Ringwald #define BTSTACK_FILE__ "le_device_db_fs.c"
399ed01c36SMatthias Ringwald 
409ed01c36SMatthias Ringwald #include <stdio.h>
419ed01c36SMatthias Ringwald #include <string.h>
42fd19b115SMatthias Ringwald 
43fd19b115SMatthias Ringwald #include "btstack_config.h"
449ed01c36SMatthias Ringwald #include "btstack_debug.h"
45fd19b115SMatthias Ringwald #include "ble/le_device_db.h"
46fd19b115SMatthias Ringwald #include "ble/core.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;
643dc3a67dSMatthias Ringwald     uint8_t  secure_connection;
659ed01c36SMatthias Ringwald 
66eda85fbfSMatthias Ringwald #ifdef ENABLE_LE_SIGNED_WRITE
679ed01c36SMatthias Ringwald     // Signed Writes by remote
689ed01c36SMatthias Ringwald     sm_key_t remote_csrk;
699ed01c36SMatthias Ringwald     uint32_t remote_counter;
709ed01c36SMatthias Ringwald 
719ed01c36SMatthias Ringwald     // Signed Writes by us
729ed01c36SMatthias Ringwald     sm_key_t local_csrk;
739ed01c36SMatthias Ringwald     uint32_t local_counter;
74eda85fbfSMatthias Ringwald #endif
759ed01c36SMatthias Ringwald 
769ed01c36SMatthias Ringwald } le_device_memory_db_t;
779ed01c36SMatthias Ringwald 
789ed01c36SMatthias Ringwald #define LE_DEVICE_MEMORY_SIZE 20
79fd19b115SMatthias Ringwald 
80fd19b115SMatthias Ringwald #ifndef LE_DEVICE_DB_PATH
81fd19b115SMatthias Ringwald #ifdef _WIN32
82fd19b115SMatthias Ringwald #define LE_DEVICE_DB_PATH ""
83fd19b115SMatthias Ringwald #else
84fd19b115SMatthias Ringwald #define LE_DEVICE_DB_PATH "/tmp/"
85fd19b115SMatthias Ringwald #endif
86fd19b115SMatthias Ringwald #endif
87fd19b115SMatthias Ringwald 
88fd19b115SMatthias Ringwald #define DB_PATH_TEMPLATE (LE_DEVICE_DB_PATH "btstack_at_%s_le_device_db.txt")
89fd19b115SMatthias Ringwald 
903dc3a67dSMatthias Ringwald #ifdef ENABLE_LE_SIGNED_WRITE
913dc3a67dSMatthias 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, secure_connection";
923dc3a67dSMatthias Ringwald #else
933dc3a67dSMatthias Ringwald const  char * csv_header = "# addr_type, addr, irk, ltk, ediv, rand[8], key_size, authenticated, authorized, secure_connection";
943dc3a67dSMatthias Ringwald #endif
953dc3a67dSMatthias Ringwald 
96f33ad81dSMatthias Ringwald static char db_path[sizeof(DB_PATH_TEMPLATE) - 2 + 17 + 1];
979ed01c36SMatthias Ringwald 
989ed01c36SMatthias Ringwald static le_device_memory_db_t le_devices[LE_DEVICE_MEMORY_SIZE];
999ed01c36SMatthias Ringwald 
100f33ad81dSMatthias Ringwald static char bd_addr_to_dash_str_buffer[6*3];  // 12-45-78-01-34-67\0
101f33ad81dSMatthias Ringwald static char * bd_addr_to_dash_str(bd_addr_t addr){
102f33ad81dSMatthias Ringwald     char * p = bd_addr_to_dash_str_buffer;
103f33ad81dSMatthias Ringwald     int i;
104f33ad81dSMatthias Ringwald     for (i = 0; i < 6 ; i++) {
105f33ad81dSMatthias Ringwald         *p++ = char_for_nibble((addr[i] >> 4) & 0x0F);
106f33ad81dSMatthias Ringwald         *p++ = char_for_nibble((addr[i] >> 0) & 0x0F);
107f33ad81dSMatthias Ringwald         *p++ = '-';
108f33ad81dSMatthias Ringwald     }
109f33ad81dSMatthias Ringwald     *--p = 0;
110f33ad81dSMatthias Ringwald     return (char *) bd_addr_to_dash_str_buffer;
111f33ad81dSMatthias Ringwald }
112f33ad81dSMatthias Ringwald 
1139ed01c36SMatthias Ringwald static inline void write_delimiter(FILE * wFile){
1149ed01c36SMatthias Ringwald     fwrite(",", 1, 1, wFile);
1159ed01c36SMatthias Ringwald }
1169ed01c36SMatthias Ringwald static inline void write_hex_byte(FILE * wFile, uint8_t value){
1179ed01c36SMatthias Ringwald     char buffer[2];
1189ed01c36SMatthias Ringwald     buffer[0] = char_for_nibble(value >>   4);
1199ed01c36SMatthias Ringwald     buffer[1] = char_for_nibble(value & 0x0f);
1209ed01c36SMatthias Ringwald     fwrite(buffer, 2, 1, wFile);
1219ed01c36SMatthias Ringwald }
1229ed01c36SMatthias Ringwald 
1239ed01c36SMatthias Ringwald static inline void write_str(FILE * wFile, const char * str){
1249ed01c36SMatthias Ringwald     fwrite(str, strlen(str), 1, wFile);
1259ed01c36SMatthias Ringwald     write_delimiter(wFile);
1269ed01c36SMatthias Ringwald }
1279ed01c36SMatthias Ringwald static void write_hex(FILE * wFile, const uint8_t * value, int len){
1289ed01c36SMatthias Ringwald     int i;
1299ed01c36SMatthias Ringwald     for (i = 0; i < len; i++){
1309ed01c36SMatthias Ringwald         write_hex_byte(wFile, value[i]);
1319ed01c36SMatthias Ringwald     }
1329ed01c36SMatthias Ringwald     write_delimiter(wFile);
1339ed01c36SMatthias Ringwald }
1349ed01c36SMatthias Ringwald static void write_value(FILE * wFile, uint32_t value, int len){
1359ed01c36SMatthias Ringwald     switch (len){
1369ed01c36SMatthias Ringwald         case 4:
1379ed01c36SMatthias Ringwald             write_hex_byte(wFile, value >> 24);
1389ed01c36SMatthias Ringwald         case 3:
1399ed01c36SMatthias Ringwald             write_hex_byte(wFile, value >> 16);
1409ed01c36SMatthias Ringwald         case 2:
1419ed01c36SMatthias Ringwald             write_hex_byte(wFile, value >> 8);
1429ed01c36SMatthias Ringwald         case 1:
1439ed01c36SMatthias Ringwald         default:
1449ed01c36SMatthias Ringwald             write_hex_byte(wFile, value);
1459ed01c36SMatthias Ringwald     }
1469ed01c36SMatthias Ringwald     write_delimiter(wFile);
1479ed01c36SMatthias Ringwald }
1489ed01c36SMatthias Ringwald 
1499ed01c36SMatthias Ringwald static void le_device_db_store(void) {
1509ed01c36SMatthias Ringwald     int i;
1519ed01c36SMatthias Ringwald     // open file
1529ed01c36SMatthias Ringwald     FILE * wFile = fopen(db_path,"w+");
1539ed01c36SMatthias Ringwald     if (wFile == NULL) return;
1549ed01c36SMatthias Ringwald     fwrite(csv_header, strlen(csv_header), 1, wFile);
1559ed01c36SMatthias Ringwald     fwrite("\n", 1, 1, wFile);
1569ed01c36SMatthias Ringwald     for (i=0;i<LE_DEVICE_MEMORY_SIZE;i++){
157d14ceebfSMatthias Ringwald         if (le_devices[i].addr_type == BD_ADDR_TYPE_UNKNOWN) continue;
1589ed01c36SMatthias Ringwald         write_value(wFile, le_devices[i].addr_type, 1);
1599ed01c36SMatthias Ringwald         write_str(wFile,   bd_addr_to_str(le_devices[i].addr));
1609ed01c36SMatthias Ringwald         write_hex(wFile,   le_devices[i].irk, 16);
1619ed01c36SMatthias Ringwald         write_hex(wFile,   le_devices[i].ltk, 16);
1629ed01c36SMatthias Ringwald         write_value(wFile, le_devices[i].ediv, 2);
1639ed01c36SMatthias Ringwald         write_hex(wFile,   le_devices[i].rand, 8);
1649ed01c36SMatthias Ringwald         write_value(wFile, le_devices[i].key_size, 1);
1659ed01c36SMatthias Ringwald         write_value(wFile, le_devices[i].authenticated, 1);
1669ed01c36SMatthias Ringwald         write_value(wFile, le_devices[i].authorized, 1);
167eda85fbfSMatthias Ringwald #ifdef ENABLE_LE_SIGNED_WRITE
1689ed01c36SMatthias Ringwald         write_hex(wFile,   le_devices[i].remote_csrk, 16);
1699ed01c36SMatthias Ringwald         write_value(wFile, le_devices[i].remote_counter, 2);
1709ed01c36SMatthias Ringwald         write_hex(wFile,   le_devices[i].local_csrk, 16);
1719ed01c36SMatthias Ringwald         write_value(wFile, le_devices[i].local_counter, 2);
172eda85fbfSMatthias Ringwald #endif
1733dc3a67dSMatthias Ringwald         write_value(wFile, le_devices[i].secure_connection, 1);
1749ed01c36SMatthias Ringwald         fwrite("\n", 1, 1, wFile);
1759ed01c36SMatthias Ringwald     }
1769ed01c36SMatthias Ringwald     fclose(wFile);
1779ed01c36SMatthias Ringwald }
1789ed01c36SMatthias Ringwald static void read_delimiter(FILE * wFile){
1799ed01c36SMatthias Ringwald     fgetc(wFile);
1809ed01c36SMatthias Ringwald }
1819ed01c36SMatthias Ringwald 
1829ed01c36SMatthias Ringwald static uint8_t read_hex_byte(FILE * wFile){
1839ed01c36SMatthias Ringwald     int c = fgetc(wFile);
1849ed01c36SMatthias Ringwald     if (c == ':') {
1859ed01c36SMatthias Ringwald         c = fgetc(wFile);
1869ed01c36SMatthias Ringwald     }
1879ed01c36SMatthias Ringwald     int d = fgetc(wFile);
1889ed01c36SMatthias Ringwald     return nibble_for_char(c) << 4 | nibble_for_char(d);
1899ed01c36SMatthias Ringwald }
1909ed01c36SMatthias Ringwald 
1919ed01c36SMatthias Ringwald static void read_hex(FILE * wFile, uint8_t * buffer, int len){
1929ed01c36SMatthias Ringwald     int i;
1939ed01c36SMatthias Ringwald     for (i=0;i<len;i++){
1949ed01c36SMatthias Ringwald         buffer[i] = read_hex_byte(wFile);
1959ed01c36SMatthias Ringwald     }
1969ed01c36SMatthias Ringwald     read_delimiter(wFile);
1979ed01c36SMatthias Ringwald }
1989ed01c36SMatthias Ringwald 
1999ed01c36SMatthias Ringwald static uint32_t read_value(FILE * wFile, int len){
2009ed01c36SMatthias Ringwald     uint32_t res = 0;
2019ed01c36SMatthias Ringwald     int i;
2029ed01c36SMatthias Ringwald     for (i=0;i<len;i++){
2039ed01c36SMatthias Ringwald         res = res << 8 | read_hex_byte(wFile);
2049ed01c36SMatthias Ringwald     }
2059ed01c36SMatthias Ringwald     read_delimiter(wFile);
2069ed01c36SMatthias Ringwald     return res;
2079ed01c36SMatthias Ringwald }
2089ed01c36SMatthias Ringwald 
2099ed01c36SMatthias Ringwald static void le_device_db_read(void){
2109ed01c36SMatthias Ringwald     // open file
2119ed01c36SMatthias Ringwald     FILE * wFile = fopen(db_path,"r");
2129ed01c36SMatthias Ringwald     if (wFile == NULL) return;
2139ed01c36SMatthias Ringwald     // skip header
214ff3cc4a5SMatthias Ringwald     while (true) {
2159ed01c36SMatthias Ringwald         int c = fgetc(wFile);
2169ed01c36SMatthias Ringwald         if (feof(wFile)) goto exit;
2179ed01c36SMatthias Ringwald         if (c == '\n') break;
2189ed01c36SMatthias Ringwald     }
2199ed01c36SMatthias Ringwald     // read entries
2209ed01c36SMatthias Ringwald     int i;
2216ecd409bSMatthias Ringwald     for (i=0 ; i<LE_DEVICE_MEMORY_SIZE ; i++){
2223dc3a67dSMatthias Ringwald         memset(&le_devices[i], 0, sizeof(le_device_memory_db_t));
2239ed01c36SMatthias Ringwald         le_devices[i].addr_type = read_value(wFile, 1);
2246ecd409bSMatthias Ringwald         if (feof(wFile)){
225d14ceebfSMatthias Ringwald             le_devices[i].addr_type = BD_ADDR_TYPE_UNKNOWN;
2266ecd409bSMatthias Ringwald             break;
2276ecd409bSMatthias Ringwald         }
2289ed01c36SMatthias Ringwald         read_hex(wFile,   le_devices[i].addr, 6);
2299ed01c36SMatthias Ringwald         read_hex(wFile,   le_devices[i].irk, 16);
2309ed01c36SMatthias Ringwald         read_hex(wFile,   le_devices[i].ltk, 16);
2319ed01c36SMatthias Ringwald         le_devices[i].ediv = read_value(wFile, 2);
2329ed01c36SMatthias Ringwald         read_hex(wFile,   le_devices[i].rand, 8);
2339ed01c36SMatthias Ringwald         le_devices[i].key_size      = read_value(wFile, 1);
2349ed01c36SMatthias Ringwald         le_devices[i].authenticated = read_value(wFile, 1);
2359ed01c36SMatthias Ringwald         le_devices[i].authorized    = read_value(wFile, 1);
236eda85fbfSMatthias Ringwald #ifdef ENABLE_LE_SIGNED_WRITE
2379ed01c36SMatthias Ringwald         read_hex(wFile,   le_devices[i].remote_csrk, 16);
2389ed01c36SMatthias Ringwald         le_devices[i].remote_counter = read_value(wFile, 2);
2399ed01c36SMatthias Ringwald         read_hex(wFile,   le_devices[i].local_csrk, 16);
2409ed01c36SMatthias Ringwald         le_devices[i].local_counter = read_value(wFile, 2);
241eda85fbfSMatthias Ringwald #endif
2423dc3a67dSMatthias Ringwald         // read next character and secure connection field if hex nibble follows
243*21a309a4SMatthias Ringwald         // (if not, we just read the newline)
2443dc3a67dSMatthias Ringwald         int c = fgetc(wFile);
2453dc3a67dSMatthias Ringwald         if (nibble_for_char(c) >= 0){
2463dc3a67dSMatthias Ringwald             int d = fgetc(wFile);
2473dc3a67dSMatthias Ringwald             le_devices[i].secure_connection = nibble_for_char(c) << 4 | nibble_for_char(d);
248*21a309a4SMatthias Ringwald             // read delimiter
249*21a309a4SMatthias Ringwald             read_delimiter(wFile);
2503dc3a67dSMatthias Ringwald             // read newline
2519ed01c36SMatthias Ringwald             fgetc(wFile);
2529ed01c36SMatthias Ringwald         }
2533dc3a67dSMatthias Ringwald     }
2549ed01c36SMatthias Ringwald exit:
2559ed01c36SMatthias Ringwald     fclose(wFile);
2569ed01c36SMatthias Ringwald }
2579ed01c36SMatthias Ringwald 
2589ed01c36SMatthias Ringwald void le_device_db_init(void){
2599ed01c36SMatthias Ringwald     int i;
2609ed01c36SMatthias Ringwald     for (i=0;i<LE_DEVICE_MEMORY_SIZE;i++){
261d14ceebfSMatthias Ringwald         le_devices[i].addr_type = BD_ADDR_TYPE_UNKNOWN;
2629ed01c36SMatthias Ringwald     }
263f33ad81dSMatthias Ringwald     sprintf(db_path, DB_PATH_TEMPLATE, "00-00-00-00-00-00");
264f33ad81dSMatthias Ringwald }
265f33ad81dSMatthias Ringwald 
266f33ad81dSMatthias Ringwald void le_device_db_set_local_bd_addr(bd_addr_t addr){
267f33ad81dSMatthias Ringwald     sprintf(db_path, DB_PATH_TEMPLATE, bd_addr_to_dash_str(addr));
268f33ad81dSMatthias Ringwald     log_info("le_device_db_fs: path %s", db_path);
2699ed01c36SMatthias Ringwald     le_device_db_read();
2709ed01c36SMatthias Ringwald     le_device_db_dump();
2719ed01c36SMatthias Ringwald }
2729ed01c36SMatthias Ringwald 
2739ed01c36SMatthias Ringwald // @returns number of device in db
2749ed01c36SMatthias Ringwald int le_device_db_count(void){
2759ed01c36SMatthias Ringwald     int i;
2769ed01c36SMatthias Ringwald     int counter = 0;
2779ed01c36SMatthias Ringwald     for (i=0;i<LE_DEVICE_MEMORY_SIZE;i++){
278d14ceebfSMatthias Ringwald         if (le_devices[i].addr_type != BD_ADDR_TYPE_UNKNOWN) counter++;
2799ed01c36SMatthias Ringwald     }
2809ed01c36SMatthias Ringwald     return counter;
2819ed01c36SMatthias Ringwald }
2829ed01c36SMatthias Ringwald 
2836fc9dda1SMatthias Ringwald int le_device_db_max_count(void){
2846fc9dda1SMatthias Ringwald     return LE_DEVICE_MEMORY_SIZE;
2856fc9dda1SMatthias Ringwald }
2866fc9dda1SMatthias Ringwald 
2879ed01c36SMatthias Ringwald // free device
2889ed01c36SMatthias Ringwald void le_device_db_remove(int index){
289d14ceebfSMatthias Ringwald     le_devices[index].addr_type = BD_ADDR_TYPE_UNKNOWN;
2909ed01c36SMatthias Ringwald     le_device_db_store();
2919ed01c36SMatthias Ringwald }
2929ed01c36SMatthias Ringwald 
2939ed01c36SMatthias Ringwald int le_device_db_add(int addr_type, bd_addr_t addr, sm_key_t irk){
2949ed01c36SMatthias Ringwald     int i;
2959ed01c36SMatthias Ringwald     int index = -1;
2969ed01c36SMatthias Ringwald     for (i=0;i<LE_DEVICE_MEMORY_SIZE;i++){
297d14ceebfSMatthias Ringwald          if (le_devices[i].addr_type == BD_ADDR_TYPE_UNKNOWN){
2989ed01c36SMatthias Ringwald             index = i;
2999ed01c36SMatthias Ringwald             break;
3009ed01c36SMatthias Ringwald          }
3019ed01c36SMatthias Ringwald     }
3029ed01c36SMatthias Ringwald 
3039ed01c36SMatthias Ringwald     if (index < 0) return -1;
3049ed01c36SMatthias Ringwald 
3059ed01c36SMatthias Ringwald     log_info("Central Device DB adding type %u - %s", addr_type, bd_addr_to_str(addr));
3069ed01c36SMatthias Ringwald     log_info_key("irk", irk);
3079ed01c36SMatthias Ringwald 
308539b14edSMatthias Ringwald     memset(&le_devices[index], 0, sizeof(le_device_memory_db_t));
309539b14edSMatthias Ringwald 
3109ed01c36SMatthias Ringwald     le_devices[index].addr_type = addr_type;
3119ed01c36SMatthias Ringwald     memcpy(le_devices[index].addr, addr, 6);
3129ed01c36SMatthias Ringwald     memcpy(le_devices[index].irk, irk, 16);
313eda85fbfSMatthias Ringwald #ifdef ENABLE_LE_SIGNED_WRITE
3149ed01c36SMatthias Ringwald     le_devices[index].remote_counter = 0;
315eda85fbfSMatthias Ringwald #endif
3169ed01c36SMatthias Ringwald     le_device_db_store();
3179ed01c36SMatthias Ringwald 
3189ed01c36SMatthias Ringwald     return index;
3199ed01c36SMatthias Ringwald }
3209ed01c36SMatthias Ringwald 
3219ed01c36SMatthias Ringwald 
3229ed01c36SMatthias Ringwald // get device information: addr type and address
3239ed01c36SMatthias Ringwald void le_device_db_info(int index, int * addr_type, bd_addr_t addr, sm_key_t irk){
3249ed01c36SMatthias Ringwald     if (addr_type) *addr_type = le_devices[index].addr_type;
3259ed01c36SMatthias Ringwald     if (addr) memcpy(addr, le_devices[index].addr, 6);
3269ed01c36SMatthias Ringwald     if (irk) memcpy(irk, le_devices[index].irk, 16);
3279ed01c36SMatthias Ringwald }
3289ed01c36SMatthias Ringwald 
3293dc3a67dSMatthias 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, int secure_connection){
3303dc3a67dSMatthias Ringwald     log_info("LE Device DB set encryption for %u, ediv x%04x, key size %u, authenticated %u, authorized %u, secure connection %u",
3313dc3a67dSMatthias Ringwald         index, ediv, key_size, authenticated, authorized, secure_connection);
3329ed01c36SMatthias Ringwald     le_device_memory_db_t * device = &le_devices[index];
3339ed01c36SMatthias Ringwald     device->ediv = ediv;
3349ed01c36SMatthias Ringwald     if (rand) memcpy(device->rand, rand, 8);
3359ed01c36SMatthias Ringwald     if (ltk) memcpy(device->ltk, ltk, 16);
3369ed01c36SMatthias Ringwald     device->key_size = key_size;
3379ed01c36SMatthias Ringwald     device->authenticated = authenticated;
3389ed01c36SMatthias Ringwald     device->authorized = authorized;
3393dc3a67dSMatthias Ringwald     device->secure_connection = secure_connection;
3409ed01c36SMatthias Ringwald 
3419ed01c36SMatthias Ringwald     le_device_db_store();
3429ed01c36SMatthias Ringwald }
3439ed01c36SMatthias Ringwald 
3443dc3a67dSMatthias 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, int * secure_connection){
3459ed01c36SMatthias Ringwald     le_device_memory_db_t * device = &le_devices[index];
3463dc3a67dSMatthias Ringwald     log_info("LE Device DB encryption for %u, ediv x%04x, keysize %u, authenticated %u, authorized %u, secure connection %u",
3473dc3a67dSMatthias Ringwald         index, device->ediv, device->key_size, device->authenticated, device->authorized, device->secure_connection);
3489ed01c36SMatthias Ringwald     if (ediv) *ediv = device->ediv;
3499ed01c36SMatthias Ringwald     if (rand) memcpy(rand, device->rand, 8);
3509ed01c36SMatthias Ringwald     if (ltk)  memcpy(ltk, device->ltk, 16);
3519ed01c36SMatthias Ringwald     if (key_size) *key_size = device->key_size;
3529ed01c36SMatthias Ringwald     if (authenticated) *authenticated = device->authenticated;
3539ed01c36SMatthias Ringwald     if (authorized) *authorized = device->authorized;
3543dc3a67dSMatthias Ringwald     if (secure_connection) *secure_connection = device->secure_connection;
3559ed01c36SMatthias Ringwald }
3569ed01c36SMatthias Ringwald 
357eda85fbfSMatthias Ringwald #ifdef ENABLE_LE_SIGNED_WRITE
358eda85fbfSMatthias Ringwald 
3599ed01c36SMatthias Ringwald // get signature key
3609ed01c36SMatthias Ringwald void le_device_db_remote_csrk_get(int index, sm_key_t csrk){
3619ed01c36SMatthias Ringwald     if (index < 0 || index >= LE_DEVICE_MEMORY_SIZE){
3629ed01c36SMatthias Ringwald         log_error("le_device_db_remote_csrk_get called with invalid index %d", index);
3639ed01c36SMatthias Ringwald         return;
3649ed01c36SMatthias Ringwald     }
3659ed01c36SMatthias Ringwald     if (csrk) memcpy(csrk, le_devices[index].remote_csrk, 16);
3669ed01c36SMatthias Ringwald }
3679ed01c36SMatthias Ringwald 
3689ed01c36SMatthias Ringwald void le_device_db_remote_csrk_set(int index, sm_key_t csrk){
3699ed01c36SMatthias Ringwald     if (index < 0 || index >= LE_DEVICE_MEMORY_SIZE){
3709ed01c36SMatthias Ringwald         log_error("le_device_db_remote_csrk_set called with invalid index %d", index);
3719ed01c36SMatthias Ringwald         return;
3729ed01c36SMatthias Ringwald     }
3739ed01c36SMatthias Ringwald     if (csrk) memcpy(le_devices[index].remote_csrk, csrk, 16);
3749ed01c36SMatthias Ringwald 
3759ed01c36SMatthias Ringwald     le_device_db_store();
3769ed01c36SMatthias Ringwald }
3779ed01c36SMatthias Ringwald 
3789ed01c36SMatthias Ringwald void le_device_db_local_csrk_get(int index, sm_key_t csrk){
3799ed01c36SMatthias Ringwald     if (index < 0 || index >= LE_DEVICE_MEMORY_SIZE){
3809ed01c36SMatthias Ringwald         log_error("le_device_db_local_csrk_get called with invalid index %d", index);
3819ed01c36SMatthias Ringwald         return;
3829ed01c36SMatthias Ringwald     }
3839ed01c36SMatthias Ringwald     if (csrk) memcpy(csrk, le_devices[index].local_csrk, 16);
3849ed01c36SMatthias Ringwald }
3859ed01c36SMatthias Ringwald 
3869ed01c36SMatthias Ringwald void le_device_db_local_csrk_set(int index, sm_key_t csrk){
3879ed01c36SMatthias Ringwald     if (index < 0 || index >= LE_DEVICE_MEMORY_SIZE){
3889ed01c36SMatthias Ringwald         log_error("le_device_db_local_csrk_set called with invalid index %d", index);
3899ed01c36SMatthias Ringwald         return;
3909ed01c36SMatthias Ringwald     }
3919ed01c36SMatthias Ringwald     if (csrk) memcpy(le_devices[index].local_csrk, csrk, 16);
3929ed01c36SMatthias Ringwald 
3939ed01c36SMatthias Ringwald     le_device_db_store();
3949ed01c36SMatthias Ringwald }
3959ed01c36SMatthias Ringwald 
3969ed01c36SMatthias Ringwald // query last used/seen signing counter
3979ed01c36SMatthias Ringwald uint32_t le_device_db_remote_counter_get(int index){
3989ed01c36SMatthias Ringwald     return le_devices[index].remote_counter;
3999ed01c36SMatthias Ringwald }
4009ed01c36SMatthias Ringwald 
4019ed01c36SMatthias Ringwald // update signing counter
4029ed01c36SMatthias Ringwald void le_device_db_remote_counter_set(int index, uint32_t counter){
4039ed01c36SMatthias Ringwald     le_devices[index].remote_counter = counter;
4049ed01c36SMatthias Ringwald 
4059ed01c36SMatthias Ringwald     le_device_db_store();
4069ed01c36SMatthias Ringwald }
4079ed01c36SMatthias Ringwald 
4089ed01c36SMatthias Ringwald // query last used/seen signing counter
4099ed01c36SMatthias Ringwald uint32_t le_device_db_local_counter_get(int index){
4109ed01c36SMatthias Ringwald     return le_devices[index].local_counter;
4119ed01c36SMatthias Ringwald }
4129ed01c36SMatthias Ringwald 
4139ed01c36SMatthias Ringwald // update signing counter
4149ed01c36SMatthias Ringwald void le_device_db_local_counter_set(int index, uint32_t counter){
4159ed01c36SMatthias Ringwald     le_devices[index].local_counter = counter;
4169ed01c36SMatthias Ringwald 
4179ed01c36SMatthias Ringwald     le_device_db_store();
4189ed01c36SMatthias Ringwald }
419eda85fbfSMatthias Ringwald #endif
4209ed01c36SMatthias Ringwald 
4219ed01c36SMatthias Ringwald void le_device_db_dump(void){
4229ed01c36SMatthias Ringwald     log_info("Central Device DB dump, devices: %d", le_device_db_count());
4239ed01c36SMatthias Ringwald     int i;
4249ed01c36SMatthias Ringwald     for (i=0;i<LE_DEVICE_MEMORY_SIZE;i++){
425d14ceebfSMatthias Ringwald         if (le_devices[i].addr_type == BD_ADDR_TYPE_UNKNOWN) continue;
4269ed01c36SMatthias Ringwald         log_info("%u: %u %s", i, le_devices[i].addr_type, bd_addr_to_str(le_devices[i].addr));
4279ed01c36SMatthias Ringwald         log_info_key("ltk", le_devices[i].ltk);
4289ed01c36SMatthias Ringwald         log_info_key("irk", le_devices[i].irk);
429eda85fbfSMatthias Ringwald #ifdef ENABLE_LE_SIGNED_WRITE
4309ed01c36SMatthias Ringwald         log_info_key("local csrk", le_devices[i].local_csrk);
4319ed01c36SMatthias Ringwald         log_info_key("remote csrk", le_devices[i].remote_csrk);
432eda85fbfSMatthias Ringwald #endif
4339ed01c36SMatthias Ringwald     }
4349ed01c36SMatthias Ringwald }
435