Search code examples
pythonbluetooth-lowenergyadafruit

Adafruit BLE python library can't list descriptors


I'm trying to use BLE library for python to communicate with one Nordic nrf51844 chipset. Because one characteristic is notification enabled, I need to enable notification from client side by setting the descriptor Client Characteristic Configuration to 0x0001. But I failed to get the descriptor with the call "characteristic.find_descriptor()" to get it. I also tried to print out all of descriptors discovered, but looks like there is no luck to get it work.

Below is the code I'm using to discover characteristics and its descriptor referred to the example of Adafruit BLE library:

def enable_notification(characteristic):
    _enableDesc = characteristic.find_descriptor(CLIENT_CHARACTERISTIC_CONFIG_DESCRIPTOR_UUID)
    _cmd = bytearray([0x01, 0x00])
    _enableDesc.write_value(_cmd)

def handle_device_message(device):
    global _status
    # Once connected do everything else in a try/finally to make sure the device
    # is disconnected when done.

    # Wait for service discovery to complete for at least the specified
    # service and characteristic UUID lists.  Will time out after 60 seconds
    # (specify timeout_sec parameter to override).
    _logger.info('Discovering services...')
    device.discover([HES_SERVICE_UUID], [DATA_CHAR_UUID, STATUS_CHAR_UUID, FACTOR_CHAR_UUID])

    # Find the HES service and its characteristics.
    hes = device.find_service(HES_SERVICE_UUID)
    dataC = hes.find_characteristic(DATA_CHAR_UUID)
    statusC = hes.find_characteristic(STATUS_CHAR_UUID)
    #factorC = hes.find_characteristic(FACTOR_CHAR_UUID)

    dataC.list_descriptors()
    statusC.list_descriptors()

    enable_notification(dataC)
    enable_notification(statusC)

But it always failed at "characteristic.find_descriptor()" with below error:

_enableDesc =
characteristic.find_descriptor(CLIENT_CHARACTERISTIC_CONFIG_DESCRIPTOR_UUID)
File "build/bdist.macosx-10.11-x86_64/egg/Adafruit_BluefruitLE/interfaces/gatt.py", line 98, in find_descriptor
File "build/bdist.macosx-10.11-x86_64/egg/Adafruit_BluefruitLE/corebluetooth/gatt.py", line 124, in list_descriptors
File "build/bdist.macosx-10.11-x86_64/egg/Adafruit_BluefruitLE/corebluetooth/metadata.py", line 63, in get_all
TypeError: 'NoneType' object is not iterable

I looked into the source code of library, but can't find the interface to get descriptors explicitly. Can anyone help me on this?

Thanks!


Solution

  • Finally I figured out by checking the API of IOS to set notification. It should be set by calling setNotify for characteristic instead of writeValue for descriptor. And for the descriptor stuff, it shows we need to wait for some time before all descriptors are discovered and returned. Might be the issue implemented with Python. Not really verified with IOS native program.

    BTW, after setting the notification, we need to wait for some time as well before the device sends notification to client.

    Will get a Linux box to verify the implementation with blueZ is working well.