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 <stdio.h>
|
||||||
#include <Arduino.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>
|
template <typename T>
|
||||||
class Dictionary
|
class Dictionary
|
||||||
@ -13,6 +43,25 @@ class Dictionary
|
|||||||
public:
|
public:
|
||||||
Dictionary() :_parameter(NULL), _value(NULL), _next(NULL), _head(this){}
|
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()
|
~Dictionary()
|
||||||
{
|
{
|
||||||
if(_head == this)
|
if(_head == this)
|
||||||
@ -133,9 +182,22 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
const char *stringValue() const {return _value == NULL ? "" : _value->toString();}
|
const char *stringValue() const {return _value == NULL ? "" : _value->toString();}
|
||||||
T getValue(){return T(*_value);}
|
const char *getParameter(const unsigned int index)
|
||||||
T* getValueRef(){return _value;}
|
{
|
||||||
const char *getParameter() const{return _parameter == NULL ? "" : _parameter;}
|
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:
|
protected:
|
||||||
Dictionary(const char *parameter, T *value) : Dictionary()
|
Dictionary(const char *parameter, T *value) : Dictionary()
|
||||||
{
|
{
|
||||||
@ -146,17 +208,6 @@ protected:
|
|||||||
_value = value;
|
_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)
|
boolean addNewNodeAtTheEnd(Dictionary *node)
|
||||||
{
|
{
|
||||||
if(node == NULL) return false;
|
if(node == NULL) return false;
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
#define DEBUG
|
#define DEBUG
|
||||||
#define DEBUG_RAW
|
#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();
|
_wifiServer.begin();
|
||||||
}
|
}
|
||||||
@ -82,11 +82,12 @@ boolean WEBServerManager::runServer()
|
|||||||
|
|
||||||
boolean WEBServerManager::parseQuery(WiFiClient *wifiClient)
|
boolean WEBServerManager::parseQuery(WiFiClient *wifiClient)
|
||||||
{
|
{
|
||||||
char readChar(0), *parseBuffer(NULL);
|
char readChar(0), *parseBuffer(NULL), *parseKey(NULL), *parseValue(NULL);
|
||||||
boolean smallTimeout(false);
|
boolean smallTimeout(false), isKey(true);
|
||||||
|
|
||||||
_httpParserState = INIT;
|
_httpParserState = INIT;
|
||||||
_clientTimeout = millis();
|
_clientTimeout = millis();
|
||||||
|
boolean slashesOrantiSlashesOnly(true);
|
||||||
while(wifiClient->available() || millis() - _clientTimeout < (smallTimeout ? 100 : 5000))
|
while(wifiClient->available() || millis() - _clientTimeout < (smallTimeout ? 100 : 5000))
|
||||||
{
|
{
|
||||||
if(wifiClient->available())
|
if(wifiClient->available())
|
||||||
@ -131,18 +132,60 @@ boolean WEBServerManager::parseQuery(WiFiClient *wifiClient)
|
|||||||
_httpParserState = ERROR;
|
_httpParserState = ERROR;
|
||||||
break;
|
break;
|
||||||
case HTTP_RESOURCE_SECTION:
|
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);
|
parseBuffer = addChar(parseBuffer, readChar);
|
||||||
_httpParserState = HTTP_RESOURCE_SECTION;
|
_httpParserState = HTTP_RESOURCE_SECTION;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
free(_httpRequestData.httpResource);_httpRequestData.httpResource = NULL;
|
free(_httpRequestData.httpResource);_httpRequestData.httpResource = NULL;
|
||||||
_httpRequestData.httpResource = parseBuffer;parseBuffer = NULL;
|
if(slashesOrantiSlashesOnly)
|
||||||
_httpParserState = HTTP_VER_SECTION;
|
{
|
||||||
|
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;
|
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:
|
case HTTP_VER_SECTION:
|
||||||
if((readChar >= 48 && readChar <= 57) || readChar == '.')
|
if((readChar >= 48 && readChar <= 57) || readChar == '.')
|
||||||
{
|
{
|
||||||
@ -194,6 +237,11 @@ boolean WEBServerManager::parseQuery(WiFiClient *wifiClient)
|
|||||||
Serial.println(_httpRequestData.HV);
|
Serial.println(_httpRequestData.HV);
|
||||||
Serial.print("BODY CONTENT : ");
|
Serial.print("BODY CONTENT : ");
|
||||||
Serial.println(_httpRequestData.httpBody);
|
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
|
#endif
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@ -323,8 +371,9 @@ boolean WEBServerManager::sendPageToClientFromSdCard(WiFiClient *wifiClient)
|
|||||||
|
|
||||||
boolean WEBServerManager::sendPageToClientFromApiDictio(WiFiClient *wifiClient)
|
boolean WEBServerManager::sendPageToClientFromApiDictio(WiFiClient *wifiClient)
|
||||||
{
|
{
|
||||||
if(_apiDictionary.count() == 0)
|
if(_apiDictionary.count() == 0 || _httpRequestData.httpResource == NULL)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
ApiRoutine *ref = _apiDictionary(_httpRequestData.httpResource);
|
ApiRoutine *ref = _apiDictionary(_httpRequestData.httpResource);
|
||||||
|
|
||||||
if(ref == NULL)
|
if(ref == NULL)
|
||||||
@ -441,5 +490,5 @@ void WEBServerManager::clearHttpRequestData()
|
|||||||
_httpRequestData.HMT = UNKNOWN_MIME;
|
_httpRequestData.HMT = UNKNOWN_MIME;
|
||||||
free(_httpRequestData.httpResource);free(_httpRequestData.httpBody);
|
free(_httpRequestData.httpResource);free(_httpRequestData.httpBody);
|
||||||
_httpRequestData.httpResource = NULL;_httpRequestData.httpBody = NULL;
|
_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 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 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 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};
|
enum HttpMIMEType{UNKNOWN_MIME, TEXT_PLAIN, TEXT_CSS, TEXT_HTML, TEXT_JAVASCRIPT, APPLICATION_JSON, APPLICATION_X_WWW_FORM_URLENCODED, IMAGE_PNG};
|
||||||
struct HttpRequestData{
|
struct HttpRequestData{
|
||||||
HttpRequestMethod HRM;
|
HttpRequestMethod HRM;
|
||||||
HttpVersion HV;
|
HttpVersion HV;
|
||||||
HttpMIMEType HMT;
|
HttpMIMEType HMT;
|
||||||
|
Dictionary<DictionaryHelper::StringEntity> getParams;
|
||||||
|
Dictionary<DictionaryHelper::StringEntity> postParams;
|
||||||
char *httpResource;
|
char *httpResource;
|
||||||
char *httpBody;
|
char *httpBody;
|
||||||
};
|
};
|
||||||
|
@ -16,6 +16,8 @@ ViewSTAPacket vstap = {sab.getConnectivityManager().macAddress(), sab.getConnect
|
|||||||
void setup()
|
void setup()
|
||||||
{
|
{
|
||||||
// put your setup code here, to run once:
|
// put your setup code here, to run once:
|
||||||
|
pinMode(GPIO_0, INPUT);
|
||||||
|
|
||||||
Serial.println("Starting setup");
|
Serial.println("Starting setup");
|
||||||
CFGFileParser cfgFileParser(sab.getSdCardManager(), AP_CFG_FILE);
|
CFGFileParser cfgFileParser(sab.getSdCardManager(), AP_CFG_FILE);
|
||||||
CFGDictionary<CFGParameterValue> *cfgDictionary = (CFGDictionary<CFGParameterValue> *) cfgFileParser.parseFile();
|
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());
|
Serial.print("AP PASSWORD : ");if((*cfgDictionary)("PASSWORD") != NULL)Serial.println((*cfgDictionary)("PASSWORD")->stringValue());
|
||||||
delete cfgDictionary;
|
delete cfgDictionary;
|
||||||
|
|
||||||
|
|
||||||
pinMode(GPIO_0, INPUT);
|
|
||||||
sab.getScreenManager().addView(&(view_1), &v1p, 0);
|
sab.getScreenManager().addView(&(view_1), &v1p, 0);
|
||||||
sab.getScreenManager().addView(&(view_2), &vap, 1);
|
sab.getScreenManager().addView(&(view_2), &vap, 1);
|
||||||
sab.getScreenManager().addView(&(view_3), &vstap, 2);
|
sab.getScreenManager().addView(&(view_3), &vstap, 2);
|
||||||
@ -34,7 +34,10 @@ void setup()
|
|||||||
Serial.println("Clock lost power");
|
Serial.println("Clock lost power");
|
||||||
sab.getRtcManager().setDateTime(DateTime(F(__DATE__), F(__TIME__)));
|
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");
|
Serial.println("End setup");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,12 +1,29 @@
|
|||||||
#include "SAB.h"
|
#include "SAB.h"
|
||||||
#include "webApi.h"
|
#include "webApi.h"
|
||||||
|
|
||||||
boolean helloServerApi(WEBServerManager::HttpRequestData& HRD, WiFiClient* wc, void* pData)
|
boolean helloServerApi(WEBServerManager::HttpRequestData &HRD, WiFiClient* wc, void* pData)
|
||||||
{
|
{
|
||||||
SAB *sab = (SAB *)pData;
|
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("Before");
|
return true;
|
||||||
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");
|
|
||||||
|
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;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3,5 +3,7 @@
|
|||||||
#include "WebServerManager.h"
|
#include "WebServerManager.h"
|
||||||
|
|
||||||
boolean helloServerApi(WEBServerManager::HttpRequestData&, WiFiClient*, void*);
|
boolean helloServerApi(WEBServerManager::HttpRequestData&, WiFiClient*, void*);
|
||||||
|
boolean nextViewApi(WEBServerManager::HttpRequestData&, WiFiClient*, void*);
|
||||||
|
boolean rtcTimeApi(WEBServerManager::HttpRequestData&, WiFiClient*, void*);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
Reference in New Issue
Block a user