Advertisement
Guest User

Untitled

a guest
Feb 7th, 2018
98
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 9.51 KB | None | 0 0
  1. WifiSettingsDialog::WifiSettingsDialog(QWidget *parent) :
  2.     QDialog(parent),
  3.     ui(new Ui::WifiSettingsDialog), _qpd(NULL), _connecting(false)
  4. {
  5.     setWindowFlags(Qt::Window | Qt::CustomizeWindowHint | Qt::WindowTitleHint);
  6.     ui->setupUi(this);
  7.     ui->list->setItemDelegate(new TwoIconsDelegate(this));
  8.     ui->buttonBox->button(QDialogButtonBox::Ok)->setEnabled(false);
  9.     connect(ui->passwordEdit, SIGNAL(textChanged(QString)), this, SLOT(checkSettings()));
  10.  
  11.     FiW1Wpa_supplicant1Interface *wpa = WpaFactory::createWpaSupplicantProxy(this);
  12.     QList<QDBusObjectPath> ifaces = wpa->interfaces();
  13.  
  14.     if (ifaces.count() == 0)
  15.     {
  16.         QMessageBox::critical(parent, tr("No wifi interfaces"), tr("No wifi interfaces available"), QMessageBox::Close);
  17.         close();
  18.     }
  19.  
  20.     foreach (QDBusObjectPath ifpath, ifaces)
  21.     {
  22.         FiW1Wpa_supplicant1InterfaceInterface interface = WpaFactory::createInterfaceProxy(ifpath, this);
  23.         ifname = interface->ifname();
  24.         qDebug() << "Using wifi interface" << ifname;
  25.  
  26.         _currentBSS = interface->currentBSS();
  27.         connect(interface, SIGNAL(BSSAdded(QDBusObjectPath,QVariantMap)), this, SLOT(onBSSAdded(QDBusObjectPath)));
  28.         connect(interface, SIGNAL(PropertiesChanged(QVariantMap)), this, SLOT(onPropertiesChanged(QVariantMap)));
  29.  
  30.         /* Call onBSSAdded() for BSSes already scanned prior to opening the dialog */
  31.         QList<QDBusObjectPath> bSSs = interface->bSSs();
  32.         foreach (QDBusObjectPath bsspath, bSSs)
  33.         {
  34.             onBSSAdded(bsspath, ifname);
  35.         }
  36.         if (ui->list->count() && ui->list->currentRow() == -1)
  37.             ui->list->setCurrentRow(0);
  38.  
  39.         /* Copy existing login information if possible
  40.         Password is only retrievable if network has just been added */
  41.         QDBusObjectPath cnp = interface->currentNetwork();
  42.         if (!cnp.path().isEmpty())
  43.         {
  44.             FiW1Wpa_supplicant1NetworkInterface *cni = WpaFactory::createNetworkProxy(cnp);
  45.             QVariantMap prop = cni->properties();
  46.             if (prop.contains("identity") && prop.contains("password"))
  47.             {
  48.                 ui->userEdit->setText(removeQuotes( prop.value("identity").toString() ));
  49.                 ui->passwordEdit->setText(removeQuotes( prop.value("password").toString() ));
  50.             }
  51.             else if (prop.contains("psk"))
  52.             {
  53.                 ui->passwordEdit->setText(removeQuotes( prop.value("psk").toString() ));
  54.             }
  55.             cni->deleteLater();
  56.         }
  57.  
  58.         QVariantMap args;
  59.         args.insert("Type", "passive");
  60.         interface->Scan(args);
  61.     }
  62. }
  63.  
  64. void WifiSettingsDialog::onBSSAdded(const QDBusObjectPath &path, QString &ifname)
  65. {
  66.     FiW1Wpa_supplicant1BSSInterface *bss = WpaFactory::createBSSProxy(path);
  67.  
  68.     QString ssid = bss->sSID();
  69.     int   signal = bss->signal();
  70.     QVariantMap properties;
  71.  
  72.     /* or maybe you can get the interface from 'bss' eg. bss->ifname();
  73.       Then no need to pass the interface to this method at all */
  74.     properties.insert("ifname", ifname);
  75.     properties.insert("SSID", bss->sSID());
  76.     properties.insert("WPA", bss->wPA());
  77.     properties.insert("WPS", bss->wPS());
  78.     properties.insert("RSN", bss->rSN());
  79.     properties.insert("Frequency", bss->frequency());
  80.     qDebug() << "New BSS detected:" << path.path() << ssid << "freq" << bss->frequency() << "WPS support:" << bss->wPS();
  81.  
  82.     if (ui->list->findItems(ssid, Qt::MatchExactly).count() )
  83.     {
  84.         bss->deleteLater();
  85.         return;
  86.     }
  87.  
  88.     QString icon;
  89.     if (signal > -50)
  90.         icon = ":/icons/network-wireless-connected-100.png";
  91.     else if (signal > -60)
  92.         icon = ":/icons/network-wireless-connected-75.png";
  93.     else if (signal > -70)
  94.         icon = ":/icons/network-wireless-connected-50.png";
  95.     else if (signal > -80)
  96.         icon = ":/icons/network-wireless-connected-25.png";
  97.     else
  98.         icon = ":/icons/network-wireless-connected-00.png";
  99.  
  100.     /* or maybe you can get the interface from 'bss' eg. bss->ifname();
  101.       Then no need to pass the interface to this method at all */
  102.     QString label = QString("%1 (%2)").arg(ssid, interface)
  103.     QListWidgetItem *item = new QListWidgetItem(QIcon(icon), label);
  104.  
  105.     item->setData(Qt::UserRole, properties);
  106.     item->setData(Qt::UserRole+1, signal);
  107.     if (path == _currentBSS)
  108.         item->setData(SecondIconRole, QIcon(":/icons/tick.png"));
  109.  
  110.     /* Insert the discovered BSS before entries with lower strength */
  111.     for (int i=0; i<ui->list->count(); i++)
  112.     {
  113.         if (ui->list->item(i)->data(Qt::UserRole+1).toInt() < signal)
  114.         {
  115.             ui->list->insertItem(i, item);
  116.             if (path == _currentBSS)
  117.                 ui->list->setCurrentItem(item);
  118.             return;
  119.         }
  120.     }
  121.  
  122.     /* No existing entries with lower signal, append to end of list. */
  123.     ui->list->addItem(item);
  124.  
  125.     if (path == _currentBSS)
  126.         ui->list->setCurrentItem(item);
  127.  
  128.     bss->deleteLater();
  129. }
  130.  
  131. void WifiSettingsDialog::accept()
  132. {
  133.     QVariantMap properties = ui->list->currentItem()->data(Qt::UserRole).toMap();
  134.  
  135.     QString username, password;
  136.     QString ifname = properties.value("ifname");
  137.     QString ssid = properties.value("SSID");
  138.     bool useWPS = ui->WpsRadio->isEnabled() && ui->WpsRadio->isChecked();
  139.  
  140.     if (ui->userEdit->isEnabled())
  141.         username = ui->userEdit->text();
  142.     if (ui->passwordEdit->isEnabled())
  143.         password = ui->passwordEdit->text();
  144.  
  145.     if (connectToWifi(ifname, ssid, username, password, useWPS))
  146.         QDialog::accept();
  147. }
  148.  
  149. bool WifiSettingsDialog::connectToWifi(const QString &ifname, const QString &ssid, const QString &username, const QString &password, bool useWPS)
  150. {
  151.     QDBusObjectPath ifpath = wpa->GetInterface(ifname).value();
  152.     FiW1Wpa_supplicant1InterfaceInterface interface = WpaFactory::createInterfaceProxy(ifpath, this);
  153.  
  154.     /* Clear the icon showing the current connection (if any) */
  155.     for (int i=0; i< ui->list->count(); i++)
  156.     {
  157.         QListWidgetItem *wi = ui->list->item(i);
  158.         if ( wi->data(SecondIconRole).isValid() )
  159.         {
  160.             wi->setData(SecondIconRole, QVariant() );
  161.         }
  162.     }
  163.     _currentBSS = QDBusObjectPath();
  164.  
  165.     _qpd = new QProgressDialog("", tr("Cancel"), 0, 0, this, Qt::Window | Qt::CustomizeWindowHint | Qt::WindowTitleHint);
  166.     _qpd->show();
  167.     ui->buttonBox->button(QDialogButtonBox::Ok)->setEnabled(false);
  168.  
  169.     if (!QNetworkInterface::interfaceFromName(ifname).addressEntries().isEmpty())
  170.     {
  171.         _qpd->setLabelText(tr("Releasing old DHCP lease"));
  172.         QApplication::processEvents();
  173.  
  174.         QStringList args;
  175.         args << "--release" << ifname;
  176.         QProcess::execute("/sbin/dhcpcd", args);
  177.         /* Give the dhcp client some time to say goodbye to the DHCP server */
  178.         msleep(100);
  179.  
  180.         /* Make sure IP is unset before proceeding */
  181.         args.clear();
  182.         args << ifname << "0.0.0.0";
  183.         QProcess::execute("/sbin/ifconfig", args);
  184.     }
  185.  
  186.     _qpd->setLabelText(tr("Disconnecting"));
  187.     QApplication::processEvents();
  188.     interface->Disconnect().waitForFinished();
  189.     interface->RemoveAllNetworks();
  190.  
  191.     _qpd->setLabelText(tr("Connecting"));
  192.     QApplication::processEvents();
  193.  
  194.     if (useWPS)
  195.     {
  196.         /* WPS authentication */
  197.         FiW1Wpa_supplicant1InterfaceWPSInterface *wps = WpaFactory::createWPSInterfaceProxy(ifpath);
  198.         QVariantMap config;
  199.         config.insert("Role", "enrollee");
  200.         config.insert("Type", "pbc");
  201.         /* TODO: should we restrict WPS to the BSSID of the access point selected? */
  202.         wps->Start(config).waitForFinished();
  203.         wps->deleteLater();
  204.     }
  205.     else
  206.     {
  207.         QVariantMap config;
  208.         config.insert("ssid", ssid);
  209.         if (!username.isEmpty())
  210.         {
  211.             config.insert("key_mgmt", "WPA-EAP");
  212.             config.insert("identity", username);
  213.             config.insert("password", password);
  214.         }
  215.         else if (!password.isEmpty())
  216.         {
  217.             config.insert("psk", password);
  218.         }
  219.         else
  220.         {
  221.             config.insert("key_mgmt", "NONE");
  222.             config.insert("auth_alg", "OPEN");
  223.         }
  224.  
  225.         qDebug() << "Connecting to new wifi network, connection parameters:" << config;
  226.         /* Set _connectiong to true. If we receive a "state => disconnected"
  227.            property change signal from this point, assume authentication failed */
  228.         _connecting = true;
  229.         /* Add network to configuration, and select the network */
  230.         interface->SelectNetwork( interface->AddNetwork(config).value() );
  231.     }
  232.  
  233.     /* Check if we have a DHCP lease every 100 msec, while displaying the progress dialog */
  234.     while (QNetworkInterface::interfaceFromName(ifname).addressEntries().isEmpty() && !_qpd->wasCanceled())
  235.     {
  236.         msleep(100);
  237.     }
  238.  
  239.     _connecting = false;
  240.     _qpd->hide();
  241.     _qpd->deleteLater();
  242.     _qpd = NULL;
  243.  
  244.     if (QNetworkInterface::interfaceFromName(ifname).addressEntries().isEmpty())
  245.     {
  246.         interface->Disconnect();
  247.         /* Re-enable OK button */
  248.         checkSettings();
  249.         return false;
  250.     }
  251.     else
  252.     {
  253.         /* There does not seem to be a DBus command to save the configuration.
  254.            So ask wpa_cli to do it for us. */
  255.         QStringList args;
  256.         args << "-i"+ifname << "save_config";
  257.         qDebug() << "Saving wifi configuration";
  258.         QProcess::execute("/usr/sbin/wpa_cli", args);
  259.  
  260.         return true;
  261.     }
  262. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement