From f93bca98ae8470ff61c98a11fdcaba8d549a964f Mon Sep 17 00:00:00 2001 From: Willem Melching Date: Thu, 19 Nov 2020 16:51:48 +0100 Subject: [PATCH] QT UI: Wifi chooser (#2062) * qt wifi Squashed commit of the following: commit bec029c7b906c1df5324a8dbb0a58b8980c313ab Author: grekiki Date: Mon Nov 2 19:31:30 2020 +0100 try to collect security type commit e1e4d97f48a293392d33fe607936bbe94415c846 Author: grekiki Date: Mon Nov 2 16:06:55 2020 +0100 add a function for refresh commit 52bd7d0937040bd1d5c582f324fdb60f33677014 Author: grekiki Date: Fri Oct 30 11:14:23 2020 +0100 allow compilation commit 1b91e1057cca564d6b021a579d97940a8f2b9328 Author: Gregor Kikelj Date: Wed Oct 21 14:12:05 2020 +0200 dont build keyboard commit cc8bad2ddd668d1397a9003a518699c3f706cca8 Author: Gregor Kikelj Date: Tue Oct 20 18:22:07 2020 +0200 kind of works commit ce3a9b6d96a1985ba5b9a2f17c15530cb8f93ca8 Author: Willem Melching Date: Mon Oct 19 11:22:55 2020 +0200 remove button and text field commit 2db3d11bdb8e69098c34c04a1341ea707ce1ed6a Author: Willem Melching Date: Mon Aug 24 15:31:26 2020 +0200 try lineedit commit d045c302dcec612c8d2ff14ba256af06c7df9ebb Author: Willem Melching Date: Mon Aug 24 15:01:18 2020 +0200 add dialog test button commit 21fa63e33b12b0bcdad441e778b2cf6c42b113e4 Author: Willem Melching Date: Mon Aug 24 12:36:10 2020 +0200 Only show one if both 2.4 and 5 Ghz found commit dfb9ca4173adc05264663a3658298899eea2c619 Author: Willem Melching Date: Mon Aug 24 12:24:16 2020 +0200 Sort networks by strength commit e57fe68f7972f955fc4da7054af676df8581b003 Author: Willem Melching Date: Sun Aug 23 13:59:39 2020 +0200 Handle currently connected AP commit a5e80e122176f39a9bccfb8056b0886d210fdf24 Author: Willem Melching Date: Sun Aug 23 13:38:18 2020 +0200 Add todo commit 98a1bc6e7a1f38b0ff7cb810b7d63a133552dfcc Author: Willem Melching Date: Sun Aug 23 13:37:35 2020 +0200 Implement scan method commit 9a774a509b1665371d9fd51b40550ad2388d58bc Author: Willem Melching Date: Sun Aug 23 13:29:03 2020 +0200 show list of wifi networks * add to settings * no wifi on pc * refactor get_property * refactor WiFi, split between UI and network manager stuff * renaming * refresh works * refactor * forgot to git add * connecting works again * print connection error on weird networks * extract adapter path * found networks * Deleting existing connections to SSID we are trying to connect to * have paths of active connections * mvp * fix review * qt wifi Squashed commit of the following: commit bec029c7b906c1df5324a8dbb0a58b8980c313ab Author: grekiki Date: Mon Nov 2 19:31:30 2020 +0100 try to collect security type commit e1e4d97f48a293392d33fe607936bbe94415c846 Author: grekiki Date: Mon Nov 2 16:06:55 2020 +0100 add a function for refresh commit 52bd7d0937040bd1d5c582f324fdb60f33677014 Author: grekiki Date: Fri Oct 30 11:14:23 2020 +0100 allow compilation commit 1b91e1057cca564d6b021a579d97940a8f2b9328 Author: Gregor Kikelj Date: Wed Oct 21 14:12:05 2020 +0200 dont build keyboard commit cc8bad2ddd668d1397a9003a518699c3f706cca8 Author: Gregor Kikelj Date: Tue Oct 20 18:22:07 2020 +0200 kind of works commit ce3a9b6d96a1985ba5b9a2f17c15530cb8f93ca8 Author: Willem Melching Date: Mon Oct 19 11:22:55 2020 +0200 remove button and text field commit 2db3d11bdb8e69098c34c04a1341ea707ce1ed6a Author: Willem Melching Date: Mon Aug 24 15:31:26 2020 +0200 try lineedit commit d045c302dcec612c8d2ff14ba256af06c7df9ebb Author: Willem Melching Date: Mon Aug 24 15:01:18 2020 +0200 add dialog test button commit 21fa63e33b12b0bcdad441e778b2cf6c42b113e4 Author: Willem Melching Date: Mon Aug 24 12:36:10 2020 +0200 Only show one if both 2.4 and 5 Ghz found commit dfb9ca4173adc05264663a3658298899eea2c619 Author: Willem Melching Date: Mon Aug 24 12:24:16 2020 +0200 Sort networks by strength commit e57fe68f7972f955fc4da7054af676df8581b003 Author: Willem Melching Date: Sun Aug 23 13:59:39 2020 +0200 Handle currently connected AP commit a5e80e122176f39a9bccfb8056b0886d210fdf24 Author: Willem Melching Date: Sun Aug 23 13:38:18 2020 +0200 Add todo commit 98a1bc6e7a1f38b0ff7cb810b7d63a133552dfcc Author: Willem Melching Date: Sun Aug 23 13:37:35 2020 +0200 Implement scan method commit 9a774a509b1665371d9fd51b40550ad2388d58bc Author: Willem Melching Date: Sun Aug 23 13:29:03 2020 +0200 show list of wifi networks * add to settings * no wifi on pc * refactor get_property * refactor WiFi, split between UI and network manager stuff * renaming * refresh works * refactor * forgot to git add * connecting works again * print connection error on weird networks * extract adapter path * found networks * Deleting existing connections to SSID we are trying to connect to * have paths of active connections * mvp * fix review * fix bugs * fix text color * colors * wider button * show connected network first * fix sorting * remove hack * sorting * auto refresh * only refresh when widget is visible * scan once on startup * dont open dialog on qcom2 Co-authored-by: Adeeb Shihadeh Co-authored-by: Comma Device Co-authored-by: grekiki --- selfdrive/ui/SConscript | 2 +- selfdrive/ui/qt/offroad/settings.cc | 17 +- selfdrive/ui/qt/offroad/settings.hpp | 1 - selfdrive/ui/qt/offroad/wifi.cc | 124 ++++++++++++ selfdrive/ui/qt/offroad/wifi.hpp | 33 +++ selfdrive/ui/qt/offroad/wifiManager.cc | 255 ++++++++++++++++++++++++ selfdrive/ui/qt/offroad/wifiManager.hpp | 43 ++++ selfdrive/ui/qt/wifi.cc | 69 ------- 8 files changed, 471 insertions(+), 73 deletions(-) create mode 100644 selfdrive/ui/qt/offroad/wifi.cc create mode 100644 selfdrive/ui/qt/offroad/wifi.hpp create mode 100644 selfdrive/ui/qt/offroad/wifiManager.cc create mode 100644 selfdrive/ui/qt/offroad/wifiManager.hpp delete mode 100644 selfdrive/ui/qt/wifi.cc diff --git a/selfdrive/ui/SConscript b/selfdrive/ui/SConscript index ca60133265..4c2a36db87 100644 --- a/selfdrive/ui/SConscript +++ b/selfdrive/ui/SConscript @@ -71,7 +71,7 @@ else: else: qt_libs += [f"Qt5{m}" for m in qt_modules] - qt_src = ["qt/ui.cc", "qt/window.cc", "qt/qt_sound.cc", "qt/offroad/settings.cc", "qt/offroad/onboarding.cc"] + src + qt_src = ["qt/ui.cc", "qt/window.cc", "qt/qt_sound.cc", "qt/offroad/settings.cc", "qt/offroad/onboarding.cc", "qt/offroad/wifi.cc", "qt/offroad/wifiManager.cc"] + src qt_env.Program("_ui", qt_src, LIBS=qt_libs + libs) # spinner and text window diff --git a/selfdrive/ui/qt/offroad/settings.cc b/selfdrive/ui/qt/offroad/settings.cc index 6bb731a09a..8711bf5c5e 100644 --- a/selfdrive/ui/qt/offroad/settings.cc +++ b/selfdrive/ui/qt/offroad/settings.cc @@ -3,8 +3,6 @@ #include #include -#include "settings.hpp" - #include #include #include @@ -12,6 +10,9 @@ #include #include +#include "wifi.hpp" +#include "settings.hpp" + #include "common/params.h" ParamsToggle::ParamsToggle(QString param, QString title, QString description, QString icon_path, QWidget *parent): QFrame(parent) , param(param) { @@ -189,6 +190,17 @@ QWidget * developer_panel() { return widget; } +QWidget * network_panel() { + QVBoxLayout *main_layout = new QVBoxLayout; + + main_layout->addWidget(new WifiUI()); + + QWidget *widget = new QWidget; + widget->setLayout(main_layout); + return widget; +} + + void SettingsWindow::setActivePanel() { QPushButton *btn = qobject_cast(sender()); panel_layout->setCurrentWidget(panels[btn->text()]); @@ -217,6 +229,7 @@ SettingsWindow::SettingsWindow(QWidget *parent) : QWidget(parent) { {"device", device_panel()}, {"toggles", toggles_panel()}, {"developer", developer_panel()}, + {"network", network_panel()}, }; for (auto &panel : panels) { diff --git a/selfdrive/ui/qt/offroad/settings.hpp b/selfdrive/ui/qt/offroad/settings.hpp index 456155e33b..e4f65a6944 100644 --- a/selfdrive/ui/qt/offroad/settings.hpp +++ b/selfdrive/ui/qt/offroad/settings.hpp @@ -21,7 +21,6 @@ public slots: void checkboxClicked(int state); }; - class SettingsWindow : public QWidget { Q_OBJECT diff --git a/selfdrive/ui/qt/offroad/wifi.cc b/selfdrive/ui/qt/offroad/wifi.cc new file mode 100644 index 0000000000..610ec0805b --- /dev/null +++ b/selfdrive/ui/qt/offroad/wifi.cc @@ -0,0 +1,124 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "wifi.hpp" +#include "wifiManager.hpp" +CustomConnectButton::CustomConnectButton(QString text, int iid){ + setText(text); + id=iid; +} + +void clearLayout(QLayout* layout){ + while (QLayoutItem* item = layout->takeAt(0)){ + if (QWidget* widget = item->widget()){ + widget->deleteLater(); + } + if (QLayout* childLayout = item->layout()){ + clearLayout(childLayout); + } + delete item; + } +} + +WifiUI::WifiUI(QWidget *parent) : QWidget(parent) { + vlayout = new QVBoxLayout; + wifi = new WifiManager; + refresh(); + setLayout(vlayout); + + setStyleSheet(R"( + QLabel { font-size: 40px } + QPushButton:enabled { + background-color: #114265; + } + QPushButton:disabled { + background-color: #323C43; + } + * { + background-color: #114265; + } + )"); + + // TODO: implement (not) connecting with wrong password + + // Update network list every second + timer = new QTimer(this); + QObject::connect(timer, SIGNAL(timeout()), this, SLOT(refresh())); + timer->start(1000); + + // Scan on startup + wifi->request_scan(); +} + +void WifiUI::refresh(){ + if (!this->isVisible()){ + return; + } + + wifi->request_scan(); + wifi->refreshNetworks(); + + clearLayout(vlayout); + int i=0; + + QButtonGroup* connectButtons=new QButtonGroup(this); + QObject::connect(connectButtons, SIGNAL(buttonClicked(QAbstractButton*)), this, SLOT(handleButton(QAbstractButton*))); + for (Network &network : wifi->seen_networks){ + QHBoxLayout *hlayout = new QHBoxLayout; + hlayout->addWidget(new QLabel(QString::fromUtf8(network.ssid))); + unsigned int strength_scale = std::round(network.strength / 25.0) * 25; + QPixmap pix("../assets/offroad/indicator_wifi_" + QString::number(strength_scale) + ".png"); + QLabel *icon = new QLabel(); + icon->setPixmap(pix.scaledToWidth(100, Qt::SmoothTransformation)); + icon->setSizePolicy(QSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed)); + hlayout->addWidget(icon); + hlayout->addSpacing(20); + + CustomConnectButton* m_button = new CustomConnectButton(network.connected ? "Connected" : "Connect",i); + m_button->setFixedWidth(300); + m_button->setDisabled(network.connected || network.security_type == SecurityType::UNSUPPORTED); + connectButtons->addButton(m_button,i); + + hlayout->addWidget(m_button); + hlayout->addSpacing(20); + vlayout->addLayout(hlayout); + i+=1; + } +} + +void WifiUI::handleButton(QAbstractButton* button){ + CustomConnectButton* m_button = static_cast(button); + int id = m_button->id; + Network n = wifi->seen_networks[id]; + // qDebug() << "Clicked a button:" << id; + // qDebug() << n.ssid; + if(n.security_type==SecurityType::OPEN){ + wifi->connect(n); + } else if (n.security_type==SecurityType::WPA){ + bool ok = false; + QString password; + +#ifdef QCOM2 + // TODO: implement touch keyboard +#else + password = QInputDialog::getText(this, "Password for "+n.ssid, "Password", QLineEdit::Normal, "", &ok); +#endif + if (ok){ + wifi->connect(n, password); + } + + } else { + qDebug() << "Cannot determine a network's security type"; + } + +} diff --git a/selfdrive/ui/qt/offroad/wifi.hpp b/selfdrive/ui/qt/offroad/wifi.hpp new file mode 100644 index 0000000000..1caf2f4ee2 --- /dev/null +++ b/selfdrive/ui/qt/offroad/wifi.hpp @@ -0,0 +1,33 @@ +#pragma once +#include "wifiManager.hpp" +#include +#include +#include +#include +#include +#include +#include + + +class CustomConnectButton : public QPushButton{ + +public: + explicit CustomConnectButton(QString text, int iid); + int id; +}; + +class WifiUI : public QWidget { + Q_OBJECT + + private: + WifiManager* wifi; + QVBoxLayout* vlayout; + QTimer * timer; + + public: + explicit WifiUI(QWidget *parent = 0); + + private slots: + void handleButton(QAbstractButton* m_button); + void refresh(); +}; diff --git a/selfdrive/ui/qt/offroad/wifiManager.cc b/selfdrive/ui/qt/offroad/wifiManager.cc new file mode 100644 index 0000000000..a602b75e12 --- /dev/null +++ b/selfdrive/ui/qt/offroad/wifiManager.cc @@ -0,0 +1,255 @@ +#include +#include + +#include "wifiManager.hpp" +#include "wifi.hpp" +typedef QMap > Connection; + +QString nm_path = "/org/freedesktop/NetworkManager"; +QString nm_settings_path = "/org/freedesktop/NetworkManager/Settings"; + +QString nm_iface = "org.freedesktop.NetworkManager"; +QString props_iface = "org.freedesktop.DBus.Properties"; +QString nm_settings_iface = "org.freedesktop.NetworkManager.Settings"; +QString nm_settings_conn_iface = "org.freedesktop.NetworkManager.Settings.Connection"; +QString device_iface = "org.freedesktop.NetworkManager.Device"; +QString wireless_device_iface = "org.freedesktop.NetworkManager.Device.Wireless"; +QString ap_iface = "org.freedesktop.NetworkManager.AccessPoint"; +QString connection_iface = "org.freedesktop.NetworkManager.Connection.Active"; + +QString nm_service = "org.freedesktop.NetworkManager"; + + +template +T get_response(QDBusMessage response){ + QVariant first = response.arguments().at(0); + QDBusVariant dbvFirst = first.value(); + QVariant vFirst = dbvFirst.variant(); + return vFirst.value(); +} + +bool compare_by_strength(const Network &a, const Network &b){ + if (a.connected) return true; + if (b.connected) return false; + return a.strength > b.strength; +} + +WifiManager::WifiManager(){ + qDBusRegisterMetaType(); + + adapter = get_adapter(); + has_adapter = adapter != ""; +} + +void WifiManager::refreshNetworks(){ + if (!has_adapter) return; + + bus = QDBusConnection::systemBus(); + seen_networks.clear(); + seen_ssids.clear(); + + for (Network &network : get_networks()){ + if(seen_ssids.count(network.ssid)){ + continue; + } + seen_ssids.push_back(network.ssid); + seen_networks.push_back(network); + } +} + +QList WifiManager::get_networks(){ + QList r; + QDBusInterface nm(nm_service, adapter, wireless_device_iface, bus); + QDBusMessage response = nm.call("GetAllAccessPoints"); + QVariant first = response.arguments().at(0); + + QString active_ap = get_active_ap(); + + const QDBusArgument &args = first.value(); + args.beginArray(); + while (!args.atEnd()) { + QDBusObjectPath path; + args >> path; + + QByteArray ssid = get_property(path.path(), "Ssid"); + unsigned int strength = get_ap_strength(path.path()); + SecurityType security = getSecurityType(path.path()); + Network network = {path.path(), ssid, strength, path.path()==active_ap, security}; + + if (ssid.length()){ + r.push_back(network); + } + } + args.endArray(); + + std::sort(r.begin(), r.end(), compare_by_strength); + return r; +} + +SecurityType WifiManager::getSecurityType(QString path){ + int sflag = get_property(path, "Flags").toInt(); + int wpaflag = get_property(path, "WpaFlags").toInt(); + int rsnflag = get_property(path, "RsnFlags").toInt(); + int wpa_props = wpaflag | rsnflag; + if(sflag == 0){ + return SecurityType::OPEN; + }else if((sflag & 0x1) && (wpa_props & (0x333) && !(wpa_props & 0x200)) ){ + return SecurityType::WPA; + }else{ + // qDebug() << "Cannot determine security type for " << get_property(path, "Ssid") << " with flags"; + // qDebug() << "flag " << sflag; + // qDebug() << "WpaFlag " << wpaflag; + // qDebug() << "RsnFlag " << rsnflag; + return SecurityType::UNSUPPORTED; + } +} +void WifiManager::connect(Network n){ + return connect(n,"",""); +} +void WifiManager::connect(Network n, QString password){ + return connect(n, "", password); +} + +void WifiManager::connect(Network n, QString username, QString password){ + QString active_ap = get_active_ap(); + if(active_ap!=""){ + clear_connections(get_property(active_ap,"Ssid")); + } + clear_connections(n.ssid); + qDebug() << "Connecting to"<< n.ssid << "with username, password =" << username << "," < result = nm_settings.call("AddConnection", QVariant::fromValue(connection)); + if (!result.isValid()) { + qDebug() << result.error().name() << result.error().message(); + } else { + qDebug() << result.value().path(); + } + +} + +void WifiManager::print_active_connections(){ + //TO-DO clean up, the code is not currently in use. + QDBusInterface nm(nm_service, nm_path, props_iface, bus); + QDBusMessage response = nm.call("Get", nm_iface, "ActiveConnections"); + QVariant first = response.arguments().at(0); + QDBusVariant dbvFirst = first.value(); + QVariant vFirst = dbvFirst.variant(); + QDBusArgument step4 = vFirst.value(); + QDBusObjectPath path; + step4.beginArray(); + while (!step4.atEnd()){ + step4 >> path; + qDebug()<(); + args.beginArray(); + while (!args.atEnd()) { + QDBusObjectPath path; + args >> path; + QDBusInterface nm2(nm_service, path.path(), nm_settings_conn_iface, bus); + QDBusMessage response = nm2.call("GetSettings"); + + const QDBusArgument &dbusArg = response.arguments().at(0).value(); + + QMap > map; + dbusArg >> map; + for( QString outer_key : map.keys() ){ + QMap innerMap = map.value(outer_key); + for( QString inner_key : innerMap.keys() ){ + if(inner_key=="ssid"){ + QString value = innerMap.value(inner_key).value(); + if(value == ssid){ + // qDebug()<<"Deleting "<(response); + return resp; +} +QString WifiManager::get_active_ap(){ + QDBusInterface device_props(nm_service, adapter, props_iface, bus); + QDBusMessage response = device_props.call("Get", wireless_device_iface, "ActiveAccessPoint"); + QDBusObjectPath r = get_response(response); + return r.path(); +} +QByteArray WifiManager::get_property(QString network_path ,QString property){ + QDBusInterface device_props(nm_service, network_path, props_iface, bus); + QDBusMessage response = device_props.call("Get", ap_iface, property); + return get_response(response); +} + +unsigned int WifiManager::get_ap_strength(QString network_path){ + QDBusInterface device_props(nm_service, network_path, props_iface, bus); + QDBusMessage response = device_props.call("Get", ap_iface, "Strength"); + return get_response(response); +} + +QString WifiManager::get_adapter(){ + + QDBusInterface nm(nm_service, nm_path, nm_iface, bus); + QDBusMessage response = nm.call("GetDevices"); + QVariant first = response.arguments().at(0); + + QString adapter_path = ""; + + const QDBusArgument &args = first.value(); + args.beginArray(); + while (!args.atEnd()) { + QDBusObjectPath path; + args >> path; + + // Get device type + QDBusInterface device_props(nm_service, path.path(), props_iface, bus); + QDBusMessage response = device_props.call("Get", device_iface, "DeviceType"); + uint device_type = get_response(response); + + if (device_type == 2){ // Wireless + adapter_path = path.path(); + break; + } + } + args.endArray(); + + return adapter_path; +} diff --git a/selfdrive/ui/qt/offroad/wifiManager.hpp b/selfdrive/ui/qt/offroad/wifiManager.hpp new file mode 100644 index 0000000000..463e3520f8 --- /dev/null +++ b/selfdrive/ui/qt/offroad/wifiManager.hpp @@ -0,0 +1,43 @@ +#pragma once +#include +#include +enum class SecurityType{OPEN, WPA, UNSUPPORTED}; + +struct Network { + QString path; + QByteArray ssid; + unsigned int strength; + bool connected; + + SecurityType security_type; +}; + +class WifiManager{ + private: + QVector seen_ssids; + QString adapter;//Path to network manager wifi-device + QDBusConnection bus = QDBusConnection::systemBus(); + + QString get_adapter(); + QList get_networks(); + void connect(QByteArray ssid, QString username, QString password, SecurityType security_type); + QString get_active_ap(); + void clear_connections(QString ssid); + void print_active_connections(); + uint get_wifi_device_state(); + QByteArray get_ap_ssid(QString network_path); + QByteArray get_property(QString network_path, QString property); + unsigned int get_ap_strength(QString network_path); + SecurityType getSecurityType(QString ssid); + + public: + bool has_adapter; + void request_scan(); + QVector seen_networks; + + explicit WifiManager(); + void refreshNetworks(); + void connect(Network ssid); + void connect(Network ssid, QString password); + void connect(Network ssid, QString username, QString password); +}; diff --git a/selfdrive/ui/qt/wifi.cc b/selfdrive/ui/qt/wifi.cc deleted file mode 100644 index 1d66c2c862..0000000000 --- a/selfdrive/ui/qt/wifi.cc +++ /dev/null @@ -1,69 +0,0 @@ -#include -#include - -typedef QMap > Connection; -Q_DECLARE_METATYPE(Connection) - -void wifi_stuff(){ - qDBusRegisterMetaType(); - - QString nm_path = "/org/freedesktop/NetworkManager"; - QString nm_settings_path = "/org/freedesktop/NetworkManager/Settings"; - - QString nm_iface = "org.freedesktop.NetworkManager"; - QString props_iface = "org.freedesktop.DBus.Properties"; - QString nm_settings_iface = "org.freedesktop.NetworkManager.Settings"; - - QString nm_service = "org.freedesktop.NetworkManager"; - QString device_service = "org.freedesktop.NetworkManager.Device"; - - QDBusConnection bus = QDBusConnection::systemBus(); - - // Get devices - QDBusInterface nm(nm_service, nm_path, nm_iface, bus); - QDBusMessage response = nm.call("GetDevices"); - QVariant first = response.arguments().at(0); - - const QDBusArgument &args = first.value(); - args.beginArray(); - while (!args.atEnd()) { - QDBusObjectPath path; - args >> path; - - // Get device type - QDBusInterface device_props(nm_service, path.path(), props_iface, bus); - QDBusMessage response = device_props.call("Get", device_service, "DeviceType"); - QVariant first = response.arguments().at(0); - QDBusVariant dbvFirst = first.value(); - QVariant vFirst = dbvFirst.variant(); - uint device_type = vFirst.value(); - qDebug() << path.path() << device_type; - } - args.endArray(); - - - // Add connection - Connection connection; - connection["connection"]["type"] = "802-11-wireless"; - connection["connection"]["uuid"] = QUuid::createUuid().toString().remove('{').remove('}'); - connection["connection"]["id"] = "Connection 1"; - - connection["802-11-wireless"]["ssid"] = QByteArray(""); - connection["802-11-wireless"]["mode"] = "infrastructure"; - - connection["802-11-wireless-security"]["key-mgmt"] = "wpa-psk"; - connection["802-11-wireless-security"]["auth-alg"] = "open"; - connection["802-11-wireless-security"]["psk"] = ""; - - connection["ipv4"]["method"] = "auto"; - connection["ipv6"]["method"] = "ignore"; - - - QDBusInterface nm_settings(nm_service, nm_settings_path, nm_settings_iface, bus); - QDBusReply result = nm_settings.call("AddConnection", QVariant::fromValue(connection)); - if (!result.isValid()) { - qDebug() << result.error().name() << result.error().message(); - } else { - qDebug() << result.value().path(); - } -}