From 7397c479605f4e141e989dc4036e59328ea36488 Mon Sep 17 00:00:00 2001 From: Jenkins Date: Thu, 19 Sep 2019 09:52:51 +0200 Subject: [PATCH 1/8] Jenkins release build --- debian/changelog | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/debian/changelog b/debian/changelog index 3ab4cc6..ceec98b 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,10 @@ +nymea-networkmanager (0.4.1) xenial; urgency=medium + + [ Simon Stürz ] + * Update pkg-config include for libnymea-networkmanager + + -- Jenkins Thu, 19 Sep 2019 09:52:51 +0200 + nymea-networkmanager (0.4.0) bionic; urgency=medium * Move libnymea-networkmanager out of this project into a separate one From 163f4ce77f4f358f823a91df1487aa8d5dc5da2f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20St=C3=BCrz?= Date: Tue, 8 Oct 2019 15:19:02 +0200 Subject: [PATCH 2/8] Migrate to new bluetooth server and improve mode handling --- README.md | 2 +- debian/changelog | 6 + debian/nymea-networkmanager.service | 5 +- nymea-networkmanager.pri | 2 + .../bluetooth/bluetoothserver.cpp | 478 --------------- .../bluetooth/bluetoothserver.h | 128 ---- .../bluetooth/bluetoothuuids.h | 46 -- .../bluetooth/networkservice.cpp | 377 ------------ .../bluetooth/networkservice.h | 94 --- .../bluetooth/systemservice.cpp | 256 -------- .../bluetooth/systemservice.h | 60 -- .../bluetooth/wirelessservice.cpp | 574 ------------------ .../bluetooth/wirelessservice.h | 116 ---- nymea-networkmanager/core.cpp | 109 +--- nymea-networkmanager/core.h | 18 +- nymea-networkmanager/loggingcategories.cpp | 1 - nymea-networkmanager/loggingcategories.h | 1 - nymea-networkmanager/main.cpp | 6 +- nymea-networkmanager/nymea-networkmanager.pro | 8 +- 19 files changed, 37 insertions(+), 2250 deletions(-) delete mode 100644 nymea-networkmanager/bluetooth/bluetoothserver.cpp delete mode 100644 nymea-networkmanager/bluetooth/bluetoothserver.h delete mode 100644 nymea-networkmanager/bluetooth/bluetoothuuids.h delete mode 100644 nymea-networkmanager/bluetooth/networkservice.cpp delete mode 100644 nymea-networkmanager/bluetooth/networkservice.h delete mode 100644 nymea-networkmanager/bluetooth/systemservice.cpp delete mode 100644 nymea-networkmanager/bluetooth/systemservice.h delete mode 100644 nymea-networkmanager/bluetooth/wirelessservice.cpp delete mode 100644 nymea-networkmanager/bluetooth/wirelessservice.h diff --git a/README.md b/README.md index 6ff3321..ea22e73 100644 --- a/README.md +++ b/README.md @@ -66,7 +66,7 @@ this repository and it will be installed to /etc/nymea-networkmanager.conf with This daemon allows to configure a wifi network using a bluetooth low energy connection. - Copyright © 2018 - 2019 Simon Stürz + Copyright © 2018 - 2019 Simon Stürz Options: -h, --help Displays this help. diff --git a/debian/changelog b/debian/changelog index ceec98b..d6cde0e 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,9 @@ +nymea-networkmanager (0.5.0) UNRELEASED; urgency=medium + + * Migrate to libnymea-networkmanager bluetooth server and improve mode handling + + -- Simon Stürz Tue, 08 Oct 2019 15:17:22 +0200 + nymea-networkmanager (0.4.1) xenial; urgency=medium [ Simon Stürz ] diff --git a/debian/nymea-networkmanager.service b/debian/nymea-networkmanager.service index 73ccc7d..de12405 100644 --- a/debian/nymea-networkmanager.service +++ b/debian/nymea-networkmanager.service @@ -1,7 +1,8 @@ [Unit] Description=Daemon for nymea to configure wifi network using a Bluetooth LE connection -Documentation=https://github.com/guh/nymea-networkmanager -After=network.target +Documentation=https://github.com/nymea/nymea-networkmanager +Wants=bluetooth.service NetworkManager.service +After=bluetooth.service NetworkManager.service [Service] ExecStart=/usr/bin/nymea-networkmanager -d diff --git a/nymea-networkmanager.pri b/nymea-networkmanager.pri index f2730f7..a94a33d 100644 --- a/nymea-networkmanager.pri +++ b/nymea-networkmanager.pri @@ -4,3 +4,5 @@ QMAKE_LFLAGS *= -std=c++1z top_srcdir=$$PWD top_builddir=$$shadowed($$PWD) +VERSION_STRING=$$system('dpkg-parsechangelog | sed -n -e "s/^Version: //p"') +DEFINES += VERSION_STRING=\\\"$${VERSION_STRING}\\\" diff --git a/nymea-networkmanager/bluetooth/bluetoothserver.cpp b/nymea-networkmanager/bluetooth/bluetoothserver.cpp deleted file mode 100644 index bc437be..0000000 --- a/nymea-networkmanager/bluetooth/bluetoothserver.cpp +++ /dev/null @@ -1,478 +0,0 @@ -/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * - * * - * Copyright (C) 2018 Simon Stürz * - * * - * This file is part of nymea-networkmanager. * - * * - * nymea-networkmanager 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, either version 3 of the License, * - * or (at your option) any later version. * - * * - * nymea-networkmanager 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 nymea-networkmanager. If not, see . * - * * - * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ - -#include "bluetoothserver.h" -#include "loggingcategories.h" -#include "bluetoothuuids.h" - -#include -#include - -BluetoothServer::BluetoothServer(QObject *parent) : - QObject(parent) -{ - -} - -BluetoothServer::~BluetoothServer() -{ - qCDebug(dcBluetoothServer()) << "Destroy bluetooth server."; - if (m_controller) - m_controller->stopAdvertising(); - - if (m_localDevice) - m_localDevice->setHostMode(QBluetoothLocalDevice::HostConnectable); - -} - -QString BluetoothServer::machineId() const -{ - return m_machineId; -} - -void BluetoothServer::setMachineId(const QString &machineId) -{ - m_machineId = machineId; -} - -QString BluetoothServer::advertiseName() const -{ - return m_advertiseName; -} - -void BluetoothServer::setAdvertiseName(const QString &advertiseName) -{ - m_advertiseName = advertiseName; -} - -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); - modelNumberCharData.setValue(m_machineId.toUtf8()); - modelNumberCharData.setProperties(QLowEnergyCharacteristic::Read); - serviceData.addCharacteristic(modelNumberCharData); - - // Firmware revision string 0x2a26 - QLowEnergyCharacteristicData firmwareRevisionCharData; - firmwareRevisionCharData.setUuid(QBluetoothUuid::FirmwareRevisionString); - firmwareRevisionCharData.setValue(QString("1.0.0").toUtf8()); - firmwareRevisionCharData.setProperties(QLowEnergyCharacteristic::Read); - serviceData.addCharacteristic(firmwareRevisionCharData); - - // Hardware revision string 0x2a27 - QLowEnergyCharacteristicData hardwareRevisionCharData; - hardwareRevisionCharData.setUuid(QBluetoothUuid::HardwareRevisionString); - hardwareRevisionCharData.setValue(QString("1.0.0").toUtf8()); - hardwareRevisionCharData.setProperties(QLowEnergyCharacteristic::Read); - serviceData.addCharacteristic(hardwareRevisionCharData); - - // Software revision string 0x2a28 - QLowEnergyCharacteristicData softwareRevisionCharData; - softwareRevisionCharData.setUuid(QBluetoothUuid::SoftwareRevisionString); - softwareRevisionCharData.setValue(QCoreApplication::applicationVersion().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); - nameCharData.setValue(QCoreApplication::applicationName().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); -} - -void BluetoothServer::startAdvertising() -{ - QLowEnergyAdvertisingData advertisingData; - advertisingData.setDiscoverability(QLowEnergyAdvertisingData::DiscoverabilityGeneral); - advertisingData.setIncludePowerLevel(true); - advertisingData.setLocalName(m_advertiseName); - - // TODO: set guh manufacturer SIG data - - // Note: start advertising in 100 ms interval, this makes the device better discoverable on certain phones - QLowEnergyAdvertisingParameters advertisingParameters; - advertisingParameters.setInterval(100,100); - - qCDebug(dcBluetoothServer()) << "Start advertising" << advertisingData.localName() << m_localDevice->address().toString(); - m_controller->startAdvertising(advertisingParameters, advertisingData, advertisingData); -} - -void BluetoothServer::onHostModeStateChanged(const QBluetoothLocalDevice::HostMode mode) -{ - switch (mode) { - case QBluetoothLocalDevice::HostConnectable: - qCDebug(dcBluetoothServer()) << "Bluetooth host in connectable mode."; - break; - case QBluetoothLocalDevice::HostDiscoverable: - qCDebug(dcBluetoothServer()) << "Bluetooth host in discoverable mode."; - break; - case QBluetoothLocalDevice::HostPoweredOff: - qCDebug(dcBluetoothServer()) << "Bluetooth host in power off mode."; - stop(); - start(); - break; - case QBluetoothLocalDevice::HostDiscoverableLimitedInquiry: - qCDebug(dcBluetoothServer()) << "Bluetooth host in discoverable limited inquiry mode."; - break; - } -} - -void BluetoothServer::onDeviceConnected(const QBluetoothAddress &address) -{ - qCDebug(dcBluetoothServer()) << "Device connected" << address.toString(); -} - -void BluetoothServer::onDeviceDisconnected(const QBluetoothAddress &address) -{ - qCDebug(dcBluetoothServer()) << "Device disconnected" << address.toString(); -} - -void BluetoothServer::onError(const QLowEnergyController::Error &error) -{ - qCWarning(dcBluetoothServer()) << "Bluetooth error occured:" << error << m_controller->errorString(); - stop(); - start(); -} - -void BluetoothServer::onConnected() -{ - qCDebug(dcBluetoothServer()) << "Client connected" << m_controller->remoteName() << m_controller->remoteAddress(); - setConnected(true); -} - -void BluetoothServer::onDisconnected() -{ - qCDebug(dcBluetoothServer()) << "Client disconnected"; - setConnected(false); -} - -void BluetoothServer::onControllerStateChanged(const QLowEnergyController::ControllerState &state) -{ - switch (state) { - case QLowEnergyController::UnconnectedState: - qCDebug(dcBluetoothServer()) << "Controller state disonnected."; - setConnected(false); - break; - case QLowEnergyController::ConnectingState: - qCDebug(dcBluetoothServer()) << "Controller state connecting..."; - setConnected(false); - break; - case QLowEnergyController::ConnectedState: - qCDebug(dcBluetoothServer()) << "Controller state connected." << m_controller->remoteName() << m_controller->remoteAddress(); - setConnected(true); - break; - case QLowEnergyController::DiscoveringState: - qCDebug(dcBluetoothServer()) << "Controller state discovering..."; - break; - case QLowEnergyController::DiscoveredState: - qCDebug(dcBluetoothServer()) << "Controller state discovered."; - break; - case QLowEnergyController::ClosingState: - qCDebug(dcBluetoothServer()) << "Controller state closing..."; - break; - case QLowEnergyController::AdvertisingState: - qCDebug(dcBluetoothServer()) << "Controller state advertising..."; - setRunning(true); - break; - } -} - -void BluetoothServer::characteristicChanged(const QLowEnergyCharacteristic &characteristic, const QByteArray &value) -{ - qCDebug(dcBluetoothServer()) << "Service characteristic changed" << characteristic.uuid() << value; -} - -void BluetoothServer::characteristicRead(const QLowEnergyCharacteristic &characteristic, const QByteArray &value) -{ - qCDebug(dcBluetoothServer()) << "Service characteristic read" << characteristic.uuid() << value; -} - -void BluetoothServer::characteristicWritten(const QLowEnergyCharacteristic &characteristic, const QByteArray &value) -{ - qCDebug(dcBluetoothServer()) << "Service characteristic written" << characteristic.uuid() << value; -} - -void BluetoothServer::descriptorRead(const QLowEnergyDescriptor &descriptor, const QByteArray &value) -{ - qCDebug(dcBluetoothServer()) << "Descriptor read" << descriptor.uuid() << value; -} - -void BluetoothServer::descriptorWritten(const QLowEnergyDescriptor &descriptor, const QByteArray &value) -{ - qCDebug(dcBluetoothServer()) << "Descriptor written" << descriptor.uuid() << value; -} - -void BluetoothServer::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(dcBluetoothServer()) << "Service error:" << errorString; -} - -void BluetoothServer::start() -{ - // Check if a user is connected - if (m_connected) { - qCDebug(dcBluetoothServer()) << "User is connected. Doing nothing."; - return; - } - - if (running()) { - qCDebug(dcBluetoothServer()) << "Already running."; - m_localDevice->setHostMode(QBluetoothLocalDevice::HostDiscoverable); - return; - } - - qCDebug(dcBluetoothServer()) << "-------------------------------------"; - qCDebug(dcBluetoothServer()) << "Starting bluetooth server"; - qCDebug(dcBluetoothServer()) << "-------------------------------------"; - - // Local bluetooth device - m_localDevice = new QBluetoothLocalDevice(this); - if (!m_localDevice->isValid()) { - qCCritical(dcBluetoothServer()) << "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(dcBluetoothServer()) << "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 services - m_networkService = new NetworkService(m_controller->addService(NetworkService::serviceData(), m_controller), m_controller); - m_wirelessService = new WirelessService(m_controller->addService(WirelessService::serviceData(), m_controller), m_controller); - - startAdvertising(); -} - -void BluetoothServer::stop() -{ - if (connected() && m_controller) { - m_controller->disconnectFromDevice(); - } - - if (!m_running) - return; - - qCDebug(dcBluetoothServer()) << "-------------------------------------"; - qCDebug(dcBluetoothServer()) << "Stopping bluetooth server."; - qCDebug(dcBluetoothServer()) << "-------------------------------------"; - - if (m_networkService) { - delete m_networkService; - m_networkService = nullptr; - } - - if (m_wirelessService) { - delete m_wirelessService; - m_wirelessService = nullptr; - } - - if (m_controller) { - qCDebug(dcBluetoothServer()) << "Stop advertising."; - m_controller->stopAdvertising(); - delete m_controller; - m_controller = nullptr; - } - - if (m_localDevice) { - qCDebug(dcBluetoothServer()) << "Set host mode to connectable."; - m_localDevice->setHostMode(QBluetoothLocalDevice::HostConnectable); - delete m_localDevice; - m_localDevice = nullptr; - } - - setConnected(false); - setRunning(false); -} - -void BluetoothServer::onNetworkManagerAvailableChanged(bool available) -{ - if (m_networkService) - m_networkService->setNetworkManagerAvailable(available); -} - -void BluetoothServer::onNetworkingEnabledChanged(bool enabled) -{ - if (m_networkService) - m_networkService->setNetworkingEnabled(enabled); -} - -void BluetoothServer::onWirelessNetworkingEnabledChanged(bool enabled) -{ - if (m_networkService) - m_networkService->setWirelessNetworkingEnabled(enabled); -} - -void BluetoothServer::onNetworkManagerStateChanged(const NetworkManager::NetworkManagerState &state) -{ - if (m_networkService) - m_networkService->setNetworkManagerState(state); -} - -void BluetoothServer::onWirelessDeviceBitRateChanged(int bitRate) -{ - if (m_wirelessService) - m_wirelessService->onWirelessDeviceBitRateChanged(bitRate); -} - -void BluetoothServer::onWirelessDeviceModeChanged(WirelessNetworkDevice::Mode mode) -{ - if (m_wirelessService) - m_wirelessService->onWirelessModeChanged(mode); -} - -void BluetoothServer::onWirelessDeviceStateChanged(const NetworkDevice::NetworkDeviceState state) -{ - if (m_wirelessService) - m_wirelessService->onWirelessDeviceStateChanged(state); -} - diff --git a/nymea-networkmanager/bluetooth/bluetoothserver.h b/nymea-networkmanager/bluetooth/bluetoothserver.h deleted file mode 100644 index c72a1e3..0000000 --- a/nymea-networkmanager/bluetooth/bluetoothserver.h +++ /dev/null @@ -1,128 +0,0 @@ -/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * - * * - * Copyright (C) 2018 Simon Stürz * - * * - * This file is part of nymea-networkmanager. * - * * - * nymea-networkmanager 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, either version 3 of the License, * - * or (at your option) any later version. * - * * - * nymea-networkmanager 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 nymea-networkmanager. If not, see . * - * * - * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ - -#ifndef BLUETOOTHSERVER_H -#define BLUETOOTHSERVER_H - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "networkservice.h" -#include "wirelessservice.h" -#include "systemservice.h" -#include "nymea-networkmanager/networkmanager.h" - -class BluetoothServer : public QObject -{ - Q_OBJECT -public: - - explicit BluetoothServer(QObject *parent = nullptr); - ~BluetoothServer(); - - QString machineId() const; - void setMachineId(const QString &machineId); - - QString advertiseName() const; - void setAdvertiseName(const QString &advertiseName); - - bool running() const; - bool connected() const; - -private: - QString m_machineId = "nymea-box"; - QString m_advertiseName = "nymea"; - 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); - - void startAdvertising(); - -signals: - void runningChanged(bool running); - void connectedChanged(bool connected); - -private slots: - // Local bluetooth device - void onHostModeStateChanged(const QBluetoothLocalDevice::HostMode mode); - void onDeviceConnected(const QBluetoothAddress &address); - void onDeviceDisconnected(const QBluetoothAddress &address); - void onError(const QLowEnergyController::Error &error); - - // Bluetooth controller - void onConnected(); - void onDisconnected(); - void onControllerStateChanged(const 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(const QLowEnergyService::ServiceError &error); - -public slots: - void start(); - void stop(); - - // Network manager - void onNetworkManagerAvailableChanged(bool available); - void onNetworkingEnabledChanged(bool enabled); - void onWirelessNetworkingEnabledChanged(bool enabled); - void onNetworkManagerStateChanged(const NetworkManager::NetworkManagerState &state); - - // Wireless device - void onWirelessDeviceBitRateChanged(int bitRate); - void onWirelessDeviceModeChanged(WirelessNetworkDevice::Mode mode); - void onWirelessDeviceStateChanged(const NetworkDevice::NetworkDeviceState state); - -}; - -#endif // BLUETOOTHSERVER_H diff --git a/nymea-networkmanager/bluetooth/bluetoothuuids.h b/nymea-networkmanager/bluetooth/bluetoothuuids.h deleted file mode 100644 index 92c7ab8..0000000 --- a/nymea-networkmanager/bluetooth/bluetoothuuids.h +++ /dev/null @@ -1,46 +0,0 @@ -/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * - * * - * Copyright (C) 2018 Simon Stürz * - * * - * This file is part of nymea-networkmanager. * - * * - * nymea-networkmanager 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, either version 3 of the License, * - * or (at your option) any later version. * - * * - * nymea-networkmanager 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 nymea-networkmanager. If not, see . * - * * - * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ - -#ifndef BLUETOOTHUUIDS_H -#define BLUETOOTHUUIDS_H - -#include - -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")); - -static QBluetoothUuid systemServiceUuid = QBluetoothUuid(QUuid("e081fed0-f757-4449-b9c9-bfa83133f7fc")); -static QBluetoothUuid systemCommanderCharacteristicUuid = QBluetoothUuid(QUuid("e081fed1-f757-4449-b9c9-bfa83133f7fc")); -static QBluetoothUuid systemResponseCharacteristicUuid = QBluetoothUuid(QUuid("e081fed2-f757-4449-b9c9-bfa83133f7fc")); -static QBluetoothUuid systemUpdateCharacteristicUuid = QBluetoothUuid(QUuid("e081fed3-f757-4449-b9c9-bfa83133f7fc")); - - -#endif // BLUETOOTHUUIDS_H diff --git a/nymea-networkmanager/bluetooth/networkservice.cpp b/nymea-networkmanager/bluetooth/networkservice.cpp deleted file mode 100644 index efd6da9..0000000 --- a/nymea-networkmanager/bluetooth/networkservice.cpp +++ /dev/null @@ -1,377 +0,0 @@ -/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * - * * - * Copyright (C) 2018 Simon Stürz * - * * - * This file is part of nymea-networkmanager. * - * * - * nymea-networkmanager 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, either version 3 of the License, * - * or (at your option) any later version. * - * * - * nymea-networkmanager 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 nymea-networkmanager. If not, see . * - * * - * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ - -#include "networkservice.h" - -#include "core.h" -#include "bluetoothuuids.h" -#include "loggingcategories.h" - -#include -#include - -NetworkService::NetworkService(QLowEnergyService *service, QObject *parent) : - QObject(parent), - m_service(service) -{ - qCDebug(dcBluetoothServer()) << "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))); - - connect(Core::instance()->networkManager(), &NetworkManager::stateChanged, this, &NetworkService::setNetworkManagerState); - connect(Core::instance()->networkManager(), &NetworkManager::availableChanged, this, &NetworkService::setNetworkManagerAvailable); - connect(Core::instance()->networkManager(), &NetworkManager::networkingEnabledChanged, this, &NetworkService::setNetworkingEnabled); - connect(Core::instance()->networkManager(), &NetworkManager::wirelessEnabledChanged, this, &NetworkService::setWirelessNetworkingEnabled); - - setNetworkManagerState(Core::instance()->networkManager()->state()); - setNetworkManagerAvailable(Core::instance()->networkManager()->available()); - setNetworkingEnabled(Core::instance()->networkManager()->networkingEnabled()); - setWirelessNetworkingEnabled(Core::instance()->networkManager()->wirelessEnabled()); -} - -NetworkService::~NetworkService() -{ - qCDebug(dcBluetoothServer()) << "Delete network service"; -} - -QLowEnergyService *NetworkService::service() -{ - return m_service; -} - -void NetworkService::setNetworkManagerAvailable(bool available) -{ - m_networkManagerAvailable = available; -} - -void NetworkService::setNetworkManagerState(const NetworkManager::NetworkManagerState &state) -{ - if (m_state == state) - return; - - m_state = state; - - if (!m_service) { - qCWarning(dcBluetoothServer()) << "NetworkService: Could not updatet network manager status. Service not valid"; - return; - } - - QLowEnergyCharacteristic characteristic = m_service->characteristic(networkStatusCharacteristicUuid); - if (!characteristic.isValid()) { - qCWarning(dcBluetoothServer()) << "NetworkService: Could not update network manager status. Characteristic not valid"; - return; - } - - qCDebug(dcBluetoothServer()) << "NetworkService: Notify state changed" << NetworkService::getNetworkManagerStateByteArray(m_state); - m_service->writeCharacteristic(characteristic, NetworkService::getNetworkManagerStateByteArray(m_state)); -} - -void NetworkService::setNetworkingEnabled(bool enabled) -{ - if (m_networkingEnabled == enabled) - return; - - m_networkingEnabled = enabled; - - if (!m_service) { - qCWarning(dcBluetoothServer()) << "NetworkService: Could not set networking enabled. Service not valid"; - return; - } - - QLowEnergyCharacteristic characteristic = m_service->characteristic(networkingEnabledCharacteristicUuid); - if (!characteristic.isValid()) { - qCWarning(dcBluetoothServer()) << "NetworkService: Could not set networking enabled. Characteristic not valid"; - return; - } - - qCDebug(dcBluetoothServer()) << "NetworkService: Notify networking enabled changed:" << (m_networkingEnabled ? "enabled" : "disabled"); - m_service->writeCharacteristic(characteristic, m_networkingEnabled ? QByteArray::fromHex("01") : QByteArray::fromHex("00")); -} - -void NetworkService::setWirelessNetworkingEnabled(bool enabled) -{ - if (m_wirelessNetworkingEnabled == enabled) - return; - - m_wirelessNetworkingEnabled = enabled; - - if (!m_service) { - qCWarning(dcBluetoothServer()) << "NetworkService: Could not set wireless enabled. Service not valid"; - return; - } - - QLowEnergyCharacteristic characteristic = m_service->characteristic(wirelessEnabledCharacteristicUuid); - if (!characteristic.isValid()) { - qCWarning(dcBluetoothServer()) << "NetworkService: Could not set wireless enabled. Characteristic not valid"; - return; - } - - qCDebug(dcBluetoothServer()) << "NetworkService: Notify wireless networking enabled changed:" << (m_wirelessNetworkingEnabled ? "enabled" : "disabled"); - m_service->writeCharacteristic(characteristic, m_wirelessNetworkingEnabled ? QByteArray::fromHex("01") : QByteArray::fromHex("00")); -} - -QLowEnergyServiceData NetworkService::serviceData() -{ - 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::NetworkManagerStateUnknown)); - 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.addDescriptor(clientConfigDescriptorData); - networkingEnabledStatusData.setValue(QByteArray::fromHex("00")); - serviceData.addCharacteristic(networkingEnabledStatusData); - - // Wireless enabled ef6d6615-b8af-49e0-9eca-ab343513641c - QLowEnergyCharacteristicData wirelessEnabledStatusData; - wirelessEnabledStatusData.setUuid(wirelessEnabledCharacteristicUuid); - wirelessEnabledStatusData.setValue(QByteArray(1, 0)); - wirelessEnabledStatusData.addDescriptor(clientConfigDescriptorData); - wirelessEnabledStatusData.setProperties(QLowEnergyCharacteristic::Read | QLowEnergyCharacteristic::Notify); - wirelessEnabledStatusData.setValue(QByteArray::fromHex("00")); - 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(dcBluetoothServer()) << "NetworkService: Could not send response. Service not valid"; - return; - } - - QLowEnergyCharacteristic characteristic = m_service->characteristic(networkResponseCharacteristicUuid); - if (!characteristic.isValid()) { - qCWarning(dcBluetoothServer()) << "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(dcBluetoothServer()) << "NetworkService: received invalid command" << command; - sendResponse(NetworkServiceResponseIvalidValue); - return; - } - - if (!m_networkManagerAvailable) { - qCWarning(dcBluetoothServer()) << "NetworkService: Networkmanager not available"; - sendResponse(NetworkServiceResponseNetworkManagerNotAvailable); - return; - } - - processCommand(command); - - sendResponse(NetworkServiceResponseSuccess); - return; - } - - qCDebug(dcBluetoothServer()) << "NetworkService: Characteristic changed" << characteristic.uuid().toString() << value; -} - -void NetworkService::characteristicRead(const QLowEnergyCharacteristic &characteristic, const QByteArray &value) -{ - qCDebug(dcBluetoothServer()) << "NetworkService: Characteristic read" << characteristic.uuid().toString() << value; -} - -void NetworkService::characteristicWritten(const QLowEnergyCharacteristic &characteristic, const QByteArray &value) -{ - qCDebug(dcBluetoothServer()) << "NetworkService: Characteristic written" << characteristic.uuid().toString() << value; -} - -void NetworkService::descriptorRead(const QLowEnergyDescriptor &descriptor, const QByteArray &value) -{ - qCDebug(dcBluetoothServer()) << "NetworkService: Descriptor read" << descriptor.uuid().toString() << value; -} - -void NetworkService::descriptorWritten(const QLowEnergyDescriptor &descriptor, const QByteArray &value) -{ - qCDebug(dcBluetoothServer()) << "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(dcBluetoothServer()) << "NetworkService: Error:" << errorString; -} - -void NetworkService::processCommand(const NetworkServiceCommand &command) -{ - switch (command) { - case NetworkServiceCommandEnableNetworking: - qCDebug(dcBluetoothServer()) << "NetworkService: received \"Enable networking\" command"; - Core::instance()->networkManager()->enableNetworking(true); - break; - case NetworkServiceCommandDisableNetworking: - qCDebug(dcBluetoothServer()) << "NetworkService: received \"Disable networking\" command"; - Core::instance()->networkManager()->enableNetworking(false); - break; - case NetworkServiceCommandEnableWireless: - qCDebug(dcBluetoothServer()) << "NetworkService: received \"Enable wireless networking\" command"; - Core::instance()->networkManager()->enableWireless(true); - break; - case NetworkServiceCommandDisableWireless: - qCDebug(dcBluetoothServer()) << "NetworkService: received \"Disable wireless networking\" command"; - Core::instance()->networkManager()->enableWireless(false); - break; - default: - qCWarning(dcBluetoothServer()) << "NetworkService: Unhandled command" << command; - sendResponse(NetworkServiceResponseIvalidValue); - break; - } -} diff --git a/nymea-networkmanager/bluetooth/networkservice.h b/nymea-networkmanager/bluetooth/networkservice.h deleted file mode 100644 index 8effe29..0000000 --- a/nymea-networkmanager/bluetooth/networkservice.h +++ /dev/null @@ -1,94 +0,0 @@ -/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * - * * - * Copyright (C) 2018 Simon Stürz * - * * - * This file is part of nymea-networkmanager. * - * * - * nymea-networkmanager 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, either version 3 of the License, * - * or (at your option) any later version. * - * * - * nymea-networkmanager 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 nymea-networkmanager. If not, see . * - * * - * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ - -#ifndef NETWORKSERVICE_H -#define NETWORKSERVICE_H - -#include -#include -#include - -#include "nymea-networkmanager/networkmanager.h" - -class NetworkService : public QObject -{ - Q_OBJECT - Q_ENUMS(NetworkServiceCommand) - Q_ENUMS(NetworkServiceResponse) - -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, QObject *parent = nullptr); - ~NetworkService(); - - QLowEnergyService *service(); - - void setNetworkManagerAvailable(bool available); - void setNetworkManagerState(const NetworkManager::NetworkManagerState &state); - void setNetworkingEnabled(bool enabled); - void setWirelessNetworkingEnabled(bool enabled); - - static QLowEnergyServiceData serviceData(); - static QByteArray getNetworkManagerStateByteArray(const NetworkManager::NetworkManagerState &state); - -private: - QLowEnergyService *m_service = nullptr; - - bool m_networkManagerAvailable = false; - NetworkManager::NetworkManagerState m_state = NetworkManager::NetworkManagerStateUnknown; - bool m_networkingEnabled = false; - bool m_wirelessNetworkingEnabled = false; - - 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); - -}; - -#endif // NETWORKSERVICE_H diff --git a/nymea-networkmanager/bluetooth/systemservice.cpp b/nymea-networkmanager/bluetooth/systemservice.cpp deleted file mode 100644 index c251f79..0000000 --- a/nymea-networkmanager/bluetooth/systemservice.cpp +++ /dev/null @@ -1,256 +0,0 @@ -#include "systemservice.h" -#include "bluetoothuuids.h" -#include "loggingcategory.h" -#include "loopd.h" - -#include -#include -#include -#include - -SystemService::SystemService(QLowEnergyService *service, QObject *parent) : - QObject(parent), - m_service(service) -{ - connect(m_service, &QLowEnergyService::characteristicChanged, this, &SystemService::characteristicChanged); - connect(m_service, &QLowEnergyService::characteristicRead, this, &SystemService::characteristicChanged); - connect(m_service, &QLowEnergyService::characteristicWritten, this, &SystemService::characteristicWritten); - connect(m_service, &QLowEnergyService::descriptorWritten, this, &SystemService::descriptorWritten); - connect(m_service, SIGNAL(error(QLowEnergyService::ServiceError)), this, SLOT(serviceError(QLowEnergyService::ServiceError))); - - connect(Loopd::instance()->snapdControl(), &SnapdControl::updateRunningChanged, this, &SystemService::onUpdateRunningChanged); -} - -QLowEnergyService *SystemService::service() -{ - return m_service; -} - -QLowEnergyServiceData SystemService::serviceData() -{ - QLowEnergyServiceData serviceData; - serviceData.setType(QLowEnergyServiceData::ServiceTypePrimary); - serviceData.setUuid(systemServiceUuid); - - QLowEnergyDescriptorData clientConfigDescriptorData(QBluetoothUuid::ClientCharacteristicConfiguration, QByteArray(2, 0)); - - // System commander characterisitc e081fed1-f757-4449-b9c9-bfa83133f7fc - QLowEnergyCharacteristicData systemCommanderCharacteristicData; - systemCommanderCharacteristicData.setUuid(systemCommanderCharacteristicUuid); - systemCommanderCharacteristicData.setProperties(QLowEnergyCharacteristic::Write); - systemCommanderCharacteristicData.setValueLength(0, 20); - serviceData.addCharacteristic(systemCommanderCharacteristicData); - - // Response characterisitc e081fed2-f757-4449-b9c9-bfa83133f7fc - QLowEnergyCharacteristicData systemResponseCharacteristicData; - systemResponseCharacteristicData.setUuid(systemResponseCharacteristicUuid); - systemResponseCharacteristicData.setProperties(QLowEnergyCharacteristic::Notify); - systemResponseCharacteristicData.addDescriptor(clientConfigDescriptorData); - systemResponseCharacteristicData.setValueLength(0, 20); - serviceData.addCharacteristic(systemResponseCharacteristicData); - return serviceData; - - // System update indicator characterisitc e081fed3-f757-4449-b9c9-bfa83133f7fc - QLowEnergyCharacteristicData systemUpdateCharacteristicData; - systemUpdateCharacteristicData.setUuid(systemUpdateCharacteristicUuid); - systemUpdateCharacteristicData.setProperties(QLowEnergyCharacteristic::Read | QLowEnergyCharacteristic::Notify); - systemUpdateCharacteristicData.addDescriptor(clientConfigDescriptorData); - systemUpdateCharacteristicData.setValueLength(1, 1); - systemUpdateCharacteristicData.setValue(QByteArray::number((int)Loopd::instance()->snapdControl()->updateRunning())); - serviceData.addCharacteristic(systemUpdateCharacteristicData); - return serviceData; -} - -void SystemService::streamData(const QVariantMap &responseMap) -{ - QLowEnergyCharacteristic characteristic = m_service->characteristic(systemResponseCharacteristicUuid); - if (!characteristic.isValid()) { - qCWarning(dcBluetoothServer()) << "SystemService: System response characteristic not valid"; - return; - } - - QByteArray data = QJsonDocument::fromVariant(responseMap).toJson(QJsonDocument::Compact) + '\n'; - qCDebug(dcBluetoothServer()) << "SystemService: 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(dcBluetoothServer()) << "SystemService: Finished streaming response data"; -} - -QVariantMap SystemService::createResponse(const SystemService::SystemServiceCommand &command, const SystemService::SystemServiceResponse &responseCode) -{ - QVariantMap response; - response.insert("c", (int)command); - response.insert("r", (int)responseCode); - return response; -} - -void SystemService::characteristicChanged(const QLowEnergyCharacteristic &characteristic, const QByteArray &value) -{ - // Command - if (characteristic.uuid() == systemCommanderCharacteristicUuid) { - // 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(dcBluetoothServer()) << "SystemService: Got invalid json object" << m_inputDataStream; - m_inputDataStream.clear(); - m_readingInputData = false; - return; - } - - qCDebug(dcBluetoothServer()) << "SystemService: 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 SystemService::characteristicRead(const QLowEnergyCharacteristic &characteristic, const QByteArray &value) -{ - qCDebug(dcBluetoothServer()) << "SystemService: Characteristic read" << characteristic.uuid().toString() << value; -} - -void SystemService::characteristicWritten(const QLowEnergyCharacteristic &characteristic, const QByteArray &value) -{ - qCDebug(dcBluetoothServer()) << "SystemService: Characteristic written" << characteristic.uuid().toString() << value; -} - -void SystemService::descriptorRead(const QLowEnergyDescriptor &descriptor, const QByteArray &value) -{ - qCDebug(dcBluetoothServer()) << "SystemService: Descriptor read" << descriptor.uuid().toString() << value; -} - -void SystemService::descriptorWritten(const QLowEnergyDescriptor &descriptor, const QByteArray &value) -{ - qCDebug(dcBluetoothServer()) << "SystemService: Descriptor written" << descriptor.uuid().toString() << value; -} - -void SystemService::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; - default: - errorString = "Unhandled error"; - break; - } - - qCWarning(dcBluetoothServer()) << "SystemService: Error:" << errorString; -} - -void SystemService::processCommand(const QVariantMap &request) -{ - if (!request.contains("c")) { - qCWarning(dcBluetoothServer()) << "SystemService: Invalid request. Command value missing."; - streamData(createResponse(SystemServiceCommandPushAuthentication, SystemServiceResponseInvalidValue)); - return; - } - - bool commandIntOk; - int command = request.value("c").toInt(&commandIntOk); - if (!commandIntOk) { - qCWarning(dcBluetoothServer()) << "SystemService: Invalid request. Could not convert method to interger."; - streamData(createResponse(SystemServiceCommandPushAuthentication, SystemServiceResponseInvalidValue)); - return; - } - - // Process method - switch (command) { - case SystemServiceCommandPushAuthentication: - commandPressPushButton(); - break; - default: - qCWarning(dcBluetoothServer()) << "SystemService: Invalid request. Unknown command" << command; - streamData(createResponse(SystemServiceCommandPushAuthentication, SystemServiceResponseInvalidCommand)); - break; - } -} - -void SystemService::commandPressPushButton() -{ - if (!m_service) { - qCWarning(dcBluetoothServer()) << "SystemService: Could not press push button. Service not valid."; - return; - } - - QLowEnergyCharacteristic characteristic = m_service->characteristic(systemResponseCharacteristicUuid); - if (!characteristic.isValid()) { - qCWarning(dcBluetoothServer()) << "SystemService: System response characteristic not valid"; - return; - } - - if (!Loopd::instance()->nymeaService()->available()) { - streamData(createResponse(SystemServiceCommandPushAuthentication, SystemServiceResponsePushServiceUnavailable)); - return; - } - - Loopd::instance()->nymeaService()->pushButtonPressed(); - - streamData(createResponse(SystemServiceCommandPushAuthentication, SystemServiceResponseSuccess)); -} - -void SystemService::onUpdateRunningChanged(const bool &running) -{ - if (!m_service) { - qCWarning(dcBluetoothServer()) << "SystemService: Could not set system update running characteristic. Service not valid."; - return; - } - - QLowEnergyCharacteristic characteristic = m_service->characteristic(systemUpdateCharacteristicUuid); - if (!characteristic.isValid()) { - qCWarning(dcBluetoothServer()) << "SystemService: Could not set system update running characteristic. Characteristic not valid"; - return; - } - - qCDebug(dcBluetoothServer()) << "SystemService: Notify system update running changed:" << (running ? "running" : "finished"); - m_service->writeCharacteristic(characteristic, running ? QByteArray::fromHex("01") : QByteArray::fromHex("00")); - return; -} diff --git a/nymea-networkmanager/bluetooth/systemservice.h b/nymea-networkmanager/bluetooth/systemservice.h deleted file mode 100644 index 91a4699..0000000 --- a/nymea-networkmanager/bluetooth/systemservice.h +++ /dev/null @@ -1,60 +0,0 @@ -#ifndef SYSTEMSERVICE_H -#define SYSTEMSERVICE_H - -#include -#include -#include - -class SystemService : public QObject -{ - Q_OBJECT -public: - enum SystemServiceCommand { - SystemServiceCommandInvalid = -1, - SystemServiceCommandPushAuthentication = 0x00 - }; - Q_ENUM(SystemServiceCommand) - - enum SystemServiceResponse { - SystemServiceResponseSuccess = 0x00, - SystemServiceResponseUnknownError = 0x01, - SystemServiceResponseInvalidCommand = 0x02, - SystemServiceResponseInvalidValue = 0x03, - SystemServiceResponsePushServiceUnavailable = 0x04, - }; - Q_ENUM(SystemServiceResponse) - - explicit SystemService(QLowEnergyService *service, QObject *parent = nullptr); - - QLowEnergyService *service(); - - static QLowEnergyServiceData serviceData(); - -private: - QLowEnergyService *m_service = nullptr; - - bool m_readingInputData = false; - QByteArray m_inputDataStream; - - void streamData(const QVariantMap &responseMap); - QVariantMap createResponse(const SystemServiceCommand &command, const SystemServiceResponse &responseCode = SystemServiceResponseSuccess); - -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); - - // Push button authentication - void commandPressPushButton(); - - void onUpdateRunningChanged(const bool &running); -}; - -#endif // SYSTEMSERVICE_H diff --git a/nymea-networkmanager/bluetooth/wirelessservice.cpp b/nymea-networkmanager/bluetooth/wirelessservice.cpp deleted file mode 100644 index da77af4..0000000 --- a/nymea-networkmanager/bluetooth/wirelessservice.cpp +++ /dev/null @@ -1,574 +0,0 @@ -/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * - * * - * Copyright (C) 2018 Simon Stürz * - * * - * This file is part of nymea-networkmanager. * - * * - * nymea-networkmanager 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, either version 3 of the License, * - * or (at your option) any later version. * - * * - * nymea-networkmanager 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 nymea-networkmanager. If not, see . * - * * - * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ - -#include "wirelessservice.h" - -#include "core.h" -#include "bluetoothuuids.h" -#include "loggingcategories.h" - -#include -#include -#include -#include - -WirelessService::WirelessService(QLowEnergyService *service, QObject *parent) : - QObject(parent), - m_service(service), - m_readingInputData(false) -{ - qCDebug(dcBluetoothServer()) << "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))); -} - -WirelessService::~WirelessService() -{ - qCDebug(dcBluetoothServer()) << "Delete wireless service"; -} - -QLowEnergyService *WirelessService::service() -{ - return m_service; -} - -QLowEnergyServiceData WirelessService::serviceData() -{ - 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); - wirelessStatusCharacteristicData.setValue(WirelessService::getWirelessNetworkDeviceState(NetworkDevice::NetworkDeviceStateUnknown)); - serviceData.addCharacteristic(wirelessStatusCharacteristicData); - - // Wireless connection 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); - wirelessModeCharacteristicData.setValue(WirelessService::getWirelessMode(WirelessNetworkDevice::ModeUnknown)); - serviceData.addCharacteristic(wirelessModeCharacteristicData); - - return serviceData; -} - - -WirelessService::WirelessServiceResponse WirelessService::checkWirelessErrors() -{ - // Check possible errors - if (!Core::instance()->networkManager()->available()) { - qCWarning(dcBluetoothServer()) << "WirelessService: The networkmanager is not available."; - return WirelessServiceResponseNetworkManagerNotAvailable; - } - - if (!Core::instance()->networkManager()->wirelessAvailable()) { - qCWarning(dcBluetoothServer()) << "WirelessService: There is no wireless device available."; - return WirelessServiceResponseWirelessNotAvailable; - } - - if (!Core::instance()->networkManager()->networkingEnabled()) { - qCWarning(dcBluetoothServer()) << "WirelessService: Networking not enabled"; - return WirelessServiceResponseNetworkingNotEnabled; - } - - if (!Core::instance()->networkManager()->wirelessEnabled()) { - qCWarning(dcBluetoothServer()) << "WirelessService: Wireless not enabled"; - return WirelessServiceResponseWirelessNotEnabled; - } - - return WirelessServiceResponseSuccess; -} - -QByteArray WirelessService::getWirelessNetworkDeviceState(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::Mode mode) -{ - switch (mode) { - case WirelessNetworkDevice::ModeUnknown: - return QByteArray::fromHex("00"); - case WirelessNetworkDevice::ModeAdhoc: - return QByteArray::fromHex("01"); - case WirelessNetworkDevice::ModeInfrastructure: - return QByteArray::fromHex("02"); - case WirelessNetworkDevice::ModeAccessPoint: - 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(dcBluetoothServer()) << "WirelessService: Wireless response characteristic not valid"; - return; - } - - QByteArray data = QJsonDocument::fromVariant(responseMap).toJson(QJsonDocument::Compact) + '\n'; - qCDebug(dcBluetoothServer()) << "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(dcBluetoothServer()) << "WirelessService: Finished streaming response data"; -} - -QVariantMap WirelessService::createResponse(const WirelessService::WirelessServiceCommand &command, const WirelessService::WirelessServiceResponse &responseCode) -{ - QVariantMap response; - response.insert("c", static_cast(command)); - response.insert("r", static_cast(responseCode)); - return response; -} - -void WirelessService::commandGetNetworks(const QVariantMap &request) -{ - Q_UNUSED(request) - - if (!m_service) { - qCWarning(dcBluetoothServer()) << "WirelessService: Could not stream wireless network list. Service not valid"; - return; - } - - QLowEnergyCharacteristic characteristic = m_service->characteristic(wirelessResponseCharacteristicUuid); - if (!characteristic.isValid()) { - qCWarning(dcBluetoothServer()) << "WirelessService: Wireless response characteristic not valid"; - return; - } - - QVariantList accessPointVariantList; - foreach (WirelessAccessPoint *accessPoint, Core::instance()->networkManager()->wirelessNetworkDevices().first()->accessPoints()) { - QVariantMap accessPointVariantMap; - accessPointVariantMap.insert("e", accessPoint->ssid()); - accessPointVariantMap.insert("m", accessPoint->macAddress()); - accessPointVariantMap.insert("s", accessPoint->signalStrength()); - accessPointVariantMap.insert("p", static_cast(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(dcBluetoothServer()) << "WirelessService: Could not stream wireless network list. Service not valid"; - return; - } - - QLowEnergyCharacteristic characteristic = m_service->characteristic(wirelessResponseCharacteristicUuid); - if (!characteristic.isValid()) { - qCWarning(dcBluetoothServer()) << "WirelessService: Wireless response characteristic not valid"; - return; - } - - if (!request.contains("p")) { - qCWarning(dcBluetoothServer()) << "WirelessService: Connect command: Missing parameters."; - streamData(createResponse(WirelessServiceCommandConnect, WirelessServiceResponseIvalidParameters)); - return; - } - - QVariantMap parameters = request.value("p").toMap(); - if (!parameters.contains("e") || !parameters.contains("p")) { - qCWarning(dcBluetoothServer()) << "WirelessService: Connect command: Invalid parameters."; - streamData(createResponse(WirelessServiceCommandConnect, WirelessServiceResponseIvalidParameters)); - return; - } - - Core::instance()->networkManager()->connectWifi(Core::instance()->networkManager()->wirelessNetworkDevices().first()->interface(), parameters.value("e").toString(), parameters.value("p").toString()); - streamData(createResponse(WirelessServiceCommandConnect)); -} - -void WirelessService::commandConnectHidden(const QVariantMap &request) -{ - Q_UNUSED(request) - // TODO: - qCWarning(dcBluetoothServer()) << "Connect to hidden network is not implemented yet."; -} - -void WirelessService::commandDisconnect(const QVariantMap &request) -{ - Q_UNUSED(request) - - if (!m_service) { - qCWarning(dcBluetoothServer()) << "WirelessService: Service not valid"; - return; - } - - QLowEnergyCharacteristic characteristic = m_service->characteristic(wirelessResponseCharacteristicUuid); - if (!characteristic.isValid()) { - qCWarning(dcBluetoothServer()) << "WirelessService: Wireless response characteristic not valid"; - return; - } - - Core::instance()->networkManager()->wirelessNetworkDevices().first()->disconnectDevice(); - streamData(createResponse(WirelessServiceCommandDisconnect)); -} - -void WirelessService::commandScan(const QVariantMap &request) -{ - Q_UNUSED(request) - - qCDebug(dcBluetoothServer()) << "WirelessService: Execute command scan."; - - if (!m_service) { - qCWarning(dcBluetoothServer()) << "WirelessService: Could scan wireless networks. Service not valid"; - return; - } - - QLowEnergyCharacteristic characteristic = m_service->characteristic(wirelessResponseCharacteristicUuid); - if (!characteristic.isValid()) { - qCWarning(dcBluetoothServer()) << "WirelessService: Wireless response characteristic not valid"; - return; - } - - Core::instance()->networkManager()->wirelessNetworkDevices().first()->scanWirelessNetworks(); - streamData(createResponse(WirelessServiceCommandScan)); -} - -void WirelessService::commandGetCurrentConnection(const QVariantMap &request) -{ - Q_UNUSED(request) - qCDebug(dcBluetoothServer()) << "WirelessService: Execute get current connection."; - - if (!m_service) { - qCWarning(dcBluetoothServer()) << "WirelessService: Service not valid"; - return; - } - - QLowEnergyCharacteristic characteristic = m_service->characteristic(wirelessResponseCharacteristicUuid); - if (!characteristic.isValid()) { - qCWarning(dcBluetoothServer()) << "WirelessService: Wireless response characteristic not valid"; - return; - } - - WirelessNetworkDevice *device = Core::instance()->networkManager()->wirelessNetworkDevices().first(); - - QVariantMap connectionDataMap; - QNetworkInterface wifiInterface = QNetworkInterface::interfaceFromName(device->interface()); - if (!device->activeAccessPoint() || !wifiInterface.isValid() || wifiInterface.addressEntries().isEmpty()) { - qCDebug(dcBluetoothServer()) << "WirelessService: 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 = wifiInterface.addressEntries().first().ip(); - qCDebug(dcBluetoothServer()) << "WirelessService: Current connection:" << device->activeAccessPoint() << address.toString(); - connectionDataMap.insert("e", device->activeAccessPoint()->ssid()); - connectionDataMap.insert("m", device->activeAccessPoint()->macAddress()); - connectionDataMap.insert("s", device->activeAccessPoint()->signalStrength()); - connectionDataMap.insert("p", static_cast(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(dcBluetoothServer()) << "WirelessService: Could not stream wireless network list. Service not valid"; - return; - } - - QLowEnergyCharacteristic characteristic = m_service->characteristic(wirelessResponseCharacteristicUuid); - if (!characteristic.isValid()) { - qCWarning(dcBluetoothServer()) << "WirelessService: Wireless response characteristic not valid"; - return; - } - - if (!request.contains("p")) { - qCWarning(dcBluetoothServer()) << "WirelessService: Connect command: Missing parameters."; - streamData(createResponse(WirelessServiceCommandConnect, WirelessServiceResponseIvalidParameters)); - return; - } - - QVariantMap parameters = request.value("p").toMap(); - if (!parameters.contains("e") || !parameters.contains("p")) { - qCWarning(dcBluetoothServer()) << "WirelessService: Connect command: Invalid parameters."; - streamData(createResponse(WirelessServiceCommandConnect, WirelessServiceResponseIvalidParameters)); - return; - } - - Core::instance()->networkManager()->startAccessPoint(Core::instance()->networkManager()->wirelessNetworkDevices().first()->interface(), parameters.value("e").toString(), parameters.value("p").toString()); - streamData(createResponse(WirelessServiceCommandStartAccessPoint)); -} - -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(dcBluetoothServer()) << "Got invalid json object" << m_inputDataStream; - m_inputDataStream.clear(); - m_readingInputData = false; - return; - } - - qCDebug(dcBluetoothServer()) << "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(dcBluetoothServer()) << "WirelessService: Characteristic read" << characteristic.uuid().toString() << value; -} - -void WirelessService::characteristicWritten(const QLowEnergyCharacteristic &characteristic, const QByteArray &value) -{ - qCDebug(dcBluetoothServer()) << "WirelessService: Characteristic written" << characteristic.uuid().toString() << value; -} - -void WirelessService::descriptorRead(const QLowEnergyDescriptor &descriptor, const QByteArray &value) -{ - qCDebug(dcBluetoothServer()) << "WirelessService: Descriptor read" << descriptor.uuid().toString() << value; -} - -void WirelessService::descriptorWritten(const QLowEnergyDescriptor &descriptor, const QByteArray &value) -{ - qCDebug(dcBluetoothServer()) << "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(dcBluetoothServer()) << "WirelessService: Error:" << errorString; -} - -void WirelessService::processCommand(const QVariantMap &request) -{ - if (!request.contains("c")) { - qCWarning(dcBluetoothServer()) << "Invalid request. Command value missing."; - streamData(createResponse(WirelessServiceCommandConnect, WirelessServiceResponseIvalidCommand)); - return; - } - - bool commandIntOk; - int command = request.value("c").toInt(&commandIntOk); - if (!commandIntOk) { - qCWarning(dcBluetoothServer()) << "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(command), responseCode)); - return; - } - - // Process method - 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(dcBluetoothServer()) << "Invalid request. Unknown command" << command; - streamData(createResponse(WirelessServiceCommandConnect, WirelessServiceResponseIvalidCommand)); - break; - } -} - -void WirelessService::onWirelessDeviceBitRateChanged(int bitRate) -{ - Q_UNUSED(bitRate) -} - -void WirelessService::onWirelessModeChanged(WirelessNetworkDevice::Mode mode) -{ - if (!m_service) { - qCWarning(dcBluetoothServer()) << "WirelessService: Could not update wireless device mode. Service not valid"; - return; - } - - QLowEnergyCharacteristic characteristic = m_service->characteristic(wirelessModeCharacteristicUuid); - if (!characteristic.isValid()) { - qCWarning(dcBluetoothServer()) << "WirelessService: Could not update wireless device mode. Characteristic not valid"; - return; - } - - qCDebug(dcBluetoothServer()) << "WirelessService: Notify wireless mode changed" << WirelessService::getWirelessMode(mode); - m_service->writeCharacteristic(characteristic, WirelessService::getWirelessMode(mode)); -} - -void WirelessService::onWirelessDeviceStateChanged(NetworkDevice::NetworkDeviceState state) -{ - if (!m_service) { - qCWarning(dcBluetoothServer()) << "WirelessService: Could not update wireless network device state. Service not valid"; - return; - } - - QLowEnergyCharacteristic characteristic = m_service->characteristic(wirelessStateCharacteristicUuid); - if (!characteristic.isValid()) { - qCWarning(dcBluetoothServer()) << "WirelessService: Could not update wireless network device state. Characteristic not valid"; - return; - } - - qCDebug(dcBluetoothServer()) << "WirelessService: Notify wireless state changed" << WirelessService::getWirelessNetworkDeviceState(state); - m_service->writeCharacteristic(characteristic, WirelessService::getWirelessNetworkDeviceState(state)); -} diff --git a/nymea-networkmanager/bluetooth/wirelessservice.h b/nymea-networkmanager/bluetooth/wirelessservice.h deleted file mode 100644 index 510aca2..0000000 --- a/nymea-networkmanager/bluetooth/wirelessservice.h +++ /dev/null @@ -1,116 +0,0 @@ -/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * - * * - * Copyright (C) 2018 Simon Stürz * - * * - * This file is part of nymea-networkmanager. * - * * - * nymea-networkmanager 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, either version 3 of the License, * - * or (at your option) any later version. * - * * - * nymea-networkmanager 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 nymea-networkmanager. If not, see . * - * * - * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ - -#ifndef WIRELESSSERVICE_H -#define WIRELESSSERVICE_H - -#include -#include -#include -#include - -#include "nymea-networkmanager/wirelessaccesspoint.h" -#include "nymea-networkmanager/wirelessnetworkdevice.h" - -class WirelessService : public QObject -{ - Q_OBJECT - Q_ENUMS(WirelessServiceCommand) - Q_ENUMS(WirelessServiceResponse) - -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, QObject *parent = nullptr); - ~WirelessService(); - - QLowEnergyService *service(); - - static QLowEnergyServiceData serviceData(); - -private: - QLowEnergyService *m_service = nullptr; - - bool m_readingInputData = false; - QByteArray m_inputDataStream; - - WirelessServiceResponse checkWirelessErrors(); - - // Note: static to be available in serviceData - static QByteArray getWirelessNetworkDeviceState(NetworkDevice::NetworkDeviceState state); - static QByteArray getWirelessMode(WirelessNetworkDevice::Mode 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); - -public slots: - // Wireless network device - void onWirelessDeviceBitRateChanged(int bitRate); - void onWirelessDeviceStateChanged(NetworkDevice::NetworkDeviceState state); - void onWirelessModeChanged(WirelessNetworkDevice::Mode mode); -}; - -#endif // WIRELESSSERVICE_H diff --git a/nymea-networkmanager/core.cpp b/nymea-networkmanager/core.cpp index 30e1e33..f1d699c 100644 --- a/nymea-networkmanager/core.cpp +++ b/nymea-networkmanager/core.cpp @@ -115,12 +115,8 @@ Core::Core(QObject *parent) : m_networkManager = new NetworkManager(this); connect(m_networkManager, &NetworkManager::availableChanged, this, &Core::onNetworkManagerAvailableChanged); connect(m_networkManager, &NetworkManager::stateChanged, this, &Core::onNetworkManagerStateChanged); - connect(m_networkManager, &NetworkManager::networkingEnabledChanged, this, &Core::onNetworkManagerNetworkingEnabledChanged); - connect(m_networkManager, &NetworkManager::wirelessEnabledChanged, this, &Core::onNetworkManagerWirelessEnabledChanged); - connect(m_networkManager, &NetworkManager::wirelessDeviceAdded, this, &Core::onNetworkManagerWirelessDeviceAdded); - connect(m_networkManager, &NetworkManager::wirelessDeviceRemoved, this, &Core::onNetworkManagerWirelessDeviceRemoved); - m_bluetoothServer = new BluetoothServer(this); + m_bluetoothServer = new BluetoothServer(m_networkManager); connect(m_bluetoothServer, &BluetoothServer::runningChanged, this, &Core::onBluetoothServerRunningChanged); connect(m_bluetoothServer, &BluetoothServer::connectedChanged, this, &Core::onBluetoothServerConnectedChanged); @@ -129,7 +125,6 @@ Core::Core(QObject *parent) : m_advertisingTimer = new QTimer(this); m_advertisingTimer->setSingleShot(true); - connect(m_advertisingTimer, &QTimer::timeout, this, &Core::onAdvertisingTimeout); } @@ -148,7 +143,7 @@ Core::~Core() m_networkManager = nullptr; } -void Core::evaluateNetworkManagerState(const NetworkManager::NetworkManagerState &state) +void Core::evaluateNetworkManagerState(NetworkManager::NetworkManagerState state) { if (m_mode != ModeOffline) return; @@ -162,6 +157,7 @@ void Core::evaluateNetworkManagerState(const NetworkManager::NetworkManagerState switch (state) { case NetworkManager::NetworkManagerStateConnectedGlobal: // We are online + qCDebug(dcApplication()) << "Not advertising bluetooth because we are online and we are running in" << m_mode; if (m_bluetoothServer->running() && !m_bluetoothServer->connected()) { qCDebug(dcApplication()) << "Stop the bluetooth service because of \"offline\" mode."; stopService(); @@ -209,7 +205,8 @@ void Core::startService() // Start the bluetooth server for this wireless device qCDebug(dcApplication()) << "Start bluetooth service"; m_bluetoothServer->setAdvertiseName(m_advertiseName); - m_bluetoothServer->setMachineId(m_platformName); + m_bluetoothServer->setModelName(m_platformName); + m_bluetoothServer->setSoftwareVersion(VERSION_STRING); QTimer::singleShot(5000, m_bluetoothServer, &BluetoothServer::start); } @@ -266,20 +263,23 @@ void Core::onBluetoothServerRunningChanged(bool running) if (!running) { // Enable bluetooth on nymea - m_nymeaService->enableBluetooth(true); m_advertisingTimer->stop(); switch (m_mode) { case ModeAlways: qCDebug(dcApplication()) << "Restart the bluetooth service because of \"always\" mode."; - startService(); + // Give some grace periode for bluez to clean up + QTimer::singleShot(2000, this, &Core::startService); break; case ModeStart: + m_nymeaService->enableBluetooth(true); break; case ModeOffline: + m_nymeaService->enableBluetooth(true); evaluateNetworkManagerState(m_networkManager->state()); break; case ModeOnce: + m_nymeaService->enableBluetooth(true); if (m_networkManager->networkSettings()->connections().isEmpty()) { qCDebug(dcApplication()) << "Start the bluetooth service because of \"once\" mode and there is currenlty no network configured yet."; startService(); @@ -294,30 +294,18 @@ void Core::onBluetoothServerRunningChanged(bool running) void Core::onBluetoothServerConnectedChanged(bool connected) { qCDebug(dcApplication()) << "Bluetooth client" << (connected ? "connected" : "disconnected"); - if (connected) { - m_advertisingTimer->stop(); + m_advertisingTimer->stop(); - m_bluetoothServer->onNetworkManagerAvailableChanged(m_networkManager->available()); - m_bluetoothServer->onNetworkManagerStateChanged(m_networkManager->state()); - m_bluetoothServer->onNetworkingEnabledChanged(m_networkManager->networkingEnabled()); - m_bluetoothServer->onWirelessNetworkingEnabledChanged(m_networkManager->wirelessEnabled()); - - if (m_wirelessDevice) { - m_bluetoothServer->onWirelessDeviceStateChanged(m_wirelessDevice->deviceState()); - m_bluetoothServer->onWirelessDeviceModeChanged(m_wirelessDevice->mode()); - } - - } else { + if (!connected) { m_advertisingTimer->stop(); m_bluetoothServer->stop(); } } -void Core::onNetworkManagerAvailableChanged(const bool &available) +void Core::onNetworkManagerAvailableChanged(bool available) { if (!available) { qCWarning(dcApplication()) << "Networkmanager is not available any more."; - m_bluetoothServer->onNetworkManagerAvailableChanged(m_networkManager->available()); return; } @@ -327,12 +315,12 @@ void Core::onNetworkManagerAvailableChanged(const bool &available) } qCDebug(dcApplication()) << "Networkmanager is now available."; - m_bluetoothServer->onNetworkManagerAvailableChanged(available); switch (m_mode) { case ModeAlways: qCDebug(dcApplication()) << "Start the bluetooth service because of \"always\" mode."; - startService(); + // Give some grace periode for networkmanager + QTimer::singleShot(2000, this, &Core::startService); break; case ModeStart: break; @@ -350,76 +338,11 @@ void Core::onNetworkManagerAvailableChanged(const bool &available) } } -void Core::onNetworkManagerNetworkingEnabledChanged(bool enabled) +void Core::onNetworkManagerStateChanged(NetworkManager::NetworkManagerState state) { - qCDebug(dcApplication()) << "Networkmanager networking is now" << (enabled ? "enabled" : "disabled"); - m_bluetoothServer->onNetworkingEnabledChanged(enabled); - evaluateNetworkManagerState(m_networkManager->state()); -} - -void Core::onNetworkManagerWirelessEnabledChanged(bool enabled) -{ - qCDebug(dcApplication()) << "Networkmanager wireless networking is now" << (enabled ? "enabled" : "disabled"); - m_bluetoothServer->onWirelessNetworkingEnabledChanged(enabled); - evaluateNetworkManagerState(m_networkManager->state()); -} - -void Core::onNetworkManagerStateChanged(const NetworkManager::NetworkManagerState &state) -{ - qCDebug(dcApplication()) << state; - if (!m_bluetoothServer) - return; - - m_bluetoothServer->onNetworkManagerStateChanged(state); evaluateNetworkManagerState(state); } -void Core::onNetworkManagerWirelessDeviceAdded(WirelessNetworkDevice *wirelessDevice) -{ - if (m_wirelessDevice) { - // We already have a wireless device - return; - } - - m_wirelessDevice = wirelessDevice; - connect(m_wirelessDevice, &WirelessNetworkDevice::stateChanged, this, &Core::onWirelessDeviceStateChanged); - connect(m_wirelessDevice, &WirelessNetworkDevice::modeChanged, this, &Core::onWirelessDeviceModeChanged); -} - -void Core::onNetworkManagerWirelessDeviceRemoved(const QString &interface) -{ - if (!m_wirelessDevice) { - // Have no wireless device... - return; - } - - if (m_wirelessDevice->interface() == interface) { - disconnect(m_wirelessDevice, &WirelessNetworkDevice::stateChanged, this, &Core::onWirelessDeviceStateChanged); - m_wirelessDevice = nullptr; - } -} - -void Core::onWirelessDeviceBitRateChanged(int bitRate) -{ - qCDebug(dcApplication()) << "Wireless device changed bitrate" << bitRate; - m_bluetoothServer->onWirelessDeviceBitRateChanged(bitRate); -} - -void Core::onWirelessDeviceModeChanged(WirelessNetworkDevice::Mode mode) -{ - qCDebug(dcApplication()) << "Wireless device mode" << mode; - - // TODO: check what to do if in ap mode - - m_bluetoothServer->onWirelessDeviceModeChanged(mode); -} - -void Core::onWirelessDeviceStateChanged(const NetworkDevice::NetworkDeviceState state) -{ - qCDebug(dcApplication()) << state; - m_bluetoothServer->onWirelessDeviceStateChanged(state); -} - void Core::onNymeaServiceAvailableChanged(bool available) { if (available) diff --git a/nymea-networkmanager/core.h b/nymea-networkmanager/core.h index ac7d2c4..86227dd 100644 --- a/nymea-networkmanager/core.h +++ b/nymea-networkmanager/core.h @@ -27,6 +27,7 @@ #include "nymeadservice.h" #include "bluetooth/bluetoothserver.h" #include "nymea-networkmanager/networkmanager.h" +#include "nymea-networkmanager/bluetooth/bluetoothserver.h" class Core : public QObject { @@ -81,12 +82,12 @@ private: int m_advertisingTimeout = 60; bool m_initRunning = true; - void evaluateNetworkManagerState(const NetworkManager::NetworkManagerState &state); + void evaluateNetworkManagerState(NetworkManager::NetworkManagerState state); +private slots: void startService(); void stopService(); -private slots: void postRun(); void onAdvertisingTimeout(); @@ -94,17 +95,8 @@ private slots: void onBluetoothServerRunningChanged(bool running); void onBluetoothServerConnectedChanged(bool connected); - void onNetworkManagerAvailableChanged(const bool &available); - void onNetworkManagerNetworkingEnabledChanged(bool enabled); - void onNetworkManagerWirelessEnabledChanged(bool enabled); - void onNetworkManagerStateChanged(const NetworkManager::NetworkManagerState &state); - void onNetworkManagerWirelessDeviceAdded(WirelessNetworkDevice *wirelessDevice); - void onNetworkManagerWirelessDeviceRemoved(const QString &interface); - - // Wireless device - void onWirelessDeviceBitRateChanged(int bitRate); - void onWirelessDeviceModeChanged(WirelessNetworkDevice::Mode mode); - void onWirelessDeviceStateChanged(const NetworkDevice::NetworkDeviceState state); + void onNetworkManagerAvailableChanged(bool available); + void onNetworkManagerStateChanged(NetworkManager::NetworkManagerState state); void onNymeaServiceAvailableChanged(bool available); diff --git a/nymea-networkmanager/loggingcategories.cpp b/nymea-networkmanager/loggingcategories.cpp index 42035e7..56fcdd5 100644 --- a/nymea-networkmanager/loggingcategories.cpp +++ b/nymea-networkmanager/loggingcategories.cpp @@ -22,5 +22,4 @@ #include "loggingcategories.h" Q_LOGGING_CATEGORY(dcApplication, "Application") -Q_LOGGING_CATEGORY(dcBluetoothServer, "BluetoothServer") Q_LOGGING_CATEGORY(dcNymeaService, "NymeaService") diff --git a/nymea-networkmanager/loggingcategories.h b/nymea-networkmanager/loggingcategories.h index 7dadf38..0d2362e 100644 --- a/nymea-networkmanager/loggingcategories.h +++ b/nymea-networkmanager/loggingcategories.h @@ -26,7 +26,6 @@ #include Q_DECLARE_LOGGING_CATEGORY(dcApplication) -Q_DECLARE_LOGGING_CATEGORY(dcBluetoothServer) Q_DECLARE_LOGGING_CATEGORY(dcNymeaService) #endif // LOGGINGCATEGORIES_H diff --git a/nymea-networkmanager/main.cpp b/nymea-networkmanager/main.cpp index 1cbf241..3cce154 100644 --- a/nymea-networkmanager/main.cpp +++ b/nymea-networkmanager/main.cpp @@ -97,7 +97,7 @@ int main(int argc, char *argv[]) parser.addHelpOption(); parser.addVersionOption(); parser.setApplicationDescription(QString("\nThis daemon allows to configure a wifi network using a bluetooth low energy connection." \ - "\n\nCopyright %1 2018 Simon Stürz ").arg(QChar(0xA9))); + "\n\nCopyright %1 2018-2019 Simon Stürz ").arg(QChar(0xA9))); QCommandLineOption debugOption(QStringList() << "d" << "debug", "Enable more debug output."); parser.addOption(debugOption); @@ -125,9 +125,9 @@ int main(int argc, char *argv[]) // Enable debug categories s_loggingFilters.insert("Application", true); - s_loggingFilters.insert("BluetoothServer", parser.isSet(debugOption)); - s_loggingFilters.insert("NetworkManager", parser.isSet(debugOption) ); s_loggingFilters.insert("NymeaService", parser.isSet(debugOption)); + s_loggingFilters.insert("NetworkManager", parser.isSet(debugOption) ); + s_loggingFilters.insert("NetworkManagerBluetoothServer", parser.isSet(debugOption)); QLoggingCategory::installFilter(loggingCategoryFilter); diff --git a/nymea-networkmanager/nymea-networkmanager.pro b/nymea-networkmanager/nymea-networkmanager.pro index 1bce2cd..c49bd3e 100644 --- a/nymea-networkmanager/nymea-networkmanager.pro +++ b/nymea-networkmanager/nymea-networkmanager.pro @@ -17,10 +17,7 @@ HEADERS += \ loggingcategories.h \ nymeadservice.h \ pushbuttonagent.h \ - bluetooth/bluetoothserver.h \ - bluetooth/networkservice.h \ - bluetooth/bluetoothuuids.h \ - bluetooth/wirelessservice.h \ + SOURCES += \ main.cpp \ @@ -29,9 +26,6 @@ SOURCES += \ loggingcategories.cpp \ nymeadservice.cpp \ pushbuttonagent.cpp \ - bluetooth/bluetoothserver.cpp \ - bluetooth/networkservice.cpp \ - bluetooth/wirelessservice.cpp \ target.path = /usr/bin INSTALLS += target From 6a51b0572edad6a066992907ac5833bda60ce54a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20St=C3=BCrz?= Date: Tue, 8 Oct 2019 16:21:54 +0200 Subject: [PATCH 3/8] Reenable bluetooth on nymea on shutdown --- nymea-networkmanager/core.cpp | 25 +++++++++++++------------ nymea-networkmanager/main.cpp | 2 +- nymea-networkmanager/nymeadservice.cpp | 6 ++++++ nymea-networkmanager/nymeadservice.h | 2 +- 4 files changed, 21 insertions(+), 14 deletions(-) diff --git a/nymea-networkmanager/core.cpp b/nymea-networkmanager/core.cpp index f1d699c..3a8f899 100644 --- a/nymea-networkmanager/core.cpp +++ b/nymea-networkmanager/core.cpp @@ -106,7 +106,7 @@ void Core::run() } // Note: give network-manager more time to start and get online status - QTimer::singleShot(5000, this, &Core::postRun); + QTimer::singleShot(3000, this, &Core::postRun); } Core::Core(QObject *parent) : @@ -117,6 +117,7 @@ Core::Core(QObject *parent) : connect(m_networkManager, &NetworkManager::stateChanged, this, &Core::onNetworkManagerStateChanged); m_bluetoothServer = new BluetoothServer(m_networkManager); + connect(m_bluetoothServer, &BluetoothServer::runningChanged, this, &Core::onBluetoothServerRunningChanged); connect(m_bluetoothServer, &BluetoothServer::connectedChanged, this, &Core::onBluetoothServerConnectedChanged); @@ -179,13 +180,14 @@ void Core::evaluateNetworkManagerState(NetworkManager::NetworkManagerState state startService(); break; default: - qCDebug(dcApplication()) << "Ignoring networkmanager state" << state; + qCDebug(dcApplication()) << "Ignoring" << state; break; } } void Core::startService() { + qCDebug(dcApplication()) << "Start the service..."; if (!m_networkManager->available()) { qCWarning(dcApplication()) << "Could not start services. There is no network manager available."; return; @@ -197,18 +199,14 @@ void Core::startService() return; } - qCDebug(dcApplication()) << "Start service"; - // Disable bluetooth on nymea in order to not crash with client connections m_nymeaService->enableBluetooth(false); // Start the bluetooth server for this wireless device - qCDebug(dcApplication()) << "Start bluetooth service"; m_bluetoothServer->setAdvertiseName(m_advertiseName); m_bluetoothServer->setModelName(m_platformName); m_bluetoothServer->setSoftwareVersion(VERSION_STRING); - - QTimer::singleShot(5000, m_bluetoothServer, &BluetoothServer::start); + m_bluetoothServer->start(); } void Core::stopService() @@ -262,28 +260,31 @@ void Core::onBluetoothServerRunningChanged(bool running) qCDebug(dcApplication()) << "Bluetooth server" << (running ? "started" : "stopped"); if (!running) { - // Enable bluetooth on nymea m_advertisingTimer->stop(); switch (m_mode) { case ModeAlways: qCDebug(dcApplication()) << "Restart the bluetooth service because of \"always\" mode."; - // Give some grace periode for bluez to clean up - QTimer::singleShot(2000, this, &Core::startService); + // Give some grace periode for bluez to clean up and restart the service again + QTimer::singleShot(3000, this, &Core::startService); break; case ModeStart: + // Enable bluetooth on nymea m_nymeaService->enableBluetooth(true); + // We are done here. The bluetooth server was already running break; case ModeOffline: + // Enable bluetooth on nymea m_nymeaService->enableBluetooth(true); evaluateNetworkManagerState(m_networkManager->state()); break; case ModeOnce: - m_nymeaService->enableBluetooth(true); if (m_networkManager->networkSettings()->connections().isEmpty()) { qCDebug(dcApplication()) << "Start the bluetooth service because of \"once\" mode and there is currenlty no network configured yet."; startService(); } else { + // Enable bluetooth on nymea + m_nymeaService->enableBluetooth(true); qCDebug(dcApplication()) << "Not starting the bluetooth service because of \"once\" mode. There are" << m_networkManager->networkSettings()->connections().count() << "network configurations."; } break; @@ -310,7 +311,7 @@ void Core::onNetworkManagerAvailableChanged(bool available) } if (m_initRunning) { - qCDebug(dcApplication()) << "Init is running"; + qCDebug(dcApplication()) << "Init is running..."; return; } diff --git a/nymea-networkmanager/main.cpp b/nymea-networkmanager/main.cpp index 3cce154..8155674 100644 --- a/nymea-networkmanager/main.cpp +++ b/nymea-networkmanager/main.cpp @@ -90,7 +90,7 @@ int main(int argc, char *argv[]) Application application(argc, argv); application.setApplicationName("nymea-networkmanager"); application.setOrganizationName("nymea"); - application.setApplicationVersion("0.3.2"); + application.setApplicationVersion(VERSION_STRING); // Command line parser QCommandLineParser parser; diff --git a/nymea-networkmanager/nymeadservice.cpp b/nymea-networkmanager/nymeadservice.cpp index 30d0bd7..7b62570 100644 --- a/nymea-networkmanager/nymeadservice.cpp +++ b/nymea-networkmanager/nymeadservice.cpp @@ -24,6 +24,12 @@ NymeadService::NymeadService(bool pushbuttonEnabled, QObject *parent) : } } +NymeadService::~NymeadService() +{ + // Note: re-enable bluetooth hardware resource on nymea + enableBluetooth(true); +} + bool NymeadService::available() const { return m_available; diff --git a/nymea-networkmanager/nymeadservice.h b/nymea-networkmanager/nymeadservice.h index 24ff9c5..319fa0b 100644 --- a/nymea-networkmanager/nymeadservice.h +++ b/nymea-networkmanager/nymeadservice.h @@ -13,7 +13,7 @@ class NymeadService : public QObject Q_OBJECT public: explicit NymeadService(bool pushbuttonEnabled, QObject *parent = nullptr); - + ~NymeadService(); bool available() const; void enableBluetooth(const bool &enable); From 1a369e1845062e54f6cb8697adc56cd8d409f8d8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20St=C3=BCrz?= Date: Tue, 8 Oct 2019 16:55:34 +0200 Subject: [PATCH 4/8] Update readme file --- README.md | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index ea22e73..f98d6b4 100644 --- a/README.md +++ b/README.md @@ -7,8 +7,11 @@ if the system is currently not connected to any network. Once the system is conn First you have to install build dependencies: +> Note: the libnymea-networkmanager-dev package can be installed from the [nymea repository](https://nymea.io/en/wiki/nymea/master/install/debian) or built +and installed from [source](https://github.com/nymea/libnymea-networkmanager). + $ sudo apt update - $ sudo apt install qt5-default qtbase5-dev qtbase5-dev-tools libqt5bluetooth5 qtconnectivity5-dev git + $ sudo apt install qt5-default qtbase5-dev qtbase5-dev-tools libqt5bluetooth5 qtconnectivity5-dev libnymea-networkmanager-dev git Clone the source code and change into the source directory @@ -27,7 +30,7 @@ And finally build the daemon and library You can run the daemon directly with following command - $ sudo LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$(pwd)/libnymea-networkmanager/ ./nymea-networkmanager/nymea-networkmanager + $ sudo ./nymea-networkmanager/nymea-networkmanager ## Building the debian packages @@ -45,8 +48,6 @@ In order to build a debian package you can do following: $ ls -l *.deb - - # Config file nymea-networkmanager will search for a config file in the following locations (in this order): From 09c782e3ec5186e00220df2aaf0c322661c6d6a4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20St=C3=BCrz?= Date: Tue, 8 Oct 2019 17:56:14 +0200 Subject: [PATCH 5/8] Add button mode --- README.md | 72 +++++++++---------- nymea-networkmanager.conf | 1 + nymea-networkmanager/core.cpp | 34 ++++++++- nymea-networkmanager/core.h | 15 +++- nymea-networkmanager/main.cpp | 54 +++++++++++--- nymea-networkmanager/nymea-networkmanager.pro | 2 +- 6 files changed, 126 insertions(+), 52 deletions(-) diff --git a/README.md b/README.md index f98d6b4..66eb4ee 100644 --- a/README.md +++ b/README.md @@ -7,11 +7,15 @@ if the system is currently not connected to any network. Once the system is conn First you have to install build dependencies: -> Note: the libnymea-networkmanager-dev package can be installed from the [nymea repository](https://nymea.io/en/wiki/nymea/master/install/debian) or built +> Note: the `libnymea-networkmanager-dev` package can be installed from the [nymea repository](https://nymea.io/en/wiki/nymea/master/install/debian) or built and installed from [source](https://github.com/nymea/libnymea-networkmanager). + +> Note: the `libnymea-gpio-dev` package can be installed from the [nymea repository](https://nymea.io/en/wiki/nymea/master/install/debian) or built +and installed from [source](https://github.com/nymea/nymea-gpio). + $ sudo apt update - $ sudo apt install qt5-default qtbase5-dev qtbase5-dev-tools libqt5bluetooth5 qtconnectivity5-dev libnymea-networkmanager-dev git + $ sudo apt install qt5-default qtbase5-dev qtbase5-dev-tools libqt5bluetooth5 qtconnectivity5-dev libnymea-networkmanager-dev libnymea-gpio-dev git Clone the source code and change into the source directory @@ -63,45 +67,41 @@ this repository and it will be installed to /etc/nymea-networkmanager.conf with # Command line parameters $ nymea-networkmanager --help - Usage:nymea-networkmanager [options] + Usage: ./nymea-networkmanager [options] This daemon allows to configure a wifi network using a bluetooth low energy connection. - Copyright © 2018 - 2019 Simon Stürz + Copyright © 2018-2019 Simon Stürz + + Modes: + - offline This mode starts the bluetooth server once the device is offline + and not connected to any LAN network. + - once This mode starts the bluetooth server only if no network configuration exists. + Once a network connection exists the server will never start again. + - button This mode enables the bluetooth server when a GPIO button has been pressed for + the configured timeout periode. + - always This mode enables the bluetooth server as long the application is running. + - start This mode starts the bluetooth server for 3 minutes on start and shuts down after a connection. + + Options: - -h, --help Displays this help. - -v, --version Displays version information. - -d, --debug Enable more debug output. - -a, --advertise-name The name of the bluetooth - server. Default "BT WLAN setup". - -p, --platform-name The name of the platform this - daemon is running. Default - "nymea-box". - -t, --timeout The timeout of the bluetooth - server. Minimum value is 10. - Default "60". - -m, --mode Run the daemon in a specific - mode. Default is "offline". - - offline: this mode starts the - bluetooth server once the device - is offline and not connected to - any LAN network. - - once: this mode starts the - bluetooth server only if no - network configuration exists. - Once a network connection exists - the server will never start - again. - - always: this mode enables the - bluetooth server as long the - application is running. - - start: this mode starts the - bluetooth server for 3 minutes - on start and shuts down after a - connection. - - + -h, --help Displays this help. + -v, --version Displays version information. + -d, --debug Enable more debug output. + -a, --advertise-name The name of the bluetooth server. Default "BT + WLAN setup". + -p, --platform-name The name of the platform this daemon is running. + Default "nymea-box". + -g, --gpio The GPIO sysfs number for the button GPIO. This + parameter is only needed for the "button" mode. + -t, --timeout The timeout of the bluetooth server. Minimum + value is 10. Default "60". + -m, --mode Run the daemon in a specific mode (offline, + once, always, button, start). Default is + "offline". + + # Bluetooth GATT profile ------------------------------------------- diff --git a/nymea-networkmanager.conf b/nymea-networkmanager.conf index 7a81a10..a6753c2 100644 --- a/nymea-networkmanager.conf +++ b/nymea-networkmanager.conf @@ -3,3 +3,4 @@ Mode=offline Timeout=60 AdvertiseName=BT WLAN setup PlatformName=nymea-box +ButtonGpio=14 diff --git a/nymea-networkmanager/core.cpp b/nymea-networkmanager/core.cpp index 3a8f899..124f0e5 100644 --- a/nymea-networkmanager/core.cpp +++ b/nymea-networkmanager/core.cpp @@ -62,7 +62,7 @@ Core::Mode Core::mode() const return m_mode; } -void Core::setMode(const Core::Mode &mode) +void Core::setMode(Mode mode) { m_mode = mode; } @@ -92,11 +92,21 @@ int Core::advertisingTimeout() const return m_advertisingTimeout; } -void Core::setAdvertisingTimeout(const int advertisingTimeout) +void Core::setAdvertisingTimeout(int advertisingTimeout) { m_advertisingTimeout = advertisingTimeout; } +int Core::buttonGpio() const +{ + return m_buttonGpio; +} + +void Core::setButtonGpio(int buttonGpio) +{ + m_buttonGpio = buttonGpio; +} + void Core::run() { // Start the networkmanager @@ -243,6 +253,17 @@ void Core::postRun() qCDebug(dcApplication()) << "Not starting the bluetooth service because of \"once\" mode. There are" << m_networkManager->networkSettings()->connections().count() << "network configurations."; } break; + case ModeButton: + // Enable button + m_button = new GpioButton(m_buttonGpio, this); + m_button->setLongPressedTimeout(2000); + connect(m_button, &GpioButton::longPressed, this, &Core::onButtonLongPressed); + if (!m_button->enable()) { + qCCritical(dcApplication()) << "Could not not enable GPIO button for" << m_buttonGpio; + m_button->deleteLater(); + m_button = nullptr; + } + break; } } @@ -288,6 +309,8 @@ void Core::onBluetoothServerRunningChanged(bool running) qCDebug(dcApplication()) << "Not starting the bluetooth service because of \"once\" mode. There are" << m_networkManager->networkSettings()->connections().count() << "network configurations."; } break; + case ModeButton: + break; } } } @@ -336,6 +359,8 @@ void Core::onNetworkManagerAvailableChanged(bool available) qCDebug(dcApplication()) << "Not starting the bluetooth service because of \"once\" mode. There are" << m_networkManager->networkSettings()->connections().count() << "network configurations."; } break; + case ModeButton: + break; } } @@ -344,6 +369,11 @@ void Core::onNetworkManagerStateChanged(NetworkManager::NetworkManagerState stat evaluateNetworkManagerState(state); } +void Core::onButtonLongPressed() +{ + startService(); +} + void Core::onNymeaServiceAvailableChanged(bool available) { if (available) diff --git a/nymea-networkmanager/core.h b/nymea-networkmanager/core.h index 86227dd..961bb51 100644 --- a/nymea-networkmanager/core.h +++ b/nymea-networkmanager/core.h @@ -25,6 +25,7 @@ #include #include "nymeadservice.h" +#include "nymea-gpio/gpiobutton.h" #include "bluetooth/bluetoothserver.h" #include "nymea-networkmanager/networkmanager.h" #include "nymea-networkmanager/bluetooth/bluetoothserver.h" @@ -38,7 +39,8 @@ public: ModeAlways, ModeOffline, ModeOnce, - ModeStart + ModeStart, + ModeButton }; Q_ENUM(Mode) @@ -50,7 +52,7 @@ public: NymeadService *nymeaService() const; Mode mode() const; - void setMode(const Mode &mode); + void setMode(Mode mode); QString advertiseName() const; void setAdvertiseName(const QString &name); @@ -59,7 +61,10 @@ public: void setPlatformName(const QString &name); int advertisingTimeout() const; - void setAdvertisingTimeout(const int advertisingTimeout); + void setAdvertisingTimeout(int advertisingTimeout); + + int buttonGpio() const; + void setButtonGpio(int buttonGpio); void run(); @@ -73,6 +78,7 @@ private: BluetoothServer *m_bluetoothServer = nullptr; NymeadService *m_nymeaService = nullptr; WirelessNetworkDevice *m_wirelessDevice = nullptr; + GpioButton *m_button = nullptr; QTimer *m_advertisingTimer = nullptr; @@ -81,6 +87,7 @@ private: QString m_platformName; int m_advertisingTimeout = 60; bool m_initRunning = true; + int m_buttonGpio = -1; void evaluateNetworkManagerState(NetworkManager::NetworkManagerState state); @@ -98,6 +105,8 @@ private slots: void onNetworkManagerAvailableChanged(bool available); void onNetworkManagerStateChanged(NetworkManager::NetworkManagerState state); + void onButtonLongPressed(); + void onNymeaServiceAvailableChanged(bool available); }; diff --git a/nymea-networkmanager/main.cpp b/nymea-networkmanager/main.cpp index 8155674..c30497c 100644 --- a/nymea-networkmanager/main.cpp +++ b/nymea-networkmanager/main.cpp @@ -84,6 +84,7 @@ int main(int argc, char *argv[]) // Default configuration: Core::Mode mode = Core::ModeOffline; int timeout = 60; + int buttonGpio = -1; QString advertiseName = "BT WLAN setup"; QString platformName = "nymea-box"; @@ -96,8 +97,17 @@ int main(int argc, char *argv[]) QCommandLineParser parser; parser.addHelpOption(); parser.addVersionOption(); - parser.setApplicationDescription(QString("\nThis daemon allows to configure a wifi network using a bluetooth low energy connection." \ - "\n\nCopyright %1 2018-2019 Simon Stürz ").arg(QChar(0xA9))); + parser.setApplicationDescription(QString("\nThis daemon allows to configure a wifi network using a bluetooth low energy connection.\n\n" + "Copyright %1 2018-2019 Simon Stürz \n\n" + "Modes: \n" + " - offline This mode starts the bluetooth server once the device is offline\n" + " and not connected to any LAN network.\n" + " - once This mode starts the bluetooth server only if no network configuration exists.\n" + " Once a network connection exists the server will never start again.\n" + " - button This mode enables the bluetooth server when a GPIO button has been pressed for\n" + " the configured timeout periode.\n" + " - always This mode enables the bluetooth server as long the application is running.\n" + " - start This mode starts the bluetooth server for 3 minutes on start and shuts down after a connection.\n\n").arg(QChar(0xA9))); QCommandLineOption debugOption(QStringList() << "d" << "debug", "Enable more debug output."); parser.addOption(debugOption); @@ -110,15 +120,15 @@ int main(int argc, char *argv[]) platformNameOption.setDefaultValue(platformName); parser.addOption(platformNameOption); + QCommandLineOption gpioOption(QStringList() << "g" << "gpio", QString("The GPIO sysfs number for the button GPIO. This parameter is only needed for the \"button\" mode."), "GPIO"); + platformNameOption.setDefaultValue("-1"); + parser.addOption(gpioOption); + QCommandLineOption timeoutOption(QStringList() << "t" << "timeout", QString("The timeout of the bluetooth server. Minimum value is 10. Default \"%1\".").arg(timeout), "SECONDS"); timeoutOption.setDefaultValue(QString::number(timeout)); parser.addOption(timeoutOption); - QCommandLineOption modeOption(QStringList() << "m" << "mode", "Run the daemon in a specific mode. Default is \"offline\".\n\n" \ - "- offline: this mode starts the bluetooth server once the device is offline and not connected to any LAN network.\n\n" \ - "- once: this mode starts the bluetooth server only if no network configuration exists. Once a network connection exists the server will never start again.\n\n" \ - "- always: this mode enables the bluetooth server as long the application is running.\n\n" \ - "- start: this mode starts the bluetooth server for 3 minutes on start and shuts down after a connection.\n\n", "offline | once | always | start"); + QCommandLineOption modeOption(QStringList() << "m" << "mode", "Run the daemon in a specific mode (offline, once, always, button, start). Default is \"offline\".", "MODE"); parser.addOption(modeOption); parser.process(application); @@ -132,6 +142,7 @@ int main(int argc, char *argv[]) QLoggingCategory::installFilter(loggingCategoryFilter); bool timeoutValueOk = true; + bool gpioValueOk = true; // Now read the cofig file, overriding defaults QStringList configLocations; @@ -152,10 +163,15 @@ int main(int argc, char *argv[]) mode = Core::ModeStart; } else if (settings.value("Mode").toString().toLower() == "once") { mode = Core::ModeOnce; + } else if (settings.value("Mode").toString().toLower() == "button") { + mode = Core::ModeButton; } else { qCWarning(dcApplication()).noquote() << QString("The config file's mode \"%1\" does not match the allowed modes.").arg(settings.value("Mode").toString()); } } + if (settings.contains("ButtonGpio")) { + buttonGpio = settings.value("ButtonGpio", -1).toInt(&gpioValueOk); + } if (settings.contains("Timeout")) { timeout = settings.value("Timeout").toInt(&timeoutValueOk); } @@ -179,7 +195,10 @@ int main(int argc, char *argv[]) mode = Core::ModeStart; } else if (parser.value(modeOption).toLower() == "once") { mode = Core::ModeOnce; - } else { + } else if (parser.value(modeOption).toLower() == "button") { + mode = Core::ModeButton; + + } else { qCWarning(dcApplication()).noquote() << QString("The given mode \"%1\" does not match the allowed modes.").arg(parser.value(modeOption)); parser.showHelp(1); } @@ -193,15 +212,27 @@ int main(int argc, char *argv[]) if (parser.isSet(timeoutOption)) { timeout = parser.value(timeoutOption).toInt(&timeoutValueOk); } + if (parser.isSet(gpioOption)) { + buttonGpio = parser.value(gpioOption).toInt(&gpioValueOk); + } // All parsed. Validate input: if (!timeoutValueOk) { qCCritical(dcApplication()) << QString("Invalid timeout value passed: \"%1\". Please pass an integer >= 10").arg(parser.value(timeoutOption)); - parser.showHelp(1); + return(1); + } + if (!gpioValueOk) { + qCCritical(dcApplication()) << QString("Invalid GPIO number value passed: \"%1\". Please pass an integer > 0").arg(parser.value(gpioOption)); + return(1); } if (timeout < 10) { qCCritical(dcApplication()) << QString("Invalid timeout value passed: \"%1\". The minimal timeout is 10 [s].").arg(parser.value(timeoutOption)); - parser.showHelp(1); + return(1); + } + + if (mode == Core::ModeButton && buttonGpio <= 0) { + qCCritical(dcApplication()) << "Button mode selected but no valid GPIO passed."; + return(1); } qCDebug(dcApplication()) << "====================================="; @@ -211,12 +242,15 @@ int main(int argc, char *argv[]) qCDebug(dcApplication()) << "Platform name:" << platformName; qCDebug(dcApplication()) << "Mode:" << mode; qCDebug(dcApplication()) << "Timeout:" << timeout; + if (mode == Core::ModeButton) + qCDebug(dcApplication()) << "Button GPIO:" << buttonGpio; // Start core Core::instance()->setMode(mode); Core::instance()->setAdvertisingTimeout(timeout); Core::instance()->setAdvertiseName(advertiseName); Core::instance()->setPlatformName(platformName); + Core::instance()->setButtonGpio(buttonGpio); Core::instance()->run(); diff --git a/nymea-networkmanager/nymea-networkmanager.pro b/nymea-networkmanager/nymea-networkmanager.pro index c49bd3e..fd84155 100644 --- a/nymea-networkmanager/nymea-networkmanager.pro +++ b/nymea-networkmanager/nymea-networkmanager.pro @@ -9,7 +9,7 @@ CONFIG += console link_pkgconfig CONFIG -= app_bundle TEMPLATE = app -PKGCONFIG += nymea-networkmanager +PKGCONFIG += nymea-networkmanager nymea-gpio HEADERS += \ application.h \ From e670137052c5826f60c6597e0af84cd8135fbe4c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20St=C3=BCrz?= Date: Tue, 8 Oct 2019 17:56:59 +0200 Subject: [PATCH 6/8] Add libnymea-gpio as dependency --- debian/control | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/debian/control b/debian/control index 8a733f9..70d1e39 100644 --- a/debian/control +++ b/debian/control @@ -9,7 +9,8 @@ Build-Depends: debhelper (>= 9.0.0), qtbase5-dev-tools, libqt5bluetooth5, qtconnectivity5-dev, - libnymea-networkmanager-dev + libnymea-networkmanager-dev, + libnymea-gpio-dev Standards-Version: 3.9.7 Package: nymea-networkmanager @@ -18,7 +19,8 @@ Depends: ${misc:Depends}, libqt5network5, libqt5bluetooth5, network-manager, - libnymea-networkmanager + libnymea-networkmanager, + libnymea-gpio Description: Daemon for wireless configuration using bluetooth LE. This daemon allows to configure a wireless network using a bluetooth low energy gatt server. The tool is written in Qt 5. From 6eb0788719d55704ec4758a7b8c775b9e571931f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20St=C3=BCrz?= Date: Wed, 9 Oct 2019 10:14:12 +0200 Subject: [PATCH 7/8] Adjust grace period for bluez when restarting the bluetooth server --- nymea-networkmanager/core.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nymea-networkmanager/core.cpp b/nymea-networkmanager/core.cpp index 124f0e5..54f4047 100644 --- a/nymea-networkmanager/core.cpp +++ b/nymea-networkmanager/core.cpp @@ -344,7 +344,7 @@ void Core::onNetworkManagerAvailableChanged(bool available) case ModeAlways: qCDebug(dcApplication()) << "Start the bluetooth service because of \"always\" mode."; // Give some grace periode for networkmanager - QTimer::singleShot(2000, this, &Core::startService); + QTimer::singleShot(4000, this, &Core::startService); break; case ModeStart: break; From 2f8c629b7b0448b6d25c5bf3968ac9060fb38bd3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20St=C3=BCrz?= Date: Wed, 9 Oct 2019 14:01:00 +0200 Subject: [PATCH 8/8] Update changelog for jenkins --- debian/changelog | 2 -- 1 file changed, 2 deletions(-) diff --git a/debian/changelog b/debian/changelog index d6cde0e..5ce572c 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,7 +1,5 @@ nymea-networkmanager (0.5.0) UNRELEASED; urgency=medium - * Migrate to libnymea-networkmanager bluetooth server and improve mode handling - -- Simon Stürz Tue, 08 Oct 2019 15:17:22 +0200 nymea-networkmanager (0.4.1) xenial; urgency=medium