getsenic / gatt-python

Bluetooth GATT SDK for Python
MIT License
318 stars 86 forks source link

Activate Notifications Client Characteristic Configuration Descriptor #39

Closed joliverr closed 5 years ago

joliverr commented 5 years ago

Hello!

The situation is the following: I'm using the gatt library for communicate between a raspberry Pi 3 (python, Client) and the bluenrg module for the nucleo F103-RB(Server, C).

The library works correctly both to read and to write. But I can't activate the notifications. To receive notifications, it must activate the Client Characteristic Configuration Descriptor ( UUID = 0x2902 ) through the handle of this notification, writing a 0x0200.

When I readed the characteristics of the servers, I didn't see this characteristic.

My code is:

import gatt import time

manager = gatt.DeviceManager(adapter_name='hci0')

class AnyDevice(gatt.Device): def services_resolved(self): super(AnyDevice,self).services_resolved()

    serv = next(
        s for s in self.services
        if s.uuid == 'd973f2e7-b19e-11e2-9e96-0800200c9a66') 

    char = next(
        c for c in serv.characteristics
        if c.uuid == 'd973f2e8-b19e-11e2-9e96-0800200c9a66')

    char.enable_notifications()
    char.write_value(b'\x22')
    #char.read_value()

def characteristic_value_updated(self, characteristic, value):
    print('updated value: ' + str(value))
    self.disconnect()
    self.manager.stop()

def characteristic_enable_notification_succeeded(self, characteristic):
    print("Notification Enabled")

def characteristic_enable_notification_failed(self, characteristic, error):
    print("Error")

device = AnyDevice(mac_address='02:80:e1:01:01:aa', manager=manager) device.connect()

manager.run()


¿Can I find the handle of all the characteristics? ¿ How Could I write to the 0x2902( CCCD) ?

Thanks you so much

Jordi

plainas commented 5 years ago

I also need to do this and can confirm that the CCCD is not added to the service characteristic list.

I outputted all characteristics of all services and the CCCD wasn't present in any service. However, if I do service discovery with bluetoothctl tool, two services have a CCCD.

Is the regex in characteristics_resolved() maybe leaving out special cases? Or are the CCCDs exposed by dbus somewhere else?

Snevzor commented 5 years ago

You've already 'activated' the notifications by executing enable_notifications(). No need to write to the CCCD yourself. So what is the problem exactly?

Fyi, when a notification has been received the characteristic_value_updated() callback will be fired. This is the same callback that is used when reading a BLE characteristic value (which I personally don't like).

plainas commented 5 years ago

The problem is that enable_notifications() doesn't do anything. I call it on a characteristic and it has no effect. characteristic_enable_notification_succeeded() never gets called.

With all due respect, are you sure you are not referring to devices that send notifications without configuration or that have their own proprietary means of enabling them? I am using a standard pulse oximeter device and it clearly says in the spec that the client should configure notifications by writing to the CCCD.

In any case, omitting characteristics is a bug, regardless if needed for this specific case or not. It has the direct impact of making it impossible to enable and disable notifications, which in some cases is critical due to battery and other reasons. And of course, it a bit of opacity.

joliverr commented 5 years ago

Hello @Snevzor

it looks like you are the only one not having this issue.

You've already 'activated' the notifications by executing enable_notifications(). No need to write to the CCCD yourself. So what is the problem exactly?

Fyi, when a notification has been received the characteristic_value_updated() callback will be fired. This is the same callback that is used when reading a BLE characteristic value (which I personally don't like).

I found out that all functions related with the notifications are yet to be implemented.

image

@Snevzor How did you manage exactly to work this around? Could you provide us some examples to know how to work with the library.

Thanks in advance and we keep in touch until we solve this.

Snevzor commented 5 years ago

Hi @joliverr.

Check the documentation. These callbacks are fired. You need to subclass gatt.Device and then you can do whatever you want with those methods.

joliverr commented 5 years ago

Thank you @Snevzor , the problem has been solved.