Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 5137fc5

Browse filesBrowse files
romansavrulinme-no-dev
authored andcommitted
Ble notification/indication status and timeout (espressif#2998)
* add timed wait * Added Notification/Indication data and status callbacks * imply null-object pattern for BLE callback
1 parent 03066e4 commit 5137fc5
Copy full SHA for 5137fc5

File tree

Expand file treeCollapse file tree

4 files changed

+105
-12
lines changed
Filter options
Expand file treeCollapse file tree

4 files changed

+105
-12
lines changed

‎libraries/BLE/src/BLECharacteristic.cpp

Copy file name to clipboardExpand all lines: libraries/BLE/src/BLECharacteristic.cpp
+56-12Lines changed: 56 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222

2323
#define NULL_HANDLE (0xffff)
2424

25+
static BLECharacteristicCallbacks defaultCallback; //null-object-pattern
2526

2627
/**
2728
* @brief Construct a characteristic
@@ -40,7 +41,7 @@ BLECharacteristic::BLECharacteristic(BLEUUID uuid, uint32_t properties) {
4041
m_bleUUID = uuid;
4142
m_handle = NULL_HANDLE;
4243
m_properties = (esp_gatt_char_prop_t)0;
43-
m_pCallbacks = nullptr;
44+
m_pCallbacks = &defaultCallback;
4445

4546
setBroadcastProperty((properties & PROPERTY_BROADCAST) != 0);
4647
setReadProperty((properties & PROPERTY_READ) != 0);
@@ -220,9 +221,7 @@ void BLECharacteristic::handleGATTServerEvent(
220221
case ESP_GATTS_EXEC_WRITE_EVT: {
221222
if (param->exec_write.exec_write_flag == ESP_GATT_PREP_WRITE_EXEC) {
222223
m_value.commit();
223-
if (m_pCallbacks != nullptr) {
224-
m_pCallbacks->onWrite(this); // Invoke the onWrite callback handler.
225-
}
224+
m_pCallbacks->onWrite(this); // Invoke the onWrite callback handler.
226225
} else {
227226
m_value.cancel();
228227
}
@@ -307,7 +306,7 @@ void BLECharacteristic::handleGATTServerEvent(
307306
}
308307
} // Response needed
309308

310-
if (m_pCallbacks != nullptr && param->write.is_prep != true) {
309+
if (param->write.is_prep != true) {
311310
m_pCallbacks->onWrite(this); // Invoke the onWrite callback handler.
312311
}
313312
} // Match on handles.
@@ -378,9 +377,9 @@ void BLECharacteristic::handleGATTServerEvent(
378377
}
379378
} else { // read.is_long == false
380379

381-
if (m_pCallbacks != nullptr) { // If is.long is false then this is the first (or only) request to read data, so invoke the callback
382-
m_pCallbacks->onRead(this); // Invoke the read callback.
383-
}
380+
// If is.long is false then this is the first (or only) request to read data, so invoke the callback
381+
// Invoke the read callback.
382+
m_pCallbacks->onRead(this);
384383

385384
std::string value = m_value.getValue();
386385

@@ -480,10 +479,13 @@ void BLECharacteristic::notify(bool is_notification) {
480479
assert(getService() != nullptr);
481480
assert(getService()->getServer() != nullptr);
482481

482+
m_pCallbacks->onNotify(this); // Invoke the notify callback.
483+
483484
GeneralUtils::hexDump((uint8_t*)m_value.getValue().data(), m_value.getValue().length());
484485

485486
if (getService()->getServer()->getConnectedCount() == 0) {
486487
log_v("<< notify: No connected clients.");
488+
m_pCallbacks->onStatus(this, BLECharacteristicCallbacks::Status::ERROR_NO_CLIENT, 0);
487489
return;
488490
}
489491

@@ -494,12 +496,14 @@ void BLECharacteristic::notify(bool is_notification) {
494496
if(is_notification) {
495497
if (p2902 != nullptr && !p2902->getNotifications()) {
496498
log_v("<< notifications disabled; ignoring");
499+
m_pCallbacks->onStatus(this, BLECharacteristicCallbacks::Status::ERROR_NOTIFY_DISABLED, 0); // Invoke the notify callback.
497500
return;
498501
}
499502
}
500503
else{
501504
if (p2902 != nullptr && !p2902->getIndications()) {
502505
log_v("<< indications disabled; ignoring");
506+
m_pCallbacks->onStatus(this, BLECharacteristicCallbacks::Status::ERROR_INDICATE_DISABLED, 0); // Invoke the notify callback.
503507
return;
504508
}
505509
}
@@ -510,7 +514,7 @@ void BLECharacteristic::notify(bool is_notification) {
510514
}
511515

512516
size_t length = m_value.getValue().length();
513-
if(!is_notification)
517+
if(!is_notification) // is indication
514518
m_semaphoreConfEvt.take("indicate");
515519
esp_err_t errRc = ::esp_ble_gatts_send_indicate(
516520
getService()->getServer()->getGattsIf(),
@@ -519,10 +523,23 @@ void BLECharacteristic::notify(bool is_notification) {
519523
if (errRc != ESP_OK) {
520524
log_e("<< esp_ble_gatts_send_ %s: rc=%d %s",is_notification?"notify":"indicate", errRc, GeneralUtils::errorToString(errRc));
521525
m_semaphoreConfEvt.give();
526+
m_pCallbacks->onStatus(this, BLECharacteristicCallbacks::Status::ERROR_GATT, errRc); // Invoke the notify callback.
522527
return;
523528
}
524-
if(!is_notification)
525-
m_semaphoreConfEvt.wait("indicate");
529+
if(!is_notification){ // is indication
530+
if(!m_semaphoreConfEvt.timedWait("indicate", indicationTimeout)){
531+
m_pCallbacks->onStatus(this, BLECharacteristicCallbacks::Status::ERROR_INDICATE_TIMEOUT, 0); // Invoke the notify callback.
532+
} else {
533+
auto code = (esp_gatt_status_t) m_semaphoreConfEvt.value();
534+
if(code == ESP_GATT_OK) {
535+
m_pCallbacks->onStatus(this, BLECharacteristicCallbacks::Status::SUCCESS_INDICATE, code); // Invoke the notify callback.
536+
} else {
537+
m_pCallbacks->onStatus(this, BLECharacteristicCallbacks::Status::ERROR_INDICATE_FAILURE, code);
538+
}
539+
}
540+
} else {
541+
m_pCallbacks->onStatus(this, BLECharacteristicCallbacks::Status::SUCCESS_NOTIFY, 0); // Invoke the notify callback.
542+
}
526543
}
527544
log_v("<< notify");
528545
} // Notify
@@ -551,7 +568,11 @@ void BLECharacteristic::setBroadcastProperty(bool value) {
551568
*/
552569
void BLECharacteristic::setCallbacks(BLECharacteristicCallbacks* pCallbacks) {
553570
log_v(">> setCallbacks: 0x%x", (uint32_t)pCallbacks);
554-
m_pCallbacks = pCallbacks;
571+
if (pCallbacks != nullptr){
572+
m_pCallbacks = pCallbacks;
573+
} else {
574+
m_pCallbacks = &defaultCallback;
575+
}
555576
log_v("<< setCallbacks");
556577
} // setCallbacks
557578

@@ -754,4 +775,27 @@ void BLECharacteristicCallbacks::onWrite(BLECharacteristic* pCharacteristic) {
754775
log_d("BLECharacteristicCallbacks", "<< onWrite");
755776
} // onWrite
756777

778+
779+
/**
780+
* @brief Callback function to support a Notify request.
781+
* @param [in] pCharacteristic The characteristic that is the source of the event.
782+
*/
783+
void BLECharacteristicCallbacks::onNotify(BLECharacteristic* pCharacteristic) {
784+
log_d("BLECharacteristicCallbacks", ">> onNotify: default");
785+
log_d("BLECharacteristicCallbacks", "<< onNotify");
786+
} // onNotify
787+
788+
789+
/**
790+
* @brief Callback function to support a Notify/Indicate Status report.
791+
* @param [in] pCharacteristic The characteristic that is the source of the event.
792+
* @param [in] s Status of the notification/indication
793+
* @param [in] code Additional code of underlying errors
794+
*/
795+
void BLECharacteristicCallbacks::onStatus(BLECharacteristic* pCharacteristic, Status s, uint32_t code) {
796+
log_d("BLECharacteristicCallbacks", ">> onStatus: default");
797+
log_d("BLECharacteristicCallbacks", "<< onStatus");
798+
} // onStatus
799+
800+
757801
#endif /* CONFIG_BT_ENABLED */

‎libraries/BLE/src/BLECharacteristic.h

Copy file name to clipboardExpand all lines: libraries/BLE/src/BLECharacteristic.h
+15Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,8 @@ class BLECharacteristic {
9090
static const uint32_t PROPERTY_INDICATE = 1<<4;
9191
static const uint32_t PROPERTY_WRITE_NR = 1<<5;
9292

93+
static const uint32_t indicationTimeout = 1000;
94+
9395
private:
9496

9597
friend class BLEServer;
@@ -130,9 +132,22 @@ class BLECharacteristic {
130132
*/
131133
class BLECharacteristicCallbacks {
132134
public:
135+
typedef enum {
136+
SUCCESS_INDICATE,
137+
SUCCESS_NOTIFY,
138+
ERROR_INDICATE_DISABLED,
139+
ERROR_NOTIFY_DISABLED,
140+
ERROR_GATT,
141+
ERROR_NO_CLIENT,
142+
ERROR_INDICATE_TIMEOUT,
143+
ERROR_INDICATE_FAILURE
144+
}Status;
145+
133146
virtual ~BLECharacteristicCallbacks();
134147
virtual void onRead(BLECharacteristic* pCharacteristic);
135148
virtual void onWrite(BLECharacteristic* pCharacteristic);
149+
virtual void onNotify(BLECharacteristic* pCharacteristic);
150+
virtual void onStatus(BLECharacteristic* pCharacteristic, Status s, uint32_t code);
136151
};
137152
#endif /* CONFIG_BT_ENABLED */
138153
#endif /* COMPONENTS_CPP_UTILS_BLECHARACTERISTIC_H_ */

‎libraries/BLE/src/FreeRTOS.cpp

Copy file name to clipboardExpand all lines: libraries/BLE/src/FreeRTOS.cpp
+32Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,38 @@ uint32_t FreeRTOS::Semaphore::wait(std::string owner) {
7878
return m_value;
7979
} // wait
8080

81+
/**
82+
* @brief Wait for a semaphore to be released in a given period of time by trying to take it and
83+
* then releasing it again. The value associated with the semaphore can be taken by value() call after return
84+
* @param [in] owner A debug tag.
85+
* @param [in] timeoutMs timeout to wait in ms.
86+
* @return True if we took the semaphore within timeframe.
87+
*/
88+
bool FreeRTOS::Semaphore::timedWait(std::string owner, uint32_t timeoutMs) {
89+
log_v(">> wait: Semaphore waiting: %s for %s", toString().c_str(), owner.c_str());
90+
91+
if (m_usePthreads && timeoutMs != portMAX_DELAY) {
92+
assert(false); // We apparently don't have a timed wait for pthreads.
93+
}
94+
95+
auto ret = pdTRUE;
96+
97+
if (m_usePthreads) {
98+
pthread_mutex_lock(&m_pthread_mutex);
99+
} else {
100+
ret = xSemaphoreTake(m_semaphore, timeoutMs);
101+
}
102+
103+
if (m_usePthreads) {
104+
pthread_mutex_unlock(&m_pthread_mutex);
105+
} else {
106+
xSemaphoreGive(m_semaphore);
107+
}
108+
109+
log_v("<< wait: Semaphore %s released: %d", toString().c_str(), ret);
110+
return ret;
111+
} // wait
112+
81113

82114
FreeRTOS::Semaphore::Semaphore(std::string name) {
83115
m_usePthreads = false; // Are we using pThreads or FreeRTOS?

‎libraries/BLE/src/FreeRTOS.h

Copy file name to clipboardExpand all lines: libraries/BLE/src/FreeRTOS.h
+2Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,8 @@ class FreeRTOS {
4040
bool take(uint32_t timeoutMs, std::string owner = "<Unknown>");
4141
std::string toString();
4242
uint32_t wait(std::string owner = "<Unknown>");
43+
bool timedWait(std::string owner = "<Unknown>", uint32_t timeoutMs = portMAX_DELAY);
44+
uint32_t value(){ return m_value; };
4345

4446
private:
4547
SemaphoreHandle_t m_semaphore;

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.