Remove bluetooth server and dependencies

remove-bluetooth-server
Simon Stürz 2021-01-12 14:05:56 +01:00
parent 86d513bfa4
commit ff3d1f8722
9 changed files with 1 additions and 1943 deletions

4
debian/control vendored
View File

@ -8,7 +8,6 @@ Build-Depends: debhelper (>= 9.0.0),
qt5-qmake,
qtbase5-dev,
qtbase5-dev-tools,
libqt5bluetooth5,
qtconnectivity5-dev
Standards-Version: 3.9.7
@ -17,8 +16,7 @@ Section: libs
Architecture: any
Depends: ${shlibs:Depends},
${misc:Depends},
libqt5network5,
libqt5bluetooth5
libqt5network5
Description: Qt 5 based library for the network-manager DBus API.
Qt 5 based library for the network-manager DBus API.

View File

@ -1,498 +0,0 @@
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*
* Copyright 2013 - 2020, nymea GmbH
* Contact: contact@nymea.io
*
* This file is part of nymea.
* This project including source code and documentation is protected by
* copyright law, and remains the property of nymea GmbH. All rights, including
* reproduction, publication, editing and translation, are reserved. The use of
* this project is subject to the terms of a license agreement to be concluded
* with nymea GmbH in accordance with the terms of use of nymea GmbH, available
* under https://nymea.io/license
*
* GNU Lesser General Public License Usage
* Alternatively, this project may be redistributed and/or modified under the
* terms of the GNU Lesser General Public License as published by the Free
* Software Foundation; version 3. This project 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 project. If not, see <https://www.gnu.org/licenses/>.
*
* For any further details and any questions please contact us under
* contact@nymea.io or see our FAQ/Licensing Information on
* https://nymea.io/license/faq
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/*!
\class BluetoothServer
\brief Represents a bluetooth LE server for network-manager remote configuration.
\inmodule nymea-networkmanager
\ingroup networkmanager-bluetooth
*/
#include "bluetoothserver.h"
#include "../networkmanager.h"
#include "../networkmanagerutils.h"
#include <QFile>
#include <QSysInfo>
BluetoothServer::BluetoothServer(NetworkManager *networkManager) :
QObject(networkManager),
m_networkManager(networkManager)
{
}
BluetoothServer::~BluetoothServer()
{
qCDebug(dcNetworkManagerBluetoothServer()) << "Destroy bluetooth server.";
if (m_controller)
m_controller->stopAdvertising();
if (m_localDevice)
m_localDevice->setHostMode(QBluetoothLocalDevice::HostConnectable);
}
QString BluetoothServer::advertiseName() const
{
return m_advertiseName;
}
void BluetoothServer::setAdvertiseName(const QString &advertiseName)
{
m_advertiseName = advertiseName;
}
QString BluetoothServer::modelName() const
{
return m_modelName;
}
void BluetoothServer::setModelName(const QString &modelName)
{
m_modelName = modelName;
}
QString BluetoothServer::softwareVersion() const
{
return m_softwareVersion;
}
void BluetoothServer::setSoftwareVersion(const QString &softwareVersion)
{
m_softwareVersion = softwareVersion;
}
QString BluetoothServer::hardwareVersion() const
{
return m_hardwareVersion;
}
void BluetoothServer::setHardwareVersion(const QString &hardwareVersion)
{
m_hardwareVersion = hardwareVersion;
}
QString BluetoothServer::serialNumber() const
{
return m_serialNumber;
}
void BluetoothServer::setSerialNumber(const QString &serialNumber)
{
m_serialNumber = serialNumber;
}
bool BluetoothServer::running() const
{
return m_running;
}
bool BluetoothServer::connected() const
{
return m_connected;
}
QLowEnergyServiceData BluetoothServer::deviceInformationServiceData()
{
QLowEnergyServiceData serviceData;
serviceData.setType(QLowEnergyServiceData::ServiceTypePrimary);
serviceData.setUuid(QBluetoothUuid::DeviceInformation);
// Model number string 0x2a24
QLowEnergyCharacteristicData modelNumberCharData;
modelNumberCharData.setUuid(QBluetoothUuid::ModelNumberString);
if (m_modelName.isEmpty()) {
modelNumberCharData.setValue(QString("N.A.").toUtf8());
} else {
modelNumberCharData.setValue(m_modelName.toUtf8());
}
modelNumberCharData.setProperties(QLowEnergyCharacteristic::Read);
serviceData.addCharacteristic(modelNumberCharData);
// Serial number string 0x2a25
QLowEnergyCharacteristicData serialNumberCharData;
serialNumberCharData.setUuid(QBluetoothUuid::SerialNumberString);
if (m_serialNumber.isNull()) {
// Note: if no serialnumber specified use the system uuid from /etc/machine-id
qCDebug(dcNetworkManagerBluetoothServer()) << "Serial number not specified. Using system uuid from /etc/machine-id as serialnumber.";
m_serialNumber = readMachineId().toString();
}
serialNumberCharData.setValue(m_serialNumber.toUtf8());
serialNumberCharData.setProperties(QLowEnergyCharacteristic::Read);
serviceData.addCharacteristic(serialNumberCharData);
// Firmware revision string 0x2a26
QLowEnergyCharacteristicData firmwareRevisionCharData;
firmwareRevisionCharData.setUuid(QBluetoothUuid::FirmwareRevisionString);
firmwareRevisionCharData.setValue(QString(VERSION_STRING).toUtf8());
firmwareRevisionCharData.setProperties(QLowEnergyCharacteristic::Read);
serviceData.addCharacteristic(firmwareRevisionCharData);
// Hardware revision string 0x2a27
QLowEnergyCharacteristicData hardwareRevisionCharData;
hardwareRevisionCharData.setUuid(QBluetoothUuid::HardwareRevisionString);
hardwareRevisionCharData.setValue(m_hardwareVersion.toUtf8());
hardwareRevisionCharData.setProperties(QLowEnergyCharacteristic::Read);
serviceData.addCharacteristic(hardwareRevisionCharData);
// Software revision string 0x2a28
QLowEnergyCharacteristicData softwareRevisionCharData;
softwareRevisionCharData.setUuid(QBluetoothUuid::SoftwareRevisionString);
softwareRevisionCharData.setValue(m_softwareVersion.toUtf8());
softwareRevisionCharData.setProperties(QLowEnergyCharacteristic::Read);
serviceData.addCharacteristic(softwareRevisionCharData);
// Manufacturer name string 0x2a29
QLowEnergyCharacteristicData manufacturerNameCharData;
manufacturerNameCharData.setUuid(QBluetoothUuid::ManufacturerNameString);
manufacturerNameCharData.setValue(QString("guh GmbH").toUtf8());
manufacturerNameCharData.setProperties(QLowEnergyCharacteristic::Read);
serviceData.addCharacteristic(manufacturerNameCharData);
return serviceData;
}
QLowEnergyServiceData BluetoothServer::genericAccessServiceData()
{
QLowEnergyServiceData serviceData;
serviceData.setType(QLowEnergyServiceData::ServiceTypePrimary);
serviceData.setUuid(QBluetoothUuid::GenericAccess);
// Device name 0x2a00
QLowEnergyCharacteristicData nameCharData;
nameCharData.setUuid(QBluetoothUuid::DeviceName);
if (m_advertiseName.isNull()) {
qCWarning(dcNetworkManagerBluetoothServer()) << "Advertise name not specified. Using system host name as device name.";
m_advertiseName = QSysInfo::machineHostName();
}
nameCharData.setValue(m_advertiseName.toUtf8());
nameCharData.setProperties(QLowEnergyCharacteristic::Read);
serviceData.addCharacteristic(nameCharData);
// Appearance 0x2a01
QLowEnergyCharacteristicData appearanceCharData;
appearanceCharData.setUuid(QBluetoothUuid::Appearance);
appearanceCharData.setValue(QByteArray(4, 0));
appearanceCharData.setProperties(QLowEnergyCharacteristic::Read);
serviceData.addCharacteristic(appearanceCharData);
// Peripheral Privacy Flag 0x2a02
QLowEnergyCharacteristicData privacyFlagCharData;
privacyFlagCharData.setUuid(QBluetoothUuid::PeripheralPrivacyFlag);
privacyFlagCharData.setValue(QByteArray(2, 0));
privacyFlagCharData.setProperties(QLowEnergyCharacteristic::Read | QLowEnergyCharacteristic::Write);
serviceData.addCharacteristic(privacyFlagCharData);
// Reconnection Address 0x2a03
QLowEnergyCharacteristicData reconnectionAddressCharData;
reconnectionAddressCharData.setUuid(QBluetoothUuid::ReconnectionAddress);
reconnectionAddressCharData.setValue(QByteArray());
reconnectionAddressCharData.setProperties(QLowEnergyCharacteristic::Write);
serviceData.addCharacteristic(reconnectionAddressCharData);
return serviceData;
}
QLowEnergyServiceData BluetoothServer::genericAttributeServiceData()
{
QLowEnergyServiceData serviceData;
serviceData.setType(QLowEnergyServiceData::ServiceTypePrimary);
serviceData.setUuid(QBluetoothUuid::GenericAttribute);
QLowEnergyCharacteristicData charData;
charData.setUuid(QBluetoothUuid::ServiceChanged);
charData.setProperties(QLowEnergyCharacteristic::Indicate);
serviceData.addCharacteristic(charData);
return serviceData;
}
void BluetoothServer::setRunning(bool running)
{
if (m_running == running)
return;
m_running = running;
emit runningChanged(m_running);
}
void BluetoothServer::setConnected(bool connected)
{
if (m_connected == connected)
return;
m_connected = connected;
emit connectedChanged(m_connected);
}
QUuid BluetoothServer::readMachineId()
{
QUuid systemUuid;
QFile systemUuidFile("/etc/machine-id");
if (systemUuidFile.open(QFile::ReadOnly)) {
QString tmpId = QString::fromLatin1(systemUuidFile.readAll()).trimmed();
tmpId.insert(8, "-");
tmpId.insert(13, "-");
tmpId.insert(18, "-");
tmpId.insert(23, "-");
systemUuid = QUuid(tmpId);
} else {
qCWarning(dcNetworkManagerBluetoothServer()) << "Failed to open /etc/machine-id for reading the system uuid as device information serialnumber.";
}
systemUuidFile.close();
return systemUuid;
}
void BluetoothServer::onHostModeStateChanged(const QBluetoothLocalDevice::HostMode mode)
{
switch (mode) {
case QBluetoothLocalDevice::HostConnectable:
qCDebug(dcNetworkManagerBluetoothServer()) << "Bluetooth host in connectable mode.";
break;
case QBluetoothLocalDevice::HostDiscoverable:
qCDebug(dcNetworkManagerBluetoothServer()) << "Bluetooth host in discoverable mode.";
break;
case QBluetoothLocalDevice::HostPoweredOff:
qCDebug(dcNetworkManagerBluetoothServer()) << "Bluetooth host in power off mode.";
break;
case QBluetoothLocalDevice::HostDiscoverableLimitedInquiry:
qCDebug(dcNetworkManagerBluetoothServer()) << "Bluetooth host in discoverable limited inquiry mode.";
break;
}
}
void BluetoothServer::onDeviceConnected(const QBluetoothAddress &address)
{
qCDebug(dcNetworkManagerBluetoothServer()) << "Device connected" << address.toString();
}
void BluetoothServer::onDeviceDisconnected(const QBluetoothAddress &address)
{
qCDebug(dcNetworkManagerBluetoothServer()) << "Device disconnected" << address.toString();
}
void BluetoothServer::onError(QLowEnergyController::Error error)
{
qCWarning(dcNetworkManagerBluetoothServer()) << "Bluetooth error occured:" << error << m_controller->errorString();
}
void BluetoothServer::onConnected()
{
qCDebug(dcNetworkManagerBluetoothServer()) << "Client connected" << m_controller->remoteName() << m_controller->remoteAddress();
setConnected(true);
}
void BluetoothServer::onDisconnected()
{
qCDebug(dcNetworkManagerBluetoothServer()) << "Client disconnected";
setConnected(false);
stop();
}
void BluetoothServer::onControllerStateChanged(QLowEnergyController::ControllerState state)
{
switch (state) {
case QLowEnergyController::UnconnectedState:
qCDebug(dcNetworkManagerBluetoothServer()) << "Controller state disonnected.";
setConnected(false);
break;
case QLowEnergyController::ConnectingState:
qCDebug(dcNetworkManagerBluetoothServer()) << "Controller state connecting...";
setConnected(false);
break;
case QLowEnergyController::ConnectedState:
qCDebug(dcNetworkManagerBluetoothServer()) << "Controller state connected." << m_controller->remoteName() << m_controller->remoteAddress();
setConnected(true);
break;
case QLowEnergyController::DiscoveringState:
qCDebug(dcNetworkManagerBluetoothServer()) << "Controller state discovering...";
break;
case QLowEnergyController::DiscoveredState:
qCDebug(dcNetworkManagerBluetoothServer()) << "Controller state discovered.";
break;
case QLowEnergyController::ClosingState:
qCDebug(dcNetworkManagerBluetoothServer()) << "Controller state closing...";
break;
case QLowEnergyController::AdvertisingState:
qCDebug(dcNetworkManagerBluetoothServer()) << "Controller state advertising...";
setRunning(true);
break;
}
}
void BluetoothServer::characteristicChanged(const QLowEnergyCharacteristic &characteristic, const QByteArray &value)
{
qCDebug(dcNetworkManagerBluetoothServer()) << "Service characteristic changed" << characteristic.uuid() << value;
}
void BluetoothServer::characteristicRead(const QLowEnergyCharacteristic &characteristic, const QByteArray &value)
{
qCDebug(dcNetworkManagerBluetoothServer()) << "Service characteristic read" << characteristic.uuid() << value;
}
void BluetoothServer::characteristicWritten(const QLowEnergyCharacteristic &characteristic, const QByteArray &value)
{
qCDebug(dcNetworkManagerBluetoothServer()) << "Service characteristic written" << characteristic.uuid() << value;
}
void BluetoothServer::descriptorRead(const QLowEnergyDescriptor &descriptor, const QByteArray &value)
{
qCDebug(dcNetworkManagerBluetoothServer()) << "Descriptor read" << descriptor.uuid() << value;
}
void BluetoothServer::descriptorWritten(const QLowEnergyDescriptor &descriptor, const QByteArray &value)
{
qCDebug(dcNetworkManagerBluetoothServer()) << "Descriptor written" << descriptor.uuid() << value;
}
void BluetoothServer::serviceError(QLowEnergyService::ServiceError error)
{
QString errorString;
switch (error) {
case QLowEnergyService::NoError:
errorString = "No error";
break;
case QLowEnergyService::OperationError:
errorString = "Operation error";
break;
case QLowEnergyService::CharacteristicReadError:
errorString = "Characteristic read error";
break;
case QLowEnergyService::CharacteristicWriteError:
errorString = "Characteristic write error";
break;
case QLowEnergyService::DescriptorReadError:
errorString = "Descriptor read error";
break;
case QLowEnergyService::DescriptorWriteError:
errorString = "Descriptor write error";
break;
case QLowEnergyService::UnknownError:
errorString = "Unknown error";
break;
}
qCWarning(dcNetworkManagerBluetoothServer()) << "Service error:" << errorString;
}
void BluetoothServer::start()
{
if (running()) {
qCDebug(dcNetworkManagerBluetoothServer()) << "Start Bluetooth server called but the server is already running. Doing nothing.";
return;
}
if (connected()) {
qCDebug(dcNetworkManagerBluetoothServer()) << "Start Bluetooth server called but the server is running and a client is connected. Doing nothing.";
return;
}
qCDebug(dcNetworkManagerBluetoothServer()) << "-------------------------------------";
qCDebug(dcNetworkManagerBluetoothServer()) << "Starting bluetooth server...";
qCDebug(dcNetworkManagerBluetoothServer()) << "-------------------------------------";
// Local bluetooth device
m_localDevice = new QBluetoothLocalDevice(this);
if (!m_localDevice->isValid()) {
qCWarning(dcNetworkManagerBluetoothServer()) << "Local bluetooth device is not valid.";
delete m_localDevice;
m_localDevice = nullptr;
return;
}
connect(m_localDevice, &QBluetoothLocalDevice::hostModeStateChanged, this, &BluetoothServer::onHostModeStateChanged);
connect(m_localDevice, &QBluetoothLocalDevice::deviceConnected, this, &BluetoothServer::onDeviceConnected);
connect(m_localDevice, &QBluetoothLocalDevice::deviceDisconnected, this, &BluetoothServer::onDeviceDisconnected);
qCDebug(dcNetworkManagerBluetoothServer()) << "Local device" << m_localDevice->name() << m_localDevice->address().toString();
m_localDevice->setHostMode(QBluetoothLocalDevice::HostDiscoverable);
m_localDevice->powerOn();
// Bluetooth low energy periperal controller
m_controller = QLowEnergyController::createPeripheral(this);
connect(m_controller, &QLowEnergyController::stateChanged, this, &BluetoothServer::onControllerStateChanged);
connect(m_controller, &QLowEnergyController::connected, this, &BluetoothServer::onConnected);
connect(m_controller, &QLowEnergyController::disconnected, this, &BluetoothServer::onDisconnected);
connect(m_controller, SIGNAL(error(QLowEnergyController::Error)), this, SLOT(onError(QLowEnergyController::Error)));
// Note: https://www.bluetooth.com/specifications/gatt/services
m_deviceInfoService = m_controller->addService(deviceInformationServiceData(), m_controller);
m_genericAccessService = m_controller->addService(genericAccessServiceData(), m_controller);
m_genericAttributeService = m_controller->addService(genericAttributeServiceData(), m_controller);
// Create custom services
m_networkService = new NetworkService(m_controller->addService(NetworkService::serviceData(m_networkManager), m_controller),
m_networkManager, m_controller);
m_wirelessService = new WirelessService(m_controller->addService(WirelessService::serviceData(m_networkManager), m_controller),
m_networkManager, m_controller);
QLowEnergyAdvertisingData advertisingData;
advertisingData.setDiscoverability(QLowEnergyAdvertisingData::DiscoverabilityGeneral);
advertisingData.setIncludePowerLevel(true);
advertisingData.setLocalName(m_advertiseName);
// FIXME: set guh manufacturer SIG data once available
// Note: start advertising in 100 ms interval, this makes the device better discoverable on certain phones
QLowEnergyAdvertisingParameters advertisingParameters;
advertisingParameters.setInterval(100, 100);
qCDebug(dcNetworkManagerBluetoothServer()) << "Start advertising" << m_advertiseName << m_localDevice->address().toString();
m_controller->startAdvertising(advertisingParameters, advertisingData, advertisingData);
// Note: setRunning(true) will be called when the service is really advertising, see onControllerStateChanged()
}
void BluetoothServer::stop()
{
qCDebug(dcNetworkManagerBluetoothServer()) << "-------------------------------------";
qCDebug(dcNetworkManagerBluetoothServer()) << "Stopping bluetooth server.";
qCDebug(dcNetworkManagerBluetoothServer()) << "-------------------------------------";
if (m_localDevice) {
qCDebug(dcNetworkManagerBluetoothServer()) << "Set host mode to connectable.";
m_localDevice->setHostMode(QBluetoothLocalDevice::HostConnectable);
delete m_localDevice;
m_localDevice = nullptr;
}
if (m_controller) {
qCDebug(dcNetworkManagerBluetoothServer()) << "Stop advertising.";
m_controller->stopAdvertising();
delete m_controller;
m_controller = nullptr;
}
setConnected(false);
setRunning(false);
}

