Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adding a descriptor to the Characteristic sequence is problematic #460

Open
yexiyue opened this issue Jul 23, 2024 · 1 comment
Open

Adding a descriptor to the Characteristic sequence is problematic #460

yexiyue opened this issue Jul 23, 2024 · 1 comment

Comments

@yexiyue
Copy link

yexiyue commented Jul 23, 2024

Adding a descriptor to the Characteristic sequence is problematic

  • MCU: esp32c3
  • OS: macos
  • ESP-IDF: v5.2.2

self.gatts.add_characteristic(
service_handle,
&GattCharacteristic {
uuid: BtUuid::uuid128(RECV_CHARACTERISTIC_UUID),
permissions: enum_set!(Permission::Write),
properties: enum_set!(Property::Write),
max_len: 200, // Max recv data
auto_rsp: AutoResponse::ByApp,
},
&[],
)?;
self.gatts.add_characteristic(
service_handle,
&GattCharacteristic {
uuid: BtUuid::uuid128(IND_CHARACTERISTIC_UUID),
permissions: enum_set!(Permission::Write | Permission::Read),
properties: enum_set!(Property::Indicate),
max_len: 200, // Mac iondicate data
auto_rsp: AutoResponse::ByApp,
},
&[],
)?;

When I swapped the order of adding these two characteristics, I found that CCCD was added to the last characteristic and not to the characteristic with Property Indicator

self.gatts.add_descriptor(
service_handle,
&GattDescriptor {
uuid: BtUuid::uuid16(0x2902), // CCCD
permissions: enum_set!(Permission::Read | Permission::Write),
},
)?;

@Vollbrecht
Copy link
Collaborator

The underlying problem here is the esp-idf descriptor api. Essentially as you build the service up on the fly from the overall service, to its corresponding characteristics and there added descriptors you get a complete service description.

This service description needs to follow a fixed form and you cannot reallocate space in between the handles once you given them out. So its essentially building the stack up from each call you make, in the specific order you call either esp_ble_gatts_add_cha or esp_ble_gatts_add_char_descr.

So in its current form the correct way is to add characteristics and then directly follow the next calls with the descriptors you want to add the that specific characteristic, and then again calling the next characteristic you want to add and so forth.

You don't need to wait in the eventloop for char A to be created to be able to call adding descriptor A or char B. The eventloop will only help you here to get the actual handle for everything you added without manually traversing the complete service database.

So after you created the service you can have one place where you describe all char/descriptors like the following

self.gatts.add_characteristic(..)?;
self.gatts.add_descriptor(..)?;
self.gatts.add_descriptor(..)?;
self.gatts.add_characteristic()?;

With using esp_ble_gatts_add_char_descr there is no other way as the api itself doesn't accept a parameter to what char the descriptor actually should be added, it only wants to know to which overall service its gets added.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
Status: Todo
Development

No branches or pull requests

2 participants