Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
106 commits
Select commit Hold shift + click to select a range
d508de9
Add Store and Forward++ module
jp-bennett Dec 20, 2025
28d507f
Broadcast root hash for an empty chain
jp-bennett Dec 21, 2025
f2b6383
Scratch fix
jp-bennett Dec 21, 2025
73cfa3c
Store incoming non-canon messages in scratch
jp-bennett Dec 22, 2025
6e83a9a
unbreak all the targets
jp-bennett Dec 22, 2025
ffdb3bc
Misc fixes
jp-bennett Dec 22, 2025
4d48d51
Build tryfix next
jp-bennett Dec 22, 2025
14ee1ed
shorthash on canon announce
jp-bennett Dec 22, 2025
20bf822
Add missing root_hash from scratch
jp-bennett Dec 22, 2025
3cbc5b7
Don't wipe scratch
jp-bennett Dec 22, 2025
e9ed2c0
Include hop_start in printPacket
jp-bennett Dec 23, 2025
3330d29
Set hop_limit and hop_start on message rebroadcasts
jp-bennett Dec 23, 2025
96726d2
Allow UDP and API packets in S$F++
jp-bennett Dec 23, 2025
e8fd517
Don't stash messages without a matching chain root
jp-bennett Dec 26, 2025
739ad0d
Add count handling to SFPP
jp-bennett Dec 26, 2025
d07f5be
misc partial chain fixes
jp-bennett Dec 26, 2025
b51235d
Misc
jp-bennett Dec 26, 2025
00a3249
Merge branch 'develop' into sfpp
jp-bennett Dec 26, 2025
a70d350
Fix getLinkFromCount()
jp-bennett Dec 26, 2025
428b839
Merge branch 'develop' into sfpp
jp-bennett Dec 27, 2025
a8a5086
Add more SFPP config values
jp-bennett Dec 28, 2025
39c0824
Minor tweak for behavior when chain is empty
jp-bennett Dec 28, 2025
426a7c1
Short hashes in
jp-bennett Dec 28, 2025
8be7908
Check for read-only DB
jp-bennett Dec 28, 2025
39a6ffc
Merge branch 'develop' into sfpp
jp-bennett Dec 28, 2025
14073e2
Merge branch 'develop' into sfpp
jp-bennett Dec 29, 2025
d63b583
Hash size 16
jp-bennett Dec 29, 2025
36e8a49
Wire in COMPRESSED port option pt 1
jp-bennett Dec 29, 2025
02d4ca2
Payload size work and misc
jp-bennett Dec 29, 2025
1cef109
More sfpp config
jp-bennett Dec 29, 2025
d44c3a8
And the enable
jp-bennett Dec 29, 2025
bbfca12
Cleanups
jp-bennett Dec 29, 2025
0759197
Merge branch 'develop' into sfpp
jp-bennett Dec 29, 2025
6d90b65
More comment cleanup
jp-bennett Dec 29, 2025
25383c9
Add sfpp as core portnum
jp-bennett Dec 29, 2025
f8c27d1
Working chain trimming
jp-bennett Dec 30, 2025
d272b28
sfpp Split Messages
jp-bennett Dec 30, 2025
55af6c4
Split message fixes
jp-bennett Dec 30, 2025
f56e651
Don't shadow variables
jp-bennett Dec 31, 2025
f634b7d
Don't Scratch!
jp-bennett Dec 31, 2025
fe22460
Keep your names consistent!
jp-bennett Dec 31, 2025
1625fd8
Merge branch 'develop' into sfpp
jp-bennett Dec 31, 2025
1fecdc7
Check again for NTP in SF++
jp-bennett Jan 1, 2026
baccd0c
Add peers table, check for null
jp-bennett Jan 1, 2026
7d7091e
Add null check for p_encrypted before MQTT publish (#9136)
jp-bennett Jan 1, 2026
9b73845
Update log messages to include StoreForwardpp
jp-bennett Jan 1, 2026
7d6a0f2
Add extra check for end of chain matching
jp-bennett Jan 2, 2026
b7028ff
Add peers table
jp-bennett Jan 2, 2026
b90b5ff
Merge branch 'develop' into sfpp
jp-bennett Jan 2, 2026
b3b115b
Don't process own packets in SF++
jp-bennett Jan 2, 2026
78baaf4
Check for existing commit hash, etc
jp-bennett Jan 2, 2026
8779842
Log rebroadcast timeouts
jp-bennett Jan 2, 2026
dd4fb6b
Add chain speculation from scratch
jp-bennett Jan 2, 2026
c7f816e
Add StoreAndForward
jp-bennett Jan 2, 2026
b3d1d56
Merge branch 'develop' into sfpp
jp-bennett Jan 2, 2026
9134239
Add sqlite to build requires
jp-bennett Jan 3, 2026
83c8875
Merge branch 'develop' into sfpp
jp-bennett Jan 3, 2026
f5b41c2
Add missed comma
jp-bennett Jan 3, 2026
1869f21
Add sqlite dev to more dockerfiles
jp-bennett Jan 3, 2026
8a059ba
Add option to clear a chain when it falls too far behind
jp-bennett Jan 4, 2026
8c37669
Check links behind when receiving a link
jp-bennett Jan 4, 2026
a34cd4c
Better log messages
jp-bennett Jan 4, 2026
436f174
Actually include the chain counter in CANON ANNOUNCE
jp-bennett Jan 4, 2026
ee25a0a
Actually include the counter in CANON ANNOUNCE
jp-bennett Jan 4, 2026
8b5141d
Merge branch 'develop' into sfpp
jp-bennett Jan 4, 2026
1b13f87
Don't double-process rebroadcast messages
jp-bennett Jan 4, 2026
21c0dca
Merge branch 'develop' into sfpp
jp-bennett Jan 4, 2026
8ecce1e
Fix for integer overflow
jp-bennett Jan 5, 2026
c6fc798
More sanity checks on incoming messages
jp-bennett Jan 5, 2026
325f7d2
Don't process packet when decoding fails
jp-bennett Jan 5, 2026
c77709a
Fix the other links_behind underflow
jp-bennett Jan 5, 2026
74a6c9f
Alpine docker fix
jp-bennett Jan 5, 2026
3ae331e
Add canon_scratch to SF++
jp-bennett Jan 7, 2026
ae2a06e
SFPP Logging misc
jp-bennett Jan 7, 2026
4e92f7f
Merge branch 'develop' into sfpp
jp-bennett Jan 8, 2026
9ab2ee3
Check for valid hash during commit
jp-bennett Jan 8, 2026
8217354
Unbork the things
jp-bennett Jan 8, 2026
76beeda
Re-add exception for empty chain
jp-bennett Jan 8, 2026
942f2cb
Tryfix next
jp-bennett Jan 8, 2026
9824357
Stratum0 fix
jp-bennett Jan 8, 2026
f46a9df
misc
jp-bennett Jan 8, 2026
e03f1b5
Merge branch 'develop' into sfpp
jp-bennett Jan 8, 2026
6c69d9e
Disable SF++ by default in forced sim mode (When running with -s)
jp-bennett Jan 8, 2026
e990198
Merge branch 'develop' into sfpp
jp-bennett Jan 8, 2026
5a0644c
Code refactor
jp-bennett Jan 8, 2026
aca7fe9
Properly empty canon_scratch
jp-bennett Jan 8, 2026
e33fbca
Refactor and bugfix
jp-bennett Jan 8, 2026
5582e94
Minor fix
jp-bennett Jan 8, 2026
4bb93c1
Don't double add to canon scratch
jp-bennett Jan 8, 2026
595b5f1
Fix message hash recalc
jp-bennett Jan 8, 2026
ab781e9
Don't try to send scratch messages from stratum0
jp-bennett Jan 8, 2026
5de0654
Logging
jp-bennett Jan 9, 2026
5adc966
Handle text messages from local node
jp-bennett Jan 9, 2026
456fa3d
Merge branch 'develop' into sfpp
jp-bennett Jan 9, 2026
a67cf0f
Add SF++ metrics logging
jp-bennett Jan 10, 2026
a1d6978
Add portnum whitelist for testing
jp-bennett Jan 11, 2026
8b8c188
Add NoHopPorts
jp-bennett Jan 11, 2026
5633848
Tryfix nohop
jp-bennett Jan 13, 2026
5af6a48
Merge branch 'develop' into sfpp
jp-bennett Jan 15, 2026
7f565fd
Merge branch 'develop' into sfpp
fifieldt Jan 16, 2026
f36406e
Merge branch 'develop' into sfpp
jp-bennett Jan 25, 2026
338dd11
Merge branch 'develop' into sfpp
jp-bennett Jan 28, 2026
0562a67
Merge branch 'develop' into sfpp
jp-bennett Feb 1, 2026
3136cb4
Merge branch 'develop' into sfpp
jp-bennett Feb 4, 2026
c0eb4f1
Merge branch 'develop' into sfpp
caveman99 Feb 16, 2026
362a2c0
Merge branch 'develop' into sfpp
jp-bennett Feb 27, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions bin/config-dist.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,16 @@ HostMetrics:
# UserStringCommand: cat /sys/firmware/devicetree/base/serial-number # Command to execute, to send the results as the userString


StoreAndForward:
# Enabled: true # Enable Store and Forward++, true by default
# DBPath: /var/lib/meshtasticd/ # Path to the S&F++ Sqlite DB
# Stratum0: false # Specify if this node is a Stratum 0 node, the controller node.
# InitialSync: 10 # Number of messages to
# Hops: 3 # Number of hops to use for SF++ messages
# AnnounceInterval: 5 # Interval in minutes between announcing tip of chain hash
# MaxChainLength: 1000 # Maximum number of messages to store in a chain


Config:
# DisplayMode: TWOCOLOR # uncomment to force BaseUI
# DisplayMode: COLOR # uncomment to force MUI
Expand Down
2 changes: 1 addition & 1 deletion platformio.ini
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ lib_deps =
# renovate: datasource=custom.pio depName=NonBlockingRTTTL packageName=end2endzone/library/NonBlockingRTTTL
end2endzone/NonBlockingRTTTL@1.4.0
build_flags = ${env.build_flags} -Os
build_src_filter = ${env.build_src_filter} -<platform/portduino/> -<graphics/niche/>
build_src_filter = ${env.build_src_filter} -<platform/portduino/> -<graphics/niche/> -<modules/Native/>

; Common libs for communicating over TCP/IP networks such as MQTT
[networking_base]
Expand Down
12 changes: 12 additions & 0 deletions src/mesh/NextHopRouter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,18 @@ bool NextHopRouter::perhapsRebroadcast(const meshtastic_MeshPacket *p)
tosend->hop_start -= (tosend->hop_limit - 2);
tosend->hop_limit = 2;
}
#elif ARCH_PORTDUINO
if (tosend->which_payload_variant == meshtastic_MeshPacket_decoded_tag &&
portduino_config.nohop_ports.size()) {
for (const auto &port : portduino_config.nohop_ports) {
if (port == tosend->decoded.portnum) {
LOG_DEBUG("0-hopping portnum %u", tosend->decoded.portnum);
tosend->hop_start -= tosend->hop_limit;
tosend->hop_limit = 0;
break;
}
}
}
#endif

