mirror of
https://github.com/markqvist/Reticulum.git
synced 2025-12-17 09:24:31 -05:00
Improved reconnect/hotplug reliability and responsiveness for RNodes connected over WiFi
This commit is contained in:
parent
309f1999e7
commit
7c99aca1d0
2 changed files with 69 additions and 50 deletions
|
|
@ -572,10 +572,8 @@ class RNodeInterface(Interface):
|
||||||
self.open_port()
|
self.open_port()
|
||||||
|
|
||||||
if self.serial != None:
|
if self.serial != None:
|
||||||
if self.serial.is_open:
|
if self.serial.is_open: self.configure_device()
|
||||||
self.configure_device()
|
else: raise IOError("Could not open serial port")
|
||||||
else:
|
|
||||||
raise IOError("Could not open serial port")
|
|
||||||
elif self.bt_manager != None:
|
elif self.bt_manager != None:
|
||||||
if self.bt_manager.connected:
|
if self.bt_manager.connected:
|
||||||
self.configure_device()
|
self.configure_device()
|
||||||
|
|
@ -724,17 +722,19 @@ class RNodeInterface(Interface):
|
||||||
thread = threading.Thread(target=self.readLoop, daemon=True).start()
|
thread = threading.Thread(target=self.readLoop, daemon=True).start()
|
||||||
|
|
||||||
self.detect()
|
self.detect()
|
||||||
if not self.use_ble:
|
if self.use_tcp:
|
||||||
sleep(0.5)
|
tcp_detect_timeout = 5.0
|
||||||
else:
|
detect_time = time.time()
|
||||||
|
while not self.detected and time.time() < detect_time + tcp_detect_timeout: time.sleep(0.1)
|
||||||
|
if not self.detected: RNS.log(f"RNode detect timed out over TCP", RNS.LOG_ERROR)
|
||||||
|
elif self.use_ble:
|
||||||
ble_detect_timeout = 5
|
ble_detect_timeout = 5
|
||||||
detect_time = time.time()
|
detect_time = time.time()
|
||||||
while not self.detected and time.time() < detect_time + ble_detect_timeout:
|
while not self.detected and time.time() < detect_time + ble_detect_timeout: time.sleep(0.1)
|
||||||
time.sleep(0.1)
|
if self.detected: detect_time = RNS.prettytime(time.time()-detect_time)
|
||||||
if self.detected:
|
else: RNS.log(f"RNode detect timed out over {self.port}", RNS.LOG_ERROR)
|
||||||
detect_time = RNS.prettytime(time.time()-detect_time)
|
else:
|
||||||
else:
|
sleep(0.2)
|
||||||
RNS.log(f"RNode detect timed out over {self.port}", RNS.LOG_ERROR)
|
|
||||||
|
|
||||||
if not self.detected:
|
if not self.detected:
|
||||||
raise IOError("Could not detect device")
|
raise IOError("Could not detect device")
|
||||||
|
|
@ -1490,6 +1490,11 @@ class RNodeInterface(Interface):
|
||||||
RNS.log("Interface "+str(self)+" is transmitting beacon data: "+str(self.id_callsign.decode("utf-8")), RNS.LOG_DEBUG)
|
RNS.log("Interface "+str(self)+" is transmitting beacon data: "+str(self.id_callsign.decode("utf-8")), RNS.LOG_DEBUG)
|
||||||
self.process_outgoing(self.id_callsign)
|
self.process_outgoing(self.id_callsign)
|
||||||
|
|
||||||
|
if self.use_tcp:
|
||||||
|
if self.tcp and self.tcp.connected:
|
||||||
|
if time.time() > self.tcp.last_write + self.tcp.ACTIVITY_KEEPALIVE:
|
||||||
|
self.detect()
|
||||||
|
|
||||||
if (time.time() - self.last_port_io > self.port_io_timeout): self.detect()
|
if (time.time() - self.last_port_io > self.port_io_timeout): self.detect()
|
||||||
if (time.time() - self.last_port_io > self.port_io_timeout*3): raise IOError("Connected port for "+str(self)+" became unresponsive")
|
if (time.time() - self.last_port_io > self.port_io_timeout*3): raise IOError("Connected port for "+str(self)+" became unresponsive")
|
||||||
if self.bt_manager != None or self.ble != None: sleep(0.08)
|
if self.bt_manager != None or self.ble != None: sleep(0.08)
|
||||||
|
|
@ -1858,9 +1863,11 @@ class BLEConnection(BluetoothDispatcher):
|
||||||
|
|
||||||
class TCPConnection():
|
class TCPConnection():
|
||||||
TARGET_PORT = 7633
|
TARGET_PORT = 7633
|
||||||
CONNECT_TIMEOUT = 2.5
|
CONNECT_TIMEOUT = 5.0
|
||||||
INITIAL_CONNECT_TIMEOUT = 2.5
|
INITIAL_CONNECT_TIMEOUT = 5.0
|
||||||
RECONNECT_WAIT = 4.0
|
RECONNECT_WAIT = 4.0
|
||||||
|
ACTIVITY_TIMEOUT = 6.0
|
||||||
|
ACTIVITY_KEEPALIVE = ACTIVITY_TIMEOUT-2.5
|
||||||
|
|
||||||
TCP_USER_TIMEOUT = 24
|
TCP_USER_TIMEOUT = 24
|
||||||
TCP_PROBE_AFTER = 5
|
TCP_PROBE_AFTER = 5
|
||||||
|
|
@ -1884,6 +1891,7 @@ class TCPConnection():
|
||||||
self.owner.tcp_tx_queue = b""
|
self.owner.tcp_tx_queue = b""
|
||||||
|
|
||||||
self.socket.sendall(data_bytes)
|
self.socket.sendall(data_bytes)
|
||||||
|
self.last_write = time.time()
|
||||||
|
|
||||||
else:
|
else:
|
||||||
with self.owner.tcp_tx_lock: self.owner.tcp_tx_queue += data_bytes
|
with self.owner.tcp_tx_lock: self.owner.tcp_tx_queue += data_bytes
|
||||||
|
|
@ -1911,6 +1919,7 @@ class TCPConnection():
|
||||||
self.should_run = False
|
self.should_run = False
|
||||||
self.must_disconnect = False
|
self.must_disconnect = False
|
||||||
self.connect_job_running = False
|
self.connect_job_running = False
|
||||||
|
self.last_write = time.time()
|
||||||
|
|
||||||
self.should_run = True
|
self.should_run = True
|
||||||
self.connection_thread = threading.Thread(target=self.initial_connect, daemon=True).start()
|
self.connection_thread = threading.Thread(target=self.initial_connect, daemon=True).start()
|
||||||
|
|
@ -1954,6 +1963,7 @@ class TCPConnection():
|
||||||
self.socket.connect(target_address)
|
self.socket.connect(target_address)
|
||||||
self.socket.settimeout(None)
|
self.socket.settimeout(None)
|
||||||
self.connected = True
|
self.connected = True
|
||||||
|
self.last_write = time.time()
|
||||||
|
|
||||||
RNS.log(f"TCP connection to device for {self.owner} established", RNS.LOG_DEBUG)
|
RNS.log(f"TCP connection to device for {self.owner} established", RNS.LOG_DEBUG)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -345,10 +345,8 @@ class RNodeInterface(Interface):
|
||||||
try:
|
try:
|
||||||
self.open_port()
|
self.open_port()
|
||||||
|
|
||||||
if self.serial.is_open:
|
if self.serial.is_open: self.configure_device()
|
||||||
self.configure_device()
|
else: raise IOError("Could not open serial port")
|
||||||
else:
|
|
||||||
raise IOError("Could not open serial port")
|
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
RNS.log("Could not open serial port for interface "+str(self), RNS.LOG_ERROR)
|
RNS.log("Could not open serial port for interface "+str(self), RNS.LOG_ERROR)
|
||||||
|
|
@ -429,39 +427,41 @@ class RNodeInterface(Interface):
|
||||||
thread.start()
|
thread.start()
|
||||||
|
|
||||||
self.detect()
|
self.detect()
|
||||||
if not self.use_ble:
|
if self.use_tcp:
|
||||||
if self.use_tcp: sleep(1.0)
|
tcp_detect_timeout = 5.0
|
||||||
else: sleep(0.2)
|
|
||||||
else:
|
|
||||||
ble_detect_timeout = 5
|
|
||||||
detect_time = time.time()
|
detect_time = time.time()
|
||||||
while not self.detected and time.time() < detect_time + ble_detect_timeout:
|
while not self.detected and time.time() < detect_time + tcp_detect_timeout: time.sleep(0.1)
|
||||||
time.sleep(0.1)
|
if not self.detected: RNS.log(f"RNode detect timed out over TCP", RNS.LOG_ERROR)
|
||||||
if self.detected:
|
elif self.use_ble:
|
||||||
detect_time = RNS.prettytime(time.time()-detect_time)
|
ble_detect_timeout = 5.0
|
||||||
else:
|
detect_time = time.time()
|
||||||
RNS.log(f"RNode detect timed out over {self.port}", RNS.LOG_ERROR)
|
while not self.detected and time.time() < detect_time + ble_detect_timeout: time.sleep(0.1)
|
||||||
|
if not self.detected: RNS.log(f"RNode detect timed out over BLE", RNS.LOG_ERROR)
|
||||||
|
else:
|
||||||
|
sleep(0.2)
|
||||||
|
|
||||||
if not self.detected:
|
if not self.detected:
|
||||||
RNS.log("Could not detect device for "+str(self), RNS.LOG_ERROR)
|
RNS.log(f"Could not detect device for {self}", RNS.LOG_ERROR)
|
||||||
self.serial.close()
|
self.serial.close()
|
||||||
else:
|
|
||||||
if self.platform == KISS.PLATFORM_ESP32 or self.platform == KISS.PLATFORM_NRF52:
|
|
||||||
self.display = True
|
|
||||||
|
|
||||||
RNS.log(f"Serial port {self.port} is now open") # TODO: Cleanup this
|
|
||||||
RNS.log("Configuring RNode interface...", RNS.LOG_VERBOSE)
|
|
||||||
self.initRadio()
|
|
||||||
if (self.validateRadioState()):
|
|
||||||
self.interface_ready = True
|
|
||||||
RNS.log(str(self)+" is configured and powered up")
|
|
||||||
sleep(0.3)
|
|
||||||
self.online = True
|
|
||||||
else:
|
else:
|
||||||
RNS.log("After configuring "+str(self)+", the reported radio parameters did not match your configuration.", RNS.LOG_ERROR)
|
if self.platform == KISS.PLATFORM_ESP32 or self.platform == KISS.PLATFORM_NRF52: self.display = True
|
||||||
RNS.log("Make sure that your hardware actually supports the parameters specified in the configuration", RNS.LOG_ERROR)
|
|
||||||
RNS.log("Aborting RNode startup", RNS.LOG_ERROR)
|
if self.use_tcp: RNS.log(f"TCP connection to {self.tcp_host} is now open", RNS.LOG_VERBOSE)
|
||||||
self.serial.close()
|
elif self.use_ble: RNS.log(f"BLE connection to {self} is now open", RNS.LOG_VERBOSE)
|
||||||
|
else: RNS.log(f"Serial port {self.port} is now open", RNS.LOG_VERBOSE)
|
||||||
|
RNS.log("Configuring RNode interface...", RNS.LOG_VERBOSE)
|
||||||
|
self.initRadio()
|
||||||
|
if (self.validateRadioState()):
|
||||||
|
self.interface_ready = True
|
||||||
|
RNS.log(str(self)+" is configured and powered up")
|
||||||
|
sleep(0.3)
|
||||||
|
self.online = True
|
||||||
|
else:
|
||||||
|
RNS.log("After configuring "+str(self)+", the reported radio parameters did not match your configuration.", RNS.LOG_ERROR)
|
||||||
|
RNS.log("Make sure that your hardware actually supports the parameters specified in the configuration", RNS.LOG_ERROR)
|
||||||
|
RNS.log("Aborting RNode startup", RNS.LOG_ERROR)
|
||||||
|
self.serial.close()
|
||||||
|
|
||||||
|
|
||||||
def initRadio(self):
|
def initRadio(self):
|
||||||
|
|
@ -1123,6 +1123,11 @@ class RNodeInterface(Interface):
|
||||||
RNS.log("Interface "+str(self)+" is transmitting beacon data: "+str(self.id_callsign.decode("utf-8")), RNS.LOG_DEBUG)
|
RNS.log("Interface "+str(self)+" is transmitting beacon data: "+str(self.id_callsign.decode("utf-8")), RNS.LOG_DEBUG)
|
||||||
self.process_outgoing(self.id_callsign)
|
self.process_outgoing(self.id_callsign)
|
||||||
|
|
||||||
|
if self.use_tcp:
|
||||||
|
if self.tcp and self.tcp.connected:
|
||||||
|
if time.time() > self.tcp.last_write + self.tcp.ACTIVITY_KEEPALIVE:
|
||||||
|
self.detect()
|
||||||
|
|
||||||
sleep(0.08)
|
sleep(0.08)
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
|
|
@ -1151,14 +1156,13 @@ class RNodeInterface(Interface):
|
||||||
time.sleep(5)
|
time.sleep(5)
|
||||||
RNS.log("Attempting to reconnect serial port "+str(self.port)+" for "+str(self)+"...", RNS.LOG_VERBOSE)
|
RNS.log("Attempting to reconnect serial port "+str(self.port)+" for "+str(self)+"...", RNS.LOG_VERBOSE)
|
||||||
self.open_port()
|
self.open_port()
|
||||||
if self.serial.is_open:
|
if self.serial.is_open: self.configure_device()
|
||||||
self.configure_device()
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
RNS.log("Error while reconnecting port, the contained exception was: "+str(e), RNS.LOG_ERROR)
|
RNS.log("Error while reconnecting port, the contained exception was: "+str(e), RNS.LOG_ERROR)
|
||||||
|
|
||||||
self.reconnecting = False
|
self.reconnecting = False
|
||||||
if self.online:
|
if self.online: RNS.log(f"Reconnected port for {self}")
|
||||||
RNS.log(f"Reconnected port for {self}")
|
|
||||||
|
|
||||||
def detach(self):
|
def detach(self):
|
||||||
self.detached = True
|
self.detached = True
|
||||||
|
|
@ -1404,6 +1408,8 @@ class TCPConnection():
|
||||||
CONNECT_TIMEOUT = 5.0
|
CONNECT_TIMEOUT = 5.0
|
||||||
INITIAL_CONNECT_TIMEOUT = 5.0
|
INITIAL_CONNECT_TIMEOUT = 5.0
|
||||||
RECONNECT_WAIT = 4.0
|
RECONNECT_WAIT = 4.0
|
||||||
|
ACTIVITY_TIMEOUT = 6.0
|
||||||
|
ACTIVITY_KEEPALIVE = ACTIVITY_TIMEOUT-2.5
|
||||||
|
|
||||||
TCP_USER_TIMEOUT = 24
|
TCP_USER_TIMEOUT = 24
|
||||||
TCP_PROBE_AFTER = 5
|
TCP_PROBE_AFTER = 5
|
||||||
|
|
@ -1427,6 +1433,7 @@ class TCPConnection():
|
||||||
self.owner.tcp_tx_queue = b""
|
self.owner.tcp_tx_queue = b""
|
||||||
|
|
||||||
self.socket.sendall(data_bytes)
|
self.socket.sendall(data_bytes)
|
||||||
|
self.last_write = time.time()
|
||||||
|
|
||||||
else:
|
else:
|
||||||
with self.owner.tcp_tx_lock: self.owner.tcp_tx_queue += data_bytes
|
with self.owner.tcp_tx_lock: self.owner.tcp_tx_queue += data_bytes
|
||||||
|
|
@ -1454,6 +1461,7 @@ class TCPConnection():
|
||||||
self.should_run = False
|
self.should_run = False
|
||||||
self.must_disconnect = False
|
self.must_disconnect = False
|
||||||
self.connect_job_running = False
|
self.connect_job_running = False
|
||||||
|
self.last_write = time.time()
|
||||||
|
|
||||||
self.should_run = True
|
self.should_run = True
|
||||||
self.connection_thread = threading.Thread(target=self.initial_connect, daemon=True).start()
|
self.connection_thread = threading.Thread(target=self.initial_connect, daemon=True).start()
|
||||||
|
|
@ -1495,6 +1503,7 @@ class TCPConnection():
|
||||||
self.socket.connect(target_address)
|
self.socket.connect(target_address)
|
||||||
self.socket.settimeout(None)
|
self.socket.settimeout(None)
|
||||||
self.connected = True
|
self.connected = True
|
||||||
|
self.last_write = time.time()
|
||||||
|
|
||||||
RNS.log(f"TCP connection to device for {self.owner} established", RNS.LOG_DEBUG)
|
RNS.log(f"TCP connection to device for {self.owner} established", RNS.LOG_DEBUG)
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue