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,73 +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
104102 // If this is the last handle then there are no descriptors
105103 if (getHandle () == getRemoteService ()->getEndHandle ()) {
106- NIMBLE_LOGD (LOG_TAG, " << retrieveDescriptors(): found 0 descriptors." );
107- return true ;
104+ NIMBLE_LOGD (LOG_TAG, " << retrieveDescriptors(): found 0 descriptors." );
105+ return true ;
108106 }
109107
110- NimBLETaskData taskData (const_cast <NimBLERemoteCharacteristic*>(this ));
111- desc_filter_t filter = {uuidFilter, &taskData};
112-
113108 int rc = ble_gattc_disc_all_dscs (getClient ()->getConnHandle (),
114109 getHandle (),
115110 getRemoteService ()->getEndHandle (),
116111 NimBLERemoteCharacteristic::descriptorDiscCB,
117- & filter);
112+ filter);
118113 if (rc != 0 ) {
119114 NIMBLE_LOGE (LOG_TAG, " ble_gattc_disc_all_dscs: rc=%d %s" , rc, NimBLEUtils::returnCodeToString (rc));
120115 return false ;
121116 }
122117
123- NimBLEUtils::taskWait (taskData, BLE_NPL_TIME_FOREVER);
124- rc = taskData. m_flags ;
125- if (rc == 0 || rc = = BLE_HS_EDONE) {
126- NIMBLE_LOGD (LOG_TAG, " << retrieveDescriptors(): found %d descriptors. " , m_vDescriptors. size ( ));
127- 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 ;
128123 }
129124
130- NIMBLE_LOGE (LOG_TAG, " << retrieveDescriptors(): failed: rc=%d %s" , rc, NimBLEUtils::returnCodeToString (rc));
131- return false ;
125+ filter->dsc = m_vDescriptors.back ();
126+ NIMBLE_LOGD (LOG_TAG, " << retrieveDescriptors(): found %d descriptors." , m_vDescriptors.size ());
127+ return true ;
132128} // retrieveDescriptors
133129
134130/* *
@@ -138,51 +134,36 @@ bool NimBLERemoteCharacteristic::retrieveDescriptors(const NimBLEUUID* uuidFilte
138134 */
139135NimBLERemoteDescriptor* NimBLERemoteCharacteristic::getDescriptor (const NimBLEUUID& uuid) const {
140136 NIMBLE_LOGD (LOG_TAG, " >> getDescriptor: uuid: %s" , uuid.toString ().c_str ());
141- NimBLERemoteDescriptor* pDsc = nullptr ;
142- size_t prev_size = m_vDescriptors.size ();
137+ NimBLETaskData taskData (const_cast <NimBLERemoteCharacteristic*>(this ));
138+ NimBLEDescriptorFilter filter = {nullptr , &uuid, &taskData};
139+ NimBLEUUID uuidTmp;
143140
144- for (const auto & it : m_vDescriptors) {
145- if (it ->getUUID () == uuid) {
146- pDsc = it ;
141+ for (const auto & dsc : m_vDescriptors) {
142+ if (dsc ->getUUID () == uuid) {
143+ filter. dsc = dsc ;
147144 goto Done;
148145 }
149146 }
150147
151- if (retrieveDescriptors (&uuid)) {
152- if (m_vDescriptors.size () > prev_size) {
153- pDsc = m_vDescriptors.back ();
154- goto Done;
155- }
156-
157- // If the request was successful but 16/32 bit uuid not found
158- // try again with the 128 bit uuid.
159- if (uuid.bitSize () == BLE_UUID_TYPE_16 || uuid.bitSize () == BLE_UUID_TYPE_32) {
160- NimBLEUUID uuid128 (uuid);
161- uuid128.to128 ();
162- if (retrieveDescriptors (&uuid128)) {
163- if (m_vDescriptors.size () > prev_size) {
164- pDsc = m_vDescriptors.back ();
165- }
166- }
167- } else {
168- // If the request was successful but the 128 bit uuid not found
169- // try again with the 16 bit uuid.
170- NimBLEUUID uuid16 (uuid);
171- uuid16.to16 ();
172- // if the uuid was 128 bit but not of the BLE base type this check will fail
173- if (uuid16.bitSize () == BLE_UUID_TYPE_16) {
174- if (retrieveDescriptors (&uuid16)) {
175- if (m_vDescriptors.size () > prev_size) {
176- pDsc = m_vDescriptors.back ();
177- }
178- }
179- }
180- }
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);
181162 }
182163
183164Done:
184- NIMBLE_LOGD (LOG_TAG, " << getDescriptor: %sfound" , pDsc ? " " : " not " );
185- return pDsc ;
165+ NIMBLE_LOGD (LOG_TAG, " << getDescriptor: %sfound" , filter. dsc ? " " : " not " );
166+ return filter. dsc ;
186167} // getDescriptor
187168
188169/* *
@@ -311,7 +292,7 @@ size_t NimBLERemoteCharacteristic::deleteDescriptor(const NimBLEUUID& uuid) cons
311292 * @return True if supported.
312293 */
313294bool NimBLERemoteCharacteristic::canBroadcast () const {
314- return (m_properties & BLE_GATT_CHR_PROP_BROADCAST) != 0 ;
295+ return (m_properties & BLE_GATT_CHR_PROP_BROADCAST);
315296};
316297
317298/* *
0 commit comments