00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #ifdef __MINGW32__
00016
00017 #include <unistd.h>
00018 #endif
00019
00020 #ifdef CONFIG_NATIVE_WINDOWS
00021 #include <windows.h>
00022 #endif
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
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
00073
00074 (void) statusBar();
00075
00076
00077
00078
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
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
00292
00293
00294
00295 if (dent->d_type != DT_SOCK &&
00296 dent->d_type != DT_UNKNOWN)
00297 continue;
00298 #endif
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
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
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
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
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
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
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
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
00782
00783
00784
00785
00786
00787 receiveMsgs();
00788 #endif
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
00822
00823 int interval = isHidden() ? 5000 : 1000;
00824 if (timer->interval() != interval)
00825 timer->setInterval(interval);
00826 #endif
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
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
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
01366
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
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
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