217 lines
6.7 KiB
C
217 lines
6.7 KiB
C
/*
|
|
* cmd_nvs.c
|
|
*
|
|
* Copyright (c) 2025 Umber Networks & Robert McMahon
|
|
* All rights reserved.
|
|
*
|
|
* Redistribution and use in source and binary forms, with or without
|
|
* modification, are permitted provided that the following conditions are met:
|
|
*
|
|
* 1. Redistributions of source code must retain the above copyright notice,
|
|
* this list of conditions and the following disclaimer.
|
|
*
|
|
* 2. Redistributions in binary form must reproduce the above copyright
|
|
* notice, this list of conditions and the following disclaimer in the
|
|
* documentation and/or other materials provided with the distribution.
|
|
*
|
|
* 3. Neither the name of the copyright holder nor the names of its
|
|
* contributors may be used to endorse or promote products derived from
|
|
* this software without specific prior written permission.
|
|
*
|
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
|
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
|
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
|
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
|
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
|
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
|
* POSSIBILITY OF SUCH DAMAGE.
|
|
*/
|
|
/*
|
|
* cmd_nvs.c
|
|
*
|
|
* Copyright (c) 2025 Umber Networks & Robert McMahon
|
|
* All rights reserved.
|
|
*/
|
|
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
#include <inttypes.h>
|
|
#include "esp_log.h"
|
|
#include "esp_console.h"
|
|
#include "nvs_flash.h"
|
|
#include "nvs.h"
|
|
#include "argtable3/argtable3.h"
|
|
#include "app_console.h"
|
|
|
|
static void print_nvs_usage(void) {
|
|
printf("Usage: nvs <subcommand>\n");
|
|
printf("Subcommands:\n");
|
|
printf(" dump Dump 'storage' namespace keys and values\n");
|
|
printf(" clear Erase 'storage' namespace (Factory Reset)\n");
|
|
}
|
|
|
|
static void print_value(nvs_handle_t h, const char *key, nvs_type_t type) {
|
|
esp_err_t err;
|
|
|
|
switch (type) {
|
|
case NVS_TYPE_I8: {
|
|
int8_t v = 0;
|
|
err = nvs_get_i8(h, key, &v);
|
|
if (err == ESP_OK) printf("Value: %d (I8)", v);
|
|
break;
|
|
}
|
|
case NVS_TYPE_U8: {
|
|
uint8_t v = 0;
|
|
err = nvs_get_u8(h, key, &v);
|
|
if (err == ESP_OK) printf("Value: %u (U8)", v);
|
|
break;
|
|
}
|
|
case NVS_TYPE_I16: {
|
|
int16_t v = 0;
|
|
err = nvs_get_i16(h, key, &v);
|
|
if (err == ESP_OK) printf("Value: %d (I16)", v);
|
|
break;
|
|
}
|
|
case NVS_TYPE_U16: {
|
|
uint16_t v = 0;
|
|
err = nvs_get_u16(h, key, &v);
|
|
if (err == ESP_OK) printf("Value: %u (U16)", v);
|
|
break;
|
|
}
|
|
case NVS_TYPE_I32: {
|
|
int32_t v = 0;
|
|
err = nvs_get_i32(h, key, &v);
|
|
if (err == ESP_OK) printf("Value: %" PRIi32 " (I32)", v);
|
|
break;
|
|
}
|
|
case NVS_TYPE_U32: {
|
|
uint32_t v = 0;
|
|
err = nvs_get_u32(h, key, &v);
|
|
if (err == ESP_OK) printf("Value: %" PRIu32 " (U32)", v);
|
|
break;
|
|
}
|
|
case NVS_TYPE_I64: {
|
|
int64_t v = 0;
|
|
err = nvs_get_i64(h, key, &v);
|
|
if (err == ESP_OK) printf("Value: %" PRIi64 " (I64)", v);
|
|
break;
|
|
}
|
|
case NVS_TYPE_U64: {
|
|
uint64_t v = 0;
|
|
err = nvs_get_u64(h, key, &v);
|
|
if (err == ESP_OK) printf("Value: %" PRIu64 " (U64)", v);
|
|
break;
|
|
}
|
|
case NVS_TYPE_STR: {
|
|
size_t len = 0;
|
|
if (nvs_get_str(h, key, NULL, &len) == ESP_OK) {
|
|
char *str = malloc(len);
|
|
if (nvs_get_str(h, key, str, &len) == ESP_OK) {
|
|
printf("Value: \"%s\" (STR)", str);
|
|
}
|
|
free(str);
|
|
}
|
|
break;
|
|
}
|
|
case NVS_TYPE_BLOB: {
|
|
size_t len = 0;
|
|
if (nvs_get_blob(h, key, NULL, &len) == ESP_OK) {
|
|
printf("Value: [BLOB %u bytes]", (unsigned int)len);
|
|
}
|
|
break;
|
|
}
|
|
default:
|
|
printf("Value: [Unknown Type 0x%02x]", type);
|
|
break;
|
|
}
|
|
}
|
|
|
|
static int do_nvs_dump(int argc, char **argv) {
|
|
nvs_iterator_t it = NULL;
|
|
nvs_handle_t h;
|
|
|
|
// 1. Open Handle (Needed to read values)
|
|
esp_err_t err = nvs_open("storage", NVS_READONLY, &h);
|
|
if (err != ESP_OK) {
|
|
printf("Error opening NVS handle: %s\n", esp_err_to_name(err));
|
|
return 1;
|
|
}
|
|
|
|
// 2. Start Iterator
|
|
esp_err_t res = nvs_entry_find("nvs", "storage", NVS_TYPE_ANY, &it);
|
|
if (res != ESP_OK) {
|
|
nvs_close(h);
|
|
if (res == ESP_ERR_NVS_NOT_FOUND) {
|
|
printf("No NVS entries found in 'storage'.\n");
|
|
} else {
|
|
printf("NVS Search Error: %s\n", esp_err_to_name(res));
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
printf("NVS Dump (Namespace: storage):\n");
|
|
printf("%-20s | %-12s | %s\n", "Key", "Type", "Value");
|
|
printf("------------------------------------------------------------\n");
|
|
|
|
while (res == ESP_OK) {
|
|
nvs_entry_info_t info;
|
|
nvs_entry_info(it, &info);
|
|
|
|
printf("%-20s | 0x%02x | ", info.key, info.type);
|
|
print_value(h, info.key, info.type);
|
|
printf("\n");
|
|
|
|
res = nvs_entry_next(&it);
|
|
}
|
|
|
|
nvs_release_iterator(it);
|
|
nvs_close(h);
|
|
return 0;
|
|
}
|
|
|
|
static int do_nvs_clear(int argc, char **argv) {
|
|
nvs_handle_t h;
|
|
esp_err_t err = nvs_open("storage", NVS_READWRITE, &h);
|
|
if (err != ESP_OK) {
|
|
printf("Error opening NVS: %s\n", esp_err_to_name(err));
|
|
return 1;
|
|
}
|
|
|
|
err = nvs_erase_all(h);
|
|
if (err == ESP_OK) {
|
|
nvs_commit(h);
|
|
printf("NVS 'storage' namespace erased.\n");
|
|
} else {
|
|
printf("Error erasing NVS: %s\n", esp_err_to_name(err));
|
|
}
|
|
nvs_close(h);
|
|
return (err == ESP_OK) ? 0 : 1;
|
|
}
|
|
|
|
static int cmd_nvs(int argc, char **argv) {
|
|
if (argc < 2) {
|
|
print_nvs_usage();
|
|
return 0;
|
|
}
|
|
|
|
if (strcmp(argv[1], "dump") == 0) return do_nvs_dump(argc - 1, &argv[1]);
|
|
if (strcmp(argv[1], "clear") == 0) return do_nvs_clear(argc - 1, &argv[1]);
|
|
|
|
print_nvs_usage();
|
|
return 1;
|
|
}
|
|
|
|
void register_nvs_cmd(void) {
|
|
const esp_console_cmd_t cmd = {
|
|
.command = "nvs",
|
|
.help = "Storage Tools: dump, clear",
|
|
.hint = "<subcommand>",
|
|
.func = &cmd_nvs,
|
|
};
|
|
ESP_ERROR_CHECK(esp_console_cmd_register(&cmd));
|
|
}
|