Remove stuff that came from a different app when this was derived.

Prepare to add DNSServer for captive portal.
This commit is contained in:
David
2021-11-02 14:46:37 +00:00
parent 4597350845
commit a0825b629e
10 changed files with 602 additions and 208 deletions

View File

@@ -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() {
// " <td>NTP Server</td>\n"
// " <td><input type=\"text\" size=\"64\" name=\"ntp\" value=\"" + ntp + "\" /></td>\n"
// " </tr>\n"
" <tr>\n"
" <td>Auto-Off</td>\n"
" <td><input type=\"text\" size=\"10\" name=\"autooff\" value=\"" + autooff + "\" /> (time in seconds when non-zero)</td>\n"
" </tr>\n"
" <tr>\n"
" <td>On Reference</td>\n"
" <td><input type=\"text\" size=\"10\" name=\"onref\" value=\"" + onref + "\" /> (sense above this indicates power is on)</td>\n"
" </tr>\n"
" <tr>\n"
" <td>Off Reference</td>\n"
" <td><input type=\"text\" size=\"10\" name=\"offref\" value=\"" + offref + "\" /> (sense below this indicates power is off)</td>\n"
" </tr>\n"
" <tr>\n"
" <td>&nbsp;</td>\n"
" <td>\n"

146
Firmware/DNSServer.cpp Normal file
View File

@@ -0,0 +1,146 @@
#include "./DNSServer.h"
#include <lwip/def.h>
#include <Arduino.h>
//#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();
}

68
Firmware/DNSServer.h Normal file
View File

@@ -0,0 +1,68 @@
#ifndef DNSServer_h
#define DNSServer_h
#include <WiFiUdp.h>
#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

34
Firmware/Firmware.ses Normal file
View File

