xref: /btstack/platform/posix/le_device_db_fs.c (revision 9ed01c3693842b1b02ee2db742f92c16bad7a415)
1*9ed01c36SMatthias Ringwald /*
2*9ed01c36SMatthias Ringwald  * Copyright (C) 2014 BlueKitchen GmbH
3*9ed01c36SMatthias Ringwald  *
4*9ed01c36SMatthias Ringwald  * Redistribution and use in source and binary forms, with or without
5*9ed01c36SMatthias Ringwald  * modification, are permitted provided that the following conditions
6*9ed01c36SMatthias Ringwald  * are met:
7*9ed01c36SMatthias Ringwald  *
8*9ed01c36SMatthias Ringwald  * 1. Redistributions of source code must retain the above copyright
9*9ed01c36SMatthias Ringwald  *    notice, this list of conditions and the following disclaimer.
10*9ed01c36SMatthias Ringwald  * 2. Redistributions in binary form must reproduce the above copyright
11*9ed01c36SMatthias Ringwald  *    notice, this list of conditions and the following disclaimer in the
12*9ed01c36SMatthias Ringwald  *    documentation and/or other materials provided with the distribution.
13*9ed01c36SMatthias Ringwald  * 3. Neither the name of the copyright holders nor the names of
14*9ed01c36SMatthias Ringwald  *    contributors may be used to endorse or promote products derived
15*9ed01c36SMatthias Ringwald  *    from this software without specific prior written permission.
16*9ed01c36SMatthias Ringwald  * 4. Any redistribution, use, or modification is done solely for
17*9ed01c36SMatthias Ringwald  *    personal benefit and not for any commercial purpose or for
18*9ed01c36SMatthias Ringwald  *    monetary gain.
19*9ed01c36SMatthias Ringwald  *
20*9ed01c36SMatthias Ringwald  * THIS SOFTWARE IS PROVIDED BY BLUEKITCHEN GMBH AND CONTRIBUTORS
21*9ed01c36SMatthias Ringwald  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22*9ed01c36SMatthias Ringwald  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
23*9ed01c36SMatthias Ringwald  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL MATTHIAS
24*9ed01c36SMatthias Ringwald  * RINGWALD OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
25*9ed01c36SMatthias Ringwald  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
26*9ed01c36SMatthias Ringwald  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
27*9ed01c36SMatthias Ringwald  * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
28*9ed01c36SMatthias Ringwald  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
29*9ed01c36SMatthias Ringwald  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
30*9ed01c36SMatthias Ringwald  * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31*9ed01c36SMatthias Ringwald  * SUCH DAMAGE.
32*9ed01c36SMatthias Ringwald  *
33*9ed01c36SMatthias Ringwald  * Please inquire about commercial licensing options at
34*9ed01c36SMatthias Ringwald  * [email protected]
35*9ed01c36SMatthias Ringwald  *
36*9ed01c36SMatthias Ringwald  */
37*9ed01c36SMatthias Ringwald 
38*9ed01c36SMatthias Ringwald #include "ble/le_device_db.h"
39*9ed01c36SMatthias Ringwald 
40*9ed01c36SMatthias Ringwald #include "ble/core.h"
41*9ed01c36SMatthias Ringwald 
42*9ed01c36SMatthias Ringwald #include <stdio.h>
43*9ed01c36SMatthias Ringwald #include <string.h>
44*9ed01c36SMatthias Ringwald #include "btstack_debug.h"
45*9ed01c36SMatthias Ringwald 
46*9ed01c36SMatthias Ringwald // Central Device db implemenation using static memory
47*9ed01c36SMatthias Ringwald typedef struct le_device_memory_db {
48*9ed01c36SMatthias Ringwald 
49*9ed01c36SMatthias Ringwald     // Identification
50*9ed01c36SMatthias Ringwald     int addr_type;
51*9ed01c36SMatthias Ringwald     bd_addr_t addr;
52*9ed01c36SMatthias Ringwald     sm_key_t irk;
53*9ed01c36SMatthias Ringwald 
54*9ed01c36SMatthias Ringwald     // Stored pairing information allows to re-establish an enncrypted connection
55*9ed01c36SMatthias Ringwald     // with a peripheral that doesn't have any persistent memory
56*9ed01c36SMatthias Ringwald     sm_key_t ltk;
57*9ed01c36SMatthias Ringwald     uint16_t ediv;
58*9ed01c36SMatthias Ringwald     uint8_t  rand[8];
59*9ed01c36SMatthias Ringwald     uint8_t  key_size;
60*9ed01c36SMatthias Ringwald     uint8_t  authenticated;
61*9ed01c36SMatthias Ringwald     uint8_t  authorized;
62*9ed01c36SMatthias Ringwald 
63*9ed01c36SMatthias Ringwald     // Signed Writes by remote
64*9ed01c36SMatthias Ringwald     sm_key_t remote_csrk;
65*9ed01c36SMatthias Ringwald     uint32_t remote_counter;
66*9ed01c36SMatthias Ringwald 
67*9ed01c36SMatthias Ringwald     // Signed Writes by us
68*9ed01c36SMatthias Ringwald     sm_key_t local_csrk;
69*9ed01c36SMatthias Ringwald     uint32_t local_counter;
70*9ed01c36SMatthias Ringwald 
71*9ed01c36SMatthias Ringwald } le_device_memory_db_t;
72*9ed01c36SMatthias Ringwald 
73*9ed01c36SMatthias Ringwald #define LE_DEVICE_MEMORY_SIZE 20
74*9ed01c36SMatthias Ringwald #define INVALID_ENTRY_ADDR_TYPE 0xff
75*9ed01c36SMatthias Ringwald const char * db_path = "/tmp/btstack_le_device_db.txt";
76*9ed01c36SMatthias 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*9ed01c36SMatthias Ringwald 
78*9ed01c36SMatthias Ringwald static le_device_memory_db_t le_devices[LE_DEVICE_MEMORY_SIZE];
79*9ed01c36SMatthias Ringwald 
80*9ed01c36SMatthias Ringwald static inline void write_delimiter(FILE * wFile){
81*9ed01c36SMatthias Ringwald     fwrite(", ", 1, 1, wFile);
82*9ed01c36SMatthias Ringwald }
83*9ed01c36SMatthias Ringwald static inline void write_hex_byte(FILE * wFile, uint8_t value){
84*9ed01c36SMatthias Ringwald     char buffer[2];
85*9ed01c36SMatthias Ringwald     buffer[0] = char_for_nibble(value >>   4);
86*9ed01c36SMatthias Ringwald     buffer[1] = char_for_nibble(value & 0x0f);
87*9ed01c36SMatthias Ringwald     fwrite(buffer, 2, 1, wFile);
88*9ed01c36SMatthias Ringwald }
89*9ed01c36SMatthias Ringwald 
90*9ed01c36SMatthias Ringwald static inline void write_str(FILE * wFile, const char * str){
91*9ed01c36SMatthias Ringwald     fwrite(str, strlen(str), 1, wFile);
92*9ed01c36SMatthias Ringwald     write_delimiter(wFile);
93*9ed01c36SMatthias Ringwald }
94*9ed01c36SMatthias Ringwald static void write_hex(FILE * wFile, const uint8_t * value, int len){
95*9ed01c36SMatthias Ringwald     int i;
96*9ed01c36SMatthias Ringwald     for (i = 0; i < len; i++){
97*9ed01c36SMatthias Ringwald         write_hex_byte(wFile, value[i]);
98*9ed01c36SMatthias Ringwald     }
99*9ed01c36SMatthias Ringwald     write_delimiter(wFile);
100*9ed01c36SMatthias Ringwald }
101*9ed01c36SMatthias Ringwald static void write_value(FILE * wFile, uint32_t value, int len){
102*9ed01c36SMatthias Ringwald     switch (len){
103*9ed01c36SMatthias Ringwald         case 4:
104*9ed01c36SMatthias Ringwald             write_hex_byte(wFile, value >> 24);
105*9ed01c36SMatthias Ringwald         case 3:
106*9ed01c36SMatthias Ringwald             write_hex_byte(wFile, value >> 16);
107*9ed01c36SMatthias Ringwald         case 2:
108*9ed01c36SMatthias Ringwald             write_hex_byte(wFile, value >> 8);
109*9ed01c36SMatthias Ringwald         case 1:
110*9ed01c36SMatthias Ringwald         default:
111*9ed01c36SMatthias Ringwald             write_hex_byte(wFile, value);
112*9ed01c36SMatthias Ringwald     }
113*9ed01c36SMatthias Ringwald     write_delimiter(wFile);
114*9ed01c36SMatthias Ringwald }
115*9ed01c36SMatthias Ringwald 
116*9ed01c36SMatthias Ringwald static void le_device_db_store(void) {
117*9ed01c36SMatthias Ringwald     int i;
118*9ed01c36SMatthias Ringwald     // open file
119*9ed01c36SMatthias Ringwald     FILE * wFile = fopen(db_path,"w+");
120*9ed01c36SMatthias Ringwald     if (wFile == NULL) return;
121*9ed01c36SMatthias Ringwald     fwrite(csv_header, strlen(csv_header), 1, wFile);
122*9ed01c36SMatthias Ringwald     fwrite("\n", 1, 1, wFile);
123*9ed01c36SMatthias Ringwald     for (i=0;i<LE_DEVICE_MEMORY_SIZE;i++){
124*9ed01c36SMatthias Ringwald         if (le_devices[i].addr_type == INVALID_ENTRY_ADDR_TYPE) continue;
125*9ed01c36SMatthias Ringwald         write_value(wFile, le_devices[i].addr_type, 1);
126*9ed01c36SMatthias Ringwald         write_str(wFile,   bd_addr_to_str(le_devices[i].addr));
127*9ed01c36SMatthias Ringwald         write_hex(wFile,   le_devices[i].irk, 16);
128*9ed01c36SMatthias Ringwald         write_hex(wFile,   le_devices[i].ltk, 16);
129*9ed01c36SMatthias Ringwald         write_value(wFile, le_devices[i].ediv, 2);
130*9ed01c36SMatthias Ringwald         write_hex(wFile,   le_devices[i].rand, 8);
131*9ed01c36SMatthias Ringwald         write_value(wFile, le_devices[i].key_size, 1);
132*9ed01c36SMatthias Ringwald         write_value(wFile, le_devices[i].authenticated, 1);
133*9ed01c36SMatthias Ringwald         write_value(wFile, le_devices[i].authorized, 1);
134*9ed01c36SMatthias Ringwald         write_hex(wFile,   le_devices[i].remote_csrk, 16);
135*9ed01c36SMatthias Ringwald         write_value(wFile, le_devices[i].remote_counter, 2);
136*9ed01c36SMatthias Ringwald         write_hex(wFile,   le_devices[i].local_csrk, 16);
137*9ed01c36SMatthias Ringwald         write_value(wFile, le_devices[i].local_counter, 2);
138*9ed01c36SMatthias Ringwald         fwrite("\n", 1, 1, wFile);
139*9ed01c36SMatthias Ringwald     }
140*9ed01c36SMatthias Ringwald     fclose(wFile);
141*9ed01c36SMatthias Ringwald }
142*9ed01c36SMatthias Ringwald static void read_delimiter(FILE * wFile){
143*9ed01c36SMatthias Ringwald     fgetc(wFile);
144*9ed01c36SMatthias Ringwald }
145*9ed01c36SMatthias Ringwald 
146*9ed01c36SMatthias Ringwald static uint8_t read_hex_byte(FILE * wFile){
147*9ed01c36SMatthias Ringwald     int c = fgetc(wFile);
148*9ed01c36SMatthias Ringwald     if (c == ':') {
149*9ed01c36SMatthias Ringwald         c = fgetc(wFile);
150*9ed01c36SMatthias Ringwald     }
151*9ed01c36SMatthias Ringwald     int d = fgetc(wFile);
152*9ed01c36SMatthias Ringwald     return nibble_for_char(c) << 4 | nibble_for_char(d);
153*9ed01c36SMatthias Ringwald }
154*9ed01c36SMatthias Ringwald 
155*9ed01c36SMatthias Ringwald static void read_hex(FILE * wFile, uint8_t * buffer, int len){
156*9ed01c36SMatthias Ringwald     int i;
157*9ed01c36SMatthias Ringwald     for (i=0;i<len;i++){
158*9ed01c36SMatthias Ringwald         buffer[i] = read_hex_byte(wFile);
159*9ed01c36SMatthias Ringwald     }
160*9ed01c36SMatthias Ringwald     read_delimiter(wFile);
161*9ed01c36SMatthias Ringwald }
162*9ed01c36SMatthias Ringwald 
163*9ed01c36SMatthias Ringwald static uint32_t read_value(FILE * wFile, int len){
164*9ed01c36SMatthias Ringwald     uint32_t res = 0;
165*9ed01c36SMatthias Ringwald     int i;
166*9ed01c36SMatthias Ringwald     for (i=0;i<len;i++){
167*9ed01c36SMatthias Ringwald         res = res << 8 | read_hex_byte(wFile);
168*9ed01c36SMatthias Ringwald     }
169*9ed01c36SMatthias Ringwald     read_delimiter(wFile);
170*9ed01c36SMatthias Ringwald     return res;
171*9ed01c36SMatthias Ringwald }
172*9ed01c36SMatthias Ringwald 
173*9ed01c36SMatthias Ringwald static void le_device_db_read(void){
174*9ed01c36SMatthias Ringwald     // open file
175*9ed01c36SMatthias Ringwald     FILE * wFile = fopen(db_path,"r");
176*9ed01c36SMatthias Ringwald     if (wFile == NULL) return;
177*9ed01c36SMatthias Ringwald     // skip header
178*9ed01c36SMatthias Ringwald     while (1) {
179*9ed01c36SMatthias Ringwald         int c = fgetc(wFile);
180*9ed01c36SMatthias Ringwald         if (feof(wFile)) goto exit;
181*9ed01c36SMatthias Ringwald         if (c == '\n') break;
182*9ed01c36SMatthias Ringwald     }
183*9ed01c36SMatthias Ringwald     // read entries
184*9ed01c36SMatthias Ringwald     int i;
185*9ed01c36SMatthias Ringwald     for (i=0;i<LE_DEVICE_MEMORY_SIZE && !feof(wFile);i++){
186*9ed01c36SMatthias Ringwald         le_devices[i].addr_type = read_value(wFile, 1);
187*9ed01c36SMatthias Ringwald         read_hex(wFile,   le_devices[i].addr, 6);
188*9ed01c36SMatthias Ringwald         read_hex(wFile,   le_devices[i].irk, 16);
189*9ed01c36SMatthias Ringwald         read_hex(wFile,   le_devices[i].ltk, 16);
190*9ed01c36SMatthias Ringwald         le_devices[i].ediv = read_value(wFile, 2);
191*9ed01c36SMatthias Ringwald         read_hex(wFile,   le_devices[i].rand, 8);
192*9ed01c36SMatthias Ringwald         le_devices[i].key_size      = read_value(wFile, 1);
193*9ed01c36SMatthias Ringwald         le_devices[i].authenticated = read_value(wFile, 1);
194*9ed01c36SMatthias Ringwald         le_devices[i].authorized    = read_value(wFile, 1);
195*9ed01c36SMatthias Ringwald         read_hex(wFile,   le_devices[i].remote_csrk, 16);
196*9ed01c36SMatthias Ringwald         le_devices[i].remote_counter = read_value(wFile, 2);
197*9ed01c36SMatthias Ringwald         read_hex(wFile,   le_devices[i].local_csrk, 16);
198*9ed01c36SMatthias Ringwald         le_devices[i].local_counter = read_value(wFile, 2);
199*9ed01c36SMatthias Ringwald         // read newling
200*9ed01c36SMatthias Ringwald         fgetc(wFile);
201*9ed01c36SMatthias Ringwald     }
202*9ed01c36SMatthias Ringwald exit:
203*9ed01c36SMatthias Ringwald     fclose(wFile);
204*9ed01c36SMatthias Ringwald }
205*9ed01c36SMatthias Ringwald 
206*9ed01c36SMatthias Ringwald void le_device_db_init(void){
207*9ed01c36SMatthias Ringwald     int i;
208*9ed01c36SMatthias Ringwald     for (i=0;i<LE_DEVICE_MEMORY_SIZE;i++){
209*9ed01c36SMatthias Ringwald         le_devices[i].addr_type = INVALID_ENTRY_ADDR_TYPE;
210*9ed01c36SMatthias Ringwald     }
211*9ed01c36SMatthias Ringwald     le_device_db_read();
212*9ed01c36SMatthias Ringwald     le_device_db_dump();
213*9ed01c36SMatthias Ringwald }
214*9ed01c36SMatthias Ringwald 
215*9ed01c36SMatthias Ringwald // @returns number of device in db
216*9ed01c36SMatthias Ringwald int le_device_db_count(void){
217*9ed01c36SMatthias Ringwald     int i;
218*9ed01c36SMatthias Ringwald     int counter = 0;
219*9ed01c36SMatthias Ringwald     for (i=0;i<LE_DEVICE_MEMORY_SIZE;i++){
220*9ed01c36SMatthias Ringwald         if (le_devices[i].addr_type != INVALID_ENTRY_ADDR_TYPE) counter++;
221*9ed01c36SMatthias Ringwald     }
222*9ed01c36SMatthias Ringwald     return counter;
223*9ed01c36SMatthias Ringwald }
224*9ed01c36SMatthias Ringwald 
225*9ed01c36SMatthias Ringwald // free device
226*9ed01c36SMatthias Ringwald void le_device_db_remove(int index){
227*9ed01c36SMatthias Ringwald     le_devices[index].addr_type = INVALID_ENTRY_ADDR_TYPE;
228*9ed01c36SMatthias Ringwald     le_device_db_store();
229*9ed01c36SMatthias Ringwald }
230*9ed01c36SMatthias Ringwald 
231*9ed01c36SMatthias Ringwald int le_device_db_add(int addr_type, bd_addr_t addr, sm_key_t irk){
232*9ed01c36SMatthias Ringwald     int i;
233*9ed01c36SMatthias Ringwald     int index = -1;
234*9ed01c36SMatthias Ringwald     for (i=0;i<LE_DEVICE_MEMORY_SIZE;i++){
235*9ed01c36SMatthias Ringwald          if (le_devices[i].addr_type == INVALID_ENTRY_ADDR_TYPE){
236*9ed01c36SMatthias Ringwald             index = i;
237*9ed01c36SMatthias Ringwald             break;
238*9ed01c36SMatthias Ringwald          }
239*9ed01c36SMatthias Ringwald     }
240*9ed01c36SMatthias Ringwald 
241*9ed01c36SMatthias Ringwald     if (index < 0) return -1;
242*9ed01c36SMatthias Ringwald 
243*9ed01c36SMatthias Ringwald     log_info("Central Device DB adding type %u - %s", addr_type, bd_addr_to_str(addr));
244*9ed01c36SMatthias Ringwald     log_info_key("irk", irk);
245*9ed01c36SMatthias Ringwald 
246*9ed01c36SMatthias Ringwald     le_devices[index].addr_type = addr_type;
247*9ed01c36SMatthias Ringwald     memcpy(le_devices[index].addr, addr, 6);
248*9ed01c36SMatthias Ringwald     memcpy(le_devices[index].irk, irk, 16);
249*9ed01c36SMatthias Ringwald     le_devices[index].remote_counter = 0;
250*9ed01c36SMatthias Ringwald 
251*9ed01c36SMatthias Ringwald     le_device_db_store();
252*9ed01c36SMatthias Ringwald 
253*9ed01c36SMatthias Ringwald     return index;
254*9ed01c36SMatthias Ringwald }
255*9ed01c36SMatthias Ringwald 
256*9ed01c36SMatthias Ringwald 
257*9ed01c36SMatthias Ringwald // get device information: addr type and address
258*9ed01c36SMatthias Ringwald void le_device_db_info(int index, int * addr_type, bd_addr_t addr, sm_key_t irk){
259*9ed01c36SMatthias Ringwald     if (addr_type) *addr_type = le_devices[index].addr_type;
260*9ed01c36SMatthias Ringwald     if (addr) memcpy(addr, le_devices[index].addr, 6);
261*9ed01c36SMatthias Ringwald     if (irk) memcpy(irk, le_devices[index].irk, 16);
262*9ed01c36SMatthias Ringwald }
263*9ed01c36SMatthias Ringwald 
264*9ed01c36SMatthias 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){
265*9ed01c36SMatthias Ringwald     log_info("Central Device DB set encryption for %u, ediv x%04x, key size %u, authenticated %u, authorized %u",
266*9ed01c36SMatthias Ringwald         index, ediv, key_size, authenticated, authorized);
267*9ed01c36SMatthias Ringwald     le_device_memory_db_t * device = &le_devices[index];
268*9ed01c36SMatthias Ringwald     device->ediv = ediv;
269*9ed01c36SMatthias Ringwald     if (rand) memcpy(device->rand, rand, 8);
270*9ed01c36SMatthias Ringwald     if (ltk) memcpy(device->ltk, ltk, 16);
271*9ed01c36SMatthias Ringwald     device->key_size = key_size;
272*9ed01c36SMatthias Ringwald     device->authenticated = authenticated;
273*9ed01c36SMatthias Ringwald     device->authorized = authorized;
274*9ed01c36SMatthias Ringwald 
275*9ed01c36SMatthias Ringwald     le_device_db_store();
276*9ed01c36SMatthias Ringwald }
277*9ed01c36SMatthias Ringwald 
278*9ed01c36SMatthias 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){
279*9ed01c36SMatthias Ringwald     le_device_memory_db_t * device = &le_devices[index];
280*9ed01c36SMatthias Ringwald     log_info("Central Device DB encryption for %u, ediv x%04x, keysize %u, authenticated %u, authorized %u",
281*9ed01c36SMatthias Ringwald         index, device->ediv, device->key_size, device->authenticated, device->authorized);
282*9ed01c36SMatthias Ringwald     if (ediv) *ediv = device->ediv;
283*9ed01c36SMatthias Ringwald     if (rand) memcpy(rand, device->rand, 8);
284*9ed01c36SMatthias Ringwald     if (ltk)  memcpy(ltk, device->ltk, 16);
285*9ed01c36SMatthias Ringwald     if (key_size) *key_size = device->key_size;
286*9ed01c36SMatthias Ringwald     if (authenticated) *authenticated = device->authenticated;
287*9ed01c36SMatthias Ringwald     if (authorized) *authorized = device->authorized;
288*9ed01c36SMatthias Ringwald }
289*9ed01c36SMatthias Ringwald 
290*9ed01c36SMatthias Ringwald // get signature key
291*9ed01c36SMatthias Ringwald void le_device_db_remote_csrk_get(int index, sm_key_t csrk){
292*9ed01c36SMatthias Ringwald     if (index < 0 || index >= LE_DEVICE_MEMORY_SIZE){
293*9ed01c36SMatthias Ringwald         log_error("le_device_db_remote_csrk_get called with invalid index %d", index);
294*9ed01c36SMatthias Ringwald         return;
295*9ed01c36SMatthias Ringwald     }
296*9ed01c36SMatthias Ringwald     if (csrk) memcpy(csrk, le_devices[index].remote_csrk, 16);
297*9ed01c36SMatthias Ringwald }
298*9ed01c36SMatthias Ringwald 
299*9ed01c36SMatthias Ringwald void le_device_db_remote_csrk_set(int index, sm_key_t csrk){
300*9ed01c36SMatthias Ringwald     if (index < 0 || index >= LE_DEVICE_MEMORY_SIZE){
301*9ed01c36SMatthias Ringwald         log_error("le_device_db_remote_csrk_set called with invalid index %d", index);
302*9ed01c36SMatthias Ringwald         return;
303*9ed01c36SMatthias Ringwald     }
304*9ed01c36SMatthias Ringwald     if (csrk) memcpy(le_devices[index].remote_csrk, csrk, 16);
305*9ed01c36SMatthias Ringwald 
306*9ed01c36SMatthias Ringwald     le_device_db_store();
307*9ed01c36SMatthias Ringwald }
308*9ed01c36SMatthias Ringwald 
309*9ed01c36SMatthias Ringwald void le_device_db_local_csrk_get(int index, sm_key_t csrk){
310*9ed01c36SMatthias Ringwald     if (index < 0 || index >= LE_DEVICE_MEMORY_SIZE){
311*9ed01c36SMatthias Ringwald         log_error("le_device_db_local_csrk_get called with invalid index %d", index);
312*9ed01c36SMatthias Ringwald         return;
313*9ed01c36SMatthias Ringwald     }
314*9ed01c36SMatthias Ringwald     if (csrk) memcpy(csrk, le_devices[index].local_csrk, 16);
315*9ed01c36SMatthias Ringwald }
316*9ed01c36SMatthias Ringwald 
317*9ed01c36SMatthias Ringwald void le_device_db_local_csrk_set(int index, sm_key_t csrk){
318*9ed01c36SMatthias Ringwald     if (index < 0 || index >= LE_DEVICE_MEMORY_SIZE){
319*9ed01c36SMatthias Ringwald         log_error("le_device_db_local_csrk_set called with invalid index %d", index);
320*9ed01c36SMatthias Ringwald         return;
321*9ed01c36SMatthias Ringwald     }
322*9ed01c36SMatthias Ringwald     if (csrk) memcpy(le_devices[index].local_csrk, csrk, 16);
323*9ed01c36SMatthias Ringwald 
324*9ed01c36SMatthias Ringwald     le_device_db_store();
325*9ed01c36SMatthias Ringwald }
326*9ed01c36SMatthias Ringwald 
327*9ed01c36SMatthias Ringwald // query last used/seen signing counter
328*9ed01c36SMatthias Ringwald uint32_t le_device_db_remote_counter_get(int index){
329*9ed01c36SMatthias Ringwald     return le_devices[index].remote_counter;
330*9ed01c36SMatthias Ringwald }
331*9ed01c36SMatthias Ringwald 
332*9ed01c36SMatthias Ringwald // update signing counter
333*9ed01c36SMatthias Ringwald void le_device_db_remote_counter_set(int index, uint32_t counter){
334*9ed01c36SMatthias Ringwald     le_devices[index].remote_counter = counter;
335*9ed01c36SMatthias Ringwald 
336*9ed01c36SMatthias Ringwald     le_device_db_store();
337*9ed01c36SMatthias Ringwald }
338*9ed01c36SMatthias Ringwald 
339*9ed01c36SMatthias Ringwald // query last used/seen signing counter
340*9ed01c36SMatthias Ringwald uint32_t le_device_db_local_counter_get(int index){
341*9ed01c36SMatthias Ringwald     return le_devices[index].local_counter;
342*9ed01c36SMatthias Ringwald }
343*9ed01c36SMatthias Ringwald 
344*9ed01c36SMatthias Ringwald // update signing counter
345*9ed01c36SMatthias Ringwald void le_device_db_local_counter_set(int index, uint32_t counter){
346*9ed01c36SMatthias Ringwald     le_devices[index].local_counter = counter;
347*9ed01c36SMatthias Ringwald 
348*9ed01c36SMatthias Ringwald     le_device_db_store();
349*9ed01c36SMatthias Ringwald }
350*9ed01c36SMatthias Ringwald 
351*9ed01c36SMatthias Ringwald void le_device_db_dump(void){
352*9ed01c36SMatthias Ringwald     log_info("Central Device DB dump, devices: %d", le_device_db_count());
353*9ed01c36SMatthias Ringwald     int i;
354*9ed01c36SMatthias Ringwald     for (i=0;i<LE_DEVICE_MEMORY_SIZE;i++){
355*9ed01c36SMatthias Ringwald         if (le_devices[i].addr_type == INVALID_ENTRY_ADDR_TYPE) continue;
356*9ed01c36SMatthias Ringwald         log_info("%u: %u %s", i, le_devices[i].addr_type, bd_addr_to_str(le_devices[i].addr));
357*9ed01c36SMatthias Ringwald         log_info_key("ltk", le_devices[i].ltk);
358*9ed01c36SMatthias Ringwald         log_info_key("irk", le_devices[i].irk);
359*9ed01c36SMatthias Ringwald         log_info_key("local csrk", le_devices[i].local_csrk);
360*9ed01c36SMatthias Ringwald         log_info_key("remote csrk", le_devices[i].remote_csrk);
361*9ed01c36SMatthias Ringwald     }
362*9ed01c36SMatthias Ringwald }
363