Added WirelessManager, a port of wpa_supplicant.
[AROS.git] / workbench / network / WirelessManager / wpa_supplicant / wpa_gui-qt4 / wpagui.cpp
blob2057d67234e1c2188c50f077d8a4db207e3352db
1 /*
2 * wpa_gui - WpaGui class
3 * Copyright (c) 2005-2010, Jouni Malinen <j@w1.fi>
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 as
7 * published by the Free Software Foundation.
9 * Alternatively, this software may be distributed under the terms of BSD
10 * license.
12 * See README and COPYING for more details.
15 #ifdef __MINGW32__
16 /* Need to get getopt() */
17 #include <unistd.h>
18 #endif
20 #ifdef CONFIG_NATIVE_WINDOWS
21 #include <windows.h>
22 #endif /* CONFIG_NATIVE_WINDOWS */
24 #include <cstdio>
25 #include <QMessageBox>
26 #include <QCloseEvent>
27 #include <QImageReader>
28 #include <QSettings>
30 #include "wpagui.h"
31 #include "dirent.h"
32 #include "common/wpa_ctrl.h"
33 #include "userdatarequest.h"
34 #include "networkconfig.h"
36 #if 1
37 /* Silence stdout */
38 #define printf wpagui_printf
39 static int wpagui_printf(const char *, ...)
41 return 0;
43 #endif
45 WpaGui::WpaGui(QApplication *_app, QWidget *parent, const char *, Qt::WFlags)
46 : QMainWindow(parent), app(_app)
48 setupUi(this);
50 #ifdef CONFIG_NATIVE_WINDOWS
51 fileStopServiceAction = new QAction(this);
52 fileStopServiceAction->setObjectName("Stop Service");
53 fileStopServiceAction->setIconText(tr("Stop Service"));
54 fileMenu->insertAction(actionWPS, fileStopServiceAction);
56 fileStartServiceAction = new QAction(this);
57 fileStartServiceAction->setObjectName("Start Service");
58 fileStartServiceAction->setIconText(tr("Start Service"));
59 fileMenu->insertAction(fileStopServiceAction, fileStartServiceAction);
61 connect(fileStartServiceAction, SIGNAL(triggered()), this,
62 SLOT(startService()));
63 connect(fileStopServiceAction, SIGNAL(triggered()), this,
64 SLOT(stopService()));
66 addInterfaceAction = new QAction(this);
67 addInterfaceAction->setIconText(tr("Add Interface"));
68 fileMenu->insertAction(fileStartServiceAction, addInterfaceAction);
70 connect(addInterfaceAction, SIGNAL(triggered()), this,
71 SLOT(addInterface()));
72 #endif /* CONFIG_NATIVE_WINDOWS */
74 (void) statusBar();
77 * Disable WPS tab by default; it will be enabled if wpa_supplicant is
78 * built with WPS support.
80 wpsTab->setEnabled(false);
81 wpaguiTab->setTabEnabled(wpaguiTab->indexOf(wpsTab), false);
83 connect(fileEventHistoryAction, SIGNAL(triggered()), this,
84 SLOT(eventHistory()));
85 connect(fileSaveConfigAction, SIGNAL(triggered()), this,
86 SLOT(saveConfig()));
87 connect(actionWPS, SIGNAL(triggered()), this, SLOT(wpsDialog()));
88 connect(actionPeers, SIGNAL(triggered()), this, SLOT(peersDialog()));
89 connect(fileExitAction, SIGNAL(triggered()), qApp, SLOT(quit()));
90 connect(networkAddAction, SIGNAL(triggered()), this,
91 SLOT(addNetwork()));
92 connect(networkEditAction, SIGNAL(triggered()), this,
93 SLOT(editSelectedNetwork()));
94 connect(networkRemoveAction, SIGNAL(triggered()), this,
95 SLOT(removeSelectedNetwork()));
96 connect(networkEnableAllAction, SIGNAL(triggered()), this,
97 SLOT(enableAllNetworks()));
98 connect(networkDisableAllAction, SIGNAL(triggered()), this,
99 SLOT(disableAllNetworks()));
100 connect(networkRemoveAllAction, SIGNAL(triggered()), this,
101 SLOT(removeAllNetworks()));
102 connect(helpIndexAction, SIGNAL(triggered()), this, SLOT(helpIndex()));
103 connect(helpContentsAction, SIGNAL(triggered()), this,
104 SLOT(helpContents()));
105 connect(helpAboutAction, SIGNAL(triggered()), this, SLOT(helpAbout()));
106 connect(disconnectButton, SIGNAL(clicked()), this, SLOT(disconnect()));
107 connect(scanButton, SIGNAL(clicked()), this, SLOT(scan()));
108 connect(connectButton, SIGNAL(clicked()), this, SLOT(connectB()));
109 connect(adapterSelect, SIGNAL(activated(const QString&)), this,
110 SLOT(selectAdapter(const QString&)));
111 connect(networkSelect, SIGNAL(activated(const QString&)), this,
112 SLOT(selectNetwork(const QString&)));
113 connect(addNetworkButton, SIGNAL(clicked()), this, SLOT(addNetwork()));
114 connect(editNetworkButton, SIGNAL(clicked()), this,
115 SLOT(editListedNetwork()));
116 connect(removeNetworkButton, SIGNAL(clicked()), this,
117 SLOT(removeListedNetwork()));
118 connect(networkList, SIGNAL(itemSelectionChanged()), this,
119 SLOT(updateNetworkDisabledStatus()));
120 connect(enableRadioButton, SIGNAL(toggled(bool)), this,
121 SLOT(enableListedNetwork(bool)));
122 connect(disableRadioButton, SIGNAL(toggled(bool)), this,
123 SLOT(disableListedNetwork(bool)));
124 connect(scanNetworkButton, SIGNAL(clicked()), this, SLOT(scan()));
125 connect(networkList, SIGNAL(itemDoubleClicked(QListWidgetItem *)),
126 this, SLOT(editListedNetwork()));
127 connect(wpaguiTab, SIGNAL(currentChanged(int)), this,
128 SLOT(tabChanged(int)));
129 connect(wpsPbcButton, SIGNAL(clicked()), this, SLOT(wpsPbc()));
130 connect(wpsPinButton, SIGNAL(clicked()), this, SLOT(wpsGeneratePin()));
131 connect(wpsApPinEdit, SIGNAL(textChanged(const QString &)), this,
132 SLOT(wpsApPinChanged(const QString &)));
133 connect(wpsApPinButton, SIGNAL(clicked()), this, SLOT(wpsApPin()));
135 eh = NULL;
136 scanres = NULL;
137 peers = NULL;
138 add_iface = NULL;
139 udr = NULL;
140 tray_icon = NULL;
141 startInTray = false;
142 ctrl_iface = NULL;
143 ctrl_conn = NULL;
144 monitor_conn = NULL;
145 msgNotifier = NULL;
146 ctrl_iface_dir = strdup("/var/run/wpa_supplicant");
148 parse_argv();
150 #ifndef QT_NO_SESSIONMANAGER
151 if (app->isSessionRestored()) {
152 QSettings settings("wpa_supplicant", "wpa_gui");
153 settings.beginGroup("state");
154 if (app->sessionId().compare(settings.value("session_id").
155 toString()) == 0)
156 startInTray = settings.value("in_tray").toBool();
157 settings.endGroup();
159 #endif
161 if (QSystemTrayIcon::isSystemTrayAvailable())
162 createTrayIcon(startInTray);
163 else
164 show();
166 connectedToService = false;
167 textStatus->setText(tr("connecting to wpa_supplicant"));
168 timer = new QTimer(this);
169 connect(timer, SIGNAL(timeout()), SLOT(ping()));
170 timer->setSingleShot(FALSE);
171 timer->start(1000);
173 if (openCtrlConnection(ctrl_iface) < 0) {
174 printf("Failed to open control connection to "
175 "wpa_supplicant.\n");
178 updateStatus();
179 networkMayHaveChanged = true;
180 updateNetworks();
184 WpaGui::~WpaGui()
186 delete msgNotifier;
188 if (monitor_conn) {
189 wpa_ctrl_detach(monitor_conn);
190 wpa_ctrl_close(monitor_conn);
191 monitor_conn = NULL;
193 if (ctrl_conn) {
194 wpa_ctrl_close(ctrl_conn);
195 ctrl_conn = NULL;
198 if (eh) {
199 eh->close();
200 delete eh;
201 eh = NULL;
204 if (scanres) {
205 scanres->close();
206 delete scanres;
207 scanres = NULL;
210 if (peers) {
211 peers->close();
212 delete peers;
213 peers = NULL;
216 if (add_iface) {
217 add_iface->close();
218 delete add_iface;
219 add_iface = NULL;
222 if (udr) {
223 udr->close();
224 delete udr;
225 udr = NULL;
228 free(ctrl_iface);
229 ctrl_iface = NULL;
231 free(ctrl_iface_dir);
232 ctrl_iface_dir = NULL;
236 void WpaGui::languageChange()
238 retranslateUi(this);
242 void WpaGui::parse_argv()
244 int c;
245 for (;;) {
246 c = getopt(qApp->argc(), qApp->argv(), "i:p:t");
247 if (c < 0)
248 break;
249 switch (c) {
250 case 'i':
251 free(ctrl_iface);
252 ctrl_iface = strdup(optarg);
253 break;
254 case 'p':
255 free(ctrl_iface_dir);
256 ctrl_iface_dir = strdup(optarg);
257 break;
258 case 't':
259 startInTray = true;
260 break;
266 int WpaGui::openCtrlConnection(const char *ifname)
268 char *cfile;
269 int flen;
270 char buf[2048], *pos, *pos2;
271 size_t len;
273 if (ifname) {
274 if (ifname != ctrl_iface) {
275 free(ctrl_iface);
276 ctrl_iface = strdup(ifname);
278 } else {
279 #ifdef CONFIG_CTRL_IFACE_UDP
280 free(ctrl_iface);
281 ctrl_iface = strdup("udp");
282 #endif /* CONFIG_CTRL_IFACE_UDP */
283 #ifdef CONFIG_CTRL_IFACE_UNIX
284 struct dirent *dent;
285 DIR *dir = opendir(ctrl_iface_dir);
286 free(ctrl_iface);
287 ctrl_iface = NULL;
288 if (dir) {
289 while ((dent = readdir(dir))) {
290 #ifdef _DIRENT_HAVE_D_TYPE
291 /* Skip the file if it is not a socket.
292 * Also accept DT_UNKNOWN (0) in case
293 * the C library or underlying file
294 * system does not support d_type. */
295 if (dent->d_type != DT_SOCK &&
296 dent->d_type != DT_UNKNOWN)
297 continue;
298 #endif /* _DIRENT_HAVE_D_TYPE */
300 if (strcmp(dent->d_name, ".") == 0 ||
301 strcmp(dent->d_name, "..") == 0)
302 continue;
303 printf("Selected interface '%s'\n",
304 dent->d_name);
305 ctrl_iface = strdup(dent->d_name);
306 break;
308 closedir(dir);
310 #endif /* CONFIG_CTRL_IFACE_UNIX */
311 #ifdef CONFIG_CTRL_IFACE_NAMED_PIPE
312 struct wpa_ctrl *ctrl;
313 int ret;
315 free(ctrl_iface);
316 ctrl_iface = NULL;
318 ctrl = wpa_ctrl_open(NULL);
319 if (ctrl) {
320 len = sizeof(buf) - 1;
321 ret = wpa_ctrl_request(ctrl, "INTERFACES", 10, buf,
322 &len, NULL);
323 if (ret >= 0) {
324 connectedToService = true;
325 buf[len] = '\0';
326 pos = strchr(buf, '\n');
327 if (pos)
328 *pos = '\0';
329 ctrl_iface = strdup(buf);
331 wpa_ctrl_close(ctrl);
333 #endif /* CONFIG_CTRL_IFACE_NAMED_PIPE */
336 if (ctrl_iface == NULL) {
337 #ifdef CONFIG_NATIVE_WINDOWS
338 static bool first = true;
339 if (first && !serviceRunning()) {
340 first = false;
341 if (QMessageBox::warning(
342 this, qAppName(),
343 tr("wpa_supplicant service is not "
344 "running.\n"
345 "Do you want to start it?"),
346 QMessageBox::Yes | QMessageBox::No) ==
347 QMessageBox::Yes)
348 startService();
350 #endif /* CONFIG_NATIVE_WINDOWS */
351 return -1;
354 #ifdef CONFIG_CTRL_IFACE_UNIX
355 flen = strlen(ctrl_iface_dir) + strlen(ctrl_iface) + 2;
356 cfile = (char *) malloc(flen);
357 if (cfile == NULL)
358 return -1;
359 snprintf(cfile, flen, "%s/%s", ctrl_iface_dir, ctrl_iface);
360 #else /* CONFIG_CTRL_IFACE_UNIX */
361 flen = strlen(ctrl_iface) + 1;
362 cfile = (char *) malloc(flen);
363 if (cfile == NULL)
364 return -1;
365 snprintf(cfile, flen, "%s", ctrl_iface);
366 #endif /* CONFIG_CTRL_IFACE_UNIX */
368 if (ctrl_conn) {
369 wpa_ctrl_close(ctrl_conn);
370 ctrl_conn = NULL;
373 if (monitor_conn) {
374 delete msgNotifier;
375 msgNotifier = NULL;
376 wpa_ctrl_detach(monitor_conn);
377 wpa_ctrl_close(monitor_conn);
378 monitor_conn = NULL;
381 printf("Trying to connect to '%s'\n", cfile);
382 ctrl_conn = wpa_ctrl_open(cfile);
383 if (ctrl_conn == NULL) {
384 free(cfile);
385 return -1;
387 monitor_conn = wpa_ctrl_open(cfile);
388 free(cfile);
389 if (monitor_conn == NULL) {
390 wpa_ctrl_close(ctrl_conn);
391 return -1;
393 if (wpa_ctrl_attach(monitor_conn)) {
394 printf("Failed to attach to wpa_supplicant\n");
395 wpa_ctrl_close(monitor_conn);
396 monitor_conn = NULL;
397 wpa_ctrl_close(ctrl_conn);
398 ctrl_conn = NULL;
399 return -1;
402 #if defined(CONFIG_CTRL_IFACE_UNIX) || defined(CONFIG_CTRL_IFACE_UDP)
403 msgNotifier = new QSocketNotifier(wpa_ctrl_get_fd(monitor_conn),
404 QSocketNotifier::Read, this);
405 connect(msgNotifier, SIGNAL(activated(int)), SLOT(receiveMsgs()));
406 #endif
408 adapterSelect->clear();
409 adapterSelect->addItem(ctrl_iface);
410 adapterSelect->setCurrentIndex(0);
412 len = sizeof(buf) - 1;
413 if (wpa_ctrl_request(ctrl_conn, "INTERFACES", 10, buf, &len, NULL) >=
414 0) {
415 buf[len] = '\0';
416 pos = buf;
417 while (*pos) {
418 pos2 = strchr(pos, '\n');
419 if (pos2)
420 *pos2 = '\0';
421 if (strcmp(pos, ctrl_iface) != 0)
422 adapterSelect->addItem(pos);
423 if (pos2)
424 pos = pos2 + 1;
425 else
426 break;
430 len = sizeof(buf) - 1;
431 if (wpa_ctrl_request(ctrl_conn, "GET_CAPABILITY eap", 18, buf, &len,
432 NULL) >= 0) {
433 buf[len] = '\0';
435 QString res(buf);
436 QStringList types = res.split(QChar(' '));
437 bool wps = types.contains("WSC");
438 actionWPS->setEnabled(wps);
439 wpsTab->setEnabled(wps);
440 wpaguiTab->setTabEnabled(wpaguiTab->indexOf(wpsTab), wps);
443 return 0;
447 int WpaGui::ctrlRequest(const char *cmd, char *buf, size_t *buflen)
449 int ret;
451 if (ctrl_conn == NULL)
452 return -3;
453 ret = wpa_ctrl_request(ctrl_conn, cmd, strlen(cmd), buf, buflen, NULL);
454 if (ret == -2)
455 printf("'%s' command timed out.\n", cmd);
456 else if (ret < 0)
457 printf("'%s' command failed.\n", cmd);
459 return ret;
463 QString WpaGui::wpaStateTranslate(char *state)
465 if (!strcmp(state, "DISCONNECTED"))
466 return tr("Disconnected");
467 else if (!strcmp(state, "INACTIVE"))
468 return tr("Inactive");
469 else if (!strcmp(state, "SCANNING"))
470 return tr("Scanning");
471 else if (!strcmp(state, "AUTHENTICATING"))
472 return tr("Authenticating");
473 else if (!strcmp(state, "ASSOCIATING"))
474 return tr("Associating");
475 else if (!strcmp(state, "ASSOCIATED"))
476 return tr("Associated");
477 else if (!strcmp(state, "4WAY_HANDSHAKE"))
478 return tr("4-Way Handshake");
479 else if (!strcmp(state, "GROUP_HANDSHAKE"))
480 return tr("Group Handshake");
481 else if (!strcmp(state, "COMPLETED"))
482 return tr("Completed");
483 else
484 return tr("Unknown");
488 void WpaGui::updateStatus()
490 char buf[2048], *start, *end, *pos;
491 size_t len;
493 pingsToStatusUpdate = 10;
495 len = sizeof(buf) - 1;
496 if (ctrl_conn == NULL || ctrlRequest("STATUS", buf, &len) < 0) {
497 textStatus->setText(tr("Could not get status from "
498 "wpa_supplicant"));
499 textAuthentication->clear();
500 textEncryption->clear();
501 textSsid->clear();
502 textBssid->clear();
503 textIpAddress->clear();
505 #ifdef CONFIG_NATIVE_WINDOWS
506 static bool first = true;
507 if (first && connectedToService &&
508 (ctrl_iface == NULL || *ctrl_iface == '\0')) {
509 first = false;
510 if (QMessageBox::information(
511 this, qAppName(),
512 tr("No network interfaces in use.\n"
513 "Would you like to add one?"),
514 QMessageBox::Yes | QMessageBox::No) ==
515 QMessageBox::Yes)
516 addInterface();
518 #endif /* CONFIG_NATIVE_WINDOWS */
519 return;
522 buf[len] = '\0';
524 bool auth_updated = false, ssid_updated = false;
525 bool bssid_updated = false, ipaddr_updated = false;
526 bool status_updated = false;
527 char *pairwise_cipher = NULL, *group_cipher = NULL;
528 char *mode = NULL;
530 start = buf;
531 while (*start) {
532 bool last = false;
533 end = strchr(start, '\n');
534 if (end == NULL) {
535 last = true;
536 end = start;
537 while (end[0] && end[1])
538 end++;
540 *end = '\0';
542 pos = strchr(start, '=');
543 if (pos) {
544 *pos++ = '\0';
545 if (strcmp(start, "bssid") == 0) {
546 bssid_updated = true;
547 textBssid->setText(pos);
548 } else if (strcmp(start, "ssid") == 0) {
549 ssid_updated = true;
550 textSsid->setText(pos);
551 } else if (strcmp(start, "ip_address") == 0) {
552 ipaddr_updated = true;
553 textIpAddress->setText(pos);
554 } else if (strcmp(start, "wpa_state") == 0) {
555 status_updated = true;
556 textStatus->setText(wpaStateTranslate(pos));
557 } else if (strcmp(start, "key_mgmt") == 0) {
558 auth_updated = true;
559 textAuthentication->setText(pos);
560 /* TODO: could add EAP status to this */
561 } else if (strcmp(start, "pairwise_cipher") == 0) {
562 pairwise_cipher = pos;
563 } else if (strcmp(start, "group_cipher") == 0) {
564 group_cipher = pos;
565 } else if (strcmp(start, "mode") == 0) {
566 mode = pos;
570 if (last)
571 break;
572 start = end + 1;
574 if (status_updated && mode)
575 textStatus->setText(textStatus->text() + " (" + mode + ")");
577 if (pairwise_cipher || group_cipher) {
578 QString encr;
579 if (pairwise_cipher && group_cipher &&
580 strcmp(pairwise_cipher, group_cipher) != 0) {
581 encr.append(pairwise_cipher);
582 encr.append(" + ");
583 encr.append(group_cipher);
584 } else if (pairwise_cipher) {
585 encr.append(pairwise_cipher);
586 } else {
587 encr.append(group_cipher);
588 encr.append(" [group key only]");
590 textEncryption->setText(encr);
591 } else
592 textEncryption->clear();
594 if (!status_updated)
595 textStatus->clear();
596 if (!auth_updated)
597 textAuthentication->clear();
598 if (!ssid_updated)
599 textSsid->clear();
600 if (!bssid_updated)
601 textBssid->clear();
602 if (!ipaddr_updated)
603 textIpAddress->clear();
607 void WpaGui::updateNetworks()
609 char buf[2048], *start, *end, *id, *ssid, *bssid, *flags;
610 size_t len;
611 int first_active = -1;
612 int was_selected = -1;
613 bool current = false;
615 if (!networkMayHaveChanged)
616 return;
618 if (networkList->currentRow() >= 0)
619 was_selected = networkList->currentRow();
621 networkSelect->clear();
622 networkList->clear();
624 if (ctrl_conn == NULL)
625 return;
627 len = sizeof(buf) - 1;
628 if (ctrlRequest("LIST_NETWORKS", buf, &len) < 0)
629 return;
631 buf[len] = '\0';
632 start = strchr(buf, '\n');
633 if (start == NULL)
634 return;
635 start++;
637 while (*start) {
638 bool last = false;
639 end = strchr(start, '\n');
640 if (end == NULL) {
641 last = true;
642 end = start;
643 while (end[0] && end[1])
644 end++;
646 *end = '\0';
648 id = start;
649 ssid = strchr(id, '\t');
650 if (ssid == NULL)
651 break;
652 *ssid++ = '\0';
653 bssid = strchr(ssid, '\t');
654 if (bssid == NULL)
655 break;
656 *bssid++ = '\0';
657 flags = strchr(bssid, '\t');
658 if (flags == NULL)
659 break;
660 *flags++ = '\0';
662 QString network(id);
663 network.append(": ");
664 network.append(ssid);
665 networkSelect->addItem(network);
666 networkList->addItem(network);
668 if (strstr(flags, "[CURRENT]")) {
669 networkSelect->setCurrentIndex(networkSelect->count() -
671 current = true;
672 } else if (first_active < 0 &&
673 strstr(flags, "[DISABLED]") == NULL)
674 first_active = networkSelect->count() - 1;
676 if (last)
677 break;
678 start = end + 1;
681 if (networkSelect->count() > 1)
682 networkSelect->addItem(tr("Select any network"));
684 if (!current && first_active >= 0)
685 networkSelect->setCurrentIndex(first_active);
687 if (was_selected >= 0 && networkList->count() > 0) {
688 if (was_selected < networkList->count())
689 networkList->setCurrentRow(was_selected);
690 else
691 networkList->setCurrentRow(networkList->count() - 1);
693 else
694 networkList->setCurrentRow(networkSelect->currentIndex());
696 networkMayHaveChanged = false;
700 void WpaGui::helpIndex()
702 printf("helpIndex\n");
706 void WpaGui::helpContents()
708 printf("helpContents\n");
712 void WpaGui::helpAbout()
714 QMessageBox::about(this, "wpa_gui for wpa_supplicant",
715 "Copyright (c) 2003-2010,\n"
716 "Jouni Malinen <j@w1.fi>\n"
717 "and contributors.\n"
718 "\n"
719 "This program is free software. You can\n"
720 "distribute it and/or modify it under the terms "
721 "of\n"
722 "the GNU General Public License version 2.\n"
723 "\n"
724 "Alternatively, this software may be distributed\n"
725 "under the terms of the BSD license.\n"
726 "\n"
727 "This product includes software developed\n"
728 "by the OpenSSL Project for use in the\n"
729 "OpenSSL Toolkit (http://www.openssl.org/)\n");
733 void WpaGui::disconnect()
735 char reply[10];
736 size_t reply_len = sizeof(reply);
737 ctrlRequest("DISCONNECT", reply, &reply_len);
738 stopWpsRun(false);
742 void WpaGui::scan()
744 if (scanres) {
745 scanres->close();
746 delete scanres;
749 scanres = new ScanResults();
750 if (scanres == NULL)
751 return;
752 scanres->setWpaGui(this);
753 scanres->show();
754 scanres->exec();
758 void WpaGui::eventHistory()
760 if (eh) {
761 eh->close();
762 delete eh;
765 eh = new EventHistory();
766 if (eh == NULL)
767 return;
768 eh->addEvents(msgs);
769 eh->show();
770 eh->exec();
774 void WpaGui::ping()
776 char buf[10];
777 size_t len;
779 #ifdef CONFIG_CTRL_IFACE_NAMED_PIPE
781 * QSocketNotifier cannot be used with Windows named pipes, so use a
782 * timer to check for received messages for now. This could be
783 * optimized be doing something specific to named pipes or Windows
784 * events, but it is not clear what would be the best way of doing that
785 * in Qt.
787 receiveMsgs();
788 #endif /* CONFIG_CTRL_IFACE_NAMED_PIPE */
790 if (scanres && !scanres->isVisible()) {
791 delete scanres;
792 scanres = NULL;
795 if (eh && !eh->isVisible()) {
796 delete eh;
797 eh = NULL;
800 if (udr && !udr->isVisible()) {
801 delete udr;
802 udr = NULL;
805 len = sizeof(buf) - 1;
806 if (ctrlRequest("PING", buf, &len) < 0) {
807 printf("PING failed - trying to reconnect\n");
808 if (openCtrlConnection(ctrl_iface) >= 0) {
809 printf("Reconnected successfully\n");
810 pingsToStatusUpdate = 0;
814 pingsToStatusUpdate--;
815 if (pingsToStatusUpdate <= 0) {
816 updateStatus();
817 updateNetworks();
820 #ifndef CONFIG_CTRL_IFACE_NAMED_PIPE
821 /* Use less frequent pings and status updates when the main window is
822 * hidden (running in taskbar). */
823 int interval = isHidden() ? 5000 : 1000;
824 if (timer->interval() != interval)
825 timer->setInterval(interval);
826 #endif /* CONFIG_CTRL_IFACE_NAMED_PIPE */
830 static int str_match(const char *a, const char *b)
832 return strncmp(a, b, strlen(b)) == 0;
836 void WpaGui::processMsg(char *msg)
838 char *pos = msg, *pos2;
839 int priority = 2;
841 if (*pos == '<') {
842 /* skip priority */
843 pos++;
844 priority = atoi(pos);
845 pos = strchr(pos, '>');
846 if (pos)
847 pos++;
848 else
849 pos = msg;
852 WpaMsg wm(pos, priority);
853 if (eh)
854 eh->addEvent(wm);
855 if (peers)
856 peers->event_notify(wm);
857 msgs.append(wm);
858 while (msgs.count() > 100)
859 msgs.pop_front();
861 /* Update last message with truncated version of the event */
862 if (strncmp(pos, "CTRL-", 5) == 0) {
863 pos2 = strchr(pos, str_match(pos, WPA_CTRL_REQ) ? ':' : ' ');
864 if (pos2)
865 pos2++;
866 else
867 pos2 = pos;
868 } else
869 pos2 = pos;
870 QString lastmsg = pos2;
871 lastmsg.truncate(40);
872 textLastMessage->setText(lastmsg);
874 pingsToStatusUpdate = 0;
875 networkMayHaveChanged = true;
877 if (str_match(pos, WPA_CTRL_REQ))
878 processCtrlReq(pos + strlen(WPA_CTRL_REQ));
879 else if (str_match(pos, WPA_EVENT_SCAN_RESULTS) && scanres)
880 scanres->updateResults();
881 else if (str_match(pos, WPA_EVENT_DISCONNECTED))
882 showTrayMessage(QSystemTrayIcon::Information, 3,
883 tr("Disconnected from network."));
884 else if (str_match(pos, WPA_EVENT_CONNECTED)) {
885 showTrayMessage(QSystemTrayIcon::Information, 3,
886 tr("Connection to network established."));
887 QTimer::singleShot(5 * 1000, this, SLOT(showTrayStatus()));
888 stopWpsRun(true);
889 } else if (str_match(pos, WPS_EVENT_AP_AVAILABLE_PBC)) {
890 wpsStatusText->setText(tr("WPS AP in active PBC mode found"));
891 if (textStatus->text() == "INACTIVE" ||
892 textStatus->text() == "DISCONNECTED")
893 wpaguiTab->setCurrentWidget(wpsTab);
894 wpsInstructions->setText(tr("Press the PBC button on the "
895 "screen to start registration"));
896 } else if (str_match(pos, WPS_EVENT_AP_AVAILABLE_PIN)) {
897 wpsStatusText->setText(tr("WPS AP with recently selected "
898 "registrar"));
899 if (textStatus->text() == "INACTIVE" ||
900 textStatus->text() == "DISCONNECTED")
901 wpaguiTab->setCurrentWidget(wpsTab);
902 } else if (str_match(pos, WPS_EVENT_AP_AVAILABLE)) {
903 wpsStatusText->setText(tr("WPS AP detected"));
904 } else if (str_match(pos, WPS_EVENT_OVERLAP)) {
905 wpsStatusText->setText(tr("PBC mode overlap detected"));
906 wpsInstructions->setText(tr("More than one AP is currently in "
907 "active WPS PBC mode. Wait couple "
908 "of minutes and try again"));
909 wpaguiTab->setCurrentWidget(wpsTab);
910 } else if (str_match(pos, WPS_EVENT_CRED_RECEIVED)) {
911 wpsStatusText->setText(tr("Network configuration received"));
912 wpaguiTab->setCurrentWidget(wpsTab);
913 } else if (str_match(pos, WPA_EVENT_EAP_METHOD)) {
914 if (strstr(pos, "(WSC)"))
915 wpsStatusText->setText(tr("Registration started"));
916 } else if (str_match(pos, WPS_EVENT_M2D)) {
917 wpsStatusText->setText(tr("Registrar does not yet know PIN"));
918 } else if (str_match(pos, WPS_EVENT_FAIL)) {
919 wpsStatusText->setText(tr("Registration failed"));
920 } else if (str_match(pos, WPS_EVENT_SUCCESS)) {
921 wpsStatusText->setText(tr("Registration succeeded"));
926 void WpaGui::processCtrlReq(const char *req)
928 if (udr) {
929 udr->close();
930 delete udr;
932 udr = new UserDataRequest();
933 if (udr == NULL)
934 return;
935 if (udr->setParams(this, req) < 0) {
936 delete udr;
937 udr = NULL;
938 return;
940 udr->show();
941 udr->exec();
945 void WpaGui::receiveMsgs()
947 char buf[256];
948 size_t len;
950 while (monitor_conn && wpa_ctrl_pending(monitor_conn) > 0) {
951 len = sizeof(buf) - 1;
952 if (wpa_ctrl_recv(monitor_conn, buf, &len) == 0) {
953 buf[len] = '\0';
954 processMsg(buf);
960 void WpaGui::connectB()
962 char reply[10];
963 size_t reply_len = sizeof(reply);
964 ctrlRequest("REASSOCIATE", reply, &reply_len);
968 void WpaGui::selectNetwork( const QString &sel )
970 QString cmd(sel);
971 char reply[10];
972 size_t reply_len = sizeof(reply);
974 if (cmd.contains(QRegExp("^\\d+:")))
975 cmd.truncate(cmd.indexOf(':'));
976 else
977 cmd = "any";
978 cmd.prepend("SELECT_NETWORK ");
979 ctrlRequest(cmd.toAscii().constData(), reply, &reply_len);
980 triggerUpdate();
981 stopWpsRun(false);
985 void WpaGui::enableNetwork(const QString &sel)
987 QString cmd(sel);
988 char reply[10];
989 size_t reply_len = sizeof(reply);
991 if (cmd.contains(QRegExp("^\\d+:")))
992 cmd.truncate(cmd.indexOf(':'));
993 else if (!cmd.startsWith("all")) {
994 printf("Invalid editNetwork '%s'\n",
995 cmd.toAscii().constData());
996 return;
998 cmd.prepend("ENABLE_NETWORK ");
999 ctrlRequest(cmd.toAscii().constData(), reply, &reply_len);
1000 triggerUpdate();
1004 void WpaGui::disableNetwork(const QString &sel)
1006 QString cmd(sel);
1007 char reply[10];
1008 size_t reply_len = sizeof(reply);
1010 if (cmd.contains(QRegExp("^\\d+:")))
1011 cmd.truncate(cmd.indexOf(':'));
1012 else if (!cmd.startsWith("all")) {
1013 printf("Invalid editNetwork '%s'\n",
1014 cmd.toAscii().constData());
1015 return;
1017 cmd.prepend("DISABLE_NETWORK ");
1018 ctrlRequest(cmd.toAscii().constData(), reply, &reply_len);
1019 triggerUpdate();
1023 void WpaGui::editNetwork(const QString &sel)
1025 QString cmd(sel);
1026 int id = -1;
1028 if (cmd.contains(QRegExp("^\\d+:"))) {
1029 cmd.truncate(cmd.indexOf(':'));
1030 id = cmd.toInt();
1033 NetworkConfig *nc = new NetworkConfig();
1034 if (nc == NULL)
1035 return;
1036 nc->setWpaGui(this);
1038 if (id >= 0)
1039 nc->paramsFromConfig(id);
1040 else
1041 nc->newNetwork();
1043 nc->show();
1044 nc->exec();
1048 void WpaGui::editSelectedNetwork()
1050 if (networkSelect->count() < 1) {
1051 QMessageBox::information(
1052 this, tr("No Networks"),
1053 tr("There are no networks to edit.\n"));
1054 return;
1056 QString sel(networkSelect->currentText());
1057 editNetwork(sel);
1061 void WpaGui::editListedNetwork()
1063 if (networkList->currentRow() < 0) {
1064 QMessageBox::information(this, tr("Select A Network"),
1065 tr("Select a network from the list to"
1066 " edit it.\n"));
1067 return;
1069 QString sel(networkList->currentItem()->text());
1070 editNetwork(sel);
1074 void WpaGui::triggerUpdate()
1076 updateStatus();
1077 networkMayHaveChanged = true;
1078 updateNetworks();
1082 void WpaGui::addNetwork()
1084 NetworkConfig *nc = new NetworkConfig();
1085 if (nc == NULL)
1086 return;
1087 nc->setWpaGui(this);
1088 nc->newNetwork();
1089 nc->show();
1090 nc->exec();
1094 void WpaGui::removeNetwork(const QString &sel)
1096 QString cmd(sel);
1097 char reply[10];
1098 size_t reply_len = sizeof(reply);
1100 if (cmd.contains(QRegExp("^\\d+:")))
1101 cmd.truncate(cmd.indexOf(':'));
1102 else if (!cmd.startsWith("all")) {
1103 printf("Invalid editNetwork '%s'\n",
1104 cmd.toAscii().constData());
1105 return;
1107 cmd.prepend("REMOVE_NETWORK ");
1108 ctrlRequest(cmd.toAscii().constData(), reply, &reply_len);
1109 triggerUpdate();
1113 void WpaGui::removeSelectedNetwork()
1115 if (networkSelect->count() < 1) {
1116 QMessageBox::information(this, tr("No Networks"),
1117 tr("There are no networks to remove."
1118 "\n"));
1119 return;
1121 QString sel(networkSelect->currentText());
1122 removeNetwork(sel);
1126 void WpaGui::removeListedNetwork()
1128 if (networkList->currentRow() < 0) {
1129 QMessageBox::information(this, tr("Select A Network"),
1130 tr("Select a network from the list "
1131 "to remove it.\n"));
1132 return;
1134 QString sel(networkList->currentItem()->text());
1135 removeNetwork(sel);
1139 void WpaGui::enableAllNetworks()
1141 QString sel("all");
1142 enableNetwork(sel);
1146 void WpaGui::disableAllNetworks()
1148 QString sel("all");
1149 disableNetwork(sel);
1153 void WpaGui::removeAllNetworks()
1155 QString sel("all");
1156 removeNetwork(sel);
1160 int WpaGui::getNetworkDisabled(const QString &sel)
1162 QString cmd(sel);
1163 char reply[10];
1164 size_t reply_len = sizeof(reply) - 1;
1165 int pos = cmd.indexOf(':');
1166 if (pos < 0) {
1167 printf("Invalid getNetworkDisabled '%s'\n",
1168 cmd.toAscii().constData());
1169 return -1;
1171 cmd.truncate(pos);
1172 cmd.prepend("GET_NETWORK ");
1173 cmd.append(" disabled");
1175 if (ctrlRequest(cmd.toAscii().constData(), reply, &reply_len) >= 0
1176 && reply_len >= 1) {
1177 reply[reply_len] = '\0';
1178 if (!str_match(reply, "FAIL"))
1179 return atoi(reply);
1182 return -1;
1186 void WpaGui::updateNetworkDisabledStatus()
1188 if (networkList->currentRow() < 0)
1189 return;
1191 QString sel(networkList->currentItem()->text());
1193 switch (getNetworkDisabled(sel)) {
1194 case 0:
1195 if (!enableRadioButton->isChecked())
1196 enableRadioButton->setChecked(true);
1197 return;
1198 case 1:
1199 if (!disableRadioButton->isChecked())
1200 disableRadioButton->setChecked(true);
1201 return;
1206 void WpaGui::enableListedNetwork(bool enabled)
1208 if (networkList->currentRow() < 0 || !enabled)
1209 return;
1211 QString sel(networkList->currentItem()->text());
1213 if (getNetworkDisabled(sel) == 1)
1214 enableNetwork(sel);
1218 void WpaGui::disableListedNetwork(bool disabled)
1220 if (networkList->currentRow() < 0 || !disabled)
1221 return;
1223 QString sel(networkList->currentItem()->text());
1225 if (getNetworkDisabled(sel) == 0)
1226 disableNetwork(sel);
1230 void WpaGui::saveConfig()
1232 char buf[10];
1233 size_t len;
1235 len = sizeof(buf) - 1;
1236 ctrlRequest("SAVE_CONFIG", buf, &len);
1238 buf[len] = '\0';
1240 if (str_match(buf, "FAIL"))
1241 QMessageBox::warning(
1242 this, tr("Failed to save configuration"),
1243 tr("The configuration could not be saved.\n"
1244 "\n"
1245 "The update_config=1 configuration option\n"
1246 "must be used for configuration saving to\n"
1247 "be permitted.\n"));
1248 else
1249 QMessageBox::information(
1250 this, tr("Saved configuration"),
1251 tr("The current configuration was saved."
1252 "\n"));
1256 void WpaGui::selectAdapter( const QString & sel )
1258 if (openCtrlConnection(sel.toAscii().constData()) < 0)
1259 printf("Failed to open control connection to "
1260 "wpa_supplicant.\n");
1261 updateStatus();
1262 updateNetworks();
1266 void WpaGui::createTrayIcon(bool trayOnly)
1268 QApplication::setQuitOnLastWindowClosed(false);
1270 tray_icon = new QSystemTrayIcon(this);
1271 tray_icon->setToolTip(qAppName() + tr(" - wpa_supplicant user interface"));
1272 if (QImageReader::supportedImageFormats().contains(QByteArray("svg")))
1273 tray_icon->setIcon(QIcon(":/icons/wpa_gui.svg"));
1274 else
1275 tray_icon->setIcon(QIcon(":/icons/wpa_gui.png"));
1277 connect(tray_icon,
1278 SIGNAL(activated(QSystemTrayIcon::ActivationReason)),
1279 this, SLOT(trayActivated(QSystemTrayIcon::ActivationReason)));
1281 ackTrayIcon = false;
1283 tray_menu = new QMenu(this);
1285 disconnectAction = new QAction(tr("&Disconnect"), this);
1286 reconnectAction = new QAction(tr("Re&connect"), this);
1287 connect(disconnectAction, SIGNAL(triggered()), this,
1288 SLOT(disconnect()));
1289 connect(reconnectAction, SIGNAL(triggered()), this,
1290 SLOT(connectB()));
1291 tray_menu->addAction(disconnectAction);
1292 tray_menu->addAction(reconnectAction);
1293 tray_menu->addSeparator();
1295 eventAction = new QAction(tr("&Event History"), this);
1296 scanAction = new QAction(tr("Scan &Results"), this);
1297 statAction = new QAction(tr("S&tatus"), this);
1298 connect(eventAction, SIGNAL(triggered()), this, SLOT(eventHistory()));
1299 connect(scanAction, SIGNAL(triggered()), this, SLOT(scan()));
1300 connect(statAction, SIGNAL(triggered()), this, SLOT(showTrayStatus()));
1301 tray_menu->addAction(eventAction);
1302 tray_menu->addAction(scanAction);
1303 tray_menu->addAction(statAction);
1304 tray_menu->addSeparator();
1306 showAction = new QAction(tr("&Show Window"), this);
1307 hideAction = new QAction(tr("&Hide Window"), this);
1308 quitAction = new QAction(tr("&Quit"), this);
1309 connect(showAction, SIGNAL(triggered()), this, SLOT(show()));
1310 connect(hideAction, SIGNAL(triggered()), this, SLOT(hide()));
1311 connect(quitAction, SIGNAL(triggered()), qApp, SLOT(quit()));
1312 tray_menu->addAction(showAction);
1313 tray_menu->addAction(hideAction);
1314 tray_menu->addSeparator();
1315 tray_menu->addAction(quitAction);
1317 tray_icon->setContextMenu(tray_menu);
1319 tray_icon->show();
1321 if (!trayOnly)
1322 show();
1323 inTray = trayOnly;
1327 void WpaGui::showTrayMessage(QSystemTrayIcon::MessageIcon type, int sec,
1328 const QString & msg)
1330 if (!QSystemTrayIcon::supportsMessages())
1331 return;
1333 if (isVisible() || !tray_icon || !tray_icon->isVisible())
1334 return;
1336 tray_icon->showMessage(qAppName(), msg, type, sec * 1000);
1340 void WpaGui::trayActivated(QSystemTrayIcon::ActivationReason how)
1342 switch (how) {
1343 /* use close() here instead of hide() and allow the
1344 * custom closeEvent handler take care of children */
1345 case QSystemTrayIcon::Trigger:
1346 ackTrayIcon = true;
1347 if (isVisible()) {
1348 close();
1349 inTray = true;
1350 } else {
1351 show();
1352 inTray = false;
1354 break;
1355 case QSystemTrayIcon::MiddleClick:
1356 showTrayStatus();
1357 break;
1358 default:
1359 break;
1364 void WpaGui::showTrayStatus()
1366 char buf[2048];
1367 size_t len;
1369 len = sizeof(buf) - 1;
1370 if (ctrlRequest("STATUS", buf, &len) < 0)
1371 return;
1372 buf[len] = '\0';
1374 QString msg, status(buf);
1376 QStringList lines = status.split(QRegExp("\\n"));
1377 for (QStringList::Iterator it = lines.begin();
1378 it != lines.end(); it++) {
1379 int pos = (*it).indexOf('=') + 1;
1380 if (pos < 1)
1381 continue;
1383 if ((*it).startsWith("bssid="))
1384 msg.append("BSSID:\t" + (*it).mid(pos) + "\n");
1385 else if ((*it).startsWith("ssid="))
1386 msg.append("SSID: \t" + (*it).mid(pos) + "\n");
1387 else if ((*it).startsWith("pairwise_cipher="))
1388 msg.append("PAIR: \t" + (*it).mid(pos) + "\n");
1389 else if ((*it).startsWith("group_cipher="))
1390 msg.append("GROUP:\t" + (*it).mid(pos) + "\n");
1391 else if ((*it).startsWith("key_mgmt="))
1392 msg.append("AUTH: \t" + (*it).mid(pos) + "\n");
1393 else if ((*it).startsWith("wpa_state="))
1394 msg.append("STATE:\t" + (*it).mid(pos) + "\n");
1395 else if ((*it).startsWith("ip_address="))
1396 msg.append("IP: \t" + (*it).mid(pos) + "\n");
1397 else if ((*it).startsWith("Supplicant PAE state="))
1398 msg.append("PAE: \t" + (*it).mid(pos) + "\n");
1399 else if ((*it).startsWith("EAP state="))
1400 msg.append("EAP: \t" + (*it).mid(pos) + "\n");
1403 if (!msg.isEmpty())
1404 showTrayMessage(QSystemTrayIcon::Information, 10, msg);
1408 void WpaGui::closeEvent(QCloseEvent *event)
1410 if (eh) {
1411 eh->close();
1412 delete eh;
1413 eh = NULL;
1416 if (scanres) {
1417 scanres->close();
1418 delete scanres;
1419 scanres = NULL;
1422 if (peers) {
1423 peers->close();
1424 delete peers;
1425 peers = NULL;
1428 if (udr) {
1429 udr->close();
1430 delete udr;
1431 udr = NULL;
1434 if (tray_icon && !ackTrayIcon) {
1435 /* give user a visual hint that the tray icon exists */
1436 if (QSystemTrayIcon::supportsMessages()) {
1437 hide();
1438 showTrayMessage(QSystemTrayIcon::Information, 3,
1439 qAppName() +
1440 tr(" will keep running in "
1441 "the system tray."));
1442 } else {
1443 QMessageBox::information(this, qAppName() +
1444 tr(" systray"),
1445 tr("The program will keep "
1446 "running in the system "
1447 "tray."));
1449 ackTrayIcon = true;
1452 event->accept();
1456 void WpaGui::wpsDialog()
1458 wpaguiTab->setCurrentWidget(wpsTab);
1462 void WpaGui::peersDialog()
1464 if (peers) {
1465 peers->close();
1466 delete peers;
1469 peers = new Peers();
1470 if (peers == NULL)
1471 return;
1472 peers->setWpaGui(this);
1473 peers->show();
1474 peers->exec();
1478 void WpaGui::tabChanged(int index)
1480 if (index != 2)
1481 return;
1483 if (wpsRunning)
1484 return;
1486 wpsApPinEdit->setEnabled(!bssFromScan.isEmpty());
1487 if (bssFromScan.isEmpty())
1488 wpsApPinButton->setEnabled(false);
1492 void WpaGui::wpsPbc()
1494 char reply[20];
1495 size_t reply_len = sizeof(reply);
1497 if (ctrlRequest("WPS_PBC", reply, &reply_len) < 0)
1498 return;
1500 wpsPinEdit->setEnabled(false);
1501 if (wpsStatusText->text().compare(tr("WPS AP in active PBC mode found"))) {
1502 wpsInstructions->setText(tr("Press the push button on the AP to "
1503 "start the PBC mode."));
1504 } else {
1505 wpsInstructions->setText(tr("If you have not yet done so, press "
1506 "the push button on the AP to start "
1507 "the PBC mode."));
1509 wpsStatusText->setText(tr("Waiting for Registrar"));
1510 wpsRunning = true;
1514 void WpaGui::wpsGeneratePin()
1516 char reply[20];
1517 size_t reply_len = sizeof(reply) - 1;
1519 if (ctrlRequest("WPS_PIN any", reply, &reply_len) < 0)
1520 return;
1522 reply[reply_len] = '\0';
1524 wpsPinEdit->setText(reply);
1525 wpsPinEdit->setEnabled(true);
1526 wpsInstructions->setText(tr("Enter the generated PIN into the Registrar "
1527 "(either the internal one in the AP or an "
1528 "external one)."));
1529 wpsStatusText->setText(tr("Waiting for Registrar"));
1530 wpsRunning = true;
1534 void WpaGui::setBssFromScan(const QString &bssid)
1536 bssFromScan = bssid;
1537 wpsApPinEdit->setEnabled(!bssFromScan.isEmpty());
1538 wpsApPinButton->setEnabled(wpsApPinEdit->text().length() == 8);
1539 wpsStatusText->setText(tr("WPS AP selected from scan results"));
1540 wpsInstructions->setText(tr("If you want to use an AP device PIN, e.g., "
1541 "from a label in the device, enter the eight "
1542 "digit AP PIN and click Use AP PIN button."));
1546 void WpaGui::wpsApPinChanged(const QString &text)
1548 wpsApPinButton->setEnabled(text.length() == 8);
1552 void WpaGui::wpsApPin()
1554 char reply[20];
1555 size_t reply_len = sizeof(reply);
1557 QString cmd("WPS_REG " + bssFromScan + " " + wpsApPinEdit->text());
1558 if (ctrlRequest(cmd.toAscii().constData(), reply, &reply_len) < 0)
1559 return;
1561 wpsStatusText->setText(tr("Waiting for AP/Enrollee"));
1562 wpsRunning = true;
1566 void WpaGui::stopWpsRun(bool success)
1568 if (wpsRunning)
1569 wpsStatusText->setText(success ? tr("Connected to the network") :
1570 tr("Stopped"));
1571 else
1572 wpsStatusText->setText("");
1573 wpsPinEdit->setEnabled(false);
1574 wpsInstructions->setText("");
1575 wpsRunning = false;
1576 bssFromScan = "";
1577 wpsApPinEdit->setEnabled(false);
1578 wpsApPinButton->setEnabled(false);
1582 #ifdef CONFIG_NATIVE_WINDOWS
1584 #ifndef WPASVC_NAME
1585 #define WPASVC_NAME TEXT("wpasvc")
1586 #endif
1588 class ErrorMsg : public QMessageBox {
1589 public:
1590 ErrorMsg(QWidget *parent, DWORD last_err = GetLastError());
1591 void showMsg(QString msg);
1592 private:
1593 DWORD err;
1596 ErrorMsg::ErrorMsg(QWidget *parent, DWORD last_err) :
1597 QMessageBox(parent), err(last_err)
1599 setWindowTitle(tr("wpa_gui error"));
1600 setIcon(QMessageBox::Warning);
1603 void ErrorMsg::showMsg(QString msg)
1605 LPTSTR buf;
1607 setText(msg);
1608 if (FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
1609 FORMAT_MESSAGE_FROM_SYSTEM,
1610 NULL, err, 0, (LPTSTR) (void *) &buf,
1611 0, NULL) > 0) {
1612 QString msg = QString::fromWCharArray(buf);
1613 setInformativeText(QString("[%1] %2").arg(err).arg(msg));
1614 LocalFree(buf);
1615 } else {
1616 setInformativeText(QString("[%1]").arg(err));
1619 exec();
1623 void WpaGui::startService()
1625 SC_HANDLE svc, scm;
1627 scm = OpenSCManager(0, 0, SC_MANAGER_CONNECT);
1628 if (!scm) {
1629 ErrorMsg(this).showMsg(tr("OpenSCManager failed"));
1630 return;
1633 svc = OpenService(scm, WPASVC_NAME, SERVICE_START);
1634 if (!svc) {
1635 ErrorMsg(this).showMsg(tr("OpenService failed"));
1636 CloseServiceHandle(scm);
1637 return;
1640 if (!StartService(svc, 0, NULL)) {
1641 ErrorMsg(this).showMsg(tr("Failed to start wpa_supplicant "
1642 "service"));
1645 CloseServiceHandle(svc);
1646 CloseServiceHandle(scm);
1650 void WpaGui::stopService()
1652 SC_HANDLE svc, scm;
1653 SERVICE_STATUS status;
1655 scm = OpenSCManager(0, 0, SC_MANAGER_CONNECT);
1656 if (!scm) {
1657 ErrorMsg(this).showMsg(tr("OpenSCManager failed"));
1658 return;
1661 svc = OpenService(scm, WPASVC_NAME, SERVICE_STOP);
1662 if (!svc) {
1663 ErrorMsg(this).showMsg(tr("OpenService failed"));
1664 CloseServiceHandle(scm);
1665 return;
1668 if (!ControlService(svc, SERVICE_CONTROL_STOP, &status)) {
1669 ErrorMsg(this).showMsg(tr("Failed to stop wpa_supplicant "
1670 "service"));
1673 CloseServiceHandle(svc);
1674 CloseServiceHandle(scm);
1678 bool WpaGui::serviceRunning()
1680 SC_HANDLE svc, scm;
1681 SERVICE_STATUS status;
1682 bool running = false;
1684 scm = OpenSCManager(0, 0, SC_MANAGER_CONNECT);
1685 if (!scm) {
1686 printf("OpenSCManager failed: %d\n", (int) GetLastError());
1687 return false;
1690 svc = OpenService(scm, WPASVC_NAME, SERVICE_QUERY_STATUS);
1691 if (!svc) {
1692 printf("OpenService failed: %d\n\n", (int) GetLastError());
1693 CloseServiceHandle(scm);
1694 return false;
1697 if (QueryServiceStatus(svc, &status)) {
1698 if (status.dwCurrentState != SERVICE_STOPPED)
1699 running = true;
1702 CloseServiceHandle(svc);
1703 CloseServiceHandle(scm);
1705 return running;
1708 #endif /* CONFIG_NATIVE_WINDOWS */
1711 void WpaGui::addInterface()
1713 if (add_iface) {
1714 add_iface->close();
1715 delete add_iface;
1717 add_iface = new AddInterface(this, this);
1718 add_iface->show();
1719 add_iface->exec();
1723 #ifndef QT_NO_SESSIONMANAGER
1724 void WpaGui::saveState()
1726 QSettings settings("wpa_supplicant", "wpa_gui");
1727 settings.beginGroup("state");
1728 settings.setValue("session_id", app->sessionId());
1729 settings.setValue("in_tray", inTray);
1730 settings.endGroup();
1732 #endif