From 92a62d93ef0e93072493ea4009c844e01a377eec Mon Sep 17 00:00:00 2001 From: Jm Casler Date: Sat, 13 Feb 2021 22:21:01 -0800 Subject: [PATCH 01/25] #671 Rangetest - This just needs to be tested. --- src/plugins/RangeTestPlugin.cpp | 137 +++++++++++++++++++++++++++++++- src/plugins/RangeTestPlugin.h | 11 ++- 2 files changed, 144 insertions(+), 4 deletions(-) diff --git a/src/plugins/RangeTestPlugin.cpp b/src/plugins/RangeTestPlugin.cpp index 8f03589c2..c719ad04c 100644 --- a/src/plugins/RangeTestPlugin.cpp +++ b/src/plugins/RangeTestPlugin.cpp @@ -5,13 +5,13 @@ #include "Router.h" #include "configuration.h" #include +#include #include /* As a sender, I can send packets every n-seonds. These packets include an incramented PacketID. As a receiver, I can receive packets from multiple senders. These packets can be saved to the spiffs. - */ RangeTestPlugin *rangeTestPlugin; @@ -19,9 +19,11 @@ RangeTestPluginRadio *rangeTestPluginRadio; RangeTestPlugin::RangeTestPlugin() : concurrency::OSThread("RangeTestPlugin") {} -uint16_t packetSequence = 0; +uint32_t packetSequence = 0; -// char serialStringChar[Constants_DATA_PAYLOAD_LEN]; +#define SEC_PER_DAY 86400 +#define SEC_PER_HOUR 3600 +#define SEC_PER_MIN 60 int32_t RangeTestPlugin::runOnce() { @@ -34,8 +36,12 @@ int32_t RangeTestPlugin::runOnce() // radioConfig.preferences.range_test_plugin_enabled = 1; // radioConfig.preferences.range_test_plugin_sender = 0; + // radioConfig.preferences.range_test_plugin_save = 1; + + // Fixed position is useful when testing indoors. // radioConfig.preferences.fixed_position = 1; + uint32_t senderHeartbeat = radioConfig.preferences.range_test_plugin_sender * 1000; if (radioConfig.preferences.range_test_plugin_enabled) { @@ -137,6 +143,9 @@ bool RangeTestPluginRadio::handleReceived(const MeshPacket &mp) NodeInfo *n = nodeDB.getNode(mp.from); + if (radioConfig.preferences.range_test_plugin_save) { + appendFile(mp); + } DEBUG_MSG("-----------------------------------------\n"); DEBUG_MSG("p.payload.bytes \"%s\"\n", p.payload.bytes); @@ -171,3 +180,125 @@ bool RangeTestPluginRadio::handleReceived(const MeshPacket &mp) return true; // Let others look at this message also if they want } + +/// Ported from my old java code, returns distance in meters along the globe +/// surface (by magic?) +float RangeTestPluginRadio::latLongToMeter(double lat_a, double lng_a, double lat_b, double lng_b) +{ + double pk = (180 / 3.14169); + double a1 = lat_a / pk; + double a2 = lng_a / pk; + double b1 = lat_b / pk; + double b2 = lng_b / pk; + double cos_b1 = cos(b1); + double cos_a1 = cos(a1); + double t1 = cos_a1 * cos(a2) * cos_b1 * cos(b2); + double t2 = cos_a1 * sin(a2) * cos_b1 * sin(b2); + double t3 = sin(a1) * sin(b1); + double tt = acos(t1 + t2 + t3); + if (isnan(tt)) + tt = 0.0; // Must have been the same point? + + return (float)(6366000 * tt); +} + +bool RangeTestPluginRadio::appendFile(const MeshPacket &mp) +{ + auto &p = mp.decoded.data; + + NodeInfo *n = nodeDB.getNode(mp.from); + /* + DEBUG_MSG("-----------------------------------------\n"); + DEBUG_MSG("p.payload.bytes \"%s\"\n", p.payload.bytes); + DEBUG_MSG("p.payload.size %d\n", p.payload.size); + DEBUG_MSG("---- Received Packet:\n"); + DEBUG_MSG("mp.from %d\n", mp.from); + DEBUG_MSG("mp.rx_snr %f\n", mp.rx_snr); + DEBUG_MSG("mp.hop_limit %d\n", mp.hop_limit); + // DEBUG_MSG("mp.decoded.position.latitude_i %d\n", mp.decoded.position.latitude_i); // Depricated + // DEBUG_MSG("mp.decoded.position.longitude_i %d\n", mp.decoded.position.longitude_i); // Depricated + DEBUG_MSG("---- Node Information of Received Packet (mp.from):\n"); + DEBUG_MSG("n->user.long_name %s\n", n->user.long_name); + DEBUG_MSG("n->user.short_name %s\n", n->user.short_name); + DEBUG_MSG("n->user.macaddr %X\n", n->user.macaddr); + DEBUG_MSG("n->has_position %d\n", n->has_position); + DEBUG_MSG("n->position.latitude_i %d\n", n->position.latitude_i); + DEBUG_MSG("n->position.longitude_i %d\n", n->position.longitude_i); + DEBUG_MSG("n->position.battery_level %d\n", n->position.battery_level); + DEBUG_MSG("---- Current device location information:\n"); + DEBUG_MSG("gpsStatus->getLatitude() %d\n", gpsStatus->getLatitude()); + DEBUG_MSG("gpsStatus->getLongitude() %d\n", gpsStatus->getLongitude()); + DEBUG_MSG("gpsStatus->getHasLock() %d\n", gpsStatus->getHasLock()); + DEBUG_MSG("gpsStatus->getDOP() %d\n", gpsStatus->getDOP()); + DEBUG_MSG("-----------------------------------------\n"); + */ + if (!SPIFFS.begin(true)) { + DEBUG_MSG("An Error has occurred while mounting SPIFFS\n"); + return 0; + } + + if (SPIFFS.totalBytes() - SPIFFS.usedBytes() < 51200) { + DEBUG_MSG("SPIFFS doesn't have enough free space. Abourting write.\n"); + return 0; + } + + //--------- Write to file + File fileToWrite = SPIFFS.open("/static/rangetest.csv", FILE_WRITE); + + if (!fileToWrite) { + DEBUG_MSG("There was an error opening the file for writing\n"); + return 0; + } + + if (fileToWrite.println("time,sender mac,rx snr,sender lat,sender long,rx lat,rx long,distance,payload")) { + DEBUG_MSG("File was written\n"); + } else { + DEBUG_MSG("File write failed\n"); + } + + fileToWrite.close(); + + //--------- Apend content to file + File fileToAppend = SPIFFS.open("/static/rangetest.csv", FILE_APPEND); + + if (!fileToAppend) { + DEBUG_MSG("There was an error opening the file for appending\n"); + return 0; + } + + 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 + + fileToAppend.printf("%02d:%02d:%02d ", hour, min, sec); // Time + } else { + fileToAppend.printf("??:??:?? "); // Time + } + + fileToAppend.printf("$X,", n->user.macaddr); // Mac Address + fileToAppend.printf("%f,", mp.rx_snr); // RX SNR + fileToAppend.printf("%d,", n->position.latitude_i); // Sender Lat + fileToAppend.printf("%d,", n->position.longitude_i); // Sender Long + fileToAppend.printf("%d,", gpsStatus->getLatitude()); // RX Lat + fileToAppend.printf("%d,", gpsStatus->getLongitude()); // RX Long + + float distance = latLongToMeter(n->position.latitude_i * 1e-7, n->position.longitude_i * 1e-7, + gpsStatus->getLatitude() * 1e-7, gpsStatus->getLongitude() * 1e-7); + fileToAppend.printf("%f,", distance); // Distance in meters + + // TODO: If quotes are found in the payload, it has to be escaped. + fileToAppend.printf("\"%s\"\n", p.payload.bytes); + + fileToAppend.close(); + + return 1; +} diff --git a/src/plugins/RangeTestPlugin.h b/src/plugins/RangeTestPlugin.h index f66744dbd..8a10ca395 100644 --- a/src/plugins/RangeTestPlugin.h +++ b/src/plugins/RangeTestPlugin.h @@ -28,7 +28,6 @@ class RangeTestPluginRadio : public SinglePortPlugin uint32_t lastRxID; public: - RangeTestPluginRadio() : SinglePortPlugin("RangeTestPluginRadio", PortNum_TEXT_MESSAGE_APP) {} /** @@ -36,6 +35,16 @@ class RangeTestPluginRadio : public SinglePortPlugin */ void sendPayload(NodeNum dest = NODENUM_BROADCAST, bool wantReplies = false); + /** + * Append range test data to the file on the spiffs + */ + bool appendFile(const MeshPacket &mp); + + /** + * Kevin's magical calculation of two points to meters. + */ + float latLongToMeter(double lat_a, double lng_a, double lat_b, double lng_b); + protected: virtual MeshPacket *allocReply(); From 36643cf5f543e5e114daf2c400bfc16816c9ed3e Mon Sep 17 00:00:00 2001 From: Jm Casler Date: Sat, 13 Feb 2021 22:40:04 -0800 Subject: [PATCH 02/25] #671 range test plugin documentation #671 range test plugin documentation --- docs/software/plugins/RangeTestPlugin.md | 54 ++++++++++++++++++++++++ 1 file changed, 54 insertions(+) create mode 100644 docs/software/plugins/RangeTestPlugin.md diff --git a/docs/software/plugins/RangeTestPlugin.md b/docs/software/plugins/RangeTestPlugin.md new file mode 100644 index 000000000..9fd9b2724 --- /dev/null +++ b/docs/software/plugins/RangeTestPlugin.md @@ -0,0 +1,54 @@ +# About + +The RangeTest Plugin will help you perform range and coverage tests. + +# Configuration + +These are the settings that can be configured. + + range_test_plugin_enabled + Is the plugin enabled? + + 0 = Disabled (Default) + 1 = Enabled + + range_test_plugin_save + If enabled, we will save a log of all received messages to /static/rangetest.csv which you can access from the webserver. We will abort + writing if there is less than 50k of space on the filesystem to prevent filling up the storage. + + 0 = Disabled (Default) + 1 = Enabled + + range_test_plugin_sender + Number of seconds to wait between sending packets. Using the long_slow channel configuration, it's best not to go more frequent than once every 60 seconds. You can be more agressive with faster settings. 0 is default which disables sending messages. + +# Usage Notes + +For basic usage, you will need two devices both with a GPS. A device with a paired phone with GPS may work, I have not tried it. + +The first thing to do is to turn on the plugin. With the plugin turned on, the other settings will be available: + + range_test_plugin_enabled = 1 + +If you want to send a message every 60 seconds: + + range_test_plugin_sender = 60 + +To save a log of the messages: + + range_test_plugin_save = 1 + + +# Known Problems + +* If turned on, using mesh network will become unwieldly because messages are sent over the same channel as the other messages. See TODO below. + +# TODO + +* Right now range test messages go over the TEXT_MESSAGE_APP port. We need a toggle to switch to RANGE_TEST_APP. + +# Need more help? + +Go to the Meshtastic Discourse Group if you have any questions or to share how you have used this. + +https://meshtastic.discourse.group From 3201d1c3bcc636feade1f82f74a5afdb20d9248c Mon Sep 17 00:00:00 2001 From: Jm Casler Date: Sun, 14 Feb 2021 08:44:49 -0800 Subject: [PATCH 03/25] #668 Partial work for store & forward --- src/plugins/StoreForwardPlugin.cpp | 54 +++++++----------------------- src/plugins/StoreForwardPlugin.h | 3 ++ 2 files changed, 15 insertions(+), 42 deletions(-) diff --git a/src/plugins/StoreForwardPlugin.cpp b/src/plugins/StoreForwardPlugin.cpp index f71fb965b..c82724560 100644 --- a/src/plugins/StoreForwardPlugin.cpp +++ b/src/plugins/StoreForwardPlugin.cpp @@ -8,22 +8,14 @@ #include -#define STORE_RECORDS 5000 -#define BYTES_PER_RECORDS 512 - -struct sfRecord -{ - uint8_t bytes[BYTES_PER_RECORDS]; - uint32_t timestamp; // Time the packet was received -}; - -struct sfRecord records[STORE_RECORDS]; +#define STORE_RECORDS 5000 +#define BYTES_PER_RECORDS 512 #define STOREFORWARDPLUGIN_ENABLED 0 StoreForwardPlugin *storeForwardPlugin; StoreForwardPluginRadio *storeForwardPluginRadio; - + StoreForwardPlugin::StoreForwardPlugin() : concurrency::OSThread("SerialPlugin") {} // char serialStringChar[Constants_DATA_PAYLOAD_LEN]; @@ -37,8 +29,8 @@ int32_t StoreForwardPlugin::runOnce() without having to configure it from the PythonAPI or WebUI. */ - //radioConfig.preferences.store_forward_plugin_enabled = 1; - //radioConfig.preferences.store_forward_plugin_records = 80; + // radioConfig.preferences.store_forward_plugin_enabled = 1; + // radioConfig.preferences.store_forward_plugin_records = 80; if (radioConfig.preferences.store_forward_plugin_enabled) { @@ -67,9 +59,8 @@ int32_t StoreForwardPlugin::runOnce() return (INT32_MAX); } - // Non-Router + // Non-Router } else { - } storeForwardPluginRadio = new StoreForwardPluginRadio(); @@ -104,7 +95,7 @@ void StoreForwardPluginRadio::sendPayload(NodeNum dest, bool wantReplies) p->to = dest; p->decoded.want_response = wantReplies; - //p->want_ack = SERIALPLUGIN_ACK; + // p->want_ack = SERIALPLUGIN_ACK; // p->decoded.data.payload.size = strlen(serialStringChar); // You must specify how many bytes are in the reply // memcpy(p->decoded.data.payload.bytes, serialStringChar, p->decoded.data.payload.size); @@ -118,36 +109,15 @@ bool StoreForwardPluginRadio::handleReceived(const MeshPacket &mp) if (STOREFORWARDPLUGIN_ENABLED) { - auto &p = mp.decoded.data; - // DEBUG_MSG("Received text msg self=0x%0x, from=0x%0x, to=0x%0x, id=%d, msg=%.*s\n", - // nodeDB.getNodeNum(), mp.from, mp.to, mp.id, p.payload.size, p.payload.bytes); + // auto &p = mp.decoded.data; - if (mp.from == nodeDB.getNodeNum()) { - - /* - * If radioConfig.preferences.serialplugin_echo is true, then echo the packets that are sent out back to the TX - * of the serial interface. - */ - if (radioConfig.preferences.serialplugin_echo) { - - // For some reason, we get the packet back twice when we send out of the radio. - // TODO: need to find out why. - if (lastRxID != mp.id) { - lastRxID = mp.id; - // DEBUG_MSG("* * Message came this device\n"); - // Serial2.println("* * Message came this device"); - Serial2.printf("%s", p.payload.bytes); - } - } - - } else { - // DEBUG_MSG("* * Message came from the mesh\n"); - // Serial2.println("* * Message came from the mesh"); - Serial2.printf("%s", p.payload.bytes); + if (mp.from != nodeDB.getNodeNum()) { + DEBUG_MSG("Store & Forward Plugin ---------- ---------- ---------- ---------- ----------\n"); + printPacket("PACKET FROM PHONE", &mp); } } else { - DEBUG_MSG("Serial Plugin Disabled\n"); + DEBUG_MSG("Store & Forward Plugin - Disabled\n"); } #endif diff --git a/src/plugins/StoreForwardPlugin.h b/src/plugins/StoreForwardPlugin.h index e9dac9b45..952206c58 100644 --- a/src/plugins/StoreForwardPlugin.h +++ b/src/plugins/StoreForwardPlugin.h @@ -34,6 +34,7 @@ class StoreForwardPluginRadio : public SinglePortPlugin */ // SerialPluginRadio() : SinglePortPlugin("SerialPluginRadio", PortNum_TEXT_MESSAGE_APP) {} + // SerialPluginRadio() : SinglePortPlugin("SerialPluginRadio", PortNum_STORE_FORWARD_APP) {} StoreForwardPluginRadio() : SinglePortPlugin("SerialPluginRadio", PortNum_SERIAL_APP) {} /** @@ -44,6 +45,8 @@ class StoreForwardPluginRadio : public SinglePortPlugin protected: virtual MeshPacket *allocReply(); + virtual bool wantPortnum(PortNum p){return true;}; + /** Called to handle a particular incoming message @return true if you've guaranteed you've handled this message and no other handlers should be considered for it From a95f612452aa4ad2e0e3152858d9a5ffb6213451 Mon Sep 17 00:00:00 2001 From: Jm Date: Sun, 14 Feb 2021 10:56:08 -0800 Subject: [PATCH 04/25] Update StoreForwardPlugin.md --- docs/software/plugins/StoreForwardPlugin.md | 82 +++++++++++++++++++-- 1 file changed, 75 insertions(+), 7 deletions(-) diff --git a/docs/software/plugins/StoreForwardPlugin.md b/docs/software/plugins/StoreForwardPlugin.md index 571ac4ed6..3877a0c0f 100644 --- a/docs/software/plugins/StoreForwardPlugin.md +++ b/docs/software/plugins/StoreForwardPlugin.md @@ -1,14 +1,12 @@ # About - This is a work in progress and is not yet available. +This is a work in progress and is not yet available. The Store Request Plugin is an implementation of a Store and Forward system to enable resilient messaging in the event that a client device is disconnected from the main network. -Because of the increased network traffic for this overhead, it's not adviced to use this if you are duty cycle limited for your airtime usage nor is it adviced to use this for SF12. +Because of the increased network traffic for this overhead, it's not adviced to use this if you are duty cycle limited for your airtime usage nor is it adviced to use this for SF12 (Long range but Slow). -# Running notes - -This will only work on nodes that are designated as a Router. +# Requirements Initial Requirements: @@ -17,5 +15,75 @@ Initial Requirements: * * Router nodes are intended to be always online. If this plugin misses any messages, the reliability of the stored messages will be reduced * Esp32 Processor based device with external PSRAM. (tbeam v1.0 and tbeamv1.1, maybe others) -Initial Features -* \ No newline at end of file +# Implementation timeline + +Not necessarily in this order: + +UC 1) MVP - automagically forward packets to a client that may have missed packets. + +UC 2) Client Interface (Web, Android, Python or iOS when that happens) to request packets be resent + +UC 3) router sends a periodic “heartbeat” to let the clients know they’re part of the main mesh + +UC 4) support for a mesh to have multiple routers that have the store & forward functionality (for redundancy) + +# Things to consider + +Not all these cases will be initially implemented. It's just a running stream of thoughts to be considered. + +## Main Mesh Network with Router + +The store and forward plugin is intended to be enabled on a router that designates your "main" mesh network. + +## Store and Forward on Multiple Routers + +If multiple routers with the plugin are enabled, they should be able to share their stored database amongst each other. This enable resilliancy from one router going offline. + +## Fragmented networks - No router + +In this case, the mesh network has been fragmented by two client devices leaving the main network. + +If two Meshtastic devices walk away from the main mesh, they will be able to message each other but not message the main network. When they return to the main network, they will receive the messages they have missed from the main mesh network. + +## Fragmented network - With routers + +In this case, we have two routers separate by a great distance, each serving multiple devices. One of the routers have gone offline. This has now created two physically seaprated mesh networks using the same channel configuration. + +Q: How do we rejoin both fragmented networks? Do we care about messages that were unrouted between fagments? + +# Router Data Structures + +Structure of received messages: + + receivedMessages + Port_No + packetID + to + from + rxTimeMsec + data + +Structure of nodes and last time we heard from them. This is a record of any packet type. + + senderRecord + From + rxTimeMsec + +# General Operation for UC1 - automagically forward packets to a client that may have missed packets + +On every handled packet +* Record the sender from and the time we heard from that sender. + +On every handled packet + +* If the packet is a message, save the messsage into receivedMessages + +On every handled packet, if we have not heard from that sender in a period of time greater than timeAway, let's assume that they have been away from the network. + +* In this case, we will resend them all the messages they have missed since they were gone + +## Expected problems this implementation + +* If the client has been away for less than 5 minutes and has received the previously sent message, the client will gracefully ignore it. This is thanks to PacketHistory::wasSeenRecently in PacketHistory.cpp. +* * If the client has been away for more than 5 minutes and we resend packets that they have already received, it's possible they will see duplicate messages. This should be unlikely but is still possible. + From d5c1e3c6e00bf9a06140761e22bfccf45759c809 Mon Sep 17 00:00:00 2001 From: Jm Date: Sun, 14 Feb 2021 11:00:11 -0800 Subject: [PATCH 05/25] Update StoreForwardPlugin.md --- docs/software/plugins/StoreForwardPlugin.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/docs/software/plugins/StoreForwardPlugin.md b/docs/software/plugins/StoreForwardPlugin.md index 3877a0c0f..97b8f49ee 100644 --- a/docs/software/plugins/StoreForwardPlugin.md +++ b/docs/software/plugins/StoreForwardPlugin.md @@ -72,7 +72,7 @@ Structure of nodes and last time we heard from them. This is a record of any pac # General Operation for UC1 - automagically forward packets to a client that may have missed packets On every handled packet -* Record the sender from and the time we heard from that sender. +* Record the sender from and the time we heard from that sender into senderRecord. On every handled packet @@ -87,3 +87,7 @@ On every handled packet, if we have not heard from that sender in a period of ti * If the client has been away for less than 5 minutes and has received the previously sent message, the client will gracefully ignore it. This is thanks to PacketHistory::wasSeenRecently in PacketHistory.cpp. * * If the client has been away for more than 5 minutes and we resend packets that they have already received, it's possible they will see duplicate messages. This should be unlikely but is still possible. + +# Designed limitations + +The Store and Forward plugin will subscribe to specific packet types and channels and only save those. This will both reduce the amount of data we will need to store and reduce the overhead on the network. Eg: There's no need to replay ACK packets nor is there's no need to replay old location packets. \ No newline at end of file From ae46b3df329e6b3434931f98e41883d1f9f790d1 Mon Sep 17 00:00:00 2001 From: Jm Date: Sun, 14 Feb 2021 11:10:56 -0800 Subject: [PATCH 06/25] Update StoreForwardPlugin.md --- docs/software/plugins/StoreForwardPlugin.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/software/plugins/StoreForwardPlugin.md b/docs/software/plugins/StoreForwardPlugin.md index 97b8f49ee..2b3aa71ad 100644 --- a/docs/software/plugins/StoreForwardPlugin.md +++ b/docs/software/plugins/StoreForwardPlugin.md @@ -2,7 +2,7 @@ This is a work in progress and is not yet available. -The Store Request Plugin is an implementation of a Store and Forward system to enable resilient messaging in the event that a client device is disconnected from the main network. +The Store Forward Plugin is an implementation of a Store and Forward system to enable resilient messaging in the event that a client device is disconnected from the main network. Because of the increased network traffic for this overhead, it's not adviced to use this if you are duty cycle limited for your airtime usage nor is it adviced to use this for SF12 (Long range but Slow). @@ -21,7 +21,7 @@ Not necessarily in this order: UC 1) MVP - automagically forward packets to a client that may have missed packets. -UC 2) Client Interface (Web, Android, Python or iOS when that happens) to request packets be resent +UC 2) Client Interface (Web, Android, Python or iOS when that happens) to optionally request packets be resent. This is to support the case where the client may not have received the message the Router has not detected that the client was away. This is because the router will only know you're away if you've been gone for a long time but will have no way of knowing if you were offline for a few minutes. This will cover the case where you have ducked into a cave or you're swapping out your battery. UC 3) router sends a periodic “heartbeat” to let the clients know they’re part of the main mesh From f1a65f9d0e67952f0f53109f6aa823a0ff9a59d4 Mon Sep 17 00:00:00 2001 From: Jm Date: Sun, 14 Feb 2021 13:31:11 -0800 Subject: [PATCH 07/25] Update to store and forward. Don't merge this to main! --- docs/software/plugins/StoreForwardPlugin.md | 2 +- src/plugins/ExternalNotificationPlugin.cpp | 2 +- src/plugins/Plugins.cpp | 6 ++- src/plugins/RangeTestPlugin.cpp | 2 +- src/plugins/StoreForwardPlugin.cpp | 43 +++++++++------------ src/plugins/StoreForwardPlugin.h | 16 +++----- 6 files changed, 32 insertions(+), 39 deletions(-) diff --git a/docs/software/plugins/StoreForwardPlugin.md b/docs/software/plugins/StoreForwardPlugin.md index 2b3aa71ad..6761f50e6 100644 --- a/docs/software/plugins/StoreForwardPlugin.md +++ b/docs/software/plugins/StoreForwardPlugin.md @@ -21,7 +21,7 @@ Not necessarily in this order: UC 1) MVP - automagically forward packets to a client that may have missed packets. -UC 2) Client Interface (Web, Android, Python or iOS when that happens) to optionally request packets be resent. This is to support the case where the client may not have received the message the Router has not detected that the client was away. This is because the router will only know you're away if you've been gone for a long time but will have no way of knowing if you were offline for a few minutes. This will cover the case where you have ducked into a cave or you're swapping out your battery. +UC 2) Client Interface (Web, Android, Python or iOS when that happens) to optionally request packets be resent. This is to support the case where Router has not detected that the client was away. This is because the router will only know you're away if you've been gone for a period of time but will have no way of knowing if you were offline for a short number of minutes. This will cover the case where you have ducked into a cave or you're swapping out your battery. UC 3) router sends a periodic “heartbeat” to let the clients know they’re part of the main mesh diff --git a/src/plugins/ExternalNotificationPlugin.cpp b/src/plugins/ExternalNotificationPlugin.cpp index 505eff7d1..b36919fd7 100644 --- a/src/plugins/ExternalNotificationPlugin.cpp +++ b/src/plugins/ExternalNotificationPlugin.cpp @@ -6,7 +6,7 @@ #include "configuration.h" #include -#include +//#include /* diff --git a/src/plugins/Plugins.cpp b/src/plugins/Plugins.cpp index ac8dd7336..46f854106 100644 --- a/src/plugins/Plugins.cpp +++ b/src/plugins/Plugins.cpp @@ -31,7 +31,11 @@ void setupPlugins() */ new SerialPlugin(); new ExternalNotificationPlugin(); + + //rangeTestPlugin = new RangeTestPlugin(); //storeForwardPlugin = new StoreForwardPlugin(); - rangeTestPlugin = new RangeTestPlugin(); + + new RangeTestPlugin(); + new StoreForwardPlugin(); #endif } \ No newline at end of file diff --git a/src/plugins/RangeTestPlugin.cpp b/src/plugins/RangeTestPlugin.cpp index c719ad04c..f8e4f53de 100644 --- a/src/plugins/RangeTestPlugin.cpp +++ b/src/plugins/RangeTestPlugin.cpp @@ -6,7 +6,7 @@ #include "configuration.h" #include #include -#include +//#include /* As a sender, I can send packets every n-seonds. These packets include an incramented PacketID. diff --git a/src/plugins/StoreForwardPlugin.cpp b/src/plugins/StoreForwardPlugin.cpp index c82724560..633aaa5ec 100644 --- a/src/plugins/StoreForwardPlugin.cpp +++ b/src/plugins/StoreForwardPlugin.cpp @@ -6,22 +6,15 @@ #include "configuration.h" #include -#include - -#define STORE_RECORDS 5000 -#define BYTES_PER_RECORDS 512 - -#define STOREFORWARDPLUGIN_ENABLED 0 - StoreForwardPlugin *storeForwardPlugin; StoreForwardPluginRadio *storeForwardPluginRadio; -StoreForwardPlugin::StoreForwardPlugin() : concurrency::OSThread("SerialPlugin") {} - -// char serialStringChar[Constants_DATA_PAYLOAD_LEN]; +StoreForwardPlugin::StoreForwardPlugin() : concurrency::OSThread("StoreForwardPlugin") {} int32_t StoreForwardPlugin::runOnce() { +#if 0 + #ifndef NO_ESP32 /* @@ -29,15 +22,15 @@ int32_t StoreForwardPlugin::runOnce() without having to configure it from the PythonAPI or WebUI. */ - // radioConfig.preferences.store_forward_plugin_enabled = 1; - // radioConfig.preferences.store_forward_plugin_records = 80; + radioConfig.preferences.store_forward_plugin_enabled = 0; if (radioConfig.preferences.store_forward_plugin_enabled) { if (firstTime) { - // Interface with the serial peripheral from in here. DEBUG_MSG("Initializing Store & Forward Plugin\n"); + /* + */ // Router if (radioConfig.preferences.is_router) { @@ -62,8 +55,7 @@ int32_t StoreForwardPlugin::runOnce() // Non-Router } else { } - - storeForwardPluginRadio = new StoreForwardPluginRadio(); + // storeForwardPluginRadio = new StoreForwardPluginRadio(); firstTime = 0; @@ -71,7 +63,7 @@ int32_t StoreForwardPlugin::runOnce() // TBD } - return (10); + return (1000); } else { DEBUG_MSG("Store & Forward Plugin - Disabled\n"); @@ -79,6 +71,8 @@ int32_t StoreForwardPlugin::runOnce() } #endif +#endif + return (INT32_MAX); } MeshPacket *StoreForwardPluginRadio::allocReply() @@ -91,35 +85,36 @@ MeshPacket *StoreForwardPluginRadio::allocReply() void StoreForwardPluginRadio::sendPayload(NodeNum dest, bool wantReplies) { +#if 0 MeshPacket *p = allocReply(); p->to = dest; p->decoded.want_response = wantReplies; - // p->want_ack = SERIALPLUGIN_ACK; - - // p->decoded.data.payload.size = strlen(serialStringChar); // You must specify how many bytes are in the reply - // memcpy(p->decoded.data.payload.bytes, serialStringChar, p->decoded.data.payload.size); - service.sendToMesh(p); +#endif } bool StoreForwardPluginRadio::handleReceived(const MeshPacket &mp) { + +#if 0 #ifndef NO_ESP32 - if (STOREFORWARDPLUGIN_ENABLED) { + if (radioConfig.preferences.store_forward_plugin_enabled) { // auto &p = mp.decoded.data; if (mp.from != nodeDB.getNodeNum()) { - DEBUG_MSG("Store & Forward Plugin ---------- ---------- ---------- ---------- ----------\n"); - printPacket("PACKET FROM PHONE", &mp); + DEBUG_MSG("Store & Forward Plugin -- Print Start ---------- ---------- ---------- ---------- ----------\n"); + printPacket("PACKET FROM RADIO", &mp); + DEBUG_MSG("Store & Forward Plugin -- Print End ---------- ---------- ---------- ---------- ----------\n"); } } else { DEBUG_MSG("Store & Forward Plugin - Disabled\n"); } +#endif #endif return true; // Let others look at this message also if they want diff --git a/src/plugins/StoreForwardPlugin.h b/src/plugins/StoreForwardPlugin.h index 952206c58..f40c7aa41 100644 --- a/src/plugins/StoreForwardPlugin.h +++ b/src/plugins/StoreForwardPlugin.h @@ -20,22 +20,16 @@ class StoreForwardPlugin : private concurrency::OSThread extern StoreForwardPlugin *storeForwardPlugin; /* - * Radio interface for SerialPlugin + * Radio interface for StoreForwardPlugin * */ class StoreForwardPluginRadio : public SinglePortPlugin { - uint32_t lastRxID; + //uint32_t lastRxID; public: - /* - TODO: Switch this to PortNum_SERIAL_APP once the change is able to be merged back here - from the main code. - */ - - // SerialPluginRadio() : SinglePortPlugin("SerialPluginRadio", PortNum_TEXT_MESSAGE_APP) {} - // SerialPluginRadio() : SinglePortPlugin("SerialPluginRadio", PortNum_STORE_FORWARD_APP) {} - StoreForwardPluginRadio() : SinglePortPlugin("SerialPluginRadio", PortNum_SERIAL_APP) {} + StoreForwardPluginRadio() : SinglePortPlugin("StoreForwardPluginRadio", PortNum_STORE_FORWARD_APP) {} + //StoreForwardPluginRadio() : SinglePortPlugin("StoreForwardPluginRadio", PortNum_TEXT_MESSAGE_APP) {} /** * Send our payload into the mesh @@ -45,7 +39,7 @@ class StoreForwardPluginRadio : public SinglePortPlugin protected: virtual MeshPacket *allocReply(); - virtual bool wantPortnum(PortNum p){return true;}; + //virtual bool wantPortnum(PortNum p){return true;}; /** Called to handle a particular incoming message From 24329a26dee2f09c11c491a597f247678ba46ac4 Mon Sep 17 00:00:00 2001 From: Jm Date: Sun, 14 Feb 2021 14:01:08 -0800 Subject: [PATCH 08/25] Framework for storeforward --- src/plugins/RangeTestPlugin.cpp | 1 - src/plugins/StoreForwardPlugin.cpp | 65 +++++------------------------- src/plugins/StoreForwardPlugin.h | 12 ++---- 3 files changed, 12 insertions(+), 66 deletions(-) diff --git a/src/plugins/RangeTestPlugin.cpp b/src/plugins/RangeTestPlugin.cpp index f8e4f53de..a1c69b101 100644 --- a/src/plugins/RangeTestPlugin.cpp +++ b/src/plugins/RangeTestPlugin.cpp @@ -41,7 +41,6 @@ int32_t RangeTestPlugin::runOnce() // Fixed position is useful when testing indoors. // radioConfig.preferences.fixed_position = 1; - uint32_t senderHeartbeat = radioConfig.preferences.range_test_plugin_sender * 1000; if (radioConfig.preferences.range_test_plugin_enabled) { diff --git a/src/plugins/StoreForwardPlugin.cpp b/src/plugins/StoreForwardPlugin.cpp index 633aaa5ec..2db4d7358 100644 --- a/src/plugins/StoreForwardPlugin.cpp +++ b/src/plugins/StoreForwardPlugin.cpp @@ -6,6 +6,10 @@ #include "configuration.h" #include +#include + + + StoreForwardPlugin *storeForwardPlugin; StoreForwardPluginRadio *storeForwardPluginRadio; @@ -13,8 +17,6 @@ StoreForwardPlugin::StoreForwardPlugin() : concurrency::OSThread("StoreForwardPl int32_t StoreForwardPlugin::runOnce() { -#if 0 - #ifndef NO_ESP32 /* @@ -22,57 +24,27 @@ int32_t StoreForwardPlugin::runOnce() without having to configure it from the PythonAPI or WebUI. */ - radioConfig.preferences.store_forward_plugin_enabled = 0; - - if (radioConfig.preferences.store_forward_plugin_enabled) { + if (0) { if (firstTime) { - DEBUG_MSG("Initializing Store & Forward Plugin\n"); - /* - */ - // Router - if (radioConfig.preferences.is_router) { - if (ESP.getPsramSize()) { - if (ESP.getFreePsram() <= 1024 * 1024) { - // Do the startup here - - } else { - DEBUG_MSG("Device has less than 1M of PSRAM free. Aborting startup.\n"); - DEBUG_MSG("Store & Forward Plugin - Aborting Startup.\n"); - - return (INT32_MAX); - } - - } else { - DEBUG_MSG("Device doesn't have PSRAM.\n"); - DEBUG_MSG("Store & Forward Plugin - Aborting Startup.\n"); - - return (INT32_MAX); - } - - // Non-Router - } else { - } - // storeForwardPluginRadio = new StoreForwardPluginRadio(); + storeForwardPluginRadio = new StoreForwardPluginRadio(); firstTime = 0; } else { - // TBD + } - return (1000); + return (10); } else { - DEBUG_MSG("Store & Forward Plugin - Disabled\n"); + DEBUG_MSG("StoreForwardPlugin Disabled\n"); return (INT32_MAX); } #endif -#endif - return (INT32_MAX); } MeshPacket *StoreForwardPluginRadio::allocReply() @@ -82,39 +54,20 @@ MeshPacket *StoreForwardPluginRadio::allocReply() return reply; } - void StoreForwardPluginRadio::sendPayload(NodeNum dest, bool wantReplies) { -#if 0 MeshPacket *p = allocReply(); p->to = dest; p->decoded.want_response = wantReplies; service.sendToMesh(p); -#endif } bool StoreForwardPluginRadio::handleReceived(const MeshPacket &mp) { - -#if 0 #ifndef NO_ESP32 - if (radioConfig.preferences.store_forward_plugin_enabled) { - // auto &p = mp.decoded.data; - - if (mp.from != nodeDB.getNodeNum()) { - DEBUG_MSG("Store & Forward Plugin -- Print Start ---------- ---------- ---------- ---------- ----------\n"); - printPacket("PACKET FROM RADIO", &mp); - DEBUG_MSG("Store & Forward Plugin -- Print End ---------- ---------- ---------- ---------- ----------\n"); - } - - } else { - DEBUG_MSG("Store & Forward Plugin - Disabled\n"); - } - -#endif #endif return true; // Let others look at this message also if they want diff --git a/src/plugins/StoreForwardPlugin.h b/src/plugins/StoreForwardPlugin.h index f40c7aa41..1a27222f4 100644 --- a/src/plugins/StoreForwardPlugin.h +++ b/src/plugins/StoreForwardPlugin.h @@ -19,17 +19,13 @@ class StoreForwardPlugin : private concurrency::OSThread extern StoreForwardPlugin *storeForwardPlugin; -/* - * Radio interface for StoreForwardPlugin - * - */ class StoreForwardPluginRadio : public SinglePortPlugin { - //uint32_t lastRxID; + uint32_t lastRxID; public: - StoreForwardPluginRadio() : SinglePortPlugin("StoreForwardPluginRadio", PortNum_STORE_FORWARD_APP) {} - //StoreForwardPluginRadio() : SinglePortPlugin("StoreForwardPluginRadio", PortNum_TEXT_MESSAGE_APP) {} + + StoreForwardPluginRadio() : SinglePortPlugin("StoreForwardPluginRadio", PortNum_TEXT_MESSAGE_APP) {} /** * Send our payload into the mesh @@ -39,8 +35,6 @@ class StoreForwardPluginRadio : public SinglePortPlugin protected: virtual MeshPacket *allocReply(); - //virtual bool wantPortnum(PortNum p){return true;}; - /** Called to handle a particular incoming message @return true if you've guaranteed you've handled this message and no other handlers should be considered for it From b8adaf6fbe9bf0b943a59623f1b9da8655a14860 Mon Sep 17 00:00:00 2001 From: Jm Date: Sun, 14 Feb 2021 16:17:40 -0800 Subject: [PATCH 09/25] #671 Range test plugin --- src/plugins/Plugins.cpp | 2 +- src/plugins/RangeTestPlugin.cpp | 62 ++++++------ src/plugins/StoreForwardPlugin-old.cpp | 125 +++++++++++++++++++++++++ src/plugins/StoreForwardPlugin-old.h | 55 +++++++++++ 4 files changed, 216 insertions(+), 28 deletions(-) create mode 100644 src/plugins/StoreForwardPlugin-old.cpp create mode 100644 src/plugins/StoreForwardPlugin-old.h diff --git a/src/plugins/Plugins.cpp b/src/plugins/Plugins.cpp index 46f854106..6fe1459f2 100644 --- a/src/plugins/Plugins.cpp +++ b/src/plugins/Plugins.cpp @@ -36,6 +36,6 @@ void setupPlugins() //storeForwardPlugin = new StoreForwardPlugin(); new RangeTestPlugin(); - new StoreForwardPlugin(); + //new StoreForwardPlugin(); #endif } \ No newline at end of file diff --git a/src/plugins/RangeTestPlugin.cpp b/src/plugins/RangeTestPlugin.cpp index a1c69b101..7f99070ec 100644 --- a/src/plugins/RangeTestPlugin.cpp +++ b/src/plugins/RangeTestPlugin.cpp @@ -153,12 +153,12 @@ bool RangeTestPluginRadio::handleReceived(const MeshPacket &mp) DEBUG_MSG("mp.from %d\n", mp.from); DEBUG_MSG("mp.rx_snr %f\n", mp.rx_snr); DEBUG_MSG("mp.hop_limit %d\n", mp.hop_limit); - DEBUG_MSG("mp.decoded.position.latitude_i %d\n", mp.decoded.position.latitude_i); - DEBUG_MSG("mp.decoded.position.longitude_i %d\n", mp.decoded.position.longitude_i); + // DEBUG_MSG("mp.decoded.position.latitude_i %d\n", mp.decoded.position.latitude_i); // Depricated + // DEBUG_MSG("mp.decoded.position.longitude_i %d\n", mp.decoded.position.longitude_i); // Depricated DEBUG_MSG("---- Node Information of Received Packet (mp.from):\n"); DEBUG_MSG("n->user.long_name %s\n", n->user.long_name); DEBUG_MSG("n->user.short_name %s\n", n->user.short_name); - DEBUG_MSG("n->user.macaddr %X\n", n->user.macaddr); + // DEBUG_MSG("n->user.macaddr %X\n", n->user.macaddr); DEBUG_MSG("n->has_position %d\n", n->has_position); DEBUG_MSG("n->position.latitude_i %d\n", n->position.latitude_i); DEBUG_MSG("n->position.longitude_i %d\n", n->position.longitude_i); @@ -241,22 +241,25 @@ bool RangeTestPluginRadio::appendFile(const MeshPacket &mp) return 0; } - //--------- Write to file - File fileToWrite = SPIFFS.open("/static/rangetest.csv", FILE_WRITE); + // If the file doesn't exist, write the header. + if (!SPIFFS.exists("/static/rangetest.csv")) { + //--------- Write to file + File fileToWrite = SPIFFS.open("/static/rangetest.csv", FILE_WRITE); - if (!fileToWrite) { - DEBUG_MSG("There was an error opening the file for writing\n"); - return 0; + if (!fileToWrite) { + DEBUG_MSG("There was an error opening the file for writing\n"); + return 0; + } + + if (fileToWrite.println("time,from,sender name,sender lat,sender long,rx lat,rx long,rx snr,distance,payload")) { + DEBUG_MSG("File was written\n"); + } else { + DEBUG_MSG("File write failed\n"); + } + + fileToWrite.close(); } - if (fileToWrite.println("time,sender mac,rx snr,sender lat,sender long,rx lat,rx long,distance,payload")) { - DEBUG_MSG("File was written\n"); - } else { - DEBUG_MSG("File write failed\n"); - } - - fileToWrite.close(); - //--------- Apend content to file File fileToAppend = SPIFFS.open("/static/rangetest.csv", FILE_APPEND); @@ -278,21 +281,26 @@ bool RangeTestPluginRadio::appendFile(const MeshPacket &mp) int min = (hms % SEC_PER_HOUR) / SEC_PER_MIN; int sec = (hms % SEC_PER_HOUR) % SEC_PER_MIN; // or hms % SEC_PER_MIN - fileToAppend.printf("%02d:%02d:%02d ", hour, min, sec); // Time + fileToAppend.printf("%02d:%02d:%02d,", hour, min, sec); // Time } else { - fileToAppend.printf("??:??:?? "); // Time + fileToAppend.printf("??:??:??,"); // Time } - fileToAppend.printf("$X,", n->user.macaddr); // Mac Address - fileToAppend.printf("%f,", mp.rx_snr); // RX SNR - fileToAppend.printf("%d,", n->position.latitude_i); // Sender Lat - fileToAppend.printf("%d,", n->position.longitude_i); // Sender Long - fileToAppend.printf("%d,", gpsStatus->getLatitude()); // RX Lat - fileToAppend.printf("%d,", gpsStatus->getLongitude()); // RX Long + fileToAppend.printf("%d,", mp.from); // From + fileToAppend.printf("%s,", n->user.long_name); // Long Name + fileToAppend.printf("%f,", n->position.latitude_i * 1e-7); // Sender Lat + fileToAppend.printf("%f,", n->position.longitude_i * 1e-7); // Sender Long + fileToAppend.printf("%f,", gpsStatus->getLatitude() * 1e-7); // RX Lat + fileToAppend.printf("%f,", gpsStatus->getLongitude() * 1e-7); // RX Long + fileToAppend.printf("%f,", mp.rx_snr); // RX SNR - float distance = latLongToMeter(n->position.latitude_i * 1e-7, n->position.longitude_i * 1e-7, - gpsStatus->getLatitude() * 1e-7, gpsStatus->getLongitude() * 1e-7); - fileToAppend.printf("%f,", distance); // Distance in meters + if (n->position.latitude_i && n->position.longitude_i && gpsStatus->getLatitude() && gpsStatus->getLongitude()) { + float distance = latLongToMeter(n->position.latitude_i * 1e-7, n->position.longitude_i * 1e-7, + gpsStatus->getLatitude() * 1e-7, gpsStatus->getLongitude() * 1e-7); + fileToAppend.printf("%f,", distance); // Distance in meters + } else { + fileToAppend.printf("0,"); + } // TODO: If quotes are found in the payload, it has to be escaped. fileToAppend.printf("\"%s\"\n", p.payload.bytes); diff --git a/src/plugins/StoreForwardPlugin-old.cpp b/src/plugins/StoreForwardPlugin-old.cpp new file mode 100644 index 000000000..3df421af6 --- /dev/null +++ b/src/plugins/StoreForwardPlugin-old.cpp @@ -0,0 +1,125 @@ +#if 0 + +#include "StoreForwardPlugin.h" +#include "MeshService.h" +#include "NodeDB.h" +#include "RTC.h" +#include "Router.h" +#include "configuration.h" +#include + +StoreForwardPlugin *storeForwardPlugin; +StoreForwardPluginRadio *storeForwardPluginRadio; + +StoreForwardPlugin::StoreForwardPlugin() : concurrency::OSThread("StoreForwardPlugin") {} + +int32_t StoreForwardPlugin::runOnce() +{ +#if 0 + +#ifndef NO_ESP32 + + /* + Uncomment the preferences below if you want to use the plugin + without having to configure it from the PythonAPI or WebUI. + */ + + radioConfig.preferences.store_forward_plugin_enabled = 0; + + if (radioConfig.preferences.store_forward_plugin_enabled) { + + if (firstTime) { + + DEBUG_MSG("Initializing Store & Forward Plugin\n"); + /* + */ + + // Router + if (radioConfig.preferences.is_router) { + if (ESP.getPsramSize()) { + if (ESP.getFreePsram() <= 1024 * 1024) { + // Do the startup here + + } else { + DEBUG_MSG("Device has less than 1M of PSRAM free. Aborting startup.\n"); + DEBUG_MSG("Store & Forward Plugin - Aborting Startup.\n"); + + return (INT32_MAX); + } + + } else { + DEBUG_MSG("Device doesn't have PSRAM.\n"); + DEBUG_MSG("Store & Forward Plugin - Aborting Startup.\n"); + + return (INT32_MAX); + } + + // Non-Router + } else { + } + // storeForwardPluginRadio = new StoreForwardPluginRadio(); + + firstTime = 0; + + } else { + // TBD + } + + return (1000); + } else { + DEBUG_MSG("Store & Forward Plugin - Disabled\n"); + + return (INT32_MAX); + } + +#endif +#endif + return (INT32_MAX); +} + +MeshPacket *StoreForwardPluginRadio::allocReply() +{ + + auto reply = allocDataPacket(); // Allocate a packet for sending + + return reply; +} + +void StoreForwardPluginRadio::sendPayload(NodeNum dest, bool wantReplies) +{ +#if 0 + MeshPacket *p = allocReply(); + p->to = dest; + p->decoded.want_response = wantReplies; + + service.sendToMesh(p); +#endif +} + +bool StoreForwardPluginRadio::handleReceived(const MeshPacket &mp) +{ + +#if 0 +#ifndef NO_ESP32 + + if (radioConfig.preferences.store_forward_plugin_enabled) { + + // auto &p = mp.decoded.data; + + if (mp.from != nodeDB.getNodeNum()) { + DEBUG_MSG("Store & Forward Plugin -- Print Start ---------- ---------- ---------- ---------- ----------\n"); + printPacket("PACKET FROM RADIO", &mp); + DEBUG_MSG("Store & Forward Plugin -- Print End ---------- ---------- ---------- ---------- ----------\n"); + } + + } else { + DEBUG_MSG("Store & Forward Plugin - Disabled\n"); + } + +#endif +#endif + + return true; // Let others look at this message also if they want +} + +#endif \ No newline at end of file diff --git a/src/plugins/StoreForwardPlugin-old.h b/src/plugins/StoreForwardPlugin-old.h new file mode 100644 index 000000000..29d11ea7d --- /dev/null +++ b/src/plugins/StoreForwardPlugin-old.h @@ -0,0 +1,55 @@ +#if 0 + +#pragma once + +#include "SinglePortPlugin.h" +#include "concurrency/OSThread.h" +#include "configuration.h" +#include +#include + +class StoreForwardPlugin : private concurrency::OSThread +{ + bool firstTime = 1; + + public: + StoreForwardPlugin(); + + protected: + virtual int32_t runOnce(); +}; + +extern StoreForwardPlugin *storeForwardPlugin; + +/* + * Radio interface for StoreForwardPlugin + * + */ +class StoreForwardPluginRadio : public SinglePortPlugin +{ + //uint32_t lastRxID; + + public: + StoreForwardPluginRadio() : SinglePortPlugin("StoreForwardPluginRadio", PortNum_STORE_FORWARD_APP) {} + //StoreForwardPluginRadio() : SinglePortPlugin("StoreForwardPluginRadio", PortNum_TEXT_MESSAGE_APP) {} + + /** + * Send our payload into the mesh + */ + void sendPayload(NodeNum dest = NODENUM_BROADCAST, bool wantReplies = false); + + protected: + virtual MeshPacket *allocReply(); + + //virtual bool wantPortnum(PortNum p){return true;}; + + /** Called to handle a particular incoming message + + @return true if you've guaranteed you've handled this message and no other handlers should be considered for it + */ + virtual bool handleReceived(const MeshPacket &mp); +}; + +extern StoreForwardPluginRadio *storeForwardPluginRadio; + +#endif \ No newline at end of file From 3311146abaf1524209a3d4c888d64c20961c8987 Mon Sep 17 00:00:00 2001 From: Jm Date: Sun, 14 Feb 2021 16:19:06 -0800 Subject: [PATCH 10/25] Turning storeforward back on for @geeksville --- src/plugins/Plugins.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/Plugins.cpp b/src/plugins/Plugins.cpp index 6fe1459f2..46f854106 100644 --- a/src/plugins/Plugins.cpp +++ b/src/plugins/Plugins.cpp @@ -36,6 +36,6 @@ void setupPlugins() //storeForwardPlugin = new StoreForwardPlugin(); new RangeTestPlugin(); - //new StoreForwardPlugin(); + new StoreForwardPlugin(); #endif } \ No newline at end of file From e6605e5ac8654055476a04553430061ad5ff8e96 Mon Sep 17 00:00:00 2001 From: Jm Date: Sun, 14 Feb 2021 20:13:52 -0800 Subject: [PATCH 11/25] Store Forward can see All(?) rx packets! --- src/plugins/Plugins.cpp | 4 +- src/plugins/StoreForwardPlugin-old.cpp | 125 ------------------------- src/plugins/StoreForwardPlugin-old.h | 55 ----------- src/plugins/StoreForwardPlugin.cpp | 62 ++++++++++-- src/plugins/StoreForwardPlugin.h | 15 ++- 5 files changed, 65 insertions(+), 196 deletions(-) delete mode 100644 src/plugins/StoreForwardPlugin-old.cpp delete mode 100644 src/plugins/StoreForwardPlugin-old.h diff --git a/src/plugins/Plugins.cpp b/src/plugins/Plugins.cpp index 46f854106..69e68ea4f 100644 --- a/src/plugins/Plugins.cpp +++ b/src/plugins/Plugins.cpp @@ -33,9 +33,9 @@ void setupPlugins() new ExternalNotificationPlugin(); //rangeTestPlugin = new RangeTestPlugin(); - //storeForwardPlugin = new StoreForwardPlugin(); + storeForwardPlugin = new StoreForwardPlugin(); new RangeTestPlugin(); - new StoreForwardPlugin(); + //new StoreForwardPlugin(); #endif } \ No newline at end of file diff --git a/src/plugins/StoreForwardPlugin-old.cpp b/src/plugins/StoreForwardPlugin-old.cpp deleted file mode 100644 index 3df421af6..000000000 --- a/src/plugins/StoreForwardPlugin-old.cpp +++ /dev/null @@ -1,125 +0,0 @@ -#if 0 - -#include "StoreForwardPlugin.h" -#include "MeshService.h" -#include "NodeDB.h" -#include "RTC.h" -#include "Router.h" -#include "configuration.h" -#include - -StoreForwardPlugin *storeForwardPlugin; -StoreForwardPluginRadio *storeForwardPluginRadio; - -StoreForwardPlugin::StoreForwardPlugin() : concurrency::OSThread("StoreForwardPlugin") {} - -int32_t StoreForwardPlugin::runOnce() -{ -#if 0 - -#ifndef NO_ESP32 - - /* - Uncomment the preferences below if you want to use the plugin - without having to configure it from the PythonAPI or WebUI. - */ - - radioConfig.preferences.store_forward_plugin_enabled = 0; - - if (radioConfig.preferences.store_forward_plugin_enabled) { - - if (firstTime) { - - DEBUG_MSG("Initializing Store & Forward Plugin\n"); - /* - */ - - // Router - if (radioConfig.preferences.is_router) { - if (ESP.getPsramSize()) { - if (ESP.getFreePsram() <= 1024 * 1024) { - // Do the startup here - - } else { - DEBUG_MSG("Device has less than 1M of PSRAM free. Aborting startup.\n"); - DEBUG_MSG("Store & Forward Plugin - Aborting Startup.\n"); - - return (INT32_MAX); - } - - } else { - DEBUG_MSG("Device doesn't have PSRAM.\n"); - DEBUG_MSG("Store & Forward Plugin - Aborting Startup.\n"); - - return (INT32_MAX); - } - - // Non-Router - } else { - } - // storeForwardPluginRadio = new StoreForwardPluginRadio(); - - firstTime = 0; - - } else { - // TBD - } - - return (1000); - } else { - DEBUG_MSG("Store & Forward Plugin - Disabled\n"); - - return (INT32_MAX); - } - -#endif -#endif - return (INT32_MAX); -} - -MeshPacket *StoreForwardPluginRadio::allocReply() -{ - - auto reply = allocDataPacket(); // Allocate a packet for sending - - return reply; -} - -void StoreForwardPluginRadio::sendPayload(NodeNum dest, bool wantReplies) -{ -#if 0 - MeshPacket *p = allocReply(); - p->to = dest; - p->decoded.want_response = wantReplies; - - service.sendToMesh(p); -#endif -} - -bool StoreForwardPluginRadio::handleReceived(const MeshPacket &mp) -{ - -#if 0 -#ifndef NO_ESP32 - - if (radioConfig.preferences.store_forward_plugin_enabled) { - - // auto &p = mp.decoded.data; - - if (mp.from != nodeDB.getNodeNum()) { - DEBUG_MSG("Store & Forward Plugin -- Print Start ---------- ---------- ---------- ---------- ----------\n"); - printPacket("PACKET FROM RADIO", &mp); - DEBUG_MSG("Store & Forward Plugin -- Print End ---------- ---------- ---------- ---------- ----------\n"); - } - - } else { - DEBUG_MSG("Store & Forward Plugin - Disabled\n"); - } - -#endif -#endif - - return true; // Let others look at this message also if they want -} - -#endif \ No newline at end of file diff --git a/src/plugins/StoreForwardPlugin-old.h b/src/plugins/StoreForwardPlugin-old.h deleted file mode 100644 index 29d11ea7d..000000000 --- a/src/plugins/StoreForwardPlugin-old.h +++ /dev/null @@ -1,55 +0,0 @@ -#if 0 - -#pragma once - -#include "SinglePortPlugin.h" -#include "concurrency/OSThread.h" -#include "configuration.h" -#include -#include - -class StoreForwardPlugin : private concurrency::OSThread -{ - bool firstTime = 1; - - public: - StoreForwardPlugin(); - - protected: - virtual int32_t runOnce(); -}; - -extern StoreForwardPlugin *storeForwardPlugin; - -/* - * Radio interface for StoreForwardPlugin - * - */ -class StoreForwardPluginRadio : public SinglePortPlugin -{ - //uint32_t lastRxID; - - public: - StoreForwardPluginRadio() : SinglePortPlugin("StoreForwardPluginRadio", PortNum_STORE_FORWARD_APP) {} - //StoreForwardPluginRadio() : SinglePortPlugin("StoreForwardPluginRadio", PortNum_TEXT_MESSAGE_APP) {} - - /** - * Send our payload into the mesh - */ - void sendPayload(NodeNum dest = NODENUM_BROADCAST, bool wantReplies = false); - - protected: - virtual MeshPacket *allocReply(); - - //virtual bool wantPortnum(PortNum p){return true;}; - - /** Called to handle a particular incoming message - - @return true if you've guaranteed you've handled this message and no other handlers should be considered for it - */ - virtual bool handleReceived(const MeshPacket &mp); -}; - -extern StoreForwardPluginRadio *storeForwardPluginRadio; - -#endif \ No newline at end of file diff --git a/src/plugins/StoreForwardPlugin.cpp b/src/plugins/StoreForwardPlugin.cpp index 2db4d7358..087b34c1c 100644 --- a/src/plugins/StoreForwardPlugin.cpp +++ b/src/plugins/StoreForwardPlugin.cpp @@ -6,10 +6,6 @@ #include "configuration.h" #include -#include - - - StoreForwardPlugin *storeForwardPlugin; StoreForwardPluginRadio *storeForwardPluginRadio; @@ -17,6 +13,7 @@ StoreForwardPlugin::StoreForwardPlugin() : concurrency::OSThread("StoreForwardPl int32_t StoreForwardPlugin::runOnce() { + #ifndef NO_ESP32 /* @@ -24,27 +21,60 @@ int32_t StoreForwardPlugin::runOnce() without having to configure it from the PythonAPI or WebUI. */ - if (0) { + radioConfig.preferences.store_forward_plugin_enabled = 1; + radioConfig.preferences.is_router = 0; + + if (radioConfig.preferences.store_forward_plugin_enabled) { if (firstTime) { + /* + */ - storeForwardPluginRadio = new StoreForwardPluginRadio(); + if (radioConfig.preferences.is_router) { + DEBUG_MSG("Initializing Store & Forward Plugin - Enabled\n"); + // Router + if (ESP.getPsramSize()) { + if (ESP.getFreePsram() >= 1024 * 1024) { + // Do the startup here + storeForwardPluginRadio = new StoreForwardPluginRadio(); - firstTime = 0; + firstTime = 0; + + } else { + DEBUG_MSG("Device has less than 1M of PSRAM free. Aborting startup.\n"); + DEBUG_MSG("Store & Forward Plugin - Aborting Startup.\n"); + + return (INT32_MAX); + } + + } else { + DEBUG_MSG("Device doesn't have PSRAM.\n"); + DEBUG_MSG("Store & Forward Plugin - Aborting Startup.\n"); + + return (INT32_MAX); + } + + } else { + DEBUG_MSG("Initializing Store & Forward Plugin - Enabled but is_router is not turned on.\n"); + DEBUG_MSG( + "Initializing Store & Forward Plugin - If you want to use this plugin, you must also turn on is_router.\n"); + // Non-Router + } } else { - + // TBD } - return (10); + return (1000); } else { - DEBUG_MSG("StoreForwardPlugin Disabled\n"); + DEBUG_MSG("Store & Forward Plugin - Disabled\n"); return (INT32_MAX); } #endif + return (INT32_MAX); } MeshPacket *StoreForwardPluginRadio::allocReply() @@ -54,6 +84,7 @@ MeshPacket *StoreForwardPluginRadio::allocReply() return reply; } + void StoreForwardPluginRadio::sendPayload(NodeNum dest, bool wantReplies) { MeshPacket *p = allocReply(); @@ -66,7 +97,18 @@ void StoreForwardPluginRadio::sendPayload(NodeNum dest, bool wantReplies) bool StoreForwardPluginRadio::handleReceived(const MeshPacket &mp) { #ifndef NO_ESP32 + if (radioConfig.preferences.store_forward_plugin_enabled) { + // auto &p = mp.decoded.data; + if (mp.from != nodeDB.getNodeNum()) { + DEBUG_MSG("Store & Forward Plugin -- Print Start ---------- ---------- ---------- ---------- ----------\n"); + printPacket("----- PACKET FROM RADIO", &mp); + DEBUG_MSG("Store & Forward Plugin -- Print End ---------- ---------- ---------- ---------- ----------\n"); + } + + } else { + DEBUG_MSG("Store & Forward Plugin - Disabled\n"); + } #endif diff --git a/src/plugins/StoreForwardPlugin.h b/src/plugins/StoreForwardPlugin.h index 1a27222f4..be9634913 100644 --- a/src/plugins/StoreForwardPlugin.h +++ b/src/plugins/StoreForwardPlugin.h @@ -19,13 +19,17 @@ class StoreForwardPlugin : private concurrency::OSThread extern StoreForwardPlugin *storeForwardPlugin; +/* + * Radio interface for StoreForwardPlugin + * + */ class StoreForwardPluginRadio : public SinglePortPlugin { - uint32_t lastRxID; + //uint32_t lastRxID; public: - - StoreForwardPluginRadio() : SinglePortPlugin("StoreForwardPluginRadio", PortNum_TEXT_MESSAGE_APP) {} + StoreForwardPluginRadio() : SinglePortPlugin("StoreForwardPluginRadio", PortNum_STORE_FORWARD_APP) {} + //StoreForwardPluginRadio() : SinglePortPlugin("StoreForwardPluginRadio", PortNum_TEXT_MESSAGE_APP) {} /** * Send our payload into the mesh @@ -35,6 +39,8 @@ class StoreForwardPluginRadio : public SinglePortPlugin protected: virtual MeshPacket *allocReply(); + virtual bool wantPortnum(PortNum p){return true;}; + /** Called to handle a particular incoming message @return true if you've guaranteed you've handled this message and no other handlers should be considered for it @@ -42,4 +48,5 @@ class StoreForwardPluginRadio : public SinglePortPlugin virtual bool handleReceived(const MeshPacket &mp); }; -extern StoreForwardPluginRadio *storeForwardPluginRadio; \ No newline at end of file +extern StoreForwardPluginRadio *storeForwardPluginRadio; + From 7d4ce483c5e3928f4281b916fbaaf9a0ac071aa6 Mon Sep 17 00:00:00 2001 From: Jm Date: Sun, 14 Feb 2021 20:16:29 -0800 Subject: [PATCH 12/25] Update RangeTestPlugin.md --- docs/software/plugins/RangeTestPlugin.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/docs/software/plugins/RangeTestPlugin.md b/docs/software/plugins/RangeTestPlugin.md index 9fd9b2724..998ce4f06 100644 --- a/docs/software/plugins/RangeTestPlugin.md +++ b/docs/software/plugins/RangeTestPlugin.md @@ -38,6 +38,10 @@ To save a log of the messages: range_test_plugin_save = 1 +Be sure to turn off either the plugin configured as a sender or the device where the plugin setup as sender when not in use. This will use a lot of time on air and will spam your channel. + +Also be mindful of your space usage on the file system. It has protections from filling up the space but it's best to delete old range test results. + # Known Problems From fea2228b16f822a3e23f2e90ef326162c0cf495d Mon Sep 17 00:00:00 2001 From: Jm Date: Sun, 14 Feb 2021 20:17:16 -0800 Subject: [PATCH 13/25] Update RangeTestPlugin.md --- docs/software/plugins/RangeTestPlugin.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/docs/software/plugins/RangeTestPlugin.md b/docs/software/plugins/RangeTestPlugin.md index 998ce4f06..58baff1e5 100644 --- a/docs/software/plugins/RangeTestPlugin.md +++ b/docs/software/plugins/RangeTestPlugin.md @@ -38,6 +38,8 @@ To save a log of the messages: range_test_plugin_save = 1 +## Other things to keep in mind + Be sure to turn off either the plugin configured as a sender or the device where the plugin setup as sender when not in use. This will use a lot of time on air and will spam your channel. Also be mindful of your space usage on the file system. It has protections from filling up the space but it's best to delete old range test results. @@ -49,7 +51,7 @@ Also be mindful of your space usage on the file system. It has protections from # TODO -* Right now range test messages go over the TEXT_MESSAGE_APP port. We need a toggle to switch to RANGE_TEST_APP. +* Right now range test messages go over the TEXT_MESSAGE_APP port. We need a toggle to switch to optionally send over RANGE_TEST_APP. # Need more help? From c9353ebee34dcc186746879dfba2937502039356 Mon Sep 17 00:00:00 2001 From: Jm Date: Sun, 14 Feb 2021 21:24:41 -0800 Subject: [PATCH 14/25] Update RangeTestPlugin.md --- docs/software/plugins/RangeTestPlugin.md | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/docs/software/plugins/RangeTestPlugin.md b/docs/software/plugins/RangeTestPlugin.md index 58baff1e5..ba9f006f2 100644 --- a/docs/software/plugins/RangeTestPlugin.md +++ b/docs/software/plugins/RangeTestPlugin.md @@ -53,6 +53,26 @@ Also be mindful of your space usage on the file system. It has protections from * Right now range test messages go over the TEXT_MESSAGE_APP port. We need a toggle to switch to optionally send over RANGE_TEST_APP. +# FAQ + +Q: Where is rangetest.csv saved? +A: Turn on the WiFi on your device as either a WiFi client or a WiFi AP. Once you can connect to your device, go to /static and you will see rangetest.csv. + +Q: Do I need to have WiFi turned on for the file to be saved? +A: Nope, it'll just work. + +Q: Do I need a phone for this plugin? +A: There's no need for a phone. + +Q: Can I use this as a message logger? +A: While it's not the intended purpose, sure, why not. Do it! + +Q: What will happen if I run out of space on my device? +A: We have a protection in place to keep you from completly filling up your device. This will make sure that other device critical functions will continue to work. We will reserve at least 50k of free space. + +Q: What do I do with the rangetest.csv file when I'm done? +A: Go to /static and delete the file. + # Need more help? Go to the Meshtastic Discourse Group if you have any questions or to share how you have used this. From 703ce2e292eca62ccfaa7a1afa282b0d9974989c Mon Sep 17 00:00:00 2001 From: Jm Date: Sun, 14 Feb 2021 21:34:47 -0800 Subject: [PATCH 15/25] Keep device from sleeping while transmitting in range test plugin. --- docs/software/plugins/RangeTestPlugin.md | 3 +++ src/plugins/RangeTestPlugin.cpp | 4 ++++ 2 files changed, 7 insertions(+) diff --git a/docs/software/plugins/RangeTestPlugin.md b/docs/software/plugins/RangeTestPlugin.md index ba9f006f2..14a43d292 100644 --- a/docs/software/plugins/RangeTestPlugin.md +++ b/docs/software/plugins/RangeTestPlugin.md @@ -73,6 +73,9 @@ A: We have a protection in place to keep you from completly filling up your devi Q: What do I do with the rangetest.csv file when I'm done? A: Go to /static and delete the file. +Q: Can I use this as a sender while on battery power? +A: Yes, but your battery will run down quicker than normal. While sending, we tell the device not to go into low-power mode since it needs to keep to a fairly strict timer. + # Need more help? Go to the Meshtastic Discourse Group if you have any questions or to share how you have used this. diff --git a/src/plugins/RangeTestPlugin.cpp b/src/plugins/RangeTestPlugin.cpp index 7f99070ec..a789357d1 100644 --- a/src/plugins/RangeTestPlugin.cpp +++ b/src/plugins/RangeTestPlugin.cpp @@ -1,6 +1,7 @@ #include "RangeTestPlugin.h" #include "MeshService.h" #include "NodeDB.h" +#include "PowerFSM.h" #include "RTC.h" #include "Router.h" #include "configuration.h" @@ -117,6 +118,9 @@ void RangeTestPluginRadio::sendPayload(NodeNum dest, bool wantReplies) memcpy(p->decoded.data.payload.bytes, heartbeatString, p->decoded.data.payload.size); service.sendToMesh(p); + + // TODO: Handle this better. We want to keep the phone awake otherwise it stops sending. + powerFSM.trigger(EVENT_CONTACT_FROM_PHONE); } bool RangeTestPluginRadio::handleReceived(const MeshPacket &mp) From 8320754b985e8c8cebb42d72c3287fb1dab45d74 Mon Sep 17 00:00:00 2001 From: Jm Date: Sun, 14 Feb 2021 21:45:26 -0800 Subject: [PATCH 16/25] Added recommended settings as a sender --- docs/software/plugins/RangeTestPlugin.md | 7 +++++++ src/plugins/StoreForwardPlugin.cpp | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/docs/software/plugins/RangeTestPlugin.md b/docs/software/plugins/RangeTestPlugin.md index 14a43d292..0c5915f6b 100644 --- a/docs/software/plugins/RangeTestPlugin.md +++ b/docs/software/plugins/RangeTestPlugin.md @@ -38,6 +38,13 @@ To save a log of the messages: range_test_plugin_save = 1 +Recommended settings for a sender at different radio settings: + + Long Slow ... range_test_plugin_sender = 60 + Long Alt ... range_test_plugin_sender = 30 + Medium ... range_test_plugin_sender = 15 + Short Fast ... range_test_plugin_sender = 15 + ## Other things to keep in mind Be sure to turn off either the plugin configured as a sender or the device where the plugin setup as sender when not in use. This will use a lot of time on air and will spam your channel. diff --git a/src/plugins/StoreForwardPlugin.cpp b/src/plugins/StoreForwardPlugin.cpp index 087b34c1c..ef0b23090 100644 --- a/src/plugins/StoreForwardPlugin.cpp +++ b/src/plugins/StoreForwardPlugin.cpp @@ -21,7 +21,7 @@ int32_t StoreForwardPlugin::runOnce() without having to configure it from the PythonAPI or WebUI. */ - radioConfig.preferences.store_forward_plugin_enabled = 1; + radioConfig.preferences.store_forward_plugin_enabled = 0; radioConfig.preferences.is_router = 0; if (radioConfig.preferences.store_forward_plugin_enabled) { From 9a044f31a345cc61653408853d943a5147ebd747 Mon Sep 17 00:00:00 2001 From: Jm Date: Mon, 15 Feb 2021 09:11:28 -0800 Subject: [PATCH 17/25] Tweak to the startup condition of the range test plugin. --- src/plugins/RangeTestPlugin.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/plugins/RangeTestPlugin.cpp b/src/plugins/RangeTestPlugin.cpp index a789357d1..fad1991df 100644 --- a/src/plugins/RangeTestPlugin.cpp +++ b/src/plugins/RangeTestPlugin.cpp @@ -35,8 +35,8 @@ int32_t RangeTestPlugin::runOnce() without having to configure it from the PythonAPI or WebUI. */ - // radioConfig.preferences.range_test_plugin_enabled = 1; - // radioConfig.preferences.range_test_plugin_sender = 0; + //radioConfig.preferences.range_test_plugin_enabled = 1; + //radioConfig.preferences.range_test_plugin_sender = 45; // radioConfig.preferences.range_test_plugin_save = 1; // Fixed position is useful when testing indoors. @@ -56,7 +56,7 @@ int32_t RangeTestPlugin::runOnce() if (radioConfig.preferences.range_test_plugin_sender) { DEBUG_MSG("Initializing Range Test Plugin -- Sender\n"); - return (senderHeartbeat); + return (5000); // Sending first message 5 seconds after initilization. } else { DEBUG_MSG("Initializing Range Test Plugin -- Receiver\n"); return (500); @@ -76,7 +76,7 @@ int32_t RangeTestPlugin::runOnce() DEBUG_MSG("pref.fixed_position() %d\n", radioConfig.preferences.fixed_position); rangeTestPluginRadio->sendPayload(); - return ((senderHeartbeat)); + return (senderHeartbeat); } else { // Otherwise, we're a receiver. From d67e2187d0156791cd9ca083cef28d839bda10b9 Mon Sep 17 00:00:00 2001 From: Jm Casler Date: Mon, 15 Feb 2021 21:17:06 -0800 Subject: [PATCH 18/25] Update RangeTestPlugin.md --- docs/software/plugins/RangeTestPlugin.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/docs/software/plugins/RangeTestPlugin.md b/docs/software/plugins/RangeTestPlugin.md index 0c5915f6b..ee7732175 100644 --- a/docs/software/plugins/RangeTestPlugin.md +++ b/docs/software/plugins/RangeTestPlugin.md @@ -83,6 +83,9 @@ A: Go to /static and delete the file. Q: Can I use this as a sender while on battery power? A: Yes, but your battery will run down quicker than normal. While sending, we tell the device not to go into low-power mode since it needs to keep to a fairly strict timer. +Q: Why is this operating on incoming messages instead of the existing location discovery protocol? +A: This plugin is still young and currently supports monitoring just one port at a time. I decided to use the existing message port because that is easy to test with. A future version will listen to multiple ports to be more promiscuous. + # Need more help? Go to the Meshtastic Discourse Group if you have any questions or to share how you have used this. From 937955b36d1d9241eadbed3a494fe6af188853ea Mon Sep 17 00:00:00 2001 From: Jm Date: Tue, 16 Feb 2021 17:42:46 -0800 Subject: [PATCH 19/25] Updating range test and storeforward. --- docs/software/plugins/StoreForwardPlugin.md | 4 +- src/plugins/StoreForwardPlugin.cpp | 55 ++++++++++++++++++--- src/plugins/StoreForwardPlugin.h | 20 ++++++-- 3 files changed, 67 insertions(+), 12 deletions(-) diff --git a/docs/software/plugins/StoreForwardPlugin.md b/docs/software/plugins/StoreForwardPlugin.md index 6761f50e6..e05171ed8 100644 --- a/docs/software/plugins/StoreForwardPlugin.md +++ b/docs/software/plugins/StoreForwardPlugin.md @@ -65,9 +65,9 @@ Structure of received messages: Structure of nodes and last time we heard from them. This is a record of any packet type. - senderRecord + receivedRecord From - rxTimeMsec + rxTimeMillis # General Operation for UC1 - automagically forward packets to a client that may have missed packets diff --git a/src/plugins/StoreForwardPlugin.cpp b/src/plugins/StoreForwardPlugin.cpp index ef0b23090..af9bf5ecd 100644 --- a/src/plugins/StoreForwardPlugin.cpp +++ b/src/plugins/StoreForwardPlugin.cpp @@ -5,6 +5,7 @@ #include "Router.h" #include "configuration.h" #include +#include StoreForwardPlugin *storeForwardPlugin; StoreForwardPluginRadio *storeForwardPluginRadio; @@ -21,8 +22,8 @@ int32_t StoreForwardPlugin::runOnce() without having to configure it from the PythonAPI or WebUI. */ - radioConfig.preferences.store_forward_plugin_enabled = 0; - radioConfig.preferences.is_router = 0; + // radioConfig.preferences.store_forward_plugin_enabled = 1; + // radioConfig.preferences.is_router = 1; if (radioConfig.preferences.store_forward_plugin_enabled) { @@ -60,13 +61,16 @@ int32_t StoreForwardPlugin::runOnce() DEBUG_MSG( "Initializing Store & Forward Plugin - If you want to use this plugin, you must also turn on is_router.\n"); // Non-Router + + return (30 * 1000); } } else { - // TBD + // What do we do if it's not our first time? + + // Maybe some cleanup functions? } - return (1000); } else { DEBUG_MSG("Store & Forward Plugin - Disabled\n"); @@ -77,6 +81,43 @@ int32_t StoreForwardPlugin::runOnce() return (INT32_MAX); } +// We saw a node. +uint32_t StoreForwardPlugin::sawNode(uint32_t node) +{ + + /* + TODO: Move receivedRecord into the PSRAM + + TODO: Gracefully handle the case where we run out of records. + Maybe replace the oldest record that hasn't been seen in a while and assume they won't be back. + + TODO: Implment this as a std::map for quicker lookups (maybe it doesn't matter?). + */ + + DEBUG_MSG("looking for node - %i\n", node); + for (int i = 0; i < 50; i++) { + DEBUG_MSG("Iterating through the seen nodes - %d %d %d\n", i, receivedRecord[i][0], receivedRecord[i][1]); + // First time seeing that node. + if (receivedRecord[i][0] == 0) { + DEBUG_MSG("New node! Woohoo! Win!\n"); + receivedRecord[i][0] = node; + receivedRecord[i][1] = millis(); + + return receivedRecord[i][1]; + } + + // We've seen this node before. + if (receivedRecord[i][0] == node) { + DEBUG_MSG("We've seen this node before\n"); + uint32_t lastSaw = receivedRecord[i][1]; + receivedRecord[i][1] = millis(); + return lastSaw; + } + } + + return 0; +} + MeshPacket *StoreForwardPluginRadio::allocReply() { @@ -101,9 +142,11 @@ bool StoreForwardPluginRadio::handleReceived(const MeshPacket &mp) // auto &p = mp.decoded.data; if (mp.from != nodeDB.getNodeNum()) { - DEBUG_MSG("Store & Forward Plugin -- Print Start ---------- ---------- ---------- ---------- ----------\n"); + DEBUG_MSG("Store & Forward Plugin -- Print Start ---------- ---------- ---------- ---------- ----------\n\n\n"); printPacket("----- PACKET FROM RADIO", &mp); - DEBUG_MSG("Store & Forward Plugin -- Print End ---------- ---------- ---------- ---------- ----------\n"); + // DEBUG_MSG("\n\nStore & Forward Plugin -- Print End ---------- ---------- ---------- ---------- ----------\n"); + uint32_t sawTime = storeForwardPlugin->sawNode(mp.from); + DEBUG_MSG("Last Saw this node %d, %d millis ago\n", mp.from, (millis() - sawTime)); } } else { diff --git a/src/plugins/StoreForwardPlugin.h b/src/plugins/StoreForwardPlugin.h index be9634913..e44d53704 100644 --- a/src/plugins/StoreForwardPlugin.h +++ b/src/plugins/StoreForwardPlugin.h @@ -10,9 +10,22 @@ class StoreForwardPlugin : private concurrency::OSThread { bool firstTime = 1; + // TODO: Move this into the PSRAM + // TODO: Allow configuration of the maximum number of records. + uint32_t receivedRecord[50][2] = {{0}}; + public: StoreForwardPlugin(); + /** + Update our local reference of when we last saw that node. + @return 0 if we have never seen that node before otherwise return the last time we saw the node. + */ + uint32_t sawNode(uint32_t); + + private: + // Nothing here + protected: virtual int32_t runOnce(); }; @@ -25,11 +38,11 @@ extern StoreForwardPlugin *storeForwardPlugin; */ class StoreForwardPluginRadio : public SinglePortPlugin { - //uint32_t lastRxID; + // uint32_t lastRxID; public: StoreForwardPluginRadio() : SinglePortPlugin("StoreForwardPluginRadio", PortNum_STORE_FORWARD_APP) {} - //StoreForwardPluginRadio() : SinglePortPlugin("StoreForwardPluginRadio", PortNum_TEXT_MESSAGE_APP) {} + // StoreForwardPluginRadio() : SinglePortPlugin("StoreForwardPluginRadio", PortNum_TEXT_MESSAGE_APP) {} /** * Send our payload into the mesh @@ -39,7 +52,7 @@ class StoreForwardPluginRadio : public SinglePortPlugin protected: virtual MeshPacket *allocReply(); - virtual bool wantPortnum(PortNum p){return true;}; + virtual bool wantPortnum(PortNum p) { return true; }; /** Called to handle a particular incoming message @@ -49,4 +62,3 @@ class StoreForwardPluginRadio : public SinglePortPlugin }; extern StoreForwardPluginRadio *storeForwardPluginRadio; - From a4fd74b58ec78309f848b0e2ce8a32267bcf9cb8 Mon Sep 17 00:00:00 2001 From: Jm Date: Tue, 16 Feb 2021 18:07:02 -0800 Subject: [PATCH 20/25] Update Plugins.cpp --- src/plugins/Plugins.cpp | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/plugins/Plugins.cpp b/src/plugins/Plugins.cpp index 69e68ea4f..0c18389b4 100644 --- a/src/plugins/Plugins.cpp +++ b/src/plugins/Plugins.cpp @@ -1,12 +1,15 @@ #include "plugins/ExternalNotificationPlugin.h" #include "plugins/NodeInfoPlugin.h" #include "plugins/PositionPlugin.h" -#include "plugins/RangeTestPlugin.h" #include "plugins/RemoteHardwarePlugin.h" #include "plugins/ReplyPlugin.h" +#include "plugins/TextMessagePlugin.h" + +#ifndef NO_ESP32 +#include "plugins/RangeTestPlugin.h" #include "plugins/SerialPlugin.h" #include "plugins/StoreForwardPlugin.h" -#include "plugins/TextMessagePlugin.h" +#endif /** * Create plugin instances here. If you are adding a new plugin, you must 'new' it here (or somewhere else) @@ -32,10 +35,10 @@ void setupPlugins() new SerialPlugin(); new ExternalNotificationPlugin(); - //rangeTestPlugin = new RangeTestPlugin(); + // rangeTestPlugin = new RangeTestPlugin(); storeForwardPlugin = new StoreForwardPlugin(); new RangeTestPlugin(); - //new StoreForwardPlugin(); + // new StoreForwardPlugin(); #endif } \ No newline at end of file From b35cd7685456b5f74b5580115cd92e3a9b71f23a Mon Sep 17 00:00:00 2001 From: Jm Casler Date: Tue, 16 Feb 2021 18:19:24 -0800 Subject: [PATCH 21/25] Update StoreForwardPlugin.md --- docs/software/plugins/StoreForwardPlugin.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/docs/software/plugins/StoreForwardPlugin.md b/docs/software/plugins/StoreForwardPlugin.md index e05171ed8..cb104314a 100644 --- a/docs/software/plugins/StoreForwardPlugin.md +++ b/docs/software/plugins/StoreForwardPlugin.md @@ -51,6 +51,10 @@ In this case, we have two routers separate by a great distance, each serving mul Q: How do we rejoin both fragmented networks? Do we care about messages that were unrouted between fagments? +## Identifing Delayed Messages + +When a message is replayed for a node, identify the packet as "Delayed". This will indicate that the message was not received in real time. + # Router Data Structures Structure of received messages: @@ -90,4 +94,4 @@ On every handled packet, if we have not heard from that sender in a period of ti # Designed limitations -The Store and Forward plugin will subscribe to specific packet types and channels and only save those. This will both reduce the amount of data we will need to store and reduce the overhead on the network. Eg: There's no need to replay ACK packets nor is there's no need to replay old location packets. \ No newline at end of file +The Store and Forward plugin will subscribe to specific packet types and channels and only save those. This will both reduce the amount of data we will need to store and reduce the overhead on the network. Eg: There's no need to replay ACK packets nor is there's no need to replay old location packets. From bd29d78a29dcb6b3b8de33b33dc4ec3e089ff1ba Mon Sep 17 00:00:00 2001 From: Jm Casler Date: Tue, 16 Feb 2021 18:24:37 -0800 Subject: [PATCH 22/25] Update StoreForwardPlugin.md --- docs/software/plugins/StoreForwardPlugin.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/software/plugins/StoreForwardPlugin.md b/docs/software/plugins/StoreForwardPlugin.md index cb104314a..129005baf 100644 --- a/docs/software/plugins/StoreForwardPlugin.md +++ b/docs/software/plugins/StoreForwardPlugin.md @@ -27,6 +27,8 @@ UC 3) router sends a periodic “heartbeat” to let the clients know they’re UC 4) support for a mesh to have multiple routers that have the store & forward functionality (for redundancy) +UC 5) Support for "long term" delayed messages and "short term" delayed messages. Handle the cases slightly different to improve user expierence. A short term delayed message would be a message that was resent becaue a node was not heard from for <5 minutes. A long term delayed message is a message that has not been delivered in >5 minutes. + # Things to consider Not all these cases will be initially implemented. It's just a running stream of thoughts to be considered. From 6376ab51f1e5f7888e31794b56a4554540c6e8b5 Mon Sep 17 00:00:00 2001 From: Jm Casler Date: Tue, 16 Feb 2021 18:36:30 -0800 Subject: [PATCH 23/25] Moving to plugins/esp32 --- src/plugins/{ => esp32}/RangeTestPlugin.cpp | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename src/plugins/{ => esp32}/RangeTestPlugin.cpp (100%) diff --git a/src/plugins/RangeTestPlugin.cpp b/src/plugins/esp32/RangeTestPlugin.cpp similarity index 100% rename from src/plugins/RangeTestPlugin.cpp rename to src/plugins/esp32/RangeTestPlugin.cpp From f24e8e5f5c4b26bc866395a17aa8f2183075f4fa Mon Sep 17 00:00:00 2001 From: Jm Casler Date: Tue, 16 Feb 2021 18:36:58 -0800 Subject: [PATCH 24/25] Rename src/plugins/RangeTestPlugin.h to src/plugins/esp32/RangeTestPlugin.h --- src/plugins/{ => esp32}/RangeTestPlugin.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename src/plugins/{ => esp32}/RangeTestPlugin.h (96%) diff --git a/src/plugins/RangeTestPlugin.h b/src/plugins/esp32/RangeTestPlugin.h similarity index 96% rename from src/plugins/RangeTestPlugin.h rename to src/plugins/esp32/RangeTestPlugin.h index 8a10ca395..be998e510 100644 --- a/src/plugins/RangeTestPlugin.h +++ b/src/plugins/esp32/RangeTestPlugin.h @@ -55,4 +55,4 @@ class RangeTestPluginRadio : public SinglePortPlugin virtual bool handleReceived(const MeshPacket &mp); }; -extern RangeTestPluginRadio *rangeTestPluginRadio; \ No newline at end of file +extern RangeTestPluginRadio *rangeTestPluginRadio; From e840465ef3429046258af5dbafb1c2d0cc6bab75 Mon Sep 17 00:00:00 2001 From: Jm Date: Tue, 16 Feb 2021 18:46:16 -0800 Subject: [PATCH 25/25] fix for failed builds on nrf and linux --- platformio.ini | 4 ++-- src/plugins/Plugins.cpp | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/platformio.ini b/platformio.ini index 4b91317d9..89cf5a1ac 100644 --- a/platformio.ini +++ b/platformio.ini @@ -188,7 +188,7 @@ build_flags = -Isdk-nrfxlib/crypto/nrf_oberon/include -Lsdk-nrfxlib/crypto/nrf_oberon/lib/cortex-m4/hard-float/ -lliboberon_3.0.7 ;-DCFG_DEBUG=3 src_filter = - ${arduino_base.src_filter} - - - - + ${arduino_base.src_filter} - - - - - lib_ignore = BluetoothOTA monitor_port = /dev/ttyACM1 @@ -329,7 +329,7 @@ lib_deps = ; The Portduino based sim environment on top of linux [env:linux] platform = https://github.com/geeksville/platform-portduino.git -src_filter = ${env.src_filter} - - - - +src_filter = ${env.src_filter} - - - - - build_flags = ${arduino_base.build_flags} -O0 framework = arduino board = linux_x86_64 diff --git a/src/plugins/Plugins.cpp b/src/plugins/Plugins.cpp index 0c18389b4..c2dfd73ca 100644 --- a/src/plugins/Plugins.cpp +++ b/src/plugins/Plugins.cpp @@ -6,7 +6,7 @@ #include "plugins/TextMessagePlugin.h" #ifndef NO_ESP32 -#include "plugins/RangeTestPlugin.h" +#include "plugins/esp32/RangeTestPlugin.h" #include "plugins/SerialPlugin.h" #include "plugins/StoreForwardPlugin.h" #endif