Compare commits

...

7 Commits

8 changed files with 127 additions and 42 deletions

View File

@ -1,5 +1,7 @@
#include "ConnectivityManager.h" #include "ConnectivityManager.h"
//#define DEBUG_CONMAN
ConnectivityManager::ConnectivityManager(bool persistent) ConnectivityManager::ConnectivityManager(bool persistent)
{ {
ConnectivityManager::persistent(persistent); ConnectivityManager::persistent(persistent);
@ -16,7 +18,7 @@ boolean ConnectivityManager::connect()
{ {
if(!WiFi.disconnect(true))_error |= STA_ENABLED_DISABLE_ERR; if(!WiFi.disconnect(true))_error |= STA_ENABLED_DISABLE_ERR;
if(!WiFi.softAPdisconnect(true))_error |= AP_ENABLED_DISABLE_ERR; if(!WiFi.softAPdisconnect(true))_error |= AP_ENABLED_DISABLE_ERR;
if(!softAP("ESP8266SwissArmyBoard", NULL, 1, false, 8))_error |= AP_SETUP_ERR; if(!softAP("ESP8266SwissArmyBoard"))_error |= AP_SETUP_ERR;
return _error == NO_ERROR; return _error == NO_ERROR;
} }
@ -32,30 +34,30 @@ boolean ConnectivityManager::connectToSTA()
CFGFileParser cfgFileParserSTA(*_sdCardManager, STA_CFG_FILE); CFGFileParser cfgFileParserSTA(*_sdCardManager, STA_CFG_FILE);
CFGDictionary<CFGParameterValue> *cfgDictionary = (CFGDictionary<CFGParameterValue> *) cfgFileParserSTA.parseFile(); CFGDictionary<CFGParameterValue> *cfgDictionary = (CFGDictionary<CFGParameterValue> *) cfgFileParserSTA.parseFile();
const char *PSK(nullptr);
uint8_t channel(0);
boolean toBeReturned(true); boolean toBeReturned(true);
if(!WiFi.disconnect(true))_error |= STA_ENABLED_DISABLE_ERR; if(!WiFi.disconnect(true))_error |= STA_ENABLED_DISABLE_ERR;
if(cfgDictionary != NULL) if(cfgDictionary != nullptr)
{ {
if((*cfgDictionary)("SSID") != NULL && (*cfgDictionary)("PASSWORD") != NULL && (*cfgDictionary)("ENABLED") != NULL) if((*cfgDictionary)("ENABLED") != nullptr && (*cfgDictionary)("SSID") != nullptr)
{ {
if((*cfgDictionary)("ENABLED")->booleanValue()) if((*cfgDictionary)("ENABLED")->booleanValue())
{ {
if(!begin((*cfgDictionary)("SSID")->stringValue(), (*cfgDictionary)("PASSWORD")->stringValue())) if((*cfgDictionary)("PASSWORD") != nullptr)
PSK = (*cfgDictionary)("PASSWORD")->stringValue();
if((*cfgDictionary)("CHANNEL") != nullptr)
channel = (*cfgDictionary)("CHANNEL")->intValue();
if(!begin((*cfgDictionary)("SSID")->stringValue(), PSK, channel))
{ {
_error |= STA_SETUP_ERR; _error |= STA_SETUP_ERR;
toBeReturned = false; toBeReturned = false;
} }
} }
} }
else
toBeReturned = false;
delete cfgDictionary; delete cfgDictionary;
} }
else
toBeReturned = false;
return toBeReturned; return toBeReturned;
} }
@ -63,35 +65,76 @@ boolean ConnectivityManager::startAP()
{ {
CFGFileParser cfgFileParser(*_sdCardManager, AP_CFG_FILE); CFGFileParser cfgFileParser(*_sdCardManager, AP_CFG_FILE);
CFGDictionary<CFGParameterValue> *cfgDictionary = (CFGDictionary<CFGParameterValue> *) cfgFileParser.parseFile(); CFGDictionary<CFGParameterValue> *cfgDictionary = (CFGDictionary<CFGParameterValue> *) cfgFileParser.parseFile();
const char defaultSSID[] = "ESP8266SwissArmyBoard";
const char *SSID(defaultSSID);
const char *PSK(nullptr);
uint8_t channel(1), maxConnection(4);
boolean hideSSID(false);
boolean toBeReturned(true); boolean toBeReturned(true);
if(!WiFi.softAPdisconnect(true))_error |= AP_ENABLED_DISABLE_ERR; if(!WiFi.softAPdisconnect(true))_error |= AP_ENABLED_DISABLE_ERR;
if(cfgDictionary == NULL) if(cfgDictionary == nullptr)
{ {
if(!softAP("ESP8266SwissArmyBoard", NULL, 1, false, 8))_error |= AP_SETUP_ERR; if(!softAP(defaultSSID))
return false;
}
else if((*cfgDictionary)("SSID") != NULL && (*cfgDictionary)("PASSWORD") != NULL && (*cfgDictionary)("CHANNEL") != NULL && (*cfgDictionary)("HIDE_SSID") != NULL && (*cfgDictionary)("AP_MAX_CONNECTION") != NULL && (*cfgDictionary)("ENABLED") != NULL)
{
if((*cfgDictionary)("ENABLED")->booleanValue())
{
if(!softAP((*cfgDictionary)("SSID")->stringValue(), strcmp((*cfgDictionary)("PASSWORD")->stringValue(),"") == 0 ? NULL:(*cfgDictionary)("PASSWORD")->stringValue(), (*cfgDictionary)("CHANNEL")->intValue(), (*cfgDictionary)("HIDE_SSID")->booleanValue(), (*cfgDictionary)("AP_MAX_CONNECTION")->intValue()))
{ {
_error |= AP_SETUP_ERR; _error |= AP_SETUP_ERR;
toBeReturned = false; toBeReturned = false;
} }
} }
else
{
if((*cfgDictionary)("ENABLED") != nullptr)
{
if((*cfgDictionary)("ENABLED")->booleanValue())
{
if((*cfgDictionary)("SSID") != nullptr)
SSID = (*cfgDictionary)("SSID")->stringValue();
if((*cfgDictionary)("PASSWORD") != nullptr)
PSK = (*cfgDictionary)("PASSWORD")->stringValue();
if((*cfgDictionary)("CHANNEL") != nullptr)
channel = (*cfgDictionary)("CHANNEL")->intValue();
if((*cfgDictionary)("HIDE_SSID") != nullptr)
hideSSID = (*cfgDictionary)("HIDE_SSID")->booleanValue();
if((*cfgDictionary)("AP_MAX_CONNECTION") != nullptr)
maxConnection = (*cfgDictionary)("AP_MAX_CONNECTION")->intValue();
#ifdef DEBUG_CONMAN
Serial.printf("AP is enabled, params are :\nSSID : %s\nPSK : %s\nCHAN : %u\nHIDE_SSID : %u\nMAX_CON : %u\n",
SSID,
PSK ? PSK : "",
channel,
hideSSID,
maxConnection);
#endif
if(!softAP(SSID, PSK, channel, hideSSID, maxConnection))
{
_error |= AP_SETUP_ERR;
toBeReturned = false;
}
} }
else else
{ {
if(!softAP("ESP8266SwissArmyBoard", NULL, 1, false, 8))_error |= AP_SETUP_ERR; #ifdef DEBUG_CONMAN
Serial.printf("AP is disabled, nothing to be done\n");
#endif
}
}
else //If the enable parameter is not specified we start the AP by default.
{
#ifdef DEBUG_CONMAN
Serial.printf("ENABLED param missing, enabling AP\n");
#endif
if(!softAP(SSID, PSK, channel, hideSSID, maxConnection))
{
_error |= AP_SETUP_ERR;
toBeReturned = false; toBeReturned = false;
} }
}
delete cfgDictionary; delete cfgDictionary;
}
return toBeReturned; return toBeReturned;
} }

