Jack Hansdampf / Mbed OS WebSwitch_ENC28J60_GSOE

Dependencies:   UIPEthernet_GSOE

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers main.cpp Source File

main.cpp

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