| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239 |
- /*
- * SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD
- *
- * SPDX-License-Identifier: Apache-2.0
- */
- #include "esp_partition.h"
- #include "nvs_partition_manager.hpp"
- #include "nvs_partition_lookup.hpp"
- #include "nvs_internal.h"
- #ifndef LINUX_TARGET
- #include "nvs_encrypted_partition.hpp"
- #endif // ! LINUX_TARGET
- namespace nvs {
- NVSPartitionManager* NVSPartitionManager::instance = nullptr;
- NVSPartitionManager* NVSPartitionManager::get_instance()
- {
- if (!instance) {
- instance = new (std::nothrow) NVSPartitionManager();
- }
- return instance;
- }
- #ifdef ESP_PLATFORM
- esp_err_t NVSPartitionManager::init_partition(const char *partition_label)
- {
- if (strlen(partition_label) > NVS_PART_NAME_MAX_SIZE) {
- return ESP_ERR_INVALID_ARG;
- }
- uint32_t size;
- Storage* mStorage;
- mStorage = lookup_storage_from_name(partition_label);
- if (mStorage) {
- return ESP_OK;
- }
- NVS_ASSERT_OR_RETURN(SPI_FLASH_SEC_SIZE != 0, ESP_FAIL);
- NVSPartition *p = nullptr;
- esp_err_t result = partition_lookup::lookup_nvs_partition(partition_label, &p);
- if (result != ESP_OK) {
- goto error;
- }
- size = p->get_size();
- result = init_custom(p, 0, size / SPI_FLASH_SEC_SIZE);
- if (result != ESP_OK) {
- goto error;
- }
- nvs_partition_list.push_back(p);
- return ESP_OK;
- error:
- delete p;
- return result;
- }
- #endif // ESP_PLATFORM
- esp_err_t NVSPartitionManager::init_custom(Partition *partition, uint32_t baseSector, uint32_t sectorCount)
- {
- Storage* new_storage = nullptr;
- Storage* storage = lookup_storage_from_name(partition->get_partition_name());
- if (storage == nullptr) {
- new_storage = new (std::nothrow) Storage(partition);
- if (new_storage == nullptr) {
- return ESP_ERR_NO_MEM;
- }
- storage = new_storage;
- } else {
- // if storage was initialized already, we don't need partition and hence delete it
- for (auto it = nvs_partition_list.begin(); it != nvs_partition_list.end(); ++it) {
- if (partition == it) {
- nvs_partition_list.erase(it);
- delete partition;
- break;
- }
- }
- }
- esp_err_t err = storage->init(baseSector, sectorCount);
- if (new_storage != nullptr) {
- if (err == ESP_OK) {
- nvs_storage_list.push_back(new_storage);
- } else {
- delete new_storage;
- }
- }
- return err;
- }
- #ifdef ESP_PLATFORM
- esp_err_t NVSPartitionManager::secure_init_partition(const char *part_name, nvs_sec_cfg_t* cfg)
- {
- if (strlen(part_name) > NVS_PART_NAME_MAX_SIZE) {
- return ESP_ERR_INVALID_ARG;
- }
- Storage* mStorage;
- mStorage = lookup_storage_from_name(part_name);
- if (mStorage != nullptr) {
- return ESP_OK;
- }
- NVSPartition *p;
- esp_err_t result;
- if (cfg != nullptr) {
- result = partition_lookup::lookup_nvs_encrypted_partition(part_name, cfg, &p);
- } else {
- result = partition_lookup::lookup_nvs_partition(part_name, &p);
- }
- if (result != ESP_OK) {
- return result;
- }
- uint32_t size = p->get_size();
- result = init_custom(p, 0, size / SPI_FLASH_SEC_SIZE);
- if (result != ESP_OK) {
- delete p;
- return result;
- }
- nvs_partition_list.push_back(p);
- return ESP_OK;
- }
- #endif // ESP_PLATFORM
- esp_err_t NVSPartitionManager::deinit_partition(const char *partition_label)
- {
- Storage* storage = lookup_storage_from_name(partition_label);
- if (!storage) {
- return ESP_ERR_NVS_NOT_INITIALIZED;
- }
- /* Clean up handles related to the storage being deinitialized */
- for (auto it = nvs_handles.begin(); it != nvs_handles.end(); ++it) {
- if (it->mStoragePtr == storage) {
- it->valid = false;
- nvs_handles.erase(it);
- }
- }
- /* Finally delete the storage and its partition */
- nvs_storage_list.erase(storage);
- delete storage;
- for (auto it = nvs_partition_list.begin(); it != nvs_partition_list.end(); ++it) {
- if (strcmp(it->get_partition_name(), partition_label) == 0) {
- NVSPartition *p = it;
- nvs_partition_list.erase(it);
- delete p;
- break;
- }
- }
- return ESP_OK;
- }
- esp_err_t NVSPartitionManager::open_handle(const char *part_name,
- const char *ns_name,
- nvs_open_mode_t open_mode,
- NVSHandleSimple** handle)
- {
- uint8_t nsIndex;
- Storage* sHandle;
- if (handle == nullptr) {
- return ESP_ERR_INVALID_ARG;
- }
- if (nvs_storage_list.empty()) {
- return ESP_ERR_NVS_NOT_INITIALIZED;
- }
- sHandle = lookup_storage_from_name(part_name);
- if (sHandle == nullptr) {
- return ESP_ERR_NVS_PART_NOT_FOUND;
- }
- esp_err_t err = sHandle->createOrOpenNamespace(ns_name, open_mode == NVS_READWRITE, nsIndex);
- if (err != ESP_OK) {
- return err;
- }
- NVSHandleSimple* new_handle = new (std::nothrow) NVSHandleSimple(open_mode==NVS_READONLY, nsIndex, sHandle);
- if (new_handle == nullptr) {
- return ESP_ERR_NO_MEM;
- }
- nvs_handles.push_back(new_handle);
- *handle = new_handle;
- return ESP_OK;
- }
- esp_err_t NVSPartitionManager::close_handle(NVSHandleSimple* handle) {
- for (auto it = nvs_handles.begin(); it != nvs_handles.end(); ++it) {
- if (it == intrusive_list<NVSHandleSimple>::iterator(handle)) {
- nvs_handles.erase(it);
- return ESP_OK;
- }
- }
- return ESP_ERR_NVS_INVALID_HANDLE;
- }
- size_t NVSPartitionManager::open_handles_size()
- {
- return nvs_handles.size();
- }
- Storage* NVSPartitionManager::lookup_storage_from_name(const char* name)
- {
- auto it = find_if(begin(nvs_storage_list), end(nvs_storage_list), [=](Storage& e) -> bool {
- return (strcmp(e.getPartName(), name) == 0);
- });
- if (it == end(nvs_storage_list)) {
- return nullptr;
- }
- return it;
- }
- } // nvs
|