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