Merge PR #21: Migrate libnymea networkmanager bluetoothserver
This commit is contained in:
commit
581e76a323
73
README.md
73
README.md
@ -7,8 +7,15 @@ if the system is currently not connected to any network. Once the system is conn
|
|||||||
|
|
||||||
First you have to install build dependencies:
|
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).
|
||||||
|
|
||||||
|
|
||||||
|
> 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 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 libnymea-gpio-dev git
|
||||||
|
|
||||||
Clone the source code and change into the source directory
|
Clone the source code and change into the source directory
|
||||||
|
|
||||||
@ -27,7 +34,7 @@ And finally build the daemon and library
|
|||||||
|
|
||||||
You can run the daemon directly with following command
|
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
|
## Building the debian packages
|
||||||
@ -45,8 +52,6 @@ In order to build a debian package you can do following:
|
|||||||
|
|
||||||
$ ls -l *.deb
|
$ ls -l *.deb
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# Config file
|
# Config file
|
||||||
|
|
||||||
nymea-networkmanager will search for a config file in the following locations (in this order):
|
nymea-networkmanager will search for a config file in the following locations (in this order):
|
||||||
@ -62,43 +67,39 @@ this repository and it will be installed to /etc/nymea-networkmanager.conf with
|
|||||||
# Command line parameters
|
# Command line parameters
|
||||||
|
|
||||||
$ nymea-networkmanager --help
|
$ 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.
|
This daemon allows to configure a wifi network using a bluetooth low energy connection.
|
||||||
|
|
||||||
Copyright © 2018 - 2019 Simon Stürz <simon.stuerz@guh.io>
|
Copyright © 2018-2019 Simon Stürz <simon.stuerz@nymea.io>
|
||||||
|
|
||||||
|
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:
|
Options:
|
||||||
-h, --help Displays this help.
|
-h, --help Displays this help.
|
||||||
-v, --version Displays version information.
|
-v, --version Displays version information.
|
||||||
-d, --debug Enable more debug output.
|
-d, --debug Enable more debug output.
|
||||||
-a, --advertise-name <NAME> The name of the bluetooth
|
-a, --advertise-name <NAME> The name of the bluetooth server. Default "BT
|
||||||
server. Default "BT WLAN setup".
|
WLAN setup".
|
||||||
-p, --platform-name <NAME> The name of the platform this
|
-p, --platform-name <NAME> The name of the platform this daemon is running.
|
||||||
daemon is running. Default
|
Default "nymea-box".
|
||||||
"nymea-box".
|
-g, --gpio <GPIO> The GPIO sysfs number for the button GPIO. This
|
||||||
-t, --timeout <SECONDS> The timeout of the bluetooth
|
parameter is only needed for the "button" mode.
|
||||||
server. Minimum value is 10.
|
-t, --timeout <SECONDS> The timeout of the bluetooth server. Minimum
|
||||||
Default "60".
|
value is 10. Default "60".
|
||||||
-m, --mode <offline | once | always | start> Run the daemon in a specific
|
-m, --mode <MODE> Run the daemon in a specific mode (offline,
|
||||||
mode. Default is "offline".
|
once, always, button, start). Default is
|
||||||
- offline: this mode starts the
|
"offline".
|
||||||
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.
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
11
debian/changelog
vendored
11
debian/changelog
vendored
@ -1,3 +1,14 @@
|
|||||||
|
nymea-networkmanager (0.5.0) UNRELEASED; urgency=medium
|
||||||
|
|
||||||
|
-- Simon Stürz <simon.stuerz@nymea.io> Tue, 08 Oct 2019 15:17:22 +0200
|
||||||
|
|
||||||
|
nymea-networkmanager (0.4.1) xenial; urgency=medium
|
||||||
|
|
||||||
|
[ Simon Stürz ]
|
||||||
|
* Update pkg-config include for libnymea-networkmanager
|
||||||
|
|
||||||
|
-- Jenkins <jenkins@nymea.io> Thu, 19 Sep 2019 09:52:51 +0200
|
||||||
|
|
||||||
nymea-networkmanager (0.4.0) bionic; urgency=medium
|
nymea-networkmanager (0.4.0) bionic; urgency=medium
|
||||||
|
|
||||||
* Move libnymea-networkmanager out of this project into a separate one
|
* Move libnymea-networkmanager out of this project into a separate one
|
||||||
|
|||||||
6
debian/control
vendored
6
debian/control
vendored
@ -9,7 +9,8 @@ Build-Depends: debhelper (>= 9.0.0),
|
|||||||
qtbase5-dev-tools,
|
qtbase5-dev-tools,
|
||||||
libqt5bluetooth5,
|
libqt5bluetooth5,
|
||||||
qtconnectivity5-dev,
|
qtconnectivity5-dev,
|
||||||
libnymea-networkmanager-dev
|
libnymea-networkmanager-dev,
|
||||||
|
libnymea-gpio-dev
|
||||||
Standards-Version: 3.9.7
|
Standards-Version: 3.9.7
|
||||||
|
|
||||||
Package: nymea-networkmanager
|
Package: nymea-networkmanager
|
||||||
@ -18,7 +19,8 @@ Depends: ${misc:Depends},
|
|||||||
libqt5network5,
|
libqt5network5,
|
||||||
libqt5bluetooth5,
|
libqt5bluetooth5,
|
||||||
network-manager,
|
network-manager,
|
||||||
libnymea-networkmanager
|
libnymea-networkmanager,
|
||||||
|
libnymea-gpio
|
||||||
Description: Daemon for wireless configuration using bluetooth LE.
|
Description: Daemon for wireless configuration using bluetooth LE.
|
||||||
This daemon allows to configure a wireless network using a bluetooth
|
This daemon allows to configure a wireless network using a bluetooth
|
||||||
low energy gatt server. The tool is written in Qt 5.
|
low energy gatt server. The tool is written in Qt 5.
|
||||||
|
|||||||
5
debian/nymea-networkmanager.service
vendored
5
debian/nymea-networkmanager.service
vendored
@ -1,7 +1,8 @@
|
|||||||
[Unit]
|
[Unit]
|
||||||
Description=Daemon for nymea to configure wifi network using a Bluetooth LE connection
|
Description=Daemon for nymea to configure wifi network using a Bluetooth LE connection
|
||||||
Documentation=https://github.com/guh/nymea-networkmanager
|
Documentation=https://github.com/nymea/nymea-networkmanager
|
||||||
After=network.target
|
Wants=bluetooth.service NetworkManager.service
|
||||||
|
After=bluetooth.service NetworkManager.service
|
||||||
|
|
||||||
[Service]
|
[Service]
|
||||||
ExecStart=/usr/bin/nymea-networkmanager -d
|
ExecStart=/usr/bin/nymea-networkmanager -d
|
||||||
|
|||||||
@ -3,3 +3,4 @@ Mode=offline
|
|||||||
Timeout=60
|
Timeout=60
|
||||||
AdvertiseName=BT WLAN setup
|
AdvertiseName=BT WLAN setup
|
||||||
PlatformName=nymea-box
|
PlatformName=nymea-box
|
||||||
|
ButtonGpio=14
|
||||||
|
|||||||
@ -4,3 +4,5 @@ QMAKE_LFLAGS *= -std=c++1z
|
|||||||
top_srcdir=$$PWD
|
top_srcdir=$$PWD
|
||||||
top_builddir=$$shadowed($$PWD)
|
top_builddir=$$shadowed($$PWD)
|
||||||
|
|
||||||
|
VERSION_STRING=$$system('dpkg-parsechangelog | sed -n -e "s/^Version: //p"')
|
||||||
|
DEFINES += VERSION_STRING=\\\"$${VERSION_STRING}\\\"
|
||||||
|
|||||||
@ -1,478 +0,0 @@
|
|||||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
|
||||||
* *
|
|
||||||
* Copyright (C) 2018 Simon Stürz <simon.stuerz@guh.io> *
|
|
||||||
* *
|
|
||||||
* 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 <http://www.gnu.org/licenses/>. *
|
|
||||||
* *
|
|
||||||
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
|
||||||
|
|
||||||
#include "bluetoothserver.h"
|
|
||||||
#include "loggingcategories.h"
|
|
||||||
#include "bluetoothuuids.h"
|
|
||||||
|
|
||||||
#include <QJsonDocument>
|
|
||||||
#include <QCoreApplication>
|
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
@ -1,128 +0,0 @@
|
|||||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
|
||||||
* *
|
|
||||||
* Copyright (C) 2018 Simon Stürz <simon.stuerz@guh.io> *
|
|
||||||
* *
|
|
||||||
* 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 <http://www.gnu.org/licenses/>. *
|
|
||||||
* *
|
|
||||||
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
|
||||||
|
|
||||||
#ifndef BLUETOOTHSERVER_H
|
|
||||||
#define BLUETOOTHSERVER_H
|
|
||||||
|
|
||||||
#include <QTimer>
|
|
||||||
#include <QObject>
|
|
||||||
#include <QPointer>
|
|
||||||
#include <QLowEnergyHandle>
|
|
||||||
#include <QLowEnergyService>
|
|
||||||
#include <QBluetoothLocalDevice>
|
|
||||||
#include <QLowEnergyController>
|
|
||||||
#include <QLowEnergyServiceData>
|
|
||||||
#include <QLowEnergyCharacteristic>
|
|
||||||
#include <QLowEnergyDescriptorData>
|
|
||||||
#include <QLowEnergyAdvertisingData>
|
|
||||||
#include <QLowEnergyCharacteristicData>
|
|
||||||
#include <QLowEnergyConnectionParameters>
|
|
||||||
#include <QLowEnergyAdvertisingParameters>
|
|
||||||
|
|
||||||
#include "networkservice.h"
|
|
||||||
#include "wirelessservice.h"
|
|
||||||
#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
|
|
||||||
@ -1,46 +0,0 @@
|
|||||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
|
||||||
* *
|
|
||||||
* Copyright (C) 2018 Simon Stürz <simon.stuerz@guh.io> *
|
|
||||||
* *
|
|
||||||
* 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 <http://www.gnu.org/licenses/>. *
|
|
||||||
* *
|
|
||||||
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
|
||||||
|
|
||||||
#ifndef BLUETOOTHUUIDS_H
|
|
||||||
#define BLUETOOTHUUIDS_H
|
|
||||||
|
|
||||||
#include <QBluetoothUuid>
|
|
||||||
|
|
||||||
static QBluetoothUuid networkServiceUuid = QBluetoothUuid(QUuid("ef6d6610-b8af-49e0-9eca-ab343513641c"));
|
|
||||||
static QBluetoothUuid networkStatusCharacteristicUuid = QBluetoothUuid(QUuid("ef6d6611-b8af-49e0-9eca-ab343513641c"));
|
|
||||||
static QBluetoothUuid networkCommanderCharacteristicUuid = QBluetoothUuid(QUuid("ef6d6612-b8af-49e0-9eca-ab343513641c"));
|
|
||||||
static QBluetoothUuid networkResponseCharacteristicUuid = QBluetoothUuid(QUuid("ef6d6613-b8af-49e0-9eca-ab343513641c"));
|
|
||||||
static QBluetoothUuid networkingEnabledCharacteristicUuid = QBluetoothUuid(QUuid("ef6d6614-b8af-49e0-9eca-ab343513641c"));
|
|
||||||
static QBluetoothUuid wirelessEnabledCharacteristicUuid = QBluetoothUuid(QUuid("ef6d6615-b8af-49e0-9eca-ab343513641c"));
|
|
||||||
|
|
||||||
static QBluetoothUuid wirelessServiceUuid = QBluetoothUuid(QUuid("e081fec0-f757-4449-b9c9-bfa83133f7fc"));
|
|
||||||
static QBluetoothUuid wirelessCommanderCharacteristicUuid = QBluetoothUuid(QUuid("e081fec1-f757-4449-b9c9-bfa83133f7fc"));
|
|
||||||
static QBluetoothUuid wirelessResponseCharacteristicUuid = QBluetoothUuid(QUuid("e081fec2-f757-4449-b9c9-bfa83133f7fc"));
|
|
||||||
static QBluetoothUuid wirelessStateCharacteristicUuid = QBluetoothUuid(QUuid("e081fec3-f757-4449-b9c9-bfa83133f7fc"));
|
|
||||||
static QBluetoothUuid wirelessModeCharacteristicUuid = QBluetoothUuid(QUuid("e081fec4-f757-4449-b9c9-bfa83133f7fc"));
|
|
||||||
|
|
||||||
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
|
|
||||||
@ -1,377 +0,0 @@
|
|||||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
|
||||||
* *
|
|
||||||
* Copyright (C) 2018 Simon Stürz <simon.stuerz@guh.io> *
|
|
||||||
* *
|
|
||||||
* 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 <http://www.gnu.org/licenses/>. *
|
|
||||||
* *
|
|
||||||
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
|
||||||
|
|
||||||
#include "networkservice.h"
|
|
||||||
|
|
||||||
#include "core.h"
|
|
||||||
#include "bluetoothuuids.h"
|
|
||||||
#include "loggingcategories.h"
|
|
||||||
|
|
||||||
#include <QLowEnergyDescriptorData>
|
|
||||||
#include <QLowEnergyCharacteristicData>
|
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,94 +0,0 @@
|
|||||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
|
||||||
* *
|
|
||||||
* Copyright (C) 2018 Simon Stürz <simon.stuerz@guh.io> *
|
|
||||||
* *
|
|
||||||
* 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 <http://www.gnu.org/licenses/>. *
|
|
||||||
* *
|
|
||||||
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
|
||||||
|
|
||||||
#ifndef NETWORKSERVICE_H
|
|
||||||
#define NETWORKSERVICE_H
|
|
||||||
|
|
||||||
#include <QObject>
|
|
||||||
#include <QLowEnergyService>
|
|
||||||
#include <QLowEnergyServiceData>
|
|
||||||
|
|
||||||
#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
|
|
||||||
@ -1,256 +0,0 @@
|
|||||||
#include "systemservice.h"
|
|
||||||
#include "bluetoothuuids.h"
|
|
||||||
#include "loggingcategory.h"
|
|
||||||
#include "loopd.h"
|
|
||||||
|
|
||||||
#include <QJsonDocument>
|
|
||||||
#include <QJsonParseError>
|
|
||||||
#include <QLowEnergyDescriptorData>
|
|
||||||
#include <QLowEnergyCharacteristicData>
|
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
@ -1,60 +0,0 @@
|
|||||||
#ifndef SYSTEMSERVICE_H
|
|
||||||
#define SYSTEMSERVICE_H
|
|
||||||
|
|
||||||
#include <QObject>
|
|
||||||
#include <QLowEnergyService>
|
|
||||||
#include <QLowEnergyServiceData>
|
|
||||||
|
|
||||||
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
|
|
||||||
@ -1,574 +0,0 @@
|
|||||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
|
||||||
* *
|
|
||||||
* Copyright (C) 2018 Simon Stürz <simon.stuerz@guh.io> *
|
|
||||||
* *
|
|
||||||
* 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 <http://www.gnu.org/licenses/>. *
|
|
||||||
* *
|
|
||||||
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
|
||||||
|
|
||||||
#include "wirelessservice.h"
|
|
||||||
|
|
||||||
#include "core.h"
|
|
||||||
#include "bluetoothuuids.h"
|
|
||||||
#include "loggingcategories.h"
|
|
||||||
|
|
||||||
#include <QJsonDocument>
|
|
||||||
#include <QNetworkInterface>
|
|
||||||
#include <QLowEnergyDescriptorData>
|
|
||||||
#include <QLowEnergyCharacteristicData>
|
|
||||||
|
|
||||||
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<int>(command));
|
|
||||||
response.insert("r", static_cast<int>(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<int>(accessPoint->isProtected()));
|
|
||||||
accessPointVariantList.append(accessPointVariantMap);
|
|
||||||
}
|
|
||||||
|
|
||||||
QVariantMap response = createResponse(WirelessServiceCommandGetNetworks);
|
|
||||||
response.insert("p", accessPointVariantList);
|
|
||||||
|
|
||||||
streamData(response);
|
|
||||||
}
|
|
||||||
|
|
||||||
void WirelessService::commandConnect(const QVariantMap &request)
|
|
||||||
{
|
|
||||||
if (!m_service) {
|
|
||||||
qCWarning(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<int>(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<WirelessServiceCommand>(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));
|
|
||||||
}
|
|
||||||
@ -1,116 +0,0 @@
|
|||||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
|
||||||
* *
|
|
||||||
* Copyright (C) 2018 Simon Stürz <simon.stuerz@guh.io> *
|
|
||||||
* *
|
|
||||||
* 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 <http://www.gnu.org/licenses/>. *
|
|
||||||
* *
|
|
||||||
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
|
||||||
|
|
||||||
#ifndef WIRELESSSERVICE_H
|
|
||||||
#define WIRELESSSERVICE_H
|
|
||||||
|
|
||||||
#include <QObject>
|
|
||||||
#include <QVariantMap>
|
|
||||||
#include <QLowEnergyService>
|
|
||||||
#include <QLowEnergyServiceData>
|
|
||||||
|
|
||||||
#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
|
|
||||||
@ -62,7 +62,7 @@ Core::Mode Core::mode() const
|
|||||||
return m_mode;
|
return m_mode;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Core::setMode(const Core::Mode &mode)
|
void Core::setMode(Mode mode)
|
||||||
{
|
{
|
||||||
m_mode = mode;
|
m_mode = mode;
|
||||||
}
|
}
|
||||||
@ -92,11 +92,21 @@ int Core::advertisingTimeout() const
|
|||||||
return m_advertisingTimeout;
|
return m_advertisingTimeout;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Core::setAdvertisingTimeout(const int advertisingTimeout)
|
void Core::setAdvertisingTimeout(int advertisingTimeout)
|
||||||
{
|
{
|
||||||
m_advertisingTimeout = advertisingTimeout;
|
m_advertisingTimeout = advertisingTimeout;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int Core::buttonGpio() const
|
||||||
|
{
|
||||||
|
return m_buttonGpio;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Core::setButtonGpio(int buttonGpio)
|
||||||
|
{
|
||||||
|
m_buttonGpio = buttonGpio;
|
||||||
|
}
|
||||||
|
|
||||||
void Core::run()
|
void Core::run()
|
||||||
{
|
{
|
||||||
// Start the networkmanager
|
// Start the networkmanager
|
||||||
@ -106,7 +116,7 @@ void Core::run()
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Note: give network-manager more time to start and get online status
|
// 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) :
|
Core::Core(QObject *parent) :
|
||||||
@ -115,12 +125,9 @@ Core::Core(QObject *parent) :
|
|||||||
m_networkManager = new NetworkManager(this);
|
m_networkManager = new NetworkManager(this);
|
||||||
connect(m_networkManager, &NetworkManager::availableChanged, this, &Core::onNetworkManagerAvailableChanged);
|
connect(m_networkManager, &NetworkManager::availableChanged, this, &Core::onNetworkManagerAvailableChanged);
|
||||||
connect(m_networkManager, &NetworkManager::stateChanged, this, &Core::onNetworkManagerStateChanged);
|
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::runningChanged, this, &Core::onBluetoothServerRunningChanged);
|
||||||
connect(m_bluetoothServer, &BluetoothServer::connectedChanged, this, &Core::onBluetoothServerConnectedChanged);
|
connect(m_bluetoothServer, &BluetoothServer::connectedChanged, this, &Core::onBluetoothServerConnectedChanged);
|
||||||
|
|
||||||
@ -129,7 +136,6 @@ Core::Core(QObject *parent) :
|
|||||||
|
|
||||||
m_advertisingTimer = new QTimer(this);
|
m_advertisingTimer = new QTimer(this);
|
||||||
m_advertisingTimer->setSingleShot(true);
|
m_advertisingTimer->setSingleShot(true);
|
||||||
|
|
||||||
connect(m_advertisingTimer, &QTimer::timeout, this, &Core::onAdvertisingTimeout);
|
connect(m_advertisingTimer, &QTimer::timeout, this, &Core::onAdvertisingTimeout);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -148,7 +154,7 @@ Core::~Core()
|
|||||||
m_networkManager = nullptr;
|
m_networkManager = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Core::evaluateNetworkManagerState(const NetworkManager::NetworkManagerState &state)
|
void Core::evaluateNetworkManagerState(NetworkManager::NetworkManagerState state)
|
||||||
{
|
{
|
||||||
if (m_mode != ModeOffline)
|
if (m_mode != ModeOffline)
|
||||||
return;
|
return;
|
||||||
@ -162,6 +168,7 @@ void Core::evaluateNetworkManagerState(const NetworkManager::NetworkManagerState
|
|||||||
switch (state) {
|
switch (state) {
|
||||||
case NetworkManager::NetworkManagerStateConnectedGlobal:
|
case NetworkManager::NetworkManagerStateConnectedGlobal:
|
||||||
// We are online
|
// 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()) {
|
if (m_bluetoothServer->running() && !m_bluetoothServer->connected()) {
|
||||||
qCDebug(dcApplication()) << "Stop the bluetooth service because of \"offline\" mode.";
|
qCDebug(dcApplication()) << "Stop the bluetooth service because of \"offline\" mode.";
|
||||||
stopService();
|
stopService();
|
||||||
@ -183,13 +190,14 @@ void Core::evaluateNetworkManagerState(const NetworkManager::NetworkManagerState
|
|||||||
startService();
|
startService();
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
qCDebug(dcApplication()) << "Ignoring networkmanager state" << state;
|
qCDebug(dcApplication()) << "Ignoring" << state;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Core::startService()
|
void Core::startService()
|
||||||
{
|
{
|
||||||
|
qCDebug(dcApplication()) << "Start the service...";
|
||||||
if (!m_networkManager->available()) {
|
if (!m_networkManager->available()) {
|
||||||
qCWarning(dcApplication()) << "Could not start services. There is no network manager available.";
|
qCWarning(dcApplication()) << "Could not start services. There is no network manager available.";
|
||||||
return;
|
return;
|
||||||
@ -201,17 +209,14 @@ void Core::startService()
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
qCDebug(dcApplication()) << "Start service";
|
|
||||||
|
|
||||||
// Disable bluetooth on nymea in order to not crash with client connections
|
// Disable bluetooth on nymea in order to not crash with client connections
|
||||||
m_nymeaService->enableBluetooth(false);
|
m_nymeaService->enableBluetooth(false);
|
||||||
|
|
||||||
// Start the bluetooth server for this wireless device
|
// Start the bluetooth server for this wireless device
|
||||||
qCDebug(dcApplication()) << "Start bluetooth service";
|
|
||||||
m_bluetoothServer->setAdvertiseName(m_advertiseName);
|
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);
|
m_bluetoothServer->start();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Core::stopService()
|
void Core::stopService()
|
||||||
@ -248,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.";
|
qCDebug(dcApplication()) << "Not starting the bluetooth service because of \"once\" mode. There are" << m_networkManager->networkSettings()->connections().count() << "network configurations.";
|
||||||
}
|
}
|
||||||
break;
|
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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -265,18 +281,22 @@ void Core::onBluetoothServerRunningChanged(bool running)
|
|||||||
qCDebug(dcApplication()) << "Bluetooth server" << (running ? "started" : "stopped");
|
qCDebug(dcApplication()) << "Bluetooth server" << (running ? "started" : "stopped");
|
||||||
|
|
||||||
if (!running) {
|
if (!running) {
|
||||||
// Enable bluetooth on nymea
|
|
||||||
m_nymeaService->enableBluetooth(true);
|
|
||||||
m_advertisingTimer->stop();
|
m_advertisingTimer->stop();
|
||||||
|
|
||||||
switch (m_mode) {
|
switch (m_mode) {
|
||||||
case ModeAlways:
|
case ModeAlways:
|
||||||
qCDebug(dcApplication()) << "Restart the bluetooth service because of \"always\" mode.";
|
qCDebug(dcApplication()) << "Restart the bluetooth service because of \"always\" mode.";
|
||||||
startService();
|
// Give some grace periode for bluez to clean up and restart the service again
|
||||||
|
QTimer::singleShot(3000, this, &Core::startService);
|
||||||
break;
|
break;
|
||||||
case ModeStart:
|
case ModeStart:
|
||||||
|
// Enable bluetooth on nymea
|
||||||
|
m_nymeaService->enableBluetooth(true);
|
||||||
|
// We are done here. The bluetooth server was already running
|
||||||
break;
|
break;
|
||||||
case ModeOffline:
|
case ModeOffline:
|
||||||
|
// Enable bluetooth on nymea
|
||||||
|
m_nymeaService->enableBluetooth(true);
|
||||||
evaluateNetworkManagerState(m_networkManager->state());
|
evaluateNetworkManagerState(m_networkManager->state());
|
||||||
break;
|
break;
|
||||||
case ModeOnce:
|
case ModeOnce:
|
||||||
@ -284,9 +304,13 @@ void Core::onBluetoothServerRunningChanged(bool running)
|
|||||||
qCDebug(dcApplication()) << "Start the bluetooth service because of \"once\" mode and there is currenlty no network configured yet.";
|
qCDebug(dcApplication()) << "Start the bluetooth service because of \"once\" mode and there is currenlty no network configured yet.";
|
||||||
startService();
|
startService();
|
||||||
} else {
|
} 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.";
|
qCDebug(dcApplication()) << "Not starting the bluetooth service because of \"once\" mode. There are" << m_networkManager->networkSettings()->connections().count() << "network configurations.";
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case ModeButton:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -294,45 +318,33 @@ void Core::onBluetoothServerRunningChanged(bool running)
|
|||||||
void Core::onBluetoothServerConnectedChanged(bool connected)
|
void Core::onBluetoothServerConnectedChanged(bool connected)
|
||||||
{
|
{
|
||||||
qCDebug(dcApplication()) << "Bluetooth client" << (connected ? "connected" : "disconnected");
|
qCDebug(dcApplication()) << "Bluetooth client" << (connected ? "connected" : "disconnected");
|
||||||
if (connected) {
|
m_advertisingTimer->stop();
|
||||||
m_advertisingTimer->stop();
|
|
||||||
|
|
||||||
m_bluetoothServer->onNetworkManagerAvailableChanged(m_networkManager->available());
|
if (!connected) {
|
||||||
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 {
|
|
||||||
m_advertisingTimer->stop();
|
m_advertisingTimer->stop();
|
||||||
m_bluetoothServer->stop();
|
m_bluetoothServer->stop();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Core::onNetworkManagerAvailableChanged(const bool &available)
|
void Core::onNetworkManagerAvailableChanged(bool available)
|
||||||
{
|
{
|
||||||
if (!available) {
|
if (!available) {
|
||||||
qCWarning(dcApplication()) << "Networkmanager is not available any more.";
|
qCWarning(dcApplication()) << "Networkmanager is not available any more.";
|
||||||
m_bluetoothServer->onNetworkManagerAvailableChanged(m_networkManager->available());
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_initRunning) {
|
if (m_initRunning) {
|
||||||
qCDebug(dcApplication()) << "Init is running";
|
qCDebug(dcApplication()) << "Init is running...";
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
qCDebug(dcApplication()) << "Networkmanager is now available.";
|
qCDebug(dcApplication()) << "Networkmanager is now available.";
|
||||||
m_bluetoothServer->onNetworkManagerAvailableChanged(available);
|
|
||||||
|
|
||||||
switch (m_mode) {
|
switch (m_mode) {
|
||||||
case ModeAlways:
|
case ModeAlways:
|
||||||
qCDebug(dcApplication()) << "Start the bluetooth service because of \"always\" mode.";
|
qCDebug(dcApplication()) << "Start the bluetooth service because of \"always\" mode.";
|
||||||
startService();
|
// Give some grace periode for networkmanager
|
||||||
|
QTimer::singleShot(4000, this, &Core::startService);
|
||||||
break;
|
break;
|
||||||
case ModeStart:
|
case ModeStart:
|
||||||
break;
|
break;
|
||||||
@ -347,77 +359,19 @@ void Core::onNetworkManagerAvailableChanged(const bool &available)
|
|||||||
qCDebug(dcApplication()) << "Not starting the bluetooth service because of \"once\" mode. There are" << m_networkManager->networkSettings()->connections().count() << "network configurations.";
|
qCDebug(dcApplication()) << "Not starting the bluetooth service because of \"once\" mode. There are" << m_networkManager->networkSettings()->connections().count() << "network configurations.";
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case ModeButton:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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);
|
evaluateNetworkManagerState(state);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Core::onNetworkManagerWirelessDeviceAdded(WirelessNetworkDevice *wirelessDevice)
|
void Core::onButtonLongPressed()
|
||||||
{
|
{
|
||||||
if (m_wirelessDevice) {
|
startService();
|
||||||
// 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)
|
void Core::onNymeaServiceAvailableChanged(bool available)
|
||||||
|
|||||||
@ -25,8 +25,10 @@
|
|||||||
#include <QObject>
|
#include <QObject>
|
||||||
|
|
||||||
#include "nymeadservice.h"
|
#include "nymeadservice.h"
|
||||||
|
#include "nymea-gpio/gpiobutton.h"
|
||||||
#include "bluetooth/bluetoothserver.h"
|
#include "bluetooth/bluetoothserver.h"
|
||||||
#include "nymea-networkmanager/networkmanager.h"
|
#include "nymea-networkmanager/networkmanager.h"
|
||||||
|
#include "nymea-networkmanager/bluetooth/bluetoothserver.h"
|
||||||
|
|
||||||
class Core : public QObject
|
class Core : public QObject
|
||||||
{
|
{
|
||||||
@ -37,7 +39,8 @@ public:
|
|||||||
ModeAlways,
|
ModeAlways,
|
||||||
ModeOffline,
|
ModeOffline,
|
||||||
ModeOnce,
|
ModeOnce,
|
||||||
ModeStart
|
ModeStart,
|
||||||
|
ModeButton
|
||||||
};
|
};
|
||||||
Q_ENUM(Mode)
|
Q_ENUM(Mode)
|
||||||
|
|
||||||
@ -49,7 +52,7 @@ public:
|
|||||||
NymeadService *nymeaService() const;
|
NymeadService *nymeaService() const;
|
||||||
|
|
||||||
Mode mode() const;
|
Mode mode() const;
|
||||||
void setMode(const Mode &mode);
|
void setMode(Mode mode);
|
||||||
|
|
||||||
QString advertiseName() const;
|
QString advertiseName() const;
|
||||||
void setAdvertiseName(const QString &name);
|
void setAdvertiseName(const QString &name);
|
||||||
@ -58,7 +61,10 @@ public:
|
|||||||
void setPlatformName(const QString &name);
|
void setPlatformName(const QString &name);
|
||||||
|
|
||||||
int advertisingTimeout() const;
|
int advertisingTimeout() const;
|
||||||
void setAdvertisingTimeout(const int advertisingTimeout);
|
void setAdvertisingTimeout(int advertisingTimeout);
|
||||||
|
|
||||||
|
int buttonGpio() const;
|
||||||
|
void setButtonGpio(int buttonGpio);
|
||||||
|
|
||||||
void run();
|
void run();
|
||||||
|
|
||||||
@ -72,6 +78,7 @@ private:
|
|||||||
BluetoothServer *m_bluetoothServer = nullptr;
|
BluetoothServer *m_bluetoothServer = nullptr;
|
||||||
NymeadService *m_nymeaService = nullptr;
|
NymeadService *m_nymeaService = nullptr;
|
||||||
WirelessNetworkDevice *m_wirelessDevice = nullptr;
|
WirelessNetworkDevice *m_wirelessDevice = nullptr;
|
||||||
|
GpioButton *m_button = nullptr;
|
||||||
|
|
||||||
QTimer *m_advertisingTimer = nullptr;
|
QTimer *m_advertisingTimer = nullptr;
|
||||||
|
|
||||||
@ -80,13 +87,14 @@ private:
|
|||||||
QString m_platformName;
|
QString m_platformName;
|
||||||
int m_advertisingTimeout = 60;
|
int m_advertisingTimeout = 60;
|
||||||
bool m_initRunning = true;
|
bool m_initRunning = true;
|
||||||
|
int m_buttonGpio = -1;
|
||||||
|
|
||||||
void evaluateNetworkManagerState(const NetworkManager::NetworkManagerState &state);
|
void evaluateNetworkManagerState(NetworkManager::NetworkManagerState state);
|
||||||
|
|
||||||
|
private slots:
|
||||||
void startService();
|
void startService();
|
||||||
void stopService();
|
void stopService();
|
||||||
|
|
||||||
private slots:
|
|
||||||
void postRun();
|
void postRun();
|
||||||
|
|
||||||
void onAdvertisingTimeout();
|
void onAdvertisingTimeout();
|
||||||
@ -94,17 +102,10 @@ private slots:
|
|||||||
void onBluetoothServerRunningChanged(bool running);
|
void onBluetoothServerRunningChanged(bool running);
|
||||||
void onBluetoothServerConnectedChanged(bool connected);
|
void onBluetoothServerConnectedChanged(bool connected);
|
||||||
|
|
||||||
void onNetworkManagerAvailableChanged(const bool &available);
|
void onNetworkManagerAvailableChanged(bool available);
|
||||||
void onNetworkManagerNetworkingEnabledChanged(bool enabled);
|
void onNetworkManagerStateChanged(NetworkManager::NetworkManagerState state);
|
||||||
void onNetworkManagerWirelessEnabledChanged(bool enabled);
|
|
||||||
void onNetworkManagerStateChanged(const NetworkManager::NetworkManagerState &state);
|
|
||||||
void onNetworkManagerWirelessDeviceAdded(WirelessNetworkDevice *wirelessDevice);
|
|
||||||
void onNetworkManagerWirelessDeviceRemoved(const QString &interface);
|
|
||||||
|
|
||||||
// Wireless device
|
void onButtonLongPressed();
|
||||||
void onWirelessDeviceBitRateChanged(int bitRate);
|
|
||||||
void onWirelessDeviceModeChanged(WirelessNetworkDevice::Mode mode);
|
|
||||||
void onWirelessDeviceStateChanged(const NetworkDevice::NetworkDeviceState state);
|
|
||||||
|
|
||||||
void onNymeaServiceAvailableChanged(bool available);
|
void onNymeaServiceAvailableChanged(bool available);
|
||||||
|
|
||||||
|
|||||||
@ -22,5 +22,4 @@
|
|||||||
#include "loggingcategories.h"
|
#include "loggingcategories.h"
|
||||||
|
|
||||||
Q_LOGGING_CATEGORY(dcApplication, "Application")
|
Q_LOGGING_CATEGORY(dcApplication, "Application")
|
||||||
Q_LOGGING_CATEGORY(dcBluetoothServer, "BluetoothServer")
|
|
||||||
Q_LOGGING_CATEGORY(dcNymeaService, "NymeaService")
|
Q_LOGGING_CATEGORY(dcNymeaService, "NymeaService")
|
||||||
|
|||||||
@ -26,7 +26,6 @@
|
|||||||
#include <QLoggingCategory>
|
#include <QLoggingCategory>
|
||||||
|
|
||||||
Q_DECLARE_LOGGING_CATEGORY(dcApplication)
|
Q_DECLARE_LOGGING_CATEGORY(dcApplication)
|
||||||
Q_DECLARE_LOGGING_CATEGORY(dcBluetoothServer)
|
|
||||||
Q_DECLARE_LOGGING_CATEGORY(dcNymeaService)
|
Q_DECLARE_LOGGING_CATEGORY(dcNymeaService)
|
||||||
|
|
||||||
#endif // LOGGINGCATEGORIES_H
|
#endif // LOGGINGCATEGORIES_H
|
||||||
|
|||||||
@ -84,20 +84,30 @@ int main(int argc, char *argv[])
|
|||||||
// Default configuration:
|
// Default configuration:
|
||||||
Core::Mode mode = Core::ModeOffline;
|
Core::Mode mode = Core::ModeOffline;
|
||||||
int timeout = 60;
|
int timeout = 60;
|
||||||
|
int buttonGpio = -1;
|
||||||
QString advertiseName = "BT WLAN setup";
|
QString advertiseName = "BT WLAN setup";
|
||||||
QString platformName = "nymea-box";
|
QString platformName = "nymea-box";
|
||||||
|
|
||||||
Application application(argc, argv);
|
Application application(argc, argv);
|
||||||
application.setApplicationName("nymea-networkmanager");
|
application.setApplicationName("nymea-networkmanager");
|
||||||
application.setOrganizationName("nymea");
|
application.setOrganizationName("nymea");
|
||||||
application.setApplicationVersion("0.3.2");
|
application.setApplicationVersion(VERSION_STRING);
|
||||||
|
|
||||||
// Command line parser
|
// Command line parser
|
||||||
QCommandLineParser parser;
|
QCommandLineParser parser;
|
||||||
parser.addHelpOption();
|
parser.addHelpOption();
|
||||||
parser.addVersionOption();
|
parser.addVersionOption();
|
||||||
parser.setApplicationDescription(QString("\nThis daemon allows to configure a wifi network using a bluetooth low energy connection." \
|
parser.setApplicationDescription(QString("\nThis daemon allows to configure a wifi network using a bluetooth low energy connection.\n\n"
|
||||||
"\n\nCopyright %1 2018 Simon Stürz <simon.stuerz@guh.io>").arg(QChar(0xA9)));
|
"Copyright %1 2018-2019 Simon Stürz <simon.stuerz@nymea.io>\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.");
|
QCommandLineOption debugOption(QStringList() << "d" << "debug", "Enable more debug output.");
|
||||||
parser.addOption(debugOption);
|
parser.addOption(debugOption);
|
||||||
@ -110,28 +120,29 @@ int main(int argc, char *argv[])
|
|||||||
platformNameOption.setDefaultValue(platformName);
|
platformNameOption.setDefaultValue(platformName);
|
||||||
parser.addOption(platformNameOption);
|
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");
|
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));
|
timeoutOption.setDefaultValue(QString::number(timeout));
|
||||||
parser.addOption(timeoutOption);
|
parser.addOption(timeoutOption);
|
||||||
|
|
||||||
QCommandLineOption modeOption(QStringList() << "m" << "mode", "Run the daemon in a specific mode. Default is \"offline\".\n\n" \
|
QCommandLineOption modeOption(QStringList() << "m" << "mode", "Run the daemon in a specific mode (offline, once, always, button, start). Default is \"offline\".", "MODE");
|
||||||
"- 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");
|
|
||||||
parser.addOption(modeOption);
|
parser.addOption(modeOption);
|
||||||
|
|
||||||
parser.process(application);
|
parser.process(application);
|
||||||
|
|
||||||
// Enable debug categories
|
// Enable debug categories
|
||||||
s_loggingFilters.insert("Application", true);
|
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("NymeaService", parser.isSet(debugOption));
|
||||||
|
s_loggingFilters.insert("NetworkManager", parser.isSet(debugOption) );
|
||||||
|
s_loggingFilters.insert("NetworkManagerBluetoothServer", parser.isSet(debugOption));
|
||||||
|
|
||||||
QLoggingCategory::installFilter(loggingCategoryFilter);
|
QLoggingCategory::installFilter(loggingCategoryFilter);
|
||||||
|
|
||||||
bool timeoutValueOk = true;
|
bool timeoutValueOk = true;
|
||||||
|
bool gpioValueOk = true;
|
||||||
|
|
||||||
// Now read the cofig file, overriding defaults
|
// Now read the cofig file, overriding defaults
|
||||||
QStringList configLocations;
|
QStringList configLocations;
|
||||||
@ -152,10 +163,15 @@ int main(int argc, char *argv[])
|
|||||||
mode = Core::ModeStart;
|
mode = Core::ModeStart;
|
||||||
} else if (settings.value("Mode").toString().toLower() == "once") {
|
} else if (settings.value("Mode").toString().toLower() == "once") {
|
||||||
mode = Core::ModeOnce;
|
mode = Core::ModeOnce;
|
||||||
|
} else if (settings.value("Mode").toString().toLower() == "button") {
|
||||||
|
mode = Core::ModeButton;
|
||||||
} else {
|
} else {
|
||||||
qCWarning(dcApplication()).noquote() << QString("The config file's mode \"%1\" does not match the allowed modes.").arg(settings.value("Mode").toString());
|
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")) {
|
if (settings.contains("Timeout")) {
|
||||||
timeout = settings.value("Timeout").toInt(&timeoutValueOk);
|
timeout = settings.value("Timeout").toInt(&timeoutValueOk);
|
||||||
}
|
}
|
||||||
@ -179,7 +195,10 @@ int main(int argc, char *argv[])
|
|||||||
mode = Core::ModeStart;
|
mode = Core::ModeStart;
|
||||||
} else if (parser.value(modeOption).toLower() == "once") {
|
} else if (parser.value(modeOption).toLower() == "once") {
|
||||||
mode = Core::ModeOnce;
|
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));
|
qCWarning(dcApplication()).noquote() << QString("The given mode \"%1\" does not match the allowed modes.").arg(parser.value(modeOption));
|
||||||
parser.showHelp(1);
|
parser.showHelp(1);
|
||||||
}
|
}
|
||||||
@ -193,15 +212,27 @@ int main(int argc, char *argv[])
|
|||||||
if (parser.isSet(timeoutOption)) {
|
if (parser.isSet(timeoutOption)) {
|
||||||
timeout = parser.value(timeoutOption).toInt(&timeoutValueOk);
|
timeout = parser.value(timeoutOption).toInt(&timeoutValueOk);
|
||||||
}
|
}
|
||||||
|
if (parser.isSet(gpioOption)) {
|
||||||
|
buttonGpio = parser.value(gpioOption).toInt(&gpioValueOk);
|
||||||
|
}
|
||||||
|
|
||||||
// All parsed. Validate input:
|
// All parsed. Validate input:
|
||||||
if (!timeoutValueOk) {
|
if (!timeoutValueOk) {
|
||||||
qCCritical(dcApplication()) << QString("Invalid timeout value passed: \"%1\". Please pass an integer >= 10").arg(parser.value(timeoutOption));
|
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) {
|
if (timeout < 10) {
|
||||||
qCCritical(dcApplication()) << QString("Invalid timeout value passed: \"%1\". The minimal timeout is 10 [s].").arg(parser.value(timeoutOption));
|
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()) << "=====================================";
|
qCDebug(dcApplication()) << "=====================================";
|
||||||
@ -211,12 +242,15 @@ int main(int argc, char *argv[])
|
|||||||
qCDebug(dcApplication()) << "Platform name:" << platformName;
|
qCDebug(dcApplication()) << "Platform name:" << platformName;
|
||||||
qCDebug(dcApplication()) << "Mode:" << mode;
|
qCDebug(dcApplication()) << "Mode:" << mode;
|
||||||
qCDebug(dcApplication()) << "Timeout:" << timeout;
|
qCDebug(dcApplication()) << "Timeout:" << timeout;
|
||||||
|
if (mode == Core::ModeButton)
|
||||||
|
qCDebug(dcApplication()) << "Button GPIO:" << buttonGpio;
|
||||||
|
|
||||||
// Start core
|
// Start core
|
||||||
Core::instance()->setMode(mode);
|
Core::instance()->setMode(mode);
|
||||||
Core::instance()->setAdvertisingTimeout(timeout);
|
Core::instance()->setAdvertisingTimeout(timeout);
|
||||||
Core::instance()->setAdvertiseName(advertiseName);
|
Core::instance()->setAdvertiseName(advertiseName);
|
||||||
Core::instance()->setPlatformName(platformName);
|
Core::instance()->setPlatformName(platformName);
|
||||||
|
Core::instance()->setButtonGpio(buttonGpio);
|
||||||
|
|
||||||
Core::instance()->run();
|
Core::instance()->run();
|
||||||
|
|
||||||
|
|||||||
@ -9,7 +9,7 @@ CONFIG += console link_pkgconfig
|
|||||||
CONFIG -= app_bundle
|
CONFIG -= app_bundle
|
||||||
|
|
||||||
TEMPLATE = app
|
TEMPLATE = app
|
||||||
PKGCONFIG += nymea-networkmanager
|
PKGCONFIG += nymea-networkmanager nymea-gpio
|
||||||
|
|
||||||
HEADERS += \
|
HEADERS += \
|
||||||
application.h \
|
application.h \
|
||||||
@ -17,10 +17,7 @@ HEADERS += \
|
|||||||
loggingcategories.h \
|
loggingcategories.h \
|
||||||
nymeadservice.h \
|
nymeadservice.h \
|
||||||
pushbuttonagent.h \
|
pushbuttonagent.h \
|
||||||
bluetooth/bluetoothserver.h \
|
|
||||||
bluetooth/networkservice.h \
|
|
||||||
bluetooth/bluetoothuuids.h \
|
|
||||||
bluetooth/wirelessservice.h \
|
|
||||||
|
|
||||||
SOURCES += \
|
SOURCES += \
|
||||||
main.cpp \
|
main.cpp \
|
||||||
@ -29,9 +26,6 @@ SOURCES += \
|
|||||||
loggingcategories.cpp \
|
loggingcategories.cpp \
|
||||||
nymeadservice.cpp \
|
nymeadservice.cpp \
|
||||||
pushbuttonagent.cpp \
|
pushbuttonagent.cpp \
|
||||||
bluetooth/bluetoothserver.cpp \
|
|
||||||
bluetooth/networkservice.cpp \
|
|
||||||
bluetooth/wirelessservice.cpp \
|
|
||||||
|
|
||||||
target.path = /usr/bin
|
target.path = /usr/bin
|
||||||
INSTALLS += target
|
INSTALLS += target
|
||||||
|
|||||||
@ -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
|
bool NymeadService::available() const
|
||||||
{
|
{
|
||||||
return m_available;
|
return m_available;
|
||||||
|
|||||||
@ -13,7 +13,7 @@ class NymeadService : public QObject
|
|||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
explicit NymeadService(bool pushbuttonEnabled, QObject *parent = nullptr);
|
explicit NymeadService(bool pushbuttonEnabled, QObject *parent = nullptr);
|
||||||
|
~NymeadService();
|
||||||
bool available() const;
|
bool available() const;
|
||||||
|
|
||||||
void enableBluetooth(const bool &enable);
|
void enableBluetooth(const bool &enable);
|
||||||
|
|||||||
Reference in New Issue
Block a user