Compare commits

..

No commits in common. "e3e01da80bb3dd704e41884f4df9a89b08e20f98" and "263d47d8d093a11eb6af4006cdef2a1ada79df88" have entirely different histories.

21 changed files with 63 additions and 711 deletions

8
.vscode/tasks.json vendored
View File

@ -6,9 +6,9 @@
{ {
"label": "Build", "label": "Build",
"type": "shell", "type": "shell",
"command": "arduino-cli compile -v --warnings all -b esp8266:esp8266:nodemcuv2:xtal=80,vt=flash,exception=disabled,stacksmash=enabled,ssl=basic,mmu=3232,non32xfer=fast,eesz=4M,led=2,ip=lm2n,dbg=Disabled,lvl=None____,wipe=none,baud=921600 -e \"`pwd`/src/app\"", "command": "arduino-cli compile -v --warnings all -b esp8266:esp8266:nodemcuv2:xtal=80,vt=flash,exception=disabled,stacksmash=enabled,ssl=basic,mmu=3232,non32xfer=fast,eesz=4M,led=2,ip=lm2f,dbg=Disabled,lvl=None____,wipe=none,baud=921600 -e \"`pwd`/src/app\"",
"windows":{ "windows":{
"command": "arduino-cli compile -v --warnings all -b esp8266:esp8266:nodemcuv2:xtal=80,vt=flash,exception=disabled,stacksmash=enabled,ssl=basic,mmu=3232,non32xfer=fast,eesz=4M,led=2,ip=lm2n,dbg=Disabled,lvl=None____,wipe=none,baud=921600 -e ((pwd).path + '/src/app')" "command": "arduino-cli compile -v --warnings all -b esp8266:esp8266:nodemcuv2:xtal=80,vt=flash,exception=disabled,stacksmash=enabled,ssl=basic,mmu=3232,non32xfer=fast,eesz=4M,led=2,ip=lm2f,dbg=Disabled,lvl=None____,wipe=none,baud=921600 -e ((pwd).path + '/src/app')"
}, },
"group": "build", "group": "build",
"presentation": { "presentation": {
@ -23,9 +23,9 @@
{ {
"label": "Flash", "label": "Flash",
"type": "shell", "type": "shell",
"command": "arduino-cli upload -v -b esp8266:esp8266:nodemcuv2:xtal=80,vt=flash,exception=disabled,stacksmash=enabled,ssl=basic,mmu=3232,non32xfer=fast,eesz=4M,led=2,ip=lm2n,dbg=Disabled,lvl=None____,wipe=none,baud=921600 \"`pwd`/src/app\" -p ${input:com_port}", "command": "arduino-cli upload -v -b esp8266:esp8266:nodemcuv2:xtal=80,vt=flash,exception=disabled,stacksmash=enabled,ssl=basic,mmu=3232,non32xfer=fast,eesz=4M,led=2,ip=lm2f,dbg=Disabled,lvl=None____,wipe=none,baud=921600 \"`pwd`/src/app\" -p ${input:com_port}",
"windows":{ "windows":{
"command": "arduino-cli upload -v -b esp8266:esp8266:nodemcuv2:xtal=80,vt=flash,exception=disabled,stacksmash=enabled,ssl=basic,mmu=3232,non32xfer=fast,eesz=4M,led=2,ip=lm2n,dbg=Disabled,lvl=None____,wipe=none,baud=921600 ((pwd).path + '/src/app') -p ${input:com_port}" "command": "arduino-cli upload -v -b esp8266:esp8266:nodemcuv2:xtal=80,vt=flash,exception=disabled,stacksmash=enabled,ssl=basic,mmu=3232,non32xfer=fast,eesz=4M,led=2,ip=lm2f,dbg=Disabled,lvl=None____,wipe=none,baud=921600 ((pwd).path + '/src/app') -p ${input:com_port}"
}, },
"group": "build", "group": "build",
"presentation": { "presentation": {

View File

@ -1,11 +0,0 @@
#This config file stores the configuration needed for OTA updates
#If this file is not present or if there is an error at parsing time
#the OTA update feature will be disabled.
#If the OTA service does not require any auth key then set this field empty ie ''
#The blank new line at then end of the file is mendatory. Without it, the last parameter won't be read.
ENABLED : 'true'
OTA_SERVER_ADDRESS : 'OTA server IP address'
OTA_SERVER_PORT : 80
OTA_SERVICE_PATH : 'OTA service url path on the server'
OTA_SERVICE_AUTH_KEY : 'OTA service auth key'

View File

@ -8,11 +8,9 @@
WEB_ENABLED : 'true' WEB_ENABLED : 'true'
WEB_PORT : 80 WEB_PORT : 80
WEB_MAX_CLIENT : 0 WEB_MAX_CLIENT : 0
WEB_WWW_DIR : '/WWW'
FTP_ENABLED : 'true' FTP_ENABLED : 'true'
FTP_LOGIN : 'ESP8266' FTP_LOGIN : 'ESP8266'
FTP_PASSWORD : '12345678' FTP_PASSWORD : '12345678'
FTP_ROOT_DIR : '/FTP'
FTP_PORT : 21 FTP_PORT : 21
FTP_DATA_PORT : 1024 FTP_DATA_PORT : 1024
FTP_MAX_CLIENT : 0 FTP_MAX_CLIENT : 0

View File

@ -6,7 +6,6 @@ const uint16_t screenHeight,
const uint16_t I2C_IOExpanderAddress, const uint16_t I2C_IOExpanderAddress,
const uint16_t _I2C_RTCFlashAddress, const uint16_t _I2C_RTCFlashAddress,
const Pin SPI_SDCard_cs, const Pin SPI_SDCard_cs,
const Pin onBoard_LED,
const Pin I2C_sda, const Pin I2C_sda,
const Pin I2C_scl, const Pin I2C_scl,
const Pin SPI_mosi, const Pin SPI_mosi,
@ -20,7 +19,6 @@ _SPI_mosi(SPI_mosi == DEFAULT_PIN ? GPIO_13_MOSI : SPI_mosi),
_SPI_miso(SPI_miso == DEFAULT_PIN ? GPIO_12_MISO : SPI_miso), _SPI_miso(SPI_miso == DEFAULT_PIN ? GPIO_12_MISO : SPI_miso),
_SPI_clk(SPI_clk == DEFAULT_PIN ? GPIO_14_CLK : SPI_clk), _SPI_clk(SPI_clk == DEFAULT_PIN ? GPIO_14_CLK : SPI_clk),
_SPI_SDCard_cs(SPI_SDCard_cs == DEFAULT_PIN ? GPIO_2 : SPI_SDCard_cs), _SPI_SDCard_cs(SPI_SDCard_cs == DEFAULT_PIN ? GPIO_2 : SPI_SDCard_cs),
_onBoard_LED(onBoard_LED == DEFAULT_PIN ? GPIO_2 : onBoard_LED),
_I2C_screenAddress(I2C_screenAddress), _I2C_screenAddress(I2C_screenAddress),
_I2C_IOExpanderAddress(I2C_IOExpanderAddress), _I2C_IOExpanderAddress(I2C_IOExpanderAddress),
_I2C_RTCFlashAddress(_I2C_RTCFlashAddress), _I2C_RTCFlashAddress(_I2C_RTCFlashAddress),
@ -61,11 +59,6 @@ Pin BoardConfig::getSPI_SDCard_cs() const
return _SPI_SDCard_cs; return _SPI_SDCard_cs;
} }
Pin BoardConfig::getOnBoard_LED() const
{
return _onBoard_LED;
}
uint16_t BoardConfig::getI2C_screenAddress() const uint16_t BoardConfig::getI2C_screenAddress() const
{ {
return _I2C_screenAddress; return _I2C_screenAddress;
@ -76,11 +69,12 @@ uint16_t BoardConfig::getI2C_IOExpanderAddress() const
return _I2C_IOExpanderAddress; return _I2C_IOExpanderAddress;
} }
uint16_t BoardConfig::getI2C_RTCFlashAddress() const uint16_t BoardConfig::getRTCFlashAddress() const
{ {
return _I2C_RTCFlashAddress; return _I2C_RTCFlashAddress;
} }
uint32_t BoardConfig::getSPISpeed() const uint32_t BoardConfig::getSPISpeed() const
{ {
return _SPISpeed; return _SPISpeed;

View File

@ -17,7 +17,6 @@ class BoardConfig
const uint16_t I2C_IOExpanderAddress = 0x27, const uint16_t I2C_IOExpanderAddress = 0x27,
const uint16_t _I2C_RTCFlashAddress = 0x0, const uint16_t _I2C_RTCFlashAddress = 0x0,
const Pin SPI_SDCard_cs = GPIO_2, const Pin SPI_SDCard_cs = GPIO_2,
const Pin onBoard_LED = GPIO_2,
const Pin I2C_sda = GPIO_4_SDA, const Pin I2C_sda = GPIO_4_SDA,
const Pin I2C_scl = GPIO_5_SCL, const Pin I2C_scl = GPIO_5_SCL,
const Pin SPI_mosi = GPIO_13_MOSI, const Pin SPI_mosi = GPIO_13_MOSI,
@ -33,11 +32,10 @@ class BoardConfig
Pin getSPI_miso() const; Pin getSPI_miso() const;
Pin getSPI_clk() const; Pin getSPI_clk() const;
Pin getSPI_SDCard_cs() const; Pin getSPI_SDCard_cs() const;
Pin getOnBoard_LED() const;
uint16_t getI2C_screenAddress() const; uint16_t getI2C_screenAddress() const;
uint16_t getI2C_IOExpanderAddress() const; uint16_t getI2C_IOExpanderAddress() const;
uint16_t getI2C_RTCFlashAddress() const; uint16_t getRTCFlashAddress() const;
uint32_t getSPISpeed() const; uint32_t getSPISpeed() const;
@ -53,7 +51,6 @@ class BoardConfig
const Pin _SPI_miso; const Pin _SPI_miso;
const Pin _SPI_clk; const Pin _SPI_clk;
const Pin _SPI_SDCard_cs; const Pin _SPI_SDCard_cs;
const Pin _onBoard_LED;
//2) I2C Addresses //2) I2C Addresses
const uint16_t _I2C_screenAddress; const uint16_t _I2C_screenAddress;

View File

@ -72,7 +72,7 @@ void *CFGFileParser::parseFile()
} }
} }
else if(readChar == ' ') _state = PARAM_SECTION; else if(readChar == ' ') _state = PARAM_SECTION;
else if((readChar >= 65 && readChar <= 90) /*A to Z*/ || (readChar >= 97 && readChar <= 122) /*a to z*/ || (readChar >= 48 && readChar <= 57) /*0 to 9*/ || readChar == '_' || readChar == '-') else if((readChar >= 65 && readChar <= 90) || (readChar >= 97 && readChar <= 122) || readChar == '_' || readChar == '-' || (readChar >= 48 && readChar <= 57))
{ {
if(_type == PARAMETER) if(_type == PARAMETER)
{ {
@ -100,9 +100,7 @@ void *CFGFileParser::parseFile()
else else
_quotedValue = true; _quotedValue = true;
} }
else if((readChar >= 65 && readChar <= 90) /*A to Z*/ || (readChar >= 97 && readChar <= 122) /*a to z*/ || (readChar >= 48 && readChar <= 57) /*0 to 9*/ || else if((readChar >= 65 && readChar <= 90) || (readChar >= 97 && readChar <= 122) || readChar == ' ' || readChar == '_' || readChar == '-' || (readChar >= 48 && readChar <= 57))
readChar == ' ' || readChar == '_' || readChar == '-' || readChar == '.' || readChar == '/'
)
{ {
//printf("%c",readChar); //printf("%c",readChar);
if(_type == PARAMETER) if(_type == PARAMETER)
@ -125,7 +123,7 @@ void *CFGFileParser::parseFile()
_type = VALUE; _type = VALUE;
if(readChar == '\'')_state = OPENING_QUOTE; if(readChar == '\'')_state = OPENING_QUOTE;
else if(readChar == ' ') _state = PARAM_SECTION; else if(readChar == ' ') _state = PARAM_SECTION;
else if((readChar >= 65 && readChar <= 90) /*A to Z*/ || (readChar >= 97 && readChar <= 122) /*a to z*/ || (readChar >= 48 && readChar <= 57) /*0 to 9*/ || readChar == '_' || readChar == '-') else if((readChar >= 65 && readChar <= 90) || (readChar >= 97 && readChar <= 122) || (readChar >= 48 && readChar <= 57) || readChar == '-' || readChar == '_')
{ {
_state = PARAM_SECTION; _state = PARAM_SECTION;

View File

@ -24,7 +24,7 @@ public:
{ {
if(_value == NULL) if(_value == NULL)
return false; return false;
return strcasecmp(_value,"true") == 0 ? true : false; return strcmp(_value,"true") == 0 || strcmp(_value,"TRUE") == 0 ? true : false;
} }
const char *getParameter() const{return _parameter == NULL ? "" : _parameter;} const char *getParameter() const{return _parameter == NULL ? "" : _parameter;}
bool isQuotedParameter()const{return _quotedParameter;} bool isQuotedParameter()const{return _quotedParameter;}

View File

@ -10,6 +10,7 @@
HttpClient::HttpClient(const char *address, uint16_t port, uint32_t timeout) : WiFiClient(), _pAddress(address), _port(port) HttpClient::HttpClient(const char *address, uint16_t port, uint32_t timeout) : WiFiClient(), _pAddress(address), _port(port)
{ {
setTimeout(timeout); setTimeout(timeout);
connectByHostOrIp();
} }
HttpClient::HttpClient(const char *address, const char *resource, uint16_t port, uint32_t timeout) : HttpClient(address, port, timeout) HttpClient::HttpClient(const char *address, const char *resource, uint16_t port, uint32_t timeout) : HttpClient(address, port, timeout)
@ -43,10 +44,7 @@ HttpClient::HttpClient(const HttpClient &object) : WiFiClient()
HttpClient::~HttpClient() HttpClient::~HttpClient()
{ {
if(connected()) if(_resource != NULL)free(_resource);
stop();
if(_resource != NULL)
free(_resource);
} }
boolean HttpClient::connectByHostOrIp() boolean HttpClient::connectByHostOrIp()
@ -55,17 +53,6 @@ boolean HttpClient::connectByHostOrIp()
#ifdef DEBUG_HTTP_CLIENT #ifdef DEBUG_HTTP_CLIENT
Serial.printf("About to connect\n"); Serial.printf("About to connect\n");
#endif #endif
//If we constructed the HttpClient with a NULL server address, we don't go further.
if(!_pAddress)
{
#ifdef DEBUG_HTTP_CLIENT
Serial.printf("IP Address is NULL !\n");
#endif
_connectionStatus = FAILED;
return false;
}
if(ipAddress.fromString(_pAddress)) if(ipAddress.fromString(_pAddress))
{ {
_isIp = true; _isIp = true;
@ -106,15 +93,12 @@ int HttpClient::sendHttpQuery(HttpRequestMethod method, Dictionary<DictionaryHel
//We reset this two flags //We reset this two flags
_httpCode = HTTP_CODE::UNDEFINED_CODE; _httpCode = HTTP_CODE::UNDEFINED_CODE;
_httpCodeParsed = false; _httpCodeParsed = false;
#ifdef DEBUG_HTTP_CLIENT #ifdef DEBUG_HTTP_CLIENT
if(_keepAlive) if(_keepAlive)
Serial.printf("Link status : %d\n", status()); Serial.printf("Link status : %d\n", status());
#endif #endif
//If we did not want to keep the connection alive and it is still open, then we first close it.
if(!_keepAlive && connected())stop();
if(!connected() || _connectionStatus == FAILED) if(!connected() || _connectionStatus == FAILED)
{ {
if(_retries == _maxRetries) return -__LINE__; if(_retries == _maxRetries) return -__LINE__;
@ -127,9 +111,9 @@ int HttpClient::sendHttpQuery(HttpRequestMethod method, Dictionary<DictionaryHel
#ifdef DEBUG_HTTP_CLIENT #ifdef DEBUG_HTTP_CLIENT
if(_keepAlive) if(_keepAlive)
Serial.printf("Link broken, we try to reconnect : addr : %s port %u\nretries : %u\n", _pAddress ? _pAddress : "NULL", _port, _retries); Serial.printf("Link broken, we try to reconnect : addr : %s port %u\nretries : %u\n", _pAddress, _port, _retries);
else else
Serial.printf("We start a new connection : %s port %u\nretries : %u\n", _pAddress ? _pAddress : "NULL", _port, _retries); Serial.printf("We start a new connection : %s port %u\nretries : %u\n", _pAddress, _port, _retries);
#endif #endif
if(!connectByHostOrIp()) if(!connectByHostOrIp())
@ -147,7 +131,7 @@ int HttpClient::sendHttpQuery(HttpRequestMethod method, Dictionary<DictionaryHel
if(connected()) if(connected())
{ {
#ifdef DEBUG_HTTP_CLIENT #ifdef DEBUG_HTTP_CLIENT
Serial.printf("Server is listening\n"); Serial.printf("Server is listening\n", status());
#endif #endif
switch(method) switch(method)
@ -158,7 +142,6 @@ int HttpClient::sendHttpQuery(HttpRequestMethod method, Dictionary<DictionaryHel
//Here we send the parameters //Here we send the parameters
sendUriWithGetParams(getData); sendUriWithGetParams(getData);
sendHeader(HttpMIMEType::UNKNOWN_MIME, 0, headerData); sendHeader(HttpMIMEType::UNKNOWN_MIME, 0, headerData);
flush(); //We force the send of the request to prevent any timeout on reception !
break; break;
case HttpRequestMethod::POST: case HttpRequestMethod::POST:
//It is necessary to compute the content length //It is necessary to compute the content length
@ -167,18 +150,17 @@ int HttpClient::sendHttpQuery(HttpRequestMethod method, Dictionary<DictionaryHel
sendUriWithGetParams(getData); sendUriWithGetParams(getData);
sendHeader(HttpMIMEType::APPLICATION_X_WWW_FORM_URLENCODED, computeBodyLength(postData), headerData); sendHeader(HttpMIMEType::APPLICATION_X_WWW_FORM_URLENCODED, computeBodyLength(postData), headerData);
sendPostData(postData); sendPostData(postData);
flush(); //We force the send of the request to prevent any timeout on reception !
break; break;
default: default:
#ifdef DEBUG_HTTP_CLIENT #ifdef DEBUG_HTTP_CLIENT
Serial.printf("Http verb unspecified\n"); Serial.printf("Http verb unspecified\n", status());
#endif #endif
if(!_keepAlive)stop(); if(!_keepAlive)stop();
return -__LINE__; return -__LINE__;
break; break;
} }
} }
return 0; return 0;
} }
@ -292,7 +274,7 @@ HttpClient::HTTP_CODE HttpClient::isReplyAvailable(uint16_t timeout)
#ifdef DEBUG_HTTP_CLIENT #ifdef DEBUG_HTTP_CLIENT
safeSize = available() > 99 ? 99 : available(); safeSize = available() > 99 ? 99 : available();
buffer[peekBytes((uint8_t*)buffer,safeSize)] = '\0'; buffer[peekBytes((uint8_t*)buffer,safeSize)] = '\0';
Serial.printf("Body chunk is : %s\n", buffer); Serial.printf("Body chunk is : %s\n",buffer);
#endif #endif
break; break;
} }
@ -303,7 +285,7 @@ HttpClient::HTTP_CODE HttpClient::isReplyAvailable(uint16_t timeout)
} }
#ifdef DEBUG_HTTP_CLIENT #ifdef DEBUG_HTTP_CLIENT
Serial.printf("\nAfter timeout or all data is received, HTTP_CODE is : %d\n", _httpCode); Serial.println("\nAfter timeout or all data is received");
#endif #endif
return _httpCode; return _httpCode;
@ -426,20 +408,5 @@ uint64_t HttpClient::computeBodyLength(Dictionary<DictionaryHelper::StringEntity
void HttpClient::setMaxRetries(int16_t retries) void HttpClient::setMaxRetries(int16_t retries)
{ {
_maxRetries = retries < 0 ? -1 : retries; _maxRetries = retries;
}
int16_t HttpClient::getMaxRetries(void) const
{
return _maxRetries;
}
uint16_t HttpClient::retriesCount(void) const
{
return _retries;
}
void HttpClient::resetRetriesCount(void)
{
_retries = 0;
} }

View File

@ -37,10 +37,7 @@ class HttpClient : public WiFiClient, public HttpConstants
Dictionary<DictionaryHelper::StringEntity> *headerData = NULL); Dictionary<DictionaryHelper::StringEntity> *headerData = NULL);
void keepAlive(boolean enabled); void keepAlive(boolean enabled);
void setMaxRetries(int16_t retries); void setMaxRetries(int16_t retries);
int16_t getMaxRetries(void) const; //100 ms is the default timeout
uint16_t retriesCount(void) const;
void resetRetriesCount(void);
//10s is the default timeout
HTTP_CODE isReplyAvailable(uint16_t timeout = 10000); HTTP_CODE isReplyAvailable(uint16_t timeout = 10000);
uint16_t readHttpBody(uint8_t *buffer, uint32_t size); uint16_t readHttpBody(uint8_t *buffer, uint32_t size);

View File

@ -1,114 +0,0 @@
#include "OTAManager.h"
#include "definition.h"
#define DEBUG_OTA_MANAGER(...) do {} while(0)
//#define DEBUG_OTA_MANAGER(...) do { Serial.printf(__VA_ARGS__); Serial.println();} while(0)
OTAManager::OTAManager(SDCardManager &sdCardManager, const BoardConfig &boardConfig) : _sdCardManager(&sdCardManager), _boardConfig(&boardConfig)
{ }
OTAManager::~OTAManager()
{ }
boolean OTAManager::init(void)
{
//If the SDCardManager is not available, then we disable the OTA service
if(!_sdCardManager)
{
DEBUG_OTA_MANAGER("SDCardMng is NULL !");
return true;
}
//If the SDCardManager is available, then we try to read the config file
CFGDictionary<CFGParameterValue> *otaCfg = _sdCardManager->getCFGFile(OTA_CFG_FILE);
boolean toReturn(true);
//If we did not find the file
if(!otaCfg)
{
DEBUG_OTA_MANAGER("otaCfg is NULL !");
return false;
}
if((*otaCfg)("ENABLED") != nullptr)
{
if((*otaCfg)("ENABLED")->booleanValue())
{
DEBUG_OTA_MANAGER("ENABLED : %s", (*otaCfg)("ENABLED")->stringValue());
if((*otaCfg)("OTA_SERVER_ADDRESS") != nullptr) //This is the only required parameter
{
_isServiceEnabled = true;
_otaUpdater.setLedPin(_boardConfig->getOnBoard_LED(), LOW);
_otaUpdater.onStart(std::bind(&OTAManager::updateStartedCb, this));
_otaUpdater.onError(std::bind(&OTAManager::updateErrorCb, this, std::placeholders::_1));
_otaUpdater.onProgress(std::bind(&OTAManager::updateProgressdCb, this, std::placeholders::_1, std::placeholders::_2));
_otaUpdater.onEnd(std::bind(&OTAManager::updateFinishedCb, this));
_otaUpdater.setServerAddress((*otaCfg)("OTA_SERVER_ADDRESS")->stringValue());
if((*otaCfg)("OTA_SERVER_PORT") != nullptr)
{
DEBUG_OTA_MANAGER("OTA_SERVER_PORT : %s", (*otaCfg)("OTA_SERVER_PORT")->stringValue());
_otaUpdater.setPort((*otaCfg)("OTA_SERVER_PORT")->uintValue());
}
if((*otaCfg)("OTA_SERVICE_PATH") != nullptr)
{
DEBUG_OTA_MANAGER("OTA_SERVICE_PATH : %s", (*otaCfg)("OTA_SERVICE_PATH")->stringValue());
_otaUpdater.setPath((*otaCfg)("OTA_SERVICE_PATH")->stringValue());
}
if((*otaCfg)("OTA_SERVICE_AUTH_KEY") != nullptr)
{
DEBUG_OTA_MANAGER("OTA_SERVICE_AUTH_KEY : %s", (*otaCfg)("OTA_SERVICE_AUTH_KEY")->stringValue());
_otaUpdater.setOtaAuthKey((*otaCfg)("OTA_SERVICE_AUTH_KEY")->stringValue());
}
}
else
{
DEBUG_OTA_MANAGER("OTA_SERVER_ADDRESS is NULL !");
toReturn = false;
}
}
}
else
{
DEBUG_OTA_MANAGER("ENABLED is NULL !");
toReturn = false;
}
delete otaCfg;
return toReturn;
}
boolean OTAManager::isEnabled(void) const
{
return _isServiceEnabled;
}
OTAUpdater& OTAManager::getOTAUpdater(void)
{
return _otaUpdater;
}
void OTAManager::updateStartedCb(void)
{
Serial.println("CALLBACK: HTTP update process started");
}
void OTAManager::updateFinishedCb(void)
{
Serial.println("CALLBACK: HTTP update process finished");
}
void OTAManager::updateProgressdCb(int cur, int total)
{
Serial.printf("CALLBACK: HTTP update process at %d of %d bytes...\n", cur, total);
}
void OTAManager::updateErrorCb(int err)
{
Serial.printf("CALLBACK: HTTP update fatal error code %d\n", err);
}

View File

@ -1,32 +0,0 @@
#ifndef OTAMANAGER_H
#define OTAMANAGER_H
#include "OTAUpdater.h"
#include "SDCardManager.h"
#include "BoardConfig.h"
class OTAManager
{
friend class SAB;
public:
~OTAManager();
boolean init(void);
boolean isEnabled(void) const;
OTAUpdater& getOTAUpdater(void);
protected:
OTAManager(SDCardManager &sdCardManager, const BoardConfig &boardConfig);
OTAManager();
private:
void updateStartedCb(void);
void updateFinishedCb(void);
void updateProgressdCb(int cur, int total);
void updateErrorCb(int err);
OTAUpdater _otaUpdater;
SDCardManager *_sdCardManager = nullptr;
const BoardConfig * _boardConfig = nullptr;
boolean _isServiceEnabled = false;
};
#endif //OTAMANAGER_H

View File

@ -1,231 +0,0 @@
#include "OTAUpdater.h"
#include "HttpClient.h"
//#define DEBUG_OTA_UPDATER
OTAUpdater::OTAUpdater(const char *serverAddress, const char *path, const char *ota_auth_key, uint16_t port) : _port(port)
{
if(serverAddress)
_serverAddress = strdup(serverAddress);
if(path)
_path = strdup(path);
if(ota_auth_key)
_ota_auth_key = strdup(ota_auth_key);
}
OTAUpdater::OTAUpdater(int httpClientTimeout,const char *serverAddress, const char *path, const char *ota_auth_key, uint16_t port) : ESP8266HTTPUpdate(httpClientTimeout), _port(port)
{
if(serverAddress)
_serverAddress = strdup(serverAddress);
if(path)
_path = strdup(path);
if(ota_auth_key)
_ota_auth_key = strdup(ota_auth_key);
}
OTAUpdater::~OTAUpdater()
{
if(_publicKey != nullptr)
delete _publicKey;
if(_hash != nullptr)
delete _hash;
if(_signingVerifier != nullptr)
delete _signingVerifier;
free(_serverAddress);
free(_path);
free(_ota_auth_key);
}
//Enables the binary signing verification
void OTAUpdater::enableSHA256UpdateVerification(const char *publicKey)
{
if(_publicKey != nullptr)
delete _publicKey;
if(_hash != nullptr)
delete _hash;
if(_signingVerifier != nullptr)
delete _signingVerifier;
_publicKey = new BearSSL::PublicKey(publicKey);
_hash = new BearSSL::HashSHA256();
_signingVerifier = new BearSSL::SigningVerifier(_publicKey);
Update.installSignature(_hash, _signingVerifier);
}
void OTAUpdater::setServerAddress(const char *serverAddress)
{
if(!serverAddress)
return;
free(_serverAddress);
_serverAddress = strdup(serverAddress);
}
void OTAUpdater::setPath(const char *path)
{
//The path can be empty
if(!path)
{
free(_path);
_path = nullptr;
}
else
{
free(_path);
_path = strdup(path);
}
}
void OTAUpdater::setOtaAuthKey(const char *ota_auth_key)
{
//The authKey can be empty
if(!ota_auth_key)
{
free(_ota_auth_key);
_ota_auth_key = nullptr;
}
else
{
free(_ota_auth_key);
_ota_auth_key = strdup(ota_auth_key);
}
}
void OTAUpdater::setPort(uint16_t port)
{
_port = port;
}
OTAUpdater::UpdateInfo OTAUpdater::fetchUpdateInfo(const char *softwareVersion, uint32_t timeout)
{
HttpClient httpClient(_serverAddress, _path, _port, timeout);
UpdateInfo ui;
if(!softwareVersion)
{
ui.info = OTAUpdater::UpdateInfo::HTTP_NO_UPDATE;
return ui;
}
Dictionary<DictionaryHelper::StringEntity> getData;
getData.add("authKey", DictionaryHelper::StringEntity(_ota_auth_key));
getData.add("checkonly", NULL);
Dictionary<DictionaryHelper::StringEntity> headerData;
headerData.add("x-ESP8266-version",DictionaryHelper::StringEntity(softwareVersion));
headerData.add("x-ESP8266-STA-MAC",DictionaryHelper::StringEntity(WiFi.macAddress().c_str()));
headerData.add("User-Agent",DictionaryHelper::StringEntity("ESP8266-http-Update"));
if(httpClient.sendHttpQuery(HttpClient::HttpRequestMethod::GET, &getData, NULL, &headerData) == 0)
{
HttpConstants::HTTP_CODE result = httpClient.isReplyAvailable(1000);
switch(result)
{
case HttpConstants::HTTP_CODE::HTTP_CODE_OK:
{
char buffer[100];
httpClient.readHttpBody((uint8_t *)buffer, 100);
#ifdef DEBUG_OTA_UPDATER
Serial.printf("Response from update service : %s\n", buffer);
#endif
char *p = strstr_P(buffer, PSTR("bin_version"));
if(p)
{
p+=14;
char *end = strchr(p, '"');
if(end)
{
*end = '\0';
ui.version = (char *)malloc(strlen(p) * sizeof(char) + 1);
if(ui.version)
strcpy(ui.version, p);
}
}
ui.info = OTAUpdater::UpdateInfo::HTTP_UPDATE_AVAILABLE;
}
break;
case HttpConstants::HTTP_CODE::HTTP_CODE_NOT_MODIFIED:
ui.info = OTAUpdater::UpdateInfo::HTTP_NO_UPDATE;
break;
case HttpConstants::HTTP_CODE::HTTP_CODE_FORBIDDEN:
ui.info = OTAUpdater::UpdateInfo::HTTP_UPDATE_AUTH_ERROR;
break;
case HttpConstants::HTTP_CODE::HTTP_CODE_NOT_FOUND:
ui.info = OTAUpdater::UpdateInfo::HTTP_UPDATE_REACH_ERROR;
break;
default:
#ifdef DEBUG_OTA_UPDATER
Serial.printf("HTTP ERROR CODE IS : %u\n", result);
#endif
ui.info = OTAUpdater::UpdateInfo::HTTP_UPDATE_UNDEFINED_ERROR;
}
httpClient.stop();
}
else
ui.info = OTAUpdater::UpdateInfo::HTTP_UPDATE_REACH_ERROR;
return ui;
}
#define DEBUG_OTA_UPDATER
HTTPUpdateResult OTAUpdater::update(const char *softwareVersion)
{
if(!softwareVersion)
{
#ifdef DEBUG_OTA_UPDATER
Serial.printf("Missing softwareVersion !\n");
#endif
return HTTPUpdateResult::HTTP_UPDATE_NO_UPDATES;
}
if(!_serverAddress)
{
#ifdef DEBUG_OTA_UPDATER
Serial.printf("Missing server address !\n");
#endif
return HTTPUpdateResult::HTTP_UPDATE_FAILED;
}
//Depending on the presence or not of the path and the authKey, we compute the size we must allocate for the full path
uint16_t length = 1 /*for the \0*/;
length += _path ? strlen(_path) : 0;
length += _ota_auth_key ? strlen(_ota_auth_key) + 9/*for : ?authKey=*/ : 0;
char *fullpath = (char *)malloc(length * sizeof(char));
if(!fullpath)return HTTP_UPDATE_FAILED;
fullpath[0] = '\0';
WiFiClient client;
if(_path)strcpy(fullpath, _path);
if(_ota_auth_key)
{
strcat(fullpath, "?authKey=");
strcat(fullpath, _ota_auth_key);
}
#ifdef DEBUG_OTA_UPDATER
Serial.printf("The fullpath is : %s\n", fullpath);
#endif
HTTPUpdateResult result = ESP8266HTTPUpdate::update(client, _serverAddress, _port, fullpath, softwareVersion);
free(fullpath);
return result;
}

View File

@ -1,103 +0,0 @@
#ifndef OTAUPDATER_H
#define OTAUPDATER_H
#include <ESP8266httpUpdate.h>
#define OTAUPDATER_STRING //PSTR
class OTAUpdater : public ESP8266HTTPUpdate
{
public:
struct UpdateInfo
{
enum HTTPUpdateInfo {
HTTP_NO_UPDATE, //There is no new update available
HTTP_UPDATE_AVAILABLE, //There is an update ready to be applied
HTTP_UPDATE_AUTH_ERROR, //There was an error during the authentification process by the update service
HTTP_UPDATE_REACH_ERROR, //Unable to reach the update service
HTTP_UPDATE_UNDEFINED_ERROR
};
UpdateInfo(){}
UpdateInfo(const UpdateInfo &object)
{
info = object.info;
if(object.version)
{
version = (char *) malloc((strlen(object.version) + 1) * sizeof(char));
if(version != NULL)
strcpy(version, object.version);
}
}
~UpdateInfo(){ dispose(); }
UpdateInfo& operator=(const UpdateInfo &object)
{
info = object.info;
if(version)
{
free(version);version = NULL;
}
if(object.version)
{
version = (char *) malloc((strlen(object.version) + 1) * sizeof(char));
if(version != NULL)
strcpy(version, object.version);
}
return *this;
}
void dispose()
{
if(version)
{
free(version);version = NULL;
}
}
const char *HTTPUpdateInfoToString(void)
{
switch(info)
{
case HTTP_NO_UPDATE:
return OTAUPDATER_STRING("HTTP_NO_UPDATE");
break;
case HTTP_UPDATE_AVAILABLE:
return OTAUPDATER_STRING("HTTP_UPDATE_AVAILABLE");
break;
case HTTP_UPDATE_AUTH_ERROR:
return OTAUPDATER_STRING("HTTP_UPDATE_AUTH_ERROR");
break;
case HTTP_UPDATE_REACH_ERROR:
return OTAUPDATER_STRING("HTTP_UPDATE_REACH_ERROR");
break;
default:
return OTAUPDATER_STRING("HTTP_UPDATE_UNDEFINED_ERROR");
break;
}
}
HTTPUpdateInfo info = HTTP_NO_UPDATE;
char *version = NULL;
};
OTAUpdater(const char *serverAddress = NULL, const char *path = NULL, const char *ota_auth_key = NULL, uint16_t port = 80);
OTAUpdater(int httpClientTimeout, const char *serverAddress, const char *path = NULL, const char *ota_auth_key = NULL, uint16_t port = 80);
~OTAUpdater();
//Enables the binary signing verification
void enableSHA256UpdateVerification(const char *publicKey);
void setServerAddress(const char *serverAddress);
void setPath(const char *path = NULL);
void setOtaAuthKey(const char *ota_auth_key = NULL);
void setPort(uint16_t port = 80);
UpdateInfo fetchUpdateInfo(const char *softwareVersion, uint32_t timeout = 500);
HTTPUpdateResult update(const char *softwareVersion);
protected:
BearSSL::PublicKey *_publicKey = nullptr;
BearSSL::HashSHA256 *_hash = nullptr;
BearSSL::SigningVerifier *_signingVerifier = nullptr;
char *_serverAddress = nullptr;
char *_path = nullptr;
char *_ota_auth_key = nullptr;
uint16_t _port;
private:
};
#endif //OTAUPDATER_H

View File

@ -6,7 +6,6 @@ _screenManager(_display, &_sdCardManager),
_connectivityManager(_sdCardManager), _connectivityManager(_sdCardManager),
_webServer(80, &_sdCardManager, 10), _webServer(80, &_sdCardManager, 10),
_ftpServer(21, &_sdCardManager, "ESP8266", "12345678", 10), _ftpServer(21, &_sdCardManager, "ESP8266", "12345678", 10),
_otaManager(_sdCardManager, _boardConfig),
_dbWSServer(81), _dbWSServer(81),
_pcf(_boardConfig.getI2C_IOExpanderAddress(), Wire), _pcf(_boardConfig.getI2C_IOExpanderAddress(), Wire),
_ioManager(_pcf), _ioManager(_pcf),
@ -22,7 +21,6 @@ _screenManager(_display, &_sdCardManager),
_connectivityManager(_sdCardManager), _connectivityManager(_sdCardManager),
_webServer(webServerPort, &_sdCardManager, 10), _webServer(webServerPort, &_sdCardManager, 10),
_ftpServer(ftpServerPort, &_sdCardManager, "ESP8266", "12345678", 10), _ftpServer(ftpServerPort, &_sdCardManager, "ESP8266", "12345678", 10),
_otaManager(_sdCardManager, _boardConfig),
_dbWSServer(81), _dbWSServer(81),
_pcf(_boardConfig.getI2C_IOExpanderAddress(), Wire), _pcf(_boardConfig.getI2C_IOExpanderAddress(), Wire),
_ioManager(_pcf), _ioManager(_pcf),
@ -41,18 +39,12 @@ void SAB::initCommonConfig()
//We initialize the pins for the I2C communication //We initialize the pins for the I2C communication
Wire.begin(_boardConfig.getI2C_sda(), _boardConfig.getI2C_scl()); Wire.begin(_boardConfig.getI2C_sda(), _boardConfig.getI2C_scl());
if(!_rtc.begin()) if(!_rtc.begin()) _error |= RTC_BEGIN_ERR;
_error |= RTC_BEGIN_ERR;
else else
{ {
_rtcManager.setDateTime(_rtc.now()); _rtcManager.setDateTime(_rtc.now());
} }
if(!_display.begin(SSD1306_SWITCHCAPVCC, _boardConfig.getI2C_screenAddress())){ _error |= DISP_BEGIN_ERR;}
if(!_display.begin(SSD1306_SWITCHCAPVCC, _boardConfig.getI2C_screenAddress()))
{
_error |= DISP_BEGIN_ERR;
}
if(!_sdCardManager.mountSD()) if(!_sdCardManager.mountSD())
{ {
_error |= SDCARD_INIT_ERR; _error |= SDCARD_INIT_ERR;
@ -60,11 +52,9 @@ void SAB::initCommonConfig()
_boardConfig.getSPISpeed(), _boardConfig.getSPISpeed(),
_boardConfig.getSPI_SDCard_cs()); _boardConfig.getSPI_SDCard_cs());
} }
_screenManager.init(); _screenManager.init();
if(!_connectivityManager.connect()){ _error |= CONNECT_ERR;} if(!_connectivityManager.connect()){ _error |= CONNECT_ERR;}
if(!_pcf.begin()){_error |= IO_INIT_ERR;} if(!_pcf.begin()){_error |= IO_INIT_ERR;}
if(!_otaManager.init()){_error |= OTA_INIT_ERR;}
//We set the different servers : //We set the different servers :
_webServer.setWWWDir(WWW_DIR); _webServer.setWWWDir(WWW_DIR);
@ -114,12 +104,7 @@ FTPServer<FTPClient>& SAB::getFtpServer()
return _ftpServer; return _ftpServer;
} }
OTAManager& SAB::getOTAManager() IOManager& SAB::getIoManager()
{
return _otaManager;
}
IOManager& SAB::getIOManager()
{ {
return _ioManager; return _ioManager;
} }

View File

@ -12,7 +12,6 @@
#include "IOManager.h" #include "IOManager.h"
#include "TaskSchedulerManager.h" #include "TaskSchedulerManager.h"
#include "PowerManager.h" #include "PowerManager.h"
#include "OTAManager.h"
#include "versions.h" #include "versions.h"
#include <Adafruit_SSD1306.h> #include <Adafruit_SSD1306.h>
#include <RTClib.h> #include <RTClib.h>
@ -21,7 +20,7 @@
class SAB class SAB
{ {
public: public:
enum Error {RTC_BEGIN_ERR = 1, DISP_BEGIN_ERR = 2, SDCARD_INIT_ERR = 4, IO_INIT_ERR = 8, CONNECT_ERR = 16, OTA_INIT_ERR = 32}; enum Error {RTC_BEGIN_ERR = 1, DISP_BEGIN_ERR = 2, SDCARD_INIT_ERR = 4, IO_INIT_ERR = 8, CONNECT_ERR = 16};
SAB(); SAB();
SAB(const BoardConfig boardConfig, const unsigned int webServerPort = 80, const unsigned int ftpServerPort = 21); SAB(const BoardConfig boardConfig, const unsigned int webServerPort = 80, const unsigned int ftpServerPort = 21);
@ -34,10 +33,10 @@ class SAB
RTC_DS3231& getRTC_DS3231(); RTC_DS3231& getRTC_DS3231();
SDCardManager& getSdCardManager(); SDCardManager& getSdCardManager();
ConnectivityManager& getConnectivityManager(); ConnectivityManager& getConnectivityManager();
//WEBServerManager& getWebServerManager();
WEBServer<WEBClient>& getWebServer(); WEBServer<WEBClient>& getWebServer();
FTPServer<FTPClient>& getFtpServer(); FTPServer<FTPClient>& getFtpServer();
OTAManager& getOTAManager(); IOManager& getIoManager();
IOManager& getIOManager();
TaskSchedulerManager& getTaskSchedulerManager(); TaskSchedulerManager& getTaskSchedulerManager();
PowerManager& getPowerManager(); PowerManager& getPowerManager();
TimeSpan getUpTime() const; TimeSpan getUpTime() const;
@ -57,10 +56,10 @@ class SAB
RTC_DS3231 _rtc; RTC_DS3231 _rtc;
RtcManager _rtcManager; RtcManager _rtcManager;
ConnectivityManager _connectivityManager; ConnectivityManager _connectivityManager;
//WEBServerManager _webServerManager;
WEBServer<WEBClient> _webServer; WEBServer<WEBClient> _webServer;
FTPServer<FTPClient> _ftpServer; FTPServer<FTPClient> _ftpServer;
OTAManager _otaManager; DashboardWSServer _dbWSServer;
DashboardWSServer _dbWSServer;
PCF8574 _pcf; PCF8574 _pcf;
IOManager _ioManager; IOManager _ioManager;
TaskSchedulerManager _taskSchedulerManager; TaskSchedulerManager _taskSchedulerManager;

View File

@ -95,10 +95,9 @@ void setup()
sab.getWebServer().addApiRoutine("/sab/io/get/mode", &(ioGetModeApi), &sab, WEBServer<WEBClient>::GET); sab.getWebServer().addApiRoutine("/sab/io/get/mode", &(ioGetModeApi), &sab, WEBServer<WEBClient>::GET);
sab.getWebServer().addApiRoutine("/sab/io/set/mode", &(ioSetModeApi), &sab, WEBServer<WEBClient>::GET); sab.getWebServer().addApiRoutine("/sab/io/set/mode", &(ioSetModeApi), &sab, WEBServer<WEBClient>::GET);
sab.getWebServer().addApiRoutine("/sab/sw/version", &(swVersionApi), &sab, WEBServer<WEBClient>::GET); sab.getWebServer().addApiRoutine("/sab/sw/version", &(swVersionApi), &sab, WEBServer<WEBClient>::GET);
sab.getWebServer().addApiRoutine("/sab/ota/update/upload", &(otaUpdateUploadApi), NULL, WEBServer<WEBClient>::POST); sab.getWebServer().addApiRoutine("/sab/ota/update", &(otaUpdateApi), NULL, WEBServer<WEBClient>::POST);
sab.getWebServer().addApiRoutine("/sab/ota/update/device", &(otaUpdateRemoteApi), &sab, WEBServer<WEBClient>::GET);
sab.getIOManager().setISROnIOChange(&(ioISR), GPIO_3_RX); sab.getIoManager().setISROnIOChange(&(ioISR), GPIO_3_RX);
sab.getTaskSchedulerManager().addTask((uint16_t)0, TaskSchedulerManagerHelper::Schedule::scheduleBuilder()->setMillis(5000), &(task_blink), &sab); sab.getTaskSchedulerManager().addTask((uint16_t)0, TaskSchedulerManagerHelper::Schedule::scheduleBuilder()->setMillis(5000), &(task_blink), &sab);
sab.getTaskSchedulerManager().addTask(1, TaskSchedulerManagerHelper::Schedule::scheduleBuilder()->setSeconds(10), &(task_sys_info), &v1p); sab.getTaskSchedulerManager().addTask(1, TaskSchedulerManagerHelper::Schedule::scheduleBuilder()->setSeconds(10), &(task_sys_info), &v1p);
@ -122,8 +121,8 @@ void loop()
vstap.ipAddr = sab.getConnectivityManager().localIP(); vstap.ipAddr = sab.getConnectivityManager().localIP();
vstap.sigStrength = sab.getConnectivityManager().RSSI(); vstap.sigStrength = sab.getConnectivityManager().RSSI();
sab.getIOManager().getPcf().digitalReadAll(vio.ioState); sab.getIoManager().getPcf().digitalReadAll(vio.ioState);
sab.getIOManager().getPcf().getPinModeAll(vio.ioMode); sab.getIoManager().getPcf().getPinModeAll(vio.ioMode);
if(ioStateChange) if(ioStateChange)
{ {

View File

@ -35,24 +35,10 @@ typedef enum { GPIO_0 = 0,
#define STA_CFG_FILE "/CONFIG/STA.CFG" #define STA_CFG_FILE "/CONFIG/STA.CFG"
#define SCREEN_CFG_FILE "/CONFIG/SCREEN.CFG" #define SCREEN_CFG_FILE "/CONFIG/SCREEN.CFG"
#define SERVER_CFG_FILE "/CONFIG/SERVER.CFG" #define SERVER_CFG_FILE "/CONFIG/SERVER.CFG"
#define OTA_CFG_FILE "/CONFIG/OTA.CFG"
#define WWW_DIR "/WWW" #define WWW_DIR "/WWW"
#define LOG_DIR "/LOGS" #define LOG_DIR "/LOGS"
#define FTP_DIR "/FTP" #define FTP_DIR "/FTP"
//OTA public key for binary verification
const char otaVerificationPubKey[] PROGMEM = R"DEL(
-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAsh6eFU0pdfir5CsQqs0v
vi7ip7MtRuNgcMtjl7lpXwQuMG5yoso1iR+Fzbz+Cso4lcqarG5uHV8nKYWQ+C39
+3OfKx9LSfabCnRAeFFhXuGWEfRcZ9aeW3Jv0Mg2+3sTOfXQGjdgNwOAqZNrL4kr
574F+c3o/PAwlr4VLMy7KygorNnaYzC5JF1H5DhqaKNniKVEqGXiVQKW10C04SsM
mGV/rKRSPpBVzyBrIf8GNPyVf7W4D0s9gSiCrRWMU2aU3tX35tezwlicsb86MKKM
o9ySHAMsIihx3zdwAGOELxE47Ylodq9cwc53fz7pfcdyL+N6FKKWM0bYJAkwNhdJ
NQIDAQAB
-----END PUBLIC KEY-----
)DEL";
typedef enum { OR_0 = 2, OR_90 = 3, OR_180 = 0, OR_270 = 1 } Orientation; typedef enum { OR_0 = 2, OR_90 = 3, OR_180 = 0, OR_270 = 1 } Orientation;
typedef enum { BIT = 0, BYTE, KBIT, KBYTE, MBIT, MBYTE, GBIT, GBYTE } SizeUnit; typedef enum { BIT = 0, BYTE, KBIT, KBYTE, MBIT, MBYTE, GBIT, GBYTE } SizeUnit;

View File

@ -3,7 +3,7 @@
boolean task_blink(void *pData) boolean task_blink(void *pData)
{ {
SAB *p = (SAB *) pData; SAB *p = (SAB *) pData;
p->getIOManager().getPcf().togglePin(PCF8574::P2); p->getIoManager().getPcf().togglePin(PCF8574::P2);
return true; return true;
} }
@ -19,36 +19,17 @@ boolean task_sys_info(void *pData)
TimeSpan ts(p->sab->getUpTime()); TimeSpan ts(p->sab->getUpTime());
Serial.printf_P(PSTR("BATT SENSING...\nSoftware version : %s\nUp Time : %d d %d h %d m %d s\nSystem error : %u\nStation IP : %s, %d dBm\nAP IP : %s\nDevice MAC : %s\nWEB Server clients : %u\nMemory info:\n\tFree RAM : %u\n\tHeap frag : %u\n\tMax block %u\n"), Serial.printf_P(PSTR("BATT SENSING...\nUp Time : %d d %d h %d m %d s\nSystem error : %u\nStation IP : %s, %d dBm\nAP IP : %s\nWEB Server clients : %u\nMemory info:\n\tFree RAM : %u\n\tHeap frag : %u\n\tMax block %u\n"),
p->sab->getSoftVersion(),
ts.days(), ts.hours(), ts.minutes(), ts.seconds(), ts.days(), ts.hours(), ts.minutes(), ts.seconds(),
p->sab->getError(), p->sab->getError(),
p->sab->getConnectivityManager().localIP().toString().c_str(), p->sab->getConnectivityManager().localIP().toString().c_str(),
p->sab->getConnectivityManager().RSSI(), p->sab->getConnectivityManager().RSSI(),
p->sab->getConnectivityManager().softAPIP().toString().c_str(), p->sab->getConnectivityManager().softAPIP().toString().c_str(),
p->sab->getConnectivityManager().macAddress().c_str(),
p->sab->getWebServer().getConnectedClientsCount(), p->sab->getWebServer().getConnectedClientsCount(),
freeRAM, freeRAM,
HEAPfrag, HEAPfrag,
biggestContigMemBlock); biggestContigMemBlock);
p->powerInfo = p->sab->getPowerManager().getPowerInfo(); p->powerInfo = p->sab->getPowerManager().getPowerInfo();
if(p->sab->getOTAManager().isEnabled())
{
OTAUpdater::UpdateInfo updateInfo = p->sab->getOTAManager().getOTAUpdater().fetchUpdateInfo(p->sab->getSoftVersion());
if(updateInfo.version != NULL)
{
Serial.printf("OTA : %s -> version(%s)\n", updateInfo.HTTPUpdateInfoToString(), updateInfo.version);
}
else
{
Serial.printf("OTA : %s\n", updateInfo.HTTPUpdateInfoToString());
}
}
else
{
Serial.println("OTA updates disabled");
}
return true; return true;
} }
@ -82,7 +63,7 @@ boolean task_post_data_logger(void * pData)
postData.add("post4", NULL); postData.add("post4", NULL);
if(p->client.sendHttpQuery(HttpClient::HttpRequestMethod::POST, &getData, &postData) == 0) if(p->client.sendHttpQuery(HttpClient::HttpRequestMethod::POST, &getData, &postData))
{ {
Serial.println("Send successful"); Serial.println("Send successful");
p->rdy = false; p->rdy = false;

View File

@ -44,7 +44,5 @@
//#define SOFT_VERSION "1.6.12" //WEBServer parsing http query parameters differently, allowing for longer URI and RAM savings. //#define SOFT_VERSION "1.6.12" //WEBServer parsing http query parameters differently, allowing for longer URI and RAM savings.
//#define SOFT_VERSION "1.6.13" //ScreenManager now providing and handling display auto power off functionality to save power as well as to fight OLED burn-in. //#define SOFT_VERSION "1.6.13" //ScreenManager now providing and handling display auto power off functionality to save power as well as to fight OLED burn-in.
//#define SOFT_VERSION "1.6.14" //Corrected a major stack overflow in the WEBServer and fixed a potential one in the FTPServer. //#define SOFT_VERSION "1.6.14" //Corrected a major stack overflow in the WEBServer and fixed a potential one in the FTPServer.
//#define SOFT_VERSION "1.6.15" //WEBServer now lists files and folder of a resource when it is a folder. #define SOFT_VERSION "1.6.15" //WEBServer now lists files and folder of a resource when it is a folder.
#define SOFT_VERSION "1.7.0" //OTA update of the device is now possible through a rest API endpoint.
#endif //VERSIONS_H #endif //VERSIONS_H

View File

@ -400,38 +400,38 @@ boolean ioSetLevelApi(WEBServer<WEBClient>::HttpRequestData &HRD, WiFiClient *wc
if(HRD.getParams("P0") != NULL) if(HRD.getParams("P0") != NULL)
{ {
p->getIOManager().getPcf().digitalWrite(PCF8574::P0,atoi(HRD.getParams("P0")->getString())); p->getIoManager().getPcf().digitalWrite(PCF8574::P0,atoi(HRD.getParams("P0")->getString()));
} }
if(HRD.getParams("P1") != NULL) if(HRD.getParams("P1") != NULL)
{ {
p->getIOManager().getPcf().digitalWrite(PCF8574::P1,atoi(HRD.getParams("P1")->getString())); p->getIoManager().getPcf().digitalWrite(PCF8574::P1,atoi(HRD.getParams("P1")->getString()));
} }
if(HRD.getParams("P2") != NULL) if(HRD.getParams("P2") != NULL)
{ {
p->getIOManager().getPcf().digitalWrite(PCF8574::P2,atoi(HRD.getParams("P2")->getString())); p->getIoManager().getPcf().digitalWrite(PCF8574::P2,atoi(HRD.getParams("P2")->getString()));
} }
if(HRD.getParams("P3") != NULL) if(HRD.getParams("P3") != NULL)
{ {
p->getIOManager().getPcf().digitalWrite(PCF8574::P3,atoi(HRD.getParams("P3")->getString())); p->getIoManager().getPcf().digitalWrite(PCF8574::P3,atoi(HRD.getParams("P3")->getString()));
} }
if(HRD.getParams("P4") != NULL) if(HRD.getParams("P4") != NULL)
{ {
p->getIOManager().getPcf().digitalWrite(PCF8574::P4,atoi(HRD.getParams("P4")->getString())); p->getIoManager().getPcf().digitalWrite(PCF8574::P4,atoi(HRD.getParams("P4")->getString()));
} }
if(HRD.getParams("P5") != NULL) if(HRD.getParams("P5") != NULL)
{ {
p->getIOManager().getPcf().digitalWrite(PCF8574::P5,atoi(HRD.getParams("P5")->getString())); p->getIoManager().getPcf().digitalWrite(PCF8574::P5,atoi(HRD.getParams("P5")->getString()));
} }
if(HRD.getParams("P6") != NULL) if(HRD.getParams("P6") != NULL)
{ {
p->getIOManager().getPcf().digitalWrite(PCF8574::P6,atoi(HRD.getParams("P6")->getString())); p->getIoManager().getPcf().digitalWrite(PCF8574::P6,atoi(HRD.getParams("P6")->getString()));
} }
if(HRD.getParams("P7") != NULL) if(HRD.getParams("P7") != NULL)
{ {
p->getIOManager().getPcf().digitalWrite(PCF8574::P7,atoi(HRD.getParams("P7")->getString())); p->getIoManager().getPcf().digitalWrite(PCF8574::P7,atoi(HRD.getParams("P7")->getString()));
} }
p->getIOManager().getPcf().digitalReadAll(ioState);//We retrieve the IO state p->getIoManager().getPcf().digitalReadAll(ioState);//We retrieve the IO state
sprintf(buffer,"{\"status\":\"ok\",\"P0\":\"%d\",\"P1\":\"%d\",\"P2\":\"%d\",\"P3\":\"%d\",\"P4\":\"%d\",\"P5\":\"%d\",\"P6\":\"%d\",\"P7\":\"%d\"}",ioState[0],ioState[1],ioState[2],ioState[3],ioState[4],ioState[5],ioState[6],ioState[7]); sprintf(buffer,"{\"status\":\"ok\",\"P0\":\"%d\",\"P1\":\"%d\",\"P2\":\"%d\",\"P3\":\"%d\",\"P4\":\"%d\",\"P5\":\"%d\",\"P6\":\"%d\",\"P7\":\"%d\"}",ioState[0],ioState[1],ioState[2],ioState[3],ioState[4],ioState[5],ioState[6],ioState[7]);
WEBServer<WEBClient>::sendHTTPHeader(wc, HttpConstants::httpMIMETypeToString(HttpConstants::APPLICATION_JSON), strlen(buffer)); WEBServer<WEBClient>::sendHTTPHeader(wc, HttpConstants::httpMIMETypeToString(HttpConstants::APPLICATION_JSON), strlen(buffer));
@ -447,7 +447,7 @@ boolean ioGetModeApi(WEBServer<WEBClient>::HttpRequestData &HRD, WiFiClient *wc,
char helperBuffer[20] = ""; char helperBuffer[20] = "";
const char * const IN = "IN", * const OUT = "OUT"; const char * const IN = "IN", * const OUT = "OUT";
p->getIOManager().getPcf().getPinModeAll(ioMode);//We retrieve the IO modes aka INPUT or OUTPUT p->getIoManager().getPcf().getPinModeAll(ioMode);//We retrieve the IO modes aka INPUT or OUTPUT
if(HRD.getParams.count() == 0)//We send every IO mode if(HRD.getParams.count() == 0)//We send every IO mode
{ {
@ -521,38 +521,38 @@ boolean ioSetModeApi(WEBServer<WEBClient>::HttpRequestData &HRD, WiFiClient *wc,
if(HRD.getParams("P0") != NULL) if(HRD.getParams("P0") != NULL)
{ {
p->getIOManager().getPcf().pinMode(PCF8574::P0,strcmp(HRD.getParams("P0")->getString(), IN) == 0 ? INPUT:OUTPUT); p->getIoManager().getPcf().pinMode(PCF8574::P0,strcmp(HRD.getParams("P0")->getString(), IN) == 0 ? INPUT:OUTPUT);
} }
if(HRD.getParams("P1") != NULL) if(HRD.getParams("P1") != NULL)
{ {
p->getIOManager().getPcf().pinMode(PCF8574::P1,strcmp(HRD.getParams("P1")->getString(), IN) == 0 ? INPUT:OUTPUT); p->getIoManager().getPcf().pinMode(PCF8574::P1,strcmp(HRD.getParams("P1")->getString(), IN) == 0 ? INPUT:OUTPUT);
} }
if(HRD.getParams("P2") != NULL) if(HRD.getParams("P2") != NULL)
{ {
p->getIOManager().getPcf().pinMode(PCF8574::P2,strcmp(HRD.getParams("P2")->getString(), IN) == 0 ? INPUT:OUTPUT); p->getIoManager().getPcf().pinMode(PCF8574::P2,strcmp(HRD.getParams("P2")->getString(), IN) == 0 ? INPUT:OUTPUT);
} }
if(HRD.getParams("P3") != NULL) if(HRD.getParams("P3") != NULL)
{ {
p->getIOManager().getPcf().pinMode(PCF8574::P3,strcmp(HRD.getParams("P3")->getString(), IN) == 0 ? INPUT:OUTPUT); p->getIoManager().getPcf().pinMode(PCF8574::P3,strcmp(HRD.getParams("P3")->getString(), IN) == 0 ? INPUT:OUTPUT);
} }
if(HRD.getParams("P4") != NULL) if(HRD.getParams("P4") != NULL)
{ {
p->getIOManager().getPcf().pinMode(PCF8574::P4,strcmp(HRD.getParams("P4")->getString(), IN) == 0 ? INPUT:OUTPUT); p->getIoManager().getPcf().pinMode(PCF8574::P4,strcmp(HRD.getParams("P4")->getString(), IN) == 0 ? INPUT:OUTPUT);
} }
if(HRD.getParams("P5") != NULL) if(HRD.getParams("P5") != NULL)
{ {
p->getIOManager().getPcf().pinMode(PCF8574::P5,strcmp(HRD.getParams("P5")->getString(), IN) == 0 ? INPUT:OUTPUT); p->getIoManager().getPcf().pinMode(PCF8574::P5,strcmp(HRD.getParams("P5")->getString(), IN) == 0 ? INPUT:OUTPUT);
} }
if(HRD.getParams("P6") != NULL) if(HRD.getParams("P6") != NULL)
{ {
p->getIOManager().getPcf().pinMode(PCF8574::P6,strcmp(HRD.getParams("P6")->getString(), IN) == 0 ? INPUT:OUTPUT); p->getIoManager().getPcf().pinMode(PCF8574::P6,strcmp(HRD.getParams("P6")->getString(), IN) == 0 ? INPUT:OUTPUT);
} }
if(HRD.getParams("P7") != NULL) if(HRD.getParams("P7") != NULL)
{ {
p->getIOManager().getPcf().pinMode(PCF8574::P7,strcmp(HRD.getParams("P7")->getString(), IN) == 0 ? INPUT:OUTPUT); p->getIoManager().getPcf().pinMode(PCF8574::P7,strcmp(HRD.getParams("P7")->getString(), IN) == 0 ? INPUT:OUTPUT);
} }
p->getIOManager().getPcf().getPinModeAll(ioMode);//We retrieve the IO modes aka INPUT or OUTPUT p->getIoManager().getPcf().getPinModeAll(ioMode);//We retrieve the IO modes aka INPUT or OUTPUT
sprintf(buffer,"{\"status\":\"ok\",\"P0\":\"%s\",\"P1\":\"%s\",\"P2\":\"%s\",\"P3\":\"%s\",\"P4\":\"%s\",\"P5\":\"%s\",\"P6\":\"%s\",\"P7\":\"%s\"}",ioMode[0] ? OUT:IN,ioMode[1] ? OUT:IN,ioMode[2] ? OUT:IN,ioMode[3] ? OUT:IN,ioMode[4] ? OUT:IN,ioMode[5] ? OUT:IN,ioMode[6] ? OUT:IN,ioMode[7] ? OUT:IN); sprintf(buffer,"{\"status\":\"ok\",\"P0\":\"%s\",\"P1\":\"%s\",\"P2\":\"%s\",\"P3\":\"%s\",\"P4\":\"%s\",\"P5\":\"%s\",\"P6\":\"%s\",\"P7\":\"%s\"}",ioMode[0] ? OUT:IN,ioMode[1] ? OUT:IN,ioMode[2] ? OUT:IN,ioMode[3] ? OUT:IN,ioMode[4] ? OUT:IN,ioMode[5] ? OUT:IN,ioMode[6] ? OUT:IN,ioMode[7] ? OUT:IN);
WEBServer<WEBClient>::sendHTTPHeader(wc, HttpConstants::httpMIMETypeToString(HttpConstants::APPLICATION_JSON), strlen(buffer)); WEBServer<WEBClient>::sendHTTPHeader(wc, HttpConstants::httpMIMETypeToString(HttpConstants::APPLICATION_JSON), strlen(buffer));
@ -563,22 +563,22 @@ boolean ioSetModeApi(WEBServer<WEBClient>::HttpRequestData &HRD, WiFiClient *wc,
boolean swVersionApi(WEBServer<WEBClient>::HttpRequestData &HRD, WiFiClient *wc, void *pData) boolean swVersionApi(WEBServer<WEBClient>::HttpRequestData &HRD, WiFiClient *wc, void *pData)
{ {
(void)HRD; (void)HRD;
SAB *p = (SAB *)pData; (void)pData;
char buffer[100] = ""; char buffer[100] = "";
sprintf(buffer ,"{\"status\":\"ok\",\"version\":\"%s\"}", p->getSoftVersion()); sprintf(buffer ,"{\"status\":\"ok\",\"version\":\"%s\"}", SOFT_VERSION);
WEBServer<WEBClient>::sendHTTPHeader(wc, HttpConstants::httpMIMETypeToString(HttpConstants::APPLICATION_JSON), strlen(buffer)); WEBServer<WEBClient>::sendHTTPHeader(wc, HttpConstants::httpMIMETypeToString(HttpConstants::APPLICATION_JSON), strlen(buffer));
wc->print(buffer); wc->print(buffer);
return true; return true;
} }
boolean otaUpdateUploadApi(WEBServer<WEBClient>::HttpRequestData &HRD, WiFiClient *wc, void *pData) boolean otaUpdateApi(WEBServer<WEBClient>::HttpRequestData &HRD, WiFiClient *wc, void *pData)
{ {
(void)HRD; (void)HRD;
(void)pData; (void)pData;
Serial.printf("OTA Update Upload resquest\n#"); Serial.printf("OTA Update resquest\n#");
char buffer[30] = ""; char buffer[30] = "";
size_t read(0), cnt(0); size_t read(0), cnt(0);
@ -602,58 +602,3 @@ boolean otaUpdateUploadApi(WEBServer<WEBClient>::HttpRequestData &HRD, WiFiClien
return true; return true;
} }
boolean otaUpdateRemoteApi(WEBServer<WEBClient>::HttpRequestData &HRD, WiFiClient *wc, void *pData)
{
SAB *p = (SAB *)pData;
char buffer[100] = "";
boolean updateDevice(false);
if(!p->getOTAManager().isEnabled())
{
strcpy(buffer ,"{\"status\":\"ok\",\"ota\":\"disabled\"}");
}
else
{
OTAUpdater::UpdateInfo updateInfo = p->getOTAManager().getOTAUpdater().fetchUpdateInfo(p->getSoftVersion());
switch(updateInfo.info)
{
case OTAUpdater::UpdateInfo::HTTP_NO_UPDATE :
strcpy(buffer ,"{\"status\":\"ok\",\"ota\":\"enabled\",\"msg\":\"No update available\"}");
break;
case OTAUpdater::UpdateInfo::HTTP_UPDATE_AUTH_ERROR :
strcpy(buffer ,"{\"status\":\"error\",\"ota\":\"enabled\",\"msg\":\"OTA auth error\"}");
break;
case OTAUpdater::UpdateInfo::HTTP_UPDATE_AVAILABLE :
//Then we update the firmware
if(HRD.getParams("update") != NULL)
{
sprintf(buffer ,"{\"status\":\"ok\",\"ota\":\"enabled\",\"msg\":\"Updating the device, please wait\",\"version\":\"%s\"}", updateInfo.version);
updateDevice = true;
}
else //This means, we only want to get the new version number
{
sprintf(buffer ,"{\"status\":\"ok\",\"ota\":\"enabled\",\"msg\":\"Update available\",\"version\":\"%s\"}", updateInfo.version);
}
break;
case OTAUpdater::UpdateInfo::HTTP_UPDATE_REACH_ERROR :
strcpy(buffer ,"{\"status\":\"error\",\"ota\":\"enabled\",\"msg\":\"OTA reach error\"}");
break;
default:
strcpy(buffer ,"{\"status\":\"error\",\"ota\":\"enabled\",\"msg\":\"Undefined error\"}");
break;
}
}
WEBServer<WEBClient>::sendHTTPHeader(wc, HttpConstants::httpMIMETypeToString(HttpConstants::APPLICATION_JSON), strlen(buffer));
wc->print(buffer);
if(updateDevice)
{
p->getOTAManager().getOTAUpdater().update(p->getSoftVersion());
}
return true;
}

View File

@ -31,7 +31,6 @@ boolean ioSetLevelApi(WEBServer<WEBClient>::HttpRequestData&, WiFiClient*, void*
boolean ioGetModeApi(WEBServer<WEBClient>::HttpRequestData&, WiFiClient*, void*); boolean ioGetModeApi(WEBServer<WEBClient>::HttpRequestData&, WiFiClient*, void*);
boolean ioSetModeApi(WEBServer<WEBClient>::HttpRequestData&, WiFiClient*, void*); boolean ioSetModeApi(WEBServer<WEBClient>::HttpRequestData&, WiFiClient*, void*);
boolean swVersionApi(WEBServer<WEBClient>::HttpRequestData&, WiFiClient*, void*); boolean swVersionApi(WEBServer<WEBClient>::HttpRequestData&, WiFiClient*, void*);
boolean otaUpdateUploadApi(WEBServer<WEBClient>::HttpRequestData&, WiFiClient*, void*); boolean otaUpdateApi(WEBServer<WEBClient>::HttpRequestData&, WiFiClient*, void*);
boolean otaUpdateRemoteApi(WEBServer<WEBClient>::HttpRequestData&, WiFiClient*, void*);
#endif #endif