/*
 * wpa_gui - Peers class
 * Copyright (c) 2009-2010, Atheros Communications
 *
 * This software may be distributed under the terms of the BSD license.
 * See README for more details.
 */

#include <cstdio>
#include <QImageReader>
#include <QMessageBox>

#include "common/wpa_ctrl.h"
#include "wpagui.h"
#include "stringquery.h"
#include "peers.h"


enum {
	peer_role_address = Qt::UserRole + 1,
	peer_role_type,
	peer_role_uuid,
	peer_role_details,
	peer_role_ifname,
	peer_role_pri_dev_type,
	peer_role_ssid,
	peer_role_config_methods,
	peer_role_dev_passwd_id,
	peer_role_bss_id,
	peer_role_selected_method,
	peer_role_selected_pin,
	peer_role_requested_method,
	peer_role_network_id
};

enum selected_method {
	SEL_METHOD_NONE,
	SEL_METHOD_PIN_PEER_DISPLAY,
	SEL_METHOD_PIN_LOCAL_DISPLAY
};

/*
 * TODO:
 * - add current AP info (e.g., from WPS) in station mode
 */

enum peer_type {
	PEER_TYPE_ASSOCIATED_STATION,
	PEER_TYPE_AP,
	PEER_TYPE_AP_WPS,
	PEER_TYPE_WPS_PIN_NEEDED,
	PEER_TYPE_P2P,
	PEER_TYPE_P2P_CLIENT,
	PEER_TYPE_P2P_GROUP,
	PEER_TYPE_P2P_PERSISTENT_GROUP_GO,
	PEER_TYPE_P2P_PERSISTENT_GROUP_CLIENT,
	PEER_TYPE_P2P_INVITATION,
	PEER_TYPE_WPS_ER_AP,
	PEER_TYPE_WPS_ER_AP_UNCONFIGURED,
	PEER_TYPE_WPS_ER_ENROLLEE,
	PEER_TYPE_WPS_ENROLLEE
};


Peers::Peers(QWidget *parent, const char *, bool, Qt::WindowFlags)
	: QDialog(parent)
{
	setupUi(this);

	if (QImageReader::supportedImageFormats().contains(QByteArray("svg")))
	{
		default_icon = new QIcon(":/icons/wpa_gui.svg");
		ap_icon = new QIcon(":/icons/ap.svg");
		laptop_icon = new QIcon(":/icons/laptop.svg");
		group_icon = new QIcon(":/icons/group.svg");
		invitation_icon = new QIcon(":/icons/invitation.svg");
	} else {
		default_icon = new QIcon(":/icons/wpa_gui.png");
		ap_icon = new QIcon(":/icons/ap.png");
		laptop_icon = new QIcon(":/icons/laptop.png");
		group_icon = new QIcon(":/icons/group.png");
		invitation_icon = new QIcon(":/icons/invitation.png");
	}

	peers->setModel(&model);
	peers->setResizeMode(QListView::Adjust);
	peers->setDragEnabled(false);
	peers->setSelectionMode(QAbstractItemView::NoSelection);

	peers->setContextMenuPolicy(Qt::CustomContextMenu);
	connect(peers, SIGNAL(customContextMenuRequested(const QPoint &)),
		this, SLOT(context_menu(const QPoint &)));

	wpagui = NULL;
	hide_ap = false;
}


void Peers::setWpaGui(WpaGui *_wpagui)
{
	wpagui = _wpagui;
	update_peers();
}


Peers::~Peers()
{
	delete default_icon;
	delete ap_icon;
	delete laptop_icon;
	delete group_icon;
	delete invitation_icon;
}


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


QString Peers::ItemType(int type)
{
	QString title;
	switch (type) {
	case PEER_TYPE_ASSOCIATED_STATION:
		title = tr("Associated station");
		break;
	case PEER_TYPE_AP:
		title = tr("AP");
		break;
	case PEER_TYPE_AP_WPS:
		title = tr("WPS AP");
		break;
	case PEER_TYPE_WPS_PIN_NEEDED:
		title = tr("WPS PIN needed");
		break;
	case PEER_TYPE_P2P:
		title = tr("P2P Device");
		break;
	case PEER_TYPE_P2P_CLIENT:
		title = tr("P2P Device (group client)");
		break;
	case PEER_TYPE_P2P_GROUP:
		title = tr("P2P Group");
		break;
	case PEER_TYPE_P2P_PERSISTENT_GROUP_GO:
		title = tr("P2P Persistent Group (GO)");
		break;
	case PEER_TYPE_P2P_PERSISTENT_GROUP_CLIENT:
		title = tr("P2P Persistent Group (client)");
		break;
	case PEER_TYPE_P2P_INVITATION:
		title = tr("P2P Invitation");
		break;
	case PEER_TYPE_WPS_ER_AP:
		title = tr("ER: WPS AP");
		break;
	case PEER_TYPE_WPS_ER_AP_UNCONFIGURED:
		title = tr("ER: WPS AP (Unconfigured)");
		break;
	case PEER_TYPE_WPS_ER_ENROLLEE:
		title = tr("ER: WPS Enrollee");
		break;
	case PEER_TYPE_WPS_ENROLLEE:
		title = tr("WPS Enrollee");
		break;
	}
	return title;
}


