Breaking: Use std::vector instead of std::map in client classes (#46)

* Exchange map for vector, saving 1,076 bytes of program memory and 5,024 bytes of heap for a small device (LYWSD03MMC)

* Removing m_characteristicMapByHandle (using the handles form m_characteristicVector instead) saving in total (compared to the current master) 1,508 bytes of program memory and 6,500 bytes of heap for a small device (LYWSD03MMC)

* Change NimBLEScan container from std::map to std::vector

* Add function to get advertised device by address

* Update documentation
This commit is contained in:
h2zero
2020-05-17 20:21:35 -06:00
parent fc1022a46d
commit 6f4ee4b498
10 changed files with 169 additions and 142 deletions

View File

@@ -43,8 +43,8 @@ static NimBLEClientCallbacks defaultCallbacks;
* Since there is a hierarchical relationship here, we will have the idea that from a NimBLERemoteService will own
* zero or more remote characteristics and a NimBLERemoteCharacteristic will own zero or more remote NimBLEDescriptors.
*
* We will assume that a NimBLERemoteService contains a map that maps NimBLEUUIDs to the set of owned characteristics
* and that a NimBLECharacteristic contains a map that maps NimBLEUUIDs to the set of owned descriptors.
* We will assume that a NimBLERemoteService contains a vector of owned characteristics
* and that a NimBLECharacteristic contains a vector of owned descriptors.
*
*
*/
@@ -90,10 +90,11 @@ NimBLEClient::~NimBLEClient() {
void NimBLEClient::clearServices() {
NIMBLE_LOGD(LOG_TAG, ">> clearServices");
// Delete all the services.
for (auto &myPair : m_servicesMap) {
delete myPair.second;
for(auto &it: m_servicesVector) {
delete it;
}
m_servicesMap.clear();
m_servicesVector.clear();
m_haveServices = false;
NIMBLE_LOGD(LOG_TAG, "<< clearServices");
} // clearServices
@@ -368,23 +369,24 @@ NimBLERemoteService* NimBLEClient::getService(const NimBLEUUID &uuid) {
if (!m_haveServices) {
return nullptr;
}
std::string uuidStr = uuid.toString();
for (auto &myPair : m_servicesMap) {
if (myPair.first == uuidStr) {
for(auto &it: m_servicesVector) {
if(it->getUUID() == uuid) {
NIMBLE_LOGD(LOG_TAG, "<< getService: found the service with uuid: %s", uuid.toString().c_str());
return myPair.second;
return it;
}
}
NIMBLE_LOGD(LOG_TAG, "<< getService: not found");
return nullptr;
} // getService
/**
* @Get a pointer to the map of found services.
* @Get a pointer to the vector of found services.
*/
std::map<std::string, NimBLERemoteService*>* NimBLEClient::getServices() {
return &m_servicesMap;
std::vector<NimBLERemoteService*>* NimBLEClient::getServices() {
return &m_servicesVector;
}
@@ -425,8 +427,8 @@ bool NimBLEClient::retrieveServices() {
// If sucessful, remember that we now have services.
m_haveServices = (m_semaphoreSearchCmplEvt.wait("retrieveServices") == 0);
if(m_haveServices){
for (auto &myPair : m_servicesMap) {
if(!m_isConnected || !myPair.second->retrieveCharacteristics()) {
for (auto &it: m_servicesVector) {
if(!m_isConnected || !it->retrieveCharacteristics()) {
NIMBLE_LOGE(LOG_TAG, "Disconnected, could not retrieve characteristics -aborting");
return false;
}
@@ -463,9 +465,9 @@ int NimBLEClient::serviceDiscoveredCB(
switch (error->status) {
case 0: {
// Found a service - add it to the map
// Found a service - add it to the vector
NimBLERemoteService* pRemoteService = new NimBLERemoteService(peer, service);
peer->m_servicesMap.insert(std::pair<std::string, NimBLERemoteService*>(pRemoteService->getUUID().toString(), pRemoteService));
peer->m_servicesVector.push_back(pRemoteService);
break;
}
case BLE_HS_EDONE:{
@@ -662,20 +664,25 @@ uint16_t NimBLEClient::getMTU() {
if(!client->m_haveServices)
return 0;
for(auto &sPair : client->m_servicesMap){
for(auto &it: client->m_servicesVector) {
// Dont waste cycles searching services without this handle in their range
if(sPair.second->getEndHandle() < event->notify_rx.attr_handle) {
if(it->getEndHandle() < event->notify_rx.attr_handle) {
continue;
}
auto cMap = sPair.second->getCharacteristicsByHandle();
NIMBLE_LOGD(LOG_TAG, "checking service %s for handle: %d", sPair.second->getUUID().toString().c_str(),event->notify_rx.attr_handle);
auto characteristic = cMap->find(event->notify_rx.attr_handle);
if(characteristic != cMap->end()) {
NIMBLE_LOGD(LOG_TAG, "Got Notification for characteristic %s", characteristic->second->toString().c_str());
if (characteristic->second->m_notifyCallback != nullptr) {
NIMBLE_LOGD(LOG_TAG, "Invoking callback for notification on characteristic %s", characteristic->second->toString().c_str());
characteristic->second->m_notifyCallback(characteristic->second, event->notify_rx.om->om_data, event->notify_rx.om->om_len, !event->notify_rx.indication);
auto cVector = it->getCharacteristics();
NIMBLE_LOGD(LOG_TAG, "checking service %s for handle: %d", it->getUUID().toString().c_str(),event->notify_rx.attr_handle);
auto characteristic = cVector->cbegin();
for(; characteristic != cVector->cend(); ++characteristic) {
if((*characteristic)->m_handle == event->notify_rx.attr_handle) break;
}
if(characteristic != cVector->cend()) {
NIMBLE_LOGD(LOG_TAG, "Got Notification for characteristic %s", (*characteristic)->toString().c_str());
if ((*characteristic)->m_notifyCallback != nullptr) {
NIMBLE_LOGD(LOG_TAG, "Invoking callback for notification on characteristic %s", (*characteristic)->toString().c_str());
(*characteristic)->m_notifyCallback(*characteristic, event->notify_rx.om->om_data, event->notify_rx.om->om_len, !event->notify_rx.indication);
}
break;
@@ -851,8 +858,9 @@ void NimBLEClient::setClientCallbacks(NimBLEClientCallbacks* pClientCallbacks, b
std::string NimBLEClient::toString() {
std::string res = "peer address: " + m_peerAddress.toString();
res += "\nServices:\n";
for (auto &myPair : m_servicesMap) {
res += myPair.second->toString() + "\n";
for(auto &it: m_servicesVector) {
res += it->toString() + "\n";
}
return res;