From 88ff8f4c5312f15977bfa2666e5fbaa25ba20de8 Mon Sep 17 00:00:00 2001 From: Peter Buchegger Date: Tue, 3 Nov 2020 23:34:36 +0100 Subject: [PATCH 01/29] fixing configuration issue and adding more printouts --- src/LoRa_APRS_iGate.cpp | 6 +++++- src/configuration.cpp | 12 +++++++----- src/configuration.h | 2 +- 3 files changed, 13 insertions(+), 7 deletions(-) diff --git a/src/LoRa_APRS_iGate.cpp b/src/LoRa_APRS_iGate.cpp index 4754501..6500eee 100644 --- a/src/LoRa_APRS_iGate.cpp +++ b/src/LoRa_APRS_iGate.cpp @@ -94,7 +94,7 @@ void setup() } delay(500); - Serial.println("setup done..."); + Serial.println("[INFO] setup done..."); secondsSinceDisplay = 0; } @@ -296,6 +296,7 @@ void load_config() { Config.display.overwritePin = KEY_BUILTIN; } + Serial.println("[INFO] Configuration loaded!"); } void setup_wifi() @@ -304,6 +305,8 @@ void setup_wifi() WiFi.setHostname(Config.callsign.c_str()); for(Configuration::Wifi::AP ap : Config.wifi.APs) { + Serial.print("[INFO] Looking for AP: "); + Serial.println(ap.SSID); WiFiMulti.addAP(ap.SSID.c_str(), ap.password.c_str()); } Serial.print("[INFO] Waiting for WiFi"); @@ -358,6 +361,7 @@ void setup_ota() }); ArduinoOTA.setHostname(Config.callsign.c_str()); ArduinoOTA.begin(); + Serial.println("[INFO] OTA init done!"); } void setup_lora() diff --git a/src/configuration.cpp b/src/configuration.cpp index 264d202..3d7d24e 100644 --- a/src/configuration.cpp +++ b/src/configuration.cpp @@ -76,6 +76,9 @@ Configuration ConfigurationManagement::readConfiguration() conf.lora.codingRate4 = data["lora"]["coding_rate4"]; } + // update config in memory to get the new fields: + writeConfiguration(conf); + return conf; } @@ -92,13 +95,12 @@ void ConfigurationManagement::writeConfiguration(Configuration conf) data["version"] = conf.version; data["callsign"] = conf.callsign; data["wifi"]["active"] = conf.wifi.active; - JsonArray aps = data["wifi"]["AP"].to(); + JsonArray aps = data["wifi"].createNestedArray("AP"); for(Configuration::Wifi::AP ap : conf.wifi.APs) { - JsonVariant v; + JsonObject v = aps.createNestedObject(); v["SSID"] = ap.SSID; v["password"] = ap.password; - aps.add(v); } data["beacon"]["message"] = conf.beacon.message; data["beacon"]["position"]["latitude"] = conf.beacon.positionLatitude; @@ -124,7 +126,7 @@ void ConfigurationManagement::writeConfiguration(Configuration conf) data["display"]["overwrite_pin"] = conf.display.overwritePin; serializeJson(data, file); - serializeJson(data, Serial); - Serial.println(); + //serializeJson(data, Serial); + //Serial.println(); file.close(); } diff --git a/src/configuration.h b/src/configuration.h index 601904c..39cdd0d 100644 --- a/src/configuration.h +++ b/src/configuration.h @@ -82,7 +82,7 @@ public: int overwritePin; }; - Configuration() : version(2), callsign("NOCALL-10") {}; + Configuration() : version(3), callsign("NOCALL-10") {}; int version; String callsign; From bc56f8af4a908437887bec95cc13159d50d8dc25 Mon Sep 17 00:00:00 2001 From: Peter Buchegger Date: Tue, 3 Nov 2020 23:35:19 +0100 Subject: [PATCH 02/29] add ftp server, config still missing --- platformio.ini | 1 + src/LoRa_APRS_iGate.cpp | 29 +++++++++++++++++++++++++++++ 2 files changed, 30 insertions(+) diff --git a/platformio.ini b/platformio.ini index 3fda3a6..83e69c4 100644 --- a/platformio.ini +++ b/platformio.ini @@ -15,6 +15,7 @@ lib_deps = sandeepmistry/LoRa @ 0.7.2 peterus/APRS-Decoder-Lib @ 0.0.5 peterus/APRS-IS-Lib @ 0.0.7 + https://github.com/peterus/ESP-FTP-Server-Lib peterus/LoRa-APRS-Lib @ 0.0.5 check_tool = cppcheck check_flags = diff --git a/src/LoRa_APRS_iGate.cpp b/src/LoRa_APRS_iGate.cpp index 6500eee..50e657a 100644 --- a/src/LoRa_APRS_iGate.cpp +++ b/src/LoRa_APRS_iGate.cpp @@ -6,6 +6,9 @@ #include #include #include +#include +#include +#include #include "LoRa_APRS.h" @@ -28,6 +31,7 @@ volatile uint secondsSinceDisplay = 0; WiFiMulti WiFiMulti; WiFiUDP ntpUDP; NTPClient timeClient(ntpUDP, 60*60); +FTPServer ftpServer; Configuration Config; APRS_IS * aprs_is = 0; LoRa_APRS lora_aprs; @@ -43,6 +47,7 @@ void setup_lora(); void setup_ntp(); void setup_aprs_is(); void setup_timer(); +void setup_ftp(); std::map> lastMessages; @@ -77,6 +82,7 @@ void setup() setup_wifi(); setup_ota(); setup_ntp(); + setup_ftp(); } else { @@ -133,6 +139,19 @@ void loop() beacon_digi = true; } + ftpServer.handle(); + static bool configWasOpen = false; + if(configWasOpen && ftpServer.countConnections() == 0) + { + Serial.println("[WARN] Configuration maybe changed via FTP, will restart now..."); + Serial.println(); + ESP.restart(); + } + if(ftpServer.countConnections() > 0) + { + configWasOpen = true; + } + if(Config.wifi.active) ArduinoOTA.handle(); if(Config.wifi.active && WiFiMulti.run() != WL_CONNECTED) { @@ -424,6 +443,16 @@ void setup_timer() timerAlarmEnable(timer); } +void setup_ftp() +{ +#define FTP_USER "ftp" +#define FTP_PASSWORD "ftp" + ftpServer.addUser(FTP_USER, FTP_PASSWORD); + ftpServer.addFilesystem("SPIFFS", &SPIFFS); + ftpServer.begin(); + Serial.println("[INFO] FTP Server init done!"); +} + String create_lat_aprs(double lat) { char str[20]; From b4be3c5d6aa9802cd8d95035225e777f3f6e818e Mon Sep 17 00:00:00 2001 From: Peter Buchegger Date: Wed, 4 Nov 2020 00:15:46 +0100 Subject: [PATCH 03/29] add ftp config --- data/is-cfg.json | 7 +++++++ src/LoRa_APRS_iGate.cpp | 36 +++++++++++++++++++++++------------- src/configuration.cpp | 32 +++++++++++++++++++++++++++----- src/configuration.h | 19 ++++++++++++++++++- 4 files changed, 75 insertions(+), 19 deletions(-) diff --git a/data/is-cfg.json b/data/is-cfg.json index 6072030..8c02d2b 100644 --- a/data/is-cfg.json +++ b/data/is-cfg.json @@ -47,5 +47,12 @@ "always_on": true, "timeout":10, "overwrite_pin":0 + }, + "ftp": + { + "active":false, + "user": [ + { "name":"ftp", "password":"ftp" } + ] } } diff --git a/src/LoRa_APRS_iGate.cpp b/src/LoRa_APRS_iGate.cpp index 50e657a..ae175a8 100644 --- a/src/LoRa_APRS_iGate.cpp +++ b/src/LoRa_APRS_iGate.cpp @@ -139,17 +139,20 @@ void loop() beacon_digi = true; } - ftpServer.handle(); - static bool configWasOpen = false; - if(configWasOpen && ftpServer.countConnections() == 0) + if(Config.ftp.active) { - Serial.println("[WARN] Configuration maybe changed via FTP, will restart now..."); - Serial.println(); - ESP.restart(); - } - if(ftpServer.countConnections() > 0) - { - configWasOpen = true; + ftpServer.handle(); + static bool configWasOpen = false; + if(configWasOpen && ftpServer.countConnections() == 0) + { + Serial.println("[WARN] Maybe the config has been changed via FTP, lets restart now to get the new config..."); + Serial.println(); + ESP.restart(); + } + if(ftpServer.countConnections() > 0) + { + configWasOpen = true; + } } if(Config.wifi.active) ArduinoOTA.handle(); @@ -445,9 +448,16 @@ void setup_timer() void setup_ftp() { -#define FTP_USER "ftp" -#define FTP_PASSWORD "ftp" - ftpServer.addUser(FTP_USER, FTP_PASSWORD); + if(!Config.ftp.active) + { + return; + } + for(Configuration::Ftp::User user : Config.ftp.users) + { + Serial.print("[INFO] Adding user to FTP Server: "); + Serial.println(user.name); + ftpServer.addUser(user.name, user.password); + } ftpServer.addFilesystem("SPIFFS", &SPIFFS); ftpServer.begin(); Serial.println("[INFO] FTP Server init done!"); diff --git a/src/configuration.cpp b/src/configuration.cpp index 3d7d24e..30d117c 100644 --- a/src/configuration.cpp +++ b/src/configuration.cpp @@ -31,19 +31,21 @@ Configuration ConfigurationManagement::readConfiguration() Serial.println("Failed to open file for reading..."); return Configuration(); } - DynamicJsonDocument data(1024); + DynamicJsonDocument data(2048); deserializeJson(data, file); + //serializeJson(data, Serial); + //Serial.println(); file.close(); Configuration conf; conf.callsign = data["callsign"].as(); conf.wifi.active = data["wifi"]["active"]; - JsonArray aps = data["wifi"]["AP"].as(); + JsonArray aps = data["wifi"]["AP"].as(); for(JsonVariant v : aps) { Configuration::Wifi::AP ap; - ap.SSID = v["SSID"].as(); - ap.password = v["password"].as(); + ap.SSID = v["SSID"].as(); + ap.password = v["password"].as(); conf.wifi.APs.push_back(ap); } conf.beacon.message = data["beacon"]["message"].as(); @@ -75,6 +77,18 @@ Configuration ConfigurationManagement::readConfiguration() conf.lora.signalBandwidth = data["lora"]["signal_bandwidth"]; conf.lora.codingRate4 = data["lora"]["coding_rate4"]; } + if(data["version"] >= 4) + { + conf.ftp.active = data["ftp"]["active"]; + JsonArray users = data["ftp"]["user"].as(); + for(JsonVariant u : users) + { + Configuration::Ftp::User us; + us.name = u["name"].as(); + us.password = u["password"].as(); + conf.ftp.users.push_back(us); + } + } // update config in memory to get the new fields: writeConfiguration(conf); @@ -90,7 +104,7 @@ void ConfigurationManagement::writeConfiguration(Configuration conf) Serial.println("Failed to open file for writing..."); return; } - DynamicJsonDocument data(1024); + DynamicJsonDocument data(2048); data["version"] = conf.version; data["callsign"] = conf.callsign; @@ -124,6 +138,14 @@ void ConfigurationManagement::writeConfiguration(Configuration conf) data["display"]["always_on"] = conf.display.alwaysOn; data["display"]["timeout"] = conf.display.timeout; data["display"]["overwrite_pin"] = conf.display.overwritePin; + data["ftp"]["active"] = conf.ftp.active; + JsonArray users = data["ftp"].createNestedArray("user"); + for(Configuration::Ftp::User u : conf.ftp.users) + { + JsonObject v = users.createNestedObject(); + v["name"] = u.name; + v["password"] = u.password; + } serializeJson(data, file); //serializeJson(data, Serial); diff --git a/src/configuration.h b/src/configuration.h index 39cdd0d..c73f615 100644 --- a/src/configuration.h +++ b/src/configuration.h @@ -82,7 +82,23 @@ public: int overwritePin; }; - Configuration() : version(3), callsign("NOCALL-10") {}; + class Ftp + { + public: + class User + { + public: + String name; + String password; + }; + + Ftp() : active(false) {} + + bool active; + std::list users; + }; + + Configuration() : version(4), callsign("NOCALL-10") {}; int version; String callsign; @@ -92,6 +108,7 @@ public: Digi digi; LoRa lora; Display display; + Ftp ftp; }; class ConfigurationManagement From e8f8ae9fe407aed425e8fc9e737297b2b869fd8b Mon Sep 17 00:00:00 2001 From: Peter Buchegger Date: Wed, 4 Nov 2020 22:18:30 +0100 Subject: [PATCH 04/29] update FTP lib --- platformio.ini | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platformio.ini b/platformio.ini index 83e69c4..0a43d7c 100644 --- a/platformio.ini +++ b/platformio.ini @@ -15,7 +15,7 @@ lib_deps = sandeepmistry/LoRa @ 0.7.2 peterus/APRS-Decoder-Lib @ 0.0.5 peterus/APRS-IS-Lib @ 0.0.7 - https://github.com/peterus/ESP-FTP-Server-Lib + https://github.com/peterus/ESP-FTP-Server-Lib @ 0.9.3 peterus/LoRa-APRS-Lib @ 0.0.5 check_tool = cppcheck check_flags = From 25531f63fe272d37ab55934d1aa3fecef7af8039 Mon Sep 17 00:00:00 2001 From: Peter Buchegger Date: Thu, 5 Nov 2020 13:46:15 +0100 Subject: [PATCH 05/29] Update is-cfg.json fixing version in json --- data/is-cfg.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/data/is-cfg.json b/data/is-cfg.json index 8c02d2b..5b91a4f 100644 --- a/data/is-cfg.json +++ b/data/is-cfg.json @@ -1,5 +1,5 @@ { - "version":3, + "version":4, "callsign":"NOCALL-10", "wifi": { From 9e56e499df69ac2eb252ed1923fe54218b014983 Mon Sep 17 00:00:00 2001 From: Peter Buchegger Date: Thu, 5 Nov 2020 22:06:45 +0100 Subject: [PATCH 06/29] change to official FTP Server Lib Version --- platformio.ini | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/platformio.ini b/platformio.ini index 0a43d7c..34a9ddf 100644 --- a/platformio.ini +++ b/platformio.ini @@ -1,6 +1,3 @@ -#[platformio] -#default_envs = ttgo-lora32-v1 - [env] platform = espressif32 framework = arduino @@ -15,7 +12,7 @@ lib_deps = sandeepmistry/LoRa @ 0.7.2 peterus/APRS-Decoder-Lib @ 0.0.5 peterus/APRS-IS-Lib @ 0.0.7 - https://github.com/peterus/ESP-FTP-Server-Lib @ 0.9.3 + peterus/ESP-FTP-Server-Lib @ 0.9.3 peterus/LoRa-APRS-Lib @ 0.0.5 check_tool = cppcheck check_flags = From b658ed2ed6055116752a999d81d825109e0e9b9f Mon Sep 17 00:00:00 2001 From: Peter Buchegger Date: Thu, 5 Nov 2020 22:47:08 +0100 Subject: [PATCH 07/29] push FTP Lib to repo as there are issues --- lib/ESP-FTP-Server-Lib/.gitignore | 5 + lib/ESP-FTP-Server-Lib/LICENSE | 21 ++ lib/ESP-FTP-Server-Lib/README.md | 34 +++ lib/ESP-FTP-Server-Lib/library.properties | 11 + lib/ESP-FTP-Server-Lib/platformio.ini | 9 + lib/ESP-FTP-Server-Lib/src/Commands/CDUP.h | 19 ++ lib/ESP-FTP-Server-Lib/src/Commands/CWD.h | 37 ++++ lib/ESP-FTP-Server-Lib/src/Commands/DELE.h | 31 +++ lib/ESP-FTP-Server-Lib/src/Commands/LIST.h | 58 +++++ lib/ESP-FTP-Server-Lib/src/Commands/MKD.h | 31 +++ lib/ESP-FTP-Server-Lib/src/Commands/PORT.h | 27 +++ lib/ESP-FTP-Server-Lib/src/Commands/PWD.h | 18 ++ lib/ESP-FTP-Server-Lib/src/Commands/RETR.h | 55 +++++ lib/ESP-FTP-Server-Lib/src/Commands/RMD.h | 31 +++ .../src/Commands/RNFR_RNTO.h | 67 ++++++ lib/ESP-FTP-Server-Lib/src/Commands/STOR.h | 55 +++++ lib/ESP-FTP-Server-Lib/src/Commands/TYPE.h | 28 +++ .../src/ESP-FTP-Server-Lib.cpp | 56 +++++ .../src/ESP-FTP-Server-Lib.h | 38 ++++ lib/ESP-FTP-Server-Lib/src/FTPCommand.h | 133 +++++++++++ lib/ESP-FTP-Server-Lib/src/FTPConnection.cpp | 207 ++++++++++++++++++ lib/ESP-FTP-Server-Lib/src/FTPConnection.h | 59 +++++ lib/ESP-FTP-Server-Lib/src/FTPFilesystem.cpp | 120 ++++++++++ lib/ESP-FTP-Server-Lib/src/FTPFilesystem.h | 70 ++++++ lib/ESP-FTP-Server-Lib/src/FTPPath.cpp | 75 +++++++ lib/ESP-FTP-Server-Lib/src/FTPPath.h | 27 +++ lib/ESP-FTP-Server-Lib/src/FTPUser.h | 14 ++ lib/ESP-FTP-Server-Lib/src/common.cpp | 22 ++ lib/ESP-FTP-Server-Lib/src/common.h | 27 +++ platformio.ini | 2 +- 30 files changed, 1386 insertions(+), 1 deletion(-) create mode 100644 lib/ESP-FTP-Server-Lib/.gitignore create mode 100644 lib/ESP-FTP-Server-Lib/LICENSE create mode 100644 lib/ESP-FTP-Server-Lib/README.md create mode 100644 lib/ESP-FTP-Server-Lib/library.properties create mode 100644 lib/ESP-FTP-Server-Lib/platformio.ini create mode 100644 lib/ESP-FTP-Server-Lib/src/Commands/CDUP.h create mode 100644 lib/ESP-FTP-Server-Lib/src/Commands/CWD.h create mode 100644 lib/ESP-FTP-Server-Lib/src/Commands/DELE.h create mode 100644 lib/ESP-FTP-Server-Lib/src/Commands/LIST.h create mode 100644 lib/ESP-FTP-Server-Lib/src/Commands/MKD.h create mode 100644 lib/ESP-FTP-Server-Lib/src/Commands/PORT.h create mode 100644 lib/ESP-FTP-Server-Lib/src/Commands/PWD.h create mode 100644 lib/ESP-FTP-Server-Lib/src/Commands/RETR.h create mode 100644 lib/ESP-FTP-Server-Lib/src/Commands/RMD.h create mode 100644 lib/ESP-FTP-Server-Lib/src/Commands/RNFR_RNTO.h create mode 100644 lib/ESP-FTP-Server-Lib/src/Commands/STOR.h create mode 100644 lib/ESP-FTP-Server-Lib/src/Commands/TYPE.h create mode 100644 lib/ESP-FTP-Server-Lib/src/ESP-FTP-Server-Lib.cpp create mode 100644 lib/ESP-FTP-Server-Lib/src/ESP-FTP-Server-Lib.h create mode 100644 lib/ESP-FTP-Server-Lib/src/FTPCommand.h create mode 100644 lib/ESP-FTP-Server-Lib/src/FTPConnection.cpp create mode 100644 lib/ESP-FTP-Server-Lib/src/FTPConnection.h create mode 100644 lib/ESP-FTP-Server-Lib/src/FTPFilesystem.cpp create mode 100644 lib/ESP-FTP-Server-Lib/src/FTPFilesystem.h create mode 100644 lib/ESP-FTP-Server-Lib/src/FTPPath.cpp create mode 100644 lib/ESP-FTP-Server-Lib/src/FTPPath.h create mode 100644 lib/ESP-FTP-Server-Lib/src/FTPUser.h create mode 100644 lib/ESP-FTP-Server-Lib/src/common.cpp create mode 100644 lib/ESP-FTP-Server-Lib/src/common.h diff --git a/lib/ESP-FTP-Server-Lib/.gitignore b/lib/ESP-FTP-Server-Lib/.gitignore new file mode 100644 index 0000000..89cc49c --- /dev/null +++ b/lib/ESP-FTP-Server-Lib/.gitignore @@ -0,0 +1,5 @@ +.pio +.vscode/.browse.c_cpp.db* +.vscode/c_cpp_properties.json +.vscode/launch.json +.vscode/ipch diff --git a/lib/ESP-FTP-Server-Lib/LICENSE b/lib/ESP-FTP-Server-Lib/LICENSE new file mode 100644 index 0000000..4960c37 --- /dev/null +++ b/lib/ESP-FTP-Server-Lib/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2020 Peter Buchegger + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/lib/ESP-FTP-Server-Lib/README.md b/lib/ESP-FTP-Server-Lib/README.md new file mode 100644 index 0000000..72b2daf --- /dev/null +++ b/lib/ESP-FTP-Server-Lib/README.md @@ -0,0 +1,34 @@ +# ESP-FTP-Server-Lib + +This library will provide a simple and modern FTP server for your ESP32 or ESP8266 device. +You can setup multiple users and mutliple filesystems (SD-Card, MMC-Card or/and SPIFFS). + +## Examples + +In the example folder you can find a very simple usage of the FTP server. You just need to setup the users, add the filesystems which you want to use, and call the handle function in the loop. + +## Known Commands to the server + +Currently all kind of simple commands are known to the server: +* CDUP +* CWD +* DELE +* LISST +* MKD +* PORT +* PWD +* RETR +* RMD +* RNFR +* RNTO +* STOR +* TYPE +* SYST +* QUIT +* ABOR + +## What is still missing / TODO + +Some commands are still missing, if you need them create a ticket :) + +Currently just the active mode is supported. For the passive mode you need to wait until version 1.0.0. diff --git a/lib/ESP-FTP-Server-Lib/library.properties b/lib/ESP-FTP-Server-Lib/library.properties new file mode 100644 index 0000000..4101a6b --- /dev/null +++ b/lib/ESP-FTP-Server-Lib/library.properties @@ -0,0 +1,11 @@ +name=ESP-FTP-Server-Lib +version=0.9.3 +author=Peter Buchegger +maintainer=Peter Buchegger +sentence=Simple and modern FTP server for ESP devices. +paragraph=With this library you can run a simple and modern FTP server on your ESP32 or ESP8266. You can mount multiple filesystems like SD-Card, MMC-Card or SPIFFS at the same time. +category=Communication +url=https://github.com/peterus/ESP-FTP-Server-Lib +architectures=esp8266,esp32,arduino-esp32 +includes=ESP-FTP-Server-Lib.h +depends= diff --git a/lib/ESP-FTP-Server-Lib/platformio.ini b/lib/ESP-FTP-Server-Lib/platformio.ini new file mode 100644 index 0000000..9fbe7ec --- /dev/null +++ b/lib/ESP-FTP-Server-Lib/platformio.ini @@ -0,0 +1,9 @@ + +[env:ttgo-lora32-v1] +platform = espressif32 +board = ttgo-lora32-v1 +framework = arduino +test_build_project_src = yes +monitor_speed = 115200 +check_flags = + cppcheck: --suppress=*:*.pio\* --suppress=unusedFunction diff --git a/lib/ESP-FTP-Server-Lib/src/Commands/CDUP.h b/lib/ESP-FTP-Server-Lib/src/Commands/CDUP.h new file mode 100644 index 0000000..474607e --- /dev/null +++ b/lib/ESP-FTP-Server-Lib/src/Commands/CDUP.h @@ -0,0 +1,19 @@ +#ifndef CDUP_H_ +#define CDUP_H_ + +#include +#include "../FTPCommand.h" + +class CDUP : public FTPCommand +{ +public: + explicit CDUP(WiFiClient * const Client) : FTPCommand("CDUP", 0, Client) {} + + void run(FTPPath & WorkDirectory, const std::vector & Line) override + { + WorkDirectory.goPathUp(); + SendResponse(250, "Ok. Current directory is " + WorkDirectory.getPath()); + } +}; + +#endif diff --git a/lib/ESP-FTP-Server-Lib/src/Commands/CWD.h b/lib/ESP-FTP-Server-Lib/src/Commands/CWD.h new file mode 100644 index 0000000..9216e55 --- /dev/null +++ b/lib/ESP-FTP-Server-Lib/src/Commands/CWD.h @@ -0,0 +1,37 @@ +#ifndef CWD_H_ +#define CWD_H_ + +#include +#include "../FTPCommand.h" + +class CWD : public FTPCommand +{ +public: + explicit CWD(WiFiClient * const Client, FTPFilesystem * const Filesystem) : FTPCommand("CWD", 1, Client, Filesystem) {} + + void run(FTPPath & WorkDirectory, const std::vector & Line) override + { + FTPPath path = WorkDirectory; + Serial.println(Line[1]); + if(Line[1] == "..") + { + path.goPathUp(); + } + else + { + path.changePath(Line[1]); + } + File dir = _Filesystem->open(path.getPath()); + if(dir.isDirectory()) + { + WorkDirectory = path; + SendResponse(250, "Ok. Current directory is " + WorkDirectory.getPath()); + } + else + { + SendResponse(550, "Directory does not exist"); + } + } +}; + +#endif diff --git a/lib/ESP-FTP-Server-Lib/src/Commands/DELE.h b/lib/ESP-FTP-Server-Lib/src/Commands/DELE.h new file mode 100644 index 0000000..d0a4f4e --- /dev/null +++ b/lib/ESP-FTP-Server-Lib/src/Commands/DELE.h @@ -0,0 +1,31 @@ +#ifndef DELE_H_ +#define DELE_H_ + +#include +#include "../FTPCommand.h" + +class DELE : public FTPCommand +{ +public: + explicit DELE(WiFiClient * const Client, FTPFilesystem * const Filesystem) : FTPCommand("DELE", 1, Client, Filesystem) {} + + void run(FTPPath & WorkDirectory, const std::vector & Line) override + { + String filepath = WorkDirectory.getFilePath(Line[1]); + if(!_Filesystem->exists(filepath)) + { + SendResponse(550, "File " + filepath + " not found"); + return; + } + if(_Filesystem->remove(filepath)) + { + SendResponse(250, " Deleted \"" + filepath + "\""); + } + else + { + SendResponse(450, "Can't delete \"" + filepath + "\""); + } + } +}; + +#endif diff --git a/lib/ESP-FTP-Server-Lib/src/Commands/LIST.h b/lib/ESP-FTP-Server-Lib/src/Commands/LIST.h new file mode 100644 index 0000000..487c1aa --- /dev/null +++ b/lib/ESP-FTP-Server-Lib/src/Commands/LIST.h @@ -0,0 +1,58 @@ +#ifndef LIST_H_ +#define LIST_H_ + +#include +#include "../FTPCommand.h" +#include "../common.h" + +class LIST : public FTPCommand +{ +public: + explicit LIST(WiFiClient * const Client, FTPFilesystem * const Filesystem, IPAddress * DataAddress, int * DataPort) + : FTPCommand("LIST", 1, Client, Filesystem, DataAddress, DataPort) + {} + + void run(FTPPath & WorkDirectory, const std::vector & Line) override + { + if(!ConnectDataConnection()) + { + return; + } + File dir = _Filesystem->open(WorkDirectory.getPath()); + if(!dir || !dir.isDirectory()) + { + CloseDataConnection(); + SendResponse(550, "Can't open directory " + WorkDirectory.getPath()); + return; + } + int cnt = 0; + File f = dir.openNextFile(); + while(f) + { + String filename = f.name(); + filename.remove(0, filename.lastIndexOf('/') + 1); + if(f.isDirectory()) + { + data_print("drwxr-xr-x"); + } + else + { + data_print("-rw-r--r--"); + } + String filesize = String(f.size()); + data_print(" 1 owner group "); + int fill_cnt = 13 - filesize.length(); + for(int i = 0; i < fill_cnt; i++) + { + data_print(" "); + } + data_println(filesize + " Jan 01 1970 " + filename); + cnt++; + f = dir.openNextFile(); + } + CloseDataConnection(); + SendResponse(226, String(cnt) + " matches total"); + } +}; + +#endif diff --git a/lib/ESP-FTP-Server-Lib/src/Commands/MKD.h b/lib/ESP-FTP-Server-Lib/src/Commands/MKD.h new file mode 100644 index 0000000..3f8a88e --- /dev/null +++ b/lib/ESP-FTP-Server-Lib/src/Commands/MKD.h @@ -0,0 +1,31 @@ +#ifndef MKD_H_ +#define MKD_H_ + +#include +#include "../FTPCommand.h" + +class MKD : public FTPCommand +{ +public: + explicit MKD(WiFiClient * const Client, FTPFilesystem * const Filesystem) : FTPCommand("MKD", 1, Client, Filesystem) {} + + void run(FTPPath & WorkDirectory, const std::vector & Line) override + { + String filepath = WorkDirectory.getFilePath(Line[1]); + if(_Filesystem->exists(filepath)) + { + SendResponse(521, "Can't create \"" + filepath + "\", Directory exists"); + return; + } + if(_Filesystem->mkdir(filepath)) + { + SendResponse(257, "\"" + filepath + "\" created"); + } + else + { + SendResponse(550, "Can't create \"" + filepath + "\""); + } + } +}; + +#endif diff --git a/lib/ESP-FTP-Server-Lib/src/Commands/PORT.h b/lib/ESP-FTP-Server-Lib/src/Commands/PORT.h new file mode 100644 index 0000000..13c4815 --- /dev/null +++ b/lib/ESP-FTP-Server-Lib/src/Commands/PORT.h @@ -0,0 +1,27 @@ +#ifndef PORT_H_ +#define PORT_H_ + +#include +#include "../FTPCommand.h" +#include "../common.h" + +class PORT : public FTPCommand +{ +public: + explicit PORT(WiFiClient * const Client, IPAddress * DataAddress, int * DataPort) + : FTPCommand("PORT", 1, Client, 0, DataAddress, DataPort) + {} + + void run(FTPPath & WorkDirectory, const std::vector & Line) override + { + std::vector connection_details = Split>(Line[1], ','); + for(int i = 0; i < 4; i++) + { + (*_DataAddress)[i] = connection_details[i].toInt(); + } + *_DataPort = connection_details[4].toInt() * 256 + connection_details[5].toInt(); + SendResponse(200, "PORT command successful"); + } +}; + +#endif diff --git a/lib/ESP-FTP-Server-Lib/src/Commands/PWD.h b/lib/ESP-FTP-Server-Lib/src/Commands/PWD.h new file mode 100644 index 0000000..6761333 --- /dev/null +++ b/lib/ESP-FTP-Server-Lib/src/Commands/PWD.h @@ -0,0 +1,18 @@ +#ifndef PWD_H_ +#define PWD_H_ + +#include +#include "../FTPCommand.h" + +class PWD : public FTPCommand +{ +public: + explicit PWD(WiFiClient * const Client) : FTPCommand("PWD", 0, Client) {} + + void run(FTPPath & WorkDirectory, const std::vector & Line) override + { + SendResponse(257, "\"" + WorkDirectory.getPath() + "\" is your current directory"); + } +}; + +#endif diff --git a/lib/ESP-FTP-Server-Lib/src/Commands/RETR.h b/lib/ESP-FTP-Server-Lib/src/Commands/RETR.h new file mode 100644 index 0000000..e772d70 --- /dev/null +++ b/lib/ESP-FTP-Server-Lib/src/Commands/RETR.h @@ -0,0 +1,55 @@ +#ifndef RETR_H_ +#define RETR_H_ + +#include +#include "../FTPCommand.h" +#include "../common.h" + +#define FTP_BUF_SIZE 4096 + +class RETR : public FTPCommandTransfer +{ +public: + explicit RETR(WiFiClient * const Client, FTPFilesystem * const Filesystem, IPAddress * DataAddress, int * DataPort) + : FTPCommandTransfer("RETR", 1, Client, Filesystem, DataAddress, DataPort) + {} + + void run(FTPPath & WorkDirectory, const std::vector & Line) override + { + if(trasferInProgress()) + { + return; + } + if(!ConnectDataConnection()) + { + return; + } + String path = WorkDirectory.getFilePath(Line[1]); + _file = _Filesystem->open(path); + if(!_file || _file.isDirectory()) + { + CloseDataConnection(); + SendResponse(550, "Can't open " + path); + return; + } + workOnData(); + } + + void workOnData() override + { + uint8_t buffer[FTP_BUF_SIZE]; + size_t nb = _file.read(buffer, FTP_BUF_SIZE); + if(nb > 0) + { + data_send(buffer, nb); + return; + } + CloseDataConnection(); + SendResponse(226, "File successfully transferred"); + _file.close(); + } + +private: +}; + +#endif diff --git a/lib/ESP-FTP-Server-Lib/src/Commands/RMD.h b/lib/ESP-FTP-Server-Lib/src/Commands/RMD.h new file mode 100644 index 0000000..a280ead --- /dev/null +++ b/lib/ESP-FTP-Server-Lib/src/Commands/RMD.h @@ -0,0 +1,31 @@ +#ifndef RMD_H_ +#define RMD_H_ + +#include +#include "../FTPCommand.h" + +class RMD : public FTPCommand +{ +public: + explicit RMD(WiFiClient * const Client, FTPFilesystem * const Filesystem) : FTPCommand("RMD", 1, Client, Filesystem) {} + + void run(FTPPath & WorkDirectory, const std::vector & Line) override + { + String filepath = WorkDirectory.getFilePath(Line[1]); + if(!_Filesystem->exists(filepath)) + { + SendResponse(550, "Folder " + filepath + " not found"); + return; + } + if(_Filesystem->rmdir(filepath)) + { + SendResponse(250, " Deleted \"" + filepath + "\""); + } + else + { + SendResponse(450, "Can't delete \"" + filepath + "\""); + } + } +}; + +#endif diff --git a/lib/ESP-FTP-Server-Lib/src/Commands/RNFR_RNTO.h b/lib/ESP-FTP-Server-Lib/src/Commands/RNFR_RNTO.h new file mode 100644 index 0000000..fd8d48a --- /dev/null +++ b/lib/ESP-FTP-Server-Lib/src/Commands/RNFR_RNTO.h @@ -0,0 +1,67 @@ +#ifndef RNFR_H_ +#define RNFR_H_ + +#include +#include "../FTPCommand.h" + +class RNFR_RNTO : public FTPCommand +{ +public: + explicit RNFR_RNTO(WiFiClient * const Client, FTPFilesystem * const Filesystem) : FTPCommand("RN", 1, Client, Filesystem), _fromSet(false) {} + + void run(FTPPath & WorkDirectory, const std::vector & Line) override + { + if(Line[0] == "RNFR") + { + from(WorkDirectory, Line); + } + else if(Line[0] == "RNTO") + { + to(WorkDirectory, Line); + } + } + + void from(const FTPPath & WorkDirectory, const std::vector & Line) + { + String filepath = WorkDirectory.getFilePath(Line[1]); + if(!_Filesystem->exists(filepath)) + { + SendResponse(550, "File " + Line[1] + " not found"); + return; + } + _fromSet = true; + _from = filepath; + SendResponse(350, "RNFR accepted - file exists, ready for destination"); + } + + void to(const FTPPath & WorkDirectory, const std::vector & Line) + { + if(!_fromSet) + { + SendResponse(503, "Need RNFR before RNTO"); + return; + } + String filepath = WorkDirectory.getFilePath(Line[1]); + if(_Filesystem->exists(filepath)) + { + SendResponse(553, "File " + Line[1] + " already exists"); + return; + } + if(_Filesystem->rename(_from, filepath)) + { + SendResponse(250, "File successfully renamed or moved"); + } + else + { + SendResponse(451, "Rename/move failure"); + } + _fromSet = false; + _from = ""; + } + +private: + bool _fromSet; + String _from; +}; + +#endif diff --git a/lib/ESP-FTP-Server-Lib/src/Commands/STOR.h b/lib/ESP-FTP-Server-Lib/src/Commands/STOR.h new file mode 100644 index 0000000..abc18d7 --- /dev/null +++ b/lib/ESP-FTP-Server-Lib/src/Commands/STOR.h @@ -0,0 +1,55 @@ +#ifndef STOR_H_ +#define STOR_H_ + +#include +#include "../FTPCommand.h" +#include "../common.h" + +#define FTP_BUF_SIZE 4096 + +class STOR : public FTPCommandTransfer +{ +public: + explicit STOR(WiFiClient * const Client, FTPFilesystem * const Filesystem, IPAddress * DataAddress, int * DataPort) + : FTPCommandTransfer("STOR", 1, Client, Filesystem, DataAddress, DataPort) + {} + + void run(FTPPath & WorkDirectory, const std::vector & Line) override + { + if(trasferInProgress()) + { + return; + } + if(!ConnectDataConnection()) + { + return; + } + String path = WorkDirectory.getFilePath(Line[1]); + _file = _Filesystem->open(path, "w"); + if(!_file) + { + CloseDataConnection(); + SendResponse(451, "Can't open/create " + path); + return; + } + workOnData(); + } + + void workOnData() override + { + uint8_t buffer[FTP_BUF_SIZE]; + int nb = data_read(buffer, FTP_BUF_SIZE); + if(nb > 0) + { + _file.write(buffer, nb); + return; + } + CloseDataConnection(); + SendResponse(226, "File successfully transferred"); + _file.close(); + } + +private: +}; + +#endif diff --git a/lib/ESP-FTP-Server-Lib/src/Commands/TYPE.h b/lib/ESP-FTP-Server-Lib/src/Commands/TYPE.h new file mode 100644 index 0000000..ddfe52c --- /dev/null +++ b/lib/ESP-FTP-Server-Lib/src/Commands/TYPE.h @@ -0,0 +1,28 @@ +#ifndef TYPE_H_ +#define TYPE_H_ + +#include +#include "../FTPCommand.h" + +class TYPE : public FTPCommand +{ +public: + explicit TYPE(WiFiClient * const Client) : FTPCommand("TYPE", 1, Client) {} + + void run(FTPPath & WorkDirectory, const std::vector & Line) override + { + if(Line[1] == "A") + { + SendResponse(200, "TYPE is now ASCII"); + return; + } + else if(Line[1] == "I") + { + SendResponse(200, "TYPE is now 8-bit binary"); + return; + } + SendResponse(504, "Unknow TYPE"); + } +}; + +#endif diff --git a/lib/ESP-FTP-Server-Lib/src/ESP-FTP-Server-Lib.cpp b/lib/ESP-FTP-Server-Lib/src/ESP-FTP-Server-Lib.cpp new file mode 100644 index 0000000..29156a5 --- /dev/null +++ b/lib/ESP-FTP-Server-Lib/src/ESP-FTP-Server-Lib.cpp @@ -0,0 +1,56 @@ +#include "ESP-FTP-Server-Lib.h" + +FTPServer::FTPServer() + : _Server(FTP_CTRL_PORT, 1) +{ +} + +FTPServer::~FTPServer() +{ +} + +void FTPServer::addUser(const String & Username, const String & Password) +{ + FTPUser user(Username, Password); + _UserList.push_back(user); +} + +void FTPServer::addUser(const FTPUser & User) +{ + _UserList.push_back(User); +} + +void FTPServer::addFilesystem(String Name, FS * const Filesystem) +{ + _Filesystem.addFilesystem(Name, Filesystem); +} + +bool FTPServer::begin() +{ + _Server.begin(); + return true; +} + +bool isNotConnected(const std::shared_ptr & con) +{ + return !con->connected(); +} + +void FTPServer::handle() +{ + if(_Server.hasClient()) + { + std::shared_ptr connection = std::shared_ptr(new FTPConnection(_Server.available(), _UserList, _Filesystem)); + _Connections.push_back(connection); + } + for(std::shared_ptr con: _Connections) + { + con->handle(); + } + _Connections.remove_if(isNotConnected); +} + +size_t FTPServer::countConnections() const +{ + return _Connections.size(); +} diff --git a/lib/ESP-FTP-Server-Lib/src/ESP-FTP-Server-Lib.h b/lib/ESP-FTP-Server-Lib/src/ESP-FTP-Server-Lib.h new file mode 100644 index 0000000..8b368e4 --- /dev/null +++ b/lib/ESP-FTP-Server-Lib/src/ESP-FTP-Server-Lib.h @@ -0,0 +1,38 @@ +#ifndef ESP_FTP_LIB_H_ +#define ESP_FTP_LIB_H_ + +#include +#include + +#include "FTPUser.h" +#include "FTPConnection.h" +#include "FTPFilesystem.h" + +class FTPServer +{ +public: + FTPServer(); + virtual ~FTPServer(); + + void addUser(const String & Username, const String & Password); + void addUser(const FTPUser & User); + + void addFilesystem(String Name, FS * const Filesystem); + + bool begin(); + void handle(); + + size_t countConnections() const; + +private: + WiFiServer _Server; + + std::list _UserList; + std::list> _Connections; + + FTPFilesystem _Filesystem; +}; + +#define FTP_DEBUG(txt) Serial.print("[DEBUG] "); Serial.println(txt) + +#endif diff --git a/lib/ESP-FTP-Server-Lib/src/FTPCommand.h b/lib/ESP-FTP-Server-Lib/src/FTPCommand.h new file mode 100644 index 0000000..580c24b --- /dev/null +++ b/lib/ESP-FTP-Server-Lib/src/FTPCommand.h @@ -0,0 +1,133 @@ +#ifndef FTP_COMMAND_H_ +#define FTP_COMMAND_H_ + +#include +#include +#include "FTPPath.h" +#include "FTPFilesystem.h" + +class FTPCommand +{ +public: + FTPCommand(String Name, int ExpectedArgumentCnt, WiFiClient * const Client, FTPFilesystem * const Filesystem = 0, IPAddress * DataAddress = 0, int * DataPort = 0) + : _Name(Name), _ExpectedArgumentCnt(ExpectedArgumentCnt), + _Filesystem(Filesystem), + _DataAddress(DataAddress), _DataPort(DataPort), _Client(Client), _DataConnection(0) {} + virtual ~FTPCommand() {} + + String getName() const + { + return _Name; + } + + virtual void run(FTPPath & WorkDirectory, const std::vector & Line) = 0; + + void SendResponse(int Code, String Text) + { + _Client->print(Code); + _Client->print(" "); + _Client->println(Text); + } + + bool ConnectDataConnection() + { + if(_DataConnection == 0) + { + _DataConnection = new WiFiClient(); + } + if(_DataConnection->connected()) + { + _DataConnection->stop(); + } + _DataConnection->connect(*_DataAddress, *_DataPort); + if(!_DataConnection->connected()) + { + _DataConnection->stop(); + SendResponse(425, "No data connection"); + return false; + } + SendResponse(150, "Accepted data connection"); + return true; + } + + void data_print(String str) + { + if(_DataConnection == 0 || !_DataConnection->connected()) + { + return; + } + _DataConnection->print(str); + } + + void data_println(String str) + { + if(_DataConnection == 0 || !_DataConnection->connected()) + { + return; + } + _DataConnection->println(str); + } + + void data_send(uint8_t * c, size_t l) + { + if(_DataConnection == 0 || !_DataConnection->connected()) + { + return; + } + _DataConnection->write(c, l); + } + + int data_read(uint8_t * c, size_t l) + { + if(_DataConnection == 0 || !_DataConnection->connected()) + { + return 0; + } + return _DataConnection->readBytes(c, l); + } + + void CloseDataConnection() + { + _DataConnection->stop(); + } + +protected: + String _Name; + int _ExpectedArgumentCnt; + FTPFilesystem * const _Filesystem; + IPAddress * const _DataAddress; + int * const _DataPort; + +private: + WiFiClient * const _Client; + WiFiClient * _DataConnection; +}; + +class FTPCommandTransfer : public FTPCommand +{ +public: + FTPCommandTransfer(String Name, int ExpectedArgumentCnt, WiFiClient * const Client, FTPFilesystem * const Filesystem = 0, IPAddress * DataAddress = 0, int * DataPort = 0) + : FTPCommand(Name, ExpectedArgumentCnt, Client, Filesystem, DataAddress, DataPort) {} + + virtual void workOnData() = 0; + + bool trasferInProgress() + { + return _file; + } + + void abort() + { + if(_file) + { + CloseDataConnection(); + SendResponse(426, "Transfer aborted"); + _file.close(); + } + } + +protected: + File _file; +}; + +#endif diff --git a/lib/ESP-FTP-Server-Lib/src/FTPConnection.cpp b/lib/ESP-FTP-Server-Lib/src/FTPConnection.cpp new file mode 100644 index 0000000..4bb54a2 --- /dev/null +++ b/lib/ESP-FTP-Server-Lib/src/FTPConnection.cpp @@ -0,0 +1,207 @@ +#include "ESP-FTP-Server-Lib.h" +#include "common.h" +#include "Commands/CDUP.h" +#include "Commands/CWD.h" +#include "Commands/DELE.h" +#include "Commands/LIST.h" +#include "Commands/MKD.h" +#include "Commands/PORT.h" +#include "Commands/PWD.h" +#include "Commands/RETR.h" +#include "Commands/RMD.h" +#include "Commands/RNFR_RNTO.h" +#include "Commands/STOR.h" +#include "Commands/TYPE.h" + +FTPConnection::FTPConnection(const WiFiClient & Client, std::list & UserList, FTPFilesystem & Filesystem) + : _ClientState(Idle), _Client(Client), _Filesystem(Filesystem), _UserList(UserList), _AuthUsername("") +{ + std::shared_ptr retr = std::shared_ptr(new RETR(&_Client, &_Filesystem, &_DataAddress, &_DataPort)); + std::shared_ptr stor = std::shared_ptr(new STOR(&_Client, &_Filesystem, &_DataAddress, &_DataPort)); + + _FTPCommands.push_back(std::shared_ptr(new CDUP(&_Client))); + _FTPCommands.push_back(std::shared_ptr(new CWD(&_Client, &_Filesystem))); + _FTPCommands.push_back(std::shared_ptr(new DELE(&_Client, &_Filesystem))); + _FTPCommands.push_back(std::shared_ptr(new LIST(&_Client, &_Filesystem, &_DataAddress, &_DataPort))); + _FTPCommands.push_back(std::shared_ptr(new MKD(&_Client, &_Filesystem))); + _FTPCommands.push_back(std::shared_ptr(new PORT(&_Client, &_DataAddress, &_DataPort))); + _FTPCommands.push_back(std::shared_ptr(new PWD(&_Client))); + _FTPCommands.push_back(retr); + _FTPCommands.push_back(std::shared_ptr(new RMD(&_Client, &_Filesystem))); + _FTPCommands.push_back(std::shared_ptr(new RNFR_RNTO(&_Client, &_Filesystem))); + _FTPCommands.push_back(stor); + _FTPCommands.push_back(std::shared_ptr(new TYPE(&_Client))); + + _FTPCommandsTransfer.push_back(retr); + _FTPCommandsTransfer.push_back(stor); + + Serial.print("New Connection from "); + Serial.print(_Client.remoteIP()); + Serial.print(":"); + Serial.println(_Client.remotePort()); + _Client.println("220--- Welcome to FTP Server for ESP32 ---"); + _Client.println("220--- By Peter Buchegger ---"); + _Client.println("220 -- Version 0.1 ---"); +} + +FTPConnection::~FTPConnection() +{ + Serial.println("Connection closed!"); +} + +bool FTPConnection::readUntilLineEnd() +{ + while(_Client.available()) + { + char c = _Client.read(); + if(c == '\n') + { + _LineSplited = Split>(_Line, ' '); + return true; + } + if(c >= 32 && c < 127) + { + _Line += c; + } + } + return false; +} + +bool FTPConnection::handle() +{ + if(!_Client.connected()) + { + return false; + } + for(std::shared_ptr cmd: _FTPCommandsTransfer) + { + if(cmd->trasferInProgress()) + { + cmd->workOnData(); + } + } + if(!readUntilLineEnd()) + { + return true; + } + // we have a new command in the queue: + Serial.println(_Line); + String command = _LineSplited[0]; + + // This commands are always possible: + if(command == "SYST") + { + _Client.println("215 UNIX Type: L8"); + _Line = ""; + return true; + } + else if(command == "QUIT") + { + _Client.println("221 Goodbye"); + _Client.stop(); + _Line = ""; + return true; + } + else if(command == "ABOR") + { + for(std::shared_ptr cmd: _FTPCommandsTransfer) + { + cmd->abort(); + } + _Client.println("226 Data connection closed"); + _Line = ""; + return true; + } + + // Logged in? + switch (_ClientState) + { + case Idle: + if(command == "USER") + { + c_USER(); + } + break; + + case UsernamePass: + if(command == "PASS") + { + c_PASS(); + } + break; + + case AuthPass: + { + std::vector>::iterator cmdIter = std::find_if(_FTPCommands.begin(), _FTPCommands.end(), [&](std::shared_ptr cmd) + { + if(command == cmd->getName() || (cmd->getName() == "RN" && (command == "RNFR" || command == "RNTO"))) + { + return true; + } + return false; + } + ); + if(cmdIter != _FTPCommands.end()) + { + (*cmdIter)->run(_WorkDirectory, _LineSplited); + _Line = ""; + return true; + } + } + + default: + _Client.println("500 Unknow command"); + break; + } + _Line = ""; + return true; +} + +bool FTPConnection::connected() +{ + return _Client.connected(); +} + +void FTPConnection::c_USER() +{ + String username = _LineSplited[1]; + std::list::iterator userIter = std::find_if(_UserList.begin(), _UserList.end(), [&](const FTPUser & user) + { + if(username == user.Username) + { + return true; + } + return false; + } + ); + if(userIter != _UserList.end()) + { + _AuthUsername = username; + _Client.println("331 OK. Password required"); + _ClientState = UsernamePass; + return; + } + _Client.println("530 user not found"); +} + +void FTPConnection::c_PASS() +{ + String password = _LineSplited[1]; + String username = _AuthUsername; + std::list::iterator _user = std::find_if(_UserList.begin(), _UserList.end(), [&](const FTPUser & user) + { + if(username == user.Username && password == user.Password) + { + return true; + } + return false; + } + ); + if(_user != _UserList.end()) + { + _Client.println("230 OK."); + _ClientState = AuthPass; + return; + } + _Client.println("530 passwort not correct"); +} diff --git a/lib/ESP-FTP-Server-Lib/src/FTPConnection.h b/lib/ESP-FTP-Server-Lib/src/FTPConnection.h new file mode 100644 index 0000000..f20d0c9 --- /dev/null +++ b/lib/ESP-FTP-Server-Lib/src/FTPConnection.h @@ -0,0 +1,59 @@ +#ifndef FTP_CONNECTION_H_ +#define FTP_CONNECTION_H_ + +#include +#include +#include "FTPPath.h" +#include "FTPCommand.h" + +#define FTP_CTRL_PORT 21 +#define FTP_USER_TIME_OUT 5 +#define FTP_CMD_SIZE 255 + 8 // max size of a command +#define FTP_DIRNAME_SIZE 255 + 8 // max size of a directory name +#define FTP_FILENAME_SIZE 255 // max size of a file name + +class FTPConnection +{ +public: + FTPConnection(const WiFiClient & Client, std::list & UserList, FTPFilesystem & Filesystem); + virtual ~FTPConnection(); + + bool readUntilLineEnd(); + + bool handle(); + + bool connected(); + + +private: + enum ClientState + { + Idle, + UsernamePass, + AuthPass, + }; + + void c_USER(); + void c_PASS(); + + ClientState _ClientState; + WiFiClient _Client; + FTPFilesystem & _Filesystem; + String _FilePath; + + String _Line; + std::vector _LineSplited; + + std::list & _UserList; + String _AuthUsername; + + IPAddress _DataAddress; + int _DataPort; + + FTPPath _WorkDirectory; + + std::vector> _FTPCommands; + std::vector> _FTPCommandsTransfer; +}; + +#endif diff --git a/lib/ESP-FTP-Server-Lib/src/FTPFilesystem.cpp b/lib/ESP-FTP-Server-Lib/src/FTPFilesystem.cpp new file mode 100644 index 0000000..030814a --- /dev/null +++ b/lib/ESP-FTP-Server-Lib/src/FTPFilesystem.cpp @@ -0,0 +1,120 @@ +#include "FTPFilesystem.h" +#include "common.h" + +FTPFilesystem::FTPFilesystem() +{ +} + +FTPFilesystem::~FTPFilesystem() +{ +} + +void FTPFilesystem::addFilesystem(String Name, FS * const Filesystem) +{ + _Filesystems[Name] = Filesystem; +} + +void FTPFilesystem::clearFilesystemList() +{ + _Filesystems.clear(); +} + +File FTPFilesystem::open(const String & path, const char* mode) +{ + if(path == "/") + { + std::shared_ptr root = std::shared_ptr(new FTPFileImpl("/")); + for(auto const & f: _Filesystems) + { + root->addFilesystem(f.first); + } + return File(root); + } + FS * fs = getFilesystem(path); + return fs->open(getPathWithoutFS(path), mode); +} + +bool FTPFilesystem::exists(const String & path) +{ + FS * fs = getFilesystem(path); + if(fs == 0) + { + return false; + } + return fs->exists(getPathWithoutFS(path)); +} + +bool FTPFilesystem::remove(const String & path) +{ + FS * fs = getFilesystem(path); + if(fs == 0) + { + return false; + } + return fs->remove(getPathWithoutFS(path)); +} + +bool FTPFilesystem::rename(const String & pathFrom, const String & pathTo) +{ + FS * fsFrom = getFilesystem(pathFrom); + FS * fsTo = getFilesystem(pathTo); + if(fsFrom == 0 || fsTo == 0) + { + return false; + } + if(fsFrom != fsTo) + { + // cant move/rename from one filesystem to another one! + return false; + } + return fsFrom->rename(getPathWithoutFS(pathFrom), getPathWithoutFS(pathTo)); +} + +bool FTPFilesystem::mkdir(const String & path) +{ + FS * fs = getFilesystem(path); + if(fs == 0) + { + return false; + } + return fs->mkdir(getPathWithoutFS(path)); +} + +bool FTPFilesystem::rmdir(const String & path) +{ + FS * fs = getFilesystem(path); + if(fs == 0) + { + return false; + } + return fs->rmdir(getPathWithoutFS(path)); +} + +void FTPFilesystem::printFilesystems() +{ + for (auto const & fs: _Filesystems) + { + Serial.println(fs.first); + } +} + +FS * FTPFilesystem::getFilesystem(String path) +{ + std::list splitted = FTPPath::splitPath(path); + String name = *(splitted.begin()); + std::map::iterator iter = _Filesystems.find(name); + if(iter == _Filesystems.end()) + { + Serial.println("[ERROR] Filesystem not found!"); + return 0; + } + return iter->second; +} + +String FTPFilesystem::getPathWithoutFS(String path) +{ + std::list splitted = FTPPath::splitPath(path); + splitted.pop_front(); + String path_without = FTPPath::createPath(splitted); + return path_without; +} diff --git a/lib/ESP-FTP-Server-Lib/src/FTPFilesystem.h b/lib/ESP-FTP-Server-Lib/src/FTPFilesystem.h new file mode 100644 index 0000000..56da178 --- /dev/null +++ b/lib/ESP-FTP-Server-Lib/src/FTPFilesystem.h @@ -0,0 +1,70 @@ +#ifndef FTP_FILESYSTEM_H_ +#define FTP_FILESYSTEM_H_ + +#include +#include +#include +#include "FTPPath.h" + +class FTPFilesystem +{ +public: + FTPFilesystem(); + virtual ~FTPFilesystem(); + + void addFilesystem(String Name, FS * const Filesystem); + void clearFilesystemList(); + + File open(const String & path, const char* mode = FILE_READ); + bool exists(const String & path); + bool remove(const String & path); + bool rename(const String & pathFrom, const String & pathTo); + bool mkdir(const String & path); + bool rmdir(const String & path); + + void printFilesystems(); + +#ifndef UNIT_TEST +private: +#endif + FS * getFilesystem(String path); + static String getPathWithoutFS(String path); + + std::map _Filesystems; +}; + +class FTPFileImpl : public fs::FileImpl +{ +public: + explicit FTPFileImpl(String name) : _Name(name) {} + ~FTPFileImpl() {} + size_t write(const uint8_t *buf, size_t size) override { return 0; }; + size_t read(uint8_t* buf, size_t size) override { return 0; }; + void flush() override {}; + bool seek(uint32_t pos, SeekMode mode) override { return false; }; + size_t position() const override { return 0; }; + size_t size() const override { return 0; }; + void close() override {}; + time_t getLastWrite() override { return 0; }; + const char* name() const override { return _Name.c_str(); }; + boolean isDirectory(void) override { return true; }; + fs::FileImplPtr openNextFile(const char* mode) override + { + if(_Filesystems.empty()) + { + return 0; + } + String next = _Filesystems.front(); + _Filesystems.pop_front(); + return fs::FileImplPtr(new FTPFileImpl(next)); + } + void rewindDirectory(void) override {}; + operator bool() override { return false; }; + + void addFilesystem(String name) { _Filesystems.push_back(name); } +private: + String _Name; + std::list _Filesystems; +}; + +#endif diff --git a/lib/ESP-FTP-Server-Lib/src/FTPPath.cpp b/lib/ESP-FTP-Server-Lib/src/FTPPath.cpp new file mode 100644 index 0000000..9990ac8 --- /dev/null +++ b/lib/ESP-FTP-Server-Lib/src/FTPPath.cpp @@ -0,0 +1,75 @@ +#include "FTPPath.h" +#include "common.h" + +FTPPath::FTPPath() +{ +} + +FTPPath::FTPPath(String path) +{ + changePath(path); +} + +FTPPath::~FTPPath() +{ +} + +void FTPPath::changePath(String path) +{ + std::list p = splitPath(path); + std::copy(p.begin(), p.end(), std::back_inserter(_Path)); +} + +void FTPPath::goPathUp() +{ + _Path.pop_back(); +} + +String FTPPath::getPath() const +{ + return createPath(_Path); +} + +String FTPPath::getFilePath(String filename) const +{ + if(*filename.begin() == '/') + { + return filename; + } + if(_Path.size() == 0) + { + return "/" + filename; + } + return getPath() + "/" + filename; +} + +std::list FTPPath::splitPath(String path) +{ + std::list p = Split>(path, '/'); + p.erase( + std::remove_if(p.begin(), p.end(), [](const String & s) + { + if(s.isEmpty()) + { + return true; + } + return false; + }), + p.end()); + return p; +} + +String FTPPath::createPath(std::list path) +{ + if(path.size() == 0) + { + return "/"; + } + String new_path; + for(const String & p: path) + { + new_path += "/"; + new_path += p; + } + return new_path; +} diff --git a/lib/ESP-FTP-Server-Lib/src/FTPPath.h b/lib/ESP-FTP-Server-Lib/src/FTPPath.h new file mode 100644 index 0000000..110e2e0 --- /dev/null +++ b/lib/ESP-FTP-Server-Lib/src/FTPPath.h @@ -0,0 +1,27 @@ +#ifndef FTP_PATH_H_ +#define FTP_PATH_H_ + +#include +#include + +class FTPPath +{ +public: + FTPPath(); + explicit FTPPath(String path); + virtual ~FTPPath(); + + void changePath(String path); + void goPathUp(); + + String getPath() const; + String getFilePath(String filename) const; + + static std::list splitPath(String path); + static String createPath(std::list path); + +private: + std::list _Path; +}; + +#endif diff --git a/lib/ESP-FTP-Server-Lib/src/FTPUser.h b/lib/ESP-FTP-Server-Lib/src/FTPUser.h new file mode 100644 index 0000000..ea6f39f --- /dev/null +++ b/lib/ESP-FTP-Server-Lib/src/FTPUser.h @@ -0,0 +1,14 @@ +#ifndef FTP_USER_H_ +#define FTP_USER_H_ + +#include + +class FTPUser +{ +public: + FTPUser(const String & username, const String & password) : Username(username), Password(password) {} + const String Username; + const String Password; +}; + +#endif diff --git a/lib/ESP-FTP-Server-Lib/src/common.cpp b/lib/ESP-FTP-Server-Lib/src/common.cpp new file mode 100644 index 0000000..8c3e2cf --- /dev/null +++ b/lib/ESP-FTP-Server-Lib/src/common.cpp @@ -0,0 +1,22 @@ +#include "common.h" + +/* +template +T Split(String str, char parser) +{ + T str_array; + int last_idx = 0; + int next_idx = str.indexOf(parser, last_idx); + do + { + str_array.push_back(str.substring(last_idx, next_idx)); + last_idx = next_idx + 1; + next_idx = str.indexOf(parser, last_idx); + if(next_idx == -1 && last_idx != 0) + { + str_array.push_back(str.substring(last_idx, str.length())); + } + } while (next_idx != -1); + return str_array; +} +*/ diff --git a/lib/ESP-FTP-Server-Lib/src/common.h b/lib/ESP-FTP-Server-Lib/src/common.h new file mode 100644 index 0000000..4a40e35 --- /dev/null +++ b/lib/ESP-FTP-Server-Lib/src/common.h @@ -0,0 +1,27 @@ +#ifndef COMMON_H_ +#define COMMON_H_ + +#include +#include +#include + +template +T Split(String str, char parser) +{ + T str_array; + int last_idx = 0; + int next_idx = str.indexOf(parser, last_idx); + do + { + str_array.push_back(str.substring(last_idx, next_idx)); + last_idx = next_idx + 1; + next_idx = str.indexOf(parser, last_idx); + if(next_idx == -1 && last_idx != 0) + { + str_array.push_back(str.substring(last_idx, str.length())); + } + } while (next_idx != -1); + return str_array; +} + +#endif diff --git a/platformio.ini b/platformio.ini index 34a9ddf..9ec6861 100644 --- a/platformio.ini +++ b/platformio.ini @@ -12,7 +12,7 @@ lib_deps = sandeepmistry/LoRa @ 0.7.2 peterus/APRS-Decoder-Lib @ 0.0.5 peterus/APRS-IS-Lib @ 0.0.7 - peterus/ESP-FTP-Server-Lib @ 0.9.3 + peterus/ESP-FTP-Server-Lib @ 0.9.2 peterus/LoRa-APRS-Lib @ 0.0.5 check_tool = cppcheck check_flags = From 75024a2617d84520b1803a35a07a0ba049edeb0f Mon Sep 17 00:00:00 2001 From: Peter Buchegger Date: Thu, 5 Nov 2020 23:25:59 +0100 Subject: [PATCH 08/29] FTP lib got added again in correct version --- lib/ESP-FTP-Server-Lib/.gitignore | 5 - lib/ESP-FTP-Server-Lib/LICENSE | 21 -- lib/ESP-FTP-Server-Lib/README.md | 34 --- lib/ESP-FTP-Server-Lib/library.properties | 11 - lib/ESP-FTP-Server-Lib/platformio.ini | 9 - lib/ESP-FTP-Server-Lib/src/Commands/CDUP.h | 19 -- lib/ESP-FTP-Server-Lib/src/Commands/CWD.h | 37 ---- lib/ESP-FTP-Server-Lib/src/Commands/DELE.h | 31 --- lib/ESP-FTP-Server-Lib/src/Commands/LIST.h | 58 ----- lib/ESP-FTP-Server-Lib/src/Commands/MKD.h | 31 --- lib/ESP-FTP-Server-Lib/src/Commands/PORT.h | 27 --- lib/ESP-FTP-Server-Lib/src/Commands/PWD.h | 18 -- lib/ESP-FTP-Server-Lib/src/Commands/RETR.h | 55 ----- lib/ESP-FTP-Server-Lib/src/Commands/RMD.h | 31 --- .../src/Commands/RNFR_RNTO.h | 67 ------ lib/ESP-FTP-Server-Lib/src/Commands/STOR.h | 55 ----- lib/ESP-FTP-Server-Lib/src/Commands/TYPE.h | 28 --- .../src/ESP-FTP-Server-Lib.cpp | 56 ----- .../src/ESP-FTP-Server-Lib.h | 38 ---- lib/ESP-FTP-Server-Lib/src/FTPCommand.h | 133 ----------- lib/ESP-FTP-Server-Lib/src/FTPConnection.cpp | 207 ------------------ lib/ESP-FTP-Server-Lib/src/FTPConnection.h | 59 ----- lib/ESP-FTP-Server-Lib/src/FTPFilesystem.cpp | 120 ---------- lib/ESP-FTP-Server-Lib/src/FTPFilesystem.h | 70 ------ lib/ESP-FTP-Server-Lib/src/FTPPath.cpp | 75 ------- lib/ESP-FTP-Server-Lib/src/FTPPath.h | 27 --- lib/ESP-FTP-Server-Lib/src/FTPUser.h | 14 -- lib/ESP-FTP-Server-Lib/src/common.cpp | 22 -- lib/ESP-FTP-Server-Lib/src/common.h | 27 --- platformio.ini | 2 +- 30 files changed, 1 insertion(+), 1386 deletions(-) delete mode 100644 lib/ESP-FTP-Server-Lib/.gitignore delete mode 100644 lib/ESP-FTP-Server-Lib/LICENSE delete mode 100644 lib/ESP-FTP-Server-Lib/README.md delete mode 100644 lib/ESP-FTP-Server-Lib/library.properties delete mode 100644 lib/ESP-FTP-Server-Lib/platformio.ini delete mode 100644 lib/ESP-FTP-Server-Lib/src/Commands/CDUP.h delete mode 100644 lib/ESP-FTP-Server-Lib/src/Commands/CWD.h delete mode 100644 lib/ESP-FTP-Server-Lib/src/Commands/DELE.h delete mode 100644 lib/ESP-FTP-Server-Lib/src/Commands/LIST.h delete mode 100644 lib/ESP-FTP-Server-Lib/src/Commands/MKD.h delete mode 100644 lib/ESP-FTP-Server-Lib/src/Commands/PORT.h delete mode 100644 lib/ESP-FTP-Server-Lib/src/Commands/PWD.h delete mode 100644 lib/ESP-FTP-Server-Lib/src/Commands/RETR.h delete mode 100644 lib/ESP-FTP-Server-Lib/src/Commands/RMD.h delete mode 100644 lib/ESP-FTP-Server-Lib/src/Commands/RNFR_RNTO.h delete mode 100644 lib/ESP-FTP-Server-Lib/src/Commands/STOR.h delete mode 100644 lib/ESP-FTP-Server-Lib/src/Commands/TYPE.h delete mode 100644 lib/ESP-FTP-Server-Lib/src/ESP-FTP-Server-Lib.cpp delete mode 100644 lib/ESP-FTP-Server-Lib/src/ESP-FTP-Server-Lib.h delete mode 100644 lib/ESP-FTP-Server-Lib/src/FTPCommand.h delete mode 100644 lib/ESP-FTP-Server-Lib/src/FTPConnection.cpp delete mode 100644 lib/ESP-FTP-Server-Lib/src/FTPConnection.h delete mode 100644 lib/ESP-FTP-Server-Lib/src/FTPFilesystem.cpp delete mode 100644 lib/ESP-FTP-Server-Lib/src/FTPFilesystem.h delete mode 100644 lib/ESP-FTP-Server-Lib/src/FTPPath.cpp delete mode 100644 lib/ESP-FTP-Server-Lib/src/FTPPath.h delete mode 100644 lib/ESP-FTP-Server-Lib/src/FTPUser.h delete mode 100644 lib/ESP-FTP-Server-Lib/src/common.cpp delete mode 100644 lib/ESP-FTP-Server-Lib/src/common.h diff --git a/lib/ESP-FTP-Server-Lib/.gitignore b/lib/ESP-FTP-Server-Lib/.gitignore deleted file mode 100644 index 89cc49c..0000000 --- a/lib/ESP-FTP-Server-Lib/.gitignore +++ /dev/null @@ -1,5 +0,0 @@ -.pio -.vscode/.browse.c_cpp.db* -.vscode/c_cpp_properties.json -.vscode/launch.json -.vscode/ipch diff --git a/lib/ESP-FTP-Server-Lib/LICENSE b/lib/ESP-FTP-Server-Lib/LICENSE deleted file mode 100644 index 4960c37..0000000 --- a/lib/ESP-FTP-Server-Lib/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2020 Peter Buchegger - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/lib/ESP-FTP-Server-Lib/README.md b/lib/ESP-FTP-Server-Lib/README.md deleted file mode 100644 index 72b2daf..0000000 --- a/lib/ESP-FTP-Server-Lib/README.md +++ /dev/null @@ -1,34 +0,0 @@ -# ESP-FTP-Server-Lib - -This library will provide a simple and modern FTP server for your ESP32 or ESP8266 device. -You can setup multiple users and mutliple filesystems (SD-Card, MMC-Card or/and SPIFFS). - -## Examples - -In the example folder you can find a very simple usage of the FTP server. You just need to setup the users, add the filesystems which you want to use, and call the handle function in the loop. - -## Known Commands to the server - -Currently all kind of simple commands are known to the server: -* CDUP -* CWD -* DELE -* LISST -* MKD -* PORT -* PWD -* RETR -* RMD -* RNFR -* RNTO -* STOR -* TYPE -* SYST -* QUIT -* ABOR - -## What is still missing / TODO - -Some commands are still missing, if you need them create a ticket :) - -Currently just the active mode is supported. For the passive mode you need to wait until version 1.0.0. diff --git a/lib/ESP-FTP-Server-Lib/library.properties b/lib/ESP-FTP-Server-Lib/library.properties deleted file mode 100644 index 4101a6b..0000000 --- a/lib/ESP-FTP-Server-Lib/library.properties +++ /dev/null @@ -1,11 +0,0 @@ -name=ESP-FTP-Server-Lib -version=0.9.3 -author=Peter Buchegger -maintainer=Peter Buchegger -sentence=Simple and modern FTP server for ESP devices. -paragraph=With this library you can run a simple and modern FTP server on your ESP32 or ESP8266. You can mount multiple filesystems like SD-Card, MMC-Card or SPIFFS at the same time. -category=Communication -url=https://github.com/peterus/ESP-FTP-Server-Lib -architectures=esp8266,esp32,arduino-esp32 -includes=ESP-FTP-Server-Lib.h -depends= diff --git a/lib/ESP-FTP-Server-Lib/platformio.ini b/lib/ESP-FTP-Server-Lib/platformio.ini deleted file mode 100644 index 9fbe7ec..0000000 --- a/lib/ESP-FTP-Server-Lib/platformio.ini +++ /dev/null @@ -1,9 +0,0 @@ - -[env:ttgo-lora32-v1] -platform = espressif32 -board = ttgo-lora32-v1 -framework = arduino -test_build_project_src = yes -monitor_speed = 115200 -check_flags = - cppcheck: --suppress=*:*.pio\* --suppress=unusedFunction diff --git a/lib/ESP-FTP-Server-Lib/src/Commands/CDUP.h b/lib/ESP-FTP-Server-Lib/src/Commands/CDUP.h deleted file mode 100644 index 474607e..0000000 --- a/lib/ESP-FTP-Server-Lib/src/Commands/CDUP.h +++ /dev/null @@ -1,19 +0,0 @@ -#ifndef CDUP_H_ -#define CDUP_H_ - -#include -#include "../FTPCommand.h" - -class CDUP : public FTPCommand -{ -public: - explicit CDUP(WiFiClient * const Client) : FTPCommand("CDUP", 0, Client) {} - - void run(FTPPath & WorkDirectory, const std::vector & Line) override - { - WorkDirectory.goPathUp(); - SendResponse(250, "Ok. Current directory is " + WorkDirectory.getPath()); - } -}; - -#endif diff --git a/lib/ESP-FTP-Server-Lib/src/Commands/CWD.h b/lib/ESP-FTP-Server-Lib/src/Commands/CWD.h deleted file mode 100644 index 9216e55..0000000 --- a/lib/ESP-FTP-Server-Lib/src/Commands/CWD.h +++ /dev/null @@ -1,37 +0,0 @@ -#ifndef CWD_H_ -#define CWD_H_ - -#include -#include "../FTPCommand.h" - -class CWD : public FTPCommand -{ -public: - explicit CWD(WiFiClient * const Client, FTPFilesystem * const Filesystem) : FTPCommand("CWD", 1, Client, Filesystem) {} - - void run(FTPPath & WorkDirectory, const std::vector & Line) override - { - FTPPath path = WorkDirectory; - Serial.println(Line[1]); - if(Line[1] == "..") - { - path.goPathUp(); - } - else - { - path.changePath(Line[1]); - } - File dir = _Filesystem->open(path.getPath()); - if(dir.isDirectory()) - { - WorkDirectory = path; - SendResponse(250, "Ok. Current directory is " + WorkDirectory.getPath()); - } - else - { - SendResponse(550, "Directory does not exist"); - } - } -}; - -#endif diff --git a/lib/ESP-FTP-Server-Lib/src/Commands/DELE.h b/lib/ESP-FTP-Server-Lib/src/Commands/DELE.h deleted file mode 100644 index d0a4f4e..0000000 --- a/lib/ESP-FTP-Server-Lib/src/Commands/DELE.h +++ /dev/null @@ -1,31 +0,0 @@ -#ifndef DELE_H_ -#define DELE_H_ - -#include -#include "../FTPCommand.h" - -class DELE : public FTPCommand -{ -public: - explicit DELE(WiFiClient * const Client, FTPFilesystem * const Filesystem) : FTPCommand("DELE", 1, Client, Filesystem) {} - - void run(FTPPath & WorkDirectory, const std::vector & Line) override - { - String filepath = WorkDirectory.getFilePath(Line[1]); - if(!_Filesystem->exists(filepath)) - { - SendResponse(550, "File " + filepath + " not found"); - return; - } - if(_Filesystem->remove(filepath)) - { - SendResponse(250, " Deleted \"" + filepath + "\""); - } - else - { - SendResponse(450, "Can't delete \"" + filepath + "\""); - } - } -}; - -#endif diff --git a/lib/ESP-FTP-Server-Lib/src/Commands/LIST.h b/lib/ESP-FTP-Server-Lib/src/Commands/LIST.h deleted file mode 100644 index 487c1aa..0000000 --- a/lib/ESP-FTP-Server-Lib/src/Commands/LIST.h +++ /dev/null @@ -1,58 +0,0 @@ -#ifndef LIST_H_ -#define LIST_H_ - -#include -#include "../FTPCommand.h" -#include "../common.h" - -class LIST : public FTPCommand -{ -public: - explicit LIST(WiFiClient * const Client, FTPFilesystem * const Filesystem, IPAddress * DataAddress, int * DataPort) - : FTPCommand("LIST", 1, Client, Filesystem, DataAddress, DataPort) - {} - - void run(FTPPath & WorkDirectory, const std::vector & Line) override - { - if(!ConnectDataConnection()) - { - return; - } - File dir = _Filesystem->open(WorkDirectory.getPath()); - if(!dir || !dir.isDirectory()) - { - CloseDataConnection(); - SendResponse(550, "Can't open directory " + WorkDirectory.getPath()); - return; - } - int cnt = 0; - File f = dir.openNextFile(); - while(f) - { - String filename = f.name(); - filename.remove(0, filename.lastIndexOf('/') + 1); - if(f.isDirectory()) - { - data_print("drwxr-xr-x"); - } - else - { - data_print("-rw-r--r--"); - } - String filesize = String(f.size()); - data_print(" 1 owner group "); - int fill_cnt = 13 - filesize.length(); - for(int i = 0; i < fill_cnt; i++) - { - data_print(" "); - } - data_println(filesize + " Jan 01 1970 " + filename); - cnt++; - f = dir.openNextFile(); - } - CloseDataConnection(); - SendResponse(226, String(cnt) + " matches total"); - } -}; - -#endif diff --git a/lib/ESP-FTP-Server-Lib/src/Commands/MKD.h b/lib/ESP-FTP-Server-Lib/src/Commands/MKD.h deleted file mode 100644 index 3f8a88e..0000000 --- a/lib/ESP-FTP-Server-Lib/src/Commands/MKD.h +++ /dev/null @@ -1,31 +0,0 @@ -#ifndef MKD_H_ -#define MKD_H_ - -#include -#include "../FTPCommand.h" - -class MKD : public FTPCommand -{ -public: - explicit MKD(WiFiClient * const Client, FTPFilesystem * const Filesystem) : FTPCommand("MKD", 1, Client, Filesystem) {} - - void run(FTPPath & WorkDirectory, const std::vector & Line) override - { - String filepath = WorkDirectory.getFilePath(Line[1]); - if(_Filesystem->exists(filepath)) - { - SendResponse(521, "Can't create \"" + filepath + "\", Directory exists"); - return; - } - if(_Filesystem->mkdir(filepath)) - { - SendResponse(257, "\"" + filepath + "\" created"); - } - else - { - SendResponse(550, "Can't create \"" + filepath + "\""); - } - } -}; - -#endif diff --git a/lib/ESP-FTP-Server-Lib/src/Commands/PORT.h b/lib/ESP-FTP-Server-Lib/src/Commands/PORT.h deleted file mode 100644 index 13c4815..0000000 --- a/lib/ESP-FTP-Server-Lib/src/Commands/PORT.h +++ /dev/null @@ -1,27 +0,0 @@ -#ifndef PORT_H_ -#define PORT_H_ - -#include -#include "../FTPCommand.h" -#include "../common.h" - -class PORT : public FTPCommand -{ -public: - explicit PORT(WiFiClient * const Client, IPAddress * DataAddress, int * DataPort) - : FTPCommand("PORT", 1, Client, 0, DataAddress, DataPort) - {} - - void run(FTPPath & WorkDirectory, const std::vector & Line) override - { - std::vector connection_details = Split>(Line[1], ','); - for(int i = 0; i < 4; i++) - { - (*_DataAddress)[i] = connection_details[i].toInt(); - } - *_DataPort = connection_details[4].toInt() * 256 + connection_details[5].toInt(); - SendResponse(200, "PORT command successful"); - } -}; - -#endif diff --git a/lib/ESP-FTP-Server-Lib/src/Commands/PWD.h b/lib/ESP-FTP-Server-Lib/src/Commands/PWD.h deleted file mode 100644 index 6761333..0000000 --- a/lib/ESP-FTP-Server-Lib/src/Commands/PWD.h +++ /dev/null @@ -1,18 +0,0 @@ -#ifndef PWD_H_ -#define PWD_H_ - -#include -#include "../FTPCommand.h" - -class PWD : public FTPCommand -{ -public: - explicit PWD(WiFiClient * const Client) : FTPCommand("PWD", 0, Client) {} - - void run(FTPPath & WorkDirectory, const std::vector & Line) override - { - SendResponse(257, "\"" + WorkDirectory.getPath() + "\" is your current directory"); - } -}; - -#endif diff --git a/lib/ESP-FTP-Server-Lib/src/Commands/RETR.h b/lib/ESP-FTP-Server-Lib/src/Commands/RETR.h deleted file mode 100644 index e772d70..0000000 --- a/lib/ESP-FTP-Server-Lib/src/Commands/RETR.h +++ /dev/null @@ -1,55 +0,0 @@ -#ifndef RETR_H_ -#define RETR_H_ - -#include -#include "../FTPCommand.h" -#include "../common.h" - -#define FTP_BUF_SIZE 4096 - -class RETR : public FTPCommandTransfer -{ -public: - explicit RETR(WiFiClient * const Client, FTPFilesystem * const Filesystem, IPAddress * DataAddress, int * DataPort) - : FTPCommandTransfer("RETR", 1, Client, Filesystem, DataAddress, DataPort) - {} - - void run(FTPPath & WorkDirectory, const std::vector & Line) override - { - if(trasferInProgress()) - { - return; - } - if(!ConnectDataConnection()) - { - return; - } - String path = WorkDirectory.getFilePath(Line[1]); - _file = _Filesystem->open(path); - if(!_file || _file.isDirectory()) - { - CloseDataConnection(); - SendResponse(550, "Can't open " + path); - return; - } - workOnData(); - } - - void workOnData() override - { - uint8_t buffer[FTP_BUF_SIZE]; - size_t nb = _file.read(buffer, FTP_BUF_SIZE); - if(nb > 0) - { - data_send(buffer, nb); - return; - } - CloseDataConnection(); - SendResponse(226, "File successfully transferred"); - _file.close(); - } - -private: -}; - -#endif diff --git a/lib/ESP-FTP-Server-Lib/src/Commands/RMD.h b/lib/ESP-FTP-Server-Lib/src/Commands/RMD.h deleted file mode 100644 index a280ead..0000000 --- a/lib/ESP-FTP-Server-Lib/src/Commands/RMD.h +++ /dev/null @@ -1,31 +0,0 @@ -#ifndef RMD_H_ -#define RMD_H_ - -#include -#include "../FTPCommand.h" - -class RMD : public FTPCommand -{ -public: - explicit RMD(WiFiClient * const Client, FTPFilesystem * const Filesystem) : FTPCommand("RMD", 1, Client, Filesystem) {} - - void run(FTPPath & WorkDirectory, const std::vector & Line) override - { - String filepath = WorkDirectory.getFilePath(Line[1]); - if(!_Filesystem->exists(filepath)) - { - SendResponse(550, "Folder " + filepath + " not found"); - return; - } - if(_Filesystem->rmdir(filepath)) - { - SendResponse(250, " Deleted \"" + filepath + "\""); - } - else - { - SendResponse(450, "Can't delete \"" + filepath + "\""); - } - } -}; - -#endif diff --git a/lib/ESP-FTP-Server-Lib/src/Commands/RNFR_RNTO.h b/lib/ESP-FTP-Server-Lib/src/Commands/RNFR_RNTO.h deleted file mode 100644 index fd8d48a..0000000 --- a/lib/ESP-FTP-Server-Lib/src/Commands/RNFR_RNTO.h +++ /dev/null @@ -1,67 +0,0 @@ -#ifndef RNFR_H_ -#define RNFR_H_ - -#include -#include "../FTPCommand.h" - -class RNFR_RNTO : public FTPCommand -{ -public: - explicit RNFR_RNTO(WiFiClient * const Client, FTPFilesystem * const Filesystem) : FTPCommand("RN", 1, Client, Filesystem), _fromSet(false) {} - - void run(FTPPath & WorkDirectory, const std::vector & Line) override - { - if(Line[0] == "RNFR") - { - from(WorkDirectory, Line); - } - else if(Line[0] == "RNTO") - { - to(WorkDirectory, Line); - } - } - - void from(const FTPPath & WorkDirectory, const std::vector & Line) - { - String filepath = WorkDirectory.getFilePath(Line[1]); - if(!_Filesystem->exists(filepath)) - { - SendResponse(550, "File " + Line[1] + " not found"); - return; - } - _fromSet = true; - _from = filepath; - SendResponse(350, "RNFR accepted - file exists, ready for destination"); - } - - void to(const FTPPath & WorkDirectory, const std::vector & Line) - { - if(!_fromSet) - { - SendResponse(503, "Need RNFR before RNTO"); - return; - } - String filepath = WorkDirectory.getFilePath(Line[1]); - if(_Filesystem->exists(filepath)) - { - SendResponse(553, "File " + Line[1] + " already exists"); - return; - } - if(_Filesystem->rename(_from, filepath)) - { - SendResponse(250, "File successfully renamed or moved"); - } - else - { - SendResponse(451, "Rename/move failure"); - } - _fromSet = false; - _from = ""; - } - -private: - bool _fromSet; - String _from; -}; - -#endif diff --git a/lib/ESP-FTP-Server-Lib/src/Commands/STOR.h b/lib/ESP-FTP-Server-Lib/src/Commands/STOR.h deleted file mode 100644 index abc18d7..0000000 --- a/lib/ESP-FTP-Server-Lib/src/Commands/STOR.h +++ /dev/null @@ -1,55 +0,0 @@ -#ifndef STOR_H_ -#define STOR_H_ - -#include -#include "../FTPCommand.h" -#include "../common.h" - -#define FTP_BUF_SIZE 4096 - -class STOR : public FTPCommandTransfer -{ -public: - explicit STOR(WiFiClient * const Client, FTPFilesystem * const Filesystem, IPAddress * DataAddress, int * DataPort) - : FTPCommandTransfer("STOR", 1, Client, Filesystem, DataAddress, DataPort) - {} - - void run(FTPPath & WorkDirectory, const std::vector & Line) override - { - if(trasferInProgress()) - { - return; - } - if(!ConnectDataConnection()) - { - return; - } - String path = WorkDirectory.getFilePath(Line[1]); - _file = _Filesystem->open(path, "w"); - if(!_file) - { - CloseDataConnection(); - SendResponse(451, "Can't open/create " + path); - return; - } - workOnData(); - } - - void workOnData() override - { - uint8_t buffer[FTP_BUF_SIZE]; - int nb = data_read(buffer, FTP_BUF_SIZE); - if(nb > 0) - { - _file.write(buffer, nb); - return; - } - CloseDataConnection(); - SendResponse(226, "File successfully transferred"); - _file.close(); - } - -private: -}; - -#endif diff --git a/lib/ESP-FTP-Server-Lib/src/Commands/TYPE.h b/lib/ESP-FTP-Server-Lib/src/Commands/TYPE.h deleted file mode 100644 index ddfe52c..0000000 --- a/lib/ESP-FTP-Server-Lib/src/Commands/TYPE.h +++ /dev/null @@ -1,28 +0,0 @@ -#ifndef TYPE_H_ -#define TYPE_H_ - -#include -#include "../FTPCommand.h" - -class TYPE : public FTPCommand -{ -public: - explicit TYPE(WiFiClient * const Client) : FTPCommand("TYPE", 1, Client) {} - - void run(FTPPath & WorkDirectory, const std::vector & Line) override - { - if(Line[1] == "A") - { - SendResponse(200, "TYPE is now ASCII"); - return; - } - else if(Line[1] == "I") - { - SendResponse(200, "TYPE is now 8-bit binary"); - return; - } - SendResponse(504, "Unknow TYPE"); - } -}; - -#endif diff --git a/lib/ESP-FTP-Server-Lib/src/ESP-FTP-Server-Lib.cpp b/lib/ESP-FTP-Server-Lib/src/ESP-FTP-Server-Lib.cpp deleted file mode 100644 index 29156a5..0000000 --- a/lib/ESP-FTP-Server-Lib/src/ESP-FTP-Server-Lib.cpp +++ /dev/null @@ -1,56 +0,0 @@ -#include "ESP-FTP-Server-Lib.h" - -FTPServer::FTPServer() - : _Server(FTP_CTRL_PORT, 1) -{ -} - -FTPServer::~FTPServer() -{ -} - -void FTPServer::addUser(const String & Username, const String & Password) -{ - FTPUser user(Username, Password); - _UserList.push_back(user); -} - -void FTPServer::addUser(const FTPUser & User) -{ - _UserList.push_back(User); -} - -void FTPServer::addFilesystem(String Name, FS * const Filesystem) -{ - _Filesystem.addFilesystem(Name, Filesystem); -} - -bool FTPServer::begin() -{ - _Server.begin(); - return true; -} - -bool isNotConnected(const std::shared_ptr & con) -{ - return !con->connected(); -} - -void FTPServer::handle() -{ - if(_Server.hasClient()) - { - std::shared_ptr connection = std::shared_ptr(new FTPConnection(_Server.available(), _UserList, _Filesystem)); - _Connections.push_back(connection); - } - for(std::shared_ptr con: _Connections) - { - con->handle(); - } - _Connections.remove_if(isNotConnected); -} - -size_t FTPServer::countConnections() const -{ - return _Connections.size(); -} diff --git a/lib/ESP-FTP-Server-Lib/src/ESP-FTP-Server-Lib.h b/lib/ESP-FTP-Server-Lib/src/ESP-FTP-Server-Lib.h deleted file mode 100644 index 8b368e4..0000000 --- a/lib/ESP-FTP-Server-Lib/src/ESP-FTP-Server-Lib.h +++ /dev/null @@ -1,38 +0,0 @@ -#ifndef ESP_FTP_LIB_H_ -#define ESP_FTP_LIB_H_ - -#include -#include - -#include "FTPUser.h" -#include "FTPConnection.h" -#include "FTPFilesystem.h" - -class FTPServer -{ -public: - FTPServer(); - virtual ~FTPServer(); - - void addUser(const String & Username, const String & Password); - void addUser(const FTPUser & User); - - void addFilesystem(String Name, FS * const Filesystem); - - bool begin(); - void handle(); - - size_t countConnections() const; - -private: - WiFiServer _Server; - - std::list _UserList; - std::list> _Connections; - - FTPFilesystem _Filesystem; -}; - -#define FTP_DEBUG(txt) Serial.print("[DEBUG] "); Serial.println(txt) - -#endif diff --git a/lib/ESP-FTP-Server-Lib/src/FTPCommand.h b/lib/ESP-FTP-Server-Lib/src/FTPCommand.h deleted file mode 100644 index 580c24b..0000000 --- a/lib/ESP-FTP-Server-Lib/src/FTPCommand.h +++ /dev/null @@ -1,133 +0,0 @@ -#ifndef FTP_COMMAND_H_ -#define FTP_COMMAND_H_ - -#include -#include -#include "FTPPath.h" -#include "FTPFilesystem.h" - -class FTPCommand -{ -public: - FTPCommand(String Name, int ExpectedArgumentCnt, WiFiClient * const Client, FTPFilesystem * const Filesystem = 0, IPAddress * DataAddress = 0, int * DataPort = 0) - : _Name(Name), _ExpectedArgumentCnt(ExpectedArgumentCnt), - _Filesystem(Filesystem), - _DataAddress(DataAddress), _DataPort(DataPort), _Client(Client), _DataConnection(0) {} - virtual ~FTPCommand() {} - - String getName() const - { - return _Name; - } - - virtual void run(FTPPath & WorkDirectory, const std::vector & Line) = 0; - - void SendResponse(int Code, String Text) - { - _Client->print(Code); - _Client->print(" "); - _Client->println(Text); - } - - bool ConnectDataConnection() - { - if(_DataConnection == 0) - { - _DataConnection = new WiFiClient(); - } - if(_DataConnection->connected()) - { - _DataConnection->stop(); - } - _DataConnection->connect(*_DataAddress, *_DataPort); - if(!_DataConnection->connected()) - { - _DataConnection->stop(); - SendResponse(425, "No data connection"); - return false; - } - SendResponse(150, "Accepted data connection"); - return true; - } - - void data_print(String str) - { - if(_DataConnection == 0 || !_DataConnection->connected()) - { - return; - } - _DataConnection->print(str); - } - - void data_println(String str) - { - if(_DataConnection == 0 || !_DataConnection->connected()) - { - return; - } - _DataConnection->println(str); - } - - void data_send(uint8_t * c, size_t l) - { - if(_DataConnection == 0 || !_DataConnection->connected()) - { - return; - } - _DataConnection->write(c, l); - } - - int data_read(uint8_t * c, size_t l) - { - if(_DataConnection == 0 || !_DataConnection->connected()) - { - return 0; - } - return _DataConnection->readBytes(c, l); - } - - void CloseDataConnection() - { - _DataConnection->stop(); - } - -protected: - String _Name; - int _ExpectedArgumentCnt; - FTPFilesystem * const _Filesystem; - IPAddress * const _DataAddress; - int * const _DataPort; - -private: - WiFiClient * const _Client; - WiFiClient * _DataConnection; -}; - -class FTPCommandTransfer : public FTPCommand -{ -public: - FTPCommandTransfer(String Name, int ExpectedArgumentCnt, WiFiClient * const Client, FTPFilesystem * const Filesystem = 0, IPAddress * DataAddress = 0, int * DataPort = 0) - : FTPCommand(Name, ExpectedArgumentCnt, Client, Filesystem, DataAddress, DataPort) {} - - virtual void workOnData() = 0; - - bool trasferInProgress() - { - return _file; - } - - void abort() - { - if(_file) - { - CloseDataConnection(); - SendResponse(426, "Transfer aborted"); - _file.close(); - } - } - -protected: - File _file; -}; - -#endif diff --git a/lib/ESP-FTP-Server-Lib/src/FTPConnection.cpp b/lib/ESP-FTP-Server-Lib/src/FTPConnection.cpp deleted file mode 100644 index 4bb54a2..0000000 --- a/lib/ESP-FTP-Server-Lib/src/FTPConnection.cpp +++ /dev/null @@ -1,207 +0,0 @@ -#include "ESP-FTP-Server-Lib.h" -#include "common.h" -#include "Commands/CDUP.h" -#include "Commands/CWD.h" -#include "Commands/DELE.h" -#include "Commands/LIST.h" -#include "Commands/MKD.h" -#include "Commands/PORT.h" -#include "Commands/PWD.h" -#include "Commands/RETR.h" -#include "Commands/RMD.h" -#include "Commands/RNFR_RNTO.h" -#include "Commands/STOR.h" -#include "Commands/TYPE.h" - -FTPConnection::FTPConnection(const WiFiClient & Client, std::list & UserList, FTPFilesystem & Filesystem) - : _ClientState(Idle), _Client(Client), _Filesystem(Filesystem), _UserList(UserList), _AuthUsername("") -{ - std::shared_ptr retr = std::shared_ptr(new RETR(&_Client, &_Filesystem, &_DataAddress, &_DataPort)); - std::shared_ptr stor = std::shared_ptr(new STOR(&_Client, &_Filesystem, &_DataAddress, &_DataPort)); - - _FTPCommands.push_back(std::shared_ptr(new CDUP(&_Client))); - _FTPCommands.push_back(std::shared_ptr(new CWD(&_Client, &_Filesystem))); - _FTPCommands.push_back(std::shared_ptr(new DELE(&_Client, &_Filesystem))); - _FTPCommands.push_back(std::shared_ptr(new LIST(&_Client, &_Filesystem, &_DataAddress, &_DataPort))); - _FTPCommands.push_back(std::shared_ptr(new MKD(&_Client, &_Filesystem))); - _FTPCommands.push_back(std::shared_ptr(new PORT(&_Client, &_DataAddress, &_DataPort))); - _FTPCommands.push_back(std::shared_ptr(new PWD(&_Client))); - _FTPCommands.push_back(retr); - _FTPCommands.push_back(std::shared_ptr(new RMD(&_Client, &_Filesystem))); - _FTPCommands.push_back(std::shared_ptr(new RNFR_RNTO(&_Client, &_Filesystem))); - _FTPCommands.push_back(stor); - _FTPCommands.push_back(std::shared_ptr(new TYPE(&_Client))); - - _FTPCommandsTransfer.push_back(retr); - _FTPCommandsTransfer.push_back(stor); - - Serial.print("New Connection from "); - Serial.print(_Client.remoteIP()); - Serial.print(":"); - Serial.println(_Client.remotePort()); - _Client.println("220--- Welcome to FTP Server for ESP32 ---"); - _Client.println("220--- By Peter Buchegger ---"); - _Client.println("220 -- Version 0.1 ---"); -} - -FTPConnection::~FTPConnection() -{ - Serial.println("Connection closed!"); -} - -bool FTPConnection::readUntilLineEnd() -{ - while(_Client.available()) - { - char c = _Client.read(); - if(c == '\n') - { - _LineSplited = Split>(_Line, ' '); - return true; - } - if(c >= 32 && c < 127) - { - _Line += c; - } - } - return false; -} - -bool FTPConnection::handle() -{ - if(!_Client.connected()) - { - return false; - } - for(std::shared_ptr cmd: _FTPCommandsTransfer) - { - if(cmd->trasferInProgress()) - { - cmd->workOnData(); - } - } - if(!readUntilLineEnd()) - { - return true; - } - // we have a new command in the queue: - Serial.println(_Line); - String command = _LineSplited[0]; - - // This commands are always possible: - if(command == "SYST") - { - _Client.println("215 UNIX Type: L8"); - _Line = ""; - return true; - } - else if(command == "QUIT") - { - _Client.println("221 Goodbye"); - _Client.stop(); - _Line = ""; - return true; - } - else if(command == "ABOR") - { - for(std::shared_ptr cmd: _FTPCommandsTransfer) - { - cmd->abort(); - } - _Client.println("226 Data connection closed"); - _Line = ""; - return true; - } - - // Logged in? - switch (_ClientState) - { - case Idle: - if(command == "USER") - { - c_USER(); - } - break; - - case UsernamePass: - if(command == "PASS") - { - c_PASS(); - } - break; - - case AuthPass: - { - std::vector>::iterator cmdIter = std::find_if(_FTPCommands.begin(), _FTPCommands.end(), [&](std::shared_ptr cmd) - { - if(command == cmd->getName() || (cmd->getName() == "RN" && (command == "RNFR" || command == "RNTO"))) - { - return true; - } - return false; - } - ); - if(cmdIter != _FTPCommands.end()) - { - (*cmdIter)->run(_WorkDirectory, _LineSplited); - _Line = ""; - return true; - } - } - - default: - _Client.println("500 Unknow command"); - break; - } - _Line = ""; - return true; -} - -bool FTPConnection::connected() -{ - return _Client.connected(); -} - -void FTPConnection::c_USER() -{ - String username = _LineSplited[1]; - std::list::iterator userIter = std::find_if(_UserList.begin(), _UserList.end(), [&](const FTPUser & user) - { - if(username == user.Username) - { - return true; - } - return false; - } - ); - if(userIter != _UserList.end()) - { - _AuthUsername = username; - _Client.println("331 OK. Password required"); - _ClientState = UsernamePass; - return; - } - _Client.println("530 user not found"); -} - -void FTPConnection::c_PASS() -{ - String password = _LineSplited[1]; - String username = _AuthUsername; - std::list::iterator _user = std::find_if(_UserList.begin(), _UserList.end(), [&](const FTPUser & user) - { - if(username == user.Username && password == user.Password) - { - return true; - } - return false; - } - ); - if(_user != _UserList.end()) - { - _Client.println("230 OK."); - _ClientState = AuthPass; - return; - } - _Client.println("530 passwort not correct"); -} diff --git a/lib/ESP-FTP-Server-Lib/src/FTPConnection.h b/lib/ESP-FTP-Server-Lib/src/FTPConnection.h deleted file mode 100644 index f20d0c9..0000000 --- a/lib/ESP-FTP-Server-Lib/src/FTPConnection.h +++ /dev/null @@ -1,59 +0,0 @@ -#ifndef FTP_CONNECTION_H_ -#define FTP_CONNECTION_H_ - -#include -#include -#include "FTPPath.h" -#include "FTPCommand.h" - -#define FTP_CTRL_PORT 21 -#define FTP_USER_TIME_OUT 5 -#define FTP_CMD_SIZE 255 + 8 // max size of a command -#define FTP_DIRNAME_SIZE 255 + 8 // max size of a directory name -#define FTP_FILENAME_SIZE 255 // max size of a file name - -class FTPConnection -{ -public: - FTPConnection(const WiFiClient & Client, std::list & UserList, FTPFilesystem & Filesystem); - virtual ~FTPConnection(); - - bool readUntilLineEnd(); - - bool handle(); - - bool connected(); - - -private: - enum ClientState - { - Idle, - UsernamePass, - AuthPass, - }; - - void c_USER(); - void c_PASS(); - - ClientState _ClientState; - WiFiClient _Client; - FTPFilesystem & _Filesystem; - String _FilePath; - - String _Line; - std::vector _LineSplited; - - std::list & _UserList; - String _AuthUsername; - - IPAddress _DataAddress; - int _DataPort; - - FTPPath _WorkDirectory; - - std::vector> _FTPCommands; - std::vector> _FTPCommandsTransfer; -}; - -#endif diff --git a/lib/ESP-FTP-Server-Lib/src/FTPFilesystem.cpp b/lib/ESP-FTP-Server-Lib/src/FTPFilesystem.cpp deleted file mode 100644 index 030814a..0000000 --- a/lib/ESP-FTP-Server-Lib/src/FTPFilesystem.cpp +++ /dev/null @@ -1,120 +0,0 @@ -#include "FTPFilesystem.h" -#include "common.h" - -FTPFilesystem::FTPFilesystem() -{ -} - -FTPFilesystem::~FTPFilesystem() -{ -} - -void FTPFilesystem::addFilesystem(String Name, FS * const Filesystem) -{ - _Filesystems[Name] = Filesystem; -} - -void FTPFilesystem::clearFilesystemList() -{ - _Filesystems.clear(); -} - -File FTPFilesystem::open(const String & path, const char* mode) -{ - if(path == "/") - { - std::shared_ptr root = std::shared_ptr(new FTPFileImpl("/")); - for(auto const & f: _Filesystems) - { - root->addFilesystem(f.first); - } - return File(root); - } - FS * fs = getFilesystem(path); - return fs->open(getPathWithoutFS(path), mode); -} - -bool FTPFilesystem::exists(const String & path) -{ - FS * fs = getFilesystem(path); - if(fs == 0) - { - return false; - } - return fs->exists(getPathWithoutFS(path)); -} - -bool FTPFilesystem::remove(const String & path) -{ - FS * fs = getFilesystem(path); - if(fs == 0) - { - return false; - } - return fs->remove(getPathWithoutFS(path)); -} - -bool FTPFilesystem::rename(const String & pathFrom, const String & pathTo) -{ - FS * fsFrom = getFilesystem(pathFrom); - FS * fsTo = getFilesystem(pathTo); - if(fsFrom == 0 || fsTo == 0) - { - return false; - } - if(fsFrom != fsTo) - { - // cant move/rename from one filesystem to another one! - return false; - } - return fsFrom->rename(getPathWithoutFS(pathFrom), getPathWithoutFS(pathTo)); -} - -bool FTPFilesystem::mkdir(const String & path) -{ - FS * fs = getFilesystem(path); - if(fs == 0) - { - return false; - } - return fs->mkdir(getPathWithoutFS(path)); -} - -bool FTPFilesystem::rmdir(const String & path) -{ - FS * fs = getFilesystem(path); - if(fs == 0) - { - return false; - } - return fs->rmdir(getPathWithoutFS(path)); -} - -void FTPFilesystem::printFilesystems() -{ - for (auto const & fs: _Filesystems) - { - Serial.println(fs.first); - } -} - -FS * FTPFilesystem::getFilesystem(String path) -{ - std::list splitted = FTPPath::splitPath(path); - String name = *(splitted.begin()); - std::map::iterator iter = _Filesystems.find(name); - if(iter == _Filesystems.end()) - { - Serial.println("[ERROR] Filesystem not found!"); - return 0; - } - return iter->second; -} - -String FTPFilesystem::getPathWithoutFS(String path) -{ - std::list splitted = FTPPath::splitPath(path); - splitted.pop_front(); - String path_without = FTPPath::createPath(splitted); - return path_without; -} diff --git a/lib/ESP-FTP-Server-Lib/src/FTPFilesystem.h b/lib/ESP-FTP-Server-Lib/src/FTPFilesystem.h deleted file mode 100644 index 56da178..0000000 --- a/lib/ESP-FTP-Server-Lib/src/FTPFilesystem.h +++ /dev/null @@ -1,70 +0,0 @@ -#ifndef FTP_FILESYSTEM_H_ -#define FTP_FILESYSTEM_H_ - -#include -#include -#include -#include "FTPPath.h" - -class FTPFilesystem -{ -public: - FTPFilesystem(); - virtual ~FTPFilesystem(); - - void addFilesystem(String Name, FS * const Filesystem); - void clearFilesystemList(); - - File open(const String & path, const char* mode = FILE_READ); - bool exists(const String & path); - bool remove(const String & path); - bool rename(const String & pathFrom, const String & pathTo); - bool mkdir(const String & path); - bool rmdir(const String & path); - - void printFilesystems(); - -#ifndef UNIT_TEST -private: -#endif - FS * getFilesystem(String path); - static String getPathWithoutFS(String path); - - std::map _Filesystems; -}; - -class FTPFileImpl : public fs::FileImpl -{ -public: - explicit FTPFileImpl(String name) : _Name(name) {} - ~FTPFileImpl() {} - size_t write(const uint8_t *buf, size_t size) override { return 0; }; - size_t read(uint8_t* buf, size_t size) override { return 0; }; - void flush() override {}; - bool seek(uint32_t pos, SeekMode mode) override { return false; }; - size_t position() const override { return 0; }; - size_t size() const override { return 0; }; - void close() override {}; - time_t getLastWrite() override { return 0; }; - const char* name() const override { return _Name.c_str(); }; - boolean isDirectory(void) override { return true; }; - fs::FileImplPtr openNextFile(const char* mode) override - { - if(_Filesystems.empty()) - { - return 0; - } - String next = _Filesystems.front(); - _Filesystems.pop_front(); - return fs::FileImplPtr(new FTPFileImpl(next)); - } - void rewindDirectory(void) override {}; - operator bool() override { return false; }; - - void addFilesystem(String name) { _Filesystems.push_back(name); } -private: - String _Name; - std::list _Filesystems; -}; - -#endif diff --git a/lib/ESP-FTP-Server-Lib/src/FTPPath.cpp b/lib/ESP-FTP-Server-Lib/src/FTPPath.cpp deleted file mode 100644 index 9990ac8..0000000 --- a/lib/ESP-FTP-Server-Lib/src/FTPPath.cpp +++ /dev/null @@ -1,75 +0,0 @@ -#include "FTPPath.h" -#include "common.h" - -FTPPath::FTPPath() -{ -} - -FTPPath::FTPPath(String path) -{ - changePath(path); -} - -FTPPath::~FTPPath() -{ -} - -void FTPPath::changePath(String path) -{ - std::list p = splitPath(path); - std::copy(p.begin(), p.end(), std::back_inserter(_Path)); -} - -void FTPPath::goPathUp() -{ - _Path.pop_back(); -} - -String FTPPath::getPath() const -{ - return createPath(_Path); -} - -String FTPPath::getFilePath(String filename) const -{ - if(*filename.begin() == '/') - { - return filename; - } - if(_Path.size() == 0) - { - return "/" + filename; - } - return getPath() + "/" + filename; -} - -std::list FTPPath::splitPath(String path) -{ - std::list p = Split>(path, '/'); - p.erase( - std::remove_if(p.begin(), p.end(), [](const String & s) - { - if(s.isEmpty()) - { - return true; - } - return false; - }), - p.end()); - return p; -} - -String FTPPath::createPath(std::list path) -{ - if(path.size() == 0) - { - return "/"; - } - String new_path; - for(const String & p: path) - { - new_path += "/"; - new_path += p; - } - return new_path; -} diff --git a/lib/ESP-FTP-Server-Lib/src/FTPPath.h b/lib/ESP-FTP-Server-Lib/src/FTPPath.h deleted file mode 100644 index 110e2e0..0000000 --- a/lib/ESP-FTP-Server-Lib/src/FTPPath.h +++ /dev/null @@ -1,27 +0,0 @@ -#ifndef FTP_PATH_H_ -#define FTP_PATH_H_ - -#include -#include - -class FTPPath -{ -public: - FTPPath(); - explicit FTPPath(String path); - virtual ~FTPPath(); - - void changePath(String path); - void goPathUp(); - - String getPath() const; - String getFilePath(String filename) const; - - static std::list splitPath(String path); - static String createPath(std::list path); - -private: - std::list _Path; -}; - -#endif diff --git a/lib/ESP-FTP-Server-Lib/src/FTPUser.h b/lib/ESP-FTP-Server-Lib/src/FTPUser.h deleted file mode 100644 index ea6f39f..0000000 --- a/lib/ESP-FTP-Server-Lib/src/FTPUser.h +++ /dev/null @@ -1,14 +0,0 @@ -#ifndef FTP_USER_H_ -#define FTP_USER_H_ - -#include - -class FTPUser -{ -public: - FTPUser(const String & username, const String & password) : Username(username), Password(password) {} - const String Username; - const String Password; -}; - -#endif diff --git a/lib/ESP-FTP-Server-Lib/src/common.cpp b/lib/ESP-FTP-Server-Lib/src/common.cpp deleted file mode 100644 index 8c3e2cf..0000000 --- a/lib/ESP-FTP-Server-Lib/src/common.cpp +++ /dev/null @@ -1,22 +0,0 @@ -#include "common.h" - -/* -template -T Split(String str, char parser) -{ - T str_array; - int last_idx = 0; - int next_idx = str.indexOf(parser, last_idx); - do - { - str_array.push_back(str.substring(last_idx, next_idx)); - last_idx = next_idx + 1; - next_idx = str.indexOf(parser, last_idx); - if(next_idx == -1 && last_idx != 0) - { - str_array.push_back(str.substring(last_idx, str.length())); - } - } while (next_idx != -1); - return str_array; -} -*/ diff --git a/lib/ESP-FTP-Server-Lib/src/common.h b/lib/ESP-FTP-Server-Lib/src/common.h deleted file mode 100644 index 4a40e35..0000000 --- a/lib/ESP-FTP-Server-Lib/src/common.h +++ /dev/null @@ -1,27 +0,0 @@ -#ifndef COMMON_H_ -#define COMMON_H_ - -#include -#include -#include - -template -T Split(String str, char parser) -{ - T str_array; - int last_idx = 0; - int next_idx = str.indexOf(parser, last_idx); - do - { - str_array.push_back(str.substring(last_idx, next_idx)); - last_idx = next_idx + 1; - next_idx = str.indexOf(parser, last_idx); - if(next_idx == -1 && last_idx != 0) - { - str_array.push_back(str.substring(last_idx, str.length())); - } - } while (next_idx != -1); - return str_array; -} - -#endif diff --git a/platformio.ini b/platformio.ini index 9ec6861..34a9ddf 100644 --- a/platformio.ini +++ b/platformio.ini @@ -12,7 +12,7 @@ lib_deps = sandeepmistry/LoRa @ 0.7.2 peterus/APRS-Decoder-Lib @ 0.0.5 peterus/APRS-IS-Lib @ 0.0.7 - peterus/ESP-FTP-Server-Lib @ 0.9.2 + peterus/ESP-FTP-Server-Lib @ 0.9.3 peterus/LoRa-APRS-Lib @ 0.0.5 check_tool = cppcheck check_flags = From aa1dd478106443c6adf167562425353ea1a76b19 Mon Sep 17 00:00:00 2001 From: Peter Buchegger Date: Fri, 6 Nov 2020 00:36:12 +0100 Subject: [PATCH 09/29] remove version tag --- src/configuration.cpp | 1 - src/configuration.h | 3 +-- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/src/configuration.cpp b/src/configuration.cpp index 30d117c..3cffa1a 100644 --- a/src/configuration.cpp +++ b/src/configuration.cpp @@ -106,7 +106,6 @@ void ConfigurationManagement::writeConfiguration(Configuration conf) } DynamicJsonDocument data(2048); - data["version"] = conf.version; data["callsign"] = conf.callsign; data["wifi"]["active"] = conf.wifi.active; JsonArray aps = data["wifi"].createNestedArray("AP"); diff --git a/src/configuration.h b/src/configuration.h index c73f615..8e7e101 100644 --- a/src/configuration.h +++ b/src/configuration.h @@ -98,9 +98,8 @@ public: std::list users; }; - Configuration() : version(4), callsign("NOCALL-10") {}; + Configuration() : callsign("NOCALL-10") {}; - int version; String callsign; Wifi wifi; Beacon beacon; From 53bbc8680103248a5e575b03b5cd1650a410b028 Mon Sep 17 00:00:00 2001 From: Peter Buchegger Date: Fri, 6 Nov 2020 00:37:40 +0100 Subject: [PATCH 10/29] remove writing config if file not exists --- src/configuration.cpp | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/src/configuration.cpp b/src/configuration.cpp index 3cffa1a..1d10731 100644 --- a/src/configuration.cpp +++ b/src/configuration.cpp @@ -16,12 +16,7 @@ ConfigurationManagement::ConfigurationManagement(String FilePath) return; } } - if(!SPIFFS.exists(mFilePath)) - { - Configuration conf; - writeConfiguration(conf); } -} Configuration ConfigurationManagement::readConfiguration() { @@ -32,7 +27,11 @@ Configuration ConfigurationManagement::readConfiguration() return Configuration(); } DynamicJsonDocument data(2048); - deserializeJson(data, file); + DeserializationError error = deserializeJson(data, file); + if(error) + { + Serial.println("Failed to read file, using default configuration."); + } //serializeJson(data, Serial); //Serial.println(); file.close(); From 0455b9d0903a79066356a5b82d573a83c4438628 Mon Sep 17 00:00:00 2001 From: Peter Buchegger Date: Fri, 6 Nov 2020 00:38:11 +0100 Subject: [PATCH 11/29] add first default reading --- src/configuration.cpp | 66 +++++++++++++++++++------------------------ 1 file changed, 29 insertions(+), 37 deletions(-) diff --git a/src/configuration.cpp b/src/configuration.cpp index 1d10731..05596fb 100644 --- a/src/configuration.cpp +++ b/src/configuration.cpp @@ -16,7 +16,7 @@ ConfigurationManagement::ConfigurationManagement(String FilePath) return; } } - } +} Configuration ConfigurationManagement::readConfiguration() { @@ -38,7 +38,7 @@ Configuration ConfigurationManagement::readConfiguration() Configuration conf; conf.callsign = data["callsign"].as(); - conf.wifi.active = data["wifi"]["active"]; + conf.wifi.active = data["wifi"]["active"] | false; JsonArray aps = data["wifi"]["AP"].as(); for(JsonVariant v : aps) { @@ -48,45 +48,37 @@ Configuration ConfigurationManagement::readConfiguration() conf.wifi.APs.push_back(ap); } conf.beacon.message = data["beacon"]["message"].as(); - conf.beacon.positionLatitude = data["beacon"]["position"]["latitude"]; - conf.beacon.positionLongitude = data["beacon"]["position"]["longitude"]; - conf.aprs_is.active = data["aprs_is"]["active"]; + conf.beacon.positionLatitude = data["beacon"]["position"]["latitude"] | 0.0; + conf.beacon.positionLongitude = data["beacon"]["position"]["longitude"] | 0.0; + conf.aprs_is.active = data["aprs_is"]["active"] | false; conf.aprs_is.password = data["aprs_is"]["password"].as(); conf.aprs_is.server = data["aprs_is"]["server"].as(); - conf.aprs_is.port = data["aprs_is"]["port"]; - conf.aprs_is.beacon = data["aprs_is"]["beacon"]; - conf.aprs_is.beaconTimeout = data["aprs_is"]["beacon_timeout"]; - conf.digi.active = data["digi"]["active"]; - conf.digi.forwardTimeout = data["digi"]["forward_timeout"]; - conf.digi.beacon = data["digi"]["beacon"]; - conf.digi.beaconTimeout = data["digi"]["beacon_timeout"]; + conf.aprs_is.port = data["aprs_is"]["port"] | 14580; + conf.aprs_is.beacon = data["aprs_is"]["beacon"] | true; + conf.aprs_is.beaconTimeout = data["aprs_is"]["beacon_timeout"] | 15; + conf.digi.active = data["digi"]["active"] | false; + conf.digi.forwardTimeout = data["digi"]["forward_timeout"] | 5; + conf.digi.beacon = data["digi"]["beacon"] | true; + conf.digi.beaconTimeout = data["digi"]["beacon_timeout"] | 30; - if(data["version"] >= 2) + conf.lora.frequencyRx = data["lora"]["frequency_rx"] | 433775000; + conf.lora.frequencyTx = data["lora"]["frequency_tx"] | 433775000; + conf.lora.power = data["lora"]["power"] | 20; + conf.lora.spreadingFactor = data["lora"]["spreading_factor"] | 12; + conf.lora.signalBandwidth = data["lora"]["signal_bandwidth"] | 125000; + conf.lora.codingRate4 = data["lora"]["coding_rate4"] | 5; + conf.display.alwaysOn = data["display"]["always_on"] | true; + conf.display.timeout = data["display"]["timeout"] | 10; + conf.display.overwritePin = data["display"]["overwrite_pin"] | 0; + + conf.ftp.active = data["ftp"]["active"] | false; + JsonArray users = data["ftp"]["user"].as(); + for(JsonVariant u : users) { - conf.lora.frequencyRx = data["lora"]["frequency_rx"]; - conf.lora.frequencyTx = data["lora"]["frequency_tx"]; - conf.lora.power = data["lora"]["power"]; - conf.display.alwaysOn = data["display"]["always_on"]; - conf.display.timeout = data["display"]["timeout"]; - conf.display.overwritePin = data["display"]["overwrite_pin"]; - } - if(data["version"] >= 3) - { - conf.lora.spreadingFactor = data["lora"]["spreading_factor"]; - conf.lora.signalBandwidth = data["lora"]["signal_bandwidth"]; - conf.lora.codingRate4 = data["lora"]["coding_rate4"]; - } - if(data["version"] >= 4) - { - conf.ftp.active = data["ftp"]["active"]; - JsonArray users = data["ftp"]["user"].as(); - for(JsonVariant u : users) - { - Configuration::Ftp::User us; - us.name = u["name"].as(); - us.password = u["password"].as(); - conf.ftp.users.push_back(us); - } + Configuration::Ftp::User us; + us.name = u["name"].as(); + us.password = u["password"].as(); + conf.ftp.users.push_back(us); } // update config in memory to get the new fields: From 6c79b559ccf1bce442aa9f1744118528fde09954 Mon Sep 17 00:00:00 2001 From: Peter Buchegger Date: Fri, 6 Nov 2020 21:32:59 +0100 Subject: [PATCH 12/29] fixing string config and some spaces --- src/configuration.cpp | 133 +++++++++++++++++++++++------------------- 1 file changed, 72 insertions(+), 61 deletions(-) diff --git a/src/configuration.cpp b/src/configuration.cpp index 05596fb..6a87901 100644 --- a/src/configuration.cpp +++ b/src/configuration.cpp @@ -13,7 +13,6 @@ ConfigurationManagement::ConfigurationManagement(String FilePath) if(!SPIFFS.begin()) { Serial.println("[ERROR] Formating SPIFFS was not okay!"); - return; } } } @@ -37,47 +36,59 @@ Configuration ConfigurationManagement::readConfiguration() file.close(); Configuration conf; - conf.callsign = data["callsign"].as(); - conf.wifi.active = data["wifi"]["active"] | false; - JsonArray aps = data["wifi"]["AP"].as(); + if(data.containsKey("callsign")) + conf.callsign = data["callsign"].as(); + + conf.wifi.active = data["wifi"]["active"] | false; + JsonArray aps = data["wifi"]["AP"].as(); for(JsonVariant v : aps) { Configuration::Wifi::AP ap; - ap.SSID = v["SSID"].as(); - ap.password = v["password"].as(); + ap.SSID = v["SSID"].as(); + ap.password = v["password"].as(); conf.wifi.APs.push_back(ap); } - conf.beacon.message = data["beacon"]["message"].as(); - conf.beacon.positionLatitude = data["beacon"]["position"]["latitude"] | 0.0; - conf.beacon.positionLongitude = data["beacon"]["position"]["longitude"] | 0.0; - conf.aprs_is.active = data["aprs_is"]["active"] | false; - conf.aprs_is.password = data["aprs_is"]["password"].as(); - conf.aprs_is.server = data["aprs_is"]["server"].as(); - conf.aprs_is.port = data["aprs_is"]["port"] | 14580; - conf.aprs_is.beacon = data["aprs_is"]["beacon"] | true; - conf.aprs_is.beaconTimeout = data["aprs_is"]["beacon_timeout"] | 15; - conf.digi.active = data["digi"]["active"] | false; - conf.digi.forwardTimeout = data["digi"]["forward_timeout"] | 5; - conf.digi.beacon = data["digi"]["beacon"] | true; - conf.digi.beaconTimeout = data["digi"]["beacon_timeout"] | 30; + if(data.containsKey("beacon") && data.containsKey("message")) + conf.beacon.message = data["beacon"]["message"].as(); + conf.beacon.positionLatitude = data["beacon"]["position"]["latitude"] | 0.0; + conf.beacon.positionLongitude = data["beacon"]["position"]["longitude"] | 0.0; + conf.aprs_is.active = data["aprs_is"]["active"] | false; + if(data.containsKey("aprs_is") && data.containsKey("password")) + conf.aprs_is.password = data["aprs_is"]["password"].as(); + if(data.containsKey("aprs_is") && data.containsKey("server")) + conf.aprs_is.server = data["aprs_is"]["server"].as(); + conf.aprs_is.port = data["aprs_is"]["port"] | 14580; + conf.aprs_is.beacon = data["aprs_is"]["beacon"] | true; + conf.aprs_is.beaconTimeout = data["aprs_is"]["beacon_timeout"] | 15; + conf.digi.active = data["digi"]["active"] | false; + conf.digi.forwardTimeout = data["digi"]["forward_timeout"] | 5; + conf.digi.beacon = data["digi"]["beacon"] | true; + conf.digi.beaconTimeout = data["digi"]["beacon_timeout"] | 30; - conf.lora.frequencyRx = data["lora"]["frequency_rx"] | 433775000; - conf.lora.frequencyTx = data["lora"]["frequency_tx"] | 433775000; - conf.lora.power = data["lora"]["power"] | 20; - conf.lora.spreadingFactor = data["lora"]["spreading_factor"] | 12; - conf.lora.signalBandwidth = data["lora"]["signal_bandwidth"] | 125000; - conf.lora.codingRate4 = data["lora"]["coding_rate4"] | 5; - conf.display.alwaysOn = data["display"]["always_on"] | true; - conf.display.timeout = data["display"]["timeout"] | 10; - conf.display.overwritePin = data["display"]["overwrite_pin"] | 0; + conf.lora.frequencyRx = data["lora"]["frequency_rx"] | 433775000; + conf.lora.frequencyTx = data["lora"]["frequency_tx"] | 433775000; + conf.lora.power = data["lora"]["power"] | 20; + conf.lora.spreadingFactor = data["lora"]["spreading_factor"] | 12; + conf.lora.signalBandwidth = data["lora"]["signal_bandwidth"] | 125000; + conf.lora.codingRate4 = data["lora"]["coding_rate4"] | 5; + conf.display.alwaysOn = data["display"]["always_on"] | true; + conf.display.timeout = data["display"]["timeout"] | 10; + conf.display.overwritePin = data["display"]["overwrite_pin"] | 0; - conf.ftp.active = data["ftp"]["active"] | false; - JsonArray users = data["ftp"]["user"].as(); + conf.ftp.active = data["ftp"]["active"] | false; + JsonArray users = data["ftp"]["user"].as(); for(JsonVariant u : users) { Configuration::Ftp::User us; - us.name = u["name"].as(); - us.password = u["password"].as(); + us.name = u["name"].as(); + us.password = u["password"].as(); + conf.ftp.users.push_back(us); + } + if(conf.ftp.users.empty()) + { + Configuration::Ftp::User us; + us.name = "ftp"; + us.password = "ftp"; conf.ftp.users.push_back(us); } @@ -97,44 +108,44 @@ void ConfigurationManagement::writeConfiguration(Configuration conf) } DynamicJsonDocument data(2048); - data["callsign"] = conf.callsign; - data["wifi"]["active"] = conf.wifi.active; + data["callsign"] = conf.callsign; + data["wifi"]["active"] = conf.wifi.active; JsonArray aps = data["wifi"].createNestedArray("AP"); for(Configuration::Wifi::AP ap : conf.wifi.APs) { JsonObject v = aps.createNestedObject(); - v["SSID"] = ap.SSID; - v["password"] = ap.password; + v["SSID"] = ap.SSID; + v["password"] = ap.password; } - data["beacon"]["message"] = conf.beacon.message; - data["beacon"]["position"]["latitude"] = conf.beacon.positionLatitude; - data["beacon"]["position"]["longitude"] = conf.beacon.positionLongitude; - data["aprs_is"]["active"] = conf.aprs_is.active; - data["aprs_is"]["password"] = conf.aprs_is.password; - data["aprs_is"]["server"] = conf.aprs_is.server; - data["aprs_is"]["port"] = conf.aprs_is.port; - data["aprs_is"]["beacon"] = conf.aprs_is.beacon; - data["aprs_is"]["beacon_timeout"] = conf.aprs_is.beaconTimeout; - data["digi"]["active"] = conf.digi.active; - data["digi"]["forward_timeout"] = conf.digi.forwardTimeout; - data["digi"]["beacon"] = conf.digi.beacon; - data["digi"]["beacon_timeout"] = conf.digi.beaconTimeout; - data["lora"]["frequency_rx"] = conf.lora.frequencyRx; - data["lora"]["frequency_tx"] = conf.lora.frequencyTx; - data["lora"]["power"] = conf.lora.power; - data["lora"]["spreading_factor"] = conf.lora.spreadingFactor; - data["lora"]["signal_bandwidth"] = conf.lora.signalBandwidth; - data["lora"]["coding_rate4"] = conf.lora.codingRate4; - data["display"]["always_on"] = conf.display.alwaysOn; - data["display"]["timeout"] = conf.display.timeout; - data["display"]["overwrite_pin"] = conf.display.overwritePin; - data["ftp"]["active"] = conf.ftp.active; + data["beacon"]["message"] = conf.beacon.message; + data["beacon"]["position"]["latitude"] = conf.beacon.positionLatitude; + data["beacon"]["position"]["longitude"] = conf.beacon.positionLongitude; + data["aprs_is"]["active"] = conf.aprs_is.active; + data["aprs_is"]["password"] = conf.aprs_is.password; + data["aprs_is"]["server"] = conf.aprs_is.server; + data["aprs_is"]["port"] = conf.aprs_is.port; + data["aprs_is"]["beacon"] = conf.aprs_is.beacon; + data["aprs_is"]["beacon_timeout"] = conf.aprs_is.beaconTimeout; + data["digi"]["active"] = conf.digi.active; + data["digi"]["forward_timeout"] = conf.digi.forwardTimeout; + data["digi"]["beacon"] = conf.digi.beacon; + data["digi"]["beacon_timeout"] = conf.digi.beaconTimeout; + data["lora"]["frequency_rx"] = conf.lora.frequencyRx; + data["lora"]["frequency_tx"] = conf.lora.frequencyTx; + data["lora"]["power"] = conf.lora.power; + data["lora"]["spreading_factor"] = conf.lora.spreadingFactor; + data["lora"]["signal_bandwidth"] = conf.lora.signalBandwidth; + data["lora"]["coding_rate4"] = conf.lora.codingRate4; + data["display"]["always_on"] = conf.display.alwaysOn; + data["display"]["timeout"] = conf.display.timeout; + data["display"]["overwrite_pin"] = conf.display.overwritePin; + data["ftp"]["active"] = conf.ftp.active; JsonArray users = data["ftp"].createNestedArray("user"); for(Configuration::Ftp::User u : conf.ftp.users) { JsonObject v = users.createNestedObject(); - v["name"] = u.name; - v["password"] = u.password; + v["name"] = u.name; + v["password"] = u.password; } serializeJson(data, file); From edf168e523fba3f19a508a1182f8ebe12a74414b Mon Sep 17 00:00:00 2001 From: Peter Buchegger Date: Fri, 6 Nov 2020 21:42:09 +0100 Subject: [PATCH 13/29] dummy change --- src/configuration.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/configuration.cpp b/src/configuration.cpp index 6a87901..92fa1e3 100644 --- a/src/configuration.cpp +++ b/src/configuration.cpp @@ -2,7 +2,6 @@ #include "configuration.h" - ConfigurationManagement::ConfigurationManagement(String FilePath) : mFilePath(FilePath) { From a91ee0c97917f3982434ef6c945b5a8bcf2ba589 Mon Sep 17 00:00:00 2001 From: Peter Buchegger Date: Fri, 6 Nov 2020 21:44:09 +0100 Subject: [PATCH 14/29] remove braches in workflow --- .github/workflows/main.yml | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index e8de1af..b940d07 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -1,10 +1,6 @@ name: PlatformIO CI -on: - push: - branches: [ master ] - pull_request: - branches: [ master ] +on: [push, pull_request] jobs: PlatformIO-Check: From 21f493ba737403cb815aa06f4c472de54cd0663a Mon Sep 17 00:00:00 2001 From: Peter Buchegger Date: Sun, 8 Nov 2020 00:07:43 +0100 Subject: [PATCH 15/29] add new logger conzept --- src/LoRa_APRS_iGate.cpp | 143 ++++++++++++------------ src/configuration.cpp | 13 +-- src/display.cpp | 4 +- src/logger.cpp | 234 ++++++++++++++++++++++++++++++++++++++++ src/logger.h | 75 +++++++++++++ 5 files changed, 391 insertions(+), 78 deletions(-) create mode 100644 src/logger.cpp create mode 100644 src/logger.h diff --git a/src/LoRa_APRS_iGate.cpp b/src/LoRa_APRS_iGate.cpp index ae175a8..acb2a86 100644 --- a/src/LoRa_APRS_iGate.cpp +++ b/src/LoRa_APRS_iGate.cpp @@ -10,6 +10,8 @@ #include #include +#include "logger.h" + #include "LoRa_APRS.h" #include "pins.h" @@ -60,20 +62,22 @@ void setup() Wire.begin(SDA, SCL); if (!powerManagement.begin(Wire)) { - Serial.println("LoRa-APRS / Init / AXP192 Begin PASS"); - } else { - Serial.println("LoRa-APRS / Init / AXP192 Begin FAIL"); + logPrintlnI("AXP192 init done!"); + } + else + { + logPrintlnE("AXP192 init failed!"); } powerManagement.activateLoRa(); powerManagement.activateOLED(); powerManagement.deactivateGPS(); #endif - setup_display(); - delay(500); - Serial.println("[INFO] LoRa APRS iGate & Digi by OE5BPA (Peter Buchegger)"); - show_display("OE5BPA", "LoRa APRS iGate & Digi", "by Peter Buchegger", 3000); + logPrintlnA("LoRa APRS iGate & Digi by OE5BPA (Peter Buchegger)"); + logPrintlnA("Version: 1.0.0-dev"); + setup_display(); + show_display("OE5BPA", "LoRa APRS iGate & Digi", "by Peter Buchegger", "1.0.0-dev", 3000); load_config(); setup_lora(); @@ -100,7 +104,7 @@ void setup() } delay(500); - Serial.println("[INFO] setup done..."); + logPrintlnI("setup done..."); secondsSinceDisplay = 0; } @@ -118,7 +122,6 @@ void loop() { turn_off_display(); display_is_on = false; - Serial.println("-"); } static bool beacon_aprs_is = Config.aprs_is.active && Config.aprs_is.beacon; @@ -145,7 +148,7 @@ void loop() static bool configWasOpen = false; if(configWasOpen && ftpServer.countConnections() == 0) { - Serial.println("[WARN] Maybe the config has been changed via FTP, lets restart now to get the new config..."); + logPrintlnW("Maybe the config has been changed via FTP, lets restart now to get the new config..."); Serial.println(); ESP.restart(); } @@ -159,7 +162,7 @@ void loop() if(Config.wifi.active && WiFiMulti.run() != WL_CONNECTED) { setup_display(); secondsSinceDisplay = 0; display_is_on = true; - Serial.println("[ERROR] WiFi not connected!"); + logPrintlnE("WiFi not connected!"); show_display("ERROR", "WiFi not connected!"); delay(1000); return; @@ -167,26 +170,26 @@ void loop() if(Config.aprs_is.active && !aprs_is->connected()) { setup_display(); secondsSinceDisplay = 0; display_is_on = true; - Serial.print("[INFO] connecting to server: "); - Serial.print(Config.aprs_is.server); - Serial.print(" on port: "); - Serial.println(Config.aprs_is.port); - show_display("INFO", "Connecting to server"); + logPrintI("connecting to APRS-IS server: "); + logPrintI(Config.aprs_is.server); + logPrintI(" on port: "); + logPrintlnI(String(Config.aprs_is.port)); + show_display("INFO", "Connecting to APRS-IS server"); if(!aprs_is->connect(Config.aprs_is.server, Config.aprs_is.port)) { - Serial.println("[ERROR] Connection failed."); - Serial.println("[INFO] Waiting 5 seconds before retrying..."); + logPrintlnE("Connection failed."); + logPrintlnI("Waiting 5 seconds before retrying..."); show_display("ERROR", "Server connection failed!", "waiting 5 sec"); delay(5000); return; } - Serial.println("[INFO] Connected to server!"); + logPrintlnI("Connected to APRS-IS server!"); } if(Config.aprs_is.active && aprs_is->available() > 0) { String str = aprs_is->getMessage(); - Serial.print("[" + timeClient.getFormattedTime() + "] "); - Serial.println(str); + logPrintD("[" + timeClient.getFormattedTime() + "] "); + logPrintlnD(str); } if(lora_aprs.hasMessage()) { @@ -194,13 +197,13 @@ void loop() setup_display(); secondsSinceDisplay = 0; display_is_on = true; show_display(Config.callsign, timeClient.getFormattedTime() + " LoRa", "RSSI: " + String(lora_aprs.packetRssi()) + ", SNR: " + String(lora_aprs.packetSnr()), msg->toString()); - Serial.print("[" + timeClient.getFormattedTime() + "] "); - Serial.print(" Received packet '"); - Serial.print(msg->toString()); - Serial.print("' with RSSI "); - Serial.print(lora_aprs.packetRssi()); - Serial.print(" and SNR "); - Serial.println(lora_aprs.packetSnr()); + logPrintD("[" + timeClient.getFormattedTime() + "] "); + logPrintD(" Received packet '"); + logPrintD(msg->toString()); + logPrintD("' with RSSI "); + logPrintD(String(lora_aprs.packetRssi())); + logPrintD(" and SNR "); + logPrintlnD(String(lora_aprs.packetSnr())); if(Config.aprs_is.active) { @@ -210,12 +213,12 @@ void loop() { if(msg->getSource().indexOf(Config.callsign) != -1) { - Serial.print("Message already received as repeater: '"); - Serial.print(msg->toString()); - Serial.print("' with RSSI "); - Serial.print(lora_aprs.packetRssi()); - Serial.print(" and SNR "); - Serial.println(lora_aprs.packetSnr()); + logPrintD("Message already received as repeater: '"); + logPrintD(msg->toString()); + logPrintD("' with RSSI "); + logPrintD(String(lora_aprs.packetRssi())); + logPrintD(" and SNR "); + logPrintlnD(String(lora_aprs.packetSnr())); return; } @@ -235,24 +238,24 @@ void loop() { setup_display(); secondsSinceDisplay = 0; display_is_on = true; show_display(Config.callsign, "RSSI: " + String(lora_aprs.packetRssi()) + ", SNR: " + String(lora_aprs.packetSnr()), msg->toString(), 0); - Serial.print("Received packet '"); - Serial.print(msg->toString()); - Serial.print("' with RSSI "); - Serial.print(lora_aprs.packetRssi()); - Serial.print(" and SNR "); - Serial.println(lora_aprs.packetSnr()); + logPrintD("Received packet '"); + logPrintD(msg->toString()); + logPrintD("' with RSSI "); + logPrintD(String(lora_aprs.packetRssi())); + logPrintD(" and SNR "); + logPrintlnD(String(lora_aprs.packetSnr())); msg->setPath(String(Config.callsign) + "*"); lora_aprs.sendMessage(msg); lastMessages.insert({secondsSinceStartup, msg}); } else { - Serial.print("Message already received (timeout): '"); - Serial.print(msg->toString()); - Serial.print("' with RSSI "); - Serial.print(lora_aprs.packetRssi()); - Serial.print(" and SNR "); - Serial.println(lora_aprs.packetSnr()); + logPrintD("Message already received (timeout): '"); + logPrintD(msg->toString()); + logPrintD("' with RSSI "); + logPrintD(String(lora_aprs.packetRssi())); + logPrintD(" and SNR "); + logPrintlnD(String(lora_aprs.packetSnr())); } return; } @@ -276,19 +279,19 @@ void loop() beacon_digi = false; setup_display(); secondsSinceDisplay = 0; display_is_on = true; show_display(Config.callsign, "Beacon to HF..."); - Serial.print("[" + timeClient.getFormattedTime() + "] "); - Serial.print(BeaconMsg->encode()); + logPrintD("[" + timeClient.getFormattedTime() + "] "); + logPrintlnD(BeaconMsg->encode()); lora_aprs.sendMessage(BeaconMsg); - Serial.println("finished TXing..."); + logPrintlnD("finished TXing..."); show_display(Config.callsign, "Standby..."); } if(beacon_aprs_is) { beacon_aprs_is = false; setup_display(); secondsSinceDisplay = 0; display_is_on = true; - show_display(Config.callsign, "Beacon to APRS IS Server..."); - Serial.print("[" + timeClient.getFormattedTime() + "] "); - Serial.print(BeaconMsg->encode()); + show_display(Config.callsign, "Beacon to APRS-IS Server..."); + logPrintD("[" + timeClient.getFormattedTime() + "] "); + logPrintlnD(BeaconMsg->encode()); aprs_is->sendMessage(BeaconMsg); show_display(Config.callsign, "Standby..."); } @@ -300,7 +303,7 @@ void load_config() Config = confmg.readConfiguration(); if(Config.callsign == "NOCALL-10") { - Serial.println("[ERROR] You have to change your settings in 'data/is-cfg.json' and upload it via \"Upload File System image\"!"); + logPrintlnE("You have to change your settings in 'data/is-cfg.json' and upload it via \"Upload File System image\"!"); show_display("ERROR", "You have to change your settings in 'data/is-cfg.json' and upload it via \"Upload File System image\"!"); while (true) {} @@ -308,7 +311,7 @@ void load_config() if(Config.aprs_is.active && !Config.wifi.active) { - Serial.println("[ERROR] You have to activate Wifi for APRS IS to work, please check your settings!"); + logPrintlnE("You have to activate Wifi for APRS IS to work, please check your settings!"); show_display("ERROR", "You have to activate Wifi for APRS IS to work, please check your settings!"); while (true) {} @@ -318,7 +321,7 @@ void load_config() { Config.display.overwritePin = KEY_BUILTIN; } - Serial.println("[INFO] Configuration loaded!"); + logPrintlnI("Configuration loaded!"); } void setup_wifi() @@ -327,22 +330,20 @@ void setup_wifi() WiFi.setHostname(Config.callsign.c_str()); for(Configuration::Wifi::AP ap : Config.wifi.APs) { - Serial.print("[INFO] Looking for AP: "); - Serial.println(ap.SSID); + logPrintD("Looking for AP: "); + logPrintlnD(ap.SSID); WiFiMulti.addAP(ap.SSID.c_str(), ap.password.c_str()); } - Serial.print("[INFO] Waiting for WiFi"); + logPrintlnI("Waiting for WiFi"); show_display("INFO", "Waiting for WiFi"); while(WiFiMulti.run() != WL_CONNECTED) { - Serial.print("."); show_display("INFO", "Waiting for WiFi", "...."); delay(500); } - Serial.println(""); - Serial.println("[INFO] WiFi connected"); - Serial.print("[INFO] IP address: "); - Serial.println(WiFi.localIP()); + logPrintlnI("WiFi connected"); + logPrintD("IP address: "); + logPrintlnD(WiFi.localIP().toString()); show_display("INFO", "WiFi connected", "IP: ", WiFi.localIP().toString(), 2000); } @@ -383,7 +384,7 @@ void setup_ota() }); ArduinoOTA.setHostname(Config.callsign.c_str()); ArduinoOTA.begin(); - Serial.println("[INFO] OTA init done!"); + logPrintlnI("OTA init done!"); } void setup_lora() @@ -392,7 +393,7 @@ void setup_lora() lora_aprs.setTxFrequency(Config.lora.frequencyTx); if (!lora_aprs.begin(lora_aprs.getRxFrequency())) { - Serial.println("[ERROR] Starting LoRa failed!"); + logPrintlnE("Starting LoRa failed!"); show_display("ERROR", "Starting LoRa failed!"); while (1); } @@ -400,7 +401,7 @@ void setup_lora() lora_aprs.setSpreadingFactor(Config.lora.spreadingFactor); lora_aprs.setSignalBandwidth(Config.lora.signalBandwidth); lora_aprs.setCodingRate4(Config.lora.codingRate4); - Serial.println("[INFO] LoRa init done!"); + logPrintlnI("LoRa init done!"); show_display("INFO", "LoRa init done!", 2000); BeaconMsg = std::shared_ptr(new APRSMessage()); @@ -416,10 +417,10 @@ void setup_ntp() timeClient.begin(); if(!timeClient.forceUpdate()) { - Serial.println("[WARN] NTP Client force update issue!"); + logPrintlnW("NTP Client force update issue!"); show_display("WARN", "NTP Client force update issue!", 2000); } - Serial.println("[INFO] NTP Client init done!"); + logPrintlnI("NTP Client init done!"); show_display("INFO", "NTP Client init done!", 2000); } @@ -454,13 +455,13 @@ void setup_ftp() } for(Configuration::Ftp::User user : Config.ftp.users) { - Serial.print("[INFO] Adding user to FTP Server: "); - Serial.println(user.name); + logPrintD("Adding user to FTP Server: "); + logPrintlnD(user.name); ftpServer.addUser(user.name, user.password); } ftpServer.addFilesystem("SPIFFS", &SPIFFS); ftpServer.begin(); - Serial.println("[INFO] FTP Server init done!"); + logPrintlnI("FTP Server init done!"); } String create_lat_aprs(double lat) diff --git a/src/configuration.cpp b/src/configuration.cpp index 92fa1e3..257f02e 100644 --- a/src/configuration.cpp +++ b/src/configuration.cpp @@ -1,17 +1,18 @@ -#include "SPIFFS.h" +#include #include "configuration.h" +#include "logger.h" ConfigurationManagement::ConfigurationManagement(String FilePath) : mFilePath(FilePath) { if(!SPIFFS.begin(true)) { - Serial.println("[ERROR] Mounting SPIFFS was not possible. Trying to format SPIFFS..."); + logPrintlnE("Mounting SPIFFS was not possible. Trying to format SPIFFS..."); SPIFFS.format(); if(!SPIFFS.begin()) { - Serial.println("[ERROR] Formating SPIFFS was not okay!"); + logPrintlnE("Formating SPIFFS was not okay!"); } } } @@ -21,14 +22,14 @@ Configuration ConfigurationManagement::readConfiguration() File file = SPIFFS.open(mFilePath); if(!file) { - Serial.println("Failed to open file for reading..."); + logPrintlnE("Failed to open file for reading..."); return Configuration(); } DynamicJsonDocument data(2048); DeserializationError error = deserializeJson(data, file); if(error) { - Serial.println("Failed to read file, using default configuration."); + logPrintlnW("Failed to read file, using default configuration."); } //serializeJson(data, Serial); //Serial.println(); @@ -102,7 +103,7 @@ void ConfigurationManagement::writeConfiguration(Configuration conf) File file = SPIFFS.open(mFilePath, "w"); if(!file) { - Serial.println("Failed to open file for writing..."); + logPrintlnE("Failed to open file for writing..."); return; } DynamicJsonDocument data(2048); diff --git a/src/display.cpp b/src/display.cpp index 09c90ab..f8a69c0 100644 --- a/src/display.cpp +++ b/src/display.cpp @@ -5,6 +5,7 @@ #include "display.h" #include "pins.h" +#include "logger.h" Adafruit_SSD1306 display(128, 64, &Wire, OLED_RST); @@ -18,9 +19,10 @@ void setup_display() Wire.begin(OLED_SDA, OLED_SCL); if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3c, false, false)) { - Serial.println("SSD1306 allocation failed"); + logPrintlnE("SSD1306 allocation failed"); while (1); } + logPrintlnI("Display init done!"); } void turn_off_display() diff --git a/src/logger.cpp b/src/logger.cpp new file mode 100644 index 0000000..97f53a4 --- /dev/null +++ b/src/logger.cpp @@ -0,0 +1,234 @@ +#include "logger.h" + +#undef LOG_RESET_COLOR +#undef LOG_COLOR_E +#undef LOG_COLOR_W +#undef LOG_COLOR_I +#undef LOG_COLOR_D +#undef LOG_COLOR_V + +#define LOG_COLOR_BLACK "30" +#define LOG_COLOR_RED "31" +#define LOG_COLOR_GREEN "32" +#define LOG_COLOR_BROWN "33" +#define LOG_COLOR_BLUE "34" +#define LOG_COLOR_PURPLE "35" +#define LOG_COLOR_CYAN "36" +#define LOG_COLOR(COLOR) "\033[0;" COLOR "m" +#define LOG_BOLD(COLOR) "\033[1;" COLOR "m" +#define LOG_RESET_COLOR "\033[0m" +#define LOG_COLOR_E LOG_COLOR(LOG_COLOR_RED) +#define LOG_COLOR_W LOG_COLOR(LOG_COLOR_BROWN) +#define LOG_COLOR_I LOG_COLOR(LOG_COLOR_GREEN) +#define LOG_COLOR_D LOG_COLOR(LOG_COLOR_BLUE) +#define LOG_COLOR_V LOG_COLOR(LOG_COLOR_CYAN) + +Logger::Logger() + : _serial(Serial), _level(DEBUG_LEVEL_DEBUG), _printIsNewline(true) +{ +} + +void Logger::setSerial(HardwareSerial & serial) +{ + _serial = serial; +} + +void Logger::setDebugLevel(debug_level_t level) +{ + _level = level; +} + +void Logger::printA(const String & text, const char * file, uint32_t line) +{ + printStartColor(DEBUG_LEVEL_NONE); + printHeader(DEBUG_LEVEL_NONE, file, line, false); + _serial.print(text); + printEndColor(DEBUG_LEVEL_NONE); +} + +void Logger::printE(const String & text, const char * file, uint32_t line) +{ + printStartColor(DEBUG_LEVEL_ERROR); + printHeader(DEBUG_LEVEL_ERROR, file, line, false); + _serial.print(text); + printEndColor(DEBUG_LEVEL_ERROR); +} + +void Logger::printlnA(const String & text, const char * file, uint32_t line) +{ + printStartColor(DEBUG_LEVEL_NONE); + printHeader(DEBUG_LEVEL_NONE, file, line, true); + _serial.println(text); + printEndColor(DEBUG_LEVEL_NONE); +} + +void Logger::printlnE(const String & text, const char * file, uint32_t line) +{ + printStartColor(DEBUG_LEVEL_ERROR); + printHeader(DEBUG_LEVEL_ERROR, file, line, true); + _serial.println(text); + printEndColor(DEBUG_LEVEL_ERROR); +} + +void Logger::printV(const String & text, const char * file, uint32_t line) +{ + if (_level >= DEBUG_LEVEL_VERBOSE) + { + printStartColor(DEBUG_LEVEL_VERBOSE); + printHeader(DEBUG_LEVEL_VERBOSE, file, line, false); + _serial.print(text); + printEndColor(DEBUG_LEVEL_VERBOSE); + } +} + +void Logger::printD(const String & text, const char * file, uint32_t line) +{ + if (_level >= DEBUG_LEVEL_DEBUG) + { + printStartColor(DEBUG_LEVEL_DEBUG); + printHeader(DEBUG_LEVEL_DEBUG, file, line, false); + _serial.print(text); + printEndColor(DEBUG_LEVEL_DEBUG); + } +} + +void Logger::printI(const String & text, const char * file, uint32_t line) +{ + if (_level >= DEBUG_LEVEL_INFO) + { + printStartColor(DEBUG_LEVEL_INFO); + printHeader(DEBUG_LEVEL_INFO, file, line, false); + _serial.print(text); + printEndColor(DEBUG_LEVEL_INFO); + } +} + +void Logger::printW(const String & text, const char * file, uint32_t line) +{ + if (_level >= DEBUG_LEVEL_WARN) + { + printStartColor(DEBUG_LEVEL_WARN); + printHeader(DEBUG_LEVEL_WARN, file, line, false); + _serial.print(text); + printEndColor(DEBUG_LEVEL_WARN); + } +} + +void Logger::printlnV(const String & text, const char * file, uint32_t line) +{ + if (_level >= DEBUG_LEVEL_VERBOSE) + { + printStartColor(DEBUG_LEVEL_VERBOSE); + printHeader(DEBUG_LEVEL_VERBOSE, file, line, true); + _serial.println(text); + printEndColor(DEBUG_LEVEL_VERBOSE); + } +} + +void Logger::printlnD(const String & text, const char * file, uint32_t line) +{ + if (_level >= DEBUG_LEVEL_DEBUG) + { + printStartColor(DEBUG_LEVEL_DEBUG); + printHeader(DEBUG_LEVEL_DEBUG, file, line, true); + _serial.println(text); + printEndColor(DEBUG_LEVEL_DEBUG); + } +} + +void Logger::printlnI(const String & text, const char * file, uint32_t line) +{ + if (_level >= DEBUG_LEVEL_INFO) + { + printStartColor(DEBUG_LEVEL_INFO); + printHeader(DEBUG_LEVEL_INFO, file, line, true); + _serial.println(text); + printEndColor(DEBUG_LEVEL_INFO); + } +} + +void Logger::printlnW(const String & text, const char * file, uint32_t line) +{ + if (_level >= DEBUG_LEVEL_WARN) + { + printStartColor(DEBUG_LEVEL_WARN); + printHeader(DEBUG_LEVEL_WARN, file, line, true); + _serial.println(text); + printEndColor(DEBUG_LEVEL_WARN); + } +} + +void Logger::printStartColor(debug_level_t level) +{ + switch (level) + { + case DEBUG_LEVEL_ERROR: + _serial.print(LOG_COLOR_E); + break; + case DEBUG_LEVEL_WARN: + _serial.print(LOG_COLOR_W); + break; + case DEBUG_LEVEL_INFO: + _serial.print(LOG_COLOR_I); + break; + case DEBUG_LEVEL_DEBUG: + _serial.print(LOG_COLOR_D); + break; + case DEBUG_LEVEL_VERBOSE: + _serial.print(LOG_COLOR_V); + break; + default: + break; + } +} + +void Logger::printHeader(debug_level_t level, const char * file, uint32_t line, bool isln) +{ + if (_printIsNewline) + { + Serial.printf("%c %25s %4d : ", levelToChar(level), file, line); + if(!isln) + { + _printIsNewline = false; + } + } + else + { + _printIsNewline = isln; + } +} + +void Logger::printEndColor(debug_level_t level) +{ + switch (level) + { + case DEBUG_LEVEL_ERROR: + case DEBUG_LEVEL_WARN: + case DEBUG_LEVEL_INFO: + case DEBUG_LEVEL_DEBUG: + case DEBUG_LEVEL_VERBOSE: + _serial.print(LOG_RESET_COLOR); + break; + default: + break; + } +} + +char Logger::levelToChar(debug_level_t level) +{ + switch (level) + { + case DEBUG_LEVEL_ERROR: + return 'E'; + case DEBUG_LEVEL_WARN: + return 'W'; + case DEBUG_LEVEL_INFO: + return 'I'; + case DEBUG_LEVEL_DEBUG: + return 'D'; + case DEBUG_LEVEL_VERBOSE: + return 'V'; + default: + return ' '; + } +} diff --git a/src/logger.h b/src/logger.h new file mode 100644 index 0000000..33ba99c --- /dev/null +++ b/src/logger.h @@ -0,0 +1,75 @@ +#ifndef _LOGGER_H_ +#define _LOGGER_H_ + +#include + +class Logger +{ +public: + enum debug_level_t { + DEBUG_LEVEL_NONE, // No debug output + DEBUG_LEVEL_ERROR, // Critical errors + DEBUG_LEVEL_WARN, // Error conditions but not critical + DEBUG_LEVEL_INFO, // Information messages + DEBUG_LEVEL_DEBUG, // Extra information - default level (if not changed) + DEBUG_LEVEL_VERBOSE, // More information than the usual + DEBUG_LEVELS_SIZE + }; + + static Logger & instance() + { + static Logger _instance; + return _instance; + } + + ~Logger() {} + + void setSerial(HardwareSerial & serial = Serial); + void setDebugLevel(debug_level_t level); + + // print always: + void printA(const String & text, const char * file, uint32_t line); // always + void printE(const String & text, const char * file, uint32_t line); // error + void printlnA(const String & text, const char * file, uint32_t line); // always with new line + void printlnE(const String & text, const char * file, uint32_t line); // error with new line + + // depending on verbose level: + void printV(const String & text, const char * file, uint32_t line); // verbose + void printD(const String & text, const char * file, uint32_t line); // debug + void printI(const String & text, const char * file, uint32_t line); // information + void printW(const String & text, const char * file, uint32_t line); // warning + + void printlnV(const String & text, const char * file, uint32_t line); // verbose with new line + void printlnD(const String & text, const char * file, uint32_t line); // debug with new line + void printlnI(const String & text, const char * file, uint32_t line); // information with new line + void printlnW(const String & text, const char * file, uint32_t line); // warning with new line + +private: + HardwareSerial & _serial; + debug_level_t _level; + bool _printIsNewline; + + void printStartColor(debug_level_t level); + void printHeader(debug_level_t level, const char * file, uint32_t line, bool isln); + void printEndColor(debug_level_t level); + char levelToChar(debug_level_t level); + + Logger(); + Logger(const Logger &); + Logger & operator = (const Logger &); +}; + +#define logPrintA(text) Logger::instance().printA(text, __FILE__, __LINE__) +#define logPrintE(text) Logger::instance().printE(text, __FILE__, __LINE__) +#define logPrintlnA(text) Logger::instance().printlnA(text, __FILE__, __LINE__) +#define logPrintlnE(text) Logger::instance().printlnE(text, __FILE__, __LINE__) +#define logPrintV(text) Logger::instance().printV(text, __FILE__, __LINE__) +#define logPrintD(text) Logger::instance().printD(text, __FILE__, __LINE__) +#define logPrintI(text) Logger::instance().printI(text, __FILE__, __LINE__) +#define logPrintW(text) Logger::instance().printW(text, __FILE__, __LINE__) +#define logPrintlnV(text) Logger::instance().printlnV(text, __FILE__, __LINE__) +#define logPrintlnD(text) Logger::instance().printlnD(text, __FILE__, __LINE__) +#define logPrintlnI(text) Logger::instance().printlnI(text, __FILE__, __LINE__) +#define logPrintlnW(text) Logger::instance().printlnW(text, __FILE__, __LINE__) + +#endif From 8df4bcc54b3a951c192877f7b04bc661f80a6973 Mon Sep 17 00:00:00 2001 From: Peter Buchegger Date: Sun, 8 Nov 2020 01:13:11 +0100 Subject: [PATCH 16/29] fixing cppcheck --- src/logger.cpp | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/src/logger.cpp b/src/logger.cpp index 97f53a4..0e63503 100644 --- a/src/logger.cpp +++ b/src/logger.cpp @@ -28,16 +28,19 @@ Logger::Logger() { } -void Logger::setSerial(HardwareSerial & serial) +// cppcheck-suppress unusedFunction +void Logger::setSerial(const HardwareSerial & serial) { _serial = serial; } +// cppcheck-suppress unusedFunction void Logger::setDebugLevel(debug_level_t level) { _level = level; } +// cppcheck-suppress unusedFunction void Logger::printA(const String & text, const char * file, uint32_t line) { printStartColor(DEBUG_LEVEL_NONE); @@ -46,6 +49,7 @@ void Logger::printA(const String & text, const char * file, uint32_t line) printEndColor(DEBUG_LEVEL_NONE); } +// cppcheck-suppress unusedFunction void Logger::printE(const String & text, const char * file, uint32_t line) { printStartColor(DEBUG_LEVEL_ERROR); @@ -54,6 +58,7 @@ void Logger::printE(const String & text, const char * file, uint32_t line) printEndColor(DEBUG_LEVEL_ERROR); } +// cppcheck-suppress unusedFunction void Logger::printlnA(const String & text, const char * file, uint32_t line) { printStartColor(DEBUG_LEVEL_NONE); @@ -62,6 +67,7 @@ void Logger::printlnA(const String & text, const char * file, uint32_t line) printEndColor(DEBUG_LEVEL_NONE); } +// cppcheck-suppress unusedFunction void Logger::printlnE(const String & text, const char * file, uint32_t line) { printStartColor(DEBUG_LEVEL_ERROR); @@ -70,6 +76,7 @@ void Logger::printlnE(const String & text, const char * file, uint32_t line) printEndColor(DEBUG_LEVEL_ERROR); } +// cppcheck-suppress unusedFunction void Logger::printV(const String & text, const char * file, uint32_t line) { if (_level >= DEBUG_LEVEL_VERBOSE) @@ -81,6 +88,7 @@ void Logger::printV(const String & text, const char * file, uint32_t line) } } +// cppcheck-suppress unusedFunction void Logger::printD(const String & text, const char * file, uint32_t line) { if (_level >= DEBUG_LEVEL_DEBUG) @@ -92,6 +100,7 @@ void Logger::printD(const String & text, const char * file, uint32_t line) } } +// cppcheck-suppress unusedFunction void Logger::printI(const String & text, const char * file, uint32_t line) { if (_level >= DEBUG_LEVEL_INFO) @@ -103,6 +112,7 @@ void Logger::printI(const String & text, const char * file, uint32_t line) } } +// cppcheck-suppress unusedFunction void Logger::printW(const String & text, const char * file, uint32_t line) { if (_level >= DEBUG_LEVEL_WARN) @@ -114,6 +124,7 @@ void Logger::printW(const String & text, const char * file, uint32_t line) } } +// cppcheck-suppress unusedFunction void Logger::printlnV(const String & text, const char * file, uint32_t line) { if (_level >= DEBUG_LEVEL_VERBOSE) @@ -125,6 +136,7 @@ void Logger::printlnV(const String & text, const char * file, uint32_t line) } } +// cppcheck-suppress unusedFunction void Logger::printlnD(const String & text, const char * file, uint32_t line) { if (_level >= DEBUG_LEVEL_DEBUG) @@ -136,6 +148,7 @@ void Logger::printlnD(const String & text, const char * file, uint32_t line) } } +// cppcheck-suppress unusedFunction void Logger::printlnI(const String & text, const char * file, uint32_t line) { if (_level >= DEBUG_LEVEL_INFO) @@ -147,6 +160,7 @@ void Logger::printlnI(const String & text, const char * file, uint32_t line) } } +// cppcheck-suppress unusedFunction void Logger::printlnW(const String & text, const char * file, uint32_t line) { if (_level >= DEBUG_LEVEL_WARN) From 4cddc2054b6dbbd168a49373eca8b30fd7fec1d9 Mon Sep 17 00:00:00 2001 From: Peter Buchegger Date: Sun, 8 Nov 2020 01:28:48 +0100 Subject: [PATCH 17/29] fixing missing const --- src/logger.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/logger.h b/src/logger.h index 33ba99c..51ddedb 100644 --- a/src/logger.h +++ b/src/logger.h @@ -24,7 +24,7 @@ public: ~Logger() {} - void setSerial(HardwareSerial & serial = Serial); + void setSerial(const HardwareSerial & serial = Serial); void setDebugLevel(debug_level_t level); // print always: From 3b53498df181d8bd25315543f2cc0a6180e3942d Mon Sep 17 00:00:00 2001 From: Peter Buchegger Date: Sun, 8 Nov 2020 13:03:46 +0100 Subject: [PATCH 18/29] add monitor flag: raw --- platformio.ini | 1 + 1 file changed, 1 insertion(+) diff --git a/platformio.ini b/platformio.ini index 34a9ddf..eee9aa1 100644 --- a/platformio.ini +++ b/platformio.ini @@ -17,6 +17,7 @@ lib_deps = check_tool = cppcheck check_flags = cppcheck: --suppress=*:*.pio\* --inline-suppr +monitor_flags = --raw # activate for OTA Update, use the CALLSIGN from is-cfg.h as upload_port: #upload_protocol = espota #upload_port = .local From 6e54f526435a02715918ba98d6a448ba6c65dcc8 Mon Sep 17 00:00:00 2001 From: Peter Buchegger Date: Sun, 8 Nov 2020 17:43:56 +0100 Subject: [PATCH 19/29] fixing config --- src/configuration.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/configuration.cpp b/src/configuration.cpp index 257f02e..bbc8d3a 100644 --- a/src/configuration.cpp +++ b/src/configuration.cpp @@ -48,14 +48,14 @@ Configuration ConfigurationManagement::readConfiguration() ap.password = v["password"].as(); conf.wifi.APs.push_back(ap); } - if(data.containsKey("beacon") && data.containsKey("message")) + if(data.containsKey("beacon") && data["beacon"].containsKey("message")) conf.beacon.message = data["beacon"]["message"].as(); conf.beacon.positionLatitude = data["beacon"]["position"]["latitude"] | 0.0; conf.beacon.positionLongitude = data["beacon"]["position"]["longitude"] | 0.0; conf.aprs_is.active = data["aprs_is"]["active"] | false; - if(data.containsKey("aprs_is") && data.containsKey("password")) + if(data.containsKey("aprs_is") && data["aprs_is"].containsKey("password")) conf.aprs_is.password = data["aprs_is"]["password"].as(); - if(data.containsKey("aprs_is") && data.containsKey("server")) + if(data.containsKey("aprs_is") && data["aprs_is"].containsKey("server")) conf.aprs_is.server = data["aprs_is"]["server"].as(); conf.aprs_is.port = data["aprs_is"]["port"] | 14580; conf.aprs_is.beacon = data["aprs_is"]["beacon"] | true; From 1e97541c1c3a7d541e85fbda5fd9ced225a758b9 Mon Sep 17 00:00:00 2001 From: Peter Buchegger Date: Sat, 14 Nov 2020 13:02:54 +0100 Subject: [PATCH 20/29] wait for NTP client to get correct time --- src/LoRa_APRS_iGate.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/LoRa_APRS_iGate.cpp b/src/LoRa_APRS_iGate.cpp index acb2a86..0ddc08f 100644 --- a/src/LoRa_APRS_iGate.cpp +++ b/src/LoRa_APRS_iGate.cpp @@ -415,10 +415,10 @@ void setup_lora() void setup_ntp() { timeClient.begin(); - if(!timeClient.forceUpdate()) + while(!timeClient.forceUpdate()) { - logPrintlnW("NTP Client force update issue!"); - show_display("WARN", "NTP Client force update issue!", 2000); + logPrintlnW("NTP Client force update issue! Waiting 1 sek..."); + show_display("WARN", "NTP Client force update issue! Waiting 1 sek...", 1000); } logPrintlnI("NTP Client init done!"); show_display("INFO", "NTP Client init done!", 2000); From 327b277a953c6aedb7c677f73544744fa4b8273b Mon Sep 17 00:00:00 2001 From: Peter Buchegger Date: Sat, 14 Nov 2020 13:03:57 +0100 Subject: [PATCH 21/29] remove version information in json --- data/is-cfg.json | 1 - 1 file changed, 1 deletion(-) diff --git a/data/is-cfg.json b/data/is-cfg.json index 5b91a4f..8c3ed65 100644 --- a/data/is-cfg.json +++ b/data/is-cfg.json @@ -1,5 +1,4 @@ { - "version":4, "callsign":"NOCALL-10", "wifi": { From 9acfe8058f46800137b3149f4746ce80bbd95bf7 Mon Sep 17 00:00:00 2001 From: Peter Buchegger Date: Sun, 15 Nov 2020 13:57:04 +0100 Subject: [PATCH 22/29] release jobs: remove comments, update names, add heltec boards --- .github/workflows/release.yml | 34 ++++++++++++++++++++++++++++------ 1 file changed, 28 insertions(+), 6 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 5572892..a83c49c 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -1,14 +1,13 @@ on: push: - # Sequence of patterns matched against refs/tags tags: - - 'v*' # Push events to matching v*, i.e. v1.0, v20.15.10 + - 'v*' -name: Upload Release Asset +name: Upload Release Assets jobs: build: - name: Upload Release Asset + name: Upload Release Assets runs-on: ubuntu-latest steps: - run: sudo apt-get install python3-setuptools python3-wheel @@ -25,14 +24,25 @@ jobs: release_name: Release ${{ github.ref }} draft: false prerelease: false + # upload heltec_wifi_lora_32_v1 - uses: actions/upload-release-asset@v1 env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} with: upload_url: ${{ steps.create_release.outputs.upload_url }} - asset_path: .pio/build/TrackerD-OE1ACM/firmware.bin - asset_name: TrackerD-OE1ACM.bin + asset_path: .pio/build/heltec_wifi_lora_32_v1/firmware.bin + asset_name: heltec_wifi_lora_32_v1.bin asset_content_type: application/bin + # upload heltec_wifi_lora_32_v2 + - uses: actions/upload-release-asset@v1 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + upload_url: ${{ steps.create_release.outputs.upload_url }} + asset_path: .pio/build/heltec_wifi_lora_32_v2/firmware.bin + asset_name: heltec_wifi_lora_32_v2.bin + asset_content_type: application/bin + # upload ttgo-lora32-v1 - uses: actions/upload-release-asset@v1 env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} @@ -41,6 +51,7 @@ jobs: asset_path: .pio/build/ttgo-lora32-v1/firmware.bin asset_name: ttgo-lora32-v1.bin asset_content_type: application/bin + # upload ttgo-lora32-v2 - uses: actions/upload-release-asset@v1 env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} @@ -49,6 +60,7 @@ jobs: asset_path: .pio/build/ttgo-lora32-v2/firmware.bin asset_name: ttgo-lora32-v2.bin asset_content_type: application/bin + # upload ttgo-t-beam-v0_7 - uses: actions/upload-release-asset@v1 env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} @@ -57,6 +69,7 @@ jobs: asset_path: .pio/build/ttgo-t-beam-v0_7/firmware.bin asset_name: ttgo-t-beam-v0_7.bin asset_content_type: application/bin + # upload ttgo-t-beam-v1 - uses: actions/upload-release-asset@v1 env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} @@ -65,3 +78,12 @@ jobs: asset_path: .pio/build/ttgo-t-beam-v1/firmware.bin asset_name: ttgo-t-beam-v1.bin asset_content_type: application/bin + # upload TrackerD-OE1ACM + - uses: actions/upload-release-asset@v1 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + upload_url: ${{ steps.create_release.outputs.upload_url }} + asset_path: .pio/build/TrackerD-OE1ACM/firmware.bin + asset_name: TrackerD-OE1ACM.bin + asset_content_type: application/bin From 4c5401288992d559fcdaaf8bd3bbb00a0d767af3 Mon Sep 17 00:00:00 2001 From: Peter Buchegger Date: Sun, 15 Nov 2020 13:57:31 +0100 Subject: [PATCH 23/29] ignore readme on push and pull requests --- .github/workflows/main.yml | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index b940d07..87c03d2 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -1,6 +1,12 @@ -name: PlatformIO CI +name: PlatformIO checks and build -on: [push, pull_request] +on: + push: + paths-ignore: + - *.md + pull_request: + paths-ignore: + - *.md jobs: PlatformIO-Check: From 7bea116ffee75def47179b3c0d7eae61b286c5e3 Mon Sep 17 00:00:00 2001 From: Peter Buchegger Date: Sun, 15 Nov 2020 13:57:53 +0100 Subject: [PATCH 24/29] update heltec names --- platformio.ini | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/platformio.ini b/platformio.ini index eee9aa1..4f6e006 100644 --- a/platformio.ini +++ b/platformio.ini @@ -22,11 +22,11 @@ monitor_flags = --raw #upload_protocol = espota #upload_port = .local -[env:heltec_wifi_lora_32_V1] +[env:heltec_wifi_lora_32_v1] board = ttgo-lora32-v1 build_flags = -Werror -Wall -DHELTEC_WIFI_LORA_32_V1 -[env:heltec_wifi_lora_32_V2] +[env:heltec_wifi_lora_32_v2] board = ttgo-lora32-v1 build_flags = -Werror -Wall -DHELTEC_WIFI_LORA_32_V2 From 6116d021a7e1b1c1cd6607f110835f35ad487de2 Mon Sep 17 00:00:00 2001 From: Peter Buchegger Date: Sun, 15 Nov 2020 14:08:57 +0100 Subject: [PATCH 25/29] fixing ignore --- .github/workflows/main.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 87c03d2..1e9250e 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -3,10 +3,10 @@ name: PlatformIO checks and build on: push: paths-ignore: - - *.md + - '*.md' pull_request: paths-ignore: - - *.md + - '*.md' jobs: PlatformIO-Check: From 6ea060098b4cf5591b76a11882266d1843755647 Mon Sep 17 00:00:00 2001 From: Peter Buchegger Date: Sun, 15 Nov 2020 14:09:33 +0100 Subject: [PATCH 26/29] rename file --- .github/workflows/{main.yml => build_check.yml} | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename .github/workflows/{main.yml => build_check.yml} (96%) diff --git a/.github/workflows/main.yml b/.github/workflows/build_check.yml similarity index 96% rename from .github/workflows/main.yml rename to .github/workflows/build_check.yml index 1e9250e..a65a723 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/build_check.yml @@ -1,4 +1,4 @@ -name: PlatformIO checks and build +name: Build check and build on: push: From d9e6127d5c2f6f463b776570e40b4fcdd5ced331 Mon Sep 17 00:00:00 2001 From: Peter Buchegger Date: Sun, 15 Nov 2020 14:30:39 +0100 Subject: [PATCH 27/29] readme update --- README.md | 92 ++++++++++++++++++++++++------------------------------- 1 file changed, 40 insertions(+), 52 deletions(-) diff --git a/README.md b/README.md index 5adabbb..d43d40c 100644 --- a/README.md +++ b/README.md @@ -14,22 +14,22 @@ Try it out and be part of the APRS network. You can use one of the Lora32 boards without changings : -* Heltec WiFi LoRa 32 V1 (433MHz SX1278) -* Heltec WiFi LoRa 32 V2 (433MHz SX1278) -* TTGO LoRa32 V1 (433MHz SX1278) -* TTGO LoRa32 V2 (433MHz SX1278) -* TTGO LoRa32 V2.1 (433MHz SX1278) -* TTGO T-Beam V0.7 (433MHz SX1278) -* TTGO T-Beam V1 (433MHz SX1278) -* Tracker D from [OE1ACM and OE1CGC](https://www.lora-aprs.at/) -* and sure many more... +* Heltec WiFi LoRa 32 V1 (433MHz SX1278) +* Heltec WiFi LoRa 32 V2 (433MHz SX1278) +* TTGO LoRa32 V1 (433MHz SX1278) +* TTGO LoRa32 V2 (433MHz SX1278) +* TTGO LoRa32 V2.1 (433MHz SX1278) +* TTGO T-Beam V0.7 (433MHz SX1278) +* TTGO T-Beam V1 (433MHz SX1278) +* Tracker D from [OE1ACM and OE1CGC](https://www.lora-aprs.at/) +* and sure many more... Here are some amazon-de links for some example boards: -* [LoRa32 V1](https://www.amazon.de/dp/B07VPHYYJD) -* [LoRa32 V1](https://www.amazon.de/dp/B07QRG89ZV) -* [LoRa32 V2](https://www.amazon.de/dp/B07VL97VNH) -* [LoRa32 V2.1](https://www.amazon.de/dp/B07RXSKPBX) -* [T-Beam V1.0](https://www.amazon.de/dp/B07RT9FKPL) +* [LoRa32 V1](https://www.amazon.de/dp/B07VPHYYJD) +* [LoRa32 V1](https://www.amazon.de/dp/B07QRG89ZV) +* [LoRa32 V2](https://www.amazon.de/dp/B07VL97VNH) +* [LoRa32 V2.1](https://www.amazon.de/dp/B07RXSKPBX) +* [T-Beam V1.0](https://www.amazon.de/dp/B07RT9FKPL) This boards cost around 20 Euros, they are very cheap and perfect for an LoRa iGate. Keep in minde: you need a 433MHz version! @@ -38,50 +38,31 @@ Keep in minde: you need a 433MHz version! ### How to compile -The best success is to use PlatformIO. +The best success is to use PlatformIO (and it is the only platform where I can support you). -* Go to [PlatformIO](https://platformio.org/) download and install the IDE. -* If installed open the IDE, go to the left side and klick on 'extensions' then search for 'PatformIO' and install. -* When installed click 'the ant head' on the left and choose import the project on the right. -* Just open the folder and you can compile the Firmware. - -### Dependencies - -* [LoRa](https://github.com/sandeepmistry/arduino-LoRa) by Sandeep Mistry -* [APRS-IS-Lib](https://github.com/peterus/APRS-IS-Lib) by Peter Buchegger -* [APRS-Decoder-Lib](https://github.com/peterus/APRS-Decoder-Lib) by Peter Buchegger -* [LoRa-APRS-Lib](https://github.com/peterus/LoRa-APRS-Lib) by Peter Buchegger -* [ArduinoJson](https://github.com/bblanchon/ArduinoJson) by Benoit Blanchon -* [AXP202X_Library](https://github.com/lewisxhe/AXP202X_Library) by Lewis He -* [Adafruit SSD1306](https://github.com/adafruit/Adafruit_SSD1306) by Adafruit (with all dependecies) -* [NTPClient](https://github.com/arduino-libraries/NTPClient) by Fabrice Weinberg - -But you don't need to download all this libs, PlatformIO will take care for you ;) +* Go to [PlatformIO](https://platformio.org/) download and install the IDE. +* If installed open the IDE, go to the left side and klick on 'extensions' then search for 'PatformIO' and install. +* When installed click 'the ant head' on the left and choose import the project on the right. +* Just open the folder and you can compile the Firmware. ## Configuration -* You can find all nessesary settings to change for your configuration in **data/is-cfg.json**. -* To upload it to your board you have to do this via **Upload File System image** in PlatformIO! -* To find the 'Upload File System image' click the PlatformIO symbol (the little alien) on the left side, choos your configuration, click on 'Platform' and search for 'Upload File System image'. - -## LoRa APRS iGates on aprs.fi - -Feel free to add a link to your iGate here: - -* [OE5BPA-10](https://aprs.fi/info/a/OE5BPA-10) +* You can find all nessesary settings to change for your configuration in **data/is-cfg.json**. +* To upload it to your board you have to do this via **Upload File System image** in PlatformIO! +* To find the 'Upload File System image' click the PlatformIO symbol (the little alien) on the left side, choos your configuration, click on 'Platform' and search for 'Upload File System image'. ## Future plans -* [x] show time until next beaconing -* [ ] show login issues from IS server -* [ ] add better OLED library to support multiple different OLEDs -* [x] add support to turn OLED on, off and dimming -* [ ] add support for temperature chips (BMExxx) -* [ ] add FTP server support to upload configuration -* [ ] add web server for configuration and other things -* [ ] add statistics for received packages -* [ ] show received packages on a map -* [ ] etc. +* [x] show time until next beaconing +* [ ] show login issues from IS server +* [ ] add better OLED library to support multiple different OLEDs +* [x] add support to turn OLED on, off and dimming +* [ ] add support for temperature chips (BMExxx) +* [x] add FTP server support to upload configuration +* [ ] add web server for configuration and other things +* [ ] add statistics for received packages +* [ ] show received packages on a map +* [ ] etc. ## LoRa Tracker @@ -99,4 +80,11 @@ For direct mount you need a display with this Pinout -> [VCC - GND - SCL - SDA]( A direct mount of the [other display](pics/display-wrong.jpg) is not possible without damage the display! The 'wrong' display works too but you have to change VCC and GND by wire ! -feel free to add hints! \ No newline at end of file +feel free to add hints! + +## Blog posts and Youtube videos from other Hams + +* [OE1ROT](https://www.aronaut.at/2020/11/lora-aprs-gateway-mit-esp32-boards/) +* [DL7AG](http://online.dl7ag.de/lora-aprs-dl7ag-10/) +* [Manuel Lausmann - Tracker](https://www.youtube.com/watch?v=clIlTEFbWLk) +* [Manuel Lausmann - iGate](https://www.youtube.com/watch?v=C7hfVe32pXs) From a96eab365228aeb1c0d21d4cfb03d7d0bb19d931 Mon Sep 17 00:00:00 2001 From: Peter Buchegger Date: Sun, 15 Nov 2020 20:58:30 +0100 Subject: [PATCH 28/29] readme changes --- README.md | 59 ++++++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 45 insertions(+), 14 deletions(-) diff --git a/README.md b/README.md index d43d40c..9cf9beb 100644 --- a/README.md +++ b/README.md @@ -1,18 +1,24 @@ # LoRa APRS iGate -![PlatformIO CI](https://github.com/lora-aprs/LoRa_APRS_iGate/workflows/PlatformIO%20CI/badge.svg) +![Build check and build](https://github.com/lora-aprs/LoRa_APRS_iGate/workflows/Build%20check%20and%20build/badge.svg) [![Codacy Badge](https://api.codacy.com/project/badge/Grade/0b7452d5b3b747b88c736e253dda51e6)](https://app.codacy.com/gh/lora-aprs/LoRa_APRS_iGate?utm_source=github.com&utm_medium=referral&utm_content=lora-aprs/LoRa_APRS_iGate&utm_campaign=Badge_Grade_Dashboard) The LoRa APRS iGate will work with very cheep hardware which you can buy from amazon, ebay or aliexpress. Try it out and be part of the APRS network. -**There is a german [quick start](https://www.lora-aprs.info/docs/LoRa_APRS_iGate/quick-start-guide/) page! Take a look ;)** - ![TTGO LoRa32](pics/iGate.png) +## Blog posts and Youtube videos from other Hams + +* [OE1ROT](https://www.aronaut.at/2020/11/lora-aprs-gateway-mit-esp32-boards/) (blog post - german) 14.11.2020 +* [DL7AG](http://online.dl7ag.de/lora-aprs-dl7ag-10/) (blog post - german) 08.11.2020 +* [Manuel Lausmann - iGate](https://www.youtube.com/watch?v=C7hfVe32pXs) (youtube - german) 06.11.2020 +* [Manuel Lausmann - Tracker](https://www.youtube.com/watch?v=clIlTEFbWLk) (youtube - german) 02.11.2020 +* [OE1ROT](https://www.aronaut.at/2019/12/lora-aprs-tracker-mit-ttgo-t-beam-433mhz/) (blog post - german) 09.12.2019 + ## Supported boards -You can use one of the Lora32 boards without changings : +You can use one of the Lora32 boards without changings: * Heltec WiFi LoRa 32 V1 (433MHz SX1278) * Heltec WiFi LoRa 32 V2 (433MHz SX1278) @@ -34,7 +40,9 @@ Here are some amazon-de links for some example boards: This boards cost around 20 Euros, they are very cheap and perfect for an LoRa iGate. Keep in minde: you need a 433MHz version! -## Compiling +## Compiling and configuration + +**There is a german [quick start](https://www.lora-aprs.info/docs/LoRa_APRS_iGate/quick-start-guide/) page! Take a look ;)** ### How to compile @@ -45,12 +53,42 @@ The best success is to use PlatformIO (and it is the only platform where I can s * When installed click 'the ant head' on the left and choose import the project on the right. * Just open the folder and you can compile the Firmware. -## Configuration +### Configuration * You can find all nessesary settings to change for your configuration in **data/is-cfg.json**. * To upload it to your board you have to do this via **Upload File System image** in PlatformIO! * To find the 'Upload File System image' click the PlatformIO symbol (the little alien) on the left side, choos your configuration, click on 'Platform' and search for 'Upload File System image'. +## Branches in this repository and version system + +This Firmware is developed in a rolling release system: everyday a new release could be created. But there are still rules where new pull requests has to go and and how the version system looks like. + +### Branches + +There are 2 main branches: +* *master* and +* *develop* + +The *master* branch has all releases and is the most stable one. With the different tags you can jump to different versions or if you take the most current master branch you will just get the last version. There will be no side releases which are branch of from master. If there is a bugfix version it will be done directly on the master branch and a tag will be generated with a new version. + +The *develop* branch is used for new feature development. It will be also used to stabilize the current development to create a new stable version (merge request to *master* branch). **Again:** all new development (pull requests) has to go directly into the *develop* branch! + +### Version system + +If the *develop* branch is stable enough for a new release it will be merged with a pull request to the *master* branch and a new version will be generated. + +The versions are based on this settings: +* major: the current year (2 digits) +* minor: the current week of the year +* patch: if there is a patch for an release, just increment the number, otherwise 0 + +*example*: a new release will be created on the 11/14/2020, this version numbers will be used: +* major: 20 +* minor: 46 +* patch: 0 + +so the version will be: 20.46.0 + ## Future plans * [x] show time until next beaconing @@ -72,7 +110,7 @@ Look at my other project: a [LoRa Tracker](https://github.com/peterus/LoRa_APRS_ ### Here are some peculiarities of the different boards -* TTGO T-Beam V1 +* TTGO T-Beam V1 When adding a 0,96" OLED display direct to the board you have to be careful, there are two different pinout versions on the market. @@ -81,10 +119,3 @@ A direct mount of the [other display](pics/display-wrong.jpg) is not possible wi The 'wrong' display works too but you have to change VCC and GND by wire ! feel free to add hints! - -## Blog posts and Youtube videos from other Hams - -* [OE1ROT](https://www.aronaut.at/2020/11/lora-aprs-gateway-mit-esp32-boards/) -* [DL7AG](http://online.dl7ag.de/lora-aprs-dl7ag-10/) -* [Manuel Lausmann - Tracker](https://www.youtube.com/watch?v=clIlTEFbWLk) -* [Manuel Lausmann - iGate](https://www.youtube.com/watch?v=C7hfVe32pXs) From 4338fa47f0a7e4033829b689f65baf1c5f2096da Mon Sep 17 00:00:00 2001 From: Peter Buchegger Date: Sun, 15 Nov 2020 21:04:44 +0100 Subject: [PATCH 29/29] readme update --- README.md | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 9cf9beb..ac540ec 100644 --- a/README.md +++ b/README.md @@ -16,6 +16,8 @@ Try it out and be part of the APRS network. * [Manuel Lausmann - Tracker](https://www.youtube.com/watch?v=clIlTEFbWLk) (youtube - german) 02.11.2020 * [OE1ROT](https://www.aronaut.at/2019/12/lora-aprs-tracker-mit-ttgo-t-beam-433mhz/) (blog post - german) 09.12.2019 +feel free to add yours or create a ticket if you want to be added. + ## Supported boards You can use one of the Lora32 boards without changings: @@ -61,7 +63,7 @@ The best success is to use PlatformIO (and it is the only platform where I can s ## Branches in this repository and version system -This Firmware is developed in a rolling release system: everyday a new release could be created. But there are still rules where new pull requests has to go and and how the version system looks like. +This firmware is developed in a rolling release system: everyday a new release could be created. But there are still rules where new pull requests has to go and and how the version system looks like. ### Branches @@ -69,9 +71,9 @@ There are 2 main branches: * *master* and * *develop* -The *master* branch has all releases and is the most stable one. With the different tags you can jump to different versions or if you take the most current master branch you will just get the last version. There will be no side releases which are branch of from master. If there is a bugfix version it will be done directly on the master branch and a tag will be generated with a new version. +The *master* branch has all releases and is the most stable one. With the different tags you can jump to different versions or if you take the most current *master* branch you will just get the latest, stable version. There will be no side releases which are branched of from *master*. If there is a bugfix version it will be done directly on the *master* branch and a tag will be generated with a new version. -The *develop* branch is used for new feature development. It will be also used to stabilize the current development to create a new stable version (merge request to *master* branch). **Again:** all new development (pull requests) has to go directly into the *develop* branch! +The *develop* branch is used for new feature development. It will be also used to stabilize the current development to create a new stable version (pull request to *master* branch). **Again:** all new development (pull requests) has to go directly into the *develop* branch! ### Version system @@ -80,7 +82,7 @@ If the *develop* branch is stable enough for a new release it will be merged wit The versions are based on this settings: * major: the current year (2 digits) * minor: the current week of the year -* patch: if there is a patch for an release, just increment the number, otherwise 0 +* patch: if there is a important fix for an release, just increment the number, otherwise 0 *example*: a new release will be created on the 11/14/2020, this version numbers will be used: * major: 20