LoRa split-packet framing, TX queue, and LXMF delivery fixes

LoRaInterface: Implement RNode-compatible split-packet framing so the
full Reticulum MTU (500 bytes) works over LoRa. Packets >254 bytes are
transparently split into two LoRa frames with matching sequence numbers
and reassembled on the receiver. Also adds a 4-deep TX queue instead of
dropping packets when the radio is busy — critical for link handshakes.

LXMFManager: Large messages (>MDU) now queue pending link establishment
and retry via resource transfer instead of failing immediately. Stale
link-pending state is detected and reset. Speculative background link
establishment removed to avoid LoRa collisions.

AnnounceManager: Add app_data hex diagnostics on announce RX for
debugging name extraction issues.

main.cpp: Centralize all announce paths through announceWithName() so
display name and app_data are always logged.
This commit is contained in:
DeFiDude
2026-03-24 20:55:07 -06:00
parent 2221eb832f
commit 851da63220
6 changed files with 252 additions and 102 deletions
+11 -14
View File
@@ -142,14 +142,19 @@ RNS::Bytes encodeAnnounceName(const String& name) {
}
static void announceWithName() {
Serial.println("[ANNOUNCE-TX] announceWithName() entry");
RNS::Bytes appData = encodeAnnounceName(userConfig.settings().displayName);
Serial.printf("[ANNOUNCE-TX] name=\"%s\" appData=%d bytes\n",
userConfig.settings().displayName.c_str(), (int)appData.size());
if (appData.size() > 0) {
Serial.printf("[ANNOUNCE-TX] hex: ");
for (size_t i = 0; i < appData.size() && i < 20; i++) Serial.printf("%02X", appData.data()[i]);
Serial.println();
}
rns.announce(appData);
ui.statusBar().flashAnnounce();
ui.statusBar().showToast("Announce sent!");
ui.lvStatusBar().flashAnnounce();
ui.lvStatusBar().showToast("Announce sent!");
Serial.println("[ANNOUNCE-TX] announceWithName() exit");
}
// =============================================================================
@@ -785,11 +790,8 @@ void setup() {
ui.lvTabBar().setActiveTab(LvTabBar::TAB_HOME);
// Initial announce with name
RNS::Bytes appData = encodeAnnounceName(userConfig.settings().displayName);
rns.announce(appData);
announceWithName();
lastAutoAnnounce = millis();
ui.statusBar().flashAnnounce();
ui.lvStatusBar().flashAnnounce();
Serial.println("[BOOT] Initial announce sent");
});
@@ -804,8 +806,7 @@ void setup() {
ui.lvTabBar().setActiveTab(LvTabBar::TAB_HOME);
// Initial announce with name
RNS::Bytes appData = encodeAnnounceName(userConfig.settings().displayName);
rns.announce(appData);
announceWithName();
lastAutoAnnounce = millis();
Serial.println("[BOOT] Initial announce sent");
}
@@ -908,10 +909,7 @@ void loop() {
if (rns.loraInterface() && rns.loraInterface()->airtimeUtilization() > LoRaInterface::AIRTIME_THROTTLE) {
Serial.println("[AUTO] Skipping announce: LoRa airtime > 25%");
} else {
RNS::Bytes appData = encodeAnnounceName(userConfig.settings().displayName);
rns.announce(appData);
ui.statusBar().flashAnnounce();
ui.lvStatusBar().flashAnnounce();
announceWithName();
Serial.println("[AUTO] Periodic announce");
}
}
@@ -963,8 +961,7 @@ void loop() {
}
if (anyTcpConnected) {
Serial.println("[TCP] Sending announce over new TCP connection...");
RNS::Bytes appData = encodeAnnounceName(userConfig.settings().displayName);
rns.announce(appData);
announceWithName();
lastAutoAnnounce = millis();
} else {
Serial.println("[TCP] No TCP clients connected, skipping announce");