summaryrefslogtreecommitdiffstats
path: root/src/bluetooth
diff options
context:
space:
mode:
authorChristian Kandeler <christian.kandeler@theqtcompany.com>2015-10-26 16:25:43 +0100
committerAlex Blasche <alexander.blasche@theqtcompany.com>2015-11-20 16:35:36 +0000
commit83c826261d6d6bf9180857c9a9cff3f78b63378d (patch)
tree4c10c7d5341044f75a16e423cfdb8a9dcc969934 /src/bluetooth
parent57353d3f91f89e6e364b9798277048e25b9c63b8 (diff)
Bluetooth: Add API to set up GATT services.
This is the next step in implementing LE peripheral support. Change-Id: I5e8cb186d556e7bfb9ae8a5e60e051ff7398b77d Reviewed-by: Alex Blasche <alexander.blasche@theqtcompany.com>
Diffstat (limited to 'src/bluetooth')
-rw-r--r--src/bluetooth/bluetooth.pro6
-rw-r--r--src/bluetooth/qlowenergycharacteristicdata.cpp189
-rw-r--r--src/bluetooth/qlowenergycharacteristicdata.h89
-rw-r--r--src/bluetooth/qlowenergycontroller.cpp74
-rw-r--r--src/bluetooth/qlowenergycontroller.h3
-rw-r--r--src/bluetooth/qlowenergycontroller_android.cpp7
-rw-r--r--src/bluetooth/qlowenergycontroller_bluez.cpp116
-rw-r--r--src/bluetooth/qlowenergycontroller_osx.mm9
-rw-r--r--src/bluetooth/qlowenergycontroller_p.cpp8
-rw-r--r--src/bluetooth/qlowenergycontroller_p.h24
-rw-r--r--src/bluetooth/qlowenergydescriptordata.cpp149
-rw-r--r--src/bluetooth/qlowenergydescriptordata.h87
-rw-r--r--src/bluetooth/qlowenergyservice.h1
-rw-r--r--src/bluetooth/qlowenergyservicedata.cpp209
-rw-r--r--src/bluetooth/qlowenergyservicedata.h92
15 files changed, 1055 insertions, 8 deletions
diff --git a/src/bluetooth/bluetooth.pro b/src/bluetooth/bluetooth.pro
index 99067c74..45190a79 100644
--- a/src/bluetooth/bluetooth.pro
+++ b/src/bluetooth/bluetooth.pro
@@ -24,8 +24,11 @@ PUBLIC_HEADERS += \
qbluetoothtransfermanager.h \
qbluetoothtransferrequest.h \
qlowenergyservice.h \
+ qlowenergyservicedata.h \
qlowenergycharacteristic.h \
+ qlowenergycharacteristicdata.h \
qlowenergydescriptor.h \
+ qlowenergydescriptordata.h \
qbluetoothtransferreply.h \
qlowenergyadvertisingdata.h \
qlowenergyadvertisingparameters.h \
@@ -66,8 +69,11 @@ SOURCES += \
qlowenergyadvertisingdata.cpp \
qlowenergyadvertisingparameters.cpp \
qlowenergyservice.cpp \
+ qlowenergyservicedata.cpp \
qlowenergycharacteristic.cpp \
+ qlowenergycharacteristicdata.cpp \
qlowenergydescriptor.cpp \
+ qlowenergydescriptordata.cpp \
qlowenergycontroller.cpp \
qlowenergyserviceprivate.cpp
diff --git a/src/bluetooth/qlowenergycharacteristicdata.cpp b/src/bluetooth/qlowenergycharacteristicdata.cpp
new file mode 100644
index 00000000..a64af7a3
--- /dev/null
+++ b/src/bluetooth/qlowenergycharacteristicdata.cpp
@@ -0,0 +1,189 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the QtBluetooth module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL21$
+** 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 Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** As a special exception, The Qt Company gives you certain additional
+** rights. These rights are described in The Qt Company LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qlowenergycharacteristicdata.h"
+
+#include "qlowenergydescriptordata.h"
+
+#include <QtCore/qbytearray.h>
+#include <QtCore/qloggingcategory.h>
+#include <QtCore/qdebug.h>
+
+QT_BEGIN_NAMESPACE
+
+Q_DECLARE_LOGGING_CATEGORY(QT_BT)
+
+struct QLowEnergyCharacteristicDataPrivate : public QSharedData
+{
+ QLowEnergyCharacteristicDataPrivate() : properties(QLowEnergyCharacteristic::Unknown) {}
+
+ QBluetoothUuid uuid;
+ QLowEnergyCharacteristic::PropertyTypes properties;
+ QList<QLowEnergyDescriptorData> descriptors;
+ QByteArray value;
+};
+
+/*!
+ \since 5.7
+ \class QLowEnergyCharacteristicData
+ \brief The QLowEnergyCharacteristicData class is used to set up GATT service data.
+ \inmodule QtBluetooth
+ \ingroup shared
+
+ An Object of this class provides a characteristic to be added to a
+ \l QLowEnergyServiceData object via \l QLowEnergyServiceData::addCharacteristic().
+
+ \sa QLowEnergyServiceData
+ \sa QLowEnergyController::addService
+*/
+
+/*! Creates a new invalid object of this class. */
+QLowEnergyCharacteristicData::QLowEnergyCharacteristicData()
+ : d(new QLowEnergyCharacteristicDataPrivate)
+{
+}
+
+/*! Constructs a new object of this class that is a copy of \a other. */
+QLowEnergyCharacteristicData::QLowEnergyCharacteristicData(const QLowEnergyCharacteristicData &other)
+ : d(other.d)
+{
+}
+
+/*! Destroys this object. */
+QLowEnergyCharacteristicData::~QLowEnergyCharacteristicData()
+{
+}
+
+/*! Makes this object a copy of \a other and returns the new value of this object. */
+QLowEnergyCharacteristicData &QLowEnergyCharacteristicData::operator=(const QLowEnergyCharacteristicData &other)
+{
+ d = other.d;
+ return *this;
+}
+
+/*! Returns the UUID of this characteristic. */
+QBluetoothUuid QLowEnergyCharacteristicData::uuid() const
+{
+ return d->uuid;
+}
+
+/*! Sets the UUID of this characteristic to \a uuid. */
+void QLowEnergyCharacteristicData::setUuid(const QBluetoothUuid &uuid)
+{
+ d->uuid = uuid;
+}
+
+/*! Returns the value of this characteristic. */
+QByteArray QLowEnergyCharacteristicData::value() const
+{
+ return d->value;
+}
+
+/*! Sets the value of this characteristic to \a value. */
+void QLowEnergyCharacteristicData::setValue(const QByteArray &value)
+{
+ d->value = value;
+}
+
+/*! Returns the properties of this characteristic. */
+QLowEnergyCharacteristic::PropertyTypes QLowEnergyCharacteristicData::properties() const
+{
+ return d->properties;
+}
+
+/*! Sets the properties of this characteristic to \a properties. */
+void QLowEnergyCharacteristicData::setProperties(QLowEnergyCharacteristic::PropertyTypes properties)
+{
+ d->properties = properties;
+}
+
+/*! Returns the descriptors of this characteristic. */
+QList<QLowEnergyDescriptorData> QLowEnergyCharacteristicData::descriptors() const
+{
+ return d->descriptors;
+}
+
+/*!
+ Sets the descriptors of this characteristic to \a descriptors. Only valid descriptors
+ are considered.
+ \sa addDescriptor()
+ */
+void QLowEnergyCharacteristicData::setDescriptors(const QList<QLowEnergyDescriptorData> &descriptors)
+{
+ foreach (const QLowEnergyDescriptorData &desc, descriptors)
+ addDescriptor(desc);
+}
+
+/*!
+ Adds \a descriptor to the list of descriptors of this characteristic, if it is valid.
+ \sa setDescriptors()
+ */
+void QLowEnergyCharacteristicData::addDescriptor(const QLowEnergyDescriptorData &descriptor)
+{
+ if (descriptor.isValid())
+ d->descriptors << descriptor;
+ else
+ qCWarning(QT_BT) << "not adding invalid descriptor to characteristic";
+}
+
+/*!
+ Returns true if and only if this characteristic is valid, that is, it has a non-null UUID.
+ */
+bool QLowEnergyCharacteristicData::isValid() const
+{
+ return !uuid().isNull();
+}
+
+/*!
+ \fn void QLowEnergyCharacteristicData::swap(QLowEnergyCharacteristicData &other)
+ Swaps this object with \a other.
+ */
+
+/*!
+ Returns \c true if \a cd1 and \a cd2 are equal with respect to their public state,
+ otherwise returns \c false.
+ */
+bool operator==(const QLowEnergyCharacteristicData &cd1, const QLowEnergyCharacteristicData &cd2)
+{
+ return cd1.d == cd2.d || (cd1.uuid() == cd2.uuid() && cd1.properties() == cd2.properties()
+ && cd1.descriptors() == cd2.descriptors() && cd1.value() == cd2.value());
+}
+
+/*!
+ \fn bool operator!=(const QLowEnergyCharacteristicData &cd1,
+ const QLowEnergyCharacteristicData &cd2)
+ Returns \c true if \a cd1 and \a cd2 are not equal with respect to their public state,
+ otherwise returns \c false.
+ */
+
+QT_END_NAMESPACE
diff --git a/src/bluetooth/qlowenergycharacteristicdata.h b/src/bluetooth/qlowenergycharacteristicdata.h
new file mode 100644
index 00000000..ac78af5e
--- /dev/null
+++ b/src/bluetooth/qlowenergycharacteristicdata.h
@@ -0,0 +1,89 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the QtBluetooth module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL21$
+** 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 Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** As a special exception, The Qt Company gives you certain additional
+** rights. These rights are described in The Qt Company LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#ifndef QLOWENERGYCHARACTERISTICDATA_H
+#define QLOWENERGYCHARACTERISTICDATA_H
+
+#include <QtBluetooth/qlowenergycharacteristic.h>
+#include <QtCore/qshareddata.h>
+
+QT_BEGIN_NAMESPACE
+
+class QLowEnergyDescriptorData;
+struct QLowEnergyCharacteristicDataPrivate;
+class Q_BLUETOOTH_EXPORT QLowEnergyCharacteristicData
+{
+ friend Q_BLUETOOTH_EXPORT bool operator==(const QLowEnergyCharacteristicData &cd1,
+ const QLowEnergyCharacteristicData &cd2);
+public:
+ QLowEnergyCharacteristicData();
+ QLowEnergyCharacteristicData(const QLowEnergyCharacteristicData &other);
+ ~QLowEnergyCharacteristicData();
+
+ QLowEnergyCharacteristicData &operator=(const QLowEnergyCharacteristicData &other);
+
+ QBluetoothUuid uuid() const;
+ void setUuid(const QBluetoothUuid &uuid);
+
+ QByteArray value() const;
+ void setValue(const QByteArray &value);
+
+ QLowEnergyCharacteristic::PropertyTypes properties() const;
+ void setProperties(QLowEnergyCharacteristic::PropertyTypes properties);
+
+ QList<QLowEnergyDescriptorData> descriptors() const;
+ void setDescriptors(const QList<QLowEnergyDescriptorData> &descriptors);
+ void addDescriptor(const QLowEnergyDescriptorData &descriptor);
+
+ bool isValid() const;
+
+ void swap(QLowEnergyCharacteristicData &other) Q_DECL_NOTHROW { qSwap(d, other.d); }
+
+ // TODO: authentication/authorization requirements (separate for reading and writing!)
+
+private:
+ QSharedDataPointer<QLowEnergyCharacteristicDataPrivate> d;
+};
+
+Q_BLUETOOTH_EXPORT bool operator==(const QLowEnergyCharacteristicData &cd1,
+ const QLowEnergyCharacteristicData &cd2);
+inline bool operator!=(const QLowEnergyCharacteristicData &cd1,
+ const QLowEnergyCharacteristicData &cd2)
+{
+ return !(cd1 == cd2);
+}
+
+Q_DECLARE_SHARED(QLowEnergyCharacteristicData)
+
+QT_END_NAMESPACE
+
+#endif // Include guard.
diff --git a/src/bluetooth/qlowenergycontroller.cpp b/src/bluetooth/qlowenergycontroller.cpp
index f8832f1a..d644fcb1 100644
--- a/src/bluetooth/qlowenergycontroller.cpp
+++ b/src/bluetooth/qlowenergycontroller.cpp
@@ -34,6 +34,10 @@
#include "qlowenergycontroller.h"
#include "qlowenergycontroller_p.h"
+#include "qlowenergycharacteristicdata.h"
+#include "qlowenergydescriptordata.h"
+#include "qlowenergyservicedata.h"
+
#include <QtBluetooth/QBluetoothLocalDevice>
#include <QtCore/QLoggingCategory>
@@ -98,13 +102,11 @@ Q_DECLARE_LOGGING_CATEGORY(QT_BT)
Such an object acts as a peripheral device itself, enabling features such as advertising
services and allowing clients to get notified about changes to characteristic values.
- \omit
After having created a controller object in the peripheral role, the first step is to
- populate the set of GATT services offered to client devices [not yet implemented].
+ populate the set of GATT services offered to client devices via calls to \l addService().
Afterwards, one would call \l startAdvertising() to let the device broadcast some data
and, depending on the type of advertising being done, also listen for incoming connections
from GATT clients.
- \endomit
\sa QLowEnergyService, QLowEnergyCharacteristic, QLowEnergyDescriptor
\sa QLowEnergyAdvertisingParameters, QLowEnergyAdvertisingData
@@ -812,6 +814,72 @@ void QLowEnergyController::stopAdvertising()
}
/*!
+ Constructs and returns a \l QLowEnergyService object with \a parent from \a service.
+ The controller must be in the \l PeripheralRole and in the \l UnconnectedState. The \a service
+ object must be valid.
+ */
+QLowEnergyService *QLowEnergyController::addService(const QLowEnergyServiceData &service,
+ QObject *parent)
+{
+ if (role() != PeripheralRole) {
+ qCWarning(QT_BT) << "Services can only be added in the peripheral role";
+ return nullptr;
+ }
+ if (state() != UnconnectedState) {
+ qCWarning(QT_BT) << "Services can only be added in unconnected state";
+ return nullptr;
+ }
+ if (!service.isValid()) {
+ qCWarning(QT_BT) << "Not adding invalid service";
+ return nullptr;
+ }
+
+ // Spec says services "should" be grouped by uuid length (16-bit first, then 128-bit).
+ // Since this is not mandatory, we ignore it here and let the caller take responsibility
+ // for it.
+
+ const auto servicePrivate = QSharedPointer<QLowEnergyServicePrivate>::create();
+ servicePrivate->uuid = service.uuid();
+ servicePrivate->type = service.type() == QLowEnergyServiceData::ServiceTypePrimary
+ ? QLowEnergyService::PrimaryService : QLowEnergyService::IncludedService;
+ foreach (QLowEnergyService * const includedService, service.includedServices()) {
+ servicePrivate->includedServices << includedService->serviceUuid();
+ includedService->d_ptr->type |= QLowEnergyService::IncludedService;
+ }
+
+ // Spec v4.2, Vol 3, Part G, Section 3.
+ const QLowEnergyHandle oldLastHandle = d_ptr->lastLocalHandle;
+ servicePrivate->startHandle = ++d_ptr->lastLocalHandle; // Service declaration.
+ d_ptr->lastLocalHandle += servicePrivate->includedServices.count(); // Include declarations.
+ foreach (const QLowEnergyCharacteristicData &cd, service.characteristics()) {
+ const QLowEnergyHandle declHandle = ++d_ptr->lastLocalHandle;
+ QLowEnergyServicePrivate::CharData charData;
+ charData.valueHandle = ++d_ptr->lastLocalHandle;
+ charData.uuid = cd.uuid();
+ charData.properties = cd.properties();
+ charData.value = cd.value();
+ foreach (const QLowEnergyDescriptorData &dd, cd.descriptors()) {
+ QLowEnergyServicePrivate::DescData descData;
+ descData.uuid = dd.uuid();
+ descData.value = dd.value();
+ charData.descriptorList.insert(++d_ptr->lastLocalHandle, descData);
+ }
+ servicePrivate->characteristicList.insert(declHandle, charData);
+ }
+ servicePrivate->endHandle = d_ptr->lastLocalHandle;
+ const bool handleOverflow = d_ptr->lastLocalHandle <= oldLastHandle;
+ if (handleOverflow) {
+ qCWarning(QT_BT) << "Not enough attribute handles left to create this service";
+ d_ptr->lastLocalHandle = oldLastHandle;
+ return nullptr;
+ }
+
+ d_ptr->localServices.insert(servicePrivate->uuid, servicePrivate);
+ d_ptr->addToGenericAttributeList(service, servicePrivate->startHandle);
+ return new QLowEnergyService(servicePrivate, parent);
+}
+
+/*!
Returns the last occurred error or \l NoError.
*/
QLowEnergyController::Error QLowEnergyController::error() const
diff --git a/src/bluetooth/qlowenergycontroller.h b/src/bluetooth/qlowenergycontroller.h
index 1abc395c..cec0a8cf 100644
--- a/src/bluetooth/qlowenergycontroller.h
+++ b/src/bluetooth/qlowenergycontroller.h
@@ -45,6 +45,7 @@ QT_BEGIN_NAMESPACE
class QLowEnergyAdvertisingParameters;
class QLowEnergyControllerPrivate;
+class QLowEnergyServiceData;
class Q_BLUETOOTH_EXPORT QLowEnergyController : public QObject
{
@@ -120,6 +121,8 @@ public:
const QLowEnergyAdvertisingData &scanResponseData = QLowEnergyAdvertisingData());
void stopAdvertising();
+ QLowEnergyService *addService(const QLowEnergyServiceData &service, QObject *parent = 0);
+
Error error() const;
QString errorString() const;
diff --git a/src/bluetooth/qlowenergycontroller_android.cpp b/src/bluetooth/qlowenergycontroller_android.cpp
index 437eb9a4..732bd6f5 100644
--- a/src/bluetooth/qlowenergycontroller_android.cpp
+++ b/src/bluetooth/qlowenergycontroller_android.cpp
@@ -595,4 +595,11 @@ void QLowEnergyControllerPrivate::stopAdvertising()
qCWarning(QT_BT_ANDROID) << "LE advertising not implemented for Android";
}
+void QLowEnergyControllerPrivate::addToGenericAttributeList(const QLowEnergyServiceData &service,
+ QLowEnergyHandle startHandle)
+{
+ Q_UNUSED(service);
+ Q_UNUSED(startHandle);
+}
+
QT_END_NAMESPACE
diff --git a/src/bluetooth/qlowenergycontroller_bluez.cpp b/src/bluetooth/qlowenergycontroller_bluez.cpp
index ea7a763a..24a89f6d 100644
--- a/src/bluetooth/qlowenergycontroller_bluez.cpp
+++ b/src/bluetooth/qlowenergycontroller_bluez.cpp
@@ -40,7 +40,10 @@
#include <QtCore/QLoggingCategory>
#include <QtBluetooth/QBluetoothSocket>
+#include <QtBluetooth/QLowEnergyCharacteristicData>
+#include <QtBluetooth/QLowEnergyDescriptorData>
#include <QtBluetooth/QLowEnergyService>
+#include <QtBluetooth/QLowEnergyServiceData>
#include <errno.h>
#include <sys/types.h>
@@ -52,10 +55,10 @@
#define ATT_DEFAULT_LE_MTU 23
#define ATT_MAX_LE_MTU 0x200
-#define GATT_PRIMARY_SERVICE 0x2800
-#define GATT_SECONDARY_SERVICE 0x2801
-#define GATT_INCLUDED_SERVICE 0x2802
-#define GATT_CHARACTERISTIC 0x2803
+#define GATT_PRIMARY_SERVICE quint16(0x2800)
+#define GATT_SECONDARY_SERVICE quint16(0x2801)
+#define GATT_INCLUDED_SERVICE quint16(0x2802)
+#define GATT_CHARACTERISTIC quint16(0x2803)
// GATT commands
#define ATT_OP_ERROR_RESPONSE 0x1
@@ -199,10 +202,38 @@ static void dumpErrorInformation(const QByteArray &response)
<< "handle:" << handle;
}
+static int getUuidSize(const QBluetoothUuid &uuid)
+{
+ return uuid.minimumSize() == 2 ? 2 : 16;
+}
+
+template<typename T> static void putDataAndIncrement(const T &src, char *&dst)
+{
+ putBtData(src, dst);
+ dst += sizeof(T);
+}
+template<> void putDataAndIncrement(const QBluetoothUuid &uuid, char *&dst)
+{
+ const int uuidSize = getUuidSize(uuid);
+ if (uuidSize == 2)
+ putBtData(uuid.toUInt16(), dst);
+ else
+ putBtData(uuid.toUInt128(), dst);
+ dst += uuidSize;
+}
+template<> void putDataAndIncrement(const QByteArray &value, char *&dst)
+{
+ using namespace std;
+ memcpy(dst, value.constData(), value.count());
+ dst += value.count();
+}
+
+
QLowEnergyControllerPrivate::QLowEnergyControllerPrivate()
: QObject(),
state(QLowEnergyController::UnconnectedState),
error(QLowEnergyController::NoError),
+ lastLocalHandle(0),
l2cpSocket(0), requestPending(false),
mtuSize(ATT_DEFAULT_LE_MTU),
securityLevelValue(-1),
@@ -1890,4 +1921,81 @@ void QLowEnergyControllerPrivate::closeServerSocket()
serverSocketNotifier = nullptr;
}
+static QByteArray uuidToByteArray(const QBluetoothUuid &uuid)
+{
+ QByteArray ba;
+ if (uuid.minimumSize() == 2) {
+ ba.resize(2);
+ putBtData(uuid.toUInt16(), ba.data());
+ } else {
+ ba.resize(16);
+ putBtData(uuid.toUInt128(), ba.data());
+ }
+ return ba;
+}
+
+void QLowEnergyControllerPrivate::addToGenericAttributeList(const QLowEnergyServiceData &service,
+ QLowEnergyHandle startHandle)
+{
+ // Construct generic attribute data for the service with handles as keys.
+ // Otherwise a number of request handling functions will be awkward to write
+ // as well as computationally inefficient.
+
+ localAttributes.resize(lastLocalHandle + 1);
+ Attribute serviceAttribute;
+ serviceAttribute.handle = startHandle;
+ serviceAttribute.type = QBluetoothUuid(static_cast<quint16>(service.type()));
+ serviceAttribute.properties = QLowEnergyCharacteristic::Read;
+ serviceAttribute.value = uuidToByteArray(service.uuid());
+ QLowEnergyHandle currentHandle = startHandle;
+ foreach (const QLowEnergyService * const service, service.includedServices()) {
+ Attribute attribute;
+ attribute.handle = ++currentHandle;
+ attribute.type = QBluetoothUuid(GATT_INCLUDED_SERVICE);
+ attribute.properties = QLowEnergyCharacteristic::Read;
+ const bool includeUuidInValue = service->serviceUuid().minimumSize() == 2;
+ attribute.value.resize((2 + includeUuidInValue) * sizeof(QLowEnergyHandle));
+ char *valueData = attribute.value.data();
+ putDataAndIncrement(service->d_ptr->startHandle, valueData);
+ putDataAndIncrement(service->d_ptr->endHandle, valueData);
+ if (includeUuidInValue)
+ putDataAndIncrement(service->serviceUuid(), valueData);
+ localAttributes[attribute.handle] = attribute;
+ }
+ foreach (const QLowEnergyCharacteristicData &cd, service.characteristics()) {
+ Attribute attribute;
+
+ // Characteristic declaration;
+ attribute.handle = ++currentHandle;
+ attribute.groupEndHandle = attribute.handle + 1 + cd.descriptors().count();
+ attribute.type = QBluetoothUuid(GATT_CHARACTERISTIC);
+ attribute.properties = QLowEnergyCharacteristic::Read;
+ attribute.value.resize(1 + sizeof(QLowEnergyHandle) + cd.uuid().minimumSize());
+ char *valueData = attribute.value.data();
+ putDataAndIncrement(static_cast<quint8>(cd.properties()), valueData);
+ putDataAndIncrement(QLowEnergyHandle(currentHandle + 1), valueData);
+ putDataAndIncrement(cd.uuid(), valueData);
+ localAttributes[attribute.handle] = attribute;
+
+ // Characteristic value declaration.
+ attribute.handle = ++currentHandle;
+ attribute.groupEndHandle = attribute.handle;
+ attribute.type = cd.uuid();
+ attribute.properties = cd.properties();
+ attribute.value = cd.value();
+ localAttributes[attribute.handle] = attribute;
+
+ foreach (const QLowEnergyDescriptorData &dd, cd.descriptors()) {
+ attribute.handle = ++currentHandle;
+ attribute.groupEndHandle = attribute.handle;
+ attribute.type = dd.uuid();
+ attribute.properties = QLowEnergyCharacteristic::Read; // TODO: The different descriptor types have different read/write capabilities.
+ attribute.value = dd.value();
+ localAttributes[attribute.handle] = attribute;
+ }
+ }
+ serviceAttribute.groupEndHandle = currentHandle;
+ localAttributes[serviceAttribute.handle] = serviceAttribute;
+}
+
QT_END_NAMESPACE
diff --git a/src/bluetooth/qlowenergycontroller_osx.mm b/src/bluetooth/qlowenergycontroller_osx.mm
index dca245a8..6a39c002 100644
--- a/src/bluetooth/qlowenergycontroller_osx.mm
+++ b/src/bluetooth/qlowenergycontroller_osx.mm
@@ -1038,4 +1038,13 @@ void QLowEnergyController::stopAdvertising()
qCWarning(QT_BT_OSX) << "LE advertising not implemented for OS X";
}
+QLowEnergyService *QLowEnergyController::addService(const QLowEnergyServiceData &service,
+ QObject *parent)
+{
+ Q_UNUSED(service);
+ Q_UNUSED(parent);
+ qCWarning(QT_BT_OSX) << "GATT server functionality not implemented for OS X";
+ return nullptr;
+}
+
QT_END_NAMESPACE
diff --git a/src/bluetooth/qlowenergycontroller_p.cpp b/src/bluetooth/qlowenergycontroller_p.cpp
index 4ee1e50f..4795c373 100644
--- a/src/bluetooth/qlowenergycontroller_p.cpp
+++ b/src/bluetooth/qlowenergycontroller_p.cpp
@@ -38,7 +38,8 @@ QT_BEGIN_NAMESPACE
QLowEnergyControllerPrivate::QLowEnergyControllerPrivate()
: QObject(),
state(QLowEnergyController::UnconnectedState),
- error(QLowEnergyController::NoError)
+ error(QLowEnergyController::NoError),
+ lastLocalHandle(0)
{
}
@@ -114,4 +115,9 @@ void QLowEnergyControllerPrivate::stopAdvertising()
{
}
+void QLowEnergyControllerPrivate::addToGenericAttributeList(const QLowEnergyServiceData &/* service */,
+ QLowEnergyHandle /* startHandle */)
+{
+}
+
QT_END_NAMESPACE
diff --git a/src/bluetooth/qlowenergycontroller_p.h b/src/bluetooth/qlowenergycontroller_p.h
index d91c2c73..912e7906 100644
--- a/src/bluetooth/qlowenergycontroller_p.h
+++ b/src/bluetooth/qlowenergycontroller_p.h
@@ -66,6 +66,7 @@ QT_END_NAMESPACE
#include <qglobal.h>
#include <QtCore/QQueue>
#include <QtBluetooth/qbluetooth.h>
+#include <QtBluetooth/qlowenergycharacteristic.h>
#include "qlowenergycontroller.h"
#include "qlowenergyserviceprivate_p.h"
@@ -76,8 +77,12 @@ QT_END_NAMESPACE
#include "android/lowenergynotificationhub_p.h"
#endif
+#include <functional>
+
QT_BEGIN_NAMESPACE
+class QLowEnergyServiceData;
+
#if defined(QT_BLUEZ_BLUETOOTH) && !defined(QT_BLUEZ_NO_BTLE)
class HciManager;
class QSocketNotifier;
@@ -146,6 +151,8 @@ public:
const QLowEnergyHandle descriptorHandle,
const QByteArray &newValue);
+ void addToGenericAttributeList(const QLowEnergyServiceData &service,
+ QLowEnergyHandle startHandle);
QBluetoothAddress remoteDevice;
QBluetoothAddress localAdapter;
@@ -160,6 +167,21 @@ public:
// list of all found service uuids
ServiceDataMap serviceList;
+ QLowEnergyHandle lastLocalHandle;
+ ServiceDataMap localServices;
+
+ struct Attribute {
+ Attribute() : handle(0) {}
+
+ QLowEnergyHandle handle;
+ QLowEnergyHandle groupEndHandle;
+ QLowEnergyCharacteristic::PropertyTypes properties;
+ QBluetoothUuid type;
+ QByteArray value;
+ // TODO: authentication/authorization requirements
+ };
+ QVector<Attribute> localAttributes;
+
QLowEnergyController::RemoteAddressType addressType;
private:
@@ -251,6 +273,8 @@ private:
};
+Q_DECLARE_TYPEINFO(QLowEnergyControllerPrivate::Attribute, Q_MOVABLE_TYPE);
+
QT_END_NAMESPACE
#endif // QT_OSX_BLUETOOTH || QT_IOS_BLUETOOTH
diff --git a/src/bluetooth/qlowenergydescriptordata.cpp b/src/bluetooth/qlowenergydescriptordata.cpp
new file mode 100644
index 00000000..40bb571c
--- /dev/null
+++ b/src/bluetooth/qlowenergydescriptordata.cpp
@@ -0,0 +1,149 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the QtBluetooth module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL21$
+** 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 Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** As a special exception, The Qt Company gives you certain additional
+** rights. These rights are described in The Qt Company LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qlowenergydescriptordata.h"
+
+#include <QtCore/qbytearray.h>
+
+QT_BEGIN_NAMESPACE
+
+struct QLowEnergyDescriptorDataPrivate : public QSharedData
+{
+ QBluetoothUuid uuid;
+ QByteArray value;
+};
+
+/*!
+ \since 5.7
+ \class QLowEnergyDescriptorData
+ \brief The QLowEnergyDescriptorData class is used to create GATT service data.
+ \inmodule QtBluetooth
+ \ingroup shared
+
+ An object of this class provides a descriptor to be added to a
+ \l QLowEnergyCharacteristicData object via \l QLowEnergyCharacteristicData::addDescriptor().
+
+ \sa QLowEnergyCharacteristicData
+ \sa QLowEnergyServiceData
+ \sa QLowEnergyController::addService
+*/
+
+/*! Creates a new invalid object of this class. */
+QLowEnergyDescriptorData::QLowEnergyDescriptorData() : d(new QLowEnergyDescriptorDataPrivate)
+{
+}
+
+/*!
+ Creates a new object of this class with UUID and value being provided by \a uuid and \a value,
+ respectively.
+ */
+QLowEnergyDescriptorData::QLowEnergyDescriptorData(const QBluetoothUuid &uuid,
+ const QByteArray &value)
+ : d(new QLowEnergyDescriptorDataPrivate)
+{
+ setUuid(uuid);
+ setValue(value);
+}
+
+/*! Constructs a new object of this class that is a copy of \a other. */
+QLowEnergyDescriptorData::QLowEnergyDescriptorData(const QLowEnergyDescriptorData &other)
+ : d(other.d)
+{
+}
+
+/*! Destroys this object. */
+QLowEnergyDescriptorData::~QLowEnergyDescriptorData()
+{
+}
+
+/*! Makes this object a copy of \a other and returns the new value of this object. */
+QLowEnergyDescriptorData &QLowEnergyDescriptorData::operator=(const QLowEnergyDescriptorData &other)
+{
+ d = other.d;
+ return *this;
+}
+
+/*! Returns the value of this descriptor. */
+QByteArray QLowEnergyDescriptorData::value() const
+{
+ return d->value;
+}
+
+/*!
+ Sets the value of this descriptor. It will be sent to a peer device exactly the way it is
+ provided here, so callers need to take care of things such as endianness.
+ */
+void QLowEnergyDescriptorData::setValue(const QByteArray &value)
+{
+ d->value = value;
+}
+
+/*! Returns the UUID of this descriptor. */
+QBluetoothUuid QLowEnergyDescriptorData::uuid() const
+{
+ return d->uuid;
+}
+
+/*! Sets the UUID of this descriptor to \a uuid. */
+void QLowEnergyDescriptorData::setUuid(const QBluetoothUuid &uuid)
+{
+ d->uuid = uuid;
+}
+
+/*! Returns true if and only if this object has a non-null UUID. */
+bool QLowEnergyDescriptorData::isValid() const
+{
+ return !uuid().isNull();
+}
+
+/*!
+ \fn void QLowEnergyDescriptorData::swap(QLowEnergyDescriptorData &other)
+ Swaps this object with \a other.
+ */
+
+/*!
+ Returns \c true if \a d1 and \a d2 are equal with respect to their public state,
+ otherwise returns \c false.
+ */
+bool operator==(const QLowEnergyDescriptorData &d1, const QLowEnergyDescriptorData &d2)
+{
+ return d1.d == d2.d || (d1.uuid() == d2.uuid() && d1.value() == d2.value());
+}
+
+/*!
+ \fn bool operator!=(const QLowEnergyDescriptorData &d1, const QLowEnergyDescriptorData &d2)
+ Returns \c true if \a d1 and \a d2 are not equal with respect to their public state,
+ otherwise returns \c false.
+ */
+
+QT_END_NAMESPACE
diff --git a/src/bluetooth/qlowenergydescriptordata.h b/src/bluetooth/qlowenergydescriptordata.h
new file mode 100644
index 00000000..189b73e4
--- /dev/null
+++ b/src/bluetooth/qlowenergydescriptordata.h
@@ -0,0 +1,87 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the QtBluetooth module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL21$
+** 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 Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** As a special exception, The Qt Company gives you certain additional
+** rights. These rights are described in The Qt Company LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QLOWENERGYDESCRIPTORDATA_H
+#define QLOWENERGYDESCRIPTORDATA_H
+
+#include <QtBluetooth/qbluetooth.h>
+#include <QtBluetooth/qbluetoothuuid.h>
+#include <QtCore/qshareddata.h>
+
+QT_BEGIN_NAMESPACE
+
+class QByteArray;
+struct QLowEnergyDescriptorDataPrivate;
+
+class Q_BLUETOOTH_EXPORT QLowEnergyDescriptorData
+{
+ friend Q_BLUETOOTH_EXPORT bool operator==(const QLowEnergyDescriptorData &d1,
+ const QLowEnergyDescriptorData &d12);
+public:
+ QLowEnergyDescriptorData();
+ QLowEnergyDescriptorData(const QBluetoothUuid &uuid,
+ const QByteArray &value);
+ QLowEnergyDescriptorData(const QLowEnergyDescriptorData &other);
+ ~QLowEnergyDescriptorData();
+
+ QLowEnergyDescriptorData &operator=(const QLowEnergyDescriptorData &other);
+
+ QByteArray value() const;
+ void setValue(const QByteArray &value);
+
+ QBluetoothUuid uuid() const;
+ void setUuid(const QBluetoothUuid &uuid);
+
+ bool isValid() const;
+
+ // TODO: read permissions, write permissions, authentication/authorization (only applicable for some descriptors)
+
+ void swap(QLowEnergyDescriptorData &other) Q_DECL_NOTHROW { qSwap(d, other.d); }
+
+private:
+ QSharedDataPointer<QLowEnergyDescriptorDataPrivate> d;
+};
+
+Q_BLUETOOTH_EXPORT bool operator==(const QLowEnergyDescriptorData &d1,
+ const QLowEnergyDescriptorData &d2);
+
+inline bool operator!=(const QLowEnergyDescriptorData &d1, const QLowEnergyDescriptorData &d2)
+{
+ return !(d1 == d2);
+}
+
+Q_DECLARE_SHARED(QLowEnergyDescriptorData)
+
+QT_END_NAMESPACE
+
+#endif // Include guard.
diff --git a/src/bluetooth/qlowenergyservice.h b/src/bluetooth/qlowenergyservice.h
index 524650c9..1dd35ab1 100644
--- a/src/bluetooth/qlowenergyservice.h
+++ b/src/bluetooth/qlowenergyservice.h
@@ -126,6 +126,7 @@ private:
// QLowEnergyController is the factory for this class
friend class QLowEnergyController;
+ friend class QLowEnergyControllerPrivate;
QLowEnergyService(QSharedPointer<QLowEnergyServicePrivate> p,
QObject *parent = 0);
};
diff --git a/src/bluetooth/qlowenergyservicedata.cpp b/src/bluetooth/qlowenergyservicedata.cpp
new file mode 100644
index 00000000..539f8472
--- /dev/null
+++ b/src/bluetooth/qlowenergyservicedata.cpp
@@ -0,0 +1,209 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the QtBluetooth module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL21$
+** 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 Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** As a special exception, The Qt Company gives you certain additional
+** rights. These rights are described in The Qt Company LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qlowenergyservicedata.h"
+
+#include "qlowenergycharacteristicdata.h"
+
+#include <QtCore/qloggingcategory.h>
+
+QT_BEGIN_NAMESPACE
+
+Q_DECLARE_LOGGING_CATEGORY(QT_BT)
+
+struct QLowEnergyServiceDataPrivate : public QSharedData
+{
+ QLowEnergyServiceDataPrivate() : type(QLowEnergyServiceData::ServiceTypePrimary) {}
+
+ QLowEnergyServiceData::ServiceType type;
+ QBluetoothUuid uuid;
+ QList<QLowEnergyService *> includedServices;
+ QList<QLowEnergyCharacteristicData> characteristics;
+};
+
+
+/*!
+ \since 5.7
+ \class QLowEnergyServiceData
+ \brief The QLowEnergyServiceData class is used to set up GATT service data.
+ \inmodule QtBluetooth
+ \ingroup shared
+
+ An Object of this class provides a service to be added to a GATT server via
+ \l QLowEnergyController::addService().
+*/
+
+/*!
+ \enum QLowEnergyServiceData::ServiceType
+ The type of GATT service.
+
+ \value ServiceTypePrimary
+ The service is a primary service.
+ \value ServiceTypeSecondary
+ The service is a secondary service. Secondary services are included by other services
+ to implement some higher-level functionality.
+ */
+
+/*! Creates a new invalid object of this class. */
+QLowEnergyServiceData::QLowEnergyServiceData() : d(new QLowEnergyServiceDataPrivate)
+{
+}
+
+/*! Constructs a new object of this class that is a copy of \a other. */
+QLowEnergyServiceData::QLowEnergyServiceData(const QLowEnergyServiceData &other) : d(other.d)
+{
+}
+
+/*! Destroys this object. */
+QLowEnergyServiceData::~QLowEnergyServiceData()
+{
+}
+
+/*! Makes this object a copy of \a other and returns the new value of this object. */
+QLowEnergyServiceData &QLowEnergyServiceData::operator=(const QLowEnergyServiceData &other)
+{
+ d = other.d;
+ return *this;
+}
+
+/*! Returns the type of this service. */
+QLowEnergyServiceData::ServiceType QLowEnergyServiceData::type() const
+{
+ return d->type;
+}
+
+/*! Sets the type of this service to \a type. */
+void QLowEnergyServiceData::setType(ServiceType type)
+{
+ d->type = type;
+}
+
+/*! Returns the UUID of this service. */
+QBluetoothUuid QLowEnergyServiceData::uuid() const
+{
+ return d->uuid;
+}
+
+/*! Sets the UUID of this service to \a uuid. */
+void QLowEnergyServiceData::setUuid(const QBluetoothUuid &uuid)
+{
+ d->uuid = uuid;
+}
+
+/*! Returns the list of included services. */
+QList<QLowEnergyService *> QLowEnergyServiceData::includedServices() const
+{
+ return d->includedServices;
+}
+
+/*!
+ Sets the list of included services to \a services.
+ All objects in this list must have been returned from a call to
+ \l QLowEnergyController::addService.
+ \sa addIncludedService()
+*/
+void QLowEnergyServiceData::setIncludedServices(const QList<QLowEnergyService *> &services)
+{
+ d->includedServices = services;
+}
+
+/*!
+ Adds \a service to the list of included services.
+ The \a service object must have been returned from a call to
+ \l QLowEnergyController::addService.
+ \sa setIncludedServices()
+*/
+void QLowEnergyServiceData::addIncludedService(QLowEnergyService *service)
+{
+ d->includedServices << service;
+}
+
+/*! Returns the list of characteristics. */
+QList<QLowEnergyCharacteristicData> QLowEnergyServiceData::characteristics() const
+{
+ return d->characteristics;
+}
+
+/*!
+ Sets the list of characteristics to \a characteristics.
+ Only valid characteristics are considered.
+ \sa addCharacteristic()
+ */
+void QLowEnergyServiceData::setCharacteristics(const QList<QLowEnergyCharacteristicData> &characteristics)
+{
+ foreach (const QLowEnergyCharacteristicData &cd, characteristics)
+ addCharacteristic(cd);
+}
+
+/*!
+ Adds \a characteristic to the list of characteristics, if it is valid.
+ \sa setCharacteristics()
+ */
+void QLowEnergyServiceData::addCharacteristic(const QLowEnergyCharacteristicData &characteristic)
+{
+ if (characteristic.isValid())
+ d->characteristics << characteristic;
+ else
+ qCWarning(QT_BT) << "not adding invalid characteristic to service";
+}
+
+/*! Returns \c true if this service is has a non-null UUID. */
+bool QLowEnergyServiceData::isValid() const
+{
+ return !uuid().isNull();
+}
+
+/*!
+ \fn void QLowEnergyServiceData::swap(QLowEnergyServiceData &other)
+ Swaps this object with \a other.
+ */
+
+/*!
+ Returns \c true if \a sd1 and \a sd2 are equal with respect to their public state,
+ otherwise returns \c false.
+ */
+bool operator==(const QLowEnergyServiceData sd1, const QLowEnergyServiceData &sd2)
+{
+ return sd1.d == sd2.d || (sd1.type() == sd2.type() && sd1.uuid() == sd2.uuid()
+ && sd1.includedServices() == sd2.includedServices()
+ && sd1.characteristics() == sd2.characteristics());
+}
+
+/*!
+ \fn bool operator!=(const QLowEnergyServiceData &sd1,
+ const QLowEnergyServiceData &sd2)
+ Returns \c true if \a sd1 and \a sd2 are not equal with respect to their public state,
+ otherwise returns \c false.
+ */
+
+QT_END_NAMESPACE
diff --git a/src/bluetooth/qlowenergyservicedata.h b/src/bluetooth/qlowenergyservicedata.h
new file mode 100644
index 00000000..c60dd8ee
--- /dev/null
+++ b/src/bluetooth/qlowenergyservicedata.h
@@ -0,0 +1,92 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the QtBluetooth module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL21$
+** 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 Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** As a special exception, The Qt Company gives you certain additional
+** rights. These rights are described in The Qt Company LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QLOWENERGYSERVICEDATA_H
+#define QLOWENERGYSERVICEDATA_H
+
+#include <QtBluetooth/qbluetoothglobal.h>
+#include <QtCore/qshareddata.h>
+
+QT_BEGIN_NAMESPACE
+
+class QBluetoothUuid;
+class QLowEnergyCharacteristicData;
+class QLowEnergyService;
+struct QLowEnergyServiceDataPrivate;
+
+class Q_BLUETOOTH_EXPORT QLowEnergyServiceData
+{
+ friend Q_BLUETOOTH_EXPORT bool operator==(const QLowEnergyServiceData sd1,
+ const QLowEnergyServiceData &sd2);
+public:
+ QLowEnergyServiceData();
+ QLowEnergyServiceData(const QLowEnergyServiceData &other);
+ ~QLowEnergyServiceData();
+
+ QLowEnergyServiceData &operator=(const QLowEnergyServiceData &other);
+
+ enum ServiceType { ServiceTypePrimary = 0x2800, ServiceTypeSecondary = 0x2801 };
+ ServiceType type() const;
+ void setType(ServiceType type);
+
+ QBluetoothUuid uuid() const;
+ void setUuid(const QBluetoothUuid &uuid);
+
+ QList<QLowEnergyService *> includedServices() const;
+ void setIncludedServices(const QList<QLowEnergyService *> &services);
+ void addIncludedService(QLowEnergyService *service);
+
+ QList<QLowEnergyCharacteristicData> characteristics() const;
+ void setCharacteristics(const QList<QLowEnergyCharacteristicData> &characteristics);
+ void addCharacteristic(const QLowEnergyCharacteristicData &characteristic);
+
+ bool isValid() const;
+
+ void swap(QLowEnergyServiceData &other) Q_DECL_NOTHROW { qSwap(d, other.d); }
+
+private:
+ QSharedDataPointer<QLowEnergyServiceDataPrivate> d;
+};
+
+Q_BLUETOOTH_EXPORT bool operator==(const QLowEnergyServiceData sd1,
+ const QLowEnergyServiceData &sd2);
+inline bool operator!=(const QLowEnergyServiceData sd1, const QLowEnergyServiceData &sd2)
+{
+ return !(sd1 == sd2);
+}
+
+Q_DECLARE_SHARED(QLowEnergyServiceData)
+
+QT_END_NAMESPACE
+
+#endif // Include guard.