diff options
author | Alex Blasche <alexander.blasche@qt.io> | 2017-10-24 16:46:03 +0200 |
---|---|---|
committer | Alex Blasche <alexander.blasche@qt.io> | 2017-11-03 13:08:45 +0000 |
commit | 59ae3cc2ac7baee7e9df1e6ceffcfc882fbe6121 (patch) | |
tree | 1c267a06201507d10dd4571942089b56c2d617f5 /src | |
parent | 4ab8bd20b590f96763dd93f4436327042fbd27da (diff) |
Introduce Base class for QLowEnergyControllerPrivate
This permits alternative implementations selectable at runtime.
Currently this is only used by Bluez.
Change-Id: I3ddeb7f888f3b09bdc62f10d5b9a36320500f329
Reviewed-by: Timur Pocheptsov <timur.pocheptsov@qt.io>
Diffstat (limited to 'src')
-rw-r--r-- | src/bluetooth/bluetooth.pro | 14 | ||||
-rw-r--r-- | src/bluetooth/bluez/bluez5_helper.cpp | 6 | ||||
-rw-r--r-- | src/bluetooth/bluez/bluez5_helper_p.h | 1 | ||||
-rw-r--r-- | src/bluetooth/qlowenergycontroller.cpp | 146 | ||||
-rw-r--r-- | src/bluetooth/qlowenergycontroller.h | 4 | ||||
-rw-r--r-- | src/bluetooth/qlowenergycontroller_android.cpp | 4 | ||||
-rw-r--r-- | src/bluetooth/qlowenergycontroller_bluez.cpp | 4 | ||||
-rw-r--r-- | src/bluetooth/qlowenergycontroller_bluezdbus.cpp | 140 | ||||
-rw-r--r-- | src/bluetooth/qlowenergycontroller_bluezdbus_p.h | 113 | ||||
-rw-r--r-- | src/bluetooth/qlowenergycontroller_p.cpp | 4 | ||||
-rw-r--r-- | src/bluetooth/qlowenergycontroller_p.h | 60 | ||||
-rw-r--r-- | src/bluetooth/qlowenergycontroller_winrt.cpp | 4 | ||||
-rw-r--r-- | src/bluetooth/qlowenergycontrollerbase.cpp | 144 | ||||
-rw-r--r-- | src/bluetooth/qlowenergycontrollerbase_p.h | 159 | ||||
-rw-r--r-- | src/bluetooth/qlowenergyserviceprivate.cpp | 2 | ||||
-rw-r--r-- | src/bluetooth/qlowenergyserviceprivate_p.h | 6 |
16 files changed, 654 insertions, 157 deletions
diff --git a/src/bluetooth/bluetooth.pro b/src/bluetooth/bluetooth.pro index 1ef7406b..fe530c81 100644 --- a/src/bluetooth/bluetooth.pro +++ b/src/bluetooth/bluetooth.pro @@ -47,6 +47,7 @@ PRIVATE_HEADERS += \ qprivatelinearbuffer_p.h \ qbluetoothlocaldevice_p.h \ qlowenergycontroller_p.h \ + qlowenergycontrollerbase_p.h \ qlowenergyserviceprivate_p.h \ qleadvertiser_p.h \ lecmaccalculator_p.h @@ -76,6 +77,7 @@ SOURCES += \ qlowenergydescriptor.cpp \ qlowenergydescriptordata.cpp \ qlowenergycontroller.cpp \ + qlowenergycontrollerbase.cpp \ qlowenergyserviceprivate.cpp win32 { @@ -107,7 +109,11 @@ qtConfig(bluez) { SOURCES += \ qleadvertiser_bluez.cpp \ qlowenergycontroller_bluez.cpp \ - lecmaccalculator.cpp + lecmaccalculator.cpp \ + qlowenergycontroller_bluezdbus.cpp + + PRIVATE_HEADERS += qlowenergycontroller_bluezdbus_p.h + qtConfig(linux_crypto_api): DEFINES += CONFIG_LINUX_CRYPTO_API } else { DEFINES += QT_BLUEZ_NO_BTLE @@ -160,6 +166,8 @@ qtConfig(bluez) { qbluetoothtransferreply_osx_p.h \ qlowenergycontroller_osx_p.h + PRIVATE_HEADERS -= qlowenergycontrollerbase_p.h + SOURCES -= qbluetoothdevicediscoveryagent.cpp SOURCES -= qbluetoothserviceinfo.cpp SOURCES -= qbluetoothservicediscoveryagent.cpp @@ -169,6 +177,7 @@ qtConfig(bluez) { SOURCES -= qlowenergyservice.cpp SOURCES -= qlowenergycontroller.cpp SOURCES -= qlowenergycontroller_p.cpp + SOURCES -= qlowenergycontrollerbase.cpp } else:ios|tvos { DEFINES += QT_IOS_BLUETOOTH LIBS_PRIVATE += -framework Foundation -framework CoreBluetooth @@ -181,6 +190,8 @@ qtConfig(bluez) { PRIVATE_HEADERS += \ qlowenergycontroller_osx_p.h + PRIVATE_HEADERS -= qlowenergycontrollerbase_p.h + include(osx/osxbt.pri) SOURCES += \ qbluetoothlocaldevice_p.cpp \ @@ -192,6 +203,7 @@ qtConfig(bluez) { SOURCES -= qbluetoothdevicediscoveryagent.cpp SOURCES -= qlowenergyservice.cpp SOURCES -= qlowenergycontroller.cpp + SOURCES -= qlowenergycontrollerbase.cpp } else: qtConfig(winrt_bt) { DEFINES += QT_WINRT_BLUETOOTH !winrt { diff --git a/src/bluetooth/bluez/bluez5_helper.cpp b/src/bluetooth/bluez/bluez5_helper.cpp index de41003f..ffe9a58d 100644 --- a/src/bluetooth/bluez/bluez5_helper.cpp +++ b/src/bluetooth/bluez/bluez5_helper.cpp @@ -97,6 +97,12 @@ bool isBluez5() return (*bluezVersion() == BluezVersion5); } +bool isBluez5DbusGatt() +{ + //TODO implement + return false; +} + struct AdapterData { public: diff --git a/src/bluetooth/bluez/bluez5_helper_p.h b/src/bluetooth/bluez/bluez5_helper_p.h index 2d72caf1..6aeed11d 100644 --- a/src/bluetooth/bluez/bluez5_helper_p.h +++ b/src/bluetooth/bluez/bluez5_helper_p.h @@ -66,6 +66,7 @@ Q_DECLARE_METATYPE(ManagedObjectList) QT_BEGIN_NAMESPACE bool isBluez5(); +bool isBluez5DbusGatt(); QString sanitizeNameForDBus(const QString& text); diff --git a/src/bluetooth/qlowenergycontroller.cpp b/src/bluetooth/qlowenergycontroller.cpp index 7cd80072..4d0d78b6 100644 --- a/src/bluetooth/qlowenergycontroller.cpp +++ b/src/bluetooth/qlowenergycontroller.cpp @@ -48,6 +48,12 @@ #include <QtBluetooth/QBluetoothLocalDevice> #include <QtCore/QLoggingCategory> + +#if QT_CONFIG(bluez) && !defined(QT_BLUEZ_NO_BTLE) +#include "bluez/bluez5_helper_p.h" +#include "qlowenergycontroller_bluezdbus_p.h" +#endif + #include <algorithm> QT_BEGIN_NAMESPACE @@ -278,79 +284,6 @@ void registerQLowEnergyControllerMetaType() } } - -void QLowEnergyControllerPrivate::setError( - QLowEnergyController::Error newError) -{ - Q_Q(QLowEnergyController); - error = newError; - - switch (newError) { - case QLowEnergyController::UnknownRemoteDeviceError: - errorString = QLowEnergyController::tr("Remote device cannot be found"); - break; - case QLowEnergyController::InvalidBluetoothAdapterError: - errorString = QLowEnergyController::tr("Cannot find local adapter"); - break; - case QLowEnergyController::NetworkError: - errorString = QLowEnergyController::tr("Error occurred during connection I/O"); - break; - case QLowEnergyController::ConnectionError: - errorString = QLowEnergyController::tr("Error occurred trying to connect to remote device."); - break; - case QLowEnergyController::AdvertisingError: - errorString = QLowEnergyController::tr("Error occurred trying to start advertising"); - break; - case QLowEnergyController::RemoteHostClosedError: - errorString = QLowEnergyController::tr("Remote device closed the connection"); - break; - case QLowEnergyController::NoError: - return; - default: - case QLowEnergyController::UnknownError: - errorString = QLowEnergyController::tr("Unknown Error"); - break; - } - - emit q->error(newError); -} - -bool QLowEnergyControllerPrivate::isValidLocalAdapter() -{ -#ifdef QT_WINRT_BLUETOOTH - return true; -#endif - if (localAdapter.isNull()) - return false; - - const QList<QBluetoothHostInfo> foundAdapters = QBluetoothLocalDevice::allDevices(); - bool adapterFound = false; - - foreach (const QBluetoothHostInfo &info, foundAdapters) { - if (info.address() == localAdapter) { - adapterFound = true; - break; - } - } - - return adapterFound; -} - -void QLowEnergyControllerPrivate::setState( - QLowEnergyController::ControllerState newState) -{ - Q_Q(QLowEnergyController); - if (state == newState) - return; - - state = newState; - if (state == QLowEnergyController::UnconnectedState - && role == QLowEnergyController::PeripheralRole) { - remoteDevice.clear(); - } - emit q->stateChanged(state); -} - void QLowEnergyControllerPrivate::invalidateServices() { foreach (const QSharedPointer<QLowEnergyServicePrivate> service, serviceList.values()) { @@ -361,20 +294,6 @@ void QLowEnergyControllerPrivate::invalidateServices() serviceList.clear(); } -QSharedPointer<QLowEnergyServicePrivate> QLowEnergyControllerPrivate::serviceForHandle( - QLowEnergyHandle handle) -{ - ServiceDataMap ¤tList = serviceList; - if (role == QLowEnergyController::PeripheralRole) - currentList = localServices; - - const QList<QSharedPointer<QLowEnergyServicePrivate>> values = currentList.values(); - for (auto service: values) - if (service->startHandle <= handle && handle <= service->endHandle) - return service; - - return QSharedPointer<QLowEnergyServicePrivate>(); -} /*! Returns a valid characteristic if the given handle is the @@ -497,9 +416,19 @@ quint16 QLowEnergyControllerPrivate::updateValueOfDescriptor( QLowEnergyController::QLowEnergyController( const QBluetoothAddress &remoteDevice, QObject *parent) - : QObject(parent), d_ptr(new QLowEnergyControllerPrivate()) -{ + : QObject(parent) +{ +#if QT_CONFIG(bluez) && !defined(QT_BLUEZ_NO_BTLE) + if (isBluez5DbusGatt()) + d_ptr = new QLowEnergyControllerPrivateBluezDBus(); + else + d_ptr = new QLowEnergyControllerPrivate(); +#else + d_ptr = new QLowEnergyControllerPrivate(); +#endif + Q_D(QLowEnergyController); + d->q_ptr = this; d->role = CentralRole; d->remoteDevice = remoteDevice; @@ -524,8 +453,17 @@ QLowEnergyController::QLowEnergyController( QLowEnergyController::QLowEnergyController( const QBluetoothDeviceInfo &remoteDeviceInfo, QObject *parent) - : QObject(parent), d_ptr(new QLowEnergyControllerPrivate()) -{ + : QObject(parent) +{ +#if QT_CONFIG(bluez) && !defined(QT_BLUEZ_NO_BTLE) + if (isBluez5DbusGatt()) + d_ptr = new QLowEnergyControllerPrivateBluezDBus(); + else + d_ptr = new QLowEnergyControllerPrivate(); +#else + d_ptr = new QLowEnergyControllerPrivate(); +#endif + Q_D(QLowEnergyController); d->q_ptr = this; d->role = CentralRole; @@ -555,8 +493,17 @@ QLowEnergyController::QLowEnergyController( const QBluetoothAddress &remoteDevice, const QBluetoothAddress &localDevice, QObject *parent) - : QObject(parent), d_ptr(new QLowEnergyControllerPrivate()) -{ + : QObject(parent) +{ +#if QT_CONFIG(bluez) && !defined(QT_BLUEZ_NO_BTLE) + if (isBluez5DbusGatt()) + d_ptr = new QLowEnergyControllerPrivateBluezDBus(); + else + d_ptr = new QLowEnergyControllerPrivate(); +#else + d_ptr = new QLowEnergyControllerPrivate(); +#endif + Q_D(QLowEnergyController); d->q_ptr = this; d->role = CentralRole; @@ -598,8 +545,17 @@ QLowEnergyController *QLowEnergyController::createPeripheral(QObject *parent) } QLowEnergyController::QLowEnergyController(QObject *parent) - : QObject(parent), d_ptr(new QLowEnergyControllerPrivate()) -{ + : QObject(parent) +{ +#if QT_CONFIG(bluez) && !defined(QT_BLUEZ_NO_BTLE) + if (isBluez5DbusGatt()) + d_ptr = new QLowEnergyControllerPrivateBluezDBus(); + else + d_ptr = new QLowEnergyControllerPrivate(); +#else + d_ptr = new QLowEnergyControllerPrivate(); +#endif + Q_D(QLowEnergyController); d->q_ptr = this; d->role = PeripheralRole; diff --git a/src/bluetooth/qlowenergycontroller.h b/src/bluetooth/qlowenergycontroller.h index f9e6ef5d..782d042a 100644 --- a/src/bluetooth/qlowenergycontroller.h +++ b/src/bluetooth/qlowenergycontroller.h @@ -51,7 +51,7 @@ QT_BEGIN_NAMESPACE class QLowEnergyAdvertisingParameters; class QLowEnergyConnectionParameters; -class QLowEnergyControllerPrivate; +class QLowEnergyControllerPrivateBase; class QLowEnergyServiceData; class Q_BLUETOOTH_EXPORT QLowEnergyController : public QObject @@ -152,7 +152,7 @@ private: explicit QLowEnergyController(QObject *parent = nullptr); // For the peripheral role. Q_DECLARE_PRIVATE(QLowEnergyController) - QLowEnergyControllerPrivate *d_ptr; + QLowEnergyControllerPrivateBase *d_ptr; }; QT_END_NAMESPACE diff --git a/src/bluetooth/qlowenergycontroller_android.cpp b/src/bluetooth/qlowenergycontroller_android.cpp index a1decd96..137fbea1 100644 --- a/src/bluetooth/qlowenergycontroller_android.cpp +++ b/src/bluetooth/qlowenergycontroller_android.cpp @@ -70,9 +70,7 @@ static QAndroidJniObject javaUuidfromQtUuid(const QBluetoothUuid& uuid) } QLowEnergyControllerPrivate::QLowEnergyControllerPrivate() - : QObject(), - state(QLowEnergyController::UnconnectedState), - error(QLowEnergyController::NoError), + : QLowEnergyControllerPrivateBase(), hub(0) { registerQLowEnergyControllerMetaType(); diff --git a/src/bluetooth/qlowenergycontroller_bluez.cpp b/src/bluetooth/qlowenergycontroller_bluez.cpp index ca3f7760..1622ffb3 100644 --- a/src/bluetooth/qlowenergycontroller_bluez.cpp +++ b/src/bluetooth/qlowenergycontroller_bluez.cpp @@ -264,9 +264,7 @@ template<> void putDataAndIncrement(const QByteArray &value, char *&dst) } QLowEnergyControllerPrivate::QLowEnergyControllerPrivate() - : QObject(), - state(QLowEnergyController::UnconnectedState), - error(QLowEnergyController::NoError), + : QLowEnergyControllerPrivateBase(), lastLocalHandle(0), l2cpSocket(0), requestPending(false), mtuSize(ATT_DEFAULT_LE_MTU), diff --git a/src/bluetooth/qlowenergycontroller_bluezdbus.cpp b/src/bluetooth/qlowenergycontroller_bluezdbus.cpp new file mode 100644 index 00000000..dc8fc721 --- /dev/null +++ b/src/bluetooth/qlowenergycontroller_bluezdbus.cpp @@ -0,0 +1,140 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtBluetooth module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** 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 https://www.qt.io/terms-conditions. For further +** information use the contact form at https://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 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qlowenergycontroller_bluezdbus_p.h" + + +QT_BEGIN_NAMESPACE + +QLowEnergyControllerPrivateBluezDBus::QLowEnergyControllerPrivateBluezDBus() + : QLowEnergyControllerPrivateBase() +{ +} + +QLowEnergyControllerPrivateBluezDBus::~QLowEnergyControllerPrivateBluezDBus() +{ +} + +void QLowEnergyControllerPrivateBluezDBus::init() +{ +} + +void QLowEnergyControllerPrivateBluezDBus::connectToDevice() +{ + qWarning() << "QLowEnergyControllerPrivateBluezDBus::connectToDevice(): Not implemented"; + //setError(QLowEnergyController::UnknownError); +} + +void QLowEnergyControllerPrivateBluezDBus::disconnectFromDevice() +{ + +} + +void QLowEnergyControllerPrivateBluezDBus::discoverServices() +{ + +} + +void QLowEnergyControllerPrivateBluezDBus::discoverServiceDetails(const QBluetoothUuid &/*service*/) +{ + +} + +void QLowEnergyControllerPrivateBluezDBus::readCharacteristic( + const QSharedPointer<QLowEnergyServicePrivate> /*service*/, + const QLowEnergyHandle /*charHandle*/) +{ + +} + +void QLowEnergyControllerPrivateBluezDBus::readDescriptor( + const QSharedPointer<QLowEnergyServicePrivate> /*service*/, + const QLowEnergyHandle /*charHandle*/, + const QLowEnergyHandle /*descriptorHandle*/) +{ + +} + +void QLowEnergyControllerPrivateBluezDBus::writeCharacteristic( + const QSharedPointer<QLowEnergyServicePrivate> /*service*/, + const QLowEnergyHandle /*charHandle*/, + const QByteArray &/*newValue*/, + QLowEnergyService::WriteMode /*writeMode*/) + { + +} + +void QLowEnergyControllerPrivateBluezDBus::writeDescriptor( + const QSharedPointer<QLowEnergyServicePrivate> /*service*/, + const QLowEnergyHandle /*charHandle*/, + const QLowEnergyHandle /*descriptorHandle*/, + const QByteArray &/*newValue*/) +{ + +} + +void QLowEnergyControllerPrivateBluezDBus::startAdvertising( + const QLowEnergyAdvertisingParameters &/* params */, + const QLowEnergyAdvertisingData &/* advertisingData */, + const QLowEnergyAdvertisingData &/* scanResponseData */) +{ +} + +void QLowEnergyControllerPrivateBluezDBus::stopAdvertising() +{ +} + +void QLowEnergyControllerPrivateBluezDBus::requestConnectionUpdate( + const QLowEnergyConnectionParameters & /* params */) +{ +} + +void QLowEnergyControllerPrivateBluezDBus::addToGenericAttributeList( + const QLowEnergyServiceData &/* service */, + QLowEnergyHandle /* startHandle */) +{ +} + +QLowEnergyService *QLowEnergyControllerPrivateBluezDBus::addServiceHelper( + const QLowEnergyServiceData &/*service*/) +{ + return nullptr; +} + +QT_END_NAMESPACE diff --git a/src/bluetooth/qlowenergycontroller_bluezdbus_p.h b/src/bluetooth/qlowenergycontroller_bluezdbus_p.h new file mode 100644 index 00000000..fb7f3e7a --- /dev/null +++ b/src/bluetooth/qlowenergycontroller_bluezdbus_p.h @@ -0,0 +1,113 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtBluetooth module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** 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 https://www.qt.io/terms-conditions. For further +** information use the contact form at https://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 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QLOWENERGYCONTROLLERPRIVATEDBUS_P_H +#define QLOWENERGYCONTROLLERPRIVATEDBUS_P_H + + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include "qlowenergycontroller.h" +#include "qlowenergycontrollerbase_p.h" + +QT_BEGIN_NAMESPACE + +class QLowEnergyControllerPrivateBluezDBus : public QLowEnergyControllerPrivateBase +{ + Q_OBJECT +public: + QLowEnergyControllerPrivateBluezDBus(); + ~QLowEnergyControllerPrivateBluezDBus(); + + void init() override; + void connectToDevice() override; + void disconnectFromDevice() override; + + void discoverServices() override; + void discoverServiceDetails(const QBluetoothUuid &/*service*/) override; + + void readCharacteristic( + const QSharedPointer<QLowEnergyServicePrivate> /*service*/, + const QLowEnergyHandle /*charHandle*/) override; + void readDescriptor( + const QSharedPointer<QLowEnergyServicePrivate> /*service*/, + const QLowEnergyHandle /*charHandle*/, + const QLowEnergyHandle /*descriptorHandle*/) override; + + void writeCharacteristic( + const QSharedPointer<QLowEnergyServicePrivate> /*service*/, + const QLowEnergyHandle /*charHandle*/, + const QByteArray &/*newValue*/, + QLowEnergyService::WriteMode /*writeMode*/) override; + void writeDescriptor( + const QSharedPointer<QLowEnergyServicePrivate> /*service*/, + const QLowEnergyHandle /*charHandle*/, + const QLowEnergyHandle /*descriptorHandle*/, + const QByteArray &/*newValue*/) override; + + void startAdvertising( + const QLowEnergyAdvertisingParameters &/* params */, + const QLowEnergyAdvertisingData &/* advertisingData */, + const QLowEnergyAdvertisingData &/* scanResponseData */) override; + void stopAdvertising() override; + + void requestConnectionUpdate( + const QLowEnergyConnectionParameters & /* params */) override; + void addToGenericAttributeList( + const QLowEnergyServiceData &/* service */, + QLowEnergyHandle /* startHandle */) override; + + QLowEnergyService *addServiceHelper(const QLowEnergyServiceData &service) override; + + QLowEnergyController::ControllerState state; + QLowEnergyController::Error error; +}; + +QT_END_NAMESPACE + +#endif // QLOWENERGYCONTROLLERPRIVATEDBUS_P_H diff --git a/src/bluetooth/qlowenergycontroller_p.cpp b/src/bluetooth/qlowenergycontroller_p.cpp index 27d16093..5c82c1fe 100644 --- a/src/bluetooth/qlowenergycontroller_p.cpp +++ b/src/bluetooth/qlowenergycontroller_p.cpp @@ -45,9 +45,7 @@ QT_BEGIN_NAMESPACE QLowEnergyControllerPrivate::QLowEnergyControllerPrivate() - : QObject(), - state(QLowEnergyController::UnconnectedState), - error(QLowEnergyController::NoError), + : QLowEnergyControllerPrivateBase(), lastLocalHandle(0) { #ifndef QT_IOS_BLUETOOTH diff --git a/src/bluetooth/qlowenergycontroller_p.h b/src/bluetooth/qlowenergycontroller_p.h index 6e866144..a9bd23fc 100644 --- a/src/bluetooth/qlowenergycontroller_p.h +++ b/src/bluetooth/qlowenergycontroller_p.h @@ -75,7 +75,7 @@ QT_END_NAMESPACE #include <QtBluetooth/qbluetooth.h> #include <QtBluetooth/qlowenergycharacteristic.h> #include "qlowenergycontroller.h" -#include "qlowenergyserviceprivate_p.h" +#include "qlowenergycontrollerbase_p.h" #if QT_CONFIG(bluez) && !defined(QT_BLUEZ_NO_BTLE) #include <QtBluetooth/QBluetoothSocket> @@ -107,47 +107,39 @@ class QWinRTLowEnergyServiceHandler; extern void registerQLowEnergyControllerMetaType(); -typedef QMap<QBluetoothUuid, QSharedPointer<QLowEnergyServicePrivate> > ServiceDataMap; class QLeAdvertiser; -class QLowEnergyControllerPrivate : public QObject +class QLowEnergyControllerPrivate : public QLowEnergyControllerPrivateBase { Q_OBJECT - Q_DECLARE_PUBLIC(QLowEnergyController) public: QLowEnergyControllerPrivate(); ~QLowEnergyControllerPrivate(); - void init(); - - void setError(QLowEnergyController::Error newError); - bool isValidLocalAdapter(); - - void setState(QLowEnergyController::ControllerState newState); + void init() override; - void connectToDevice(); - void disconnectFromDevice(); + void connectToDevice() override; + void disconnectFromDevice() override; - void discoverServices(); + void discoverServices() override; void invalidateServices(); - void discoverServiceDetails(const QBluetoothUuid &service); + void discoverServiceDetails(const QBluetoothUuid &service) override; void startAdvertising(const QLowEnergyAdvertisingParameters ¶ms, const QLowEnergyAdvertisingData &advertisingData, - const QLowEnergyAdvertisingData &scanResponseData); - void stopAdvertising(); + const QLowEnergyAdvertisingData &scanResponseData) override; + void stopAdvertising() override; - void requestConnectionUpdate(const QLowEnergyConnectionParameters ¶ms); + void requestConnectionUpdate(const QLowEnergyConnectionParameters ¶ms) override; // misc helpers - QSharedPointer<QLowEnergyServicePrivate> serviceForHandle( - QLowEnergyHandle handle); + QLowEnergyCharacteristic characteristicForHandle( QLowEnergyHandle handle); QLowEnergyDescriptor descriptorForHandle( QLowEnergyHandle handle); - QLowEnergyService *addServiceHelper(const QLowEnergyServiceData &service); + QLowEnergyService *addServiceHelper(const QLowEnergyServiceData &service) override; quint16 updateValueOfCharacteristic(QLowEnergyHandle charHandle, @@ -160,39 +152,25 @@ public: // read data void readCharacteristic(const QSharedPointer<QLowEnergyServicePrivate> service, - const QLowEnergyHandle charHandle); + const QLowEnergyHandle charHandle) override; void readDescriptor(const QSharedPointer<QLowEnergyServicePrivate> service, const QLowEnergyHandle charHandle, - const QLowEnergyHandle descriptorHandle); + const QLowEnergyHandle descriptorHandle) override; // write data void writeCharacteristic(const QSharedPointer<QLowEnergyServicePrivate> service, const QLowEnergyHandle charHandle, - const QByteArray &newValue, QLowEnergyService::WriteMode mode); + const QByteArray &newValue, QLowEnergyService::WriteMode mode) override; void writeDescriptor(const QSharedPointer<QLowEnergyServicePrivate> service, const QLowEnergyHandle charHandle, const QLowEnergyHandle descriptorHandle, - const QByteArray &newValue); + const QByteArray &newValue) override; void addToGenericAttributeList(const QLowEnergyServiceData &service, - QLowEnergyHandle startHandle); + QLowEnergyHandle startHandle) override; - QBluetoothAddress remoteDevice; - QBluetoothAddress localAdapter; - QLowEnergyController::Role role; - - QString remoteName; - - QLowEnergyController::ControllerState state; - QLowEnergyController::Error error; - QString errorString; - - // list of all found service uuids on remote device - ServiceDataMap serviceList; QLowEnergyHandle lastLocalHandle; - // list of all service uuids on local peripheral device - ServiceDataMap localServices; struct Attribute { Attribute() : handle(0) {} @@ -209,8 +187,6 @@ public: }; QVector<Attribute> localAttributes; - QLowEnergyController::RemoteAddressType addressType; - private: #if QT_CONFIG(bluez) && !defined(QT_BLUEZ_NO_BTLE) quint16 connectionHandle = 0; @@ -488,8 +464,6 @@ private: void obtainIncludedServices(QSharedPointer<QLowEnergyServicePrivate> servicePointer, Microsoft::WRL::ComPtr<ABI::Windows::Devices::Bluetooth::GenericAttributeProfile::IGattDeviceService> nativeService); #endif -private: - QLowEnergyController *q_ptr; }; diff --git a/src/bluetooth/qlowenergycontroller_winrt.cpp b/src/bluetooth/qlowenergycontroller_winrt.cpp index 62b8a9d3..37195bad 100644 --- a/src/bluetooth/qlowenergycontroller_winrt.cpp +++ b/src/bluetooth/qlowenergycontroller_winrt.cpp @@ -275,9 +275,7 @@ signals: }; QLowEnergyControllerPrivate::QLowEnergyControllerPrivate() - : QObject(), - state(QLowEnergyController::UnconnectedState), - error(QLowEnergyController::NoError) + : QLowEnergyControllerPrivateBase() { qCDebug(QT_BT_WINRT) << __FUNCTION__; diff --git a/src/bluetooth/qlowenergycontrollerbase.cpp b/src/bluetooth/qlowenergycontrollerbase.cpp new file mode 100644 index 00000000..5e9228e2 --- /dev/null +++ b/src/bluetooth/qlowenergycontrollerbase.cpp @@ -0,0 +1,144 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtBluetooth module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** 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 https://www.qt.io/terms-conditions. For further +** information use the contact form at https://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 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qlowenergycontrollerbase_p.h" + +#include <QtBluetooth/QBluetoothLocalDevice> +#include <QtBluetooth/QLowEnergyServiceData> + +QT_BEGIN_NAMESPACE + +QLowEnergyControllerPrivateBase::QLowEnergyControllerPrivateBase() + : QObject() +{ +} + +QLowEnergyControllerPrivateBase::~QLowEnergyControllerPrivateBase() +{ +} + +bool QLowEnergyControllerPrivateBase::isValidLocalAdapter() +{ +#ifdef QT_WINRT_BLUETOOTH + return true; +#endif + if (localAdapter.isNull()) + return false; + + const QList<QBluetoothHostInfo> foundAdapters = QBluetoothLocalDevice::allDevices(); + bool adapterFound = false; + + foreach (const QBluetoothHostInfo &info, foundAdapters) { + if (info.address() == localAdapter) { + adapterFound = true; + break; + } + } + + return adapterFound; +} + + +void QLowEnergyControllerPrivateBase::setError( + QLowEnergyController::Error newError) +{ + Q_Q(QLowEnergyController); + error = newError; + + switch (newError) { + case QLowEnergyController::UnknownRemoteDeviceError: + errorString = QLowEnergyController::tr("Remote device cannot be found"); + break; + case QLowEnergyController::InvalidBluetoothAdapterError: + errorString = QLowEnergyController::tr("Cannot find local adapter"); + break; + case QLowEnergyController::NetworkError: + errorString = QLowEnergyController::tr("Error occurred during connection I/O"); + break; + case QLowEnergyController::ConnectionError: + errorString = QLowEnergyController::tr("Error occurred trying to connect to remote device."); + break; + case QLowEnergyController::AdvertisingError: + errorString = QLowEnergyController::tr("Error occurred trying to start advertising"); + break; + case QLowEnergyController::RemoteHostClosedError: + errorString = QLowEnergyController::tr("Remote device closed the connection"); + break; + case QLowEnergyController::NoError: + return; + default: + case QLowEnergyController::UnknownError: + errorString = QLowEnergyController::tr("Unknown Error"); + break; + } + + emit q->error(newError); +} + +void QLowEnergyControllerPrivateBase::setState( + QLowEnergyController::ControllerState newState) +{ + Q_Q(QLowEnergyController); + if (state == newState) + return; + + state = newState; + if (state == QLowEnergyController::UnconnectedState + && role == QLowEnergyController::PeripheralRole) { + remoteDevice.clear(); + } + emit q->stateChanged(state); +} + +QSharedPointer<QLowEnergyServicePrivate> QLowEnergyControllerPrivateBase::serviceForHandle( + QLowEnergyHandle handle) +{ + ServiceDataMap ¤tList = serviceList; + if (role == QLowEnergyController::PeripheralRole) + currentList = localServices; + + const QList<QSharedPointer<QLowEnergyServicePrivate>> values = currentList.values(); + for (auto service: values) + if (service->startHandle <= handle && handle <= service->endHandle) + return service; + + return QSharedPointer<QLowEnergyServicePrivate>(); +} + +QT_END_NAMESPACE diff --git a/src/bluetooth/qlowenergycontrollerbase_p.h b/src/bluetooth/qlowenergycontrollerbase_p.h new file mode 100644 index 00000000..8c16bc9f --- /dev/null +++ b/src/bluetooth/qlowenergycontrollerbase_p.h @@ -0,0 +1,159 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtBluetooth module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** 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 https://www.qt.io/terms-conditions. For further +** information use the contact form at https://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 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QLOWENERGYCONTROLLERPRIVATEBASE_P_H +#define QLOWENERGYCONTROLLERPRIVATEBASE_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + + +#include <qglobal.h> +#include <QtCore/qobject.h> + +#include <QtBluetooth/qlowenergycontroller.h> + +#include "qlowenergyserviceprivate_p.h" + +QT_BEGIN_NAMESPACE + +typedef QMap<QBluetoothUuid, QSharedPointer<QLowEnergyServicePrivate> > ServiceDataMap; + +class QLowEnergyControllerPrivateBase : public QObject +{ + Q_OBJECT +public: + // This class is required to enable selection of multiple + // alternative QLowEnergyControllerPrivate implementations on BlueZ. + // Bluez has a low level ATT protocol stack implementation and a DBus + // implementation. + + QLowEnergyControllerPrivateBase(); + virtual ~QLowEnergyControllerPrivateBase(); + + // interface definition + virtual void init() = 0; + virtual void connectToDevice() = 0; + virtual void disconnectFromDevice() = 0; + + virtual void discoverServices() = 0; + virtual void discoverServiceDetails(const QBluetoothUuid &/*service*/) = 0; + + virtual void readCharacteristic( + const QSharedPointer<QLowEnergyServicePrivate> /*service*/, + const QLowEnergyHandle /*charHandle*/) = 0; + virtual void readDescriptor( + const QSharedPointer<QLowEnergyServicePrivate> /*service*/, + const QLowEnergyHandle /*charHandle*/, + const QLowEnergyHandle /*descriptorHandle*/) = 0; + + virtual void writeCharacteristic( + const QSharedPointer<QLowEnergyServicePrivate> /*service*/, + const QLowEnergyHandle /*charHandle*/, + const QByteArray &/*newValue*/, + QLowEnergyService::WriteMode /*writeMode*/) = 0; + virtual void writeDescriptor( + const QSharedPointer<QLowEnergyServicePrivate> /*service*/, + const QLowEnergyHandle /*charHandle*/, + const QLowEnergyHandle /*descriptorHandle*/, + const QByteArray &/*newValue*/) = 0; + + virtual void startAdvertising( + const QLowEnergyAdvertisingParameters &/* params */, + const QLowEnergyAdvertisingData &/* advertisingData */, + const QLowEnergyAdvertisingData &/* scanResponseData */) = 0; + virtual void stopAdvertising() = 0; + + virtual void requestConnectionUpdate( + const QLowEnergyConnectionParameters & /* params */) = 0; + virtual void addToGenericAttributeList( + const QLowEnergyServiceData &/* service */, + QLowEnergyHandle /* startHandle */) = 0; + + + virtual QLowEnergyService *addServiceHelper( + const QLowEnergyServiceData &service) = 0; + + + // common backend methods + bool isValidLocalAdapter(); + void setError(QLowEnergyController::Error newError); + void setState(QLowEnergyController::ControllerState newState); + + // public variables + QLowEnergyController::Role role; + QLowEnergyController::RemoteAddressType addressType; + + // list of all found service uuids on remote device + ServiceDataMap serviceList; + // list of all found service uuids on local peripheral device + ServiceDataMap localServices; + + //common helper functions + + QSharedPointer<QLowEnergyServicePrivate> serviceForHandle(QLowEnergyHandle handle); + + + +protected: + QLowEnergyController::ControllerState state = QLowEnergyController::UnconnectedState; + QLowEnergyController::Error error = QLowEnergyController::NoError; + QString errorString; + + QBluetoothAddress remoteDevice; + QBluetoothAddress localAdapter; + + + QString remoteName; // device name of the remote + + Q_DECLARE_PUBLIC(QLowEnergyController) + QLowEnergyController *q_ptr; +}; + +QT_END_NAMESPACE + +#endif // QLOWENERGYCONTROLLERPRIVATEBASE_P_H diff --git a/src/bluetooth/qlowenergyserviceprivate.cpp b/src/bluetooth/qlowenergyserviceprivate.cpp index 83724d4e..e16aec72 100644 --- a/src/bluetooth/qlowenergyserviceprivate.cpp +++ b/src/bluetooth/qlowenergyserviceprivate.cpp @@ -57,7 +57,7 @@ QLowEnergyServicePrivate::~QLowEnergyServicePrivate() { } -void QLowEnergyServicePrivate::setController(QLowEnergyControllerPrivate *control) +void QLowEnergyServicePrivate::setController(QLowEnergyControllerPrivateBase *control) { controller = control; diff --git a/src/bluetooth/qlowenergyserviceprivate_p.h b/src/bluetooth/qlowenergyserviceprivate_p.h index 7727b583..3a0edd8a 100644 --- a/src/bluetooth/qlowenergyserviceprivate_p.h +++ b/src/bluetooth/qlowenergyserviceprivate_p.h @@ -63,7 +63,7 @@ QT_BEGIN_NAMESPACE -class QLowEnergyControllerPrivate; +class QLowEnergyControllerPrivateBase; class QLowEnergyServicePrivate : public QObject { @@ -92,7 +92,7 @@ public: Characteristic = 0x2803 }; - void setController(QLowEnergyControllerPrivate* control); + void setController(QLowEnergyControllerPrivateBase* control); void setError(QLowEnergyService::ServiceError newError); void setState(QLowEnergyService::ServiceState newState); @@ -122,7 +122,7 @@ public: QHash<QLowEnergyHandle, CharData> characteristicList; - QPointer<QLowEnergyControllerPrivate> controller; + QPointer<QLowEnergyControllerPrivateBase> controller; #if defined(QT_ANDROID_BLUETOOTH) // reference to the BluetoothGattService object |