static unsigned int try_to_flush_duplicates(const char *new_key, unsigned int buf_len) { unsigned int key_size, new_record_size, ret = 0, can_rollback = 0; struct record record, previous_record; char sector_buff[STORAGE_SIZE]; struct iter_state is; memcpy(sector_buff, STORAGE_ADDRESS, STORAGE_SIZE); if(check_for_duplicates(sector_buff) || key_exists(sector_buff, new_key, §or_buff[STORAGE_SIZE], 0, NULL) || check_for_empty_records(sector_buff)) { fs_erase(); record_iter_init(&is, sector_buff, STORAGE_SIZE); while(record_iter_next(&is, &record, NULL)) { if(is_empty(&record)) continue; if(!key_exists((char *)STORAGE_ADDRESS, record.key, STORAGE_ADDRESS + STORAGE_SIZE, 1, NULL)) { struct record rec; if(!key_exists(sector_buff, record.key, §or_buff[STORAGE_SIZE], 0, &rec)) continue; if(strcmp(new_key, record.key) == 0) { // If we are about to write this key we don't keep the old value. previous_record = rec; // This holds the old record in case we need it back (for instance if new record is too long) can_rollback = 1; } else fs_write(record.key, rec.value, rec.value_len); } } ret = 1; } key_size = strlen(new_key) + 1; new_record_size = key_size + buf_len + sizeof(new_record_size); if(can_rollback && new_record_size > get_free_space()) { fs_write(new_key, previous_record.value, previous_record.value_len); } return ret; }
/** @brief Internal function to initialize DFU BLE transport */ fs_ret_t nrf_dfu_flash_erase(uint32_t const * p_dest, uint32_t num_pages, dfu_flash_callback_t callback) { fs_ret_t ret_val = FS_SUCCESS; NRF_LOG_INFO("Erasing: 0x%08x, num: %d\r\n", (uint32_t)p_dest, num_pages); #ifdef BLE_STACK_SUPPORT_REQD if ((m_flags & FLASH_FLAG_SD_ENABLED) != 0) { // Check if there is a pending error if ((m_flags & FLASH_FLAG_FAILURE_SINCE_LAST) != 0) { NRF_LOG_ERROR("Erase: Failure since last\r\n"); return FS_ERR_FAILURE_SINCE_LAST; } m_flags |= FLASH_FLAG_OPER; ret_val = fs_erase(&fs_dfu_config, p_dest, num_pages, (void*)callback); if (ret_val != FS_SUCCESS) { NRF_LOG_ERROR("Erase failed: %d\r\n", ret_val); m_flags &= ~FLASH_FLAG_OPER; return ret_val; } // Set the flag to indicate ongoing operation m_flags |= FLASH_FLAG_OPER; } else #endif { #ifndef NRF51 // Softdevice is not present or activated. Run the NVMC instead if (((uint32_t)p_dest & (CODE_PAGE_SIZE-1)) != 0) { NRF_LOG_ERROR("Invalid address\r\n"); return FS_ERR_UNALIGNED_ADDR; } #endif uint16_t first_page = ((uint32_t)p_dest / CODE_PAGE_SIZE); do { nrf_nvmc_page_erase((uint32_t)p_dest); p_dest += CODE_PAGE_SIZE/sizeof(uint32_t); } while(--num_pages > 0); if (callback) { #if (__LINT__ != 1) fs_evt_t evt = { .id = FS_EVT_ERASE, .p_context = (void*)callback, .erase = { .first_page = first_page, .last_page = ((uint32_t)p_dest / CODE_PAGE_SIZE) } }; callback(&evt, FS_SUCCESS); #else (void)first_page; #endif } } return ret_val; }