View File

@ -1,142 +0,0 @@
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*
* Copyright 2013 - 2020, nymea GmbH
* Contact: contact@nymea.io
*
* This file is part of nymea.
* This project including source code and documentation is protected by
* copyright law, and remains the property of nymea GmbH. All rights, including
* reproduction, publication, editing and translation, are reserved. The use of
* this project is subject to the terms of a license agreement to be concluded
* with nymea GmbH in accordance with the terms of use of nymea GmbH, available
* under https://nymea.io/license
*
* GNU Lesser General Public License Usage
* Alternatively, this project may be redistributed and/or modified under the
* terms of the GNU Lesser General Public License as published by the Free
* Software Foundation; version 3. This project 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 project. If not, see <https://www.gnu.org/licenses/>.
*
* For any further details and any questions please contact us under
* contact@nymea.io or see our FAQ/Licensing Information on
* https://nymea.io/license/faq
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
#ifndef BLUETOOTHSERVER_H
#define BLUETOOTHSERVER_H
#include <QObject>
#include <QTimer>
#include <QObject>
#include <QPointer>
#include <QLowEnergyHandle>
#include <QLowEnergyService>
#include <QBluetoothLocalDevice>
#include <QLowEnergyController>
#include <QLowEnergyServiceData>
#include <QLowEnergyCharacteristic>
#include <QLowEnergyDescriptorData>
#include <QLowEnergyAdvertisingData>
#include <QLowEnergyCharacteristicData>
#include <QLowEnergyConnectionParameters>
#include <QLowEnergyAdvertisingParameters>
#include "networkservice.h"
#include "wirelessservice.h"
class NetworkManager;
class BluetoothServer : public QObject
{
Q_OBJECT
public:
explicit BluetoothServer(NetworkManager *networkManager);
~BluetoothServer();
QString advertiseName() const;
void setAdvertiseName(const QString &advertiseName);
// Information for the device info service
QString modelName() const;
void setModelName(const QString &modelName);
QString softwareVersion() const;
void setSoftwareVersion(const QString &softwareVersion);
QString hardwareVersion() const;
void setHardwareVersion(const QString &hardwareVersion);
QString serialNumber() const;
void setSerialNumber(const QString &serialNumber);
bool running() const;
bool connected() const;
private:
QString m_advertiseName;
QString m_modelName;
QString m_softwareVersion;
QString m_hardwareVersion;
QString m_serialNumber;
NetworkManager *m_networkManager = nullptr;
QBluetoothLocalDevice *m_localDevice = nullptr;
QLowEnergyController *m_controller = nullptr;
QLowEnergyService *m_deviceInfoService = nullptr;
QLowEnergyService *m_genericAccessService = nullptr;
QLowEnergyService *m_genericAttributeService = nullptr;
NetworkService *m_networkService = nullptr;
WirelessService *m_wirelessService = nullptr;
bool m_running = false;
bool m_connected = false;
QLowEnergyServiceData deviceInformationServiceData();
QLowEnergyServiceData genericAccessServiceData();
QLowEnergyServiceData genericAttributeServiceData();
void setRunning(bool running);
void setConnected(bool connected);
QUuid readMachineId();
signals:
void runningChanged(const bool &running);
void connectedChanged(const bool &connected);
private slots:
// Local bluetooth device
void onHostModeStateChanged(QBluetoothLocalDevice::HostMode mode);
void onDeviceConnected(const QBluetoothAddress &address);
void onDeviceDisconnected(const QBluetoothAddress &address);
void onError(QLowEnergyController::Error error);
// Bluetooth controller
void onConnected();
void onDisconnected();
void onControllerStateChanged(QLowEnergyController::ControllerState state);
// Services
void characteristicChanged(const QLowEnergyCharacteristic &characteristic, const QByteArray &value);
void characteristicRead(const QLowEnergyCharacteristic &characteristic, const QByteArray &value);
void characteristicWritten(const QLowEnergyCharacteristic &characteristic, const QByteArray &value);
void descriptorRead(const QLowEnergyDescriptor &descriptor, const QByteArray &value);
void descriptorWritten(const QLowEnergyDescriptor &descriptor, const QByteArray &value);
void serviceError(QLowEnergyService::ServiceError error);
public slots:
void start();
void stop();
};
#endif // BLUETOOTHSERVER_H

