summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIvan Solovev <ivan.solovev@qt.io>2023-03-24 12:27:32 +0100
committerIvan Solovev <ivan.solovev@qt.io>2023-03-28 14:44:12 +0200
commit6f155ca7df89c649e178dac57f69574290cb516b (patch)
treef1e34bf76ce014725e531af0a746a796e801962c
parentca681cd1b3a51d10106a1287a98c5590100feb6a (diff)
downloadqtconnectivity-6f155ca7df89c649e178dac57f69574290cb516b.tar.gz
HeartRate Server: revamp the example
Some code clean-ups: * Use qt_standard_project_setup() and PRIVATE linking in CMake * Port away from QScopedPointer and use std::unique_ptr instead Documentation updates: * Add Connectivity category * Mention the new BlueZ D-Bus backend in the documentation * Small wording improvements * Provide more links to Qt classes and enums Task-number: QTBUG-111972 Pick-to: 6.5 6.5.0 Change-Id: Id2a0ef48d3ce82f1784dd4b51f94236731730432 Reviewed-by: Juha Vuolle <juha.vuolle@qt.io>
-rw-r--r--examples/bluetooth/heartrate-server/CMakeLists.txt8
-rw-r--r--examples/bluetooth/heartrate-server/doc/src/heartrate-server.qdoc43
-rw-r--r--examples/bluetooth/heartrate-server/heartrate-server.pro2
-rw-r--r--examples/bluetooth/heartrate-server/main.cpp20
-rw-r--r--src/bluetooth/doc/qtbluetooth.qdocconf2
5 files changed, 45 insertions, 30 deletions
diff --git a/examples/bluetooth/heartrate-server/CMakeLists.txt b/examples/bluetooth/heartrate-server/CMakeLists.txt
index 02dbf876..b1fa569d 100644
--- a/examples/bluetooth/heartrate-server/CMakeLists.txt
+++ b/examples/bluetooth/heartrate-server/CMakeLists.txt
@@ -4,8 +4,6 @@
cmake_minimum_required(VERSION 3.16)
project(heartrate-server LANGUAGES CXX)
-set(CMAKE_AUTOMOC ON)
-
if(NOT DEFINED INSTALL_EXAMPLESDIR)
set(INSTALL_EXAMPLESDIR "examples")
endif()
@@ -14,6 +12,8 @@ set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/bluetooth/heartrate-server")
find_package(Qt6 REQUIRED COMPONENTS Bluetooth Core)
+qt_standard_project_setup()
+
if(ANDROID OR APPLE)
find_package(Qt6 REQUIRED COMPONENTS Gui)
endif()
@@ -26,13 +26,13 @@ set_target_properties(heartrate-server PROPERTIES
MACOSX_BUNDLE TRUE
)
-target_link_libraries(heartrate-server PUBLIC
+target_link_libraries(heartrate-server PRIVATE
Qt::Bluetooth
Qt::Core
)
if(ANDROID OR APPLE)
- target_link_libraries(heartrate-server PUBLIC
+ target_link_libraries(heartrate-server PRIVATE
Qt::Gui
)
endif()
diff --git a/examples/bluetooth/heartrate-server/doc/src/heartrate-server.qdoc b/examples/bluetooth/heartrate-server/doc/src/heartrate-server.qdoc
index 39d4c976..c5ccf1de 100644
--- a/examples/bluetooth/heartrate-server/doc/src/heartrate-server.qdoc
+++ b/examples/bluetooth/heartrate-server/doc/src/heartrate-server.qdoc
@@ -3,7 +3,8 @@
/*!
\example heartrate-server
- \title Bluetooth Low Energy Heart Rate Server Example
+ \title Bluetooth Low Energy Heart Rate Server
+ \meta category {Connectivity}
\brief An example demonstrating how to set up and advertise a GATT service. The example
demonstrates the use of the Qt Bluetooth Low Energy classes related to peripheral (slave)
functionality.
@@ -30,8 +31,12 @@
To visualize what it is doing, you can use the \l {heartrate-game}{Heart Rate Game}
example, which is basically the client-side counterpart to this application.
- \note On Linux, advertising requires privileged access, so you need to run
- the example as root, for instance via \c sudo.
+ \note By default on Linux a kernel socket API is used for advertising, which
+ means that a privileged access is required to start advertising. This can
+ be achieved by running the example as root, for instance via \c sudo.
+ Starting from Qt 6.5, an alternative approach is to use the BlueZ D-Bus
+ backend for advertising, which does not require root access. To enable
+ this backend, set \c QT_BLUETOOTH_USE_DBUS_PERIPHERAL environment variable.
\section1 Checking Bluetooth Permission
Before the application can create a service and start advertising, we have to check
@@ -44,10 +49,17 @@
\snippet heartrate-server/main.cpp Request Bluetooth Permission
\section1 Setting up Advertising Data and Parameters
- Two classes are used to configure the advertising process: \l QLowEnergyAdvertisingData to
- specify which information is to be broadcast, and \l QLowEnergyAdvertisingParameters for
- specific aspects such as setting the advertising interval or controlling which devices are
- allowed to connect. In our example, we simply use the default parameters.
+
+ Two classes are used to configure the advertising process:
+ \list
+ \li \l QLowEnergyAdvertisingData specifies which information is to be
+ broadcasted
+ \li \l QLowEnergyAdvertisingParameters is used for specific aspects such
+ as setting the advertising interval or controlling which devices are
+ allowed to connect.
+ \endlist
+
+ In our example, we simply use the default parameters.
The information contained in the \l QLowEnergyAdvertisingData will be visible to other devices
that are currently scanning. They can use it to decide whether they want to establish a connection
@@ -60,13 +72,16 @@
\snippet heartrate-server/main.cpp Advertising Data
\section1 Setting up Service Data
- Next we configure the kind of service we want to offer. We use the \c {Heart Rate} service as
- defined in the Bluetooth specification in its minimal form, that is, consisting only of the
- \c {Heart Rate Measurement} characteristic. This characteristic must support the \c Notify
- property (and no others), and it needs to have a \c {Client Characteristic Configuration}
- descriptor, which enables clients to register to get notified about changes to characteristic
- values. We set the initial heart rate value to zero, as it cannot be read anyway (the only
- way the client can get at the value is via notifications).
+ Next we configure the kind of service we want to offer. We use the
+ \l {QBluetoothUuid::ServiceClassUuid}{Heart Rate} service as defined in the
+ Bluetooth specification in its minimal form, that is, consisting only of the
+ \l {QBluetoothUuid::CharacteristicType}{Heart Rate Measurement} characteristic.
+ This characteristic must support the \l {QLowEnergyCharacteristic::}{Notify}
+ property (and no others), and it needs to have a \l {QBluetoothUuid::DescriptorType}
+ {Client Characteristic Configuration} descriptor, which enables clients to
+ register to get notified about changes to characteristic values. We set the
+ initial heart rate value to zero, as it cannot be read anyway (the only way
+ the client can get the value is via notifications).
\snippet heartrate-server/main.cpp Service Data
\section1 Advertising and Listening for Incoming Connections
diff --git a/examples/bluetooth/heartrate-server/heartrate-server.pro b/examples/bluetooth/heartrate-server/heartrate-server.pro
index 34d8eaf7..800f3f16 100644
--- a/examples/bluetooth/heartrate-server/heartrate-server.pro
+++ b/examples/bluetooth/heartrate-server/heartrate-server.pro
@@ -4,7 +4,7 @@ TARGET = heartrate-server
QT = core bluetooth
android|darwin: QT += gui
-CONFIG += c++11 console
+CONFIG += console
SOURCES += main.cpp
diff --git a/examples/bluetooth/heartrate-server/main.cpp b/examples/bluetooth/heartrate-server/main.cpp
index 6cc40a4d..434d37eb 100644
--- a/examples/bluetooth/heartrate-server/main.cpp
+++ b/examples/bluetooth/heartrate-server/main.cpp
@@ -17,12 +17,13 @@
#endif
#include <QtCore/qlist.h>
#include <QtCore/qloggingcategory.h>
-#include <QtCore/qscopedpointer.h>
#include <QtCore/qtimer.h>
#if QT_CONFIG(permissions)
#include <QtCore/qpermissions.h>
#endif
+#include <memory>
+
int main(int argc, char *argv[])
{
// QLoggingCategory::setFilterRules(QStringLiteral("qt.bluetooth* = true"));
@@ -81,9 +82,8 @@ int main(int argc, char *argv[])
//! [Start Advertising]
bool errorOccurred = false;
- const QScopedPointer<QLowEnergyController> leController(QLowEnergyController::createPeripheral());
- auto errorHandler = [&leController,&errorOccurred](QLowEnergyController::Error errorCode)
- {
+ const std::unique_ptr<QLowEnergyController> leController(QLowEnergyController::createPeripheral());
+ auto errorHandler = [&leController, &errorOccurred](QLowEnergyController::Error errorCode) {
qWarning().noquote().nospace() << errorCode << " occurred: "
<< leController->errorString();
if (errorCode != QLowEnergyController::RemoteHostClosedError) {
@@ -92,9 +92,9 @@ int main(int argc, char *argv[])
QCoreApplication::quit();
}
};
- QObject::connect(leController.data(), &QLowEnergyController::errorOccurred, errorHandler);
+ QObject::connect(leController.get(), &QLowEnergyController::errorOccurred, errorHandler);
- QScopedPointer<QLowEnergyService> service(leController->addService(serviceData));
+ std::unique_ptr<QLowEnergyService> service(leController->addService(serviceData));
leController->startAdvertising(QLowEnergyAdvertisingParameters(), advertisingData,
advertisingData);
if (errorOccurred)
@@ -126,14 +126,14 @@ int main(int argc, char *argv[])
heartbeatTimer.start(1000);
//! [Provide Heartbeat]
- auto reconnect = [&leController, advertisingData, &service, serviceData]()
- {
+ auto reconnect = [&leController, advertisingData, &service, serviceData]() {
service.reset(leController->addService(serviceData));
- if (!service.isNull())
+ if (service) {
leController->startAdvertising(QLowEnergyAdvertisingParameters(),
advertisingData, advertisingData);
+ }
};
- QObject::connect(leController.data(), &QLowEnergyController::disconnected, reconnect);
+ QObject::connect(leController.get(), &QLowEnergyController::disconnected, reconnect);
const int retval = QCoreApplication::exec();
return errorOccurred ? -1 : retval;
diff --git a/src/bluetooth/doc/qtbluetooth.qdocconf b/src/bluetooth/doc/qtbluetooth.qdocconf
index d8bc6e7a..e6b7541d 100644
--- a/src/bluetooth/doc/qtbluetooth.qdocconf
+++ b/src/bluetooth/doc/qtbluetooth.qdocconf
@@ -39,7 +39,7 @@ exampledirs += ../../../examples/bluetooth \
snippets/ \
../
-manifestmeta.thumbnail.names = "QtBluetooth/Bluetooth Low Energy Heart Rate Server Example"
+manifestmeta.thumbnail.names = "QtBluetooth/Bluetooth Low Energy Heart Rate Server"
manifestmeta.highlighted.names += "QtBluetooth/Bluetooth Low Energy Heart Rate Game"
imagedirs += images