From 92a62d93ef0e93072493ea4009c844e01a377eec Mon Sep 17 00:00:00 2001 From: Jm Casler Date: Sat, 13 Feb 2021 22:21:01 -0800 Subject: [PATCH 01/36] #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 8f03589c..c719ad04 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 f66744db..8a10ca39 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/36] #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 00000000..9fd9b272 --- /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/36] #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 f71fb965..c8272456 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 e9dac9b4..952206c5 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/36] 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 571ac4ed..3877a0c0 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/36] 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 3877a0c0..97b8f49e 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/36] 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 97b8f49e..2b3aa71a 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/36] 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 2b3aa71a..6761f50e 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 505eff7d..b36919fd 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 ac8dd733..46f85410 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 c719ad04..f8e4f53d 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 c8272456..633aaa5e 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 952206c5..f40c7aa4 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/36] 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 f8e4f53d..a1c69b10 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 633aaa5e..2db4d735 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 f40c7aa4..1a27222f 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/36] #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 46f85410..6fe1459f 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 a1c69b10..7f99070e 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 00000000..3df421af --- /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 00000000..29d11ea7 --- /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/36] 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 6fe1459f..46f85410 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/36] 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 46f85410..69e68ea4 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 3df421af..00000000 --- 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 29d11ea7..00000000 --- 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 2db4d735..087b34c1 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 1a27222f..be963491 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/36] 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 9fd9b272..998ce4f0 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/36] 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 998ce4f0..58baff1e 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/36] 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 58baff1e..ba9f006f 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/36] 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 ba9f006f..14a43d29 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 7f99070e..a789357d 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/36] 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 14a43d29..0c5915f6 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 087b34c1..ef0b2309 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/36] 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 a789357d..fad1991d 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 c8584d576aca41b5f92695b1600841fcb3e63a18 Mon Sep 17 00:00:00 2001 From: geoffreyheller Date: Mon, 15 Feb 2021 19:33:35 -0800 Subject: [PATCH 18/36] Fix for non-working tx pin --- src/configuration.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/configuration.h b/src/configuration.h index 26742087..4fd395fd 100644 --- a/src/configuration.h +++ b/src/configuration.h @@ -343,7 +343,7 @@ along with this program. If not, see . #undef GPS_RX_PIN #undef GPS_TX_PIN #define GPS_RX_PIN 36 -#define GPS_TX_PIN 39 +#define GPS_TX_PIN 13 #define BATTERY_PIN 35 // A battery voltage measurement pin, voltage divider connected here to measure battery voltage From d67e2187d0156791cd9ca083cef28d839bda10b9 Mon Sep 17 00:00:00 2001 From: Jm Casler Date: Mon, 15 Feb 2021 21:17:06 -0800 Subject: [PATCH 19/36] 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 0c5915f6..ee773217 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 20/36] 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 6761f50e..e05171ed 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 ef0b2309..af9bf5ec 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 be963491..e44d5370 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 21/36] 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 69e68ea4..0c18389b 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 22/36] 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 e05171ed..cb104314 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 23/36] 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 cb104314..129005ba 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 24/36] 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 25/36] 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 8a10ca39..be998e51 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 26/36] 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 4b91317d..89cf5a1a 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 0c18389b..c2dfd73c 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 From 13b8c140b46f70b0c784819e4e893b38896832bd Mon Sep 17 00:00:00 2001 From: Jm Date: Thu, 18 Feb 2021 21:47:16 -0800 Subject: [PATCH 27/36] Update StoreForwardPlugin.md --- docs/software/plugins/StoreForwardPlugin.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/docs/software/plugins/StoreForwardPlugin.md b/docs/software/plugins/StoreForwardPlugin.md index 129005ba..02389e42 100644 --- a/docs/software/plugins/StoreForwardPlugin.md +++ b/docs/software/plugins/StoreForwardPlugin.md @@ -29,6 +29,12 @@ UC 4) support for a mesh to have multiple routers that have the store & forward 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. +UC 6) Eventually we could add a "want_store_and_forward" bit to MeshPacket and that could be nicer than whitelists in this plugin. Initially we'd only set that bit in text messages (and any other plugin messages that can cope with this). This change would be backward wire compatible so can add easily later. + +UC 7) Currently the way we allocate messages in the device code is super inefficient. It always allocates the worst case message size. Really we should dynamically allocate just the # of bytes we need. This would allow many more MeshPackets to be kept in RAM. + +UC 8) We'll want a "delayed" bit in MeshPacket. This will indicate that the message was not received in real time. + # Things to consider Not all these cases will be initially implemented. It's just a running stream of thoughts to be considered. From a2bea87332be9b9a37f1983d2f3486c3cc719bdc Mon Sep 17 00:00:00 2001 From: Charles Crossan Date: Fri, 19 Feb 2021 19:24:18 -0500 Subject: [PATCH 28/36] Fix exception decoder output --- bin/exception_decoder.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bin/exception_decoder.py b/bin/exception_decoder.py index 0286e1c1..8ef66b9b 100755 --- a/bin/exception_decoder.py +++ b/bin/exception_decoder.py @@ -241,7 +241,7 @@ def print_addr(name, value, resolver): def print_stack_full(lines, resolver): print("stack:") for line in lines: - print(line.offset + ":") + print(str(line.offset) + ":") for content in line.content: print(" " + resolver.resolve_stack_addr(content)) From 621313d63cd5630827e906247c595ed4e487e9e4 Mon Sep 17 00:00:00 2001 From: Jm Date: Fri, 19 Feb 2021 16:58:52 -0800 Subject: [PATCH 29/36] #701 - Add system up time to debug output --- src/RedirectablePrint.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/RedirectablePrint.cpp b/src/RedirectablePrint.cpp index 541b55c7..c60b8a50 100644 --- a/src/RedirectablePrint.cpp +++ b/src/RedirectablePrint.cpp @@ -78,9 +78,9 @@ size_t RedirectablePrint::logDebug(const char *format, ...) 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); + r += printf("%02d:%02d:%02d %u ", hour, min, sec, millis() / 1000); } else - r += printf("??:??:?? "); + r += printf("??:??:?? %u ", millis() / 1000); auto thread = concurrency::OSThread::currentThread; if(thread) { From 47b942ca00ac3786d38ab018b5c4e6ba224653fa Mon Sep 17 00:00:00 2001 From: Jm Date: Fri, 19 Feb 2021 17:46:15 -0800 Subject: [PATCH 30/36] #697 - Fixed button selection for tlora v2 1.6 --- src/configuration.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/configuration.h b/src/configuration.h index 4fd395fd..e5b80efe 100644 --- a/src/configuration.h +++ b/src/configuration.h @@ -355,7 +355,7 @@ along with this program. If not, see . #define VEXT_ENABLE 21 // active low, powers the oled display and the lora antenna boost #define LED_PIN 25 // If defined we will blink this LED #define BUTTON_PIN \ - 12 // If defined, this will be used for user button presses, if your board doesn't have a physical switch, you can wire one + 34 // If defined, this will be used for user button presses, if your board doesn't have a physical switch, you can wire one // between this pin and ground #define BUTTON_NEED_PULLUP From c690f8157437865a8293a891db6384511b97e5ca Mon Sep 17 00:00:00 2001 From: Jm Date: Fri, 19 Feb 2021 18:19:14 -0800 Subject: [PATCH 31/36] #697 Disable internal pullup on this board. --- src/configuration.h | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/configuration.h b/src/configuration.h index e5b80efe..55612a12 100644 --- a/src/configuration.h +++ b/src/configuration.h @@ -355,9 +355,14 @@ along with this program. If not, see . #define VEXT_ENABLE 21 // active low, powers the oled display and the lora antenna boost #define LED_PIN 25 // If defined we will blink this LED #define BUTTON_PIN \ - 34 // If defined, this will be used for user button presses, if your board doesn't have a physical switch, you can wire one + 12 // If defined, this will be used for user button presses, if your board doesn't have a physical switch, you can wire one // between this pin and ground -#define BUTTON_NEED_PULLUP + +/* Don't enable the internal pull up on the TLORA_V2_1_16. GPIO 12 is connected to a bidirectional + diode. If someone needs to use a button, they should connect an external pull up that's stronger + than what's built into the esp32 +*/ +// #define BUTTON_NEED_PULLUP #define USE_RF95 #define LORA_DIO0 26 // a No connect on the SX1262 module From e4141df0e9ddb2f95dd01daa548b6c3453a82533 Mon Sep 17 00:00:00 2001 From: Jm Date: Sat, 20 Feb 2021 00:34:25 -0800 Subject: [PATCH 32/36] #697 GPIO 12 is an odd pin. --- src/configuration.h | 19 +++++++------------ src/main.cpp | 7 +++++-- 2 files changed, 12 insertions(+), 14 deletions(-) diff --git a/src/configuration.h b/src/configuration.h index 55612a12..cb68a2e3 100644 --- a/src/configuration.h +++ b/src/configuration.h @@ -354,15 +354,9 @@ along with this program. If not, see . #define VEXT_ENABLE 21 // active low, powers the oled display and the lora antenna boost #define LED_PIN 25 // If defined we will blink this LED -#define BUTTON_PIN \ - 12 // If defined, this will be used for user button presses, if your board doesn't have a physical switch, you can wire one - // between this pin and ground +#define BUTTON_PIN 12 // If defined, this will be used for user button presses, -/* Don't enable the internal pull up on the TLORA_V2_1_16. GPIO 12 is connected to a bidirectional - diode. If someone needs to use a button, they should connect an external pull up that's stronger - than what's built into the esp32 -*/ -// #define BUTTON_NEED_PULLUP +#define BUTTON_NEED_PULLUP #define USE_RF95 #define LORA_DIO0 26 // a No connect on the SX1262 module @@ -380,15 +374,16 @@ along with this program. If not, see . #define GPS_RESET_N 10 #define GPS_EXTINT 23 // On MAX-M8 module pin name is EXTINT. On L70 module pin name is STANDBY. -#define BATTERY_PIN 39 // A battery voltage measurement pin, voltage divider connected here to measure battery voltage +#define BATTERY_PIN 39 // A battery voltage measurement pin, voltage divider connected here to measure battery voltage #define BATTERY_EN_PIN 14 // Voltage voltage divider enable pin connected to mosfet #define I2C_SDA 4 // I2C pins for this board #define I2C_SCL 2 -#define LED_PIN 12 // If defined we will blink this LED -//#define BUTTON_PIN 36 // If defined, this will be used for user button presses (ToDo problem on that line on debug screen --> Long press start!) -//#define BUTTON_NEED_PULLUP //GPIOs 34 to 39 are GPIs – input only pins. These pins don’t have internal pull-ups or pull-down resistors. +#define LED_PIN 12 // If defined we will blink this LED +//#define BUTTON_PIN 36 // If defined, this will be used for user button presses (ToDo problem on that line on debug screen --> +//Long press start!) #define BUTTON_NEED_PULLUP //GPIOs 34 to 39 are GPIs – input only pins. These pins don’t have internal +//pull-ups or pull-down resistors. #define USE_RF95 #define LORA_DIO0 38 // a No connect on the SX1262 module diff --git a/src/main.cpp b/src/main.cpp index bb3ec482..9bd34c23 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -305,12 +305,15 @@ void setup() #ifdef BUTTON_PIN #ifndef NO_ESP32 - // If BUTTON_PIN is held down during the startup process, - // force the device to go into a SoftAP mode. bool forceSoftAP = 0; + + // If the button is connected to GPIO 12, don't enable the ability to use + // meshtasticAdmin on the device. pinMode(BUTTON_PIN, INPUT); + #ifdef BUTTON_NEED_PULLUP gpio_pullup_en((gpio_num_t)BUTTON_PIN); + delay(10); #endif // BUTTON_PIN is pulled high by a 12k resistor. From ca40cb4be33ef05f4c29b9bb147ddfc8c1b4c634 Mon Sep 17 00:00:00 2001 From: Jm Date: Sat, 20 Feb 2021 00:43:56 -0800 Subject: [PATCH 33/36] Update RangeTestPlugin.cpp --- src/plugins/esp32/RangeTestPlugin.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/esp32/RangeTestPlugin.cpp b/src/plugins/esp32/RangeTestPlugin.cpp index fad1991d..d453574f 100644 --- a/src/plugins/esp32/RangeTestPlugin.cpp +++ b/src/plugins/esp32/RangeTestPlugin.cpp @@ -37,7 +37,7 @@ int32_t RangeTestPlugin::runOnce() //radioConfig.preferences.range_test_plugin_enabled = 1; //radioConfig.preferences.range_test_plugin_sender = 45; - // radioConfig.preferences.range_test_plugin_save = 1; + //radioConfig.preferences.range_test_plugin_save = 1; // Fixed position is useful when testing indoors. // radioConfig.preferences.fixed_position = 1; From 3c564796e0f540a5d25243ab23f9929c8312ff9b Mon Sep 17 00:00:00 2001 From: Charles Crossan Date: Sun, 17 Jan 2021 15:59:48 -0500 Subject: [PATCH 34/36] --- platformio.ini | 2 + proto | 2 +- .../generated/environmental_measurement.pb.c | 12 ++ .../generated/environmental_measurement.pb.h | 53 +++++++++ src/mesh/generated/portnums.pb.h | 1 + src/plugins/Plugins.cpp | 2 + .../esp32/EnvironmentalMeasurementPlugin.cpp | 104 ++++++++++++++++++ .../esp32/EnvironmentalMeasurementPlugin.h | 45 ++++++++ 8 files changed, 220 insertions(+), 1 deletion(-) create mode 100644 src/mesh/generated/environmental_measurement.pb.c create mode 100644 src/mesh/generated/environmental_measurement.pb.h create mode 100644 src/plugins/esp32/EnvironmentalMeasurementPlugin.cpp create mode 100644 src/plugins/esp32/EnvironmentalMeasurementPlugin.h diff --git a/platformio.ini b/platformio.ini index 89cf5a1a..39b57dd9 100644 --- a/platformio.ini +++ b/platformio.ini @@ -104,6 +104,8 @@ build_flags = lib_deps = ${arduino_base.lib_deps} https://github.com/meshtastic/esp32_https_server.git + adafruit/DHT sensor library@^1.4.1 + adafruit/Adafruit Unified Sensor@^1.1.4 # Hmm - this doesn't work yet # board_build.ldscript = linker/esp32.extram.bss.ld lib_ignore = segger_rtt diff --git a/proto b/proto index 0cadaed3..564292ee 160000 --- a/proto +++ b/proto @@ -1 +1 @@ -Subproject commit 0cadaed3953f66cf1edc99d0fa53e4fd5ebf56d6 +Subproject commit 564292ee83bbd085d0c51a7f882d3a2aa305d6d6 diff --git a/src/mesh/generated/environmental_measurement.pb.c b/src/mesh/generated/environmental_measurement.pb.c new file mode 100644 index 00000000..b55d14a0 --- /dev/null +++ b/src/mesh/generated/environmental_measurement.pb.c @@ -0,0 +1,12 @@ +/* Automatically generated nanopb constant definitions */ +/* Generated by nanopb-0.4.4 */ + +#include "environmental_measurement.pb.h" +#if PB_PROTO_HEADER_VERSION != 40 +#error Regenerate this file with the current version of nanopb generator. +#endif + +PB_BIND(EnvironmentalMeasurement, EnvironmentalMeasurement, AUTO) + + + diff --git a/src/mesh/generated/environmental_measurement.pb.h b/src/mesh/generated/environmental_measurement.pb.h new file mode 100644 index 00000000..8adf5774 --- /dev/null +++ b/src/mesh/generated/environmental_measurement.pb.h @@ -0,0 +1,53 @@ +/* Automatically generated nanopb header */ +/* Generated by nanopb-0.4.4 */ + +#ifndef PB_ENVIRONMENTAL_MEASUREMENT_PB_H_INCLUDED +#define PB_ENVIRONMENTAL_MEASUREMENT_PB_H_INCLUDED +#include + +#if PB_PROTO_HEADER_VERSION != 40 +#error Regenerate this file with the current version of nanopb generator. +#endif + +/* Struct definitions */ +typedef struct _EnvironmentalMeasurement { + float temperature; + float relative_humidity; + float barometric_pressure; +} EnvironmentalMeasurement; + + +#ifdef __cplusplus +extern "C" { +#endif + +/* Initializer values for message structs */ +#define EnvironmentalMeasurement_init_default {0, 0, 0} +#define EnvironmentalMeasurement_init_zero {0, 0, 0} + +/* Field tags (for use in manual encoding/decoding) */ +#define EnvironmentalMeasurement_temperature_tag 1 +#define EnvironmentalMeasurement_relative_humidity_tag 2 +#define EnvironmentalMeasurement_barometric_pressure_tag 3 + +/* Struct field encoding specification for nanopb */ +#define EnvironmentalMeasurement_FIELDLIST(X, a) \ +X(a, STATIC, SINGULAR, FLOAT, temperature, 1) \ +X(a, STATIC, SINGULAR, FLOAT, relative_humidity, 2) \ +X(a, STATIC, SINGULAR, FLOAT, barometric_pressure, 3) +#define EnvironmentalMeasurement_CALLBACK NULL +#define EnvironmentalMeasurement_DEFAULT NULL + +extern const pb_msgdesc_t EnvironmentalMeasurement_msg; + +/* Defines for backwards compatibility with code written before nanopb-0.4.0 */ +#define EnvironmentalMeasurement_fields &EnvironmentalMeasurement_msg + +/* Maximum encoded size of messages (where known) */ +#define EnvironmentalMeasurement_size 15 + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif diff --git a/src/mesh/generated/portnums.pb.h b/src/mesh/generated/portnums.pb.h index 2133ecaa..8d262c47 100644 --- a/src/mesh/generated/portnums.pb.h +++ b/src/mesh/generated/portnums.pb.h @@ -18,6 +18,7 @@ typedef enum _PortNum { PortNum_NODEINFO_APP = 4, PortNum_REPLY_APP = 32, PortNum_IP_TUNNEL_APP = 33, + PortNum_ENVIRONMENTAL_MEASUREMENT_APP = 34, PortNum_SERIAL_APP = 64, PortNum_STORE_FORWARD_APP = 65, PortNum_RANGE_TEST_APP = 66, diff --git a/src/plugins/Plugins.cpp b/src/plugins/Plugins.cpp index c2dfd73c..233c5f37 100644 --- a/src/plugins/Plugins.cpp +++ b/src/plugins/Plugins.cpp @@ -6,6 +6,7 @@ #include "plugins/TextMessagePlugin.h" #ifndef NO_ESP32 +#include "plugins/esp32/EnvironmentalMeasurementPlugin.h" #include "plugins/esp32/RangeTestPlugin.h" #include "plugins/SerialPlugin.h" #include "plugins/StoreForwardPlugin.h" @@ -19,6 +20,7 @@ void setupPlugins() nodeInfoPlugin = new NodeInfoPlugin(); positionPlugin = new PositionPlugin(); textMessagePlugin = new TextMessagePlugin(); + environmentalMeasurementPlugin = new EnvironmentalMeasurementPlugin(); // Note: if the rest of meshtastic doesn't need to explicitly use your plugin, you do not need to assign the instance // to a global variable. diff --git a/src/plugins/esp32/EnvironmentalMeasurementPlugin.cpp b/src/plugins/esp32/EnvironmentalMeasurementPlugin.cpp new file mode 100644 index 00000000..75bb0911 --- /dev/null +++ b/src/plugins/esp32/EnvironmentalMeasurementPlugin.cpp @@ -0,0 +1,104 @@ +#include "EnvironmentalMeasurementPlugin.h" +#include "MeshService.h" +#include "NodeDB.h" +#include "RTC.h" +#include "Router.h" +#include "configuration.h" +#include "main.h" +#include "../mesh/generated/environmental_measurement.pb.h" +#include + +EnvironmentalMeasurementPlugin *environmentalMeasurementPlugin; +EnvironmentalMeasurementPluginRadio *environmentalMeasurementPluginRadio; + +EnvironmentalMeasurementPlugin::EnvironmentalMeasurementPlugin() : concurrency::OSThread("EnvironmentalMeasurementPlugin") {} + +uint32_t sensor_read_error_count = 0; + +#define DHT_11_GPIO_PIN 13 +//TODO: Make a related radioconfig preference to allow less-frequent reads +#define DHT_SENSOR_MINIMUM_WAIT_TIME_BETWEEN_READS 1000 +#define SENSOR_READ_ERROR_COUNT_THRESHOLD 5 +#define SENSOR_READ_MULTIPLIER 3 + + +DHT dht(DHT_11_GPIO_PIN,DHT11); + +int32_t EnvironmentalMeasurementPlugin::runOnce() { +#ifndef NO_ESP32 + if (firstTime) { + // This is the first time the OSThread library has called this function, so do some setup + DEBUG_MSG("Initializing Environmental Measurement Plugin -- Sender\n"); + environmentalMeasurementPluginRadio = new EnvironmentalMeasurementPluginRadio(); + firstTime = 0; + // begin reading measurements from the sensor + // DHT have a max read-rate of 1HZ, so we should wait at least 1 second + // after initializing the sensor before we try to read from it. + // returning the interval here means that the next time OSThread + // calls our plugin, we'll run the other branch of this if statement + // and actually do a "sendOurEnvironmentalMeasurement()" + dht.begin(); + return(DHT_SENSOR_MINIMUM_WAIT_TIME_BETWEEN_READS); + } + else { + // this is not the first time OSThread library has called this function + // so just do what we intend to do on the interval + if(sensor_read_error_count > SENSOR_READ_ERROR_COUNT_THRESHOLD) + { + DEBUG_MSG("Environmental Measurement Plugin: DISABLED; The SENSOR_READ_ERROR_COUNT_THRESHOLD has been exceed: %d\n",SENSOR_READ_ERROR_COUNT_THRESHOLD); + return(DHT_SENSOR_MINIMUM_WAIT_TIME_BETWEEN_READS); + } + else if (sensor_read_error_count > 0){ + DEBUG_MSG("Environmental Measurement Plugin: There have been %d sensor read failures.\n",sensor_read_error_count); + } + if (! environmentalMeasurementPluginRadio->sendOurEnvironmentalMeasurement() ){ + // if we failed to read the sensor, then try again + // as soon as we can according to the maximum polling frequency + return(DHT_SENSOR_MINIMUM_WAIT_TIME_BETWEEN_READS); + } + } + // The return of runOnce is an int32 representing the desired number of + // miliseconds until the function should be called again by the + // OSThread library. + return(SENSOR_READ_MULTIPLIER * DHT_SENSOR_MINIMUM_WAIT_TIME_BETWEEN_READS); +#endif +} + +bool EnvironmentalMeasurementPluginRadio::handleReceivedProtobuf(const MeshPacket &mp, const EnvironmentalMeasurement &p) +{ + // This plugin doesn't really do anything with the messages it receives. + return false; // Let others look at this message also if they want +} + +bool EnvironmentalMeasurementPluginRadio::sendOurEnvironmentalMeasurement(NodeNum dest, bool wantReplies) +{ + EnvironmentalMeasurement m; + + m.barometric_pressure=0; + float t = dht.readTemperature(); + float h = dht.readHumidity(); + m.relative_humidity= 0; + m.temperature=0; + + DEBUG_MSG("-----------------------------------------\n"); + + DEBUG_MSG("Environmental Measurement Plugin: Read data\n"); + DEBUG_MSG("EnvironmentalMeasurement->relative_humidity: %f\n",h); + DEBUG_MSG("EnvironmentalMeasurement->temperature: %f\n",t); + + if (isnan(h) || isnan(t) ){ + sensor_read_error_count++; + DEBUG_MSG("Environmental Measurement Plugin: FAILED TO READ DATA\n"); + return false; + } + + sensor_read_error_count = 0; + + MeshPacket *p = allocDataProtobuf(m); + p->to = dest; + p->decoded.want_response = wantReplies; + + service.sendToMesh(p); + return true; +} + diff --git a/src/plugins/esp32/EnvironmentalMeasurementPlugin.h b/src/plugins/esp32/EnvironmentalMeasurementPlugin.h new file mode 100644 index 00000000..31581b31 --- /dev/null +++ b/src/plugins/esp32/EnvironmentalMeasurementPlugin.h @@ -0,0 +1,45 @@ +#pragma once +#include "ProtobufPlugin.h" +#include "../mesh/generated/environmental_measurement.pb.h" + + +class EnvironmentalMeasurementPlugin : private concurrency::OSThread +{ + bool firstTime = 1; + + public: + EnvironmentalMeasurementPlugin(); + + protected: + virtual int32_t runOnce(); +}; + +extern EnvironmentalMeasurementPlugin *environmentalMeasurementPlugin; + +/** + * EnvironmentalMeasurementPluginRadio plugin for sending/receiving environmental measurements to/from the mesh + */ +class EnvironmentalMeasurementPluginRadio : public ProtobufPlugin +{ + public: + /** Constructor + * name is for debugging output + */ + EnvironmentalMeasurementPluginRadio() : ProtobufPlugin("EnvironmentalMeasurement", PortNum_ENVIRONMENTAL_MEASUREMENT_APP, &EnvironmentalMeasurement_msg) {} + + /** + * Send our EnvironmentalMeasurement into the mesh + */ + bool sendOurEnvironmentalMeasurement(NodeNum dest = NODENUM_BROADCAST, bool wantReplies = false); + + protected: + + /** 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 handleReceivedProtobuf(const MeshPacket &mp, const EnvironmentalMeasurement &p); + +}; + +extern EnvironmentalMeasurementPluginRadio *environmentalMeasurementPluginRadio; \ No newline at end of file From 77961e8e9366d68c4a10b23d870bc17d5918928f Mon Sep 17 00:00:00 2001 From: Charles Crossan Date: Sun, 21 Feb 2021 11:00:58 -0500 Subject: [PATCH 35/36] Un-derp testing details --- .../esp32/EnvironmentalMeasurementPlugin.cpp | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/src/plugins/esp32/EnvironmentalMeasurementPlugin.cpp b/src/plugins/esp32/EnvironmentalMeasurementPlugin.cpp index 75bb0911..76eda3d2 100644 --- a/src/plugins/esp32/EnvironmentalMeasurementPlugin.cpp +++ b/src/plugins/esp32/EnvironmentalMeasurementPlugin.cpp @@ -74,19 +74,17 @@ bool EnvironmentalMeasurementPluginRadio::sendOurEnvironmentalMeasurement(NodeNu { EnvironmentalMeasurement m; - m.barometric_pressure=0; - float t = dht.readTemperature(); - float h = dht.readHumidity(); - m.relative_humidity= 0; - m.temperature=0; + m.barometric_pressure = 0; // TODO: Add support for barometric sensors + m.relative_humidity = dht.readHumidity(); + m.temperature = dht.readTemperature();; DEBUG_MSG("-----------------------------------------\n"); DEBUG_MSG("Environmental Measurement Plugin: Read data\n"); - DEBUG_MSG("EnvironmentalMeasurement->relative_humidity: %f\n",h); - DEBUG_MSG("EnvironmentalMeasurement->temperature: %f\n",t); + DEBUG_MSG("EnvironmentalMeasurement->relative_humidity: %f\n", m.relative_humidity); + DEBUG_MSG("EnvironmentalMeasurement->temperature: %f\n", m.temperature); - if (isnan(h) || isnan(t) ){ + if (isnan(m.relative_humidity) || isnan(m.temperature) ){ sensor_read_error_count++; DEBUG_MSG("Environmental Measurement Plugin: FAILED TO READ DATA\n"); return false; From 27f74382aab3a77dd5150a6f60510b5e92c77ccc Mon Sep 17 00:00:00 2001 From: Charles Crossan Date: Sun, 21 Feb 2021 11:09:58 -0500 Subject: [PATCH 36/36] Fix CI build for non-esp32 devices --- 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 233c5f37..cfcc21d5 100644 --- a/src/plugins/Plugins.cpp +++ b/src/plugins/Plugins.cpp @@ -20,7 +20,6 @@ void setupPlugins() nodeInfoPlugin = new NodeInfoPlugin(); positionPlugin = new PositionPlugin(); textMessagePlugin = new TextMessagePlugin(); - environmentalMeasurementPlugin = new EnvironmentalMeasurementPlugin(); // Note: if the rest of meshtastic doesn't need to explicitly use your plugin, you do not need to assign the instance // to a global variable. @@ -42,5 +41,6 @@ void setupPlugins() new RangeTestPlugin(); // new StoreForwardPlugin(); + new EnvironmentalMeasurementPlugin(); #endif } \ No newline at end of file