diff --git a/arch/nrf52/nrf52.ini b/arch/nrf52/nrf52.ini index 46f946530..9ee2c37b5 100644 --- a/arch/nrf52/nrf52.ini +++ b/arch/nrf52/nrf52.ini @@ -8,7 +8,7 @@ build_flags = ${arduino_base.build_flags} -Wno-unused-variable -Isrc/platform/nrf52 build_src_filter = - ${arduino_base.build_src_filter} - - - - - - - - - + ${arduino_base.build_src_filter} - - - - - - - - - lib_ignore = BluetoothOTA diff --git a/arch/rp2040/rp2040.ini b/arch/rp2040/rp2040.ini index cf898a60f..f30a94d3d 100644 --- a/arch/rp2040/rp2040.ini +++ b/arch/rp2040/rp2040.ini @@ -12,7 +12,7 @@ build_flags = -D__PLAT_RP2040__ # -D _POSIX_THREADS build_src_filter = - ${arduino_base.build_src_filter} - - - - - - - - - + ${arduino_base.build_src_filter} - - - - - - - - - lib_ignore = BluetoothOTA lib_deps = diff --git a/arch/stm32/stm32wl5e.ini b/arch/stm32/stm32wl5e.ini index 3fc7583ad..a38fb65e8 100644 --- a/arch/stm32/stm32wl5e.ini +++ b/arch/stm32/stm32wl5e.ini @@ -10,7 +10,7 @@ build_flags = # Arduino/PlatformIO framework-arduinoststm32 package does not presently have SUBGHZSPI support # -DPIN_SPI_MOSI=PINSUBGHZSPIMOSI -DPIN_SPI_MISO=PINSUBGHZSPIMISO -DPIN_SPI_SCK=PINSUBGHZSPISCK build_src_filter = - ${arduino_base.build_src_filter} - - - - - - - - - - - - - - + ${arduino_base.build_src_filter} - - - - - - - - - - - - - - lib_deps = ${env.lib_deps} https://github.com/kokke/tiny-AES-c.git#f06ac37fc31dfdaca2e0d9bec83f90d5663c319b diff --git a/src/RedirectablePrint.cpp b/src/RedirectablePrint.cpp index e7f305e19..74b44dd86 100644 --- a/src/RedirectablePrint.cpp +++ b/src/RedirectablePrint.cpp @@ -3,7 +3,6 @@ #include "RTC.h" #include "NodeDB.h" #include "concurrency/OSThread.h" -// #include "wifi/WiFiServerAPI.h" #include #include #include @@ -27,10 +26,6 @@ size_t RedirectablePrint::write(uint8_t c) SEGGER_RTT_PutChar(SEGGER_STDOUT_CH, c); #endif - // FIXME - clean this up, the whole relationship of this class to SerialConsole to TCP/bluetooth debug log output is kinda messed up. But for now, just have this hack to - // optionally send chars to TCP also - //WiFiServerPort::debugOut(c); - if (!config.has_lora || config.device.serial_enabled) dest->write(c); @@ -108,3 +103,31 @@ size_t RedirectablePrint::log(const char *logLevel, const char *format, ...) return r; } + +void RedirectablePrint::hexDump(const char *logLevel, unsigned char *buf, uint16_t len) { + const char alphabet[17] = "0123456789abcdef"; + log(logLevel, " +------------------------------------------------+ +----------------+\n"); + log(logLevel, " |.0 .1 .2 .3 .4 .5 .6 .7 .8 .9 .a .b .c .d .e .f | | ASCII |\n"); + for (uint16_t i = 0; i < len; i += 16) { + if (i % 128 == 0) + log(logLevel, " +------------------------------------------------+ +----------------+\n"); + char s[] = "| | | |\n"; + uint8_t ix = 1, iy = 52; + for (uint8_t j = 0; j < 16; j++) { + if (i + j < len) { + uint8_t c = buf[i + j]; + s[ix++] = alphabet[(c >> 4) & 0x0F]; + s[ix++] = alphabet[c & 0x0F]; + ix++; + if (c > 31 && c < 128) s[iy++] = c; + else s[iy++] = '.'; + } + } + uint8_t index = i / 16; + if (i < 256) log(logLevel, " "); + log(logLevel, "%02x",index); + log(logLevel, "."); + log(logLevel, s); + } + log(logLevel, " +------------------------------------------------+ +----------------+\n"); +} diff --git a/src/RedirectablePrint.h b/src/RedirectablePrint.h index 8fabd4a72..7aaeb4a47 100644 --- a/src/RedirectablePrint.h +++ b/src/RedirectablePrint.h @@ -38,6 +38,8 @@ class RedirectablePrint : public Print /** like printf but va_list based */ size_t vprintf(const char *format, va_list arg); + + void hexDump(const char *logLevel, unsigned char *buf, uint16_t len); }; class NoopPrint : public Print diff --git a/src/main.cpp b/src/main.cpp index af7f28b50..47236bf7d 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -36,12 +36,12 @@ #endif #if HAS_WIFI -#include "mesh/wifi/WiFiServerAPI.h" +#include "mesh/api/WiFiServerAPI.h" #include "mqtt/MQTT.h" #endif #if HAS_ETHERNET -#include "mesh/eth/ethServerAPI.h" +#include "mesh/api/ethServerAPI.h" #include "mqtt/MQTT.h" #endif diff --git a/src/mesh/InterfacesTemplates.cpp b/src/mesh/InterfacesTemplates.cpp index 0d2246428..d8f84c487 100644 --- a/src/mesh/InterfacesTemplates.cpp +++ b/src/mesh/InterfacesTemplates.cpp @@ -2,9 +2,23 @@ #include "SX126xInterface.cpp" #include "SX128xInterface.h" #include "SX128xInterface.cpp" +#include "api/ServerAPI.h" +#include "api/ServerAPI.cpp" // We need this declaration for proper linking in derived classes template class SX126xInterface; template class SX126xInterface; template class SX126xInterface; template class SX128xInterface; + +#if HAS_ETHERNET +#include "api/ethServerAPI.h" +template class ServerAPI; +template class APIServerPort; +#endif + +#if HAS_WIFI +#include "api/WiFiServerAPI.h" +template class ServerAPI; +template class APIServerPort; +#endif \ No newline at end of file diff --git a/src/mesh/PhoneAPI.h b/src/mesh/PhoneAPI.h index 2f2695807..aa190ae37 100644 --- a/src/mesh/PhoneAPI.h +++ b/src/mesh/PhoneAPI.h @@ -86,9 +86,6 @@ class PhoneAPI : public Observer // FIXME, we shouldn't be inheriting void setInitialState() { state = STATE_SEND_MY_INFO; } - /// emit a debugging log character, FIXME - implement - void debugOut(char c) { } - protected: /// Our fromradio packet while it is being assembled FromRadio fromRadioScratch = {}; diff --git a/src/mesh/api/ServerAPI.cpp b/src/mesh/api/ServerAPI.cpp new file mode 100644 index 000000000..e35455063 --- /dev/null +++ b/src/mesh/api/ServerAPI.cpp @@ -0,0 +1,67 @@ +#include "ServerAPI.h" +#include "configuration.h" +#include + +template +ServerAPI::ServerAPI(T &_client) : StreamAPI(&client), concurrency::OSThread("ServerAPI"), client(_client) +{ + LOG_INFO("Incoming wifi connection\n"); +} + +template +ServerAPI::~ServerAPI() +{ + client.stop(); +} + +template +void ServerAPI::close() +{ + client.stop(); // drop tcp connection + StreamAPI::close(); +} + +/// Check the current underlying physical link to see if the client is currently connected +template +bool ServerAPI::checkIsConnected() +{ + return client.connected(); +} + +template +int32_t ServerAPI::runOnce() +{ + if (client.connected()) { + return StreamAPI::runOncePart(); + } else { + LOG_INFO("Client dropped connection, suspending API service\n"); + enabled = false; // we no longer need to run + return 0; + } +} + +template +APIServerPort::APIServerPort(int port) : U(port), concurrency::OSThread("ApiServer") {} + +template +void APIServerPort::init() +{ + U::begin(); +} + +template +int32_t APIServerPort::runOnce() +{ + auto client = U::available(); + if (client) { + // Close any previous connection (see FIXME in header file) + if (openAPI) { + LOG_INFO("Force closing previous TCP connection\n"); + delete openAPI; + } + + openAPI = new T(client); + } + + return 100; // only check occasionally for incoming connections +} diff --git a/src/mesh/wifi/WiFiServerAPI.h b/src/mesh/api/ServerAPI.h similarity index 72% rename from src/mesh/wifi/WiFiServerAPI.h rename to src/mesh/api/ServerAPI.h index 812408818..174aa774f 100644 --- a/src/mesh/wifi/WiFiServerAPI.h +++ b/src/mesh/api/ServerAPI.h @@ -1,21 +1,21 @@ #pragma once #include "StreamAPI.h" -#include /** * Provides both debug printing and, if the client starts sending protobufs to us, switches to send/receive protobufs * (and starts dropping debug printing - FIXME, eventually those prints should be encapsulated in protobufs). */ -class WiFiServerAPI : public StreamAPI, private concurrency::OSThread +template +class ServerAPI : public StreamAPI, private concurrency::OSThread { private: - WiFiClient client; + T client; public: - explicit WiFiServerAPI(WiFiClient &_client); + explicit ServerAPI(T &_client); - virtual ~WiFiServerAPI(); + virtual ~ServerAPI(); /// override close to also shutdown the TCP link virtual void close(); @@ -34,25 +34,21 @@ class WiFiServerAPI : public StreamAPI, private concurrency::OSThread /** * Listens for incoming connections and does accepts and creates instances of WiFiServerAPI as needed */ -class WiFiServerPort : public WiFiServer, private concurrency::OSThread +template +class APIServerPort : public U, private concurrency::OSThread { /** The currently open port * * FIXME: We currently only allow one open TCP connection at a time, because we depend on the loop() call in this class to * delegate to the worker. Once coroutines are implemented we can relax this restriction. */ - WiFiServerAPI *openAPI = NULL; + T *openAPI = NULL; public: - explicit WiFiServerPort(int port); + explicit APIServerPort(int port); void init(); - /// If an api server is running, we try to spit out debug 'serial' characters there - static void debugOut(char c); - protected: int32_t runOnce() override; }; - -void initApiServer(int port=4403); diff --git a/src/mesh/api/WiFiServerAPI.cpp b/src/mesh/api/WiFiServerAPI.cpp new file mode 100644 index 000000000..5f86dbe85 --- /dev/null +++ b/src/mesh/api/WiFiServerAPI.cpp @@ -0,0 +1,25 @@ +#include "configuration.h" +#include + +#if HAS_WIFI +#include "WiFiServerAPI.h" + +static WiFiServerPort *apiPort; + +void initApiServer(int port) +{ + // Start API server on port 4403 + if (!apiPort) { + apiPort = new WiFiServerPort(port); + LOG_INFO("API server listening on TCP port %d\n", port); + apiPort->init(); + } +} + +WiFiServerAPI::WiFiServerAPI(WiFiClient &_client) : ServerAPI(_client) +{ + LOG_INFO("Incoming wifi connection\n"); +} + +WiFiServerPort::WiFiServerPort(int port) : APIServerPort(port) {} +#endif diff --git a/src/mesh/api/WiFiServerAPI.h b/src/mesh/api/WiFiServerAPI.h new file mode 100644 index 000000000..279ee0f3f --- /dev/null +++ b/src/mesh/api/WiFiServerAPI.h @@ -0,0 +1,25 @@ +#pragma once + +#include "ServerAPI.h" +#include + +/** + * Provides both debug printing and, if the client starts sending protobufs to us, switches to send/receive protobufs + * (and starts dropping debug printing - FIXME, eventually those prints should be encapsulated in protobufs). + */ +class WiFiServerAPI : public ServerAPI +{ + public: + explicit WiFiServerAPI(WiFiClient &_client); +}; + +/** + * Listens for incoming connections and does accepts and creates instances of WiFiServerAPI as needed + */ +class WiFiServerPort : public APIServerPort +{ + public: + explicit WiFiServerPort(int port); +}; + +void initApiServer(int port=4403); diff --git a/src/mesh/api/ethServerAPI.cpp b/src/mesh/api/ethServerAPI.cpp new file mode 100644 index 000000000..3badcdfde --- /dev/null +++ b/src/mesh/api/ethServerAPI.cpp @@ -0,0 +1,27 @@ +#include "configuration.h" +#include + +#if HAS_ETHERNET + +#include "ethServerAPI.h" + +static ethServerPort *apiPort; + +void initApiServer(int port) +{ + // Start API server on port 4403 + if (!apiPort) { + apiPort = new ethServerPort(port); + LOG_INFO("API server listening on TCP port %d\n", port); + apiPort->init(); + } +} + +ethServerAPI::ethServerAPI(EthernetClient &_client) : ServerAPI(_client) +{ + LOG_INFO("Incoming ethernet connection\n"); +} + +ethServerPort::ethServerPort(int port) : APIServerPort(port) {} + +#endif \ No newline at end of file diff --git a/src/mesh/api/ethServerAPI.h b/src/mesh/api/ethServerAPI.h new file mode 100644 index 000000000..36f363f70 --- /dev/null +++ b/src/mesh/api/ethServerAPI.h @@ -0,0 +1,25 @@ +#pragma once + +#include "ServerAPI.h" +#include + +/** + * Provides both debug printing and, if the client starts sending protobufs to us, switches to send/receive protobufs + * (and starts dropping debug printing - FIXME, eventually those prints should be encapsulated in protobufs). + */ +class ethServerAPI : public ServerAPI +{ + public: + explicit ethServerAPI(EthernetClient &_client); +}; + +/** + * Listens for incoming connections and does accepts and creates instances of WiFiServerAPI as needed + */ +class ethServerPort : public APIServerPort +{ + public: + explicit ethServerPort(int port); +}; + +void initApiServer(int port=4403); diff --git a/src/mesh/eth/ethClient.cpp b/src/mesh/eth/ethClient.cpp index 4ac9bd9ad..dce04b191 100644 --- a/src/mesh/eth/ethClient.cpp +++ b/src/mesh/eth/ethClient.cpp @@ -5,7 +5,7 @@ #include #include #include "target_specific.h" -#include "mesh/eth/ethServerAPI.h" +#include "mesh/api/ethServerAPI.h" #include "mqtt/MQTT.h" #ifndef DISABLE_NTP diff --git a/src/mesh/eth/ethServerAPI.cpp b/src/mesh/eth/ethServerAPI.cpp deleted file mode 100644 index d91b798a0..000000000 --- a/src/mesh/eth/ethServerAPI.cpp +++ /dev/null @@ -1,82 +0,0 @@ -#include "ethServerAPI.h" -#include "configuration.h" -#include - -static ethServerPort *apiPort; - -void initApiServer(int port) -{ - // Start API server on port 4403 - if (!apiPort) { - apiPort = new ethServerPort(port); - LOG_INFO("API server listening on TCP port %d\n", port); - apiPort->init(); - } -} - -ethServerAPI::ethServerAPI(EthernetClient &_client) : StreamAPI(&client), concurrency::OSThread("ethServerAPI"), client(_client) -{ - LOG_INFO("Incoming ethernet connection\n"); -} - -ethServerAPI::~ethServerAPI() -{ - client.stop(); - - // FIXME - delete this if the client dropps the connection! -} - -/// override close to also shutdown the TCP link -void ethServerAPI::close() -{ - client.stop(); // drop tcp connection - StreamAPI::close(); -} - -/// Check the current underlying physical link to see if the client is currently connected -bool ethServerAPI::checkIsConnected() -{ - return client.connected(); -} - -int32_t ethServerAPI::runOnce() -{ - if (client.connected()) { - return StreamAPI::runOncePart(); - } else { - LOG_INFO("Client dropped connection, suspending API service\n"); - enabled = false; // we no longer need to run - return 0; - } -} - -/// If an api server is running, we try to spit out debug 'serial' characters there -void ethServerPort::debugOut(char c) -{ - if (apiPort && apiPort->openAPI) - apiPort->openAPI->debugOut(c); -} - - -ethServerPort::ethServerPort(int port) : EthernetServer(port), concurrency::OSThread("ApiServer") {} - -void ethServerPort::init() -{ - begin(); -} - -int32_t ethServerPort::runOnce() -{ - auto client = available(); - if (client) { - // Close any previous connection (see FIXME in header file) - if (openAPI) { - LOG_WARN("Force closing previous TCP connection\n"); - delete openAPI; - } - - openAPI = new ethServerAPI(client); - } - - return 100; // only check occasionally for incoming connections -} diff --git a/src/mesh/eth/ethServerAPI.h b/src/mesh/eth/ethServerAPI.h deleted file mode 100644 index 962841c80..000000000 --- a/src/mesh/eth/ethServerAPI.h +++ /dev/null @@ -1,58 +0,0 @@ -#pragma once - -#include "StreamAPI.h" -#include - -/** - * Provides both debug printing and, if the client starts sending protobufs to us, switches to send/receive protobufs - * (and starts dropping debug printing - FIXME, eventually those prints should be encapsulated in protobufs). - */ -class ethServerAPI : public StreamAPI, private concurrency::OSThread -{ - private: - EthernetClient client; - - public: - explicit ethServerAPI(EthernetClient &_client); - - virtual ~ethServerAPI(); - - /// override close to also shutdown the TCP link - virtual void close(); - - protected: - /// We override this method to prevent publishing EVENT_SERIAL_CONNECTED/DISCONNECTED for wifi links (we want the board to - /// stay in the POWERED state to prevent disabling wifi) - virtual void onConnectionChanged(bool connected) override {} - - virtual int32_t runOnce() override; // Check for dropped client connections - - /// Check the current underlying physical link to see if the client is currently connected - virtual bool checkIsConnected() override; -}; - -/** - * Listens for incoming connections and does accepts and creates instances of WiFiServerAPI as needed - */ -class ethServerPort : public EthernetServer, private concurrency::OSThread -{ - /** The currently open port - * - * FIXME: We currently only allow one open TCP connection at a time, because we depend on the loop() call in this class to - * delegate to the worker. Once coroutines are implemented we can relax this restriction. - */ - ethServerAPI *openAPI = NULL; - - public: - explicit ethServerPort(int port); - - void init(); - - /// If an api server is running, we try to spit out debug 'serial' characters there - static void debugOut(char c); - - protected: - int32_t runOnce() override; -}; - -void initApiServer(int port=4403); diff --git a/src/mesh/http/WiFiAPClient.cpp b/src/mesh/http/WiFiAPClient.cpp index 82ca7a52d..0f9832fdf 100644 --- a/src/mesh/http/WiFiAPClient.cpp +++ b/src/mesh/http/WiFiAPClient.cpp @@ -5,7 +5,7 @@ #include "configuration.h" #include "main.h" #include "mesh/http/WebServer.h" -#include "mesh/wifi/WiFiServerAPI.h" +#include "mesh/api/WiFiServerAPI.h" #include "mqtt/MQTT.h" #include "target_specific.h" #include diff --git a/src/mesh/wifi/WiFiServerAPI.cpp b/src/mesh/wifi/WiFiServerAPI.cpp deleted file mode 100644 index 136dfadb7..000000000 --- a/src/mesh/wifi/WiFiServerAPI.cpp +++ /dev/null @@ -1,82 +0,0 @@ -#include "WiFiServerAPI.h" -#include "configuration.h" -#include - -static WiFiServerPort *apiPort; - -void initApiServer(int port) -{ - // Start API server on port 4403 - if (!apiPort) { - apiPort = new WiFiServerPort(port); - LOG_INFO("API server listening on TCP port %d\n", port); - apiPort->init(); - } -} - -WiFiServerAPI::WiFiServerAPI(WiFiClient &_client) : StreamAPI(&client), concurrency::OSThread("WiFiServerAPI"), client(_client) -{ - LOG_INFO("Incoming wifi connection\n"); -} - -WiFiServerAPI::~WiFiServerAPI() -{ - client.stop(); - - // FIXME - delete this if the client dropps the connection! -} - -/// override close to also shutdown the TCP link -void WiFiServerAPI::close() -{ - client.stop(); // drop tcp connection - StreamAPI::close(); -} - -/// Check the current underlying physical link to see if the client is currently connected -bool WiFiServerAPI::checkIsConnected() -{ - return client.connected(); -} - -int32_t WiFiServerAPI::runOnce() -{ - if (client.connected()) { - return StreamAPI::runOncePart(); - } else { - LOG_INFO("Client dropped connection, suspending API service\n"); - enabled = false; // we no longer need to run - return 0; - } -} - -/// If an api server is running, we try to spit out debug 'serial' characters there -void WiFiServerPort::debugOut(char c) -{ - if (apiPort && apiPort->openAPI) - apiPort->openAPI->debugOut(c); -} - - -WiFiServerPort::WiFiServerPort(int port) : WiFiServer(port), concurrency::OSThread("ApiServer") {} - -void WiFiServerPort::init() -{ - begin(); -} - -int32_t WiFiServerPort::runOnce() -{ - auto client = available(); - if (client) { - // Close any previous connection (see FIXME in header file) - if (openAPI) { - LOG_INFO("Force closing previous TCP connection\n"); - delete openAPI; - } - - openAPI = new WiFiServerAPI(client); - } - - return 100; // only check occasionally for incoming connections -} diff --git a/src/platform/portduino/SimRadio.h b/src/platform/portduino/SimRadio.h index d2a36c81e..c4336a22b 100644 --- a/src/platform/portduino/SimRadio.h +++ b/src/platform/portduino/SimRadio.h @@ -2,7 +2,7 @@ #include "RadioInterface.h" #include "MeshPacketQueue.h" -#include "wifi/WiFiServerAPI.h" +#include "api/WiFiServerAPI.h" #include diff --git a/variants/rak4631/platformio.ini b/variants/rak4631/platformio.ini index e08b54dae..a0928605f 100644 --- a/variants/rak4631/platformio.ini +++ b/variants/rak4631/platformio.ini @@ -3,7 +3,7 @@ extends = nrf52840_base board = wiscore_rak4631 build_flags = ${nrf52840_base.build_flags} -Ivariants/rak4631 -D RAK_4631 -build_src_filter = ${nrf52_base.build_src_filter} +<../variants/rak4631> + + +build_src_filter = ${nrf52_base.build_src_filter} +<../variants/rak4631> + + + lib_deps = ${nrf52840_base.lib_deps} ${networking_base.lib_deps}