Releases: MeshMapper/MeshMapper_Project
MeshMapper App v1.3.0
This is a major release, it has been in beta since April. The map engine has been fully rewritten and a ton of new features and fixes are packed in. Please report any issues you run into.
✨New Features
- Map Engine Migration: Replaced flutter_map (raster tiles) with maplibre_gl (vector tiles via OpenFreeMap). Liberty is the new default map layer, check it out, it's quite nice!
- Offline Maps & Tile Caching: New "Offline Maps" screen in Settings lets you download map regions for offline wardriving. Multiple downloads can be queued and run back-to-back. Tiles are cached automatically between sessions. Thanks @dedskelly for all the work writing the code for this feature!
- TCP, USB Serial: MeshMapper now supports connecting to your device over TCP (Wi-Fi/LAN), USB Serial (Android via OTG, based on MeshCore-Open). Connect screen now has tabs for each transport.
- Broadcast My Coords Toggle: Off by default. The app uses a wiretag on the mesh for privacy instead of broadcasting GPS coordinates.
- Anonymous Mode UX: Enabling anonymous mode now shows a progress popup instead of switching to the Connect tab.
- Multi-Hop TX Echo Grouping: Multi-hop TX echoes (2+ hops) are now grouped under their parent TX ping instead of appearing as anonymous RX observations. TX markers use three outcome states: green (direct echo), RX-colored (multi-hop only), red (no response).
- RX Hop Path: Tapping an RX marker now shows the full mesh path the packet travelled as a tappable chain of repeater chips. The same chain renders on every RX entry in the Log tab. CSV export gains a
path_hopscolumn. - Session History Tab: The "Graph" tab has been renamed to "History." View past sessions on the map with ping markers and camera fit-to-bounds, or open the Noise Floor graph. Tapping history markers opens the same detail sheets as live sessions.
- Repeater Marker Clustering & Spiderfy: Stacked repeater markers now collapse into a cluster bubble with a count. Tapping a cluster at max zoom fans the members out in a ring with leader lines, each independently tappable.
- Tap Repeaters & Tiles on Map: You can now tap repeaters and coverage tiles on the map to see details, just like the web UI. This is the beginning of more features being moved to the app.
- Grid Mode Tap Details: In Detailed grid mode, tapping a cell now shows pings from the full 3x3 blob and outlines that block on the map, matching the web UI. Simplified mode focuses the single tapped cell.
- Unified Focus Mode: Focus mode is now shared across ping markers, repeaters, and tile taps. All use a common themed minimized detail bar that can be expanded for more detail. The bottom sheet can be minimized to freely explore the map.
- Flood Traffic Toggle in Settings → Modes (default OFF). When OFF, Send Ping, Active, and Hybrid controls are hidden. Passive and Trace stay visible. Auto-syncs with regional admin flood policy on connect and zone change.
- Zone Transfer Auto-Registration: Crossing into a new zone no longer drops your session if the server hasn't seen your device before. The app auto-registers silently so wardriving resumes without a reconnect.
- Stale Repeater Filtering: Repeaters not heard within the region's stale threshold are hidden from the map. The repeater picker and Log tab still show everything.
- Duplicate Repeater ID Indicator: Ambiguous repeater IDs now show amber "DUPLICATE ID" lines on the map and amber (i) icons in the log tab. Tap the warning to see all possible matches with names, distances, and status.
- Radio Settings Capture: The app now captures radio settings from your device and publishes them to the backend, enabling data filtering by radio preset.
- Offline Session Download: Offline sessions can be downloaded on mobile through the system share sheet.
- Landscape Minimize Button: Landscape control panel now has a minimize button with a compact collapsed bar.
🔄 Offline Uploads Reworked
- Multi-region drives just work. Your trip can cross as many region borders as you like and the whole thing uploads in one go, with no more session errors partway through and no more manual retries.
- Every ping lands where it was actually recorded. Each ping is individually placed into the correct region's map, so a Sheffield to Nottingham drive shows Sheffield coverage in Sheffield and Nottingham coverage in Nottingham.
- You can see where your upload went. After a successful upload, the session in your list shows a summary like "Uploaded · DSA 88 · EMA 157", and you can tap it for the full per-region breakdown.
- Pings far outside any region are handled gracefully. A stray ping more than 50 km outside every mapped region is reported back as "too far" rather than being dumped into the nearest region or silently lost.
- Uploading from anywhere works. Even if you are outside all coverage when you hit upload, the session is created and your data is placed correctly by location.
- Your uploaded sessions stick around. Nothing is auto-deleted, and download stays available after upload.
🔧 Improvements
- Auto-Follow Zoom: Tap follow and the map zooms to street level once; after that it just pans. Pinch-zooming while following now sticks instead of fighting you.
- Ping Button Responsiveness: Send Ping and auto-mode buttons now respond instantly on tap instead of occasionally needing multiple taps. Reduced unnecessary UI rebuilds for snappier controls during wardriving.
🐛 Bug Fixes
- Phone Heat & Battery Drain: The coverage overlay refresh was running dual GPU layers on every cycle. Replaced with a lightweight refresh that eliminates the overhead.
- (iOS) Launch & Resume Crashes: Fixed multiple crashes caused by MapLibre firing camera animations before the GL surface was ready on cold start and resume from background.
- (Android) Background Resume Crash: Fixed the same MapLibre GL surface crash on Android. Also fixed
flutter_local_notificationsTypeToken errors on startup. - (iOS) BLE Reconnect: Fixed reconnect taking 4+ minutes with stale bond keys, now under 10 seconds.
- (iOS) TCP Background: TCP connections now auto-reconnect on resume since iOS doesn't preserve TCP sockets in the background.
- (Android) TCP Background: Added foreground service permission and
tcpNoDelayto prevent TCP drops when backgrounded. - Anonymous Mode: Fixed Anonymous mode getting permanently stuck after an unexpected Bluetooth disconnect. Your real name is now persisted and automatically restored.
- TX Pings Silently Dropped: Fixed TX pings being dropped when driving a new area or on a later day, leaving DEAD tiles. Only beta users were impacted.
- Fixed focus mode jumping to (0, 0) off the coast of Africa when heard repeaters have no published location.
- Fixed map label flicker at max zoom during follow mode.
- Fixed GPS marker drifting toward the top of the map in heading mode.
- Fixed spider fan-out pulling in markers from neighbouring clusters and rendering at 2x intended radius.
- Fixed offline map cancel during setup orphaning the native download.
- Fixed being unable to switch from offline back to online mode while connected.
- Fixed auto-ping permanently stopping on zone transfers, reconnects, and grace period re-entry. Multiple related fixes for mode validation, setting persistence, and cooldown timer conflicts across zone boundaries.
- Fixed path hash mode not reconfiguring correctly when moving between enforced and non-enforced zones.
- Fixed zone admin overrides persisting after moving to a less restrictive zone.
- Fixed Connect screen always defaulting to BLE instead of remembering last used transport.
- Fixed misleading "No empty channel slots" error when BLE disconnects during connection.
- Fixed generic "Timestamp is too old" registration failure now diagnosing a device clock stuck in the future with actionable instructions to power-cycle.
- Fixed Hive preferences being wiped by transient open failures on startup.
- Settings now flush to disk immediately after every write, preventing loss on crash.
- Fixed RX ping popup showing wrong header badge colour.
- Fixed performance freeze when entering focus mode.
- Fixed coverage overlay disappearing after background/foreground transitions.
- Corrected multi-byte path-mode warning text.
- Fixed failed discovery markers being untappable in drop mode.
MeshMapper App v1.3.0(1782214423)
Bug Fixes
- Attempting to fix GPS icon flicker regression
MeshMapper App v1.3.0(1782016879)
New Features
- Focus mode is now shared across ping markers, repeaters, and tile taps with a common minimized detail bar that expands for more detail
Improvements
- Reworked offline sessions
Bug Fixes
- Fixed a render bug
- Another attempt at fixing the iOS boot crash caused by MapLibre
- Another attempt at fixing repeater marker order
MeshMapper App v1.3.0(1781957897)
✨New Features
- Landscape Minimize Button: Added a minimize button to the landscape control panel. The collapsed state shows a compact bar centered along the bottom of the map.
- Repeater Coverage Overlay & Tile Tap: Added repeater coverage overlay and tile tap inspect to the repeater line drawing view. Both of these bring more functionality from the web UI into the app.
🐛 Bug Fixes
- Offline Uploads: Finally I think I fixed offline uploads.
- (iOS) App Open Crash: Pretty sure I fixed the iOS crashes on app open. Let me know if you're still seeing it.
- App Crash on Launch/Resume: Fixed crash caused by invalid map coordinates being passed to MapLibre on launch and resume from background.
MeshMapper App v1.3.0(1781864859)
✨New Features
- Grid Mode Tap Details: In Detailed grid mode, tapping a cell now shows pings from the full 3x3 blob that colours it and outlines that block on the map. Simplified mode focuses the single tapped cell. This now matches the web UI behaviour.
- Offline Session Download: Offline sessions can now be downloaded on mobile through the system share sheet (Save to Files, Drive, email, etc.), available before upload and for sessions that failed to upload.
🐛 Bug Fixes
- Offline Upload Fix: Fixed offline sessions failing to upload. The app now waits for server acceptance before sending, and never discards pings it couldn't upload. Failed pings are kept and retried instead of being lost as a "partial upload."
- Map style and colour-vision (CVD) palette changes now apply immediately instead of requiring a map reload.
- Smoother ping and marker display in long sessions. Coverage markers now update only when they actually change, so display lag no longer grows the longer a session runs.
- Corrected the multi-byte path-mode warning: it now says the app restores your original radio setting on a normal disconnect (only an unclean disconnect requires a manual revert in Settings).
🔄 Changed
- With "Broadcast My Coordinates" enabled, TX pings now send the keyed wire-tag and your plaintext coordinates on-air. The API still receives only the tag, so coverage uploads and TX validation are unchanged. The session-limit guard now applies in both privacy and broadcast modes.
MeshMapper App v1.3.0(1781753278)
ℹ️ Note: Heat and battery drain should be fixed in this build. Please report back with your experience.
Note: I expect some bugs / UI bugs with the new Tap Repeaters & Tile on map.
✨New Features
Radio Settings Capture: The app now captures radio settings from your device and publishes them to the backend, enabling filtering of wardrive data by radio preset.
Broadcast My Coords Toggle: New toggle, off by default. Instead of broadcasting your GPS coordinates on the mesh, the app now uses a wiretag when sending TX/Channel messages to #wardrive for privacy.
Tap Repeaters & Tiles on Map: You can now tap repeaters and coverage tiles on the map to see details about them, just like in the web UI. This is the beginning of more features being moved to the app to bring closer unity between the two.
MeshMapper - v1.3.0(1779073780)
🧪 Added TCP and USB support (Experimental)
ℹ️ Note: The coverage overlay flicker is still present. The dual-layer approach I originally built to hide it I think was the source of phones getting hot and battery draining more than normal (see fix below), so it's been removed. Tom and I are discussing a complete rework of the overlay architecture that will allow single-tile refreshes instead of reloading the entire overlay each time, and should unlock a ton of new features. More on this later.
✨New Features
- TCP, USB Serial & Web Serial Support: MeshMapper now supports connecting to your device over TCP (Wi-Fi/LAN), USB Serial (Android via OTG, based on MeshCore-Open), and Web Serial (Chrome/Edge) alongside Bluetooth. The Connect screen now has tabs for each transport, with platform-appropriate options shown per device.
- Saved connections and reconnect support extended to TCP and USB Serial, so your preferred connection method is remembered.
- Focus Mode Sheet Minimize: While in focus mode, you can now minimize the bottom sheet to look around the map and zoom in/out to check out individual repeater locations.
- Duplicate Repeater ID in Log Tab: The amber "duplicate ID" indicator now appears on every ping card in the log tab when a repeater ID matches multiple physical nodes, no longer restricted to name-search mode only. The (i) icon on each repeater row turns amber for the specific repeater(s) with ambiguous IDs, so you can see at a glance which node in the table is the duplicate.
- Session History Tab: The "Graph" tab has been renamed to "History." Each recorded session now shows two options: View on Map (replays ping markers with camera fit-to-bounds) and Noise Floor (the existing interactive graph). Tapping any history marker opens the same detail sheet as a live session. Live markers and controls are hidden during playback for a clean view. Sessions with no GPS-tagged events have "View on Map" greyed out, and in-progress sessions only offer the Noise Floor graph.
🔧 Improvements
- Coverage Overlay Debounce: Tile refresh debounce increased from 5s to 30s. During active wardriving with 15-second ping intervals, this prevents excessive tile reloads on intermittent networks and reduces visual churn on the map.
🐛 Bug Fixes
- Phone Heat & Battery Drain: The coverage overlay refresh was creating and destroying MapLibre layers many times per session, with each cycle running two raster layers simultaneously for 3 seconds. Replaced with a lightweight remove-then-add cycle that eliminates the dual-layer GPU overhead. This should help battery life significantly during long sessions — testing is needed. Also fixed the overlay disappearing mid-session after background/foreground transitions.
- (iOS) Reconnect After BLE Disconnect: Fixed reconnect taking 4+ minutes when iOS encounters stale bond keys. The error now propagates immediately to the auto-reconnect system, cutting reconnect delay to under 10 seconds.
- Auto-Ping Grace Period: Fixed auto-ping timers not actually stopping during zone grace period, causing a desync where re-enabling auto-ping silently failed.
- Cross-Zone Auto-Ping Restore: Fixed auto-ping mode not being restored after transferring to a different zone during grace period. The saved mode was being cleared before the transfer could read it.
- Path Hash Mode on Zone Change: Fixed path hash mode not being reconfigured correctly when moving from an enforced zone to a non-enforced zone whose firmware default matched the previous setting.
- Zone Transition Mode Mismatch: Fixed auto-ping mode not being validated against the new zone's permissions on transfer and grace re-entry. The restored mode is now checked against
tx_allowed/rx_allowed/enforceHybridflags before being applied. - Restrictive Zone Settings Persist: Fixed zone admin overrides (flood, path hash, etc.) sticking after transferring to a less restrictive zone. User preferences are now snapshotted on initial connect and restored before applying the new zone's policies.
- TCP Drops in Background (Android): Added
FOREGROUND_SERVICE_DATA_SYNCpermission and enabledtcpNoDelayto prevent TCP connections from dropping when the app is backgrounded. - Connection Screen Default: Fixed the Connect screen always defaulting to BLE instead of remembering your last used transport.
- (iOS) TCP Background Disconnect: Fixed TCP connections silently dying when the app is backgrounded. The app now probes the connection on resume and auto-reconnects if the socket is stale, restoring auto-ping mode automatically.
- Legacy Offline Sessions: Fixed legacy offline sessions being permanently un-uploadable. Sessions created before device credentials were stored now fall back to the currently-connected device's credentials for authentication, preventing data loss.
- Stuck Device Clock: Fixed registration failure showing generic "Timestamp is too old" when the device's RTC clock is stuck in the future (e.g. Heltec V4 with a corrupted external RTC reading year 2096). The firmware refuses to set the clock backwards, so retrying will always fail. The app now queries the device's RTC and shows an actionable message with the incorrect date and instructions to power-cycle the device.
MeshMapper - v1.3.0(1778348910)
ℹ️ Note: The coverage overlay tile flicker is still present in this build. CSP-Tom and I are discussing a new approach to how overlay tiles are added that should reduce battery usage and unlock new functionality. No ETA on this yet.
ℹ️ Note: I am working on TCP and USB support and need active testers for these features. Please react to this message if you would like to participate.
🔧 Improvements
- Auto-Follow Zoom: Tap follow and the map zooms to street level once; after that it just pans. Pinch-zooming while following now sticks instead of fighting you on every tick.
- Duplicate Repeater ID Indicator: When a short repeater ID matches multiple repeaters, focus mode now draws amber "DUPLICATE ID" lines to all candidates. Tap the amber warning in the bottom sheet to see all possible matches with names, distances, and status.
- Per-Region Stale Threshold: Stale repeater cutoff is now read from the server per-region to match the web client.
- Battery & Performance: Countdown timers, noise floor, and battery streams no longer trigger unnecessary full UI rebuilds, significantly reducing CPU and battery usage during long sessions.
- Anonymous Mode UX: Enabling anonymous mode now shows a popup with progress instead of switching to the Connect tab to show the reconnection flow.
🐛 Bug Fixes
- (iOS) Fixed a crash on app launch and resume from background caused by MapLibre firing camera animations before the GL surface was ready.
- (Android) Fixed a crash when returning to the app after extended background time. Same root cause as the iOS fix — MapLibre's GL surface can be temporarily invalid on resume. Map interactions now wait one frame after resume. Also fixed
flutter_local_notificationsTypeToken errors on every startup. - Anonymous Mode Fix: Fixed a bug where Anonymous mode could become permanently stuck after an unexpected Bluetooth disconnect. The device's real name is now persisted before the anonymous rename and automatically restored on the next connection when Anonymous mode is off. If you've been affected by this, your name will be restored on your next connect.
- Focus mode no longer jumps to (0, 0) when heard repeaters have no published location. Unlocated repeaters now show a location-off icon in the detail sheet.
- Map label flicker at max zoom during follow mode fixed.
- Offline map cancel during setup no longer orphans the native download.
- Offline Mode Toggle Fix: Fixed being unable to switch from offline back to online mode while connected. The zone status check was skipped because the offline flag hadn't been cleared yet, creating a catch-22. The flag is now cleared before the zone check and restored if the switch fails.
- Offline Upload Fix: Offline sessions that got stuck at "partial upload" now work reliably. The app waits for server propagation and retries with backoff if the first attempt is rejected. Invalid data is discarded instead of blocking the entire session, and successfully-uploaded pings are removed so retrying picks up where it left off.
- Stale threshold now applies immediately on zone transfers instead of waiting up to 60s.
- Spider fan-out rings no longer render at 2x intended radius.
- DISC Tap Fix: Failed discovery markers in drop mode are now tappable again. Rendering them with the TX-fail icon was overwriting their tap metadata.
- BLE Disconnect Error Message: Fixed misleading "No empty channel slots" error when BLE disconnects during connection. The error now accurately tells the user to try connecting again.
- Fixed a timer dispose leak on teardown.
- Code cleanup: removed duplicate parsing and unused constants.
MeshMapper - v1.3.0(1777429509)
🐛 Bug Fixes
- Focus Mode No-Location Filter: Repeaters with no published location no longer drag focus mode to (0, 0) off the coast of Africa. If all heard repeaters are unlocated, focus mode skips entirely. Unlocated repeaters now show a location-off icon in the detail sheet.
- Coverage Overlay Flicker: Fixed the overlay flashing every ~10 seconds during long wardriving sessions. Tile refreshes are now double-buffered so new data appears without flicker.
MeshMapper - v1.3.0(1777345110)
✨New Features
- RX Hop Path: Tapping an RX marker now shows the full mesh path the packet travelled (origin → ... → us) as a tappable chain of repeater chips, with the receiving repeater tagged "(heard)". Each hop chip opens the standard repeater info popup so you can resolve names and distances along the path without leaving the sheet. The same chain renders on every RX entry in the Log tab. If your own carpeater was on the tail, it's stripped from the chain just like it's stripped from the displayed last-hop ID. CSV export gains a
path_hopscolumn on RX rows. Path data is transient and lost on app restart, matching how TX heard-repeater data already works. - Stale Repeater Filtering: Repeaters not heard in the past 30 days are now hidden from the map. They don't render as markers, don't contribute to cluster bubble counts, and don't get pulled into spider expansions. The repeater picker (trace mode) and Log tab still list every repeater the server returns, so nothing is lost from the data view, it's a map-only declutter.
- Zone Transfer Auto-Registration: Crossing into a new zone no longer drops your session if the server hasn't seen your device's public key in that region. When zone-transfer auth comes back with
unknown_device, MeshMapper now automatically requests a signed contact URI from the radio and re-submits as a register call, the same two-stage flow used during initial connect, so the transfer completes silently and wardriving resumes without a reconnect. Other auth failure reasons (GPS, capacity, etc.) still end the session as before.
🐛 Bug Fixes
- Fixed a spiderfy bug where tapping a cluster bubble at max zoom could fan out markers from neighbouring clusters too. The spider group was computed via BFS through every repeater within ~42m of any chained neighbour, which doesn't match how MapLibre/Supercluster decides cluster membership. Cluster taps now read
point_countdirectly from MapLibre and spread exactly that many of the nearest repeaters around the tap, so the fan always matches the count shown on the bubble.