Suspended plotter for the skaperfest
Dependencies: mbed HTTPServer EthernetNetIf FatFileSystemCpp
Diff: HomePageHandler.cpp
- Revision:
- 0:602ff2b2d41c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/HomePageHandler.cpp Mon Aug 22 10:24:23 2022 +0000 @@ -0,0 +1,227 @@ +#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; + } +}