Skip to content

Get CCCD with ATT_FIND_INFORMATION_REQ instead of ATT_READ_BY_TYPE_REQ #346

Open
@simonft

Description

@simonft

[Caveat to all of the below: I'm newish to Rust, and very new to embedded development and Bluetooth]

I've been debugging why communication with a third party peripheral has been hanging on a call to characteristic_by_uuid() when other Bluetooth stack implementations (Bluez, iOS, Android) work. I narrowed down the issue to get_characteristic_cccd() and have discovered the peripheral is not responding to ATT_READ_BY_TYPE_REQ when the attribute type is set to 0x2902 (the client characteristic configuration descriptor). It will respond when the attribute type is set to some others, like 0x2803 (Characteristic). If I'm reading the GATT spec correctly this is a trouble bug.

The spec says "Only those portions of the ATT protocol requests, responses, notifications or indications necessary to implement the mandatory or supported optional sub-procedures is required."

4.6.2 describes using ATT_READ_BY_TYPE_REQ with the type set to Characteristic to retrieve the characteristics in a service, which is what trouble is doing. But for discovering all characteristic descriptors (4.7.1) the spec uses ATT_FIND_INFORMATION_REQ, whereas trouble is using ATT_READ_BY_TYPE when it wants to find the Client Characteristic Configuration Descriptor. This makes sense in that trouble only cares about one type of descriptor at that point, but from my read the GATT spec doesn't provide a way to get just one type of descriptor.

My takeaway is that trouble should be changed to use ATT_FIND_INFORMATION_REQ to get the handle of the Client Characteristic Configuration, but that's based on my understanding that a server is only required to implement the sub-parts of the various PDUs that are actually used in the diagrams in the GATT spec, which might be incorrect.

FWIW, my read of the relevant Bluez code is that it uses ATT_FIND_INFORMATION_REQ unless there's only one possible place the CCCD could be, in which case it just returns that handle.

If all of the above is correct I'm happy to take a crack at a PR for this, though as noted in the caveat at the top I'm relatively new to multiple pieces of this.

And I don't think it's relevant, but in case it's helpful I'm using the latest commit from the main branch on an ESP32c3.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions