mirror of
https://github.com/h2zero/esp-nimble-cpp.git
synced 2024-11-24 14:10:55 +01:00
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:
parent
fc1022a46d
commit
6f4ee4b498
10 changed files with 169 additions and 142 deletions
|
@ -100,7 +100,7 @@ The `BLEAdvertisedDeviceCallbacks` class `onResult()` method now receives a poin
|
|||
Defined as:
|
||||
```
|
||||
bool connect(NimBLEAdvertisedDevice* device, bool refreshServices = true);
|
||||
bool connect(NimBLEAddress address, uint8_t type = BLE_ADDR_TYPE_PUBLIC, bool refreshServices = true);
|
||||
bool connect(NimBLEAddress address, uint8_t type = BLE_ADDR_PUBLIC, bool refreshServices = true);
|
||||
```
|
||||
If set to false the client will use the services database it retrieved from the peripheral last time it connected.
|
||||
This allows for faster connections and power saving if the devices just dropped connection and want to reconnect.
|
||||
|
@ -111,6 +111,17 @@ NimBLERemoteCharacteristic::registerForNotify();
|
|||
```
|
||||
Now return true or false to indicate success or failure so you can choose to disconnect or try again.
|
||||
|
||||
```
|
||||
NimBLEClient::getServices()
|
||||
NimBLERemoteService::getCharacteristics()
|
||||
```
|
||||
Now return a pointer to a `std::vector` of the respective object database instead of `std::map`.
|
||||
|
||||
`NimBLERemoteService::getCharacteristicsByHandle()`
|
||||
Has been removed from the API as it is no longer maintained in the library.
|
||||
|
||||
The last two above changes reduce the heap usage significantly with minimal application code adjustments.
|
||||
|
||||
#### Client Security:
|
||||
The client will automatically initiate security when the peripheral responds that it's required.
|
||||
The default configuration will use "just-works" pairing with no bonding, if you wish to enable bonding see below.
|
||||
|
|
11
README.md
11
README.md
|
@ -1,7 +1,14 @@
|
|||
# *** UPDATE ***
|
||||
Client long read/write characteristics/descriptors now working.
|
||||
We are now nearing 100% replacement of the original cpp_utils BLE library :smile:
|
||||
**Breaking change:** Client and scan now use `std::vector` instead of `std::map` for storing the remote attribute database.
|
||||
|
||||
This change will affect your application code if you use `NimBLEClient::getServices()` or `NimBLERemoteService::getCharacteristics()`
|
||||
in your application as they now return a pointer to `std::vector` of the respective attributes.
|
||||
|
||||
In addition `NimBLERemoteService::getCharacteristicsByHandle()` has been removed as it is no longer maintained in the library.
|
||||
|
||||
These changes were necessary due to the amount of resources required to use `std::map`, it was not justifed by any benfit it provided.
|
||||
|
||||
It is expected that there will be minimal impact on most applications, if you need help adjusting your code please create an issue.
|
||||
|
||||
# esp-nimble-cpp
|
||||
NimBLE CPP library for use with ESP32 that attempts to maintain compatibility with the @nkolban cpp_uitls API.
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -24,7 +24,7 @@
|
|||
#include "NimBLEAdvertisedDevice.h"
|
||||
#include "NimBLERemoteService.h"
|
||||
|
||||
#include <map>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
|
||||
class NimBLERemoteService;
|
||||
|
@ -41,9 +41,10 @@ public:
|
|||
int disconnect(uint8_t reason = BLE_ERR_REM_USER_CONN_TERM); // Disconnect from the remote BLE Server
|
||||
NimBLEAddress getPeerAddress(); // Get the address of the remote BLE Server
|
||||
int getRssi(); // Get the RSSI of the remote BLE Server
|
||||
std::map<std::string, NimBLERemoteService*>* getServices(); // Get a map of the services offered by the remote BLE Server
|
||||
NimBLERemoteService* getService(const char* uuid); // Get a reference to a specified service offered by the remote BLE server.
|
||||
NimBLERemoteService* getService(const NimBLEUUID &uuid); // Get a reference to a specified service offered by the remote BLE server.
|
||||
|
||||
std::vector<NimBLERemoteService*>* getServices(); // Get a vector of the services offered by the remote BLE Server
|
||||
NimBLERemoteService* getService(const char* uuid); // Get a reference to a specified service offered by the remote BLE server.
|
||||
NimBLERemoteService* getService(const NimBLEUUID &uuid); // Get a reference to a specified service offered by the remote BLE server.
|
||||
std::string getValue(const NimBLEUUID &serviceUUID, const NimBLEUUID &characteristicUUID); // Get the value of a given characteristic at a given service.
|
||||
bool setValue(const NimBLEUUID &serviceUUID, const NimBLEUUID &characteristicUUID, const std::string &value); // Set the value of a given characteristic at a given service.
|
||||
bool isConnected(); // Return true if we are connected.
|
||||
|
@ -87,7 +88,7 @@ private:
|
|||
FreeRTOS::Semaphore m_semaphoreSearchCmplEvt = FreeRTOS::Semaphore("SearchCmplEvt");
|
||||
FreeRTOS::Semaphore m_semeaphoreSecEvt = FreeRTOS::Semaphore("Security");
|
||||
|
||||
std::map<std::string, NimBLERemoteService*> m_servicesMap;
|
||||
std::vector<NimBLERemoteService*> m_servicesVector;
|
||||
|
||||
private:
|
||||
friend class NimBLEClientCallbacks;
|
||||
|
|
|
@ -157,10 +157,9 @@ int NimBLERemoteCharacteristic::descriptorDiscCB(uint16_t conn_handle,
|
|||
|
||||
switch (error->status) {
|
||||
case 0: {
|
||||
// Found a descriptor - add it to the map
|
||||
// Found a descriptor - add it to the vector
|
||||
NimBLERemoteDescriptor* pNewRemoteDescriptor = new NimBLERemoteDescriptor(characteristic, dsc);
|
||||
characteristic->m_descriptorMap.insert(std::pair<std::string, NimBLERemoteDescriptor*>(pNewRemoteDescriptor->getUUID().toString(), pNewRemoteDescriptor));
|
||||
|
||||
characteristic->m_descriptorVector.push_back(pNewRemoteDescriptor);
|
||||
break;
|
||||
}
|
||||
case BLE_HS_EDONE:{
|
||||
|
@ -212,15 +211,15 @@ bool NimBLERemoteCharacteristic::retrieveDescriptors(uint16_t endHdl) {
|
|||
}
|
||||
|
||||
return true;
|
||||
NIMBLE_LOGD(LOG_TAG, "<< retrieveDescriptors(): Found %d descriptors.", m_descriptorMap.size());
|
||||
NIMBLE_LOGD(LOG_TAG, "<< retrieveDescriptors(): Found %d descriptors.", m_descriptorVector.size());
|
||||
} // getDescriptors
|
||||
|
||||
|
||||
/**
|
||||
* @brief Retrieve the map of descriptors keyed by UUID.
|
||||
*/
|
||||
std::map<std::string, NimBLERemoteDescriptor*>* NimBLERemoteCharacteristic::getDescriptors() {
|
||||
return &m_descriptorMap;
|
||||
* @brief Retrieve the vector of descriptors.
|
||||
*/
|
||||
std::vector<NimBLERemoteDescriptor*>* NimBLERemoteCharacteristic::getDescriptors() {
|
||||
return &m_descriptorVector;
|
||||
} // getDescriptors
|
||||
|
||||
|
||||
|
@ -248,12 +247,12 @@ uint16_t NimBLERemoteCharacteristic::getDefHandle() {
|
|||
*/
|
||||
NimBLERemoteDescriptor* NimBLERemoteCharacteristic::getDescriptor(const NimBLEUUID &uuid) {
|
||||
NIMBLE_LOGD(LOG_TAG, ">> getDescriptor: uuid: %s", uuid.toString().c_str());
|
||||
std::string v = uuid.toString();
|
||||
for (auto &myPair : m_descriptorMap) {
|
||||
if (myPair.first == v) {
|
||||
NIMBLE_LOGD(LOG_TAG, "<< getDescriptor: found");
|
||||
return myPair.second;
|
||||
}
|
||||
|
||||
for(auto &it: m_descriptorVector) {
|
||||
if(it->getUUID() == uuid) {
|
||||
NIMBLE_LOGD(LOG_TAG, "<< getDescriptor: found");
|
||||
return it;
|
||||
}
|
||||
}
|
||||
NIMBLE_LOGD(LOG_TAG, "<< getDescriptor: Not found");
|
||||
return nullptr;
|
||||
|
@ -444,19 +443,18 @@ bool NimBLERemoteCharacteristic::registerForNotify(notify_callback notifyCallbac
|
|||
|
||||
|
||||
/**
|
||||
* @brief Delete the descriptors in the descriptor map.
|
||||
* We maintain a map called m_descriptorMap that contains pointers to BLERemoteDescriptors
|
||||
* object references. Since we allocated these in this class, we are also responsible for deleteing
|
||||
* them. This method does just that.
|
||||
* @brief Delete the descriptors in the descriptor vector.
|
||||
* We maintain a vector called m_descriptorVector that contains pointers to BLERemoteDescriptors
|
||||
* object references. Since we allocated these in this class, we are also responsible for deleteing
|
||||
* them. This method does just that.
|
||||
* @return N/A.
|
||||
*/
|
||||
void NimBLERemoteCharacteristic::removeDescriptors() {
|
||||
// Iterate through all the descriptors releasing their storage and erasing them from the map.
|
||||
for (auto &myPair : m_descriptorMap) {
|
||||
m_descriptorMap.erase(myPair.first);
|
||||
delete myPair.second;
|
||||
// Iterate through all the descriptors releasing their storage and erasing them from the vector.
|
||||
for(auto &it: m_descriptorVector) {
|
||||
delete it;
|
||||
}
|
||||
m_descriptorMap.clear(); // Technically not neeeded, but just to be sure.
|
||||
m_descriptorVector.clear();
|
||||
} // removeCharacteristics
|
||||
|
||||
|
||||
|
@ -478,8 +476,8 @@ std::string NimBLERemoteCharacteristic::toString() {
|
|||
snprintf(val, sizeof(val), "%02x", m_charProp);
|
||||
res += val;
|
||||
|
||||
for (auto &myPair : m_descriptorMap) {
|
||||
res += "\n" + myPair.second->toString();
|
||||
for(auto &it: m_descriptorVector) {
|
||||
res += "\n" + it->toString();
|
||||
}
|
||||
|
||||
return res;
|
||||
|
@ -645,8 +643,8 @@ size_t NimBLERemoteCharacteristic::getDataLength() {
|
|||
|
||||
|
||||
void NimBLERemoteCharacteristic::releaseSemaphores() {
|
||||
for (auto &dPair : m_descriptorMap) {
|
||||
dPair.second->releaseSemaphores();
|
||||
for (auto &it: m_descriptorVector) {
|
||||
it->releaseSemaphores();
|
||||
}
|
||||
m_semaphoreWriteCharEvt.give(1);
|
||||
m_semaphoreGetDescEvt.give(1);
|
||||
|
|
|
@ -26,7 +26,7 @@
|
|||
#include "NimBLERemoteDescriptor.h"
|
||||
|
||||
//#include <string>
|
||||
#include <map>
|
||||
#include <vector>
|
||||
|
||||
class NimBLERemoteService;
|
||||
class NimBLERemoteDescriptor;
|
||||
|
@ -49,7 +49,7 @@ public:
|
|||
bool canWrite();
|
||||
bool canWriteNoResponse();
|
||||
NimBLERemoteDescriptor* getDescriptor(const NimBLEUUID &uuid);
|
||||
std::map<std::string, NimBLERemoteDescriptor*>* getDescriptors();
|
||||
std::vector<NimBLERemoteDescriptor*>* getDescriptors();
|
||||
uint16_t getHandle();
|
||||
uint16_t getDefHandle();
|
||||
NimBLEUUID getUUID();
|
||||
|
@ -98,8 +98,8 @@ private:
|
|||
size_t m_dataLen;
|
||||
notify_callback m_notifyCallback;
|
||||
|
||||
// We maintain a map of descriptors owned by this characteristic keyed by a string representation of the UUID.
|
||||
std::map<std::string, NimBLERemoteDescriptor*> m_descriptorMap;
|
||||
// We maintain a vector of descriptors owned by this characteristic.
|
||||
std::vector<NimBLERemoteDescriptor*> m_descriptorVector;
|
||||
}; // BLERemoteCharacteristic
|
||||
|
||||
#endif // #if defined( CONFIG_BT_NIMBLE_ROLE_CENTRAL)
|
||||
|
|
|
@ -81,10 +81,9 @@ NimBLERemoteCharacteristic* NimBLERemoteService::getCharacteristic(const char* u
|
|||
*/
|
||||
NimBLERemoteCharacteristic* NimBLERemoteService::getCharacteristic(const NimBLEUUID &uuid) {
|
||||
if (m_haveCharacteristics) {
|
||||
std::string v = uuid.toString();
|
||||
for (auto &myPair : m_characteristicMap) {
|
||||
if (myPair.first == v) {
|
||||
return myPair.second;
|
||||
for(auto &it: m_characteristicVector) {
|
||||
if(it->getUUID() == uuid) {
|
||||
return it;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -112,10 +111,9 @@ int NimBLERemoteService::characteristicDiscCB(uint16_t conn_handle,
|
|||
|
||||
switch (error->status) {
|
||||
case 0: {
|
||||
// Found a service - add it to the map
|
||||
// Found a service - add it to the vector
|
||||
NimBLERemoteCharacteristic* pRemoteCharacteristic = new NimBLERemoteCharacteristic(service, chr);
|
||||
service->m_characteristicMap.insert(std::pair<std::string, NimBLERemoteCharacteristic*>(pRemoteCharacteristic->getUUID().toString(), pRemoteCharacteristic));
|
||||
service->m_characteristicMapByHandle.insert(std::pair<uint16_t, NimBLERemoteCharacteristic*>(chr->val_handle, pRemoteCharacteristic));
|
||||
service->m_characteristicVector.push_back(pRemoteCharacteristic);
|
||||
break;
|
||||
}
|
||||
case BLE_HS_EDONE:{
|
||||
|
@ -171,17 +169,18 @@ bool NimBLERemoteService::retrieveCharacteristics() {
|
|||
m_haveCharacteristics = (m_semaphoreGetCharEvt.wait("retrieveCharacteristics") == 0);
|
||||
if(m_haveCharacteristics){
|
||||
uint16_t endHdl = 0xFFFF;
|
||||
NIMBLE_LOGD(LOG_TAG, "Found %d Characteristics", m_characteristicMapByHandle.size());
|
||||
for (auto it = m_characteristicMapByHandle.cbegin(); it != m_characteristicMapByHandle.cend(); ++it) {
|
||||
NIMBLE_LOGD(LOG_TAG, "Found UUID: %s Handle: %d Def Handle: %d", (*it).second->getUUID().toString().c_str(), (*it).second->getHandle(), (*it).second->getDefHandle());
|
||||
|
||||
NIMBLE_LOGD(LOG_TAG, "Found %d Characteristics", m_characteristicVector.size());
|
||||
for(auto it = m_characteristicVector.cbegin(); it != m_characteristicVector.cend(); ++it) {
|
||||
NIMBLE_LOGD(LOG_TAG, "Found UUID: %s Handle: %d Def Handle: %d", (*it)->getUUID().toString().c_str(), (*it)->getHandle(), (*it)->getDefHandle());
|
||||
// The descriptor handle is between this characteristic val_handle and the next ones def_handle
|
||||
// so make the end of the scan at the handle before the next characteristic def_handle
|
||||
|
||||
// Make sure we don't go past the service end handle
|
||||
if(++it != m_characteristicMapByHandle.cend()){
|
||||
NIMBLE_LOGD(LOG_TAG, "Next UUID: %s Handle: %d Def Handle: %d", (*it).second->getUUID().toString().c_str(), (*it).second->getHandle(),(*it).second->getDefHandle());
|
||||
if(++it != m_characteristicVector.cend()){
|
||||
NIMBLE_LOGD(LOG_TAG, "Next UUID: %s Handle: %d Def Handle: %d", (*it)->getUUID().toString().c_str(), (*it)->getHandle(),(*it)->getDefHandle());
|
||||
|
||||
endHdl = (*it).second->getDefHandle()-1;
|
||||
endHdl = (*it)->getDefHandle()-1;
|
||||
}
|
||||
else{
|
||||
NIMBLE_LOGD(LOG_TAG, "END CHARS");
|
||||
|
@ -190,8 +189,8 @@ bool NimBLERemoteService::retrieveCharacteristics() {
|
|||
--it;
|
||||
|
||||
//If there is no handles between this characteristic and the next there is no descriptor so skip to the next
|
||||
if((*it).second->getHandle() != endHdl){
|
||||
if(!m_pClient->m_isConnected || !(*it).second->retrieveDescriptors(endHdl)) {
|
||||
if((*it)->getHandle() != endHdl){
|
||||
if(!m_pClient->m_isConnected || !(*it)->retrieveDescriptors(endHdl)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -209,23 +208,14 @@ bool NimBLERemoteService::retrieveCharacteristics() {
|
|||
|
||||
|
||||
/**
|
||||
* @brief Retrieve a map of all the characteristics of this service.
|
||||
* @return A map of all the characteristics of this service.
|
||||
* @brief Retrieve a vector of all the characteristics of this service.
|
||||
* @return A vector of all the characteristics of this service.
|
||||
*/
|
||||
std::map<std::string, NimBLERemoteCharacteristic*>* NimBLERemoteService::getCharacteristics() {
|
||||
return &m_characteristicMap;
|
||||
std::vector<NimBLERemoteCharacteristic*>* NimBLERemoteService::getCharacteristics() {
|
||||
return &m_characteristicVector;
|
||||
} // getCharacteristics
|
||||
|
||||
|
||||
/**
|
||||
* @brief Retrieve a map of all the characteristics of this service.
|
||||
* @return A map of all the characteristics of this service.
|
||||
*/
|
||||
std::map<uint16_t, NimBLERemoteCharacteristic*>* NimBLERemoteService::getCharacteristicsByHandle() {
|
||||
return &m_characteristicMapByHandle;
|
||||
} // getCharacteristicsByHandle
|
||||
|
||||
|
||||
/**
|
||||
* @brief Get the client associated with this service.
|
||||
* @return A reference to the client associated with this service.
|
||||
|
@ -301,20 +291,17 @@ bool NimBLERemoteService::setValue(const NimBLEUUID &characteristicUuid, const s
|
|||
|
||||
|
||||
/**
|
||||
* @brief Delete the characteristics in the characteristics map.
|
||||
* We maintain a map called m_characteristicsMap that contains pointers to BLERemoteCharacteristic
|
||||
* object references. Since we allocated these in this class, we are also responsible for deleteing
|
||||
* them. This method does just that.
|
||||
* @brief Delete the characteristics in the characteristics vector.
|
||||
* We maintain a vector called m_characteristicsVector that contains pointers to BLERemoteCharacteristic
|
||||
* object references. Since we allocated these in this class, we are also responsible for deleting
|
||||
* them. This method does just that.
|
||||
* @return N/A.
|
||||
*/
|
||||
void NimBLERemoteService::removeCharacteristics() {
|
||||
m_characteristicMap.clear(); // Clear the map
|
||||
|
||||
for (auto &myPair : m_characteristicMapByHandle) {
|
||||
delete myPair.second;
|
||||
for(auto &it: m_characteristicVector) {
|
||||
delete it;
|
||||
}
|
||||
m_characteristicMapByHandle.clear(); // Clear the map
|
||||
|
||||
m_characteristicVector.clear(); // Clear the vector
|
||||
} // removeCharacteristics
|
||||
|
||||
|
||||
|
@ -338,8 +325,8 @@ std::string NimBLERemoteService::toString() {
|
|||
res += " 0x";
|
||||
res += val;
|
||||
|
||||
for (auto &myPair : m_characteristicMap) {
|
||||
res += "\n" + myPair.second->toString();
|
||||
for (auto &it: m_characteristicVector) {
|
||||
res += "\n" + it->toString();
|
||||
}
|
||||
|
||||
return res;
|
||||
|
@ -351,8 +338,8 @@ std::string NimBLERemoteService::toString() {
|
|||
* Will release all characteristic and subsequently all descriptor semaphores for this service.
|
||||
*/
|
||||
void NimBLERemoteService::releaseSemaphores() {
|
||||
for (auto &cPair : m_characteristicMapByHandle) {
|
||||
cPair.second->releaseSemaphores();
|
||||
for(auto &it: m_characteristicVector) {
|
||||
it->releaseSemaphores();
|
||||
}
|
||||
m_semaphoreGetCharEvt.give(1);
|
||||
}
|
||||
|
|
|
@ -25,7 +25,7 @@
|
|||
#include "FreeRTOS.h"
|
||||
#include "NimBLERemoteCharacteristic.h"
|
||||
|
||||
#include <map>
|
||||
#include <vector>
|
||||
|
||||
class NimBLEClient;
|
||||
class NimBLERemoteCharacteristic;
|
||||
|
@ -42,8 +42,7 @@ public:
|
|||
NimBLERemoteCharacteristic* getCharacteristic(const char* uuid); // Get the specified characteristic reference.
|
||||
NimBLERemoteCharacteristic* getCharacteristic(const NimBLEUUID &uuid); // Get the specified characteristic reference.
|
||||
// BLERemoteCharacteristic* getCharacteristic(uint16_t uuid); // Get the specified characteristic reference.
|
||||
std::map<std::string, NimBLERemoteCharacteristic*>* getCharacteristics();
|
||||
std::map<uint16_t, NimBLERemoteCharacteristic*>* getCharacteristicsByHandle(); // Get the characteristics map.
|
||||
std::vector<NimBLERemoteCharacteristic*>* getCharacteristics();
|
||||
// void getCharacteristics(std::map<uint16_t, BLERemoteCharacteristic*>* pCharacteristicMap);
|
||||
|
||||
NimBLEClient* getClient(void); // Get a reference to the client associated with this service.
|
||||
|
@ -74,11 +73,8 @@ private:
|
|||
|
||||
// Properties
|
||||
|
||||
// We maintain a map of characteristics owned by this service keyed by a string representation of the UUID.
|
||||
std::map<std::string, NimBLERemoteCharacteristic*> m_characteristicMap;
|
||||
|
||||
// We maintain a map of characteristics owned by this service keyed by a handle.
|
||||
std::map<uint16_t, NimBLERemoteCharacteristic*> m_characteristicMapByHandle;
|
||||
// We maintain a vector of characteristics owned by this service.
|
||||
std::vector<NimBLERemoteCharacteristic*> m_characteristicVector;
|
||||
|
||||
bool m_haveCharacteristics; // Have we previously obtained the characteristics.
|
||||
NimBLEClient* m_pClient;
|
||||
|
|
|
@ -117,13 +117,15 @@ NimBLEScan::NimBLEScan() {
|
|||
|
||||
NimBLEAdvertisedDevice* advertisedDevice = nullptr;
|
||||
|
||||
// If we've seen this device before get a pointer to it from the map
|
||||
auto it = pScan->m_scanResults.m_advertisedDevicesMap.find(advertisedAddress.toString());
|
||||
if(it != pScan->m_scanResults.m_advertisedDevicesMap.cend()) {
|
||||
advertisedDevice = (*it).second;
|
||||
// If we've seen this device before get a pointer to it from the vector
|
||||
for(auto &it: pScan->m_scanResults.m_advertisedDevicesVector) {
|
||||
if(it->getAddress() == advertisedAddress) {
|
||||
advertisedDevice = it;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// If we haven't seen this device before; create a new instance and insert it in the map.
|
||||
// If we haven't seen this device before; create a new instance and insert it in the vector.
|
||||
// Otherwise just update the relevant parameters of the already known device.
|
||||
if(advertisedDevice == nullptr){
|
||||
advertisedDevice = new NimBLEAdvertisedDevice();
|
||||
|
@ -131,7 +133,7 @@ NimBLEScan::NimBLEScan() {
|
|||
advertisedDevice->setAddress(advertisedAddress);
|
||||
//NIMBLE_LOGE(LOG_TAG, "advertisement type: %d, %s",event->disc.event_type, NimBLEUtils::advTypeToString(event->disc.event_type));
|
||||
advertisedDevice->setAdvType(event->disc.event_type);
|
||||
pScan->m_scanResults.m_advertisedDevicesMap.insert(std::pair<std::string, NimBLEAdvertisedDevice*>(advertisedAddress.toString(), advertisedDevice));
|
||||
pScan->m_scanResults.m_advertisedDevicesVector.push_back(advertisedDevice);
|
||||
NIMBLE_LOGI(LOG_TAG, "NEW DEVICE FOUND: %s", advertisedAddress.toString().c_str());
|
||||
}
|
||||
else{
|
||||
|
@ -262,7 +264,7 @@ bool NimBLEScan::start(uint32_t duration, void (*scanCompleteCB)(NimBLEScanResul
|
|||
}
|
||||
|
||||
// if we are connecting to devices that are advertising even after being connected, multiconnecting peripherals
|
||||
// then we should not clear map or we will connect the same device few times
|
||||
// then we should not clear vector or we will connect the same device few times
|
||||
if(!is_continue) {
|
||||
clearResults();
|
||||
}
|
||||
|
@ -330,9 +332,14 @@ void NimBLEScan::stop() {
|
|||
// delete peer device from cache after disconnecting, it is required in case we are connecting to devices with not public address
|
||||
void NimBLEScan::erase(const NimBLEAddress &address) {
|
||||
NIMBLE_LOGI(LOG_TAG, "erase device: %s", address.toString().c_str());
|
||||
NimBLEAdvertisedDevice *advertisedDevice = m_scanResults.m_advertisedDevicesMap.find(address.toString())->second;
|
||||
m_scanResults.m_advertisedDevicesMap.erase(address.toString());
|
||||
delete advertisedDevice;
|
||||
|
||||
for(auto it = m_scanResults.m_advertisedDevicesVector.begin(); it != m_scanResults.m_advertisedDevicesVector.begin(); ++it) {
|
||||
if((*it)->getAddress() == address) {
|
||||
delete *it;
|
||||
m_scanResults.m_advertisedDevicesVector.erase(it);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -359,10 +366,10 @@ NimBLEScanResults NimBLEScan::getResults() {
|
|||
* @brief Clear the results of the scan.
|
||||
*/
|
||||
void NimBLEScan::clearResults() {
|
||||
for(auto _dev : m_scanResults.m_advertisedDevicesMap){
|
||||
delete _dev.second;
|
||||
for(auto &it: m_scanResults.m_advertisedDevicesVector) {
|
||||
delete it;
|
||||
}
|
||||
m_scanResults.m_advertisedDevicesMap.clear();
|
||||
m_scanResults.m_advertisedDevicesVector.clear();
|
||||
}
|
||||
|
||||
|
||||
|
@ -382,7 +389,7 @@ void NimBLEScanResults::dump() {
|
|||
* @return The number of devices found in the last scan.
|
||||
*/
|
||||
int NimBLEScanResults::getCount() {
|
||||
return m_advertisedDevicesMap.size();
|
||||
return m_advertisedDevicesVector.size();
|
||||
} // getCount
|
||||
|
||||
|
||||
|
@ -393,14 +400,24 @@ int NimBLEScanResults::getCount() {
|
|||
* @return The device at the specified index.
|
||||
*/
|
||||
NimBLEAdvertisedDevice NimBLEScanResults::getDevice(uint32_t i) {
|
||||
uint32_t x = 0;
|
||||
NimBLEAdvertisedDevice dev = *m_advertisedDevicesMap.begin()->second;
|
||||
for (auto it = m_advertisedDevicesMap.begin(); it != m_advertisedDevicesMap.end(); it++) {
|
||||
dev = *it->second;
|
||||
if (x==i) break;
|
||||
x++;
|
||||
return *m_advertisedDevicesVector[i];
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Return a pointer to the specified device at the given address.
|
||||
* If the address is not found a nullptr is returned.
|
||||
* @param [in] address The address of the device.
|
||||
* @return A pointer to the device at the specified address.
|
||||
*/
|
||||
NimBLEAdvertisedDevice *NimBLEScanResults::getDevice(const NimBLEAddress &address) {
|
||||
for(size_t index = 0; index < m_advertisedDevicesVector.size(); index++) {
|
||||
if(m_advertisedDevicesVector[index]->getAddress() == address) {
|
||||
return m_advertisedDevicesVector[index];
|
||||
}
|
||||
}
|
||||
return dev;
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
#endif // #if defined(CONFIG_BT_NIMBLE_ROLE_OBSERVER)
|
||||
|
|
|
@ -24,12 +24,13 @@
|
|||
|
||||
#include "host/ble_gap.h"
|
||||
|
||||
#include <map>
|
||||
#include <vector>
|
||||
|
||||
class NimBLEDevice;
|
||||
class NimBLEScan;
|
||||
class NimBLEAdvertisedDevice;
|
||||
class NimBLEAdvertisedDeviceCallbacks;
|
||||
class NimBLEAddress;
|
||||
|
||||
/**
|
||||
* @brief The result of having performed a scan.
|
||||
|
@ -40,13 +41,14 @@ class NimBLEAdvertisedDeviceCallbacks;
|
|||
*/
|
||||
class NimBLEScanResults {
|
||||
public:
|
||||
void dump();
|
||||
int getCount();
|
||||
void dump();
|
||||
int getCount();
|
||||
NimBLEAdvertisedDevice getDevice(uint32_t i);
|
||||
NimBLEAdvertisedDevice *getDevice(const NimBLEAddress &address);
|
||||
|
||||
private:
|
||||
friend NimBLEScan;
|
||||
std::map<std::string, NimBLEAdvertisedDevice*> m_advertisedDevicesMap;
|
||||
std::vector<NimBLEAdvertisedDevice*> m_advertisedDevicesVector;
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
Loading…
Reference in a new issue