void Peers::context_menu(const QPoint &pos)
{
	QMenu *menu = new QMenu;
	if (menu == NULL)
		return;

	QModelIndex idx = peers->indexAt(pos);
	if (idx.isValid()) {
		ctx_item = model.itemFromIndex(idx);
		int type = ctx_item->data(peer_role_type).toInt();
		menu->addAction(Peers::ItemType(type))->setEnabled(false);
		menu->addSeparator();

		int config_methods = -1;
		QVariant var = ctx_item->data(peer_role_config_methods);
		if (var.isValid())
			config_methods = var.toInt();

		enum selected_method method = SEL_METHOD_NONE;
		var = ctx_item->data(peer_role_selected_method);
		if (var.isValid())
			method = (enum selected_method) var.toInt();

		if ((type == PEER_TYPE_ASSOCIATED_STATION ||
		     type == PEER_TYPE_AP_WPS ||
		     type == PEER_TYPE_WPS_PIN_NEEDED ||
		     type == PEER_TYPE_WPS_ER_ENROLLEE ||
		     type == PEER_TYPE_WPS_ENROLLEE) &&
		    (config_methods == -1 || (config_methods & 0x010c))) {
			menu->addAction(tr("Enter WPS PIN"), this,
					SLOT(enter_pin()));
		}

		if (type == PEER_TYPE_P2P || type == PEER_TYPE_P2P_CLIENT) {
			menu->addAction(tr("P2P Connect"), this,
					SLOT(ctx_p2p_connect()));
			if (method == SEL_METHOD_NONE &&
			    config_methods > -1 &&
			    config_methods & 0x0080 /* PBC */ &&
			    config_methods != 0x0080)
				menu->addAction(tr("P2P Connect (PBC)"), this,
						SLOT(connect_pbc()));
			if (method == SEL_METHOD_NONE) {
				menu->addAction(tr("P2P Request PIN"), this,
						SLOT(ctx_p2p_req_pin()));
				menu->addAction(tr("P2P Show PIN"), this,
						SLOT(ctx_p2p_show_pin()));
			}

			if (config_methods > -1 && (config_methods & 0x0100)) {
				/* Peer has Keypad */
				menu->addAction(tr("P2P Display PIN"), this,
						SLOT(ctx_p2p_display_pin()));
			}

			if (config_methods > -1 && (config_methods & 0x000c)) {
				/* Peer has Label or Display */
				menu->addAction(tr("P2P Enter PIN"), this,
						SLOT(ctx_p2p_enter_pin()));
			}
		}

		if (type == PEER_TYPE_P2P_GROUP) {
			menu->addAction(tr("Show passphrase"), this,
					SLOT(ctx_p2p_show_passphrase()));
			menu->addAction(tr("Remove P2P Group"), this,
					SLOT(ctx_p2p_remove_group()));
		}

		if (type == PEER_TYPE_P2P_PERSISTENT_GROUP_GO ||
		    type == PEER_TYPE_P2P_PERSISTENT_GROUP_CLIENT ||
		    type == PEER_TYPE_P2P_INVITATION) {
			menu->addAction(tr("Start group"), this,
					SLOT(ctx_p2p_start_persistent()));
		}

		if (type == PEER_TYPE_P2P_PERSISTENT_GROUP_GO ||
		    type == PEER_TYPE_P2P_PERSISTENT_GROUP_CLIENT) {
			menu->addAction(tr("Invite"), this,
					SLOT(ctx_p2p_invite()));
		}

		if (type == PEER_TYPE_P2P_INVITATION) {
			menu->addAction(tr("Ignore"), this,
					SLOT(ctx_p2p_delete()));
		}

		if (type == PEER_TYPE_AP_WPS) {
			menu->addAction(tr("Connect (PBC)"), this,
					SLOT(connect_pbc()));
		}

		if ((type == PEER_TYPE_ASSOCIATED_STATION ||
		     type == PEER_TYPE_WPS_ER_ENROLLEE ||
		     type == PEER_TYPE_WPS_ENROLLEE) &&
		    config_methods >= 0 && (config_methods & 0x0080)) {
			menu->addAction(tr("Enroll (PBC)"), this,
					SLOT(connect_pbc()));
		}

		if (type == PEER_TYPE_WPS_ER_AP) {
			menu->addAction(tr("Learn Configuration"), this,
					SLOT(learn_ap_config()));
		}

		menu->addAction(tr("Properties"), this, SLOT(properties()));
	} else {
		ctx_item = NULL;
		menu->addAction(QString(tr("Refresh")), this,
				SLOT(ctx_refresh()));
		menu->addAction(tr("Start P2P discovery"), this,
				SLOT(ctx_p2p_start()));
		menu->addAction(tr("Stop P2P discovery"), this,
				SLOT(ctx_p2p_stop()));
		menu->addAction(tr("P2P listen only"), this,
				SLOT(ctx_p2p_listen()));
		menu->addAction(tr("Start P2P group"), this,
				SLOT(ctx_p2p_start_group()));
		if (hide_ap)
			menu->addAction(tr("Show AP entries"), this,
					SLOT(ctx_show_ap()));
		else
			menu->addAction(tr("Hide AP entries"), this,
					SLOT(ctx_hide_ap()));
	}

	menu->exec(peers->mapToGlobal(pos));
}


void Peers::enter_pin()
{
	if (ctx_item == NULL)
		return;

	int peer_type = ctx_item->data(peer_role_type).toInt();
	QString uuid;
	QString addr;
	addr = ctx_item->data(peer_role_address).toString();
	if (peer_type == PEER_TYPE_WPS_ER_ENROLLEE)
		uuid = ctx_item->data(peer_role_uuid).toString();

	StringQuery input(tr("PIN:"));
	input.setWindowTitle(tr("PIN for ") + ctx_item->text());
	if (input.exec() != QDialog::Accepted)
		return;

	char cmd[100];
	char reply[100];
	size_t reply_len;

	if (peer_type == PEER_TYPE_WPS_ER_ENROLLEE) {
		snprintf(cmd, sizeof(cmd), "WPS_ER_PIN %s %s %s",
			 uuid.toLocal8Bit().constData(),
			 input.get_string().toLocal8Bit().constData(),
			 addr.toLocal8Bit().constData());
	} else {
		snprintf(cmd, sizeof(cmd), "WPS_PIN %s %s",
			 addr.toLocal8Bit().constData(),
			 input.get_string().toLocal8Bit().constData());
	}
	reply_len = sizeof(reply) - 1;
	if (wpagui->ctrlRequest(cmd, reply, &reply_len) < 0) {
		QMessageBox msg;
		msg.setIcon(QMessageBox::Warning);
		msg.setText(tr("Failed to set the WPS PIN."));
		msg.exec();
	}
}


void Peers::ctx_refresh()
{
	update_peers();
}


void Peers::ctx_p2p_start()
{
	char reply[20];
	size_t reply_len;
	reply_len = sizeof(reply) - 1;
	if (wpagui->ctrlRequest("P2P_FIND", reply, &reply_len) < 0 ||
	    memcmp(reply, "FAIL", 4) == 0) {
		QMessageBox msg;
		msg.setIcon(QMessageBox::Warning);
		msg.setText("Failed to start P2P discovery.");
		msg.exec();
	}
}


void Peers::ctx_p2p_stop()
{
	char reply[20];
	size_t reply_len;
	reply_len = sizeof(reply) - 1;
	wpagui->ctrlRequest("P2P_STOP_FIND", reply, &reply_len);
}


void Peers::ctx_p2p_listen()
{
	char reply[20];
	size_t reply_len;
	reply_len = sizeof(reply) - 1;
	if (wpagui->ctrlRequest("P2P_LISTEN 3600", reply, &reply_len) < 0 ||
	    memcmp(reply, "FAIL", 4) == 0) {
		QMessageBox msg;
		msg.setIcon(QMessageBox::Warning);
		msg.setText("Failed to start P2P listen.");
		msg.exec();
	}
}


void Peers::ctx_p2p_start_group()
{
	char reply[20];
	size_t reply_len;
	reply_len = sizeof(reply) - 1;
	if (wpagui->ctrlRequest("P2P_GROUP_ADD", reply, &reply_len) < 0 ||
	    memcmp(reply, "FAIL", 4) == 0) {
		QMessageBox msg;
		msg.setIcon(QMessageBox::Warning);
		msg.setText("Failed to start P2P group.");
		msg.exec();
	}
}


void Peers::add_station(QString info)
{
	QStringList lines = info.split(QRegExp("\\n"));
	QString name;

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

		if ((*it).startsWith("wpsDeviceName="))
			name = (*it).mid(pos);
		else if ((*it).startsWith("p2p_device_name="))
			name = (*it).mid(pos);
	}

	if (name.isEmpty())
		name = lines[0];

	QStandardItem *item = new QStandardItem(*laptop_icon, name);
	if (item) {
		/* Remove WPS enrollee entry if one is still pending */
		if (model.rowCount() > 0) {
			QModelIndexList lst = model.match(model.index(0, 0),
							  peer_role_address,
							  lines[0]);
			for (int i = 0; i < lst.size(); i++) {
				QStandardItem *item;
				item = model.itemFromIndex(lst[i]);
				if (item == NULL)
					continue;
				int type = item->data(peer_role_type).toInt();
				if (type == PEER_TYPE_WPS_ENROLLEE) {
					model.removeRow(lst[i].row());
					break;
				}
			}
		}

		item->setData(lines[0], peer_role_address);
		item->setData(PEER_TYPE_ASSOCIATED_STATION,
			      peer_role_type);
		item->setData(info, peer_role_details);
		item->setToolTip(ItemType(PEER_TYPE_ASSOCIATED_STATION));
		model.appendRow(item);
	}
}


