From 5c82533d069f6754ba4ce3e70dc29bb5f95fbc2e Mon Sep 17 00:00:00 2001 From: George Beckstein Date: Tue, 6 Oct 2020 18:44:41 -0400 Subject: [PATCH 1/5] Enabled getting an implicitly-created CCCD through GattCharacteristic::getDescriptor --- .../include/ble/gatt/GattCharacteristic.h | 44 ++++++++++++++++++- .../source/cordio/source/GattServerImpl.cpp | 17 +++++++ 2 files changed, 59 insertions(+), 2 deletions(-) diff --git a/connectivity/FEATURE_BLE/include/ble/gatt/GattCharacteristic.h b/connectivity/FEATURE_BLE/include/ble/gatt/GattCharacteristic.h index 2e0510854b..3b26255834 100644 --- a/connectivity/FEATURE_BLE/include/ble/gatt/GattCharacteristic.h +++ b/connectivity/FEATURE_BLE/include/ble/gatt/GattCharacteristic.h @@ -1429,6 +1429,12 @@ public: GattCharacteristic(const GattCharacteristic &) = delete; GattCharacteristic& operator=(const GattCharacteristic &) = delete; + ~GattCharacteristic() { + if(_implicit_cccd != nullptr) { + delete _implicit_cccd; + } + } + public: /** @@ -1714,7 +1720,7 @@ public: */ uint8_t getDescriptorCount() const { - return _descriptorCount; + return (_implicit_cccd == nullptr? _descriptorCount : _descriptorCount+1); } /** @@ -1750,16 +1756,40 @@ public: * * @return A pointer the requested descriptor if @p index is within the * range of the descriptor array or nullptr otherwise. + * + * @note if this characteristic has an implicitly-created CCCD this + * descriptor will be available at the highest index + * (ie: return of getDescriptorCount() - 1) */ GattAttribute *getDescriptor(uint8_t index) { - if (index >= _descriptorCount) { + + if(index == _descriptorCount) { + // If _implicit_cccd is nullptr, we want to return that anyway + return _implicit_cccd; + } + else if (index > _descriptorCount) { return nullptr; } return _descriptors[index]; } + /** + * Sets this GattCharacteristic's implicitly-created CCCD, if + * applicable. + * + * @note once this is called, the pointed-to GattAttribute + * is owned by this GattCharacteristic and will be deleted + * during this object's destructor + * + * @note this is an internal function and should not be called + * by the application + */ + void _setImplicitCCCD(GattAttribute *implicit_cccd) { + _implicit_cccd = implicit_cccd; + } + private: /** @@ -1783,6 +1813,16 @@ private: */ uint8_t _descriptorCount; + /** + * Pointer to characteristic's implicit CCCD, if applicable + * + * @note this is only populated if the stack creates an implicit CCCD + * for this GattCharacteristic. If the descriptors array passed into + * the constructor includes a CCCD this field is left as nullptr to + * indicate the CCCD was explicitly created. + */ + GattAttribute* _implicit_cccd; + /** * The registered callback handler for read authorization reply. */ diff --git a/connectivity/FEATURE_BLE/source/cordio/source/GattServerImpl.cpp b/connectivity/FEATURE_BLE/source/cordio/source/GattServerImpl.cpp index a7ca14d567..e1bc17eccf 100644 --- a/connectivity/FEATURE_BLE/source/cordio/source/GattServerImpl.cpp +++ b/connectivity/FEATURE_BLE/source/cordio/source/GattServerImpl.cpp @@ -588,6 +588,23 @@ ble_error_t GattServer::insert_cccd( cccds[cccd_cnt].secLevel = characteristic->getUpdateSecurityRequirement().value(); cccd_handles[cccd_cnt] = characteristic->getValueAttribute().getHandle(); + /** + * Set the characteristic's implicitly-created CCCD + * + * Ownership is passed to the GattCharacteristic + */ + GattAttribute* implicit_cccd = new GattAttribute( + CCCD_UUID, + attribute_it->pValue, + *attribute_it->pLen, + attribute_it->maxLen, + false); + + implicit_cccd->setHandle(cccds[cccd_cnt].handle); + implicit_cccd->allowRead(true); + implicit_cccd->allowWrite(true); + characteristic->_setImplicitCCCD(implicit_cccd); + cccd_cnt++; attribute_it++; From ca9b70582c0daaea41a9745306386814ba8e2462 Mon Sep 17 00:00:00 2001 From: George Beckstein Date: Wed, 7 Oct 2020 13:12:08 -0400 Subject: [PATCH 2/5] Remove nullptr check when deleting _implicit_cccd --- .../FEATURE_BLE/include/ble/gatt/GattCharacteristic.h | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/connectivity/FEATURE_BLE/include/ble/gatt/GattCharacteristic.h b/connectivity/FEATURE_BLE/include/ble/gatt/GattCharacteristic.h index 3b26255834..348cb158a3 100644 --- a/connectivity/FEATURE_BLE/include/ble/gatt/GattCharacteristic.h +++ b/connectivity/FEATURE_BLE/include/ble/gatt/GattCharacteristic.h @@ -1430,9 +1430,8 @@ public: GattCharacteristic& operator=(const GattCharacteristic &) = delete; ~GattCharacteristic() { - if(_implicit_cccd != nullptr) { delete _implicit_cccd; - } + _implicit_cccd = nullptr; } public: @@ -1821,7 +1820,7 @@ private: * the constructor includes a CCCD this field is left as nullptr to * indicate the CCCD was explicitly created. */ - GattAttribute* _implicit_cccd; + GattAttribute* _implicit_cccd = nullptr; /** * The registered callback handler for read authorization reply. From eccb3e9bdaf912b9a0d8e9728c01a378f7893937 Mon Sep 17 00:00:00 2001 From: George Beckstein Date: Wed, 7 Oct 2020 13:31:09 -0400 Subject: [PATCH 3/5] Make setImplicitCCCD private and add impl::GattServer as a friend class --- .../include/ble/gatt/GattCharacteristic.h | 19 +++++++++++++++---- .../source/cordio/source/GattServerImpl.cpp | 2 +- 2 files changed, 16 insertions(+), 5 deletions(-) diff --git a/connectivity/FEATURE_BLE/include/ble/gatt/GattCharacteristic.h b/connectivity/FEATURE_BLE/include/ble/gatt/GattCharacteristic.h index 348cb158a3..31133b117b 100644 --- a/connectivity/FEATURE_BLE/include/ble/gatt/GattCharacteristic.h +++ b/connectivity/FEATURE_BLE/include/ble/gatt/GattCharacteristic.h @@ -24,6 +24,16 @@ #include "ble/gatt/GattAttribute.h" #include "ble/gatt/GattCallbackParamTypes.h" +// Forward declare ble::impl::GattServer +namespace ble { + +#if !defined(DOXYGEN_ONLY) +namespace impl { +class GattServer; +} +#endif // !defined(DOXYGEN_ONLY) +} + /** * @addtogroup ble * @{ @@ -1774,6 +1784,10 @@ public: return _descriptors[index]; } +private: + + friend ble::impl::GattServer; + /** * Sets this GattCharacteristic's implicitly-created CCCD, if * applicable. @@ -1781,11 +1795,8 @@ public: * @note once this is called, the pointed-to GattAttribute * is owned by this GattCharacteristic and will be deleted * during this object's destructor - * - * @note this is an internal function and should not be called - * by the application */ - void _setImplicitCCCD(GattAttribute *implicit_cccd) { + void setImplicitCCCD(GattAttribute *implicit_cccd) { _implicit_cccd = implicit_cccd; } diff --git a/connectivity/FEATURE_BLE/source/cordio/source/GattServerImpl.cpp b/connectivity/FEATURE_BLE/source/cordio/source/GattServerImpl.cpp index e1bc17eccf..00b25d5750 100644 --- a/connectivity/FEATURE_BLE/source/cordio/source/GattServerImpl.cpp +++ b/connectivity/FEATURE_BLE/source/cordio/source/GattServerImpl.cpp @@ -603,7 +603,7 @@ ble_error_t GattServer::insert_cccd( implicit_cccd->setHandle(cccds[cccd_cnt].handle); implicit_cccd->allowRead(true); implicit_cccd->allowWrite(true); - characteristic->_setImplicitCCCD(implicit_cccd); + characteristic->setImplicitCCCD(implicit_cccd); cccd_cnt++; attribute_it++; From fa2c3633ddd374562840355aa503400b8f6c2cc7 Mon Sep 17 00:00:00 2001 From: George Beckstein Date: Wed, 7 Oct 2020 13:32:17 -0400 Subject: [PATCH 4/5] Add doxygen guard to private function --- .../FEATURE_BLE/include/ble/gatt/GattCharacteristic.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/connectivity/FEATURE_BLE/include/ble/gatt/GattCharacteristic.h b/connectivity/FEATURE_BLE/include/ble/gatt/GattCharacteristic.h index 31133b117b..d5e88eedfb 100644 --- a/connectivity/FEATURE_BLE/include/ble/gatt/GattCharacteristic.h +++ b/connectivity/FEATURE_BLE/include/ble/gatt/GattCharacteristic.h @@ -1784,10 +1784,12 @@ public: return _descriptors[index]; } + private: friend ble::impl::GattServer; +#if !defined(DOXYGEN_ONLY) /** * Sets this GattCharacteristic's implicitly-created CCCD, if * applicable. @@ -1799,6 +1801,8 @@ private: void setImplicitCCCD(GattAttribute *implicit_cccd) { _implicit_cccd = implicit_cccd; } +#endif // !defined(DOXYGEN_ONLY) + private: From f9af08c0ada99d7fc5187446bfdbc3ad594ef2f9 Mon Sep 17 00:00:00 2001 From: George Beckstein Date: Fri, 9 Oct 2020 09:47:05 -0400 Subject: [PATCH 5/5] Add error if allocation of cccd attribute fails --- .../FEATURE_BLE/source/cordio/source/GattServerImpl.cpp | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/connectivity/FEATURE_BLE/source/cordio/source/GattServerImpl.cpp b/connectivity/FEATURE_BLE/source/cordio/source/GattServerImpl.cpp index 00b25d5750..24c8c35805 100644 --- a/connectivity/FEATURE_BLE/source/cordio/source/GattServerImpl.cpp +++ b/connectivity/FEATURE_BLE/source/cordio/source/GattServerImpl.cpp @@ -23,6 +23,8 @@ #include "wsf_types.h" #include "att_api.h" +#include + namespace ble { namespace impl { @@ -593,13 +595,18 @@ ble_error_t GattServer::insert_cccd( * * Ownership is passed to the GattCharacteristic */ - GattAttribute* implicit_cccd = new GattAttribute( + GattAttribute* implicit_cccd = new (std::nothrow) GattAttribute( CCCD_UUID, attribute_it->pValue, *attribute_it->pLen, attribute_it->maxLen, false); + if(implicit_cccd == nullptr) { + currentHandle--; + return BLE_ERROR_NO_MEM; + } + implicit_cccd->setHandle(cccds[cccd_cnt].handle); implicit_cccd->allowRead(true); implicit_cccd->allowWrite(true);