pm0269 Bluetooth Low Energy Stack v3x Programming Guidelines Stmicroelectronics
pm0269 Bluetooth Low Energy Stack v3x Programming Guidelines Stmicroelectronics
Programming manual
Introduction
The main purpose of this document is to provide developers with reference programming guidelines on how to develop a
Bluetooth® Low Energy (Bluetooth® LE) application using the Bluetooth® Low Energy stack v3.x family APIs and related event
callbacks.
The document describes the Bluetooth® Low Energy stack v3.x stack library framework, API interfaces, and event callbacks
allowing access to the Bluetooth® Low Energy functions provided by the STMicroelectronics Bluetooth® Low Energy devices
system-on-chip.
The following Bluetooth® Low Energy device supports the Bluetooth® Low Energy (Bluetooth® LE) stack v3.x family:
• BlueNRG-LP device
• BlueNRG-LPS device (Bluetooth® Low Energy stack v3.1 or later)
The document also focuses on the key changes about APIs and the callback interface, Bluetooth® Low Energy stack
initialization versus the Bluetooth® Low Energy stack v2.x family.
This programming manual also provides some fundamental concepts about the Bluetooth® LE technology in order to associate
the Bluetooth® Low Energy stack v3.x APIs, parameters, and related event callbacks to the Bluetooth® Low Energy protocol
stack features. The user is expected to have a basic knowledge of Bluetooth® Low Energy technology and its main features.
For more information about the supported devices and the Bluetooth® Low Energy specifications, refer to Section 6 References
at the end of this document.
The manual is structured as follows:
• Fundamentals of the Bluetooth® Low Energy (Bluetooth® LE) technology
• Bluetooth® Low Energy stack v3.x library APIs and the event callback overview.
• How to design an application using the Bluetooth® Low Energy stack v3.x library APIs and event callbacks.
Note: The document content is valid for all the specified Bluetooth® Low Energy devices. Any specific difference is
highlighted whenever required.
1 General information
This document applies to the BlueNRG-LP, BlueNRG-LPS MCUs, which are Arm®-based devices.
For information on Bluetooth®, refer to the www.bluetooth.com website.
Note: Arm is a registered trademark of Arm Limited (or its subsidiaries) in the US and/or elsewhere.
The Bluetooth® Low Energy wireless technology has been developed by the Bluetooth® special interest group
(SIG) in order to achieve a very low power standard operating with a coin cell battery for several years.
Classic Bluetooth® technology has been developed as a wireless standard allowing cables to be replaced
connecting portable and/or fixed electronic devices, but it cannot achieve an extreme level of battery life because
of its fast hopping, connection-oriented behavior, and relatively complex connection procedures.
The Bluetooth® Low Energy devices consume only a fraction of the power of standard Bluetooth® products and
enable devices with coin cell batteries to be connected via wireless to standardBluetooth® enabled devices.
Figure 1. Bluetooth® Low Energy technology enabled coin cell battery devices
Bluetooth® Low Energy technology is used on a broad range of sensor applications transmitting small amounts of
data:
• Automotive
• Sport and fitness
• Healthcare
• Entertainment
• Home automation
• Security and proximity
• Controller
• Host
The controller includes the physical layer and the link layer.
Host includes the logical link control and adaptation protocol (L2CAP), the security manager (SM), the attribute
protocol (ATT), the generic attribute profile (GATT) and the generic access profile (GAP). The interface between
the two components is called host controller interface (HCI).
In addition, Bluetooth® specifications v4.1, v4.2, v5.x have been released with new supported features.
For more information about these new features, refer to the related specification document.
Bluetooth® Low Energy is an adaptive frequency hopping (AFH) technology that can only use a subset of all
the available frequencies in order to avoid all frequencies used by other nonadaptive technologies. This allows
moving from a bad channel to a known good channel by using a specific frequency hopping algorithm, which
determines the next good channel to be used.
2.2.2 LE 2M PHY
Main characteristics:
• 2 Msym/s modulation
• Uncoded
There are several application use cases demanding a higher throughput:
• Over-the-air firmware upgrade procedure
• Sports, fitness, medical applications use cases require to collect a significant amount of data with a greater
accuracy, and also to send data more frequently through some medical devices.
LE 2M PHY allows the physical layer to work at 2 Mbps and, as a consequence, PHY can achieve higher data
rates than LE 1M. It uses adaptive frequency-hopping Gaussian frequency shift keying (GFSK) radio. LE 2M PHY
uses a frequency deviation of at least 370 kHz.
Figure 4. 2MB
• Preamble: start of the packet. 1 octet for LE 1M PHY, 2 octets for LE 2M PHY.
• Access address: 32 bits. It is different for each connection.
• PDU: it can be an advertising physical channel PDU or a data physical channel PDU.
• CRC: 24 bits of control code calculated over the PDU.
• Constant tone extension: optional. It consists of a constantly modulated series of unwhitened 1s.
The packet format for LE Coded PHY is shown in Figure 5. Coded PHY.
LSB MSB
Header Payload
DT57301V1
• The header is 16 bits and contains information on the PDU type and the length of the payload
• The payload filed is specific to the PDU type.
The PDU type contained in the advertising header can be one of types described in the Table 3. PDU advertising
header.
Data physical channel PDUs has the format shown in Figure 7. Data physical channel PDUs.
Header
Payload MIC (32 bits)
DT57302V1
(16 bits or 24 bits)
• The header contains the PDU type, the length of the payload and other information like sequence numbers.
It is 16-bit long but can be increased to 24 bits if CTE info is included (i.e. if constant tone extension for
direction finding is used)
• The payload can be up to 251 octets
• The MIC is included in encrypted link layer connection if payload length is not zero.
Primary
DT57303V1
Secondary
It is also possible to create a chain of advertising packets on secondary channels in order to transmit more
advertising payload data (greater than 255 bytes). Each advertising packet on a secondary channel includes on
its AuxPtr the number of the next secondary channel for the next advertising packet on the chain. Consequently,
each chain in the advertising packet chain can be sent on a different secondary channel.
DT57304V1
A direct advantage of the new extended advertising packets is the capability to send less data on primary
channels (37,38,39) so reducing the data on primary channels. Furthermore, the advertising payload is sent on
a secondary channel only and no longer on all the three primary advertising channels, reducing the overall duty
cycle.
Some restrictions are applied to allowed channels:
• Legacy advertising PDUs and new ADV_EXT_IND are allowed on the primary adv phy channel only
• New advertising PDUs (except for ADV_EXT_IND) are allowed on the secondary adv phy channel only.
Some restrictions are also applied to allowed PHYs:
• Legacy advertising PDUs can only use LE 1M PHY
• New advertising PDUs can use one of the three PHYs (LE 1M, LE 2M, LE Coded), but LE 2M is not
allowed on a primary adv phy channel. So, ADV_EXT_IND can only be sent on LE 1M and LE Coded.
Any combination of PHYs is possible between primary and secondary channels. However, some combination may
not have a real use case.
Common use cases are: LE 1M -> LE 1M, LE 1M -> LE 2M, LE Coded -> LE Coded
Note: The minimum advertising interval has been reduced from 100 ms to 20 ms for non-connectable advertising.
DT57305V1
header length address discoverable Level = 4 dBm “Temperature” “Temperature
address
flag = 20.5 °C service”
A white-list is a list of stored device addresses used by the device controller to filter devices. The white-list content
cannot be modified while it is being used. If the device is in an advertising state and uses a white-list to filter the
devices (scan requests or connection requests), it has to disable the advertising mode to change its white-list.
The transmit window starts after the end of the connection request packet plus the transmit window offset plus
a mandatory delay of 1.25 ms. When the transmit window starts, the slave device enters the receiver mode and
waits for a packet from the master device. If no packet is received within this time, the slave leaves the receiver
mode, and it tries one connection interval again later. When a connection is established, a master has to transmit
a packet to the slave on every connection event to allow the slave to send packets to the master. Optionally, a
slave device can skip a given number of connection events (slave latency).
A connection event is the time between the start of the last connection event and the beginning of the next
connection event.
A Bluetooth® LE slave device can only be connected to one Bluetooth® LE master device, but a Bluetooth® LE
master device can be connected to several Bluetooth® LE slave devices. On the Bluetooth® SIG, there is no limit
to the number of slaves a master can connect to (this is limited by the specific used Bluetooth® LE technology or
stack).
• No input
• Ability to select yes/no
• Ability to input a number by using the keyboard.
There are two output capabilities:
• No output
• Numeric output: ability to display a six-digit number
The following table shows the possible IO capability combinations:
No output Display
LE legacy pairing
LE legacy pairing algorithm uses and generates two keys:
• Temporary key (TK): a 128-bit temporary key, which is used to generate a short-term key (STK)
• Short-term key (STK): a 128-bit temporary key used to encrypt a connection following pairing
Pairing procedure is a three-phase process.
Phase 1: pairing feature exchange
The two connected devices communicate their input/output capabilities by using the pairing request message.
This message also contains a bit stating if out-of-band data is available and the authentication requirements. The
information exchanged in phase 1 is used to select which pairing method is used for the STK generation in phase
2.
Phase 2: short-term key (STK) generation
The pairing devices first define a temporary key (TK), by using one of the following key generation methods:
1. The out-of-band (OOB) method, which uses out-of-band communication (for example, NFC) for TK
agreement. It provides the authentication (MITM protection). This method is selected only if the out-of-band
bit is set on both devices, otherwise the IO capabilities of the devices must be used to determine which other
method could be used (Passkey Entry or Just Works)
2. Passkey Entry method: user passes six numeric digits as the TK between the devices. It provides the
authentication (MITM protection)
3. Just Works: this method does not provide the authentication and protection against man-in-the-middle
(MITM) attacks
The selection between the Passkey and Just Works method is done based on the IO capability as defined in the
following table.
Display only Display yes/no Keyboard only No input, no output Keyboard display
Display only Just Works Just Works Passkey Entry Just Works Passkey Entry
Display Yes/No Just Works Just Works Passkey Entry Just Works Passkey Entry
Keyboard only Passkey Entry Passkey Entry Passkey Entry Just Works Passkey Entry
No input No output Just Works Just Works Just Works Just Works Just Works
Keyboard display Passkey Entry Passkey Entry Passkey Entry Just Works Passkey Entry
Phase 3: transport specific key distribution methods used to calculate the temporary key (TK)
Once phase 2 is completed, up to three 128-bit keys can be distributed by messages encrypted by the STK key:
1. Long-term key (LTK): it is used to generate the 128-bit key used for link layer encryption and authentication
2. Connection signature resolving key (CSRK): a 128-bit key used for the data signing and verification
performed at the ATT layer
3. Identity resolving key (IRK): a 128-bit key used to generate and resolve random addresses
LE secure connections
LE secure connection pairing methods use and generate one key:
• Long-term key (LTK): a 128-bit key used to encrypt the connection following pairing and subsequent
connections
Pairing procedure is a three-phase process:
Phase 1: pairing feature exchange
The two connected devices communicate their input/output capabilities by using the pairing request message.
This message also contains a bit stating if out-of-band data is available and the authentication requirements. The
information exchanged in phase 1 is used to select which pairing method is used in phase 2.
Phase 2: long-term key (LTK) generation
Pairing procedure is started by the initiating device, which sends its public key to the receiving device. The
receiving device replies with its public key. The public key exchange phase is done for all the pairing methods
(except the OOB one). Each device generates its own elliptic curve Diffie-Hellman (ECDH) public-private key pair.
Each key pair contains a private (secret) key, and a public key. The key pair should be generated only once on
each device and may be computed before a pairing is performed.
The following pairing key generation methods are supported:
1. The out-of-band (OOB) method uses OOB communication to set up the public key. This method is selected
if the out-of-band bit, in the pairing request/response, is set at least by one device, otherwise the IO
capabilities of the devices must be used to determine which other method could be used (Passkey Entry,
Just Works or numeric comparison)
2. Just Works: this method is not authenticated, and it does not provide any protection against man-in-the-
middle (MITM) attacks
3. Passkey Entry method: this method is authenticated. User passes six numeric digits. This six-digit value is
the base of the device authentication
4. Numeric comparison: this method is authenticated. Both devices have IO capabilities set to either display
Yes/No or keyboard display. The two devices compute six-digit confirmation values that are displayed to
the user on both devices: user is requested to confirm if there is a match by entering yes or not. If yes is
selected on both devices, pairing is performed with success. This method allows confirmation to the user
that their device is connected with the right one, in a context where there are several devices, which could
not have different names
The selection among the possible methods is based on the following table.
Initiator/ No input no
Display only Display yes/no Keyboard only Keyboard display
responder output
Display only Just Works Just Works Passkey Entry Just Works Passkey Entry
Just Works
Passkey Entry (LE legacy)
(LE legacy)
Display yes/no Just Works Passkey Entry Just Works Numeric comparison (LE secure
Numeric comparison (LE secure connections)
connections)
Keyboard only Passkey Entry Passkey Entry Passkey Entry Just Works Passkey Entry
No input no output Just Works Just Works Just Works Just Works Just Works
Passkey Entry
Passkey Entry (LE legacy)
(LE legacy)
Keyboard display Passkey Entry Passkey Entry Just Works Numeric comparison (LE secure
Numeric comparison (LE secure connections)
connections)
Note: If the possible key generation method does not provide a key that matches the security properties (authenticated
- MITM protection or unauthenticated - no MITM protection), then the device sends the pairing failed command
with the error code “Authentication Requirements”.
2.8 Privacy
A device, which always advertises with the same address (public or static random), can be tracked by scanners.
However, this can be avoided by enabling the privacy feature on the advertising device. On a privacy-enabled
device, private addresses are used. There are two kinds of private addresses:
• Non-resolvable private address
• Resolvable private address
Non-resolvable private addresses are completely random (except for the two most significant bits) and cannot
be resolved. Hence, a device using a non-resolvable private address cannot be recognized by those devices,
which have not been previously paired. The resolvable private address has a 24-bit random part and a hash part.
The hash is derived from the random number and from an IRK (identity-resolving key). Hence, only a device that
knows this IRK can resolve the address and identify the device. The IRK is distributed during the pairing process.
Both types of addresses are frequently changed, enhancing the device identity confidentiality. The privacy feature
is not used during the GAP discovery modes and procedures but during GAP connection modes and procedures
only.
On Bluetooth® Low Energy stacks up to v4.1, the private addresses are resolved and generated by the host. In
Bluetooth® Low Energy v4.2, the privacy feature has been updated from version 1.1 to version 1.2. On Bluetooth®
Low Energy stack v4.2, private addresses can be resolved and generated by the controller, using the device
identity information provided by the host.
Peripheral
A privacy-enabled peripheral in a non-connectable mode uses non-resolvable or resolvable private addresses.
To connect to a central, the undirected connectable mode should only be used if host privacy is used. If controller
privacy is used, the device can also use the directed connectable mode. When in connectable mode, the device
uses a resolvable private address.
Whether non-resolvable or resolvable private addresses are used, they are automatically regenerated after each
interval of 15 minutes. The device does not send the device name to the advertising data.
Central
A privacy-enabled central, performing active scanning, uses non-resolvable or resolvable private addresses
only. To connect to a peripheral, the general connection establishment procedure should be used if host
privacy is enabled. With controller-based privacy, any connection procedure can be used. The central uses a
resolvable private address as the initiator’s device address. A new resolvable or non-resolvable private address is
regenerated after each interval of 15 minutes.
Broadcaster
A privacy-enabled broadcaster uses non-resolvable or resolvable private addresses. New addresses are
automatically generated after each interval of 15 minutes. A broadcaster should not send the name or unique
data to the advertising data.
Observer
A privacy-enabled observer uses non-resolvable or resolvable private addresses. New addresses are
automatically generated after each interval of 15 minutes.
Characteristic definition
Characteristic declaration
Descriptor declaration
…..
DT57306V1
Descriptor declaration
Characteristic value
properties (read, broadcast,
write, write without response,
notify, indicate, …). Determine
0x2803 how characteristic value can Read only,
be used or how characteristic
0xNNNN (UUID for characteristic descriptor can be accessed no authentication, no
attribute type) authorization
Characteristic value attribute
handle
Characteristic value UUID (16
or 128 bits)
A characteristic declaration contains the value of the characteristic. This value is the first attribute after the
characteristic declaration:
0xuuuu–16 bits or 128 bits for characteristic Higher layer profile or implementation
0xNNNN Characteristic value
UUID specific
Attribute
Attribute type Attribute value Attribute permissions
handle
Read only,
0x2800–UUID for “Primary Service” or 0xuuuu–16 bits or 128 bits for
0xNNNN no authentication,
0x2801–UUID for “Secondary Service” service UUID
no authorization
A service contains a service declaration and may contain definitions and characteristic definitions. A "service
include declaration" follows the service declaration and any other attributes of the service.
Attribute
Attribute type Attribute value Attribute permissions
handle
Read only,
0x2802 (UUID for Include service End group
0xNNNN Service UUID no authentication, no
include attribute type) attribute handle handle
authorization
“Include service attribute handle” is the attribute handle of the included secondary service and “end group handle”
is the handle of the last attribute within the included secondary service.
For a detailed description of the GATT procedures and related response events, refer to the Bluetooth®
specifications in Section 6 References.
For connected and not bonded devices, the only safe mechanism to be aligned to the possible change of the
GATT server attribute table is to perform a time and power consuming service discovery procedure at each
connection.
Bluetooth® specifications v5.1 defines two new characteristics:
1. Database hash
2. Client-supported features
These characteristics allow a client to understand if something has been changed on the server GATT attributes
table, even if there is no bonding between the two devices.
The GATT client updates a flag on the client-supported features characteristic on the server to inform the server
that it supports the database hash characteristic.
The database hash characteristic stores a 128-bit value, which is an AES-CMAC hash calculated from the server
attribute table. Any change in the server GATT attribute database structure results in a different hash value. The
server has the responsibility to keep the database hash value always up to date.
The database hash characteristic allows the client to ask the server if something has been changed on its
attributes database: each time a GATT client connects to a server, it performs immediately a read of this
characteristic in order to establish if a change or not has been performed on the server attribute table.
The GATT client may cache the read database hash value to verify if a change on the database structure
occurred since the last connection. This allows the client to perform the service and characteristic discovery
procedures only if a change has occurred since the last discovery, enhancing the user experience in terms of
timing and saving power.
In addition to these two characteristics, the concept of robust caching has been defined in order to synchronize
client and server views of the attributes table. Basically, when client tries to read the GATT server attributes table
before receiving the service change indication, the client may get inconsistent data if the GATT server attributes
table content has changed. In this case, the server can send a new ATT error code (database out-of-sync) to
inform the client of this inconsistency.
When robust caching is enabled, a client can be in two states, from the server point of view:
1. Change-aware state
2. Change-unaware state
After connection, the state of a client without a trusted relationship is change-aware. Instead, if the client is
bonded, the state is the same as on the previous connection, unless the database has changed. In this case, the
client is considered change-unaware.
Server ignores all the ATT commands from a client that are change-unaware and if it receives an ATT request it
sends an ATT error response with an error code set to the database out of sync.
Some events can change the state of the client to change-aware:
1. Server receives an ATT confirmation for a service changed indication it has previously sent
2. Server sends the database out of sync ATT error response to an ATT request from client and then receives
another ATT request from the client.
1. 1. M = mandatory; O = optional
Device only broadcasts data using the link layer Broadcast data can be
Broadcast mode advertising channels and packets (it does not set detected by a device using the Broadcaster
any bit on flags AD type) observation procedure
The following GAP procedures are defined in Section 2.3.1 Bluetooth® Low Energy packet:
For a detailed description of the GAP procedures, refer to the Bluetooth® specifications.
Data to
position
AoA Method engine server
Receiver
AoA
DT57307V1
Transmitter
On a receiver (locator) device, an antenna array is needed, and the angle calculation of several tags requires a
consistent processing power. The transmitter (tag) device requires a single antenna, and it must only support the
capability to send the information required to perform IQ data sampling.
AoD Method
Transmitter
AoD
Receiver
Data to
position
engine server
or calculated
DT57308V1
locally
The transmitter device needs to send a multi-antenna location signal using an antenna array. It must support the
capability to send the information required to perform an IQ data sampling.
The receiver device needs a single antenna and the angle calculation of the received signal may require an FPU
(float processing unit) and some memory resources.
Another limitation is linked to the ATT MTU size (which can negotiated through the ATT_Exchange_MTU request)
and response PDUs, as soon as 2 devices connect with no capability to change the established value. This
prevents that a second application from requesting an increased ATT MTU size on the same connection.
Enhanced Attribute protocol (EATT) is an improvement of the Attribute protocol (ATT) which provides the following
main new features:
• Concurrent transactions of L2CAP packets related to ATT packets coming from different applications are
possible over distinct enhanced ATT bearers, which are based on a new L2CAP mode called L2CAP
Enhanced Credit Based Flow Control Mode providing flow control and reliable communication.
• Capability to change the ATT Maximum Transmission Unit (MTU) during a connection (the MTU values at
ATT and L2CAP layer can be independently configured by reducing latency problems on scenarios where
some applications share the Bluetooth® Low Energy stack with other applications).
The new features in the EATT + L2CAP Enhanced Credit Based Flow Control Mode determine a consistent
improvement in terms of latency, when different applications use the Bluetooth® Low Energy stack at the same
time. Since L2CAP packets can be interleaved with each other, this reduces the case where application usage
of the stack would prevent usage of other application. This implies a benefit on latency and therefore on user
experience.
Some mechanisms are available to know if a connected device supports the new EATT feature:
• A new characteristic Server Supported Feature is defined. It must be included if the device supports the
EATT feature. A client device can just read this characteristic value to discover if the EATT is supported (bit
0 of the first octet of the characteristic value equal to 1 means that EATT is supported).
• The Client Supported Features characteristic bit 1 indicates whether or not the Enhanced ATT Bearer is
supported by the client. Bit 2 indicates whether or not a new ATT packet called Multiple Handle Value
Notifications is supported.
A CIS stream defines a point-to point isochronous communication between two connected devices.
A flushing period is defined for the CIS logical transport. Any packet that has not been transmitted within the
flushing period is discarded.
CIS streams are members of groups named Connected Isochronous Groups (CIG), each of which may contain
multiple CIS instances.
Connectionless isochronous channels use Broadcast Isochronous Streams (BIS) and only support uni-directional
communication. A BIS can stream identical copies of data to multiple receiver devices. BIS streams are members
of groups named Broadcast Isochronous Groups (BIG), each of which may contain multiple BIS instances.
The capability of the Bluetooth® Low Energy isochronous channels has a wide range of application use cases, in
particular on audio sharing domains:
• Personal audio sharing groups of friends: sharing simultaneously music on one smartphone through
Bluetooth®headphones.
• Public assisted hearing: broadcasting a dialogue to a specific audience.
• Public television: listening to the television through Bluetooth® Low Energy headphones.
• Multilanguage flight announcements: getting specific information through the preferred language via
Bluetooth® Low Energy headphones.
• https://developer.bluetooth.org/gatt/characteristics/Pages/CharacteristicsHome.aspx
Server
Client Service A
Char.
Use case 1
Char.
DT57309V1
2.17.1 Proximity profile example
This section describes the proximity profile target, how it works and required services:
Target
• When a device is close, very far away:
– Causes an alert
How it works
• If a device disconnects, it causes an alert
• Alert on link loss: «Link Loss» service
– If a device is too far away
– Causes an alert on path loss: «Immediate Alert» and «Tx Power» service
• «Link Loss» service
– «Alert Level» characteristic
– Behavior: on link loss, causes alert as counted
• «Immediate Alert» service
– «Alert Level» characteristic
– Behavior: when written, causes alert as counted
• «Tx Power» service
– «Tx Power» characteristic
– Behavior: when read, reports current Tx power for connection.
Bluetooth® Low Energy stack v3.x provides a new architecture, which offers further advantages rather than the
previous Bluetooth® Low Energy stack v2.x family.
Binary library
(singe file for
Bluetooth® Low Energy stack v3.x EWARM, KEIL
WiSE-Studio IDE
projects)
Bluetooth®
Timer NVM LE
AES
RNG
Bluetooth® LE
controller PKA support layer
Peripheral drivers
DT57310V1
BlueNRG-LP/LPS
The new architecture provides the following new features with related benefits:
1. Code is more modular and testable in isolation:
– test coverage is increased
2. Hardware-dependent parts are provided in source form:
– New sleep timer module external to Bluetooth® Low Energy stack (Init API and tick API to be called on
user main application)
– New NVM module external to Bluetooth® Low Energy stack (Init API and tick API to be called on user
main application).
Note: It makes easy customize or fix bugs
3. Certification targets the protocol part only:
– It reduces the number of stack versions, since hardware-related problems are mostly isolated in other
modules
– It reduces the number of certifications
4. It implements more flexible and robust radio activity scheduler
– It allows the robustness against late interrupt routines (for example, flash writes and/or interrupt
disabled by the user)
5. It reduces real-time constraint (less code in interrupt handler)
– System gives more time to applications
Bluetooth® Low Energy stack v3.x is a standard C library, in binary format, which provides a high-level interface
to control STMicroelectronics devices Bluetooth® Low Energy functionalities. The Bluetooth® Low Energy binary
library provides the following functionalities:
• Stack APIs for
– Bluetooth® Low Energy stack initialization
– Bluetooth® Low Energy stack application command interface (HCI command prefixed with hci_, and
vendor-specific command prefixed with aci_ )
– Sleep timer access
– Bluetooth® Low Energy stack state machine handling
Note: 1. API is a C function defined by the Bluetooth® Low Energy stack library and called by the user application.
2. A callback is a C function called by the Bluetooth® Low Energy stack library and defined by the user
application.
3. Driver sources are a set of drivers (header and source files), which handles all the Bluetooth® Low Energy
device peripherals (ADC, I2C, SPI, timers, watchdog, GPIOs, RTC, UART, ...).
4. Bluetooth® Low Energy radio initialization structure and related application configuration files have been
modified if compared to the Bluetooth® Low Energy stack v2.x family
5. Bluetooth® Low Energy stack APIx naming for Bluetooth® Low Energy stack init, Bluetooth® Low Energy
stack tick has been modified if compared to Bluetooth® Low Energy stack v2.x family
6. New GAP APIs interface for GAP initialization, scanning, connection, and advertising APIs/events have
been added if compared to Bluetooth® Low Energy stack v2.x family
7. New GATT APIs/event framework and interface have been defined if compared to Bluetooth® Low Energy
stack v2.x family
Table 26. Bluetooth® Low Energy stack library framework interface (BlueNRG-LP, BlueNRG-LPS STSW-
BNRGLP-DK)
Bluetooth®
Header file for Low
ble_status.h Middlewares\ST\Bluetooth_LE\inc -
Energy stack error codes
Note: Bluetooth® Low Energy stack v3.x provides the capability to enable/disable, at compile time, the following
Bluetooth® Low Energy stack features based on a user-specific application scenario:
1. Enable/disable controller privacy
2. Enable/disable LE secure connections
3. Enable/disable master capability
4. Enable/disable data length extension (valid only for the device supporting the data length extension feature)
5. Enable/disable LE 2M and LE Coded PHYs features
6. Enable/disable extended advertising and scanning features
7. Enable/disable L2CAP, connection-oriented data service feature (L2CAP-COS)
8. Enable/disable constant tone extension (where applicable; from Bluetooth® Low Energy v3.1 or later)
9. Enable/disable LE Power Control and Path Loss Monitoring (from Bluetooth® Low Energy v3.1 or later)
10. Enable/disable the connection capability (from Bluetooth® Low Energy stack v3.1a or later). It configures
support to connections:
– If connection option is disabled, connections are not supported; the device is a broadcaster only if
master capability option is disabled, or a broadcaster and observer only if master capability option is
enabled.
– If connection option is enabled, connections are supported; device can only act as broadcaster or
peripheral if the master capability option is disabled, or any role (broadcaster, observer, peripheral, and
central) if master capability option is enabled.
11. Enable/disable the enhanced ATT (from Bluetooth® Low Energy v3.2 or later)
12. Enable/disable the connection subrating (from Bluetooth® Low Energy v3.2 or later)
13. Enable/disable the channel classification (from Bluetooth® Low Energy v3.2 or later)
14. Enable/disable the broadcast isochronous streams (from Bluetooth® Low Energy v3.2 or later)
15. Enable/disable the connected isochronous streams (from Bluetooth® Low Energy v3.2 or later)
From Bluetooth® Low Energy stack v3.1a or later, the master capability option is linked to the new connection
option as follows:
1. Observer disabled (master capability option disabled) or enabled (master capability option enabled) if
connection option is disabled
2. Observer and Central disabled (master capability option disabled) or enabled (master capability option
enabled) if connection option is enabled.
The modular configuration options allow the user to exclude some features from the available Bluetooth® Low
Energy stack binary library and decrease the overall flash memory.
The following table provides the list of modular options to be added or not in order to address some typical
Bluetooth® Low Energy configurations:
1. Broadcaster only: send advertising PDU and scan response PDU; receive and process scan request PDU.
2. Broadcaster + observer only: send advertising PDU, scan request PDU and scan response PDU; receive
and process advertising PDU, scan request PDU and scan response PDU.
3. Basic: all modular options OFF expects the capability to connect as a peripheral device (connection
capability enabled).
4. Basic + DLE: all modular options OFF expect with the connection and the data length extension capabilities.
5. Full: all the modular options ON.
1. Broadcaster only or broadcaster + observer-only roles could be also extended with other modular options and related
features except for the following ones:
• Secure Connections
• L2CAP COS
• Power Control
2. Observer-only role is not supported.
3. It is supported on Bluetooth® LE stack v3.1a or later. This implies that broadcaster only (connection capability = OFF) or
broadcaster + observer only (connection capability = OFF and master capability = ON) and possible extensions could be
supported only from Bluetooth® LE stack v3.1a or later.
4. ACI_GAP_INIT(), Role parameter should be set according to the connection support and master role modular options (using
the available parameter values or combination of such values: broadcaster, peripheral, observer, central).
Peripheral device with legacy security (aka: basic configuration already available through the
BLE_STACK_BASIC_CONF preprocessor option)
Note: When CONNECTION_ENABLED = 0 (connection capability is not supported), a user shall perform the following
modifications on his user application:
• On the user IDE project, the
BLE_STACK_CUSTOM_CONF
is used.
• On the user IDE project, the gap_profile.c, gatt_profile.c files are excluded from the application building.
• The aci_gatt_srv_init() is not anymore called (since no characteristics are added).
• The aci_gap_init(), role parameter is defined as GAP_BROADCASTER_ROLE (only broadcaster)
or GAP_BROADCASTER_ROLE|GAP_OBSERVER_ROLE (only broadcaster, observer) depending on
CONTROLLER_MASTER_ENABLED value (0/1).
• The Gap_profile_set_dev_name() is not anymore called.
• The aci_gap_set_advertising_configuration(), Discoverable_Mode parameter is defined as
GAP_MODE_BROADCAST.
• The Advertising_Data parameter on aci_gap_set_advertising_data() does not set the general
discoverable mode flag, since it is not supported on broadcaster mode.
Table 28. Bluetooth® Low Energy application stack library framework interface (BlueNRG-LP, BlueNRG-
LPS STSW-BNRGLP-DK)
To be included
It includes the requiredBluetooth® Low
ble_const.h Middlewares\ST\BLE_Application\layers_inc on the user-
Energy stack header files
main application
Header and source files for generic access
gap_profile.[ch] Middlewares\BLE_Application\Profiles -
profile service (GAP) library
Header and source files for generic
gatt_profile.[ch] Middlewares\BLE_Application\Profiles -
attribute profile service (GATT) library
Header and source files for ATT prepare
att_pwrq.[ch] Middlewares\BLE_Application\Queued_Write -
write queue implementation library
Header and source files for EATT Prepare
eatt_pwrq.[ch] Middlewares\BLE_Application\Queued_Write -
Write Queue implementation
Note: The AES CMAC encryption functionality required by Bluetooth® Low Energy stack is available on a new
standalone binary library: cryptolib\\cryptolib.a. This library must also be included on the user application IDE
project.
BLE_STACK_InitParams is a variable, which contains memory and low-level hardware configuration data for
the device, and it is defined using this structure:
typedef struct {
uint8_t* BLEStartRamAddress ;
uint32_t TotalBufferSize ;
uint16_t NumAttrRecord ;
uint8_t MaxNumOfClientProcs;
uint8_t NumOfLinks;
uint8_t NumOfEATTChannels;
uint16_t NumBlockCount ;
uint16_t ATT_MTU;
uint32_t MaxConnEventLength;
uint16_t SleepClockAccuracy;
uint8_t NumOfAdvDataSet;
uint8_t NumOfAuxScanSlots;
uint8_t NumOfSyncSlots;
uint8_t WhiteListSizeLog2;
uint16_t L2CAP_MPS;
uint8_t L2CAP_NumChannels;
uint8_t CTE_MaxNumAntennaIDs;
uint8_t CTE_MaxNumIQSamples;
uint16_t isr0_fifo_size;
uint16_t isr1_fifo_size;
uint16_t user_fifo_size;
}
Maximum supported
ATT_MTU Supported values range is from 23 to 1020 bytes
ATT_MTU size
Maximum duration of the connection
MaxConnEventLength event when the device is in slave mode <= 4000 (ms)
in units of 625/256 us (~2.44 us)
SleepClockAccuracy Sleep clock accuracy ppm value
Maximum number of advertising data
NumOfAdvDataSet set, valid only when advertising Refer to Table 1
extension feature is enabled
Maximum number of slots for scanning
on the secondary advertising channel,
NumOfAuxScanSlots Refer to Table 1
valid only when advertising extension
feature is enabled
Maximum number of slots to be
synchronized, valid only when Periodic 0 if Periodic Advertising is disabled.
NumOfSyncSlots
Advertising and Synchronizing Feature [1 - NumOfLinks-1] if Periodic Advertising is enabled
is enabled.
Two's logarithm of the white/resolving
WhiteListSizeLog2 -
list size
The maximum size of payload data in
L2CAP_MPS octets that the L2CAP layer entity can Supported values range is from 0 to 1024 bytes
accept
Maximum number of channels in LE
L2CAP_NumChannels Supported values range is from 0 to 255 bytes
credit based flow control mode
Maximum number of antenna IDs in the
[0x02-0x4B] if the direction finding feature is enabled
CTE_MaxNumAntennaIDs antenna pattern used in CTE connection
and supported from the device.
oriented mode.
Note: A specific tool named "Radio Init Wizard" is provided on the BlueNRG-LP, BlueNRG-LPS device software
development kit (STSW_BNRGLP_DK). The Radio Init Wizard allows the described parameter values to be
configured according to the application needs, and to get an overview about the associated required RAM
for the Bluetooth® Low Energy stack. User can also evaluate the impact of each parameter on an overall
RAM memory footprint. This tunes the value of each radio initialization parameter (that is, NumOfLinks,
ATT_MTU, ...), according to the available device RAM memory.
If a low speed ring oscillator is used instead of the LS crystal oscillator, this function also performs the LS RO
calibration, and hence must be called at least once at every system wake-up in order to keep the 500 ppm
accuracy (at least 500 ppm accuracy is mandatory if acting as a master).
Note: No Bluetooth® Low Energy stack function must be called while the BLE_STACK_Tick() is being run. For
example, if a Bluetooth® Low Energy stack function may be called inside an interrupt routine, that interrupt must
be disabled during the execution of BLE_STACK_Tick().
Example: if a stack function may be called inside UART ISR, the following code should be used:
NVIC_DisableIRQ(UART_IRQn);
BLE_STACK_Tick();
NVIC_EnableIRQ(UART_IRQn);
This section provides some information and code examples about how to design and implement a Bluetooth® Low
Energy application using the Bluetooth® Low Energy stack v3.x binary library.
A user implementing a Bluetooth® Low Energy stack v3.x application has to go through some basic and common
steps:
1. Initialization phase and main application loop.
2. Bluetooth® Low Energy stack events callbacks setup.
3. Services and characteristic configuration (on GATT server).
4. Create a connection: discoverable, connectable modes and procedures.
5. Security (pairing and bonding).
6. Service and characteristic discovery.
7. Characteristic notification/indications, write, read.
8. Basic/typical error conditions description.
Note: In the following sections, some user application “defines” 's used to identify the Bluetooth® Low Energy device
role (central, peripheral, client, and server). Furthermore, the BlueNRG-LP device is used as reference device
running Bluetooth® Low Energy stack v3.x applications. Any specific device-dependent part is highlighted
whenever it is needed.
Table 31. User application defines for Bluetooth® Low Energy device roles
Define Description
The following pseudocode example illustrates the required initialization steps on STSW-BNRGLPDK SW package
supporting BlueNRG-LP, BlueNRG-LPS devices:
int main(void)
{
WakeupSourceConfig_TypeDef wakeupIO;
PowerSaveLevels stopLevel;
BLE_STACK_InitTypeDef BLE_STACK_InitParams = BLE_STACK_INIT_PARAMETERS;
/* Enable clock for PKA and RNG IPs used by Bluetooth® LE radio */
LL_AHB_EnableClock(LL_AHB_PERIPH_PKA|LL_AHB_PERIPH_RNG);
BLECNTR_InitGlobal();
AESMGR_Init();
ret = BLE_STACK_Init(&BLE_STACK_InitParams);
if (ret != BLE_STATUS_SUCCESS) {
printf("Error in BLE_STACK_Init() 0x%02x\r\n", ret);
while(1);
}
/* Device Initialization: GATT and GAP Init APIs.
It could add services and characteristics (if it is a GATT server)
It could also initialize its state machine and other specific drivers (
i.e. leds, buttons, sensors, …) */
ret = DeviceInit();
if (ret != BLE_STATUS_SUCCESS) {
while(1);
}
/* Set wakeup sources if needed through the wakeupIO. Variable */
/* No wakeup sources: */
wakeupIO.IO_Mask_High_polarity = 0;
wakeupIO.IO_Mask_Low_polarity = 0;
wakeupIO.RTC_enable = 0;
wakeupIO.LPU_enable = 0;
while(1)
{
/* Timer tick */
HAL_VTIMER_Tick();
/* Bluetooth® LE stack tick */
BLE_STACK_Tick();
/* NVM manager tick */
NVMDB_Tick();
/* Application Tick: user application where application
state machine is handled*/
APP_Tick();
/* Power Save management*/
/* It enables power save modes with wakeup on radio operating timings
(adverting, connections intervals) */
HAL_PWR_MNGR_Request(POWER_SAVE_LEVEL_STOP_NOTIMER,wakeupIO, &stopLevel);
}/* while (1) */
} /* end main() */
Char value
Default Attribute Char value
Characteristic Char property Char UUID length
services handle handle
(bytes)
Attribute profile
- 0x0001 - - - -
service
- Service changed 0x0002 Indicate 0x0003 0x2A05 4
Client Supported
- 0x0005 Read, Write 0x0006 0x2B29 1
Features
- Database Hash GATT 0x0007 Read 0x0008 0x2B2A 16
Generic access
profile (GAP) - 0x0009 - - - -
service
Read|write without
response| write|
- Device name 0x000A 0x000B 0x2A00 8
authenticated signed
writes
Read|write without
response| write|
- Appearance 0x000C 0x000D 0x2A01 2
authenticated signed
writes
Peripheral preferred
- 0x000E Read| write 0x000F 0x2A04 8
connection parameters
Char value
Default Attribute Char value
Characteristic Char property Char UUID length
services handle handle
(bytes)
Readable without
Central address authentication or
- 0x0010 authorization. 0x00011 0x2AA6 1
resolution(1)
Not writable
0x01: Peripheral
0x02: Broadcaster The role parameter can be a bitwise OR of any of the
Role
0x04: Central supported values (multiple roles simultaneously support)
0x08: Observer
0x00 for disabling privacy;
Privacy_Type 0x01 for enabling privacy; Specify whether privacy is enabled or not and which one
0x02 for enabling controller-based privacy
It allows the length of the device name characteristic to
device_name_char_len -
be indicated
0x00: public address
Identity_Address_Type Specify which address has to be used as identity address
0x01: static random address
For a complete description of this API and related parameters, refer to the Bluetooth® Low Energy stack APIs and
event documentation, in Section 6 References.
MAC address needs to be stored in the specific flash location associated to the MAC address during the product
manufacturing.
A user can write its application assuming that the MAC address is placed at a known specific MAC flash location
of the device. During manufacturing, the microcontroller can be programmed with the customer flash image via
SWD.
A second step could involve generating the unique MAC address (that is, reading it from a database) and storing
of the MAC address in the known MAC flash location.
uC memory map
MAC address
This value changes
for each device
Application
code The application
code is the same for all
devices
DT57312V1
The BlueNRG-LP/BlueNRG-LPS devices do not have a valid preassigned MAC address, but a unique serial
number (read only for the user). The unique serial number is an 8-bytes value stored at address 0x10001EF0: it is
stored as two words at address 0x10001EF0 and 0x10001EF4.
The following utility APIs get access to the BlueNRG-LP, BlueNRG-LPS unique serial ID:
uint32_t UID_word0;
uint32_t UID_word1;
The static random address is generated and programmed at every first boot of the device on the dedicated flash
area. The value on flash is the actual value that the device uses: each time the user resets the device the stack
checks if valid data is on the dedicated flash area and it uses it (a special valid marker on flash is used to identify
if valid data is present). If the user performs mass erase, the stored values (including marker) are removed so the
stack generates a new random address and stores it on the dedicated flash.
Private addresses are used when privacy is enabled and according to the Bluetooth® Low Energy specification.
For more information about private addresses, refer to Section 2.7 Security manager (SM).
Follow a pseudocode example for setting the radio transmit power at 0 dBm output power:
ret= aci_hal_set_tx_power_level (0, 25);
The En_High_Power parameter allows the selection of one of two possible power configurations. In each
configuration, a different SMPS output voltage level is set. The PA_Level parameter is used to select the output
level of the power amplifier with a granularity of around 1 dB. This output level depends on the SMPS output
voltage.
The Table 35 and Table 36 provide the expected TX output power for each level in the two configurations on the
device.
Table 35. TX power level with En_High_Power = 0 (SMPS voltage @ 1.4 Volts)
0 OFF (1)
1 -21
2 -20
3 -19
4 -17
5 -16
6 -15
7 -14
8 -13
9 -12
10 -11
11 -10
12 -9
13 -8
14 -7
15 -6
16 -6
17 -4
18 -3
19 -3
20 -2
21 -2
22 -1
23 -1
24 0
25 0
26 1
27 2
28 3
29 4
30 5
31 6
1. When PA level is set to 0, PA is turned off. However, a very low output power may still be measured on the RF pin.
Table 36. TX power level with En_High_Power = 1 (SMPS voltage @ 1.9 Volts)
0 OFF (1)
1 -19
2 -18
3 -17
4 -16
5 -15
6 -14
7 -13
8 -12
9 -11
10 -10
11 -9
12 -8
13 -7
14 -6
15 -5
16 -4
17 -3
18 -3
19 -2
20 -1
21 0
22 1
23 2
24 3
25 8
26 8
27 8
28 8
29 8
30 8
31 8
1. When PA level is set to 0, PA is turned off. However, a very low output power may still be measured on the RF pin.
Note: When using an SMPS OFF configuration, the output power levels depend on the voltage applied to the VFBSD
pin. In this case, the user must fill the look-up table in miscutil.c file (under Middlewares\ST\hal\Src directory)
with the real-measured values. Filling the look-up table with the correct values is important because it is used by
the Bluetooth® stack to correctly convert dBm to PA level and vice versa.
4.2.2.1 Service
A service is a collection of data and associated behaviors to accomplish a function or feature. A service definition
may contain included services and characteristics.
There are two types of services:
• Primary service is a service that exposes the primary usable functionality of this device
• Secondary service is a service that is only intended to be included from a primary service or another
secondary service
A service is defined using the following ble_gatt_srv_def_t C language structure:
typedef struct ble_gatt_srv_def_s {
ble_uuid_t uuid;
uint8_t type;
uint16_t group_size;
struct {
uint8_t incl_srv_count;
struct ble_gatt_srv_def_s **included_srv_pp;
} included_srv;
struct {
uint8_t chr_count;
ble_gatt_chr_def_t *chrs_p;
} chrs;
} ble_gatt_srv_def_t
Note: Static variables and global variables (and their fields in case of structures) are initialized to 0 if not explicitly
initialized.
To register a service in the GATT DB the aci_gatt_srv_add_service function is used:
aci_gatt_srv_add_service(&gap_srvc);
while retrieving the assigned attribute handle the aci_gatt_srv_get_service_handle
function is used: uint16_t gap_h = aci_gatt_srv_get_service_handle(&gap_srvc);
The registered services can be also removed at run time if needed using the aci_gatt_srv_rm_service
function: aci_gatt_srv_rm_service(gap_h);
Note: The memory used for a service definition structure is kept valid for all the time such service is active.
Note: The memory used for a characteristic definition structure is kept valid for all the time such characteristic is active.
4.2.2.3 Descriptor
Characteristic descriptors are used to contain the related information about the characteristic value. A standard
set of characteristic descriptors are defined to be used by application. The application can also define additional
characteristic descriptors as profile specifics.
A characteristic descriptor is defined using the following ble_gatt_descr_def_t C language structure:
typedef struct ble_gatt_descr_def_s {
uint8_t properties;
uint8_t min_key_size;
uint8_t permissions;
ble_uuid_t uuid;
ble_gatt_val_buffer_def_t *val_buffer_p;
} ble_gatt_descr_def_t;
The descriptor can also be added together with the related characteristic by specifying the descrs field of
ble_gatt_chr_def_t.
Since the client characteristic configuration descriptor (CCCD) is quite common to be present in a profile, then
some helper macros are provided to define it:
• BLE_GATT_SRV_CCCD_DECLARE: declares CCCD value buffer and descriptor fields. Commonly used
when a characteristic has just the CCCD as unique descriptor
• BLE_GATT_SRV_CCCD_DEF_STR_FIELDS: fills the descriptor structure fields for a CCCD. It can be used
when a characteristic has more than the CCC descriptor to fill the fields of a descriptor definition array
Note: The memory used for a characteristic descriptor definition structure is valid for all the time such descriptor is
active.
If the application needs to fill the value buffer with a 2-byte value (e.g. 0x0101), it can directly address its value
through the buffer and set the actual length:
memset(val_buffer.buffer_p, 0x01, 2);
val_buffer.val_len = 2;
The stack is not aware of such value update until a remote device sends a read request to retrieve its value.
If the characteristic has a fixed length, ble_gatt_val_buffer_def_t structure can be defined as a constant.
const ble_gatt_val_buffer_def_t val_buffer = {
buffer_len = 2,
buffer_p = buffer,
};
Moreover, if the value cannot be changed (i.e. read only access), then the buffer pointed by buffer_p can be
also declared as a constant.
const uint8_t buffer[2] = {0x01, 0x01};
If the value is dynamically computed (e.g. temperature) then the value buffer is not needed: if val_buffer_p
field of characteristic or descriptor C structure is not set (i.e. set to NULL) then some events are generated to
access such value:
• aci_gatt_srv_read_event is generated when a remote device needs to read a characteristic value or
descriptor
• aci_gatt_srv_write_event, is generated when a remote device needs to write a characteristic value
or descriptor
Note: The memory used for value buffer definition is valid for all the time such buffer is active.
API Description
aci_gatt_srv_rm_service This function removes the provided service from the database
aci_gatt_srv_rm_char_desc This function removes the provided descriptor from the database
4.2.2.6 Examples
The following examples are intended to explain how to define a profile.
GATT profile
This example illustrates how to implement and register the GATT profile.
Note: The complete GATT service is already implemented in gatt_profile.c. A more simple implementation is described
here.
This profile is composed of a primary service with a 16-bit UUID set to 0x1801 and the service changed
characteristic, with the indication property bit set. To support indications the characteristic has the client
characteristic configuration descriptor. To declare this descriptor the BLE_GATT_SRV_CCCD_DECLARE macro
can be used. This macro has the following parameter:
BLE_GATT_SRV_CCCD_DECLARE(NAME, NUM_CONN, PERM, OP_FLAGS)
Where:
• NAME is the name assigned to identify this CCCD
• NUM_CONN is the number of supported concurrent connections for the targeted application
• PERM, is the bit field of descriptor permission
Declare now the characteristic value buffer, since it has to be provided as val_buffer_p of
ble_gatt_chr_def_t structure:
uint8_t srv_chgd_buff[4];
const ble_gatt_val_buffer_def_t srv_chgd_val_buff = {
.buffer_len = 4U,
.buffer_p = gatt_chr_srv_changed_buff,
};
Once the descriptor and the characteristic value buffer are declared then the service changed characteristic can
be declared:
static ble_gatt_chr_def_t gatt_chr = {
.properties = BLE_GATT_SRV_CHAR_PROP_INDICATE,
.permissions = BLE_GATT_SRV_PERM_NONE,
.uuid = BLE_UUID_INIT_16(0x2A05),
.val_buffer_p = &srv_chgd_val_buff,
.descrs = {
.descrs_p =
&BLE_GATT_SRV_CCCD_DEF_NAME(gatt_chr_srv_changed),
.descr_count = 1U,
},
};
As stated, this characteristic has the indication bit set in the properties bit field, no security permissions, the
UUID set to 0x2A05 and one descriptor.
Now the GATT service can be declared:
static ble_gatt_srv_def_t gatt_srvc = {
.type = BLE_GATT_SRV_PRIMARY_SRV_TYPE,
.uuid = BLE_UUID_INIT_16(0x1801),
.chrs = {
.chrs_p = &gatt_chr,
.chr_count = 1,
},
};
To register the whole profile, only the service is registered: all the included characteristics and its descriptors are
automatically registered. Use the aci_gatt_srv_add_service to register the service:
aci_gatt_srv_add_service(&gatt_srvc);
Glucose
Consider the following database:
ble_gatt_chr_def_t batt_level_chr = {
.properties = BLE_GATT_SRV_CHAR_PROP_READ,
.permissions = BLE_GATT_SRV_PERM_NONE,
.uuid = BLE_UUID_INIT_16(0x2A19),
.val_buffer_p = &battery_level_val_buff,
};
ble_gatt_srv_def_t battery_level_srvc = {
.type = BLE_GATT_SRV_SECONDARY_SRV_TYPE,
.uuid = BLE_UUID_INIT_16(0x180F),
.chrs = {
.chrs_p = &batt_level_chr,
.chr_count = 1,
},
};
uint8_t ext_prop_descr_buff[2];
ble_gatt_val_buffer_def_t ext_prop_descr_val_buff = {
.buffer_len = 2,
.buffer_p = ext_prop_descr_buff,
};
ble_gatt_descr_def_t glucose_chr_descrs[] = {
{
BLE_GATT_SRV_CCCD_DEF_STR_FIELDS(glucose_mes, MAX_CONN,
BLE_GATT_SRV_CCCD_PERM_DEFAULT),
},
};
ble_gatt_chr_def_t glucose_mes_chr = {
.properties = BLE_GATT_SRV_CHAR_PROP_READ | BLE_GATT_SRV_CHAR_PROP_INDICATE |
BLE_GATT_SRV_CHAR_PROP_EXTENDED_PROP,
.permissions = BLE_GATT_SRV_PERM_NONE,
.uuid = BLE_UUID_INIT_16(0x2A18),
.descrs = {
.descrs_p = &BLE_GATT_SRV_CCCD_DEF_NAME(glucose_chr_descrs),
.descr_count = 2U,
},
};
As shown the glucose_srvc has set the group_size field: this is there to allow the battery service to be
registered at 0x1000 attribute handles. This service does not include any characteristic or included services. This
is a choice, for this example, to show how to register such elements one by one.
First, register the glucose service:
aci_gatt_srv_add_service(&glucose_srvc);
this is a primary service with a 16-bit UUID set to 0x1808.
Register battery service and its characteristic:
aci_gatt_srv_add_service(&battery_level_srvc);
This is a secondary service with a 16-bit UUID set to 0x180F that includes a characteristic. Both service and
characteristic are registered.
Now it is time to include the battery service in the glucose service and register its characteristic and descriptors.
For this purpose the assigned attribute handle is needed to get for the glucose and battery services:
uint16_t glucose_srvc_handle =
aci_gatt_srv_get_service_handle(&glucose_srvc);
uint16_t battery_srvc_handle =
aci_gatt_srv_get_service_handle(&battery_level_srvc);
Note: Included services are added to service before registering any characteristic to the same service. This is
needed because the include service attribute is placed after the service declaration attribute and before any
characteristic declaration attributes.
To register the glucose measurement characteristic and its descriptors, use the aci_gatt_srv_add_char()
function as shown below:
aci_gatt_srv_add_char(&glucose_mes_chr, glucose_srvc_handle);
The glucose measurement characteristic and the included descriptors are added.
uint16_t Connection_Handle The connection handle for which the notification is requested
uint16_t Attr_Handle The attribute handle to notify
Notification flags:
• 0x00: sends a notification
uint8_t Flags
• 0x01: sends a flushable notification
• 0x02: sends an indication
uint16_t Val_Length The length of provided value buffer
uint8_t * Val_p The pointer to the buffer containing the value to notify
The Flags parameter indicates the kind of message that is sent. For instance, to notify the value of the attribute
with handle 0x13 to a client, with a connection handle of 0x0801 then the following code is used.
uint8_t value = 1;
ret = aci_gatt_srv_notify(0x0801, 0x13, 0, 1, &value);
If the client has set the notification bit into the CCCD of the characteristic then the notification is sent, otherwise a
BLE_STATUS_NOT_ALLOWED error is returned.
aci_gatt_srv_read_event()
This event is generated when the server receives a read operation of an attribute value and the stack does not
have direct access to such value. This event must be followed by aci_gatt_srv_resp(), passing the value of
the attribute.
uint16_t Connection_Handle The connection handle where the read request is received
aci_gatt_srv_write_event()
This event is generated when the server receives a write operation of an attribute value and it does not have
access to the attribute value buffer. This event must be followed by aci_gatt_srv_resp() if Resp_Needed is
1.
uint16_t Connection_Handle The connection handle where the write request is received
aci_att_srv_prepare_write_req_event()
This event is generated when the server receives a prepare write request. It carries the received data stored at
application level. This event must be followed by aci_gatt_srv_resp(), passing back to the stack the value,
which is written by the application.
uint16_t Attribute_Handle Attribute handle for which the write request is received
aci_att_srv_exec_write_req_event()
This event is generated when the server receives an execute write request. Application must handle it to write
or flush all stored prepare write requests, depending on the Flags value. This event must be followed by
aci_gatt_srv_resp().
aci_gatt_srv_resp()
When the previous events are generated by the stack, the application must decide to allow (and execute) or deny
the requested operation. To inform the stack about the choice made by the application and pass the requested
data (in case of a read request or a prepare write request), a function is provided: aci_gatt_srv_resp(). This
function is used to close a read or write transaction started by a remote client.
Note: This function is executed within 30 seconds from the reception of event otherwise a GATT timeout occurs.
uint16_t Attribute_Handle Attribute handle for which the response command is issued
The reason why the request has generated an error response (use one of the ATT error
uint8_t Error_Code
codes, see [1], Vol. 3, Part F, Table 3.4)
Note: Data pointed by Val is no more needed on function return and can be released.
aci_gatt_srv_read_event() example
The following code shows an example of how to implement the aci_gatt_srv_read_event() handler.
The code manages the attribute handles 0x16 and 0x19. The handle 0x16 is mapped on a GPIO value while
handle 0x19 returns 4 bytes. The aci_gatt_srv_resp() generates the read response with the given data if
Error_Code is set to 0, otherwise it sends an error response.
aci_gatt_srv_write_event() example
The following example shows how to manage the aci_gatt_srv_write_event() event. In this example,
writing the attribute handle 0x16 changes a GPIO state.
buffer_len = 0;
buffer = NULL;
if (Data_Length != 1)
{
att_err = BLE_ATT_ERR_INVAL_ATTR_VALUE_LEN;
}
else if (Attribute_Handle != 0x16)
{
att_err = BLE_ATT_ERR_UNLIKELY;
}
else if ((Data[0] != 0) && (Data[0] != 1))
{
att_err = BLE_ATT_ERR_VALUE_NOT_ALLOWED;
}
else
{
/** Set GPIO value */
att_err = BLE_ATT_ERR_NONE;
gpio_set(GPIO_01, Data[0];
}
if (Resp_Needed == 1U)
{
aci_gatt_srv_resp(Connection_Handle, Attribute_Handle,
att_err, buffer_len, buffer);
}
}
aci_att_srv_prepare_write_req_event() example
The following example shows how to implement the aci_att_srv_prepare_write_req_event() handler.
This function uses the ATT_pwrq module to store the received prepare write but any kind of queue that can
handle such use case can be used.
Note: The aci_gatt_srv_resp() function is called passing the received data. This data is needed to be redirected
back to the stack to generate the prepare write response packet. It contains such data and acknowledges the
client about the correctness of the received data.
aci_gatt_srv_exec_write_resp() example
The following code shows an example of how to implement an aci_att_srv_exec_write_req_event()
handler. All queued prepare write requests are written by write_queued_data() function, as shown below.
The aci_gatt_srv_resp() function generates an exec write response or an error based on att_error
value.
void aci_gatt_srv_exec_write_resp(uint16_t Conn_Handle,
void aci_gatt_srv_exec_write_resp(uint16_t Conn_Handle, uint8_t Exec)
{
uint8_t att_error;
att_error = BLE_ATT_ERR_NONE;
if (Exec == 1U)
{
att_error = write_queued_data(Conn_Handle);
}
ATT_pwrq_flush(Conn_Handle);
aci_gatt_srv_resp(Conn_Handle, 0U, att_error, 0U, NULL);
}
ATT_pwrq_flush()
This function removes all the queued writes related to a connection handle.
ATT_pwrq_read()
Read the FIFO elements. Such elements are filtered per connection handle and indexed by a parameter.
ble_gatt_clt_write_ops_t * wr_ops_p Returning pointer to the structure that holds the prepared write information
ATT_pwrq_pop()
Extract an entry from the FIFO. The entry is filtered per connection and attribute handles.
ATT_pwrq_push()
Push the data of a prepare write in the FIFO.
uint16_t conn_handle The connection handle from where the connection handle is received
uint16_t data_offset The offset from where to start writing the data
4.2.3.1 DTM
An adaptation layer inside the device is needed to use the device as a network coprocessor. The DTM (direct test
mode) example application is a way to use the device in a network processor mode. DTM application exposes
ACI (application-controller interface) commands and events, so that an application on an external device can use
the Bluetooth® Low Energy stack through a serial interface.
The interface to the GATT layer exposed by the DTM application is different from the native GATT API.
The aci_gatt_nwk.c file implements the adaptation layer between the network co-processor API and the
native API. This module defines some buffers used to allocate the memory space needed to define services,
characteristics and descriptors. It also allocates the memory needed to store the attribute values that reside in
the DTM memory space. It uses a dynamic memory allocator to allocate the requested memory. The allocated
structures are inserted in a linked list to search the associated value buffer when a read/write operation is
requested by a client.
Some client procedures (e.g. write and write long characteristic procedures) need to temporary store data in a
buffer. This component also allocates the buffer needed by those procedures. These buffers are kept allocated
until the procedure is complete.
API Description
API Description
A service with its characteristics can be added using the following command:
ret= aci_gatt_srv_add_service((ble_gatt_srv_def_t *)&user_service);
Once the service with related characteristics (TX, RX) has been added, the user can get the related TX, RX
characteristics handles with the following commands:
TXCharHandle=aci_gatt_srv_get_char_decl_handle((ble_gatt_chr_def_t *)&chat_chars[0]);
RXCharHandle=aci_gatt_srv_get_char_decl_handle((ble_gatt_chr_def_t *)&chat_chars[1]);
For a detailed description of the aci_gatt_srv_add_service() API parameters refer to the header file
bluenrg_lp_events.h.
Table 51. aci_gap_set_advertising_configuration() API : discoverable mode and advertising type selection
Discoverable_Mode Advertising_Event_Properties
API
parameter parameter
0x0001: connectable
0x0002: scannable
0x00: not discoverable
0x0004: directed
0x01: limited
0x0008: high duty cycle directed
aci_gap_set_advertising_configuration() discoverable
connectable
0x02: general
0x0010: legacy
discoverable
0x0020: anonymous
0x0040: include TX power
The aci_gap_set_advertising_data() API allows the data to be set in advertising PDUs. In particular,
the user is requested to specify the length of advertising data (Advertising_Data_Length parameter) and
to provide the advertising data (Advertising_Data parameter) inline with the advertising format defined on
Bluetooth® LE specifications.
The content of the buffer containing the advertising/scan response data is directly accessed by the stack, hence it
should not change when device is advertising.
An aci_hal_adv_scan_resp_data_update_event is received to inform the application that the buffer is
no more used by the stack. This can happen after a new advertising buffer is provided to the stack through
aci_gap_set_advertising_data or when advertising has been terminated. It is possible to change the
content of the advertising buffer, while it is used by the stack, without any unwanted effect (e.g. corrupted data
over-the-air) only when the change is atomic, e.g. a single byte or word is modified.
Once the advertising configuration and data have been defined, the user can enable/disable advertising using the
aci_gap_set_advertising_enable() API (Enable parameter).
GAP discovery procedure
The aci_gap_set_scan_configuration() API allows the scan parameters to be configured for a given
PHY. Once the scan parameters are defined, the user can start a specific discovery procedure by using the
aci_gap_start_procedure() API, Procedure_Code parameter.
0x00: LIMITED_DISCOVERY
0x01: GENERAL_DISCOVERY
0x02: AUTO_CONNECTION
aci_gap_start_procedure()
0x03: GENERAL_CONNECTION
0x04: SELECTIVE_CONNECTION
0x05: OBSERVATION
0x00: LIMITED_DISCOVERY
aci_gap_terminate_proc()
0x01: GENERAL_DISCOVERY
4.3.1 Set the discoverable mode and use the direct connection establishment procedure
The following pseudocode example illustrates the specific steps only to be followed to let a GAP peripheral device
be a general discoverable mode, and for a GAP central device to directly connect to it through a direct connection
establishment procedure.
Note: It is assumed that the device public address has been set during the initialization phase as follows:
uint8_t bdaddr[] = {0x12, 0x34, 0x00, 0xE1, 0x80, 0x02}; ret=aci_hal_write_config_data(CONFIG_DATA_PUBA
DDR_OFFSET,CONFIG_DATA_PUBADDR_LEN, bdaddr);
if(ret != BLE_STATUS_SUCCESS)PRINTF("Failure.\n");
/*GAP Peripheral: configure general discoverable mode and set advertising data
*/
void GAP_Peripheral_Configure_Advertising(void )
{
tBleStatus ret;
/* Define advertising data content: set AD type flags and complete local name */
static uint8_t adv_data[] = {0x02,AD_TYPE_FLAGS, FLAG_BIT_LE_GENERAL_DISCOVERABLE_MODE|FLAG_BIT_BR_
EDR_NOT_SUPPORTED,13, AD_TYPE_COMPLETE_LOCAL_NAME, 'B','l','u','e','N','R','G','X','T','e','s',' t'};
/* Configure the General Discoverable mode, connectable and scannable (legacy advertising):
Advertising_Handle: 0
Discoverable_Mode: GAP_MODE_GENERAL_DISCOVERABLE (general discovery mode)
Advertising_Event_Properties ADV_PROP_CONNECTABLE|ADV_PROP_SCANNABLE|ADV_PROP_LEGACY(connectable, s
cannable and legacy)
Primary_Advertising_Interval_Min: 100;
Primary_Advertising_Interval_Max: 100
Primary_Advertising_Channel_Map: ADV_CH_ALL (channels 37,38,39)
Peer_Address_Type: 0;
Peer_Address[6]: NULL;
Advertising_Filter_Policy: ADV_NO_WHITE_LIST_USE (no whitelist);
Advertising_Tx_Power: 0;
Primary_Advertising_PHY: 0;
Secondary_Advertising_Max_Skip: 0;
Secondary_Advertising_PHY: 0;
Advertising_SID: 0;
Scan_Request_Notification_Enable: 0.
*/
ret = aci_gap_set_advertising_configuration(0,
GAP_MODE_GENERAL_DISCOVERABLE,
ADV_PROP_CONNECTABLE
ADV_PROP_SCANNABLE|ADV_PROP_LEGACY,
100, 100,
ADV_CH_ALL,
0,
NULL,
ADV_NO_WHITE_LIST_USE,
0, 1, 0, 1, 0,0);
if (ret != BLE_STATUS_SUCCESS) PRINTF("Failure.\n");
} /* end GAP_Peripheral_Configure_Advertising() */
Once that advertising mode and data have been configured, the GAP peripheral device can enable advertising
using the aci_gap_set_advertising_enable() API:
static Advertising_Set_Parameters_t Advertising_Set_Parameters[1];
GAP central device must configure the scanning and connection parameters, before connecting to the GAP
peripheral device in discoverable mode.
/*GAP Central: configure scanning and connection parameters
*/
void GAP_Central_Configure_Connection(void)
{
/* Configure the scanning parameters:
Filter_Duplicates: DUPLICATE_FILTER_ENABLED (Duplicate filtering enabled)
Scanning_Filter_Policy: SCAN_ACCEPT_ALL (accept all scan requests)
Scanning_PHY: LE_1M_PHY (1Mbps PHY)
Scan_Type: PASSIVE_SCAN
Scan_Interval: 0x4000;
Scan_Window: 0x4000;
*/
ret=aci_gap_set_scan_configuration(DUPLICATE_FILTER_ENABLED,
SCAN_ACCEPT_ALL,
LE_1M_PHY,
PASSIVE_SCAN,
0x4000,
0x4000);
if(ret != BLE_STATUS_SUCCESS) PRINTF("Failure.\n");
Once the scanning and connection parameters have been configured, the GAP central device can perform the
direct connection to the GAP peripheral device using the aci_gap_create_connection() API.
void GAP_Central_Make_Connection(void)
{
/*Start the direct connection establishment procedure to the GAP peripheral device:
Initiating_PHY:LE_1M_PHY(1 Mbps PHY)
Peer_Address_Type: PUBLIC_ADDR (public address);
Peer_Address: {0xaa, 0x00, 0x00, 0xE1, 0x80, 0x02};
*/
Note: 1. If ret = BLE_STATUS_SUCCESS is returned, on termination of the GAP procedure, the event callback
hci_le_enhanced_connection_complete_event() is called, to indicate that a connection has been
established with the GAP_Peripheral_address (same event is returned on the GAP peripheral device)
2. The connection procedure can be explicitly terminated by issuing the API aci_gap_terminate_proc()
with proper Procedure_Code parameter value
3. The last two parameters Minimum_CE_Length and Maximum_CE_Length of the
aci_gap_set_connection_configuration() are the length of the connection event needed for the
Bluetooth® LE connection. These parameters allow the user to specify the amount of time the master has
to allocate for a single slave so they must be chosen wisely. In particular, when a master connects to more
slaves, the connection interval for each slave must be equal or a multiple of the other connection intervals
and the user must not overdo the connection event length for each slave.
4.3.2 Set discoverable mode and use general discovery procedure (active scan)
The following pseudocode example illustrates the specific steps only to be followed to let a GAP peripheral device
be in a general discoverable mode, and for a GAP central device to start a general discovery procedure in order
to discover the devices within its radio range.
Note: It is assumed that the device public address has been set during the initialization phase as follows:
uint8_t bdaddr[] = {0x12, 0x34, 0x00, 0xE1, 0x80, 0x02};
ret =aci_hal_write_config_data(CONFIG_DATA_PUBADDR_OFFSET,CONFIG_DATA_PUBADDR_LEN, bdaddr)
if (ret != BLE_STATUS_SUCCESS)PRINTF("Failure.\n");
Furthermore, the GAP peripheral device has configured the advertising and related data as described
in Section 4.3.1 Set the discoverable mode and use the direct connection establishment procedure.
The GAP peripheral device can enable scan response data and then the advertising using the
aci_gap_set_advertising_enable() API:
static Advertising_Set_Parameters_t Advertising_Set_Parameters[1];
/* Enable advertising:
Enable: ENABLE (enable advertsing);
Number_of_Sets: 1;
Advertising_Set_Parameters: Advertising_Set_Parameters */
Advertising_Set_Parameters[0].Advertising_Handle = 0;
Advertising_Set_Parameters[0].Duration = 0;
Advertising_Set_Parameters[0].Max_Extended_Advertising_Events = 0;
//enable advertising
ret = aci_gap_set_advertising_enable(ENABLE, 1,Advertising_Set_Parameters);
if (ret != BLE_STATUS_SUCCESS) PRINTF("Failure.\n");
} /* end GAP_Peripheral_Make_Discoverable() */
The GAP central device must configure the scanning parameters, before starting the GAP general discovery
procedure.
/*GAP Central: configure scanning parameters for general discovery procedure*/
void GAP_Central_Configure_General_Discovery_Procedure(void)
{
tBleStatus ret;
/*GAP Central: start general discovery procedure to discover the GAP peripheral device in dis coverable
mode */
void GAP_Central_General_Discovery_Procedure(void)
{
tBleStatus ret;
The responses of the procedure are given through the event callback
hci_le_extended_advertising_report_event(). The end of the procedure is indicated by
aci_gap_proc_complete_event() event callback with Procedure_Code parameter equal to
GAP_GENERAL_DISCOVERY_PROC (0x1).
/* This callback is called when an advertising report is received */
void hci_le_extended_advertising_report_event(uint8_t Num_Reports,
Extended_Advertising_Report_t Advertising_Report[])
{
/* Advertising_Report contains all the expected parameters.
User application should add code for decoding the received
Advertising_Report event databased on the specific evt_type (ADV_IND, SCAN_RSP, ..)
*/
/* RSSI value */
int8_t RSSI = Advertising_Report[0].RSSI;
} /* hci_le_extended_advertising_report_event() */
In particular, in this specific context, the following events are raised on the GAP central
hci_le_extended_advertising_report_event(), as a consequence of the GAP peripheral device in
discoverable mode with scan response enabled:
1. Advertising Report event with advertising packet type (evt_type =ADV_IND - 0x0013)
2. Advertising Report event with scan response packet type (evt_type =SCAN_RSP - 0x001B)
0x02,0x01,0x06,0x08,0x09,0x42
0x0013 0x0280E1003
0x00 (public address) ,0x6C,0x75,0x65,0x4E,0x52,0x4 0xCE
(ADV_IND) 412
7,0x02,0x 0A,0xFE
The advertising data are shown as follows (refer to Bluetooth® specification version in Section 6 References):
0x12,0x66,0x9A,0x0C, 0x20,0x00,0x08,0xA7,0
0x01 (random xBA,0xE3,0x11,0x06,0x
0x001B (SCAN_RS P) 0x0280E1003412 0xDA
address)
85,0xC0,0xF7,0x97,0x8A,0x06,0x11
The scan response data can be interpreted as follows: (refer to Bluetooth® specifications):
GAP
hci_disconnection_complete_event() A connection is terminated central/
peripheral
GAP
Indicates to both of the devices forming
central/
the connection that a new connection has
hci_le_enhanced_connection_complete_event() been established. This event is raised peripheral
when the Bluetooth® LE stack supports (Bluetooth®
the extended advertsing/scanning features LE stack
v3.x)
Generated by the GATT client when a
aci_gatt_clt_notification_event() GATT client
server notifies any attribute on the client
Generated by the GATT client when a
aci_gatt_clt_indication_event() GATT client
server indicates any attribute on the client
Generated by the security manager to the
application when a passkey is required for GAP
pairing.
aci_gap_pass_key_req_event() central/
When this event is received, the
application has to respond with the peripheral
aci_gap_pass_key_resp() API
For a detailed description of the Bluetooth® Low Energy event, and related formats refer to the Bluetooth® Low
Energy stack APIs and events documentation in References.
The following pseudocode provides an example of event callbacks handling some of the described Bluetooth®
Low Energy stack events (disconnection complete event, connection complete event, GATT attribute modified
event , GATT notification event):
/* This event callback indicates the disconnection from a peer device.
It is called in the Bluetooth® LE radio interrupt context.
*/
void hci_disconnection_complete_event(uint8_t Status,
uint16_t Connection_Handle, uint8_t Reason)
{
/* Add user code for handling Bluetooth® LE disconnection complete event based on application scen
ario.
*/
}/* end hci_disconnection_complete_event() */
*/
#if GATT_SERVER
/* This event callback indicates that an attribute has been written from a peer device.
*/
void aci_gatt_srv_write_event(uint16_t Connection_Handle,
uint8_t Resp_Needed,
uint16_t Attribute_Handle,
uint16_t Data_Length,
uint8_t Data[]);{
/* Add user code for handling attribute modification event based on application scenario.
NOTE: Refer to header file bluenrglp_events.h for a complete description of the event callbac
k parameters.
*/
...
} /* end aci_gatt_srv_write_event () */
#endif /* GATT_SERVER */
#if GATT_CLIENT
/* This event callback indicates that an attribute notification has been received from a peer
device.
*/
void aci_gatt_notification_event(uint16_t Connection_Handle,uint16_t Attribute_Handle,
uint8_t Attribute_Value_Length,uint8_t Attribute_Value[])
{
/* Add user code for handling attribute notification event based on application scenario.
NOTE: Refer to header bluenrglp_events.h for a complete
description of the event callback parameters*/
…
} /* end aci_gatt_notification_event() */
#endif /* GATT_CLIENT */
PassKey Entry example with 2 Bluetooth® Low Energy devices: Device_1, Device_2
The following pseudocode example illustrates only the specific steps to be followed to pair two devices by using
the PassKey entry method.
As described in Table 2, Device_1, Device_2 must set the IO capability in order to select PassKey entry as a
security method.
In this particular example, "Display Only" on Device_1 and "Keyboard Only" on Device_2 are selected, as follows:
/*Device_1: */
tBleStatus ret;
ret= aci_gap_set_io_capability(IO_CAP_DISPLAY_ONLY);
if (ret != BLE_STATUS_SUCCESS) PRINTF("Failure.\n");
/*Device_2: */
tBleStatus ret;
ret= aci_gap_set_io_capability(IO_CAP_KEYBOARD_ONLY);
if (ret != BLE_STATUS_SUCCESS) PRINTF("Failure.\n");
ret=aci_gap_set_authentication_requirement(BONDING,/*bonding is
enabled */
MITM_PROTECTION_REQUIRED,
SC_IS_SUPPORTED,/*Secure connection
supported
but optional */
KEYPRESS_IS_NOT_SUPPORTED,
7, /* Min encryption key size */
16, /* Max encryption
key size */
0x01, /* fixed pin is not used*/
0x123456, /* fixed pin */
0x00 /* Public Identity address type */);
if (ret != BLE_STATUS_SUCCESS) PRINTF("Failure.\n");
Once the security IO capability and authentication requirements are defined, an application can initiate a pairing
procedure as follows:
1. By using aci_gap_slave_security_req() on a GAP peripheral (slave) device (it sends a slave security
request to the master):
tBleStatus ret;
ret= aci_gap_slave_security_req(conn_handle,
if (ret != BLE_STATUS_SUCCESS) PRINTF("Failure.\n");
Since the Device_1, I/O capability is set as “Display Only”, it should display the generated pin in the device
display. Since Device_2, I/O capability is set as “Keyboard Only”, the user can provide the pin displayed on
Device_1 to the Device_2 though the same aci_gap_pass_key_resp() API, by a keyboard.
Alternatively, if the user wants to set the authentication requirements with a fixed pin 0x123456 (no pass key
event is required), the following pseudocode can be used:
tBleStatus ret;
Note: 1. When the pairing procedure is started by calling the described APIs (aci_gap_slave_security_req()
or aci_gap_send_pairing_req()) and the value ret= BLE_STATUS_SUCCESS is returned, on
termination of the procedure, an aci_gap_pairing_complete_event() event callback is called to
indicate the pairing status on the callback Status parameter:
– 0x00: pairing success
– 0x01: pairing timeout
– 0x02: pairing failed
The reason parameter provides the pairing failed reason code in case of failure (0 if status
parameter returns success or timeout).
2. When two devices get paired, the link is automatically encrypted during the first connection. If bonding is
also enabled (keys are stored for a future time), when the two devices get connected again, the link can be
simply encrypted (with no need to perform again the pairing procedure). User applications can simply use
the same APIs, which do not perform the paring process but just encrypt the link:
– aci_gap_slave_security_req ) on the GAP peripheral (slave) device or
– aci_gap_send_pairing_req() on the GAP central (master ) device.
3. If a slave has already bonded with a master, it can send a slave security request to the master to encrypt
the link. When receiving the slave security request, the master may encrypt the link, initiate the pairing
procedure, or reject the request. Typically, the master only encrypts the link, without performing the pairing
procedure. Instead, if the master starts the pairing procedure, it means that for some reason, the master
lost its bond information, so it has to start the pairing procedure again. As a consequence, the slave device
calls the aci_gap_bond_lost_event()event callback to inform the user application that it is no longer
bonded with the master it was previously bonded with. Then, the slave application can decide to allow the
security manager to complete the pairing procedure and re-bond with the master by calling the command
aci_gap_allow_rebond(), or just close the connection and inform the user of the security issue.
Table 59. Bluetooth® Low Energy sensor profile demo services and characteristic handle
Characteristic
Service /
Characteristic client descriptor Characteristic
Service Characteristic characteristic
value handle configuration format handle
handle
handle
Acceleration
NA 0x0010 NA NA NA
service
Free Fall
0x0011 0x0012 0x0013 NA
characteristic
Acceleration
0x0014 0x0015 0x0016 NA
characteristic
Environmental
NA 0x0017 NA NA NA
service
Temperature
0x0018 0xx0019 NA 0x001A
characteristic
Pressure
0x001B 0xx001C NA 0x001D
characteristic
For detailed information about the sensor profile demo, refer to the SDK user manual and the sensor demo
source code available within the SDK software package (see Section 6 References).
A list of the service discovery APIs with related description is as follows:
This API starts the GATT client procedure to discover all primary services on
the GATT server. It is used when a GATT client connects to a device and it
aci_gatt_clt_disc_all_primary_services()
wants to find all the primary services provided on the device to determine what
it can do
This API starts the GATT client procedure to discover a primary service on the
GATT server by using its UUID.
aci_gatt_clt_disc_primary_service_by_uuid()
It is used when a GATT client connects to a device and it wants to find a
specific service without the need to get any other services
This API starts the procedure to find all included services. It is used when a
aci_gatt_clt_find_included_services() GATT client wants to discover secondary services once the primary services
have been discovered
In the context of the sensor profile demo, the GAP central application should get three read by group type
response events (through related aci_gatt_clt_read_by_group_type_resp_event() event callback),
with the following callback parameter values.
First read by group type response event callback parameters:
Connection_Handle: 0x0801 (connection handle);
Attr_Data_Length: 0x06 (length of each discovered service data: service
handle, end group handle,service uuid);
Data_Length: 0x0C (length of Attribute_Data_List in octets
Att_Data_List: 0x0C bytes as follows:
Table 61. First read by group type response event callback parameters
Table 62. Second read by group type response event callback parameters
0x02366E80CF3A11E19AB4
0x0010 0x0016 Acceleration service 128-bit service proprietary UUID
0002A5D5C51B
Table 63. Third read by group type response event callback parameters
In the context of the sensor profile demo, when the discovery all primary service procedure completes, the
aci_gatt_clt_proc_complete_event() event callback is called on GAP central application, with the
following parameters
Conn_Handle: 0x0801 (connection handle;
Error_Code: 0x00
aci_gatt_ctl_disc_all_char_of_service () This API starts the GATT procedure to discover all the
characteristics of a given service
This API starts the GATT procedure to discover all the
aci_gatt_ctl_disc_char_by_uuid ()
characteristics specified by a UUID
This API starts the procedure to discover all characteristic
aci_gatt_ctl_disc_all_char_desc ()
descriptors on the GATT server
In the context of theBluetooth® Low Energy sensor profile demo, follow a simple pseudocode illustrating
how a GAP central application can discover all the characteristics of the acceleration service (refer to
Table 1. Bluetooth® Low Energy LE RF channel types and frequencies second read by group type response
event callback parameters):
uint16_t service_handle= 0x0010;
uint16_t end_group_handle = 0x0016;
The responses of the procedure are given through the aci_att_read_by_type_resp_event() event
callback. The end of the procedure is indicated by aci_gatt_proc_complete_event() event callback call.
void aci_att_read_by_type_resp_event(uint16_t Connection_Handle,
uint8_t Handle_Value_Pair_Length,
uint8_t Data_Length,
uint8_t Handle_Value_Pair_Data[])
{
/*
Connection_Handle: connection handle related to the response;
Handle_Value_Pair_Length: size of each attribute handle-value
Pair;
Data_Length: length of Handle_Value_Pair_Data in octets.
Handle_Value_Pair_Data: Attribute Data List as defined in
Bluetooth Core specifications. A sequence of handle-value pairs: [2
octets for Attribute Handle, (Handle_Value_Pair_Length - 2 octets)
for Attribute Value].
*/
/* Add user code for decoding the Handle_Value_Pair_Data field and
In the context of the Bluetooth® Low Energy sensor profile demo, the GAP central application should get two
read type response events (through related aci_att_read_by_type_resp_event() event callback), with the
following callback parameter values.
First read by type response event callback parameters:
Free fall
characteristic
128-bit
0x0011 0x10 (notify) 0x0012 0xE23E78A0CF4A11E18FFC0002A5D5C51B
characteristic
proprietary
UUID
Characteristi
Characteristic
Characteristic handle c value Characteristic UUID Note
properties
handle
Acceleration
characteristic
0x12 (notify and 0x340A1B80CF4B11E1AC360002A5D5C51
0x0014 0x0015 128-bit
read) B
characteristic
proprietary UUID
In the context of the sensor profile demo, when the discovery all primary service procedure completes, the
aci_gatt_proc_complete_event() event callback is called on GAP central application, with the following
parameters:
Connection_Handle: 0x0801 (connection handle);
Error_Code: 0x00.
Similar steps can be followed in order to discover all the characteristics of the environment service
(Table 1. Bluetooth® Low Energy LE RF channel types and frequencies).
In the context of the sensor profile demo, the GAP central application should use a simple pseudocode in order to
configure the free fall and the acceleration characteristic client descriptor configuration for notification:
tBleStatus ret;
uint16_t handle_value = 0x0013;
/*Enable the free fall characteristic client descriptor configuration */
ret = aci_gatt_clt_write(conn_handle,
handle_value /* handle for free fall client descriptor configuration */
0x02,/* attribute value length */
0x0001,/* attribute value: 1 for notification */
if (ret != BLE_STATUS_SUCCESS) PRINTF("Failure.\n");
handle_value = 0x0016;
/*Enable the acceleration characteristic client descriptor configuration for notification */
ret= aci_gatt_clt_write (conn_handle,handle_value/* handle for acceleration client descriptor
configuration *0x02, /*attribute value length */
0x0001, /* attribute value:1 for notification */);
if (ret != BLE_STATUS_SUCCESS) PRINTF("Failure.\n");
Once the characteristic notification has been enabled from the GAP central, the GAP peripheral can notify a new
value for the free fall and acceleration characteristics as follows:
tBleStatus ret;
uint8_t val = 0x01;
uint16_t charac_handle = 0x0017;
tBleStatus ret;
uint8_t buff[6];
uint16_t charac_handle = 0x004;
/*Set the mems acceleration values on three axis x,y,z on buff array */
/*GAP peripheral notifies acceleration characteristic to GAP Central*/
ret= aci_gatt_srv_notify (connection_handle, /* connection handle */
charac_handle, /* acceleration characteristic handle*/
0, /* updated type: notification */
0x06, /* characteristic value length */
buff /* characteristic value */)
);
if(ret != BLE_STATUS_SUCCESS) PRINTF("Failure.\n");
}/* aci_gatt_clt_notification_event */
Master(1)
Master&Slave is a GAP
peripheral
Master&Slave(2)
Master&Slave Master&Slave
is a GAP central is a GAP central
Slave_A(3) Slave_B(3)
DT57313V1
Step 1. One Bluetooth® LE device (called Master&Slave) is configured as central and peripheral by setting role
as GAP_PERIPHERAL_ROLE |GAP_CENTRAL_ROLE on GAP_Init() API . Let’s also assume that
this device also defines a service with a characteristic.
Step 2. Two devices (called Slave_A, Slave_B) are configured as peripheral by setting role as
GAP_PERIPHERAL_ROLE on GAP_Init() API. Both Slave_A and Slave_B define the same service
and characteristic as Master&Slave device.
Step 3. One device (called Master) is configured as central by setting role as GAP_CENTRAL_ROLE on
GAP_Init()API.
Step 4. Both Slave_A and Slave_B devices enter discovery mode by using the following APIs:
– aci_gap_set_advertising_configuration(). This API defines the advertising
configuration with the following main parameters:
◦ Discoverable_mode = GAP_MODE_GENERAL_DISCOVERABLE
◦ Advertising_Event_Properties = ADV_PROP_CONNECTABLE|
ADV_PROP_SCANNABLE|ADV_PROP_LEGACY,
◦ Primary_Advertising_Interval_Min = 0x20
◦ Primary_Advertising_Interval_Max = 0x100
– aci_gap_set_advertising_enable(). This API allows advertising to be enabled as follows:
static Advertising_Set_Parameters_t Advertising_Set_Parameters[1];
Advertising_Set_Parameters[0].Advertising_Handle = 0;
Advertising_Set_Parameters[0].Duration = 0;
Advertising_Set_Parameters[0].Max_Extended_Advertising_Events = 0;
ret = aci_gap_set_advertising_enable(ENABLE, 1,Advertising_Set_Parameters);
– aci_gap_set_advertising_data(). This API defines the advertising data with the following
parameters:
◦ Advertising_Handle = 0;
◦ Operation = ADV_COMPLETE_DATA’
◦ Advertising_Data_Length = sizeof(adv_data);
◦ Advertising_Data_Length = adv_data
◦ Where adv_data is defined as follows:
Step 5. Master&Slave device configures the scanning and connection parameters before performing a
discovery procedure, by using the following APIs:
– aci_gap_set_scan_configuration(). This API defines the scanning parameters:
◦ Filter_Duplicates: 0x0;
◦ Scanning_Filter_Policy: 0x0 (accept all);
◦ Scanning_PHY: LE_1M_PHY (1 Mbps PHY);
◦ Scan_Type: PASSIVE_SCAN;
◦ Scan_Interval: 0x10;Scan_Window: 0x10
– aci_gap_set_connection_configuration(). This API defines the connection
parameters:
◦ Initiating_PHY = LE_1M_PHY (1 Mbps PHY);
◦ Conn_Interval_Min = 0x6c;
◦ Conn_Interval_Max= 0x6c;
◦ Conn_Latency = 0;
◦ Supervision_Timeout = 0xc80;
◦ Minimum_CE_Length = 0x000c;
◦ Maximum_CE_Length = 0x000c
Step 6. Master&Slave device performs a discovery procedure in order to discover the peripheral devices
Slave_A and Slave_B:
The general discovery procedure is started by calling the API
aci_gap_start_procedure() with the parameters:
– Procedure_Code = 0x01 /* GENERAL_DISCOVERY */
– PHYs=LE_1M_PHY /* 1 Mbps PHY */
The two devices are discovered through the advertising report events notified with the
(hci_le_extendede_advertising_report_event() event callback.
Once the two devices are discovered, Master&Slave device starts two connection procedures (as
central) to connect, respectively, to Slave_A and Slave_B devices:
/*
Connect to Slave_A:Slave_A address type and address have been found during the discovery
procedure through the Advertising Report events.
*/
ret = aci_gap_create_connection(LE_1M_PHY, ”Slave_A address type”, ”Slave_A address”);
/* Connect to Slave_B:Slave_Baddress type and address have been found during the discovery pr
ocedure through the Advertising Report events.
*/
ret = aci_gap_create_connection(LE_1M_PHY, ”Slave_B address type”, ”Slave_B address”);
Step 7. Once connected, Master&Slave device enables the characteristics notification, on both of them, using
the aci_gatt_clt_write API. Slave_A and Slave_B devices start the characteristic notification by
using the the aci_gatt_srv_notify API.
Step 8. At this stage, Master&Slave device enters discovery mode (acting as peripheral). During initialization
sequence, defines the advertising configuration data and advertising data with local name 'Test' =
[0x08,0x74,0x65,0x73,0x74]. Master&Slave enters in discovery mode by enabling advertising as
follows:
aci_gap_set_advertising_enable(ENABLE, 1, Advertising_Set_Parameters);
Since Master&Slave device also acts as a central device, it receives the notification event related to the
characteristic values notified from, respectively, Slave_A and Slave_B devices.
Step 9. Once Master&Slave device enters discovery mode, it also waits for the connection request coming
from the other Bluetooth® LE device (called Master) configured as GAP central. Master device starts
discovery procedure to discover the Master&Slave device after configuring the scan parameters by
using the aci_gap_set_scan_configuration()API).
The general discovery procedure is started as follows:
ret = aci_gap_start_procedure(Procedure_Code = 0x01,PHYs = 0x01, Duration = 0; Perio
d=0);
Step 10. Once the Master&Slave device is discovered, Master device starts a connection procedure to connect
to it (after configuring the scan parameters using the: aci_gap_set_scan_configuration()
API).
/* Master device connects to Master&Slave device: Master&Slave address type and addr
ess have been found during the discovery procedure through the Advertising Report ev
ents */
ret= aci_gap_create_connection(Initiating_PHY = 0x01, Peer_Address_Type= ”Master&Sl
ave address type”,Peer_Address=” Master&Slave address");
Master&Slave device is discovered through the advertising report events notified with the
hci_le_extended_advertising_report_event() event callback.
Step 11. Once connected, Master device enables the characteristic notification on Master&Slave device using
the aci_gatt_clt_write API.
Step 12. At this stage, Master&Slave device receives the characteristic notifications from both Slave_A, Slave_B
devices, since it is a GAP central and, as GAP peripheral, it is also able to notify these characteristic
values to the Master device.
Host-based privacy
If controller privacy is not enabled, a resolvable private address can be resolved by using
aci_gap_resolve_private_addr(). The address is resolved if the corresponding IRK can be found among
the stored IRKs of the bonded devices. A resolvable private address may be received when Bluetooth®
Low Energy devices are in scanning, through hci_le_extended_advertising_report_event()/
hci_le_advertising_report_event(), or when a connection is established, through
hci_le_extended_connection_complete_event()/hci_le_connection_complete_event(). .
Controller-based privacy
If the resolution of addresses is enabled at link layer, a resolving list is used when a
resolvable private address is received. To add a bonded device to the resolving list, the
aci_gap_configure_white_and_resolving_list(); has to be called. This function searches for the
corresponding IRK and adds it to the resolving list.
When privacy is enabled, if a device has been added to the resolving list, its address is automatically resolved
by the link layer and reported to the application without the need to explicitly call any other function. After a
connection with a device, the hci_le_enhanced_connection_complete_event() is returned. This event
reports the identity address of the device, if it has been successfully resolved.
When scanning, the hci_le_extended_advertising_report_event() contains the identity address of the
device in advertising if that device uses a resolvable private address and its address is correctly resolved.
In that case, the reported address type is 0x02 or 0x03. If no IRK can be found that can resolve the
address, the resolvable private address is reported. If the advertiser uses directed advertisement, the resolved
private address is reported through the hci_le_extended_advertising_report_event() or through the
hci_le_direct_advertising_report_event() if it has been unmasked and the scanner filter policy is set
to 0x02 or 0x03.
Server_RX_MTU specifies the ATT_MTU value agreed between the server and client.
The supported TxOctets value is in the range [27-251] and the TxTime is provided as follows: (TxOctets +14)*8.
Once hci_le_set_data_length() API is performed after the device connection, if the connected peer device
supports LE data packet length extension feature, the following event is raised on both devices:
hci_le_data_length_change_event(uint16_t Connection_Handle,
uint16_t MaxTxOctets,
uint16_t MaxTxTime,
uint16_t MaxRxOctets,
uint16_t MaxRxTime)
This event notifies the host of a change to either the maximum link layer payload length or the maximum
time of link layer data channel PDUs in either direction (TX and RX). The values reported (MaxTxOctets,
MaxTxTime, MaxRxOctets, MaxRxTime) are the maximum values that are actually used on the connection
following the change.
Refer to the aci_gatt_srv_notify() API description for detailed information about API usage and its
parameter values.
}
}
A FlashRoutine() performs the flash write operation only if there is enough time for this operation before next
scheduled radio activity.
The following API allows PHY preferences to be set for the connection identified by the Connection_Handle.
tBleStatus hci_le_set_phy(uint16_t Connection_Handle,
uint8_t ALL_PHYS,
uint8_t TX_PHYS,
uint8_t RX_PHYS,
uint16_t PHY_options);
Refer to APIs html documentation for detailed description about APIs and related parameters.
/* Enable advertising */
ret = aci_gap_set_advertising_enable(ENABLE, 1, Advertising_Set_Parameters);
In system-on-chip (SoC) mode the buffer pointer is provided by the application and
transferred to the controller by the ll_set_periodic_advertising_data_ptr and freed by the
aci_hal_adv_scan_resp_data_update_event.
In network mode the buffer shall be managed at DTM level both for the standard and GAP level commands:
aci_gap_set_periodic_advertising_configuration();
aci_gap_set_periodic_advertising_enable();
aci_gap_set_periodic_advertising_data();
aci_gap_set_periodic_advertising_data_nwk().
Note: Refer to Bluetooth® Low Energy APIs html documentation for detailed commands description.
aci_gap_set_periodic_advertising_receive_enable();
aci_gap_add_device_to_periodic_advertiser_list();
aci_gap_remove_device_from_periodic_advertiser_list();
aci_gap_clear_periodic_advertiser_list();
aci_gap_read_periodic_advertiser_list_size();
aci_gap_set_periodic_advertising_sync_transfer_parameters();
aci_gap_set_default_periodic_advertising_sync_transfer_parameters().
Note: Refer to Bluetooth® Low Energy APIs html documentation for detailed commands description.
Events
The events involved on this mode are the following:
hci_le_periodic_advertising_sync_established_event()
hci_le_periodic_advertising_report_event()
hci_le_periodic_advertising_sync_lost_event()
hci_le_periodic_advertising_sync_transfer_received_event().
/* Read the current and maximum transmit power levels of the local Controller on a connection */
tBleStatus hci_le_enhanced_read_transmit_power_level(uint16_t Connection_Handle,
uint8_tPHY,
int8_t*Current_Transmit_Power_Level,
int8_t *Max_Transmit_Power_Level);
/* Read the transmit power level used by the remote Controller on a connection*/
tBleStatus hci_le_read_remote_transmit_power_level(uint16_t Connection_Handle,
uint8_t PHY);
/* Set the path loss threshold reporting parameters for a connection */
tBleStatus hci_le_set_path_loss_reporting_parameters(uint16_t Connection_Handle,
uint8_t High_Threshold,
uint8_t High_Hysteresis,
uint8_t Low_Threshold,
uint8_t Low_Hysteresis,
uint16_t Min_Time_Spent);
/* Enable or disable path loss reporting for a connection */
tBleStatus hci_le_set_path_loss_reporting_enable(uint16_t Connection_Handle,
uint8_t Enable);
/* Enable or disable the reporting of transmit power level changes in the
local and remote Controllers for a connection */
tBleStatus hci_le_set_transmit_power_reporting_enable(uint16_t Connection_Handle,
uint8_t Local_Enable,
uint8_t Remote_Enable);
/* Enable or disable the LE Power Control feature and procedure for a given PHY on the later established connections
*/
tBleStatus aci_hal_set_le_power_control(uint8_t Enable,
uint8_t PHY,
int8_t RSSI_Target,
uint8_t RSSI_Hysteresis,
int8_t Initial_TX_Power,
uint8_t RSSI_Filtering_Coefficient);
/* Report a path loss threshold crossing on a connection */
void hci_le_path_loss_threshold_event(uint16_t Connection_Handle,
uint8_t Current_Path_Loss,
uint8_t Zone_Entered);
/* Report the transmit power level on a connection */
void hci_le_transmit_power_reporting_event(uint8_t Status,
uint16_t Connection_Handle,
uint8_t Reason,
uint8_t PHY,
int8_t Transmit_Power_Level,
uint8_t Transmit_Power_Level_Flag,
int8_t Delta);
Note: Refer to Bluetooth® Low Energy APIs html documentation for a detailed description of commands and events.
Output
Command/event and parameters
parameter
Refer to the Bluetooth® Low Energy v3.1a or later commands and event documentation for a detailed description.
Direction finding features are supported only on the BlueNRG-LPS device (not on the BlueNRG-LP devices).
Bluetooth® specifications allow the direction-finding enabled packets to be used in both connectionless
and connection-oriented communication, as described on next Section 4.19.1 Connectionless scenario and
Section 4.19.2 Connection-oriented scenario.
Note: • To receive the Connectionless IQ Report events on the scanner, they must be enabled also through the
hci_le_set_event_mask() command.
• Some other events, which may be needed in some of the steps on the scanner, are not enabled by
default. It is suggested to enable at least:
– LE Extended Advertising Report event
– LE Periodic Advertising Sync Established event
– LE Periodic Advertising Report event
– LE Periodic Advertising Sync Lost event
• The IQ samples algorithms are not defined by Bluetooth Core specifications
• Reception of IQ reports can be disabled with
hci_le_set_connectionless_iq_sampling_enable() when no longer needed.
Refer to the APIs and events html documentation for a detailed description of the APIs and the related
parameters.
Command name
aci_gatt_clt_read_multiple_var_len_char_value
aci_gatt_srv_multi_notify
aci_gatt_eatt_clt_confirm_indication
aci_gatt_eatt_clt_disc_all_char_desc
aci_gatt_eatt_clt_disc_all_char_of_service
aci_gatt_eatt_clt_disc_all_primary_services
aci_gatt_eatt_clt_disc_char_by_uuid
aci_gatt_eatt_clt_disc_primary_service_by_uuid
aci_gatt_eatt_clt_execute_write_req
aci_gatt_eatt_clt_find_included_services
aci_gatt_eatt_clt_prepare_write_req
aci_gatt_eatt_clt_read
aci_gatt_eatt_clt_read_long
aci_gatt_eatt_clt_read_multiple_char_value
aci_gatt_eatt_clt_read_multiple_var_len_char_value
aci_gatt_eatt_clt_read_using_char_uuid
aci_gatt_eatt_clt_write
aci_gatt_eatt_clt_write_char_reliable
aci_gatt_eatt_clt_write_long
aci_gatt_eatt_clt_write_without_resp
aci_gatt_eatt_srv_init
aci_gatt_eatt_srv_multi_notify
aci_gatt_eatt_srv_notify
aci_gatt_eatt_srv_resp
Event name
aci_att_clt_read_multiple_var_len_resp_event
aci_eatt_clt_exec_write_resp_event
aci_eatt_clt_find_by_type_value_resp_event
aci_eatt_clt_find_info_resp_event
aci_eatt_clt_prepare_write_resp_event
aci_eatt_clt_prepare_write_resp_event
aci_eatt_clt_read_blob_resp_event
aci_eatt_clt_read_by_group_type_resp_event
aci_eatt_clt_read_by_type_resp_event
aci_eatt_clt_read_multiple_resp_event
aci_eatt_clt_read_multiple_var_len_resp_event
aci_eatt_clt_read_resp_event
aci_eatt_srv_exec_write_req_event
aci_eatt_srv_prepare_write_req_event
aci_gatt_eatt_clt_disc_read_char_by_uuid_resp_event
aci_gatt_eatt_clt_error_resp_event
aci_gatt_eatt_clt_indication_event
aci_gatt_eatt_clt_notification_event
aci_gatt_eatt_clt_proc_complete_event
aci_gatt_eatt_proc_timeout_event
aci_gatt_eatt_srv_attribute_modified_event
aci_gatt_eatt_srv_confirmation_event
aci_gatt_eatt_srv_read_event
aci_gatt_eatt_srv_write_event
4.23 New Bluetooth® Low Energy stack v3.2 or later HCI APIs and events
Table 77. New HCI commands related to some link layer controller features
Table 78. New HCI events related to some link layer controller features
This section aims to provide the user the fundamentals of the new Bluetooth® LE stack v3.x time scheduler.
The goal is to help the user to set up connections, scanning, and advertising procedures in multilink scenarios
so that the measured performance (for example, throughput, latency, robustness against connection drops) is as
much coherent as possible with the expected one.
Advantages/disadvantages with respect to the `Bluetooth® LE stack v2.x time scheduler are also be described.
All link layer (LL) radio tasks (that is, connection, advertising, or scanning) can be represented in a time base
through sequences of slots (that is time windows where associated events occur).
Each slot occurrence of a radio task can be represented through:
• an anchor, that is the exact time the slot is expected to start;
• a length, that is the expected time duration of the slot.
Radio tasks can be classified as:
• periodic, where slots are repeated at fixed time intervals (for example, connect events)
• asynchronous, where:
– Slots are NOT repeated (usually referred as one-shot slots)
– Slots are repeated but NOT at fixed time intervals (for example, advertising events)
Anchor
Event #1 Event #2
DT57314V1
Interval
Since multiple radio tasks can be concurrently active on a device, the associated slots can overlap in time. In the
following, a slot overlap is referred as a collision.
In case of collision, only one of the colliding slots is granted access to the air and is referred as a scheduled slot.
Colliding slots that do not have access to the air is referred as skipped slots.
The time scheduler is an SW module that provides the following functionalities:
• At the time, a new radio task is started by the host, it computes the very first anchor of the associated slot
sequence (that is, the exact time the first Rx/Tx event associated, with the radio task, is expected to “grab
the air”)
• At the time a slot ends, according to the rules specified by the Bluetooth® standard (that is, in case of a
master connection event, at the time, the CE_Length is exceeded):
1. it computes the next anchor (if any) of the associated radio task.
2. In case of multiple radio tasks currently active on the device, it computes, per each radio task, the
next anchor (if any) that is, in the future, with respect to the current time.
3. In case of multiple radio tasks currently active on the device, it selects which radio task has to be
served next, based on a chronological order.
4. In case the first slot (in chronological order) collides with other slots, it schedules one of the colliding
slots based on a priority mechanism.
Number of radio tasks
When a Bluetooth® activity is started, for example a new advertising set or a connection, usually a single radio
task is needed. However, there are some Bluetooth® activities, which need more than one radio task.
In particular, the number of radio tasks for each advertising set is two if extended advertising
PDUs are used. Moreover, if an extended scan is enabled through the modular configuration
(CONTROLLER_EXT_ADV_SCAN_ENABLED), the scan requires a number of slots equal to 1 +
NumOfAuxScanSlots, which is a parameter of the initialization structure passed to BLE_STACK_Init() function.
The NumOfAuxScanSlots is equal to the number of radio tasks that can be allocated simultaneously to scan
on the secondary advertising physical channel. Once a packet on the primary advertising physical channel is
received, which points to a packet on the secondary advertising physical channel, a radio task is allocated and,
if served, it triggers a scan on the secondary advertising physical channel. In a presence of several advertisers
using extended advertising events, the higher the number of auxiliary scan slots is, the higher the chance to
receive extended advertising events.
The total number of radio tasks that can be allocated is specified through NumOfLinks field of the initialization
structure BLE_STACK_InitTypeDef. In addition to this constraint, the number of simultaneous periodic advertising
synchronization slots is limited by the NumOfSyncSlots field.
x1 LEN1
x0 LEN0
0 1 0 0 0 1 0 0 0 1
DT57315V1
Anchor Period
Time
Here is a list of the main advantages of the Bluetooth® Low Energy stack v2.x time scheduler:
1. The scheduler forces the application to choose suitable parameters for new slots in order to avoid collisions
with existing slots. If new master slots cannot be allocated because they would collide with other slots, the
scheduler just returns an error. In this condition, where no collisions can occur between master slots, the
maximum throughput is guaranteed.
2. Collisions can occur only with slave connect slots. Here the priority mechanism used by the time scheduler
is a simple round-robin approach
Here is a list of the main limitations of the Bluetooth® Low Energy stack v2.x time scheduler:
1. Since the sum of the allocated master radio task lengths must fit within the anchor period, there is a limit to
the number of concurrent master radio tasks.
2. Since new master radio tasks must have an interval that is a multiple integer of the existing anchor period,
the user has a very reduced flexibility in choosing the periodicity of a new link layer slot (that is, connect,
advertising, and scan intervals).
3. Once reduced (due to the start of a new radio task), the anchor period cannot be increased anymore, thus
resulting in an additional limitation to the number of concurrent radio tasks.
4. Asynchronous radio tasks are not compatible with the anchor period approach because they are not
periodic.
Almost all the link layer features introduced by the Bluetooth 5.0 standard (for example, advertising extensions)
are characterized by asynchronous events that are not compatible with the anchor period approach of the
Bluetooth® Low Energy stack v2.x time scheduler; this is the main reason that led to the implementation of a new
time scheduler.
The probability of having multi slots collisions is also proportional to the number of concurrent asynchronous radio
tasks, which makes the simple round-robin mechanism of the Bluetooth® Low Energy stack v2.x time scheduler
no more appropriate to guarantee adequate performance.
5.2 The new Bluetooth® Low Energy stack v3.x time scheduler
To support to all new link layer features introduced by the Bluetooth® 5.0 standard as well as to allow the user to
implement application scenarios with different QoS requirements, a new Bluetooth® Low Energy stack v3.x time
scheduler removes the main constraints of the previous implementation.
In the Bluetooth® Low Energy stack v3.x time scheduler, all radio tasks are treated as they were asynchronous,
that is they are excluded from the anchor period representation.
One significant advantage with respect to the Bluetooth® Low Energy stack v2.x time scheduler is that an LL
activity, started by the host, is never rejected because of its periodicity (that is, connection, advertising, or scan
interval) or event duration (that is, connection CE_Length, scan window, etc.).
The main drawback of this new approach is that master task slots (that is, Bluetooth® connection, advertising, and
scanning events) can now potentially collide each other. For this reason, the users could occasionally experience
reduced performances (for example, reduced throughput). Performance can be increased if certain guidelines are
followed (refer to Section 5.4 Guidelines for the users).
LENGTH1 CONN1
INTERVAL1
Start_CONN2
2) CONN1 CONN1 CONN1
SELECTED TIME
DT57316V1
GUARD_TIME
BEST ANCHOR
1. Choose the same connection interval (Conn_Interval) for all the master connections such that it can contain the
sum of the connection event lengths (CE_Length) of all the master connection slots plus a guard time that is:
CE_Lengtℎi
Conn_Interval > ∑i + GUARD (2)
2
Where: GUARD = max_num_of_radio_tasks/25
Note: • CE_Lengthi is the CE_Length of the i-th connection
• CE_Length is in 0.625 ms time units
• Conn_Interval is in 1.25 ms time units
• GUARD is in 1.25 ms time units
• CE_Length(i)/2 is rounded to the next integer value
• GUARD is the least integer greater than or equal to the maximum number of supported radio tasks
divided by 25. In other words, it is:
– 1 if max_num_of_radio_tasks ≤ 25;
– 2 if 25 < max_num_of_radio_tasks ≤ 50, and so on.
For the sake of simplicity, the following assumptions have been made:
• Minimum_CE_Length = Maximum_CE_Length = CE_Length
• Conn_Interval_Min = Conn_Interval_Max = Conn_Interval
• If Minimum_CE_Length ≠ Maximum_CE_Length, only Max_CE_Length is used by the prescheduler.
• If Conn_Interval_Min ≠ Conn_Interval_Max, only Conn_Interval_Min is used by the prescheduler.
• Besides, consider that the actual value of CE_Length, used by the stack, can differ from the one passed
by the application: the minimum value used by the stack, depending on the library modular configuration, is
reported in the table below.
CONTROLLER_DATA_LENGTH_-
CONTROLLER_2M_CODED_PHY-_ENABLED Minimum CE_Length
EXTENSION_ENABLED
- - 3
X - 8
- X 10
X X 56
The maximum length of an LL PDU that can be sent or received is established during
the connection by using the data length update procedure. The LL payload length can be
set either through the hci_le_write_suggested_default_data_length() command or through
hci_le_set_data_length() command. The length of an LL PDU payload is 27 octets by default and can
be increased up to 251 octets if data length extension feature is supported (in Bluetooth® LE stack 3.x this is done
through the CONTROLLER_DATA_LENGTH_EXTENSION_ENABLED macro).
The duration of an LL PDU is reported in the table below and it includes transmission of the MIC (message
integrity check) field. Payload_length does not include MIC.
A connection event is made by several packets exchanged between master and slave. The CE length can be
calculated with this formula:
CE_Length = num_packets_CE × TX_PDU_Duration + RX_PDU_Duration + 2 × T (4)
_IFS /625
Where:
• TX_PDU_Duration is the value in microseconds needed to transmit the data PDU (see Table 81). If this
value is not known, the maximum possible value should be used.
• RX_PDU_Duration is the value in microseconds to receive a data PDU (see Table 81). If this value is not
known, the maximum possible value should be used.
• T_IFS is equal to 150 µs.
• CE_Length is in a unit of 625 µs and it is rounded to the next integer value.
If the resulting value of the CE length is greater than the connection interval or, more generally, the condition (2) is
not satisfied, the connection interval needs to be increased and a number of packets per connection event needs
to be re-calculated. If the connection interval cannot be increased, the desired throughput cannot be reached.
Example:
It is requested to have 100 kbps of unidirectional throughput (LL data throughput), with a connection interval of
50 ms. If data length extension is enabled (LL payload up to 251 octets), data is sent only in one direction (empty
packet on RX), and PHY is LE_1M:
num_packets_CE = (100 x 50)/(251 x 8) = 3
CE_Length = 3 x (2120 + 80 + 300)/625 = 12 -> CE_Length_ms = 7.5 ms
The CE length is less than the connection interval, so no need to increase.
3. The Conn_Interval should be chosen in order to be less than the maximum latency required by all the
connections.
In case a master connection can tolerate a bigger latency than Conn_Interval, the user may choose, for that
connection, a connection interval that is an integer multiple of Conn_Interval.
• Application 3:
– Throughput = 30 kbps, bidirectional
– Latency = 200 ms
The maximum connection interval value that guarantees the required latency to all master connections is equal to
100 ms:
Connection_Interval ≤ 100ms (5)
Now, we have to verify whether 100 ms of connection interval is also appropriate to contain all master
connections CE_Lengths.
If data length extension is not enabled and PHY is 1 Mbps.
• Application 1 has to transmit (10 x 100)/(27 x 8) = 5 data PDUs (27 bytes each) per each connection event
--> CE_Lenght1 = 5 x ((27+14)x8 + (27+14)x8 + 2x150)/625 = 8, (that is, 5 ms)
• Application 2 has to transmit (20 x 100)/(27 x 8) = 10 data PDUs (27 bytes each) per each connection
event --> CE_Lenght2 = 10 x ((27+14)x8 + (27+14)x8 + 2x150)/625 = 16, (that is, 10 ms)
• Application 3 has to transmit (30 x 100)/(27 x 8) = 14 data PDUs (27 bytes each) per each connection
event --> CE_Lenght3 = 14 x ((27+14)x8 + (27+14)x8 + 2x150)/625 = 22, (that is, 13.75 ms)
The minimum connection interval that fits all connections CE_Lengths is:
Conn_Interval_Min_allowed = SUM(Max_CE_Length(i)/2 + GUARD) = (4 + 1) + (8 + 1) + (11 + 1) = 26 --> 32.5
ms
Where GUARD = 1, assuming the maximum number of radio tasks supported by the device is not greater than
25.
Since Conn_Interval_Min_allowed ≤ 100 ms, a connection interval of 100 ms can be used for all the master
connections to guarantee the appropriate performance.
With the ISR robustness mechanism, the firmware can detect the situation where the ISR is served too late with
respect to the associated radio event. Whenever this specific condition is detected by the firmware:
1. The associated back-to-back radio event is skipped
2. The Bluetooth® Low Energy stack v3.x time scheduler is called that selects the next radio task to be served
3. A hardware error event is pushed to the application to inform that something wrong happened.
The application is not expected to handle the hardware error event in a specific way but, upon receiving it, the
user gets an indication that the application design was not at 100% correct in terms of masking time of the radio
interrupt.
6 References
Name Title/description
This section lists the standard acronyms and abbreviations used throughout the document.
Term Meaning
Term Meaning
Revision history
Table 84. Document revision history
Contents
1 General information . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2
2 Bluetooth® Low Energy technology . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
2.1 Bluetooth® LE stack architecture. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
2.2 Physical layer. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4
2.2.1 LE 2M and LE Coded physical layers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
2.2.2 LE 2M PHY . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
2.2.3 LE Coded PHY . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
2.3 Link layer (LL) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
2.3.1 Bluetooth® Low Energy packet . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
2.3.2 Extended advertising. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10
2.3.3 Advertising sets. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12
2.3.4 Advertising state . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12
2.3.5 Scanning state . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13
2.3.6 Connection state . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13
2.3.7 Periodic advertising and periodic advertising sync transfer . . . . . . . . . . . . . . . . . . . . . . . . 14
2.3.8 Randomized advertising . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14
2.3.9 Bluetooth® Low Energy power control . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15
2.4 Host controller interface (HCI) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15
2.5 Logical link control and adaptation layer protocol (L2CAP) . . . . . . . . . . . . . . . . . . . . . . . . . . . 15
2.5.1 LE L2CAP connection-oriented channels . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15
2.6 Attribute protocol (ATT) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15
2.7 Security manager (SM). . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16
2.8 Privacy . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19
2.8.1 The device filtering . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20
2.9 Generic attribute profile (GATT) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20
2.9.1 Characteristic attribute type. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20
2.9.2 Characteristic descriptor type . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22
2.9.3 Service attribute type . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22
2.9.4 GATT procedures . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22
2.9.5 GATT caching . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23
2.10 Generic access profile (GAP) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24
2.11 Direction finding. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27
2.11.1 Direction finding with angle of arrival (AoA). . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27
2.11.2 Direction finding with angle of departure (AoD) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28
2.11.3 In-phase and quadrature (IQ) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29
List of tables
Table 1. Bluetooth® Low Energy LE RF channel types and frequencies. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4
Table 2. LE PHY key parameters . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
Table 3. PDU advertising header . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
Table 4. Connection request timing intervals . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13
Table 5. Attribute example. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15
Table 6. Attribute protocol messages . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16
Table 7. Combination of input/output capabilities on a Bluetooth® LE device . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17
Table 8. Methods used to calculate the temporary key (TK) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17
Table 9. Mapping of IO capabilities to possible key generation methods . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18
Table 10. Characteristic declaration . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21
Table 11. Characteristic value . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21
Table 12. Service declaration . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22
Table 13. Include declaration . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22
Table 14. Discovery procedures and related response events . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23
Table 15. Client-initiated procedures and related response events . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23
Table 16. Server-initiated procedures and related response events . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23
Table 17. GAP roles . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25
Table 18. GAP broadcaster mode . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25
Table 19. GAP discoverable modes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25
Table 20. GAP connectable modes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26
Table 21. GAP bondable modes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26
Table 22. GAP observer procedure . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26
Table 23. GAP discovery procedures . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26
Table 24. GAP connection procedures . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26
Table 25. GAP bonding procedures . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27
Table 26. Bluetooth® Low Energy stack library framework interface (BlueNRG-LP, BlueNRG-LPS STSW-BNRGLP-DK) . . . 35
Table 27. Modular configurations option combination examples . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37
Table 28. Bluetooth® Low Energy application stack library framework interface (BlueNRG-LP, BlueNRG-LPS STSW-BNRGLP-
DK) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39
Table 29. Bluetooth® Low Energy stack v3.x initialization parameters . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 40
Table 30. Application configuration preprocessor options . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 42
Table 31. User application defines for Bluetooth® Low Energy device roles . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 44
Table 32. GATT, GAP service handles . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 46
Table 33. GATT, GAP characteristic handles . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 46
Table 34. aci_gap_init() role parameter values . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 47
Table 35. TX power level with En_High_Power = 0 (SMPS voltage @ 1.4 Volts) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 49
Table 36. TX power level with En_High_Power = 1 (SMPS voltage @ 1.9 Volts) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 50
Table 37. GATT server database APIs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 56
Table 38. Example database . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 57
Table 39. aci_gatt_srv_notify parameters . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 59
Table 40. aci_gatt_srv_read_event parameters . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 60
Table 41. aci_gatt_srv_write_event parameters . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 60
Table 42. aci_att_srv_prepare_write_req_event parameters . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 60
Table 43. aci_att_srv_exec_write_req_event parameters . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 61
Table 44. aci_gatt_srv_resp parameters . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 61
Table 45. ATT_pwrq_init parameters . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 63
Table 46. ATT_pwrq_flush parameter . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 63
Table 47. ATT_pwrq_read parameters . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 64
Table 48. ATT_pwrq_pop parameters . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 64
Table 49. ATT_pwrq_push parameters . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 64
Table 50. GATT client APIs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 65
Table 51. aci_gap_set_advertising_configuration() API : discoverable mode and advertising type selection . . . . . . . . . . . . 68
List of figures
Figure 1. Bluetooth® Low Energy technology enabled coin cell battery devices. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
Figure 2. Bluetooth® LE stack architecture. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4
Figure 3. LL state machine . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
Figure 4. 2MB . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8
Figure 5. Coded PHY . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8
Figure 6. Advertising physical channel PDU . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8
Figure 7. Data physical channel PDUs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10
Figure 8. Bluetooth® LE 5.x extended advertising . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
Figure 9. Advertising packet chain . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
Figure 10. Advertising packet with AD type flags . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12
Figure 11. Example of characteristic definition . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21
Figure 12. Angle of arrival (AoA) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28
Figure 13. Angle of departure (AoD) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29
Figure 14. Client and server profiles . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32
Figure 15. Bluetooth® Low Energy stack v3.x architecture . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33
Figure 16. Bluetooth® LE stack reference application . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34
Figure 17. MAC address storage . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 48
Figure 18. Bluetooth® LE simultaneous master and slave scenario . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 84
Figure 19. Example of periodic radio task . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 104
Figure 20. Example of two radio tasks allocation in an anchor period . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 105
Figure 21. Example of prescheduler operation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 107