Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of WebSwitch_mbed-os by
main.cpp@3:c927a415dd38, 2017-05-06 (annotated)
- 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?
| User | Revision | Line number | New 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) + "°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(ðernet); |
| 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 | } |
