packet handling to support locally injected packets in RepeaterHandler and update trace packet forwarding to use injection method

This commit is contained in:
Lloyd
2025-12-01 22:43:02 +00:00
parent 60964ea13d
commit 1b3ee8f4f1
3 changed files with 35 additions and 34 deletions

View File

@@ -488,15 +488,24 @@ class RepeaterHandler(BaseHandler):
def direct_forward(self, packet: Packet) -> Optional[Packet]:
# Check if we're the next hop
# Check if we're the next hop (skip for locally injected packets)
if not packet.path or len(packet.path) == 0:
self._last_drop_reason = "Direct: no path"
return None
# For locally injected packets, this is expected - they don't have paths yet
if hasattr(packet, '_locally_injected') and packet._locally_injected:
pass
else:
self._last_drop_reason = "Direct: no path"
return None
next_hop = packet.path[0]
if next_hop != self.local_hash:
self._last_drop_reason = "Direct: not for us"
return None
elif len(packet.path) > 0:
next_hop = packet.path[0]
if next_hop != self.local_hash:
# Skip this check for locally injected packets
if hasattr(packet, '_locally_injected') and packet._locally_injected:
pass
else:
self._last_drop_reason = "Direct: not for us"
return None
original_path = list(packet.path)
packet.path = bytearray(packet.path[1:])

View File

@@ -211,7 +211,8 @@ class TraceHelper:
async def _forward_trace_packet(self, packet, trace_path_len: int) -> None:
"""
Forward a trace packet by appending SNR and sending directly.
Forward a trace packet by appending SNR and sending via injection.
Args:
packet: The trace packet to forward
trace_path_len: The length of the trace path
@@ -251,7 +252,6 @@ class TraceHelper:
)
# Inject packet into router for proper routing and transmission
# Router will handle marking as seen to prevent duplicate processing
if self.packet_injector:
await self.packet_injector(packet, wait_for_ack=False)
else:

View File

@@ -51,13 +51,10 @@ class PacketRouter:
async def inject_packet(self, packet, wait_for_ack: bool = False):
"""
Inject a new packet into the system for direct transmission.
Inject a new packet into the system for transmission through the engine.
This method bypasses the normal routing and sends packets directly
via the dispatcher. Used by helpers to send response packets.
IMPORTANT: Pre-marks packet as seen to prevent processing our own
transmitted packets as duplicates when they're received back.
This method uses the engine's main packet handler but marks the packet
as originated locally to bypass forwarding logic.
Args:
packet: The packet to send
@@ -67,28 +64,23 @@ class PacketRouter:
True if packet was sent successfully, False otherwise
"""
try:
# Pre-mark the packet as seen BEFORE transmission to prevent
# our own radio from processing it as an incoming duplicate
if hasattr(self.daemon, 'repeater_handler') and self.daemon.repeater_handler:
self.daemon.repeater_handler.mark_seen(packet)
logger.debug("Pre-marked injected packet as seen to prevent duplicate processing")
# Mark this packet as locally originated to bypass forwarding checks
packet._locally_injected = True
if hasattr(self.daemon, 'dispatcher') and self.daemon.dispatcher:
success = await self.daemon.dispatcher.send_packet(packet, wait_for_ack=wait_for_ack)
if success:
packet_len = len(packet.payload) if packet.payload else 0
logger.debug(f"Injected packet sent successfully ({packet_len} bytes)")
else:
logger.warning("Failed to send injected packet")
return success
else:
logger.error("No dispatcher available for packet injection")
return False
metadata = {
"rssi": getattr(packet, "rssi", 0),
"snr": getattr(packet, "snr", 0.0),
"timestamp": getattr(packet, "timestamp", 0),
}
await self.daemon.repeater_handler(packet, metadata)
packet_len = len(packet.payload) if packet.payload else 0
logger.debug(f"Injected packet processed by engine ({packet_len} bytes)")
return True
except Exception as e:
logger.error(f"Error injecting packet: {e}")
logger.error(f"Error injecting packet through engine: {e}")
return False
async def _process_queue(self):