Compare commits
3 Commits
63ead30ad0
...
29ae07da64
Author | SHA1 | Date | |
---|---|---|---|
|
29ae07da64 | ||
|
dc21169fbd | ||
|
45b7a6245c |
@ -7,7 +7,8 @@ _screenConfig.getHeight(), &Wire),
|
||||
_screenManager(_display), _rtc(),
|
||||
_rtcManager(_rtc), _sdCardManager(),
|
||||
_connectivityManager(NULL),
|
||||
_webServerManager(80, &_sdCardManager),
|
||||
//_webServerManager(80, &_sdCardManager),
|
||||
_webServer(80, &_sdCardManager),
|
||||
_pcf(0x27, Wire),
|
||||
_ioManager(_pcf),
|
||||
_taskSchedulerManager(_rtcManager),
|
||||
@ -37,7 +38,8 @@ _rtc(),
|
||||
_rtcManager(_rtc),
|
||||
_sdCardManager(),
|
||||
_connectivityManager(NULL),
|
||||
_webServerManager(webServerPort, &_sdCardManager),
|
||||
//_webServerManager(webServerPort, &_sdCardManager),
|
||||
_webServer(webServerPort, &_sdCardManager),
|
||||
_pcf(0x27, Wire),
|
||||
_ioManager(_pcf),
|
||||
_taskSchedulerManager(_rtcManager),
|
||||
@ -82,9 +84,14 @@ ConnectivityManager& SAB::getConnectivityManager()
|
||||
return *_connectivityManager;
|
||||
}
|
||||
|
||||
WEBServerManager& SAB::getWebServerManager()
|
||||
/*WEBServerManager& SAB::getWebServerManager()
|
||||
{
|
||||
return _webServerManager;
|
||||
}*/
|
||||
|
||||
WEBServer<WEBClient>& SAB::getWebServer()
|
||||
{
|
||||
return _webServer;
|
||||
}
|
||||
|
||||
IOManager& SAB::getIoManager()
|
||||
|
@ -7,7 +7,8 @@
|
||||
#include "ScreenManager.h"
|
||||
#include "SDCardManager.h"
|
||||
#include "ConnectivityManager.h"
|
||||
#include "WEBServerManager.h"
|
||||
//#include "WEBServerManager.h"
|
||||
#include "WEBClient.h" //includes WEBServer internally
|
||||
#include "IOManager.h"
|
||||
#include "TaskSchedulerManager.h"
|
||||
#include "PowerManager.h"
|
||||
@ -32,7 +33,8 @@ class SAB
|
||||
RtcManager& getRtcManager();
|
||||
SDCardManager& getSdCardManager();
|
||||
ConnectivityManager& getConnectivityManager();
|
||||
WEBServerManager& getWebServerManager();
|
||||
//WEBServerManager& getWebServerManager();
|
||||
WEBServer<WEBClient>& getWebServer();
|
||||
IOManager& getIoManager();
|
||||
TaskSchedulerManager& getTaskSchedulerManager();
|
||||
PowerManager& getPowerManager();
|
||||
@ -53,7 +55,8 @@ class SAB
|
||||
RtcManager _rtcManager;
|
||||
SDCardManager _sdCardManager;
|
||||
ConnectivityManager *_connectivityManager;
|
||||
WEBServerManager _webServerManager;
|
||||
//WEBServerManager _webServerManager;
|
||||
WEBServer<WEBClient> _webServer;
|
||||
PCF8574 _pcf;
|
||||
IOManager _ioManager;
|
||||
TaskSchedulerManager _taskSchedulerManager;
|
||||
|
82
src/app/TCPClient.cpp
Normal file
82
src/app/TCPClient.cpp
Normal file
@ -0,0 +1,82 @@
|
||||
#include "TCPClient.h"
|
||||
|
||||
//#define DEBUG_CL
|
||||
|
||||
TCPClient::TCPClient(WiFiClient client, uint8_t id, uint16_t dataBufferSize) : _client(client),
|
||||
_clientState(NEW),
|
||||
_error(OK),
|
||||
_data(NULL),
|
||||
_dataSize(0),
|
||||
_dataBufferSize(dataBufferSize+1),
|
||||
_newDataAvailable(false),
|
||||
_id(id)
|
||||
{
|
||||
#ifdef DEBUG_CL
|
||||
Serial.println("TCPClient : Standard constructor called");
|
||||
#endif
|
||||
|
||||
uint8_t *p = (uint8_t *) malloc(sizeof(uint8_t) * _dataBufferSize);
|
||||
if(p != NULL)
|
||||
_data = p;
|
||||
else
|
||||
_error = MALLOC_ERR;
|
||||
}
|
||||
|
||||
TCPClient::TCPClient(const TCPClient &Object) : _client(Object._client),
|
||||
_clientState(Object._clientState),
|
||||
_error(Object._error),
|
||||
_data(NULL),
|
||||
_dataSize(Object._dataSize),
|
||||
_dataBufferSize(Object._dataBufferSize),
|
||||
_newDataAvailable(Object._newDataAvailable),
|
||||
_id(Object._id)
|
||||
{
|
||||
#ifdef DEBUG_CL
|
||||
Serial.println("TCPClient : Copy constructor called");
|
||||
#endif
|
||||
|
||||
uint8_t *p = (uint8_t *) malloc(sizeof(uint8_t) * _dataBufferSize);
|
||||
if(p != NULL)
|
||||
{
|
||||
_data = p;
|
||||
memcpy(_data,Object._data,_dataSize);
|
||||
}
|
||||
else
|
||||
_error = MALLOC_ERR;
|
||||
}
|
||||
|
||||
TCPClient::~TCPClient()
|
||||
{
|
||||
#ifdef DEBUG_CL
|
||||
Serial.println("TCPClient : Destructor called");
|
||||
#endif
|
||||
|
||||
free(_data);
|
||||
}
|
||||
|
||||
bool TCPClient::operator==(TCPClient& Object)
|
||||
{
|
||||
return this->_client == Object._client;
|
||||
}
|
||||
|
||||
bool TCPClient::closeConnection()
|
||||
{
|
||||
_client.stop();
|
||||
}
|
||||
|
||||
void TCPClient::freeDataBuffer(uint16_t size)
|
||||
{
|
||||
if(size > _dataBufferSize-1) size = _dataBufferSize - 1;
|
||||
|
||||
uint16_t secureSize = size > _dataSize ? _dataSize : size;
|
||||
|
||||
if(*(_data + secureSize) == '\0')
|
||||
{
|
||||
#ifdef DEBUG_CL
|
||||
Serial.println("Its the terminating string");
|
||||
#endif
|
||||
}
|
||||
|
||||
strcpy((char *)_data, (char *)_data + secureSize);
|
||||
_dataSize -= secureSize;
|
||||
}
|
34
src/app/TCPClient.h
Normal file
34
src/app/TCPClient.h
Normal file
@ -0,0 +1,34 @@
|
||||
#ifndef TCPCLIENT_H
|
||||
#define TCPCLIENT_H
|
||||
|
||||
#include <ESP8266WiFi.h>
|
||||
|
||||
//Forward class declaration
|
||||
template <typename T> class TCPServer;
|
||||
|
||||
class TCPClient
|
||||
{
|
||||
template<typename T>
|
||||
friend class TCPServer;
|
||||
public:
|
||||
TCPClient(WiFiClient client, uint8_t id, uint16_t dataBufferSize = 255);
|
||||
TCPClient(const TCPClient &Object);
|
||||
virtual ~TCPClient();
|
||||
bool operator==(TCPClient& Object);
|
||||
bool closeConnection();
|
||||
protected:
|
||||
enum ClientState {NEW, HANDLED, DISCARDED} _clientState;
|
||||
enum Error {OK = 0, MALLOC_ERR = 1} _error;
|
||||
|
||||
WiFiClient _client;
|
||||
uint8_t *_data; //The actual data
|
||||
uint16_t _dataSize; //The logic size of the data contained
|
||||
uint16_t _dataBufferSize; //The physic size of the buffer
|
||||
boolean _newDataAvailable;
|
||||
uint8_t _id;
|
||||
|
||||
void freeDataBuffer(uint16_t size);
|
||||
private:
|
||||
};
|
||||
|
||||
#endif //TCPCLIENT_H
|
199
src/app/TCPServer.h
Normal file
199
src/app/TCPServer.h
Normal file
@ -0,0 +1,199 @@
|
||||
#ifndef TCPSERVER_H
|
||||
#define TCPSERVER_H
|
||||
|
||||
#include <ESP8266WiFi.h>
|
||||
#include "List.h"
|
||||
#include "TCPClient.h"
|
||||
|
||||
#define MAX_CLIENT -1
|
||||
//#define DEBUG_TCPS
|
||||
|
||||
|
||||
template <typename T>
|
||||
class TCPServer
|
||||
{
|
||||
public:
|
||||
TCPServer(unsigned int port = 80, uint8_t maxClient = MAX_CLIENT, uint16_t clientDataBufferSize = 255) : _wifiServer(port), _port(port), _serverStarted(true), _maxClient(maxClient), _clientDataBufferSize(clientDataBufferSize), _currentClient(NULL)
|
||||
{
|
||||
_wifiServer.begin();
|
||||
}
|
||||
|
||||
virtual ~TCPServer()
|
||||
{
|
||||
_clientList.dispose();
|
||||
}
|
||||
|
||||
uint8_t getMaxClient()
|
||||
{
|
||||
return _maxClient;
|
||||
}
|
||||
|
||||
unsigned int getPort() const
|
||||
{
|
||||
return _port;
|
||||
}
|
||||
|
||||
uint8_t getConnectedClientsCount()
|
||||
{
|
||||
return _clientList.count();
|
||||
}
|
||||
|
||||
virtual void runServer()
|
||||
{
|
||||
handleNewClients();
|
||||
getClientData();
|
||||
}
|
||||
|
||||
virtual void startServer()
|
||||
{
|
||||
if(!_serverStarted)
|
||||
{
|
||||
_wifiServer.begin();
|
||||
_serverStarted = true;
|
||||
}
|
||||
}
|
||||
|
||||
virtual void stopServer()
|
||||
{
|
||||
if(_serverStarted)
|
||||
{
|
||||
_wifiServer.stop();
|
||||
_clientList.dispose();
|
||||
_serverStarted = false;
|
||||
}
|
||||
}
|
||||
|
||||
protected:
|
||||
virtual T* createNewClient(WiFiClient wc)
|
||||
{
|
||||
return new T(wc, freeClientId(), _clientDataBufferSize);
|
||||
}
|
||||
|
||||
virtual void handleNewClients()
|
||||
{
|
||||
WiFiClient wc;
|
||||
|
||||
if(_maxClient == -1 || _maxClient > _clientList.count())
|
||||
{
|
||||
wc = _wifiServer.available();
|
||||
}
|
||||
|
||||
if(wc && wc.connected())
|
||||
{
|
||||
T *clientPointer = createNewClient(wc);
|
||||
_clientList.addFirst(clientPointer);
|
||||
#ifdef DEBUG_TCPS
|
||||
Serial.print("TCPServer : New client accepted : ");Serial.println(clientPointer->_id);
|
||||
#endif
|
||||
greetClient(clientPointer);
|
||||
}
|
||||
|
||||
_currentClient = _clientList.removeLastRef();//We pick a client in the list to process it's request
|
||||
|
||||
if(_currentClient != NULL)
|
||||
{
|
||||
if(_currentClient->_error != TCPClient::OK)
|
||||
{
|
||||
_currentClient->closeConnection();
|
||||
delete _currentClient; _currentClient = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
virtual void greetClient(T *client)
|
||||
{
|
||||
client->_client.println(F("Successfully connected !"));
|
||||
client->_client.print(F("Your are client with id : "));
|
||||
client->_client.println(client->_id);
|
||||
}
|
||||
|
||||
virtual void getClientData()
|
||||
{
|
||||
if(_currentClient == NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
uint32_t bytesAvailable((_currentClient->_client).available());
|
||||
|
||||
if(bytesAvailable)
|
||||
{
|
||||
uint16_t freeSpace = (_currentClient->_dataBufferSize-1/*for \0*/ - _currentClient->_dataSize);
|
||||
|
||||
if(freeSpace != 0)
|
||||
{
|
||||
int amountToBeRead = bytesAvailable < freeSpace ? bytesAvailable : freeSpace;
|
||||
|
||||
(_currentClient->_client).read(_currentClient->_data + _currentClient->_dataSize, amountToBeRead);
|
||||
_currentClient->_dataSize += amountToBeRead;
|
||||
_currentClient->_data[_currentClient->_dataSize] = '\0';
|
||||
_currentClient->_newDataAvailable = true;
|
||||
}
|
||||
}
|
||||
else if(!(_currentClient->_client).connected())
|
||||
{
|
||||
#ifdef DEBUG_TCPS
|
||||
Serial.print("TCPServer : Client disconnected and can be discarded : ");Serial.println(_currentClient->_id);
|
||||
#endif
|
||||
_currentClient->_clientState = TCPClient::DISCARDED;
|
||||
}
|
||||
|
||||
if(_currentClient->_dataSize > 0)
|
||||
{
|
||||
processClientData(_currentClient);//We process the actual data
|
||||
_currentClient->_newDataAvailable = false;
|
||||
}
|
||||
|
||||
if(_currentClient->_clientState == TCPClient::ClientState::DISCARDED)
|
||||
{
|
||||
_currentClient->closeConnection();
|
||||
#ifdef DEBUG_TCPS
|
||||
Serial.print("TCPServer : Client was discarded : ");Serial.println(_currentClient->_id);
|
||||
#endif
|
||||
delete _currentClient;
|
||||
_currentClient = NULL;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
_clientList.addFirst(_currentClient);
|
||||
|
||||
}
|
||||
|
||||
virtual void processClientData(T *client)
|
||||
{
|
||||
if(client->_dataSize > 0 && ((char) client->_data[0] != '\r' && (char) client->_data[0] != '\n'))
|
||||
{
|
||||
Serial.print("Client --> ");Serial.print(client->_id);Serial.print(" : ");Serial.print((char *)client->_data);Serial.println("#");
|
||||
}
|
||||
|
||||
client->freeDataBuffer(client->_dataSize);
|
||||
}
|
||||
|
||||
uint8_t freeClientId()
|
||||
{
|
||||
int listCounter(_clientList.count());
|
||||
int freeId(0);
|
||||
|
||||
for(int i(0); i < listCounter; i++)
|
||||
{
|
||||
if(_clientList.getRef(i)->_id == freeId)
|
||||
{
|
||||
freeId++;
|
||||
i = -1;
|
||||
}
|
||||
}
|
||||
return freeId;
|
||||
}
|
||||
|
||||
boolean _serverStarted;
|
||||
uint8_t _maxClient;
|
||||
unsigned int _port;
|
||||
uint16_t _clientDataBufferSize;
|
||||
WiFiServer _wifiServer;
|
||||
T *_currentClient; //current client to be processed
|
||||
List<T> _clientList;
|
||||
private:
|
||||
};
|
||||
|
||||
#endif //TCPSERVER_H
|
@ -11,7 +11,7 @@ TaskSchedulerManagerHelper::Schedule::Schedule() :
|
||||
_triggerType(TRIGGER_REPEAT),
|
||||
_mode(EVERY),
|
||||
_enabled(true),
|
||||
_millis(0),
|
||||
_millis(millis()),
|
||||
_everyMillis(1000),
|
||||
_dateTime(NULL)
|
||||
{
|
||||
@ -27,7 +27,7 @@ TaskSchedulerManagerHelper::Schedule::Schedule(const TaskSchedulerManagerHelper:
|
||||
_triggerType(Object._triggerType),
|
||||
_mode(Object._mode),
|
||||
_enabled(Object._enabled),
|
||||
_millis(0),
|
||||
_millis(Object._millis),
|
||||
_everyMillis(Object._everyMillis),
|
||||
_dateTime(NULL)
|
||||
{
|
||||
@ -214,7 +214,7 @@ void TaskSchedulerManager::runTaskScheduler()
|
||||
|
||||
if(p->schedule._triggerType != TaskSchedulerManagerHelper::Schedule::TRIGGER_ONCE_AND_DELETE)_nextTaskIndexToBeRun++;
|
||||
else if(p->schedule._triggerType == TaskSchedulerManagerHelper::Schedule::TRIGGER_ONCE_AND_DELETE && !(p->schedule._triggered))_nextTaskIndexToBeRun++;
|
||||
else if(p->schedule._triggerType == TaskSchedulerManagerHelper::Schedule::TRIGGER_ONCE_AND_DELETE && p->schedule._triggered) //If the task has to be deleted after executing and if it has been executed, we delete it
|
||||
else if(p->schedule._triggerType == TaskSchedulerManagerHelper::Schedule::TRIGGER_ONCE_AND_DELETE && p->schedule._triggered) //If the task has to be deleted after it has been executed and if it has, we delete it
|
||||
{
|
||||
_taskDataDictio.removeAt(_nextTaskIndexToBeRun);
|
||||
}
|
||||
|
37
src/app/WEBClient.cpp
Normal file
37
src/app/WEBClient.cpp
Normal file
@ -0,0 +1,37 @@
|
||||
#include "WEBClient.h"
|
||||
|
||||
//#define DEBUG_WEBCL
|
||||
|
||||
WEBClient::WEBClient(WiFiClient client, uint8_t id, uint16_t maxResourceBuffer, uint16_t maxBodyBuffer, uint16_t dataBufferSize) : TCPClient(client, id, dataBufferSize), _WEBClientState(WEBServer<WEBClient>::WEBClientState::ACCEPTED), _httpParserState(WEBServer<WEBClient>::HttpParserStatus::HTTP_VERB), _fileSentBytes(0)
|
||||
{
|
||||
#ifdef DEBUG_WEBCL
|
||||
Serial.println("WEBClient : Standard constructor called");
|
||||
#endif
|
||||
|
||||
_httpRequestData.HRM = WEBServer<WEBClient>::HttpRequestMethod::UNDEFINED;
|
||||
_httpRequestData.HV = WEBServer<WEBClient>::HttpVersion::UNKNOWN;
|
||||
_httpRequestData.HMT = WEBServer<WEBClient>::HttpMIMEType::UNKNOWN_MIME;
|
||||
|
||||
_httpRequestData.getParamsDataPointer = NULL;
|
||||
_httpRequestData.postParamsDataPointer = NULL;
|
||||
|
||||
_httpRequestData.httpResource = NULL;
|
||||
_httpRequestData.maxResourceBuffer = maxResourceBuffer;
|
||||
_httpRequestData.httpBody = NULL;
|
||||
_httpRequestData.maxBodyBuffer = maxBodyBuffer;
|
||||
}
|
||||
|
||||
WEBClient::~WEBClient()
|
||||
{
|
||||
#ifdef DEBUG_WEBCL
|
||||
Serial.println("WEBClient : Destructor called");
|
||||
#endif
|
||||
clearHttpRequestData();
|
||||
}
|
||||
|
||||
void WEBClient::clearHttpRequestData()
|
||||
{
|
||||
free(_httpRequestData.httpResource);free(_httpRequestData.httpBody);
|
||||
_httpRequestData.getParams.dispose();
|
||||
_httpRequestData.postParams.dispose();
|
||||
}
|
24
src/app/WEBClient.h
Normal file
24
src/app/WEBClient.h
Normal file
@ -0,0 +1,24 @@
|
||||
#ifndef WEBCLIENT_H
|
||||
#define WEBCLIENT_H
|
||||
|
||||
#include "WEBServer.h"
|
||||
#include "TCPClient.h"
|
||||
#include "Dictionary.h"
|
||||
|
||||
class WEBClient : public TCPClient
|
||||
{
|
||||
template <typename T>
|
||||
friend class WEBServer;
|
||||
public:
|
||||
WEBClient(WiFiClient client, uint8_t id, uint16_t maxResourceBuffer = 255, uint16_t maxBodyBuffer = 255, uint16_t dataBufferSize = 511);
|
||||
virtual ~WEBClient();
|
||||
protected:
|
||||
WEBServer<WEBClient>::WEBClientState _WEBClientState;
|
||||
private:
|
||||
WEBServer<WEBClient>::HttpRequestData _httpRequestData;
|
||||
WEBServer<WEBClient>::HttpParserStatus _httpParserState;
|
||||
uint64_t _fileSentBytes;
|
||||
void clearHttpRequestData();
|
||||
};
|
||||
|
||||
#endif //WEBCLIENT_H
|
599
src/app/WEBServer.h
Normal file
599
src/app/WEBServer.h
Normal file
@ -0,0 +1,599 @@
|
||||
#ifndef WEBSERVER_H
|
||||
#define WEBSERVER_H
|
||||
|
||||
#include "TCPServer.h"
|
||||
#include "Dictionary.h"
|
||||
#include "SDCardManager.h"
|
||||
//#define DEBUG_WEBS
|
||||
|
||||
template <typename T>
|
||||
class WEBServer : public TCPServer<T>
|
||||
{
|
||||
public:
|
||||
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 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};
|
||||
enum HttpParserStatus {HTTP_VERB, HTTP_RESSOURCE, HTTP_VERSION, HTTP_PARAMS, POST_DATA};
|
||||
enum WEBClientState {ACCEPTED, QUERY_PARSED, RESPONSE_SENT, DONE};
|
||||
enum HTTP_CODE {_100, _101, _200, _400, _401, _403, _404, _405, _500, _501};
|
||||
|
||||
struct HttpRequestData
|
||||
{
|
||||
HttpRequestMethod HRM;
|
||||
HttpVersion HV;
|
||||
HttpMIMEType HMT;
|
||||
|
||||
Dictionary<DictionaryHelper::StringEntity> getParams;
|
||||
char *getParamsDataPointer; //Used in the getParams algorithm
|
||||
Dictionary<DictionaryHelper::StringEntity> postParams;
|
||||
char *postParamsDataPointer; //Used in the postParams algorithm
|
||||
|
||||
char *httpResource;
|
||||
uint16_t maxResourceBuffer;
|
||||
char *httpBody;
|
||||
uint16_t maxBodyBuffer;
|
||||
};
|
||||
|
||||
WEBServer(unsigned int port = 80, SDCardManager *sdCardManager = NULL, uint8_t maxClient = MAX_CLIENT, uint16_t clientDataBufferSize = 512) : TCPServer<T>(port, maxClient, clientDataBufferSize), _sdCardManager(sdCardManager) {}
|
||||
|
||||
boolean addApiRoutine(const char *uri, boolean (*apiRoutine)(HttpRequestData&, WiFiClient*, void*), void *pData, HttpRequestMethod HRM = UNDEFINED)
|
||||
{
|
||||
return _apiDictionary.add(uri, new ApiRoutine({apiRoutine, pData, HRM}));
|
||||
}
|
||||
|
||||
void clearApiRoutine() { _apiDictionary.clear(); };
|
||||
|
||||
boolean removeApiRoutine(const char* uri)
|
||||
{
|
||||
return _apiDictionary.remove(uri);
|
||||
}
|
||||
protected:
|
||||
private:
|
||||
virtual T* createNewClient(WiFiClient wc)
|
||||
{
|
||||
return new T(wc, TCPServer<T>::freeClientId());
|
||||
}
|
||||
|
||||
virtual void greetClient(T *client)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
virtual void processClientData(T *client)
|
||||
{
|
||||
switch(client->_WEBClientState)
|
||||
{
|
||||
case ACCEPTED:
|
||||
#ifdef DEBUG_WEBS
|
||||
Serial.println("WEBServer : ACCEPTED");
|
||||
#endif
|
||||
queryParser(client);
|
||||
break;
|
||||
case QUERY_PARSED:
|
||||
#ifdef DEBUG_WEBS
|
||||
Serial.println("WEBServer : QUERY_PARSED");
|
||||
#endif
|
||||
sendDataToClient(client);
|
||||
break;
|
||||
case RESPONSE_SENT:
|
||||
#ifdef DEBUG_WEBS
|
||||
Serial.println("WEBServer : RESPONSE_SENT");
|
||||
#endif
|
||||
client->_WEBClientState = WEBClientState::DONE;
|
||||
break;
|
||||
case DONE:
|
||||
#ifdef DEBUG_WEBS
|
||||
Serial.println("WEBServer : DONE");
|
||||
#endif
|
||||
client->_clientState = TCPClient::ClientState::DISCARDED;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void queryParser(T *client)
|
||||
{
|
||||
switch(client->_httpParserState)
|
||||
{
|
||||
case HttpParserStatus::HTTP_VERB:
|
||||
{
|
||||
#ifdef DEBUG_WEBS
|
||||
Serial.println((char *)client->_data);
|
||||
#endif
|
||||
|
||||
char *pVerb = strstr((char *)client->_data, " ");
|
||||
|
||||
if(pVerb != NULL)
|
||||
{
|
||||
*pVerb = '\0';
|
||||
client->_httpRequestData.HRM = getHttpVerbEnumValue((char *)client->_data);
|
||||
client->freeDataBuffer((pVerb - (char *)client->_data) +1);
|
||||
|
||||
if(client->_httpRequestData.HRM == HttpRequestMethod::UNDEFINED) //Error 400
|
||||
{
|
||||
sendInfoResponse(HTTP_CODE::_400, client, "The server could not understand the request due to invalid syntax");
|
||||
client->_clientState = TCPClient::ClientState::DISCARDED;
|
||||
break;
|
||||
}
|
||||
|
||||
#ifdef DEBUG_WEBS
|
||||
Serial.print("Verb : ");Serial.println(client->_httpRequestData.HRM);
|
||||
Serial.println((char *)client->_data);
|
||||
#endif
|
||||
|
||||
client->_httpParserState = HttpParserStatus::HTTP_RESSOURCE;
|
||||
}
|
||||
else
|
||||
{
|
||||
sendInfoResponse(HTTP_CODE::_400, client, "The server could not understand the request due to invalid syntax");
|
||||
client->_clientState = TCPClient::ClientState::DISCARDED;
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case HttpParserStatus::HTTP_RESSOURCE:
|
||||
{
|
||||
char *pRsrc = strstr((char *)client->_data, " ");
|
||||
|
||||
if(pRsrc != NULL)
|
||||
{
|
||||
*pRsrc = '\0';
|
||||
uint16_t safeLength = pRsrc - (char *)client->_data <= client->_httpRequestData.maxResourceBuffer ? pRsrc - (char *)client->_data : client->_httpRequestData.maxResourceBuffer;
|
||||
|
||||
#ifdef DEBUG_WEBS
|
||||
Serial.print("Resrc length : ");Serial.println(safeLength);
|
||||
#endif
|
||||
|
||||
client->_httpRequestData.httpResource = (char *) malloc(sizeof(char) * (safeLength+1) ); //for \0
|
||||
if(client->_httpRequestData.httpResource != NULL)
|
||||
{
|
||||
strncpy(client->_httpRequestData.httpResource, (char *)client->_data, safeLength);
|
||||
client->_httpRequestData.httpResource[safeLength] = '\0';
|
||||
}
|
||||
else //Error 500
|
||||
{
|
||||
sendInfoResponse(HTTP_CODE::_500, client, "Failed to allocate memory for resources");
|
||||
client->_clientState = TCPClient::ClientState::DISCARDED;
|
||||
break;
|
||||
}
|
||||
|
||||
client->freeDataBuffer(safeLength + 1);
|
||||
|
||||
#ifdef DEBUG_WEBS
|
||||
Serial.print("Resrc : ");Serial.println(client->_httpRequestData.httpResource);
|
||||
Serial.println((char *)client->_data);
|
||||
#endif
|
||||
}
|
||||
else //Resource is probably too long, so we truncate it
|
||||
{
|
||||
client->_httpRequestData.httpResource = (char *) malloc(sizeof(char) * (client->_httpRequestData.maxResourceBuffer+1) ); //for \0
|
||||
if(client->_httpRequestData.httpResource != NULL)
|
||||
{
|
||||
strncpy(client->_httpRequestData.httpResource, (char *)client->_data, client->_httpRequestData.maxResourceBuffer);
|
||||
client->_httpRequestData.httpResource[client->_httpRequestData.maxResourceBuffer] = '\0';
|
||||
}
|
||||
else //Error 500
|
||||
{
|
||||
sendInfoResponse(HTTP_CODE::_500, client, "Failed to allocate memory for resources");
|
||||
client->_clientState = TCPClient::ClientState::DISCARDED;
|
||||
break;
|
||||
}
|
||||
|
||||
client->freeDataBuffer(client->_httpRequestData.maxResourceBuffer + 1);
|
||||
}
|
||||
client->_httpParserState = HttpParserStatus::HTTP_PARAMS;
|
||||
}
|
||||
break;
|
||||
case HttpParserStatus::HTTP_VERSION:
|
||||
{
|
||||
char *pEndline = strstr((char *)client->_data, "\r\n");
|
||||
char *pVers = strstr((char *)client->_data, "HTTP/");
|
||||
|
||||
if(pEndline != NULL && pVers!= NULL)
|
||||
{
|
||||
*pEndline = '\0';
|
||||
client->_httpRequestData.HV = getHttpVersionEnumValue(pVers+5);
|
||||
|
||||
#ifdef DEBUG_WEBS
|
||||
Serial.print("Vers : ");Serial.println(pVers+5);
|
||||
Serial.print("Vers : ");Serial.println(client->_httpRequestData.HV);
|
||||
#endif
|
||||
|
||||
client->freeDataBuffer((pEndline - (char *)client->_data)+2);
|
||||
|
||||
#ifdef DEBUG_WEBS
|
||||
Serial.println((char *)client->_data);
|
||||
#endif
|
||||
|
||||
client->_httpParserState = HttpParserStatus::POST_DATA;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case HttpParserStatus::HTTP_PARAMS: //index.htm?var1=1&var2=2...
|
||||
if(!httpParamParser(client))
|
||||
{
|
||||
#ifdef DEBUG_WEBS
|
||||
Serial.print("Resrc : ");Serial.println(client->_httpRequestData.httpResource);
|
||||
Serial.println("Get params :");
|
||||
for(int i = 0; i < client->_httpRequestData.getParams.count(); i++)
|
||||
{
|
||||
Serial.print(client->_httpRequestData.getParams.getParameter(i));Serial.print(" : ");Serial.println(client->_httpRequestData.getParams.getAt(i)->getString());
|
||||
}
|
||||
#endif
|
||||
client->_httpParserState = HttpParserStatus::HTTP_VERSION;
|
||||
}
|
||||
break;
|
||||
case HttpParserStatus::POST_DATA:
|
||||
|
||||
client->_WEBClientState = WEBClientState::QUERY_PARSED;
|
||||
break;
|
||||
default :
|
||||
sendInfoResponse(HTTP_CODE::_500, client, "WEB server error");
|
||||
client->_clientState = TCPClient::ClientState::DISCARDED;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
boolean httpParamParser(T *client)
|
||||
{
|
||||
char *pGetParam = strchr((char *)client->_httpRequestData.httpResource, '?');
|
||||
|
||||
|
||||
if(pGetParam != NULL) //There are some params to be parsed
|
||||
{
|
||||
if(client->_httpRequestData.getParamsDataPointer == NULL)
|
||||
{
|
||||
client->_httpRequestData.getParamsDataPointer = pGetParam +1;//We save the starting position of the string to parse
|
||||
}
|
||||
|
||||
char *key = strchr(client->_httpRequestData.getParamsDataPointer, '=');
|
||||
char *value = strchr(client->_httpRequestData.getParamsDataPointer, '&');
|
||||
|
||||
if(key == NULL && value == NULL) //Only the key is present
|
||||
{
|
||||
client->_httpRequestData.getParams.add(client->_httpRequestData.getParamsDataPointer, new DictionaryHelper::StringEntity(NULL));
|
||||
*pGetParam = '\0';
|
||||
return false;
|
||||
}
|
||||
else if(key != NULL && value != NULL)
|
||||
{
|
||||
if(key < value)*key = '\0';
|
||||
*value = '\0';
|
||||
|
||||
client->_httpRequestData.getParams.add(client->_httpRequestData.getParamsDataPointer, new DictionaryHelper::StringEntity(key > value ? NULL : key + 1));
|
||||
strcpy(client->_httpRequestData.getParamsDataPointer,value+1);
|
||||
|
||||
#ifdef DEBUG_WEBS
|
||||
Serial.print("Params pointer : ");Serial.println(client->_httpRequestData.getParamsDataPointer);
|
||||
#endif
|
||||
}
|
||||
else if(key != NULL && value == NULL) //Only one key/value pair present
|
||||
{
|
||||
*key = '\0';
|
||||
|
||||
client->_httpRequestData.getParams.add(client->_httpRequestData.getParamsDataPointer, new DictionaryHelper::StringEntity(key+1));
|
||||
*pGetParam = '\0';
|
||||
return false;
|
||||
}
|
||||
else if(key == NULL && value != NULL)
|
||||
{
|
||||
*value = '\0';
|
||||
|
||||
client->_httpRequestData.getParams.add(client->_httpRequestData.getParamsDataPointer, new DictionaryHelper::StringEntity(NULL));
|
||||
strcpy(client->_httpRequestData.getParamsDataPointer,value+1);
|
||||
}
|
||||
}
|
||||
else //nothing to parse or done
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
void sendDataToClient(T *client)
|
||||
{
|
||||
if(!sendPageToClientFromApiDictio(client)) //Then we check if it is not a file that is requested
|
||||
{
|
||||
if(!sendPageToClientFromSdCard(client)) //If this function returns false, we close the connection with the client. An error occured (An error message has already been sent) or the whole file has been sent.
|
||||
{
|
||||
client->_WEBClientState = WEBClientState::RESPONSE_SENT;
|
||||
}
|
||||
}
|
||||
else //If we found the api endpoint, we can close the connection with the client after the data has been sent.
|
||||
client->_WEBClientState = WEBClientState::RESPONSE_SENT;
|
||||
}
|
||||
|
||||
boolean sendPageToClientFromApiDictio(T *client)
|
||||
{
|
||||
if(_apiDictionary.count() == 0 || client->_httpRequestData.httpResource == NULL)
|
||||
return false;
|
||||
|
||||
ApiRoutine *ref = _apiDictionary(client->_httpRequestData.httpResource);
|
||||
|
||||
if(ref == NULL)
|
||||
return false;
|
||||
|
||||
if(ref->HRM == UNDEFINED)
|
||||
{
|
||||
return (*(ref->apiRoutine))(client->_httpRequestData, &(client->_client), ref->pData);
|
||||
}else if(ref->HRM == client->_httpRequestData.HRM)
|
||||
{
|
||||
return (*(ref->apiRoutine))(client->_httpRequestData, &(client->_client), ref->pData);
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
boolean sendPageToClientFromSdCard(T *client)
|
||||
{
|
||||
if(_sdCardManager != NULL)
|
||||
{
|
||||
File pageToSend;
|
||||
char *filePath(NULL), *header(NULL), sendBuffer[2048];
|
||||
int readBytes(0);
|
||||
//We check what kind of http verb it is
|
||||
switch(client->_httpRequestData.HRM)
|
||||
{
|
||||
case GET:
|
||||
filePath = getFilePathByHttpResource(client->_httpRequestData.httpResource);
|
||||
if(filePath == NULL)
|
||||
{
|
||||
sendInfoResponse(HTTP_CODE::_500, client, "Failed to allocate memory for the filePath");
|
||||
return false;
|
||||
}
|
||||
|
||||
#ifdef DEBUG_WEBS
|
||||
Serial.print("FILE PATH : ");
|
||||
Serial.println(filePath);
|
||||
#endif
|
||||
|
||||
pageToSend = _sdCardManager->open(filePath);
|
||||
free(filePath);filePath = NULL;
|
||||
|
||||
//If we couldn't open the file
|
||||
if(!pageToSend)
|
||||
{
|
||||
pageToSend.close();
|
||||
|
||||
char *response(NULL);
|
||||
|
||||
response = (char *) malloc(sizeof(char) * (strlen_P((PGM_P)F("Resource : not found on this server")) + strlen(client->_httpRequestData.httpResource) + 1));
|
||||
if(response == NULL)
|
||||
{
|
||||
sendInfoResponse(HTTP_CODE::_500, client, "Failed to allocate memory for the response");
|
||||
return false;
|
||||
}
|
||||
|
||||
sprintf(response, "Resource : %s not found on this server", client->_httpRequestData.httpResource);
|
||||
sendInfoResponse(HTTP_CODE::_404, client, response);
|
||||
|
||||
free(response);response = NULL;
|
||||
return false;
|
||||
}
|
||||
|
||||
#ifdef DEBUG_WEBS
|
||||
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
|
||||
|
||||
if(pageToSend.isDirectory()) //To DO : List the files present in the directory
|
||||
{
|
||||
pageToSend.close();
|
||||
|
||||
sendInfoResponse(HTTP_CODE::_403, client, "The file you want to access is a folder");
|
||||
return false;
|
||||
}
|
||||
|
||||
if(client->_fileSentBytes == 0)
|
||||
{
|
||||
header = getHTTPHeader(getMIMETypeByExtension(getFileExtension(pageToSend.name())), pageToSend.size());
|
||||
if(header == NULL)
|
||||
{
|
||||
sendInfoResponse(HTTP_CODE::_500, client, "Failed to allocate memory for the header");
|
||||
pageToSend.close();
|
||||
return false;
|
||||
}
|
||||
|
||||
client->_client.print(header);
|
||||
free(header);header = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
pageToSend.seek(client->_fileSentBytes);
|
||||
}
|
||||
|
||||
if(pageToSend.available())
|
||||
{
|
||||
readBytes = pageToSend.read(sendBuffer,2048);
|
||||
client->_client.write(sendBuffer, readBytes);
|
||||
|
||||
client->_fileSentBytes += readBytes; //We save the number of bytes sent so that we can reopen the file to this position later on.
|
||||
}
|
||||
else
|
||||
{
|
||||
pageToSend.close();
|
||||
return false;
|
||||
}
|
||||
|
||||
pageToSend.close();
|
||||
break;
|
||||
default: //If not supported
|
||||
sendInfoResponse(HTTP_CODE::_500, client, "The method used is not allowed");
|
||||
break;
|
||||
}
|
||||
}else
|
||||
{
|
||||
sendInfoResponse(HTTP_CODE::_500, client, "Unable to access the SDCard");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void sendInfoResponse(HTTP_CODE http_code, T *client, const char *message)
|
||||
{
|
||||
uint16_t code(0);
|
||||
char codeLiteral[100];
|
||||
switch(http_code)
|
||||
{
|
||||
case _400:
|
||||
code = 400;
|
||||
strcpy_P(codeLiteral,(PGM_P)F("Bad Request"));
|
||||
break;
|
||||
case _404:
|
||||
code = 404;
|
||||
strcpy_P(codeLiteral,(PGM_P)F("Not Found"));
|
||||
break;
|
||||
case _403:
|
||||
code = 403;
|
||||
strcpy_P(codeLiteral,(PGM_P)F("Forbidden"));
|
||||
break;
|
||||
case _405:
|
||||
code = 405;
|
||||
strcpy_P(codeLiteral,(PGM_P)F("Method Not Allowed"));
|
||||
break;
|
||||
case _500:
|
||||
code = 500;
|
||||
strcpy_P(codeLiteral,(PGM_P)F("Internal Server Error"));
|
||||
break;
|
||||
default:
|
||||
code = 000;
|
||||
strcpy_P(codeLiteral,(PGM_P)F("Error Not Defined"));
|
||||
break;
|
||||
}
|
||||
|
||||
client->_client.print(F("HTTP/1.1 "));client->_client.print(code);client->_client.print(F(" "));client->_client.print(codeLiteral);client->_client.print(F("\r\nContent-Type: text/html\r\nContent-Length: "));
|
||||
client->_client.print(strlen(message) + 59);
|
||||
client->_client.print(F("\r\n\r\n<!DOCTYPE HTML>\r\n<html>\r\n<h1>Error "));client->_client.print(code);client->_client.print(F("</h1><p>"));
|
||||
client->_client.print(message);
|
||||
client->_client.print(F("</p>\r\n</html>"));
|
||||
}
|
||||
|
||||
/*Static helper methods*/
|
||||
|
||||
static HttpRequestMethod getHttpVerbEnumValue(const char *parseBuffer)
|
||||
{
|
||||
if(parseBuffer == NULL)return HttpRequestMethod::UNDEFINED;
|
||||
|
||||
//UNDEFINED, GET, HEAD, POST, PUT, DELETE, CONNECT, OPTIONS, TRACE, PATCH
|
||||
if(strcmp(parseBuffer,"GET") == 0){return HttpRequestMethod::GET;}
|
||||
else if(strcmp(parseBuffer,"POST") == 0){return HttpRequestMethod::POST;}
|
||||
else if(strcmp(parseBuffer,"HEAD") == 0){return HttpRequestMethod::HEAD;}
|
||||
else if(strcmp(parseBuffer,"PUT") == 0){return HttpRequestMethod::PUT;}
|
||||
else if(strcmp(parseBuffer,"DELETE") == 0){return HttpRequestMethod::DELETE;}
|
||||
else if(strcmp(parseBuffer,"CONNECT") == 0){return HttpRequestMethod::CONNECT;}
|
||||
else if(strcmp(parseBuffer,"TRACE") == 0){return HttpRequestMethod::TRACE;}
|
||||
else if(strcmp(parseBuffer,"PATCH") == 0){return HttpRequestMethod::PATCH;}
|
||||
else if(strcmp(parseBuffer,"OPTIONS") == 0){return HttpRequestMethod::OPTIONS;}
|
||||
else
|
||||
return HttpRequestMethod::UNDEFINED;
|
||||
}
|
||||
|
||||
static HttpMIMEType getMIMETypeByExtension(const char *extension)
|
||||
{
|
||||
if(extension == NULL)return UNKNOWN_MIME;
|
||||
|
||||
//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 *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;
|
||||
}
|
||||
|
||||
return header;
|
||||
}
|
||||
|
||||
static char *getFileExtension(char *name)
|
||||
{
|
||||
if(name == NULL)return NULL;
|
||||
|
||||
char *p(strchr(name, '.'));
|
||||
|
||||
return p != NULL ? p+1 : NULL;
|
||||
}
|
||||
|
||||
static char *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);
|
||||
|
||||
#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;
|
||||
}
|
||||
|
||||
static HttpVersion getHttpVersionEnumValue(const char *parseBuffer)
|
||||
{
|
||||
//HTTP_0_9, HTTP_1_1, HTTP_1_0, HTTP_2_0
|
||||
if(strcmp(parseBuffer,"1.1") == 0){return HttpVersion::HTTP_1_1;}
|
||||
else if(strcmp(parseBuffer,"2.0") == 0){return HttpVersion::HTTP_2_0;}
|
||||
else if(strcmp(parseBuffer,"1.0") == 0){return HttpVersion::HTTP_1_0;}
|
||||
else if(strcmp(parseBuffer,"0.9") == 0){return HttpVersion::HTTP_0_9;}
|
||||
else
|
||||
return HttpVersion::UNKNOWN;
|
||||
}
|
||||
|
||||
struct ApiRoutine
|
||||
{
|
||||
boolean (*apiRoutine)(HttpRequestData&, WiFiClient*, void*);
|
||||
void *pData;
|
||||
HttpRequestMethod HRM;
|
||||
};
|
||||
|
||||
Dictionary<ApiRoutine> _apiDictionary;
|
||||
SDCardManager *_sdCardManager;
|
||||
};
|
||||
|
||||
#endif //WEBSERVER_H
|
@ -54,25 +54,25 @@ void setup()
|
||||
sab.getRtcManager().setDateTime(DateTime(F(__DATE__), F(__TIME__)));
|
||||
}
|
||||
|
||||
sab.getWebServerManager().addApiRoutine("/sab/web/apitester", &(apiTesterApi), NULL);
|
||||
sab.getWebServerManager().addApiRoutine("/sab/view/next", &(nextViewApi), &sab, WEBServerManager::GET);
|
||||
sab.getWebServerManager().addApiRoutine("/sab/view", &(viewByUIDApi), &sab, WEBServerManager::GET);
|
||||
sab.getWebServerManager().addApiRoutine("/sab/rtc/get/datetime", &(rtcGetTimeApi), &sab, WEBServerManager::GET);
|
||||
sab.getWebServerManager().addApiRoutine("/sab/rtc/set/datetime", &(rtcSetTimeApi), &sab, WEBServerManager::GET);
|
||||
sab.getWebServerManager().addApiRoutine("/sab/sdcard/size", &(sdCardSizeApi), &sab, WEBServerManager::GET);
|
||||
sab.getWebServer().addApiRoutine("/sab/web/apitester", &(apiTesterApi), NULL);
|
||||
sab.getWebServer().addApiRoutine("/sab/view/next", &(nextViewApi), &sab, WEBServer<WEBClient>::GET);
|
||||
sab.getWebServer().addApiRoutine("/sab/view", &(viewByUIDApi), &sab, WEBServer<WEBClient>::GET);
|
||||
sab.getWebServer().addApiRoutine("/sab/rtc/get/datetime", &(rtcGetTimeApi), &sab, WEBServer<WEBClient>::GET);
|
||||
sab.getWebServer().addApiRoutine("/sab/rtc/set/datetime", &(rtcSetTimeApi), &sab, WEBServer<WEBClient>::GET);
|
||||
sab.getWebServer().addApiRoutine("/sab/sdcard/size", &(sdCardSizeApi), &sab, WEBServer<WEBClient>::GET);
|
||||
sdCardApiPacket.pSab = &sab;sdCardApiPacket.pView = &v1p;
|
||||
sab.getWebServerManager().addApiRoutine("/sab/sdcard/unmount", &(sdCardUnmountApi), &sdCardApiPacket, WEBServerManager::GET);
|
||||
sab.getWebServerManager().addApiRoutine("/sab/sdcard/mount", &(sdCardMountApi), &sdCardApiPacket, WEBServerManager::GET);
|
||||
sab.getWebServer().addApiRoutine("/sab/sdcard/unmount", &(sdCardUnmountApi), &sdCardApiPacket, WEBServer<WEBClient>::GET);
|
||||
sab.getWebServer().addApiRoutine("/sab/sdcard/mount", &(sdCardMountApi), &sdCardApiPacket, WEBServer<WEBClient>::GET);
|
||||
|
||||
sab.getWebServerManager().addApiRoutine("/esp/restart", &(espRestartApi), &sab, WEBServerManager::GET);
|
||||
sab.getWebServerManager().addApiRoutine("/esp/reset", &(espResetApi), &sab, WEBServerManager::GET);
|
||||
sab.getWebServerManager().addApiRoutine("/sab/wifi/stainfo", &(staWifiInfoApi), &sab, WEBServerManager::GET);
|
||||
sab.getWebServerManager().addApiRoutine("/sab/systeminfo", &(systemInfoApi), &sab, WEBServerManager::GET);
|
||||
sab.getWebServerManager().addApiRoutine("/sab/power/info", &(powerInfoApi), &sab, WEBServerManager::GET);
|
||||
sab.getWebServerManager().addApiRoutine("/sab/io/get/level", &(ioGetLevelApi), vio.ioState, WEBServerManager::GET);
|
||||
sab.getWebServerManager().addApiRoutine("/sab/io/set/level", &(ioSetLevelApi), &sab, WEBServerManager::GET);
|
||||
sab.getWebServerManager().addApiRoutine("/sab/io/get/mode", &(ioGetModeApi), &sab, WEBServerManager::GET);
|
||||
sab.getWebServerManager().addApiRoutine("/sab/io/set/mode", &(ioSetModeApi), &sab, WEBServerManager::GET);
|
||||
sab.getWebServer().addApiRoutine("/esp/restart", &(espRestartApi), &sab, WEBServer<WEBClient>::GET);
|
||||
sab.getWebServer().addApiRoutine("/esp/reset", &(espResetApi), &sab, WEBServer<WEBClient>::GET);
|
||||
sab.getWebServer().addApiRoutine("/sab/wifi/stainfo", &(staWifiInfoApi), &sab, WEBServer<WEBClient>::GET);
|
||||
sab.getWebServer().addApiRoutine("/sab/systeminfo", &(systemInfoApi), &sab, WEBServer<WEBClient>::GET);
|
||||
sab.getWebServer().addApiRoutine("/sab/power/info", &(powerInfoApi), &sab, WEBServer<WEBClient>::GET);
|
||||
sab.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.getWebServer().addApiRoutine("/sab/io/get/mode", &(ioGetModeApi), &sab, WEBServer<WEBClient>::GET);
|
||||
sab.getWebServer().addApiRoutine("/sab/io/set/mode", &(ioSetModeApi), &sab, WEBServer<WEBClient>::GET);
|
||||
|
||||
sab.getIoManager().setISROnIOChange(&(ioISR), GPIO_3_RX);
|
||||
|
||||
@ -119,7 +119,7 @@ void loop()
|
||||
}
|
||||
|
||||
//Run the webServer
|
||||
sab.getWebServerManager().runServer();
|
||||
sab.getWebServer().runServer();
|
||||
sab.getTaskSchedulerManager().runTaskScheduler();
|
||||
}
|
||||
|
||||
|
@ -19,8 +19,6 @@ typedef enum { GPIO_0 = 0,
|
||||
ADC = A0,
|
||||
DEFAULT_PIN = -1 } Pin;
|
||||
|
||||
#define MALLOC_ERR B00000001
|
||||
|
||||
#define AP_AND_STA_ENABLED_ERR B00000001
|
||||
#define AP_SETUP_ERR B00000010
|
||||
#define STA_SETUP_ERR B00000100
|
||||
|
@ -14,5 +14,7 @@
|
||||
#define SOFT_VERSION "1.1.3" //TaskSchedulerManager added millis rollover
|
||||
#define SOFT_VERSION "1.1.4" //Cleaned AP and STA wifi start
|
||||
#define SOFT_VERSION "1.2.0" //Added new PowerManager class
|
||||
#define SOFT_VERSION "1.2.1" //Corrected a bug in the TaskSchedulerManager class
|
||||
#define SOFT_VERSION "1.3.0" //Implemented multi-client non blocking webserver
|
||||
|
||||
#endif //VERSIONS_H
|
||||
|
@ -2,13 +2,13 @@
|
||||
#include "webApi.h"
|
||||
#include "tasks.h"
|
||||
|
||||
boolean apiTesterApi(WEBServerManager::HttpRequestData &HRD, WiFiClient* wc, void* pData)
|
||||
boolean apiTesterApi(WEBServer<WEBClient>::HttpRequestData &HRD, WiFiClient* wc, void* pData)
|
||||
{
|
||||
wc->print(F("HTTP/1.1 200 OK\r\nContent-Type: application/json\r\n\r\n{ \"status\" : \"ok\", \"API\" : \"available\" }"));
|
||||
return true;
|
||||
}
|
||||
|
||||
boolean viewByUIDApi(WEBServerManager::HttpRequestData &HRD, WiFiClient *wc, void *pData)
|
||||
boolean viewByUIDApi(WEBServer<WEBClient>::HttpRequestData &HRD, WiFiClient *wc, void *pData)
|
||||
{
|
||||
SAB *p = (SAB *)pData;
|
||||
char buffer[200];
|
||||
@ -31,7 +31,7 @@ boolean viewByUIDApi(WEBServerManager::HttpRequestData &HRD, WiFiClient *wc, voi
|
||||
return true;
|
||||
}
|
||||
|
||||
boolean nextViewApi(WEBServerManager::HttpRequestData &HRD, WiFiClient *wc, void *pData)
|
||||
boolean nextViewApi(WEBServer<WEBClient>::HttpRequestData &HRD, WiFiClient *wc, void *pData)
|
||||
{
|
||||
SAB *p = (SAB *)pData;
|
||||
char buffer[200];
|
||||
@ -43,7 +43,7 @@ boolean nextViewApi(WEBServerManager::HttpRequestData &HRD, WiFiClient *wc, void
|
||||
return true;
|
||||
}
|
||||
|
||||
boolean rtcGetTimeApi(WEBServerManager::HttpRequestData &HRD, WiFiClient *wc, void *pData)
|
||||
boolean rtcGetTimeApi(WEBServer<WEBClient>::HttpRequestData &HRD, WiFiClient *wc, void *pData)
|
||||
{
|
||||
SAB *p = (SAB *)pData;
|
||||
char buffer[200];
|
||||
@ -53,7 +53,7 @@ boolean rtcGetTimeApi(WEBServerManager::HttpRequestData &HRD, WiFiClient *wc, vo
|
||||
return true;
|
||||
}
|
||||
|
||||
boolean rtcSetTimeApi(WEBServerManager::HttpRequestData &HRD, WiFiClient *wc, void *pData)
|
||||
boolean rtcSetTimeApi(WEBServer<WEBClient>::HttpRequestData &HRD, WiFiClient *wc, void *pData)
|
||||
{
|
||||
SAB *p = (SAB *)pData;
|
||||
char buffer[200];
|
||||
@ -101,7 +101,7 @@ boolean rtcSetTimeApi(WEBServerManager::HttpRequestData &HRD, WiFiClient *wc, vo
|
||||
return true;
|
||||
}
|
||||
|
||||
boolean sdCardUnmountApi(WEBServerManager::HttpRequestData &HRD, WiFiClient *wc, void *pData)
|
||||
boolean sdCardUnmountApi(WEBServer<WEBClient>::HttpRequestData &HRD, WiFiClient *wc, void *pData)
|
||||
{
|
||||
SdCardApiPacket *pV = (SdCardApiPacket*)pData;
|
||||
SAB *p = (SAB *)pV->pSab;
|
||||
@ -114,7 +114,7 @@ boolean sdCardUnmountApi(WEBServerManager::HttpRequestData &HRD, WiFiClient *wc,
|
||||
return true;
|
||||
}
|
||||
|
||||
boolean sdCardMountApi(WEBServerManager::HttpRequestData &HRD, WiFiClient *wc, void *pData)
|
||||
boolean sdCardMountApi(WEBServer<WEBClient>::HttpRequestData &HRD, WiFiClient *wc, void *pData)
|
||||
{
|
||||
SdCardApiPacket *pV = (SdCardApiPacket*)pData;
|
||||
SAB *p = (SAB *)pV->pSab;
|
||||
@ -133,7 +133,7 @@ boolean sdCardMountApi(WEBServerManager::HttpRequestData &HRD, WiFiClient *wc, v
|
||||
return true;
|
||||
}
|
||||
|
||||
boolean espRestartApi(WEBServerManager::HttpRequestData &HRD, WiFiClient *wc, void *pData)
|
||||
boolean espRestartApi(WEBServer<WEBClient>::HttpRequestData &HRD, WiFiClient *wc, void *pData)
|
||||
{
|
||||
SAB *sab = (SAB*)pData;
|
||||
char buffer[200];
|
||||
@ -149,12 +149,12 @@ boolean espRestartApi(WEBServerManager::HttpRequestData &HRD, WiFiClient *wc, vo
|
||||
return true;
|
||||
}
|
||||
|
||||
boolean espResetApi(WEBServerManager::HttpRequestData &HRD, WiFiClient *wc, void *pData)
|
||||
boolean espResetApi(WEBServer<WEBClient>::HttpRequestData &HRD, WiFiClient *wc, void *pData)
|
||||
{
|
||||
return espRestartApi(HRD, wc, pData);
|
||||
}
|
||||
|
||||
boolean sdCardSizeApi(WEBServerManager::HttpRequestData &HRD, WiFiClient *wc, void *pData)
|
||||
boolean sdCardSizeApi(WEBServer<WEBClient>::HttpRequestData &HRD, WiFiClient *wc, void *pData)
|
||||
{
|
||||
SAB *p = (SAB *)pData;
|
||||
char buffer[200];
|
||||
@ -168,7 +168,7 @@ boolean sdCardSizeApi(WEBServerManager::HttpRequestData &HRD, WiFiClient *wc, vo
|
||||
return true;
|
||||
}
|
||||
|
||||
boolean staWifiInfoApi(WEBServerManager::HttpRequestData &HRD, WiFiClient *wc, void *pData)
|
||||
boolean staWifiInfoApi(WEBServer<WEBClient>::HttpRequestData &HRD, WiFiClient *wc, void *pData)
|
||||
{
|
||||
SAB *p = (SAB *)pData;
|
||||
char buffer[300];
|
||||
@ -180,7 +180,7 @@ boolean staWifiInfoApi(WEBServerManager::HttpRequestData &HRD, WiFiClient *wc, v
|
||||
return true;
|
||||
}
|
||||
|
||||
boolean systemInfoApi(WEBServerManager::HttpRequestData &HRD, WiFiClient *wc, void *pData)
|
||||
boolean systemInfoApi(WEBServer<WEBClient>::HttpRequestData &HRD, WiFiClient *wc, void *pData)
|
||||
{
|
||||
SAB *p = (SAB *)pData;
|
||||
char buffer[300];
|
||||
@ -194,7 +194,7 @@ boolean systemInfoApi(WEBServerManager::HttpRequestData &HRD, WiFiClient *wc, vo
|
||||
return true;
|
||||
}
|
||||
|
||||
boolean powerInfoApi(WEBServerManager::HttpRequestData &HRD, WiFiClient *wc, void *pData)
|
||||
boolean powerInfoApi(WEBServer<WEBClient>::HttpRequestData &HRD, WiFiClient *wc, void *pData)
|
||||
{
|
||||
SAB *p = (SAB *)pData;
|
||||
char buffer[300];
|
||||
@ -206,7 +206,7 @@ boolean powerInfoApi(WEBServerManager::HttpRequestData &HRD, WiFiClient *wc, voi
|
||||
return true;
|
||||
}
|
||||
|
||||
boolean ioGetLevelApi(WEBServerManager::HttpRequestData &HRD, WiFiClient *wc, void *pData)
|
||||
boolean ioGetLevelApi(WEBServer<WEBClient>::HttpRequestData &HRD, WiFiClient *wc, void *pData)
|
||||
{
|
||||
boolean *ioState = (boolean *)pData;
|
||||
char buffer[300] = "";
|
||||
@ -266,7 +266,7 @@ boolean ioGetLevelApi(WEBServerManager::HttpRequestData &HRD, WiFiClient *wc, vo
|
||||
return true;
|
||||
}
|
||||
|
||||
boolean ioSetLevelApi(WEBServerManager::HttpRequestData &HRD, WiFiClient *wc, void *pData)
|
||||
boolean ioSetLevelApi(WEBServer<WEBClient>::HttpRequestData &HRD, WiFiClient *wc, void *pData)
|
||||
{
|
||||
SAB *p = (SAB *)pData;
|
||||
char buffer[300] = "";
|
||||
@ -312,7 +312,7 @@ boolean ioSetLevelApi(WEBServerManager::HttpRequestData &HRD, WiFiClient *wc, vo
|
||||
return true;
|
||||
}
|
||||
|
||||
boolean ioGetModeApi(WEBServerManager::HttpRequestData &HRD, WiFiClient *wc, void *pData)
|
||||
boolean ioGetModeApi(WEBServer<WEBClient>::HttpRequestData &HRD, WiFiClient *wc, void *pData)
|
||||
{
|
||||
SAB *p = (SAB *)pData;
|
||||
boolean ioMode[8] = {0};
|
||||
@ -375,7 +375,7 @@ boolean ioGetModeApi(WEBServerManager::HttpRequestData &HRD, WiFiClient *wc, voi
|
||||
return true;
|
||||
}
|
||||
|
||||
boolean ioSetModeApi(WEBServerManager::HttpRequestData &HRD, WiFiClient *wc, void *pData)
|
||||
boolean ioSetModeApi(WEBServer<WEBClient>::HttpRequestData &HRD, WiFiClient *wc, void *pData)
|
||||
{
|
||||
SAB *p = (SAB *)pData;
|
||||
char buffer[300] = "";
|
||||
|
@ -1,33 +1,33 @@
|
||||
#ifndef WEBAPI_H
|
||||
#define WEBAPI_H
|
||||
#include "WebServerManager.h"
|
||||
//#include "WebServerManager.h"
|
||||
#include "SAB.h"
|
||||
#include "views.h"
|
||||
|
||||
boolean apiTesterApi(WEBServerManager::HttpRequestData&, WiFiClient*, void*);
|
||||
boolean nextViewApi(WEBServerManager::HttpRequestData&, WiFiClient*, void*);
|
||||
boolean viewByUIDApi(WEBServerManager::HttpRequestData&, WiFiClient*, void*);
|
||||
boolean rtcGetTimeApi(WEBServerManager::HttpRequestData&, WiFiClient*, void*);
|
||||
boolean rtcSetTimeApi(WEBServerManager::HttpRequestData&, WiFiClient*, void*);
|
||||
boolean sdCardSizeApi(WEBServerManager::HttpRequestData&, WiFiClient*, void*);
|
||||
boolean apiTesterApi(WEBServer<WEBClient>::HttpRequestData&, WiFiClient*, void*);
|
||||
boolean nextViewApi(WEBServer<WEBClient>::HttpRequestData&, WiFiClient*, void*);
|
||||
boolean viewByUIDApi(WEBServer<WEBClient>::HttpRequestData&, WiFiClient*, void*);
|
||||
boolean rtcGetTimeApi(WEBServer<WEBClient>::HttpRequestData&, WiFiClient*, void*);
|
||||
boolean rtcSetTimeApi(WEBServer<WEBClient>::HttpRequestData&, WiFiClient*, void*);
|
||||
boolean sdCardSizeApi(WEBServer<WEBClient>::HttpRequestData&, WiFiClient*, void*);
|
||||
|
||||
typedef struct sdCardApiPacket
|
||||
{
|
||||
SAB *pSab;
|
||||
View1Packet *pView;
|
||||
} SdCardApiPacket;
|
||||
boolean sdCardUnmountApi(WEBServerManager::HttpRequestData&, WiFiClient*, void*);
|
||||
boolean sdCardMountApi(WEBServerManager::HttpRequestData&, WiFiClient*, void*);
|
||||
boolean sdCardUnmountApi(WEBServer<WEBClient>::HttpRequestData&, WiFiClient*, void*);
|
||||
boolean sdCardMountApi(WEBServer<WEBClient>::HttpRequestData&, WiFiClient*, void*);
|
||||
|
||||
boolean staWifiInfoApi(WEBServerManager::HttpRequestData&, WiFiClient*, void*);
|
||||
boolean apWifiInfoApi(WEBServerManager::HttpRequestData&, WiFiClient*, void*);
|
||||
boolean espRestartApi(WEBServerManager::HttpRequestData&, WiFiClient*, void*);
|
||||
boolean espResetApi(WEBServerManager::HttpRequestData&, WiFiClient*, void*);
|
||||
boolean systemInfoApi(WEBServerManager::HttpRequestData&, WiFiClient*, void*);
|
||||
boolean powerInfoApi(WEBServerManager::HttpRequestData&, WiFiClient*, void*);
|
||||
boolean ioGetLevelApi(WEBServerManager::HttpRequestData&, WiFiClient*, void*);
|
||||
boolean ioSetLevelApi(WEBServerManager::HttpRequestData&, WiFiClient*, void*);
|
||||
boolean ioGetModeApi(WEBServerManager::HttpRequestData&, WiFiClient*, void*);
|
||||
boolean ioSetModeApi(WEBServerManager::HttpRequestData&, WiFiClient*, void*);
|
||||
boolean staWifiInfoApi(WEBServer<WEBClient>::HttpRequestData&, WiFiClient*, void*);
|
||||
boolean apWifiInfoApi(WEBServer<WEBClient>::HttpRequestData&, WiFiClient*, void*);
|
||||
boolean espRestartApi(WEBServer<WEBClient>::HttpRequestData&, WiFiClient*, void*);
|
||||
boolean espResetApi(WEBServer<WEBClient>::HttpRequestData&, WiFiClient*, void*);
|
||||
boolean systemInfoApi(WEBServer<WEBClient>::HttpRequestData&, WiFiClient*, void*);
|
||||
boolean powerInfoApi(WEBServer<WEBClient>::HttpRequestData&, WiFiClient*, void*);
|
||||
boolean ioGetLevelApi(WEBServer<WEBClient>::HttpRequestData&, WiFiClient*, void*);
|
||||
boolean ioSetLevelApi(WEBServer<WEBClient>::HttpRequestData&, WiFiClient*, void*);
|
||||
boolean ioGetModeApi(WEBServer<WEBClient>::HttpRequestData&, WiFiClient*, void*);
|
||||
boolean ioSetModeApi(WEBServer<WEBClient>::HttpRequestData&, WiFiClient*, void*);
|
||||
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue
Block a user