From abdf6cda3599e2a8e5e5e9a8900b39d43568dc44 Mon Sep 17 00:00:00 2001 From: h2zero <32826625+h2zero@users.noreply.github.com> Date: Tue, 28 Jul 2020 20:57:33 -0600 Subject: [PATCH] Add clearAll parameter to deinit() (#22) * Add clearAll parameter to deinit() Adds the ability to clear all resources consumed during BLE operation when deinitializing and shutting down BLE. Useful when BLE is used intermittently or in a task that initializes, performs operations then deinitializes. By setting the clearAll parameter to true all created BLE objects will be deleted, freeing the memory for other tasks. Warning: This will invalidate any pointers that may be referencing the deleted objects. * Add bool deleteCallbacks parameter to NimBLEServer::setCallbacks, if true (default) will delete the callback class when server is destructed. * Delete scan results when scan is destructed. --- src/NimBLEDevice.cpp | 40 +++++++++++++++++++++++++++++++++++++++- src/NimBLEDevice.h | 2 +- src/NimBLEScan.cpp | 7 +++++++ src/NimBLEScan.h | 4 +++- src/NimBLEServer.cpp | 9 ++++++++- src/NimBLEServer.h | 4 +++- 6 files changed, 61 insertions(+), 5 deletions(-) diff --git a/src/NimBLEDevice.cpp b/src/NimBLEDevice.cpp index a2dc882..68d4ec0 100644 --- a/src/NimBLEDevice.cpp +++ b/src/NimBLEDevice.cpp @@ -539,8 +539,10 @@ void NimBLEDevice::stopAdvertising() { /** * @brief Shutdown the NimBLE stack/controller. + * @param [in] clearAll If true, deletes all server/advertising/scan/client objects after deinitializing. + * @note If clearAll is true when called, any references to the created objects become invalid. */ -/* STATIC */ void NimBLEDevice::deinit() { +/* STATIC */ void NimBLEDevice::deinit(bool clearAll) { int ret = nimble_port_stop(); if (ret == 0) { nimble_port_deinit(); @@ -552,6 +554,42 @@ void NimBLEDevice::stopAdvertising() { initialized = false; m_synced = false; + + if(clearAll) { +#if defined(CONFIG_BT_NIMBLE_ROLE_PERIPHERAL) + if(NimBLEDevice::m_pServer != nullptr) { + delete NimBLEDevice::m_pServer; + NimBLEDevice::m_pServer = nullptr; + } +#endif + +#if defined(CONFIG_BT_NIMBLE_ROLE_BROADCASTER) + if(NimBLEDevice::m_bleAdvertising != nullptr) { + delete NimBLEDevice::m_bleAdvertising; + NimBLEDevice::m_bleAdvertising = nullptr; + } +#endif + +#if defined(CONFIG_BT_NIMBLE_ROLE_OBSERVER) + if(NimBLEDevice::m_pScan != nullptr) { + delete NimBLEDevice::m_pScan; + NimBLEDevice::m_pScan= nullptr; + } +#endif + +#if defined( CONFIG_BT_NIMBLE_ROLE_CENTRAL) + for(auto &it : m_cList) { + deleteClient(it); + m_cList.clear(); + } +#endif + + m_ignoreList.clear(); + + if(m_securityCallbacks != nullptr) { + delete m_securityCallbacks; + } + } } } // deinit diff --git a/src/NimBLEDevice.h b/src/NimBLEDevice.h index 767f825..36fd2de 100644 --- a/src/NimBLEDevice.h +++ b/src/NimBLEDevice.h @@ -91,7 +91,7 @@ extern "C" void ble_store_config_init(void); class NimBLEDevice { public: static void init(const std::string &deviceName); - static void deinit(); + static void deinit(bool clearAll = false); static bool getInitialized(); static NimBLEAddress getAddress(); static std::string toString(); diff --git a/src/NimBLEScan.cpp b/src/NimBLEScan.cpp index 62bb3fc..c3cdefc 100644 --- a/src/NimBLEScan.cpp +++ b/src/NimBLEScan.cpp @@ -44,6 +44,13 @@ NimBLEScan::NimBLEScan() { } +/** + * @brief Scan destructor, release any allocated resources. + */ +NimBLEScan::~NimBLEScan() { + clearResults(); +} + /** * @brief Handle GAP events related to scans. * @param [in] event The event type for this event. diff --git a/src/NimBLEScan.h b/src/NimBLEScan.h index 75a301e..8226290 100644 --- a/src/NimBLEScan.h +++ b/src/NimBLEScan.h @@ -77,8 +77,10 @@ public: private: - NimBLEScan(); friend class NimBLEDevice; + + NimBLEScan(); + ~NimBLEScan(); static int handleGapEvent(ble_gap_event* event, void* arg); void onHostReset(); diff --git a/src/NimBLEServer.cpp b/src/NimBLEServer.cpp index decc630..a39fdd6 100644 --- a/src/NimBLEServer.cpp +++ b/src/NimBLEServer.cpp @@ -42,6 +42,7 @@ NimBLEServer::NimBLEServer() { m_gattsStarted = false; m_advertiseOnDisconnect = true; m_svcChanged = false; + m_deleteCallbacks = true; } // NimBLEServer @@ -52,6 +53,10 @@ NimBLEServer::~NimBLEServer() { for(auto &it : m_svcVec) { delete it; } + + if(m_deleteCallbacks && m_pServerCallbacks != &defaultCallbacks) { + delete m_pServerCallbacks; + } } @@ -465,10 +470,12 @@ size_t NimBLEServer::getConnectedCount() { * events are detected. * * @param [in] pCallbacks The callbacks to be invoked. + * @param [in] deleteCallbacks if true callback class will be deleted when server is destructed. */ -void NimBLEServer::setCallbacks(NimBLEServerCallbacks* pCallbacks) { +void NimBLEServer::setCallbacks(NimBLEServerCallbacks* pCallbacks, bool deleteCallbacks) { if (pCallbacks != nullptr){ m_pServerCallbacks = pCallbacks; + m_deleteCallbacks = deleteCallbacks; } else { m_pServerCallbacks = &defaultCallbacks; } diff --git a/src/NimBLEServer.h b/src/NimBLEServer.h index 351a6fc..1fa24b2 100644 --- a/src/NimBLEServer.h +++ b/src/NimBLEServer.h @@ -44,7 +44,8 @@ public: void removeService(NimBLEService* service, bool deleteSvc = false); void addService(NimBLEService* service); NimBLEAdvertising* getAdvertising(); - void setCallbacks(NimBLEServerCallbacks* pCallbacks); + void setCallbacks(NimBLEServerCallbacks* pCallbacks, + bool deleteCallbacks = true); void startAdvertising(); void stopAdvertising(); void start(); @@ -70,6 +71,7 @@ private: bool m_advertiseOnDisconnect; bool m_svcChanged; NimBLEServerCallbacks* m_pServerCallbacks; + bool m_deleteCallbacks; std::vector m_connectedPeersVec; // uint16_t m_svcChgChrHdl; // Future use