summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristian Kandeler <christian.kandeler@theqtcompany.com>2016-01-15 15:30:53 +0100
committerAlex Blasche <alexander.blasche@theqtcompany.com>2016-01-26 11:39:16 +0000
commit4b5d90106c489c5099f1c4f4a553132c6bf72b95 (patch)
tree6ef2e59a8b29778cd7073fbc59555f2e0de27640
parentf9d1962595237dab3e1162e14cccaefda919f1ca (diff)
Add example for Bluetooth Peripheral functionality.
Change-Id: I1b48bc0be6265fb033fa2c14c2b7a182966fe2a2 Reviewed-by: Alex Blasche <alexander.blasche@theqtcompany.com>
-rw-r--r--examples/bluetooth/bluetooth.pro3
-rw-r--r--examples/bluetooth/heartlistener/doc/src/heartlistener.qdoc6
-rw-r--r--examples/bluetooth/heartrate-server/doc/src/heartrate-server.qdoc115
-rw-r--r--examples/bluetooth/heartrate-server/heartrate-server.pro10
-rw-r--r--examples/bluetooth/heartrate-server/main.cpp121
-rw-r--r--src/bluetooth/doc/src/bluetooth-index.qdoc1
6 files changed, 254 insertions, 2 deletions
diff --git a/examples/bluetooth/bluetooth.pro b/examples/bluetooth/bluetooth.pro
index a98bb62d..1c09dade 100644
--- a/examples/bluetooth/bluetooth.pro
+++ b/examples/bluetooth/bluetooth.pro
@@ -1,4 +1,7 @@
TEMPLATE = subdirs
+
+SUBDIRS += heartrate-server
+
qtHaveModule(widgets) {
SUBDIRS += btchat \
btscanner \
diff --git a/examples/bluetooth/heartlistener/doc/src/heartlistener.qdoc b/examples/bluetooth/heartlistener/doc/src/heartlistener.qdoc
index e7e1176f..2bb59ae1 100644
--- a/examples/bluetooth/heartlistener/doc/src/heartlistener.qdoc
+++ b/examples/bluetooth/heartlistener/doc/src/heartlistener.qdoc
@@ -51,8 +51,10 @@
A Bluetooth Low Energy device with a Heart Rate
service is required for this application to work. An alternative might be a programmable
- Bluetooth Low Energy device which might simulate the service. If no such device can be
- found, the example uses a demo mode which creates and displays random values.
+ Bluetooth Low Energy device which might simulate the service. You can also use the
+ \l {heartrate-server} {Heart Rate server} example for that purpose.
+ If no such device can be found, the example uses a demo mode which creates and displays
+ random values.
The \l {lowenergyscanner}{Bluetooth Low Energy Scanner} example might be more suitable
if a heart rate device is not available. The scanner example works with any type of Bluetooth
diff --git a/examples/bluetooth/heartrate-server/doc/src/heartrate-server.qdoc b/examples/bluetooth/heartrate-server/doc/src/heartrate-server.qdoc
new file mode 100644
index 00000000..22c6fcd1
--- /dev/null
+++ b/examples/bluetooth/heartrate-server/doc/src/heartrate-server.qdoc
@@ -0,0 +1,115 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the documentation of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:FDL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Free Documentation License Usage
+** Alternatively, this file may be used under the terms of the GNU Free
+** Documentation License version 1.3 as published by the Free Software
+** Foundation and appearing in the file included in the packaging of
+** this file. Please review the following information to ensure
+** the GNU Free Documentation License version 1.3 requirements
+** will be met: http://www.gnu.org/copyleft/fdl.html.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+/*!
+ \example heartrate-server
+ \title Bluetooth Low Energy Heart Rate Server Example
+ \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.
+
+ The Bluetooth Low Energy Heart Rate Server is a command-line application that shows how to
+ develop a Bluetooth GATT server using the Qt Bluetooth API.
+ The application covers setting up a service, advertising it and notifying clients about changes
+ to characteristic values.
+
+ The example makes use of the following Qt classes:
+
+ \list
+ \li \l QLowEnergyAdvertisingData
+ \li \l QLowEnergyAdvertisingParameters
+ \li \l QLowEnergyServiceData
+ \li \l QLowEnergyCharacteristicData
+ \li \l QLowEnergyDescriptorData
+ \li \l QLowEnergyController
+ \li \l QLowEnergyService
+
+ \endlist
+
+ The example implements a server application, which means it has no graphical user interface.
+ To visualize what it is doing, you can use the \l {heartlistener}{Heart Listener}
+ 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.
+
+ \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.
+
+ 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
+ or not. In our example, we include the type of service we offer, a name that adequately
+ describes our device to humans, and the transmit power level of the device. The latter is
+ often useful to potential clients, because they can tell how far away our device is by
+ comparing the received signal strength to the advertised one.
+ \note Space for the advertising data is very limited (only 31 bytes in total), so
+ variable-length data such as the device name should be kept as short as possible.
+ \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).
+ \snippet heartrate-server/main.cpp Service Data
+
+ \section1 Advertising and Listening for Incoming Connections
+ Now that all the data has been set up, we can start advertising. First we create a
+ \l QLowEnergyController object in the
+ \l {QLowEnergyController::PeripheralRole} {peripheral role} and use it to create a (dynamic)
+ \l QLowEnergyService object from our (static) \l QLowEnergyServiceData.
+ Then we call \l QLowEnergyController::startAdvertising().
+ Note that we hand in our \l QLowEnergyAdvertisingData twice: The first argument
+ acts as the actual advertising data, the second one as the scan response data. They could
+ transport different information, but here we don't have a need for that. We also pass
+ a default-constructed instance of \l QLowEnergyAdvertisingParameters, because the default
+ advertising parameters are fine for us. If a client is interested in the advertised service,
+ it can now establish a connection to our device. When that happens, the device stops advertising
+ and the \l QLowEnergyController::connected() signal is emitted.
+ \note When a client disconnects, advertising does not resume automatically. If you want that
+ to happen, you need to connect to the \l QLowEnergyController::disconnected() signal
+ and call \l QLowEnergyController::startAdvertising() in the respective slot.
+ \snippet heartrate-server/main.cpp Start Advertising
+
+ \section1 Providing the Heartrate
+ So far, so good. But how does a client actually get at the heart rate? This happens by
+ regularly updating the value of the respective characteristic in the \l QLowEnergyService
+ object that we received from the \l QLowEnergyController in the code snippet above.
+ The source of the heart rate would normally be some kind of sensor, but in our example,
+ we just make up values that we let oscillate between 60 and 100. The most important part in the
+ following code snippet is the call to \l QLowEnergyService::writeCharacteristic. If
+ a client is currently connected and has enabled notifications by writing to the aforementioned
+ \c {Client Characteristic Configuration}, it will get notified about the new value.
+ \snippet heartrate-server/main.cpp Provide Heartbeat
+*/
+
diff --git a/examples/bluetooth/heartrate-server/heartrate-server.pro b/examples/bluetooth/heartrate-server/heartrate-server.pro
new file mode 100644
index 00000000..4ccf486c
--- /dev/null
+++ b/examples/bluetooth/heartrate-server/heartrate-server.pro
@@ -0,0 +1,10 @@
+TEMPLATE = app
+TARGET = heartrate-server
+
+QT += bluetooth
+CONFIG += c++11
+
+SOURCES += main.cpp
+
+target.path = $$[QT_INSTALL_EXAMPLES]/bluetooth/heartrate-server
+INSTALLS += target
diff --git a/examples/bluetooth/heartrate-server/main.cpp b/examples/bluetooth/heartrate-server/main.cpp
new file mode 100644
index 00000000..779dbb6a
--- /dev/null
+++ b/examples/bluetooth/heartrate-server/main.cpp
@@ -0,0 +1,121 @@
+/***************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the examples of the QtBluetooth module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtBluetooth/qlowenergyadvertisingdata.h>
+#include <QtBluetooth/qlowenergyadvertisingparameters.h>
+#include <QtBluetooth/qlowenergycharacteristic.h>
+#include <QtBluetooth/qlowenergycharacteristicdata.h>
+#include <QtBluetooth/qlowenergydescriptordata.h>
+#include <QtBluetooth/qlowenergycontroller.h>
+#include <QtBluetooth/qlowenergyservice.h>
+#include <QtBluetooth/qlowenergyservicedata.h>
+#include <QtCore/qbytearray.h>
+#include <QtCore/qcoreapplication.h>
+#include <QtCore/qlist.h>
+#include <QtCore/qscopedpointer.h>
+#include <QtCore/qtimer.h>
+
+int main(int argc, char *argv[])
+{
+ QCoreApplication app(argc, argv);
+
+ //! [Advertising Data]
+ QLowEnergyAdvertisingData advertisingData;
+ advertisingData.setDiscoverability(QLowEnergyAdvertisingData::DiscoverabilityGeneral);
+ advertisingData.setIncludePowerLevel(true);
+ advertisingData.setLocalName("HeartRateServer");
+ advertisingData.setServices(QList<QBluetoothUuid>() << QBluetoothUuid::HeartRate);
+ //! [Advertising Data]
+
+ //! [Service Data]
+ QLowEnergyCharacteristicData charData;
+ charData.setUuid(QBluetoothUuid::HeartRateMeasurement);
+ charData.setValue(QByteArray(2, 0));
+ charData.setProperties(QLowEnergyCharacteristic::Notify);
+ const QLowEnergyDescriptorData clientConfig(QBluetoothUuid::ClientCharacteristicConfiguration,
+ QByteArray(2, 0));
+ charData.addDescriptor(clientConfig);
+
+ QLowEnergyServiceData serviceData;
+ serviceData.setType(QLowEnergyServiceData::ServiceTypePrimary);
+ serviceData.setUuid(QBluetoothUuid::HeartRate);
+ serviceData.addCharacteristic(charData);
+ //! [Service Data]
+
+ //! [Start Advertising]
+ const QScopedPointer<QLowEnergyController> leController(QLowEnergyController::createPeripheral());
+ const QScopedPointer<QLowEnergyService> service(leController->addService(serviceData));
+ leController->startAdvertising(QLowEnergyAdvertisingParameters(), advertisingData,
+ advertisingData);
+ //! [Start Advertising]
+
+ //! [Provide Heartbeat]
+ QTimer heartbeatTimer;
+ quint8 currentHeartRate = 60;
+ enum ValueChange { ValueUp, ValueDown } valueChange = ValueUp;
+ const auto heartbeatProvider = [&service, &currentHeartRate, &valueChange]() {
+ QByteArray value;
+ value.append(char(0)); // Flags that specify the format of the value.
+ value.append(char(currentHeartRate)); // Actual value.
+ QLowEnergyCharacteristic characteristic
+ = service->characteristic(QBluetoothUuid::HeartRateMeasurement);
+ Q_ASSERT(characteristic.isValid());
+ service->writeCharacteristic(characteristic, value); // Potentially causes notification.
+ if (currentHeartRate == 60)
+ valueChange = ValueUp;
+ else if (currentHeartRate == 100)
+ valueChange = ValueDown;
+ if (valueChange == ValueUp)
+ ++currentHeartRate;
+ else
+ --currentHeartRate;
+ };
+ QObject::connect(&heartbeatTimer, &QTimer::timeout, heartbeatProvider);
+ heartbeatTimer.start(1000);
+ //! [Provide Heartbeat]
+
+ auto reconnect = [&leController, advertisingData]() {
+ leController->startAdvertising(QLowEnergyAdvertisingParameters(), advertisingData,
+ advertisingData);
+ };
+ QObject::connect(leController.data(), &QLowEnergyController::disconnected, reconnect);
+
+ return app.exec();
+}
diff --git a/src/bluetooth/doc/src/bluetooth-index.qdoc b/src/bluetooth/doc/src/bluetooth-index.qdoc
index 41b962bf..8e5f1d35 100644
--- a/src/bluetooth/doc/src/bluetooth-index.qdoc
+++ b/src/bluetooth/doc/src/bluetooth-index.qdoc
@@ -84,6 +84,7 @@ import statement in your \c .qml file:
\li \l {pingpong}{QML Bluetooth PingPong}
\li \l {chat}{QML Bluetooth Chat}
\li \l {heartlistener}{Bluetooth Low Energy Heart Listener}
+ \li \l {heartrate-server}{Bluetooth Low Energy Heart Rate Server}
\li \l {lowenergyscanner}{Bluetooth Low Energy Scanner}
\endlist
\li C++