Zoltan Hudak / Mbed OS WebSwitch_mbed-os

Fork of WebSwitch_mbed-os by Zoltan Hudak

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers main.cpp Source File

main.cpp

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