/*
 * wpa_gui - WpaGui class
 * Copyright (c) 2005-2011, Jouni Malinen <j@w1.fi>
 *
 * This software may be distributed under the terms of the BSD license.
 * See README for more details.
 */

#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 "common/wpa_ctrl.h"
#include "userdatarequest.h"
#include "networkconfig.h"


#ifndef QT_NO_DEBUG
#define debug(M, ...) qDebug("DEBUG %d: " M, __LINE__, ##__VA_ARGS__)
#else
#define debug(M, ...) do {} while (0)
#endif


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()));
	connect(networkEditAction, SIGNAL(triggered()), this,
		SLOT(editSelectedNetwork()));
	connect(networkRemoveAction, SIGNAL(triggered()), this,
		SLOT(removeSelectedNetwork()));
	connect(networkEnableAllAction, SIGNAL(triggered()), this,
		SLOT(enableAllNetworks()));
	connect(networkDisableAllAction, SIGNAL(triggered()), this,
		SLOT(disableAllNetworks()));
	connect(networkRemoveAllAction, SIGNAL(triggered()), this,
		SLOT(removeAllNetworks()));
	connect(helpIndexAction, SIGNAL(triggered()), this, SLOT(helpIndex()));
	connect(helpContentsAction, SIGNAL(triggered()), this,
		SLOT(helpContents()));
	connect(helpAboutAction, SIGNAL(triggered()), this, SLOT(helpAbout()));
	connect(disconnectButton, SIGNAL(clicked()), this, SLOT(disconnect()));
	connect(scanButton, SIGNAL(clicked()), this, SLOT(scan()));
	connect(connectButton, SIGNAL(clicked()), this, SLOT(connectB()));
	connect(adapterSelect, SIGNAL(activated(const QString&)), this,
		SLOT(selectAdapter(const QString&)));
	connect(networkSelect, SIGNAL(activated(const QString&)), this,
		SLOT(selectNetwork(const QString&)));
	connect(addNetworkButton, SIGNAL(clicked()), this, SLOT(addNetwork()));
	connect(editNetworkButton, SIGNAL(clicked()), this,
		SLOT(editListedNetwork()));
	connect(removeNetworkButton, SIGNAL(clicked()), this,
		SLOT(removeListedNetwork()));
	connect(networkList, SIGNAL(itemSelectionChanged()), this,
		SLOT(updateNetworkDisabledStatus()));
	connect(enableRadioButton, SIGNAL(toggled(bool)), this,
		SLOT(enableListedNetwork(bool)));
	connect(disableRadioButton, SIGNAL(toggled(bool)), this,
		SLOT(disableListedNetwork(bool)));
	connect(scanNetworkButton, SIGNAL(clicked()), this, SLOT(scan()));
	connect(networkList, SIGNAL(itemDoubleClicked(QListWidgetItem *)),
		this, SLOT(editListedNetwork()));
	connect(wpaguiTab, SIGNAL(currentChanged(int)), this,
		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();

	connectedToService = false;
	textStatus->setText(tr("connecting to wpa_supplicant"));
	timer = new QTimer(this);
	connect(timer, SIGNAL(timeout()), SLOT(ping()));
	timer->setSingleShot(false);
	timer->start(1000);

	signalMeterTimer = new QTimer(this);
	signalMeterTimer->setInterval(signalMeterInterval);
	connect(signalMeterTimer, SIGNAL(timeout()), SLOT(signalMeterUpdate()));

	if (openCtrlConnection(ctrl_iface) < 0) {
		debug("Failed to open control connection to "
		      "wpa_supplicant.");
	}

	updateStatus();
	networkMayHaveChanged = true;
	updateNetworks();
}


WpaGui::~WpaGui()
{
	delete msgNotifier;

	if (monitor_conn) {
		wpa_ctrl_detach(monitor_conn);
		wpa_ctrl_close(monitor_conn);
		monitor_conn = NULL;
	}
	if (ctrl_conn) {
		wpa_ctrl_close(ctrl_conn);
		ctrl_conn = NULL;
	}

	if (eh) {
		eh->close();
		delete eh;
		eh = NULL;
	}

	if (scanres) {
		scanres->close();
		delete scanres;
		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;
		udr = NULL;
	}

	free(ctrl_iface);
	ctrl_iface = NULL;

	free(ctrl_iface_dir);
	ctrl_iface_dir = NULL;
}


void WpaGui::languageChange()
{
	retranslateUi(this);
}


void WpaGui::parse_argv()
{
	int c;
	WpaGuiApp *app = qobject_cast<WpaGuiApp*>(qApp);
	for (;;) {
		c = getopt(app->argc, app->argv, "i:m:p:tq");
		if (c < 0)
			break;
		switch (c) {
		case 'i':
			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);
			break;
		case 't':
			startInTray = true;
			break;
		case 'q':
			quietMode = true;
			break;
		}
	}
}


int WpaGui::openCtrlConnection(const char *ifname)
{
	char *cfile;
	int flen;
	char buf[2048], *pos, *pos2;
	size_t len;

	if (ifname) {
		if (ifname != ctrl_iface) {
			free(ctrl_iface);
			ctrl_iface = strdup(ifname);
		}
	} else {
#ifdef CONFIG_CTRL_IFACE_UDP
		free(ctrl_iface);
		ctrl_iface = strdup("udp");
#endif /* CONFIG_CTRL_IFACE_UDP */
#ifdef CONFIG_CTRL_IFACE_UNIX
		struct dirent *dent;
		DIR *dir = opendir(ctrl_iface_dir);
		free(ctrl_iface);
		ctrl_iface = NULL;
		if (dir) {
			while ((dent = readdir(dir))) {
#ifdef _DIRENT_HAVE_D_TYPE
				/* Skip the file if it is not a socket.
				 * Also accept DT_UNKNOWN (0) in case
				 * the C library or underlying file
				 * system does not support d_type. */
				if (dent->d_type != DT_SOCK &&
				    dent->d_type != DT_UNKNOWN)
					continue;
#endif /* _DIRENT_HAVE_D_TYPE */

				if (strcmp(dent->d_name, ".") == 0 ||
				    strcmp(dent->d_name, "..") == 0)
					continue;
				debug("Selected interface '%s'",
				      dent->d_name);
				ctrl_iface = strdup(dent->d_name);
				break;
			}
			closedir(dir);
		}
#endif /* CONFIG_CTRL_IFACE_UNIX */
#ifdef CONFIG_CTRL_IFACE_NAMED_PIPE
		struct wpa_ctrl *ctrl;
		int ret;

		free(ctrl_iface);
		ctrl_iface = NULL;

		ctrl = wpa_ctrl_open(NULL);
		if (ctrl) {
			len = sizeof(buf) - 1;
			ret = wpa_ctrl_request(ctrl, "INTERFACES", 10, buf,
					       &len, NULL);
			if (ret >= 0) {
				connectedToService = true;
				buf[len] = '\0';
				pos = strchr(buf, '\n');
				if (pos)
					*pos = '\0';
				ctrl_iface = strdup(buf);
			}
			wpa_ctrl_close(ctrl);
		}
#endif /* CONFIG_CTRL_IFACE_NAMED_PIPE */
	}

	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;
	cfile = (char *) malloc(flen);
	if (cfile == NULL)
		return -1;
	snprintf(cfile, flen, "%s/%s", ctrl_iface_dir, ctrl_iface);
#else /* CONFIG_CTRL_IFACE_UNIX */
	flen = strlen(ctrl_iface) + 1;
	cfile = (char *) malloc(flen);
	if (cfile == NULL)
		return -1;
	snprintf(cfile, flen, "%s", ctrl_iface);
#endif /* CONFIG_CTRL_IFACE_UNIX */

	if (ctrl_conn) {
		wpa_ctrl_close(ctrl_conn);
		ctrl_conn = NULL;
	}

	if (monitor_conn) {
		delete msgNotifier;
		msgNotifier = NULL;
		wpa_ctrl_detach(monitor_conn);
		wpa_ctrl_close(monitor_conn);
		monitor_conn = NULL;
	}

	debug("Trying to connect to '%s'", cfile);
	ctrl_conn = wpa_ctrl_open(cfile);
	if (ctrl_conn == NULL) {
		free(cfile);
		return -1;
	}
	monitor_conn = wpa_ctrl_open(cfile);
	free(cfile);
	if (monitor_conn == NULL) {
		wpa_ctrl_close(ctrl_conn);
		return -1;
	}
	if (wpa_ctrl_attach(monitor_conn)) {
		debug("Failed to attach to wpa_supplicant");
		wpa_ctrl_close(monitor_conn);
		monitor_conn = NULL;
		wpa_ctrl_close(ctrl_conn);
		ctrl_conn = NULL;
		return -1;
	}

#if defined(CONFIG_CTRL_IFACE_UNIX) || defined(CONFIG_CTRL_IFACE_UDP)
	msgNotifier = new QSocketNotifier(wpa_ctrl_get_fd(monitor_conn),
					  QSocketNotifier::Read, this);
	connect(msgNotifier, SIGNAL(activated(int)), SLOT(receiveMsgs()));
#endif

	adapterSelect->clear();
	adapterSelect->addItem(ctrl_iface);
	adapterSelect->setCurrentIndex(0);

	len = sizeof(buf) - 1;
	if (wpa_ctrl_request(ctrl_conn, "INTERFACES", 10, buf, &len, NULL) >=
	    0) {
		buf[len] = '\0';
		pos = buf;
		while (*pos) {
			pos2 = strchr(pos, '\n');
			if (pos2)
				*pos2 = '\0';
			if (strcmp(pos, ctrl_iface) != 0)
				adapterSelect->addItem(pos);
			if (pos2)
				pos = pos2 + 1;
			else
				break;
		}
	}

	len = sizeof(buf) - 1;
	if (wpa_ctrl_request(ctrl_conn, "GET_CAPABILITY eap", 18, buf, &len,
			     NULL) >= 0) {
		buf[len] = '\0';

		QString res(buf);
		QStringList types = res.split(QChar(' '));
		bool wps = types.contains("WSC");
		actionWPS->setEnabled(wps);
		wpsTab->setEnabled(wps);
		wpaguiTab->setTabEnabled(wpaguiTab->indexOf(wpsTab), wps);
	}

	return 0;
}


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, NULL);
	if (ret == -2)
		debug("'%s' command timed out.", cmd);
	else if (ret < 0)
		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;
	size_t len;

	pingsToStatusUpdate = 10;

	len = sizeof(buf) - 1;
	if (ctrl_conn == NULL || ctrlRequest("STATUS", buf, &len) < 0) {
		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;
	}

	buf[len] = '\0';

	bool auth_updated = false, ssid_updated = false;
	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) {
		bool last = false;
		end = strchr(start, '\n');
		if (end == NULL) {
			last = true;
			end = start;
			while (end[0] && end[1])
				end++;
		}
		*end = '\0';

		pos = strchr(start, '=');
		if (pos) {
			*pos++ = '\0';
			if (strcmp(start, "bssid") == 0) {
				bssid_updated = true;
				textBssid->setText(pos);
			} 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(wpaStateTranslate(pos));
			} else if (strcmp(start, "key_mgmt") == 0) {
				auth_updated = true;
				textAuthentication->setText(pos);
				/* TODO: could add EAP status to this */
			} else if (strcmp(start, "pairwise_cipher") == 0) {
				pairwise_cipher = pos;
			} else if (strcmp(start, "group_cipher") == 0) {
				group_cipher = pos;
			} else if (strcmp(start, "mode") == 0) {
				mode = pos;
			}
		}

		if (last)
			break;
		start = end + 1;
	}
	if (status_updated && mode)
		textStatus->setText(textStatus->text() + " (" + mode + ")");

	if (pairwise_cipher || group_cipher) {
		QString encr;
		if (pairwise_cipher && group_cipher &&
		    strcmp(pairwise_cipher, group_cipher) != 0) {
			encr.append(pairwise_cipher);
			encr.append(" + ");
			encr.append(group_cipher);
		} else if (pairwise_cipher) {
			encr.append(pairwise_cipher);
		} else {
			encr.append(group_cipher);
			encr.append(" [group key only]");
		}
		textEncryption->setText(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) {
		textSsid->clear();
		updateTrayToolTip(tr("(not-associated)"));
		updateTrayIcon(TrayIconOffline);
	}
	if (!bssid_updated)
		textBssid->clear();
	if (!ipaddr_updated)
		textIpAddress->clear();
}


