diff --git a/platformio.ini b/platformio.ini index 4760ec67..02e70fb8 100644 --- a/platformio.ini +++ b/platformio.ini @@ -183,7 +183,7 @@ lib_deps = ; MeshCore core = the meshcomod monorepo built as a lib, pinned by tag. ; Touch-app files (TouchPrefsStore, WifiRuntimeStore, transports, ...) are ; vendored in this app's src/ and dropped from the lib via -DMC_VENDORED_TOUCH_APP. - https://github.com/ALLFATHER-BV/meshcomod.git#core-v1.17.0 + https://github.com/ALLFATHER-BV/meshcomod.git#core-v1.17.1 SPI Wire jgromes/RadioLib @ ^7.6.0 @@ -451,7 +451,7 @@ build_src_filter = +<../variants/attaky_mesh_series/*.cpp> lib_deps = - https://github.com/ALLFATHER-BV/meshcomod.git#core-v1.17.0 + https://github.com/ALLFATHER-BV/meshcomod.git#core-v1.17.1 SPI Wire jgromes/RadioLib @ ^7.6.0 @@ -626,7 +626,7 @@ build_src_filter = +<../variants/lilygo_tdeck/*.cpp> lib_deps = - https://github.com/ALLFATHER-BV/meshcomod.git#core-v1.17.0 + https://github.com/ALLFATHER-BV/meshcomod.git#core-v1.17.1 SPI Wire jgromes/RadioLib @ ^7.6.0 @@ -847,7 +847,7 @@ build_src_filter = +<../variants/lilygo_tlora_pager/*.cpp> lib_deps = - https://github.com/ALLFATHER-BV/meshcomod.git#core-v1.17.0 + https://github.com/ALLFATHER-BV/meshcomod.git#core-v1.17.1 SPI Wire jgromes/RadioLib @ ^7.6.0 @@ -1073,7 +1073,7 @@ build_src_filter = +<../variants/lilygo_tlora_pager/*.cpp> lib_deps = - https://github.com/ALLFATHER-BV/meshcomod.git#core-v1.17.0 + https://github.com/ALLFATHER-BV/meshcomod.git#core-v1.17.1 SPI Wire jgromes/RadioLib @ ^7.6.0 @@ -1311,7 +1311,7 @@ build_src_filter = +<../variants/thinknode_m9/*.cpp> lib_deps = - https://github.com/ALLFATHER-BV/meshcomod.git#core-v1.17.0 + https://github.com/ALLFATHER-BV/meshcomod.git#core-v1.17.1 SPI Wire jgromes/RadioLib @ ^7.6.0 @@ -1505,7 +1505,7 @@ build_src_filter = +<../variants/rak_tap_v2/*.cpp> lib_deps = - https://github.com/ALLFATHER-BV/meshcomod.git#core-v1.17.0 + https://github.com/ALLFATHER-BV/meshcomod.git#core-v1.17.1 SPI Wire jgromes/RadioLib @ ^7.6.0 diff --git a/release-notes/beta_61.txt b/release-notes/beta_61.txt new file mode 100644 index 00000000..8ead36ab --- /dev/null +++ b/release-notes/beta_61.txt @@ -0,0 +1,11 @@ +# beta_61 - fixes two contact-table regressions from the 1.17 rebase +# One user-facing note per non-blank, non-# line; # lines are section comments. + +# --- The headline --------------------------------------------------------------------- +Fixes a boot loop introduced by beta_60. A device whose contact list was empty - a fresh install, an erase-and-flash, or a card that had not mounted yet - crashed during startup and rebooted forever. Devices that already had contacts saved were unaffected, which is why it reached release: every board on the bench had a populated contact list. If you are stuck on beta_60, flashing beta_61 over it is enough; nothing needs erasing. +Fixes contacts becoming unreachable on beta_60. MeshCore 1.17 reserved eight slots at the start of the contact table, and our contact list, action sheets and phone-app sync were still counting from the old start, so the eight most recently added contacts could not be shown or acted on. A contact you had just added was invisible, and buttons like a room server's Log in silently did nothing because they resolved to an empty reserved slot. Nothing was ever lost - those contacts were in the table the whole time and reappear on this build. Reported by myshoeisonfire. +Upgrading from beta_60 also cleans up the empty placeholder contacts it wrote into the contacts file; they are dropped on load and gone for good after the next save. + +# --- Also fixed ------------------------------------------------------------------------- +A contact that changes its node name no longer leaves two chat threads behind. The thread is matched by key, but its title was never updated, while incoming messages are filed by sender name - so the next message after a rename started a second thread. The thread now follows the rename. Duplicates you already have can be deleted as before. Reported by myshoeisonfire. +Release builds now derive the firmware version, build date and core version from the release itself, and a release aborts if any board's image does not carry its own tag. beta_60 shipped reporting v1.16.0-touch in About because that value was maintained by hand; it now cannot drift. diff --git a/scripts/release.sh b/scripts/release.sh index 7e87dd4e..ef179338 100755 --- a/scripts/release.sh +++ b/scripts/release.sh @@ -47,7 +47,19 @@ mkdir -p "$ARCH/$TAG" "$FEED" if [ "$MODE" = "beta" ]; then # 2b. TEST build: compile both boards (tag + version embedded) into the beta archive + feed. - export PLATFORMIO_BUILD_FLAGS="-DFIRMWARE_RELEASE_TAG='\"${TAG}\"' -DFIRMWARE_VERSION='\"wadamesh ${TAG}\"'" + # Firmware data (About screen + the app's device info) is derived here, never + # hand-maintained: the tag, the core version actually pinned in platformio.ini, + # and today's build date. Every staged binary is verified to carry them below — + # beta_60 shipped with a stale in-tree default and About read "v1.16.0-touch". + CORE_VER="$(grep -oE 'meshcomod\.git#core-v[0-9.]+' platformio.ini | head -1 | sed 's/.*#core-//')" + [ -n "$CORE_VER" ] || { echo "ERROR: no core-v* pin found in platformio.ini"; exit 1; } + BUILD_DATE="$(date '+%d %b %Y')" + echo "firmware data: tag=$TAG core=$CORE_VER date=$BUILD_DATE" + export PLATFORMIO_BUILD_FLAGS="-DFIRMWARE_RELEASE_TAG='\"${TAG}\"' -DFIRMWARE_VERSION='\"wadamesh ${TAG}\"' -DFIRMWARE_BUILD_DATE='\"${BUILD_DATE}\"' -DFIRMWARE_CORE_VERSION='\"${CORE_VER}\"'" + # Keep the in-tree default (what DEV flashes show) in step with the pinned core, + # so a bench build never reports a version the firmware no longer is. + sed -i '' -E "s/^#define FIRMWARE_VERSION \"v[0-9.]+-touch\"/#define FIRMWARE_VERSION \"${CORE_VER}-touch\"/" src/MyMesh.h + git diff --quiet src/MyMesh.h || echo "note: refreshed the dev FIRMWARE_VERSION default in src/MyMesh.h -> ${CORE_VER}-touch (commit it)" for pair in $ENVS; do env="${pair%%:*}"; name="${pair##*:}" "$PIO" run -t mergebin -e "$env" @@ -89,6 +101,23 @@ print(json.dumps([{"name": b, "type": "dir"} for b in betas], indent=2)) PY echo "listing ($MODE): $(python3 -c 'import json,sys;print(", ".join(x["name"] for x in json.load(open(sys.argv[1]))))' "$ARCH/index.json")" +# 3a2. FIRMWARE DATA GATE — every staged app image must carry this tag, or the +# release ships binaries whose About screen / update check disagree with the +# release they are published under. Covers the out-of-band IDF boards +# (T-Display P4) too: they are injected into $ARCH/$TAG before this runs, so +# forgetting to rebuild them with WADA_FW_TAG fails here instead of shipping. +missing="" +for f in "$ARCH/$TAG"/*.bin; do + case "$f" in *-merged.bin) continue;; esac # merged images embed the same app + strings "$f" | grep -q "$TAG" || missing="$missing $(basename "$f")" +done +if [ -n "$missing" ]; then + echo "ERROR: these staged images do not embed $TAG:$missing" + echo " rebuild them with the tag (S3: release.sh does it; P4: WADA_FW_TAG=$TAG ./build.sh build)" + exit 1 +fi +echo "firmware data verified: every staged image embeds $TAG" + # 3b. Web-flasher metadata for THIS channel (version.json + manifests -> the channel feed). python3 "$ROOT/scripts/build/gen-flasher-meta.py" "$TAG" "$FEED" "$ROOT/release-notes/$TAG.txt" "$MODE" diff --git a/src/DataStore.cpp b/src/DataStore.cpp index 55b1395d..f39136d1 100644 --- a/src/DataStore.cpp +++ b/src/DataStore.cpp @@ -1,6 +1,7 @@ #include #include #include "DataStore.h" +#include // ADV_TYPE_NONE (blank-record skip in loadContacts) #if defined(ESP32) #include #include "helpers/esp32/WdtHeavyGuard.h" // suspend core-0 idle WDT during the (SPIFFS-GC-prone) contact write @@ -482,6 +483,12 @@ File file = openRead(_getContactsChannelsFS(), "/contacts3"); if (!success) break; // EOF + // Skip blank records. beta_60 saved the core's reserved anon slots (the + // save walked the raw table, which 1.17 had shifted), so an upgrade from + // it carries up to MAX_ANON_CONTACTS empty entries that would otherwise + // load as real, nameless contacts. The next save drops them for good. + if (c.type == ADV_TYPE_NONE || !c.name[0]) continue; + c.id = mesh::Identity(pub_key); if (!host->onContactLoaded(c)) full = true; } diff --git a/src/ui-touch/UITask.cpp b/src/ui-touch/UITask.cpp index 6f4ab2ca..d5f1cfcc 100644 --- a/src/ui-touch/UITask.cpp +++ b/src/ui-touch/UITask.cpp @@ -45880,6 +45880,13 @@ void UITask::refreshThreadsFromMesh() { _ui_threads[t].mesh_contact_idx = static_cast(i); memcpy(_ui_threads[t].mesh_contact_pub, c.id.pub_key, sizeof(_ui_threads[t].mesh_contact_pub)); memcpy(_ui_threads[t].mesh_contact_key6, c.id.pub_key, sizeof(_ui_threads[t].mesh_contact_key6)); + // Follow a peer's rename. The thread was matched by KEY above, but inbound + // messages are routed by findThreadByName(sender) — so leaving the old name + // here spawned a SECOND thread for the same peer the next time they wrote. + if (c.name[0] && strncmp(_ui_threads[t].name, c.name, MAX_THREAD_NAME) != 0) { + strlcpy(_ui_threads[t].name, c.name, sizeof(_ui_threads[t].name)); + _threads_dirty = true; + } } } #ifdef MAX_GROUP_CHANNELS