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

GATT Server API for decriptors is incompatable with BLE spec (IDFGH-14165) #14967

Closed
3 tasks done
leonid-galperin opened this issue Dec 2, 2024 · 5 comments
Closed
3 tasks done
Assignees
Labels
Awaiting Response awaiting a response from the author Resolution: Done Issue is done internally Status: Done Issue is done internally

Comments

@leonid-galperin
Copy link

Answers checklist.

  • I have read the documentation ESP-IDF Programming Guide and the issue is not addressed there.
  • I have updated my IDF branch (master or release) to the latest version and checked that the issue is present there.
  • I have searched the issue tracker for a similar issue and not found a similar issue.

General issue report

Hello,

According to BLE spec (e.g. Bluetooth® Core Specification Version 5.4)
GATT services characteristics and descriptors have have very clear tree structure as shown on page 37:
image
Services have characteristics and characteristics have descriptors.

The following ESP32 calls violate this structure:

  • esp_err_t esp_ble_gatts_add_char_descr(uint16_t service_handle, esp_bt_uuid_t *descr_uuid, esp_gatt_perm_t perm, esp_attr_value_t *char_descr_val, esp_attr_control_t *control)
    Accepts service handle while have to accept characteristic handle. Even function names says that descriptor belongs to characteristic, not service

  • struct gatts_add_char_descr_evt_param have field service_handle instead of characteristic handle

Suche vilation prohibits having same decriptor id within different characteristics.
E.g. having CCCD for each characteristics within same service

@espressif-bot espressif-bot added the Status: Opened Issue is new label Dec 2, 2024
@github-actions github-actions bot changed the title GATT Server API for decriptors is incompatable with BLE spec GATT Server API for decriptors is incompatable with BLE spec (IDFGH-14165) Dec 2, 2024
@leonid-galperin
Copy link
Author

After spending day in looking for possible quick fix I found that both characteristics and descriptors are stored in "service database" and treated equally as service attributes.
This is the main reason there can not be multiple descriptors with same UUID within the same service even though they related to different characteristics.
Will try to fix it locally fro my self but hope this misleading architecture will be fixed officially in near future.

@esp-zhp
Copy link
Collaborator

esp-zhp commented Dec 3, 2024

Thank you for reporting this issue.

Currently, Bluedroid supports two methods for creating GATT server databases:

  1. Native Method
    This is the approach you are currently using, which is consistent with the example found at esp-idf/examples/bluetooth/bluedroid/ble/gatt_server.

  2. Recommended Method
    This method involves defining a GATT server using a table-like data structure, allowing you to clearly add descriptors. It supports multiple descriptors per characteristic and multiple characteristics per service.
    You can refer to the example at:
    esp-idf/examples/bluetooth/bluedroid/ble/gatt_server_service_table


Addressing Your Concern:

You pointed out that the native method has issues with the following aspects:

  • The function esp_ble_gatts_add_char_descr(uint16_t service_handle, ...) accepts a service_handle but should accept a characteristic_handle.
  • The struct gatts_add_char_descr_evt_param contains a service_handle instead of a characteristic_handle.

Let me clarify why using the service_handle is intentional and not problematic:

In the database, services, characteristics, and descriptors are all treated as attributes, and Bluedroid organizes these attributes sequentially during database creation. Here’s how it works:

  1. Create Service:
    The esp_ble_gatts_create_service function assigns an attribute index for the service.

  2. Add Characteristic:
    The esp_ble_gatts_add_char function adds the characteristic, assigning an attribute index sequentially after the service.

  3. Add Descriptors:
    The esp_ble_gatts_add_char_descr function adds descriptors, assigning their attribute indices sequentially after the characteristics.

The service_handle is used to locate the service to which the descriptor belongs. The exact placement of the descriptor (i.e., which characteristic it is associated with) is determined by the sequence in which attributes are added.

You can verify the attribute hierarchy and sequence using the esp_ble_gatts_show_local_database API.


If you require multiple descriptors or characteristics within the same service, the database creation process will handle this seamlessly, as each attribute is assigned a unique index (or handle) sequentially.

If you still have concerns or require further clarification, feel free to reach out. We're here to help!

@espressif-bot espressif-bot added Status: In Progress Work is in progress and removed Status: Opened Issue is new labels Dec 3, 2024
@leonid-galperin
Copy link
Author

Thansk for reply
I'm aware that if descriptors are being added by esp_ble_gatts_add_char_descr immediately after adding characteristic by esp_ble_gatts_add_char then it sort of added to the last characteristic. Even though I see it as not the best code architecture I'm fine with it.

The problem I'm addressing is the follows.
Let's say I want to have this serivce structure:

  • Service 0x180f
    • Characteristic 0x2a19
      • Descriptor 0x2902
  • Service 0x181c
    • Characteristic 0x2000
      • Descriptor 0x2902
    • Characteristic 0x2001
      • Descriptor 0x2902
    • Characteristic 0x2002
      • Descriptor 0x2902
    • Characteristic 0x2003
      • Descriptor 0x2902
  • Service 0x180a
    • Characteristic 0x2a00
      • Descriptor 0x2902

To create it I call esp_ble_gatts_create_service, esp_ble_gatts_start_service, esp_ble_gatts_add_char and esp_ble_gatts_add_char_descr and get the service three exactly as I described above.

Now I wait for ESP_GATTS_ADD_CHAR_EVT and ESP_GATTS_ADD_CHAR_DESCR_EVT to save attribute handles for further handling of read/write events.

Let's say I receive ESP_GATTS_ADD_CHAR_DESCR_EVT:

param->add_char_descr.descr_uuid.uuid.uuid16: 0x2902
param->add_char_descr.service_handle: 0x28
param->add_char_descr.attr_handle: 0x2b

How do I distiguish to which of my characteristics (0x2000, 0x2001, 0x2002 or 0x2002) this descriptor was added?

Later, when ESP_GATTS_READ_EVT/ESP_GATTS_READ_EVT arrives I have only attribute handle and need to find which one of all attributes it is by search through saved handles, but I can't because of the previous problem.

If you find that "sequential adding" concept fine and don't want to chage esp_ble_gatts_add_char_descr signature could you at least add parent characteristic uuid or handle to gatts_add_char_descr_evt_param so that added descritpr can be bound to characteristic as it should?

@esp-zhp
Copy link
Collaborator

esp-zhp commented Dec 4, 2024

If you're unsure how to manage this sequence, I recommend using a table-based approach to create your database.

@esp-zhp
Copy link
Collaborator

esp-zhp commented Dec 10, 2024

@leonid-galperin Does the table-based approach address your issue?

@espressif-bot espressif-bot added Status: Done Issue is done internally Resolution: Done Issue is done internally and removed Status: In Progress Work is in progress labels Dec 16, 2024
@Alvin1Zhang Alvin1Zhang added the Awaiting Response awaiting a response from the author label Dec 17, 2024
@Alvin1Zhang Alvin1Zhang closed this as not planned Won't fix, can't repro, duplicate, stale Jan 9, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Awaiting Response awaiting a response from the author Resolution: Done Issue is done internally Status: Done Issue is done internally
Projects
None yet
Development

No branches or pull requests

4 participants