void WpaGui::updateNetworks()
{
	char buf[4096], *start, *end, *id, *ssid, *bssid, *flags;
	size_t len;
	int first_active = -1;
	int was_selected = -1;
	bool current = false;

	if (!networkMayHaveChanged)
		return;

	if (networkList->currentRow() >= 0)
		was_selected = networkList->currentRow();

	networkSelect->clear();
	networkList->clear();

	if (ctrl_conn == NULL)
		return;

	len = sizeof(buf) - 1;
	if (ctrlRequest("LIST_NETWORKS", buf, &len) < 0)
		return;

	buf[len] = '\0';
	start = strchr(buf, '\n');
	if (start == NULL)
		return;
	start++;

	while (*start) {
		bool last = false;
		end = strchr(start, '\n');
		if (end == NULL) {
			last = true;
			end = start;
			while (end[0] && end[1])
				end++;
		}
		*end = '\0';

		id = start;
		ssid = strchr(id, '\t');
		if (ssid == NULL)
			break;
		*ssid++ = '\0';
		bssid = strchr(ssid, '\t');
		if (bssid == NULL)
			break;
		*bssid++ = '\0';
		flags = strchr(bssid, '\t');
		if (flags == NULL)
			break;
		*flags++ = '\0';

		if (strstr(flags, "[DISABLED][P2P-PERSISTENT]")) {
			if (last)
				break;
			start = end + 1;
			continue;
		}

		QString network(id);
		network.append(": ");
		network.append(ssid);
		networkSelect->addItem(network);
		networkList->addItem(network);

		if (strstr(flags, "[CURRENT]")) {
			networkSelect->setCurrentIndex(networkSelect->count() -
						      1);
			current = true;
		} else if (first_active < 0 &&
			   strstr(flags, "[DISABLED]") == NULL)
			first_active = networkSelect->count() - 1;

		if (last)
			break;
		start = end + 1;
	}

	if (networkSelect->count() > 1)
		networkSelect->addItem(tr("Select any network"));

	if (!current && first_active >= 0)
		networkSelect->setCurrentIndex(first_active);

	if (was_selected >= 0 && networkList->count() > 0) {
		if (was_selected < networkList->count())
			networkList->setCurrentRow(was_selected);
		else
			networkList->setCurrentRow(networkList->count() - 1);
	}
	else
		networkList->setCurrentRow(networkSelect->currentIndex());

	networkMayHaveChanged = false;
}


