From 3348fd18def21f08224c8234122addf95b674359 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20St=C3=BCrz?= Date: Thu, 5 Mar 2015 10:13:11 +0100 Subject: [PATCH] added bluetooth low energy device type --- libguh/bluetooth/bluetoothlowenergydevice.cpp | 155 ++++++++++++++++++ libguh/bluetooth/bluetoothlowenergydevice.h | 76 +++++++++ libguh/libguh.pro | 7 +- plugins/deviceplugins/deviceplugins.pro | 4 + 4 files changed, 240 insertions(+), 2 deletions(-) create mode 100644 libguh/bluetooth/bluetoothlowenergydevice.cpp create mode 100644 libguh/bluetooth/bluetoothlowenergydevice.h diff --git a/libguh/bluetooth/bluetoothlowenergydevice.cpp b/libguh/bluetooth/bluetoothlowenergydevice.cpp new file mode 100644 index 00000000..aa59932c --- /dev/null +++ b/libguh/bluetooth/bluetoothlowenergydevice.cpp @@ -0,0 +1,155 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * * + * This file is part of guh. * + * * + * Guh is free software: you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation, version 2 of the License. * + * * + * Guh 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 General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with guh. If not, see . * + * * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +#include "bluetoothlowenergydevice.h" + +BluetoothLowEnergyDevice::BluetoothLowEnergyDevice(const QBluetoothDeviceInfo &deviceInfo, const QLowEnergyController::RemoteAddressType &addressType, QObject *parent) : + QObject(parent), m_deviceInfo(deviceInfo) +{ + m_controller = new QLowEnergyController(address(), this); + m_controller->setRemoteAddressType(addressType); + + connect(m_controller, &QLowEnergyController::connected, this, &BluetoothLowEnergyDevice::connected); + connect(m_controller, &QLowEnergyController::disconnected, this, &BluetoothLowEnergyDevice::disconnected); + connect(m_controller, &QLowEnergyController::serviceDiscovered, this, &BluetoothLowEnergyDevice::serviceDiscovered); + connect(m_controller, &QLowEnergyController::discoveryFinished, this, &BluetoothLowEnergyDevice::serviceScanFinished); + connect(m_controller, SIGNAL(error(QLowEnergyController::Error)), this, SLOT(deviceError(QLowEnergyController::Error))); +} + +QString BluetoothLowEnergyDevice::name() const +{ + return m_deviceInfo.name(); +} + +QBluetoothAddress BluetoothLowEnergyDevice::address() const +{ + return m_deviceInfo.address(); +} + +QList BluetoothLowEnergyDevice::services() const +{ + return m_services; +} + +QList BluetoothLowEnergyDevice::characteristics() const +{ + return m_characteristics; +} + +void BluetoothLowEnergyDevice::connectDevice() +{ + m_controller->connectToDevice(); +} + +void BluetoothLowEnergyDevice::disconnectDevice() +{ + m_controller->disconnectFromDevice(); +} + +bool BluetoothLowEnergyDevice::isConnected() const +{ + return m_connected; +} + +bool BluetoothLowEnergyDevice::isDiscovered() const +{ + return m_discovered; +} + +void BluetoothLowEnergyDevice::discoverService(const QBluetoothUuid &serviceUuid) +{ + Q_UNUSED(serviceUuid); +} + +void BluetoothLowEnergyDevice::connected() +{ + m_connected = true; + qDebug() << "connected successfully to" << name() << address().toString(); + emit connectionStatusChanged(true); + m_controller->discoverServices(); +} + +void BluetoothLowEnergyDevice::disconnected() +{ + m_connected = false; + qWarning() << "disconnected from" << name() << address().toString(); + emit connectionStatusChanged(false); +} + +void BluetoothLowEnergyDevice::deviceError(const QLowEnergyController::Error &error) +{ + qWarning() << "ERROR: Bluetooth device" << name() << address().toString() << ": " << error << m_controller->errorString(); +} + +void BluetoothLowEnergyDevice::serviceDiscovered(const QBluetoothUuid &serviceUuid) +{ + QLowEnergyService *service = m_controller->createServiceObject(serviceUuid); + + if (!service) { + qWarning() << "Cannot create service for uuid" << serviceUuid; + return; + } + + connect(service, SIGNAL(characteristicChanged(QLowEnergyCharacteristic,QByteArray)), this, SLOT(serviceCharacteristicChanged(QLowEnergyCharacteristic,QByteArray))); + connect(service, SIGNAL(error(QLowEnergyService::ServiceError)), this, SLOT(serviceError(QLowEnergyService::ServiceError))); + connect(service, SIGNAL(stateChanged(QLowEnergyService::ServiceState)), this, SLOT(serviceStateChanged(QLowEnergyService::ServiceState))); + + m_services.append(service); +} + +void BluetoothLowEnergyDevice::serviceStateChanged(const QLowEnergyService::ServiceState &newState) +{ + if (newState != QLowEnergyService::ServiceDiscovered) { + return; + } + + QLowEnergyService *service = qobject_cast(sender()); + foreach (QLowEnergyCharacteristic characteristic, service->characteristics()) { + if (!characteristic.descriptors().isEmpty()) { + foreach (QLowEnergyDescriptor descriptor, characteristic.descriptors()) { + if (descriptor.isValid()) { + m_descriptors.append(descriptor); + } + } + } + m_characteristics.append(characteristic); + } + qDebug() << "details discovered for service " << service->serviceName() << service->serviceUuid().toString(); +} + +void BluetoothLowEnergyDevice::serviceScanFinished() +{ + qDebug() << "service scan finished"; + emit serviceScanFinished(); +} + +void BluetoothLowEnergyDevice::serviceCharacteristicChanged(const QLowEnergyCharacteristic &characteristic, const QByteArray &value) +{ + qDebug() << "characteristic" << characteristic.name() << "changed:" << value; +} + +void BluetoothLowEnergyDevice::serviceError(const QLowEnergyService::ServiceError &error) +{ + QLowEnergyService *service = qobject_cast(sender()); + qWarning() << "ERROR: Bluetooth service " << service->serviceName() << service->serviceUuid() << ": " << error; +} + +void BluetoothLowEnergyDevice::confirmedDescriptorWrite(const QLowEnergyDescriptor &descriptor, const QByteArray &value) +{ + qDebug() << "descriptor" << descriptor.name() << "written successfully " << value; +} diff --git a/libguh/bluetooth/bluetoothlowenergydevice.h b/libguh/bluetooth/bluetoothlowenergydevice.h new file mode 100644 index 00000000..0c0f199c --- /dev/null +++ b/libguh/bluetooth/bluetoothlowenergydevice.h @@ -0,0 +1,76 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * * + * This file is part of guh. * + * * + * Guh is free software: you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation, version 2 of the License. * + * * + * Guh 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 General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with guh. If not, see . * + * * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +#ifndef BLUETOOTHLOWENERGYDEVICE_H +#define BLUETOOTHLOWENERGYDEVICE_H + +#include +#include +#include +#include +#include + +class BluetoothLowEnergyDevice : public QObject +{ + Q_OBJECT +public: + explicit BluetoothLowEnergyDevice(const QBluetoothDeviceInfo &deviceInfo, const QLowEnergyController::RemoteAddressType &addressType = QLowEnergyController::PublicAddress, QObject *parent = 0); + + QString name() const; + QBluetoothAddress address() const; + QList services() const; + QList characteristics() const; + + void connectDevice(); + void disconnectDevice(); + + bool isConnected() const; + bool isDiscovered() const; + + void discoverService(const QBluetoothUuid &serviceUuid); + +private: + QBluetoothDeviceInfo m_deviceInfo; + QLowEnergyController *m_controller; + QList m_services; + QList m_characteristics; + QList m_descriptors; + + bool m_connected; + bool m_discovered; + +signals: + void connectionStatusChanged(const bool &connectionStatus); + void servicesDiscovered(); + +private slots: + // Device + void connected(); + void disconnected(); + void deviceError(const QLowEnergyController::Error &error); + void serviceDiscovered(const QBluetoothUuid &serviceUuid); + void serviceStateChanged(const QLowEnergyService::ServiceState &newState); + void serviceScanFinished(); + + // Service + void serviceCharacteristicChanged(const QLowEnergyCharacteristic &characteristic, const QByteArray &value); + void serviceError(const QLowEnergyService::ServiceError &error); + void confirmedDescriptorWrite(const QLowEnergyDescriptor &descriptor, const QByteArray &value); +}; + +#endif // BLUETOOTHLOWENERGYDEVICE_H diff --git a/libguh/libguh.pro b/libguh/libguh.pro index 46c42db2..0b887c85 100644 --- a/libguh/libguh.pro +++ b/libguh/libguh.pro @@ -9,8 +9,11 @@ target.path = /usr/lib INSTALLS += target contains(DEFINES, BLUETOOTH_LE) { - SOURCES += bluetooth/bluetoothscanner.cpp - HEADERS += bluetooth/bluetoothscanner.h + SOURCES += bluetooth/bluetoothscanner.cpp \ + bluetooth/bluetoothlowenergydevice.cpp \ + + HEADERS += bluetooth/bluetoothscanner.h \ + bluetooth/bluetoothlowenergydevice.h \ } SOURCES += plugin/device.cpp \ diff --git a/plugins/deviceplugins/deviceplugins.pro b/plugins/deviceplugins/deviceplugins.pro index 0c1a14eb..c8980366 100644 --- a/plugins/deviceplugins/deviceplugins.pro +++ b/plugins/deviceplugins/deviceplugins.pro @@ -24,3 +24,7 @@ SUBDIRS += elro \ boblight { SUBDIRS += boblight } + +contains(DEFINES, BLUETOOTH_LE) { + # bluetooth plugins +}