Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /**
- * A BLE client example that is rich in capabilities.
- * There is a lot new capabilities implemented.
- * author unknown
- * updated by chegewara
- *
- * Patched: remove unsafe notify registration, fix return value, add safety checks.
- */
- #include <string>
- #include "BLEDevice.h"
- #include "BLEScan.h"
- // The remote service we wish to connect to.
- static BLEUUID serviceUUID("38d98c26-26ed-430d-83ee-04848df9c4e3");
- // The characteristic of the remote service we are interested in.
- static BLEUUID charUUID("0f9162bf-09eb-42c0-853d-19ea0847a71d");
- static boolean doConnect = false;
- static boolean connected = false;
- static boolean doScan = false;
- static BLERemoteCharacteristic* pRemoteCharacteristic = nullptr;
- static BLEAdvertisedDevice* myDevice = nullptr;
- // Kept for future use if you add NOTIFY on the server.
- 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: ");
- // Print length-safe (don't assume pData is NUL-terminated)
- for (size_t i = 0; i < length; ++i) {
- Serial.print((char)pData[i]);
- }
- Serial.println();
- }
- class MyClientCallback : public BLEClientCallbacks {
- void onConnect(BLEClient* /*pclient*/) override {
- }
- void onDisconnect(BLEClient* /*pclient*/) override {
- connected = false;
- Serial.println("onDisconnect");
- }
- };
- 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 remote BLE Server.
- pClient->connect(myDevice); // using BLEAdvertisedDevice preserves address type
- 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());
- }
- // IMPORTANT:
- // Do NOT register for notifications unless the server characteristic
- // has PROPERTY_NOTIFY and exposes a CCCD (0x2902). Your server does not.
- // if (pRemoteCharacteristic->canNotify()) {
- // auto* cccd = pRemoteCharacteristic->getDescriptor(BLEUUID((uint16_t)0x2902));
- // if (cccd) pRemoteCharacteristic->registerForNotify(notifyCallback);
- // }
- connected = true;
- return true; // FIX: correctly report success
- }
- // Scan for BLE servers and find the first one that advertises the service we are looking for.
- class MyAdvertisedDeviceCallbacks : public BLEAdvertisedDeviceCallbacks {
- void onResult(BLEAdvertisedDevice advertisedDevice) override {
- 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)) {
- BLEDevice::getScan()->stop();
- myDevice = new BLEAdvertisedDevice(advertisedDevice);
- doConnect = true;
- doScan = true; // allow re-scan after disconnect (optional)
- }
- }
- };
- 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->setAdvertisedDeviceCallbacks(new MyAdvertisedDeviceCallbacks());
- pBLEScan->setInterval(1349);
- pBLEScan->setWindow(449);
- pBLEScan->setActiveScan(true);
- pBLEScan->start(5, false);
- }
- // Arduino main loop
- void loop() {
- // If the flag "doConnect" is true then we have scanned for and found the desired BLE Server.
- if (doConnect) {
- 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 nothing more we will do.");
- }
- doConnect = false;
- }
- // If connected, write to the characteristic each second.
- if (connected && pRemoteCharacteristic != nullptr) {
- if (pRemoteCharacteristic->canWrite()) {
- String newValue = "Time since boot: " + String(millis() / 1000);
- Serial.println("Setting new characteristic value to \"" + newValue + "\"");
- pRemoteCharacteristic->writeValue(newValue.c_str(), newValue.length());
- }
- } else if (doScan) {
- // Restart scan after disconnect (example behavior).
- BLEDevice::getScan()->start(0); // non-blocking continuous scan
- }
- delay(1000);
- }
Advertisement
Add Comment
Please, Sign In to add comment