Skip to content

Commit 360e04f

Browse files
JimmyDurandWesolowskiJimmy Durand Wesolowski
and
Jimmy Durand Wesolowski
authored
Fixing BLE GATT Characteristic notification and Characteristic Descriptor read (#4464)
* BLERemoteChar: fix descriptor 2902 write for characteristic notifications When registering a notification on a characteristic, the 2902 descriptor (CCCD) value is set to 1 (or 2 for indication). According to the BLUETOOTH CORE SPECIFICATION Version 5.2, Revision Date 2019-12-31, section 4.12.3 "Write Characteristic Descriptors" (page 1588), the characteristic descriptor write must expect a response. Currently, the descriptor write is performed without expecting a reponse, which prevents the notification to be functional with some BLE stacks. This commit modify the write to expect the response. Signed-off-by: Jimmy Durand Wesolowski <[email protected]> * BLERemoteChar: forward GATT client event to characteristic descriptors This commits prevents a permanent wait when calling BLERemoteDescriptor readValue function, on the m_semaphoreReadDescrEvt semaphore. ESP32 BLE stack calls to remote characteristic - notification, - value read - value write and remote characteristic descriptor - value read are asynchronous. When such a call is performed by this library, a semaphore is taken prior to the BLE stack read or write operation, and waited on after it. Releasing the semaphore is done by the characteristic event handling function (gattClientEventHandler), when the appropriate event is received. However, the characteristic descriptor events are discarded, and the value read semaphore is never released. This commits forwards the GATT client events from the remote characteristic down to their remote characteristic descriptor, and implements their event handling. Adding a semaphore for the remote characteristic descriptor value write will be done in a separate commit. Signed-off-by: Jimmy Durand Wesolowski <[email protected]> * BLERemoteDescriptor: add semaphore to characteristic descriptor write This adds a semaphore to characteristic descriptor value write, to mimic the value read function, and to ensure completion of the operation before we carry on. Signed-off-by: Jimmy Durand Wesolowski <[email protected]> Co-authored-by: Jimmy Durand Wesolowski <[email protected]>
1 parent 57145ad commit 360e04f

File tree

3 files changed

+32
-3
lines changed

3 files changed

+32
-3
lines changed

Diff for: libraries/BLE/src/BLERemoteCharacteristic.cpp

+9-2
Original file line numberDiff line numberDiff line change
@@ -237,6 +237,13 @@ void BLERemoteCharacteristic::gattClientEventHandler(esp_gattc_cb_event_t event,
237237
break;
238238
} // ESP_GATTC_WRITE_CHAR_EVT
239239

240+
case ESP_GATTC_READ_DESCR_EVT:
241+
case ESP_GATTC_WRITE_DESCR_EVT:
242+
for (auto &myPair : m_descriptorMap) {
243+
myPair.second->gattClientEventHandler(
244+
event, gattc_if, evtParam);
245+
}
246+
break;
240247

241248
default:
242249
break;
@@ -468,7 +475,7 @@ void BLERemoteCharacteristic::registerForNotify(notify_callback notifyCallback,
468475
if(!notifications) val[0] = 0x02;
469476
BLERemoteDescriptor* desc = getDescriptor(BLEUUID((uint16_t)0x2902));
470477
if (desc != nullptr)
471-
desc->writeValue(val, 2);
478+
desc->writeValue(val, 2, true);
472479
} // End Register
473480
else { // If we weren't passed a callback function, then this is an unregistration.
474481
esp_err_t errRc = ::esp_ble_gattc_unregister_for_notify(
@@ -484,7 +491,7 @@ void BLERemoteCharacteristic::registerForNotify(notify_callback notifyCallback,
484491
uint8_t val[] = {0x00, 0x00};
485492
BLERemoteDescriptor* desc = getDescriptor((uint16_t)0x2902);
486493
if (desc != nullptr)
487-
desc->writeValue(val, 2);
494+
desc->writeValue(val, 2, true);
488495
} // End Unregister
489496

490497
m_semaphoreRegForNotifyEvt.wait("registerForNotify");

Diff for: libraries/BLE/src/BLERemoteDescriptor.cpp

+21
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,23 @@ BLEUUID BLERemoteDescriptor::getUUID() {
4949
return m_uuid;
5050
} // getUUID
5151

52+
void BLERemoteDescriptor::gattClientEventHandler(esp_gattc_cb_event_t event, esp_gatt_if_t gattc_if, esp_ble_gattc_cb_param_t* evtParam) {
53+
switch(event) {
54+
case ESP_GATTC_READ_DESCR_EVT:
55+
if (evtParam->read.handle != getHandle())
56+
break;
57+
m_semaphoreReadDescrEvt.give();
58+
break;
59+
60+
case ESP_GATTC_WRITE_DESCR_EVT:
61+
if (evtParam->write.handle != getHandle())
62+
break;
63+
m_semaphoreWriteDescrEvt.give();
64+
break;
65+
default:
66+
break;
67+
}
68+
}
5269

5370
std::string BLERemoteDescriptor::readValue() {
5471
log_v(">> readValue: %s", toString().c_str());
@@ -137,6 +154,8 @@ void BLERemoteDescriptor::writeValue(uint8_t* data, size_t length, bool response
137154
return;
138155
}
139156

157+
m_semaphoreWriteDescrEvt.take("writeValue");
158+
140159
esp_err_t errRc = ::esp_ble_gattc_write_char_descr(
141160
m_pRemoteCharacteristic->getRemoteService()->getClient()->getGattcIf(),
142161
m_pRemoteCharacteristic->getRemoteService()->getClient()->getConnId(),
@@ -149,6 +168,8 @@ void BLERemoteDescriptor::writeValue(uint8_t* data, size_t length, bool response
149168
if (errRc != ESP_OK) {
150169
log_e("esp_ble_gattc_write_char_descr: %d", errRc);
151170
}
171+
172+
m_semaphoreWriteDescrEvt.wait("writeValue");
152173
log_v("<< writeValue");
153174
} // writeValue
154175

Diff for: libraries/BLE/src/BLERemoteDescriptor.h

+2-1
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ class BLERemoteDescriptor {
3535
void writeValue(std::string newValue, bool response = false);
3636
void writeValue(uint8_t newValue, bool response = false);
3737
void setAuth(esp_gatt_auth_req_t auth);
38-
38+
void gattClientEventHandler(esp_gattc_cb_event_t event, esp_gatt_if_t gattc_if, esp_ble_gattc_cb_param_t* evtParam);
3939

4040
private:
4141
friend class BLERemoteCharacteristic;
@@ -49,6 +49,7 @@ class BLERemoteDescriptor {
4949
std::string m_value; // Last received value of the descriptor.
5050
BLERemoteCharacteristic* m_pRemoteCharacteristic; // Reference to the Remote characteristic of which this descriptor is associated.
5151
FreeRTOS::Semaphore m_semaphoreReadDescrEvt = FreeRTOS::Semaphore("ReadDescrEvt");
52+
FreeRTOS::Semaphore m_semaphoreWriteDescrEvt = FreeRTOS::Semaphore("WriteDescrEvt");
5253
esp_gatt_auth_req_t m_auth;
5354

5455

0 commit comments

Comments
 (0)