| 
							
							
							
						 |  |  | @ -1,364 +1,364 @@ | 
		
	
		
			
				|  |  |  |  | /* configmanager persists runtime configuration using NVRAM of ESP32*/ | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | #include "globals.h" | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | // Local logging tag
 | 
		
	
		
			
				|  |  |  |  | static const char TAG[] = "flash"; | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | nvs_handle my_handle; | 
		
	
		
			
				|  |  |  |  | esp_err_t err; | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | #define PAYLOADMASK                                                            \ | 
		
	
		
			
				|  |  |  |  |   (ALARM_DATA | MEMS_DATA | COUNT_DATA | GPS_DATA | SENSOR1_DATA |             \ | 
		
	
		
			
				|  |  |  |  |    SENSOR2_DATA | SENSOR3_DATA) &                                              \ | 
		
	
		
			
				|  |  |  |  |       (~BATT_DATA) | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | // populate cfg vars with factory settings
 | 
		
	
		
			
				|  |  |  |  | void defaultConfig() { | 
		
	
		
			
				|  |  |  |  |   cfg.loradr = LORADRDEFAULT;     // 0-15, lora datarate, see paxcounter.conf
 | 
		
	
		
			
				|  |  |  |  |   cfg.txpower = LORATXPOWDEFAULT; // 0-15, lora tx power
 | 
		
	
		
			
				|  |  |  |  |   cfg.adrmode = 1;                // 0=disabled, 1=enabled
 | 
		
	
		
			
				|  |  |  |  |   cfg.screensaver = 0;            // 0=disabled, 1=enabled
 | 
		
	
		
			
				|  |  |  |  |   cfg.screenon = 1;               // 0=disabled, 1=enabled
 | 
		
	
		
			
				|  |  |  |  |   cfg.countermode = COUNTERMODE;  // 0=cyclic, 1=cumulative, 2=cyclic confirmed
 | 
		
	
		
			
				|  |  |  |  |   cfg.rssilimit = 0;              // threshold for rssilimiter, negative value!
 | 
		
	
		
			
				|  |  |  |  |   cfg.sendcycle = SENDCYCLE;      // payload send cycle [seconds/2]
 | 
		
	
		
			
				|  |  |  |  |   cfg.wifichancycle = | 
		
	
		
			
				|  |  |  |  |       WIFI_CHANNEL_SWITCH_INTERVAL; // wifi channel switch cycle [seconds/100]
 | 
		
	
		
			
				|  |  |  |  |   cfg.blescantime = | 
		
	
		
			
				|  |  |  |  |       BLESCANINTERVAL / | 
		
	
		
			
				|  |  |  |  |       10; // BT channel scan cycle [seconds/100], default 1 (= 10ms)
 | 
		
	
		
			
				|  |  |  |  |   cfg.blescan = BLECOUNTER;        // 0=disabled, 1=enabled
 | 
		
	
		
			
				|  |  |  |  |   cfg.wifiscan = WIFICOUNTER;      // 0=disabled, 1=enabled
 | 
		
	
		
			
				|  |  |  |  |   cfg.wifiant = 0;                 // 0=internal, 1=external (for LoPy/LoPy4)
 | 
		
	
		
			
				|  |  |  |  |   cfg.vendorfilter = VENDORFILTER; // 0=disabled, 1=enabled
 | 
		
	
		
			
				|  |  |  |  |   cfg.rgblum = RGBLUMINOSITY;      // RGB Led luminosity (0..100%)
 | 
		
	
		
			
				|  |  |  |  |   cfg.monitormode = 0;             // 0=disabled, 1=enabled
 | 
		
	
		
			
				|  |  |  |  |   cfg.payloadmask = PAYLOADMASK;   // all payload switched on
 | 
		
	
		
			
				|  |  |  |  |   cfg.bsecstate[BSEC_MAX_STATE_BLOB_SIZE] = { | 
		
	
		
			
				|  |  |  |  |       0}; // init BSEC state for BME680 sensor
 | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |   strncpy(cfg.version, PROGVERSION, sizeof(cfg.version) - 1); | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | void open_storage() { | 
		
	
		
			
				|  |  |  |  |   err = nvs_flash_init(); | 
		
	
		
			
				|  |  |  |  |   if (err == ESP_ERR_NVS_NO_FREE_PAGES) { | 
		
	
		
			
				|  |  |  |  |     // NVS partition was truncated and needs to be erased
 | 
		
	
		
			
				|  |  |  |  |     // Retry nvs_flash_init
 | 
		
	
		
			
				|  |  |  |  |     ESP_ERROR_CHECK(nvs_flash_erase()); | 
		
	
		
			
				|  |  |  |  |     err = nvs_flash_init(); | 
		
	
		
			
				|  |  |  |  |   } | 
		
	
		
			
				|  |  |  |  |   ESP_ERROR_CHECK(err); | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |   // Open
 | 
		
	
		
			
				|  |  |  |  |   ESP_LOGI(TAG, "Opening NVS"); | 
		
	
		
			
				|  |  |  |  |   err = nvs_open("config", NVS_READWRITE, &my_handle); | 
		
	
		
			
				|  |  |  |  |   if (err != ESP_OK) | 
		
	
		
			
				|  |  |  |  |     ESP_LOGI(TAG, "Error (%d) opening NVS handle", err); | 
		
	
		
			
				|  |  |  |  |   else | 
		
	
		
			
				|  |  |  |  |     ESP_LOGI(TAG, "Done"); | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | // erase all keys and values in NVRAM
 | 
		
	
		
			
				|  |  |  |  | void eraseConfig() { | 
		
	
		
			
				|  |  |  |  |   ESP_LOGI(TAG, "Clearing settings in NVS"); | 
		
	
		
			
				|  |  |  |  |   open_storage(); | 
		
	
		
			
				|  |  |  |  |   if (err == ESP_OK) { | 
		
	
		
			
				|  |  |  |  |     nvs_erase_all(my_handle); | 
		
	
		
			
				|  |  |  |  |     nvs_commit(my_handle); | 
		
	
		
			
				|  |  |  |  |     nvs_close(my_handle); | 
		
	
		
			
				|  |  |  |  |     ESP_LOGI(TAG, "Done"); | 
		
	
		
			
				|  |  |  |  |   } else { | 
		
	
		
			
				|  |  |  |  |     ESP_LOGW(TAG, "NVS erase failed"); | 
		
	
		
			
				|  |  |  |  |   } | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | // save current configuration from RAM to NVRAM
 | 
		
	
		
			
				|  |  |  |  | void saveConfig() { | 
		
	
		
			
				|  |  |  |  |   ESP_LOGI(TAG, "Storing settings in NVS"); | 
		
	
		
			
				|  |  |  |  |   open_storage(); | 
		
	
		
			
				|  |  |  |  |   if (err == ESP_OK) { | 
		
	
		
			
				|  |  |  |  |     int8_t flash8 = 0; | 
		
	
		
			
				|  |  |  |  |     int16_t flash16 = 0; | 
		
	
		
			
				|  |  |  |  |     size_t required_size; | 
		
	
		
			
				|  |  |  |  |     uint8_t bsecstate_buffer[BSEC_MAX_STATE_BLOB_SIZE + 1]; | 
		
	
		
			
				|  |  |  |  |     char storedversion[10]; | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |     if (nvs_get_blob(my_handle, "bsecstate", bsecstate_buffer, | 
		
	
		
			
				|  |  |  |  |                      &required_size) != ESP_OK || | 
		
	
		
			
				|  |  |  |  |         memcmp(bsecstate_buffer, cfg.bsecstate, BSEC_MAX_STATE_BLOB_SIZE + 1) != | 
		
	
		
			
				|  |  |  |  |             0) | 
		
	
		
			
				|  |  |  |  |       nvs_set_blob(my_handle, "bsecstate", cfg.bsecstate, | 
		
	
		
			
				|  |  |  |  |                    BSEC_MAX_STATE_BLOB_SIZE + 1); | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |     if (nvs_get_str(my_handle, "version", storedversion, &required_size) != | 
		
	
		
			
				|  |  |  |  |             ESP_OK || | 
		
	
		
			
				|  |  |  |  |         strcmp(storedversion, cfg.version) != 0) | 
		
	
		
			
				|  |  |  |  |       nvs_set_str(my_handle, "version", cfg.version); | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |     if (nvs_get_i8(my_handle, "loradr", &flash8) != ESP_OK || | 
		
	
		
			
				|  |  |  |  |         flash8 != cfg.loradr) | 
		
	
		
			
				|  |  |  |  |       nvs_set_i8(my_handle, "loradr", cfg.loradr); | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |     if (nvs_get_i8(my_handle, "txpower", &flash8) != ESP_OK || | 
		
	
		
			
				|  |  |  |  |         flash8 != cfg.txpower) | 
		
	
		
			
				|  |  |  |  |       nvs_set_i8(my_handle, "txpower", cfg.txpower); | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |     if (nvs_get_i8(my_handle, "adrmode", &flash8) != ESP_OK || | 
		
	
		
			
				|  |  |  |  |         flash8 != cfg.adrmode) | 
		
	
		
			
				|  |  |  |  |       nvs_set_i8(my_handle, "adrmode", cfg.adrmode); | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |     if (nvs_get_i8(my_handle, "screensaver", &flash8) != ESP_OK || | 
		
	
		
			
				|  |  |  |  |         flash8 != cfg.screensaver) | 
		
	
		
			
				|  |  |  |  |       nvs_set_i8(my_handle, "screensaver", cfg.screensaver); | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |     if (nvs_get_i8(my_handle, "screenon", &flash8) != ESP_OK || | 
		
	
		
			
				|  |  |  |  |         flash8 != cfg.screenon) | 
		
	
		
			
				|  |  |  |  |       nvs_set_i8(my_handle, "screenon", cfg.screenon); | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |     if (nvs_get_i8(my_handle, "countermode", &flash8) != ESP_OK || | 
		
	
		
			
				|  |  |  |  |         flash8 != cfg.countermode) | 
		
	
		
			
				|  |  |  |  |       nvs_set_i8(my_handle, "countermode", cfg.countermode); | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |     if (nvs_get_i8(my_handle, "sendcycle", &flash8) != ESP_OK || | 
		
	
		
			
				|  |  |  |  |         flash8 != cfg.sendcycle) | 
		
	
		
			
				|  |  |  |  |       nvs_set_i8(my_handle, "sendcycle", cfg.sendcycle); | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |     if (nvs_get_i8(my_handle, "wifichancycle", &flash8) != ESP_OK || | 
		
	
		
			
				|  |  |  |  |         flash8 != cfg.wifichancycle) | 
		
	
		
			
				|  |  |  |  |       nvs_set_i8(my_handle, "wifichancycle", cfg.wifichancycle); | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |     if (nvs_get_i8(my_handle, "blescantime", &flash8) != ESP_OK || | 
		
	
		
			
				|  |  |  |  |         flash8 != cfg.blescantime) | 
		
	
		
			
				|  |  |  |  |       nvs_set_i8(my_handle, "blescantime", cfg.blescantime); | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |     if (nvs_get_i8(my_handle, "blescanmode", &flash8) != ESP_OK || | 
		
	
		
			
				|  |  |  |  |         flash8 != cfg.blescan) | 
		
	
		
			
				|  |  |  |  |       nvs_set_i8(my_handle, "blescanmode", cfg.blescan); | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |     if (nvs_get_i8(my_handle, "wifiscanmode", &flash8) != ESP_OK || | 
		
	
		
			
				|  |  |  |  |         flash8 != cfg.wifiscan) | 
		
	
		
			
				|  |  |  |  |       nvs_set_i8(my_handle, "wifiscanmode", cfg.wifiscan); | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |     if (nvs_get_i8(my_handle, "wifiant", &flash8) != ESP_OK || | 
		
	
		
			
				|  |  |  |  |         flash8 != cfg.wifiant) | 
		
	
		
			
				|  |  |  |  |       nvs_set_i8(my_handle, "wifiant", cfg.wifiant); | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |     if (nvs_get_i8(my_handle, "vendorfilter", &flash8) != ESP_OK || | 
		
	
		
			
				|  |  |  |  |         flash8 != cfg.vendorfilter) | 
		
	
		
			
				|  |  |  |  |       nvs_set_i8(my_handle, "vendorfilter", cfg.vendorfilter); | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |     if (nvs_get_i8(my_handle, "rgblum", &flash8) != ESP_OK || | 
		
	
		
			
				|  |  |  |  |         flash8 != cfg.rgblum) | 
		
	
		
			
				|  |  |  |  |       nvs_set_i8(my_handle, "rgblum", cfg.rgblum); | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |     if (nvs_get_i8(my_handle, "payloadmask", &flash8) != ESP_OK || | 
		
	
		
			
				|  |  |  |  |         flash8 != cfg.payloadmask) | 
		
	
		
			
				|  |  |  |  |       nvs_set_i8(my_handle, "payloadmask", cfg.payloadmask); | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |     if (nvs_get_i8(my_handle, "monitormode", &flash8) != ESP_OK || | 
		
	
		
			
				|  |  |  |  |         flash8 != cfg.monitormode) | 
		
	
		
			
				|  |  |  |  |       nvs_set_i8(my_handle, "monitormode", cfg.monitormode); | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |     if (nvs_get_i16(my_handle, "rssilimit", &flash16) != ESP_OK || | 
		
	
		
			
				|  |  |  |  |         flash16 != cfg.rssilimit) | 
		
	
		
			
				|  |  |  |  |       nvs_set_i16(my_handle, "rssilimit", cfg.rssilimit); | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |     err = nvs_commit(my_handle); | 
		
	
		
			
				|  |  |  |  |     nvs_close(my_handle); | 
		
	
		
			
				|  |  |  |  |     if (err == ESP_OK) { | 
		
	
		
			
				|  |  |  |  |       ESP_LOGI(TAG, "Done"); | 
		
	
		
			
				|  |  |  |  |     } else { | 
		
	
		
			
				|  |  |  |  |       ESP_LOGW(TAG, "NVS config write failed"); | 
		
	
		
			
				|  |  |  |  |     } | 
		
	
		
			
				|  |  |  |  |   } else { | 
		
	
		
			
				|  |  |  |  |     ESP_LOGW(TAG, "Error (%d) opening NVS handle", err); | 
		
	
		
			
				|  |  |  |  |   } | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | // set and save cfg.version
 | 
		
	
		
			
				|  |  |  |  | void migrateVersion() { | 
		
	
		
			
				|  |  |  |  |   snprintf(cfg.version, 10, "%s", PROGVERSION); | 
		
	
		
			
				|  |  |  |  |   ESP_LOGI(TAG, "version set to %s", cfg.version); | 
		
	
		
			
				|  |  |  |  |   saveConfig(); | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | // load configuration from NVRAM into RAM and make it current
 | 
		
	
		
			
				|  |  |  |  | void loadConfig() { | 
		
	
		
			
				|  |  |  |  |   defaultConfig(); // start with factory settings
 | 
		
	
		
			
				|  |  |  |  |   ESP_LOGI(TAG, "Reading settings from NVS"); | 
		
	
		
			
				|  |  |  |  |   open_storage(); | 
		
	
		
			
				|  |  |  |  |   if (err != ESP_OK) { | 
		
	
		
			
				|  |  |  |  |     ESP_LOGW(TAG, "Error (%d) opening NVS handle, storing defaults", err); | 
		
	
		
			
				|  |  |  |  |     saveConfig(); | 
		
	
		
			
				|  |  |  |  |   } // saves factory settings to NVRAM
 | 
		
	
		
			
				|  |  |  |  |   else { | 
		
	
		
			
				|  |  |  |  |     int8_t flash8 = 0; | 
		
	
		
			
				|  |  |  |  |     int16_t flash16 = 0; | 
		
	
		
			
				|  |  |  |  |     size_t required_size; | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |     // check if configuration stored in NVRAM matches PROGVERSION
 | 
		
	
		
			
				|  |  |  |  |     if (nvs_get_str(my_handle, "version", NULL, &required_size) == ESP_OK) { | 
		
	
		
			
				|  |  |  |  |       nvs_get_str(my_handle, "version", cfg.version, &required_size); | 
		
	
		
			
				|  |  |  |  |       ESP_LOGI(TAG, "NVRAM settings version = %s", cfg.version); | 
		
	
		
			
				|  |  |  |  |       if (strcmp(cfg.version, PROGVERSION)) { | 
		
	
		
			
				|  |  |  |  |         ESP_LOGI(TAG, "migrating NVRAM settings to new version %s", | 
		
	
		
			
				|  |  |  |  |                  PROGVERSION); | 
		
	
		
			
				|  |  |  |  |         nvs_close(my_handle); | 
		
	
		
			
				|  |  |  |  |         migrateVersion(); | 
		
	
		
			
				|  |  |  |  |       } | 
		
	
		
			
				|  |  |  |  |     } else { | 
		
	
		
			
				|  |  |  |  |       ESP_LOGI(TAG, "new version %s, deleting NVRAM settings", PROGVERSION); | 
		
	
		
			
				|  |  |  |  |       nvs_close(my_handle); | 
		
	
		
			
				|  |  |  |  |       eraseConfig(); | 
		
	
		
			
				|  |  |  |  |       migrateVersion(); | 
		
	
		
			
				|  |  |  |  |     } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |     // populate pre set defaults with current values from NVRAM
 | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |     if (nvs_get_blob(my_handle, "bsecstate", NULL, &required_size) == ESP_OK) { | 
		
	
		
			
				|  |  |  |  |       nvs_get_blob(my_handle, "bsecstate", cfg.bsecstate, &required_size); | 
		
	
		
			
				|  |  |  |  |       ESP_LOGI(TAG, "bsecstate = %d", cfg.bsecstate[BSEC_MAX_STATE_BLOB_SIZE]); | 
		
	
		
			
				|  |  |  |  |     }; | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |     if (nvs_get_i8(my_handle, "loradr", &flash8) == ESP_OK) { | 
		
	
		
			
				|  |  |  |  |       cfg.loradr = flash8; | 
		
	
		
			
				|  |  |  |  |       ESP_LOGI(TAG, "loradr = %d", flash8); | 
		
	
		
			
				|  |  |  |  |     } else { | 
		
	
		
			
				|  |  |  |  |       ESP_LOGI(TAG, "loradr set to default %d", cfg.loradr); | 
		
	
		
			
				|  |  |  |  |       saveConfig(); | 
		
	
		
			
				|  |  |  |  |     } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |     if (nvs_get_i8(my_handle, "txpower", &flash8) == ESP_OK) { | 
		
	
		
			
				|  |  |  |  |       cfg.txpower = flash8; | 
		
	
		
			
				|  |  |  |  |       ESP_LOGI(TAG, "txpower = %d", flash8); | 
		
	
		
			
				|  |  |  |  |     } else { | 
		
	
		
			
				|  |  |  |  |       ESP_LOGI(TAG, "txpower set to default %d", cfg.txpower); | 
		
	
		
			
				|  |  |  |  |       saveConfig(); | 
		
	
		
			
				|  |  |  |  |     } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |     if (nvs_get_i8(my_handle, "adrmode", &flash8) == ESP_OK) { | 
		
	
		
			
				|  |  |  |  |       cfg.adrmode = flash8; | 
		
	
		
			
				|  |  |  |  |       ESP_LOGI(TAG, "adrmode = %d", flash8); | 
		
	
		
			
				|  |  |  |  |     } else { | 
		
	
		
			
				|  |  |  |  |       ESP_LOGI(TAG, "adrmode set to default %d", cfg.adrmode); | 
		
	
		
			
				|  |  |  |  |       saveConfig(); | 
		
	
		
			
				|  |  |  |  |     } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |     if (nvs_get_i8(my_handle, "screensaver", &flash8) == ESP_OK) { | 
		
	
		
			
				|  |  |  |  |       cfg.screensaver = flash8; | 
		
	
		
			
				|  |  |  |  |       ESP_LOGI(TAG, "screensaver = %d", flash8); | 
		
	
		
			
				|  |  |  |  |     } else { | 
		
	
		
			
				|  |  |  |  |       ESP_LOGI(TAG, "screensaver set to default %d", cfg.screensaver); | 
		
	
		
			
				|  |  |  |  |       saveConfig(); | 
		
	
		
			
				|  |  |  |  |     } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |     if (nvs_get_i8(my_handle, "screenon", &flash8) == ESP_OK) { | 
		
	
		
			
				|  |  |  |  |       cfg.screenon = flash8; | 
		
	
		
			
				|  |  |  |  |       ESP_LOGI(TAG, "screenon = %d", flash8); | 
		
	
		
			
				|  |  |  |  |     } else { | 
		
	
		
			
				|  |  |  |  |       ESP_LOGI(TAG, "screenon set to default %d", cfg.screenon); | 
		
	
		
			
				|  |  |  |  |       saveConfig(); | 
		
	
		
			
				|  |  |  |  |     } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |     if (nvs_get_i8(my_handle, "countermode", &flash8) == ESP_OK) { | 
		
	
		
			
				|  |  |  |  |       cfg.countermode = flash8; | 
		
	
		
			
				|  |  |  |  |       ESP_LOGI(TAG, "countermode = %d", flash8); | 
		
	
		
			
				|  |  |  |  |     } else { | 
		
	
		
			
				|  |  |  |  |       ESP_LOGI(TAG, "countermode set to default %d", cfg.countermode); | 
		
	
		
			
				|  |  |  |  |       saveConfig(); | 
		
	
		
			
				|  |  |  |  |     } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |     if (nvs_get_i8(my_handle, "sendcycle", &flash8) == ESP_OK) { | 
		
	
		
			
				|  |  |  |  |       cfg.sendcycle = flash8; | 
		
	
		
			
				|  |  |  |  |       ESP_LOGI(TAG, "sendcycle = %d", flash8); | 
		
	
		
			
				|  |  |  |  |     } else { | 
		
	
		
			
				|  |  |  |  |       ESP_LOGI(TAG, "Payload send cycle set to default %d", cfg.sendcycle); | 
		
	
		
			
				|  |  |  |  |       saveConfig(); | 
		
	
		
			
				|  |  |  |  |     } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |     if (nvs_get_i8(my_handle, "wifichancycle", &flash8) == ESP_OK) { | 
		
	
		
			
				|  |  |  |  |       cfg.wifichancycle = flash8; | 
		
	
		
			
				|  |  |  |  |       ESP_LOGI(TAG, "wifichancycle = %d", flash8); | 
		
	
		
			
				|  |  |  |  |     } else { | 
		
	
		
			
				|  |  |  |  |       ESP_LOGI(TAG, "WIFI channel cycle set to default %d", cfg.wifichancycle); | 
		
	
		
			
				|  |  |  |  |       saveConfig(); | 
		
	
		
			
				|  |  |  |  |     } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |     if (nvs_get_i8(my_handle, "wifiant", &flash8) == ESP_OK) { | 
		
	
		
			
				|  |  |  |  |       cfg.wifiant = flash8; | 
		
	
		
			
				|  |  |  |  |       ESP_LOGI(TAG, "wifiantenna = %d", flash8); | 
		
	
		
			
				|  |  |  |  |     } else { | 
		
	
		
			
				|  |  |  |  |       ESP_LOGI(TAG, "WIFI antenna switch set to default %d", cfg.wifiant); | 
		
	
		
			
				|  |  |  |  |       saveConfig(); | 
		
	
		
			
				|  |  |  |  |     } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |     if (nvs_get_i8(my_handle, "vendorfilter", &flash8) == ESP_OK) { | 
		
	
		
			
				|  |  |  |  |       cfg.vendorfilter = flash8; | 
		
	
		
			
				|  |  |  |  |       ESP_LOGI(TAG, "vendorfilter = %d", flash8); | 
		
	
		
			
				|  |  |  |  |     } else { | 
		
	
		
			
				|  |  |  |  |       ESP_LOGI(TAG, "Vendorfilter mode set to default %d", cfg.vendorfilter); | 
		
	
		
			
				|  |  |  |  |       saveConfig(); | 
		
	
		
			
				|  |  |  |  |     } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |     if (nvs_get_i8(my_handle, "rgblum", &flash8) == ESP_OK) { | 
		
	
		
			
				|  |  |  |  |       cfg.rgblum = flash8; | 
		
	
		
			
				|  |  |  |  |       ESP_LOGI(TAG, "rgbluminosity = %d", flash8); | 
		
	
		
			
				|  |  |  |  |     } else { | 
		
	
		
			
				|  |  |  |  |       ESP_LOGI(TAG, "RGB luminosity set to default %d", cfg.rgblum); | 
		
	
		
			
				|  |  |  |  |       saveConfig(); | 
		
	
		
			
				|  |  |  |  |     } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |     if (nvs_get_i8(my_handle, "blescantime", &flash8) == ESP_OK) { | 
		
	
		
			
				|  |  |  |  |       cfg.blescantime = flash8; | 
		
	
		
			
				|  |  |  |  |       ESP_LOGI(TAG, "blescantime = %d", flash8); | 
		
	
		
			
				|  |  |  |  |     } else { | 
		
	
		
			
				|  |  |  |  |       ESP_LOGI(TAG, "BLEscantime set to default %d", cfg.blescantime); | 
		
	
		
			
				|  |  |  |  |       saveConfig(); | 
		
	
		
			
				|  |  |  |  |     } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |     if (nvs_get_i8(my_handle, "blescanmode", &flash8) == ESP_OK) { | 
		
	
		
			
				|  |  |  |  |       cfg.blescan = flash8; | 
		
	
		
			
				|  |  |  |  |       ESP_LOGI(TAG, "BLEscanmode = %d", flash8); | 
		
	
		
			
				|  |  |  |  |     } else { | 
		
	
		
			
				|  |  |  |  |       ESP_LOGI(TAG, "BLEscanmode set to default %d", cfg.blescan); | 
		
	
		
			
				|  |  |  |  |       saveConfig(); | 
		
	
		
			
				|  |  |  |  |     } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |     if (nvs_get_i8(my_handle, "wifiscanmode", &flash8) == ESP_OK) { | 
		
	
		
			
				|  |  |  |  |       cfg.wifiscan = flash8; | 
		
	
		
			
				|  |  |  |  |       ESP_LOGI(TAG, "WIFIscanmode = %d", flash8); | 
		
	
		
			
				|  |  |  |  |     } else { | 
		
	
		
			
				|  |  |  |  |       ESP_LOGI(TAG, "WIFIscanmode set to default %d", cfg.wifiscan); | 
		
	
		
			
				|  |  |  |  |       saveConfig(); | 
		
	
		
			
				|  |  |  |  |     } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |     if (nvs_get_i16(my_handle, "rssilimit", &flash16) == ESP_OK) { | 
		
	
		
			
				|  |  |  |  |       cfg.rssilimit = flash16; | 
		
	
		
			
				|  |  |  |  |       ESP_LOGI(TAG, "rssilimit = %d", flash16); | 
		
	
		
			
				|  |  |  |  |     } else { | 
		
	
		
			
				|  |  |  |  |       ESP_LOGI(TAG, "rssilimit set to default %d", cfg.rssilimit); | 
		
	
		
			
				|  |  |  |  |       saveConfig(); | 
		
	
		
			
				|  |  |  |  |     } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |     if (nvs_get_i8(my_handle, "payloadmask", &flash8) == ESP_OK) { | 
		
	
		
			
				|  |  |  |  |       cfg.payloadmask = flash8; | 
		
	
		
			
				|  |  |  |  |       ESP_LOGI(TAG, "payloadmask = %hhu", flash8); | 
		
	
		
			
				|  |  |  |  |     } else { | 
		
	
		
			
				|  |  |  |  |       ESP_LOGI(TAG, "payloadmask set to default %hhu", cfg.payloadmask); | 
		
	
		
			
				|  |  |  |  |       saveConfig(); | 
		
	
		
			
				|  |  |  |  |     } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |     if (nvs_get_i8(my_handle, "monitormode", &flash8) == ESP_OK) { | 
		
	
		
			
				|  |  |  |  |       cfg.monitormode = flash8; | 
		
	
		
			
				|  |  |  |  |       ESP_LOGI(TAG, "Monitor mode = %d", flash8); | 
		
	
		
			
				|  |  |  |  |     } else { | 
		
	
		
			
				|  |  |  |  |       ESP_LOGI(TAG, "Monitor mode set to default %d", cfg.monitormode); | 
		
	
		
			
				|  |  |  |  |       saveConfig(); | 
		
	
		
			
				|  |  |  |  |     } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |     nvs_close(my_handle); | 
		
	
		
			
				|  |  |  |  |     ESP_LOGI(TAG, "Done"); | 
		
	
		
			
				|  |  |  |  |   } | 
		
	
		
			
				|  |  |  |  | } // loadConfig()
 | 
		
	
		
			
				|  |  |  |  | /* configmanager persists runtime configuration using NVRAM of ESP32*/ | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | #include "globals.h" | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | // Local logging tag
 | 
		
	
		
			
				|  |  |  |  | static const char TAG[] = "flash"; | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | nvs_handle my_handle; | 
		
	
		
			
				|  |  |  |  | esp_err_t err; | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | #define PAYLOADMASK                                  \ | 
		
	
		
			
				|  |  |  |  |   ((GPS_DATA | ALARM_DATA | MEMS_DATA | COUNT_DATA | \ | 
		
	
		
			
				|  |  |  |  |     SENSOR1_DATA | SENSOR2_DATA | SENSOR3_DATA) &    \ | 
		
	
		
			
				|  |  |  |  |    (~BATT_DATA) ) | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | // populate cfg vars with factory settings
 | 
		
	
		
			
				|  |  |  |  | void defaultConfig() { | 
		
	
		
			
				|  |  |  |  |   cfg.loradr = LORADRDEFAULT;     // 0-15, lora datarate, see paxcounter.conf
 | 
		
	
		
			
				|  |  |  |  |   cfg.txpower = LORATXPOWDEFAULT; // 0-15, lora tx power
 | 
		
	
		
			
				|  |  |  |  |   cfg.adrmode = 1;                // 0=disabled, 1=enabled
 | 
		
	
		
			
				|  |  |  |  |   cfg.screensaver = 0;            // 0=disabled, 1=enabled
 | 
		
	
		
			
				|  |  |  |  |   cfg.screenon = 1;               // 0=disabled, 1=enabled
 | 
		
	
		
			
				|  |  |  |  |   cfg.countermode = COUNTERMODE;  // 0=cyclic, 1=cumulative, 2=cyclic confirmed
 | 
		
	
		
			
				|  |  |  |  |   cfg.rssilimit = 0;              // threshold for rssilimiter, negative value!
 | 
		
	
		
			
				|  |  |  |  |   cfg.sendcycle = SENDCYCLE;      // payload send cycle [seconds/2]
 | 
		
	
		
			
				|  |  |  |  |   cfg.wifichancycle = | 
		
	
		
			
				|  |  |  |  |       WIFI_CHANNEL_SWITCH_INTERVAL; // wifi channel switch cycle [seconds/100]
 | 
		
	
		
			
				|  |  |  |  |   cfg.blescantime = | 
		
	
		
			
				|  |  |  |  |       BLESCANINTERVAL / | 
		
	
		
			
				|  |  |  |  |       10; // BT channel scan cycle [seconds/100], default 1 (= 10ms)
 | 
		
	
		
			
				|  |  |  |  |   cfg.blescan = BLECOUNTER;        // 0=disabled, 1=enabled
 | 
		
	
		
			
				|  |  |  |  |   cfg.wifiscan = WIFICOUNTER;      // 0=disabled, 1=enabled
 | 
		
	
		
			
				|  |  |  |  |   cfg.wifiant = 0;                 // 0=internal, 1=external (for LoPy/LoPy4)
 | 
		
	
		
			
				|  |  |  |  |   cfg.vendorfilter = VENDORFILTER; // 0=disabled, 1=enabled
 | 
		
	
		
			
				|  |  |  |  |   cfg.rgblum = RGBLUMINOSITY;      // RGB Led luminosity (0..100%)
 | 
		
	
		
			
				|  |  |  |  |   cfg.monitormode = 0;             // 0=disabled, 1=enabled
 | 
		
	
		
			
				|  |  |  |  |   cfg.payloadmask = PAYLOADMASK;   // all payload switched on
 | 
		
	
		
			
				|  |  |  |  |   cfg.bsecstate[BSEC_MAX_STATE_BLOB_SIZE] = { | 
		
	
		
			
				|  |  |  |  |       0}; // init BSEC state for BME680 sensor
 | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |   strncpy(cfg.version, PROGVERSION, sizeof(cfg.version) - 1); | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | void open_storage() { | 
		
	
		
			
				|  |  |  |  |   err = nvs_flash_init(); | 
		
	
		
			
				|  |  |  |  |   if (err == ESP_ERR_NVS_NO_FREE_PAGES) { | 
		
	
		
			
				|  |  |  |  |     // NVS partition was truncated and needs to be erased
 | 
		
	
		
			
				|  |  |  |  |     // Retry nvs_flash_init
 | 
		
	
		
			
				|  |  |  |  |     ESP_ERROR_CHECK(nvs_flash_erase()); | 
		
	
		
			
				|  |  |  |  |     err = nvs_flash_init(); | 
		
	
		
			
				|  |  |  |  |   } | 
		
	
		
			
				|  |  |  |  |   ESP_ERROR_CHECK(err); | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |   // Open
 | 
		
	
		
			
				|  |  |  |  |   ESP_LOGI(TAG, "Opening NVS"); | 
		
	
		
			
				|  |  |  |  |   err = nvs_open("config", NVS_READWRITE, &my_handle); | 
		
	
		
			
				|  |  |  |  |   if (err != ESP_OK) | 
		
	
		
			
				|  |  |  |  |     ESP_LOGI(TAG, "Error (%d) opening NVS handle", err); | 
		
	
		
			
				|  |  |  |  |   else | 
		
	
		
			
				|  |  |  |  |     ESP_LOGI(TAG, "Done"); | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | // erase all keys and values in NVRAM
 | 
		
	
		
			
				|  |  |  |  | void eraseConfig() { | 
		
	
		
			
				|  |  |  |  |   ESP_LOGI(TAG, "Clearing settings in NVS"); | 
		
	
		
			
				|  |  |  |  |   open_storage(); | 
		
	
		
			
				|  |  |  |  |   if (err == ESP_OK) { | 
		
	
		
			
				|  |  |  |  |     nvs_erase_all(my_handle); | 
		
	
		
			
				|  |  |  |  |     nvs_commit(my_handle); | 
		
	
		
			
				|  |  |  |  |     nvs_close(my_handle); | 
		
	
		
			
				|  |  |  |  |     ESP_LOGI(TAG, "Done"); | 
		
	
		
			
				|  |  |  |  |   } else { | 
		
	
		
			
				|  |  |  |  |     ESP_LOGW(TAG, "NVS erase failed"); | 
		
	
		
			
				|  |  |  |  |   } | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | // save current configuration from RAM to NVRAM
 | 
		
	
		
			
				|  |  |  |  | void saveConfig() { | 
		
	
		
			
				|  |  |  |  |   ESP_LOGI(TAG, "Storing settings in NVS"); | 
		
	
		
			
				|  |  |  |  |   open_storage(); | 
		
	
		
			
				|  |  |  |  |   if (err == ESP_OK) { | 
		
	
		
			
				|  |  |  |  |     int8_t flash8 = 0; | 
		
	
		
			
				|  |  |  |  |     int16_t flash16 = 0; | 
		
	
		
			
				|  |  |  |  |     size_t required_size; | 
		
	
		
			
				|  |  |  |  |     uint8_t bsecstate_buffer[BSEC_MAX_STATE_BLOB_SIZE + 1]; | 
		
	
		
			
				|  |  |  |  |     char storedversion[10]; | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |     if (nvs_get_blob(my_handle, "bsecstate", bsecstate_buffer, | 
		
	
		
			
				|  |  |  |  |                      &required_size) != ESP_OK || | 
		
	
		
			
				|  |  |  |  |         memcmp(bsecstate_buffer, cfg.bsecstate, BSEC_MAX_STATE_BLOB_SIZE + 1) != | 
		
	
		
			
				|  |  |  |  |             0) | 
		
	
		
			
				|  |  |  |  |       nvs_set_blob(my_handle, "bsecstate", cfg.bsecstate, | 
		
	
		
			
				|  |  |  |  |                    BSEC_MAX_STATE_BLOB_SIZE + 1); | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |     if (nvs_get_str(my_handle, "version", storedversion, &required_size) != | 
		
	
		
			
				|  |  |  |  |             ESP_OK || | 
		
	
		
			
				|  |  |  |  |         strcmp(storedversion, cfg.version) != 0) | 
		
	
		
			
				|  |  |  |  |       nvs_set_str(my_handle, "version", cfg.version); | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |     if (nvs_get_i8(my_handle, "loradr", &flash8) != ESP_OK || | 
		
	
		
			
				|  |  |  |  |         flash8 != cfg.loradr) | 
		
	
		
			
				|  |  |  |  |       nvs_set_i8(my_handle, "loradr", cfg.loradr); | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |     if (nvs_get_i8(my_handle, "txpower", &flash8) != ESP_OK || | 
		
	
		
			
				|  |  |  |  |         flash8 != cfg.txpower) | 
		
	
		
			
				|  |  |  |  |       nvs_set_i8(my_handle, "txpower", cfg.txpower); | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |     if (nvs_get_i8(my_handle, "adrmode", &flash8) != ESP_OK || | 
		
	
		
			
				|  |  |  |  |         flash8 != cfg.adrmode) | 
		
	
		
			
				|  |  |  |  |       nvs_set_i8(my_handle, "adrmode", cfg.adrmode); | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |     if (nvs_get_i8(my_handle, "screensaver", &flash8) != ESP_OK || | 
		
	
		
			
				|  |  |  |  |         flash8 != cfg.screensaver) | 
		
	
		
			
				|  |  |  |  |       nvs_set_i8(my_handle, "screensaver", cfg.screensaver); | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |     if (nvs_get_i8(my_handle, "screenon", &flash8) != ESP_OK || | 
		
	
		
			
				|  |  |  |  |         flash8 != cfg.screenon) | 
		
	
		
			
				|  |  |  |  |       nvs_set_i8(my_handle, "screenon", cfg.screenon); | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |     if (nvs_get_i8(my_handle, "countermode", &flash8) != ESP_OK || | 
		
	
		
			
				|  |  |  |  |         flash8 != cfg.countermode) | 
		
	
		
			
				|  |  |  |  |       nvs_set_i8(my_handle, "countermode", cfg.countermode); | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |     if (nvs_get_i8(my_handle, "sendcycle", &flash8) != ESP_OK || | 
		
	
		
			
				|  |  |  |  |         flash8 != cfg.sendcycle) | 
		
	
		
			
				|  |  |  |  |       nvs_set_i8(my_handle, "sendcycle", cfg.sendcycle); | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |     if (nvs_get_i8(my_handle, "wifichancycle", &flash8) != ESP_OK || | 
		
	
		
			
				|  |  |  |  |         flash8 != cfg.wifichancycle) | 
		
	
		
			
				|  |  |  |  |       nvs_set_i8(my_handle, "wifichancycle", cfg.wifichancycle); | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |     if (nvs_get_i8(my_handle, "blescantime", &flash8) != ESP_OK || | 
		
	
		
			
				|  |  |  |  |         flash8 != cfg.blescantime) | 
		
	
		
			
				|  |  |  |  |       nvs_set_i8(my_handle, "blescantime", cfg.blescantime); | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |     if (nvs_get_i8(my_handle, "blescanmode", &flash8) != ESP_OK || | 
		
	
		
			
				|  |  |  |  |         flash8 != cfg.blescan) | 
		
	
		
			
				|  |  |  |  |       nvs_set_i8(my_handle, "blescanmode", cfg.blescan); | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |     if (nvs_get_i8(my_handle, "wifiscanmode", &flash8) != ESP_OK || | 
		
	
		
			
				|  |  |  |  |         flash8 != cfg.wifiscan) | 
		
	
		
			
				|  |  |  |  |       nvs_set_i8(my_handle, "wifiscanmode", cfg.wifiscan); | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |     if (nvs_get_i8(my_handle, "wifiant", &flash8) != ESP_OK || | 
		
	
		
			
				|  |  |  |  |         flash8 != cfg.wifiant) | 
		
	
		
			
				|  |  |  |  |       nvs_set_i8(my_handle, "wifiant", cfg.wifiant); | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |     if (nvs_get_i8(my_handle, "vendorfilter", &flash8) != ESP_OK || | 
		
	
		
			
				|  |  |  |  |         flash8 != cfg.vendorfilter) | 
		
	
		
			
				|  |  |  |  |       nvs_set_i8(my_handle, "vendorfilter", cfg.vendorfilter); | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |     if (nvs_get_i8(my_handle, "rgblum", &flash8) != ESP_OK || | 
		
	
		
			
				|  |  |  |  |         flash8 != cfg.rgblum) | 
		
	
		
			
				|  |  |  |  |       nvs_set_i8(my_handle, "rgblum", cfg.rgblum); | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |     if (nvs_get_i8(my_handle, "payloadmask", &flash8) != ESP_OK || | 
		
	
		
			
				|  |  |  |  |         flash8 != cfg.payloadmask) | 
		
	
		
			
				|  |  |  |  |       nvs_set_i8(my_handle, "payloadmask", cfg.payloadmask); | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |     if (nvs_get_i8(my_handle, "monitormode", &flash8) != ESP_OK || | 
		
	
		
			
				|  |  |  |  |         flash8 != cfg.monitormode) | 
		
	
		
			
				|  |  |  |  |       nvs_set_i8(my_handle, "monitormode", cfg.monitormode); | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |     if (nvs_get_i16(my_handle, "rssilimit", &flash16) != ESP_OK || | 
		
	
		
			
				|  |  |  |  |         flash16 != cfg.rssilimit) | 
		
	
		
			
				|  |  |  |  |       nvs_set_i16(my_handle, "rssilimit", cfg.rssilimit); | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |     err = nvs_commit(my_handle); | 
		
	
		
			
				|  |  |  |  |     nvs_close(my_handle); | 
		
	
		
			
				|  |  |  |  |     if (err == ESP_OK) { | 
		
	
		
			
				|  |  |  |  |       ESP_LOGI(TAG, "Done"); | 
		
	
		
			
				|  |  |  |  |     } else { | 
		
	
		
			
				|  |  |  |  |       ESP_LOGW(TAG, "NVS config write failed"); | 
		
	
		
			
				|  |  |  |  |     } | 
		
	
		
			
				|  |  |  |  |   } else { | 
		
	
		
			
				|  |  |  |  |     ESP_LOGW(TAG, "Error (%d) opening NVS handle", err); | 
		
	
		
			
				|  |  |  |  |   } | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | // set and save cfg.version
 | 
		
	
		
			
				|  |  |  |  | void migrateVersion() { | 
		
	
		
			
				|  |  |  |  |   snprintf(cfg.version, 10, "%s", PROGVERSION); | 
		
	
		
			
				|  |  |  |  |   ESP_LOGI(TAG, "version set to %s", cfg.version); | 
		
	
		
			
				|  |  |  |  |   saveConfig(); | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | // load configuration from NVRAM into RAM and make it current
 | 
		
	
		
			
				|  |  |  |  | void loadConfig() { | 
		
	
		
			
				|  |  |  |  |   defaultConfig(); // start with factory settings
 | 
		
	
		
			
				|  |  |  |  |   ESP_LOGI(TAG, "Reading settings from NVS"); | 
		
	
		
			
				|  |  |  |  |   open_storage(); | 
		
	
		
			
				|  |  |  |  |   if (err != ESP_OK) { | 
		
	
		
			
				|  |  |  |  |     ESP_LOGW(TAG, "Error (%d) opening NVS handle, storing defaults", err); | 
		
	
		
			
				|  |  |  |  |     saveConfig(); | 
		
	
		
			
				|  |  |  |  |   } // saves factory settings to NVRAM
 | 
		
	
		
			
				|  |  |  |  |   else { | 
		
	
		
			
				|  |  |  |  |     int8_t flash8 = 0; | 
		
	
		
			
				|  |  |  |  |     int16_t flash16 = 0; | 
		
	
		
			
				|  |  |  |  |     size_t required_size; | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |     // check if configuration stored in NVRAM matches PROGVERSION
 | 
		
	
		
			
				|  |  |  |  |     if (nvs_get_str(my_handle, "version", NULL, &required_size) == ESP_OK) { | 
		
	
		
			
				|  |  |  |  |       nvs_get_str(my_handle, "version", cfg.version, &required_size); | 
		
	
		
			
				|  |  |  |  |       ESP_LOGI(TAG, "NVRAM settings version = %s", cfg.version); | 
		
	
		
			
				|  |  |  |  |       if (strcmp(cfg.version, PROGVERSION)) { | 
		
	
		
			
				|  |  |  |  |         ESP_LOGI(TAG, "migrating NVRAM settings to new version %s", | 
		
	
		
			
				|  |  |  |  |                  PROGVERSION); | 
		
	
		
			
				|  |  |  |  |         nvs_close(my_handle); | 
		
	
		
			
				|  |  |  |  |         migrateVersion(); | 
		
	
		
			
				|  |  |  |  |       } | 
		
	
		
			
				|  |  |  |  |     } else { | 
		
	
		
			
				|  |  |  |  |       ESP_LOGI(TAG, "new version %s, deleting NVRAM settings", PROGVERSION); | 
		
	
		
			
				|  |  |  |  |       nvs_close(my_handle); | 
		
	
		
			
				|  |  |  |  |       eraseConfig(); | 
		
	
		
			
				|  |  |  |  |       migrateVersion(); | 
		
	
		
			
				|  |  |  |  |     } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |     // populate pre set defaults with current values from NVRAM
 | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |     if (nvs_get_blob(my_handle, "bsecstate", NULL, &required_size) == ESP_OK) { | 
		
	
		
			
				|  |  |  |  |       nvs_get_blob(my_handle, "bsecstate", cfg.bsecstate, &required_size); | 
		
	
		
			
				|  |  |  |  |       ESP_LOGI(TAG, "bsecstate = %d", cfg.bsecstate[BSEC_MAX_STATE_BLOB_SIZE]); | 
		
	
		
			
				|  |  |  |  |     }; | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |     if (nvs_get_i8(my_handle, "loradr", &flash8) == ESP_OK) { | 
		
	
		
			
				|  |  |  |  |       cfg.loradr = flash8; | 
		
	
		
			
				|  |  |  |  |       ESP_LOGI(TAG, "loradr = %d", flash8); | 
		
	
		
			
				|  |  |  |  |     } else { | 
		
	
		
			
				|  |  |  |  |       ESP_LOGI(TAG, "loradr set to default %d", cfg.loradr); | 
		
	
		
			
				|  |  |  |  |       saveConfig(); | 
		
	
		
			
				|  |  |  |  |     } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |     if (nvs_get_i8(my_handle, "txpower", &flash8) == ESP_OK) { | 
		
	
		
			
				|  |  |  |  |       cfg.txpower = flash8; | 
		
	
		
			
				|  |  |  |  |       ESP_LOGI(TAG, "txpower = %d", flash8); | 
		
	
		
			
				|  |  |  |  |     } else { | 
		
	
		
			
				|  |  |  |  |       ESP_LOGI(TAG, "txpower set to default %d", cfg.txpower); | 
		
	
		
			
				|  |  |  |  |       saveConfig(); | 
		
	
		
			
				|  |  |  |  |     } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |     if (nvs_get_i8(my_handle, "adrmode", &flash8) == ESP_OK) { | 
		
	
		
			
				|  |  |  |  |       cfg.adrmode = flash8; | 
		
	
		
			
				|  |  |  |  |       ESP_LOGI(TAG, "adrmode = %d", flash8); | 
		
	
		
			
				|  |  |  |  |     } else { | 
		
	
		
			
				|  |  |  |  |       ESP_LOGI(TAG, "adrmode set to default %d", cfg.adrmode); | 
		
	
		
			
				|  |  |  |  |       saveConfig(); | 
		
	
		
			
				|  |  |  |  |     } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |     if (nvs_get_i8(my_handle, "screensaver", &flash8) == ESP_OK) { | 
		
	
		
			
				|  |  |  |  |       cfg.screensaver = flash8; | 
		
	
		
			
				|  |  |  |  |       ESP_LOGI(TAG, "screensaver = %d", flash8); | 
		
	
		
			
				|  |  |  |  |     } else { | 
		
	
		
			
				|  |  |  |  |       ESP_LOGI(TAG, "screensaver set to default %d", cfg.screensaver); | 
		
	
		
			
				|  |  |  |  |       saveConfig(); | 
		
	
		
			
				|  |  |  |  |     } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |     if (nvs_get_i8(my_handle, "screenon", &flash8) == ESP_OK) { | 
		
	
		
			
				|  |  |  |  |       cfg.screenon = flash8; | 
		
	
		
			
				|  |  |  |  |       ESP_LOGI(TAG, "screenon = %d", flash8); | 
		
	
		
			
				|  |  |  |  |     } else { | 
		
	
		
			
				|  |  |  |  |       ESP_LOGI(TAG, "screenon set to default %d", cfg.screenon); | 
		
	
		
			
				|  |  |  |  |       saveConfig(); | 
		
	
		
			
				|  |  |  |  |     } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |     if (nvs_get_i8(my_handle, "countermode", &flash8) == ESP_OK) { | 
		
	
		
			
				|  |  |  |  |       cfg.countermode = flash8; | 
		
	
		
			
				|  |  |  |  |       ESP_LOGI(TAG, "countermode = %d", flash8); | 
		
	
		
			
				|  |  |  |  |     } else { | 
		
	
		
			
				|  |  |  |  |       ESP_LOGI(TAG, "countermode set to default %d", cfg.countermode); | 
		
	
		
			
				|  |  |  |  |       saveConfig(); | 
		
	
		
			
				|  |  |  |  |     } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |     if (nvs_get_i8(my_handle, "sendcycle", &flash8) == ESP_OK) { | 
		
	
		
			
				|  |  |  |  |       cfg.sendcycle = flash8; | 
		
	
		
			
				|  |  |  |  |       ESP_LOGI(TAG, "sendcycle = %d", flash8); | 
		
	
		
			
				|  |  |  |  |     } else { | 
		
	
		
			
				|  |  |  |  |       ESP_LOGI(TAG, "Payload send cycle set to default %d", cfg.sendcycle); | 
		
	
		
			
				|  |  |  |  |       saveConfig(); | 
		
	
		
			
				|  |  |  |  |     } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |     if (nvs_get_i8(my_handle, "wifichancycle", &flash8) == ESP_OK) { | 
		
	
		
			
				|  |  |  |  |       cfg.wifichancycle = flash8; | 
		
	
		
			
				|  |  |  |  |       ESP_LOGI(TAG, "wifichancycle = %d", flash8); | 
		
	
		
			
				|  |  |  |  |     } else { | 
		
	
		
			
				|  |  |  |  |       ESP_LOGI(TAG, "WIFI channel cycle set to default %d", cfg.wifichancycle); | 
		
	
		
			
				|  |  |  |  |       saveConfig(); | 
		
	
		
			
				|  |  |  |  |     } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |     if (nvs_get_i8(my_handle, "wifiant", &flash8) == ESP_OK) { | 
		
	
		
			
				|  |  |  |  |       cfg.wifiant = flash8; | 
		
	
		
			
				|  |  |  |  |       ESP_LOGI(TAG, "wifiantenna = %d", flash8); | 
		
	
		
			
				|  |  |  |  |     } else { | 
		
	
		
			
				|  |  |  |  |       ESP_LOGI(TAG, "WIFI antenna switch set to default %d", cfg.wifiant); | 
		
	
		
			
				|  |  |  |  |       saveConfig(); | 
		
	
		
			
				|  |  |  |  |     } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |     if (nvs_get_i8(my_handle, "vendorfilter", &flash8) == ESP_OK) { | 
		
	
		
			
				|  |  |  |  |       cfg.vendorfilter = flash8; | 
		
	
		
			
				|  |  |  |  |       ESP_LOGI(TAG, "vendorfilter = %d", flash8); | 
		
	
		
			
				|  |  |  |  |     } else { | 
		
	
		
			
				|  |  |  |  |       ESP_LOGI(TAG, "Vendorfilter mode set to default %d", cfg.vendorfilter); | 
		
	
		
			
				|  |  |  |  |       saveConfig(); | 
		
	
		
			
				|  |  |  |  |     } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |     if (nvs_get_i8(my_handle, "rgblum", &flash8) == ESP_OK) { | 
		
	
		
			
				|  |  |  |  |       cfg.rgblum = flash8; | 
		
	
		
			
				|  |  |  |  |       ESP_LOGI(TAG, "rgbluminosity = %d", flash8); | 
		
	
		
			
				|  |  |  |  |     } else { | 
		
	
		
			
				|  |  |  |  |       ESP_LOGI(TAG, "RGB luminosity set to default %d", cfg.rgblum); | 
		
	
		
			
				|  |  |  |  |       saveConfig(); | 
		
	
		
			
				|  |  |  |  |     } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |     if (nvs_get_i8(my_handle, "blescantime", &flash8) == ESP_OK) { | 
		
	
		
			
				|  |  |  |  |       cfg.blescantime = flash8; | 
		
	
		
			
				|  |  |  |  |       ESP_LOGI(TAG, "blescantime = %d", flash8); | 
		
	
		
			
				|  |  |  |  |     } else { | 
		
	
		
			
				|  |  |  |  |       ESP_LOGI(TAG, "BLEscantime set to default %d", cfg.blescantime); | 
		
	
		
			
				|  |  |  |  |       saveConfig(); | 
		
	
		
			
				|  |  |  |  |     } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |     if (nvs_get_i8(my_handle, "blescanmode", &flash8) == ESP_OK) { | 
		
	
		
			
				|  |  |  |  |       cfg.blescan = flash8; | 
		
	
		
			
				|  |  |  |  |       ESP_LOGI(TAG, "BLEscanmode = %d", flash8); | 
		
	
		
			
				|  |  |  |  |     } else { | 
		
	
		
			
				|  |  |  |  |       ESP_LOGI(TAG, "BLEscanmode set to default %d", cfg.blescan); | 
		
	
		
			
				|  |  |  |  |       saveConfig(); | 
		
	
		
			
				|  |  |  |  |     } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |     if (nvs_get_i8(my_handle, "wifiscanmode", &flash8) == ESP_OK) { | 
		
	
		
			
				|  |  |  |  |       cfg.wifiscan = flash8; | 
		
	
		
			
				|  |  |  |  |       ESP_LOGI(TAG, "WIFIscanmode = %d", flash8); | 
		
	
		
			
				|  |  |  |  |     } else { | 
		
	
		
			
				|  |  |  |  |       ESP_LOGI(TAG, "WIFIscanmode set to default %d", cfg.wifiscan); | 
		
	
		
			
				|  |  |  |  |       saveConfig(); | 
		
	
		
			
				|  |  |  |  |     } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |     if (nvs_get_i16(my_handle, "rssilimit", &flash16) == ESP_OK) { | 
		
	
		
			
				|  |  |  |  |       cfg.rssilimit = flash16; | 
		
	
		
			
				|  |  |  |  |       ESP_LOGI(TAG, "rssilimit = %d", flash16); | 
		
	
		
			
				|  |  |  |  |     } else { | 
		
	
		
			
				|  |  |  |  |       ESP_LOGI(TAG, "rssilimit set to default %d", cfg.rssilimit); | 
		
	
		
			
				|  |  |  |  |       saveConfig(); | 
		
	
		
			
				|  |  |  |  |     } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |     if (nvs_get_i8(my_handle, "payloadmask", &flash8) == ESP_OK) { | 
		
	
		
			
				|  |  |  |  |       cfg.payloadmask = flash8; | 
		
	
		
			
				|  |  |  |  |       ESP_LOGI(TAG, "payloadmask = %hhu", flash8); | 
		
	
		
			
				|  |  |  |  |     } else { | 
		
	
		
			
				|  |  |  |  |       ESP_LOGI(TAG, "payloadmask set to default %hhu", cfg.payloadmask); | 
		
	
		
			
				|  |  |  |  |       saveConfig(); | 
		
	
		
			
				|  |  |  |  |     } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |     if (nvs_get_i8(my_handle, "monitormode", &flash8) == ESP_OK) { | 
		
	
		
			
				|  |  |  |  |       cfg.monitormode = flash8; | 
		
	
		
			
				|  |  |  |  |       ESP_LOGI(TAG, "Monitor mode = %d", flash8); | 
		
	
		
			
				|  |  |  |  |     } else { | 
		
	
		
			
				|  |  |  |  |       ESP_LOGI(TAG, "Monitor mode set to default %d", cfg.monitormode); | 
		
	
		
			
				|  |  |  |  |       saveConfig(); | 
		
	
		
			
				|  |  |  |  |     } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |     nvs_close(my_handle); | 
		
	
		
			
				|  |  |  |  |     ESP_LOGI(TAG, "Done"); | 
		
	
		
			
				|  |  |  |  |   } | 
		
	
		
			
				|  |  |  |  | } // loadConfig()
 | 
		
	
	
		
			
				
					
					| 
							
							
							
						 |  |  | 
 |