WiFi WebServer for ESP8266
Fork of ESP8266_WebServer by
Diff: ESP8266_WebServer.cpp
- Revision:
- 0:56c72c87d2f5
- Child:
- 1:1c4333ce7448
diff -r 000000000000 -r 56c72c87d2f5 ESP8266_WebServer.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ESP8266_WebServer.cpp Thu Jan 01 10:11:55 2015 +0000 @@ -0,0 +1,287 @@ +#include "ESP8266_WebServer.h" + +ESP8266_WebServer::ESP8266_WebServer(Serial *espUART) { + serial = espUART; + rxptr = buffer; + debugSerial = NULL; + reqMode = false; + reqLen = 0; +} + +void ESP8266_WebServer::rxint(void) { + char c = serial->getc(); + if( (c != 0x0A) && (c != 0x0D) && ((c < 0x20) || (c > 0x80)) ) return; + if( !reqMode && c == '+' ) { + if( echoMode ) { + debugSerial->putc('~'); + } + rxptrStored = rxptr; + rxptr = reqBuffer; + reqMode = true; + } + if( echoMode ) { + debugSerial->putc(c); + } + if( reqMode && reqLen == 0 && c == ':' ) { + if( echoMode ) { + debugSerial->putc('!'); + } + int numMatched = sscanf(reqBuffer,"+IPD,%*d,%d%n", &reqLen, &ipdLen); + if( numMatched < 1 ) { + reqMode = false; + reqLen = 0; + rxptr = rxptrStored; + return; + } + reqLen += ipdLen + 1; + } + if( echoMode ) { + debugSerial->putc('@'); + } + *rxptr = c; + rxptr++; + *rxptr = 0; + if( reqMode && reqLen > 0 ) { + if( echoMode ) { + debugSerial->putc('#'); + } + if( (int)(rxptr - reqBuffer) == reqLen ) { + // Process it + queueRequest(); + // Return to normal buffer mode + reqMode = false; + reqLen = 0; + rxptr = rxptrStored; + } + } +} + +void ESP8266_WebServer::debugBuffers(Serial* target) { + target->printf("\r\n\r\nRequest Buffer '%s'\r\nReqLen=%d,ReqMode=%d\r\n", reqBuffer, reqLen, reqMode); +} + +void ESP8266_WebServer::readBuffer(void) { + strncpy(reply, buffer, 1024); + while(reqMode == true ) { wait_ms(10); } + + rxptr = buffer; + *rxptr = 0; +} + +short ESP8266_WebServer::data_waiting(void) +{ + char* ok = strstr(buffer, "OK\r\n"); + char* error = strstr(buffer, "ERROR\r\n"); + char* nochange = strstr(buffer, "no change\r\n"); + + if( (ok != NULL) || (error != NULL ) || (nochange != NULL ) ) + { + return 1; + } + + return 0; +} + +short ESP8266_WebServer::string_waiting(const char* str) +{ + char* pr = strstr(buffer, str); + char* error = strstr(buffer, "ERROR\r\n"); + + if( (pr != NULL) || (error != NULL ) ) + { + return 1; + } + + return 0; +} + +void ESP8266_WebServer::Initialize(void) { + readBuffer(); + serial->printf("AT+RST\r\n"); + wait_ms(1000); + while( string_waiting("\r\nready\r\n") == 0 ) { + wait_ms(100); + } + readBuffer(); + serial->printf("ATE0\r\n"); + while( data_waiting() == 0 ) { + wait_ms(10); + } + readBuffer(); + + if( debugSerial != NULL ) { + debugSerial->printf("Done\r\nSetting operating mode..."); + } + serial->printf("AT+CWMODE=3\r\n"); + while( data_waiting() == 0 ) { + wait_ms(10); + } + readBuffer(); + + if( debugSerial != NULL ) { + debugSerial->printf("Done\r\nAccept Multiple connections..."); + } + serial->printf("AT+CIPMUX=1\r\n"); + while( data_waiting() == 0 ) { + wait_ms(10); + } + readBuffer(); + + if( debugSerial != NULL ) { + debugSerial->printf("Done\r\nStarting Web Server..."); + } + + serial->printf("AT+CIPSERVER=1,80\r\n"); + while( data_waiting() == 0 ) { + wait_ms(10); + } + readBuffer(); +} + +void ESP8266_WebServer::queueRequest(void) { + if( strstr(reqBuffer, "HTTP") != NULL ) { + ESP8266_WebRequest* request = new ESP8266_WebRequest(reqBuffer, debugSerial); + + incoming.push(request); + } +} + +ESP8266_WebRequest* ESP8266_WebServer::GetRequest(void) +{ + if( incoming.empty() == false ) { + ESP8266_WebRequest* temp = incoming.front(); + incoming.pop(); + temp->Read(); + + return temp; + } + + return NULL; +} + +void ESP8266_WebServer::sendResponse(int linkID, int numBytes) { + bool sent = false; + + readBuffer(); + if( debugSerial != NULL ) { + debugSerial->printf("HTTP Reply Packet(%d bytes)\r\n", numBytes); + } + while( sent == false ) { + while( reqMode == true ) { wait_ms(1); } + serial->printf("AT+CIPSEND=%d,%d\r\n", linkID, numBytes); + wait_ms(100); + if( (string_waiting(">") == 1) ) { + char* error = strstr(buffer, "ERROR\r\n"); + if( error != NULL ) { continue; } + for( int i=0; i<numBytes; i++ ) { + serial->putc(response[i]); + } + while( string_waiting("\r\nSEND OK\r\n") == 0 ) { + wait_ms(10); + } + error = strstr(buffer, "ERROR\r\n"); + if( error != NULL ) { continue; } + sent = true; + } + } + readBuffer(); +} + +void ESP8266_WebServer::SendError(int linkID, std::string error) { + SendError(linkID, error.c_str()); +} +void ESP8266_WebServer::SendError(int linkID, const char* error) { + sprintf(response, "HTTP/1.1 %s\r\nContent-Type: text/html\r\nContent-Length: %d\r\n\r\n%s", error, strlen(error), error); + sendResponse(linkID, strlen(response)); +} +void ESP8266_WebServer::Send404Error(int linkID) { + SendError(linkID, "404 Not Found"); +} + +void ESP8266_WebServer::SendReply(int linkID, std::string reply, const char* mimeType) { + SendReply(linkID, reply.c_str(), reply.length(), mimeType); +} + +void ESP8266_WebServer::SendReply(int linkID, const char* reply, int replySize, const char* mimeType) { + sprintf(response, "HTTP/1.1 200 OK\r\nContent-Type:%s\r\nContent-Length: %d\r\n\r\n", mimeType, replySize); + sendResponse(linkID, strlen(response)); + memcpy(response, reply, replySize); + sendResponse(linkID, replySize); +} + +ESP8266_WebRequest::ESP8266_WebRequest(const char* packet, Serial* debug) { + int sz = strlen(packet); + data = (char *)malloc(sz+1); + memcpy(data, packet, sz+1); + debugSerial = debug; +} + +void ESP8266_WebRequest::Read(void) { + int bytesRecv, ipdLen, linkID; + int numMatched = sscanf(data,"+IPD,%d,%d:%n", &linkID, &bytesRecv, &ipdLen); + if( numMatched != 2 ) { + if( debugSerial != NULL ) { + debugSerial->printf("IPD ERROR : Matched %d, LinkID=%d, BytesRecv=%d, IPD Header Len=%d\r\n", numMatched, linkID, bytesRecv, ipdLen); + } + return; + } + + if( debugSerial != NULL ) { + debugSerial->printf("IPD Data: LinkID=%d, BytesRecv=%d, IPD Header Len=%d\r\n", linkID, bytesRecv, ipdLen); + } + if( strstr(data, "HTTP") != NULL ) { + if( debugSerial != NULL ) { + debugSerial->printf("Got HTTP Request\r\n"); + } + char* httpPacket = data + ipdLen; + if( debugSerial != NULL ) { + debugSerial->printf("HTTP Packet: %s\r\n", httpPacket); + } + int numMatched = sscanf(httpPacket, "%s %s HTTP/%*c.%*c", httpMethod, httpURI); + if( numMatched != 2 ) { + if( debugSerial != NULL ) { + debugSerial->printf("HTTP ERROR : Matched %d, Method=%s, URI=%s\r\n", numMatched, httpMethod, httpURI); + } + return; + } + + LinkID = linkID; + Method = httpMethod; + URI = httpURI; + int pos = URI.find('?'); + if(pos != string::npos ) { + string params = URI.substr(pos+1); + URI = URI.substr(0,pos); + pos = params.find('='); + while( pos != string::npos ) { + string name = params.substr(0,pos); + string value = params.substr(pos+1); + pos = params.find('&'); + if( pos == string::npos ) + { + if( debugSerial != NULL ) { + debugSerial->printf("HTTP GET Parameter %s=%s\r\n", name.c_str(), value.c_str()); + } + Parameters[name] = value; + break; + } + + value = value.substr(0,value.find('&')); + params = params.substr(pos+1); + pos = params.find('='); + if( debugSerial != NULL ) { + debugSerial->printf("HTTP GET Parameter %s=%s\r\n", name.c_str(), value.c_str()); + } + Parameters[name] = value; + } + } + if( debugSerial != NULL ) { + debugSerial->printf("HTTP %s %s\r\n", httpMethod, httpURI); + } + } +} + +ESP8266_WebRequest::~ESP8266_WebRequest() +{ + free(data); +} \ No newline at end of file