diff --git a/RNS/Interfaces/Android/RNodeInterface.py b/RNS/Interfaces/Android/RNodeInterface.py index 5d8b19f0..0e744d61 100644 --- a/RNS/Interfaces/Android/RNodeInterface.py +++ b/RNS/Interfaces/Android/RNodeInterface.py @@ -1504,13 +1504,13 @@ class RNodeInterface(Interface): except Exception as e: self.online = False - RNS.log("A serial port error occurred, the contained exception was: "+str(e), RNS.LOG_ERROR) - RNS.log("The interface "+str(self)+" experienced an unrecoverable error and is now offline.", RNS.LOG_ERROR) + if not self.detached: + RNS.log("A serial port error occurred, the contained exception was: "+str(e), RNS.LOG_ERROR) + RNS.log("The interface "+str(self)+" experienced an unrecoverable error and is now offline.", RNS.LOG_ERROR) - if RNS.Reticulum.panic_on_interface_error: - RNS.panic() + if RNS.Reticulum.panic_on_interface_error: RNS.panic() - RNS.log("Reticulum will attempt to reconnect the interface periodically.", RNS.LOG_ERROR) + RNS.log("Reticulum will attempt to reconnect the interface periodically.", RNS.LOG_ERROR) self.online = False @@ -1570,10 +1570,14 @@ class RNodeInterface(Interface): except Exception as e: RNS.log(f"An error occurred while detaching {self}: {e}", RNS.LOG_ERROR) - if self.use_ble: self.ble.close() - if self.use_tcp: + if self.use_ble: + self.ble.close() + self.ble.cleanup() + elif self.use_tcp: time.sleep(0.5) self.tcp.close() + else: + self.serial.close() def should_ingress_limit(self): return False @@ -1652,6 +1656,9 @@ class BLEConnection(BluetoothDispatcher): self.owner.ble_rx_queue = b"" return data + def cleanup(self): + self.should_run = False + def close(self): try: if self.connected: diff --git a/RNS/Interfaces/AutoInterface.py b/RNS/Interfaces/AutoInterface.py index 4dcad4d4..110de664 100644 --- a/RNS/Interfaces/AutoInterface.py +++ b/RNS/Interfaces/AutoInterface.py @@ -1,6 +1,6 @@ # Reticulum License # -# Copyright (c) 2016-2025 Mark Qvist +# Copyright (c) 2016-2026 Mark Qvist # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal diff --git a/RNS/Interfaces/Interface.py b/RNS/Interfaces/Interface.py index 003e2447..7b9839c1 100755 --- a/RNS/Interfaces/Interface.py +++ b/RNS/Interfaces/Interface.py @@ -1,6 +1,6 @@ # Reticulum License # -# Copyright (c) 2016-2025 Mark Qvist +# Copyright (c) 2016-2026 Mark Qvist # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal diff --git a/RNS/Interfaces/RNodeInterface.py b/RNS/Interfaces/RNodeInterface.py index 4633484a..bf623672 100644 --- a/RNS/Interfaces/RNodeInterface.py +++ b/RNS/Interfaces/RNodeInterface.py @@ -1,6 +1,6 @@ # Reticulum License # -# Copyright (c) 2016-2025 Mark Qvist +# Copyright (c) 2016-2026 Mark Qvist # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal @@ -1157,19 +1157,17 @@ class RNodeInterface(Interface): except Exception as e: self.online = False - RNS.log("A serial port error occurred, the contained exception was: "+str(e), RNS.LOG_ERROR) - RNS.log("The interface "+str(self)+" experienced an unrecoverable error and is now offline.", RNS.LOG_ERROR) + if not self.detached: + RNS.log("A serial port error occurred, the contained exception was: "+str(e), RNS.LOG_ERROR) + RNS.log("The interface "+str(self)+" experienced an unrecoverable error and is now offline.", RNS.LOG_ERROR) - if RNS.Reticulum.panic_on_interface_error: - RNS.panic() + if RNS.Reticulum.panic_on_interface_error: RNS.panic() - RNS.log("Reticulum will attempt to reconnect the interface periodically.", RNS.LOG_ERROR) + RNS.log("Reticulum will attempt to reconnect the interface periodically.", RNS.LOG_ERROR) self.online = False - try: - self.serial.close() - except Exception as e: - pass + try: self.serial.close() + except Exception as e: pass if not self.detached and not self.reconnecting: self.reconnect_port() @@ -1195,14 +1193,20 @@ class RNodeInterface(Interface): self.disable_external_framebuffer() self.setRadioState(KISS.RADIO_STATE_OFF) self.leave() + self.serial.close() except Exception as e: RNS.log(f"An error occurred while detaching {self}: {e}", RNS.LOG_ERROR) - if self.use_ble: self.ble.close() - if self.use_tcp: + if self.use_ble: + self.ble.close() + self.ble.cleanup() + self.ble = None + elif self.use_tcp: time.sleep(0.5) self.tcp.close() + else: + self.serial.close() def should_ingress_limit(self): return False diff --git a/RNS/Interfaces/RNodeMultiInterface.py b/RNS/Interfaces/RNodeMultiInterface.py index 8f48ba78..6e0f5fc9 100644 --- a/RNS/Interfaces/RNodeMultiInterface.py +++ b/RNS/Interfaces/RNodeMultiInterface.py @@ -1,6 +1,6 @@ # Reticulum License # -# Copyright (c) 2016-2025 Mark Qvist +# Copyright (c) 2016-2026 Mark Qvist # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal @@ -916,6 +916,7 @@ class RNodeMultiInterface(Interface): if interface != 0: self.setRadioState(KISS.RADIO_STATE_OFF, interface) self.leave() + self.serial.close() def teardown_subinterfaces(self): for interface in self.subinterfaces: