Skip to content

Meck-P4 v0.3.5: Direct Messaging, Repeater Admin, Room servers & Maps

Pre-release
Pre-release

Choose a tag to compare

@pelgraine pelgraine released this 21 May 09:56
· 69 commits to main since this release

Direct messaging arrives in v0.3.5 — compose, send, receive, and persist DMs from any companion contact, with unread badges viewable in the channel list. Room server support and repeater admin land alongside, giving you logged-in access to room post history and the full status/CLI/settings interface for remote repeater management. A new map screen renders OSM slippy tiles from the SD card with a GPS dot, contact markers, and pan/zoom. Plus a per-contact path editor, a standalone trace route screen, a keyboard layout overhaul, a GPS time-sync fix, debug logs to SD, and config export to a MeshCore-app-compatible JSON file.

⚠️ Still a pre-release. ⚠️ Web browser, IRC, and the BLE/WiFi companion path are still not in this build. See What's Not Yet Implemented for the full pending list.

First-Time Flashing: Read This First

Meck-P4 ships as a single merged binary (bootloader + partition table + application combined). One file, flash at offset 0x0.

An SD card is recommended. With a FAT32-formatted card inserted, every saved setting, channel message, DM, and room post is mirrored automatically, audio files have somewhere to live, and the device recovers gracefully from a wiped NVS. Without an SD card the device still works but loses message history on reboot.

Ensure you use the right-side USB-C port (the data port), not the high-speed charger port, to flash.
correct port usage for flashing

Flashing with the MeshCore Web Flasher (recommended)

  1. Go to https://flasher.meshcore.io/
  2. Scroll to the bottom and select Custom Firmware
  3. Select the meck-p4-0.3.5-version-merged.bin file you downloaded
  4. Click OK on the merged-binary warning
  5. Click Flash, pick your device in the popup, and click Connect

Flashing with esptool.py

pip install esptool
esptool.py --chip esp32p4 -p PORT write_flash 0x0 meck-p4-0.3.5-version-merged.bin

(Replace PORT with /dev/cu.usbmodemXXXX on macOS, /dev/ttyACM0 on Linux, or COM3 on Windows.)

Upgrading from v0.3.3 does not require erase_flash. The prefs loader continues to tolerate older shorter-blob layouts, so any new fields come up at default rather than wiping existing settings.

⚠️ AMOLED variant remains untested by the maintainer. The -amoled.bin is built from the same source tree with the AMOLED display option selected in menuconfig, but the project maintainer doesn't have the AMOLED hardware on hand. The TFT variant is the tested and known-working build.

What's New Since v0.3.3

Direct Messaging

Open a companion contact's detail screen (from the Contacts menu tile on the home screen) and tap the cyan Send DM button (stacked above the red Delete button) to compose. The DM conversation view uses the standard chat layout — keyboard on the bottom half, message bubbles scrolling above.

  • Per-contact 20-message ring buffers in PSRAM, lazy-allocated so unused contacts cost nothing
  • Per-contact DM history persisted to SD and reloaded on boot
  • DM Inbox row in the channel picker shows a per-contact unread badge, refreshed every tick
  • Send-side ACK tracking — outgoing bubbles update from "Sending..." through to "Delivered" or "Failed" as the ACK round-trip completes

Room Server Support

Tap a Room-type contact to open the same admin login flow as repeaters. On successful login, the room's post timeline appears as a scrollable bubble list, left-aligned, with the author name above each bubble and a timestamp and hop count footer below.

  • Post history persisted per-room to SD and loaded on boot, so you don't need to re-login to see what's already been received
  • Live re-render: posts arriving while you're sitting on the room view land in the bubble list without leaving the screen
  • Author resolution walks your contacts looking for a matching 4-byte pubkey prefix; unknown authors render as Unknown <hex>
  • Composer for posting back to the room is included

Repeater Admin

Tap a Repeater contact to open contact detail. A cyan Admin button opens the login screen.