View File

@ -1,49 +0,0 @@
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*
* Copyright 2013 - 2020, nymea GmbH
* Contact: contact@nymea.io
*
* This file is part of nymea.
* This project including source code and documentation is protected by
* copyright law, and remains the property of nymea GmbH. All rights, including
* reproduction, publication, editing and translation, are reserved. The use of
* this project is subject to the terms of a license agreement to be concluded
* with nymea GmbH in accordance with the terms of use of nymea GmbH, available
* under https://nymea.io/license
*
* GNU Lesser General Public License Usage
* Alternatively, this project may be redistributed and/or modified under the
* terms of the GNU Lesser General Public License as published by the Free
* Software Foundation; version 3. This project 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 project. If not, see <https://www.gnu.org/licenses/>.
*
* For any further details and any questions please contact us under
* contact@nymea.io or see our FAQ/Licensing Information on
* https://nymea.io/license/faq
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
#ifndef BLUETOOTHUUIDS_H
#define BLUETOOTHUUIDS_H
#include <QBluetoothUuid>
static QBluetoothUuid networkServiceUuid = QBluetoothUuid(QUuid("ef6d6610-b8af-49e0-9eca-ab343513641c"));
static QBluetoothUuid networkStatusCharacteristicUuid = QBluetoothUuid(QUuid("ef6d6611-b8af-49e0-9eca-ab343513641c"));
static QBluetoothUuid networkCommanderCharacteristicUuid = QBluetoothUuid(QUuid("ef6d6612-b8af-49e0-9eca-ab343513641c"));
static QBluetoothUuid networkResponseCharacteristicUuid = QBluetoothUuid(QUuid("ef6d6613-b8af-49e0-9eca-ab343513641c"));
static QBluetoothUuid networkingEnabledCharacteristicUuid = QBluetoothUuid(QUuid("ef6d6614-b8af-49e0-9eca-ab343513641c"));
static QBluetoothUuid wirelessEnabledCharacteristicUuid = QBluetoothUuid(QUuid("ef6d6615-b8af-49e0-9eca-ab343513641c"));
static QBluetoothUuid wirelessServiceUuid = QBluetoothUuid(QUuid("e081fec0-f757-4449-b9c9-bfa83133f7fc"));
static QBluetoothUuid wirelessCommanderCharacteristicUuid = QBluetoothUuid(QUuid("e081fec1-f757-4449-b9c9-bfa83133f7fc"));
static QBluetoothUuid wirelessResponseCharacteristicUuid = QBluetoothUuid(QUuid("e081fec2-f757-4449-b9c9-bfa83133f7fc"));
static QBluetoothUuid wirelessStateCharacteristicUuid = QBluetoothUuid(QUuid("e081fec3-f757-4449-b9c9-bfa83133f7fc"));
static QBluetoothUuid wirelessModeCharacteristicUuid = QBluetoothUuid(QUuid("e081fec4-f757-4449-b9c9-bfa83133f7fc"));
#endif // BLUETOOTHUUIDS_H

View File

