Advertisement
Guest User

Untitled

a guest
Feb 7th, 2018
149
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 10.07 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.         QString 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.     /* Clear the icon showing the current connection (if any) */
  152.     for (int i=0; i< ui->list->count(); i++)
  153.     {
  154.         QListWidgetItem *wi = ui->list->item(i);
  155.         if ( wi->data(SecondIconRole).isValid() )
  156.         {
  157.             wi->setData(SecondIconRole, QVariant() );
  158.         }
  159.     }
  160.     _currentBSS = QDBusObjectPath();
  161.  
  162.     _qpd = new QProgressDialog("", tr("Cancel"), 0, 0, this, Qt::Window | Qt::CustomizeWindowHint | Qt::WindowTitleHint);
  163.     _qpd->show();
  164.     ui->buttonBox->button(QDialogButtonBox::Ok)->setEnabled(false);
  165.  
  166.     /* Disconnect all wifi interfaces */
  167.     FiW1Wpa_supplicant1Interface *wpa = WpaFactory::createWpaSupplicantProxy(this);
  168.     QList<QDBusObjectPath> ifaces = wpa->interfaces();
  169.  
  170.     foreach (QDBusObjectPath d_ifpath, ifaces)
  171.     {
  172.         FiW1Wpa_supplicant1InterfaceInterface d_interface = WpaFactory::createInterfaceProxy(d_ifpath, this);
  173.         QString d_ifname = d_interface->ifname();
  174.  
  175.         if (!QNetworkInterface::interfaceFromName(d_ifname).addressEntries().isEmpty())
  176.         {
  177.             _qpd->setLabelText(tr("Releasing old DHCP lease"));
  178.             QApplication::processEvents();
  179.  
  180.             QStringList args;
  181.             args << "--release" << d_ifname;
  182.             QProcess::execute("/sbin/dhcpcd", args);
  183.             /* Give the dhcp client some time to say goodbye to the DHCP server */
  184.             msleep(100);
  185.  
  186.             /* Make sure IP is unset before proceeding */
  187.             args.clear();
  188.             args << d_ifname << "0.0.0.0";
  189.             QProcess::execute("/sbin/ifconfig", args);
  190.         }
  191.  
  192.         /* Maybe add ifname to the _qpd labels */
  193.         _qpd->setLabelText(tr("Disconnecting"));
  194.         QApplication::processEvents();
  195.         d_interface->Disconnect().waitForFinished();
  196.         d_interface->RemoveAllNetworks();
  197.     }
  198.  
  199.     /* Connect */
  200.     QDBusObjectPath ifpath = wpa->GetInterface(ifname).value();
  201.     FiW1Wpa_supplicant1InterfaceInterface interface = WpaFactory::createInterfaceProxy(ifpath, this);
  202.  
  203.     _qpd->setLabelText(tr("Connecting"));
  204.     QApplication::processEvents();
  205.  
  206.     if (useWPS)
  207.     {
  208.         /* WPS authentication */
  209.         FiW1Wpa_supplicant1InterfaceWPSInterface *wps = WpaFactory::createWPSInterfaceProxy(ifpath);
  210.         QVariantMap config;
  211.         config.insert("Role", "enrollee");
  212.         config.insert("Type", "pbc");
  213.         /* TODO: should we restrict WPS to the BSSID of the access point selected? */
  214.         wps->Start(config).waitForFinished();
  215.         wps->deleteLater();
  216.     }
  217.     else
  218.     {
  219.         QVariantMap config;
  220.         config.insert("ssid", ssid);
  221.         if (!username.isEmpty())
  222.         {
  223.             config.insert("key_mgmt", "WPA-EAP");
  224.             config.insert("identity", username);
  225.             config.insert("password", password);
  226.         }
  227.         else if (!password.isEmpty())
  228.         {
  229.             config.insert("psk", password);
  230.         }
  231.         else
  232.         {
  233.             config.insert("key_mgmt", "NONE");
  234.             config.insert("auth_alg", "OPEN");
  235.         }
  236.  
  237.         qDebug() << "Connecting to new wifi network, connection parameters:" << config;
  238.         /* Set _connectiong to true. If we receive a "state => disconnected"
  239.            property change signal from this point, assume authentication failed */
  240.         _connecting = true;
  241.         /* Add network to configuration, and select the network */
  242.         interface->SelectNetwork( interface->AddNetwork(config).value() );
  243.     }
  244.  
  245.     /* Check if we have a DHCP lease every 100 msec, while displaying the progress dialog */
  246.     while (QNetworkInterface::interfaceFromName(ifname).addressEntries().isEmpty() && !_qpd->wasCanceled())
  247.     {
  248.         msleep(100);
  249.     }
  250.  
  251.     _connecting = false;
  252.     _qpd->hide();
  253.     _qpd->deleteLater();
  254.     _qpd = NULL;
  255.  
  256.     if (QNetworkInterface::interfaceFromName(ifname).addressEntries().isEmpty())
  257.     {
  258.         interface->Disconnect();
  259.         /* Re-enable OK button */
  260.         checkSettings();
  261.         return false;
  262.     }
  263.     else
  264.     {
  265.         /* There does not seem to be a DBus command to save the configuration.
  266.            So ask wpa_cli to do it for us. */
  267.         QStringList args;
  268.         args << "-i"+ifname << "save_config";
  269.         qDebug() << "Saving wifi configuration";
  270.         QProcess::execute("/usr/sbin/wpa_cli", args);
  271.  
  272.         return true;
  273.     }
  274. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement