/*
 * 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::WFlags)
	: 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.toAscii().constData(),
			 input.get_string().toAscii().constData(),
			 addr.toAscii().constData());
	} else {
		snprintf(cmd, sizeof(cmd), "WPS_PIN %s %s",
			 addr.toAscii().constData(),
			 input.get_string().toAscii().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.toAscii().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.toAscii().constData(),
			 arg.toAscii().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.toAscii().constData(),
		 arg.toAscii().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.toAscii().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.toAscii().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.toAscii().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.toAscii().constData(),
		 arg.toAscii().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.toAscii().constData(),
		 arg.toAscii().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().toAscii().
		 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().toAscii().
			 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().
			 toAscii().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.toAscii().constData(),
		 input.get_string().toAscii().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);
	}
}
