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/protobufs b/protobufs
index 3b0d871ca..e00b5ba7d 160000
--- a/protobufs
+++ b/protobufs
@@ -1 +1 @@
-Subproject commit 3b0d871ca1e0f8a2ed823f0696e2d7cf31ed2ebd
+Subproject commit e00b5ba7d06053d820f1123351881fc4fa9270d1
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/airtime.cpp b/src/airtime.cpp
index c72a21d54..ae3b30811 100644
--- a/src/airtime.cpp
+++ b/src/airtime.cpp
@@ -117,6 +117,31 @@ float AirTime::utilizationTXPercent()
return (float(sum) / float(MS_IN_HOUR)) * 100;
}
+bool AirTime::isTxAllowedChannelUtil(bool polite)
+{
+ uint8_t percentage = (polite ? polite_channel_util_percent : max_channel_util_percent);
+ if (channelUtilizationPercent() < percentage) {
+ return true;
+ } else {
+ LOG_WARN("Channel utilization is >%d percent. Skipping this opportunity to send.\n", percentage);
+ return false;
+ }
+}
+
+
+bool AirTime::isTxAllowedAirUtil()
+{
+ if (!config.lora.override_duty_cycle && myRegion->dutyCycle < 100) {
+ if (utilizationTXPercent() < polite_tx_util_percent) {
+ return true;
+ } else {
+ LOG_WARN("Tx air utilization is >%d percent. Skipping this opportunity to send.\n", polite_tx_util_percent);
+ return false;
+ }
+ }
+ return true;
+}
+
// Get the amount of minutes we have to be silent before we can send again
uint8_t AirTime::getSilentMinutes(float txPercent, float dutyCycle)
{
diff --git a/src/airtime.h b/src/airtime.h
index 3f38f39f8..2d1f1e2d9 100644
--- a/src/airtime.h
+++ b/src/airtime.h
@@ -4,6 +4,7 @@
#include "configuration.h"
#include
#include
+#include "MeshRadio.h"
/*
TX_LOG - Time on air this device has transmitted
@@ -59,12 +60,17 @@ class AirTime : private concurrency::OSThread
uint32_t getSecondsSinceBoot();
uint32_t *airtimeReport(reportTypes reportType);
uint8_t getSilentMinutes(float txPercent, float dutyCycle);
+ bool isTxAllowedChannelUtil(bool polite=false);
+ bool isTxAllowedAirUtil();
private:
bool firstTime = true;
uint8_t lastUtilPeriod = 0;
uint8_t lastUtilPeriodTX = 0;
uint32_t secSinceBoot = 0;
+ uint8_t max_channel_util_percent = 40;
+ uint8_t polite_channel_util_percent = 25;
+ uint8_t polite_tx_util_percent = 5;
struct airtimeStruct {
uint32_t periodTX[PERIODS_TO_LOG]; // AirTime transmitted
diff --git a/src/main.cpp b/src/main.cpp
index af7f28b50..2631e68df 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
@@ -239,7 +239,7 @@ void setup()
#ifdef RAK4630
// We need to enable 3.3V periphery in order to scan it
pinMode(PIN_3V3_EN, OUTPUT);
- digitalWrite(PIN_3V3_EN, 1);
+ digitalWrite(PIN_3V3_EN, HIGH);
#endif
// Currently only the tbeam has a PMU
diff --git a/src/mesh/Channels.cpp b/src/mesh/Channels.cpp
index 85db38403..337fa66e0 100644
--- a/src/mesh/Channels.cpp
+++ b/src/mesh/Channels.cpp
@@ -210,7 +210,7 @@ Channel &Channels::getByIndex(ChannelIndex chIndex)
Channel &Channels::getByName(const char* chName)
{
for (ChannelIndex i = 0; i < getNumChannels(); i++) {
- if (strcasecmp(channelFile.channels[i].settings.name, chName) == 0) {
+ if (strcasecmp(getGlobalId(i), chName) == 0) {
return channelFile.channels[i];
}
}
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/MeshService.cpp b/src/mesh/MeshService.cpp
index f881f4d40..9a6fa984c 100644
--- a/src/mesh/MeshService.cpp
+++ b/src/mesh/MeshService.cpp
@@ -280,8 +280,7 @@ NodeInfo *MeshService::refreshMyNodeInfo()
node->last_heard =
getValidTime(RTCQualityFromNet); // This nodedb timestamp might be stale, so update it if our clock is kinda valid
- // For the time in the position field, only set that if we have a real GPS clock
- position.time = getValidTime(RTCQualityGPS);
+ position.time = getValidTime(RTCQualityFromNet);
updateBatteryLevel(powerStatus->getBatteryChargePercent());
@@ -327,4 +326,4 @@ int MeshService::onGPSChanged(const meshtastic::GPSStatus *newStatus)
bool MeshService::isToPhoneQueueEmpty()
{
return toPhoneQueue.isEmpty();
-}
\ No newline at end of file
+}
diff --git a/src/mesh/PhoneAPI.h b/src/mesh/PhoneAPI.h
index 8e28efcbf..ff1e7347c 100644
--- a/src/mesh/PhoneAPI.h
+++ b/src/mesh/PhoneAPI.h
@@ -89,9 +89,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/Router.cpp b/src/mesh/Router.cpp
index 69ac1d5c9..74487588b 100644
--- a/src/mesh/Router.cpp
+++ b/src/mesh/Router.cpp
@@ -138,7 +138,7 @@ void Router::sendAckNak(Routing_Error err, NodeNum to, PacketId idFrom, ChannelI
void Router::abortSendAndNak(Routing_Error err, MeshPacket *p)
{
LOG_ERROR("Error=%d, returning NAK and dropping packet.\n", err);
- sendAckNak(Routing_Error_NO_INTERFACE, getFrom(p), p->id, p->channel);
+ sendAckNak(err, getFrom(p), p->id, p->channel);
packetPool.release(p);
}
@@ -199,15 +199,19 @@ ErrorCode Router::send(MeshPacket *p)
} // should have already been handled by sendLocal
// Abort sending if we are violating the duty cycle
- if (!config.lora.override_duty_cycle && myRegion->dutyCycle != 100) {
- float hourlyTxPercent = airTime->utilizationTXPercent();
- if (hourlyTxPercent > myRegion->dutyCycle) {
- uint8_t silentMinutes = airTime->getSilentMinutes(hourlyTxPercent, myRegion->dutyCycle);
- LOG_WARN("Duty cycle limit exceeded. Aborting send for now, you can send again in %d minutes.\n", silentMinutes);
- Routing_Error err = Routing_Error_DUTY_CYCLE_LIMIT;
- abortSendAndNak(err, p);
- return err;
- }
+ if (!config.lora.override_duty_cycle && myRegion->dutyCycle < 100) {
+ float hourlyTxPercent = airTime->utilizationTXPercent();
+ if (hourlyTxPercent > myRegion->dutyCycle) {
+ uint8_t silentMinutes = airTime->getSilentMinutes(hourlyTxPercent, myRegion->dutyCycle);
+ LOG_WARN("Duty cycle limit exceeded. Aborting send for now, you can send again in %d minutes.\n", silentMinutes);
+ Routing_Error err = Routing_Error_DUTY_CYCLE_LIMIT;
+ if (getFrom(p) == nodeDB.getNodeNum()) { // only send NAK to API, not to the mesh
+ abortSendAndNak(err, p);
+ } else {
+ packetPool.release(p);
+ }
+ return err;
+ }
}
// PacketId nakId = p->decoded.which_ackVariant == SubPacket_fail_id_tag ? p->decoded.ackVariant.fail_id : 0;
diff --git a/src/mesh/SX126xInterface.cpp b/src/mesh/SX126xInterface.cpp
index 15b808852..0e033eeb6 100644
--- a/src/mesh/SX126xInterface.cpp
+++ b/src/mesh/SX126xInterface.cpp
@@ -70,7 +70,7 @@ bool SX126xInterface::init()
#if defined(SX126X_TXEN) && (SX126X_TXEN != RADIOLIB_NC)
// lora.begin sets Dio2 as RF switch control, which is not true if we are manually controlling RX and TX
if (res == RADIOLIB_ERR_NONE)
- res = lora.setDio2AsRfSwitch(false);
+ res = lora.setDio2AsRfSwitch(true);
#endif
#if 0
diff --git a/src/mesh/SinglePortModule.h b/src/mesh/SinglePortModule.h
index 57db73221..2e587cb89 100644
--- a/src/mesh/SinglePortModule.h
+++ b/src/mesh/SinglePortModule.h
@@ -18,9 +18,6 @@ class SinglePortModule : public MeshModule
SinglePortModule(const char *_name, PortNum _ourPortNum) : MeshModule(_name), ourPortNum(_ourPortNum) {}
protected:
- uint32_t max_channel_util_percent = 40;
- uint32_t polite_channel_util_percent = 25;
-
/**
* @return true if you want to receive the specified portnum
*/
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/generated/localonly.pb.h b/src/mesh/generated/localonly.pb.h
index d2b9dfcae..1e4aa633c 100644
--- a/src/mesh/generated/localonly.pb.h
+++ b/src/mesh/generated/localonly.pb.h
@@ -157,7 +157,7 @@ extern const pb_msgdesc_t LocalModuleConfig_msg;
/* Maximum encoded size of messages (where known) */
#define LocalConfig_size 391
-#define LocalModuleConfig_size 380
+#define LocalModuleConfig_size 412
#ifdef __cplusplus
} /* extern "C" */
diff --git a/src/mesh/generated/mesh.pb.h b/src/mesh/generated/mesh.pb.h
index 6380092ac..2a373978a 100644
--- a/src/mesh/generated/mesh.pb.h
+++ b/src/mesh/generated/mesh.pb.h
@@ -85,6 +85,8 @@ typedef enum _HardwareModel {
HardwareModel_HELTEC_V3 = 43,
/* New Heltec Wireless Stick Lite with ESP32-S3 CPU */
HardwareModel_HELTEC_WSL_V3 = 44,
+ /* New BETAFPV ELRS Micro TX Module 2.4G with ESP32 CPU */
+ HardwareModel_BETAFPV_2400_TX = 45,
/* Reserved ID For developing private Ports. These will show up in live traffic sparsely, so we can use a high number. Keep it within 8 bits. */
HardwareModel_PRIVATE_HW = 255
} HardwareModel;
@@ -440,9 +442,10 @@ typedef struct _Waypoint {
bool locked;
/* Name of the waypoint - max 30 chars */
char name[30];
- /* *
- Description of the waypoint - max 100 chars */
+ /* Description of the waypoint - max 100 chars */
char description[100];
+ /* Designator icon for the waypoint in the form of a unicode emoji */
+ uint32_t icon;
} Waypoint;
typedef PB_BYTES_ARRAY_T(256) MeshPacket_encrypted_t;
@@ -783,7 +786,7 @@ extern "C" {
#define RouteDiscovery_init_default {0, {0, 0, 0, 0, 0, 0, 0, 0}}
#define Routing_init_default {0, {RouteDiscovery_init_default}}
#define Data_init_default {_PortNum_MIN, {0, {0}}, 0, 0, 0, 0, 0, 0}
-#define Waypoint_init_default {0, 0, 0, 0, 0, "", ""}
+#define Waypoint_init_default {0, 0, 0, 0, 0, "", "", 0}
#define MeshPacket_init_default {0, 0, 0, 0, {Data_init_default}, 0, 0, 0, 0, 0, _MeshPacket_Priority_MIN, 0, _MeshPacket_Delayed_MIN}
#define NodeInfo_init_default {0, false, User_init_default, false, Position_init_default, 0, 0, false, DeviceMetrics_init_default}
#define MyNodeInfo_init_default {0, 0, 0, "", _CriticalErrorCode_MIN, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0, 0, 0, 0, 0, 0}, 0, {0, 0, 0, 0, 0, 0, 0, 0}, 0, 0, 0}
@@ -797,7 +800,7 @@ extern "C" {
#define RouteDiscovery_init_zero {0, {0, 0, 0, 0, 0, 0, 0, 0}}
#define Routing_init_zero {0, {RouteDiscovery_init_zero}}
#define Data_init_zero {_PortNum_MIN, {0, {0}}, 0, 0, 0, 0, 0, 0}
-#define Waypoint_init_zero {0, 0, 0, 0, 0, "", ""}
+#define Waypoint_init_zero {0, 0, 0, 0, 0, "", "", 0}
#define MeshPacket_init_zero {0, 0, 0, 0, {Data_init_zero}, 0, 0, 0, 0, 0, _MeshPacket_Priority_MIN, 0, _MeshPacket_Delayed_MIN}
#define NodeInfo_init_zero {0, false, User_init_zero, false, Position_init_zero, 0, 0, false, DeviceMetrics_init_zero}
#define MyNodeInfo_init_zero {0, 0, 0, "", _CriticalErrorCode_MIN, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0, 0, 0, 0, 0, 0}, 0, {0, 0, 0, 0, 0, 0, 0, 0}, 0, 0, 0}
@@ -855,6 +858,7 @@ extern "C" {
#define Waypoint_locked_tag 5
#define Waypoint_name_tag 6
#define Waypoint_description_tag 7
+#define Waypoint_icon_tag 8
#define MeshPacket_from_tag 1
#define MeshPacket_to_tag 2
#define MeshPacket_channel_tag 3
@@ -987,7 +991,8 @@ X(a, STATIC, SINGULAR, SFIXED32, longitude_i, 3) \
X(a, STATIC, SINGULAR, UINT32, expire, 4) \
X(a, STATIC, SINGULAR, BOOL, locked, 5) \
X(a, STATIC, SINGULAR, STRING, name, 6) \
-X(a, STATIC, SINGULAR, STRING, description, 7)
+X(a, STATIC, SINGULAR, STRING, description, 7) \
+X(a, STATIC, SINGULAR, FIXED32, icon, 8)
#define Waypoint_CALLBACK NULL
#define Waypoint_DEFAULT NULL
@@ -1144,7 +1149,7 @@ extern const pb_msgdesc_t Compressed_msg;
#define Routing_size 42
#define ToRadio_size 324
#define User_size 77
-#define Waypoint_size 156
+#define Waypoint_size 161
#ifdef __cplusplus
} /* extern "C" */
diff --git a/src/mesh/generated/module_config.pb.h b/src/mesh/generated/module_config.pb.h
index da13ac706..bd4e90832 100644
--- a/src/mesh/generated/module_config.pb.h
+++ b/src/mesh/generated/module_config.pb.h
@@ -80,7 +80,7 @@ typedef struct _ModuleConfig_MQTTConfig {
bool enabled;
/* The server to use for our MQTT global message gateway feature.
If not set, the default server will be used */
- char address[32];
+ char address[64];
/* MQTT username to use (most useful for a custom MQTT server).
If using a custom server, this will be honoured even if empty.
If using the default server, this will only be honoured if set, otherwise the device will use the default username */
@@ -553,13 +553,13 @@ extern const pb_msgdesc_t ModuleConfig_CannedMessageConfig_msg;
#define ModuleConfig_AudioConfig_size 19
#define ModuleConfig_CannedMessageConfig_size 49
#define ModuleConfig_ExternalNotificationConfig_size 40
-#define ModuleConfig_MQTTConfig_size 169
+#define ModuleConfig_MQTTConfig_size 201
#define ModuleConfig_RangeTestConfig_size 10
#define ModuleConfig_RemoteHardwareConfig_size 2
#define ModuleConfig_SerialConfig_size 26
#define ModuleConfig_StoreForwardConfig_size 22
#define ModuleConfig_TelemetryConfig_size 18
-#define ModuleConfig_size 172
+#define ModuleConfig_size 204
#ifdef __cplusplus
} /* extern "C" */
diff --git a/src/mesh/http/WiFiAPClient.cpp b/src/mesh/http/WiFiAPClient.cpp
index 82ca7a52d..733e4c1f1 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
@@ -55,11 +55,13 @@ static int32_t reconnectWiFi()
// Make sure we clear old connection credentials
WiFi.disconnect(false, true);
-
LOG_INFO("Reconnecting to WiFi access point %s\n",wifiName);
- WiFi.mode(WIFI_MODE_STA);
- WiFi.begin(wifiName, wifiPsw);
+ delay(5000);
+
+ if (!WiFi.isConnected()) {
+ WiFi.begin(wifiName, wifiPsw);
+ }
}
#ifndef DISABLE_NTP
@@ -167,7 +169,7 @@ bool initWifi()
WiFi.mode(WIFI_MODE_STA);
WiFi.setHostname(ourHost);
WiFi.onEvent(WiFiEvent);
- WiFi.setAutoReconnect(false);
+ WiFi.setAutoReconnect(true);
WiFi.setSleep(false);
if (config.network.address_mode == Config_NetworkConfig_AddressMode_STATIC && config.network.ipv4_config.ip != 0) {
WiFi.config(config.network.ipv4_config.ip,
@@ -182,7 +184,8 @@ bool initWifi()
WiFi.onEvent(
[](WiFiEvent_t event, WiFiEventInfo_t info) {
- LOG_WARN("WiFi lost connection. Reason: %d", info.wifi_sta_disconnected.reason);
+
+ LOG_WARN("WiFi lost connection. Reason: %d\n", info.wifi_sta_disconnected.reason);
/*
If we are disconnected from the AP for some reason,
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/modules/NodeInfoModule.cpp b/src/modules/NodeInfoModule.cpp
index d8047c5f0..5dc05cd95 100644
--- a/src/modules/NodeInfoModule.cpp
+++ b/src/modules/NodeInfoModule.cpp
@@ -65,8 +65,10 @@ int32_t NodeInfoModule::runOnce()
bool requestReplies = currentGeneration != radioGeneration;
currentGeneration = radioGeneration;
- LOG_INFO("Sending our nodeinfo to mesh (wantReplies=%d)\n", requestReplies);
- sendOurNodeInfo(NODENUM_BROADCAST, requestReplies); // Send our info (don't request replies)
+ if (airTime->isTxAllowedAirUtil()) {
+ LOG_INFO("Sending our nodeinfo to mesh (wantReplies=%d)\n", requestReplies);
+ sendOurNodeInfo(NODENUM_BROADCAST, requestReplies); // Send our info (don't request replies)
+ }
return default_broadcast_interval_secs * 1000;
-}
\ No newline at end of file
+}
diff --git a/src/modules/PositionModule.cpp b/src/modules/PositionModule.cpp
index 6680eaba5..4d119043c 100644
--- a/src/modules/PositionModule.cpp
+++ b/src/modules/PositionModule.cpp
@@ -144,7 +144,7 @@ int32_t PositionModule::runOnce()
if (lastGpsSend == 0 || (now - lastGpsSend) >= intervalMs) {
// Only send packets if the channel is less than 40% utilized.
- if (airTime->channelUtilizationPercent() < max_channel_util_percent) {
+ if (airTime->isTxAllowedChannelUtil()) {
if (node->has_position && (node->position.latitude_i != 0 || node->position.longitude_i != 0)) {
lastGpsSend = now;
@@ -158,14 +158,12 @@ int32_t PositionModule::runOnce()
LOG_INFO("Sending pos@%x:6 to mesh (wantReplies=%d)\n", node->position.timestamp, requestReplies);
sendOurPosition(NODENUM_BROADCAST, requestReplies);
}
- } else {
- LOG_WARN("Channel utilization is >40 percent. Skipping this opportunity to send.\n");
}
} else if (config.position.position_broadcast_smart_enabled) {
// Only send packets if the channel is less than 25% utilized.
- if (airTime->channelUtilizationPercent() < polite_channel_util_percent) {
+ if (airTime->isTxAllowedChannelUtil(true)) {
NodeInfo *node2 = service.refreshMyNodeInfo(); // should guarantee there is now a position
@@ -208,8 +206,6 @@ int32_t PositionModule::runOnce()
lastGpsSend = now;
}
}
- } else {
- LOG_WARN("Channel utilization is >25 percent. Skipping this opportunity to send.\n");
}
}
diff --git a/src/modules/Telemetry/DeviceTelemetry.cpp b/src/modules/Telemetry/DeviceTelemetry.cpp
index 109d8b5b1..5f96661e5 100644
--- a/src/modules/Telemetry/DeviceTelemetry.cpp
+++ b/src/modules/Telemetry/DeviceTelemetry.cpp
@@ -13,11 +13,10 @@
int32_t DeviceTelemetryModule::runOnce()
{
-#ifndef ARCH_PORTDUINO
uint32_t now = millis();
if ((lastSentToMesh == 0 ||
(now - lastSentToMesh) >= getConfiguredOrDefaultMs(moduleConfig.telemetry.device_update_interval)) &&
- airTime->channelUtilizationPercent() < max_channel_util_percent) {
+ airTime->isTxAllowedChannelUtil() && airTime->isTxAllowedAirUtil()) {
sendTelemetry();
lastSentToMesh = now;
} else if (service.isToPhoneQueueEmpty()) {
@@ -26,7 +25,6 @@ int32_t DeviceTelemetryModule::runOnce()
sendTelemetry(NODENUM_BROADCAST, true);
}
return sendToPhoneIntervalMs;
-#endif
}
bool DeviceTelemetryModule::handleReceivedProtobuf(const MeshPacket &mp, Telemetry *t)
diff --git a/src/modules/Telemetry/EnvironmentTelemetry.cpp b/src/modules/Telemetry/EnvironmentTelemetry.cpp
index 3bf303157..2a29405d3 100644
--- a/src/modules/Telemetry/EnvironmentTelemetry.cpp
+++ b/src/modules/Telemetry/EnvironmentTelemetry.cpp
@@ -107,7 +107,7 @@ int32_t EnvironmentTelemetryModule::runOnce()
uint32_t now = millis();
if ((lastSentToMesh == 0 ||
(now - lastSentToMesh) >= getConfiguredOrDefaultMs(moduleConfig.telemetry.environment_update_interval)) &&
- airTime->channelUtilizationPercent() < max_channel_util_percent) {
+ airTime->isTxAllowedAirUtil()) {
sendTelemetry();
lastSentToMesh = now;
} else if (service.isToPhoneQueueEmpty()) {
diff --git a/src/modules/esp32/RangeTestModule.cpp b/src/modules/esp32/RangeTestModule.cpp
index 1624a972b..52a18def5 100644
--- a/src/modules/esp32/RangeTestModule.cpp
+++ b/src/modules/esp32/RangeTestModule.cpp
@@ -73,10 +73,8 @@ int32_t RangeTestModule::runOnce()
LOG_INFO("fixed_position() %d\n", config.position.fixed_position);
// Only send packets if the channel is less than 25% utilized.
- if (airTime->channelUtilizationPercent() < 25) {
+ if (airTime->isTxAllowedChannelUtil(true)) {
rangeTestModuleRadio->sendPayload();
- } else {
- LOG_WARN("RangeTest - Channel utilization is >25 percent. Skipping this opportunity to send.\n");
}
return (senderHeartbeat);
diff --git a/src/modules/esp32/StoreForwardModule.cpp b/src/modules/esp32/StoreForwardModule.cpp
index bf0421a9a..b5e0b1e65 100644
--- a/src/modules/esp32/StoreForwardModule.cpp
+++ b/src/modules/esp32/StoreForwardModule.cpp
@@ -21,7 +21,7 @@ int32_t StoreForwardModule::runOnce()
// Send out the message queue.
if (this->busy) {
// Only send packets if the channel is less than 25% utilized.
- if (airTime->channelUtilizationPercent() < polite_channel_util_percent) {
+ if (airTime->isTxAllowedChannelUtil(true)) {
storeForwardModule->sendPayload(this->busyTo, this->packetHistoryTXQueue_index);
if (this->packetHistoryTXQueue_index == packetHistoryTXQueue_size) {
// Tell the client we're done sending
@@ -34,12 +34,10 @@ int32_t StoreForwardModule::runOnce()
} else {
this->packetHistoryTXQueue_index++;
}
- } else {
- LOG_WARN("*** Channel utilization is too high. Retrying later.\n");
}
LOG_DEBUG("*** SF bitrate = %f bytes / sec\n", myNodeInfo.bitrate);
- } else if ((millis() - lastHeartbeat > (heartbeatInterval * 1000)) && (airTime->channelUtilizationPercent() < polite_channel_util_percent)) {
+ } else if ((millis() - lastHeartbeat > (heartbeatInterval * 1000)) && airTime->isTxAllowedChannelUtil(true)) {
lastHeartbeat = millis();
LOG_INFO("*** Sending heartbeat\n");
StoreAndForward sf = StoreAndForward_init_zero;
diff --git a/src/mqtt/MQTT.cpp b/src/mqtt/MQTT.cpp
index f4004139a..cc091bcff 100644
--- a/src/mqtt/MQTT.cpp
+++ b/src/mqtt/MQTT.cpp
@@ -43,9 +43,20 @@ void MQTT::onPublish(char *topic, byte *payload, unsigned int length)
JSONValue *json_value = JSON::Parse(payloadStr);
if (json_value != NULL) {
LOG_INFO("JSON Received on MQTT, parsing..\n");
+
// check if it is a valid envelope
JSONObject json;
json = json_value->AsObject();
+
+ // parse the channel name from the topic string
+ char *ptr = strtok(topic, "/");
+ for (int i = 0; i < 3; i++) {
+ ptr = strtok(NULL, "/");
+ }
+ LOG_DEBUG("Looking for Channel name: %s\n", ptr);
+ Channel sendChannel = channels.getByName(ptr);
+ LOG_DEBUG("Found Channel name: %s (Index %d)\n", channels.getGlobalId(sendChannel.settings.channel_num), sendChannel.settings.channel_num);
+
if ((json.find("sender") != json.end()) && (json.find("payload") != json.end()) && (json.find("type") != json.end()) && json["type"]->IsString() && (json["type"]->AsString().compare("sendtext") == 0)) {
// this is a valid envelope
if (json["payload"]->IsString() && json["type"]->IsString() && (json["sender"]->AsString().compare(owner.id) != 0)) {
@@ -55,13 +66,18 @@ void MQTT::onPublish(char *topic, byte *payload, unsigned int length)
// construct protobuf data packet using TEXT_MESSAGE, send it to the mesh
MeshPacket *p = router->allocForSending();
p->decoded.portnum = PortNum_TEXT_MESSAGE_APP;
- if (jsonPayloadStr.length() <= sizeof(p->decoded.payload.bytes)) {
- memcpy(p->decoded.payload.bytes, jsonPayloadStr.c_str(), jsonPayloadStr.length());
- p->decoded.payload.size = jsonPayloadStr.length();
- MeshPacket *packet = packetPool.allocCopy(*p);
- service.sendToMesh(packet, RX_SRC_LOCAL);
+ p->channel = sendChannel.settings.channel_num;
+ if (sendChannel.settings.downlink_enabled) {
+ if (jsonPayloadStr.length() <= sizeof(p->decoded.payload.bytes)) {
+ memcpy(p->decoded.payload.bytes, jsonPayloadStr.c_str(), jsonPayloadStr.length());
+ p->decoded.payload.size = jsonPayloadStr.length();
+ MeshPacket *packet = packetPool.allocCopy(*p);
+ service.sendToMesh(packet, RX_SRC_LOCAL);
+ } else {
+ LOG_WARN("Received MQTT json payload too long, dropping\n");
+ }
} else {
- LOG_WARN("Received MQTT json payload too long, dropping\n");
+ LOG_WARN("Received MQTT json payload on channel %s, but downlink is disabled, dropping\n", sendChannel.settings.name);
}
} else {
LOG_DEBUG("JSON Ignoring downlink message we originally sent.\n");
@@ -80,9 +96,13 @@ void MQTT::onPublish(char *topic, byte *payload, unsigned int length)
// construct protobuf data packet using POSITION, send it to the mesh
MeshPacket *p = router->allocForSending();
p->decoded.portnum = PortNum_POSITION_APP;
- p->decoded.payload.size = pb_encode_to_bytes(p->decoded.payload.bytes, sizeof(p->decoded.payload.bytes), &Position_msg, &pos); //make the Data protobuf from position
- service.sendToMesh(p, RX_SRC_LOCAL);
-
+ p->channel = sendChannel.settings.channel_num;
+ if (sendChannel.settings.downlink_enabled) {
+ p->decoded.payload.size = pb_encode_to_bytes(p->decoded.payload.bytes, sizeof(p->decoded.payload.bytes), &Position_msg, &pos); //make the Data protobuf from position
+ service.sendToMesh(p, RX_SRC_LOCAL);
+ } else {
+ LOG_WARN("Received MQTT json payload on channel %s, but downlink is disabled, dropping\n", sendChannel.settings.name);
+ }
} else {
LOG_DEBUG("JSON Ignoring downlink message we originally sent.\n");
}
@@ -187,14 +207,17 @@ void MQTT::reconnect()
sendSubscriptions();
} else {
- LOG_ERROR("Failed to contact MQTT server (%d/10)...\n",reconnectCount);
#if HAS_WIFI && !defined(ARCH_PORTDUINO)
- if (reconnectCount > 9) {
+ LOG_ERROR("Failed to contact MQTT server (%d/5)...\n",reconnectCount + 1);
+ if (reconnectCount >= 4) {
needReconnect = true;
- wifiReconnect->setIntervalFromNow(1000);
+ wifiReconnect->setIntervalFromNow(0);
+ reconnectCount = 0;
+ } else {
+ reconnectCount++;
}
+
#endif
- reconnectCount++;
}
}
}
@@ -264,7 +287,6 @@ int32_t MQTT::runOnce()
String topic = cryptTopic + env->channel_id + "/" + owner.id;
LOG_INFO("publish %s, %u bytes from queue\n", topic.c_str(), numBytes);
-
pubSub.publish(topic.c_str(), bytes, numBytes, false);
@@ -279,7 +301,7 @@ int32_t MQTT::runOnce()
}
mqttPool.release(env);
}
- return 20;
+ return 200;
} else {
return 30000;
}
diff --git a/src/mqtt/MQTT.h b/src/mqtt/MQTT.h
index ddbacbcc4..16ce4c37a 100644
--- a/src/mqtt/MQTT.h
+++ b/src/mqtt/MQTT.h
@@ -13,7 +13,7 @@
#include
#endif
-#define MAX_MQTT_QUEUE 32
+#define MAX_MQTT_QUEUE 16
/**
* Our wrapper/singleton for sending/receiving MQTT "udp" packets. This object isolates the MQTT protocol implementation from
diff --git a/src/platform/nrf52/main-nrf52.cpp b/src/platform/nrf52/main-nrf52.cpp
index 9a942a606..e3096b0ce 100644
--- a/src/platform/nrf52/main-nrf52.cpp
+++ b/src/platform/nrf52/main-nrf52.cpp
@@ -172,6 +172,9 @@ void cpuDeepSleep(uint64_t msecToWake)
Serial1.end();
#endif
setBluetoothEnable(false);
+#ifdef RAK4630
+ digitalWrite(PIN_3V3_EN, LOW);
+#endif
// FIXME, use system off mode with ram retention for key state?
// FIXME, use non-init RAM per
// https://devzone.nordicsemi.com/f/nordic-q-a/48919/ram-retention-settings-with-softdevice-enabled
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}
diff --git a/version.properties b/version.properties
index 816f7c2ac..40e7926a9 100644
--- a/version.properties
+++ b/version.properties
@@ -1,4 +1,4 @@
[VERSION]
major = 2
minor = 0
-build = 12
+build = 13