[Suggestion] BLE GATT Server: Improve handling of read/write/notify
Posted: Wed Jan 11, 2017 8:08 am
When implementing a GATT server, the current handling of GATT read events seems rather convoluted and inefficient to me. In my understanding of Bluetooth LE, the value of a GATT characteristic is a value stored in the server. It only needs to change when the underlying data changes (e.g. a sensor value, status, etc.).
Currently, when a GATT client reads a characteristic, on the ESP32 GATT server, an ESP_GATTS_READ_EVT is propagated to the event handler. For the client to actually receive the characteristic value, the server needs to call esp_ble_gatts_send_response every time, even when the value did not change since the last read request.
I think an approach where the ESP API (or maybe even bluedroid already does?) provides a database for the GATT server, into which the current characteristic value is written to and read from. E.g. when the server wants to update a characteristic value, it can just call something like esp_ble_gatts_characteristic_value_update with a handle identifying the characteristic and connection and the updated value. Subsequent requests will then read the value that was last stored to the database.
In combination with the current handling of write and notify, the way read works is really odd: When a characteristic has read, write and notify permissions and notifications are enabled on the characteristic value, when the client issues a write, the written value will immediately be notified (makes sense), but an immediate subsequent read could return whatever value is being written using esp_ble_gatts_send_response.
The need to explicitly and manually send a response to a write request seems unnecessary as well, but maybe I just don't see the use case in that.
I would be really happy, if you would implement a proper characteristic data base and remove the need to explicitly send a response to read and write requests! I think having a look how e.g. the API of a Nordic Softdevice BLE stack looks may give some good ideas
Thank you for listening
Small addendum: After calling esp_ble_gatts_characteristic_value_update, further down the stack, in the consecutive functions that transfer the data from the ESP API to the underlying bluedroid stack, the function btc_to_bta_response will be called and will copy THE COMPLETE MAXIMUM supported length of 600 bytes of characteristic value to the structure to be relayed to BTA, even when the characteristic is merely 1 byte in length! The same thing seems to be done further down the stack... Seems a bit over the top to me?
Currently, when a GATT client reads a characteristic, on the ESP32 GATT server, an ESP_GATTS_READ_EVT is propagated to the event handler. For the client to actually receive the characteristic value, the server needs to call esp_ble_gatts_send_response every time, even when the value did not change since the last read request.
I think an approach where the ESP API (or maybe even bluedroid already does?) provides a database for the GATT server, into which the current characteristic value is written to and read from. E.g. when the server wants to update a characteristic value, it can just call something like esp_ble_gatts_characteristic_value_update with a handle identifying the characteristic and connection and the updated value. Subsequent requests will then read the value that was last stored to the database.
In combination with the current handling of write and notify, the way read works is really odd: When a characteristic has read, write and notify permissions and notifications are enabled on the characteristic value, when the client issues a write, the written value will immediately be notified (makes sense), but an immediate subsequent read could return whatever value is being written using esp_ble_gatts_send_response.
The need to explicitly and manually send a response to a write request seems unnecessary as well, but maybe I just don't see the use case in that.
I would be really happy, if you would implement a proper characteristic data base and remove the need to explicitly send a response to read and write requests! I think having a look how e.g. the API of a Nordic Softdevice BLE stack looks may give some good ideas
Thank you for listening
Small addendum: After calling esp_ble_gatts_characteristic_value_update, further down the stack, in the consecutive functions that transfer the data from the ESP API to the underlying bluedroid stack, the function btc_to_bta_response will be called and will copy THE COMPLETE MAXIMUM supported length of 600 bytes of characteristic value to the structure to be relayed to BTA, even when the characteristic is merely 1 byte in length! The same thing seems to be done further down the stack... Seems a bit over the top to me?