diff --git a/src/app/WEBServerManager.cpp b/src/app/WEBServerManager.cpp new file mode 100644 index 0000000..9058a28 --- /dev/null +++ b/src/app/WEBServerManager.cpp @@ -0,0 +1,232 @@ +#include "WEBServerManager.h" + +#define DEBUG + +WEBServerManager::WEBServerManager(unsigned int port, SDCardManager *sdCardManager) : _wifiServer(port), _sdCardManager(sdCardManager), _httpRequestData({UNDEFINED, UNKNOWN, NULL,NULL}), _httpParserState(INIT), _clientState(WAITING_FOR_CLIENT), _port(port), _clientTimeout(0) +{ + _wifiServer.begin(); +} + +boolean WEBServerManager::runServer() +{ + switch(_clientState) + { + case WAITING_FOR_CLIENT: + _wifiClient.stopAll(); + _wifiClient = _wifiServer.available(); + if(_wifiClient) + { + _clientState = NEW; + _clientTimeout = millis(); + #ifdef DEBUG + Serial.println("Client connected !!!"); + #endif + } + break; + case NEW: + _clientState = NOT_HANDLED; + break; + case NOT_HANDLED: + if(millis()-_clientTimeout > 500) + { + _clientState = HANDLED; + #ifdef DEBUG + Serial.println("Client timed out !!!"); + #endif + } + parseQuery(&_wifiClient); + break; + case QUERY_PARSED: + _clientState = RESPONSE_SENT; + break; + case RESPONSE_SENT: + #ifdef DEBUG + Serial.println("Client handled !!!"); + #endif + _wifiClient.print(F("HTTP/1.1 200 OK\r\nContent-Type: text/html\r\n\r\n\r\n\r\n
Response !!!
")); + + _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); + _httpParserState = INIT; + + while(wifiClient->available()) + { + readChar = (char)wifiClient->read(); + #ifdef DEBUG + //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: + _httpParserState = IGNORED; + 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 + #ifdef DEBUG + Serial.print("HTTP VERB : "); + Serial.println(parseBuffer); + #endif + _httpRequestData.HRM = getHttpVerbEnumValue(parseBuffer); + #ifdef DEBUG + Serial.print("ENUM VALUE :"); + Serial.println(_httpRequestData.HRM); + #endif + free(parseBuffer);parseBuffer = NULL; + _httpParserState = HTTP_RESOURCE_SECTION; + } + else + _httpParserState = ERROR; + break; + case HTTP_RESOURCE_SECTION: + if(readChar != ' ') + { + parseBuffer = addChar(parseBuffer, readChar); + _httpParserState = HTTP_RESOURCE_SECTION; + } + else + { + #ifdef DEBUG + Serial.print("HTTP RESOURCE : "); + Serial.println(parseBuffer); + #endif + free(_httpRequestData.httpResource);_httpRequestData.httpResource = NULL; + _httpRequestData.httpResource = parseBuffer;parseBuffer = NULL; + _httpParserState = HTTP_VER_SECTION; + } + break; + case HTTP_VER_SECTION: + if((readChar >= 48 && readChar <= 57) || readChar == '.') + { + parseBuffer = addChar(parseBuffer, readChar); + _httpParserState = HTTP_VER_SECTION; + } + else if(readChar == '\r' || readChar == '\n') + { + #ifdef DEBUG + Serial.print("HTTP VERSION : "); + Serial.println(parseBuffer); + #endif + _httpRequestData.HV = getHttpVersionEnumValue(parseBuffer); + #ifdef DEBUG + Serial.print("HTTP VERSION ENUM : "); + Serial.println(_httpRequestData.HV); + #endif + free(parseBuffer);parseBuffer = NULL; + _httpParserState = LINE_BREAK; + } + break; + case BODY_SECTION: + break; + case IGNORED: + break; + case ERROR: + return false; + break; //Not necessary + default : + break; + } + + _clientState = QUERY_PARSED; + } + return true; +} + +unsigned int WEBServerManager::getPort() const +{ + return _port; +} + +char *WEBServerManager::addChar(char *pointer, const char character) +{ + char *tempAddr = NULL; + if(pointer == NULL) + { + tempAddr = (char *) realloc(pointer, 2*sizeof(char)); + if(tempAddr == NULL) + return NULL; + else + { + pointer = tempAddr; + pointer[0] = character; + pointer[1] = '\0'; + } + } + else + { + tempAddr = (char *) realloc(pointer, (strlen(pointer)+2)*sizeof(char)); + if(tempAddr == NULL) + { + free(pointer); + return NULL; + } + else + { + pointer = tempAddr; + pointer[strlen(pointer)+1] = '\0'; + pointer[strlen(pointer)] = character; + } + } + + return pointer; +} + +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; +} + diff --git a/src/app/WEBServerManager.h b/src/app/WEBServerManager.h new file mode 100644 index 0000000..eb15056 --- /dev/null +++ b/src/app/WEBServerManager.h @@ -0,0 +1,46 @@ +#ifndef WEBSERVERMANAGER_H +#define WEBSERVERMANAGER_H + +#include