Zoltan Hudak / Mbed OS STM32F407VET6_WebSwitch-os
Committer:
hudakz
Date:
Sat Jun 15 13:50:41 2019 +0000
Revision:
7:482a6f018329
Parent:
6:55e13e19bec3
Child:
8:6f52a0c88bca
Updated.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
hudakz 0:912fb893b03c 1 #include "mbed.h"
hudakz 0:912fb893b03c 2 #include "EthernetInterface.h"
hudakz 0:912fb893b03c 3 #include "TCPSocket.h"
hudakz 0:912fb893b03c 4 #include <stdio.h>
hudakz 0:912fb893b03c 5 #include <string>
hudakz 6:55e13e19bec3 6
hudakz 0:912fb893b03c 7 using namespace std;
hudakz 6:55e13e19bec3 8
hudakz 6:55e13e19bec3 9 #define IP "192.168.1.181"
hudakz 6:55e13e19bec3 10 #define GATEWAY "192.168.1.1"
hudakz 6:55e13e19bec3 11 #define NETMASK "255.255.255.0"
hudakz 6:55e13e19bec3 12 #define PORT 80
hudakz 0:912fb893b03c 13
hudakz 0:912fb893b03c 14 Serial pc(PC_6, PC_7);
hudakz 0:912fb893b03c 15 //Serial pc(PA_9, PA_10);
hudakz 0:912fb893b03c 16 EthernetInterface* net;
hudakz 0:912fb893b03c 17 TCPSocket server;
hudakz 0:912fb893b03c 18 TCPSocket* clientSocket;
hudakz 0:912fb893b03c 19 SocketAddress clientAddress;
hudakz 0:912fb893b03c 20 char receiveBuf[1024] = { };
hudakz 0:912fb893b03c 21 const int OFF = 1;
hudakz 0:912fb893b03c 22 const int ON = 0;
hudakz 6:55e13e19bec3 23 DigitalOut sw(PA_6); // A switch
hudakz 6:55e13e19bec3 24 float roomTemp = 21.8; // A temperature sensor output
hudakz 6:55e13e19bec3 25 const string PASSWORD = "secret"; // change as you like
hudakz 6:55e13e19bec3 26 const string HTTP_OK = "HTTP/1.0 200 OK";
hudakz 6:55e13e19bec3 27 const string MOVED_PERM = "HTTP/1.0 301 Moved Permanently\r\nLocation: ";
hudakz 0:912fb893b03c 28 const string UNAUTHORIZED = "HTTP/1.0 401 Unauthorized";
hudakz 6:55e13e19bec3 29 string httpHeader; // HTTP header
hudakz 6:55e13e19bec3 30 string httpContent; // HTTP content
hudakz 6:55e13e19bec3 31
hudakz 0:912fb893b03c 32 /**
hudakz 7:482a6f018329 33 * @brief Defines a custom MAC address
hudakz 7:482a6f018329 34 * @note Uncomment the code below to define a unique MAC address.
hudakz 7:482a6f018329 35 * Modify the mac array items as needed.
hudakz 7:482a6f018329 36 * @param
hudakz 7:482a6f018329 37 * @retval
hudakz 7:482a6f018329 38 */
hudakz 7:482a6f018329 39 //extern "C" void mbed_mac_address(char* mac) {
hudakz 7:482a6f018329 40 // mac[0] = 0x00;
hudakz 7:482a6f018329 41 // mac[1] = 0x01;
hudakz 7:482a6f018329 42 // mac[2] = 0x02;
hudakz 7:482a6f018329 43 // mac[3] = 0x03;
hudakz 7:482a6f018329 44 // mac[4] = 0x04;
hudakz 7:482a6f018329 45 // mac[5] = 0x05;
hudakz 7:482a6f018329 46 //};
hudakz 7:482a6f018329 47
hudakz 7:482a6f018329 48 /**
hudakz 0:912fb893b03c 49 * @brief Analyses the received URL
hudakz 0:912fb893b03c 50 * @note The string passed to this function will look like this:
hudakz 0:912fb893b03c 51 * GET /password HTTP/1.....
hudakz 0:912fb893b03c 52 * GET /password/ HTTP/1.....
hudakz 0:912fb893b03c 53 * GET /password/?sw=1 HTTP/1.....
hudakz 0:912fb893b03c 54 * GET /password/?sw=0 HTTP/1.....
hudakz 0:912fb893b03c 55 * @param url URL string
hudakz 0:912fb893b03c 56 * @retval -1 invalid password
hudakz 0:912fb893b03c 57 * -2 no command given but password valid
hudakz 0:912fb893b03c 58 * -3 just refresh page
hudakz 0:912fb893b03c 59 * 0 switch off
hudakz 0:912fb893b03c 60 * 1 switch on
hudakz 0:912fb893b03c 61 */
hudakz 6:55e13e19bec3 62 int8_t analyseURL(string& url)
hudakz 6:55e13e19bec3 63 {
hudakz 6:55e13e19bec3 64 if (url.length() < 5 + PASSWORD.size() + 1)
hudakz 5:92942d4f4ff6 65 return(-1);
hudakz 6:55e13e19bec3 66
hudakz 6:55e13e19bec3 67 if (url.substr(5, PASSWORD.size()) != PASSWORD)
hudakz 0:912fb893b03c 68 return(-1);
hudakz 6:55e13e19bec3 69
hudakz 0:912fb893b03c 70 uint8_t pos = 5 + PASSWORD.size();
hudakz 6:55e13e19bec3 71
hudakz 6:55e13e19bec3 72 if (url.substr(pos, 1) != "/")
hudakz 5:92942d4f4ff6 73 return(-1);
hudakz 5:92942d4f4ff6 74
hudakz 6:55e13e19bec3 75 if (url.substr(pos++, 1) == " ")
hudakz 0:912fb893b03c 76 return(-2);
hudakz 6:55e13e19bec3 77
hudakz 0:912fb893b03c 78 string cmd(url.substr(pos, 5));
hudakz 6:55e13e19bec3 79
hudakz 6:55e13e19bec3 80 if (cmd == "?sw=0")
hudakz 0:912fb893b03c 81 return(0);
hudakz 6:55e13e19bec3 82
hudakz 6:55e13e19bec3 83 if (cmd == "?sw=1")
hudakz 0:912fb893b03c 84 return(1);
hudakz 6:55e13e19bec3 85
hudakz 0:912fb893b03c 86 return(-3);
hudakz 0:912fb893b03c 87 }
hudakz 6:55e13e19bec3 88
hudakz 0:912fb893b03c 89 /**
hudakz 0:912fb893b03c 90 * @brief
hudakz 0:912fb893b03c 91 * @note
hudakz 0:912fb893b03c 92 * @param
hudakz 0:912fb893b03c 93 * @retval
hudakz 0:912fb893b03c 94 */
hudakz 6:55e13e19bec3 95 string& movedPermanently(uint8_t flag)
hudakz 6:55e13e19bec3 96 {
hudakz 6:55e13e19bec3 97 if (flag == 1)
hudakz 0:912fb893b03c 98 httpContent = "/" + PASSWORD + "/";
hudakz 0:912fb893b03c 99 else
hudakz 0:912fb893b03c 100 httpContent = "";
hudakz 6:55e13e19bec3 101
hudakz 0:912fb893b03c 102 httpContent += "<h1>301 Moved Permanently</h1>\r\n";
hudakz 6:55e13e19bec3 103
hudakz 0:912fb893b03c 104 return(httpContent);
hudakz 0:912fb893b03c 105 }
hudakz 6:55e13e19bec3 106
hudakz 0:912fb893b03c 107 /**
hudakz 0:912fb893b03c 108 * @brief
hudakz 0:912fb893b03c 109 * @note
hudakz 0:912fb893b03c 110 * @param
hudakz 0:912fb893b03c 111 * @retval
hudakz 0:912fb893b03c 112 */
hudakz 6:55e13e19bec3 113 string& showWebPage(uint8_t status)
hudakz 6:55e13e19bec3 114 {
hudakz 6:55e13e19bec3 115 /*$off*/
hudakz 6:55e13e19bec3 116 char roomTempStr[5];
hudakz 6:55e13e19bec3 117
hudakz 0:912fb893b03c 118 //roomTemp = ds1820.read();
hudakz 0:912fb893b03c 119 sprintf(roomTempStr, "%3.1f", roomTemp);
hudakz 6:55e13e19bec3 120
hudakz 0:912fb893b03c 121 // CSS toggle switch
hudakz 7:482a6f018329 122 httpContent =
hudakz 3:6edf142a16a8 123 "<head>"
hudakz 7:482a6f018329 124 "<style>"
hudakz 7:482a6f018329 125 ".switch {"
hudakz 7:482a6f018329 126 "position: relative;"
hudakz 7:482a6f018329 127 "display: inline-block;"
hudakz 7:482a6f018329 128 "width: 60px;"
hudakz 7:482a6f018329 129 "height: 34px;"
hudakz 7:482a6f018329 130 "}"
hudakz 7:482a6f018329 131 ".switch input {display:none;}"
hudakz 7:482a6f018329 132 ".slider {"
hudakz 7:482a6f018329 133 "position: absolute;"
hudakz 7:482a6f018329 134 "cursor: pointer;"
hudakz 7:482a6f018329 135 "top: 0;"
hudakz 7:482a6f018329 136 "left: 0;"
hudakz 7:482a6f018329 137 "right: 0;"
hudakz 7:482a6f018329 138 "bottom: 0;"
hudakz 7:482a6f018329 139 "border-radius: 34px;"
hudakz 7:482a6f018329 140 "background-color: #ccc;"
hudakz 7:482a6f018329 141 "-webkit-transition: .4s;"
hudakz 7:482a6f018329 142 "transition: .4s;"
hudakz 7:482a6f018329 143 "}"
hudakz 7:482a6f018329 144 ".slider:before {"
hudakz 7:482a6f018329 145 "position: absolute;"
hudakz 7:482a6f018329 146 "content: "";"
hudakz 7:482a6f018329 147 "height: 26px;"
hudakz 7:482a6f018329 148 "width: 26px;"
hudakz 7:482a6f018329 149 "left: 4px;"
hudakz 7:482a6f018329 150 "bottom: 4px;"
hudakz 7:482a6f018329 151 "border-radius: 50%;"
hudakz 7:482a6f018329 152 "background-color: white;"
hudakz 7:482a6f018329 153 "-webkit-transition: .4s;"
hudakz 7:482a6f018329 154 "transition: .4s;"
hudakz 7:482a6f018329 155 "}"
hudakz 7:482a6f018329 156 "input:checked + .slider {"
hudakz 7:482a6f018329 157 "background-color: #8ce196;"
hudakz 7:482a6f018329 158 "}"
hudakz 7:482a6f018329 159 "input:focus + .slider {"
hudakz 7:482a6f018329 160 "box-shadow: 0 0 1px #8ce196;"
hudakz 7:482a6f018329 161 "}"
hudakz 7:482a6f018329 162 "input:checked + .slider:before {"
hudakz 7:482a6f018329 163 "-webkit-transform: translateX(26px);"
hudakz 7:482a6f018329 164 "-ms-transform: translateX(26px);"
hudakz 7:482a6f018329 165 "transform: translateX(26px);"
hudakz 7:482a6f018329 166 "}"
hudakz 7:482a6f018329 167 "</style>"
hudakz 7:482a6f018329 168 "</head>"
hudakz 6:55e13e19bec3 169
hudakz 4:c11d58a6c9e2 170 // Web page
hudakz 3:6edf142a16a8 171 "<body>"
hudakz 7:482a6f018329 172 "<h2><a href=\".\" title=\"Click to refresh the page\">Smart Home</a></h2>"
hudakz 7:482a6f018329 173 "<pre>Temperature:\t" + string(roomTempStr) + "&deg;C</pre>"
hudakz 3:6edf142a16a8 174 "<pre>Heating:\t";
hudakz 6:55e13e19bec3 175
hudakz 6:55e13e19bec3 176 if (status == ON) {
hudakz 7:482a6f018329 177 httpContent +=
hudakz 7:482a6f018329 178 "<a href=\"./?sw=0\" class=\"switch\"> "
hudakz 3:6edf142a16a8 179 "<input type=\"checkbox\" checked>";
hudakz 0:912fb893b03c 180 }
hudakz 0:912fb893b03c 181 else {
hudakz 7:482a6f018329 182 httpContent +=
hudakz 7:482a6f018329 183 "<a href=\"./?sw=1\" class=\"switch\"> "
hudakz 3:6edf142a16a8 184 "<input type=\"checkbox\">";
hudakz 6:55e13e19bec3 185 }
hudakz 6:55e13e19bec3 186
hudakz 7:482a6f018329 187 httpContent +=
hudakz 7:482a6f018329 188 "<div class=\"slider\"></div>"
hudakz 7:482a6f018329 189 "</a></pre>"
hudakz 7:482a6f018329 190 "<hr>"
hudakz 7:482a6f018329 191 "<pre>2017 ARMmbed</pre>"
hudakz 3:6edf142a16a8 192 "</body>";
hudakz 6:55e13e19bec3 193
hudakz 0:912fb893b03c 194 return httpContent;
hudakz 6:55e13e19bec3 195 /*$on*/
hudakz 0:912fb893b03c 196 }
hudakz 6:55e13e19bec3 197
hudakz 0:912fb893b03c 198 /**
hudakz 0:912fb893b03c 199 * @brief
hudakz 0:912fb893b03c 200 * @note
hudakz 0:912fb893b03c 201 * @param
hudakz 0:912fb893b03c 202 * @retval
hudakz 0:912fb893b03c 203 */
hudakz 6:55e13e19bec3 204 void sendHTTP(TCPSocket& client, string& header, string& content)
hudakz 6:55e13e19bec3 205 {
hudakz 6:55e13e19bec3 206 /*$off*/
hudakz 0:912fb893b03c 207 char content_length[5] = { };
hudakz 6:55e13e19bec3 208
hudakz 7:482a6f018329 209 header +=
hudakz 7:482a6f018329 210 "\r\nContent-Type: text/html\r\n"
hudakz 3:6edf142a16a8 211 "Content-Length: ";
hudakz 0:912fb893b03c 212 sprintf(content_length, "%d", content.length());
hudakz 7:482a6f018329 213 header +=
hudakz 7:482a6f018329 214 string(content_length) + "\r\n"
hudakz 7:482a6f018329 215 "Pragma: no-cache\r\n"
hudakz 3:6edf142a16a8 216 "Connection: About to close\r\n\r\n";
hudakz 6:55e13e19bec3 217
hudakz 0:912fb893b03c 218 string webpage = header + content;
hudakz 0:912fb893b03c 219 client.send((char*)webpage.c_str(), webpage.length());
hudakz 0:912fb893b03c 220 pc.printf("HTTP message sent to client.\n\r");
hudakz 6:55e13e19bec3 221 /*$on*/
hudakz 0:912fb893b03c 222 }
hudakz 6:55e13e19bec3 223
hudakz 0:912fb893b03c 224 /**
hudakz 0:912fb893b03c 225 * @brief
hudakz 0:912fb893b03c 226 * @note
hudakz 0:912fb893b03c 227 * @param
hudakz 0:912fb893b03c 228 * @retval
hudakz 0:912fb893b03c 229 */
hudakz 6:55e13e19bec3 230 int main(void)
hudakz 6:55e13e19bec3 231 {
hudakz 0:912fb893b03c 232 pc.printf("Starting.. \r\n\r\n");
hudakz 6:55e13e19bec3 233
hudakz 0:912fb893b03c 234 net = new EthernetInterface();
hudakz 0:912fb893b03c 235
hudakz 0:912fb893b03c 236 if (!net) {
hudakz 0:912fb893b03c 237 pc.printf("Error! No network inteface found.\n");
hudakz 0:912fb893b03c 238 return 0;
hudakz 0:912fb893b03c 239 }
hudakz 0:912fb893b03c 240
hudakz 0:912fb893b03c 241 //net->set_network (IP, NETMASK, GATEWAY); // include this for using static IP address
hudakz 6:55e13e19bec3 242 nsapi_size_or_error_t r = net->connect();
hudakz 7:482a6f018329 243
hudakz 0:912fb893b03c 244 if (r != 0) {
hudakz 0:912fb893b03c 245 pc.printf("Error! net->connect() returned: %d\n", r);
hudakz 0:912fb893b03c 246 return r;
hudakz 0:912fb893b03c 247 }
hudakz 0:912fb893b03c 248
hudakz 6:55e13e19bec3 249 // Show the network address
hudakz 6:55e13e19bec3 250 const char* ip = net->get_ip_address();
hudakz 6:55e13e19bec3 251 const char* netmask = net->get_netmask();
hudakz 6:55e13e19bec3 252 const char* gateway = net->get_gateway();
hudakz 0:912fb893b03c 253 pc.printf("IP address: %s\r\n", ip ? ip : "None");
hudakz 0:912fb893b03c 254 pc.printf("Netmask: %s\r\n", netmask ? netmask : "None");
hudakz 6:55e13e19bec3 255 pc.printf("Gateway: %s\r\n\r\n", gateway ? gateway : "None");
hudakz 0:912fb893b03c 256 pc.printf("Usage: Type %s/%s/ into your web browser and hit ENTER\r\n\r\n", ip, PASSWORD.c_str());
hudakz 6:55e13e19bec3 257
hudakz 0:912fb893b03c 258 /* Open the server on ethernet stack */
hudakz 0:912fb893b03c 259 server.open(net);
hudakz 6:55e13e19bec3 260
hudakz 0:912fb893b03c 261 /* Bind the HTTP port (TCP 80) to the server */
hudakz 0:912fb893b03c 262 server.bind(ip, PORT);
hudakz 6:55e13e19bec3 263
hudakz 0:912fb893b03c 264 /* Can handle 5 simultaneous connections */
hudakz 0:912fb893b03c 265 server.listen(5);
hudakz 6:55e13e19bec3 266
hudakz 0:912fb893b03c 267 //listening for http GET request
hudakz 6:55e13e19bec3 268 while (true) {
hudakz 0:912fb893b03c 269 pc.printf("=========================================\r\n");
hudakz 6:55e13e19bec3 270
hudakz 6:55e13e19bec3 271 nsapi_error_t error;
hudakz 7:482a6f018329 272
hudakz 0:912fb893b03c 273 clientSocket = server.accept(&error);
hudakz 0:912fb893b03c 274 if (error != 0) {
hudakz 0:912fb893b03c 275 pc.printf("Connection failed!\r\n");
hudakz 5:92942d4f4ff6 276 clientSocket->close();
hudakz 0:912fb893b03c 277 continue;
hudakz 0:912fb893b03c 278 }
hudakz 6:55e13e19bec3 279
hudakz 0:912fb893b03c 280 clientSocket->getpeername(&clientAddress);
hudakz 0:912fb893b03c 281 pc.printf("Client with IP address %s connected.\r\n\r\n", clientAddress.get_ip_address());
hudakz 0:912fb893b03c 282 clientSocket->recv(receiveBuf, 1023);
hudakz 0:912fb893b03c 283 pc.printf("Data received:\r\n%s\n\r", receiveBuf);
hudakz 6:55e13e19bec3 284
hudakz 0:912fb893b03c 285 string received(receiveBuf);
hudakz 6:55e13e19bec3 286
hudakz 6:55e13e19bec3 287 if (received.substr(0, 3) != "GET") {
hudakz 0:912fb893b03c 288 httpHeader = HTTP_OK;
hudakz 0:912fb893b03c 289 httpContent = "<h1>200 OK</h1>";
hudakz 0:912fb893b03c 290 sendHTTP(*clientSocket, httpHeader, httpContent);
hudakz 5:92942d4f4ff6 291 clientSocket->close();
hudakz 0:912fb893b03c 292 continue;
hudakz 0:912fb893b03c 293 }
hudakz 6:55e13e19bec3 294
hudakz 6:55e13e19bec3 295 if (received.substr(0, 6) == "GET / ") {
hudakz 0:912fb893b03c 296 httpHeader = HTTP_OK;
hudakz 0:912fb893b03c 297 httpContent = "<p>Usage: Type http://ip_address/password/ into your web browser and hit ENTER</p>\r\n";
hudakz 0:912fb893b03c 298 sendHTTP(*clientSocket, httpHeader, httpContent);
hudakz 5:92942d4f4ff6 299 clientSocket->close();
hudakz 0:912fb893b03c 300 continue;
hudakz 0:912fb893b03c 301 }
hudakz 6:55e13e19bec3 302
hudakz 0:912fb893b03c 303 int cmd = analyseURL(received);
hudakz 6:55e13e19bec3 304
hudakz 6:55e13e19bec3 305 if (cmd == -2) {
hudakz 0:912fb893b03c 306 // redirect to the right base url
hudakz 0:912fb893b03c 307 httpHeader = MOVED_PERM;
hudakz 0:912fb893b03c 308 sendHTTP(*clientSocket, httpHeader, movedPermanently(1));
hudakz 5:92942d4f4ff6 309 clientSocket->close();
hudakz 0:912fb893b03c 310 continue;
hudakz 0:912fb893b03c 311 }
hudakz 6:55e13e19bec3 312
hudakz 6:55e13e19bec3 313 if (cmd == -1) {
hudakz 0:912fb893b03c 314 httpHeader = UNAUTHORIZED;
hudakz 0:912fb893b03c 315 httpContent = "<h1>401 Unauthorized</h1>";
hudakz 0:912fb893b03c 316 sendHTTP(*clientSocket, httpHeader, httpContent);
hudakz 5:92942d4f4ff6 317 clientSocket->close();
hudakz 0:912fb893b03c 318 continue;
hudakz 0:912fb893b03c 319 }
hudakz 6:55e13e19bec3 320
hudakz 7:482a6f018329 321 switch (cmd) {
hudakz 7:482a6f018329 322 case 0:
hudakz 7:482a6f018329 323 sw = OFF; // turn the switch off
hudakz 7:482a6f018329 324 break;
hudakz 7:482a6f018329 325 case 1:
hudakz 7:482a6f018329 326 sw = ON; // turn the switch on
hudakz 7:482a6f018329 327 break;
hudakz 7:482a6f018329 328 default:
hudakz 7:482a6f018329 329 clientSocket->close();
hudakz 7:482a6f018329 330 continue;
hudakz 7:482a6f018329 331 }
hudakz 7:482a6f018329 332
hudakz 0:912fb893b03c 333 httpHeader = HTTP_OK;
hudakz 0:912fb893b03c 334 sendHTTP(*clientSocket, httpHeader, showWebPage(sw));
hudakz 0:912fb893b03c 335 clientSocket->close();
hudakz 0:912fb893b03c 336 }
hudakz 0:912fb893b03c 337 }