wpagui.cpp
Go to the documentation of this file.
00001 /*
00002  * wpa_gui - WpaGui class
00003  * Copyright (c) 2005-2008, Jouni Malinen <j@w1.fi>
00004  *
00005  * This program is free software; you can redistribute it and/or modify
00006  * it under the terms of the GNU General Public License version 2 as
00007  * published by the Free Software Foundation.
00008  *
00009  * Alternatively, this software may be distributed under the terms of BSD
00010  * license.
00011  *
00012  * See README and COPYING for more details.
00013  */
00014 
00015 #ifdef __MINGW32__
00016 /* Need to get getopt() */
00017 #include <unistd.h>
00018 #endif
00019 
00020 #ifdef CONFIG_NATIVE_WINDOWS
00021 #include <windows.h>
00022 #endif /* CONFIG_NATIVE_WINDOWS */
00023 
00024 #include <cstdio>
00025 #include <QMessageBox>
00026 #include <QCloseEvent>
00027 #include <QImageReader>
00028 #include <QSettings>
00029 
00030 #include "wpagui.h"
00031 #include "dirent.h"
00032 #include "common/wpa_ctrl.h"
00033 #include "userdatarequest.h"
00034 #include "networkconfig.h"
00035 
00036 #if 1
00037 /* Silence stdout */
00038 #define printf wpagui_printf
00039 static int wpagui_printf(const char *, ...)
00040 {
00041         return 0;
00042 }
00043 #endif
00044 
00045 WpaGui::WpaGui(QApplication *_app, QWidget *parent, const char *, Qt::WFlags)
00046         : QMainWindow(parent), app(_app)
00047 {
00048         setupUi(this);
00049 
00050 #ifdef CONFIG_NATIVE_WINDOWS
00051         fileStopServiceAction = new QAction(this);
00052         fileStopServiceAction->setObjectName("Stop Service");
00053         fileStopServiceAction->setIconText(tr("Stop Service"));
00054         fileMenu->insertAction(actionWPS, fileStopServiceAction);
00055 
00056         fileStartServiceAction = new QAction(this);
00057         fileStartServiceAction->setObjectName("Start Service");
00058         fileStartServiceAction->setIconText(tr("Start Service"));
00059         fileMenu->insertAction(fileStopServiceAction, fileStartServiceAction);
00060 
00061         connect(fileStartServiceAction, SIGNAL(triggered()), this,
00062                 SLOT(startService()));
00063         connect(fileStopServiceAction, SIGNAL(triggered()), this,
00064                 SLOT(stopService()));
00065 
00066         addInterfaceAction = new QAction(this);
00067         addInterfaceAction->setIconText(tr("Add Interface"));
00068         fileMenu->insertAction(fileStartServiceAction, addInterfaceAction);
00069 
00070         connect(addInterfaceAction, SIGNAL(triggered()), this,
00071                 SLOT(addInterface()));
00072 #endif /* CONFIG_NATIVE_WINDOWS */
00073 
00074         (void) statusBar();
00075 
00076         /*
00077          * Disable WPS tab by default; it will be enabled if wpa_supplicant is
00078          * built with WPS support.
00079          */
00080         wpsTab->setEnabled(false);
00081         wpaguiTab->setTabEnabled(wpaguiTab->indexOf(wpsTab), false);
00082 
00083         connect(fileEventHistoryAction, SIGNAL(triggered()), this,
00084                 SLOT(eventHistory()));
00085         connect(fileSaveConfigAction, SIGNAL(triggered()), this,
00086                 SLOT(saveConfig()));
00087         connect(actionWPS, SIGNAL(triggered()), this, SLOT(wpsDialog()));
00088         connect(actionPeers, SIGNAL(triggered()), this, SLOT(peersDialog()));
00089         connect(fileExitAction, SIGNAL(triggered()), qApp, SLOT(quit()));
00090         connect(networkAddAction, SIGNAL(triggered()), this,
00091                 SLOT(addNetwork()));
00092         connect(networkEditAction, SIGNAL(triggered()), this,
00093                 SLOT(editSelectedNetwork()));
00094         connect(networkRemoveAction, SIGNAL(triggered()), this,
00095                 SLOT(removeSelectedNetwork()));
00096         connect(networkEnableAllAction, SIGNAL(triggered()), this,
00097                 SLOT(enableAllNetworks()));
00098         connect(networkDisableAllAction, SIGNAL(triggered()), this,
00099                 SLOT(disableAllNetworks()));
00100         connect(networkRemoveAllAction, SIGNAL(triggered()), this,
00101                 SLOT(removeAllNetworks()));
00102         connect(helpIndexAction, SIGNAL(triggered()), this, SLOT(helpIndex()));
00103         connect(helpContentsAction, SIGNAL(triggered()), this,
00104                 SLOT(helpContents()));
00105         connect(helpAboutAction, SIGNAL(triggered()), this, SLOT(helpAbout()));
00106         connect(disconnectButton, SIGNAL(clicked()), this, SLOT(disconnect()));
00107         connect(scanButton, SIGNAL(clicked()), this, SLOT(scan()));
00108         connect(connectButton, SIGNAL(clicked()), this, SLOT(connectB()));
00109         connect(adapterSelect, SIGNAL(activated(const QString&)), this,
00110                 SLOT(selectAdapter(const QString&)));
00111         connect(networkSelect, SIGNAL(activated(const QString&)), this,
00112                 SLOT(selectNetwork(const QString&)));
00113         connect(addNetworkButton, SIGNAL(clicked()), this, SLOT(addNetwork()));
00114         connect(editNetworkButton, SIGNAL(clicked()), this,
00115                 SLOT(editListedNetwork()));
00116         connect(removeNetworkButton, SIGNAL(clicked()), this,
00117                 SLOT(removeListedNetwork()));
00118         connect(networkList, SIGNAL(itemSelectionChanged()), this,
00119                 SLOT(updateNetworkDisabledStatus()));
00120         connect(enableRadioButton, SIGNAL(toggled(bool)), this,
00121                 SLOT(enableListedNetwork(bool)));
00122         connect(disableRadioButton, SIGNAL(toggled(bool)), this,
00123                 SLOT(disableListedNetwork(bool)));
00124         connect(scanNetworkButton, SIGNAL(clicked()), this, SLOT(scan()));
00125         connect(networkList, SIGNAL(itemDoubleClicked(QListWidgetItem *)),
00126                 this, SLOT(editListedNetwork()));
00127         connect(wpaguiTab, SIGNAL(currentChanged(int)), this,
00128                 SLOT(tabChanged(int)));
00129         connect(wpsPbcButton, SIGNAL(clicked()), this, SLOT(wpsPbc()));
00130         connect(wpsPinButton, SIGNAL(clicked()), this, SLOT(wpsGeneratePin()));
00131         connect(wpsApPinEdit, SIGNAL(textChanged(const QString &)), this,
00132                 SLOT(wpsApPinChanged(const QString &)));
00133         connect(wpsApPinButton, SIGNAL(clicked()), this, SLOT(wpsApPin()));
00134 
00135         eh = NULL;
00136         scanres = NULL;
00137         peers = NULL;
00138         add_iface = NULL;
00139         udr = NULL;
00140         tray_icon = NULL;
00141         startInTray = false;
00142         ctrl_iface = NULL;
00143         ctrl_conn = NULL;
00144         monitor_conn = NULL;
00145         msgNotifier = NULL;
00146         ctrl_iface_dir = strdup("/var/run/wpa_supplicant");
00147 
00148         parse_argv();
00149 
00150 #ifndef QT_NO_SESSIONMANAGER
00151         if (app->isSessionRestored()) {
00152                 QSettings settings("wpa_supplicant", "wpa_gui");
00153                 settings.beginGroup("state");
00154                 if (app->sessionId().compare(settings.value("session_id").
00155                                              toString()) == 0)
00156                         startInTray = settings.value("in_tray").toBool();
00157                 settings.endGroup();
00158         }
00159 #endif
00160 
00161         if (QSystemTrayIcon::isSystemTrayAvailable())
00162                 createTrayIcon(startInTray);
00163         else
00164                 show();
00165 
00166         connectedToService = false;
00167         textStatus->setText(tr("connecting to wpa_supplicant"));
00168         timer = new QTimer(this);
00169         connect(timer, SIGNAL(timeout()), SLOT(ping()));
00170         timer->setSingleShot(FALSE);
00171         timer->start(1000);
00172 
00173         if (openCtrlConnection(ctrl_iface) < 0) {
00174                 printf("Failed to open control connection to "
00175                        "wpa_supplicant.\n");
00176         }
00177 
00178         updateStatus();
00179         networkMayHaveChanged = true;
00180         updateNetworks();
00181 }
00182 
00183 
00184 WpaGui::~WpaGui()
00185 {
00186         delete msgNotifier;
00187 
00188         if (monitor_conn) {
00189                 wpa_ctrl_detach(monitor_conn);
00190                 wpa_ctrl_close(monitor_conn);
00191                 monitor_conn = NULL;
00192         }
00193         if (ctrl_conn) {
00194                 wpa_ctrl_close(ctrl_conn);
00195                 ctrl_conn = NULL;
00196         }
00197 
00198         if (eh) {
00199                 eh->close();
00200                 delete eh;
00201                 eh = NULL;
00202         }
00203 
00204         if (scanres) {
00205                 scanres->close();
00206                 delete scanres;
00207                 scanres = NULL;
00208         }
00209 
00210         if (peers) {
00211                 peers->close();
00212                 delete peers;
00213                 peers = NULL;
00214         }
00215 
00216         if (add_iface) {
00217                 add_iface->close();
00218                 delete add_iface;
00219                 add_iface = NULL;
00220         }
00221 
00222         if (udr) {
00223                 udr->close();
00224                 delete udr;
00225                 udr = NULL;
00226         }
00227 
00228         free(ctrl_iface);
00229         ctrl_iface = NULL;
00230 
00231         free(ctrl_iface_dir);
00232         ctrl_iface_dir = NULL;
00233 }
00234 
00235 
00236 void WpaGui::languageChange()
00237 {
00238         retranslateUi(this);
00239 }
00240 
00241 
00242 void WpaGui::parse_argv()
00243 {
00244         int c;
00245         for (;;) {
00246                 c = getopt(qApp->argc(), qApp->argv(), "i:p:t");
00247                 if (c < 0)
00248                         break;
00249                 switch (c) {
00250                 case 'i':
00251                         free(ctrl_iface);
00252                         ctrl_iface = strdup(optarg);
00253                         break;
00254                 case 'p':
00255                         free(ctrl_iface_dir);
00256                         ctrl_iface_dir = strdup(optarg);
00257                         break;
00258                 case 't':
00259                         startInTray = true;
00260                         break;
00261                 }
00262         }
00263 }
00264 
00265 
00266 int WpaGui::openCtrlConnection(const char *ifname)
00267 {
00268         char *cfile;
00269         int flen;
00270         char buf[2048], *pos, *pos2;
00271         size_t len;
00272 
00273         if (ifname) {
00274                 if (ifname != ctrl_iface) {
00275                         free(ctrl_iface);
00276                         ctrl_iface = strdup(ifname);
00277                 }
00278         } else {
00279 #ifdef CONFIG_CTRL_IFACE_UDP
00280                 free(ctrl_iface);
00281                 ctrl_iface = strdup("udp");
00282 #endif /* CONFIG_CTRL_IFACE_UDP */
00283 #ifdef CONFIG_CTRL_IFACE_UNIX
00284                 struct dirent *dent;
00285                 DIR *dir = opendir(ctrl_iface_dir);
00286                 free(ctrl_iface);
00287                 ctrl_iface = NULL;
00288                 if (dir) {
00289                         while ((dent = readdir(dir))) {
00290 #ifdef _DIRENT_HAVE_D_TYPE
00291                                 /* Skip the file if it is not a socket.
00292                                  * Also accept DT_UNKNOWN (0) in case
00293                                  * the C library or underlying file
00294                                  * system does not support d_type. */
00295                                 if (dent->d_type != DT_SOCK &&
00296                                     dent->d_type != DT_UNKNOWN)
00297                                         continue;
00298 #endif /* _DIRENT_HAVE_D_TYPE */
00299 
00300                                 if (strcmp(dent->d_name, ".") == 0 ||
00301                                     strcmp(dent->d_name, "..") == 0)
00302                                         continue;
00303                                 printf("Selected interface '%s'\n",
00304                                        dent->d_name);
00305                                 ctrl_iface = strdup(dent->d_name);
00306                                 break;
00307                         }
00308                         closedir(dir);
00309                 }
00310 #endif /* CONFIG_CTRL_IFACE_UNIX */
00311 #ifdef CONFIG_CTRL_IFACE_NAMED_PIPE
00312                 struct wpa_ctrl *ctrl;
00313                 int ret;
00314 
00315                 free(ctrl_iface);
00316                 ctrl_iface = NULL;
00317 
00318                 ctrl = wpa_ctrl_open(NULL);
00319                 if (ctrl) {
00320                         len = sizeof(buf) - 1;
00321                         ret = wpa_ctrl_request(ctrl, "INTERFACES", 10, buf,
00322                                                &len, NULL);
00323                         if (ret >= 0) {
00324                                 connectedToService = true;
00325                                 buf[len] = '\0';
00326                                 pos = strchr(buf, '\n');
00327                                 if (pos)
00328                                         *pos = '\0';
00329                                 ctrl_iface = strdup(buf);
00330                         }
00331                         wpa_ctrl_close(ctrl);
00332                 }
00333 #endif /* CONFIG_CTRL_IFACE_NAMED_PIPE */
00334         }
00335 
00336         if (ctrl_iface == NULL) {
00337 #ifdef CONFIG_NATIVE_WINDOWS
00338                 static bool first = true;
00339                 if (first && !serviceRunning()) {
00340                         first = false;
00341                         if (QMessageBox::warning(
00342                                     this, qAppName(),
00343                                     tr("wpa_supplicant service is not "
00344                                        "running.\n"
00345                                        "Do you want to start it?"),
00346                                     QMessageBox::Yes | QMessageBox::No) ==
00347                             QMessageBox::Yes)
00348                                 startService();
00349                 }
00350 #endif /* CONFIG_NATIVE_WINDOWS */
00351                 return -1;
00352         }
00353 
00354 #ifdef CONFIG_CTRL_IFACE_UNIX
00355         flen = strlen(ctrl_iface_dir) + strlen(ctrl_iface) + 2;
00356         cfile = (char *) malloc(flen);
00357         if (cfile == NULL)
00358                 return -1;
00359         snprintf(cfile, flen, "%s/%s", ctrl_iface_dir, ctrl_iface);
00360 #else /* CONFIG_CTRL_IFACE_UNIX */
00361         flen = strlen(ctrl_iface) + 1;
00362         cfile = (char *) malloc(flen);
00363         if (cfile == NULL)
00364                 return -1;
00365         snprintf(cfile, flen, "%s", ctrl_iface);
00366 #endif /* CONFIG_CTRL_IFACE_UNIX */
00367 
00368         if (ctrl_conn) {
00369                 wpa_ctrl_close(ctrl_conn);
00370                 ctrl_conn = NULL;
00371         }
00372 
00373         if (monitor_conn) {
00374                 delete msgNotifier;
00375                 msgNotifier = NULL;
00376                 wpa_ctrl_detach(monitor_conn);
00377                 wpa_ctrl_close(monitor_conn);
00378                 monitor_conn = NULL;
00379         }
00380 
00381         printf("Trying to connect to '%s'\n", cfile);
00382         ctrl_conn = wpa_ctrl_open(cfile);
00383         if (ctrl_conn == NULL) {
00384                 free(cfile);
00385                 return -1;
00386         }
00387         monitor_conn = wpa_ctrl_open(cfile);
00388         free(cfile);
00389         if (monitor_conn == NULL) {
00390                 wpa_ctrl_close(ctrl_conn);
00391                 return -1;
00392         }
00393         if (wpa_ctrl_attach(monitor_conn)) {
00394                 printf("Failed to attach to wpa_supplicant\n");
00395                 wpa_ctrl_close(monitor_conn);
00396                 monitor_conn = NULL;
00397                 wpa_ctrl_close(ctrl_conn);
00398                 ctrl_conn = NULL;
00399                 return -1;
00400         }
00401 
00402 #if defined(CONFIG_CTRL_IFACE_UNIX) || defined(CONFIG_CTRL_IFACE_UDP)
00403         msgNotifier = new QSocketNotifier(wpa_ctrl_get_fd(monitor_conn),
00404                                           QSocketNotifier::Read, this);
00405         connect(msgNotifier, SIGNAL(activated(int)), SLOT(receiveMsgs()));
00406 #endif
00407 
00408         adapterSelect->clear();
00409         adapterSelect->addItem(ctrl_iface);
00410         adapterSelect->setCurrentIndex(0);
00411 
00412         len = sizeof(buf) - 1;
00413         if (wpa_ctrl_request(ctrl_conn, "INTERFACES", 10, buf, &len, NULL) >=
00414             0) {
00415                 buf[len] = '\0';
00416                 pos = buf;
00417                 while (*pos) {
00418                         pos2 = strchr(pos, '\n');
00419                         if (pos2)
00420                                 *pos2 = '\0';
00421                         if (strcmp(pos, ctrl_iface) != 0)
00422                                 adapterSelect->addItem(pos);
00423                         if (pos2)
00424                                 pos = pos2 + 1;
00425                         else
00426                                 break;
00427                 }
00428         }
00429 
00430         len = sizeof(buf) - 1;
00431         if (wpa_ctrl_request(ctrl_conn, "GET_CAPABILITY eap", 18, buf, &len,
00432                              NULL) >= 0) {
00433                 buf[len] = '\0';
00434 
00435                 QString res(buf);
00436                 QStringList types = res.split(QChar(' '));
00437                 bool wps = types.contains("WSC");
00438                 actionWPS->setEnabled(wps);
00439                 wpsTab->setEnabled(wps);
00440                 wpaguiTab->setTabEnabled(wpaguiTab->indexOf(wpsTab), wps);
00441         }
00442 
00443         return 0;
00444 }
00445 
00446 
00447 int WpaGui::ctrlRequest(const char *cmd, char *buf, size_t *buflen)
00448 {
00449         int ret;
00450 
00451         if (ctrl_conn == NULL)
00452                 return -3;
00453         ret = wpa_ctrl_request(ctrl_conn, cmd, strlen(cmd), buf, buflen, NULL);
00454         if (ret == -2)
00455                 printf("'%s' command timed out.\n", cmd);
00456         else if (ret < 0)
00457                 printf("'%s' command failed.\n", cmd);
00458 
00459         return ret;
00460 }
00461 
00462 
00463 QString WpaGui::wpaStateTranslate(char *state)
00464 {
00465         if (!strcmp(state, "DISCONNECTED"))
00466                 return tr("Disconnected");
00467         else if (!strcmp(state, "INACTIVE"))
00468                 return tr("Inactive");
00469         else if (!strcmp(state, "SCANNING"))
00470                 return tr("Scanning");
00471         else if (!strcmp(state, "AUTHENTICATING"))
00472                 return tr("Authenticating");
00473         else if (!strcmp(state, "ASSOCIATING"))
00474                 return tr("Associating");
00475         else if (!strcmp(state, "ASSOCIATED"))
00476                 return tr("Associated");
00477         else if (!strcmp(state, "4WAY_HANDSHAKE"))
00478                 return tr("4-Way Handshake");
00479         else if (!strcmp(state, "GROUP_HANDSHAKE"))
00480                 return tr("Group Handshake");
00481         else if (!strcmp(state, "COMPLETED"))
00482                 return tr("Completed");
00483         else
00484                 return tr("Unknown");
00485 }
00486 
00487 
00488 void WpaGui::updateStatus()
00489 {
00490         char buf[2048], *start, *end, *pos;
00491         size_t len;
00492 
00493         pingsToStatusUpdate = 10;
00494 
00495         len = sizeof(buf) - 1;
00496         if (ctrl_conn == NULL || ctrlRequest("STATUS", buf, &len) < 0) {
00497                 textStatus->setText(tr("Could not get status from "
00498                                        "wpa_supplicant"));
00499                 textAuthentication->clear();
00500                 textEncryption->clear();
00501                 textSsid->clear();
00502                 textBssid->clear();
00503                 textIpAddress->clear();
00504 
00505 #ifdef CONFIG_NATIVE_WINDOWS
00506                 static bool first = true;
00507                 if (first && connectedToService &&
00508                     (ctrl_iface == NULL || *ctrl_iface == '\0')) {
00509                         first = false;
00510                         if (QMessageBox::information(
00511                                     this, qAppName(),
00512                                     tr("No network interfaces in use.\n"
00513                                        "Would you like to add one?"),
00514                                     QMessageBox::Yes | QMessageBox::No) ==
00515                             QMessageBox::Yes)
00516                                 addInterface();
00517                 }
00518 #endif /* CONFIG_NATIVE_WINDOWS */
00519                 return;
00520         }
00521 
00522         buf[len] = '\0';
00523 
00524         bool auth_updated = false, ssid_updated = false;
00525         bool bssid_updated = false, ipaddr_updated = false;
00526         bool status_updated = false;
00527         char *pairwise_cipher = NULL, *group_cipher = NULL;
00528         char *mode = NULL;
00529 
00530         start = buf;
00531         while (*start) {
00532                 bool last = false;
00533                 end = strchr(start, '\n');
00534                 if (end == NULL) {
00535                         last = true;
00536                         end = start;
00537                         while (end[0] && end[1])
00538                                 end++;
00539                 }
00540                 *end = '\0';
00541 
00542                 pos = strchr(start, '=');
00543                 if (pos) {
00544                         *pos++ = '\0';
00545                         if (strcmp(start, "bssid") == 0) {
00546                                 bssid_updated = true;
00547                                 textBssid->setText(pos);
00548                         } else if (strcmp(start, "ssid") == 0) {
00549                                 ssid_updated = true;
00550                                 textSsid->setText(pos);
00551                         } else if (strcmp(start, "ip_address") == 0) {
00552                                 ipaddr_updated = true;
00553                                 textIpAddress->setText(pos);
00554                         } else if (strcmp(start, "wpa_state") == 0) {
00555                                 status_updated = true;
00556                                 textStatus->setText(wpaStateTranslate(pos));
00557                         } else if (strcmp(start, "key_mgmt") == 0) {
00558                                 auth_updated = true;
00559                                 textAuthentication->setText(pos);
00560                                 /* TODO: could add EAP status to this */
00561                         } else if (strcmp(start, "pairwise_cipher") == 0) {
00562                                 pairwise_cipher = pos;
00563                         } else if (strcmp(start, "group_cipher") == 0) {
00564                                 group_cipher = pos;
00565                         } else if (strcmp(start, "mode") == 0) {
00566                                 mode = pos;
00567                         }
00568                 }
00569 
00570                 if (last)
00571                         break;
00572                 start = end + 1;
00573         }
00574         if (status_updated && mode)
00575                 textStatus->setText(textStatus->text() + " (" + mode + ")");
00576 
00577         if (pairwise_cipher || group_cipher) {
00578                 QString encr;
00579                 if (pairwise_cipher && group_cipher &&
00580                     strcmp(pairwise_cipher, group_cipher) != 0) {
00581                         encr.append(pairwise_cipher);
00582                         encr.append(" + ");
00583                         encr.append(group_cipher);
00584                 } else if (pairwise_cipher) {
00585                         encr.append(pairwise_cipher);
00586                 } else {
00587                         encr.append(group_cipher);
00588                         encr.append(" [group key only]");
00589                 }
00590                 textEncryption->setText(encr);
00591         } else
00592                 textEncryption->clear();
00593 
00594         if (!status_updated)
00595                 textStatus->clear();
00596         if (!auth_updated)
00597                 textAuthentication->clear();
00598         if (!ssid_updated)
00599                 textSsid->clear();
00600         if (!bssid_updated)
00601                 textBssid->clear();
00602         if (!ipaddr_updated)
00603                 textIpAddress->clear();
00604 }
00605 
00606 
00607 void WpaGui::updateNetworks()
00608 {
00609         char buf[2048], *start, *end, *id, *ssid, *bssid, *flags;
00610         size_t len;
00611         int first_active = -1;
00612         int was_selected = -1;
00613         bool current = false;
00614 
00615         if (!networkMayHaveChanged)
00616                 return;
00617 
00618         if (networkList->currentRow() >= 0)
00619                 was_selected = networkList->currentRow();
00620 
00621         networkSelect->clear();
00622         networkList->clear();
00623 
00624         if (ctrl_conn == NULL)
00625                 return;
00626 
00627         len = sizeof(buf) - 1;
00628         if (ctrlRequest("LIST_NETWORKS", buf, &len) < 0)
00629                 return;
00630 
00631         buf[len] = '\0';
00632         start = strchr(buf, '\n');
00633         if (start == NULL)
00634                 return;
00635         start++;
00636 
00637         while (*start) {
00638                 bool last = false;
00639                 end = strchr(start, '\n');
00640                 if (end == NULL) {
00641                         last = true;
00642                         end = start;
00643                         while (end[0] && end[1])
00644                                 end++;
00645                 }
00646                 *end = '\0';
00647 
00648                 id = start;
00649                 ssid = strchr(id, '\t');
00650                 if (ssid == NULL)
00651                         break;
00652                 *ssid++ = '\0';
00653                 bssid = strchr(ssid, '\t');
00654                 if (bssid == NULL)
00655                         break;
00656                 *bssid++ = '\0';
00657                 flags = strchr(bssid, '\t');
00658                 if (flags == NULL)
00659                         break;
00660                 *flags++ = '\0';
00661 
00662                 QString network(id);
00663                 network.append(": ");
00664                 network.append(ssid);
00665                 networkSelect->addItem(network);
00666                 networkList->addItem(network);
00667 
00668                 if (strstr(flags, "[CURRENT]")) {
00669                         networkSelect->setCurrentIndex(networkSelect->count() -
00670                                                       1);
00671                         current = true;
00672                 } else if (first_active < 0 &&
00673                            strstr(flags, "[DISABLED]") == NULL)
00674                         first_active = networkSelect->count() - 1;
00675 
00676                 if (last)
00677                         break;
00678                 start = end + 1;
00679         }
00680 
00681         if (networkSelect->count() > 1)
00682                 networkSelect->addItem(tr("Select any network"));
00683 
00684         if (!current && first_active >= 0)
00685                 networkSelect->setCurrentIndex(first_active);
00686 
00687         if (was_selected >= 0 && networkList->count() > 0) {
00688                 if (was_selected < networkList->count())
00689                         networkList->setCurrentRow(was_selected);
00690                 else
00691                         networkList->setCurrentRow(networkList->count() - 1);
00692         }
00693         else
00694                 networkList->setCurrentRow(networkSelect->currentIndex());
00695 
00696         networkMayHaveChanged = false;
00697 }
00698 
00699 
00700 void WpaGui::helpIndex()
00701 {
00702         printf("helpIndex\n");
00703 }
00704 
00705 
00706 void WpaGui::helpContents()
00707 {
00708         printf("helpContents\n");
00709 }
00710 
00711 
00712 void WpaGui::helpAbout()
00713 {
00714         QMessageBox::about(this, "wpa_gui for wpa_supplicant",
00715                            "Copyright (c) 2003-2008,\n"
00716                            "Jouni Malinen <j@w1.fi>\n"
00717                            "and contributors.\n"
00718                            "\n"
00719                            "This program is free software. You can\n"
00720                            "distribute it and/or modify it under the terms "
00721                            "of\n"
00722                            "the GNU General Public License version 2.\n"
00723                            "\n"
00724                            "Alternatively, this software may be distributed\n"
00725                            "under the terms of the BSD license.\n"
00726                            "\n"
00727                            "This product includes software developed\n"
00728                            "by the OpenSSL Project for use in the\n"
00729                            "OpenSSL Toolkit (http://www.openssl.org/)\n");
00730 }
00731 
00732 
00733 void WpaGui::disconnect()
00734 {
00735         char reply[10];
00736         size_t reply_len = sizeof(reply);
00737         ctrlRequest("DISCONNECT", reply, &reply_len);
00738         stopWpsRun(false);
00739 }
00740 
00741 
00742 void WpaGui::scan()
00743 {
00744         if (scanres) {
00745                 scanres->close();
00746                 delete scanres;
00747         }
00748 
00749         scanres = new ScanResults();
00750         if (scanres == NULL)
00751                 return;
00752         scanres->setWpaGui(this);
00753         scanres->show();
00754         scanres->exec();
00755 }
00756 
00757 
00758 void WpaGui::eventHistory()
00759 {
00760         if (eh) {
00761                 eh->close();
00762                 delete eh;
00763         }
00764 
00765         eh = new EventHistory();
00766         if (eh == NULL)
00767                 return;
00768         eh->addEvents(msgs);
00769         eh->show();
00770         eh->exec();
00771 }
00772 
00773 
00774 void WpaGui::ping()
00775 {
00776         char buf[10];
00777         size_t len;
00778 
00779 #ifdef CONFIG_CTRL_IFACE_NAMED_PIPE
00780         /*
00781          * QSocketNotifier cannot be used with Windows named pipes, so use a
00782          * timer to check for received messages for now. This could be
00783          * optimized be doing something specific to named pipes or Windows
00784          * events, but it is not clear what would be the best way of doing that
00785          * in Qt.
00786          */
00787         receiveMsgs();
00788 #endif /* CONFIG_CTRL_IFACE_NAMED_PIPE */
00789 
00790         if (scanres && !scanres->isVisible()) {
00791                 delete scanres;
00792                 scanres = NULL;
00793         }
00794 
00795         if (eh && !eh->isVisible()) {
00796                 delete eh;
00797                 eh = NULL;
00798         }
00799 
00800         if (udr && !udr->isVisible()) {
00801                 delete udr;
00802                 udr = NULL;
00803         }
00804 
00805         len = sizeof(buf) - 1;
00806         if (ctrlRequest("PING", buf, &len) < 0) {
00807                 printf("PING failed - trying to reconnect\n");
00808                 if (openCtrlConnection(ctrl_iface) >= 0) {
00809                         printf("Reconnected successfully\n");
00810                         pingsToStatusUpdate = 0;
00811                 }
00812         }
00813 
00814         pingsToStatusUpdate--;
00815         if (pingsToStatusUpdate <= 0) {
00816                 updateStatus();
00817                 updateNetworks();
00818         }
00819 
00820 #ifndef CONFIG_CTRL_IFACE_NAMED_PIPE
00821         /* Use less frequent pings and status updates when the main window is
00822          * hidden (running in taskbar). */
00823         int interval = isHidden() ? 5000 : 1000;
00824         if (timer->interval() != interval)
00825                 timer->setInterval(interval);
00826 #endif /* CONFIG_CTRL_IFACE_NAMED_PIPE */
00827 }
00828 
00829 
00830 static int str_match(const char *a, const char *b)
00831 {
00832         return strncmp(a, b, strlen(b)) == 0;
00833 }
00834 
00835 
00836 void WpaGui::processMsg(char *msg)
00837 {
00838         char *pos = msg, *pos2;
00839         int priority = 2;
00840 
00841         if (*pos == '<') {
00842                 /* skip priority */
00843                 pos++;
00844                 priority = atoi(pos);
00845                 pos = strchr(pos, '>');
00846                 if (pos)
00847                         pos++;
00848                 else
00849                         pos = msg;
00850         }
00851 
00852         WpaMsg wm(pos, priority);
00853         if (eh)
00854                 eh->addEvent(wm);
00855         if (peers)
00856                 peers->event_notify(wm);
00857         msgs.append(wm);
00858         while (msgs.count() > 100)
00859                 msgs.pop_front();
00860 
00861         /* Update last message with truncated version of the event */
00862         if (strncmp(pos, "CTRL-", 5) == 0) {
00863                 pos2 = strchr(pos, str_match(pos, WPA_CTRL_REQ) ? ':' : ' ');
00864                 if (pos2)
00865                         pos2++;
00866                 else
00867                         pos2 = pos;
00868         } else
00869                 pos2 = pos;
00870         QString lastmsg = pos2;
00871         lastmsg.truncate(40);
00872         textLastMessage->setText(lastmsg);
00873 
00874         pingsToStatusUpdate = 0;
00875         networkMayHaveChanged = true;
00876 
00877         if (str_match(pos, WPA_CTRL_REQ))
00878                 processCtrlReq(pos + strlen(WPA_CTRL_REQ));
00879         else if (str_match(pos, WPA_EVENT_SCAN_RESULTS) && scanres)
00880                 scanres->updateResults();
00881         else if (str_match(pos, WPA_EVENT_DISCONNECTED))
00882                 showTrayMessage(QSystemTrayIcon::Information, 3,
00883                                 tr("Disconnected from network."));
00884         else if (str_match(pos, WPA_EVENT_CONNECTED)) {
00885                 showTrayMessage(QSystemTrayIcon::Information, 3,
00886                                 tr("Connection to network established."));
00887                 QTimer::singleShot(5 * 1000, this, SLOT(showTrayStatus()));
00888                 stopWpsRun(true);
00889         } else if (str_match(pos, WPS_EVENT_AP_AVAILABLE_PBC)) {
00890                 wpsStatusText->setText(tr("WPS AP in active PBC mode found"));
00891                 if (textStatus->text() == "INACTIVE" ||
00892                     textStatus->text() == "DISCONNECTED")
00893                         wpaguiTab->setCurrentWidget(wpsTab);
00894                 wpsInstructions->setText(tr("Press the PBC button on the "
00895                                             "screen to start registration"));
00896         } else if (str_match(pos, WPS_EVENT_AP_AVAILABLE_PIN)) {
00897                 wpsStatusText->setText(tr("WPS AP with recently selected "
00898                                           "registrar"));
00899                 if (textStatus->text() == "INACTIVE" ||
00900                     textStatus->text() == "DISCONNECTED")
00901                         wpaguiTab->setCurrentWidget(wpsTab);
00902         } else if (str_match(pos, WPS_EVENT_AP_AVAILABLE)) {
00903                 wpsStatusText->setText(tr("WPS AP detected"));
00904         } else if (str_match(pos, WPS_EVENT_OVERLAP)) {
00905                 wpsStatusText->setText(tr("PBC mode overlap detected"));
00906                 wpsInstructions->setText(tr("More than one AP is currently in "
00907                                             "active WPS PBC mode. Wait couple "
00908                                             "of minutes and try again"));
00909                 wpaguiTab->setCurrentWidget(wpsTab);
00910         } else if (str_match(pos, WPS_EVENT_CRED_RECEIVED)) {
00911                 wpsStatusText->setText(tr("Network configuration received"));
00912                 wpaguiTab->setCurrentWidget(wpsTab);
00913         } else if (str_match(pos, WPA_EVENT_EAP_METHOD)) {
00914                 if (strstr(pos, "(WSC)"))
00915                         wpsStatusText->setText(tr("Registration started"));
00916         } else if (str_match(pos, WPS_EVENT_M2D)) {
00917                 wpsStatusText->setText(tr("Registrar does not yet know PIN"));
00918         } else if (str_match(pos, WPS_EVENT_FAIL)) {
00919                 wpsStatusText->setText(tr("Registration failed"));
00920         } else if (str_match(pos, WPS_EVENT_SUCCESS)) {
00921                 wpsStatusText->setText(tr("Registration succeeded"));
00922         }
00923 }
00924 
00925 
00926 void WpaGui::processCtrlReq(const char *req)
00927 {
00928         if (udr) {
00929                 udr->close();
00930                 delete udr;
00931         }
00932         udr = new UserDataRequest();
00933         if (udr == NULL)
00934                 return;
00935         if (udr->setParams(this, req) < 0) {
00936                 delete udr;
00937                 udr = NULL;
00938                 return;
00939         }
00940         udr->show();
00941         udr->exec();
00942 }
00943 
00944 
00945 void WpaGui::receiveMsgs()
00946 {
00947         char buf[256];
00948         size_t len;
00949 
00950         while (monitor_conn && wpa_ctrl_pending(monitor_conn) > 0) {
00951                 len = sizeof(buf) - 1;
00952                 if (wpa_ctrl_recv(monitor_conn, buf, &len) == 0) {
00953                         buf[len] = '\0';
00954                         processMsg(buf);
00955                 }
00956         }
00957 }
00958 
00959 
00960 void WpaGui::connectB()
00961 {
00962         char reply[10];
00963         size_t reply_len = sizeof(reply);
00964         ctrlRequest("REASSOCIATE", reply, &reply_len);
00965 }
00966 
00967 
00968 void WpaGui::selectNetwork( const QString &sel )
00969 {
00970         QString cmd(sel);
00971         char reply[10];
00972         size_t reply_len = sizeof(reply);
00973 
00974         if (cmd.compare(tr("Select any network"))) {
00975                 cmd = "any";
00976         } else {
00977                 int pos = cmd.indexOf(':');
00978                 if (pos < 0) {
00979                         printf("Invalid selectNetwork '%s'\n",
00980                                cmd.toAscii().constData());
00981                         return;
00982                 }
00983                 cmd.truncate(pos);
00984         }
00985         cmd.prepend("SELECT_NETWORK ");
00986         ctrlRequest(cmd.toAscii().constData(), reply, &reply_len);
00987         triggerUpdate();
00988         stopWpsRun(false);
00989 }
00990 
00991 
00992 void WpaGui::enableNetwork(const QString &sel)
00993 {
00994         QString cmd(sel);
00995         char reply[10];
00996         size_t reply_len = sizeof(reply);
00997 
00998         if (!cmd.startsWith("all")) {
00999                 int pos = cmd.indexOf(':');
01000                 if (pos < 0) {
01001                         printf("Invalid enableNetwork '%s'\n",
01002                                cmd.toAscii().constData());
01003                         return;
01004                 }
01005                 cmd.truncate(pos);
01006         }
01007         cmd.prepend("ENABLE_NETWORK ");
01008         ctrlRequest(cmd.toAscii().constData(), reply, &reply_len);
01009         triggerUpdate();
01010 }
01011 
01012 
01013 void WpaGui::disableNetwork(const QString &sel)
01014 {
01015         QString cmd(sel);
01016         char reply[10];
01017         size_t reply_len = sizeof(reply);
01018 
01019         if (!cmd.startsWith("all")) {
01020                 int pos = cmd.indexOf(':');
01021                 if (pos < 0) {
01022                         printf("Invalid disableNetwork '%s'\n",
01023                                cmd.toAscii().constData());
01024                         return;
01025                 }
01026                 cmd.truncate(pos);
01027         }
01028         cmd.prepend("DISABLE_NETWORK ");
01029         ctrlRequest(cmd.toAscii().constData(), reply, &reply_len);
01030         triggerUpdate();
01031 }
01032 
01033 
01034 void WpaGui::editNetwork(const QString &sel)
01035 {
01036         QString cmd(sel);
01037         int id = -1;
01038 
01039         if (!cmd.compare(tr("Select any network"))) {
01040                 int pos = sel.indexOf(':');
01041                 if (pos < 0) {
01042                         printf("Invalid editNetwork '%s'\n",
01043                                cmd.toAscii().constData());
01044                         return;
01045                 }
01046                 cmd.truncate(pos);
01047                 id = cmd.toInt();
01048         }
01049 
01050         NetworkConfig *nc = new NetworkConfig();
01051         if (nc == NULL)
01052                 return;
01053         nc->setWpaGui(this);
01054 
01055         if (id >= 0)
01056                 nc->paramsFromConfig(id);
01057         else
01058                 nc->newNetwork();
01059 
01060         nc->show();
01061         nc->exec();
01062 }
01063 
01064 
01065 void WpaGui::editSelectedNetwork()
01066 {
01067         if (networkSelect->count() < 1) {
01068                 QMessageBox::information(
01069                         this, tr("No Networks"),
01070                         tr("There are no networks to edit.\n"));
01071                 return;
01072         }
01073         QString sel(networkSelect->currentText());
01074         editNetwork(sel);
01075 }
01076 
01077 
01078 void WpaGui::editListedNetwork()
01079 {
01080         if (networkList->currentRow() < 0) {
01081                 QMessageBox::information(this, tr("Select A Network"),
01082                                          tr("Select a network from the list to"
01083                                             " edit it.\n"));
01084                 return;
01085         }
01086         QString sel(networkList->currentItem()->text());
01087         editNetwork(sel);
01088 }
01089 
01090 
01091 void WpaGui::triggerUpdate()
01092 {
01093         updateStatus();
01094         networkMayHaveChanged = true;
01095         updateNetworks();
01096 }
01097 
01098 
01099 void WpaGui::addNetwork()
01100 {
01101         NetworkConfig *nc = new NetworkConfig();
01102         if (nc == NULL)
01103                 return;
01104         nc->setWpaGui(this);
01105         nc->newNetwork();
01106         nc->show();
01107         nc->exec();
01108 }
01109 
01110 
01111 void WpaGui::removeNetwork(const QString &sel)
01112 {
01113         QString cmd(sel);
01114         char reply[10];
01115         size_t reply_len = sizeof(reply);
01116 
01117         if (cmd.compare(tr("Select any network")))
01118                 return;
01119 
01120         if (!cmd.startsWith("all")) {
01121                 int pos = cmd.indexOf(':');
01122                 if (pos < 0) {
01123                         printf("Invalid removeNetwork '%s'\n",
01124                                cmd.toAscii().constData());
01125                         return;
01126                 }
01127                 cmd.truncate(pos);
01128         }
01129         cmd.prepend("REMOVE_NETWORK ");
01130         ctrlRequest(cmd.toAscii().constData(), reply, &reply_len);
01131         triggerUpdate();
01132 }
01133 
01134 
01135 void WpaGui::removeSelectedNetwork()
01136 {
01137         if (networkSelect->count() < 1) {
01138                 QMessageBox::information(this, tr("No Networks"),
01139                                          tr("There are no networks to remove."
01140                                             "\n"));
01141                 return;
01142         }
01143         QString sel(networkSelect->currentText());
01144         removeNetwork(sel);
01145 }
01146 
01147 
01148 void WpaGui::removeListedNetwork()
01149 {
01150         if (networkList->currentRow() < 0) {
01151                 QMessageBox::information(this, tr("Select A Network"),
01152                                          tr("Select a network from the list "
01153                                             "to remove it.\n"));
01154                 return;
01155         }
01156         QString sel(networkList->currentItem()->text());
01157         removeNetwork(sel);
01158 }
01159 
01160 
01161 void WpaGui::enableAllNetworks()
01162 {
01163         QString sel("all");
01164         enableNetwork(sel);
01165 }
01166 
01167 
01168 void WpaGui::disableAllNetworks()
01169 {
01170         QString sel("all");
01171         disableNetwork(sel);
01172 }
01173 
01174 
01175 void WpaGui::removeAllNetworks()
01176 {
01177         QString sel("all");
01178         removeNetwork(sel);
01179 }
01180 
01181 
01182 int WpaGui::getNetworkDisabled(const QString &sel)
01183 {
01184         QString cmd(sel);
01185         char reply[10];
01186         size_t reply_len = sizeof(reply) - 1;
01187         int pos = cmd.indexOf(':');
01188         if (pos < 0) {
01189                 printf("Invalid getNetworkDisabled '%s'\n",
01190                        cmd.toAscii().constData());
01191                 return -1;
01192         }
01193         cmd.truncate(pos);
01194         cmd.prepend("GET_NETWORK ");
01195         cmd.append(" disabled");
01196 
01197         if (ctrlRequest(cmd.toAscii().constData(), reply, &reply_len) >= 0
01198             && reply_len >= 1) {
01199                 reply[reply_len] = '\0';
01200                 if (!str_match(reply, "FAIL"))
01201                         return atoi(reply);
01202         }
01203 
01204         return -1;
01205 }
01206 
01207 
01208 void WpaGui::updateNetworkDisabledStatus()
01209 {
01210         if (networkList->currentRow() < 0)
01211                 return;
01212 
01213         QString sel(networkList->currentItem()->text());
01214 
01215         switch (getNetworkDisabled(sel)) {
01216         case 0:
01217                 if (!enableRadioButton->isChecked())
01218                         enableRadioButton->setChecked(true);
01219                 return;
01220         case 1:
01221                 if (!disableRadioButton->isChecked())
01222                         disableRadioButton->setChecked(true);
01223                 return;
01224         }
01225 }
01226 
01227 
01228 void WpaGui::enableListedNetwork(bool enabled)
01229 {
01230         if (networkList->currentRow() < 0 || !enabled)
01231                 return;
01232 
01233         QString sel(networkList->currentItem()->text());
01234 
01235         if (getNetworkDisabled(sel) == 1)
01236                 enableNetwork(sel);
01237 }
01238 
01239 
01240 void WpaGui::disableListedNetwork(bool disabled)
01241 {
01242         if (networkList->currentRow() < 0 || !disabled)
01243                 return;
01244 
01245         QString sel(networkList->currentItem()->text());
01246 
01247         if (getNetworkDisabled(sel) == 0)
01248                 disableNetwork(sel);
01249 }
01250 
01251 
01252 void WpaGui::saveConfig()
01253 {
01254         char buf[10];
01255         size_t len;
01256 
01257         len = sizeof(buf) - 1;
01258         ctrlRequest("SAVE_CONFIG", buf, &len);
01259 
01260         buf[len] = '\0';
01261 
01262         if (str_match(buf, "FAIL"))
01263                 QMessageBox::warning(
01264                         this, tr("Failed to save configuration"),
01265                         tr("The configuration could not be saved.\n"
01266                            "\n"
01267                            "The update_config=1 configuration option\n"
01268                            "must be used for configuration saving to\n"
01269                            "be permitted.\n"));
01270         else
01271                 QMessageBox::information(
01272                         this, tr("Saved configuration"),
01273                         tr("The current configuration was saved."
01274                            "\n"));
01275 }
01276 
01277 
01278 void WpaGui::selectAdapter( const QString & sel )
01279 {
01280         if (openCtrlConnection(sel.toAscii().constData()) < 0)
01281                 printf("Failed to open control connection to "
01282                        "wpa_supplicant.\n");
01283         updateStatus();
01284         updateNetworks();
01285 }
01286 
01287 
01288 void WpaGui::createTrayIcon(bool trayOnly)
01289 {
01290         QApplication::setQuitOnLastWindowClosed(false);
01291 
01292         tray_icon = new QSystemTrayIcon(this);
01293         tray_icon->setToolTip(qAppName() + tr(" - wpa_supplicant user interface"));
01294         if (QImageReader::supportedImageFormats().contains(QByteArray("svg")))
01295                 tray_icon->setIcon(QIcon(":/icons/wpa_gui.svg"));
01296         else
01297                 tray_icon->setIcon(QIcon(":/icons/wpa_gui.png"));
01298 
01299         connect(tray_icon,
01300                 SIGNAL(activated(QSystemTrayIcon::ActivationReason)),
01301                 this, SLOT(trayActivated(QSystemTrayIcon::ActivationReason)));
01302 
01303         ackTrayIcon = false;
01304 
01305         tray_menu = new QMenu(this);
01306 
01307         disconnectAction = new QAction(tr("&Disconnect"), this);
01308         reconnectAction = new QAction(tr("Re&connect"), this);
01309         connect(disconnectAction, SIGNAL(triggered()), this,
01310                 SLOT(disconnect()));
01311         connect(reconnectAction, SIGNAL(triggered()), this,
01312                 SLOT(connectB()));
01313         tray_menu->addAction(disconnectAction);
01314         tray_menu->addAction(reconnectAction);
01315         tray_menu->addSeparator();
01316 
01317         eventAction = new QAction(tr("&Event History"), this);
01318         scanAction = new QAction(tr("Scan &Results"), this);
01319         statAction = new QAction(tr("S&tatus"), this);
01320         connect(eventAction, SIGNAL(triggered()), this, SLOT(eventHistory()));
01321         connect(scanAction, SIGNAL(triggered()), this, SLOT(scan()));
01322         connect(statAction, SIGNAL(triggered()), this, SLOT(showTrayStatus()));
01323         tray_menu->addAction(eventAction);
01324         tray_menu->addAction(scanAction);
01325         tray_menu->addAction(statAction);
01326         tray_menu->addSeparator();
01327 
01328         showAction = new QAction(tr("&Show Window"), this);
01329         hideAction = new QAction(tr("&Hide Window"), this);
01330         quitAction = new QAction(tr("&Quit"), this);
01331         connect(showAction, SIGNAL(triggered()), this, SLOT(show()));
01332         connect(hideAction, SIGNAL(triggered()), this, SLOT(hide()));
01333         connect(quitAction, SIGNAL(triggered()), qApp, SLOT(quit()));
01334         tray_menu->addAction(showAction);
01335         tray_menu->addAction(hideAction);
01336         tray_menu->addSeparator();
01337         tray_menu->addAction(quitAction);
01338 
01339         tray_icon->setContextMenu(tray_menu);
01340 
01341         tray_icon->show();
01342 
01343         if (!trayOnly)
01344                 show();
01345         inTray = trayOnly;
01346 }
01347 
01348 
01349 void WpaGui::showTrayMessage(QSystemTrayIcon::MessageIcon type, int sec,
01350                              const QString & msg)
01351 {
01352         if (!QSystemTrayIcon::supportsMessages())
01353                 return;
01354 
01355         if (isVisible() || !tray_icon || !tray_icon->isVisible())
01356                 return;
01357 
01358         tray_icon->showMessage(qAppName(), msg, type, sec * 1000);
01359 }
01360 
01361 
01362 void WpaGui::trayActivated(QSystemTrayIcon::ActivationReason how)
01363  {
01364         switch (how) {
01365         /* use close() here instead of hide() and allow the
01366          * custom closeEvent handler take care of children */
01367         case QSystemTrayIcon::Trigger:
01368                 ackTrayIcon = true;
01369                 if (isVisible()) {
01370                         close();
01371                         inTray = true;
01372                 } else {
01373                         show();
01374                         inTray = false;
01375                 }
01376                 break;
01377         case QSystemTrayIcon::MiddleClick:
01378                 showTrayStatus();
01379                 break;
01380         default:
01381                 break;
01382         }
01383 }
01384 
01385 
01386 void WpaGui::showTrayStatus()
01387 {
01388         char buf[2048];
01389         size_t len;
01390 
01391         len = sizeof(buf) - 1;
01392         if (ctrlRequest("STATUS", buf, &len) < 0)
01393                 return;
01394         buf[len] = '\0';
01395 
01396         QString msg, status(buf);
01397 
01398         QStringList lines = status.split(QRegExp("\\n"));
01399         for (QStringList::Iterator it = lines.begin();
01400              it != lines.end(); it++) {
01401                 int pos = (*it).indexOf('=') + 1;
01402                 if (pos < 1)
01403                         continue;
01404 
01405                 if ((*it).startsWith("bssid="))
01406                         msg.append("BSSID:\t" + (*it).mid(pos) + "\n");
01407                 else if ((*it).startsWith("ssid="))
01408                         msg.append("SSID: \t" + (*it).mid(pos) + "\n");
01409                 else if ((*it).startsWith("pairwise_cipher="))
01410                         msg.append("PAIR: \t" + (*it).mid(pos) + "\n");
01411                 else if ((*it).startsWith("group_cipher="))
01412                         msg.append("GROUP:\t" + (*it).mid(pos) + "\n");
01413                 else if ((*it).startsWith("key_mgmt="))
01414                         msg.append("AUTH: \t" + (*it).mid(pos) + "\n");
01415                 else if ((*it).startsWith("wpa_state="))
01416                         msg.append("STATE:\t" + (*it).mid(pos) + "\n");
01417                 else if ((*it).startsWith("ip_address="))
01418                         msg.append("IP:   \t" + (*it).mid(pos) + "\n");
01419                 else if ((*it).startsWith("Supplicant PAE state="))
01420                         msg.append("PAE:  \t" + (*it).mid(pos) + "\n");
01421                 else if ((*it).startsWith("EAP state="))
01422                         msg.append("EAP:  \t" + (*it).mid(pos) + "\n");
01423         }
01424 
01425         if (!msg.isEmpty())
01426                 showTrayMessage(QSystemTrayIcon::Information, 10, msg);
01427 }
01428 
01429 
01430 void WpaGui::closeEvent(QCloseEvent *event)
01431 {
01432         if (eh) {
01433                 eh->close();
01434                 delete eh;
01435                 eh = NULL;
01436         }
01437 
01438         if (scanres) {
01439                 scanres->close();
01440                 delete scanres;
01441                 scanres = NULL;
01442         }
01443 
01444         if (peers) {
01445                 peers->close();
01446                 delete peers;
01447                 peers = NULL;
01448         }
01449 
01450         if (udr) {
01451                 udr->close();
01452                 delete udr;
01453                 udr = NULL;
01454         }
01455 
01456         if (tray_icon && !ackTrayIcon) {
01457                 /* give user a visual hint that the tray icon exists */
01458                 if (QSystemTrayIcon::supportsMessages()) {
01459                         hide();
01460                         showTrayMessage(QSystemTrayIcon::Information, 3,
01461                                         qAppName() +
01462                                         tr(" will keep running in "
01463                                            "the system tray."));
01464                 } else {
01465                         QMessageBox::information(this, qAppName() +
01466                                                  tr(" systray"),
01467                                                  tr("The program will keep "
01468                                                     "running in the system "
01469                                                     "tray."));
01470                 }
01471                 ackTrayIcon = true;
01472         }
01473 
01474         event->accept();
01475 }
01476 
01477 
01478 void WpaGui::wpsDialog()
01479 {
01480         wpaguiTab->setCurrentWidget(wpsTab);
01481 }
01482 
01483 
01484 void WpaGui::peersDialog()
01485 {
01486         if (peers) {
01487                 peers->close();
01488                 delete peers;
01489         }
01490 
01491         peers = new Peers();
01492         if (peers == NULL)
01493                 return;
01494         peers->setWpaGui(this);
01495         peers->show();
01496         peers->exec();
01497 }
01498 
01499 
01500 void WpaGui::tabChanged(int index)
01501 {
01502         if (index != 2)
01503                 return;
01504 
01505         if (wpsRunning)
01506                 return;
01507 
01508         wpsApPinEdit->setEnabled(!bssFromScan.isEmpty());
01509         if (bssFromScan.isEmpty())
01510                 wpsApPinButton->setEnabled(false);
01511 }
01512 
01513 
01514 void WpaGui::wpsPbc()
01515 {
01516         char reply[20];
01517         size_t reply_len = sizeof(reply);
01518 
01519         if (ctrlRequest("WPS_PBC", reply, &reply_len) < 0)
01520                 return;
01521 
01522         wpsPinEdit->setEnabled(false);
01523         if (wpsStatusText->text().compare(tr("WPS AP in active PBC mode found"))) {
01524                 wpsInstructions->setText(tr("Press the push button on the AP to "
01525                                          "start the PBC mode."));
01526         } else {
01527                 wpsInstructions->setText(tr("If you have not yet done so, press "
01528                                          "the push button on the AP to start "
01529                                          "the PBC mode."));
01530         }
01531         wpsStatusText->setText(tr("Waiting for Registrar"));
01532         wpsRunning = true;
01533 }
01534 
01535 
01536 void WpaGui::wpsGeneratePin()
01537 {
01538         char reply[20];
01539         size_t reply_len = sizeof(reply) - 1;
01540 
01541         if (ctrlRequest("WPS_PIN any", reply, &reply_len) < 0)
01542                 return;
01543 
01544         reply[reply_len] = '\0';
01545 
01546         wpsPinEdit->setText(reply);
01547         wpsPinEdit->setEnabled(true);
01548         wpsInstructions->setText(tr("Enter the generated PIN into the Registrar "
01549                                  "(either the internal one in the AP or an "
01550                                  "external one)."));
01551         wpsStatusText->setText(tr("Waiting for Registrar"));
01552         wpsRunning = true;
01553 }
01554 
01555 
01556 void WpaGui::setBssFromScan(const QString &bssid)
01557 {
01558         bssFromScan = bssid;
01559         wpsApPinEdit->setEnabled(!bssFromScan.isEmpty());
01560         wpsApPinButton->setEnabled(wpsApPinEdit->text().length() == 8);
01561         wpsStatusText->setText(tr("WPS AP selected from scan results"));
01562         wpsInstructions->setText(tr("If you want to use an AP device PIN, e.g., "
01563                                  "from a label in the device, enter the eight "
01564                                  "digit AP PIN and click Use AP PIN button."));
01565 }
01566 
01567 
01568 void WpaGui::wpsApPinChanged(const QString &text)
01569 {
01570         wpsApPinButton->setEnabled(text.length() == 8);
01571 }
01572 
01573 
01574 void WpaGui::wpsApPin()
01575 {
01576         char reply[20];
01577         size_t reply_len = sizeof(reply);
01578 
01579         QString cmd("WPS_REG " + bssFromScan + " " + wpsApPinEdit->text());
01580         if (ctrlRequest(cmd.toAscii().constData(), reply, &reply_len) < 0)
01581                 return;
01582 
01583         wpsStatusText->setText(tr("Waiting for AP/Enrollee"));
01584         wpsRunning = true;
01585 }
01586 
01587 
01588 void WpaGui::stopWpsRun(bool success)
01589 {
01590         if (wpsRunning)
01591                 wpsStatusText->setText(success ? tr("Connected to the network") :
01592                                        tr("Stopped"));
01593         else
01594                 wpsStatusText->setText("");
01595         wpsPinEdit->setEnabled(false);
01596         wpsInstructions->setText("");
01597         wpsRunning = false;
01598         bssFromScan = "";
01599         wpsApPinEdit->setEnabled(false);
01600         wpsApPinButton->setEnabled(false);
01601 }
01602 
01603 
01604 #ifdef CONFIG_NATIVE_WINDOWS
01605 
01606 #ifndef WPASVC_NAME
01607 #define WPASVC_NAME TEXT("wpasvc")
01608 #endif
01609 
01610 class ErrorMsg : public QMessageBox {
01611 public:
01612         ErrorMsg(QWidget *parent, DWORD last_err = GetLastError());
01613         void showMsg(QString msg);
01614 private:
01615         DWORD err;
01616 };
01617 
01618 ErrorMsg::ErrorMsg(QWidget *parent, DWORD last_err) :
01619         QMessageBox(parent), err(last_err)
01620 {
01621         setWindowTitle(tr("wpa_gui error"));
01622         setIcon(QMessageBox::Warning);
01623 }
01624 
01625 void ErrorMsg::showMsg(QString msg)
01626 {
01627         LPTSTR buf;
01628 
01629         setText(msg);
01630         if (FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
01631                           FORMAT_MESSAGE_FROM_SYSTEM,
01632                           NULL, err, 0, (LPTSTR) (void *) &buf,
01633                           0, NULL) > 0) {
01634                 QString msg = QString::fromWCharArray(buf);
01635                 setInformativeText(QString("[%1] %2").arg(err).arg(msg));
01636                 LocalFree(buf);
01637         } else {
01638                 setInformativeText(QString("[%1]").arg(err));
01639         }
01640 
01641         exec();
01642 }
01643 
01644 
01645 void WpaGui::startService()
01646 {
01647         SC_HANDLE svc, scm;
01648 
01649         scm = OpenSCManager(0, 0, SC_MANAGER_CONNECT);
01650         if (!scm) {
01651                 ErrorMsg(this).showMsg(tr("OpenSCManager failed"));
01652                 return;
01653         }
01654 
01655         svc = OpenService(scm, WPASVC_NAME, SERVICE_START);
01656         if (!svc) {
01657                 ErrorMsg(this).showMsg(tr("OpenService failed"));
01658                 CloseServiceHandle(scm);
01659                 return;
01660         }
01661 
01662         if (!StartService(svc, 0, NULL)) {
01663                 ErrorMsg(this).showMsg(tr("Failed to start wpa_supplicant "
01664                                        "service"));
01665         }
01666 
01667         CloseServiceHandle(svc);
01668         CloseServiceHandle(scm);
01669 }
01670 
01671 
01672 void WpaGui::stopService()
01673 {
01674         SC_HANDLE svc, scm;
01675         SERVICE_STATUS status;
01676 
01677         scm = OpenSCManager(0, 0, SC_MANAGER_CONNECT);
01678         if (!scm) {
01679                 ErrorMsg(this).showMsg(tr("OpenSCManager failed"));
01680                 return;
01681         }
01682 
01683         svc = OpenService(scm, WPASVC_NAME, SERVICE_STOP);
01684         if (!svc) {
01685                 ErrorMsg(this).showMsg(tr("OpenService failed"));
01686                 CloseServiceHandle(scm);
01687                 return;
01688         }
01689 
01690         if (!ControlService(svc, SERVICE_CONTROL_STOP, &status)) {
01691                 ErrorMsg(this).showMsg(tr("Failed to stop wpa_supplicant "
01692                                        "service"));
01693         }
01694 
01695         CloseServiceHandle(svc);
01696         CloseServiceHandle(scm);
01697 }
01698 
01699 
01700 bool WpaGui::serviceRunning()
01701 {
01702         SC_HANDLE svc, scm;
01703         SERVICE_STATUS status;
01704         bool running = false;
01705 
01706         scm = OpenSCManager(0, 0, SC_MANAGER_CONNECT);
01707         if (!scm) {
01708                 printf("OpenSCManager failed: %d\n", (int) GetLastError());
01709                 return false;
01710         }
01711 
01712         svc = OpenService(scm, WPASVC_NAME, SERVICE_QUERY_STATUS);
01713         if (!svc) {
01714                 printf("OpenService failed: %d\n\n", (int) GetLastError());
01715                 CloseServiceHandle(scm);
01716                 return false;
01717         }
01718 
01719         if (QueryServiceStatus(svc, &status)) {
01720                 if (status.dwCurrentState != SERVICE_STOPPED)
01721                         running = true;
01722         }
01723 
01724         CloseServiceHandle(svc);
01725         CloseServiceHandle(scm);
01726 
01727         return running;
01728 }
01729 
01730 #endif /* CONFIG_NATIVE_WINDOWS */
01731 
01732 
01733 void WpaGui::addInterface()
01734 {
01735         if (add_iface) {
01736                 add_iface->close();
01737                 delete add_iface;
01738         }
01739         add_iface = new AddInterface(this, this);
01740         add_iface->show();
01741         add_iface->exec();
01742 }
01743 
01744 
01745 #ifndef QT_NO_SESSIONMANAGER
01746 void WpaGui::saveState()
01747 {
01748         QSettings settings("wpa_supplicant", "wpa_gui");
01749         settings.beginGroup("state");
01750         settings.setValue("session_id", app->sessionId());
01751         settings.setValue("in_tray", inTray);
01752         settings.endGroup();
01753 }
01754 #endif


wpa_supplicant_node
Author(s): Package maintained by Blaise Gassend
autogenerated on Thu Jan 2 2014 11:25:15