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,61 @@ 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
95+ * The descriptor pointer
96+ * The end handle of the characteristic, or the service, whichever comes first.
97+ * @return True if successfully retrieved, success = 0 or BLE_HS_EDONE.
10098 */
101- bool NimBLERemoteCharacteristic::retrieveDescriptors (const NimBLEUUID* uuidFilter ) const {
99+ bool NimBLERemoteCharacteristic::retrieveDescriptors (desc_filter_t * 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};
106-
107102 int rc = ble_gattc_disc_all_dscs (getClient ()->getConnHandle (),
108103 getHandle (),
109104 getRemoteService ()->getEndHandle (),
110105 NimBLERemoteCharacteristic::descriptorDiscCB,
111- & filter);
106+ filter);
112107 if (rc != 0 ) {
113108 NIMBLE_LOGE (LOG_TAG, " ble_gattc_disc_all_dscs: rc=%d %s" , rc, NimBLEUtils::returnCodeToString (rc));
114109 return false ;
115110 }
116111
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 ;
112+ NimBLEUtils::taskWait (filter-> taskData , BLE_NPL_TIME_FOREVER);
113+ rc = ((NimBLETaskData*)filter-> taskData )-> m_flags ;
114+ if (rc ! = BLE_HS_EDONE) {
115+ NIMBLE_LOGE (LOG_TAG, " << retrieveDescriptors(): failed: rc= %d %s " , rc, NimBLEUtils::returnCodeToString (rc ));
116+ return false ;
122117 }
123118
124- NIMBLE_LOGE (LOG_TAG, " << retrieveDescriptors(): failed: rc=%d %s" , rc, NimBLEUtils::returnCodeToString (rc));
125- return false ;
119+ filter->dsc = m_vDescriptors.back ();
120+ NIMBLE_LOGD (LOG_TAG, " << retrieveDescriptors(): found %d descriptors." , m_vDescriptors.size ());
121+ return true ;
126122} // retrieveDescriptors
127123
128124/* *
@@ -132,51 +128,36 @@ bool NimBLERemoteCharacteristic::retrieveDescriptors(const NimBLEUUID* uuidFilte
132128 */
133129NimBLERemoteDescriptor* NimBLERemoteCharacteristic::getDescriptor (const NimBLEUUID& uuid) const {
134130 NIMBLE_LOGD (LOG_TAG, " >> getDescriptor: uuid: %s" , uuid.toString ().c_str ());
135- NimBLERemoteDescriptor* pDsc = nullptr ;
136- size_t prev_size = m_vDescriptors.size ();
131+ NimBLETaskData taskData (const_cast <NimBLERemoteCharacteristic*>(this ));
132+ desc_filter_t filter = {nullptr , &uuid, &taskData};
133+ NimBLEUUID uuidTmp;
137134
138135 for (const auto & it : m_vDescriptors) {
139136 if (it->getUUID () == uuid) {
140- pDsc = it;
137+ filter. dsc = it;
141138 goto Done;
142139 }
143140 }
144141
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- }
142+ if (!retrieveDescriptors (&filter) || filter.dsc ) {
143+ goto Done;
144+ }
145+ // Try again with 128 bit uuid if request succeeded with no uuid found.
146+ if (uuid.bitSize () == BLE_UUID_TYPE_16 || uuid.bitSize () == BLE_UUID_TYPE_32) {
147+ uuidTmp = NimBLEUUID (uuid).to128 ();
148+ retrieveDescriptors (&filter);
149+ goto Done;
150+ }
151+ // Try again with 16 bit uuid if request succeeded with no uuid found.
152+ // If the uuid was 128 bit but not of the BLE base type this check will fail.
153+ uuidTmp = NimBLEUUID (uuid).to16 ();
154+ if (uuidTmp.bitSize () == BLE_UUID_TYPE_16) {
155+ retrieveDescriptors (&filter);
175156 }
176157
177158Done:
178- NIMBLE_LOGD (LOG_TAG, " << getDescriptor: %sfound" , pDsc ? " " : " not " );
179- return pDsc ;
159+ NIMBLE_LOGD (LOG_TAG, " << getDescriptor: %sfound" , filter. dsc ? " " : " not " );
160+ return filter. dsc ;
180161} // getDescriptor
181162
182163/* *
@@ -305,7 +286,7 @@ size_t NimBLERemoteCharacteristic::deleteDescriptor(const NimBLEUUID& uuid) cons
305286 * @return True if supported.
306287 */
307288bool NimBLERemoteCharacteristic::canBroadcast () const {
308- return (m_properties & BLE_GATT_CHR_PROP_BROADCAST) != 0 ;
289+ return (m_properties & BLE_GATT_CHR_PROP_BROADCAST);
309290};
310291
311292/* *
0 commit comments