@@ -44,7 +44,7 @@ BLECharacteristic::BLECharacteristic(const char* uuid, uint32_t properties) : BL
44
44
BLECharacteristic::BLECharacteristic (BLEUUID uuid, uint32_t properties) {
45
45
m_bleUUID = uuid;
46
46
m_handle = NULL_HANDLE;
47
- m_properties = (esp_gatt_char_prop_t ) 0 ;
47
+ m_properties = (esp_gatt_char_prop_t )0 ;
48
48
m_pCallbacks = nullptr ;
49
49
50
50
setBroadcastProperty ((properties & PROPERTY_BROADCAST) != 0 );
@@ -87,7 +87,7 @@ void BLECharacteristic::executeCreate(BLEService* pService) {
87
87
return ;
88
88
}
89
89
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.
91
91
92
92
ESP_LOGD (LOG_TAG, " Registering characteristic (esp_ble_gatts_add_char): uuid: %s, service: %s" ,
93
93
getUUID ().toString ().c_str (),
@@ -96,14 +96,6 @@ void BLECharacteristic::executeCreate(BLEService* pService) {
96
96
esp_attr_control_t control;
97
97
control.auto_rsp = ESP_GATT_RSP_BY_APP;
98
98
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
- */
107
99
108
100
esp_err_t errRc = ::esp_ble_gatts_add_char (
109
101
m_pService->getHandle (),
@@ -119,19 +111,6 @@ void BLECharacteristic::executeCreate(BLEService* pService) {
119
111
return ;
120
112
}
121
113
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
-
135
114
ESP_LOGD (LOG_TAG, " << executeCreate" );
136
115
} // executeCreate
137
116
@@ -216,7 +195,7 @@ void BLECharacteristic::handleGATTServerEvent(
216
195
esp_ble_gatts_cb_param_t * param) {
217
196
ESP_LOGD (LOG_TAG, " >> handleGATTServerEvent: %s" , BLEUtils::gattServerEventTypeToString (event).c_str ());
218
197
219
- switch (event) {
198
+ switch (event) {
220
199
// Events handled:
221
200
//
222
201
// ESP_GATTS_ADD_CHAR_EVT
@@ -246,7 +225,7 @@ void BLECharacteristic::handleGATTServerEvent(
246
225
} else {
247
226
m_value.cancel ();
248
227
}
249
-
228
+ // ???
250
229
esp_err_t errRc = ::esp_ble_gatts_send_response (
251
230
gatts_if,
252
231
param->write .conn_id ,
@@ -267,8 +246,15 @@ void BLECharacteristic::handleGATTServerEvent(
267
246
case ESP_GATTS_ADD_CHAR_EVT: {
268
247
if (getUUID ().equals (BLEUUID (param->add_char .char_uuid )) &&
269
248
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
+
272
258
}
273
259
break ;
274
260
} // ESP_GATTS_ADD_CHAR_EVT
@@ -357,7 +343,7 @@ void BLECharacteristic::handleGATTServerEvent(
357
343
//
358
344
// 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.
359
345
// 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.
361
347
// If we are sending 22 bytes exactly, we just send it BUT we will get a follow on request.
362
348
// If we are sending more than 22 bytes, we send the first 22 bytes and we will get a follow on request.
363
349
// 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(
367
353
//
368
354
// The following code has deliberately not been factored to make it fewer statements because this would cloud the
369
355
// the logic flow comprehension.
356
+ //
370
357
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) ;
374
361
if (param->read .need_rsp ) {
375
362
ESP_LOGD (LOG_TAG, " Sending a response (esp_ble_gatts_send_response)" );
376
363
esp_gatt_rsp_t rsp;
@@ -393,10 +380,6 @@ void BLECharacteristic::handleGATTServerEvent(
393
380
}
394
381
} else { // read.is_long == false
395
382
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
-
400
383
std::string value = m_value.getValue ();
401
384
402
385
if (value.length () + 1 > maxOffset) {
@@ -411,6 +394,10 @@ void BLECharacteristic::handleGATTServerEvent(
411
394
rsp.attr_value .offset = 0 ;
412
395
memcpy (rsp.attr_value .value , value.data (), rsp.attr_value .len );
413
396
}
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
+ }
414
401
}
415
402
rsp.attr_value .handle = param->read .handle ;
416
403
rsp.attr_value .auth_req = ESP_GATT_AUTH_REQ_NONE;
@@ -440,12 +427,13 @@ void BLECharacteristic::handleGATTServerEvent(
440
427
// - uint16_t conn_id – The connection used.
441
428
//
442
429
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 );
444
433
break ;
445
434
}
446
435
447
436
case ESP_GATTS_CONNECT_EVT: {
448
- m_semaphoreConfEvt.give ();
449
437
break ;
450
438
}
451
439
@@ -475,46 +463,9 @@ void BLECharacteristic::handleGATTServerEvent(
475
463
* @return N/A
476
464
*/
477
465
void 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
- }
516
466
517
- m_semaphoreConfEvt.wait (" indicate" );
467
+ ESP_LOGD (LOG_TAG, " >> indicate: length: %d" , m_value.getValue ().length ());
468
+ notify (false );
518
469
ESP_LOGD (LOG_TAG, " << indicate" );
519
470
} // indicate
520
471
@@ -525,7 +476,7 @@ void BLECharacteristic::indicate() {
525
476
* will not block; it is a fire and forget.
526
477
* @return N/A.
527
478
*/
528
- void BLECharacteristic::notify () {
479
+ void BLECharacteristic::notify (bool is_notification ) {
529
480
ESP_LOGD (LOG_TAG, " >> notify: length: %d" , m_value.getValue ().length ());
530
481
531
482
assert (getService () != nullptr );
@@ -541,31 +492,40 @@ void BLECharacteristic::notify() {
541
492
// Test to see if we have a 0x2902 descriptor. If we do, then check to see if notification is enabled
542
493
// and, if not, prevent the notification.
543
494
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
+ }
548
501
}
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
+ }
552
507
}
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
+ }
553
513
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" );
565
528
}
566
-
567
- m_semaphoreConfEvt.wait (" notify" );
568
-
569
529
ESP_LOGD (LOG_TAG, " << notify" );
570
530
} // Notify
571
531
@@ -580,9 +540,9 @@ void BLECharacteristic::notify() {
580
540
void BLECharacteristic::setBroadcastProperty (bool value) {
581
541
// ESP_LOGD(LOG_TAG, "setBroadcastProperty(%d)", value);
582
542
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);
584
544
} 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);
586
546
}
587
547
} // setBroadcastProperty
588
548
@@ -592,7 +552,7 @@ void BLECharacteristic::setBroadcastProperty(bool value) {
592
552
* @param [in] pCallbacks An instance of a callbacks structure used to define any callbacks for the characteristic.
593
553
*/
594
554
void 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);
596
556
m_pCallbacks = pCallbacks;
597
557
ESP_LOGD (LOG_TAG, " << setCallbacks" );
598
558
} // setCallbacks
@@ -622,9 +582,9 @@ void BLECharacteristic::setHandle(uint16_t handle) {
622
582
void BLECharacteristic::setIndicateProperty (bool value) {
623
583
// ESP_LOGD(LOG_TAG, "setIndicateProperty(%d)", value);
624
584
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);
626
586
} 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);
628
588
}
629
589
} // setIndicateProperty
630
590
@@ -636,9 +596,9 @@ void BLECharacteristic::setIndicateProperty(bool value) {
636
596
void BLECharacteristic::setNotifyProperty (bool value) {
637
597
// ESP_LOGD(LOG_TAG, "setNotifyProperty(%d)", value);
638
598
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);
640
600
} 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);
642
602
}
643
603
} // setNotifyProperty
644
604
@@ -650,9 +610,9 @@ void BLECharacteristic::setNotifyProperty(bool value) {
650
610
void BLECharacteristic::setReadProperty (bool value) {
651
611
// ESP_LOGD(LOG_TAG, "setReadProperty(%d)", value);
652
612
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);
654
614
} 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);
656
616
}
657
617
} // setReadProperty
658
618
@@ -683,7 +643,7 @@ void BLECharacteristic::setValue(uint8_t* data, size_t length) {
683
643
* @return N/A.
684
644
*/
685
645
void BLECharacteristic::setValue (std::string value) {
686
- setValue ((uint8_t *) (value.data ()), value.length ());
646
+ setValue ((uint8_t *)(value.data ()), value.length ());
687
647
} // setValue
688
648
689
649
void BLECharacteristic::setValue (uint16_t & data16) {
@@ -713,13 +673,13 @@ void BLECharacteristic::setValue(int& data32) {
713
673
714
674
void BLECharacteristic::setValue (float & data32) {
715
675
uint8_t temp[4 ];
716
- *((float *) temp) = data32;
676
+ *((float *)temp) = data32;
717
677
setValue (temp, 4 );
718
678
} // setValue
719
679
720
680
void BLECharacteristic::setValue (double & data64) {
721
681
uint8_t temp[8 ];
722
- *((double *) temp) = data64;
682
+ *((double *)temp) = data64;
723
683
setValue (temp, 8 );
724
684
} // setValue
725
685
@@ -731,9 +691,9 @@ void BLECharacteristic::setValue(double& data64) {
731
691
void BLECharacteristic::setWriteNoResponseProperty (bool value) {
732
692
// ESP_LOGD(LOG_TAG, "setWriteNoResponseProperty(%d)", value);
733
693
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);
735
695
} 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);
737
697
}
738
698
} // setWriteNoResponseProperty
739
699
@@ -745,9 +705,9 @@ void BLECharacteristic::setWriteNoResponseProperty(bool value) {
745
705
void BLECharacteristic::setWriteProperty (bool value) {
746
706
// ESP_LOGD(LOG_TAG, "setWriteProperty(%d)", value);
747
707
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);
749
709
} 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);
751
711
}
752
712
} // setWriteProperty
753
713
0 commit comments