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

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/webswitch_desktop.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.

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

For a Web Switch using

Committer:
hudakz
Date:
Fri Apr 14 07:17:03 2017 +0000
Revision:
1:c024e74b3a75
Parent:
0:da3404d26549
Child:
2:4a51bdd24745
Updated.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
hudakz 0:da3404d26549 1 #include "mbed.h"
hudakz 0:da3404d26549 2 #include "EthernetInterface.h"
hudakz 0:da3404d26549 3 #include <stdio.h>
hudakz 0:da3404d26549 4 #include <string>
hudakz 0:da3404d26549 5
hudakz 0:da3404d26549 6 using namespace std;
hudakz 0:da3404d26549 7
hudakz 1:c024e74b3a75 8 #define PORT 80
hudakz 0:da3404d26549 9
hudakz 0:da3404d26549 10 EthernetInterface ethernet;
hudakz 0:da3404d26549 11
hudakz 0:da3404d26549 12 TCPSocketServer server;
hudakz 0:da3404d26549 13 bool serverIsListening = false;
hudakz 0:da3404d26549 14
hudakz 0:da3404d26549 15 TCPSocketConnection client;
hudakz 0:da3404d26549 16 bool clientIsConnected = false;
hudakz 0:da3404d26549 17
hudakz 0:da3404d26549 18 const int OFF = 0;
hudakz 0:da3404d26549 19 const int ON = 1;
hudakz 0:da3404d26549 20
hudakz 0:da3404d26549 21 DigitalOut sw(LED1);
hudakz 0:da3404d26549 22
hudakz 0:da3404d26549 23 const string PASSWORD = "secret"; // change as you like
hudakz 0:da3404d26549 24 const string HTTP_OK = "HTTP/1.0 200 OK";
hudakz 0:da3404d26549 25 const string MOVED_PERM = "HTTP/1.0 301 Moved Permanently\r\nLocation: ";
hudakz 0:da3404d26549 26 const string UNAUTHORIZED = "HTTP/1.0 401 Unauthorized";
hudakz 0:da3404d26549 27 string httpHeader; // HTTP header
hudakz 0:da3404d26549 28 string httpContent; // HTTP content
hudakz 0:da3404d26549 29 /**
hudakz 1:c024e74b3a75 30 * @brief Defines a custom MAC address
hudakz 1:c024e74b3a75 31 * @note Uncomment the code below to define a unique MAC address.
hudakz 1:c024e74b3a75 32 * Modify the mac array items as needed.
hudakz 0:da3404d26549 33 * @param
hudakz 0:da3404d26549 34 * @retval
hudakz 0:da3404d26549 35 */
hudakz 0:da3404d26549 36 //extern "C" void mbed_mac_address(char* mac) {
hudakz 0:da3404d26549 37 // mac[0] = 0x00;
hudakz 0:da3404d26549 38 // mac[1] = 0x01;
hudakz 0:da3404d26549 39 // mac[2] = 0x02;
hudakz 0:da3404d26549 40 // mac[3] = 0x03;
hudakz 0:da3404d26549 41 // mac[4] = 0x04;
hudakz 0:da3404d26549 42 // mac[5] = 0x05;
hudakz 0:da3404d26549 43 //};
hudakz 0:da3404d26549 44
hudakz 1:c024e74b3a75 45 /**
hudakz 1:c024e74b3a75 46 * @brief Analyses the received URL
hudakz 1:c024e74b3a75 47 * @note The string passed to this function will look like this:
hudakz 1:c024e74b3a75 48 * GET /password HTTP/1.....
hudakz 1:c024e74b3a75 49 * GET /password/ HTTP/1.....
hudakz 1:c024e74b3a75 50 * GET /password/?sw=1 HTTP/1.....
hudakz 1:c024e74b3a75 51 * GET /password/?sw=0 HTTP/1.....
hudakz 1:c024e74b3a75 52 * @param url URL string
hudakz 1:c024e74b3a75 53 * @retval -1 invalid password
hudakz 1:c024e74b3a75 54 * -2 no command given but password valid
hudakz 1:c024e74b3a75 55 * -3 just refresh page
hudakz 1:c024e74b3a75 56 * 0 switch off
hudakz 1:c024e74b3a75 57 * 1 switch on
hudakz 1:c024e74b3a75 58 */
hudakz 1:c024e74b3a75 59 int8_t analyseURL(string& url) {
hudakz 1:c024e74b3a75 60 if(url.substr(5, PASSWORD.size()) != PASSWORD)
hudakz 0:da3404d26549 61 return(-1);
hudakz 0:da3404d26549 62
hudakz 0:da3404d26549 63 uint8_t pos = 5 + PASSWORD.size();
hudakz 0:da3404d26549 64
hudakz 1:c024e74b3a75 65 if(url.substr(pos, 1) == " ")
hudakz 0:da3404d26549 66 return(-2);
hudakz 0:da3404d26549 67
hudakz 1:c024e74b3a75 68 if(url.substr(pos++, 1) != "/")
hudakz 0:da3404d26549 69 return(-1);
hudakz 0:da3404d26549 70
hudakz 1:c024e74b3a75 71 string cmd(url.substr(pos, 5));
hudakz 0:da3404d26549 72
hudakz 0:da3404d26549 73 if(cmd == "?sw=0")
hudakz 0:da3404d26549 74 return(OFF);
hudakz 0:da3404d26549 75
hudakz 0:da3404d26549 76 if(cmd == "?sw=1")
hudakz 0:da3404d26549 77 return(ON);
hudakz 0:da3404d26549 78
hudakz 0:da3404d26549 79 return(-3);
hudakz 0:da3404d26549 80 }
hudakz 0:da3404d26549 81
hudakz 0:da3404d26549 82 /**
hudakz 0:da3404d26549 83 * @brief
hudakz 0:da3404d26549 84 * @note
hudakz 0:da3404d26549 85 * @param
hudakz 0:da3404d26549 86 * @retval
hudakz 0:da3404d26549 87 */
hudakz 0:da3404d26549 88 string& movedPermanently(uint8_t flag) {
hudakz 0:da3404d26549 89 if(flag == 1)
hudakz 0:da3404d26549 90 httpContent = "/" + PASSWORD + "/";
hudakz 0:da3404d26549 91 else
hudakz 0:da3404d26549 92 httpContent = "";
hudakz 0:da3404d26549 93
hudakz 0:da3404d26549 94 httpContent += "<h1>301 Moved Permanently</h1>\r\n";
hudakz 0:da3404d26549 95
hudakz 0:da3404d26549 96 return(httpContent);
hudakz 0:da3404d26549 97 }
hudakz 0:da3404d26549 98
hudakz 0:da3404d26549 99 /**
hudakz 0:da3404d26549 100 * @brief
hudakz 0:da3404d26549 101 * @note
hudakz 0:da3404d26549 102 * @param
hudakz 0:da3404d26549 103 * @retval
hudakz 0:da3404d26549 104 */
hudakz 0:da3404d26549 105 string& showWebPage(uint8_t status) {
hudakz 0:da3404d26549 106 httpContent = "<h2>WebSwitch - Smart Home</h2>\r\n";
hudakz 0:da3404d26549 107
hudakz 0:da3404d26549 108 httpContent += "<pre>Temperature:\t21.8&deg;C\r\n</pre>";
hudakz 0:da3404d26549 109
hudakz 0:da3404d26549 110 if(status == ON) {
hudakz 0:da3404d26549 111 httpContent += "<pre>\r\nHeating:\t<font color=#FF0000>ON </font>";
hudakz 0:da3404d26549 112 httpContent += " <a href=\"./?sw=0\">[Turn off]</a>\r\n";
hudakz 0:da3404d26549 113 }
hudakz 0:da3404d26549 114 else {
hudakz 0:da3404d26549 115 httpContent += "<pre>\r\nHeating:\t<font color=#BBBBBB>OFF</font>";
hudakz 0:da3404d26549 116 httpContent += " <a href=\"./?sw=1\">[Turn on]</a>\r\n";
hudakz 0:da3404d26549 117 }
hudakz 0:da3404d26549 118
hudakz 0:da3404d26549 119 // httpContent += " \r\n";
hudakz 0:da3404d26549 120 // httpContent += " <a href=\".\">Refresh status]</a>\r\n";
hudakz 0:da3404d26549 121 httpContent += "</pre>\r\n";
hudakz 0:da3404d26549 122 httpContent += "<hr>\r\n";
hudakz 0:da3404d26549 123 httpContent += "<pre>2017 ARMmbed Open Source</pre>";
hudakz 0:da3404d26549 124 return httpContent;
hudakz 0:da3404d26549 125 }
hudakz 0:da3404d26549 126
hudakz 0:da3404d26549 127 /**
hudakz 0:da3404d26549 128 * @brief
hudakz 0:da3404d26549 129 * @note
hudakz 0:da3404d26549 130 * @param
hudakz 0:da3404d26549 131 * @retval
hudakz 0:da3404d26549 132 */
hudakz 0:da3404d26549 133 void sendHTTP(TCPSocketConnection& client, string& header, string& content) {
hudakz 1:c024e74b3a75 134 char contentLength[5] = { };
hudakz 0:da3404d26549 135
hudakz 0:da3404d26549 136 header += "\r\nContent-Type: text/html\r\n";
hudakz 0:da3404d26549 137 header += "Content-Length: ";
hudakz 1:c024e74b3a75 138 sprintf(contentLength, "%d", content.length());
hudakz 1:c024e74b3a75 139 header += string(contentLength) + "\r\n";
hudakz 0:da3404d26549 140 header += "Pragma: no-cache\r\n";
hudakz 0:da3404d26549 141 header += "Connection: About to close\r\n";
hudakz 0:da3404d26549 142 header += "\r\n";
hudakz 0:da3404d26549 143
hudakz 0:da3404d26549 144 string webpage = header + content;
hudakz 0:da3404d26549 145 client.send((char*)webpage.c_str(), webpage.length());
hudakz 0:da3404d26549 146 clientIsConnected = false;
hudakz 0:da3404d26549 147 printf("HTTP sent.\n\r");
hudakz 0:da3404d26549 148 }
hudakz 0:da3404d26549 149
hudakz 0:da3404d26549 150 /**
hudakz 0:da3404d26549 151 * @brief
hudakz 0:da3404d26549 152 * @note
hudakz 0:da3404d26549 153 * @param
hudakz 0:da3404d26549 154 * @retval
hudakz 0:da3404d26549 155 */
hudakz 0:da3404d26549 156 int main(void) {
hudakz 0:da3404d26549 157
hudakz 0:da3404d26549 158 //setup ethernet interface
hudakz 0:da3404d26549 159 ethernet.init(); //Use DHCP
hudakz 1:c024e74b3a75 160 //ethernet.init("192.168.1.36", "255.255.255.0", "192.168.1.1"); // Use static IP
hudakz 0:da3404d26549 161 ethernet.connect();
hudakz 1:c024e74b3a75 162 printf("USAGE: Type '%s/%s/' into your web browser and hit ENTER\r\n", ethernet.getIPAddress(), PASSWORD.c_str());
hudakz 1:c024e74b3a75 163 printf("NOTE: Don't forget to type the last '/'.\r\n\r\n");
hudakz 0:da3404d26549 164
hudakz 0:da3404d26549 165 //setup tcp socket
hudakz 0:da3404d26549 166 if(server.bind(PORT) < 0) {
hudakz 0:da3404d26549 167 printf("HTTP server bind failed.\n\r");
hudakz 0:da3404d26549 168 return -1;
hudakz 0:da3404d26549 169 }
hudakz 0:da3404d26549 170 else {
hudakz 1:c024e74b3a75 171 printf("HTTP server bind succeeded.\n\r");
hudakz 0:da3404d26549 172 serverIsListening = true;
hudakz 0:da3404d26549 173 }
hudakz 0:da3404d26549 174
hudakz 0:da3404d26549 175 if(server.listen(1) < 0) {
hudakz 0:da3404d26549 176 printf("HTTP server listen failed.\n\r");
hudakz 0:da3404d26549 177 return -1;
hudakz 0:da3404d26549 178 }
hudakz 0:da3404d26549 179 else {
hudakz 0:da3404d26549 180 printf("HTTP server is listening...\n\r");
hudakz 0:da3404d26549 181 }
hudakz 0:da3404d26549 182
hudakz 0:da3404d26549 183 //listening for http GET request
hudakz 0:da3404d26549 184 while(serverIsListening) {
hudakz 0:da3404d26549 185
hudakz 0:da3404d26549 186 if(server.accept(client) < 0) {
hudakz 0:da3404d26549 187 printf("Failed to accept connection.\n\r");
hudakz 0:da3404d26549 188 }
hudakz 0:da3404d26549 189 else {
hudakz 0:da3404d26549 190 printf("\r\n=========================================\r\n");
hudakz 1:c024e74b3a75 191 printf("Connection accepted!\n\rIP: %s\n\r", client.get_address());
hudakz 0:da3404d26549 192 clientIsConnected = true;
hudakz 0:da3404d26549 193
hudakz 0:da3404d26549 194 while(clientIsConnected) {
hudakz 0:da3404d26549 195 char buffer[1024] = { };
hudakz 0:da3404d26549 196 switch(client.receive(buffer, 1023)) {
hudakz 0:da3404d26549 197 case 0:
hudakz 0:da3404d26549 198 printf("Recieved buffer is empty.\n\r");
hudakz 0:da3404d26549 199 clientIsConnected = false;
hudakz 0:da3404d26549 200 break;
hudakz 0:da3404d26549 201
hudakz 0:da3404d26549 202 case -1:
hudakz 0:da3404d26549 203 printf("Failed to read data from client.\n\r");
hudakz 0:da3404d26549 204 clientIsConnected = false;
hudakz 0:da3404d26549 205 break;
hudakz 0:da3404d26549 206
hudakz 0:da3404d26549 207 default:
hudakz 0:da3404d26549 208 printf("Recieved Data: %d\n\r\n\r%.*s\n\r", strlen(buffer), strlen(buffer), buffer);
hudakz 0:da3404d26549 209
hudakz 0:da3404d26549 210 string received(buffer);
hudakz 0:da3404d26549 211 if(received.substr(0, 3) != "GET") {
hudakz 0:da3404d26549 212 httpHeader = HTTP_OK;
hudakz 0:da3404d26549 213 httpContent = "<h1>200 OK</h1>";
hudakz 0:da3404d26549 214 sendHTTP(client, httpHeader, httpContent);
hudakz 0:da3404d26549 215 continue;
hudakz 0:da3404d26549 216 }
hudakz 0:da3404d26549 217
hudakz 0:da3404d26549 218 if(received.substr(0, 6) == "GET / ") {
hudakz 0:da3404d26549 219 httpHeader = HTTP_OK;
hudakz 1:c024e74b3a75 220 httpContent = "<p>USAGE: Type 'http://ip_address/password/' into your web browser and hit ENTER</p>\r\n";
hudakz 0:da3404d26549 221 sendHTTP(client, httpHeader, httpContent);
hudakz 0:da3404d26549 222 continue;
hudakz 0:da3404d26549 223 }
hudakz 0:da3404d26549 224
hudakz 0:da3404d26549 225 int cmd = analyseURL(received);
hudakz 0:da3404d26549 226
hudakz 0:da3404d26549 227 if(cmd == -2) {
hudakz 0:da3404d26549 228
hudakz 1:c024e74b3a75 229 // redirect to the correct base URL
hudakz 0:da3404d26549 230 httpHeader = MOVED_PERM;
hudakz 0:da3404d26549 231 sendHTTP(client, httpHeader, movedPermanently(1));
hudakz 0:da3404d26549 232 continue;
hudakz 0:da3404d26549 233 }
hudakz 0:da3404d26549 234
hudakz 0:da3404d26549 235 if(cmd == -1) {
hudakz 0:da3404d26549 236 httpHeader = UNAUTHORIZED;
hudakz 0:da3404d26549 237 httpContent = "<h1>401 Unauthorized</h1>";
hudakz 0:da3404d26549 238 sendHTTP(client, httpHeader, httpContent);
hudakz 0:da3404d26549 239 continue;
hudakz 0:da3404d26549 240 }
hudakz 0:da3404d26549 241
hudakz 0:da3404d26549 242 if(cmd == ON) {
hudakz 0:da3404d26549 243 sw = ON; // turn the switch on
hudakz 0:da3404d26549 244 }
hudakz 0:da3404d26549 245
hudakz 0:da3404d26549 246 if(cmd == OFF) {
hudakz 0:da3404d26549 247 sw = OFF; // turn the switch off
hudakz 0:da3404d26549 248 }
hudakz 0:da3404d26549 249
hudakz 0:da3404d26549 250 httpHeader = HTTP_OK;
hudakz 0:da3404d26549 251 sendHTTP(client, httpHeader, showWebPage(sw));
hudakz 0:da3404d26549 252 break;
hudakz 0:da3404d26549 253 }
hudakz 0:da3404d26549 254 }
hudakz 0:da3404d26549 255
hudakz 1:c024e74b3a75 256 printf("Closing connection.\n\r");
hudakz 1:c024e74b3a75 257 printf("HTTP server is listening...\n\r");
hudakz 0:da3404d26549 258 client.close();
hudakz 0:da3404d26549 259 }
hudakz 0:da3404d26549 260 }
hudakz 0:da3404d26549 261 }