HTTP Server serving a simple webpage which enables to remotely turn LED1 on/off. Compile, download, run and type 'IP_address/secret/' (don't forget the last '/') into your web browser and hit ENTER.

Dependencies:   EthernetInterface mbed-rtos mbed-dev

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers main.cpp Source File

main.cpp

00001 #include "mbed.h"
00002 #include "EthernetInterface.h"
00003 #include <stdio.h>
00004 #include <string>
00005 
00006 using namespace     std;
00007 
00008 #define PORT        80
00009 
00010 EthernetInterface   ethernet;
00011 
00012 TCPSocketServer     server;
00013 bool                serverIsListening = false;
00014 
00015 TCPSocketConnection client;
00016 bool                clientIsConnected = false;
00017 
00018 const int           OFF = 0;
00019 const int           ON = 1;
00020 
00021 DigitalOut          sw(LED1);
00022 float               roomTemp = 21.8;    // A temperature sensor output
00023 
00024 const string        PASSWORD = "secret";    // change as you like
00025 const string        HTTP_OK = "HTTP/1.0 200 OK";
00026 const string        MOVED_PERM = "HTTP/1.0 301 Moved Permanently\r\nLocation: ";
00027 const string        UNAUTHORIZED = "HTTP/1.0 401 Unauthorized";
00028 string              httpHeader;     // HTTP header
00029 string              httpContent;    // HTTP content
00030 
00031 /**
00032  * @brief   Defines a custom MAC address
00033  * @note    Uncomment the code below to define a unique MAC address.
00034  *          Modify the mac array items as needed.
00035  * @param
00036  * @retval
00037  */
00038 //extern "C" void mbed_mac_address(char* mac) {
00039 //    mac[0] = 0x00;
00040 //    mac[1] = 0x01;
00041 //    mac[2] = 0x02;
00042 //    mac[3] = 0x03;
00043 //    mac[4] = 0x04;
00044 //    mac[5] = 0x05;
00045 //};
00046 
00047 /**
00048  * @brief   Analyses the received URL
00049  * @note    The string passed to this function will look like this:
00050  *          GET /password HTTP/1.....
00051  *          GET /password/ HTTP/1.....
00052  *          GET /password/?sw=1 HTTP/1.....
00053  *          GET /password/?sw=0 HTTP/1.....
00054  * @param   url URL string
00055  * @retval -1 invalid password
00056  *         -2 no command given but password valid
00057  *         -3 just refresh page
00058  *          0 switch off
00059  *          1 switch on
00060  */
00061 int8_t analyseURL(string& url) {
00062     if(url.substr(5, PASSWORD.size()) != PASSWORD)
00063         return(-1);
00064 
00065     uint8_t pos = 5 + PASSWORD.size();
00066 
00067     if(url.substr(pos, 1) == " ")
00068         return(-2);
00069 
00070     if(url.substr(pos++, 1) != "/")
00071         return(-1);
00072 
00073     string  cmd(url.substr(pos, 5));
00074 
00075     if(cmd == "?sw=0")
00076         return(OFF);
00077 
00078     if(cmd == "?sw=1")
00079         return(ON);
00080 
00081     return(-3);
00082 }
00083 
00084 /**
00085  * @brief
00086  * @note
00087  * @param
00088  * @retval
00089  */
00090 string& movedPermanently(uint8_t flag) {
00091     if(flag == 1)
00092         httpContent = "/" + PASSWORD + "/";
00093     else
00094         httpContent = "";
00095 
00096     httpContent += "<h1>301 Moved Permanently</h1>\r\n";
00097 
00098     return(httpContent);
00099 }
00100 
00101 /**
00102  * @brief
00103  * @note
00104  * @param
00105  * @retval
00106  */
00107 string& showWebPage(uint8_t status) {
00108     char roomTempStr[5];
00109 
00110     //roomTemp = ds1820.read();
00111     sprintf(roomTempStr, "%3.1f", roomTemp);
00112 
00113     httpContent = "<h2><a href=\".\" title=\"Click to refresh the page\">Smart Home</a></h2>"; 
00114     httpContent += "<pre>Temperature:\t" + string(roomTempStr) + "&deg;C\r\n</pre>";
00115 
00116     if(status == ON) {
00117         httpContent += "<pre>\r\nHeating:\t<font color=#FF0000>On </font>";
00118         httpContent += " <a href=\"./?sw=0\"><button>Turn off</button></a>\r\n";
00119     }
00120     else {
00121         httpContent += "<pre>\r\nHeating:\t<font color=#999999>Off</font>";
00122         httpContent += " <a href=\"./?sw=1\"><button>Turn on</button></a>\r\n";
00123     }
00124 
00125     httpContent += "</pre>\r\n";
00126     httpContent += "<hr>\r\n";
00127     httpContent += "<pre>2017 ARMmbed</pre>";
00128     return httpContent;
00129 }
00130 
00131 /**
00132  * @brief
00133  * @note
00134  * @param
00135  * @retval
00136  */
00137 void sendHTTP(TCPSocketConnection& client, string& header, string& content) {
00138     char    contentLength[5] = { };
00139 
00140     header += "\r\nContent-Type: text/html\r\n";
00141     header += "Content-Length: ";
00142     sprintf(contentLength, "%d", content.length());
00143     header += string(contentLength) + "\r\n";
00144     header += "Pragma: no-cache\r\n";
00145     header += "Connection: About to close\r\n";
00146     header += "\r\n";
00147 
00148     string  webpage = header + content;
00149     client.send((char*)webpage.c_str(), webpage.length());
00150     clientIsConnected = false;
00151     printf("HTTP sent.\n\r");
00152 }
00153 
00154 /**
00155  * @brief
00156  * @note
00157  * @param
00158  * @retval
00159  */
00160 int main(void) {
00161 
00162     //setup ethernet interface
00163     ethernet.init(); //Use DHCP
00164     //ethernet.init("192.168.1.181", "255.255.255.0", "192.168.1.1");   // Use static IP
00165     ethernet.connect();
00166     printf("USAGE: Type '%s/%s/' into your web browser and hit ENTER\r\n", ethernet.getIPAddress(), PASSWORD.c_str());
00167     printf("NOTE:  Don't forget to type the last '/'.\r\n\r\n");
00168 
00169     //setup tcp socket
00170     if(server.bind(PORT) < 0) {
00171         printf("HTTP server bind failed.\n\r");
00172         return -1;
00173     }
00174     else {
00175         printf("HTTP server bind succeeded.\n\r");
00176         serverIsListening = true;
00177     }
00178 
00179     if(server.listen(1) < 0) {
00180         printf("HTTP server listen failed.\n\r");
00181         return -1;
00182     }
00183     else {
00184         printf("HTTP server is listening...\n\r");
00185     }
00186 
00187     //listening for http GET request
00188     while(serverIsListening) {
00189 
00190         if(server.accept(client) < 0) {
00191             printf("Failed to accept connection.\n\r");
00192         }
00193         else {
00194             printf("\r\n=========================================\r\n");
00195             printf("Connection accepted!\n\rIP: %s\n\r", client.get_address());
00196             clientIsConnected = true;
00197 
00198             while(clientIsConnected) {
00199                 char    buffer[1024] = { };
00200                 switch(client.receive(buffer, 1023)) {
00201                 case 0:
00202                     printf("Recieved buffer is empty.\n\r");
00203                     clientIsConnected = false;
00204                     break;
00205 
00206                 case -1:
00207                     printf("Failed to read data from client.\n\r");
00208                     clientIsConnected = false;
00209                     break;
00210 
00211                 default:
00212                     printf("Recieved Data: %d\n\r\n\r%.*s\n\r", strlen(buffer), strlen(buffer), buffer);
00213 
00214                     string  received(buffer);
00215                     if(received.substr(0, 3) != "GET") {
00216                         httpHeader = HTTP_OK;
00217                         httpContent = "<h1>200 OK</h1>";
00218                         sendHTTP(client, httpHeader, httpContent);
00219                         continue;
00220                     }
00221 
00222                     if(received.substr(0, 6) == "GET / ") {
00223                         httpHeader = HTTP_OK;
00224                         httpContent = "<p>USAGE: Type 'http://ip_address/password/' into your web browser and hit ENTER</p>\r\n";
00225                         sendHTTP(client, httpHeader, httpContent);
00226                         continue;
00227                     }
00228 
00229                     int cmd = analyseURL(received);
00230 
00231                     if(cmd == -2) {
00232 
00233                         // redirect to the correct base URL
00234                         httpHeader = MOVED_PERM;
00235                         sendHTTP(client, httpHeader, movedPermanently(1));
00236                         continue;
00237                     }
00238 
00239                     if(cmd == -1) {
00240                         httpHeader = UNAUTHORIZED;
00241                         httpContent = "<h1>401 Unauthorized</h1>";
00242                         sendHTTP(client, httpHeader, httpContent);
00243                         continue;
00244                     }
00245 
00246                     if(cmd == ON) {
00247                         sw = ON;    // turn the switch on
00248                     }
00249 
00250                     if(cmd == OFF) {
00251                         sw = OFF;   // turn the switch off
00252                     }
00253 
00254                     httpHeader = HTTP_OK;
00255                     sendHTTP(client, httpHeader, showWebPage(sw));
00256                     break;
00257                 }
00258             }
00259 
00260             printf("Closing connection.\n\r");
00261             printf("HTTP server is listening...\n\r");
00262             client.close();
00263         }
00264     }
00265 }
00266