diff --git a/lib/session/MeasurementSession.h b/lib/session/MeasurementSession.h index 73e831f..40c3b10 100644 --- a/lib/session/MeasurementSession.h +++ b/lib/session/MeasurementSession.h @@ -18,6 +18,7 @@ public: bool addPoint(Measurement_T measurement) { const bool successful = currentChunk->addPoint(measurement); if (!successful) { + Serial.println("Starting session rotate"); rotate(); const bool secondInsertSuccess = currentChunk->addPoint(measurement); assert(secondInsertSuccess, "Session: insertion after rotation failed"); @@ -77,6 +78,8 @@ private: void saveChunkToFile(Chunk_T *chunk) const { const uint32_t chunkNr = chunk->getStartIndex() / CHUNK_SIZE; const auto fileName = chunkFileName(chunkNr, chunk->getStartTime()); + Serial.print("Writing session to file "); + Serial.println(fileName); Writer writer( fileName ); chunk->serialize(writer.encoder()); }; diff --git a/lib/session/SpiffsStorage.h b/lib/session/SpiffsStorage.h index 2e44b6c..bc075eb 100644 --- a/lib/session/SpiffsStorage.h +++ b/lib/session/SpiffsStorage.h @@ -7,13 +7,26 @@ class SpiffsStorageWriter { public: SpiffsStorageWriter(const String &fileName) : f_(SPIFFS.open(fileName, "w")), - encoder_(&f_) {} - + encoder_(&f_), + fileName_(fileName) + { + Serial.println("Opened file for writing successful?"); + bool success = f_; + Serial.println(success); + } + ~SpiffsStorageWriter() { + f_.close(); + Serial.print("Closing file: "); + Serial.println(fileName_); + Serial.print("File exists: "); + Serial.println(SPIFFS.exists(fileName_)); + } StreamingMsgPackEncoder &encoder() { return encoder_; } private: File f_; StreamingMsgPackEncoder encoder_; + String fileName_; }; @@ -23,6 +36,9 @@ public: SpiffsStorageReader(const String &fileName) : f_(SPIFFS.open(fileName, "w")) {} + ~SpiffsStorageReader() { + f_.close(); + } uint32_t readBytes(char *buffer, size_t length) { return f_.readBytes(buffer, length); diff --git a/lib/webdav/AsyncWebDav.h b/lib/webdav/AsyncWebDav.h new file mode 100644 index 0000000..abe9329 --- /dev/null +++ b/lib/webdav/AsyncWebDav.h @@ -0,0 +1,117 @@ +#include +#include + +#define FLASH_TEXT(name) const char *name + +namespace webdav_constants { + FLASH_TEXT(MULTISTATUS_START) = ""; + FLASH_TEXT(MULTISTATUS_END) = ""; + FLASH_TEXT(RESPONSE_START) = ""; + FLASH_TEXT(RESPONSE_END) = ""; + FLASH_TEXT(HREF_START) = ""; + FLASH_TEXT(HREF_END) = ""; + FLASH_TEXT(PROPSTAT_START) = ""; + FLASH_TEXT(PROPSTAT_END) = ""; + FLASH_TEXT(PROP_START) = ""; + FLASH_TEXT(PROP_END) = ""; + FLASH_TEXT(RESOURCETYPE_START) = ""; + FLASH_TEXT(RESOURCETYPE_END) = ""; + FLASH_TEXT(RESOURCE_COLLECTION) = ""; + + FLASH_TEXT(CONTENTLEN_START) = ""; + FLASH_TEXT(CONTENTLEN_END) = ""; + FLASH_TEXT(CREATEDATE_START) = ""; + FLASH_TEXT(CREATEDATE_END) = ""; + FLASH_TEXT(MODDATE_START) = ""; + FLASH_TEXT(MODDATE_END) = ""; + FLASH_TEXT(STATUS_OK) = "HTTP/1.1 200 OK"; +} + +void listFiles(AsyncResponseStream * response, const char *folderPath, Dir * dir) +{ + using namespace webdav_constants; + response->println(MULTISTATUS_START); + dir->rewind(); + while (dir->next()) { + response->print(RESPONSE_START); + response->print(HREF_START); + response->print(folderPath); + response->print(dir->fileName()); + response->print(HREF_END); + response->print(PROPSTAT_START); + response->print(PROP_START); + if (dir->isDirectory()) { + response->print(RESOURCETYPE_START); + response->print(RESOURCE_COLLECTION); + response->print(RESOURCETYPE_END); + } else { + response->print(CONTENTLEN_START); + response->print(dir->fileSize(), DEC); + response->print(CONTENTLEN_END); + } + + response->print(PROP_END); + response->print(STATUS_OK); + response->print(PROPSTAT_END); + response->print(webdav_constants::RESPONSE_END); + } + response->println(MULTISTATUS_END); +} + + +class SpiffsWebDavHandler : public AsyncWebHandler +{ +public: + SpiffsWebDavHandler(const String & prefix, const String & folder) + : prefix_(prefix), folder_(folder) + {} + + virtual bool canHandle(AsyncWebServerRequest *request) override final + { + Serial.print("Can handle for url : "); + Serial.println(request->url()); + return request->url().startsWith(prefix_); + } + + virtual void handleRequest(AsyncWebServerRequest *request) override final + { + if (request->url() == prefix_ && request->method() == HTTP_PROPFIND) { + Serial.println("Propfind start"); + AsyncResponseStream * response = request->beginResponseStream("application/xml"); + Dir dir = SPIFFS.openDir(folder_); + listFiles(response, "/", &dir); + request->send(response); + } else if(request->url() == prefix_ && request->method() == HTTP_GET) { + AsyncResponseStream * response = request->beginResponseStream("text/plain"); + Dir dir = SPIFFS.openDir(folder_); + Serial.print("Opening folder "); + Serial.println(folder_); + while (dir.next()) { + Serial.print(" File: "); + Serial.println(dir.fileName()); + response->println(dir.fileName()); + } + request->send(response); + } + else if (request->method() == HTTP_GET) { + auto path = folder_ + request->url().substring(prefix_.length()); + Serial.print("Testing if path exists: "); + Serial.println(path); + if (SPIFFS.exists(path)) { + Serial.println("Exists!"); + request->send(SPIFFS, path, "application/x-msgpack"); + } else { + Serial.println("Does not exist :("); + request->send(404, "text/plain", "Webdav: File not found"); + } + } else { + request->send(404, "text/plain", "Webdav: Invalid request"); + } + } + virtual bool isRequestHandlerTrivial() override final {return false;} + +private: + String prefix_; + String folder_; +}; + diff --git a/platformio.ini b/platformio.ini index a1f3aba..19d239e 100644 --- a/platformio.ini +++ b/platformio.ini @@ -10,13 +10,14 @@ [env:d1] platform = espressif8266 -board = d1 +board = esp_wroom_02 framework = arduino monitor_port = /dev/ttyUSB0 upload_port = /dev/ttyUSB0 monitor_speed = 115200 +build_flags = -Wl,-Teagle.flash.2m1m.ld lib_deps = - ESP Async WebServer + https://github.com/mabau/ESPAsyncWebServer.git AsyncTCP NTPClient diff --git a/src/ConfigHardware.h b/src/ConfigHardware.h index 008e9d7..696c71f 100644 --- a/src/ConfigHardware.h +++ b/src/ConfigHardware.h @@ -8,4 +8,4 @@ const int CONFIG_VALUE_DIVIDER = 128; // uint32 measurements are divid const int CONFIG_MEASURE_DELAY = 100; // interval in ms between measurements -const uint32_t CONFIG_SESSION_CHUNK_SIZE = 1024*8 - 16 * sizeof(uint32_t); +const uint32_t CONFIG_SESSION_CHUNK_SIZE = 1024; //1024*8 - 16 * sizeof(uint32_t); diff --git a/src/firmware_main.cpp b/src/firmware_main.cpp index 9769187..42f8971 100644 --- a/src/firmware_main.cpp +++ b/src/firmware_main.cpp @@ -16,6 +16,8 @@ #include "ConfigWifi.h" #include "ConfigHardware.h" +#include "AsyncWebDav.h" + AsyncWebServer server(80); WiFiUDP ntpUDP; NTPClient timeClient(ntpUDP, "pool.ntp.org"); @@ -130,7 +132,7 @@ void httpSetup(SessionManager * sessionManager) response->addHeader("content-disposition", "attachment; filename=\"" + String(sessionId) + ".st\""); req->send(response); }); - + server.addHandler(new SpiffsWebDavHandler("/webdav", "/dat")); server.onNotFound(onNotFound); server.begin(); @@ -141,6 +143,54 @@ void setup() // Serial Serial.begin(115200); while(!Serial) {} + Serial.println(" "); + Serial.println("----- New start -----"); + + // File system + SPIFFS.begin(); + Serial.print("SPIFFS begin "); + + FSInfo fs_info; + SPIFFS.info(fs_info); + + float fileTotalKB = (float)fs_info.totalBytes / 1024.0; + float fileUsedKB = (float)fs_info.usedBytes / 1024.0; + + float flashChipSize = (float)ESP.getFlashChipSize() / 1024.0 / 1024.0; + float realFlashChipSize = (float)ESP.getFlashChipRealSize() / 1024.0 / 1024.0; + float flashFreq = (float)ESP.getFlashChipSpeed() / 1000.0 / 1000.0; + FlashMode_t ideMode = ESP.getFlashChipMode(); + + Serial.printf("\n#####################\n"); + + Serial.printf("__________________________\n\n"); + Serial.println("Firmware: "); + Serial.printf(" Chip Id: %08X\n", ESP.getChipId()); + Serial.print(" Core version: "); Serial.println(ESP.getCoreVersion()); + Serial.print(" SDK version: "); Serial.println(ESP.getSdkVersion()); + Serial.print(" Boot version: "); Serial.println(ESP.getBootVersion()); + Serial.print(" Boot mode: "); Serial.println(ESP.getBootMode()); + + Serial.printf("__________________________\n\n"); + + Serial.println("Flash chip information: "); + Serial.printf(" Flash chip Id: %08X (for example: Id=001640E0 Manuf=E0, Device=4016 (swap bytes))\n", ESP.getFlashChipId()); + Serial.printf(" Sketch thinks Flash RAM is size: "); Serial.print(flashChipSize); Serial.println(" MB"); + Serial.print(" Actual size based on chip Id: "); Serial.print(realFlashChipSize); + Serial.println(" MB ... given by (2^( Device - 1) / 8 / 1024"); + Serial.print(" Flash frequency: "); Serial.print(flashFreq); Serial.println(" MHz"); + Serial.printf(" Flash write mode: %s\n", (ideMode == FM_QIO ? "QIO" : ideMode == FM_QOUT ? "QOUT" : ideMode == FM_DIO ? "DIO" : ideMode == FM_DOUT ? "DOUT" : "UNKNOWN")); + + Serial.printf("__________________________\n\n"); + + Serial.println("File system (SPIFFS): "); + Serial.print(" Total KB: "); Serial.print(fileTotalKB); Serial.println(" KB"); + Serial.print(" Used KB: "); Serial.print(fileUsedKB); Serial.println(" KB"); + Serial.printf(" Block size: %lu\n", fs_info.blockSize); + Serial.printf(" Page size: %lu\n", fs_info.pageSize); + Serial.printf(" Maximum open files: %lu\n", fs_info.maxOpenFiles); + Serial.printf(" Maximum path length: %lu\n\n", fs_info.maxPathLength); + // WiFi WiFi.mode(WIFI_STA);