diff --git a/src/Dockerfile b/src/Dockerfile index 3424113..37a83de 100644 --- a/src/Dockerfile +++ b/src/Dockerfile @@ -17,7 +17,7 @@ RUN tar -xf arduino-cli_${ARDUINO_CLI_VERSION}_Linux_64bit.tar.gz # TODO: version-lock these COPY arduino-cli.yaml . RUN ./arduino-cli core update-index --config-file arduino-cli.yaml -RUN ./arduino-cli core install esp32:esp32 +RUN ./arduino-cli core install esp32:esp32@2.0.4 RUN ./arduino-cli lib install \ "ESP8266 and ESP32 OLED driver for SSD1306 displays" \ "Adafruit NeoPixel" diff --git a/src/RubberNugget/RubberNugget.ino b/src/RubberNugget/RubberNugget.ino index 882c8bf..cfffe7a 100644 --- a/src/RubberNugget/RubberNugget.ino +++ b/src/RubberNugget/RubberNugget.ino @@ -8,6 +8,9 @@ #include #include +#include +#include + #include "webUI/index.h" #include "SH1106Wire.h" #include "Nugget_Interface.h" @@ -38,54 +41,66 @@ WebServer server(80); TaskHandle_t webapp; TaskHandle_t nuggweb; -void getPayloads() { - String* payloadPaths = RubberNugget::allPayloadPaths(); +void getPayloads() +{ + String *payloadPaths = RubberNugget::allPayloadPaths(); Serial.printf("[SERVER][getPayloads] %s\n", payloadPaths->c_str()); server.send(200, "text/plain", *payloadPaths); } -void handleRoot() { +void handleRoot() +{ Serial.println("handling root!"); server.send(200, "text/html", String(INDEX)); } -void delpayload() { +void delpayload() +{ String path(server.arg("path")); FRESULT res = f_unlink(path.c_str()); - if (res == FR_OK){ + if (res == FR_OK) + { server.send(200); - } else { + } + else + { server.send(500); } } -void websave() { +void websave() +{ // path should be corrected, i.e. by index.html's pathCorrector function // Each path should start with '/' and not end with '/' String path = (server.arg("path")); - const char* constPath = path.c_str(); + const char *constPath = path.c_str(); // construct directories as needed FILINFO filinfo; int pathSoFarIdx = 1; - while(true) { + while (true) + { int nextDir = path.indexOf("/", pathSoFarIdx); - if (nextDir == -1){ + if (nextDir == -1) + { break; } String pathSoFar = path.substring(0, nextDir); - if (FR_OK != f_stat(pathSoFar.c_str(), &filinfo)){ - if (f_mkdir(pathSoFar.c_str()) != FR_OK) { + if (FR_OK != f_stat(pathSoFar.c_str(), &filinfo)) + { + if (f_mkdir(pathSoFar.c_str()) != FR_OK) + { server.send(500, "text/plain", "Could not create directory"); return; } } - pathSoFarIdx = nextDir+1; + pathSoFarIdx = nextDir + 1; } // Create file FIL file; - if (FR_OK != f_open(&file, constPath, FA_WRITE | FA_CREATE_ALWAYS)){ + if (FR_OK != f_open(&file, constPath, FA_WRITE | FA_CREATE_ALWAYS)) + { server.send(500, "text/plain", "Could not open file for writing"); return; } @@ -93,12 +108,13 @@ void websave() { // Write to file String content = (server.arg("payloadText")); content.replace(" ", "/"); // why - const char* contentBase64 = content.c_str(); + const char *contentBase64 = content.c_str(); size_t payloadLength = BASE64::decodeLength(contentBase64); uint8_t payloadContent[payloadLength]; BASE64::decode(contentBase64, payloadContent); UINT written = 0; - if (FR_OK != f_write(&file, payloadContent, payloadLength, &written)){ + if (FR_OK != f_write(&file, payloadContent, payloadLength, &written)) + { server.send(500, "text/plain", "Could not write to file"); f_close(&file); return; @@ -108,15 +124,18 @@ void websave() { } // decode base64 and run -void webrunlive() { +void webrunlive() +{ server.send(200, "text/plain", "Running payload..."); - if (server.hasArg("plain")) { + if (server.hasArg("plain")) + { Serial.print("Decoding: "); String decoded = (server.arg("plain")); char tab2[decoded.length() + 1]; strcpy(tab2, decoded.c_str()); - for (int i = 0; i < decoded.length(); i++) { + for (int i = 0; i < decoded.length(); i++) + { Serial.print(tab2[i]); } @@ -128,15 +147,16 @@ void webrunlive() { Serial.println(BASE64::decodeLength(tab2)); BASE64::decode(tab2, raw); - String meow = (char*) raw; - meow = meow.substring(0, (int) BASE64::decodeLength(tab2)); + String meow = (char *)raw; + meow = meow.substring(0, (int)BASE64::decodeLength(tab2)); RubberNugget::runLivePayload(meow); Serial.println(); Serial.println("-------"); } } -void webget() { +void webget() +{ FRESULT fr; FIL file; uint16_t size; @@ -145,7 +165,8 @@ void webget() { String path = server.arg("path"); fr = f_open(&file, path.c_str(), FA_READ); - if (fr != FR_OK) { + if (fr != FR_OK) + { // TODO: most likely file not found, but we need to check why fr != OK. // Marking 500 until resolved server.send(500, "plain/text", String("Error loading script")); @@ -153,32 +174,40 @@ void webget() { } size = f_size(&file); - char * data = NULL; + char *data = NULL; - data = (char*) malloc(size); + data = (char *)malloc(size); - fr = f_read(&file, data, (UINT) size, &bytesRead); - if (fr == FR_OK) { + fr = f_read(&file, data, (UINT)size, &bytesRead); + if (fr == FR_OK) + { String payload = String(data); payload = payload.substring(0, bytesRead); payload = base64::encode(payload); server.send(200, "plain/text", payload); - } else { + } + else + { server.send(500, "plain/text", String("Error reading script")); } f_close(&file); - } // run payload with get request path -void webrun() { +void webrun() +{ server.send(200, "text/html", "Running payload..."); String path = server.arg("path"); RubberNugget::runPayload(path.c_str(), 1); // provide parameter triggered from webpage } -void webserverInit(void *p) { - while (1) { + DNSServer dns; + +void webserverInit(void *p) +{ + while (1) + { + dns.processNextRequest(); server.handleClient(); vTaskDelay(2); } @@ -187,32 +216,44 @@ void webserverInit(void *p) { extern String netPassword; extern String networkName; -void setup() { - pinMode(12, OUTPUT); - strip.begin(); + + +void setup() +{ + pinMode(12, OUTPUT); + strip.begin(); delay(500); Serial.begin(115200); RubberNugget::init(); - - if (networkName.length() >0) { + + if (networkName.length() > 0) + { Serial.println(networkName); - const char * c = networkName.c_str(); - ssid=c; + const char *c = networkName.c_str(); + ssid = c; } - if (netPassword.length() >=8) { + if (netPassword.length() >= 8) + { Serial.println(netPassword); - const char * d = netPassword.c_str(); - password=d; + const char *d = netPassword.c_str(); + password = d; } WiFi.softAP(ssid, password); - // } + // } IPAddress myIP = WiFi.softAPIP(); Serial.print("AP IP address: "); Serial.println(myIP); + + dns.setErrorReplyCode(DNSReplyCode::NoError); + dns.start(53, "*", myIP); + + MDNS.begin("usb.nugg"); + Serial.println("mDNS responder started"); + server.on("/", handleRoot); server.on("/payloads", getPayloads); server.on("/savepayload", HTTP_POST, websave); @@ -223,13 +264,14 @@ void setup() { server.begin(); - strip.clear(); - strip.setPixelColor(0, strip.Color(0, 0, 0)); + MDNS.addService("http", "tcp", 80); + strip.clear(); + strip.setPixelColor(0, strip.Color(0, 0, 0)); strip.show(); strip.show(); // initialize & launch payload selector - + xTaskCreate(webserverInit, "webapptask", 12 * 1024, NULL, 5, &webapp); // create task priority 1 RubberNugget::selectPayload(); }