QT UI: Wifi chooser (#2062)
	
		
	
				
					
				
			* qt wifi
Squashed commit of the following:
commit bec029c7b906c1df5324a8dbb0a58b8980c313ab
Author: grekiki <gregor1234567890@gmail.com>
Date:   Mon Nov 2 19:31:30 2020 +0100
    try to collect security type
commit e1e4d97f48a293392d33fe607936bbe94415c846
Author: grekiki <gregor1234567890@gmail.com>
Date:   Mon Nov 2 16:06:55 2020 +0100
    add a function for refresh
commit 52bd7d0937040bd1d5c582f324fdb60f33677014
Author: grekiki <gregor1234567890@gmail.com>
Date:   Fri Oct 30 11:14:23 2020 +0100
    allow compilation
commit 1b91e1057cca564d6b021a579d97940a8f2b9328
Author: Gregor Kikelj <gregor1234567890@gmail.com>
Date:   Wed Oct 21 14:12:05 2020 +0200
    dont build keyboard
commit cc8bad2ddd668d1397a9003a518699c3f706cca8
Author: Gregor Kikelj <gregor1234567890@gmail.com>
Date:   Tue Oct 20 18:22:07 2020 +0200
    kind of works
commit ce3a9b6d96a1985ba5b9a2f17c15530cb8f93ca8
Author: Willem Melching <willem.melching@gmail.com>
Date:   Mon Oct 19 11:22:55 2020 +0200
    remove button and text field
commit 2db3d11bdb8e69098c34c04a1341ea707ce1ed6a
Author: Willem Melching <willem.melching@gmail.com>
Date:   Mon Aug 24 15:31:26 2020 +0200
    try lineedit
commit d045c302dcec612c8d2ff14ba256af06c7df9ebb
Author: Willem Melching <willem.melching@gmail.com>
Date:   Mon Aug 24 15:01:18 2020 +0200
    add dialog test button
commit 21fa63e33b12b0bcdad441e778b2cf6c42b113e4
Author: Willem Melching <willem.melching@gmail.com>
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 <willem.melching@gmail.com>
Date:   Mon Aug 24 12:24:16 2020 +0200
    Sort networks by strength
commit e57fe68f7972f955fc4da7054af676df8581b003
Author: Willem Melching <willem.melching@gmail.com>
Date:   Sun Aug 23 13:59:39 2020 +0200
    Handle currently connected AP
commit a5e80e122176f39a9bccfb8056b0886d210fdf24
Author: Willem Melching <willem.melching@gmail.com>
Date:   Sun Aug 23 13:38:18 2020 +0200
    Add todo
commit 98a1bc6e7a1f38b0ff7cb810b7d63a133552dfcc
Author: Willem Melching <willem.melching@gmail.com>
Date:   Sun Aug 23 13:37:35 2020 +0200
    Implement scan method
commit 9a774a509b1665371d9fd51b40550ad2388d58bc
Author: Willem Melching <willem.melching@gmail.com>
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 <gregor1234567890@gmail.com>
Date:   Mon Nov 2 19:31:30 2020 +0100
    try to collect security type
commit e1e4d97f48a293392d33fe607936bbe94415c846
Author: grekiki <gregor1234567890@gmail.com>
Date:   Mon Nov 2 16:06:55 2020 +0100
    add a function for refresh
commit 52bd7d0937040bd1d5c582f324fdb60f33677014
Author: grekiki <gregor1234567890@gmail.com>
Date:   Fri Oct 30 11:14:23 2020 +0100
    allow compilation
commit 1b91e1057cca564d6b021a579d97940a8f2b9328
Author: Gregor Kikelj <gregor1234567890@gmail.com>
Date:   Wed Oct 21 14:12:05 2020 +0200
    dont build keyboard
commit cc8bad2ddd668d1397a9003a518699c3f706cca8
Author: Gregor Kikelj <gregor1234567890@gmail.com>
Date:   Tue Oct 20 18:22:07 2020 +0200
    kind of works
commit ce3a9b6d96a1985ba5b9a2f17c15530cb8f93ca8
Author: Willem Melching <willem.melching@gmail.com>
Date:   Mon Oct 19 11:22:55 2020 +0200
    remove button and text field
commit 2db3d11bdb8e69098c34c04a1341ea707ce1ed6a
Author: Willem Melching <willem.melching@gmail.com>
Date:   Mon Aug 24 15:31:26 2020 +0200
    try lineedit
commit d045c302dcec612c8d2ff14ba256af06c7df9ebb
Author: Willem Melching <willem.melching@gmail.com>
Date:   Mon Aug 24 15:01:18 2020 +0200
    add dialog test button
commit 21fa63e33b12b0bcdad441e778b2cf6c42b113e4
Author: Willem Melching <willem.melching@gmail.com>
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 <willem.melching@gmail.com>
Date:   Mon Aug 24 12:24:16 2020 +0200
    Sort networks by strength
commit e57fe68f7972f955fc4da7054af676df8581b003
Author: Willem Melching <willem.melching@gmail.com>
Date:   Sun Aug 23 13:59:39 2020 +0200
    Handle currently connected AP
commit a5e80e122176f39a9bccfb8056b0886d210fdf24
Author: Willem Melching <willem.melching@gmail.com>
Date:   Sun Aug 23 13:38:18 2020 +0200
    Add todo
commit 98a1bc6e7a1f38b0ff7cb810b7d63a133552dfcc
Author: Willem Melching <willem.melching@gmail.com>
Date:   Sun Aug 23 13:37:35 2020 +0200
    Implement scan method
commit 9a774a509b1665371d9fd51b40550ad2388d58bc
Author: Willem Melching <willem.melching@gmail.com>
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 <adeebshihadeh@gmail.com>
Co-authored-by: Comma Device <device@comma.ai>
Co-authored-by: grekiki <gregor1234567890@gmail.com>
			
			
				x-archive-community-master-merge
			
			
		
							parent
							
								
									5ebc0dd85b
								
							
						
					
					
						commit
						f93bca98ae
					
				
				 8 changed files with 471 additions and 73 deletions
			
			
		@ -0,0 +1,124 @@ | 
				
			||||
#include <QDebug> | 
				
			||||
#include <QListWidget> | 
				
			||||
#include <QVBoxLayout> | 
				
			||||
#include <QHBoxLayout> | 
				
			||||
#include <QLabel> | 
				
			||||
#include <QPixmap> | 
				
			||||
#include <QPushButton> | 
				
			||||
#include <QInputDialog> | 
				
			||||
#include <QLineEdit> | 
				
			||||
#include <QCoreApplication> | 
				
			||||
#include <QButtonGroup> | 
				
			||||
#include <QStackedLayout> | 
				
			||||
 | 
				
			||||
#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<CustomConnectButton*>(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"; | 
				
			||||
  } | 
				
			||||
 | 
				
			||||
} | 
				
			||||
