// ArduinoNvs.cpp // Copyright (c) 2018 Sinai RnD // Copyright (c) 2016-2017 TridentTD // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be included in all // copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. #include "ArduinoNvs.h" ArduinoNvs::ArduinoNvs() { } bool ArduinoNvs::begin(String namespaceNvs) { esp_err_t err = nvs_flash_init(); if (err != ESP_OK) { DEBUG_PRINTLN("W: NVS. Cannot init flash mem"); if (err != ESP_ERR_NVS_NO_FREE_PAGES) return false; // erase and reinit DEBUG_PRINTLN("NVS. Try reinit the partition"); const esp_partition_t *nvs_partition = esp_partition_find_first(ESP_PARTITION_TYPE_DATA, ESP_PARTITION_SUBTYPE_DATA_NVS, NULL); if (nvs_partition == NULL) return false; err = esp_partition_erase_range(nvs_partition, 0, nvs_partition->size); esp_err_t err = nvs_flash_init(); if (err) return false; DEBUG_PRINTLN("NVS. Partition re-formatted"); } err = nvs_open(namespaceNvs.c_str(), NVS_READWRITE, &_nvs_handle); if (err != ESP_OK) return false; return true; } void ArduinoNvs::close() { nvs_close(_nvs_handle); } bool ArduinoNvs::eraseAll(bool forceCommit) { esp_err_t err = nvs_erase_all(_nvs_handle); if (err != ESP_OK) return false; return forceCommit ? commit() : true; } bool ArduinoNvs::erase(String key, bool forceCommit) { esp_err_t err = nvs_erase_key(_nvs_handle, key.c_str()); if (err != ESP_OK) return false; return forceCommit ? commit() : true; } bool ArduinoNvs::commit() { esp_err_t err = nvs_commit(_nvs_handle); if (err != ESP_OK) return false; return true; } bool ArduinoNvs::setInt(String key, uint8_t value, bool forceCommit) { esp_err_t err = nvs_set_u8(_nvs_handle, (char *)key.c_str(), value); if (err != ESP_OK) return false; return forceCommit ? commit() : true; } bool ArduinoNvs::setInt(String key, int16_t value, bool forceCommit) { esp_err_t err = nvs_set_i16(_nvs_handle, (char *)key.c_str(), value); if (err != ESP_OK) return false; return forceCommit ? commit() : true; } bool ArduinoNvs::setInt(String key, uint16_t value, bool forceCommit) { esp_err_t err = nvs_set_u16(_nvs_handle, (char *)key.c_str(), value); if (err != ESP_OK) return false; return forceCommit ? commit() : true; } bool ArduinoNvs::setInt(String key, int32_t value, bool forceCommit) { esp_err_t err = nvs_set_i32(_nvs_handle, (char *)key.c_str(), value); if (err != ESP_OK) return false; return forceCommit ? commit() : true; } bool ArduinoNvs::setInt(String key, uint32_t value, bool forceCommit) { esp_err_t err = nvs_set_u32(_nvs_handle, (char *)key.c_str(), value); if (err != ESP_OK) return false; return forceCommit ? commit() : true; } bool ArduinoNvs::setInt(String key, int64_t value, bool forceCommit) { esp_err_t err = nvs_set_i64(_nvs_handle, (char *)key.c_str(), value); if (err != ESP_OK) return false; return forceCommit ? commit() : true; } bool ArduinoNvs::setInt(String key, uint64_t value, bool forceCommit) { esp_err_t err = nvs_set_u64(_nvs_handle, (char *)key.c_str(), value); if (err != ESP_OK) return false; return forceCommit ? commit() : true; } bool ArduinoNvs::setString(String key, String value, bool forceCommit) { esp_err_t err = nvs_set_str(_nvs_handle, (char *)key.c_str(), value.c_str()); if (err != ESP_OK) return false; return forceCommit ? commit() : true; } bool ArduinoNvs::setBlob(String key, uint8_t *blob, size_t length, bool forceCommit) { DEBUG_PRINTF("ArduinoNvs::setObjct(): set obj addr = [0x%X], length = [%d]\n", (int32_t)blob, length); if (length == 0) return false; esp_err_t err = nvs_set_blob(_nvs_handle, (char *)key.c_str(), blob, length); if (err) { DEBUG_PRINTF("ArduinoNvs::setObjct(): err = [0x%X]\n", err); return false; } return forceCommit ? commit() : true; } bool ArduinoNvs::setBlob(String key, std::vector<uint8_t> &blob, bool forceCommit) { return setBlob(key, &blob[0], blob.size(), forceCommit); } int64_t ArduinoNvs::getInt(String key, int64_t default_value) { uint8_t v_u8; int16_t v_i16; uint16_t v_u16; int32_t v_i32; uint32_t v_u32; int64_t v_i64; uint64_t v_u64; esp_err_t err; err = nvs_get_u8(_nvs_handle, (char *)key.c_str(), &v_u8); if (err == ESP_OK) return (int64_t)v_u8; err = nvs_get_i16(_nvs_handle, (char *)key.c_str(), &v_i16); if (err == ESP_OK) return (int64_t)v_i16; err = nvs_get_u16(_nvs_handle, (char *)key.c_str(), &v_u16); if (err == ESP_OK) return (int64_t)v_u16; err = nvs_get_i32(_nvs_handle, (char *)key.c_str(), &v_i32); if (err == ESP_OK) return (int64_t)v_i32; err = nvs_get_u32(_nvs_handle, (char *)key.c_str(), &v_u32); if (err == ESP_OK) return (int64_t)v_u32; err = nvs_get_i64(_nvs_handle, (char *)key.c_str(), &v_i64); if (err == ESP_OK) return (int64_t)v_i64; err = nvs_get_u64(_nvs_handle, (char *)key.c_str(), &v_u64); if (err == ESP_OK) return (int64_t)v_u64; return default_value; } bool ArduinoNvs::getString(String key, String &res) { size_t required_size; esp_err_t err; err = nvs_get_str(_nvs_handle, key.c_str(), NULL, &required_size); if (err) return false; char value[required_size]; err = nvs_get_str(_nvs_handle, key.c_str(), value, &required_size); if (err) return false; res = value; return true; } String ArduinoNvs::getString(String key) { String res; bool ok = getString(key, res); if (!ok) return String(); return res; } size_t ArduinoNvs::getBlobSize(String key) { size_t required_size; esp_err_t err = nvs_get_blob(_nvs_handle, key.c_str(), NULL, &required_size); if (err) { if (err != ESP_ERR_NVS_NOT_FOUND) // key_not_found is not an error, just return size 0 DEBUG_PRINTF("ArduinoNvs::getBlobSize(): err = [0x%X]\n", err); return 0; } return required_size; } bool ArduinoNvs::getBlob(String key, uint8_t *blob, size_t length) { if (length == 0) return false; size_t required_size = getBlobSize(key); if (required_size == 0) return false; if (length < required_size) return false; esp_err_t err = nvs_get_blob(_nvs_handle, key.c_str(), blob, &required_size); if (err) { DEBUG_PRINTF("ArduinoNvs::getBlob(): get object err = [0x%X]\n", err); return false; } return true; } bool ArduinoNvs::getBlob(String key, std::vector<uint8_t> &blob) { size_t required_size = getBlobSize(key); if (required_size == 0) return false; blob.resize(required_size); esp_err_t err = nvs_get_blob(_nvs_handle, key.c_str(), &blob[0], &required_size); if (err) { DEBUG_PRINTF("ArduinoNvs::getBlob(): get object err = [0x%X]\n", err); return false; } return true; } std::vector<uint8_t> ArduinoNvs::getBlob(String key) { std::vector<uint8_t> res; bool ok = getBlob(key, res); if (!ok) res.clear(); return res; } bool ArduinoNvs::setFloat(String key, float value, bool forceCommit) { return setBlob(key, (uint8_t *)&value, sizeof(float), forceCommit); } float ArduinoNvs::getFloat(String key, float default_value) { std::vector<uint8_t> res(sizeof(float)); if (!getBlob(key, res)) return default_value; return *(float *)(&res[0]); } ArduinoNvs NVS;