void Peers::add_stations()
{
	char reply[2048];
	size_t reply_len;
	char cmd[30];
	int res;

	reply_len = sizeof(reply) - 1;
	if (wpagui->ctrlRequest("STA-FIRST", reply, &reply_len) < 0)
		return;

	do {
		reply[reply_len] = '\0';
		QString info(reply);
		char *txt = reply;
		while (*txt != '\0' && *txt != '\n')
			txt++;
		*txt++ = '\0';
		if (strncmp(reply, "FAIL", 4) == 0 ||
		    strncmp(reply, "UNKNOWN", 7) == 0)
			break;

		add_station(info);

		reply_len = sizeof(reply) - 1;
		snprintf(cmd, sizeof(cmd), "STA-NEXT %s", reply);
		res = wpagui->ctrlRequest(cmd, reply, &reply_len);
	} while (res >= 0);
}


void Peers::add_single_station(const char *addr)
{
	char reply[2048];
	size_t reply_len;
	char cmd[30];

	reply_len = sizeof(reply) - 1;
	snprintf(cmd, sizeof(cmd), "STA %s", addr);
	if (wpagui->ctrlRequest(cmd, reply, &reply_len) < 0)
		return;

	reply[reply_len] = '\0';
	QString info(reply);
	char *txt = reply;
	while (*txt != '\0' && *txt != '\n')
		txt++;
	*txt++ = '\0';
	if (strncmp(reply, "FAIL", 4) == 0 ||
	    strncmp(reply, "UNKNOWN", 7) == 0)
		return;

	add_station(info);
}


void Peers::add_p2p_group_client(QStandardItem * /*parent*/, QString params)
{
	/*
	 * dev=02:b5:64:63:30:63 iface=02:b5:64:63:30:63 dev_capab=0x0
	 * dev_type=1-0050f204-1 dev_name='Wireless Client'
	 * config_methods=0x8c
	 */

	QStringList items =
		params.split(QRegExp(" (?=[^']*('[^']*'[^']*)*$)"));
	QString addr = "";
	QString name = "";
	int config_methods = 0;
	QString dev_type;

	for (int i = 0; i < items.size(); i++) {
		QString str = items.at(i);
		int pos = str.indexOf('=') + 1;
		if (str.startsWith("dev_name='"))
			name = str.section('\'', 1, -2);
		else if (str.startsWith("config_methods="))
			config_methods =
				str.section('=', 1).toInt(0, 0);
		else if (str.startsWith("dev="))
			addr = str.mid(pos);
		else if (str.startsWith("dev_type=") && dev_type.isEmpty())
			dev_type = str.mid(pos);
	}

	QStandardItem *item = find_addr(addr);
	if (item)
		return;

	item = new QStandardItem(*default_icon, name);
	if (item) {
		/* TODO: indicate somehow the relationship to the group owner
		 * (parent) */
		item->setData(addr, peer_role_address);
		item->setData(config_methods, peer_role_config_methods);
		item->setData(PEER_TYPE_P2P_CLIENT, peer_role_type);
		if (!dev_type.isEmpty())
			item->setData(dev_type, peer_role_pri_dev_type);
		item->setData(items.join(QString("\n")), peer_role_details);
		item->setToolTip(ItemType(PEER_TYPE_P2P_CLIENT));
		model.appendRow(item);
	}
}


void Peers::remove_bss(int id)
{
	if (model.rowCount() == 0)
		return;

	QModelIndexList lst = model.match(model.index(0, 0), peer_role_bss_id,
					  id);
	if (lst.size() == 0)
		return;
	model.removeRow(lst[0].row());
}


bool Peers::add_bss(const char *cmd)
{
	char reply[2048];
	size_t reply_len;

	if (hide_ap)
		return false;

	reply_len = sizeof(reply) - 1;
	if (wpagui->ctrlRequest(cmd, reply, &reply_len) < 0)
		return false;
	reply[reply_len] = '\0';

	QString bss(reply);
	if (bss.isEmpty() || bss.startsWith("FAIL"))
		return false;

	QString ssid, bssid, flags, wps_name, pri_dev_type;
	int id = -1;

	QStringList lines = bss.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="))
			bssid = (*it).mid(pos);
		else if ((*it).startsWith("id="))
			id = (*it).mid(pos).toInt();
		else if ((*it).startsWith("flags="))
			flags = (*it).mid(pos);
		else if ((*it).startsWith("ssid="))
			ssid = (*it).mid(pos);
		else if ((*it).startsWith("wps_device_name="))
			wps_name = (*it).mid(pos);
		else if ((*it).startsWith("wps_primary_device_type="))
			pri_dev_type = (*it).mid(pos);
	}

	QString name = wps_name;
	if (name.isEmpty())
		name = ssid + "\n" + bssid;

	QStandardItem *item = new QStandardItem(*ap_icon, name);
	if (item) {
		item->setData(bssid, peer_role_address);
		if (id >= 0)
			item->setData(id, peer_role_bss_id);
		int type;
		if (flags.contains("[WPS"))
			type = PEER_TYPE_AP_WPS;
		else
			type = PEER_TYPE_AP;
		item->setData(type, peer_role_type);

		for (int i = 0; i < lines.size(); i++) {
			if (lines[i].length() > 60) {
				lines[i].remove(60, lines[i].length());
				lines[i] += "..";
			}
		}
		item->setToolTip(ItemType(type));
		item->setData(lines.join("\n"), peer_role_details);
		if (!pri_dev_type.isEmpty())
			item->setData(pri_dev_type,
				      peer_role_pri_dev_type);
		if (!ssid.isEmpty())
			item->setData(ssid, peer_role_ssid);
		model.appendRow(item);

		lines = bss.split(QRegExp("\\n"));
		for (QStringList::Iterator it = lines.begin();
		     it != lines.end(); it++) {
			if ((*it).startsWith("p2p_group_client:"))
				add_p2p_group_client(item,
						     (*it).mid(18));
		}
	}

	return true;
}


void Peers::add_scan_results()
{
	int index;
	char cmd[20];

	index = 0;
	while (wpagui) {
		snprintf(cmd, sizeof(cmd), "BSS %d", index++);
		if (index > 1000)
			break;

		if (!add_bss(cmd))
			break;
	}
}


void Peers::add_persistent(int id, const char *ssid, const char *bssid)
{
	char cmd[100];
	char reply[100];
	size_t reply_len;
	int mode;

	snprintf(cmd, sizeof(cmd), "GET_NETWORK %d mode", id);
	if (wpagui->ctrlRequest(cmd, reply, &reply_len) < 0)
		return;
	reply[reply_len] = '\0';
	mode = atoi(reply);

	QString name = ssid;
	name = '[' + name + ']';

	QStandardItem *item = new QStandardItem(*group_icon, name);
	if (!item)
		return;

	int type;
	if (mode == 3)
		type = PEER_TYPE_P2P_PERSISTENT_GROUP_GO;
	else
		type = PEER_TYPE_P2P_PERSISTENT_GROUP_CLIENT;
	item->setData(type, peer_role_type);
	item->setToolTip(ItemType(type));
	item->setData(ssid, peer_role_ssid);
	if (bssid && strcmp(bssid, "any") == 0)
		bssid = NULL;
	if (bssid)
		item->setData(bssid, peer_role_address);
	item->setData(id, peer_role_network_id);
	item->setBackground(Qt::BDiagPattern);

	model.appendRow(item);
}


