Bluetooth Low Energy (BLE)

Note: The code snippets in this article are intended for Mita version 1a1ed7881e2220895ec60ce4f657972538c43195 and XDK-Workbench versions 3.4.0 and higher.

The BLE API provides several interfaces to manage the BLE functionality on the XDK. XDK applications can implement this API to communicate over the BT EM9301 chip with surrounding BLE devices. XDK-Live offers an abstraction that solely focuses on allowing devices to connect with the XDK and to send messages via custom characteristics. This allows for simple and easily understandable implementations of BLE functionality.

  1. General Information
    1. Understanding the Protocols
      1. GAP - General Access Profile
      2. GATT - Generic Attribute Profile
      3. L2CAP - Logical Link Control and Adaptation Protocol
      4. HCI - Host Controller Interface
    2. About BLE Communication Roles
    3. Understanding BLE Data Profiles and Services
      1. BLE Data Hierarchy
  2. API Overview
    1. Setting up a BLE resource
    2. Setting up variable topic-signals
    3. Writing on a Characteristic
    4. Reading a Characteristic
    5. Settings
      1. Device Name
      2. Advertising Interval
      3. Service UID
    6. Full Code Example

General Information

Understanding the Protocols

BLE is built up of several protocols that are being used on different layers to transfer information between physical parts of the chip and the application level. The protocols supported by the ALPWISE BLE stack are depicted in the following picture and explained beneath.

Image

GAP - General Access Profile

  • initializing and configuring the internal BLE module in regards to BLE role and parameters
  • advertising data visible to other BLE devices with the goal of a connection establishment
  • discovering other devices that are in an advertising state
  • connecting to and disconnecting from devices

GATT - Generic Attribute Profile

  • configuring the data to be provided to other BLE devices
  • querying available data and how the data can be read and/or written
  • providing data exchange services between two BLE devices which interact as server and client (e.g. reading and writing data)
  • multiplexing data between higher layer protocols and lower physical layer protocols
  • segmenting and reassembling incoming and outgoing packets

HCI - Host Controller Interface

  • provides a command interface between a BLE application on a host controller (e.g. XDK application, laptop debugging console) and the BLE controller inside of the XDK
  • enables direct interaction possibilities for the host, like device configuration, discovery, connection, sending / receiving data, etc.

About BLE Communication Roles

The BLE controller (EM9301) supports Bluetooth version 4.0 and can be run as a master or slave device. Depending on state and configuration, the BLE controller can act in the communication roles as seen in the following picture.

Image

One of the most important differences between a peripheral and central device is that:

  • BLE peripheral mode will support advertising data and accepting incoming connection requests
  • BLE central mode will take over the role of discovering other devices and initiating connections

Once the connection is established the BLE devices exchange data in a client-servercommunication consisting of two roles:

  • a server hosting the BLE data services, typically a data sensor offering values like heart rate or acceleration
  • a client requesting information from the server, typically a data collector computing information (e.g. displaying it to a user)

Currently, the XDK can only be used as a peripheral device, to be employed as a peripheral device to advertise data for interested central devices. After accepting the connection initiation, the XDK communicates as a slave device with the master device by providing data as a server to the client. So the usual setup of BLE use cases with the XDK looks as shown in the following pictures.

Image

Understanding BLE Data Profiles and Services

BLE Data Hierarchy

BLE data is organised in hierarchical elements which makes it easy to understand what the BLE device is offering as a data provider on different detail levels. It also provides the possibility to reuse single components of the structure in other use-cases. Typical data structure is shown in an example profile in the following picture.

Image

In BLE services that fit together for a specific use case (e.g. Battery Service and Heart Rate Service into Heart Rate Profile) are combined into profiles. Services consist of at least one or more characteristics. Characteristics can be seen as data containers with a value and descriptors describing the access rules and allowed data operations. The following operations to move data between the client and the server are supported in BLE:

  • read requests can be executed by the client and the server responds with the requested data.
  • write commands are issued by the client to write values to the characteristics of the server.
  • notify needs to be actively enabled by the client at the server so the server sends notifications including the values periodically or whenever an update of data is available.
  • indicate works the same way notify does but it also requests acknowledgement by the client whenever the values have been received which makes the notify faster but less reliable.

API Overview

Mita provides the possibility to create a BLE resource. If the configuration and implementation provided by the Mita implementation are insufficient for a certain purpose, it is recommended to make adapting changes in the generated C code.

The image below illustrates the software API layers for BLE on the XDK.

Image

This section will demonstrate the Mita BLE API. In Mita, BLE is defined as a named singleton resource. That means, there can only be one instance of the BLE resource set up, and the name can be specified by the developer. All possible configuration items for the BLE resource are listed below. The use of some of the configuration items will be explained in subsequent chapters.

