Added the WEBServerManager class to enable the initialization of the WEBServer using a config file, I might change the behaviour of this initialization when some parameters are missing, renamed the old WEBServerManager class to WEBServerManager_deprecated, now using the new WEBServerManager in the SAB object instead of the WEBServer directly, minor changes to the OTAManager, migrating the dashboard v2 layout so that every tile has the same size
This commit is contained in:
parent
a23fb4cba9
commit
a951cdd6fc
@ -7,7 +7,7 @@
|
|||||||
|
|
||||||
WEB_ENABLED : 'true'
|
WEB_ENABLED : 'true'
|
||||||
WEB_PORT : 80
|
WEB_PORT : 80
|
||||||
WEB_MAX_CLIENT : 0
|
WEB_MAX_CLIENT : 10
|
||||||
WEB_WWW_DIR : '/WWW'
|
WEB_WWW_DIR : '/WWW'
|
||||||
FTP_ENABLED : 'true'
|
FTP_ENABLED : 'true'
|
||||||
FTP_LOGIN : 'ESP8266'
|
FTP_LOGIN : 'ESP8266'
|
||||||
@ -15,4 +15,4 @@ FTP_PASSWORD : '12345678'
|
|||||||
FTP_ROOT_DIR : '/FTP'
|
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 : 10
|
||||||
|
@ -14,6 +14,10 @@
|
|||||||
{
|
{
|
||||||
/*flex: 1 0 auto;*/
|
/*flex: 1 0 auto;*/
|
||||||
}
|
}
|
||||||
|
|
||||||
|
td,tr
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
.switch label input[type=checkbox]:checked+.lever
|
.switch label input[type=checkbox]:checked+.lever
|
||||||
{
|
{
|
||||||
@ -116,18 +120,28 @@
|
|||||||
</div>
|
</div>
|
||||||
<!-- End of modal window definition -->
|
<!-- End of modal window definition -->
|
||||||
<section id="mainpage_id">
|
<section id="mainpage_id">
|
||||||
<div class="row">
|
<table>
|
||||||
<div class="row col m6">
|
<tr>
|
||||||
<div style="margin:10px;padding:5px 0 10px 0;" class="grey lighten-2 z-depth-3">
|
<td colspan="2" style="width: 50%;">
|
||||||
<h5 class="center-align">Connectivity</h5>
|
<div style="margin:10px;padding:5px 0 10px 0;" class="grey lighten-2 z-depth-3">
|
||||||
</div>
|
<h5 class="center-align">Connectivity</h5>
|
||||||
<div class="col m6">
|
|
||||||
<div class="card teal darken-1">
|
|
||||||
<div class="card-content white-text">
|
|
||||||
<span class="card-title center-align" style="font-weight:bold;">Access Point Mode</span>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="card-action center-align">
|
</td>
|
||||||
<div class="switch">
|
<td colspan="2" style="width: 50%;">
|
||||||
|
<div style="margin:10px;padding:5px 0 10px 0;" class="grey lighten-2 z-depth-3">
|
||||||
|
<h5 class="center-align">System Info</h5>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td colspan="4">
|
||||||
|
<div class="row" style="display:flex;">
|
||||||
|
<div class="teal darken-1 col m3" style="margin: 7px 22px 7px 22px;border-radius: 5px;padding-bottom: 15px;">
|
||||||
|
<div class="white-text">
|
||||||
|
<h5 style="font-weight:bold;" class="center-align">Access Point Mode</h5>
|
||||||
|
</div>
|
||||||
|
<hr>
|
||||||
|
<div class="switch center-align">
|
||||||
<label class="white-text">
|
<label class="white-text">
|
||||||
Disabled
|
Disabled
|
||||||
<input type="checkbox">
|
<input type="checkbox">
|
||||||
@ -145,24 +159,20 @@
|
|||||||
</div>
|
</div>
|
||||||
<input placeholder="SSID" id="ssid" type="text" class="validate white-text">
|
<input placeholder="SSID" id="ssid" type="text" class="validate white-text">
|
||||||
<input onmouseleave="showHidePassword('pwd','hide')" onmouseover="showHidePassword('pwd','show');" value="somePassword" placeholder="Password" id="pwd" type="password" class="validate white-text">
|
<input onmouseleave="showHidePassword('pwd','hide')" onmouseover="showHidePassword('pwd','show');" value="somePassword" placeholder="Password" id="pwd" type="password" class="validate white-text">
|
||||||
|
<hr>
|
||||||
|
<div class="center-align">
|
||||||
|
<button class="btn waves-effect waves-light green darken-3" type="submit" name="apply">
|
||||||
|
Apply ✔
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="card-action">
|
|
||||||
<button class="btn waves-effect waves-light green darken-3" type="submit" name="apply">
|
<div class="teal darken-1 col m3" style="margin: 7px 22px 7px 22px;border-radius: 5px;padding-bottom: 15px;">
|
||||||
Apply ✔
|
<div class="white-text">
|
||||||
</button>
|
<h5 style="font-weight:bold;" class="center-align">Station Mode</h5>
|
||||||
<button class="btn waves-effect waves-light red darken-3" style="" type="submit" name="cancel">
|
</div>
|
||||||
Cancel ✘
|
<hr>
|
||||||
</button>
|
<div class="switch center-align">
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="col m6">
|
|
||||||
<div class="card teal darken-1">
|
|
||||||
<div class="card-content white-text">
|
|
||||||
<span class="card-title center-align" style="font-weight:bold;">Station Mode</span>
|
|
||||||
</div>
|
|
||||||
<div class="card-action center-align">
|
|
||||||
<div class="switch">
|
|
||||||
<label class="white-text">
|
<label class="white-text">
|
||||||
Disabled
|
Disabled
|
||||||
<input type="checkbox">
|
<input type="checkbox">
|
||||||
@ -179,31 +189,30 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<select id="networksSelect">
|
<select id="networksSelect">
|
||||||
<option value="" disabled selected>Click on scan</option>
|
<option value="" disabled selected>Click on scan</option>
|
||||||
</select>
|
</select>
|
||||||
<input placeholder="Password" id="pwd" type="password" class="validate white-text">
|
<input placeholder="Password" id="pwd" type="password" class="validate white-text">
|
||||||
</div>
|
<hr>
|
||||||
<div class="card-action">
|
<div class="row">
|
||||||
<button class="btn waves-effect waves-light green darken-3" type="submit" name="apply">
|
<div class="col m6">
|
||||||
Connect
|
<button class="btn waves-effect waves-light green darken-3" type="submit" name="apply">
|
||||||
</button>
|
Connect
|
||||||
<button class="btn waves-effect waves-light lime darken-3" style="" onclick="scanAvailableNetworks();" type="submit" name="Scan">
|
</button>
|
||||||
Scan
|
</div>
|
||||||
</button>
|
<div class="col m6 right-align">
|
||||||
</div>
|
<button class="btn waves-effect waves-light lime darken-3" style="" onclick="scanAvailableNetworks();" type="submit" name="Scan">
|
||||||
</div>
|
Scan
|
||||||
</div>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<div class="row col m6">
|
|
||||||
<div style="margin:10px;padding:5px 0 10px 0;" class="grey lighten-2 z-depth-3">
|
|
||||||
<h5 class="center-align">System Info</h5>
|
|
||||||
</div>
|
|
||||||
<div class="col m12">
|
|
||||||
<div class="card teal darken-1">
|
|
||||||
<div class="card-content white-text">
|
|
||||||
<span class="card-title center-align" style="font-weight:bold;">System State</span>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="card-action white-text" style="font-size:1.2em;">
|
</div>
|
||||||
|
|
||||||
|
<div class="teal darken-1 col m6" style="margin: 7px 22px 7px 22px;border-radius: 5px;padding-bottom: 15px;">
|
||||||
|
<div class="white-text">
|
||||||
|
<h5 style="font-weight:bold;" class="center-align">System State</h5>
|
||||||
|
</div>
|
||||||
|
<hr>
|
||||||
|
<div class="white-text" style="font-size:1.2em;">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col m6">
|
<div class="col m6">
|
||||||
Cpu frequency :
|
Cpu frequency :
|
||||||
@ -242,79 +251,131 @@
|
|||||||
<div class="col m6">
|
<div class="col m6">
|
||||||
<span id="upTime"></span>
|
<span id="upTime"></span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</td>
|
||||||
</div>
|
</tr>
|
||||||
|
<tr>
|
||||||
<div class="row" style="margin-top:-20px;">
|
<td>
|
||||||
<div class="row col m3">
|
|
||||||
<div style="margin:10px;padding:5px 0 10px 0;" class="grey lighten-2 z-depth-3">
|
<div style="margin:10px;padding:5px 0 10px 0;" class="grey lighten-2 z-depth-3">
|
||||||
<h5 class="center-align">Clock</h5>
|
<h5 class="center-align">Clock</h5>
|
||||||
</div>
|
</div>
|
||||||
<div class="col m12">
|
</td>
|
||||||
<div class="card teal darken-1">
|
<td>
|
||||||
<div class="card-content white-text">
|
<div style="margin:10px;padding:5px 0 10px 0;" class="grey lighten-2 z-depth-3">
|
||||||
<span class="card-title center-align" style="font-weight:bold;">DS3231 RTC</span>
|
<h5 class="center-align">Storage</h5>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
<td colspan="2">
|
||||||
|
<div style="margin:10px;padding:5px 0 10px 0;" class="grey lighten-2 z-depth-3">
|
||||||
|
<h5 class="center-align">Services</h5>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td colspan="4">
|
||||||
|
<div class="row" style="display:flex;">
|
||||||
|
<div class="teal darken-1 col m3" style="margin: 7px 22px 7px 22px;border-radius: 5px;padding-bottom: 15px;">
|
||||||
|
<div class="white-text">
|
||||||
|
<h5 style="font-weight:bold;" class="center-align">DS3231 RTC</h5>
|
||||||
|
</div>
|
||||||
|
<hr>
|
||||||
|
<div style="font-size:1.2em;">
|
||||||
|
<input type="text" class="datepicker" id="datepicker_id">
|
||||||
|
<input type="text" class="timepicker" id="timepicker_id">
|
||||||
|
</div>
|
||||||
|
<hr>
|
||||||
|
<div class="row">
|
||||||
|
<div class="col m6">
|
||||||
|
<button class="btn waves-effect waves-light green darken-3" onclick="setRtcTime();" name="apply">
|
||||||
|
Apply ✔
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<div class="col m6 right-align">
|
||||||
|
<button class="btn waves-effect waves-light green darken-3 tooltipped" onclick="setRtc2BrowserTime();" data-position="bottom" data-tooltip="Use the browser time to set the RTC time" name="browserTime">
|
||||||
|
Set browser time ✔
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="teal darken-1 col m3" style="margin: 7px 22px 7px 22px;border-radius: 5px;padding-bottom: 15px;">
|
||||||
<div class="card-action" style="font-size:1.2em;">
|
<div class="white-text">
|
||||||
<input type="text" class="datepicker" id="datepicker_id">
|
<h5 style="font-weight:bold;" class="center-align">SD Card</h5>
|
||||||
<input type="text" class="timepicker" id="timepicker_id">
|
</div>
|
||||||
</div>
|
<hr>
|
||||||
<div class="card-action">
|
<div class="white-text center-align" style="font-size:1.2em;">
|
||||||
<button class="btn waves-effect waves-light green darken-3" onclick="setRtcTime();" name="apply">
|
<div class="switch">
|
||||||
Apply ✔
|
<label class="white-text">
|
||||||
</button>
|
Unmounted
|
||||||
<button class="btn waves-effect waves-light green darken-3 tooltipped" onclick="setRtc2BrowserTime();" data-position="bottom" data-tooltip="Use the browser time to set the RTC time" name="browserTime">
|
<input type="checkbox" id="sdcardmounted_id" onchange="mountUnmountCard('sdcardmounted_id');">
|
||||||
Set browser time ✔
|
<span class="lever"></span>
|
||||||
</button>
|
Mounted
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
<div class="row left-align">
|
||||||
|
<div class="col m6">
|
||||||
|
Size :
|
||||||
|
</div>
|
||||||
|
<div class="col m6">
|
||||||
|
<span id="cardSize">NaN Gbytes</span>
|
||||||
|
</div>
|
||||||
|
<div class="col m6">
|
||||||
|
Free :
|
||||||
|
</div>
|
||||||
|
<div class="col m6">
|
||||||
|
XX GBytes
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
<div class="row" style="margin-top:-20px;">
|
||||||
|
<div class="row col m3">
|
||||||
|
<div class="col m12">
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="row col m3">
|
<div class="row col m3">
|
||||||
<div style="margin:10px;padding:5px 0 10px 0;" class="grey lighten-2 z-depth-3">
|
|
||||||
<h5 class="center-align">Storage</h5>
|
|
||||||
</div>
|
|
||||||
<div class="col m12">
|
<div class="col m12">
|
||||||
<div class="card teal darken-1">
|
|
||||||
<div class="card-content white-text">
|
|
||||||
<span class="card-title center-align" style="font-weight:bold;">SD Card</span>
|
|
||||||
</div>
|
|
||||||
<div class="card-action white-text center-align" style="font-size:1.2em;">
|
|
||||||
<div class="switch">
|
|
||||||
<label class="white-text">
|
|
||||||
Unmounted
|
|
||||||
<input type="checkbox" id="sdcardmounted_id" onchange="mountUnmountCard('sdcardmounted_id');">
|
|
||||||
<span class="lever"></span>
|
|
||||||
Mounted
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
<div class="row left-align">
|
|
||||||
<div class="col m6">
|
|
||||||
Size :
|
|
||||||
</div>
|
|
||||||
<div class="col m6">
|
|
||||||
<span id="cardSize">NaN Gbytes</span>
|
|
||||||
</div>
|
|
||||||
<div class="col m6">
|
|
||||||
Free :
|
|
||||||
</div>
|
|
||||||
<div class="col m6">
|
|
||||||
XX GBytes
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="col m6">
|
<div class="col m6">
|
||||||
<div style="margin:10px;padding:5px 0 10px 0;" class="grey lighten-2 z-depth-3">
|
|
||||||
<h5 class="center-align">Services</h5>
|
|
||||||
</div>
|
|
||||||
<div class="col m6">
|
<div class="col m6">
|
||||||
<div class="card teal darken-1">
|
<div class="card teal darken-1">
|
||||||
<div class="card-content white-text">
|
<div class="card-content white-text">
|
||||||
|
@ -2,7 +2,6 @@
|
|||||||
#include "definition.h"
|
#include "definition.h"
|
||||||
|
|
||||||
#define DEBUG_OTA_MANAGER(...) do {} while(0)
|
#define DEBUG_OTA_MANAGER(...) do {} while(0)
|
||||||
|
|
||||||
//#define DEBUG_OTA_MANAGER(...) do { Serial.printf(__VA_ARGS__); Serial.println();} 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(SDCardManager &sdCardManager, const BoardConfig &boardConfig) : _sdCardManager(&sdCardManager), _boardConfig(&boardConfig)
|
||||||
@ -12,18 +11,11 @@ OTAManager::~OTAManager()
|
|||||||
{ }
|
{ }
|
||||||
|
|
||||||
boolean OTAManager::init(void)
|
boolean OTAManager::init(void)
|
||||||
{
|
{
|
||||||
//If the SDCardManager is not available, then we disable the OTA service
|
//We try to read the config file
|
||||||
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);
|
CFGDictionary<CFGParameterValue> *otaCfg = _sdCardManager->getCFGFile(OTA_CFG_FILE);
|
||||||
boolean toReturn(true);
|
boolean toReturn(true);
|
||||||
//If we did not find the file
|
//If we did not find the file or we didn't manage to open it !
|
||||||
if(!otaCfg)
|
if(!otaCfg)
|
||||||
{
|
{
|
||||||
DEBUG_OTA_MANAGER("otaCfg is NULL !");
|
DEBUG_OTA_MANAGER("otaCfg is NULL !");
|
||||||
@ -68,13 +60,17 @@ boolean OTAManager::init(void)
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
DEBUG_OTA_MANAGER("OTA_SERVER_ADDRESS is NULL !");
|
DEBUG_OTA_MANAGER("OTA_SERVER_ADDRESS is NULL !");
|
||||||
|
_isServiceEnabled = false;
|
||||||
toReturn = false;
|
toReturn = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
_isServiceEnabled = false;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
DEBUG_OTA_MANAGER("ENABLED is NULL !");
|
DEBUG_OTA_MANAGER("ENABLED is NULL !");
|
||||||
|
_isServiceEnabled = false;
|
||||||
toReturn = false;
|
toReturn = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -14,9 +14,10 @@ class OTAManager
|
|||||||
boolean init(void);
|
boolean init(void);
|
||||||
boolean isEnabled(void) const;
|
boolean isEnabled(void) const;
|
||||||
OTAUpdater& getOTAUpdater(void);
|
OTAUpdater& getOTAUpdater(void);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
OTAManager(SDCardManager &sdCardManager, const BoardConfig &boardConfig);
|
OTAManager(SDCardManager &sdCardManager, const BoardConfig &boardConfig);
|
||||||
OTAManager();
|
|
||||||
private:
|
private:
|
||||||
void updateStartedCb(void);
|
void updateStartedCb(void);
|
||||||
void updateFinishedCb(void);
|
void updateFinishedCb(void);
|
||||||
@ -27,6 +28,7 @@ class OTAManager
|
|||||||
SDCardManager *_sdCardManager = nullptr;
|
SDCardManager *_sdCardManager = nullptr;
|
||||||
const BoardConfig * _boardConfig = nullptr;
|
const BoardConfig * _boardConfig = nullptr;
|
||||||
boolean _isServiceEnabled = false;
|
boolean _isServiceEnabled = false;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif //OTAMANAGER_H
|
#endif //OTAMANAGER_H
|
@ -4,7 +4,7 @@ SAB::SAB() : _sdCardManager(_boardConfig.getSPI_SDCard_cs(), _boardConfig.getSPI
|
|||||||
_display(_boardConfig.getScreenWidth(),_boardConfig.getScreenHeight(), &Wire),
|
_display(_boardConfig.getScreenWidth(),_boardConfig.getScreenHeight(), &Wire),
|
||||||
_screenManager(_display, &_sdCardManager),
|
_screenManager(_display, &_sdCardManager),
|
||||||
_connectivityManager(_sdCardManager),
|
_connectivityManager(_sdCardManager),
|
||||||
_webServer(80, &_sdCardManager, 10),
|
_webServerManager(_sdCardManager),
|
||||||
_ftpServer(&_sdCardManager, 21, "ESP8266", "12345678", 10),
|
_ftpServer(&_sdCardManager, 21, "ESP8266", "12345678", 10),
|
||||||
_otaManager(_sdCardManager, _boardConfig),
|
_otaManager(_sdCardManager, _boardConfig),
|
||||||
_dbWSServer(81),
|
_dbWSServer(81),
|
||||||
@ -15,12 +15,12 @@ _taskSchedulerManager(_rtcManager)
|
|||||||
initCommonConfig();
|
initCommonConfig();
|
||||||
}
|
}
|
||||||
|
|
||||||
SAB::SAB(const BoardConfig boardConfig, const unsigned int webServerPort, const unsigned int ftpServerPort) : _boardConfig(boardConfig),
|
SAB::SAB(const BoardConfig boardConfig, const unsigned int ftpServerPort) : _boardConfig(boardConfig),
|
||||||
_sdCardManager(_boardConfig.getSPI_SDCard_cs(), _boardConfig.getSPISpeed()),
|
_sdCardManager(_boardConfig.getSPI_SDCard_cs(), _boardConfig.getSPISpeed()),
|
||||||
_display(_boardConfig.getScreenWidth(), _boardConfig.getScreenHeight(), &Wire),
|
_display(_boardConfig.getScreenWidth(), _boardConfig.getScreenHeight(), &Wire),
|
||||||
_screenManager(_display, &_sdCardManager),
|
_screenManager(_display, &_sdCardManager),
|
||||||
_connectivityManager(_sdCardManager),
|
_connectivityManager(_sdCardManager),
|
||||||
_webServer(webServerPort, &_sdCardManager, 10),
|
_webServerManager(_sdCardManager),
|
||||||
_ftpServer(&_sdCardManager, ftpServerPort, "ESP8266", "12345678", 10),
|
_ftpServer(&_sdCardManager, ftpServerPort, "ESP8266", "12345678", 10),
|
||||||
_otaManager(_sdCardManager, _boardConfig),
|
_otaManager(_sdCardManager, _boardConfig),
|
||||||
_dbWSServer(81),
|
_dbWSServer(81),
|
||||||
@ -64,16 +64,14 @@ void SAB::initCommonConfig()
|
|||||||
_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;}
|
if(!_otaManager.init()){_error |= OTAMAN_INIT_ERR;}
|
||||||
|
if(!_webServerManager.init()){_error |= WEBSRVMAN_INIT_ERR;}
|
||||||
|
|
||||||
//We set the different servers :
|
//We set the different servers :
|
||||||
_webServer.setWWWDir(WWW_DIR);
|
|
||||||
_ftpServer.setFTPDir(FTP_DIR);
|
_ftpServer.setFTPDir(FTP_DIR);
|
||||||
//We start the servers
|
//We start the servers
|
||||||
_dbWSServer.begin();
|
_dbWSServer.begin();
|
||||||
_webServer.enableTCPKeepAlive(15,5,5);
|
|
||||||
_ftpServer.enableTCPKeepAlive(15,5,5);
|
_ftpServer.enableTCPKeepAlive(15,5,5);
|
||||||
_webServer.start();
|
|
||||||
_ftpServer.start();
|
_ftpServer.start();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -106,9 +104,9 @@ ConnectivityManager& SAB::getConnectivityManager()
|
|||||||
return _connectivityManager;
|
return _connectivityManager;
|
||||||
}
|
}
|
||||||
|
|
||||||
WEBServer<WEBClient>& SAB::getWebServer()
|
WEBServerManager& SAB::getWebServerManager()
|
||||||
{
|
{
|
||||||
return _webServer;
|
return _webServerManager;
|
||||||
}
|
}
|
||||||
|
|
||||||
FTPServer<FTPClient>& SAB::getFtpServer()
|
FTPServer<FTPClient>& SAB::getFtpServer()
|
||||||
@ -158,7 +156,7 @@ uint8_t SAB::getError() const
|
|||||||
|
|
||||||
void SAB::run()
|
void SAB::run()
|
||||||
{
|
{
|
||||||
_webServer.run();
|
_webServerManager.getWEBServer().run();
|
||||||
_ftpServer.run();
|
_ftpServer.run();
|
||||||
_taskSchedulerManager.run();
|
_taskSchedulerManager.run();
|
||||||
_screenManager.run();
|
_screenManager.run();
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
#include "ScreenManager.h"
|
#include "ScreenManager.h"
|
||||||
#include "SDCardManager.h"
|
#include "SDCardManager.h"
|
||||||
#include "ConnectivityManager.h"
|
#include "ConnectivityManager.h"
|
||||||
#include "WEBClient.h" //includes WEBServer internally
|
#include "WEBServerManager.h"
|
||||||
#include "FTPClient.h" //includes FTPServer internally
|
#include "FTPClient.h" //includes FTPServer internally
|
||||||
#include "DashboardWSServer.h"
|
#include "DashboardWSServer.h"
|
||||||
#include "IOManager.h"
|
#include "IOManager.h"
|
||||||
@ -21,10 +21,10 @@
|
|||||||
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 << 0, DISP_BEGIN_ERR = 1 << 1, SDCARD_INIT_ERR = 1 << 2, IO_INIT_ERR = 1 << 3, CONNECT_ERR = 1 << 4, OTAMAN_INIT_ERR = 1 << 5, WEBSRVMAN_INIT_ERR = 1 << 6};
|
||||||
|
|
||||||
SAB();
|
SAB();
|
||||||
SAB(const BoardConfig boardConfig, const unsigned int webServerPort = 80, const unsigned int ftpServerPort = 21);
|
SAB(const BoardConfig boardConfig, const unsigned int ftpServerPort = 21);
|
||||||
~SAB()
|
~SAB()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@ -34,7 +34,7 @@ class SAB
|
|||||||
RTC_DS3231& getRTC_DS3231();
|
RTC_DS3231& getRTC_DS3231();
|
||||||
SDCardManager& getSdCardManager();
|
SDCardManager& getSdCardManager();
|
||||||
ConnectivityManager& getConnectivityManager();
|
ConnectivityManager& getConnectivityManager();
|
||||||
WEBServer<WEBClient>& getWebServer();
|
WEBServerManager& getWebServerManager();
|
||||||
FTPServer<FTPClient>& getFtpServer();
|
FTPServer<FTPClient>& getFtpServer();
|
||||||
OTAManager& getOTAManager();
|
OTAManager& getOTAManager();
|
||||||
IOManager& getIOManager();
|
IOManager& getIOManager();
|
||||||
@ -57,7 +57,7 @@ class SAB
|
|||||||
RTC_DS3231 _rtc;
|
RTC_DS3231 _rtc;
|
||||||
RtcManager _rtcManager;
|
RtcManager _rtcManager;
|
||||||
ConnectivityManager _connectivityManager;
|
ConnectivityManager _connectivityManager;
|
||||||
WEBServer<WEBClient> _webServer;
|
WEBServerManager _webServerManager;
|
||||||
FTPServer<FTPClient> _ftpServer;
|
FTPServer<FTPClient> _ftpServer;
|
||||||
OTAManager _otaManager;
|
OTAManager _otaManager;
|
||||||
DashboardWSServer _dbWSServer;
|
DashboardWSServer _dbWSServer;
|
||||||
|
@ -93,6 +93,11 @@ class WEBServer : public TCPServer<T>, public HttpConstants
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void setSDClass(SDClass *sdClass)
|
||||||
|
{
|
||||||
|
_sdClass = sdClass;
|
||||||
|
}
|
||||||
|
|
||||||
const char * getWWWDir(void) const
|
const char * getWWWDir(void) const
|
||||||
{
|
{
|
||||||
return _WWWDir;
|
return _WWWDir;
|
||||||
|
@ -1,552 +1,83 @@
|
|||||||
/**
|
|
||||||
* @file WEBServerManager.cpp
|
|
||||||
* @author Anatole SCHRAMM-HENRY
|
|
||||||
* @brief Single client WEB Server.
|
|
||||||
* This class is now retired and replaced by the much better WEBServer class
|
|
||||||
* which handles multiclients among other things.
|
|
||||||
* @version 0.1
|
|
||||||
* @date 31/03/2019
|
|
||||||
*
|
|
||||||
* @copyright MIT
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
#include "WEBServerManager.h"
|
#include "WEBServerManager.h"
|
||||||
|
#include "definition.h"
|
||||||
|
|
||||||
//#define DEBUG
|
//#define DEBUG_WEB_SERVER_MANAGER(...) do {} while(0)
|
||||||
#define DEBUG_BODY
|
#define DEBUG_WEB_SERVER_MANAGER(...) do { Serial.printf(__VA_ARGS__); Serial.println();} while(0)
|
||||||
//#define DEBUG_PARAMETER
|
|
||||||
//#define DEBUG_CONTENT_LENGTH
|
|
||||||
//#define DEBUG_RAW
|
|
||||||
//#define DEBUG_FILEPATH
|
|
||||||
|
|
||||||
WEBServerManager::WEBServerManager(unsigned int port, SDCardManager *sdCardManager) : _wifiServer(port), _sdCardManager(sdCardManager), _httpRequestData({UNDEFINED, UNKNOWN, UNKNOWN_MIME, Dictionary<DictionaryHelper::StringEntity>(), Dictionary<DictionaryHelper::StringEntity>(), NULL,NULL}), _httpParserState(INIT), _clientState(WAITING_FOR_CLIENT), _port(port), _clientTimeout(0)
|
WEBServerManager::WEBServerManager(SDCardManager &sdCardManager) : _sdCardManager(&sdCardManager), _webServer(80, &sdCardManager, 10)
|
||||||
{
|
{
|
||||||
_wifiServer.begin();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean WEBServerManager::addApiRoutine(const char *uri, boolean (*apiRoutine)(HttpRequestData&, WiFiClient* , void*), void *pData, HttpRequestMethod HRM)
|
WEBServerManager::~WEBServerManager()
|
||||||
{
|
{
|
||||||
return _apiDictionary.add(uri,new ApiRoutine({apiRoutine,pData, HRM}));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void WEBServerManager::clearApiRoutine()
|
boolean WEBServerManager::init(void)
|
||||||
{
|
{
|
||||||
_apiDictionary.clear();
|
CFGDictionary<CFGParameterValue> *serverCfg = _sdCardManager->getCFGFile(SERVER_CFG_FILE);
|
||||||
}
|
boolean toReturn(true);
|
||||||
|
|
||||||
boolean WEBServerManager::removeApiRoutine(const char *uri)
|
//We were not able to read the config file, so we apply default parameters
|
||||||
{
|
if(!serverCfg)
|
||||||
return _apiDictionary.remove(uri);
|
|
||||||
}
|
|
||||||
|
|
||||||
boolean WEBServerManager::runServer()
|
|
||||||
{
|
|
||||||
switch(_clientState)
|
|
||||||
{
|
|
||||||
case WAITING_FOR_CLIENT:
|
|
||||||
_wifiClient.stopAll();
|
|
||||||
|
|
||||||
_wifiClient = _wifiServer.available();
|
|
||||||
if(_wifiClient)
|
|
||||||
{
|
|
||||||
_clientState = NEW;
|
|
||||||
#ifdef DEBUG
|
|
||||||
Serial.println("Client connected !!!");
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case NEW:
|
|
||||||
_clientState = NOT_HANDLED;
|
|
||||||
break;
|
|
||||||
case NOT_HANDLED:
|
|
||||||
clearHttpRequestData();
|
|
||||||
parseQuery(&_wifiClient);
|
|
||||||
#ifdef DEBUG
|
|
||||||
Serial.println("Nothing more from client !!!");
|
|
||||||
#endif
|
|
||||||
_clientState = QUERY_PARSED;
|
|
||||||
break;
|
|
||||||
case QUERY_PARSED:
|
|
||||||
#ifdef DEBUG
|
|
||||||
Serial.println("Sending response !!!");
|
|
||||||
#endif
|
|
||||||
//We first check if it's an api call
|
|
||||||
if(!sendPageToClientFromApiDictio(&_wifiClient))
|
|
||||||
{
|
|
||||||
sendPageToClientFromSdCard(&_wifiClient);
|
|
||||||
}
|
|
||||||
_clientState = RESPONSE_SENT;
|
|
||||||
break;
|
|
||||||
case RESPONSE_SENT:
|
|
||||||
#ifdef DEBUG
|
|
||||||
Serial.println("Client handled !!!");
|
|
||||||
#endif
|
|
||||||
_clientState = HANDLED;
|
|
||||||
break;
|
|
||||||
case HANDLED:
|
|
||||||
_wifiClient.stopAll();
|
|
||||||
_clientState = WAITING_FOR_CLIENT;
|
|
||||||
#ifdef DEBUG
|
|
||||||
Serial.println("Client discarded !!!");
|
|
||||||
#endif
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
boolean WEBServerManager::parseQuery(WiFiClient *wifiClient)
|
|
||||||
{
|
|
||||||
char readChar(0), *parseBuffer(NULL), *parseKey(NULL), *parseValue(NULL), *parseParameter(NULL), *contentLength(NULL);
|
|
||||||
boolean isKey(true), receivingDone(false);
|
|
||||||
unsigned int activeTimeout = 10000;
|
|
||||||
unsigned long dataBytesCounter = 0, dataBytes = 0;
|
|
||||||
|
|
||||||
/* Better way to read data
|
|
||||||
char temp[2048];
|
|
||||||
temp[wifiClient->read((uint8_t*)temp,2040)] = '\0';
|
|
||||||
Serial.print(temp);
|
|
||||||
*/
|
|
||||||
_httpParserState = INIT;
|
|
||||||
_clientTimeout = millis();
|
|
||||||
boolean slashesOrAntiSlashesOnly(true);
|
|
||||||
while((wifiClient->available() || ( millis() - _clientTimeout < activeTimeout)) && wifiClient->connected())
|
|
||||||
{
|
|
||||||
if(wifiClient->available())
|
|
||||||
{
|
{
|
||||||
readChar = (char)wifiClient->read();
|
DEBUG_WEB_SERVER_MANAGER("serverCfg is NULL, applying default parameters !");
|
||||||
|
_webServer.setWWWDir(WWW_DIR);
|
||||||
#ifdef DEBUG_RAW
|
_webServer.enableTCPKeepAlive(15,5,5);
|
||||||
Serial.print(readChar);
|
_webServer.start();
|
||||||
#endif
|
_isServiceEnabled = true;
|
||||||
//INIT, LINE_BREAK, HTTP_VERB_SECTION, HTTP_RESOURCE_SECTION, HTTP_VER_SECTION, BODY_SECTION, IGNORED, ERROR
|
return toReturn;
|
||||||
switch(_httpParserState)
|
}
|
||||||
{
|
|
||||||
case INIT:
|
|
||||||
if(readChar >= 65 && readChar <= 90)
|
|
||||||
{
|
|
||||||
parseBuffer = addChar(parseBuffer, readChar);
|
|
||||||
_httpParserState = HTTP_VERB_SECTION;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
_httpParserState = ERROR;
|
|
||||||
break;
|
|
||||||
case LINE_BREAK:
|
|
||||||
if(readChar == '\n')
|
|
||||||
{
|
|
||||||
if(_httpRequestData.HRM == GET)
|
|
||||||
{
|
|
||||||
#ifdef DEBUG
|
|
||||||
Serial.println("GET DONE");
|
|
||||||
#endif
|
|
||||||
receivingDone = true;
|
|
||||||
}
|
|
||||||
_httpParserState = BODY_SECTION;
|
|
||||||
}
|
|
||||||
else if(readChar != '\r')
|
|
||||||
{
|
|
||||||
if(parseParameter != NULL)
|
|
||||||
{
|
|
||||||
contentLength = strstr(parseParameter, "ent-Len");//Matches Content-Length short to save some RAM
|
|
||||||
if(contentLength != NULL)
|
|
||||||
{
|
|
||||||
dataBytes = strtol(contentLength+11,NULL,10);
|
|
||||||
#ifdef DEBUG_CONTENT_LENGTH
|
|
||||||
Serial.print("Data length : ");Serial.println(dataBytes);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef DEBUG_PARAMETER
|
//We managed to read the config file, now we can apply it !
|
||||||
Serial.println(parseParameter);
|
if((*serverCfg)("WEB_ENABLED"))
|
||||||
#endif
|
{
|
||||||
free(parseParameter);parseParameter = NULL;
|
if((*serverCfg)("WEB_ENABLED")->booleanValue())
|
||||||
}
|
{
|
||||||
parseParameter = addChar(parseParameter, readChar);
|
_isServiceEnabled = true;
|
||||||
_httpParserState = PARAMETER_SECTION;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case HTTP_VERB_SECTION:
|
|
||||||
if(readChar >= 65 && readChar <= 90)
|
|
||||||
{
|
|
||||||
parseBuffer = addChar(parseBuffer, readChar);
|
|
||||||
_httpParserState = HTTP_VERB_SECTION;
|
|
||||||
}
|
|
||||||
else if (readChar == ' ')
|
|
||||||
{
|
|
||||||
//This is the end of the section
|
|
||||||
_httpRequestData.HRM = getHttpVerbEnumValue(parseBuffer);
|
|
||||||
free(parseBuffer);parseBuffer = NULL;
|
|
||||||
_httpParserState = HTTP_RESOURCE_SECTION;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
_httpParserState = ERROR;
|
|
||||||
break;
|
|
||||||
case HTTP_RESOURCE_SECTION:
|
|
||||||
if(readChar == '?' )
|
|
||||||
{
|
|
||||||
free(_httpRequestData.httpResource);_httpRequestData.httpResource = NULL;
|
|
||||||
_httpRequestData.httpResource = parseBuffer;parseBuffer = NULL;
|
|
||||||
|
|
||||||
_httpParserState = HTTP_RESOURCE_PARAM_SECTION;
|
if((*serverCfg)("WEB_PORT"))
|
||||||
}
|
|
||||||
else if(readChar == ' ')
|
|
||||||
{
|
|
||||||
free(_httpRequestData.httpResource);_httpRequestData.httpResource = NULL;
|
|
||||||
if(slashesOrAntiSlashesOnly)
|
|
||||||
{
|
{
|
||||||
free(parseBuffer);parseBuffer = NULL;
|
DEBUG_WEB_SERVER_MANAGER("WEB_PORT is %u", (*serverCfg)("WEB_PORT")->uintValue());
|
||||||
_httpRequestData.httpResource = (char *) malloc(sizeof(char)*2);
|
_webServer.setPort((*serverCfg)("WEB_PORT")->uintValue());
|
||||||
strcpy(_httpRequestData.httpResource,"/");
|
|
||||||
}
|
}
|
||||||
else
|
|
||||||
_httpRequestData.httpResource = parseBuffer;parseBuffer = NULL;
|
|
||||||
|
|
||||||
_httpParserState = HTTP_VER_SECTION;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if(readChar != '/' && readChar != '\\') slashesOrAntiSlashesOnly = false;
|
|
||||||
|
|
||||||
parseBuffer = addChar(parseBuffer, readChar);
|
if((*serverCfg)("WEB_MAX_CLIENT"))
|
||||||
_httpParserState = HTTP_RESOURCE_SECTION;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case HTTP_RESOURCE_PARAM_SECTION: //index.web?var1=1&var2=2...
|
|
||||||
if(readChar == ' ')
|
|
||||||
{
|
{
|
||||||
_httpRequestData.getParams.add(parseKey,new DictionaryHelper::StringEntity(parseValue));
|
DEBUG_WEB_SERVER_MANAGER("WEB_MAX_CLIENT is %u", (*serverCfg)("WEB_MAX_CLIENT")->uintValue());
|
||||||
free(parseKey);free(parseValue);
|
_webServer.setMaxClient((*serverCfg)("WEB_MAX_CLIENT")->uintValue());
|
||||||
parseKey = NULL;parseValue = NULL;
|
|
||||||
_httpParserState = HTTP_VER_SECTION;
|
|
||||||
}
|
}
|
||||||
else if( readChar == '=')
|
|
||||||
isKey = false;
|
if((*serverCfg)("WEB_WWW_DIR"))
|
||||||
else if(readChar == '&')
|
|
||||||
{
|
{
|
||||||
isKey = true;
|
DEBUG_WEB_SERVER_MANAGER("WEB_WWW_DIR is %s", (*serverCfg)("WEB_WWW_DIR")->stringValue());
|
||||||
_httpRequestData.getParams.add(parseKey, new DictionaryHelper::StringEntity(parseValue));
|
_webServer.setWWWDir((*serverCfg)("WEB_WWW_DIR")->stringValue());
|
||||||
free(parseKey);free(parseValue);
|
|
||||||
parseKey = NULL;parseValue = NULL;
|
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
if(isKey)
|
|
||||||
parseKey = addChar(parseKey, readChar);
|
|
||||||
else
|
|
||||||
parseValue = addChar(parseValue, readChar);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case HTTP_VER_SECTION:
|
|
||||||
if((readChar >= 48 && readChar <= 57) || readChar == '.')
|
|
||||||
{
|
|
||||||
parseBuffer = addChar(parseBuffer, readChar);
|
|
||||||
_httpParserState = HTTP_VER_SECTION;
|
|
||||||
}
|
|
||||||
else if(readChar == '\n')
|
|
||||||
{
|
|
||||||
_httpRequestData.HV = getHttpVersionEnumValue(parseBuffer);
|
|
||||||
free(parseBuffer);parseBuffer = NULL;
|
|
||||||
_httpParserState = LINE_BREAK;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case BODY_SECTION:
|
|
||||||
//parseBuffer = addChar(parseBuffer, readChar);
|
|
||||||
if(_httpRequestData.HRM != GET)
|
|
||||||
{
|
|
||||||
dataBytesCounter++;//Should be always true
|
|
||||||
}
|
|
||||||
#ifdef DEBUG_BODY
|
|
||||||
Serial.print(readChar);
|
|
||||||
#endif
|
|
||||||
break;
|
|
||||||
case PARAMETER_SECTION: //Here are all the http header params
|
|
||||||
if(readChar == '\n')
|
|
||||||
{
|
|
||||||
_httpParserState = LINE_BREAK;
|
|
||||||
}else
|
|
||||||
parseParameter = addChar(parseParameter, readChar);
|
|
||||||
break;
|
|
||||||
case IGNORED:
|
|
||||||
break;
|
|
||||||
case ERROR:
|
|
||||||
return false;
|
|
||||||
break; //Not necessary
|
|
||||||
default :
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
//Exit condition
|
|
||||||
if(receivingDone) break;
|
|
||||||
if(_httpRequestData.HRM == POST && dataBytes != 0 && dataBytes == dataBytesCounter) break;
|
|
||||||
|
|
||||||
_clientTimeout = millis();
|
|
||||||
}
|
|
||||||
//yield(); //Likely causing a crash
|
|
||||||
ESP.wdtFeed();
|
|
||||||
}
|
|
||||||
|
|
||||||
if(parseBuffer != NULL)
|
_webServer.start();
|
||||||
{
|
}
|
||||||
if(strlen(parseBuffer) > 0)
|
else
|
||||||
|
{
|
||||||
|
_webServer.stop();
|
||||||
|
_isServiceEnabled = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
_httpRequestData.httpBody = parseBuffer;
|
DEBUG_WEB_SERVER_MANAGER("WEB_ENABLED is NULL !");
|
||||||
parseBuffer = NULL;
|
toReturn = false;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
return toReturn;
|
||||||
free(parseParameter);parseParameter = NULL;
|
|
||||||
|
|
||||||
#ifdef DEBUG
|
|
||||||
Serial.print("HTTP VERB : ");
|
|
||||||
Serial.println(_httpRequestData.HRM);
|
|
||||||
Serial.print("HTTP RESOURCE : ");
|
|
||||||
Serial.println(_httpRequestData.httpResource);
|
|
||||||
Serial.print("HTTP VERSION : ");
|
|
||||||
Serial.println(_httpRequestData.HV);
|
|
||||||
Serial.print("BODY CONTENT : ");
|
|
||||||
Serial.println(_httpRequestData.httpBody);
|
|
||||||
Serial.println("GET PARAMS :");
|
|
||||||
for(int i = 0; i < _httpRequestData.getParams.count(); i++)
|
|
||||||
{
|
|
||||||
Serial.print(_httpRequestData.getParams.getParameter(i));Serial.print(" : ");Serial.println(_httpRequestData.getParams.getAt(i)->getString());
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int WEBServerManager::getPort() const
|
boolean WEBServerManager::isEnabled(void) const
|
||||||
{
|
{
|
||||||
return _port;
|
return _isServiceEnabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean WEBServerManager::sendPageToClientFromSdCard(WiFiClient *wifiClient)
|
WEBServer<WEBClient> &WEBServerManager::getWEBServer(void)
|
||||||
{
|
{
|
||||||
if(_sdCardManager != NULL)
|
return _webServer;
|
||||||
{
|
}
|
||||||
File pageToSend;
|
|
||||||
char readChar(0), *filePath(NULL), *header(NULL), sendBuffer[2048];
|
|
||||||
|
|
||||||
//We check what kind of http verb it is
|
|
||||||
switch(_httpRequestData.HRM)
|
|
||||||
{
|
|
||||||
case GET:
|
|
||||||
filePath = getFilePathByHttpResource(_httpRequestData.httpResource);
|
|
||||||
if(filePath == NULL)
|
|
||||||
{
|
|
||||||
wifiClient->print(F("HTTP/1.1 500 Internal Server Error\r\nContent-Type: text/html\r\n\r\n<!DOCTYPE HTML>\r\n<html>\r\n<p>Failed to malloc filePath</p>\r\n</html>"));
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef DEBUG
|
|
||||||
Serial.print("FILE PATH : ");
|
|
||||||
Serial.println(filePath);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
pageToSend = _sdCardManager->open(filePath);
|
|
||||||
free(filePath);filePath = NULL;
|
|
||||||
|
|
||||||
if(!pageToSend)
|
|
||||||
{
|
|
||||||
char *response(NULL);
|
|
||||||
response = (char *) malloc(sizeof(char) * (strlen("HTTP/1.1 404 Not Found\r\nContent-Type: text/html\r\n\r\n<!DOCTYPE HTML>\r\n<html>\r\n<h1>Page not found for : </h1>\r\n<h4></h4>\r\n</html>") + strlen(_httpRequestData.httpResource) + 1));
|
|
||||||
if(response == NULL)
|
|
||||||
{
|
|
||||||
wifiClient->print(F("HTTP/1.1 500 Internal Server Error\r\nContent-Type: text/html\r\n\r\n<!DOCTYPE HTML>\r\n<html>\r\n<h1>Failed to malloc response</h1>\r\n</html>"));
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
sprintf(response, "HTTP/1.1 404 Not Found\r\nContent-Type: text/html\r\n\r\n<!DOCTYPE HTML>\r\n<html>\r\n<h1>Page not found for : </h1>\r\n<h4>%s</h4>\r\n</html>", _httpRequestData.httpResource);
|
|
||||||
wifiClient->print(response);
|
|
||||||
free(response);response = NULL;
|
|
||||||
pageToSend.close();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef DEBUG
|
|
||||||
Serial.print("FILE SIZE : ");
|
|
||||||
Serial.println(pageToSend.size());
|
|
||||||
Serial.print("FILE NAME : ");
|
|
||||||
Serial.println(pageToSend.name());
|
|
||||||
Serial.print("FILE EXTENSION : ");
|
|
||||||
//Serial.println(getFileExtension(pageToSend.name()));
|
|
||||||
#endif
|
|
||||||
|
|
||||||
header = getHTTPHeader(getMIMETypeByExtension(getFileExtension(/*pageToSend.name()*/ "dummy")), pageToSend.size());
|
|
||||||
if(header == NULL)
|
|
||||||
{
|
|
||||||
wifiClient->print(F("HTTP/1.1 500 Internal Server Error\r\nContent-Type: text/html\r\n\r\n<!DOCTYPE HTML>\r\n<html>\r\n<h1>Failed to malloc header</h1>\r\n</html>"));
|
|
||||||
pageToSend.close();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
wifiClient->print(header);
|
|
||||||
free(header);header = NULL;
|
|
||||||
|
|
||||||
while(pageToSend.available())
|
|
||||||
{
|
|
||||||
//if(wifiClient->write(sendBuffer, pageToSend.read(sendBuffer,2048)) == 0)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
pageToSend.close();
|
|
||||||
break;
|
|
||||||
default: //If not supported
|
|
||||||
wifiClient->print(F("HTTP/1.1 405 Method Not Allowed\r\nContent-Type: text/html\r\n\r\n<!DOCTYPE HTML>\r\n<html>\r\n<h1>Method Not Allowed</h1>\r\n</html>"));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}else
|
|
||||||
{
|
|
||||||
wifiClient->print(F("HTTP/1.1 500 Internal Server Error\r\nContent-Type: text/html\r\n\r\n<!DOCTYPE HTML>\r\n<html>\r\n<h1>SDCardManager is NULL<br \\>Check code</h1>\r\n</html>"));
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
boolean WEBServerManager::sendPageToClientFromApiDictio(WiFiClient *wifiClient)
|
|
||||||
{
|
|
||||||
if(_apiDictionary.count() == 0 || _httpRequestData.httpResource == NULL)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
ApiRoutine *ref = _apiDictionary(_httpRequestData.httpResource);
|
|
||||||
|
|
||||||
if(ref == NULL)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if(ref->HRM == UNDEFINED)
|
|
||||||
{
|
|
||||||
return (*(ref->apiRoutine))(_httpRequestData, wifiClient, ref->pData);
|
|
||||||
}else if(ref->HRM == _httpRequestData.HRM)
|
|
||||||
{
|
|
||||||
return (*(ref->apiRoutine))(_httpRequestData, wifiClient, ref->pData);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
WEBServerManager::HttpMIMEType WEBServerManager::getMIMETypeByExtension(const char *extension)
|
|
||||||
{
|
|
||||||
//TEXT_PLAIN, TEXT_CSS, TEXT_HTML, TEXT_JAVASCRIPT
|
|
||||||
if(strcmp(extension,"web") == 0) return TEXT_HTML;
|
|
||||||
else if(strcmp(extension,"htm") == 0) return TEXT_HTML;
|
|
||||||
else if(strcmp(extension,"css") == 0) return TEXT_CSS;
|
|
||||||
else if(strcmp(extension,"js") == 0) return TEXT_JAVASCRIPT;
|
|
||||||
else if(strcmp(extension,"png") == 0) return IMAGE_PNG;
|
|
||||||
else if(strcmp(extension,"jpg") == 0) return IMAGE_JPEG;
|
|
||||||
else if(strcmp(extension, "mp3") == 0) return AUDIO_MPEG;
|
|
||||||
else return UNKNOWN_MIME;
|
|
||||||
}
|
|
||||||
|
|
||||||
char *WEBServerManager::getHTTPHeader(HttpMIMEType httpMIMEType, unsigned long size)
|
|
||||||
{
|
|
||||||
char *header = (char *) malloc(sizeof(char) + strlen("HTTP/1.1 200 OK\r\nContent-Type: \r\nContent-Length: \r\n\r\n") + 74/*Longest MIME-TYPE*/ + 10 /*Max unsigned long footprint*/ + 1);
|
|
||||||
|
|
||||||
switch(httpMIMEType)
|
|
||||||
{
|
|
||||||
case TEXT_HTML:
|
|
||||||
sprintf(header,"HTTP/1.1 200 OK\r\nContent-Type: %s\r\nContent-Length: %lu\r\n\r\n","text/html",size);
|
|
||||||
break;
|
|
||||||
case TEXT_CSS:
|
|
||||||
sprintf(header,"HTTP/1.1 200 OK\r\nContent-Type: %s\r\nContent-Length: %lu\r\n\r\n","text/css",size);
|
|
||||||
break;
|
|
||||||
case TEXT_JAVASCRIPT:
|
|
||||||
sprintf(header,"HTTP/1.1 200 OK\r\nContent-Type: %s\r\nContent-Length: %lu\r\n\r\n","text/javascript",size);
|
|
||||||
break;
|
|
||||||
case IMAGE_PNG:
|
|
||||||
sprintf(header,"HTTP/1.1 200 OK\r\nContent-Type: %s\r\nContent-Length: %lu\r\n\r\n","image/png",size);
|
|
||||||
break;
|
|
||||||
case IMAGE_JPEG:
|
|
||||||
sprintf(header,"HTTP/1.1 200 OK\r\nContent-Type: %s\r\nContent-Length: %lu\r\n\r\n","image/jpeg",size);
|
|
||||||
break;
|
|
||||||
case TEXT_PLAIN:
|
|
||||||
sprintf(header,"HTTP/1.1 200 OK\r\nContent-Type: %s\r\nContent-Length: %lu\r\n\r\n","text/plain",size);
|
|
||||||
break;
|
|
||||||
case AUDIO_MPEG:
|
|
||||||
sprintf(header,"HTTP/1.1 200 OK\r\nContent-Type: %s\r\nContent-Length: %lu\r\n\r\n","audio/mpeg",size);
|
|
||||||
break;
|
|
||||||
case APPLICATION_OCTET_STREAM:
|
|
||||||
sprintf(header,"HTTP/1.1 200 OK\r\nContent-Type: %s\r\nContent-Length: %lu\r\n\r\n","application/octet-stream",size);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
sprintf(header,"HTTP/1.1 200 OK\r\nContent-Type: %s\r\nContent-Length: %lu\r\n\r\n","application/octet-stream",size);
|
|
||||||
break;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return header;
|
|
||||||
}
|
|
||||||
|
|
||||||
char *WEBServerManager::getFileExtension(char *name)
|
|
||||||
{
|
|
||||||
if(name == NULL)return "";
|
|
||||||
|
|
||||||
char *ptr(name);
|
|
||||||
int index(0);
|
|
||||||
while(ptr[index] != '\0')
|
|
||||||
{
|
|
||||||
if(ptr[++index] == '.')
|
|
||||||
{
|
|
||||||
return (name + index +1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
|
|
||||||
char *WEBServerManager::getFilePathByHttpResource(char *res)
|
|
||||||
{
|
|
||||||
uint16_t buffSize = strlen(WWW_DIR) + (strcmp(res, "/") == 0 ? 10:strlen(res)) + 1;//10 for /index.htm +1 for \0
|
|
||||||
char *filePath = (char*) malloc( sizeof(char) * buffSize);
|
|
||||||
|
|
||||||
if(filePath == NULL)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
strcpy(filePath, WWW_DIR);
|
|
||||||
strcat(filePath, strcmp(res, "/") == 0 ? "/index.htm":res);
|
|
||||||
//sprintf(filePath,"%s%s",WWW_DIR, strcmp(res, "/") == 0 ? "/index.htm":res);
|
|
||||||
|
|
||||||
#ifdef DEBUG_FILEPATH
|
|
||||||
Serial.println(res);
|
|
||||||
Serial.print("Reserved space : ");Serial.println(buffSize);
|
|
||||||
Serial.print("Actual size : ");Serial.println(strlen(filePath));
|
|
||||||
Serial.println(filePath);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return filePath;
|
|
||||||
}
|
|
||||||
|
|
||||||
WEBServerManager::HttpRequestMethod WEBServerManager::getHttpVerbEnumValue(const char *parseBuffer)
|
|
||||||
{
|
|
||||||
//UNDEFINED, GET, HEAD, POST, PUT, DELETE, CONNECT, OPTIONS, TRACE, PATCH
|
|
||||||
if(strcmp(parseBuffer,"GET") == 0){return GET;}
|
|
||||||
else if(strcmp(parseBuffer,"POST") == 0){return POST;}
|
|
||||||
else if(strcmp(parseBuffer,"HEAD") == 0){return HEAD;}
|
|
||||||
else if(strcmp(parseBuffer,"PUT") == 0){return PUT;}
|
|
||||||
else if(strcmp(parseBuffer,"DELETE") == 0){return DELETE;}
|
|
||||||
else if(strcmp(parseBuffer,"CONNECT") == 0){return CONNECT;}
|
|
||||||
else if(strcmp(parseBuffer,"TRACE") == 0){return TRACE;}
|
|
||||||
else if(strcmp(parseBuffer,"PATCH") == 0){return PATCH;}
|
|
||||||
else if(strcmp(parseBuffer,"OPTIONS") == 0){return OPTIONS;}
|
|
||||||
else
|
|
||||||
return UNDEFINED;
|
|
||||||
}
|
|
||||||
|
|
||||||
WEBServerManager::HttpVersion WEBServerManager::getHttpVersionEnumValue(const char *parseBuffer)
|
|
||||||
{
|
|
||||||
//HTTP_0_9, HTTP_1_1, HTTP_1_0, HTTP_2_0
|
|
||||||
if(strcmp(parseBuffer,"1.1") == 0){return HTTP_1_1;}
|
|
||||||
else if(strcmp(parseBuffer,"2.0") == 0){return HTTP_2_0;}
|
|
||||||
else if(strcmp(parseBuffer,"1.0") == 0){return HTTP_1_0;}
|
|
||||||
else if(strcmp(parseBuffer,"0.9") == 0){return HTTP_0_9;}
|
|
||||||
else
|
|
||||||
return UNKNOWN;
|
|
||||||
}
|
|
||||||
|
|
||||||
void WEBServerManager::clearHttpRequestData()
|
|
||||||
{
|
|
||||||
_httpRequestData.HRM = UNDEFINED;
|
|
||||||
_httpRequestData.HV = UNKNOWN;
|
|
||||||
_httpRequestData.HMT = UNKNOWN_MIME;
|
|
||||||
free(_httpRequestData.httpResource);free(_httpRequestData.httpBody);
|
|
||||||
_httpRequestData.httpResource = NULL;_httpRequestData.httpBody = NULL;
|
|
||||||
_httpRequestData.getParams.dispose();
|
|
||||||
_httpRequestData.postParams.dispose();
|
|
||||||
}
|
|
@ -1,81 +1,26 @@
|
|||||||
/**
|
|
||||||
* @file WEBServerManager.h
|
|
||||||
* @author Anatole SCHRAMM-HENRY
|
|
||||||
* @brief Single client WEB Server.
|
|
||||||
* This class is now retired and replaced by the much better WEBServer class
|
|
||||||
* which handles multiclients among other things.
|
|
||||||
* @version 0.1
|
|
||||||
* @date 31/03/2019
|
|
||||||
*
|
|
||||||
* @copyright MIT
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
#ifndef WEBSERVERMANAGER_H
|
#ifndef WEBSERVERMANAGER_H
|
||||||
#define WEBSERVERMANAGER_H
|
#define WEBSERVERMANAGER_H
|
||||||
|
|
||||||
#include <WiFiServer.h>
|
|
||||||
#include <WiFiClient.h>
|
|
||||||
#include "SDCardManager.h"
|
#include "SDCardManager.h"
|
||||||
#include "definition.h"
|
#include "WEBClient.h" //includes WEBServer internally
|
||||||
#include "Dictionary.h"
|
|
||||||
|
|
||||||
struct HttpRequestData;
|
|
||||||
|
|
||||||
class WEBServerManager
|
class WEBServerManager
|
||||||
{
|
{
|
||||||
public:
|
friend class SAB;
|
||||||
enum ClientStatus {NOT_HANDLED, HANDLED, NEW, WAITING_FOR_CLIENT, QUERY_PARSED, RESPONSE_SENT};
|
public:
|
||||||
enum HttpRequestMethod {UNDEFINED, GET, HEAD, POST, PUT, DELETE, CONNECT, OPTIONS, TRACE, PATCH};
|
~WEBServerManager();
|
||||||
enum HttpVersion {UNKNOWN, HTTP_0_9, HTTP_1_1, HTTP_1_0, HTTP_2_0};
|
boolean init(void);
|
||||||
enum HttpParserStatus {INIT, LINE_BREAK, HTTP_VERB_SECTION, HTTP_RESOURCE_SECTION, HTTP_RESOURCE_PARAM_SECTION, HTTP_VER_SECTION, PARAMETER_SECTION, BODY_SECTION, IGNORED, ERROR};
|
boolean isEnabled(void) const;
|
||||||
enum HttpMIMEType{UNKNOWN_MIME, TEXT_PLAIN, TEXT_CSS, TEXT_HTML, TEXT_JAVASCRIPT, APPLICATION_JSON, APPLICATION_X_WWW_FORM_URLENCODED, IMAGE_PNG, IMAGE_JPEG, AUDIO_MPEG, APPLICATION_OCTET_STREAM};
|
WEBServer<WEBClient> &getWEBServer(void);
|
||||||
struct HttpRequestData{
|
|
||||||
HttpRequestMethod HRM;
|
|
||||||
HttpVersion HV;
|
|
||||||
HttpMIMEType HMT;
|
|
||||||
Dictionary<DictionaryHelper::StringEntity> getParams;
|
|
||||||
Dictionary<DictionaryHelper::StringEntity> postParams;
|
|
||||||
char *httpResource;
|
|
||||||
char *httpBody;
|
|
||||||
};
|
|
||||||
|
|
||||||
WEBServerManager(unsigned int port = 80, SDCardManager *sdCardManager = NULL);
|
|
||||||
|
|
||||||
boolean runServer();
|
protected:
|
||||||
unsigned int getPort() const;
|
WEBServerManager(SDCardManager &sdCardManager);
|
||||||
boolean addApiRoutine(const char *uri, boolean (*apiRoutine)(HttpRequestData&, WiFiClient*, void*), void *pData, HttpRequestMethod HRM = UNDEFINED);
|
|
||||||
void clearApiRoutine();
|
private:
|
||||||
boolean removeApiRoutine(const char *uri);
|
SDCardManager *_sdCardManager = nullptr;
|
||||||
protected:
|
boolean _isServiceEnabled = false;
|
||||||
private:
|
WEBServer<WEBClient> _webServer;
|
||||||
struct ApiRoutine
|
|
||||||
{
|
|
||||||
boolean (*apiRoutine)(HttpRequestData&, WiFiClient*, void*);
|
|
||||||
void *pData;
|
|
||||||
HttpRequestMethod HRM;
|
|
||||||
};
|
|
||||||
|
|
||||||
boolean parseQuery(WiFiClient *wifiClient);
|
|
||||||
boolean sendPageToClientFromSdCard(WiFiClient *wifiClient);
|
|
||||||
boolean sendPageToClientFromApiDictio(WiFiClient *wifiClient);
|
|
||||||
HttpRequestMethod getHttpVerbEnumValue(const char *parseBuffer);
|
|
||||||
HttpVersion getHttpVersionEnumValue(const char *parseBuffer);
|
|
||||||
char *getFilePathByHttpResource(char *res);
|
|
||||||
char *getFileExtension(char *name);
|
|
||||||
HttpMIMEType getMIMETypeByExtension(const char *extension);
|
|
||||||
char *getHTTPHeader(HttpMIMEType httpMIMEType, unsigned long size);
|
|
||||||
void clearHttpRequestData();
|
|
||||||
|
|
||||||
WiFiServer _wifiServer;
|
|
||||||
WiFiClient _wifiClient;//One client only, may be replaced with a fifo in the future
|
|
||||||
SDCardManager *_sdCardManager;
|
|
||||||
HttpRequestData _httpRequestData;
|
|
||||||
Dictionary<ApiRoutine> _apiDictionary;
|
|
||||||
|
|
||||||
ClientStatus _clientState;
|
|
||||||
HttpParserStatus _httpParserState;
|
|
||||||
unsigned long _clientTimeout;
|
|
||||||
unsigned int _port;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif //WEBSERVERMANAGER_H
|
#endif //WEBSERVERMANAGER_H
|
552
src/app/WEBServerManager_deprecated.cpp
Normal file
552
src/app/WEBServerManager_deprecated.cpp
Normal file
@ -0,0 +1,552 @@
|
|||||||
|
/**
|
||||||
|
* @file WEBServerManager.cpp
|
||||||
|
* @author Anatole SCHRAMM-HENRY
|
||||||
|
* @brief Single client WEB Server.
|
||||||
|
* This class is now retired and replaced by the much better WEBServer class
|
||||||
|
* which handles multiclients among other things.
|
||||||
|
* @version 0.1
|
||||||
|
* @date 31/03/2019
|
||||||
|
*
|
||||||
|
* @copyright MIT
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#include "WEBServerManager_deprecated.h"
|
||||||
|
|
||||||
|
//#define DEBUG
|
||||||
|
#define DEBUG_BODY
|
||||||
|
//#define DEBUG_PARAMETER
|
||||||
|
//#define DEBUG_CONTENT_LENGTH
|
||||||
|
//#define DEBUG_RAW
|
||||||
|
//#define DEBUG_FILEPATH
|
||||||
|
|
||||||
|
WEBServerManager_deprecated::WEBServerManager_deprecated(unsigned int port, SDCardManager *sdCardManager) : _wifiServer(port), _sdCardManager(sdCardManager), _httpRequestData({UNDEFINED, UNKNOWN, UNKNOWN_MIME, Dictionary<DictionaryHelper::StringEntity>(), Dictionary<DictionaryHelper::StringEntity>(), NULL,NULL}), _httpParserState(INIT), _clientState(WAITING_FOR_CLIENT), _port(port), _clientTimeout(0)
|
||||||
|
{
|
||||||
|
_wifiServer.begin();
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean WEBServerManager_deprecated::addApiRoutine(const char *uri, boolean (*apiRoutine)(HttpRequestData&, WiFiClient* , void*), void *pData, HttpRequestMethod HRM)
|
||||||
|
{
|
||||||
|
return _apiDictionary.add(uri,new ApiRoutine({apiRoutine,pData, HRM}));
|
||||||
|
}
|
||||||
|
|
||||||
|
void WEBServerManager_deprecated::clearApiRoutine()
|
||||||
|
{
|
||||||
|
_apiDictionary.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean WEBServerManager_deprecated::removeApiRoutine(const char *uri)
|
||||||
|
{
|
||||||
|
return _apiDictionary.remove(uri);
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean WEBServerManager_deprecated::runServer()
|
||||||
|
{
|
||||||
|
switch(_clientState)
|
||||||
|
{
|
||||||
|
case WAITING_FOR_CLIENT:
|
||||||
|
_wifiClient.stopAll();
|
||||||
|
|
||||||
|
_wifiClient = _wifiServer.available();
|
||||||
|
if(_wifiClient)
|
||||||
|
{
|
||||||
|
_clientState = NEW;
|
||||||
|
#ifdef DEBUG
|
||||||
|
Serial.println("Client connected !!!");
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case NEW:
|
||||||
|
_clientState = NOT_HANDLED;
|
||||||
|
break;
|
||||||
|
case NOT_HANDLED:
|
||||||
|
clearHttpRequestData();
|
||||||
|
parseQuery(&_wifiClient);
|
||||||
|
#ifdef DEBUG
|
||||||
|
Serial.println("Nothing more from client !!!");
|
||||||
|
#endif
|
||||||
|
_clientState = QUERY_PARSED;
|
||||||
|
break;
|
||||||
|
case QUERY_PARSED:
|
||||||
|
#ifdef DEBUG
|
||||||
|
Serial.println("Sending response !!!");
|
||||||
|
#endif
|
||||||
|
//We first check if it's an api call
|
||||||
|
if(!sendPageToClientFromApiDictio(&_wifiClient))
|
||||||
|
{
|
||||||
|
sendPageToClientFromSdCard(&_wifiClient);
|
||||||
|
}
|
||||||
|
_clientState = RESPONSE_SENT;
|
||||||
|
break;
|
||||||
|
case RESPONSE_SENT:
|
||||||
|
#ifdef DEBUG
|
||||||
|
Serial.println("Client handled !!!");
|
||||||
|
#endif
|
||||||
|
_clientState = HANDLED;
|
||||||
|
break;
|
||||||
|
case HANDLED:
|
||||||
|
_wifiClient.stopAll();
|
||||||
|
_clientState = WAITING_FOR_CLIENT;
|
||||||
|
#ifdef DEBUG
|
||||||
|
Serial.println("Client discarded !!!");
|
||||||
|
#endif
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean WEBServerManager_deprecated::parseQuery(WiFiClient *wifiClient)
|
||||||
|
{
|
||||||
|
char readChar(0), *parseBuffer(NULL), *parseKey(NULL), *parseValue(NULL), *parseParameter(NULL), *contentLength(NULL);
|
||||||
|
boolean isKey(true), receivingDone(false);
|
||||||
|
unsigned int activeTimeout = 10000;
|
||||||
|
unsigned long dataBytesCounter = 0, dataBytes = 0;
|
||||||
|
|
||||||
|
/* Better way to read data
|
||||||
|
char temp[2048];
|
||||||
|
temp[wifiClient->read((uint8_t*)temp,2040)] = '\0';
|
||||||
|
Serial.print(temp);
|
||||||
|
*/
|
||||||
|
_httpParserState = INIT;
|
||||||
|
_clientTimeout = millis();
|
||||||
|
boolean slashesOrAntiSlashesOnly(true);
|
||||||
|
while((wifiClient->available() || ( millis() - _clientTimeout < activeTimeout)) && wifiClient->connected())
|
||||||
|
{
|
||||||
|
if(wifiClient->available())
|
||||||
|
{
|
||||||
|
readChar = (char)wifiClient->read();
|
||||||
|
|
||||||
|
#ifdef DEBUG_RAW
|
||||||
|
Serial.print(readChar);
|
||||||
|
#endif
|
||||||
|
//INIT, LINE_BREAK, HTTP_VERB_SECTION, HTTP_RESOURCE_SECTION, HTTP_VER_SECTION, BODY_SECTION, IGNORED, ERROR
|
||||||
|
switch(_httpParserState)
|
||||||
|
{
|
||||||
|
case INIT:
|
||||||
|
if(readChar >= 65 && readChar <= 90)
|
||||||
|
{
|
||||||
|
parseBuffer = addChar(parseBuffer, readChar);
|
||||||
|
_httpParserState = HTTP_VERB_SECTION;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
_httpParserState = ERROR;
|
||||||
|
break;
|
||||||
|
case LINE_BREAK:
|
||||||
|
if(readChar == '\n')
|
||||||
|
{
|
||||||
|
if(_httpRequestData.HRM == GET)
|
||||||
|
{
|
||||||
|
#ifdef DEBUG
|
||||||
|
Serial.println("GET DONE");
|
||||||
|
#endif
|
||||||
|
receivingDone = true;
|
||||||
|
}
|
||||||
|
_httpParserState = BODY_SECTION;
|
||||||
|
}
|
||||||
|
else if(readChar != '\r')
|
||||||
|
{
|
||||||
|
if(parseParameter != NULL)
|
||||||
|
{
|
||||||
|
contentLength = strstr(parseParameter, "ent-Len");//Matches Content-Length short to save some RAM
|
||||||
|
if(contentLength != NULL)
|
||||||
|
{
|
||||||
|
dataBytes = strtol(contentLength+11,NULL,10);
|
||||||
|
#ifdef DEBUG_CONTENT_LENGTH
|
||||||
|
Serial.print("Data length : ");Serial.println(dataBytes);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef DEBUG_PARAMETER
|
||||||
|
Serial.println(parseParameter);
|
||||||
|
#endif
|
||||||
|
free(parseParameter);parseParameter = NULL;
|
||||||
|
}
|
||||||
|
parseParameter = addChar(parseParameter, readChar);
|
||||||
|
_httpParserState = PARAMETER_SECTION;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case HTTP_VERB_SECTION:
|
||||||
|
if(readChar >= 65 && readChar <= 90)
|
||||||
|
{
|
||||||
|
parseBuffer = addChar(parseBuffer, readChar);
|
||||||
|
_httpParserState = HTTP_VERB_SECTION;
|
||||||
|
}
|
||||||
|
else if (readChar == ' ')
|
||||||
|
{
|
||||||
|
//This is the end of the section
|
||||||
|
_httpRequestData.HRM = getHttpVerbEnumValue(parseBuffer);
|
||||||
|
free(parseBuffer);parseBuffer = NULL;
|
||||||
|
_httpParserState = HTTP_RESOURCE_SECTION;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
_httpParserState = ERROR;
|
||||||
|
break;
|
||||||
|
case HTTP_RESOURCE_SECTION:
|
||||||
|
if(readChar == '?' )
|
||||||
|
{
|
||||||
|
free(_httpRequestData.httpResource);_httpRequestData.httpResource = NULL;
|
||||||
|
_httpRequestData.httpResource = parseBuffer;parseBuffer = NULL;
|
||||||
|
|
||||||
|
_httpParserState = HTTP_RESOURCE_PARAM_SECTION;
|
||||||
|
}
|
||||||
|
else if(readChar == ' ')
|
||||||
|
{
|
||||||
|
free(_httpRequestData.httpResource);_httpRequestData.httpResource = NULL;
|
||||||
|
if(slashesOrAntiSlashesOnly)
|
||||||
|
{
|
||||||
|
free(parseBuffer);parseBuffer = NULL;
|
||||||
|
_httpRequestData.httpResource = (char *) malloc(sizeof(char)*2);
|
||||||
|
strcpy(_httpRequestData.httpResource,"/");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
_httpRequestData.httpResource = parseBuffer;parseBuffer = NULL;
|
||||||
|
|
||||||
|
_httpParserState = HTTP_VER_SECTION;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if(readChar != '/' && readChar != '\\') slashesOrAntiSlashesOnly = false;
|
||||||
|
|
||||||
|
parseBuffer = addChar(parseBuffer, readChar);
|
||||||
|
_httpParserState = HTTP_RESOURCE_SECTION;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case HTTP_RESOURCE_PARAM_SECTION: //index.web?var1=1&var2=2...
|
||||||
|
if(readChar == ' ')
|
||||||
|
{
|
||||||
|
_httpRequestData.getParams.add(parseKey,new DictionaryHelper::StringEntity(parseValue));
|
||||||
|
free(parseKey);free(parseValue);
|
||||||
|
parseKey = NULL;parseValue = NULL;
|
||||||
|
_httpParserState = HTTP_VER_SECTION;
|
||||||
|
}
|
||||||
|
else if( readChar == '=')
|
||||||
|
isKey = false;
|
||||||
|
else if(readChar == '&')
|
||||||
|
{
|
||||||
|
isKey = true;
|
||||||
|
_httpRequestData.getParams.add(parseKey, new DictionaryHelper::StringEntity(parseValue));
|
||||||
|
free(parseKey);free(parseValue);
|
||||||
|
parseKey = NULL;parseValue = NULL;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if(isKey)
|
||||||
|
parseKey = addChar(parseKey, readChar);
|
||||||
|
else
|
||||||
|
parseValue = addChar(parseValue, readChar);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case HTTP_VER_SECTION:
|
||||||
|
if((readChar >= 48 && readChar <= 57) || readChar == '.')
|
||||||
|
{
|
||||||
|
parseBuffer = addChar(parseBuffer, readChar);
|
||||||
|
_httpParserState = HTTP_VER_SECTION;
|
||||||
|
}
|
||||||
|
else if(readChar == '\n')
|
||||||
|
{
|
||||||
|
_httpRequestData.HV = getHttpVersionEnumValue(parseBuffer);
|
||||||
|
free(parseBuffer);parseBuffer = NULL;
|
||||||
|
_httpParserState = LINE_BREAK;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case BODY_SECTION:
|
||||||
|
//parseBuffer = addChar(parseBuffer, readChar);
|
||||||
|
if(_httpRequestData.HRM != GET)
|
||||||
|
{
|
||||||
|
dataBytesCounter++;//Should be always true
|
||||||
|
}
|
||||||
|
#ifdef DEBUG_BODY
|
||||||
|
Serial.print(readChar);
|
||||||
|
#endif
|
||||||
|
break;
|
||||||
|
case PARAMETER_SECTION: //Here are all the http header params
|
||||||
|
if(readChar == '\n')
|
||||||
|
{
|
||||||
|
_httpParserState = LINE_BREAK;
|
||||||
|
}else
|
||||||
|
parseParameter = addChar(parseParameter, readChar);
|
||||||
|
break;
|
||||||
|
case IGNORED:
|
||||||
|
break;
|
||||||
|
case ERROR:
|
||||||
|
return false;
|
||||||
|
break; //Not necessary
|
||||||
|
default :
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
//Exit condition
|
||||||
|
if(receivingDone) break;
|
||||||
|
if(_httpRequestData.HRM == POST && dataBytes != 0 && dataBytes == dataBytesCounter) break;
|
||||||
|
|
||||||
|
_clientTimeout = millis();
|
||||||
|
}
|
||||||
|
//yield(); //Likely causing a crash
|
||||||
|
ESP.wdtFeed();
|
||||||
|
}
|
||||||
|
|
||||||
|
if(parseBuffer != NULL)
|
||||||
|
{
|
||||||
|
if(strlen(parseBuffer) > 0)
|
||||||
|
{
|
||||||
|
_httpRequestData.httpBody = parseBuffer;
|
||||||
|
parseBuffer = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
free(parseParameter);parseParameter = NULL;
|
||||||
|
|
||||||
|
#ifdef DEBUG
|
||||||
|
Serial.print("HTTP VERB : ");
|
||||||
|
Serial.println(_httpRequestData.HRM);
|
||||||
|
Serial.print("HTTP RESOURCE : ");
|
||||||
|
Serial.println(_httpRequestData.httpResource);
|
||||||
|
Serial.print("HTTP VERSION : ");
|
||||||
|
Serial.println(_httpRequestData.HV);
|
||||||
|
Serial.print("BODY CONTENT : ");
|
||||||
|
Serial.println(_httpRequestData.httpBody);
|
||||||
|
Serial.println("GET PARAMS :");
|
||||||
|
for(int i = 0; i < _httpRequestData.getParams.count(); i++)
|
||||||
|
{
|
||||||
|
Serial.print(_httpRequestData.getParams.getParameter(i));Serial.print(" : ");Serial.println(_httpRequestData.getParams.getAt(i)->getString());
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int WEBServerManager_deprecated::getPort() const
|
||||||
|
{
|
||||||
|
return _port;
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean WEBServerManager_deprecated::sendPageToClientFromSdCard(WiFiClient *wifiClient)
|
||||||
|
{
|
||||||
|
if(_sdCardManager != NULL)
|
||||||
|
{
|
||||||
|
File pageToSend;
|
||||||
|
char readChar(0), *filePath(NULL), *header(NULL), sendBuffer[2048];
|
||||||
|
|
||||||
|
//We check what kind of http verb it is
|
||||||
|
switch(_httpRequestData.HRM)
|
||||||
|
{
|
||||||
|
case GET:
|
||||||
|
filePath = getFilePathByHttpResource(_httpRequestData.httpResource);
|
||||||
|
if(filePath == NULL)
|
||||||
|
{
|
||||||
|
wifiClient->print(F("HTTP/1.1 500 Internal Server Error\r\nContent-Type: text/html\r\n\r\n<!DOCTYPE HTML>\r\n<html>\r\n<p>Failed to malloc filePath</p>\r\n</html>"));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef DEBUG
|
||||||
|
Serial.print("FILE PATH : ");
|
||||||
|
Serial.println(filePath);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
pageToSend = _sdCardManager->open(filePath);
|
||||||
|
free(filePath);filePath = NULL;
|
||||||
|
|
||||||
|
if(!pageToSend)
|
||||||
|
{
|
||||||
|
char *response(NULL);
|
||||||
|
response = (char *) malloc(sizeof(char) * (strlen("HTTP/1.1 404 Not Found\r\nContent-Type: text/html\r\n\r\n<!DOCTYPE HTML>\r\n<html>\r\n<h1>Page not found for : </h1>\r\n<h4></h4>\r\n</html>") + strlen(_httpRequestData.httpResource) + 1));
|
||||||
|
if(response == NULL)
|
||||||
|
{
|
||||||
|
wifiClient->print(F("HTTP/1.1 500 Internal Server Error\r\nContent-Type: text/html\r\n\r\n<!DOCTYPE HTML>\r\n<html>\r\n<h1>Failed to malloc response</h1>\r\n</html>"));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
sprintf(response, "HTTP/1.1 404 Not Found\r\nContent-Type: text/html\r\n\r\n<!DOCTYPE HTML>\r\n<html>\r\n<h1>Page not found for : </h1>\r\n<h4>%s</h4>\r\n</html>", _httpRequestData.httpResource);
|
||||||
|
wifiClient->print(response);
|
||||||
|
free(response);response = NULL;
|
||||||
|
pageToSend.close();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef DEBUG
|
||||||
|
Serial.print("FILE SIZE : ");
|
||||||
|
Serial.println(pageToSend.size());
|
||||||
|
Serial.print("FILE NAME : ");
|
||||||
|
Serial.println(pageToSend.name());
|
||||||
|
Serial.print("FILE EXTENSION : ");
|
||||||
|
//Serial.println(getFileExtension(pageToSend.name()));
|
||||||
|
#endif
|
||||||
|
|
||||||
|
header = getHTTPHeader(getMIMETypeByExtension(getFileExtension(/*pageToSend.name()*/ "dummy")), pageToSend.size());
|
||||||
|
if(header == NULL)
|
||||||
|
{
|
||||||
|
wifiClient->print(F("HTTP/1.1 500 Internal Server Error\r\nContent-Type: text/html\r\n\r\n<!DOCTYPE HTML>\r\n<html>\r\n<h1>Failed to malloc header</h1>\r\n</html>"));
|
||||||
|
pageToSend.close();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
wifiClient->print(header);
|
||||||
|
free(header);header = NULL;
|
||||||
|
|
||||||
|
while(pageToSend.available())
|
||||||
|
{
|
||||||
|
//if(wifiClient->write(sendBuffer, pageToSend.read(sendBuffer,2048)) == 0)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
pageToSend.close();
|
||||||
|
break;
|
||||||
|
default: //If not supported
|
||||||
|
wifiClient->print(F("HTTP/1.1 405 Method Not Allowed\r\nContent-Type: text/html\r\n\r\n<!DOCTYPE HTML>\r\n<html>\r\n<h1>Method Not Allowed</h1>\r\n</html>"));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}else
|
||||||
|
{
|
||||||
|
wifiClient->print(F("HTTP/1.1 500 Internal Server Error\r\nContent-Type: text/html\r\n\r\n<!DOCTYPE HTML>\r\n<html>\r\n<h1>SDCardManager is NULL<br \\>Check code</h1>\r\n</html>"));
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean WEBServerManager_deprecated::sendPageToClientFromApiDictio(WiFiClient *wifiClient)
|
||||||
|
{
|
||||||
|
if(_apiDictionary.count() == 0 || _httpRequestData.httpResource == NULL)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
ApiRoutine *ref = _apiDictionary(_httpRequestData.httpResource);
|
||||||
|
|
||||||
|
if(ref == NULL)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if(ref->HRM == UNDEFINED)
|
||||||
|
{
|
||||||
|
return (*(ref->apiRoutine))(_httpRequestData, wifiClient, ref->pData);
|
||||||
|
}else if(ref->HRM == _httpRequestData.HRM)
|
||||||
|
{
|
||||||
|
return (*(ref->apiRoutine))(_httpRequestData, wifiClient, ref->pData);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
WEBServerManager_deprecated::HttpMIMEType WEBServerManager_deprecated::getMIMETypeByExtension(const char *extension)
|
||||||
|
{
|
||||||
|
//TEXT_PLAIN, TEXT_CSS, TEXT_HTML, TEXT_JAVASCRIPT
|
||||||
|
if(strcmp(extension,"web") == 0) return TEXT_HTML;
|
||||||
|
else if(strcmp(extension,"htm") == 0) return TEXT_HTML;
|
||||||
|
else if(strcmp(extension,"css") == 0) return TEXT_CSS;
|
||||||
|
else if(strcmp(extension,"js") == 0) return TEXT_JAVASCRIPT;
|
||||||
|
else if(strcmp(extension,"png") == 0) return IMAGE_PNG;
|
||||||
|
else if(strcmp(extension,"jpg") == 0) return IMAGE_JPEG;
|
||||||
|
else if(strcmp(extension, "mp3") == 0) return AUDIO_MPEG;
|
||||||
|
else return UNKNOWN_MIME;
|
||||||
|
}
|
||||||
|
|
||||||
|
char *WEBServerManager_deprecated::getHTTPHeader(HttpMIMEType httpMIMEType, unsigned long size)
|
||||||
|
{
|
||||||
|
char *header = (char *) malloc(sizeof(char) + strlen("HTTP/1.1 200 OK\r\nContent-Type: \r\nContent-Length: \r\n\r\n") + 74/*Longest MIME-TYPE*/ + 10 /*Max unsigned long footprint*/ + 1);
|
||||||
|
|
||||||
|
switch(httpMIMEType)
|
||||||
|
{
|
||||||
|
case TEXT_HTML:
|
||||||
|
sprintf(header,"HTTP/1.1 200 OK\r\nContent-Type: %s\r\nContent-Length: %lu\r\n\r\n","text/html",size);
|
||||||
|
break;
|
||||||
|
case TEXT_CSS:
|
||||||
|
sprintf(header,"HTTP/1.1 200 OK\r\nContent-Type: %s\r\nContent-Length: %lu\r\n\r\n","text/css",size);
|
||||||
|
break;
|
||||||
|
case TEXT_JAVASCRIPT:
|
||||||
|
sprintf(header,"HTTP/1.1 200 OK\r\nContent-Type: %s\r\nContent-Length: %lu\r\n\r\n","text/javascript",size);
|
||||||
|
break;
|
||||||
|
case IMAGE_PNG:
|
||||||
|
sprintf(header,"HTTP/1.1 200 OK\r\nContent-Type: %s\r\nContent-Length: %lu\r\n\r\n","image/png",size);
|
||||||
|
break;
|
||||||
|
case IMAGE_JPEG:
|
||||||
|
sprintf(header,"HTTP/1.1 200 OK\r\nContent-Type: %s\r\nContent-Length: %lu\r\n\r\n","image/jpeg",size);
|
||||||
|
break;
|
||||||
|
case TEXT_PLAIN:
|
||||||
|
sprintf(header,"HTTP/1.1 200 OK\r\nContent-Type: %s\r\nContent-Length: %lu\r\n\r\n","text/plain",size);
|
||||||
|
break;
|
||||||
|
case AUDIO_MPEG:
|
||||||
|
sprintf(header,"HTTP/1.1 200 OK\r\nContent-Type: %s\r\nContent-Length: %lu\r\n\r\n","audio/mpeg",size);
|
||||||
|
break;
|
||||||
|
case APPLICATION_OCTET_STREAM:
|
||||||
|
sprintf(header,"HTTP/1.1 200 OK\r\nContent-Type: %s\r\nContent-Length: %lu\r\n\r\n","application/octet-stream",size);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
sprintf(header,"HTTP/1.1 200 OK\r\nContent-Type: %s\r\nContent-Length: %lu\r\n\r\n","application/octet-stream",size);
|
||||||
|
break;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return header;
|
||||||
|
}
|
||||||
|
|
||||||
|
char *WEBServerManager_deprecated::getFileExtension(char *name)
|
||||||
|
{
|
||||||
|
if(name == NULL)return "";
|
||||||
|
|
||||||
|
char *ptr(name);
|
||||||
|
int index(0);
|
||||||
|
while(ptr[index] != '\0')
|
||||||
|
{
|
||||||
|
if(ptr[++index] == '.')
|
||||||
|
{
|
||||||
|
return (name + index +1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
char *WEBServerManager_deprecated::getFilePathByHttpResource(char *res)
|
||||||
|
{
|
||||||
|
uint16_t buffSize = strlen(WWW_DIR) + (strcmp(res, "/") == 0 ? 10:strlen(res)) + 1;//10 for /index.htm +1 for \0
|
||||||
|
char *filePath = (char*) malloc( sizeof(char) * buffSize);
|
||||||
|
|
||||||
|
if(filePath == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
strcpy(filePath, WWW_DIR);
|
||||||
|
strcat(filePath, strcmp(res, "/") == 0 ? "/index.htm":res);
|
||||||
|
//sprintf(filePath,"%s%s",WWW_DIR, strcmp(res, "/") == 0 ? "/index.htm":res);
|
||||||
|
|
||||||
|
#ifdef DEBUG_FILEPATH
|
||||||
|
Serial.println(res);
|
||||||
|
Serial.print("Reserved space : ");Serial.println(buffSize);
|
||||||
|
Serial.print("Actual size : ");Serial.println(strlen(filePath));
|
||||||
|
Serial.println(filePath);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return filePath;
|
||||||
|
}
|
||||||
|
|
||||||
|
WEBServerManager_deprecated::HttpRequestMethod WEBServerManager_deprecated::getHttpVerbEnumValue(const char *parseBuffer)
|
||||||
|
{
|
||||||
|
//UNDEFINED, GET, HEAD, POST, PUT, DELETE, CONNECT, OPTIONS, TRACE, PATCH
|
||||||
|
if(strcmp(parseBuffer,"GET") == 0){return GET;}
|
||||||
|
else if(strcmp(parseBuffer,"POST") == 0){return POST;}
|
||||||
|
else if(strcmp(parseBuffer,"HEAD") == 0){return HEAD;}
|
||||||
|
else if(strcmp(parseBuffer,"PUT") == 0){return PUT;}
|
||||||
|
else if(strcmp(parseBuffer,"DELETE") == 0){return DELETE;}
|
||||||
|
else if(strcmp(parseBuffer,"CONNECT") == 0){return CONNECT;}
|
||||||
|
else if(strcmp(parseBuffer,"TRACE") == 0){return TRACE;}
|
||||||
|
else if(strcmp(parseBuffer,"PATCH") == 0){return PATCH;}
|
||||||
|
else if(strcmp(parseBuffer,"OPTIONS") == 0){return OPTIONS;}
|
||||||
|
else
|
||||||
|
return UNDEFINED;
|
||||||
|
}
|
||||||
|
|
||||||
|
WEBServerManager_deprecated::HttpVersion WEBServerManager_deprecated::getHttpVersionEnumValue(const char *parseBuffer)
|
||||||
|
{
|
||||||
|
//HTTP_0_9, HTTP_1_1, HTTP_1_0, HTTP_2_0
|
||||||
|
if(strcmp(parseBuffer,"1.1") == 0){return HTTP_1_1;}
|
||||||
|
else if(strcmp(parseBuffer,"2.0") == 0){return HTTP_2_0;}
|
||||||
|
else if(strcmp(parseBuffer,"1.0") == 0){return HTTP_1_0;}
|
||||||
|
else if(strcmp(parseBuffer,"0.9") == 0){return HTTP_0_9;}
|
||||||
|
else
|
||||||
|
return UNKNOWN;
|
||||||
|
}
|
||||||
|
|
||||||
|
void WEBServerManager_deprecated::clearHttpRequestData()
|
||||||
|
{
|
||||||
|
_httpRequestData.HRM = UNDEFINED;
|
||||||
|
_httpRequestData.HV = UNKNOWN;
|
||||||
|
_httpRequestData.HMT = UNKNOWN_MIME;
|
||||||
|
free(_httpRequestData.httpResource);free(_httpRequestData.httpBody);
|
||||||
|
_httpRequestData.httpResource = NULL;_httpRequestData.httpBody = NULL;
|
||||||
|
_httpRequestData.getParams.dispose();
|
||||||
|
_httpRequestData.postParams.dispose();
|
||||||
|
}
|
81
src/app/WEBServerManager_deprecated.h
Normal file
81
src/app/WEBServerManager_deprecated.h
Normal file
@ -0,0 +1,81 @@
|
|||||||
|
/**
|
||||||
|
* @file WEBServerManager.h
|
||||||
|
* @author Anatole SCHRAMM-HENRY
|
||||||
|
* @brief Single client WEB Server.
|
||||||
|
* This class is now retired and replaced by the much better WEBServer class
|
||||||
|
* which handles multiclients among other things.
|
||||||
|
* @version 0.1
|
||||||
|
* @date 31/03/2019
|
||||||
|
*
|
||||||
|
* @copyright MIT
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#ifndef WEBSERVERMANAGERDEPRECATED_H
|
||||||
|
#define WEBSERVERMANAGERDEPRECATED_H
|
||||||
|
|
||||||
|
#include <WiFiServer.h>
|
||||||
|
#include <WiFiClient.h>
|
||||||
|
#include "SDCardManager.h"
|
||||||
|
#include "definition.h"
|
||||||
|
#include "Dictionary.h"
|
||||||
|
|
||||||
|
struct HttpRequestData;
|
||||||
|
|
||||||
|
class WEBServerManager_deprecated
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
enum ClientStatus {NOT_HANDLED, HANDLED, NEW, WAITING_FOR_CLIENT, QUERY_PARSED, RESPONSE_SENT};
|
||||||
|
enum HttpRequestMethod {UNDEFINED, GET, HEAD, POST, PUT, DELETE, CONNECT, OPTIONS, TRACE, PATCH};
|
||||||
|
enum HttpVersion {UNKNOWN, HTTP_0_9, HTTP_1_1, HTTP_1_0, HTTP_2_0};
|
||||||
|
enum HttpParserStatus {INIT, LINE_BREAK, HTTP_VERB_SECTION, HTTP_RESOURCE_SECTION, HTTP_RESOURCE_PARAM_SECTION, HTTP_VER_SECTION, PARAMETER_SECTION, BODY_SECTION, IGNORED, ERROR};
|
||||||
|
enum HttpMIMEType{UNKNOWN_MIME, TEXT_PLAIN, TEXT_CSS, TEXT_HTML, TEXT_JAVASCRIPT, APPLICATION_JSON, APPLICATION_X_WWW_FORM_URLENCODED, IMAGE_PNG, IMAGE_JPEG, AUDIO_MPEG, APPLICATION_OCTET_STREAM};
|
||||||
|
struct HttpRequestData{
|
||||||
|
HttpRequestMethod HRM;
|
||||||
|
HttpVersion HV;
|
||||||
|
HttpMIMEType HMT;
|
||||||
|
Dictionary<DictionaryHelper::StringEntity> getParams;
|
||||||
|
Dictionary<DictionaryHelper::StringEntity> postParams;
|
||||||
|
char *httpResource;
|
||||||
|
char *httpBody;
|
||||||
|
};
|
||||||
|
|
||||||
|
WEBServerManager_deprecated(unsigned int port = 80, SDCardManager *sdCardManager = NULL);
|
||||||
|
|
||||||
|
boolean runServer();
|
||||||
|
unsigned int getPort() const;
|
||||||
|
boolean addApiRoutine(const char *uri, boolean (*apiRoutine)(HttpRequestData&, WiFiClient*, void*), void *pData, HttpRequestMethod HRM = UNDEFINED);
|
||||||
|
void clearApiRoutine();
|
||||||
|
boolean removeApiRoutine(const char *uri);
|
||||||
|
protected:
|
||||||
|
private:
|
||||||
|
struct ApiRoutine
|
||||||
|
{
|
||||||
|
boolean (*apiRoutine)(HttpRequestData&, WiFiClient*, void*);
|
||||||
|
void *pData;
|
||||||
|
HttpRequestMethod HRM;
|
||||||
|
};
|
||||||
|
|
||||||
|
boolean parseQuery(WiFiClient *wifiClient);
|
||||||
|
boolean sendPageToClientFromSdCard(WiFiClient *wifiClient);
|
||||||
|
boolean sendPageToClientFromApiDictio(WiFiClient *wifiClient);
|
||||||
|
HttpRequestMethod getHttpVerbEnumValue(const char *parseBuffer);
|
||||||
|
HttpVersion getHttpVersionEnumValue(const char *parseBuffer);
|
||||||
|
char *getFilePathByHttpResource(char *res);
|
||||||
|
char *getFileExtension(char *name);
|
||||||
|
HttpMIMEType getMIMETypeByExtension(const char *extension);
|
||||||
|
char *getHTTPHeader(HttpMIMEType httpMIMEType, unsigned long size);
|
||||||
|
void clearHttpRequestData();
|
||||||
|
|
||||||
|
WiFiServer _wifiServer;
|
||||||
|
WiFiClient _wifiClient;//One client only, may be replaced with a fifo in the future
|
||||||
|
SDCardManager *_sdCardManager;
|
||||||
|
HttpRequestData _httpRequestData;
|
||||||
|
Dictionary<ApiRoutine> _apiDictionary;
|
||||||
|
|
||||||
|
ClientStatus _clientState;
|
||||||
|
HttpParserStatus _httpParserState;
|
||||||
|
unsigned long _clientTimeout;
|
||||||
|
unsigned int _port;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif //WEBSERVERMANAGERDEPRECATED_H
|
@ -74,34 +74,35 @@ void setup()
|
|||||||
sab.getRtcManager().setDateTime(sab.getRTC_DS3231().now());
|
sab.getRtcManager().setDateTime(sab.getRTC_DS3231().now());
|
||||||
}
|
}
|
||||||
|
|
||||||
sab.getWebServer().addApiRoutine("/sab/web/apitester", &(apiTesterApi), NULL);
|
sab.getWebServerManager().getWEBServer().addApiRoutine("/sab/web/apitester", &(apiTesterApi), NULL);
|
||||||
sab.getWebServer().addApiRoutine("/sab/view/next", &(nextViewApi), &sab, WEBServer<WEBClient>::GET);
|
sab.getWebServerManager().getWEBServer().addApiRoutine("/sab/view/next", &(nextViewApi), &sab, WEBServer<WEBClient>::GET);
|
||||||
sab.getWebServer().addApiRoutine("/sab/view/reloadcfg", &(reloadViewApi), &sab, WEBServer<WEBClient>::GET);
|
sab.getWebServerManager().getWEBServer().addApiRoutine("/sab/view/reloadcfg", &(reloadViewApi), &sab, WEBServer<WEBClient>::GET);
|
||||||
sab.getWebServer().addApiRoutine("/sab/view", &(viewByUIDApi), &sab, WEBServer<WEBClient>::GET);
|
sab.getWebServerManager().getWEBServer().addApiRoutine("/sab/view", &(viewByUIDApi), &sab, WEBServer<WEBClient>::GET);
|
||||||
sab.getWebServer().addApiRoutine("/sab/rtc/get/datetime", &(rtcGetTimeApi), &sab, WEBServer<WEBClient>::GET);
|
sab.getWebServerManager().getWEBServer().addApiRoutine("/sab/rtc/get/datetime", &(rtcGetTimeApi), &sab, WEBServer<WEBClient>::GET);
|
||||||
sab.getWebServer().addApiRoutine("/sab/rtc/set/datetime", &(rtcSetTimeApi), &sab, WEBServer<WEBClient>::GET);
|
sab.getWebServerManager().getWEBServer().addApiRoutine("/sab/rtc/set/datetime", &(rtcSetTimeApi), &sab, WEBServer<WEBClient>::GET);
|
||||||
sab.getWebServer().addApiRoutine("/sab/sdcard/size", &(sdCardSizeApi), &sab, WEBServer<WEBClient>::GET);
|
sab.getWebServerManager().getWEBServer().addApiRoutine("/sab/sdcard/size", &(sdCardSizeApi), &sab, WEBServer<WEBClient>::GET);
|
||||||
sdCardApiPacket.pSab = &sab;sdCardApiPacket.pView = &v1p;
|
sdCardApiPacket.pSab = &sab;sdCardApiPacket.pView = &v1p;
|
||||||
sab.getWebServer().addApiRoutine("/sab/sdcard/action", &(sdCardActionApi), &sdCardApiPacket, WEBServer<WEBClient>::GET);
|
sab.getWebServerManager().getWEBServer().addApiRoutine("/sab/sdcard/action", &(sdCardActionApi), &sdCardApiPacket, WEBServer<WEBClient>::GET);
|
||||||
|
|
||||||
sab.getWebServer().addApiRoutine("/esp/restart", &(espRestartApi), &sab, WEBServer<WEBClient>::GET);
|
sab.getWebServerManager().getWEBServer().addApiRoutine("/esp/restart", &(espRestartApi), &sab, WEBServer<WEBClient>::GET);
|
||||||
sab.getWebServer().addApiRoutine("/esp/reset", &(espResetApi), &sab, WEBServer<WEBClient>::GET);
|
sab.getWebServerManager().getWEBServer().addApiRoutine("/esp/reset", &(espResetApi), &sab, WEBServer<WEBClient>::GET);
|
||||||
sab.getWebServer().addApiRoutine("/sab/wifi/stainfo", &(staWifiInfoApi), &sab, WEBServer<WEBClient>::GET);
|
sab.getWebServerManager().getWEBServer().addApiRoutine("/sab/wifi/stainfo", &(staWifiInfoApi), &sab, WEBServer<WEBClient>::GET);
|
||||||
sab.getWebServer().addApiRoutine("/sab/wifi/scanner", &(apScannerApi), NULL, WEBServer<WEBClient>::GET);
|
sab.getWebServerManager().getWEBServer().addApiRoutine("/sab/wifi/scanner", &(apScannerApi), NULL, WEBServer<WEBClient>::GET);
|
||||||
sab.getWebServer().addApiRoutine("/sab/systeminfo", &(systemInfoApi), &sab, WEBServer<WEBClient>::GET);
|
sab.getWebServerManager().getWEBServer().addApiRoutine("/sab/systeminfo", &(systemInfoApi), &sab, WEBServer<WEBClient>::GET);
|
||||||
sab.getWebServer().addApiRoutine("/sab/power/info", &(powerInfoApi), &sab, WEBServer<WEBClient>::GET);
|
sab.getWebServerManager().getWEBServer().addApiRoutine("/sab/power/info", &(powerInfoApi), &sab, WEBServer<WEBClient>::GET);
|
||||||
sab.getWebServer().addApiRoutine("/sab/io/get/level", &(ioGetLevelApi), vio.ioState, WEBServer<WEBClient>::GET);
|
sab.getWebServerManager().getWEBServer().addApiRoutine("/sab/io/get/level", &(ioGetLevelApi), vio.ioState, WEBServer<WEBClient>::GET);
|
||||||
sab.getWebServer().addApiRoutine("/sab/io/set/level", &(ioSetLevelApi), &sab, WEBServer<WEBClient>::GET);
|
sab.getWebServerManager().getWEBServer().addApiRoutine("/sab/io/set/level", &(ioSetLevelApi), &sab, WEBServer<WEBClient>::GET);
|
||||||
sab.getWebServer().addApiRoutine("/sab/io/get/mode", &(ioGetModeApi), &sab, WEBServer<WEBClient>::GET);
|
sab.getWebServerManager().getWEBServer().addApiRoutine("/sab/io/get/mode", &(ioGetModeApi), &sab, WEBServer<WEBClient>::GET);
|
||||||
sab.getWebServer().addApiRoutine("/sab/io/set/mode", &(ioSetModeApi), &sab, WEBServer<WEBClient>::GET);
|
sab.getWebServerManager().getWEBServer().addApiRoutine("/sab/io/set/mode", &(ioSetModeApi), &sab, WEBServer<WEBClient>::GET);
|
||||||
sab.getWebServer().addApiRoutine("/sab/sw/version", &(swVersionApi), &sab, WEBServer<WEBClient>::GET);
|
sab.getWebServerManager().getWEBServer().addApiRoutine("/sab/sw/version", &(swVersionApi), &sab, WEBServer<WEBClient>::GET);
|
||||||
sab.getWebServer().addApiRoutine("/sab/ota/update/upload", &(otaUpdateUploadApi), NULL, WEBServer<WEBClient>::POST);
|
sab.getWebServerManager().getWEBServer().addApiRoutine("/sab/ota/update/upload", &(otaUpdateUploadApi), NULL, WEBServer<WEBClient>::POST);
|
||||||
sab.getWebServer().addApiRoutine("/sab/ota/update/device", &(otaUpdateRemoteApi), &sab, WEBServer<WEBClient>::GET);
|
sab.getWebServerManager().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);
|
||||||
|
sab.getTaskSchedulerManager().addTask(2, TaskSchedulerManagerHelper::Schedule::scheduleBuilder()->setSeconds(5), &(testTask), &sab);
|
||||||
//dataLogger.client.keepAlive(true);
|
//dataLogger.client.keepAlive(true);
|
||||||
//sab.getTaskSchedulerManager().addTask(2, TaskSchedulerManagerHelper::Schedule::scheduleBuilder()->setSeconds(1)->setTriggerRightAway(false), &(task_post_data_logger), &dataLogger);
|
//sab.getTaskSchedulerManager().addTask(2, TaskSchedulerManagerHelper::Schedule::scheduleBuilder()->setSeconds(1)->setTriggerRightAway(false), &(task_post_data_logger), &dataLogger);
|
||||||
|
|
||||||
|
@ -27,7 +27,7 @@ boolean task_sys_info(void *pData)
|
|||||||
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->getConnectivityManager().macAddress().c_str(),
|
||||||
p->sab->getWebServer().getConnectedClientsCount(),
|
p->sab->getWebServerManager().getWEBServer().getConnectedClientsCount(),
|
||||||
freeRAM,
|
freeRAM,
|
||||||
HEAPfrag,
|
HEAPfrag,
|
||||||
biggestContigMemBlock);
|
biggestContigMemBlock);
|
||||||
@ -108,3 +108,10 @@ boolean task_post_data_logger(void * pData)
|
|||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
boolean testTask(void *pData)
|
||||||
|
{
|
||||||
|
SAB *pSab = (SAB *)pData;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
@ -8,6 +8,7 @@
|
|||||||
boolean task_blink(void *);
|
boolean task_blink(void *);
|
||||||
boolean task_sys_info(void *);
|
boolean task_sys_info(void *);
|
||||||
boolean task_esp_reset_restart(void *);
|
boolean task_esp_reset_restart(void *);
|
||||||
|
boolean testTask(void *);
|
||||||
|
|
||||||
typedef struct dataLogger
|
typedef struct dataLogger
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user