@@ -44,7 +44,7 @@ BLECharacteristic::BLECharacteristic(const char* uuid, uint32_t properties) : BL
4444BLECharacteristic::BLECharacteristic (BLEUUID uuid, uint32_t properties) {
4545 m_bleUUID = uuid;
4646 m_handle = NULL_HANDLE;
47- m_properties = (esp_gatt_char_prop_t ) 0 ;
47+ m_properties = (esp_gatt_char_prop_t )0 ;
4848 m_pCallbacks = nullptr ;
4949
5050 setBroadcastProperty ((properties & PROPERTY_BROADCAST) != 0 );
@@ -87,7 +87,7 @@ void BLECharacteristic::executeCreate(BLEService* pService) {
8787 return ;
8888 }
8989
90- m_pService = pService; // Save the service for to which this characteristic belongs.
90+ m_pService = pService; // Save the service to which this characteristic belongs.
9191
9292 ESP_LOGD (LOG_TAG, " Registering characteristic (esp_ble_gatts_add_char): uuid: %s, service: %s" ,
9393 getUUID ().toString ().c_str (),
@@ -96,14 +96,6 @@ void BLECharacteristic::executeCreate(BLEService* pService) {
9696 esp_attr_control_t control;
9797 control.auto_rsp = ESP_GATT_RSP_BY_APP;
9898
99- m_semaphoreCreateEvt.take (" executeCreate" );
100-
101- /*
102- esp_attr_value_t value;
103- value.attr_len = m_value.getLength();
104- value.attr_max_len = ESP_GATT_MAX_ATTR_LEN;
105- value.attr_value = m_value.getData();
106- */
10799
108100 esp_err_t errRc = ::esp_ble_gatts_add_char (
109101 m_pService->getHandle (),
@@ -119,19 +111,6 @@ void BLECharacteristic::executeCreate(BLEService* pService) {
119111 return ;
120112 }
121113
122- m_semaphoreCreateEvt.wait (" executeCreate" );
123-
124- // Now that we have registered the characteristic, we must also register all the descriptors associated with this
125- // characteristic. We iterate through each of those and invoke the registration call to register them with the
126- // ESP environment.
127-
128- BLEDescriptor* pDescriptor = m_descriptorMap.getFirst ();
129-
130- while (pDescriptor != nullptr ) {
131- pDescriptor->executeCreate (this );
132- pDescriptor = m_descriptorMap.getNext ();
133- } // End while
134-
135114 ESP_LOGD (LOG_TAG, " << executeCreate" );
136115} // executeCreate
137116
@@ -216,7 +195,7 @@ void BLECharacteristic::handleGATTServerEvent(
216195 esp_ble_gatts_cb_param_t * param) {
217196 ESP_LOGD (LOG_TAG, " >> handleGATTServerEvent: %s" , BLEUtils::gattServerEventTypeToString (event).c_str ());
218197
219- switch (event) {
198+ switch (event) {
220199 // Events handled:
221200 //
222201 // ESP_GATTS_ADD_CHAR_EVT
@@ -246,7 +225,7 @@ void BLECharacteristic::handleGATTServerEvent(
246225 } else {
247226 m_value.cancel ();
248227 }
249-
228+ // ???
250229 esp_err_t errRc = ::esp_ble_gatts_send_response (
251230 gatts_if,
252231 param->write .conn_id ,
@@ -267,8 +246,15 @@ void BLECharacteristic::handleGATTServerEvent(
267246 case ESP_GATTS_ADD_CHAR_EVT: {
268247 if (getUUID ().equals (BLEUUID (param->add_char .char_uuid )) &&
269248 getHandle () == param->add_char .attr_handle &&
270- getService ()->getHandle () == param->add_char .service_handle ) {
271- m_semaphoreCreateEvt.give ();
249+ getService ()->getHandle ()==param->add_char .service_handle ) {
250+
251+ // we have created characteristic, now we can create descriptors
252+ BLEDescriptor* pDescriptor = m_descriptorMap.getFirst ();
253+ while (pDescriptor != nullptr ) {
254+ pDescriptor->executeCreate (this );
255+ pDescriptor = m_descriptorMap.getNext ();
256+ } // End while
257+
272258 }
273259 break ;
274260 } // ESP_GATTS_ADD_CHAR_EVT
@@ -357,7 +343,7 @@ void BLECharacteristic::handleGATTServerEvent(
357343//
358344// If the is_long flag is set then this is a follow on from an original read and we will already have sent at least 22 bytes.
359345// If the is_long flag is not set then we need to check how much data we are going to send. If we are sending LESS than
360- // 22 bytes, then we "just" send it and that's the end of the story.
346+ // 22 bytes, then we "just" send it and thats the end of the story.
361347// If we are sending 22 bytes exactly, we just send it BUT we will get a follow on request.
362348// If we are sending more than 22 bytes, we send the first 22 bytes and we will get a follow on request.
363349// Because of follow on request processing, we need to maintain an offset of how much data we have already sent
@@ -367,10 +353,11 @@ void BLECharacteristic::handleGATTServerEvent(
367353//
368354// The following code has deliberately not been factored to make it fewer statements because this would cloud the
369355// the logic flow comprehension.
356+ //
370357
371- // TODO requires some more research to confirm that 512 is max PDU like in bluetooth specs
372- uint16_t maxOffset = BLEDevice::getMTU ( ) - 1 ;
373- if ( BLEDevice::getMTU () > 512 ) maxOffset = 512 ;
358+ // get mtu for peer device that we are sending read request to
359+ uint16_t maxOffset = getService ()-> getServer ()-> getPeerMTU (param-> read . conn_id ) - 1 ;
360+ ESP_LOGD (LOG_TAG, " mtu value: %d " , maxOffset) ;
374361 if (param->read .need_rsp ) {
375362 ESP_LOGD (LOG_TAG, " Sending a response (esp_ble_gatts_send_response)" );
376363 esp_gatt_rsp_t rsp;
@@ -393,10 +380,6 @@ void BLECharacteristic::handleGATTServerEvent(
393380 }
394381 } else { // read.is_long == false
395382
396- if (m_pCallbacks != nullptr ) { // If is.long is false then this is the first (or only) request to read data, so invoke the callback
397- m_pCallbacks->onRead (this ); // Invoke the read callback.
398- }
399-
400383 std::string value = m_value.getValue ();
401384
402385 if (value.length () + 1 > maxOffset) {
@@ -411,6 +394,10 @@ void BLECharacteristic::handleGATTServerEvent(
411394 rsp.attr_value .offset = 0 ;
412395 memcpy (rsp.attr_value .value , value.data (), rsp.attr_value .len );
413396 }
397+
398+ if (m_pCallbacks != nullptr ) { // If is.long is false then this is the first (or only) request to read data, so invoke the callback
399+ m_pCallbacks->onRead (this ); // Invoke the read callback.
400+ }
414401 }
415402 rsp.attr_value .handle = param->read .handle ;
416403 rsp.attr_value .auth_req = ESP_GATT_AUTH_REQ_NONE;
@@ -440,12 +427,13 @@ void BLECharacteristic::handleGATTServerEvent(
440427 // - uint16_t conn_id – The connection used.
441428 //
442429 case ESP_GATTS_CONF_EVT: {
443- m_semaphoreConfEvt.give ();
430+ ESP_LOGD (LOG_TAG, " m_handle = %d, conf->handle = %d" , m_handle, param->conf .handle );
431+ if (param->conf .conn_id == getService ()->getServer ()->getConnId ()) // && param->conf.handle == m_handle) // bug in esp-idf and not implemented in arduino yet
432+ m_semaphoreConfEvt.give (param->conf .status );
444433 break ;
445434 }
446435
447436 case ESP_GATTS_CONNECT_EVT: {
448- m_semaphoreConfEvt.give ();
449437 break ;
450438 }
451439
@@ -475,46 +463,9 @@ void BLECharacteristic::handleGATTServerEvent(
475463 * @return N/A
476464 */
477465void BLECharacteristic::indicate () {
478- ESP_LOGD (LOG_TAG, " >> indicate: length: %d" , m_value.getValue ().length ());
479-
480- assert (getService () != nullptr );
481- assert (getService ()->getServer () != nullptr );
482-
483- GeneralUtils::hexDump ((uint8_t *)m_value.getValue ().data (), m_value.getValue ().length ());
484-
485- if (getService ()->getServer ()->getConnectedCount () == 0 ) {
486- ESP_LOGD (LOG_TAG, " << indicate: No connected clients." );
487- return ;
488- }
489-
490- // Test to see if we have a 0x2902 descriptor. If we do, then check to see if indications are enabled
491- // and, if not, prevent the indication.
492-
493- BLE2902 *p2902 = (BLE2902*) getDescriptorByUUID ((uint16_t ) 0x2902 );
494- if (p2902 != nullptr && !p2902->getIndications ()) {
495- ESP_LOGD (LOG_TAG, " << indications disabled; ignoring" );
496- return ;
497- }
498-
499- if (m_value.getValue ().length () > (BLEDevice::getMTU () - 3 )) {
500- ESP_LOGI (LOG_TAG, " - Truncating to %d bytes (maximum indicate size)" , BLEDevice::getMTU () - 3 );
501- }
502-
503- size_t length = m_value.getValue ().length ();
504-
505- m_semaphoreConfEvt.take (" indicate" );
506-
507- esp_err_t errRc = ::esp_ble_gatts_send_indicate (
508- getService ()->getServer ()->getGattsIf (),
509- getService ()->getServer ()->getConnId (),
510- getHandle (), length, (uint8_t *)m_value.getValue ().data (), true ); // The need_confirm = true makes this an indication.
511-
512- if (errRc != ESP_OK) {
513- ESP_LOGE (LOG_TAG, " << esp_ble_gatts_send_indicate: rc=%d %s" , errRc, GeneralUtils::errorToString (errRc));
514- return ;
515- }
516466
517- m_semaphoreConfEvt.wait (" indicate" );
467+ ESP_LOGD (LOG_TAG, " >> indicate: length: %d" , m_value.getValue ().length ());
468+ notify (false );
518469 ESP_LOGD (LOG_TAG, " << indicate" );
519470} // indicate
520471
@@ -525,7 +476,7 @@ void BLECharacteristic::indicate() {
525476 * will not block; it is a fire and forget.
526477 * @return N/A.
527478 */
528- void BLECharacteristic::notify () {
479+ void BLECharacteristic::notify (bool is_notification ) {
529480 ESP_LOGD (LOG_TAG, " >> notify: length: %d" , m_value.getValue ().length ());
530481
531482 assert (getService () != nullptr );
@@ -541,31 +492,40 @@ void BLECharacteristic::notify() {
541492 // Test to see if we have a 0x2902 descriptor. If we do, then check to see if notification is enabled
542493 // and, if not, prevent the notification.
543494
544- BLE2902 *p2902 = (BLE2902*) getDescriptorByUUID ((uint16_t ) 0x2902 );
545- if (p2902 != nullptr && !p2902->getNotifications ()) {
546- ESP_LOGD (LOG_TAG, " << notifications disabled; ignoring" );
547- return ;
495+ BLE2902 *p2902 = (BLE2902*)getDescriptorByUUID ((uint16_t )0x2902 );
496+ if (is_notification) {
497+ if (p2902 != nullptr && !p2902->getNotifications ()) {
498+ ESP_LOGD (LOG_TAG, " << notifications disabled; ignoring" );
499+ return ;
500+ }
548501 }
549-
550- if (m_value.getValue ().length () > (BLEDevice::getMTU () - 3 )) {
551- ESP_LOGI (LOG_TAG, " - Truncating to %d bytes (maximum notify size)" , BLEDevice::getMTU () - 3 );
502+ else {
503+ if (p2902 != nullptr && !p2902->getIndications ()) {
504+ ESP_LOGD (LOG_TAG, " << indications disabled; ignoring" );
505+ return ;
506+ }
552507 }
508+ for (auto &myPair : getService ()->getServer ()->getPeerDevices (false )) {
509+ uint16_t _mtu = (myPair.second .mtu );
510+ if (m_value.getValue ().length () > _mtu - 3 ) {
511+ ESP_LOGW (LOG_TAG, " - Truncating to %d bytes (maximum notify size)" , _mtu - 3 );
512+ }
553513
554- size_t length = m_value.getValue ().length ();
555-
556- m_semaphoreConfEvt.take (" notify" );
557-
558- esp_err_t errRc = ::esp_ble_gatts_send_indicate (
559- getService ()->getServer ()->getGattsIf (),
560- getService ()->getServer ()->getConnId (),
561- getHandle (), length, (uint8_t *)m_value.getValue ().data (), false ); // The need_confirm = false makes this a notify.
562- if (errRc != ESP_OK) {
563- ESP_LOGE (LOG_TAG, " << esp_ble_gatts_send_indicate: rc=%d %s" , errRc, GeneralUtils::errorToString (errRc));
564- return ;
514+ size_t length = m_value.getValue ().length ();
515+ if (!is_notification)
516+ m_semaphoreConfEvt.take (" indicate" );
517+ esp_err_t errRc = ::esp_ble_gatts_send_indicate (
518+ getService ()->getServer ()->getGattsIf (),
519+ myPair.first ,
520+ getHandle (), length, (uint8_t *)m_value.getValue ().data (), !is_notification); // The need_confirm = false makes this a notify.
521+ if (errRc != ESP_OK) {
522+ ESP_LOGE (LOG_TAG, " << esp_ble_gatts_send_ %s: rc=%d %s" ,is_notification?" notify" :" indicate" , errRc, GeneralUtils::errorToString (errRc));
523+ m_semaphoreConfEvt.give ();
524+ return ;
525+ }
526+ if (!is_notification)
527+ m_semaphoreConfEvt.wait (" indicate" );
565528 }
566-
567- m_semaphoreConfEvt.wait (" notify" );
568-
569529 ESP_LOGD (LOG_TAG, " << notify" );
570530} // Notify
571531
@@ -580,9 +540,9 @@ void BLECharacteristic::notify() {
580540void BLECharacteristic::setBroadcastProperty (bool value) {
581541 // ESP_LOGD(LOG_TAG, "setBroadcastProperty(%d)", value);
582542 if (value) {
583- m_properties = (esp_gatt_char_prop_t ) (m_properties | ESP_GATT_CHAR_PROP_BIT_BROADCAST);
543+ m_properties = (esp_gatt_char_prop_t )(m_properties | ESP_GATT_CHAR_PROP_BIT_BROADCAST);
584544 } else {
585- m_properties = (esp_gatt_char_prop_t ) (m_properties & ~ESP_GATT_CHAR_PROP_BIT_BROADCAST);
545+ m_properties = (esp_gatt_char_prop_t )(m_properties & ~ESP_GATT_CHAR_PROP_BIT_BROADCAST);
586546 }
587547} // setBroadcastProperty
588548
@@ -592,7 +552,7 @@ void BLECharacteristic::setBroadcastProperty(bool value) {
592552 * @param [in] pCallbacks An instance of a callbacks structure used to define any callbacks for the characteristic.
593553 */
594554void BLECharacteristic::setCallbacks (BLECharacteristicCallbacks* pCallbacks) {
595- ESP_LOGD (LOG_TAG, " >> setCallbacks: 0x%x" , (uint32_t ) pCallbacks);
555+ ESP_LOGD (LOG_TAG, " >> setCallbacks: 0x%x" , (uint32_t )pCallbacks);
596556 m_pCallbacks = pCallbacks;
597557 ESP_LOGD (LOG_TAG, " << setCallbacks" );
598558} // setCallbacks
@@ -622,9 +582,9 @@ void BLECharacteristic::setHandle(uint16_t handle) {
622582void BLECharacteristic::setIndicateProperty (bool value) {
623583 // ESP_LOGD(LOG_TAG, "setIndicateProperty(%d)", value);
624584 if (value) {
625- m_properties = (esp_gatt_char_prop_t ) (m_properties | ESP_GATT_CHAR_PROP_BIT_INDICATE);
585+ m_properties = (esp_gatt_char_prop_t )(m_properties | ESP_GATT_CHAR_PROP_BIT_INDICATE);
626586 } else {
627- m_properties = (esp_gatt_char_prop_t ) (m_properties & ~ESP_GATT_CHAR_PROP_BIT_INDICATE);
587+ m_properties = (esp_gatt_char_prop_t )(m_properties & ~ESP_GATT_CHAR_PROP_BIT_INDICATE);
628588 }
629589} // setIndicateProperty
630590
@@ -636,9 +596,9 @@ void BLECharacteristic::setIndicateProperty(bool value) {
636596void BLECharacteristic::setNotifyProperty (bool value) {
637597 // ESP_LOGD(LOG_TAG, "setNotifyProperty(%d)", value);
638598 if (value) {
639- m_properties = (esp_gatt_char_prop_t ) (m_properties | ESP_GATT_CHAR_PROP_BIT_NOTIFY);
599+ m_properties = (esp_gatt_char_prop_t )(m_properties | ESP_GATT_CHAR_PROP_BIT_NOTIFY);
640600 } else {
641- m_properties = (esp_gatt_char_prop_t ) (m_properties & ~ESP_GATT_CHAR_PROP_BIT_NOTIFY);
601+ m_properties = (esp_gatt_char_prop_t )(m_properties & ~ESP_GATT_CHAR_PROP_BIT_NOTIFY);
642602 }
643603} // setNotifyProperty
644604
@@ -650,9 +610,9 @@ void BLECharacteristic::setNotifyProperty(bool value) {
650610void BLECharacteristic::setReadProperty (bool value) {
651611 // ESP_LOGD(LOG_TAG, "setReadProperty(%d)", value);
652612 if (value) {
653- m_properties = (esp_gatt_char_prop_t ) (m_properties | ESP_GATT_CHAR_PROP_BIT_READ);
613+ m_properties = (esp_gatt_char_prop_t )(m_properties | ESP_GATT_CHAR_PROP_BIT_READ);
654614 } else {
655- m_properties = (esp_gatt_char_prop_t ) (m_properties & ~ESP_GATT_CHAR_PROP_BIT_READ);
615+ m_properties = (esp_gatt_char_prop_t )(m_properties & ~ESP_GATT_CHAR_PROP_BIT_READ);
656616 }
657617} // setReadProperty
658618
@@ -683,7 +643,7 @@ void BLECharacteristic::setValue(uint8_t* data, size_t length) {
683643 * @return N/A.
684644 */
685645void BLECharacteristic::setValue (std::string value) {
686- setValue ((uint8_t *) (value.data ()), value.length ());
646+ setValue ((uint8_t *)(value.data ()), value.length ());
687647} // setValue
688648
689649void BLECharacteristic::setValue (uint16_t & data16) {
@@ -713,13 +673,13 @@ void BLECharacteristic::setValue(int& data32) {
713673
714674void BLECharacteristic::setValue (float & data32) {
715675 uint8_t temp[4 ];
716- *((float *) temp) = data32;
676+ *((float *)temp) = data32;
717677 setValue (temp, 4 );
718678} // setValue
719679
720680void BLECharacteristic::setValue (double & data64) {
721681 uint8_t temp[8 ];
722- *((double *) temp) = data64;
682+ *((double *)temp) = data64;
723683 setValue (temp, 8 );
724684} // setValue
725685
@@ -731,9 +691,9 @@ void BLECharacteristic::setValue(double& data64) {
731691void BLECharacteristic::setWriteNoResponseProperty (bool value) {
732692 // ESP_LOGD(LOG_TAG, "setWriteNoResponseProperty(%d)", value);
733693 if (value) {
734- m_properties = (esp_gatt_char_prop_t ) (m_properties | ESP_GATT_CHAR_PROP_BIT_WRITE_NR);
694+ m_properties = (esp_gatt_char_prop_t )(m_properties | ESP_GATT_CHAR_PROP_BIT_WRITE_NR);
735695 } else {
736- m_properties = (esp_gatt_char_prop_t ) (m_properties & ~ESP_GATT_CHAR_PROP_BIT_WRITE_NR);
696+ m_properties = (esp_gatt_char_prop_t )(m_properties & ~ESP_GATT_CHAR_PROP_BIT_WRITE_NR);
737697 }
738698} // setWriteNoResponseProperty
739699
@@ -745,9 +705,9 @@ void BLECharacteristic::setWriteNoResponseProperty(bool value) {
745705void BLECharacteristic::setWriteProperty (bool value) {
746706 // ESP_LOGD(LOG_TAG, "setWriteProperty(%d)", value);
747707 if (value) {
748- m_properties = (esp_gatt_char_prop_t ) (m_properties | ESP_GATT_CHAR_PROP_BIT_WRITE);
708+ m_properties = (esp_gatt_char_prop_t )(m_properties | ESP_GATT_CHAR_PROP_BIT_WRITE);
749709 } else {
750- m_properties = (esp_gatt_char_prop_t ) (m_properties & ~ESP_GATT_CHAR_PROP_BIT_WRITE);
710+ m_properties = (esp_gatt_char_prop_t )(m_properties & ~ESP_GATT_CHAR_PROP_BIT_WRITE);
751711 }
752712} // setWriteProperty
753713
0 commit comments