From 9834ae7059bf031f35d345a6ba6a67c06dd333c2 Mon Sep 17 00:00:00 2001 From: Lloyd Date: Sun, 21 Dec 2025 21:22:49 +0000 Subject: [PATCH] Add LBT metadata extraction and logging after packet transmission --- repeater/engine.py | 74 ++++++++++++++-------------------------------- 1 file changed, 23 insertions(+), 51 deletions(-) diff --git a/repeater/engine.py b/repeater/engine.py index 1074779..9f2e5d2 100644 --- a/repeater/engine.py +++ b/repeater/engine.py @@ -11,6 +11,8 @@ from pymc_core.protocol.constants import ( MAX_PATH_SIZE, PAYLOAD_TYPE_ADVERT, PH_ROUTE_MASK, + PH_TYPE_MASK, + PH_TYPE_SHIFT, ROUTE_TYPE_DIRECT, ROUTE_TYPE_FLOOD, ROUTE_TYPE_TRANSPORT_FLOOD, @@ -166,6 +168,24 @@ class RepeaterHandler(BaseHandler): transmitted = True # Schedule retransmit with delay await self.schedule_retransmit(fwd_pkt, delay, airtime_ms) + + # Extract LBT metadata after transmission + tx_metadata = getattr(fwd_pkt, '_tx_metadata', None) + lbt_attempts = 0 + lbt_backoff_delays_ms = None + lbt_channel_busy = False + + if tx_metadata: + lbt_attempts = tx_metadata.get('lbt_attempts', 0) + lbt_backoff_delays_ms = tx_metadata.get('lbt_backoff_delays_ms', []) + lbt_channel_busy = tx_metadata.get('lbt_channel_busy', False) + + if lbt_attempts > 0: + total_lbt_delay = sum(lbt_backoff_delays_ms) + logger.info( + f"LBT: {lbt_attempts} attempts, {total_lbt_delay:.0f}ms delay, " + f"backoffs={lbt_backoff_delays_ms}" + ) else: self.dropped_count += 1 # Determine drop reason from process_packet result @@ -257,6 +277,9 @@ class RepeaterHandler(BaseHandler): [f"{b:02X}" for b in forwarded_path] if forwarded_path is not None else None ), "raw_packet": packet.write_to().hex() if hasattr(packet, "write_to") else None, + "lbt_attempts": lbt_attempts if transmitted else 0, + "lbt_backoff_delays_ms": lbt_backoff_delays_ms if transmitted and lbt_backoff_delays_ms else None, + "lbt_channel_busy": lbt_channel_busy if transmitted else False, } # Store packet record to persistent storage @@ -620,57 +643,6 @@ class RepeaterHandler(BaseHandler): try: await self.dispatcher.send_packet(fwd_pkt, wait_for_ack=False) - - tx_metadata = getattr(fwd_pkt, '_tx_metadata', None) - lbt_attempts = 0 - lbt_backoff_delays_ms = [] - lbt_channel_busy = False - - if tx_metadata: - lbt_attempts = tx_metadata.get('lbt_attempts', 0) - lbt_backoff_delays_ms = tx_metadata.get('lbt_backoff_delays_ms', []) - lbt_channel_busy = tx_metadata.get('lbt_channel_busy', False) - - if lbt_attempts > 0: - total_lbt_delay = sum(lbt_backoff_delays_ms) - logger.info( - f"LBT: {lbt_attempts} attempts, {total_lbt_delay:.0f}ms delay, " - f"backoffs={lbt_backoff_delays_ms}" - ) - - # Store TX packet record with LBT metrics if storage is available - if self.storage and lbt_attempts > 0: - try: - tx_record = { - "timestamp": time.time(), - "header": f"0x{fwd_pkt.header:02X}" if hasattr(fwd_pkt, "header") else None, - "payload": fwd_pkt.payload.hex() if hasattr(fwd_pkt, "payload") and fwd_pkt.payload else None, - "payload_length": len(fwd_pkt.payload) if hasattr(fwd_pkt, "payload") and fwd_pkt.payload else 0, - "type": (fwd_pkt.header >> 4) if hasattr(fwd_pkt, "header") else 0, - "route": (fwd_pkt.header & 0x07) if hasattr(fwd_pkt, "header") else 0, - "length": len(fwd_pkt.payload or b""), - "rssi": None, # TX packets don't have RSSI - "snr": None, # TX packets don't have SNR - "score": None, - "tx_delay_ms": delay * 1000.0, - "transmitted": True, - "is_duplicate": False, - "packet_hash": fwd_pkt.write_to().hex()[:16] if hasattr(fwd_pkt, "write_to") else "", - "drop_reason": None, - "path_hash": None, - "src_hash": None, - "dst_hash": None, - "original_path": None, - "forwarded_path": [f"{b:02X}" for b in fwd_pkt.path] if hasattr(fwd_pkt, "path") and fwd_pkt.path else None, - "raw_packet": fwd_pkt.write_to().hex() if hasattr(fwd_pkt, "write_to") else None, - "lbt_attempts": lbt_attempts, - "lbt_backoff_delays_ms": lbt_backoff_delays_ms, - "lbt_channel_busy": lbt_channel_busy, - } - self.storage.record_packet(tx_record, skip_letsmesh_if_invalid=False) - except Exception as e: - logger.error(f"Failed to store TX packet record with LBT metrics: {e}") - # Record airtime after successful TX if airtime_ms > 0: self.airtime_mgr.record_tx(airtime_ms)