5 Commits
snap ... v0.2.8

Author SHA1 Message Date
Shin'ichiro Kawasaki
dc2ee5a22f Tag version 0.2.8
Signed-off-by: Shin'ichiro Kawasaki <kawasaki@juno.dti.ne.jp>
2023-07-02 21:52:08 +09:00
Shin'ichiro Kawasaki
caa344ecbb scratch_link.py: Support COMPLETE_LOCAL_NAME for 'namePrefix' filter
Current implementation of match() does filter matching for 'namePrefix'
keyword only for SHORT_LOCAL_NAME of the device. When the device does
not provide SHORT_LOCAL_NAME but provides COMPLETE_LOCAL_NAME, match()
for 'namePrefix' fails. For example, MicroBit More v2 [1] does not
provide the SHORT_LOCAL_NAME.

To support 'namePrefix' filter match with COMPLETE_LOCAL_NAME, add
support for it. While at it, replace the SHORT_LOCAL_NAME identifier
constant with the definition in btle.ScanEntry.

[1] https://lab.yengawa.com/project/microbit-more-v2/

Signed-off-by: Shin'ichiro Kawasaki <kawasaki@juno.dti.ne.jp>
2023-07-02 21:52:08 +09:00
Shin'ichiro Kawasaki
0f9ccd3b63 Tag version 0.2.7
Signed-off-by: Shin'ichiro Kawasaki <kawasaki@juno.dti.ne.jp>
2023-03-21 17:17:31 +09:00
Shin'ichiro Kawasaki
d1f7f58ca2 README.md: Add description about -r option for scan failure
Add an item to "In Case You Fail to Connect" section to describe that
the "-r" option may help to address device scan failure.

Signed-off-by: Shin'ichiro Kawasaki <kawasaki@juno.dti.ne.jp>
2023-03-21 16:54:59 +09:00
Shin'ichiro Kawasaki
7050016ee6 scratch_link.py: Add -r option to retry BLE scan
Recently, scratch link connection failure is reported. Similar failure
is observed with my environment. I found BTLEDisconnectError happens at
scanner.scan(). Though the true cause of the failure is not yet known, I
found simple retry of scanner.scan() avoids the failure. As a temporary
work around, implement -r or --scan_retry option which specify how many
times to retry the scan. I confirmed that "-r 2" option avoided the
failure.

Signed-off-by: Shin'ichiro Kawasaki <kawasaki@juno.dti.ne.jp>
2023-03-21 15:53:34 +09:00
3 changed files with 60 additions and 23 deletions

View File