void WpaGui::helpIndex()
{
	debug("helpIndex");
}


void WpaGui::helpContents()
{
	debug("helpContents");
}


void WpaGui::helpAbout()
{
	QMessageBox::about(this, "wpa_gui for wpa_supplicant",
			   "Copyright (c) 2003-2015,\n"
			   "Jouni Malinen <j@w1.fi>\n"
			   "and contributors.\n"
			   "\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"
			   "OpenSSL Toolkit (http://www.openssl.org/)\n");
}


void WpaGui::disconnect()
{
	char reply[10];
	size_t reply_len = sizeof(reply);
	ctrlRequest("DISCONNECT", reply, &reply_len);
	stopWpsRun(false);
}


void WpaGui::scan()
{
	if (scanres) {
		scanres->close();
		delete scanres;
	}

	scanres = new ScanResults();
	if (scanres == NULL)
		return;
	scanres->setWpaGui(this);
	scanres->show();
	scanres->exec();
}


void WpaGui::eventHistory()
{
	if (eh) {
		eh->close();
		delete eh;
	}

	eh = new EventHistory();
	if (eh == NULL)
		return;
	eh->addEvents(msgs);
	eh->show();
	eh->exec();
}


void WpaGui::ping()
{
	char buf[10];
	size_t len;

#ifdef CONFIG_CTRL_IFACE_NAMED_PIPE
	/*
	 * QSocketNotifier cannot be used with Windows named pipes, so use a
	 * timer to check for received messages for now. This could be
	 * optimized be doing something specific to named pipes or Windows
	 * events, but it is not clear what would be the best way of doing that
	 * in Qt.
	 */
	receiveMsgs();
#endif /* CONFIG_CTRL_IFACE_NAMED_PIPE */

	if (scanres && !scanres->isVisible()) {
		delete scanres;
		scanres = NULL;
	}

	if (eh && !eh->isVisible()) {
		delete eh;
		eh = NULL;
	}

	if (udr && !udr->isVisible()) {
		delete udr;
		udr = NULL;
	}

	len = sizeof(buf) - 1;
	if (ctrlRequest("PING", buf, &len) < 0) {
		debug("PING failed - trying to reconnect");
		if (openCtrlConnection(ctrl_iface) >= 0) {
			debug("Reconnected successfully");
			pingsToStatusUpdate = 0;
		}
	}

	pingsToStatusUpdate--;
	if (pingsToStatusUpdate <= 0) {
		updateStatus();
		updateNetworks();
	}

#ifndef CONFIG_CTRL_IFACE_NAMED_PIPE
	/* Use less frequent pings and status updates when the main window is
	 * hidden (running in taskbar). */
	int interval = isHidden() ? 5000 : 1000;
	if (timer->interval() != interval)
		timer->setInterval(interval);
#endif /* CONFIG_CTRL_IFACE_NAMED_PIPE */
}


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;
}


