Commit Graph

22 Commits

Author SHA1 Message Date
Shin'ichiro Kawasaki
0af23d4280 BLEThread.run: Reduce notification wait time from 1s to 1ms
Now notification wait has 1 second timeout. This might be too long for
Lego Boost. Reduce it to 1 millisecond.

If BLE device does not send out any notification, bluepy-scratch-link
wait for 1 second and during this wait, write or read message from
Scratch is not sent to Boost. This is not an issue for micro:bit since
micro:bit sends out notifications frequently, the notification wait
completes before 1 second timeout.

It was reported that Lego Boost has a few seconds latency between Scratch
motor control command execution to Lego Boost motor move. To try out
smaller timeout, reduce the value.

Signed-off-by: Shin'ichiro Kawasaki <kawasaki@juno.dti.ne.jp>
2020-06-20 13:36:11 +09:00
Shin'ichiro Kawasaki
128786b06b BLESession: Guard getCharacteristics() and getServiceByUUID() with lock
It turned out that bluepy Peripheral's getCharacteristics() and
getServiceByUUID() accesses shared resource with other bluepy APIs. Then
it needs guard with lock in same manner as other bluepy API calls. Guard
them with the lock of the session.

Introduce _get_characteristic() and _get_service() helper functions to
wrap the API calls with lock guard, and replace API calls with them.

Also remove unnecessary getCharacteristics() calls.

Signed-off-by: Shin'ichiro Kawasaki <kawasaki@juno.dti.ne.jp>
2020-06-20 13:36:04 +09:00
Shin'ichiro Kawasaki
751a96eec2 scratch_link.py: Print stack trace of all threads at KeyboardInterrupt
To debug the dead lock status, print stack trace of all threads when
scratch_link.py stops by key interrupt.

Signed-off-by: Shin'ichiro Kawasaki <kawasaki@juno.dti.ne.jp>
2020-06-20 13:35:58 +09:00
Shin'ichiro Kawasaki
22d5b04d20 Session, BLESession: Avoid websocket send job from BLE thread
During trials to make Lego Boost work with bluepy-scratch-link, deadlock
race was observed between the lock for write to BLE device and
waitForNotifcations to BLE device. The cause of the dead lock is
coroutine call by BLE delegate handler to send out notifications to
Scratch through websocket conflict with websocket receive call by
websocket loop thread.

To avoid the conflict, only allow websocket loop thread to send out
through websocket. Have BLE thread to queue notifications so that it does
not need to touch websocket. On the other hand, introduce timeout when
websocket loop thread receives message from Scratch. This allow the
websocket loop thread to check the notifications queued. If any
notification is queued, the websocket loop thread sends it to Scratch.

Also fix notify() function argument signature, which was broken by commit
ba8eba4 ("BLESession: Introduce notification queue").

Signed-off-by: Shin'ichiro Kawasaki <kawasaki@juno.dti.ne.jp>
2020-06-20 13:35:51 +09:00
Shin'ichiro Kawasaki
5dbb85713f BLESession: Add debug prints for Lego Boost
Signed-off-by: Shin'ichiro Kawasaki <kawasaki@juno.dti.ne.jp>
2020-06-20 13:33:34 +09:00
Shin'ichiro Kawasaki
e015d9c283 Revert "BLESession.notify: Send out notifications at once to avoid interruption"
This reverts commit 2c7a10f848.
It turned out that string join with '\n' is not the proper way to pack
multiple JSON messages to Scratch Lego Boost extension.
2020-06-20 13:31:31 +09:00
MDE
2c7a10f848 BLESession.notify: Send out notifications at once to avoid interruption 2020-05-17 09:35:34 +09:00
MDE
ba8eba4800 BLESession: Introduce notification queue
During bluepy-scratch-link handles requests from Scratch, it throws away
notifications from BLE devices. This loses those notifications.

