1
6
7
8
9
10
11
12
13
14
15
16
17
18
19
27
28
29
30
31
34
35
36
37
38
39
40
43
44
45
46
47
48
49
52
53
54
55
56
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
92
93
94
101
102
103
104
105
106
107
110
111
112
113
114
117
118
119
120
125
126
129
130
131
132
133
134
138
139
140
141
142
143
144
145
146
147
148
151
152
153
159
160
161
162
163
164
172
173
174
175
176
177
178
179
180
181
182
183
184
187
188
191
192
193
196
197
200
201
202
203
206
207
208
211
212
213
214
215
216
217
218
228
229
233
234
245
246
/* ... */
#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
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;
const uint32_t sec_size = esp_partition_get_main_flash_sector_size();
Storage* mStorage;
mStorage = lookup_storage_from_name(partition_label);
if (mStorage) {
return ESP_OK;
}{...}
NVS_ASSERT_OR_RETURN(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 / sec_size);
if (result != ESP_OK) {
goto error;
}{...}
nvs_partition_list.push_back(p);
return ESP_OK;
error:
delete p;
return result;
}{ ... }
/* ... */#endif
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 {
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();
const uint32_t sec_size = esp_partition_get_main_flash_sector_size();
result = init_custom(p, 0, size / sec_size);
if (result != ESP_OK) {
delete p;
return result;
}{...}
nvs_partition_list.push_back(p);
return ESP_OK;
}{ ... }
/* ... */#endif
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;
}{...}
for (auto it = nvs_handles.begin(); it != nvs_handles.end(); ++it) {
if (it->mStoragePtr == storage) {
it->valid = false;
nvs_handles.erase(it);
}{...}
}{...}
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;
}{...}
if (open_mode == NVS_READWRITE && const_cast<Partition*>(sHandle->getPart())->get_readonly()) {
return ESP_ERR_NOT_ALLOWED;
}{...}
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;
}{ ... }
}{...}