diff --git a/lib/ConfigurationManagement/configuration.cpp b/lib/ConfigurationManagement/configuration.cpp deleted file mode 100644 index 5f50550..0000000 --- a/lib/ConfigurationManagement/configuration.cpp +++ /dev/null @@ -1,53 +0,0 @@ -#include "configuration.h" -#include -#include - -ConfigurationManagement::ConfigurationManagement(String FilePath) : mFilePath(FilePath) { - if (!SPIFFS.begin(true)) { - logPrintlnI("Mounting SPIFFS was not possible. Trying to format SPIFFS..."); - SPIFFS.format(); - if (!SPIFFS.begin()) { - logPrintlnE("Formating SPIFFS was not okay!"); - } - } -} - -ConfigurationManagement::~ConfigurationManagement() { -} - -void ConfigurationManagement::readConfiguration(Configuration &conf) { - File file = SPIFFS.open(mFilePath); - if (!file) { - logPrintlnE("Failed to open file for reading, using default configuration."); - return; - } - DynamicJsonDocument data(2048); - DeserializationError error = deserializeJson(data, file); - if (error) { - logPrintlnW("Failed to read file, using default configuration."); - } - // serializeJson(data, Serial); - // Serial.println(); - file.close(); - - readProjectConfiguration(data, conf); - - // update config in memory to get the new fields: - writeConfiguration(conf); -} - -void ConfigurationManagement::writeConfiguration(Configuration &conf) { - File file = SPIFFS.open(mFilePath, "w"); - if (!file) { - logPrintlnE("Failed to open file for writing..."); - return; - } - DynamicJsonDocument data(2048); - - writeProjectConfiguration(conf, data); - - serializeJson(data, file); - // serializeJson(data, Serial); - // Serial.println(); - file.close(); -} diff --git a/lib/ConfigurationManagement/configuration.h b/lib/ConfigurationManagement/configuration.h deleted file mode 100644 index 6ebcf75..0000000 --- a/lib/ConfigurationManagement/configuration.h +++ /dev/null @@ -1,29 +0,0 @@ -#ifndef CONFIGURATION_H_ -#define CONFIGURATION_H_ - -#include -#include - -#include -#ifndef CPPCHECK -#include -#endif - -class Configuration; - -class ConfigurationManagement { -public: - explicit ConfigurationManagement(String FilePath); - virtual ~ConfigurationManagement(); - - void readConfiguration(Configuration &conf); - void writeConfiguration(Configuration &conf); - -private: - virtual void readProjectConfiguration(DynamicJsonDocument &data, Configuration &conf) = 0; - virtual void writeProjectConfiguration(Configuration &conf, DynamicJsonDocument &data) = 0; - - const String mFilePath; -}; - -#endif diff --git a/lib/System/System.h b/lib/System/System.h index 376741b..55c9497 100644 --- a/lib/System/System.h +++ b/lib/System/System.h @@ -6,7 +6,8 @@ #include "TaskManager.h" #include #include -#include + +class Configuration; // needs to be defined in user programm class System { public: diff --git a/lib/System/TaskManager.cpp b/lib/System/TaskManager.cpp index b53bc1d..d2bd551 100644 --- a/lib/System/TaskManager.cpp +++ b/lib/System/TaskManager.cpp @@ -18,17 +18,19 @@ std::list TaskManager::getTasks() { } bool TaskManager::setup(System &system) { - logPrintlnV("will setup all tasks..."); + logPrintlnV("will setup all always run tasks..."); for (Task *elem : _alwaysRunTasks) { - logPrintD("call setup from "); + logPrintD("call setup from always task "); logPrintlnD(elem->getName()); elem->setup(system); } + logPrintlnD("done, will setup all normal tasks..."); for (Task *elem : _tasks) { logPrintD("call setup from "); logPrintlnD(elem->getName()); elem->setup(system); } + logPrintlnD("done"); _nextTask = _tasks.begin(); return true; } @@ -36,7 +38,7 @@ bool TaskManager::setup(System &system) { bool TaskManager::loop(System &system) { // logPrintlnD("will loop all tasks..."); for (Task *elem : _alwaysRunTasks) { - // logPrintD("call loop from "); + // logPrintD("call always loop for "); // logPrintlnD(elem->getName()); elem->loop(system); } @@ -44,6 +46,8 @@ bool TaskManager::loop(System &system) { if (_nextTask == _tasks.end()) { _nextTask = _tasks.begin(); } + // logPrintD("call loop for "); + // logPrintlnD((*_nextTask)->getName()); bool ret = (*_nextTask)->loop(system); ++_nextTask; return ret; diff --git a/lib/System/TaskManager.h b/lib/System/TaskManager.h index 7b7c4b6..b5c4287 100644 --- a/lib/System/TaskManager.h +++ b/lib/System/TaskManager.h @@ -7,7 +7,6 @@ #include #include -#include #include "TaskQueue.h" diff --git a/platformio.ini b/platformio.ini index d0aa3c4..1fb595b 100644 --- a/platformio.ini +++ b/platformio.ini @@ -13,6 +13,7 @@ lib_deps = peterus/APRS-Decoder-Lib @ 0.0.6 peterus/esp-logger @ 0.0.1 peterus/ESP-FTP-Server-Lib @ 0.9.5 + peterus/ESP-Config @ 0.0.4 check_tool = cppcheck check_flags = cppcheck: --suppress=*:*.pio\* --inline-suppr -DCPPCHECK --force lib -ilib/TimeLib -ilib/LoRa -ilib/NTPClient diff --git a/src/LoRa_APRS_iGate.cpp b/src/LoRa_APRS_iGate.cpp index 08d2912..e568d87 100644 --- a/src/LoRa_APRS_iGate.cpp +++ b/src/LoRa_APRS_iGate.cpp @@ -16,7 +16,7 @@ #include "TaskOTA.h" #include "TaskRouter.h" #include "TaskWifi.h" -#include "project_configuration.h" +#include "configuration.h" #define VERSION "21.25.0-dev" @@ -27,8 +27,12 @@ TaskQueue> toAprsIs; TaskQueue> fromModem; TaskQueue> toModem; -System LoRaSystem; -Configuration userConfig; +System LoRaSystem; +Configuration userConfig; +ConfigHTML html; +ConfigFactory fact; +const String config_filename = "/is-cfg.json"; +AsyncWebServer server(80); DisplayTask displayTask; ModemTask modemTask(fromModem, toModem); @@ -43,6 +47,7 @@ RouterTask routerTask(fromModem, toModem, toAprsIs); void setup() { Serial.begin(115200); Logger::instance().setSerial(&Serial); + SPIFFS.begin(true); delay(500); logPrintlnI("LoRa APRS iGate by OE5BPA (Peter Buchegger)"); logPrintlnI("Version: " VERSION); @@ -57,11 +62,17 @@ void setup() { boardConfigs.push_back(&HELTEC_WIFI_LORA_32_V1); boardConfigs.push_back(&HELTEC_WIFI_LORA_32_V2); - ProjectConfigurationManagement confmg; - confmg.readConfiguration(userConfig); + fact.addPage(&page); + fact.loadConfig(config_filename); + + html.addPage(&page); + html.registerWebServer(server); + server.onNotFound([](AsyncWebServerRequest *request) { + request->send(404, "text/plain", "Not found"); + }); BoardFinder finder(boardConfigs); - BoardConfig const *boardConfig = finder.getBoardConfig(userConfig.board); + BoardConfig const *boardConfig = finder.getBoardConfig(userConfig.board()); if (!boardConfig) { boardConfig = finder.searchBoardConfig(); if (!boardConfig) { @@ -69,8 +80,8 @@ void setup() { while (true) ; } else { - userConfig.board = boardConfig->Name; - confmg.writeConfiguration(userConfig); + userConfig.board.setValue(boardConfig->Name); + fact.saveConfig(config_filename); logPrintlnI("will restart board now!"); ESP.restart(); } @@ -96,10 +107,12 @@ void setup() { LoRaSystem.setBoardConfig(boardConfig); LoRaSystem.setUserConfig(&userConfig); LoRaSystem.getTaskManager().addTask(&displayTask); - LoRaSystem.getTaskManager().addTask(&modemTask); - LoRaSystem.getTaskManager().addTask(&routerTask); + if (userConfig.callsign() != "NOCALL-10") { + LoRaSystem.getTaskManager().addTask(&modemTask); + LoRaSystem.getTaskManager().addTask(&routerTask); + } - if (userConfig.aprs_is.active) { + if (userConfig.aprs_is.active()) { if (boardConfig->Type == eETH_BOARD) { LoRaSystem.getTaskManager().addAlwaysRunTask(ðTask); } else { @@ -107,32 +120,21 @@ void setup() { } LoRaSystem.getTaskManager().addTask(&otaTask); LoRaSystem.getTaskManager().addTask(&ntpTask); - if (userConfig.ftp.active) { + if (userConfig.ftp.active()) { LoRaSystem.getTaskManager().addTask(&ftpTask); } - LoRaSystem.getTaskManager().addTask(&aprsIsTask); + if (userConfig.callsign() != "NOCALL-10") { + LoRaSystem.getTaskManager().addTask(&aprsIsTask); + } } LoRaSystem.getTaskManager().setup(LoRaSystem); LoRaSystem.getDisplay().showSpashScreen("LoRa APRS iGate", VERSION); - if (userConfig.callsign == "NOCALL-10") { - logPrintlnE("You have to change your settings in 'data/is-cfg.json' and upload it via \"Upload File System image\"!"); - LoRaSystem.getDisplay().showStatusScreen("ERROR", "You have to change your settings in 'data/is-cfg.json' and upload it via \"Upload File System image\"!"); - while (true) - ; - } - if ((!userConfig.aprs_is.active) && !(userConfig.digi.active)) { - logPrintlnE("No mode selected (iGate or Digi)! You have to activate one of iGate or Digi."); - LoRaSystem.getDisplay().showStatusScreen("ERROR", "No mode selected (iGate or Digi)! You have to activate one of iGate or Digi."); - while (true) - ; - } - - if (userConfig.display.overwritePin != 0) { - pinMode(userConfig.display.overwritePin, INPUT); - pinMode(userConfig.display.overwritePin, INPUT_PULLUP); + if (userConfig.display.overwritePin() != 0) { + pinMode(userConfig.display.overwritePin(), INPUT); + pinMode(userConfig.display.overwritePin(), INPUT_PULLUP); } delay(5000); @@ -141,6 +143,17 @@ void setup() { void loop() { LoRaSystem.getTaskManager().loop(LoRaSystem); + if (html.wasSaved()) { + fact.saveConfig(config_filename); + ESP.restart(); + } + + // we can start the http server just when we are connected to something + static bool httpServerInitDone = false; + if (LoRaSystem.isWifiEthConnected() && !httpServerInitDone) { + server.begin(); + httpServerInitDone = true; + } } String create_lat_aprs(double lat) { diff --git a/src/TaskAprsIs.cpp b/src/TaskAprsIs.cpp index b96b06e..e4879af 100644 --- a/src/TaskAprsIs.cpp +++ b/src/TaskAprsIs.cpp @@ -2,7 +2,7 @@ #include "Task.h" #include "TaskAprsIs.h" -#include "project_configuration.h" +#include "configuration.h" AprsIsTask::AprsIsTask(TaskQueue> &toAprsIs) : Task(TASK_APRS_IS, TaskAprsIs), _toAprsIs(toAprsIs) { } @@ -11,7 +11,7 @@ AprsIsTask::~AprsIsTask() { } bool AprsIsTask::setup(System &system) { - _aprs_is.setup(system.getUserConfig()->callsign, system.getUserConfig()->aprs_is.passcode, "ESP32-APRS-IS", "0.2"); + _aprs_is.setup(system.getUserConfig()->callsign(), system.getUserConfig()->aprs_is.passcode(), "ESP32-APRS-IS", "0.2"); return true; } @@ -42,10 +42,10 @@ bool AprsIsTask::loop(System &system) { bool AprsIsTask::connect(const System &system) { logPrintI("connecting to APRS-IS server: "); - logPrintI(system.getUserConfig()->aprs_is.server); + logPrintI(system.getUserConfig()->aprs_is.server()); logPrintI(" on port: "); - logPrintlnI(String(system.getUserConfig()->aprs_is.port)); - if (!_aprs_is.connect(system.getUserConfig()->aprs_is.server, system.getUserConfig()->aprs_is.port)) { + logPrintlnI(String(system.getUserConfig()->aprs_is.port())); + if (!_aprs_is.connect(system.getUserConfig()->aprs_is.server(), system.getUserConfig()->aprs_is.port())) { logPrintlnE("Connection failed."); return false; } diff --git a/src/TaskDisplay.cpp b/src/TaskDisplay.cpp index bfe6d0b..35ad69f 100644 --- a/src/TaskDisplay.cpp +++ b/src/TaskDisplay.cpp @@ -1,7 +1,7 @@ #include #include "TaskDisplay.h" -#include "project_configuration.h" +#include "configuration.h" DisplayTask::DisplayTask() : Task("DisplayTask", 0) { } @@ -11,16 +11,16 @@ DisplayTask::~DisplayTask() { bool DisplayTask::setup(System &system) { system.getDisplay().setup(system.getBoardConfig()); - if (system.getUserConfig()->display.turn180) { + if (system.getUserConfig()->display.turn180()) { system.getDisplay().turn180(); } std::shared_ptr statusFrame = std::shared_ptr(new StatusFrame(system.getTaskManager().getTasks())); system.getDisplay().setStatusFrame(statusFrame); - if (!system.getUserConfig()->display.alwaysOn) { + if (!system.getUserConfig()->display.alwaysOn()) { system.getDisplay().activateDisplaySaveMode(); - system.getDisplay().setDisplaySaveTimeout(system.getUserConfig()->display.timeout); + system.getDisplay().setDisplaySaveTimeout(system.getUserConfig()->display.timeout()); } - _stateInfo = system.getUserConfig()->callsign; + _stateInfo = system.getUserConfig()->callsign(); return true; } diff --git a/src/TaskFTP.cpp b/src/TaskFTP.cpp index d9615cf..75f3bc7 100644 --- a/src/TaskFTP.cpp +++ b/src/TaskFTP.cpp @@ -4,7 +4,7 @@ #include "Task.h" #include "TaskFTP.h" -#include "project_configuration.h" +#include "configuration.h" FTPTask::FTPTask() : Task(TASK_FTP, TaskFtp), _beginCalled(false) { } @@ -13,11 +13,14 @@ FTPTask::~FTPTask() { } bool FTPTask::setup(System &system) { - for (Configuration::Ftp::User user : system.getUserConfig()->ftp.users) { + /*for (Configuration::Ftp::User user : system.getUserConfig()->ftp.users) { logPrintD("Adding user to FTP Server: "); logPrintlnD(user.name); _ftpServer.addUser(user.name, user.password); - } + }*/ + logPrintD("Adding user to FTP Server: "); + logPrintlnD(system.getUserConfig()->ftp.name()); + _ftpServer.addUser(system.getUserConfig()->ftp.name(), system.getUserConfig()->ftp.password()); _ftpServer.addFilesystem("SPIFFS", &SPIFFS); _stateInfo = "waiting"; return true; diff --git a/src/TaskModem.cpp b/src/TaskModem.cpp index 7dad353..25ca787 100644 --- a/src/TaskModem.cpp +++ b/src/TaskModem.cpp @@ -5,7 +5,7 @@ #include "Task.h" #include "TaskAprsIs.h" #include "TaskModem.h" -#include "project_configuration.h" +#include "configuration.h" ModemTask::ModemTask(TaskQueue> &fromModem, TaskQueue> &toModem) : Task(TASK_MODEM, TaskModem), _lora_aprs(), _fromModem(fromModem), _toModem(toModem) { } @@ -16,19 +16,19 @@ ModemTask::~ModemTask() { bool ModemTask::setup(System &system) { SPI.begin(system.getBoardConfig()->LoraSck, system.getBoardConfig()->LoraMiso, system.getBoardConfig()->LoraMosi, system.getBoardConfig()->LoraCS); _lora_aprs.setPins(system.getBoardConfig()->LoraCS, system.getBoardConfig()->LoraReset, system.getBoardConfig()->LoraIRQ); - if (!_lora_aprs.begin(system.getUserConfig()->lora.frequencyRx)) { + if (!_lora_aprs.begin(system.getUserConfig()->lora.frequencyRx())) { logPrintlnE("Starting LoRa failed!"); _stateInfo = "LoRa-Modem failed"; _state = Error; while (true) ; } - _lora_aprs.setRxFrequency(system.getUserConfig()->lora.frequencyRx); - _lora_aprs.setTxFrequency(system.getUserConfig()->lora.frequencyTx); - _lora_aprs.setTxPower(system.getUserConfig()->lora.power); - _lora_aprs.setSpreadingFactor(system.getUserConfig()->lora.spreadingFactor); - _lora_aprs.setSignalBandwidth(system.getUserConfig()->lora.signalBandwidth); - _lora_aprs.setCodingRate4(system.getUserConfig()->lora.codingRate4); + _lora_aprs.setRxFrequency(system.getUserConfig()->lora.frequencyRx()); + _lora_aprs.setTxFrequency(system.getUserConfig()->lora.frequencyTx()); + _lora_aprs.setTxPower(system.getUserConfig()->lora.power()); + _lora_aprs.setSpreadingFactor(system.getUserConfig()->lora.spreadingFactor()); + _lora_aprs.setSignalBandwidth(system.getUserConfig()->lora.signalBandwidth()); + _lora_aprs.setCodingRate4(system.getUserConfig()->lora.codingRate4()); _lora_aprs.enableCrc(); _stateInfo = ""; diff --git a/src/TaskNTP.cpp b/src/TaskNTP.cpp index 14b3808..003af98 100644 --- a/src/TaskNTP.cpp +++ b/src/TaskNTP.cpp @@ -4,7 +4,7 @@ #include "Task.h" #include "TaskNTP.h" -#include "project_configuration.h" +#include "configuration.h" NTPTask::NTPTask() : Task(TASK_NTP, TaskNtp), _beginCalled(false) { } @@ -13,7 +13,7 @@ NTPTask::~NTPTask() { } bool NTPTask::setup(System &system) { - _ntpClient.setPoolServerName(system.getUserConfig()->ntpServer.c_str()); + _ntpClient.setPoolServerName(system.getUserConfig()->ntpServer().c_str()); return true; } diff --git a/src/TaskOTA.cpp b/src/TaskOTA.cpp index 6b6348c..487f021 100644 --- a/src/TaskOTA.cpp +++ b/src/TaskOTA.cpp @@ -2,7 +2,7 @@ #include "Task.h" #include "TaskOTA.h" -#include "project_configuration.h" +#include "configuration.h" OTATask::OTATask() : Task(TASK_OTA, TaskOta), _beginCalled(false) { } @@ -43,7 +43,7 @@ bool OTATask::setup(System &system) { else if (error == OTA_END_ERROR) logPrintlnE("End Failed"); }); - _ota.setHostname(system.getUserConfig()->callsign.c_str()); + _ota.setHostname(system.getUserConfig()->callsign().c_str()); _stateInfo = ""; return true; } diff --git a/src/TaskRouter.cpp b/src/TaskRouter.cpp index 210ed7e..74bb6a1 100644 --- a/src/TaskRouter.cpp +++ b/src/TaskRouter.cpp @@ -4,7 +4,7 @@ #include "Task.h" #include "TaskRouter.h" -#include "project_configuration.h" +#include "configuration.h" String create_lat_aprs(double lat); String create_long_aprs(double lng); @@ -17,14 +17,14 @@ RouterTask::~RouterTask() { bool RouterTask::setup(System &system) { // setup beacon - _beacon_timer.setTimeout(system.getUserConfig()->beacon.timeout * 60 * 1000); + _beacon_timer.setTimeout(system.getUserConfig()->beacon.timeout() * 60 * 1000); _beaconMsg = std::shared_ptr(new APRSMessage()); - _beaconMsg->setSource(system.getUserConfig()->callsign); + _beaconMsg->setSource(system.getUserConfig()->callsign()); _beaconMsg->setDestination("APLG01"); - String lat = create_lat_aprs(system.getUserConfig()->beacon.positionLatitude); - String lng = create_long_aprs(system.getUserConfig()->beacon.positionLongitude); - _beaconMsg->getBody()->setData(String("=") + lat + "L" + lng + "&" + system.getUserConfig()->beacon.message); + String lat = create_lat_aprs(system.getUserConfig()->beacon.positionLatitude()); + String lng = create_long_aprs(system.getUserConfig()->beacon.positionLongitude()); + _beaconMsg->getBody()->setData(String("=") + lat + "L" + lng + "&" + system.getUserConfig()->beacon.message()); return true; } @@ -34,7 +34,7 @@ bool RouterTask::loop(System &system) { if (!_fromModem.empty()) { std::shared_ptr modemMsg = _fromModem.getElement(); - if (system.getUserConfig()->aprs_is.active && modemMsg->getSource() != system.getUserConfig()->callsign) { + if (system.getUserConfig()->aprs_is.active() && modemMsg->getSource() != system.getUserConfig()->callsign()) { std::shared_ptr aprsIsMsg = std::make_shared(*modemMsg); String path = aprsIsMsg->getPath(); @@ -43,7 +43,7 @@ bool RouterTask::loop(System &system) { path += ","; } - aprsIsMsg->setPath(path + "qAR," + system.getUserConfig()->callsign); + aprsIsMsg->setPath(path + "qAR," + system.getUserConfig()->callsign()); logPrintD("APRS-IS: "); logPrintlnD(aprsIsMsg->toString()); @@ -52,21 +52,21 @@ bool RouterTask::loop(System &system) { logPrintlnD("APRS-IS: no forward => RFonly"); } } else { - if (!system.getUserConfig()->aprs_is.active) + if (!system.getUserConfig()->aprs_is.active()) logPrintlnD("APRS-IS: disabled"); - if (modemMsg->getSource() == system.getUserConfig()->callsign) + if (modemMsg->getSource() == system.getUserConfig()->callsign()) logPrintlnD("APRS-IS: no forward => own packet received"); } - if (system.getUserConfig()->digi.active && modemMsg->getSource() != system.getUserConfig()->callsign) { + if (system.getUserConfig()->digi.active() && modemMsg->getSource() != system.getUserConfig()->callsign()) { std::shared_ptr digiMsg = std::make_shared(*modemMsg); String path = digiMsg->getPath(); // simple loop check - if (path.indexOf("WIDE1-1") >= 0 || path.indexOf(system.getUserConfig()->callsign) == -1) { + if (path.indexOf("WIDE1-1") >= 0 || path.indexOf(system.getUserConfig()->callsign()) == -1) { // fixme - digiMsg->setPath(system.getUserConfig()->callsign + "*"); + digiMsg->setPath(system.getUserConfig()->callsign() + "*"); logPrintD("DIGI: "); logPrintlnD(digiMsg->toString()); @@ -81,10 +81,10 @@ bool RouterTask::loop(System &system) { logPrintD("[" + timeString() + "] "); logPrintlnD(_beaconMsg->encode()); - if (system.getUserConfig()->aprs_is.active) + if (system.getUserConfig()->aprs_is.active()) _toAprsIs.addElement(_beaconMsg); - if (system.getUserConfig()->digi.beacon) { + if (system.getUserConfig()->digi.beacon()) { _toModem.addElement(_beaconMsg); } diff --git a/src/TaskWifi.cpp b/src/TaskWifi.cpp index 408a0fd..4449755 100644 --- a/src/TaskWifi.cpp +++ b/src/TaskWifi.cpp @@ -4,9 +4,9 @@ #include "Task.h" #include "TaskEth.h" #include "TaskWifi.h" -#include "project_configuration.h" +#include "configuration.h" -WifiTask::WifiTask() : Task(TASK_WIFI, TaskWifi), _oldWifiStatus(WL_IDLE_STATUS) { +WifiTask::WifiTask() : Task(TASK_WIFI, TaskWifi), _oldWifiStatus(WL_IDLE_STATUS), _isAPMode(false) { } WifiTask::~WifiTask() { @@ -14,16 +14,27 @@ WifiTask::~WifiTask() { bool WifiTask::setup(System &system) { WiFi.onEvent(WiFiEvent); - WiFi.setHostname(system.getUserConfig()->callsign.c_str()); - for (Configuration::Wifi::AP ap : system.getUserConfig()->wifi.APs) { + WiFi.setHostname(system.getUserConfig()->callsign().c_str()); + if (system.getUserConfig()->wifi.ssid() == "" && system.getUserConfig()->wifi.password() == "") { + // ssid and password not set... + WiFi.softAP("LoRa APRS iGate", "LoRaAPRS"); + IPAddress IP = WiFi.softAPIP(); + logPrintD("AP IP address: "); + logPrintlnD(IP.toString()); + _isAPMode = true; + system.connectedViaWifiEth(true); + } else { logPrintD("Looking for AP: "); - logPrintlnD(ap.SSID); - _wiFiMulti.addAP(ap.SSID.c_str(), ap.password.c_str()); + logPrintlnD(system.getUserConfig()->wifi.ssid()); + _wiFiMulti.addAP(system.getUserConfig()->wifi.ssid().c_str(), system.getUserConfig()->wifi.password().c_str()); } return true; } bool WifiTask::loop(System &system) { + if (_isAPMode) { + return false; + } const uint8_t wifi_status = _wiFiMulti.run(); if (wifi_status != WL_CONNECTED) { system.connectedViaWifiEth(false); diff --git a/src/TaskWifi.h b/src/TaskWifi.h index 8196629..2f1d21c 100644 --- a/src/TaskWifi.h +++ b/src/TaskWifi.h @@ -15,6 +15,7 @@ public: private: WiFiMulti _wiFiMulti; uint8_t _oldWifiStatus; + bool _isAPMode; }; #endif diff --git a/src/configuration.cpp b/src/configuration.cpp new file mode 100644 index 0000000..fabd39a --- /dev/null +++ b/src/configuration.cpp @@ -0,0 +1,35 @@ +#include "configuration.h" + +ConfigPage page("config", "LoRa APRS iGate Config", "This is the configuration page for the LoRa APRS iGate."); + +ConfigSection sGeneral(page, "general", "General", "General configuration"); +ConfigSection sWifi(page, "wifi_aps", "WiFi APs", "Configuration for the WiFi access points."); +ConfigSection sBeacon(page, "beacon", "LoRa beacon", "Configuration for the LoRa beacon."); +ConfigSection sAprsIs(page, "aprs_is", "APRS IS", "Configuration for the APRS IS upload."); +ConfigSection sDigi(page, "digi", "Digi", "Configuration for the APRS digi."); +ConfigSection sLora(page, "lora", "Lora", "Configuration for the Lora interface."); +ConfigSection sDisplay(page, "display", "Display", "Configuration for the Display."); +ConfigSection sFtp(page, "ftp", "FTP", "Configuration for the FTP server."); + +Configuration::Wifi::Wifi() : ssid(sWifi, "wifi_ssid", "SSID", "WiFi SSID", ""), password(sWifi, "wifi_password", "Password", "WiFi password", "") { +} + +Configuration::Beacon::Beacon() : message(sBeacon, "message", "Message", "APRS message to send", "LoRa iGATE & Digi, Info: github.com/peterus/LoRa_APRS_iGate"), positionLatitude(sBeacon, "pos_lat", "Position Latitude", "The position of the iGate (latitude)", 0.0, 6), positionLongitude(sBeacon, "pos_long", "Position Longitude", "The position of the iGate (longitude)", 0.0, 6), timeout(sBeacon, "timeout", "Timeout", "The timeout to send the message (second)", 15) { +} + +Configuration::APRS_IS::APRS_IS() : active(sAprsIs, "aprs_active", "active", "Activate upload to APRS IS", true), passcode(sAprsIs, "passcode", "Passcode", "The APRS IS passcode", ""), server(sAprsIs, "server", "Server", "The APRS IS server", "euro.aprs2.net"), port(sAprsIs, "port", "Port", "APRS IS port", 14580) { +} + +Configuration::Digi::Digi() : active(sDigi, "digi_active", "active", "Activate digi mode", false), beacon(sDigi, "digi_beacon", "beacon", "Activate digi beacon", true) { +} + +Configuration::LoRa::LoRa() : frequencyRx(sLora, "frequency_rx", "Frequency RX", "The RX frequency", 433775000), frequencyTx(sLora, "frequency_tx", "Frequency TX", "The TX frequency", 433775000), power(sLora, "power", "Power", "power in dBm", 20), spreadingFactor(sLora, "spreading_factor", "spreading factor", "", 12), signalBandwidth(sLora, "signal_bandwidth", "signal bandwidth", "", 125000), codingRate4(sLora, "coding_rate4", "coding rate 4", "", 5) { +} + +Configuration::Display::Display() : alwaysOn(sDisplay, "display_always_on", "always on", "", true), timeout(sDisplay, "display_timeout", "Timeout", "", 10), overwritePin(sDisplay, "display_overwrite_pin", "overwrite pin", "", 0), turn180(sDisplay, "display_turn180", "turn 180", "", true) { +} + +Configuration::Ftp::Ftp() : active(sFtp, "ftp_active", "active", "Activate ftp server", false), name(sFtp, "ftp_name", "Username", "FTP username", ""), password(sFtp, "ftp_password", "Password", "FTP password", "") { +} + +Configuration::Configuration() : callsign(sGeneral, "callsign", "Callsign", "your callsign", "NOCALL-10"), board(sGeneral, "board", "Board", "you don't need to change this!", ""), ntpServer(sGeneral, "ntp_server", "NTP Server", "", "pool.ntp.org"){}; diff --git a/src/configuration.h b/src/configuration.h new file mode 100644 index 0000000..053b215 --- /dev/null +++ b/src/configuration.h @@ -0,0 +1,83 @@ +#ifndef CONFIGURATION_H_ +#define CONFIGURATION_H_ + +#include + +extern ConfigPage page; + +class Configuration { +public: + class Wifi { + public: + Wifi(); + ConfigString ssid; + ConfigString password; + }; + + class Beacon { + public: + Beacon(); + ConfigString message; + ConfigDecimal positionLatitude; + ConfigDecimal positionLongitude; + ConfigInt timeout; + }; + + class APRS_IS { + public: + APRS_IS(); + ConfigBool active; + ConfigString passcode; + ConfigString server; + ConfigInt port; + }; + + class Digi { + public: + Digi(); + ConfigBool active; + ConfigBool beacon; + }; + + class LoRa { + public: + LoRa(); + ConfigInt frequencyRx; + ConfigInt frequencyTx; + ConfigInt power; + ConfigInt spreadingFactor; + ConfigInt signalBandwidth; + ConfigInt codingRate4; + }; + + class Display { + public: + Display(); + ConfigBool alwaysOn; + ConfigInt timeout; + ConfigInt overwritePin; + ConfigBool turn180; + }; + + class Ftp { + public: + Ftp(); + ConfigBool active; + ConfigString name; + ConfigString password; + }; + + Configuration(); + ConfigString callsign; + Wifi wifi; + Beacon beacon; + APRS_IS aprs_is; + Digi digi; + LoRa lora; + Display display; + Ftp ftp; + ConfigString board; + ConfigString ntpServer; +}; + +#endif diff --git a/src/project_configuration.cpp b/src/project_configuration.cpp deleted file mode 100644 index 4bce038..0000000 --- a/src/project_configuration.cpp +++ /dev/null @@ -1,102 +0,0 @@ -#include - -#include - -#include "project_configuration.h" - -void ProjectConfigurationManagement::readProjectConfiguration(DynamicJsonDocument &data, Configuration &conf) { - if (data.containsKey("callsign")) - conf.callsign = data["callsign"].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(); - conf.wifi.APs.push_back(ap); - } - 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.beacon.timeout = data["beacon"]["timeout"] | 15; - conf.aprs_is.active = data["aprs_is"]["active"] | true; - if (data.containsKey("aprs_is") && data["aprs_is"].containsKey("passcode")) - conf.aprs_is.passcode = data["aprs_is"]["passcode"].as(); - 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.digi.active = data["digi"]["active"] | false; - conf.digi.beacon = data["digi"]["beacon"] | false; - 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.display.turn180 = data["display"]["turn180"] | true; - - 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(); - 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); - } - if (data.containsKey("ntp_server")) - conf.ntpServer = data["ntp_server"].as(); - - if (data.containsKey("board")) - conf.board = data["board"].as(); -} - -void ProjectConfigurationManagement::writeProjectConfiguration(Configuration &conf, DynamicJsonDocument &data) { - data["callsign"] = conf.callsign; - 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; - } - data["beacon"]["message"] = conf.beacon.message; - data["beacon"]["position"]["latitude"] = conf.beacon.positionLatitude; - data["beacon"]["position"]["longitude"] = conf.beacon.positionLongitude; - data["beacon"]["timeout"] = conf.beacon.timeout; - data["aprs_is"]["active"] = conf.aprs_is.active; - data["aprs_is"]["passcode"] = conf.aprs_is.passcode; - data["aprs_is"]["server"] = conf.aprs_is.server; - data["aprs_is"]["port"] = conf.aprs_is.port; - data["digi"]["active"] = conf.digi.active; - data["digi"]["beacon"] = conf.digi.beacon; - 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["display"]["turn180"] = conf.display.turn180; - 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; - } - data["ntp_server"] = conf.ntpServer; - - data["board"] = conf.board; -} diff --git a/src/project_configuration.h b/src/project_configuration.h deleted file mode 100644 index e1e1686..0000000 --- a/src/project_configuration.h +++ /dev/null @@ -1,119 +0,0 @@ -#ifndef PROJECT_CONFIGURATION_H_ -#define PROJECT_CONFIGURATION_H_ - -#include -#include - -class Configuration { -public: - class Wifi { - public: - class AP { - public: - String SSID; - String password; - }; - - Wifi() { - } - - std::list APs; - }; - - class Beacon { - public: - Beacon() : message("LoRa iGATE & Digi, Info: github.com/peterus/LoRa_APRS_iGate"), positionLatitude(0.0), positionLongitude(0.0), timeout(15) { - } - - String message; - double positionLatitude; - double positionLongitude; - int timeout; - }; - - class APRS_IS { - public: - APRS_IS() : active(true), server("euro.aprs2.net"), port(14580) { - } - - bool active; - String passcode; - String server; - int port; - }; - - class Digi { - public: - Digi() : active(false), beacon(true) { - } - - bool active; - bool beacon; - }; - - class LoRa { - public: - LoRa() : frequencyRx(433775000), frequencyTx(433775000), power(20), spreadingFactor(12), signalBandwidth(125000), codingRate4(5) { - } - - long frequencyRx; - long frequencyTx; - int power; - int spreadingFactor; - long signalBandwidth; - int codingRate4; - }; - - class Display { - public: - Display() : alwaysOn(true), timeout(10), overwritePin(0), turn180(true) { - } - - bool alwaysOn; - int timeout; - int overwritePin; - bool turn180; - }; - - class Ftp { - public: - class User { - public: - String name; - String password; - }; - - Ftp() : active(false) { - } - - bool active; - std::list users; - }; - - Configuration() : callsign("NOCALL-10"), board(""), ntpServer("pool.ntp.org"){}; - - String callsign; - Wifi wifi; - Beacon beacon; - APRS_IS aprs_is; - Digi digi; - LoRa lora; - Display display; - Ftp ftp; - String board; - String ntpServer; -}; - -class ProjectConfigurationManagement : public ConfigurationManagement { -public: - explicit ProjectConfigurationManagement() : ConfigurationManagement("/is-cfg.json") { - } - virtual ~ProjectConfigurationManagement() { - } - -private: - virtual void readProjectConfiguration(DynamicJsonDocument &data, Configuration &conf) override; - virtual void writeProjectConfiguration(Configuration &conf, DynamicJsonDocument &data) override; -}; - -#endif