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:
Mon May 01 20:03:14 2017 +0000
Revision:
2:4a51bdd24745
Parent:
1:c024e74b3a75
Button added.

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