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... diff --git a/lib/services/meshcore/connection.dart b/lib/services/meshcore/connection.dart index 66bc30c..9e3a7ba 100644 --- a/lib/services/meshcore/connection.dart +++ b/lib/services/meshcore/connection.dart @@ -967,19 +967,14 @@ 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 { + /// 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; 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..2187e7d 100644 --- a/lib/services/ping_service.dart +++ b/lib/services/ping_service.dart @@ -554,10 +554,11 @@ 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) + // 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'); // Capture noise floor at ping time final noiseFloor = _connection.lastNoiseFloor; @@ -638,8 +639,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();