Suspended plotter for the skaperfest
Dependencies: mbed HTTPServer EthernetNetIf FatFileSystemCpp
HomePageHandler.cpp
- Committer:
- rengro01
- Date:
- 2022-08-22
- Revision:
- 0:602ff2b2d41c
File content as of revision 0:602ff2b2d41c:
#include "HomePageHandler.hpp" #include "mbed.h" #define CHUNK_SIZE 128 HomePageHandler::HomePageHandler(const char* rootPath, const char* path, TCPSocket* pTcpSocket) : HTTPRequestHandler(rootPath, path, pTcpSocket) { } HomePageHandler::~HomePageHandler() { } void HomePageHandler::doGet() { const char* opening = "<html>\n" " <head>\n" " <title>ARM MBED Plotter</title>\n" " <style>\n" " table {\n" " text-align: center;\n" " width:352px;\n" " }\n" " #btn {\n" " border: 1px solid black;\n" " background-color: powderblue;\n" " }\n" " td, tr {\n" " width: 32px;\n" " height: 32px;\n" " }\n" " </style>\n" " <script>\n" " var client;\n" " function upload()\n" " {\n" " var filetag = document.getElementById('uploadfile');\n" " var file = filetag.files[0];\n" " if (!file) {\n" " return;\n" " }\n" " client = new XMLHttpRequest();\n" " client.open('POST', 'upload');\n" " client.setRequestHeader('Content-Type', 'text/plain');\n" " client.setRequestHeader('Request', 'upload');\n" " client.setRequestHeader('X-File-Name', file.name);\n" " client.setRequestHeader('X-File-Size', file.size);\n" " client.send(file);\n" " }\n" " function plot()\n" " {\n" " var filetag = document.getElementById('to_plot');\n" " var file = filetag.value;\n" " var formData = new FormData();\n" " formData.append('plot', file);\n" " client = new XMLHttpRequest();\n" " client.open('POST', 'upload');\n" " client.setRequestHeader('Request', 'plot');\n" " client.setRequestHeader('X-File-Name', file);\n" " client.setRequestHeader('Content-Type', 'multipart/form-data');\n" " client.send(formData);\n" " }\n" " function move(value)\n" " {\n" " var formData = new FormData();\n" " formData.append('value', value);\n" " client = new XMLHttpRequest();\n" " client.open('POST', 'upload');\n" " client.setRequestHeader('Request', 'move');\n" " client.setRequestHeader('Direction', value);\n" " client.setRequestHeader('Content-Type', 'multipart/form-data');\n" " client.send(formData);\n" " }\n" " </script>\n" " </head>\n" " <body>\n" " <h1>ARM MBED Plotter</h1>\n" " <br/>\n" " <br/>\n" " <input name='FileSubmit' type='submit' value='Upload' onclick='upload()' />\n" " <input type='file' id='uploadfile' name='uploadfile' />\n" " <br/>\n" " <br/>\n" " <input name='FilePlot' type='submit' value='Plot' onclick='plot()' />\n" " <select id='to_plot' name='to_plot'>\n" ""; const char* closing = " </select>\n" " <br/>\n" " <br/>\n" " <table>\n" " <tr>\n" " <td></td>\n" " <td id='btn' onclick='move(0)' >⇑</td>\n" " <td></td>\n" " <td></td>\n" " <td id='btn' onclick='move(4)' >↰</td>\n" " <td></td>\n" " <td id='btn' onclick='move(6)' >⇖</td>\n" " <td></td>\n" " <td id='btn' onclick='move(10)'> 0 </td>\n" " <td></td>\n" " <td id='btn' onclick='move(9)' >⇗</td>\n" " </tr>\n" " <tr>\n" " <td id='btn' onclick='move(1)' >⇐</td>\n" " <td id='btn' onclick='move(2)' >⇓</td>\n" " <td id='btn' onclick='move(3)' >⇒</td>\n" " <td></td>\n" " <td id='btn' onclick='move(5)' >↳</td>\n" " <td></td>\n" " <td></td>\n" " <td id='btn' onclick='move(7)' >⇘</td>\n" " <td></td>\n" " <td id='btn' onclick='move(8)' >⇙</td>\n" " <td></td>\n" " </tr>\n" " </table>\n" " </body>\n" "</html>\n"; m_fp = fopen("/usb/tmpidx", "w"); m_idx_size = 0; for(int i=0; i<strlen(opening); i++) { m_idx_size += fwrite(&opening[i], 1, 1, m_fp); } fclose(m_fp); m_fp = fopen("/usb/tmpidx", "a"); DIR *d = opendir("/usb"); if ( d != NULL ) { struct dirent *p; while ( (p = readdir(d)) != NULL ) { if(strncmp(p->d_name, "tmpidx", sizeof("tmpidx"))==0) continue; char filename[256]; strncpy(filename, " <option value='", 256); strncat(filename, p->d_name, 256); strncat(filename, "'>", 256); strncat(filename, p->d_name, 256); strncat(filename, "</option>\n", 256); m_idx_size += fwrite(filename, strlen(filename), 1, m_fp); } closedir(d); } for(int i=0; i<strlen(closing); i++) { m_idx_size += fwrite(&closing[i], 1, 1, m_fp); } // workaroud: add 2KB of new lines to allow the tcp socket to flush... for(int i=0; i<2048; i++) { const char* nl = "\n"; m_idx_size += fwrite(nl, 1, 1, m_fp); } fclose(m_fp); m_fp = fopen("/usb/tmpidx", "r"); setContentLen(m_idx_size); respHeaders()["Connection"] = "close"; onWriteable(); } void HomePageHandler::doPost() { } void HomePageHandler::doHead() { } void HomePageHandler::onReadable() { } void HomePageHandler::onWriteable() { static char rBuf[CHUNK_SIZE]; while(true) { int len = fread(rBuf, 1, CHUNK_SIZE, m_fp); if(len>0) { int writtenLen = writeData(rBuf, len); if(writtenLen < 0) //Socket error { if(writtenLen == TCPSOCKET_MEM) { fseek(m_fp, -len, SEEK_CUR); return; //Wait for the queued TCP segments to be transmitted } else { //This is a critical error close(); return; } } else if(writtenLen < len) //Short write, socket's buffer is full { fseek(m_fp, writtenLen - len, SEEK_CUR); return; } } else { close(); //Data written, we can close the connection return; } } } void HomePageHandler::onClose() { if(m_fp) { fclose(m_fp); m_fp = NULL; } }