diff --git a/repeater/data_acquisition/sqlite_handler.py b/repeater/data_acquisition/sqlite_handler.py index 104b864..ca1484f 100644 --- a/repeater/data_acquisition/sqlite_handler.py +++ b/repeater/data_acquisition/sqlite_handler.py @@ -5,11 +5,10 @@ import time import secrets import base64 from pathlib import Path -from typing import Optional, Dict, Any, List +from typing import Optional, List logger = logging.getLogger("SQLiteHandler") - class SQLiteHandler: def __init__(self, storage_dir: Path): self.storage_dir = storage_dir @@ -387,14 +386,36 @@ class SQLiteHandler: def store_advert(self, record: dict): try: with sqlite3.connect(self.sqlite_path) as conn: + conn.row_factory = sqlite3.Row existing = conn.execute( - "SELECT pubkey, first_seen, advert_count FROM adverts WHERE pubkey = ? ORDER BY last_seen DESC LIMIT 1", + "SELECT pubkey, first_seen, advert_count, zero_hop, rssi, snr FROM adverts WHERE pubkey = ? ORDER BY last_seen DESC LIMIT 1", (record.get("pubkey", ""),) ).fetchone() current_time = record.get("timestamp", time.time()) - if existing: + if existing: + # Use incoming zero_hop value (already calculated from route_type + path_len) + incoming_zero_hop = record.get("zero_hop", False) + existing_zero_hop = bool(existing["zero_hop"]) + + # Signal measurement logic: + # - If incoming is zero-hop: ALWAYS store incoming rssi/snr (most recent zero-hop measurement) + # - If incoming is multi-hop and existing was zero-hop: preserve existing (don't overwrite zero-hop with multi-hop) + # - If both are multi-hop: signal measurements are not applicable + if incoming_zero_hop: + rssi_to_store = record.get("rssi") + snr_to_store = record.get("snr") + zero_hop_to_store = True + elif existing_zero_hop: + rssi_to_store = existing["rssi"] + snr_to_store = existing["snr"] + zero_hop_to_store = True + else: + rssi_to_store = None + snr_to_store = None + zero_hop_to_store = False + conn.execute(""" UPDATE adverts SET timestamp = ?, node_name = ?, is_repeater = ?, route_type = ?, @@ -411,9 +432,9 @@ class SQLiteHandler: record.get("latitude"), record.get("longitude"), current_time, - record.get("rssi"), - record.get("snr"), - record.get("zero_hop", False), + rssi_to_store, + snr_to_store, + zero_hop_to_store, record.get("pubkey", "") )) else: diff --git a/repeater/engine.py b/repeater/engine.py index 5a1888d..5500d3f 100644 --- a/repeater/engine.py +++ b/repeater/engine.py @@ -1,4 +1,5 @@ import asyncio +import copy import logging import struct import time @@ -119,6 +120,9 @@ class RepeaterHandler(BaseHandler): f"rssi={metadata.get('rssi', 'N/A')}, snr={metadata.get('snr', 'N/A')}, mode={mode}" ) + # clone the packet to avoid modifying the original + processed_packet = copy.deepcopy(packet) + snr = metadata.get("snr", 0.0) rssi = metadata.get("rssi", 0) transmitted = False @@ -128,7 +132,7 @@ class RepeaterHandler(BaseHandler): original_path = list(packet.path) if packet.path else [] # Process for forwarding (skip if in monitor mode or if this is a local transmission) - result = None if (monitor_mode or local_transmission) else self.process_packet(packet, snr) + result = None if (monitor_mode or local_transmission) else self.process_packet(processed_packet, snr) forwarded_path = None # For local transmissions, create a direct transmission result @@ -196,7 +200,7 @@ class RepeaterHandler(BaseHandler): drop_reason = "Monitor mode" else: # Check if packet has a specific drop reason set by handlers - drop_reason = packet.drop_reason or self._get_drop_reason(packet) + drop_reason = processed_packet.drop_reason or self._get_drop_reason(processed_packet) logger.debug(f"Packet not forwarded: {drop_reason}") # Extract packet type and route from header diff --git a/repeater/handler_helpers/advert.py b/repeater/handler_helpers/advert.py index 1ab47b6..4b0fa62 100644 --- a/repeater/handler_helpers/advert.py +++ b/repeater/handler_helpers/advert.py @@ -88,6 +88,11 @@ class AdvertHelper: else: is_new_neighbor = False + # Determine zero-hop: direct routes are always zero-hop, + # flood routes are zero-hop if path_len <= 1 (received directly) + path_len = len(packet.path) if packet.path else 0 + zero_hop = path_len == 0 + # Build advert record advert_record = { "timestamp": current_time, @@ -101,7 +106,7 @@ class AdvertHelper: "rssi": rssi, "snr": snr, "is_new_neighbor": is_new_neighbor, - "zero_hop": route_type in [0x02, 0x03], # True for direct routes (no intermediate hops) + "zero_hop": zero_hop, } # Store to database