1. Introduction

1.1. Before You Start


Before you start you need to:

  • Install the latest SmartSnippets Studio
  • Download the latest SDK for the DA1468x platforms

These can be downloaded from the Dialog Semiconductor support portal.

Additionally, for this tutorial either a Pro or Basic Development kit is required.

The key goals of this tutorial are to provide:

  • A basic understanding of Generic ATT profile
  • A basic understanding of Dialog Bluetooth framework architecture
  • A basic understanding of Bluetooth database creation process
  • A complete sample project demonstrating the creation of a custom Bluetooth service

1.2. Attribute Protocol (ATT)

The attribute protocol provides mechanisms for discovering attributes of a remote device, as well as reading and writing attributes. The attribute protocol follows a client-server model. The server exposes a set of attributes to the client. The client can discover, read, and write those attributes. The server can also send notifications or indications to the client about any of the attributes. A device can implement a client, a server, or both client and server roles. At any given time, only one server can be active on a device.

1.2.1. Client-Server Architecture

Servers have data, this is known as the peripheral in the Generic Access Protocol (GAP).

Clients request data to/from servers, this is known as central in GAP.

Servers expose data using Attributes.

Client Server Architecture

Fig. 1 Client-Server Architecture

1.3. Attribute Definition

An attribute is something that represents data. It could be thought of as any data, at any given time, when the device is in any given state. ATT is designed to push or pull that data to or from a remote device. ATT also supports setting notifications and indications, so that the remote device can be alerted when the data changes. As well as containing the value of the data, an attribute has three properties associated with it:

  1. Attribute Type
  2. Attribute Handle
  3. Access Permissions

1.3.1. Attribute Value

An attribute value is an octet array that contains the actual value of the attribute. The length of the attribute can be either fixed or variable:

  • Fixed length: The length can be one, two or four octet.
  • Variable length: The attribute can be a variable length string.

To simplify things, ATT does not allow multiple attribute values to be transmitted in a single PDU. A PDU contains only one attribute value and if the attribute value is too long to transmit in a single PDU, it can be split across multiple PDUs. There are some exceptions to this, for example, when a client requests multiple attributes to be read and the attributes have a fixed length, then the response can contain multiple attributes.

1.3.2. Attribute Type

The attribute type specifies what that particular attribute represents. This allows the client to understand the meaning of the attribute. The attribute type is identified by a Universally Unique Identifier (UUID). A UUID is a 128-bit value which is considered to be unique over space and time. The implementation could either use the set of predefined UUIDs or define its own UUIDs. In general, a shorter form of UUIDs is used. This shorter form is 16-bit. The 16-bit UUIDs are assigned by the Bluetooth SIG and published on the Bluetooth Assigned Numbers page on the Bluetooth SIG website.

1.3.3. Attribute Handle

All attributes on the server are assigned a unique non-zero attribute handle. This handle is used by the client in all operations with the server to identify the attribute. It is allowed to dynamically add or remove attributes on the server as long as the new attributes are not assigned a handle which has already been used by any other attribute in the past (even if that attribute has been deleted). This ensures that clients always get a unique attribute handle. Once an attribute has been assigned an attribute handle, it should not change over time. This ensures that clients can keep accessing that attribute with the same handle. The attributes on the server are ordered by the attribute handle. The attribute handle of 0x0000 is reserved and the attribute handle of 0xFFFF is known as the maximum attribute handle.

1.3.4. Attribute Permissions

Each attribute has an associated set of permissions which determines the level of access permitted for that particular attribute. The attribute permissions are used by a server to determine whether a client is allowed to read or write an attribute value, and whether Authentication or Authorization is required to access that particular attribute. Attribute permissions are a combination of the following three permissions:

  1. Access Permission: This can be:
    • Readable
    • Writeable
    • Readable and Writeable
  2. Authentication Permission: This is used by the server to determine if an authenticated physical link is required when a client attempts to access that attribute or when the server has to send a notification or indication to client. This can be set to either:
    • Authentication Required
    • No Authentication Required
  3. Authorization Permission: This is used by the server to determine if client needs to be authorized before accessing an attribute value. This could be set to either:
    • Authorization Required
    • No Authorization Required

If client does not have sufficient permissions an error is returned.


1.4. BLE Service Structure

This section describes the internal structure of an ATT Profile. It contains a brief description of the attributes that make up a profile and then it explains the Dialog BLE framework architecture.

1.4.1. Service Declaration

A service is grouped using a Service Declaration. This is an attribute with an attribute type of either Primary Service or Secondary Service. All attributes that follow this Service Declaration and occur before the next Service Declaration are considered grouped with this service; they belong to this service. A Primary Service is one that encapsulates what the device does. A Secondary Service is one that helps the Primary Service to achieve its behavior. All Secondary Services are referenced from a Primary Service. The service declaration’s value is a Service UUID. This is either a 16-bit Bluetooth UUID or a 128-bit custom UUID. Any service that a device does not understand can be safely ignored. To help with this, the Attribute Protocol allows the range of attribute handles of services to be discovered and only known services will be processed further.

'Primary and Secondary Service Declaration'

Fig. 2 Primary and Secondary Service Declaration

1.4.2. Include Declaration

Secondary Services must be discovered separately. To do this, each service can have zero or more Include attributes. Include declarations always immediately follow the Service Declaration and come before any other attributes of the service. The Include definitions also encompass the handle range of the referenced service, along with the Service UUID of the included service. This allows very quick discovery of the referenced services, their grouped attributes and the type of the service. It does not state if this referenced service is a primary or a secondary service because this is not relevant.

'Including Service Declaration'

Fig. 3 Including Service Declaration

Note

