xref: /btstack/platform/wiced/le_device_db_wiced_dct.c (revision 2fca4dad957cd7b88f4657ed51e89c12615dda72)
113e71c7bSMatthias Ringwald /*
213e71c7bSMatthias Ringwald  * Copyright (C) 2016 BlueKitchen GmbH
313e71c7bSMatthias Ringwald  *
413e71c7bSMatthias Ringwald  * Redistribution and use in source and binary forms, with or without
513e71c7bSMatthias Ringwald  * modification, are permitted provided that the following conditions
613e71c7bSMatthias Ringwald  * are met:
713e71c7bSMatthias Ringwald  *
813e71c7bSMatthias Ringwald  * 1. Redistributions of source code must retain the above copyright
913e71c7bSMatthias Ringwald  *    notice, this list of conditions and the following disclaimer.
1013e71c7bSMatthias Ringwald  * 2. Redistributions in binary form must reproduce the above copyright
1113e71c7bSMatthias Ringwald  *    notice, this list of conditions and the following disclaimer in the
1213e71c7bSMatthias Ringwald  *    documentation and/or other materials provided with the distribution.
1313e71c7bSMatthias Ringwald  * 3. Neither the name of the copyright holders nor the names of
1413e71c7bSMatthias Ringwald  *    contributors may be used to endorse or promote products derived
1513e71c7bSMatthias Ringwald  *    from this software without specific prior written permission.
1613e71c7bSMatthias Ringwald  * 4. Any redistribution, use, or modification is done solely for
1713e71c7bSMatthias Ringwald  *    personal benefit and not for any commercial purpose or for
1813e71c7bSMatthias Ringwald  *    monetary gain.
1913e71c7bSMatthias Ringwald  *
2013e71c7bSMatthias Ringwald  * THIS SOFTWARE IS PROVIDED BY BLUEKITCHEN GMBH AND CONTRIBUTORS
2113e71c7bSMatthias Ringwald  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
2213e71c7bSMatthias Ringwald  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
23*2fca4dadSMilanka Ringwald  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BLUEKITCHEN
24*2fca4dadSMilanka Ringwald  * GMBH OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
2513e71c7bSMatthias Ringwald  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
2613e71c7bSMatthias Ringwald  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
2713e71c7bSMatthias Ringwald  * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
2813e71c7bSMatthias Ringwald  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
2913e71c7bSMatthias Ringwald  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
3013e71c7bSMatthias Ringwald  * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
3113e71c7bSMatthias Ringwald  * SUCH DAMAGE.
3213e71c7bSMatthias Ringwald  *
3313e71c7bSMatthias Ringwald  * Please inquire about commercial licensing options at
3413e71c7bSMatthias Ringwald  * [email protected]
3513e71c7bSMatthias Ringwald  *
3613e71c7bSMatthias Ringwald  */
3713e71c7bSMatthias Ringwald 
38e501bae0SMatthias Ringwald #define BTSTACK_FILE__ "le_device_db_wiced_dct.c"
3913e71c7bSMatthias Ringwald 
4013e71c7bSMatthias Ringwald /*
4113e71c7bSMatthias Ringwald  *  le_device_db_wiced_dct.c
4213e71c7bSMatthias Ringwald  *
4313e71c7bSMatthias Ringwald  *  Persistent LE Device DB implemenetation for WICED using DCT mechanism
4413e71c7bSMatthias Ringwald  */
4513e71c7bSMatthias Ringwald 
4613e71c7bSMatthias Ringwald #include "stdint.h"
4713e71c7bSMatthias Ringwald #include "string.h"
4813e71c7bSMatthias Ringwald #include "inttypes.h"
4913e71c7bSMatthias Ringwald 
5013e71c7bSMatthias Ringwald #include "wiced.h"
5113e71c7bSMatthias Ringwald 
5213e71c7bSMatthias Ringwald #include "ble/le_device_db.h"
5313e71c7bSMatthias Ringwald #include "btstack_link_key_db_wiced_dct.h"	// for size of
5413e71c7bSMatthias Ringwald 
5513e71c7bSMatthias Ringwald #include "btstack_debug.h"
5613e71c7bSMatthias Ringwald #include "btstack_util.h"
5713e71c7bSMatthias Ringwald 
5813e71c7bSMatthias Ringwald // Link Key Magic
5913e71c7bSMatthias Ringwald #define LE_DEVICE_MAGIC ((uint32_t) 'L' << 24 | 'E' << 16 | 'D' << 8 | 'B')
6013e71c7bSMatthias Ringwald 
6113e71c7bSMatthias Ringwald typedef struct le_device_nvm {
6213e71c7bSMatthias Ringwald 	uint32_t magic;
6313e71c7bSMatthias Ringwald 	uint32_t seq_nr;	// used for "last recently stored" eviction strategy
6413e71c7bSMatthias Ringwald 
6513e71c7bSMatthias Ringwald     // Identification
6613e71c7bSMatthias Ringwald     sm_key_t irk;
6713e71c7bSMatthias Ringwald     bd_addr_t addr;
6813e71c7bSMatthias Ringwald     uint8_t addr_type;
6913e71c7bSMatthias Ringwald 
7013e71c7bSMatthias Ringwald     // pairing information
7113e71c7bSMatthias Ringwald     uint8_t  key_size;
7213e71c7bSMatthias Ringwald     uint8_t  authenticated;
7313e71c7bSMatthias Ringwald     uint8_t  authorized;
743dc3a67dSMatthias Ringwald     uint8_t  secure_connection;
753dc3a67dSMatthias Ringwald 
7613e71c7bSMatthias Ringwald     sm_key_t ltk;
7713e71c7bSMatthias Ringwald 
7813e71c7bSMatthias Ringwald     // Stored pairing information allows to re-establish an enncrypted connection
7913e71c7bSMatthias Ringwald     // with a peripheral that doesn't have any persistent memory
8013e71c7bSMatthias Ringwald     uint16_t ediv;
8113e71c7bSMatthias Ringwald     uint8_t  rand[8];
8213e71c7bSMatthias Ringwald 
8313e71c7bSMatthias Ringwald } le_device_nvm_t;
8413e71c7bSMatthias Ringwald 
8513e71c7bSMatthias Ringwald static uint32_t start_of_le_device_db;
8613e71c7bSMatthias Ringwald 
8713e71c7bSMatthias Ringwald // calculate address
le_device_db_address_for_absolute_index(int abolute_index)8813e71c7bSMatthias Ringwald static int le_device_db_address_for_absolute_index(int abolute_index){
8913e71c7bSMatthias Ringwald 	return start_of_le_device_db + abolute_index * sizeof(le_device_nvm_t);
9013e71c7bSMatthias Ringwald }
9113e71c7bSMatthias Ringwald 
le_device_db_entry_valid(int absolute_index)9213e71c7bSMatthias Ringwald static int le_device_db_entry_valid(int absolute_index){
9313e71c7bSMatthias Ringwald 	// read lock
9413e71c7bSMatthias Ringwald 	le_device_nvm_t * entry;
9513e71c7bSMatthias Ringwald 	wiced_dct_read_lock((void*) &entry, WICED_FALSE, DCT_APP_SECTION, le_device_db_address_for_absolute_index(absolute_index), sizeof(le_device_nvm_t));
9613e71c7bSMatthias Ringwald 	int valid = entry->magic == LE_DEVICE_MAGIC;
9713e71c7bSMatthias Ringwald 	// read unlock
9813e71c7bSMatthias Ringwald 	wiced_dct_read_unlock((void*) entry, WICED_FALSE);
9913e71c7bSMatthias Ringwald 	return valid;
10013e71c7bSMatthias Ringwald }
10113e71c7bSMatthias Ringwald 
10213e71c7bSMatthias Ringwald // @return valid
le_device_db_entry_read(int absolute_index,le_device_nvm_t * out_entry)10313e71c7bSMatthias Ringwald static int le_device_db_entry_read(int absolute_index, le_device_nvm_t * out_entry){
10413e71c7bSMatthias Ringwald 
10513e71c7bSMatthias Ringwald 	// read lock
10613e71c7bSMatthias Ringwald 	le_device_nvm_t * entry;
10713e71c7bSMatthias Ringwald 	wiced_dct_read_lock((void*) &entry, WICED_FALSE, DCT_APP_SECTION, le_device_db_address_for_absolute_index(absolute_index), sizeof(le_device_nvm_t));
10813e71c7bSMatthias Ringwald 
10913e71c7bSMatthias Ringwald 	if (entry->magic == LE_DEVICE_MAGIC){
11013e71c7bSMatthias Ringwald 		memcpy(out_entry, entry, sizeof(le_device_nvm_t));
11113e71c7bSMatthias Ringwald 	} else {
11213e71c7bSMatthias Ringwald 		memset(out_entry, 0, sizeof(le_device_nvm_t));
11313e71c7bSMatthias Ringwald 	}
11413e71c7bSMatthias Ringwald 
11513e71c7bSMatthias Ringwald 	// read unlock
11613e71c7bSMatthias Ringwald 	wiced_dct_read_unlock((void*) entry, WICED_FALSE);
11713e71c7bSMatthias Ringwald 
11813e71c7bSMatthias Ringwald 	return out_entry->magic == LE_DEVICE_MAGIC;
11913e71c7bSMatthias Ringwald }
12013e71c7bSMatthias Ringwald 
le_device_db_entry_write(int absolute_index,le_device_nvm_t * entry)12113e71c7bSMatthias Ringwald static void le_device_db_entry_write(int absolute_index, le_device_nvm_t * entry){
12213e71c7bSMatthias Ringwald 	// write block
12313e71c7bSMatthias Ringwald 	wiced_dct_write((void*)entry, DCT_APP_SECTION, le_device_db_address_for_absolute_index(absolute_index), sizeof(le_device_nvm_t));
12413e71c7bSMatthias Ringwald }
12513e71c7bSMatthias Ringwald 
le_device_db_highest_seq_nr(void)12613e71c7bSMatthias Ringwald static uint32_t le_device_db_highest_seq_nr(void){
12713e71c7bSMatthias Ringwald 	le_device_nvm_t entry;
12813e71c7bSMatthias Ringwald 	int i;
12913e71c7bSMatthias Ringwald 	uint32_t seq_nr = 0;
13013e71c7bSMatthias Ringwald 	for (i=0;i<NVM_NUM_LE_DEVICES;i++){
13113e71c7bSMatthias Ringwald 		le_device_db_entry_read(i, &entry);
13213e71c7bSMatthias Ringwald 		if (entry.magic != LE_DEVICE_MAGIC) continue;
13313e71c7bSMatthias Ringwald 		if (entry.seq_nr < seq_nr) continue;
13413e71c7bSMatthias Ringwald 		seq_nr = entry.seq_nr;
13513e71c7bSMatthias Ringwald 	}
13613e71c7bSMatthias Ringwald 	return seq_nr;
13713e71c7bSMatthias Ringwald }
13813e71c7bSMatthias Ringwald 
13913e71c7bSMatthias Ringwald // returns absoulte index
le_device_db_find_free_entry(void)14013e71c7bSMatthias Ringwald static int le_device_db_find_free_entry(void){
14113e71c7bSMatthias Ringwald 	le_device_nvm_t entry;
14213e71c7bSMatthias Ringwald 	int i;
14313e71c7bSMatthias Ringwald 	uint32_t seq_nr = 0;
14413e71c7bSMatthias Ringwald 	int lowest_index = -1;
14513e71c7bSMatthias Ringwald 	for (i=0;i<NVM_NUM_LE_DEVICES;i++){
14613e71c7bSMatthias Ringwald 		le_device_db_entry_read(i, &entry);
14713e71c7bSMatthias Ringwald 		if (entry.magic != LE_DEVICE_MAGIC) return i;
14813e71c7bSMatthias Ringwald 		if ((lowest_index < 0) || (entry.seq_nr < seq_nr)){
14913e71c7bSMatthias Ringwald 			lowest_index = i;
15013e71c7bSMatthias Ringwald 			seq_nr= entry.seq_nr;
15113e71c7bSMatthias Ringwald 		}
15213e71c7bSMatthias Ringwald 	}
15313e71c7bSMatthias Ringwald 	return lowest_index;
15413e71c7bSMatthias Ringwald }
15513e71c7bSMatthias Ringwald 
15613e71c7bSMatthias Ringwald // returns absolute index
le_device_db_get_absolute_index_for_device_index(int device_index)15713e71c7bSMatthias Ringwald static int le_device_db_get_absolute_index_for_device_index(int device_index){
15813e71c7bSMatthias Ringwald     int i;
15913e71c7bSMatthias Ringwald     int counter = 0;
16013e71c7bSMatthias Ringwald     for (i=0;i<NVM_NUM_LE_DEVICES;i++){
16113e71c7bSMatthias Ringwald     	if (le_device_db_entry_valid(i)) {
16213e71c7bSMatthias Ringwald     		// found
16313e71c7bSMatthias Ringwald     		if (counter == device_index) return i;
16413e71c7bSMatthias Ringwald     		counter++;
16513e71c7bSMatthias Ringwald     	}
16613e71c7bSMatthias Ringwald     }
16713e71c7bSMatthias Ringwald     return 0;
16813e71c7bSMatthias Ringwald }
16913e71c7bSMatthias Ringwald 
17013e71c7bSMatthias Ringwald // PUBLIC API
17113e71c7bSMatthias Ringwald 
le_device_db_wiced_dct_set_start_address(uint32_t start_address)17213e71c7bSMatthias Ringwald void le_device_db_wiced_dct_set_start_address(uint32_t start_address){
17313e71c7bSMatthias Ringwald 	log_info("set start address: %"PRIu32, start_address);
17413e71c7bSMatthias Ringwald 	start_of_le_device_db = start_address;
17513e71c7bSMatthias Ringwald }
17613e71c7bSMatthias Ringwald 
le_device_db_init(void)17713e71c7bSMatthias Ringwald void le_device_db_init(void){
17813e71c7bSMatthias Ringwald }
17913e71c7bSMatthias Ringwald 
le_device_db_set_local_bd_addr(bd_addr_t addr)18013e71c7bSMatthias Ringwald void le_device_db_set_local_bd_addr(bd_addr_t addr){
18113e71c7bSMatthias Ringwald 	(void) addr;
18213e71c7bSMatthias Ringwald }
18313e71c7bSMatthias Ringwald 
18413e71c7bSMatthias Ringwald // @returns number of device in db
le_device_db_count(void)18513e71c7bSMatthias Ringwald int le_device_db_count(void){
18613e71c7bSMatthias Ringwald     int i;
18713e71c7bSMatthias Ringwald     int counter = 0;
18813e71c7bSMatthias Ringwald     for (i=0;i<NVM_NUM_LE_DEVICES;i++){
18913e71c7bSMatthias Ringwald     	if (le_device_db_entry_valid(i)) counter++;
19013e71c7bSMatthias Ringwald     }
19113e71c7bSMatthias Ringwald     return counter;
19213e71c7bSMatthias Ringwald }
19313e71c7bSMatthias Ringwald 
le_device_db_max_count(void)1946fc9dda1SMatthias Ringwald int le_device_db_max_count(void){
1956fc9dda1SMatthias Ringwald     return NVM_NUM_LE_DEVICES;
1966fc9dda1SMatthias Ringwald }
1976fc9dda1SMatthias Ringwald 
19813e71c7bSMatthias Ringwald // get device information: addr type and address
le_device_db_info(int device_index,int * addr_type,bd_addr_t addr,sm_key_t irk)19913e71c7bSMatthias Ringwald void le_device_db_info(int device_index, int * addr_type, bd_addr_t addr, sm_key_t irk){
20013e71c7bSMatthias Ringwald 	int absolute_index = le_device_db_get_absolute_index_for_device_index(device_index);
20113e71c7bSMatthias Ringwald     le_device_nvm_t entry;
202d14ceebfSMatthias Ringwald     int valid = le_device_db_entry_read(absolute_index, &entry);
203d14ceebfSMatthias Ringwald 
204d14ceebfSMatthias Ringwald     // set defaults if not found
205d14ceebfSMatthias Ringwald     if (!valid) {
206e90da8a6SMatthias Ringwald         memset(&entry, 0, sizeof(le_device_nvm_t));
207d14ceebfSMatthias Ringwald         entry.addr_type = BD_ADDR_TYPE_UNKNOWN;
208d14ceebfSMatthias Ringwald     }
209d14ceebfSMatthias Ringwald 
21013e71c7bSMatthias Ringwald     if (addr_type) *addr_type = entry.addr_type;
21113e71c7bSMatthias Ringwald     if (addr) memcpy(addr, entry.addr, 6);
21213e71c7bSMatthias Ringwald     if (irk) memcpy(irk, entry.irk, 16);
21313e71c7bSMatthias Ringwald }
21413e71c7bSMatthias Ringwald 
21513e71c7bSMatthias Ringwald // free device
le_device_db_remove(int device_index)21613e71c7bSMatthias Ringwald void le_device_db_remove(int device_index){
21713e71c7bSMatthias Ringwald 	int absolute_index = le_device_db_get_absolute_index_for_device_index(device_index);
21813e71c7bSMatthias Ringwald 	le_device_nvm_t entry;
21913e71c7bSMatthias Ringwald 	memset(&entry, 0, sizeof(le_device_nvm_t));
22013e71c7bSMatthias Ringwald 	le_device_db_entry_write(absolute_index, &entry);
22113e71c7bSMatthias Ringwald }
22213e71c7bSMatthias Ringwald 
22313e71c7bSMatthias Ringwald // custom function
le_device_db_wiced_dct_delete_all(void)22413e71c7bSMatthias Ringwald void le_device_db_wiced_dct_delete_all(void){
22513e71c7bSMatthias Ringwald 	int i;
22613e71c7bSMatthias Ringwald 	le_device_nvm_t entry;
22713e71c7bSMatthias Ringwald 	memset(&entry, 0, sizeof(le_device_nvm_t));
22813e71c7bSMatthias Ringwald 	for (i=0;i<NVM_NUM_LE_DEVICES;i++){
22913e71c7bSMatthias Ringwald 		le_device_db_entry_write(i, &entry);
23013e71c7bSMatthias Ringwald 	}
23113e71c7bSMatthias Ringwald }
23213e71c7bSMatthias Ringwald 
le_device_db_add(int addr_type,bd_addr_t addr,sm_key_t irk)23313e71c7bSMatthias Ringwald int le_device_db_add(int addr_type, bd_addr_t addr, sm_key_t irk){
23413e71c7bSMatthias Ringwald     int absolute_index = le_device_db_find_free_entry();
23513e71c7bSMatthias Ringwald     uint32_t seq_nr = le_device_db_highest_seq_nr() + 1;
23613e71c7bSMatthias Ringwald     log_info("adding type %u - %s, seq nr %u, as #%u", addr_type, bd_addr_to_str(addr), (int) seq_nr, absolute_index);
23713e71c7bSMatthias Ringwald     log_info_key("irk", irk);
23813e71c7bSMatthias Ringwald 
23913e71c7bSMatthias Ringwald 	le_device_nvm_t entry;
24013e71c7bSMatthias Ringwald 	memset(&entry, 0, sizeof(le_device_nvm_t));
24113e71c7bSMatthias Ringwald 
24213e71c7bSMatthias Ringwald     entry.magic     = LE_DEVICE_MAGIC;
24313e71c7bSMatthias Ringwald 	entry.seq_nr    = seq_nr;
24413e71c7bSMatthias Ringwald     entry.addr_type = addr_type;
24513e71c7bSMatthias Ringwald     memcpy(entry.addr, addr, 6);
24613e71c7bSMatthias Ringwald     memcpy(entry.irk, irk, 16);
24713e71c7bSMatthias Ringwald 
24813e71c7bSMatthias Ringwald     le_device_db_entry_write(absolute_index, &entry);
24913e71c7bSMatthias Ringwald 
25013e71c7bSMatthias Ringwald     return absolute_index;
25113e71c7bSMatthias Ringwald }
25213e71c7bSMatthias Ringwald 
le_device_db_encryption_set(int device_index,uint16_t ediv,uint8_t rand[8],sm_key_t ltk,int key_size,int authenticated,int authorized,int secure_connection)2533dc3a67dSMatthias Ringwald void le_device_db_encryption_set(int device_index, uint16_t ediv, uint8_t rand[8], sm_key_t ltk, int key_size, int authenticated, int authorized, int secure_connection){
25413e71c7bSMatthias Ringwald 
25513e71c7bSMatthias Ringwald 	int absolute_index = le_device_db_get_absolute_index_for_device_index(device_index);
25613e71c7bSMatthias Ringwald     le_device_nvm_t entry;
25713e71c7bSMatthias Ringwald 	le_device_db_entry_read(absolute_index, &entry);
25813e71c7bSMatthias Ringwald 
2593dc3a67dSMatthias Ringwald     log_info("LE Device DB set encryption for %u, ediv x%04x, key size %u, authenticated %u, authorized %u, secure connection %u",
2603dc3a67dSMatthias Ringwald         device_index, ediv, key_size, authenticated, authorized, secure_connection);
26113e71c7bSMatthias Ringwald 
26213e71c7bSMatthias Ringwald     entry.ediv = ediv;
26313e71c7bSMatthias Ringwald     if (rand) memcpy(entry.rand, rand, 8);
26413e71c7bSMatthias Ringwald     if (ltk) memcpy(entry.ltk, ltk, 16);
26513e71c7bSMatthias Ringwald     entry.key_size = key_size;
26613e71c7bSMatthias Ringwald     entry.authenticated = authenticated;
26713e71c7bSMatthias Ringwald     entry.authorized = authorized;
2683dc3a67dSMatthias Ringwald     entry.secure_connection = secure_connection;
26913e71c7bSMatthias Ringwald 
27013e71c7bSMatthias Ringwald     le_device_db_entry_write(absolute_index, &entry);
27113e71c7bSMatthias Ringwald }
27213e71c7bSMatthias Ringwald 
le_device_db_encryption_get(int device_index,uint16_t * ediv,uint8_t rand[8],sm_key_t ltk,int * key_size,int * authenticated,int * authorized,int * secure_connection)2733dc3a67dSMatthias Ringwald void le_device_db_encryption_get(int device_index, uint16_t * ediv, uint8_t rand[8], sm_key_t ltk, int * key_size, int * authenticated, int * authorized, int * secure_connection){
27413e71c7bSMatthias Ringwald 
27513e71c7bSMatthias Ringwald 	int absolute_index = le_device_db_get_absolute_index_for_device_index(device_index);
27613e71c7bSMatthias Ringwald     le_device_nvm_t entry;
27713e71c7bSMatthias Ringwald 	le_device_db_entry_read(absolute_index, &entry);
27813e71c7bSMatthias Ringwald 
2793dc3a67dSMatthias Ringwald     log_info("LE Device DB encryption for %u, ediv x%04x, keysize %u, authenticated %u, authorized %u, secure connection %u",
2803dc3a67dSMatthias Ringwald         device_index, entry.ediv, entry.key_size, entry.authenticated, entry.authorized, entry.secure_connection);
28113e71c7bSMatthias Ringwald 
28213e71c7bSMatthias Ringwald     if (ediv) *ediv = entry.ediv;
28313e71c7bSMatthias Ringwald     if (rand) memcpy(rand, entry.rand, 8);
28413e71c7bSMatthias Ringwald     if (ltk)  memcpy(ltk, entry.ltk, 16);
28513e71c7bSMatthias Ringwald     if (key_size) *key_size = entry.key_size;
28613e71c7bSMatthias Ringwald     if (authenticated) *authenticated = entry.authenticated;
28713e71c7bSMatthias Ringwald     if (authorized) *authorized = entry.authorized;
2883dc3a67dSMatthias Ringwald     if (secure_connection) *secure_connection = entry.secure_connection;
28913e71c7bSMatthias Ringwald }
29013e71c7bSMatthias Ringwald 
le_device_db_dump(void)29113e71c7bSMatthias Ringwald void le_device_db_dump(void){
29213e71c7bSMatthias Ringwald     log_info("dump, devices: %d", le_device_db_count());
29313e71c7bSMatthias Ringwald     int i;
29413e71c7bSMatthias Ringwald     for (i=0;i<NVM_NUM_LE_DEVICES;i++){
29513e71c7bSMatthias Ringwald 	    le_device_nvm_t entry;
29613e71c7bSMatthias Ringwald 		int valid = le_device_db_entry_read(i, &entry);
29713e71c7bSMatthias Ringwald 
29813e71c7bSMatthias Ringwald         if (!valid) continue;
29913e71c7bSMatthias Ringwald 
30013e71c7bSMatthias Ringwald         log_info("#%u: %u %s", i, entry.addr_type, bd_addr_to_str(entry.addr));
30113e71c7bSMatthias Ringwald         log_info_key("ltk", entry.ltk);
30213e71c7bSMatthias Ringwald         log_info_key("irk", entry.irk);
30313e71c7bSMatthias Ringwald     }
30413e71c7bSMatthias Ringwald }
305ad1a357bSMatthias Ringwald 
le_device_db_wiced_dct_get_storage_size(void)306ad1a357bSMatthias Ringwald int le_device_db_wiced_dct_get_storage_size(void){
307ad1a357bSMatthias Ringwald 	return NVM_NUM_LE_DEVICES * sizeof(le_device_nvm_t);
308ad1a357bSMatthias Ringwald }
309