Skip to content

Commit 5736444

Browse files
committed
Changes, bugfixes, new features.
Add server and client multi connect feature.
1 parent 68411ff commit 5736444

15 files changed

+628
-488
lines changed

cpp_utils/BLECharacteristic.cpp

Lines changed: 74 additions & 114 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ BLECharacteristic::BLECharacteristic(const char* uuid, uint32_t properties) : BL
4444
BLECharacteristic::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
*/
477465
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-
}
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() {
580540
void 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
*/
594554
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);
596556
m_pCallbacks = pCallbacks;
597557
ESP_LOGD(LOG_TAG, "<< setCallbacks");
598558
} // setCallbacks
@@ -622,9 +582,9 @@ void BLECharacteristic::setHandle(uint16_t handle) {
622582
void 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) {
636596
void 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) {
650610
void 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
*/
685645
void BLECharacteristic::setValue(std::string value) {
686-
setValue((uint8_t*) (value.data()), value.length());
646+
setValue((uint8_t*)(value.data()), value.length());
687647
} // setValue
688648

689649
void BLECharacteristic::setValue(uint16_t& data16) {
@@ -713,13 +673,13 @@ void BLECharacteristic::setValue(int& data32) {
713673

714674
void BLECharacteristic::setValue(float& data32) {
715675
uint8_t temp[4];
716-
*((float*) temp) = data32;
676+
*((float*)temp) = data32;
717677
setValue(temp, 4);
718678
} // setValue
719679

720680
void 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) {
731691
void 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) {
745705
void 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

Comments
 (0)