From c5f17f726bc968fa7429328caaad7efe3ae1fe31 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20St=C3=BCrz?= Date: Wed, 13 Jun 2018 17:26:50 +0200 Subject: [PATCH] Initial commit --- debian/changelog | 5 + debian/compat | 1 + debian/control | 38 ++ debian/copyright | 11 + debian/libnymea-networkmanager-dev.dirs.in | 2 + debian/libnymea-networkmanager-dev.install.in | 3 + debian/libnymea-networkmanager.install.in | 3 + debian/rules | 22 + debian/source/format | 1 + libnymea-networkmanager.pro | 2 + .../libnymea-networkmanager.pro | 39 ++ libnymea-networkmanager/networkconnection.cpp | 125 +++++ libnymea-networkmanager/networkconnection.h | 65 +++ libnymea-networkmanager/networkdevice.cpp | 336 ++++++++++++ libnymea-networkmanager/networkdevice.h | 219 ++++++++ libnymea-networkmanager/networkmanager.cpp | 515 ++++++++++++++++++ libnymea-networkmanager/networkmanager.h | 173 ++++++ .../networkmanagerutils.cpp | 71 +++ libnymea-networkmanager/networkmanagerutils.h | 51 ++ libnymea-networkmanager/networksettings.cpp | 106 ++++ libnymea-networkmanager/networksettings.h | 57 ++ .../wirednetworkdevice.cpp | 97 ++++ libnymea-networkmanager/wirednetworkdevice.h | 58 ++ .../wirelessaccesspoint.cpp | 149 +++++ libnymea-networkmanager/wirelessaccesspoint.h | 92 ++++ .../wirelessnetworkdevice.cpp | 221 ++++++++ .../wirelessnetworkdevice.h | 84 +++ 27 files changed, 2546 insertions(+) create mode 100644 debian/changelog create mode 100644 debian/compat create mode 100644 debian/control create mode 100644 debian/copyright create mode 100644 debian/libnymea-networkmanager-dev.dirs.in create mode 100644 debian/libnymea-networkmanager-dev.install.in create mode 100644 debian/libnymea-networkmanager.install.in create mode 100755 debian/rules create mode 100644 debian/source/format create mode 100644 libnymea-networkmanager.pro create mode 100644 libnymea-networkmanager/libnymea-networkmanager.pro create mode 100644 libnymea-networkmanager/networkconnection.cpp create mode 100644 libnymea-networkmanager/networkconnection.h create mode 100644 libnymea-networkmanager/networkdevice.cpp create mode 100644 libnymea-networkmanager/networkdevice.h create mode 100644 libnymea-networkmanager/networkmanager.cpp create mode 100644 libnymea-networkmanager/networkmanager.h create mode 100644 libnymea-networkmanager/networkmanagerutils.cpp create mode 100644 libnymea-networkmanager/networkmanagerutils.h create mode 100644 libnymea-networkmanager/networksettings.cpp create mode 100644 libnymea-networkmanager/networksettings.h create mode 100644 libnymea-networkmanager/wirednetworkdevice.cpp create mode 100644 libnymea-networkmanager/wirednetworkdevice.h create mode 100644 libnymea-networkmanager/wirelessaccesspoint.cpp create mode 100644 libnymea-networkmanager/wirelessaccesspoint.h create mode 100644 libnymea-networkmanager/wirelessnetworkdevice.cpp create mode 100644 libnymea-networkmanager/wirelessnetworkdevice.h diff --git a/debian/changelog b/debian/changelog new file mode 100644 index 0000000..dcac8f0 --- /dev/null +++ b/debian/changelog @@ -0,0 +1,5 @@ +libnymea-networkmanager (0.1.0) xenial; urgency=medium + + * Initial release. + + -- Simon Stürz Mon, 13 Jun 2018 17:48:40 +0100 diff --git a/debian/compat b/debian/compat new file mode 100644 index 0000000..ec63514 --- /dev/null +++ b/debian/compat @@ -0,0 +1 @@ +9 diff --git a/debian/control b/debian/control new file mode 100644 index 0000000..c1b93ac --- /dev/null +++ b/debian/control @@ -0,0 +1,38 @@ +Source: libnymea-networkmanager +Section: utils +Priority: optional +Maintainer: Simon Stürz +Build-Depends: debhelper (>= 9.0.0), + dpkg-dev (>= 1.16.1~), + dh-systemd, + qt5-default, + qtbase5-dev, + qtbase5-dev-tools, + libqt5bluetooth5, + qtconnectivity5-dev +Standards-Version: 3.9.7 + +Package: libnymea-networkmanager +Section: libs +Architecture: any +Depends: ${misc:Depends}, + libqt5network5 +Description: Qt 5 based library for the network-manager DBus API. + Qt 5 based library for the network-manager DBus API. + +Package: libnymea-networkmanager-dev +Section: libdevel +Architecture: any +Depends: ${misc:Depends}, + libnymea-networkmanager (= ${binary:Version}) +Description: Qt 5 based library for the network-manager DBus API - development files + Development files for Qt 5 based network-manager DBus API. + +Package: libnymea-networkmanager-dbg +Priority: extra +Architecture: any +Section: debug +Depends: ${misc:Depends}, + libnymea-networkmanager (= ${binary:Version}) +Description: Qt 5 based library for the network-manager DBus API - debug symbols + Debug Symbols for Qt 5 based network-manager DBus API. diff --git a/debian/copyright b/debian/copyright new file mode 100644 index 0000000..57a982b --- /dev/null +++ b/debian/copyright @@ -0,0 +1,11 @@ +Format: http://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ +Author: Simon Stürz +Download: https://github.com/guh/nymea-networkmanager + +License: GPL-3+ + On Debian systems, the complete text of the GNU General + Public License can be found in `/usr/share/common-licenses/GPL-3'. + +Files: * +Copyright: (C) 2018 Simon Stürz +License: GPL-3+ diff --git a/debian/libnymea-networkmanager-dev.dirs.in b/debian/libnymea-networkmanager-dev.dirs.in new file mode 100644 index 0000000..a877bf3 --- /dev/null +++ b/debian/libnymea-networkmanager-dev.dirs.in @@ -0,0 +1,2 @@ +usr/lib/@DEB_HOST_MULTIARCH@ +usr/include/nymea-networkmanager diff --git a/debian/libnymea-networkmanager-dev.install.in b/debian/libnymea-networkmanager-dev.install.in new file mode 100644 index 0000000..d11e061 --- /dev/null +++ b/debian/libnymea-networkmanager-dev.install.in @@ -0,0 +1,3 @@ +usr/lib/@DEB_HOST_MULTIARCH@/libnymea-networkmanager.so +usr/include/libnymea-networkmanager/* usr/include/libnymea-networkmanager + diff --git a/debian/libnymea-networkmanager.install.in b/debian/libnymea-networkmanager.install.in new file mode 100644 index 0000000..88eb485 --- /dev/null +++ b/debian/libnymea-networkmanager.install.in @@ -0,0 +1,3 @@ +usr/lib/@DEB_HOST_MULTIARCH@/libnymea-networkmanager.so.1 +usr/lib/@DEB_HOST_MULTIARCH@/libnymea-networkmanager.so.1.0 +usr/lib/@DEB_HOST_MULTIARCH@/libnymea-networkmanager.so.1.0.0 diff --git a/debian/rules b/debian/rules new file mode 100755 index 0000000..494030a --- /dev/null +++ b/debian/rules @@ -0,0 +1,22 @@ +#!/usr/bin/make -f + +export DH_VERBOSE=1 +DEB_HOST_MULTIARCH ?= $(shell dpkg-architecture -qDEB_HOST_MULTIARCH) + +PREPROCESS_FILES := $(wildcard debian/*.in) + +$(PREPROCESS_FILES:.in=): %: %.in + sed 's,/@DEB_HOST_MULTIARCH@,$(DEB_HOST_MULTIARCH:%=/%),g' $< > $@ + +%: + dh $@ --buildsystem=qmake --parallel --with systemd + +override_dh_install: $(PREPROCESS_FILES:.in=) + dh_install + +override_dh_strip: + dh_strip --dbg-package=libnymea-networkmanager-dbg + +override_dh_auto_clean: + dh_auto_clean + rm -rf $(PREPROCESS_FILES:.in=) diff --git a/debian/source/format b/debian/source/format new file mode 100644 index 0000000..89ae9db --- /dev/null +++ b/debian/source/format @@ -0,0 +1 @@ +3.0 (native) diff --git a/libnymea-networkmanager.pro b/libnymea-networkmanager.pro new file mode 100644 index 0000000..e013ac2 --- /dev/null +++ b/libnymea-networkmanager.pro @@ -0,0 +1,2 @@ +TEMPLATE = subdirs +SUBDIRS += libnymea-networkmanager diff --git a/libnymea-networkmanager/libnymea-networkmanager.pro b/libnymea-networkmanager/libnymea-networkmanager.pro new file mode 100644 index 0000000..c83a4d0 --- /dev/null +++ b/libnymea-networkmanager/libnymea-networkmanager.pro @@ -0,0 +1,39 @@ +TARGET = nymea-networkmanager +TEMPLATE = lib + +target.path = /usr/lib/$$system('dpkg-architecture -q DEB_HOST_MULTIARCH') +INSTALLS += target + +QT += dbus network + +QMAKE_CXXFLAGS *= -Werror -std=c++1z -g +QMAKE_LFLAGS *= -std=c++1z + +HEADERS += \ + networkmanager.h \ + networkconnection.h \ + networkdevice.h \ + networksettings.h \ + wirednetworkdevice.h \ + wirelessaccesspoint.h \ + wirelessnetworkdevice.h \ + networkmanagerutils.h \ + +SOURCES += \ + networkmanager.cpp \ + networkconnection.cpp \ + networkdevice.cpp \ + networksettings.cpp \ + wirednetworkdevice.cpp \ + wirelessaccesspoint.cpp \ + wirelessnetworkdevice.cpp \ + networkmanagerutils.cpp \ + + +# install header file with relative subdirectory +for(header, HEADERS) { + path = /usr/include/libnymea-networkmanager/$${dirname(header)} + eval(headers_$${path}.files += $${header}) + eval(headers_$${path}.path = $${path}) + eval(INSTALLS *= headers_$${path}) +} diff --git a/libnymea-networkmanager/networkconnection.cpp b/libnymea-networkmanager/networkconnection.cpp new file mode 100644 index 0000000..31244ea --- /dev/null +++ b/libnymea-networkmanager/networkconnection.cpp @@ -0,0 +1,125 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * * + * Copyright (C) 2018 Simon Stürz * + * * + * This file is part of libnymea-networkmanager. * + * * + * libnymea-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. * + * * + * libnymea-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 libnymea-networkmanager. If not, see . * + * * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +#include "networkconnection.h" +#include "networkmanagerutils.h" + +#include +#include + +/*! Constructs a new \l{NetworkConnection} with the given dbus \a objectPath and \a parent. */ +NetworkConnection::NetworkConnection(const QDBusObjectPath &objectPath, QObject *parent) : + QObject(parent), + m_objectPath(objectPath) +{ + qDBusRegisterMetaType(); + + m_connectionInterface = new QDBusInterface(NetworkManagerUtils::networkManagerServiceString(), m_objectPath.path(), NetworkManagerUtils::connectionsInterfaceString(), QDBusConnection::systemBus(), this); + if(!m_connectionInterface->isValid()) { + qCWarning(dcNetworkManager()) << "Invalid connection dbus interface"; + return; + } + + QDBusMessage query = m_connectionInterface->call("GetSettings"); + if(query.type() != QDBusMessage::ReplyMessage) { + qCWarning(dcNetworkManager()) << query.errorName() << query.errorMessage(); + return; + } + + if (query.arguments().isEmpty()) + return; + + const QDBusArgument &argument = query.arguments().at(0).value(); + m_connectionSettings = qdbus_cast(argument); +} + +/*! Delete this \l{NetworkConnection} in the \l{NetworkManager}. */ +void NetworkConnection::deleteConnection() +{ + QDBusMessage query = m_connectionInterface->call("Delete"); + if(query.type() != QDBusMessage::ReplyMessage) + qCWarning(dcNetworkManager()) << query.errorName() << query.errorMessage(); + +} + +/*! Returns the dbus object path of this \l{NetworkConnection}. */ +QDBusObjectPath NetworkConnection::objectPath() const +{ + return m_objectPath; +} + +/*! Returns the connection settings of this \l{NetworkConnection}. */ +ConnectionSettings NetworkConnection::connectionSettings() const +{ + return m_connectionSettings; +} + +/*! Returns the id of this \l{NetworkConnection}. */ +QString NetworkConnection::id() const +{ + return m_connectionSettings.value("connection").value("id").toString(); +} + +/*! Returns the name of this \l{NetworkConnection}. */ +QString NetworkConnection::name() const +{ + return m_connectionSettings.value("connection").value("name").toString(); +} + +/*! Returns the type of this \l{NetworkConnection}. */ +QString NetworkConnection::type() const +{ + return m_connectionSettings.value("connection").value("type").toString(); +} + +/*! Returns the uuid of this \l{NetworkConnection}. */ +QUuid NetworkConnection::uuid() const +{ + return m_connectionSettings.value("connection").value("uuid").toUuid(); +} + +/*! Returns the interface name of this \l{NetworkConnection}. */ +QString NetworkConnection::interfaceName() const +{ + return m_connectionSettings.value("connection").value("interface-name").toString(); +} + +/*! Returns true if this \l{NetworkConnection} will autoconnect if available. */ +bool NetworkConnection::autoconnect() const +{ + return m_connectionSettings.value("connection").value("autoconnect").toBool(); +} + +/*! Returns the timestamp of this \l{NetworkConnection} from the last connection. */ +QDateTime NetworkConnection::timeStamp() const +{ + return QDateTime::fromTime_t(m_connectionSettings.value("connection").value("timestamp").toUInt()); +} + +QDebug operator<<(QDebug debug, NetworkConnection *networkConnection) +{ + debug.nospace() << "NetworkConnection(" << networkConnection->id() << ", "; + debug.nospace() << networkConnection->uuid().toString() << ", "; + debug.nospace() << networkConnection->interfaceName() << ", "; + debug.nospace() << networkConnection->type() << ", "; + debug.nospace() << networkConnection->timeStamp().toString("dd.MM.yyyy hh:mm") << ") "; + return debug; +} diff --git a/libnymea-networkmanager/networkconnection.h b/libnymea-networkmanager/networkconnection.h new file mode 100644 index 0000000..70506f0 --- /dev/null +++ b/libnymea-networkmanager/networkconnection.h @@ -0,0 +1,65 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * * + * Copyright (C) 2018 Simon Stürz * + * * + * This file is part of libnymea-networkmanager. * + * * + * libnymea-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. * + * * + * libnymea-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 libnymea-networkmanager. If not, see . * + * * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +#ifndef NETWORKCONNECTION_H +#define NETWORKCONNECTION_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +typedef QMap ConnectionSettings; + +class NetworkConnection : public QObject +{ + Q_OBJECT +public: + explicit NetworkConnection(const QDBusObjectPath &objectPath, QObject *parent = 0); + + void deleteConnection(); + + QDBusObjectPath objectPath() const; + ConnectionSettings connectionSettings() const; + + QString id() const; + QString name() const; + QString type() const; + QUuid uuid() const; + QString interfaceName() const; + bool autoconnect() const; + QDateTime timeStamp() const; + +private: + QDBusObjectPath m_objectPath; + QDBusInterface *m_connectionInterface = nullptr; + + ConnectionSettings m_connectionSettings; +}; + +QDebug operator<<(QDebug debug, NetworkConnection *networkConnection); + +#endif // NETWORKCONNECTION_H diff --git a/libnymea-networkmanager/networkdevice.cpp b/libnymea-networkmanager/networkdevice.cpp new file mode 100644 index 0000000..4bf6931 --- /dev/null +++ b/libnymea-networkmanager/networkdevice.cpp @@ -0,0 +1,336 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * * + * Copyright (C) 2018 Simon Stürz * + * * + * This file is part of libnymea-networkmanager. * + * * + * libnymea-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. * + * * + * libnymea-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 libnymea-networkmanager. If not, see . * + * * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +/*! \enum guhserver::NetworkDevice::NetworkDeviceState + \value NetworkDeviceStateUnknown + \value NetworkDeviceStateUnmanaged + \value NetworkDeviceStateUnavailable + \value NetworkDeviceStateDisconnected + \value NetworkDeviceStatePrepare + \value NetworkDeviceStateConfig + \value NetworkDeviceStateNeedAuth + \value NetworkDeviceStateIpConfig + \value NetworkDeviceStateIpCheck + \value NetworkDeviceStateSecondaries + \value NetworkDeviceStateActivated + \value NetworkDeviceStateDeactivating + \value NetworkDeviceStateFailed +*/ + +/*! \enum guhserver::NetworkDevice::NetworkDeviceStateReason + \value NetworkDeviceStateReasonNone + \value NetworkDeviceStateReasonUnknown + \value NetworkDeviceStateReasonNowManaged + \value NetworkDeviceStateReasonNowUnmanaged + \value NetworkDeviceStateReasonConfigFailed + \value NetworkDeviceStateReasonIpConfigUnavailable + \value NetworkDeviceStateReasonIpConfigExpired + \value NetworkDeviceStateReasonNoSecrets + \value NetworkDeviceStateReasonSupplicantDisconnected + \value NetworkDeviceStateReasonSupplicantConfigFailed + \value NetworkDeviceStateReasonSupplicantFailed + \value NetworkDeviceStateReasonSupplicantTimeout + \value NetworkDeviceStateReasonPppStartFailed + \value NetworkDeviceStateReasonPppDisconnected + \value NetworkDeviceStateReasonPppFailed + \value NetworkDeviceStateReasonDhcpStartFailed + \value NetworkDeviceStateReasonDhcpError + \value NetworkDeviceStateReasonDhcpFailed + \value NetworkDeviceStateReasonSharedStartFailed + \value NetworkDeviceStateReasonSharedFailed + \value NetworkDeviceStateReasonAutoIpStartFailed + \value NetworkDeviceStateReasonAutoIpError + \value NetworkDeviceStateReasonAutoIpFailed + \value NetworkDeviceStateReasonModemBusy + \value NetworkDeviceStateReasonModemNoDialTone + \value NetworkDeviceStateReasonModemNoCarrier + \value NetworkDeviceStateReasonModemDialTimeout + \value NetworkDeviceStateReasonModemDialFailed + \value NetworkDeviceStateReasonModemInitFailed + \value NetworkDeviceStateReasonGsmApnFailed + \value NetworkDeviceStateReasonGsmRegistrationNotSearching + \value NetworkDeviceStateReasonGsmRegistrationDenied + \value NetworkDeviceStateReasonGsmRegistrationTimeout + \value NetworkDeviceStateReasonGsmRegistrationFailed + \value NetworkDeviceStateReasonGsmPinCheckFailed + \value NetworkDeviceStateReasonFirmwareMissing + \value NetworkDeviceStateReasonRemoved + \value NetworkDeviceStateReasonSleeping + \value NetworkDeviceStateReasonConnectionRemoved + \value NetworkDeviceStateReasonUserRequest + \value NetworkDeviceStateReasonCarrier + \value NetworkDeviceStateReasonConnectionAssumed + \value NetworkDeviceStateReasonSupplicantAvailable + \value NetworkDeviceStateReasonModemNotFound + \value NetworkDeviceStateReasonBtFailed + \value NetworkDeviceStateReasonGsmSimNotInserted + \value NetworkDeviceStateReasonGsmSimPinRequired + \value NetworkDeviceStateReasonGsmSimPukRequired + \value NetworkDeviceStateReasonGsmSimWrong + \value NetworkDeviceStateReasonInfinibandMode + \value NetworkDeviceStateReasonDependencyFailed + \value NetworkDeviceStateReasonBR2684Failed + \value NetworkDeviceStateReasonModemManagerUnavailable + \value NetworkDeviceStateReasonSsidNotFound + \value NetworkDeviceStateReasonSecondaryConnectionFailed + \value NetworkDeviceStateReasonDcbFoecFailed + \value NetworkDeviceStateReasonTeamdControlFailed + \value NetworkDeviceStateReasonModemFailed + \value NetworkDeviceStateReasonModemAvailable + \value NetworkDeviceStateReasonSimPinIncorrect + \value NetworkDeviceStateReasonNewActivision + \value NetworkDeviceStateReasonParentChanged + \value NetworkDeviceStateReasonParentManagedChanged +*/ + + +/*! \enum guhserver::NetworkDevice::NetworkDeviceType + \value NetworkDeviceTypeUnknown + \value NetworkDeviceTypeEthernet + \value NetworkDeviceTypeWifi + \value NetworkDeviceTypeBluetooth + \value NetworkDeviceTypeOlpcMesh + \value NetworkDeviceTypeWiMax + \value NetworkDeviceTypeModem + \value NetworkDeviceTypeInfiniBand + \value NetworkDeviceTypeBond + \value NetworkDeviceTypeVLan + \value NetworkDeviceTypeAdsl + \value NetworkDeviceTypeBridge + \value NetworkDeviceTypeGeneric + \value NetworkDeviceTypeTeam + \value NetworkDeviceTypeTun + \value NetworkDeviceTypeIpTunnel + \value NetworkDeviceTypeMacVLan + \value NetworkDeviceTypeVXLan + \value NetworkDeviceTypeVEth +*/ + + +/*! \fn void NetworkDevice::deviceChanged(); + This signal will be emitted when the properties of this \l{NetworkDevice} have changed. +*/ + + +#include "networkdevice.h" + +#include +#include + +/*! Constructs a new \l{NetworkDevice} with the given dbus \a objectPath and \a parent. */ +NetworkDevice::NetworkDevice(const QDBusObjectPath &objectPath, QObject *parent) : + QObject(parent), + m_objectPath(objectPath) +{ + QDBusConnection systemBus = QDBusConnection::systemBus(); + if (!systemBus.isConnected()) { + qCWarning(dcNetworkManager()) << "NetworkDevice: System DBus not connected"; + return; + } + + m_networkDeviceInterface = new QDBusInterface(NetworkManagerUtils::networkManagerServiceString(), m_objectPath.path(), NetworkManagerUtils::deviceInterfaceString(), QDBusConnection::systemBus(), this); + if(!m_networkDeviceInterface->isValid()) { + qCWarning(dcNetworkManager()) << "NetworkDevice: Invalid DBus device interface" << m_objectPath.path(); + return; + } + + m_udi = m_networkDeviceInterface->property("Udi").toString(); + m_interface = m_networkDeviceInterface->property("Interface").toString(); + m_ipInterface = m_networkDeviceInterface->property("IpInterface").toString(); + m_driver = m_networkDeviceInterface->property("Driver").toString(); + m_driverVersion = m_networkDeviceInterface->property("DriverVersion").toString(); + m_firmwareVersion = m_networkDeviceInterface->property("FirmwareVersion").toString(); + m_physicalPortId = m_networkDeviceInterface->property("PhysicalPortId").toString(); + m_mtu = m_networkDeviceInterface->property("Mtu").toUInt(); + m_metered = m_networkDeviceInterface->property("Metered").toUInt(); + m_autoconnect = m_networkDeviceInterface->property("Autoconnect").toBool(); + + m_deviceState = NetworkDeviceState(m_networkDeviceInterface->property("State").toUInt()); + m_deviceType = NetworkDeviceType(m_networkDeviceInterface->property("DeviceType").toUInt()); + + m_activeConnection = qdbus_cast(m_networkDeviceInterface->property("ActiveConnection")); + m_ip4Config = qdbus_cast(m_networkDeviceInterface->property("Ip4Config")); + m_ip6Config = qdbus_cast(m_networkDeviceInterface->property("Ip6Config")); + + QDBusConnection::systemBus().connect(NetworkManagerUtils::networkManagerServiceString(), m_objectPath.path(), NetworkManagerUtils::deviceInterfaceString(), "StateChanged", this, SLOT(onStateChanged(uint,uint,uint))); +} + +/*! Returns the dbus object path of this \l{NetworkDevice}. */ +QDBusObjectPath NetworkDevice::objectPath() const +{ + return m_objectPath; +} + +/*! Returns the udi of this \l{NetworkDevice}. */ +QString NetworkDevice::udi() const +{ + return m_udi; +} + +/*! Returns the interface name of this \l{NetworkDevice}. */ +QString NetworkDevice::interface() const +{ + return m_interface; +} + +/*! Returns the ip interface of this \l{NetworkDevice}. */ +QString NetworkDevice::ipInterface() const +{ + return m_ipInterface; +} + +/*! Returns the used driver name for this \l{NetworkDevice}. */ +QString NetworkDevice::driver() const +{ + return m_driver; +} + +/*! Returns the version of the used driver for this \l{NetworkDevice}. */ +QString NetworkDevice::driverVersion() const +{ + return m_driverVersion; +} + +/*! Returns the firmware version of this \l{NetworkDevice}. */ +QString NetworkDevice::firmwareVersion() const +{ + return m_firmwareVersion; +} + +/*! Returns the physical port id of this \l{NetworkDevice}. */ +QString NetworkDevice::physicalPortId() const +{ + return m_physicalPortId; +} + +/*! Returns the mtu of this \l{NetworkDevice}. */ +uint NetworkDevice::mtu() const +{ + return m_mtu; +} + +/*! Returns the metered property of this \l{NetworkDevice}. */ +uint NetworkDevice::metered() const +{ + return m_metered; +} + +/*! Returns true if autoconnect is enabled for this \l{NetworkDevice}. */ +bool NetworkDevice::autoconnect() const +{ + return m_autoconnect; +} + +/*! Returns the device state of this \l{NetworkDevice}. \sa NetworkDeviceState, */ +NetworkDevice::NetworkDeviceState NetworkDevice::deviceState() const +{ + return m_deviceState; +} + +/*! Returns the human readable device state of this \l{NetworkDevice}. \sa NetworkDeviceState, */ +QString NetworkDevice::deviceStateString() const +{ + return NetworkDevice::deviceStateToString(m_deviceState); +} + +/*! Returns the reason for the current state of this \l{NetworkDevice}. \sa NetworkDeviceStateReason, */ +NetworkDevice::NetworkDeviceStateReason NetworkDevice::deviceStateReason() const +{ + return m_deviceStateReason; +} + +/*! Returns the device type of this \l{NetworkDevice}. \sa NetworkDeviceType, */ +NetworkDevice::NetworkDeviceType NetworkDevice::deviceType() const +{ + return m_deviceType; +} + +/*! Returns the dbus object path of the currently active connection of this \l{NetworkDevice}. */ +QDBusObjectPath NetworkDevice::activeConnection() const +{ + return m_activeConnection; +} + +/*! Returns the dbus object path from the IPv4 configuration of this \l{NetworkDevice}. */ +QDBusObjectPath NetworkDevice::ip4Config() const +{ + return m_ip4Config; +} + +/*! Returns the list of dbus object paths for the currently available connection of this \l{NetworkDevice}. */ +QList NetworkDevice::availableConnections() const +{ + return m_availableConnections; +} + +/*! Disconnect the current connection from this \l{NetworkDevice}. */ +void NetworkDevice::disconnectDevice() +{ + QDBusMessage query = m_networkDeviceInterface->call("Disconnect"); + if(query.type() != QDBusMessage::ReplyMessage) + qCWarning(dcNetworkManager()) << query.errorName() << query.errorMessage(); + +} + +/*! Returns the human readable device type string of the given \a deviceType. \sa NetworkDeviceType, */ +QString NetworkDevice::deviceTypeToString(const NetworkDevice::NetworkDeviceType &deviceType) +{ + QMetaObject metaObject = NetworkDevice::staticMetaObject; + int enumIndex = metaObject.indexOfEnumerator(QString("NetworkDeviceType").toLatin1().data()); + QMetaEnum metaEnum = metaObject.enumerator(enumIndex); + return QString(metaEnum.valueToKey(deviceType)).remove("NetworkDeviceType"); +} + +/*! Returns the human readable device state string of the given \a deviceState. \sa NetworkDeviceState, */ +QString NetworkDevice::deviceStateToString(const NetworkDevice::NetworkDeviceState &deviceState) +{ + QMetaObject metaObject = NetworkDevice::staticMetaObject; + int enumIndex = metaObject.indexOfEnumerator(QString("NetworkDeviceState").toLatin1().data()); + QMetaEnum metaEnum = metaObject.enumerator(enumIndex); + return QString(metaEnum.valueToKey(deviceState)); +} + +/*! Returns the human readable device state reason string of the given \a deviceStateReason. \sa NetworkDeviceStateReason, */ +QString NetworkDevice::deviceStateReasonToString(const NetworkDevice::NetworkDeviceStateReason &deviceStateReason) +{ + QMetaObject metaObject = NetworkDevice::staticMetaObject; + int enumIndex = metaObject.indexOfEnumerator(QString("NetworkDeviceStateReason").toLatin1().data()); + QMetaEnum metaEnum = metaObject.enumerator(enumIndex); + return QString(metaEnum.valueToKey(deviceStateReason)); +} + +void NetworkDevice::onStateChanged(uint newState, uint oldState, uint reason) +{ + Q_UNUSED(oldState); + qCDebug(dcNetworkManager()) << m_interface << "--> State changed:" << deviceStateToString(NetworkDeviceState(newState)) << ":" << deviceStateReasonToString(NetworkDeviceStateReason(reason)); + if (m_deviceState != NetworkDeviceState(newState)) { + m_deviceState = NetworkDeviceState(newState); + emit deviceChanged(); + emit stateChanged(m_deviceState); + } +} + +QDebug operator<<(QDebug debug, NetworkDevice *device) +{ + debug.nospace() << "NetworkDevice(" << device->interface() << " - " << NetworkDevice::deviceTypeToString(device->deviceType()) << ", " << device->deviceStateString() << ")"; + return debug; +} + diff --git a/libnymea-networkmanager/networkdevice.h b/libnymea-networkmanager/networkdevice.h new file mode 100644 index 0000000..222f069 --- /dev/null +++ b/libnymea-networkmanager/networkdevice.h @@ -0,0 +1,219 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * * + * Copyright (C) 2018 Simon Stürz * + * * + * This file is part of libnymea-networkmanager. * + * * + * libnymea-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. * + * * + * libnymea-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 libnymea-networkmanager. If not, see . * + * * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +#ifndef NETWORKDEVICE_H +#define NETWORKDEVICE_H + +#include +#include +#include +#include +#include +#include +#include + +#include "networkmanagerutils.h" + +class NetworkDevice : public QObject +{ + Q_OBJECT + Q_ENUMS(NetworkDeviceType) + Q_ENUMS(NetworkDeviceState) + Q_ENUMS(NetworkDeviceStateReason) + +public: + enum NetworkDeviceState { + NetworkDeviceStateUnknown = 0, + NetworkDeviceStateUnmanaged = 10, + NetworkDeviceStateUnavailable = 20, + NetworkDeviceStateDisconnected = 30, + NetworkDeviceStatePrepare = 40, + NetworkDeviceStateConfig = 50, + NetworkDeviceStateNeedAuth = 60, + NetworkDeviceStateIpConfig = 70, + NetworkDeviceStateIpCheck = 80, + NetworkDeviceStateSecondaries = 90, + NetworkDeviceStateActivated = 100, + NetworkDeviceStateDeactivating = 110, + NetworkDeviceStateFailed = 120 + }; + Q_ENUM(NetworkDeviceState) + + enum NetworkDeviceStateReason { + NetworkDeviceStateReasonNone = 0, + NetworkDeviceStateReasonUnknown = 1, + NetworkDeviceStateReasonNowManaged = 2, + NetworkDeviceStateReasonNowUnmanaged = 3, + NetworkDeviceStateReasonConfigFailed = 4, + NetworkDeviceStateReasonIpConfigUnavailable = 5, + NetworkDeviceStateReasonIpConfigExpired = 6, + NetworkDeviceStateReasonNoSecrets = 7, + NetworkDeviceStateReasonSupplicantDisconnected = 8, + NetworkDeviceStateReasonSupplicantConfigFailed = 9, + NetworkDeviceStateReasonSupplicantFailed = 10, + NetworkDeviceStateReasonSupplicantTimeout = 11, + NetworkDeviceStateReasonPppStartFailed = 12, + NetworkDeviceStateReasonPppDisconnected = 13, + NetworkDeviceStateReasonPppFailed = 14, + NetworkDeviceStateReasonDhcpStartFailed = 15, + NetworkDeviceStateReasonDhcpError = 16, + NetworkDeviceStateReasonDhcpFailed = 17, + NetworkDeviceStateReasonSharedStartFailed = 18, + NetworkDeviceStateReasonSharedFailed = 19, + NetworkDeviceStateReasonAutoIpStartFailed = 20, + NetworkDeviceStateReasonAutoIpError = 21, + NetworkDeviceStateReasonAutoIpFailed = 22, + NetworkDeviceStateReasonModemBusy = 23, + NetworkDeviceStateReasonModemNoDialTone = 24, + NetworkDeviceStateReasonModemNoCarrier = 25, + NetworkDeviceStateReasonModemDialTimeout = 26, + NetworkDeviceStateReasonModemDialFailed = 27, + NetworkDeviceStateReasonModemInitFailed = 28, + NetworkDeviceStateReasonGsmApnFailed = 29, + NetworkDeviceStateReasonGsmRegistrationNotSearching = 30, + NetworkDeviceStateReasonGsmRegistrationDenied = 31, + NetworkDeviceStateReasonGsmRegistrationTimeout = 32, + NetworkDeviceStateReasonGsmRegistrationFailed = 33, + NetworkDeviceStateReasonGsmPinCheckFailed = 34, + NetworkDeviceStateReasonFirmwareMissing = 35, + NetworkDeviceStateReasonRemoved = 36, + NetworkDeviceStateReasonSleeping = 37, + NetworkDeviceStateReasonConnectionRemoved = 38, + NetworkDeviceStateReasonUserRequest = 39, + NetworkDeviceStateReasonCarrier = 40, + NetworkDeviceStateReasonConnectionAssumed = 41, + NetworkDeviceStateReasonSupplicantAvailable = 42, + NetworkDeviceStateReasonModemNotFound = 43, + NetworkDeviceStateReasonBtFailed = 44, + NetworkDeviceStateReasonGsmSimNotInserted = 45, + NetworkDeviceStateReasonGsmSimPinRequired = 46, + NetworkDeviceStateReasonGsmSimPukRequired = 47, + NetworkDeviceStateReasonGsmSimWrong = 48, + NetworkDeviceStateReasonInfinibandMode = 49, + NetworkDeviceStateReasonDependencyFailed = 50, + NetworkDeviceStateReasonBR2684Failed = 51, + NetworkDeviceStateReasonModemManagerUnavailable = 52, + NetworkDeviceStateReasonSsidNotFound = 53, + NetworkDeviceStateReasonSecondaryConnectionFailed = 54, + NetworkDeviceStateReasonDcbFoecFailed = 55, + NetworkDeviceStateReasonTeamdControlFailed = 56, + NetworkDeviceStateReasonModemFailed = 57, + NetworkDeviceStateReasonModemAvailable = 58, + NetworkDeviceStateReasonSimPinIncorrect = 59, + NetworkDeviceStateReasonNewActivision = 60, + NetworkDeviceStateReasonParentChanged = 61, + NetworkDeviceStateReasonParentManagedChanged = 62 + }; + Q_ENUM(NetworkDeviceStateReason) + + enum NetworkDeviceType { + NetworkDeviceTypeUnknown = 0, + NetworkDeviceTypeEthernet = 1, + NetworkDeviceTypeWifi = 2, + NetworkDeviceTypeBluetooth = 5, + NetworkDeviceTypeOlpcMesh = 6, + NetworkDeviceTypeWiMax = 7, + NetworkDeviceTypeModem = 8, + NetworkDeviceTypeInfiniBand = 9, + NetworkDeviceTypeBond = 10, + NetworkDeviceTypeVLan = 11, + NetworkDeviceTypeAdsl = 12, + NetworkDeviceTypeBridge = 13, + NetworkDeviceTypeGeneric = 14, + NetworkDeviceTypeTeam = 15, + NetworkDeviceTypeTun = 16, + NetworkDeviceTypeIpTunnel = 17, + NetworkDeviceTypeMacVLan = 18, + NetworkDeviceTypeVXLan = 19, + NetworkDeviceTypeVEth = 20, + }; + Q_ENUM(NetworkDeviceType) + + explicit NetworkDevice(const QDBusObjectPath &objectPath, QObject *parent = 0); + + QDBusObjectPath objectPath() const; + + QString udi() const; + QString interface() const; + QString ipInterface() const; + QString driver() const; + QString driverVersion() const; + QString firmwareVersion() const; + QString physicalPortId() const; + uint mtu() const; + uint metered() const; + bool autoconnect() const; + + NetworkDeviceState deviceState() const; + QString deviceStateString() const; + + NetworkDeviceStateReason deviceStateReason() const; + NetworkDeviceType deviceType() const; + + QDBusObjectPath activeConnection() const; + QDBusObjectPath ip4Config() const; + QList availableConnections() const; + + // Method + void disconnectDevice(); + + static QString deviceTypeToString(const NetworkDeviceType &deviceType); + static QString deviceStateToString(const NetworkDeviceState &deviceState); + static QString deviceStateReasonToString(const NetworkDeviceStateReason &deviceStateReason); + +private: + QDBusInterface *m_networkDeviceInterface = nullptr; + QDBusObjectPath m_objectPath; + + // Device properties + QString m_udi; + QString m_interface; + QString m_ipInterface; + QString m_driver; + QString m_driverVersion; + QString m_firmwareVersion; + QString m_physicalPortId; + uint m_mtu = 0; + uint m_metered = 0; + bool m_autoconnect = false; + NetworkDeviceState m_deviceState = NetworkDeviceStateUnknown; + NetworkDeviceStateReason m_deviceStateReason = NetworkDeviceStateReasonUnknown; + NetworkDeviceType m_deviceType = NetworkDeviceTypeUnknown; + + QDBusObjectPath m_activeConnection; + QDBusObjectPath m_ip4Config; + QDBusObjectPath m_ip6Config; + + QList m_availableConnections; + +private slots: + void onStateChanged(uint newState, uint oldState, uint reason); + +signals: + void deviceChanged(); + void stateChanged(const NetworkDeviceState &state); + + +}; + +QDebug operator<<(QDebug debug, NetworkDevice *device); + +#endif // NETWORKDEVICE_H diff --git a/libnymea-networkmanager/networkmanager.cpp b/libnymea-networkmanager/networkmanager.cpp new file mode 100644 index 0000000..9a8fcce --- /dev/null +++ b/libnymea-networkmanager/networkmanager.cpp @@ -0,0 +1,515 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * * + * Copyright (C) 2018 Simon Stürz * + * * + * This file is part of libnymea-networkmanager. * + * * + * libnymea-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. * + * * + * libnymea-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 libnymea-networkmanager. If not, see . * + * * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +#include "networkmanager.h" +#include "networkconnection.h" + +#include +#include +#include + +/*! Constructs a new \l{NetworkManager} object with the given \a parent. */ +NetworkManager::NetworkManager(QObject *parent) : + QObject(parent) +{ + +} + +NetworkManager::~NetworkManager() +{ + qCDebug(dcNetworkManager()) << "Destroy network manager."; +} + +/*! Returns true if the network-manager is available on this system. */ +bool NetworkManager::available() const +{ + return m_available; +} + +/*! Returns true if wifi is available on this system. */ +bool NetworkManager::wirelessAvailable() const +{ + return !m_wirelessNetworkDevices.isEmpty(); +} + +/*! Returns the list of \l{NetworkDevice}{NetworkDevices} from this \l{NetworkManager}. */ +QList NetworkManager::networkDevices() const +{ + return m_networkDevices.values(); +} + +QList NetworkManager::wirelessNetworkDevices() const +{ + return m_wirelessNetworkDevices.values(); +} + +/*! Returns the list of \l{WiredNetworkDevice}{WiredNetworkDevices} from this \l{NetworkManager}. */ +QList NetworkManager::wiredNetworkDevices() const +{ + return m_wiredNetworkDevices.values(); +} + +/*! Returns the \l{NetworkDevice} with the given \a interface from this \l{NetworkManager}. If there is no such \a interface returns Q_NULLPTR. */ +NetworkDevice *NetworkManager::getNetworkDevice(const QString &interface) +{ + foreach (NetworkDevice *device, m_networkDevices.values()) { + if (device->interface() == interface) + return device; + } + return nullptr; +} + +/*! Returns the version of the running \l{NetworkManager}. */ +QString NetworkManager::version() const +{ + return m_version; +} + +/*! Returns the state of this \l{NetworkManager}. \sa NetworkManagerState, */ +NetworkManager::NetworkManagerState NetworkManager::state() const +{ + return m_state; +} + +/*! Returns the human readable string of the current state of this \l{NetworkManager}. \sa NetworkManagerState, */ +QString NetworkManager::stateString() const +{ + return networkManagerStateToString(m_state); +} + +/*! Returns the current connectivity state of this \l{NetworkManager}. \sa NetworkManagerConnectivityState, */ +NetworkManager::NetworkManagerConnectivityState NetworkManager::connectivityState() const +{ + return m_connectivityState; +} + +/*! Connect the given \a interface to a wifi network with the given \a ssid and \a password. Returns the \l{NetworkManagerError} to inform about the result. \sa NetworkManagerError, */ +NetworkManager::NetworkManagerError NetworkManager::connectWifi(const QString &interface, const QString &ssid, const QString &password, bool hidden) +{ + // Check interface + if (!getNetworkDevice(interface)) + return NetworkManagerErrorNetworkInterfaceNotFound; + + // Get wirelessNetworkDevice + WirelessNetworkDevice *wirelessNetworkDevice = 0; + foreach (WirelessNetworkDevice *networkDevice, wirelessNetworkDevices()) { + if (networkDevice->interface() == interface) + wirelessNetworkDevice = networkDevice; + } + + if (!wirelessNetworkDevice) + return NetworkManagerErrorInvalidNetworkDeviceType; + + // Get the access point object path + WirelessAccessPoint *accessPoint = wirelessNetworkDevice->getAccessPoint(ssid); + if (!accessPoint) + return NetworkManagerErrorAccessPointNotFound; + + // Note: https://developer.gnome.org/NetworkManager/stable/ref-settings.html + + QVariantMap connectionSettings; + connectionSettings.insert("autoconnect", true); + connectionSettings.insert("id", ssid); + connectionSettings.insert("uuid", QUuid::createUuid().toString().remove("{").remove("}")); + connectionSettings.insert("type", "802-11-wireless"); + + QVariantMap wirelessSettings; + wirelessSettings.insert("ssid", ssid.toUtf8()); + wirelessSettings.insert("mode", "infrastructure"); + + // Note: disable power save mode + wirelessSettings.insert("powersave", 2); + + if (hidden) + wirelessSettings.insert("hidden", true); + + QVariantMap wirelessSecuritySettings; + wirelessSecuritySettings.insert("auth-alg", "open"); + wirelessSecuritySettings.insert("key-mgmt", "wpa-psk"); + wirelessSecuritySettings.insert("psk", password); + + QVariantMap ipv4Settings; + ipv4Settings.insert("method", "auto"); + + QVariantMap ipv6Settings; + ipv6Settings.insert("method", "auto"); + + // Build connection object + ConnectionSettings settings; + settings.insert("connection", connectionSettings); + settings.insert("802-11-wireless", wirelessSettings); + settings.insert("ipv4", ipv4Settings); + settings.insert("ipv6", ipv6Settings); + settings.insert("802-11-wireless-security", wirelessSecuritySettings); + + // Remove old configuration (if there is any) + foreach (NetworkConnection *connection, m_networkSettings->connections()) { + if (connection->id() == connectionSettings.value("id")) { + connection->deleteConnection(); + } + } + + // Add connection + QDBusObjectPath connectionObjectPath = m_networkSettings->addConnection(settings); + if (connectionObjectPath.path().isEmpty()) + return NetworkManagerErrorWirelessConnectionFailed; + + // Activate connection + QDBusMessage query = m_networkManagerInterface->call("ActivateConnection", QVariant::fromValue(connectionObjectPath), QVariant::fromValue(wirelessNetworkDevice->objectPath()), QVariant::fromValue(accessPoint->objectPath())); + if(query.type() != QDBusMessage::ReplyMessage) { + qCWarning(dcNetworkManager()) << query.errorName() << query.errorMessage(); + return NetworkManagerErrorWirelessConnectionFailed; + } + + return NetworkManagerErrorNoError; +} + +/*! Returns true if the networking of this \l{NetworkManager} is enabled. */ +bool NetworkManager::networkingEnabled() const +{ + return m_networkingEnabled; +} + +/*! Returns true if the networking of this \l{NetworkManager} could be \a enabled. */ +bool NetworkManager::enableNetworking(bool enabled) +{ + if (m_networkingEnabled == enabled) + return true; + + QDBusMessage query = m_networkManagerInterface->call("Enable", enabled); + if(query.type() != QDBusMessage::ReplyMessage) { + qCWarning(dcNetworkManager()) << query.errorName() << query.errorMessage(); + return false; + } + return true; +} + +/*! Sets the networking of this \l{NetworkManager} to \a enabled. */ +void NetworkManager::setNetworkingEnabled(bool enabled) +{ + if (m_networkingEnabled == enabled) + return; + + qCDebug(dcNetworkManager()) << "Networking" << (enabled ? "enabled" : "disabled"); + + m_networkingEnabled = enabled; + emit networkingEnabledChanged(m_networkingEnabled); +} + +/*! Returns true if the wireless networking of this \l{NetworkManager} is enabled. */ +bool NetworkManager::wirelessEnabled() const +{ + return m_wirelessEnabled; +} + +/*! Returns true if the wireless networking of this \l{NetworkManager} could be set to \a enabled. */ +bool NetworkManager::enableWireless(bool enabled) +{ + if (m_wirelessEnabled == enabled) + return true; + + return m_networkManagerInterface->setProperty("WirelessEnabled", enabled); +} + +void NetworkManager::loadDevices() +{ + // Get network devices + QDBusMessage query = m_networkManagerInterface->call("GetDevices"); + if(query.type() != QDBusMessage::ReplyMessage) { + qCWarning(dcNetworkManager()) << query.errorName() << query.errorMessage(); + return; + } + + if (query.arguments().isEmpty()) + return; + + const QDBusArgument &argument = query.arguments().at(0).value(); + argument.beginArray(); + while(!argument.atEnd()) { + QDBusObjectPath deviceObjectPath = qdbus_cast(argument); + onDeviceAdded(deviceObjectPath); + } + argument.endArray(); +} + +QString NetworkManager::networkManagerStateToString(const NetworkManager::NetworkManagerState &state) +{ + QMetaObject metaObject = NetworkManager::staticMetaObject; + int enumIndex = metaObject.indexOfEnumerator(QString("NetworkManagerState").toLatin1().data()); + QMetaEnum metaEnum = metaObject.enumerator(enumIndex); + return QString(metaEnum.valueToKey(state)); +} + +QString NetworkManager::networkManagerConnectivityStateToString(const NetworkManager::NetworkManagerConnectivityState &state) +{ + QMetaObject metaObject = NetworkManager::staticMetaObject; + int enumIndex = metaObject.indexOfEnumerator(QString("NetworkManagerConnectivityState").toLatin1().data()); + QMetaEnum metaEnum = metaObject.enumerator(enumIndex); + return QString(metaEnum.valueToKey(state)).remove("NetworkManagerConnectivityState"); +} + +void NetworkManager::setAvailable(bool available) +{ + if (m_available == available) + return; + + qCDebug(dcNetworkManager()) << "Service is now" << (available ? "available" : "unavailable"); + m_available = available; + emit availableChanged(m_available); +} + +void NetworkManager::setVersion(const QString &version) +{ + if (m_version == version) + return; + + qCDebug(dcNetworkManager()) << "Version:" << version; + m_version = version; + emit versionChanged(m_version); +} + +void NetworkManager::setWirelessEnabled(bool enabled) +{ + if (m_wirelessEnabled == enabled) + return; + + qCDebug(dcNetworkManager()) << "Wireless networking" << (enabled ? "enabled" : "disabled"); + m_wirelessEnabled = enabled; + emit wirelessEnabledChanged(m_wirelessEnabled); +} + +void NetworkManager::setConnectivityState(const NetworkManager::NetworkManagerConnectivityState &connectivityState) +{ + if (m_connectivityState == connectivityState) + return; + + qCDebug(dcNetworkManager()) << "Connectivity state changed:" << networkManagerConnectivityStateToString(connectivityState); + m_connectivityState = connectivityState; + emit connectivityStateChanged(m_connectivityState); +} + +void NetworkManager::setState(const NetworkManager::NetworkManagerState &state) +{ + if (m_state == state) + return; + + qCDebug(dcNetworkManager()) << "State changed:" << networkManagerStateToString(state); + m_state = state; + emit stateChanged(m_state); +} + +void NetworkManager::onServiceRegistered() +{ + qCDebug(dcNetworkManager()) << "DBus service registered and available."; + // TODO: init stuff +} + +void NetworkManager::onServiceUnregistered() +{ + qCWarning(dcNetworkManager()) << "DBus service unregistered."; + // TODO: deinit stuff +} + +void NetworkManager::onDeviceAdded(const QDBusObjectPath &deviceObjectPath) +{ + if (m_networkDevices.keys().contains(deviceObjectPath)) { + qCWarning(dcNetworkManager()) << "Device" << deviceObjectPath.path() << "already added."; + return; + } + + // Get device Type + QDBusInterface networkDeviceInterface(NetworkManagerUtils::networkManagerServiceString(), deviceObjectPath.path(), NetworkManagerUtils::deviceInterfaceString(), QDBusConnection::systemBus()); + if(!networkDeviceInterface.isValid()) { + qCWarning(dcNetworkManager()) << "NetworkDevice: Invalid DBus device interface" << deviceObjectPath.path(); + return; + } + + // Create object + NetworkDevice::NetworkDeviceType deviceType = NetworkDevice::NetworkDeviceType(networkDeviceInterface.property("DeviceType").toUInt()); + switch (deviceType) { + case NetworkDevice::NetworkDeviceTypeWifi: { + WirelessNetworkDevice *wirelessNetworkDevice = new WirelessNetworkDevice(deviceObjectPath, this); + qCDebug(dcNetworkManager()) << "[+]" << wirelessNetworkDevice; + m_networkDevices.insert(deviceObjectPath, wirelessNetworkDevice); + m_wirelessNetworkDevices.insert(deviceObjectPath, wirelessNetworkDevice); + connect(wirelessNetworkDevice, &WirelessNetworkDevice::deviceChanged, this, &NetworkManager::onWirelessDeviceChanged); + emit wirelessDeviceAdded(wirelessNetworkDevice); + break; + } + case NetworkDevice::NetworkDeviceTypeEthernet: { + WiredNetworkDevice *wiredNetworkDevice = new WiredNetworkDevice(deviceObjectPath, this); + qCDebug(dcNetworkManager()) << "[+]" << wiredNetworkDevice; + m_networkDevices.insert(deviceObjectPath, wiredNetworkDevice); + m_wiredNetworkDevices.insert(deviceObjectPath, wiredNetworkDevice); + + connect(wiredNetworkDevice, &WiredNetworkDevice::deviceChanged, this, &NetworkManager::onWiredDeviceChanged); + emit wiredDeviceAdded(wiredNetworkDevice); + break; + } + default: + NetworkDevice *networkDevice = new NetworkDevice(deviceObjectPath, this); + qCDebug(dcNetworkManager()) << "[+]" << networkDevice; + m_networkDevices.insert(deviceObjectPath, networkDevice); + break; + } +} + +void NetworkManager::onDeviceRemoved(const QDBusObjectPath &deviceObjectPath) +{ + if (!m_networkDevices.keys().contains(deviceObjectPath)) { + qCWarning(dcNetworkManager()) << "Unknown network device removed:" << deviceObjectPath.path(); + return; + } + + NetworkDevice *networkDevice = m_networkDevices.take(deviceObjectPath); + + if (m_wiredNetworkDevices.contains(deviceObjectPath)) { + qCDebug(dcNetworkManager()) << "[-]" << m_wiredNetworkDevices.value(deviceObjectPath); + m_wiredNetworkDevices.remove(deviceObjectPath); + emit wiredDeviceRemoved(networkDevice->interface()); + } else if (m_wirelessNetworkDevices.contains(deviceObjectPath)) { + qCDebug(dcNetworkManager()) << "[-]" << m_wirelessNetworkDevices.value(deviceObjectPath); + m_wirelessNetworkDevices.remove(deviceObjectPath); + if (!wirelessAvailable()) + emit wirelessAvailableChanged(wirelessAvailable()); + + emit wirelessDeviceRemoved(networkDevice->interface()); + } else { + qCDebug(dcNetworkManager()) << "[-]" << networkDevice; + } + + networkDevice->deleteLater(); +} + +void NetworkManager::onPropertiesChanged(const QVariantMap &properties) +{ + if (properties.contains("Version")) + setVersion(properties.value("Version").toString()); + + if (properties.contains("State")) + setState((NetworkManagerState)properties.value("State").toUInt()); + + if (properties.contains("Connectivity")) + setConnectivityState(NetworkManagerConnectivityState(properties.value("Connectivity").toUInt())); + + if (properties.contains("NetworkingEnabled")) + setNetworkingEnabled(properties.value("NetworkingEnabled").toBool()); + + if (properties.contains("WirelessEnabled")) + setWirelessEnabled(properties.value("WirelessEnabled").toBool()); + +} + +void NetworkManager::onWirelessDeviceChanged() +{ + WirelessNetworkDevice *networkDevice = static_cast(sender()); + emit wirelessDeviceChanged(networkDevice); +} + +void NetworkManager::onWiredDeviceChanged() +{ + WiredNetworkDevice *networkDevice = static_cast(sender()); + emit wiredDeviceChanged(networkDevice); +} + +bool NetworkManager::start() +{ + // Get notification when network-manager appears/disappears on DBus + m_serviceWatcher = new QDBusServiceWatcher(NetworkManagerUtils::networkManagerServiceString(), QDBusConnection::systemBus(), QDBusServiceWatcher::WatchForRegistration | QDBusServiceWatcher::WatchForUnregistration, this); + connect(m_serviceWatcher, &QDBusServiceWatcher::serviceRegistered, this, &NetworkManager::onServiceRegistered); + connect(m_serviceWatcher, &QDBusServiceWatcher::serviceUnregistered, this, &NetworkManager::onServiceUnregistered); + + // Check DBus connection + if (!QDBusConnection::systemBus().isConnected()) { + qCWarning(dcNetworkManager()) << "System DBus not connected. NetworkManagre not available."; + m_serviceWatcher->deleteLater(); + m_serviceWatcher = nullptr; + return false; + } + + // Create interface + m_networkManagerInterface = new QDBusInterface(NetworkManagerUtils::networkManagerServiceString(), NetworkManagerUtils::networkManagerPathString(), NetworkManagerUtils::networkManagerServiceString(), QDBusConnection::systemBus(), this); + if(!m_networkManagerInterface->isValid()) { + qCWarning(dcNetworkManager()) << "Invalid DBus network manager interface. NetworkManagre not available."; + m_serviceWatcher->deleteLater(); + m_serviceWatcher = nullptr; + + m_networkManagerInterface->deleteLater(); + m_networkManagerInterface = nullptr; + return false; + } + + // Init properties + setVersion(m_networkManagerInterface->property("Version").toString()); + setState((NetworkManagerState)m_networkManagerInterface->property("State").toUInt()); + setConnectivityState((NetworkManagerConnectivityState)m_networkManagerInterface->property("Connectivity").toUInt()); + setNetworkingEnabled(m_networkManagerInterface->property("NetworkingEnabled").toBool()); + setWirelessEnabled(m_networkManagerInterface->property("WirelessEnabled").toBool()); + + // Load network devices + loadDevices(); + + // Create settings + m_networkSettings = new NetworkSettings(this); + + // Connect signals + QDBusConnection::systemBus().connect(NetworkManagerUtils::networkManagerServiceString(), NetworkManagerUtils::networkManagerPathString(), NetworkManagerUtils::networkManagerServiceString(), "StateChanged", this, SLOT(onStateChanged(uint))); + QDBusConnection::systemBus().connect(NetworkManagerUtils::networkManagerServiceString(), NetworkManagerUtils::networkManagerPathString(), NetworkManagerUtils::networkManagerServiceString(), "DeviceAdded", this, SLOT(onDeviceAdded(QDBusObjectPath))); + QDBusConnection::systemBus().connect(NetworkManagerUtils::networkManagerServiceString(), NetworkManagerUtils::networkManagerPathString(), NetworkManagerUtils::networkManagerServiceString(), "DeviceRemoved", this, SLOT(onDeviceRemoved(QDBusObjectPath))); + QDBusConnection::systemBus().connect(NetworkManagerUtils::networkManagerServiceString(), NetworkManagerUtils::networkManagerPathString(), NetworkManagerUtils::networkManagerServiceString(), "PropertiesChanged", this, SLOT(onPropertiesChanged(QVariantMap))); + + setAvailable(true); + return true; +} + +void NetworkManager::stop() +{ + foreach (NetworkDevice *device, m_networkDevices) { + onDeviceRemoved(device->objectPath()); + } + + m_wiredNetworkDevices.clear(); + m_wirelessNetworkDevices.clear(); + + if (m_networkSettings) { + delete m_networkSettings; + m_networkSettings = nullptr; + } + + if (m_networkManagerInterface) { + delete m_networkManagerInterface; + m_networkManagerInterface = nullptr; + } + + if (m_serviceWatcher) { + delete m_serviceWatcher; + m_serviceWatcher = nullptr; + } + + m_version = QString(); + m_state = NetworkManagerStateUnknown; + m_connectivityState = NetworkManagerConnectivityStateUnknown; + m_networkingEnabled = false; + m_wirelessEnabled = false; + + setAvailable(false); +} + diff --git a/libnymea-networkmanager/networkmanager.h b/libnymea-networkmanager/networkmanager.h new file mode 100644 index 0000000..351f698 --- /dev/null +++ b/libnymea-networkmanager/networkmanager.h @@ -0,0 +1,173 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * * + * Copyright (C) 2018 Simon Stürz * + * * + * This file is part of libnymea-networkmanager. * + * * + * libnymea-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. * + * * + * libnymea-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 libnymea-networkmanager. If not, see . * + * * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +#ifndef NETWORKMANAGER_H +#define NETWORKMANAGER_H + +#include +#include +#include +#include +#include +#include +#include + +#include "networksettings.h" +#include "wirednetworkdevice.h" +#include "networkmanagerutils.h" +#include "wirelessnetworkdevice.h" + +// Docs: https://developer.gnome.org/NetworkManager/unstable/spec.html + +class NetworkManager : public QObject +{ + Q_OBJECT + Q_ENUMS(NetworkManagerState) + Q_ENUMS(NetworkManagerConnectivityState) + Q_ENUMS(NetworkManagerError) + +public: + enum NetworkManagerState { + NetworkManagerStateUnknown = 0, + NetworkManagerStateAsleep = 10, + NetworkManagerStateDisconnected = 20, + NetworkManagerStateDisconnecting = 30, + NetworkManagerStateConnecting = 40, + NetworkManagerStateConnectedLocal = 50, + NetworkManagerStateConnectedSite = 60, + NetworkManagerStateConnectedGlobal = 70 + }; + Q_ENUM(NetworkManagerState) + + enum NetworkManagerConnectivityState { + NetworkManagerConnectivityStateUnknown = 0, + NetworkManagerConnectivityStateNone = 1, + NetworkManagerConnectivityStatePortal = 2, + NetworkManagerConnectivityStateLimited = 3, + NetworkManagerConnectivityStateFull = 4 + }; + Q_ENUM(NetworkManagerConnectivityState) + + enum NetworkManagerError { + NetworkManagerErrorNoError, + NetworkManagerErrorUnknownError, + NetworkManagerErrorWirelessNotAvailable, + NetworkManagerErrorAccessPointNotFound, + NetworkManagerErrorNetworkInterfaceNotFound, + NetworkManagerErrorInvalidNetworkDeviceType, + NetworkManagerErrorWirelessNetworkingDisabled, + NetworkManagerErrorWirelessConnectionFailed, + NetworkManagerErrorNetworkingDisabled, + NetworkManagerErrorNetworkManagerNotAvailable + }; + Q_ENUM(NetworkManagerError) + + explicit NetworkManager(QObject *parent = 0); + ~NetworkManager(); + + bool available() const; + bool wirelessAvailable() const; + + QList networkDevices() const; + QList wirelessNetworkDevices() const; + QList wiredNetworkDevices() const; + + NetworkDevice *getNetworkDevice(const QString &interface); + + // Properties + QString version() const; + NetworkManagerState state() const; + QString stateString() const; + NetworkManagerConnectivityState connectivityState() const; + + NetworkManagerError connectWifi(const QString &interface, const QString &ssid, const QString &password, bool hidden = false); + + // Networking + bool networkingEnabled() const; + bool enableNetworking(bool enabled); + + // Wireless Networking + bool wirelessEnabled() const; + bool enableWireless(bool enabled); + +private: + QDBusServiceWatcher *m_serviceWatcher = nullptr; + QDBusInterface *m_networkManagerInterface = nullptr; + NetworkSettings *m_networkSettings = nullptr; + + QHash m_networkDevices; + QHash m_wirelessNetworkDevices; + QHash m_wiredNetworkDevices; + + bool m_available = false; + QString m_version; + NetworkManagerState m_state = NetworkManagerStateUnknown; + NetworkManagerConnectivityState m_connectivityState = NetworkManagerConnectivityStateUnknown; + bool m_networkingEnabled = false; + bool m_wirelessEnabled = false; + + void loadDevices(); + + static QString networkManagerStateToString(const NetworkManagerState &state); + static QString networkManagerConnectivityStateToString(const NetworkManagerConnectivityState &state); + + void setAvailable(bool available); + void setVersion(const QString &version); + void setNetworkingEnabled(bool enabled); + void setWirelessEnabled(bool enabled); + void setConnectivityState(const NetworkManagerConnectivityState &connectivityState); + void setState(const NetworkManagerState &state); + +signals: + void availableChanged(bool available); + void versionChanged(const QString &version); + void networkingEnabledChanged(bool enabled); + void wirelessEnabledChanged(bool enabled); + void wirelessAvailableChanged(bool available); + void stateChanged(const NetworkManagerState &state); + void connectivityStateChanged(const NetworkManagerConnectivityState &state); + + void wirelessDeviceAdded(WirelessNetworkDevice *wirelessDevice); + void wirelessDeviceRemoved(const QString &interface); + void wirelessDeviceChanged(WirelessNetworkDevice *wirelessDevice); + + void wiredDeviceAdded(WiredNetworkDevice *wiredDevice); + void wiredDeviceRemoved(const QString &interface); + void wiredDeviceChanged(WiredNetworkDevice *wiredDevice); + +private slots: + void onServiceRegistered(); + void onServiceUnregistered(); + + void onDeviceAdded(const QDBusObjectPath &deviceObjectPath); + void onDeviceRemoved(const QDBusObjectPath &deviceObjectPath); + void onPropertiesChanged(const QVariantMap &properties); + + void onWirelessDeviceChanged(); + void onWiredDeviceChanged(); + +public slots: + bool start(); + void stop(); + +}; + +#endif // NETWORKMANAGER_H diff --git a/libnymea-networkmanager/networkmanagerutils.cpp b/libnymea-networkmanager/networkmanagerutils.cpp new file mode 100644 index 0000000..b3afbae --- /dev/null +++ b/libnymea-networkmanager/networkmanagerutils.cpp @@ -0,0 +1,71 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * * + * Copyright (C) 2018 Simon Stürz * + * * + * This file is part of libnymea-networkmanager. * + * * + * libnymea-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. * + * * + * libnymea-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 libnymea-networkmanager. If not, see . * + * * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +#include "networkmanagerutils.h" + +Q_LOGGING_CATEGORY(dcNetworkManager, "NetworkManager") + +QString NetworkManagerUtils::NetworkManagerUtils::networkManagerServiceString() +{ + return "org.freedesktop.NetworkManager"; +} + +QString NetworkManagerUtils::networkManagerPathString() +{ + return "/org/freedesktop/NetworkManager"; +} + +QString NetworkManagerUtils::NetworkManagerUtils::settingsPathString() +{ + return "/org/freedesktop/NetworkManager/Settings"; +} + +QString NetworkManagerUtils::NetworkManagerUtils::deviceInterfaceString() +{ + return "org.freedesktop.NetworkManager.Device"; +} + +QString NetworkManagerUtils::NetworkManagerUtils::wirelessInterfaceString() +{ + return "org.freedesktop.NetworkManager.Device.Wireless"; +} + +QString NetworkManagerUtils::NetworkManagerUtils::wiredInterfaceString() +{ + return "org.freedesktop.NetworkManager.Device.Wired"; +} + +QString NetworkManagerUtils::NetworkManagerUtils::accessPointInterfaceString() +{ + return "org.freedesktop.NetworkManager.AccessPoint"; +} + +QString NetworkManagerUtils::NetworkManagerUtils::settingsInterfaceString() +{ + return "org.freedesktop.NetworkManager.Settings"; +} + +QString NetworkManagerUtils::connectionsInterfaceString() +{ + return "org.freedesktop.NetworkManager.Settings.Connection"; +} + + diff --git a/libnymea-networkmanager/networkmanagerutils.h b/libnymea-networkmanager/networkmanagerutils.h new file mode 100644 index 0000000..cb9a269 --- /dev/null +++ b/libnymea-networkmanager/networkmanagerutils.h @@ -0,0 +1,51 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * * + * Copyright (C) 2018 Simon Stürz * + * * + * This file is part of libnymea-networkmanager. * + * * + * libnymea-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. * + * * + * libnymea-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 libnymea-networkmanager. If not, see . * + * * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +#ifndef NETWORKMANAGERUTILS_H +#define NETWORKMANAGERUTILS_H + +#include +#include +#include +#include + +Q_DECLARE_LOGGING_CATEGORY(dcNetworkManager) + +class NetworkManagerUtils +{ + Q_GADGET + +public: + static QString networkManagerServiceString(); + + static QString networkManagerPathString(); + static QString settingsPathString(); + + static QString deviceInterfaceString(); + static QString wirelessInterfaceString(); + static QString wiredInterfaceString(); + static QString accessPointInterfaceString(); + static QString settingsInterfaceString(); + static QString connectionsInterfaceString(); + +}; + +#endif // NETWORKMANAGERUTILS_H diff --git a/libnymea-networkmanager/networksettings.cpp b/libnymea-networkmanager/networksettings.cpp new file mode 100644 index 0000000..f6bbaba --- /dev/null +++ b/libnymea-networkmanager/networksettings.cpp @@ -0,0 +1,106 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * * + * Copyright (C) 2018 Simon Stürz * + * * + * This file is part of libnymea-networkmanager. * + * * + * libnymea-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. * + * * + * libnymea-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 libnymea-networkmanager. If not, see . * + * * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +#include "networksettings.h" +#include "networkmanagerutils.h" + +#include + +/*! Constructs a new \l{NetworkSettings} object with the given \a parent. */ +NetworkSettings::NetworkSettings(QObject *parent) : + QObject(parent) +{ + m_settingsInterface = new QDBusInterface(NetworkManagerUtils::networkManagerServiceString(), NetworkManagerUtils::settingsPathString(), NetworkManagerUtils::settingsInterfaceString(), QDBusConnection::systemBus(), this); + if(!m_settingsInterface->isValid()) { + qCWarning(dcNetworkManager()) << "Invalid DBus network settings interface"; + return; + } + + loadConnections(); + + QDBusConnection::systemBus().connect(NetworkManagerUtils::networkManagerServiceString(), NetworkManagerUtils::settingsPathString(), NetworkManagerUtils::settingsInterfaceString(), "NewConnection", this, SLOT(connectionAdded(QDBusObjectPath))); + QDBusConnection::systemBus().connect(NetworkManagerUtils::networkManagerServiceString(), NetworkManagerUtils::settingsPathString(), NetworkManagerUtils::settingsInterfaceString(), "ConnectionRemoved", this, SLOT(connectionRemoved(QDBusObjectPath))); + QDBusConnection::systemBus().connect(NetworkManagerUtils::networkManagerServiceString(), NetworkManagerUtils::settingsPathString(), NetworkManagerUtils::settingsInterfaceString(), "PropertiesChanged", this, SLOT(propertiesChanged(QVariantMap))); +} + +/*! Add the given \a settings to this \l{NetworkSettings}. Returns the dbus object path from the new settings. */ +QDBusObjectPath NetworkSettings::addConnection(const ConnectionSettings &settings) +{ + QDBusMessage query = m_settingsInterface->call("AddConnection", QVariant::fromValue(settings)); + if(query.type() != QDBusMessage::ReplyMessage) { + qCWarning(dcNetworkManager()) << query.errorName() << query.errorMessage(); + return QDBusObjectPath(); + } + + if (query.arguments().isEmpty()) + return QDBusObjectPath(); + + return query.arguments().at(0).value(); +} + +/*! Returns the list of current \l{NetworkConnection}{NetworkConnections} from this \l{NetworkSettings}. */ +QList NetworkSettings::connections() const +{ + return m_connections.values(); +} + +void NetworkSettings::loadConnections() +{ + QDBusMessage query = m_settingsInterface->call("ListConnections"); + if(query.type() != QDBusMessage::ReplyMessage) { + qCWarning(dcNetworkManager()) << query.errorName() << query.errorMessage(); + return; + } + + if (query.arguments().isEmpty()) + return; + + const QDBusArgument &argument = query.arguments().at(0).value(); + argument.beginArray(); + while(!argument.atEnd()) { + QDBusObjectPath objectPath = qdbus_cast(argument); + connectionAdded(objectPath); + } + argument.endArray(); + +} + +void NetworkSettings::connectionAdded(const QDBusObjectPath &objectPath) +{ + NetworkConnection *connection = new NetworkConnection(objectPath, this); + m_connections.insert(objectPath, connection); + + qCDebug(dcNetworkManager()) << "Settings: [+]" << connection; +} + +void NetworkSettings::connectionRemoved(const QDBusObjectPath &objectPath) +{ + NetworkConnection *connection = m_connections.take(objectPath); + qCDebug(dcNetworkManager()) << "Settings: [-]" << connection; + connection->deleteLater(); +} + +void NetworkSettings::propertiesChanged(const QVariantMap &properties) +{ + Q_UNUSED(properties); + // TODO: handle settings changes + //qCDebug(dcNetworkManager()) << "Settins: properties changed" << properties; +} diff --git a/libnymea-networkmanager/networksettings.h b/libnymea-networkmanager/networksettings.h new file mode 100644 index 0000000..05ff477 --- /dev/null +++ b/libnymea-networkmanager/networksettings.h @@ -0,0 +1,57 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * * + * Copyright (C) 2018 Simon Stürz * + * * + * This file is part of libnymea-networkmanager. * + * * + * libnymea-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. * + * * + * libnymea-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 libnymea-networkmanager. If not, see . * + * * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +#ifndef NETWORKSETTINGS_H +#define NETWORKSETTINGS_H + +#include +#include +#include +#include +#include + +#include "networkconnection.h" + +class NetworkConnection; + +class NetworkSettings : public QObject +{ + Q_OBJECT +public: + explicit NetworkSettings(QObject *parent = 0); + + QDBusObjectPath addConnection(const ConnectionSettings &settings); + QList connections() const; + +private: + QDBusInterface *m_settingsInterface = nullptr; + QHash m_connections; + + void loadConnections(); + +private slots: + void connectionAdded(const QDBusObjectPath &objectPath); + void connectionRemoved(const QDBusObjectPath &objectPath); + void propertiesChanged(const QVariantMap &properties); + +}; + +#endif // NETWORKSETTINGS_H diff --git a/libnymea-networkmanager/wirednetworkdevice.cpp b/libnymea-networkmanager/wirednetworkdevice.cpp new file mode 100644 index 0000000..c2bf35c --- /dev/null +++ b/libnymea-networkmanager/wirednetworkdevice.cpp @@ -0,0 +1,97 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * * + * Copyright (C) 2018 Simon Stürz * + * * + * This file is part of libnymea-networkmanager. * + * * + * libnymea-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. * + * * + * libnymea-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 libnymea-networkmanager. If not, see . * + * * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +#include "wirednetworkdevice.h" + +#include + +/*! Constructs a new \l{WiredNetworkDevice} with the given dbus \a objectPath and \a parent. */ +WiredNetworkDevice::WiredNetworkDevice(const QDBusObjectPath &objectPath, QObject *parent) : + NetworkDevice(objectPath, parent) +{ + QDBusConnection systemBus = QDBusConnection::systemBus(); + if (!systemBus.isConnected()) { + qCWarning(dcNetworkManager()) << "WiredNetworkDevice: System DBus not connected"; + return; + } + + m_wiredInterface = new QDBusInterface(NetworkManagerUtils::networkManagerServiceString(), this->objectPath().path(), NetworkManagerUtils::wiredInterfaceString(), systemBus, this); + if(!m_wiredInterface->isValid()) { + qCWarning(dcNetworkManager()) << "WiredNetworkDevice: Invalid wired dbus interface"; + return; + } + + setMacAddress(m_wiredInterface->property("HwAddress").toString()); + setBitRate(m_wiredInterface->property("Bitrate").toInt()); + setPluggedIn(m_wiredInterface->property("Carrier").toBool()); + + QDBusConnection::systemBus().connect(NetworkManagerUtils::networkManagerServiceString(), this->objectPath().path(), NetworkManagerUtils::wiredInterfaceString(), "PropertiesChanged", this, SLOT(propertiesChanged(QVariantMap))); +} + +/*! Returns the mac address of this \l{WiredNetworkDevice}. */ +QString WiredNetworkDevice::macAddress() const +{ + return m_macAddress; +} + +/*! Returns the current bit rate [Mb/s] of this \l{WiredNetworkDevice}. */ +int WiredNetworkDevice::bitRate() const +{ + return m_bitRate; +} + +/*! Returns true if this \l{WiredNetworkDevice} has a cable plugged in. */ +bool WiredNetworkDevice::pluggedIn() const +{ + return m_pluggedIn; +} + +void WiredNetworkDevice::setMacAddress(const QString &macAddress) +{ + m_macAddress = macAddress; +} + +void WiredNetworkDevice::setBitRate(const int &bitRate) +{ + m_bitRate = bitRate; +} + +void WiredNetworkDevice::setPluggedIn(const bool &pluggedIn) +{ + m_pluggedIn = pluggedIn; +} + +void WiredNetworkDevice::propertiesChanged(const QVariantMap &properties) +{ + if (properties.contains("Carrier")) + setPluggedIn(properties.value("Carrier").toBool()); + +} + +QDebug operator<<(QDebug debug, WiredNetworkDevice *networkDevice) +{ + debug.nospace() << "WiredNetworkDevice(" << networkDevice->interface() << ", "; + debug.nospace() << networkDevice->macAddress() << ", "; + debug.nospace() << networkDevice->bitRate() << " [Mb/s], "; + debug.nospace() << networkDevice->pluggedIn() << ", "; + debug.nospace() << networkDevice->deviceStateString() << ") "; + return debug; +} diff --git a/libnymea-networkmanager/wirednetworkdevice.h b/libnymea-networkmanager/wirednetworkdevice.h new file mode 100644 index 0000000..02ce8d9 --- /dev/null +++ b/libnymea-networkmanager/wirednetworkdevice.h @@ -0,0 +1,58 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * * + * Copyright (C) 2018 Simon Stürz * + * * + * This file is part of libnymea-networkmanager. * + * * + * libnymea-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. * + * * + * libnymea-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 libnymea-networkmanager. If not, see . * + * * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +#ifndef WIREDNETWORKDEVICE_H +#define WIREDNETWORKDEVICE_H + +#include +#include + +#include "networkdevice.h" + +class WiredNetworkDevice : public NetworkDevice +{ + Q_OBJECT +public: + explicit WiredNetworkDevice(const QDBusObjectPath &objectPath, QObject *parent = 0); + + QString macAddress() const; + int bitRate() const; + bool pluggedIn() const; + +private: + QDBusInterface *m_wiredInterface = nullptr; + + QString m_macAddress; + int m_bitRate = 0; + bool m_pluggedIn = false; + + void setMacAddress(const QString &macAddress); + void setBitRate(const int &bitRate); + void setPluggedIn(const bool &pluggedIn); + +private slots: + void propertiesChanged(const QVariantMap &properties); + +}; + +QDebug operator<<(QDebug debug, WiredNetworkDevice *networkDevice); + +#endif // WIREDNETWORKDEVICE_H diff --git a/libnymea-networkmanager/wirelessaccesspoint.cpp b/libnymea-networkmanager/wirelessaccesspoint.cpp new file mode 100644 index 0000000..7d5f2b4 --- /dev/null +++ b/libnymea-networkmanager/wirelessaccesspoint.cpp @@ -0,0 +1,149 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * * + * Copyright (C) 2018 Simon Stürz * + * * + * This file is part of libnymea-networkmanager. * + * * + * libnymea-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. * + * * + * libnymea-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 libnymea-networkmanager. If not, see . * + * * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +/*! \enum guhserver::WirelessAccessPoint::ApSecurityMode + \value ApSecurityModeNone + \value ApSecurityModePairWep40 + \value ApSecurityModePairWep104 + \value ApSecurityModePairTkip + \value ApSecurityModePairCcmp + \value ApSecurityModeGroupWep40 + \value ApSecurityModeGroupWep104 + \value ApSecurityModeGroupTkip + \value ApSecurityModeGroupCcmp + \value ApSecurityModeKeyMgmtPsk + \value ApSecurityModeKeyMgmt8021X +*/ + +/*! \fn void WirelessAccessPoint::signalStrengthChanged(); + This signal will be emitted when the signalStrength of this \l{WirelessAccessPoint} has changed. +*/ + +#include "wirelessaccesspoint.h" +#include "networkmanagerutils.h" + +/*! Constructs a new \l{WirelessAccessPoint} with the given dbus \a objectPath and \a parent. */ +WirelessAccessPoint::WirelessAccessPoint(const QDBusObjectPath &objectPath, QObject *parent) : + QObject(parent), + m_objectPath(objectPath), + m_securityFlags(0) +{ + QDBusInterface accessPointInterface(NetworkManagerUtils::networkManagerServiceString(), m_objectPath.path(), NetworkManagerUtils::accessPointInterfaceString(), QDBusConnection::systemBus()); + if(!accessPointInterface.isValid()) { + qCWarning(dcNetworkManager()) << "Invalid access point dbus interface"; + return; + } + + // Init properties + setSsid(accessPointInterface.property("Ssid").toString()); + setMacAddress(accessPointInterface.property("HwAddress").toString()); + setFrequency(accessPointInterface.property("Frequency").toDouble() / 1000); + setSignalStrength(accessPointInterface.property("Strength").toUInt()); + setSecurityFlags(WirelessAccessPoint::ApSecurityModes(accessPointInterface.property("WpaFlags").toUInt())); + setIsProtected((bool)accessPointInterface.property("Flags").toUInt()); + + QDBusConnection::systemBus().connect(NetworkManagerUtils::networkManagerServiceString(), objectPath.path(), NetworkManagerUtils::accessPointInterfaceString(), "PropertiesChanged", this, SLOT(onPropertiesChanged(QVariantMap))); +} + +/*! Returns the dbus object path of this \l{WirelessAccessPoint}. */ +QDBusObjectPath WirelessAccessPoint::objectPath() const +{ + return m_objectPath; +} + +/*! Returns the ssid of this \l{WirelessAccessPoint}. */ +QString WirelessAccessPoint::ssid() const +{ + return m_ssid; +} + +void WirelessAccessPoint::setSsid(const QString &ssid) +{ + m_ssid = ssid; +} + +/*! Returns the mac address of this \l{WirelessAccessPoint}. */ +QString WirelessAccessPoint::macAddress() const +{ + return m_macAddress; +} + +void WirelessAccessPoint::setMacAddress(const QString &macAddress) +{ + m_macAddress = macAddress; +} + +/*! Returns the frequency of this \l{WirelessAccessPoint}. (2.4 GHz or 5GHz) */ +double WirelessAccessPoint::frequency() const +{ + return m_frequency; +} + +void WirelessAccessPoint::setFrequency(const double &frequency) +{ + m_frequency = frequency; +} + +/*! Returns the signal strength in percentage [0, 100] % of this \l{WirelessAccessPoint}. */ +int WirelessAccessPoint::signalStrength() const +{ + return m_signalStrength; +} + +void WirelessAccessPoint::setSignalStrength(const int &signalStrength) +{ + m_signalStrength = signalStrength; + emit signalStrengthChanged(); +} + +void WirelessAccessPoint::setIsProtected(const bool &isProtected) +{ + m_isProtected = isProtected; +} + +/*! Returns true if this \l{WirelessAccessPoint} is password protected. */ +bool WirelessAccessPoint::isProtected() const +{ + return m_isProtected; +} + +/*! Returns the security flags of this \l{WirelessAccessPoint}. \sa WirelessAccessPoint::ApSecurityModes */ +WirelessAccessPoint::ApSecurityModes WirelessAccessPoint::securityFlags() const +{ + return m_securityFlags; +} + +void WirelessAccessPoint::setSecurityFlags(const WirelessAccessPoint::ApSecurityModes &securityFlags) +{ + m_securityFlags = securityFlags; +} + +void WirelessAccessPoint::onPropertiesChanged(const QVariantMap &properties) +{ + if (properties.contains("Strength")) + setSignalStrength(properties.value("Strength").toUInt()); + +} + +QDebug operator<<(QDebug debug, WirelessAccessPoint *accessPoint) +{ + return debug.nospace() << "AccessPoint(" << accessPoint->signalStrength() << "%, " << accessPoint->frequency()<< " GHz, " << accessPoint->ssid() << ", " << (accessPoint->isProtected() ? "protected" : "open" ) << ")"; +} diff --git a/libnymea-networkmanager/wirelessaccesspoint.h b/libnymea-networkmanager/wirelessaccesspoint.h new file mode 100644 index 0000000..fd0f735 --- /dev/null +++ b/libnymea-networkmanager/wirelessaccesspoint.h @@ -0,0 +1,92 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * * + * Copyright (C) 2018 Simon Stürz * + * * + * This file is part of libnymea-networkmanager. * + * * + * libnymea-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. * + * * + * libnymea-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 libnymea-networkmanager. If not, see . * + * * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +#ifndef WIRELESSACCESSPOINT_H +#define WIRELESSACCESSPOINT_H + +#include +#include +#include +#include +#include +#include +#include + +class WirelessAccessPoint : public QObject +{ + Q_OBJECT + Q_FLAGS(ApSecurityModes) + +public: + enum ApSecurityMode { + ApSecurityModeNone = 0x000, + ApSecurityModePairWep40 = 0x001, + ApSecurityModePairWep104 = 0x002, + ApSecurityModePairTkip = 0x004, + ApSecurityModePairCcmp = 0x008, + ApSecurityModeGroupWep40 = 0x010, + ApSecurityModeGroupWep104 = 0x020, + ApSecurityModeGroupTkip = 0x040, + ApSecurityModeGroupCcmp = 0x080, + ApSecurityModeKeyMgmtPsk = 0x100, + ApSecurityModeKeyMgmt8021X = 0x200, + }; + Q_DECLARE_FLAGS(ApSecurityModes, ApSecurityMode) + + explicit WirelessAccessPoint(const QDBusObjectPath &objectPath, QObject *parent = 0); + + QDBusObjectPath objectPath() const; + + QString ssid() const; + QString macAddress() const; + double frequency() const; + int signalStrength() const; + bool isProtected() const; + + WirelessAccessPoint::ApSecurityModes securityFlags() const; + +private: + QDBusObjectPath m_objectPath; + QString m_ssid; + QString m_macAddress; + double m_frequency; + int m_signalStrength; + bool m_isProtected; + WirelessAccessPoint::ApSecurityModes m_securityFlags; + + void setSsid(const QString &ssid); + void setMacAddress(const QString &macAddress); + void setFrequency(const double &frequency); + void setSignalStrength(const int &signalStrength); + void setIsProtected(const bool &isProtected); + void setSecurityFlags(const WirelessAccessPoint::ApSecurityModes &securityFlags); + +signals: + void signalStrengthChanged(); + +private slots: + void onPropertiesChanged(const QVariantMap &properties); + +}; + +QDebug operator<<(QDebug debug, WirelessAccessPoint *accessPoint); + +#endif // WIRELESSACCESSPOINT_H diff --git a/libnymea-networkmanager/wirelessnetworkdevice.cpp b/libnymea-networkmanager/wirelessnetworkdevice.cpp new file mode 100644 index 0000000..eaa5bbf --- /dev/null +++ b/libnymea-networkmanager/wirelessnetworkdevice.cpp @@ -0,0 +1,221 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * * + * Copyright (C) 2018 Simon Stürz * + * * + * This file is part of libnymea-networkmanager. * + * * + * libnymea-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. * + * * + * libnymea-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 libnymea-networkmanager. If not, see . * + * * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +/*! \fn void WirelessNetworkDevice::bitRateChanged(const int &bitRate); + This signal will be emitted when the \a bitRate of this \l{WirelessNetworkDevice} has changed. +*/ + +/*! \fn void WirelessNetworkDevice::stateChanged(const NetworkDeviceState &state); + This signal will be emitted when the current \a state of this \l{WirelessNetworkDevice} has changed. + + \sa NetworkDeviceState +*/ + + +#include "networkmanagerutils.h" +#include "wirelessnetworkdevice.h" + +#include +#include +#include + +/*! Constructs a new \l{WirelessNetworkDevice} with the given dbus \a objectPath and \a parent. */ +WirelessNetworkDevice::WirelessNetworkDevice(const QDBusObjectPath &objectPath, QObject *parent) : + NetworkDevice(objectPath, parent), + m_activeAccessPoint(Q_NULLPTR) +{ + QDBusConnection systemBus = QDBusConnection::systemBus(); + if (!systemBus.isConnected()) { + qCWarning(dcNetworkManager()) << "WirelessNetworkDevice: System DBus not connected"; + return; + } + + m_wirelessInterface = new QDBusInterface(NetworkManagerUtils::networkManagerServiceString(), this->objectPath().path(), NetworkManagerUtils::wirelessInterfaceString(), systemBus, this); + if (!m_wirelessInterface->isValid()) { + qCWarning(dcNetworkManager()) << "WirelessNetworkDevice: Invalid wireless dbus interface"; + return; + } + + QDBusConnection::systemBus().connect(NetworkManagerUtils::networkManagerServiceString(), this->objectPath().path(), NetworkManagerUtils::wirelessInterfaceString(), "AccessPointAdded", this, SLOT(accessPointAdded(QDBusObjectPath))); + QDBusConnection::systemBus().connect(NetworkManagerUtils::networkManagerServiceString(), this->objectPath().path(), NetworkManagerUtils::wirelessInterfaceString(), "AccessPointRemoved", this, SLOT(accessPointRemoved(QDBusObjectPath))); + QDBusConnection::systemBus().connect(NetworkManagerUtils::networkManagerServiceString(), this->objectPath().path(), NetworkManagerUtils::wirelessInterfaceString(), "PropertiesChanged", this, SLOT(propertiesChanged(QVariantMap))); + + readAccessPoints(); + + setMacAddress(m_wirelessInterface->property("HwAddress").toString()); + setBitrate(m_wirelessInterface->property("Bitrate").toInt()); + setActiveAccessPoint(qdbus_cast(m_wirelessInterface->property("ActiveAccessPoint"))); +} + +/*! Returns the mac address of this \l{WirelessNetworkDevice}. */ +QString WirelessNetworkDevice::macAddress() const +{ + return m_macAddress; +} + +/*! Returns the bit rate [Mb/s] of this \l{WirelessNetworkDevice}. */ +int WirelessNetworkDevice::bitRate() const +{ + return m_bitRate; +} + +/*! Returns the current active \l{WirelessAccessPoint} of this \l{WirelessNetworkDevice}. */ +WirelessAccessPoint *WirelessNetworkDevice::activeAccessPoint() +{ + return m_activeAccessPoint; +} + +/*! Perform a wireless network scan on this \l{WirelessNetworkDevice}. */ +void WirelessNetworkDevice::scanWirelessNetworks() +{ + qCDebug(dcNetworkManager()) << this << "Request scan"; + QDBusMessage query = m_wirelessInterface->call("RequestScan", QVariantMap()); + if (query.type() != QDBusMessage::ReplyMessage) { + qCWarning(dcNetworkManager()) << "Scan error:" << query.errorName() << query.errorMessage(); + return; + } +} + +/*! Returns the list of all \l{WirelessAccessPoint}{WirelessAccessPoints} of this \l{WirelessNetworkDevice}. */ +QList WirelessNetworkDevice::accessPoints() +{ + return m_accessPointsTable.values(); +} + +/*! Returns the \l{WirelessAccessPoint} with the given \a ssid. If the \l{WirelessAccessPoint} could not be found, return Q_NULLPTR. */ +WirelessAccessPoint *WirelessNetworkDevice::getAccessPoint(const QString &ssid) +{ + foreach (WirelessAccessPoint *accessPoint, m_accessPointsTable.values()) { + if (accessPoint->ssid() == ssid) + return accessPoint; + } + return Q_NULLPTR; +} + +/*! Returns the \l{WirelessAccessPoint} with the given \a objectPath. If the \l{WirelessAccessPoint} could not be found, return Q_NULLPTR. */ +WirelessAccessPoint *WirelessNetworkDevice::getAccessPoint(const QDBusObjectPath &objectPath) +{ + return m_accessPointsTable.value(objectPath); +} + +void WirelessNetworkDevice::readAccessPoints() +{ + QDBusMessage query = m_wirelessInterface->call("GetAccessPoints"); + if(query.type() != QDBusMessage::ReplyMessage) { + qCWarning(dcNetworkManager()) << query.errorName() << query.errorMessage(); + return; + } + + if (query.arguments().isEmpty()) + return; + + const QDBusArgument &argument = query.arguments().at(0).value(); + argument.beginArray(); + while (!argument.atEnd()) { + QDBusObjectPath accessPointObjectPath = qdbus_cast(argument); + accessPointAdded(accessPointObjectPath); + } + argument.endArray(); +} + +void WirelessNetworkDevice::setMacAddress(const QString &macAddress) +{ + m_macAddress = macAddress; +} + +void WirelessNetworkDevice::setBitrate(const int &bitRate) +{ + if (m_bitRate != bitRate / 1000) { + m_bitRate = bitRate / 1000; + emit deviceChanged(); + } +} + +void WirelessNetworkDevice::setActiveAccessPoint(const QDBusObjectPath &activeAccessPointObjectPath) +{ + if (m_activeAccessPointObjectPath != activeAccessPointObjectPath) { + m_activeAccessPointObjectPath = activeAccessPointObjectPath; + if (m_accessPointsTable.contains(m_activeAccessPointObjectPath)) { + if (m_activeAccessPoint) + disconnect(m_activeAccessPoint, &WirelessAccessPoint::signalStrengthChanged, this, &WirelessNetworkDevice::deviceChanged); + + // Set new access point object + m_activeAccessPoint = m_accessPointsTable.value(activeAccessPointObjectPath); + // Update the device when the signalstrength changed + connect(m_activeAccessPoint, &WirelessAccessPoint::signalStrengthChanged, this, &WirelessNetworkDevice::deviceChanged); + } else { + m_activeAccessPoint = Q_NULLPTR; + } + emit deviceChanged(); + } +} + +void WirelessNetworkDevice::accessPointAdded(const QDBusObjectPath &objectPath) +{ + QDBusInterface accessPointInterface(NetworkManagerUtils::networkManagerServiceString(), objectPath.path(), NetworkManagerUtils::accessPointInterfaceString(), QDBusConnection::systemBus()); + if (!accessPointInterface.isValid()) { + qCWarning(dcNetworkManager()) << "WirelessNetworkDevice: Invalid access point dbus interface"; + return; + } + + if (m_accessPointsTable.keys().contains(objectPath)) { + qCWarning(dcNetworkManager()) << "WirelessNetworkDevice: Access point already added" << objectPath.path(); + return; + } + + WirelessAccessPoint *accessPoint = new WirelessAccessPoint(objectPath, this); + //qCDebug(dcNetworkManager()) << "WirelessNetworkDevice: [+]" << accessPoint; + m_accessPointsTable.insert(objectPath, accessPoint); +} + +void WirelessNetworkDevice::accessPointRemoved(const QDBusObjectPath &objectPath) +{ + if (!m_accessPointsTable.keys().contains(objectPath)) + return; + + WirelessAccessPoint *accessPoint = m_accessPointsTable.take(objectPath); + if (accessPoint == m_activeAccessPoint) + m_activeAccessPoint = Q_NULLPTR; + + //qCDebug(dcNetworkManager()) << "WirelessNetworkDevice: [-]" << accessPoint; + accessPoint->deleteLater(); +} + +void WirelessNetworkDevice::propertiesChanged(const QVariantMap &properties) +{ + //qCDebug(dcNetworkManager()) << "WirelessNetworkDevice: Property changed" << properties; + + if (properties.contains("Bitrate")) + setBitrate(properties.value("Bitrate").toInt()); + + if (properties.contains("ActiveAccessPoint")) + setActiveAccessPoint(qdbus_cast(properties.value("ActiveAccessPoint"))); +} + +/*! Writes the given \a device to the given to \a debug. \sa WirelessNetworkDevice, */ +QDebug operator<<(QDebug debug, WirelessNetworkDevice *device) +{ + debug.nospace() << "WirelessNetworkDevice(" << device->interface() << ", "; + debug.nospace() << device->macAddress() << ", "; + debug.nospace() << device->bitRate() << " [Mb/s], "; + debug.nospace() << device->deviceStateString() << ") "; + return debug; +} diff --git a/libnymea-networkmanager/wirelessnetworkdevice.h b/libnymea-networkmanager/wirelessnetworkdevice.h new file mode 100644 index 0000000..ed53380 --- /dev/null +++ b/libnymea-networkmanager/wirelessnetworkdevice.h @@ -0,0 +1,84 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * * + * Copyright (C) 2018 Simon Stürz * + * * + * This file is part of libnymea-networkmanager. * + * * + * libnymea-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. * + * * + * libnymea-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 libnymea-networkmanager. If not, see . * + * * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +#ifndef WIRELESSNETWORKMANAGER_H +#define WIRELESSNETWORKMANAGER_H + +#include +#include +#include +#include +#include +#include +#include + +#include "networkdevice.h" +#include "wirelessaccesspoint.h" + +class WirelessNetworkDevice : public NetworkDevice +{ + Q_OBJECT +public: + + explicit WirelessNetworkDevice(const QDBusObjectPath &objectPath, QObject *parent = 0); + + // Properties + QString macAddress() const; + int bitRate() const; + WirelessAccessPoint *activeAccessPoint(); + + // Accesspoints + QList accessPoints(); + WirelessAccessPoint *getAccessPoint(const QString &ssid); + WirelessAccessPoint *getAccessPoint(const QDBusObjectPath &objectPath); + + // Methods + void scanWirelessNetworks(); + +private: + QDBusInterface *m_wirelessInterface; + + QString m_macAddress; + int m_bitRate; + WirelessAccessPoint *m_activeAccessPoint; + QDBusObjectPath m_activeAccessPointObjectPath; + + QHash m_accessPointsTable; + + void readAccessPoints(); + + void setMacAddress(const QString &macAddress); + void setBitrate(const int &bitRate); + void setActiveAccessPoint(const QDBusObjectPath &activeAccessPointObjectPath); + +private slots: + void accessPointAdded(const QDBusObjectPath &objectPath); + void accessPointRemoved(const QDBusObjectPath &objectPath); + void propertiesChanged(const QVariantMap &properties); + +signals: + void bitRateChanged(const int &bitRate); + +}; + +QDebug operator<<(QDebug debug, WirelessNetworkDevice *device); + +#endif // WIRELESSNETWORKMANAGER_H