configmanager: improved error handling

This commit is contained in:
Klaus K Wilting 2020-10-04 13:15:17 +02:00
parent c7fcf438e6
commit 502434abc4
3 changed files with 36 additions and 20 deletions

View File

@ -5,7 +5,7 @@
#include "globals.h" #include "globals.h"
void saveConfig(bool erase = false); void saveConfig(bool erase = false);
void loadConfig(void); bool loadConfig(void);
void eraseConfig(void); void eraseConfig(void);
#endif #endif

View File

@ -16,11 +16,12 @@ static const char TAG[] = __FILE__;
Preferences nvram; Preferences nvram;
static const size_t cfgLen = sizeof(cfg); static const char cfgMagicBytes[] = {0x21, 0x76, 0x87, 0x32, 0xf3};
static char buffer[cfgLen]; static const size_t cfgLen = sizeof(cfg), cfgLen2 = sizeof(cfgMagicBytes);
static char buffer[cfgLen + cfgLen2];
// populate runtime config with factory settings // populate runtime config with factory settings
void defaultConfig(configData_t *myconfig) { static void defaultConfig(configData_t *myconfig) {
char version[10]; char version[10];
snprintf(version, 10, "%-10s", PROGVERSION); snprintf(version, 10, "%-10s", PROGVERSION);
@ -56,45 +57,60 @@ void defaultConfig(configData_t *myconfig) {
// save current configuration from RAM to NVRAM // save current configuration from RAM to NVRAM
void saveConfig(bool erase) { void saveConfig(bool erase) {
ESP_LOGI(TAG, "Storing settings in NVRAM"); ESP_LOGI(TAG, "Storing settings to NVRAM...");
nvram.begin(DEVCONFIG, false); nvram.begin(DEVCONFIG, false);
if (erase) { if (erase) {
ESP_LOGI(TAG, "Resetting NVRAM to factory settings"); ESP_LOGI(TAG, "Resetting device to factory settings");
nvram.clear(); nvram.clear();
defaultConfig(&cfg); defaultConfig(&cfg);
} }
// Copy device runtime config cfg to byte array // Copy device runtime config cfg to byte array, padding it with magicBytes
memcpy(buffer, &cfg, cfgLen); memcpy(buffer, &cfg, cfgLen);
memcpy(buffer + cfgLen, &cfgMagicBytes, cfgLen2);
// save byte array to NVRAM, padding with cfg magicbyes
if (nvram.putBytes(DEVCONFIG, buffer, cfgLen + cfgLen2))
ESP_LOGI(TAG, "Device settings saved");
else
ESP_LOGE(TAG, "NVRAM Error, device settings not saved");
// save byte array to NVRAM
nvram.putBytes(DEVCONFIG, buffer, cfgLen);
nvram.end(); nvram.end();
} }
// load configuration from NVRAM into RAM and make it current // load configuration from NVRAM into RAM and make it current
void loadConfig() { bool loadConfig() {
ESP_LOGI(TAG, "Loading runtime settings from NVS"); ESP_LOGI(TAG, "Loading device runtime configuration from NVRAM...");
if (!nvram.begin(DEVCONFIG, true)) { if (!nvram.begin(DEVCONFIG, true)) {
ESP_LOGI(TAG, "Initializing NVRAM"); ESP_LOGW(TAG, "NVRAM initialized, device starts with factory settings");
eraseConfig(); eraseConfig();
return true;
} else { } else {
// simple check that runtime config data matches // simple check that runtime config data matches
if (nvram.getBytesLength(DEVCONFIG) != cfgLen) { if (nvram.getBytesLength(DEVCONFIG) != (cfgLen + cfgLen2)) {
ESP_LOGW(TAG, "NVRAM settings invalid"); ESP_LOGE(TAG, "configuration invalid");
eraseConfig(); return false;
} else { } else {
// load device runtime config from nvram and copy it to byte array // load device runtime config from nvram and copy it to byte array
nvram.getBytes(DEVCONFIG, buffer, cfgLen); nvram.getBytes(DEVCONFIG, buffer, cfgLen + cfgLen2);
nvram.end(); nvram.end();
// validate configuration by checking magic bytes at end of array
if (memcmp(buffer + cfgLen, &cfgMagicBytes, cfgLen2) != 0) {
ESP_LOGW(TAG, "No configuration found");
return false;
// copy the byte array into runtime cfg struct } else {
memcpy(&cfg, buffer, cfgLen); // copy byte array into runtime cfg struct
memcpy(&cfg, buffer, cfgLen);
ESP_LOGI(TAG, "Runtime configuration loaded");
return true;
}
} }
} }
} }

View File

@ -196,7 +196,7 @@ void setup() {
#endif #endif
// read (and initialize on first run) runtime settings from NVRAM // read (and initialize on first run) runtime settings from NVRAM
loadConfig(); // includes initialize if necessary assert(loadConfig()); // includes initialize if necessary
// now that we are powered, we scan i2c bus for devices // now that we are powered, we scan i2c bus for devices
i2c_scan(); i2c_scan();