@ -1,363 +0,0 @@
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*
* Copyright 2013 - 2020, nymea GmbH
* Contact: contact@nymea.io
*
* This file is part of nymea.
* This project including source code and documentation is protected by
* copyright law, and remains the property of nymea GmbH. All rights, including
* reproduction, publication, editing and translation, are reserved. The use of
* this project is subject to the terms of a license agreement to be concluded
* with nymea GmbH in accordance with the terms of use of nymea GmbH, available
* under https://nymea.io/license
*
* GNU Lesser General Public License Usage
* Alternatively, this project may be redistributed and/or modified under the
* terms of the GNU Lesser General Public License as published by the Free
* Software Foundation; version 3. This project 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 project. If not, see <https://www.gnu.org/licenses/>.
*
* For any further details and any questions please contact us under
* contact@nymea.io or see our FAQ/Licensing Information on
* https://nymea.io/license/faq
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/*!
\class NetworkService
\brief Represents a bluetooth LE service interfacing the network-manager.
\inmodule nymea-networkmanager
\ingroup networkmanager-bluetooth
*/
#include "networkservice.h"
#include "bluetoothuuids.h"
#include <QLowEnergyDescriptorData>
#include <QLowEnergyCharacteristicData>
NetworkService::NetworkService(QLowEnergyService *service, NetworkManager *networkManager, QObject *parent) :
QObject(parent),
m_service(service),
m_networkManager(networkManager)
{
qCDebug(dcNetworkManagerBluetoothServer()) << "Create NetworkService.";
// Service
connect(m_service, SIGNAL(characteristicChanged(QLowEnergyCharacteristic, QByteArray)), this, SLOT(characteristicChanged(QLowEnergyCharacteristic, QByteArray)));
connect(m_service, SIGNAL(characteristicRead(QLowEnergyCharacteristic, QByteArray)), this, SLOT(characteristicChanged(QLowEnergyCharacteristic, QByteArray)));
connect(m_service, SIGNAL(characteristicWritten(QLowEnergyCharacteristic, QByteArray)), this, SLOT(characteristicWritten(QLowEnergyCharacteristic, QByteArray)));
connect(m_service, SIGNAL(descriptorWritten(QLowEnergyDescriptor, QByteArray)), this, SLOT(descriptorWritten(QLowEnergyDescriptor, QByteArray)));
connect(m_service, SIGNAL(error(QLowEnergyService::ServiceError)), this, SLOT(serviceError(QLowEnergyService::ServiceError)));
// NetworkManager
connect(m_networkManager, &NetworkManager::stateChanged, this, &NetworkService::onNetworkManagerStateChanged);
connect(m_networkManager, &NetworkManager::networkingEnabledChanged, this, &NetworkService::onNetworkingEnabledChanged);
connect(m_networkManager, &NetworkManager::wirelessEnabledChanged, this, &NetworkService::onWirelessEnabledChanged);
}
QLowEnergyService *NetworkService::service()
{
return m_service;
}
QLowEnergyServiceData NetworkService::serviceData(NetworkManager *networkManager)
{
QLowEnergyServiceData serviceData;
serviceData.setType(QLowEnergyServiceData::ServiceTypePrimary);
serviceData.setUuid(networkServiceUuid);
QLowEnergyDescriptorData clientConfigDescriptorData(QBluetoothUuid::ClientCharacteristicConfiguration, QByteArray(2, 0));
// Network manager status ef6d661-b8af-49e0-9eca-ab343513641c
QLowEnergyCharacteristicData networkStatusData;
networkStatusData.setUuid(networkStatusCharacteristicUuid);
networkStatusData.setValue(QByteArray(1, 0));
networkStatusData.setProperties(QLowEnergyCharacteristic::Read | QLowEnergyCharacteristic::Notify);
networkStatusData.addDescriptor(clientConfigDescriptorData);
networkStatusData.setValue(NetworkService::getNetworkManagerStateByteArray(networkManager->state()));
serviceData.addCharacteristic(networkStatusData);
// Network manager commander ef6d6612-b8af-49e0-9eca-ab343513641c
QLowEnergyCharacteristicData networkCommanderCharacteristicData;
networkCommanderCharacteristicData.setUuid(networkCommanderCharacteristicUuid);
networkCommanderCharacteristicData.setProperties(QLowEnergyCharacteristic::Write);
networkCommanderCharacteristicData.setValueLength(1, 1);
serviceData.addCharacteristic(networkCommanderCharacteristicData);
// Response characteristic ef6d6613-b8af-49e0-9eca-ab343513641c
QLowEnergyCharacteristicData networkResponseCharacteristicData;
networkResponseCharacteristicData.setUuid(networkResponseCharacteristicUuid);
networkResponseCharacteristicData.setProperties(QLowEnergyCharacteristic::Notify);
networkResponseCharacteristicData.addDescriptor(clientConfigDescriptorData);
networkResponseCharacteristicData.setValueLength(1, 1);
serviceData.addCharacteristic(networkResponseCharacteristicData);
// Networking enabled ef6d6614-b8af-49e0-9eca-ab343513641c
QLowEnergyCharacteristicData networkingEnabledStatusData;
networkingEnabledStatusData.setUuid(networkingEnabledCharacteristicUuid);
networkingEnabledStatusData.setValue(QByteArray(1, 0));
networkingEnabledStatusData.setProperties(QLowEnergyCharacteristic::Read | QLowEnergyCharacteristic::Notify);
networkingEnabledStatusData.setValue(QByteArray::number(static_cast<int>(networkManager->networkingEnabled())));
serviceData.addCharacteristic(networkingEnabledStatusData);
// Wireless enabled ef6d6615-b8af-49e0-9eca-ab343513641c
QLowEnergyCharacteristicData wirelessEnabledStatusData;
wirelessEnabledStatusData.setUuid(wirelessEnabledCharacteristicUuid);
wirelessEnabledStatusData.setValue(QByteArray(1, 0));
wirelessEnabledStatusData.setProperties(QLowEnergyCharacteristic::Read | QLowEnergyCharacteristic::Notify);
wirelessEnabledStatusData.setValue(QByteArray::number(static_cast<int>(networkManager->wirelessEnabled())));
serviceData.addCharacteristic(wirelessEnabledStatusData);
return serviceData;
}
QByteArray NetworkService::getNetworkManagerStateByteArray(const NetworkManager::NetworkManagerState &state)
{
QByteArray networkManagerState;
switch (state) {
case NetworkManager::NetworkManagerStateUnknown:
networkManagerState = QByteArray::fromHex("00");
break;
case NetworkManager::NetworkManagerStateAsleep:
networkManagerState = QByteArray::fromHex("01");
break;
case NetworkManager::NetworkManagerStateDisconnected:
networkManagerState = QByteArray::fromHex("02");
break;
case NetworkManager::NetworkManagerStateDisconnecting:
networkManagerState = QByteArray::fromHex("03");
break;
case NetworkManager::NetworkManagerStateConnecting:
networkManagerState = QByteArray::fromHex("04");
break;
case NetworkManager::NetworkManagerStateConnectedLocal:
networkManagerState = QByteArray::fromHex("05");
break;
case NetworkManager::NetworkManagerStateConnectedSite:
networkManagerState = QByteArray::fromHex("06");
break;
case NetworkManager::NetworkManagerStateConnectedGlobal:
networkManagerState = QByteArray::fromHex("07");
break;
}
return networkManagerState;
}
void NetworkService::sendResponse(const NetworkService::NetworkServiceResponse &response)
{
if (!m_service) {
qCWarning(dcNetworkManagerBluetoothServer()) << "NetworkService: Could not send response. Service not valid";
return;
}
QLowEnergyCharacteristic characteristic = m_service->characteristic(networkResponseCharacteristicUuid);
if (!characteristic.isValid()) {
qCWarning(dcNetworkManagerBluetoothServer()) << "NetworkService: Could not send response. Characteristic not valid";
return;
}
switch (response) {
case NetworkServiceResponseSuccess:
m_service->writeCharacteristic(characteristic, QByteArray::fromHex("00"));
break;
case NetworkServiceResponseIvalidValue:
m_service->writeCharacteristic(characteristic, QByteArray::fromHex("01"));
break;
case NetworkServiceResponseNetworkManagerNotAvailable:
m_service->writeCharacteristic(characteristic, QByteArray::fromHex("02"));
break;
case NetworkServiceResponseWirelessNotAvailable:
m_service->writeCharacteristic(characteristic, QByteArray::fromHex("03"));
break;
default:
// Unknown error
m_service->writeCharacteristic(characteristic, QByteArray::fromHex("04"));
break;
}
}
NetworkService::NetworkServiceCommand NetworkService::verifyCommand(const QByteArray &commandData)
{
if (commandData.length() != 1)
return NetworkServiceCommandInvalid;
uint commandInteger = commandData.toHex().toUInt(nullptr, 16);
switch (commandInteger) {
case NetworkServiceCommandEnableNetworking:
return NetworkServiceCommandEnableNetworking;
case NetworkServiceCommandDisableNetworking:
return NetworkServiceCommandDisableNetworking;
case NetworkServiceCommandEnableWireless:
return NetworkServiceCommandEnableWireless;
case NetworkServiceCommandDisableWireless:
return NetworkServiceCommandDisableWireless;
default:
break;
}
return NetworkServiceCommandInvalid;
}
void NetworkService::characteristicChanged(const QLowEnergyCharacteristic &characteristic, const QByteArray &value)
{
if (characteristic.uuid() == networkCommanderCharacteristicUuid) {
NetworkServiceCommand command = verifyCommand(value);
if (command == NetworkServiceCommandInvalid) {
qCWarning(dcNetworkManagerBluetoothServer()) << "NetworkService: received invalid command" << command;
sendResponse(NetworkServiceResponseIvalidValue);
return;
}
if (!m_networkManager->available()) {
qCWarning(dcNetworkManagerBluetoothServer()) << "NetworkService: Networkmanager not available";
sendResponse(NetworkServiceResponseNetworkManagerNotAvailable);
return;
}
processCommand(command);
sendResponse(NetworkServiceResponseSuccess);
return;
}
qCDebug(dcNetworkManagerBluetoothServer()) << "NetworkService: Characteristic changed" << characteristic.uuid().toString() << value;
}
void NetworkService::characteristicRead(const QLowEnergyCharacteristic &characteristic, const QByteArray &value)
{
qCDebug(dcNetworkManagerBluetoothServer()) << "NetworkService: Characteristic read" << characteristic.uuid().toString() << value;
}
void NetworkService::characteristicWritten(const QLowEnergyCharacteristic &characteristic, const QByteArray &value)
{
qCDebug(dcNetworkManagerBluetoothServer()) << "NetworkService: Characteristic written" << characteristic.uuid().toString() << value;
}
void NetworkService::descriptorRead(const QLowEnergyDescriptor &descriptor, const QByteArray &value)
{
qCDebug(dcNetworkManagerBluetoothServer()) << "NetworkService: Descriptor read" << descriptor.uuid().toString() << value;
}
void NetworkService::descriptorWritten(const QLowEnergyDescriptor &descriptor, const QByteArray &value)
{
qCDebug(dcNetworkManagerBluetoothServer()) << "NetworkService: Descriptor written" << descriptor.uuid().toString() << value;
}
void NetworkService::serviceError(const QLowEnergyService::ServiceError &error)
{
QString errorString;
switch (error) {
case QLowEnergyService::NoError:
errorString = "No error";
break;
case QLowEnergyService::OperationError:
errorString = "Operation error";
break;
case QLowEnergyService::CharacteristicReadError:
errorString = "Characteristic read error";
break;
case QLowEnergyService::CharacteristicWriteError:
errorString = "Characteristic write error";
break;
case QLowEnergyService::DescriptorReadError:
errorString = "Descriptor read error";
break;
case QLowEnergyService::DescriptorWriteError:
errorString = "Descriptor write error";
break;
case QLowEnergyService::UnknownError:
errorString = "Unknown error";
break;
}
qCWarning(dcNetworkManagerBluetoothServer()) << "NetworkService: Error:" << errorString;
}
void NetworkService::processCommand(const NetworkServiceCommand &command)
{
switch (command) {
case NetworkServiceCommandEnableNetworking:
qCDebug(dcNetworkManagerBluetoothServer()) << "NetworkService: received \"Enable networking\" command";
m_networkManager->enableNetworking(true);
break;
case NetworkServiceCommandDisableNetworking:
qCDebug(dcNetworkManagerBluetoothServer()) << "NetworkService: received \"Disable networking\" command";
m_networkManager->enableNetworking(false);
break;
case NetworkServiceCommandEnableWireless:
qCDebug(dcNetworkManagerBluetoothServer()) << "NetworkService: received \"Enable wireless networking\" command";
m_networkManager->enableWireless(true);
break;
case NetworkServiceCommandDisableWireless:
qCDebug(dcNetworkManagerBluetoothServer()) << "NetworkService: received \"Disable wireless networking\" command";
m_networkManager->enableWireless(false);
break;
default:
qCWarning(dcNetworkManagerBluetoothServer()) << "NetworkService: Unhandled command" << command;
sendResponse(NetworkServiceResponseIvalidValue);
break;
}
}
bool NetworkService::onNetworkManagerStateChanged()
{
if (!m_service) {
qCWarning(dcNetworkManagerBluetoothServer()) << "NetworkService: Could not updatet network manager status. Service not valid";
return false;
}
QLowEnergyCharacteristic characteristic = m_service->characteristic(networkStatusCharacteristicUuid);
if (!characteristic.isValid()) {
qCWarning(dcNetworkManagerBluetoothServer()) << "NetworkService: Could not update network manager status. Characteristic not valid";
return false;
}
qCDebug(dcNetworkManagerBluetoothServer()) << "NetworkService: Notify state changed" << NetworkService::getNetworkManagerStateByteArray(m_networkManager->state());
m_service->writeCharacteristic(characteristic, NetworkService::getNetworkManagerStateByteArray(m_networkManager->state()));
return true;
}
bool NetworkService::onNetworkingEnabledChanged()
{
if (!m_service) {
qCWarning(dcNetworkManagerBluetoothServer()) << "NetworkService: Could not set networking enabled. Service not valid";
return false;
}
QLowEnergyCharacteristic characteristic = m_service->characteristic(networkingEnabledCharacteristicUuid);
if (!characteristic.isValid()) {
qCWarning(dcNetworkManagerBluetoothServer()) << "NetworkService: Could not set networking enabled. Characteristic not valid";
return false;
}
qCDebug(dcNetworkManagerBluetoothServer()) << "NetworkService: Notify networking enabled changed:" << (m_networkManager->networkingEnabled() ? "enabled" : "disabled");
m_service->writeCharacteristic(characteristic, m_networkManager->networkingEnabled() ? QByteArray::fromHex("01") : QByteArray::fromHex("00"));
return true;
}
bool NetworkService::onWirelessEnabledChanged()
{
if (!m_service) {
qCWarning(dcNetworkManagerBluetoothServer()) << "NetworkService: Could not set wireless enabled. Service not valid";
return false;
}
QLowEnergyCharacteristic characteristic = m_service->characteristic(wirelessEnabledCharacteristicUuid);
if (!characteristic.isValid()) {
qCWarning(dcNetworkManagerBluetoothServer()) << "NetworkService: Could not set wireless enabled. Characteristic not valid";
return false;
}
qCDebug(dcNetworkManagerBluetoothServer()) << "NetworkService: Notify wireless networking enabled changed:" << (m_networkManager->wirelessEnabled() ? "enabled" : "disabled");
m_service->writeCharacteristic(characteristic, m_networkManager->wirelessEnabled() ? QByteArray::fromHex("01") : QByteArray::fromHex("00"));
return true;
}

