27
27
28
28
# include < climits>
29
29
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
+ };
34
35
35
36
static const char * LOG_TAG = " NimBLERemoteCharacteristic" ;
36
37
37
38
/* *
38
39
* @brief Constructor.
39
40
* @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:
41
42
* struct ble_gatt_chr {
42
43
* uint16_t def_handle;
43
44
* uint16_t val_handle;
@@ -62,73 +63,68 @@ NimBLERemoteCharacteristic::~NimBLERemoteCharacteristic() {
62
63
/* *
63
64
* @brief Callback used by the API when a descriptor is discovered or search complete.
64
65
*/
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
68
76
NIMBLE_LOGD (LOG_TAG, " Descriptor Discovery >> status: %d handle: %d" , rc, (rc == 0 ) ? dsc->handle : -1 );
69
77
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
88
83
pChr->m_vDescriptors .push_back (new NimBLERemoteDescriptor (pChr, dsc));
89
- return 0 ;
84
+ rc = !!uuid * BLE_HS_EDONE ;
90
85
}
91
86
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
+ }
94
91
return rc;
95
92
}
96
93
97
94
/* *
98
95
* @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.
100
98
*/
101
- bool NimBLERemoteCharacteristic::retrieveDescriptors (const NimBLEUUID* uuidFilter ) const {
99
+ bool NimBLERemoteCharacteristic::retrieveDescriptors (NimBLEDescriptorFilter* filter ) const {
102
100
NIMBLE_LOGD (LOG_TAG, " >> retrieveDescriptors() for characteristic: %s" , getUUID ().toString ().c_str ());
103
101
104
102
// If this is the last handle then there are no descriptors
105
103
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 ;
108
106
}
109
107
110
- NimBLETaskData taskData (const_cast <NimBLERemoteCharacteristic*>(this ));
111
- desc_filter_t filter = {uuidFilter, &taskData};
112
-
113
108
int rc = ble_gattc_disc_all_dscs (getClient ()->getConnHandle (),
114
109
getHandle (),
115
110
getRemoteService ()->getEndHandle (),
116
111
NimBLERemoteCharacteristic::descriptorDiscCB,
117
- & filter);
112
+ filter);
118
113
if (rc != 0 ) {
119
114
NIMBLE_LOGE (LOG_TAG, " ble_gattc_disc_all_dscs: rc=%d %s" , rc, NimBLEUtils::returnCodeToString (rc));
120
115
return false ;
121
116
}
122
117
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 ;
128
123
}
129
124
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 ;
132
128
} // retrieveDescriptors
133
129
134
130
/* *
@@ -138,51 +134,36 @@ bool NimBLERemoteCharacteristic::retrieveDescriptors(const NimBLEUUID* uuidFilte
138
134
*/
139
135
NimBLERemoteDescriptor* NimBLERemoteCharacteristic::getDescriptor (const NimBLEUUID& uuid) const {
140
136
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;
143
140
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 ;
147
144
goto Done;
148
145
}
149
146
}
150
147
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);
181
162
}
182
163
183
164
Done:
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 ;
186
167
} // getDescriptor
187
168
188
169
/* *
@@ -311,7 +292,7 @@ size_t NimBLERemoteCharacteristic::deleteDescriptor(const NimBLEUUID& uuid) cons
311
292
* @return True if supported.
312
293
*/
313
294
bool NimBLERemoteCharacteristic::canBroadcast () const {
314
- return (m_properties & BLE_GATT_CHR_PROP_BROADCAST) != 0 ;
295
+ return (m_properties & BLE_GATT_CHR_PROP_BROADCAST);
315
296
};
316
297
317
298
/* *
0 commit comments