Skip to content

Commit

Permalink
[ESP32] Use nvs iterator to check if key exists (#16885)
Browse files Browse the repository at this point in the history
* [ESP32] Use nvs iterator to check if key exists

* Comment explaining why no need to release iterator in NULL case
  • Loading branch information
shubhamdp authored and pull[bot] committed Nov 27, 2023
1 parent fe47f5e commit 2482385
Showing 1 changed file with 11 additions and 74 deletions.
85 changes: 11 additions & 74 deletions src/platform/ESP32/ESP32Config.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -318,82 +318,19 @@ 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;
// if nvs_entry_find() or nvs_entry_next() returns NULL, then no need to release the iterator.
return false;
}

CHIP_ERROR ESP32Config::EnsureNamespace(const char * ns)
Expand Down

0 comments on commit 2482385

Please sign in to comment.