parent
							
								
									e617b4f283
								
							
						
					
					
						commit
						509b19a9bc
					
				@ -0,0 +1,192 @@ | 
				
			|||||||
 | 
					//
 | 
				
			||||||
 | 
					// Created by MightyPork on 2017/07/09.
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "persist.h" | 
				
			||||||
 | 
					#include <esp8266.h> | 
				
			||||||
 | 
					#include "wifimgr.h" | 
				
			||||||
 | 
					#include "screen.h" | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					FullPersistBlock persist; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define PERSIST_SECTOR_ID 0x3D | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//region Persist and restore individual modules
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Load persistent settings to live config structs | 
				
			||||||
 | 
					 */ | 
				
			||||||
 | 
					static void ICACHE_FLASH_ATTR | 
				
			||||||
 | 
					load_settings_to_live(void) | 
				
			||||||
 | 
					{ | 
				
			||||||
 | 
						dbg("[Persist] Loading current settings to modules..."); | 
				
			||||||
 | 
						memcpy(&wificonf, &persist.current.wificonf, sizeof(WiFiConfigBlock)); | 
				
			||||||
 | 
						memcpy(&termconf, &persist.current.termconf, sizeof(TerminalConfigBlock)); | 
				
			||||||
 | 
						// ...
 | 
				
			||||||
 | 
					} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void ICACHE_FLASH_ATTR | 
				
			||||||
 | 
					store_settings_from_live(void) | 
				
			||||||
 | 
					{ | 
				
			||||||
 | 
						dbg("[Persist] Collecting live settings to persist block..."); | 
				
			||||||
 | 
						memcpy(&persist.current.wificonf, &wificonf, sizeof(wificonf)); | 
				
			||||||
 | 
						memcpy(&persist.current.termconf, &termconf, sizeof(termconf)); | 
				
			||||||
 | 
						// ...
 | 
				
			||||||
 | 
					} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void ICACHE_FLASH_ATTR | 
				
			||||||
 | 
					apply_live_settings(void) | 
				
			||||||
 | 
					{ | 
				
			||||||
 | 
						dbg("[Persist] Applying live settings..."); | 
				
			||||||
 | 
						terminal_apply_settings(); | 
				
			||||||
 | 
						wifimgr_apply_settings(); | 
				
			||||||
 | 
						// ...
 | 
				
			||||||
 | 
					} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void ICACHE_FLASH_ATTR | 
				
			||||||
 | 
					restore_live_settings_to_hard_defaults(void) | 
				
			||||||
 | 
					{ | 
				
			||||||
 | 
						wifimgr_restore_defaults(); | 
				
			||||||
 | 
						terminal_restore_defaults(); | 
				
			||||||
 | 
						// ...
 | 
				
			||||||
 | 
					} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//endregion
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Compute CRC32. Adapted from https://github.com/esp8266/Arduino
 | 
				
			||||||
 | 
					 * @param data | 
				
			||||||
 | 
					 * @param length | 
				
			||||||
 | 
					 * @return crc32 | 
				
			||||||
 | 
					 */ | 
				
			||||||
 | 
					static uint32_t ICACHE_FLASH_ATTR | 
				
			||||||
 | 
					calculateCRC32(const uint8_t *data, size_t length) | 
				
			||||||
 | 
					{ | 
				
			||||||
 | 
						uint32_t crc = 0xffffffff; | 
				
			||||||
 | 
						while (length--) { | 
				
			||||||
 | 
							uint8_t c = *data++; | 
				
			||||||
 | 
							for (uint32_t i = 0x80; i > 0; i >>= 1) { | 
				
			||||||
 | 
								bool bit = (bool) (crc & 0x80000000UL); | 
				
			||||||
 | 
								if (c & i) { | 
				
			||||||
 | 
									bit = !bit; | 
				
			||||||
 | 
								} | 
				
			||||||
 | 
								crc <<= 1; | 
				
			||||||
 | 
								if (bit) { | 
				
			||||||
 | 
									crc ^= 0x04c11db7UL; | 
				
			||||||
 | 
								} | 
				
			||||||
 | 
							} | 
				
			||||||
 | 
						} | 
				
			||||||
 | 
						return crc; | 
				
			||||||
 | 
					} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Compute a persist bundle checksum | 
				
			||||||
 | 
					 * | 
				
			||||||
 | 
					 * @param bundle | 
				
			||||||
 | 
					 * @return | 
				
			||||||
 | 
					 */ | 
				
			||||||
 | 
					static uint32_t ICACHE_FLASH_ATTR | 
				
			||||||
 | 
					compute_checksum(PersistBundle *bundle) | 
				
			||||||
 | 
					{ | 
				
			||||||
 | 
						return calculateCRC32((uint8_t *) bundle, sizeof(PersistBundle) - 4); | 
				
			||||||
 | 
					} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Load, verify and apply persistent config | 
				
			||||||
 | 
					 */ | 
				
			||||||
 | 
					void ICACHE_FLASH_ATTR | 
				
			||||||
 | 
					persist_load(void) | 
				
			||||||
 | 
					{ | 
				
			||||||
 | 
						info("[Persist] Loading stored settings from FLASH..."); | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						bool hard_reset = false; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Try to load
 | 
				
			||||||
 | 
						hard_reset |= !system_param_load(PERSIST_SECTOR_ID, 0, &persist, sizeof(persist)); | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Verify checksums
 | 
				
			||||||
 | 
						if (hard_reset || | 
				
			||||||
 | 
							(compute_checksum(&persist.defaults) != persist.defaults.checksum) || | 
				
			||||||
 | 
							(compute_checksum(&persist.current) != persist.current.checksum)) { | 
				
			||||||
 | 
							error("[Persist] Config block failed to load, restoring to hard defaults."); | 
				
			||||||
 | 
							hard_reset = true; | 
				
			||||||
 | 
						} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (hard_reset) { | 
				
			||||||
 | 
							persist_restore_hard_default(); | 
				
			||||||
 | 
							// this also stores them to flash and applies to modues
 | 
				
			||||||
 | 
						} else { | 
				
			||||||
 | 
							load_settings_to_live(); | 
				
			||||||
 | 
							apply_live_settings(); | 
				
			||||||
 | 
						} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						info("[Persist] All settings loaded and applied."); | 
				
			||||||
 | 
					} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void ICACHE_FLASH_ATTR | 
				
			||||||
 | 
					persist_store(void) | 
				
			||||||
 | 
					{ | 
				
			||||||
 | 
						info("[Persist] Storing all settings to FLASH..."); | 
				
			||||||
 | 
						store_settings_from_live(); | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Update checksums before write
 | 
				
			||||||
 | 
						persist.current.checksum = compute_checksum(&persist.current); | 
				
			||||||
 | 
						persist.defaults.checksum = compute_checksum(&persist.defaults); | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (!system_param_save_with_protect(PERSIST_SECTOR_ID, &persist, sizeof(persist))) { | 
				
			||||||
 | 
							error("[Persist] Store to flash failed!"); | 
				
			||||||
 | 
						} | 
				
			||||||
 | 
						info("[Persist] All settings persisted."); | 
				
			||||||
 | 
					} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Restore to built-in defaults | 
				
			||||||
 | 
					 */ | 
				
			||||||
 | 
					void ICACHE_FLASH_ATTR | 
				
			||||||
 | 
					persist_restore_hard_default(void) | 
				
			||||||
 | 
					{ | 
				
			||||||
 | 
						info("[Persist] Restoring all settings to hard defaults..."); | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Set live config to default values
 | 
				
			||||||
 | 
						restore_live_settings_to_hard_defaults(); | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Store live -> current
 | 
				
			||||||
 | 
						store_settings_from_live(); | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Store current -> default
 | 
				
			||||||
 | 
						memcpy(&persist.defaults, &persist.current, sizeof(persist.current)); | 
				
			||||||
 | 
						persist_store(); | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						info("[Persist] All settings restored to hard defaults."); | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						apply_live_settings(); // apply
 | 
				
			||||||
 | 
					} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Restore default settings & apply | 
				
			||||||
 | 
					 */ | 
				
			||||||
 | 
					void ICACHE_FLASH_ATTR | 
				
			||||||
 | 
					persist_restore_default(void) | 
				
			||||||
 | 
					{ | 
				
			||||||
 | 
						info("[Persist] Restoring live settings to stored defaults..."); | 
				
			||||||
 | 
						memcpy(&persist.current, &persist.defaults, sizeof(persist.defaults)); | 
				
			||||||
 | 
						load_settings_to_live(); | 
				
			||||||
 | 
						apply_live_settings(); | 
				
			||||||
 | 
						info("[Persist] Settings restored to stored defaults."); | 
				
			||||||
 | 
					} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Store current settings as defaults & write to flash | 
				
			||||||
 | 
					 */ | 
				
			||||||
 | 
					void ICACHE_FLASH_ATTR | 
				
			||||||
 | 
					persist_set_as_default(void) | 
				
			||||||
 | 
					{ | 
				
			||||||
 | 
						info("[Persist] Storing live settings as defaults.."); | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						store_settings_from_live(); | 
				
			||||||
 | 
						memcpy(&persist.defaults, &persist.current, sizeof(persist.current)); | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						persist_store(); | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						info("[Persist] Default settings updated."); | 
				
			||||||
 | 
					} | 
				
			||||||