@@ -141,10 +141,22 @@ In Case You Fail to Connect
* If the service is not working, refer guide of your distro to set it up.
* If the service is working, also check that /etc/bluetooth/main.conf sets AutoEnable=true.
3. If scratch_link.py says "failed to connect to BT device: [Errno 13] Permission denied",
3. If device scan still fails, use -r option to retry device scan.
The command line below does device scan twice. Each scan takes 10 seconds.
```
$ scratch_link -r 2
```
It would be good to use -s option together to reduce each scan duration.
The command line below does 3 seconds device scan twice.
```
$ scratch_link -r 2 -s 3
```
4. If scratch_link.py says "failed to connect to BT device: [Errno 13] Permission denied",
make sure to pair the bluetooth device to your PC before connecting to Scratch.
4. To connect to multiple devices at the same time, make all the target devices
5. To connect to multiple devices at the same time, make all the target devices
ready for scan at the first device scan. This is important for toio. The toio
allows a single project to connect to two toio devices.
* When the second device was prepared after the first device was connected, device scan can not find the second device.
@@ -158,6 +170,15 @@ Please file issues to [GitHub issue tracker](https://github.com/kawasaki/pyscrli
Releases
--------
Release 0.2.8
* Supported Microbit More v2
Release 0.2.7
* Supported Snap Firefox and Chromium
* Added -r option to retry BLE scan
Release 0.2.6
* Removed Bluetooth Classic and LEGO Mindstorm EV3 support

View File

@@ -18,7 +18,7 @@ import traceback
import argparse
# for BLESession (e.g. BBC micro:bit)
from bluepy.btle import Scanner, UUID, Peripheral, DefaultDelegate
from bluepy.btle import Scanner, UUID, Peripheral, DefaultDelegate, ScanEntry
from bluepy.btle import BTLEDisconnectError, BTLEManagementError
from pyscrlink import bluepy_helper_cap
@@ -292,15 +292,19 @@ class BLESession(Session):
logger.debug("match...")
return True
if 'namePrefix' in f:
# 0x08: Shortened Local Name
deviceName = dev.getValueText(0x08)
if not deviceName:
continue
logger.debug(f"Name of \"{deviceName}\" begins with: \"{f['namePrefix']}\"?")
if(deviceName.startswith(f['namePrefix'])):
logger.debug("Yes")
return True
logger.debug("No")
logger.debug(f"given namePrefix: {f['namePrefix']}")
deviceName = dev.getValueText(ScanEntry.SHORT_LOCAL_NAME)
if deviceName:
logger.debug(f"SHORT_LOCAL_NAME: {deviceName}")
if deviceName.startswith(f['namePrefix']):
logger.debug(f"match...")
return True
deviceName = dev.getValueText(ScanEntry.COMPLETE_LOCAL_NAME)
if deviceName:
logger.debug(f"COMPLETE_LOCAL_NAME: {deviceName}")
if deviceName.startswith(f['namePrefix']):
logger.debug(f"match...")
return True
if 'name' in f or 'manufactureData' in f:
logger.error("name/manufactureData filters not implemented")
# TODO: implement other filters defined:
@@ -318,16 +322,23 @@ class BLESession(Session):
BLESession.found_devices.clear()
for i in range(self.MAX_SCANNER_IF):
scanner = Scanner(iface=i)
try:
logger.debug(f"start BLE scan: {scan_seconds} seconds")
devices = scanner.scan(scan_seconds)
for dev in devices:
if self.matches(dev, params['filters']):
BLESession.found_devices.append(dev)
found = True
logger.debug(f"BLE device found with iface #{i}");
except BTLEManagementError as e:
logger.debug(f"BLE iface #{i}: {e}");
for j in range(scan_retry):
try:
logger.debug(f"start BLE scan: {scan_seconds} seconds")
devices = scanner.scan(scan_seconds)
for dev in devices:
if self.matches(dev, params['filters']):
BLESession.found_devices.append(dev)
found = True
logger.debug(f"BLE device found with iface #{i}");
if found:
break
except BTLEDisconnectError as de:
logger.debug(f"BLE iface #{i}: {de}");
except BTLEManagementError as me:
logger.debug(f"BLE iface #{i}: {me}");
if found:
break
else:
found = len(BLESession.found_devices) > 0
return found
@@ -534,11 +545,14 @@ def stack_trace():
def main():
global scan_seconds
global scan_retry
parser = argparse.ArgumentParser(description='start Scratch-link')
parser.add_argument('-d', '--debug', action='store_true',
help='print debug messages')
parser.add_argument('-s', '--scan_seconds', type=float, default=10.0,
help='specifiy duration to scan BLE devices in seconds')
parser.add_argument('-r', '--scan_retry', type=int, default=1,
help='specifiy retry times to scan BLE devices')
args = parser.parse_args()
if args.debug:
print("Print debug messages")
@@ -546,7 +560,9 @@ def main():
handler.setLevel(logLevel)
logger.setLevel(logLevel)
scan_seconds = args.scan_seconds
scan_retry = args.scan_retry
logger.debug(f"set scan_seconds: {scan_seconds}")
logger.debug(f"set scan_retry: {scan_retry}")
# Prepare certificate of the WSS server
gencert.prep_cert()

View File

@@ -5,7 +5,7 @@ with open("README.md", "r") as fh:
setuptools.setup(
name="pyscrlink",
version="0.2.6",
version="0.2.8",
author="Shin'ichiro Kawasaki",
author_email='kawasaki@juno.dti.ne.jp',
description='Scratch-link for Linux with Python',