View File

@ -27,7 +27,7 @@ class FTPServer : public TCPServer<T>
{ {
if (login != NULL) if (login != NULL)
{ {
if (strlen(login) > 0) if (strlen(login))
{ {
_login = (char *)malloc((sizeof(char) * strlen(login)) + 1); _login = (char *)malloc((sizeof(char) * strlen(login)) + 1);
strcpy(_login, login); strcpy(_login, login);
@ -36,7 +36,7 @@ class FTPServer : public TCPServer<T>
if (password != NULL) if (password != NULL)
{ {
if (strlen(password) > 0) if (strlen(password))
{ {
_password = (char *)malloc((sizeof(char) * strlen(password)) + 1); _password = (char *)malloc((sizeof(char) * strlen(password)) + 1);
strcpy(_password, password); strcpy(_password, password);
@ -53,7 +53,7 @@ class FTPServer : public TCPServer<T>
virtual ~FTPServer() virtual ~FTPServer()
{ {
_dataServer.stop(); _dataServer.stop();
free(_login); free(_password); free(_login); free(_password); free(_FTPDir);
} }
virtual void stop() virtual void stop()
@ -67,7 +67,12 @@ class FTPServer : public TCPServer<T>
virtual void setFTPDir(const char *FTPDir) virtual void setFTPDir(const char *FTPDir)
{ {
_FTPDir = FTPDir; if(FTPDir)
{
free(_FTPDir);
_FTPDir = (char *)malloc((strlen(FTPDir) * sizeof(char)) + 1);
strcpy(_FTPDir, FTPDir);
}
} }
protected: protected:
@ -1028,7 +1033,7 @@ class FTPServer : public TCPServer<T>
char *_login; char *_login;
char *_password; char *_password;
const char *_FTPDir = NULL; //Pointer to constant string and char * const is a constant pointer to string char *_FTPDir = nullptr;
uint16_t _dataPort; uint16_t _dataPort;
WiFiServer _dataServer; //In passive mode, the FTP server opens two different ports (one for the commands and the other for the data stream) WiFiServer _dataServer; //In passive mode, the FTP server opens two different ports (one for the commands and the other for the data stream)

View File

@ -174,9 +174,7 @@ class TCPServer
return; return;
} }
_clientList.addFirst(_currentClient); _clientList.addFirst(_currentClient);
} }
virtual void processClientData(T *client) virtual void processClientData(T *client)

View File

@ -42,6 +42,11 @@ class WEBServer : public TCPServer<T>, public HttpConstants
WEBServer(uint16_t port = 80, SDClass *sdClass = NULL, uint8_t maxClient = MAX_CLIENT, uint16_t clientDataBufferSize = 256) : TCPServer<T>(port, maxClient, clientDataBufferSize), _sdClass(sdClass) {} WEBServer(uint16_t port = 80, SDClass *sdClass = NULL, uint8_t maxClient = MAX_CLIENT, uint16_t clientDataBufferSize = 256) : TCPServer<T>(port, maxClient, clientDataBufferSize), _sdClass(sdClass) {}
virtual ~WEBServer()
{
free(_WWWDir);
}
boolean addApiRoutine(const char *uri, boolean (*apiRoutine)(HttpRequestData&, WiFiClient*, void*), void *pData, HttpRequestMethod HRM = UNDEFINED) boolean addApiRoutine(const char *uri, boolean (*apiRoutine)(HttpRequestData&, WiFiClient*, void*), void *pData, HttpRequestMethod HRM = UNDEFINED)
{ {
return _apiDictionary.add(uri, new ApiRoutine({apiRoutine, pData, HRM})); return _apiDictionary.add(uri, new ApiRoutine({apiRoutine, pData, HRM}));
@ -72,7 +77,12 @@ class WEBServer : public TCPServer<T>, public HttpConstants
void setWWWDir(const char *WWWDir) void setWWWDir(const char *WWWDir)
{ {
_WWWDir = WWWDir; if(WWWDir != nullptr)
{
free(_WWWDir);
_WWWDir = (char *)malloc((strlen(WWWDir) * sizeof(char)) + 1);
strcpy(_WWWDir, WWWDir);
}
} }
protected: protected:
private: private:
@ -165,11 +175,14 @@ class WEBServer : public TCPServer<T>, public HttpConstants
case HttpParserStatus::PARSE_HTTP_RESOURCE: case HttpParserStatus::PARSE_HTTP_RESOURCE:
{ {
char *pRsrc(strchr((char *)client->_data, ' ')), *pRsrcQuery(strchr((char *)client->_data, '?')); char *pRsrc(strchr((char *)client->_data, ' ')), *pRsrcQuery(strchr((char *)client->_data, '?'));
//!\ the ? should be present before ' ' if ' ' is found !!!!
if(pRsrc && pRsrcQuery)
if(pRsrcQuery > pRsrc)pRsrcQuery = nullptr;
//The case where we have the resource complete or not complete with query parameters like : GET /some/path/resource.rsrc?param1=one&param2 HTTP/1.1 //The case where we have the resource complete or not complete with query parameters like : GET /some/path/resource.rsrc?param1=one&param2 HTTP/1.1
if(pRsrc || pRsrcQuery) if(pRsrc || pRsrcQuery)
{ {
uint16_t rawLengthOfResource(0); uint16_t rawLengthOfResource(0);
if(pRsrcQuery) if(pRsrcQuery )
{ {
*pRsrcQuery = '\0'; // The ? is the end of the resource string *pRsrcQuery = '\0'; // The ? is the end of the resource string
rawLengthOfResource = pRsrcQuery - (char *)client->_data; rawLengthOfResource = pRsrcQuery - (char *)client->_data;
@ -182,7 +195,7 @@ class WEBServer : public TCPServer<T>, public HttpConstants
*pRsrc = '\0'; *pRsrc = '\0';
rawLengthOfResource = pRsrc - (char *)client->_data; rawLengthOfResource = pRsrc - (char *)client->_data;
#ifdef DEBUG_WEBS #ifdef DEBUG_WEBS
Serial.printf("Resource w/o query\n"); Serial.printf("Resource w/o query\nRaw length : %u\n",rawLengthOfResource);
#endif #endif
} }
@ -937,7 +950,7 @@ class WEBServer : public TCPServer<T>, public HttpConstants
Dictionary<ApiRoutine> _apiDictionary; Dictionary<ApiRoutine> _apiDictionary;
SDClass *_sdClass; SDClass *_sdClass;
const char *_WWWDir = NULL; //Website root folder char *_WWWDir = nullptr; //Website root folder
}; };
#endif //WEBSERVER_H #endif //WEBSERVER_H

View File

@ -42,7 +42,8 @@ void setup()
if(cfgDictionary != NULL) if(cfgDictionary != NULL)
{ {
Serial.print("AP PASSWORD : ");if((*cfgDictionary)("PASSWORD") != NULL)Serial.println((*cfgDictionary)("PASSWORD")->stringValue()); Serial.printf("AP PASSWORD : %s\n",
(*cfgDictionary)("PASSWORD") ? (*cfgDictionary)("PASSWORD")->stringValue() : "");
} }
#if 0 #if 0
@ -92,6 +93,7 @@ void setup()
sab.getWebServer().addApiRoutine("/sab/io/set/level", &(ioSetLevelApi), &sab, WEBServer<WEBClient>::GET); sab.getWebServer().addApiRoutine("/sab/io/set/level", &(ioSetLevelApi), &sab, WEBServer<WEBClient>::GET);
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/ota/update", &(otaUpdateApi), NULL, WEBServer<WEBClient>::POST);
sab.getIoManager().setISROnIOChange(&(ioISR), GPIO_3_RX); sab.getIoManager().setISROnIOChange(&(ioISR), GPIO_3_RX);

View File

@ -557,3 +557,26 @@ boolean ioSetModeApi(WEBServer<WEBClient>::HttpRequestData &HRD, WiFiClient *wc,
wc->print(buffer); wc->print(buffer);
return true; return true;
} }
boolean otaUpdateApi(WEBServer<WEBClient>::HttpRequestData &HRD, WiFiClient *wc, void *pData)
{
Serial.printf("OTA Update resquest\n");
char buffer[500];
size_t read(0);
while(wc->available())
{
read = wc->read(buffer, 500);
for(uint8_t i(0); i < read; i++)
Serial.printf("%02X %s",buffer[i], i % 30 == 0 ? "\n" : "");
yield();
}
WEBServer<WEBClient>::sendHTTPHeader(wc, HttpConstants::httpMIMETypeToString(HttpConstants::TEXT_PLAIN), 2);
wc->print("OK");
//wc->peekBuffer
return true;
}

View File

@ -30,5 +30,6 @@ boolean ioGetLevelApi(WEBServer<WEBClient>::HttpRequestData&, WiFiClient*, void*
boolean ioSetLevelApi(WEBServer<WEBClient>::HttpRequestData&, WiFiClient*, void*); 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 otaUpdateApi(WEBServer<WEBClient>::HttpRequestData&, WiFiClient*, void*);
#endif #endif