void Peers::add_persistent_groups()
{
	char buf[2048], *start, *end, *id, *ssid, *bssid, *flags;
	size_t len;

	len = sizeof(buf) - 1;
	if (wpagui->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]"))
			add_persistent(atoi(id), ssid, bssid);

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


void Peers::update_peers()
{
	model.clear();
	if (wpagui == NULL)
		return;

	char reply[20];
	size_t replylen = sizeof(reply) - 1;
	wpagui->ctrlRequest("WPS_ER_START", reply, &replylen);

	add_stations();
	add_scan_results();
	add_persistent_groups();
}


QStandardItem * Peers::find_addr(QString addr)
{
	if (model.rowCount() == 0)
		return NULL;

	QModelIndexList lst = model.match(model.index(0, 0), peer_role_address,
					  addr);
	if (lst.size() == 0)
		return NULL;
	return model.itemFromIndex(lst[0]);
}


QStandardItem * Peers::find_addr_type(QString addr, int type)
{
	if (model.rowCount() == 0)
		return NULL;

	QModelIndexList lst = model.match(model.index(0, 0), peer_role_address,
					  addr);
	for (int i = 0; i < lst.size(); i++) {
		QStandardItem *item = model.itemFromIndex(lst[i]);
		if (item->data(peer_role_type).toInt() == type)
			return item;
	}
	return NULL;
}


QStandardItem * Peers::find_uuid(QString uuid)
{
	if (model.rowCount() == 0)
		return NULL;

	QModelIndexList lst = model.match(model.index(0, 0), peer_role_uuid,
					  uuid);
	if (lst.size() == 0)
		return NULL;
	return model.itemFromIndex(lst[0]);
}


void Peers::event_notify(WpaMsg msg)
{
	QString text = msg.getMsg();

	if (text.startsWith(WPS_EVENT_PIN_NEEDED)) {
		/*
		 * WPS-PIN-NEEDED 5a02a5fa-9199-5e7c-bc46-e183d3cb32f7
		 * 02:2a:c4:18:5b:f3
		 * [Wireless Client|Company|cmodel|123|12345|1-0050F204-1]
		 */
		QStringList items = text.split(' ');
		QString uuid = items[1];
		QString addr = items[2];
		QString name = "";

		QStandardItem *item = find_addr(addr);
		if (item)
			return;

		int pos = text.indexOf('[');
		if (pos >= 0) {
			int pos2 = text.lastIndexOf(']');
			if (pos2 >= pos) {
				items = text.mid(pos + 1, pos2 - pos - 1).
					split('|');
				name = items[0];
				items.append(addr);
			}
		}

		item = new QStandardItem(*laptop_icon, name);
		if (item) {
			item->setData(addr, peer_role_address);
			item->setData(PEER_TYPE_WPS_PIN_NEEDED,
				      peer_role_type);
			item->setToolTip(ItemType(PEER_TYPE_WPS_PIN_NEEDED));
			item->setData(items.join("\n"), peer_role_details);
			item->setData(items[5], peer_role_pri_dev_type);
			model.appendRow(item);
		}
		return;
	}

	if (text.startsWith(AP_STA_CONNECTED)) {
		/* AP-STA-CONNECTED 02:2a:c4:18:5b:f3 */
		QStringList items = text.split(' ');
		QString addr = items[1];
		QStandardItem *item = find_addr(addr);
		if (item == NULL || item->data(peer_role_type).toInt() !=
		    PEER_TYPE_ASSOCIATED_STATION)
			add_single_station(addr.toLocal8Bit().constData());
		return;
	}

	if (text.startsWith(AP_STA_DISCONNECTED)) {
		/* AP-STA-DISCONNECTED 02:2a:c4:18:5b:f3 */
		QStringList items = text.split(' ');
		QString addr = items[1];

		if (model.rowCount() == 0)
			return;

		QModelIndexList lst = model.match(model.index(0, 0),
						  peer_role_address, addr, -1);
		for (int i = 0; i < lst.size(); i++) {
			QStandardItem *item = model.itemFromIndex(lst[i]);
			if (item && item->data(peer_role_type).toInt() ==
			    PEER_TYPE_ASSOCIATED_STATION) {
				model.removeRow(lst[i].row());
				break;
			}
		}
		return;
	}

	if (text.startsWith(P2P_EVENT_DEVICE_FOUND)) {
		/*
		 * P2P-DEVICE-FOUND 02:b5:64:63:30:63
		 * p2p_dev_addr=02:b5:64:63:30:63 pri_dev_type=1-0050f204-1
		 * name='Wireless Client' config_methods=0x84 dev_capab=0x21
		 * group_capab=0x0
		 */
		QStringList items =
			text.split(QRegExp(" (?=[^']*('[^']*'[^']*)*$)"));
		QString addr = items[1];
		QString name = "";
		QString pri_dev_type;
		int config_methods = 0;
		for (int i = 0; i < items.size(); i++) {
			QString str = items.at(i);
			if (str.startsWith("name='"))
				name = str.section('\'', 1, -2);
			else if (str.startsWith("config_methods="))
				config_methods =
					str.section('=', 1).toInt(0, 0);
			else if (str.startsWith("pri_dev_type="))
				pri_dev_type = str.section('=', 1);
		}

		QStandardItem *item = find_addr(addr);
		if (item) {
			int type = item->data(peer_role_type).toInt();
			if (type == PEER_TYPE_P2P)
				return;
		}

		item = new QStandardItem(*default_icon, name);
		if (item) {
			item->setData(addr, peer_role_address);
			item->setData(config_methods,
				      peer_role_config_methods);
			item->setData(PEER_TYPE_P2P, peer_role_type);
			if (!pri_dev_type.isEmpty())
				item->setData(pri_dev_type,
					      peer_role_pri_dev_type);
			item->setData(items.join(QString("\n")),
				      peer_role_details);
			item->setToolTip(ItemType(PEER_TYPE_P2P));
			model.appendRow(item);
		}

		item = find_addr_type(addr,
				      PEER_TYPE_P2P_PERSISTENT_GROUP_CLIENT);
		if (item)
			item->setBackground(Qt::NoBrush);
	}

	if (text.startsWith(P2P_EVENT_GROUP_STARTED)) {
		/* P2P-GROUP-STARTED wlan0-p2p-0 GO ssid="DIRECT-3F"
		 * passphrase="YOyTkxID" go_dev_addr=02:40:61:c2:f3:b7
		 * [PERSISTENT] */
		QStringList items = text.split(' ');
		if (items.size() < 4)
			return;

		int pos = text.indexOf(" ssid=\"");
		if (pos < 0)
			return;
		QString ssid = text.mid(pos + 7);
		pos = ssid.indexOf(" passphrase=\"");
		if (pos < 0)
			pos = ssid.indexOf(" psk=");
		if (pos >= 0)
			ssid.truncate(pos);
		pos = ssid.lastIndexOf('"');
		if (pos >= 0)
			ssid.truncate(pos);

		QStandardItem *item = new QStandardItem(*group_icon, ssid);
		if (item) {
			item->setData(PEER_TYPE_P2P_GROUP, peer_role_type);
			item->setData(items[1], peer_role_ifname);
			QString details;
			if (items[2] == "GO") {
				details = tr("P2P GO for interface ") +
					items[1];
			} else {
				details = tr("P2P client for interface ") +
					items[1];
			}
			if (text.contains(" [PERSISTENT]"))
				details += "\nPersistent group";
			item->setData(details, peer_role_details);
			item->setToolTip(ItemType(PEER_TYPE_P2P_GROUP));
			model.appendRow(item);
		}
	}

	if (text.startsWith(P2P_EVENT_GROUP_REMOVED)) {
		/* P2P-GROUP-REMOVED wlan0-p2p-0 GO */
		QStringList items = text.split(' ');
		if (items.size() < 2)
			return;

		if (model.rowCount() == 0)
			return;

		QModelIndexList lst = model.match(model.index(0, 0),
						  peer_role_ifname, items[1]);
		for (int i = 0; i < lst.size(); i++)
			model.removeRow(lst[i].row());
		return;
	}

	if (text.startsWith(P2P_EVENT_PROV_DISC_SHOW_PIN)) {
		/* P2P-PROV-DISC-SHOW-PIN 02:40:61:c2:f3:b7 12345670 */
		QStringList items = text.split(' ');
		if (items.size() < 3)
			return;
		QString addr = items[1];
		QString pin = items[2];

		QStandardItem *item = find_addr_type(addr, PEER_TYPE_P2P);
		if (item == NULL)
			return;
		item->setData(SEL_METHOD_PIN_LOCAL_DISPLAY,
			      peer_role_selected_method);
		item->setData(pin, peer_role_selected_pin);
		QVariant var = item->data(peer_role_requested_method);
		if (var.isValid() &&
		    var.toInt() == SEL_METHOD_PIN_LOCAL_DISPLAY) {
			ctx_item = item;
			ctx_p2p_display_pin_pd();
		}
		return;
	}

	if (text.startsWith(P2P_EVENT_PROV_DISC_ENTER_PIN)) {
		/* P2P-PROV-DISC-ENTER-PIN 02:40:61:c2:f3:b7 */
		QStringList items = text.split(' ');
		if (items.size() < 2)
			return;
		QString addr = items[1];

		QStandardItem *item = find_addr_type(addr, PEER_TYPE_P2P);
		if (item == NULL)
			return;
		item->setData(SEL_METHOD_PIN_PEER_DISPLAY,
			      peer_role_selected_method);
		QVariant var = item->data(peer_role_requested_method);
		if (var.isValid() &&
		    var.toInt() == SEL_METHOD_PIN_PEER_DISPLAY) {
			ctx_item = item;
			ctx_p2p_connect();
		}
		return;
	}

	if (text.startsWith(P2P_EVENT_INVITATION_RECEIVED)) {
		/* P2P-INVITATION-RECEIVED sa=02:f0:bc:44:87:62 persistent=4 */
		QStringList items = text.split(' ');
		if (items.size() < 3)
			return;
		if (!items[1].startsWith("sa=") ||
		    !items[2].startsWith("persistent="))
			return;
		QString addr = items[1].mid(3);
		int id = items[2].mid(11).toInt();

		char cmd[100];
		char reply[100];
		size_t reply_len;

		snprintf(cmd, sizeof(cmd), "GET_NETWORK %d ssid", id);
		reply_len = sizeof(reply) - 1;
		if (wpagui->ctrlRequest(cmd, reply, &reply_len) < 0)
			return;
		reply[reply_len] = '\0';
		QString name;
		char *pos = strrchr(reply, '"');
		if (pos && reply[0] == '"') {
			*pos = '\0';
			name = reply + 1;
		} else
			name = reply;

		QStandardItem *item;
		item = find_addr_type(addr, PEER_TYPE_P2P_INVITATION);
		if (item)
			model.removeRow(item->row());

		item = new QStandardItem(*invitation_icon, name);
		if (!item)
			return;
		item->setData(PEER_TYPE_P2P_INVITATION, peer_role_type);
		item->setToolTip(ItemType(PEER_TYPE_P2P_INVITATION));
		item->setData(addr, peer_role_address);
		item->setData(id, peer_role_network_id);

		model.appendRow(item);

		enable_persistent(id);

		return;
	}

	if (text.startsWith(P2P_EVENT_INVITATION_RESULT)) {
		/* P2P-INVITATION-RESULT status=1 */
		/* TODO */
		return;
	}

	if (text.startsWith(WPS_EVENT_ER_AP_ADD)) {
		/*
		 * WPS-ER-AP-ADD 87654321-9abc-def0-1234-56789abc0002
		 * 02:11:22:33:44:55 pri_dev_type=6-0050F204-1 wps_state=1
		 * |Very friendly name|Company|Long description of the model|
		 * WAP|http://w1.fi/|http://w1.fi/hostapd/
		 */
		QStringList items = text.split(' ');
		if (items.size() < 5)
			return;
		QString uuid = items[1];
		QString addr = items[2];
		QString pri_dev_type = items[3].mid(13);
		int wps_state = items[4].mid(10).toInt();

		int pos = text.indexOf('|');
		if (pos < 0)
			return;
		items = text.mid(pos + 1).split('|');
		if (items.size() < 1)
			return;

		QStandardItem *item = find_uuid(uuid);
		if (item)
			return;

		item = new QStandardItem(*ap_icon, items[0]);
		if (item) {
			item->setData(uuid, peer_role_uuid);
			item->setData(addr, peer_role_address);
			int type = wps_state == 2 ? PEER_TYPE_WPS_ER_AP:
				PEER_TYPE_WPS_ER_AP_UNCONFIGURED;
			item->setData(type, peer_role_type);
			item->setToolTip(ItemType(type));
			item->setData(pri_dev_type, peer_role_pri_dev_type);
			item->setData(items.join(QString("\n")),
				      peer_role_details);
			model.appendRow(item);
		}

		return;
	}

	if (text.startsWith(WPS_EVENT_ER_AP_REMOVE)) {
		/* WPS-ER-AP-REMOVE 87654321-9abc-def0-1234-56789abc0002 */
		QStringList items = text.split(' ');
		if (items.size() < 2)
			return;
		if (model.rowCount() == 0)
			return;

		QModelIndexList lst = model.match(model.index(0, 0),
						  peer_role_uuid, items[1]);
		for (int i = 0; i < lst.size(); i++) {
			QStandardItem *item = model.itemFromIndex(lst[i]);
			if (item &&
			    (item->data(peer_role_type).toInt() ==
			     PEER_TYPE_WPS_ER_AP ||
			     item->data(peer_role_type).toInt() ==
			     PEER_TYPE_WPS_ER_AP_UNCONFIGURED))
				model.removeRow(lst[i].row());
		}
		return;
	}

	if (text.startsWith(WPS_EVENT_ER_ENROLLEE_ADD)) {
		/*
		 * WPS-ER-ENROLLEE-ADD 2b7093f1-d6fb-5108-adbb-bea66bb87333
		 * 02:66:a0:ee:17:27 M1=1 config_methods=0x14d dev_passwd_id=0
		 * pri_dev_type=1-0050F204-1
		 * |Wireless Client|Company|cmodel|123|12345|
		 */
		QStringList items = text.split(' ');
		if (items.size() < 3)
			return;
		QString uuid = items[1];
		QString addr = items[2];
		QString pri_dev_type = items[6].mid(13);
		int config_methods = -1;
		int dev_passwd_id = -1;

		for (int i = 3; i < items.size(); i++) {
			int pos = items[i].indexOf('=') + 1;
			if (pos < 1)
				continue;
			QString val = items[i].mid(pos);
			if (items[i].startsWith("config_methods=")) {
				config_methods = val.toInt(0, 0);
			} else if (items[i].startsWith("dev_passwd_id=")) {
				dev_passwd_id = val.toInt();
			}
		}

		int pos = text.indexOf('|');
		if (pos < 0)
			return;
		items = text.mid(pos + 1).split('|');
		if (items.size() < 1)
			return;
		QString name = items[0];
		if (name.length() == 0)
			name = addr;

		remove_enrollee_uuid(uuid);

		QStandardItem *item;
		item = new QStandardItem(*laptop_icon, name);
		if (item) {
			item->setData(uuid, peer_role_uuid);
			item->setData(addr, peer_role_address);
			item->setData(PEER_TYPE_WPS_ER_ENROLLEE,
				      peer_role_type);
			item->setToolTip(ItemType(PEER_TYPE_WPS_ER_ENROLLEE));
			item->setData(items.join(QString("\n")),
				      peer_role_details);
			item->setData(pri_dev_type, peer_role_pri_dev_type);
			if (config_methods >= 0)
				item->setData(config_methods,
					      peer_role_config_methods);
			if (dev_passwd_id >= 0)
				item->setData(dev_passwd_id,
					      peer_role_dev_passwd_id);
			model.appendRow(item);
		}

		return;
	}

	if (text.startsWith(WPS_EVENT_ER_ENROLLEE_REMOVE)) {
		/*
		 * WPS-ER-ENROLLEE-REMOVE 2b7093f1-d6fb-5108-adbb-bea66bb87333
		 * 02:66:a0:ee:17:27
		 */
		QStringList items = text.split(' ');
		if (items.size() < 2)
			return;
		remove_enrollee_uuid(items[1]);
		return;
	}

	if (text.startsWith(WPS_EVENT_ENROLLEE_SEEN)) {
		/* TODO: need to time out this somehow or remove on successful
		 * WPS run, etc. */
		/*
		 * WPS-ENROLLEE-SEEN 02:00:00:00:01:00
		 * 572cf82f-c957-5653-9b16-b5cfb298abf1 1-0050F204-1 0x80 4 1
		 * [Wireless Client]
		 * (MAC addr, UUID-E, pri dev type, config methods,
		 * dev passwd id, request type, [dev name])
		 */
		QStringList items = text.split(' ');
		if (items.size() < 7)
			return;
		QString addr = items[1];
		QString uuid = items[2];
		QString pri_dev_type = items[3];
		int config_methods = items[4].toInt(0, 0);
		int dev_passwd_id = items[5].toInt();
		QString name;

		QStandardItem *item = find_addr(addr);
		if (item) {
			int type = item->data(peer_role_type).toInt();
			if (type == PEER_TYPE_ASSOCIATED_STATION)
				return; /* already associated */
		}

		int pos = text.indexOf('[');
		if (pos >= 0) {
			int pos2 = text.lastIndexOf(']');
			if (pos2 >= pos) {
				QStringList items2 =
					text.mid(pos + 1, pos2 - pos - 1).
					split('|');
				name = items2[0];
			}
		}
		if (name.isEmpty())
			name = addr;

		item = find_uuid(uuid);
		if (item) {
			QVariant var = item->data(peer_role_config_methods);
			QVariant var2 = item->data(peer_role_dev_passwd_id);
			if ((var.isValid() && config_methods != var.toInt()) ||
			    (var2.isValid() && dev_passwd_id != var2.toInt()))
				remove_enrollee_uuid(uuid);
			else
				return;
		}

		item = new QStandardItem(*laptop_icon, name);
		if (item) {
			item->setData(uuid, peer_role_uuid);
			item->setData(addr, peer_role_address);
			item->setData(PEER_TYPE_WPS_ENROLLEE,
				      peer_role_type);
			item->setToolTip(ItemType(PEER_TYPE_WPS_ENROLLEE));
			item->setData(items.join(QString("\n")),
				      peer_role_details);
			item->setData(pri_dev_type, peer_role_pri_dev_type);
			item->setData(config_methods,
				      peer_role_config_methods);
			item->setData(dev_passwd_id, peer_role_dev_passwd_id);
			model.appendRow(item);
		}

		return;
	}

	if (text.startsWith(WPA_EVENT_BSS_ADDED)) {
		/* CTRL-EVENT-BSS-ADDED 34 00:11:22:33:44:55 */
		QStringList items = text.split(' ');
		if (items.size() < 2)
			return;
		char cmd[20];
		snprintf(cmd, sizeof(cmd), "BSS ID-%d", items[1].toInt());
		add_bss(cmd);
		return;
	}

	if (text.startsWith(WPA_EVENT_BSS_REMOVED)) {
		/* CTRL-EVENT-BSS-REMOVED 34 00:11:22:33:44:55 */
		QStringList items = text.split(' ');
		if (items.size() < 2)
			return;
		remove_bss(items[1].toInt());
		return;
	}
}


void Peers::ctx_p2p_connect()
{
	if (ctx_item == NULL)
		return;
	QString addr = ctx_item->data(peer_role_address).toString();
	QString arg;
	int config_methods =
		ctx_item->data(peer_role_config_methods).toInt();
	enum selected_method method = SEL_METHOD_NONE;
	QVariant var = ctx_item->data(peer_role_selected_method);
	if (var.isValid())
		method = (enum selected_method) var.toInt();
	if (method == SEL_METHOD_PIN_LOCAL_DISPLAY) {
		arg = ctx_item->data(peer_role_selected_pin).toString();
		char cmd[100];
		char reply[100];
		size_t reply_len;
		snprintf(cmd, sizeof(cmd), "P2P_CONNECT %s %s display",
			 addr.toLocal8Bit().constData(),
			 arg.toLocal8Bit().constData());
		reply_len = sizeof(reply) - 1;
		if (wpagui->ctrlRequest(cmd, reply, &reply_len) < 0) {
			QMessageBox msg;
			msg.setIcon(QMessageBox::Warning);
			msg.setText("Failed to initiate P2P connect.");
			msg.exec();
			return;
		}
		QMessageBox::information(this,
					 tr("PIN for ") + ctx_item->text(),
					 tr("Enter the following PIN on the\n"
					    "peer device: ") + arg);
	} else if (method == SEL_METHOD_PIN_PEER_DISPLAY) {
		StringQuery input(tr("PIN from peer display:"));
		input.setWindowTitle(tr("PIN for ") + ctx_item->text());
		if (input.exec() != QDialog::Accepted)
			return;
		arg = input.get_string();
	} else if (config_methods == 0x0080 /* PBC */) {
		arg = "pbc";
	} else {
		StringQuery input(tr("PIN:"));
		input.setWindowTitle(tr("PIN for ") + ctx_item->text());
		if (input.exec() != QDialog::Accepted)
			return;
		arg = input.get_string();
	}

	char cmd[100];
	char reply[100];
	size_t reply_len;
	snprintf(cmd, sizeof(cmd), "P2P_CONNECT %s %s",
		 addr.toLocal8Bit().constData(),
		 arg.toLocal8Bit().constData());
	reply_len = sizeof(reply) - 1;
	if (wpagui->ctrlRequest(cmd, reply, &reply_len) < 0) {
		QMessageBox msg;
		msg.setIcon(QMessageBox::Warning);
		msg.setText("Failed to initiate P2P connect.");
		msg.exec();
	}
}


void Peers::ctx_p2p_req_pin()
{
	if (ctx_item == NULL)
		return;
	QString addr = ctx_item->data(peer_role_address).toString();
	ctx_item->setData(SEL_METHOD_PIN_PEER_DISPLAY,
			  peer_role_requested_method);

	char cmd[100];
	char reply[100];
	size_t reply_len;
	snprintf(cmd, sizeof(cmd), "P2P_PROV_DISC %s display",
		 addr.toLocal8Bit().constData());
	reply_len = sizeof(reply) - 1;
	if (wpagui->ctrlRequest(cmd, reply, &reply_len) < 0) {
		QMessageBox msg;
		msg.setIcon(QMessageBox::Warning);
		msg.setText(tr("Failed to request PIN from peer."));
		msg.exec();
	}
}


void Peers::ctx_p2p_show_pin()
{
	if (ctx_item == NULL)
		return;
	QString addr = ctx_item->data(peer_role_address).toString();
	ctx_item->setData(SEL_METHOD_PIN_LOCAL_DISPLAY,
			  peer_role_requested_method);

	char cmd[100];
	char reply[100];
	size_t reply_len;
	snprintf(cmd, sizeof(cmd), "P2P_PROV_DISC %s keypad",
		 addr.toLocal8Bit().constData());
	reply_len = sizeof(reply) - 1;
	if (wpagui->ctrlRequest(cmd, reply, &reply_len) < 0) {
		QMessageBox msg;
		msg.setIcon(QMessageBox::Warning);
		msg.setText(tr("Failed to request peer to enter PIN."));
		msg.exec();
	}
}


void Peers::ctx_p2p_display_pin()
{
	if (ctx_item == NULL)
		return;
	QString addr = ctx_item->data(peer_role_address).toString();

	char cmd[100];
	char reply[100];
	size_t reply_len;
	snprintf(cmd, sizeof(cmd), "P2P_CONNECT %s pin",
		 addr.toLocal8Bit().constData());
	reply_len = sizeof(reply) - 1;
	if (wpagui->ctrlRequest(cmd, reply, &reply_len) < 0) {
		QMessageBox msg;
		msg.setIcon(QMessageBox::Warning);
		msg.setText("Failed to initiate P2P connect.");
		msg.exec();
		return;
	}
	reply[reply_len] = '\0';
	QMessageBox::information(this,
				 tr("PIN for ") + ctx_item->text(),
				 tr("Enter the following PIN on the\n"
				    "peer device: ") + reply);
}


void Peers::ctx_p2p_display_pin_pd()
{
	if (ctx_item == NULL)
		return;
	QString addr = ctx_item->data(peer_role_address).toString();
	QString arg = ctx_item->data(peer_role_selected_pin).toString();

	char cmd[100];
	char reply[100];
	size_t reply_len;
	snprintf(cmd, sizeof(cmd), "P2P_CONNECT %s %s display",
		 addr.toLocal8Bit().constData(),
		 arg.toLocal8Bit().constData());
	reply_len = sizeof(reply) - 1;
	if (wpagui->ctrlRequest(cmd, reply, &reply_len) < 0) {
		QMessageBox msg;
		msg.setIcon(QMessageBox::Warning);
		msg.setText("Failed to initiate P2P connect.");
		msg.exec();
		return;
	}
	reply[reply_len] = '\0';
	QMessageBox::information(this,
				 tr("PIN for ") + ctx_item->text(),
				 tr("Enter the following PIN on the\n"
				    "peer device: ") + arg);
}


void Peers::ctx_p2p_enter_pin()
{
	if (ctx_item == NULL)
		return;
	QString addr = ctx_item->data(peer_role_address).toString();
	QString arg;

	StringQuery input(tr("PIN from peer:"));
	input.setWindowTitle(tr("PIN for ") + ctx_item->text());
	if (input.exec() != QDialog::Accepted)
		return;
	arg = input.get_string();

	char cmd[100];
	char reply[100];
	size_t reply_len;
	snprintf(cmd, sizeof(cmd), "P2P_CONNECT %s %s keypad",
		 addr.toLocal8Bit().constData(),
		 arg.toLocal8Bit().constData());
	reply_len = sizeof(reply) - 1;
	if (wpagui->ctrlRequest(cmd, reply, &reply_len) < 0) {
		QMessageBox msg;
		msg.setIcon(QMessageBox::Warning);
		msg.setText("Failed to initiate P2P connect.");
		msg.exec();
	}
}


void Peers::ctx_p2p_remove_group()
{
	if (ctx_item == NULL)
		return;
	char cmd[100];
	char reply[100];
	size_t reply_len;
	snprintf(cmd, sizeof(cmd), "P2P_GROUP_REMOVE %s",
		 ctx_item->data(peer_role_ifname).toString().toLocal8Bit().
		 constData());
	reply_len = sizeof(reply) - 1;
	if (wpagui->ctrlRequest(cmd, reply, &reply_len) < 0) {
		QMessageBox msg;
		msg.setIcon(QMessageBox::Warning);
		msg.setText("Failed to remove P2P Group.");
		msg.exec();
	}
}


void Peers::closeEvent(QCloseEvent *)
{
	if (wpagui) {
		char reply[20];
		size_t replylen = sizeof(reply) - 1;
		wpagui->ctrlRequest("WPS_ER_STOP", reply, &replylen);
	}
}


void Peers::done(int r)
{
	QDialog::done(r);
	close();
}


void Peers::remove_enrollee_uuid(QString uuid)
{
	if (model.rowCount() == 0)
		return;

	QModelIndexList lst = model.match(model.index(0, 0),
					  peer_role_uuid, uuid);
	for (int i = 0; i < lst.size(); i++) {
		QStandardItem *item = model.itemFromIndex(lst[i]);
		if (item == NULL)
			continue;
		int type = item->data(peer_role_type).toInt();
		if (type == PEER_TYPE_WPS_ER_ENROLLEE ||
		    type == PEER_TYPE_WPS_ENROLLEE)
			model.removeRow(lst[i].row());
	}
}


void Peers::properties()
{
	if (ctx_item == NULL)
		return;

	QMessageBox msg(this);
	msg.setStandardButtons(QMessageBox::Ok);
	msg.setDefaultButton(QMessageBox::Ok);
	msg.setEscapeButton(QMessageBox::Ok);
	msg.setWindowTitle(tr("Peer Properties"));

	int type = ctx_item->data(peer_role_type).toInt();
	QString title = Peers::ItemType(type);

	msg.setText(title + QString("\n") + tr("Name: ") + ctx_item->text());

	QVariant var;
	QString info;

	var = ctx_item->data(peer_role_address);
	if (var.isValid())
		info += tr("Address: ") + var.toString() + QString("\n");

	var = ctx_item->data(peer_role_uuid);
	if (var.isValid())
		info += tr("UUID: ") + var.toString() + QString("\n");

	var = ctx_item->data(peer_role_pri_dev_type);
	if (var.isValid())
		info += tr("Primary Device Type: ") + var.toString() +
			QString("\n");

	var = ctx_item->data(peer_role_ssid);
	if (var.isValid())
		info += tr("SSID: ") + var.toString() + QString("\n");

	var = ctx_item->data(peer_role_config_methods);
	if (var.isValid()) {
		int methods = var.toInt();
		info += tr("Configuration Methods: ");
		if (methods & 0x0001)
			info += tr("[USBA]");
		if (methods & 0x0002)
			info += tr("[Ethernet]");
		if (methods & 0x0004)
			info += tr("[Label]");
		if (methods & 0x0008)
			info += tr("[Display]");
		if (methods & 0x0010)
			info += tr("[Ext. NFC Token]");
		if (methods & 0x0020)
			info += tr("[Int. NFC Token]");
		if (methods & 0x0040)
			info += tr("[NFC Interface]");
		if (methods & 0x0080)
			info += tr("[Push Button]");
		if (methods & 0x0100)
			info += tr("[Keypad]");
		info += "\n";
	}

	var = ctx_item->data(peer_role_selected_method);
	if (var.isValid()) {
		enum selected_method method =
			(enum selected_method) var.toInt();
		switch (method) {
		case SEL_METHOD_NONE:
			break;
		case SEL_METHOD_PIN_PEER_DISPLAY:
			info += tr("Selected Method: PIN on peer display\n");
			break;
		case SEL_METHOD_PIN_LOCAL_DISPLAY:
			info += tr("Selected Method: PIN on local display\n");
			break;
		}
	}

	var = ctx_item->data(peer_role_selected_pin);
	if (var.isValid()) {
		info += tr("PIN to enter on peer: ") + var.toString() + "\n";
	}

	var = ctx_item->data(peer_role_dev_passwd_id);
	if (var.isValid()) {
		info += tr("Device Password ID: ") + var.toString();
		switch (var.toInt()) {
		case 0:
			info += tr(" (Default PIN)");
			break;
		case 1:
			info += tr(" (User-specified PIN)");
			break;
		case 2:
			info += tr(" (Machine-specified PIN)");
			break;
		case 3:
			info += tr(" (Rekey)");
			break;
		case 4:
			info += tr(" (Push Button)");
			break;
		case 5:
			info += tr(" (Registrar-specified)");
			break;
		}
		info += "\n";
	}

	msg.setInformativeText(info);

	var = ctx_item->data(peer_role_details);
	if (var.isValid())
		msg.setDetailedText(var.toString());

	msg.exec();
}


void Peers::connect_pbc()
{
	if (ctx_item == NULL)
		return;

	char cmd[100];
	char reply[100];
	size_t reply_len;

	int peer_type = ctx_item->data(peer_role_type).toInt();
	if (peer_type == PEER_TYPE_WPS_ER_ENROLLEE) {
		snprintf(cmd, sizeof(cmd), "WPS_ER_PBC %s",
			 ctx_item->data(peer_role_uuid).toString().toLocal8Bit().
			 constData());
	} else if (peer_type == PEER_TYPE_P2P ||
		   peer_type == PEER_TYPE_P2P_CLIENT) {
		snprintf(cmd, sizeof(cmd), "P2P_CONNECT %s pbc",
			 ctx_item->data(peer_role_address).toString().
			 toLocal8Bit().constData());
	} else {
		snprintf(cmd, sizeof(cmd), "WPS_PBC");
	}
	reply_len = sizeof(reply) - 1;
	if (wpagui->ctrlRequest(cmd, reply, &reply_len) < 0) {
		QMessageBox msg;
		msg.setIcon(QMessageBox::Warning);
		msg.setText(tr("Failed to start WPS PBC."));
		msg.exec();
	}
}


void Peers::learn_ap_config()
{
	if (ctx_item == NULL)
		return;

	QString uuid = ctx_item->data(peer_role_uuid).toString();

	StringQuery input(tr("AP PIN:"));
	input.setWindowTitle(tr("AP PIN for ") + ctx_item->text());
	if (input.exec() != QDialog::Accepted)
		return;

	char cmd[100];
	char reply[100];
	size_t reply_len;

	snprintf(cmd, sizeof(cmd), "WPS_ER_LEARN %s %s",
		 uuid.toLocal8Bit().constData(),
		 input.get_string().toLocal8Bit().constData());
	reply_len = sizeof(reply) - 1;
	if (wpagui->ctrlRequest(cmd, reply, &reply_len) < 0) {
		QMessageBox msg;
		msg.setIcon(QMessageBox::Warning);
		msg.setText(tr("Failed to start learning AP configuration."));
		msg.exec();
	}
}


void Peers::ctx_hide_ap()
{
	hide_ap = true;

	if (model.rowCount() == 0)
		return;

	do {
		QModelIndexList lst;
		lst = model.match(model.index(0, 0),
				  peer_role_type, PEER_TYPE_AP);
		if (lst.size() == 0) {
			lst = model.match(model.index(0, 0),
					  peer_role_type, PEER_TYPE_AP_WPS);
			if (lst.size() == 0)
				break;
		}

		model.removeRow(lst[0].row());
	} while (1);
}


void Peers::ctx_show_ap()
{
	hide_ap = false;
	add_scan_results();
}


void Peers::ctx_p2p_show_passphrase()
{
	char reply[64];
	size_t reply_len;

	reply_len = sizeof(reply) - 1;
	if (wpagui->ctrlRequest("P2P_GET_PASSPHRASE", reply, &reply_len) < 0 ||
	    memcmp(reply, "FAIL", 4) == 0) {
		QMessageBox msg;
		msg.setIcon(QMessageBox::Warning);
		msg.setText("Failed to get P2P group passphrase.");
		msg.exec();
	} else {
		reply[reply_len] = '\0';
		QMessageBox::information(this, tr("Passphrase"),
					 tr("P2P group passphrase:\n") +
					 reply);
	}
}


void Peers::ctx_p2p_start_persistent()
{
	if (ctx_item == NULL)
		return;

	char cmd[100];
	char reply[100];
	size_t reply_len;

	snprintf(cmd, sizeof(cmd), "P2P_GROUP_ADD persistent=%d",
		 ctx_item->data(peer_role_network_id).toInt());
	if (wpagui->ctrlRequest(cmd, reply, &reply_len) < 0 ||
	    memcmp(reply, "FAIL", 4) == 0) {
		QMessageBox msg;
		msg.setIcon(QMessageBox::Warning);
		msg.setText(tr("Failed to start persistent P2P Group."));
		msg.exec();
	} else if (ctx_item->data(peer_role_type).toInt() ==
		   PEER_TYPE_P2P_INVITATION)
		model.removeRow(ctx_item->row());
}


void Peers::ctx_p2p_invite()
{
	if (ctx_item == NULL)
		return;

	char cmd[100];
	char reply[100];
	size_t reply_len;

	snprintf(cmd, sizeof(cmd), "P2P_INVITE persistent=%d",
		 ctx_item->data(peer_role_network_id).toInt());
	if (wpagui->ctrlRequest(cmd, reply, &reply_len) < 0 ||
	    memcmp(reply, "FAIL", 4) == 0) {
		QMessageBox msg;
		msg.setIcon(QMessageBox::Warning);
		msg.setText(tr("Failed to invite peer to start persistent "
			       "P2P Group."));
		msg.exec();
	}
}


void Peers::ctx_p2p_delete()
{
	if (ctx_item == NULL)
		return;
	model.removeRow(ctx_item->row());
}


void Peers::enable_persistent(int id)
{
	if (model.rowCount() == 0)
		return;

	QModelIndexList lst = model.match(model.index(0, 0),
					  peer_role_network_id, id);
	for (int i = 0; i < lst.size(); i++) {
		QStandardItem *item = model.itemFromIndex(lst[i]);
		int type = item->data(peer_role_type).toInt();
		if (type == PEER_TYPE_P2P_PERSISTENT_GROUP_GO ||
		    type == PEER_TYPE_P2P_PERSISTENT_GROUP_CLIENT)
			item->setBackground(Qt::NoBrush);
	}
}