void WpaGui::processMsg(char *msg)
{
	char *pos = msg, *pos2;
	int priority = 2;

	if (*pos == '<') {
		/* skip priority */
		pos++;
		priority = atoi(pos);
		pos = strchr(pos, '>');
		if (pos)
			pos++;
		else
			pos = msg;
	}

	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();

	/* Update last message with truncated version of the event */
	if (strncmp(pos, "CTRL-", 5) == 0) {
		pos2 = strchr(pos, str_match(pos, WPA_CTRL_REQ) ? ':' : ' ');
		if (pos2)
			pos2++;
		else
			pos2 = pos;
	} else
		pos2 = pos;
	QString lastmsg = pos2;
	lastmsg.truncate(40);
	textLastMessage->setText(lastmsg);

	pingsToStatusUpdate = 0;
	networkMayHaveChanged = true;

	if (str_match(pos, WPA_CTRL_REQ))
		processCtrlReq(pos + strlen(WPA_CTRL_REQ));
	else if (str_match(pos, WPA_EVENT_SCAN_RESULTS) && scanres)
		scanres->updateResults();
	else if (str_match(pos, WPA_EVENT_DISCONNECTED))
		showTrayMessage(QSystemTrayIcon::Information, 3,
				tr("Disconnected from network."));
	else if (str_match(pos, WPA_EVENT_CONNECTED)) {
		showTrayMessage(QSystemTrayIcon::Information, 3,
				tr("Connection to network established."));
		QTimer::singleShot(5 * 1000, this, SLOT(showTrayStatus()));
		stopWpsRun(true);
	} else if (str_match(pos, WPS_EVENT_AP_AVAILABLE_PBC)) {
		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"
				"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)) {
		wpsStatusText->setText(tr("WPS AP detected"));
	} else if (str_match(pos, WPS_EVENT_OVERLAP)) {
		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(tr("Network configuration received"));
		wpaguiTab->setCurrentWidget(wpsTab);
	} else if (str_match(pos, WPA_EVENT_EAP_METHOD)) {
		if (strstr(pos, "(WSC)"))
			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"));
	}
}


void WpaGui::processCtrlReq(const char *req)
{
	if (udr) {
		udr->close();
		delete udr;
	}
	udr = new UserDataRequest();
	if (udr == NULL)
		return;
	if (udr->setParams(this, req) < 0) {
		delete udr;
		udr = NULL;
		return;
	}
	udr->show();
	udr->exec();
}


void WpaGui::receiveMsgs()
{
	char buf[256];
	size_t len;

	while (monitor_conn && wpa_ctrl_pending(monitor_conn) > 0) {
		len = sizeof(buf) - 1;
		if (wpa_ctrl_recv(monitor_conn, buf, &len) == 0) {
			buf[len] = '\0';
			processMsg(buf);
		}
	}
}


void WpaGui::connectB()
{
	char reply[10];
	size_t reply_len = sizeof(reply);
	ctrlRequest("REASSOCIATE", reply, &reply_len);
}


