#pragma once #include #include #include #include #include #include #include "../wifi.hpp" #include "accesspoint.hpp" #include "connection.hpp" #include "dbus_nm_wireless.h" #include "device.hpp" #include "enums.hpp" namespace qs::dbus { template <> struct DBusDataTransform { using Wire = quint32; using Data = qs::network::NMWirelessCapabilities::Enum; static DBusResult fromWire(Wire wire); }; template <> struct DBusDataTransform { using Wire = qint64; using Data = QDateTime; static DBusResult fromWire(Wire wire); }; } // namespace qs::dbus namespace qs::network { // NMWirelessNetwork aggregates all related NMActiveConnection, NMAccessPoint, and NMConnectionSetting objects. class NMWirelessNetwork: public QObject { Q_OBJECT; public: explicit NMWirelessNetwork(QString ssid, QObject* parent = nullptr); void addAccessPoint(NMAccessPoint* ap); void addConnection(NMConnectionSettings* conn); void addActiveConnection(NMActiveConnection* active); void forget(); [[nodiscard]] QString ssid() const { return this->mSsid; }; [[nodiscard]] quint8 signalStrength() const { return this->bSignalStrength; }; [[nodiscard]] WifiSecurityType::Enum security() const { return this->bSecurity; }; [[nodiscard]] NMConnectionState::Enum state() const { return this->bState; }; [[nodiscard]] bool known() const { return this->bKnown; }; [[nodiscard]] NMConnectionStateReason::Enum reason() const { return this->bReason; }; [[nodiscard]] NMAccessPoint* referenceAp() const { return this->mReferenceAp; }; [[nodiscard]] NMConnectionSettings* referenceConnection() const { return this->mReferenceConn; }; [[nodiscard]] QList accessPoints() const { return this->mAccessPoints.values(); }; [[nodiscard]] QList connections() const { return this->mConnections.values(); } [[nodiscard]] QBindable bindableActiveApPath() { return &this->bActiveApPath; }; [[nodiscard]] QBindable bindableVisible() { return &this->bVisible; }; [[nodiscard]] bool visible() const { return this->bVisible; }; signals: void disappeared(); void visibilityChanged(bool visible); void signalStrengthChanged(quint8 signal); void stateChanged(NMConnectionState::Enum state); void knownChanged(bool known); void securityChanged(WifiSecurityType::Enum security); void reasonChanged(NMConnectionStateReason::Enum reason); void capabilitiesChanged(NMWirelessCapabilities::Enum caps); void activeApPathChanged(QString path); private: void updateReferenceAp(); void updateReferenceConnection(); QString mSsid; QHash mAccessPoints; QHash mConnections; NMAccessPoint* mReferenceAp = nullptr; NMConnectionSettings* mReferenceConn = nullptr; NMActiveConnection* mActiveConnection = nullptr; // clang-format off Q_OBJECT_BINDABLE_PROPERTY(NMWirelessNetwork, bool, bVisible, &NMWirelessNetwork::visibilityChanged); Q_OBJECT_BINDABLE_PROPERTY(NMWirelessNetwork, bool, bKnown, &NMWirelessNetwork::knownChanged); Q_OBJECT_BINDABLE_PROPERTY(NMWirelessNetwork, WifiSecurityType::Enum, bSecurity, &NMWirelessNetwork::securityChanged); Q_OBJECT_BINDABLE_PROPERTY(NMWirelessNetwork, NMConnectionStateReason::Enum, bReason, &NMWirelessNetwork::reasonChanged); Q_OBJECT_BINDABLE_PROPERTY(NMWirelessNetwork, NMConnectionState::Enum, bState, &NMWirelessNetwork::stateChanged); Q_OBJECT_BINDABLE_PROPERTY(NMWirelessNetwork, quint8, bSignalStrength, &NMWirelessNetwork::signalStrengthChanged); Q_OBJECT_BINDABLE_PROPERTY(NMWirelessNetwork, QString, bActiveApPath, &NMWirelessNetwork::activeApPathChanged); // clang-format on }; // Proxy of a /org/freedesktop/NetworkManager/Device/* object. // Extends NMDevice to also include members from the org.freedesktop.NetworkManager.Device.Wireless interface // Owns the lifetime of NMAccessPoints(s), NMWirelessNetwork(s), frontend WifiNetwork(s). class NMWirelessDevice: public NMDevice { Q_OBJECT; public: explicit NMWirelessDevice(const QString& path, QObject* parent = nullptr); [[nodiscard]] bool isValid() const override; [[nodiscard]] NMWirelessCapabilities::Enum capabilities() { return this->bCapabilities; }; [[nodiscard]] const QDBusObjectPath& activeApPath() { return this->bActiveAccessPoint; }; [[nodiscard]] NM80211Mode::Enum mode() { return this->bMode; }; [[nodiscard]] QBindable bindableScanning() { return &this->bScanning; }; signals: void accessPointLoaded(NMAccessPoint* ap); void accessPointRemoved(NMAccessPoint* ap); void networkAdded(WifiNetwork* net); void networkRemoved(WifiNetwork* net); void lastScanChanged(QDateTime lastScan); void scanningChanged(bool scanning); void capabilitiesChanged(NMWirelessCapabilities::Enum caps); void activeAccessPointChanged(const QDBusObjectPath& path); void modeChanged(NM80211Mode::Enum mode); private slots: void onAccessPointAdded(const QDBusObjectPath& path); void onAccessPointRemoved(const QDBusObjectPath& path); void onAccessPointLoaded(NMAccessPoint* ap); void onConnectionLoaded(NMConnectionSettings* conn); void onActiveConnectionLoaded(NMActiveConnection* active); void onScanTimeout(); void onScanningChanged(bool scanning); private: void registerAccessPoint(const QString& path); void registerFrontendNetwork(NMWirelessNetwork* net); void removeFrontendNetwork(NMWirelessNetwork* net); void removeNetwork(); bool checkVisibility(WifiNetwork* net); void registerAccessPoints(); void initWireless(); NMWirelessNetwork* registerNetwork(const QString& ssid); QHash mAccessPoints; QHash mNetworks; QHash mFrontendNetworks; QDateTime mLastScanRequest; QTimer mScanTimer; qint32 mScanIntervalMs = 10001; // clang-format off Q_OBJECT_BINDABLE_PROPERTY(NMWirelessDevice, bool, bScanning, &NMWirelessDevice::scanningChanged); Q_OBJECT_BINDABLE_PROPERTY(NMWirelessDevice, QDateTime, bLastScan, &NMWirelessDevice::lastScanChanged); Q_OBJECT_BINDABLE_PROPERTY(NMWirelessDevice, NMWirelessCapabilities::Enum, bCapabilities, &NMWirelessDevice::capabilitiesChanged); Q_OBJECT_BINDABLE_PROPERTY(NMWirelessDevice, QDBusObjectPath, bActiveAccessPoint, &NMWirelessDevice::activeAccessPointChanged); Q_OBJECT_BINDABLE_PROPERTY(NMWirelessDevice, NM80211Mode::Enum, bMode, &NMWirelessDevice::modeChanged); QS_DBUS_BINDABLE_PROPERTY_GROUP(NMWireless, wirelessProperties); QS_DBUS_PROPERTY_BINDING(NMWirelessDevice, pLastScan, bLastScan, wirelessProperties, "LastScan"); QS_DBUS_PROPERTY_BINDING(NMWirelessDevice, pCapabilities, bCapabilities, wirelessProperties, "WirelessCapabilities"); QS_DBUS_PROPERTY_BINDING(NMWirelessDevice, pActiveAccessPoint, bActiveAccessPoint, wirelessProperties, "ActiveAccessPoint"); QS_DBUS_PROPERTY_BINDING(NMWirelessDevice, pMode, bMode, wirelessProperties, "Mode"); // clang-format on DBusNMWirelessProxy* wirelessProxy = nullptr; }; } // namespace qs::network