Added Dictionary string entity class for char * manipulation, completed webApi, updated main app and other small things
This commit is contained in:
parent
bd99e8ff27
commit
bd5afe4592
@ -6,6 +6,36 @@
|
||||
#include <stdio.h>
|
||||
#include <Arduino.h>
|
||||
|
||||
namespace DictionaryHelper
|
||||
{
|
||||
//String helper class with c style char array
|
||||
class StringEntity
|
||||
{
|
||||
public:
|
||||
StringEntity(const char *string) : _string(NULL)
|
||||
{
|
||||
if(string == NULL)
|
||||
{
|
||||
_string = (char *) malloc((sizeof(char)) * 2); //+1 for the string terminating character
|
||||
strcpy(_string, "");
|
||||
}
|
||||
else
|
||||
{
|
||||
_string = (char *) malloc((strlen(string) * sizeof(char)) + 1); //+1 for the string terminating character
|
||||
strcpy(_string, string);
|
||||
}
|
||||
}
|
||||
StringEntity(const StringEntity &Object)
|
||||
{
|
||||
_string = (char *) malloc((strlen(Object._string) * sizeof(char)) + 1); //+1 for the string terminating character
|
||||
strcpy(_string, Object._string);
|
||||
}
|
||||
~StringEntity(){free(_string);}
|
||||
char *getString(){return _string;}
|
||||
private:
|
||||
char *_string;
|
||||
};
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
class Dictionary
|
||||
@ -13,6 +43,25 @@ class Dictionary
|
||||
public:
|
||||
Dictionary() :_parameter(NULL), _value(NULL), _next(NULL), _head(this){}
|
||||
|
||||
Dictionary(Dictionary const& dictionaryToCopy) //Copy constructor needed because of pointers
|
||||
{
|
||||
_head = this;
|
||||
_next = NULL;
|
||||
|
||||
if(dictionaryToCopy._parameter != NULL)
|
||||
{
|
||||
_parameter = (char *) malloc((strlen(dictionaryToCopy._parameter) * sizeof(char)) + 1); //+1 for the string terminating character
|
||||
_value = new T(*(dictionaryToCopy._value));
|
||||
|
||||
strcpy(_parameter, dictionaryToCopy._parameter);
|
||||
}else
|
||||
{
|
||||
_parameter = NULL;
|
||||
_value = NULL;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
~Dictionary()
|
||||
{
|
||||
if(_head == this)
|
||||
@ -133,9 +182,22 @@ public:
|
||||
}
|
||||
|
||||
const char *stringValue() const {return _value == NULL ? "" : _value->toString();}
|
||||
T getValue(){return T(*_value);}
|
||||
T* getValueRef(){return _value;}
|
||||
const char *getParameter() const{return _parameter == NULL ? "" : _parameter;}
|
||||
const char *getParameter(const unsigned int index)
|
||||
{
|
||||
unsigned int position(0);
|
||||
if(isListEmpty(_head->_next))return "";
|
||||
|
||||
Dictionary *cursor = _head->_next;
|
||||
|
||||
while(!isListEmpty(cursor))
|
||||
{
|
||||
if(position++ == index)
|
||||
return cursor->_parameter;
|
||||
cursor = cursor->_next;
|
||||
}
|
||||
|
||||
return "";
|
||||
}
|
||||
protected:
|
||||
Dictionary(const char *parameter, T *value) : Dictionary()
|
||||
{
|
||||
@ -146,17 +208,6 @@ protected:
|
||||
_value = value;
|
||||
}
|
||||
|
||||
Dictionary(Dictionary const& dictionaryToCopy) //Copy constructor needed because of pointers
|
||||
{
|
||||
_head = NULL;
|
||||
_next = NULL;
|
||||
|
||||
_parameter = (char *) malloc((strlen(dictionaryToCopy._parameter) * sizeof(char)) + 1); //+1 for the string terminating character
|
||||
_value = dictionaryToCopy._value;
|
||||
|
||||
strcpy(_parameter, dictionaryToCopy._parameter);
|
||||
}
|
||||
|
||||
boolean addNewNodeAtTheEnd(Dictionary *node)
|
||||
{
|
||||
if(node == NULL) return false;
|
||||
|
@ -3,7 +3,7 @@
|
||||
#define DEBUG
|
||||
#define DEBUG_RAW
|
||||
|
||||
WEBServerManager::WEBServerManager(unsigned int port, SDCardManager *sdCardManager) : _wifiServer(port), _sdCardManager(sdCardManager), _httpRequestData({UNDEFINED, UNKNOWN, UNKNOWN_MIME, NULL,NULL}), _httpParserState(INIT), _clientState(WAITING_FOR_CLIENT), _port(port), _clientTimeout(0)
|
||||
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)
|
||||
{
|
||||
_wifiServer.begin();
|
||||
}
|
||||
@ -82,11 +82,12 @@ boolean WEBServerManager::runServer()
|
||||
|
||||
boolean WEBServerManager::parseQuery(WiFiClient *wifiClient)
|
||||
{
|
||||
char readChar(0), *parseBuffer(NULL);
|
||||
boolean smallTimeout(false);
|
||||
char readChar(0), *parseBuffer(NULL), *parseKey(NULL), *parseValue(NULL);
|
||||
boolean smallTimeout(false), isKey(true);
|
||||
|
||||
_httpParserState = INIT;
|
||||
_clientTimeout = millis();
|
||||
boolean slashesOrantiSlashesOnly(true);
|
||||
while(wifiClient->available() || millis() - _clientTimeout < (smallTimeout ? 100 : 5000))
|
||||
{
|
||||
if(wifiClient->available())
|
||||
@ -131,18 +132,60 @@ boolean WEBServerManager::parseQuery(WiFiClient *wifiClient)
|
||||
_httpParserState = ERROR;
|
||||
break;
|
||||
case HTTP_RESOURCE_SECTION:
|
||||
if(readChar != ' ')
|
||||
if(readChar == '?' )
|
||||
{
|
||||
free(_httpRequestData.httpResource);_httpRequestData.httpResource = NULL;
|
||||
_httpRequestData.httpResource = parseBuffer;parseBuffer = NULL;
|
||||
|
||||
_httpParserState = HTTP_RESOURCE_PARAM_SECTION;
|
||||
}
|
||||
else if(readChar != ' ')
|
||||
{
|
||||
//if(readChar != '/' && readChar != '\\') slashesOrantiSlashesOnly = false;
|
||||
|
||||
parseBuffer = addChar(parseBuffer, readChar);
|
||||
_httpParserState = HTTP_RESOURCE_SECTION;
|
||||
}
|
||||
else
|
||||
{
|
||||
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;
|
||||
}
|
||||
break;
|
||||
case HTTP_RESOURCE_PARAM_SECTION:
|
||||
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 == '.')
|
||||
{
|
||||
@ -194,6 +237,11 @@ boolean WEBServerManager::parseQuery(WiFiClient *wifiClient)
|
||||
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(i)->getString());
|
||||
}
|
||||
#endif
|
||||
|
||||
return true;
|
||||
@ -323,8 +371,9 @@ boolean WEBServerManager::sendPageToClientFromSdCard(WiFiClient *wifiClient)
|
||||
|
||||
boolean WEBServerManager::sendPageToClientFromApiDictio(WiFiClient *wifiClient)
|
||||
{
|
||||
if(_apiDictionary.count() == 0)
|
||||
if(_apiDictionary.count() == 0 || _httpRequestData.httpResource == NULL)
|
||||
return false;
|
||||
|
||||
ApiRoutine *ref = _apiDictionary(_httpRequestData.httpResource);
|
||||
|
||||
if(ref == NULL)
|
||||
@ -441,5 +490,5 @@ void WEBServerManager::clearHttpRequestData()
|
||||
_httpRequestData.HMT = UNKNOWN_MIME;
|
||||
free(_httpRequestData.httpResource);free(_httpRequestData.httpBody);
|
||||
_httpRequestData.httpResource = NULL;_httpRequestData.httpBody = NULL;
|
||||
|
||||
_httpRequestData.getParams.dispose();
|
||||
}
|
||||
|
@ -15,12 +15,14 @@ class WEBServerManager
|
||||
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_VER_SECTION, PARAMETER_SECTION, BODY_SECTION, IGNORED, ERROR};
|
||||
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};
|
||||
struct HttpRequestData{
|
||||
HttpRequestMethod HRM;
|
||||
HttpVersion HV;
|
||||
HttpMIMEType HMT;
|
||||
Dictionary<DictionaryHelper::StringEntity> getParams;
|
||||
Dictionary<DictionaryHelper::StringEntity> postParams;
|
||||
char *httpResource;
|
||||
char *httpBody;
|
||||
};
|
||||
|
@ -16,6 +16,8 @@ ViewSTAPacket vstap = {sab.getConnectivityManager().macAddress(), sab.getConnect
|
||||
void setup()
|
||||
{
|
||||
// put your setup code here, to run once:
|
||||
pinMode(GPIO_0, INPUT);
|
||||
|
||||
Serial.println("Starting setup");
|
||||
CFGFileParser cfgFileParser(sab.getSdCardManager(), AP_CFG_FILE);
|
||||
CFGDictionary<CFGParameterValue> *cfgDictionary = (CFGDictionary<CFGParameterValue> *) cfgFileParser.parseFile();
|
||||
@ -23,8 +25,6 @@ void setup()
|
||||
Serial.print("AP PASSWORD : ");if((*cfgDictionary)("PASSWORD") != NULL)Serial.println((*cfgDictionary)("PASSWORD")->stringValue());
|
||||
delete cfgDictionary;
|
||||
|
||||
|
||||
pinMode(GPIO_0, INPUT);
|
||||
sab.getScreenManager().addView(&(view_1), &v1p, 0);
|
||||
sab.getScreenManager().addView(&(view_2), &vap, 1);
|
||||
sab.getScreenManager().addView(&(view_3), &vstap, 2);
|
||||
@ -34,7 +34,10 @@ void setup()
|
||||
Serial.println("Clock lost power");
|
||||
sab.getRtcManager().setDateTime(DateTime(F(__DATE__), F(__TIME__)));
|
||||
}
|
||||
sab.getWebServerManager().addApiRoutine("/hello", &(helloServerApi), &sab);
|
||||
|
||||
sab.getWebServerManager().addApiRoutine("/helloServer", &(helloServerApi), NULL);
|
||||
sab.getWebServerManager().addApiRoutine("/view/next", &(nextViewApi), &sab, WEBServerManager::GET);
|
||||
sab.getWebServerManager().addApiRoutine("/rtc/get/time", &(rtcTimeApi), &sab, WEBServerManager::GET);
|
||||
Serial.println("End setup");
|
||||
}
|
||||
|
||||
|
@ -3,10 +3,27 @@
|
||||
|
||||
boolean helloServerApi(WEBServerManager::HttpRequestData &HRD, WiFiClient* wc, void* pData)
|
||||
{
|
||||
SAB *sab = (SAB *)pData;
|
||||
Serial.println("Before");
|
||||
wc->print(F("HTTP/1.1 200 OK\r\nContent-Type: text/html\r\n\r\n<!DOCTYPE HTML>\r\n<html>\r\n<p>Hello Client !!!</p>\r\n</html>"));
|
||||
Serial.println("After");
|
||||
wc->print(F("HTTP/1.1 200 OK\r\nContent-Type: text/html\r\n\r\n<!DOCTYPE HTML>\r\n<html>\r\n<p>Hello client !!!</p>\r\n</html>"));
|
||||
return true;
|
||||
}
|
||||
|
||||
boolean nextViewApi(WEBServerManager::HttpRequestData &HRD, WiFiClient *wc, void *pData)
|
||||
{
|
||||
SAB *p = (SAB *)pData;
|
||||
char buffer[200];
|
||||
p->getScreenManager().displayNextView();
|
||||
sprintf(buffer,"HTTP/1.1 200 OK\r\nContent-Type: application/json\r\n\r\n{ \"status\" : \"ok\", \"ViewUID\" : \"%d\" }", p->getScreenManager().getCurrentViewUID());
|
||||
wc->print(buffer);
|
||||
return true;
|
||||
}
|
||||
|
||||
boolean rtcTimeApi(WEBServerManager::HttpRequestData &HRD, WiFiClient *wc, void *pData)
|
||||
{
|
||||
SAB *p = (SAB *)pData;
|
||||
char buffer[200];
|
||||
DateTime d = p->getRtcManager().getDateTime();
|
||||
sprintf(buffer,"HTTP/1.1 200 OK\r\nContent-Type: application/json\r\n\r\n{ \"status\" : \"ok\", \"date\" : \"%d/%d/%d\", \"time\" : \"%d:%d:%d\" }", d.day(), d.month(), d.year(), d.hour(), d.minute(), d.second());
|
||||
wc->print(buffer);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -3,5 +3,7 @@
|
||||
#include "WebServerManager.h"
|
||||
|
||||
boolean helloServerApi(WEBServerManager::HttpRequestData&, WiFiClient*, void*);
|
||||
boolean nextViewApi(WEBServerManager::HttpRequestData&, WiFiClient*, void*);
|
||||
boolean rtcTimeApi(WEBServerManager::HttpRequestData&, WiFiClient*, void*);
|
||||
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue
Block a user