void WpaGui::selectNetwork( const QString &sel )
{
	QString cmd(sel);
	char reply[10];
	size_t reply_len = sizeof(reply);

	if (cmd.contains(QRegExp("^\\d+:")))
		cmd.truncate(cmd.indexOf(':'));
	else
		cmd = "any";
	cmd.prepend("SELECT_NETWORK ");
	ctrlRequest(cmd.toLocal8Bit().constData(), reply, &reply_len);
	triggerUpdate();
	stopWpsRun(false);
}


void WpaGui::enableNetwork(const QString &sel)
{
	QString cmd(sel);
	char reply[10];
	size_t reply_len = sizeof(reply);

	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.toLocal8Bit().constData(), reply, &reply_len);
	triggerUpdate();
}


void WpaGui::disableNetwork(const QString &sel)
{
	QString cmd(sel);
	char reply[10];
	size_t reply_len = sizeof(reply);

	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.toLocal8Bit().constData(), reply, &reply_len);
	triggerUpdate();
}


void WpaGui::editNetwork(const QString &sel)
{
	QString cmd(sel);
	int id = -1;

	if (cmd.contains(QRegExp("^\\d+:"))) {
		cmd.truncate(cmd.indexOf(':'));
		id = cmd.toInt();
	}

	NetworkConfig *nc = new NetworkConfig();
	if (nc == NULL)
		return;
	nc->setWpaGui(this);

	if (id >= 0)
		nc->paramsFromConfig(id);
	else
		nc->newNetwork();

	nc->show();
	nc->exec();
}


void WpaGui::editSelectedNetwork()
{
	if (networkSelect->count() < 1) {
		QMessageBox::information(
			this, tr("No Networks"),
			tr("There are no networks to edit.\n"));
		return;
	}
	QString sel(networkSelect->currentText());
	editNetwork(sel);
}


void WpaGui::editListedNetwork()
{
	if (networkList->currentRow() < 0) {
		QMessageBox::information(this, tr("Select A Network"),
					 tr("Select a network from the list to"
					    " edit it.\n"));
		return;
	}
	QString sel(networkList->currentItem()->text());
	editNetwork(sel);
}


void WpaGui::triggerUpdate()
{
	updateStatus();
	networkMayHaveChanged = true;
	updateNetworks();
}


void WpaGui::addNetwork()
{
	NetworkConfig *nc = new NetworkConfig();
	if (nc == NULL)
		return;
	nc->setWpaGui(this);
	nc->newNetwork();
	nc->show();
	nc->exec();
}


void WpaGui::removeNetwork(const QString &sel)
{
	QString cmd(sel);
	char reply[10];
	size_t reply_len = sizeof(reply);

	if (cmd.contains(QRegExp("^\\d+:")))
		cmd.truncate(cmd.indexOf(':'));
	else if (!cmd.startsWith("all")) {
		debug("Invalid editNetwork '%s'",
		      cmd.toLocal8Bit().constData());
		return;
	}
	cmd.prepend("REMOVE_NETWORK ");
	ctrlRequest(cmd.toLocal8Bit().constData(), reply, &reply_len);
	triggerUpdate();
}


void WpaGui::removeSelectedNetwork()
{
	if (networkSelect->count() < 1) {
		QMessageBox::information(this, tr("No Networks"),
			                 tr("There are no networks to remove."
					    "\n"));
		return;
	}
	QString sel(networkSelect->currentText());
	removeNetwork(sel);
}


void WpaGui::removeListedNetwork()
{
	if (networkList->currentRow() < 0) {
		QMessageBox::information(this, tr("Select A Network"),
					 tr("Select a network from the list "
					    "to remove it.\n"));
		return;
	}
	QString sel(networkList->currentItem()->text());
	removeNetwork(sel);
}


void WpaGui::enableAllNetworks()
{
	QString sel("all");
	enableNetwork(sel);
}


void WpaGui::disableAllNetworks()
{
	QString sel("all");
	disableNetwork(sel);
}


void WpaGui::removeAllNetworks()
{
	QString sel("all");
	removeNetwork(sel);
}


