Enhance advert storage logic: prioritize direct routes and handle zero-hop measurements

Refactor packet processing: use processed_packet for forwarding and drop reason checks

Fix: Update zero-hop determination logic in AdvertHelper

Fix: Clone packet in process_packet to prevent modification of the original

Fix: Import copy module for deep copying of packets in process_packet
This commit is contained in:
Paul Picazo
2025-12-30 00:02:33 -08:00
parent 75c4967bd6
commit 942d4dfe28
3 changed files with 40 additions and 10 deletions

View File

@@ -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:

View File

@@ -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

View File

@@ -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