/* * Copyright (C) 2016 BlueKitchen GmbH * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the copyright holders nor the names of * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * 4. Any redistribution, use, or modification is done solely for * personal benefit and not for any commercial purpose or for * monetary gain. * * THIS SOFTWARE IS PROVIDED BY BLUEKITCHEN GMBH AND CONTRIBUTORS * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL MATTHIAS * RINGWALD OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * Please inquire about commercial licensing options at * contact@bluekitchen-gmbh.com * */ #define __BTSTACK_FILE__ "le_device_db_wiced_dct.c" /* * le_device_db_wiced_dct.c * * Persistent LE Device DB implemenetation for WICED using DCT mechanism */ #include "stdint.h" #include "string.h" #include "inttypes.h" #include "wiced.h" #include "ble/le_device_db.h" #include "btstack_link_key_db_wiced_dct.h" // for size of #include "btstack_debug.h" #include "btstack_util.h" // Link Key Magic #define LE_DEVICE_MAGIC ((uint32_t) 'L' << 24 | 'E' << 16 | 'D' << 8 | 'B') #define INVALID_ENTRY_ADDR_TYPE 0xff typedef struct le_device_nvm { uint32_t magic; uint32_t seq_nr; // used for "last recently stored" eviction strategy // Identification sm_key_t irk; bd_addr_t addr; uint8_t addr_type; // pairing information uint8_t key_size; uint8_t authenticated; uint8_t authorized; sm_key_t ltk; // Stored pairing information allows to re-establish an enncrypted connection // with a peripheral that doesn't have any persistent memory uint16_t ediv; uint8_t rand[8]; } le_device_nvm_t; static uint32_t start_of_le_device_db; // calculate address static int le_device_db_address_for_absolute_index(int abolute_index){ return start_of_le_device_db + abolute_index * sizeof(le_device_nvm_t); } static int le_device_db_entry_valid(int absolute_index){ // read lock le_device_nvm_t * entry; 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)); int valid = entry->magic == LE_DEVICE_MAGIC; // read unlock wiced_dct_read_unlock((void*) entry, WICED_FALSE); return valid; } // @return valid static int le_device_db_entry_read(int absolute_index, le_device_nvm_t * out_entry){ // read lock le_device_nvm_t * entry; 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)); if (entry->magic == LE_DEVICE_MAGIC){ memcpy(out_entry, entry, sizeof(le_device_nvm_t)); } else { memset(out_entry, 0, sizeof(le_device_nvm_t)); } // read unlock wiced_dct_read_unlock((void*) entry, WICED_FALSE); return out_entry->magic == LE_DEVICE_MAGIC; } static void le_device_db_entry_write(int absolute_index, le_device_nvm_t * entry){ // write block wiced_dct_write((void*)entry, DCT_APP_SECTION, le_device_db_address_for_absolute_index(absolute_index), sizeof(le_device_nvm_t)); } static uint32_t le_device_db_highest_seq_nr(void){ le_device_nvm_t entry; int i; uint32_t seq_nr = 0; for (i=0;i