diff --git a/debian/changelog b/debian/changelog index 9675bc1..68d1444 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,8 @@ +libnymea-networkmanager (1.5.0) UNRELEASED; urgency=medium + + + -- jenkins Fri, 23 Sep 2022 16:33:36 +0200 + libnymea-networkmanager (1.4.1) jammy; urgency=medium diff --git a/libnymea-networkmanager/networkdevice.h b/libnymea-networkmanager/networkdevice.h index 6ac78fe..bacb06a 100644 --- a/libnymea-networkmanager/networkdevice.h +++ b/libnymea-networkmanager/networkdevice.h @@ -183,13 +183,22 @@ public: 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); +signals: + void deviceChanged(); + void stateChanged(const NetworkDeviceState &state); + +private slots: + void onStateChanged(uint newState, uint oldState, uint reason); + +private: + QStringList readIpAddresses(const QString &property, const QString &interface); + private: QDBusInterface *m_networkDeviceInterface = nullptr; QDBusObjectPath m_objectPath; @@ -215,17 +224,6 @@ private: QList m_availableConnections; -private: - QStringList readIpAddresses(const QString &property, const QString &interface); - -private slots: - void onStateChanged(uint newState, uint oldState, uint reason); - -signals: - void deviceChanged(); - void stateChanged(const NetworkDeviceState &state); - - }; QDebug operator<<(QDebug debug, NetworkDevice *device); diff --git a/libnymea-networkmanager/networkmanager.cpp b/libnymea-networkmanager/networkmanager.cpp index 65434f5..cfcd9a3 100644 --- a/libnymea-networkmanager/networkmanager.cpp +++ b/libnymea-networkmanager/networkmanager.cpp @@ -46,6 +46,8 @@ #include #include +#include + /*! Constructs a new \l{NetworkManager} object with the given \a parent. */ NetworkManager::NetworkManager(QObject *parent) : QObject(parent) @@ -222,7 +224,7 @@ NetworkManager::NetworkManagerError NetworkManager::connectWifi(const QString &i NetworkManager::NetworkManagerError NetworkManager::startAccessPoint(const QString &interface, const QString &ssid, const QString &password) { - qCDebug(dcNetworkManager()) << "Start an access point for" << interface << "SSID:" << ssid << "password:" << password; + qCDebug(dcNetworkManager()) << "Starting access point for" << interface << "SSID:" << ssid << "password:" << password; // Check interface if (!getNetworkDevice(interface)) @@ -303,6 +305,224 @@ NetworkManager::NetworkManagerError NetworkManager::startAccessPoint(const QStri return NetworkManagerErrorNoError; } +NetworkManager::NetworkManagerError NetworkManager::createWiredAutoConnection(const QString &interface) +{ + qCDebug(dcNetworkManager()) << "Creating auto connection for" << interface; + + NetworkDevice *networkDevice = getNetworkDevice(interface); + if (!networkDevice) { + return NetworkManagerErrorNetworkInterfaceNotFound; + } + + QVariantMap ethernetMode { + {"duplex", "full"} + }; + + QVariantMap connectionSettings { + {"id", "auto"}, + {"autoconnect", true}, + {"uuid", QUuid::createUuid().toString().remove(QRegExp("[{}]"))}, + {"type", "802-3-ethernet"} + }; + + QVariantMap ipv4Settings { + {"method", "auto"} + }; + + QVariantMap ipv6Settings { + {"method", "auto"} + }; + + ConnectionSettings settings; + settings.insert("connection", connectionSettings); + settings.insert("ipv4", ipv4Settings); + settings.insert("ipv6", ipv6Settings); + settings.insert("802-3-ethernet", ethernetMode); + + // 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 NetworkManagerErrorUnknownError; + + + qCDebug(dcNetworkManager()) << "Connection added" << connectionObjectPath.path(); + + // Activate connection + QDBusMessage query = m_networkManagerInterface->call("ActivateConnection", + QVariant::fromValue(connectionObjectPath), + QVariant::fromValue(networkDevice->objectPath()), + QVariant::fromValue(QDBusObjectPath("/"))); + if (query.type() != QDBusMessage::ReplyMessage) { + qCWarning(dcNetworkManager()) << query.errorName() << query.errorMessage(); + return NetworkManagerErrorUnknownError; + } + + return NetworkManagerErrorNoError; +} + +NetworkManager::NetworkManagerError NetworkManager::createWiredManualConnection(const QString &interface, const QHostAddress &ip, quint8 prefix, const QHostAddress &gateway, const QHostAddress &dns) +{ + qCDebug(dcNetworkManager()) << "Creating manual connection for" << interface << ip << prefix << gateway << dns; + + NetworkDevice *networkDevice = getNetworkDevice(interface); + if (!networkDevice) { + return NetworkManagerErrorNetworkInterfaceNotFound; + } + if (ip.isNull() || prefix < 8) { + return NetworkManagerErrorInvalidConfiguration; + } + + QVariantMap ethernetMode { + {"duplex", "full"} + }; + + QVariantMap connectionSettings { + {"id", "manual"}, + {"autoconnect", true}, + {"uuid", QUuid::createUuid().toString().remove(QRegExp("[{}]"))}, + {"type", "802-3-ethernet"} + }; + + NMIntListList addresses; + QList address; + address << inet_addr(ip.toString().toLocal8Bit().data()); + address << prefix; + address << inet_addr(gateway.toString().toLocal8Bit().data()); + addresses << address; + + NMVariantMapList addressData; + addressData.append({{"address", ip.toString()}, {"prefix", prefix}}); + + QVariantMap ipv4Settings { + {"method", "manual"}, + {"addresses", QVariant::fromValue(addresses)}, // Deprecated but for our supported platforms still required + {"address-data", QVariant::fromValue(addressData)} // New style, but ignored by NM as long as addresses is still supported and given + }; + if (!dns.isNull()) { + ipv4Settings.insert("dns", QVariant::fromValue(NMIntList{inet_addr(dns.toString().toLocal8Bit().data())})); + } + + // This is ignored if addresses is given, but it's required once the deprecated addresses entry is removed + if (!gateway.isNull()) { + ipv4Settings.insert("gateway", gateway.toString()); + } + + QVariantMap ipv6Settings { + {"method", "disabled"} + }; + + ConnectionSettings settings; + settings.insert("connection", connectionSettings); + settings.insert("ipv4", ipv4Settings); + settings.insert("ipv6", ipv6Settings); + settings.insert("802-3-ethernet", ethernetMode); + + // 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 NetworkManagerErrorUnknownError; + + + qCDebug(dcNetworkManager()) << "Connection added" << connectionObjectPath.path(); + + // Activate connection + QDBusMessage query = m_networkManagerInterface->call("ActivateConnection", + QVariant::fromValue(connectionObjectPath), + QVariant::fromValue(networkDevice->objectPath()), + QVariant::fromValue(QDBusObjectPath("/"))); + if (query.type() != QDBusMessage::ReplyMessage) { + qCWarning(dcNetworkManager()) << query.errorName() << query.errorMessage(); + return NetworkManagerErrorUnknownError; + } + + return NetworkManagerErrorNoError; + +} + +NetworkManager::NetworkManagerError NetworkManager::createSharedConnection(const QString &interface, const QHostAddress &ip, quint8 prefix) +{ + qCDebug(dcNetworkManager()) << "Starting shared connection for" << interface; + + NetworkDevice *networkDevice = getNetworkDevice(interface); + if (!networkDevice) { + return NetworkManagerErrorNetworkInterfaceNotFound; + } + + QVariantMap connectionSettings; + connectionSettings.insert("id", "shared"); + connectionSettings.insert("autoconnect", true); + connectionSettings.insert("uuid", QUuid::createUuid().toString().remove("{").remove("}")); + connectionSettings.insert("type", "802-3-ethernet"); + + NMIntListList addresses; + QList address; + address << inet_addr(ip.toString().toLocal8Bit().data()); + address << prefix; + address << 0; + addresses << address; + + NMVariantMapList addressData; + addressData.append({{"address", ip.toString()}, {"prefix", prefix}}); + + QVariantMap ipv4Settings { + {"method", "shared"} + }; + if (!ip.isNull()) { + ipv4Settings.insert("addresses", QVariant::fromValue(addresses)); // Deprecated but for our supported platforms still required + ipv4Settings.insert("address-data", QVariant::fromValue(addressData)); // New style, but ignored by NM as long as addresses is still supported and given + } + + QVariantMap ipv6Settings; + ipv6Settings.insert("method", "disabled"); + + // Build connection object + ConnectionSettings settings; + settings.insert("connection", connectionSettings); + settings.insert("ipv4", ipv4Settings); + settings.insert("ipv6", ipv6Settings); + + // 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 NetworkManagerErrorUnknownError; + + + qCDebug(dcNetworkManager()) << "Connection added" << connectionObjectPath.path(); + + // Activate connection + QDBusMessage query = m_networkManagerInterface->call("ActivateConnection", + QVariant::fromValue(connectionObjectPath), + QVariant::fromValue(networkDevice->objectPath()), + QVariant::fromValue(QDBusObjectPath("/"))); + if (query.type() != QDBusMessage::ReplyMessage) { + qCWarning(dcNetworkManager()) << query.errorName() << query.errorMessage(); + return NetworkManagerErrorUnknownError; + } + + return NetworkManagerErrorNoError; +} + /*! Returns true if the networking of this \l{NetworkManager} is enabled. */ bool NetworkManager::networkingEnabled() const { @@ -630,13 +850,13 @@ void NetworkManager::onPropertiesChanged(const QVariantMap &properties) void NetworkManager::onWirelessDeviceChanged() { - WirelessNetworkDevice *networkDevice = static_cast(sender()); + WirelessNetworkDevice *networkDevice = qobject_cast(sender()); emit wirelessDeviceChanged(networkDevice); } void NetworkManager::onWiredDeviceChanged() { - WiredNetworkDevice *networkDevice = static_cast(sender()); + WiredNetworkDevice *networkDevice = qobject_cast(sender()); emit wiredDeviceChanged(networkDevice); } diff --git a/libnymea-networkmanager/networkmanager.h b/libnymea-networkmanager/networkmanager.h index 2a469c7..786fa38 100644 --- a/libnymea-networkmanager/networkmanager.h +++ b/libnymea-networkmanager/networkmanager.h @@ -38,6 +38,7 @@ #include #include #include +#include #include "networksettings.h" #include "wirednetworkdevice.h" @@ -85,7 +86,8 @@ public: NetworkManagerErrorWirelessNetworkingDisabled, NetworkManagerErrorWirelessConnectionFailed, NetworkManagerErrorNetworkingDisabled, - NetworkManagerErrorNetworkManagerNotAvailable + NetworkManagerErrorNetworkManagerNotAvailable, + NetworkManagerErrorInvalidConfiguration, }; Q_ENUM(NetworkManagerError) @@ -110,6 +112,9 @@ public: NetworkManagerError connectWifi(const QString &interface, const QString &ssid, const QString &password, bool hidden = false); NetworkManagerError startAccessPoint(const QString &interface, const QString &ssid, const QString &password); + NetworkManagerError createWiredAutoConnection(const QString &interface); + NetworkManagerError createWiredManualConnection(const QString &interface, const QHostAddress &ip, quint8 prefix, const QHostAddress &gateway, const QHostAddress &dns); + NetworkManagerError createSharedConnection(const QString& interface, const QHostAddress &ip, quint8 prefix); // Networking bool networkingEnabled() const; diff --git a/libnymea-networkmanager/networksettings.cpp b/libnymea-networkmanager/networksettings.cpp index f6e4e96..480a36c 100644 --- a/libnymea-networkmanager/networksettings.cpp +++ b/libnymea-networkmanager/networksettings.cpp @@ -46,6 +46,10 @@ NetworkSettings::NetworkSettings(QObject *parent) : QObject(parent) { + qDBusRegisterMetaType(); + qDBusRegisterMetaType(); + qDBusRegisterMetaType(); + m_settingsInterface = new QDBusInterface(NetworkManagerUtils::networkManagerServiceString(), NetworkManagerUtils::settingsPathString(), NetworkManagerUtils::settingsInterfaceString(), QDBusConnection::systemBus(), this); if(!m_settingsInterface->isValid()) { qCWarning(dcNetworkManager()) << "Invalid DBus network settings interface"; diff --git a/libnymea-networkmanager/networksettings.h b/libnymea-networkmanager/networksettings.h index a40b43a..53a9ea6 100644 --- a/libnymea-networkmanager/networksettings.h +++ b/libnymea-networkmanager/networksettings.h @@ -41,6 +41,15 @@ class NetworkConnection; +typedef QList NMVariantMapList; +Q_DECLARE_METATYPE(NMVariantMapList) + +typedef QList> NMIntListList; +Q_DECLARE_METATYPE(NMIntListList) + +typedef QList NMIntList; +Q_DECLARE_METATYPE(NMIntList) + class NetworkSettings : public QObject { Q_OBJECT diff --git a/libnymea-networkmanager/wirednetworkdevice.cpp b/libnymea-networkmanager/wirednetworkdevice.cpp index f64e7ba..411b04c 100644 --- a/libnymea-networkmanager/wirednetworkdevice.cpp +++ b/libnymea-networkmanager/wirednetworkdevice.cpp @@ -58,11 +58,11 @@ WiredNetworkDevice::WiredNetworkDevice(const QDBusObjectPath &objectPath, QObjec return; } - setMacAddress(m_wiredInterface->property("HwAddress").toString()); - setBitRate(m_wiredInterface->property("Bitrate").toInt()); - setPluggedIn(m_wiredInterface->property("Carrier").toBool()); + m_macAddress = m_wiredInterface->property("HwAddress").toString(); + m_bitRate = m_wiredInterface->property("Bitrate").toInt(); + m_pluggedIn = m_wiredInterface->property("Carrier").toBool(); - QDBusConnection::systemBus().connect(NetworkManagerUtils::networkManagerServiceString(), this->objectPath().path(), NetworkManagerUtils::wiredInterfaceString(), "PropertiesChanged", this, SLOT(propertiesChanged(QVariantMap))); + QDBusConnection::systemBus().connect(NetworkManagerUtils::networkManagerServiceString(), this->objectPath().path(), "org.freedesktop.DBus.Properties", "PropertiesChanged", this, SLOT(propertiesChanged(QString, QVariantMap, QStringList))); } /*! Returns the mac address of this \l{WiredNetworkDevice}. */ @@ -83,26 +83,16 @@ bool WiredNetworkDevice::pluggedIn() const return m_pluggedIn; } -void WiredNetworkDevice::setMacAddress(const QString &macAddress) +void WiredNetworkDevice::propertiesChanged(const QString &interface_name, const QVariantMap &changed_properties, const QStringList &invalidated_properties) { - m_macAddress = macAddress; -} - -void WiredNetworkDevice::setBitRate(int bitRate) -{ - m_bitRate = bitRate; -} - -void WiredNetworkDevice::setPluggedIn(bool pluggedIn) -{ - m_pluggedIn = pluggedIn; -} - -void WiredNetworkDevice::propertiesChanged(const QVariantMap &properties) -{ - if (properties.contains("Carrier")) - setPluggedIn(properties.value("Carrier").toBool()); + Q_UNUSED(interface_name) + Q_UNUSED(invalidated_properties) + if (changed_properties.contains("Carrier")) { + m_pluggedIn = changed_properties.value("Carrier").toBool(); + emit pluggedInChanged(m_pluggedIn); + } + emit deviceChanged(); } QDebug operator<<(QDebug debug, WiredNetworkDevice *networkDevice) diff --git a/libnymea-networkmanager/wirednetworkdevice.h b/libnymea-networkmanager/wirednetworkdevice.h index c223509..d526ada 100644 --- a/libnymea-networkmanager/wirednetworkdevice.h +++ b/libnymea-networkmanager/wirednetworkdevice.h @@ -46,6 +46,12 @@ public: int bitRate() const; bool pluggedIn() const; +signals: + void pluggedInChanged(bool pluggedIn); + +private slots: + void propertiesChanged(const QString &interface_name, const QVariantMap &changed_properties, const QStringList &invalidated_properties); + private: QDBusInterface *m_wiredInterface = nullptr; @@ -53,13 +59,6 @@ private: int m_bitRate = 0; bool m_pluggedIn = false; - void setMacAddress(const QString &macAddress); - void setBitRate(int bitRate); - void setPluggedIn(bool pluggedIn); - -private slots: - void propertiesChanged(const QVariantMap &properties); - }; QDebug operator<<(QDebug debug, WiredNetworkDevice *networkDevice); diff --git a/libnymea-networkmanager/wirelessnetworkdevice.cpp b/libnymea-networkmanager/wirelessnetworkdevice.cpp index 40227c8..9018ef4 100644 --- a/libnymea-networkmanager/wirelessnetworkdevice.cpp +++ b/libnymea-networkmanager/wirelessnetworkdevice.cpp @@ -219,28 +219,31 @@ void WirelessNetworkDevice::accessPointRemoved(const QDBusObjectPath &objectPath accessPoint->deleteLater(); } -void WirelessNetworkDevice::propertiesChanged(const QVariantMap &properties) +void WirelessNetworkDevice::propertiesChanged(const QString &interface_name, const QVariantMap &changed_properties, const QStringList &invalidated_properties) { + Q_UNUSED(interface_name) + Q_UNUSED(invalidated_properties) + //qCDebug(dcNetworkManager()) << "WirelessNetworkDevice: Property changed" << properties; - if (properties.contains("Bitrate")) { - m_bitRate = properties.value("Bitrate").toInt() / 1000; + if (changed_properties.contains("Bitrate")) { + m_bitRate = changed_properties.value("Bitrate").toInt() / 1000; emit bitRateChanged(m_bitRate); } - if (properties.contains("Mode")) { + if (changed_properties.contains("Mode")) { m_wirelessMode = static_cast(m_wirelessInterface->property("Mode").toUInt()); emit wirelessModeChanged(m_wirelessMode); } // Note: available since 1.12 (-1 means never scanned) - if (properties.contains("LastScan")) { + if (changed_properties.contains("LastScan")) { m_lastScan = m_wirelessInterface->property("LastScan").toInt(); emit lastScanChanged(m_lastScan); } - if (properties.contains("ActiveAccessPoint")) { - setActiveAccessPoint(qdbus_cast(properties.value("ActiveAccessPoint"))); + if (changed_properties.contains("ActiveAccessPoint")) { + setActiveAccessPoint(qdbus_cast(changed_properties.value("ActiveAccessPoint"))); } emit deviceChanged(); diff --git a/libnymea-networkmanager/wirelessnetworkdevice.h b/libnymea-networkmanager/wirelessnetworkdevice.h index 667734c..b066e3a 100644 --- a/libnymea-networkmanager/wirelessnetworkdevice.h +++ b/libnymea-networkmanager/wirelessnetworkdevice.h @@ -78,7 +78,7 @@ signals: private slots: void accessPointAdded(const QDBusObjectPath &objectPath); void accessPointRemoved(const QDBusObjectPath &objectPath); - void propertiesChanged(const QVariantMap &properties); + void propertiesChanged(const QString &interface_name, const QVariantMap &changed_properties, const QStringList &invalidated_properties); private: QDBusInterface *m_wirelessInterface = nullptr;