From 0665676f47e53a5f27cf604a4cb168461da34421 Mon Sep 17 00:00:00 2001 From: Shubham Patil Date: Thu, 31 Mar 2022 21:28:50 +0530 Subject: [PATCH 1/2] [ESP32] Use nvs iterator to check if key exists --- src/platform/ESP32/ESP32Config.cpp | 84 ++++-------------------------- 1 file changed, 10 insertions(+), 74 deletions(-) diff --git a/src/platform/ESP32/ESP32Config.cpp b/src/platform/ESP32/ESP32Config.cpp index 2d6818450e5937..3762725e903a82 100644 --- a/src/platform/ESP32/ESP32Config.cpp +++ b/src/platform/ESP32/ESP32Config.cpp @@ -318,82 +318,18 @@ CHIP_ERROR ESP32Config::ClearConfigValue(Key key) bool ESP32Config::ConfigValueExists(Key key) { - ScopedNvsHandle handle; - - if (handle.Open(key.Namespace, NVS_READONLY) != CHIP_NO_ERROR) - { - return false; - } - - // This code is a rather unfortunate consequence of the limitations - // in the ESP NVS API. As defined, there is no API for determining - // whether a particular key exists. Furthermore, calling one of the - // nvs_get_* APIs will result in a ESP_ERR_NVS_NOT_FOUND in the case - // where the key exists, but the requested data type does not match. - // (This is true despite the existence of the ESP_ERR_NVS_TYPE_MISMATCH - // error, which would seem to be the obvious correct response). - // - // Thus the solution is to exhaustively check for the key using - // each possible value type. - esp_err_t err; - { - uint8_t v; - err = nvs_get_u8(handle, key.Name, &v); - } - if (err == ESP_ERR_NVS_NOT_FOUND) - { - int8_t v; - err = nvs_get_i8(handle, key.Name, &v); - } - if (err == ESP_ERR_NVS_NOT_FOUND) - { - uint16_t v; - err = nvs_get_u16(handle, key.Name, &v); - } - if (err == ESP_ERR_NVS_NOT_FOUND) + nvs_iterator_t iterator = nvs_entry_find(NVS_DEFAULT_PART_NAME, key.Namespace, NVS_TYPE_ANY); + for (; iterator; iterator = nvs_entry_next(iterator)) { - int16_t v; - err = nvs_get_i16(handle, key.Name, &v); - } - if (err == ESP_ERR_NVS_NOT_FOUND) - { - uint32_t v; - err = nvs_get_u32(handle, key.Name, &v); - } - if (err == ESP_ERR_NVS_NOT_FOUND) - { - int32_t v; - err = nvs_get_i32(handle, key.Name, &v); - } - if (err == ESP_ERR_NVS_NOT_FOUND) - { - uint64_t v; - err = nvs_get_u64(handle, key.Name, &v); - } - if (err == ESP_ERR_NVS_NOT_FOUND) - { - int64_t v; - err = nvs_get_i64(handle, key.Name, &v); - } - if (err == ESP_ERR_NVS_NOT_FOUND) - { - size_t sz; - err = nvs_get_str(handle, key.Name, NULL, &sz); - } - if (err == ESP_ERR_NVS_NOT_FOUND) - { - size_t sz; - err = nvs_get_blob(handle, key.Name, NULL, &sz); - } - - // In the case of blob and string, ESP_ERR_NVS_INVALID_LENGTH means - // the key exists. - if (err == ESP_ERR_NVS_INVALID_LENGTH) - { - err = ESP_OK; + nvs_entry_info_t info; + nvs_entry_info(iterator, &info); + if (strcmp(info.key, key.Name) == 0) + { + nvs_release_iterator(iterator); + return true; + } } - - return err == ESP_OK; + return false; } CHIP_ERROR ESP32Config::EnsureNamespace(const char * ns) From 6a8d3f7c7f1fec56b2e00b2adf7c8ef3dd9f4f65 Mon Sep 17 00:00:00 2001 From: Shubham Patil Date: Fri, 1 Apr 2022 08:57:51 +0530 Subject: [PATCH 2/2] Comment explaining why no need to release iterator in NULL case --- src/platform/ESP32/ESP32Config.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/platform/ESP32/ESP32Config.cpp b/src/platform/ESP32/ESP32Config.cpp index 3762725e903a82..bed53cd74e9eae 100644 --- a/src/platform/ESP32/ESP32Config.cpp +++ b/src/platform/ESP32/ESP32Config.cpp @@ -329,6 +329,7 @@ bool ESP32Config::ConfigValueExists(Key key) return true; } } + // if nvs_entry_find() or nvs_entry_next() returns NULL, then no need to release the iterator. return false; }