Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
bluetooth-le-overview.qdoc
Go to the documentation of this file.
1
// Copyright (C) 2017 The Qt Company Ltd.
2
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
3
4
/*!
5
\ingroup technology-apis
6
\title Bluetooth Low Energy Overview
7
\page qtbluetooth-le-overview.html
8
\brief The Qt Bluetooth Low Energy API enables communication between Bluetooth
9
Low Energy devices.
10
11
The Qt Bluetooth Low Energy API supports the peripheral/server and central/client roles.
12
It is supported on all major Qt platforms. The only exception is the missing peripheral role
13
support on Windows.
14
15
\section1 What Is Bluetooth Low Energy
16
17
Bluetooth Low Energy, also known as Bluetooth Smart, is a wireless computer
18
network technology, which was officially introduced in 2011. It works on the same
19
2.4 GHz frequency as ”classic” Bluetooth. The main difference is, as stated by its technology name,
20
low energy consumption. It provides an opportunity for Bluetooth Low Energy devices to
21
operate for months, even years, on coin-cell batteries. The technology was introduced by
22
\l {https://www.bluetooth.org/en-us/specification/adopted-specifications}{Bluetooth v4.0}.
23
Devices which support this technology are called Bluetooth Smart Ready Devices.
24
The key features of the technology are:
25
26
\list
27
\li Ultra-low peak, average and idle mode power consumption
28
\li Ability to run for years on standard, coin-cell batteries
29
\li Low cost
30
\li Multi-vendor interoperability
31
\li Enhanced range
32
\endlist
33
34
Bluetooth Low Energy uses a client-server architecture. The server (also
35
known as peripheral) offers services such as temperature or heart rate
36
and advertises them. The client (known as central
37
device) connects to the server and reads the values advertised by the server.
38
An example might be an apartment with Bluetooth Smart Ready sensors such
39
as a thermostat, humidity or pressure sensor. Those sensors are peripheral
40
devices advertising the environment values of the apartment. At the same time
41
a mobile phone or computer might connect to those sensors, retrieve their
42
values and present them as part of a larger environment control application
43
to the user.
44
45
\section1 Basic Service Structure
46
47
Bluetooth Low Energy is based on two protocols: ATT (Attribute Protocol)
48
and GATT (Generic Attribute Profile). They specify the communication layers
49
used by every Bluetooth Smart Ready device.
50
51
\section2 ATT Protocol
52
53
The basic building block of ATT is an \e attribute. Each attribute consists of
54
three elements:
55
56
\list
57
\li a value - the payload or desirable piece of information
58
\li a UUID - the type of attribute (used by GATT)
59
\li a 16-bit handle - a unique identifier for the attribute
60
\endlist
61
62
The server stores the attributes and the client uses the ATT protocol to
63
read and write values on the server.
64
65
\section2 GATT Profile
66
67
GATT defines grouping for a set of attributes by applying a meaning to predefined
68
UUIDs. The table below shows an example service exposing a heart rate
69
on a particular day. The actual values are stored inside the two characteristics:
70
71
\table
72
\header
73
\li Handle
74
\li UUID
75
\li Value
76
\li Description
77
\row
78
\li 0x0001
79
\li 0x2800
80
\li UUID 0x180D
81
\li Begin Heart Rate service
82
\row
83
\li 0x0002
84
\li 0x2803
85
\li UUID 0x2A37, Value handle: 0x0003
86
\li Characteristic of type \e {Heart Rate Measurement (HRM)}
87
\row
88
\li 0x0003
89
\li 0x2A37
90
\li 65 bpm
91
\li Heart rate value
92
\row
93
\li 0x0004
94
\li 0x2803
95
\li UUID 0x2A08, Value handle: 0x0005
96
\li Characteristic of type Date Time
97
\row
98
\li 0x0005
99
\li 0x2A08
100
\li 18/08/2014 11:00
101
\li Date and Time of the measurement
102
\row
103
\li 0x0006
104
\li 0x2800
105
\li UUID xxxxxx
106
\li Begin next service
107
\row
108
\li ...
109
\li ...
110
\li ...
111
\li ...
112
\endtable
113
114
GATT specifies that the above used UUID \c 0x2800 marks the begin of a service definition.
115
Every attribute following \c 0x2800 is part of the service until the next \c 0x2800 or the
116
end is encountered. In similar ways the well known UUID \c 0x2803 states that a characteristic
117
is to be found and each of the characteristics has a type defining the nature of the value.
118
The example above uses the UUIDs \c 0x2A08 (Date Time) and \c 0x2A37 (Heart Rate Measurement).
119
Each of the above UUIDs is defined by the \l {https://bluetooth.org}{Bluetooth Special Interest Group}.
120
and can be found in the
121
\l{https://www.bluetooth.com/specifications/assigned-numbers}{GATT specifications}. While it
122
is advisable to use pre-defined UUIDs where available it is entirely possible to use new and not
123
yet used UUIDs for characteristic and service types.
124
125
In general, each service may consist of one or more characteristics. A characteristic
126
contains data and can be further described by descriptors, which provide additional
127
information or means of manipulating the characteristic. All services, characteristics and
128
descriptors are recognized by their 128-bit UUID. Finally, it is possible to include
129
services inside of services (see picture below).
130
131
\image {peripheral-structure.png} {Structure of a BLE peripheral in Qt}
132
133
\section1 Using Qt Bluetooth Low Energy API
134
135
This section describes how to use the Bluetooth Low Energy API provided by Qt.
136
On the client side, the API permits creating connections to peripheral devices, discovering
137
their services, as well as reading and writing data stored on the device.
138
On the server side, it allows to set up services, advertise them, and get notified when the
139
client writes characteristics.
140
The example code below is taken from the \l {heartrate-game}{Heart Rate Game} and
141
\l {heartrate-server}{Heart Rate Server} examples.
142
143
\section2 Establishing a Connection
144
145
To be able to read and write the characteristics of the Bluetooth Low Energy peripheral device,
146
it is necessary to find and connect the device. This requires the peripheral device to advertise
147
its presence and services. We start the device discovery with the help of the
148
\l QBluetoothDeviceDiscoveryAgent class. We connect to its \l {QBluetoothDeviceDiscoveryAgent::deviceDiscovered()}
149
signal and start the search with \l {QBluetoothDeviceDiscoveryAgent::start()}{start()}:
150
151
\snippet heartrate-game/devicefinder.cpp devicediscovery-1
152
\snippet heartrate-game/devicefinder.cpp devicediscovery-2
153
154
Since we are only interested in Low Energy devices we filter the device type within the
155
receiving slot. The device type can be ascertained using the \l QBluetoothDeviceInfo::coreConfigurations()
156
flag. The \l {QBluetoothDeviceDiscoveryAgent::}{deviceDiscovered()} signal
157
may be emitted multiple times for the same device as more details are
158
discovered. Here we match these device discoveries so that the user only
159
sees the individual devices:
160
161
\snippet heartrate-game/devicefinder.cpp devicediscovery-3
162
\snippet heartrate-game/devicefinder.cpp devicediscovery-4
163
164
Once the address of the peripheral device is known we use the \l QLowEnergyController class.
165
This class is the entry point for all Bluetooth Low Energy development. The constructor of the class
166
accepts the remote device's \l QBluetoothAddress. Finally we set up the customary slots and
167
directly connect to the device using
168
\l {QLowEnergyController::connectToDevice()}{connectToDevice()}:
169
170
\snippet heartrate-game/devicehandler.cpp Connect-Signals-1
171
\snippet heartrate-game/devicehandler.cpp Connect-Signals-2
172
173
\section2 Service Search
174
175
The above code snippet shows how the application initiates the service discovery once the
176
connection has been established.
177
178
The \c serviceDiscovered() slot below is triggered as a result of the
179
\l {QLowEnergyController::serviceDiscovered()} signal and provides an intermittent progress report.
180
Since we are talking about the heart listener app which monitors HeartRate devices in the vicinity
181
we ignore any service that is not of type \l QBluetoothUuid::ServiceClassUuid::HeartRate.
182
183
\snippet heartrate-game/devicehandler.cpp Filter HeartRate service 1
184
185
Eventually the \l {QLowEnergyController::discoveryFinished()} signal is emitted to indicate
186
the successful completion of the service discovery. Provided a HeartRate service was found,
187
a \l QLowEnergyService instance is created to represent the service. The returned service object
188
provides the required signals for update notifications and the discovery of service details
189
is triggered using \l QLowEnergyService::discoverDetails():
190
191
\snippet heartrate-game/devicehandler.cpp Filter HeartRate service 2
192
193
During the detail search the service's \l {QLowEnergyService::state()}{state()} transitions
194
from \l {QLowEnergyService::RemoteService}{RemoteService} to
195
\l {QLowEnergyService::RemoteServiceDiscovering}{RemoteServiceDiscovering} and eventually ends with
196
\l {QLowEnergyService::RemoteServiceDiscovered}{RemoteServiceDiscovered}:
197
198
\snippet heartrate-game/devicehandler.cpp Find HRM characteristic
199
200
\section2 Interaction with the Peripheral Device
201
202
In the code example above, the desired characteristic is of type
203
\l {QBluetoothUuid::CharacteristicType::HeartRateMeasurement}{HeartRateMeasurement}. Since the application measures
204
the heart rate changes, it must enable change notifications for the characteristic.
205
Note that not all characteristics provide change notifications. Since the HeartRate characteristic
206
has been standardized it is possible to assume that notifications can be received. Ultimately
207
\l QLowEnergyCharacteristic::properties() must have the \l {QLowEnergyCharacteristic::Notify} flag
208
set and a descriptor of type \l {QBluetoothUuid::DescriptorType::ClientCharacteristicConfiguration} must exist to confirm
209
the availability of an appropriate notification.
210
211
Finally, we process the value of the HeartRate characteristic, as per Bluetooth Low Energy standard:
212
213
\snippet heartrate-game/devicehandler.cpp Reading value
214
215
In general a characteristic value is a series of bytes. The precise interpretation of
216
those bytes depends on the characteristic type and value structure.
217
A significant number has been standardized by the
218
\l {https://developer.bluetooth.org/gatt/services/Pages/ServicesHome.aspx}{Bluetooth SIG} whereas others
219
may follow a custom protocol. The above code snippet demonstrates how to the read the standardized
220
HeartRate value.
221
222
\section2 Advertising Services
223
224
If we are implementing a GATT server application on a peripheral device, we need to define the
225
services we want to offer to central devices and advertise them:
226
227
\snippet heartrate-server/main.cpp Advertising Data
228
\snippet heartrate-server/main.cpp Start Advertising
229
230
Now potential clients can connect to our device, discover the provided service and
231
register themselves to get notified of changes to the characteristic value.
232
This part of the API was already covered by the above sections.
233
234
\section2 Implementing a Service on the Peripheral Device
235
236
The first step is to define the service, its characteristics and descriptors. This is achieved
237
using the \l QLowEnergyServiceData, \l QLowEnergyCharacteristicData and
238
\l QLowEnergyDescriptorData classes. These classes act as containers or building blocks for the
239
essential information that comprises the to-be-defined Bluetooth Low Energy service.
240
The code snippet below defines a simple HeartRate service which publishes
241
the measured beats per minute. An example where such a service could be used is a wrist watch.
242
243
\snippet heartrate-server/main.cpp Service Data
244
245
The resulting \c serviceData object can be published as described in the
246
\l {Advertising Services} section above. Despite the partial information overlap between the
247
information wrapped by \l QLowEnergyServiceData and \l QLowEnergyAdvertisingData the two classes
248
serve two very different tasks. The advertising data is published to nearby devices and often
249
limited in scope due to its size restriction of 29 bytes. Therefore they are not always 100%
250
complete. By comparison the service data contained inside of \l QLowEnergyServiceData provides
251
the complete set of service data and only becomes visible to the connecting client when a
252
connection with an active service discovery has been performed.
253
254
The next section demonstrates how the service can update the heart rate value. Depending on the
255
nature of the service it may have to comply with the official service definition
256
as defined on \l {https://www.bluetooth.org}. Other services may be completely custom. The
257
heart rate service was adopted and its specification can be found under
258
\l {https://www.bluetooth.com/specifications/adopted-specifications}.
259
260
\snippet heartrate-server/main.cpp Provide Heartbeat
261
262
In general characteristic and descriptor value updates on the peripheral device use the same
263
methods as connecting Bluetooth Low Energy devices.
264
265
\note To use \l{Qt Bluetooth} (in both central and peripheral roles) on iOS, you have to provide
266
an Info.plist file containing the usage description. According to the CoreBluetooth's
267
documentation: \e {Your app will crash if its Info.plist doesn’t include usage description
268
keys for the types of data it needs to access. To access Core Bluetooth APIs on apps linked
269
on or after iOS 13, include the NSBluetoothAlwaysUsageDescription key. In iOS 12 and earlier,
270
include NSBluetoothPeripheralUsageDescription to access Bluetooth peripheral data.}
271
*/
qtconnectivity
src
bluetooth
doc
src
bluetooth-le-overview.qdoc
Generated on
for Qt by
1.14.0