Zoltan Hudak
/
STM32F407VET6_WebSwitch-os
Tiny HTTP server controlling a DigitalOutput.
Embed:
(wiki syntax)
Show/hide line numbers
main.cpp
00001 #include "mbed.h" 00002 #include "EthernetInterface.h" 00003 #include "TCPSocket.h" 00004 #include <stdio.h> 00005 #include <string> 00006 00007 DigitalOut led(PA_6); 00008 00009 FileHandle* mbed::mbed_override_console(int) 00010 { 00011 static BufferedSerial arch_max_serial1(PA_9, PA_10, 9600); 00012 return &arch_max_serial1; 00013 } 00014 00015 #define PORT 80 00016 /* */ 00017 EthernetInterface* net; 00018 TCPSocket server; 00019 TCPSocket* client; 00020 char httpBuf[1500]; 00021 char httpHeader[256]; 00022 const int OFF = 0; 00023 const int ON = 1; 00024 const char PASSWORD[] = "secret"; // Change as you like 00025 DigitalOut output(LED1); 00026 float roomTemp = 21.8; // A temperature sensor output 00027 00028 FileHandle* mbed_override_console(int) 00029 { 00030 static BufferedSerial arch_max_serial1(PA_9, PA_10, 9600); 00031 return &arch_max_serial1; 00032 } 00033 00034 /** 00035 * @brief Analyses the received URL 00036 * @note The string passed to this function will look like this: 00037 * GET /password HTTP/1..... 00038 * GET /password/ HTTP/1..... 00039 * GET /password/?sw=1 HTTP/1..... 00040 * GET /password/?sw=0 HTTP/1..... 00041 * @param url URL string 00042 * @retval -1 invalid password 00043 * -2 no command given but password valid 00044 * -3 just refresh page 00045 * 0 switch off 00046 * 1 switch on 00047 */ 00048 int8_t analyseURL(char* url) 00049 { 00050 if (strlen(url) < (5 + strlen(PASSWORD) + 1)) 00051 return(-1); 00052 00053 //if (url.substr(5, PASSWORD.size()) != PASSWORD) 00054 if (strncmp(url + 5, PASSWORD, strlen(PASSWORD)) != 0) 00055 return(-1); 00056 00057 uint8_t pos = 5 + strlen(PASSWORD); 00058 00059 //if (url.substr(pos, 1) != "/") 00060 00061 if (*(url + pos) != '/') 00062 return(-1); 00063 00064 //if (url.substr(pos++, 1) == " ") 00065 if (*(url + pos++) == ' ') 00066 return(-2); 00067 00068 //string cmd(url.substr(pos, 5)); 00069 *(url + pos + 5) = '\0'; // terminate the cmd string 00070 char* cmd = ((url + pos)); 00071 if (strcmp(cmd, "?sw=0") == 0) 00072 return(0); 00073 if (strcmp(cmd, "?sw=1") == 0) 00074 return(1); 00075 return(-3); 00076 } 00077 00078 /** 00079 * @brief 00080 * @note 00081 * @param 00082 * @retval 00083 */ 00084 char* movedPermanently(uint8_t flag) 00085 { 00086 memset(httpBuf, 0, sizeof(httpBuf)); 00087 if (flag == 1) { 00088 strcpy(httpBuf, "/"); 00089 strcat(httpBuf, PASSWORD); 00090 strcat(httpBuf, "/"); 00091 } 00092 00093 strcat(httpBuf, "<h1>301 Moved Permanently</h1>\r\n"); 00094 return(httpBuf); 00095 } 00096 00097 /** 00098 * @brief 00099 * @note 00100 * @param 00101 * @retval 00102 */ 00103 char* showWebPage(int status) 00104 { 00105 char roomTempStr[10] = { }; 00106 00107 //roomTemp = ds1820.read(); 00108 00109 sprintf(roomTempStr, "%3.1f", roomTemp); 00110 memset(httpBuf, 0, sizeof(httpBuf)); 00111 00112 /*$off*/ 00113 strcat 00114 ( 00115 httpBuf, 00116 "<head>" 00117 "<meta charset=\"utf-8\">" 00118 "<meta name=\"viewport\" content=\" initial-scale=1.0; maximum-scale=1.0; minimum-scale=1.0; user-scalable=0;\"/>" 00119 "<title>Smart Home</title>" 00120 "<link href='http://fonts.googleapis.com/css?family=Droid+Sans&v1' rel='stylesheet' type='text/css'>" 00121 "<style>" 00122 ".switch {" 00123 "position: relative;" 00124 "display: inline-block;" 00125 "width: 60px;" 00126 "height: 34px;" 00127 "}" 00128 ".switch input {display:none;}" 00129 ".slider {" 00130 "position: absolute;" 00131 "cursor: pointer;" 00132 "top: 0;" 00133 "left: 0;" 00134 "right: 0;" 00135 "bottom: 0;" 00136 "border-radius: 34px;" 00137 "background-color: #ccc;" 00138 "-webkit-transition: .4s;" 00139 "transition: .4s;" 00140 "}" 00141 ".slider:before {" 00142 "position: absolute;" 00143 "content: \"\";" 00144 "height: 26px;" 00145 "width: 26px;" 00146 "left: 4px;" 00147 "bottom: 4px;" 00148 "border-radius: 50%;" 00149 "background-color: white;" 00150 "-webkit-transition: .4s;" 00151 "transition: .4s;" 00152 "}" 00153 "input:checked + .slider {" 00154 "background-color: #8ce196;" 00155 "}" 00156 "input:focus + .slider {" 00157 "box-shadow: 0 0 1px #8ce196;" 00158 "}" 00159 "input:checked + .slider:before {" 00160 "-webkit-transform: translateX(26px);" 00161 "-ms-transform: translateX(26px);" 00162 "transform: translateX(26px);" 00163 "}" 00164 "</style>" 00165 "</head>" 00166 00167 "<body>" 00168 "<h2><a href=\".\" title=\"Click to refresh the page\">Smart Home</a></h2>" 00169 "<pre>Temperature:\t" 00170 ); 00171 strcat(httpBuf, roomTempStr); 00172 strcat(httpBuf, "°C</pre>"); 00173 strcat 00174 ( 00175 httpBuf, 00176 "<pre>Heating:\t" 00177 ); 00178 if(status == ON) { 00179 strcat 00180 ( 00181 httpBuf, 00182 "<a href=\"./?sw=0\" class=\"switch\"> " 00183 "<input type=\"checkbox\" checked>" 00184 ); 00185 } 00186 else { 00187 strcat 00188 ( 00189 httpBuf, 00190 "<a href=\"./?sw=1\" class=\"switch\"> " 00191 "<input type=\"checkbox\">" 00192 ); 00193 } 00194 strcat 00195 ( 00196 httpBuf, 00197 "<div class=\"slider\"></div>" 00198 "</a>" 00199 "</pre>" 00200 "<hr>" 00201 "<pre>2017 ARMmbed</pre>" 00202 "</body>" 00203 ); 00204 /*$on*/ 00205 return httpBuf; 00206 } 00207 00208 /** 00209 * @brief 00210 * @note 00211 * @param 00212 * @retval 00213 */ 00214 void sendHTTP(TCPSocket* client, char* header, char* content) 00215 { 00216 char content_length[10] = { }; 00217 sprintf(content_length, "%u\r\n", strlen(content)); 00218 strcat(header, "\r\nContent-Type: text/html\r\n"); 00219 strcat(header, "Content-Length: "); 00220 strcat(header, content_length); 00221 strcat(header, "Pragma: no-cache\r\n"); 00222 strcat(header, "Connection: About to close\r\n\r\n"); 00223 00224 char c = content[0]; 00225 memmove(httpBuf + strlen(header), httpBuf, strlen(content)); // make room for the header 00226 strcpy(httpBuf, header); // copy the header on front of the content 00227 httpBuf[strlen(header)] = c; 00228 client->send((uint8_t*)httpBuf, strlen(httpBuf)); 00229 } 00230 00231 /** 00232 * @brief 00233 * @note 00234 * @param 00235 * @retval 00236 */ 00237 int main() 00238 { 00239 printf("starting\r\n"); 00240 00241 net = new EthernetInterface(); 00242 00243 //net->set_network("192.168.1.181","255.255.255.0","192.168.1.1"); // use static IP address, netmask, gateway 00244 if (!net) { 00245 printf("Error! No network inteface found.\n"); 00246 return 0; 00247 } 00248 00249 //net->set_network (IP, NETMASK, GATEWAY); // include this for using static IP address 00250 nsapi_size_or_error_t r = net->connect(); 00251 if (r != NSAPI_ERROR_OK) { 00252 printf("Error! net->connect() returned: %d\n", r); 00253 return r; 00254 } 00255 00256 // Show the network address 00257 SocketAddress addr; 00258 net->get_ip_address(&addr); 00259 printf("IP address: %s\n", addr.get_ip_address() ? addr.get_ip_address() : "None"); 00260 net->get_netmask(&addr); 00261 printf("Netmask: %s\n", addr.get_ip_address() ? addr.get_ip_address() : "None"); 00262 net->get_gateway(&addr); 00263 printf("Gateway: %s\n", addr.get_ip_address() ? addr.get_ip_address() : "None"); 00264 00265 /* Open the server on ethernet stack */ 00266 server.open(net); 00267 00268 /* Bind the HTTP port (TCP 80) to the server */ 00269 server.bind(PORT); 00270 00271 /* Listen for clients */ 00272 server.listen(); 00273 00274 //listening for http GET request 00275 while (true) { 00276 printf("=========================================\r\n"); 00277 printf("Ready to serve clients.\r\n"); 00278 net->get_ip_address(&addr); 00279 printf("Usage: Type http:\/\/%s\/%s\/ into your web browser and hit ENTER\r\n", addr.get_ip_address(), PASSWORD); 00280 client = server.accept(); 00281 if (client) { 00282 client->getpeername(&addr); 00283 printf("Connection succeeded!\n\rIP: %s\n\r", addr.get_ip_address()); 00284 client->recv(httpBuf, 1500); 00285 if (strncmp(httpBuf, "GET", 3) != 0) { 00286 strcpy(httpHeader, "HTTP/1.0 200 OK"); 00287 strcpy(httpBuf, "<h1>200 OK</h1>"); 00288 sendHTTP(client, httpHeader, httpBuf); 00289 } 00290 else 00291 if ((strncmp(httpBuf, "GET", 3) == 0) && (strncmp(httpBuf + 3, " / ", 3 == 0))) { 00292 strcpy(httpHeader, "HTTP/1.0 200 OK"); 00293 strcpy(httpBuf, "<p>Usage: http://host_or_ip/password</p>\r\n"); 00294 sendHTTP(client, httpHeader, httpBuf); 00295 } 00296 else { 00297 int cmd = analyseURL(httpBuf); 00298 switch (cmd) { 00299 case -3: 00300 // update webpage 00301 strcpy(httpHeader, "HTTP/1.0 200 OK"); 00302 sendHTTP(client, httpHeader, showWebPage(output)); 00303 break; 00304 00305 case -2: 00306 // redirect to the right base url 00307 strcpy(httpHeader, "HTTP/1.0 301 Moved Permanently\r\nLocation: "); 00308 sendHTTP(client, httpHeader, movedPermanently(1)); 00309 break; 00310 00311 case -1: 00312 strcpy(httpHeader, "HTTP/1.0 401 Unauthorized"); 00313 strcpy(httpBuf, "<h1>401 Unauthorized</h1>"); 00314 sendHTTP(client, httpHeader, httpBuf); 00315 break; 00316 00317 case 0: 00318 output = OFF; // output off 00319 strcpy(httpHeader, "HTTP/1.0 200 OK"); 00320 sendHTTP(client, httpHeader, showWebPage(output)); 00321 break; 00322 00323 case 1: 00324 output = ON; // output on 00325 strcpy(httpHeader, "HTTP/1.0 200 OK"); 00326 sendHTTP(client, httpHeader, showWebPage(output)); 00327 break; 00328 } 00329 } 00330 00331 client->close(); 00332 } 00333 } 00334 }
Generated on Wed Jul 13 2022 21:09:14 by 1.7.2