int WpaGui::getNetworkDisabled(const QString &sel)
{
	QString cmd(sel);
	char reply[10];
	size_t reply_len = sizeof(reply) - 1;
	int pos = cmd.indexOf(':');
	if (pos < 0) {
		debug("Invalid getNetworkDisabled '%s'",
		      cmd.toLocal8Bit().constData());
		return -1;
	}
	cmd.truncate(pos);
	cmd.prepend("GET_NETWORK ");
	cmd.append(" disabled");

	if (ctrlRequest(cmd.toLocal8Bit().constData(), reply, &reply_len) >= 0
	    && reply_len >= 1) {
		reply[reply_len] = '\0';
		if (!str_match(reply, "FAIL"))
			return atoi(reply);
	}

	return -1;
}


void WpaGui::updateNetworkDisabledStatus()
{
	if (networkList->currentRow() < 0)
		return;

	QString sel(networkList->currentItem()->text());

	switch (getNetworkDisabled(sel)) {
	case 0:
		if (!enableRadioButton->isChecked())
			enableRadioButton->setChecked(true);
		return;
	case 1:
		if (!disableRadioButton->isChecked())
			disableRadioButton->setChecked(true);
		return;
	}
}


void WpaGui::enableListedNetwork(bool enabled)
{
	if (networkList->currentRow() < 0 || !enabled)
		return;

	QString sel(networkList->currentItem()->text());

	if (getNetworkDisabled(sel) == 1)
		enableNetwork(sel);
}


void WpaGui::disableListedNetwork(bool disabled)
{
	if (networkList->currentRow() < 0 || !disabled)
		return;

	QString sel(networkList->currentItem()->text());

	if (getNetworkDisabled(sel) == 0)
		disableNetwork(sel);
}


void WpaGui::saveConfig()
{
	char buf[10];
	size_t len;

	len = sizeof(buf) - 1;
	ctrlRequest("SAVE_CONFIG", buf, &len);

	buf[len] = '\0';

	if (str_match(buf, "FAIL"))
		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, tr("Saved configuration"),
			tr("The current configuration was saved."
			   "\n"));
}


void WpaGui::selectAdapter( const QString & sel )
{
	if (openCtrlConnection(sel.toLocal8Bit().constData()) < 0)
		debug("Failed to open control connection to "
		      "wpa_supplicant.");
	updateStatus();
	updateNetworks();
}


void WpaGui::createTrayIcon(bool trayOnly)
{
	QApplication::setQuitOnLastWindowClosed(false);

	tray_icon = new QSystemTrayIcon(this);
	updateTrayIcon(TrayIconOffline);

	connect(tray_icon,
		SIGNAL(activated(QSystemTrayIcon::ActivationReason)),
		this, SLOT(trayActivated(QSystemTrayIcon::ActivationReason)));

	ackTrayIcon = false;

	tray_menu = new QMenu(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,
		SLOT(connectB()));
	tray_menu->addAction(disconnectAction);
	tray_menu->addAction(reconnectAction);
	tray_menu->addSeparator();

	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(eventAction);
	tray_menu->addAction(scanAction);
	tray_menu->addAction(statAction);
	tray_menu->addSeparator();

	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()));
	tray_menu->addAction(showAction);
	tray_menu->addAction(hideAction);
	tray_menu->addSeparator();
	tray_menu->addAction(quitAction);

	tray_icon->setContextMenu(tray_menu);

	tray_icon->show();

	if (!trayOnly)
		show();
	inTray = trayOnly;
}


void WpaGui::showTrayMessage(QSystemTrayIcon::MessageIcon type, int sec,
			     const QString & msg)
{
	if (!QSystemTrayIcon::supportsMessages())
		return;

	if (isVisible() || !tray_icon || !tray_icon->isVisible() || quietMode)
		return;

	tray_icon->showMessage(qAppName(), msg, type, sec * 1000);
}


void WpaGui::trayActivated(QSystemTrayIcon::ActivationReason how)
 {
	switch (how) {
	/* use close() here instead of hide() and allow the
	 * custom closeEvent handler take care of children */
	case QSystemTrayIcon::Trigger:
		ackTrayIcon = true;
		if (isVisible()) {
			close();
			inTray = true;
		} else {
			show();
			inTray = false;
		}
		break;
	case QSystemTrayIcon::MiddleClick:
		showTrayStatus();
		break;
	default:
		break;
	}
}


