/* 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) { 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); }