Not to lose the notifications, introduce a queue to keep notifications
from BLE devices. Once request handling completes, flush the
notifications kept in the queue.
2020-05-16 18:24:26 +09:00
MDE
199b54f094 BLESession: Simplify lock and unlock statements using 'with" statement 2020-05-16 17:48:35 +09:00
MDE
9038ef0ce3 BLESession.setNotifications: Refactor out start/stopNotifications 2020-05-16 17:44:13 +09:00
MDE
a217df401b BLESession.handle_request: Support stopNotifications request 2020-05-16 17:39:11 +09:00
MDE
1d29943233 BLESession.handle_request: Support startNotifications request 2020-05-16 17:39:11 +09:00
MDE
e42869c93b BLESession.startNotifications: Refactor out to a function 2020-05-16 17:23:11 +09:00
Shin'ichiro Kawasaki
6fdc8dcbb3 BLESession.handle_request: Fix startNotification KeyError
The value 'startNotification' is optional for the "read" request.
However, bluepy-scratch-link expects Scratch always set the value in the
requests. This may cause KeyError.

Signed-off-by: Shin'ichiro Kawasaki <kawasaki@juno.dti.ne.jp>
2020-05-16 17:09:54 +09:00
Shin'ichiro Kawasaki
1ca2e910fb scratch_link.py: Add debug print option
In the GitHub issue "Scratux support #9", debug message log was required
for analysis. However, script edit by users was required to enable debug
print. This is not handy.

To avoid that the chore by users, add -d debug print option.

Signed-off-by: Shin'ichiro Kawasaki <kawasaki@juno.dti.ne.jp>
2020-05-01 12:55:03 +09:00
Shin'ichiro Kawasaki
8958594cf9 scratch_link.py: Enrich log information
In the GitHub issue "Scratux support #9", it was noticed that
bluepy-scratch-link is not so informative to tell what is happening.
Especially when BLE controllers or BLE devices are not available, no
information is printed.

Enrich log information so that users can tell what is happening easier.

Signed-off-by: Shin'ichiro Kawasaki <kawasaki@juno.dti.ne.jp>
2020-05-01 12:54:07 +09:00
Shin'ichiro Kawasaki
8c42fc04b7 scratch_link.py, gencert.sh: Separate certification and private key
Now gencert.sh generates private key and certificate for the Secure WSS
server in a single file. This is not good to automate certification
addition to NSS databases. Generate them separately into two files and
initialize the Secure WSS server specifying them.

Signed-off-by: Shin'ichiro Kawasaki <kawasaki@juno.dti.ne.jp>
2020-04-18 17:48:28 +09:00
Chris Glencross
6b7619ebeb Add Lego Mindstorms functionality 2020-02-24 19:48:12 +00:00
Shin'ichiro Kawasaki
2240de0085 BLESession.matches: Check service adtypes both 16 bits and 128 bits
LEGO Boost communicates with a Scratch extension through Scratch-link.
It was reported that bluepy-scratch-link fails to connect to LEGO Boost.
LEGO Boost advertises adtype 0x7 "Complete List of 128-bit Service Class
UUIDs". However, bluepy-scratch-link checks only adtype 0x3 "Complete
List of 16-bit Service Class UUIDs" which is valid for micro:bit.

To allow bluepy-scratch-link, check both adtypes 0x7 and 0x3. Introduce
constants to note those two adtype values.

Signed-off-by: Shin'ichiro Kawasaki <kawasaki@juno.dti.ne.jp>
2020-01-25 18:58:35 +09:00
MDE
865c613890 filter: Removed UUID conversion
Scratch 3.0 sends full UUID for LEGO Boost Extension.
If other extensions don't do this, a classifier
will be needed.
2020-01-25 18:58:35 +09:00
MDE
cea2723a0b BLESession.__del__: Fixed NameError exception on exit because of error
Message was:
NameError: name 'close' is not defined
2020-01-25 18:58:35 +09:00
Shin'ichiro Kawasaki
402f79936f scratch_link.py: Initial commit
Implemented Scratch-link[1] feature as a small python script. Confirmed
it is working with Scratch 3.0[2] using a micro:bit as the BLE device to
link. This allows Linux PCs to connect Scratch and micro:bit.

Utilized bluez[3] and bluepy[4] to handle Bluetooth Low Energy connection.
Utilized Websocket module for Secure Web Socket server.

[1] https://github.com/LLK/scratch-link
[2] https://scratch.mit.edu/
[3] http://www.bluez.org/
[4] https://github.com/IanHarvey/bluepy

This is a minimal implementation to support micro:bit. Some of
Scratch-link features are not implemented. For example, Bluetooth (not
BLE) devices are not supported. BLE device support is confirmed only with
micro:bit.

Signed-off-by: Shin'ichiro Kawasaki <kawasaki@juno.dti.ne.jp>
2019-09-15 20:37:37 +09:00