#include "peers.h"
-static const int peer_role_address = Qt::UserRole + 1;
-static const int peer_role_type = Qt::UserRole + 2;
-static const int peer_role_uuid = Qt::UserRole + 3;
+enum {
+ peer_role_address = Qt::UserRole + 1,
+ peer_role_type,
+ peer_role_uuid,
+ peer_role_details,
+ peer_role_pri_dev_type,
+ peer_role_ssid,
+ peer_role_config_methods,
+ peer_role_dev_passwd_id
+};
/*
* TODO:
* - add current AP info (e.g., from WPS) in station mode
- * - different icons to indicate peer type
*/
enum peer_type {
}
+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_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;
+ }
+ return title;
+}
+
+
void Peers::context_menu(const QPoint &pos)
{
QMenu *menu = new QMenu;
if (idx.isValid()) {
ctx_item = model.itemFromIndex(idx);
int type = ctx_item->data(peer_role_type).toInt();
- 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_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;
- }
- menu->addAction(title)->setEnabled(false);
+ menu->addAction(Peers::ItemType(type))->setEnabled(false);
menu->addSeparator();
- if (type == PEER_TYPE_ASSOCIATED_STATION ||
- type == PEER_TYPE_AP_WPS ||
- type == PEER_TYPE_WPS_PIN_NEEDED ||
- type == PEER_TYPE_WPS_ER_ENROLLEE) {
- /* TODO: only for peers that are requesting WPS PIN
- * method */
- menu->addAction(QString("Enter WPS PIN"), this,
+ int config_methods = -1;
+ QVariant var = ctx_item->data(peer_role_config_methods);
+ if (var.isValid())
+ config_methods = 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) &&
+ (config_methods == -1 || (config_methods & 0x010c))) {
+ menu->addAction(tr("Enter WPS PIN"), this,
SLOT(enter_pin()));
}
+
+ 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) &&
+ config_methods >= 0 && (config_methods & 0x0080)) {
+ menu->addAction(tr("Enroll (PBC)"), this,
+ SLOT(connect_pbc()));
+ }
+
+ menu->addAction(tr("Properties"), this, SLOT(properties()));
} else {
ctx_item = NULL;
menu->addAction(QString("Refresh"), this, SLOT(ctx_refresh()));
item->setData(lines[0], peer_role_address);
item->setData(PEER_TYPE_ASSOCIATED_STATION,
peer_role_type);
- item->setToolTip(info);
+ item->setData(info, peer_role_details);
+ item->setToolTip(ItemType(PEER_TYPE_ASSOCIATED_STATION));
model.appendRow(item);
}
}
if (bss.isEmpty() || bss.startsWith("FAIL"))
break;
- QString ssid, bssid, flags, wps_name;
+ QString ssid, bssid, flags, wps_name, pri_dev_type;
QStringList lines = bss.split(QRegExp("\\n"));
for (QStringList::Iterator it = lines.begin();
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;
QStandardItem *item = new QStandardItem(*ap_icon, name);
if (item) {
item->setData(bssid, peer_role_address);
+ int type;
if (flags.contains("[WPS"))
- item->setData(PEER_TYPE_AP_WPS,
- peer_role_type);
+ type = PEER_TYPE_AP_WPS;
else
- item->setData(PEER_TYPE_AP, peer_role_type);
+ 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] += "..";
}
}
- item->setToolTip(lines.join("\n"));
+ 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);
}
}
item->setData(addr, peer_role_address);
item->setData(PEER_TYPE_WPS_PIN_NEEDED,
peer_role_type);
- item->setToolTip(items.join(QString("\n")));
+ 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;
return;
QString uuid = items[1];
QString addr = items[2];
- QString pri_dev_type = items[3];
+ QString pri_dev_type = items[3].mid(13);
int wps_state = items[4].mid(10).toInt();
int pos = text.indexOf('|');
if (item) {
item->setData(uuid, peer_role_uuid);
item->setData(addr, peer_role_address);
- item->setData(wps_state == 2 ? PEER_TYPE_WPS_ER_AP:
- PEER_TYPE_WPS_ER_AP_UNCONFIGURED,
- peer_role_type);
- item->setToolTip(addr + QString("\n") +
- pri_dev_type + QString("\n") +
- items.join(QString("\n")));
+ 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;
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)
item->setData(addr, peer_role_address);
item->setData(PEER_TYPE_WPS_ER_ENROLLEE,
peer_role_type);
- item->setToolTip(items.join(QString("\n")));
+ 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);
}
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_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 {
+ 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("Failed to start WPS PBC.");
+ msg.exec();
+ }
+}