Skip to content

Commit 840e6ec

Browse files
committed
feat: merge backend connections + networks -> WifiNetwork.
Adds NMWirelessManager which merges identical NMWirelessNetworks (groups of APs with the same SSID) and NMConnectionAdapters (saved connection settings to wifi networks), and creates WifiNetworks on the frontend. The manager takes a similar approach to plasma-nm and nm-applet. Adds utilities to determine a connections security type and a networks best choice for security, in sync with nm_utils_security_valid from nmcli.
1 parent be80d20 commit 840e6ec

20 files changed

+1215
-433
lines changed

src/network/CMakeLists.txt

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ qt_add_dbus_interface(NM_DBUS_INTERFACES
4141

4242
set_source_files_properties(nm/org.freedesktop.NetworkManager.Settings.Connection.xml PROPERTIES
4343
CLASSNAME DBusNMConnectionProxy
44-
NO_NAMESPACE TRUE
44+
INCLUDE ${CMAKE_CURRENT_SOURCE_DIR}/nm/dbus_types.hpp
4545
)
4646

4747
qt_add_dbus_interface(NM_DBUS_INTERFACES
@@ -53,9 +53,11 @@ qt_add_library(quickshell-network STATIC
5353
frontend.cpp
5454
nm/backend.cpp
5555
nm/device.cpp
56+
nm/connection.cpp
5657
nm/accesspoint.cpp
5758
nm/wireless.cpp
58-
nm/connection.cpp
59+
nm/utils.cpp
60+
nm/enums.hpp
5961
${NM_DBUS_INTERFACES}
6062
)
6163

src/network/frontend.cpp

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -92,9 +92,13 @@ void NetworkWifiDevice::scan() {
9292
this->requestScan();
9393
}
9494

95-
void NetworkWifiDevice::addNetwork(WifiNetwork* network) { mNetworks.insertObject(network); }
95+
void NetworkWifiDevice::wifiNetworkAdded(WifiNetwork* network) {
96+
this->mNetworks.insertObject(network);
97+
}
9698

97-
void NetworkWifiDevice::removeNetwork(WifiNetwork* network) { mNetworks.removeObject(network); }
99+
void NetworkWifiDevice::wifiNetworkRemoved(WifiNetwork* network) {
100+
this->mNetworks.removeObject(network);
101+
}
98102

99103
WifiNetwork::WifiNetwork(QObject* parent): QObject(parent) {};
100104

@@ -119,6 +123,20 @@ void WifiNetwork::setConnected(bool connected) {
119123
}
120124
}
121125

126+
void WifiNetwork::setNmSecurity(NMWirelessSecurityType::Enum security) {
127+
if (this->bNmSecurity != security) {
128+
this->bNmSecurity = security;
129+
emit this->nmSecurityChanged();
130+
}
131+
}
132+
133+
void WifiNetwork::setKnown(bool known) {
134+
if (this->bKnown != known) {
135+
this->bKnown = known;
136+
emit this->knownChanged();
137+
}
138+
}
139+
122140
Network::Network(QObject* parent): QObject(parent) {
123141
// Try each backend
124142

src/network/frontend.hpp

Lines changed: 24 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11,45 +11,63 @@
1111
#include <qtypes.h>
1212

1313
#include "../core/model.hpp"
14+
#include "nm/enums.hpp"
1415

1516
namespace qs::network {
1617

17-
///! A wifi network
18+
///! A wifi network represents an available connection or access point on a wireless device.
1819
class WifiNetwork: public QObject {
1920
Q_OBJECT;
2021
QML_ELEMENT;
21-
QML_UNCREATABLE("Wifi networks can only be acquired through Network");
22+
QML_UNCREATABLE("Wifi items can only be acquired through Network");
2223
// clang-format off
23-
/// The service set identifier of the wifi network
24+
/// The SSID (service set identifier) of the wifi network
2425
Q_PROPERTY(QString ssid READ default NOTIFY ssidChanged BINDABLE bindableSsid);
2526
// The current signal strength of the best access point on the network, in percent.
2627
Q_PROPERTY(quint8 signalStrength READ default NOTIFY signalStrengthChanged BINDABLE bindableSignalStrength);
27-
/// True if the wireless device is curerntly connected to this wifi network.
28+
/// True if the wireless device is currently connected to this wifi network.
2829
Q_PROPERTY(bool connected READ default NOTIFY connectedChanged BINDABLE bindableConnected);
30+
/// The security type of the wifi network when the backend is NetworkManager. Otherwise NMWirelessSecurityType::Unknown.
31+
Q_PROPERTY(NMWirelessSecurityType::Enum nmSecurity READ default NOTIFY nmSecurityChanged BINDABLE bindableNmSecurity);
32+
/// True if the wifi network has a known connection profile saved.
33+
Q_PROPERTY(bool known READ default NOTIFY knownChanged BINDABLE bindableKnown);
2934
// clang-format on
3035

3136
signals:
3237
void ssidChanged();
3338
void signalStrengthChanged();
3439
void connectedChanged();
40+
void nmSecurityChanged();
41+
void knownChanged();
42+
void requestConnect();
3543

3644
public slots:
3745
void setSsid(const QString& ssid);
3846
void setSignalStrength(quint8 signalStrength);
3947
void setConnected(bool connected);
48+
void setNmSecurity(NMWirelessSecurityType::Enum security);
49+
void setKnown(bool known);
4050

4151
public:
4252
explicit WifiNetwork(QObject* parent = nullptr);
4353

4454
[[nodiscard]] QBindable<QString> bindableSsid() const { return &this->bSsid; };
4555
[[nodiscard]] QBindable<quint8> bindableSignalStrength() const { return &this->bSignalStrength; };
4656
[[nodiscard]] QBindable<bool> bindableConnected() const { return &this->bConnected; };
57+
[[nodiscard]] QBindable<NMWirelessSecurityType::Enum> bindableNmSecurity() const {
58+
return &this->bNmSecurity;
59+
};
60+
[[nodiscard]] QBindable<bool> bindableKnown() const { return &this->bKnown; };
61+
62+
// Q_INVOKABLE void connect();
4763

4864
private:
4965
// clang-format off
5066
Q_OBJECT_BINDABLE_PROPERTY(WifiNetwork, QString, bSsid, &WifiNetwork::ssidChanged);
5167
Q_OBJECT_BINDABLE_PROPERTY(WifiNetwork, quint8, bSignalStrength, &WifiNetwork::signalStrengthChanged);
5268
Q_OBJECT_BINDABLE_PROPERTY(WifiNetwork, bool, bConnected, &WifiNetwork::connectedChanged);
69+
Q_OBJECT_BINDABLE_PROPERTY(WifiNetwork, NMWirelessSecurityType::Enum, bNmSecurity, &WifiNetwork::nmSecurityChanged);
70+
Q_OBJECT_BINDABLE_PROPERTY(WifiNetwork, bool, bKnown, &WifiNetwork::knownChanged);
5371
// clang-format on
5472
};
5573

@@ -160,8 +178,8 @@ class NetworkWifiDevice: public NetworkDevice {
160178

161179
public slots:
162180
void scanComplete();
163-
void addNetwork(WifiNetwork* network);
164-
void removeNetwork(WifiNetwork* network);
181+
void wifiNetworkAdded(WifiNetwork* network);
182+
void wifiNetworkRemoved(WifiNetwork* network);
165183

166184
public:
167185
explicit NetworkWifiDevice(QObject* parent = nullptr);

src/network/nm/accesspoint.cpp

Lines changed: 27 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,27 @@
1111
#include "../../dbus/properties.hpp"
1212
#include "nm/dbus_nm_accesspoint.h"
1313

14-
using namespace qs::dbus;
14+
namespace qs::dbus {
15+
16+
DBusResult<qs::network::NM80211ApFlags::Enum>
17+
DBusDataTransform<qs::network::NM80211ApFlags::Enum>::fromWire(quint32 wire) {
18+
return DBusResult(static_cast<qs::network::NM80211ApFlags::Enum>(wire));
19+
}
20+
21+
DBusResult<qs::network::NM80211ApSecurityFlags::Enum>
22+
DBusDataTransform<qs::network::NM80211ApSecurityFlags::Enum>::fromWire(quint32 wire) {
23+
return DBusResult(static_cast<qs::network::NM80211ApSecurityFlags::Enum>(wire));
24+
}
25+
26+
DBusResult<qs::network::NM80211Mode::Enum>
27+
DBusDataTransform<qs::network::NM80211Mode::Enum>::fromWire(quint32 wire) {
28+
return DBusResult(static_cast<qs::network::NM80211Mode::Enum>(wire));
29+
}
30+
31+
} // namespace qs::dbus
1532

1633
namespace qs::network {
34+
using namespace qs::dbus;
1735

1836
namespace {
1937
Q_LOGGING_CATEGORY(logNetworkManager, "quickshell.network.networkmanager", QtWarningMsg);
@@ -32,6 +50,14 @@ NMAccessPointAdapter::NMAccessPointAdapter(const QString& path, QObject* parent)
3250
return;
3351
}
3452

53+
QObject::connect(
54+
&this->accessPointProperties,
55+
&DBusPropertyGroup::getAllFinished,
56+
this,
57+
[this]() { emit this->ready(); },
58+
Qt::SingleShotConnection
59+
);
60+
3561
this->accessPointProperties.setInterface(this->proxy);
3662
this->accessPointProperties.updateAllViaGetAll();
3763
}
@@ -42,55 +68,4 @@ QString NMAccessPointAdapter::address() const {
4268
}
4369
QString NMAccessPointAdapter::path() const { return this->proxy ? this->proxy->path() : QString(); }
4470

45-
NMWifiNetwork::NMWifiNetwork(QByteArray ssid, QObject* parent)
46-
: QObject(parent)
47-
, mSsid(std::move(ssid)) {}
48-
49-
void NMWifiNetwork::updateSignalStrength() {
50-
quint8 max = 0;
51-
for (auto* ap: mAccessPoints) {
52-
max = qMax(max, ap->getSignal());
53-
}
54-
if (this->bMaxSignal != max) {
55-
this->bMaxSignal = max;
56-
}
57-
}
58-
59-
void NMWifiNetwork::addAccessPoint(NMAccessPointAdapter* ap) {
60-
if (this->mAccessPoints.contains(ap)) {
61-
qCWarning(logNetworkManager) << "Access point" << ap->path() << "was already in AP group";
62-
return;
63-
}
64-
65-
this->mAccessPoints.append(ap);
66-
QObject::connect(
67-
ap,
68-
&NMAccessPointAdapter::signalStrengthChanged,
69-
this,
70-
&NMWifiNetwork::updateSignalStrength
71-
);
72-
this->updateSignalStrength();
73-
}
74-
75-
void NMWifiNetwork::removeAccessPoint(NMAccessPointAdapter* ap) {
76-
if (mAccessPoints.removeOne(ap)) {
77-
QObject::disconnect(ap, nullptr, this, nullptr);
78-
this->updateSignalStrength();
79-
}
80-
}
81-
8271
} // namespace qs::network
83-
84-
namespace qs::dbus {
85-
86-
DBusResult<qs::network::NM80211ApFlags::Enum>
87-
DBusDataTransform<qs::network::NM80211ApFlags::Enum>::fromWire(quint32 wire) {
88-
return DBusResult(static_cast<qs::network::NM80211ApFlags::Enum>(wire));
89-
}
90-
91-
DBusResult<qs::network::NM80211ApSecurityFlags::Enum>
92-
DBusDataTransform<qs::network::NM80211ApSecurityFlags::Enum>::fromWire(quint32 wire) {
93-
return DBusResult(static_cast<qs::network::NM80211ApSecurityFlags::Enum>(wire));
94-
}
95-
96-
} // namespace qs::dbus

src/network/nm/accesspoint.hpp

Lines changed: 18 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -11,50 +11,9 @@
1111
#include <qtypes.h>
1212

1313
#include "../../dbus/properties.hpp"
14+
#include "enums.hpp"
1415
#include "nm/dbus_nm_accesspoint.h"
1516

16-
namespace qs::network {
17-
18-
class NM80211ApFlags: public QObject {
19-
Q_OBJECT;
20-
21-
public:
22-
enum Enum : quint8 {
23-
None = 0,
24-
Privacy = 1,
25-
Wps = 2,
26-
WpsPbc = 4,
27-
WpsPin = 8,
28-
};
29-
Q_ENUM(Enum);
30-
};
31-
32-
class NM80211ApSecurityFlags: public QObject {
33-
Q_OBJECT;
34-
35-
public:
36-
enum Enum : quint16 {
37-
None = 0,
38-
PairWep40 = 1,
39-
PairWep104 = 2,
40-
PairTkip = 4,
41-
PairCcmp = 8,
42-
GroupWep40 = 16,
43-
GroupWep104 = 32,
44-
GroupTkip = 64,
45-
GroupCcmp = 128,
46-
KeyMgmtPsk = 256,
47-
KeyMgmt8021x = 512,
48-
KeyMgmtSae = 1024,
49-
KeyMgmtOwe = 2048,
50-
KeyMgmtOweTm = 4096,
51-
KeyMgmtEapSuiteB192 = 8192,
52-
};
53-
Q_ENUM(Enum);
54-
};
55-
56-
} // namespace qs::network
57-
5817
namespace qs::dbus {
5918

6019
template <>
@@ -71,6 +30,13 @@ struct DBusDataTransform<qs::network::NM80211ApSecurityFlags::Enum> {
7130
static DBusResult<Data> fromWire(Wire wire);
7231
};
7332

33+
template <>
34+
struct DBusDataTransform<qs::network::NM80211Mode::Enum> {
35+
using Wire = quint32;
36+
using Data = qs::network::NM80211Mode::Enum;
37+
static DBusResult<Data> fromWire(Wire wire);
38+
};
39+
7440
} // namespace qs::dbus
7541

7642
namespace qs::network {
@@ -86,14 +52,21 @@ class NMAccessPointAdapter: public QObject {
8652
[[nodiscard]] bool isValid() const;
8753
[[nodiscard]] QString path() const;
8854
[[nodiscard]] QString address() const;
89-
[[nodiscard]] quint8 getSignal() const { return this->bSignalStrength; };
55+
[[nodiscard]] QByteArray ssid() const { return this->bSsid; };
56+
[[nodiscard]] quint8 signalStrength() const { return this->bSignalStrength; };
57+
[[nodiscard]] NM80211ApFlags::Enum flags() const { return this->bFlags; };
58+
[[nodiscard]] NM80211ApSecurityFlags::Enum wpaFlags() const { return this->bWpaFlags; };
59+
[[nodiscard]] NM80211ApSecurityFlags::Enum rsnFlags() const { return this->bRsnFlags; };
60+
[[nodiscard]] NM80211Mode::Enum mode() const { return this->bMode; };
9061

9162
signals:
9263
void ssidChanged(const QByteArray& ssid);
9364
void signalStrengthChanged(quint8 signal);
9465
void wpaFlagsChanged(NM80211ApSecurityFlags::Enum wpaFlags);
9566
void rsnFlagsChanged(NM80211ApSecurityFlags::Enum rsnFlags);
9667
void flagsChanged(NM80211ApFlags::Enum flags);
68+
void modeChanged(NM80211Mode::Enum mode);
69+
void ready();
9770

9871
private:
9972
// clang-format off
@@ -102,40 +75,18 @@ class NMAccessPointAdapter: public QObject {
10275
Q_OBJECT_BINDABLE_PROPERTY(NMAccessPointAdapter, NM80211ApFlags::Enum, bFlags, &NMAccessPointAdapter::flagsChanged);
10376
Q_OBJECT_BINDABLE_PROPERTY(NMAccessPointAdapter, NM80211ApSecurityFlags::Enum, bWpaFlags, &NMAccessPointAdapter::wpaFlagsChanged);
10477
Q_OBJECT_BINDABLE_PROPERTY(NMAccessPointAdapter, NM80211ApSecurityFlags::Enum, bRsnFlags, &NMAccessPointAdapter::rsnFlagsChanged);
78+
Q_OBJECT_BINDABLE_PROPERTY(NMAccessPointAdapter, NM80211Mode::Enum, bMode, &NMAccessPointAdapter::modeChanged);
10579

10680
QS_DBUS_BINDABLE_PROPERTY_GROUP(NMAccessPointAdapter, accessPointProperties);
10781
QS_DBUS_PROPERTY_BINDING(NMAccessPointAdapter, pSsid, bSsid, accessPointProperties, "Ssid");
10882
QS_DBUS_PROPERTY_BINDING(NMAccessPointAdapter, pSignalStrength, bSignalStrength, accessPointProperties, "Strength");
10983
QS_DBUS_PROPERTY_BINDING(NMAccessPointAdapter, pFlags, bFlags, accessPointProperties, "Flags");
11084
QS_DBUS_PROPERTY_BINDING(NMAccessPointAdapter, pWpaFlags, bWpaFlags, accessPointProperties, "WpaFlags");
11185
QS_DBUS_PROPERTY_BINDING(NMAccessPointAdapter, pRsnFlags, bRsnFlags, accessPointProperties, "RsnFlags");
86+
QS_DBUS_PROPERTY_BINDING(NMAccessPointAdapter, pMode, bMode, accessPointProperties, "Mode");
11287
// clang-format on
11388

11489
DBusNMAccessPointProxy* proxy = nullptr;
11590
};
11691

117-
// NMWifiNetwork represents a wireless network, which aggregates all access points with
118-
// the same SSID. It also provides signals and slots for a frontend WifiNetwork.
119-
class NMWifiNetwork: public QObject {
120-
Q_OBJECT;
121-
122-
public:
123-
explicit NMWifiNetwork(QByteArray ssid, QObject* parent = nullptr);
124-
void addAccessPoint(NMAccessPointAdapter* ap);
125-
void removeAccessPoint(NMAccessPointAdapter* ap);
126-
void updateSignalStrength();
127-
[[nodiscard]] bool isEmpty() const { return this->mAccessPoints.isEmpty(); };
128-
129-
signals:
130-
void signalStrengthChanged(quint8 signal);
131-
132-
private:
133-
QList<NMAccessPointAdapter*> mAccessPoints;
134-
QByteArray mSsid;
135-
136-
// clang-format off
137-
Q_OBJECT_BINDABLE_PROPERTY(NMWifiNetwork, quint8, bMaxSignal, &NMWifiNetwork::signalStrengthChanged);
138-
// clang-format on
139-
};
140-
14192
} // namespace qs::network

0 commit comments

Comments
 (0)