From e98bcda23c8aa574c63816c578618e135d4ac446 Mon Sep 17 00:00:00 2001 From: h2zero Date: Thu, 4 Jul 2024 12:03:03 -0600 Subject: [PATCH] [BREAKING] Use an array to manage created client instances. * Replaces the use of std::list with a fixed array to track and manage created client instances. * Removes: NimBLEDevice::getClientList * Replaces: NimBLEDevice::getClientListSize with NimBLEDevice::getCreatedClientCount --- examples/NimBLE_Client/NimBLE_Client.ino | 4 +- src/NimBLEDevice.cpp | 85 +++++++++++++----------- src/NimBLEDevice.h | 16 ++--- 3 files changed, 55 insertions(+), 50 deletions(-) diff --git a/examples/NimBLE_Client/NimBLE_Client.ino b/examples/NimBLE_Client/NimBLE_Client.ino index 7b6f8712..3d45c960 100644 --- a/examples/NimBLE_Client/NimBLE_Client.ino +++ b/examples/NimBLE_Client/NimBLE_Client.ino @@ -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. @@ -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; } diff --git a/src/NimBLEDevice.cpp b/src/NimBLEDevice.cpp index 9ae964cd..a1cefb4a 100644 --- a/src/NimBLEDevice.cpp +++ b/src/NimBLEDevice.cpp @@ -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 NimBLEDevice::m_cList; +std::array NimBLEDevice::m_pClients{nullptr}; #endif -std::list NimBLEDevice::m_ignoreList; + +gap_event_handler NimBLEDevice::m_customGapHandler = nullptr; +ble_gap_event_listener NimBLEDevice::m_listener; +std::vector NimBLEDevice::m_ignoreList; std::vector NimBLEDevice::m_whiteList; uint8_t NimBLEDevice::m_own_addr_type = BLE_OWN_ADDR_PUBLIC; #ifdef ESP_PLATFORM @@ -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 @@ -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* 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 /** @@ -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; } } @@ -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 @@ -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(); } } diff --git a/src/NimBLEDevice.h b/src/NimBLEDevice.h index 64bd4ed3..7dd8c7b3 100644 --- a/src/NimBLEDevice.h +++ b/src/NimBLEDevice.h @@ -45,9 +45,7 @@ # include "esp_bt.h" #endif -#include #include -#include #define BLEDevice NimBLEDevice #define BLEClient NimBLEClient @@ -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* getClientList(); + static size_t getCreatedClientCount(); #endif #if defined(CONFIG_BT_NIMBLE_ROLE_CENTRAL) || defined(CONFIG_BT_NIMBLE_ROLE_PERIPHERAL) @@ -221,21 +218,22 @@ class NimBLEDevice { # endif #endif -#if defined( CONFIG_BT_NIMBLE_ROLE_CENTRAL) - static std::list m_cList; -#endif - static std::list m_ignoreList; + static std::vector 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 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 m_whiteList; + +#if defined( CONFIG_BT_NIMBLE_ROLE_CENTRAL) + static std::array m_pClients; +#endif };