if (p->next_hop == NO_NEXT_HOP_PREFERENCE) {
Expand Down
6 changes: 3 additions & 3 deletions src/mesh/RadioInterface.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -640,9 +640,9 @@ uint32_t RadioInterface::getTxDelayMsecWeighted(meshtastic_MeshPacket *p)
void printPacket(const char *prefix, const meshtastic_MeshPacket *p)
{
#if defined(DEBUG_PORT) && !defined(DEBUG_MUTE)
std::string out =
DEBUG_PORT.mt_sprintf("%s (id=0x%08x fr=0x%08x to=0x%08x, transport = %u, WantAck=%d, HopLim=%d Ch=0x%x", prefix, p->id,
p->from, p->to, p->transport_mechanism, p->want_ack, p->hop_limit, p->channel);
std::string out = DEBUG_PORT.mt_sprintf(
"%s (id=0x%08x fr=0x%08x to=0x%08x, transport = %u, WantAck=%d, HopLim=%d HopStart=%d Ch=0x%x", prefix, p->id, p->from,
p->to, p->transport_mechanism, p->want_ack, p->hop_limit, p->hop_start, p->channel);
if (p->which_payload_variant == meshtastic_MeshPacket_decoded_tag) {
auto &s = p->decoded;

Expand Down
23 changes: 23 additions & 0 deletions src/mesh/Router.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,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
Expand Down Expand Up @@ -365,6 +366,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) {
Expand Down Expand Up @@ -745,6 +752,22 @@ void Router::handleReceived(meshtastic_MeshPacket *p, RxSource src)
cancelSending(p->from, p->id);
skipHandle = true;
}
#if ARCH_PORTDUINO
if (portduino_config.whitelist_enabled) {
bool allowed = false;
for (const auto &port : portduino_config.whitelist_ports) {
if (port == p->decoded.portnum) {
allowed = true;
break;
}
}
if (!allowed) {
LOG_DEBUG("Dropping packet not on Portduino Whitelist");
cancelSending(p->from, p->id);
skipHandle = true;
}
}
#endif
} else {
printPacket("packet decoding failed or skipped (no PSK?)", p);
}
Expand Down
8 changes: 8 additions & 0 deletions src/modules/Modules.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,9 @@
#include "modules/WaypointModule.h"
#endif
#if ARCH_PORTDUINO
#include "input/LinuxInputImpl.h"
#include "input/SeesawRotary.h"
#include "modules/Native/StoreForwardPlusPlus.h"
#include "modules/Telemetry/HostMetrics.h"
#if !MESHTASTIC_EXCLUDE_STOREFORWARD
#include "modules/StoreForwardModule.h"
Expand Down Expand Up @@ -184,6 +187,11 @@ void setupModules()
#endif
#if ARCH_PORTDUINO
new HostMetricsModule();
#if SFPP_ENABLED
if (portduino_config.sfpp_enabled) {
storeForwardPlusPlusModule = new StoreForwardPlusPlusModule();
}
#endif
#endif
#if HAS_TELEMETRY
new DeviceTelemetryModule();
Expand Down
Loading
Loading