Skip to content

[Bugfix]Provide default task data when retrieving all descriptors. #888

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Feb 8, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 25 additions & 21 deletions src/NimBLERemoteCharacteristic.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -63,11 +63,8 @@ NimBLERemoteCharacteristic::~NimBLERemoteCharacteristic() {
/**
* @brief Callback used by the API when a descriptor is discovered or search complete.
*/
int NimBLERemoteCharacteristic::descriptorDiscCB(uint16_t connHandle,
const ble_gatt_error* error,
uint16_t chrHandle,
const ble_gatt_dsc* dsc,
void* arg) {
int NimBLERemoteCharacteristic::descriptorDiscCB(
uint16_t connHandle, const ble_gatt_error* error, uint16_t chrHandle, const ble_gatt_dsc* dsc, void* arg) {
int rc = error->status;
auto filter = (NimBLEDescriptorFilter*)arg;
auto pTaskData = (NimBLETaskData*)filter->taskData;
Expand All @@ -77,8 +74,7 @@ int NimBLERemoteCharacteristic::descriptorDiscCB(uint16_t connHandle,

// Results for chrHandle added until rc != 0
// Must find specified UUID if filter is used
if (rc == 0 && pChr->getHandle() == chrHandle
&& (!uuid || 0 == ble_uuid_cmp(uuid->getBase(), &dsc->uuid.u))) {
if (rc == 0 && pChr->getHandle() == chrHandle && (!uuid || 0 == ble_uuid_cmp(uuid->getBase(), &dsc->uuid.u))) {
// Return BLE_HS_EDONE if the descriptor was found, stop the search
pChr->m_vDescriptors.push_back(new NimBLERemoteDescriptor(pChr, dsc));
rc = !!uuid * BLE_HS_EDONE;
Expand All @@ -93,10 +89,10 @@ int NimBLERemoteCharacteristic::descriptorDiscCB(uint16_t connHandle,

/**
* @brief Populate the descriptors (if any) for this characteristic.
* @param [in] filter Structure containing pointers to descriptor, UUID, and task data.
* @param [in] pFilter Pointer to a filter containing pointers to descriptor, UUID, and task data.
* @return True if successfully retrieved, success = BLE_HS_EDONE.
*/
bool NimBLERemoteCharacteristic::retrieveDescriptors(NimBLEDescriptorFilter* filter) const {
bool NimBLERemoteCharacteristic::retrieveDescriptors(NimBLEDescriptorFilter* pFilter) const {
NIMBLE_LOGD(LOG_TAG, ">> retrieveDescriptors() for characteristic: %s", getUUID().toString().c_str());

// If this is the last handle then there are no descriptors
Expand All @@ -105,24 +101,30 @@ bool NimBLERemoteCharacteristic::retrieveDescriptors(NimBLEDescriptorFilter* fil
return true;
}

NimBLETaskData taskData(const_cast<NimBLERemoteCharacteristic*>(this));
NimBLEDescriptorFilter defaultFilter{nullptr, nullptr, &taskData};
if (pFilter == nullptr) {
pFilter = &defaultFilter;
}

int rc = ble_gattc_disc_all_dscs(getClient()->getConnHandle(),
getHandle(),
getRemoteService()->getEndHandle(),
NimBLERemoteCharacteristic::descriptorDiscCB,
filter);
pFilter);
if (rc != 0) {
NIMBLE_LOGE(LOG_TAG, "ble_gattc_disc_all_dscs: rc=%d %s", rc, NimBLEUtils::returnCodeToString(rc));
return false;
}

NimBLEUtils::taskWait(filter->taskData, BLE_NPL_TIME_FOREVER);
rc = ((NimBLETaskData*)filter->taskData)->m_flags;
NimBLEUtils::taskWait(pFilter->taskData, BLE_NPL_TIME_FOREVER);
rc = ((NimBLETaskData*)pFilter->taskData)->m_flags;
if (rc != BLE_HS_EDONE) {
NIMBLE_LOGE(LOG_TAG, "<< retrieveDescriptors(): failed: rc=%d %s", rc, NimBLEUtils::returnCodeToString(rc));
return false;
}

filter->dsc = m_vDescriptors.back();
pFilter->dsc = m_vDescriptors.back();
NIMBLE_LOGD(LOG_TAG, "<< retrieveDescriptors(): found %d descriptors.", m_vDescriptors.size());
return true;
} // retrieveDescriptors
Expand All @@ -134,9 +136,9 @@ bool NimBLERemoteCharacteristic::retrieveDescriptors(NimBLEDescriptorFilter* fil
*/
NimBLERemoteDescriptor* NimBLERemoteCharacteristic::getDescriptor(const NimBLEUUID& uuid) const {
NIMBLE_LOGD(LOG_TAG, ">> getDescriptor: uuid: %s", uuid.toString().c_str());
NimBLEUUID uuidTmp{uuid};
NimBLETaskData taskData(const_cast<NimBLERemoteCharacteristic*>(this));
NimBLEDescriptorFilter filter = {nullptr, &uuid, &taskData};
NimBLEUUID uuidTmp;
NimBLEDescriptorFilter filter{nullptr, &uuidTmp, &taskData};

for (const auto& dsc : m_vDescriptors) {
if (dsc->getUUID() == uuid) {
Expand All @@ -148,16 +150,18 @@ NimBLERemoteDescriptor* NimBLERemoteCharacteristic::getDescriptor(const NimBLEUU
if (!retrieveDescriptors(&filter) || filter.dsc) {
goto Done;
}
// Try again with 128 bit uuid if request succeeded with no uuid found.
if (uuid.bitSize() == BLE_UUID_TYPE_16 || uuid.bitSize() == BLE_UUID_TYPE_32) {
uuidTmp = NimBLEUUID(uuid).to128();

// Try again with 128 bit uuid if request succeeded but no descriptor found.
if (uuid.bitSize() != BLE_UUID_TYPE_128) {
uuidTmp.to128();
retrieveDescriptors(&filter);
goto Done;
}
// Try again with 16 bit uuid if request succeeded with no uuid found.
// If the uuid was 128 bit but not of the BLE base type this check will fail.
uuidTmp = NimBLEUUID(uuid).to16();

// If the uuid was 128 bit, try again with 16 bit uuid.
uuidTmp.to16();
if (uuidTmp.bitSize() == BLE_UUID_TYPE_16) {
filter.uuid = &uuidTmp;
retrieveDescriptors(&filter);
}

Expand Down
2 changes: 1 addition & 1 deletion src/NimBLERemoteCharacteristic.h
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ class NimBLERemoteCharacteristic : public NimBLERemoteValueAttribute {
~NimBLERemoteCharacteristic();

bool setNotify(uint16_t val, notify_callback notifyCallback = nullptr, bool response = true) const;
bool retrieveDescriptors(NimBLEDescriptorFilter* filter = nullptr) const;
bool retrieveDescriptors(NimBLEDescriptorFilter* pFilter = nullptr) const;

static int descriptorDiscCB(
uint16_t connHandle, const ble_gatt_error* error, uint16_t chrHandle, const ble_gatt_dsc* dsc, void* arg);
Expand Down