diff --git a/proto b/proto
index 4a64080d1..7b80bde42 160000
--- a/proto
+++ b/proto
@@ -1 +1 @@
-Subproject commit 4a64080d160f9219768a4126414d41dc82a3d63c
+Subproject commit 7b80bde4213c530ab3d85a19d1795025299d4633
diff --git a/src/mesh/MeshPlugin.cpp b/src/mesh/MeshPlugin.cpp
index f801682d1..85988ec7b 100644
--- a/src/mesh/MeshPlugin.cpp
+++ b/src/mesh/MeshPlugin.cpp
@@ -96,7 +96,7 @@ void MeshPlugin::callPlugins(const MeshPacket &mp, RxSource src)
assert(!pi.myReply); // If it is !null it means we have a bug, because it should have been sent the previous time
if (wantsPacket) {
- DEBUG_MSG("Plugin %s wantsPacket=%d\n", pi.name, wantsPacket);
+ DEBUG_MSG("Plugin '%s' wantsPacket=%d\n", pi.name, wantsPacket);
pluginFound = true;
@@ -109,7 +109,10 @@ void MeshPlugin::callPlugins(const MeshPacket &mp, RxSource src)
/// Also: if a packet comes in on the local PC interface, we don't check for bound channels, because it is TRUSTED and it needs to
/// to be able to fetch the initial admin packets without yet knowing any channels.
- bool rxChannelOk = !pi.boundChannel || (mp.from == 0) || (ch && (strcmp(ch->settings.name, pi.boundChannel) == 0));
+ bool rxChannelOk = !pi.boundChannel || (mp.from == 0) ||
+ !ch ||
+ strlen(ch->settings.name) > 0 ||
+ strcmp(ch->settings.name, pi.boundChannel);
if (!rxChannelOk) {
// no one should have already replied!
@@ -134,9 +137,9 @@ void MeshPlugin::callPlugins(const MeshPacket &mp, RxSource src)
// any other node.
if (mp.decoded.want_response && toUs && (getFrom(&mp) != ourNodeNum || mp.to == ourNodeNum) && !currentReply) {
pi.sendResponse(mp);
- DEBUG_MSG("Plugin %s sent a response\n", pi.name);
+ DEBUG_MSG("Plugin '%s' sent a response\n", pi.name);
} else {
- DEBUG_MSG("Plugin %s considered\n", pi.name);
+ DEBUG_MSG("Plugin '%s' considered\n", pi.name);
}
// If the requester didn't ask for a response we might need to discard unused replies to prevent memory leaks
@@ -147,7 +150,7 @@ void MeshPlugin::callPlugins(const MeshPacket &mp, RxSource src)
}
if (handled == ProcessMessage::STOP) {
- DEBUG_MSG("Plugin %s handled and skipped other processing\n", pi.name);
+ DEBUG_MSG("Plugin '%s' handled and skipped other processing\n", pi.name);
break;
}
}
diff --git a/src/mesh/http/ContentHandler.cpp b/src/mesh/http/ContentHandler.cpp
index c1fced6de..9a655839f 100644
--- a/src/mesh/http/ContentHandler.cpp
+++ b/src/mesh/http/ContentHandler.cpp
@@ -297,14 +297,21 @@ void handleStatic(HTTPRequest *req, HTTPResponse *res)
file = SPIFFS.open(filenameGzip.c_str());
res->setHeader("Content-Encoding", "gzip");
if (!file.available()) {
- DEBUG_MSG("File not available\n");
+ DEBUG_MSG("File not available - %s\n", filenameGzip.c_str());
}
} else {
has_set_content_type = true;
filenameGzip = "/static/index.html.gz";
file = SPIFFS.open(filenameGzip.c_str());
- res->setHeader("Content-Encoding", "gzip");
res->setHeader("Content-Type", "text/html");
+ if (!file.available()) {
+ DEBUG_MSG("File not available - %s\n", filenameGzip.c_str());
+ res->println("Web server is running.
The content you are looking for can't be found. Please see: FAQ.
stats");
+ } else {
+ res->setHeader("Content-Encoding", "gzip");
+ }
}
res->setHeader("Content-Length", httpsserver::intToString(file.size()));
@@ -576,6 +583,7 @@ void handleReport(HTTPRequest *req, HTTPResponse *res)
res->println("},");
res->println("\"device\": {");
+ res->printf("\"channel_utilization\": %3.2f%,\n", airTime->channelUtilizationPercent());
res->printf("\"reboot_counter\": %d\n", myNodeInfo.reboot_count);
res->println("},");
diff --git a/src/mesh/http/WiFiAPClient.cpp b/src/mesh/http/WiFiAPClient.cpp
index 91892b5de..c5cbe9c93 100644
--- a/src/mesh/http/WiFiAPClient.cpp
+++ b/src/mesh/http/WiFiAPClient.cpp
@@ -3,9 +3,9 @@
#include "concurrency/Periodic.h"
#include "configuration.h"
#include "main.h"
-#include "mqtt/MQTT.h"
#include "mesh/http/WebServer.h"
#include "mesh/wifi/WiFiServerAPI.h"
+#include "mqtt/MQTT.h"
#include "target_specific.h"
#include
#include
@@ -132,30 +132,30 @@ static void onNetworkConnected()
initApiServer();
APStartupComplete = true;
- }
+ }
// FIXME this is kinda yucky, instead we should just have an observable for 'wifireconnected'
- if(mqtt)
+ if (mqtt)
mqtt->reconnect();
}
// Startup WiFi
bool initWifi(bool forceSoftAP)
{
- if (forceSoftAP) {
- DEBUG_MSG("WiFi ... Forced AP Mode\n");
- } else if (radioConfig.preferences.wifi_ap_mode) {
- DEBUG_MSG("WiFi ... AP Mode\n");
- } else {
- DEBUG_MSG("WiFi ... Client Mode\n");
- }
-
forcedSoftAP = forceSoftAP;
if ((radioConfig.has_preferences && radioConfig.preferences.wifi_ssid[0]) || forceSoftAP) {
const char *wifiName = radioConfig.preferences.wifi_ssid;
const char *wifiPsw = radioConfig.preferences.wifi_password;
+ if (forceSoftAP) {
+ DEBUG_MSG("WiFi ... Forced AP Mode\n");
+ } else if (radioConfig.preferences.wifi_ap_mode) {
+ DEBUG_MSG("WiFi ... AP Mode\n");
+ } else {
+ DEBUG_MSG("WiFi ... Client Mode\n");
+ }
+
createSSLCert();
if (!*wifiPsw) // Treat empty password as no password
@@ -176,7 +176,6 @@ bool initWifi(bool forceSoftAP)
} else {
DEBUG_MSG("Starting WIFI AP: ssid=%s, ok=%d\n", wifiName, WiFi.softAP(wifiName, wifiPsw));
-
}
WiFi.softAPConfig(apIP, apIP, IPAddress(255, 255, 255, 0));
diff --git a/src/plugins/esp32/StoreForwardPlugin.cpp b/src/plugins/esp32/StoreForwardPlugin.cpp
index 10dedda41..f613fc7c0 100644
--- a/src/plugins/esp32/StoreForwardPlugin.cpp
+++ b/src/plugins/esp32/StoreForwardPlugin.cpp
@@ -3,6 +3,7 @@
#include "NodeDB.h"
#include "RTC.h"
#include "Router.h"
+#include "airtime.h"
#include "configuration.h"
#include "mesh-pb-constants.h"
#include "mesh/generated/storeforward.pb.h"
@@ -22,20 +23,29 @@ int32_t StoreForwardPlugin::runOnce()
if (radioConfig.preferences.is_router) {
+ // Send out the message queue.
if (this->busy) {
- // Send out the message queue.
+
- // DEBUG_MSG("--- --- --- In busy loop 1 %d\n", this->packetHistoryTXQueue_index);
- storeForwardPlugin->sendPayload(this->busyTo, this->packetHistoryTXQueue_index);
+ // Only send packets if the channel is less than 25% utilized.
+ if (airTime->channelUtilizationPercent() < 25) {
- if (this->packetHistoryTXQueue_index == packetHistoryTXQueue_size) {
- strcpy(this->routerMessage, "** S&F - Done");
- storeForwardPlugin->sendMessage(this->busyTo, this->routerMessage);
- // DEBUG_MSG("--- --- --- In busy loop - Done \n");
- this->packetHistoryTXQueue_index = 0;
- this->busy = false;
+ // DEBUG_MSG("--- --- --- In busy loop 1 %d\n", this->packetHistoryTXQueue_index);
+ storeForwardPlugin->sendPayload(this->busyTo, this->packetHistoryTXQueue_index);
+
+ if (this->packetHistoryTXQueue_index == packetHistoryTXQueue_size) {
+ strcpy(this->routerMessage, "** S&F - Done");
+ storeForwardPlugin->sendMessage(this->busyTo, this->routerMessage);
+
+ // DEBUG_MSG("--- --- --- In busy loop - Done \n");
+ this->packetHistoryTXQueue_index = 0;
+ this->busy = false;
+ } else {
+ this->packetHistoryTXQueue_index++;
+ }
+
} else {
- this->packetHistoryTXQueue_index++;
+ DEBUG_MSG("Channel utilization is too high. Skipping this opportunity to send and will retry later.\n");
}
}
DEBUG_MSG("SF myNodeInfo.bitrate = %f bytes / sec\n", myNodeInfo.bitrate);
@@ -414,9 +424,6 @@ StoreForwardPlugin::StoreForwardPlugin()
// Popupate PSRAM with our data structures.
this->populatePSRAM();
- // this->packetTimeMax = 2000;
- // DEBUG_MSG("SF Time to Transmit maxPacketSize (%d bytes) %d ms\n", maxPacketSize, this->packetTimeMax);
-
} else {
DEBUG_MSG("Device has less than 1M of PSRAM free. Aborting startup.\n");
DEBUG_MSG("Store & Forward Plugin - Aborting Startup.\n");