View File

@ -1,97 +0,0 @@
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*
* Copyright 2013 - 2020, nymea GmbH
* Contact: contact@nymea.io
*
* This file is part of nymea.
* This project including source code and documentation is protected by
* copyright law, and remains the property of nymea GmbH. All rights, including
* reproduction, publication, editing and translation, are reserved. The use of
* this project is subject to the terms of a license agreement to be concluded
* with nymea GmbH in accordance with the terms of use of nymea GmbH, available
* under https://nymea.io/license
*
* GNU Lesser General Public License Usage
* Alternatively, this project may be redistributed and/or modified under the
* terms of the GNU Lesser General Public License as published by the Free
* Software Foundation; version 3. This project 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 project. If not, see <https://www.gnu.org/licenses/>.
*
* For any further details and any questions please contact us under
* contact@nymea.io or see our FAQ/Licensing Information on
* https://nymea.io/license/faq
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
#ifndef NETWORKSERVICE_H
#define NETWORKSERVICE_H
#include <QObject>
#include <QLowEnergyService>
#include <QLowEnergyServiceData>
#include "../networkmanager.h"
class NetworkService : public QObject
{
Q_OBJECT
public:
enum NetworkServiceCommand {
NetworkServiceCommandInvalid = -1,
NetworkServiceCommandEnableNetworking = 0x00,
NetworkServiceCommandDisableNetworking = 0x01,
NetworkServiceCommandEnableWireless = 0x02,
NetworkServiceCommandDisableWireless = 0x03
};
Q_ENUM(NetworkServiceCommand)
enum NetworkServiceResponse {
NetworkServiceResponseSuccess = 0x00,
NetworkServiceResponseIvalidValue = 0x01,
NetworkServiceResponseNetworkManagerNotAvailable = 0x02,
NetworkServiceResponseWirelessNotAvailable = 0x03,
NetworkServiceResponseUnknownError = 0x04,
};
Q_ENUM(NetworkServiceResponse)
explicit NetworkService(QLowEnergyService *service, NetworkManager *networkManager, QObject *parent = nullptr);
QLowEnergyService *service();
static QLowEnergyServiceData serviceData(NetworkManager *networkManager);
static QByteArray getNetworkManagerStateByteArray(const NetworkManager::NetworkManagerState &state);
private:
QLowEnergyService *m_service = nullptr;
NetworkManager *m_networkManager = nullptr;
void sendResponse(const NetworkServiceResponse &response);
NetworkServiceCommand verifyCommand(const QByteArray &commandData);
private slots:
// Service
void characteristicChanged(const QLowEnergyCharacteristic &characteristic, const QByteArray &value);
void characteristicRead(const QLowEnergyCharacteristic &characteristic, const QByteArray &value);
void characteristicWritten(const QLowEnergyCharacteristic &characteristic, const QByteArray &value);
void descriptorRead(const QLowEnergyDescriptor &descriptor, const QByteArray &value);
void descriptorWritten(const QLowEnergyDescriptor &descriptor, const QByteArray &value);
void serviceError(const QLowEnergyService::ServiceError &error);
// Commands
void processCommand(const NetworkServiceCommand &command);
public slots:
bool onNetworkManagerStateChanged();
bool onNetworkingEnabledChanged();
bool onWirelessEnabledChanged();
};
#endif // NETWORKSERVICE_H

View File

