diff --git a/src/software_test/dataStructure_test/dataStructure_test.ino b/src/software_test/dataStructure_test/dataStructure_test.ino new file mode 100644 index 0000000..b7df9b1 --- /dev/null +++ b/src/software_test/dataStructure_test/dataStructure_test.ino @@ -0,0 +1,57 @@ +/** + * This sketch was written in order to test the List and Queue datastructures used in my project + * This test was aimed toward spotting memory leaks + * Anatole SCHRAMM-HENRY 08/05/2019 + */ + +#include "D:/Users/Think/Desktop/Mes documents/Programmation/Arduino/ESP8266_swiss_army_board/src/app/List.h" +#include "D:/Users/Think/Desktop/Mes documents/Programmation/Arduino/ESP8266_swiss_army_board/src/app/Queue.h" + +uint32_t timer(0); + +List strList; +Queue strQueue; + +void setup() { + // put your setup code here, to run once: + Serial.begin(115200); + timer = millis(); +} + +void loop() { + // put your main code here, to run repeatedly: + strList.addFirst(String("Vive l'esp")); + strList.addLast(strList.removeFirstRef()); + strList.addFirst(strList.removeLastRef()); + strList.addLast(String("Vive l'esp")); + + + strQueue.add(String("Meme pas vrai")); + delete strQueue.removeRef(); + strQueue.add(String("Meme pas vrai")); + strQueue.remove(); + if(millis() - timer >= 1000) + { + debugInfo(); + timer = millis(); + } + + if(strList.count() > 20) + { + //Serial.println("Cleared"); + strList.clear(); + } + strList.removeFirst(); + +} + + +void debugInfo() +{ + uint32_t freeMem; + uint16_t biggestContigMemBlock; + uint8_t frag; + ESP.getHeapStats(&freeMem, &biggestContigMemBlock, &frag); + Serial.print("Free MEM : ");Serial.println(freeMem); + Serial.print("Heap Frag : ");Serial.println(frag); +} diff --git a/src/software_test/tcpServer_test/Dictionary.h b/src/software_test/tcpServer_test/Dictionary.h new file mode 100644 index 0000000..b9d2055 --- /dev/null +++ b/src/software_test/tcpServer_test/Dictionary.h @@ -0,0 +1,304 @@ +#ifndef DICTIONARY_H +#define DICTIONARY_H + +#include +#include +#include +#include + +template +class Dictionary; + +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;} + Dictionary *split(char character); + private: + char *_string; + }; +} + +template +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) + dispose(); + free(_parameter); + //_parameter = NULL; Useless, just my c habits + delete _value; + //_value = NULL; //Useless, just my c habits + } + + boolean add(const char *parameter, T *value) + { + Dictionary *dictionaryNode = new Dictionary(parameter, value); + return addNewNodeAtTheEnd(dictionaryNode); + } + + boolean add(int indice, T *value) + { + char indiceToStr[10]; + sprintf(indiceToStr,"%d", indice); + Dictionary *dictionaryNode = new Dictionary(indiceToStr, value); + return addNewNodeAtTheEnd(dictionaryNode); + } + + boolean add(const char *parameter, T value) + { + Dictionary *dictionaryNode = new Dictionary(parameter, new T(value)); + return addNewNodeAtTheEnd(dictionaryNode); + } + + boolean add(int indice, T value) + { + char indiceToStr[10]; + sprintf(indiceToStr,"%d", indice); + Dictionary *dictionaryNode = new Dictionary(indiceToStr, new T(value)); + return addNewNodeAtTheEnd(dictionaryNode); + } + + boolean remove(const char *parameter) + { + if(_head->_next == NULL) return false; + + Dictionary *cursor = _head, *toDelete(NULL); + + while(!isListEmpty(cursor->_next)) + { + if(strcmp(cursor->_next->_parameter, parameter) == 0) + { + toDelete = cursor->_next; + cursor->_next = cursor->_next->_next; + + delete toDelete; + return true; + } + cursor = cursor->_next; + } + return false; + } + + boolean remove(int indice) + { + char indiceToStr[10]; + sprintf(indiceToStr,"%d", indice); + return remove(indiceToStr); + } + + boolean removeAt(unsigned int index) + { + unsigned int position(0); + if(_head->_next == NULL) return false; + + Dictionary *cursor = _head, *toDelete(NULL); + + while(!isListEmpty(cursor->_next)) + { + if(position++ == index) + { + toDelete = cursor->_next; + cursor->_next = cursor->_next->_next; + + delete toDelete; + return true; + } + cursor = cursor->_next; + } + return false; + } + + T* get(const char *parameter) + { + if(parameter == NULL) return NULL; + if(isListEmpty(_head->_next))return NULL; + + Dictionary *cursor = _head->_next; + + while(!isListEmpty(cursor)) + { + if(strcmp(cursor->_parameter,parameter) == 0) + return cursor->_value; + cursor = cursor->_next; + } + + return NULL; + } + + T* operator()(const char *parameter) + { + return get(parameter); + } + + T* get(const unsigned int index) + { + unsigned int position(0); + if(isListEmpty(_head->_next))return NULL; + + Dictionary *cursor = _head->_next; + + while(!isListEmpty(cursor)) + { + if(position++ == index) + return cursor->_value; + cursor = cursor->_next; + } + + return NULL; + } + + T* operator()(const unsigned int index) + { + return get(index); + } + + unsigned int count() + { + unsigned int counter(0); + if(isListEmpty(_head->_next))return counter; + + Dictionary *cursor = _head->_next; + while(!isListEmpty(cursor)) + { + counter++; + cursor = cursor->_next; + } + return counter; + } + + void clear() {this->dispose();} + + void dispose() + { + if(isListEmpty(_head->_next))return; + + Dictionary *cursor = _head->_next, *toDelete(NULL); + + while(!isListEmpty(cursor)) + { + toDelete = cursor; + cursor = cursor->_next; + + delete toDelete; + } + _head = this; + _next = NULL; + } + + const char *stringValue() const {return _value == NULL ? "" : _value->toString();} + 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() + { + //We copy the parameter and the value + _parameter = (char *) malloc((strlen(parameter) * sizeof(char)) + 1); //+1 for the string terminating character + + strcpy(_parameter, parameter); + _value = value; + } + + boolean addNewNodeAtTheEnd(Dictionary *node) + { + if(node == NULL) return false; + + node->_head = _head; //Every node should point to the first node + + if(_next == NULL) //This is our first node then + { + _next = node; + return true; + } + + // /!\ We have to work with the _next reference in the loop, if we don't it won't work as expected + Dictionary *cursor = _head; + while(!isListEmpty(cursor->_next)) + { + if(strcmp(cursor->_next->_parameter, node->_parameter) == 0)//If we find the same parameter name, we replace it + { + delete (cursor->_next->_value); + cursor->_next->_value = new T(*(node->_value)); + if(cursor->_next->_value == NULL)return false; + + delete node; + + return true; + } + cursor = cursor->_next; + } + cursor->_next = node; + + return true; + } + boolean isListEmpty(Dictionary *node) {return node == NULL;} + + char *_parameter; + T *_value; + Dictionary *_next; + Dictionary *_head; +private: +}; + + + +#endif //DICTIONARY_H diff --git a/src/software_test/tcpServer_test/List.h b/src/software_test/tcpServer_test/List.h new file mode 100644 index 0000000..d856117 --- /dev/null +++ b/src/software_test/tcpServer_test/List.h @@ -0,0 +1,318 @@ +#ifndef LIST_H +#define LIST_H + +template +class List +{ +public: + List():_next(NULL), _head(this), _value(NULL) + { + } + ~List() + { + if(_head == this) + dispose(); + } + + boolean addFirst(T value) + { + List *listNode = new List(new T(value)); + return addNewNodeAtTheStart(listNode); + } + boolean addFirst(T *value) + { + List *listNode = new List(value); + return addNewNodeAtTheStart(listNode); + } + + boolean addLast(T value) + { + List *listNode = new List(new T(value)); + return addNewNodeAtTheEnd(listNode); + } + boolean addLast(T *value) + { + List *listNode = new List(value); + return addNewNodeAtTheEnd(listNode); + } + + T* getRef(unsigned int index) + { + unsigned int position(0); + if(_head->_next == NULL) return NULL; + + List *cursor = _head; + + while(!isListEmpty(cursor->_next)) + { + if(position++ == index) + { + return cursor->_next->_value; + } + cursor = cursor->_next; + } + return NULL; + } + T get(unsigned int index) + { + T* p = getRef(index); + if(p == NULL) + { + T value; + return value; + }else + { + T value(*p); + return value; + } + } + + T* getFirstRef() + { + if(_head->_next == NULL) return NULL; + + return _head->_next->_value; + } + T getFirst() + { + T* p = getFirstRef(); + if(p == NULL) + { + T value; + return value; + }else + { + T value(*p); + return value; + } + } + + T* getLastRef() + { + if(_head->_next == NULL) return NULL; + + List *cursor = _head; + while(!isListEmpty(cursor->_next)) + { + cursor = cursor->_next; + } + + return cursor->_value; + } + T getLast() + { + T* p = getLastRef(); + if(p == NULL) + { + T value; + return value; + }else + { + T value(*p); + return value; + } + } + + T* removeRef(unsigned int index) + { + unsigned int position(0); + if(_head->_next == NULL) return NULL; + + List *cursor = _head, *toRemove(NULL); + + while(!isListEmpty(cursor->_next)) + { + if(position++ == index || position == _head->count()) + { + toRemove = cursor->_next; + cursor->_next = cursor->_next->_next; + + T *toReturn = toRemove->_value; + delete toRemove; + return toReturn; + } + cursor = cursor->_next; + } + return NULL; + } + T remove(unsigned int index) + { + T *ref = removeRef(index); + if(ref != NULL) + { + T value(*ref); + delete ref; + return value; + }else + { + T value; + return value; + } + } + + T* removeFirstRef() + { + if(isListEmpty(_head->_next))return NULL; + + T *refToReturn = _head->_next->_value; + List *toDelete(_head->_next); + _head->_next = _head->_next->_next; + + delete toDelete; + return refToReturn; + } + T removeFirst() + { + T *ref = removeFirstRef(); + if(ref != NULL) + { + T value(*ref); + delete ref; + return value; + }else + { + T value; + return value; + } + } + + T* removeLastRef() + { + unsigned int position(0); + if(_head->_next == NULL) return NULL; + + List *cursor = _head, *toRemove(NULL); + + while(!isListEmpty(cursor->_next->_next)) + { + cursor = cursor->_next; + } + toRemove = cursor->_next; + cursor->_next = cursor->_next->_next; + + T *toReturn = toRemove->_value; + delete toRemove; + return toReturn; + } + T removeLast() + { + T *ref = removeLastRef(); + if(ref != NULL) + { + T value(*ref); + delete ref; + return value; + }else + { + T value; + return value; + } + } + int contains(T *value) + { + unsigned int position(-1); + if(_head->_next == NULL) return NULL; + + List *cursor = _head; + + while(!isListEmpty(cursor->_next)) + { + position++; + + if(*(cursor->_next->_value) == *value) + return position; + + cursor = cursor->_next; + } + return -1; + } + int contains(T value) + { + return contains(new T(value)); + } + unsigned int count() + { + unsigned int counter(0); + if(isListEmpty(_head->_next))return counter; + + List *cursor = _head->_next; + while(!isListEmpty(cursor)) + { + counter++; + cursor = cursor->_next; + } + return counter; + } + void clear(){_head->dispose();} + void dispose() + { + if(isListEmpty(_head->_next))return; + + List *cursor = _head->_next, *toDelete(NULL); + + while(!isListEmpty(cursor)) + { + toDelete = cursor; + cursor = cursor->_next; + + delete toDelete->_value; + delete toDelete; + } + _head = this; + _next = NULL; + } +protected: + List(T *value):List() + { + _value = value; + } + boolean isListEmpty(List *node){return node == NULL;} + boolean addNewNodeAtTheEnd(List *node) + { + if(node == NULL) return false; + + node->_head = _head; + + if(_next == NULL) + { + _next = node; + return true; + } + + // /!\ We have to work with the _next reference in the loop, if we don't it won't work as expected + List *cursor = _head; + while(!isListEmpty(cursor->_next)) + { + cursor = cursor->_next; + } + cursor->_next = node; + + return true; + } + + boolean addNewNodeAtTheStart(List *node) + { + if(node == NULL) return false; + + node->_head = _head; + + if(_next == NULL) + { + _next = node; + return true; + } + + List *temp = _next; + _next = node; + node->_next = temp; + + return true; + } + + List *_next; + List *_head; + T* _value; +private: +}; + +#endif //LIST_H diff --git a/src/software_test/tcpServer_test/TCPServer.cpp b/src/software_test/tcpServer_test/TCPServer.cpp new file mode 100644 index 0000000..80b6263 --- /dev/null +++ b/src/software_test/tcpServer_test/TCPServer.cpp @@ -0,0 +1,117 @@ +#include "TCPServer.h" +#define DEBUG + +TCPServer::TCPServer(unsigned int port, uint8_t maxClient) : _wifiServer(port), _port(port), _serverStarted(true), _maxClient(maxClient), _currentClient(NULL) +{ + _wifiServer.begin(); +} + +TCPServer::~TCPServer() +{ + _clientList.dispose(); +} + +void TCPServer::runServer() +{ + handleNewClients(); + getClientData(); +} + +void TCPServer::handleNewClients() +{ + WiFiClient wc; + + if(_maxClient == -1 || _maxClient > _clientList.count()) + { + wc = _wifiServer.available(); + } + + if(wc && wc.connected()) + { + _clientList.addFirst(new TCPServerHelper::TCPServerClient({wc, TCPServerHelper::TCPServerClient::NEW,{'/0'},0,false,_clientList.count(),{TCPServerHelper::UNDEFINED, TCPServerHelper::UNKNOWN, TCPServerHelper::UNKNOWN_MIME, Dictionary(), Dictionary(), NULL,NULL},TCPServerHelper::HTTP_VERB})); + #ifdef DEBUG + Serial.print("New client accepted : ");Serial.println(_clientList.count()-1); + #endif + } + + _currentClient = _clientList.removeLastRef();//We pick a client in the list to process it's request + +} + +void TCPServer::getClientData() +{ + if(_currentClient == NULL) + { + return; + } + + uint32_t bytesAvailable((_currentClient->client).available()); + + if(bytesAvailable) + { + if(_currentClient->dataSize < 255) + { + int freeSpace = (255-1/*for \0*/ - _currentClient->dataSize); + int amountToBeRead = bytesAvailable < freeSpace ? bytesAvailable : freeSpace;//;bytesAvailable < 254 ? bytesAvailable : 254; + + _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 + Serial.print("Client can be discarded : ");Serial.println(_currentClient->id); + #endif + _currentClient->clientState = TCPServerHelper::TCPServerClient::DISCARDED; + } + + + if(_currentClient->dataSize > 0) + { + processClientData(_currentClient);//We process the actual data + _currentClient->newDataAvailable = false; + } + + if(_currentClient->clientState == TCPServerHelper::TCPServerClient::DISCARDED) + { + _currentClient->client.stop(); + #ifdef DEBUG + Serial.print("Client was discarded : ");Serial.println(_currentClient->id); + #endif + delete _currentClient; + _currentClient = NULL; + return; + } + + _clientList.addFirst(_currentClient); + +} + +void TCPServer::processClientData(TCPServerHelper::TCPServerClient *client) +{ + Serial.print("Client --> ");Serial.print(client->id);Serial.print(" : ");Serial.println((char *)client->data); +} + +uint8_t TCPServer::getMaxClient() +{ + return _maxClient; +} + +uint8_t TCPServer::getClientsCount() +{ + return _clientList.count(); +} + +void TCPServer::startServer() +{ + _serverStarted = true; +} + +void TCPServer::stopServer() +{ + _serverStarted = false; + _clientList.dispose(); +} diff --git a/src/software_test/tcpServer_test/TCPServer.h b/src/software_test/tcpServer_test/TCPServer.h new file mode 100644 index 0000000..d0705ad --- /dev/null +++ b/src/software_test/tcpServer_test/TCPServer.h @@ -0,0 +1,86 @@ +#ifndef TCPSERVER_H +#define TCPSERVER_H +#include +#include +#include "List.h" +#include "Dictionary.h" + +#define MAX_CLIENT -1 + +namespace TCPServerHelper +{ + 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}; + + struct HttpRequestData + { + HttpRequestMethod HRM; + HttpVersion HV; + HttpMIMEType HMT; + Dictionary getParams; + Dictionary postParams; + char *httpResource; + char *httpBody; + }; + + struct TCPServerClient + { + WiFiClient client; + enum ClientState {NEW, HANDLED, QUERY_PARSED, RESPONSE_SENT, DISCARDED} clientState; + uint8_t data[255]; + uint16_t dataSize; + boolean newDataAvailable; + uint8_t id; + HttpRequestData httpRequestData; + HttpParserStatus httpParserState; + + bool operator==(TCPServerClient& Object){return this->client == Object.client;} + void clearHttpRequestData(TCPServerHelper::HttpRequestData *httpRequestData) + { + free(httpRequestData->httpResource);free(httpRequestData->httpBody); + httpRequestData->getParams.dispose(); + httpRequestData->postParams.dispose(); + } + ~TCPServerClient() + { + client.stop(); + clearHttpRequestData(&httpRequestData); + } + void freeDataBuffer(uint16_t size) + { + if(size > 254) size = 254; + + uint16_t secureSize = size > dataSize ? dataSize : size; + strcpy((char *)data, (char *)data + secureSize); + dataSize -= secureSize; + } + }; +} + +class TCPServer +{ + public: + TCPServer(unsigned int port = 80, uint8_t maxClient = MAX_CLIENT); + ~TCPServer(); + uint8_t getMaxClient(); + uint8_t getClientsCount(); + virtual void runServer(); + virtual void startServer(); + virtual void stopServer(); + protected: + private: + virtual void handleNewClients(); + virtual void getClientData(); + virtual void processClientData(TCPServerHelper::TCPServerClient *client); + + boolean _serverStarted; + uint8_t _maxClient; + unsigned int _port; + WiFiServer _wifiServer; + TCPServerHelper::TCPServerClient *_currentClient; //current client to be processed + List _clientList; +}; + +#endif //TCPSERVER_H diff --git a/src/software_test/tcpServer_test/TCPWebServer.cpp b/src/software_test/tcpServer_test/TCPWebServer.cpp new file mode 100644 index 0000000..50ce476 --- /dev/null +++ b/src/software_test/tcpServer_test/TCPWebServer.cpp @@ -0,0 +1,143 @@ +#include "TCPWebServer.h" +#define DEBUG + +TCPWebServer::TCPWebServer(unsigned int port, uint8_t maxClient) : TCPServer(port, maxClient) +{ + +} + +void debugInfo() +{ + uint32_t freeMem; + uint16_t biggestContigMemBlock; + uint8_t frag; + ESP.getHeapStats(&freeMem, &biggestContigMemBlock, &frag); + Serial.print("Free MEM : ");Serial.println(freeMem); + Serial.print("Heap Frag : ");Serial.println(frag); +} + +void TCPWebServer::processClientData(TCPServerHelper::TCPServerClient *client) +{ + if(client->newDataAvailable) + { + switch(client->httpParserState) + { + case TCPServerHelper::HTTP_VERB: + { + 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); + #ifdef DEBUG + Serial.print("Verb : ");Serial.println(client->httpRequestData.HRM); + #endif + client->httpParserState = TCPServerHelper::HttpParserStatus::HTTP_RESSOURCE; + } + } + break; + case TCPServerHelper::HTTP_RESSOURCE: + { + char *pRsrc = strstr((char *)client->data, " "); + + if(pRsrc != NULL) + { + *pRsrc = '\0'; + uint16_t length = pRsrc - (char *)client->data; + client->httpRequestData.httpResource = (char *) malloc(sizeof(char) * length + 1 ); //for \0 + if(client->httpRequestData.httpResource != NULL) + strcpy(client->httpRequestData.httpResource, (char *)client->data); + else + { + client->clientState = TCPServerHelper::TCPServerClient::ClientState::DISCARDED; + break; + } + + #ifdef DEBUG + Serial.print("Resrc : ");Serial.println(client->httpRequestData.httpResource); + #endif + client->freeDataBuffer(length + 1); + + client->httpParserState = TCPServerHelper::HttpParserStatus::HTTP_VERSION; + } + else if(client->dataSize == 254) + { + client->httpRequestData.httpResource = (char *) malloc(sizeof(char) * client->dataSize + 1 ); //for \0 + if(client->httpRequestData.httpResource != NULL) + strcpy(client->httpRequestData.httpResource, (char *)client->data); + else + { + client->clientState = TCPServerHelper::TCPServerClient::ClientState::DISCARDED; + break; + } + + #ifdef DEBUG + Serial.print("Resrc : ");Serial.println(client->httpRequestData.httpResource); + #endif + client->freeDataBuffer(client->dataSize); + client->httpParserState = TCPServerHelper::HttpParserStatus::HTTP_VERSION; + } + } + break; + case TCPServerHelper::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 + Serial.print("Vers : ");Serial.println(pVers+5); + Serial.print("Vers : ");Serial.println(client->httpRequestData.HV); + #endif + client->freeDataBuffer((pEndline - (char *)client->data)+2); + client->clientState = TCPServerHelper::TCPServerClient::ClientState::DISCARDED; + } + else //If we do not find it, it's probably split at the end of the buffer, so we ignore some of the resource left over + { + client->freeDataBuffer(100); + } + } + break; + /*case TCPServerHelper::HTTP_PARAMS: + break; + case TCPServerHelper::POST_DATA: + break; + default :*/ + } + /*Serial.print("WEB Client --> ");Serial.print(client->id);Serial.print(" : ");Serial.println((char *)client->data); + client->freeDataBuffer(client->dataSize);*/ + } + +} + +TCPServerHelper::HttpRequestMethod TCPWebServer::getHttpVerbEnumValue(const char *parseBuffer) +{ + //UNDEFINED, GET, HEAD, POST, PUT, DELETE, CONNECT, OPTIONS, TRACE, PATCH + if(strcmp(parseBuffer,"GET") == 0){return TCPServerHelper::HttpRequestMethod::GET;} + else if(strcmp(parseBuffer,"POST") == 0){return TCPServerHelper::HttpRequestMethod::POST;} + else if(strcmp(parseBuffer,"HEAD") == 0){return TCPServerHelper::HttpRequestMethod::HEAD;} + else if(strcmp(parseBuffer,"PUT") == 0){return TCPServerHelper::HttpRequestMethod::PUT;} + else if(strcmp(parseBuffer,"DELETE") == 0){return TCPServerHelper::HttpRequestMethod::DELETE;} + else if(strcmp(parseBuffer,"CONNECT") == 0){return TCPServerHelper::HttpRequestMethod::CONNECT;} + else if(strcmp(parseBuffer,"TRACE") == 0){return TCPServerHelper::HttpRequestMethod::TRACE;} + else if(strcmp(parseBuffer,"PATCH") == 0){return TCPServerHelper::HttpRequestMethod::PATCH;} + else if(strcmp(parseBuffer,"OPTIONS") == 0){return TCPServerHelper::HttpRequestMethod::OPTIONS;} + else + return TCPServerHelper::HttpRequestMethod::UNDEFINED; +} + +TCPServerHelper::HttpVersion TCPWebServer::getHttpVersionEnumValue(const char *parseBuffer) +{ + //HTTP_0_9, HTTP_1_1, HTTP_1_0, HTTP_2_0 + if(strcmp(parseBuffer,"1.1") == 0){return TCPServerHelper::HttpVersion::HTTP_1_1;} + else if(strcmp(parseBuffer,"2.0") == 0){return TCPServerHelper::HttpVersion::HTTP_2_0;} + else if(strcmp(parseBuffer,"1.0") == 0){return TCPServerHelper::HttpVersion::HTTP_1_0;} + else if(strcmp(parseBuffer,"0.9") == 0){return TCPServerHelper::HttpVersion::HTTP_0_9;} + else + return TCPServerHelper::HttpVersion::UNKNOWN; +} diff --git a/src/software_test/tcpServer_test/TCPWebServer.h b/src/software_test/tcpServer_test/TCPWebServer.h new file mode 100644 index 0000000..63826c6 --- /dev/null +++ b/src/software_test/tcpServer_test/TCPWebServer.h @@ -0,0 +1,17 @@ +#ifndef TCPWEBSERVER_H +#define TCPWEBSERVER_H + +#include "TCPServer.h" + +class TCPWebServer : public TCPServer +{ + public: + TCPWebServer(unsigned int port = 80, uint8_t maxClient = MAX_CLIENT); + protected: + private: + virtual void processClientData(TCPServerHelper::TCPServerClient *client); + TCPServerHelper::HttpRequestMethod getHttpVerbEnumValue(const char *parseBuffer); + TCPServerHelper::HttpVersion getHttpVersionEnumValue(const char *parseBuffer); +}; + +#endif //TCPWEBSERVER_H \ No newline at end of file diff --git a/src/software_test/tcpServer_test/tcpServer_test.ino b/src/software_test/tcpServer_test/tcpServer_test.ino new file mode 100644 index 0000000..31dda11 --- /dev/null +++ b/src/software_test/tcpServer_test/tcpServer_test.ino @@ -0,0 +1,36 @@ +/** + * This sketch was written in order to developp and test the multi client tcp server which will be used in my project + * Anatole SCHRAMM-HENRY 08/05/2019 + */ + +#include "TCPWebServer.h" + +WiFiEventHandler gotIpEventHandler, disconnectedEventHandler; +TCPWebServer tws(80,2); + +void setup() { + // put your setup code here, to run once: + Serial.begin(115200); + + gotIpEventHandler = WiFi.onStationModeGotIP(&(gotIp)); + disconnectedEventHandler = WiFi.onStationModeDisconnected(&(lostCon)); + + WiFi.persistent(false); + WiFi.begin("freebox_Henry","eustache1930"); +} + +void loop() { + // put your main code here, to run repeatedly: + tws.runServer(); +} + + +void gotIp(const WiFiEventStationModeGotIP& event) +{ + Serial.print("Got IP : ");Serial.println(WiFi.localIP()); +} + +void lostCon(const WiFiEventStationModeDisconnected& event) +{ + Serial.println("Lost connection"); +}