diff --git a/.github/workflows/build_check.yml b/.github/workflows/build_check.yml index 0cbe379..542fe65 100644 --- a/.github/workflows/build_check.yml +++ b/.github/workflows/build_check.yml @@ -1,56 +1,22 @@ -name: push pull checks +name: Integreation Tests on: [push, pull_request] jobs: - #check: - # runs-on: ubuntu-latest - # steps: - # - uses: actions/checkout@v2 - # - name: Cache pip - # uses: actions/cache@v2 - # with: - # path: ~/.cache/pip - # key: ${{ runner.os }}-pip-${{ hashFiles('**/requirements.txt') }} - # restore-keys: ${{ runner.os }}-pip- - # - name: Cache PlatformIO - # uses: actions/cache@v2 - # with: - # path: ~/.platformio - # key: ${{ runner.os }}-${{ hashFiles('**/lockfiles') }} - # - name: Set up Python - # uses: actions/setup-python@v2 - # - name: Install PlatformIO - # run: | - # python -m pip install --upgrade pip - # pip install --upgrade platformio - # - name: Run PlatformIO Check - # run: platformio check --fail-on-defect low --fail-on-defect medium --fail-on-defect high - build: + name: Compile Firmware runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 - - name: Cache pip - uses: actions/cache@v2 - with: - path: ~/.cache/pip - key: ${{ runner.os }}-pip-${{ hashFiles('**/requirements.txt') }} - restore-keys: ${{ runner.os }}-pip- - - name: Cache PlatformIO - uses: actions/cache@v2 - with: - path: ~/.platformio - key: ${{ runner.os }}-${{ hashFiles('**/lockfiles') }} + - name: Checkout code + uses: actions/checkout@v2 - name: Set up Python uses: actions/setup-python@v2 - name: Install PlatformIO - run: | - python -m pip install --upgrade pip - pip install --upgrade platformio + run: python -m pip install --upgrade pip platformio - name: Run PlatformIO CI run: platformio run - - uses: actions/upload-artifact@v2 + - name: Upload artifacts + uses: actions/upload-artifact@v2 with: name: firmware path: .pio/build/lora_board/firmware.bin @@ -72,10 +38,29 @@ jobs: - 'lib/System' #- 'lib/TimeLib' steps: - - uses: actions/checkout@v2 + - name: Checkout code + uses: actions/checkout@v2 - name: Run clang-format style check for C/C++ programs. uses: jidicula/clang-format-action@v3.2.0 with: clang-format-version: '11' check-path: ${{ matrix.path }} + cppcheck: + name: Run cppcheck + runs-on: ubuntu-latest + env: + CPPCHECK_ARGS: --enable=all --std=c++14 --inline-suppr -I lib/BoardFinder -I lib/ConfigurationManagement -I lib/Display -I lib/LoRa -I lib/LoRa_APRS -I lib/NTPClient -I lib/PowerManagement -I lib/System -I lib/TimeLib -i lib/Display -i lib/LoRa -i lib/NTPClient -i lib/TimeLib src lib + steps: + - name: checkout code + uses: actions/checkout@v2 + - run: docker pull facthunder/cppcheck:latest + - name: Run cppcheck and print result + run: docker run --rm -v ${PWD}:/src facthunder/cppcheck:latest /bin/bash -c "cppcheck $CPPCHECK_ARGS" + - name: Run cppcheck and create html + run: docker run --rm -v ${PWD}:/src facthunder/cppcheck:latest /bin/bash -c "cppcheck --xml $CPPCHECK_ARGS 2> report.xml && cppcheck-htmlreport --file=report.xml --report-dir=output" + - name: Upload report + uses: actions/upload-artifact@v1 + with: + name: Cppcheck Report + path: output diff --git a/.gitignore b/.gitignore index 89cc49c..9f19284 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,5 @@ .vscode/c_cpp_properties.json .vscode/launch.json .vscode/ipch +report.xml +output diff --git a/README.md b/README.md index 93c25c1..bc8bd22 100644 --- a/README.md +++ b/README.md @@ -10,10 +10,12 @@ Try it out and be part of the APRS network. ## Blog posts and Youtube videos from other Hams +* [Manuel Lausmann - iGate & Tracker](https://www.youtube.com/watch?v=-KdFQEaNC1k) (youtube - german) 04.06.2021 +* [Manuel Lausmann - Installationsanleitung als PDF](http://mala-one.de/Lora-APRS/) (PDF - german) 04.06.2021 * [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 +* [Manuel Lausmann - iGate](https://www.youtube.com/watch?v=C7hfVe32pXs) (youtube - german - OLD) 06.11.2020 +* [Manuel Lausmann - Tracker](https://www.youtube.com/watch?v=clIlTEFbWLk) (youtube - german - OLD) 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. diff --git a/data/is-cfg.json b/data/is-cfg.json index c84a3f5..3d536bb 100644 --- a/data/is-cfg.json +++ b/data/is-cfg.json @@ -17,10 +17,15 @@ "timeout": 15 }, "aprs_is": { + "active": true, "passcode": "", "server": "euro.aprs2.net", "port": 14580 }, + "digi": { + "active": false, + "beacon": false + }, "lora": { "frequency_rx": 433775000, "frequency_tx": 433775000, diff --git a/lib/APRS-IS/APRS-IS.cpp b/lib/APRS-IS/APRS-IS.cpp new file mode 100644 index 0000000..6988ac9 --- /dev/null +++ b/lib/APRS-IS/APRS-IS.cpp @@ -0,0 +1,88 @@ +#include "APRS-IS.h" +#include + +void APRS_IS::setup(const String &user, const String &passcode, const String &tool_name, const String &version) { + _user = user; + _passcode = passcode; + _tool_name = tool_name; + _version = version; +} + +bool APRS_IS::connect(const String &server, const int port) { + const String login = "user " + _user + " pass " + _passcode + " vers " + _tool_name + " " + _version + "\n\r"; + return _connect(server, port, login); +} + +bool APRS_IS::connect(const String &server, const int port, const String &filter) { + const String login = "user " + _user + " pass " + _passcode + " vers " + _tool_name + " " + _version + " filter " + filter + "\n\r"; + return _connect(server, port, login); +} + +bool APRS_IS::_connect(const String &server, const int port, const String &login_line) { + if (!_client.connect(server.c_str(), port)) { + logPrintlnE("Something went wrong on connecting! Is the server reachable?"); + return false; + } + sendMessage(login_line); + while (true) { + String line = _client.readStringUntil('\n'); + if (line.indexOf("logresp") != -1) { + if (line.indexOf("unverified") == -1) { + return true; + } else { + logPrintlnE("User can not be verified with passcode!"); + return false; + } + } + } + return true; +} + +bool APRS_IS::connected() { + return _client.connected(); +} + +bool APRS_IS::sendMessage(const String &message) { + if (!connected()) { + return false; + } + _client.println(message); + return true; +} + +bool APRS_IS::sendMessage(const std::shared_ptr message) { + if (!connected()) { + return false; + } + _client.println(message->encode() + "\n"); + return true; +} + +int APRS_IS::available() { + return _client.available(); +} + +String APRS_IS::getMessage() { + String line; + if (_client.available() > 0) { + line = _client.readStringUntil('\n'); + } + return line; +} + +std::shared_ptr APRS_IS::getAPRSMessage() { + String line; + if (_client.available() > 0) { + line = _client.readStringUntil('\n'); + } + if (line.startsWith("#")) { + logPrintlnD(line); + return 0; + } + if (line.length() == 0) { + return 0; + } + std::shared_ptr msg = std::shared_ptr(new APRSMessage()); + msg->decode(line); + return msg; +} diff --git a/lib/APRS-IS/APRS-IS.h b/lib/APRS-IS/APRS-IS.h new file mode 100644 index 0000000..00d27ca --- /dev/null +++ b/lib/APRS-IS/APRS-IS.h @@ -0,0 +1,34 @@ + +#ifndef APRS_IS_Lib_h_ +#define APRS_IS_Lib_h_ + +#include +#include + +class APRS_IS { +public: + void setup(const String &user, const String &passcode, const String &tool_name, const String &version); + + bool connect(const String &server, const int port); + bool connect(const String &server, const int port, const String &filter); + bool connected(); + + bool sendMessage(const String &message); + bool sendMessage(const std::shared_ptr message); + + int available(); + + String getMessage(); + std::shared_ptr getAPRSMessage(); + +private: + String _user; + String _passcode; + String _tool_name; + String _version; + WiFiClient _client; + + bool _connect(const String &server, const int port, const String &login_line); +}; + +#endif diff --git a/lib/BoardFinder/BoardFinder.cpp b/lib/BoardFinder/BoardFinder.cpp index 57d3d28..0e076e0 100644 --- a/lib/BoardFinder/BoardFinder.cpp +++ b/lib/BoardFinder/BoardFinder.cpp @@ -6,19 +6,18 @@ BoardConfig::BoardConfig(String name, BoardType type, uint8_t oledsda, uint8_t o : Name(name), Type(type), OledSda(oledsda), OledScl(oledscl), OledAddr(oledaddr), OledReset(oledreset), LoraSck(lorasck), LoraMiso(loramiso), LoraMosi(loramosi), LoraCS(loracs), LoraReset(lorareset), LoraIRQ(lorairq), needCheckPowerChip(needcheckpowerchip), powerCheckStatus(powercheckstatus) { } -BoardFinder::BoardFinder(std::list> &boardConfigs) : _boardConfigs(boardConfigs) { +BoardFinder::BoardFinder(const std::list &boardConfigs) : _boardConfigs(boardConfigs) { } -std::shared_ptr BoardFinder::searchBoardConfig() { +BoardConfig const *BoardFinder::searchBoardConfig() { logPrintlnI("looking for a board config."); logPrintlnI("searching for OLED..."); - for (std::shared_ptr boardconf : _boardConfigs) { + for (BoardConfig const *boardconf : _boardConfigs) { if (boardconf->needCheckPowerChip && checkPowerConfig(boardconf) == boardconf->powerCheckStatus) { PowerManagement powerManagement; - TwoWire wire(0); - wire.begin(boardconf->OledSda, boardconf->OledScl); - powerManagement.begin(wire); + Wire.begin(boardconf->OledSda, boardconf->OledScl); + powerManagement.begin(Wire); powerManagement.activateOLED(); } else if (boardconf->needCheckPowerChip) { continue; @@ -30,14 +29,13 @@ std::shared_ptr BoardFinder::searchBoardConfig() { } } - logPrintlnW("could not find OLED, will search for the modem now..."); + logPrintlnI("could not find OLED, will search for the modem now..."); - for (std::shared_ptr boardconf : _boardConfigs) { + for (BoardConfig const *boardconf : _boardConfigs) { if (boardconf->needCheckPowerChip && checkPowerConfig(boardconf) == boardconf->powerCheckStatus) { PowerManagement powerManagement; - TwoWire wire(0); - wire.begin(boardconf->OledSda, boardconf->OledScl); - powerManagement.begin(wire); + Wire.begin(boardconf->OledSda, boardconf->OledScl); + powerManagement.begin(Wire); powerManagement.activateLoRa(); } if (checkModemConfig(boardconf)) { @@ -47,13 +45,13 @@ std::shared_ptr BoardFinder::searchBoardConfig() { } } - logPrintlnW("could not find a board config!"); + logPrintlnE("could not find a board config!"); return 0; } -std::shared_ptr BoardFinder::getBoardConfig(String name) { - std::_List_iterator> elem = std::find_if(_boardConfigs.begin(), _boardConfigs.end(), [&](std::shared_ptr conf) { +BoardConfig const *BoardFinder::getBoardConfig(String name) { + std::_List_const_iterator elem = std::find_if(_boardConfigs.begin(), _boardConfigs.end(), [&](BoardConfig const *conf) { return conf->Name == name; }); if (elem == _boardConfigs.end()) { @@ -62,7 +60,7 @@ std::shared_ptr BoardFinder::getBoardConfig(String name) { return *elem; } -bool BoardFinder::checkOledConfig(std::shared_ptr boardConfig) { +bool BoardFinder::checkOledConfig(BoardConfig const *boardConfig) { if (boardConfig->OledReset > 0) { pinMode(boardConfig->OledReset, OUTPUT); digitalWrite(boardConfig->OledReset, HIGH); @@ -71,19 +69,18 @@ bool BoardFinder::checkOledConfig(std::shared_ptr boardConfig) { delay(10); digitalWrite(boardConfig->OledReset, HIGH); } - TwoWire wire(0); - if (!wire.begin(boardConfig->OledSda, boardConfig->OledScl)) { + if (!Wire.begin(boardConfig->OledSda, boardConfig->OledScl)) { logPrintlnW("issue with wire"); return false; } - wire.beginTransmission(boardConfig->OledAddr); - if (!wire.endTransmission()) { + Wire.beginTransmission(boardConfig->OledAddr); + if (!Wire.endTransmission()) { return true; } return false; } -bool BoardFinder::checkModemConfig(std::shared_ptr boardConfig) { +bool BoardFinder::checkModemConfig(BoardConfig const *boardConfig) { pinMode(boardConfig->LoraReset, OUTPUT); digitalWrite(boardConfig->LoraReset, LOW); delay(10); @@ -93,15 +90,14 @@ bool BoardFinder::checkModemConfig(std::shared_ptr boardConfig) { pinMode(boardConfig->LoraCS, OUTPUT); digitalWrite(boardConfig->LoraCS, HIGH); - SPIClass spi; - spi.begin(boardConfig->LoraSck, boardConfig->LoraMiso, boardConfig->LoraMosi, boardConfig->LoraCS); + SPI.begin(boardConfig->LoraSck, boardConfig->LoraMiso, boardConfig->LoraMosi, boardConfig->LoraCS); digitalWrite(boardConfig->LoraCS, LOW); - spi.beginTransaction(SPISettings(8E6, MSBFIRST, SPI_MODE0)); - spi.transfer(0x42); - uint8_t response = spi.transfer(0x00); - spi.endTransaction(); + SPI.beginTransaction(SPISettings(8E6, MSBFIRST, SPI_MODE0)); + SPI.transfer(0x42); + uint8_t response = SPI.transfer(0x00); + SPI.endTransaction(); digitalWrite(boardConfig->LoraCS, HIGH); @@ -111,19 +107,18 @@ bool BoardFinder::checkModemConfig(std::shared_ptr boardConfig) { return false; } -bool BoardFinder::checkPowerConfig(std::shared_ptr boardConfig) { - TwoWire wire(0); - if (!wire.begin(boardConfig->OledSda, boardConfig->OledScl)) { +bool BoardFinder::checkPowerConfig(BoardConfig const *boardConfig) { + if (!Wire.begin(boardConfig->OledSda, boardConfig->OledScl)) { logPrintlnW("issue with wire"); return false; } - wire.beginTransmission(0x34); - wire.write(0x03); - wire.endTransmission(); + Wire.beginTransmission(0x34); + Wire.write(0x03); + Wire.endTransmission(); - wire.requestFrom(0x34, 1); - int response = wire.read(); - wire.endTransmission(); + Wire.requestFrom(0x34, 1); + int response = Wire.read(); + Wire.endTransmission(); logPrintlnD(String(response)); if (response == 0x03) { @@ -133,3 +128,14 @@ bool BoardFinder::checkPowerConfig(std::shared_ptr boardConfig) { logPrintlnD("power chip NOT found"); return false; } + +// clang-format off +BoardConfig TTGO_LORA32_V1 ("TTGO_LORA32_V1", eTTGO_LORA32_V1, 4, 15, 0x3C, 0, 5, 19, 27, 18, 14, 26); +BoardConfig TTGO_LORA32_V2 ("TTGO_LORA32_V2", eTTGO_LORA32_V2, 21, 22, 0x3C, 0, 5, 19, 27, 18, 14, 26, true); +BoardConfig TTGO_T_Beam_V0_7 ("TTGO_T_Beam_V0_7", eTTGO_T_Beam_V0_7, 21, 22, 0x3C, 0, 5, 19, 27, 18, 14, 26, true); +BoardConfig TTGO_T_Beam_V1_0 ("TTGO_T_Beam_V1_0", eTTGO_T_Beam_V1_0, 21, 22, 0x3C, 0, 5, 19, 27, 18, 14, 26, true, true); +BoardConfig ETH_BOARD ("ETH_BOARD", eETH_BOARD, 33, 32, 0x3C, 0, 14, 2, 15, 12, 4, 36); +BoardConfig TRACKERD ("TRACKERD", eTRACKERD, 5, 4, 0x3C, 0, 18, 19, 23, 16, 14, 26); +BoardConfig HELTEC_WIFI_LORA_32_V1("HELTEC_WIFI_LORA_32_V1", eHELTEC_WIFI_LORA_32_V1, 4, 15, 0x3C, 16, 5, 19, 27, 18, 14, 26); +BoardConfig HELTEC_WIFI_LORA_32_V2("HELTEC_WIFI_LORA_32_V2", eHELTEC_WIFI_LORA_32_V2, 4, 15, 0x3C, 16, 5, 19, 27, 18, 14, 26); +// clang-format on diff --git a/lib/BoardFinder/BoardFinder.h b/lib/BoardFinder/BoardFinder.h index 04dc8a4..142de6d 100644 --- a/lib/BoardFinder/BoardFinder.h +++ b/lib/BoardFinder/BoardFinder.h @@ -45,18 +45,27 @@ public: class BoardFinder { public: - explicit BoardFinder(std::list> &boardConfigs); + explicit BoardFinder(const std::list &boardConfigs); - std::shared_ptr searchBoardConfig(); + BoardConfig const *searchBoardConfig(); - std::shared_ptr getBoardConfig(String name); + BoardConfig const *getBoardConfig(String name); private: - std::list> _boardConfigs; + const std::list &_boardConfigs; - bool checkOledConfig(std::shared_ptr boardConfig); - bool checkModemConfig(std::shared_ptr boardConfig); - bool checkPowerConfig(std::shared_ptr boardConfig); + bool checkOledConfig(BoardConfig const *boardConfig); + bool checkModemConfig(BoardConfig const *boardConfig); + bool checkPowerConfig(BoardConfig const *boardConfig); }; +extern BoardConfig TTGO_LORA32_V1; +extern BoardConfig TTGO_LORA32_V2; +extern BoardConfig TTGO_T_Beam_V0_7; +extern BoardConfig TTGO_T_Beam_V1_0; +extern BoardConfig ETH_BOARD; +extern BoardConfig TRACKERD; +extern BoardConfig HELTEC_WIFI_LORA_32_V1; +extern BoardConfig HELTEC_WIFI_LORA_32_V2; + #endif diff --git a/lib/ConfigurationManagement/configuration.cpp b/lib/ConfigurationManagement/configuration.cpp index 7a35fdc..5f50550 100644 --- a/lib/ConfigurationManagement/configuration.cpp +++ b/lib/ConfigurationManagement/configuration.cpp @@ -4,7 +4,7 @@ ConfigurationManagement::ConfigurationManagement(String FilePath) : mFilePath(FilePath) { if (!SPIFFS.begin(true)) { - logPrintlnE("Mounting SPIFFS was not possible. Trying to format SPIFFS..."); + logPrintlnI("Mounting SPIFFS was not possible. Trying to format SPIFFS..."); SPIFFS.format(); if (!SPIFFS.begin()) { logPrintlnE("Formating SPIFFS was not okay!"); @@ -15,11 +15,11 @@ ConfigurationManagement::ConfigurationManagement(String FilePath) : mFilePath(Fi ConfigurationManagement::~ConfigurationManagement() { } -std::shared_ptr ConfigurationManagement::readConfiguration() { +void ConfigurationManagement::readConfiguration(Configuration &conf) { File file = SPIFFS.open(mFilePath); if (!file) { - logPrintlnE("Failed to open file for reading..."); - return 0; + logPrintlnE("Failed to open file for reading, using default configuration."); + return; } DynamicJsonDocument data(2048); DeserializationError error = deserializeJson(data, file); @@ -30,15 +30,13 @@ std::shared_ptr ConfigurationManagement::readConfiguration() { // Serial.println(); file.close(); - std::shared_ptr conf = readProjectConfiguration(data); + readProjectConfiguration(data, conf); // update config in memory to get the new fields: writeConfiguration(conf); - - return conf; } -void ConfigurationManagement::writeConfiguration(std::shared_ptr conf) { +void ConfigurationManagement::writeConfiguration(Configuration &conf) { File file = SPIFFS.open(mFilePath, "w"); if (!file) { logPrintlnE("Failed to open file for writing..."); diff --git a/lib/ConfigurationManagement/configuration.h b/lib/ConfigurationManagement/configuration.h index cb7b6d3..6ebcf75 100644 --- a/lib/ConfigurationManagement/configuration.h +++ b/lib/ConfigurationManagement/configuration.h @@ -16,12 +16,12 @@ public: explicit ConfigurationManagement(String FilePath); virtual ~ConfigurationManagement(); - std::shared_ptr readConfiguration(); - void writeConfiguration(std::shared_ptr conf); + void readConfiguration(Configuration &conf); + void writeConfiguration(Configuration &conf); private: - virtual std::shared_ptr readProjectConfiguration(DynamicJsonDocument &data) = 0; - virtual void writeProjectConfiguration(std::shared_ptr conf, DynamicJsonDocument &data) = 0; + virtual void readProjectConfiguration(DynamicJsonDocument &data, Configuration &conf) = 0; + virtual void writeProjectConfiguration(Configuration &conf, DynamicJsonDocument &data) = 0; const String mFilePath; }; diff --git a/lib/Display/Display.cpp b/lib/Display/Display.cpp index b62074e..95766b5 100644 --- a/lib/Display/Display.cpp +++ b/lib/Display/Display.cpp @@ -8,7 +8,7 @@ Display::Display() : _disp(0), _statusFrame(0), _displaySaveMode(false) { Display::~Display() { } -void Display::setup(std::shared_ptr boardConfig) { +void Display::setup(BoardConfig const *const boardConfig) { if (boardConfig->OledReset != 0) { pinMode(boardConfig->OledReset, OUTPUT); digitalWrite(boardConfig->OledReset, HIGH); @@ -18,7 +18,7 @@ void Display::setup(std::shared_ptr boardConfig) { digitalWrite(boardConfig->OledReset, HIGH); } Wire.begin(boardConfig->OledSda, boardConfig->OledScl); - _disp = std::shared_ptr(new SSD1306(&Wire, boardConfig->OledAddr)); + _disp = new SSD1306(&Wire, boardConfig->OledAddr); Bitmap bitmap(_disp->getWidth(), _disp->getHeight()); _disp->display(&bitmap); @@ -47,7 +47,7 @@ void Display::update() { if (_frames.size() > 0) { std::shared_ptr frame = *_frames.begin(); - Bitmap bitmap(_disp.get()); + Bitmap bitmap(_disp); frame->drawStatusPage(bitmap); _disp->display(&bitmap); @@ -60,7 +60,7 @@ void Display::update() { } } else { if (_disp->isDisplayOn()) { - Bitmap bitmap(_disp.get()); + Bitmap bitmap(_disp); _statusFrame->drawStatusPage(bitmap); _disp->display(&bitmap); @@ -88,7 +88,7 @@ void Display::setStatusFrame(std::shared_ptr frame) { } void Display::showSpashScreen(String firmwareTitle, String version) { - Bitmap bitmap(_disp.get()); + Bitmap bitmap(_disp); bitmap.drawString(0, 10, firmwareTitle); bitmap.drawString(0, 20, version); bitmap.drawString(0, 35, "by Peter Buchegger"); @@ -97,7 +97,7 @@ void Display::showSpashScreen(String firmwareTitle, String version) { } void Display::showStatusScreen(String header, String text) { - Bitmap bitmap(_disp.get()); + Bitmap bitmap(_disp); bitmap.drawString(0, 0, header); bitmap.drawStringLF(0, 10, text); _disp->display(&bitmap); diff --git a/lib/Display/Display.h b/lib/Display/Display.h index 2259291..045e898 100644 --- a/lib/Display/Display.h +++ b/lib/Display/Display.h @@ -4,7 +4,6 @@ #include #include #include -#include #include #include #include @@ -28,7 +27,7 @@ public: Display(); ~Display(); - void setup(std::shared_ptr boardConfig); + void setup(BoardConfig const *const boardConfig); // setup functions void showSpashScreen(String firmwareTitle, String version); void setStatusFrame(std::shared_ptr frame); @@ -43,7 +42,7 @@ public: void addFrame(std::shared_ptr frame); private: - std::shared_ptr _disp; + OLEDDisplay *_disp; Timer _displayFrameRate; std::shared_ptr _statusFrame; diff --git a/lib/LoRa_APRS/LoRa_APRS.cpp b/lib/LoRa_APRS/LoRa_APRS.cpp index d3279b2..ea28f8b 100644 --- a/lib/LoRa_APRS/LoRa_APRS.cpp +++ b/lib/LoRa_APRS/LoRa_APRS.cpp @@ -1,8 +1,6 @@ #include "LoRa_APRS.h" -LoRa_APRS::LoRa_APRS(std::shared_ptr boardConfig) : _LastReceivedMsg(0), _RxFrequency(LORA_RX_FREQUENCY), _TxFrequency(LORA_TX_FREQUENCY) { - SPI.begin(boardConfig->LoraSck, boardConfig->LoraMiso, boardConfig->LoraMosi, boardConfig->LoraCS); - setPins(boardConfig->LoraCS, boardConfig->LoraReset, boardConfig->LoraIRQ); +LoRa_APRS::LoRa_APRS() : _RxFrequency(433775000), _TxFrequency(433775000) { } bool LoRa_APRS::checkMessage() { @@ -33,7 +31,6 @@ std::shared_ptr LoRa_APRS::getMessage() { return _LastReceivedMsg; } -// cppcheck-suppress unusedFunction void LoRa_APRS::sendMessage(const std::shared_ptr msg) { setFrequency(_TxFrequency); String data = msg->encode(); @@ -53,6 +50,7 @@ void LoRa_APRS::setRxFrequency(long frequency) { setFrequency(_RxFrequency); } +// cppcheck-suppress unusedFunction long LoRa_APRS::getRxFrequency() const { return _RxFrequency; } diff --git a/lib/LoRa_APRS/LoRa_APRS.h b/lib/LoRa_APRS/LoRa_APRS.h index 1c29b41..cacd0fe 100644 --- a/lib/LoRa_APRS/LoRa_APRS.h +++ b/lib/LoRa_APRS/LoRa_APRS.h @@ -4,19 +4,12 @@ #include #include -#include #include #include -#define LORA_RX_FREQUENCY (433775000) -#define LORA_TX_FREQUENCY (433900000) -#define LORA_SPREADING_FACTOR (12) -#define LORA_SIGNAL_BANDWIDTH (125E3) -#define LORA_CODING_RATE4 (5) - class LoRa_APRS : public LoRaClass { public: - explicit LoRa_APRS(std::shared_ptr boardConfig); + LoRa_APRS(); bool checkMessage(); std::shared_ptr getMessage(); diff --git a/lib/PowerManagement/power_management.cpp b/lib/PowerManagement/power_management.cpp index 06771a3..779d32b 100644 --- a/lib/PowerManagement/power_management.cpp +++ b/lib/PowerManagement/power_management.cpp @@ -1,11 +1,9 @@ #include "power_management.h" -// cppcheck-suppress uninitMemberVar PowerManagement::PowerManagement() { } -// cppcheck-suppress unusedFunction bool PowerManagement::begin(TwoWire &port) { bool result = axp.begin(port, AXP192_SLAVE_ADDRESS); if (!result) { @@ -14,7 +12,6 @@ bool PowerManagement::begin(TwoWire &port) { return result; } -// cppcheck-suppress unusedFunction void PowerManagement::activateLoRa() { axp.setPowerOutPut(AXP192_LDO2, AXP202_ON); } @@ -29,12 +26,10 @@ void PowerManagement::activateGPS() { axp.setPowerOutPut(AXP192_LDO3, AXP202_ON); } -// cppcheck-suppress unusedFunction void PowerManagement::deactivateGPS() { axp.setPowerOutPut(AXP192_LDO3, AXP202_OFF); } -// cppcheck-suppress unusedFunction void PowerManagement::activateOLED() { axp.setPowerOutPut(AXP192_DCDC1, AXP202_ON); } diff --git a/lib/System/System.cpp b/lib/System/System.cpp index 6c77c3f..e074745 100644 --- a/lib/System/System.cpp +++ b/lib/System/System.cpp @@ -1,17 +1,25 @@ #include "System.h" -System::System(std::shared_ptr boardConfig, std::shared_ptr userConfig) : _boardConfig(boardConfig), _userConfig(userConfig), _isWifiEthConnected(false) { +System::System() : _boardConfig(0), _userConfig(0), _isWifiEthConnected(false) { } System::~System() { } -std::shared_ptr System::getBoardConfig() const { +void System::setBoardConfig(BoardConfig const *const boardConfig) { + _boardConfig = boardConfig; +} + +void System::setUserConfig(Configuration const *const userConfig) { + _userConfig = userConfig; +} + +BoardConfig const *const System::getBoardConfig() const { return _boardConfig; } -std::shared_ptr System::getUserConfig() const { +Configuration const *const System::getUserConfig() const { return _userConfig; } diff --git a/lib/System/System.h b/lib/System/System.h index ab3d655..376741b 100644 --- a/lib/System/System.h +++ b/lib/System/System.h @@ -10,22 +10,25 @@ class System { public: - System(std::shared_ptr boardConfig, std::shared_ptr userConfig); + System(); ~System(); - std::shared_ptr getBoardConfig() const; - std::shared_ptr getUserConfig() const; - TaskManager & getTaskManager(); - Display & getDisplay(); - bool isWifiEthConnected() const; - void connectedViaWifiEth(bool status); + void setBoardConfig(BoardConfig const *const boardConfig); + void setUserConfig(Configuration const *const userConfig); + + BoardConfig const *const getBoardConfig() const; + Configuration const *const getUserConfig() const; + TaskManager & getTaskManager(); + Display & getDisplay(); + bool isWifiEthConnected() const; + void connectedViaWifiEth(bool status); private: - std::shared_ptr _boardConfig; - std::shared_ptr _userConfig; - TaskManager _taskManager; - Display _display; - bool _isWifiEthConnected; + BoardConfig const * _boardConfig; + Configuration const *_userConfig; + TaskManager _taskManager; + Display _display; + bool _isWifiEthConnected; }; #endif diff --git a/lib/System/TaskManager.cpp b/lib/System/TaskManager.cpp index ce57033..b53bc1d 100644 --- a/lib/System/TaskManager.cpp +++ b/lib/System/TaskManager.cpp @@ -5,47 +5,37 @@ TaskManager::TaskManager() { } -void TaskManager::addTask(std::shared_ptr task) { +void TaskManager::addTask(Task *task) { _tasks.push_back(task); } -void TaskManager::addAlwaysRunTask(std::shared_ptr task) { +void TaskManager::addAlwaysRunTask(Task *task) { _alwaysRunTasks.push_back(task); } -std::shared_ptr TaskManager::getTask(const char *name) { - std::_List_iterator> elem = std::find_if(_tasks.begin(), _tasks.end(), [&](std::shared_ptr task) { - return task->getName() == name; - }); - if (elem == _tasks.end()) { - return 0; - } - return *elem; -} - -std::list> TaskManager::getTasks() { +std::list TaskManager::getTasks() { return _tasks; } -bool TaskManager::setup(std::shared_ptr system) { +bool TaskManager::setup(System &system) { logPrintlnV("will setup all tasks..."); - for (std::shared_ptr &elem : _alwaysRunTasks) { - logPrintW("call setup from "); - logPrintlnW(elem->getName()); + for (Task *elem : _alwaysRunTasks) { + logPrintD("call setup from "); + logPrintlnD(elem->getName()); elem->setup(system); } - for (std::shared_ptr &elem : _tasks) { - logPrintW("call setup from "); - logPrintlnW(elem->getName()); + for (Task *elem : _tasks) { + logPrintD("call setup from "); + logPrintlnD(elem->getName()); elem->setup(system); } _nextTask = _tasks.begin(); return true; } -bool TaskManager::loop(std::shared_ptr system) { +bool TaskManager::loop(System &system) { // logPrintlnD("will loop all tasks..."); - for (std::shared_ptr &elem : _alwaysRunTasks) { + for (Task *elem : _alwaysRunTasks) { // logPrintD("call loop from "); // logPrintlnD(elem->getName()); elem->loop(system); @@ -59,9 +49,10 @@ bool TaskManager::loop(std::shared_ptr system) { return ret; } +// cppcheck-suppress unusedFunction void StatusFrame::drawStatusPage(Bitmap &bitmap) { int y = 0; - for (std::shared_ptr task : _tasks) { + for (Task *task : _tasks) { int x = bitmap.drawString(0, y, (task->getName()).substring(0, task->getName().indexOf("Task"))); x = bitmap.drawString(x, y, ": "); if (task->getStateInfo() == "") { diff --git a/lib/System/TaskManager.h b/lib/System/TaskManager.h index edb8f14..7b7c4b6 100644 --- a/lib/System/TaskManager.h +++ b/lib/System/TaskManager.h @@ -43,8 +43,8 @@ public: return _stateInfo; } - virtual bool setup(std::shared_ptr system) = 0; - virtual bool loop(std::shared_ptr system) = 0; + virtual bool setup(System &system) = 0; + virtual bool loop(System &system) = 0; protected: TaskDisplayState _state; @@ -61,30 +61,29 @@ public: ~TaskManager() { } - void addTask(std::shared_ptr task); - void addAlwaysRunTask(std::shared_ptr task); - std::shared_ptr getTask(const char *name); - std::list> getTasks(); + void addTask(Task *task); + void addAlwaysRunTask(Task *task); + std::list getTasks(); - bool setup(std::shared_ptr system); - bool loop(std::shared_ptr system); + bool setup(System &system); + bool loop(System &system); private: - std::list> _tasks; - std::list>::iterator _nextTask; - std::list> _alwaysRunTasks; + std::list _tasks; + std::list::iterator _nextTask; + std::list _alwaysRunTasks; }; class StatusFrame : public DisplayFrame { public: - explicit StatusFrame(const std::list> &tasks) : _tasks(tasks) { + explicit StatusFrame(const std::list &tasks) : _tasks(tasks) { } virtual ~StatusFrame() { } void drawStatusPage(Bitmap &bitmap) override; private: - std::list> _tasks; + std::list _tasks; }; #include "System.h" diff --git a/lib/System/Timer.cpp b/lib/System/Timer.cpp index c22e34a..4fb9e9f 100644 --- a/lib/System/Timer.cpp +++ b/lib/System/Timer.cpp @@ -1,3 +1,5 @@ +#include + #include "Timer.h" Timer::Timer() : _timeout_ms(0), _nextTimeout(0) { @@ -7,14 +9,16 @@ void Timer::setTimeout(const uint32_t timeout_ms) { _timeout_ms = timeout_ms; } -time_t Timer::getTriggerTimeInSec() const { +uint32_t Timer::getTriggerTimeInSec() const { return (_nextTimeout - millis()) / 1000; } +// cppcheck-suppress unusedFunction bool Timer::isActive() const { return _nextTimeout != 0; } +// cppcheck-suppress unusedFunction void Timer::reset() { _nextTimeout = 0; } diff --git a/lib/System/Timer.h b/lib/System/Timer.h index 239f995..4e3eee5 100644 --- a/lib/System/Timer.h +++ b/lib/System/Timer.h @@ -1,14 +1,12 @@ #ifndef TIMER_H_ #define TIMER_H_ -#include - class Timer { public: Timer(); - void setTimeout(const uint32_t timeout_ms); - time_t getTriggerTimeInSec() const; + void setTimeout(const uint32_t timeout_ms); + uint32_t getTriggerTimeInSec() const; bool isActive() const; diff --git a/platformio.ini b/platformio.ini index edf1463..d0aa3c4 100644 --- a/platformio.ini +++ b/platformio.ini @@ -2,15 +2,15 @@ default_envs = lora_board [env] -platform = espressif32 @ 3.0.0 +platform = espressif32 @ 3.1.1 framework = arduino lib_ldf_mode = deep+ monitor_speed = 115200 +monitor_flags = --raw lib_deps = bblanchon/ArduinoJson @ 6.17.0 lewisxhe/AXP202X_Library @ 1.1.2 peterus/APRS-Decoder-Lib @ 0.0.6 - peterus/APRS-IS-Lib @ 0.0.8 peterus/esp-logger @ 0.0.1 peterus/ESP-FTP-Server-Lib @ 0.9.5 check_tool = cppcheck @@ -24,10 +24,10 @@ check_skip_packages = yes [env:lora_board] board = esp32doit-devkit-v1 -build_flags = -Werror -Wall -DNO_GLOBAL_INSTANCES +build_flags = -Werror -Wall -DCORE_DEBUG_LEVEL=5 [env:lora_board_debug] board = esp32doit-devkit-v1 -build_flags = -Werror -Wall -DNO_GLOBAL_INSTANCES +build_flags = -Werror -Wall -DCORE_DEBUG_LEVEL=5 build_type = debug monitor_filters = esp32_exception_decoder diff --git a/src/LoRa_APRS_iGate.cpp b/src/LoRa_APRS_iGate.cpp index 915e561..d6ede91 100644 --- a/src/LoRa_APRS_iGate.cpp +++ b/src/LoRa_APRS_iGate.cpp @@ -4,7 +4,6 @@ #include #include #include -#include #include #include @@ -12,111 +11,136 @@ #include "TaskDisplay.h" #include "TaskEth.h" #include "TaskFTP.h" -#include "TaskLora.h" +#include "TaskModem.h" #include "TaskNTP.h" #include "TaskOTA.h" +#include "TaskRouter.h" #include "TaskWifi.h" #include "project_configuration.h" -#define VERSION "21.14.0" +#define VERSION "21.25.0" String create_lat_aprs(double lat); String create_long_aprs(double lng); -std::shared_ptr LoRaSystem; -HardwareSerial Serial(0); +TaskQueue> toAprsIs; +TaskQueue> fromModem; +TaskQueue> toModem; + +System LoRaSystem; +Configuration userConfig; + +DisplayTask displayTask; +ModemTask modemTask(fromModem, toModem); +EthTask ethTask; +WifiTask wifiTask; +OTATask otaTask; +NTPTask ntpTask; +FTPTask ftpTask; +AprsIsTask aprsIsTask(toAprsIs); +RouterTask routerTask(fromModem, toModem, toAprsIs); -// cppcheck-suppress unusedFunction void setup() { Serial.begin(115200); Logger::instance().setSerial(&Serial); delay(500); - logPrintlnW("LoRa APRS iGate by OE5BPA (Peter Buchegger)"); - logPrintlnW("Version: " VERSION); + logPrintlnI("LoRa APRS iGate by OE5BPA (Peter Buchegger)"); + logPrintlnI("Version: " VERSION); - std::list> boardConfigs; - // clang-format off - boardConfigs.push_back(std::shared_ptr(new BoardConfig("TTGO_LORA32_V1", eTTGO_LORA32_V1, 4, 15, 0x3C, 0, 5, 19, 27, 18, 14, 26))); - boardConfigs.push_back(std::shared_ptr(new BoardConfig("TTGO_LORA32_V2", eTTGO_LORA32_V2, 21, 22, 0x3C, 0, 5, 19, 27, 18, 14, 26, true))); - boardConfigs.push_back(std::shared_ptr(new BoardConfig("TTGO_T_Beam_V0_7", eTTGO_T_Beam_V0_7, 21, 22, 0x3C, 0, 5, 19, 27, 18, 14, 26, true))); - boardConfigs.push_back(std::shared_ptr(new BoardConfig("TTGO_T_Beam_V1_0", eTTGO_T_Beam_V1_0, 21, 22, 0x3C, 0, 5, 19, 27, 18, 14, 26, true, true))); - boardConfigs.push_back(std::shared_ptr(new BoardConfig("ETH_BOARD", eETH_BOARD, 33, 32, 0x3C, 0, 14, 2, 15, 12, 4, 36))); - boardConfigs.push_back(std::shared_ptr(new BoardConfig("TRACKERD", eTRACKERD, 5, 4, 0x3C, 0, 18, 19, 23, 16, 14, 26))); - boardConfigs.push_back(std::shared_ptr(new BoardConfig("HELTEC_WIFI_LORA_32_V1", eHELTEC_WIFI_LORA_32_V1, 4, 15, 0x3C, 16, 5, 19, 27, 18, 14, 26))); - boardConfigs.push_back(std::shared_ptr(new BoardConfig("HELTEC_WIFI_LORA_32_V2", eHELTEC_WIFI_LORA_32_V2, 4, 15, 0x3C, 16, 5, 19, 27, 18, 14, 26))); - // clang-format on + std::list boardConfigs; + boardConfigs.push_back(&TTGO_LORA32_V1); + boardConfigs.push_back(&TTGO_LORA32_V2); + boardConfigs.push_back(&TTGO_T_Beam_V0_7); + boardConfigs.push_back(&TTGO_T_Beam_V1_0); + boardConfigs.push_back(Ð_BOARD); + boardConfigs.push_back(&TRACKERD); + boardConfigs.push_back(&HELTEC_WIFI_LORA_32_V1); + boardConfigs.push_back(&HELTEC_WIFI_LORA_32_V2); ProjectConfigurationManagement confmg; - std::shared_ptr userConfig = confmg.readConfiguration(); - BoardFinder finder(boardConfigs); - std::shared_ptr boardConfig = finder.getBoardConfig(userConfig->board); - if (boardConfig == 0) { + confmg.readConfiguration(userConfig); + + BoardFinder finder(boardConfigs); + BoardConfig const *boardConfig = finder.getBoardConfig(userConfig.board); + if (!boardConfig) { boardConfig = finder.searchBoardConfig(); - if (boardConfig == 0) { + if (!boardConfig) { logPrintlnE("Board config not set and search failed!"); - while (true) { - } + while (true) + ; + } else { + userConfig.board = boardConfig->Name; + confmg.writeConfiguration(userConfig); + logPrintlnI("will restart board now!"); + ESP.restart(); } - userConfig->board = boardConfig->Name; - confmg.writeConfiguration(userConfig); - logPrintlnI("will restart board now!"); - ESP.restart(); } + logPrintI("Board "); logPrintI(boardConfig->Name); logPrintlnI(" loaded."); if (boardConfig->Type == eTTGO_T_Beam_V1_0) { Wire.begin(boardConfig->OledSda, boardConfig->OledScl); - std::shared_ptr powerManagement = std::shared_ptr(new PowerManagement); - if (!powerManagement->begin(Wire)) { + PowerManagement powerManagement; + if (!powerManagement.begin(Wire)) { logPrintlnI("AXP192 init done!"); } else { logPrintlnE("AXP192 init failed!"); } - powerManagement->activateLoRa(); - powerManagement->activateOLED(); - powerManagement->deactivateGPS(); + powerManagement.activateLoRa(); + powerManagement.activateOLED(); + powerManagement.deactivateGPS(); } - LoRaSystem = std::shared_ptr(new System(boardConfig, userConfig)); - LoRaSystem->getTaskManager().addTask(std::shared_ptr(new DisplayTask())); - LoRaSystem->getTaskManager().addTask(std::shared_ptr(new LoraTask())); - if (boardConfig->Type == eETH_BOARD) { - LoRaSystem->getTaskManager().addAlwaysRunTask(std::shared_ptr(new EthTask())); - } else { - LoRaSystem->getTaskManager().addAlwaysRunTask(std::shared_ptr(new WifiTask())); + LoRaSystem.setBoardConfig(boardConfig); + LoRaSystem.setUserConfig(&userConfig); + LoRaSystem.getTaskManager().addTask(&displayTask); + LoRaSystem.getTaskManager().addTask(&modemTask); + LoRaSystem.getTaskManager().addTask(&routerTask); + + if (userConfig.aprs_is.active) { + if (boardConfig->Type == eETH_BOARD) { + LoRaSystem.getTaskManager().addAlwaysRunTask(ðTask); + } else { + LoRaSystem.getTaskManager().addAlwaysRunTask(&wifiTask); + } + LoRaSystem.getTaskManager().addTask(&otaTask); + LoRaSystem.getTaskManager().addTask(&ntpTask); + if (userConfig.ftp.active) { + LoRaSystem.getTaskManager().addTask(&ftpTask); + } + LoRaSystem.getTaskManager().addTask(&aprsIsTask); } - LoRaSystem->getTaskManager().addTask(std::shared_ptr(new OTATask())); - LoRaSystem->getTaskManager().addTask(std::shared_ptr(new NTPTask())); - if (userConfig->ftp.active) { - LoRaSystem->getTaskManager().addTask(std::shared_ptr(new FTPTask())); - } - LoRaSystem->getTaskManager().addTask(std::shared_ptr(new AprsIsTask())); - LoRaSystem->getTaskManager().setup(LoRaSystem); + LoRaSystem.getTaskManager().setup(LoRaSystem); - LoRaSystem->getDisplay().showSpashScreen("LoRa APRS iGate", VERSION); + LoRaSystem.getDisplay().showSpashScreen("LoRa APRS iGate", VERSION); - if (userConfig->callsign == "NOCALL-10") { + 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\"!"); + 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); logPrintlnI("setup done..."); } -// cppcheck-suppress unusedFunction void loop() { - LoRaSystem->getTaskManager().loop(LoRaSystem); + LoRaSystem.getTaskManager().loop(LoRaSystem); } String create_lat_aprs(double lat) { diff --git a/src/Task.h b/src/Task.h index 4c881a4..4c8163b 100644 --- a/src/Task.h +++ b/src/Task.h @@ -6,21 +6,21 @@ enum TaskNames TaskAprsIs = 1, TaskEth, TaskFtp, - TaskLora, + TaskModem, TaskNtp, TaskOta, TaskWifi, + TaskRouter, TaskSize, }; -// char const * const getTaskName(TaskNames task); - #define TASK_APRS_IS "AprsIsTask" #define TASK_ETH "EthTask" #define TASK_FTP "FTPTask" -#define TASK_LORA "LoraTask" +#define TASK_MODEM "ModemTask" #define TASK_NTP "NTPTask" #define TASK_OTA "OTATask" #define TASK_WIFI "WifiTask" +#define TASK_ROUTER "RouterTask" #endif diff --git a/src/TaskAprsIs.cpp b/src/TaskAprsIs.cpp index d060043..b96b06e 100644 --- a/src/TaskAprsIs.cpp +++ b/src/TaskAprsIs.cpp @@ -1,38 +1,25 @@ -#include #include #include "Task.h" #include "TaskAprsIs.h" #include "project_configuration.h" -String create_lat_aprs(double lat); -String create_long_aprs(double lng); - -AprsIsTask::AprsIsTask() : Task(TASK_APRS_IS, TaskAprsIs) { +AprsIsTask::AprsIsTask(TaskQueue> &toAprsIs) : Task(TASK_APRS_IS, TaskAprsIs), _toAprsIs(toAprsIs) { } AprsIsTask::~AprsIsTask() { } -bool AprsIsTask::setup(std::shared_ptr system) { - _beacon_timer.setTimeout(system->getUserConfig()->beacon.timeout * 60 * 1000); - _aprs_is = std::shared_ptr(new APRS_IS(system->getUserConfig()->callsign, system->getUserConfig()->aprs_is.passcode, "ESP32-APRS-IS", "0.2")); - - _beaconMsg = std::shared_ptr(new APRSMessage()); - _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); - +bool AprsIsTask::setup(System &system) { + _aprs_is.setup(system.getUserConfig()->callsign, system.getUserConfig()->aprs_is.passcode, "ESP32-APRS-IS", "0.2"); return true; } -bool AprsIsTask::loop(std::shared_ptr system) { - if (!system->isWifiEthConnected()) { +bool AprsIsTask::loop(System &system) { + if (!system.isWifiEthConnected()) { return false; } - if (!_aprs_is->connected()) { + if (!_aprs_is.connected()) { if (!connect(system)) { _stateInfo = "not connected"; _state = Error; @@ -43,32 +30,22 @@ bool AprsIsTask::loop(std::shared_ptr system) { return false; } - _aprs_is->getAPRSMessage(); + _aprs_is.getAPRSMessage(); - if (!inputQueue.empty()) { - std::shared_ptr msg = inputQueue.getElement(); - _aprs_is->sendMessage(msg); + if (!_toAprsIs.empty()) { + std::shared_ptr msg = _toAprsIs.getElement(); + _aprs_is.sendMessage(msg); } - if (_beacon_timer.check()) { - logPrintD("[" + timeString() + "] "); - logPrintlnD(_beaconMsg->encode()); - _aprs_is->sendMessage(_beaconMsg); - system->getDisplay().addFrame(std::shared_ptr(new TextFrame("BEACON", _beaconMsg->toString()))); - _beacon_timer.start(); - } - time_t diff = _beacon_timer.getTriggerTimeInSec(); - _stateInfo = "beacon " + String(diff / 60) + ":" + String(diff % 60); - _state = Okay; return true; } -bool AprsIsTask::connect(std::shared_ptr 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/TaskAprsIs.h b/src/TaskAprsIs.h index 67b1d31..de75fec 100644 --- a/src/TaskAprsIs.h +++ b/src/TaskAprsIs.h @@ -8,20 +8,18 @@ class AprsIsTask : public Task { public: - AprsIsTask(); + explicit AprsIsTask(TaskQueue> &toAprsIs); virtual ~AprsIsTask(); - virtual bool setup(std::shared_ptr system) override; - virtual bool loop(std::shared_ptr system) override; - - TaskQueue> inputQueue; + virtual bool setup(System &system) override; + virtual bool loop(System &system) override; private: - std::shared_ptr _aprs_is; - std::shared_ptr _beaconMsg; - Timer _beacon_timer; + APRS_IS _aprs_is; - bool connect(std::shared_ptr system); + TaskQueue> &_toAprsIs; + + bool connect(const System &system); }; #endif diff --git a/src/TaskDisplay.cpp b/src/TaskDisplay.cpp index 06d74ec..bfe6d0b 100644 --- a/src/TaskDisplay.cpp +++ b/src/TaskDisplay.cpp @@ -1,4 +1,3 @@ -#include #include #include "TaskDisplay.h" @@ -10,22 +9,22 @@ DisplayTask::DisplayTask() : Task("DisplayTask", 0) { DisplayTask::~DisplayTask() { } -bool DisplayTask::setup(std::shared_ptr system) { - system->getDisplay().setup(system->getBoardConfig()); - if (system->getUserConfig()->display.turn180) { - system->getDisplay().turn180(); +bool DisplayTask::setup(System &system) { + system.getDisplay().setup(system.getBoardConfig()); + 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) { - system->getDisplay().activateDisplaySaveMode(); - system->getDisplay().setDisplaySaveTimeout(system->getUserConfig()->display.timeout); + std::shared_ptr statusFrame = std::shared_ptr(new StatusFrame(system.getTaskManager().getTasks())); + system.getDisplay().setStatusFrame(statusFrame); + if (!system.getUserConfig()->display.alwaysOn) { + system.getDisplay().activateDisplaySaveMode(); + system.getDisplay().setDisplaySaveTimeout(system.getUserConfig()->display.timeout); } - _stateInfo = system->getUserConfig()->callsign; + _stateInfo = system.getUserConfig()->callsign; return true; } -bool DisplayTask::loop(std::shared_ptr system) { - system->getDisplay().update(); +bool DisplayTask::loop(System &system) { + system.getDisplay().update(); return true; } diff --git a/src/TaskDisplay.h b/src/TaskDisplay.h index 80cb98e..95dff61 100644 --- a/src/TaskDisplay.h +++ b/src/TaskDisplay.h @@ -9,8 +9,8 @@ public: DisplayTask(); virtual ~DisplayTask(); - virtual bool setup(std::shared_ptr system) override; - virtual bool loop(std::shared_ptr system) override; + virtual bool setup(System &system) override; + virtual bool loop(System &system) override; }; #endif diff --git a/src/TaskEth.cpp b/src/TaskEth.cpp index 77ef9c6..fdad5a2 100644 --- a/src/TaskEth.cpp +++ b/src/TaskEth.cpp @@ -7,8 +7,26 @@ volatile bool eth_connected = false; -static void WiFiEvent(WiFiEvent_t event) { +void WiFiEvent(WiFiEvent_t event) { switch (event) { + case SYSTEM_EVENT_STA_START: + logPrintlnI("WiFi Started"); + break; + case SYSTEM_EVENT_STA_CONNECTED: + logPrintlnI("WiFi Connected"); + break; + case SYSTEM_EVENT_STA_GOT_IP: + logPrintI("WiFi MAC: "); + logPrintI(WiFi.macAddress()); + logPrintI(", IPv4: "); + logPrintlnI(WiFi.localIP().toString()); + break; + case SYSTEM_EVENT_STA_DISCONNECTED: + logPrintlnW("WiFi Disconnected"); + break; + case SYSTEM_EVENT_STA_STOP: + logPrintlnW("WiFi Stopped"); + break; case SYSTEM_EVENT_ETH_START: logPrintlnI("ETH Started"); ETH.setHostname("esp32-ethernet"); @@ -21,6 +39,8 @@ static void WiFiEvent(WiFiEvent_t event) { logPrintI(ETH.macAddress()); logPrintI(", IPv4: "); logPrintI(ETH.localIP().toString()); + logPrintI(", DNS: "); + logPrintI(ETH.dnsIP().toString()); if (ETH.fullDuplex()) { logPrintI(", FULL_DUPLEX"); } @@ -48,7 +68,7 @@ EthTask::EthTask() : Task(TASK_ETH, TaskEth) { EthTask::~EthTask() { } -bool EthTask::setup(std::shared_ptr system) { +bool EthTask::setup(System &system) { WiFi.onEvent(WiFiEvent); constexpr uint8_t ETH_NRST = 5; @@ -73,14 +93,14 @@ bool EthTask::setup(std::shared_ptr system) { return true; } -bool EthTask::loop(std::shared_ptr system) { +bool EthTask::loop(System &system) { if (!eth_connected) { - system->connectedViaWifiEth(false); + system.connectedViaWifiEth(false); _stateInfo = "Ethernet not connected"; _state = Error; return false; } - system->connectedViaWifiEth(true); + system.connectedViaWifiEth(true); _stateInfo = ETH.localIP().toString(); _state = Okay; return true; diff --git a/src/TaskEth.h b/src/TaskEth.h index 8597369..4a63d3f 100644 --- a/src/TaskEth.h +++ b/src/TaskEth.h @@ -3,13 +3,15 @@ #include +void WiFiEvent(WiFiEvent_t event); + class EthTask : public Task { public: EthTask(); virtual ~EthTask(); - virtual bool setup(std::shared_ptr system) override; - virtual bool loop(std::shared_ptr system) override; + virtual bool setup(System &system) override; + virtual bool loop(System &system) override; private: }; diff --git a/src/TaskFTP.cpp b/src/TaskFTP.cpp index b2e67fb..d9615cf 100644 --- a/src/TaskFTP.cpp +++ b/src/TaskFTP.cpp @@ -12,31 +12,30 @@ FTPTask::FTPTask() : Task(TASK_FTP, TaskFtp), _beginCalled(false) { FTPTask::~FTPTask() { } -bool FTPTask::setup(std::shared_ptr system) { - _ftpServer = std::shared_ptr(new FTPServer()); - for (Configuration::Ftp::User user : system->getUserConfig()->ftp.users) { +bool FTPTask::setup(System &system) { + for (Configuration::Ftp::User user : system.getUserConfig()->ftp.users) { logPrintD("Adding user to FTP Server: "); logPrintlnD(user.name); - _ftpServer->addUser(user.name, user.password); + _ftpServer.addUser(user.name, user.password); } - _ftpServer->addFilesystem("SPIFFS", &SPIFFS); + _ftpServer.addFilesystem("SPIFFS", &SPIFFS); _stateInfo = "waiting"; return true; } -bool FTPTask::loop(std::shared_ptr system) { +bool FTPTask::loop(System &system) { if (!_beginCalled) { - _ftpServer->begin(); + _ftpServer.begin(); _beginCalled = true; } - _ftpServer->handle(); + _ftpServer.handle(); static bool configWasOpen = false; - if (configWasOpen && _ftpServer->countConnections() == 0) { + if (configWasOpen && _ftpServer.countConnections() == 0) { logPrintlnW("Maybe the config has been changed via FTP, lets restart now to get the new config..."); logPrintlnW(""); ESP.restart(); } - if (_ftpServer->countConnections() > 0) { + if (_ftpServer.countConnections() > 0) { configWasOpen = true; _stateInfo = "has connection"; } diff --git a/src/TaskFTP.h b/src/TaskFTP.h index 46d27cf..83c0ea7 100644 --- a/src/TaskFTP.h +++ b/src/TaskFTP.h @@ -9,12 +9,12 @@ public: FTPTask(); virtual ~FTPTask(); - virtual bool setup(std::shared_ptr system) override; - virtual bool loop(std::shared_ptr system) override; + virtual bool setup(System &system) override; + virtual bool loop(System &system) override; private: - std::shared_ptr _ftpServer; - bool _beginCalled; + FTPServer _ftpServer; + bool _beginCalled; }; #endif diff --git a/src/TaskLora.cpp b/src/TaskLora.cpp deleted file mode 100644 index 04b6f83..0000000 --- a/src/TaskLora.cpp +++ /dev/null @@ -1,69 +0,0 @@ -#include -#include - -#include "Task.h" -#include "TaskAprsIs.h" -#include "TaskLora.h" -#include "project_configuration.h" - -LoraTask::LoraTask() : Task(TASK_LORA, TaskLora) { -} - -LoraTask::~LoraTask() { -} - -bool LoraTask::setup(std::shared_ptr system) { - _lora_aprs = std::shared_ptr(new LoRa_APRS(system->getBoardConfig())); - if (!_lora_aprs->begin(_lora_aprs->getRxFrequency())) { - 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->enableCrc(); - - _stateInfo = ""; - return true; -} - -bool LoraTask::loop(std::shared_ptr system) { - if (_lora_aprs->checkMessage()) { - std::shared_ptr msg = _lora_aprs->getMessage(); - // msg->getAPRSBody()->setData(msg->getAPRSBody()->getData() + " 123"); - logPrintD("[" + timeString() + "] "); - logPrintD("Received packet '"); - logPrintD(msg->toString()); - logPrintD("' with RSSI "); - logPrintD(String(_lora_aprs->packetRssi())); - logPrintD(" and SNR "); - logPrintlnD(String(_lora_aprs->packetSnr())); - - String path = msg->getPath(); - if (path.indexOf("RFONLY") != -1 || path.indexOf("NOGATE") != -1 || path.indexOf("TCPIP") != -1) { - return true; - } - - if (!path.isEmpty()) { - path += ","; - } - msg->setPath(path + "qAR," + system->getUserConfig()->callsign); - - std::shared_ptr is_thread = std::static_pointer_cast(system->getTaskManager().getTask(TASK_APRS_IS)); - is_thread->inputQueue.addElement(msg); - system->getDisplay().addFrame(std::shared_ptr(new TextFrame("LoRa", msg->toString()))); - } - - if (!inputQueue.empty()) { - std::shared_ptr msg = inputQueue.getElement(); - _lora_aprs->sendMessage(msg); - } - - return true; -} diff --git a/src/TaskLora.h b/src/TaskLora.h deleted file mode 100644 index b274f5b..0000000 --- a/src/TaskLora.h +++ /dev/null @@ -1,22 +0,0 @@ -#ifndef TASK_LORA_H_ -#define TASK_LORA_H_ - -#include -#include -#include - -class LoraTask : public Task { -public: - LoraTask(); - virtual ~LoraTask(); - - virtual bool setup(std::shared_ptr system) override; - virtual bool loop(std::shared_ptr system) override; - - TaskQueue> inputQueue; - -private: - std::shared_ptr _lora_aprs; -}; - -#endif diff --git a/src/TaskModem.cpp b/src/TaskModem.cpp new file mode 100644 index 0000000..7dad353 --- /dev/null +++ b/src/TaskModem.cpp @@ -0,0 +1,60 @@ +#include + +#include + +#include "Task.h" +#include "TaskAprsIs.h" +#include "TaskModem.h" +#include "project_configuration.h" + +ModemTask::ModemTask(TaskQueue> &fromModem, TaskQueue> &toModem) : Task(TASK_MODEM, TaskModem), _lora_aprs(), _fromModem(fromModem), _toModem(toModem) { +} + +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)) { + 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.enableCrc(); + + _stateInfo = ""; + return true; +} + +bool ModemTask::loop(System &system) { + if (_lora_aprs.checkMessage()) { + std::shared_ptr msg = _lora_aprs.getMessage(); + // msg->getAPRSBody()->setData(msg->getAPRSBody()->getData() + " 123"); + logPrintD("[" + timeString() + "] "); + logPrintD("Received packet '"); + logPrintD(msg->toString()); + logPrintD("' with RSSI "); + logPrintD(String(_lora_aprs.packetRssi())); + logPrintD(" and SNR "); + logPrintlnD(String(_lora_aprs.packetSnr())); + + _fromModem.addElement(msg); + system.getDisplay().addFrame(std::shared_ptr(new TextFrame("LoRa", msg->toString()))); + } + + if (!_toModem.empty()) { + std::shared_ptr msg = _toModem.getElement(); + _lora_aprs.sendMessage(msg); + } + + return true; +} diff --git a/src/TaskModem.h b/src/TaskModem.h new file mode 100644 index 0000000..6087b67 --- /dev/null +++ b/src/TaskModem.h @@ -0,0 +1,23 @@ +#ifndef TASK_LORA_H_ +#define TASK_LORA_H_ + +#include +#include +#include + +class ModemTask : public Task { +public: + explicit ModemTask(TaskQueue> &fromModem, TaskQueue> &_toModem); + virtual ~ModemTask(); + + virtual bool setup(System &system) override; + virtual bool loop(System &system) override; + +private: + LoRa_APRS _lora_aprs; + + TaskQueue> &_fromModem; + TaskQueue> &_toModem; +}; + +#endif diff --git a/src/TaskNTP.cpp b/src/TaskNTP.cpp index 8bac58f..14b3808 100644 --- a/src/TaskNTP.cpp +++ b/src/TaskNTP.cpp @@ -1,6 +1,7 @@ -#include #include +#include + #include "Task.h" #include "TaskNTP.h" #include "project_configuration.h" @@ -11,25 +12,25 @@ NTPTask::NTPTask() : Task(TASK_NTP, TaskNtp), _beginCalled(false) { NTPTask::~NTPTask() { } -bool NTPTask::setup(std::shared_ptr system) { - _ntpClient = std::shared_ptr(new NTPClient(system->getUserConfig()->ntpServer.c_str())); +bool NTPTask::setup(System &system) { + _ntpClient.setPoolServerName(system.getUserConfig()->ntpServer.c_str()); return true; } -bool NTPTask::loop(std::shared_ptr system) { - if (!system->isWifiEthConnected()) { +bool NTPTask::loop(System &system) { + if (!system.isWifiEthConnected()) { return false; } if (!_beginCalled) { - _ntpClient->begin(); + _ntpClient.begin(); _beginCalled = true; } - if (_ntpClient->update()) { - setTime(_ntpClient->getEpochTime()); + if (_ntpClient.update()) { + setTime(_ntpClient.getEpochTime()); logPrintI("Current time: "); - logPrintlnI(_ntpClient->getFormattedTime()); + logPrintlnI(_ntpClient.getFormattedTime()); } - _stateInfo = _ntpClient->getFormattedTime(); + _stateInfo = _ntpClient.getFormattedTime(); _state = Okay; return true; } diff --git a/src/TaskNTP.h b/src/TaskNTP.h index a18103e..3eab8e3 100644 --- a/src/TaskNTP.h +++ b/src/TaskNTP.h @@ -9,12 +9,12 @@ public: NTPTask(); virtual ~NTPTask(); - virtual bool setup(std::shared_ptr system) override; - virtual bool loop(std::shared_ptr system) override; + virtual bool setup(System &system) override; + virtual bool loop(System &system) override; private: - std::shared_ptr _ntpClient; - bool _beginCalled; + NTPClient _ntpClient; + bool _beginCalled; }; #endif diff --git a/src/TaskOTA.cpp b/src/TaskOTA.cpp index 45ba900..6b6348c 100644 --- a/src/TaskOTA.cpp +++ b/src/TaskOTA.cpp @@ -10,11 +10,10 @@ OTATask::OTATask() : Task(TASK_OTA, TaskOta), _beginCalled(false) { OTATask::~OTATask() { } -bool OTATask::setup(std::shared_ptr system) { - _ota = std::shared_ptr(new ArduinoOTAClass()); - _ota->onStart([&]() { +bool OTATask::setup(System &system) { + _ota.onStart([&]() { String type; - if (_ota->getCommand() == U_FLASH) + if (_ota.getCommand() == U_FLASH) type = "sketch"; else // U_SPIFFS type = "filesystem"; @@ -44,16 +43,16 @@ bool OTATask::setup(std::shared_ptr 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; } -bool OTATask::loop(std::shared_ptr system) { +bool OTATask::loop(System &system) { if (!_beginCalled) { - _ota->begin(); + _ota.begin(); _beginCalled = true; } - _ota->handle(); + _ota.handle(); return true; } diff --git a/src/TaskOTA.h b/src/TaskOTA.h index ab781d8..1942d69 100644 --- a/src/TaskOTA.h +++ b/src/TaskOTA.h @@ -9,12 +9,12 @@ public: OTATask(); virtual ~OTATask(); - virtual bool setup(std::shared_ptr system) override; - virtual bool loop(std::shared_ptr system) override; + virtual bool setup(System &system) override; + virtual bool loop(System &system) override; private: - std::shared_ptr _ota; - bool _beginCalled; + ArduinoOTAClass _ota; + bool _beginCalled; }; #endif diff --git a/src/TaskRouter.cpp b/src/TaskRouter.cpp new file mode 100644 index 0000000..210ed7e --- /dev/null +++ b/src/TaskRouter.cpp @@ -0,0 +1,100 @@ +#include + +#include + +#include "Task.h" +#include "TaskRouter.h" +#include "project_configuration.h" + +String create_lat_aprs(double lat); +String create_long_aprs(double lng); + +RouterTask::RouterTask(TaskQueue> &fromModem, TaskQueue> &toModem, TaskQueue> &toAprsIs) : Task(TASK_ROUTER, TaskRouter), _fromModem(fromModem), _toModem(toModem), _toAprsIs(toAprsIs) { +} + +RouterTask::~RouterTask() { +} + +bool RouterTask::setup(System &system) { + // setup beacon + _beacon_timer.setTimeout(system.getUserConfig()->beacon.timeout * 60 * 1000); + + _beaconMsg = std::shared_ptr(new APRSMessage()); + _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); + + return true; +} + +bool RouterTask::loop(System &system) { + // do routing + if (!_fromModem.empty()) { + std::shared_ptr modemMsg = _fromModem.getElement(); + + if (system.getUserConfig()->aprs_is.active && modemMsg->getSource() != system.getUserConfig()->callsign) { + std::shared_ptr aprsIsMsg = std::make_shared(*modemMsg); + String path = aprsIsMsg->getPath(); + + if (!(path.indexOf("RFONLY") != -1 || path.indexOf("NOGATE") != -1 || path.indexOf("TCPIP") != -1)) { + if (!path.isEmpty()) { + path += ","; + } + + aprsIsMsg->setPath(path + "qAR," + system.getUserConfig()->callsign); + + logPrintD("APRS-IS: "); + logPrintlnD(aprsIsMsg->toString()); + _toAprsIs.addElement(aprsIsMsg); + } else { + logPrintlnD("APRS-IS: no forward => RFonly"); + } + } else { + if (!system.getUserConfig()->aprs_is.active) + logPrintlnD("APRS-IS: disabled"); + + if (modemMsg->getSource() == system.getUserConfig()->callsign) + logPrintlnD("APRS-IS: no forward => own packet received"); + } + + 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) { + // fixme + digiMsg->setPath(system.getUserConfig()->callsign + "*"); + + logPrintD("DIGI: "); + logPrintlnD(digiMsg->toString()); + + _toModem.addElement(digiMsg); + } + } + } + + // check for beacon + if (_beacon_timer.check()) { + logPrintD("[" + timeString() + "] "); + logPrintlnD(_beaconMsg->encode()); + + if (system.getUserConfig()->aprs_is.active) + _toAprsIs.addElement(_beaconMsg); + + if (system.getUserConfig()->digi.beacon) { + _toModem.addElement(_beaconMsg); + } + + system.getDisplay().addFrame(std::shared_ptr(new TextFrame("BEACON", _beaconMsg->toString()))); + + _beacon_timer.start(); + } + + uint32_t diff = _beacon_timer.getTriggerTimeInSec(); + _stateInfo = "beacon " + String(uint32_t(diff / 60)) + ":" + String(uint32_t(diff % 60)); + + return true; +} diff --git a/src/TaskRouter.h b/src/TaskRouter.h new file mode 100644 index 0000000..8d8d1ac --- /dev/null +++ b/src/TaskRouter.h @@ -0,0 +1,24 @@ +#ifndef TASK_ROUTER_H_ +#define TASK_ROUTER_H_ + +#include +#include + +class RouterTask : public Task { +public: + RouterTask(TaskQueue> &fromModem, TaskQueue> &toModem, TaskQueue> &toAprsIs); + virtual ~RouterTask(); + + virtual bool setup(System &system) override; + virtual bool loop(System &system) override; + +private: + TaskQueue> &_fromModem; + TaskQueue> &_toModem; + TaskQueue> &_toAprsIs; + + std::shared_ptr _beaconMsg; + Timer _beacon_timer; +}; + +#endif diff --git a/src/TaskWifi.cpp b/src/TaskWifi.cpp index db0cce9..408a0fd 100644 --- a/src/TaskWifi.cpp +++ b/src/TaskWifi.cpp @@ -2,6 +2,7 @@ #include #include "Task.h" +#include "TaskEth.h" #include "TaskWifi.h" #include "project_configuration.h" @@ -11,23 +12,21 @@ WifiTask::WifiTask() : Task(TASK_WIFI, TaskWifi), _oldWifiStatus(WL_IDLE_STATUS) WifiTask::~WifiTask() { } -bool WifiTask::setup(std::shared_ptr system) { - // WiFi.onEvent(WiFiEvent); - WiFi.setHostname(system->getUserConfig()->callsign.c_str()); - _wiFiMulti = std::shared_ptr(new WiFiMulti()); - ; - for (Configuration::Wifi::AP ap : system->getUserConfig()->wifi.APs) { +bool WifiTask::setup(System &system) { + WiFi.onEvent(WiFiEvent); + WiFi.setHostname(system.getUserConfig()->callsign.c_str()); + for (Configuration::Wifi::AP ap : system.getUserConfig()->wifi.APs) { logPrintD("Looking for AP: "); logPrintlnD(ap.SSID); - _wiFiMulti->addAP(ap.SSID.c_str(), ap.password.c_str()); + _wiFiMulti.addAP(ap.SSID.c_str(), ap.password.c_str()); } return true; } -bool WifiTask::loop(std::shared_ptr system) { - const uint8_t wifi_status = _wiFiMulti->run(); +bool WifiTask::loop(System &system) { + const uint8_t wifi_status = _wiFiMulti.run(); if (wifi_status != WL_CONNECTED) { - system->connectedViaWifiEth(false); + system.connectedViaWifiEth(false); logPrintlnE("WiFi not connected!"); _oldWifiStatus = wifi_status; _stateInfo = "WiFi not connected"; @@ -39,7 +38,7 @@ bool WifiTask::loop(std::shared_ptr system) { _oldWifiStatus = wifi_status; return false; } - system->connectedViaWifiEth(true); + system.connectedViaWifiEth(true); _stateInfo = WiFi.localIP().toString(); _state = Okay; return true; diff --git a/src/TaskWifi.h b/src/TaskWifi.h index b6758e2..8196629 100644 --- a/src/TaskWifi.h +++ b/src/TaskWifi.h @@ -9,12 +9,12 @@ public: WifiTask(); virtual ~WifiTask(); - virtual bool setup(std::shared_ptr system) override; - virtual bool loop(std::shared_ptr system) override; + virtual bool setup(System &system) override; + virtual bool loop(System &system) override; private: - std::shared_ptr _wiFiMulti; - uint8_t _oldWifiStatus; + WiFiMulti _wiFiMulti; + uint8_t _oldWifiStatus; }; #endif diff --git a/src/project_configuration.cpp b/src/project_configuration.cpp index 57a23c7..4bce038 100644 --- a/src/project_configuration.cpp +++ b/src/project_configuration.cpp @@ -4,96 +4,99 @@ #include "project_configuration.h" -std::shared_ptr ProjectConfigurationManagement::readProjectConfiguration(DynamicJsonDocument &data) { - std::shared_ptr conf = std::shared_ptr(new Configuration); +void ProjectConfigurationManagement::readProjectConfiguration(DynamicJsonDocument &data, Configuration &conf) { if (data.containsKey("callsign")) - conf->callsign = data["callsign"].as(); + 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); + 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.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(); + 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.aprs_is.server = data["aprs_is"]["server"].as(); + conf.aprs_is.port = data["aprs_is"]["port"] | 14580; - 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.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(); + 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); + conf.ftp.users.push_back(us); } - if (conf->ftp.users.empty()) { + if (conf.ftp.users.empty()) { Configuration::Ftp::User us; us.name = "ftp"; us.password = "ftp"; - conf->ftp.users.push_back(us); + conf.ftp.users.push_back(us); } if (data.containsKey("ntp_server")) - conf->ntpServer = data["ntp_server"].as(); + conf.ntpServer = data["ntp_server"].as(); if (data.containsKey("board")) - conf->board = data["board"].as(); - - return conf; + conf.board = data["board"].as(); } -void ProjectConfigurationManagement::writeProjectConfiguration(std::shared_ptr conf, DynamicJsonDocument &data) { - data["callsign"] = conf->callsign; +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) { + 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"]["passcode"] = conf->aprs_is.passcode; - data["aprs_is"]["server"] = conf->aprs_is.server; - data["aprs_is"]["port"] = conf->aprs_is.port; - 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; + 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) { + 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["ntp_server"] = conf.ntpServer; - data["board"] = conf->board; + data["board"] = conf.board; } diff --git a/src/project_configuration.h b/src/project_configuration.h index 00ebefa..e1e1686 100644 --- a/src/project_configuration.h +++ b/src/project_configuration.h @@ -33,14 +33,24 @@ public: class APRS_IS { public: - APRS_IS() : server("euro.aprs2.net"), port(14580) { + 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) { @@ -86,6 +96,7 @@ public: Wifi wifi; Beacon beacon; APRS_IS aprs_is; + Digi digi; LoRa lora; Display display; Ftp ftp; @@ -101,10 +112,8 @@ public: } private: - virtual std::shared_ptr readProjectConfiguration(DynamicJsonDocument &data) override; - virtual void writeProjectConfiguration(std::shared_ptr conf, DynamicJsonDocument &data) override; + virtual void readProjectConfiguration(DynamicJsonDocument &data, Configuration &conf) override; + virtual void writeProjectConfiguration(Configuration &conf, DynamicJsonDocument &data) override; }; -std::shared_ptr load_config(std::shared_ptr boardConfig); - #endif