The login screen shows the contact name in the title bar, a password field with reveal-while-typing (the last char shows for 1.5s before being masked — easier than blind-typing symbols and numbers), a full Show/Hide toggle, a Remember Password checkbox, and a routing-mode badge showing Flood vs Direct (picked from the contact's out_path_len at entry).

After login, the admin home shows a persistent banner across the top — green for admin, yellow for guest — with the contact name and session role. Below it, a scrollable menu:

Item What it does
Status Full RepeaterStats view: battery, clock-at-login, uptime, TX/RX airtime, last RSSI/SNR, noise floor, packet counts, duplicates, errors, queue length, debug flags. Refresh button. "Updated N s ago" line goes yellow during refresh, green when populated, red on send failure.
Send Advert Single big button. Yellow status during in-flight, green on success with the repeater's response text, red on send failure.
Cmd Line Free-form 100-char text input + Send button. Virtual keyboard slides up on focus. Scrollback shows command in cyan, response in white (or red on failure). Trimmed at 50 entries.
Settings Scrollable menu list of setting categories — Position, Sync Clock, Admin Password, Guest Password, Change Identity Key, Manage Regions, Neighbours, Repeat Settings. Guest sessions see only Neighbours.

Single-session policy is enforced: logging into a new repeater tears down the prior session. Remember Password persists the entered password for that contact, so subsequent visits skip the prompt (until the device is rebooted).

Map Screen

IMG_3025-EDIT

A new map screen renders OSM "slippy map" PNG tiles from /sdcard/tiles/{z}/{x}/{y}.png via LVGL's image widget plus LV_USE_LODEPNG. Pan and zoom by touch. A GPS dot follows your fix when GPS is enabled; markers overlay contact positions filtered by type (repeaters by default), with a filter modal for other types.

You'll need to provide your own map tiles. See the README's Maps section for download sources and how to copy them to the SD card.

Config Export to SD

A new Export Config entry in Settings opens a modal letting you tick which sections to include (Identity, Channels, Contacts, Radio) and writes a MeshCore-app-compatible JSON file to /sdcard/meshcore/export-<unix_epoch>.json. The file format matches what the MeshCore mobile and desktop apps emit and what the v0.3.3 importer reads back in, so a Meck-exported file is portable to another Meck device or into the MeshCore apps directly.

Identity is optional — exporting with it included produces a re-importable backup of your node; exporting without it produces a portable contacts/channels/radio bundle you can share without handing over your private key.

Screen-Off Power Saving

The Auto Off timer (Never / 1 / 2 / 5 / 10 / 30 min) now tears down the MIPI-DSI bus when it fires, dropping CPU usage from ~94% CPU_MAX to ~57% CPU_MAX and trimming idle current accordingly. The screen wakes via the boot button, not by touch — touch wake via the XL9535 INT line on GPIO 5 is planned for a later release.

This is not light sleep. The PM config sets light_sleep_enable=true, but light_sleep_counts stays at 8 after the screen-off transition — some PM lock is still preventing light sleep from actually engaging. The visible power saving comes from the dynamic frequency scaling running more aggressively when the screen-on workload disappears.

The change should give approximately an hour to an hour and a half of additional run time with low to moderate usage at 35% brightness. Power saving investigation continues; see Known Limitations.

Debug Logs to SD

Settings → Debug Logs → Start redirects printf output to a per-session log file on the SD card under a recursive FreeRTOS mutex. Useful when serial monitor isn't practical — leave the device running with logging on, retrieve the SD card afterwards. Tap Stop in the Debug Logs menu to revert to UART logging.

Per-Contact Path Editor and Trace Path

Two new utilities for diagnosing and fixing route problems.

Per-Contact Path Editor. A teal Edit Path button on the contact detail screen opens a screen with a Path Size dropdown (1-byte / 2-byte), a comma-separated hex-hops text field, a Save button, and a Reset to Flood button. Saving with an empty path records the contact as a 0-hop direct path; Reset to Flood clears the stored path so the next send floods.

Trace Path. A separate screen reachable from the home screen with the same hex-hops input and Path Size dropdown. Run Trace sends a TRACE packet down the entered path; the result list below shows the per-hop SNR as 3-bar icons, with a 30-second pending timeout.

Audio File Format Requirements

A reminder of the audio player's format compatibility window, now clearly documented in the audio player guide:

  • MP3 files must be at 44.1 kHz sample rate. Tracks at 48 kHz (the typical Bandcamp / DAW-export rate) won't play. Convert with ffmpeg -i input.mp3 -ar 44100 output.mp3.
  • WAV files must be 16-bit PCM (format code 0x0001) at 44.1 kHz, mono or stereo. Files in WAVE_FORMAT_EXTENSIBLE (0xFFFE) — common from DAWs at 24-bit/32-bit/multichannel — fail the format check. Convert with ffmpeg -i input.wav -acodec pcm_s16le -ar 44100 output.wav.
  • Cover art displays when placed as a 256x256 cover.png in the album folder. Larger PNGs are read by the file scanner but fail to allocate at decode time.

See the audio player guide for full conversion examples, ffprobe checks, and SD card layout details.

Keyboard Layout Overhaul

The alpha layouts (QWERTY / AZERTY / QWERTZ, lowercase + uppercase) have been re-arranged:

  • Backspace moved to the right end of row 2, doubled in width
  • Row 3 now reads , + 7 letters + . + ↵
  • Row 4 reads [<] [-] [ABC] [space] [1#] [>] — arrows on the far ends, 1# next to the spacebar
  • Unused keyboard-icon and ✓ keys removed
  • The symbol/numbers layout is unchanged

Cursor styling on the trace and path-editor textareas now matches the channel/DM compose textarea (a 2-pixel white left border instead of the default black bar that was invisible against the dark background).

GPS Time Sync Fix

Important bug fix. Prior to v0.3.5, two separate RTCs ran in parallel — a soft RTC (meck::rtc) that GPS updated and the GPS tile displayed, and a P4RTCClock (g_rtc) that the top-bar clock and every MeshCore-internal timestamp read. The latter only ever held compileTimeEpoch() because GPS never wrote to it. The top-bar clock therefore stayed at build time even after a perfect GPS fix.

v0.3.5 routes meck_clock_set_utc(epoch) to both RTCs, so a single GPS fix now updates the top bar, the message bubble timestamps, and everything else that reads from Meck::getRTCClock().

Other Changes

  • Build epoch sentinel. MECK_BUILD_EPOCH now re-bakes on every build via a sentinel file touched in an ALL custom target, registered as a CMAKE_CONFIGURE_DEPENDS. Previously the macro froze at the last idf.py reconfigure value, so a fresh-flashed device could boot with an out-of-date clock that the mesh's "first sync wins" logic would lock in.
  • Two new font sizes (meck_montserrat_30, meck_montserrat_32) added for the new screens.
  • Audio Player Guide rewritten to cover the format requirements above plus new troubleshooting entries for "unknown file type" WAV errors and non-44.1 kHz MP3s.

Known Limitations

  • Background audio playback has known issues — not recommended for general use yet. A blue >> glyph was added to the top bar to indicate when the audio player is actively playing, mirrored across every home tile and full screen. However, the broader background-playback experience has a number of unresolved bugs: tapping the Audio tile while a track is playing doesn't jump back to the Now Playing screen (so pausing requires navigating back to the file manually), and starting a second track while the first is playing leaves the second track's play button stuck in the "play" state so it can't be paused from its row. Targeted for finalisation in v0.3.6. In the meantime, use the audio player as a foreground feature — leave it open on the Now Playing screen while a track is in progress.
  • GPS cold-boot acquisition is slow. First cold start takes around 12 minutes outdoors with clear sky; subsequent fixes after a reboot can take longer than expected even when the chip should have prior almanac data, suggesting EASY (predicted ephemeris) may not be persisting across reboots as intended. Investigation and fix targeted for v0.3.6.
  • Light sleep itself isn't engaging. The screen-off path releases the dsi_phy NO_LIGHT_SLEEP PM lock, but light_sleep_counts remains at 8 after transition. Other PM locks (likely from I2S, USB-CDC, SDMMC, or BLE controller drivers) are still preventing automatic light sleep entry. CPU dropping out of 360 MHz mode is what's providing the visible power saving in this release.
  • Touch wake from screen-off is not supported. Use the boot button to wake. XL9535 INT line wake is on the v0.3.6 list.
  • Cover art larger than 256x256 still doesn't display. Carry-over from v0.3.3. Use a 256x256 cover.png in each album folder.
  • AMOLED variant has not been flashed or tested by the maintainer. Reports welcome via Discord or GitHub Issues.

What's Not Yet Implemented

Carried over from v0.3.3, with completed items removed:

  • Private channel creation (no UI to generate new channel secrets or add shared ones; approach undecided)
  • Notes app
  • Audio cover-art rendering at >256x256 (pre-flight succeeds but heap allocation for the decoded framebuffer fails for larger sizes; needs decode-time downscale or a streaming decoder)
  • Emoji support (real Unicode codepoints with Twemoji-style colour font fallback in LVGL, plus an emoji picker accessible from the keyboard's symbols page; current builds strip non-ASCII from displayed names instead)
  • Web browser & IRC client
  • ESP32-C6 BLE companion firmware (the C6 is on the board but Meck-P4 doesn't drive it yet)
  • PCF8563 hardware RTC integration (init only, not yet read on boot or written on shutdown)
  • Light sleep actually engaging (see Known Limitations)
  • Touch wake from screen-off (see Known Limitations)
  • OTA firmware updates over WiFi via the C6
  • Region scope (MeshCore v1.15+ compatibility)

PRs welcome. See the full roadmap in the README.

Reporting Issues

The Meck-P4 channel on the MeshCore Discord is the fastest path. GitHub Issues on the Meck-P4 repo also work for anything reproducible. Include the serial log if you can — Settings → Debug Logs → Start (new in v0.3.5) captures it to SD if serial monitor isn't practical.

License

MIT for Meck-specific code. The combined firmware binary links libraries with mixed licensing including GPL-3.0 and is effectively GPL-3.0 when distributed.