Recently pybluez is not maintained actively and causing troubles. One of
the troubles is pip installation failure [1] and this made pyscrlink
uninstallable via pip. To avoid this, remove pybluez dependency from
pyscrlink. This removes Bluetooth Classic protocol support, then LEGO
Mindstorm EV3 is no longer supported.
[1] https://github.com/pybluez/pybluez/issues/431
Signed-off-by: Shin'ichiro Kawasaki <kawasaki@juno.dti.ne.jp>
In the debug for the issue #30, it turned out that the bluepy API
ScanEntry.getValueText() for adtypes may return multiple UUIDs
concatenated with comma. Current code assumes that the API returns
single UUID, then multiple UUIDs cause the "Error: Non-hexadecimal digit
found" for the comma.
To fix it, replace ScanEntry.getValueText() call with getValue(), and
handle the result as a list of UUIDs. Also rename the helper function
_get_dev_uuid() to _get_dev_uuids() accordingly.
Signed-off-by: Shin'ichiro Kawasaki <kawasaki@juno.dti.ne.jp>
For toio, it is recommended to add "-s 1" option to scratch_link
command. It reduces scan wait duration, and allows toio Do Visual
Programming to connect toio devices automatically. Document it for toio
users.
Signed-off-by: Shin'ichiro Kawasaki <kawasaki@juno.dti.ne.jp>
Pyscrlink scans BLE devices for 10 seconds. This is a safe number to
cover various environments and devices. However, this is too long for
specific devices. One example is toio. Toio's Visual Programming
environment has automated connection to toio devices via Scratch-link,
at it assumes that the scan finishes with shorter time. To allow users
to specify shorter scan duration, add -s, or --scan_seconds option.
To simplify this new option support, utilize argparse library. Rewrite
option parser with argparse.
Signed-off-by: Shin'ichiro Kawasaki <kawasaki@juno.dti.ne.jp>
@n3storm reported that it is not clear which device is BLE, and requires
bluepy-helper capability setup. Improve description to note that most of
devices require the setup since BLE devices are getting the majority.
Signed-off-by: Shin'ichiro Kawasaki <kawasaki@juno.dti.ne.jp>
When the address of device-manager.scratch.mit.edu can not be resolved,
scratch_link.py catches the exception for the resolve failure and
restarts itself. This results in eternal loop.
To avoid the eternal loop, catch the resolve failure, print error
message and break the loop. Also improve the error message for the other
exceptions caught in the loop.
Signed-off-by: Shin'ichiro Kawasaki <kawasaki@juno.dti.ne.jp>
Describe limitation for multiple device connections in "In Case You Fail
to Connect" section. Also, mention about toio support and improved a few
descriptions.
Signed-off-by: Shin'ichiro Kawasaki <kawasaki@juno.dti.ne.jp>
When one pyscrlink uses tries to connect multiple devices at the same
time, the user can connect to the first device without problem. However,
the device scan for the second device causes connection loss for the
first connected device. As discussed in its GitHub issue #357 [1], it is
the limitation of bluepy as of today. This limitation is critical for
pyscrlink to bridge toio[2] and its own scratch[3], because the toio
scratch allows to connect two toio devices to single scratch project.
[1] https://github.com/IanHarvey/bluepy/issues/357
[2] https://www.sony.com/en/SonyInfo/design/stories/toio/
[3] https://github.com/toio/toio-visual-programming/
To bridge multiple devices by pyscrlink, keep references to multiple
devices at the first device scan. Assuming that the user prepares all of
the target devices ready at the device scan, pyscrlink can find the all
devices and keep references to them. When the user requests scan for the
second device, pyscrlink does not invoke the device scan. Instead, it
returns the references to the device it keeps. With this approach, the
disconnection by device scan can be avoided.
In detail, add BLESession.found_devices to keep the found devices and
share across multiple BLESessions. Add BLESession.nr_connected to count
connected sessions. While connected sessions exist, do not scan and
refer the list to return the found device list. Also refactor out device
scan part to a private function _scan_devices().
Note that the user must prepare all devices ready before the first scan.
The devices prepared after the first can not be found since pyscrlink
does not invoke scan. User must disconnect all devices to have pyscrlink
scan devices again.
Signed-off-by: Shin'ichiro Kawasaki <kawasaki@juno.dti.ne.jp>
When an exception is thrown during a session, still the session no
longer works, but still keeps connection. With this status, following
device scan can not find the device. This symptom was observed when
micro:bit with scratch-microbit.hex is connected to "micro:bit MORE" and
BTLEException is thrown. Another symptom observed is the Scratch web
page closed and websocket connection slows ConnectionClosedOK exception.
To avoid the device scan failure, close the session when an exception is
caught. Also improve error message for the exception.
Signed-off-by: Shin'ichiro Kawasaki <kawasaki@juno.dti.ne.jp>
It was informed that the required tools setcap and getcap are not placed
in /usr/bin in some user environment. They can not be executed since
they are out of PATH. To allow the script to execute the commands out of
PATH, have the script find the tools. Keep the found paths of each
command in the dictionary 'tools', and refer it to execute the commands.
Signed-off-by: Shin'ichiro Kawasaki <kawasaki@juno.dti.ne.jp>
To improve readability a bit, introduce _get_characteristic_cached().
Added some failure handlings in the method for robustness.
Also rename _get_all_characteristics() to _cache_characteristics() for
simplification.
Signed-off-by: Shin'ichiro Kawasaki <kawasaki@juno.dti.ne.jp>
Retrieve all characteristics value on connect and cache it to speed up characteristics write that was slow as the handle got by _get_characteristic() every time a write occurred.
Improved English of the description. Updated list of devices and distros
that work with pyscrlink. Replaced 'Lego' with 'LEGO'.
Signed-off-by: Shin'ichiro Kawasaki <kawasaki@juno.dti.ne.jp>
By default, pyOpenSSL generates X.509 certification version 1. However,
Chrome does not work with X.509 with version 1 and fails with
ERR_SSL_SERVER_CERT_BAD_FORMAT error. Set version 3 to generate X.509
certificate.
Signed-off-by: Shin'ichiro Kawasaki <kawasaki@juno.dti.ne.jp>
The argument capture_output which was introduced in python 3.7 is used in
bluepy_helper_cap.py and gencert.py. This cause failure with python 3.6
environment. Avoid the failure by removing the argument.
Signed-off-by: Shin'ichiro Kawasaki <kawasaki@juno.dti.ne.jp>
As the first step to rename the project to pyscrlink, rename the module
directory from bluepy_scratch_link to pyscrlink.
Signed-off-by: Shin'ichiro Kawasaki <kawasaki@juno.dti.ne.jp>
When scratch_link.py is executed as the command specified by setuptools'
entry_point, following errors happen. Fix them.
- Package name can not be resolved to import modules.
- The global variable sessionTypes can not be refereed from the main
function.
- Command line options are not parsed in main function.
Signed-off-by: Shin'ichiro Kawasaki <kawasaki@juno.dti.ne.jp>
When a python package is installed by user, the commands in the package
can not run with sudo. To run setcap in bluepy_helper_cap.py with sudo
privilege, specify sudo command within the python script.
Signed-off-by: Shin'ichiro Kawasaki <kawasaki@juno.dti.ne.jp>
Add __main__.py to the bluepy-scratch-link package to invoke its feature
using the package name.
Signed-off-by: Shin'ichiro Kawasaki <kawasaki@juno.dti.ne.jp>
To create PyPI package for bluepy-scratch-link, create a package
directory to hold the python scripts. Also add __init__.py to mark the
directory as a package.
Signed-off-by: Shin'ichiro Kawasaki <kawasaki@juno.dti.ne.jp>
BLED112 is not supported at this moment. Comment it in README.md until
path for support gets clarified.
Signed-off-by: Shin'ichiro Kawasaki <kawasaki@juno.dti.ne.jp>
To run bluepy-scratch-link as a normal user bluepy-helper must have
cap_net_admin and cap_net_raw capabilities to connect to BLE devices
using bluepy. When it lacks these capabilities, bluepy-scratch-link
fails to discover BLE devices without message about the failure reason.
To inform users the reason of BLE device detection failure, check
capabilities of bluepy-helper when discovery of BLE device is requested.
If the capabilities are not set, print error messages and request users
to run script to set the capabilities. Implement this features in
bluepy_helper_cap.py.
In addition, re-implement bash script setcap.sh feature as python and
added to bluepy_helper_cap.py to simplify the code set.
Signed-off-by: Shin'ichiro Kawasaki <kawasaki@juno.dti.ne.jp>
Now scratch_link.py generates certificate at server start. Remove
description about gencert.sh which is no longer needed.
Signed-off-by: Shin'ichiro Kawasaki <kawasaki@juno.dti.ne.jp>
WSS server certificate files are no longer generated in the directory
git controls. Remove it from .gitignore.
Add __pycache__ directory to .gitignore not to make "git status" list it.
Signed-off-by: Shin'ichiro Kawasaki <kawasaki@juno.dti.ne.jp>
The script gencert.sh prepares the certificate for the WSS server.
The certificate is stored in the bluepy-scratch-link directory path, and
shared by users on the machine. This certificate sharing among users is
not handy in case one user prepares bluepy-scratch-link and another user
use it, since the latter user may not know where the certificate is.
Address this issue by generating the certificate for each user.
Re-implement gencert.sh as a python module gencert.py, and integrate it
in scratch_link.py. With this, when a user starts scratch_link.py,
the certificate unique for the user is generated and stored under user
home directory at the path "~/.local/share/blupy-scrach-link".
The newly added python module gencert.py depends on pyOpenSSL to generate
the certificates. Add this dependency to requirements.txt.
Signed-off-by: Shin'ichiro Kawasaki <kawasaki@juno.dti.ne.jp>
To know how long each operation in scratch_link.py takes, add time stamps
to each log entry.
Signed-off-by: Shin'ichiro Kawasaki <kawasaki@juno.dti.ne.jp>