void WpaGui::showTrayStatus()
{
	char buf[2048];
	size_t len;

	len = sizeof(buf) - 1;
	if (ctrlRequest("STATUS", buf, &len) < 0)
		return;
	buf[len] = '\0';

	QString msg, status(buf);

	QStringList lines = status.split(QRegExp("\\n"));
	for (QStringList::Iterator it = lines.begin();
	     it != lines.end(); it++) {
		int pos = (*it).indexOf('=') + 1;
		if (pos < 1)
			continue;

		if ((*it).startsWith("bssid="))
			msg.append("BSSID:\t" + (*it).mid(pos) + "\n");
		else if ((*it).startsWith("ssid="))
			msg.append("SSID: \t" + (*it).mid(pos) + "\n");
		else if ((*it).startsWith("pairwise_cipher="))
			msg.append("PAIR: \t" + (*it).mid(pos) + "\n");
		else if ((*it).startsWith("group_cipher="))
			msg.append("GROUP:\t" + (*it).mid(pos) + "\n");
		else if ((*it).startsWith("key_mgmt="))
			msg.append("AUTH: \t" + (*it).mid(pos) + "\n");
		else if ((*it).startsWith("wpa_state="))
			msg.append("STATE:\t" + (*it).mid(pos) + "\n");
		else if ((*it).startsWith("ip_address="))
			msg.append("IP:   \t" + (*it).mid(pos) + "\n");
		else if ((*it).startsWith("Supplicant PAE state="))
			msg.append("PAE:  \t" + (*it).mid(pos) + "\n");
		else if ((*it).startsWith("EAP state="))
			msg.append("EAP:  \t" + (*it).mid(pos) + "\n");
	}

	if (!msg.isEmpty())
		showTrayMessage(QSystemTrayIcon::Information, 10, msg);
}


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) {
		eh->close();
		delete eh;
		eh = NULL;
	}

	if (scanres) {
		scanres->close();
		delete scanres;
		scanres = NULL;
	}

	if (peers) {
		peers->close();
		delete peers;
		peers = NULL;
	}

	if (udr) {
		udr->close();
		delete udr;
		udr = NULL;
	}

	if (tray_icon && !ackTrayIcon) {
		/* give user a visual hint that the tray icon exists */
		if (QSystemTrayIcon::supportsMessages()) {
			hide();
			showTrayMessage(QSystemTrayIcon::Information, 3,
					qAppName() +
					tr(" will keep running in "
					   "the system tray."));
		} else {
			QMessageBox::information(this, qAppName() +
						 tr(" systray"),
						 tr("The program will keep "
						    "running in the system "
						    "tray."));
		}
		ackTrayIcon = true;
	}

	event->accept();
}


void WpaGui::wpsDialog()
{
	wpaguiTab->setCurrentWidget(wpsTab);
}


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)
		return;

	if (wpsRunning)
		return;

	wpsApPinEdit->setEnabled(!bssFromScan.isEmpty());
	if (bssFromScan.isEmpty())
		wpsApPinButton->setEnabled(false);
}


void WpaGui::wpsPbc()
{
	char reply[20];
	size_t reply_len = sizeof(reply);

	if (ctrlRequest("WPS_PBC", reply, &reply_len) < 0)
		return;

	wpsPinEdit->setEnabled(false);
	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(tr("If you have not yet done so, press "
					 "the push button on the AP to start "
					 "the PBC mode."));
	}
	wpsStatusText->setText(tr("Waiting for Registrar"));
	wpsRunning = true;
}


void WpaGui::wpsGeneratePin()
{
	char reply[20];
	size_t reply_len = sizeof(reply) - 1;

	if (ctrlRequest("WPS_PIN any", reply, &reply_len) < 0)
		return;

	reply[reply_len] = '\0';

	wpsPinEdit->setText(reply);
	wpsPinEdit->setEnabled(true);
	wpsInstructions->setText(tr("Enter the generated PIN into the Registrar "
				 "(either the internal one in the AP or an "
				 "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
