refactor(RemoteServ): Reduce nesting

* Adds parameter out to retrieveCharacteristics, default value works as
  the original method.
    * out: if not nullptr, will allow caller to obtain the characteristic
* Add check to retrieveCharacteristics, return if found the last handle
* General cleanup
This commit is contained in:
thekurtovic 2025-01-11 00:17:51 -05:00
parent 5ac7272f5d
commit 31b2d0f390
2 changed files with 66 additions and 96 deletions

View file

@ -76,50 +76,34 @@ NimBLERemoteCharacteristic* NimBLERemoteService::getCharacteristic(const char* u
*/ */
NimBLERemoteCharacteristic* NimBLERemoteService::getCharacteristic(const NimBLEUUID& uuid) const { NimBLERemoteCharacteristic* NimBLERemoteService::getCharacteristic(const NimBLEUUID& uuid) const {
NIMBLE_LOGD(LOG_TAG, ">> getCharacteristic: uuid: %s", uuid.toString().c_str()); NIMBLE_LOGD(LOG_TAG, ">> getCharacteristic: uuid: %s", uuid.toString().c_str());
NimBLERemoteCharacteristic* pChar = nullptr; NimBLERemoteCharacteristic* pChar = nullptr;
size_t prev_size = m_vChars.size(); NimBLEUUID uuidTmp;
for (const auto& it : m_vChars) { for (const auto& chr : m_vChars) {
if (it->getUUID() == uuid) { if (chr->getUUID() == uuid) {
pChar = it; pChar = chr;
goto Done; goto Done;
} }
} }
if (retrieveCharacteristics(&uuid)) { if (!retrieveCharacteristics(&uuid, pChar) || pChar) {
if (m_vChars.size() > prev_size) { goto Done;
pChar = m_vChars.back(); }
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();
// If the request was successful but 16/32 bit uuid not found retrieveCharacteristics(&uuidTmp, pChar);
// try again with the 128 bit uuid. goto Done;
if (uuid.bitSize() == BLE_UUID_TYPE_16 || uuid.bitSize() == BLE_UUID_TYPE_32) { }
NimBLEUUID uuid128(uuid); // Try again with 16 bit uuid if request succeeded with no uuid found.
uuid128.to128(); // If the uuid was 128 bit but not of the BLE base type this check will fail.
if (retrieveCharacteristics(&uuid128)) { uuidTmp = NimBLEUUID(uuid).to16();
if (m_vChars.size() > prev_size) { if (uuidTmp.bitSize() == BLE_UUID_TYPE_16) {
pChar = m_vChars.back(); retrieveCharacteristics(&uuidTmp, pChar);
}
}
} else {
// If the request was successful but the 128 bit uuid not found
// try again with the 16 bit uuid.
NimBLEUUID uuid16(uuid);
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();
}
}
}
}
} }
Done: Done:
NIMBLE_LOGD(LOG_TAG, "<< Characteristic %sfound", pChar ? "" : "not "); NIMBLE_LOGD(LOG_TAG, "<< getCharacteristic: %sfound", !pChar ? "not " : "");
return pChar; return pChar;
} // getCharacteristic } // getCharacteristic
@ -143,63 +127,51 @@ const std::vector<NimBLERemoteCharacteristic*>& NimBLERemoteService::getCharacte
* @brief Callback for Characteristic discovery. * @brief Callback for Characteristic discovery.
* @return success == 0 or error code. * @return success == 0 or error code.
*/ */
int NimBLERemoteService::characteristicDiscCB(uint16_t conn_handle, int NimBLERemoteService::chrDiscCB(uint16_t connHandle,
const ble_gatt_error* error, const ble_gatt_error* error,
const ble_gatt_chr* chr, const ble_gatt_chr* chr,
void* arg) { void* arg) {
NIMBLE_LOGD(LOG_TAG, const int rc = error->status;
"Characteristic Discovery >> status: %d handle: %d",
error->status,
(error->status == 0) ? chr->def_handle : -1);
auto pTaskData = (NimBLETaskData*)arg; auto pTaskData = (NimBLETaskData*)arg;
const auto pSvc = (NimBLERemoteService*)pTaskData->m_pInstance; const auto pSvc = (NimBLERemoteService*)pTaskData->m_pInstance;
NIMBLE_LOGD(LOG_TAG, "Characteristic Discovery >> status: %d handle: %d", rc, (rc == 0) ? chr->def_handle : -1);
if (error->status == BLE_HS_ENOTCONN) {
NIMBLE_LOGE(LOG_TAG, "<< Characteristic Discovery; Not connected");
NimBLEUtils::taskRelease(*pTaskData, error->status);
return error->status;
}
// Make sure the discovery is for this device // Make sure the discovery is for this device
if (pSvc->getClient()->getConnHandle() != conn_handle) { if (pSvc->getClient()->getConnHandle() != connHandle) {
return 0; return 0;
} }
if (error->status == 0) { if (rc == 0) {
pSvc->m_vChars.push_back(new NimBLERemoteCharacteristic(pSvc, chr)); pSvc->m_vChars.push_back(new NimBLERemoteCharacteristic(pSvc, chr));
return 0; return 0;
} }
NimBLEUtils::taskRelease(*pTaskData, error->status); NimBLEUtils::taskRelease(*pTaskData, rc);
NIMBLE_LOGD(LOG_TAG, "<< Characteristic Discovery"); NIMBLE_LOGD(LOG_TAG, "<< Characteristic Discovery%s", (rc == BLE_HS_ENOTCONN) ? "; Not connected" : "");
return error->status; return rc;
} }
/** /**
* @brief Retrieve all the characteristics for this service. * @brief Retrieve all the characteristics for this service.
* This function will not return until we have all the characteristics. * This function will not return until we have all the characteristics.
* @return True if successful. * @return True if successfully retrieved, success = BLE_HS_EDONE.
*/ */
bool NimBLERemoteService::retrieveCharacteristics(const NimBLEUUID* uuidFilter) const { bool NimBLERemoteService::retrieveCharacteristics(const NimBLEUUID* uuid, NimBLERemoteCharacteristic* out) const {
NIMBLE_LOGD(LOG_TAG, ">> retrieveCharacteristics()"); NIMBLE_LOGD(LOG_TAG, ">> retrieveCharacteristics()");
int rc = 0;
NimBLETaskData taskData(const_cast<NimBLERemoteService*>(this)); NimBLETaskData taskData(const_cast<NimBLERemoteService*>(this));
const uint16_t hdlConn = m_pClient->getConnHandle();
if (uuidFilter == nullptr) { const uint16_t hdlEnd = getEndHandle();
rc = ble_gattc_disc_all_chrs(m_pClient->getConnHandle(), const uint16_t hdlStart = getHandle();
getHandle(), // If this is the last handle then there are no more characteristics
getEndHandle(), if (hdlStart == hdlEnd) {
NimBLERemoteService::characteristicDiscCB, NIMBLE_LOGD(LOG_TAG, "<< retrieveCharacteristics(): found %d characteristics.", m_vChars.size());
&taskData); return true;
} else {
rc = ble_gattc_disc_chrs_by_uuid(m_pClient->getConnHandle(),
getHandle(),
getEndHandle(),
uuidFilter->getBase(),
NimBLERemoteService::characteristicDiscCB,
&taskData);
} }
int rc = (uuid == nullptr)
? ble_gattc_disc_all_chrs(hdlConn, hdlStart, hdlEnd, chrDiscCB, &taskData)
: ble_gattc_disc_chrs_by_uuid(hdlConn, hdlStart, hdlEnd, uuid->getBase(), chrDiscCB, &taskData);
if (rc != 0) { if (rc != 0) {
NIMBLE_LOGE(LOG_TAG, "ble_gattc_disc_chrs rc=%d %s", rc, NimBLEUtils::returnCodeToString(rc)); NIMBLE_LOGE(LOG_TAG, "ble_gattc_disc_chrs rc=%d %s", rc, NimBLEUtils::returnCodeToString(rc));
return false; return false;
@ -207,13 +179,16 @@ bool NimBLERemoteService::retrieveCharacteristics(const NimBLEUUID* uuidFilter)
NimBLEUtils::taskWait(taskData, BLE_NPL_TIME_FOREVER); NimBLEUtils::taskWait(taskData, BLE_NPL_TIME_FOREVER);
rc = taskData.m_flags; rc = taskData.m_flags;
if (rc == 0 || rc == BLE_HS_EDONE) { if (rc != BLE_HS_EDONE) {
NIMBLE_LOGD(LOG_TAG, "<< retrieveCharacteristics()"); NIMBLE_LOGE(LOG_TAG, "<< retrieveCharacteristics(): failed: rc=%d %s", rc, NimBLEUtils::returnCodeToString(rc));
return true; return false;
} }
NIMBLE_LOGE(LOG_TAG, "<< retrieveCharacteristics() rc=%d %s", rc, NimBLEUtils::returnCodeToString(rc)); if (out) {
return false; out = m_vChars.back();
}
NIMBLE_LOGD(LOG_TAG, "<< retrieveCharacteristics(): found %d characteristics.", m_vChars.size());
return true;
} // retrieveCharacteristics } // retrieveCharacteristics
/** /**
@ -231,11 +206,8 @@ NimBLEClient* NimBLERemoteService::getClient() const {
*/ */
NimBLEAttValue NimBLERemoteService::getValue(const NimBLEUUID& uuid) const { NimBLEAttValue NimBLERemoteService::getValue(const NimBLEUUID& uuid) const {
const auto pChar = getCharacteristic(uuid); const auto pChar = getCharacteristic(uuid);
if (pChar) { return pChar ? pChar->readValue()
return pChar->readValue(); : NimBLEAttValue{};
}
return NimBLEAttValue{};
} // readValue } // readValue
/** /**
@ -246,11 +218,8 @@ NimBLEAttValue NimBLERemoteService::getValue(const NimBLEUUID& uuid) const {
*/ */
bool NimBLERemoteService::setValue(const NimBLEUUID& uuid, const NimBLEAttValue& value) const { bool NimBLERemoteService::setValue(const NimBLEUUID& uuid, const NimBLEAttValue& value) const {
const auto pChar = getCharacteristic(uuid); const auto pChar = getCharacteristic(uuid);
if (pChar) { return pChar ? pChar->writeValue(value)
return pChar->writeValue(value); : false;
}
return false;
} // setValue } // setValue
/** /**
@ -260,8 +229,8 @@ bool NimBLERemoteService::setValue(const NimBLEUUID& uuid, const NimBLEAttValue&
* them. This method does just that. * them. This method does just that.
*/ */
void NimBLERemoteService::deleteCharacteristics() const { void NimBLERemoteService::deleteCharacteristics() const {
for (const auto& it : m_vChars) { for (const auto& chr : m_vChars) {
delete it; delete chr;
} }
std::vector<NimBLERemoteCharacteristic*>{}.swap(m_vChars); std::vector<NimBLERemoteCharacteristic*>{}.swap(m_vChars);
} // deleteCharacteristics } // deleteCharacteristics
@ -303,4 +272,4 @@ std::string NimBLERemoteService::toString() const {
return res; return res;
} // toString } // toString
#endif /* CONFIG_BT_ENABLED && CONFIG_BT_NIMBLE_ROLE_CENTRAL */ #endif /* CONFIG_BT_ENABLED && CONFIG_BT_NIMBLE_ROLE_CENTRAL */

View file

@ -53,11 +53,12 @@ class NimBLERemoteService : public NimBLEAttribute {
NimBLERemoteService(NimBLEClient* pClient, const struct ble_gatt_svc* service); NimBLERemoteService(NimBLEClient* pClient, const struct ble_gatt_svc* service);
~NimBLERemoteService(); ~NimBLERemoteService();
bool retrieveCharacteristics(const NimBLEUUID* uuidFilter = nullptr) const; bool retrieveCharacteristics(const NimBLEUUID* uuid = nullptr,
static int characteristicDiscCB(uint16_t conn_handle, NimBLERemoteCharacteristic* out = nullptr) const;
const struct ble_gatt_error* error, static int chrDiscCB(uint16_t connHandle,
const struct ble_gatt_chr* chr, const struct ble_gatt_error* error,
void* arg); const struct ble_gatt_chr* chr,
void* arg);
mutable std::vector<NimBLERemoteCharacteristic*> m_vChars{}; mutable std::vector<NimBLERemoteCharacteristic*> m_vChars{};
NimBLEClient* m_pClient{nullptr}; NimBLEClient* m_pClient{nullptr};
@ -65,4 +66,4 @@ class NimBLERemoteService : public NimBLEAttribute {
}; // NimBLERemoteService }; // NimBLERemoteService
#endif /* CONFIG_BT_ENABLED && CONFIG_BT_NIMBLE_ROLE_CENTRAL */ #endif /* CONFIG_BT_ENABLED && CONFIG_BT_NIMBLE_ROLE_CENTRAL */
#endif /* NIMBLE_CPP_REMOTE_SERVICE_H_*/ #endif /* NIMBLE_CPP_REMOTE_SERVICE_H_*/