Webserver controller with url trimming for value controls

Dependencies:   LCD_DISCO_F746NG BSP_DISCO_F746NG

Committer:
hudakz
Date:
Sat May 06 07:43:20 2017 +0000
Revision:
3:c927a415dd38
Parent:
2:33e8bb5615a6
Child:
4:d7c37f516f5f
Updated.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
hudakz 0:e455fdb56bc8 1 #include "mbed.h"
hudakz 0:e455fdb56bc8 2 #include "EthernetInterface.h"
hudakz 0:e455fdb56bc8 3 #include "TCPServer.h"
hudakz 0:e455fdb56bc8 4 #include "TCPSocket.h"
hudakz 0:e455fdb56bc8 5 #include <stdio.h>
hudakz 0:e455fdb56bc8 6 #include <string>
hudakz 0:e455fdb56bc8 7
hudakz 0:e455fdb56bc8 8 using namespace std;
hudakz 0:e455fdb56bc8 9
hudakz 0:e455fdb56bc8 10 #define PORT 80
hudakz 0:e455fdb56bc8 11
hudakz 0:e455fdb56bc8 12 EthernetInterface ethernet;
hudakz 0:e455fdb56bc8 13 TCPServer server;
hudakz 0:e455fdb56bc8 14 TCPSocket clientSocket;
hudakz 0:e455fdb56bc8 15 SocketAddress clientAddress;
hudakz 0:e455fdb56bc8 16 char receiveBuf[1024] = { };
hudakz 0:e455fdb56bc8 17
hudakz 0:e455fdb56bc8 18 const int OFF = 0;
hudakz 0:e455fdb56bc8 19 const int ON = 1;
hudakz 0:e455fdb56bc8 20
hudakz 0:e455fdb56bc8 21 DigitalOut sw(LED1);
hudakz 2:33e8bb5615a6 22 float roomTemp = 21.8; // A temperature sensor output
hudakz 0:e455fdb56bc8 23
hudakz 0:e455fdb56bc8 24 const string PASSWORD = "secret"; // change as you like
hudakz 0:e455fdb56bc8 25 const string HTTP_OK = "HTTP/1.0 200 OK";
hudakz 0:e455fdb56bc8 26 const string MOVED_PERM = "HTTP/1.0 301 Moved Permanently\r\nLocation: ";
hudakz 0:e455fdb56bc8 27 const string UNAUTHORIZED = "HTTP/1.0 401 Unauthorized";
hudakz 0:e455fdb56bc8 28 string httpHeader; // HTTP header
hudakz 0:e455fdb56bc8 29 string httpContent; // HTTP content
hudakz 2:33e8bb5615a6 30
hudakz 2:33e8bb5615a6 31 /**
hudakz 2:33e8bb5615a6 32 * @brief Defines a custom MAC address
hudakz 2:33e8bb5615a6 33 * @note Uncomment the code below to define a unique MAC address.
hudakz 2:33e8bb5615a6 34 * Modify the mac array items as needed.
hudakz 2:33e8bb5615a6 35 * @param
hudakz 2:33e8bb5615a6 36 * @retval
hudakz 2:33e8bb5615a6 37 */
hudakz 2:33e8bb5615a6 38 //extern "C" void mbed_mac_address(char* mac) {
hudakz 2:33e8bb5615a6 39 // mac[0] = 0x00;
hudakz 2:33e8bb5615a6 40 // mac[1] = 0x01;
hudakz 2:33e8bb5615a6 41 // mac[2] = 0x02;
hudakz 2:33e8bb5615a6 42 // mac[3] = 0x03;
hudakz 2:33e8bb5615a6 43 // mac[4] = 0x04;
hudakz 2:33e8bb5615a6 44 // mac[5] = 0x05;
hudakz 2:33e8bb5615a6 45 //};
hudakz 0:e455fdb56bc8 46
hudakz 2:33e8bb5615a6 47 /**
hudakz 2:33e8bb5615a6 48 * @brief Analyses the received URL
hudakz 2:33e8bb5615a6 49 * @note The string passed to this function will look like this:
hudakz 2:33e8bb5615a6 50 * GET /password HTTP/1.....
hudakz 2:33e8bb5615a6 51 * GET /password/ HTTP/1.....
hudakz 2:33e8bb5615a6 52 * GET /password/?sw=1 HTTP/1.....
hudakz 2:33e8bb5615a6 53 * GET /password/?sw=0 HTTP/1.....
hudakz 2:33e8bb5615a6 54 * @param url URL string
hudakz 2:33e8bb5615a6 55 * @retval -1 invalid password
hudakz 2:33e8bb5615a6 56 * -2 no command given but password valid
hudakz 2:33e8bb5615a6 57 * -3 just refresh page
hudakz 2:33e8bb5615a6 58 * 0 switch off
hudakz 2:33e8bb5615a6 59 * 1 switch on
hudakz 2:33e8bb5615a6 60 */
hudakz 2:33e8bb5615a6 61 int8_t analyseURL(string& url) {
hudakz 2:33e8bb5615a6 62 if(url.substr(5, PASSWORD.size()) != PASSWORD)
hudakz 0:e455fdb56bc8 63 return(-1);
hudakz 0:e455fdb56bc8 64
hudakz 0:e455fdb56bc8 65 uint8_t pos = 5 + PASSWORD.size();
hudakz 0:e455fdb56bc8 66
hudakz 2:33e8bb5615a6 67 if(url.substr(pos, 1) == " ")
hudakz 0:e455fdb56bc8 68 return(-2);
hudakz 0:e455fdb56bc8 69
hudakz 2:33e8bb5615a6 70 if(url.substr(pos++, 1) != "/")
hudakz 0:e455fdb56bc8 71 return(-1);
hudakz 0:e455fdb56bc8 72
hudakz 2:33e8bb5615a6 73 string cmd(url.substr(pos, 5));
hudakz 0:e455fdb56bc8 74
hudakz 0:e455fdb56bc8 75 if(cmd == "?sw=0")
hudakz 2:33e8bb5615a6 76 return(0);
hudakz 0:e455fdb56bc8 77
hudakz 0:e455fdb56bc8 78 if(cmd == "?sw=1")
hudakz 2:33e8bb5615a6 79 return(1);
hudakz 0:e455fdb56bc8 80
hudakz 0:e455fdb56bc8 81 return(-3);
hudakz 0:e455fdb56bc8 82 }
hudakz 0:e455fdb56bc8 83
hudakz 0:e455fdb56bc8 84 /**
hudakz 0:e455fdb56bc8 85 * @brief
hudakz 0:e455fdb56bc8 86 * @note
hudakz 0:e455fdb56bc8 87 * @param
hudakz 0:e455fdb56bc8 88 * @retval
hudakz 0:e455fdb56bc8 89 */
hudakz 0:e455fdb56bc8 90 string& movedPermanently(uint8_t flag) {
hudakz 0:e455fdb56bc8 91 if(flag == 1)
hudakz 0:e455fdb56bc8 92 httpContent = "/" + PASSWORD + "/";
hudakz 0:e455fdb56bc8 93 else
hudakz 0:e455fdb56bc8 94 httpContent = "";
hudakz 0:e455fdb56bc8 95
hudakz 0:e455fdb56bc8 96 httpContent += "<h1>301 Moved Permanently</h1>\r\n";
hudakz 0:e455fdb56bc8 97
hudakz 0:e455fdb56bc8 98 return(httpContent);
hudakz 0:e455fdb56bc8 99 }
hudakz 0:e455fdb56bc8 100
hudakz 0:e455fdb56bc8 101 /**
hudakz 0:e455fdb56bc8 102 * @brief
hudakz 0:e455fdb56bc8 103 * @note
hudakz 0:e455fdb56bc8 104 * @param
hudakz 0:e455fdb56bc8 105 * @retval
hudakz 0:e455fdb56bc8 106 */
hudakz 0:e455fdb56bc8 107 string& showWebPage(uint8_t status) {
hudakz 2:33e8bb5615a6 108 char roomTempStr[5];
hudakz 0:e455fdb56bc8 109
hudakz 2:33e8bb5615a6 110 //roomTemp = ds1820.read();
hudakz 2:33e8bb5615a6 111 sprintf(roomTempStr, "%3.1f", roomTemp);
hudakz 2:33e8bb5615a6 112
hudakz 2:33e8bb5615a6 113 httpContent = "<h2><a href=\".\" title=\"Click to refresh the page\">Smart Home</a></h2>";
hudakz 2:33e8bb5615a6 114 httpContent += "<pre>Temperature:\t" + string(roomTempStr) + "&deg;C\r\n</pre>";
hudakz 0:e455fdb56bc8 115
hudakz 0:e455fdb56bc8 116 if(status == ON) {
hudakz 2:33e8bb5615a6 117 httpContent += "<pre>\r\nHeating:\t<font color=#FF0000>On </font>";
hudakz 2:33e8bb5615a6 118 httpContent += " <a href=\"./?sw=0\"><button>Turn off</button></a>\r\n";
hudakz 0:e455fdb56bc8 119 }
hudakz 0:e455fdb56bc8 120 else {
hudakz 2:33e8bb5615a6 121 httpContent += "<pre>\r\nHeating:\t<font color=#999999>Off</font>";
hudakz 2:33e8bb5615a6 122 httpContent += " <a href=\"./?sw=1\"><button>Turn on</button></a>\r\n";
hudakz 0:e455fdb56bc8 123 }
hudakz 0:e455fdb56bc8 124
hudakz 0:e455fdb56bc8 125 httpContent += "</pre>\r\n";
hudakz 0:e455fdb56bc8 126 httpContent += "<hr>\r\n";
hudakz 2:33e8bb5615a6 127 httpContent += "<pre>2017 ARMmbed</pre>";
hudakz 0:e455fdb56bc8 128 return httpContent;
hudakz 0:e455fdb56bc8 129 }
hudakz 0:e455fdb56bc8 130
hudakz 0:e455fdb56bc8 131 /**
hudakz 0:e455fdb56bc8 132 * @brief
hudakz 0:e455fdb56bc8 133 * @note
hudakz 0:e455fdb56bc8 134 * @param
hudakz 0:e455fdb56bc8 135 * @retval
hudakz 0:e455fdb56bc8 136 */
hudakz 0:e455fdb56bc8 137 void sendHTTP(TCPSocket& client, string& header, string& content) {
hudakz 0:e455fdb56bc8 138 char content_length[5] = { };
hudakz 0:e455fdb56bc8 139
hudakz 0:e455fdb56bc8 140 header += "\r\nContent-Type: text/html\r\n";
hudakz 0:e455fdb56bc8 141 header += "Content-Length: ";
hudakz 0:e455fdb56bc8 142 sprintf(content_length, "%d", content.length());
hudakz 0:e455fdb56bc8 143 header += string(content_length) + "\r\n";
hudakz 0:e455fdb56bc8 144 header += "Pragma: no-cache\r\n";
hudakz 0:e455fdb56bc8 145 header += "Connection: About to close\r\n";
hudakz 0:e455fdb56bc8 146 header += "\r\n";
hudakz 0:e455fdb56bc8 147
hudakz 0:e455fdb56bc8 148 string webpage = header + content;
hudakz 0:e455fdb56bc8 149 client.send((char*)webpage.c_str(), webpage.length());
hudakz 0:e455fdb56bc8 150 printf("HTTP sent.\n\r");
hudakz 0:e455fdb56bc8 151 }
hudakz 0:e455fdb56bc8 152
hudakz 0:e455fdb56bc8 153 /**
hudakz 0:e455fdb56bc8 154 * @brief
hudakz 0:e455fdb56bc8 155 * @note
hudakz 0:e455fdb56bc8 156 * @param
hudakz 0:e455fdb56bc8 157 * @retval
hudakz 0:e455fdb56bc8 158 */
hudakz 0:e455fdb56bc8 159 int main(void) {
hudakz 3:c927a415dd38 160 //ethernet.set_network("192.168.1.181","255.255.255.0","192.168.1.1"); // use static IP address (IP address, netmask, gateway)
hudakz 0:e455fdb56bc8 161 ethernet.connect();
hudakz 0:e455fdb56bc8 162 printf("Usage: Type %s/%s/ into your web browser and hit ENTER\r\n", ethernet.get_ip_address(), PASSWORD);
hudakz 0:e455fdb56bc8 163
hudakz 0:e455fdb56bc8 164 /* Open the server on ethernet stack */
hudakz 0:e455fdb56bc8 165 server.open(&ethernet);
hudakz 0:e455fdb56bc8 166
hudakz 0:e455fdb56bc8 167 /* Bind the HTTP port (TCP 80) to the server */
hudakz 0:e455fdb56bc8 168 server.bind(ethernet.get_ip_address(), 80);
hudakz 0:e455fdb56bc8 169
hudakz 0:e455fdb56bc8 170 /* Can handle 5 simultaneous connections */
hudakz 0:e455fdb56bc8 171 server.listen(5);
hudakz 0:e455fdb56bc8 172
hudakz 0:e455fdb56bc8 173 //listening for http GET request
hudakz 0:e455fdb56bc8 174 while(true) {
hudakz 2:33e8bb5615a6 175 printf("\r\n=========================================\r\n");
hudakz 2:33e8bb5615a6 176 printf("Ready to serve clients.\r\n");
hudakz 0:e455fdb56bc8 177 server.accept(&clientSocket, &clientAddress);
hudakz 0:e455fdb56bc8 178 printf("Connection succeeded!\n\rIP: %s\n\r", clientAddress.get_ip_address());
hudakz 0:e455fdb56bc8 179 clientSocket.recv(receiveBuf, 1023);
hudakz 0:e455fdb56bc8 180 printf("Recieved Data: %d\n\r\n\r%.*s\n\r", strlen(receiveBuf), strlen(receiveBuf), receiveBuf);
hudakz 0:e455fdb56bc8 181
hudakz 0:e455fdb56bc8 182 string received(receiveBuf);
hudakz 2:33e8bb5615a6 183
hudakz 0:e455fdb56bc8 184 if(received.substr(0, 3) != "GET") {
hudakz 0:e455fdb56bc8 185 httpHeader = HTTP_OK;
hudakz 0:e455fdb56bc8 186 httpContent = "<h1>200 OK</h1>";
hudakz 0:e455fdb56bc8 187 sendHTTP(clientSocket, httpHeader, httpContent);
hudakz 0:e455fdb56bc8 188 continue;
hudakz 0:e455fdb56bc8 189 }
hudakz 0:e455fdb56bc8 190
hudakz 0:e455fdb56bc8 191 if(received.substr(0, 6) == "GET / ") {
hudakz 0:e455fdb56bc8 192 httpHeader = HTTP_OK;
hudakz 0:e455fdb56bc8 193 httpContent = "<p>Usage: Type http://ip_address/password/ into your web browser and hit ENTER</p>\r\n";
hudakz 0:e455fdb56bc8 194 sendHTTP(clientSocket, httpHeader, httpContent);
hudakz 0:e455fdb56bc8 195 continue;
hudakz 0:e455fdb56bc8 196 }
hudakz 0:e455fdb56bc8 197
hudakz 0:e455fdb56bc8 198 int cmd = analyseURL(received);
hudakz 0:e455fdb56bc8 199
hudakz 0:e455fdb56bc8 200 if(cmd == -2) {
hudakz 0:e455fdb56bc8 201
hudakz 0:e455fdb56bc8 202 // redirect to the right base url
hudakz 0:e455fdb56bc8 203 httpHeader = MOVED_PERM;
hudakz 0:e455fdb56bc8 204 sendHTTP(clientSocket, httpHeader, movedPermanently(1));
hudakz 0:e455fdb56bc8 205 continue;
hudakz 0:e455fdb56bc8 206 }
hudakz 0:e455fdb56bc8 207
hudakz 0:e455fdb56bc8 208 if(cmd == -1) {
hudakz 0:e455fdb56bc8 209 httpHeader = UNAUTHORIZED;
hudakz 0:e455fdb56bc8 210 httpContent = "<h1>401 Unauthorized</h1>";
hudakz 0:e455fdb56bc8 211 sendHTTP(clientSocket, httpHeader, httpContent);
hudakz 0:e455fdb56bc8 212 continue;
hudakz 0:e455fdb56bc8 213 }
hudakz 0:e455fdb56bc8 214
hudakz 0:e455fdb56bc8 215 if(cmd == ON) {
hudakz 0:e455fdb56bc8 216 sw = ON; // turn the switch on
hudakz 0:e455fdb56bc8 217 }
hudakz 0:e455fdb56bc8 218
hudakz 0:e455fdb56bc8 219 if(cmd == OFF) {
hudakz 0:e455fdb56bc8 220 sw = OFF; // turn the switch off
hudakz 0:e455fdb56bc8 221 }
hudakz 0:e455fdb56bc8 222
hudakz 0:e455fdb56bc8 223 httpHeader = HTTP_OK;
hudakz 0:e455fdb56bc8 224 sendHTTP(clientSocket, httpHeader, showWebPage(sw));
hudakz 0:e455fdb56bc8 225 }
hudakz 0:e455fdb56bc8 226 }