connectivity named-singleton BLE {
    generator "org.eclipse.mita.platform.xdk110.connectivity.BleGenerator"
    validator "org.eclipse.mita.platform.xdk110.connectivity.BleValidator"

    /**
     * The name of the device as advertised via GAP.
     */
    configuration-item deviceName : string

    /**
     * MAC Address to be configured. Format: "FC:D6:BD:xx:xx:xx" or "FC-D6-BD-xx-xx-xx".
     */
    configuration-item macAddress : string

    /**
     * The last four bytes of the UUID of the GATT service we'll create.
     */
    configuration-item serviceUID : uint32

    /**
     * The advertising interval in milliseconds.
     */
    configuration-item advertisingInterval : int16 = 1000

    /**
     * Creates a boolean GATT characteristic.
     *
     * @param UUID The last four bytes of the characteristic UUID. Defaults to the hash code of the VCI name.
     */
    signal bool_characteristic(UUID : uint32) : bool

    /**
     * Creates an unsigned integer GATT characteristic.
     *
     * @param UUID The last four bytes of the characteristic UUID. Defaults to the hash code of the VCI name.
     */
    signal uint32_characteristic(UUID : uint32) : uint32

    /**
     * Creates a signed integer GATT characteristic.
     *
     * @param UUID The last four bytes of the characteristic UUID. Defaults to the hash code of the VCI name.
     */
    signal int32_characteristic(UUID : uint32) : int32

}

Setting up a BLE resource

A BLE resource is generally setup with the required configuration-item macAddress. This configuration-item is a string, which represents the resulting Mac Address. Every Mac Address must match the pattern FC:D6:BD:xx:xx:xx. Here, x represents a hexadecimal digit, and the first three parts of the Mac Address must always be FC:D6:BD. An example for a valid Mac Address is "FC:D6:BD:00:77:FF".

The following code can be used to create an BLE resource:

setup ble : BLE {
    macAddress = "FC:D6:BD:00:00:00";
    var light = uint32_characteristic(0x0001);
}

Setting up variable topic-signals

In the above example, light is a variable of type uint32_characteristic. This variable is a so-called signal, a BLE instance can have multiple signals, each representing a characteristic. For example, if it is desired to have one characteristic for temperature and one for light, the following code would initialize a BLE resource with characteristics for light and temperature:

setup ble : BLE {
    macAddress = "FC:D6:BD:00:00:00";
    var light = uint32_characteristic(0x0001);
  var temperature = int32_characteristic(0x0002);
}

Every read/write operation on one of the signals will send or read messages on the on the associated characteristics. The UUID of the characteristics ends with 0001 and 0002 (in hexadecimal) respectively. They are part of the same custom service.

Writing on a Characteristic

Assuming that the following BLE resource has been previously set up:

setup ble : BLE {
    macAddress = "FC:D6:BD:00:00:00";
    var light = uint32_characteristic(0x0001);
  var temperature = int32_characteristic(0x0002);
}

Then the following code will write the light and temperature values on the respective characteristics every 1 second.

every 1 second {
  ble.light.write(light.intensity.read());
  ble.temperature.write(environment.temperature.read());
}

Reading a Characteristic

This functionality is not implemented currently.

Settings

Device Name

The BLE resource can be further configured using the configuration-items deviceName of type string.

This defines the advertised name of the XDK in the BLE context. The string may only be 20 explicit characters long (the 21st character is the string terminating null-character by default).

The default value for this configuration-item has the prefix ConnectivityBLE, followed by the name chosen for the resource instance.

Advertising Interval

The BLE resource can be further configured using the configuration-item advertisingInterval of type int16.

This defines the interval between two advertisements in ms. The XDK can only be detected by BLE devices via broadcasts, which occur after the advertising interval. The advertising interval should (optimally) not be higher than the scanning interval of relevant BLE devices.

A higher advertising interval will reduce power consumption for idle XDKs, but lessens the probability of being detected by other devices.

As an example value, if a smartphone runs an app that uses a scanning interval of 1000ms, then the advertising interval is recommended to be at most 990ms (0 - 10ms less than 1000ms, to account for pseudo-random delay between broadcasts).

The advertising interval must be at least 20ms.

Service UID

The BLE resource can be further configured using the configuration-item serviceUid of type uint32.

Full Code Example

package main;
import platforms.xdk110;

setup ble : BLE {
  deviceName = "XDK_BLE";
  macAddress = "FC:D6:BD:00:00:00";
  var temperature = int32_characteristic(UUID=0x9a66);
}

every 1 second {
  ble.temperature.write(environment.temperature.read());
}