diff --git a/libraries/CurieBLE/examples/central/peripheral_explorer/peripheral_explorer.ino b/libraries/CurieBLE/examples/central/peripheral_explorer/peripheral_explorer.ino index 45429655..66b7ea31 100644 --- a/libraries/CurieBLE/examples/central/peripheral_explorer/peripheral_explorer.ino +++ b/libraries/CurieBLE/examples/central/peripheral_explorer/peripheral_explorer.ino @@ -132,10 +132,30 @@ void exploreCharacteristic(BLECharacteristic characteristic) { Serial.print(", value 0x"); printData(characteristic.value(), characteristic.valueLength()); } - } Serial.println(); + // loop the descriptors of the characteristic and explore each + for (int i = 0; i < characteristic.descriptorCount(); i++) { + BLEDescriptor descriptor = characteristic.descriptor(i); + + exploreDescriptor(descriptor); + } +} + +void exploreDescriptor(BLEDescriptor descriptor) { + // print the UUID of the descriptor + Serial.print("\t\tDescriptor "); + Serial.print(descriptor.uuid()); + + // read the descriptor value + descriptor.read(); + + // print out the value of the descriptor + Serial.print(", value 0x"); + printData(descriptor.value(), descriptor.valueLength()); + + Serial.println(); } void printData(const unsigned char data[], int length) { diff --git a/libraries/CurieBLE/src/BLECharacteristic.cpp b/libraries/CurieBLE/src/BLECharacteristic.cpp index f8432b11..1fca1ff6 100644 --- a/libraries/CurieBLE/src/BLECharacteristic.cpp +++ b/libraries/CurieBLE/src/BLECharacteristic.cpp @@ -439,15 +439,20 @@ int BLECharacteristic::addDescriptor(BLEDescriptor& descriptor) else if (BLEUtils::isLocalBLE(_bledev) == true) { // Only support the GATT server that create the service in local device. - _chrc_local_imp = new BLECharacteristicImp(*this, _bledev); + // Consider to add multi-descriptor if (NULL == _chrc_local_imp) { - retVar = BLE_STATUS_NO_MEMORY; + _chrc_local_imp = new BLECharacteristicImp(*this, _bledev); } - else + + if (NULL != _chrc_local_imp) { retVar = _chrc_local_imp->addDescriptor(descriptor); } + else + { + retVar = BLE_STATUS_NO_MEMORY; + } } return retVar; } diff --git a/libraries/CurieBLE/src/BLEDescriptor.cpp b/libraries/CurieBLE/src/BLEDescriptor.cpp index 31c4ba7e..eb624532 100644 --- a/libraries/CurieBLE/src/BLEDescriptor.cpp +++ b/libraries/CurieBLE/src/BLEDescriptor.cpp @@ -35,28 +35,19 @@ BLEDescriptor::BLEDescriptor(BLEDescriptorImp* descriptorImp, const BLEDevice *bleDev): _bledev(bleDev), _value_size(0), - _value(NULL) + _value(NULL), + _internal(descriptorImp) { _properties = descriptorImp->properties(); memset(_uuid_cstr, 0, sizeof (_uuid_cstr)); BLEUtils::uuidBT2String(descriptorImp->bt_uuid(), _uuid_cstr); - - _value_size = descriptorImp->valueSize(); - _value = (unsigned char*)malloc(_value_size); - if (NULL == _value) - { - memcpy(_value, descriptorImp->value(), _value_size); - } - else - { - errno = ENOMEM; - } } BLEDescriptor::BLEDescriptor(const char* uuid, const unsigned char value[], unsigned short valueLength): - _bledev() + _bledev(), + _internal(NULL) { bt_uuid_128_t uuid_tmp; memset(_uuid_cstr, 0, sizeof (_uuid_cstr)); @@ -65,15 +56,16 @@ BLEDescriptor::BLEDescriptor(const char* uuid, _bledev.setAddress(*BLEUtils::bleGetLoalAddress()); - _value_size = valueLength > BLE_MAX_ATTR_LONGDATA_LEN ? BLE_MAX_ATTR_LONGDATA_LEN : valueLength; + _value_size = (valueLength > BLE_MAX_ATTR_LONGDATA_LEN) ? BLE_MAX_ATTR_LONGDATA_LEN : valueLength; _value = (unsigned char*)malloc(_value_size); - if (NULL == _value) + if (NULL != _value) { memcpy(_value, value, _value_size); } else { errno = ENOMEM; + _value_size = 0; } } @@ -82,22 +74,27 @@ BLEDescriptor::BLEDescriptor(const char* uuid, BLEDescriptor(uuid, (const unsigned char*)value, strlen(value)) {} -BLEDescriptor::BLEDescriptor(const BLEDescriptor& rhs) +BLEDescriptor::BLEDescriptor(const BLEDescriptor& rhs): + _bledev(&rhs._bledev), + _properties(rhs._properties), + _value_size(0), + _value(NULL), + _internal(rhs._internal) { - _value = (unsigned char*)malloc(rhs._value_size); // Sid. KW: allocate memory for _value, not local - if (_value) - { - memcpy(_value, rhs._value, rhs._value_size); - _value_size = rhs._value_size; - } - else + memcpy(_uuid_cstr, rhs._uuid_cstr, sizeof(_uuid_cstr)); + if (NULL == _internal && rhs._value_size > 0) { - _value_size = 0; - errno = ENOMEM; + _value = (unsigned char*)malloc(rhs._value_size); // Sid. KW: allocate memory for _value, not local + if (_value) + { + memcpy(_value, rhs._value, rhs._value_size); + _value_size = rhs._value_size; + } + else + { + errno = ENOMEM; + } } - memcpy(_uuid_cstr, rhs._uuid_cstr, sizeof(_uuid_cstr)); - _properties = rhs._properties; - _bledev = BLEDevice(&rhs._bledev); } BLEDescriptor& BLEDescriptor::operator= (const BLEDescriptor& rhs) @@ -107,23 +104,27 @@ BLEDescriptor& BLEDescriptor::operator= (const BLEDescriptor& rhs) memcpy(_uuid_cstr, rhs._uuid_cstr, sizeof(_uuid_cstr)); _properties = rhs._properties; _bledev = BLEDevice(&rhs._bledev); - if (_value_size < rhs._value_size) + _internal = rhs._internal; + if (NULL == _internal && rhs._value_size > 0) { - _value_size = rhs._value_size; + if (_value_size < rhs._value_size) + { + _value_size = rhs._value_size; + + if (NULL != _value) + free(_value); + _value = (unsigned char*)malloc(_value_size); + } if (NULL != _value) - free(_value); - _value = (unsigned char*)malloc(_value_size); - } - - if (NULL != _value) - { - memcpy(_value, rhs._value, rhs._value_size); - } - else - { - _value_size = 0; - errno = ENOMEM; + { + memcpy(_value, rhs._value, rhs._value_size); + } + else + { + _value_size = 0; + errno = ENOMEM; + } } } return *this; @@ -145,12 +146,22 @@ const char* BLEDescriptor::uuid() const const byte* BLEDescriptor::value() const { - return _value; + const byte* ret = _value; + if (NULL != _internal) + { + ret = _internal->value(); + } + return ret; } int BLEDescriptor::valueLength() const { - return _value_size; + int ret = _value_size; + if (NULL != _internal) + { + ret = _internal->valueLength(); + } + return ret; } BLEDescriptor::operator bool() const @@ -166,6 +177,22 @@ unsigned char BLEDescriptor::properties() const int BLEDescriptor::valueSize() const { - return _value_size; + int ret = _value_size; + if (NULL != _internal) + { + ret = _internal->valueSize(); + } + return ret; +} + +bool BLEDescriptor::read() +{ + bool retVar = false; + + if (NULL != _internal) + { + retVar = _internal->read(); + } + return retVar; } diff --git a/libraries/CurieBLE/src/BLEDescriptor.h b/libraries/CurieBLE/src/BLEDescriptor.h index e1a79f2a..9e95de7d 100644 --- a/libraries/CurieBLE/src/BLEDescriptor.h +++ b/libraries/CurieBLE/src/BLEDescriptor.h @@ -37,73 +37,92 @@ class BLEDescriptor virtual ~BLEDescriptor(); + /** + * @brief Get the descriptor's UUID string + * + * @param none + * + * @return const char* The UUID string + * + * @note none + */ const char* uuid() const; - virtual const byte* value() const; // returns the value buffer - virtual int valueLength() const; // returns the current length of the value - - virtual operator bool() const; // is the descriptor valid (discovered from peripheral) - - unsigned char properties() const; - int valueSize() const; -private: - char _uuid_cstr[37]; // The characteristic UUID - BLEDevice _bledev; - - unsigned char _properties; // The characteristic property - - unsigned short _value_size; // The value size - unsigned char* _value; // The value. Will delete after create the _internal - - - // The API reserved for feature release - // move here for temp /** - * @brief Write the value of the descriptor + * @brief Get the value of descriptor * - * @param value The value buffer that want to write to descriptor + * @param none * - * @param length The value buffer's length + * @return const byte* The value buffer * - * @return bool true - Success, false - Failed + * @note none + */ + virtual const byte* value() const; + + /** + * @brief Get the current length of the value + * + * @param none + * + * @return int The current length of the value string * * @note none */ - //virtual bool writeValue(const byte value[], int length); + virtual int valueLength() const; /** - * @brief Write the value of the descriptor + * @brief Is the descriptor valid + * + * @param none * - * @param value The value buffer that want to write to descriptor + * @return bool true/false * - * @param length The value buffer's length + * @note none + */ + virtual operator bool() const; + + /** + * @brief Read the descriptor value * - * @param offset The offset in the descriptor's data + * @param none * * @return bool true - Success, false - Failed * + * @note Only for GATT client. Schedule read request to the GATT server + */ + bool read(); + + /** + * @brief Get the property mask of the descriptor + * + * @param none + * + * @return unsigned char The property mask of the descriptor + * * @note none */ - //bool writeValue(const byte value[], int length, int offset); + unsigned char properties() const; /** - * @brief Write the value of the descriptor + * @brief Get the maximum size of the value * - * @param value The value string that want to write to descriptor + * @param none * - * @return bool true - Success, false - Failed + * @return int The maximum size of the value * * @note none */ - //bool writeValue(const char* value); - //virtual byte operator[] (int offset) const; // returns a byte of the value at the specified offset - - // GATT client Write the value of the descriptor - //virtual bool write(const byte value[], int length); - //bool write(const byte value[], int length, int offset); - //bool write(const char* value); - //bool read(); + int valueSize() const; +private: + char _uuid_cstr[37]; // The characteristic UUID + BLEDevice _bledev; + + unsigned char _properties; // The characteristic property + + unsigned short _value_size; // The value size + unsigned char* _value; // The value. Will delete after create the _internal + BLEDescriptorImp *_internal; // The real implementation of Descriptor }; #endif diff --git a/libraries/CurieBLE/src/BLEDevice.h b/libraries/CurieBLE/src/BLEDevice.h index 56742f1b..6c1090d6 100644 --- a/libraries/CurieBLE/src/BLEDevice.h +++ b/libraries/CurieBLE/src/BLEDevice.h @@ -644,6 +644,7 @@ class BLEDevice void setEventHandler(BLEDeviceEvent event, BLEDeviceEventHandler eventHandler); // set an event handler (callback) protected: + friend class BLEDescriptorImp; friend class BLECharacteristicImp; friend class BLEServiceImp; friend class BLEDeviceManager; @@ -659,6 +660,11 @@ class BLEDevice bt_gatt_read_params_t *params, const void *data, uint16_t length); + friend uint8_t profile_descriptor_read_rsp_process(bt_conn_t *conn, + int err, + bt_gatt_read_params_t *params, + const void *data, + uint16_t length); const bt_addr_le_t* bt_le_address() const; const bt_le_conn_param* bt_conn_param() const; void setAddress(const bt_addr_le_t& addr); diff --git a/libraries/CurieBLE/src/internal/BLECallbacks.cpp b/libraries/CurieBLE/src/internal/BLECallbacks.cpp index 568c54f8..a5af7d97 100644 --- a/libraries/CurieBLE/src/internal/BLECallbacks.cpp +++ b/libraries/CurieBLE/src/internal/BLECallbacks.cpp @@ -161,6 +161,31 @@ uint8_t profile_read_rsp_process(bt_conn_t *conn, return BT_GATT_ITER_STOP; } +uint8_t profile_descriptor_read_rsp_process(bt_conn_t *conn, + int err, + bt_gatt_read_params_t *params, + const void *data, + uint16_t length) +{ + if (NULL == data) + { + return BT_GATT_ITER_STOP; + } + BLEDescriptorImp *descriptor = NULL; + BLEDevice bleDevice(bt_conn_get_dst(conn)); + + // Get characteristic by handle params->single.handle + descriptor = BLEProfileManager::instance()->descriptor(bleDevice, params->single.handle); + + //pr_debug(LOG_MODULE_BLE, "%s-%d", __FUNCTION__, __LINE__); + if (descriptor) + { + descriptor->writeValue((const unsigned char *)data, length, params->single.offset); + } + //pr_debug(LOG_MODULE_BLE, "%s-%d: desc len-%d", __FUNCTION__, __LINE__, descriptor->valueLength()); + return BT_GATT_ITER_STOP; +} + uint8_t profile_service_read_rsp_process(bt_conn_t *conn, int err, bt_gatt_read_params_t *params, diff --git a/libraries/CurieBLE/src/internal/BLECallbacks.h b/libraries/CurieBLE/src/internal/BLECallbacks.h index 213bd794..cc05fc01 100644 --- a/libraries/CurieBLE/src/internal/BLECallbacks.h +++ b/libraries/CurieBLE/src/internal/BLECallbacks.h @@ -28,6 +28,13 @@ uint8_t profile_read_rsp_process(bt_conn_t *conn, int err, bt_gatt_read_params_t *params, const void *data, uint16_t length); + +uint8_t profile_descriptor_read_rsp_process(bt_conn_t *conn, + int err, + bt_gatt_read_params_t *params, + const void *data, + uint16_t length); + int profile_longflush_process(struct bt_conn *conn, const struct bt_gatt_attr *attr, uint8_t flags); diff --git a/libraries/CurieBLE/src/internal/BLECharacteristicImp.cpp b/libraries/CurieBLE/src/internal/BLECharacteristicImp.cpp index 415aa5ff..9727cb82 100644 --- a/libraries/CurieBLE/src/internal/BLECharacteristicImp.cpp +++ b/libraries/CurieBLE/src/internal/BLECharacteristicImp.cpp @@ -537,6 +537,26 @@ BLECharacteristicImp::valueHandle() return handle; } +BLEDescriptorImp* BLECharacteristicImp::descriptor(uint16_t handle) +{ + BLEDescriptorImp* descriptorImp = NULL; + BLEDescriptorNodePtr node = link_node_get_first(&_descriptors_header); + while (NULL != node) + { + descriptorImp = node->value; + if (handle == descriptorImp->valueHandle()) + { + break; + } + node = node->next; + } + if (NULL == node) + { + descriptorImp = NULL; + } + return descriptorImp; +} + void BLECharacteristicImp::_setValue(const uint8_t value[], uint16_t length, uint16_t offset) { diff --git a/libraries/CurieBLE/src/internal/BLECharacteristicImp.h b/libraries/CurieBLE/src/internal/BLECharacteristicImp.h index 1066992c..74fe20af 100644 --- a/libraries/CurieBLE/src/internal/BLECharacteristicImp.h +++ b/libraries/CurieBLE/src/internal/BLECharacteristicImp.h @@ -188,6 +188,8 @@ class BLECharacteristicImp: public BLEAttribute{ friend class BLEProfileManager; friend class BLEServiceImp; friend class BLECharacteristic; + + BLEDescriptorImp* descriptor(uint16_t handle); /** * Constructor for BLE Characteristic * diff --git a/libraries/CurieBLE/src/internal/BLEDescriptorImp.cpp b/libraries/CurieBLE/src/internal/BLEDescriptorImp.cpp index 0586bc09..42ca6a24 100644 --- a/libraries/CurieBLE/src/internal/BLEDescriptorImp.cpp +++ b/libraries/CurieBLE/src/internal/BLEDescriptorImp.cpp @@ -23,11 +23,15 @@ #include "internal/ble_client.h" #include "BLECallbacks.h" +#include "BLEUtils.h" BLEDescriptorImp::BLEDescriptorImp(BLEDevice& bledevice, BLEDescriptor &descriptor): - BLEAttribute(descriptor.uuid(), BLETypeDescriptor), - _value_handle(0) + BLEAttribute(descriptor.uuid(), BLETypeDescriptor), + _value_handle(0), + _bledev(bledevice), + _reading(false), + _attr_desc_value(NULL) { _properties = descriptor.properties(); @@ -45,21 +49,22 @@ BLEDescriptorImp::BLEDescriptorImp(const bt_uuid_t* uuid, uint16_t handle, BLEDevice& bledevice): BLEAttribute(uuid, BLETypeDescriptor), + _value_length(0), _value_handle(handle), - _properties(properties) + _value(NULL), + _properties(properties), + _bledev(bledevice), + _reading(false), + _attr_desc_value(NULL) { - _value_length = BLE_MAX_ATTR_DATA_LEN; - _value = (unsigned char*)malloc(_value_length); - - if (_value) - memset(_value, 0, _value_length); - else - _value_length = 0; + memset(&_read_params, 0, sizeof(_read_params)); } BLEDescriptorImp::BLEDescriptorImp(const BLEDescriptorImp& rhs) : - BLEAttribute(rhs) + BLEAttribute(rhs), + _reading(false), + _attr_desc_value(rhs._attr_desc_value) { _value_length = rhs._value_length; _value = (unsigned char *)malloc(_value_length); @@ -70,30 +75,29 @@ BLEDescriptorImp::BLEDescriptorImp(const BLEDescriptorImp& rhs) : _value_handle = rhs._value_handle; _properties = rhs._properties; - _descriptor_uuid = rhs._descriptor_uuid; _bledev = BLEDevice(&rhs._bledev); } BLEDescriptorImp& BLEDescriptorImp::operator=(const BLEDescriptorImp& that) { - if (this != &that) { - - BLEAttribute::operator=(that); - if (_value) - free(_value); - - _value_length = that._value_length; - _value = (unsigned char *)malloc(_value_length); - if (_value) - memcpy(_value, that._value, sizeof(_value_length)); - else - _value_length = 0; - - _value_handle = that._value_handle; - _properties = that._properties; - _descriptor_uuid = that._descriptor_uuid; - _bledev = BLEDevice(&that._bledev); + if (this != &that) + { + BLEAttribute::operator=(that); + if (_value) + free(_value); + + _value_length = that._value_length; + _value = (unsigned char *)malloc(_value_length); + if (_value) + memcpy(_value, that._value, sizeof(_value_length)); + else + _value_length = 0; + + _value_handle = that._value_handle; + _properties = that._properties; + _bledev = BLEDevice(&that._bledev); + _attr_desc_value = that._attr_desc_value; } return *this; } @@ -136,6 +140,24 @@ int BLEDescriptorImp::updateProfile(bt_gatt_attr_t *attr_start, int& index) return 1; } +uint16_t +BLEDescriptorImp::valueHandle() const +{ + uint16_t handle = 0; + if (NULL != _attr_desc_value) + { + //GATT server + handle = _attr_desc_value->handle; + } + else + { + // GATT client + handle = _value_handle; + } + + return handle; +} + unsigned char BLEDescriptorImp::properties() const { return _properties; @@ -146,4 +168,88 @@ int BLEDescriptorImp::valueSize() const return _value_length; } +bool BLEDescriptorImp::read() +{ + int retval = 0; + bt_conn_t* conn = NULL; + + if (true == BLEUtils::isLocalBLE(_bledev)) + { + // GATT server can't read + return false; + } + + if (_reading) + { + // Already in reading state + return false; + } + + _read_params.func = profile_descriptor_read_rsp_process; + _read_params.handle_count = 1; + _read_params.single.handle = _value_handle; + _read_params.single.offset = 0; + + if (0 == _read_params.single.handle) + { + // Discover not complete + return false; + } + + conn = bt_conn_lookup_addr_le(_bledev.bt_le_address()); + if (NULL == conn) + { + return false; + } + + // Send read request + retval = bt_gatt_read(conn, &_read_params); + bt_conn_unref(conn); + if (0 == retval) + { + _reading = true; + } + return _reading; +} + +bool BLEDescriptorImp::writeValue(const byte value[], + int length, + int offset) +{ + bool ret = true; + int total_length = length + offset; + int write_len = length; + if (total_length > BLE_MAX_ATTR_DATA_LEN) + { + return false; + } + + if (NULL == _value) + { + _value_length = length + offset; + _value = (unsigned char*)malloc(_value_length); + + if (NULL != _value) + { + memset(_value, 0, _value_length); + } + else + { + _value_length = 0; + ret = false; + } + } + + if (_value_length < total_length) + { + write_len = _value_length - offset; + } + + if (NULL != _value) + { + memcpy(_value + offset, value, write_len); + } + return ret; +} + diff --git a/libraries/CurieBLE/src/internal/BLEDescriptorImp.h b/libraries/CurieBLE/src/internal/BLEDescriptorImp.h index 32fceb1a..701f3f83 100644 --- a/libraries/CurieBLE/src/internal/BLEDescriptorImp.h +++ b/libraries/CurieBLE/src/internal/BLEDescriptorImp.h @@ -59,12 +59,80 @@ class BLEDescriptorImp: public BLEAttribute{ * @return unsigned short size of Descriptor value in bytes */ unsigned short valueLength(void) const; - + + /** + * @brief Fill the attribute for profile register structure + * + * @param bt_gatt_attr_t * The start pointer of the profile register structure array + * + * @param int& The current index in the profile structure array + * + * @return int Filled structure counter + * + * @note none + */ int updateProfile(bt_gatt_attr_t *attr_start, int& index); unsigned char operator[] (int offset) const; + + /** + * @brief Get the property mask of the descriptor + * + * @param none + * + * @return unsigned char The property mask of the descriptor + * + * @note none + */ unsigned char properties() const; + + /** + * @brief Get the maximum size of the value + * + * @param none + * + * @return int The maximum size of the value + * + * @note none + */ int valueSize() const; + + /** + * @brief Get the descriptor value handle + * + * @param none + * + * @return none + * + * @note none + */ + uint16_t valueHandle() const; + + /** + * @brief Write the value of the descriptor + * + * @param value The value buffer that want to write to descriptor + * + * @param length The value buffer's length + * + * @param offset The offset in the descriptor's data + * + * @return bool true - Success, false - Failed + * + * @note none + */ + bool writeValue(const byte value[], int length, int offset); + + /** + * @brief Read the descriptor value + * + * @param none + * + * @return bool true - Success, false - Failed + * + * @note Only for GATT client. Schedule read request to the GATT server + */ + bool read(); protected: @@ -75,9 +143,12 @@ class BLEDescriptorImp: public BLEAttribute{ unsigned char* _value; unsigned char _properties; // The characteristic property - bt_uuid_128 _descriptor_uuid; - BLEDevice _bledev; + + bool _reading; + bt_gatt_read_params_t _read_params; // GATT read parameter + + bt_gatt_attr_t *_attr_desc_value; // GATT server only }; #endif // _BLE_DESCRIPTOR_H_INCLUDED diff --git a/libraries/CurieBLE/src/internal/BLEProfileManager.cpp b/libraries/CurieBLE/src/internal/BLEProfileManager.cpp index df34c996..7ea0c206 100644 --- a/libraries/CurieBLE/src/internal/BLEProfileManager.cpp +++ b/libraries/CurieBLE/src/internal/BLEProfileManager.cpp @@ -337,6 +337,30 @@ void BLEProfileManager::clearProfile(BLEServiceLinkNodeHeader* serviceHeader) } } +BLEDescriptorImp* BLEProfileManager::descriptor(const BLEDevice &bledevice, uint16_t handle) +{ + BLEDescriptorImp* descriptorImp = NULL; + BLEServiceLinkNodeHeader* serviceHeader = getServiceHeader(bledevice); + if (NULL == serviceHeader) + { + // Doesn't find the service + return NULL; + } + + BLEServiceNodePtr node = serviceHeader->next; + while (node != NULL) + { + BLEServiceImp *service = node->value; + descriptorImp = service->descriptor(handle); + if (NULL != descriptorImp) + { + break; + } + node = node->next; + } + return descriptorImp; +} + BLECharacteristicImp* BLEProfileManager::characteristic(const BLEDevice &bledevice, int index) { BLECharacteristicImp* characteristicImp = NULL; diff --git a/libraries/CurieBLE/src/internal/BLEProfileManager.h b/libraries/CurieBLE/src/internal/BLEProfileManager.h index 02c42c9c..679a86e4 100644 --- a/libraries/CurieBLE/src/internal/BLEProfileManager.h +++ b/libraries/CurieBLE/src/internal/BLEProfileManager.h @@ -73,6 +73,7 @@ class BLEProfileManager{ inline bool hasRegisterProfile(){return _profile_registered;} + BLEDescriptorImp* descriptor(const BLEDevice &bledevice, uint16_t handle); /** * @brief Get the BLE's Characteristic implementation object by uuid and index * diff --git a/libraries/CurieBLE/src/internal/BLEServiceImp.cpp b/libraries/CurieBLE/src/internal/BLEServiceImp.cpp index 4f4d3dc1..6bcdde18 100644 --- a/libraries/CurieBLE/src/internal/BLEServiceImp.cpp +++ b/libraries/CurieBLE/src/internal/BLEServiceImp.cpp @@ -174,6 +174,29 @@ void BLEServiceImp::releaseCharacteristic() } +BLEDescriptorImp* BLEServiceImp::descriptor(uint16_t handle) +{ + BLEDescriptorImp* descriptorImp = NULL; + + BLECharacteristicImp* characteristicImp = NULL; + BLECharacteristicNodePtr node = link_node_get_first(&_characteristics_header); + while (NULL != node) + { + characteristicImp = node->value; + descriptorImp = characteristicImp->descriptor(handle); + if (descriptorImp != NULL) + { + break; + } + node = node->next; + } + if (NULL == node) + { + descriptorImp = NULL; + } + return descriptorImp; +} + BLECharacteristicImp* BLEServiceImp::characteristic(int index) { BLECharacteristicImp* characteristicImp = NULL; diff --git a/libraries/CurieBLE/src/internal/BLEServiceImp.h b/libraries/CurieBLE/src/internal/BLEServiceImp.h index d6c63389..04b21e9b 100644 --- a/libraries/CurieBLE/src/internal/BLEServiceImp.h +++ b/libraries/CurieBLE/src/internal/BLEServiceImp.h @@ -57,6 +57,8 @@ class BLEServiceImp: public BLEAttribute{ uint16_t handle, unsigned char properties); int getCharacteristicCount(); + + BLEDescriptorImp* descriptor(uint16_t handle); BLECharacteristicImp* characteristic(const bt_uuid_t* uuid); BLECharacteristicImp* characteristic(const char* uuid);