diff --git a/src/NimBLERemoteService.cpp b/src/NimBLERemoteService.cpp index 2651f5fb..f15a9a31 100644 --- a/src/NimBLERemoteService.cpp +++ b/src/NimBLERemoteService.cpp @@ -25,7 +25,6 @@ # include "NimBLELog.h" # include -# include static const char* LOG_TAG = "NimBLERemoteService"; @@ -77,31 +76,22 @@ NimBLERemoteCharacteristic* NimBLERemoteService::getCharacteristic(const char* u NimBLERemoteCharacteristic* NimBLERemoteService::getCharacteristic(const NimBLEUUID& uuid) const { NIMBLE_LOGD(LOG_TAG, ">> getCharacteristic: uuid: %s", uuid.toString().c_str()); NimBLERemoteCharacteristic* pChar = nullptr; - size_t prev_size = m_vChars.size(); for (const auto& it : m_vChars) { if (it->getUUID() == uuid) { pChar = it; - goto Done; + NIMBLE_LOGD(LOG_TAG, "<< getCharacteristic: found in cache"); + return pChar; } } - if (retrieveCharacteristics(&uuid)) { - if (m_vChars.size() > prev_size) { - pChar = m_vChars.back(); - goto Done; - } - + if (retrieveCharacteristics(&uuid, &pChar) && pChar == nullptr) { // If the request was successful but 16/32 bit uuid not found // try again with the 128 bit uuid. if (uuid.bitSize() == BLE_UUID_TYPE_16 || uuid.bitSize() == BLE_UUID_TYPE_32) { NimBLEUUID uuid128(uuid); uuid128.to128(); - if (retrieveCharacteristics(&uuid128)) { - if (m_vChars.size() > prev_size) { - pChar = m_vChars.back(); - } - } + retrieveCharacteristics(&uuid128, &pChar); } else { // If the request was successful but the 128 bit uuid not found // try again with the 16 bit uuid. @@ -109,16 +99,11 @@ NimBLERemoteCharacteristic* NimBLERemoteService::getCharacteristic(const NimBLEU uuid16.to16(); // if the uuid was 128 bit but not of the BLE base type this check will fail if (uuid16.bitSize() == BLE_UUID_TYPE_16) { - if (retrieveCharacteristics(&uuid16)) { - if (m_vChars.size() > prev_size) { - pChar = m_vChars.back(); - } - } + retrieveCharacteristics(&uuid16, &pChar); } } } -Done: NIMBLE_LOGD(LOG_TAG, "<< Characteristic %sfound", pChar ? "" : "not "); return pChar; } // getCharacteristic @@ -166,7 +151,18 @@ int NimBLERemoteService::characteristicDiscCB(uint16_t conn_handle, } if (error->status == 0) { - pSvc->m_vChars.push_back(new NimBLERemoteCharacteristic(pSvc, chr)); + // insert in handle order + auto pNewChar = new NimBLERemoteCharacteristic(pSvc, chr); + for (auto it = pSvc->m_vChars.begin(); it != pSvc->m_vChars.end(); ++it) { + if ((*it)->getHandle() > chr->def_handle) { + pSvc->m_vChars.insert(it, pNewChar); + pTaskData->m_pBuf = pNewChar; + return 0; + } + } + + pSvc->m_vChars.push_back(pNewChar); + pTaskData->m_pBuf = pNewChar; return 0; } @@ -180,7 +176,7 @@ int NimBLERemoteService::characteristicDiscCB(uint16_t conn_handle, * This function will not return until we have all the characteristics. * @return True if successful. */ -bool NimBLERemoteService::retrieveCharacteristics(const NimBLEUUID* uuidFilter) const { +bool NimBLERemoteService::retrieveCharacteristics(const NimBLEUUID* uuidFilter, NimBLERemoteCharacteristic** ppChar) const { NIMBLE_LOGD(LOG_TAG, ">> retrieveCharacteristics()"); int rc = 0; NimBLETaskData taskData(const_cast(this)); @@ -208,12 +204,9 @@ bool NimBLERemoteService::retrieveCharacteristics(const NimBLEUUID* uuidFilter) NimBLEUtils::taskWait(taskData, BLE_NPL_TIME_FOREVER); rc = taskData.m_flags; if (rc == 0 || rc == BLE_HS_EDONE) { - // sort the characteristics vector by handle to make sure the search range for descriptors is correct - std::sort(m_vChars.begin(), - m_vChars.end(), - [](const NimBLERemoteCharacteristic* a, const NimBLERemoteCharacteristic* b) { - return a->getHandle() < b->getHandle(); - }); + if (ppChar != nullptr) { + *ppChar = static_cast(taskData.m_pBuf); + } NIMBLE_LOGD(LOG_TAG, "<< retrieveCharacteristics()"); return true; } diff --git a/src/NimBLERemoteService.h b/src/NimBLERemoteService.h index c2aa445d..4d953494 100644 --- a/src/NimBLERemoteService.h +++ b/src/NimBLERemoteService.h @@ -53,7 +53,7 @@ class NimBLERemoteService : public NimBLEAttribute { NimBLERemoteService(NimBLEClient* pClient, const struct ble_gatt_svc* service); ~NimBLERemoteService(); - bool retrieveCharacteristics(const NimBLEUUID* uuidFilter = nullptr) const; + bool retrieveCharacteristics(const NimBLEUUID* uuidFilter = nullptr, NimBLERemoteCharacteristic** ppChar = nullptr) const; static int characteristicDiscCB(uint16_t conn_handle, const struct ble_gatt_error* error, const struct ble_gatt_chr* chr,