@ -1,650 +0,0 @@
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*
* Copyright 2013 - 2020, nymea GmbH
* Contact: contact@nymea.io
*
* This file is part of nymea.
* This project including source code and documentation is protected by
* copyright law, and remains the property of nymea GmbH. All rights, including
* reproduction, publication, editing and translation, are reserved. The use of
* this project is subject to the terms of a license agreement to be concluded
* with nymea GmbH in accordance with the terms of use of nymea GmbH, available
* under https://nymea.io/license
*
* GNU Lesser General Public License Usage
* Alternatively, this project may be redistributed and/or modified under the
* terms of the GNU Lesser General Public License as published by the Free
* Software Foundation; version 3. This project 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 project. If not, see <https://www.gnu.org/licenses/>.
*
* For any further details and any questions please contact us under
* contact@nymea.io or see our FAQ/Licensing Information on
* https://nymea.io/license/faq
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/*!
\class WirelessService
\brief Represents a bluetooth LE service interfacing the wireless configuration of the network-manager.
\inmodule nymea-networkmanager
\ingroup networkmanager-bluetooth
*/
#include "wirelessservice.h"
#include "bluetoothuuids.h"
#include <QJsonDocument>
#include <QNetworkInterface>
#include <QLowEnergyDescriptorData>
#include <QLowEnergyCharacteristicData>
WirelessService::WirelessService(QLowEnergyService *service, NetworkManager *networkManager, QObject *parent) :
QObject(parent),
m_service(service),
m_networkManager(networkManager)
{
qCDebug(dcNetworkManagerBluetoothServer()) << "Create WirelessService.";
// Service
connect(m_service, SIGNAL(characteristicChanged(QLowEnergyCharacteristic, QByteArray)), this, SLOT(characteristicChanged(QLowEnergyCharacteristic, QByteArray)));
connect(m_service, SIGNAL(characteristicRead(QLowEnergyCharacteristic, QByteArray)), this, SLOT(characteristicChanged(QLowEnergyCharacteristic, QByteArray)));
connect(m_service, SIGNAL(characteristicWritten(QLowEnergyCharacteristic, QByteArray)), this, SLOT(characteristicWritten(QLowEnergyCharacteristic, QByteArray)));
connect(m_service, SIGNAL(descriptorWritten(QLowEnergyDescriptor, QByteArray)), this, SLOT(descriptorWritten(QLowEnergyDescriptor, QByteArray)));
connect(m_service, SIGNAL(error(QLowEnergyService::ServiceError)), this, SLOT(serviceError(QLowEnergyService::ServiceError)));
// Get the wireless network device if there is any
if (!m_networkManager->wirelessAvailable()) {
qCWarning(dcNetworkManagerBluetoothServer()) << "WirelessService: There is no wireless network device available";
return;
}
qCDebug(dcNetworkManagerBluetoothServer()) << "WirelessService: Using" << m_networkManager->wirelessNetworkDevices().first();
m_device = m_networkManager->wirelessNetworkDevices().first();
connect(m_device, &WirelessNetworkDevice::bitRateChanged, this, &WirelessService::onWirelessDeviceBitRateChanged);
connect(m_device, &WirelessNetworkDevice::stateChanged, this, &WirelessService::onWirelessDeviceStateChanged);
connect(m_device, &WirelessNetworkDevice::wirelessModeChanged, this, &WirelessService::onWirelessModeChanged);
}
QLowEnergyService *WirelessService::service()
{
return m_service;
}
QLowEnergyServiceData WirelessService::serviceData(NetworkManager *networkManager)
{
QLowEnergyServiceData serviceData;
serviceData.setType(QLowEnergyServiceData::ServiceTypePrimary);
serviceData.setUuid(wirelessServiceUuid);
QLowEnergyDescriptorData clientConfigDescriptorData(QBluetoothUuid::ClientCharacteristicConfiguration, QByteArray(2, 0));
// Wifi commander characterisitc e081fec1-f757-4449-b9c9-bfa83133f7fc
QLowEnergyCharacteristicData wirelessCommanderCharacteristicData;
wirelessCommanderCharacteristicData.setUuid(wirelessCommanderCharacteristicUuid);
wirelessCommanderCharacteristicData.setProperties(QLowEnergyCharacteristic::Write);
wirelessCommanderCharacteristicData.setValueLength(0, 20);
serviceData.addCharacteristic(wirelessCommanderCharacteristicData);
// Response characterisitc e081fec2-f757-4449-b9c9-bfa83133f7fc
QLowEnergyCharacteristicData wirelessResponseCharacteristicData;
wirelessResponseCharacteristicData.setUuid(wirelessResponseCharacteristicUuid);
wirelessResponseCharacteristicData.setProperties(QLowEnergyCharacteristic::Notify);
wirelessResponseCharacteristicData.addDescriptor(clientConfigDescriptorData);
wirelessResponseCharacteristicData.setValueLength(0, 20);
serviceData.addCharacteristic(wirelessResponseCharacteristicData);
// Wireless connection status characterisitc e081fec3-f757-4449-b9c9-bfa83133f7fc
QLowEnergyCharacteristicData wirelessStatusCharacteristicData;
wirelessStatusCharacteristicData.setUuid(wirelessStateCharacteristicUuid);
wirelessStatusCharacteristicData.setProperties(QLowEnergyCharacteristic::Read | QLowEnergyCharacteristic::Notify);
wirelessStatusCharacteristicData.addDescriptor(clientConfigDescriptorData);
wirelessStatusCharacteristicData.setValueLength(1, 1);
if (networkManager->wirelessNetworkDevices().isEmpty()) {
wirelessStatusCharacteristicData.setValue(WirelessService::getWirelessNetworkDeviceState(NetworkDevice::NetworkDeviceStateUnknown));
} else {
wirelessStatusCharacteristicData.setValue(WirelessService::getWirelessNetworkDeviceState(networkManager->wirelessNetworkDevices().first()->deviceState()));
}
serviceData.addCharacteristic(wirelessStatusCharacteristicData);
// Wireless mode characterisitc e081fec4-f757-4449-b9c9-bfa83133f7fc
QLowEnergyCharacteristicData wirelessModeCharacteristicData;
wirelessModeCharacteristicData.setUuid(wirelessModeCharacteristicUuid);
wirelessModeCharacteristicData.setProperties(QLowEnergyCharacteristic::Read | QLowEnergyCharacteristic::Notify);
wirelessModeCharacteristicData.addDescriptor(clientConfigDescriptorData);
wirelessModeCharacteristicData.setValueLength(1, 1);
if (networkManager->wirelessNetworkDevices().isEmpty()) {
wirelessModeCharacteristicData.setValue(WirelessService::getWirelessMode(WirelessNetworkDevice::WirelessModeUnknown));
} else {
wirelessModeCharacteristicData.setValue(WirelessService::getWirelessMode(networkManager->wirelessNetworkDevices().first()->wirelessMode()));
}
serviceData.addCharacteristic(wirelessModeCharacteristicData);
return serviceData;
}
WirelessService::WirelessServiceResponse WirelessService::checkWirelessErrors()
{
// Check possible errors
if (!m_networkManager->available()) {
qCWarning(dcNetworkManagerBluetoothServer()) << "WirelessService: The networkmanager is not available.";
return WirelessServiceResponseNetworkManagerNotAvailable;
}
if (!m_device) {
qCWarning(dcNetworkManagerBluetoothServer()) << "WirelessService: There is no wireless device available.";
return WirelessServiceResponseWirelessNotAvailable;
}
if (!m_networkManager->networkingEnabled()) {
qCWarning(dcNetworkManagerBluetoothServer()) << "WirelessService: Networking not enabled";
return WirelessServiceResponseNetworkingNotEnabled;
}
if (!m_networkManager->wirelessEnabled()) {
qCWarning(dcNetworkManagerBluetoothServer()) << "WirelessService: Wireless not enabled";
return WirelessServiceResponseWirelessNotEnabled;
}
return WirelessServiceResponseSuccess;
}
QByteArray WirelessService::getWirelessNetworkDeviceState(const NetworkDevice::NetworkDeviceState &state)
{
switch (state) {
case NetworkDevice::NetworkDeviceStateUnknown:
return QByteArray::fromHex("00");
case NetworkDevice::NetworkDeviceStateUnmanaged:
return QByteArray::fromHex("01");
case NetworkDevice::NetworkDeviceStateUnavailable:
return QByteArray::fromHex("02");
case NetworkDevice::NetworkDeviceStateDisconnected:
return QByteArray::fromHex("03");
case NetworkDevice::NetworkDeviceStatePrepare:
return QByteArray::fromHex("04");
case NetworkDevice::NetworkDeviceStateConfig:
return QByteArray::fromHex("05");
case NetworkDevice::NetworkDeviceStateNeedAuth:
return QByteArray::fromHex("06");
case NetworkDevice::NetworkDeviceStateIpConfig:
return QByteArray::fromHex("07");
case NetworkDevice::NetworkDeviceStateIpCheck:
return QByteArray::fromHex("08");
case NetworkDevice::NetworkDeviceStateSecondaries:
return QByteArray::fromHex("09");
case NetworkDevice::NetworkDeviceStateActivated:
return QByteArray::fromHex("0a");
case NetworkDevice::NetworkDeviceStateDeactivating:
return QByteArray::fromHex("0b");
case NetworkDevice::NetworkDeviceStateFailed:
return QByteArray::fromHex("0c");
}
// Unknown
return QByteArray::fromHex("00");
}
QByteArray WirelessService::getWirelessMode(WirelessNetworkDevice::WirelessMode mode)
{
switch (mode) {
case WirelessNetworkDevice::WirelessModeUnknown:
return QByteArray::fromHex("00");
case WirelessNetworkDevice::WirelessModeAdhoc:
return QByteArray::fromHex("01");
case WirelessNetworkDevice::WirelessModeInfrastructure:
return QByteArray::fromHex("02");
case WirelessNetworkDevice::WirelessModeAccessPoint:
return QByteArray::fromHex("03");
}
// Unknown
return QByteArray::fromHex("00");
}
void WirelessService::streamData(const QVariantMap &responseMap)
{
QLowEnergyCharacteristic characteristic = m_service->characteristic(wirelessResponseCharacteristicUuid);
if (!characteristic.isValid()) {
qCWarning(dcNetworkManagerBluetoothServer()) << "WirelessService: Wireless response characteristic not valid";
return;
}
QByteArray data = QJsonDocument::fromVariant(responseMap).toJson(QJsonDocument::Compact) + '\n';
qCDebug(dcNetworkManagerBluetoothServer()) << "WirelessService: Start streaming response data:" << data.count() << "bytes";
int sentDataLength = 0;
QByteArray remainingData = data;
while (!remainingData.isEmpty()) {
QByteArray package = remainingData.left(20);
sentDataLength += package.count();
m_service->writeCharacteristic(characteristic, package);
remainingData = remainingData.remove(0, package.count());
}
qCDebug(dcNetworkManagerBluetoothServer()) << "WirelessService: Finished streaming response data";
}
QVariantMap WirelessService::createResponse(const WirelessService::WirelessServiceCommand &command, const WirelessService::WirelessServiceResponse &responseCode)
{
QVariantMap response;
response.insert("c", static_cast<int>(command));
response.insert("r", static_cast<int>(responseCode));
return response;
}
void WirelessService::commandGetNetworks(const QVariantMap &request)
{
Q_UNUSED(request)
if (!m_service) {
qCWarning(dcNetworkManagerBluetoothServer()) << "WirelessService: Could not stream wireless network list. Service not valid";
return;
}
QLowEnergyCharacteristic characteristic = m_service->characteristic(wirelessResponseCharacteristicUuid);
if (!characteristic.isValid()) {
qCWarning(dcNetworkManagerBluetoothServer()) << "WirelessService: Wireless response characteristic not valid";
return;
}
QVariantList accessPointVariantList;
foreach (WirelessAccessPoint *accessPoint, m_device->accessPoints()) {
QVariantMap accessPointVariantMap;
accessPointVariantMap.insert("e", accessPoint->ssid());
accessPointVariantMap.insert("m", accessPoint->macAddress());
accessPointVariantMap.insert("s", accessPoint->signalStrength());
accessPointVariantMap.insert("p", static_cast<int>(accessPoint->isProtected()));
accessPointVariantList.append(accessPointVariantMap);
}
QVariantMap response = createResponse(WirelessServiceCommandGetNetworks);
response.insert("p", accessPointVariantList);
streamData(response);
}
void WirelessService::commandConnect(const QVariantMap &request)
{
if (!m_service) {
qCWarning(dcNetworkManagerBluetoothServer()) << "WirelessService: Could not stream wireless network list. Service not valid";
return;
}
QLowEnergyCharacteristic characteristic = m_service->characteristic(wirelessResponseCharacteristicUuid);
if (!characteristic.isValid()) {
qCWarning(dcNetworkManagerBluetoothServer()) << "WirelessService: Wireless response characteristic not valid";
return;
}
if (!request.contains("p")) {
qCWarning(dcNetworkManagerBluetoothServer()) << "WirelessService: Connect command: Missing parameters.";
streamData(createResponse(WirelessServiceCommandConnect, WirelessServiceResponseIvalidParameters));
return;
}
QVariantMap parameters = request.value("p").toMap();
if (!parameters.contains("e") || !parameters.contains("p")) {
qCWarning(dcNetworkManagerBluetoothServer()) << "WirelessService: Connect command: Invalid parameters.";
streamData(createResponse(WirelessServiceCommandConnect, WirelessServiceResponseIvalidParameters));
return;
}
NetworkManager::NetworkManagerError networkError = m_networkManager->connectWifi(m_device->interface(), parameters.value("e").toString(), parameters.value("p").toString());
WirelessService::WirelessServiceResponse responseCode = WirelessService::WirelessServiceResponseSuccess;
switch (networkError) {
case NetworkManager::NetworkManagerErrorNoError:
break;
case NetworkManager::NetworkManagerErrorWirelessNetworkingDisabled:
responseCode = WirelessService::WirelessServiceResponseWirelessNotEnabled;
break;
case NetworkManager::NetworkManagerErrorWirelessConnectionFailed:
responseCode = WirelessService::WirelessServiceResponseUnknownError;
break;
default:
responseCode = WirelessService::WirelessServiceResponseUnknownError;
break;
}
streamData(createResponse(WirelessServiceCommandConnect, responseCode));
}
void WirelessService::commandConnectHidden(const QVariantMap &request)
{
Q_UNUSED(request)
// TODO:
qCWarning(dcNetworkManagerBluetoothServer()) << "Connect to hidden network is not implemented yet.";
}
void WirelessService::commandDisconnect(const QVariantMap &request)
{
Q_UNUSED(request)
if (!m_service) {
qCWarning(dcNetworkManagerBluetoothServer()) << "WirelessService: Could not stream wireless network list. Service not valid";
return;
}
QLowEnergyCharacteristic characteristic = m_service->characteristic(wirelessResponseCharacteristicUuid);
if (!characteristic.isValid()) {
qCWarning(dcNetworkManagerBluetoothServer()) << "WirelessService: Wireless response characteristic not valid";
return;
}
m_device->disconnectDevice();
streamData(createResponse(WirelessServiceCommandDisconnect));
}
void WirelessService::commandScan(const QVariantMap &request)
{
Q_UNUSED(request)
if (!m_service) {
qCWarning(dcNetworkManagerBluetoothServer()) << "WirelessService: Could not stream wireless network list. Service not valid";
return;
}
QLowEnergyCharacteristic characteristic = m_service->characteristic(wirelessResponseCharacteristicUuid);
if (!characteristic.isValid()) {
qCWarning(dcNetworkManagerBluetoothServer()) << "WirelessService: Wireless response characteristic not valid";
return;
}
m_device->scanWirelessNetworks();
streamData(createResponse(WirelessServiceCommandScan));
}
void WirelessService::commandGetCurrentConnection(const QVariantMap &request)
{
Q_UNUSED(request)
if (!m_service) {
qCWarning(dcNetworkManagerBluetoothServer()) << "WirelessService: Could not stream wireless network list. Service not valid";
return;
}
QLowEnergyCharacteristic characteristic = m_service->characteristic(wirelessResponseCharacteristicUuid);
if (!characteristic.isValid()) {
qCWarning(dcNetworkManagerBluetoothServer()) << "WirelessService: Wireless response characteristic not valid";
return;
}
QVariantMap connectionDataMap;
QNetworkInterface wifiInterface = QNetworkInterface::interfaceFromName(m_device->interface());
if (!m_device->activeAccessPoint() || !wifiInterface.isValid() || wifiInterface.addressEntries().isEmpty()) {
qCDebug(dcNetworkManagerBluetoothServer()) << "There is currently no access active accesspoint";
connectionDataMap.insert("e", "");
connectionDataMap.insert("m", "");
connectionDataMap.insert("s", 0);
connectionDataMap.insert("p", 0);
connectionDataMap.insert("i", "");
} else {
QHostAddress address;
// Note: for now, we'll just use the first IPv4 address. However, in a future version
// this should somehow pack all addresses, IPv4 and IPv6 ones.
foreach (const QNetworkAddressEntry &entry, wifiInterface.addressEntries()) {
if (entry.ip().protocol() == QAbstractSocket::IPv4Protocol) {
address = entry.ip();
break;
}
}
qCDebug(dcNetworkManagerBluetoothServer()) << "Current connection:" << m_device->activeAccessPoint() << address.toString();
connectionDataMap.insert("e", m_device->activeAccessPoint()->ssid());
connectionDataMap.insert("m", m_device->activeAccessPoint()->macAddress());
connectionDataMap.insert("s", m_device->activeAccessPoint()->signalStrength());
connectionDataMap.insert("p", static_cast<int>(m_device->activeAccessPoint()->isProtected()));
connectionDataMap.insert("i", address.toString());
}
QVariantMap response = createResponse(WirelessServiceCommandGetCurrentConnection);
response.insert("p", connectionDataMap);
streamData(response);
}
void WirelessService::commandStartAccessPoint(const QVariantMap &request)
{
if (!m_service) {
qCWarning(dcNetworkManagerBluetoothServer()) << "WirelessService: Could not start access point. Service is not valid.";
return;
}
QLowEnergyCharacteristic characteristic = m_service->characteristic(wirelessResponseCharacteristicUuid);
if (!characteristic.isValid()) {
qCWarning(dcNetworkManagerBluetoothServer()) << "WirelessService: Wireless response characteristic not valid";
return;
}
if (!request.contains("p")) {
qCWarning(dcNetworkManagerBluetoothServer()) << "WirelessService: Start access point command: Missing parameters.";
streamData(createResponse(WirelessServiceCommandStartAccessPoint, WirelessServiceResponseIvalidParameters));
return;
}
QVariantMap parameters = request.value("p").toMap();
if (!parameters.contains("e")) {
qCWarning(dcNetworkManagerBluetoothServer()) << "WirelessService: Missing ESSID (e) parameter.";
streamData(createResponse(WirelessServiceCommandStartAccessPoint, WirelessServiceResponseIvalidParameters));
return;
}
QString essid = parameters.value("e").toString();
if (essid.length() > 32) {
qCWarning(dcNetworkManagerBluetoothServer()) << "WirelessService: Invalid ESSID (e) parameter.";
streamData(createResponse(WirelessServiceCommandStartAccessPoint, WirelessServiceResponseIvalidParameters));
return;
}
if (!parameters.contains("p")) {
qCWarning(dcNetworkManagerBluetoothServer()) << "WirelessService: Missing passkey (p) parameter.";
streamData(createResponse(WirelessServiceCommandStartAccessPoint, WirelessServiceResponseIvalidParameters));
return;
}
QString passkey = parameters.value("p").toString();
if (passkey.length() < 8 || passkey.length() > 64) {
qCWarning(dcNetworkManagerBluetoothServer()) << "WirelessService: Invalid passkey (p) parameter.";
streamData(createResponse(WirelessServiceCommandStartAccessPoint, WirelessServiceResponseIvalidParameters));
return;
}
NetworkManager::NetworkManagerError status = m_networkManager->startAccessPoint(m_device->interface(), essid, passkey);
if (status != NetworkManager::NetworkManagerErrorNoError) {
qCWarning(dcNetworkManagerBluetoothServer()) << "Failed to start the access point:" << status;
// FIXME: Add more error codes so that we can actually report this failure to the client
streamData(createResponse(WirelessServiceCommandStartAccessPoint, WirelessServiceResponseUnknownError));
return;
}
streamData(createResponse(WirelessServiceCommandStartAccessPoint, WirelessServiceResponseSuccess));
}
void WirelessService::characteristicChanged(const QLowEnergyCharacteristic &characteristic, const QByteArray &value)
{
// Command
if (characteristic.uuid() == wirelessCommanderCharacteristicUuid) {
// Check if currently reading
if (m_readingInputData) {
m_inputDataStream.append(value);
} else {
m_inputDataStream.clear();
m_readingInputData = true;
m_inputDataStream.append(value);
}
// If command finished
if (value.endsWith('\n')) {
QJsonParseError error;
QJsonDocument jsonDocument = QJsonDocument::fromJson(m_inputDataStream, &error);
if (error.error != QJsonParseError::NoError) {
qCWarning(dcNetworkManagerBluetoothServer()) << "Got invalid json object" << m_inputDataStream;
m_inputDataStream.clear();
m_readingInputData = false;
return;
}
qCDebug(dcNetworkManagerBluetoothServer()) << "Got command stream" << jsonDocument.toJson();
processCommand(jsonDocument.toVariant().toMap());
m_inputDataStream.clear();
m_readingInputData = false;
}
// Limit possible data stream to prevent overflow
if (m_inputDataStream.length() >= 20 * 1024) {
m_inputDataStream.clear();
m_readingInputData = false;
return;
}
}
}
void WirelessService::characteristicRead(const QLowEnergyCharacteristic &characteristic, const QByteArray &value)
{
qCDebug(dcNetworkManagerBluetoothServer()) << "WirelessService: Characteristic read" << characteristic.uuid().toString() << value;
}
void WirelessService::characteristicWritten(const QLowEnergyCharacteristic &characteristic, const QByteArray &value)
{
qCDebug(dcNetworkManagerBluetoothServer()) << "WirelessService: Characteristic written" << characteristic.uuid().toString() << value;
}
void WirelessService::descriptorRead(const QLowEnergyDescriptor &descriptor, const QByteArray &value)
{
qCDebug(dcNetworkManagerBluetoothServer()) << "WirelessService: Descriptor read" << descriptor.uuid().toString() << value;
}
void WirelessService::descriptorWritten(const QLowEnergyDescriptor &descriptor, const QByteArray &value)
{
qCDebug(dcNetworkManagerBluetoothServer()) << "WirelessService: Descriptor written" << descriptor.uuid().toString() << value;
}
void WirelessService::serviceError(const QLowEnergyService::ServiceError &error)
{
QString errorString;
switch (error) {
case QLowEnergyService::NoError:
errorString = "No error";
break;
case QLowEnergyService::OperationError:
errorString = "Operation error";
break;
case QLowEnergyService::CharacteristicReadError:
errorString = "Characteristic read error";
break;
case QLowEnergyService::CharacteristicWriteError:
errorString = "Characteristic write error";
break;
case QLowEnergyService::DescriptorReadError:
errorString = "Descriptor read error";
break;
case QLowEnergyService::DescriptorWriteError:
errorString = "Descriptor write error";
break;
case QLowEnergyService::UnknownError:
errorString = "Unknown error";
break;
}
qCWarning(dcNetworkManagerBluetoothServer()) << "WirelessService: Error:" << errorString;
}
void WirelessService::processCommand(const QVariantMap &request)
{
if (!request.contains("c")) {
qCWarning(dcNetworkManagerBluetoothServer()) << "Invalid request. Command value missing.";
streamData(createResponse(WirelessServiceCommandConnect, WirelessServiceResponseIvalidCommand));
return;
}
bool commandIntOk;
int command = request.value("c").toInt(&commandIntOk);
if (!commandIntOk) {
qCWarning(dcNetworkManagerBluetoothServer()) << "Invalid request. Could not convert method to interger.";
streamData(createResponse(WirelessServiceCommandConnect, WirelessServiceResponseIvalidCommand));
return;
}
// Check wireless errors
WirelessServiceResponse responseCode = checkWirelessErrors();
if (responseCode != WirelessServiceResponseSuccess) {
streamData(createResponse(static_cast<WirelessServiceCommand>(command), responseCode));
return;
}
// Process method
qCDebug(dcNetworkManagerBluetoothServer()) << "Received command" << static_cast<WirelessServiceCommand>(command);
switch (command) {
case WirelessServiceCommandGetNetworks:
commandGetNetworks(request);
break;
case WirelessServiceCommandConnect:
commandConnect(request);
break;
case WirelessServiceCommandConnectHidden:
commandConnectHidden(request);
break;
case WirelessServiceCommandDisconnect:
commandDisconnect(request);
break;
case WirelessServiceCommandScan:
commandScan(request);
break;
case WirelessServiceCommandGetCurrentConnection:
commandGetCurrentConnection(request);
break;
case WirelessServiceCommandStartAccessPoint:
commandStartAccessPoint(request);
break;
default:
qCWarning(dcNetworkManagerBluetoothServer()) << "Invalid request. Unknown command" << command;
streamData(createResponse(WirelessServiceCommandConnect, WirelessServiceResponseIvalidCommand));
break;
}
}
void WirelessService::onWirelessDeviceBitRateChanged(const int &bitRate)
{
Q_UNUSED(bitRate)
}
void WirelessService::onWirelessDeviceStateChanged(const NetworkDevice::NetworkDeviceState &state)
{
qCDebug(dcNetworkManagerBluetoothServer()) << "WirelessService: Wireless network device state changed" << state;
if (!m_service) {
qCWarning(dcNetworkManagerBluetoothServer()) << "WirelessService: Could not update wireless network device state. Service not valid";
return;
}
QLowEnergyCharacteristic characteristic = m_service->characteristic(wirelessStateCharacteristicUuid);
if (!characteristic.isValid()) {
qCWarning(dcNetworkManagerBluetoothServer()) << "WirelessService: Could not update wireless network device state. Characteristic not valid";
return;
}
m_service->writeCharacteristic(characteristic, WirelessService::getWirelessNetworkDeviceState(state));
}
void WirelessService::onWirelessModeChanged(WirelessNetworkDevice::WirelessMode mode)
{
if (!m_service) {
qCWarning(dcNetworkManagerBluetoothServer()) << "WirelessService: Could not update wireless device mode. Service not valid";
return;
}
QLowEnergyCharacteristic characteristic = m_service->characteristic(wirelessModeCharacteristicUuid);
if (!characteristic.isValid()) {
qCWarning(dcNetworkManagerBluetoothServer()) << "WirelessService: Could not update wireless device mode. Characteristic not valid";
return;
}
qCDebug(dcNetworkManagerBluetoothServer()) << "WirelessService: Notify wireless mode changed" << WirelessService::getWirelessMode(mode);
m_service->writeCharacteristic(characteristic, WirelessService::getWirelessMode(mode));
}

