Skip to content

Commit 3b23e2f

Browse files
committed
Improved RNode BLE reconnection reliability
1 parent 7417cf5 commit 3b23e2f

File tree

1 file changed

+44
-5
lines changed

1 file changed

+44
-5
lines changed

RNS/Interfaces/RNodeInterface.py

+44-5
Original file line numberDiff line numberDiff line change
@@ -290,6 +290,11 @@ def open_port(self):
290290

291291
else:
292292
RNS.log(f"Opening BLE connection for {self}...")
293+
if self.ble != None and self.ble.running == False:
294+
self.ble.close()
295+
self.ble.cleanup()
296+
self.ble = None
297+
293298
if self.ble == None:
294299
self.ble = BLEConnection(owner=self, target_name=self.ble_name, target_bt_addr=self.ble_addr)
295300
self.serial = self.ble
@@ -298,15 +303,18 @@ def open_port(self):
298303
while not self.ble.connected and time.time() < open_time + self.ble.CONNECT_TIMEOUT:
299304
time.sleep(1)
300305

301-
302-
def configure_device(self):
306+
def reset_radio_state(self):
303307
self.r_frequency = None
304308
self.r_bandwidth = None
305309
self.r_txpower = None
306310
self.r_sf = None
307311
self.r_cr = None
308312
self.r_state = None
309313
self.r_lock = None
314+
self.detected = False
315+
316+
def configure_device(self):
317+
self.reset_radio_state()
310318
sleep(2.0)
311319

312320
thread = threading.Thread(target=self.readLoop)
@@ -513,7 +521,14 @@ def validate_firmware(self):
513521

514522
def validateRadioState(self):
515523
RNS.log("Waiting for radio configuration validation for "+str(self)+"...", RNS.LOG_VERBOSE)
516-
sleep(0.25);
524+
if self.use_ble:
525+
sleep(1.00)
526+
else:
527+
sleep(0.25)
528+
529+
if self.use_ble and self.ble != None and self.ble.device_disappeared:
530+
RNS.log(f"Device disappeared during radio state validation for {self}", RNS.LOG_ERROR)
531+
return False
517532

518533
self.validcfg = True
519534
if (self.r_frequency != None and abs(self.frequency - int(self.r_frequency)) > 100):
@@ -1010,11 +1025,13 @@ def __init__(self, owner=None, target_name=None, target_bt_addr=None):
10101025
self.target_bt_addr = target_bt_addr
10111026
self.scan_timeout = BLEConnection.SCAN_TIMEOUT
10121027
self.ble_device = None
1028+
self.last_client = None
10131029
self.connected = False
10141030
self.running = False
10151031
self.should_run = False
10161032
self.must_disconnect = False
10171033
self.connect_job_running = False
1034+
self.device_disappeared = False
10181035

10191036
import importlib
10201037
if BLEConnection.bleak == None:
@@ -1032,8 +1049,17 @@ def __init__(self, owner=None, target_name=None, target_bt_addr=None):
10321049
self.should_run = True
10331050
self.connection_thread = threading.Thread(target=self.connection_job, daemon=True).start()
10341051

1052+
def cleanup(self):
1053+
try:
1054+
if self.last_client != None:
1055+
self.asyncio.run(self.last_client.disconnect())
1056+
except Exception as e:
1057+
RNS.log(f"Error while disconnecting BLE device on cleanup for {self.owner}", RNS.LOG_ERROR)
1058+
1059+
self.should_run = False
1060+
10351061
def connection_job(self):
1036-
while (self.should_run):
1062+
while self.should_run:
10371063
if self.ble_device == None:
10381064
self.ble_device = self.find_target_device()
10391065

@@ -1043,6 +1069,10 @@ def connection_job(self):
10431069

10441070
time.sleep(1)
10451071

1072+
self.cleanup()
1073+
self.running = False
1074+
RNS.log(f"BLE connection job for {self.owner} ended", RNS.LOG_DEBUG)
1075+
10461076
def connect_device(self):
10471077
if self.ble_device != None and type(self.ble_device) == self.bleak.backends.device.BLEDevice:
10481078
RNS.log(f"Connecting BLE device {self.ble_device} for {self.owner}...", RNS.LOG_DEBUG)
@@ -1056,6 +1086,7 @@ def handle_rx(device, data):
10561086

10571087
self.connected = True
10581088
self.ble_device = ble_client
1089+
self.last_client = ble_client
10591090
self.owner.port = str(f"ble://{ble_client.address}")
10601091

10611092
loop = self.asyncio.get_running_loop()
@@ -1077,12 +1108,14 @@ def handle_rx(device, data):
10771108
self.asyncio.run(connect_job())
10781109
except Exception as e:
10791110
RNS.log(f"Could not connect BLE device {self.ble_device} for {self.owner}. Possibly missing authentication.", RNS.LOG_ERROR)
1111+
10801112
self.connect_job_running = False
10811113

10821114
def device_disconnected(self, device):
10831115
RNS.log(f"BLE device for {self.owner} disconnected", RNS.LOG_NOTICE)
10841116
self.connected = False
10851117
self.ble_device = None
1118+
self.device_disappeared = True
10861119

10871120
def find_target_device(self):
10881121
RNS.log(f"Searching for attachable BLE device for {self.owner}...", RNS.LOG_EXTREME)
@@ -1106,7 +1139,13 @@ def device_filter(device: self.bleak.backends.device.BLEDevice, adv: self.bleak.
11061139

11071140
return False
11081141

1109-
device = self.asyncio.run(self.bleak.BleakScanner.find_device_by_filter(device_filter, timeout=self.scan_timeout))
1142+
device = None
1143+
try:
1144+
device = self.asyncio.run(self.bleak.BleakScanner.find_device_by_filter(device_filter, timeout=self.scan_timeout))
1145+
except Exception as e:
1146+
RNS.log(f"Error while finding BLE device for {self.owner}: {e}", RNS.LOG_ERROR)
1147+
self.should_run = False
1148+
11101149
return device
11111150

11121151
def device_bonded(self, device):

0 commit comments

Comments
 (0)