diff --git a/Firmware/CustomHandlers.cpp b/Firmware/CustomHandlers.cpp
index 8b008a6..e7f26a8 100644
--- a/Firmware/CustomHandlers.cpp
+++ b/Firmware/CustomHandlers.cpp
@@ -177,15 +177,7 @@ void HandleAPConfigPage() {
String ssid = wifiConfig.getSSID();
String pass = wifiConfig.getPassword();
String url = wifiConfig.getURL();
- //String ntp = wifiConfig.getNTPServerName();
- char _onref[6], _offref[6], _autoOff[6];
-
- snprintf(_onref, sizeof(_onref), "%d", wifiConfig.getOnRef());
- snprintf(_offref, sizeof(_offref), "%d", wifiConfig.getOffRef());
- snprintf(_autoOff, sizeof(_autoOff), "%d", wifiConfig.getAutoOff());
- String onref = String(_onref);
- String offref = String(_offref);
- String autooff = String(_autoOff);
+ String ntp = wifiConfig.getNTPServerName();
if (server.hasArg("ssid") && server.hasArg("pass")) {
String _ssid = server.hasArg("_ssid") ? server.arg("_ssid") : "";
@@ -194,10 +186,7 @@ void HandleAPConfigPage() {
ssid = server.arg("ssid");
pass = server.arg("pass");
url = server.hasArg("url") ? server.arg("url") : "";
- onref = server.hasArg("onref") ? server.arg("onref") : "";
- offref = server.hasArg("offref") ? server.arg("offref") : "";
- autooff = server.hasArg("autooff") ? server.arg("autooff") : "";
- //ntp = server.hasArg("ntp") ? server.arg("ntp") : "";
+ ntp = server.hasArg("ntp") ? server.arg("ntp") : "";
if (ssid == "reset" && pass == "reset") {
FactoryReset(true);
}
@@ -205,10 +194,7 @@ void HandleAPConfigPage() {
wifiConfig.setSSID(ssid);
wifiConfig.setPassword(pass);
wifiConfig.setURL(url);
- wifiConfig.setOnRef(onref.toInt());
- wifiConfig.setOffRef(offref.toInt());
- wifiConfig.setAutoOff(autooff.toInt());
- //wifiConfig.setNTPServerName(ntp);
+ wifiConfig.setNTPServerName(ntp);
wifiConfig.save();
Serial.println("Settings saved.");
if (ssid != _ssid || pass != _pass) {
@@ -262,18 +248,6 @@ void HandleAPConfigPage() {
// "
\n"
" | | \n"
" \n"
diff --git a/Firmware/DNSServer.cpp b/Firmware/DNSServer.cpp
new file mode 100644
index 0000000..d8b00ae
--- /dev/null
+++ b/Firmware/DNSServer.cpp
@@ -0,0 +1,146 @@
+#include "./DNSServer.h"
+#include
+#include
+
+//#define DEBUG
+#define DEBUG_OUTPUT Serial
+
+DNSServer::DNSServer() {
+ _ttl = htonl(60);
+ _errorReplyCode = DNSReplyCode::NonExistentDomain;
+}
+
+bool DNSServer::start(const uint16_t &port, const String &domainName,
+ const IPAddress &resolvedIP) {
+ _port = port;
+ _domainName = domainName;
+ _resolvedIP[0] = resolvedIP[0];
+ _resolvedIP[1] = resolvedIP[1];
+ _resolvedIP[2] = resolvedIP[2];
+ _resolvedIP[3] = resolvedIP[3];
+ downcaseAndRemoveWwwPrefix(_domainName);
+ return _udp.begin(_port) == 1;
+}
+
+void DNSServer::setErrorReplyCode(const DNSReplyCode &replyCode) {
+ _errorReplyCode = replyCode;
+}
+
+void DNSServer::setTTL(const uint32_t &ttl) {
+ _ttl = htonl(ttl);
+}
+
+void DNSServer::stop() {
+ _udp.stop();
+}
+
+void DNSServer::downcaseAndRemoveWwwPrefix(String &domainName) {
+ domainName.toLowerCase();
+ domainName.replace("www.", "");
+}
+
+void DNSServer::processNextRequest() {
+ _currentPacketSize = _udp.parsePacket();
+ if (_currentPacketSize) {
+ _buffer = (unsigned char*) malloc(_currentPacketSize * sizeof(char));
+ if (_buffer == NULL) {
+ Serial.printf("ERROR in %s line %d\n", __FILE__, __LINE__);
+ } else {
+ _udp.read(_buffer, _currentPacketSize);
+ _dnsHeader = (DNSHeader*) _buffer;
+
+ if (_dnsHeader->QR == DNS_QR_QUERY &&
+ _dnsHeader->OPCode == DNS_OPCODE_QUERY &&
+ requestIncludesOnlyOneQuestion() &&
+ (_domainName == "*" || getDomainNameWithoutWwwPrefix() == _domainName)
+ ) {
+ replyWithIP();
+ } else if (_dnsHeader->QR == DNS_QR_QUERY) {
+ replyWithCustomCode();
+ }
+ }
+ free(_buffer);
+ }
+}
+
+bool DNSServer::requestIncludesOnlyOneQuestion() {
+ return ntohs(_dnsHeader->QDCount) == 1 &&
+ _dnsHeader->ANCount == 0 &&
+ _dnsHeader->NSCount == 0 &&
+ _dnsHeader->ARCount == 0;
+}
+
+String DNSServer::getDomainNameWithoutWwwPrefix() {
+ String parsedDomainName = "";
+ unsigned char *start = _buffer + 12;
+ if (*start == 0) {
+ return parsedDomainName;
+ }
+ int pos = 0;
+ while (true) {
+ unsigned char labelLength = *(start + pos);
+ for (int i = 0; i < labelLength; i++) {
+ pos++;
+ parsedDomainName += (char)*(start + pos);
+ }
+ pos++;
+ if (*(start + pos) == 0) {
+ downcaseAndRemoveWwwPrefix(parsedDomainName);
+ return parsedDomainName;
+ } else {
+ parsedDomainName += ".";
+ }
+ }
+}
+
+void DNSServer::replyWithIP() {
+ _dnsHeader->QR = DNS_QR_RESPONSE;
+ _dnsHeader->ANCount = _dnsHeader->QDCount;
+ _dnsHeader->QDCount = _dnsHeader->QDCount;
+ //_dnsHeader->RA = 1;
+
+ _udp.beginPacket(_udp.remoteIP(), _udp.remotePort());
+ _udp.write(_buffer, _currentPacketSize);
+
+ _udp.write((uint8_t) 192); // answer name is a pointer
+ _udp.write((uint8_t) 12); // pointer to offset at 0x00c
+
+ _udp.write((uint8_t) 0); // 0x0001 answer is type A query (host address)
+ _udp.write((uint8_t) 1);
+
+ _udp.write((uint8_t) 0); //0x0001 answer is class IN (internet address)
+ _udp.write((uint8_t) 1);
+
+ _udp.write((unsigned char*) &_ttl, 4);
+
+ // Length of RData is 4 bytes (because, in this case, RData is IPv4)
+ _udp.write((uint8_t) 0);
+ _udp.write((uint8_t) 4);
+ _udp.write(_resolvedIP, sizeof(_resolvedIP));
+ _udp.endPacket();
+
+
+
+ #ifdef DEBUG
+ DEBUG_OUTPUT.print("DNS responds: ");
+ DEBUG_OUTPUT.print(_resolvedIP[0]);
+ DEBUG_OUTPUT.print(".");
+ DEBUG_OUTPUT.print(_resolvedIP[1]);
+ DEBUG_OUTPUT.print(".");
+ DEBUG_OUTPUT.print(_resolvedIP[2]);
+ DEBUG_OUTPUT.print(".");
+ DEBUG_OUTPUT.print(_resolvedIP[3]);
+ DEBUG_OUTPUT.print(" for ");
+ DEBUG_OUTPUT.println(getDomainNameWithoutWwwPrefix());
+ #endif
+}
+
+void DNSServer::replyWithCustomCode() {
+ _dnsHeader->QR = DNS_QR_RESPONSE;
+ _dnsHeader->RCode = (unsigned char) _errorReplyCode;
+ _dnsHeader->QDCount = 0;
+
+ _udp.beginPacket(_udp.remoteIP(), _udp.remotePort());
+ _udp.write(_buffer, sizeof(DNSHeader));
+ _udp.endPacket();
+}
diff --git a/Firmware/DNSServer.h b/Firmware/DNSServer.h
new file mode 100644
index 0000000..691fec6
--- /dev/null
+++ b/Firmware/DNSServer.h
@@ -0,0 +1,68 @@
+#ifndef DNSServer_h
+#define DNSServer_h
+#include
+
+#define DNS_QR_QUERY 0
+#define DNS_QR_RESPONSE 1
+#define DNS_OPCODE_QUERY 0
+
+enum class DNSReplyCode {
+ NoError = 0,
+ FormError = 1,
+ ServerFailure = 2,
+ NonExistentDomain = 3,
+ NotImplemented = 4,
+ Refused = 5,
+ YXDomain = 6,
+ YXRRSet = 7,
+ NXRRSet = 8
+};
+
+struct DNSHeader {
+ uint16_t ID; // identification number
+ unsigned char RD : 1; // recursion desired
+ unsigned char TC : 1; // truncated message
+ unsigned char AA : 1; // authoritive answer
+ unsigned char OPCode : 4; // message_type
+ unsigned char QR : 1; // query/response flag
+ unsigned char RCode : 4; // response code
+ unsigned char Z : 3; // its z! reserved
+ unsigned char RA : 1; // recursion available
+ uint16_t QDCount; // number of question entries
+ uint16_t ANCount; // number of answer entries
+ uint16_t NSCount; // number of authority entries
+ uint16_t ARCount; // number of resource entries
+};
+
+class DNSServer {
+public:
+ DNSServer();
+ void processNextRequest();
+ void setErrorReplyCode(const DNSReplyCode &replyCode);
+ void setTTL(const uint32_t &ttl);
+
+ // Returns true if successful, false if there are no sockets available
+ bool start(const uint16_t &port,
+ const String &domainName,
+ const IPAddress &resolvedIP);
+ // stops the DNS server
+ void stop();
+
+private:
+ WiFiUDP _udp;
+ uint16_t _port;
+ String _domainName;
+ unsigned char _resolvedIP[4];
+ int _currentPacketSize;
+ unsigned char* _buffer;
+ DNSHeader* _dnsHeader;
+ uint32_t _ttl;
+ DNSReplyCode _errorReplyCode;
+
+ void downcaseAndRemoveWwwPrefix(String &domainName);
+ String getDomainNameWithoutWwwPrefix();
+ bool requestIncludesOnlyOneQuestion();
+ void replyWithIP();
+ void replyWithCustomCode();
+};
+#endif // DNSServer_h
diff --git a/Firmware/Firmware.ses b/Firmware/Firmware.ses
new file mode 100644
index 0000000..c4dfcc2
--- /dev/null
+++ b/Firmware/Firmware.ses
@@ -0,0 +1,34 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Firmware/GrowController.ses b/Firmware/GrowController.ses
deleted file mode 100644
index 3258f31..0000000
--- a/Firmware/GrowController.ses
+++ /dev/null
@@ -1,35 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/Firmware/PlantModel.cpp b/Firmware/PlantModel.cpp
index 02dc719..316acf8 100644
--- a/Firmware/PlantModel.cpp
+++ b/Firmware/PlantModel.cpp
@@ -161,7 +161,7 @@ void simulation() {
// Simulate Ambient temp rising and falling
if (lastMinutesToday != minutesToday) {
lastMinutesToday = minutesToday;
- Serial.printf("%02u:%02u, Ambient %3.1f\n", hoursToday, minutesToday % 60, plant.AmbientTemp_C);
+ //Serial.printf("%02u:%02u, Ambient %3.1f\n", hoursToday, minutesToday % 60, plant.AmbientTemp_C);
if (hoursToday < 15) {
// warming part of the day
diff --git a/Firmware/Utility.cpp b/Firmware/Utility.cpp
index 622c469..8973501 100644
--- a/Firmware/Utility.cpp
+++ b/Firmware/Utility.cpp
@@ -7,23 +7,51 @@
#include "Utility.h"
-static String macToStr(const uint8_t * mac);
+static String macToStr(const uint8_t * mac, char padd = ':');
-String GetMacString() {
+String GetMacString(char padd) {
unsigned char mac[6];
WiFi.macAddress(mac);
- String clientMac(macToStr(mac));
+ String clientMac(macToStr(mac, padd));
return clientMac;
}
-String macToStr(const uint8_t * mac) {
+static String macToStr(const uint8_t * mac, char padd) {
String result;
for (int i = 0; i < 6; ++i) {
result += String(mac[i], 16);
- if (i < 5)
- result += ':';
+ if (i < 5) {
+ if (padd)
+ result += padd;
+ }
}
return result;
}
+void HexDump(const char * title, const uint8_t * p, int count)
+{
+ int i;
+ char buf[100] = "0000: ";
+ char asc[17] = " ";
+
+ if (*title) {
+ printf("%s [@%08X]\n", title, (uint32_t)p);
+ }
+ for (i=0; i
// Returns the MAC Address as a string object
-String GetMacString();
+String GetMacString(char padd = ':');
+
+// Dump a block of memory as a hex title-named listing
+//
+void HexDump(const char * title, const uint8_t * p, int count);
+
+
+// A macro to generate a build error on the condition
+//
+// Example:
+// BUILD_BUG_ON(sizeof(something) > limit);
+//
+#define BUILD_BUG_ON(condition) ((void)sizeof(char[1 - 2*!!(condition)]))
+
+// And the more positive direction
+//
+// Example:
+// COMPILER_ASSERT(sizeof(something) <= limit);
+//
+#define COMPILER_ASSERT(condition) ((void)sizeof(char[-!(condition)]))
+
+#endif // UTILITY_H
diff --git a/Firmware/WiFiConfiguration.h b/Firmware/WiFiConfiguration.h
index 314ea26..546a1fa 100644
--- a/Firmware/WiFiConfiguration.h
+++ b/Firmware/WiFiConfiguration.h
@@ -9,16 +9,20 @@
#define CFG_NAMESIZE 32
#define CFG_SSIDSIZE 32
#define CFG_PASSSIZE 64
-#define CFG_UURLSIZE 64
+#define CFG_UPDURLSIZE 64
+#define CFG_NTPSSIZE 64
-/// Provides a handy interface for WiFi configuration.
+/// Provides a handy interface for WiFi configuration and user NV data.
+///
+/// Because the WiFi needs to have its configuration managed through
+/// non-volatile memory.
///
/// @code
/// WiFiConfiguration config;
/// ...
/// config.load();
-/// ssid = config.getSSID();
-/// pass = config.getPassword();
+/// String ssid = config.getSSID();
+/// String pass = config.getPassword();
/// ...
/// WiFi.begin(ssid.c_str(), pass.c_str());
///
@@ -26,29 +30,174 @@
///
class ConfigManager {
public:
- ConfigManager();
- void load();
- void save();
- void factoryReset();
- String getName();
- void setName(String _name);
- String getSSID();
- void setSSID(String _ssid);
- String getPassword();
- void setPassword(String _password);
- String getURL();
- void setURL(String _url);
- uint16_t getOnRef();
- void setOnRef(uint16 onR);
- uint16_t getOffRef();
- void setOffRef(uint16 offR);
- uint16_t getAutoOff();
- void setAutoOff(uint16 autoOff);
- #if 0
- String getNTPServerName();
- void setNTPServerName(String _name);
- #endif
+
+ /// Data structure that is used for 'factory reset' of this node,
+ /// where all setup data is erased. This reset state can include
+ /// specific settings, such as the device name (as it will appear
+ /// on the network, and the default software update server, and so on.
+ typedef struct {
+ const char * name; ///< the device name
+ const char * UPDURL; ///< the URL of a SW update server
+ const char * NTPURL; ///< The URL of an NTP server
+ } ConfigDefaults_t;
+
+ /// load checks the version of the image for validity.
+ ///
+ typedef enum {
+ MATCHING, ///< The current version matches the expected version
+ IS_OLDER, ///< [Newer firmware] detected an older configuration
+ IS_NEWER, ///< detected a configuration that is newer than this app knows.
+ IS_BROKEN, ///< format check failed, this image is bad.
+ } FirmwareCheck_t;
+
+ /// Instantiate the WiFi Configuration Manager, which also manages
+ /// user non-volatile storage.
+ ///
+ /// This creates a RAM cache (typically 512B), where information is
+ /// held. This is then saved to non-volatile (save), or overwritten
+ /// from non-volatile (load).
+ ///
+ /// Instantiation does not automatically load from non-volatile.
+ ///
+ /// @param[in] defaults is an optional pointer to the default information.
+ ///
+ ConfigManager(const ConfigDefaults_t * defaults = NULL);
+
+ /// Destructor, which is usually not used in an embedded system.
+ ///
+ ~ConfigManager();
+
+ /// loads the information from non-volatile storage into RAM
+ ///
+ /// @returns status of the firmware check. @see FirmwareCheck_t
+ ///
+ FirmwareCheck_t load();
+
+ /// get the current firmware version
+ ///
+ /// specific software may be able to upgrade (or even downgrade) the
+ /// non-volatile data storage format.
+ ///
+ /// @returns the format version number (only useful if load is not broken.
+ ///
+ uint8_t getFormatVersion();
+
+
+ /// saves the information to non-volatile.
+ ///
+ void save();
+
+ /// Resets the RAM information to factory defaults, completely wiping
+ /// all data, so it cannot be extracted.
+ ///
+ /// To complete the wipe, be sure to issue to the save command.
+ ///
+ void factoryReset();
+
+ /// get the name of this device, as it will appear on the network.
+ ///
+ /// @returns string of the name.
+ ///
+ String getName();
+
+ /// set the name of this device, to a maximum length of CFG_NAMESIZE.
+ ///
+ /// @param[in] _name is the name to assign it.
+ ///
+ void setName(String _name);
+
+ /// get the ssid that this node is assigned to.
+ ///
+ /// @returns the SSID, or a pointer to NULL if none set.
+ ///
+ String getSSID();
+
+ /// set the ssid that this node is assigned to.
+ ///
+ /// @param[in] _ssid to assign this device to, to a maximum length of CFG_SSIDSIZE
+ ///
+ void setSSID(String _ssid);
+
+ /// get the passcode that this node will use with the joined ssid.
+ ///
+ /// @returns the passcode.
+ ///
+ String getPassword();
+
+ /// set the passcode that this node uses.
+ ///
+ /// @param[in] passcode to assign this device to, to a maximum length of CFG_PASSSIZE
+ ///
+ void setPassword(String _password);
+
+ /// get the URL that this node will use for software updates
+ ///
+ /// @returns the url.
+ ///
+ String getURL();
+
+ /// set the URL that this node will use for software updates
+ ///
+ /// @param[in] _url to assign this device to, to a maximum length of CFG_UPDURLSIZE
+ ///
+ void setURL(String _url);
+
+ /// get the URL of the NTP server that this node will use for setting the clock
+ ///
+ /// @returns the url.
+ ///
+ String getNTPServerName();
+
+ /// set the URL of the NTP server that this node will use for software updates
+ ///
+ /// @param[in] _url to assign this device to, to a maximum length of CFG_NTPSSIZE
+ ///
+ void setNTPServerName(String _url);
+
+ /// get a pointer to the portion of the data that will be saved to non-volatile
+ ///
+ /// This points to the block of memory that is for user settings. The user code
+ /// will typically create a structure, and overlay it on this location.
+ ///
+ /// The size is fixed at compile time, but may be queried with getUserDataSize()
+ /// to ensure that there is no buffer overrun.
+ ///
+ /// @returns the pointer to the memory for the user to use.
+ ///
+ uint8_t * getUserDataHandle();
+
+ /// get the size of the user data block that can be saved to non-volatile.
+ ///
+ /// @returns the size (in bytes) of the user space.
+ ///
+ int getUserDataSize();
+
private:
+
+ #define EEROM_SIZE 512
+
+ // Change this when it is required to force a reinitialization
+ //
+ #define EXPECTED_FMT 0x04
+
+ #define SYSTEMSIZE (2 + CFG_NAMESIZE + CFG_SSIDSIZE + CFG_PASSSIZE + CFG_UPDURLSIZE + CFG_NTPSSIZE)
+ #define USERSIZE (EEROM_SIZE - SYSTEMSIZE)
+
+ typedef struct {
+ uint8_t format[2]; // Format of this data structure, and ~format check
+ struct info {
+ char name[CFG_NAMESIZE]; // Network Discoverable Name of this node
+ char ssid[CFG_SSIDSIZE]; // SSID of the saved network [max length defined by standard]
+ char pass[CFG_PASSSIZE]; // PASScode of the saved network
+ char UPDURL[CFG_UPDURLSIZE]; // URL of the trusted server with code updates
+ char NTPURL[CFG_NTPSSIZE]; // Name or IP of the NTP Server
+ } info;
+ uint8_t userData[USERSIZE]; // User data here and to the EEROM_SIZE end.
+ } NVConfig_04_t; // This layout matches EXPECTED_FMT == 04
+
+ NVConfig_04_t Configuration; // the instantiation of the Configuration
+
+ const ConfigDefaults_t * defaults;
};
#endif // !WIFICONFIGURATION_H
diff --git a/Firmware/WifiConfiguration.cpp b/Firmware/WifiConfiguration.cpp
index 384824c..0cde2fa 100644
--- a/Firmware/WifiConfiguration.cpp
+++ b/Firmware/WifiConfiguration.cpp
@@ -1,156 +1,162 @@
//
// This file hosts all the non-volatile configuration options for this node
//
-#include "WiFiConfiguration.h"
#include
-#define EEROM_SIZE 512
+#include "WiFiConfiguration.h"
+#include "Utility.h"
-// Change this when it is required to force a reinitialization
-//
-#define EXPECTED_FMT 0x03
-
-typedef struct {
- uint8_t format[2]; // Format of this data structure, and ~format
- struct info {
- char name[CFG_NAMESIZE]; // Network Discoverable Name of this node
- char ssid[CFG_SSIDSIZE]; // SSID of the saved network [max length defined by standard]
- char pass[CFG_PASSSIZE]; // PASScode of the saved network
- char updateURL[CFG_UURLSIZE]; // URL of the trusted server with code updates
- uint16_t onRef; // A/D reference above which the output is considered 'On'
- uint16_t offRef; // A/D reference below which the output is considered 'Off'
- uint16_t autoOff; // When non-zero, this is the # minutes until auto-turn off
- //char NTPIP[64]; // Name or IP of the NTP Server
- char Padding[10];
- } info;
-} Config_t;
-#define OFS_FORMAT (0)
-#define OFS_NAME (OFS_FORMAT + 2)
-#define OFS_SSID (OFS_NAME + CFG_NAMESIZE)
-#define OFS_PASS (OFS_SSID + CFG_SSIDSIZE)
-#define OFS_URL (OFS_PASS + CFG_PASSSIZE)
-#define OFS_ONREF (OFS_URL + CFG_UURLSIZE)
-#define OFS_OFFREF (OFS_ONREF + sizeof(uint16_t))
-#define OFS_AUTOOFF (OFS_OFFREF + sizeof(uint16_t))
-//#define OFS_NTPIP (OFS_OFFREF + 2)
-
-Config_t Configuration;
-
-ConfigManager::ConfigManager() {
+ConfigManager::ConfigManager(const ConfigDefaults_t * _defaults) {
+ (void)_defaults;
+// defaults = _defaults;
+ COMPILER_ASSERT(sizeof(NVConfig_04_t) <= EEROM_SIZE);
+ EEPROM.begin(EEROM_SIZE); // Set for the max expected size
+ // Here we could perform a 'load()' followed by a format check,
+ // and it could then do a graceful update from one version to another,
+ // and then commit it back to the rest of the program doesn't notice.
+ int ret = load();
+ switch (ret) {
+ case MATCHING:
+ // life is good, continue.
+ break;
+ case IS_OLDER:
+ //if (getFormatVersion() == 3) {
+ // Upgrade();
+ // save();
+ //} else {
+ // factoryReset();
+ // save();
+ //}
+ break;
+ case IS_NEWER:
+ // can't politely downgrade, so factory reset it.
+ case IS_BROKEN:
+ default:
+// factoryReset(); // Can't fix it, so factory reset it.
+// save();
+ break;
+ }
}
+// Quite likely that this never runs...
+ConfigManager::~ConfigManager() {
+ EEPROM.end();
+}
+
+
+uint8_t ConfigManager::getFormatVersion() {
+ return Configuration.format[0];
+}
+
+uint8_t * ConfigManager::getUserDataHandle() {
+ return Configuration.userData;
+}
+
+int ConfigManager::getUserDataSize() {
+ return USERSIZE;
+}
+
+
void ConfigManager::factoryReset() {
- Configuration.format[0] = EXPECTED_FMT;
- Configuration.format[1] = ~EXPECTED_FMT;
- strcpy(Configuration.info.name, "3-Way Switch");
- Configuration.info.ssid[0] = '\0';
- Configuration.info.pass[0] = '\0';
- //Configuration.info.updateURL[0] = '\0';
- strcpy(Configuration.info.updateURL, "https://192.168.1.201/mbed/ESP.php");
- Configuration.info.onRef = 150;
- Configuration.info.offRef = 100;
- Configuration.info.autoOff = 0;
- //Configuration.info.NTPIP[0] = '\0';
+ memset(&Configuration, 0, sizeof(NVConfig_04_t)); // Wipe them to be more secure
+ Configuration.format[0] = EXPECTED_FMT; // put back the minimal
+ Configuration.format[1] = ~EXPECTED_FMT;
+ if (defaults) {
+ strcpy(Configuration.info.name, defaults->name);
+ strcpy(Configuration.info.UPDURL, defaults->UPDURL);
+ strcpy(Configuration.info.NTPURL, defaults->NTPURL);
+ }
+ HexDump("factoryReset", (uint8_t *)&Configuration, sizeof(Configuration));
}
-void ConfigManager::load() {
- EEPROM.begin(512);
- uint8_t * ptr = (uint8_t *) &Configuration;
- uint8_t i = 0;
- do {
- *ptr++ = EEPROM.read(OFS_FORMAT + i++);
- } while (i < sizeof(Configuration));
- if ((Configuration.format[0] & 0xFF) != (~Configuration.format[1] & 0xFF)) {
- // Factory default
- Serial.printf("Bad Configuration - reset to factory defaults\n");
- factoryReset();
- return;
- }
- Serial.printf("Loading from EEROM\n");
- Serial.printf("Node Name: %s\n", Configuration.info.name);
- Serial.printf("SSID: %s\n", Configuration.info.ssid);
- Serial.printf("PASS: %s\n", Configuration.info.pass);
- Serial.printf("URL : %s\n", Configuration.info.updateURL);
- Serial.printf("On Ref: %d\n", Configuration.info.onRef);
- Serial.printf("Off Ref: %d\n", Configuration.info.offRef);
- Serial.printf("Auto Off: %d\n", Configuration.info.autoOff);
- //Serial.printf("NTP Svr: %s\n", Configuration.info.NTPIP);
- delay(500);
+
+ConfigManager::FirmwareCheck_t ConfigManager::load() {
+ uint8_t * ptr = (uint8_t *)&Configuration;
+ size_t i = 0;
+ do {
+ *ptr++ = EEPROM.read(i++);
+ } while (i < sizeof(Configuration));
+// if ((Configuration.format[0] & 0xFF) != (~Configuration.format[1] & 0xFF)) {
+// // Factory default
+// Serial.printf("Bad Configuration\n");
+// return IS_BROKEN; // Fatal and restored to factory default.
+// } else if (Configuration.format[0] < EXPECTED_FMT) {
+// Serial.printf("Old Configuration. It needs an update!\n");
+// return IS_OLDER;
+// } else if (Configuration.format[0] > EXPECTED_FMT) {
+// Serial.printf("Too new a configuration.\n");
+// return IS_NEWER;
+// }
+ Serial.printf("Loading from EEROM\n");
+ Serial.printf("Node Name: %s\n", Configuration.info.name);
+ Serial.printf("SSID: %s\n", Configuration.info.ssid);
+ Serial.printf("PASS: %s\n", Configuration.info.pass);
+ Serial.printf("URL : %s\n", Configuration.info.UPDURL);
+ Serial.printf("NTP : %s\n", Configuration.info.NTPURL);
+ HexDump("After Load", (uint8_t *)&Configuration, sizeof(Configuration));
+// //delay(500);
+ return MATCHING; // no error
}
+
void ConfigManager::save(void) {
- EEPROM.begin(512);
- uint8_t * ptr = (uint8_t *) &Configuration;
- uint8_t i = 0;
- do {
- EEPROM.write(OFS_FORMAT + i++, *ptr++);
- } while (i < sizeof(Configuration));
- EEPROM.commit();
- delay(500);
+ uint8_t * ptr = (uint8_t *)&Configuration;
+ size_t i = 0;
+ do {
+ EEPROM.write(i++, *ptr++);
+ } while (i < sizeof(Configuration));
+ if (EEPROM.commit()) {
+ Serial.printf("EEPROM.commit() success.\n");
+ } else {
+ Serial.printf("EEPROM.commit() FAILED !!!!!!!! FAILED !!!!!!!! FAILED !!!!!!!!\n");
+ }
+ HexDump("After Save", (uint8_t *)&Configuration, sizeof(Configuration));
+ //delay(500);
}
-#if 0
+
String ConfigManager::getNTPServerName() {
- return String(Configuration.info.NTPIP);
+ return String(Configuration.info.NTPURL);
}
void ConfigManager::setNTPServerName(String _name) {
- strncpy(Configuration.info.NTPIP, _name.c_str(), sizeof(Configuration.info.NTPIP));
- Serial.printf("setNTPServerName(%s)\n", Configuration.info.NTPIP);
+ strncpy(Configuration.info.NTPURL, _name.c_str(), sizeof(Configuration.info.NTPURL));
+ Serial.printf("setNTPServerName(%s)\n", Configuration.info.NTPURL);
}
-#endif
String ConfigManager::getName() {
- return String(Configuration.info.name);
+ return String(Configuration.info.name);
}
void ConfigManager::setName(String _name) {
- strncpy(Configuration.info.name, _name.c_str(), sizeof(Configuration.info.name));
- Serial.printf("setName(%s)\n", Configuration.info.name);
+ strncpy(Configuration.info.name, _name.c_str(), sizeof(Configuration.info.name));
+ Serial.printf("setName(%s)\n", Configuration.info.name);
}
String ConfigManager::getSSID() {
- return String(Configuration.info.ssid);
+ return String(Configuration.info.ssid);
}
void ConfigManager::setSSID(String _ssid) {
- strncpy(Configuration.info.ssid, _ssid.c_str(), sizeof(Configuration.info.ssid));
- Serial.printf("setSSID(%s)\n", Configuration.info.ssid);
+ strncpy(Configuration.info.ssid, _ssid.c_str(), sizeof(Configuration.info.ssid));
+ Serial.printf("setSSID(%s)\n", Configuration.info.ssid);
}
String ConfigManager::getPassword() {
- return String(Configuration.info.pass);
+ return String(Configuration.info.pass);
}
void ConfigManager::setPassword(String _password) {
- strncpy(Configuration.info.pass, _password.c_str(), sizeof(Configuration.info.pass));
- Serial.printf("setPass(%s)\n", Configuration.info.pass);
+ strncpy(Configuration.info.pass, _password.c_str(), sizeof(Configuration.info.pass));
+ Serial.printf("setPass(%s)\n", Configuration.info.pass);
}
String ConfigManager::getURL() {
- return String(Configuration.info.updateURL);
+ return String(Configuration.info.UPDURL);
}
void ConfigManager::setURL(String _url) {
- strncpy(Configuration.info.updateURL, _url.c_str(), sizeof(Configuration.info.updateURL));
- Serial.printf("setURL (%s)\n", Configuration.info.updateURL);
+ strncpy(Configuration.info.UPDURL, _url.c_str(), sizeof(Configuration.info.UPDURL));
+ Serial.printf("setURL (%s)\n", Configuration.info.UPDURL);
}
-uint16_t ConfigManager::getOnRef() {
- return Configuration.info.onRef;
-}
-void ConfigManager::setOnRef(uint16 onR) {
- Configuration.info.onRef = onR;
-}
-uint16_t ConfigManager::getOffRef() {
- return Configuration.info.offRef;
-}
-void ConfigManager::setOffRef(uint16 offR) {
- Configuration.info.offRef = offR;
-}
-uint16_t ConfigManager::getAutoOff() {
- return Configuration.info.autoOff;
-}
-void ConfigManager::setAutoOff(uint16 autoOff) {
- Configuration.info.autoOff = autoOff;
-}
|