@ -0,0 +1,33 @@ | 
				
			||||
#pragma once | 
				
			||||
#include "wifiManager.hpp" | 
				
			||||
#include <QWidget> | 
				
			||||
#include <QtDBus> | 
				
			||||
#include <QPushButton> | 
				
			||||
#include <QButtonGroup> | 
				
			||||
#include <QVBoxLayout> | 
				
			||||
#include <QStackedLayout> | 
				
			||||
#include <QTimer> | 
				
			||||
 | 
				
			||||
 | 
				
			||||
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(); | 
				
			||||
}; | 
				
			||||
@ -0,0 +1,255 @@ | 
				
			||||
#include <algorithm> | 
				
			||||
#include <set> | 
				
			||||
 | 
				
			||||
#include "wifiManager.hpp" | 
				
			||||
#include "wifi.hpp" | 
				
			||||
typedef QMap<QString, QMap<QString, QVariant> > 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 <typename T> | 
				
			||||
T get_response(QDBusMessage response){ | 
				
			||||
  QVariant first =  response.arguments().at(0); | 
				
			||||
  QDBusVariant dbvFirst = first.value<QDBusVariant>(); | 
				
			||||
  QVariant vFirst = dbvFirst.variant(); | 
				
			||||
  return vFirst.value<T>(); | 
				
			||||
} | 
				
			||||
 | 
				
			||||
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<Connection>(); | 
				
			||||
 | 
				
			||||
  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<Network> WifiManager::get_networks(){ | 
				
			||||
  QList<Network> 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<QDBusArgument>(); | 
				
			||||
  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 << "," <<password; | 
				
			||||
  connect(n.ssid, username, password, n.security_type); | 
				
			||||
} | 
				
			||||
void WifiManager::connect(QByteArray ssid, QString username, QString password, SecurityType security_type){ | 
				
			||||
  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()); //TODO Add security type
 | 
				
			||||
 | 
				
			||||
  connection["802-11-wireless"]["ssid"] = ssid; | 
				
			||||
  connection["802-11-wireless"]["mode"] = "infrastructure"; | 
				
			||||
 | 
				
			||||
  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; | 
				
			||||
  } | 
				
			||||
 | 
				
			||||
  connection["ipv4"]["method"] = "auto"; | 
				
			||||
  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)); | 
				
			||||
  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<QDBusVariant>(); | 
				
			||||
  QVariant vFirst = dbvFirst.variant(); | 
				
			||||
  QDBusArgument step4 = vFirst.value<QDBusArgument>(); | 
				
			||||
  QDBusObjectPath path; | 
				
			||||
  step4.beginArray(); | 
				
			||||
  while (!step4.atEnd()){ | 
				
			||||
      step4 >> path; | 
				
			||||
      qDebug()<<path.path(); | 
				
			||||
  } | 
				
			||||
  step4.endArray(); | 
				
			||||
} | 
				
			||||
