From 19a4223906e9c10f22a6b7416b1a9ffee9bf416f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20St=C3=BCrz?= Date: Wed, 22 Nov 2017 20:00:55 +0100 Subject: [PATCH] First version of bluetooth manager --- .../bluetooth/bluetoothlowenergymanager.cpp | 107 ++++++++++++++--- libguh/bluetooth/bluetoothlowenergymanager.h | 25 +++- libguh/bluetooth/bluetoothscanner.cpp | 112 ------------------ libguh/bluetooth/bluetoothscanner.h | 64 ---------- libguh/devicemanager.cpp | 41 ------- libguh/devicemanager.h | 1 - libguh/hardwaremanager.cpp | 1 - libguh/hardwaremanager.h | 1 - libguh/libguh.pro | 2 - .../network/avahi/qtavahiservicebrowser.cpp | 4 + libguh/plugin/deviceplugin.cpp | 2 +- libguh/plugin/deviceplugin.h | 4 +- plugins/mock/devicepluginmock.cpp | 5 - plugins/mock/devicepluginmock.h | 1 - plugins/mock/translations/de_DE.ts | 2 +- plugins/mock/translations/en_US.ts | 2 +- 16 files changed, 120 insertions(+), 254 deletions(-) delete mode 100644 libguh/bluetooth/bluetoothscanner.cpp delete mode 100644 libguh/bluetooth/bluetoothscanner.h diff --git a/libguh/bluetooth/bluetoothlowenergymanager.cpp b/libguh/bluetooth/bluetoothlowenergymanager.cpp index ba44a845..49c7ef82 100644 --- a/libguh/bluetooth/bluetoothlowenergymanager.cpp +++ b/libguh/bluetooth/bluetoothlowenergymanager.cpp @@ -23,6 +23,35 @@ #include "bluetoothlowenergymanager.h" #include "loggingcategories.h" +bool BluetoothLowEnergyManager::discoverDevices(QPointer caller, const QString &callbackMethod) +{ + if (!available()) { + qCWarning(dcHardware()) << name() << "is not avilable."; + return false; + } + + if (!enabled()) { + qCWarning(dcHardware()) << name() << "is not enabled."; + return false; + } + + if (m_timer->isActive()) { + qCWarning(dcHardware()) << name() << "discovery already running."; + return false; + } + + m_discoveredDevices.clear(); + m_currentReply.caller = caller; + m_currentReply.callbackMethod = callbackMethod; + + // Start discovery on all adapters + qCDebug(dcHardware()) << name() << "Start bluetooth discovery"; + foreach (QBluetoothDeviceDiscoveryAgent *discoveryAgent, m_bluetoothDiscoveryAgents) { + discoveryAgent->start(); + } + return true; +} + BluetoothLowEnergyManager::BluetoothLowEnergyManager(QObject *parent) : HardwareResource(HardwareResource::TypeBluetoothLE, "Bluetooth LE manager", parent) { @@ -36,38 +65,80 @@ BluetoothLowEnergyManager::BluetoothLowEnergyManager(QObject *parent) : // Create a scanner for each adapter foreach (const QBluetoothHostInfo &hostInfo, bluetoothAdapters) { - qCDebug(dcHardware()) << name() << "Adapter:" << hostInfo.name() << hostInfo.address().toString(); - m_bluetoothScanners.append(new BluetoothScanner(hostInfo.address(), this)); + qCDebug(dcHardware()) << name() << "Using adapter:" << hostInfo.name() << hostInfo.address().toString(); + QBluetoothLocalDevice localDevice(hostInfo.address()); + localDevice.powerOn(); + localDevice.setHostMode(QBluetoothLocalDevice::HostDiscoverable); + + QBluetoothDeviceDiscoveryAgent *discoveryAgent = new QBluetoothDeviceDiscoveryAgent(hostInfo.address(), this); + connect(discoveryAgent, &QBluetoothDeviceDiscoveryAgent::deviceDiscovered, this, &BluetoothLowEnergyManager::onDeviceDiscovered); + connect(discoveryAgent, SIGNAL(error(QBluetoothDeviceDiscoveryAgent::Error)), this, SLOT(onDiscoveryError(QBluetoothDeviceDiscoveryAgent::Error))); + + m_bluetoothDiscoveryAgents.append(discoveryAgent); } + // Discovery timer + m_timer = new QTimer(this); + m_timer->setSingleShot(true); + m_timer->setInterval(5000); - -// // Check if Bluetooth is available on this device -// if (!localDevice.isValid()) { -// qCWarning(dcHardware()) << "No Bluetooth device found."; -// setAvailable(false); -// return false; -// } - -// // Turn Bluetooth on -// localDevice.powerOn(); - -// // Make it visible to others -// localDevice.setHostMode(QBluetoothLocalDevice::HostDiscoverable); + connect(m_timer, &QTimer::timeout, this, &BluetoothLowEnergyManager::discoveryTimeout); qCDebug(dcHardware()) << "-->" << name() << "created successfully."; - setAvailable(true); } +void BluetoothLowEnergyManager::discoveryTimeout() +{ + // Start discovery on all adapters + qCDebug(dcHardware()) << name() << "Stop bluetooth discovery"; + foreach (QBluetoothDeviceDiscoveryAgent *discoveryAgent, m_bluetoothDiscoveryAgents) { + discoveryAgent->stop(); + } + + qCDebug(dcHardware()) << name() << "Discovery finished. Found"<< m_discoveredDevices.count() << "Bluetooth devices."; + + if (m_currentReply.caller.isNull()) { + qCWarning(dcHardware()) << name() << "The reciver of the discovery request does not exist any more."; + } else { + // Invoke the method containing the discovered devicelist + // FIXME: check the callback method paramters during compililation + QMetaObject::invokeMethod(m_currentReply.caller.data(), m_currentReply.callbackMethod.toLatin1().data(), Q_ARG(QList, m_discoveredDevices)); + } +} + +void BluetoothLowEnergyManager::onDeviceDiscovered(const QBluetoothDeviceInfo &deviceInfo) +{ + // Add the device to the list if not already added + bool alreadyAdded = false; + foreach (const QBluetoothDeviceInfo &device, m_discoveredDevices) { + if (device.address() == deviceInfo.address()) { + alreadyAdded = true; + } + } + + if (!alreadyAdded) { + qCDebug(dcHardware()) << name() << "device discovered" << deviceInfo.name() <(sender()); + qCWarning(dcHardware()) << name() << "Discovery error:" << error << discoveryAgent->errorString(); +} + bool BluetoothLowEnergyManager::enable() { - // TODO: enable all devices created by this - + // TODO: enable all devices and trigger reconnect + setEnabled(true); return true; } bool BluetoothLowEnergyManager::disable() { + // TODO: disable reconnect and disconnect all devices + setEnabled(false); return true; } diff --git a/libguh/bluetooth/bluetoothlowenergymanager.h b/libguh/bluetooth/bluetoothlowenergymanager.h index 75838f02..b667ce0b 100644 --- a/libguh/bluetooth/bluetoothlowenergymanager.h +++ b/libguh/bluetooth/bluetoothlowenergymanager.h @@ -23,11 +23,20 @@ #ifndef BLUETOOTHLOWENERGYMANAGER_H #define BLUETOOTHLOWENERGYMANAGER_H +#include #include +#include +#include #include +#include #include "hardwareresource.h" -#include "bluetoothscanner.h" + +struct BluetoothDiscoveryReply +{ + QPointer caller; + QString callbackMethod; +}; class BluetoothLowEnergyManager : public HardwareResource { @@ -36,13 +45,25 @@ class BluetoothLowEnergyManager : public HardwareResource friend class HardwareManager; public: + bool discoverDevices(QPointer caller = QPointer(), const QString &callbackMethod = QString()); private: explicit BluetoothLowEnergyManager(QObject *parent = nullptr); - QList m_bluetoothScanners; + QTimer *m_timer = nullptr; + + QList m_bluetoothDiscoveryAgents; + QList m_discoveredDevices; + + BluetoothDiscoveryReply m_currentReply; signals: +private slots: + void onDeviceDiscovered(const QBluetoothDeviceInfo &deviceInfo); + void onDiscoveryError(const QBluetoothDeviceDiscoveryAgent::Error &error); + + void discoveryTimeout(); + public slots: bool enable(); bool disable(); diff --git a/libguh/bluetooth/bluetoothscanner.cpp b/libguh/bluetooth/bluetoothscanner.cpp deleted file mode 100644 index 64b985b4..00000000 --- a/libguh/bluetooth/bluetoothscanner.cpp +++ /dev/null @@ -1,112 +0,0 @@ -/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * - * * - * Copyright (C) 2015 Simon Stürz * - * * - * This file is part of guh. * - * * - * This library is free software; you can redistribute it and/or * - * modify it under the terms of the GNU Lesser General Public * - * License as published by the Free Software Foundation; either * - * version 2.1 of the License, or (at your option) any later version. * - * * - * This library is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * - * Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public * - * License along with this library; If not, see * - * . * - * * - * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ - -/*! - \class BluetoothScanner - \brief Allows to discover bluetooth low energy devices. - - \ingroup hardware - \inmodule libguh - - The bluetooth scanner hardware resource allows to discover bluetooth low energy devices. -*/ - -/*! - * \fn BluetoothScanner::bluetoothDiscoveryFinished(const PluginId &pluginId, const QList &deviceInfos) - * This signal will be emitted whenever a bluetooth discover for the plugin with the given \a pluginId is finished. - * The passed list of \a deviceInfos contains the information of the discovered devices. - */ - -#include "bluetoothscanner.h" -#include "loggingcategories.h" - -/*! Construct the hardware resource BluetoothScanner with the given \a parent. */ -BluetoothScanner::BluetoothScanner(const QBluetoothAddress &adapterAddress, QObject *parent) : - QObject(parent), - m_adapterAddress(adapterAddress) -{ - m_timer = new QTimer(this); - m_timer->setSingleShot(true); - m_timer->setInterval(5000); - - connect(m_timer, &QTimer::timeout, this, &BluetoothScanner::discoveryTimeout); - - m_discoveryAgent = new QBluetoothDeviceDiscoveryAgent(m_adapterAddress, this); - - connect(m_discoveryAgent, &QBluetoothDeviceDiscoveryAgent::deviceDiscovered, this, &BluetoothScanner::deviceDiscovered); - connect(m_discoveryAgent, SIGNAL(error(QBluetoothDeviceDiscoveryAgent::Error)), this, SLOT(onError(QBluetoothDeviceDiscoveryAgent::Error))); -} - -/*! Returns true, if the discovering agent currently is running. */ -bool BluetoothScanner::isRunning() -{ - return m_discoveryAgent->isActive(); -} - -/*! This method will start the discovering process for the plugin with the given \a pluginId. - * Returns true if the discovery could be started. */ -bool BluetoothScanner::discover(const PluginId &pluginId) -{ - if (m_available && !m_discoveryAgent->isActive()) { - m_pluginId = pluginId; - m_deviceInfos.clear(); - m_discoveryAgent->start(); - m_timer->start(); - qCDebug(dcHardware) << "Bluetooth discovery started..."; - return true; - } - return false; -} - -void BluetoothScanner::deviceDiscovered(const QBluetoothDeviceInfo &device) -{ - // check if this is a LE device - bool bluetoothLE = false; - if (device.coreConfigurations() & QBluetoothDeviceInfo::LowEnergyCoreConfiguration) { - bluetoothLE = true; - } - qCDebug(dcHardware) << "Bluetooth device discovered:" << device.name() << device.address() << "LE:" << bluetoothLE; - - m_deviceInfos.append(device); -} - -void BluetoothScanner::onError(QBluetoothDeviceDiscoveryAgent::Error error) -{ - Q_UNUSED(error) - - m_available = false; - - if (m_timer->isActive()) - m_timer->stop(); - - if (isRunning()) - m_discoveryAgent->stop(); - - qCWarning(dcHardware) << "Bluetooth discovery error:" << m_discoveryAgent->errorString(); -} - -void BluetoothScanner::discoveryTimeout() -{ - qCDebug(dcHardware) << "Bluetooth discovery finished."; - m_discoveryAgent->stop(); - emit bluetoothDiscoveryFinished(m_pluginId, m_deviceInfos); -} diff --git a/libguh/bluetooth/bluetoothscanner.h b/libguh/bluetooth/bluetoothscanner.h deleted file mode 100644 index 613c7788..00000000 --- a/libguh/bluetooth/bluetoothscanner.h +++ /dev/null @@ -1,64 +0,0 @@ -/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * - * * - * Copyright (C) 2015 Simon Stürz * - * * - * This file is part of guh. * - * * - * This library is free software; you can redistribute it and/or * - * modify it under the terms of the GNU Lesser General Public * - * License as published by the Free Software Foundation; either * - * version 2.1 of the License, or (at your option) any later version. * - * * - * This library is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * - * Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public * - * License along with this library; If not, see * - * . * - * * - * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ - -#ifndef BLUETOOTHSCANNER_H -#define BLUETOOTHSCANNER_H - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "libguh.h" -#include "typeutils.h" - -class LIBGUH_EXPORT BluetoothScanner : public QObject -{ - Q_OBJECT -public: - explicit BluetoothScanner(const QBluetoothAddress &adapterAddress, QObject *parent = 0); - bool isRunning(); - bool discover(const PluginId &pluginId); - -private: - QBluetoothAddress m_adapterAddress; - QBluetoothDeviceDiscoveryAgent *m_discoveryAgent; - QList m_deviceInfos; - QTimer *m_timer; - bool m_available; - PluginId m_pluginId; - -signals: - void bluetoothDiscoveryFinished(const PluginId &pluginId, const QList &deviceInfos); - -private slots: - void deviceDiscovered(const QBluetoothDeviceInfo &device); - void onError(QBluetoothDeviceDiscoveryAgent::Error error); - void discoveryTimeout(); -}; - -#endif // BLUETOOTHSCANNER_H diff --git a/libguh/devicemanager.cpp b/libguh/devicemanager.cpp index ce86a5ec..03dbb8bb 100644 --- a/libguh/devicemanager.cpp +++ b/libguh/devicemanager.cpp @@ -745,22 +745,6 @@ DeviceManager::DeviceError DeviceManager::removeConfiguredDevice(const DeviceId } m_devicePlugins.value(device->pluginId())->deviceRemoved(device); - // check if this plugin still needs the guhTimer call - bool pluginNeedsTimer = false; - foreach (Device* d, m_configuredDevices) { - if (d->pluginId() == device->pluginId()) { - pluginNeedsTimer = true; - break; - } - } - - // if this plugin doesn't need any longer the guhTimer call - if (!pluginNeedsTimer) { - m_pluginTimerUsers.removeAll(plugin(device->pluginId())); - if (m_pluginTimerUsers.isEmpty()) { - m_hardwareManager->pluginTimer()->disable(); - } - } device->deleteLater(); GuhSettings settings(GuhSettings::SettingsRoleDevices); @@ -1220,18 +1204,6 @@ void DeviceManager::slotDeviceSetupFinished(Device *device, DeviceManager::Devic storeConfiguredDevices(); } - DevicePlugin *plugin = m_devicePlugins.value(device->pluginId()); - if (plugin->requiredHardware().testFlag(HardwareResource::TypeTimer)) { - if (!m_hardwareManager->pluginTimer()->enabled()) { - m_hardwareManager->pluginTimer()->enable(); - // Additionally fire off one event to initialize stuff - QTimer::singleShot(0, this, SLOT(timerEvent())); - } - if (!m_pluginTimerUsers.contains(plugin)) { - m_pluginTimerUsers.append(plugin); - } - } - // if this is a async device edit result if (m_asyncDeviceReconfiguration.contains(device)) { m_asyncDeviceReconfiguration.removeAll(device); @@ -1465,19 +1437,6 @@ DeviceManager::DeviceSetupStatus DeviceManager::setupDevice(Device *device) return status; } - if (plugin->requiredHardware().testFlag(HardwareResource::TypeTimer)) { - - if (!m_hardwareManager->pluginTimer()->enabled()) { - m_hardwareManager->pluginTimer()->enable(); - // Additionally fire off one event to initialize stuff - QTimer::singleShot(0, this, SLOT(timerEvent())); - } - - if (!m_pluginTimerUsers.contains(plugin)) { - m_pluginTimerUsers.append(plugin); - } - } - connect(device, SIGNAL(stateValueChanged(QUuid,QVariant)), this, SLOT(slotDeviceStateValueChanged(QUuid,QVariant))); device->setupCompleted(); diff --git a/libguh/devicemanager.h b/libguh/devicemanager.h index 98f8e2df..73bbae75 100644 --- a/libguh/devicemanager.h +++ b/libguh/devicemanager.h @@ -185,7 +185,6 @@ private: QHash m_discoveredDevices; QHash m_devicePlugins; - QList m_pluginTimerUsers; HardwareManager *m_hardwareManager; diff --git a/libguh/hardwaremanager.cpp b/libguh/hardwaremanager.cpp index a86aed4b..284eb0fc 100644 --- a/libguh/hardwaremanager.cpp +++ b/libguh/hardwaremanager.cpp @@ -24,7 +24,6 @@ #include "plugintimer.h" #include "loggingcategories.h" -#include "bluetooth/bluetoothscanner.h" #include "hardware/radio433/radio433.h" #include "network/networkaccessmanager.h" #include "network/upnp/upnpdiscovery.h" diff --git a/libguh/hardwaremanager.h b/libguh/hardwaremanager.h index 3d7bdab7..789d09e6 100644 --- a/libguh/hardwaremanager.h +++ b/libguh/hardwaremanager.h @@ -75,7 +75,6 @@ signals: void hardwareResourceAvailableChanged(const HardwareResource::Type &hardwareResourceType, const bool &available); void hardwareResourceEnabledChanged(const HardwareResource::Type &hardwareResourceType, const bool &enabled); - }; diff --git a/libguh/libguh.pro b/libguh/libguh.pro index d36ad2a6..689f9c4c 100644 --- a/libguh/libguh.pro +++ b/libguh/libguh.pro @@ -43,7 +43,6 @@ HEADERS += devicemanager.h \ network/avahi/qtavahiservice_p.h \ network/avahi/qtavahiservicebrowser.h \ network/avahi/qtavahiservicebrowser_p.h \ - bluetooth/bluetoothscanner.h \ bluetooth/bluetoothlowenergydevice.h \ coap/coap.h \ coap/coappdu.h \ @@ -100,7 +99,6 @@ SOURCES += devicemanager.cpp \ network/avahi/qtavahiservice_p.cpp \ network/avahi/qtavahiservicebrowser.cpp \ network/avahi/qtavahiservicebrowser_p.cpp \ - bluetooth/bluetoothscanner.cpp \ bluetooth/bluetoothlowenergydevice.cpp \ coap/coap.cpp \ coap/coappdu.cpp \ diff --git a/libguh/network/avahi/qtavahiservicebrowser.cpp b/libguh/network/avahi/qtavahiservicebrowser.cpp index 448e8229..75c66b4a 100644 --- a/libguh/network/avahi/qtavahiservicebrowser.cpp +++ b/libguh/network/avahi/qtavahiservicebrowser.cpp @@ -48,6 +48,10 @@ QtAvahiServiceBrowser::QtAvahiServiceBrowser(QObject *parent) : d_ptr(new QtAvahiServiceBrowserPrivate(new QtAvahiClient)) { connect(d_ptr->client, &QtAvahiClient::clientStateChanged, this, &QtAvahiServiceBrowser::onClientStateChanged); + + // TODO: check available here + setAvailable(true); + qCDebug(dcHardware()) << "-->" << name() << "created successfully."; } diff --git a/libguh/plugin/deviceplugin.cpp b/libguh/plugin/deviceplugin.cpp index 1e213021..54fa6ade 100644 --- a/libguh/plugin/deviceplugin.cpp +++ b/libguh/plugin/deviceplugin.cpp @@ -148,7 +148,7 @@ #include "devicemanager.h" #include "guhsettings.h" -#include "bluetooth/bluetoothscanner.h" + #include "hardware/radio433/radio433.h" #include "network/upnp/upnpdiscovery.h" diff --git a/libguh/plugin/deviceplugin.h b/libguh/plugin/deviceplugin.h index a737c36f..a344203e 100644 --- a/libguh/plugin/deviceplugin.h +++ b/libguh/plugin/deviceplugin.h @@ -43,8 +43,8 @@ #include #include -class DeviceManager; class Device; +class DeviceManager; class LIBGUH_EXPORT DevicePlugin: public QObject { @@ -66,8 +66,6 @@ public: QTranslator *translator(); bool setLocale(const QLocale &locale); - virtual HardwareResource::Types requiredHardware() const = 0; - virtual void startMonitoringAutoDevices(); virtual DeviceManager::DeviceError discoverDevices(const DeviceClassId &deviceClassId, const ParamList ¶ms); diff --git a/plugins/mock/devicepluginmock.cpp b/plugins/mock/devicepluginmock.cpp index 5e70e60f..ba47fb64 100644 --- a/plugins/mock/devicepluginmock.cpp +++ b/plugins/mock/devicepluginmock.cpp @@ -61,11 +61,6 @@ DevicePluginMock::~DevicePluginMock() { } -HardwareResource::Types DevicePluginMock::requiredHardware() const -{ - return HardwareResource::TypeTimer; -} - DeviceManager::DeviceError DevicePluginMock::discoverDevices(const DeviceClassId &deviceClassId, const ParamList ¶ms) { if (deviceClassId == mockDeviceClassId || deviceClassId == mockDeviceAutoDeviceClassId) { diff --git a/plugins/mock/devicepluginmock.h b/plugins/mock/devicepluginmock.h index 065ab47e..622e93a9 100644 --- a/plugins/mock/devicepluginmock.h +++ b/plugins/mock/devicepluginmock.h @@ -41,7 +41,6 @@ public: explicit DevicePluginMock(); ~DevicePluginMock(); - HardwareResource::Types requiredHardware() const override; DeviceManager::DeviceError discoverDevices(const DeviceClassId &deviceClassId, const ParamList ¶ms) override; DeviceManager::DeviceSetupStatus setupDevice(Device *device) override; diff --git a/plugins/mock/translations/de_DE.ts b/plugins/mock/translations/de_DE.ts index 19d60bc3..a41b9c91 100644 --- a/plugins/mock/translations/de_DE.ts +++ b/plugins/mock/translations/de_DE.ts @@ -4,7 +4,7 @@ DevicePluginMock - + Display pin!! The pin is 243681 Pin anzeigen!! Der pin lautet 243581 diff --git a/plugins/mock/translations/en_US.ts b/plugins/mock/translations/en_US.ts index adf3e165..c631361a 100644 --- a/plugins/mock/translations/en_US.ts +++ b/plugins/mock/translations/en_US.ts @@ -4,7 +4,7 @@ DevicePluginMock - + Display pin!! The pin is 243681