Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
58 changes: 56 additions & 2 deletions connectivity/FEATURE_BLE/include/ble/gatt/GattCharacteristic.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
* @{
Expand Down Expand Up @@ -1429,6 +1439,11 @@ class GattCharacteristic {
GattCharacteristic(const GattCharacteristic &) = delete;
GattCharacteristic& operator=(const GattCharacteristic &) = delete;

~GattCharacteristic() {
delete _implicit_cccd;
_implicit_cccd = nullptr;
}

public:

/**
Expand Down Expand Up @@ -1714,7 +1729,7 @@ class GattCharacteristic {
*/
uint8_t getDescriptorCount() const
{
return _descriptorCount;
return (_implicit_cccd == nullptr? _descriptorCount : _descriptorCount+1);
}

/**
Expand Down Expand Up @@ -1750,16 +1765,45 @@ class GattCharacteristic {
*
* @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];
}


private:

friend ble::impl::GattServer;

#if !defined(DOXYGEN_ONLY)
/**
* 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
*/
void setImplicitCCCD(GattAttribute *implicit_cccd) {
_implicit_cccd = implicit_cccd;
}
#endif // !defined(DOXYGEN_ONLY)


private:

/**
Expand All @@ -1783,6 +1827,16 @@ class GattCharacteristic {
*/
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 = nullptr;

/**
* The registered callback handler for read authorization reply.
*/
Expand Down
24 changes: 24 additions & 0 deletions connectivity/FEATURE_BLE/source/cordio/source/GattServerImpl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@
#include "wsf_types.h"
#include "att_api.h"

#include <new>

namespace ble {
namespace impl {

Expand Down Expand Up @@ -588,6 +590,28 @@ 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 (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);
characteristic->setImplicitCCCD(implicit_cccd);

cccd_cnt++;
attribute_it++;

Expand Down