mirror of
https://github.com/h2zero/esp-nimble-cpp.git
synced 2025-01-22 17:30:50 +01:00
refactor: Consolidate attribute get code into NimBLEUtils
This commit is contained in:
parent
8158a16fbf
commit
a04ee15815
4 changed files with 182 additions and 282 deletions
|
@ -101,8 +101,8 @@ NimBLEClient::~NimBLEClient() {
|
||||||
*/
|
*/
|
||||||
void NimBLEClient::deleteServices() {
|
void NimBLEClient::deleteServices() {
|
||||||
// Delete all the services.
|
// Delete all the services.
|
||||||
for (auto& it : m_svcVec) {
|
for (auto& svc : m_svcVec) {
|
||||||
delete it;
|
delete svc;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<NimBLERemoteService*>().swap(m_svcVec);
|
std::vector<NimBLERemoteService*>().swap(m_svcVec);
|
||||||
|
@ -243,8 +243,7 @@ bool NimBLEClient::connect(const NimBLEAddress& address, bool deleteAttributes,
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
NIMBLE_LOGE(LOG_TAG,
|
NIMBLE_LOGE(LOG_TAG, "Failed to connect to %s, rc=%d; %s",
|
||||||
"Failed to connect to %s, rc=%d; %s",
|
|
||||||
std::string(m_peerAddress).c_str(),
|
std::string(m_peerAddress).c_str(),
|
||||||
rc,
|
rc,
|
||||||
NimBLEUtils::returnCodeToString(rc));
|
NimBLEUtils::returnCodeToString(rc));
|
||||||
|
@ -631,48 +630,14 @@ NimBLERemoteService* NimBLEClient::getService(const char* uuid) {
|
||||||
*/
|
*/
|
||||||
NimBLERemoteService* NimBLEClient::getService(const NimBLEUUID& uuid) {
|
NimBLERemoteService* NimBLEClient::getService(const NimBLEUUID& uuid) {
|
||||||
NIMBLE_LOGD(LOG_TAG, ">> getService: uuid: %s", uuid.toString().c_str());
|
NIMBLE_LOGD(LOG_TAG, ">> getService: uuid: %s", uuid.toString().c_str());
|
||||||
|
NimBLERemoteService *pSvc = nullptr;
|
||||||
|
|
||||||
for (auto& it : m_svcVec) {
|
NimBLEUtils::getAttr(uuid, pSvc, m_svcVec, [this](const NimBLEUUID* u, void* arg) {
|
||||||
if (it->getUUID() == uuid) {
|
return retrieveServices(u, (NimBLERemoteService*)arg);
|
||||||
NIMBLE_LOGD(LOG_TAG, "<< getService: found the service with uuid: %s", uuid.toString().c_str());
|
});
|
||||||
return it;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t prevSize = m_svcVec.size();
|
NIMBLE_LOGD(LOG_TAG, "<< getService: %sfound", !pSvc ? "not " : "");
|
||||||
if (retrieveServices(&uuid)) {
|
return pSvc;
|
||||||
if (m_svcVec.size() > prevSize) {
|
|
||||||
return m_svcVec.back();
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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 (retrieveServices(&uuid128)) {
|
|
||||||
if (m_svcVec.size() > prevSize) {
|
|
||||||
return m_svcVec.back();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} 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 (retrieveServices(&uuid16)) {
|
|
||||||
if (m_svcVec.size() > prevSize) {
|
|
||||||
return m_svcVec.back();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
NIMBLE_LOGD(LOG_TAG, "<< getService: not found");
|
|
||||||
return nullptr;
|
|
||||||
} // getService
|
} // getService
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -725,7 +690,7 @@ bool NimBLEClient::discoverAttributes() {
|
||||||
* * Here we ask the server for its set of services and wait until we have received them all.
|
* * Here we ask the server for its set of services and wait until we have received them all.
|
||||||
* @return true on success otherwise false if an error occurred
|
* @return true on success otherwise false if an error occurred
|
||||||
*/
|
*/
|
||||||
bool NimBLEClient::retrieveServices(const NimBLEUUID* uuidFilter) {
|
bool NimBLEClient::retrieveServices(const NimBLEUUID* uuidFilter, NimBLERemoteService *out) {
|
||||||
if (!isConnected()) {
|
if (!isConnected()) {
|
||||||
NIMBLE_LOGE(LOG_TAG, "Disconnected, could not retrieve services -aborting");
|
NIMBLE_LOGE(LOG_TAG, "Disconnected, could not retrieve services -aborting");
|
||||||
return false;
|
return false;
|
||||||
|
@ -735,9 +700,9 @@ bool NimBLEClient::retrieveServices(const NimBLEUUID* uuidFilter) {
|
||||||
NimBLETaskData taskData(this);
|
NimBLETaskData taskData(this);
|
||||||
|
|
||||||
if (uuidFilter == nullptr) {
|
if (uuidFilter == nullptr) {
|
||||||
rc = ble_gattc_disc_all_svcs(m_connHandle, NimBLEClient::serviceDiscoveredCB, &taskData);
|
rc = ble_gattc_disc_all_svcs(m_connHandle, NimBLEClient::serviceDiscCB, &taskData);
|
||||||
} else {
|
} else {
|
||||||
rc = ble_gattc_disc_svc_by_uuid(m_connHandle, uuidFilter->getBase(), NimBLEClient::serviceDiscoveredCB, &taskData);
|
rc = ble_gattc_disc_svc_by_uuid(m_connHandle, uuidFilter->getBase(), NimBLEClient::serviceDiscCB, &taskData);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rc != 0) {
|
if (rc != 0) {
|
||||||
|
@ -748,13 +713,15 @@ bool NimBLEClient::retrieveServices(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) {
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_lastErr = rc;
|
m_lastErr = rc;
|
||||||
NIMBLE_LOGE(LOG_TAG, "Could not retrieve services, rc=%d %s", rc, NimBLEUtils::returnCodeToString(rc));
|
NIMBLE_LOGE(LOG_TAG, "Could not retrieve services, rc=%d %s", rc, NimBLEUtils::returnCodeToString(rc));
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
out = m_svcVec.back();
|
||||||
|
NIMBLE_LOGD(LOG_TAG, "<< retrieveServices(): found %d services.", m_svcVec.size());
|
||||||
|
return true;
|
||||||
} // getServices
|
} // getServices
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -762,39 +729,29 @@ bool NimBLEClient::retrieveServices(const NimBLEUUID* uuidFilter) {
|
||||||
* @details When a service is found or there is none left or there was an error
|
* @details When a service is found or there is none left or there was an error
|
||||||
* the API will call this and report findings.
|
* the API will call this and report findings.
|
||||||
*/
|
*/
|
||||||
int NimBLEClient::serviceDiscoveredCB(uint16_t connHandle,
|
int NimBLEClient::serviceDiscCB(uint16_t connHandle,
|
||||||
const struct ble_gatt_error* error,
|
const struct ble_gatt_error* error,
|
||||||
const struct ble_gatt_svc* service,
|
const struct ble_gatt_svc* service,
|
||||||
void* arg) {
|
void* arg) {
|
||||||
NIMBLE_LOGD(LOG_TAG,
|
const int rc = error->status;
|
||||||
"Service Discovered >> status: %d handle: %d",
|
auto pTaskData = (NimBLETaskData*)arg;
|
||||||
error->status,
|
auto pClient = (NimBLEClient*)pTaskData->m_pInstance;
|
||||||
(error->status == 0) ? service->start_handle : -1);
|
NIMBLE_LOGD(LOG_TAG, "Service Discovered >> status: %d handle: %d", rc, (rc == 0) ? service->start_handle : -1);
|
||||||
|
|
||||||
NimBLETaskData* pTaskData = (NimBLETaskData*)arg;
|
|
||||||
NimBLEClient* pClient = (NimBLEClient*)pTaskData->m_pInstance;
|
|
||||||
|
|
||||||
if (error->status == BLE_HS_ENOTCONN) {
|
|
||||||
NIMBLE_LOGE(LOG_TAG, "<< Service Discovered; Disconnected");
|
|
||||||
NimBLEUtils::taskRelease(*pTaskData, error->status);
|
|
||||||
return error->status;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Make sure the service discovery is for this device
|
// Make sure the service discovery is for this device
|
||||||
if (pClient->getConnHandle() != connHandle) {
|
if (pClient->getConnHandle() != connHandle) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (error->status == 0) {
|
if (rc == 0) { // Found a service - add it to the vector
|
||||||
// Found a service - add it to the vector
|
|
||||||
pClient->m_svcVec.push_back(new NimBLERemoteService(pClient, service));
|
pClient->m_svcVec.push_back(new NimBLERemoteService(pClient, service));
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
NimBLEUtils::taskRelease(*pTaskData, error->status);
|
NimBLEUtils::taskRelease(*pTaskData, error->status);
|
||||||
NIMBLE_LOGD(LOG_TAG, "<< Service Discovered");
|
NIMBLE_LOGD(LOG_TAG, "<< Service Discovered%s", (rc == BLE_HS_ENOTCONN) ? "; Disconnected" : "");
|
||||||
return error->status;
|
return error->status;
|
||||||
} // serviceDiscoveredCB
|
} // serviceDiscCB
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Get the value of a specific characteristic associated with a specific service.
|
* @brief Get the value of a specific characteristic associated with a specific service.
|
||||||
|
@ -803,8 +760,7 @@ int NimBLEClient::serviceDiscoveredCB(uint16_t connHandle,
|
||||||
* @returns characteristic value or an empty value if not found.
|
* @returns characteristic value or an empty value if not found.
|
||||||
*/
|
*/
|
||||||
NimBLEAttValue NimBLEClient::getValue(const NimBLEUUID& serviceUUID, const NimBLEUUID& characteristicUUID) {
|
NimBLEAttValue NimBLEClient::getValue(const NimBLEUUID& serviceUUID, const NimBLEUUID& characteristicUUID) {
|
||||||
NIMBLE_LOGD(LOG_TAG,
|
NIMBLE_LOGD(LOG_TAG, ">> getValue: serviceUUID: %s, characteristicUUID: %s",
|
||||||
">> getValue: serviceUUID: %s, characteristicUUID: %s",
|
|
||||||
serviceUUID.toString().c_str(),
|
serviceUUID.toString().c_str(),
|
||||||
characteristicUUID.toString().c_str());
|
characteristicUUID.toString().c_str());
|
||||||
|
|
||||||
|
@ -833,15 +789,14 @@ bool NimBLEClient::setValue(const NimBLEUUID& serviceUUID,
|
||||||
const NimBLEUUID& characteristicUUID,
|
const NimBLEUUID& characteristicUUID,
|
||||||
const NimBLEAttValue& value,
|
const NimBLEAttValue& value,
|
||||||
bool response) {
|
bool response) {
|
||||||
NIMBLE_LOGD(LOG_TAG,
|
NIMBLE_LOGD(LOG_TAG, ">> setValue: serviceUUID: %s, characteristicUUID: %s",
|
||||||
">> setValue: serviceUUID: %s, characteristicUUID: %s",
|
|
||||||
serviceUUID.toString().c_str(),
|
serviceUUID.toString().c_str(),
|
||||||
characteristicUUID.toString().c_str());
|
characteristicUUID.toString().c_str());
|
||||||
|
|
||||||
bool ret = false;
|
bool ret = false;
|
||||||
auto pService = getService(serviceUUID);
|
auto pService = getService(serviceUUID);
|
||||||
if (pService != nullptr) {
|
if (pService != nullptr) {
|
||||||
NimBLERemoteCharacteristic* pChar = pService->getCharacteristic(characteristicUUID);
|
auto pChar = pService->getCharacteristic(characteristicUUID);
|
||||||
if (pChar != nullptr) {
|
if (pChar != nullptr) {
|
||||||
ret = pChar->writeValue(value, response);
|
ret = pChar->writeValue(value, response);
|
||||||
}
|
}
|
||||||
|
@ -858,14 +813,16 @@ bool NimBLEClient::setValue(const NimBLEUUID& serviceUUID,
|
||||||
*/
|
*/
|
||||||
NimBLERemoteCharacteristic* NimBLEClient::getCharacteristic(uint16_t handle) {
|
NimBLERemoteCharacteristic* NimBLEClient::getCharacteristic(uint16_t handle) {
|
||||||
for (const auto& svc : m_svcVec) {
|
for (const auto& svc : m_svcVec) {
|
||||||
if (svc->getStartHandle() <= handle && handle <= svc->getEndHandle()) {
|
if (svc->getStartHandle() > handle && handle > svc->getEndHandle()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
for (const auto& chr : svc->m_vChars) {
|
for (const auto& chr : svc->m_vChars) {
|
||||||
if (chr->getHandle() == handle) {
|
if (chr->getHandle() == handle) {
|
||||||
return chr;
|
return chr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
return nullptr;
|
return nullptr;
|
||||||
} // getCharacteristic
|
} // getCharacteristic
|
||||||
|
@ -882,28 +839,28 @@ uint16_t NimBLEClient::getMTU() const {
|
||||||
* @brief Callback for the MTU exchange API function.
|
* @brief Callback for the MTU exchange API function.
|
||||||
* @details When the MTU exchange is complete the API will call this and report the new MTU.
|
* @details When the MTU exchange is complete the API will call this and report the new MTU.
|
||||||
*/
|
*/
|
||||||
int NimBLEClient::exchangeMTUCb(uint16_t conn_handle, const ble_gatt_error* error, uint16_t mtu, void* arg) {
|
int NimBLEClient::exchangeMTUCB(uint16_t connHandle, const ble_gatt_error* error, uint16_t mtu, void* arg) {
|
||||||
NIMBLE_LOGD(LOG_TAG, "exchangeMTUCb: status=%d, mtu=%d", error->status, mtu);
|
NIMBLE_LOGD(LOG_TAG, "exchangeMTUCB: status=%d, mtu=%d", error->status, mtu);
|
||||||
|
|
||||||
NimBLEClient* pClient = (NimBLEClient*)arg;
|
NimBLEClient* pClient = (NimBLEClient*)arg;
|
||||||
if (pClient->getConnHandle() != conn_handle) {
|
if (pClient->getConnHandle() != connHandle) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (error->status != 0) {
|
if (error->status != 0) {
|
||||||
NIMBLE_LOGE(LOG_TAG, "exchangeMTUCb() rc=%d %s", error->status, NimBLEUtils::returnCodeToString(error->status));
|
NIMBLE_LOGE(LOG_TAG, "exchangeMTUCB() rc=%d %s", error->status, NimBLEUtils::returnCodeToString(error->status));
|
||||||
pClient->m_lastErr = error->status;
|
pClient->m_lastErr = error->status;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
} // exchangeMTUCb
|
} // exchangeMTUCB
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Begin the MTU exchange process with the server.
|
* @brief Begin the MTU exchange process with the server.
|
||||||
* @returns true if the request was sent successfully.
|
* @returns true if the request was sent successfully.
|
||||||
*/
|
*/
|
||||||
bool NimBLEClient::exchangeMTU() {
|
bool NimBLEClient::exchangeMTU() {
|
||||||
int rc = ble_gattc_exchange_mtu(m_connHandle, NimBLEClient::exchangeMTUCb, this);
|
int rc = ble_gattc_exchange_mtu(m_connHandle, NimBLEClient::exchangeMTUCB, this);
|
||||||
if (rc != 0) {
|
if (rc != 0) {
|
||||||
NIMBLE_LOGE(LOG_TAG, "MTU exchange error; rc=%d %s", rc, NimBLEUtils::returnCodeToString(rc));
|
NIMBLE_LOGE(LOG_TAG, "MTU exchange error; rc=%d %s", rc, NimBLEUtils::returnCodeToString(rc));
|
||||||
m_lastErr = rc;
|
m_lastErr = rc;
|
||||||
|
@ -989,7 +946,10 @@ int NimBLEClient::handleGapEvent(struct ble_gap_event* event, void* arg) {
|
||||||
pClient->m_pClientCallbacks->onConnect(pClient);
|
pClient->m_pClientCallbacks->onConnect(pClient);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pClient->m_config.exchangeMTU) {
|
if (!pClient->m_config.exchangeMTU) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
if (!pClient->exchangeMTU()) {
|
if (!pClient->exchangeMTU()) {
|
||||||
rc = pClient->m_lastErr; // sets the error in the task data
|
rc = pClient->m_lastErr; // sets the error in the task data
|
||||||
break;
|
break;
|
||||||
|
@ -997,17 +957,14 @@ int NimBLEClient::handleGapEvent(struct ble_gap_event* event, void* arg) {
|
||||||
|
|
||||||
return 0; // return as we may have a task waiting for the MTU before releasing it.
|
return 0; // return as we may have a task waiting for the MTU before releasing it.
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
pClient->m_connHandle = BLE_HS_CONN_HANDLE_NONE;
|
|
||||||
|
|
||||||
|
pClient->m_connHandle = BLE_HS_CONN_HANDLE_NONE;
|
||||||
if (pClient->m_config.asyncConnect) {
|
if (pClient->m_config.asyncConnect) {
|
||||||
pClient->m_pClientCallbacks->onConnectFail(pClient, rc);
|
pClient->m_pClientCallbacks->onConnectFail(pClient, rc);
|
||||||
if (pClient->m_config.deleteOnConnectFail) {
|
if (pClient->m_config.deleteOnConnectFail) {
|
||||||
NimBLEDevice::deleteClient(pClient);
|
NimBLEDevice::deleteClient(pClient);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
} // BLE_GAP_EVENT_CONNECT
|
} // BLE_GAP_EVENT_CONNECT
|
||||||
|
|
||||||
|
@ -1035,15 +992,16 @@ int NimBLEClient::handleGapEvent(struct ble_gap_event* event, void* arg) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
NIMBLE_LOGD(LOG_TAG,
|
NIMBLE_LOGD(LOG_TAG, "checking service %s for handle: %d",
|
||||||
"checking service %s for handle: %d",
|
|
||||||
svc->getUUID().toString().c_str(),
|
svc->getUUID().toString().c_str(),
|
||||||
event->notify_rx.attr_handle);
|
event->notify_rx.attr_handle);
|
||||||
|
|
||||||
for (const auto& chr : svc->m_vChars) {
|
for (const auto& chr : svc->m_vChars) {
|
||||||
if (chr->getHandle() == event->notify_rx.attr_handle) {
|
if (chr->getHandle() != event->notify_rx.attr_handle) {
|
||||||
NIMBLE_LOGD(LOG_TAG, "Got Notification for characteristic %s", chr->toString().c_str());
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
NIMBLE_LOGD(LOG_TAG, "Got Notification for characteristic %s", chr->toString().c_str());
|
||||||
uint32_t data_len = OS_MBUF_PKTLEN(event->notify_rx.om);
|
uint32_t data_len = OS_MBUF_PKTLEN(event->notify_rx.om);
|
||||||
chr->m_value.setValue(event->notify_rx.om->om_data, data_len);
|
chr->m_value.setValue(event->notify_rx.om->om_data, data_len);
|
||||||
|
|
||||||
|
@ -1053,7 +1011,6 @@ int NimBLEClient::handleGapEvent(struct ble_gap_event* event, void* arg) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
} // BLE_GAP_EVENT_NOTIFY_RX
|
} // BLE_GAP_EVENT_NOTIFY_RX
|
||||||
|
@ -1064,8 +1021,7 @@ int NimBLEClient::handleGapEvent(struct ble_gap_event* event, void* arg) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
NIMBLE_LOGD(LOG_TAG, "Peer requesting to update connection parameters");
|
NIMBLE_LOGD(LOG_TAG, "Peer requesting to update connection parameters");
|
||||||
NIMBLE_LOGD(LOG_TAG,
|
NIMBLE_LOGD(LOG_TAG, "MinInterval: %d, MaxInterval: %d, Latency: %d, Timeout: %d",
|
||||||
"MinInterval: %d, MaxInterval: %d, Latency: %d, Timeout: %d",
|
|
||||||
event->conn_update_req.peer_params->itvl_min,
|
event->conn_update_req.peer_params->itvl_min,
|
||||||
event->conn_update_req.peer_params->itvl_max,
|
event->conn_update_req.peer_params->itvl_max,
|
||||||
event->conn_update_req.peer_params->latency,
|
event->conn_update_req.peer_params->latency,
|
||||||
|
|
|
@ -27,17 +27,17 @@
|
||||||
|
|
||||||
# include <climits>
|
# include <climits>
|
||||||
|
|
||||||
typedef struct {
|
struct desc_filter_t {
|
||||||
const NimBLEUUID* uuid;
|
const NimBLEUUID* uuid;
|
||||||
void* task_data;
|
void* taskData;
|
||||||
} desc_filter_t;
|
};
|
||||||
|
|
||||||
static const char* LOG_TAG = "NimBLERemoteCharacteristic";
|
static const char* LOG_TAG = "NimBLERemoteCharacteristic";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Constructor.
|
* @brief Constructor.
|
||||||
* @param [in] svc A pointer to the service this characteristic belongs to.
|
* @param [in] svc A pointer to the service this characteristic belongs to.
|
||||||
* @param [in] ble_gatt_chr struct defined as:
|
* @param [in] chr struct defined as:
|
||||||
* struct ble_gatt_chr {
|
* struct ble_gatt_chr {
|
||||||
* uint16_t def_handle;
|
* uint16_t def_handle;
|
||||||
* uint16_t val_handle;
|
* uint16_t val_handle;
|
||||||
|
@ -62,57 +62,56 @@ NimBLERemoteCharacteristic::~NimBLERemoteCharacteristic() {
|
||||||
/**
|
/**
|
||||||
* @brief Callback used by the API when a descriptor is discovered or search complete.
|
* @brief Callback used by the API when a descriptor is discovered or search complete.
|
||||||
*/
|
*/
|
||||||
int NimBLERemoteCharacteristic::descriptorDiscCB(
|
int NimBLERemoteCharacteristic::descriptorDiscCB(uint16_t connHandle,
|
||||||
uint16_t conn_handle, const ble_gatt_error* error, uint16_t chr_val_handle, const ble_gatt_dsc* dsc, void* arg) {
|
const ble_gatt_error* error,
|
||||||
|
uint16_t chrHandle,
|
||||||
|
const ble_gatt_dsc* dsc,
|
||||||
|
void* arg) {
|
||||||
int rc = error->status;
|
int rc = error->status;
|
||||||
|
auto filter = (desc_filter_t*)arg;
|
||||||
|
auto pTaskData = (NimBLETaskData*)filter->taskData;
|
||||||
|
const auto pChr = (NimBLERemoteCharacteristic*)pTaskData->m_pInstance;
|
||||||
|
const auto uuid = filter->uuid; // UUID to filter for
|
||||||
NIMBLE_LOGD(LOG_TAG, "Descriptor Discovery >> status: %d handle: %d", rc, (rc == 0) ? dsc->handle : -1);
|
NIMBLE_LOGD(LOG_TAG, "Descriptor Discovery >> status: %d handle: %d", rc, (rc == 0) ? dsc->handle : -1);
|
||||||
|
|
||||||
auto filter = (desc_filter_t*)arg;
|
// Results for chrHandle added until rc != 0
|
||||||
auto pTaskData = (NimBLETaskData*)filter->task_data;
|
// Must find specified UUID if filter is used
|
||||||
const auto pChr = (NimBLERemoteCharacteristic*)pTaskData->m_pInstance;
|
if (rc == 0 && pChr->getHandle() == chrHandle
|
||||||
const NimBLEUUID* uuidFilter = filter->uuid;
|
&& (!uuid || 0 == ble_uuid_cmp(uuid->getBase(), &dsc->uuid.u))) {
|
||||||
|
// Return BLE_HS_EDONE if the descriptor was found, stop the search
|
||||||
if (pChr->getHandle() != chr_val_handle) {
|
|
||||||
return 0; // Descriptor not for this characteristic
|
|
||||||
}
|
|
||||||
|
|
||||||
if (rc == 0) {
|
|
||||||
if (uuidFilter != nullptr) {
|
|
||||||
if (ble_uuid_cmp(uuidFilter->getBase(), &dsc->uuid.u) == 0) {
|
|
||||||
rc = BLE_HS_EDONE; // Found the descriptor, stop the search
|
|
||||||
} else {
|
|
||||||
return 0; // Not the descriptor we are looking for
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pChr->m_vDescriptors.push_back(new NimBLERemoteDescriptor(pChr, dsc));
|
pChr->m_vDescriptors.push_back(new NimBLERemoteDescriptor(pChr, dsc));
|
||||||
return 0;
|
rc = !!uuid * BLE_HS_EDONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (rc != 0) {
|
||||||
NimBLEUtils::taskRelease(*pTaskData, rc);
|
NimBLEUtils::taskRelease(*pTaskData, rc);
|
||||||
NIMBLE_LOGD(LOG_TAG, "<< Descriptor Discovery");
|
NIMBLE_LOGD(LOG_TAG, "<< Descriptor Discovery");
|
||||||
|
}
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Populate the descriptors (if any) for this characteristic.
|
* @brief Populate the descriptors (if any) for this characteristic.
|
||||||
* @param [in] the end handle of the characteristic, or the service, whichever comes first.
|
* @param [in] filter Structure containing pointers to descriptor, UUID, and task data.
|
||||||
|
* @return True if successfully retrieved, success = BLE_HS_EDONE.
|
||||||
*/
|
*/
|
||||||
bool NimBLERemoteCharacteristic::retrieveDescriptors(const NimBLEUUID* uuidFilter) const {
|
bool NimBLERemoteCharacteristic::retrieveDescriptors(const NimBLEUUID* uuidFilter, NimBLERemoteDescriptor* out) const {
|
||||||
NIMBLE_LOGD(LOG_TAG, ">> retrieveDescriptors() for characteristic: %s", getUUID().toString().c_str());
|
NIMBLE_LOGD(LOG_TAG, ">> retrieveDescriptors() for characteristic: %s", getUUID().toString().c_str());
|
||||||
|
|
||||||
|
NimBLETaskData taskData(const_cast<NimBLERemoteCharacteristic*>(this));
|
||||||
|
desc_filter_t filter = {uuidFilter, &taskData};
|
||||||
|
const uint16_t handle = getHandle();
|
||||||
|
const uint16_t svcHandle = getRemoteService()->getEndHandle();
|
||||||
|
|
||||||
// If this is the last handle then there are no descriptors
|
// If this is the last handle then there are no descriptors
|
||||||
if (getHandle() == getRemoteService()->getEndHandle()) {
|
if (handle == svcHandle) {
|
||||||
NIMBLE_LOGD(LOG_TAG, "<< retrieveDescriptors(): found 0 descriptors.");
|
NIMBLE_LOGD(LOG_TAG, "<< retrieveDescriptors(): found 0 descriptors.");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
NimBLETaskData taskData(const_cast<NimBLERemoteCharacteristic*>(this));
|
|
||||||
desc_filter_t filter = {uuidFilter, &taskData};
|
|
||||||
|
|
||||||
int rc = ble_gattc_disc_all_dscs(getClient()->getConnHandle(),
|
int rc = ble_gattc_disc_all_dscs(getClient()->getConnHandle(),
|
||||||
getHandle(),
|
handle,
|
||||||
getRemoteService()->getEndHandle(),
|
svcHandle,
|
||||||
NimBLERemoteCharacteristic::descriptorDiscCB,
|
NimBLERemoteCharacteristic::descriptorDiscCB,
|
||||||
&filter);
|
&filter);
|
||||||
if (rc != 0) {
|
if (rc != 0) {
|
||||||
|
@ -122,13 +121,14 @@ bool NimBLERemoteCharacteristic::retrieveDescriptors(const NimBLEUUID* uuidFilte
|
||||||
|
|
||||||
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, "<< retrieveDescriptors(): found %d descriptors.", m_vDescriptors.size());
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
NIMBLE_LOGE(LOG_TAG, "<< retrieveDescriptors(): failed: rc=%d %s", rc, NimBLEUtils::returnCodeToString(rc));
|
NIMBLE_LOGE(LOG_TAG, "<< retrieveDescriptors(): failed: rc=%d %s", rc, NimBLEUtils::returnCodeToString(rc));
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
out = m_vDescriptors.back();
|
||||||
|
NIMBLE_LOGD(LOG_TAG, "<< retrieveDescriptors(): found %d descriptors.", m_vDescriptors.size());
|
||||||
|
return true;
|
||||||
} // retrieveDescriptors
|
} // retrieveDescriptors
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -139,49 +139,12 @@ bool NimBLERemoteCharacteristic::retrieveDescriptors(const NimBLEUUID* uuidFilte
|
||||||
NimBLERemoteDescriptor* NimBLERemoteCharacteristic::getDescriptor(const NimBLEUUID& uuid) const {
|
NimBLERemoteDescriptor* NimBLERemoteCharacteristic::getDescriptor(const NimBLEUUID& uuid) const {
|
||||||
NIMBLE_LOGD(LOG_TAG, ">> getDescriptor: uuid: %s", uuid.toString().c_str());
|
NIMBLE_LOGD(LOG_TAG, ">> getDescriptor: uuid: %s", uuid.toString().c_str());
|
||||||
NimBLERemoteDescriptor* pDsc = nullptr;
|
NimBLERemoteDescriptor* pDsc = nullptr;
|
||||||
size_t prev_size = m_vDescriptors.size();
|
|
||||||
|
|
||||||
for (const auto& it : m_vDescriptors) {
|
NimBLEUtils::getAttr(uuid, pDsc, m_vDescriptors, [this](const NimBLEUUID* u, void* arg) {
|
||||||
if (it->getUUID() == uuid) {
|
return retrieveDescriptors(u, (NimBLERemoteDescriptor*)arg);
|
||||||
pDsc = it;
|
});
|
||||||
goto Done;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (retrieveDescriptors(&uuid)) {
|
NIMBLE_LOGD(LOG_TAG, "<< getDescriptor: %sfound", !pDsc ? "not " : "");
|
||||||
if (m_vDescriptors.size() > prev_size) {
|
|
||||||
pDsc = m_vDescriptors.back();
|
|
||||||
goto Done;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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 (retrieveDescriptors(&uuid128)) {
|
|
||||||
if (m_vDescriptors.size() > prev_size) {
|
|
||||||
pDsc = m_vDescriptors.back();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} 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 (retrieveDescriptors(&uuid16)) {
|
|
||||||
if (m_vDescriptors.size() > prev_size) {
|
|
||||||
pDsc = m_vDescriptors.back();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Done:
|
|
||||||
NIMBLE_LOGD(LOG_TAG, "<< getDescriptor: %sfound", pDsc ? "" : "not ");
|
|
||||||
return pDsc;
|
return pDsc;
|
||||||
} // getDescriptor
|
} // getDescriptor
|
||||||
|
|
||||||
|
@ -311,7 +274,7 @@ size_t NimBLERemoteCharacteristic::deleteDescriptor(const NimBLEUUID& uuid) cons
|
||||||
* @return True if supported.
|
* @return True if supported.
|
||||||
*/
|
*/
|
||||||
bool NimBLERemoteCharacteristic::canBroadcast() const {
|
bool NimBLERemoteCharacteristic::canBroadcast() const {
|
||||||
return (m_properties & BLE_GATT_CHR_PROP_BROADCAST) != 0;
|
return (m_properties & BLE_GATT_CHR_PROP_BROADCAST);
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -77,49 +77,12 @@ 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();
|
|
||||||
|
|
||||||
for (const auto& it : m_vChars) {
|
NimBLEUtils::getAttr(uuid, pChar, m_vChars, [this](const NimBLEUUID* u, void* arg) {
|
||||||
if (it->getUUID() == uuid) {
|
return retrieveCharacteristics(u, (NimBLERemoteCharacteristic*)arg);
|
||||||
pChar = it;
|
});
|
||||||
goto Done;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (retrieveCharacteristics(&uuid)) {
|
NIMBLE_LOGD(LOG_TAG, "<< getCharacteristic: %sfound", !pChar ? "not " : "");
|
||||||
if (m_vChars.size() > prev_size) {
|
|
||||||
pChar = m_vChars.back();
|
|
||||||
goto Done;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} 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:
|
|
||||||
NIMBLE_LOGD(LOG_TAG, "<< Characteristic %sfound", pChar ? "" : "not ");
|
|
||||||
return pChar;
|
return pChar;
|
||||||
} // getCharacteristic
|
} // getCharacteristic
|
||||||
|
|
||||||
|
@ -143,47 +106,39 @@ 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::characteristicDiscCB(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* uuidFilter, 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));
|
||||||
|
int rc = 0;
|
||||||
|
|
||||||
if (uuidFilter == nullptr) {
|
if (uuidFilter == nullptr) {
|
||||||
rc = ble_gattc_disc_all_chrs(m_pClient->getConnHandle(),
|
rc = ble_gattc_disc_all_chrs(m_pClient->getConnHandle(),
|
||||||
|
@ -207,13 +162,14 @@ 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));
|
out = m_vChars.back();
|
||||||
return false;
|
NIMBLE_LOGD(LOG_TAG, "<< retrieveCharacteristics(): found %d characteristics.", m_vChars.size());
|
||||||
|
return true;
|
||||||
} // retrieveCharacteristics
|
} // retrieveCharacteristics
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -231,11 +187,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 +199,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 +210,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
|
||||||
|
|
|
@ -20,6 +20,8 @@
|
||||||
|
|
||||||
#include "nimconfig.h"
|
#include "nimconfig.h"
|
||||||
#if defined(CONFIG_BT_ENABLED)
|
#if defined(CONFIG_BT_ENABLED)
|
||||||
|
# include "NimBLEUUID.h"
|
||||||
|
# include "functional"
|
||||||
# include <string>
|
# include <string>
|
||||||
|
|
||||||
class NimBLEAddress;
|
class NimBLEAddress;
|
||||||
|
@ -53,6 +55,35 @@ class NimBLEUtils {
|
||||||
static NimBLEAddress generateAddr(bool nrpa);
|
static NimBLEAddress generateAddr(bool nrpa);
|
||||||
static bool taskWait(const NimBLETaskData& taskData, uint32_t timeout);
|
static bool taskWait(const NimBLETaskData& taskData, uint32_t timeout);
|
||||||
static void taskRelease(const NimBLETaskData& taskData, int rc = 0);
|
static void taskRelease(const NimBLETaskData& taskData, int rc = 0);
|
||||||
|
|
||||||
|
template <typename T, typename S>
|
||||||
|
static void getAttr(const NimBLEUUID& uuid, T* attr, const std::vector<S*> vec, const std::function<bool(const NimBLEUUID*, void*)>& getter) {
|
||||||
|
// Check if already exists.
|
||||||
|
for (const auto& v : vec) {
|
||||||
|
if (v->getUUID() == uuid) {
|
||||||
|
attr = v;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Exit if request failed or uuid was found.
|
||||||
|
if (!getter(&uuid, attr) || attr) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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) {
|
||||||
|
NimBLEUUID uuid128 = NimBLEUUID(uuid).to128();
|
||||||
|
getter(&uuid128, attr);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// 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.
|
||||||
|
NimBLEUUID uuid16 = NimBLEUUID(uuid).to16();
|
||||||
|
if (uuid16.bitSize() == BLE_UUID_TYPE_16) {
|
||||||
|
getter(&uuid16, attr);
|
||||||
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // CONFIG_BT_ENABLED
|
#endif // CONFIG_BT_ENABLED
|
||||||
|
|
Loading…
Add table
Reference in a new issue