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) {
4041m_bleUUID = uuid;
4142m_handle = NULL_HANDLE;
4243m_properties = (esp_gatt_char_prop_t )0 ;
43- m_pCallbacks = nullptr ;
44+ m_pCallbacks = &defaultCallback ;
4445
4546setBroadcastProperty ((properties & PROPERTY_BROADCAST) != 0 );
4647setReadProperty ((properties & PROPERTY_READ) != 0 );
@@ -220,9 +221,7 @@ void BLECharacteristic::handleGATTServerEvent(
220221case ESP_GATTS_EXEC_WRITE_EVT: {
221222if (param->exec_write .exec_write_flag == ESP_GATT_PREP_WRITE_EXEC) {
222223m_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 {
227226m_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 ) {
311310m_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
385384std::string value = m_value.getValue ();
386385
@@ -480,10 +479,13 @@ void BLECharacteristic::notify(bool is_notification) {
480479assert (getService () != nullptr );
481480assert (getService ()->getServer () != nullptr );
482481
482+ m_pCallbacks->onNotify (this ); // Invoke the notify callback.
483+
483484GeneralUtils::hexDump ((uint8_t *)m_value.getValue ().data (), m_value.getValue ().length ());
484485
485486if (getService ()->getServer ()->getConnectedCount () == 0 ) {
486487log_v (" << notify: No connected clients." );
488+ m_pCallbacks->onStatus (this , BLECharacteristicCallbacks::Status::ERROR_NO_CLIENT, 0 );
487489return ;
488490}
489491
@@ -494,12 +496,14 @@ void BLECharacteristic::notify(bool is_notification) {
494496if (is_notification) {
495497if (p2902 != nullptr && !p2902->getNotifications ()) {
496498log_v (" << notifications disabled; ignoring" );
499+ m_pCallbacks->onStatus (this , BLECharacteristicCallbacks::Status::ERROR_NOTIFY_DISABLED, 0 ); // Invoke the notify callback.
497500return ;
498501}
499502}
500503else {
501504if (p2902 != nullptr && !p2902->getIndications ()) {
502505log_v (" << indications disabled; ignoring" );
506+ m_pCallbacks->onStatus (this , BLECharacteristicCallbacks::Status::ERROR_INDICATE_DISABLED, 0 ); // Invoke the notify callback.
503507return ;
504508}
505509}
@@ -510,7 +514,7 @@ void BLECharacteristic::notify(bool is_notification) {
510514}
511515
512516size_t length = m_value.getValue ().length ();
513- if (!is_notification)
517+ if (!is_notification) // is indication
514518m_semaphoreConfEvt.take (" indicate" );
515519esp_err_t errRc = ::esp_ble_gatts_send_indicate (
516520getService ()->getServer ()->getGattsIf (),
@@ -519,10 +523,23 @@ void BLECharacteristic::notify(bool is_notification) {
519523if (errRc != ESP_OK) {
520524log_e (" << esp_ble_gatts_send_ %s: rc=%d %s" ,is_notification?" notify" :" indicate" , errRc, GeneralUtils::errorToString (errRc));
521525m_semaphoreConfEvt.give ();
526+ m_pCallbacks->onStatus (this , BLECharacteristicCallbacks::Status::ERROR_GATT, errRc); // Invoke the notify callback.
522527return ;
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}
527544log_v (" << notify" );
528545} // Notify
@@ -551,7 +568,11 @@ void BLECharacteristic::setBroadcastProperty(bool value) {
551568 */
552569void BLECharacteristic::setCallbacks (BLECharacteristicCallbacks* pCallbacks) {
553570log_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+ }
555576log_v (" << setCallbacks" );
556577} // setCallbacks
557578
@@ -754,4 +775,27 @@ void BLECharacteristicCallbacks::onWrite(BLECharacteristic* pCharacteristic) {
754775log_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 */
0 commit comments