$search
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