Skip to content

Commit bb4bdcc

Browse files
committed
[Bugfix] get remote characteristic by uuid returning the wrong instance.
This fixes a bug introduced when sorting the characteristic vector where the last item on in the vector was returned but the characteristc wasn't at the end anymore. This reverts the previous sorting of the vector after retrieval and instead sorts as the characteristics are found and also provides a pointer to the characteristic from the retrieval callback.
1 parent cb02931 commit bb4bdcc

2 files changed

Lines changed: 18 additions & 29 deletions

File tree

src/NimBLERemoteService.cpp

Lines changed: 17 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@
2525
# include "NimBLELog.h"
2626

2727
# include <climits>
28-
# include <algorithm>
2928

3029
static const char* LOG_TAG = "NimBLERemoteService";
3130

@@ -77,48 +76,34 @@ NimBLERemoteCharacteristic* NimBLERemoteService::getCharacteristic(const char* u
7776
NimBLERemoteCharacteristic* NimBLERemoteService::getCharacteristic(const NimBLEUUID& uuid) const {
7877
NIMBLE_LOGD(LOG_TAG, ">> getCharacteristic: uuid: %s", uuid.toString().c_str());
7978
NimBLERemoteCharacteristic* pChar = nullptr;
80-
size_t prev_size = m_vChars.size();
8179

8280
for (const auto& it : m_vChars) {
8381
if (it->getUUID() == uuid) {
8482
pChar = it;
85-
goto Done;
83+
NIMBLE_LOGD(LOG_TAG, "<< getCharacteristic: found in cache");
84+
return pChar;
8685
}
8786
}
8887

89-
if (retrieveCharacteristics(&uuid)) {
90-
if (m_vChars.size() > prev_size) {
91-
pChar = m_vChars.back();
92-
goto Done;
93-
}
94-
88+
if (retrieveCharacteristics(&uuid, &pChar) && pChar == nullptr) {
9589
// If the request was successful but 16/32 bit uuid not found
9690
// try again with the 128 bit uuid.
9791
if (uuid.bitSize() == BLE_UUID_TYPE_16 || uuid.bitSize() == BLE_UUID_TYPE_32) {
9892
NimBLEUUID uuid128(uuid);
9993
uuid128.to128();
100-
if (retrieveCharacteristics(&uuid128)) {
101-
if (m_vChars.size() > prev_size) {
102-
pChar = m_vChars.back();
103-
}
104-
}
94+
retrieveCharacteristics(&uuid128, &pChar);
10595
} else {
10696
// If the request was successful but the 128 bit uuid not found
10797
// try again with the 16 bit uuid.
10898
NimBLEUUID uuid16(uuid);
10999
uuid16.to16();
110100
// if the uuid was 128 bit but not of the BLE base type this check will fail
111101
if (uuid16.bitSize() == BLE_UUID_TYPE_16) {
112-
if (retrieveCharacteristics(&uuid16)) {
113-
if (m_vChars.size() > prev_size) {
114-
pChar = m_vChars.back();
115-
}
116-
}
102+
retrieveCharacteristics(&uuid16, &pChar);
117103
}
118104
}
119105
}
120106

121-
Done:
122107
NIMBLE_LOGD(LOG_TAG, "<< Characteristic %sfound", pChar ? "" : "not ");
123108
return pChar;
124109
} // getCharacteristic
@@ -166,7 +151,14 @@ int NimBLERemoteService::characteristicDiscCB(uint16_t conn_handle,
166151
}
167152

168153
if (error->status == 0) {
169-
pSvc->m_vChars.push_back(new NimBLERemoteCharacteristic(pSvc, chr));
154+
// insert in handle order
155+
for (auto it = pSvc->m_vChars.begin(); it != pSvc->m_vChars.end(); ++it) {
156+
if ((*it)->getHandle() > chr->def_handle) {
157+
pTaskData->m_pBuf = (*pSvc->m_vChars.insert(it, new NimBLERemoteCharacteristic(pSvc, chr)));
158+
return 0;
159+
}
160+
}
161+
pTaskData->m_pBuf = pSvc->m_vChars.emplace_back(new NimBLERemoteCharacteristic(pSvc, chr));
170162
return 0;
171163
}
172164

@@ -180,7 +172,7 @@ int NimBLERemoteService::characteristicDiscCB(uint16_t conn_handle,
180172
* This function will not return until we have all the characteristics.
181173
* @return True if successful.
182174
*/
183-
bool NimBLERemoteService::retrieveCharacteristics(const NimBLEUUID* uuidFilter) const {
175+
bool NimBLERemoteService::retrieveCharacteristics(const NimBLEUUID* uuidFilter, NimBLERemoteCharacteristic** ppChar) const {
184176
NIMBLE_LOGD(LOG_TAG, ">> retrieveCharacteristics()");
185177
int rc = 0;
186178
NimBLETaskData taskData(const_cast<NimBLERemoteService*>(this));
@@ -208,12 +200,9 @@ bool NimBLERemoteService::retrieveCharacteristics(const NimBLEUUID* uuidFilter)
208200
NimBLEUtils::taskWait(taskData, BLE_NPL_TIME_FOREVER);
209201
rc = taskData.m_flags;
210202
if (rc == 0 || rc == BLE_HS_EDONE) {
211-
// sort the characteristics vector by handle to make sure the search range for descriptors is correct
212-
std::sort(m_vChars.begin(),
213-
m_vChars.end(),
214-
[](const NimBLERemoteCharacteristic* a, const NimBLERemoteCharacteristic* b) {
215-
return a->getHandle() < b->getHandle();
216-
});
203+
if (ppChar != nullptr) {
204+
*ppChar = static_cast<NimBLERemoteCharacteristic*>(taskData.m_pBuf);
205+
}
217206
NIMBLE_LOGD(LOG_TAG, "<< retrieveCharacteristics()");
218207
return true;
219208
}

src/NimBLERemoteService.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ class NimBLERemoteService : public NimBLEAttribute {
5353

5454
NimBLERemoteService(NimBLEClient* pClient, const struct ble_gatt_svc* service);
5555
~NimBLERemoteService();
56-
bool retrieveCharacteristics(const NimBLEUUID* uuidFilter = nullptr) const;
56+
bool retrieveCharacteristics(const NimBLEUUID* uuidFilter = nullptr, NimBLERemoteCharacteristic** ppChar = nullptr) const;
5757
static int characteristicDiscCB(uint16_t conn_handle,
5858
const struct ble_gatt_error* error,
5959
const struct ble_gatt_chr* chr,

0 commit comments

Comments
 (0)