View File

@ -1,123 +0,0 @@
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*
* Copyright 2013 - 2020, nymea GmbH
* Contact: contact@nymea.io
*
* This file is part of nymea.
* This project including source code and documentation is protected by
* copyright law, and remains the property of nymea GmbH. All rights, including
* reproduction, publication, editing and translation, are reserved. The use of
* this project is subject to the terms of a license agreement to be concluded
* with nymea GmbH in accordance with the terms of use of nymea GmbH, available
* under https://nymea.io/license
*
* GNU Lesser General Public License Usage
* Alternatively, this project may be redistributed and/or modified under the
* terms of the GNU Lesser General Public License as published by the Free
* Software Foundation; version 3. This project 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 project. If not, see <https://www.gnu.org/licenses/>.
*
* For any further details and any questions please contact us under
* contact@nymea.io or see our FAQ/Licensing Information on
* https://nymea.io/license/faq
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
#ifndef WIRELESSSERVICE_H
#define WIRELESSSERVICE_H
#include <QObject>
#include <QVariantMap>
#include <QLowEnergyService>
#include <QLowEnergyServiceData>
#include "../networkmanager.h"
#include "../wirelessaccesspoint.h"
#include "../wirelessnetworkdevice.h"
class WirelessService : public QObject
{
Q_OBJECT
public:
enum WirelessServiceCommand {
WirelessServiceCommandInvalid = -1,
WirelessServiceCommandGetNetworks = 0x00,
WirelessServiceCommandConnect = 0x01,
WirelessServiceCommandConnectHidden = 0x02,
WirelessServiceCommandDisconnect = 0x03,
WirelessServiceCommandScan = 0x04,
WirelessServiceCommandGetCurrentConnection = 0x05,
WirelessServiceCommandStartAccessPoint = 0x06
};
Q_ENUM(WirelessServiceCommand)
enum WirelessServiceResponse {
WirelessServiceResponseSuccess = 0x00,
WirelessServiceResponseIvalidCommand = 0x01,
WirelessServiceResponseIvalidParameters = 0x02,
WirelessServiceResponseNetworkManagerNotAvailable = 0x03,
WirelessServiceResponseWirelessNotAvailable = 0x04,
WirelessServiceResponseWirelessNotEnabled = 0x05,
WirelessServiceResponseNetworkingNotEnabled = 0x06,
WirelessServiceResponseUnknownError = 0x07
};
Q_ENUM(WirelessServiceResponse)
explicit WirelessService(QLowEnergyService *service, NetworkManager *networkManager, QObject *parent = nullptr);
QLowEnergyService *service();
static QLowEnergyServiceData serviceData(NetworkManager *networkManager);
private:
QLowEnergyService *m_service = nullptr;
NetworkManager *m_networkManager = nullptr;
WirelessNetworkDevice *m_device = nullptr;
bool m_readingInputData = false;
QByteArray m_inputDataStream;
WirelessServiceResponse checkWirelessErrors();
// Note: static to be available in serviceData
static QByteArray getWirelessNetworkDeviceState(const NetworkDevice::NetworkDeviceState &state);
static QByteArray getWirelessMode(WirelessNetworkDevice::WirelessMode mode);
void streamData(const QVariantMap &responseMap);
QVariantMap createResponse(const WirelessServiceCommand &command, const WirelessServiceResponse &responseCode = WirelessServiceResponseSuccess);
// Methods
void commandGetNetworks(const QVariantMap &request);
void commandConnect(const QVariantMap &request);
void commandConnectHidden(const QVariantMap &request);
void commandDisconnect(const QVariantMap &request);
void commandScan(const QVariantMap &request);
void commandGetCurrentConnection(const QVariantMap &request);
void commandStartAccessPoint(const QVariantMap &request);
private slots:
// Service
void characteristicChanged(const QLowEnergyCharacteristic &characteristic, const QByteArray &value);
void characteristicRead(const QLowEnergyCharacteristic &characteristic, const QByteArray &value);
void characteristicWritten(const QLowEnergyCharacteristic &characteristic, const QByteArray &value);
void descriptorRead(const QLowEnergyDescriptor &descriptor, const QByteArray &value);
void descriptorWritten(const QLowEnergyDescriptor &descriptor, const QByteArray &value);
void serviceError(const QLowEnergyService::ServiceError &error);
// Commands
void processCommand(const QVariantMap &request);
// Wireless network device
void onWirelessDeviceBitRateChanged(const int &bitRate);
void onWirelessDeviceStateChanged(const NetworkDevice::NetworkDeviceState &state);
void onWirelessModeChanged(WirelessNetworkDevice::WirelessMode mode);
};
#endif // WIRELESSSERVICE_H

View File

@ -28,24 +28,6 @@ SOURCES += \
wirelessnetworkdevice.cpp \
networkmanagerutils.cpp
equals(QT_MAJOR_VERSION, 5):!lessThan(QT_MINOR_VERSION, 7) {
message(Building with Bluetooth LE server functionality. Qt $${QT_VERSION}.)
QT += bluetooth
HEADERS += \
bluetooth/bluetoothserver.h \
bluetooth/bluetoothuuids.h \
bluetooth/networkservice.h \
bluetooth/wirelessservice.h \
SOURCES += \
bluetooth/bluetoothserver.cpp \
bluetooth/networkservice.cpp \
bluetooth/wirelessservice.cpp \
} else {
message(Bluetooth LE server functionality not supported with Qt $${QT_VERSION}.)
}
target.path = $$[QT_INSTALL_LIBS]
INSTALLS += target