From 01cedc27d65918ab159dbfcf378eca795d230aa8 Mon Sep 17 00:00:00 2001 From: fauxreigner-mb Date: Mon, 6 Apr 2026 20:43:26 -0400 Subject: [PATCH 1/3] Ping message is now a 3-byte UID derived from a hash of the coordinates and timestamp. This removes the sender's location from the mesh message while preserving TxTracker echo correlation. Coordinates remain in the API payload only. --- lib/services/meshcore/connection.dart | 10 ++-------- lib/services/ping_service.dart | 12 ++++++------ 2 files changed, 8 insertions(+), 14 deletions(-) diff --git a/lib/services/meshcore/connection.dart b/lib/services/meshcore/connection.dart index 66bc30c..8389433 100644 --- a/lib/services/meshcore/connection.dart +++ b/lib/services/meshcore/connection.dart @@ -967,19 +967,13 @@ class MeshCoreConnection { } /// Send ping to #wardriving channel - /// Format: @[MapperBot] LAT, LON - /// Power is no longer included in the mesh message — it is sent per-ping in the API payload instead - /// Reference: buildPayload() in wardrive.js - Future sendPing(double lat, double lon) async { + /// Message is a 3-byte UID (6 hex chars) derived from coordinates + timestamp + Future sendPing(String message) async { final channel = _wardrivingChannel; if (channel == null) { throw Exception('Wardriving channel not initialized'); } - // Format coordinates to 5 decimal places with comma separator - final coordsStr = '${lat.toStringAsFixed(5)}, ${lon.toStringAsFixed(5)}'; - final message = '@[MapperBot] $coordsStr'; - debugLog('[CONN] Sending ping: $message'); final timestamp = DateTime.now().millisecondsSinceEpoch ~/ 1000; await sendChannelTextMessage(TxtTypes.plain, channel.channelIndex, timestamp, message); diff --git a/lib/services/ping_service.dart b/lib/services/ping_service.dart index 50bc46e..cabeb28 100644 --- a/lib/services/ping_service.dart +++ b/lib/services/ping_service.dart @@ -554,10 +554,10 @@ class PingService { } final txPowerDbm = _connection.deviceModel?.txPower ?? 22; - // Build ping message (same format used for TxTracker correlation) - // Power is no longer included in the mesh message — sent per-ping in API payload - final coordsStr = '${position.latitude.toStringAsFixed(5)}, ${position.longitude.toStringAsFixed(5)}'; - final pingMessage = '@[MapperBot] $coordsStr'; + // Build 3-byte ping UID from coordinates + timestamp (for TxTracker correlation) + final hash = '${position.latitude},${position.longitude},${DateTime.now().millisecondsSinceEpoch ~/ 1000}'.hashCode; + final pingMessage = (hash & 0xFFFFFF).toRadixString(16).padLeft(6, '0'); + debugLog('[PING] Generated UID: $pingMessage'); // Capture noise floor at ping time final noiseFloor = _connection.lastNoiseFloor; @@ -638,8 +638,8 @@ class PingService { // Play transmit sound immediately before sending _audioService?.playTransmitSound(); - // Send ping via BLE (coordinates only — power is in API payload) - await _connection.sendPing(position.latitude, position.longitude); + // Send ping via BLE (UID only — coordinates and power are in API payload) + await _connection.sendPing(pingMessage); // Mark ping time and position _lastTxTime = DateTime.now(); From eac8f71d12921d6ce99241ede67f8ac138f4042f Mon Sep 17 00:00:00 2001 From: fauxreigner-mb Date: Mon, 6 Apr 2026 21:04:36 -0400 Subject: [PATCH 2/3] Restore comments noting coordinates and power are sent in API payload --- lib/services/meshcore/connection.dart | 1 + lib/services/ping_service.dart | 1 + 2 files changed, 2 insertions(+) diff --git a/lib/services/meshcore/connection.dart b/lib/services/meshcore/connection.dart index 8389433..9e3a7ba 100644 --- a/lib/services/meshcore/connection.dart +++ b/lib/services/meshcore/connection.dart @@ -967,6 +967,7 @@ class MeshCoreConnection { } /// Send ping to #wardriving channel + /// Coordinates and power are no longer included in the mesh message — sent per-ping in API payload instead /// Message is a 3-byte UID (6 hex chars) derived from coordinates + timestamp Future sendPing(String message) async { final channel = _wardrivingChannel; diff --git a/lib/services/ping_service.dart b/lib/services/ping_service.dart index cabeb28..2187e7d 100644 --- a/lib/services/ping_service.dart +++ b/lib/services/ping_service.dart @@ -555,6 +555,7 @@ class PingService { final txPowerDbm = _connection.deviceModel?.txPower ?? 22; // Build 3-byte ping UID from coordinates + timestamp (for TxTracker correlation) + // Coordinates and power are no longer included in the mesh message — sent per-ping in API payload final hash = '${position.latitude},${position.longitude},${DateTime.now().millisecondsSinceEpoch ~/ 1000}'.hashCode; final pingMessage = (hash & 0xFFFFFF).toRadixString(16).padLeft(6, '0'); debugLog('[PING] Generated UID: $pingMessage'); From d75febc5c77c8b8baec2eeeca32491777f449fde Mon Sep 17 00:00:00 2001 From: fauxreigner-mb Date: Mon, 6 Apr 2026 22:14:15 -0400 Subject: [PATCH 3/3] Update DEVELOPMENT.md to reflect UID-based ping message --- DEVELOPMENT.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/DEVELOPMENT.md b/DEVELOPMENT.md index b7b1ad2..6332de6 100644 --- a/DEVELOPMENT.md +++ b/DEVELOPMENT.md @@ -146,7 +146,7 @@ Discovery pings use the MeshCore control data protocol to directly query nearby Three auto-ping modes are available after connecting: -- **Active Mode**: Sends TX pings at user-configured interval (15s, 30s, or 60s). Each ping broadcasts a group channel message containing GPS location and radio power to `#wardriving`, then listens 7s for repeater echoes via `TxTracker`. +- **Active Mode**: Sends TX pings at user-configured interval (15s, 30s, or 60s). Each ping broadcasts a 3-byte UID (derived from coordinates + timestamp) to `#wardriving`, then listens 7s for repeater echoes via `TxTracker`. Coordinates and power are sent in the API payload only. - **Passive Mode**: Sends discovery requests every 30s. No TX pings — only discovery request-response. Responses tracked via `DiscTracker`. - **Hybrid Mode**: Alternates between discovery and TX pings at the user-configured interval. Discovery → TX → Discovery → TX...