BLE Features - non-blocking connects, char presentation format
-
After working on adding a callback on characteristic subscription I've got a few more feature requests for the BLE API. I might attempt these myself... but first I'm looking to make sure that they are achievable given other's knowledge of the underlying ESP-32 API.
-
✅ Read a characteristic's presentation format descriptor. I created a pull request for this feature. However, it could use a second pair of eyes to make sure this is a good approach for future extensibility.
-
✅ Non-blocking connect with configurable timeout. I've got this working. Looks like "background auto connection" is a red herring. I can't find any documentation on it, and setting
is_direct
tofalse
never connects. A quick repl paste below shows how it works. I created a pull request that needs review, testing, etc. -
✅ Making sure scan response data is available in the advertisement. Looking into this possibly related issue and associated ESP-idf pull request. Update: I have confirmed that the current WiPy firmware is affected by this issue. Implementing
sizeof
instead ofESP_BLE_ADV_DATA_LEN_MAX
allows for the parsing of the full scan response. I created a pull request for this fix.
As you may have gathered, these are on the GATTC side of the API.
#2 REPL paste...
Vanilla async_connect:
paste mode; Ctrl-C to cancel, Ctrl-D to finish === from network import Bluetooth === ble = Bluetooth() === import binascii === === def conn_cb (bt_o): === print('conn_cb events {}'.format(bt_o.events())) === === ble.callback(trigger=Bluetooth.SERVER_ASYNC_CONNECTED, handler=conn_cb) === === ble.start_scan(-1) === c = ble.async_connect(binascii.unhexlify('12345678ABCD')) === bt_async_connect: creating connection object >>> >>> >>> c.isconnected() False >>> c.isconnected() False >>> >>> >>> >>> >>> gattc_events_handler: ESP_GATTC_CONNECT_EVT gattc_events_handler: loop gattc_events_handler: found match gattc_events_handler: async_disconnect false: sending callback conn_cb events 262 >>> c.isconnected() True >>> >>> >>> c.disconnect() >>> c.isconnected() False
Then, immediately afterwards in the same REPL, a demonstration of cancelling a connection.
>>> c = ble.async_connect(binascii.unhexlify('12345678ABCD')) bt_async_connect: creating connection object >>> c.disconnect() >>> c.isconnected() False >>> >>> >>> >>> close_connection: async_disconnect: truegattc_events_handler: ESP_GATTC_CONNECT_EVT gattc_events_handler: loop gattc_events_handler: found match gattc_events_handler: async_disconnect true: closing >>> >>> c.isconnected() False
This works for my use case. I couldn't find a better way to effectively cancel
esp_ble_gattc_open
. Again, check out the pull request.Here's a version that's easily pastable via ctrl-e:
from network import Bluetooth ble = Bluetooth() import binascii def conn_cb (bt_o): print('--- conn_cb events {}'.format(bt_o.events())) ble.callback(trigger=Bluetooth.SERVER_ASYNC_CONNECTED, handler=conn_cb) ble.start_scan(-1) c = ble.async_connect(binascii.unhexlify('12345678ABCD'))
-