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.

    1. 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.

    2. 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 to false never connects. A quick repl paste below shows how it works. I created a pull request that needs review, testing, etc.

    3. 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 of ESP_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'))
    

Log in to reply
 

Pycom on Twitter