|
|
|
@ -1,11 +1,26 @@ |
|
|
|
|
#include <algorithm> |
|
|
|
|
#include <set> |
|
|
|
|
#include <stdlib.h> |
|
|
|
|
#include <iostream> |
|
|
|
|
#include "wifiManager.hpp" |
|
|
|
|
#include "common/params.h" |
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* We are using a NetworkManager DBUS API : https://developer.gnome.org/NetworkManager/1.26/spec.html
|
|
|
|
|
* */ |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// https://developer.gnome.org/NetworkManager/1.26/nm-dbus-types.html#NM80211ApFlags
|
|
|
|
|
const int NM_802_11_AP_FLAGS_PRIVACY = 0x00000001; |
|
|
|
|
|
|
|
|
|
// https://developer.gnome.org/NetworkManager/1.26/nm-dbus-types.html#NM80211ApSecurityFlags
|
|
|
|
|
const int NM_802_11_AP_SEC_PAIR_WEP40 = 0x00000001; |
|
|
|
|
const int NM_802_11_AP_SEC_PAIR_WEP104 = 0x00000002; |
|
|
|
|
const int NM_802_11_AP_SEC_GROUP_WEP40 = 0x00000010; |
|
|
|
|
const int NM_802_11_AP_SEC_GROUP_WEP104 = 0x00000020; |
|
|
|
|
const int NM_802_11_AP_SEC_KEY_MGMT_PSK = 0x00000100; |
|
|
|
|
const int NM_802_11_AP_SEC_KEY_MGMT_802_1X = 0x00000200; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
QString nm_path = "/org/freedesktop/NetworkManager"; |
|
|
|
|
QString nm_settings_path = "/org/freedesktop/NetworkManager/Settings"; |
|
|
|
|
|
|
|
|
@ -40,12 +55,14 @@ bool compare_by_strength(const Network &a, const Network &b){ |
|
|
|
|
return a.strength > b.strength; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
WifiManager::WifiManager(){ |
|
|
|
|
qDBusRegisterMetaType<Connection>(); |
|
|
|
|
qDBusRegisterMetaType<IpConfig>(); |
|
|
|
|
connecting_to_network = ""; |
|
|
|
|
adapter = get_adapter(); |
|
|
|
|
has_adapter = adapter != ""; |
|
|
|
|
if(has_adapter){ |
|
|
|
|
if (has_adapter){ |
|
|
|
|
QDBusInterface nm(nm_service, adapter, device_iface, bus); |
|
|
|
|
bus.connect(nm_service, adapter, device_iface, "StateChanged", this, SLOT(change(unsigned int, unsigned int, unsigned int))); |
|
|
|
|
|
|
|
|
@ -54,6 +71,13 @@ WifiManager::WifiManager(){ |
|
|
|
|
raw_adapter_state = get_response<uint>(response); |
|
|
|
|
change(raw_adapter_state, 0, 0); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// Compute tethering ssid as "Weedle" + first 4 characters of a dongle id
|
|
|
|
|
tethering_ssid = "weedle"; |
|
|
|
|
std::string bytes = Params().get("DongleId"); |
|
|
|
|
if (bytes.length() >= 4){ |
|
|
|
|
tethering_ssid+="-"+QString::fromStdString(bytes.substr(0,4)); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void WifiManager::refreshNetworks(){ |
|
|
|
@ -64,7 +88,7 @@ void WifiManager::refreshNetworks(){ |
|
|
|
|
seen_ssids.clear(); |
|
|
|
|
|
|
|
|
|
for (Network &network : get_networks()){ |
|
|
|
|
if(seen_ssids.count(network.ssid)){ |
|
|
|
|
if (seen_ssids.count(network.ssid)){ |
|
|
|
|
continue; |
|
|
|
|
} |
|
|
|
|
seen_ssids.push_back(network.ssid); |
|
|
|
@ -89,12 +113,12 @@ QList<Network> WifiManager::get_networks(){ |
|
|
|
|
unsigned int strength = get_ap_strength(path.path()); |
|
|
|
|
SecurityType security = getSecurityType(path.path()); |
|
|
|
|
ConnectedType ctype; |
|
|
|
|
if(path.path() != active_ap){ |
|
|
|
|
if (path.path() != active_ap){ |
|
|
|
|
ctype = ConnectedType::DISCONNECTED; |
|
|
|
|
}else{ |
|
|
|
|
if(ssid == connecting_to_network){ |
|
|
|
|
}else { |
|
|
|
|
if (ssid == connecting_to_network){ |
|
|
|
|
ctype = ConnectedType::CONNECTING; |
|
|
|
|
}else{ |
|
|
|
|
}else { |
|
|
|
|
ctype = ConnectedType::CONNECTED; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
@ -116,9 +140,12 @@ SecurityType WifiManager::getSecurityType(QString path){ |
|
|
|
|
int rsnflag = get_property(path, "RsnFlags").toInt(); |
|
|
|
|
int wpa_props = wpaflag | rsnflag; |
|
|
|
|
|
|
|
|
|
if(sflag == 0){ |
|
|
|
|
// obtained by looking at flags of networks in the office as reported by an Android phone
|
|
|
|
|
const int supports_wpa = NM_802_11_AP_SEC_PAIR_WEP40 | NM_802_11_AP_SEC_PAIR_WEP104 | NM_802_11_AP_SEC_GROUP_WEP40 | NM_802_11_AP_SEC_GROUP_WEP104 | NM_802_11_AP_SEC_KEY_MGMT_PSK; |
|
|
|
|
|
|
|
|
|
if (sflag == 0){ |
|
|
|
|
return SecurityType::OPEN; |
|
|
|
|
} else if((sflag & 0x1) && (wpa_props & (0x333) && !(wpa_props & 0x200))) { |
|
|
|
|
} else if ((sflag & NM_802_11_AP_FLAGS_PRIVACY) && (wpa_props & supports_wpa) && !(wpa_props & NM_802_11_AP_SEC_KEY_MGMT_802_1X)) { |
|
|
|
|
return SecurityType::WPA; |
|
|
|
|
} else { |
|
|
|
|
return SecurityType::UNSUPPORTED; |
|
|
|
@ -135,10 +162,7 @@ void WifiManager::connect(Network n, QString password){ |
|
|
|
|
|
|
|
|
|
void WifiManager::connect(Network n, QString username, QString password){ |
|
|
|
|
connecting_to_network = n.ssid; |
|
|
|
|
QString active_ap = get_active_ap(); |
|
|
|
|
if(active_ap!="" && active_ap!="/"){ |
|
|
|
|
deactivate_connections(get_property(active_ap, "Ssid")); //Disconnect from any connected networks
|
|
|
|
|
} |
|
|
|
|
disconnect(); |
|
|
|
|
clear_connections(n.ssid); //Clear all connections that may already exist to the network we are connecting
|
|
|
|
|
connect(n.ssid, username, password, n.security_type); |
|
|
|
|
} |
|
|
|
@ -147,13 +171,13 @@ void WifiManager::connect(QByteArray ssid, QString username, QString password, S |
|
|
|
|
Connection connection; |
|
|
|
|
connection["connection"]["type"] = "802-11-wireless"; |
|
|
|
|
connection["connection"]["uuid"] = QUuid::createUuid().toString().remove('{').remove('}'); |
|
|
|
|
|
|
|
|
|
connection["connection"]["id"] = "OpenPilot connection "+QString::fromStdString(ssid.toStdString()); |
|
|
|
|
connection["connection"]["autoconnect-retries"] = 0; |
|
|
|
|
|
|
|
|
|
connection["802-11-wireless"]["ssid"] = ssid; |
|
|
|
|
connection["802-11-wireless"]["mode"] = "infrastructure"; |
|
|
|
|
|
|
|
|
|
if(security_type == SecurityType::WPA){ |
|
|
|
|
if (security_type == SecurityType::WPA){ |
|
|
|
|
connection["802-11-wireless-security"]["key-mgmt"] = "wpa-psk"; |
|
|
|
|
connection["802-11-wireless-security"]["auth-alg"] = "open"; |
|
|
|
|
connection["802-11-wireless-security"]["psk"] = password; |
|
|
|
@ -163,16 +187,16 @@ void WifiManager::connect(QByteArray ssid, QString username, QString password, S |
|
|
|
|
connection["ipv6"]["method"] = "ignore"; |
|
|
|
|
|
|
|
|
|
QDBusInterface nm_settings(nm_service, nm_settings_path, nm_settings_iface, bus); |
|
|
|
|
QDBusReply<QDBusObjectPath> result = nm_settings.call("AddConnection", QVariant::fromValue(connection)); |
|
|
|
|
nm_settings.call("AddConnection", QVariant::fromValue(connection)); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void WifiManager::deactivate_connections(QString ssid){ |
|
|
|
|
for(QDBusObjectPath active_connection_raw : get_active_connections()){ |
|
|
|
|
for (QDBusObjectPath active_connection_raw : get_active_connections()){ |
|
|
|
|
QString active_connection = active_connection_raw.path(); |
|
|
|
|
QDBusInterface nm(nm_service, active_connection, props_iface, bus); |
|
|
|
|
QDBusObjectPath pth = get_response<QDBusObjectPath>(nm.call("Get", connection_iface, "SpecificObject")); |
|
|
|
|
QString Ssid = get_property(pth.path(), "Ssid"); |
|
|
|
|
if(Ssid == ssid){ |
|
|
|
|
if (Ssid == ssid){ |
|
|
|
|
QDBusInterface nm2(nm_service, nm_path, nm_iface, bus); |
|
|
|
|
nm2.call("DeactivateConnection", QVariant::fromValue(active_connection_raw)); |
|
|
|
|
} |
|
|
|
@ -210,12 +234,12 @@ void WifiManager::clear_connections(QString ssid){ |
|
|
|
|
|
|
|
|
|
QMap<QString,QMap<QString,QVariant> > map; |
|
|
|
|
dbusArg >> map; |
|
|
|
|
for(QString outer_key : map.keys()) { |
|
|
|
|
for (QString outer_key : map.keys()) { |
|
|
|
|
QMap<QString,QVariant> innerMap = map.value(outer_key); |
|
|
|
|
for(QString inner_key : innerMap.keys()) { |
|
|
|
|
if(inner_key == "ssid"){ |
|
|
|
|
for (QString inner_key : innerMap.keys()) { |
|
|
|
|
if (inner_key == "ssid"){ |
|
|
|
|
QString value = innerMap.value(inner_key).value<QString>(); |
|
|
|
|
if(value == ssid){ |
|
|
|
|
if (value == ssid){ |
|
|
|
|
nm2.call("Delete"); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
@ -288,9 +312,58 @@ QString WifiManager::get_adapter(){ |
|
|
|
|
|
|
|
|
|
void WifiManager::change(unsigned int new_state,unsigned int previous_state,unsigned int change_reason){ |
|
|
|
|
raw_adapter_state = new_state; |
|
|
|
|
if(new_state == state_need_auth && change_reason == reason_wrong_password){ |
|
|
|
|
if (new_state == state_need_auth && change_reason == reason_wrong_password){ |
|
|
|
|
emit wrongPassword(connecting_to_network); |
|
|
|
|
}else if(new_state == state_connected){ |
|
|
|
|
connecting_to_network=""; |
|
|
|
|
}else if (new_state == state_connected){ |
|
|
|
|
connecting_to_network = ""; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void WifiManager::disconnect(){ |
|
|
|
|
QString active_ap = get_active_ap(); |
|
|
|
|
if (active_ap!="" && active_ap!="/"){ |
|
|
|
|
deactivate_connections(get_property(active_ap, "Ssid")); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
//Functions for tethering
|
|
|
|
|
|
|
|
|
|
void WifiManager::enableTethering(){ |
|
|
|
|
disconnect(); |
|
|
|
|
Connection connection; |
|
|
|
|
connection["connection"]["id"] = "Hotspot"; |
|
|
|
|
connection["connection"]["uuid"] = QUuid::createUuid().toString().remove('{').remove('}'); |
|
|
|
|
connection["connection"]["type"] = "802-11-wireless"; |
|
|
|
|
connection["connection"]["interface-name"] = "wlan0"; |
|
|
|
|
|
|
|
|
|
connection["802-11-wireless"]["band"] = "bg"; |
|
|
|
|
connection["802-11-wireless"]["mode"] = "ap"; |
|
|
|
|
connection["802-11-wireless"]["ssid"] = tethering_ssid.toUtf8(); |
|
|
|
|
|
|
|
|
|
connection["802-11-wireless-security"]["group"] = QStringList("ccmp"); |
|
|
|
|
connection["802-11-wireless-security"]["key-mgmt"] = "wpa-psk"; |
|
|
|
|
connection["802-11-wireless-security"]["pairwise"] = QStringList("ccmp"); |
|
|
|
|
connection["802-11-wireless-security"]["proto"] = QStringList("rsn"); |
|
|
|
|
connection["802-11-wireless-security"]["psk"] = "swagswagcomma"; |
|
|
|
|
|
|
|
|
|
connection["ipv4"]["method"] = "shared"; |
|
|
|
|
QMap<QString,QVariant> adress1; |
|
|
|
|
adress1["address"] = "192.168.43.1"; |
|
|
|
|
adress1["prefix"] = 24u; |
|
|
|
|
connection["ipv4"]["address-data"] = QVariant::fromValue(IpConfig() << adress1); |
|
|
|
|
connection["ipv4"]["gateway"] = "192.168.43.1"; |
|
|
|
|
connection["ipv6"]["method"] = "ignore"; |
|
|
|
|
|
|
|
|
|
QDBusInterface nm_settings(nm_service, nm_settings_path, nm_settings_iface, bus); |
|
|
|
|
nm_settings.call("AddConnection", QVariant::fromValue(connection)); |
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void WifiManager::disableTethering(){ |
|
|
|
|
clear_connections(tethering_ssid); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
bool WifiManager::tetheringEnabled(){ |
|
|
|
|
QString active_ap = get_active_ap(); |
|
|
|
|
return get_property(active_ap, "Ssid") == tethering_ssid; |
|
|
|
|
} |
|
|
|
|