@ -0,0 +1,39 @@ | 
				
			|||||||
 | 
					//
 | 
				
			||||||
 | 
					// Created by MightyPork on 2017/07/09.
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// There are 4 sets of settings.
 | 
				
			||||||
 | 
					// - hard defaults - hardcoded in firmware, used for init defaults after flash or if stored data are corrupt
 | 
				
			||||||
 | 
					// - defaults - persisted by privileged user
 | 
				
			||||||
 | 
					// - current - persistent current config state, can be restored to defaults any time
 | 
				
			||||||
 | 
					// - live - non-persistent settings valid only for the current runtime
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifndef ESP_VT100_FIRMWARE_PERSIST_H | 
				
			||||||
 | 
					#define ESP_VT100_FIRMWARE_PERSIST_H | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "wifimgr.h" | 
				
			||||||
 | 
					#include "screen.h" | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					typedef struct { | 
				
			||||||
 | 
						WiFiConfigBlock wificonf; | 
				
			||||||
 | 
						TerminalConfigBlock termconf; | 
				
			||||||
 | 
						// ...
 | 
				
			||||||
 | 
						// other settings here
 | 
				
			||||||
 | 
						// ...
 | 
				
			||||||
 | 
						uint32_t checksum; // computed before write and tested on load. If it doesn't match, values are reset to hard defaults.
 | 
				
			||||||
 | 
					} PersistBundle; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					typedef struct { | 
				
			||||||
 | 
						PersistBundle defaults; // defaults are stored here
 | 
				
			||||||
 | 
						PersistBundle current;  // settings persisted by user
 | 
				
			||||||
 | 
					} FullPersistBlock; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Persist holds the data currently loaded from the flash
 | 
				
			||||||
 | 
					extern FullPersistBlock persist; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void persist_load(void); | 
				
			||||||
 | 
					void persist_restore_hard_default(void); | 
				
			||||||
 | 
					void persist_restore_default(void); | 
				
			||||||
 | 
					void persist_set_as_default(void); | 
				
			||||||
 | 
					void persist_store(void); | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif //ESP_VT100_FIRMWARE_PERSIST_H
 | 
				
			||||||
					Loading…
					
					
				
		Reference in new issue