From 3579a5f182b49e68144c13c03d67ad428798ac1c Mon Sep 17 00:00:00 2001 From: h2zero Date: Thu, 27 Jun 2024 14:05:26 -0600 Subject: [PATCH] build ext server example --- .github/workflows/build.yml | 19 ++- .../BLE_Ext_Server/BLE_Ext_Server.ino | 160 ++++++++++++++++++ .../examples/BLE_Ext_Server/build_opt.h | 1 + 3 files changed, 178 insertions(+), 2 deletions(-) create mode 100644 libraries/n-able/examples/BLE_Ext_Server/BLE_Ext_Server.ino create mode 100644 libraries/n-able/examples/BLE_Ext_Server/build_opt.h diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index e255fbd..5a21044 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -54,6 +54,19 @@ jobs: - "libraries/n-able/examples/FreeRTOS" - "libraries/n-able/examples/BLE_Advertiser" - "libraries/n-able/examples/BLE_Scan" + - "libraries/n-able/examples/BLE_Ext_Server" + variant: + - generic_nrf52832 + - generic_nrf52833 + - generic_nrf52840 + - adafruit_feather_nrf52840 + include: + - example: "libraries/n-able/examples/BLE_Ext_Server" + flags: build_flags = '-DCONFIG_BT_NIMBLE_EXT_ADV=1' + exclude: + - example: "libraries/n-able/examples/BLE_Ext_Server" + variant: generic_nrf52832 + runs-on: ubuntu-latest @@ -78,9 +91,11 @@ jobs: platform_packages = framework-n-able-arduino @ file://./framework framework = arduino lib_deps = h2zero/NimBLE-Arduino + ${{ matrix.flags }} - [env:generic_nrf52840] - board = generic_nrf52840 + [env:${{ matrix.variant }}] + board = ${{ matrix.variant }} EOF cp ${{ matrix.example }}/* example/src/ platformio run -d example + diff --git a/libraries/n-able/examples/BLE_Ext_Server/BLE_Ext_Server.ino b/libraries/n-able/examples/BLE_Ext_Server/BLE_Ext_Server.ino new file mode 100644 index 0000000..029469f --- /dev/null +++ b/libraries/n-able/examples/BLE_Ext_Server/BLE_Ext_Server.ino @@ -0,0 +1,160 @@ +/** NimBLE Extended Advertiser Demo: + * + * Demonstrates the Bluetooth 5.x extended advertising capabilities. + * + * This demo will advertise a long data string on the CODED and 1M Phy's and + * starts a server allowing connection over either PHY's. It will advertise for + * 5 seconds then sleep for 20 seconds, if a client connects it will sleep once + * it has disconnected then repeats. + * + * Created: on April 2 2022 + * Author: H2zero + * +*/ + +#include "NimBLEDevice.h" +#if !CONFIG_BT_NIMBLE_EXT_ADV +# error Must enable extended advertising, see nimconfig.h file. +#endif + +#ifdef ESP_PLATFORM +#include "esp_sleep.h" +#endif + +#define SERVICE_UUID "ABCD" +#define CHARACTERISTIC_UUID "1234" + +/* Time in milliseconds to advertise */ +static uint32_t advTime = 5000; + +/* 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 */ +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 + */ +static uint8_t secondaryPhy = BLE_HCI_LE_PHY_1M; + + +/* Handler class for server events */ +class ServerCallbacks: public NimBLEServerCallbacks { + void onConnect(NimBLEServer* pServer, NimBLEConnInfo& connInfo) { + 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); +#ifdef ESP_PLATFORM + esp_deep_sleep_start(); +#else + systemRestart(); // nRF platforms restart then sleep via delay in setup. +#endif + }; +}; + +/* Callback class to handle advertising events */ +class advertisingCallbacks: public NimBLEExtAdvertisingCallbacks { + void onStopped(NimBLEExtAdvertising* pAdv, int reason, uint8_t inst_id) { + /* Check the reason advertising stopped, don't sleep if client is connecting */ + printf("Advertising instance %u stopped\n", inst_id); + switch (reason) { + case 0: + printf("Client connecting\n"); + return; + case BLE_HS_ETIMEOUT: + 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 + } +}; + +void setup () { + Serial.begin(115200); +#ifndef ESP_PLATFORM + delay(sleepSeconds * 1000); // system ON sleep mode for nRF platforms to simulate the esp deep sleep with timer wakeup +#endif + + NimBLEDevice::init("Extended advertiser"); + + /* Create the server and add the services/characteristics/descriptors */ + NimBLEServer *pServer = NimBLEDevice::createServer(); + pServer->setCallbacks(new ServerCallbacks); + + 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 */ + 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. + */ + NimBLEExtAdvertisement extAdv(primaryPhy, secondaryPhy); + + /* Set the advertisement as connectable */ + extAdv.setConnectable(true); + + /* 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.")); + + extAdv.setCompleteServices16({NimBLEUUID(SERVICE_UUID)}); + + /* 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); + + /* + * 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. + */ + 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). + */ + if (pAdvertising->start(0, advTime)) { + Serial.printf("Started advertising\n"); + } else { + Serial.printf("Failed to start advertising\n"); + } + } else { + Serial.printf("Failed to register advertisment data\n"); + } + +#ifdef ESP_PLATFORM + esp_sleep_enable_timer_wakeup(sleepSeconds * 1000000); +#endif +} + +void loop () { +} \ No newline at end of file diff --git a/libraries/n-able/examples/BLE_Ext_Server/build_opt.h b/libraries/n-able/examples/BLE_Ext_Server/build_opt.h new file mode 100644 index 0000000..d3ab4f2 --- /dev/null +++ b/libraries/n-able/examples/BLE_Ext_Server/build_opt.h @@ -0,0 +1 @@ +'-DCONFIG_BT_NIMBLE_EXT_ADV=1' \ No newline at end of file