Skip to content

Commit ef1521e

Browse files
committed
Merge branch 'thekurtovic-consolidate'
2 parents 8158a16 + ca0565b commit ef1521e

9 files changed

+292
-320
lines changed

CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ idf_component_register(
5757
"src/NimBLEHIDDevice.cpp"
5858
"src/NimBLERemoteCharacteristic.cpp"
5959
"src/NimBLERemoteDescriptor.cpp"
60+
"src/NimBLERemoteGattUtils.cpp"
6061
"src/NimBLERemoteService.cpp"
6162
"src/NimBLERemoteValueAttribute.cpp"
6263
"src/NimBLEScan.cpp"

src/NimBLEClient.cpp

Lines changed: 76 additions & 121 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
# include "NimBLEClient.h"
2222
# include "NimBLERemoteService.h"
2323
# include "NimBLERemoteCharacteristic.h"
24+
# include "NimBLERemoteGattUtils.h"
2425
# include "NimBLEDevice.h"
2526
# include "NimBLELog.h"
2627

@@ -101,8 +102,8 @@ NimBLEClient::~NimBLEClient() {
101102
*/
102103
void NimBLEClient::deleteServices() {
103104
// Delete all the services.
104-
for (auto& it : m_svcVec) {
105-
delete it;
105+
for (auto& svc : m_svcVec) {
106+
delete svc;
106107
}
107108

108109
std::vector<NimBLERemoteService*>().swap(m_svcVec);
@@ -243,8 +244,7 @@ bool NimBLEClient::connect(const NimBLEAddress& address, bool deleteAttributes,
243244
break;
244245

245246
default:
246-
NIMBLE_LOGE(LOG_TAG,
247-
"Failed to connect to %s, rc=%d; %s",
247+
NIMBLE_LOGE(LOG_TAG, "Failed to connect to %s, rc=%d; %s",
248248
std::string(m_peerAddress).c_str(),
249249
rc,
250250
NimBLEUtils::returnCodeToString(rc));
@@ -631,48 +631,15 @@ NimBLERemoteService* NimBLEClient::getService(const char* uuid) {
631631
*/
632632
NimBLERemoteService* NimBLEClient::getService(const NimBLEUUID& uuid) {
633633
NIMBLE_LOGD(LOG_TAG, ">> getService: uuid: %s", uuid.toString().c_str());
634+
NimBLERemoteService *pSvc = nullptr;
634635

635-
for (auto& it : m_svcVec) {
636-
if (it->getUUID() == uuid) {
637-
NIMBLE_LOGD(LOG_TAG, "<< getService: found the service with uuid: %s", uuid.toString().c_str());
638-
return it;
639-
}
640-
}
641-
642-
size_t prevSize = m_svcVec.size();
643-
if (retrieveServices(&uuid)) {
644-
if (m_svcVec.size() > prevSize) {
645-
return m_svcVec.back();
646-
}
647-
648-
// If the request was successful but 16/32 bit uuid not found
649-
// try again with the 128 bit uuid.
650-
if (uuid.bitSize() == BLE_UUID_TYPE_16 || uuid.bitSize() == BLE_UUID_TYPE_32) {
651-
NimBLEUUID uuid128(uuid);
652-
uuid128.to128();
653-
if (retrieveServices(&uuid128)) {
654-
if (m_svcVec.size() > prevSize) {
655-
return m_svcVec.back();
656-
}
657-
}
658-
} else {
659-
// If the request was successful but the 128 bit uuid not found
660-
// try again with the 16 bit uuid.
661-
NimBLEUUID uuid16(uuid);
662-
uuid16.to16();
663-
// if the uuid was 128 bit but not of the BLE base type this check will fail
664-
if (uuid16.bitSize() == BLE_UUID_TYPE_16) {
665-
if (retrieveServices(&uuid16)) {
666-
if (m_svcVec.size() > prevSize) {
667-
return m_svcVec.back();
668-
}
669-
}
670-
}
671-
}
672-
}
636+
NimBLERemoteGattUtils::getAttr<NimBLERemoteService>(uuid, &pSvc, m_svcVec,
637+
[this](const NimBLEUUID* u, NimBLERemoteService** svc) {
638+
return retrieveServices(u, svc);
639+
});
673640

674-
NIMBLE_LOGD(LOG_TAG, "<< getService: not found");
675-
return nullptr;
641+
NIMBLE_LOGD(LOG_TAG, "<< getService: %sfound", !pSvc ? "not " : "");
642+
return pSvc;
676643
} // getService
677644

678645
/**
@@ -725,20 +692,17 @@ bool NimBLEClient::discoverAttributes() {
725692
* * Here we ask the server for its set of services and wait until we have received them all.
726693
* @return true on success otherwise false if an error occurred
727694
*/
728-
bool NimBLEClient::retrieveServices(const NimBLEUUID* uuidFilter) {
695+
bool NimBLEClient::retrieveServices(const NimBLEUUID* uuid, NimBLERemoteService **out) {
696+
NIMBLE_LOGD(LOG_TAG, ">> retrieveServices()");
697+
NimBLETaskData taskData(this);
729698
if (!isConnected()) {
730699
NIMBLE_LOGE(LOG_TAG, "Disconnected, could not retrieve services -aborting");
731700
return false;
732701
}
733702

734-
int rc = 0;
735-
NimBLETaskData taskData(this);
736-
737-
if (uuidFilter == nullptr) {
738-
rc = ble_gattc_disc_all_svcs(m_connHandle, NimBLEClient::serviceDiscoveredCB, &taskData);
739-
} else {
740-
rc = ble_gattc_disc_svc_by_uuid(m_connHandle, uuidFilter->getBase(), NimBLEClient::serviceDiscoveredCB, &taskData);
741-
}
703+
int rc = (uuid == nullptr)
704+
? ble_gattc_disc_all_svcs(m_connHandle, svcDiscCB, &taskData)
705+
: ble_gattc_disc_svc_by_uuid(m_connHandle, uuid->getBase(), svcDiscCB, &taskData);
742706

743707
if (rc != 0) {
744708
NIMBLE_LOGE(LOG_TAG, "ble_gattc_disc_all_svcs: rc=%d %s", rc, NimBLEUtils::returnCodeToString(rc));
@@ -748,53 +712,45 @@ bool NimBLEClient::retrieveServices(const NimBLEUUID* uuidFilter) {
748712

749713
NimBLEUtils::taskWait(taskData, BLE_NPL_TIME_FOREVER);
750714
rc = taskData.m_flags;
751-
if (rc == 0 || rc == BLE_HS_EDONE) {
752-
return true;
715+
if (rc != BLE_HS_EDONE) {
716+
m_lastErr = rc;
717+
NIMBLE_LOGE(LOG_TAG, "Could not retrieve services, rc=%d %s", rc, NimBLEUtils::returnCodeToString(rc));
718+
return false;
753719
}
754720

755-
m_lastErr = rc;
756-
NIMBLE_LOGE(LOG_TAG, "Could not retrieve services, rc=%d %s", rc, NimBLEUtils::returnCodeToString(rc));
757-
return false;
721+
*out = m_svcVec.back();
722+
NIMBLE_LOGD(LOG_TAG, "<< retrieveServices(): found %d services.", m_svcVec.size());
723+
return true;
758724
} // getServices
759725

760726
/**
761727
* @brief Callback for the service discovery API function.
762728
* @details When a service is found or there is none left or there was an error
763729
* the API will call this and report findings.
764730
*/
765-
int NimBLEClient::serviceDiscoveredCB(uint16_t connHandle,
766-
const struct ble_gatt_error* error,
767-
const struct ble_gatt_svc* service,
768-
void* arg) {
769-
NIMBLE_LOGD(LOG_TAG,
770-
"Service Discovered >> status: %d handle: %d",
771-
error->status,
772-
(error->status == 0) ? service->start_handle : -1);
773-
774-
NimBLETaskData* pTaskData = (NimBLETaskData*)arg;
775-
NimBLEClient* pClient = (NimBLEClient*)pTaskData->m_pInstance;
776-
777-
if (error->status == BLE_HS_ENOTCONN) {
778-
NIMBLE_LOGE(LOG_TAG, "<< Service Discovered; Disconnected");
779-
NimBLEUtils::taskRelease(*pTaskData, error->status);
780-
return error->status;
781-
}
731+
int NimBLEClient::svcDiscCB(uint16_t connHandle,
732+
const struct ble_gatt_error* error,
733+
const struct ble_gatt_svc* service,
734+
void* arg) {
735+
const int rc = error->status;
736+
auto pTaskData = (NimBLETaskData*)arg;
737+
auto pClient = (NimBLEClient*)pTaskData->m_pInstance;
738+
NIMBLE_LOGD(LOG_TAG, "Service Discovered >> status: %d handle: %d", rc, (rc == 0) ? service->start_handle : -1);
782739

783740
// Make sure the service discovery is for this device
784741
if (pClient->getConnHandle() != connHandle) {
785742
return 0;
786743
}
787744

788-
if (error->status == 0) {
789-
// Found a service - add it to the vector
745+
if (rc == 0) { // Found a service - add it to the vector
790746
pClient->m_svcVec.push_back(new NimBLERemoteService(pClient, service));
791747
return 0;
792748
}
793749

794750
NimBLEUtils::taskRelease(*pTaskData, error->status);
795-
NIMBLE_LOGD(LOG_TAG, "<< Service Discovered");
751+
NIMBLE_LOGD(LOG_TAG, "<< Service Discovered%s", (rc == BLE_HS_ENOTCONN) ? "; Not connected" : "");
796752
return error->status;
797-
} // serviceDiscoveredCB
753+
} // serviceDiscCB
798754

799755
/**
800756
* @brief Get the value of a specific characteristic associated with a specific service.
@@ -803,8 +759,7 @@ int NimBLEClient::serviceDiscoveredCB(uint16_t connHandle,
803759
* @returns characteristic value or an empty value if not found.
804760
*/
805761
NimBLEAttValue NimBLEClient::getValue(const NimBLEUUID& serviceUUID, const NimBLEUUID& characteristicUUID) {
806-
NIMBLE_LOGD(LOG_TAG,
807-
">> getValue: serviceUUID: %s, characteristicUUID: %s",
762+
NIMBLE_LOGD(LOG_TAG, ">> getValue: serviceUUID: %s, characteristicUUID: %s",
808763
serviceUUID.toString().c_str(),
809764
characteristicUUID.toString().c_str());
810765

@@ -833,15 +788,14 @@ bool NimBLEClient::setValue(const NimBLEUUID& serviceUUID,
833788
const NimBLEUUID& characteristicUUID,
834789
const NimBLEAttValue& value,
835790
bool response) {
836-
NIMBLE_LOGD(LOG_TAG,
837-
">> setValue: serviceUUID: %s, characteristicUUID: %s",
791+
NIMBLE_LOGD(LOG_TAG, ">> setValue: serviceUUID: %s, characteristicUUID: %s",
838792
serviceUUID.toString().c_str(),
839793
characteristicUUID.toString().c_str());
840794

841795
bool ret = false;
842796
auto pService = getService(serviceUUID);
843797
if (pService != nullptr) {
844-
NimBLERemoteCharacteristic* pChar = pService->getCharacteristic(characteristicUUID);
798+
auto pChar = pService->getCharacteristic(characteristicUUID);
845799
if (pChar != nullptr) {
846800
ret = pChar->writeValue(value, response);
847801
}
@@ -858,11 +812,13 @@ bool NimBLEClient::setValue(const NimBLEUUID& serviceUUID,
858812
*/
859813
NimBLERemoteCharacteristic* NimBLEClient::getCharacteristic(uint16_t handle) {
860814
for (const auto& svc : m_svcVec) {
861-
if (svc->getStartHandle() <= handle && handle <= svc->getEndHandle()) {
862-
for (const auto& chr : svc->m_vChars) {
863-
if (chr->getHandle() == handle) {
864-
return chr;
865-
}
815+
if (svc->getStartHandle() > handle && handle > svc->getEndHandle()) {
816+
continue;
817+
}
818+
819+
for (const auto& chr : svc->m_vChars) {
820+
if (chr->getHandle() == handle) {
821+
return chr;
866822
}
867823
}
868824
}
@@ -882,28 +838,28 @@ uint16_t NimBLEClient::getMTU() const {
882838
* @brief Callback for the MTU exchange API function.
883839
* @details When the MTU exchange is complete the API will call this and report the new MTU.
884840
*/
885-
int NimBLEClient::exchangeMTUCb(uint16_t conn_handle, const ble_gatt_error* error, uint16_t mtu, void* arg) {
886-
NIMBLE_LOGD(LOG_TAG, "exchangeMTUCb: status=%d, mtu=%d", error->status, mtu);
841+
int NimBLEClient::exchangeMTUCB(uint16_t connHandle, const ble_gatt_error* error, uint16_t mtu, void* arg) {
842+
NIMBLE_LOGD(LOG_TAG, "exchangeMTUCB: status=%d, mtu=%d", error->status, mtu);
887843

888844
NimBLEClient* pClient = (NimBLEClient*)arg;
889-
if (pClient->getConnHandle() != conn_handle) {
845+
if (pClient->getConnHandle() != connHandle) {
890846
return 0;
891847
}
892848

893849
if (error->status != 0) {
894-
NIMBLE_LOGE(LOG_TAG, "exchangeMTUCb() rc=%d %s", error->status, NimBLEUtils::returnCodeToString(error->status));
850+
NIMBLE_LOGE(LOG_TAG, "exchangeMTUCB() rc=%d %s", error->status, NimBLEUtils::returnCodeToString(error->status));
895851
pClient->m_lastErr = error->status;
896852
}
897853

898854
return 0;
899-
} // exchangeMTUCb
855+
} // exchangeMTUCB
900856

901857
/**
902858
* @brief Begin the MTU exchange process with the server.
903859
* @returns true if the request was sent successfully.
904860
*/
905861
bool NimBLEClient::exchangeMTU() {
906-
int rc = ble_gattc_exchange_mtu(m_connHandle, NimBLEClient::exchangeMTUCb, this);
862+
int rc = ble_gattc_exchange_mtu(m_connHandle, NimBLEClient::exchangeMTUCB, this);
907863
if (rc != 0) {
908864
NIMBLE_LOGE(LOG_TAG, "MTU exchange error; rc=%d %s", rc, NimBLEUtils::returnCodeToString(rc));
909865
m_lastErr = rc;
@@ -989,25 +945,25 @@ int NimBLEClient::handleGapEvent(struct ble_gap_event* event, void* arg) {
989945
pClient->m_pClientCallbacks->onConnect(pClient);
990946
}
991947

992-
if (pClient->m_config.exchangeMTU) {
993-
if (!pClient->exchangeMTU()) {
994-
rc = pClient->m_lastErr; // sets the error in the task data
995-
break;
996-
}
997-
998-
return 0; // return as we may have a task waiting for the MTU before releasing it.
948+
if (!pClient->m_config.exchangeMTU) {
949+
break;
999950
}
1000-
} else {
1001-
pClient->m_connHandle = BLE_HS_CONN_HANDLE_NONE;
1002951

1003-
if (pClient->m_config.asyncConnect) {
1004-
pClient->m_pClientCallbacks->onConnectFail(pClient, rc);
1005-
if (pClient->m_config.deleteOnConnectFail) {
1006-
NimBLEDevice::deleteClient(pClient);
1007-
}
952+
if (!pClient->exchangeMTU()) {
953+
rc = pClient->m_lastErr; // sets the error in the task data
954+
break;
1008955
}
956+
957+
return 0; // return as we may have a task waiting for the MTU before releasing it.
1009958
}
1010959

960+
pClient->m_connHandle = BLE_HS_CONN_HANDLE_NONE;
961+
if (pClient->m_config.asyncConnect) {
962+
pClient->m_pClientCallbacks->onConnectFail(pClient, rc);
963+
if (pClient->m_config.deleteOnConnectFail) {
964+
NimBLEDevice::deleteClient(pClient);
965+
}
966+
}
1011967
break;
1012968
} // BLE_GAP_EVENT_CONNECT
1013969

@@ -1035,23 +991,23 @@ int NimBLEClient::handleGapEvent(struct ble_gap_event* event, void* arg) {
1035991
continue;
1036992
}
1037993

1038-
NIMBLE_LOGD(LOG_TAG,
1039-
"checking service %s for handle: %d",
994+
NIMBLE_LOGD(LOG_TAG, "checking service %s for handle: %d",
1040995
svc->getUUID().toString().c_str(),
1041996
event->notify_rx.attr_handle);
1042997

1043998
for (const auto& chr : svc->m_vChars) {
1044-
if (chr->getHandle() == event->notify_rx.attr_handle) {
1045-
NIMBLE_LOGD(LOG_TAG, "Got Notification for characteristic %s", chr->toString().c_str());
999+
if (chr->getHandle() != event->notify_rx.attr_handle) {
1000+
continue;
1001+
}
10461002

1047-
uint32_t data_len = OS_MBUF_PKTLEN(event->notify_rx.om);
1048-
chr->m_value.setValue(event->notify_rx.om->om_data, data_len);
1003+
NIMBLE_LOGD(LOG_TAG, "Got Notification for characteristic %s", chr->toString().c_str());
1004+
uint32_t data_len = OS_MBUF_PKTLEN(event->notify_rx.om);
1005+
chr->m_value.setValue(event->notify_rx.om->om_data, data_len);
10491006

1050-
if (chr->m_notifyCallback != nullptr) {
1051-
chr->m_notifyCallback(chr, event->notify_rx.om->om_data, data_len, !event->notify_rx.indication);
1052-
}
1053-
break;
1007+
if (chr->m_notifyCallback != nullptr) {
1008+
chr->m_notifyCallback(chr, event->notify_rx.om->om_data, data_len, !event->notify_rx.indication);
10541009
}
1010+
break;
10551011
}
10561012
}
10571013

@@ -1064,8 +1020,7 @@ int NimBLEClient::handleGapEvent(struct ble_gap_event* event, void* arg) {
10641020
return 0;
10651021
}
10661022
NIMBLE_LOGD(LOG_TAG, "Peer requesting to update connection parameters");
1067-
NIMBLE_LOGD(LOG_TAG,
1068-
"MinInterval: %d, MaxInterval: %d, Latency: %d, Timeout: %d",
1023+
NIMBLE_LOGD(LOG_TAG, "MinInterval: %d, MaxInterval: %d, Latency: %d, Timeout: %d",
10691024
event->conn_update_req.peer_params->itvl_min,
10701025
event->conn_update_req.peer_params->itvl_max,
10711026
event->conn_update_req.peer_params->latency,

src/NimBLEClient.h

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -116,13 +116,13 @@ class NimBLEClient {
116116
NimBLEClient(const NimBLEClient&) = delete;
117117
NimBLEClient& operator=(const NimBLEClient&) = delete;
118118

119-
bool retrieveServices(const NimBLEUUID* uuidFilter = nullptr);
119+
bool retrieveServices(const NimBLEUUID* uuid = nullptr, NimBLERemoteService **out = nullptr);
120+
static int exchangeMTUCB(uint16_t connHandle, const ble_gatt_error* error, uint16_t mtu, void* arg);
120121
static int handleGapEvent(struct ble_gap_event* event, void* arg);
121-
static int exchangeMTUCb(uint16_t conn_handle, const ble_gatt_error* error, uint16_t mtu, void* arg);
122-
static int serviceDiscoveredCB(uint16_t connHandle,
123-
const struct ble_gatt_error* error,
124-
const struct ble_gatt_svc* service,
125-
void* arg);
122+
static int svcDiscCB(uint16_t connHandle,
123+
const struct ble_gatt_error* error,
124+
const struct ble_gatt_svc* service,
125+
void* arg);
126126

127127
NimBLEAddress m_peerAddress;
128128
mutable int m_lastErr;

0 commit comments

Comments
 (0)