From b064cc65d412c0a69b1be61afcc4e52d97b5c567 Mon Sep 17 00:00:00 2001 From: wakwak_koba <5591750+wakwak-koba@users.noreply.github.com> Date: Wed, 13 Jan 2021 18:04:52 -0700 Subject: [PATCH] Find characteristic end handle using the next characterisic handle. On some devices, searching for descriptors using the service end handle would return an invalid error. This patch instead uses the handle of the next characteristic as the end handle (if available). --- src/NimBLERemoteCharacteristic.cpp | 11 +++++++++-- src/NimBLERemoteService.cpp | 17 +++++++++++++++++ src/NimBLERemoteService.h | 1 + 3 files changed, 27 insertions(+), 2 deletions(-) diff --git a/src/NimBLERemoteCharacteristic.cpp b/src/NimBLERemoteCharacteristic.cpp index a81d48d..8bc5090 100644 --- a/src/NimBLERemoteCharacteristic.cpp +++ b/src/NimBLERemoteCharacteristic.cpp @@ -209,15 +209,21 @@ int NimBLERemoteCharacteristic::descriptorDiscCB(uint16_t conn_handle, bool NimBLERemoteCharacteristic::retrieveDescriptors(const NimBLEUUID *uuid_filter) { NIMBLE_LOGD(LOG_TAG, ">> retrieveDescriptors() for characteristic: %s", getUUID().toString().c_str()); + uint16_t endHandle = getRemoteService()->getEndHandle(this); + if(m_handle >= endHandle) { + return false; + } + int rc = 0; ble_task_data_t taskData = {this, xTaskGetCurrentTaskHandle(), 0, nullptr}; desc_filter_t filter = {uuid_filter, &taskData}; rc = ble_gattc_disc_all_dscs(getRemoteService()->getClient()->getConnId(), m_handle, - getRemoteService()->getEndHandle(), + endHandle, NimBLERemoteCharacteristic::descriptorDiscCB, &filter); + if (rc != 0) { NIMBLE_LOGE(LOG_TAG, "ble_gattc_disc_all_chrs: rc=%d %s", rc, NimBLEUtils::returnCodeToString(rc)); return false; @@ -226,12 +232,13 @@ bool NimBLERemoteCharacteristic::retrieveDescriptors(const NimBLEUUID *uuid_filt ulTaskNotifyTake(pdTRUE, portMAX_DELAY); if(taskData.rc != 0) { + NIMBLE_LOGE(LOG_TAG, "ble_gattc_disc_all_chrs: startHandle:%d endHandle:%d taskData.rc=%d %s", m_handle, endHandle, taskData.rc, NimBLEUtils::returnCodeToString(0x0100+taskData.rc)); return false; } return true; NIMBLE_LOGD(LOG_TAG, "<< retrieveDescriptors(): Found %d descriptors.", m_descriptorVector.size()); -} // getDescriptors +} // retrieveDescriptors /** diff --git a/src/NimBLERemoteService.cpp b/src/NimBLERemoteService.cpp index 0b22992..cb20e0b 100644 --- a/src/NimBLERemoteService.cpp +++ b/src/NimBLERemoteService.cpp @@ -249,6 +249,23 @@ uint16_t NimBLERemoteService::getEndHandle() { return m_endHandle; } // getEndHandle +/** + * @brief Get the end handle of specified NimBLERemoteCharacteristic. + */ + +uint16_t NimBLERemoteService::getEndHandle(NimBLERemoteCharacteristic *pCharacteristic) { + uint16_t endHandle = m_endHandle; + + for(auto &it: m_characteristicVector) { + uint16_t defHandle = it->getDefHandle() - 1; + if(defHandle > pCharacteristic->getDefHandle() && endHandle > defHandle) { + endHandle = defHandle; + } + } + + return endHandle; +} // getEndHandle + /** * @brief Get the service start handle. diff --git a/src/NimBLERemoteService.h b/src/NimBLERemoteService.h index 751c9ef..4920844 100644 --- a/src/NimBLERemoteService.h +++ b/src/NimBLERemoteService.h @@ -70,6 +70,7 @@ private: uint16_t getStartHandle(); uint16_t getEndHandle(); + uint16_t getEndHandle(NimBLERemoteCharacteristic *pCharacteristic); void releaseSemaphores(); // Properties