diff --git a/repeater/engine.py b/repeater/engine.py index ba17935..b36a908 100644 --- a/repeater/engine.py +++ b/repeater/engine.py @@ -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:]) diff --git a/repeater/handler_helpers/trace.py b/repeater/handler_helpers/trace.py index 3ca96ac..85ed559 100644 --- a/repeater/handler_helpers/trace.py +++ b/repeater/handler_helpers/trace.py @@ -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: diff --git a/repeater/packet_router.py b/repeater/packet_router.py index 43383fd..267ebb9 100644 --- a/repeater/packet_router.py +++ b/repeater/packet_router.py @@ -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):