Files
pyxis/patch_msgpack.py
T
torlando-tech 6e14d626d1 feat(build): wire microReticulum for T-Deck — PSRAM, LittleFS, FS path persistence
Five build-config changes that unlock proper microReticulum behavior
on the T-Deck Plus:

1. PSRAM allocator (`-DRNS_DEFAULT_ALLOCATOR=RNS_PSRAM_ALLOCATOR`,
   `-DRNS_CONTAINER_ALLOCATOR=RNS_PSRAM_POOL_ALLOCATOR`,
   `-DRNS_PSRAM_POOL_BUFFER_SIZE=2048000`). Previously default-heap
   on ESP32, which routed every microReticulum allocation (path
   table, destinations, etc.) through internal SRAM. Under live
   announce flood the internal heap dropped from 92KB → 40KB free,
   max_block fragmented from 77KB → 19KB. With PSRAM allocator the
   internal heap stays rock-steady at 137KB and microReticulum lives
   in 2MB of dedicated TLSF pool in PSRAM.

2. LittleFS instead of SPIFFS (`-DUSTORE_USE_LITTLEFS`). microStore's
   FileStore puts (path table, etc.) hit the filesystem several
   times per second on a busy network. SPIFFS GC stalls for 100s of
   ms during block erase, causing flush_buffer() to fail and every
   put to bail silently. LittleFS handles sustained writes cleanly.

3. Filesystem-backed path persistence (`-DRNS_USE_FS`,
   `-DRNS_PERSIST_PATHS`). Without these flags, Transport::start()
   skips _path_store.init() entirely and every announce-driven put
   fails at TypedStore::isValid() — surfacing as "Failed to add
   destination to path table" spam (~3.4/sec) and an empty UI
   announce list.

4. Switch lib_ldf_mode to chain+ (was deep+) — deep+ scans every
   #include statement and auto-fetches matching libs from the
   registry, which was pulling a parallel microReticulum copy and
   bypassing our deps/microReticulum/ overlay. chain+ follows only
   explicit dependencies declared in library.json files.

5. patch_msgpack.py PIO pre-script — promotes hideakitai/MsgPack's
   `Packer::packRawBytes` and `Unpacker::indices` from private to
   public so microLXMF can splice arbitrary msgpack values into
   LXMessage's fields-map wire format. Mirrors the equivalent patch
   in microLXMF/conformance-bridge/CMakeLists.txt:106-125.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-06 18:16:09 -04:00

53 lines
2.0 KiB
Python

"""
PlatformIO pre-build script: Expose hideakitai/MsgPack internals used by microLXMF.
LXMessage's wire format includes a `dict[int, Any]` fields map. To splice
arbitrary msgpack values into the stream without LXMessage knowing each
value's type, the encoder uses Packer::packRawBytes (private upstream)
to write pre-encoded bytes; the decoder uses Unpacker::indices /
raw_data (also private upstream) to capture each key+value byte span as
an opaque slice.
This patch promotes the relevant access modifiers from private to
public. Idempotent: only rewrites on first apply, no-op afterward.
Mirrors the patch the microLXMF conformance-bridge applies via its
CMakeLists (microLXMF/conformance-bridge/CMakeLists.txt:106-125).
"""
Import("env")
import os
MSGPACK_BASE = os.path.join(
env.get("PROJECT_DIR", "."),
".pio", "libdeps", "tdeck", "MsgPack", "MsgPack"
)
def apply_patch(filepath, old, new, label):
if not os.path.exists(filepath):
print(f"PATCH: {os.path.basename(filepath)} not found, skipping {label}")
return
with open(filepath, "r") as f:
content = f.read()
if old in content:
with open(filepath, "w") as f:
f.write(content.replace(old, new))
print(f"PATCH: {label}")
elif new in content or "patched by pyxis" in content:
print(f"PATCH: {label} (already applied)")
else:
print(f"PATCH: WARNING -- {label}: expected pattern not found")
apply_patch(
os.path.join(MSGPACK_BASE, "Packer.h"),
" private:\n void packRawByte",
" public: // patched by pyxis (microLXMF needs packRawBytes)\n void packRawByte",
"Packer.h: expose packRawBytes/packRawByte as public",
)
apply_patch(
os.path.join(MSGPACK_BASE, "Unpacker.h"),
" class Unpacker {\n uint8_t* raw_data",
" class Unpacker {\n public: // patched by pyxis (microLXMF needs indices/raw_data)\n uint8_t* raw_data",
"Unpacker.h: expose indices/raw_data as public",
)