/*
* wpa_gui - WpaGui class
- * Copyright (c) 2005-2008, Jouni Malinen <j@w1.fi>
+ * Copyright (c) 2005-2011, Jouni Malinen <j@w1.fi>
*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * Alternatively, this software may be distributed under the terms of BSD
- * license.
- *
- * See README and COPYING for more details.
+ * This software may be distributed under the terms of the BSD license.
+ * See README for more details.
*/
-#ifdef __MINGW32__
-/* Need to get getopt() */
-#include <unistd.h>
-#endif
+#ifdef CONFIG_NATIVE_WINDOWS
+#include <windows.h>
+#endif /* CONFIG_NATIVE_WINDOWS */
#include <cstdio>
+#include <unistd.h>
#include <QMessageBox>
#include <QCloseEvent>
#include <QImageReader>
+#include <QSettings>
#include "wpagui.h"
#include "dirent.h"
-#include "wpa_ctrl.h"
+#include "common/wpa_ctrl.h"
#include "userdatarequest.h"
#include "networkconfig.h"
-#if 1
-/* Silence stdout */
-#define printf wpagui_printf
-static int wpagui_printf(const char *, ...)
-{
- return 0;
-}
+
+#ifndef QT_NO_DEBUG
+#define debug(M, ...) qDebug("DEBUG %d: " M, __LINE__, ##__VA_ARGS__)
+#else
+#define debug(M, ...) do {} while (0)
#endif
-WpaGui::WpaGui(QWidget *parent, const char *, Qt::WFlags)
- : QMainWindow(parent)
+
+WpaGui::WpaGui(QApplication *_app, QWidget *parent, const char *,
+ Qt::WindowFlags)
+ : QMainWindow(parent), app(_app)
{
setupUi(this);
+ this->setWindowFlags(Qt::Dialog);
+
+#ifdef CONFIG_NATIVE_WINDOWS
+ fileStopServiceAction = new QAction(this);
+ fileStopServiceAction->setObjectName("Stop Service");
+ fileStopServiceAction->setIconText(tr("Stop Service"));
+ fileMenu->insertAction(actionWPS, fileStopServiceAction);
+
+ fileStartServiceAction = new QAction(this);
+ fileStartServiceAction->setObjectName("Start Service");
+ fileStartServiceAction->setIconText(tr("Start Service"));
+ fileMenu->insertAction(fileStopServiceAction, fileStartServiceAction);
+
+ connect(fileStartServiceAction, SIGNAL(triggered()), this,
+ SLOT(startService()));
+ connect(fileStopServiceAction, SIGNAL(triggered()), this,
+ SLOT(stopService()));
+
+ addInterfaceAction = new QAction(this);
+ addInterfaceAction->setIconText(tr("Add Interface"));
+ fileMenu->insertAction(fileStartServiceAction, addInterfaceAction);
+
+ connect(addInterfaceAction, SIGNAL(triggered()), this,
+ SLOT(addInterface()));
+#endif /* CONFIG_NATIVE_WINDOWS */
(void) statusBar();
+ /*
+ * Disable WPS tab by default; it will be enabled if wpa_supplicant is
+ * built with WPS support.
+ */
+ wpsTab->setEnabled(false);
+ wpaguiTab->setTabEnabled(wpaguiTab->indexOf(wpsTab), false);
+
connect(fileEventHistoryAction, SIGNAL(triggered()), this,
SLOT(eventHistory()));
connect(fileSaveConfigAction, SIGNAL(triggered()), this,
SLOT(saveConfig()));
connect(actionWPS, SIGNAL(triggered()), this, SLOT(wpsDialog()));
+ connect(actionPeers, SIGNAL(triggered()), this, SLOT(peersDialog()));
connect(fileExitAction, SIGNAL(triggered()), qApp, SLOT(quit()));
connect(networkAddAction, SIGNAL(triggered()), this,
SLOT(addNetwork()));
SLOT(tabChanged(int)));
connect(wpsPbcButton, SIGNAL(clicked()), this, SLOT(wpsPbc()));
connect(wpsPinButton, SIGNAL(clicked()), this, SLOT(wpsGeneratePin()));
+ connect(wpsApPinEdit, SIGNAL(textChanged(const QString &)), this,
+ SLOT(wpsApPinChanged(const QString &)));
+ connect(wpsApPinButton, SIGNAL(clicked()), this, SLOT(wpsApPin()));
eh = NULL;
scanres = NULL;
+ peers = NULL;
+ add_iface = NULL;
udr = NULL;
tray_icon = NULL;
startInTray = false;
+ quietMode = false;
ctrl_iface = NULL;
ctrl_conn = NULL;
monitor_conn = NULL;
msgNotifier = NULL;
ctrl_iface_dir = strdup("/var/run/wpa_supplicant");
+ signalMeterInterval = 0;
parse_argv();
+#ifndef QT_NO_SESSIONMANAGER
+ if (app->isSessionRestored()) {
+ QSettings settings("wpa_supplicant", "wpa_gui");
+ settings.beginGroup("state");
+ if (app->sessionId().compare(settings.value("session_id").
+ toString()) == 0)
+ startInTray = settings.value("in_tray").toBool();
+ settings.endGroup();
+ }
+#endif
+
if (QSystemTrayIcon::isSystemTrayAvailable())
createTrayIcon(startInTray);
else
show();
- textStatus->setText("connecting to wpa_supplicant");
+ connectedToService = false;
+ textStatus->setText(tr("connecting to wpa_supplicant"));
timer = new QTimer(this);
connect(timer, SIGNAL(timeout()), SLOT(ping()));
- timer->setSingleShot(FALSE);
+ timer->setSingleShot(false);
timer->start(1000);
+ signalMeterTimer = new QTimer(this);
+ signalMeterTimer->setInterval(signalMeterInterval);
+ connect(signalMeterTimer, SIGNAL(timeout()), SLOT(signalMeterUpdate()));
+
if (openCtrlConnection(ctrl_iface) < 0) {
- printf("Failed to open control connection to "
- "wpa_supplicant.\n");
+ debug("Failed to open control connection to "
+ "wpa_supplicant.");
}
updateStatus();
scanres = NULL;
}
+ if (peers) {
+ peers->close();
+ delete peers;
+ peers = NULL;
+ }
+
+ if (add_iface) {
+ add_iface->close();
+ delete add_iface;
+ add_iface = NULL;
+ }
+
if (udr) {
udr->close();
delete udr;
void WpaGui::parse_argv()
{
int c;
+ WpaGuiApp *app = qobject_cast<WpaGuiApp*>(qApp);
for (;;) {
- c = getopt(qApp->argc(), qApp->argv(), "i:p:t");
+ c = getopt(app->argc, app->argv, "i:m:p:tq");
if (c < 0)
break;
switch (c) {
free(ctrl_iface);
ctrl_iface = strdup(optarg);
break;
+ case 'm':
+ signalMeterInterval = atoi(optarg) * 1000;
+ break;
case 'p':
free(ctrl_iface_dir);
ctrl_iface_dir = strdup(optarg);
case 't':
startInTray = true;
break;
+ case 'q':
+ quietMode = true;
+ break;
}
}
}
if (strcmp(dent->d_name, ".") == 0 ||
strcmp(dent->d_name, "..") == 0)
continue;
- printf("Selected interface '%s'\n",
- dent->d_name);
+ debug("Selected interface '%s'",
+ dent->d_name);
ctrl_iface = strdup(dent->d_name);
break;
}
ret = wpa_ctrl_request(ctrl, "INTERFACES", 10, buf,
&len, NULL);
if (ret >= 0) {
+ connectedToService = true;
buf[len] = '\0';
pos = strchr(buf, '\n');
if (pos)
#endif /* CONFIG_CTRL_IFACE_NAMED_PIPE */
}
- if (ctrl_iface == NULL)
+ if (ctrl_iface == NULL) {
+#ifdef CONFIG_NATIVE_WINDOWS
+ static bool first = true;
+ if (first && !serviceRunning()) {
+ first = false;
+ if (QMessageBox::warning(
+ this, qAppName(),
+ tr("wpa_supplicant service is not "
+ "running.\n"
+ "Do you want to start it?"),
+ QMessageBox::Yes | QMessageBox::No) ==
+ QMessageBox::Yes)
+ startService();
+ }
+#endif /* CONFIG_NATIVE_WINDOWS */
return -1;
+ }
#ifdef CONFIG_CTRL_IFACE_UNIX
flen = strlen(ctrl_iface_dir) + strlen(ctrl_iface) + 2;
monitor_conn = NULL;
}
- printf("Trying to connect to '%s'\n", cfile);
+ debug("Trying to connect to '%s'", cfile);
ctrl_conn = wpa_ctrl_open(cfile);
if (ctrl_conn == NULL) {
free(cfile);
return -1;
}
if (wpa_ctrl_attach(monitor_conn)) {
- printf("Failed to attach to wpa_supplicant\n");
+ debug("Failed to attach to wpa_supplicant");
wpa_ctrl_close(monitor_conn);
monitor_conn = NULL;
wpa_ctrl_close(ctrl_conn);
QString res(buf);
QStringList types = res.split(QChar(' '));
- actionWPS->setEnabled(types.contains("WSC"));
+ bool wps = types.contains("WSC");
+ actionWPS->setEnabled(wps);
+ wpsTab->setEnabled(wps);
+ wpaguiTab->setTabEnabled(wpaguiTab->indexOf(wpsTab), wps);
}
return 0;
}
-static void wpa_gui_msg_cb(char *msg, size_t)
-{
- /* This should not happen anymore since two control connections are
- * used. */
- printf("missed message: %s\n", msg);
-}
-
-
int WpaGui::ctrlRequest(const char *cmd, char *buf, size_t *buflen)
{
int ret;
if (ctrl_conn == NULL)
return -3;
- ret = wpa_ctrl_request(ctrl_conn, cmd, strlen(cmd), buf, buflen,
- wpa_gui_msg_cb);
+ ret = wpa_ctrl_request(ctrl_conn, cmd, strlen(cmd), buf, buflen, NULL);
if (ret == -2)
- printf("'%s' command timed out.\n", cmd);
+ debug("'%s' command timed out.", cmd);
else if (ret < 0)
- printf("'%s' command failed.\n", cmd);
+ debug("'%s' command failed.", cmd);
return ret;
}
+QString WpaGui::wpaStateTranslate(char *state)
+{
+ if (!strcmp(state, "DISCONNECTED"))
+ return tr("Disconnected");
+ else if (!strcmp(state, "INACTIVE"))
+ return tr("Inactive");
+ else if (!strcmp(state, "SCANNING"))
+ return tr("Scanning");
+ else if (!strcmp(state, "AUTHENTICATING"))
+ return tr("Authenticating");
+ else if (!strcmp(state, "ASSOCIATING"))
+ return tr("Associating");
+ else if (!strcmp(state, "ASSOCIATED"))
+ return tr("Associated");
+ else if (!strcmp(state, "4WAY_HANDSHAKE"))
+ return tr("4-Way Handshake");
+ else if (!strcmp(state, "GROUP_HANDSHAKE"))
+ return tr("Group Handshake");
+ else if (!strcmp(state, "COMPLETED"))
+ return tr("Completed");
+ else
+ return tr("Unknown");
+}
+
+
void WpaGui::updateStatus()
{
char buf[2048], *start, *end, *pos;
len = sizeof(buf) - 1;
if (ctrl_conn == NULL || ctrlRequest("STATUS", buf, &len) < 0) {
- textStatus->setText("Could not get status from "
- "wpa_supplicant");
+ textStatus->setText(tr("Could not get status from "
+ "wpa_supplicant"));
textAuthentication->clear();
textEncryption->clear();
textSsid->clear();
textBssid->clear();
textIpAddress->clear();
+ updateTrayToolTip(tr("no status information"));
+ updateTrayIcon(TrayIconOffline);
+ signalMeterTimer->stop();
+
+#ifdef CONFIG_NATIVE_WINDOWS
+ static bool first = true;
+ if (first && connectedToService &&
+ (ctrl_iface == NULL || *ctrl_iface == '\0')) {
+ first = false;
+ if (QMessageBox::information(
+ this, qAppName(),
+ tr("No network interfaces in use.\n"
+ "Would you like to add one?"),
+ QMessageBox::Yes | QMessageBox::No) ==
+ QMessageBox::Yes)
+ addInterface();
+ }
+#endif /* CONFIG_NATIVE_WINDOWS */
return;
}
bool bssid_updated = false, ipaddr_updated = false;
bool status_updated = false;
char *pairwise_cipher = NULL, *group_cipher = NULL;
+ char *mode = NULL;
start = buf;
while (*start) {
} else if (strcmp(start, "ssid") == 0) {
ssid_updated = true;
textSsid->setText(pos);
+ updateTrayToolTip(pos + tr(" (associated)"));
+ if (!signalMeterInterval) {
+ /* if signal meter is not enabled show
+ * full signal strength */
+ updateTrayIcon(TrayIconSignalExcellent);
+ }
} else if (strcmp(start, "ip_address") == 0) {
ipaddr_updated = true;
textIpAddress->setText(pos);
} else if (strcmp(start, "wpa_state") == 0) {
status_updated = true;
- textStatus->setText(pos);
+ textStatus->setText(wpaStateTranslate(pos));
} else if (strcmp(start, "key_mgmt") == 0) {
auth_updated = true;
textAuthentication->setText(pos);
pairwise_cipher = pos;
} else if (strcmp(start, "group_cipher") == 0) {
group_cipher = pos;
+ } else if (strcmp(start, "mode") == 0) {
+ mode = pos;
}
}
break;
start = end + 1;
}
+ if (status_updated && mode)
+ textStatus->setText(textStatus->text() + " (" + mode + ")");
if (pairwise_cipher || group_cipher) {
QString encr;
} else
textEncryption->clear();
+ if (signalMeterInterval) {
+ /*
+ * Handle signal meter service. When network is not associated,
+ * deactivate timer, otherwise keep it going. Tray icon has to
+ * be initialized here, because of the initial delay of the
+ * timer.
+ */
+ if (ssid_updated) {
+ if (!signalMeterTimer->isActive()) {
+ updateTrayIcon(TrayIconConnected);
+ signalMeterTimer->start();
+ }
+ } else {
+ signalMeterTimer->stop();
+ }
+ }
+
if (!status_updated)
textStatus->clear();
if (!auth_updated)
textAuthentication->clear();
- if (!ssid_updated)
+ if (!ssid_updated) {
textSsid->clear();
+ updateTrayToolTip(tr("(not-associated)"));
+ updateTrayIcon(TrayIconOffline);
+ }
if (!bssid_updated)
textBssid->clear();
if (!ipaddr_updated)
void WpaGui::updateNetworks()
{
- char buf[2048], *start, *end, *id, *ssid, *bssid, *flags;
+ char buf[4096], *start, *end, *id, *ssid, *bssid, *flags;
size_t len;
int first_active = -1;
int was_selected = -1;
break;
*flags++ = '\0';
+ if (strstr(flags, "[DISABLED][P2P-PERSISTENT]")) {
+ if (last)
+ break;
+ start = end + 1;
+ continue;
+ }
+
QString network(id);
network.append(": ");
network.append(ssid);
}
if (networkSelect->count() > 1)
- networkSelect->addItem("Select any network");
+ networkSelect->addItem(tr("Select any network"));
if (!current && first_active >= 0)
networkSelect->setCurrentIndex(first_active);
void WpaGui::helpIndex()
{
- printf("helpIndex\n");
+ debug("helpIndex");
}
void WpaGui::helpContents()
{
- printf("helpContents\n");
+ debug("helpContents");
}
void WpaGui::helpAbout()
{
QMessageBox::about(this, "wpa_gui for wpa_supplicant",
- "Copyright (c) 2003-2008,\n"
+ "Copyright (c) 2003-2015,\n"
"Jouni Malinen <j@w1.fi>\n"
"and contributors.\n"
"\n"
- "This program is free software. You can\n"
- "distribute it and/or modify it under the terms "
- "of\n"
- "the GNU General Public License version 2.\n"
- "\n"
- "Alternatively, this software may be distributed\n"
- "under the terms of the BSD license.\n"
+ "This software may be distributed under\n"
+ "the terms of the BSD license.\n"
+ "See README for more details.\n"
"\n"
"This product includes software developed\n"
"by the OpenSSL Project for use in the\n"
char reply[10];
size_t reply_len = sizeof(reply);
ctrlRequest("DISCONNECT", reply, &reply_len);
-
- if (wpsRunning)
- wpsStatusText->setText("Stopped");
- else
- wpsStatusText->setText("");
- wpsPinEdit->setEnabled(false);
- wpsInstructions->setText("");
- wpsRunning = false;
+ stopWpsRun(false);
}
len = sizeof(buf) - 1;
if (ctrlRequest("PING", buf, &len) < 0) {
- printf("PING failed - trying to reconnect\n");
+ debug("PING failed - trying to reconnect");
if (openCtrlConnection(ctrl_iface) >= 0) {
- printf("Reconnected successfully\n");
+ debug("Reconnected successfully");
pingsToStatusUpdate = 0;
}
}
}
+void WpaGui::signalMeterUpdate()
+{
+ char reply[128];
+ size_t reply_len = sizeof(reply);
+ char *rssi;
+ int rssi_value;
+
+ ctrlRequest("SIGNAL_POLL", reply, &reply_len);
+
+ /* In order to eliminate signal strength fluctuations, try
+ * to obtain averaged RSSI value in the first place. */
+ if ((rssi = strstr(reply, "AVG_RSSI=")) != NULL)
+ rssi_value = atoi(&rssi[sizeof("AVG_RSSI")]);
+ else if ((rssi = strstr(reply, "RSSI=")) != NULL)
+ rssi_value = atoi(&rssi[sizeof("RSSI")]);
+ else {
+ debug("Failed to get RSSI value");
+ updateTrayIcon(TrayIconSignalNone);
+ return;
+ }
+
+ debug("RSSI value: %d", rssi_value);
+
+ /*
+ * NOTE: The code below assumes, that the unit of the value returned
+ * by the SIGNAL POLL request is dBm. It might not be true for all
+ * wpa_supplicant drivers.
+ */
+
+ /*
+ * Calibration is based on "various Internet sources". Nonetheless,
+ * it seems to be compatible with the Windows 8.1 strength meter -
+ * tested on Intel Centrino Advanced-N 6235.
+ */
+ if (rssi_value >= -60)
+ updateTrayIcon(TrayIconSignalExcellent);
+ else if (rssi_value >= -68)
+ updateTrayIcon(TrayIconSignalGood);
+ else if (rssi_value >= -76)
+ updateTrayIcon(TrayIconSignalOk);
+ else if (rssi_value >= -84)
+ updateTrayIcon(TrayIconSignalWeak);
+ else
+ updateTrayIcon(TrayIconSignalNone);
+}
+
+
static int str_match(const char *a, const char *b)
{
return strncmp(a, b, strlen(b)) == 0;
WpaMsg wm(pos, priority);
if (eh)
eh->addEvent(wm);
+ if (peers)
+ peers->event_notify(wm);
msgs.append(wm);
while (msgs.count() > 100)
msgs.pop_front();
scanres->updateResults();
else if (str_match(pos, WPA_EVENT_DISCONNECTED))
showTrayMessage(QSystemTrayIcon::Information, 3,
- "Disconnected from network.");
+ tr("Disconnected from network."));
else if (str_match(pos, WPA_EVENT_CONNECTED)) {
showTrayMessage(QSystemTrayIcon::Information, 3,
- "Connection to network established.");
+ tr("Connection to network established."));
QTimer::singleShot(5 * 1000, this, SLOT(showTrayStatus()));
- if (wpsRunning) {
- wpsStatusText->setText("Connected to the network");
- wpsPinEdit->setEnabled(false);
- wpsInstructions->setText("");
- wpsRunning = false;
- }
+ stopWpsRun(true);
} else if (str_match(pos, WPS_EVENT_AP_AVAILABLE_PBC)) {
- showTrayMessage(QSystemTrayIcon::Information, 3,
- "Wi-Fi Protected Setup (WPS) AP\n"
- "in active PBC mode found.");
- wpsStatusText->setText("WPS AP in active PBC mode found");
- wpaguiTab->setCurrentWidget(wpsTab);
- wpsInstructions->setText("Press the PBC button on the screen "
- "to start registration");
+ wpsStatusText->setText(tr("WPS AP in active PBC mode found"));
+ if (textStatus->text() == "INACTIVE" ||
+ textStatus->text() == "DISCONNECTED")
+ wpaguiTab->setCurrentWidget(wpsTab);
+ wpsInstructions->setText(tr("Press the PBC button on the "
+ "screen to start registration"));
} else if (str_match(pos, WPS_EVENT_AP_AVAILABLE_PIN)) {
+ wpsStatusText->setText(tr("WPS AP with recently selected "
+ "registrar"));
+ if (textStatus->text() == "INACTIVE" ||
+ textStatus->text() == "DISCONNECTED")
+ wpaguiTab->setCurrentWidget(wpsTab);
+ } else if (str_match(pos, WPS_EVENT_AP_AVAILABLE_AUTH)) {
showTrayMessage(QSystemTrayIcon::Information, 3,
"Wi-Fi Protected Setup (WPS) AP\n"
- " in active PIN mode found.");
- wpsStatusText->setText("WPS AP with recently selected "
- "registrar");
- wpaguiTab->setCurrentWidget(wpsTab);
+ "indicating this client is authorized.");
+ wpsStatusText->setText("WPS AP indicating this client is "
+ "authorized");
+ if (textStatus->text() == "INACTIVE" ||
+ textStatus->text() == "DISCONNECTED")
+ wpaguiTab->setCurrentWidget(wpsTab);
} else if (str_match(pos, WPS_EVENT_AP_AVAILABLE)) {
- showTrayMessage(QSystemTrayIcon::Information, 3,
- "Wi-Fi Protected Setup (WPS)\n"
- "AP detected.");
- wpsStatusText->setText("WPS AP detected");
- wpaguiTab->setCurrentWidget(wpsTab);
+ wpsStatusText->setText(tr("WPS AP detected"));
} else if (str_match(pos, WPS_EVENT_OVERLAP)) {
- showTrayMessage(QSystemTrayIcon::Information, 3,
- "Wi-Fi Protected Setup (WPS)\n"
- "PBC mode overlap detected.");
- wpsStatusText->setText("PBC mode overlap detected");
- wpsInstructions->setText("More than one AP is currently in "
- "active WPS PBC mode. Wait couple of "
- "minutes and try again");
+ wpsStatusText->setText(tr("PBC mode overlap detected"));
+ wpsInstructions->setText(tr("More than one AP is currently in "
+ "active WPS PBC mode. Wait couple "
+ "of minutes and try again"));
wpaguiTab->setCurrentWidget(wpsTab);
} else if (str_match(pos, WPS_EVENT_CRED_RECEIVED)) {
- wpsStatusText->setText("Network configuration received");
+ wpsStatusText->setText(tr("Network configuration received"));
wpaguiTab->setCurrentWidget(wpsTab);
} else if (str_match(pos, WPA_EVENT_EAP_METHOD)) {
if (strstr(pos, "(WSC)"))
- wpsStatusText->setText("Registration started");
+ wpsStatusText->setText(tr("Registration started"));
+ } else if (str_match(pos, WPS_EVENT_M2D)) {
+ wpsStatusText->setText(tr("Registrar does not yet know PIN"));
+ } else if (str_match(pos, WPS_EVENT_FAIL)) {
+ wpsStatusText->setText(tr("Registration failed"));
+ } else if (str_match(pos, WPS_EVENT_SUCCESS)) {
+ wpsStatusText->setText(tr("Registration succeeded"));
}
}
char reply[10];
size_t reply_len = sizeof(reply);
- if (cmd.startsWith("Select any")) {
+ if (cmd.contains(QRegExp("^\\d+:")))
+ cmd.truncate(cmd.indexOf(':'));
+ else
cmd = "any";
- } else {
- int pos = cmd.indexOf(':');
- if (pos < 0) {
- printf("Invalid selectNetwork '%s'\n",
- cmd.toAscii().constData());
- return;
- }
- cmd.truncate(pos);
- }
cmd.prepend("SELECT_NETWORK ");
- ctrlRequest(cmd.toAscii().constData(), reply, &reply_len);
+ ctrlRequest(cmd.toLocal8Bit().constData(), reply, &reply_len);
triggerUpdate();
-
- if (wpsRunning)
- wpsStatusText->setText("Stopped");
- else
- wpsStatusText->setText("");
- wpsPinEdit->setEnabled(false);
- wpsInstructions->setText("");
- wpsRunning = false;
+ stopWpsRun(false);
}
char reply[10];
size_t reply_len = sizeof(reply);
- if (!cmd.startsWith("all")) {
- int pos = cmd.indexOf(':');
- if (pos < 0) {
- printf("Invalid enableNetwork '%s'\n",
- cmd.toAscii().constData());
- return;
- }
- cmd.truncate(pos);
+ if (cmd.contains(QRegExp("^\\d+:")))
+ cmd.truncate(cmd.indexOf(':'));
+ else if (!cmd.startsWith("all")) {
+ debug("Invalid editNetwork '%s'",
+ cmd.toLocal8Bit().constData());
+ return;
}
cmd.prepend("ENABLE_NETWORK ");
- ctrlRequest(cmd.toAscii().constData(), reply, &reply_len);
+ ctrlRequest(cmd.toLocal8Bit().constData(), reply, &reply_len);
triggerUpdate();
}
char reply[10];
size_t reply_len = sizeof(reply);
- if (!cmd.startsWith("all")) {
- int pos = cmd.indexOf(':');
- if (pos < 0) {
- printf("Invalid disableNetwork '%s'\n",
- cmd.toAscii().constData());
- return;
- }
- cmd.truncate(pos);
+ if (cmd.contains(QRegExp("^\\d+:")))
+ cmd.truncate(cmd.indexOf(':'));
+ else if (!cmd.startsWith("all")) {
+ debug("Invalid editNetwork '%s'",
+ cmd.toLocal8Bit().constData());
+ return;
}
cmd.prepend("DISABLE_NETWORK ");
- ctrlRequest(cmd.toAscii().constData(), reply, &reply_len);
+ ctrlRequest(cmd.toLocal8Bit().constData(), reply, &reply_len);
triggerUpdate();
}
QString cmd(sel);
int id = -1;
- if (!cmd.startsWith("Select any")) {
- int pos = sel.indexOf(':');
- if (pos < 0) {
- printf("Invalid editNetwork '%s'\n",
- cmd.toAscii().constData());
- return;
- }
- cmd.truncate(pos);
+ if (cmd.contains(QRegExp("^\\d+:"))) {
+ cmd.truncate(cmd.indexOf(':'));
id = cmd.toInt();
}
void WpaGui::editSelectedNetwork()
{
if (networkSelect->count() < 1) {
- QMessageBox::information(this, "No Networks",
- "There are no networks to edit.\n");
+ QMessageBox::information(
+ this, tr("No Networks"),
+ tr("There are no networks to edit.\n"));
return;
}
QString sel(networkSelect->currentText());
void WpaGui::editListedNetwork()
{
if (networkList->currentRow() < 0) {
- QMessageBox::information(this, "Select A Network",
- "Select a network from the list to"
- " edit it.\n");
+ QMessageBox::information(this, tr("Select A Network"),
+ tr("Select a network from the list to"
+ " edit it.\n"));
return;
}
QString sel(networkList->currentItem()->text());
char reply[10];
size_t reply_len = sizeof(reply);
- if (cmd.startsWith("Select any"))
+ if (cmd.contains(QRegExp("^\\d+:")))
+ cmd.truncate(cmd.indexOf(':'));
+ else if (!cmd.startsWith("all")) {
+ debug("Invalid editNetwork '%s'",
+ cmd.toLocal8Bit().constData());
return;
-
- if (!cmd.startsWith("all")) {
- int pos = cmd.indexOf(':');
- if (pos < 0) {
- printf("Invalid removeNetwork '%s'\n",
- cmd.toAscii().constData());
- return;
- }
- cmd.truncate(pos);
}
cmd.prepend("REMOVE_NETWORK ");
- ctrlRequest(cmd.toAscii().constData(), reply, &reply_len);
+ ctrlRequest(cmd.toLocal8Bit().constData(), reply, &reply_len);
triggerUpdate();
}
void WpaGui::removeSelectedNetwork()
{
if (networkSelect->count() < 1) {
- QMessageBox::information(this, "No Networks",
- "There are no networks to remove.\n");
+ QMessageBox::information(this, tr("No Networks"),
+ tr("There are no networks to remove."
+ "\n"));
return;
}
QString sel(networkSelect->currentText());
void WpaGui::removeListedNetwork()
{
if (networkList->currentRow() < 0) {
- QMessageBox::information(this, "Select A Network",
- "Select a network from the list to"
- " remove it.\n");
+ QMessageBox::information(this, tr("Select A Network"),
+ tr("Select a network from the list "
+ "to remove it.\n"));
return;
}
QString sel(networkList->currentItem()->text());
size_t reply_len = sizeof(reply) - 1;
int pos = cmd.indexOf(':');
if (pos < 0) {
- printf("Invalid getNetworkDisabled '%s'\n",
- cmd.toAscii().constData());
+ debug("Invalid getNetworkDisabled '%s'",
+ cmd.toLocal8Bit().constData());
return -1;
}
cmd.truncate(pos);
cmd.prepend("GET_NETWORK ");
cmd.append(" disabled");
- if (ctrlRequest(cmd.toAscii().constData(), reply, &reply_len) >= 0
+ if (ctrlRequest(cmd.toLocal8Bit().constData(), reply, &reply_len) >= 0
&& reply_len >= 1) {
reply[reply_len] = '\0';
if (!str_match(reply, "FAIL"))
buf[len] = '\0';
if (str_match(buf, "FAIL"))
- QMessageBox::warning(this, "Failed to save configuration",
- "The configuration could not be saved.\n"
- "\n"
- "The update_config=1 configuration option\n"
- "must be used for configuration saving to\n"
- "be permitted.\n");
+ QMessageBox::warning(
+ this, tr("Failed to save configuration"),
+ tr("The configuration could not be saved.\n"
+ "\n"
+ "The update_config=1 configuration option\n"
+ "must be used for configuration saving to\n"
+ "be permitted.\n"));
else
- QMessageBox::information(this, "Saved configuration",
- "The current configuration was saved."
- "\n");
+ QMessageBox::information(
+ this, tr("Saved configuration"),
+ tr("The current configuration was saved."
+ "\n"));
}
void WpaGui::selectAdapter( const QString & sel )
{
- if (openCtrlConnection(sel.toAscii().constData()) < 0)
- printf("Failed to open control connection to "
- "wpa_supplicant.\n");
+ if (openCtrlConnection(sel.toLocal8Bit().constData()) < 0)
+ debug("Failed to open control connection to "
+ "wpa_supplicant.");
updateStatus();
updateNetworks();
}
QApplication::setQuitOnLastWindowClosed(false);
tray_icon = new QSystemTrayIcon(this);
- tray_icon->setToolTip(qAppName() + " - wpa_supplicant user interface");
- if (QImageReader::supportedImageFormats().contains(QByteArray("svg")))
- tray_icon->setIcon(QIcon(":/icons/wpa_gui.svg"));
- else
- tray_icon->setIcon(QIcon(":/icons/wpa_gui.png"));
+ updateTrayIcon(TrayIconOffline);
connect(tray_icon,
SIGNAL(activated(QSystemTrayIcon::ActivationReason)),
tray_menu = new QMenu(this);
- disconnectAction = new QAction("&Disconnect", this);
- reconnectAction = new QAction("Re&connect", this);
+ disconnectAction = new QAction(tr("&Disconnect"), this);
+ reconnectAction = new QAction(tr("Re&connect"), this);
connect(disconnectAction, SIGNAL(triggered()), this,
SLOT(disconnect()));
connect(reconnectAction, SIGNAL(triggered()), this,
tray_menu->addAction(reconnectAction);
tray_menu->addSeparator();
- eventAction = new QAction("&Event History", this);
- scanAction = new QAction("Scan &Results", this);
- statAction = new QAction("S&tatus", this);
+ eventAction = new QAction(tr("&Event History"), this);
+ scanAction = new QAction(tr("Scan &Results"), this);
+ statAction = new QAction(tr("S&tatus"), this);
connect(eventAction, SIGNAL(triggered()), this, SLOT(eventHistory()));
connect(scanAction, SIGNAL(triggered()), this, SLOT(scan()));
connect(statAction, SIGNAL(triggered()), this, SLOT(showTrayStatus()));
tray_menu->addAction(statAction);
tray_menu->addSeparator();
- showAction = new QAction("&Show Window", this);
- hideAction = new QAction("&Hide Window", this);
- quitAction = new QAction("&Quit", this);
+ showAction = new QAction(tr("&Show Window"), this);
+ hideAction = new QAction(tr("&Hide Window"), this);
+ quitAction = new QAction(tr("&Quit"), this);
connect(showAction, SIGNAL(triggered()), this, SLOT(show()));
connect(hideAction, SIGNAL(triggered()), this, SLOT(hide()));
connect(quitAction, SIGNAL(triggered()), qApp, SLOT(quit()));
if (!trayOnly)
show();
+ inTray = trayOnly;
}
if (!QSystemTrayIcon::supportsMessages())
return;
- if (isVisible() || !tray_icon || !tray_icon->isVisible())
+ if (isVisible() || !tray_icon || !tray_icon->isVisible() || quietMode)
return;
tray_icon->showMessage(qAppName(), msg, type, sec * 1000);
* custom closeEvent handler take care of children */
case QSystemTrayIcon::Trigger:
ackTrayIcon = true;
- if (isVisible())
+ if (isVisible()) {
close();
- else
+ inTray = true;
+ } else {
show();
+ inTray = false;
+ }
break;
case QSystemTrayIcon::MiddleClick:
showTrayStatus();
}
+void WpaGui::updateTrayToolTip(const QString &msg)
+{
+ if (tray_icon)
+ tray_icon->setToolTip(msg);
+}
+
+
+void WpaGui::updateTrayIcon(TrayIconType type)
+{
+ if (!tray_icon || currentIconType == type)
+ return;
+
+ QIcon fallback_icon;
+ QStringList names;
+
+ if (QImageReader::supportedImageFormats().contains(QByteArray("svg")))
+ fallback_icon = QIcon(":/icons/wpa_gui.svg");
+ else
+ fallback_icon = QIcon(":/icons/wpa_gui.png");
+
+ switch (type) {
+ case TrayIconOffline:
+ names << "network-wireless-offline-symbolic"
+ << "network-wireless-offline"
+ << "network-wireless-signal-none-symbolic"
+ << "network-wireless-signal-none";
+ break;
+ case TrayIconAcquiring:
+ names << "network-wireless-acquiring-symbolic"
+ << "network-wireless-acquiring";
+ break;
+ case TrayIconConnected:
+ names << "network-wireless-connected-symbolic"
+ << "network-wireless-connected";
+ break;
+ case TrayIconSignalNone:
+ names << "network-wireless-signal-none-symbolic"
+ << "network-wireless-signal-none";
+ break;
+ case TrayIconSignalWeak:
+ names << "network-wireless-signal-weak-symbolic"
+ << "network-wireless-signal-weak";
+ break;
+ case TrayIconSignalOk:
+ names << "network-wireless-signal-ok-symbolic"
+ << "network-wireless-signal-ok";
+ break;
+ case TrayIconSignalGood:
+ names << "network-wireless-signal-good-symbolic"
+ << "network-wireless-signal-good";
+ break;
+ case TrayIconSignalExcellent:
+ names << "network-wireless-signal-excellent-symbolic"
+ << "network-wireless-signal-excellent";
+ break;
+ }
+
+ currentIconType = type;
+ tray_icon->setIcon(loadThemedIcon(names, fallback_icon));
+}
+
+
+QIcon WpaGui::loadThemedIcon(const QStringList &names,
+ const QIcon &fallback)
+{
+ QIcon icon;
+
+ for (QStringList::ConstIterator it = names.begin();
+ it != names.end(); it++) {
+ icon = QIcon::fromTheme(*it);
+ if (!icon.isNull())
+ return icon;
+ }
+
+ return fallback;
+}
+
+
void WpaGui::closeEvent(QCloseEvent *event)
{
if (eh) {
scanres = NULL;
}
+ if (peers) {
+ peers->close();
+ delete peers;
+ peers = NULL;
+ }
+
if (udr) {
udr->close();
delete udr;
if (QSystemTrayIcon::supportsMessages()) {
hide();
showTrayMessage(QSystemTrayIcon::Information, 3,
- qAppName() + " will keep running in "
- "the system tray.");
+ qAppName() +
+ tr(" will keep running in "
+ "the system tray."));
} else {
- QMessageBox::information(this, qAppName() + " systray",
- "The program will keep "
- "running in the system "
- "tray.");
+ QMessageBox::information(this, qAppName() +
+ tr(" systray"),
+ tr("The program will keep "
+ "running in the system "
+ "tray."));
}
ackTrayIcon = true;
}
}
+void WpaGui::peersDialog()
+{
+ if (peers) {
+ peers->close();
+ delete peers;
+ }
+
+ peers = new Peers();
+ if (peers == NULL)
+ return;
+ peers->setWpaGui(this);
+ peers->show();
+ peers->exec();
+}
+
+
void WpaGui::tabChanged(int index)
{
if (index != 2)
if (wpsRunning)
return;
- /* TODO: Update WPS status based on latest scan results and
- * availability of WPS APs */
+ wpsApPinEdit->setEnabled(!bssFromScan.isEmpty());
+ if (bssFromScan.isEmpty())
+ wpsApPinButton->setEnabled(false);
}
return;
wpsPinEdit->setEnabled(false);
- if (wpsStatusText->text().compare("WPS AP in active PBC mode found")) {
- wpsInstructions->setText("Press the push button on the AP to "
- "start the PBC mode.");
+ if (wpsStatusText->text().compare(tr("WPS AP in active PBC mode found"))) {
+ wpsInstructions->setText(tr("Press the push button on the AP to "
+ "start the PBC mode."));
} else {
- wpsInstructions->setText("If you have not yet done so, press "
+ wpsInstructions->setText(tr("If you have not yet done so, press "
"the push button on the AP to start "
- "the PBC mode.");
+ "the PBC mode."));
}
- wpsStatusText->setText("Waiting for Registrar");
+ wpsStatusText->setText(tr("Waiting for Registrar"));
wpsRunning = true;
}
wpsPinEdit->setText(reply);
wpsPinEdit->setEnabled(true);
- wpsInstructions->setText("Enter the generated PIN into the Registrar "
+ wpsInstructions->setText(tr("Enter the generated PIN into the Registrar "
"(either the internal one in the AP or an "
- "external one).");
- wpsStatusText->setText("Waiting for Registrar");
+ "external one)."));
+ wpsStatusText->setText(tr("Waiting for Registrar"));
wpsRunning = true;
}
+
+
+void WpaGui::setBssFromScan(const QString &bssid)
+{
+ bssFromScan = bssid;
+ wpsApPinEdit->setEnabled(!bssFromScan.isEmpty());
+ wpsApPinButton->setEnabled(wpsApPinEdit->text().length() == 8);
+ wpsStatusText->setText(tr("WPS AP selected from scan results"));
+ wpsInstructions->setText(tr("If you want to use an AP device PIN, e.g., "
+ "from a label in the device, enter the eight "
+ "digit AP PIN and click Use AP PIN button."));
+}
+
+
+void WpaGui::wpsApPinChanged(const QString &text)
+{
+ wpsApPinButton->setEnabled(text.length() == 8);
+}
+
+
+void WpaGui::wpsApPin()
+{
+ char reply[20];
+ size_t reply_len = sizeof(reply);
+
+ QString cmd("WPS_REG " + bssFromScan + " " + wpsApPinEdit->text());
+ if (ctrlRequest(cmd.toLocal8Bit().constData(), reply, &reply_len) < 0)
+ return;
+
+ wpsStatusText->setText(tr("Waiting for AP/Enrollee"));
+ wpsRunning = true;
+}
+
+
+void WpaGui::stopWpsRun(bool success)
+{
+ if (wpsRunning)
+ wpsStatusText->setText(success ? tr("Connected to the network") :
+ tr("Stopped"));
+ else
+ wpsStatusText->setText("");
+ wpsPinEdit->setEnabled(false);
+ wpsInstructions->setText("");
+ wpsRunning = false;
+ bssFromScan = "";
+ wpsApPinEdit->setEnabled(false);
+ wpsApPinButton->setEnabled(false);
+}
+
+
+#ifdef CONFIG_NATIVE_WINDOWS
+
+#ifndef WPASVC_NAME
+#define WPASVC_NAME TEXT("wpasvc")
+#endif
+
+class ErrorMsg : public QMessageBox {
+public:
+ ErrorMsg(QWidget *parent, DWORD last_err = GetLastError());
+ void showMsg(QString msg);
+private:
+ DWORD err;
+};
+
+ErrorMsg::ErrorMsg(QWidget *parent, DWORD last_err) :
+ QMessageBox(parent), err(last_err)
+{
+ setWindowTitle(tr("wpa_gui error"));
+ setIcon(QMessageBox::Warning);
+}
+
+void ErrorMsg::showMsg(QString msg)
+{
+ LPTSTR buf;
+
+ setText(msg);
+ if (FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
+ FORMAT_MESSAGE_FROM_SYSTEM,
+ NULL, err, 0, (LPTSTR) (void *) &buf,
+ 0, NULL) > 0) {
+ QString msg = QString::fromWCharArray(buf);
+ setInformativeText(QString("[%1] %2").arg(err).arg(msg));
+ LocalFree(buf);
+ } else {
+ setInformativeText(QString("[%1]").arg(err));
+ }
+
+ exec();
+}
+
+
+void WpaGui::startService()
+{
+ SC_HANDLE svc, scm;
+
+ scm = OpenSCManager(0, 0, SC_MANAGER_CONNECT);
+ if (!scm) {
+ ErrorMsg(this).showMsg(tr("OpenSCManager failed"));
+ return;
+ }
+
+ svc = OpenService(scm, WPASVC_NAME, SERVICE_START);
+ if (!svc) {
+ ErrorMsg(this).showMsg(tr("OpenService failed"));
+ CloseServiceHandle(scm);
+ return;
+ }
+
+ if (!StartService(svc, 0, NULL)) {
+ ErrorMsg(this).showMsg(tr("Failed to start wpa_supplicant "
+ "service"));
+ }
+
+ CloseServiceHandle(svc);
+ CloseServiceHandle(scm);
+}
+
+
+void WpaGui::stopService()
+{
+ SC_HANDLE svc, scm;
+ SERVICE_STATUS status;
+
+ scm = OpenSCManager(0, 0, SC_MANAGER_CONNECT);
+ if (!scm) {
+ ErrorMsg(this).showMsg(tr("OpenSCManager failed"));
+ return;
+ }
+
+ svc = OpenService(scm, WPASVC_NAME, SERVICE_STOP);
+ if (!svc) {
+ ErrorMsg(this).showMsg(tr("OpenService failed"));
+ CloseServiceHandle(scm);
+ return;
+ }
+
+ if (!ControlService(svc, SERVICE_CONTROL_STOP, &status)) {
+ ErrorMsg(this).showMsg(tr("Failed to stop wpa_supplicant "
+ "service"));
+ }
+
+ CloseServiceHandle(svc);
+ CloseServiceHandle(scm);
+}
+
+
+bool WpaGui::serviceRunning()
+{
+ SC_HANDLE svc, scm;
+ SERVICE_STATUS status;
+ bool running = false;
+
+ scm = OpenSCManager(0, 0, SC_MANAGER_CONNECT);
+ if (!scm) {
+ debug("OpenSCManager failed: %d", (int) GetLastError());
+ return false;
+ }
+
+ svc = OpenService(scm, WPASVC_NAME, SERVICE_QUERY_STATUS);
+ if (!svc) {
+ debug("OpenService failed: %d", (int) GetLastError());
+ CloseServiceHandle(scm);
+ return false;
+ }
+
+ if (QueryServiceStatus(svc, &status)) {
+ if (status.dwCurrentState != SERVICE_STOPPED)
+ running = true;
+ }
+
+ CloseServiceHandle(svc);
+ CloseServiceHandle(scm);
+
+ return running;
+}
+
+#endif /* CONFIG_NATIVE_WINDOWS */
+
+
+void WpaGui::addInterface()
+{
+ if (add_iface) {
+ add_iface->close();
+ delete add_iface;
+ }
+ add_iface = new AddInterface(this, this);
+ add_iface->show();
+ add_iface->exec();
+}
+
+
+#ifndef QT_NO_SESSIONMANAGER
+void WpaGui::saveState()
+{
+ QSettings settings("wpa_supplicant", "wpa_gui");
+ settings.beginGroup("state");
+ settings.setValue("session_id", app->sessionId());
+ settings.setValue("in_tray", inTray);
+ settings.endGroup();
+}
+#endif