ui/networking: async dbus calls (#23535)

* async dbus calls

* simplify get ip address

* Revert "simplify get ip address"

This reverts commit 7ade7ec57d.

* cleanup getConnectionPath()

* remove unused functions

* cleanup

* rename to getIp4Address

* clenup class definition
pull/23559/head
Dean Lee 2022-01-18 04:12:58 +08:00 committed by GitHub
parent e38564b154
commit f7932f874d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 58 additions and 67 deletions

View File

@ -31,6 +31,12 @@ T call(const QString &path, const QString &interface, const QString &method, Arg
return T();
}
template <typename... Args>
QDBusPendingCall asyncCall(const QString &path, const QString &interface, const QString &method, Args &&...args) {
QDBusInterface nm = QDBusInterface(NM_DBUS_SERVICE, path, interface, QDBusConnection::systemBus());
return nm.asyncCall(method, args...);
}
WifiManager::WifiManager(QObject *parent) : QObject(parent) {
qDBusRegisterMetaType<Connection>();
qDBusRegisterMetaType<IpConfig>();
@ -78,39 +84,39 @@ void WifiManager::stop() {
void WifiManager::refreshNetworks() {
if (adapter.isEmpty() || !timer.isActive()) return;
seenNetworks.clear();
ipv4_address = get_ipv4_address();
QDBusReply<QList<QDBusObjectPath>> response = call(adapter, NM_DBUS_INTERFACE_DEVICE_WIRELESS, "GetAllAccessPoints");
for (const QDBusObjectPath &path : response.value()) {
const QByteArray &ssid = get_property(path.path(), "Ssid");
unsigned int strength = get_ap_strength(path.path());
if (ssid.isEmpty() || (seenNetworks.contains(ssid) &&
strength <= seenNetworks.value(ssid).strength)) {
continue;
}
SecurityType security = getSecurityType(path.path());
ConnectedType ctype;
QString activeSsid = (activeAp != "" && activeAp != "/") ? get_property(activeAp, "Ssid") : "";
if (ssid != activeSsid) {
ctype = ConnectedType::DISCONNECTED;
} else {
if (ssid == connecting_to_network) {
ctype = ConnectedType::CONNECTING;
} else {
ctype = ConnectedType::CONNECTED;
}
}
Network network = {ssid, strength, ctype, security};
seenNetworks[ssid] = network;
}
emit refreshSignal();
QDBusPendingCall pending_call = asyncCall(adapter, NM_DBUS_INTERFACE_DEVICE_WIRELESS, "GetAllAccessPoints");
QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(pending_call);
QObject::connect(watcher, &QDBusPendingCallWatcher::finished, this, &WifiManager::refreshFinished);
}
QString WifiManager::get_ipv4_address() {
if (raw_adapter_state != NM_DEVICE_STATE_ACTIVATED) {
return "";
void WifiManager::refreshFinished(QDBusPendingCallWatcher *watcher) {
ipv4_address = getIp4Address();
seenNetworks.clear();
const QDBusReply<QList<QDBusObjectPath>> wather_reply = *watcher;
for (const QDBusObjectPath &path : wather_reply.value()) {
QDBusReply<QVariantMap> replay = call(path.path(), NM_DBUS_INTERFACE_PROPERTIES, "GetAll", NM_DBUS_INTERFACE_ACCESS_POINT);
auto properties = replay.value();
const QByteArray ssid = properties["Ssid"].toByteArray();
uint32_t strength = properties["Strength"].toUInt();
if (ssid.isEmpty() || (seenNetworks.contains(ssid) && strength <= seenNetworks[ssid].strength)) continue;
SecurityType security = getSecurityType(properties);
ConnectedType ctype = ConnectedType::DISCONNECTED;
if (path.path() == activeAp) {
ctype = (ssid == connecting_to_network) ? ConnectedType::CONNECTING : ConnectedType::CONNECTED;
}
seenNetworks[ssid] = {ssid, strength, ctype, security};
}
emit refreshSignal();
watcher->deleteLater();
}
QString WifiManager::getIp4Address() {
if (raw_adapter_state != NM_DEVICE_STATE_ACTIVATED) return "";
for (const auto &p : getActiveConnections()) {
QString type = call<QString>(p.path(), NM_DBUS_INTERFACE_PROPERTIES, "Get", NM_DBUS_INTERFACE_ACTIVE_CONNECTION, "Type");
if (type == "802-11-wireless") {
@ -129,10 +135,10 @@ QString WifiManager::get_ipv4_address() {
return "";
}
SecurityType WifiManager::getSecurityType(const QString &path) {
int sflag = get_property(path, "Flags").toInt();
int wpaflag = get_property(path, "WpaFlags").toInt();
int rsnflag = get_property(path, "RsnFlags").toInt();
SecurityType WifiManager::getSecurityType(const QVariantMap &properties) {
int sflag = properties["Flags"].toUInt();
int wpaflag = properties["WpaFlags"].toUInt();
int rsnflag = properties["RsnFlags"].toUInt();
int wpa_props = wpaflag | rsnflag;
// obtained by looking at flags of networks in the office as reported by an Android phone
@ -181,13 +187,14 @@ void WifiManager::deactivateConnectionBySsid(const QString &ssid) {
QString Ssid = get_property(pth.path(), "Ssid");
if (Ssid == ssid) {
deactivateConnection(active_connection);
return;
}
}
}
}
void WifiManager::deactivateConnection(const QDBusObjectPath &path) {
call(NM_DBUS_PATH, NM_DBUS_INTERFACE, "DeactivateConnection", QVariant::fromValue(path));
asyncCall(NM_DBUS_PATH, NM_DBUS_INTERFACE, "DeactivateConnection", QVariant::fromValue(path));
}
QVector<QDBusObjectPath> WifiManager::getActiveConnections() {
@ -219,17 +226,13 @@ uint WifiManager::getAdapterType(const QDBusObjectPath &path) {
}
void WifiManager::requestScan() {
call(adapter, NM_DBUS_INTERFACE_DEVICE_WIRELESS, "RequestScan", QVariantMap());
asyncCall(adapter, NM_DBUS_INTERFACE_DEVICE_WIRELESS, "RequestScan", QVariantMap());
}
QByteArray WifiManager::get_property(const QString &network_path , const QString &property) {
return call<QByteArray>(network_path, NM_DBUS_INTERFACE_PROPERTIES, "Get", NM_DBUS_INTERFACE_ACCESS_POINT, property);
}
unsigned int WifiManager::get_ap_strength(const QString &network_path) {
return call<unsigned int>(network_path, NM_DBUS_INTERFACE_PROPERTIES, "Get", NM_DBUS_INTERFACE_ACCESS_POINT, "Strength");
}
QString WifiManager::getAdapter(const uint adapter_type) {
QDBusReply<QList<QDBusObjectPath>> response = call(NM_DBUS_PATH, NM_DBUS_INTERFACE, "GetDevices");
for (const QDBusObjectPath &path : response.value()) {
@ -281,19 +284,8 @@ void WifiManager::newConnection(const QDBusObjectPath &path) {
}
}
void WifiManager::disconnect() {
if (activeAp != "" && activeAp != "/") {
deactivateConnectionBySsid(get_property(activeAp, "Ssid"));
}
}
QDBusObjectPath WifiManager::getConnectionPath(const QString &ssid) {
for (const QString &conn_ssid : knownConnections) {
if (ssid == conn_ssid) {
return knownConnections.key(conn_ssid);
}
}
return QDBusObjectPath();
return knownConnections.key(ssid);
}
Connection WifiManager::getConnectionSettings(const QDBusObjectPath &path) {
@ -316,14 +308,14 @@ void WifiManager::activateWifiConnection(const QString &ssid) {
const QDBusObjectPath &path = getConnectionPath(ssid);
if (!path.path().isEmpty()) {
connecting_to_network = ssid;
call(NM_DBUS_PATH, NM_DBUS_INTERFACE, "ActivateConnection", QVariant::fromValue(path), QVariant::fromValue(QDBusObjectPath(adapter)), QVariant::fromValue(QDBusObjectPath("/")));
asyncCall(NM_DBUS_PATH, NM_DBUS_INTERFACE, "ActivateConnection", QVariant::fromValue(path), QVariant::fromValue(QDBusObjectPath(adapter)), QVariant::fromValue(QDBusObjectPath("/")));
}
}
void WifiManager::activateModemConnection(const QDBusObjectPath &path) {
QString modem = getAdapter(NM_DEVICE_TYPE_MODEM);
if (!path.path().isEmpty() && !modem.isEmpty()) {
call(NM_DBUS_PATH, NM_DBUS_INTERFACE, "ActivateConnection", QVariant::fromValue(path), QVariant::fromValue(QDBusObjectPath(modem)), QVariant::fromValue(QDBusObjectPath("/")));
asyncCall(NM_DBUS_PATH, NM_DBUS_INTERFACE, "ActivateConnection", QVariant::fromValue(path), QVariant::fromValue(QDBusObjectPath(modem)), QVariant::fromValue(QDBusObjectPath("/")));
}
}

View File

@ -37,29 +37,24 @@ class WifiManager : public QObject {
Q_OBJECT
public:
QMap<QString, Network> seenNetworks;
QMap<QDBusObjectPath, QString> knownConnections;
QString ipv4_address;
explicit WifiManager(QObject* parent);
void start();
void stop();
void requestScan();
QMap<QString, Network> seenNetworks;
QMap<QDBusObjectPath, QString> knownConnections;
QDBusObjectPath lteConnectionPath;
QString ipv4_address;
void refreshNetworks();
void forgetConnection(const QString &ssid);
bool isKnownConnection(const QString &ssid);
void activateWifiConnection(const QString &ssid);
void activateModemConnection(const QDBusObjectPath &path);
NetworkType currentNetworkType();
void updateGsmSettings(bool roaming, QString apn);
void connect(const Network &ssid, const QString &password = {}, const QString &username = {});
void disconnect();
// Tethering functions
void setTetheringEnabled(bool enabled);
bool isTetheringEnabled();
void addTetheringConnection();
void changeTetheringPassword(const QString &newPassword);
QString getTetheringPassword();
@ -70,23 +65,26 @@ private:
QString connecting_to_network;
QString tethering_ssid;
const QString defaultTetheringPassword = "swagswagcomma";
QString activeAp;
QDBusObjectPath lteConnectionPath;
QString getAdapter(const uint = NM_DEVICE_TYPE_WIFI);
uint getAdapterType(const QDBusObjectPath &path);
bool isWirelessAdapter(const QDBusObjectPath &path);
QString get_ipv4_address();
QString getIp4Address();
void connect(const QByteArray &ssid, const QString &username, const QString &password, SecurityType security_type);
QString activeAp;
void deactivateConnectionBySsid(const QString &ssid);
void deactivateConnection(const QDBusObjectPath &path);
QVector<QDBusObjectPath> getActiveConnections();
QByteArray get_property(const QString &network_path, const QString &property);
unsigned int get_ap_strength(const QString &network_path);
SecurityType getSecurityType(const QString &path);
SecurityType getSecurityType(const QVariantMap &properties);
QDBusObjectPath getConnectionPath(const QString &ssid);
Connection getConnectionSettings(const QDBusObjectPath &path);
void initConnections();
void setup();
void refreshNetworks();
void activateModemConnection(const QDBusObjectPath &path);
void addTetheringConnection();
signals:
void wrongPassword(const QString &ssid);
@ -98,4 +96,5 @@ private slots:
void deviceAdded(const QDBusObjectPath &path);
void connectionRemoved(const QDBusObjectPath &path);
void newConnection(const QDBusObjectPath &path);
void refreshFinished(QDBusPendingCallWatcher *call);
};