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:
Sat May 06 06:21:17 2017 +0000
Revision:
2:33e8bb5615a6
Parent:
0:e455fdb56bc8
Child:
3:c927a415dd38
Initial issue.

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 2:33e8bb5615a6 22 float roomTemp = 21.8; // A temperature sensor output
hudakz 0:e455fdb56bc8 23
hudakz 0:e455fdb56bc8 24 const string PASSWORD = "secret"; // change as you like
hudakz 0:e455fdb56bc8 25 const string HTTP_OK = "HTTP/1.0 200 OK";
hudakz 0:e455fdb56bc8 26 const string MOVED_PERM = "HTTP/1.0 301 Moved Permanently\r\nLocation: ";
hudakz 0:e455fdb56bc8 27 const string UNAUTHORIZED = "HTTP/1.0 401 Unauthorized";
hudakz 0:e455fdb56bc8 28 string httpHeader; // HTTP header
hudakz 0:e455fdb56bc8 29 string httpContent; // HTTP content
hudakz 2:33e8bb5615a6 30
hudakz 2:33e8bb5615a6 31 /**
hudakz 2:33e8bb5615a6 32 * @brief Defines a custom MAC address
hudakz 2:33e8bb5615a6 33 * @note Uncomment the code below to define a unique MAC address.
hudakz 2:33e8bb5615a6 34 * Modify the mac array items as needed.
hudakz 2:33e8bb5615a6 35 * @param
hudakz 2:33e8bb5615a6 36 * @retval
hudakz 2:33e8bb5615a6 37 */
hudakz 2:33e8bb5615a6 38 //extern "C" void mbed_mac_address(char* mac) {
hudakz 2:33e8bb5615a6 39 // mac[0] = 0x00;
hudakz 2:33e8bb5615a6 40 // mac[1] = 0x01;
hudakz 2:33e8bb5615a6 41 // mac[2] = 0x02;
hudakz 2:33e8bb5615a6 42 // mac[3] = 0x03;
hudakz 2:33e8bb5615a6 43 // mac[4] = 0x04;
hudakz 2:33e8bb5615a6 44 // mac[5] = 0x05;
hudakz 2:33e8bb5615a6 45 //};
hudakz 0:e455fdb56bc8 46
hudakz 2:33e8bb5615a6 47 /**
hudakz 2:33e8bb5615a6 48 * @brief Analyses the received URL
hudakz 2:33e8bb5615a6 49 * @note The string passed to this function will look like this:
hudakz 2:33e8bb5615a6 50 * GET /password HTTP/1.....
hudakz 2:33e8bb5615a6 51 * GET /password/ HTTP/1.....
hudakz 2:33e8bb5615a6 52 * GET /password/?sw=1 HTTP/1.....
hudakz 2:33e8bb5615a6 53 * GET /password/?sw=0 HTTP/1.....
hudakz 2:33e8bb5615a6 54 * @param url URL string
hudakz 2:33e8bb5615a6 55 * @retval -1 invalid password
hudakz 2:33e8bb5615a6 56 * -2 no command given but password valid
hudakz 2:33e8bb5615a6 57 * -3 just refresh page
hudakz 2:33e8bb5615a6 58 * 0 switch off
hudakz 2:33e8bb5615a6 59 * 1 switch on
hudakz 2:33e8bb5615a6 60 */
hudakz 2:33e8bb5615a6 61 int8_t analyseURL(string& url) {
hudakz 2:33e8bb5615a6 62 if(url.substr(5, PASSWORD.size()) != PASSWORD)
hudakz 0:e455fdb56bc8 63 return(-1);
hudakz 0:e455fdb56bc8 64
hudakz 0:e455fdb56bc8 65 uint8_t pos = 5 + PASSWORD.size();
hudakz 0:e455fdb56bc8 66
hudakz 2:33e8bb5615a6 67 if(url.substr(pos, 1) == " ")
hudakz 0:e455fdb56bc8 68 return(-2);
hudakz 0:e455fdb56bc8 69
hudakz 2:33e8bb5615a6 70 if(url.substr(pos++, 1) != "/")
hudakz 0:e455fdb56bc8 71 return(-1);
hudakz 0:e455fdb56bc8 72
hudakz 2:33e8bb5615a6 73 string cmd(url.substr(pos, 5));
hudakz 0:e455fdb56bc8 74
hudakz 0:e455fdb56bc8 75 if(cmd == "?sw=0")
hudakz 2:33e8bb5615a6 76 return(0);
hudakz 0:e455fdb56bc8 77
hudakz 0:e455fdb56bc8 78 if(cmd == "?sw=1")
hudakz 2:33e8bb5615a6 79 return(1);
hudakz 0:e455fdb56bc8 80
hudakz 0:e455fdb56bc8 81 return(-3);
hudakz 0:e455fdb56bc8 82 }
hudakz 0:e455fdb56bc8 83
hudakz 0:e455fdb56bc8 84 /**
hudakz 0:e455fdb56bc8 85 * @brief
hudakz 0:e455fdb56bc8 86 * @note
hudakz 0:e455fdb56bc8 87 * @param
hudakz 0:e455fdb56bc8 88 * @retval
hudakz 0:e455fdb56bc8 89 */
hudakz 0:e455fdb56bc8 90 string& movedPermanently(uint8_t flag) {
hudakz 0:e455fdb56bc8 91 if(flag == 1)
hudakz 0:e455fdb56bc8 92 httpContent = "/" + PASSWORD + "/";
hudakz 0:e455fdb56bc8 93 else
hudakz 0:e455fdb56bc8 94 httpContent = "";
hudakz 0:e455fdb56bc8 95
hudakz 0:e455fdb56bc8 96 httpContent += "<h1>301 Moved Permanently</h1>\r\n";
hudakz 0:e455fdb56bc8 97
hudakz 0:e455fdb56bc8 98 return(httpContent);
hudakz 0:e455fdb56bc8 99 }
hudakz 0:e455fdb56bc8 100
hudakz 0:e455fdb56bc8 101 /**
hudakz 0:e455fdb56bc8 102 * @brief
hudakz 0:e455fdb56bc8 103 * @note
hudakz 0:e455fdb56bc8 104 * @param
hudakz 0:e455fdb56bc8 105 * @retval
hudakz 0:e455fdb56bc8 106 */
hudakz 0:e455fdb56bc8 107 string& showWebPage(uint8_t status) {
hudakz 2:33e8bb5615a6 108 char roomTempStr[5];
hudakz 0:e455fdb56bc8 109
hudakz 2:33e8bb5615a6 110 //roomTemp = ds1820.read();
hudakz 2:33e8bb5615a6 111 sprintf(roomTempStr, "%3.1f", roomTemp);
hudakz 2:33e8bb5615a6 112
hudakz 2:33e8bb5615a6 113 httpContent = "<h2><a href=\".\" title=\"Click to refresh the page\">Smart Home</a></h2>";
hudakz 2:33e8bb5615a6 114 httpContent += "<pre>Temperature:\t" + string(roomTempStr) + "&deg;C\r\n</pre>";
hudakz 0:e455fdb56bc8 115
hudakz 0:e455fdb56bc8 116 if(status == ON) {
hudakz 2:33e8bb5615a6 117 httpContent += "<pre>\r\nHeating:\t<font color=#FF0000>On </font>";
hudakz 2:33e8bb5615a6 118 httpContent += " <a href=\"./?sw=0\"><button>Turn off</button></a>\r\n";
hudakz 0:e455fdb56bc8 119 }
hudakz 0:e455fdb56bc8 120 else {
hudakz 2:33e8bb5615a6 121 httpContent += "<pre>\r\nHeating:\t<font color=#999999>Off</font>";
hudakz 2:33e8bb5615a6 122 httpContent += " <a href=\"./?sw=1\"><button>Turn on</button></a>\r\n";
hudakz 0:e455fdb56bc8 123 }
hudakz 0:e455fdb56bc8 124
hudakz 0:e455fdb56bc8 125 httpContent += "</pre>\r\n";
hudakz 0:e455fdb56bc8 126 httpContent += "<hr>\r\n";
hudakz 2:33e8bb5615a6 127 httpContent += "<pre>2017 ARMmbed</pre>";
hudakz 0:e455fdb56bc8 128 return httpContent;
hudakz 0:e455fdb56bc8 129 }
hudakz 0:e455fdb56bc8 130
hudakz 0:e455fdb56bc8 131 /**
hudakz 0:e455fdb56bc8 132 * @brief
hudakz 0:e455fdb56bc8 133 * @note
hudakz 0:e455fdb56bc8 134 * @param
hudakz 0:e455fdb56bc8 135 * @retval
hudakz 0:e455fdb56bc8 136 */
hudakz 0:e455fdb56bc8 137 void sendHTTP(TCPSocket& client, string& header, string& content) {
hudakz 0:e455fdb56bc8 138 char content_length[5] = { };
hudakz 0:e455fdb56bc8 139
hudakz 0:e455fdb56bc8 140 header += "\r\nContent-Type: text/html\r\n";
hudakz 0:e455fdb56bc8 141 header += "Content-Length: ";
hudakz 0:e455fdb56bc8 142 sprintf(content_length, "%d", content.length());
hudakz 0:e455fdb56bc8 143 header += string(content_length) + "\r\n";
hudakz 0:e455fdb56bc8 144 header += "Pragma: no-cache\r\n";
hudakz 0:e455fdb56bc8 145 header += "Connection: About to close\r\n";
hudakz 0:e455fdb56bc8 146 header += "\r\n";
hudakz 0:e455fdb56bc8 147
hudakz 0:e455fdb56bc8 148 string webpage = header + content;
hudakz 0:e455fdb56bc8 149 client.send((char*)webpage.c_str(), webpage.length());
hudakz 0:e455fdb56bc8 150 printf("HTTP sent.\n\r");
hudakz 0:e455fdb56bc8 151 }
hudakz 0:e455fdb56bc8 152
hudakz 0:e455fdb56bc8 153 /**
hudakz 0:e455fdb56bc8 154 * @brief
hudakz 0:e455fdb56bc8 155 * @note
hudakz 0:e455fdb56bc8 156 * @param
hudakz 0:e455fdb56bc8 157 * @retval
hudakz 0:e455fdb56bc8 158 */
hudakz 0:e455fdb56bc8 159 int main(void) {
hudakz 0:e455fdb56bc8 160
hudakz 0:e455fdb56bc8 161 ethernet.connect();
hudakz 0:e455fdb56bc8 162 printf("Usage: Type %s/%s/ into your web browser and hit ENTER\r\n", ethernet.get_ip_address(), PASSWORD);
hudakz 0:e455fdb56bc8 163
hudakz 0:e455fdb56bc8 164 /* Open the server on ethernet stack */
hudakz 0:e455fdb56bc8 165 server.open(&ethernet);
hudakz 0:e455fdb56bc8 166
hudakz 0:e455fdb56bc8 167 /* Bind the HTTP port (TCP 80) to the server */
hudakz 0:e455fdb56bc8 168 server.bind(ethernet.get_ip_address(), 80);
hudakz 0:e455fdb56bc8 169
hudakz 0:e455fdb56bc8 170 /* Can handle 5 simultaneous connections */
hudakz 0:e455fdb56bc8 171 server.listen(5);
hudakz 0:e455fdb56bc8 172
hudakz 0:e455fdb56bc8 173 //listening for http GET request
hudakz 0:e455fdb56bc8 174 while(true) {
hudakz 2:33e8bb5615a6 175 printf("\r\n=========================================\r\n");
hudakz 2:33e8bb5615a6 176 printf("Ready to serve clients.\r\n");
hudakz 0:e455fdb56bc8 177 server.accept(&clientSocket, &clientAddress);
hudakz 0:e455fdb56bc8 178 printf("Connection succeeded!\n\rIP: %s\n\r", clientAddress.get_ip_address());
hudakz 0:e455fdb56bc8 179 clientSocket.recv(receiveBuf, 1023);
hudakz 0:e455fdb56bc8 180 printf("Recieved Data: %d\n\r\n\r%.*s\n\r", strlen(receiveBuf), strlen(receiveBuf), receiveBuf);
hudakz 0:e455fdb56bc8 181
hudakz 0:e455fdb56bc8 182 string received(receiveBuf);
hudakz 2:33e8bb5615a6 183
hudakz 0:e455fdb56bc8 184 if(received.substr(0, 3) != "GET") {
hudakz 0:e455fdb56bc8 185 httpHeader = HTTP_OK;
hudakz 0:e455fdb56bc8 186 httpContent = "<h1>200 OK</h1>";
hudakz 0:e455fdb56bc8 187 sendHTTP(clientSocket, httpHeader, httpContent);
hudakz 0:e455fdb56bc8 188 continue;
hudakz 0:e455fdb56bc8 189 }
hudakz 0:e455fdb56bc8 190
hudakz 0:e455fdb56bc8 191 if(received.substr(0, 6) == "GET / ") {
hudakz 0:e455fdb56bc8 192 httpHeader = HTTP_OK;
hudakz 0:e455fdb56bc8 193 httpContent = "<p>Usage: Type http://ip_address/password/ into your web browser and hit ENTER</p>\r\n";
hudakz 0:e455fdb56bc8 194 sendHTTP(clientSocket, httpHeader, httpContent);
hudakz 0:e455fdb56bc8 195 continue;
hudakz 0:e455fdb56bc8 196 }
hudakz 0:e455fdb56bc8 197
hudakz 0:e455fdb56bc8 198 int cmd = analyseURL(received);
hudakz 0:e455fdb56bc8 199
hudakz 0:e455fdb56bc8 200 if(cmd == -2) {
hudakz 0:e455fdb56bc8 201
hudakz 0:e455fdb56bc8 202 // redirect to the right base url
hudakz 0:e455fdb56bc8 203 httpHeader = MOVED_PERM;
hudakz 0:e455fdb56bc8 204 sendHTTP(clientSocket, httpHeader, movedPermanently(1));
hudakz 0:e455fdb56bc8 205 continue;
hudakz 0:e455fdb56bc8 206 }
hudakz 0:e455fdb56bc8 207
hudakz 0:e455fdb56bc8 208 if(cmd == -1) {
hudakz 0:e455fdb56bc8 209 httpHeader = UNAUTHORIZED;
hudakz 0:e455fdb56bc8 210 httpContent = "<h1>401 Unauthorized</h1>";
hudakz 0:e455fdb56bc8 211 sendHTTP(clientSocket, httpHeader, httpContent);
hudakz 0:e455fdb56bc8 212 continue;
hudakz 0:e455fdb56bc8 213 }
hudakz 0:e455fdb56bc8 214
hudakz 0:e455fdb56bc8 215 if(cmd == ON) {
hudakz 0:e455fdb56bc8 216 sw = ON; // turn the switch on
hudakz 0:e455fdb56bc8 217 }
hudakz 0:e455fdb56bc8 218
hudakz 0:e455fdb56bc8 219 if(cmd == OFF) {
hudakz 0:e455fdb56bc8 220 sw = OFF; // turn the switch off
hudakz 0:e455fdb56bc8 221 }
hudakz 0:e455fdb56bc8 222
hudakz 0:e455fdb56bc8 223 httpHeader = HTTP_OK;
hudakz 0:e455fdb56bc8 224 sendHTTP(clientSocket, httpHeader, showWebPage(sw));
hudakz 0:e455fdb56bc8 225 }
hudakz 0:e455fdb56bc8 226 }