#ifndef TCPSERVER_H #define TCPSERVER_H #include #include "List.h" #include "TCPClient.h" #define MAX_CLIENT -1 //#define DEBUG_TCPS template 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 run() { handleNewClients(); getClientData(); } virtual void start() { if(!_serverStarted) { _wifiServer.begin(); _serverStarted = true; } } virtual void stop() { 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.printf("TCPServer : New client accepted. Id : %u , Number of clients : %u, local port : %u, remote port : %u\n",clientPointer->_id, _clientList.count(),clientPointer->_client.localPort(),clientPointer->_client.remotePort()); #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; } 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 _clientList; private: }; #endif //TCPSERVER_H