diff --git a/libraries/BLE/examples/BLE_iBeacon/BLE_iBeacon.ino b/libraries/BLE/examples/BLE_iBeacon/BLE_iBeacon.ino index 324e821e95c..5ebcec65077 100644 --- a/libraries/BLE/examples/BLE_iBeacon/BLE_iBeacon.ino +++ b/libraries/BLE/examples/BLE_iBeacon/BLE_iBeacon.ino @@ -1,104 +1,138 @@ -/* - 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 - -*/ -#include "sys/time.h" - -#include "BLEDevice.h" -#include "BLEUtils.h" -#include "BLEBeacon.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); - -} - -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() { -} +/* + Based on 31337Ghost's reference code from https://github.com/nkolban/esp32-snippets/issues/385#issuecomment-362535434 + which is based on pcbreflux's Arduino ESP32 port of Neil Kolban's example for IDF: https://github.com/nkolban/esp32-snippets/blob/master/cpp_utils/tests/BLE%20Tests/SampleScan.cpp +*/ + +/* + 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. +*/ +#include +#include +#include +#include +#include + +#define DEVICE_NAME "ESP32" +#define SERVICE_UUID "7A0247E7-8E88-409B-A959-AB5092DDB03E" +#define BEACON_UUID "2D7A9F0C-E0E8-4CC9-A71B-A21DB2D034A1" +#define BEACON_UUID_REV "A134D0B2-1DA2-1BA7-C94C-E8E00C9F7A2D" +#define CHARACTERISTIC_UUID "82258BAA-DF72-47E8-99BC-B73D7ECD08A5" + +BLEServer *pServer; +BLECharacteristic *pCharacteristic; +bool deviceConnected = false; +uint8_t value = 0; + +class MyServerCallbacks: public BLEServerCallbacks { + void onConnect(BLEServer* pServer) { + deviceConnected = true; + Serial.println("deviceConnected = true"); + }; + + void onDisconnect(BLEServer* pServer) { + deviceConnected = false; + Serial.println("deviceConnected = false"); + + // Restart advertising to be visible and connectable again + BLEAdvertising* pAdvertising; + pAdvertising = pServer->getAdvertising(); + pAdvertising->start(); + Serial.println("iBeacon advertising restarted"); + } +}; + +class MyCallbacks: public BLECharacteristicCallbacks { + void onWrite(BLECharacteristic *pCharacteristic) { + 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 init_service() { + BLEAdvertising* pAdvertising; + pAdvertising = pServer->getAdvertising(); + pAdvertising->stop(); + + // Create the BLE Service + BLEService *pService = pServer->createService(BLEUUID(SERVICE_UUID)); + + // Create a BLE Characteristic + pCharacteristic = pService->createCharacteristic( + CHARACTERISTIC_UUID, + BLECharacteristic::PROPERTY_READ | + BLECharacteristic::PROPERTY_WRITE | + BLECharacteristic::PROPERTY_NOTIFY + ); + pCharacteristic->setCallbacks(new MyCallbacks()); + pCharacteristic->addDescriptor(new BLE2902()); + + pAdvertising->addServiceUUID(BLEUUID(SERVICE_UUID)); + + // Start the service + pService->start(); + + pAdvertising->start(); +} + +void init_beacon() { + BLEAdvertising* pAdvertising; + pAdvertising = pServer->getAdvertising(); + pAdvertising->stop(); + // iBeacon + BLEBeacon myBeacon; + myBeacon.setManufacturerId(0x4c00); + myBeacon.setMajor(5); + myBeacon.setMinor(88); + myBeacon.setSignalPower(0xc5); + myBeacon.setProximityUUID(BLEUUID(BEACON_UUID_REV)); + + BLEAdvertisementData advertisementData; + advertisementData.setFlags(0x1A); + advertisementData.setManufacturerData(myBeacon.getData()); + pAdvertising->setAdvertisementData(advertisementData); + + pAdvertising->start(); +} + +void setup() { + Serial.begin(115200); + Serial.println(); + Serial.println("Initializing..."); + Serial.flush(); + + BLEDevice::init(DEVICE_NAME); + pServer = BLEDevice::createServer(); + pServer->setCallbacks(new MyServerCallbacks()); + + init_service(); + init_beacon(); + + Serial.println("iBeacon + service defined and advertising!"); +} + +void loop() { + if (deviceConnected) { + Serial.printf("*** NOTIFY: %d ***\n", value); + pCharacteristic->setValue(&value, 1); + pCharacteristic->notify(); + value++; + } + delay(2000); +}