From 0e47dc6717271fc52bac9c3d5af2374267135be8 Mon Sep 17 00:00:00 2001 From: James Rich Date: Sun, 19 Apr 2026 12:45:34 -0500 Subject: [PATCH] fix(tcp): stop emitting redundant permanent disconnect from close() TcpRadioTransport.close() unconditionally emitted onDisconnect with isPermanent=true. The 'closing' guard at the listener level already suppresses the transient signal during teardown, and the explicit- disconnect emit is owned by SharedRadioInterfaceService.stopTransportLocked. The double-emit caused two terminal disconnect events for one user action and prevented the auto-reconnect loop from cleanly owning its lifecycle. --- .../org/meshtastic/core/network/radio/TcpRadioTransport.kt | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/core/network/src/jvmAndroidMain/kotlin/org/meshtastic/core/network/radio/TcpRadioTransport.kt b/core/network/src/jvmAndroidMain/kotlin/org/meshtastic/core/network/radio/TcpRadioTransport.kt index 354c4cd30..202d8de57 100644 --- a/core/network/src/jvmAndroidMain/kotlin/org/meshtastic/core/network/radio/TcpRadioTransport.kt +++ b/core/network/src/jvmAndroidMain/kotlin/org/meshtastic/core/network/radio/TcpRadioTransport.kt @@ -78,7 +78,11 @@ open class TcpRadioTransport( Logger.d { "[$address] Closing TCP transport" } closing = true transport.stop() - callback.onDisconnect(isPermanent = true) + // Do NOT emit onDisconnect(isPermanent = true) here. The explicit-disconnect signal is the + // service layer's responsibility (SharedRadioInterfaceService.stopTransportLocked); emitting + // it from close() caused a double-disconnect and prevented the auto-reconnect loop from + // owning its own lifecycle. The `closing` guard above suppresses the listener's transient + // disconnect during teardown. } override fun keepAlive() {