From 616290edcc1ae77254d3ef6b95fccd9bea45d051 Mon Sep 17 00:00:00 2001 From: Kevin Hester Date: Mon, 21 Dec 2020 11:13:16 +0800 Subject: [PATCH 01/18] speed up build for my slow laptop --- bin/build-all.sh | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/bin/build-all.sh b/bin/build-all.sh index 5021680c..c27760c4 100755 --- a/bin/build-all.sh +++ b/bin/build-all.sh @@ -14,6 +14,8 @@ BOARDS_ESP32="tlora-v2 tlora-v1 tlora-v2-1-1.6 tbeam heltec tbeam0.7" # FIXME note nrf52840dk build is for some reason only generating a BIN file but not a HEX file nrf52840dk-geeksville is fine BOARDS_NRF52="lora-relay-v1" +NUM_JOBS=2 + OUTDIR=release/latest # We keep all old builds (and their map files in the archive dir) @@ -49,7 +51,7 @@ function do_build() { basename=universal/firmware-$BOARD-$VERSION fi - pio run --jobs 4 --environment $BOARD # -v + pio run --jobs $NUM_JOBS --environment $BOARD # -v SRCELF=.pio/build/$BOARD/firmware.elf cp $SRCELF $OUTDIR/elfs/$basename.elf From 412916ba7cbe0ea8b83e339591be17e787fa180c Mon Sep 17 00:00:00 2001 From: Kevin Hester Date: Mon, 21 Dec 2020 11:13:30 +0800 Subject: [PATCH 02/18] fix printf format for 64 bits --- src/plugins/RemoteHardwarePlugin.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/plugins/RemoteHardwarePlugin.cpp b/src/plugins/RemoteHardwarePlugin.cpp index e9f25e51..e63e05cf 100644 --- a/src/plugins/RemoteHardwarePlugin.cpp +++ b/src/plugins/RemoteHardwarePlugin.cpp @@ -89,7 +89,7 @@ bool RemoteHardwarePlugin::handleReceivedProtobuf(const MeshPacket &req, const H lastWatchMsec = 0; // Force a new publish soon previousWatch = ~watchGpios; // generate a 'previous' value which is guaranteed to not match (to force an initial publish) enabled = true; // Let our thread run at least once - DEBUG_MSG("Now watching GPIOs 0x%x\n", watchGpios); + DEBUG_MSG("Now watching GPIOs 0x%llx\n", watchGpios); break; } @@ -114,7 +114,7 @@ int32_t RemoteHardwarePlugin::runOnce() { if(curVal != previousWatch) { previousWatch = curVal; - DEBUG_MSG("Broadcasting GPIOS 0x%x changed!\n", curVal); + DEBUG_MSG("Broadcasting GPIOS 0x%llx changed!\n", curVal); // Something changed! Tell the world with a broadcast message HardwareMessage reply = HardwareMessage_init_default; From a8d770029518cddfb4f088ee3e2a3dac6a95fd20 Mon Sep 17 00:00:00 2001 From: Kevin Hester Date: Mon, 21 Dec 2020 11:38:03 +0800 Subject: [PATCH 03/18] move more of is_router out of python and into the device code --- docs/software/TODO.md | 2 ++ proto | 2 +- src/PowerFSM.cpp | 5 +++-- src/gps/GPS.cpp | 6 +++--- src/mesh/NodeDB.h | 42 ++++++++++++++++++++++++++++++++++++------ src/mesh/mesh.pb.h | 13 +++++-------- 6 files changed, 50 insertions(+), 20 deletions(-) diff --git a/docs/software/TODO.md b/docs/software/TODO.md index c08ddabe..73df45a6 100644 --- a/docs/software/TODO.md +++ b/docs/software/TODO.md @@ -4,6 +4,8 @@ You probably don't care about this section - skip to the next one. For app cleanup: +* DONE writeup nice python options docs (common cases, link to protobuf docs) +* have android app link to user manual * DONE only do wantReplies once per packet type, if we change network settings force it again * update positions and nodeinfos based on packets we just merely witness on the mesh. via isPromsciousPort bool, remove sniffing * DONE make device build always have a valid version diff --git a/proto b/proto index 75078afe..020ef9ee 160000 --- a/proto +++ b/proto @@ -1 +1 @@ -Subproject commit 75078afe43934f4ce15ef86ebc6950658a170145 +Subproject commit 020ef9eea8129756a0b45be5a3900b0355be4451 diff --git a/src/PowerFSM.cpp b/src/PowerFSM.cpp index 7894361d..a6ee29c9 100644 --- a/src/PowerFSM.cpp +++ b/src/PowerFSM.cpp @@ -173,9 +173,10 @@ void PowerFSM_setup() { // If we are not a router and we already have AC power go to POWER state after init, otherwise go to ON // We assume routers might be powered all the time, but from a low current (solar) source - bool isLowPower = radioConfig.preferences.is_low_power; - bool hasPower = !isLowPower && powerStatus && powerStatus->getHasUSB(); bool isRouter = radioConfig.preferences.is_router; + bool isLowPower = radioConfig.preferences.is_low_power || isRouter; + bool hasPower = !isLowPower && powerStatus && powerStatus->getHasUSB(); + DEBUG_MSG("PowerFSM init, USB power=%d\n", hasPower); powerFSM.add_timed_transition(&stateBOOT, hasPower ? &statePOWER : &stateON, 3 * 1000, NULL, "boot timeout"); diff --git a/src/gps/GPS.cpp b/src/gps/GPS.cpp index 314b4c31..c0e336f0 100644 --- a/src/gps/GPS.cpp +++ b/src/gps/GPS.cpp @@ -158,7 +158,7 @@ uint32_t GPS::getWakeTime() const return t; // already maxint if (t == 0) - t = 15 * 60; // Allow up to 5 mins for each attempt (probably will be much less if we can find sats) + t = radioConfig.preferences.is_router ? 5 * 60 : 15 * 60; // Allow up to 15 mins for each attempt (probably will be much less if we can find sats) or less if a router t *= 1000; // msecs @@ -179,8 +179,8 @@ uint32_t GPS::getSleepTime() const if (t == UINT32_MAX) return t; // already maxint - if (t == 0) - t = 2 * 60; // 2 mins + if (t == 0) // default - unset in preferences + t = radioConfig.preferences.is_router ? 24 * 60 * 60 : 2 * 60; // 2 mins or once per day for routers t *= 1000; diff --git a/src/mesh/NodeDB.h b/src/mesh/NodeDB.h index e8c230ce..5174f564 100644 --- a/src/mesh/NodeDB.h +++ b/src/mesh/NodeDB.h @@ -147,23 +147,53 @@ their nodes */ const char *getChannelName(); +/* + If is_router is set, we use a number of different default values + + # FIXME - after tuning, move these params into the on-device defaults based on is_router and is_low_power + + # prefs.position_broadcast_secs = FIXME possibly broadcast only once an hr + prefs.wait_bluetooth_secs = 1 # Don't stay in bluetooth mode + prefs.mesh_sds_timeout_secs = never + prefs.phone_sds_timeout_sec = never + # try to stay in light sleep one full day, then briefly wake and sleep again + + prefs.ls_secs = oneday + + prefs.send_owner_interval = 2 # Send an owner packet every other network ping + prefs.position_broadcast_secs = 12 hours # send either position or owner every 12hrs + + # get a new GPS position once per day + prefs.gps_update_interval = oneday + + prefs.is_low_power = True + + # allow up to five minutes for each new GPS lock attempt + prefs.gps_attempt_time = 300 +*/ + +// Our delay functions check for this for times that should never expire +#define DELAY_FOREVER 0xffffffff + +#define IF_ROUTER(routerVal, normalVal) (radioConfig.preferences.is_router ? (routerVal) : (normalVal)) + #define PREF_GET(name, defaultVal) \ inline uint32_t getPref_##name() { return radioConfig.preferences.name ? radioConfig.preferences.name : (defaultVal); } -PREF_GET(send_owner_interval, 4) -PREF_GET(position_broadcast_secs, 15 * 60) +PREF_GET(send_owner_interval, IF_ROUTER(2, 4)) +PREF_GET(position_broadcast_secs, IF_ROUTER(12 * 60 * 60, 15 * 60)) // Each time we wake into the DARK state allow 1 minute to send and receive BLE packets to the phone -PREF_GET(wait_bluetooth_secs, 60) +PREF_GET(wait_bluetooth_secs, IF_ROUTER(1, 60)) PREF_GET(screen_on_secs, 60) -PREF_GET(mesh_sds_timeout_secs, 2 * 60 * 60) -PREF_GET(phone_sds_timeout_sec, 2 * 60 * 60) +PREF_GET(mesh_sds_timeout_secs, IF_ROUTER(DELAY_FOREVER, 2 * 60 * 60)) +PREF_GET(phone_sds_timeout_sec, IF_ROUTER(DELAY_FOREVER, 2 * 60 * 60)) PREF_GET(sds_secs, 365 * 24 * 60 * 60) // We default to sleeping (with bluetooth off for 5 minutes at a time). This seems to be a good tradeoff between // latency for the user sending messages and power savings because of not having to run (expensive) ESP32 bluetooth -PREF_GET(ls_secs, 5 * 60) +PREF_GET(ls_secs, IF_ROUTER(24 * 60 * 60, 5 * 60)) PREF_GET(phone_timeout_secs, 15 * 60) PREF_GET(min_wake_secs, 10) diff --git a/src/mesh/mesh.pb.h b/src/mesh/mesh.pb.h index bda4873b..92bab3ae 100644 --- a/src/mesh/mesh.pb.h +++ b/src/mesh/mesh.pb.h @@ -106,7 +106,6 @@ typedef struct _Position { typedef struct _RadioConfig_UserPreferences { uint32_t position_broadcast_secs; uint32_t send_owner_interval; - uint32_t num_missed_to_fail; uint32_t wait_bluetooth_secs; uint32_t screen_on_secs; uint32_t phone_timeout_secs; @@ -284,7 +283,7 @@ extern "C" { #define MeshPacket_init_default {0, 0, 0, {SubPacket_init_default}, 0, 0, 0, 0, 0, 0} #define ChannelSettings_init_default {0, _ChannelSettings_ModemConfig_MIN, {0, {0}}, "", 0, 0, 0, 0} #define RadioConfig_init_default {false, RadioConfig_UserPreferences_init_default, false, ChannelSettings_init_default} -#define RadioConfig_UserPreferences_init_default {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "", "", 0, _RegionCode_MIN, _LocationSharing_MIN, _GpsOperation_MIN, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0}} +#define RadioConfig_UserPreferences_init_default {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "", "", 0, _RegionCode_MIN, _LocationSharing_MIN, _GpsOperation_MIN, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0}} #define NodeInfo_init_default {0, false, User_init_default, false, Position_init_default, 0, 0} #define MyNodeInfo_init_default {0, 0, 0, "", "", "", 0, 0, 0, 0, 0, 0, 0, 0} #define DeviceState_init_default {false, RadioConfig_init_default, false, MyNodeInfo_init_default, false, User_init_default, 0, {NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default}, 0, {MeshPacket_init_default}, false, MeshPacket_init_default, 0, 0, 0, 0, {ChannelSettings_init_default, ChannelSettings_init_default, ChannelSettings_init_default, ChannelSettings_init_default}} @@ -299,7 +298,7 @@ extern "C" { #define MeshPacket_init_zero {0, 0, 0, {SubPacket_init_zero}, 0, 0, 0, 0, 0, 0} #define ChannelSettings_init_zero {0, _ChannelSettings_ModemConfig_MIN, {0, {0}}, "", 0, 0, 0, 0} #define RadioConfig_init_zero {false, RadioConfig_UserPreferences_init_zero, false, ChannelSettings_init_zero} -#define RadioConfig_UserPreferences_init_zero {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "", "", 0, _RegionCode_MIN, _LocationSharing_MIN, _GpsOperation_MIN, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0}} +#define RadioConfig_UserPreferences_init_zero {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "", "", 0, _RegionCode_MIN, _LocationSharing_MIN, _GpsOperation_MIN, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0}} #define NodeInfo_init_zero {0, false, User_init_zero, false, Position_init_zero, 0, 0} #define MyNodeInfo_init_zero {0, 0, 0, "", "", "", 0, 0, 0, 0, 0, 0, 0, 0} #define DeviceState_init_zero {false, RadioConfig_init_zero, false, MyNodeInfo_init_zero, false, User_init_zero, 0, {NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero}, 0, {MeshPacket_init_zero}, false, MeshPacket_init_zero, 0, 0, 0, 0, {ChannelSettings_init_zero, ChannelSettings_init_zero, ChannelSettings_init_zero, ChannelSettings_init_zero}} @@ -340,7 +339,6 @@ extern "C" { #define Position_time_tag 9 #define RadioConfig_UserPreferences_position_broadcast_secs_tag 1 #define RadioConfig_UserPreferences_send_owner_interval_tag 2 -#define RadioConfig_UserPreferences_num_missed_to_fail_tag 3 #define RadioConfig_UserPreferences_wait_bluetooth_secs_tag 4 #define RadioConfig_UserPreferences_screen_on_secs_tag 5 #define RadioConfig_UserPreferences_phone_timeout_secs_tag 6 @@ -509,7 +507,6 @@ X(a, STATIC, OPTIONAL, MESSAGE, channel_settings, 2) #define RadioConfig_UserPreferences_FIELDLIST(X, a) \ X(a, STATIC, SINGULAR, UINT32, position_broadcast_secs, 1) \ X(a, STATIC, SINGULAR, UINT32, send_owner_interval, 2) \ -X(a, STATIC, SINGULAR, UINT32, num_missed_to_fail, 3) \ X(a, STATIC, SINGULAR, UINT32, wait_bluetooth_secs, 4) \ X(a, STATIC, SINGULAR, UINT32, screen_on_secs, 5) \ X(a, STATIC, SINGULAR, UINT32, phone_timeout_secs, 6) \ @@ -661,11 +658,11 @@ extern const pb_msgdesc_t ToRadio_msg; #define SubPacket_size 275 #define MeshPacket_size 320 #define ChannelSettings_size 84 -#define RadioConfig_size 314 -#define RadioConfig_UserPreferences_size 225 +#define RadioConfig_size 308 +#define RadioConfig_UserPreferences_size 219 #define NodeInfo_size 132 #define MyNodeInfo_size 110 -#define DeviceState_size 5824 +#define DeviceState_size 5818 #define DebugString_size 258 #define FromRadio_size 329 #define ToRadio_size 323 From 5c70f36aa598c4919b1d0f016ef417200e725d9f Mon Sep 17 00:00:00 2001 From: Charles Crossan Date: Mon, 21 Dec 2020 17:42:55 -0500 Subject: [PATCH 04/18] add mime types for ico and svg --- src/meshwifi/meshhttp.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/meshwifi/meshhttp.cpp b/src/meshwifi/meshhttp.cpp index ebff1e7b..04dc237c 100644 --- a/src/meshwifi/meshhttp.cpp +++ b/src/meshwifi/meshhttp.cpp @@ -78,7 +78,8 @@ char contentTypes[][2][32] = {{".txt", "text/plain"}, {".html", "text/html"} {".js", "text/javascript"}, {".png", "image/png"}, {".jpg", "image/jpg"}, {".gz", "application/gzip"}, {".gif", "image/gif"}, {".json", "application/json"}, - {".css", "text/css"}, {"", ""}}; + {".css", "text/css"}, {".ico","image/vnd.microsoft.icon"}, + {".svg", "image/svg+xml"}, {"", ""}}; void handleWebResponse() { From 5f97740ab74ad59044a9fc83782fb22d9f067ee4 Mon Sep 17 00:00:00 2001 From: Jm Casler Date: Mon, 21 Dec 2020 17:42:00 -0800 Subject: [PATCH 05/18] Fix for #535 -- Heltec board stays asleep ... --- src/PowerFSM.cpp | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/PowerFSM.cpp b/src/PowerFSM.cpp index 7894361d..be1ace0d 100644 --- a/src/PowerFSM.cpp +++ b/src/PowerFSM.cpp @@ -144,12 +144,12 @@ static void onEnter() uint32_t now = millis(); - if (now - lastPingMs > 30 * 1000) { // if more than a minute since our last press, ask node we are looking at to update their state + if (now - lastPingMs > + 30 * 1000) { // if more than a minute since our last press, ask node we are looking at to update their state if (displayedNodeNum) service.sendNetworkPing(displayedNodeNum, true); // Refresh the currently displayed node lastPingMs = now; } - } static void screenPress() @@ -174,7 +174,12 @@ void PowerFSM_setup() // If we are not a router and we already have AC power go to POWER state after init, otherwise go to ON // We assume routers might be powered all the time, but from a low current (solar) source bool isLowPower = radioConfig.preferences.is_low_power; - bool hasPower = !isLowPower && powerStatus && powerStatus->getHasUSB(); + + /* To determine if we're externally powered, assumptions + 1) If we're powered up and there's no battery, we must be getting power externally. + 2) If we detect USB power from the power management chip, we must be getting power externally. + */ + bool hasPower = (powerStatus && !powerStatus->getHasBattery()) || !isLowPower && powerStatus && powerStatus->getHasUSB(); bool isRouter = radioConfig.preferences.is_router; DEBUG_MSG("PowerFSM init, USB power=%d\n", hasPower); powerFSM.add_timed_transition(&stateBOOT, hasPower ? &statePOWER : &stateON, 3 * 1000, NULL, "boot timeout"); From 47ccfb610693704c1865451e6d530b422bd1ba40 Mon Sep 17 00:00:00 2001 From: Charles Crossan Date: Mon, 21 Dec 2020 21:10:53 -0500 Subject: [PATCH 06/18] add HTTP/Delete method handler for SPIFFS --- src/meshwifi/meshhttp.cpp | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/src/meshwifi/meshhttp.cpp b/src/meshwifi/meshhttp.cpp index 04dc237c..11d6dfc2 100644 --- a/src/meshwifi/meshhttp.cpp +++ b/src/meshwifi/meshhttp.cpp @@ -55,6 +55,7 @@ void handleFavicon(HTTPRequest *req, HTTPResponse *res); void handleRoot(HTTPRequest *req, HTTPResponse *res); void handleStaticBrowse(HTTPRequest *req, HTTPResponse *res); void handleStaticPost(HTTPRequest *req, HTTPResponse *res); +void handleStaticDelete(HTTPRequest *req, HTTPResponse *res); void handleStatic(HTTPRequest *req, HTTPResponse *res); void handleRestart(HTTPRequest *req, HTTPResponse *res); void handle404(HTTPRequest *req, HTTPResponse *res); @@ -240,6 +241,7 @@ void initWebServer() ResourceNode *nodeRoot = new ResourceNode("/", "GET", &handleRoot); ResourceNode *nodeStaticBrowse = new ResourceNode("/static", "GET", &handleStaticBrowse); ResourceNode *nodeStaticPOST = new ResourceNode("/static", "POST", &handleStaticPost); + ResourceNode *nodeStaticDelete = new ResourceNode("/static", "DELETE", &handleStaticDelete); ResourceNode *nodeStatic = new ResourceNode("/static/*", "GET", &handleStatic); ResourceNode *nodeRestart = new ResourceNode("/restart", "POST", &handleRestart); ResourceNode *node404 = new ResourceNode("", "GET", &handle404); @@ -257,6 +259,7 @@ void initWebServer() secureServer->registerNode(nodeRoot); secureServer->registerNode(nodeStaticBrowse); secureServer->registerNode(nodeStaticPOST); + secureServer->registerNode(nodeStaticDelete); secureServer->registerNode(nodeStatic); secureServer->registerNode(nodeRestart); secureServer->registerNode(nodeFormUpload); @@ -276,6 +279,7 @@ void initWebServer() insecureServer->registerNode(nodeRoot); insecureServer->registerNode(nodeStaticBrowse); insecureServer->registerNode(nodeStaticPOST); + insecureServer->registerNode(nodeStaticDelete); insecureServer->registerNode(nodeStatic); insecureServer->registerNode(nodeRestart); insecureServer->registerNode(nodeFormUpload); @@ -389,6 +393,31 @@ void handleStaticPost(HTTPRequest *req, HTTPResponse *res) res->println(""); } +void handleStaticDelete(HTTPRequest *req, HTTPResponse *res) +{ + ResourceParameters *params = req->getParams(); + std::string paramValDelete; + + res->setHeader("Content-Type", "application/json"); + if (params->getQueryParameter("delete", paramValDelete)) { + std::string pathDelete = "/" + paramValDelete; + if (SPIFFS.remove(pathDelete.c_str())) { + Serial.println(pathDelete.c_str()); + res->println("{"); + res->println("\"status\": \"ok\""); + res->println("}"); + return; + } else { + Serial.println(pathDelete.c_str()); + res->println("{"); + res->println("\"status\": \"Error\""); + res->println("}"); + return; + } + } +} + + void handleSpiffsBrowseStatic(HTTPRequest *req, HTTPResponse *res) { // jm From 5a96dc0083cf92e2ed6bb4fb8c0875f9e33575c4 Mon Sep 17 00:00:00 2001 From: Charles Crossan Date: Tue, 22 Dec 2020 17:44:40 -0500 Subject: [PATCH 07/18] move json delete endpoint --- src/meshwifi/meshhttp.cpp | 55 ++++++++++++++++++++------------------- 1 file changed, 28 insertions(+), 27 deletions(-) diff --git a/src/meshwifi/meshhttp.cpp b/src/meshwifi/meshhttp.cpp index 11d6dfc2..79e7fd89 100644 --- a/src/meshwifi/meshhttp.cpp +++ b/src/meshwifi/meshhttp.cpp @@ -55,13 +55,13 @@ void handleFavicon(HTTPRequest *req, HTTPResponse *res); void handleRoot(HTTPRequest *req, HTTPResponse *res); void handleStaticBrowse(HTTPRequest *req, HTTPResponse *res); void handleStaticPost(HTTPRequest *req, HTTPResponse *res); -void handleStaticDelete(HTTPRequest *req, HTTPResponse *res); void handleStatic(HTTPRequest *req, HTTPResponse *res); void handleRestart(HTTPRequest *req, HTTPResponse *res); void handle404(HTTPRequest *req, HTTPResponse *res); void handleFormUpload(HTTPRequest *req, HTTPResponse *res); void handleScanNetworks(HTTPRequest *req, HTTPResponse *res); void handleSpiffsBrowseStatic(HTTPRequest *req, HTTPResponse *res); +void handleSpiffsDeleteStatic(HTTPRequest *req, HTTPResponse *res); void handleBlinkLED(HTTPRequest *req, HTTPResponse *res); void middlewareSpeedUp240(HTTPRequest *req, HTTPResponse *res, std::function next); @@ -241,7 +241,6 @@ void initWebServer() ResourceNode *nodeRoot = new ResourceNode("/", "GET", &handleRoot); ResourceNode *nodeStaticBrowse = new ResourceNode("/static", "GET", &handleStaticBrowse); ResourceNode *nodeStaticPOST = new ResourceNode("/static", "POST", &handleStaticPost); - ResourceNode *nodeStaticDelete = new ResourceNode("/static", "DELETE", &handleStaticDelete); ResourceNode *nodeStatic = new ResourceNode("/static/*", "GET", &handleStatic); ResourceNode *nodeRestart = new ResourceNode("/restart", "POST", &handleRestart); ResourceNode *node404 = new ResourceNode("", "GET", &handle404); @@ -249,6 +248,7 @@ void initWebServer() ResourceNode *nodeJsonScanNetworks = new ResourceNode("/json/scanNetworks", "GET", &handleScanNetworks); ResourceNode *nodeJsonBlinkLED = new ResourceNode("/json/blink", "POST", &handleBlinkLED); ResourceNode *nodeJsonSpiffsBrowseStatic = new ResourceNode("/json/spiffs/browse/static/", "GET", &handleSpiffsBrowseStatic); + ResourceNode *nodeJsonDelete = new ResourceNode("/json/spiffs/delete/static", "DELETE", &handleSpiffsDeleteStatic); // Secure nodes secureServer->registerNode(nodeAPIv1ToRadioOptions); @@ -259,13 +259,13 @@ void initWebServer() secureServer->registerNode(nodeRoot); secureServer->registerNode(nodeStaticBrowse); secureServer->registerNode(nodeStaticPOST); - secureServer->registerNode(nodeStaticDelete); secureServer->registerNode(nodeStatic); secureServer->registerNode(nodeRestart); secureServer->registerNode(nodeFormUpload); secureServer->registerNode(nodeJsonScanNetworks); secureServer->registerNode(nodeJsonBlinkLED); secureServer->registerNode(nodeJsonSpiffsBrowseStatic); + secureServer->registerNode(nodeJsonDelete); secureServer->setDefaultNode(node404); secureServer->addMiddleware(&middlewareSpeedUp240); @@ -279,13 +279,13 @@ void initWebServer() insecureServer->registerNode(nodeRoot); insecureServer->registerNode(nodeStaticBrowse); insecureServer->registerNode(nodeStaticPOST); - insecureServer->registerNode(nodeStaticDelete); insecureServer->registerNode(nodeStatic); insecureServer->registerNode(nodeRestart); insecureServer->registerNode(nodeFormUpload); insecureServer->registerNode(nodeJsonScanNetworks); insecureServer->registerNode(nodeJsonBlinkLED); insecureServer->registerNode(nodeJsonSpiffsBrowseStatic); + insecureServer->registerNode(nodeJsonDelete); insecureServer->setDefaultNode(node404); insecureServer->addMiddleware(&middlewareSpeedUp160); @@ -393,29 +393,6 @@ void handleStaticPost(HTTPRequest *req, HTTPResponse *res) res->println(""); } -void handleStaticDelete(HTTPRequest *req, HTTPResponse *res) -{ - ResourceParameters *params = req->getParams(); - std::string paramValDelete; - - res->setHeader("Content-Type", "application/json"); - if (params->getQueryParameter("delete", paramValDelete)) { - std::string pathDelete = "/" + paramValDelete; - if (SPIFFS.remove(pathDelete.c_str())) { - Serial.println(pathDelete.c_str()); - res->println("{"); - res->println("\"status\": \"ok\""); - res->println("}"); - return; - } else { - Serial.println(pathDelete.c_str()); - res->println("{"); - res->println("\"status\": \"Error\""); - res->println("}"); - return; - } - } -} void handleSpiffsBrowseStatic(HTTPRequest *req, HTTPResponse *res) @@ -472,6 +449,30 @@ void handleSpiffsBrowseStatic(HTTPRequest *req, HTTPResponse *res) } } +void handleSpiffsDeleteStatic(HTTPRequest *req, HTTPResponse *res) +{ + ResourceParameters *params = req->getParams(); + std::string paramValDelete; + + res->setHeader("Content-Type", "application/json"); + if (params->getQueryParameter("delete", paramValDelete)) { + std::string pathDelete = "/" + paramValDelete; + if (SPIFFS.remove(pathDelete.c_str())) { + Serial.println(pathDelete.c_str()); + res->println("{"); + res->println("\"status\": \"ok\""); + res->println("}"); + return; + } else { + Serial.println(pathDelete.c_str()); + res->println("{"); + res->println("\"status\": \"Error\""); + res->println("}"); + return; + } + } +} + void handleStaticBrowse(HTTPRequest *req, HTTPResponse *res) { // Get access to the parameters From 8e0c2248138138e6a4d6273310f3e2ae020e7914 Mon Sep 17 00:00:00 2001 From: Charles Crossan Date: Tue, 22 Dec 2020 17:47:24 -0500 Subject: [PATCH 08/18] remove extra whitespace --- src/meshwifi/meshhttp.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/meshwifi/meshhttp.cpp b/src/meshwifi/meshhttp.cpp index 79e7fd89..a0183f34 100644 --- a/src/meshwifi/meshhttp.cpp +++ b/src/meshwifi/meshhttp.cpp @@ -393,8 +393,6 @@ void handleStaticPost(HTTPRequest *req, HTTPResponse *res) res->println(""); } - - void handleSpiffsBrowseStatic(HTTPRequest *req, HTTPResponse *res) { // jm From 877dc824a9979ab81dd5b76bbe506a9f7531b2c9 Mon Sep 17 00:00:00 2001 From: Jm Date: Tue, 22 Dec 2020 22:26:08 -0800 Subject: [PATCH 09/18] #407 - Fix for wifi does not come back up after power down --- platformio.ini | 2 +- src/meshwifi/meshwifi.cpp | 21 +++++++++++++++------ 2 files changed, 16 insertions(+), 7 deletions(-) diff --git a/platformio.ini b/platformio.ini index 015aa105..327c5d6c 100644 --- a/platformio.ini +++ b/platformio.ini @@ -103,7 +103,7 @@ lib_deps = # board_build.ldscript = linker/esp32.extram.bss.ld lib_ignore = segger_rtt platform_packages = - framework-arduinoespressif32@https://github.com/meshtastic/arduino-esp32.git#2814f110aa618429bdd9a0a2d6a93c55f29f87a6 + framework-arduinoespressif32@https://github.com/meshtastic/arduino-esp32.git#c29e0bcde1b1b4a939dd7339dea0302d2d589ae7 ; customize the partition table ; http://docs.platformio.org/en/latest/platforms/espressif32.html#partition-tables diff --git a/src/meshwifi/meshwifi.cpp b/src/meshwifi/meshwifi.cpp index 16ae6185..54358077 100644 --- a/src/meshwifi/meshwifi.cpp +++ b/src/meshwifi/meshwifi.cpp @@ -40,12 +40,14 @@ bool isWifiAvailable() const char *wifiName = radioConfig.preferences.wifi_ssid; const char *wifiPsw = radioConfig.preferences.wifi_password; - // strcpy(radioConfig.preferences.wifi_ssid, ""); - // strcpy(radioConfig.preferences.wifi_password, ""); + // strcpy(radioConfig.preferences.wifi_ssid, "meshtastic"); + // strcpy(radioConfig.preferences.wifi_password, "meshtastic!"); // strcpy(radioConfig.preferences.wifi_ssid, "meshtasticAdmin"); // strcpy(radioConfig.preferences.wifi_password, "12345678"); + // radioConfig.preferences.wifi_ap_mode = true; + // radioConfig.preferences.wifi_ap_mode = false; if (*wifiName && *wifiPsw) { return 1; @@ -221,9 +223,16 @@ static void WiFiEvent(WiFiEvent_t event) DEBUG_MSG("Obtained IP address: \n"); Serial.println(WiFi.localIP()); - // Start web server - initWebServer(); - initApiServer(); + if (!APStartupComplete) { + // Start web server + DEBUG_MSG("... Starting network services\n"); + initWebServer(); + initApiServer(); + + APStartupComplete = true; + } else { + DEBUG_MSG("... Not starting network services (They're already running)\n"); + } break; case SYSTEM_EVENT_STA_LOST_IP: @@ -253,7 +262,7 @@ static void WiFiEvent(WiFiEvent_t event) APStartupComplete = true; } else { - DEBUG_MSG("... Not starting network services\n"); + DEBUG_MSG("... Not starting network services (They're already running)\n"); } break; From bacc1b1dad83611c7f044cfa7d6f42b797c1dcb4 Mon Sep 17 00:00:00 2001 From: Jm Date: Tue, 22 Dec 2020 22:37:34 -0800 Subject: [PATCH 10/18] #581 - Quiet a compile time warning I introduced. --- src/PowerFSM.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/PowerFSM.cpp b/src/PowerFSM.cpp index be1ace0d..20ad6625 100644 --- a/src/PowerFSM.cpp +++ b/src/PowerFSM.cpp @@ -179,7 +179,7 @@ void PowerFSM_setup() 1) If we're powered up and there's no battery, we must be getting power externally. 2) If we detect USB power from the power management chip, we must be getting power externally. */ - bool hasPower = (powerStatus && !powerStatus->getHasBattery()) || !isLowPower && powerStatus && powerStatus->getHasUSB(); + bool hasPower = (powerStatus && !powerStatus->getHasBattery()) || (!isLowPower && powerStatus && powerStatus->getHasUSB()); bool isRouter = radioConfig.preferences.is_router; DEBUG_MSG("PowerFSM init, USB power=%d\n", hasPower); powerFSM.add_timed_transition(&stateBOOT, hasPower ? &statePOWER : &stateON, 3 * 1000, NULL, "boot timeout"); From 35b1cfcc42d8613373db9bc45d98467f17f25089 Mon Sep 17 00:00:00 2001 From: Jm Date: Tue, 22 Dec 2020 23:15:09 -0800 Subject: [PATCH 11/18] #554 Keep radio turned on if we're contacted over http(s) while on battery power. --- src/meshwifi/meshhttp.cpp | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/meshwifi/meshhttp.cpp b/src/meshwifi/meshhttp.cpp index a0183f34..0e2e5687 100644 --- a/src/meshwifi/meshhttp.cpp +++ b/src/meshwifi/meshhttp.cpp @@ -4,6 +4,7 @@ #include "main.h" #include "meshhttpStatic.h" #include "meshwifi/meshwifi.h" +#include "PowerFSM.h" #include "sleep.h" #include #include @@ -306,6 +307,10 @@ void middlewareSpeedUp240(HTTPRequest *req, HTTPResponse *res, std::function Date: Wed, 23 Dec 2020 17:12:48 +0800 Subject: [PATCH 12/18] remove logspam that was busting serial api --- docs/software/TODO.md | 1 - src/mesh/PhoneAPI.cpp | 4 ++-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/docs/software/TODO.md b/docs/software/TODO.md index 73df45a6..f96d2acb 100644 --- a/docs/software/TODO.md +++ b/docs/software/TODO.md @@ -38,7 +38,6 @@ For app cleanup: * fix the RTC drift bug * move python ping functionality into device, reply with rxsnr info * use channels for gpio security https://github.com/meshtastic/Meshtastic-device/issues/104 -* generate autodocs * MeshPackets for sending should be reference counted so that API clients would have the option of checking sent status (would allow removing the nasty 30 sec timer in gpio watch sending) For high speed/lots of devices/short range tasks: diff --git a/src/mesh/PhoneAPI.cpp b/src/mesh/PhoneAPI.cpp index e122c45c..754f0d38 100644 --- a/src/mesh/PhoneAPI.cpp +++ b/src/mesh/PhoneAPI.cpp @@ -100,7 +100,7 @@ void PhoneAPI::handleToRadio(const uint8_t *buf, size_t bufLength) size_t PhoneAPI::getFromRadio(uint8_t *buf) { if (!available()) { - DEBUG_MSG("getFromRadio, !available\n"); + // DEBUG_MSG("getFromRadio, !available\n"); return 0; } @@ -226,7 +226,7 @@ bool PhoneAPI::available() if (!packetForPhone) packetForPhone = service.getForPhone(); bool hasPacket = !!packetForPhone; - DEBUG_MSG("available hasPacket=%d\n", hasPacket); + // DEBUG_MSG("available hasPacket=%d\n", hasPacket); return hasPacket; } From 901ff6bb1ea0e9415071ca3cf428ac1136d7feb5 Mon Sep 17 00:00:00 2001 From: Kevin Hester Date: Fri, 25 Dec 2020 10:16:49 +0800 Subject: [PATCH 13/18] bug #587 try to work with old (2.x?) versions of python --- bin/platformio-custom.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bin/platformio-custom.py b/bin/platformio-custom.py index d56cc09f..ec9dd454 100644 --- a/bin/platformio-custom.py +++ b/bin/platformio-custom.py @@ -8,7 +8,7 @@ config.read(prefsLoc) version = dict(config.items('VERSION')) verStr = "{}.{}.{}".format(version["major"], version["minor"], version["build"]) -print(f"Using meshtastic platform-custom.py, firmare version {verStr}") +print("Using meshtastic platform-custom.py, firmare version " + verStr) # General options that are passed to the C and C++ compilers projenv.Append(CCFLAGS=[ From dda5568e2c688c5f815941b820645789176e080d Mon Sep 17 00:00:00 2001 From: Kevin Hester Date: Fri, 25 Dec 2020 11:14:00 +0800 Subject: [PATCH 14/18] update arduino lib & esp bins to fix #584 --- docs/software/esp32-arduino-build-notes.md | 8 +++++++- platformio.ini | 2 +- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/docs/software/esp32-arduino-build-notes.md b/docs/software/esp32-arduino-build-notes.md index 94b64f62..1b5a5da0 100644 --- a/docs/software/esp32-arduino-build-notes.md +++ b/docs/software/esp32-arduino-build-notes.md @@ -10,7 +10,7 @@ you'll automatically get our fixed libraries. IDF release/v3.3 46b12a560 IDF release/v3.3 367c3c09c https://docs.espressif.com/projects/esp-idf/en/release-v3.3/get-started/linux-setup.html - kevinh@kevin-server:~/development/meshtastic/esp32-arduino-lib-builder\$ python /home/kevinh/development/meshtastic/esp32-arduino-lib-builder/esp-idf/components/esptool*py/esptool/esptool.py --chip esp32 --port /dev/ttyUSB0 --baud 921600 --before default_reset --after hard_reset write_flash -z --flash_mode dout --flash_freq 40m --flash_size detect 0x1000 /home/kevinh/development/meshtastic/esp32-arduino-lib-builder/build/bootloader/bootloader.bin + kevinh@kevin-server:~/development/meshtastic/esp32-arduino-lib-builder\$ python /home/kevinh/development/meshtastic/ cp -a out/tools/sdk/* components/arduino/tools/sdk cp -ar components/arduino/* ~/.platformio/packages/framework-arduinoespressif32 @@ -21,3 +21,9 @@ you'll automatically get our fixed libraries. cp -ar out/tools/sdk/* ~/.platformio/packages/framework-arduinoespressif32/tools/sdk ``` + +How to flash new bootloader + +``` +esp32-arduino-lib-builder/esp-idf/components/esptool*py/esptool/esptool.py --chip esp32 --port /dev/ttyUSB0 --baud 921600 --before default_reset --after hard_reset write_flash -z --flash_mode dout --flash_freq 40m --flash_size detect 0x1000 /home/kevinh/development/meshtastic/esp32-arduino-lib-builder/build/bootloader/bootloader.bin +``` diff --git a/platformio.ini b/platformio.ini index 327c5d6c..50d381c8 100644 --- a/platformio.ini +++ b/platformio.ini @@ -103,7 +103,7 @@ lib_deps = # board_build.ldscript = linker/esp32.extram.bss.ld lib_ignore = segger_rtt platform_packages = - framework-arduinoespressif32@https://github.com/meshtastic/arduino-esp32.git#c29e0bcde1b1b4a939dd7339dea0302d2d589ae7 + framework-arduinoespressif32@https://github.com/meshtastic/arduino-esp32.git#352c8ea7cb73f10433ed139f34251979c470ad56 ; customize the partition table ; http://docs.platformio.org/en/latest/platforms/espressif32.html#partition-tables From c349ad62e73f9ad314e086806802c012ba9e414d Mon Sep 17 00:00:00 2001 From: Kevin Hester Date: Fri, 25 Dec 2020 14:53:33 +0800 Subject: [PATCH 15/18] we set randomSeed at boot so I think probably not good to do again cool @mc-hamster? --- src/meshwifi/meshhttp.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/meshwifi/meshhttp.cpp b/src/meshwifi/meshhttp.cpp index a0183f34..401cb86d 100644 --- a/src/meshwifi/meshhttp.cpp +++ b/src/meshwifi/meshhttp.cpp @@ -940,8 +940,6 @@ void handleRoot(HTTPRequest *req, HTTPResponse *res) { res->setHeader("Content-Type", "text/html"); - randomSeed(millis()); - res->setHeader("Set-Cookie", "mt_session=" + httpsserver::intToString(random(1, 9999999)) + "; Expires=Wed, 20 Apr 2049 4:20:00 PST"); From 59577b9d7930ec7262e8aa180e3d6dbaa2b99d3b Mon Sep 17 00:00:00 2001 From: Kevin Hester Date: Fri, 25 Dec 2020 15:17:56 +0800 Subject: [PATCH 16/18] add real formatted debug logging with timestamps --- src/RedirectablePrint.cpp | 75 ++++++++++++++++++++++++++++++++++++ src/RedirectablePrint.h | 23 +++++++++++ src/concurrency/OSThread.cpp | 5 +++ src/concurrency/OSThread.h | 4 ++ src/configuration.h | 2 +- 5 files changed, 108 insertions(+), 1 deletion(-) diff --git a/src/RedirectablePrint.cpp b/src/RedirectablePrint.cpp index 0205aa66..541b55c7 100644 --- a/src/RedirectablePrint.cpp +++ b/src/RedirectablePrint.cpp @@ -1,6 +1,9 @@ #include "RedirectablePrint.h" #include "configuration.h" #include +#include +#include +#include "concurrency/OSThread.h" /** * A printer that doesn't go anywhere @@ -15,10 +18,82 @@ void RedirectablePrint::setDestination(Print *_dest) size_t RedirectablePrint::write(uint8_t c) { + // Always send the characters to our segger JTAG debugger #ifdef SEGGER_STDOUT_CH SEGGER_RTT_PutCharSkip(SEGGER_STDOUT_CH, c); #endif dest->write(c); return 1; // We always claim one was written, rather than trusting what the serial port said (which could be zero) +} + +size_t RedirectablePrint::vprintf(const char *format, va_list arg) +{ + va_list copy; + + va_copy(copy, arg); + int len = vsnprintf(printBuf, printBufLen, format, copy); + va_end(copy); + if (len < 0) { + va_end(arg); + return 0; + }; + if (len >= printBufLen) { + delete[] printBuf; + printBufLen *= 2; + printBuf = new char[printBufLen]; + len = vsnprintf(printBuf, printBufLen, format, arg); + } + + len = Print::write(printBuf, len); + return len; +} + +#define SEC_PER_DAY 86400 +#define SEC_PER_HOUR 3600 +#define SEC_PER_MIN 60 + +size_t RedirectablePrint::logDebug(const char *format, ...) +{ + va_list arg; + va_start(arg, format); + + // Cope with 0 len format strings, but look for new line terminator + bool hasNewline = *format && format[strlen(format) - 1] == '\n'; + + size_t r = 0; + + // If we are the first message on a report, include the header + if (!isContinuationMessage) { + struct timeval tv; + if (!gettimeofday(&tv, NULL)) { + long hms = tv.tv_sec % SEC_PER_DAY; + //hms += tz.tz_dsttime * SEC_PER_HOUR; + //hms -= tz.tz_minuteswest * SEC_PER_MIN; + // mod `hms` to ensure in positive range of [0...SEC_PER_DAY) + hms = (hms + SEC_PER_DAY) % SEC_PER_DAY; + + // Tear apart hms into h:m:s + int hour = hms / SEC_PER_HOUR; + int min = (hms % SEC_PER_HOUR) / SEC_PER_MIN; + int sec = (hms % SEC_PER_HOUR) % SEC_PER_MIN; // or hms % SEC_PER_MIN + + r += printf("%02d:%02d:%02d ", hour, min, sec); + } else + r += printf("??:??:?? "); + + auto thread = concurrency::OSThread::currentThread; + if(thread) { + print("["); + print(thread->ThreadName); + print("] "); + } + } + + r += vprintf(format, arg); + va_end(arg); + + isContinuationMessage = !hasNewline; + + return r; } \ No newline at end of file diff --git a/src/RedirectablePrint.h b/src/RedirectablePrint.h index 2d525118..ca208612 100644 --- a/src/RedirectablePrint.h +++ b/src/RedirectablePrint.h @@ -1,6 +1,7 @@ #pragma once #include +#include /** * A Printable that can be switched to squirt its bytes to a different sink. @@ -11,6 +12,13 @@ class RedirectablePrint : public Print { Print *dest; + /// We dynamically grow this scratch buffer if necessary + char *printBuf = new char[64]; + size_t printBufLen = 64; + + /// Used to allow multiple logDebug messages to appear on a single log line + bool isContinuationMessage = false; + public: RedirectablePrint(Print *_dest) : dest(_dest) {} @@ -20,6 +28,21 @@ class RedirectablePrint : public Print void setDestination(Print *dest); virtual size_t write(uint8_t c); + + /** + * Debug logging print message + * + * If the provide format string ends with a newline we assume it is the final print of a single + * log message. Otherwise we assume more prints will come before the log message ends. This + * allows you to call logDebug a few times to build up a single log message line if you wish. + * + * FIXME, eventually add log levels (INFO, WARN, ERROR) and subsystems. Move into + * a different class. + */ + size_t logDebug(const char * format, ...) __attribute__ ((format (printf, 2, 3))); + + /** like printf but va_list based */ + size_t vprintf(const char *format, va_list arg); }; class NoopPrint : public Print diff --git a/src/concurrency/OSThread.cpp b/src/concurrency/OSThread.cpp index 916e68e1..58a0d59c 100644 --- a/src/concurrency/OSThread.cpp +++ b/src/concurrency/OSThread.cpp @@ -14,6 +14,8 @@ bool OSThread::showRun = false; /// Show debugging info for threads we decide not to run; bool OSThread::showWaiting = false; +const OSThread *OSThread::currentThread; + ThreadController mainController, timerController; InterruptableDelay mainDelay; @@ -68,12 +70,15 @@ bool OSThread::shouldRun(unsigned long time) void OSThread::run() { + currentThread = this; auto newDelay = runOnce(); runned(); if (newDelay >= 0) setInterval(newDelay); + + currentThread = NULL; } } // namespace concurrency diff --git a/src/concurrency/OSThread.h b/src/concurrency/OSThread.h index dc600387..3be149d5 100644 --- a/src/concurrency/OSThread.h +++ b/src/concurrency/OSThread.h @@ -42,6 +42,10 @@ class OSThread : public Thread static bool showWaiting; public: + + /// For debug printing only (might be null) + static const OSThread *currentThread; + OSThread(const char *name, uint32_t period = 0, ThreadController *controller = &mainController); virtual ~OSThread(); diff --git a/src/configuration.h b/src/configuration.h index 28eea052..6fa07ce6 100644 --- a/src/configuration.h +++ b/src/configuration.h @@ -428,7 +428,7 @@ along with this program. If not, see . #define DEBUG_MSG(...) SEGGER_RTT_printf(0, __VA_ARGS__) #else #ifdef DEBUG_PORT -#define DEBUG_MSG(...) DEBUG_PORT.printf(__VA_ARGS__) +#define DEBUG_MSG(...) DEBUG_PORT.logDebug(__VA_ARGS__) #else #define DEBUG_MSG(...) #endif From f45451ca74312b81841844b324b35d51f3fd28b4 Mon Sep 17 00:00:00 2001 From: Kevin Hester Date: Fri, 25 Dec 2020 15:31:17 +0800 Subject: [PATCH 17/18] missing line term --- src/graphics/Screen.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/graphics/Screen.cpp b/src/graphics/Screen.cpp index 3f98969d..8cc8ebe2 100644 --- a/src/graphics/Screen.cpp +++ b/src/graphics/Screen.cpp @@ -912,7 +912,7 @@ void Screen::blink() { void Screen::handlePrint(const char *text) { - DEBUG_MSG("Screen: %s", text); + DEBUG_MSG("Screen: %s\n", text); if (!useDisplay || !showingNormalScreen) return; From 3c2aac87f7bd94cd492f13652e8de87295a7487f Mon Sep 17 00:00:00 2001 From: Kevin Hester Date: Fri, 25 Dec 2020 15:39:42 +0800 Subject: [PATCH 18/18] better fix for screen messages in log --- src/graphics/Screen.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/graphics/Screen.cpp b/src/graphics/Screen.cpp index 8cc8ebe2..ecaa216f 100644 --- a/src/graphics/Screen.cpp +++ b/src/graphics/Screen.cpp @@ -912,7 +912,9 @@ void Screen::blink() { void Screen::handlePrint(const char *text) { - DEBUG_MSG("Screen: %s\n", text); + // the string passed into us probably has a newline, but that would confuse the logging system + // so strip it + DEBUG_MSG("Screen: %.*s\n", strlen(text) - 1, text); if (!useDisplay || !showingNormalScreen) return;