From 1a8b128640cf978eb5f373ed97a75fba0739e4b4 Mon Sep 17 00:00:00 2001 From: Jm Date: Fri, 16 Apr 2021 19:44:59 -0700 Subject: [PATCH 01/13] small change, moving it to the laptop --- proto | 2 +- src/plugins/esp32/StoreForwardPlugin.cpp | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/proto b/proto index 157f9891..0ea23280 160000 --- a/proto +++ b/proto @@ -1 +1 @@ -Subproject commit 157f9891dd35d3087f51e32dc0b103fcb1f0ca7c +Subproject commit 0ea232802651fd6aaa53c93c09f4c2eb36470dd0 diff --git a/src/plugins/esp32/StoreForwardPlugin.cpp b/src/plugins/esp32/StoreForwardPlugin.cpp index 6a90bf22..3c6c3bbd 100644 --- a/src/plugins/esp32/StoreForwardPlugin.cpp +++ b/src/plugins/esp32/StoreForwardPlugin.cpp @@ -197,10 +197,10 @@ bool StoreForwardPlugin::handleReceived(const MeshPacket &mp) if (radioConfig.preferences.store_forward_plugin_enabled) { if (getFrom(&mp) != nodeDB.getNodeNum()) { - printPacket("----- PACKET FROM RADIO -----", &mp); + printPacket("PACKET FROM RADIO", &mp); // uint32_t sawTime = storeForwardPlugin->sawNode(getFrom(&mp) & 0xffffffff); // DEBUG_MSG("We last saw this node (%u), %u sec ago\n", mp.from & 0xffffffff, (millis() - sawTime) / 1000); - DEBUG_MSG(" -------------- "); + // DEBUG_MSG(" -------------- "); if (mp.decoded.portnum == PortNum_TEXT_MESSAGE_APP) { DEBUG_MSG("Packet came from - PortNum_TEXT_MESSAGE_APP\n"); From 9702dffa12c04f4d85ddb42d1a70cef3e1769e59 Mon Sep 17 00:00:00 2001 From: Jm Date: Wed, 27 Oct 2021 19:57:37 -0700 Subject: [PATCH 02/13] Update proto --- proto | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proto b/proto index 0ea23280..e24fa8c6 160000 --- a/proto +++ b/proto @@ -1 +1 @@ -Subproject commit 0ea232802651fd6aaa53c93c09f4c2eb36470dd0 +Subproject commit e24fa8c6edd46c2bf66005f45d2547ebd15887c1 From 5dd9610d36759562dc45c7bbeca6a71dbbd1358b Mon Sep 17 00:00:00 2001 From: Jm Date: Wed, 27 Oct 2021 20:05:33 -0700 Subject: [PATCH 03/13] Fix for #874 - RangeTest Plugin header fields swapped for elevation and SNR Fix for #874 - RangeTest Plugin header fields swapped for elevation and SNR --- 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 b28bd8c9..b2ec553e 100644 --- a/src/plugins/esp32/RangeTestPlugin.cpp +++ b/src/plugins/esp32/RangeTestPlugin.cpp @@ -257,7 +257,7 @@ bool RangeTestPluginRadio::appendFile(const MeshPacket &mp) // Print the CSV header if (fileToWrite.println( - "time,from,sender name,sender lat,sender long,rx lat,rx long,rx snr,rx elevation,distance,payload")) { + "time,from,sender name,sender lat,sender long,rx lat,rx long,rx elevation,rx snr,distance,payload")) { DEBUG_MSG("File was written\n"); } else { DEBUG_MSG("File write failed\n"); From 37aab8a42b91fcbdd95226d12e8c9d8d4399f350 Mon Sep 17 00:00:00 2001 From: Jm Casler Date: Thu, 18 Nov 2021 09:35:05 -0800 Subject: [PATCH 04/13] Able to store and forward, but packets are corrupt --- src/plugins/esp32/StoreForwardPlugin.cpp | 131 ++++++++++++++--------- src/plugins/esp32/StoreForwardPlugin.h | 3 +- 2 files changed, 79 insertions(+), 55 deletions(-) diff --git a/src/plugins/esp32/StoreForwardPlugin.cpp b/src/plugins/esp32/StoreForwardPlugin.cpp index ae725422..0bbdf0e2 100644 --- a/src/plugins/esp32/StoreForwardPlugin.cpp +++ b/src/plugins/esp32/StoreForwardPlugin.cpp @@ -12,6 +12,16 @@ #define STOREFORWARD_MAX_PACKETS 0 #define STOREFORWARD_SEND_HISTORY_PERIOD 10 * 60 #define STOREFORWARD_SEND_HISTORY_MAX 0 +#define STOREFORWARD_HOP_MAX 0 // How many hops should we allow the packet to be forwarded? + +/* + Jm's TODO: + - Be able to identify if you're within range of a router. + - Be able to specify the HOP MAX to reduce airtime. + - Restrict operation of S&F on the slow channel configurations. + +*/ + StoreForwardPlugin *storeForwardPlugin; @@ -51,6 +61,9 @@ int32_t StoreForwardPlugin::runOnce() return (INT32_MAX); } +/* + Create our data structure in the PSRAM. +*/ void StoreForwardPlugin::populatePSRAM() { /* @@ -81,24 +94,11 @@ void StoreForwardPlugin::populatePSRAM() DEBUG_MSG(" numberOfPackets - %u\n", numberOfPackets); } -// We saw a node. -void StoreForwardPlugin::sawNode(uint32_t whoWeSaw, uint32_t sawSecAgo) -{ - if (radioConfig.preferences.is_router) { - - // If node has been away for more than 10 minutes, send the node the last 10 minutes of - // messages - if (sawSecAgo > STOREFORWARD_SEND_HISTORY_PERIOD) { - // Node has been away for a while. - storeForwardPlugin->historySend(STOREFORWARD_SEND_HISTORY_PERIOD, whoWeSaw); - } - } -} - void StoreForwardPlugin::historyReport() { DEBUG_MSG("Iterating through the message history...\n"); DEBUG_MSG("Message history contains %u records\n", this->packetHistoryCurrent); + /* uint32_t startTimer = millis(); for (int i = 0; i < this->packetHistoryCurrent; i++) { if (this->packetHistory[i].time) { @@ -106,6 +106,7 @@ void StoreForwardPlugin::historyReport() } } DEBUG_MSG("StoreForwardPlugin::historyReport runtime - %u ms\n", millis() - startTimer); + */ } /* @@ -113,12 +114,42 @@ void StoreForwardPlugin::historyReport() */ void StoreForwardPlugin::historySend(uint32_t msAgo, uint32_t to) { - // Send "Welcome back" - this->sendPayloadWelcome(to, false); + MeshPacket mp; for (int i = 0; i < this->packetHistoryCurrent; i++) { if (this->packetHistory[i].time) { - // DEBUG_MSG("... time-%u to-0x%08x\n", this->packetHistory[i].time, this->packetHistory[i].to & 0xffffffff); + + + /* + Stored packet was sent to a broadcast address + */ + if ((this->packetHistory[i].to & 0xffffffff) == 0xffffffff) { + DEBUG_MSG("Request: to-0x%08x, Stored: time-%u to-0x%08x\n", to & 0xffffffff, this->packetHistory[i].time, this->packetHistory[i].to & 0xffffffff); + + //bool pb_decode_from_bytes(const uint8_t *srcbuf, size_t srcbufsize, const pb_msgdesc_t *fields, void *dest_struct); + pb_decode_from_bytes(this->packetHistory[i].bytes, this->packetHistory[i].bytes_size, ToRadio_fields, &mp); + + /* + Take saved packet + Decode it + Read something form the decoded packet. + */ + DEBUG_MSG(">>>>> %s\n", mp.decoded.payload.bytes); + + storeForwardPlugin->sendPayload(to, true); + } + + /* + Stored packet was intended to a named address + + TODO: TEST ME! I don't know if this works. + */ + if ((this->packetHistory[i].to & 0xffffffff) == to) { + DEBUG_MSG("Request: to-0x%08x, Stored: time-%u to-0x%08x\n", to & 0xffffffff, this->packetHistory[i].time, this->packetHistory[i].to & 0xffffffff); + storeForwardPlugin->sendPayload(to, true); + } + + //break; } } } @@ -131,14 +162,16 @@ void StoreForwardPlugin::historyAdd(const MeshPacket *mp) size_t numbytes = pb_encode_to_bytes(bytes, sizeof(bytes), Data_fields, &p->decoded); assert(numbytes <= MAX_RHPACKETLEN); - DEBUG_MSG("MP numbytes %u\n", numbytes); + //DEBUG_MSG("MP numbytes %u\n", numbytes); // destination, source, bytes // memcpy(p->encrypted.bytes, bytes, numbytes); memcpy(this->packetHistory[this->packetHistoryCurrent].bytes, bytes, MAX_RHPACKETLEN); this->packetHistory[this->packetHistoryCurrent].time = millis(); this->packetHistory[this->packetHistoryCurrent].to = mp->to; + this->packetHistory[this->packetHistoryCurrent].bytes_size = sizeof(bytes); this->packetHistoryCurrent++; + } MeshPacket *StoreForwardPlugin::allocReply() @@ -157,54 +190,41 @@ void StoreForwardPlugin::sendPayload(NodeNum dest, bool wantReplies) p->want_ack = true; static char heartbeatString[20]; - snprintf(heartbeatString, sizeof(heartbeatString), "1"); + snprintf(heartbeatString, sizeof(heartbeatString), "From SF"); p->decoded.payload.size = strlen(heartbeatString); // You must specify how many bytes are in the reply - memcpy(p->decoded.payload.bytes, "1", 1); + memcpy(p->decoded.payload.bytes, "From SF", 7); service.sendToMesh(p); } -void StoreForwardPlugin::sendPayloadWelcome(NodeNum dest, bool wantReplies) -{ - DEBUG_MSG("*********************************\n"); - DEBUG_MSG("*********************************\n"); - DEBUG_MSG("*********************************\n"); - DEBUG_MSG("Sending S&F Welcome Message\n"); - DEBUG_MSG("*********************************\n"); - DEBUG_MSG("*********************************\n"); - DEBUG_MSG("*********************************\n"); - MeshPacket *p = allocReply(); - p->to = dest; - p->decoded.want_response = wantReplies; - - p->want_ack = true; - - p->decoded.portnum = PortNum_TEXT_MESSAGE_APP; - - static char heartbeatString[80]; - snprintf(heartbeatString, sizeof(heartbeatString), "Welcome back to the mesh. We have not seen you in x minutes!"); - - p->decoded.payload.size = strlen(heartbeatString); // You must specify how many bytes are in the reply - memcpy(p->decoded.payload.bytes, heartbeatString, p->decoded.payload.size); - - service.sendToMesh(p); -} ProcessMessage StoreForwardPlugin::handleReceived(const MeshPacket &mp) { #ifndef NO_ESP32 if (radioConfig.preferences.store_forward_plugin_enabled) { + DEBUG_MSG("--- S&F Received something\n"); + + auto &p = mp.decoded; + + // The router node should not be sending messages as a client. if (getFrom(&mp) != nodeDB.getNodeNum()) { printPacket("PACKET FROM RADIO", &mp); - // uint32_t sawTime = storeForwardPlugin->sawNode(getFrom(&mp) & 0xffffffff); // DEBUG_MSG("We last saw this node (%u), %u sec ago\n", mp.from & 0xffffffff, (millis() - sawTime) / 1000); // DEBUG_MSG(" -------------- "); if (mp.decoded.portnum == PortNum_TEXT_MESSAGE_APP) { DEBUG_MSG("Packet came from - PortNum_TEXT_MESSAGE_APP\n"); - storeForwardPlugin->historyAdd(&mp); + DEBUG_MSG("--- --- --- %s \n", p.payload.bytes); + + if ((p.payload.bytes[0] == 'S') && (p.payload.bytes[1] == 'F')) { + DEBUG_MSG("--- --- --- Request to send\n"); + + storeForwardPlugin->historySend(5 * 1000 * 60, getFrom(&mp)); + } else { + storeForwardPlugin->historyAdd(&mp); + } } else { DEBUG_MSG("Packet came from an unknown port %u\n", mp.decoded.portnum); @@ -221,21 +241,26 @@ ProcessMessage StoreForwardPlugin::handleReceived(const MeshPacket &mp) } StoreForwardPlugin::StoreForwardPlugin() - : SinglePortPlugin("StoreForwardPlugin", PortNum_STORE_FORWARD_APP), concurrency::OSThread("StoreForwardPlugin") + : SinglePortPlugin("StoreForwardPlugin", PortNum_TEXT_MESSAGE_APP), concurrency::OSThread("StoreForwardPlugin") { +//StoreForwardPlugin::StoreForwardPlugin() +// : SinglePortPlugin("StoreForwardPlugin", PortNum_STORE_FORWARD_APP), concurrency::OSThread("StoreForwardPlugin") +//{ + #ifndef NO_ESP32 isPromiscuous = true; // Brown chicken brown cow - /* - Uncomment the preferences below if you want to use the plugin - without having to configure it from the PythonAPI or WebUI. - */ - if (StoreForward_Dev) { + /* + 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 = 1; radioConfig.preferences.is_router = 1; + radioConfig.preferences.is_always_powered = 1; } if (radioConfig.preferences.store_forward_plugin_enabled) { diff --git a/src/plugins/esp32/StoreForwardPlugin.h b/src/plugins/esp32/StoreForwardPlugin.h index acdac6f6..782541ef 100644 --- a/src/plugins/esp32/StoreForwardPlugin.h +++ b/src/plugins/esp32/StoreForwardPlugin.h @@ -11,6 +11,7 @@ struct PacketHistoryStruct { uint32_t to; bool ack; uint8_t bytes[MAX_RHPACKETLEN]; + uint8_t bytes_size; }; class StoreForwardPlugin : public SinglePortPlugin, private concurrency::OSThread @@ -29,7 +30,6 @@ class StoreForwardPlugin : public SinglePortPlugin, private concurrency::OSThrea 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. */ - void sawNode(uint32_t whoWeSaw, uint32_t sawSecAgo); void historyAdd(const MeshPacket *mp); void historyReport(); void historySend(uint32_t msAgo, uint32_t to); @@ -39,7 +39,6 @@ class StoreForwardPlugin : public SinglePortPlugin, private concurrency::OSThrea * Send our payload into the mesh */ void sendPayload(NodeNum dest = NODENUM_BROADCAST, bool wantReplies = false); - void sendPayloadWelcome(NodeNum dest = NODENUM_BROADCAST, bool wantReplies = false); virtual MeshPacket *allocReply(); virtual bool wantPortnum(PortNum p) { return true; }; From 32017e53f5f32859a33c8c8c5b61e8716099a1dc Mon Sep 17 00:00:00 2001 From: Jm Casler Date: Thu, 18 Nov 2021 09:36:39 -0800 Subject: [PATCH 05/13] Formatting applied --- src/plugins/esp32/StoreForwardPlugin.cpp | 34 +++++++++++------------- src/plugins/esp32/StoreForwardPlugin.h | 3 ++- 2 files changed, 18 insertions(+), 19 deletions(-) diff --git a/src/plugins/esp32/StoreForwardPlugin.cpp b/src/plugins/esp32/StoreForwardPlugin.cpp index 0bbdf0e2..ec607ce5 100644 --- a/src/plugins/esp32/StoreForwardPlugin.cpp +++ b/src/plugins/esp32/StoreForwardPlugin.cpp @@ -22,7 +22,6 @@ */ - StoreForwardPlugin *storeForwardPlugin; int32_t StoreForwardPlugin::runOnce() @@ -119,37 +118,39 @@ void StoreForwardPlugin::historySend(uint32_t msAgo, uint32_t to) for (int i = 0; i < this->packetHistoryCurrent; i++) { if (this->packetHistory[i].time) { - /* Stored packet was sent to a broadcast address */ if ((this->packetHistory[i].to & 0xffffffff) == 0xffffffff) { - DEBUG_MSG("Request: to-0x%08x, Stored: time-%u to-0x%08x\n", to & 0xffffffff, this->packetHistory[i].time, this->packetHistory[i].to & 0xffffffff); - - //bool pb_decode_from_bytes(const uint8_t *srcbuf, size_t srcbufsize, const pb_msgdesc_t *fields, void *dest_struct); + DEBUG_MSG("Request: to-0x%08x, Stored: time-%u to-0x%08x\n", to & 0xffffffff, this->packetHistory[i].time, + this->packetHistory[i].to & 0xffffffff); + + // bool pb_decode_from_bytes(const uint8_t *srcbuf, size_t srcbufsize, const pb_msgdesc_t *fields, void + // *dest_struct); pb_decode_from_bytes(this->packetHistory[i].bytes, this->packetHistory[i].bytes_size, ToRadio_fields, &mp); /* Take saved packet Decode it Read something form the decoded packet. - */ - DEBUG_MSG(">>>>> %s\n", mp.decoded.payload.bytes); - + */ + DEBUG_MSG(">>>>> %s\n", mp.decoded.payload.bytes); + storeForwardPlugin->sendPayload(to, true); } /* Stored packet was intended to a named address - TODO: TEST ME! I don't know if this works. + TODO: TEST ME! I don't know if this works. */ if ((this->packetHistory[i].to & 0xffffffff) == to) { - DEBUG_MSG("Request: to-0x%08x, Stored: time-%u to-0x%08x\n", to & 0xffffffff, this->packetHistory[i].time, this->packetHistory[i].to & 0xffffffff); + DEBUG_MSG("Request: to-0x%08x, Stored: time-%u to-0x%08x\n", to & 0xffffffff, this->packetHistory[i].time, + this->packetHistory[i].to & 0xffffffff); storeForwardPlugin->sendPayload(to, true); } - //break; + // break; } } } @@ -162,7 +163,7 @@ void StoreForwardPlugin::historyAdd(const MeshPacket *mp) size_t numbytes = pb_encode_to_bytes(bytes, sizeof(bytes), Data_fields, &p->decoded); assert(numbytes <= MAX_RHPACKETLEN); - //DEBUG_MSG("MP numbytes %u\n", numbytes); + // DEBUG_MSG("MP numbytes %u\n", numbytes); // destination, source, bytes // memcpy(p->encrypted.bytes, bytes, numbytes); @@ -171,7 +172,6 @@ void StoreForwardPlugin::historyAdd(const MeshPacket *mp) this->packetHistory[this->packetHistoryCurrent].to = mp->to; this->packetHistory[this->packetHistoryCurrent].bytes_size = sizeof(bytes); this->packetHistoryCurrent++; - } MeshPacket *StoreForwardPlugin::allocReply() @@ -198,7 +198,6 @@ void StoreForwardPlugin::sendPayload(NodeNum dest, bool wantReplies) service.sendToMesh(p); } - ProcessMessage StoreForwardPlugin::handleReceived(const MeshPacket &mp) { #ifndef NO_ESP32 @@ -243,10 +242,9 @@ ProcessMessage StoreForwardPlugin::handleReceived(const MeshPacket &mp) StoreForwardPlugin::StoreForwardPlugin() : SinglePortPlugin("StoreForwardPlugin", PortNum_TEXT_MESSAGE_APP), concurrency::OSThread("StoreForwardPlugin") { -//StoreForwardPlugin::StoreForwardPlugin() -// : SinglePortPlugin("StoreForwardPlugin", PortNum_STORE_FORWARD_APP), concurrency::OSThread("StoreForwardPlugin") -//{ - + // StoreForwardPlugin::StoreForwardPlugin() + // : SinglePortPlugin("StoreForwardPlugin", PortNum_STORE_FORWARD_APP), concurrency::OSThread("StoreForwardPlugin") + //{ #ifndef NO_ESP32 diff --git a/src/plugins/esp32/StoreForwardPlugin.h b/src/plugins/esp32/StoreForwardPlugin.h index 782541ef..12d81946 100644 --- a/src/plugins/esp32/StoreForwardPlugin.h +++ b/src/plugins/esp32/StoreForwardPlugin.h @@ -50,7 +50,8 @@ class StoreForwardPlugin : public SinglePortPlugin, private concurrency::OSThrea /** Called to handle a particular incoming message - @return ProcessMessage::STOP if you've guaranteed you've handled this message and no other handlers should be considered for it + @return ProcessMessage::STOP if you've guaranteed you've handled this message and no other handlers should be considered for + it */ virtual ProcessMessage handleReceived(const MeshPacket &mp); }; From 5191fd6475bd5f996bafa96c3e14271ccbdf55b0 Mon Sep 17 00:00:00 2001 From: Jm Casler Date: Sat, 20 Nov 2021 21:21:11 -0800 Subject: [PATCH 06/13] Initial demonstrable build --- src/plugins/esp32/StoreForwardPlugin.cpp | 80 ++++++++++++------------ src/plugins/esp32/StoreForwardPlugin.h | 13 ++-- 2 files changed, 47 insertions(+), 46 deletions(-) diff --git a/src/plugins/esp32/StoreForwardPlugin.cpp b/src/plugins/esp32/StoreForwardPlugin.cpp index ec607ce5..f562c54b 100644 --- a/src/plugins/esp32/StoreForwardPlugin.cpp +++ b/src/plugins/esp32/StoreForwardPlugin.cpp @@ -9,16 +9,21 @@ #include #include -#define STOREFORWARD_MAX_PACKETS 0 +//#define STOREFORWARD_MAX_PACKETS 0 #define STOREFORWARD_SEND_HISTORY_PERIOD 10 * 60 #define STOREFORWARD_SEND_HISTORY_MAX 0 #define STOREFORWARD_HOP_MAX 0 // How many hops should we allow the packet to be forwarded? /* - Jm's TODO: + TODO: - Be able to identify if you're within range of a router. - Be able to specify the HOP MAX to reduce airtime. - Restrict operation of S&F on the slow channel configurations. + - Build in rate limiting -- Don't allow a user to repeatedly request the history. + + DONE: + Allow max history to be defined by radioConfig.preferences.store_forward_plugin_records + */ @@ -43,9 +48,9 @@ int32_t StoreForwardPlugin::runOnce() * This behavior is expected to change. It's only here until we come up with something better. */ - DEBUG_MSG("Store & Forward Plugin - Sending heartbeat\n"); + //DEBUG_MSG("Store & Forward Plugin - Sending heartbeat\n"); - storeForwardPlugin->sendPayload(); + //storeForwardPlugin->sendPayload(); return (4 * 60 * 1000); } @@ -77,9 +82,9 @@ void StoreForwardPlugin::populatePSRAM() DEBUG_MSG(" Total PSRAM: %d\n", ESP.getPsramSize()); DEBUG_MSG(" Free PSRAM: %d\n", ESP.getFreePsram()); - // Use a maximum of half the available PSRAM unless otherwise specified. - uint32_t numberOfPackets = - STOREFORWARD_MAX_PACKETS ? STOREFORWARD_MAX_PACKETS : ((ESP.getPsramSize() / 2) / sizeof(PacketHistoryStruct)); + // Use a maximum of 2/3 the available PSRAM unless otherwise specified. + uint32_t numberOfPackets =( radioConfig.preferences.store_forward_plugin_records ? radioConfig.preferences.store_forward_plugin_records : + ( ( (ESP.getFreePsram() / 3) * 2 )/ sizeof(PacketHistoryStruct)) ); // this->packetHistory = (PacketHistoryStruct *)ps_calloc(numberOfPackets, sizeof(PacketHistoryStruct)); this->packetHistory = static_cast(ps_calloc(numberOfPackets, sizeof(PacketHistoryStruct))); @@ -114,7 +119,7 @@ void StoreForwardPlugin::historyReport() void StoreForwardPlugin::historySend(uint32_t msAgo, uint32_t to) { - MeshPacket mp; + //MeshPacket mp; for (int i = 0; i < this->packetHistoryCurrent; i++) { if (this->packetHistory[i].time) { @@ -125,18 +130,9 @@ void StoreForwardPlugin::historySend(uint32_t msAgo, uint32_t to) DEBUG_MSG("Request: to-0x%08x, Stored: time-%u to-0x%08x\n", to & 0xffffffff, this->packetHistory[i].time, this->packetHistory[i].to & 0xffffffff); - // bool pb_decode_from_bytes(const uint8_t *srcbuf, size_t srcbufsize, const pb_msgdesc_t *fields, void - // *dest_struct); - pb_decode_from_bytes(this->packetHistory[i].bytes, this->packetHistory[i].bytes_size, ToRadio_fields, &mp); + DEBUG_MSG(">>>>> %s\n", this->packetHistory[i].payload); - /* - Take saved packet - Decode it - Read something form the decoded packet. - */ - DEBUG_MSG(">>>>> %s\n", mp.decoded.payload.bytes); - - storeForwardPlugin->sendPayload(to, true); + storeForwardPlugin->sendPayload(to, i); } /* @@ -147,7 +143,7 @@ void StoreForwardPlugin::historySend(uint32_t msAgo, uint32_t to) if ((this->packetHistory[i].to & 0xffffffff) == to) { DEBUG_MSG("Request: to-0x%08x, Stored: time-%u to-0x%08x\n", to & 0xffffffff, this->packetHistory[i].time, this->packetHistory[i].to & 0xffffffff); - storeForwardPlugin->sendPayload(to, true); + storeForwardPlugin->sendPayload(to, i); } // break; @@ -155,22 +151,19 @@ void StoreForwardPlugin::historySend(uint32_t msAgo, uint32_t to) } } -void StoreForwardPlugin::historyAdd(const MeshPacket *mp) +void StoreForwardPlugin::historyAdd(const MeshPacket &mp) { - auto &p = mp; + //auto &p = *mp.decoded; + auto &p = mp.decoded; - static uint8_t bytes[MAX_RHPACKETLEN]; - size_t numbytes = pb_encode_to_bytes(bytes, sizeof(bytes), Data_fields, &p->decoded); - assert(numbytes <= MAX_RHPACKETLEN); + //uint16_t payloadSize = p.payload.size; - // DEBUG_MSG("MP numbytes %u\n", numbytes); - - // destination, source, bytes - // memcpy(p->encrypted.bytes, bytes, numbytes); - memcpy(this->packetHistory[this->packetHistoryCurrent].bytes, bytes, MAX_RHPACKETLEN); this->packetHistory[this->packetHistoryCurrent].time = millis(); - this->packetHistory[this->packetHistoryCurrent].to = mp->to; - this->packetHistory[this->packetHistoryCurrent].bytes_size = sizeof(bytes); + this->packetHistory[this->packetHistoryCurrent].to = mp.to; + this->packetHistory[this->packetHistoryCurrent].from = mp.from; + this->packetHistory[this->packetHistoryCurrent].payload_size = p.payload.size; + memcpy(this->packetHistory[this->packetHistoryCurrent].payload, p.payload.bytes, Constants_DATA_PAYLOAD_LEN); + this->packetHistoryCurrent++; } @@ -180,20 +173,23 @@ MeshPacket *StoreForwardPlugin::allocReply() return reply; } -void StoreForwardPlugin::sendPayload(NodeNum dest, bool wantReplies) +void StoreForwardPlugin::sendPayload(NodeNum dest, uint32_t packetHistory_index) { DEBUG_MSG("Sending S&F Payload\n"); MeshPacket *p = allocReply(); + p->to = dest; - p->decoded.want_response = wantReplies; + p->from = this->packetHistory[packetHistory_index].from; + + // Let's assume that if the router received the S&F request that the client is in range. + // TODO: Make this configurable. + p->want_ack = false; - p->want_ack = true; + //static char heartbeatString[20]; + //snprintf(heartbeatString, sizeof(heartbeatString), "From SF"); - static char heartbeatString[20]; - snprintf(heartbeatString, sizeof(heartbeatString), "From SF"); - - p->decoded.payload.size = strlen(heartbeatString); // You must specify how many bytes are in the reply - memcpy(p->decoded.payload.bytes, "From SF", 7); + p->decoded.payload.size = this->packetHistory[packetHistory_index].payload_size; // You must specify how many bytes are in the reply + memcpy(p->decoded.payload.bytes, this->packetHistory[packetHistory_index].payload, this->packetHistory[packetHistory_index].payload_size); service.sendToMesh(p); } @@ -220,9 +216,10 @@ ProcessMessage StoreForwardPlugin::handleReceived(const MeshPacket &mp) if ((p.payload.bytes[0] == 'S') && (p.payload.bytes[1] == 'F')) { DEBUG_MSG("--- --- --- Request to send\n"); + // Send the last 5 minutes of messages. storeForwardPlugin->historySend(5 * 1000 * 60, getFrom(&mp)); } else { - storeForwardPlugin->historyAdd(&mp); + storeForwardPlugin->historyAdd(mp); } } else { @@ -259,6 +256,7 @@ StoreForwardPlugin::StoreForwardPlugin() radioConfig.preferences.store_forward_plugin_enabled = 1; radioConfig.preferences.is_router = 1; radioConfig.preferences.is_always_powered = 1; + } if (radioConfig.preferences.store_forward_plugin_enabled) { diff --git a/src/plugins/esp32/StoreForwardPlugin.h b/src/plugins/esp32/StoreForwardPlugin.h index 12d81946..0a182d18 100644 --- a/src/plugins/esp32/StoreForwardPlugin.h +++ b/src/plugins/esp32/StoreForwardPlugin.h @@ -9,9 +9,12 @@ struct PacketHistoryStruct { uint32_t time; uint32_t to; + uint32_t from; bool ack; - uint8_t bytes[MAX_RHPACKETLEN]; - uint8_t bytes_size; + uint8_t payload[Constants_DATA_PAYLOAD_LEN]; + pb_size_t payload_size; + //uint8_t bytes[MAX_RHPACKETLEN]; + //uint8_t bytes_size; }; class StoreForwardPlugin : public SinglePortPlugin, private concurrency::OSThread @@ -30,7 +33,7 @@ class StoreForwardPlugin : public SinglePortPlugin, private concurrency::OSThrea 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. */ - void historyAdd(const MeshPacket *mp); + void historyAdd(const MeshPacket &mp); void historyReport(); void historySend(uint32_t msAgo, uint32_t to); void populatePSRAM(); @@ -38,12 +41,12 @@ class StoreForwardPlugin : public SinglePortPlugin, private concurrency::OSThrea /** * Send our payload into the mesh */ - void sendPayload(NodeNum dest = NODENUM_BROADCAST, bool wantReplies = false); + void sendPayload(NodeNum dest = NODENUM_BROADCAST, uint32_t packetHistory_index = 0); virtual MeshPacket *allocReply(); virtual bool wantPortnum(PortNum p) { return true; }; private: - // Nothing here + // Nothing here. protected: virtual int32_t runOnce(); From 97aec5f125414396715e8021fbbc0f9eadca37ae Mon Sep 17 00:00:00 2001 From: Jm Casler Date: Sat, 20 Nov 2021 21:35:13 -0800 Subject: [PATCH 07/13] Remove comments from SF --- src/plugins/esp32/StoreForwardPlugin.cpp | 20 ------------------ src/plugins/esp32/StoreForwardPlugin.h | 27 +----------------------- 2 files changed, 1 insertion(+), 46 deletions(-) diff --git a/src/plugins/esp32/StoreForwardPlugin.cpp b/src/plugins/esp32/StoreForwardPlugin.cpp index f562c54b..abb49e7b 100644 --- a/src/plugins/esp32/StoreForwardPlugin.cpp +++ b/src/plugins/esp32/StoreForwardPlugin.cpp @@ -102,15 +102,6 @@ void StoreForwardPlugin::historyReport() { DEBUG_MSG("Iterating through the message history...\n"); DEBUG_MSG("Message history contains %u records\n", this->packetHistoryCurrent); - /* - uint32_t startTimer = millis(); - for (int i = 0; i < this->packetHistoryCurrent; i++) { - if (this->packetHistory[i].time) { - // DEBUG_MSG("... time-%u to-0x%08x\n", this->packetHistory[i].time, this->packetHistory[i].to & 0xffffffff); - } - } - DEBUG_MSG("StoreForwardPlugin::historyReport runtime - %u ms\n", millis() - startTimer); - */ } /* @@ -145,19 +136,14 @@ void StoreForwardPlugin::historySend(uint32_t msAgo, uint32_t to) this->packetHistory[i].to & 0xffffffff); storeForwardPlugin->sendPayload(to, i); } - - // break; } } } void StoreForwardPlugin::historyAdd(const MeshPacket &mp) { - //auto &p = *mp.decoded; auto &p = mp.decoded; - //uint16_t payloadSize = p.payload.size; - this->packetHistory[this->packetHistoryCurrent].time = millis(); this->packetHistory[this->packetHistoryCurrent].to = mp.to; this->packetHistory[this->packetHistoryCurrent].from = mp.from; @@ -185,9 +171,6 @@ void StoreForwardPlugin::sendPayload(NodeNum dest, uint32_t packetHistory_index) // TODO: Make this configurable. p->want_ack = false; - //static char heartbeatString[20]; - //snprintf(heartbeatString, sizeof(heartbeatString), "From SF"); - p->decoded.payload.size = this->packetHistory[packetHistory_index].payload_size; // You must specify how many bytes are in the reply memcpy(p->decoded.payload.bytes, this->packetHistory[packetHistory_index].payload, this->packetHistory[packetHistory_index].payload_size); @@ -239,9 +222,6 @@ ProcessMessage StoreForwardPlugin::handleReceived(const MeshPacket &mp) StoreForwardPlugin::StoreForwardPlugin() : SinglePortPlugin("StoreForwardPlugin", PortNum_TEXT_MESSAGE_APP), concurrency::OSThread("StoreForwardPlugin") { - // StoreForwardPlugin::StoreForwardPlugin() - // : SinglePortPlugin("StoreForwardPlugin", PortNum_STORE_FORWARD_APP), concurrency::OSThread("StoreForwardPlugin") - //{ #ifndef NO_ESP32 diff --git a/src/plugins/esp32/StoreForwardPlugin.h b/src/plugins/esp32/StoreForwardPlugin.h index 0a182d18..0e65594f 100644 --- a/src/plugins/esp32/StoreForwardPlugin.h +++ b/src/plugins/esp32/StoreForwardPlugin.h @@ -13,8 +13,6 @@ struct PacketHistoryStruct { bool ack; uint8_t payload[Constants_DATA_PAYLOAD_LEN]; pb_size_t payload_size; - //uint8_t bytes[MAX_RHPACKETLEN]; - //uint8_t bytes_size; }; class StoreForwardPlugin : public SinglePortPlugin, private concurrency::OSThread @@ -59,27 +57,4 @@ class StoreForwardPlugin : public SinglePortPlugin, private concurrency::OSThrea virtual ProcessMessage handleReceived(const MeshPacket &mp); }; -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) {} - - void sendPayloadHeartbeat(NodeNum dest = NODENUM_BROADCAST, bool wantReplies = false); - - protected: - virtual MeshPacket *allocReply2(); -}; - -extern StoreForwardPluginRadio *storeForwardPluginRadio; -*/ +extern StoreForwardPlugin *storeForwardPlugin; \ No newline at end of file From 4367f05b24788765e1506d95ea2d3be8c055f446 Mon Sep 17 00:00:00 2001 From: Jm Casler Date: Sat, 20 Nov 2021 21:57:21 -0800 Subject: [PATCH 08/13] Applied code formatters. --- src/plugins/esp32/StoreForwardPlugin.cpp | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/src/plugins/esp32/StoreForwardPlugin.cpp b/src/plugins/esp32/StoreForwardPlugin.cpp index abb49e7b..1b41ebe4 100644 --- a/src/plugins/esp32/StoreForwardPlugin.cpp +++ b/src/plugins/esp32/StoreForwardPlugin.cpp @@ -48,9 +48,9 @@ int32_t StoreForwardPlugin::runOnce() * This behavior is expected to change. It's only here until we come up with something better. */ - //DEBUG_MSG("Store & Forward Plugin - Sending heartbeat\n"); + // DEBUG_MSG("Store & Forward Plugin - Sending heartbeat\n"); - //storeForwardPlugin->sendPayload(); + // storeForwardPlugin->sendPayload(); return (4 * 60 * 1000); } @@ -83,8 +83,9 @@ void StoreForwardPlugin::populatePSRAM() DEBUG_MSG(" Free PSRAM: %d\n", ESP.getFreePsram()); // Use a maximum of 2/3 the available PSRAM unless otherwise specified. - uint32_t numberOfPackets =( radioConfig.preferences.store_forward_plugin_records ? radioConfig.preferences.store_forward_plugin_records : - ( ( (ESP.getFreePsram() / 3) * 2 )/ sizeof(PacketHistoryStruct)) ); + uint32_t numberOfPackets = + (radioConfig.preferences.store_forward_plugin_records ? radioConfig.preferences.store_forward_plugin_records + : (((ESP.getFreePsram() / 3) * 2) / sizeof(PacketHistoryStruct))); // this->packetHistory = (PacketHistoryStruct *)ps_calloc(numberOfPackets, sizeof(PacketHistoryStruct)); this->packetHistory = static_cast(ps_calloc(numberOfPackets, sizeof(PacketHistoryStruct))); @@ -110,7 +111,7 @@ void StoreForwardPlugin::historyReport() void StoreForwardPlugin::historySend(uint32_t msAgo, uint32_t to) { - //MeshPacket mp; + // MeshPacket mp; for (int i = 0; i < this->packetHistoryCurrent; i++) { if (this->packetHistory[i].time) { @@ -166,13 +167,15 @@ void StoreForwardPlugin::sendPayload(NodeNum dest, uint32_t packetHistory_index) p->to = dest; p->from = this->packetHistory[packetHistory_index].from; - + // Let's assume that if the router received the S&F request that the client is in range. // TODO: Make this configurable. - p->want_ack = false; + p->want_ack = false; - p->decoded.payload.size = this->packetHistory[packetHistory_index].payload_size; // You must specify how many bytes are in the reply - memcpy(p->decoded.payload.bytes, this->packetHistory[packetHistory_index].payload, this->packetHistory[packetHistory_index].payload_size); + p->decoded.payload.size = + this->packetHistory[packetHistory_index].payload_size; // You must specify how many bytes are in the reply + memcpy(p->decoded.payload.bytes, this->packetHistory[packetHistory_index].payload, + this->packetHistory[packetHistory_index].payload_size); service.sendToMesh(p); } @@ -236,7 +239,6 @@ StoreForwardPlugin::StoreForwardPlugin() radioConfig.preferences.store_forward_plugin_enabled = 1; radioConfig.preferences.is_router = 1; radioConfig.preferences.is_always_powered = 1; - } if (radioConfig.preferences.store_forward_plugin_enabled) { From 834f2f416070007906fe4d6dd8e841ee0c9b08dd Mon Sep 17 00:00:00 2001 From: Jm Casler Date: Sun, 21 Nov 2021 14:43:47 -0800 Subject: [PATCH 09/13] Updates to S&F (this one doesn't work) --- src/plugins/esp32/StoreForwardPlugin.cpp | 92 ++++++++++++++++-------- src/plugins/esp32/StoreForwardPlugin.h | 8 ++- 2 files changed, 67 insertions(+), 33 deletions(-) diff --git a/src/plugins/esp32/StoreForwardPlugin.cpp b/src/plugins/esp32/StoreForwardPlugin.cpp index 1b41ebe4..36512342 100644 --- a/src/plugins/esp32/StoreForwardPlugin.cpp +++ b/src/plugins/esp32/StoreForwardPlugin.cpp @@ -2,6 +2,7 @@ #include "MeshService.h" #include "NodeDB.h" #include "RTC.h" +#include "RadioLibInterface.h" #include "Router.h" #include "configuration.h" #include "mesh-pb-constants.h" @@ -10,22 +11,10 @@ #include //#define STOREFORWARD_MAX_PACKETS 0 -#define STOREFORWARD_SEND_HISTORY_PERIOD 10 * 60 -#define STOREFORWARD_SEND_HISTORY_MAX 0 -#define STOREFORWARD_HOP_MAX 0 // How many hops should we allow the packet to be forwarded? - -/* - TODO: - - Be able to identify if you're within range of a router. - - Be able to specify the HOP MAX to reduce airtime. - - Restrict operation of S&F on the slow channel configurations. - - Build in rate limiting -- Don't allow a user to repeatedly request the history. - - DONE: - Allow max history to be defined by radioConfig.preferences.store_forward_plugin_records +//#define STOREFORWARD_SEND_HISTORY_PERIOD 10 * 60 +//#define STOREFORWARD_HOP_MAX 0 // How many hops should we allow the packet to be forwarded? -*/ StoreForwardPlugin *storeForwardPlugin; @@ -34,25 +23,23 @@ int32_t StoreForwardPlugin::runOnce() #ifndef NO_ESP32 + /* + Calculate the time it takes for the maximum payload to be transmitted. Considering + most messages will be much shorter than this length, this will make us a good radio + neighbor and hopefully we won't use all the airtime. + */ + //uint32_t packetTimeMax = 500; + if (radioConfig.preferences.store_forward_plugin_enabled) { if (radioConfig.preferences.is_router) { - // Maybe some cleanup functions? - this->historyReport(); - return (60 * 1000); + DEBUG_MSG("Store & Forward Plugin - packetTimeMax %d\n", this->packetTimeMax); + + return (500); } else { - /* - * If the plugin is turned on and is_router is not enabled, then we'll send a heartbeat every - * few minutes. - * - * This behavior is expected to change. It's only here until we come up with something better. - */ + DEBUG_MSG("Store & Forward Plugin - Disabled (is_router = false)\n"); - // DEBUG_MSG("Store & Forward Plugin - Sending heartbeat\n"); - - // storeForwardPlugin->sendPayload(); - - return (4 * 60 * 1000); + return (INT32_MAX); } } else { @@ -75,6 +62,8 @@ void StoreForwardPlugin::populatePSRAM() https://learn.upesy.com/en/programmation/psram.html#psram-tab */ + uint32_t store_forward_plugin_replay_max_records = 250; + DEBUG_MSG("Before PSRAM initilization:\n"); DEBUG_MSG(" Total heap: %d\n", ESP.getHeapSize()); @@ -87,8 +76,8 @@ void StoreForwardPlugin::populatePSRAM() (radioConfig.preferences.store_forward_plugin_records ? radioConfig.preferences.store_forward_plugin_records : (((ESP.getFreePsram() / 3) * 2) / sizeof(PacketHistoryStruct))); - // this->packetHistory = (PacketHistoryStruct *)ps_calloc(numberOfPackets, sizeof(PacketHistoryStruct)); this->packetHistory = static_cast(ps_calloc(numberOfPackets, sizeof(PacketHistoryStruct))); + this->packetHistoryTXQueue = static_cast(ps_calloc(store_forward_plugin_replay_max_records, sizeof(PacketHistoryStruct))); DEBUG_MSG("After PSRAM initilization:\n"); DEBUG_MSG(" Total heap: %d\n", ESP.getHeapSize()); @@ -111,6 +100,12 @@ void StoreForwardPlugin::historyReport() void StoreForwardPlugin::historySend(uint32_t msAgo, uint32_t to) { + uint32_t packetsSent = 0; + char routerMessage[80]; + + strcpy(routerMessage, "** S&F - Sending history"); + storeForwardPlugin->sendMessage(to, routerMessage); + // MeshPacket mp; for (int i = 0; i < this->packetHistoryCurrent; i++) { if (this->packetHistory[i].time) { @@ -125,20 +120,31 @@ void StoreForwardPlugin::historySend(uint32_t msAgo, uint32_t to) DEBUG_MSG(">>>>> %s\n", this->packetHistory[i].payload); storeForwardPlugin->sendPayload(to, i); + + packetsSent++; } /* Stored packet was intended to a named address - TODO: TEST ME! I don't know if this works. + TODO: + - TEST ME! I don't know if this works. + - If this works, merge it into the "if" statement above. + */ if ((this->packetHistory[i].to & 0xffffffff) == to) { DEBUG_MSG("Request: to-0x%08x, Stored: time-%u to-0x%08x\n", to & 0xffffffff, this->packetHistory[i].time, this->packetHistory[i].to & 0xffffffff); storeForwardPlugin->sendPayload(to, i); + + packetsSent++; } } } + + snprintf(routerMessage, 80, "** S&F - Sent %d message(s) - Done", packetsSent); + //strcpy(routerMessage, "** S&F - Sent x message(s)"); + storeForwardPlugin->sendMessage(to, routerMessage); } void StoreForwardPlugin::historyAdd(const MeshPacket &mp) @@ -180,6 +186,23 @@ void StoreForwardPlugin::sendPayload(NodeNum dest, uint32_t packetHistory_index) service.sendToMesh(p); } +void StoreForwardPlugin::sendMessage(NodeNum dest, char *str) +{ + MeshPacket *p = allocReply(); + + p->to = dest; + + // Let's assume that if the router received the S&F request that the client is in range. + // TODO: Make this configurable. + p->want_ack = false; + + p->decoded.payload.size = strlen(str); // You must specify how many bytes are in the reply + memcpy(p->decoded.payload.bytes, str, strlen(str)); + + + service.sendToMesh(p); +} + ProcessMessage StoreForwardPlugin::handleReceived(const MeshPacket &mp) { #ifndef NO_ESP32 @@ -251,7 +274,14 @@ StoreForwardPlugin::StoreForwardPlugin() // Do the startup here + // Popupate PSRAM with our data structures. this->populatePSRAM(); + + // Calculate the packet time. + //this->packetTimeMax = RadioLibInterface::instance->getPacketTime(Constants_DATA_PAYLOAD_LEN); + //RadioLibInterface::instance->getPacketTime(Constants_DATA_PAYLOAD_LEN); + RadioLibInterface::instance->getPacketTime(200); + } else { DEBUG_MSG("Device has less than 1M of PSRAM free. Aborting startup.\n"); DEBUG_MSG("Store & Forward Plugin - Aborting Startup.\n"); @@ -268,4 +298,4 @@ StoreForwardPlugin::StoreForwardPlugin() } } #endif -} \ No newline at end of file +} diff --git a/src/plugins/esp32/StoreForwardPlugin.h b/src/plugins/esp32/StoreForwardPlugin.h index 0e65594f..80987593 100644 --- a/src/plugins/esp32/StoreForwardPlugin.h +++ b/src/plugins/esp32/StoreForwardPlugin.h @@ -22,8 +22,12 @@ class StoreForwardPlugin : public SinglePortPlugin, private concurrency::OSThrea uint32_t receivedRecord[50][2] = {{0}}; PacketHistoryStruct *packetHistory; + PacketHistoryStruct *packetHistoryTXQueue; uint32_t packetHistoryCurrent = 0; + uint32_t packetTimeMax = 0; + + public: StoreForwardPlugin(); @@ -34,17 +38,17 @@ class StoreForwardPlugin : public SinglePortPlugin, private concurrency::OSThrea void historyAdd(const MeshPacket &mp); void historyReport(); void historySend(uint32_t msAgo, uint32_t to); - void populatePSRAM(); /** * Send our payload into the mesh */ void sendPayload(NodeNum dest = NODENUM_BROADCAST, uint32_t packetHistory_index = 0); + void sendMessage(NodeNum dest, char *str); virtual MeshPacket *allocReply(); virtual bool wantPortnum(PortNum p) { return true; }; private: - // Nothing here. + void populatePSRAM(); protected: virtual int32_t runOnce(); From 44a4bde626165da9bf63a29facc62a62defd76cb Mon Sep 17 00:00:00 2001 From: Jm Casler Date: Mon, 22 Nov 2021 13:15:36 -0800 Subject: [PATCH 10/13] Rename src/plugins/SerialPlugin.cpp to src/plugins/esp32/SerialPlugin.cpp --- src/plugins/{ => esp32}/SerialPlugin.cpp | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename src/plugins/{ => esp32}/SerialPlugin.cpp (100%) diff --git a/src/plugins/SerialPlugin.cpp b/src/plugins/esp32/SerialPlugin.cpp similarity index 100% rename from src/plugins/SerialPlugin.cpp rename to src/plugins/esp32/SerialPlugin.cpp From ec7953ccf027f4bac344bd30164510a4c0edadf1 Mon Sep 17 00:00:00 2001 From: Jm Casler Date: Mon, 22 Nov 2021 13:15:50 -0800 Subject: [PATCH 11/13] Rename src/plugins/SerialPlugin.h to src/plugins/esp32/SerialPlugin.h --- src/plugins/{ => esp32}/SerialPlugin.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename src/plugins/{ => esp32}/SerialPlugin.h (96%) diff --git a/src/plugins/SerialPlugin.h b/src/plugins/esp32/SerialPlugin.h similarity index 96% rename from src/plugins/SerialPlugin.h rename to src/plugins/esp32/SerialPlugin.h index c83d3689..27cd7e91 100644 --- a/src/plugins/SerialPlugin.h +++ b/src/plugins/esp32/SerialPlugin.h @@ -50,4 +50,4 @@ class SerialPluginRadio : public SinglePortPlugin virtual ProcessMessage handleReceived(const MeshPacket &mp); }; -extern SerialPluginRadio *serialPluginRadio; \ No newline at end of file +extern SerialPluginRadio *serialPluginRadio; From a3ce728e26dd97ea52d630d7096b3a3d32d961ad Mon Sep 17 00:00:00 2001 From: Jm Casler Date: Mon, 22 Nov 2021 13:18:49 -0800 Subject: [PATCH 12/13] Move SerialPlugin to plugins/esp32 --- src/plugins/Plugins.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/plugins/Plugins.cpp b/src/plugins/Plugins.cpp index 2a9e326d..92602c7a 100644 --- a/src/plugins/Plugins.cpp +++ b/src/plugins/Plugins.cpp @@ -5,12 +5,11 @@ #include "plugins/RemoteHardwarePlugin.h" #include "plugins/ReplyPlugin.h" #include "plugins/TextMessagePlugin.h" -#include "plugins/SerialPlugin.h" #include "plugins/TextMessagePlugin.h" #include "plugins/RoutingPlugin.h" #include "plugins/AdminPlugin.h" #ifndef NO_ESP32 -#include "plugins/SerialPlugin.h" +#include "plugins/esp32/SerialPlugin.h" #include "plugins/esp32/EnvironmentalMeasurementPlugin.h" #include "plugins/esp32/RangeTestPlugin.h" #include "plugins/esp32/StoreForwardPlugin.h" From 9ddcc5d2eddd11d853b969018012c2a872e67ca2 Mon Sep 17 00:00:00 2001 From: Jm Casler Date: Mon, 22 Nov 2021 17:47:42 -0800 Subject: [PATCH 13/13] S&F Pre-Alpha. Functional. No crashes (I hope). --- src/plugins/esp32/StoreForwardPlugin.cpp | 164 ++++++++++++++--------- src/plugins/esp32/StoreForwardPlugin.h | 12 +- 2 files changed, 107 insertions(+), 69 deletions(-) diff --git a/src/plugins/esp32/StoreForwardPlugin.cpp b/src/plugins/esp32/StoreForwardPlugin.cpp index 36512342..6c326343 100644 --- a/src/plugins/esp32/StoreForwardPlugin.cpp +++ b/src/plugins/esp32/StoreForwardPlugin.cpp @@ -2,18 +2,13 @@ #include "MeshService.h" #include "NodeDB.h" #include "RTC.h" -#include "RadioLibInterface.h" #include "Router.h" #include "configuration.h" #include "mesh-pb-constants.h" #include "plugins/PluginDev.h" #include #include - -//#define STOREFORWARD_MAX_PACKETS 0 -//#define STOREFORWARD_SEND_HISTORY_PERIOD 10 * 60 -//#define STOREFORWARD_HOP_MAX 0 // How many hops should we allow the packet to be forwarded? - +#include StoreForwardPlugin *storeForwardPlugin; @@ -23,19 +18,30 @@ int32_t StoreForwardPlugin::runOnce() #ifndef NO_ESP32 - /* - Calculate the time it takes for the maximum payload to be transmitted. Considering - most messages will be much shorter than this length, this will make us a good radio - neighbor and hopefully we won't use all the airtime. - */ - //uint32_t packetTimeMax = 500; - if (radioConfig.preferences.store_forward_plugin_enabled) { if (radioConfig.preferences.is_router) { - DEBUG_MSG("Store & Forward Plugin - packetTimeMax %d\n", this->packetTimeMax); - - return (500); + + if (this->busy) { + // Send out the message queue. + + //DEBUG_MSG("--- --- --- In busy loop 1 %d\n", this->packetHistoryTXQueue_index); + storeForwardPlugin->sendPayload(this->busyTo, this->packetHistoryTXQueue_index); + + if (this->packetHistoryTXQueue_index == packetHistoryTXQueue_size) { + strcpy(this->routerMessage, "** S&F - Done"); + storeForwardPlugin->sendMessage(this->busyTo, this->routerMessage); + //DEBUG_MSG("--- --- --- In busy loop - Done \n"); + this->packetHistoryTXQueue_index = 0; + this->busy = false; + } else { + this->packetHistoryTXQueue_index++; + } + + } + + // TODO: Dynamicly adjust the time this returns in the loop based on the size of the packets being actually transmitted. + return (this->packetTimeMax); } else { DEBUG_MSG("Store & Forward Plugin - Disabled (is_router = false)\n"); @@ -62,7 +68,7 @@ void StoreForwardPlugin::populatePSRAM() https://learn.upesy.com/en/programmation/psram.html#psram-tab */ - uint32_t store_forward_plugin_replay_max_records = 250; + uint32_t store_forward_plugin_replay_max_records = 250; DEBUG_MSG("Before PSRAM initilization:\n"); @@ -85,7 +91,7 @@ void StoreForwardPlugin::populatePSRAM() DEBUG_MSG(" Total PSRAM: %d\n", ESP.getPsramSize()); DEBUG_MSG(" Free PSRAM: %d\n", ESP.getFreePsram()); DEBUG_MSG("Store and Forward Stats:\n"); - DEBUG_MSG(" numberOfPackets - %u\n", numberOfPackets); + DEBUG_MSG(" numberOfPackets for packetHistory - %u\n", numberOfPackets); } void StoreForwardPlugin::historyReport() @@ -101,50 +107,66 @@ void StoreForwardPlugin::historySend(uint32_t msAgo, uint32_t to) { uint32_t packetsSent = 0; - char routerMessage[80]; + - strcpy(routerMessage, "** S&F - Sending history"); - storeForwardPlugin->sendMessage(to, routerMessage); + uint32_t queueSize = storeForwardPlugin->historyQueueCreate(msAgo, to); + + if (queueSize) { + snprintf(this->routerMessage, 80, "** S&F - Sending %d message(s)", queueSize); + storeForwardPlugin->sendMessage(to, this->routerMessage); + + this->busy = true; // runOnce() will pickup the next steps once busy = true. + this->busyTo = to; + + } else { + strcpy(this->routerMessage, "** S&F - No history to send"); + storeForwardPlugin->sendMessage(to, this->routerMessage); + } +} + +uint32_t StoreForwardPlugin::historyQueueCreate(uint32_t msAgo, uint32_t to) { + + //uint32_t packetHistoryTXQueueIndex = 0; + + this->packetHistoryTXQueue_size = 0; - // MeshPacket mp; for (int i = 0; i < this->packetHistoryCurrent; i++) { - if (this->packetHistory[i].time) { - + /* + DEBUG_MSG("SF historyQueueCreate\n"); + DEBUG_MSG("SF historyQueueCreate - time %d\n", this->packetHistory[i].time); + DEBUG_MSG("SF historyQueueCreate - millis %d\n", millis()); + DEBUG_MSG("SF historyQueueCreate - math %d\n", (millis() - msAgo)); + */ + if (this->packetHistory[i].time && (this->packetHistory[i].time < (millis() - msAgo))) { + DEBUG_MSG("SF historyQueueCreate - Time matches - ok\n"); /* - Stored packet was sent to a broadcast address + Copy the messages that were received by the router in the last msAgo + to the packetHistoryTXQueue structure. + + TODO: The condition (this->packetHistory[i].to & 0xffffffff) == to) is not tested since + I don't have an easy way to target a specific user. Will need to do this soon. */ - if ((this->packetHistory[i].to & 0xffffffff) == 0xffffffff) { - DEBUG_MSG("Request: to-0x%08x, Stored: time-%u to-0x%08x\n", to & 0xffffffff, this->packetHistory[i].time, - this->packetHistory[i].to & 0xffffffff); + if ((this->packetHistory[i].to & 0xffffffff) == 0xffffffff + || + ((this->packetHistory[i].to & 0xffffffff) == to) + ) { + this->packetHistoryTXQueue[this->packetHistoryTXQueue_size].time = this->packetHistory[i].time; + this->packetHistoryTXQueue[this->packetHistoryTXQueue_size].to = this->packetHistory[i].to; + this->packetHistoryTXQueue[this->packetHistoryTXQueue_size].from = this->packetHistory[i].from; + this->packetHistoryTXQueue[this->packetHistoryTXQueue_size].payload_size = this->packetHistory[i].payload_size; + memcpy(this->packetHistoryTXQueue[this->packetHistoryTXQueue_size].payload, this->packetHistory[i].payload, Constants_DATA_PAYLOAD_LEN); + this->packetHistoryTXQueue_size++; - DEBUG_MSG(">>>>> %s\n", this->packetHistory[i].payload); + DEBUG_MSG("PacketHistoryStruct time=%d\n", this->packetHistory[i].time); + DEBUG_MSG("PacketHistoryStruct msg=%.*s\n", this->packetHistory[i].payload); + //DEBUG_MSG("PacketHistoryStruct msg=%.*s\n", this->packetHistoryTXQueue[packetHistoryTXQueueIndex].payload); - storeForwardPlugin->sendPayload(to, i); - packetsSent++; } - /* - Stored packet was intended to a named address - - TODO: - - TEST ME! I don't know if this works. - - If this works, merge it into the "if" statement above. - - */ - if ((this->packetHistory[i].to & 0xffffffff) == to) { - DEBUG_MSG("Request: to-0x%08x, Stored: time-%u to-0x%08x\n", to & 0xffffffff, this->packetHistory[i].time, - this->packetHistory[i].to & 0xffffffff); - storeForwardPlugin->sendPayload(to, i); - - packetsSent++; - } } } - - snprintf(routerMessage, 80, "** S&F - Sent %d message(s) - Done", packetsSent); - //strcpy(routerMessage, "** S&F - Sent x message(s)"); - storeForwardPlugin->sendMessage(to, routerMessage); + return this->packetHistoryTXQueue_size; } void StoreForwardPlugin::historyAdd(const MeshPacket &mp) @@ -172,16 +194,16 @@ void StoreForwardPlugin::sendPayload(NodeNum dest, uint32_t packetHistory_index) MeshPacket *p = allocReply(); p->to = dest; - p->from = this->packetHistory[packetHistory_index].from; + p->from = this->packetHistoryTXQueue[packetHistory_index].from; // Let's assume that if the router received the S&F request that the client is in range. // TODO: Make this configurable. p->want_ack = false; p->decoded.payload.size = - this->packetHistory[packetHistory_index].payload_size; // You must specify how many bytes are in the reply - memcpy(p->decoded.payload.bytes, this->packetHistory[packetHistory_index].payload, - this->packetHistory[packetHistory_index].payload_size); + this->packetHistoryTXQueue[packetHistory_index].payload_size; // You must specify how many bytes are in the reply + memcpy(p->decoded.payload.bytes, this->packetHistoryTXQueue[packetHistory_index].payload, + this->packetHistoryTXQueue[packetHistory_index].payload_size); service.sendToMesh(p); } @@ -214,19 +236,24 @@ ProcessMessage StoreForwardPlugin::handleReceived(const MeshPacket &mp) // The router node should not be sending messages as a client. if (getFrom(&mp) != nodeDB.getNodeNum()) { - printPacket("PACKET FROM RADIO", &mp); - // DEBUG_MSG("We last saw this node (%u), %u sec ago\n", mp.from & 0xffffffff, (millis() - sawTime) / 1000); - // DEBUG_MSG(" -------------- "); + if (mp.decoded.portnum == PortNum_TEXT_MESSAGE_APP) { DEBUG_MSG("Packet came from - PortNum_TEXT_MESSAGE_APP\n"); - DEBUG_MSG("--- --- --- %s \n", p.payload.bytes); - - if ((p.payload.bytes[0] == 'S') && (p.payload.bytes[1] == 'F')) { + if ((p.payload.bytes[0] == 'S') && (p.payload.bytes[1] == 'F') && (p.payload.bytes[2] == 0x00)) { DEBUG_MSG("--- --- --- Request to send\n"); - // Send the last 5 minutes of messages. - storeForwardPlugin->historySend(5 * 1000 * 60, getFrom(&mp)); + // Send the last 60 minutes of messages. + if (this->busy) { + strcpy(this->routerMessage, "** S&F - Busy. Try again shortly."); + storeForwardPlugin->sendMessage(getFrom(&mp), this->routerMessage); + } else { + storeForwardPlugin->historySend(1000 * 60, getFrom(&mp)); + } + } else if ((p.payload.bytes[0] == 'S') && (p.payload.bytes[1] == 'F') && (p.payload.bytes[2] == 'm') && (p.payload.bytes[3] == 0x00)) { + strcpy(this->routerMessage, "012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456"); + storeForwardPlugin->sendMessage(getFrom(&mp), this->routerMessage); + } else { storeForwardPlugin->historyAdd(mp); } @@ -259,9 +286,9 @@ StoreForwardPlugin::StoreForwardPlugin() without having to configure it from the PythonAPI or WebUI. */ - radioConfig.preferences.store_forward_plugin_enabled = 1; - radioConfig.preferences.is_router = 1; - radioConfig.preferences.is_always_powered = 1; + // radioConfig.preferences.store_forward_plugin_enabled = 1; + // radioConfig.preferences.is_router = 1; + // radioConfig.preferences.is_always_powered = 1; } if (radioConfig.preferences.store_forward_plugin_enabled) { @@ -278,9 +305,12 @@ StoreForwardPlugin::StoreForwardPlugin() this->populatePSRAM(); // Calculate the packet time. - //this->packetTimeMax = RadioLibInterface::instance->getPacketTime(Constants_DATA_PAYLOAD_LEN); + // this->packetTimeMax = RadioLibInterface::instance->getPacketTime(Constants_DATA_PAYLOAD_LEN); //RadioLibInterface::instance->getPacketTime(Constants_DATA_PAYLOAD_LEN); - RadioLibInterface::instance->getPacketTime(200); + //RadioLibInterface::instance->getPacketTime(Constants_DATA_PAYLOAD_LEN); + //RadioInterface::getPacketTime(500)l + + this->packetTimeMax = 2000; } else { DEBUG_MSG("Device has less than 1M of PSRAM free. Aborting startup.\n"); diff --git a/src/plugins/esp32/StoreForwardPlugin.h b/src/plugins/esp32/StoreForwardPlugin.h index 80987593..3df64077 100644 --- a/src/plugins/esp32/StoreForwardPlugin.h +++ b/src/plugins/esp32/StoreForwardPlugin.h @@ -17,14 +17,20 @@ struct PacketHistoryStruct { class StoreForwardPlugin : public SinglePortPlugin, private concurrency::OSThread { - bool firstTime = 1; + //bool firstTime = 1; + bool busy = 0; + uint32_t busyTo; + char routerMessage[80]; uint32_t receivedRecord[50][2] = {{0}}; PacketHistoryStruct *packetHistory; - PacketHistoryStruct *packetHistoryTXQueue; uint32_t packetHistoryCurrent = 0; + PacketHistoryStruct *packetHistoryTXQueue; + uint32_t packetHistoryTXQueue_size; + uint32_t packetHistoryTXQueue_index = 0; + uint32_t packetTimeMax = 0; @@ -39,6 +45,8 @@ class StoreForwardPlugin : public SinglePortPlugin, private concurrency::OSThrea void historyReport(); void historySend(uint32_t msAgo, uint32_t to); + uint32_t historyQueueCreate(uint32_t msAgo, uint32_t to); + /** * Send our payload into the mesh */