@@ -0,0 +1,34 @@
<?xml version="1.0" encoding="UTF-8" ?>
<NotepadPlus>
<Session activeView="0">
<mainView activeIndex="18">
<File firstVisibleLine="0" xOffset="0" scrollWidth="968" startPos="0" endPos="0" selMode="0" offset="0" wrapCount="1" lang="C++" encoding="-1" userReadOnly="no" filename="D:\Projects\GrowController\Firmware\Web_Resources.h" backupFilePath="" originalFileLastModifTimestamp="-1740723406" originalFileLastModifTimestampHigh="30920687" mapFirstVisibleDisplayLine="-1" mapFirstVisibleDocLine="-1" mapLastVisibleDocLine="-1" mapNbLine="-1" mapHigherPos="-1" mapWidth="-1" mapHeight="-1" mapKByteInDoc="1139802112" mapWrapIndentMode="-1" mapIsWrap="no" />
<File firstVisibleLine="8" xOffset="0" scrollWidth="968" startPos="1055" endPos="1055" selMode="0" offset="0" wrapCount="1" lang="C++" encoding="-1" userReadOnly="no" filename="D:\Projects\GrowController\Firmware\WifiConfiguration.cpp" backupFilePath="" originalFileLastModifTimestamp="-1744253404" originalFileLastModifTimestampHigh="30920687" mapFirstVisibleDisplayLine="-1" mapFirstVisibleDocLine="-1" mapLastVisibleDocLine="-1" mapNbLine="-1" mapHigherPos="-1" mapWidth="-1" mapHeight="-1" mapKByteInDoc="512" mapWrapIndentMode="-1" mapIsWrap="no" />
<File firstVisibleLine="164" xOffset="0" scrollWidth="840" startPos="6208" endPos="6208" selMode="0" offset="0" wrapCount="1" lang="C++" encoding="-1" userReadOnly="no" filename="D:\Projects\GrowController\Firmware\WiFiConfiguration.h" backupFilePath="" originalFileLastModifTimestamp="-1740783399" originalFileLastModifTimestampHigh="30920687" mapFirstVisibleDisplayLine="-1" mapFirstVisibleDocLine="-1" mapLastVisibleDocLine="-1" mapNbLine="-1" mapHigherPos="-1" mapWidth="-1" mapHeight="-1" mapKByteInDoc="512" mapWrapIndentMode="-1" mapIsWrap="no" />
<File firstVisibleLine="34" xOffset="0" scrollWidth="800" startPos="1339" endPos="1339" selMode="0" offset="0" wrapCount="1" lang="C++" encoding="-1" userReadOnly="no" filename="D:\Projects\GrowController\Firmware\WiFiStateHandler.cpp" backupFilePath="" originalFileLastModifTimestamp="-1740693408" originalFileLastModifTimestampHigh="30920687" mapFirstVisibleDisplayLine="-1" mapFirstVisibleDocLine="-1" mapLastVisibleDocLine="-1" mapNbLine="-1" mapHigherPos="-1" mapWidth="-1" mapHeight="-1" mapKByteInDoc="1139802112" mapWrapIndentMode="-1" mapIsWrap="no" />
<File firstVisibleLine="6" xOffset="0" scrollWidth="568" startPos="0" endPos="0" selMode="0" offset="0" wrapCount="1" lang="C++" encoding="-1" userReadOnly="no" filename="D:\Projects\GrowController\Firmware\WiFiStateHandler.h" backupFilePath="" originalFileLastModifTimestamp="-1744853417" originalFileLastModifTimestampHigh="30920687" mapFirstVisibleDisplayLine="-1" mapFirstVisibleDocLine="-1" mapLastVisibleDocLine="-1" mapNbLine="-1" mapHigherPos="-1" mapWidth="-1" mapHeight="-1" mapKByteInDoc="1139802112" mapWrapIndentMode="-1" mapIsWrap="no" />
<File firstVisibleLine="0" xOffset="0" scrollWidth="816" startPos="37" endPos="37" selMode="0" offset="0" wrapCount="1" lang="C++" encoding="-1" userReadOnly="no" filename="D:\Projects\GrowController\Firmware\CustomHandlers.cpp" backupFilePath="" originalFileLastModifTimestamp="-1740813409" originalFileLastModifTimestampHigh="30920687" mapFirstVisibleDisplayLine="-1" mapFirstVisibleDocLine="-1" mapLastVisibleDocLine="-1" mapNbLine="-1" mapHigherPos="-1" mapWidth="-1" mapHeight="-1" mapKByteInDoc="61" mapWrapIndentMode="-1" mapIsWrap="no" />
<File firstVisibleLine="21" xOffset="0" scrollWidth="824" startPos="1410" endPos="1410" selMode="0" offset="0" wrapCount="1" lang="C++" encoding="-1" userReadOnly="no" filename="D:\Projects\GrowController\Firmware\CustomHandlers.h" backupFilePath="" originalFileLastModifTimestamp="-1744983407" originalFileLastModifTimestampHigh="30920687" mapFirstVisibleDisplayLine="-1" mapFirstVisibleDocLine="-1" mapLastVisibleDocLine="-1" mapNbLine="-1" mapHigherPos="-1" mapWidth="-1" mapHeight="-1" mapKByteInDoc="477" mapWrapIndentMode="-1" mapIsWrap="no" />
<File firstVisibleLine="57" xOffset="0" scrollWidth="896" startPos="2588" endPos="2604" selMode="0" offset="0" wrapCount="1" lang="C++" encoding="-1" userReadOnly="no" filename="D:\Projects\GrowController\Firmware\Firmware.ino" backupFilePath="" originalFileLastModifTimestamp="-1745163414" originalFileLastModifTimestampHigh="30920687" mapFirstVisibleDisplayLine="-1" mapFirstVisibleDocLine="-1" mapLastVisibleDocLine="-1" mapNbLine="-1" mapHigherPos="-1" mapWidth="-1" mapHeight="-1" mapKByteInDoc="793" mapWrapIndentMode="-1" mapIsWrap="no" />
<File firstVisibleLine="147" xOffset="0" scrollWidth="896" startPos="5800" endPos="5800" selMode="0" offset="0" wrapCount="1" lang="C++" encoding="-1" userReadOnly="no" filename="D:\Projects\GrowController\Firmware\PlantModel.cpp" backupFilePath="" originalFileLastModifTimestamp="-1745073400" originalFileLastModifTimestampHigh="30920687" mapFirstVisibleDisplayLine="-1" mapFirstVisibleDocLine="-1" mapLastVisibleDocLine="-1" mapNbLine="-1" mapHigherPos="-1" mapWidth="-1" mapHeight="-1" mapKByteInDoc="1273" mapWrapIndentMode="-1" mapIsWrap="no" />
<File firstVisibleLine="0" xOffset="0" scrollWidth="192" startPos="156" endPos="156" selMode="0" offset="0" wrapCount="1" lang="C++" encoding="-1" userReadOnly="no" filename="D:\Projects\GrowController\Firmware\PlantModel.h" backupFilePath="" originalFileLastModifTimestamp="-1744383409" originalFileLastModifTimestampHigh="30920687" mapFirstVisibleDisplayLine="-1" mapFirstVisibleDocLine="-1" mapLastVisibleDocLine="-1" mapNbLine="-1" mapHigherPos="-1" mapWidth="-1" mapHeight="-1" mapKByteInDoc="308" mapWrapIndentMode="-1" mapIsWrap="no" />
<File firstVisibleLine="38" xOffset="0" scrollWidth="952" startPos="0" endPos="0" selMode="0" offset="0" wrapCount="1" lang="C++" encoding="-1" userReadOnly="no" filename="D:\Projects\GrowController\Firmware\ProjGlobals.h" backupFilePath="" originalFileLastModifTimestamp="-1744703417" originalFileLastModifTimestampHigh="30920687" mapFirstVisibleDisplayLine="-1" mapFirstVisibleDocLine="-1" mapLastVisibleDocLine="-1" mapNbLine="-1" mapHigherPos="-1" mapWidth="-1" mapHeight="-1" mapKByteInDoc="67" mapWrapIndentMode="-1" mapIsWrap="no" />
<File firstVisibleLine="0" xOffset="0" scrollWidth="552" startPos="469" endPos="469" selMode="0" offset="0" wrapCount="1" lang="C++" encoding="-1" userReadOnly="no" filename="D:\Projects\GrowController\Firmware\Utility.cpp" backupFilePath="" originalFileLastModifTimestamp="-1744533396" originalFileLastModifTimestampHigh="30920687" mapFirstVisibleDisplayLine="-1" mapFirstVisibleDocLine="-1" mapLastVisibleDocLine="-1" mapNbLine="-1" mapHigherPos="-1" mapWidth="-1" mapHeight="-1" mapKByteInDoc="1588" mapWrapIndentMode="-1" mapIsWrap="no" />
<File firstVisibleLine="0" xOffset="0" scrollWidth="968" startPos="553" endPos="553" selMode="0" offset="0" wrapCount="1" lang="C++" encoding="-1" userReadOnly="no" filename="D:\Projects\GrowController\Firmware\Utility.h" backupFilePath="" originalFileLastModifTimestamp="-1744143406" originalFileLastModifTimestampHigh="30920687" mapFirstVisibleDisplayLine="-1" mapFirstVisibleDocLine="-1" mapLastVisibleDocLine="-1" mapNbLine="-1" mapHigherPos="-1" mapWidth="-1" mapHeight="-1" mapKByteInDoc="1351" mapWrapIndentMode="-1" mapIsWrap="no" />
<File firstVisibleLine="0" xOffset="0" scrollWidth="1" startPos="0" endPos="0" selMode="0" offset="0" wrapCount="1" lang="JavaScript" encoding="-1" userReadOnly="no" filename="D:\Projects\GrowController\Firmware\Resources\index.js" backupFilePath="" originalFileLastModifTimestamp="-1743093392" originalFileLastModifTimestampHigh="30920687" mapFirstVisibleDisplayLine="-1" mapFirstVisibleDocLine="-1" mapLastVisibleDocLine="-1" mapNbLine="-1" mapHigherPos="-1" mapWidth="-1" mapHeight="-1" mapKByteInDoc="954" mapWrapIndentMode="-1" mapIsWrap="no" />
<File firstVisibleLine="0" xOffset="0" scrollWidth="1" startPos="0" endPos="0" selMode="0" offset="0" wrapCount="0" lang="JavaScript" encoding="-1" userReadOnly="no" filename="D:\Projects\GrowController\Firmware\Resources\myip.js" backupFilePath="" originalFileLastModifTimestamp="-1742013411" originalFileLastModifTimestampHigh="30920687" mapFirstVisibleDisplayLine="-1" mapFirstVisibleDocLine="-1" mapLastVisibleDocLine="-1" mapNbLine="-1" mapHigherPos="-1" mapWidth="-1" mapHeight="-1" mapKByteInDoc="0" mapWrapIndentMode="-1" mapIsWrap="no" />
<File firstVisibleLine="0" xOffset="0" scrollWidth="1" startPos="0" endPos="0" selMode="0" offset="0" wrapCount="0" lang="JavaScript" encoding="-1" userReadOnly="no" filename="D:\Projects\GrowController\Firmware\Resources\nav.js" backupFilePath="" originalFileLastModifTimestamp="-1741213410" originalFileLastModifTimestampHigh="30920687" mapFirstVisibleDisplayLine="-1" mapFirstVisibleDocLine="-1" mapLastVisibleDocLine="-1" mapNbLine="-1" mapHigherPos="-1" mapWidth="-1" mapHeight="-1" mapKByteInDoc="556" mapWrapIndentMode="-1" mapIsWrap="no" />
<File firstVisibleLine="0" xOffset="0" scrollWidth="1" startPos="0" endPos="0" selMode="0" offset="0" wrapCount="0" lang="JavaScript" encoding="-1" userReadOnly="no" filename="D:\Projects\GrowController\Firmware\Resources\rssi.js" backupFilePath="" originalFileLastModifTimestamp="-1741833407" originalFileLastModifTimestampHigh="30920687" mapFirstVisibleDisplayLine="-1" mapFirstVisibleDocLine="-1" mapLastVisibleDocLine="-1" mapNbLine="-1" mapHigherPos="-1" mapWidth="-1" mapHeight="-1" mapKByteInDoc="538976315" mapWrapIndentMode="-1" mapIsWrap="no" />
<File firstVisibleLine="0" xOffset="0" scrollWidth="1" startPos="0" endPos="0" selMode="0" offset="0" wrapCount="0" lang="HTML" encoding="-1" userReadOnly="no" filename="D:\Projects\GrowController\Firmware\Resources\about.htm" backupFilePath="" originalFileLastModifTimestamp="-1741013423" originalFileLastModifTimestampHigh="30920687" mapFirstVisibleDisplayLine="-1" mapFirstVisibleDocLine="-1" mapLastVisibleDocLine="-1" mapNbLine="-1" mapHigherPos="-1" mapWidth="-1" mapHeight="-1" mapKByteInDoc="1035" mapWrapIndentMode="-1" mapIsWrap="no" />
<File firstVisibleLine="0" xOffset="0" scrollWidth="736" startPos="651" endPos="651" selMode="0" offset="0" wrapCount="1" lang="HTML" encoding="-1" userReadOnly="no" filename="D:\Projects\GrowController\Firmware\Resources\curr.htm" backupFilePath="" originalFileLastModifTimestamp="-1740983405" originalFileLastModifTimestampHigh="30920687" mapFirstVisibleDisplayLine="-1" mapFirstVisibleDocLine="-1" mapLastVisibleDocLine="-1" mapNbLine="-1" mapHigherPos="-1" mapWidth="-1" mapHeight="-1" mapKByteInDoc="1114" mapWrapIndentMode="-1" mapIsWrap="no" />
<File firstVisibleLine="0" xOffset="0" scrollWidth="1" startPos="0" endPos="0" selMode="0" offset="0" wrapCount="0" lang="HTML" encoding="-1" userReadOnly="no" filename="D:\Projects\GrowController\Firmware\Resources\index.htm" backupFilePath="" originalFileLastModifTimestamp="-1741673407" originalFileLastModifTimestampHigh="30920687" mapFirstVisibleDisplayLine="-1" mapFirstVisibleDocLine="-1" mapLastVisibleDocLine="-1" mapNbLine="-1" mapHigherPos="-1" mapWidth="-1" mapHeight="-1" mapKByteInDoc="1194" mapWrapIndentMode="-1" mapIsWrap="no" />
<File firstVisibleLine="0" xOffset="0" scrollWidth="1" startPos="0" endPos="0" selMode="0" offset="0" wrapCount="0" lang="HTML" encoding="-1" userReadOnly="no" filename="D:\Projects\GrowController\Firmware\Resources\navigation.htm" backupFilePath="" originalFileLastModifTimestamp="-1742483431" originalFileLastModifTimestampHigh="30920687" mapFirstVisibleDisplayLine="-1" mapFirstVisibleDocLine="-1" mapLastVisibleDocLine="-1" mapNbLine="-1" mapHigherPos="-1" mapWidth="-1" mapHeight="-1" mapKByteInDoc="1819569769" mapWrapIndentMode="-1" mapIsWrap="no" />
<File firstVisibleLine="0" xOffset="0" scrollWidth="1" startPos="0" endPos="0" selMode="0" offset="0" wrapCount="0" lang="HTML" encoding="-1" userReadOnly="no" filename="D:\Projects\GrowController\Firmware\Resources\rssi.htm" backupFilePath="" originalFileLastModifTimestamp="-1740843407" originalFileLastModifTimestampHigh="30920687" mapFirstVisibleDisplayLine="-1" mapFirstVisibleDocLine="-1" mapLastVisibleDocLine="-1" mapNbLine="-1" mapHigherPos="-1" mapWidth="-1" mapHeight="-1" mapKByteInDoc="1431" mapWrapIndentMode="-1" mapIsWrap="no" />
<File firstVisibleLine="0" xOffset="0" scrollWidth="1" startPos="0" endPos="0" selMode="0" offset="0" wrapCount="0" lang="CSS" encoding="-1" userReadOnly="no" filename="D:\Projects\GrowController\Firmware\Resources\button.css" backupFilePath="" originalFileLastModifTimestamp="-1740943390" originalFileLastModifTimestampHigh="30920687" mapFirstVisibleDisplayLine="-1" mapFirstVisibleDocLine="-1" mapLastVisibleDocLine="-1" mapNbLine="-1" mapHigherPos="-1" mapWidth="-1" mapHeight="-1" mapKByteInDoc="147" mapWrapIndentMode="-1" mapIsWrap="no" />
<File firstVisibleLine="0" xOffset="0" scrollWidth="208" startPos="0" endPos="0" selMode="0" offset="0" wrapCount="1" lang="CSS" encoding="-1" userReadOnly="no" filename="D:\Projects\GrowController\Firmware\Resources\plantmodel.css" backupFilePath="" originalFileLastModifTimestamp="-1742173407" originalFileLastModifTimestampHigh="30920687" mapFirstVisibleDisplayLine="-1" mapFirstVisibleDocLine="-1" mapLastVisibleDocLine="-1" mapNbLine="-1" mapHigherPos="-1" mapWidth="-1" mapHeight="-1" mapKByteInDoc="227" mapWrapIndentMode="-1" mapIsWrap="no" />
<File firstVisibleLine="0" xOffset="0" scrollWidth="512" startPos="0" endPos="0" selMode="0" offset="0" wrapCount="1" lang="JavaScript" encoding="-1" userReadOnly="no" filename="D:\Projects\GrowController\Firmware\Resources\about.js" backupFilePath="" originalFileLastModifTimestamp="-1742643407" originalFileLastModifTimestampHigh="30920687" mapFirstVisibleDisplayLine="-1" mapFirstVisibleDocLine="-1" mapLastVisibleDocLine="-1" mapNbLine="-1" mapHigherPos="-1" mapWidth="-1" mapHeight="-1" mapKByteInDoc="393" mapWrapIndentMode="-1" mapIsWrap="no" />
<File firstVisibleLine="53" xOffset="0" scrollWidth="816" startPos="0" endPos="0" selMode="0" offset="0" wrapCount="1" lang="JavaScript" encoding="-1" userReadOnly="no" filename="D:\Projects\GrowController\Firmware\Resources\curr.js" backupFilePath="" originalFileLastModifTimestamp="-1742343396" originalFileLastModifTimestampHigh="30920687" mapFirstVisibleDisplayLine="-1" mapFirstVisibleDocLine="-1" mapLastVisibleDocLine="-1" mapNbLine="-1" mapHigherPos="-1" mapWidth="-1" mapHeight="-1" mapKByteInDoc="1748" mapWrapIndentMode="-1" mapIsWrap="no" />
</mainView>
<subView activeIndex="0" />
</Session>
</NotepadPlus>

