diff --git a/examples/BLE_Beacon_Scanner/BLE_Beacon_Scanner.ino b/examples/BLE_Beacon_Scanner/BLE_Beacon_Scanner.ino index f412e279..1aab09db 100644 --- a/examples/BLE_Beacon_Scanner/BLE_Beacon_Scanner.ino +++ b/examples/BLE_Beacon_Scanner/BLE_Beacon_Scanner.ino @@ -3,151 +3,95 @@ Ported to Arduino ESP32 by Evandro Copercini */ -/** NimBLE differences highlighted in comment blocks **/ - -/*******original******** - #include - #include - #include - #include - #include "BLEEddystoneURL.h" - #include "BLEEddystoneTLM.h" - #include "BLEBeacon.h" -***********************/ - #include - #include #include -#include "NimBLEEddystoneURL.h" #include "NimBLEEddystoneTLM.h" #include "NimBLEBeacon.h" -#define ENDIAN_CHANGE_U16(x) ((((x)&0xFF00) >> 8) + (((x)&0xFF) << 8)) - -int scanTime = 5 * 1000; //In milliseconds -BLEScan *pBLEScan; +#define ENDIAN_CHANGE_U16(x) ((((x) & 0xFF00) >> 8) + (((x) & 0xFF) << 8)) -class MyAdvertisedDeviceCallbacks : public BLEAdvertisedDeviceCallbacks -{ - /*** Only a reference to the advertised device is passed now - void onResult(BLEAdvertisedDevice advertisedDevice) { **/ - void onResult(BLEAdvertisedDevice *advertisedDevice) - { - if (advertisedDevice->haveName()) - { - Serial.print("Device name: "); - Serial.println(advertisedDevice->getName().c_str()); - Serial.println(""); - } +int scanTime = 5 * 1000; // In milliseconds +NimBLEScan* pBLEScan; - if (advertisedDevice->haveServiceUUID()) - { - BLEUUID devUUID = advertisedDevice->getServiceUUID(); - Serial.print("Found ServiceUUID: "); - Serial.println(devUUID.toString().c_str()); - Serial.println(""); - } - else - { - if (advertisedDevice->haveManufacturerData() == true) - { - std::string strManufacturerData = advertisedDevice->getManufacturerData(); - - uint8_t cManufacturerData[100]; - strManufacturerData.copy((char *)cManufacturerData, strManufacturerData.length(), 0); - - if (strManufacturerData.length() == 25 && cManufacturerData[0] == 0x4C && cManufacturerData[1] == 0x00) - { - Serial.println("Found an iBeacon!"); - BLEBeacon oBeacon = BLEBeacon(); - oBeacon.setData(strManufacturerData); - Serial.printf("iBeacon Frame\n"); - Serial.printf("ID: %04X Major: %d Minor: %d UUID: %s Power: %d\n", oBeacon.getManufacturerId(), ENDIAN_CHANGE_U16(oBeacon.getMajor()), ENDIAN_CHANGE_U16(oBeacon.getMinor()), oBeacon.getProximityUUID().toString().c_str(), oBeacon.getSignalPower()); - } - else - { - Serial.println("Found another manufacturers beacon!"); - Serial.printf("strManufacturerData: %d ", strManufacturerData.length()); - for (int i = 0; i < strManufacturerData.length(); i++) - { - Serial.printf("[%X]", cManufacturerData[i]); - } - Serial.printf("\n"); - } +class ScanCallbacks : public NimBLEScanCallbacks { + void onResult(const NimBLEAdvertisedDevice* advertisedDevice) override { + if (advertisedDevice->haveName()) { + Serial.print("Device name: "); + Serial.println(advertisedDevice->getName().c_str()); + Serial.println(""); } - return; - } - BLEUUID eddyUUID = (uint16_t)0xfeaa; - - if (advertisedDevice->getServiceUUID().equals(eddyUUID)) - { - std::string serviceData = advertisedDevice->getServiceData(eddyUUID); - if (serviceData[0] == 0x10) - { - Serial.println("Found an EddystoneURL beacon!"); - BLEEddystoneURL foundEddyURL = BLEEddystoneURL(); - - foundEddyURL.setData(serviceData); - std::string bareURL = foundEddyURL.getURL(); - if (bareURL[0] == 0x00) - { - Serial.println("DATA-->"); - for (int idx = 0; idx < serviceData.length(); idx++) - { - Serial.printf("0x%08X ", serviceData[idx]); + if (advertisedDevice->haveServiceUUID()) { + NimBLEUUID devUUID = advertisedDevice->getServiceUUID(); + Serial.print("Found ServiceUUID: "); + Serial.println(devUUID.toString().c_str()); + Serial.println(""); + } else if (advertisedDevice->haveManufacturerData() == true) { + std::string strManufacturerData = advertisedDevice->getManufacturerData(); + if (strManufacturerData.length() == 25 && strManufacturerData[0] == 0x4C && strManufacturerData[1] == 0x00) { + Serial.println("Found an iBeacon!"); + NimBLEBeacon oBeacon = NimBLEBeacon(); + oBeacon.setData(reinterpret_cast(strManufacturerData.data()), strManufacturerData.length()); + Serial.printf("iBeacon Frame\n"); + Serial.printf("ID: %04X Major: %d Minor: %d UUID: %s Power: %d\n", + oBeacon.getManufacturerId(), + ENDIAN_CHANGE_U16(oBeacon.getMajor()), + ENDIAN_CHANGE_U16(oBeacon.getMinor()), + oBeacon.getProximityUUID().toString().c_str(), + oBeacon.getSignalPower()); + } else { + Serial.println("Found another manufacturers beacon!"); + Serial.printf("strManufacturerData: %d ", strManufacturerData.length()); + for (int i = 0; i < strManufacturerData.length(); i++) { + Serial.printf("[%X]", strManufacturerData[i]); + } + Serial.printf("\n"); } - Serial.println("\nInvalid Data"); return; - } - - Serial.printf("Found URL: %s\n", foundEddyURL.getURL().c_str()); - Serial.printf("Decoded URL: %s\n", foundEddyURL.getDecodedURL().c_str()); - Serial.printf("TX power %d\n", foundEddyURL.getPower()); - Serial.println("\n"); } - else if (serviceData[0] == 0x20) - { - Serial.println("Found an EddystoneTLM beacon!"); - BLEEddystoneTLM foundEddyURL = BLEEddystoneTLM(); - foundEddyURL.setData(serviceData); - Serial.printf("Reported battery voltage: %dmV\n", foundEddyURL.getVolt()); - Serial.printf("Reported temperature from TLM class: %.2fC\n", (double)foundEddyURL.getTemp()); - int temp = (int)serviceData[5] + (int)(serviceData[4] << 8); - float calcTemp = temp / 256.0f; - Serial.printf("Reported temperature from data: %.2fC\n", calcTemp); - Serial.printf("Reported advertise count: %d\n", foundEddyURL.getCount()); - Serial.printf("Reported time since last reboot: %ds\n", foundEddyURL.getTime()); - Serial.println("\n"); - Serial.print(foundEddyURL.toString().c_str()); - Serial.println("\n"); + NimBLEUUID eddyUUID = (uint16_t)0xfeaa; + + if (advertisedDevice->getServiceUUID().equals(eddyUUID)) { + std::string serviceData = advertisedDevice->getServiceData(eddyUUID); + if (serviceData[0] == 0x20) { + Serial.println("Found an EddystoneTLM beacon!"); + NimBLEEddystoneTLM foundEddyTLM = NimBLEEddystoneTLM(); + foundEddyTLM.setData(reinterpret_cast(serviceData.data()), serviceData.length()); + + Serial.printf("Reported battery voltage: %dmV\n", foundEddyTLM.getVolt()); + Serial.printf("Reported temperature from TLM class: %.2fC\n", (double)foundEddyTLM.getTemp()); + int temp = (int)serviceData[5] + (int)(serviceData[4] << 8); + float calcTemp = temp / 256.0f; + Serial.printf("Reported temperature from data: %.2fC\n", calcTemp); + Serial.printf("Reported advertise count: %d\n", foundEddyTLM.getCount()); + Serial.printf("Reported time since last reboot: %ds\n", foundEddyTLM.getTime()); + Serial.println("\n"); + Serial.print(foundEddyTLM.toString().c_str()); + Serial.println("\n"); + } } - } } -}; - -void setup() -{ - Serial.begin(115200); - Serial.println("Scanning..."); - - BLEDevice::init(""); - pBLEScan = BLEDevice::getScan(); //create new scan - pBLEScan->setScanCallbacks(new MyAdvertisedDeviceCallbacks()); - pBLEScan->setActiveScan(true); //active scan uses more power, but get results faster - pBLEScan->setInterval(100); - pBLEScan->setWindow(99); // less or equal setInterval value +} scanCallbacks; + +void setup() { + Serial.begin(115200); + Serial.println("Scanning..."); + + NimBLEDevice::init("Beacon-scanner"); + pBLEScan = BLEDevice::getScan(); + pBLEScan->setScanCallbacks(&scanCallbacks); + pBLEScan->setActiveScan(true); + pBLEScan->setInterval(100); + pBLEScan->setWindow(100); } -void loop() -{ - // put your main code here, to run repeatedly: - BLEScanResults foundDevices = pBLEScan->getResults(scanTime, false); - Serial.print("Devices found: "); - Serial.println(foundDevices.getCount()); - Serial.println("Scan done!"); - pBLEScan->clearResults(); // delete results fromBLEScan buffer to release memory - delay(2000); +void loop() { + NimBLEScanResults foundDevices = pBLEScan->getResults(scanTime, false); + Serial.print("Devices found: "); + Serial.println(foundDevices.getCount()); + Serial.println("Scan done!"); + pBLEScan->clearResults(); // delete results scan buffer to release memory + delay(2000); } diff --git a/examples/BLE_Beacon_Scanner/BLE_Beacon_Scanner.md b/examples/BLE_Beacon_Scanner/BLE_Beacon_Scanner.md index 558c3e7a..d6b568f9 100644 --- a/examples/BLE_Beacon_Scanner/BLE_Beacon_Scanner.md +++ b/examples/BLE_Beacon_Scanner/BLE_Beacon_Scanner.md @@ -4,6 +4,5 @@ Initiates a BLE device scan. Checks if the discovered devices are - an iBeacon - an Eddystone TLM beacon -- an Eddystone URL beacon and sends the decoded beacon information over Serial log \ No newline at end of file diff --git a/examples/BLE_EddystoneTLM_Beacon/BLE_EddystoneTLM_Beacon.ino b/examples/BLE_EddystoneTLM_Beacon/BLE_EddystoneTLM_Beacon.ino index fc8fa71c..681d452a 100644 --- a/examples/BLE_EddystoneTLM_Beacon/BLE_EddystoneTLM_Beacon.ino +++ b/examples/BLE_EddystoneTLM_Beacon/BLE_EddystoneTLM_Beacon.ino @@ -1,5 +1,6 @@ /* - EddystoneTLM beacon for NimBLE by BeeGee based on https://github.com/pcbreflux/espressif/blob/master/esp32/arduino/sketchbook/ESP32_Eddystone_TLM_deepsleep/ESP32_Eddystone_TLM_deepsleep.ino + EddystoneTLM beacon by BeeGee based on + https://github.com/pcbreflux/espressif/blob/master/esp32/arduino/sketchbook/ESP32_Eddystone_TLM_deepsleep/ESP32_Eddystone_TLM_deepsleep.ino EddystoneTLM frame specification https://github.com/google/eddystone/blob/master/eddystone-tlm/tlm-plain.md */ @@ -13,102 +14,71 @@ 5. Stop advertising. 6. deep sleep + To read data advertised by this beacon use second ESP with example sketch BLE_Beacon_Scanner */ -#include "NimBLEDevice.h" -#include "NimBLEBeacon.h" -#include "NimBLEAdvertising.h" -#include "NimBLEEddystoneURL.h" +#include +#include +#include +#include +#include -#include "sys/time.h" -#include "esp_sleep.h" +#define GPIO_DEEP_SLEEP_DURATION 10 // sleep x seconds and then wake up +#define BEACON_POWER 3 // 3dbm -#define GPIO_DEEP_SLEEP_DURATION 10 // sleep x seconds and then wake up - -// UUID 1 128-Bit (may use linux tool uuidgen or random numbers via https://www.uuidgenerator.net/) -#define BEACON_UUID "8ec76ea3-6668-48da-9866-75be8bc86f4d" - -RTC_DATA_ATTR static time_t last; // remember last boot in RTC Memory +RTC_DATA_ATTR static time_t last; // remember last boot in RTC Memory RTC_DATA_ATTR static uint32_t bootcount; // remember number of boots in RTC Memory +NimBLEAdvertising* pAdvertising; +struct timeval nowTimeStruct; -BLEAdvertising *pAdvertising; -struct timeval nowTimeStruct; - -time_t lastTenth; +#define BEACON_UUID \ + "8ec76ea3-6668-48da-9866-75be8bc86f4d" // UUID 1 128-Bit (may use linux tool uuidgen or random numbers via https://www.uuidgenerator.net/) // Check // https://github.com/google/eddystone/blob/master/eddystone-tlm/tlm-plain.md // and http://www.hugi.scene.org/online/coding/hugi%2015%20-%20cmtadfix.htm // for the temperature value. It is a 8.8 fixed-point notation -void setBeacon() -{ - char beacon_data[25]; - uint16_t beconUUID = 0xFEAA; - uint16_t volt = random(2800, 3700); // 3300mV = 3.3V - float tempFloat = random(2000, 3100) / 100.0f; - Serial.printf("Random temperature is %.2fC\n", tempFloat); - int temp = (int)(tempFloat * 256); //(uint16_t)((float)23.00); - Serial.printf("Converted to 8.8 format %0X%0X\n", (temp >> 8), (temp & 0xFF)); - - BLEAdvertisementData oAdvertisementData = BLEAdvertisementData(); - BLEAdvertisementData oScanResponseData = BLEAdvertisementData(); - - oScanResponseData.setFlags(0x06); // GENERAL_DISC_MODE 0x02 | BR_EDR_NOT_SUPPORTED 0x04 - oScanResponseData.setCompleteServices(BLEUUID(beconUUID)); - - beacon_data[0] = 0x20; // Eddystone Frame Type (Unencrypted Eddystone-TLM) - beacon_data[1] = 0x00; // TLM version - beacon_data[2] = (volt >> 8); // Battery voltage, 1 mV/bit i.e. 0xCE4 = 3300mV = 3.3V - beacon_data[3] = (volt & 0xFF); // - beacon_data[4] = (temp >> 8); // Beacon temperature - beacon_data[5] = (temp & 0xFF); // - beacon_data[6] = ((bootcount & 0xFF000000) >> 24); // Advertising PDU count - beacon_data[7] = ((bootcount & 0xFF0000) >> 16); // - beacon_data[8] = ((bootcount & 0xFF00) >> 8); // - beacon_data[9] = (bootcount & 0xFF); // - beacon_data[10] = ((lastTenth & 0xFF000000) >> 24); // Time since power-on or reboot as 0.1 second resolution counter - beacon_data[11] = ((lastTenth & 0xFF0000) >> 16); // - beacon_data[12] = ((lastTenth & 0xFF00) >> 8); // - beacon_data[13] = (lastTenth & 0xFF); // - - oScanResponseData.setServiceData(BLEUUID(beconUUID), std::string(beacon_data, 14)); - oAdvertisementData.setName("TLMBeacon"); - pAdvertising->setAdvertisementData(oAdvertisementData); - pAdvertising->setScanResponseData(oScanResponseData); +void setBeacon() { + NimBLEEddystoneTLM eddystoneTLM; + eddystoneTLM.setVolt((uint16_t)random(2800, 3700)); // 3300mV = 3.3V + eddystoneTLM.setTemp(random(-3000, 3000)); // 3000 = 30.00 ˚C + Serial.printf("Random Battery voltage is %d mV = 0x%04X\n", eddystoneTLM.getVolt(), eddystoneTLM.getVolt()); + Serial.printf("Random Temperature is: %d.%d 0x%04X\n", + eddystoneTLM.getTemp() / 256, + eddystoneTLM.getTemp() % 256 * 100 / 256); + + NimBLEAdvertisementData oAdvertisementData = BLEAdvertisementData(); + NimBLEAdvertisementData oScanResponseData = BLEAdvertisementData(); + oScanResponseData.setServiceData(NimBLEUUID("FEAA"), + reinterpret_cast(&eddystoneTLM.getData()), + sizeof(NimBLEEddystoneTLM::BeaconData)); + + oAdvertisementData.setName("ESP32 TLM Beacon"); + pAdvertising->setAdvertisementData(oAdvertisementData); + pAdvertising->setScanResponseData(oScanResponseData); } -void setup() -{ - - Serial.begin(115200); - gettimeofday(&nowTimeStruct, NULL); - - Serial.printf("start ESP32 %d\n", bootcount++); - - Serial.printf("deep sleep (%lds since last reset, %lds since last boot)\n", nowTimeStruct.tv_sec, nowTimeStruct.tv_sec - last); - - last = nowTimeStruct.tv_sec; - lastTenth = nowTimeStruct.tv_sec * 10; // Time since last reset as 0.1 second resolution counter - - // Create the BLE Device - BLEDevice::init("TLMBeacon"); - - BLEDevice::setPower(ESP_PWR_LVL_N12); - - pAdvertising = BLEDevice::getAdvertising(); - pAdvertising->enableScanResponse(true); - - setBeacon(); - // Start advertising - pAdvertising->start(); - Serial.println("Advertizing started for 10s ..."); - delay(10000); - pAdvertising->stop(); - Serial.printf("enter deep sleep for 10s\n"); - esp_deep_sleep(1000000LL * GPIO_DEEP_SLEEP_DURATION); - Serial.printf("in deep sleep\n"); +void setup() { + Serial.begin(115200); + gettimeofday(&nowTimeStruct, NULL); + + Serial.printf("Starting ESP32. Bootcount = %lu\n", bootcount++); + Serial.printf("Deep sleep (%llds since last reset, %llds since last boot)\n", + nowTimeStruct.tv_sec, + nowTimeStruct.tv_sec - last); + last = nowTimeStruct.tv_sec; + + NimBLEDevice::init("TLMBeacon"); + NimBLEDevice::setPower(BEACON_POWER); + + pAdvertising = NimBLEDevice::getAdvertising(); + setBeacon(); + pAdvertising->start(); + Serial.println("Advertising started for 10s ..."); + delay(10000); + pAdvertising->stop(); + Serial.printf("Enter deep sleep for 10s\n"); + esp_deep_sleep(1000000LL * GPIO_DEEP_SLEEP_DURATION); } -void loop() -{ -} +void loop() {} 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 20f82455..aef73c19 100644 --- a/examples/Bluetooth_5/NimBLE_extended_client/NimBLE_extended_client.ino +++ b/examples/Bluetooth_5/NimBLE_extended_client/NimBLE_extended_client.ino @@ -8,67 +8,59 @@ * */ +#include #include #if !CONFIG_BT_NIMBLE_EXT_ADV -# error Must enable extended advertising, see nimconfig.h file. +# error Must enable extended advertising, see nimconfig.h file. #endif #define SERVICE_UUID "ABCD" #define CHARACTERISTIC_UUID "1234" static const NimBLEAdvertisedDevice* advDevice; -static bool doConnect = false; -static uint32_t scanTime = 10 * 1000; // In milliseconds, 0 = scan forever +static bool doConnect = false; +static uint32_t scanTime = 10 * 1000; // In milliseconds, 0 = scan forever -/* Define the PHY's to use when connecting to peer devices, can be 1, 2, or all 3 (default).*/ -static uint8_t connectPhys = BLE_GAP_LE_PHY_CODED_MASK | BLE_GAP_LE_PHY_1M_MASK /*| BLE_GAP_LE_PHY_2M_MASK */ ; +/** Define the PHY's to use when connecting to peer devices, can be 1, 2, or all 3 (default).*/ +static uint8_t connectPhys = BLE_GAP_LE_PHY_CODED_MASK | BLE_GAP_LE_PHY_1M_MASK /*| BLE_GAP_LE_PHY_2M_MASK */; -/* Define a class to handle the callbacks for client connection events */ +/** Define a class to handle the callbacks for client connection events */ class ClientCallbacks : public NimBLEClientCallbacks { - void onConnect(NimBLEClient* pClient) { - Serial.printf("Connected\n"); - }; + void onConnect(NimBLEClient* pClient) override { Serial.printf("Connected\n"); }; - void onDisconnect(NimBLEClient* pClient, int reason) { - Serial.printf("%s Disconnected, reason = %d - Starting scan\n", - pClient->getPeerAddress().toString().c_str(), reason); + void onDisconnect(NimBLEClient* pClient, int reason) override { + Serial.printf("%s Disconnected, reason = %d - Starting scan\n", pClient->getPeerAddress().toString().c_str(), reason); NimBLEDevice::getScan()->start(scanTime); - }; -}; - - -/* Define a class to handle the callbacks when advertisements are received */ -class scanCallbacks: public NimBLEScanCallbacks { + } +} clientCallbacks; - void onResult(const NimBLEAdvertisedDevice* advertisedDevice) { +/** Define a class to handle the callbacks when advertisements are received */ +class scanCallbacks : public NimBLEScanCallbacks { + void onResult(const NimBLEAdvertisedDevice* advertisedDevice) override { Serial.printf("Advertised Device found: %s\n", advertisedDevice->toString().c_str()); - if(advertisedDevice->isAdvertisingService(NimBLEUUID("ABCD"))) - { + if (advertisedDevice->isAdvertisingService(NimBLEUUID("ABCD"))) { Serial.printf("Found Our Service\n"); - /* Ready to connect now */ doConnect = true; - /* Save the device reference in a global for the client to use*/ + /** Save the device reference in a global for the client to use*/ advDevice = advertisedDevice; - /* stop scan before connecting */ + /** stop scan before connecting */ NimBLEDevice::getScan()->stop(); } } /** Callback to process the results of the completed scan or restart it */ - void onScanEnd(const NimBLEScanResults& results, int reason) { - Serial.print("Scan Ended; reason = "); Serial.println(reason); - } -}; - + void onScanEnd(const NimBLEScanResults& results, int rc) override { Serial.printf("Scan Ended\n"); } +} scanCallbacks; -/* Handles the provisioning of clients and connects / interfaces with the server */ +/** Handles the provisioning of clients and connects / interfaces with the server */ bool connectToServer() { NimBLEClient* pClient = nullptr; pClient = NimBLEDevice::createClient(); - pClient->setClientCallbacks(new ClientCallbacks, false); + pClient->setClientCallbacks(&clientCallbacks, false); - /* Set the PHY's to use for this connection. This is a bitmask that represents the PHY's: + /** + * Set the PHY's to use for this connection. This is a bitmask that represents the PHY's: * * 0x01 BLE_GAP_LE_PHY_1M_MASK * * 0x02 BLE_GAP_LE_PHY_2M_MASK * * 0x04 BLE_GAP_LE_PHY_CODED_MASK @@ -80,27 +72,22 @@ bool connectToServer() { pClient->setConnectTimeout(10 * 1000); if (!pClient->connect(advDevice)) { - /* Created a client but failed to connect, don't need to keep it as it has no data */ + /** Created a client but failed to connect, don't need to keep it as it has no data */ NimBLEDevice::deleteClient(pClient); Serial.printf("Failed to connect, deleted client\n"); return false; } - Serial.printf("Connected to: %s RSSI: %d\n", - pClient->getPeerAddress().toString().c_str(), - pClient->getRssi()); + Serial.printf("Connected to: %s RSSI: %d\n", pClient->getPeerAddress().toString().c_str(), pClient->getRssi()); - /* Now we can read/write/subscribe the charateristics of the services we are interested in */ - NimBLERemoteService* pSvc = nullptr; + /** Now we can read/write/subscribe the characteristics of the services we are interested in */ + NimBLERemoteService* pSvc = nullptr; NimBLERemoteCharacteristic* pChr = nullptr; pSvc = pClient->getService(SERVICE_UUID); - if (pSvc) { pChr = pSvc->getCharacteristic(CHARACTERISTIC_UUID); - if (pChr) { - // Read the value of the characteristic. if (pChr->canRead()) { std::string value = pChr->readValue(); Serial.printf("Characteristic value: %s\n", value.c_str()); @@ -116,27 +103,29 @@ bool connectToServer() { return true; } -void setup () { +void setup() { Serial.begin(115200); Serial.printf("Starting NimBLE Client\n"); - /* Initialize NimBLE, no device name specified as we are not advertising */ - NimBLEDevice::init(""); - NimBLEScan* pScan = NimBLEDevice::getScan(); + /** Initialize NimBLE and set the device name */ + NimBLEDevice::init("NimBLE Extended Client"); - /* create a callback that gets called when advertisers are found */ - pScan->setScanCallbacks(new scanCallbacks()); + /** Create aNimBLE Scan instance and set the callbacks for scan events */ + NimBLEScan* pScan = NimBLEDevice::getScan(); + pScan->setScanCallbacks(&scanCallbacks); - /* Set scan interval (how often) and window (how long) in milliseconds */ + /** Set scan interval (how often) and window (how long) in milliseconds */ pScan->setInterval(97); pScan->setWindow(67); - /* Active scan will gather scan response data from advertisers + /** + * Active scan will gather scan response data from advertisers * but will use more energy from both devices */ pScan->setActiveScan(true); - /* Start scanning for advertisers for the scan time specified (in milliseconds) 0 = forever + /** + * Start scanning for advertisers for the scan time specified (in milliseconds) 0 = forever * Optional callback for when scanning stops. */ pScan->start(scanTime); @@ -144,10 +133,9 @@ void setup () { Serial.printf("Scanning for peripherals\n"); } -void loop () { - /* Loop here until we find a device we want to connect to */ +void loop() { + /** Loop here until we find a device we want to connect to */ if (doConnect) { - /* Found a device we want to connect to, do it now */ if (connectToServer()) { Serial.printf("Success!, scanning for more!\n"); } else { 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 df08d560..78e810ef 100644 --- a/examples/Bluetooth_5/NimBLE_extended_scan/NimBLE_extended_scan.ino +++ b/examples/Bluetooth_5/NimBLE_extended_scan/NimBLE_extended_scan.ino @@ -5,38 +5,42 @@ * * Created: on November 28, 2024 * Author: H2zero - * -*/ + */ #include #include +#if !CONFIG_BT_NIMBLE_EXT_ADV +# error Must enable extended advertising, see nimconfig.h file. +#endif -static uint32_t scanTime = 10 * 1000; // In milliseconds, 0 = scan forever -static NimBLEScan::Phy scanPhy = NimBLEScan::Phy::SCAN_ALL; +static uint32_t scanTime = 10 * 1000; // In milliseconds, 0 = scan forever +static NimBLEScan::Phy scanPhy = NimBLEScan::Phy::SCAN_ALL; -// Define a class to handle the callbacks when advertisements are received -class scanCallbacks: public NimBLEScanCallbacks { +/** Define a class to handle the callbacks when advertisements are received */ +class ScanCallbacks : public NimBLEScanCallbacks { void onResult(const NimBLEAdvertisedDevice* advertisedDevice) { - Serial.printf("Advertised Device found: %s\n PHY1: %d\n PHY2: %d\n", advertisedDevice->toString().c_str(), - advertisedDevice->getPrimaryPhy(), advertisedDevice->getSecondaryPhy()); + Serial.printf("Advertised Device found: %s\n PHY1: %d\n PHY2: %d\n", + advertisedDevice->toString().c_str(), + advertisedDevice->getPrimaryPhy(), + advertisedDevice->getSecondaryPhy()); } - // Callback to process the results of the completed scan or restart it + /** Callback to process the results of the completed scan or restart it */ void onScanEnd(const NimBLEScanResults& scanResults, int reason) { Serial.printf("Scan Ended, reason: %d; found %d devices\n", reason, scanResults.getCount()); - // Try Different PHY's + /** Try Different PHY's */ switch (scanPhy) { case NimBLEScan::Phy::SCAN_ALL: - Serial.prinln("Scanning only 1M PHY"); + Serial.printf("Scanning only 1M PHY\n"); scanPhy = NimBLEScan::Phy::SCAN_1M; break; case NimBLEScan::Phy::SCAN_1M: - Serial.println("Scanning only CODED PHY"); + Serial.printf("Scanning only CODED PHY\n"); scanPhy = NimBLEScan::Phy::SCAN_CODED; break; case NimBLEScan::Phy::SCAN_CODED: - Serial.println("Scanning all PHY's"); + Serial.printf("Scanning all PHY's\n"); scanPhy = NimBLEScan::Phy::SCAN_ALL; break; } @@ -45,30 +49,27 @@ class scanCallbacks: public NimBLEScanCallbacks { pScan->setPhy(scanPhy); pScan->start(scanTime); } -} scanCb; +} scanCallbacks; void setup() { - Serial.begin(115200); Serial.printf("Starting Extended Scanner\n"); - // Initialize NimBLE, no device name specified as we are not advertising - NimBLEDevice::init(""); + /** Initialize NimBLE and set the device name */ + NimBLEDevice::init("NimBLE Extended Scanner"); NimBLEScan* pScan = NimBLEDevice::getScan(); - // Set the callbacks that the scanner will call on events. - pScan->setScanCallbacks(&scanCb); + /** Set the callbacks that the scanner will call on events. */ + pScan->setScanCallbacks(&scanCallbacks); - // Use active scanning to obtain scan response data from advertisers + /** Use active scanning to obtain scan response data from advertisers */ pScan->setActiveScan(true); - // Set the initial PHY's to scan on, default is SCAN_ALL + /** Set the initial PHY's to scan on, default is SCAN_ALL */ pScan->setPhy(scanPhy); - // Start scanning for scanTime, 0 = forever + /** Start scanning for scanTime */ pScan->start(scanTime); - Serial.println("Scanning for peripherals"); + Serial.printf("Scanning for peripherals\n"); } -void loop() { - delay(2000); -} +void loop() {} 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 029469fd..70160144 100644 --- a/examples/Bluetooth_5/NimBLE_extended_server/NimBLE_extended_server.ino +++ b/examples/Bluetooth_5/NimBLE_extended_server/NimBLE_extended_server.ino @@ -1,4 +1,5 @@ -/** NimBLE Extended Advertiser Demo: +/** + * NimBLE Extended Server Demo: * * Demonstrates the Bluetooth 5.x extended advertising capabilities. * @@ -9,138 +10,141 @@ * * Created: on April 2 2022 * Author: H2zero - * -*/ + */ -#include "NimBLEDevice.h" +#include +#include #if !CONFIG_BT_NIMBLE_EXT_ADV -# error Must enable extended advertising, see nimconfig.h file. +# error Must enable extended advertising, see nimconfig.h file. #endif #ifdef ESP_PLATFORM -#include "esp_sleep.h" +# include "esp_sleep.h" #endif #define SERVICE_UUID "ABCD" #define CHARACTERISTIC_UUID "1234" -/* Time in milliseconds to advertise */ +/** Time in milliseconds to advertise */ static uint32_t advTime = 5000; -/* Time to sleep between advertisements */ +/** Time to sleep between advertisements */ static uint32_t sleepSeconds = 20; -/* Primary PHY used for advertising, can be one of BLE_HCI_LE_PHY_1M or BLE_HCI_LE_PHY_CODED */ +/** Primary PHY used for advertising, can be one of BLE_HCI_LE_PHY_1M or BLE_HCI_LE_PHY_CODED */ static uint8_t primaryPhy = BLE_HCI_LE_PHY_CODED; -/* Secondary PHY used for advertising and connecting, - * can be one of BLE_HCI_LE_PHY_1M, BLE_HCI_LE_PHY_2M or BLE_HCI_LE_PHY_CODED +/** + * Secondary PHY used for advertising and connecting, + * can be one of BLE_HCI_LE_PHY_1M, BLE_HCI_LE_PHY_2M or BLE_HCI_LE_PHY_CODED */ static uint8_t secondaryPhy = BLE_HCI_LE_PHY_1M; - -/* Handler class for server events */ -class ServerCallbacks: public NimBLEServerCallbacks { - void onConnect(NimBLEServer* pServer, NimBLEConnInfo& connInfo) { +/** Handler class for server events */ +class ServerCallbacks : public NimBLEServerCallbacks { + void onConnect(NimBLEServer* pServer, NimBLEConnInfo& connInfo) override { Serial.printf("Client connected:: %s\n", connInfo.getAddress().toString().c_str()); - }; + } - void onDisconnect(NimBLEServer* pServer, NimBLEConnInfo& connInfo, int reason) { - Serial.printf("Client disconnected - sleeping for %" PRIu32 "seconds\n", sleepSeconds); + void onDisconnect(NimBLEServer* pServer, NimBLEConnInfo& connInfo, int reason) override { + Serial.printf("Client disconnected - sleeping for %" PRIu32 " seconds\n", sleepSeconds); #ifdef ESP_PLATFORM esp_deep_sleep_start(); #else - systemRestart(); // nRF platforms restart then sleep via delay in setup. + systemRestart(); // nRF platforms restart then sleep via delay in setup. #endif - }; -}; + } +} serverCallbacks; -/* Callback class to handle advertising events */ -class advertisingCallbacks: public NimBLEExtAdvertisingCallbacks { - void onStopped(NimBLEExtAdvertising* pAdv, int reason, uint8_t inst_id) { +/** Callback class to handle advertising events */ +class AdvertisingCallbacks : public NimBLEExtAdvertisingCallbacks { + void onStopped(NimBLEExtAdvertising* pAdv, int reason, uint8_t instId) override { /* Check the reason advertising stopped, don't sleep if client is connecting */ - printf("Advertising instance %u stopped\n", inst_id); + Serial.printf("Advertising instance %u stopped\n", instId); switch (reason) { case 0: - printf("Client connecting\n"); + Serial.printf("Client connecting\n"); return; case BLE_HS_ETIMEOUT: - printf("Time expired - sleeping for %" PRIu32 "seconds\n", sleepSeconds); + Serial.printf("Time expired - sleeping for %" PRIu32 " seconds\n", sleepSeconds); break; default: break; } + #ifdef ESP_PLATFORM esp_deep_sleep_start(); #else systemRestart(); // nRF platforms restart then sleep via delay in setup. #endif } -}; +} advertisingCallbacks; -void setup () { - Serial.begin(115200); +void setup() { #ifndef ESP_PLATFORM delay(sleepSeconds * 1000); // system ON sleep mode for nRF platforms to simulate the esp deep sleep with timer wakeup #endif + Serial.begin(115200); + /** Initialize NimBLE and set the device name */ NimBLEDevice::init("Extended advertiser"); - /* Create the server and add the services/characteristics/descriptors */ - NimBLEServer *pServer = NimBLEDevice::createServer(); - pServer->setCallbacks(new ServerCallbacks); + /** Create the server and add the services/characteristics/descriptors */ + NimBLEServer* pServer = NimBLEDevice::createServer(); + pServer->setCallbacks(&serverCallbacks); - NimBLEService *pService = pServer->createService(SERVICE_UUID); - NimBLECharacteristic *pCharacteristic = pService->createCharacteristic(CHARACTERISTIC_UUID, - NIMBLE_PROPERTY::READ | - NIMBLE_PROPERTY::WRITE | - NIMBLE_PROPERTY::NOTIFY); + NimBLEService* pService = pServer->createService(SERVICE_UUID); + NimBLECharacteristic* pCharacteristic = + pService->createCharacteristic(CHARACTERISTIC_UUID, + NIMBLE_PROPERTY::READ | NIMBLE_PROPERTY::WRITE | NIMBLE_PROPERTY::NOTIFY); pCharacteristic->setValue("Hello World"); - /* Start the services */ + /** Start the service */ pService->start(); - /* - * Create an extended advertisement with the instance ID 0 and set the PHY's. - * Multiple instances can be added as long as the instance ID is incremented. - */ + /** + * Create an extended advertisement with the instance ID 0 and set the PHY's. + * Multiple instances can be added as long as the instance ID is incremented. + */ NimBLEExtAdvertisement extAdv(primaryPhy, secondaryPhy); - /* Set the advertisement as connectable */ + /** Set the advertisement as connectable */ extAdv.setConnectable(true); - /* As per Bluetooth specification, extended advertising cannot be both scannable and connectable */ + /** As per Bluetooth specification, extended advertising cannot be both scannable and connectable */ extAdv.setScannable(false); // The default is false, set here for demonstration. - /* Extended advertising allows for 251 bytes (minus header bytes ~20) in a single advertisement or up to 1650 if chained */ - extAdv.setServiceData(NimBLEUUID(SERVICE_UUID), std::string("Extended Advertising Demo.\r\n" - "Extended advertising allows for " - "251 bytes of data in a single advertisement,\r\n" - "or up to 1650 bytes with chaining.\r\n" - "This example message is 226 bytes long " - "and is using CODED_PHY for long range.")); + /** Extended advertising allows for 251 bytes (minus header bytes ~20) in a single advertisement or up to 1650 if chained */ + extAdv.setServiceData(NimBLEUUID(SERVICE_UUID), + std::string("Extended Advertising Demo.\r\n" + "Extended advertising allows for " + "251 bytes of data in a single advertisement,\r\n" + "or up to 1650 bytes with chaining.\r\n" + "This example message is 226 bytes long " + "and is using CODED_PHY for long range.")); extAdv.setCompleteServices16({NimBLEUUID(SERVICE_UUID)}); + extAdv.setName("Extended advertiser"); - /* When extended advertising is enabled `NimBLEDevice::getAdvertising` returns a pointer to `NimBLEExtAdvertising */ + /** When extended advertising is enabled `NimBLEDevice::getAdvertising` returns a pointer to `NimBLEExtAdvertising */ NimBLEExtAdvertising* pAdvertising = NimBLEDevice::getAdvertising(); - /* Set the callbacks for advertising events */ - pAdvertising->setCallbacks(new advertisingCallbacks); + /** Set the callbacks for advertising events */ + pAdvertising->setCallbacks(&advertisingCallbacks); - /* - * NimBLEExtAdvertising::setInstanceData takes the instance ID and - * a reference to a `NimBLEExtAdvertisement` object. This sets the data - * that will be advertised for this instance ID, returns true if successful. + /** + * NimBLEExtAdvertising::setInstanceData takes the instance ID and + * a reference to a `NimBLEExtAdvertisement` object. This sets the data + * that will be advertised for this instance ID, returns true if successful. * - * Note: It is safe to create the advertisement as a local variable if setInstanceData - * is called before exiting the code block as the data will be copied. + * Note: It is safe to create the advertisement as a local variable if setInstanceData + * is called before exiting the code block as the data will be copied. */ if (pAdvertising->setInstanceData(0, extAdv)) { - /* - * `NimBLEExtAdvertising::start` takes the advertisement instance ID to start - * and a duration in milliseconds or a max number of advertisements to send (or both). + /** + * NimBLEExtAdvertising::start takes the advertisement instance ID to start + * and a duration in milliseconds or a max number of advertisements to send (or both). */ if (pAdvertising->start(0, advTime)) { Serial.printf("Started advertising\n"); @@ -148,7 +152,7 @@ void setup () { Serial.printf("Failed to start advertising\n"); } } else { - Serial.printf("Failed to register advertisment data\n"); + Serial.printf("Failed to register advertisement data\n"); } #ifdef ESP_PLATFORM @@ -156,5 +160,4 @@ void setup () { #endif } -void loop () { -} \ No newline at end of file +void loop() {} 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 f340f5a9..f888423c 100644 --- a/examples/Bluetooth_5/NimBLE_multi_advertiser/NimBLE_multi_advertiser.ino +++ b/examples/Bluetooth_5/NimBLE_multi_advertiser/NimBLE_multi_advertiser.ino @@ -1,4 +1,5 @@ -/** NimBLE Multi Advertiser Demo: +/** + * NimBLE Multi Advertiser Demo: * * Demonstrates the Bluetooth 5.x extended advertising capabilities. * @@ -9,161 +10,170 @@ * * Created: on April 9 2022 * Author: H2zero - * -*/ - -/**************************************************** - * For use with ESP32C3, ESP32S3, ESP32H2 ONLY! * - /**************************************************/ + */ +#include #include #if !CONFIG_BT_NIMBLE_EXT_ADV -# error Must enable extended advertising, see nimconfig.h file. +# error Must enable extended advertising, see nimconfig.h file. #endif -#include "esp_sleep.h" +#ifdef ESP_PLATFORM +# include "esp_sleep.h" +#endif #define SERVICE_UUID "ABCD" #define CHARACTERISTIC_UUID "1234" -/* Time in milliseconds to advertise */ +/** Time in milliseconds to advertise */ static uint32_t advTime = 5000; -/* Time to sleep between advertisements */ -static uint32_t sleepTime = 20; +/** Time to sleep between advertisements */ +static uint32_t sleepSeconds = 20; -/* Primary PHY used for advertising, can be one of BLE_HCI_LE_PHY_1M or BLE_HCI_LE_PHY_CODED */ +/** Primary PHY used for advertising, can be one of BLE_HCI_LE_PHY_1M or BLE_HCI_LE_PHY_CODED */ static uint8_t primaryPhy = BLE_HCI_LE_PHY_CODED; -/* Secondary PHY used for advertising and connecting, - * can be one of BLE_HCI_LE_PHY_1M, BLE_HCI_LE_PHY_2M or BLE_HCI_LE_PHY_CODED +/** + * Secondary PHY used for advertising and connecting, + * can be one of BLE_HCI_LE_PHY_1M, BLE_HCI_LE_PHY_2M or BLE_HCI_LE_PHY_CODED */ static uint8_t secondaryPhy = BLE_HCI_LE_PHY_1M; - -/* Handler class for server events */ -class ServerCallbacks: public NimBLEServerCallbacks { - void onConnect(NimBLEServer* pServer, NimBLEConnInfo& connInfo) { +/** Handler class for server events */ +class ServerCallbacks : public NimBLEServerCallbacks { + void onConnect(NimBLEServer* pServer, NimBLEConnInfo& connInfo) override { Serial.printf("Client connected: %s\n", connInfo.getAddress().toString().c_str()); - }; + } - void onDisconnect(NimBLEServer* pServer, NimBLEConnInfo& connInfo, int reason) { + void onDisconnect(NimBLEServer* pServer, NimBLEConnInfo& connInfo, int reason) override { Serial.printf("Client disconnected\n"); // if still advertising we won't sleep yet. if (!pServer->getAdvertising()->isAdvertising()) { - Serial.printf("Sleeping for %u seconds\n", sleepTime); + Serial.printf("Sleeping for %" PRIu32 " seconds\n", sleepSeconds); +#ifdef ESP_PLATFORM esp_deep_sleep_start(); +#else + systemRestart(); // nRF platforms restart then sleep via delay in setup. +#endif } - }; -}; + } +} serverCallbacks; -/* Callback class to handle advertising events */ -class advCallbacks: public NimBLEExtAdvertisingCallbacks { - void onStopped(NimBLEExtAdvertising* pAdv, int reason, uint8_t inst_id) { +/** Callback class to handle advertising events */ +class AdvCallbacks : public NimBLEExtAdvertisingCallbacks { + void onStopped(NimBLEExtAdvertising* pAdv, int reason, uint8_t instId) override { /* Check the reason advertising stopped, don't sleep if client is connecting */ - Serial.printf("Advertising instance %u stopped\n", inst_id); + Serial.printf("Advertising instance %u stopped\n", instId); switch (reason) { case 0: Serial.printf(" client connecting\n"); return; case BLE_HS_ETIMEOUT: - Serial.printf("Time expired - sleeping for %u seconds\n", sleepTime); + Serial.printf("Time expired - sleeping for %" PRIu32 " seconds\n", sleepSeconds); break; default: break; } +#ifdef ESP_PLATFORM esp_deep_sleep_start(); +#else + systemRestart(); // nRF platforms restart then sleep via delay in setup. +#endif } bool m_updatedSR = false; - void onScanRequest(NimBLEExtAdvertising* pAdv, uint8_t inst_id, NimBLEAddress addr) { - Serial.printf("Scan request for instance %u\n", inst_id); + void onScanRequest(NimBLEExtAdvertising* pAdv, uint8_t instId, NimBLEAddress addr) override { + Serial.printf("Scan request for instance %u\n", instId); // if the data has already been updated we don't need to change it again. if (!m_updatedSR) { Serial.printf("Updating scan data\n"); NimBLEExtAdvertisement sr; sr.setServiceData(NimBLEUUID(SERVICE_UUID), std::string("Hello from scan response!")); - pAdv->setScanResponseData(inst_id, sr); + pAdv->setScanResponseData(instId, sr); m_updatedSR = true; } } -}; +} advCallbacks; -void setup () { +void setup() { +#ifndef ESP_PLATFORM + delay(sleepSeconds * 1000); // system ON sleep mode for nRF platforms to simulate the esp deep sleep with timer wakeup +#endif Serial.begin(115200); + /** Initialize NimBLE and set the device name */ NimBLEDevice::init("Multi advertiser"); - /* Create a server for our legacy advertiser */ - NimBLEServer *pServer = NimBLEDevice::createServer(); - pServer->setCallbacks(new ServerCallbacks); + /** Create a server for our legacy advertiser */ + NimBLEServer* pServer = NimBLEDevice::createServer(); + pServer->setCallbacks(&serverCallbacks); - NimBLEService *pService = pServer->createService(SERVICE_UUID); - NimBLECharacteristic *pCharacteristic = pService->createCharacteristic(CHARACTERISTIC_UUID, - NIMBLE_PROPERTY::READ | - NIMBLE_PROPERTY::WRITE | - NIMBLE_PROPERTY::NOTIFY); + NimBLEService* pService = pServer->createService(SERVICE_UUID); + NimBLECharacteristic* pCharacteristic = + pService->createCharacteristic(CHARACTERISTIC_UUID, + NIMBLE_PROPERTY::READ | NIMBLE_PROPERTY::WRITE | NIMBLE_PROPERTY::NOTIFY); pCharacteristic->setValue("Hello World"); - /* Start the service */ + /** Start the service */ pService->start(); - /* Create our multi advertising instances */ + /** Create our multi advertising instances */ - // extended scannable instance advertising on coded and 1m PHY's. + /** extended scannable instance advertising on coded and 1m PHY's. */ NimBLEExtAdvertisement extScannable(primaryPhy, secondaryPhy); - // Legacy advertising as a connectable device. + /** Legacy advertising as a connectable device. */ NimBLEExtAdvertisement legacyConnectable; - // Optional scan response data. + /** Optional scan response data. */ NimBLEExtAdvertisement legacyScanResponse; - /* As per Bluetooth specification, extended advertising cannot be both scannable and connectable */ + /** As per Bluetooth specification, extended advertising cannot be both scannable and connectable */ extScannable.setScannable(true); extScannable.setConnectable(false); - /* Set the initial data */ + /** Set the initial data */ extScannable.setServiceData(NimBLEUUID(SERVICE_UUID), std::string("Scan me!")); - /* enable the scan response callback, we will use this to update the data. */ + /** Enable the scan response callback, we will use this to update the data. */ extScannable.enableScanRequestCallback(true); - /* Optional custom address for this advertisment. */ + /** Optional custom address for this advertisment. */ legacyConnectable.setAddress(NimBLEAddress("DE:AD:BE:EF:BA:AD")); - /* Set the advertising data. */ + /** Set the advertising data. */ legacyConnectable.setName("Legacy"); legacyConnectable.setCompleteServices16({NimBLEUUID(SERVICE_UUID)}); - /* Set the legacy and connectable flags. */ + /** Set the legacy and connectable flags. */ legacyConnectable.setLegacyAdvertising(true); legacyConnectable.setConnectable(true); - /* Put some data in the scan response if desired. */ + /** Put some data in the scan response if desired. */ legacyScanResponse.setServiceData(NimBLEUUID(SERVICE_UUID), "Legacy SR"); - /* Get the advertising ready */ + /** Get the advertising ready */ NimBLEExtAdvertising* pAdvertising = NimBLEDevice::getAdvertising(); - /* Set the callbacks to handle advertising events */ - pAdvertising->setCallbacks(new advCallbacks); + /** Set the callbacks to handle advertising events */ + pAdvertising->setCallbacks(&advCallbacks); - /* Set instance data. - * Up to 5 instances can be used if configured in menuconfig, instance 0 is always available. + /** + * Set instance data. + * Up to 5 instances can be used if configured in menuconfig, instance 0 is always available. * - * We will set the extended scannable data on instance 0 and the legacy data on instance 1. - * Note that the legacy scan response data needs to be set to the same instance (1). + * We will set the extended scannable data on instance 0 and the legacy data on instance 1. + * Note that the legacy scan response data needs to be set to the same instance (1). */ - if (pAdvertising->setInstanceData( 0, extScannable ) && - pAdvertising->setInstanceData( 1, legacyConnectable ) && - pAdvertising->setScanResponseData( 1, legacyScanResponse )) { - /* - * `NimBLEExtAdvertising::start` takes the advertisement instance ID to start - * and a duration in milliseconds or a max number of advertisements to send (or both). + if (pAdvertising->setInstanceData(0, extScannable) && pAdvertising->setInstanceData(1, legacyConnectable) && + pAdvertising->setScanResponseData(1, legacyScanResponse)) { + /** + * NimBLEExtAdvertising::start takes the advertisement instance ID to start + * and a duration in milliseconds or a max number of advertisements to send (or both). */ if (pAdvertising->start(0, advTime) && pAdvertising->start(1, advTime)) { Serial.printf("Started advertising\n"); @@ -171,11 +181,12 @@ void setup () { Serial.printf("Failed to start advertising\n"); } } else { - Serial.printf("Failed to register advertisment data\n"); + Serial.printf("Failed to register advertisement data\n"); } - esp_sleep_enable_timer_wakeup(sleepTime * 1000000); +#ifdef ESP_PLATFORM + esp_sleep_enable_timer_wakeup(sleepSeconds * 1000000); +#endif } -void loop(){ -} +void loop() {} diff --git a/examples/NimBLE_Async_Client/NimBLE_Async_Client.ino b/examples/NimBLE_Async_Client/NimBLE_Async_Client.ino index f852b54f..dce3ad67 100644 --- a/examples/NimBLE_Async_Client/NimBLE_Async_Client.ino +++ b/examples/NimBLE_Async_Client/NimBLE_Async_Client.ino @@ -6,64 +6,65 @@ * * Created: on November 4, 2024 * Author: H2zero - * */ +#include #include static constexpr uint32_t scanTimeMs = 5 * 1000; class ClientCallbacks : public NimBLEClientCallbacks { - void onConnect(NimBLEClient* pClient) { + void onConnect(NimBLEClient* pClient) override { Serial.printf("Connected to: %s\n", pClient->getPeerAddress().toString().c_str()); } - void onDisconnect(NimBLEClient* pClient, int reason) { + void onDisconnect(NimBLEClient* pClient, int reason) override { Serial.printf("%s Disconnected, reason = %d - Starting scan\n", pClient->getPeerAddress().toString().c_str(), reason); NimBLEDevice::getScan()->start(scanTimeMs); } -} clientCB; +} clientCallbacks; -class scanCallbacks : public NimBLEScanCallbacks { - void onResult(const NimBLEAdvertisedDevice* advertisedDevice) { +class ScanCallbacks : public NimBLEScanCallbacks { + void onResult(const NimBLEAdvertisedDevice* advertisedDevice) override { Serial.printf("Advertised Device found: %s\n", advertisedDevice->toString().c_str()); if (advertisedDevice->haveName() && advertisedDevice->getName() == "NimBLE-Server") { - Serial.println("Found Our Device"); + Serial.printf("Found Our Device\n"); + /** Async connections can be made directly in the scan callbacks */ auto pClient = NimBLEDevice::getDisconnectedClient(); if (!pClient) { pClient = NimBLEDevice::createClient(advertisedDevice->getAddress()); if (!pClient) { - Serial.println("Failed to create client"); + Serial.printf("Failed to create client\n"); return; } } - pClient->setClientCallbacks(&clientCB, false); + pClient->setClientCallbacks(&clientCallbacks, false); if (!pClient->connect(true, true, false)) { // delete attributes, async connect, no MTU exchange NimBLEDevice::deleteClient(pClient); - Serial.println("Failed to connect"); + Serial.printf("Failed to connect\n"); return; } } } - void onScanEnd(const NimBLEScanResults& results, int reason) { - Serial.print("Scan Ended; reason = "); Serial.println(reason); + void onScanEnd(const NimBLEScanResults& results, int reason) override { + Serial.printf("Scan Ended\n"); NimBLEDevice::getScan()->start(scanTimeMs); } -}; +} scanCallbacks; void setup() { Serial.begin(115200); - Serial.println("Starting NimBLE Client"); - NimBLEDevice::init(""); + Serial.printf("Starting NimBLE Async Client\n"); + NimBLEDevice::init("Async-Client"); NimBLEDevice::setPower(3); /** +3db */ NimBLEScan* pScan = NimBLEDevice::getScan(); - pScan->setScanCallbacks(new scanCallbacks()); + pScan->setScanCallbacks(&scanCallbacks); pScan->setInterval(45); - pScan->setWindow(15); + pScan->setWindow(45); pScan->setActiveScan(true); pScan->start(scanTimeMs); } @@ -71,12 +72,12 @@ void setup() { void loop() { delay(1000); auto pClients = NimBLEDevice::getConnectedClients(); - if (pClients.size() == 0) { + if (!pClients.size()) { return; } for (auto& pClient : pClients) { - Serial.println(pClient->toString().c_str()); + Serial.printf("%s\n", pClient->toString().c_str()); NimBLEDevice::deleteClient(pClient); } diff --git a/examples/NimBLE_Client/NimBLE_Client.ino b/examples/NimBLE_Client/NimBLE_Client.ino index 4b0b25a6..27111816 100644 --- a/examples/NimBLE_Client/NimBLE_Client.ino +++ b/examples/NimBLE_Client/NimBLE_Client.ino @@ -1,96 +1,62 @@ -/** NimBLE_Server Demo: +/** NimBLE_Client Demo: * * Demonstrates many of the available features of the NimBLE client library. * * Created: on March 24 2020 * Author: H2zero - * -*/ + */ +#include #include static const NimBLEAdvertisedDevice* advDevice; - -static bool doConnect = false; -static uint32_t scanTime = 0 * 1000; // In milliseconds, 0 = scan forever - +static bool doConnect = false; +static uint32_t scanTime = 5000; /** scan time in milliseconds, 0 = scan forever */ /** None of these are required as they will be handled by the library with defaults. ** ** Remove as you see fit for your needs */ class ClientCallbacks : public NimBLEClientCallbacks { - void onConnect(NimBLEClient* pClient) { - Serial.println("Connected"); - /** After connection we should change the parameters if we don't need fast response times. - * These settings are 150ms interval, 0 latency, 450ms timout. - * Timeout should be a multiple of the interval, minimum is 100ms. - * I find a multiple of 3-5 * the interval works best for quick response/reconnect. - * Min interval: 120 * 1.25ms = 150, Max interval: 120 * 1.25ms = 150, 0 latency, 60 * 10ms = 600ms timeout - */ - pClient->updateConnParams(120,120,0,60); - }; - - void onDisconnect(NimBLEClient* pClient, int reason) { - Serial.printf("%s Disconnected, reason = %d - Starting scan\n", - pClient->getPeerAddress().toString().c_str(), reason); - NimBLEDevice::getScan()->start(scanTime); - }; - - /** Called when the peripheral requests a change to the connection parameters. - * Return true to accept and apply them or false to reject and keep - * the currently used parameters. Default will return true. - */ - bool onConnParamsUpdateRequest(NimBLEClient* pClient, const ble_gap_upd_params* params) { - if(params->itvl_min < 24) { /** 1.25ms units */ - return false; - } else if(params->itvl_max > 40) { /** 1.25ms units */ - return false; - } else if(params->latency > 2) { /** Number of intervals allowed to skip */ - return false; - } else if(params->supervision_timeout > 100) { /** 10ms units */ - return false; - } + void onConnect(NimBLEClient* pClient) override { Serial.printf("Connected\n"); } - return true; - }; + void onDisconnect(NimBLEClient* pClient, int reason) override { + Serial.printf("%s Disconnected, reason = %d - Starting scan\n", pClient->getPeerAddress().toString().c_str(), reason); + NimBLEDevice::getScan()->start(scanTime, false, true); + } - /********************* Security handled here ********************** - ****** Note: these are the same return values as defaults ********/ - void onPassKeyEntry(NimBLEConnInfo& connInfo){ - Serial.println("Server Passkey Entry"); - /** This should prompt the user to enter the passkey displayed + /********************* Security handled here *********************/ + void onPassKeyEntry(NimBLEConnInfo& connInfo) override { + Serial.printf("Server Passkey Entry\n"); + /** + * This should prompt the user to enter the passkey displayed * on the peer device. */ NimBLEDevice::injectPassKey(connInfo, 123456); - }; + } - void onConfirmPasskey(NimBLEConnInfo& connInfo, uint32_t pass_key){ - Serial.print("The passkey YES/NO number: ");Serial.println(pass_key); + void onConfirmPasskey(NimBLEConnInfo& connInfo, uint32_t pass_key) override { + Serial.printf("The passkey YES/NO number: %" PRIu32 "\n", pass_key); /** Inject false if passkeys don't match. */ NimBLEDevice::injectConfirmPasskey(connInfo, true); - }; + } /** Pairing process complete, we can check the results in connInfo */ - void onAuthenticationComplete(NimBLEConnInfo& connInfo){ - if(!connInfo.isEncrypted()) { - Serial.println("Encrypt connection failed - disconnecting"); - /** Find the client with the connection handle provided in desc */ + void onAuthenticationComplete(NimBLEConnInfo& connInfo) override { + if (!connInfo.isEncrypted()) { + Serial.printf("Encrypt connection failed - disconnecting\n"); + /** Find the client with the connection handle provided in connInfo */ NimBLEDevice::getClientByHandle(connInfo.getConnHandle())->disconnect(); return; } } -}; - - -/** Define a class to handle the callbacks when advertisments are received */ -class scanCallbacks: public NimBLEScanCallbacks { - - void onResult(const NimBLEAdvertisedDevice* advertisedDevice) { - Serial.print("Advertised Device found: "); - Serial.println(advertisedDevice->toString().c_str()); - if(advertisedDevice->isAdvertisingService(NimBLEUUID("DEAD"))) - { - Serial.println("Found Our Service"); +} clientCB; + +/** Define a class to handle the callbacks when scan events are received */ +class scanCallbacks : public NimBLEScanCallbacks { + void onResult(const NimBLEAdvertisedDevice* advertisedDevice) override { + Serial.printf("Advertised Device found: %s\n", advertisedDevice->toString().c_str()); + if (advertisedDevice->isAdvertisingService(NimBLEUUID("DEAD"))) { + Serial.printf("Found Our Service\n"); /** stop scan before connecting */ NimBLEDevice::getScan()->stop(); /** Save the device reference in a global for the client to use*/ @@ -101,292 +67,241 @@ class scanCallbacks: public NimBLEScanCallbacks { } /** Callback to process the results of the completed scan or restart it */ - void onScanEnd(const NimBLEScanResults& results, int reason) { - Serial.print("Scan Ended; reason = "); Serial.println(reason); + void onScanEnd(const NimBLEScanResults& results, int reason) override { + Serial.printf("Scan Ended, reason: %d, device count: %d; Restarting scan\n", reason, results.getCount()); + NimBLEDevice::getScan()->start(scanTime, false, true); } -}; - +} scanCB; /** Notification / Indication receiving handler callback */ -void notifyCB(NimBLERemoteCharacteristic* pRemoteCharacteristic, uint8_t* pData, size_t length, bool isNotify){ - std::string str = (isNotify == true) ? "Notification" : "Indication"; - str += " from "; - /** NimBLEAddress and NimBLEUUID have std::string operators */ - str += std::string(pRemoteCharacteristic->getClient()->getPeerAddress()); - str += ": Service = " + std::string(pRemoteCharacteristic->getRemoteService()->getUUID()); - str += ", Characteristic = " + std::string(pRemoteCharacteristic->getUUID()); - str += ", Value = " + std::string((char*)pData, length); - Serial.println(str.c_str()); +void notifyCB(NimBLERemoteCharacteristic* pRemoteCharacteristic, uint8_t* pData, size_t length, bool isNotify) { + std::string str = (isNotify == true) ? "Notification" : "Indication"; + str += " from "; + str += pRemoteCharacteristic->getClient()->getPeerAddress().toString(); + str += ": Service = " + pRemoteCharacteristic->getRemoteService()->getUUID().toString(); + str += ", Characteristic = " + pRemoteCharacteristic->getUUID().toString(); + str += ", Value = " + std::string((char*)pData, length); + Serial.printf("%s\n", str.c_str()); } - -/** Create a single global instance of the callback class to be used by all clients */ -static ClientCallbacks clientCB; - - /** Handles the provisioning of clients and connects / interfaces with the server */ bool connectToServer() { NimBLEClient* pClient = nullptr; /** Check if we have a client we should reuse first **/ - if(NimBLEDevice::getCreatedClientCount()) { - /** Special case when we already know this device, we send false as the + 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. */ pClient = NimBLEDevice::getClientByPeerAddress(advDevice->getAddress()); - if(pClient){ - if(!pClient->connect(advDevice, false)) { - Serial.println("Reconnect failed"); + if (pClient) { + if (!pClient->connect(advDevice, false)) { + Serial.printf("Reconnect failed\n"); return false; } - Serial.println("Reconnected client"); - } - /** We don't already have a client that knows this device, - * we will check for a client that is disconnected that we can use. - */ - else { + Serial.printf("Reconnected client\n"); + } else { + /** + * We don't already have a client that knows this device, + * check for a client that is disconnected that we can use. + */ pClient = NimBLEDevice::getDisconnectedClient(); } } /** No client to reuse? Create a new one. */ - if(!pClient) { - if(NimBLEDevice::getCreatedClientCount() >= NIMBLE_MAX_CONNECTIONS) { - Serial.println("Max clients reached - no more connections available"); + if (!pClient) { + if (NimBLEDevice::getCreatedClientCount() >= NIMBLE_MAX_CONNECTIONS) { + Serial.printf("Max clients reached - no more connections available\n"); return false; } pClient = NimBLEDevice::createClient(); - Serial.println("New client created"); + Serial.printf("New client created\n"); pClient->setClientCallbacks(&clientCB, false); - /** Set initial connection parameters: These settings are 15ms interval, 0 latency, 120ms timout. + /** + * Set initial connection parameters: * These settings are safe for 3 clients to connect reliably, can go faster if you have less * connections. Timeout should be a multiple of the interval, minimum is 100ms. - * Min interval: 12 * 1.25ms = 15, Max interval: 12 * 1.25ms = 15, 0 latency, 51 * 10ms = 510ms timeout + * Min interval: 12 * 1.25ms = 15, Max interval: 12 * 1.25ms = 15, 0 latency, 150 * 10ms = 1500ms timeout */ - pClient->setConnectionParams(12,12,0,51); + pClient->setConnectionParams(12, 12, 0, 150); + /** Set how long we are willing to wait for the connection to complete (milliseconds), default is 30000. */ pClient->setConnectTimeout(5 * 1000); - if (!pClient->connect(advDevice)) { /** Created a client but failed to connect, don't need to keep it as it has no data */ NimBLEDevice::deleteClient(pClient); - Serial.println("Failed to connect, deleted client"); + Serial.printf("Failed to connect, deleted client\n"); return false; } } - if(!pClient->isConnected()) { + if (!pClient->isConnected()) { if (!pClient->connect(advDevice)) { - Serial.println("Failed to connect"); + Serial.printf("Failed to connect\n"); return false; } } - Serial.print("Connected to: "); - Serial.println(pClient->getPeerAddress().toString().c_str()); - Serial.print("RSSI: "); - Serial.println(pClient->getRssi()); + Serial.printf("Connected to: %s RSSI: %d\n", pClient->getPeerAddress().toString().c_str(), pClient->getRssi()); - /** Now we can read/write/subscribe the charateristics of the services we are interested in */ - NimBLERemoteService* pSvc = nullptr; + /** Now we can read/write/subscribe the characteristics of the services we are interested in */ + NimBLERemoteService* pSvc = nullptr; NimBLERemoteCharacteristic* pChr = nullptr; - NimBLERemoteDescriptor* pDsc = nullptr; + NimBLERemoteDescriptor* pDsc = nullptr; pSvc = pClient->getService("DEAD"); - if(pSvc) { /** make sure it's not null */ + if (pSvc) { pChr = pSvc->getCharacteristic("BEEF"); + } - if(pChr) { /** make sure it's not null */ - if(pChr->canRead()) { - Serial.print(pChr->getUUID().toString().c_str()); - Serial.print(" Value: "); - Serial.println(pChr->readValue().c_str()); - } + if (pChr) { + if (pChr->canRead()) { + Serial.printf("%s Value: %s\n", pChr->getUUID().toString().c_str(), pChr->readValue().c_str()); + } - if(pChr->canWrite()) { - if(pChr->writeValue("Tasty")) { - Serial.print("Wrote new value to: "); - Serial.println(pChr->getUUID().toString().c_str()); - } - else { - /** Disconnect if write failed */ - pClient->disconnect(); - return false; - } + if (pChr->canWrite()) { + if (pChr->writeValue("Tasty")) { + Serial.printf("Wrote new value to: %s\n", pChr->getUUID().toString().c_str()); + } else { + pClient->disconnect(); + return false; + } - if(pChr->canRead()) { - Serial.print("The value of: "); - Serial.print(pChr->getUUID().toString().c_str()); - Serial.print(" is now: "); - Serial.println(pChr->readValue().c_str()); - } + if (pChr->canRead()) { + Serial.printf("The value of: %s is now: %s\n", pChr->getUUID().toString().c_str(), pChr->readValue().c_str()); } + } - /** registerForNotify() has been removed and replaced with subscribe() / unsubscribe(). - * Subscribe parameter defaults are: notifications=true, notifyCallback=nullptr. - * Unsubscribe takes no parameters. - */ - if(pChr->canNotify()) { - //if(!pChr->registerForNotify(notifyCB)) { - if(!pChr->subscribe(true, notifyCB)) { - /** Disconnect if subscribe failed */ - pClient->disconnect(); - return false; - } + if (pChr->canNotify()) { + if (!pChr->subscribe(true, notifyCB)) { + pClient->disconnect(); + return false; } - else if(pChr->canIndicate()) { - /** Send false as first argument to subscribe to indications instead of notifications */ - //if(!pChr->registerForNotify(notifyCB, false)) { - if(!pChr->subscribe(false, notifyCB)) { - /** Disconnect if subscribe failed */ - pClient->disconnect(); - return false; - } + } else if (pChr->canIndicate()) { + /** Send false as first argument to subscribe to indications instead of notifications */ + if (!pChr->subscribe(false, notifyCB)) { + pClient->disconnect(); + return false; } } - } else { - Serial.println("DEAD service not found."); + Serial.printf("DEAD service not found.\n"); } pSvc = pClient->getService("BAAD"); - if(pSvc) { /** make sure it's not null */ + if (pSvc) { pChr = pSvc->getCharacteristic("F00D"); - - if(pChr) { /** make sure it's not null */ - if(pChr->canRead()) { - Serial.print(pChr->getUUID().toString().c_str()); - Serial.print(" Value: "); - Serial.println(pChr->readValue().c_str()); + if (pChr) { + if (pChr->canRead()) { + Serial.printf("%s Value: %s\n", pChr->getUUID().toString().c_str(), pChr->readValue().c_str()); } pDsc = pChr->getDescriptor(NimBLEUUID("C01D")); - if(pDsc) { /** make sure it's not null */ - Serial.print("Descriptor: "); - Serial.print(pDsc->getUUID().toString().c_str()); - Serial.print(" Value: "); - Serial.println(pDsc->readValue().c_str()); + if (pDsc) { + Serial.printf("Descriptor: %s Value: %s\n", pDsc->getUUID().toString().c_str(), pDsc->readValue().c_str()); } - if(pChr->canWrite()) { - if(pChr->writeValue("No tip!")) { - Serial.print("Wrote new value to: "); - Serial.println(pChr->getUUID().toString().c_str()); - } - else { - /** Disconnect if write failed */ + if (pChr->canWrite()) { + if (pChr->writeValue("No tip!")) { + Serial.printf("Wrote new value to: %s\n", pChr->getUUID().toString().c_str()); + } else { pClient->disconnect(); return false; } - if(pChr->canRead()) { - Serial.print("The value of: "); - Serial.print(pChr->getUUID().toString().c_str()); - Serial.print(" is now: "); - Serial.println(pChr->readValue().c_str()); + if (pChr->canRead()) { + Serial.printf("The value of: %s is now: %s\n", pChr->getUUID().toString().c_str(), pChr->readValue().c_str()); } } - /** registerForNotify() has been removed and replaced with subscribe() / unsubscribe(). - * Subscribe parameter defaults are: notifications=true, notifyCallback=nullptr, response=true. - * Unsubscribe parameter defaults are: response=true. - */ - if(pChr->canNotify()) { - //if(!pChr->registerForNotify(notifyCB)) { - if(!pChr->subscribe(true, notifyCB)) { - /** Disconnect if subscribe failed */ + if (pChr->canNotify()) { + if (!pChr->subscribe(true, notifyCB)) { pClient->disconnect(); return false; } - } - else if(pChr->canIndicate()) { + } else if (pChr->canIndicate()) { /** Send false as first argument to subscribe to indications instead of notifications */ - //if(!pChr->registerForNotify(notifyCB, false)) { - if(!pChr->subscribe(false, notifyCB)) { - /** Disconnect if subscribe failed */ + if (!pChr->subscribe(false, notifyCB)) { pClient->disconnect(); return false; } } } - } else { - Serial.println("BAAD service not found."); + Serial.printf("BAAD service not found.\n"); } - Serial.println("Done with this device!"); + Serial.printf("Done with this device!\n"); return true; } -void setup (){ +void setup() { Serial.begin(115200); - Serial.println("Starting NimBLE Client"); - /** Initialize NimBLE, no device name spcified as we are not advertising */ - NimBLEDevice::init(""); + Serial.printf("Starting NimBLE Client\n"); - /** Set the IO capabilities of the device, each option will trigger a different pairing method. - * BLE_HS_IO_KEYBOARD_ONLY - Passkey pairing + /** Initialize NimBLE and set the device name */ + NimBLEDevice::init("NimBLE-Client"); + + /** + * Set the IO capabilities of the device, each option will trigger a different pairing method. + * BLE_HS_IO_KEYBOARD_ONLY - Passkey pairing * BLE_HS_IO_DISPLAY_YESNO - Numeric comparison pairing * BLE_HS_IO_NO_INPUT_OUTPUT - DEFAULT setting - just works pairing */ - //NimBLEDevice::setSecurityIOCap(BLE_HS_IO_KEYBOARD_ONLY); // use passkey - //NimBLEDevice::setSecurityIOCap(BLE_HS_IO_DISPLAY_YESNO); //use numeric comparison + // NimBLEDevice::setSecurityIOCap(BLE_HS_IO_KEYBOARD_ONLY); // use passkey + // NimBLEDevice::setSecurityIOCap(BLE_HS_IO_DISPLAY_YESNO); //use numeric comparison - /** 2 different ways to set security - both calls achieve the same result. - * no bonding, no man in the middle protection, secure connections. - * + /** + * 2 different ways to set security - both calls achieve the same result. + * no bonding, no man in the middle protection, BLE secure connections. * These are the default values, only shown here for demonstration. */ - //NimBLEDevice::setSecurityAuth(false, false, true); - NimBLEDevice::setSecurityAuth(/*BLE_SM_PAIR_AUTHREQ_BOND | BLE_SM_PAIR_AUTHREQ_MITM |*/ BLE_SM_PAIR_AUTHREQ_SC); + // NimBLEDevice::setSecurityAuth(false, false, true); - /** Optional: set the transmit power, default is 3db */ -#ifdef ESP_PLATFORM - NimBLEDevice::setPower(ESP_PWR_LVL_P9); /** +9db */ -#else - NimBLEDevice::setPower(9); /** +9db */ -#endif + NimBLEDevice::setSecurityAuth(/*BLE_SM_PAIR_AUTHREQ_BOND | BLE_SM_PAIR_AUTHREQ_MITM |*/ BLE_SM_PAIR_AUTHREQ_SC); - /** create new scan */ + /** Optional: set the transmit power */ + NimBLEDevice::setPower(3); // 9dbm NimBLEScan* pScan = NimBLEDevice::getScan(); - /** create a callback that gets called when advertisers are found */ - pScan->setScanCallbacks(new scanCallbacks()); + /** Set the callbacks to call when scan events occur, no duplicates */ + pScan->setScanCallbacks(&scanCB, false); /** Set scan interval (how often) and window (how long) in milliseconds */ - pScan->setInterval(45); - pScan->setWindow(15); + pScan->setInterval(100); + pScan->setWindow(100); - /** Active scan will gather scan response data from advertisers + /** + * Active scan will gather scan response data from advertisers * but will use more energy from both devices */ pScan->setActiveScan(true); - /** Start scanning for advertisers for the scan time specified (in seconds) 0 = forever - * Optional callback for when scanning stops. - */ + + /** Start scanning for advertisers */ pScan->start(scanTime); + Serial.printf("Scanning for peripherals\n"); } - -void loop (){ +void loop() { /** Loop here until we find a device we want to connect to */ - while(!doConnect){ - delay(1); - } - - doConnect = false; + delay(10); + + if (doConnect) { + doConnect = false; + /** Found a device we want to connect to, do it now */ + if (connectToServer()) { + Serial.printf("Success! we should now be getting notifications, scanning for more!\n"); + } else { + Serial.printf("Failed to connect, starting scan\n"); + } - /** Found a device we want to connect to, do it now */ - if(connectToServer()) { - Serial.println("Success! we should now be getting notifications, scanning for more!"); - } else { - Serial.println("Failed to connect, starting scan"); + NimBLEDevice::getScan()->start(scanTime, false, true); } - - NimBLEDevice::getScan()->start(scanTime); } diff --git a/examples/NimBLE_Scan_Continuous/NimBLE_Scan_Continuous.ino b/examples/NimBLE_Scan_Continuous/NimBLE_Scan_Continuous.ino index 0fe44a3c..72d208fc 100644 --- a/examples/NimBLE_Scan_Continuous/NimBLE_Scan_Continuous.ino +++ b/examples/NimBLE_Scan_Continuous/NimBLE_Scan_Continuous.ino @@ -7,43 +7,43 @@ * When the scan timeout is reached the onScanEnd callback will be called and the scan will be restarted. * This will clear the duplicate cache in the controller and allow the same devices to be reported again. * - * Created: on January 31 2021 + * Created: on March 24 2020 * Author: H2zero */ -#include "NimBLEDevice.h" +#include +#include static constexpr uint32_t scanTime = 30 * 1000; // 30 seconds scan time. class scanCallbacks : public NimBLEScanCallbacks { - // Initial discovery, advertisement data only. + /** Initial discovery, advertisement data only. */ void onDiscovered(const NimBLEAdvertisedDevice* advertisedDevice) override { - Serial.printf("Discovered Device: %s\n", advertisedDevice->toString().c_str()); + printf("Discovered Device: %s\n", advertisedDevice->toString().c_str()); } - // If active scanning the result here will have the scan response data. - // If not active scanning then this will be the same as onDiscovered. + /** + * If active scanning the result here will have the scan response data. + * If not active scanning then this will be the same as onDiscovered. + */ void onResult(const NimBLEAdvertisedDevice* advertisedDevice) override { - Serial.printf("Device result: %s\n", advertisedDevice->toString().c_str()); + printf("Device result: %s\n", advertisedDevice->toString().c_str()); } void onScanEnd(const NimBLEScanResults& results, int reason) override { - Serial.printf("Scan ended reason = %d; restarting scan\n", reason); + printf("Scan ended reason = %d; restarting scan\n", reason); NimBLEDevice::getScan()->start(scanTime, false, true); } -} scanCallbacks; // create a callback class instance. +} scanCallbacks; void setup() { - Serial.begin(115200); 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->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(scanTime, false, true); // duration, not a continuation of last scan, restart to get all devices again. - Serial.println("Scanning..."); + printf("Scanning...\n"); } -void loop() { - delay(2000); -} +void loop() {} diff --git a/examples/NimBLE_Scan_Whitelist/NimBLE_Scan_whitelist.ino b/examples/NimBLE_Scan_Whitelist/NimBLE_Scan_whitelist.ino index 585e59c1..b5108757 100644 --- a/examples/NimBLE_Scan_Whitelist/NimBLE_Scan_whitelist.ino +++ b/examples/NimBLE_Scan_Whitelist/NimBLE_Scan_whitelist.ino @@ -5,63 +5,65 @@ * Author: h2zero */ +#include #include -int scanTime = 5 * 1000; // In milliseconds, 0 = scan forever +int scanTime = 5 * 1000; // In milliseconds, 0 = scan forever NimBLEScan* pBLEScan; -class MyAdvertisedDeviceCallbacks: public BLEAdvertisedDeviceCallbacks { - void onResult(BLEAdvertisedDevice* advertisedDevice) { - Serial.printf("Advertised Device: %s \n", advertisedDevice->toString().c_str()); - /* - * Here we add the device scanned to the whitelist based on service data but any - * advertised data can be used for your preffered data. - */ - if (advertisedDevice->haveServiceData()) { - /* If this is a device with data we want to capture, add it to the whitelist */ - if (advertisedDevice->getServiceData(NimBLEUUID("AABB")) != "") { - Serial.printf("Adding %s to whitelist\n", std::string(advertisedDevice->getAddress()).c_str()); - NimBLEDevice::whiteListAdd(advertisedDevice->getAddress()); - } +class ScanCallbacks : public NimBLEScanCallbacks { + void onResult(const NimBLEAdvertisedDevice* advertisedDevice) override { + Serial.printf("Advertised Device: %s \n", advertisedDevice->toString().c_str()); + /* + * Here we add the device scanned to the whitelist based on service data but any + * advertised data can be used for your preferred data. + */ + if (advertisedDevice->haveServiceData()) { + /* If this is a device with data we want to capture, add it to the whitelist */ + if (advertisedDevice->getServiceData(NimBLEUUID("AABB")) != "") { + Serial.printf("Adding %s to whitelist\n", std::string(advertisedDevice->getAddress()).c_str()); + NimBLEDevice::whiteListAdd(advertisedDevice->getAddress()); + } + } } - } -}; +} scanCallbacks; void setup() { - Serial.begin(115200); - Serial.println("Scanning..."); + Serial.begin(115200); + Serial.println("Scanning..."); - NimBLEDevice::init(""); - pBLEScan = NimBLEDevice::getScan(); - pBLEScan->setScanCallbacks(new MyAdvertisedDeviceCallbacks()); - pBLEScan->setActiveScan(true); - pBLEScan->setInterval(100); - pBLEScan->setFilterPolicy(BLE_HCI_SCAN_FILT_NO_WL); - pBLEScan->setWindow(99); + NimBLEDevice::init(""); + pBLEScan = NimBLEDevice::getScan(); + pBLEScan->setScanCallbacks(&scanCallbacks); + pBLEScan->setActiveScan(true); + pBLEScan->setInterval(100); + pBLEScan->setFilterPolicy(BLE_HCI_SCAN_FILT_NO_WL); + pBLEScan->setWindow(99); } void loop() { - NimBLEScanResults foundDevices = pBLEScan->getResults(scanTime, false); - Serial.print("Devices found: "); - Serial.println(foundDevices.getCount()); - Serial.println("Scan done!"); + NimBLEScanResults foundDevices = pBLEScan->getResults(scanTime, false); + Serial.print("Devices found: "); + Serial.println(foundDevices.getCount()); + Serial.println("Scan done!"); - Serial.println("Whitelist contains:"); - for (auto i=0; i 0) { - if (foundDevices.getCount() == 0) { - pBLEScan->setFilterPolicy(BLE_HCI_SCAN_FILT_NO_WL); - } else { - pBLEScan->setFilterPolicy(BLE_HCI_SCAN_FILT_USE_WL); + /* + * If we have addresses in the whitelist enable the filter unless no devices were found + * then scan without so we can find any new devices that we want. + */ + if (NimBLEDevice::getWhiteListCount() > 0) { + if (foundDevices.getCount() == 0) { + pBLEScan->setFilterPolicy(BLE_HCI_SCAN_FILT_NO_WL); + } else { + pBLEScan->setFilterPolicy(BLE_HCI_SCAN_FILT_USE_WL); + } } - } - pBLEScan->clearResults(); - delay(2000); + + pBLEScan->clearResults(); + delay(2000); } diff --git a/examples/NimBLE_Secure_Client/NimBLE_Secure_Client.ino b/examples/NimBLE_Secure_Client/NimBLE_Secure_Client.ino index d45c700c..3fd20fc8 100644 --- a/examples/NimBLE_Secure_Client/NimBLE_Secure_Client.ino +++ b/examples/NimBLE_Secure_Client/NimBLE_Secure_Client.ino @@ -1,95 +1,83 @@ -/** NimBLE_Secure_Client Demo: +/** + * NimBLE_Secure_Client Demo: * - * This example demonstrates the secure passkey protected conenction and communication between an esp32 server and an esp32 client. - * Please note that esp32 stores auth info in nvs memory. After a successful connection it is possible that a passkey change will be ineffective. - * To avoid this clear the memory of the esp32's between security testings. esptool.py is capable of this, example: esptool.py --port /dev/ttyUSB0 erase_flash. + * This example demonstrates the secure passkey protected conenction and communication between an esp32 server and an + * esp32 client. Please note that esp32 stores auth info in nvs memory. After a successful connection it is possible + * that a passkey change will be ineffective. To avoid this clear the memory of the esp32's between security testings. + * esptool.py is capable of this, example: esptool.py --port /dev/ttyUSB0 erase_flash. * * Created: on Jan 08 2021 * Author: mblasee */ +#include #include -class ClientCallbacks : public NimBLEClientCallbacks -{ - uint32_t onPassKeyEntry() - { - Serial.println("Client Passkey Entry"); - /** return the passkey to send to the server */ - /** Change this to be different from NimBLE_Secure_Server if you want to test what happens on key mismatch */ - return 123456; - }; -}; -static ClientCallbacks clientCB; +class ClientCallbacks : public NimBLEClientCallbacks { + void onPassKeyEntry(NimBLEConnInfo& connInfo) override { + Serial.printf("Server Passkey Entry\n"); + /** + * This should prompt the user to enter the passkey displayed + * on the peer device. + */ + NimBLEDevice::injectPassKey(connInfo, 123456); + } +} clientCallbacks; -void setup() -{ - Serial.begin(115200); - Serial.println("Starting NimBLE Client"); +void setup() { + Serial.begin(115200); + Serial.println("Starting NimBLE Client"); - NimBLEDevice::init(""); -#ifdef ESP_PLATFORM - NimBLEDevice::setPower(ESP_PWR_LVL_P9); /** +9db */ -#else - NimBLEDevice::setPower(9); /** +9db */ -#endif - NimBLEDevice::setSecurityAuth(true, true, true); - NimBLEDevice::setSecurityIOCap(BLE_HS_IO_KEYBOARD_ONLY); - NimBLEScan *pScan = NimBLEDevice::getScan(); - NimBLEScanResults results = pScan->getResults(5 * 1000); + NimBLEDevice::init(""); + NimBLEDevice::setPower(3); /** +3db */ + NimBLEDevice::setSecurityAuth(true, true, true); /** bonding, MITM, BLE secure connections */ + NimBLEDevice::setSecurityIOCap(BLE_HS_IO_KEYBOARD_ONLY); /** passkey */ + NimBLEScan* pScan = NimBLEDevice::getScan(); + NimBLEScanResults results = pScan->getResults(5 * 1000); - NimBLEUUID serviceUuid("ABCD"); + NimBLEUUID serviceUuid("ABCD"); - for (int i = 0; i < results.getCount(); i++) - { - NimBLEAdvertisedDevice device = results.getDevice(i); - Serial.println(device.getName().c_str()); + for (int i = 0; i < results.getCount(); i++) { + const NimBLEAdvertisedDevice* device = results.getDevice(i); + Serial.println(device->getName().c_str()); - if (device.isAdvertisingService(serviceUuid)) - { - NimBLEClient *pClient = NimBLEDevice::createClient(); - pClient->setClientCallbacks(&clientCB, false); + if (device->isAdvertisingService(serviceUuid)) { + NimBLEClient* pClient = NimBLEDevice::createClient(); + pClient->setClientCallbacks(&clientCallbacks, false); - if (pClient->connect(&device)) - { - pClient->secureConnection(); - NimBLERemoteService *pService = pClient->getService(serviceUuid); - if (pService != nullptr) - { - NimBLERemoteCharacteristic *pNonSecureCharacteristic = pService->getCharacteristic("1234"); + if (pClient->connect(&device)) { + pClient->secureConnection(); + NimBLERemoteService* pService = pClient->getService(serviceUuid); + if (pService != nullptr) { + NimBLERemoteCharacteristic* pNonSecureCharacteristic = pService->getCharacteristic("1234"); - if (pNonSecureCharacteristic != nullptr) - { - // Testing to read a non secured characteristic, you should be able to read this even if you have mismatching passkeys. - std::string value = pNonSecureCharacteristic->readValue(); - // print or do whatever you need with the value - Serial.println(value.c_str()); - } + if (pNonSecureCharacteristic != nullptr) { + // Testing to read a non secured characteristic, you should be able to read this even if you have mismatching passkeys. + std::string value = pNonSecureCharacteristic->readValue(); + // print or do whatever you need with the value + Serial.println(value.c_str()); + } - NimBLERemoteCharacteristic *pSecureCharacteristic = pService->getCharacteristic("1235"); + NimBLERemoteCharacteristic* pSecureCharacteristic = pService->getCharacteristic("1235"); - if (pSecureCharacteristic != nullptr) - { - // Testing to read a secured characteristic, you should be able to read this only if you have matching passkeys, otherwise you should - // get an error like this. E NimBLERemoteCharacteristic: "<< readValue rc=261" - // This means you are trying to do something without the proper permissions. - std::string value = pSecureCharacteristic->readValue(); - // print or do whatever you need with the value - Serial.println(value.c_str()); - } - } - } - else - { - // failed to connect - Serial.println("failed to connect"); - } + if (pSecureCharacteristic != nullptr) { + // Testing to read a secured characteristic, you should be able to read this only if you have + // matching passkeys, otherwise you should get an error like this. E NimBLERemoteCharacteristic: + // "<< readValue rc=261" This means you are trying to do something without the proper + // permissions. + std::string value = pSecureCharacteristic->readValue(); + // print or do whatever you need with the value + Serial.println(value.c_str()); + } + } + } else { + // failed to connect + Serial.println("failed to connect"); + } - NimBLEDevice::deleteClient(pClient); + NimBLEDevice::deleteClient(pClient); + } } - } } -void loop() -{ -} +void loop() {} diff --git a/examples/NimBLE_Secure_Server/NimBLE_Secure_Server.ino b/examples/NimBLE_Secure_Server/NimBLE_Secure_Server.ino index 9cd866cc..065db87c 100644 --- a/examples/NimBLE_Secure_Server/NimBLE_Secure_Server.ino +++ b/examples/NimBLE_Secure_Server/NimBLE_Secure_Server.ino @@ -1,41 +1,45 @@ -/** NimBLE_Secure_Server Demo: +/** + * NimBLE_Secure_Server Demo: * - * This example demonstrates the secure passkey protected conenction and communication between an esp32 server and an esp32 client. - * Please note that esp32 stores auth info in nvs memory. After a successful connection it is possible that a passkey change will be ineffective. - * To avoid this clear the memory of the esp32's between security testings. esptool.py is capable of this, example: esptool.py --port /dev/ttyUSB0 erase_flash. + * This example demonstrates the secure passkey protected conenction and communication between an esp32 server and an + * esp32 client. Please note that esp32 stores auth info in nvs memory. After a successful connection it is possible + * that a passkey change will be ineffective. To avoid this clear the memory of the esp32's between security testings. + * esptool.py is capable of this, example: esptool.py --port /dev/ttyUSB0 erase_flash. * * Created: on Jan 08 2021 * Author: mblasee */ +#include #include void setup() { - Serial.begin(115200); - Serial.println("Starting NimBLE Server"); - NimBLEDevice::init("NimBLE"); + Serial.begin(115200); + Serial.println("Starting NimBLE Server"); + NimBLEDevice::init("NimBLE"); #ifdef ESP_PLATFORM NimBLEDevice::setPower(ESP_PWR_LVL_P9); /** +9db */ #else NimBLEDevice::setPower(9); /** +9db */ #endif - NimBLEDevice::setSecurityAuth(true, true, true); - NimBLEDevice::setSecurityPasskey(123456); - NimBLEDevice::setSecurityIOCap(BLE_HS_IO_DISPLAY_ONLY); - NimBLEServer *pServer = NimBLEDevice::createServer(); - NimBLEService *pService = pServer->createService("ABCD"); - NimBLECharacteristic *pNonSecureCharacteristic = pService->createCharacteristic("1234", NIMBLE_PROPERTY::READ ); - NimBLECharacteristic *pSecureCharacteristic = pService->createCharacteristic("1235", NIMBLE_PROPERTY::READ | NIMBLE_PROPERTY::READ_ENC | NIMBLE_PROPERTY::READ_AUTHEN); + NimBLEDevice::setSecurityAuth(true, true, true); /** bonding, MITM, BLE secure connections */ + NimBLEDevice::setSecurityPasskey(123456); + NimBLEDevice::setSecurityIOCap(BLE_HS_IO_DISPLAY_ONLY); /** Display only passkey */ + NimBLEServer* pServer = NimBLEDevice::createServer(); + NimBLEService* pService = pServer->createService("ABCD"); + NimBLECharacteristic* pNonSecureCharacteristic = pService->createCharacteristic("1234", NIMBLE_PROPERTY::READ); + NimBLECharacteristic* pSecureCharacteristic = + pService->createCharacteristic("1235", + NIMBLE_PROPERTY::READ | NIMBLE_PROPERTY::READ_ENC | NIMBLE_PROPERTY::READ_AUTHEN); - pService->start(); - pNonSecureCharacteristic->setValue("Hello Non Secure BLE"); - pSecureCharacteristic->setValue("Hello Secure BLE"); + pService->start(); + pNonSecureCharacteristic->setValue("Hello Non Secure BLE"); + pSecureCharacteristic->setValue("Hello Secure BLE"); - NimBLEAdvertising *pAdvertising = NimBLEDevice::getAdvertising(); - pAdvertising->addServiceUUID("ABCD"); - pAdvertising->start(); + NimBLEAdvertising* pAdvertising = NimBLEDevice::getAdvertising(); + pAdvertising->addServiceUUID("ABCD"); + pAdvertising->start(); } -void loop() { -} +void loop() {} diff --git a/examples/NimBLE_Server/NimBLE_Server.ino b/examples/NimBLE_Server/NimBLE_Server.ino index 7fa09b19..29a6c0f2 100644 --- a/examples/NimBLE_Server/NimBLE_Server.ino +++ b/examples/NimBLE_Server/NimBLE_Server.ino @@ -1,218 +1,188 @@ -/** NimBLE_Server Demo: +/** + * NimBLE_Server Demo: * * Demonstrates many of the available features of the NimBLE server library. * * Created: on March 22 2020 * Author: H2zero - * -*/ + */ +#include #include static NimBLEServer* pServer; /** None of these are required as they will be handled by the library with defaults. ** ** Remove as you see fit for your needs */ -class ServerCallbacks: public NimBLEServerCallbacks { - void onConnect(NimBLEServer* pServer, NimBLEConnInfo& connInfo) { - Serial.print("Client address: "); - Serial.println(connInfo.getAddress().toString().c_str()); - /** We can use the connection handle here to ask for different connection parameters. +class ServerCallbacks : public NimBLEServerCallbacks { + void onConnect(NimBLEServer* pServer, NimBLEConnInfo& connInfo) override { + Serial.printf("Client address: %s\n", connInfo.getAddress().toString().c_str()); + + /** + * We can use the connection handle here to ask for different connection parameters. * Args: connection handle, min connection interval, max connection interval * latency, supervision timeout. * Units; Min/Max Intervals: 1.25 millisecond increments. * Latency: number of intervals allowed to skip. - * Timeout: 10 millisecond increments, try for 5x interval time for best results. + * Timeout: 10 millisecond increments. */ - pServer->updateConnParams(connInfo.getConnHandle(), 24, 48, 0, 60); - }; - void onDisconnect(NimBLEServer* pServer, NimBLEConnInfo& connInfo, int reason) { - Serial.println("Client disconnected - start advertising"); + pServer->updateConnParams(connInfo.getConnHandle(), 24, 48, 0, 18); + } + + void onDisconnect(NimBLEServer* pServer, NimBLEConnInfo& connInfo, int reason) override { + Serial.printf("Client disconnected - start advertising\n"); NimBLEDevice::startAdvertising(); - }; - void onMTUChange(uint16_t MTU, NimBLEConnInfo& connInfo) { + } + + void onMTUChange(uint16_t MTU, NimBLEConnInfo& connInfo) override { Serial.printf("MTU updated: %u for connection ID: %u\n", MTU, connInfo.getConnHandle()); - }; + } -/********************* Security handled here ********************** -****** Note: these are the same return values as defaults ********/ - uint32_t onPassKeyDisplay() { - Serial.println("Server Passkey Display"); - /** This should return a random 6 digit number for security + /********************* Security handled here *********************/ + uint32_t onPassKeyDisplay() override { + Serial.printf("Server Passkey Display\n"); + /** + * This should return a random 6 digit number for security * or make your own static passkey as done here. */ return 123456; - }; + } - void onConfirmPasskey(NimBLEConnInfo& connInfo, uint32_t pass_key) { - Serial.print("The passkey YES/NO number: ");Serial.println(pass_key); + void onConfirmPassKey(NimBLEConnInfo& connInfo, uint32_t pass_key) override { + Serial.printf("The passkey YES/NO number: %" PRIu32 "\n", pass_key); /** Inject false if passkeys don't match. */ NimBLEDevice::injectConfirmPasskey(connInfo, true); - }; + } - void onAuthenticationComplete(NimBLEConnInfo& connInfo) { + void onAuthenticationComplete(NimBLEConnInfo& connInfo) override { /** Check that encryption was successful, if not we disconnect the client */ - if(!connInfo.isEncrypted()) { + if (!connInfo.isEncrypted()) { NimBLEDevice::getServer()->disconnect(connInfo.getConnHandle()); - Serial.println("Encrypt connection failed - disconnecting client"); + Serial.printf("Encrypt connection failed - disconnecting client\n"); return; } - Serial.println("Starting BLE work!"); - }; -}; + + Serial.printf("Secured connection to: %s\n", connInfo.getAddress().toString().c_str()); + } +} serverCallbacks; /** Handler class for characteristic actions */ -class CharacteristicCallbacks: public NimBLECharacteristicCallbacks { - void onRead(NimBLECharacteristic* pCharacteristic, NimBLEConnInfo& connInfo){ - Serial.print(pCharacteristic->getUUID().toString().c_str()); - Serial.print(": onRead(), value: "); - Serial.println(pCharacteristic->getValue().c_str()); - }; - - void onWrite(NimBLECharacteristic* pCharacteristic, NimBLEConnInfo& connInfo) { - Serial.print(pCharacteristic->getUUID().toString().c_str()); - Serial.print(": onWrite(), value: "); - Serial.println(pCharacteristic->getValue().c_str()); - }; - /** Called before notification or indication is sent, - * the value can be changed here before sending if desired. - */ - void onNotify(NimBLECharacteristic* pCharacteristic) { - Serial.println("Sending notification to clients"); - }; +class CharacteristicCallbacks : public NimBLECharacteristicCallbacks { + void onRead(NimBLECharacteristic* pCharacteristic, NimBLEConnInfo& connInfo) override { + Serial.printf("%s : onRead(), value: %s\n", + pCharacteristic->getUUID().toString().c_str(), + pCharacteristic->getValue().c_str()); + } + void onWrite(NimBLECharacteristic* pCharacteristic, NimBLEConnInfo& connInfo) override { + Serial.printf("%s : onWrite(), value: %s\n", + pCharacteristic->getUUID().toString().c_str(), + pCharacteristic->getValue().c_str()); + } /** * The value returned in code is the NimBLE host return code. */ - void onStatus(NimBLECharacteristic* pCharacteristic, int code) { - String str = ("Notification/Indication return code: "); - str += code; - str += ", "; - str += NimBLEUtils::returnCodeToString(code); - Serial.println(str); - }; - - void onSubscribe(NimBLECharacteristic* pCharacteristic, NimBLEConnInfo& connInfo, uint16_t subValue) { - String str = "Client ID: "; - str += connInfo.getConnHandle(); - str += " Address: "; - str += connInfo.getAddress().toString().c_str(); - if(subValue == 0) { + void onStatus(NimBLECharacteristic* pCharacteristic, int code) override { + Serial.printf("Notification/Indication return code: %d, %s\n", code, NimBLEUtils::returnCodeToString(code)); + } + + /** Peer subscribed to notifications/indications */ + void onSubscribe(NimBLECharacteristic* pCharacteristic, NimBLEConnInfo& connInfo, uint16_t subValue) override { + std::string str = "Client ID: "; + str += connInfo.getConnHandle(); + str += " Address: "; + str += connInfo.getAddress().toString(); + if (subValue == 0) { str += " Unsubscribed to "; - }else if(subValue == 1) { - str += " Subscribed to notfications for "; - } else if(subValue == 2) { + } else if (subValue == 1) { + str += " Subscribed to notifications for "; + } else if (subValue == 2) { str += " Subscribed to indications for "; - } else if(subValue == 3) { + } else if (subValue == 3) { str += " Subscribed to notifications and indications for "; } - str += std::string(pCharacteristic->getUUID()).c_str(); + str += std::string(pCharacteristic->getUUID()); - Serial.println(str); - }; -}; + Serial.printf("%s\n", str.c_str()); + } +} chrCallbacks; /** Handler class for descriptor actions */ class DescriptorCallbacks : public NimBLEDescriptorCallbacks { - void onWrite(NimBLEDescriptor* pDescriptor, NimBLEConnInfo& connInfo) { + void onWrite(NimBLEDescriptor* pDescriptor, NimBLEConnInfo& connInfo) override { std::string dscVal = pDescriptor->getValue(); - Serial.print("Descriptor witten value:"); - Serial.println(dscVal.c_str()); - }; - - void onRead(NimBLEDescriptor* pDescriptor, NimBLEConnInfo& connInfo) { - Serial.print(pDescriptor->getUUID().toString().c_str()); - Serial.println(" Descriptor read"); - }; -}; - - -/** Define callback instances globally to use for multiple Charateristics \ Descriptors */ -static DescriptorCallbacks dscCallbacks; -static CharacteristicCallbacks chrCallbacks; + Serial.printf("Descriptor written value: %s\n", dscVal.c_str()); + } + void onRead(NimBLEDescriptor* pDescriptor, NimBLEConnInfo& connInfo) override { + Serial.printf("%s Descriptor read\n", pDescriptor->getUUID().toString().c_str()); + } +} dscCallbacks; -void setup() { +void setup(void) { Serial.begin(115200); - Serial.println("Starting NimBLE Server"); + Serial.printf("Starting NimBLE Server\n"); - /** sets device name */ - NimBLEDevice::init("NimBLE-Arduino"); + /** Initialize NimBLE and set the device name */ + NimBLEDevice::init("NimBLE"); - /** Optional: set the transmit power, default is 3db */ -#ifdef ESP_PLATFORM - NimBLEDevice::setPower(ESP_PWR_LVL_P9); /** +9db */ -#else - NimBLEDevice::setPower(9); /** +9db */ -#endif - - /** Set the IO capabilities of the device, each option will trigger a different pairing method. + /** + * Set the IO capabilities of the device, each option will trigger a different pairing method. * BLE_HS_IO_DISPLAY_ONLY - Passkey pairing * BLE_HS_IO_DISPLAY_YESNO - Numeric comparison pairing * BLE_HS_IO_NO_INPUT_OUTPUT - DEFAULT setting - just works pairing */ - //NimBLEDevice::setSecurityIOCap(BLE_HS_IO_DISPLAY_ONLY); // use passkey - //NimBLEDevice::setSecurityIOCap(BLE_HS_IO_DISPLAY_YESNO); //use numeric comparison + // NimBLEDevice::setSecurityIOCap(BLE_HS_IO_DISPLAY_ONLY); // use passkey + // NimBLEDevice::setSecurityIOCap(BLE_HS_IO_DISPLAY_YESNO); //use numeric comparison - /** 2 different ways to set security - both calls achieve the same result. - * no bonding, no man in the middle protection, secure connections. + /** + * 2 different ways to set security - both calls achieve the same result. + * no bonding, no man in the middle protection, BLE secure connections. * * These are the default values, only shown here for demonstration. */ - //NimBLEDevice::setSecurityAuth(false, false, true); - NimBLEDevice::setSecurityAuth(/*BLE_SM_PAIR_AUTHREQ_BOND | BLE_SM_PAIR_AUTHREQ_MITM |*/ BLE_SM_PAIR_AUTHREQ_SC); + // NimBLEDevice::setSecurityAuth(false, false, true); + NimBLEDevice::setSecurityAuth(/*BLE_SM_PAIR_AUTHREQ_BOND | BLE_SM_PAIR_AUTHREQ_MITM |*/ BLE_SM_PAIR_AUTHREQ_SC); pServer = NimBLEDevice::createServer(); - pServer->setCallbacks(new ServerCallbacks()); - - NimBLEService* pDeadService = pServer->createService("DEAD"); - NimBLECharacteristic* pBeefCharacteristic = pDeadService->createCharacteristic( - "BEEF", - NIMBLE_PROPERTY::READ | - NIMBLE_PROPERTY::WRITE | - /** Require a secure connection for read and write access */ - NIMBLE_PROPERTY::READ_ENC | // only allow reading if paired / encrypted - NIMBLE_PROPERTY::WRITE_ENC // only allow writing if paired / encrypted - ); + pServer->setCallbacks(&serverCallbacks); + + NimBLEService* pDeadService = pServer->createService("DEAD"); + NimBLECharacteristic* pBeefCharacteristic = + pDeadService->createCharacteristic("BEEF", + NIMBLE_PROPERTY::READ | NIMBLE_PROPERTY::WRITE | + /** Require a secure connection for read and write access */ + NIMBLE_PROPERTY::READ_ENC | // only allow reading if paired / encrypted + NIMBLE_PROPERTY::WRITE_ENC // only allow writing if paired / encrypted + ); pBeefCharacteristic->setValue("Burger"); pBeefCharacteristic->setCallbacks(&chrCallbacks); - /** 2904 descriptors are a special case, when createDescriptor is called with - * 0x2904 a NimBLE2904 class is created with the correct properties and sizes. - * However we must cast the returned reference to the correct type as the method + /** + * 2902 and 2904 descriptors are a special case, when createDescriptor is called with + * either of those uuid's it will create the associated class with the correct properties + * and sizes. However we must cast the returned reference to the correct type as the method * only returns a pointer to the base NimBLEDescriptor class. */ NimBLE2904* pBeef2904 = pBeefCharacteristic->create2904(); pBeef2904->setFormat(NimBLE2904::FORMAT_UTF8); pBeef2904->setCallbacks(&dscCallbacks); - - NimBLEService* pBaadService = pServer->createService("BAAD"); - NimBLECharacteristic* pFoodCharacteristic = pBaadService->createCharacteristic( - "F00D", - NIMBLE_PROPERTY::READ | - NIMBLE_PROPERTY::WRITE | - NIMBLE_PROPERTY::NOTIFY - ); + 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); - /** Note a 0x2902 descriptor MUST NOT be created as NimBLE will create one automatically - * if notification or indication properties are assigned to a characteristic. - */ - - /** Custom descriptor: Arguments are UUID, Properties, max length in bytes of the value */ - NimBLEDescriptor* pC01Ddsc = pFoodCharacteristic->createDescriptor( - "C01D", - NIMBLE_PROPERTY::READ | - NIMBLE_PROPERTY::WRITE| - NIMBLE_PROPERTY::WRITE_ENC, // only allow writing if paired / encrypted - 20 - ); + /** Custom descriptor: Arguments are UUID, Properties, max length of the value in bytes */ + NimBLEDescriptor* pC01Ddsc = + pFoodCharacteristic->createDescriptor("C01D", + NIMBLE_PROPERTY::READ | NIMBLE_PROPERTY::WRITE | NIMBLE_PROPERTY::WRITE_ENC, + 20); pC01Ddsc->setValue("Send it back!"); pC01Ddsc->setCallbacks(&dscCallbacks); @@ -220,31 +190,32 @@ void setup() { pDeadService->start(); pBaadService->start(); + /** Create an advertising instance and add the services to the advertised data */ NimBLEAdvertising* pAdvertising = NimBLEDevice::getAdvertising(); - /** Add the services to the advertisment data **/ + pAdvertising->setName("NimBLE-Server"); pAdvertising->addServiceUUID(pDeadService->getUUID()); pAdvertising->addServiceUUID(pBaadService->getUUID()); - /** If your device is battery powered you may consider setting scan response + /** + * If your device is battery powered you may consider setting scan response * to false as it will extend battery life at the expense of less data sent. */ pAdvertising->enableScanResponse(true); pAdvertising->start(); - Serial.println("Advertising Started"); + Serial.printf("Advertising Started\n"); } - void loop() { - /** Do your thing here, this just spams notifications to all connected clients */ - if(pServer->getConnectedCount()) { + /** Loop here and send notifications to connected peers */ + delay(2000); + + if (pServer->getConnectedCount()) { NimBLEService* pSvc = pServer->getServiceByUUID("BAAD"); - if(pSvc) { + if (pSvc) { NimBLECharacteristic* pChr = pSvc->getCharacteristic("F00D"); - if(pChr) { + if (pChr) { pChr->notify(); } } } - - delay(2000); -} \ No newline at end of file +} diff --git a/examples/NimBLE_Server_Whitelist/NimBLE_Server_Whitelist.ino b/examples/NimBLE_Server_Whitelist/NimBLE_Server_Whitelist.ino index 2ff54fe9..c22aa758 100644 --- a/examples/NimBLE_Server_Whitelist/NimBLE_Server_Whitelist.ino +++ b/examples/NimBLE_Server_Whitelist/NimBLE_Server_Whitelist.ino @@ -5,12 +5,13 @@ * Author: h2zero */ +#include #include -NimBLECharacteristic* pCharacteristic = nullptr; -bool deviceConnected = false; -bool oldDeviceConnected = false; -uint32_t value = 0; +NimBLECharacteristic* pCharacteristic = nullptr; +bool deviceConnected = false; +bool oldDeviceConnected = false; +uint32_t value = 0; // See the following for generating UUIDs: // https://www.uuidgenerator.net/ @@ -18,84 +19,71 @@ uint32_t value = 0; #define SERVICE_UUID "4fafc201-1fb5-459e-8fcc-c5c9c331914b" #define CHARACTERISTIC_UUID "beb5483e-36e1-4688-b7f5-ea07361b26a8" +class ServerCallbacks : public NimBLEServerCallbacks { + void onConnect(NimBLEServer* pServer, NimBLEConnInfo& connInfo) override { deviceConnected = true; }; -class MyServerCallbacks: public NimBLEServerCallbacks { - void onConnect(NimBLEServer* pServer, NimBLEConnInfo& connInfo) { - deviceConnected = true; - }; - - void onDisconnect(NimBLEServer* pServer, NimBLEConnInfo& connInfo, int reason) { - // Peer disconnected, add them to the whitelist - // This allows us to use the whitelist to filter connection attempts - // which will minimize reconnection time. - NimBLEDevice::whiteListAdd(connInfo.getAddress()); - deviceConnected = false; + void onDisconnect(NimBLEServer* pServer, NimBLEConnInfo& connInfo, int reason) override { + // Peer disconnected, add them to the whitelist + // This allows us to use the whitelist to filter connection attempts + // which will minimize reconnection time. + NimBLEDevice::whiteListAdd(connInfo.getAddress()); + deviceConnected = false; } -}; +} serverCallbacks; -void onAdvComplete(NimBLEAdvertising *pAdvertising) { +void onAdvComplete(NimBLEAdvertising* pAdvertising) { Serial.println("Advertising stopped"); if (deviceConnected) { return; } // If advertising timed out without connection start advertising without whitelist filter - pAdvertising->setScanFilter(false,false); + pAdvertising->setScanFilter(false, false); pAdvertising->start(); } - void setup() { - Serial.begin(115200); - - // Create the BLE Device - NimBLEDevice::init("ESP32"); - - // Create the BLE Server - NimBLEServer* pServer = NimBLEDevice::createServer(); - pServer->setCallbacks(new MyServerCallbacks()); - pServer->advertiseOnDisconnect(false); - - // Create the BLE Service - NimBLEService *pService = pServer->createService(SERVICE_UUID); - - // Create a BLE Characteristic - pCharacteristic = pService->createCharacteristic( - CHARACTERISTIC_UUID, - NIMBLE_PROPERTY::READ | - NIMBLE_PROPERTY::WRITE | - NIMBLE_PROPERTY::NOTIFY ); - - // Start the service - pService->start(); - - // Start advertising - NimBLEAdvertising *pAdvertising = NimBLEDevice::getAdvertising(); - pAdvertising->addServiceUUID(SERVICE_UUID); - pAdvertising->enableScanResponse(false); - pAdvertising->start(); - Serial.println("Waiting a client connection to notify..."); + Serial.begin(115200); + + NimBLEDevice::init("Whitelist NimBLEServer"); + + NimBLEServer* pServer = NimBLEDevice::createServer(); + pServer->setCallbacks(&serverCallbacks); + pServer->advertiseOnDisconnect(false); + + NimBLEService* pService = pServer->createService(SERVICE_UUID); + + pCharacteristic = + pService->createCharacteristic(CHARACTERISTIC_UUID, + NIMBLE_PROPERTY::READ | NIMBLE_PROPERTY::WRITE | NIMBLE_PROPERTY::NOTIFY); + pService->start(); + + NimBLEAdvertising* pAdvertising = NimBLEDevice::getAdvertising(); + pAdvertising->addServiceUUID(SERVICE_UUID); + pAdvertising->enableScanResponse(false); + pAdvertising->setAdvertisingCompleteCallback(onAdvComplete); + pAdvertising->start(); + Serial.println("Waiting a client connection to notify..."); } void loop() { - // notify changed value if (deviceConnected) { pCharacteristic->setValue((uint8_t*)&value, 4); pCharacteristic->notify(); value++; } - // disconnecting + if (!deviceConnected && oldDeviceConnected) { - NimBLEAdvertising *pAdvertising = NimBLEDevice::getAdvertising(); + NimBLEAdvertising* pAdvertising = NimBLEDevice::getAdvertising(); if (NimBLEDevice::getWhiteListCount() > 0) { // Allow anyone to scan but only whitelisted can connect. - pAdvertising->setScanFilter(false,true); + pAdvertising->setScanFilter(false, true); } // advertise with whitelist for 30 seconds - pAdvertising->start(30 * 1000, onAdvComplete); + pAdvertising->start(30 * 1000); Serial.println("start advertising"); oldDeviceConnected = deviceConnected; } - // connecting + if (deviceConnected && !oldDeviceConnected) { // do stuff here on connecting oldDeviceConnected = deviceConnected; diff --git a/examples/NimBLE_Service_Data_Advertiser/NimBLE_Service_Data_Advertiser.ino b/examples/NimBLE_Service_Data_Advertiser/NimBLE_Service_Data_Advertiser.ino deleted file mode 100644 index 21bddf05..00000000 --- a/examples/NimBLE_Service_Data_Advertiser/NimBLE_Service_Data_Advertiser.ino +++ /dev/null @@ -1,34 +0,0 @@ -/** NimBLE_Service_Data_Advertiser Demo: - * - * Simple demo of advertising service data that changes every 5 seconds - * - * Created: on February 7 2021 - * Author: H2zero - * -*/ - -#include - -#define SERVICE_UUID "4fafc201-1fb5-459e-8fcc-c5c9c331914b" - -static NimBLEUUID dataUuid(SERVICE_UUID); -static NimBLEAdvertising *pAdvertising = nullptr; -static uint32_t count = 0; - -void setup() { - Serial.begin(115200); - Serial.println("Starting BLE work!"); - - NimBLEDevice::init("svc data"); - pAdvertising = NimBLEDevice::getAdvertising(); -} - -void loop() { - pAdvertising->stop(); - pAdvertising->setServiceData(dataUuid, std::string((char*)&count, sizeof(count))); - pAdvertising->start(); - - Serial.printf("Advertising count = %d\n", count); - count++; - delay(5000); -} 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 3bf2c598..38a6daa2 100644 --- a/examples/NimBLE_active_passive_scan/NimBLE_active_passive_scan.ino +++ b/examples/NimBLE_active_passive_scan/NimBLE_active_passive_scan.ino @@ -4,45 +4,44 @@ * Demonstrates the use of the scan callbacks while alternating between passive and active scanning. */ -#include "NimBLEDevice.h" -int scanTime = 5 * 1000; // In milliseconds, 0 = scan forever -BLEScan* pBLEScan; +#include +#include -bool active = false; +int scanTime = 5 * 1000; // In milliseconds, 0 = scan forever +NimBLEScan* pBLEScan; -class scanCallbacks: public NimBLEScanCallbacks { +bool active = false; - void onDiscovered(const NimBLEAdvertisedDevice* advertisedDevice) { - Serial.printf("Discovered Advertised Device: %s \n", advertisedDevice->toString().c_str()); +class ScanCallbacks : public NimBLEScanCallbacks { + void onDiscovered(const NimBLEAdvertisedDevice* advertisedDevice) override { + Serial.printf("Discovered Advertised Device: %s \n", advertisedDevice->toString().c_str()); } - void onResult(const NimBLEAdvertisedDevice* advertisedDevice) { - Serial.printf("Advertised Device Result: %s \n", advertisedDevice->toString().c_str()); + void onResult(const NimBLEAdvertisedDevice* advertisedDevice) override { + Serial.printf("Advertised Device Result: %s \n", advertisedDevice->toString().c_str()); } - void onScanEnd(const NimBLEScanResults& results, int reason) { - Serial.print("Scan Ended; reason = "); Serial.println(reason); + void onScanEnd(const NimBLEScanResults& results, int reason) override { + Serial.print("Scan Ended; reason = "); + Serial.println(reason); active = !active; pBLEScan->setActiveScan(active); Serial.printf("scan start, active = %u\n", active); pBLEScan->start(scanTime); } -}; - - +} scanCallbacks; void setup() { - Serial.begin(115200); - Serial.println("Scanning..."); - - NimBLEDevice::init(""); - pBLEScan = NimBLEDevice::getScan(); - pBLEScan->setScanCallbacks(new scanCallbacks()); - pBLEScan->setActiveScan(active); - pBLEScan->setInterval(100); - pBLEScan->setWindow(99); - pBLEScan->start(scanTime); + Serial.begin(115200); + Serial.println("Scanning..."); + + NimBLEDevice::init("active-passive-scan"); + pBLEScan = NimBLEDevice::getScan(); + pBLEScan->setScanCallbacks(&scanCallbacks); + pBLEScan->setActiveScan(active); + pBLEScan->setInterval(100); + pBLEScan->setWindow(100); + pBLEScan->start(scanTime); } -void loop() { -} +void loop() {} diff --git a/examples/NimBLE_server_get_client_name/NimBLE_server_get_client_name.ino b/examples/NimBLE_server_get_client_name/NimBLE_server_get_client_name.ino deleted file mode 100644 index d3a2a259..00000000 --- a/examples/NimBLE_server_get_client_name/NimBLE_server_get_client_name.ino +++ /dev/null @@ -1,91 +0,0 @@ -/** NimBLE_server_get_client_name - * - * Demonstrates 2 ways for the server to read the device name from the connected client. - * - * Created: on June 24 2024 - * Author: H2zero - * - */ - -#include - -// See the following for generating UUIDs: -// https://www.uuidgenerator.net/ - -#define SERVICE_UUID "4fafc201-1fb5-459e-8fcc-c5c9c331914b" -#define CHARACTERISTIC_UUID "beb5483e-36e1-4688-b7f5-ea07361b26a8" -#define ENC_CHARACTERISTIC_UUID "9551f35b-8d91-42e4-8f7e-1358dfe272dc" - -NimBLEServer* pServer; - -class ServerCallbacks : public NimBLEServerCallbacks { - // Same as before but now includes the name parameter - void onConnect(NimBLEServer* pServer, NimBLEConnInfo& connInfo, std::string& name) override { - Serial.print("Client address: "); - Serial.print(connInfo.getAddress().toString().c_str()); - Serial.print(" Name: "); - Serial.println(name.c_str()); - } - - // Same as before but now includes the name parameter - void onAuthenticationComplete(NimBLEConnInfo& connInfo, const std::string& name) override { - if (!connInfo.isEncrypted()) { - NimBLEDevice::getServer()->disconnect(connInfo.getConnHandle()); - Serial.println("Encrypt connection failed - disconnecting client"); - return; - } - - Serial.print("Encrypted Client address: "); - Serial.print(connInfo.getAddress().toString().c_str()); - Serial.print(" Name: "); - Serial.println(name.c_str()); - } -}; - -void setup() { - Serial.begin(115200); - Serial.println("Starting BLE Server!"); - - NimBLEDevice::init("Connect to me!"); - NimBLEDevice::setSecurityAuth(true, false, true); // Enable bonding to see full name on phones. - - pServer = NimBLEDevice::createServer(); - NimBLEService* pService = pServer->createService(SERVICE_UUID); - NimBLECharacteristic* pCharacteristic = - pService->createCharacteristic(CHARACTERISTIC_UUID, NIMBLE_PROPERTY::READ | NIMBLE_PROPERTY::WRITE); - pCharacteristic->setValue("Hello World says NimBLE"); - - NimBLECharacteristic* pEncCharacteristic = pService->createCharacteristic( - ENC_CHARACTERISTIC_UUID, - (NIMBLE_PROPERTY::READ | NIMBLE_PROPERTY::WRITE | NIMBLE_PROPERTY::READ_ENC | NIMBLE_PROPERTY::WRITE_ENC)); - pEncCharacteristic->setValue("Hello World says NimBLE Encrypted"); - - pService->start(); - - pServer->setCallbacks(new ServerCallbacks()); - pServer->getPeerNameOnConnect(true); // Setting this will enable the onConnect callback that provides the name. - - BLEAdvertising* pAdvertising = NimBLEDevice::getAdvertising(); - pAdvertising->addServiceUUID(SERVICE_UUID); - pAdvertising->enableScanResponse(true); - - pAdvertising->start(); - Serial.println("Advertising started, connect with your phone."); -} - -void loop() { - auto clientCount = pServer->getConnectedCount(); - if (clientCount) { - Serial.println("Connected clients: "); - for (auto i = 0; i < clientCount; ++i) { - NimBLEConnInfo peerInfo = pServer->getPeerInfo(i); - Serial.print("Client address: "); - Serial.print(peerInfo.getAddress().toString().c_str()); - Serial.print(" Name: "); - // This function blocks until the name is retrieved, so cannot be used in callback functions. - Serial.println(pServer->getPeerName(peerInfo).c_str()); - } - } - - delay(10000); -} diff --git a/examples/Refactored_original_examples/BLE_client/BLE_client.ino b/examples/Refactored_original_examples/BLE_client/BLE_client.ino deleted file mode 100644 index afbbeecb..00000000 --- a/examples/Refactored_original_examples/BLE_client/BLE_client.ino +++ /dev/null @@ -1,204 +0,0 @@ -/** - * A BLE client example that is rich in capabilities. - * There is a lot new capabilities implemented. - * author unknown - * updated by chegewara - * updated for NimBLE by H2zero - */ - -/** NimBLE differences highlighted in comment blocks **/ - -/*******original******** -#include "BLEDevice.h" -***********************/ -#include "NimBLEDevice.h" - -// The remote service we wish to connect to. -static BLEUUID serviceUUID("4fafc201-1fb5-459e-8fcc-c5c9c331914b"); -// The characteristic of the remote service we are interested in. -static BLEUUID charUUID("beb5483e-36e1-4688-b7f5-ea07361b26a8"); - -static boolean doConnect = false; -static boolean connected = false; -static boolean doScan = false; -static BLERemoteCharacteristic* pRemoteCharacteristic; -/* const required now */ -/* static BLEAdvertisedDevice* myDevice;*/ -static const BLEAdvertisedDevice* myDevice; - -static void notifyCallback( - BLERemoteCharacteristic* pBLERemoteCharacteristic, - uint8_t* pData, - size_t length, - bool isNotify) { - Serial.print("Notify callback for characteristic "); - Serial.print(pBLERemoteCharacteristic->getUUID().toString().c_str()); - Serial.print(" of data length "); - Serial.println(length); - Serial.print("data: "); - Serial.println((char*)pData); -} - -/** None of these are required as they will be handled by the library with defaults. ** - ** Remove as you see fit for your needs */ -class MyClientCallback : public BLEClientCallbacks { - void onConnect(BLEClient* pclient) { - } - - /** onDisconnect now takes a reason parameter to indicate the reason for disconnection - void onDisconnect(BLEClient* pclient) { */ - void onDisconnect(BLEClient* pclient, int reason) { - connected = false; - Serial.println("onDisconnect"); - } -/***************** New - Security handled here ******************** -****** Note: these are the same return values as defaults ********/ - void onPassKeyEntry() { - Serial.println("Client PassKey Entry"); - NimBLEDevice::injectPassKey(connInfo, 123456); - } - - void onConfirmPasskey(const BLEConnInfo& connInfo, uint32_t pass_key) { - Serial.print("The passkey YES/NO number: ");Serial.println(pass_key); - NimBLEDevice::injectConfirmPasskey(connInfo, true); - } - - void onAuthenticationComplete(const BLEConnInfo& connInfo){ - Serial.println("Starting BLE work!"); - } -/*******************************************************************/ -}; - -bool connectToServer() { - Serial.print("Forming a connection to "); - Serial.println(myDevice->getAddress().toString().c_str()); - - BLEClient* pClient = BLEDevice::createClient(); - Serial.println(" - Created client"); - - pClient->setClientCallbacks(new MyClientCallback()); - - // Connect to the remove BLE Server. - pClient->connect(myDevice); // if you pass BLEAdvertisedDevice instead of address, it will be recognized type of peer device address (public or private) - Serial.println(" - Connected to server"); - - // Obtain a reference to the service we are after in the remote BLE server. - BLERemoteService* pRemoteService = pClient->getService(serviceUUID); - if (pRemoteService == nullptr) { - Serial.print("Failed to find our service UUID: "); - Serial.println(serviceUUID.toString().c_str()); - pClient->disconnect(); - return false; - } - Serial.println(" - Found our service"); - - - // Obtain a reference to the characteristic in the service of the remote BLE server. - pRemoteCharacteristic = pRemoteService->getCharacteristic(charUUID); - if (pRemoteCharacteristic == nullptr) { - Serial.print("Failed to find our characteristic UUID: "); - Serial.println(charUUID.toString().c_str()); - pClient->disconnect(); - return false; - } - Serial.println(" - Found our characteristic"); - - // Read the value of the characteristic. - if(pRemoteCharacteristic->canRead()) { - std::string value = pRemoteCharacteristic->readValue(); - Serial.print("The characteristic value was: "); - Serial.println(value.c_str()); - } - - /** registerForNotify() has been removed and replaced with subscribe() / unsubscribe(). - * Subscribe parameter defaults are: notifications=true, notifyCallback=nullptr, response=true. - * Unsubscribe parameter defaults are: response=true. - */ - if(pRemoteCharacteristic->canNotify()) - pRemoteCharacteristic->subscribe(true, notifyCallback); - /*pRemoteCharacteristic->registerForNotify(notifyCallback);*/ - - connected = true; - return true; -} - -/** - * Scan for BLE servers and find the first one that advertises the service we are looking for. - */ -class MyAdvertisedDeviceCallbacks: public BLEAdvertisedDeviceCallbacks { - /** - * Called for each advertising BLE server. - */ - -/*** Only a const pointer to the advertised device is passed now - void onResult(BLEAdvertisedDevice advertisedDevice) { **/ - void onResult(const BLEAdvertisedDevice* advertisedDevice) { - Serial.print("BLE Advertised Device found: "); - Serial.println(advertisedDevice->toString().c_str()); - - // We have found a device, let us now see if it contains the service we are looking for. -/******************************************************************************** - if (advertisedDevice.haveServiceUUID() && advertisedDevice.isAdvertisingService(serviceUUID)) { -********************************************************************************/ - if (advertisedDevice->haveServiceUUID() && advertisedDevice->isAdvertisingService(serviceUUID)) { - - BLEDevice::getScan()->stop(); -/******************************************************************* - myDevice = new BLEAdvertisedDevice(advertisedDevice); -*******************************************************************/ - myDevice = advertisedDevice; /** Just save the reference now, no need to copy the object */ - doConnect = true; - doScan = true; - - } // Found our server - } // onResult -}; // MyAdvertisedDeviceCallbacks - - -void setup() { - Serial.begin(115200); - Serial.println("Starting Arduino BLE Client application..."); - BLEDevice::init(""); - - // Retrieve a Scanner and set the callback we want to use to be informed when we - // have detected a new device. Specify that we want active scanning and start the - // scan to run for 5 seconds. - BLEScan* pBLEScan = BLEDevice::getScan(); - pBLEScan->setScanCallbacks(new MyAdvertisedDeviceCallbacks()); - pBLEScan->setInterval(1349); - pBLEScan->setWindow(449); - pBLEScan->setActiveScan(true); - pBLEScan->start(5 * 1000, false); -} // End of setup. - - -// This is the Arduino main loop function. -void loop() { - - // If the flag "doConnect" is true then we have scanned for and found the desired - // BLE Server with which we wish to connect. Now we connect to it. Once we are - // connected we set the connected flag to be true. - if (doConnect == true) { - if (connectToServer()) { - Serial.println("We are now connected to the BLE Server."); - } else { - Serial.println("We have failed to connect to the server; there is nothin more we will do."); - } - doConnect = false; - } - - // If we are connected to a peer BLE Server, update the characteristic each time we are reached - // with the current time since boot. - if (connected) { - String newValue = "Time since boot: " + String(millis()/1000); - Serial.println("Setting new characteristic value to \"" + newValue + "\""); - - // Set the characteristic's value to be the array of bytes that is actually a string. - /*** Note: write / read value now returns true if successful, false otherwise - try again or disconnect ***/ - pRemoteCharacteristic->writeValue(newValue.c_str(), newValue.length()); - }else if(doScan){ - BLEDevice::getScan()->start(0); // this is just eample to start scan after disconnect, most likely there is better way to do it in arduino - } - - delay(1000); // Delay a second between loops. -} // End of loop diff --git a/examples/Refactored_original_examples/BLE_iBeacon/BLE_iBeacon.ino b/examples/Refactored_original_examples/BLE_iBeacon/BLE_iBeacon.ino deleted file mode 100644 index 86b97def..00000000 --- a/examples/Refactored_original_examples/BLE_iBeacon/BLE_iBeacon.ino +++ /dev/null @@ -1,118 +0,0 @@ -/* - Based on Neil Kolban example for IDF: https://github.com/nkolban/esp32-snippets/blob/master/cpp_utils/tests/BLE%20Tests/SampleScan.cpp - Ported to Arduino ESP32 by pcbreflux -*/ - - -/* - Create a BLE server that will send periodic iBeacon frames. - The design of creating the BLE server is: - 1. Create a BLE Server - 2. Create advertising data - 3. Start advertising. - 4. wait - 5. Stop advertising. - 6. deep sleep - -*/ - - -/** NimBLE differences highlighted in comment blocks **/ - - -#include "sys/time.h" -/*******original******** -#include "BLEDevice.h" -#include "BLEUtils.h" -#include "BLEBeacon.h" -***********************/ -#include "NimBLEDevice.h" -#include "NimBLEBeacon.h" -#include "esp_sleep.h" - -#define GPIO_DEEP_SLEEP_DURATION 10 // sleep x seconds and then wake up -RTC_DATA_ATTR static time_t last; // remember last boot in RTC Memory -RTC_DATA_ATTR static uint32_t bootcount; // remember number of boots in RTC Memory - -#ifdef __cplusplus -extern "C" { -#endif - -uint8_t temprature_sens_read(); -//uint8_t g_phyFuns; - -#ifdef __cplusplus -} -#endif - -// See the following for generating UUIDs: -// https://www.uuidgenerator.net/ -BLEAdvertising *pAdvertising; -struct timeval now; - -#define BEACON_UUID "8ec76ea3-6668-48da-9866-75be8bc86f4d" // UUID 1 128-Bit (may use linux tool uuidgen or random numbers via https://www.uuidgenerator.net/) - -void setBeacon() { - - BLEBeacon oBeacon = BLEBeacon(); - oBeacon.setManufacturerId(0x4C00); // fake Apple 0x004C LSB (ENDIAN_CHANGE_U16!) - oBeacon.setProximityUUID(BLEUUID(BEACON_UUID)); - oBeacon.setMajor((bootcount & 0xFFFF0000) >> 16); - oBeacon.setMinor(bootcount&0xFFFF); - BLEAdvertisementData oAdvertisementData = BLEAdvertisementData(); - BLEAdvertisementData oScanResponseData = BLEAdvertisementData(); - - oAdvertisementData.setFlags(0x04); // BR_EDR_NOT_SUPPORTED 0x04 - - std::string strServiceData = ""; - - strServiceData += (char)26; // Len - strServiceData += (char)0xFF; // Type - strServiceData += oBeacon.getData(); - oAdvertisementData.addData(strServiceData); - - pAdvertising->setAdvertisementData(oAdvertisementData); - pAdvertising->setScanResponseData(oScanResponseData); - /** pAdvertising->setAdvertisementType(ADV_TYPE_NONCONN_IND); - * Advertising mode. Can be one of following constants: - * - BLE_GAP_CONN_MODE_NON (non-connectable; 3.C.9.3.2). - * - BLE_GAP_CONN_MODE_DIR (directed-connectable; 3.C.9.3.3). - * - BLE_GAP_CONN_MODE_UND (undirected-connectable; 3.C.9.3.4). - */ - pAdvertising->setAdvertisementType(BLE_GAP_CONN_MODE_NON); - -} - -void setup() { - - - Serial.begin(115200); - gettimeofday(&now, NULL); - - Serial.printf("start ESP32 %d\n",bootcount++); - - Serial.printf("deep sleep (%lds since last reset, %lds since last boot)\n",now.tv_sec,now.tv_sec-last); - - last = now.tv_sec; - - // Create the BLE Device - BLEDevice::init(""); - - // Create the BLE Server - // BLEServer *pServer = BLEDevice::createServer(); // <-- no longer required to instantiate BLEServer, less flash and ram usage - - pAdvertising = BLEDevice::getAdvertising(); - - setBeacon(); - // Start advertising - pAdvertising->start(); - Serial.println("Advertizing started..."); - delay(100); - pAdvertising->stop(); - Serial.printf("enter deep sleep\n"); - esp_deep_sleep(1000000LL * GPIO_DEEP_SLEEP_DURATION); - Serial.printf("in deep sleep\n"); -} - -void loop() { -} diff --git a/examples/Refactored_original_examples/BLE_notify/BLE_notify.ino b/examples/Refactored_original_examples/BLE_notify/BLE_notify.ino deleted file mode 100644 index e0e121f0..00000000 --- a/examples/Refactored_original_examples/BLE_notify/BLE_notify.ino +++ /dev/null @@ -1,149 +0,0 @@ -/* - Video: https://www.youtube.com/watch?v=oCMOYS71NIU - Based on Neil Kolban example for IDF: https://github.com/nkolban/esp32-snippets/blob/master/cpp_utils/tests/BLE%20Tests/SampleNotify.cpp - Ported to Arduino ESP32 by Evandro Copercini - updated by chegewara - - Create a BLE server that, once we receive a connection, will send periodic notifications. - The service advertises itself as: 4fafc201-1fb5-459e-8fcc-c5c9c331914b - And has a characteristic of: beb5483e-36e1-4688-b7f5-ea07361b26a8 - - The design of creating the BLE server is: - 1. Create a BLE Server - 2. Create a BLE Service - 3. Create a BLE Characteristic on the Service - 4. Create a BLE Descriptor on the characteristic - 5. Start the service. - 6. Start advertising. - - A connect hander associated with the server starts a background task that performs notification - every couple of seconds. -*/ - -/** NimBLE differences highlighted in comment blocks **/ - -/*******original******** -#include -#include -#include -#include -***********************/ -#include - -BLEServer* pServer = NULL; -BLECharacteristic* pCharacteristic = NULL; -bool deviceConnected = false; -bool oldDeviceConnected = false; -uint32_t value = 0; - -// See the following for generating UUIDs: -// https://www.uuidgenerator.net/ - -#define SERVICE_UUID "4fafc201-1fb5-459e-8fcc-c5c9c331914b" -#define CHARACTERISTIC_UUID "beb5483e-36e1-4688-b7f5-ea07361b26a8" - -/** None of these are required as they will be handled by the library with defaults. ** - ** Remove as you see fit for your needs */ -class MyServerCallbacks: public BLEServerCallbacks { - void onConnect(BLEServer* pServer, BLEConnInfo& connInfo) { - deviceConnected = true; - }; - - void onDisconnect(BLEServer* pServer, BLEConnInfo& connInfo, int reason) { - deviceConnected = false; - } -/***************** New - Security handled here ******************** -****** Note: these are the same return values as defaults ********/ - uint32_t onPassKeyDisplay() { - Serial.println("Server Passkey Display"); - /** This should return a random 6 digit number for security - * or make your own static passkey as done here. - */ - return 123456; - } - - void onConfirmPasskey(const BLEConnInfo& connInfo, uint32_t pass_key) { - Serial.print("The passkey YES/NO number: ");Serial.println(pass_key); - /** Inject false if passkeys don't match. */ - NimBLEDevice::injectConfirmPasskey(connInfo, true); - } - - void onAuthenticationComplete(const BLEConnInfo& connInfo) { - Serial.println("Starting BLE work!"); - } -/*******************************************************************/ -}; - - -void setup() { - Serial.begin(115200); - - // Create the BLE Device - BLEDevice::init("ESP32"); - - // Create the BLE Server - pServer = BLEDevice::createServer(); - pServer->setCallbacks(new MyServerCallbacks()); - - // Create the BLE Service - BLEService *pService = pServer->createService(SERVICE_UUID); - - // Create a BLE Characteristic - pCharacteristic = pService->createCharacteristic( - CHARACTERISTIC_UUID, - /******* Enum Type NIMBLE_PROPERTY now ******* - BLECharacteristic::PROPERTY_READ | - BLECharacteristic::PROPERTY_WRITE | - BLECharacteristic::PROPERTY_NOTIFY | - BLECharacteristic::PROPERTY_INDICATE - ); - **********************************************/ - NIMBLE_PROPERTY::READ | - NIMBLE_PROPERTY::WRITE | - NIMBLE_PROPERTY::NOTIFY | - NIMBLE_PROPERTY::INDICATE - ); - - // Create a BLE Descriptor - /*************************************************** - NOTE: DO NOT create a 2902 descriptor. - it will be created automatically if notifications - or indications are enabled on a characteristic. - - pCharacteristic->addDescriptor(new BLE2902()); - ****************************************************/ - // Start the service - pService->start(); - - // Start advertising - BLEAdvertising *pAdvertising = BLEDevice::getAdvertising(); - pAdvertising->addServiceUUID(SERVICE_UUID); - pAdvertising->enableScanResponse(false); - /** Note, this could be left out as that is the default value */ - pAdvertising->setMinPreferred(0x0); // set value to 0x00 to not advertise this parameter - - BLEDevice::startAdvertising(); - Serial.println("Waiting a client connection to notify..."); -} - -void loop() { - // notify changed value - if (deviceConnected) { - pCharacteristic->setValue((uint8_t*)&value, 4); - pCharacteristic->notify(); - value++; - delay(3); // bluetooth stack will go into congestion, if too many packets are sent, in 6 hours test i was able to go as low as 3ms - } - // disconnecting - if (!deviceConnected && oldDeviceConnected) { - delay(500); // give the bluetooth stack the chance to get things ready - pServer->startAdvertising(); // restart advertising - Serial.println("start advertising"); - oldDeviceConnected = deviceConnected; - } - // connecting - if (deviceConnected && !oldDeviceConnected) { - // do stuff here on connecting - oldDeviceConnected = deviceConnected; - } -} \ No newline at end of file diff --git a/examples/Refactored_original_examples/BLE_scan/BLE_scan.ino b/examples/Refactored_original_examples/BLE_scan/BLE_scan.ino deleted file mode 100644 index c2c142f5..00000000 --- a/examples/Refactored_original_examples/BLE_scan/BLE_scan.ino +++ /dev/null @@ -1,49 +0,0 @@ -/* - Based on Neil Kolban example for IDF: https://github.com/nkolban/esp32-snippets/blob/master/cpp_utils/tests/BLE%20Tests/SampleScan.cpp - Ported to Arduino ESP32 by Evandro Copercini -*/ - -/** NimBLE differences highlighted in comment blocks **/ - -/*******original******** -#include -#include -#include -#include -***********************/ - -#include - -int scanTime = 5 * 1000; // In milliseconds, 0 = scan forever -BLEScan* pBLEScan; - -class MyAdvertisedDeviceCallbacks: public BLEAdvertisedDeviceCallbacks { - /*** Only a const pointer to the advertised device is passed now - void onResult(BLEAdvertisedDevice advertisedDevice) { **/ - void onResult(const BLEAdvertisedDevice* advertisedDevice) { - /** Serial.printf("Advertised Device: %s \n", advertisedDevice.toString().c_str()); **/ - Serial.printf("Advertised Device: %s \n", advertisedDevice->toString().c_str()); - } -}; - -void setup() { - Serial.begin(115200); - Serial.println("Scanning..."); - - BLEDevice::init(""); - pBLEScan = BLEDevice::getScan(); //create new scan - pBLEScan->setScanCallbacks(new MyAdvertisedDeviceCallbacks()); - pBLEScan->setActiveScan(true); //active scan uses more power, but get results faster - pBLEScan->setInterval(100); - pBLEScan->setWindow(99); // less or equal setInterval value -} - -void loop() { - // put your main code here, to run repeatedly: - BLEScanResults foundDevices = pBLEScan->getResults(scanTime, false); - Serial.print("Devices found: "); - Serial.println(foundDevices.getCount()); - Serial.println("Scan done!"); - pBLEScan->clearResults(); // delete results fromBLEScan buffer to release memory - delay(2000); -} \ No newline at end of file diff --git a/examples/Refactored_original_examples/BLE_server/BLE_server.ino b/examples/Refactored_original_examples/BLE_server/BLE_server.ino deleted file mode 100644 index 7e2b2f35..00000000 --- a/examples/Refactored_original_examples/BLE_server/BLE_server.ino +++ /dev/null @@ -1,57 +0,0 @@ -/* - Based on Neil Kolban example for IDF: https://github.com/nkolban/esp32-snippets/blob/master/cpp_utils/tests/BLE%20Tests/SampleServer.cpp - Ported to Arduino ESP32 by Evandro Copercini - updates by chegewara -*/ - -/** NimBLE differences highlighted in comment blocks **/ - -/*******original******** -#include -#include -#include -***********************/ - -#include - -// See the following for generating UUIDs: -// https://www.uuidgenerator.net/ - -#define SERVICE_UUID "4fafc201-1fb5-459e-8fcc-c5c9c331914b" -#define CHARACTERISTIC_UUID "beb5483e-36e1-4688-b7f5-ea07361b26a8" - -void setup() { - Serial.begin(115200); - Serial.println("Starting BLE work!"); - - BLEDevice::init("Long name works now"); - BLEServer *pServer = BLEDevice::createServer(); - BLEService *pService = pServer->createService(SERVICE_UUID); - BLECharacteristic *pCharacteristic = pService->createCharacteristic( - CHARACTERISTIC_UUID, - /***** Enum Type NIMBLE_PROPERTY now ***** - BLECharacteristic::PROPERTY_READ | - BLECharacteristic::PROPERTY_WRITE - ); - *****************************************/ - NIMBLE_PROPERTY::READ | - NIMBLE_PROPERTY::WRITE - ); - - pCharacteristic->setValue("Hello World says Neil"); - pService->start(); - // BLEAdvertising *pAdvertising = pServer->getAdvertising(); // this still is working for backward compatibility - BLEAdvertising *pAdvertising = BLEDevice::getAdvertising(); - pAdvertising->addServiceUUID(SERVICE_UUID); - pAdvertising->enableScanResponse(true); - pAdvertising->setMinPreferred(0x06); // functions that help with iPhone connections issue - pAdvertising->setMaxPreferred(0x12); - - BLEDevice::startAdvertising(); - Serial.println("Characteristic defined! Now you can read it in your phone!"); -} - -void loop() { - // put your main code here, to run repeatedly: - delay(2000); -} \ No newline at end of file diff --git a/examples/Refactored_original_examples/BLE_server_multiconnect/BLE_server_multiconnect.ino b/examples/Refactored_original_examples/BLE_server_multiconnect/BLE_server_multiconnect.ino deleted file mode 100644 index a1d340c0..00000000 --- a/examples/Refactored_original_examples/BLE_server_multiconnect/BLE_server_multiconnect.ino +++ /dev/null @@ -1,153 +0,0 @@ -/* - Video: https://www.youtube.com/watch?v=oCMOYS71NIU - Based on Neil Kolban example for IDF: https://github.com/nkolban/esp32-snippets/blob/master/cpp_utils/tests/BLE%20Tests/SampleNotify.cpp - Ported to Arduino ESP32 by Evandro Copercini - updated by chegewara - - Create a BLE server that, once we receive a connection, will send periodic notifications. - The service advertises itself as: 4fafc201-1fb5-459e-8fcc-c5c9c331914b - And has a characteristic of: beb5483e-36e1-4688-b7f5-ea07361b26a8 - - The design of creating the BLE server is: - 1. Create a BLE Server - 2. Create a BLE Service - 3. Create a BLE Characteristic on the Service - 4. Create a BLE Descriptor on the characteristic - 5. Start the service. - 6. Start advertising. - - A connect hander associated with the server starts a background task that performs notification - every couple of seconds. -*/ - -/** NimBLE differences highlighted in comment blocks **/ - -/*******original******** -#include -#include -#include -#include -***********************/ -#include - -BLEServer* pServer = NULL; -BLECharacteristic* pCharacteristic = NULL; -bool deviceConnected = false; -bool oldDeviceConnected = false; -uint32_t value = 0; - -// See the following for generating UUIDs: -// https://www.uuidgenerator.net/ - -#define SERVICE_UUID "4fafc201-1fb5-459e-8fcc-c5c9c331914b" -#define CHARACTERISTIC_UUID "beb5483e-36e1-4688-b7f5-ea07361b26a8" - - -/** None of these are required as they will be handled by the library with defaults. ** - ** Remove as you see fit for your needs */ -class MyServerCallbacks: public BLEServerCallbacks { - void onConnect(BLEServer* pServer, BLEConnInfo& connInfo) { - deviceConnected = true; - BLEDevice::startAdvertising(); - }; - - void onDisconnect(BLEServer* pServer, BLEConnInfo& connInfo, int reason) { - deviceConnected = false; - } - /***************** New - Security handled here ******************** - ****** Note: these are the same return values as defaults ********/ - uint32_t onPassKeyDisplay() { - Serial.println("Server Passkey Display"); - /** This should return a random 6 digit number for security - * or make your own static passkey as done here. - */ - return 123456; - } - - void onConfirmPIN(const BLEConnInfo& connInfo, uint32_t pass_key) { - Serial.print("The passkey YES/NO number: ");Serial.println(pass_key); - /** Inject false if passkeys don't match. */ - NimBLEDevice::injectConfirmPasskey(connInfo, true); - } - - void onAuthenticationComplete(const BLEConnInfo& connInfo) { - Serial.println("Starting BLE work!"); - } - /*******************************************************************/ -}; - - - -void setup() { - Serial.begin(115200); - - // Create the BLE Device - BLEDevice::init("ESP32"); - - // Create the BLE Server - pServer = BLEDevice::createServer(); - pServer->setCallbacks(new MyServerCallbacks()); - - // Create the BLE Service - BLEService *pService = pServer->createService(SERVICE_UUID); - - // Create a BLE Characteristic - pCharacteristic = pService->createCharacteristic( - CHARACTERISTIC_UUID, - /******* Enum Type NIMBLE_PROPERTY now ******* - BLECharacteristic::PROPERTY_READ | - BLECharacteristic::PROPERTY_WRITE | - BLECharacteristic::PROPERTY_NOTIFY | - BLECharacteristic::PROPERTY_INDICATE - ); - **********************************************/ - NIMBLE_PROPERTY::READ | - NIMBLE_PROPERTY::WRITE | - NIMBLE_PROPERTY::NOTIFY | - NIMBLE_PROPERTY::INDICATE - ); - - // Create a BLE Descriptor - /*************************************************** - NOTE: DO NOT create a 2902 descriptor - it will be created automatically if notifications - or indications are enabled on a characteristic. - - pCharacteristic->addDescriptor(new BLE2902()); - ****************************************************/ - - // Start the service - pService->start(); - - // Start advertising - BLEAdvertising *pAdvertising = BLEDevice::getAdvertising(); - pAdvertising->addServiceUUID(SERVICE_UUID); - pAdvertising->enableScanResponse(false); - /** Note, this could be left out as that is the default value */ - pAdvertising->setMinPreferred(0x0); // set value to 0x00 to not advertise this parameter - - BLEDevice::startAdvertising(); - Serial.println("Waiting a client connection to notify..."); -} - -void loop() { - // notify changed value - if (deviceConnected) { - pCharacteristic->setValue((uint8_t*)&value, 4); - pCharacteristic->notify(); - value++; - delay(10); // bluetooth stack will go into congestion, if too many packets are sent, in 6 hours test i was able to go as low as 3ms - } - // disconnecting - if (!deviceConnected && oldDeviceConnected) { - delay(500); // give the bluetooth stack the chance to get things ready - pServer->startAdvertising(); // restart advertising - Serial.println("start advertising"); - oldDeviceConnected = deviceConnected; - } - // connecting - if (deviceConnected && !oldDeviceConnected) { - // do stuff here on connecting - oldDeviceConnected = deviceConnected; - } -} diff --git a/examples/Refactored_original_examples/BLE_uart/BLE_uart.ino b/examples/Refactored_original_examples/BLE_uart/BLE_uart.ino deleted file mode 100644 index f1914ae5..00000000 --- a/examples/Refactored_original_examples/BLE_uart/BLE_uart.ino +++ /dev/null @@ -1,167 +0,0 @@ -/* - Video: https://www.youtube.com/watch?v=oCMOYS71NIU - Based on Neil Kolban example for IDF: https://github.com/nkolban/esp32-snippets/blob/master/cpp_utils/tests/BLE%20Tests/SampleNotify.cpp - Ported to Arduino ESP32 by Evandro Copercini - - Create a BLE server that, once we receive a connection, will send periodic notifications. - The service advertises itself as: 6E400001-B5A3-F393-E0A9-E50E24DCCA9E - Has a characteristic of: 6E400002-B5A3-F393-E0A9-E50E24DCCA9E - used for receiving data with "WRITE" - Has a characteristic of: 6E400003-B5A3-F393-E0A9-E50E24DCCA9E - used to send data with "NOTIFY" - - The design of creating the BLE server is: - 1. Create a BLE Server - 2. Create a BLE Service - 3. Create a BLE Characteristic on the Service - 4. Create a BLE Descriptor on the characteristic - 5. Start the service. - 6. Start advertising. - - In this example rxValue is the data received (only accessible inside that function). - And txValue is the data to be sent, in this example just a byte incremented every second. -*/ - -/** NimBLE differences highlighted in comment blocks **/ - -/*******original******** -#include -#include -#include -#include -***********************/ -#include - -BLEServer *pServer = NULL; -BLECharacteristic * pTxCharacteristic; -bool deviceConnected = false; -bool oldDeviceConnected = false; -uint8_t txValue = 0; - -// See the following for generating UUIDs: -// https://www.uuidgenerator.net/ - -#define SERVICE_UUID "6E400001-B5A3-F393-E0A9-E50E24DCCA9E" // UART service UUID -#define CHARACTERISTIC_UUID_RX "6E400002-B5A3-F393-E0A9-E50E24DCCA9E" -#define CHARACTERISTIC_UUID_TX "6E400003-B5A3-F393-E0A9-E50E24DCCA9E" - - -/** None of these are required as they will be handled by the library with defaults. ** - ** Remove as you see fit for your needs */ -class MyServerCallbacks: public BLEServerCallbacks { - void onConnect(BLEServer* pServer, BLEConnInfo& connInfo) { - deviceConnected = true; - }; - - void onDisconnect(BLEServer* pServer, BLEConnInfo& connInfo, int reason) { - deviceConnected = false; - } - /***************** New - Security handled here ******************** - ****** Note: these are the same return values as defaults ********/ - uint32_t onPassKeyDisplay() { - Serial.println("Server Passkey Display"); - /** This should return a random 6 digit number for security - * or make your own static passkey as done here. - */ - return 123456; - } - - void onConfirmPasskey(const BLEConnInfo& connInfo, uint32_t pass_key) { - Serial.print("The passkey YES/NO number: ");Serial.println(pass_key); - /** Inject false if passkeys don't match. */ - NimBLEDevice::injectConfirmPasskey(connInfo, true); - } - - void onAuthenticationComplete(const BLEConnInfo& connInfo) { - Serial.println("Starting BLE work!"); - } - /*******************************************************************/ -}; - -class MyCallbacks: public BLECharacteristicCallbacks { - void onWrite(BLECharacteristic *pCharacteristic, BLEConnInfo& connInfo) { - std::string rxValue = pCharacteristic->getValue(); - - if (rxValue.length() > 0) { - Serial.println("*********"); - Serial.print("Received Value: "); - for (int i = 0; i < rxValue.length(); i++) - Serial.print(rxValue[i]); - - Serial.println(); - Serial.println("*********"); - } - } -}; - - -void setup() { - Serial.begin(115200); - - // Create the BLE Device - BLEDevice::init("UART Service"); - - // Create the BLE Server - pServer = BLEDevice::createServer(); - pServer->setCallbacks(new MyServerCallbacks()); - - // Create the BLE Service - BLEService *pService = pServer->createService(SERVICE_UUID); - - // Create a BLE Characteristic - pTxCharacteristic = pService->createCharacteristic( - CHARACTERISTIC_UUID_TX, - /******* Enum Type NIMBLE_PROPERTY now ******* - BLECharacteristic::PROPERTY_NOTIFY - ); - **********************************************/ - NIMBLE_PROPERTY::NOTIFY - ); - - /*************************************************** - NOTE: DO NOT create a 2902 descriptor - it will be created automatically if notifications - or indications are enabled on a characteristic. - - pCharacteristic->addDescriptor(new BLE2902()); - ****************************************************/ - - BLECharacteristic * pRxCharacteristic = pService->createCharacteristic( - CHARACTERISTIC_UUID_RX, - /******* Enum Type NIMBLE_PROPERTY now ******* - BLECharacteristic::PROPERTY_WRITE - ); - *********************************************/ - NIMBLE_PROPERTY::WRITE - ); - - pRxCharacteristic->setCallbacks(new MyCallbacks()); - - // Start the service - pService->start(); - - // Start advertising - pServer->getAdvertising()->start(); - Serial.println("Waiting a client connection to notify..."); -} - -void loop() { - - if (deviceConnected) { - pTxCharacteristic->setValue(&txValue, 1); - pTxCharacteristic->notify(); - txValue++; - delay(10); // bluetooth stack will go into congestion, if too many packets are sent - } - - // disconnecting - if (!deviceConnected && oldDeviceConnected) { - delay(500); // give the bluetooth stack the chance to get things ready - pServer->startAdvertising(); // restart advertising - Serial.println("start advertising"); - oldDeviceConnected = deviceConnected; - } - // connecting - if (deviceConnected && !oldDeviceConnected) { - // do stuff here on connecting - oldDeviceConnected = deviceConnected; - } -} diff --git a/examples/Refactored_original_examples/BLE_write/BLE_write.ino b/examples/Refactored_original_examples/BLE_write/BLE_write.ino deleted file mode 100644 index a48fa01f..00000000 --- a/examples/Refactored_original_examples/BLE_write/BLE_write.ino +++ /dev/null @@ -1,75 +0,0 @@ -/* - Based on Neil Kolban example for IDF: https://github.com/nkolban/esp32-snippets/blob/master/cpp_utils/tests/BLE%20Tests/SampleWrite.cpp - Ported to Arduino ESP32 by Evandro Copercini -*/ - -/** NimBLE differences highlighted in comment blocks **/ - -/*******original******** -#include -#include -#include -***********************/ -#include - -// See the following for generating UUIDs: -// https://www.uuidgenerator.net/ - -#define SERVICE_UUID "4fafc201-1fb5-459e-8fcc-c5c9c331914b" -#define CHARACTERISTIC_UUID "beb5483e-36e1-4688-b7f5-ea07361b26a8" - - -class MyCallbacks: public BLECharacteristicCallbacks { - void onWrite(BLECharacteristic *pCharacteristic, BLEConnInfo& connInfo) { - std::string value = pCharacteristic->getValue(); - - if (value.length() > 0) { - Serial.println("*********"); - Serial.print("New value: "); - for (int i = 0; i < value.length(); i++) - Serial.print(value[i]); - - Serial.println(); - Serial.println("*********"); - } - } -}; - -void setup() { - Serial.begin(115200); - - Serial.println("1- Download and install an BLE scanner app in your phone"); - Serial.println("2- Scan for BLE devices in the app"); - Serial.println("3- Connect to MyESP32"); - Serial.println("4- Go to CUSTOM CHARACTERISTIC in CUSTOM SERVICE and write something"); - Serial.println("5- See the magic =)"); - - BLEDevice::init("MyESP32"); - BLEServer *pServer = BLEDevice::createServer(); - - BLEService *pService = pServer->createService(SERVICE_UUID); - - BLECharacteristic *pCharacteristic = pService->createCharacteristic( - CHARACTERISTIC_UUID, - /***** Enum Type NIMBLE_PROPERTY now ***** - BLECharacteristic::PROPERTY_READ | - BLECharacteristic::PROPERTY_WRITE - ); - *****************************************/ - NIMBLE_PROPERTY::READ | - NIMBLE_PROPERTY::WRITE - ); - - pCharacteristic->setCallbacks(new MyCallbacks()); - - pCharacteristic->setValue("Hello World"); - pService->start(); - - BLEAdvertising *pAdvertising = pServer->getAdvertising(); - pAdvertising->start(); -} - -void loop() { - // put your main code here, to run repeatedly: - delay(2000); -} \ No newline at end of file