From 86b800888937768d1e74f719003c382c6e759399 Mon Sep 17 00:00:00 2001 From: h2zero Date: Fri, 10 Apr 2026 15:57:26 -0600 Subject: [PATCH] [Breaking] Rename callback setters to setCallbacks, taking a reference only --- examples/ANCS/ANCS.ino | 2 +- .../BLE_Beacon_Scanner/BLE_Beacon_Scanner.ino | 2 +- .../NimBLE_extended_client.ino | 4 +- .../NimBLE_extended_scan.ino | 2 +- .../NimBLE_extended_server.ino | 4 +- .../NimBLE_multi_advertiser.ino | 4 +- examples/L2CAP/L2CAP_Client/L2CAP_Client.ino | 4 +- examples/L2CAP/L2CAP_Server/L2CAP_Server.ino | 2 +- .../NimBLE_Async_Client.ino | 4 +- examples/NimBLE_Client/NimBLE_Client.ino | 4 +- .../NimBLE_Scan_Continuous.ino | 2 +- .../NimBLE_Scan_whitelist.ino | 2 +- .../NimBLE_Secure_Client.ino | 2 +- examples/NimBLE_Server/NimBLE_Server.ino | 10 ++-- .../NimBLE_Server_Whitelist.ino | 2 +- .../NimBLE_Stream_Client.ino | 4 +- .../NimBLE_Stream_Server.ino | 2 +- .../NimBLE_active_passive_scan.ino | 2 +- src/NimBLECharacteristic.cpp | 21 ++++--- src/NimBLECharacteristic.h | 3 +- src/NimBLEClient.cpp | 55 +++++++++---------- src/NimBLEClient.h | 14 ++--- src/NimBLEDescriptor.cpp | 17 +++--- src/NimBLEDescriptor.h | 3 +- src/NimBLEDevice.cpp | 21 +++++-- src/NimBLEDevice.h | 5 +- src/NimBLEExtAdvertising.cpp | 31 +++++------ src/NimBLEExtAdvertising.h | 4 +- src/NimBLEScan.cpp | 42 ++++++++------ src/NimBLEScan.h | 20 ++++--- src/NimBLEServer.cpp | 55 ++++++++----------- src/NimBLEServer.h | 6 +- src/NimBLEStream.cpp | 4 +- src/NimBLEStream.h | 2 +- 34 files changed, 186 insertions(+), 175 deletions(-) diff --git a/examples/ANCS/ANCS.ino b/examples/ANCS/ANCS.ino index 8df3b067a..64690fc72 100644 --- a/examples/ANCS/ANCS.ino +++ b/examples/ANCS/ANCS.ino @@ -120,7 +120,7 @@ void setup() { NimBLEDevice::setPower(9); NimBLEServer* pServer = NimBLEDevice::createServer(); - pServer->setCallbacks(&serverCallbacks); + pServer->setCallbacks(serverCallbacks); pServer->advertiseOnDisconnect(true); NimBLEAdvertising* pAdvertising = pServer->getAdvertising(); diff --git a/examples/BLE_Beacon_Scanner/BLE_Beacon_Scanner.ino b/examples/BLE_Beacon_Scanner/BLE_Beacon_Scanner.ino index 1aab09db6..7bce12a55 100644 --- a/examples/BLE_Beacon_Scanner/BLE_Beacon_Scanner.ino +++ b/examples/BLE_Beacon_Scanner/BLE_Beacon_Scanner.ino @@ -81,7 +81,7 @@ void setup() { NimBLEDevice::init("Beacon-scanner"); pBLEScan = BLEDevice::getScan(); - pBLEScan->setScanCallbacks(&scanCallbacks); + pBLEScan->setCallbacks(scanCallbacks); pBLEScan->setActiveScan(true); pBLEScan->setInterval(100); pBLEScan->setWindow(100); diff --git a/examples/Bluetooth_5/NimBLE_extended_client/NimBLE_extended_client.ino b/examples/Bluetooth_5/NimBLE_extended_client/NimBLE_extended_client.ino index 93c9ce53b..d4ced5e51 100644 --- a/examples/Bluetooth_5/NimBLE_extended_client/NimBLE_extended_client.ino +++ b/examples/Bluetooth_5/NimBLE_extended_client/NimBLE_extended_client.ino @@ -57,7 +57,7 @@ bool connectToServer() { NimBLEClient* pClient = nullptr; pClient = NimBLEDevice::createClient(); - pClient->setClientCallbacks(&clientCallbacks, false); + pClient->setCallbacks(clientCallbacks); /** * Set the PHY's to use for this connection. This is a bitmask that represents the PHY's: @@ -112,7 +112,7 @@ void setup() { /** Create aNimBLE Scan instance and set the callbacks for scan events */ NimBLEScan* pScan = NimBLEDevice::getScan(); - pScan->setScanCallbacks(&scanCallbacks); + pScan->setCallbacks(scanCallbacks); /** Set scan interval (how often) and window (how long) in milliseconds */ pScan->setInterval(97); diff --git a/examples/Bluetooth_5/NimBLE_extended_scan/NimBLE_extended_scan.ino b/examples/Bluetooth_5/NimBLE_extended_scan/NimBLE_extended_scan.ino index a9947b99e..7c22401a7 100644 --- a/examples/Bluetooth_5/NimBLE_extended_scan/NimBLE_extended_scan.ino +++ b/examples/Bluetooth_5/NimBLE_extended_scan/NimBLE_extended_scan.ino @@ -60,7 +60,7 @@ void setup() { NimBLEScan* pScan = NimBLEDevice::getScan(); /** Set the callbacks that the scanner will call on events. */ - pScan->setScanCallbacks(&scanCallbacks); + pScan->setCallbacks(scanCallbacks); /** Use active scanning to obtain scan response data from advertisers */ pScan->setActiveScan(true); diff --git a/examples/Bluetooth_5/NimBLE_extended_server/NimBLE_extended_server.ino b/examples/Bluetooth_5/NimBLE_extended_server/NimBLE_extended_server.ino index d54ada12a..6197b2dfa 100644 --- a/examples/Bluetooth_5/NimBLE_extended_server/NimBLE_extended_server.ino +++ b/examples/Bluetooth_5/NimBLE_extended_server/NimBLE_extended_server.ino @@ -89,7 +89,7 @@ void setup() { /** Create the server and add the services/characteristics/descriptors */ NimBLEServer* pServer = NimBLEDevice::createServer(); - pServer->setCallbacks(&serverCallbacks); + pServer->setCallbacks(serverCallbacks); NimBLEService* pService = pServer->createService(SERVICE_UUID); NimBLECharacteristic* pCharacteristic = @@ -125,7 +125,7 @@ void setup() { NimBLEExtAdvertising* pAdvertising = NimBLEDevice::getAdvertising(); /** Set the callbacks for advertising events */ - pAdvertising->setCallbacks(&advertisingCallbacks); + pAdvertising->setCallbacks(advertisingCallbacks); /** * NimBLEExtAdvertising::setInstanceData takes the instance ID and diff --git a/examples/Bluetooth_5/NimBLE_multi_advertiser/NimBLE_multi_advertiser.ino b/examples/Bluetooth_5/NimBLE_multi_advertiser/NimBLE_multi_advertiser.ino index dfade4088..cdf988911 100644 --- a/examples/Bluetooth_5/NimBLE_multi_advertiser/NimBLE_multi_advertiser.ino +++ b/examples/Bluetooth_5/NimBLE_multi_advertiser/NimBLE_multi_advertiser.ino @@ -107,7 +107,7 @@ void setup() { /** Create a server for our legacy advertiser */ NimBLEServer* pServer = NimBLEDevice::createServer(); - pServer->setCallbacks(&serverCallbacks); + pServer->setCallbacks(serverCallbacks); NimBLEService* pService = pServer->createService(SERVICE_UUID); NimBLECharacteristic* pCharacteristic = @@ -155,7 +155,7 @@ void setup() { NimBLEExtAdvertising* pAdvertising = NimBLEDevice::getAdvertising(); /** Set the callbacks to handle advertising events */ - pAdvertising->setCallbacks(&advCallbacks); + pAdvertising->setCallbacks(advCallbacks); /** * Set instance data. diff --git a/examples/L2CAP/L2CAP_Client/L2CAP_Client.ino b/examples/L2CAP/L2CAP_Client/L2CAP_Client.ino index 46444cdce..502f643ee 100644 --- a/examples/L2CAP/L2CAP_Client/L2CAP_Client.ino +++ b/examples/L2CAP/L2CAP_Client/L2CAP_Client.ino @@ -86,7 +86,7 @@ void setup() { NimBLEDevice::setMTU(BLE_ATT_MTU_MAX); auto scan = NimBLEDevice::getScan(); - scan->setScanCallbacks(&scanCallbacks); + scan->setCallbacks(scanCallbacks); scan->setInterval(1349); scan->setWindow(449); scan->setActiveScan(true); @@ -106,7 +106,7 @@ void loop() { if (!theClient) { theClient = NimBLEDevice::createClient(); theClient->setConnectionParams(6, 6, 0, 42); - theClient->setClientCallbacks(&clientCallbacks); + theClient->setCallbacks(clientCallbacks); if (!theClient->connect(theDevice)) { Serial.println("Error: Could not connect to device"); return; diff --git a/examples/L2CAP/L2CAP_Server/L2CAP_Server.ino b/examples/L2CAP/L2CAP_Server/L2CAP_Server.ino index 94f1a4a0b..633fdbe6b 100644 --- a/examples/L2CAP/L2CAP_Server/L2CAP_Server.ino +++ b/examples/L2CAP/L2CAP_Server/L2CAP_Server.ino @@ -65,7 +65,7 @@ void setup() { auto channel = cocServer->createService(L2CAP_CHANNEL, L2CAP_MTU, &l2capCallbacks); auto server = NimBLEDevice::createServer(); - server->setCallbacks(&gattCallbacks); + server->setCallbacks(gattCallbacks); auto service = server->createService(SERVICE_UUID); auto characteristic = service->createCharacteristic(CHARACTERISTIC_UUID, NIMBLE_PROPERTY::READ); diff --git a/examples/NimBLE_Async_Client/NimBLE_Async_Client.ino b/examples/NimBLE_Async_Client/NimBLE_Async_Client.ino index dce3ad671..fa1ba9056 100644 --- a/examples/NimBLE_Async_Client/NimBLE_Async_Client.ino +++ b/examples/NimBLE_Async_Client/NimBLE_Async_Client.ino @@ -40,7 +40,7 @@ class ScanCallbacks : public NimBLEScanCallbacks { } } - pClient->setClientCallbacks(&clientCallbacks, false); + pClient->setCallbacks(clientCallbacks); if (!pClient->connect(true, true, false)) { // delete attributes, async connect, no MTU exchange NimBLEDevice::deleteClient(pClient); Serial.printf("Failed to connect\n"); @@ -62,7 +62,7 @@ void setup() { NimBLEDevice::setPower(3); /** +3db */ NimBLEScan* pScan = NimBLEDevice::getScan(); - pScan->setScanCallbacks(&scanCallbacks); + pScan->setCallbacks(scanCallbacks); pScan->setInterval(45); pScan->setWindow(45); pScan->setActiveScan(true); diff --git a/examples/NimBLE_Client/NimBLE_Client.ino b/examples/NimBLE_Client/NimBLE_Client.ino index 13b466ad4..3438eda95 100644 --- a/examples/NimBLE_Client/NimBLE_Client.ino +++ b/examples/NimBLE_Client/NimBLE_Client.ino @@ -122,7 +122,7 @@ bool connectToServer() { Serial.printf("New client created\n"); - pClient->setClientCallbacks(&clientCallbacks, false); + pClient->setCallbacks(clientCallbacks); /** * Set initial connection parameters: * These settings are safe for 3 clients to connect reliably, can go faster if you have less @@ -273,7 +273,7 @@ void setup() { NimBLEScan* pScan = NimBLEDevice::getScan(); /** Set the callbacks to call when scan events occur, no duplicates */ - pScan->setScanCallbacks(&scanCallbacks, false); + pScan->setCallbacks(scanCallbacks, false); /** Set scan interval (how often) and window (how long) in milliseconds */ pScan->setInterval(100); diff --git a/examples/NimBLE_Scan_Continuous/NimBLE_Scan_Continuous.ino b/examples/NimBLE_Scan_Continuous/NimBLE_Scan_Continuous.ino index eb156d7f4..67539f6bc 100644 --- a/examples/NimBLE_Scan_Continuous/NimBLE_Scan_Continuous.ino +++ b/examples/NimBLE_Scan_Continuous/NimBLE_Scan_Continuous.ino @@ -39,7 +39,7 @@ class scanCallbacks : public NimBLEScanCallbacks { void setup() { NimBLEDevice::init(""); // Initialize the device, you can specify a device name if you want. NimBLEScan* pBLEScan = NimBLEDevice::getScan(); // Create the scan object. - pBLEScan->setScanCallbacks(&scanCallbacks, false); // Set the callback for when devices are discovered, no duplicates. + pBLEScan->setCallbacks(scanCallbacks, false); // Set the callback for when devices are discovered, no duplicates. pBLEScan->setActiveScan(true); // Set active scanning, this will get more data from the advertiser. pBLEScan->setMaxResults(0); // Do not store the scan results, use callback only. pBLEScan->start(scanTimeMs, false, true); // duration, not a continuation of last scan, restart to get all devices again. diff --git a/examples/NimBLE_Scan_Whitelist/NimBLE_Scan_whitelist.ino b/examples/NimBLE_Scan_Whitelist/NimBLE_Scan_whitelist.ino index 65c2e33f0..eb8827c54 100644 --- a/examples/NimBLE_Scan_Whitelist/NimBLE_Scan_whitelist.ino +++ b/examples/NimBLE_Scan_Whitelist/NimBLE_Scan_whitelist.ino @@ -34,7 +34,7 @@ void setup() { NimBLEDevice::init(""); pBLEScan = NimBLEDevice::getScan(); - pBLEScan->setScanCallbacks(&scanCallbacks); + pBLEScan->setCallbacks(scanCallbacks); pBLEScan->setActiveScan(true); pBLEScan->setInterval(100); pBLEScan->setFilterPolicy(BLE_HCI_SCAN_FILT_NO_WL); diff --git a/examples/NimBLE_Secure_Client/NimBLE_Secure_Client.ino b/examples/NimBLE_Secure_Client/NimBLE_Secure_Client.ino index 9d4da9570..aa504eae8 100644 --- a/examples/NimBLE_Secure_Client/NimBLE_Secure_Client.ino +++ b/examples/NimBLE_Secure_Client/NimBLE_Secure_Client.ino @@ -43,7 +43,7 @@ void setup() { if (device->isAdvertisingService(serviceUuid)) { NimBLEClient* pClient = NimBLEDevice::createClient(); - pClient->setClientCallbacks(&clientCallbacks, false); + pClient->setCallbacks(clientCallbacks); if (pClient->connect(&device)) { pClient->secureConnection(); diff --git a/examples/NimBLE_Server/NimBLE_Server.ino b/examples/NimBLE_Server/NimBLE_Server.ino index b945f5821..1acc4ea3e 100644 --- a/examples/NimBLE_Server/NimBLE_Server.ino +++ b/examples/NimBLE_Server/NimBLE_Server.ino @@ -147,7 +147,7 @@ void setup(void) { // NimBLEDevice::setSecurityAuth(BLE_SM_PAIR_AUTHREQ_BOND | BLE_SM_PAIR_AUTHREQ_MITM | BLE_SM_PAIR_AUTHREQ_SC); pServer = NimBLEDevice::createServer(); - pServer->setCallbacks(&serverCallbacks); + pServer->setCallbacks(serverCallbacks); NimBLEService* pDeadService = pServer->createService("DEAD"); NimBLECharacteristic* pBeefCharacteristic = @@ -159,7 +159,7 @@ void setup(void) { ); pBeefCharacteristic->setValue("Burger"); - pBeefCharacteristic->setCallbacks(&chrCallbacks); + pBeefCharacteristic->setCallbacks(chrCallbacks); /** * 2902 and 2904 descriptors are a special case, when createDescriptor is called with @@ -169,14 +169,14 @@ void setup(void) { */ NimBLE2904* pBeef2904 = pBeefCharacteristic->create2904(); pBeef2904->setFormat(NimBLE2904::FORMAT_UTF8); - pBeef2904->setCallbacks(&dscCallbacks); + pBeef2904->setCallbacks(dscCallbacks); NimBLEService* pBaadService = pServer->createService("BAAD"); NimBLECharacteristic* pFoodCharacteristic = pBaadService->createCharacteristic("F00D", NIMBLE_PROPERTY::READ | NIMBLE_PROPERTY::WRITE | NIMBLE_PROPERTY::NOTIFY); pFoodCharacteristic->setValue("Fries"); - pFoodCharacteristic->setCallbacks(&chrCallbacks); + pFoodCharacteristic->setCallbacks(chrCallbacks); /** Custom descriptor: Arguments are UUID, Properties, max length of the value in bytes */ NimBLEDescriptor* pC01Ddsc = @@ -184,7 +184,7 @@ void setup(void) { NIMBLE_PROPERTY::READ | NIMBLE_PROPERTY::WRITE | NIMBLE_PROPERTY::WRITE_ENC, 20); pC01Ddsc->setValue("Send it back!"); - pC01Ddsc->setCallbacks(&dscCallbacks); + pC01Ddsc->setCallbacks(dscCallbacks); /** Create an advertising instance and add the services to the advertised data */ NimBLEAdvertising* pAdvertising = NimBLEDevice::getAdvertising(); diff --git a/examples/NimBLE_Server_Whitelist/NimBLE_Server_Whitelist.ino b/examples/NimBLE_Server_Whitelist/NimBLE_Server_Whitelist.ino index 620a6271f..88fb8c1a5 100644 --- a/examples/NimBLE_Server_Whitelist/NimBLE_Server_Whitelist.ino +++ b/examples/NimBLE_Server_Whitelist/NimBLE_Server_Whitelist.ino @@ -47,7 +47,7 @@ void setup() { NimBLEDevice::init("Whitelist NimBLEServer"); NimBLEServer* pServer = NimBLEDevice::createServer(); - pServer->setCallbacks(&serverCallbacks); + pServer->setCallbacks(serverCallbacks); pServer->advertiseOnDisconnect(false); NimBLEService* pService = pServer->createService(SERVICE_UUID); diff --git a/examples/NimBLE_Stream_Client/NimBLE_Stream_Client.ino b/examples/NimBLE_Stream_Client/NimBLE_Stream_Client.ino index 1ae4c30a7..fbb0e78bb 100644 --- a/examples/NimBLE_Stream_Client/NimBLE_Stream_Client.ino +++ b/examples/NimBLE_Stream_Client/NimBLE_Stream_Client.ino @@ -103,7 +103,7 @@ bool connectToServer() { Serial.println("Failed to create client"); return false; } - pClient->setClientCallbacks(&clientCallbacks, false); + pClient->setCallbacks(clientCallbacks); pClient->setConnectionParams(12, 24, 0, 200); pClient->setConnectTimeout(5000); } @@ -162,7 +162,7 @@ void setup() { * Configure scan parameters */ NimBLEScan* pScan = NimBLEDevice::getScan(); - pScan->setScanCallbacks(&scanCallbacks, false); + pScan->setCallbacks(scanCallbacks, false); pScan->setActiveScan(true); /** Start scanning for the server */ diff --git a/examples/NimBLE_Stream_Server/NimBLE_Stream_Server.ino b/examples/NimBLE_Stream_Server/NimBLE_Stream_Server.ino index 960402053..62bec92d9 100644 --- a/examples/NimBLE_Stream_Server/NimBLE_Stream_Server.ino +++ b/examples/NimBLE_Stream_Server/NimBLE_Stream_Server.ino @@ -71,7 +71,7 @@ void setup() { * Note: The stream will create its own service and characteristic */ NimBLEServer* pServer = NimBLEDevice::createServer(); - pServer->setCallbacks(&serverCallbacks); + pServer->setCallbacks(serverCallbacks); /** * Initialize the stream server with: diff --git a/examples/NimBLE_active_passive_scan/NimBLE_active_passive_scan.ino b/examples/NimBLE_active_passive_scan/NimBLE_active_passive_scan.ino index 38a6daa2f..bd46a96d0 100644 --- a/examples/NimBLE_active_passive_scan/NimBLE_active_passive_scan.ino +++ b/examples/NimBLE_active_passive_scan/NimBLE_active_passive_scan.ino @@ -37,7 +37,7 @@ void setup() { NimBLEDevice::init("active-passive-scan"); pBLEScan = NimBLEDevice::getScan(); - pBLEScan->setScanCallbacks(&scanCallbacks); + pBLEScan->setCallbacks(scanCallbacks); pBLEScan->setActiveScan(active); pBLEScan->setInterval(100); pBLEScan->setWindow(100); diff --git a/src/NimBLECharacteristic.cpp b/src/NimBLECharacteristic.cpp index 343d40713..d4cf3b751 100644 --- a/src/NimBLECharacteristic.cpp +++ b/src/NimBLECharacteristic.cpp @@ -438,18 +438,21 @@ void NimBLECharacteristic::writeEvent(const uint8_t* val, uint16_t len, NimBLECo } // writeEvent /** - * @brief Set the callback handlers for this characteristic. - * @param [in] pCallbacks An instance of a NimBLECharacteristicCallbacks class\n - * used to define any callbacks for the characteristic. + * @brief Set the callbacks for this characteristic. + * @param [in] callbacks Callback handler instance. + * @details The callback handler must outlive this characteristic or until resetCallbacks() is called. */ -void NimBLECharacteristic::setCallbacks(NimBLECharacteristicCallbacks* pCallbacks) { - if (pCallbacks != nullptr) { - m_pCallbacks = pCallbacks; - } else { - m_pCallbacks = &defaultCallback; - } +void NimBLECharacteristic::setCallbacks(NimBLECharacteristicCallbacks& callbacks) { + m_pCallbacks = &callbacks; } // setCallbacks +/** + * @brief Restore default callback handlers. + */ +void NimBLECharacteristic::resetCallbacks() { + m_pCallbacks = &defaultCallback; +} // resetCallbacks + /** * @brief Get the callback handlers for this characteristic. */ diff --git a/src/NimBLECharacteristic.h b/src/NimBLECharacteristic.h index e3c70b63f..b7ef5258c 100644 --- a/src/NimBLECharacteristic.h +++ b/src/NimBLECharacteristic.h @@ -56,7 +56,8 @@ class NimBLECharacteristic : public NimBLELocalValueAttribute { void addDescriptor(NimBLEDescriptor* pDescriptor); void removeDescriptor(NimBLEDescriptor* pDescriptor, bool deleteDsc = false); uint16_t getProperties() const; - void setCallbacks(NimBLECharacteristicCallbacks* pCallbacks); + void setCallbacks(NimBLECharacteristicCallbacks& callbacks); + void resetCallbacks(); bool indicate(uint16_t connHandle = BLE_HS_CONN_HANDLE_NONE) const; bool indicate(const uint8_t* value, size_t length, uint16_t connHandle = BLE_HS_CONN_HANDLE_NONE) const; bool notify(uint16_t connHandle = BLE_HS_CONN_HANDLE_NONE) const; diff --git a/src/NimBLEClient.cpp b/src/NimBLEClient.cpp index f17d0489c..0674a5a12 100644 --- a/src/NimBLEClient.cpp +++ b/src/NimBLEClient.cpp @@ -69,7 +69,7 @@ NimBLEClient::NimBLEClient(const NimBLEAddress& peerAddress) m_connectTimeout{30000}, m_pTaskData{nullptr}, m_svcVec{}, - m_pClientCallbacks{&defaultCallbacks}, + m_pCallbacks{&defaultCallbacks}, m_connHandle{BLE_HS_CONN_HANDLE_NONE}, m_terminateFailCount{0}, m_asyncSecureAttempt{0}, @@ -104,10 +104,6 @@ NimBLEClient::~NimBLEClient() { // We may have allocated service references associated with this client. // Before we are finished with the client, we must release resources. deleteServices(); - - if (m_config.deleteCallbacks) { - delete m_pClientCallbacks; - } } // ~NimBLEClient /** @@ -977,7 +973,7 @@ bool NimBLEClient::completeConnectEstablished() { ble_npl_callout_stop(&m_connectEstablishedTimer); auto pTaskData = m_pTaskData; // save a copy in case something in the callback changes it m_pTaskData = nullptr; // clear before callback to prevent other handlers from releasing - m_pClientCallbacks->onConnect(this); + m_pCallbacks->onConnect(this); if (pTaskData != nullptr) { NimBLEUtils::taskRelease(*pTaskData, 0); @@ -1079,9 +1075,9 @@ int NimBLEClient::handleGapEvent(struct ble_gap_event* event, void* arg) { } if (rc == connEstablishFailReason) { - pClient->m_pClientCallbacks->onConnectFail(pClient, rc); + pClient->m_pCallbacks->onConnectFail(pClient, rc); } else { - pClient->m_pClientCallbacks->onDisconnect(pClient, rc); + pClient->m_pCallbacks->onDisconnect(pClient, rc); } pClient->m_connHandle = BLE_HS_CONN_HANDLE_NONE; @@ -1138,7 +1134,7 @@ int NimBLEClient::handleGapEvent(struct ble_gap_event* event, void* arg) { ble_npl_callout_stop(&pClient->m_connectEstablishedTimer); if (pClient->m_config.asyncConnect) { - pClient->m_pClientCallbacks->onConnectFail(pClient, rc); + pClient->m_pCallbacks->onConnectFail(pClient, rc); if (pClient->m_config.deleteOnConnectFail) { NimBLEDevice::deleteClient(pClient); } @@ -1230,7 +1226,7 @@ int NimBLEClient::handleGapEvent(struct ble_gap_event* event, void* arg) { event->conn_update_req.peer_params->latency, event->conn_update_req.peer_params->supervision_timeout); - rc = pClient->m_pClientCallbacks->onConnParamsUpdateRequest(pClient, event->conn_update_req.peer_params) + rc = pClient->m_pCallbacks->onConnParamsUpdateRequest(pClient, event->conn_update_req.peer_params) ? 0 : BLE_ERR_CONN_PARMS; @@ -1288,7 +1284,7 @@ int NimBLEClient::handleGapEvent(struct ble_gap_event* event, void* arg) { } } else { pClient->m_asyncSecureAttempt = 0; - pClient->m_pClientCallbacks->onAuthenticationComplete(peerInfo); + pClient->m_pCallbacks->onAuthenticationComplete(peerInfo); } } @@ -1312,7 +1308,7 @@ int NimBLEClient::handleGapEvent(struct ble_gap_event* event, void* arg) { break; } - pClient->m_pClientCallbacks->onIdentity(peerInfo); + pClient->m_pCallbacks->onIdentity(peerInfo); break; } // BLE_GAP_EVENT_IDENTITY_RESOLVED @@ -1331,7 +1327,7 @@ int NimBLEClient::handleGapEvent(struct ble_gap_event* event, void* arg) { return BLE_ATT_ERR_INVALID_HANDLE; } - pClient->m_pClientCallbacks->onPhyUpdate(pClient, event->phy_updated.tx_phy, event->phy_updated.rx_phy); + pClient->m_pCallbacks->onPhyUpdate(pClient, event->phy_updated.tx_phy, event->phy_updated.rx_phy); return 0; } // BLE_GAP_EVENT_PHY_UPDATE_COMPLETE @@ -1345,7 +1341,7 @@ int NimBLEClient::handleGapEvent(struct ble_gap_event* event, void* arg) { } NIMBLE_LOGI(LOG_TAG, "mtu update: mtu=%d", event->mtu.value); - pClient->m_pClientCallbacks->onMTUChange(pClient, event->mtu.value); + pClient->m_pCallbacks->onMTUChange(pClient, event->mtu.value); rc = 0; break; } // BLE_GAP_EVENT_MTU @@ -1371,13 +1367,13 @@ int NimBLEClient::handleGapEvent(struct ble_gap_event* event, void* arg) { pkey.action = event->passkey.params.action; pkey.passkey = NimBLEDevice::getSecurityPasskey(); if (pkey.passkey == 123456) { - pkey.passkey = pClient->m_pClientCallbacks->onPassKeyDisplay(peerInfo); + pkey.passkey = pClient->m_pCallbacks->onPassKeyDisplay(peerInfo); } rc = ble_sm_inject_io(event->passkey.conn_handle, &pkey); NIMBLE_LOGD(LOG_TAG, "BLE_SM_IOACT_DISP; ble_sm_inject_io result: %d", rc); } else if (event->passkey.params.action == BLE_SM_IOACT_NUMCMP) { NIMBLE_LOGD(LOG_TAG, "Passkey on device's display: %" PRIu32, event->passkey.params.numcmp); - pClient->m_pClientCallbacks->onConfirmPasskey(peerInfo, event->passkey.params.numcmp); + pClient->m_pCallbacks->onConfirmPasskey(peerInfo, event->passkey.params.numcmp); } else if (event->passkey.params.action == BLE_SM_IOACT_OOB) { NIMBLE_LOGD(LOG_TAG, "OOB request received"); // TODO: Handle out of band pairing @@ -1388,7 +1384,7 @@ int NimBLEClient::handleGapEvent(struct ble_gap_event* event, void* arg) { // NIMBLE_LOGD(LOG_TAG, "ble_sm_inject_io result: %d", rc); } else if (event->passkey.params.action == BLE_SM_IOACT_INPUT) { NIMBLE_LOGD(LOG_TAG, "Enter the passkey"); - pClient->m_pClientCallbacks->onPassKeyEntry(peerInfo); + pClient->m_pCallbacks->onPassKeyEntry(peerInfo); } else if (event->passkey.params.action == BLE_SM_IOACT_NONE) { NIMBLE_LOGD(LOG_TAG, "No passkey action required"); } @@ -1418,19 +1414,20 @@ bool NimBLEClient::isConnected() const { } // isConnected /** - * @brief Set the callbacks that will be invoked when events are received. - * @param [in] pClientCallbacks A pointer to a class to receive the event callbacks. - * @param [in] deleteCallbacks If true this will delete the callback class sent when the client is destructed. + * @brief Set the callbacks for client events. + * @param [in] callbacks Callback handler instance. + * @details The callback handler must outlive this client or until resetCallbacks() is called. */ -void NimBLEClient::setClientCallbacks(NimBLEClientCallbacks* pClientCallbacks, bool deleteCallbacks) { - if (pClientCallbacks != nullptr) { - m_pClientCallbacks = pClientCallbacks; - m_config.deleteCallbacks = deleteCallbacks; - } else { - m_pClientCallbacks = &defaultCallbacks; - m_config.deleteCallbacks = false; - } -} // setClientCallbacks +void NimBLEClient::setCallbacks(NimBLEClientCallbacks& callbacks) { + m_pCallbacks = &callbacks; +} // setCallbacks + +/** + * @brief Restore default callback handlers. + */ +void NimBLEClient::resetCallbacks() { + m_pCallbacks = &defaultCallbacks; +} // resetCallbacks /** * @brief Return a string representation of this client. diff --git a/src/NimBLEClient.h b/src/NimBLEClient.h index 9b9b8538e..ce35b484b 100644 --- a/src/NimBLEClient.h +++ b/src/NimBLEClient.h @@ -64,7 +64,8 @@ class NimBLEClient { bool setPeerAddress(const NimBLEAddress& address); int getRssi() const; bool isConnected() const; - void setClientCallbacks(NimBLEClientCallbacks* pClientCallbacks, bool deleteCallbacks = true); + void setCallbacks(NimBLEClientCallbacks& callbacks); + void resetCallbacks(); std::string toString() const; uint16_t getConnHandle() const; uint16_t getMTU() const; @@ -103,7 +104,6 @@ class NimBLEClient { bool getPhy(uint8_t* txPhy, uint8_t* rxPhy); struct Config { - uint8_t deleteCallbacks : 1; // Delete the callback object when the client is deleted. uint8_t deleteOnDisconnect : 1; // Delete the client when disconnected. uint8_t deleteOnConnectFail : 1; // Delete the client when a connection attempt fails. uint8_t asyncConnect : 1; // Connect asynchronously. @@ -113,7 +113,6 @@ class NimBLEClient { /** * @brief Construct a new Config object with default values. * @details Default values are: - * - deleteCallbacks: false * - deleteOnDisconnect: false * - deleteOnConnectFail: false * - asyncConnect: false @@ -121,12 +120,7 @@ class NimBLEClient { * - connectFailRetries: 2 */ Config() - : deleteCallbacks(0), - deleteOnDisconnect(0), - deleteOnConnectFail(0), - asyncConnect(0), - exchangeMTU(1), - connectFailRetries(2) {} + : deleteOnDisconnect(0), deleteOnConnectFail(0), asyncConnect(0), exchangeMTU(1), connectFailRetries(2) {} }; Config getConfig() const; @@ -157,7 +151,7 @@ class NimBLEClient { int32_t m_connectTimeout; mutable NimBLETaskData* m_pTaskData; std::vector m_svcVec; - NimBLEClientCallbacks* m_pClientCallbacks; + NimBLEClientCallbacks* m_pCallbacks; uint16_t m_connHandle; uint8_t m_terminateFailCount; mutable uint8_t m_asyncSecureAttempt; diff --git a/src/NimBLEDescriptor.cpp b/src/NimBLEDescriptor.cpp index 8f1bb41e3..fc02281c2 100644 --- a/src/NimBLEDescriptor.cpp +++ b/src/NimBLEDescriptor.cpp @@ -91,16 +91,19 @@ NimBLECharacteristic* NimBLEDescriptor::getCharacteristic() const { /** * @brief Set the callback handlers for this descriptor. - * @param [in] pCallbacks An instance of a callback structure used to define any callbacks for the descriptor. + * @param [in] callbacks An instance of a callback structure used to define any callbacks for the descriptor. */ -void NimBLEDescriptor::setCallbacks(NimBLEDescriptorCallbacks* pCallbacks) { - if (pCallbacks != nullptr) { - m_pCallbacks = pCallbacks; - } else { - m_pCallbacks = &defaultCallbacks; - } +void NimBLEDescriptor::setCallbacks(NimBLEDescriptorCallbacks& callbacks) { + m_pCallbacks = &callbacks; } // setCallbacks +/** + * @brief Restore default callback handlers. + */ +void NimBLEDescriptor::resetCallbacks() { + m_pCallbacks = &defaultCallbacks; +} // resetCallbacks + /** * @brief Set the characteristic this descriptor belongs to. * @param [in] pChar A pointer to the characteristic this descriptor belongs to. diff --git a/src/NimBLEDescriptor.h b/src/NimBLEDescriptor.h index b6e9b8f2a..c2eab3714 100644 --- a/src/NimBLEDescriptor.h +++ b/src/NimBLEDescriptor.h @@ -41,7 +41,8 @@ class NimBLEDescriptor : public NimBLELocalValueAttribute { ~NimBLEDescriptor() = default; std::string toString() const; - void setCallbacks(NimBLEDescriptorCallbacks* pCallbacks); + void setCallbacks(NimBLEDescriptorCallbacks& callbacks); + void resetCallbacks(); NimBLECharacteristic* getCharacteristic() const; private: diff --git a/src/NimBLEDevice.cpp b/src/NimBLEDevice.cpp index b309b0271..95d194047 100644 --- a/src/NimBLEDevice.cpp +++ b/src/NimBLEDevice.cpp @@ -69,7 +69,7 @@ extern "C" void ble_store_config_init(void); * Singletons for the NimBLEDevice. */ NimBLEDeviceCallbacks NimBLEDevice::defaultDeviceCallbacks{}; -NimBLEDeviceCallbacks* NimBLEDevice::m_pDeviceCallbacks = &defaultDeviceCallbacks; +NimBLEDeviceCallbacks* NimBLEDevice::m_pCallbacks = &defaultDeviceCallbacks; # if MYNEWT_VAL(BLE_ROLE_OBSERVER) NimBLEScan* NimBLEDevice::m_pScan = nullptr; @@ -985,7 +985,7 @@ bool NimBLEDevice::init(const std::string& deviceName) { ble_hs_cfg.reset_cb = NimBLEDevice::onReset; ble_hs_cfg.sync_cb = NimBLEDevice::onSync; ble_hs_cfg.store_status_cb = [](struct ble_store_status_event* event, void* arg) { - return m_pDeviceCallbacks->onStoreStatus(event, arg); + return m_pCallbacks->onStoreStatus(event, arg); }; // Set initial security capabilities @@ -1074,6 +1074,7 @@ bool NimBLEDevice::deinit(bool clearAll) { deleteClient(clt); } # endif + resetCallbacks(); } return rc == 0; @@ -1377,8 +1378,20 @@ void nimble_cpp_assert(const char* file, unsigned line) { } # endif // MYNEWT_VAL(NIMBLE_CPP_DEBUG_ASSERT_ENABLED) -void NimBLEDevice::setDeviceCallbacks(NimBLEDeviceCallbacks* cb) { - m_pDeviceCallbacks = cb ? cb : &defaultDeviceCallbacks; +/** + * @brief Set callbacks for NimBLEDevice host events. + * @param [in] callbacks Callback handler instance. + * @details The callback handler must outlive the active NimBLEDevice session or until resetCallbacks() is called. + */ +void NimBLEDevice::setCallbacks(NimBLEDeviceCallbacks& callbacks) { + m_pCallbacks = &callbacks; +} + +/** + * @brief Restore default NimBLEDevice callback handlers. + */ +void NimBLEDevice::resetCallbacks() { + m_pCallbacks = &defaultDeviceCallbacks; } int NimBLEDeviceCallbacks::onStoreStatus(struct ble_store_status_event* event, void* arg) { diff --git a/src/NimBLEDevice.h b/src/NimBLEDevice.h index fb64c83db..e63ba9e8d 100644 --- a/src/NimBLEDevice.h +++ b/src/NimBLEDevice.h @@ -133,7 +133,8 @@ class NimBLEDevice { static bool setOwnAddrType(uint8_t type); static bool setOwnAddr(const NimBLEAddress& addr); static bool setOwnAddr(const uint8_t* addr); - static void setDeviceCallbacks(NimBLEDeviceCallbacks* cb); + static void setCallbacks(NimBLEDeviceCallbacks& callbacks); + static void resetCallbacks(); static void setScanDuplicateCacheSize(uint16_t cacheSize); static void setScanFilterMode(uint8_t type); static void setScanDuplicateCacheResetTime(uint16_t time); @@ -220,7 +221,7 @@ class NimBLEDevice { static ble_gap_event_listener m_listener; static uint8_t m_ownAddrType; static std::vector m_whiteList; - static NimBLEDeviceCallbacks* m_pDeviceCallbacks; + static NimBLEDeviceCallbacks* m_pCallbacks; static NimBLEDeviceCallbacks defaultDeviceCallbacks; # if MYNEWT_VAL(BLE_ROLE_OBSERVER) diff --git a/src/NimBLEExtAdvertising.cpp b/src/NimBLEExtAdvertising.cpp index 237e75b0e..12f880573 100644 --- a/src/NimBLEExtAdvertising.cpp +++ b/src/NimBLEExtAdvertising.cpp @@ -36,18 +36,13 @@ static const char* LOG_TAG = "NimBLEExtAdvertising"; * @brief Constructor. */ NimBLEExtAdvertising::NimBLEExtAdvertising() - : m_deleteCallbacks{false}, - m_pCallbacks{&defaultCallbacks}, + : m_pCallbacks{&defaultCallbacks}, m_advStatus(MYNEWT_VAL(BLE_MULTI_ADV_INSTANCES) + 1, false) {} /** - * @brief Destructor: deletes callback instances if requested. + * @brief Destructor. */ -NimBLEExtAdvertising::~NimBLEExtAdvertising() { - if (m_deleteCallbacks) { - delete m_pCallbacks; - } -} +NimBLEExtAdvertising::~NimBLEExtAdvertising() {} /** * @brief Register the extended advertisement data. @@ -241,19 +236,19 @@ bool NimBLEExtAdvertising::stop() { /** * @brief Set a callback to call when the advertisement stops. - * @param [in] pCallbacks A pointer to a callback to be invoked when an advertisement stops. - * @param [in] deleteCallbacks if true callback class will be deleted when advertising is destructed. + * @param [in] callbacks A reference to a callback to be invoked when an advertisement stops. */ -void NimBLEExtAdvertising::setCallbacks(NimBLEExtAdvertisingCallbacks* pCallbacks, bool deleteCallbacks) { - if (pCallbacks != nullptr) { - m_pCallbacks = pCallbacks; - m_deleteCallbacks = deleteCallbacks; - } else { - m_pCallbacks = &defaultCallbacks; - m_deleteCallbacks = false; - } +void NimBLEExtAdvertising::setCallbacks(NimBLEExtAdvertisingCallbacks& callbacks) { + m_pCallbacks = &callbacks; } // setCallbacks +/** + * @brief Restore default callback handlers. + */ +void NimBLEExtAdvertising::resetCallbacks() { + m_pCallbacks = &defaultCallbacks; +} // resetCallbacks + /** * @brief Check if currently advertising. * @param [in] instId The instance ID of the advertised data to get the status of. diff --git a/src/NimBLEExtAdvertising.h b/src/NimBLEExtAdvertising.h index a9cc73475..dd1322f3c 100644 --- a/src/NimBLEExtAdvertising.h +++ b/src/NimBLEExtAdvertising.h @@ -120,7 +120,8 @@ class NimBLEExtAdvertising { bool stop(); bool isActive(uint8_t instId); bool isAdvertising(); - void setCallbacks(NimBLEExtAdvertisingCallbacks* callbacks, bool deleteCallbacks = true); + void setCallbacks(NimBLEExtAdvertisingCallbacks& callbacks); + void resetCallbacks(); private: friend class NimBLEDevice; @@ -129,7 +130,6 @@ class NimBLEExtAdvertising { void onHostSync(); static int handleGapEvent(struct ble_gap_event* event, void* arg); - bool m_deleteCallbacks; NimBLEExtAdvertisingCallbacks* m_pCallbacks; std::vector m_advStatus; }; diff --git a/src/NimBLEScan.cpp b/src/NimBLEScan.cpp index 6f80d6e96..42b735941 100644 --- a/src/NimBLEScan.cpp +++ b/src/NimBLEScan.cpp @@ -58,7 +58,7 @@ void NimBLEScan::srTimerCb(ble_npl_event* event) { pScan->m_stats.incMissedSrCount(); pScan->removeWaitingDevice(pDev); pDev->m_callbackSent = 2; - pScan->m_pScanCallbacks->onResult(pDev); + pScan->m_pCallbacks->onResult(pDev); if (pScan->m_maxResults == 0) { pScan->erase(pDev); } @@ -68,7 +68,7 @@ void NimBLEScan::srTimerCb(ble_npl_event* event) { * @brief Scan constructor. */ NimBLEScan::NimBLEScan() - : m_pScanCallbacks{&defaultScanCallbacks}, + : m_pCallbacks{&defaultScanCallbacks}, // default interval + window, no whitelist scan filter,not limited scan, no scan response, filter_duplicates m_scanParams{0, 0, BLE_HCI_SCAN_FILT_NO_WL, 0, 1, 1}, m_pTaskData{nullptr}, @@ -306,18 +306,18 @@ int NimBLEScan::handleGapEvent(ble_gap_event* event, void* arg) { if (!advertisedDevice->m_callbackSent) { advertisedDevice->m_callbackSent++; - pScan->m_pScanCallbacks->onDiscovered(advertisedDevice); + pScan->m_pCallbacks->onDiscovered(advertisedDevice); } // If not active scanning or scan response is not available // or extended advertisement scanning, report the result to the callback now. if (pScan->m_scanParams.passive || !isLegacyAdv || !advertisedDevice->isScannable()) { advertisedDevice->m_callbackSent++; - pScan->m_pScanCallbacks->onResult(advertisedDevice); + pScan->m_pCallbacks->onResult(advertisedDevice); } else if (isLegacyAdv && event_type == BLE_HCI_ADV_RPT_EVTYPE_SCAN_RSP) { advertisedDevice->m_callbackSent++; // got the scan response report the full data. - pScan->m_pScanCallbacks->onResult(advertisedDevice); + pScan->m_pCallbacks->onResult(advertisedDevice); } else if (isLegacyAdv && advertisedDevice->isScannable()) { // Add to waiting list for scan response and start the timer pScan->addWaitingDevice(advertisedDevice); @@ -345,7 +345,7 @@ int NimBLEScan::handleGapEvent(ble_gap_event* event, void* arg) { pScan->m_stats.incMissedSrCount(); pScan->removeWaitingDevice(pDev); pDev->m_callbackSent = 2; - pScan->m_pScanCallbacks->onResult(pDev); + pScan->m_pCallbacks->onResult(pDev); } if (pScan->m_maxResults == 0) { @@ -355,7 +355,7 @@ int NimBLEScan::handleGapEvent(ble_gap_event* event, void* arg) { NIMBLE_LOGD(LOG_TAG, "discovery complete; reason=%d", event->disc_complete.reason); NIMBLE_LOGD(LOG_TAG, "%s", pScan->getStatsString().c_str()); - pScan->m_pScanCallbacks->onScanEnd(pScan->m_scanResults, event->disc_complete.reason); + pScan->m_pCallbacks->onScanEnd(pScan->m_scanResults, event->disc_complete.reason); if (pScan->m_pTaskData != nullptr) { NimBLEUtils::taskRelease(*pScan->m_pTaskData, event->disc_complete.reason); @@ -454,18 +454,24 @@ void NimBLEScan::setMaxResults(uint8_t maxResults) { } // setMaxResults /** - * @brief Set the call backs to be invoked. - * @param [in] pScanCallbacks Call backs to be invoked. - * @param [in] wantDuplicates True if we wish to be called back with duplicates, default: false. + * @brief Set scan callbacks. + * @param [in] callbacks Callback handler instance. + * @param [in] wantDuplicates True to report duplicate advertisements. + * @details The callback handler must outlive this scanner or until resetCallbacks() is called. */ -void NimBLEScan::setScanCallbacks(NimBLEScanCallbacks* pScanCallbacks, bool wantDuplicates) { +void NimBLEScan::setCallbacks(NimBLEScanCallbacks& callbacks, bool wantDuplicates) { setDuplicateFilter(!wantDuplicates); - if (pScanCallbacks == nullptr) { - m_pScanCallbacks = &defaultScanCallbacks; - return; - } - m_pScanCallbacks = pScanCallbacks; -} // setScanCallbacks + m_pCallbacks = &callbacks; +} // setCallbacks + +/** + * @brief Restore default scan callback handlers. + * @param [in] wantDuplicates True to report duplicate advertisements. + */ +void NimBLEScan::resetCallbacks(bool wantDuplicates) { + setDuplicateFilter(!wantDuplicates); + m_pCallbacks = &defaultScanCallbacks; +} // resetCallbacks /** * @brief Set the interval to scan. @@ -659,7 +665,7 @@ void NimBLEScan::erase(const NimBLEAdvertisedDevice* device) { * If the application was scanning indefinitely with a callback, restart it. */ void NimBLEScan::onHostSync() { - m_pScanCallbacks->onScanEnd(m_scanResults, BLE_HS_ENOTSYNCED); + m_pCallbacks->onScanEnd(m_scanResults, BLE_HS_ENOTSYNCED); } /** diff --git a/src/NimBLEScan.h b/src/NimBLEScan.h index 2b8a24996..273571178 100644 --- a/src/NimBLEScan.h +++ b/src/NimBLEScan.h @@ -70,7 +70,8 @@ class NimBLEScan { public: bool start(uint32_t duration, bool isContinue = false, bool restart = true); bool isScanning(); - void setScanCallbacks(NimBLEScanCallbacks* pScanCallbacks, bool wantDuplicates = false); + void setCallbacks(NimBLEScanCallbacks& callbacks, bool wantDuplicates = false); + void resetCallbacks(bool wantDuplicates = false); void setActiveScan(bool active); void setInterval(uint16_t intervalMs); void setWindow(uint16_t windowMs); @@ -129,11 +130,16 @@ class NimBLEScan { snprintf(&out[0], out.size(), "Scan stats:\n" - " Devices seen : %" PRIu32 "\n" - " Duplicate advs : %" PRIu32 "\n" - " Scan responses : %" PRIu32 "\n" - " SR timing (ms) : min=%" PRIu32 ", max=%" PRIu32 ", avg=%" PRIu64 "\n" - " Orphaned SR : %" PRIu32 "\n" + " Devices seen : %" PRIu32 + "\n" + " Duplicate advs : %" PRIu32 + "\n" + " Scan responses : %" PRIu32 + "\n" + " SR timing (ms) : min=%" PRIu32 ", max=%" PRIu32 ", avg=%" PRIu64 + "\n" + " Orphaned SR : %" PRIu32 + "\n" " Missed SR : %" PRIu32 "\n", devCount, dupCount, @@ -184,7 +190,7 @@ class NimBLEScan { void clearWaitingList(); void resetWaitingTimer(); - NimBLEScanCallbacks* m_pScanCallbacks; + NimBLEScanCallbacks* m_pCallbacks; ble_gap_disc_params m_scanParams; NimBLEScanResults m_scanResults; NimBLETaskData* m_pTaskData; diff --git a/src/NimBLEServer.cpp b/src/NimBLEServer.cpp index 1cab58ed9..683522061 100644 --- a/src/NimBLEServer.cpp +++ b/src/NimBLEServer.cpp @@ -53,11 +53,10 @@ struct gattRegisterCallbackArgs { NimBLEServer::NimBLEServer() : m_gattsStarted{false}, m_svcChanged{false}, - m_deleteCallbacks{false}, # if !MYNEWT_VAL(BLE_EXT_ADV) m_advertiseOnDisconnect{false}, # endif - m_pServerCallbacks{&defaultCallbacks}, + m_pCallbacks{&defaultCallbacks}, m_svcVec{} { m_connectedPeers.fill(BLE_HS_CONN_HANDLE_NONE); } // NimBLEServer @@ -70,10 +69,6 @@ NimBLEServer::~NimBLEServer() { delete svc; } - if (m_deleteCallbacks) { - delete m_pServerCallbacks; - } - # if MYNEWT_VAL(BLE_ROLE_CENTRAL) if (m_pClient != nullptr) { delete m_pClient; @@ -483,7 +478,7 @@ int NimBLEServer::handleGapEvent(ble_gap_event* event, void* arg) { } } - pServer->m_pServerCallbacks->onConnect(pServer, peerInfo); + pServer->m_pCallbacks->onConnect(pServer, peerInfo); } break; @@ -519,7 +514,7 @@ int NimBLEServer::handleGapEvent(ble_gap_event* event, void* arg) { # endif peerInfo.m_desc = event->disconnect.conn; - pServer->m_pServerCallbacks->onDisconnect(pServer, peerInfo, event->disconnect.reason); + pServer->m_pCallbacks->onDisconnect(pServer, peerInfo, event->disconnect.reason); # if !MYNEWT_VAL(BLE_EXT_ADV) && MYNEWT_VAL(BLE_ROLE_BROADCASTER) if (pServer->m_advertiseOnDisconnect) { pServer->startAdvertising(); @@ -550,7 +545,7 @@ int NimBLEServer::handleGapEvent(ble_gap_event* event, void* arg) { case BLE_GAP_EVENT_MTU: { NIMBLE_LOGI(LOG_TAG, "mtu update event; conn_handle=%d mtu=%d", event->mtu.conn_handle, event->mtu.value); if (ble_gap_conn_find(event->mtu.conn_handle, &peerInfo.m_desc) == 0) { - pServer->m_pServerCallbacks->onMTUChange(event->mtu.value, peerInfo); + pServer->m_pCallbacks->onMTUChange(event->mtu.value, peerInfo); } break; @@ -598,7 +593,7 @@ int NimBLEServer::handleGapEvent(ble_gap_event* event, void* arg) { case BLE_GAP_EVENT_CONN_UPDATE: { if (ble_gap_conn_find(event->connect.conn_handle, &peerInfo.m_desc) == 0) { - pServer->m_pServerCallbacks->onConnParamsUpdate(peerInfo); + pServer->m_pCallbacks->onConnParamsUpdate(peerInfo); } break; @@ -630,7 +625,7 @@ int NimBLEServer::handleGapEvent(ble_gap_event* event, void* arg) { return BLE_ATT_ERR_INVALID_HANDLE; } - pServer->m_pServerCallbacks->onAuthenticationComplete(peerInfo); + pServer->m_pCallbacks->onAuthenticationComplete(peerInfo); # if MYNEWT_VAL(BLE_ROLE_CENTRAL) if (pServer->m_pClient && pServer->m_pClient->m_connHandle == event->enc_change.conn_handle) { NimBLEClient::handleGapEvent(event, pServer->m_pClient); @@ -652,7 +647,7 @@ int NimBLEServer::handleGapEvent(ble_gap_event* event, void* arg) { return BLE_ATT_ERR_INVALID_HANDLE; } - pServer->m_pServerCallbacks->onIdentity(peerInfo); + pServer->m_pCallbacks->onIdentity(peerInfo); break; } // BLE_GAP_EVENT_IDENTITY_RESOLVED @@ -662,7 +657,7 @@ int NimBLEServer::handleGapEvent(ble_gap_event* event, void* arg) { return BLE_ATT_ERR_INVALID_HANDLE; } - pServer->m_pServerCallbacks->onPhyUpdate(peerInfo, event->phy_updated.tx_phy, event->phy_updated.rx_phy); + pServer->m_pCallbacks->onPhyUpdate(peerInfo, event->phy_updated.tx_phy, event->phy_updated.rx_phy); return 0; } // BLE_GAP_EVENT_PHY_UPDATE_COMPLETE @@ -676,7 +671,7 @@ int NimBLEServer::handleGapEvent(ble_gap_event* event, void* arg) { // if the (static)passkey is the default, check the callback for custom value // both values default to the same. if (pkey.passkey == 123456) { - pkey.passkey = pServer->m_pServerCallbacks->onPassKeyDisplay(); + pkey.passkey = pServer->m_pCallbacks->onPassKeyDisplay(); } rc = ble_sm_inject_io(event->passkey.conn_handle, &pkey); NIMBLE_LOGD(LOG_TAG, "BLE_SM_IOACT_DISP; ble_sm_inject_io result: %d", rc); @@ -689,7 +684,7 @@ int NimBLEServer::handleGapEvent(ble_gap_event* event, void* arg) { return BLE_ATT_ERR_INVALID_HANDLE; } - pServer->m_pServerCallbacks->onConfirmPassKey(peerInfo, event->passkey.params.numcmp); + pServer->m_pCallbacks->onConfirmPassKey(peerInfo, event->passkey.params.numcmp); } else if (event->passkey.params.action == BLE_SM_IOACT_OOB) { // TODO: Handle out of band pairing // static uint8_t tem_oob[16] = {0}; @@ -707,7 +702,7 @@ int NimBLEServer::handleGapEvent(ble_gap_event* event, void* arg) { return BLE_ATT_ERR_INVALID_HANDLE; } - pServer->m_pServerCallbacks->onPassKeyEntry(peerInfo); + pServer->m_pCallbacks->onPassKeyEntry(peerInfo); } else if (event->passkey.params.action == BLE_SM_IOACT_NONE) { NIMBLE_LOGD(LOG_TAG, "No passkey action required"); } @@ -785,25 +780,21 @@ int NimBLEServer::handleGattEvent(uint16_t connHandle, uint16_t attrHandle, ble_ } // handleGattEvent /** - * @brief Set the server callbacks. - * - * As a BLE server operates, it will generate server level events such as a new client connecting or a previous - * client disconnecting. This function can be called to register a callback handler that will be invoked when these - * 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. + * @brief Set the callbacks for server events. + * @param [in] callbacks Callback handler instance. + * @details The callback handler must outlive this server or until resetCallbacks() is called. */ -void NimBLEServer::setCallbacks(NimBLEServerCallbacks* pCallbacks, bool deleteCallbacks) { - if (pCallbacks != nullptr) { - m_pServerCallbacks = pCallbacks; - m_deleteCallbacks = deleteCallbacks; - } else { - m_pServerCallbacks = &defaultCallbacks; - m_deleteCallbacks = false; - } +void NimBLEServer::setCallbacks(NimBLEServerCallbacks& callbacks) { + m_pCallbacks = &callbacks; } // setCallbacks +/** + * @brief Restore default callback handlers. + */ +void NimBLEServer::resetCallbacks() { + m_pCallbacks = &defaultCallbacks; +} // resetCallbacks + /** * @brief Remove a service from the server. * diff --git a/src/NimBLEServer.h b/src/NimBLEServer.h index b2b79e1eb..0d51712be 100644 --- a/src/NimBLEServer.h +++ b/src/NimBLEServer.h @@ -65,7 +65,8 @@ class NimBLEServer { uint8_t getConnectedCount() const; bool disconnect(uint16_t connHandle, uint8_t reason = BLE_ERR_REM_USER_CONN_TERM) const; bool disconnect(const NimBLEConnInfo& connInfo, uint8_t reason = BLE_ERR_REM_USER_CONN_TERM) const; - void setCallbacks(NimBLEServerCallbacks* pCallbacks, bool deleteCallbacks = true); + void setCallbacks(NimBLEServerCallbacks& callbacks); + void resetCallbacks(); void updateConnParams(uint16_t connHandle, uint16_t minInterval, uint16_t maxInterval, uint16_t latency, uint16_t timeout) const; NimBLEService* createService(const char* uuid); NimBLEService* createService(const NimBLEUUID& uuid); @@ -128,11 +129,10 @@ class NimBLEServer { bool m_gattsStarted : 1; bool m_svcChanged : 1; - bool m_deleteCallbacks : 1; # if !MYNEWT_VAL(BLE_EXT_ADV) && MYNEWT_VAL(BLE_ROLE_BROADCASTER) bool m_advertiseOnDisconnect : 1; # endif - NimBLEServerCallbacks* m_pServerCallbacks; + NimBLEServerCallbacks* m_pCallbacks; std::vector m_svcVec; std::array m_connectedPeers; diff --git a/src/NimBLEStream.cpp b/src/NimBLEStream.cpp index 7ed0c9085..1f670871e 100644 --- a/src/NimBLEStream.cpp +++ b/src/NimBLEStream.cpp @@ -572,7 +572,7 @@ bool NimBLEStreamServer::begin(NimBLECharacteristic* pChr, uint32_t txBufSize, u } m_charCallbacks.m_userCallbacks = pChr->getCallbacks(); - pChr->setCallbacks(&m_charCallbacks); + pChr->setCallbacks(m_charCallbacks); m_pChr = pChr; return true; } @@ -661,7 +661,7 @@ void NimBLEStreamServer::end() { } } } else { - m_pChr->setCallbacks(m_charCallbacks.m_userCallbacks); // restore any user callbacks + m_pChr->setCallbacks(*m_charCallbacks.m_userCallbacks); // restore any user callbacks } } diff --git a/src/NimBLEStream.h b/src/NimBLEStream.h index 47ccb83d8..d4bde54da 100644 --- a/src/NimBLEStream.h +++ b/src/NimBLEStream.h @@ -159,7 +159,7 @@ class NimBLEStreamServer : public NimBLEStream { void end() override; size_t write(const uint8_t* data, size_t len) override; uint16_t getPeerHandle() const { return m_charCallbacks.m_peerHandle; } - void setCallbacks(NimBLECharacteristicCallbacks* pCallbacks) { m_charCallbacks.m_userCallbacks = pCallbacks; } + void setCallbacks(NimBLECharacteristicCallbacks& callbacks) { m_charCallbacks.m_userCallbacks = &callbacks; } bool ready() const override; virtual void flush() override;