View File

@@ -1,35 +0,0 @@
<?xml version="1.0" encoding="UTF-8" ?>
<NotepadPlus>
<Session activeView="0">
<mainView activeIndex="16">
<File firstVisibleLine="0" xOffset="0" scrollWidth="1152" startPos="66" endPos="135" selMode="0" offset="0" wrapCount="1" lang="HTML" encoding="-1" userReadOnly="no" filename="C:\Projects\GrowController\gcfw\Resources\about.htm" backupFilePath="" originalFileLastModifTimestamp="-1755984831" originalFileLastModifTimestampHigh="30918723" mapFirstVisibleDisplayLine="-1" mapFirstVisibleDocLine="-1" mapLastVisibleDocLine="-1" mapNbLine="-1" mapHigherPos="-1" mapWidth="-1" mapHeight="-1" mapKByteInDoc="7864439" mapWrapIndentMode="-1" mapIsWrap="no" />
<File firstVisibleLine="0" xOffset="0" scrollWidth="1152" startPos="135" endPos="135" selMode="0" offset="0" wrapCount="1" lang="HTML" encoding="-1" userReadOnly="no" filename="C:\Projects\GrowController\gcfw\Resources\curr.htm" backupFilePath="" originalFileLastModifTimestamp="-1755304900" originalFileLastModifTimestampHigh="30918723" mapFirstVisibleDisplayLine="-1" mapFirstVisibleDocLine="-1" mapLastVisibleDocLine="-1" mapNbLine="-1" mapHigherPos="-1" mapWidth="-1" mapHeight="-1" mapKByteInDoc="8699361" mapWrapIndentMode="-1" mapIsWrap="no" />
<File firstVisibleLine="15" xOffset="0" scrollWidth="1161" startPos="1008" endPos="1008" selMode="0" offset="0" wrapCount="1" lang="HTML" encoding="-1" userReadOnly="no" filename="C:\Projects\GrowController\gcfw\Resources\index.htm" backupFilePath="" originalFileLastModifTimestamp="582500597" originalFileLastModifTimestampHigh="30918741" mapFirstVisibleDisplayLine="-1" mapFirstVisibleDocLine="-1" mapLastVisibleDocLine="-1" mapNbLine="-1" mapHigherPos="-1" mapWidth="-1" mapHeight="-1" mapKByteInDoc="0" mapWrapIndentMode="-1" mapIsWrap="no" />
<File firstVisibleLine="0" xOffset="0" scrollWidth="576" startPos="399" endPos="412" selMode="0" offset="0" wrapCount="1" lang="JavaScript" encoding="-1" userReadOnly="no" filename="C:\Projects\GrowController\gcfw\Resources\about.js" backupFilePath="" originalFileLastModifTimestamp="304003083" originalFileLastModifTimestampHigh="30772255" mapFirstVisibleDisplayLine="-1" mapFirstVisibleDocLine="-1" mapLastVisibleDocLine="-1" mapNbLine="-1" mapHigherPos="-1" mapWidth="-1" mapHeight="-1" mapKByteInDoc="0" mapWrapIndentMode="-1" mapIsWrap="no" />
<File firstVisibleLine="0" xOffset="0" scrollWidth="369" startPos="54" endPos="54" selMode="0" offset="0" wrapCount="1" lang="CSS" encoding="-1" userReadOnly="no" filename="C:\Projects\GrowController\gcfw\Resources\button.css" backupFilePath="" originalFileLastModifTimestamp="-809889817" originalFileLastModifTimestampHigh="30918529" mapFirstVisibleDisplayLine="-1" mapFirstVisibleDocLine="-1" mapLastVisibleDocLine="-1" mapNbLine="-1" mapHigherPos="-1" mapWidth="-1" mapHeight="-1" mapKByteInDoc="-285211648" mapWrapIndentMode="-1" mapIsWrap="no" />
<File firstVisibleLine="0" xOffset="0" scrollWidth="272" startPos="92" endPos="92" selMode="0" offset="0" wrapCount="1" lang="CSS" encoding="-1" userReadOnly="no" filename="C:\Projects\GrowController\gcfw\Resources\plantmodel.css" backupFilePath="" originalFileLastModifTimestamp="1181250598" originalFileLastModifTimestampHigh="30918741" mapFirstVisibleDisplayLine="-1" mapFirstVisibleDocLine="-1" mapLastVisibleDocLine="-1" mapNbLine="-1" mapHigherPos="-1" mapWidth="-1" mapHeight="-1" mapKByteInDoc="0" mapWrapIndentMode="-1" mapIsWrap="no" />
<File firstVisibleLine="0" xOffset="0" scrollWidth="1" startPos="0" endPos="0" selMode="0" offset="0" wrapCount="0" lang="JavaScript" encoding="-1" userReadOnly="no" filename="C:\Projects\GrowController\gcfw\Resources\curr.js" backupFilePath="" originalFileLastModifTimestamp="-1210165259" originalFileLastModifTimestampHigh="30918511" mapFirstVisibleDisplayLine="-1" mapFirstVisibleDocLine="-1" mapLastVisibleDocLine="-1" mapNbLine="-1" mapHigherPos="-1" mapWidth="-1" mapHeight="-1" mapKByteInDoc="7733353" mapWrapIndentMode="-1" mapIsWrap="no" />
<File firstVisibleLine="0" xOffset="0" scrollWidth="756" startPos="727" endPos="734" selMode="0" offset="0" wrapCount="1" lang="JavaScript" encoding="-1" userReadOnly="no" filename="C:\Projects\GrowController\gcfw\Resources\index.js" backupFilePath="" originalFileLastModifTimestamp="1069068571" originalFileLastModifTimestampHigh="30918535" mapFirstVisibleDisplayLine="-1" mapFirstVisibleDocLine="-1" mapLastVisibleDocLine="-1" mapNbLine="-1" mapHigherPos="-1" mapWidth="-1" mapHeight="-1" mapKByteInDoc="1139900416" mapWrapIndentMode="-1" mapIsWrap="no" />
<File firstVisibleLine="0" xOffset="0" scrollWidth="1" startPos="0" endPos="0" selMode="0" offset="0" wrapCount="0" lang="JavaScript" encoding="-1" userReadOnly="no" filename="C:\Projects\GrowController\gcfw\Resources\rssi.js" backupFilePath="" originalFileLastModifTimestamp="304113078" originalFileLastModifTimestampHigh="30772255" mapFirstVisibleDisplayLine="-1" mapFirstVisibleDocLine="-1" mapLastVisibleDocLine="-1" mapNbLine="-1" mapHigherPos="-1" mapWidth="-1" mapHeight="-1" mapKByteInDoc="1139900416" mapWrapIndentMode="-1" mapIsWrap="no" />
<File firstVisibleLine="0" xOffset="0" scrollWidth="1451" startPos="231" endPos="287" selMode="0" offset="0" wrapCount="1" lang="HTML" encoding="-1" userReadOnly="no" filename="C:\Projects\GrowController\gcfw\Resources\rssi.htm" backupFilePath="" originalFileLastModifTimestamp="-1754114876" originalFileLastModifTimestampHigh="30918723" mapFirstVisibleDisplayLine="-1" mapFirstVisibleDocLine="-1" mapLastVisibleDocLine="-1" mapNbLine="-1" mapHigherPos="-1" mapWidth="-1" mapHeight="-1" mapKByteInDoc="131072" mapWrapIndentMode="-1" mapIsWrap="no" />
<File firstVisibleLine="0" xOffset="0" scrollWidth="1071" startPos="100" endPos="100" selMode="0" offset="0" wrapCount="1" lang="HTML" encoding="-1" userReadOnly="no" filename="C:\Projects\GrowController\gcfw\Resources\navigation.htm" backupFilePath="" originalFileLastModifTimestamp="-1753474825" originalFileLastModifTimestampHigh="30918723" mapFirstVisibleDisplayLine="-1" mapFirstVisibleDocLine="-1" mapLastVisibleDocLine="-1" mapNbLine="-1" mapHigherPos="-1" mapWidth="-1" mapHeight="-1" mapKByteInDoc="0" mapWrapIndentMode="-1" mapIsWrap="no" />
<File firstVisibleLine="0" xOffset="0" scrollWidth="1089" startPos="212" endPos="212" selMode="0" offset="0" wrapCount="1" lang="JavaScript" encoding="-1" userReadOnly="no" filename="C:\Projects\GrowController\gcfw\Resources\nav.js" backupFilePath="" originalFileLastModifTimestamp="2129232066" originalFileLastModifTimestampHigh="30918721" mapFirstVisibleDisplayLine="-1" mapFirstVisibleDocLine="-1" mapLastVisibleDocLine="-1" mapNbLine="-1" mapHigherPos="-1" mapWidth="-1" mapHeight="-1" mapKByteInDoc="0" mapWrapIndentMode="-1" mapIsWrap="no" />
<File firstVisibleLine="0" xOffset="0" scrollWidth="594" startPos="152" endPos="152" selMode="0" offset="0" wrapCount="1" lang="JavaScript" encoding="-1" userReadOnly="no" filename="C:\Projects\GrowController\gcfw\Resources\myip.js" backupFilePath="" originalFileLastModifTimestamp="1696718592" originalFileLastModifTimestampHigh="30918535" mapFirstVisibleDisplayLine="-1" mapFirstVisibleDocLine="-1" mapLastVisibleDocLine="-1" mapNbLine="-1" mapHigherPos="-1" mapWidth="-1" mapHeight="-1" mapKByteInDoc="0" mapWrapIndentMode="-1" mapIsWrap="no" />
<File firstVisibleLine="257" xOffset="0" scrollWidth="994" startPos="11252" endPos="11252" selMode="0" offset="0" wrapCount="1" lang="C++" encoding="-1" userReadOnly="no" filename="C:\Projects\GrowController\gcfw\CustomHandlers.cpp" backupFilePath="" originalFileLastModifTimestamp="-1709816653" originalFileLastModifTimestampHigh="30918741" mapFirstVisibleDisplayLine="-1" mapFirstVisibleDocLine="-1" mapLastVisibleDocLine="-1" mapNbLine="-1" mapHigherPos="-1" mapWidth="-1" mapHeight="-1" mapKByteInDoc="7733353" mapWrapIndentMode="-1" mapIsWrap="no" />
<File firstVisibleLine="0" xOffset="0" scrollWidth="721" startPos="661" endPos="661" selMode="0" offset="0" wrapCount="1" lang="C++" encoding="-1" userReadOnly="no" filename="C:\Projects\GrowController\gcfw\CustomHandlers.h" backupFilePath="" originalFileLastModifTimestamp="-931836632" originalFileLastModifTimestampHigh="30918741" mapFirstVisibleDisplayLine="-1" mapFirstVisibleDocLine="-1" mapLastVisibleDocLine="-1" mapNbLine="-1" mapHigherPos="-1" mapWidth="-1" mapHeight="-1" mapKByteInDoc="131072" mapWrapIndentMode="-1" mapIsWrap="no" />
<File firstVisibleLine="71" xOffset="0" scrollWidth="749" startPos="3433" endPos="3443" selMode="0" offset="0" wrapCount="1" lang="C++" encoding="-1" userReadOnly="no" filename="C:\Projects\GrowController\gcfw\gcfw.ino" backupFilePath="" originalFileLastModifTimestamp="-347279647" originalFileLastModifTimestampHigh="30918751" mapFirstVisibleDisplayLine="-1" mapFirstVisibleDocLine="-1" mapLastVisibleDocLine="-1" mapNbLine="-1" mapHigherPos="-1" mapWidth="-1" mapHeight="-1" mapKByteInDoc="7733353" mapWrapIndentMode="-1" mapIsWrap="no">
<Mark line="110" />
</File>
<File firstVisibleLine="10" xOffset="0" scrollWidth="567" startPos="487" endPos="487" selMode="0" offset="0" wrapCount="1" lang="C++" encoding="-1" userReadOnly="no" filename="C:\Projects\GrowController\gcfw\ProjGlobals.h" backupFilePath="" originalFileLastModifTimestamp="320190381" originalFileLastModifTimestampHigh="30918752" mapFirstVisibleDisplayLine="-1" mapFirstVisibleDocLine="-1" mapLastVisibleDocLine="-1" mapNbLine="-1" mapHigherPos="-1" mapWidth="-1" mapHeight="-1" mapKByteInDoc="7733353" mapWrapIndentMode="-1" mapIsWrap="no" />
<File firstVisibleLine="0" xOffset="0" scrollWidth="1" startPos="0" endPos="0" selMode="0" offset="0" wrapCount="0" lang="C++" encoding="-1" userReadOnly="no" filename="C:\Projects\GrowController\gcfw\Web_Resources.h" backupFilePath="" originalFileLastModifTimestamp="-1355064912" originalFileLastModifTimestampHigh="30918723" mapFirstVisibleDisplayLine="-1" mapFirstVisibleDocLine="-1" mapLastVisibleDocLine="-1" mapNbLine="-1" mapHigherPos="-1" mapWidth="-1" mapHeight="-1" mapKByteInDoc="131072" mapWrapIndentMode="-1" mapIsWrap="no" />
<File firstVisibleLine="0" xOffset="0" scrollWidth="1" startPos="0" endPos="0" selMode="0" offset="0" wrapCount="0" lang="C++" encoding="-1" userReadOnly="no" filename="C:\Projects\GrowController\gcfw\WiFiConfiguration.cpp" backupFilePath="" originalFileLastModifTimestamp="755248262" originalFileLastModifTimestampHigh="30917526" mapFirstVisibleDisplayLine="-1" mapFirstVisibleDocLine="-1" mapLastVisibleDocLine="-1" mapNbLine="-1" mapHigherPos="-1" mapWidth="-1" mapHeight="-1" mapKByteInDoc="-285211648" mapWrapIndentMode="-1" mapIsWrap="no" />
<File firstVisibleLine="0" xOffset="0" scrollWidth="1" startPos="0" endPos="0" selMode="0" offset="0" wrapCount="0" lang="C++" encoding="-1" userReadOnly="no" filename="C:\Projects\GrowController\gcfw\WiFiConfiguration.h" backupFilePath="" originalFileLastModifTimestamp="755308276" originalFileLastModifTimestampHigh="30917526" mapFirstVisibleDisplayLine="-1" mapFirstVisibleDocLine="-1" mapLastVisibleDocLine="-1" mapNbLine="-1" mapHigherPos="-1" mapWidth="-1" mapHeight="-1" mapKByteInDoc="7274563" mapWrapIndentMode="-1" mapIsWrap="no" />
<File firstVisibleLine="0" xOffset="0" scrollWidth="1" startPos="0" endPos="0" selMode="0" offset="0" wrapCount="0" lang="C++" encoding="-1" userReadOnly="no" filename="C:\Projects\GrowController\gcfw\WiFiStateHandler.cpp" backupFilePath="" originalFileLastModifTimestamp="-1855225827" originalFileLastModifTimestampHigh="30917528" mapFirstVisibleDisplayLine="-1" mapFirstVisibleDocLine="-1" mapLastVisibleDocLine="-1" mapNbLine="-1" mapHigherPos="-1" mapWidth="-1" mapHeight="-1" mapKByteInDoc="5439531" mapWrapIndentMode="-1" mapIsWrap="no" />
<File firstVisibleLine="0" xOffset="0" scrollWidth="490" startPos="70" endPos="70" selMode="0" offset="0" wrapCount="1" lang="C++" encoding="-1" userReadOnly="no" filename="C:\Projects\GrowController\gcfw\WiFiStateHandler.h" backupFilePath="" originalFileLastModifTimestamp="-1855157359" originalFileLastModifTimestampHigh="30917528" mapFirstVisibleDisplayLine="-1" mapFirstVisibleDocLine="-1" mapLastVisibleDocLine="-1" mapNbLine="-1" mapHigherPos="-1" mapWidth="-1" mapHeight="-1" mapKByteInDoc="6553711" mapWrapIndentMode="-1" mapIsWrap="no" />
</mainView>
<subView activeIndex="1">
<File firstVisibleLine="4" xOffset="0" scrollWidth="648" startPos="278" endPos="278" selMode="0" offset="0" wrapCount="1" lang="C++" encoding="-1" userReadOnly="no" filename="C:\Projects\GrowController\gcfw\ProjGlobals.h" backupFilePath="" originalFileLastModifTimestamp="320190381" originalFileLastModifTimestampHigh="30918752" mapFirstVisibleDisplayLine="-1" mapFirstVisibleDocLine="-1" mapLastVisibleDocLine="-1" mapNbLine="-1" mapHigherPos="-1" mapWidth="-1" mapHeight="-1" mapKByteInDoc="7733353" mapWrapIndentMode="-1" mapIsWrap="no" />
<File firstVisibleLine="36" xOffset="0" scrollWidth="272" startPos="98" endPos="107" selMode="0" offset="0" wrapCount="1" lang="CSS" encoding="-1" userReadOnly="no" filename="C:\Projects\GrowController\gcfw\Resources\plantmodel.css" backupFilePath="" originalFileLastModifTimestamp="1181250598" originalFileLastModifTimestampHigh="30918741" mapFirstVisibleDisplayLine="-1" mapFirstVisibleDocLine="-1" mapLastVisibleDocLine="-1" mapNbLine="-1" mapHigherPos="-1" mapWidth="-1" mapHeight="-1" mapKByteInDoc="0" mapWrapIndentMode="-1" mapIsWrap="no" />
</subView>
</Session>
</NotepadPlus>

View File

@@ -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

View File

@@ -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<count; ) {
sprintf(buf + strlen(buf), "%02X ", *(p+i));
asc[i % 16] = isprint(*(p+i)) ? *(p+i) : '.';
if ((++i & 0x0F) == 0x00) {
printf("%-55s | %s |\n", buf, asc);
if (i < count) {
sprintf(buf, "%04X: ", i);
} else {
buf[0] = '\0';
asc[0] = '\0';
}
}
}
if (strlen(buf)) {
printf("%-55s | %s |\n", buf, asc);
}
}

View File

@@ -3,9 +3,33 @@
// Utility.h
//
//
#ifndef UTILITY_H
#define UTILITY_H
#include <ESP8266WiFi.h>
// 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

View File

@@ -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

View File

@@ -1,156 +1,162 @@
//
// This file hosts all the non-volatile configuration options for this node
//
#include "WiFiConfiguration.h"
#include <EEPROM.h>
#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;
}