Jack Hansdampf / Mbed OS WebSwitch_ENC28J60_GSOE

Dependencies:   UIPEthernet_GSOE

Committer:
hudakz
Date:
Sat Sep 07 17:53:02 2019 +0000
Revision:
14:810ac368dd6e
Parent:
12:7c46dcf6f7e2
Child:
15:9beb9b99695d
Updated.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
hudakz 10:b47c7921346f 1 #include "mbed.h"
hudakz 0:68a0003c4cb8 2 #include <string>
hudakz 10:b47c7921346f 3 #include "UipEthernet.h"
hudakz 10:b47c7921346f 4 #include "TcpServer.h"
hudakz 10:b47c7921346f 5 #include "TcpClient.h"
hudakz 0:68a0003c4cb8 6
hudakz 10:b47c7921346f 7 using namespace std;
hudakz 4:d34811deedab 8
hudakz 11:6c0b20227ca2 9 //#define DEBUG
hudakz 11:6c0b20227ca2 10
hudakz 14:810ac368dd6e 11 // Static IP address must be unique and compatible with your network.
hudakz 10:b47c7921346f 12 #define IP "192.168.1.35"
hudakz 10:b47c7921346f 13 #define GATEWAY "192.168.1.1"
hudakz 10:b47c7921346f 14 #define NETMASK "255.255.255.0"
hudakz 10:b47c7921346f 15 #define PORT 80
hudakz 0:68a0003c4cb8 16
hudakz 11:6c0b20227ca2 17 const uint8_t MAC[6] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x06 };
hudakz 11:6c0b20227ca2 18 UipEthernet net(MAC, D11, D12, D13, D10); // mosi, miso, sck, cs
hudakz 12:7c46dcf6f7e2 19 TcpServer server; // Ethernet server
hudakz 11:6c0b20227ca2 20 TcpClient* client;
hudakz 11:6c0b20227ca2 21 char receiveBuf[1024];
hudakz 10:b47c7921346f 22 const int OFF = 0;
hudakz 10:b47c7921346f 23 const int ON = 1;
hudakz 11:6c0b20227ca2 24 DigitalOut output(D3); // A digital output to be switched on/off
hudakz 11:6c0b20227ca2 25 float roomTemp = 21.8; // A temperature sensor output
hudakz 11:6c0b20227ca2 26 const string PASSWORD = "secret"; // Change as you like
hudakz 11:6c0b20227ca2 27 string httpHeader; // HTTP header
hudakz 11:6c0b20227ca2 28 string httpContent; // HTTP content
hudakz 0:68a0003c4cb8 29
hudakz 10:b47c7921346f 30 /**
hudakz 10:b47c7921346f 31 * @brief Analyses the received URL
hudakz 10:b47c7921346f 32 * @note The string passed to this function will look like this:
hudakz 10:b47c7921346f 33 * GET /HTTP/1.....
hudakz 10:b47c7921346f 34 * GET /password HTTP/1.....
hudakz 10:b47c7921346f 35 * GET /password/ HTTP/1.....
hudakz 10:b47c7921346f 36 * GET /password/?sw=1 HTTP/1.....
hudakz 10:b47c7921346f 37 * GET /password/?sw=0 HTTP/1.....
hudakz 10:b47c7921346f 38 * @param url URL string
hudakz 10:b47c7921346f 39 * @retval -3 just refresh page
hudakz 10:b47c7921346f 40 * -2 no command given but password valid
hudakz 10:b47c7921346f 41 * -1 invalid password
hudakz 10:b47c7921346f 42 * 0 switch off
hudakz 10:b47c7921346f 43 * 1 switch on
hudakz 10:b47c7921346f 44 */
hudakz 10:b47c7921346f 45 int8_t analyseURL(string& url)
hudakz 10:b47c7921346f 46 {
hudakz 10:b47c7921346f 47 if (url.length() < 5 + PASSWORD.size() + 1)
hudakz 10:b47c7921346f 48 return(-1);
hudakz 0:68a0003c4cb8 49
hudakz 10:b47c7921346f 50 if (url.substr(5, PASSWORD.size()) != PASSWORD)
hudakz 0:68a0003c4cb8 51 return(-1);
hudakz 0:68a0003c4cb8 52
hudakz 0:68a0003c4cb8 53 uint8_t pos = 5 + PASSWORD.size();
hudakz 0:68a0003c4cb8 54
hudakz 10:b47c7921346f 55 if (url.substr(pos, 1) != "/")
hudakz 0:68a0003c4cb8 56 return(-1);
hudakz 0:68a0003c4cb8 57
hudakz 10:b47c7921346f 58 if (url.substr(pos++, 1) == " ")
hudakz 10:b47c7921346f 59 return(-2);
hudakz 0:68a0003c4cb8 60
hudakz 10:b47c7921346f 61 string cmd(url.substr(pos, 5));
hudakz 0:68a0003c4cb8 62
hudakz 10:b47c7921346f 63 if (cmd == "?sw=0")
hudakz 0:68a0003c4cb8 64 return(0);
hudakz 0:68a0003c4cb8 65
hudakz 10:b47c7921346f 66 if (cmd == "?sw=1")
hudakz 0:68a0003c4cb8 67 return(1);
hudakz 0:68a0003c4cb8 68
hudakz 0:68a0003c4cb8 69 return(-3);
hudakz 0:68a0003c4cb8 70 }
hudakz 0:68a0003c4cb8 71
hudakz 5:0ab8292e37da 72 /**
hudakz 5:0ab8292e37da 73 * @brief
hudakz 5:0ab8292e37da 74 * @note
hudakz 5:0ab8292e37da 75 * @param
hudakz 5:0ab8292e37da 76 * @retval
hudakz 5:0ab8292e37da 77 */
hudakz 10:b47c7921346f 78 string& movedPermanently(uint8_t flag)
hudakz 10:b47c7921346f 79 {
hudakz 10:b47c7921346f 80 if (flag == 1)
hudakz 5:0ab8292e37da 81 httpContent = "/" + PASSWORD + "/";
hudakz 0:68a0003c4cb8 82 else
hudakz 0:68a0003c4cb8 83 httpContent = "";
hudakz 0:68a0003c4cb8 84
hudakz 0:68a0003c4cb8 85 httpContent += "<h1>301 Moved Permanently</h1>\r\n";
hudakz 0:68a0003c4cb8 86
hudakz 5:0ab8292e37da 87 return(httpContent);
hudakz 0:68a0003c4cb8 88 }
hudakz 0:68a0003c4cb8 89
hudakz 5:0ab8292e37da 90 /**
hudakz 5:0ab8292e37da 91 * @brief
hudakz 5:0ab8292e37da 92 * @note
hudakz 5:0ab8292e37da 93 * @param
hudakz 5:0ab8292e37da 94 * @retval
hudakz 5:0ab8292e37da 95 */
hudakz 10:b47c7921346f 96 string& showWebPage(int status)
hudakz 10:b47c7921346f 97 {
hudakz 10:b47c7921346f 98 char roomTempStr[5];
hudakz 10:b47c7921346f 99
hudakz 10:b47c7921346f 100 //roomTemp = ds1820.read();
hudakz 10:b47c7921346f 101 sprintf(roomTempStr, "%3.1f", roomTemp);
hudakz 0:68a0003c4cb8 102
hudakz 10:b47c7921346f 103 /*$off*/
hudakz 10:b47c7921346f 104 httpContent =
hudakz 10:b47c7921346f 105 "<head>"
hudakz 10:b47c7921346f 106 "<meta charset=\"utf-8\">"
hudakz 10:b47c7921346f 107 "<meta name=\"viewport\" content=\" initial-scale=1.0; maximum-scale=1.0; minimum-scale=1.0; user-scalable=0;\"/>"
hudakz 10:b47c7921346f 108 "<title>Smart Home</title>"
hudakz 10:b47c7921346f 109 "<link href='http://fonts.googleapis.com/css?family=Droid+Sans&v1' rel='stylesheet' type='text/css'>"
hudakz 10:b47c7921346f 110 "<style>"
hudakz 10:b47c7921346f 111 ".switch {"
hudakz 10:b47c7921346f 112 "position: relative;"
hudakz 10:b47c7921346f 113 "display: inline-block;"
hudakz 10:b47c7921346f 114 "width: 60px;"
hudakz 10:b47c7921346f 115 "height: 34px;"
hudakz 10:b47c7921346f 116 "}"
hudakz 10:b47c7921346f 117 ".switch input {display:none;}"
hudakz 10:b47c7921346f 118 ".slider {"
hudakz 10:b47c7921346f 119 "position: absolute;"
hudakz 10:b47c7921346f 120 "cursor: pointer;"
hudakz 10:b47c7921346f 121 "top: 0;"
hudakz 10:b47c7921346f 122 "left: 0;"
hudakz 10:b47c7921346f 123 "right: 0;"
hudakz 10:b47c7921346f 124 "bottom: 0;"
hudakz 10:b47c7921346f 125 "border-radius: 34px;"
hudakz 10:b47c7921346f 126 "background-color: #ccc;"
hudakz 10:b47c7921346f 127 "-webkit-transition: .4s;"
hudakz 10:b47c7921346f 128 "transition: .4s;"
hudakz 10:b47c7921346f 129 "}"
hudakz 10:b47c7921346f 130 ".slider:before {"
hudakz 10:b47c7921346f 131 "position: absolute;"
hudakz 10:b47c7921346f 132 "content: \"\";"
hudakz 10:b47c7921346f 133 "height: 26px;"
hudakz 10:b47c7921346f 134 "width: 26px;"
hudakz 10:b47c7921346f 135 "left: 4px;"
hudakz 10:b47c7921346f 136 "bottom: 4px;"
hudakz 10:b47c7921346f 137 "border-radius: 50%;"
hudakz 10:b47c7921346f 138 "background-color: white;"
hudakz 10:b47c7921346f 139 "-webkit-transition: .4s;"
hudakz 10:b47c7921346f 140 "transition: .4s;"
hudakz 10:b47c7921346f 141 "}"
hudakz 10:b47c7921346f 142 "input:checked + .slider {"
hudakz 10:b47c7921346f 143 "background-color: #8ce196;"
hudakz 10:b47c7921346f 144 "}"
hudakz 10:b47c7921346f 145 "input:focus + .slider {"
hudakz 10:b47c7921346f 146 "box-shadow: 0 0 1px #8ce196;"
hudakz 10:b47c7921346f 147 "}"
hudakz 10:b47c7921346f 148 "input:checked + .slider:before {"
hudakz 10:b47c7921346f 149 "-webkit-transform: translateX(26px);"
hudakz 10:b47c7921346f 150 "-ms-transform: translateX(26px);"
hudakz 10:b47c7921346f 151 "transform: translateX(26px);"
hudakz 10:b47c7921346f 152 "}"
hudakz 10:b47c7921346f 153 "</style>"
hudakz 10:b47c7921346f 154 "</head>"
hudakz 10:b47c7921346f 155
hudakz 10:b47c7921346f 156 "<body>"
hudakz 10:b47c7921346f 157 "<h2><a href=\".\" title=\"Click to refresh the page\">Smart Home</a></h2>"
hudakz 10:b47c7921346f 158 "<pre>Temperature:\t" + string(roomTempStr) + "&deg;C</pre>"
hudakz 10:b47c7921346f 159 "<pre>Heating:\t";
hudakz 10:b47c7921346f 160
hudakz 10:b47c7921346f 161 if(status == ON) {
hudakz 10:b47c7921346f 162 httpContent +=
hudakz 10:b47c7921346f 163 "<a href=\"./?sw=0\" class=\"switch\"> "
hudakz 10:b47c7921346f 164 "<input type=\"checkbox\" checked>";
hudakz 5:0ab8292e37da 165 }
hudakz 5:0ab8292e37da 166 else {
hudakz 10:b47c7921346f 167 httpContent +=
hudakz 10:b47c7921346f 168 "<a href=\"./?sw=1\" class=\"switch\"> "
hudakz 10:b47c7921346f 169 "<input type=\"checkbox\">";
hudakz 0:68a0003c4cb8 170 }
hudakz 0:68a0003c4cb8 171
hudakz 10:b47c7921346f 172 httpContent +=
hudakz 10:b47c7921346f 173 "<div class=\"slider\"></div>"
hudakz 10:b47c7921346f 174 "</a>"
hudakz 10:b47c7921346f 175 "</pre>"
hudakz 10:b47c7921346f 176 "<hr>"
hudakz 10:b47c7921346f 177 "<pre>2017 ARMmbed</pre>"
hudakz 10:b47c7921346f 178 "</body>";
hudakz 0:68a0003c4cb8 179
hudakz 10:b47c7921346f 180 return httpContent;
hudakz 10:b47c7921346f 181 /*$on*/
hudakz 0:68a0003c4cb8 182 }
hudakz 0:68a0003c4cb8 183
hudakz 5:0ab8292e37da 184 /**
hudakz 5:0ab8292e37da 185 * @brief
hudakz 5:0ab8292e37da 186 * @note
hudakz 5:0ab8292e37da 187 * @param
hudakz 5:0ab8292e37da 188 * @retval
hudakz 5:0ab8292e37da 189 */
hudakz 10:b47c7921346f 190 void sendHTTP(TcpClient& client, string& header, string& content)
hudakz 10:b47c7921346f 191 {
hudakz 10:b47c7921346f 192 /*$off*/
hudakz 10:b47c7921346f 193 char content_length[5] = { };
hudakz 10:b47c7921346f 194
hudakz 10:b47c7921346f 195 header +=
hudakz 10:b47c7921346f 196 "\r\nContent-Type: text/html\r\n"
hudakz 10:b47c7921346f 197 "Content-Length: ";
hudakz 10:b47c7921346f 198 sprintf(content_length, "%d", content.length());
hudakz 10:b47c7921346f 199 header +=
hudakz 10:b47c7921346f 200 string(content_length) + "\r\n"
hudakz 10:b47c7921346f 201 "Pragma: no-cache\r\n"
hudakz 10:b47c7921346f 202 "Connection: About to close\r\n\r\n";
hudakz 10:b47c7921346f 203
hudakz 10:b47c7921346f 204 string webpage = header + content;
hudakz 11:6c0b20227ca2 205 client.send((uint8_t*)webpage.c_str(), webpage.length());
hudakz 10:b47c7921346f 206 /*$on*/
hudakz 10:b47c7921346f 207 }
hudakz 10:b47c7921346f 208
hudakz 10:b47c7921346f 209 /**
hudakz 10:b47c7921346f 210 * @brief
hudakz 10:b47c7921346f 211 * @note
hudakz 10:b47c7921346f 212 * @param
hudakz 10:b47c7921346f 213 * @retval
hudakz 10:b47c7921346f 214 */
hudakz 10:b47c7921346f 215 int main(void)
hudakz 10:b47c7921346f 216 {
hudakz 10:b47c7921346f 217 printf("Starting ...\r\n");
hudakz 10:b47c7921346f 218
hudakz 12:7c46dcf6f7e2 219 //net.set_network(IP, NETMASK, GATEWAY); // include this for using static IP address
hudakz 14:810ac368dd6e 220 if (net.connect(30) != 0) { // 'connect' timeout in seconds (defaults to 60 sec)
hudakz 14:810ac368dd6e 221 printf("Unable to connet.\r\n");
hudakz 14:810ac368dd6e 222 return -1;
hudakz 14:810ac368dd6e 223 }
hudakz 10:b47c7921346f 224
hudakz 10:b47c7921346f 225 // Show the network address
hudakz 10:b47c7921346f 226 const char* ip = net.get_ip_address();
hudakz 10:b47c7921346f 227 const char* netmask = net.get_netmask();
hudakz 10:b47c7921346f 228 const char* gateway = net.get_gateway();
hudakz 10:b47c7921346f 229
hudakz 10:b47c7921346f 230 printf("IP address: %s\r\n", ip ? ip : "None");
hudakz 10:b47c7921346f 231 printf("Netmask: %s\r\n", netmask ? netmask : "None");
hudakz 10:b47c7921346f 232 printf("Gateway: %s\r\n\r\n", gateway ? gateway : "None");
hudakz 14:810ac368dd6e 233 printf("------------------------------------------------------------------\r\n");
hudakz 14:810ac368dd6e 234 printf("Usage: Type %s/%s/ into your web browser and hit ENTER\r\n", ip, PASSWORD.c_str());
hudakz 14:810ac368dd6e 235 printf("------------------------------------------------------------------\r\n");
hudakz 10:b47c7921346f 236
hudakz 10:b47c7921346f 237 /* Open the server on ethernet stack */
hudakz 10:b47c7921346f 238 server.open(&net);
hudakz 10:b47c7921346f 239
hudakz 10:b47c7921346f 240 /* Bind the HTTP port (TCP 80) to the server */
hudakz 10:b47c7921346f 241 server.bind(PORT);
hudakz 10:b47c7921346f 242
hudakz 14:810ac368dd6e 243 /* Can handle 4 simultaneous connections */
hudakz 14:810ac368dd6e 244 server.listen(4);
hudakz 10:b47c7921346f 245
hudakz 11:6c0b20227ca2 246 while (true) {
hudakz 10:b47c7921346f 247 client = server.accept();
hudakz 10:b47c7921346f 248
hudakz 10:b47c7921346f 249 if (client) {
hudakz 11:6c0b20227ca2 250 client->recv((uint8_t*)receiveBuf, client->available());
hudakz 11:6c0b20227ca2 251 #ifdef DEBUG
hudakz 11:6c0b20227ca2 252 printf("Client with IP address %s connected.\r\n\r\n", client->getpeername());
hudakz 11:6c0b20227ca2 253 printf("Data received:\r\n%s\n\r", receiveBuf);
hudakz 11:6c0b20227ca2 254 #endif
hudakz 11:6c0b20227ca2 255 string received(receiveBuf);
hudakz 10:b47c7921346f 256
hudakz 11:6c0b20227ca2 257 if (received.substr(0, 3) != "GET") {
hudakz 11:6c0b20227ca2 258 httpHeader = "HTTP/1.0 200 OK";
hudakz 11:6c0b20227ca2 259 httpContent = "<h1>200 OK</h1>";
hudakz 11:6c0b20227ca2 260 sendHTTP(*client, httpHeader, httpContent);
hudakz 11:6c0b20227ca2 261 client->close();
hudakz 11:6c0b20227ca2 262 continue;
hudakz 11:6c0b20227ca2 263 }
hudakz 0:68a0003c4cb8 264
hudakz 11:6c0b20227ca2 265 if (received.substr(0, 6) == "GET / ") {
hudakz 11:6c0b20227ca2 266 httpHeader = "HTTP/1.0 200 OK";
hudakz 11:6c0b20227ca2 267 httpContent = "<p>Usage: http://host_or_ip/password</p>\r\n";
hudakz 11:6c0b20227ca2 268 sendHTTP(*client, httpHeader, httpContent);
hudakz 11:6c0b20227ca2 269 client->close();
hudakz 11:6c0b20227ca2 270 continue;
hudakz 11:6c0b20227ca2 271 }
hudakz 0:68a0003c4cb8 272
hudakz 11:6c0b20227ca2 273 int cmd = analyseURL(received);
hudakz 10:b47c7921346f 274
hudakz 11:6c0b20227ca2 275 switch (cmd) {
hudakz 11:6c0b20227ca2 276 case -3:
hudakz 11:6c0b20227ca2 277 // update webpage
hudakz 11:6c0b20227ca2 278 httpHeader = "HTTP/1.0 200 OK";
hudakz 11:6c0b20227ca2 279 sendHTTP(*client, httpHeader, showWebPage(output));
hudakz 11:6c0b20227ca2 280 break;
hudakz 10:b47c7921346f 281
hudakz 11:6c0b20227ca2 282 case -2:
hudakz 11:6c0b20227ca2 283 // redirect to the right base url
hudakz 11:6c0b20227ca2 284 httpHeader = "HTTP/1.0 301 Moved Permanently\r\nLocation: ";
hudakz 11:6c0b20227ca2 285 sendHTTP(*client, httpHeader, movedPermanently(1));
hudakz 11:6c0b20227ca2 286 break;
hudakz 0:68a0003c4cb8 287
hudakz 11:6c0b20227ca2 288 case -1:
hudakz 11:6c0b20227ca2 289 httpHeader = "HTTP/1.0 401 Unauthorized";
hudakz 11:6c0b20227ca2 290 httpContent = "<h1>401 Unauthorized</h1>";
hudakz 11:6c0b20227ca2 291 sendHTTP(*client, httpHeader, httpContent);
hudakz 11:6c0b20227ca2 292 break;
hudakz 0:68a0003c4cb8 293
hudakz 11:6c0b20227ca2 294 case 0:
hudakz 11:6c0b20227ca2 295 output = OFF; // output off
hudakz 11:6c0b20227ca2 296 httpHeader = "HTTP/1.0 200 OK";
hudakz 11:6c0b20227ca2 297 sendHTTP(*client, httpHeader, showWebPage(output));
hudakz 11:6c0b20227ca2 298 break;
hudakz 0:68a0003c4cb8 299
hudakz 11:6c0b20227ca2 300 case 1:
hudakz 11:6c0b20227ca2 301 output = ON; // output on
hudakz 11:6c0b20227ca2 302 httpHeader = "HTTP/1.0 200 OK";
hudakz 11:6c0b20227ca2 303 sendHTTP(*client, httpHeader, showWebPage(output));
hudakz 11:6c0b20227ca2 304 break;
hudakz 0:68a0003c4cb8 305 }
hudakz 11:6c0b20227ca2 306
hudakz 10:b47c7921346f 307 client->close();
hudakz 0:68a0003c4cb8 308 }
hudakz 0:68a0003c4cb8 309 }
hudakz 0:68a0003c4cb8 310 }