Given that four octets are used for handles in the Attribute Value fields, a full 128-bit Service UUID will not fit into the standard response packets used to find the included services. Therefore, when the included service has a 128-bit UUID, the Service UUID is not part of the value declaration. This means that an additional Attribute Protocol read request is required to find the type of the service included.

1.4.3. Characteristics

Grouping attributes together within a service, demonstrates how these attributes can be combined to provide a consistent interface to a block of behavior. The Bluetooth Low Energy architecture also makes it possible to group attributes to allow the state and behavior of a service to be exposed. More specifically, a characteristic exposes the type of data a value represents, whether a value can be read or written, how to configure the value to be indicated, notified, or broadcast, and what a value means. To do this, a characteristic is composed of three basic elements:

  • Declaration
  • Value
  • Descriptor(s)

A Declaration is the start of a characteristic; it groups all the other attributes for this characteristic. The Value attribute contains the actual value for this characteristic. The Descriptors hold additional information or configuration for this characteristic.

1.4.3.1. Characteristic Declaration

To start a characteristic, a Characteristic attribute is used. This contains three fields, as shown in Fig. 4:

  • Properties
  • Value handle
  • Characteristic UUID

More specifically, the characteristic Properties determines if the characteristic Value attribute can be read, written, notified, indicated, broadcast, or authenticated in a signed write. The characteristic Value Handle field is the handle of the attribute that contains the value for the characteristic. The final field is the Characteristic UUID which holds the UUID that is used to identify the type of the characteristic value.

'Characteristic Declaration'

Fig. 4 Characteristic Declaration

Note

The Value Handle field allows a very quick search for the characteristic to be performed by a client. It returns only Characteristic Declarations. With this declaration, the attribute that holds the value is immediately available. If this field did not exist, the client would need to perform an additional search for attributes and effectively guess which attribute after the declaration was the value.

1.4.3.2. Characteristic Value

The Characteristic Value is an attribute with a type that must match the characteristic declarations’ Characteristic UUID field. Apart from that, it is an ordinary attribute. The biggest difference is that the types of actions that can be performed on this characteristic value attribute, are exposed in the characteristic declarations’ Properties field and additionally might be in the Characteristic Extended Properties descriptor.

1.4.3.3. Characteristic Descriptors

There can be any number of descriptors on a characteristic. Most descriptors are optional, although they might be required depending on the Characteristic Declaration. Some descriptors might also be required by a service specification. The following descriptors can be included in a characteristic:

Characteristic Extended Properties

This is used to capture the additional extended properties, for example the ability to perform reliable writes on the value or to write the Characteristic User Description descriptor.

Characteristic User Description

Using this descriptor, a device can associate a text string with a characteristic.

Client Characteristic Configuration

If a characteristic is notifiable or indicatable, this descriptor must exist. It is a two-bit value, with one bit for notifications and the other for indications. Notifications and Indications are complementary procedures, so it’s impossible to set both of these bits at the same time. How the value is notified or indicated is not defined in the core specifications; this is defined by the service specifications.

Server Characteristic Configuration

This is very similar to the Client Characteristic Configuration descriptor, except that is has only one bit which is used for broadcast. Setting this bit causes the device to broadcast data associated with the service in which this characteristic is grouped. The timing of this broadcast is determined by the service.

Characteristic Presentation Format

One of the goals for the Generic Attribute Profile is to enable generic clients. A generic client is defined as a device that can read the values of a characteristic and display them to the user without understanding what they mean. The Characteristic Presentation Format denotes if a characteristic can be used by a generic client.

Characteristic Aggregation Format

Some characteristic values are more complex than just a single value. To allow for such complex characteristic values, the Characteristic Aggregation Format descriptor allows multiple Characteristic Presentation Format descriptors to be referenced, so that individual fields of the value can be illustrated.

1.5. BLE Framework Architecture

The Dialog’s BLE framework consists of the following building blocks:

  • BLE Service Framework - provides implemented ‘out-of-the-box’ BLE services
  • Dialog BLE API - a set of functions to initiate BLE operations or respond to BLE events
  • BLE Manager - provides the interface to the BLE functionality of the chip
  • BLE Adapter - provides the interface to the BLE stack and executes the BLE stack internal scheduler, BLE interrupts etc.
  • BLE Stack - together with the BLE H/W IP, this implements all of the additional BLE stack layers up to GAP and GATT
BLE framework architecture

Fig. 5 BLE Framework Architecture

A typical flow chart of a command execution is as follows:

  1. In principle, an application should only have to interface either with the Dialog BLE API library or/and the BLE Service Framework.
  2. Commands are sent to the BLE Manager over the command queue and Application tasks wait for the response on the response queue.
  3. Once the command is received, the response message is sent on the response queue.
  4. API call completes and application execution continues.
  5. BLE events are received asynchronously from the BLE event queue.

Note

Some API calls don’t send command messages but directly access BLE manager’s device parameters structure (acquire, modify, release).

BLE framework flow chart

Fig. 6 BLE Framework Flow Chart

1.6. Event Handling Levels

Several events can occur during the lifetime of the BLE application and these events need to be handled in a specific manner. In all Dialog’s sample projects (found in the SDK) there are three levels of event handling:

  1. Check whether Bluetooth events can be handled by well-defined Bluetooth Services
  2. If not, then the main application task should handle them.
  3. If the application does not exhibit handlers for handling specific Bluetooth events, then ble_handle_event_default() should be invoked.
'Levels of event handling'

Fig. 7 Levels of Event Handling

1.7. BLE Service Framework

Provides:

  • The API to create new services.
  • A pool of services to be used “out-of-the-box” in an end application.

Header files are in:

  • sdk/ble_services/include

Usage:

  • Call simple initialization functions
  • Define callbacks for the various BLE service events
'Out-of-the-box Services in the Service Framework'

Fig. 8 Out-of-the-Box Services in the Service Framework