Bluetooth Low Energy


Bluetooth Low Energy (a.k.a Bluetooth LE, BTLE, Bluetooth Smart)

You are viewing an older revision! See the latest version

API Development

API Development

Change Requests

Main header file name (cacu) [DONE - rgrover1]

<ble.h> or <bledevice.h> rather than <nRF51822n.h>. That way if one day the developer switches chips he does not have to change the source

Main stack instance (cacu) [DONE - rgrover1]

Currently it is "nRF51822n nrf;", I suggest "BLEDevice ble;" instead

Repo Layout and Code sharing across multiple chipsets (cacu)

Currently the repo layout looks like this:

|-- BLE_API_Native
|   |-- hw
|   |   |-- nRF51822n
|   |   |   |-- btle
|   |   |   |-- common
|   |   |   |-- nordic
|   |   |   | nRF51Gap.cpp
|   |   |   | nRF51Gap.h
|   |   |   | [...]
|   |   |   | projectconfig.h
|   |   |
|   |   | BLEDevice.h
|   |   | Gap.h
|   |   | GapEvents.h
|   |   | GattServer.h
|   |   | GattServerEvents.h
|   |-- mbed-src-Nordic
|   
| blecommon.h
| GapAdvertisingData.cpp
| GapAdvertisingData.h
| [...]
| UUID.h
|

I think this layout does not split the common vs the chip-specific code clearly.

Instead I would suggest something along these lines:

|-- ble
|   |-- public // the public API that app developers are going to use, those are the only files they need to include
|   |   | BLEDevice.h
|   |   | Gap.h
|   |   | GapEvents.h
|   |   | GattServer.h
|   |   | GattServerEvents.h
|   |   | GapAdvertisingData.h
|   |   | GapAdvertisingParams.h
|   |   | GattCharacteristic.h
|   |   | GattService.h
|   |   | UUID.h
|   |-- common
|   |   |-- hwapi // internal API for the hardware, isolates the chip-specific code from the common classes
|   |   |    | HwBLEDevice.h 
|   |   |    | ???  // depending on how this internal API is split there may be more interface files headers 
|   |   |    | [...]
|   |   | blecommon.h // all files on this level are common to all chips, they include the implementation to the "public" folder
|   |   | GapAdvertisingData.cpp
|   |   | [...]
|   |   | UUID.cpp
|   |   | BLEDevice.cpp // this implements the API in public/
|   |   | Gap.cpp
|   |   | GapEvents.cpp
|   |   | GattServer.cpp
|   |   | GattServerEvents.cpp
|   |-- hw
|   |   |-- nRF51822n
|   |   |   |-- btle
|   |   |   |-- common
|   |   |   |-- nordic
|   |   |   |-- mbed-src-Nordic
|   |   |   | nRF51BLEDevice.cpp // this implements the HwBLEDevice.h API in common/hwapi
|   |   |   | ??? // depending on how this internal API is split there may be more implementation files
|   |   |   | [...]
|   |   |   | projectconfig.h
|   |   |
|   |   |-- <Another chipset>
|

Using the above repo layout, then the files in common/ would not need to know about which radio is running:

in ble/common:

class BLEDevice
{
   HwBLEDevice hwBLEDevice;
}


void GAP::startAdvertising(void)
{
   // common adv code
  this->state = GAP_ADV;
   // tell the radio to start advertising 
   hwBLEDevice.startAdvertising();
}

And the application would simply:

BLEDevice bleDevice;

void main(void)
{
    bleDevice.reset();
    bleDevice.startAdvertising();
}

Reason code on disconnection (cacu)

Allow the application to provide a reason code when initiating a disconnection

Move GAP service functions to Gap.h (cacu)

The following funcions should really be in Gap.h:

virtual ble_error_t setDeviceName(const uint8_t *deviceName) = 0; virtual ble_error_t getDeviceName(uint8_t *deviceName, unsigned *lengthP) = 0; virtual ble_error_t setAppearance(uint16_t appearance) = 0; virtual ble_error_t getAppearance(uint16_t *appearanceP) = 0;

Connection Handles in all relevant API calls / Multiple instances (cacu)

Even when acting as a peripheral, version 4.1 of the specification allows connections to multiple centrals. A connection handle is therefore required in most of the API calls that deal with link-specific things: disconnecting, data transfer, etc. Another option is to use multiple instances, but that would perhaps be more cumbersome.

GattServer::updateValue without packet out (cacu) - DONE (ktown)

For servers that do not want to notify/indicate always, it would be practical to have an overload (or param) to tell the stack to only change the value locally, without sending any packets out.

onUpdatesEnabled/Disabled: merge and flags (cacu)

It would be good to have an additional flags parameter with the flags (notification, and/or indications) enabled or disabled. this would allow the app to know which of the two (or both) are enabled or disabled, and would also allow us to merge both into a single callback.

Examples: use onConnected (cacu) - DONE (KTOWN)

All examples should not send any data until they are connected to the central. Right now they start just after advertising begins.

Examples: use onUpdatesEnabled (cacu)

All examples using notifications or indications should wait until the central has enabled the CCCD before they start sending data.

Feature Requests

