Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Revision 0:56c72c87d2f5, committed 2015-01-01
- Comitter:
- sschocke
- Date:
- Thu Jan 01 10:11:55 2015 +0000
- Child:
- 1:1c4333ce7448
- Commit message:
- Initial Commit
Changed in this revision
| ESP8266_WebServer.cpp | Show annotated file Show diff for this revision Revisions of this file |
| ESP8266_WebServer.h | Show annotated file Show diff for this revision Revisions of this file |
--- /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
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/ESP8266_WebServer.h Thu Jan 01 10:11:55 2015 +0000
@@ -0,0 +1,70 @@
+#include "mbed.h"
+#include <string>
+#include <map>
+#include <queue>
+#include <list>
+
+#ifndef _ESP8266_WEB_SERVER_H
+#define _ESP8266_WEB_SERVER_H
+
+const char mimeHTML[] = "text/html";
+const char mimeJavaScript[] = "text/javascript";
+const char mimeCSS[] = "text/css";
+const char mimeJPEG[] = "image/jpeg";
+const char mimePNG[] = "image/png";
+
+class ESP8266_WebRequest
+{
+ char httpMethod[64];
+ char httpURI[512];
+ char* data;
+ Serial *debugSerial;
+
+ public:
+ ESP8266_WebRequest(const char* packet, Serial* debug);
+ ~ESP8266_WebRequest();
+ int LinkID;
+ void Read(void);
+ std::string Method;
+ std::string URI;
+ std::map<std::string, std::string> Parameters;
+};
+
+class ESP8266_WebServer
+{
+ Serial *serial;
+ char buffer[1024];
+ char reply[1024];
+ char response[2048];
+ char reqBuffer[1024];
+ volatile char* rxptr;
+ volatile char* rxptrStored;
+ volatile bool reqMode;
+ volatile int ipdLen;
+ volatile int reqLen;
+ std::queue<ESP8266_WebRequest*, std::list<ESP8266_WebRequest*> > incoming;
+
+ private:
+ short data_waiting(void);
+ short string_waiting(const char*);
+ void readBuffer(void);
+ void sendResponse(int linkID, int numBytes);
+ void queueRequest(void);
+
+ public:
+ Serial *debugSerial;
+ bool echoMode;
+
+ ESP8266_WebServer(Serial *espUART);
+ void rxint(void);
+ void debugBuffers(Serial* target);
+ void Initialize(void);
+ ESP8266_WebRequest* GetRequest(void);
+ void SendError(int linkID, std::string error);
+ void SendError(int linkID, const char* error);
+ void Send404Error(int linkID);
+ void SendReply(int linkID, std::string reply, const char* mimeType);
+ void SendReply(int linkID, const char* reply, int replySize, const char* mimeType);
+};
+
+#endif
\ No newline at end of file