Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion DEVELOPMENT.md
Original file line number Diff line number Diff line change
Expand Up @@ -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...

Expand Down
11 changes: 3 additions & 8 deletions lib/services/meshcore/connection.dart
Original file line number Diff line number Diff line change
Expand Up @@ -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<void> 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<void> 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);
Expand Down
13 changes: 7 additions & 6 deletions lib/services/ping_service.dart
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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();
Expand Down