From 5adc9663b731a77faf1ba1c0fcd51deb725ac6ac Mon Sep 17 00:00:00 2001 From: Jonathan Bennett Date: Fri, 9 Jan 2026 16:29:54 -0600 Subject: [PATCH] Handle text messages from local node --- src/mesh/Router.cpp | 7 ++ src/modules/Modules.cpp | 2 +- src/modules/Native/StoreForwardPlusPlus.cpp | 87 +++++++++++++++------ src/modules/Native/StoreForwardPlusPlus.h | 4 + 4 files changed, 77 insertions(+), 23 deletions(-) diff --git a/src/mesh/Router.cpp b/src/mesh/Router.cpp index a3861521a..391c827de 100644 --- a/src/mesh/Router.cpp +++ b/src/mesh/Router.cpp @@ -17,6 +17,7 @@ #endif #include "Default.h" #if ARCH_PORTDUINO +#include "modules/Native/StoreForwardPlusPlus.h" #include "platform/portduino/PortduinoGlue.h" #endif #if ENABLE_JSON_LOGGING || ARCH_PORTDUINO @@ -359,6 +360,12 @@ ErrorCode Router::send(meshtastic_MeshPacket *p) abortSendAndNak(encodeResult, p); return encodeResult; // FIXME - this isn't a valid ErrorCode } +#if ARCH_PORTDUINO + if (p_decoded->decoded.portnum == meshtastic_PortNum_TEXT_MESSAGE_APP && + (p->from == 0 || p->from == nodeDB->getNodeNum()) && storeForwardPlusPlusModule && portduino_config.sfpp_enabled) { + storeForwardPlusPlusModule->handleEncrypted(p_decoded, p); + } +#endif #if !MESHTASTIC_EXCLUDE_MQTT // Only publish to MQTT if we're the original transmitter of the packet if (moduleConfig.mqtt.enabled && isFromUs(p) && mqtt) { diff --git a/src/modules/Modules.cpp b/src/modules/Modules.cpp index 9889f074d..655810124 100644 --- a/src/modules/Modules.cpp +++ b/src/modules/Modules.cpp @@ -246,7 +246,7 @@ void setupModules() new HostMetricsModule(); #if SFPP_ENABLED if (portduino_config.sfpp_enabled) { - new StoreForwardPlusPlusModule(); + storeForwardPlusPlusModule = new StoreForwardPlusPlusModule(); } #endif #endif diff --git a/src/modules/Native/StoreForwardPlusPlus.cpp b/src/modules/Native/StoreForwardPlusPlus.cpp index 8978beeef..859ebdc9a 100644 --- a/src/modules/Native/StoreForwardPlusPlus.cpp +++ b/src/modules/Native/StoreForwardPlusPlus.cpp @@ -392,6 +392,42 @@ int32_t StoreForwardPlusPlusModule::runOnce() return portduino_config.sfpp_announce_interval * 60 * 1000; } +void StoreForwardPlusPlusModule::handleEncrypted(const meshtastic_MeshPacket *mp, const meshtastic_MeshPacket *p_encrypted) +{ + // This is intended to handle text messages from the local node + if (mp->from != nodeDB->getNodeNum() && mp->from != 0) { + return; + } + + link_object lo = ingestTextPacket(*mp, p_encrypted); + + if (lo.from == 0) + lo.from = nodeDB->getNodeNum(); + + if (isInDB(lo.message_hash, lo.message_hash_len) && isInScratch(lo.message_hash, lo.message_hash_len) && + isInCanonScratch(lo.message_hash, lo.message_hash_len)) { + return; + } + + if (!portduino_config.sfpp_stratum0) { + if (lo.root_hash_len == 0) { + LOG_DEBUG("StoreForwardpp Received text message, but no chain. Possibly no Stratum0 on local mesh."); + return; + } + addToScratch(lo); + LOG_DEBUG("StoreForwardpp added message to scratch db"); + // send link to upstream? + + return; + } + addToChain(lo); + + if (!pendingRun) { + setIntervalFromNow(10 * 1000); // run again in 10 seconds to announce the new tip of chain + pendingRun = true; + } +} + ProcessMessage StoreForwardPlusPlusModule::handleReceived(const meshtastic_MeshPacket &mp) { // To avoid terrible time problems, require NTP or GPS time @@ -399,36 +435,37 @@ ProcessMessage StoreForwardPlusPlusModule::handleReceived(const meshtastic_MeshP return ProcessMessage::CONTINUE; } - if (mp.from == nodeDB->getNodeNum()) { - return ProcessMessage::CONTINUE; // don't process our own packets + if (mp.from == nodeDB->getNodeNum() || mp.from == 0) { + return ProcessMessage::CONTINUE; // don't process our own packets here } // Allow only LoRa, Multicast UDP, and API packets // maybe in the future, only disallow MQTT - if (mp.transport_mechanism != meshtastic_MeshPacket_TransportMechanism_TRANSPORT_INTERNAL && - mp.transport_mechanism != meshtastic_MeshPacket_TransportMechanism_TRANSPORT_LORA && + if (mp.transport_mechanism != meshtastic_MeshPacket_TransportMechanism_TRANSPORT_LORA && mp.transport_mechanism != meshtastic_MeshPacket_TransportMechanism_TRANSPORT_MULTICAST_UDP && mp.transport_mechanism != meshtastic_MeshPacket_TransportMechanism_TRANSPORT_API) { return ProcessMessage::CONTINUE; // Let others look at this message also if they want } + // will eventually host DMs and other undecodable messages + if (mp.which_payload_variant != meshtastic_MeshPacket_decoded_tag) { + LOG_WARN("StoreForwardpp Saw an encoded message, dropping"); + return ProcessMessage::CONTINUE; // Let others look at this message also if they want + } + if (router == nullptr || router->p_encrypted == nullptr) { - LOG_WARN("StoreForwardpp cannot process message, due to null pointer"); + LOG_WARN("StoreForwardpp cannot process text message, due to null pointer"); return ProcessMessage::CONTINUE; } - // will eventually host DMs and other undecodable messages - if (mp.which_payload_variant != meshtastic_MeshPacket_decoded_tag) { + if (mp.id != router->p_encrypted->id) { + LOG_WARN("Wrong packet in p_encrypted, dropping text message"); return ProcessMessage::CONTINUE; // Let others look at this message also if they want } + if (mp.decoded.portnum == meshtastic_PortNum_TEXT_MESSAGE_APP && mp.to == NODENUM_BROADCAST) { link_object lo = ingestTextPacket(mp, router->p_encrypted); - // the big problem here is that the packet passes through here before encryption - // From 0 in this context means it originated from the local node - if (lo.from == 0) - lo.from = nodeDB->getNodeNum(); - if (isInDB(lo.message_hash, lo.message_hash_len)) { LOG_DEBUG("StoreForwardpp Found text message in chain DB"); // We may have this message already, but we may not have the payload @@ -437,18 +474,20 @@ ProcessMessage StoreForwardPlusPlusModule::handleReceived(const meshtastic_MeshP updatePayload(lo.message_hash, lo.message_hash_len, lo.payload); return ProcessMessage::CONTINUE; } + if (isInDB(lo.message_hash, lo.message_hash_len) && isInScratch(lo.message_hash, lo.message_hash_len) && + isInCanonScratch(lo.message_hash, lo.message_hash_len)) { + return ProcessMessage::CONTINUE; + } if (!portduino_config.sfpp_stratum0) { - if (!isInDB(lo.message_hash, lo.message_hash_len) && !isInScratch(lo.message_hash, lo.message_hash_len) && - !isInCanonScratch(lo.message_hash, lo.message_hash_len)) { - if (lo.root_hash_len == 0) { - LOG_DEBUG("StoreForwardpp Received text message, but no chain. Possibly no Stratum0 on local mesh."); - return ProcessMessage::CONTINUE; - } - addToScratch(lo); - LOG_DEBUG("StoreForwardpp added message to scratch db"); - // send link to upstream? + if (lo.root_hash_len == 0) { + LOG_DEBUG("StoreForwardpp Received text message, but no chain. Possibly no Stratum0 on local mesh."); + return ProcessMessage::CONTINUE; } + addToScratch(lo); + LOG_DEBUG("StoreForwardpp added message to scratch db"); + // send link to upstream? + return ProcessMessage::CONTINUE; } addToChain(lo); @@ -686,14 +725,16 @@ bool StoreForwardPlusPlusModule::handleReceivedProtobuf(const meshtastic_MeshPac // Respond by announcing this if (t->commit_hash.size == 0) { link_object link_to_announce = getLinkFromMessageHash(incoming_link.message_hash, incoming_link.message_hash_len); - canonAnnounce(link_to_announce); LOG_INFO("StoreForwardpp Received link already in chain #%u, announcing that commit hash", link_to_announce.counter); + canonAnnounce(link_to_announce); + } else { LOG_INFO("StoreForwardpp Received link already in chain"); } return true; } + // do we want to explicitly check for blank comm hash here? // We have a link. Recalculate the message hash and check if the commit hash matches if (recalculateHash(incoming_link, t->root_hash.bytes, t->root_hash.size, t->commit_hash.bytes, t->commit_hash.size)) { @@ -2004,4 +2045,6 @@ void StoreForwardPlusPlusModule::logLinkObject(link_object &lo) } } +StoreForwardPlusPlusModule *storeForwardPlusPlusModule; + #endif // has include sqlite3 \ No newline at end of file diff --git a/src/modules/Native/StoreForwardPlusPlus.h b/src/modules/Native/StoreForwardPlusPlus.h index 71c0d0f24..de03f5abf 100644 --- a/src/modules/Native/StoreForwardPlusPlus.h +++ b/src/modules/Native/StoreForwardPlusPlus.h @@ -87,6 +87,8 @@ class StoreForwardPlusPlusModule : public ProtobufModule