2727
2828# include < climits>
2929
30- typedef struct {
31- const NimBLEUUID* uuid;
32- void * task_data;
33- } desc_filter_t ;
30+ struct desc_filter_t {
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;
@@ -63,66 +64,59 @@ NimBLERemoteCharacteristic::~NimBLERemoteCharacteristic() {
6364 * @brief Callback used by the API when a descriptor is discovered or search complete.
6465 */
6566int 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+ uint16_t connHandle , const ble_gatt_error* error, uint16_t chrHandle , const ble_gatt_dsc* dsc, void * arg) {
6768 int rc = error->status ;
6869 NIMBLE_LOGD (LOG_TAG, " Descriptor Discovery >> status: %d handle: %d" , rc, (rc == 0 ) ? dsc->handle : -1 );
6970
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- }
71+ auto filter = (desc_filter_t *)arg;
72+ auto pTaskData = (NimBLETaskData*)filter->taskData ;
73+ const auto pChr = (NimBLERemoteCharacteristic*)pTaskData->m_pInstance ;
74+ const auto uuid = filter->uuid ; // UUID to filter for
8775
76+ // Results for chrHandle added until rc != 0
77+ // Must find specified UUID if filter is used
78+ if (rc == 0 && pChr->getHandle () == chrHandle
79+ && (!uuid || 0 == ble_uuid_cmp (uuid->getBase (), &dsc->uuid .u ))) {
80+ // Return BLE_HS_EDONE if the descriptor was found, stop the search
8881 pChr->m_vDescriptors .push_back (new NimBLERemoteDescriptor (pChr, dsc));
89- return 0 ;
82+ rc = !!uuid * BLE_HS_EDONE ;
9083 }
9184
92- NimBLEUtils::taskRelease (*pTaskData, rc);
93- NIMBLE_LOGD (LOG_TAG, " << Descriptor Discovery" );
85+ if (rc != 0 ) {
86+ NimBLEUtils::taskRelease (*pTaskData, rc);
87+ NIMBLE_LOGD (LOG_TAG, " << Descriptor Discovery" );
88+ }
9489 return rc;
9590}
9691
9792/* *
9893 * @brief Populate the descriptors (if any) for this characteristic.
99- * @param [in] the end handle of the characteristic, or the service, whichever comes first.
94+ * @param [in] filter Structure containing pointers to descriptor, UUID, and task data.
95+ * @return True if successfully retrieved, success = 0 or BLE_HS_EDONE.
10096 */
101- bool NimBLERemoteCharacteristic::retrieveDescriptors (const NimBLEUUID* uuidFilter ) const {
97+ bool NimBLERemoteCharacteristic::retrieveDescriptors (desc_filter_t * filter ) const {
10298 NIMBLE_LOGD (LOG_TAG, " >> retrieveDescriptors() for characteristic: %s" , getUUID ().toString ().c_str ());
10399
104- NimBLETaskData taskData (const_cast <NimBLERemoteCharacteristic*>(this ));
105- desc_filter_t filter = {uuidFilter, &taskData};
106-
107100 int rc = ble_gattc_disc_all_dscs (getClient ()->getConnHandle (),
108101 getHandle (),
109102 getRemoteService ()->getEndHandle (),
110103 NimBLERemoteCharacteristic::descriptorDiscCB,
111- & filter);
104+ filter);
112105 if (rc != 0 ) {
113106 NIMBLE_LOGE (LOG_TAG, " ble_gattc_disc_all_dscs: rc=%d %s" , rc, NimBLEUtils::returnCodeToString (rc));
114107 return false ;
115108 }
116109
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 ;
110+ NimBLEUtils::taskWait (filter-> taskData , BLE_NPL_TIME_FOREVER);
111+ rc = ((NimBLETaskData*)filter-> taskData )-> m_flags ;
112+ if (rc ! = BLE_HS_EDONE) {
113+ NIMBLE_LOGE (LOG_TAG, " << retrieveDescriptors(): failed: rc= %d %s " , rc, NimBLEUtils::returnCodeToString (rc ));
114+ return false ;
122115 }
123116
124- NIMBLE_LOGE (LOG_TAG, " << retrieveDescriptors(): failed: rc=%d %s" , rc, NimBLEUtils::returnCodeToString (rc));
125- return false ;
117+ filter->dsc = m_vDescriptors.back ();
118+ NIMBLE_LOGD (LOG_TAG, " << retrieveDescriptors(): found %d descriptors." , m_vDescriptors.size ());
119+ return true ;
126120} // retrieveDescriptors
127121
128122/* *
@@ -132,51 +126,36 @@ bool NimBLERemoteCharacteristic::retrieveDescriptors(const NimBLEUUID* uuidFilte
132126 */
133127NimBLERemoteDescriptor* NimBLERemoteCharacteristic::getDescriptor (const NimBLEUUID& uuid) const {
134128 NIMBLE_LOGD (LOG_TAG, " >> getDescriptor: uuid: %s" , uuid.toString ().c_str ());
135- NimBLERemoteDescriptor* pDsc = nullptr ;
136- size_t prev_size = m_vDescriptors.size ();
129+ NimBLETaskData taskData (const_cast <NimBLERemoteCharacteristic*>(this ));
130+ desc_filter_t filter = {nullptr , &uuid, &taskData};
131+ NimBLEUUID uuidTmp;
137132
138133 for (const auto & it : m_vDescriptors) {
139134 if (it->getUUID () == uuid) {
140- pDsc = it;
135+ filter. dsc = it;
141136 goto Done;
142137 }
143138 }
144139
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- }
140+ if (!retrieveDescriptors (&filter) || filter.dsc ) {
141+ goto Done;
142+ }
143+ // Try again with 128 bit uuid if request succeeded with no uuid found.
144+ if (uuid.bitSize () == BLE_UUID_TYPE_16 || uuid.bitSize () == BLE_UUID_TYPE_32) {
145+ uuidTmp = NimBLEUUID (uuid).to128 ();
146+ retrieveDescriptors (&filter);
147+ goto Done;
148+ }
149+ // Try again with 16 bit uuid if request succeeded with no uuid found.
150+ // If the uuid was 128 bit but not of the BLE base type this check will fail.
151+ uuidTmp = NimBLEUUID (uuid).to16 ();
152+ if (uuidTmp.bitSize () == BLE_UUID_TYPE_16) {
153+ retrieveDescriptors (&filter);
175154 }
176155
177156Done:
178- NIMBLE_LOGD (LOG_TAG, " << getDescriptor: %sfound" , pDsc ? " " : " not " );
179- return pDsc ;
157+ NIMBLE_LOGD (LOG_TAG, " << getDescriptor: %sfound" , filter. dsc ? " " : " not " );
158+ return filter. dsc ;
180159} // getDescriptor
181160
182161/* *
@@ -305,7 +284,7 @@ size_t NimBLERemoteCharacteristic::deleteDescriptor(const NimBLEUUID& uuid) cons
305284 * @return True if supported.
306285 */
307286bool NimBLERemoteCharacteristic::canBroadcast () const {
308- return (m_properties & BLE_GATT_CHR_PROP_BROADCAST) != 0 ;
287+ return (m_properties & BLE_GATT_CHR_PROP_BROADCAST);
309288};
310289
311290/* *
0 commit comments