@@ -26,6 +26,10 @@ class TxTracker {
2626 /// Parameters: (repeaterId, snr, rssi, isNew) - isNew is true for first time seeing this repeater
2727 void Function (String repeaterId, double snr, int rssi, bool isNew)? onEchoReceived;
2828
29+ /// Callback for carpeater drops (for quiet error logging)
30+ /// Called with repeater ID and reason when an echo is dropped due to carpeater detection
31+ void Function (String repeaterId, String reason)? onCarpeaterDrop;
32+
2933 /// Start tracking echoes for a sent ping
3034 ///
3135 /// @param payload - The message text sent (for content verification)
@@ -94,10 +98,23 @@ class TxTracker {
9498 }
9599 debugLog ('[TX LOG] Header validation passed: 0x${metadata .header .toRadixString (16 ).padLeft (2 , '0' )}' );
96100
97- // VALIDATION STEP 1.5: Check RSSI (carpeater failsafe)
101+ // VALIDATION STEP 1.5: Path length check (must have hops to identify repeater)
102+ // Moved before RSSI check so we can log the repeater ID on carpeater drops
103+ if (metadata.pathLength == 0 ) {
104+ debugLog ('[TX LOG] Ignoring: no path (direct transmission, not a repeater echo)' );
105+ return false ;
106+ }
107+
108+ // Extract first hop (first repeater) for use in validation and logging
109+ final firstHopId = metadata.firstHop! ;
110+ final pathHex = firstHopId.toRadixString (16 ).padLeft (2 , '0' );
111+
112+ // VALIDATION STEP 2: Check RSSI (carpeater failsafe)
98113 if (PacketValidator .isCarpeater (metadata.rssi)) {
99114 debugLog ('[TX LOG] ❌ DROPPED: RSSI too strong (${metadata .rssi } ≥ ${PacketValidator .maxRssiThreshold }) '
100- '- possible carpeater (RSSI failsafe)' );
115+ '- possible carpeater (RSSI failsafe), repeater=$pathHex ' );
116+ debugLog ('[TX LOG] onCarpeaterDrop callback is ${onCarpeaterDrop != null ? "SET" : "NULL" }' );
117+ onCarpeaterDrop? .call (pathHex, 'RSSI too strong (${metadata .rssi } dBm)' );
101118 return false ; // Mark as handled (dropped)
102119 }
103120 debugLog ('[TX LOG] ✓ RSSI OK (${metadata .rssi } < ${PacketValidator .maxRssiThreshold })' );
@@ -174,15 +191,7 @@ class TxTracker {
174191 debugWarn ('[MESSAGE_CORRELATION] Proceeding without message content verification (less reliable)' );
175192 }
176193
177- // VALIDATION STEP 4: Path length check (must have hops)
178- if (metadata.pathLength == 0 ) {
179- debugLog ('[TX LOG] Ignoring: no path (direct transmission, not a repeater echo)' );
180- return false ;
181- }
182-
183- // Extract first hop (first repeater)
184- final firstHopId = metadata.firstHop! ;
185- final pathHex = firstHopId.toRadixString (16 ).padLeft (2 , '0' );
194+ // Path length and first hop already validated/extracted earlier (before RSSI check)
186195
187196 debugLog ('[PING] Repeater echo accepted: first_hop=$pathHex , SNR=${metadata .snr }, '
188197 'full_path_length=${metadata .pathLength }' );
0 commit comments