Skip to content

Commit 898018e

Browse files
committed
yay Bleak works again on Linux!
1 parent 9f015f4 commit 898018e

3 files changed

Lines changed: 113 additions & 121 deletions

File tree

.vscode/launch.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
"request": "launch",
1111
"module": "meshtastic",
1212
"justMyCode": false,
13-
"args": ["--debug", "--ble", "--ble-dest", "Meshtastic_9f6e"]
13+
"args": ["--ble", "--ble-dest", "Meshtastic_9f6e"]
1414
},
1515
{
1616
"name": "meshtastic BLE scan",

meshtastic/ble_interface.py

Lines changed: 21 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ def __init__(
4545
self.should_read = False
4646

4747
logging.debug("Threads starting")
48-
self._receiveThread = Thread(target=self._receiveFromRadioImpl)
48+
self._receiveThread = Thread(target=self._receiveFromRadioImpl, name="BLEReceive", daemon=True)
4949
self._receiveThread_started = Event()
5050
self._receiveThread_stopped = Event()
5151
self._receiveThread.start()
@@ -62,6 +62,8 @@ def __init__(
6262
self.close()
6363
raise e
6464

65+
self.client.start_notify(LOGRADIO_UUID, self.log_radio_handler)
66+
6567
logging.debug("Mesh init starting")
6668
MeshInterface.__init__(
6769
self, debugOut=debugOut, noProto=noProto, noNodes=noNodes
@@ -75,9 +77,10 @@ def __init__(
7577

7678
logging.debug("Register FROMNUM notify callback")
7779
self.client.start_notify(FROMNUM_UUID, self.from_num_handler)
78-
self.client.start_notify(LOGRADIO_UUID, self.log_radio_handler)
7980

80-
async def from_num_handler(self, _, b): # pylint: disable=C0116
81+
def from_num_handler(self, _, b): # pylint: disable=C0116
82+
"""Handle callbacks for fromnum notify.
83+
Note: this method does not need to be async because it is just setting a bool."""
8184
from_num = struct.unpack("<I", bytes(b))[0]
8285
logging.debug(f"FROMNUM notify: {from_num}")
8386
self.should_read = True
@@ -95,13 +98,12 @@ async def log_radio_handler(self, _, b): # pylint: disable=C0116
9598
else:
9699
print(log_radio, end=None)
97100

98-
self.should_read = False
99-
100101
@staticmethod
101102
def scan() -> list[BLEDevice]:
102103
"""Scan for available BLE devices."""
103104
with BLEClient() as client:
104-
response = client.discover(return_adv=True, service_uuids=[SERVICE_UUID])
105+
logging.info("Scanning for BLE devices (takes 10 seconds)...")
106+
response = client.discover(timeout=10, return_adv=True, service_uuids=[SERVICE_UUID])
105107

106108
devices = response.values()
107109

@@ -116,20 +118,15 @@ def scan() -> list[BLEDevice]:
116118
def find_device(self, address: Optional[str]) -> BLEDevice:
117119
"""Find a device by address."""
118120

119-
# Bleak scan is buggy (only on linux?) Try a few times
120-
for _ in range(5):
121-
addressed_devices = BLEInterface.scan()
121+
addressed_devices = BLEInterface.scan()
122122

123-
if address:
124-
addressed_devices = list(
125-
filter(
126-
lambda x: address == x.name or address == x.address,
127-
addressed_devices,
128-
)
123+
if address:
124+
addressed_devices = list(
125+
filter(
126+
lambda x: address == x.name or address == x.address,
127+
addressed_devices,
129128
)
130-
# We finally found something?
131-
if len(addressed_devices) > 0:
132-
break
129+
)
133130

134131
if len(addressed_devices) == 0:
135132
raise BLEInterface.BLEError(
@@ -152,6 +149,7 @@ def connect(self, address: Optional[str] = None):
152149
device = self.find_device(address)
153150
client = BLEClient(device.address)
154151
client.connect()
152+
client.discover()
155153
return client
156154

157155
def _receiveFromRadioImpl(self):
@@ -182,11 +180,12 @@ def _sendToRadioImpl(self, toRadio):
182180
if b:
183181
logging.debug(f"TORADIO write: {b.hex()}")
184182
try:
185-
self.client.write_gatt_char(TORADIO_UUID, b, response=False)
183+
self.client.write_gatt_char(TORADIO_UUID, b, response=True) # FIXME: or False?
184+
# search Bleak src for org.bluez.Error.InProgress
186185
except Exception as e:
187-
raise BLEInterface.BLEError("Error writing BLE") from e
186+
raise BLEInterface.BLEError("Error writing BLE (are you in the 'bluetooth' user group? did you enter the pairing PIN on your computer?)") from e
188187
# Allow to propagate and then make sure we read
189-
time.sleep(0.1)
188+
time.sleep(0.01)
190189
self.should_read = True
191190

192191
def close(self):
@@ -206,7 +205,7 @@ class BLEClient:
206205
"""Client for managing connection to a BLE device"""
207206

208207
def __init__(self, address=None, **kwargs):
209-
self._eventThread = Thread(target=self._run_event_loop, name="BLEClient")
208+
self._eventThread = Thread(target=self._run_event_loop, name="BLEClient", daemon=True)
210209
self._eventThread_started = Event()
211210
self._eventThread_stopped = Event()
212211
self._eventThread.start()

0 commit comments

Comments
 (0)