Marco Oehler / Mbed OS Lab7
Committer:
oehlemar
Date:
Fri Jun 12 08:18:46 2020 +0000
Revision:
0:7c29edfbb0bb
asdf

Who changed what in which revision?

UserRevisionLine numberNew contents of line
oehlemar 0:7c29edfbb0bb 1 /*
oehlemar 0:7c29edfbb0bb 2 * HTTPServer.cpp
oehlemar 0:7c29edfbb0bb 3 * Copyright (c) 2020, ZHAW
oehlemar 0:7c29edfbb0bb 4 * All rights reserved.
oehlemar 0:7c29edfbb0bb 5 */
oehlemar 0:7c29edfbb0bb 6
oehlemar 0:7c29edfbb0bb 7 #include <algorithm>
oehlemar 0:7c29edfbb0bb 8 #include "HTTPScript.h"
oehlemar 0:7c29edfbb0bb 9 #include "HTTPServer.h"
oehlemar 0:7c29edfbb0bb 10
oehlemar 0:7c29edfbb0bb 11 using namespace std;
oehlemar 0:7c29edfbb0bb 12
oehlemar 0:7c29edfbb0bb 13 inline string int2String(int i) {
oehlemar 0:7c29edfbb0bb 14
oehlemar 0:7c29edfbb0bb 15 char buffer[32];
oehlemar 0:7c29edfbb0bb 16 sprintf(buffer, "%d", i);
oehlemar 0:7c29edfbb0bb 17
oehlemar 0:7c29edfbb0bb 18 return string(buffer);
oehlemar 0:7c29edfbb0bb 19 }
oehlemar 0:7c29edfbb0bb 20
oehlemar 0:7c29edfbb0bb 21 const unsigned int HTTPServer::INPUT_BUFFER_SIZE = 1024; // size of receive buffer, given in [bytes]
oehlemar 0:7c29edfbb0bb 22 const int HTTPServer::SOCKET_TIMEOUT = 1000; // timeout of socket, given in [ms]
oehlemar 0:7c29edfbb0bb 23
oehlemar 0:7c29edfbb0bb 24 /**
oehlemar 0:7c29edfbb0bb 25 * Create and initialize an http server object.
oehlemar 0:7c29edfbb0bb 26 * @param ethernet a reference to the embedded TCP/IP stack to use.
oehlemar 0:7c29edfbb0bb 27 */
oehlemar 0:7c29edfbb0bb 28 HTTPServer::HTTPServer(EthernetInterface& ethernet) : ethernet(ethernet), thread(osPriorityNormal, STACK_SIZE) {
oehlemar 0:7c29edfbb0bb 29
oehlemar 0:7c29edfbb0bb 30 // start thread
oehlemar 0:7c29edfbb0bb 31
oehlemar 0:7c29edfbb0bb 32 thread.start(callback(this, &HTTPServer::run));
oehlemar 0:7c29edfbb0bb 33 }
oehlemar 0:7c29edfbb0bb 34
oehlemar 0:7c29edfbb0bb 35 /**
oehlemar 0:7c29edfbb0bb 36 * Delete the http server object.
oehlemar 0:7c29edfbb0bb 37 */
oehlemar 0:7c29edfbb0bb 38 HTTPServer::~HTTPServer() {}
oehlemar 0:7c29edfbb0bb 39
oehlemar 0:7c29edfbb0bb 40 /**
oehlemar 0:7c29edfbb0bb 41 * Registers the given script with the http server.
oehlemar 0:7c29edfbb0bb 42 * This allows to call a method of this script object
oehlemar 0:7c29edfbb0bb 43 * through virtual cgi-bin requests from a remote system.
oehlemar 0:7c29edfbb0bb 44 */
oehlemar 0:7c29edfbb0bb 45 void HTTPServer::add(string name, HTTPScript* httpScript) {
oehlemar 0:7c29edfbb0bb 46
oehlemar 0:7c29edfbb0bb 47 httpScriptNames.push_back(name);
oehlemar 0:7c29edfbb0bb 48 httpScripts.push_back(httpScript);
oehlemar 0:7c29edfbb0bb 49 }
oehlemar 0:7c29edfbb0bb 50
oehlemar 0:7c29edfbb0bb 51 /**
oehlemar 0:7c29edfbb0bb 52 * Decodes a given URL string into a standard text string.
oehlemar 0:7c29edfbb0bb 53 */
oehlemar 0:7c29edfbb0bb 54 string HTTPServer::urlDecoder(string url) {
oehlemar 0:7c29edfbb0bb 55
oehlemar 0:7c29edfbb0bb 56 size_t pos = 0;
oehlemar 0:7c29edfbb0bb 57 while ((pos = url.find("+")) != string::npos) url = url.substr(0, pos)+" "+url.substr(pos+1);
oehlemar 0:7c29edfbb0bb 58 while ((pos = url.find("%08")) != string::npos) url = url.substr(0, pos)+"\b"+url.substr(pos+3);
oehlemar 0:7c29edfbb0bb 59 while ((pos = url.find("%09")) != string::npos) url = url.substr(0, pos)+"\t"+url.substr(pos+3);
oehlemar 0:7c29edfbb0bb 60 while ((pos = url.find("%0A")) != string::npos) url = url.substr(0, pos)+"\n"+url.substr(pos+3);
oehlemar 0:7c29edfbb0bb 61 while ((pos = url.find("%0D")) != string::npos) url = url.substr(0, pos)+"\r"+url.substr(pos+3);
oehlemar 0:7c29edfbb0bb 62 while ((pos = url.find("%20")) != string::npos) url = url.substr(0, pos)+" "+url.substr(pos+3);
oehlemar 0:7c29edfbb0bb 63 while ((pos = url.find("%22")) != string::npos) url = url.substr(0, pos)+"\""+url.substr(pos+3);
oehlemar 0:7c29edfbb0bb 64 while ((pos = url.find("%23")) != string::npos) url = url.substr(0, pos)+"#"+url.substr(pos+3);
oehlemar 0:7c29edfbb0bb 65 while ((pos = url.find("%24")) != string::npos) url = url.substr(0, pos)+"$"+url.substr(pos+3);
oehlemar 0:7c29edfbb0bb 66 while ((pos = url.find("%25")) != string::npos) url = url.substr(0, pos)+"%"+url.substr(pos+3);
oehlemar 0:7c29edfbb0bb 67 while ((pos = url.find("%26")) != string::npos) url = url.substr(0, pos)+"&"+url.substr(pos+3);
oehlemar 0:7c29edfbb0bb 68 while ((pos = url.find("%2B")) != string::npos) url = url.substr(0, pos)+"+"+url.substr(pos+3);
oehlemar 0:7c29edfbb0bb 69 while ((pos = url.find("%2C")) != string::npos) url = url.substr(0, pos)+","+url.substr(pos+3);
oehlemar 0:7c29edfbb0bb 70 while ((pos = url.find("%2F")) != string::npos) url = url.substr(0, pos)+"/"+url.substr(pos+3);
oehlemar 0:7c29edfbb0bb 71 while ((pos = url.find("%3A")) != string::npos) url = url.substr(0, pos)+":"+url.substr(pos+3);
oehlemar 0:7c29edfbb0bb 72 while ((pos = url.find("%3B")) != string::npos) url = url.substr(0, pos)+";"+url.substr(pos+3);
oehlemar 0:7c29edfbb0bb 73 while ((pos = url.find("%3C")) != string::npos) url = url.substr(0, pos)+"<"+url.substr(pos+3);
oehlemar 0:7c29edfbb0bb 74 while ((pos = url.find("%3D")) != string::npos) url = url.substr(0, pos)+"="+url.substr(pos+3);
oehlemar 0:7c29edfbb0bb 75 while ((pos = url.find("%3E")) != string::npos) url = url.substr(0, pos)+">"+url.substr(pos+3);
oehlemar 0:7c29edfbb0bb 76 while ((pos = url.find("%3F")) != string::npos) url = url.substr(0, pos)+"?"+url.substr(pos+3);
oehlemar 0:7c29edfbb0bb 77 while ((pos = url.find("%40")) != string::npos) url = url.substr(0, pos)+"@"+url.substr(pos+3);
oehlemar 0:7c29edfbb0bb 78
oehlemar 0:7c29edfbb0bb 79 return url;
oehlemar 0:7c29edfbb0bb 80 }
oehlemar 0:7c29edfbb0bb 81
oehlemar 0:7c29edfbb0bb 82 /**
oehlemar 0:7c29edfbb0bb 83 * This <code>run()</code> method binds the TCP/IP server to a given port number
oehlemar 0:7c29edfbb0bb 84 * and enters an infinite loop that waits for http requests and then processes
oehlemar 0:7c29edfbb0bb 85 * these requests and returns a response.
oehlemar 0:7c29edfbb0bb 86 */
oehlemar 0:7c29edfbb0bb 87 void HTTPServer::run() {
oehlemar 0:7c29edfbb0bb 88
oehlemar 0:7c29edfbb0bb 89 // bind the server to a given port number
oehlemar 0:7c29edfbb0bb 90
oehlemar 0:7c29edfbb0bb 91 server.open(&ethernet);
oehlemar 0:7c29edfbb0bb 92 server.bind(PORT_NUMBER);
oehlemar 0:7c29edfbb0bb 93 server.listen();
oehlemar 0:7c29edfbb0bb 94
oehlemar 0:7c29edfbb0bb 95 // enter infinite loop
oehlemar 0:7c29edfbb0bb 96
oehlemar 0:7c29edfbb0bb 97 while (true) {
oehlemar 0:7c29edfbb0bb 98
oehlemar 0:7c29edfbb0bb 99 TCPSocket* client = server.accept();
oehlemar 0:7c29edfbb0bb 100 if (client != NULL) {
oehlemar 0:7c29edfbb0bb 101
oehlemar 0:7c29edfbb0bb 102 client->set_blocking(true);
oehlemar 0:7c29edfbb0bb 103 client->set_timeout(SOCKET_TIMEOUT); // set timeout of socket
oehlemar 0:7c29edfbb0bb 104
oehlemar 0:7c29edfbb0bb 105 // read input
oehlemar 0:7c29edfbb0bb 106
oehlemar 0:7c29edfbb0bb 107 char buffer[INPUT_BUFFER_SIZE];
oehlemar 0:7c29edfbb0bb 108 int size = client->recv(buffer, sizeof(buffer));
oehlemar 0:7c29edfbb0bb 109
oehlemar 0:7c29edfbb0bb 110 if (size > 0) {
oehlemar 0:7c29edfbb0bb 111
oehlemar 0:7c29edfbb0bb 112 string input(buffer, size);
oehlemar 0:7c29edfbb0bb 113 string header;
oehlemar 0:7c29edfbb0bb 114 string output;
oehlemar 0:7c29edfbb0bb 115
oehlemar 0:7c29edfbb0bb 116 // parse input
oehlemar 0:7c29edfbb0bb 117
oehlemar 0:7c29edfbb0bb 118 if ((input.find("GET") == 0) || (input.find("HEAD") == 0)) {
oehlemar 0:7c29edfbb0bb 119
oehlemar 0:7c29edfbb0bb 120 if (input.find("cgi-bin") != string::npos) {
oehlemar 0:7c29edfbb0bb 121
oehlemar 0:7c29edfbb0bb 122 // process script request with arguments
oehlemar 0:7c29edfbb0bb 123
oehlemar 0:7c29edfbb0bb 124 string script = input.substr(input.find("cgi-bin/")+8, input.find(" ", input.find("cgi-bin/")+8)-input.find("cgi-bin/")-8);
oehlemar 0:7c29edfbb0bb 125 string name;
oehlemar 0:7c29edfbb0bb 126 vector<string> names;
oehlemar 0:7c29edfbb0bb 127 vector<string> values;
oehlemar 0:7c29edfbb0bb 128
oehlemar 0:7c29edfbb0bb 129 if (script.find("?") != string::npos) {
oehlemar 0:7c29edfbb0bb 130
oehlemar 0:7c29edfbb0bb 131 name = script.substr(0, script.find("?"));
oehlemar 0:7c29edfbb0bb 132 script = script.substr(script.find("?")+1);
oehlemar 0:7c29edfbb0bb 133
oehlemar 0:7c29edfbb0bb 134 vector<string> arguments;
oehlemar 0:7c29edfbb0bb 135 while (script.find("&") != string::npos) {
oehlemar 0:7c29edfbb0bb 136 arguments.push_back(script.substr(0, script.find("&")));
oehlemar 0:7c29edfbb0bb 137 script = script.substr(script.find("&")+1);
oehlemar 0:7c29edfbb0bb 138 }
oehlemar 0:7c29edfbb0bb 139 arguments.push_back(script);
oehlemar 0:7c29edfbb0bb 140
oehlemar 0:7c29edfbb0bb 141 for (int i = 0; i < arguments.size(); i++) {
oehlemar 0:7c29edfbb0bb 142
oehlemar 0:7c29edfbb0bb 143 if (arguments[i].find("=") != string::npos) {
oehlemar 0:7c29edfbb0bb 144
oehlemar 0:7c29edfbb0bb 145 names.push_back(arguments[i].substr(0, arguments[i].find("=")));
oehlemar 0:7c29edfbb0bb 146 values.push_back(urlDecoder(arguments[i].substr(arguments[i].find("=")+1)));
oehlemar 0:7c29edfbb0bb 147
oehlemar 0:7c29edfbb0bb 148 } else {
oehlemar 0:7c29edfbb0bb 149
oehlemar 0:7c29edfbb0bb 150 names.push_back(arguments[i]);
oehlemar 0:7c29edfbb0bb 151 values.push_back("");
oehlemar 0:7c29edfbb0bb 152 }
oehlemar 0:7c29edfbb0bb 153 }
oehlemar 0:7c29edfbb0bb 154
oehlemar 0:7c29edfbb0bb 155 } else {
oehlemar 0:7c29edfbb0bb 156
oehlemar 0:7c29edfbb0bb 157 name = script;
oehlemar 0:7c29edfbb0bb 158 }
oehlemar 0:7c29edfbb0bb 159
oehlemar 0:7c29edfbb0bb 160 // look for corresponding script
oehlemar 0:7c29edfbb0bb 161
oehlemar 0:7c29edfbb0bb 162 for (int i = 0; i < min(httpScriptNames.size(), httpScripts.size()); i++) {
oehlemar 0:7c29edfbb0bb 163
oehlemar 0:7c29edfbb0bb 164 if (httpScriptNames[i].compare(name) == 0) {
oehlemar 0:7c29edfbb0bb 165
oehlemar 0:7c29edfbb0bb 166 output = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n";
oehlemar 0:7c29edfbb0bb 167 output += "<!DOCTYPE html>\r\n";
oehlemar 0:7c29edfbb0bb 168 output += "<html xmlns=\"http://www.w3.org/1999/xhtml\" xml:lang=\"en\" lang=\"en\">\r\n";
oehlemar 0:7c29edfbb0bb 169 output += "<body>\r\n";
oehlemar 0:7c29edfbb0bb 170 output += httpScripts[i]->call(names, values);
oehlemar 0:7c29edfbb0bb 171 output += "</body>\r\n";
oehlemar 0:7c29edfbb0bb 172 output += "</html>\r\n";
oehlemar 0:7c29edfbb0bb 173
oehlemar 0:7c29edfbb0bb 174 header = "HTTP/1.1 200 OK\r\n";
oehlemar 0:7c29edfbb0bb 175 header += "Content-Length: "+int2String(output.size())+"\r\n";
oehlemar 0:7c29edfbb0bb 176 header += "Content-Type: text/xml\r\n";
oehlemar 0:7c29edfbb0bb 177 header += "Expires: 0\r\n";
oehlemar 0:7c29edfbb0bb 178 header += "\r\n";
oehlemar 0:7c29edfbb0bb 179
oehlemar 0:7c29edfbb0bb 180 output = header+output;
oehlemar 0:7c29edfbb0bb 181 }
oehlemar 0:7c29edfbb0bb 182 }
oehlemar 0:7c29edfbb0bb 183
oehlemar 0:7c29edfbb0bb 184 // requested script was not found on this server
oehlemar 0:7c29edfbb0bb 185
oehlemar 0:7c29edfbb0bb 186 if ((output).size() == 0) {
oehlemar 0:7c29edfbb0bb 187
oehlemar 0:7c29edfbb0bb 188 output = "<!DOCTYPE html>\r\n";
oehlemar 0:7c29edfbb0bb 189 output += "<html lang=\"en\">\r\n";
oehlemar 0:7c29edfbb0bb 190 output += "<head>\r\n";
oehlemar 0:7c29edfbb0bb 191 output += " <title>404 Not Found</title>\r\n";
oehlemar 0:7c29edfbb0bb 192 output += " <style type=\"text/css\">\r\n";
oehlemar 0:7c29edfbb0bb 193 output += " h2 {font-family:Helvetica,Arial,sans-serif; font-size: 24; color:#FFFFFF;}\r\n";
oehlemar 0:7c29edfbb0bb 194 output += " p {font-family:Helvetica,Arial,sans-serif; font-size: 14; color:#444444;}\r\n";
oehlemar 0:7c29edfbb0bb 195 output += " </style>\r\n";
oehlemar 0:7c29edfbb0bb 196 output += "</head>\r\n";
oehlemar 0:7c29edfbb0bb 197 output += "<body leftmargin=\"0\" topmargin=\"0\" marginwidth=\"0\" marginheight=\"0\">\r\n";
oehlemar 0:7c29edfbb0bb 198 output += " <table width=\"100%\" height=\"100%\" border=\"0\" frame=\"void\" cellspacing=\"0\" cellpadding=\"20\">\r\n";
oehlemar 0:7c29edfbb0bb 199 output += " <tr>\r\n";
oehlemar 0:7c29edfbb0bb 200 output += " <th width=\"100%\" height=\"30\" bgcolor=\"#0064A6\"><h2>400 Bad Request</h2></th>\r\n";
oehlemar 0:7c29edfbb0bb 201 output += " </tr>\r\n";
oehlemar 0:7c29edfbb0bb 202 output += " <tr>\r\n";
oehlemar 0:7c29edfbb0bb 203 output += " <td valign=\"top\">\r\n";
oehlemar 0:7c29edfbb0bb 204 output += " <p>The requested script could not be found on this server!</p>\r\n";
oehlemar 0:7c29edfbb0bb 205 output += " </td>\r\n";
oehlemar 0:7c29edfbb0bb 206 output += " </tr>\r\n";
oehlemar 0:7c29edfbb0bb 207 output += " </table>\r\n";
oehlemar 0:7c29edfbb0bb 208 output += "</body>\r\n";
oehlemar 0:7c29edfbb0bb 209 output += "</html>\r\n";
oehlemar 0:7c29edfbb0bb 210
oehlemar 0:7c29edfbb0bb 211 header = "HTTP/1.1 404 Not Found\r\n";
oehlemar 0:7c29edfbb0bb 212 header += "Content-Length: "+int2String(output.size())+"\r\n";
oehlemar 0:7c29edfbb0bb 213 header += "Content-Type: text/html\r\n";
oehlemar 0:7c29edfbb0bb 214 header += "\r\n";
oehlemar 0:7c29edfbb0bb 215
oehlemar 0:7c29edfbb0bb 216 output = header+output;
oehlemar 0:7c29edfbb0bb 217 }
oehlemar 0:7c29edfbb0bb 218
oehlemar 0:7c29edfbb0bb 219 // write output
oehlemar 0:7c29edfbb0bb 220
oehlemar 0:7c29edfbb0bb 221 void* address = (void*)(output).c_str();
oehlemar 0:7c29edfbb0bb 222 int offset = 0;
oehlemar 0:7c29edfbb0bb 223 while (offset < (output).size()) offset += client->send((void*)(static_cast<int>(reinterpret_cast<intptr_t>(address))+offset), (output).size()-offset);
oehlemar 0:7c29edfbb0bb 224
oehlemar 0:7c29edfbb0bb 225 } else {
oehlemar 0:7c29edfbb0bb 226
oehlemar 0:7c29edfbb0bb 227 // transmit static file
oehlemar 0:7c29edfbb0bb 228
oehlemar 0:7c29edfbb0bb 229 output = "<!DOCTYPE html>\r\n";
oehlemar 0:7c29edfbb0bb 230 output += "<html lang=\"en\">\r\n";
oehlemar 0:7c29edfbb0bb 231 output += "<head>\r\n";
oehlemar 0:7c29edfbb0bb 232 output += " <meta charset=\"utf-8\"/>\r\n";
oehlemar 0:7c29edfbb0bb 233 output += " <title>Sensor Fusion</title>\r\n";
oehlemar 0:7c29edfbb0bb 234 output += " <style type=\"text/css\">\r\n";
oehlemar 0:7c29edfbb0bb 235 output += " html {background-color: #223344;}\r\n";
oehlemar 0:7c29edfbb0bb 236 output += " h2 {font-family:Helvetica,Arial,sans-serif; font-size: 24; color:#FFFFFF;}\r\n";
oehlemar 0:7c29edfbb0bb 237 output += " p, td {font-family:Helvetica,Arial,sans-serif; font-size: 16; color:#EEEEEE;}\r\n";
oehlemar 0:7c29edfbb0bb 238 output += " </style>\r\n";
oehlemar 0:7c29edfbb0bb 239 output += "</head>\r\n";
oehlemar 0:7c29edfbb0bb 240 output += "<body leftmargin=\"0\" topmargin=\"0\" marginwidth=\"0\" marginheight=\"0\">\r\n";
oehlemar 0:7c29edfbb0bb 241 output += " <script type=\"text/javascript\">\r\n";
oehlemar 0:7c29edfbb0bb 242 output += " var tiltAngleA = [];\r\n";
oehlemar 0:7c29edfbb0bb 243 output += " var tiltAngleG = [];\r\n";
oehlemar 0:7c29edfbb0bb 244 output += " var tiltAngleK = [];\r\n";
oehlemar 0:7c29edfbb0bb 245 output += " var tiltAngleC = [];\r\n";
oehlemar 0:7c29edfbb0bb 246 output += " var xmlhttp = null;\r\n";
oehlemar 0:7c29edfbb0bb 247 output += " var task = window.setInterval(\"update()\", 50);\r\n";
oehlemar 0:7c29edfbb0bb 248 output += " function update() {\r\n";
oehlemar 0:7c29edfbb0bb 249 output += " if (window.XMLHttpRequest) {\r\n";
oehlemar 0:7c29edfbb0bb 250 output += " xmlhttp = new XMLHttpRequest();\r\n";
oehlemar 0:7c29edfbb0bb 251 output += " } else if (window.ActiveXObject) {\r\n";
oehlemar 0:7c29edfbb0bb 252 output += " try {\r\n";
oehlemar 0:7c29edfbb0bb 253 output += " xmlhttp = new ActiveXObject(\"Msxml2.XMLHTTP\");\r\n";
oehlemar 0:7c29edfbb0bb 254 output += " } catch (exception) {\r\n";
oehlemar 0:7c29edfbb0bb 255 output += " try {\r\n";
oehlemar 0:7c29edfbb0bb 256 output += " xmlhttp = new ActiveXObject(\"Microsoft.XMLHTTP\");\r\n";
oehlemar 0:7c29edfbb0bb 257 output += " } catch (exception) {}\r\n";
oehlemar 0:7c29edfbb0bb 258 output += " }\r\n";
oehlemar 0:7c29edfbb0bb 259 output += " }\r\n";
oehlemar 0:7c29edfbb0bb 260 output += " xmlhttp.onreadystatechange = refresh;\r\n";
oehlemar 0:7c29edfbb0bb 261 output += " xmlhttp.open(\"GET\", \"/cgi-bin/tiltAngle\");\r\n";
oehlemar 0:7c29edfbb0bb 262 output += " xmlhttp.send(null);\r\n";
oehlemar 0:7c29edfbb0bb 263 output += " }\r\n";
oehlemar 0:7c29edfbb0bb 264 output += " function refresh() {\r\n";
oehlemar 0:7c29edfbb0bb 265 output += " if (xmlhttp.readyState == 4) {\r\n";
oehlemar 0:7c29edfbb0bb 266 output += " var xml = xmlhttp.responseXML;\r\n";
oehlemar 0:7c29edfbb0bb 267 output += " var floatValues = xml.getElementsByTagName(\"float\");\r\n";
oehlemar 0:7c29edfbb0bb 268 output += " tiltAngleA.push(floatValues[0].childNodes[0].nodeValue/Math.PI*180.0); if (tiltAngleA.length > 400) tiltAngleA.shift();\r\n";
oehlemar 0:7c29edfbb0bb 269 output += " tiltAngleG.push(floatValues[1].childNodes[0].nodeValue/Math.PI*180.0); if (tiltAngleG.length > 400) tiltAngleG.shift();\r\n";
oehlemar 0:7c29edfbb0bb 270 output += " tiltAngleK.push(floatValues[2].childNodes[0].nodeValue/Math.PI*180.0); if (tiltAngleK.length > 400) tiltAngleK.shift();\r\n";
oehlemar 0:7c29edfbb0bb 271 output += " tiltAngleC.push(floatValues[3].childNodes[0].nodeValue/Math.PI*180.0); if (tiltAngleC.length > 400) tiltAngleC.shift();\r\n";
oehlemar 0:7c29edfbb0bb 272 output += " drawPlot(\"tiltAngle\", tiltAngleA, tiltAngleG, tiltAngleK, tiltAngleC, \"°\");\r\n";
oehlemar 0:7c29edfbb0bb 273 output += " }\r\n";
oehlemar 0:7c29edfbb0bb 274 output += " }\r\n";
oehlemar 0:7c29edfbb0bb 275 output += " function drawPlot(id, value0, value1, value2, value3, valueUnit) {\r\n";
oehlemar 0:7c29edfbb0bb 276 output += " var canvas = document.getElementById(id);\r\n";
oehlemar 0:7c29edfbb0bb 277 output += " var width = window.innerWidth-50;\r\n";
oehlemar 0:7c29edfbb0bb 278 output += " var height = window.innerHeight-50;\r\n";
oehlemar 0:7c29edfbb0bb 279 output += " canvas.width = 2*width;\r\n";
oehlemar 0:7c29edfbb0bb 280 output += " canvas.height = 2*height;\r\n";
oehlemar 0:7c29edfbb0bb 281 output += " canvas.style.width = width+\"px\";\r\n";
oehlemar 0:7c29edfbb0bb 282 output += " canvas.style.height = height+\"px\";\r\n";
oehlemar 0:7c29edfbb0bb 283 output += " var ctx = canvas.getContext(\"2d\");\r\n";
oehlemar 0:7c29edfbb0bb 284 output += " ctx.scale(2,2);\r\n";
oehlemar 0:7c29edfbb0bb 285 output += " ctx.fillStyle = \"#334455\";\r\n";
oehlemar 0:7c29edfbb0bb 286 output += " ctx.fillRect(0.5, 0.5, width-1, height-1);\r\n";
oehlemar 0:7c29edfbb0bb 287 output += " var valueMin = value0[0];\r\n";
oehlemar 0:7c29edfbb0bb 288 output += " var valueMax = value0[0];\r\n";
oehlemar 0:7c29edfbb0bb 289 output += " for (i = 0; i < Math.min(Math.min(value0.length, value1.length), value2.length); i++) {\r\n";
oehlemar 0:7c29edfbb0bb 290 output += " valueMin = Math.min(valueMin, Math.min(value0[i], Math.min(value1[i], Math.min(value2[i], value3[i]))));\r\n";
oehlemar 0:7c29edfbb0bb 291 output += " valueMax = Math.max(valueMax, Math.max(value0[i], Math.max(value1[i], Math.max(value2[i], value3[i]))));\r\n";
oehlemar 0:7c29edfbb0bb 292 output += " }\r\n";
oehlemar 0:7c29edfbb0bb 293 output += " if (valueMax-valueMin < 2.0/Math.pow(10.0, 3)) {\r\n";
oehlemar 0:7c29edfbb0bb 294 output += " var valueMean = (valueMin+valueMax)/2.0;\r\n";
oehlemar 0:7c29edfbb0bb 295 output += " valueMin = valueMean-1.0/Math.pow(10.0, 3);\r\n";
oehlemar 0:7c29edfbb0bb 296 output += " valueMax = valueMean+1.0/Math.pow(10.0, 3);\r\n";
oehlemar 0:7c29edfbb0bb 297 output += " }\r\n";
oehlemar 0:7c29edfbb0bb 298 output += " var valueStep = (valueMax-valueMin)/(height/100); if (valueStep < 1.0/Math.pow(10.0, 3)) valueStep = 1.0/Math.pow(10.0, 3);\r\n";
oehlemar 0:7c29edfbb0bb 299 output += " var valueGain = Math.pow(10.0, Math.floor(Math.log(valueStep)/Math.log(10.0)));\r\n";
oehlemar 0:7c29edfbb0bb 300 output += " valueStep = valueStep/valueGain;\r\n";
oehlemar 0:7c29edfbb0bb 301 output += " if (valueStep > 5.0) valueStep = 5.0*valueGain; else if (valueStep > 2.0) valueStep = 2.0*valueGain; else valueStep = valueGain;\r\n";
oehlemar 0:7c29edfbb0bb 302 output += " valueMin = Math.floor(valueMin/valueStep-0.25)*valueStep;\r\n";
oehlemar 0:7c29edfbb0bb 303 output += " valueMax = Math.ceil(valueMax/valueStep+0.25)*valueStep;\r\n";
oehlemar 0:7c29edfbb0bb 304 output += " ctx.strokeStyle = \"#EEEEEE\";\r\n";
oehlemar 0:7c29edfbb0bb 305 output += " ctx.lineWidth = 1;\r\n";
oehlemar 0:7c29edfbb0bb 306 output += " ctx.beginPath();\r\n";
oehlemar 0:7c29edfbb0bb 307 output += " for (valueCurrent = valueMin+valueStep; valueCurrent < valueMax-valueStep/2.0; valueCurrent += valueStep) {\r\n";
oehlemar 0:7c29edfbb0bb 308 output += " ctx.moveTo(0, (valueMax-valueCurrent)/(valueMax-valueMin)*height+0.5);\r\n";
oehlemar 0:7c29edfbb0bb 309 output += " ctx.lineTo(width, (valueMax-valueCurrent)/(valueMax-valueMin)*height+0.5);\r\n";
oehlemar 0:7c29edfbb0bb 310 output += " }\r\n";
oehlemar 0:7c29edfbb0bb 311 output += " ctx.stroke();\r\n";
oehlemar 0:7c29edfbb0bb 312
oehlemar 0:7c29edfbb0bb 313 output += " ctx.font = \"normal 16px sans-serif\";\r\n";
oehlemar 0:7c29edfbb0bb 314 output += " ctx.textBaseline = \"bottom\";\r\n";
oehlemar 0:7c29edfbb0bb 315 output += " ctx.fillStyle = \"white\";\r\n";
oehlemar 0:7c29edfbb0bb 316 output += " for (valueCurrent = valueMin+valueStep; valueCurrent < valueMax-valueStep/2.0; valueCurrent += valueStep) {\r\n";
oehlemar 0:7c29edfbb0bb 317 output += " ctx.fillText(valueCurrent.toFixed(2), 10.0, (valueMax-valueCurrent)/(valueMax-valueMin)*height-5.0);\r\n";
oehlemar 0:7c29edfbb0bb 318 output += " }\r\n";
oehlemar 0:7c29edfbb0bb 319 output += " ctx.fillStyle = \"#FF0000\";\r\n";
oehlemar 0:7c29edfbb0bb 320 output += " ctx.fillText(\"Tilt Angle from Accelerometer: \"+(value0[value0.length-1]*1.0).toFixed(3)+\" [\"+valueUnit+\"]\", width/2.0, 40);\r\n";
oehlemar 0:7c29edfbb0bb 321 output += " ctx.fillStyle = \"#FFFF00\";\r\n";
oehlemar 0:7c29edfbb0bb 322 output += " ctx.fillText(\"Tilt Angle from Gyro: \"+(value1[value1.length-1]*1.0).toFixed(3)+\" [\"+valueUnit+\"]\", width/2.0, 65);\r\n";
oehlemar 0:7c29edfbb0bb 323 output += " ctx.fillStyle = \"#00FF00\";\r\n";
oehlemar 0:7c29edfbb0bb 324 output += " ctx.fillText(\"Tilt Angle from Kalman-Filter: \"+(value2[value2.length-1]*1.0).toFixed(3)+\" [\"+valueUnit+\"]\", width/2.0, 90);\r\n";
oehlemar 0:7c29edfbb0bb 325 output += " ctx.fillStyle = \"#00AA00\";\r\n";
oehlemar 0:7c29edfbb0bb 326 output += " ctx.fillText(\"Tilt Angle from Complementary Filter: \"+(value3[value3.length-1]*1.0).toFixed(3)+\" [\"+valueUnit+\"]\", width/2.0, 115);\r\n";
oehlemar 0:7c29edfbb0bb 327
oehlemar 0:7c29edfbb0bb 328 output += " ctx.strokeStyle = \"#FF0000\";\r\n";
oehlemar 0:7c29edfbb0bb 329 output += " ctx.lineWidth = 2;\r\n";
oehlemar 0:7c29edfbb0bb 330 output += " ctx.beginPath();\r\n";
oehlemar 0:7c29edfbb0bb 331 output += " ctx.moveTo(0, (valueMax-value0[0])/(valueMax-valueMin)*height+0.5);\r\n";
oehlemar 0:7c29edfbb0bb 332 output += " for (i = 1; i < value0.length; i++) {\r\n";
oehlemar 0:7c29edfbb0bb 333 output += " ctx.lineTo(i/(value0.length-1)*width, (valueMax-value0[i])/(valueMax-valueMin)*height+0.5);\r\n";
oehlemar 0:7c29edfbb0bb 334 output += " }\r\n";
oehlemar 0:7c29edfbb0bb 335 output += " ctx.stroke();\r\n";
oehlemar 0:7c29edfbb0bb 336
oehlemar 0:7c29edfbb0bb 337 output += " ctx.strokeStyle = \"#FFFF00\";\r\n";
oehlemar 0:7c29edfbb0bb 338 output += " ctx.lineWidth = 2;\r\n";
oehlemar 0:7c29edfbb0bb 339 output += " ctx.beginPath();\r\n";
oehlemar 0:7c29edfbb0bb 340 output += " ctx.moveTo(0, (valueMax-value1[0])/(valueMax-valueMin)*height+0.5);\r\n";
oehlemar 0:7c29edfbb0bb 341 output += " for (i = 1; i < value1.length; i++) {\r\n";
oehlemar 0:7c29edfbb0bb 342 output += " ctx.lineTo(i/(value1.length-1)*width, (valueMax-value1[i])/(valueMax-valueMin)*height+0.5);\r\n";
oehlemar 0:7c29edfbb0bb 343 output += " }\r\n";
oehlemar 0:7c29edfbb0bb 344 output += " ctx.stroke();\r\n";
oehlemar 0:7c29edfbb0bb 345
oehlemar 0:7c29edfbb0bb 346 output += " ctx.strokeStyle = \"#00FF00\";\r\n";
oehlemar 0:7c29edfbb0bb 347 output += " ctx.lineWidth = 2;\r\n";
oehlemar 0:7c29edfbb0bb 348 output += " ctx.beginPath();\r\n";
oehlemar 0:7c29edfbb0bb 349 output += " ctx.moveTo(0, (valueMax-value2[0])/(valueMax-valueMin)*height+0.5);\r\n";
oehlemar 0:7c29edfbb0bb 350 output += " for (i = 1; i < value2.length; i++) {\r\n";
oehlemar 0:7c29edfbb0bb 351 output += " ctx.lineTo(i/(value2.length-1)*width, (valueMax-value2[i])/(valueMax-valueMin)*height+0.5);\r\n";
oehlemar 0:7c29edfbb0bb 352 output += " }\r\n";
oehlemar 0:7c29edfbb0bb 353 output += " ctx.stroke();\r\n";
oehlemar 0:7c29edfbb0bb 354
oehlemar 0:7c29edfbb0bb 355 output += " ctx.strokeStyle = \"#00AA00\";\r\n";
oehlemar 0:7c29edfbb0bb 356 output += " ctx.lineWidth = 2;\r\n";
oehlemar 0:7c29edfbb0bb 357 output += " ctx.beginPath();\r\n";
oehlemar 0:7c29edfbb0bb 358 output += " ctx.moveTo(0, (valueMax-value3[0])/(valueMax-valueMin)*height+0.5);\r\n";
oehlemar 0:7c29edfbb0bb 359 output += " for (i = 1; i < value3.length; i++) {\r\n";
oehlemar 0:7c29edfbb0bb 360 output += " ctx.lineTo(i/(value3.length-1)*width, (valueMax-value3[i])/(valueMax-valueMin)*height+0.5);\r\n";
oehlemar 0:7c29edfbb0bb 361 output += " }\r\n";
oehlemar 0:7c29edfbb0bb 362 output += " ctx.stroke();\r\n";
oehlemar 0:7c29edfbb0bb 363
oehlemar 0:7c29edfbb0bb 364 output += " ctx.strokeStyle = \"white\";\r\n";
oehlemar 0:7c29edfbb0bb 365 output += " ctx.lineWidth = 1;\r\n";
oehlemar 0:7c29edfbb0bb 366 output += " ctx.strokeRect(0.5, 0.5, width-1, height-1);\r\n";
oehlemar 0:7c29edfbb0bb 367 output += " }\r\n";
oehlemar 0:7c29edfbb0bb 368 output += " </script>";
oehlemar 0:7c29edfbb0bb 369 output += " <table width=\"100%\" height=\"100%\" border=\"0\" frame=\"void\" cellspacing=\"20\" cellpadding=\"0\">\r\n";
oehlemar 0:7c29edfbb0bb 370 output += " <tr>\r\n";
oehlemar 0:7c29edfbb0bb 371 output += " <th><canvas id=\"tiltAngle\"></canvas></th>\r\n";
oehlemar 0:7c29edfbb0bb 372 output += " </tr>\r\n";
oehlemar 0:7c29edfbb0bb 373 output += " </table>\r\n";
oehlemar 0:7c29edfbb0bb 374 output += "</body>\r\n";
oehlemar 0:7c29edfbb0bb 375 output += "</html>\r\n";
oehlemar 0:7c29edfbb0bb 376
oehlemar 0:7c29edfbb0bb 377 header = "HTTP/1.1 404 Not Found\r\n";
oehlemar 0:7c29edfbb0bb 378 header += "Content-Length: "+int2String(output.size())+"\r\n";
oehlemar 0:7c29edfbb0bb 379 header += "Content-Type: text/html\r\n";
oehlemar 0:7c29edfbb0bb 380 header += "\r\n";
oehlemar 0:7c29edfbb0bb 381
oehlemar 0:7c29edfbb0bb 382 output = header+output;
oehlemar 0:7c29edfbb0bb 383
oehlemar 0:7c29edfbb0bb 384 // write output
oehlemar 0:7c29edfbb0bb 385
oehlemar 0:7c29edfbb0bb 386 void* address = (void*)output.c_str();
oehlemar 0:7c29edfbb0bb 387 int offset = 0;
oehlemar 0:7c29edfbb0bb 388 while (offset < output.size()) offset += client->send((void*)(static_cast<int>(reinterpret_cast<intptr_t>(address))+offset), output.size()-offset);
oehlemar 0:7c29edfbb0bb 389 }
oehlemar 0:7c29edfbb0bb 390
oehlemar 0:7c29edfbb0bb 391 } else {
oehlemar 0:7c29edfbb0bb 392
oehlemar 0:7c29edfbb0bb 393 // the http method is not known
oehlemar 0:7c29edfbb0bb 394
oehlemar 0:7c29edfbb0bb 395 output = "<!DOCTYPE html>\r\n";
oehlemar 0:7c29edfbb0bb 396 output += "<html lang=\"en\">\r\n";
oehlemar 0:7c29edfbb0bb 397 output += "<head>\r\n";
oehlemar 0:7c29edfbb0bb 398 output += " <title>400 Bad Request</title>\r\n";
oehlemar 0:7c29edfbb0bb 399 output += " <style type=\"text/css\">\r\n";
oehlemar 0:7c29edfbb0bb 400 output += " h2 {font-family:Helvetica,Arial,sans-serif; font-size: 24; color:#FFFFFF;}\r\n";
oehlemar 0:7c29edfbb0bb 401 output += " p {font-family:Helvetica,Arial,sans-serif; font-size: 14; color:#444444;}\r\n";
oehlemar 0:7c29edfbb0bb 402 output += " </style>\r\n";
oehlemar 0:7c29edfbb0bb 403 output += "</head>\r\n";
oehlemar 0:7c29edfbb0bb 404 output += "<body leftmargin=\"0\" topmargin=\"0\" marginwidth=\"0\" marginheight=\"0\">\r\n";
oehlemar 0:7c29edfbb0bb 405 output += " <table width=\"100%\" height=\"100%\" border=\"0\" frame=\"void\" cellspacing=\"0\" cellpadding=\"20\">\r\n";
oehlemar 0:7c29edfbb0bb 406 output += " <tr>\r\n";
oehlemar 0:7c29edfbb0bb 407 output += " <th width=\"100%\" height=\"30\" bgcolor=\"#0064A6\"><h2>400 Bad Request</h2></th>\r\n";
oehlemar 0:7c29edfbb0bb 408 output += " </tr>\r\n";
oehlemar 0:7c29edfbb0bb 409 output += " <tr>\r\n";
oehlemar 0:7c29edfbb0bb 410 output += " <td valign=\"top\">\r\n";
oehlemar 0:7c29edfbb0bb 411 output += " <p>The requested method is not supported by this server!</p>\r\n";
oehlemar 0:7c29edfbb0bb 412 output += " </td>\r\n";
oehlemar 0:7c29edfbb0bb 413 output += " </tr>\r\n";
oehlemar 0:7c29edfbb0bb 414 output += " </table>\r\n";
oehlemar 0:7c29edfbb0bb 415 output += "</body>\r\n";
oehlemar 0:7c29edfbb0bb 416 output += "</html>\r\n";
oehlemar 0:7c29edfbb0bb 417
oehlemar 0:7c29edfbb0bb 418 header = "HTTP/1.1 400 Bad Request\r\n";
oehlemar 0:7c29edfbb0bb 419 header += "Content-Length: "+int2String(output.size())+"\r\n";
oehlemar 0:7c29edfbb0bb 420 header += "Content-Type: text/html\r\n";
oehlemar 0:7c29edfbb0bb 421 header += "\r\n";
oehlemar 0:7c29edfbb0bb 422
oehlemar 0:7c29edfbb0bb 423 output = header+output;
oehlemar 0:7c29edfbb0bb 424
oehlemar 0:7c29edfbb0bb 425 // write output
oehlemar 0:7c29edfbb0bb 426
oehlemar 0:7c29edfbb0bb 427 void* address = (void*)output.c_str();
oehlemar 0:7c29edfbb0bb 428 int offset = 0;
oehlemar 0:7c29edfbb0bb 429 while (offset < output.size()) offset += client->send((void*)(static_cast<int>(reinterpret_cast<intptr_t>(address))+offset), output.size()-offset);
oehlemar 0:7c29edfbb0bb 430 }
oehlemar 0:7c29edfbb0bb 431 }
oehlemar 0:7c29edfbb0bb 432
oehlemar 0:7c29edfbb0bb 433 client->close();
oehlemar 0:7c29edfbb0bb 434
oehlemar 0:7c29edfbb0bb 435 } // client != NULL
oehlemar 0:7c29edfbb0bb 436
oehlemar 0:7c29edfbb0bb 437 } // infinite while loop
oehlemar 0:7c29edfbb0bb 438 }
oehlemar 0:7c29edfbb0bb 439