You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
328 lines
12 KiB
328 lines
12 KiB
.. _bluetooth_le_host: |
|
|
|
LE Host |
|
####### |
|
|
|
The Bluetooth Host implements all the higher-level protocols and |
|
profiles, and most importantly, provides a high-level API for |
|
applications. The following diagram depicts the main protocol & profile |
|
layers of the host. |
|
|
|
.. figure:: img/ble_host_layers.png |
|
:align: center |
|
:alt: Bluetooth Host protocol & profile layers |
|
|
|
Bluetooth Host protocol & profile layers. |
|
|
|
Lowest down in the host stack sits a so-called HCI driver, which is |
|
responsible for abstracting away the details of the HCI transport. It |
|
provides a basic API for delivering data from the controller to the |
|
host, and vice-versa. |
|
|
|
Perhaps the most important block above the HCI handling is the Generic |
|
Access Profile (GAP). GAP simplifies Bluetooth LE access by defining |
|
four distinct roles of Bluetooth usage: |
|
|
|
* Connection-oriented roles |
|
|
|
* Peripheral (e.g. a smart sensor, often with a limited user interface) |
|
|
|
* Central (typically a mobile phone or a PC) |
|
|
|
* Connection-less roles |
|
|
|
* Broadcaster (sending out Bluetooth LE advertisements, e.g. a smart beacon) |
|
|
|
* Observer (scanning for Bluetooth LE advertisements) |
|
|
|
Each role comes with its own build-time configuration option: |
|
:kconfig:option:`CONFIG_BT_PERIPHERAL`, :kconfig:option:`CONFIG_BT_CENTRAL`, |
|
:kconfig:option:`CONFIG_BT_BROADCASTER` & :kconfig:option:`CONFIG_BT_OBSERVER`. Of the |
|
connection-oriented roles central implicitly enables observer role, and |
|
peripheral implicitly enables broadcaster role. Usually the first step |
|
when creating an application is to decide which roles are needed and go |
|
from there. Bluetooth Mesh is a slightly special case, requiring at |
|
least the observer and broadcaster roles, and possibly also the |
|
Peripheral role. This will be described in more detail in a later |
|
section. |
|
|
|
Peripheral role |
|
=============== |
|
|
|
Most Zephyr-based Bluetooth LE devices will most likely be peripheral-role |
|
devices. This means that they perform connectable advertising and expose |
|
one or more GATT services. After registering services using the |
|
:c:func:`bt_gatt_service_register` API the application will typically |
|
start connectable advertising using the :c:func:`bt_le_adv_start` API. |
|
|
|
There are several peripheral sample applications available in the tree, |
|
such as :zephyr_file:`samples/bluetooth/peripheral_hr`. |
|
|
|
Central role |
|
============ |
|
|
|
Central role may not be as common for Zephyr-based devices as peripheral |
|
role, but it is still a plausible one and equally well supported in |
|
Zephyr. Rather than accepting connections from other devices a central |
|
role device will scan for available peripheral device and choose one to |
|
connect to. Once connected, a central will typically act as a GATT |
|
client, first performing discovery of available services and then |
|
accessing one or more supported services. |
|
|
|
To initially discover a device to connect to the application will likely |
|
use the :c:func:`bt_le_scan_start` API, wait for an appropriate device |
|
to be found (using the scan callback), stop scanning using |
|
:c:func:`bt_le_scan_stop` and then connect to the device using |
|
:c:func:`bt_conn_le_create`. |
|
|
|
There are some sample applications for the central role available in the |
|
tree, such as :zephyr_file:`samples/bluetooth/central_hr`. |
|
|
|
Observer role |
|
============= |
|
|
|
An observer role device will use the :c:func:`bt_le_scan_start` API to |
|
scan for device, but it will not connect to any of them. Instead it will |
|
simply utilize the advertising data of found devices, combining it |
|
optionally with the received signal strength (RSSI). |
|
|
|
Broadcaster role |
|
================ |
|
|
|
A broadcaster role device will use the :c:func:`bt_le_adv_start` API to |
|
advertise specific advertising data, but the type of advertising will be |
|
non-connectable, i.e. other device will not be able to connect to it. |
|
|
|
Connections |
|
=========== |
|
|
|
Connection handling and the related APIs can be found in the |
|
:ref:`Connection Management <bluetooth_connection_mgmt>` section. |
|
|
|
Security |
|
======== |
|
|
|
To achieve a secure relationship between two Bluetooth devices a process |
|
called pairing is used. This process can either be triggered implicitly |
|
through the security properties of GATT services, or explicitly using |
|
the :c:func:`bt_conn_set_security` API on a connection object. |
|
|
|
To achieve a higher security level, and protect against |
|
Man-In-The-Middle (MITM) attacks, it is recommended to use some |
|
out-of-band channel during the pairing. If the devices have a sufficient |
|
user interface this "channel" is the user itself. The capabilities of |
|
the device are registered using the :c:func:`bt_conn_auth_cb_register` |
|
API. The :c:struct:`bt_conn_auth_cb` struct that's passed to this API has |
|
a set of optional callbacks that can be used during the pairing - if the |
|
device lacks some feature the corresponding callback may be set to NULL. |
|
For example, if the device does not have an input method but does have a |
|
display, the ``passkey_entry`` and ``passkey_confirm`` callbacks would |
|
be set to NULL, but the ``passkey_display`` would be set to a callback |
|
capable of displaying a passkey to the user. |
|
|
|
Depending on the local and remote security requirements & capabilities, |
|
there are four possible security levels that can be reached: |
|
|
|
:c:enumerator:`BT_SECURITY_L1` |
|
No encryption and no authentication. |
|
|
|
:c:enumerator:`BT_SECURITY_L2` |
|
Encryption but no authentication (no MITM protection). |
|
|
|
:c:enumerator:`BT_SECURITY_L3` |
|
Encryption and authentication using the legacy pairing method |
|
from Bluetooth 4.0 and 4.1. |
|
|
|
:c:enumerator:`BT_SECURITY_L4` |
|
Encryption and authentication using the LE Secure Connections |
|
feature available since Bluetooth 4.2. |
|
|
|
.. note:: |
|
Mesh has its own security solution through a process called |
|
provisioning. It follows a similar procedure as pairing, but is done |
|
using separate mesh-specific APIs. |
|
|
|
L2CAP |
|
===== |
|
|
|
L2CAP stands for the Logical Link Control and Adaptation Protocol. It is |
|
a common layer for all communication over Bluetooth connections, however |
|
an application comes in direct contact with it only when using it in the |
|
so-called Connection-oriented Channels (CoC) mode. More information on |
|
this can be found in the :ref:`L2CAP API section <bt_l2cap>`. |
|
|
|
Terminology |
|
----------- |
|
|
|
The definitions are from the Core Specification version 5.4, volume 3, part A |
|
1.4. |
|
|
|
.. list-table:: |
|
:header-rows: 1 |
|
|
|
* - Term |
|
- Description |
|
|
|
* - Upper layer |
|
- Layer above L2CAP, it exchanges data in form of SDUs. It may be an |
|
application or a higher level protocol. |
|
|
|
* - Lower layer |
|
- Layer below L2CAP, it exchanges data in form of PDUs (or fragments). It is |
|
usually the HCI. |
|
|
|
* - Service Data Unit (SDU) |
|
- Packet of data that L2CAP exchanges with the upper layer. |
|
|
|
This term is relevant only in Enhanced Retransmission mode, Streaming |
|
mode, Retransmission mode and Flow Control Mode, not in Basic L2CAP mode. |
|
|
|
* - Protocol Data Unit (PDU) |
|
- Packet of data containing L2CAP data. PDUs always start with Basic L2CAP |
|
header. |
|
|
|
Types of PDUs for LE: :ref:`B-frames <bluetooth_l2cap_b_frame>` and |
|
:ref:`K-frames <bluetooth_l2cap_k_frame>`. |
|
|
|
Types of PDUs for BR/EDR: I-frames, S-frames, C-frames and G-frames. |
|
|
|
* - Maximum Transmission Unit (MTU) |
|
- Maximum size of an SDU that the upper layer is capable of accepting. |
|
|
|
* - Maximum Payload Size (MPS) |
|
- Maximum payload size that the L2CAP layer is capable of accepting. |
|
|
|
In Basic L2CAP mode, the MTU size is equal to MPS. In credit-based |
|
channels without segmentation, the MTU is MPS minus 2. |
|
|
|
* - Basic L2CAP header |
|
- Present at the beginning of each PDU. It contains two fields, the PDU |
|
length and the Channel Identifier (CID). |
|
|
|
PDU Types |
|
--------- |
|
|
|
.. _bluetooth_l2cap_b_frame: |
|
|
|
B-frame: Basic information frame |
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ |
|
|
|
PDU used in Basic L2CAP mode. It contains the payload received from the upper |
|
layer or delivered to the upper layer as its payload. |
|
|
|
.. image:: img/l2cap_b_frame.drawio.svg |
|
:align: center |
|
:width: 45% |
|
:alt: Representation of a B-frame PDU. The PDU is split into two rectangles, |
|
the first one being the L2CAP header, its size is 4 octets and its made |
|
of the PDU length and the channel ID. The second rectangle represents |
|
the information payload and its size is less or equal to MPS. |
|
|
|
.. _bluetooth_l2cap_k_frame: |
|
|
|
K-frame: Credit-based frame |
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^ |
|
|
|
PDU used in LE Credit Based Flow Control mode and Enhanced Credit Based Flow |
|
Control mode. It contains a SDU segment and additional protocol information. |
|
|
|
.. image:: img/l2cap_k_frame_1.drawio.svg |
|
:width: 45% |
|
:alt: Representation of a starting K-frame PDU. The PDU is split into three |
|
rectangles, the first one being the L2CAP header, its size is 4 octets |
|
and its made of the PDU length and the channel ID. The second rectangle |
|
represents the L2CAP SDU length, its size is 2 octets. The third |
|
rectangle represents the information payload and its size is less or |
|
equal to MPS minus 2 octets. The information payload contains the L2CAP |
|
SDU. |
|
|
|
.. image:: img/l2cap_k_frame.drawio.svg |
|
:align: right |
|
:width: 45% |
|
:alt: Representation of K-frames PDUs after the starting one. The PDU is split |
|
into two rectangles, the first one being the L2CAP header, its size is 4 |
|
octets and its made of the PDU length and the channel ID. The second |
|
rectangle represents the information payload and its size is less or |
|
equal to MPS. The information payload contains the L2CAP SDU. |
|
|
|
Relevant Kconfig |
|
---------------- |
|
|
|
.. list-table:: |
|
:header-rows: 1 |
|
|
|
* - Kconfig symbol |
|
- Description |
|
|
|
* - :kconfig:option:`CONFIG_BT_BUF_ACL_RX_SIZE` |
|
- Represents the MPS |
|
|
|
* - :kconfig:option:`CONFIG_BT_L2CAP_TX_MTU` |
|
- Represents the L2CAP MTU |
|
|
|
* - :kconfig:option:`CONFIG_BT_L2CAP_DYNAMIC_CHANNEL` |
|
- Enables LE Credit Based Flow Control and thus the stack may use |
|
:ref:`K-frame <bluetooth_l2cap_k_frame>` PDUs |
|
|
|
GATT |
|
==== |
|
|
|
The Generic Attribute Profile is the most common means of communication |
|
over LE connections. A more detailed description of this layer and the |
|
API reference can be found in the |
|
:ref:`GATT API reference section <bt_gatt>`. |
|
|
|
ATT timeout |
|
----------- |
|
|
|
If the peer device does not respond to an ATT request (such as read or write) |
|
within the ATT timeout, the host will automatically initiate a disconnect. This |
|
simplifies error handling by reducing rare failure conditions to a common |
|
disconnection, allowing developers to manage unexpected disconnects without |
|
special cases for ATT timeouts. |
|
|
|
.. image:: img/att_timeout.svg |
|
:align: center |
|
:alt: ATT timeout |
|
|
|
Mesh |
|
==== |
|
|
|
Mesh is a little bit special when it comes to the needed GAP roles. By |
|
default, mesh requires both observer and broadcaster role to be enabled. |
|
If the optional GATT Proxy feature is desired, then peripheral role |
|
should also be enabled. |
|
|
|
The API reference for mesh can be found in the |
|
:ref:`Mesh API reference section <bluetooth_mesh>`. |
|
|
|
LE Audio |
|
======== |
|
The LE audio is a set of profiles and services that utilizes GATT and |
|
Isochronous Channel to provide audio over Bluetooth Low Energy. |
|
The architecture and API references can be found in |
|
:ref:`Bluetooth Audio Architecture <bluetooth_le_audio_arch>`. |
|
|
|
|
|
.. _bluetooth-persistent-storage: |
|
|
|
Persistent storage |
|
================== |
|
|
|
The Bluetooth host stack uses the settings subsystem to implement |
|
persistent storage to flash. This requires the presence of a flash |
|
driver and a designated "storage" partition on flash. A typical set of |
|
configuration options needed will look something like the following: |
|
|
|
.. code-block:: cfg |
|
|
|
CONFIG_BT_SETTINGS=y |
|
CONFIG_FLASH=y |
|
CONFIG_FLASH_PAGE_LAYOUT=y |
|
CONFIG_FLASH_MAP=y |
|
CONFIG_NVS=y |
|
CONFIG_SETTINGS=y |
|
|
|
Once enabled, it is the responsibility of the application to call |
|
settings_load() after having initialized Bluetooth (using the |
|
:c:func:`bt_enable` API).
|
|
|