void WifiManager::clear_connections(QString ssid){ | 
				
			||||
  QDBusInterface nm(nm_service, nm_settings_path, nm_settings_iface, bus); | 
				
			||||
  QDBusMessage response = nm.call("ListConnections"); | 
				
			||||
  QVariant first =  response.arguments().at(0); | 
				
			||||
  const QDBusArgument &args = first.value<QDBusArgument>(); | 
				
			||||
  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<QDBusArgument>(); | 
				
			||||
 | 
				
			||||
    QMap<QString,QMap<QString,QVariant> > map; | 
				
			||||
    dbusArg >> map; | 
				
			||||
    for( QString outer_key : map.keys() ){ | 
				
			||||
        QMap<QString,QVariant> innerMap = map.value(outer_key); | 
				
			||||
        for( QString inner_key : innerMap.keys() ){ | 
				
			||||
            if(inner_key=="ssid"){ | 
				
			||||
              QString value = innerMap.value(inner_key).value<QString>(); | 
				
			||||
              if(value == ssid){ | 
				
			||||
                // qDebug()<<"Deleting "<<value;
 | 
				
			||||
                nm2.call("Delete"); | 
				
			||||
              } | 
				
			||||
            } | 
				
			||||
        } | 
				
			||||
    } | 
				
			||||
  } | 
				
			||||
} | 
				
			||||
void WifiManager::request_scan(){ | 
				
			||||
  if (!has_adapter) return; | 
				
			||||
 | 
				
			||||
  QDBusInterface nm(nm_service, adapter, wireless_device_iface, bus); | 
				
			||||
  QDBusMessage response = nm.call("RequestScan",  QVariantMap()); | 
				
			||||
} | 
				
			||||
 | 
				
			||||
uint WifiManager::get_wifi_device_state(){ | 
				
			||||
  QDBusInterface device_props(nm_service, adapter, props_iface, bus); | 
				
			||||
  QDBusMessage response = device_props.call("Get", device_iface, "State"); | 
				
			||||
  uint resp = get_response<uint>(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<QDBusObjectPath>(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<QByteArray>(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<unsigned int>(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<QDBusArgument>(); | 
				
			||||
  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<uint>(response); | 
				
			||||
 | 
				
			||||
    if (device_type == 2){ // Wireless
 | 
				
			||||
      adapter_path = path.path(); | 
				
			||||
      break; | 
				
			||||
    } | 
				
			||||
  } | 
				
			||||
  args.endArray(); | 
				
			||||
 | 
				
			||||
  return adapter_path; | 
				
			||||
} | 
				
			||||
@ -0,0 +1,43 @@ | 
				
			||||
#pragma once | 
				
			||||
#include <QWidget> | 
				
			||||
#include <QtDBus> | 
				
			||||
enum class SecurityType{OPEN, WPA, UNSUPPORTED}; | 
				
			||||
 | 
				
			||||
struct Network { | 
				
			||||
  QString path; | 
				
			||||
  QByteArray ssid; | 
				
			||||
  unsigned int strength; | 
				
			||||
  bool connected; | 
				
			||||
 | 
				
			||||
  SecurityType security_type; | 
				
			||||
}; | 
				
			||||
 | 
				
			||||
class WifiManager{ | 
				
			||||
  private: | 
				
			||||
    QVector<QByteArray> seen_ssids; | 
				
			||||
    QString adapter;//Path to network manager wifi-device
 | 
				
			||||
    QDBusConnection bus = QDBusConnection::systemBus(); | 
				
			||||
 | 
				
			||||
    QString get_adapter(); | 
				
			||||
    QList<Network> 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<Network> seen_networks; | 
				
			||||
 | 
				
			||||
    explicit WifiManager(); | 
				
			||||
    void refreshNetworks(); | 
				
			||||
    void connect(Network ssid); | 
				
			||||
    void connect(Network ssid, QString password); | 
				
			||||
    void connect(Network ssid, QString username, QString password); | 
				
			||||
}; | 
				
			||||
@ -1,69 +0,0 @@ | 
				
			||||
#include <QtDBus> | 
				
			||||
#include <QDebug> | 
				
			||||
 | 
				
			||||
typedef QMap<QString, QMap<QString, QVariant> > Connection; | 
				
			||||
Q_DECLARE_METATYPE(Connection) | 
				
			||||
 | 
				
			||||
void wifi_stuff(){ | 
				
			||||
  qDBusRegisterMetaType<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_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<QDBusArgument>(); | 
				
			||||
  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<QDBusVariant>(); | 
				
			||||
    QVariant vFirst = dbvFirst.variant(); | 
				
			||||
    uint device_type = vFirst.value<uint>(); | 
				
			||||
    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("<ssid>"); | 
				
			||||
  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"] = "<password>"; | 
				
			||||
 | 
				
			||||
  connection["ipv4"]["method"] = "auto"; | 
				
			||||
  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)); | 
				
			||||
  if (!result.isValid()) { | 
				
			||||
    qDebug() << result.error().name() << result.error().message(); | 
				
			||||
  } else { | 
				
			||||
    qDebug() << result.value().path(); | 
				
			||||
  } | 
				
			||||
} | 
				
			||||
					Loading…
					
					
				
		Reference in new issue