2727
2828# include < climits>
2929
30- typedef struct {
31- const NimBLEUUID* uuid;
32- void * task_data;
33- } desc_filter_t ;
30+ struct NimBLEDescriptorFilter {
31+ NimBLERemoteDescriptor* dsc;
32+ const NimBLEUUID* uuid;
33+ void * taskData;
34+ };
3435
3536static const char * LOG_TAG = " NimBLERemoteCharacteristic" ;
3637
3738/* *
3839 * @brief Constructor.
3940 * @param [in] svc A pointer to the service this characteristic belongs to.
40- * @param [in] ble_gatt_chr struct defined as:
41+ * @param [in] chr struct defined as:
4142 * struct ble_gatt_chr {
4243 * uint16_t def_handle;
4344 * uint16_t val_handle;
@@ -62,67 +63,68 @@ NimBLERemoteCharacteristic::~NimBLERemoteCharacteristic() {
6263/* *
6364 * @brief Callback used by the API when a descriptor is discovered or search complete.
6465 */
65- int NimBLERemoteCharacteristic::descriptorDiscCB (
66- uint16_t conn_handle, const ble_gatt_error* error, uint16_t chr_val_handle, const ble_gatt_dsc* dsc, void * arg) {
67- int rc = error->status ;
66+ int NimBLERemoteCharacteristic::descriptorDiscCB (uint16_t connHandle,
67+ const ble_gatt_error* error,
68+ uint16_t chrHandle,
69+ const ble_gatt_dsc* dsc,
70+ void * arg) {
71+ int rc = error->status ;
72+ auto filter = (NimBLEDescriptorFilter*)arg;
73+ auto pTaskData = (NimBLETaskData*)filter->taskData ;
74+ const auto pChr = (NimBLERemoteCharacteristic*)pTaskData->m_pInstance ;
75+ const auto uuid = filter->uuid ; // UUID to filter for
6876 NIMBLE_LOGD (LOG_TAG, " Descriptor Discovery >> status: %d handle: %d" , rc, (rc == 0 ) ? dsc->handle : -1 );
6977
70- auto filter = (desc_filter_t *)arg;
71- auto pTaskData = (NimBLETaskData*)filter->task_data ;
72- const auto pChr = (NimBLERemoteCharacteristic*)pTaskData->m_pInstance ;
73- const NimBLEUUID* uuidFilter = filter->uuid ;
74-
75- if (pChr->getHandle () != chr_val_handle) {
76- return 0 ; // Descriptor not for this characteristic
77- }
78-
79- if (rc == 0 ) {
80- if (uuidFilter != nullptr ) {
81- if (ble_uuid_cmp (uuidFilter->getBase (), &dsc->uuid .u ) == 0 ) {
82- rc = BLE_HS_EDONE; // Found the descriptor, stop the search
83- } else {
84- return 0 ; // Not the descriptor we are looking for
85- }
86- }
87-
78+ // Results for chrHandle added until rc != 0
79+ // Must find specified UUID if filter is used
80+ if (rc == 0 && pChr->getHandle () == chrHandle
81+ && (!uuid || 0 == ble_uuid_cmp (uuid->getBase (), &dsc->uuid .u ))) {
82+ // Return BLE_HS_EDONE if the descriptor was found, stop the search
8883 pChr->m_vDescriptors .push_back (new NimBLERemoteDescriptor (pChr, dsc));
89- return 0 ;
84+ rc = !!uuid * BLE_HS_EDONE ;
9085 }
9186
92- NimBLEUtils::taskRelease (*pTaskData, rc);
93- NIMBLE_LOGD (LOG_TAG, " << Descriptor Discovery" );
87+ if (rc != 0 ) {
88+ NimBLEUtils::taskRelease (*pTaskData, rc);
89+ NIMBLE_LOGD (LOG_TAG, " << Descriptor Discovery" );
90+ }
9491 return rc;
9592}
9693
9794/* *
9895 * @brief Populate the descriptors (if any) for this characteristic.
99- * @param [in] the end handle of the characteristic, or the service, whichever comes first.
96+ * @param [in] filter Structure containing pointers to descriptor, UUID, and task data.
97+ * @return True if successfully retrieved, success = BLE_HS_EDONE.
10098 */
101- bool NimBLERemoteCharacteristic::retrieveDescriptors (const NimBLEUUID* uuidFilter ) const {
99+ bool NimBLERemoteCharacteristic::retrieveDescriptors (NimBLEDescriptorFilter* filter ) const {
102100 NIMBLE_LOGD (LOG_TAG, " >> retrieveDescriptors() for characteristic: %s" , getUUID ().toString ().c_str ());
103101
104- NimBLETaskData taskData (const_cast <NimBLERemoteCharacteristic*>(this ));
105- desc_filter_t filter = {uuidFilter, &taskData};
102+ // If this is the last handle then there are no descriptors
103+ if (getHandle () == getRemoteService ()->getEndHandle ()) {
104+ NIMBLE_LOGD (LOG_TAG, " << retrieveDescriptors(): found 0 descriptors." );
105+ return true ;
106+ }
106107
107108 int rc = ble_gattc_disc_all_dscs (getClient ()->getConnHandle (),
108109 getHandle (),
109110 getRemoteService ()->getEndHandle (),
110111 NimBLERemoteCharacteristic::descriptorDiscCB,
111- & filter);
112+ filter);
112113 if (rc != 0 ) {
113114 NIMBLE_LOGE (LOG_TAG, " ble_gattc_disc_all_dscs: rc=%d %s" , rc, NimBLEUtils::returnCodeToString (rc));
114115 return false ;
115116 }
116117
117- NimBLEUtils::taskWait (taskData, BLE_NPL_TIME_FOREVER);
118- rc = taskData. m_flags ;
119- if (rc == 0 || rc = = BLE_HS_EDONE) {
120- NIMBLE_LOGD (LOG_TAG, " << retrieveDescriptors(): found %d descriptors. " , m_vDescriptors. size ( ));
121- return true ;
118+ NimBLEUtils::taskWait (filter-> taskData , BLE_NPL_TIME_FOREVER);
119+ rc = ((NimBLETaskData*)filter-> taskData )-> m_flags ;
120+ if (rc ! = BLE_HS_EDONE) {
121+ NIMBLE_LOGE (LOG_TAG, " << retrieveDescriptors(): failed: rc= %d %s " , rc, NimBLEUtils::returnCodeToString (rc ));
122+ return false ;
122123 }
123124
124- NIMBLE_LOGE (LOG_TAG, " << retrieveDescriptors(): failed: rc=%d %s" , rc, NimBLEUtils::returnCodeToString (rc));
125- return false ;
125+ filter->dsc = m_vDescriptors.back ();
126+ NIMBLE_LOGD (LOG_TAG, " << retrieveDescriptors(): found %d descriptors." , m_vDescriptors.size ());
127+ return true ;
126128} // retrieveDescriptors
127129
128130/* *
@@ -132,51 +134,36 @@ bool NimBLERemoteCharacteristic::retrieveDescriptors(const NimBLEUUID* uuidFilte
132134 */
133135NimBLERemoteDescriptor* NimBLERemoteCharacteristic::getDescriptor (const NimBLEUUID& uuid) const {
134136 NIMBLE_LOGD (LOG_TAG, " >> getDescriptor: uuid: %s" , uuid.toString ().c_str ());
135- NimBLERemoteDescriptor* pDsc = nullptr ;
136- size_t prev_size = m_vDescriptors.size ();
137+ NimBLETaskData taskData (const_cast <NimBLERemoteCharacteristic*>(this ));
138+ NimBLEDescriptorFilter filter = {nullptr , &uuid, &taskData};
139+ NimBLEUUID uuidTmp;
137140
138- for (const auto & it : m_vDescriptors) {
139- if (it ->getUUID () == uuid) {
140- pDsc = it ;
141+ for (const auto & dsc : m_vDescriptors) {
142+ if (dsc ->getUUID () == uuid) {
143+ filter. dsc = dsc ;
141144 goto Done;
142145 }
143146 }
144147
145- if (retrieveDescriptors (&uuid)) {
146- if (m_vDescriptors.size () > prev_size) {
147- pDsc = m_vDescriptors.back ();
148- goto Done;
149- }
150-
151- // If the request was successful but 16/32 bit uuid not found
152- // try again with the 128 bit uuid.
153- if (uuid.bitSize () == BLE_UUID_TYPE_16 || uuid.bitSize () == BLE_UUID_TYPE_32) {
154- NimBLEUUID uuid128 (uuid);
155- uuid128.to128 ();
156- if (retrieveDescriptors (&uuid128)) {
157- if (m_vDescriptors.size () > prev_size) {
158- pDsc = m_vDescriptors.back ();
159- }
160- }
161- } else {
162- // If the request was successful but the 128 bit uuid not found
163- // try again with the 16 bit uuid.
164- NimBLEUUID uuid16 (uuid);
165- uuid16.to16 ();
166- // if the uuid was 128 bit but not of the BLE base type this check will fail
167- if (uuid16.bitSize () == BLE_UUID_TYPE_16) {
168- if (retrieveDescriptors (&uuid16)) {
169- if (m_vDescriptors.size () > prev_size) {
170- pDsc = m_vDescriptors.back ();
171- }
172- }
173- }
174- }
148+ if (!retrieveDescriptors (&filter) || filter.dsc ) {
149+ goto Done;
150+ }
151+ // Try again with 128 bit uuid if request succeeded with no uuid found.
152+ if (uuid.bitSize () == BLE_UUID_TYPE_16 || uuid.bitSize () == BLE_UUID_TYPE_32) {
153+ uuidTmp = NimBLEUUID (uuid).to128 ();
154+ retrieveDescriptors (&filter);
155+ goto Done;
156+ }
157+ // Try again with 16 bit uuid if request succeeded with no uuid found.
158+ // If the uuid was 128 bit but not of the BLE base type this check will fail.
159+ uuidTmp = NimBLEUUID (uuid).to16 ();
160+ if (uuidTmp.bitSize () == BLE_UUID_TYPE_16) {
161+ retrieveDescriptors (&filter);
175162 }
176163
177164Done:
178- NIMBLE_LOGD (LOG_TAG, " << getDescriptor: %sfound" , pDsc ? " " : " not " );
179- return pDsc ;
165+ NIMBLE_LOGD (LOG_TAG, " << getDescriptor: %sfound" , filter. dsc ? " " : " not " );
166+ return filter. dsc ;
180167} // getDescriptor
181168
182169/* *
@@ -305,7 +292,7 @@ size_t NimBLERemoteCharacteristic::deleteDescriptor(const NimBLEUUID& uuid) cons
305292 * @return True if supported.
306293 */
307294bool NimBLERemoteCharacteristic::canBroadcast () const {
308- return (m_properties & BLE_GATT_CHR_PROP_BROADCAST) != 0 ;
295+ return (m_properties & BLE_GATT_CHR_PROP_BROADCAST);
309296};
310297
311298/* *
0 commit comments