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.

Fork of WebSwitch_mbed-os by Zoltan Hudak

Turn LED1, or other digital output, on/off using a web browser.

In this example we create a HTTP server that will serve a simple Web page to remotely turn LED1, or other digital output, on/off by using a web browser.

/media/uploads/hudakz/webswitch03.png/media/uploads/hudakz/webswitch_mobile01.jpg

Notice that DHCP is turned on by default. The IP address assigned to the WebSwitch server along with an instruction how to use it is printed to the connected PC's serial terminal window during program start up.
To use static IP address uncomment and adjust line #221 in main.cpp.

The project was inspired by the Tuxgraphics Web Switch. Thank you Guido!

For a Web Switch using

Committer:
hudakz
Date:
Thu Apr 06 18:58:40 2017 +0000
Revision:
0:e455fdb56bc8
Child:
2:33e8bb5615a6
Initial release.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
hudakz 0:e455fdb56bc8 1 #include "mbed.h"
hudakz 0:e455fdb56bc8 2 #include "EthernetInterface.h"
hudakz 0:e455fdb56bc8 3 #include "TCPServer.h"
hudakz 0:e455fdb56bc8 4 #include "TCPSocket.h"
hudakz 0:e455fdb56bc8 5 #include <stdio.h>
hudakz 0:e455fdb56bc8 6 #include <string>
hudakz 0:e455fdb56bc8 7
hudakz 0:e455fdb56bc8 8 using namespace std;
hudakz 0:e455fdb56bc8 9
hudakz 0:e455fdb56bc8 10 #define PORT 80
hudakz 0:e455fdb56bc8 11
hudakz 0:e455fdb56bc8 12 EthernetInterface ethernet;
hudakz 0:e455fdb56bc8 13 TCPServer server;
hudakz 0:e455fdb56bc8 14 TCPSocket clientSocket;
hudakz 0:e455fdb56bc8 15 SocketAddress clientAddress;
hudakz 0:e455fdb56bc8 16 char receiveBuf[1024] = { };
hudakz 0:e455fdb56bc8 17
hudakz 0:e455fdb56bc8 18 const int OFF = 0;
hudakz 0:e455fdb56bc8 19 const int ON = 1;
hudakz 0:e455fdb56bc8 20
hudakz 0:e455fdb56bc8 21 DigitalOut sw(LED1);
hudakz 0:e455fdb56bc8 22
hudakz 0:e455fdb56bc8 23 const string PASSWORD = "secret"; // change as you like
hudakz 0:e455fdb56bc8 24 const string HTTP_OK = "HTTP/1.0 200 OK";
hudakz 0:e455fdb56bc8 25 const string MOVED_PERM = "HTTP/1.0 301 Moved Permanently\r\nLocation: ";
hudakz 0:e455fdb56bc8 26 const string UNAUTHORIZED = "HTTP/1.0 401 Unauthorized";
hudakz 0:e455fdb56bc8 27 string httpHeader; // HTTP header
hudakz 0:e455fdb56bc8 28 string httpContent; // HTTP content
hudakz 0:e455fdb56bc8 29 // analyse the url given
hudakz 0:e455fdb56bc8 30 // return values: -1 invalid password
hudakz 0:e455fdb56bc8 31 // -2 no command given but password valid
hudakz 0:e455fdb56bc8 32 // -3 just refresh page
hudakz 0:e455fdb56bc8 33 // 0 switch off
hudakz 0:e455fdb56bc8 34 // 1 switch on
hudakz 0:e455fdb56bc8 35 //
hudakz 0:e455fdb56bc8 36 // The string passed to this function will look like this:
hudakz 0:e455fdb56bc8 37 // GET /password HTTP/1.....
hudakz 0:e455fdb56bc8 38 // GET /password/ HTTP/1.....
hudakz 0:e455fdb56bc8 39 // GET /password/?sw=1 HTTP/1.....
hudakz 0:e455fdb56bc8 40
hudakz 0:e455fdb56bc8 41 // GET /password/?sw=0 HTTP/1.....
hudakz 0:e455fdb56bc8 42 int8_t analyseURL(string& str) {
hudakz 0:e455fdb56bc8 43 if(str.substr(5, PASSWORD.size()) != PASSWORD)
hudakz 0:e455fdb56bc8 44 return(-1);
hudakz 0:e455fdb56bc8 45
hudakz 0:e455fdb56bc8 46 uint8_t pos = 5 + PASSWORD.size();
hudakz 0:e455fdb56bc8 47
hudakz 0:e455fdb56bc8 48 if(str.substr(pos, 1) == " ")
hudakz 0:e455fdb56bc8 49 return(-2);
hudakz 0:e455fdb56bc8 50
hudakz 0:e455fdb56bc8 51 if(str.substr(pos++, 1) != "/")
hudakz 0:e455fdb56bc8 52 return(-1);
hudakz 0:e455fdb56bc8 53
hudakz 0:e455fdb56bc8 54 string cmd(str.substr(pos, 5));
hudakz 0:e455fdb56bc8 55
hudakz 0:e455fdb56bc8 56 if(cmd == "?sw=0")
hudakz 0:e455fdb56bc8 57 return(OFF);
hudakz 0:e455fdb56bc8 58
hudakz 0:e455fdb56bc8 59 if(cmd == "?sw=1")
hudakz 0:e455fdb56bc8 60 return(ON);
hudakz 0:e455fdb56bc8 61
hudakz 0:e455fdb56bc8 62 return(-3);
hudakz 0:e455fdb56bc8 63 }
hudakz 0:e455fdb56bc8 64
hudakz 0:e455fdb56bc8 65 /**
hudakz 0:e455fdb56bc8 66 * @brief
hudakz 0:e455fdb56bc8 67 * @note
hudakz 0:e455fdb56bc8 68 * @param
hudakz 0:e455fdb56bc8 69 * @retval
hudakz 0:e455fdb56bc8 70 */
hudakz 0:e455fdb56bc8 71 string& movedPermanently(uint8_t flag) {
hudakz 0:e455fdb56bc8 72 if(flag == 1)
hudakz 0:e455fdb56bc8 73 httpContent = "/" + PASSWORD + "/";
hudakz 0:e455fdb56bc8 74 else
hudakz 0:e455fdb56bc8 75 httpContent = "";
hudakz 0:e455fdb56bc8 76
hudakz 0:e455fdb56bc8 77 httpContent += "<h1>301 Moved Permanently</h1>\r\n";
hudakz 0:e455fdb56bc8 78
hudakz 0:e455fdb56bc8 79 return(httpContent);
hudakz 0:e455fdb56bc8 80 }
hudakz 0:e455fdb56bc8 81
hudakz 0:e455fdb56bc8 82 /**
hudakz 0:e455fdb56bc8 83 * @brief
hudakz 0:e455fdb56bc8 84 * @note
hudakz 0:e455fdb56bc8 85 * @param
hudakz 0:e455fdb56bc8 86 * @retval
hudakz 0:e455fdb56bc8 87 */
hudakz 0:e455fdb56bc8 88 string& showWebPage(uint8_t status) {
hudakz 0:e455fdb56bc8 89 httpContent = "<h2>WebSwitch - Smart Home</h2>\r\n";
hudakz 0:e455fdb56bc8 90
hudakz 0:e455fdb56bc8 91 httpContent += "<pre>Temperature:\t21.8&deg;C\r\n</pre>";
hudakz 0:e455fdb56bc8 92
hudakz 0:e455fdb56bc8 93 if(status == ON) {
hudakz 0:e455fdb56bc8 94 httpContent += "<pre>\r\nHeating:\t<font color=#FF0000>ON </font>";
hudakz 0:e455fdb56bc8 95 httpContent += " <a href=\"./?sw=0\">[Turn off]</a>\r\n";
hudakz 0:e455fdb56bc8 96 }
hudakz 0:e455fdb56bc8 97 else {
hudakz 0:e455fdb56bc8 98 httpContent += "<pre>\r\nHeating:\t<font color=#BBBBBB>OFF</font>";
hudakz 0:e455fdb56bc8 99 httpContent += " <a href=\"./?sw=1\">[Turn on]</a>\r\n";
hudakz 0:e455fdb56bc8 100 }
hudakz 0:e455fdb56bc8 101
hudakz 0:e455fdb56bc8 102 //httpContent += " \r\n";
hudakz 0:e455fdb56bc8 103 //httpContent += " <a href=\".\">Refresh status]</a>\r\n";
hudakz 0:e455fdb56bc8 104 httpContent += "</pre>\r\n";
hudakz 0:e455fdb56bc8 105 httpContent += "<hr>\r\n";
hudakz 0:e455fdb56bc8 106 httpContent += "<pre>2017 ARMmbed Open Source</pre>";
hudakz 0:e455fdb56bc8 107 return httpContent;
hudakz 0:e455fdb56bc8 108 }
hudakz 0:e455fdb56bc8 109
hudakz 0:e455fdb56bc8 110 /**
hudakz 0:e455fdb56bc8 111 * @brief
hudakz 0:e455fdb56bc8 112 * @note
hudakz 0:e455fdb56bc8 113 * @param
hudakz 0:e455fdb56bc8 114 * @retval
hudakz 0:e455fdb56bc8 115 */
hudakz 0:e455fdb56bc8 116 void sendHTTP(TCPSocket& client, string& header, string& content) {
hudakz 0:e455fdb56bc8 117 char content_length[5] = { };
hudakz 0:e455fdb56bc8 118
hudakz 0:e455fdb56bc8 119 header += "\r\nContent-Type: text/html\r\n";
hudakz 0:e455fdb56bc8 120 header += "Content-Length: ";
hudakz 0:e455fdb56bc8 121 sprintf(content_length, "%d", content.length());
hudakz 0:e455fdb56bc8 122 header += string(content_length) + "\r\n";
hudakz 0:e455fdb56bc8 123 header += "Pragma: no-cache\r\n";
hudakz 0:e455fdb56bc8 124 header += "Connection: About to close\r\n";
hudakz 0:e455fdb56bc8 125 header += "\r\n";
hudakz 0:e455fdb56bc8 126
hudakz 0:e455fdb56bc8 127 string webpage = header + content;
hudakz 0:e455fdb56bc8 128 client.send((char*)webpage.c_str(), webpage.length());
hudakz 0:e455fdb56bc8 129 printf("HTTP sent.\n\r");
hudakz 0:e455fdb56bc8 130 }
hudakz 0:e455fdb56bc8 131
hudakz 0:e455fdb56bc8 132 /**
hudakz 0:e455fdb56bc8 133 * @brief
hudakz 0:e455fdb56bc8 134 * @note
hudakz 0:e455fdb56bc8 135 * @param
hudakz 0:e455fdb56bc8 136 * @retval
hudakz 0:e455fdb56bc8 137 */
hudakz 0:e455fdb56bc8 138 int main(void) {
hudakz 0:e455fdb56bc8 139
hudakz 0:e455fdb56bc8 140 ethernet.connect();
hudakz 0:e455fdb56bc8 141 printf("Usage: Type %s/%s/ into your web browser and hit ENTER\r\n", ethernet.get_ip_address(), PASSWORD);
hudakz 0:e455fdb56bc8 142
hudakz 0:e455fdb56bc8 143 /* Open the server on ethernet stack */
hudakz 0:e455fdb56bc8 144 server.open(&ethernet);
hudakz 0:e455fdb56bc8 145
hudakz 0:e455fdb56bc8 146 /* Bind the HTTP port (TCP 80) to the server */
hudakz 0:e455fdb56bc8 147 server.bind(ethernet.get_ip_address(), 80);
hudakz 0:e455fdb56bc8 148
hudakz 0:e455fdb56bc8 149 /* Can handle 5 simultaneous connections */
hudakz 0:e455fdb56bc8 150 server.listen(5);
hudakz 0:e455fdb56bc8 151
hudakz 0:e455fdb56bc8 152 //listening for http GET request
hudakz 0:e455fdb56bc8 153 while(true) {
hudakz 0:e455fdb56bc8 154 server.accept(&clientSocket, &clientAddress);
hudakz 0:e455fdb56bc8 155 printf("\r\n=========================================\r\n");
hudakz 0:e455fdb56bc8 156 printf("Connection succeeded!\n\rIP: %s\n\r", clientAddress.get_ip_address());
hudakz 0:e455fdb56bc8 157 clientSocket.recv(receiveBuf, 1023);
hudakz 0:e455fdb56bc8 158 printf("Recieved Data: %d\n\r\n\r%.*s\n\r", strlen(receiveBuf), strlen(receiveBuf), receiveBuf);
hudakz 0:e455fdb56bc8 159
hudakz 0:e455fdb56bc8 160 string received(receiveBuf);
hudakz 0:e455fdb56bc8 161 if(received.substr(0, 3) != "GET") {
hudakz 0:e455fdb56bc8 162 httpHeader = HTTP_OK;
hudakz 0:e455fdb56bc8 163 httpContent = "<h1>200 OK</h1>";
hudakz 0:e455fdb56bc8 164 sendHTTP(clientSocket, httpHeader, httpContent);
hudakz 0:e455fdb56bc8 165 continue;
hudakz 0:e455fdb56bc8 166 }
hudakz 0:e455fdb56bc8 167
hudakz 0:e455fdb56bc8 168 if(received.substr(0, 6) == "GET / ") {
hudakz 0:e455fdb56bc8 169 httpHeader = HTTP_OK;
hudakz 0:e455fdb56bc8 170 httpContent = "<p>Usage: Type http://ip_address/password/ into your web browser and hit ENTER</p>\r\n";
hudakz 0:e455fdb56bc8 171 sendHTTP(clientSocket, httpHeader, httpContent);
hudakz 0:e455fdb56bc8 172 continue;
hudakz 0:e455fdb56bc8 173 }
hudakz 0:e455fdb56bc8 174
hudakz 0:e455fdb56bc8 175 int cmd = analyseURL(received);
hudakz 0:e455fdb56bc8 176
hudakz 0:e455fdb56bc8 177 if(cmd == -2) {
hudakz 0:e455fdb56bc8 178
hudakz 0:e455fdb56bc8 179 // redirect to the right base url
hudakz 0:e455fdb56bc8 180 httpHeader = MOVED_PERM;
hudakz 0:e455fdb56bc8 181 sendHTTP(clientSocket, httpHeader, movedPermanently(1));
hudakz 0:e455fdb56bc8 182 continue;
hudakz 0:e455fdb56bc8 183 }
hudakz 0:e455fdb56bc8 184
hudakz 0:e455fdb56bc8 185 if(cmd == -1) {
hudakz 0:e455fdb56bc8 186 httpHeader = UNAUTHORIZED;
hudakz 0:e455fdb56bc8 187 httpContent = "<h1>401 Unauthorized</h1>";
hudakz 0:e455fdb56bc8 188 sendHTTP(clientSocket, httpHeader, httpContent);
hudakz 0:e455fdb56bc8 189 continue;
hudakz 0:e455fdb56bc8 190 }
hudakz 0:e455fdb56bc8 191
hudakz 0:e455fdb56bc8 192 if(cmd == ON) {
hudakz 0:e455fdb56bc8 193 sw = ON; // turn the switch on
hudakz 0:e455fdb56bc8 194 }
hudakz 0:e455fdb56bc8 195
hudakz 0:e455fdb56bc8 196 if(cmd == OFF) {
hudakz 0:e455fdb56bc8 197 sw = OFF; // turn the switch off
hudakz 0:e455fdb56bc8 198 }
hudakz 0:e455fdb56bc8 199
hudakz 0:e455fdb56bc8 200 httpHeader = HTTP_OK;
hudakz 0:e455fdb56bc8 201 sendHTTP(clientSocket, httpHeader, showWebPage(sw));
hudakz 0:e455fdb56bc8 202 }
hudakz 0:e455fdb56bc8 203 }