From 6bb5f7365021567393180a0c81e2384b1ea29b4e Mon Sep 17 00:00:00 2001 From: agessaman Date: Fri, 17 Oct 2025 19:56:42 -0700 Subject: [PATCH] fix to raw publishing logic, update to installers to fix timeout issue --- install.ps1 | 1 + install.sh | 2 ++ packet_capture.py | 38 +++++++++++++++++++++++++++++++------- 3 files changed, 34 insertions(+), 7 deletions(-) diff --git a/install.ps1 b/install.ps1 index 7006a15..1433bad 100644 --- a/install.ps1 +++ b/install.ps1 @@ -776,6 +776,7 @@ PACKETCAPTURE_MQTT1_TRANSPORT=websockets PACKETCAPTURE_MQTT1_USE_TLS=true PACKETCAPTURE_MQTT1_USE_AUTH_TOKEN=true PACKETCAPTURE_MQTT1_TOKEN_AUDIENCE=mqtt-us-v1.letsmesh.net +PACKETCAPTURE_MQTT1_KEEPALIVE=120 "@ Add-Content -Path $envLocal -Value $letsMeshConfig Write-Success "LetsMesh Packet Analyzer enabled" diff --git a/install.sh b/install.sh index 9659ef8..6708034 100755 --- a/install.sh +++ b/install.sh @@ -781,6 +781,7 @@ PACKETCAPTURE_MQTT1_TRANSPORT=websockets PACKETCAPTURE_MQTT1_USE_TLS=true PACKETCAPTURE_MQTT1_USE_AUTH_TOKEN=true PACKETCAPTURE_MQTT1_TOKEN_AUDIENCE=mqtt-us-v1.letsmesh.net +PACKETCAPTURE_MQTT1_KEEPALIVE=120 EOF print_success "LetsMesh Packet Analyzer enabled" @@ -921,6 +922,7 @@ PACKETCAPTURE_MQTT1_TRANSPORT=websockets PACKETCAPTURE_MQTT1_USE_TLS=true PACKETCAPTURE_MQTT1_USE_AUTH_TOKEN=true PACKETCAPTURE_MQTT1_TOKEN_AUDIENCE=mqtt-us-v1.letsmesh.net +PACKETCAPTURE_MQTT1_KEEPALIVE=120 EOF print_success "LetsMesh Packet Analyzer enabled" diff --git a/packet_capture.py b/packet_capture.py index 8d14abc..d18346c 100644 --- a/packet_capture.py +++ b/packet_capture.py @@ -262,11 +262,15 @@ class PacketCapture: if global_topic: return self.resolve_topic_template(global_topic, broker_num) + # For RAW topic, don't provide a default - only publish if explicitly configured + if topic_type_upper == 'RAW': + if self.debug: + self.logger.debug(f"No RAW topic configured for broker {broker_num}, skipping RAW publish") + return None - # CRITICAL FIX: Always provide a valid default topic + # CRITICAL FIX: Always provide a valid default topic for other types default_topics = { 'STATUS': 'meshcore/status', - 'RAW': 'meshcore/raw', 'DECODED': 'meshcore/decoded', 'PACKETS': 'meshcore/packets', 'DEBUG': 'meshcore/debug' @@ -762,7 +766,15 @@ class PacketCapture: def on_mqtt_disconnect(self, client, userdata, disconnect_flags, reason_code, properties): broker_name = userdata.get('name', 'unknown') if userdata else 'unknown' - self.logger.warning(f"Disconnected from MQTT broker {broker_name} (code: {reason_code})") + + # Provide more specific logging for different disconnect reasons + if reason_code == mqtt.MQTT_ERR_KEEPALIVE: + self.logger.warning(f"Disconnected from MQTT broker {broker_name} (code: Keep alive timeout)") + self.logger.info("This may be due to network latency or firewall timeouts. Connection will be retried.") + elif reason_code == mqtt.MQTT_ERR_NETWORK_ERROR: + self.logger.warning(f"Disconnected from MQTT broker {broker_name} (code: Network error)") + else: + self.logger.warning(f"Disconnected from MQTT broker {broker_name} (code: {reason_code})") # Check if any brokers are still connected (excluding the one that just disconnected) connected_brokers = [] @@ -908,8 +920,14 @@ class PacketCapture: headers=None ) - # Connect - keepalive = self.get_env_int(f'MQTT{broker_num}_KEEPALIVE', 60) + # Connect with adaptive keep-alive based on transport type + if transport == "websockets": + # WebSocket connections need longer keep-alive to handle network latency + keepalive = self.get_env_int(f'MQTT{broker_num}_KEEPALIVE', 120) + else: + # TCP connections can use shorter keep-alive + keepalive = self.get_env_int(f'MQTT{broker_num}_KEEPALIVE', 60) + mqtt_client.connect(server, port, keepalive=keepalive) mqtt_client.loop_start() @@ -1091,6 +1109,12 @@ class PacketCapture: self.logger.error("Neither topic nor topic_type provided to safe_publish") continue + # Skip publishing if topic is None (e.g., RAW topic not configured) + if resolved_topic is None: + if self.debug: + self.logger.debug(f"Skipping publish to MQTT{current_broker_num} - topic not configured for {topic_type}") + continue + # Validate topic before publishing if not resolved_topic: self.logger.error(f"Failed to resolve topic (type={topic_type}, topic={topic})") @@ -1593,7 +1617,7 @@ class PacketCapture: # Publish full packet data packet_metrics = self.safe_publish(None, json.dumps(packet_data), topic_type="packets") - # Publish raw data if TOPIC_RAW is configured + # Publish raw data only to brokers that have RAW topic explicitly configured raw_data = { "origin": packet_data["origin"], "origin_id": packet_data["origin_id"], @@ -1603,7 +1627,7 @@ class PacketCapture: } raw_metrics = self.safe_publish(None, json.dumps(raw_data), topic_type="raw") - # Combine metrics: success only if BOTH packets and raw publish successfully + # Combine metrics: success only if BOTH packets and raw (if configured) publish successfully # This ensures we count a broker as successful only if all its topics succeed publish_metrics["attempted"] = max(packet_metrics["attempted"], raw_metrics["attempted"]) publish_metrics["succeeded"] = min(packet_metrics["succeeded"], raw_metrics["succeeded"])