Suspended plotter for the skaperfest
Dependencies: mbed HTTPServer EthernetNetIf FatFileSystemCpp
HomePageHandler.cpp@0:602ff2b2d41c, 2022-08-22 (annotated)
- Committer:
- rengro01
- Date:
- Mon Aug 22 10:24:23 2022 +0000
- Revision:
- 0:602ff2b2d41c
skaperfest
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
rengro01 | 0:602ff2b2d41c | 1 | #include "HomePageHandler.hpp" |
rengro01 | 0:602ff2b2d41c | 2 | #include "mbed.h" |
rengro01 | 0:602ff2b2d41c | 3 | |
rengro01 | 0:602ff2b2d41c | 4 | #define CHUNK_SIZE 128 |
rengro01 | 0:602ff2b2d41c | 5 | |
rengro01 | 0:602ff2b2d41c | 6 | HomePageHandler::HomePageHandler(const char* rootPath, const char* path, TCPSocket* pTcpSocket) |
rengro01 | 0:602ff2b2d41c | 7 | : HTTPRequestHandler(rootPath, path, pTcpSocket) |
rengro01 | 0:602ff2b2d41c | 8 | { |
rengro01 | 0:602ff2b2d41c | 9 | } |
rengro01 | 0:602ff2b2d41c | 10 | |
rengro01 | 0:602ff2b2d41c | 11 | HomePageHandler::~HomePageHandler() |
rengro01 | 0:602ff2b2d41c | 12 | { |
rengro01 | 0:602ff2b2d41c | 13 | } |
rengro01 | 0:602ff2b2d41c | 14 | |
rengro01 | 0:602ff2b2d41c | 15 | void HomePageHandler::doGet() |
rengro01 | 0:602ff2b2d41c | 16 | { |
rengro01 | 0:602ff2b2d41c | 17 | const char* opening = |
rengro01 | 0:602ff2b2d41c | 18 | "<html>\n" |
rengro01 | 0:602ff2b2d41c | 19 | " <head>\n" |
rengro01 | 0:602ff2b2d41c | 20 | " <title>ARM MBED Plotter</title>\n" |
rengro01 | 0:602ff2b2d41c | 21 | " <style>\n" |
rengro01 | 0:602ff2b2d41c | 22 | " table {\n" |
rengro01 | 0:602ff2b2d41c | 23 | " text-align: center;\n" |
rengro01 | 0:602ff2b2d41c | 24 | " width:352px;\n" |
rengro01 | 0:602ff2b2d41c | 25 | " }\n" |
rengro01 | 0:602ff2b2d41c | 26 | " #btn {\n" |
rengro01 | 0:602ff2b2d41c | 27 | " border: 1px solid black;\n" |
rengro01 | 0:602ff2b2d41c | 28 | " background-color: powderblue;\n" |
rengro01 | 0:602ff2b2d41c | 29 | " }\n" |
rengro01 | 0:602ff2b2d41c | 30 | " td, tr {\n" |
rengro01 | 0:602ff2b2d41c | 31 | " width: 32px;\n" |
rengro01 | 0:602ff2b2d41c | 32 | " height: 32px;\n" |
rengro01 | 0:602ff2b2d41c | 33 | " }\n" |
rengro01 | 0:602ff2b2d41c | 34 | " </style>\n" |
rengro01 | 0:602ff2b2d41c | 35 | " <script>\n" |
rengro01 | 0:602ff2b2d41c | 36 | " var client;\n" |
rengro01 | 0:602ff2b2d41c | 37 | " function upload()\n" |
rengro01 | 0:602ff2b2d41c | 38 | " {\n" |
rengro01 | 0:602ff2b2d41c | 39 | " var filetag = document.getElementById('uploadfile');\n" |
rengro01 | 0:602ff2b2d41c | 40 | " var file = filetag.files[0];\n" |
rengro01 | 0:602ff2b2d41c | 41 | " if (!file) {\n" |
rengro01 | 0:602ff2b2d41c | 42 | " return;\n" |
rengro01 | 0:602ff2b2d41c | 43 | " }\n" |
rengro01 | 0:602ff2b2d41c | 44 | " client = new XMLHttpRequest();\n" |
rengro01 | 0:602ff2b2d41c | 45 | " client.open('POST', 'upload');\n" |
rengro01 | 0:602ff2b2d41c | 46 | " client.setRequestHeader('Content-Type', 'text/plain');\n" |
rengro01 | 0:602ff2b2d41c | 47 | " client.setRequestHeader('Request', 'upload');\n" |
rengro01 | 0:602ff2b2d41c | 48 | " client.setRequestHeader('X-File-Name', file.name);\n" |
rengro01 | 0:602ff2b2d41c | 49 | " client.setRequestHeader('X-File-Size', file.size);\n" |
rengro01 | 0:602ff2b2d41c | 50 | " client.send(file);\n" |
rengro01 | 0:602ff2b2d41c | 51 | " }\n" |
rengro01 | 0:602ff2b2d41c | 52 | " function plot()\n" |
rengro01 | 0:602ff2b2d41c | 53 | " {\n" |
rengro01 | 0:602ff2b2d41c | 54 | " var filetag = document.getElementById('to_plot');\n" |
rengro01 | 0:602ff2b2d41c | 55 | " var file = filetag.value;\n" |
rengro01 | 0:602ff2b2d41c | 56 | " var formData = new FormData();\n" |
rengro01 | 0:602ff2b2d41c | 57 | " formData.append('plot', file);\n" |
rengro01 | 0:602ff2b2d41c | 58 | " client = new XMLHttpRequest();\n" |
rengro01 | 0:602ff2b2d41c | 59 | " client.open('POST', 'upload');\n" |
rengro01 | 0:602ff2b2d41c | 60 | " client.setRequestHeader('Request', 'plot');\n" |
rengro01 | 0:602ff2b2d41c | 61 | " client.setRequestHeader('X-File-Name', file);\n" |
rengro01 | 0:602ff2b2d41c | 62 | " client.setRequestHeader('Content-Type', 'multipart/form-data');\n" |
rengro01 | 0:602ff2b2d41c | 63 | " client.send(formData);\n" |
rengro01 | 0:602ff2b2d41c | 64 | " }\n" |
rengro01 | 0:602ff2b2d41c | 65 | " function move(value)\n" |
rengro01 | 0:602ff2b2d41c | 66 | " {\n" |
rengro01 | 0:602ff2b2d41c | 67 | " var formData = new FormData();\n" |
rengro01 | 0:602ff2b2d41c | 68 | " formData.append('value', value);\n" |
rengro01 | 0:602ff2b2d41c | 69 | " client = new XMLHttpRequest();\n" |
rengro01 | 0:602ff2b2d41c | 70 | " client.open('POST', 'upload');\n" |
rengro01 | 0:602ff2b2d41c | 71 | " client.setRequestHeader('Request', 'move');\n" |
rengro01 | 0:602ff2b2d41c | 72 | " client.setRequestHeader('Direction', value);\n" |
rengro01 | 0:602ff2b2d41c | 73 | " client.setRequestHeader('Content-Type', 'multipart/form-data');\n" |
rengro01 | 0:602ff2b2d41c | 74 | " client.send(formData);\n" |
rengro01 | 0:602ff2b2d41c | 75 | " }\n" |
rengro01 | 0:602ff2b2d41c | 76 | " </script>\n" |
rengro01 | 0:602ff2b2d41c | 77 | " </head>\n" |
rengro01 | 0:602ff2b2d41c | 78 | " <body>\n" |
rengro01 | 0:602ff2b2d41c | 79 | " <h1>ARM MBED Plotter</h1>\n" |
rengro01 | 0:602ff2b2d41c | 80 | " <br/>\n" |
rengro01 | 0:602ff2b2d41c | 81 | " <br/>\n" |
rengro01 | 0:602ff2b2d41c | 82 | " <input name='FileSubmit' type='submit' value='Upload' onclick='upload()' />\n" |
rengro01 | 0:602ff2b2d41c | 83 | " <input type='file' id='uploadfile' name='uploadfile' />\n" |
rengro01 | 0:602ff2b2d41c | 84 | " <br/>\n" |
rengro01 | 0:602ff2b2d41c | 85 | " <br/>\n" |
rengro01 | 0:602ff2b2d41c | 86 | " <input name='FilePlot' type='submit' value='Plot' onclick='plot()' />\n" |
rengro01 | 0:602ff2b2d41c | 87 | " <select id='to_plot' name='to_plot'>\n" |
rengro01 | 0:602ff2b2d41c | 88 | ""; |
rengro01 | 0:602ff2b2d41c | 89 | |
rengro01 | 0:602ff2b2d41c | 90 | const char* closing = |
rengro01 | 0:602ff2b2d41c | 91 | " </select>\n" |
rengro01 | 0:602ff2b2d41c | 92 | " <br/>\n" |
rengro01 | 0:602ff2b2d41c | 93 | " <br/>\n" |
rengro01 | 0:602ff2b2d41c | 94 | " <table>\n" |
rengro01 | 0:602ff2b2d41c | 95 | " <tr>\n" |
rengro01 | 0:602ff2b2d41c | 96 | " <td></td>\n" |
rengro01 | 0:602ff2b2d41c | 97 | " <td id='btn' onclick='move(0)' >⇑</td>\n" |
rengro01 | 0:602ff2b2d41c | 98 | " <td></td>\n" |
rengro01 | 0:602ff2b2d41c | 99 | " <td></td>\n" |
rengro01 | 0:602ff2b2d41c | 100 | " <td id='btn' onclick='move(4)' >↰</td>\n" |
rengro01 | 0:602ff2b2d41c | 101 | " <td></td>\n" |
rengro01 | 0:602ff2b2d41c | 102 | " <td id='btn' onclick='move(6)' >⇖</td>\n" |
rengro01 | 0:602ff2b2d41c | 103 | " <td></td>\n" |
rengro01 | 0:602ff2b2d41c | 104 | " <td id='btn' onclick='move(10)'> 0 </td>\n" |
rengro01 | 0:602ff2b2d41c | 105 | " <td></td>\n" |
rengro01 | 0:602ff2b2d41c | 106 | " <td id='btn' onclick='move(9)' >⇗</td>\n" |
rengro01 | 0:602ff2b2d41c | 107 | " </tr>\n" |
rengro01 | 0:602ff2b2d41c | 108 | " <tr>\n" |
rengro01 | 0:602ff2b2d41c | 109 | " <td id='btn' onclick='move(1)' >⇐</td>\n" |
rengro01 | 0:602ff2b2d41c | 110 | " <td id='btn' onclick='move(2)' >⇓</td>\n" |
rengro01 | 0:602ff2b2d41c | 111 | " <td id='btn' onclick='move(3)' >⇒</td>\n" |
rengro01 | 0:602ff2b2d41c | 112 | " <td></td>\n" |
rengro01 | 0:602ff2b2d41c | 113 | " <td id='btn' onclick='move(5)' >↳</td>\n" |
rengro01 | 0:602ff2b2d41c | 114 | " <td></td>\n" |
rengro01 | 0:602ff2b2d41c | 115 | " <td></td>\n" |
rengro01 | 0:602ff2b2d41c | 116 | " <td id='btn' onclick='move(7)' >⇘</td>\n" |
rengro01 | 0:602ff2b2d41c | 117 | " <td></td>\n" |
rengro01 | 0:602ff2b2d41c | 118 | " <td id='btn' onclick='move(8)' >⇙</td>\n" |
rengro01 | 0:602ff2b2d41c | 119 | " <td></td>\n" |
rengro01 | 0:602ff2b2d41c | 120 | " </tr>\n" |
rengro01 | 0:602ff2b2d41c | 121 | " </table>\n" |
rengro01 | 0:602ff2b2d41c | 122 | " </body>\n" |
rengro01 | 0:602ff2b2d41c | 123 | "</html>\n"; |
rengro01 | 0:602ff2b2d41c | 124 | |
rengro01 | 0:602ff2b2d41c | 125 | m_fp = fopen("/usb/tmpidx", "w"); |
rengro01 | 0:602ff2b2d41c | 126 | |
rengro01 | 0:602ff2b2d41c | 127 | m_idx_size = 0; |
rengro01 | 0:602ff2b2d41c | 128 | for(int i=0; i<strlen(opening); i++) |
rengro01 | 0:602ff2b2d41c | 129 | { |
rengro01 | 0:602ff2b2d41c | 130 | m_idx_size += fwrite(&opening[i], 1, 1, m_fp); |
rengro01 | 0:602ff2b2d41c | 131 | } |
rengro01 | 0:602ff2b2d41c | 132 | fclose(m_fp); |
rengro01 | 0:602ff2b2d41c | 133 | m_fp = fopen("/usb/tmpidx", "a"); |
rengro01 | 0:602ff2b2d41c | 134 | |
rengro01 | 0:602ff2b2d41c | 135 | DIR *d = opendir("/usb"); |
rengro01 | 0:602ff2b2d41c | 136 | if ( d != NULL ) |
rengro01 | 0:602ff2b2d41c | 137 | { |
rengro01 | 0:602ff2b2d41c | 138 | struct dirent *p; |
rengro01 | 0:602ff2b2d41c | 139 | while ( (p = readdir(d)) != NULL ) |
rengro01 | 0:602ff2b2d41c | 140 | { |
rengro01 | 0:602ff2b2d41c | 141 | if(strncmp(p->d_name, "tmpidx", sizeof("tmpidx"))==0) continue; |
rengro01 | 0:602ff2b2d41c | 142 | char filename[256]; |
rengro01 | 0:602ff2b2d41c | 143 | strncpy(filename, " <option value='", 256); |
rengro01 | 0:602ff2b2d41c | 144 | strncat(filename, p->d_name, 256); |
rengro01 | 0:602ff2b2d41c | 145 | strncat(filename, "'>", 256); |
rengro01 | 0:602ff2b2d41c | 146 | strncat(filename, p->d_name, 256); |
rengro01 | 0:602ff2b2d41c | 147 | strncat(filename, "</option>\n", 256); |
rengro01 | 0:602ff2b2d41c | 148 | m_idx_size += fwrite(filename, strlen(filename), 1, m_fp); |
rengro01 | 0:602ff2b2d41c | 149 | } |
rengro01 | 0:602ff2b2d41c | 150 | closedir(d); |
rengro01 | 0:602ff2b2d41c | 151 | } |
rengro01 | 0:602ff2b2d41c | 152 | for(int i=0; i<strlen(closing); i++) |
rengro01 | 0:602ff2b2d41c | 153 | { |
rengro01 | 0:602ff2b2d41c | 154 | m_idx_size += fwrite(&closing[i], 1, 1, m_fp); |
rengro01 | 0:602ff2b2d41c | 155 | } |
rengro01 | 0:602ff2b2d41c | 156 | // workaroud: add 2KB of new lines to allow the tcp socket to flush... |
rengro01 | 0:602ff2b2d41c | 157 | for(int i=0; i<2048; i++) |
rengro01 | 0:602ff2b2d41c | 158 | { |
rengro01 | 0:602ff2b2d41c | 159 | const char* nl = "\n"; |
rengro01 | 0:602ff2b2d41c | 160 | m_idx_size += fwrite(nl, 1, 1, m_fp); |
rengro01 | 0:602ff2b2d41c | 161 | } |
rengro01 | 0:602ff2b2d41c | 162 | fclose(m_fp); |
rengro01 | 0:602ff2b2d41c | 163 | |
rengro01 | 0:602ff2b2d41c | 164 | m_fp = fopen("/usb/tmpidx", "r"); |
rengro01 | 0:602ff2b2d41c | 165 | |
rengro01 | 0:602ff2b2d41c | 166 | setContentLen(m_idx_size); |
rengro01 | 0:602ff2b2d41c | 167 | respHeaders()["Connection"] = "close"; |
rengro01 | 0:602ff2b2d41c | 168 | onWriteable(); |
rengro01 | 0:602ff2b2d41c | 169 | } |
rengro01 | 0:602ff2b2d41c | 170 | |
rengro01 | 0:602ff2b2d41c | 171 | void HomePageHandler::doPost() |
rengro01 | 0:602ff2b2d41c | 172 | { |
rengro01 | 0:602ff2b2d41c | 173 | } |
rengro01 | 0:602ff2b2d41c | 174 | |
rengro01 | 0:602ff2b2d41c | 175 | void HomePageHandler::doHead() |
rengro01 | 0:602ff2b2d41c | 176 | { |
rengro01 | 0:602ff2b2d41c | 177 | } |
rengro01 | 0:602ff2b2d41c | 178 | |
rengro01 | 0:602ff2b2d41c | 179 | void HomePageHandler::onReadable() |
rengro01 | 0:602ff2b2d41c | 180 | { |
rengro01 | 0:602ff2b2d41c | 181 | } |
rengro01 | 0:602ff2b2d41c | 182 | |
rengro01 | 0:602ff2b2d41c | 183 | void HomePageHandler::onWriteable() |
rengro01 | 0:602ff2b2d41c | 184 | { |
rengro01 | 0:602ff2b2d41c | 185 | static char rBuf[CHUNK_SIZE]; |
rengro01 | 0:602ff2b2d41c | 186 | while(true) |
rengro01 | 0:602ff2b2d41c | 187 | { |
rengro01 | 0:602ff2b2d41c | 188 | int len = fread(rBuf, 1, CHUNK_SIZE, m_fp); |
rengro01 | 0:602ff2b2d41c | 189 | if(len>0) |
rengro01 | 0:602ff2b2d41c | 190 | { |
rengro01 | 0:602ff2b2d41c | 191 | int writtenLen = writeData(rBuf, len); |
rengro01 | 0:602ff2b2d41c | 192 | if(writtenLen < 0) //Socket error |
rengro01 | 0:602ff2b2d41c | 193 | { |
rengro01 | 0:602ff2b2d41c | 194 | if(writtenLen == TCPSOCKET_MEM) |
rengro01 | 0:602ff2b2d41c | 195 | { |
rengro01 | 0:602ff2b2d41c | 196 | fseek(m_fp, -len, SEEK_CUR); |
rengro01 | 0:602ff2b2d41c | 197 | return; //Wait for the queued TCP segments to be transmitted |
rengro01 | 0:602ff2b2d41c | 198 | } |
rengro01 | 0:602ff2b2d41c | 199 | else |
rengro01 | 0:602ff2b2d41c | 200 | { |
rengro01 | 0:602ff2b2d41c | 201 | //This is a critical error |
rengro01 | 0:602ff2b2d41c | 202 | close(); |
rengro01 | 0:602ff2b2d41c | 203 | return; |
rengro01 | 0:602ff2b2d41c | 204 | } |
rengro01 | 0:602ff2b2d41c | 205 | } |
rengro01 | 0:602ff2b2d41c | 206 | else if(writtenLen < len) //Short write, socket's buffer is full |
rengro01 | 0:602ff2b2d41c | 207 | { |
rengro01 | 0:602ff2b2d41c | 208 | fseek(m_fp, writtenLen - len, SEEK_CUR); |
rengro01 | 0:602ff2b2d41c | 209 | return; |
rengro01 | 0:602ff2b2d41c | 210 | } |
rengro01 | 0:602ff2b2d41c | 211 | } |
rengro01 | 0:602ff2b2d41c | 212 | else |
rengro01 | 0:602ff2b2d41c | 213 | { |
rengro01 | 0:602ff2b2d41c | 214 | close(); //Data written, we can close the connection |
rengro01 | 0:602ff2b2d41c | 215 | return; |
rengro01 | 0:602ff2b2d41c | 216 | } |
rengro01 | 0:602ff2b2d41c | 217 | } |
rengro01 | 0:602ff2b2d41c | 218 | } |
rengro01 | 0:602ff2b2d41c | 219 | |
rengro01 | 0:602ff2b2d41c | 220 | void HomePageHandler::onClose() |
rengro01 | 0:602ff2b2d41c | 221 | { |
rengro01 | 0:602ff2b2d41c | 222 | if(m_fp) |
rengro01 | 0:602ff2b2d41c | 223 | { |
rengro01 | 0:602ff2b2d41c | 224 | fclose(m_fp); |
rengro01 | 0:602ff2b2d41c | 225 | m_fp = NULL; |
rengro01 | 0:602ff2b2d41c | 226 | } |
rengro01 | 0:602ff2b2d41c | 227 | } |