Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[BREAKING] Use an array to manage created client instances. #698

Merged
merged 1 commit into from
Jul 13, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions examples/NimBLE_Client/NimBLE_Client.ino
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ bool connectToServer() {
NimBLEClient* pClient = nullptr;

/** Check if we have a client we should reuse first **/
if(NimBLEDevice::getClientListSize()) {
if(NimBLEDevice::getCreatedClientCount()) {
/** Special case when we already know this device, we send false as the
* second argument in connect() to prevent refreshing the service database.
* This saves considerable time and power.
Expand All @@ -152,7 +152,7 @@ bool connectToServer() {

/** No client to reuse? Create a new one. */
if(!pClient) {
if(NimBLEDevice::getClientListSize() >= NIMBLE_MAX_CONNECTIONS) {
if(NimBLEDevice::getCreatedClientCount() >= NIMBLE_MAX_CONNECTIONS) {
Serial.println("Max clients reached - no more connections available");
return false;
}
Expand Down
85 changes: 46 additions & 39 deletions src/NimBLEDevice.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -78,12 +78,13 @@ NimBLEAdvertising* NimBLEDevice::m_bleAdvertising = nullptr;
# endif
#endif

gap_event_handler NimBLEDevice::m_customGapHandler = nullptr;
ble_gap_event_listener NimBLEDevice::m_listener;
#if defined( CONFIG_BT_NIMBLE_ROLE_CENTRAL)
std::list <NimBLEClient*> NimBLEDevice::m_cList;
std::array<NimBLEClient*, NIMBLE_MAX_CONNECTIONS> NimBLEDevice::m_pClients{nullptr};
#endif
std::list <NimBLEAddress> NimBLEDevice::m_ignoreList;

gap_event_handler NimBLEDevice::m_customGapHandler = nullptr;
ble_gap_event_listener NimBLEDevice::m_listener;
std::vector <NimBLEAddress> NimBLEDevice::m_ignoreList;
std::vector<NimBLEAddress> NimBLEDevice::m_whiteList;
uint8_t NimBLEDevice::m_own_addr_type = BLE_OWN_ADDR_PUBLIC;
#ifdef ESP_PLATFORM
Expand Down Expand Up @@ -213,18 +214,23 @@ NimBLEScan* NimBLEDevice::getScan() {
* each client can connect to 1 peripheral device.
* @param [in] peerAddress An optional peer address that is copied to the new client
* object, allows for calling NimBLEClient::connect(bool) without a device or address parameter.
* @return A reference to the new client object.
* @return A reference to the new client object, or nullptr on error.
*/
#if defined(CONFIG_BT_NIMBLE_ROLE_CENTRAL)
/* STATIC */
NimBLEClient* NimBLEDevice::createClient(NimBLEAddress peerAddress) {
if(m_cList.size() >= NIMBLE_MAX_CONNECTIONS) {
NIMBLE_LOGW(LOG_TAG,"Number of clients exceeds Max connections. Cur=%d Max=%d",
m_cList.size(), NIMBLE_MAX_CONNECTIONS);
if (getCreatedClientCount() == NIMBLE_MAX_CONNECTIONS) {
NIMBLE_LOGE(LOG_TAG,"Unable to create client; already at max: %d",NIMBLE_MAX_CONNECTIONS);
return nullptr;
}

NimBLEClient* pClient = new NimBLEClient(peerAddress);
m_cList.push_back(pClient);
for (auto& clt : m_pClients) {
if (clt == nullptr) {
clt = pClient;
break;
}
}

return pClient;
} // createClient
Expand Down Expand Up @@ -269,31 +275,32 @@ bool NimBLEDevice::deleteClient(NimBLEClient* pClient) {
}
}

m_cList.remove(pClient);
delete pClient;
for (auto& clt : m_pClients) {
if (clt == pClient) {
delete pClient;
clt = nullptr;
}
}

return true;
} // deleteClient


/**
* @brief Get the list of created client objects.
* @return A pointer to the list of clients.
*/
/* STATIC */
std::list<NimBLEClient*>* NimBLEDevice::getClientList() {
return &m_cList;
} // getClientList


/**
* @brief Get the number of created client objects.
* @return Number of client objects created.
*/
/* STATIC */
size_t NimBLEDevice::getClientListSize() {
return m_cList.size();
} // getClientList
size_t NimBLEDevice::getCreatedClientCount() {
auto count = 0;
for (auto clt : m_pClients) {
if (clt != nullptr) {
count++;
}
}

return count;
} // getCreatedClientCount


/**
Expand All @@ -303,9 +310,9 @@ size_t NimBLEDevice::getClientListSize() {
*/
/* STATIC */
NimBLEClient* NimBLEDevice::getClientByID(uint16_t conn_id) {
for(auto it = m_cList.cbegin(); it != m_cList.cend(); ++it) {
if((*it)->getConnId() == conn_id) {
return (*it);
for(auto clt : m_pClients) {
if(clt != nullptr && clt->getConnId() == conn_id) {
return clt;
}
}

Expand All @@ -316,30 +323,32 @@ NimBLEClient* NimBLEDevice::getClientByID(uint16_t conn_id) {
/**
* @brief Get a reference to a client by peer address.
* @param [in] peer_addr The address of the peer to search for.
* @return A pointer to the client object with the peer address.
* @return A pointer to the client object with the peer address or nullptr.
*/
/* STATIC */
NimBLEClient* NimBLEDevice::getClientByPeerAddress(const NimBLEAddress &peer_addr) {
for(auto it = m_cList.cbegin(); it != m_cList.cend(); ++it) {
if((*it)->getPeerAddress().equals(peer_addr)) {
return (*it);
for(auto clt : m_pClients) {
if(clt != nullptr && clt->getPeerAddress() == peer_addr) {
return clt;
}
}

return nullptr;
} // getClientPeerAddress


/**
* @brief Finds the first disconnected client in the list.
* @return A pointer to the first client object that is not connected to a peer.
* @return A pointer to the first client object that is not connected to a peer or nullptr.
*/
/* STATIC */
NimBLEClient* NimBLEDevice::getDisconnectedClient() {
for(auto it = m_cList.cbegin(); it != m_cList.cend(); ++it) {
if(!(*it)->isConnected()) {
return (*it);
for(auto clt : m_pClients) {
if(clt != nullptr && !clt->isConnected()) {
return clt;
}
}

return nullptr;
} // getDisconnectedClient

Expand Down Expand Up @@ -994,12 +1003,10 @@ void NimBLEDevice::deinit(bool clearAll) {
#endif

#if defined( CONFIG_BT_NIMBLE_ROLE_CENTRAL)
for(auto &it : m_cList) {
deleteClient(it);
m_cList.clear();
for(auto clt : m_pClients) {
deleteClient(clt);
}
#endif

m_ignoreList.clear();
}
}
Expand Down
16 changes: 7 additions & 9 deletions src/NimBLEDevice.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,9 +45,7 @@
# include "esp_bt.h"
#endif

#include <map>
#include <string>
#include <list>

#define BLEDevice NimBLEDevice
#define BLEClient NimBLEClient
Expand Down Expand Up @@ -166,8 +164,7 @@ class NimBLEDevice {
static NimBLEClient* getClientByID(uint16_t conn_id);
static NimBLEClient* getClientByPeerAddress(const NimBLEAddress &peer_addr);
static NimBLEClient* getDisconnectedClient();
static size_t getClientListSize();
static std::list<NimBLEClient*>* getClientList();
static size_t getCreatedClientCount();
#endif

#if defined(CONFIG_BT_NIMBLE_ROLE_CENTRAL) || defined(CONFIG_BT_NIMBLE_ROLE_PERIPHERAL)
Expand Down Expand Up @@ -221,21 +218,22 @@ class NimBLEDevice {
# endif
#endif

#if defined( CONFIG_BT_NIMBLE_ROLE_CENTRAL)
static std::list <NimBLEClient*> m_cList;
#endif
static std::list <NimBLEAddress> m_ignoreList;
static std::vector<NimBLEAddress> m_ignoreList;
static uint32_t m_passkey;
static ble_gap_event_listener m_listener;
static gap_event_handler m_customGapHandler;
static uint8_t m_own_addr_type;
static std::vector<NimBLEAddress> m_whiteList;
#ifdef ESP_PLATFORM
# ifdef CONFIG_BTDM_BLE_SCAN_DUPL
static uint16_t m_scanDuplicateSize;
static uint8_t m_scanFilterMode;
# endif
#endif
static std::vector<NimBLEAddress> m_whiteList;

#if defined( CONFIG_BT_NIMBLE_ROLE_CENTRAL)
static std::array<NimBLEClient*, NIMBLE_MAX_CONNECTIONS> m_pClients;
#endif
};


Expand Down
Loading