diff --git a/app/database.py b/app/database.py index 08414cc..fcc8b01 100644 --- a/app/database.py +++ b/app/database.py @@ -248,14 +248,15 @@ class Database: cursor = conn.execute( """INSERT INTO direct_messages (contact_pubkey, direction, content, timestamp, sender_timestamp, - txt_type, snr, path_len, expected_ack, signature, raw_json) - VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)""", + txt_type, snr, path_len, expected_ack, pkt_payload, signature, raw_json) + VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)""", (contact_pubkey, direction, content, timestamp, kwargs.get('sender_timestamp'), kwargs.get('txt_type', 0), kwargs.get('snr'), kwargs.get('path_len'), kwargs.get('expected_ack'), + kwargs.get('pkt_payload'), kwargs.get('signature'), kwargs.get('raw_json')) ) diff --git a/app/device_manager.py b/app/device_manager.py index 498d558..f4be437 100644 --- a/app/device_manager.py +++ b/app/device_manager.py @@ -262,6 +262,7 @@ class DeviceManager: sender_timestamp=data.get('sender_timestamp'), snr=data.get('snr'), path_len=data.get('path_len'), + pkt_payload=data.get('pkt_payload'), raw_json=json.dumps(data, default=str), ) @@ -454,6 +455,7 @@ class DeviceManager: content=text, timestamp=ts, expected_ack=event_data.get('expected_ack'), + pkt_payload=event_data.get('pkt_payload'), ) return { diff --git a/app/schema.sql b/app/schema.sql index 7587142..422d6a4 100644 --- a/app/schema.sql +++ b/app/schema.sql @@ -72,6 +72,7 @@ CREATE TABLE IF NOT EXISTS direct_messages ( snr REAL, path_len INTEGER, expected_ack TEXT, -- ACK code for delivery tracking + pkt_payload TEXT, -- raw packet payload for hash/analyzer signature TEXT, -- dedup signature raw_json TEXT, created_at TEXT NOT NULL DEFAULT (datetime('now')), diff --git a/scripts/watchdog/watchdog.py b/scripts/watchdog/watchdog.py index 6b61290..6bea456 100755 --- a/scripts/watchdog/watchdog.py +++ b/scripts/watchdog/watchdog.py @@ -38,8 +38,8 @@ LOG_FILE = os.environ.get('LOG_FILE', '/var/log/mc-webui-watchdog.log') HTTP_PORT = int(os.environ.get('HTTP_PORT', '5051')) AUTO_START = os.environ.get('AUTO_START', 'true').lower() != 'false' -# Containers to monitor -CONTAINERS = ['meshcore-bridge', 'mc-webui'] +# Containers to monitor (v2: single container, no meshcore-bridge) +CONTAINERS = ['mc-webui'] # Global state last_check_time = None @@ -318,8 +318,8 @@ def handle_unhealthy_container(container_name: str, status: dict): except Exception as e: log(f"Failed to save diagnostic info: {e}", 'ERROR') - # Check if we should do a USB reset for meshcore-bridge - if container_name == 'meshcore-bridge': + # v2: mc-webui owns the device connection directly — USB reset if repeated failures + if container_name == 'mc-webui': recent_restarts = count_recent_restarts(container_name, minutes=8) if recent_restarts >= 3: log(f"{container_name} has been restarted {recent_restarts} times in the last 8 minutes. Attempting hardware USB reset.", "WARN") diff --git a/tests/test_database.py b/tests/test_database.py index ad25885..e25c809 100644 --- a/tests/test_database.py +++ b/tests/test_database.py @@ -250,6 +250,16 @@ class TestDirectMessages: assert ack is not None assert ack['snr'] == -3.0 + def test_dm_with_pkt_payload(self, db): + db.upsert_contact('cc', name='Charlie') + ts = int(time.time()) + dm_id = db.insert_direct_message( + 'cc', 'in', 'Hello', ts, pkt_payload='deadbeef01020304' + ) + messages = db.get_dm_messages('cc') + assert len(messages) == 1 + assert messages[0]['pkt_payload'] == 'deadbeef01020304' + # ================================================================ # Echoes