Additional functionality not currently covered by the API

Connection Parameter Update Procedure (cacu) (DONE)

This is critical for many applications, add it in GAP.

OTA DFU

  • 2 options: - Integrate DFU service and DFU into the app (BLE APIs).

- Use the current SDK-sanctioned model where we reboot into the bootload and then expose the DFU service, additionally triggered by a "Start DFU" char writeable from the phone app (preferred).

  • Use the standard SDK OTA DFU libraries and integrate them into the mbed BLE libs: This is located in "Board\nrf6310\experimental\device_firmware_updates" in the SDK 6.0.0 release.

- By default the SDK requires a physical trigger to start OTA DFU

- Add a special service and characteristic to trigger OTA DFU from the peer. This has to be implemented both on the mbed BLE code and the smartphone app or PC software. Alternative: use LightBlue (or MCP) first, then switch to OTA DFU app.

  • Online IDE + drag and drop: merge Bootloader+App+SoftDevice into a single .hex file.

- The bootloader needs to contain the UICR values mapped into the .hex

- When compiling an app for OTA DFU, generate an app-only .hex file (requires a new target in the online IDE)

- Bootloader in source form as a part of the library tree, when pulling in the bootloader (as OTA DFU support), support for "Start DFU" char is pulled in automatically

  • Keil + drag and drop: delayed for later, once OTA DFU works with online IDE+drag and drop
  • From SD 7.0.0 onwards, the UICR contents are no longer in the SD .hex file in a format that is automatically flashed, the UICR is erased (drag and drop erases the whole chip) and remains so until flashing the bootloader.
  • The bootloader needs to write its own version of the UICR values into the UICR register, it does so by simply containing the values mapped at the UICR address.
  • Torsten main Nordic contact

Triggering DFU and rebooting into the bootloader

   if (bootloader_is_pushed || (!bootloader_app_is_valid(DFU_BANK_0_REGION_START)))
    {
        nrf_gpio_pin_set(LED_2);

        // Initiate an update of the firmware.
        err_code = bootloader_dfu_start();
        APP_ERROR_CHECK(err_code);

        nrf_gpio_pin_clear(LED_2);
    }

peripheral as GATT client (cacu)

  • SDK does implement a layer on top of the SD, covering at the very least service and characteristic discovery.
  • Makes sense for the BLE API to reuse as much of that as possible.

- FindCharacteristic(serviceUUID, characteristicUUID)

- onCharacteristicFound(characteristic)

  • All procedures need to be multilink-aware and ready.
  • Single call or multi-call: In principle single-call with results callback
  • Discovery support:
  • Primary or Secondary Service
  • Characteristic - Descriptor
  • Read support: - Read Char value - Read using Char UUID
  • Write support: - Write Without Response (aka Write Command) - Write Request
  • Server Initiated: - Notifications - Indications

GAP: Security (cacu)

Integrate with the Device Manager and whatever non-volatile storage mechanisms are present in mbed to bond and store keys.

- Go over the Device Manager API and see if it can map consistently to the existing C++ classes and any required new ones. - Requires the following SDK modules: pstorage device manager - Will require additional RAM, provided by XLR3+ (32KB RAM version of the nRF51). - Krishna is the main dev Nordic contact, check for availability.

- Second stage: provide a plugin interface for customers to define their own pstorage backing storage medium.

support for read/write authorization (rgrover)

GATT Server timeout event (cacu)

Similar to GAP, a timeout event is required to notify the app that an operation has timed out.

unit-test various advertising/discovery options: non-discoverable; limited discoverable; general discoverable (rgrover1)

Unit test the correct encapsulation and formatting of multiple AD data types (rgrover1)

introduce API for setScanResponse(); and support for active scanning; ADV_SCAN_IND; unit test (rgrover1)

This is important. Also bear in mind that in S110 7.0.0 there will be a new event for the application every time a scan response is sent by the advertiser (this serves as sort of confirmation that the scanner has received the data).

white-list for advertising (rgrover1)

Start with address-based white list first, then add support for IRK whitelisting. iOS devices can only be whitelisted using IRK and not address, but for that you would need pairing and bonding first. I think starting with address whitelisting is reasonable, but bear in mind the IRKs to be added later when you add the API.

create demos for SIG-defiend GATT profiles

  • proximity
  • find-me
  • HID over GATT
  • A full list of SIG-approved profiles is available at the Bluetooth SIG's Specification Adopted Documents page.

This can be time-consuming, and will require a lot of development effort, especially for complex profiles like glucose meter and some of the sports profiles. Also remember Apple's ANCS, which seems to be extremely popular. Someone actually has a proof of concept: http://mbed.org/users/devsar/code/BLE_ANCS_SDAPI/file/1f985a7c0a8b/main.cpp

setting of connection parameters; and changing them dynamically (rgrover1)

terminating connection

name discovery procedure using GAP advertisement data; and also using GATT

[s110 v7/BLE4.1] concurrent peripheral and broadcaster

[BLE4.1 specific]: L2CAP user-defined channels; LE credit-based flow control mode

The S110 7.0.0 SD will still not support this unfortunately, you will have to wait until the S130.

  • Description (request author)

All wikipages