168 lines
4.6 KiB
C++
168 lines
4.6 KiB
C++
/**
|
|
* @file nvsIo.cpp
|
|
* @author Gustice
|
|
* @brief Read-Write access to specific NVS partition
|
|
*
|
|
* @copyright Copyright (c) 2024
|
|
*/
|
|
|
|
#include "nvsIo.hpp"
|
|
#include "esp_err.h"
|
|
#include "esp_log.h"
|
|
#include <cstring>
|
|
#include <memory>
|
|
|
|
static const char *TAG = "NVS";
|
|
|
|
static esp_err_t storeBlob(nvs_handle_t nvs, const char *key, const char *str_values) {
|
|
uint8_t value;
|
|
size_t str_len = strlen(str_values);
|
|
size_t blob_len = str_len / 2;
|
|
|
|
if (str_len % 2) {
|
|
ESP_LOGE(TAG, "Blob data must contain even number of characters");
|
|
return ESP_ERR_NVS_TYPE_MISMATCH;
|
|
}
|
|
|
|
char *blob = (char *)malloc(blob_len);
|
|
if (blob == NULL) {
|
|
return ESP_ERR_NO_MEM;
|
|
}
|
|
|
|
for (int i = 0, j = 0; i < str_len; i++) {
|
|
char ch = str_values[i];
|
|
if (ch >= '0' && ch <= '9') {
|
|
value = ch - '0';
|
|
} else if (ch >= 'A' && ch <= 'F') {
|
|
value = ch - 'A' + 10;
|
|
} else if (ch >= 'a' && ch <= 'f') {
|
|
value = ch - 'a' + 10;
|
|
} else {
|
|
ESP_LOGE(TAG, "Blob data contain invalid character");
|
|
free(blob);
|
|
return ESP_ERR_NVS_TYPE_MISMATCH;
|
|
}
|
|
|
|
if (i & 1) {
|
|
blob[j++] += value;
|
|
} else {
|
|
blob[j] = value << 4;
|
|
}
|
|
}
|
|
|
|
esp_err_t err = nvs_set_blob(nvs, key, blob, blob_len);
|
|
free(blob);
|
|
|
|
if (err == ESP_OK) {
|
|
err = nvs_commit(nvs);
|
|
}
|
|
|
|
return err;
|
|
}
|
|
|
|
template <>
|
|
esp_err_t NvsIo::setValueByStr<int8_t>(const char *key, const char *strValue) {
|
|
int32_t value = strtol(strValue, NULL, 0);
|
|
if (value < INT8_MIN || value > INT8_MAX || errno == ERANGE) {
|
|
throw CoreException(ErrMsg_TooLong);
|
|
}
|
|
return setInt8(key, (int8_t)value);
|
|
}
|
|
|
|
template <>
|
|
esp_err_t NvsIo::setValueByStr<uint8_t>(const char *key, const char *strValue) {
|
|
uint32_t value = strtoul(strValue, NULL, 0);
|
|
if (value > UINT8_MAX || errno == ERANGE) {
|
|
throw CoreException(ErrMsg_TooLong);
|
|
}
|
|
return setUint8(key, (uint8_t)value);
|
|
}
|
|
|
|
template <>
|
|
esp_err_t NvsIo::setValueByStr<int16_t>(const char *key, const char *strValue) {
|
|
int32_t value = strtol(strValue, NULL, 0);
|
|
if (value < INT16_MIN || value > INT16_MAX || errno == ERANGE) {
|
|
throw CoreException(ErrMsg_TooLong);
|
|
}
|
|
return setInt16(key, (int16_t)value);
|
|
}
|
|
|
|
template <>
|
|
esp_err_t NvsIo::setValueByStr<uint16_t>(const char *key, const char *strValue) {
|
|
uint32_t value = strtoul(strValue, NULL, 0);
|
|
if (value > UINT16_MAX || errno == ERANGE) {
|
|
throw CoreException(ErrMsg_TooLong);
|
|
}
|
|
return setUint16(key, (uint16_t)value);
|
|
}
|
|
|
|
template <>
|
|
esp_err_t NvsIo::setValueByStr<int32_t>(const char *key, const char *strValue) {
|
|
int32_t value = strtol(strValue, NULL, 0);
|
|
if (errno == ERANGE) {
|
|
throw CoreException(ErrMsg_TooLong);
|
|
}
|
|
return setInt32(key, value);
|
|
}
|
|
|
|
template <>
|
|
esp_err_t NvsIo::setValueByStr<uint32_t>(const char *key, const char *strValue) {
|
|
uint32_t value = strtoul(strValue, NULL, 0);
|
|
if (errno == ERANGE) {
|
|
throw CoreException(ErrMsg_TooLong);
|
|
}
|
|
return setUint32(key, value);
|
|
}
|
|
|
|
template <>
|
|
esp_err_t NvsIo::setValueByStr<int64_t>(const char *key, const char *strValue) {
|
|
int64_t value = strtoll(strValue, NULL, 0);
|
|
if (errno == ERANGE) {
|
|
throw CoreException(ErrMsg_TooLong);
|
|
}
|
|
return setInt64(key, value);
|
|
}
|
|
|
|
template <>
|
|
esp_err_t NvsIo::setValueByStr<uint64_t>(const char *key, const char *strValue) {
|
|
uint64_t value = strtoull(strValue, NULL, 0);
|
|
if (errno == ERANGE) {
|
|
throw CoreException(ErrMsg_TooLong);
|
|
}
|
|
return setUint64(key, value);
|
|
}
|
|
|
|
esp_err_t NvsIo::setString(const char *key, const char *strValue) {
|
|
return nvs_set_str(_nvs, key, strValue);
|
|
}
|
|
esp_err_t NvsIo::setBlob(const char *key, const char *strValue) {
|
|
return storeBlob(_nvs, key, strValue);
|
|
}
|
|
|
|
std::optional<std::string> NvsIo::getString(const char *key) {
|
|
size_t len;
|
|
if (nvs_get_str(_nvs, key, NULL, &len) != ESP_OK) {
|
|
return {std::nullopt};
|
|
}
|
|
auto str = std::make_unique<char[]>(len);
|
|
if ((nvs_get_str(_nvs, key, str.get(), &len)) != ESP_OK) {
|
|
return {std::nullopt};
|
|
}
|
|
return {str.get()};
|
|
}
|
|
|
|
std::optional<std::vector<char>> NvsIo::getBlob(const char *key) {
|
|
size_t len;
|
|
if (nvs_get_blob(_nvs, key, NULL, &len) != ESP_OK) {
|
|
return {std::nullopt};
|
|
}
|
|
auto blob = std::make_unique<char[]>(len);
|
|
if (nvs_get_blob(_nvs, key, blob.get(), &len) != ESP_OK) {
|
|
return {std::nullopt};
|
|
}
|
|
std::vector<char> vec;
|
|
vec.reserve(len);
|
|
vec.insert(vec.end(), blob.get(), blob.get() + len);
|
|
return {vec};
|
|
}
|