2 * wpa_gui - Peers class
3 * Copyright (c) 2009-2010, Atheros Communications
5 * This software may be distributed under the terms of the BSD license.
6 * See README for more details.
10 #include <QImageReader>
11 #include <QMessageBox>
13 #include "common/wpa_ctrl.h"
15 #include "stringquery.h"
20 peer_role_address = Qt::UserRole + 1,
25 peer_role_pri_dev_type,
27 peer_role_config_methods,
28 peer_role_dev_passwd_id,
30 peer_role_selected_method,
31 peer_role_selected_pin,
32 peer_role_requested_method,
36 enum selected_method {
38 SEL_METHOD_PIN_PEER_DISPLAY,
39 SEL_METHOD_PIN_LOCAL_DISPLAY
44 * - add current AP info (e.g., from WPS) in station mode
48 PEER_TYPE_ASSOCIATED_STATION,
51 PEER_TYPE_WPS_PIN_NEEDED,
55 PEER_TYPE_P2P_PERSISTENT_GROUP_GO,
56 PEER_TYPE_P2P_PERSISTENT_GROUP_CLIENT,
57 PEER_TYPE_P2P_INVITATION,
59 PEER_TYPE_WPS_ER_AP_UNCONFIGURED,
60 PEER_TYPE_WPS_ER_ENROLLEE,
61 PEER_TYPE_WPS_ENROLLEE
65 Peers::Peers(QWidget *parent, const char *, bool, Qt::WindowFlags)
70 if (QImageReader::supportedImageFormats().contains(QByteArray("svg")))
72 default_icon = new QIcon(":/icons/wpa_gui.svg");
73 ap_icon = new QIcon(":/icons/ap.svg");
74 laptop_icon = new QIcon(":/icons/laptop.svg");
75 group_icon = new QIcon(":/icons/group.svg");
76 invitation_icon = new QIcon(":/icons/invitation.svg");
78 default_icon = new QIcon(":/icons/wpa_gui.png");
79 ap_icon = new QIcon(":/icons/ap.png");
80 laptop_icon = new QIcon(":/icons/laptop.png");
81 group_icon = new QIcon(":/icons/group.png");
82 invitation_icon = new QIcon(":/icons/invitation.png");
85 peers->setModel(&model);
86 peers->setResizeMode(QListView::Adjust);
87 peers->setDragEnabled(false);
88 peers->setSelectionMode(QAbstractItemView::NoSelection);
90 peers->setContextMenuPolicy(Qt::CustomContextMenu);
91 connect(peers, SIGNAL(customContextMenuRequested(const QPoint &)),
92 this, SLOT(context_menu(const QPoint &)));
99 void Peers::setWpaGui(WpaGui *_wpagui)
112 delete invitation_icon;
116 void Peers::languageChange()
122 QString Peers::ItemType(int type)
126 case PEER_TYPE_ASSOCIATED_STATION:
127 title = tr("Associated station");
132 case PEER_TYPE_AP_WPS:
133 title = tr("WPS AP");
135 case PEER_TYPE_WPS_PIN_NEEDED:
136 title = tr("WPS PIN needed");
139 title = tr("P2P Device");
141 case PEER_TYPE_P2P_CLIENT:
142 title = tr("P2P Device (group client)");
144 case PEER_TYPE_P2P_GROUP:
145 title = tr("P2P Group");
147 case PEER_TYPE_P2P_PERSISTENT_GROUP_GO:
148 title = tr("P2P Persistent Group (GO)");
150 case PEER_TYPE_P2P_PERSISTENT_GROUP_CLIENT:
151 title = tr("P2P Persistent Group (client)");
153 case PEER_TYPE_P2P_INVITATION:
154 title = tr("P2P Invitation");
156 case PEER_TYPE_WPS_ER_AP:
157 title = tr("ER: WPS AP");
159 case PEER_TYPE_WPS_ER_AP_UNCONFIGURED:
160 title = tr("ER: WPS AP (Unconfigured)");
162 case PEER_TYPE_WPS_ER_ENROLLEE:
163 title = tr("ER: WPS Enrollee");
165 case PEER_TYPE_WPS_ENROLLEE:
166 title = tr("WPS Enrollee");
173 void Peers::context_menu(const QPoint &pos)
175 QMenu *menu = new QMenu;
179 QModelIndex idx = peers->indexAt(pos);
181 ctx_item = model.itemFromIndex(idx);
182 int type = ctx_item->data(peer_role_type).toInt();
183 menu->addAction(Peers::ItemType(type))->setEnabled(false);
184 menu->addSeparator();
186 int config_methods = -1;
187 QVariant var = ctx_item->data(peer_role_config_methods);
189 config_methods = var.toInt();
191 enum selected_method method = SEL_METHOD_NONE;
192 var = ctx_item->data(peer_role_selected_method);
194 method = (enum selected_method) var.toInt();
196 if ((type == PEER_TYPE_ASSOCIATED_STATION ||
197 type == PEER_TYPE_AP_WPS ||
198 type == PEER_TYPE_WPS_PIN_NEEDED ||
199 type == PEER_TYPE_WPS_ER_ENROLLEE ||
200 type == PEER_TYPE_WPS_ENROLLEE) &&
201 (config_methods == -1 || (config_methods & 0x010c))) {
202 menu->addAction(tr("Enter WPS PIN"), this,
206 if (type == PEER_TYPE_P2P || type == PEER_TYPE_P2P_CLIENT) {
207 menu->addAction(tr("P2P Connect"), this,
208 SLOT(ctx_p2p_connect()));
209 if (method == SEL_METHOD_NONE &&
210 config_methods > -1 &&
211 config_methods & 0x0080 /* PBC */ &&
212 config_methods != 0x0080)
213 menu->addAction(tr("P2P Connect (PBC)"), this,
214 SLOT(connect_pbc()));
215 if (method == SEL_METHOD_NONE) {
216 menu->addAction(tr("P2P Request PIN"), this,
217 SLOT(ctx_p2p_req_pin()));
218 menu->addAction(tr("P2P Show PIN"), this,
219 SLOT(ctx_p2p_show_pin()));
222 if (config_methods > -1 && (config_methods & 0x0100)) {
223 /* Peer has Keypad */
224 menu->addAction(tr("P2P Display PIN"), this,
225 SLOT(ctx_p2p_display_pin()));
228 if (config_methods > -1 && (config_methods & 0x000c)) {
229 /* Peer has Label or Display */
230 menu->addAction(tr("P2P Enter PIN"), this,
231 SLOT(ctx_p2p_enter_pin()));
235 if (type == PEER_TYPE_P2P_GROUP) {
236 menu->addAction(tr("Show passphrase"), this,
237 SLOT(ctx_p2p_show_passphrase()));
238 menu->addAction(tr("Remove P2P Group"), this,
239 SLOT(ctx_p2p_remove_group()));
242 if (type == PEER_TYPE_P2P_PERSISTENT_GROUP_GO ||
243 type == PEER_TYPE_P2P_PERSISTENT_GROUP_CLIENT ||
244 type == PEER_TYPE_P2P_INVITATION) {
245 menu->addAction(tr("Start group"), this,
246 SLOT(ctx_p2p_start_persistent()));
249 if (type == PEER_TYPE_P2P_PERSISTENT_GROUP_GO ||
250 type == PEER_TYPE_P2P_PERSISTENT_GROUP_CLIENT) {
251 menu->addAction(tr("Invite"), this,
252 SLOT(ctx_p2p_invite()));
255 if (type == PEER_TYPE_P2P_INVITATION) {
256 menu->addAction(tr("Ignore"), this,
257 SLOT(ctx_p2p_delete()));
260 if (type == PEER_TYPE_AP_WPS) {
261 menu->addAction(tr("Connect (PBC)"), this,
262 SLOT(connect_pbc()));
265 if ((type == PEER_TYPE_ASSOCIATED_STATION ||
266 type == PEER_TYPE_WPS_ER_ENROLLEE ||
267 type == PEER_TYPE_WPS_ENROLLEE) &&
268 config_methods >= 0 && (config_methods & 0x0080)) {
269 menu->addAction(tr("Enroll (PBC)"), this,
270 SLOT(connect_pbc()));
273 if (type == PEER_TYPE_WPS_ER_AP) {
274 menu->addAction(tr("Learn Configuration"), this,
275 SLOT(learn_ap_config()));
278 menu->addAction(tr("Properties"), this, SLOT(properties()));
281 menu->addAction(QString(tr("Refresh")), this,
282 SLOT(ctx_refresh()));
283 menu->addAction(tr("Start P2P discovery"), this,
284 SLOT(ctx_p2p_start()));
285 menu->addAction(tr("Stop P2P discovery"), this,
286 SLOT(ctx_p2p_stop()));
287 menu->addAction(tr("P2P listen only"), this,
288 SLOT(ctx_p2p_listen()));
289 menu->addAction(tr("Start P2P group"), this,
290 SLOT(ctx_p2p_start_group()));
292 menu->addAction(tr("Show AP entries"), this,
293 SLOT(ctx_show_ap()));
295 menu->addAction(tr("Hide AP entries"), this,
296 SLOT(ctx_hide_ap()));
299 menu->exec(peers->mapToGlobal(pos));
303 void Peers::enter_pin()
305 if (ctx_item == NULL)
308 int peer_type = ctx_item->data(peer_role_type).toInt();
311 addr = ctx_item->data(peer_role_address).toString();
312 if (peer_type == PEER_TYPE_WPS_ER_ENROLLEE)
313 uuid = ctx_item->data(peer_role_uuid).toString();
315 StringQuery input(tr("PIN:"));
316 input.setWindowTitle(tr("PIN for ") + ctx_item->text());
317 if (input.exec() != QDialog::Accepted)
324 if (peer_type == PEER_TYPE_WPS_ER_ENROLLEE) {
325 snprintf(cmd, sizeof(cmd), "WPS_ER_PIN %s %s %s",
326 uuid.toLocal8Bit().constData(),
327 input.get_string().toLocal8Bit().constData(),
328 addr.toLocal8Bit().constData());
330 snprintf(cmd, sizeof(cmd), "WPS_PIN %s %s",
331 addr.toLocal8Bit().constData(),
332 input.get_string().toLocal8Bit().constData());
334 reply_len = sizeof(reply) - 1;
335 if (wpagui->ctrlRequest(cmd, reply, &reply_len) < 0) {
337 msg.setIcon(QMessageBox::Warning);
338 msg.setText(tr("Failed to set the WPS PIN."));
344 void Peers::ctx_refresh()
350 void Peers::ctx_p2p_start()
354 reply_len = sizeof(reply) - 1;
355 if (wpagui->ctrlRequest("P2P_FIND", reply, &reply_len) < 0 ||
356 memcmp(reply, "FAIL", 4) == 0) {
358 msg.setIcon(QMessageBox::Warning);
359 msg.setText("Failed to start P2P discovery.");
365 void Peers::ctx_p2p_stop()
369 reply_len = sizeof(reply) - 1;
370 wpagui->ctrlRequest("P2P_STOP_FIND", reply, &reply_len);
374 void Peers::ctx_p2p_listen()
378 reply_len = sizeof(reply) - 1;
379 if (wpagui->ctrlRequest("P2P_LISTEN 3600", reply, &reply_len) < 0 ||
380 memcmp(reply, "FAIL", 4) == 0) {
382 msg.setIcon(QMessageBox::Warning);
383 msg.setText("Failed to start P2P listen.");
389 void Peers::ctx_p2p_start_group()
393 reply_len = sizeof(reply) - 1;
394 if (wpagui->ctrlRequest("P2P_GROUP_ADD", reply, &reply_len) < 0 ||
395 memcmp(reply, "FAIL", 4) == 0) {
397 msg.setIcon(QMessageBox::Warning);
398 msg.setText("Failed to start P2P group.");
404 void Peers::add_station(QString info)
406 QStringList lines = info.split(QRegExp("\\n"));
409 for (QStringList::Iterator it = lines.begin();
410 it != lines.end(); it++) {
411 int pos = (*it).indexOf('=') + 1;
415 if ((*it).startsWith("wpsDeviceName="))
416 name = (*it).mid(pos);
417 else if ((*it).startsWith("p2p_device_name="))
418 name = (*it).mid(pos);
424 QStandardItem *item = new QStandardItem(*laptop_icon, name);
426 /* Remove WPS enrollee entry if one is still pending */
427 if (model.rowCount() > 0) {
428 QModelIndexList lst = model.match(model.index(0, 0),
431 for (int i = 0; i < lst.size(); i++) {
433 item = model.itemFromIndex(lst[i]);
436 int type = item->data(peer_role_type).toInt();
437 if (type == PEER_TYPE_WPS_ENROLLEE) {
438 model.removeRow(lst[i].row());
444 item->setData(lines[0], peer_role_address);
445 item->setData(PEER_TYPE_ASSOCIATED_STATION,
447 item->setData(info, peer_role_details);
448 item->setToolTip(ItemType(PEER_TYPE_ASSOCIATED_STATION));
449 model.appendRow(item);
454 void Peers::add_stations()
461 reply_len = sizeof(reply) - 1;
462 if (wpagui->ctrlRequest("STA-FIRST", reply, &reply_len) < 0)
466 reply[reply_len] = '\0';
469 while (*txt != '\0' && *txt != '\n')
472 if (strncmp(reply, "FAIL", 4) == 0 ||
473 strncmp(reply, "UNKNOWN", 7) == 0)
478 reply_len = sizeof(reply) - 1;
479 snprintf(cmd, sizeof(cmd), "STA-NEXT %s", reply);
480 res = wpagui->ctrlRequest(cmd, reply, &reply_len);
485 void Peers::add_single_station(const char *addr)
491 reply_len = sizeof(reply) - 1;
492 snprintf(cmd, sizeof(cmd), "STA %s", addr);
493 if (wpagui->ctrlRequest(cmd, reply, &reply_len) < 0)
496 reply[reply_len] = '\0';
499 while (*txt != '\0' && *txt != '\n')
502 if (strncmp(reply, "FAIL", 4) == 0 ||
503 strncmp(reply, "UNKNOWN", 7) == 0)
510 void Peers::add_p2p_group_client(QStandardItem * /*parent*/, QString params)
513 * dev=02:b5:64:63:30:63 iface=02:b5:64:63:30:63 dev_capab=0x0
514 * dev_type=1-0050f204-1 dev_name='Wireless Client'
515 * config_methods=0x8c
519 params.split(QRegExp(" (?=[^']*('[^']*'[^']*)*$)"));
522 int config_methods = 0;
525 for (int i = 0; i < items.size(); i++) {
526 QString str = items.at(i);
527 int pos = str.indexOf('=') + 1;
528 if (str.startsWith("dev_name='"))
529 name = str.section('\'', 1, -2);
530 else if (str.startsWith("config_methods="))
532 str.section('=', 1).toInt(0, 0);
533 else if (str.startsWith("dev="))
535 else if (str.startsWith("dev_type=") && dev_type.isEmpty())
536 dev_type = str.mid(pos);
539 QStandardItem *item = find_addr(addr);
543 item = new QStandardItem(*default_icon, name);
545 /* TODO: indicate somehow the relationship to the group owner
547 item->setData(addr, peer_role_address);
548 item->setData(config_methods, peer_role_config_methods);
549 item->setData(PEER_TYPE_P2P_CLIENT, peer_role_type);
550 if (!dev_type.isEmpty())
551 item->setData(dev_type, peer_role_pri_dev_type);
552 item->setData(items.join(QString("\n")), peer_role_details);
553 item->setToolTip(ItemType(PEER_TYPE_P2P_CLIENT));
554 model.appendRow(item);
559 void Peers::remove_bss(int id)
561 if (model.rowCount() == 0)
564 QModelIndexList lst = model.match(model.index(0, 0), peer_role_bss_id,
568 model.removeRow(lst[0].row());
572 bool Peers::add_bss(const char *cmd)
580 reply_len = sizeof(reply) - 1;
581 if (wpagui->ctrlRequest(cmd, reply, &reply_len) < 0)
583 reply[reply_len] = '\0';
586 if (bss.isEmpty() || bss.startsWith("FAIL"))
589 QString ssid, bssid, flags, wps_name, pri_dev_type;
592 QStringList lines = bss.split(QRegExp("\\n"));
593 for (QStringList::Iterator it = lines.begin();
594 it != lines.end(); it++) {
595 int pos = (*it).indexOf('=') + 1;
599 if ((*it).startsWith("bssid="))
600 bssid = (*it).mid(pos);
601 else if ((*it).startsWith("id="))
602 id = (*it).mid(pos).toInt();
603 else if ((*it).startsWith("flags="))
604 flags = (*it).mid(pos);
605 else if ((*it).startsWith("ssid="))
606 ssid = (*it).mid(pos);
607 else if ((*it).startsWith("wps_device_name="))
608 wps_name = (*it).mid(pos);
609 else if ((*it).startsWith("wps_primary_device_type="))
610 pri_dev_type = (*it).mid(pos);
613 QString name = wps_name;
615 name = ssid + "\n" + bssid;
617 QStandardItem *item = new QStandardItem(*ap_icon, name);
619 item->setData(bssid, peer_role_address);
621 item->setData(id, peer_role_bss_id);
623 if (flags.contains("[WPS"))
624 type = PEER_TYPE_AP_WPS;
627 item->setData(type, peer_role_type);
629 for (int i = 0; i < lines.size(); i++) {
630 if (lines[i].length() > 60) {
631 lines[i].remove(60, lines[i].length());
635 item->setToolTip(ItemType(type));
636 item->setData(lines.join("\n"), peer_role_details);
637 if (!pri_dev_type.isEmpty())
638 item->setData(pri_dev_type,
639 peer_role_pri_dev_type);
641 item->setData(ssid, peer_role_ssid);
642 model.appendRow(item);
644 lines = bss.split(QRegExp("\\n"));
645 for (QStringList::Iterator it = lines.begin();
646 it != lines.end(); it++) {
647 if ((*it).startsWith("p2p_group_client:"))
648 add_p2p_group_client(item,
657 void Peers::add_scan_results()
664 snprintf(cmd, sizeof(cmd), "BSS %d", index++);
674 void Peers::add_persistent(int id, const char *ssid, const char *bssid)
681 snprintf(cmd, sizeof(cmd), "GET_NETWORK %d mode", id);
682 if (wpagui->ctrlRequest(cmd, reply, &reply_len) < 0)
684 reply[reply_len] = '\0';
688 name = '[' + name + ']';
690 QStandardItem *item = new QStandardItem(*group_icon, name);
696 type = PEER_TYPE_P2P_PERSISTENT_GROUP_GO;
698 type = PEER_TYPE_P2P_PERSISTENT_GROUP_CLIENT;
699 item->setData(type, peer_role_type);
700 item->setToolTip(ItemType(type));
701 item->setData(ssid, peer_role_ssid);
702 if (bssid && strcmp(bssid, "any") == 0)
705 item->setData(bssid, peer_role_address);
706 item->setData(id, peer_role_network_id);
707 item->setBackground(Qt::BDiagPattern);
709 model.appendRow(item);
713 void Peers::add_persistent_groups()
715 char buf[2048], *start, *end, *id, *ssid, *bssid, *flags;
718 len = sizeof(buf) - 1;
719 if (wpagui->ctrlRequest("LIST_NETWORKS", buf, &len) < 0)
723 start = strchr(buf, '\n');
730 end = strchr(start, '\n');
734 while (end[0] && end[1])
740 ssid = strchr(id, '\t');
744 bssid = strchr(ssid, '\t');
748 flags = strchr(bssid, '\t');
753 if (strstr(flags, "[DISABLED][P2P-PERSISTENT]"))
754 add_persistent(atoi(id), ssid, bssid);
763 void Peers::update_peers()
770 size_t replylen = sizeof(reply) - 1;
771 wpagui->ctrlRequest("WPS_ER_START", reply, &replylen);
775 add_persistent_groups();
779 QStandardItem * Peers::find_addr(QString addr)
781 if (model.rowCount() == 0)
784 QModelIndexList lst = model.match(model.index(0, 0), peer_role_address,
788 return model.itemFromIndex(lst[0]);
792 QStandardItem * Peers::find_addr_type(QString addr, int type)
794 if (model.rowCount() == 0)
797 QModelIndexList lst = model.match(model.index(0, 0), peer_role_address,
799 for (int i = 0; i < lst.size(); i++) {
800 QStandardItem *item = model.itemFromIndex(lst[i]);
801 if (item->data(peer_role_type).toInt() == type)
808 QStandardItem * Peers::find_uuid(QString uuid)
810 if (model.rowCount() == 0)
813 QModelIndexList lst = model.match(model.index(0, 0), peer_role_uuid,
817 return model.itemFromIndex(lst[0]);
821 void Peers::event_notify(WpaMsg msg)
823 QString text = msg.getMsg();
825 if (text.startsWith(WPS_EVENT_PIN_NEEDED)) {
827 * WPS-PIN-NEEDED 5a02a5fa-9199-5e7c-bc46-e183d3cb32f7
829 * [Wireless Client|Company|cmodel|123|12345|1-0050F204-1]
831 QStringList items = text.split(' ');
832 QString uuid = items[1];
833 QString addr = items[2];
836 QStandardItem *item = find_addr(addr);
840 int pos = text.indexOf('[');
842 int pos2 = text.lastIndexOf(']');
844 items = text.mid(pos + 1, pos2 - pos - 1).
851 item = new QStandardItem(*laptop_icon, name);
853 item->setData(addr, peer_role_address);
854 item->setData(PEER_TYPE_WPS_PIN_NEEDED,
856 item->setToolTip(ItemType(PEER_TYPE_WPS_PIN_NEEDED));
857 item->setData(items.join("\n"), peer_role_details);
858 item->setData(items[5], peer_role_pri_dev_type);
859 model.appendRow(item);
864 if (text.startsWith(AP_STA_CONNECTED)) {
865 /* AP-STA-CONNECTED 02:2a:c4:18:5b:f3 */
866 QStringList items = text.split(' ');
867 QString addr = items[1];
868 QStandardItem *item = find_addr(addr);
869 if (item == NULL || item->data(peer_role_type).toInt() !=
870 PEER_TYPE_ASSOCIATED_STATION)
871 add_single_station(addr.toLocal8Bit().constData());
875 if (text.startsWith(AP_STA_DISCONNECTED)) {
876 /* AP-STA-DISCONNECTED 02:2a:c4:18:5b:f3 */
877 QStringList items = text.split(' ');
878 QString addr = items[1];
880 if (model.rowCount() == 0)
883 QModelIndexList lst = model.match(model.index(0, 0),
884 peer_role_address, addr, -1);
885 for (int i = 0; i < lst.size(); i++) {
886 QStandardItem *item = model.itemFromIndex(lst[i]);
887 if (item && item->data(peer_role_type).toInt() ==
888 PEER_TYPE_ASSOCIATED_STATION) {
889 model.removeRow(lst[i].row());
896 if (text.startsWith(P2P_EVENT_DEVICE_FOUND)) {
898 * P2P-DEVICE-FOUND 02:b5:64:63:30:63
899 * p2p_dev_addr=02:b5:64:63:30:63 pri_dev_type=1-0050f204-1
900 * name='Wireless Client' config_methods=0x84 dev_capab=0x21
904 text.split(QRegExp(" (?=[^']*('[^']*'[^']*)*$)"));
905 QString addr = items[1];
907 QString pri_dev_type;
908 int config_methods = 0;
909 for (int i = 0; i < items.size(); i++) {
910 QString str = items.at(i);
911 if (str.startsWith("name='"))
912 name = str.section('\'', 1, -2);
913 else if (str.startsWith("config_methods="))
915 str.section('=', 1).toInt(0, 0);
916 else if (str.startsWith("pri_dev_type="))
917 pri_dev_type = str.section('=', 1);
920 QStandardItem *item = find_addr(addr);
922 int type = item->data(peer_role_type).toInt();
923 if (type == PEER_TYPE_P2P)
927 item = new QStandardItem(*default_icon, name);
929 item->setData(addr, peer_role_address);
930 item->setData(config_methods,
931 peer_role_config_methods);
932 item->setData(PEER_TYPE_P2P, peer_role_type);
933 if (!pri_dev_type.isEmpty())
934 item->setData(pri_dev_type,
935 peer_role_pri_dev_type);
936 item->setData(items.join(QString("\n")),
938 item->setToolTip(ItemType(PEER_TYPE_P2P));
939 model.appendRow(item);
942 item = find_addr_type(addr,
943 PEER_TYPE_P2P_PERSISTENT_GROUP_CLIENT);
945 item->setBackground(Qt::NoBrush);
948 if (text.startsWith(P2P_EVENT_GROUP_STARTED)) {
949 /* P2P-GROUP-STARTED wlan0-p2p-0 GO ssid="DIRECT-3F"
950 * passphrase="YOyTkxID" go_dev_addr=02:40:61:c2:f3:b7
952 QStringList items = text.split(' ');
953 if (items.size() < 4)
956 int pos = text.indexOf(" ssid=\"");
959 QString ssid = text.mid(pos + 7);
960 pos = ssid.indexOf(" passphrase=\"");
962 pos = ssid.indexOf(" psk=");
965 pos = ssid.lastIndexOf('"');
969 QStandardItem *item = new QStandardItem(*group_icon, ssid);
971 item->setData(PEER_TYPE_P2P_GROUP, peer_role_type);
972 item->setData(items[1], peer_role_ifname);
974 if (items[2] == "GO") {
975 details = tr("P2P GO for interface ") +
978 details = tr("P2P client for interface ") +
981 if (text.contains(" [PERSISTENT]"))
982 details += "\nPersistent group";
983 item->setData(details, peer_role_details);
984 item->setToolTip(ItemType(PEER_TYPE_P2P_GROUP));
985 model.appendRow(item);
989 if (text.startsWith(P2P_EVENT_GROUP_REMOVED)) {
990 /* P2P-GROUP-REMOVED wlan0-p2p-0 GO */
991 QStringList items = text.split(' ');
992 if (items.size() < 2)
995 if (model.rowCount() == 0)
998 QModelIndexList lst = model.match(model.index(0, 0),
999 peer_role_ifname, items[1]);
1000 for (int i = 0; i < lst.size(); i++)
1001 model.removeRow(lst[i].row());
1005 if (text.startsWith(P2P_EVENT_PROV_DISC_SHOW_PIN)) {
1006 /* P2P-PROV-DISC-SHOW-PIN 02:40:61:c2:f3:b7 12345670 */
1007 QStringList items = text.split(' ');
1008 if (items.size() < 3)
1010 QString addr = items[1];
1011 QString pin = items[2];
1013 QStandardItem *item = find_addr_type(addr, PEER_TYPE_P2P);
1016 item->setData(SEL_METHOD_PIN_LOCAL_DISPLAY,
1017 peer_role_selected_method);
1018 item->setData(pin, peer_role_selected_pin);
1019 QVariant var = item->data(peer_role_requested_method);
1020 if (var.isValid() &&
1021 var.toInt() == SEL_METHOD_PIN_LOCAL_DISPLAY) {
1023 ctx_p2p_display_pin_pd();
1028 if (text.startsWith(P2P_EVENT_PROV_DISC_ENTER_PIN)) {
1029 /* P2P-PROV-DISC-ENTER-PIN 02:40:61:c2:f3:b7 */
1030 QStringList items = text.split(' ');
1031 if (items.size() < 2)
1033 QString addr = items[1];
1035 QStandardItem *item = find_addr_type(addr, PEER_TYPE_P2P);
1038 item->setData(SEL_METHOD_PIN_PEER_DISPLAY,
1039 peer_role_selected_method);
1040 QVariant var = item->data(peer_role_requested_method);
1041 if (var.isValid() &&
1042 var.toInt() == SEL_METHOD_PIN_PEER_DISPLAY) {
1049 if (text.startsWith(P2P_EVENT_INVITATION_RECEIVED)) {
1050 /* P2P-INVITATION-RECEIVED sa=02:f0:bc:44:87:62 persistent=4 */
1051 QStringList items = text.split(' ');
1052 if (items.size() < 3)
1054 if (!items[1].startsWith("sa=") ||
1055 !items[2].startsWith("persistent="))
1057 QString addr = items[1].mid(3);
1058 int id = items[2].mid(11).toInt();
1064 snprintf(cmd, sizeof(cmd), "GET_NETWORK %d ssid", id);
1065 reply_len = sizeof(reply) - 1;
1066 if (wpagui->ctrlRequest(cmd, reply, &reply_len) < 0)
1068 reply[reply_len] = '\0';
1070 char *pos = strrchr(reply, '"');
1071 if (pos && reply[0] == '"') {
1077 QStandardItem *item;
1078 item = find_addr_type(addr, PEER_TYPE_P2P_INVITATION);
1080 model.removeRow(item->row());
1082 item = new QStandardItem(*invitation_icon, name);
1085 item->setData(PEER_TYPE_P2P_INVITATION, peer_role_type);
1086 item->setToolTip(ItemType(PEER_TYPE_P2P_INVITATION));
1087 item->setData(addr, peer_role_address);
1088 item->setData(id, peer_role_network_id);
1090 model.appendRow(item);
1092 enable_persistent(id);
1097 if (text.startsWith(P2P_EVENT_INVITATION_RESULT)) {
1098 /* P2P-INVITATION-RESULT status=1 */
1103 if (text.startsWith(WPS_EVENT_ER_AP_ADD)) {
1105 * WPS-ER-AP-ADD 87654321-9abc-def0-1234-56789abc0002
1106 * 02:11:22:33:44:55 pri_dev_type=6-0050F204-1 wps_state=1
1107 * |Very friendly name|Company|Long description of the model|
1108 * WAP|http://w1.fi/|http://w1.fi/hostapd/
1110 QStringList items = text.split(' ');
1111 if (items.size() < 5)
1113 QString uuid = items[1];
1114 QString addr = items[2];
1115 QString pri_dev_type = items[3].mid(13);
1116 int wps_state = items[4].mid(10).toInt();
1118 int pos = text.indexOf('|');
1121 items = text.mid(pos + 1).split('|');
1122 if (items.size() < 1)
1125 QStandardItem *item = find_uuid(uuid);
1129 item = new QStandardItem(*ap_icon, items[0]);
1131 item->setData(uuid, peer_role_uuid);
1132 item->setData(addr, peer_role_address);
1133 int type = wps_state == 2 ? PEER_TYPE_WPS_ER_AP:
1134 PEER_TYPE_WPS_ER_AP_UNCONFIGURED;
1135 item->setData(type, peer_role_type);
1136 item->setToolTip(ItemType(type));
1137 item->setData(pri_dev_type, peer_role_pri_dev_type);
1138 item->setData(items.join(QString("\n")),
1140 model.appendRow(item);
1146 if (text.startsWith(WPS_EVENT_ER_AP_REMOVE)) {
1147 /* WPS-ER-AP-REMOVE 87654321-9abc-def0-1234-56789abc0002 */
1148 QStringList items = text.split(' ');
1149 if (items.size() < 2)
1151 if (model.rowCount() == 0)
1154 QModelIndexList lst = model.match(model.index(0, 0),
1155 peer_role_uuid, items[1]);
1156 for (int i = 0; i < lst.size(); i++) {
1157 QStandardItem *item = model.itemFromIndex(lst[i]);
1159 (item->data(peer_role_type).toInt() ==
1160 PEER_TYPE_WPS_ER_AP ||
1161 item->data(peer_role_type).toInt() ==
1162 PEER_TYPE_WPS_ER_AP_UNCONFIGURED))
1163 model.removeRow(lst[i].row());
1168 if (text.startsWith(WPS_EVENT_ER_ENROLLEE_ADD)) {
1170 * WPS-ER-ENROLLEE-ADD 2b7093f1-d6fb-5108-adbb-bea66bb87333
1171 * 02:66:a0:ee:17:27 M1=1 config_methods=0x14d dev_passwd_id=0
1172 * pri_dev_type=1-0050F204-1
1173 * |Wireless Client|Company|cmodel|123|12345|
1175 QStringList items = text.split(' ');
1176 if (items.size() < 3)
1178 QString uuid = items[1];
1179 QString addr = items[2];
1180 QString pri_dev_type = items[6].mid(13);
1181 int config_methods = -1;
1182 int dev_passwd_id = -1;
1184 for (int i = 3; i < items.size(); i++) {
1185 int pos = items[i].indexOf('=') + 1;
1188 QString val = items[i].mid(pos);
1189 if (items[i].startsWith("config_methods=")) {
1190 config_methods = val.toInt(0, 0);
1191 } else if (items[i].startsWith("dev_passwd_id=")) {
1192 dev_passwd_id = val.toInt();
1196 int pos = text.indexOf('|');
1199 items = text.mid(pos + 1).split('|');
1200 if (items.size() < 1)
1202 QString name = items[0];
1203 if (name.length() == 0)
1206 remove_enrollee_uuid(uuid);
1208 QStandardItem *item;
1209 item = new QStandardItem(*laptop_icon, name);
1211 item->setData(uuid, peer_role_uuid);
1212 item->setData(addr, peer_role_address);
1213 item->setData(PEER_TYPE_WPS_ER_ENROLLEE,
1215 item->setToolTip(ItemType(PEER_TYPE_WPS_ER_ENROLLEE));
1216 item->setData(items.join(QString("\n")),
1218 item->setData(pri_dev_type, peer_role_pri_dev_type);
1219 if (config_methods >= 0)
1220 item->setData(config_methods,
1221 peer_role_config_methods);
1222 if (dev_passwd_id >= 0)
1223 item->setData(dev_passwd_id,
1224 peer_role_dev_passwd_id);
1225 model.appendRow(item);
1231 if (text.startsWith(WPS_EVENT_ER_ENROLLEE_REMOVE)) {
1233 * WPS-ER-ENROLLEE-REMOVE 2b7093f1-d6fb-5108-adbb-bea66bb87333
1236 QStringList items = text.split(' ');
1237 if (items.size() < 2)
1239 remove_enrollee_uuid(items[1]);
1243 if (text.startsWith(WPS_EVENT_ENROLLEE_SEEN)) {
1244 /* TODO: need to time out this somehow or remove on successful
1247 * WPS-ENROLLEE-SEEN 02:00:00:00:01:00
1248 * 572cf82f-c957-5653-9b16-b5cfb298abf1 1-0050F204-1 0x80 4 1
1250 * (MAC addr, UUID-E, pri dev type, config methods,
1251 * dev passwd id, request type, [dev name])
1253 QStringList items = text.split(' ');
1254 if (items.size() < 7)
1256 QString addr = items[1];
1257 QString uuid = items[2];
1258 QString pri_dev_type = items[3];
1259 int config_methods = items[4].toInt(0, 0);
1260 int dev_passwd_id = items[5].toInt();
1263 QStandardItem *item = find_addr(addr);
1265 int type = item->data(peer_role_type).toInt();
1266 if (type == PEER_TYPE_ASSOCIATED_STATION)
1267 return; /* already associated */
1270 int pos = text.indexOf('[');
1272 int pos2 = text.lastIndexOf(']');
1274 QStringList items2 =
1275 text.mid(pos + 1, pos2 - pos - 1).
1283 item = find_uuid(uuid);
1285 QVariant var = item->data(peer_role_config_methods);
1286 QVariant var2 = item->data(peer_role_dev_passwd_id);
1287 if ((var.isValid() && config_methods != var.toInt()) ||
1288 (var2.isValid() && dev_passwd_id != var2.toInt()))
1289 remove_enrollee_uuid(uuid);
1294 item = new QStandardItem(*laptop_icon, name);
1296 item->setData(uuid, peer_role_uuid);
1297 item->setData(addr, peer_role_address);
1298 item->setData(PEER_TYPE_WPS_ENROLLEE,
1300 item->setToolTip(ItemType(PEER_TYPE_WPS_ENROLLEE));
1301 item->setData(items.join(QString("\n")),
1303 item->setData(pri_dev_type, peer_role_pri_dev_type);
1304 item->setData(config_methods,
1305 peer_role_config_methods);
1306 item->setData(dev_passwd_id, peer_role_dev_passwd_id);
1307 model.appendRow(item);
1313 if (text.startsWith(WPA_EVENT_BSS_ADDED)) {
1314 /* CTRL-EVENT-BSS-ADDED 34 00:11:22:33:44:55 */
1315 QStringList items = text.split(' ');
1316 if (items.size() < 2)
1319 snprintf(cmd, sizeof(cmd), "BSS ID-%d", items[1].toInt());
1324 if (text.startsWith(WPA_EVENT_BSS_REMOVED)) {
1325 /* CTRL-EVENT-BSS-REMOVED 34 00:11:22:33:44:55 */
1326 QStringList items = text.split(' ');
1327 if (items.size() < 2)
1329 remove_bss(items[1].toInt());
1335 void Peers::ctx_p2p_connect()
1337 if (ctx_item == NULL)
1339 QString addr = ctx_item->data(peer_role_address).toString();
1341 int config_methods =
1342 ctx_item->data(peer_role_config_methods).toInt();
1343 enum selected_method method = SEL_METHOD_NONE;
1344 QVariant var = ctx_item->data(peer_role_selected_method);
1346 method = (enum selected_method) var.toInt();
1347 if (method == SEL_METHOD_PIN_LOCAL_DISPLAY) {
1348 arg = ctx_item->data(peer_role_selected_pin).toString();
1352 snprintf(cmd, sizeof(cmd), "P2P_CONNECT %s %s display",
1353 addr.toLocal8Bit().constData(),
1354 arg.toLocal8Bit().constData());
1355 reply_len = sizeof(reply) - 1;
1356 if (wpagui->ctrlRequest(cmd, reply, &reply_len) < 0) {
1358 msg.setIcon(QMessageBox::Warning);
1359 msg.setText("Failed to initiate P2P connect.");
1363 QMessageBox::information(this,
1364 tr("PIN for ") + ctx_item->text(),
1365 tr("Enter the following PIN on the\n"
1366 "peer device: ") + arg);
1367 } else if (method == SEL_METHOD_PIN_PEER_DISPLAY) {
1368 StringQuery input(tr("PIN from peer display:"));
1369 input.setWindowTitle(tr("PIN for ") + ctx_item->text());
1370 if (input.exec() != QDialog::Accepted)
1372 arg = input.get_string();
1373 } else if (config_methods == 0x0080 /* PBC */) {
1376 StringQuery input(tr("PIN:"));
1377 input.setWindowTitle(tr("PIN for ") + ctx_item->text());
1378 if (input.exec() != QDialog::Accepted)
1380 arg = input.get_string();
1386 snprintf(cmd, sizeof(cmd), "P2P_CONNECT %s %s",
1387 addr.toLocal8Bit().constData(),
1388 arg.toLocal8Bit().constData());
1389 reply_len = sizeof(reply) - 1;
1390 if (wpagui->ctrlRequest(cmd, reply, &reply_len) < 0) {
1392 msg.setIcon(QMessageBox::Warning);
1393 msg.setText("Failed to initiate P2P connect.");
1399 void Peers::ctx_p2p_req_pin()
1401 if (ctx_item == NULL)
1403 QString addr = ctx_item->data(peer_role_address).toString();
1404 ctx_item->setData(SEL_METHOD_PIN_PEER_DISPLAY,
1405 peer_role_requested_method);
1410 snprintf(cmd, sizeof(cmd), "P2P_PROV_DISC %s display",
1411 addr.toLocal8Bit().constData());
1412 reply_len = sizeof(reply) - 1;
1413 if (wpagui->ctrlRequest(cmd, reply, &reply_len) < 0) {
1415 msg.setIcon(QMessageBox::Warning);
1416 msg.setText(tr("Failed to request PIN from peer."));
1422 void Peers::ctx_p2p_show_pin()
1424 if (ctx_item == NULL)
1426 QString addr = ctx_item->data(peer_role_address).toString();
1427 ctx_item->setData(SEL_METHOD_PIN_LOCAL_DISPLAY,
1428 peer_role_requested_method);
1433 snprintf(cmd, sizeof(cmd), "P2P_PROV_DISC %s keypad",
1434 addr.toLocal8Bit().constData());
1435 reply_len = sizeof(reply) - 1;
1436 if (wpagui->ctrlRequest(cmd, reply, &reply_len) < 0) {
1438 msg.setIcon(QMessageBox::Warning);
1439 msg.setText(tr("Failed to request peer to enter PIN."));
1445 void Peers::ctx_p2p_display_pin()
1447 if (ctx_item == NULL)
1449 QString addr = ctx_item->data(peer_role_address).toString();
1454 snprintf(cmd, sizeof(cmd), "P2P_CONNECT %s pin",
1455 addr.toLocal8Bit().constData());
1456 reply_len = sizeof(reply) - 1;
1457 if (wpagui->ctrlRequest(cmd, reply, &reply_len) < 0) {
1459 msg.setIcon(QMessageBox::Warning);
1460 msg.setText("Failed to initiate P2P connect.");
1464 reply[reply_len] = '\0';
1465 QMessageBox::information(this,
1466 tr("PIN for ") + ctx_item->text(),
1467 tr("Enter the following PIN on the\n"
1468 "peer device: ") + reply);
1472 void Peers::ctx_p2p_display_pin_pd()
1474 if (ctx_item == NULL)
1476 QString addr = ctx_item->data(peer_role_address).toString();
1477 QString arg = ctx_item->data(peer_role_selected_pin).toString();
1482 snprintf(cmd, sizeof(cmd), "P2P_CONNECT %s %s display",
1483 addr.toLocal8Bit().constData(),
1484 arg.toLocal8Bit().constData());
1485 reply_len = sizeof(reply) - 1;
1486 if (wpagui->ctrlRequest(cmd, reply, &reply_len) < 0) {
1488 msg.setIcon(QMessageBox::Warning);
1489 msg.setText("Failed to initiate P2P connect.");
1493 reply[reply_len] = '\0';
1494 QMessageBox::information(this,
1495 tr("PIN for ") + ctx_item->text(),
1496 tr("Enter the following PIN on the\n"
1497 "peer device: ") + arg);
1501 void Peers::ctx_p2p_enter_pin()
1503 if (ctx_item == NULL)
1505 QString addr = ctx_item->data(peer_role_address).toString();
1508 StringQuery input(tr("PIN from peer:"));
1509 input.setWindowTitle(tr("PIN for ") + ctx_item->text());
1510 if (input.exec() != QDialog::Accepted)
1512 arg = input.get_string();
1517 snprintf(cmd, sizeof(cmd), "P2P_CONNECT %s %s keypad",
1518 addr.toLocal8Bit().constData(),
1519 arg.toLocal8Bit().constData());
1520 reply_len = sizeof(reply) - 1;
1521 if (wpagui->ctrlRequest(cmd, reply, &reply_len) < 0) {
1523 msg.setIcon(QMessageBox::Warning);
1524 msg.setText("Failed to initiate P2P connect.");
1530 void Peers::ctx_p2p_remove_group()
1532 if (ctx_item == NULL)
1537 snprintf(cmd, sizeof(cmd), "P2P_GROUP_REMOVE %s",
1538 ctx_item->data(peer_role_ifname).toString().toLocal8Bit().
1540 reply_len = sizeof(reply) - 1;
1541 if (wpagui->ctrlRequest(cmd, reply, &reply_len) < 0) {
1543 msg.setIcon(QMessageBox::Warning);
1544 msg.setText("Failed to remove P2P Group.");
1550 void Peers::closeEvent(QCloseEvent *)
1554 size_t replylen = sizeof(reply) - 1;
1555 wpagui->ctrlRequest("WPS_ER_STOP", reply, &replylen);
1560 void Peers::done(int r)
1567 void Peers::remove_enrollee_uuid(QString uuid)
1569 if (model.rowCount() == 0)
1572 QModelIndexList lst = model.match(model.index(0, 0),
1573 peer_role_uuid, uuid);
1574 for (int i = 0; i < lst.size(); i++) {
1575 QStandardItem *item = model.itemFromIndex(lst[i]);
1578 int type = item->data(peer_role_type).toInt();
1579 if (type == PEER_TYPE_WPS_ER_ENROLLEE ||
1580 type == PEER_TYPE_WPS_ENROLLEE)
1581 model.removeRow(lst[i].row());
1586 void Peers::properties()
1588 if (ctx_item == NULL)
1591 QMessageBox msg(this);
1592 msg.setStandardButtons(QMessageBox::Ok);
1593 msg.setDefaultButton(QMessageBox::Ok);
1594 msg.setEscapeButton(QMessageBox::Ok);
1595 msg.setWindowTitle(tr("Peer Properties"));
1597 int type = ctx_item->data(peer_role_type).toInt();
1598 QString title = Peers::ItemType(type);
1600 msg.setText(title + QString("\n") + tr("Name: ") + ctx_item->text());
1605 var = ctx_item->data(peer_role_address);
1607 info += tr("Address: ") + var.toString() + QString("\n");
1609 var = ctx_item->data(peer_role_uuid);
1611 info += tr("UUID: ") + var.toString() + QString("\n");
1613 var = ctx_item->data(peer_role_pri_dev_type);
1615 info += tr("Primary Device Type: ") + var.toString() +
1618 var = ctx_item->data(peer_role_ssid);
1620 info += tr("SSID: ") + var.toString() + QString("\n");
1622 var = ctx_item->data(peer_role_config_methods);
1623 if (var.isValid()) {
1624 int methods = var.toInt();
1625 info += tr("Configuration Methods: ");
1626 if (methods & 0x0001)
1627 info += tr("[USBA]");
1628 if (methods & 0x0002)
1629 info += tr("[Ethernet]");
1630 if (methods & 0x0004)
1631 info += tr("[Label]");
1632 if (methods & 0x0008)
1633 info += tr("[Display]");
1634 if (methods & 0x0010)
1635 info += tr("[Ext. NFC Token]");
1636 if (methods & 0x0020)
1637 info += tr("[Int. NFC Token]");
1638 if (methods & 0x0040)
1639 info += tr("[NFC Interface]");
1640 if (methods & 0x0080)
1641 info += tr("[Push Button]");
1642 if (methods & 0x0100)
1643 info += tr("[Keypad]");
1647 var = ctx_item->data(peer_role_selected_method);
1648 if (var.isValid()) {
1649 enum selected_method method =
1650 (enum selected_method) var.toInt();
1652 case SEL_METHOD_NONE:
1654 case SEL_METHOD_PIN_PEER_DISPLAY:
1655 info += tr("Selected Method: PIN on peer display\n");
1657 case SEL_METHOD_PIN_LOCAL_DISPLAY:
1658 info += tr("Selected Method: PIN on local display\n");
1663 var = ctx_item->data(peer_role_selected_pin);
1664 if (var.isValid()) {
1665 info += tr("PIN to enter on peer: ") + var.toString() + "\n";
1668 var = ctx_item->data(peer_role_dev_passwd_id);
1669 if (var.isValid()) {
1670 info += tr("Device Password ID: ") + var.toString();
1671 switch (var.toInt()) {
1673 info += tr(" (Default PIN)");
1676 info += tr(" (User-specified PIN)");
1679 info += tr(" (Machine-specified PIN)");
1682 info += tr(" (Rekey)");
1685 info += tr(" (Push Button)");
1688 info += tr(" (Registrar-specified)");
1694 msg.setInformativeText(info);
1696 var = ctx_item->data(peer_role_details);
1698 msg.setDetailedText(var.toString());
1704 void Peers::connect_pbc()
1706 if (ctx_item == NULL)
1713 int peer_type = ctx_item->data(peer_role_type).toInt();
1714 if (peer_type == PEER_TYPE_WPS_ER_ENROLLEE) {
1715 snprintf(cmd, sizeof(cmd), "WPS_ER_PBC %s",
1716 ctx_item->data(peer_role_uuid).toString().toLocal8Bit().
1718 } else if (peer_type == PEER_TYPE_P2P ||
1719 peer_type == PEER_TYPE_P2P_CLIENT) {
1720 snprintf(cmd, sizeof(cmd), "P2P_CONNECT %s pbc",
1721 ctx_item->data(peer_role_address).toString().
1722 toLocal8Bit().constData());
1724 snprintf(cmd, sizeof(cmd), "WPS_PBC");
1726 reply_len = sizeof(reply) - 1;
1727 if (wpagui->ctrlRequest(cmd, reply, &reply_len) < 0) {
1729 msg.setIcon(QMessageBox::Warning);
1730 msg.setText(tr("Failed to start WPS PBC."));
1736 void Peers::learn_ap_config()
1738 if (ctx_item == NULL)
1741 QString uuid = ctx_item->data(peer_role_uuid).toString();
1743 StringQuery input(tr("AP PIN:"));
1744 input.setWindowTitle(tr("AP PIN for ") + ctx_item->text());
1745 if (input.exec() != QDialog::Accepted)
1752 snprintf(cmd, sizeof(cmd), "WPS_ER_LEARN %s %s",
1753 uuid.toLocal8Bit().constData(),
1754 input.get_string().toLocal8Bit().constData());
1755 reply_len = sizeof(reply) - 1;
1756 if (wpagui->ctrlRequest(cmd, reply, &reply_len) < 0) {
1758 msg.setIcon(QMessageBox::Warning);
1759 msg.setText(tr("Failed to start learning AP configuration."));
1765 void Peers::ctx_hide_ap()
1769 if (model.rowCount() == 0)
1773 QModelIndexList lst;
1774 lst = model.match(model.index(0, 0),
1775 peer_role_type, PEER_TYPE_AP);
1776 if (lst.size() == 0) {
1777 lst = model.match(model.index(0, 0),
1778 peer_role_type, PEER_TYPE_AP_WPS);
1779 if (lst.size() == 0)
1783 model.removeRow(lst[0].row());
1788 void Peers::ctx_show_ap()
1795 void Peers::ctx_p2p_show_passphrase()
1800 reply_len = sizeof(reply) - 1;
1801 if (wpagui->ctrlRequest("P2P_GET_PASSPHRASE", reply, &reply_len) < 0 ||
1802 memcmp(reply, "FAIL", 4) == 0) {
1804 msg.setIcon(QMessageBox::Warning);
1805 msg.setText("Failed to get P2P group passphrase.");
1808 reply[reply_len] = '\0';
1809 QMessageBox::information(this, tr("Passphrase"),
1810 tr("P2P group passphrase:\n") +
1816 void Peers::ctx_p2p_start_persistent()
1818 if (ctx_item == NULL)
1825 snprintf(cmd, sizeof(cmd), "P2P_GROUP_ADD persistent=%d",
1826 ctx_item->data(peer_role_network_id).toInt());
1827 if (wpagui->ctrlRequest(cmd, reply, &reply_len) < 0 ||
1828 memcmp(reply, "FAIL", 4) == 0) {
1830 msg.setIcon(QMessageBox::Warning);
1831 msg.setText(tr("Failed to start persistent P2P Group."));
1833 } else if (ctx_item->data(peer_role_type).toInt() ==
1834 PEER_TYPE_P2P_INVITATION)
1835 model.removeRow(ctx_item->row());
1839 void Peers::ctx_p2p_invite()
1841 if (ctx_item == NULL)
1848 snprintf(cmd, sizeof(cmd), "P2P_INVITE persistent=%d",
1849 ctx_item->data(peer_role_network_id).toInt());
1850 if (wpagui->ctrlRequest(cmd, reply, &reply_len) < 0 ||
1851 memcmp(reply, "FAIL", 4) == 0) {
1853 msg.setIcon(QMessageBox::Warning);
1854 msg.setText(tr("Failed to invite peer to start persistent "
1861 void Peers::ctx_p2p_delete()
1863 if (ctx_item == NULL)
1865 model.removeRow(ctx_item->row());
1869 void Peers::enable_persistent(int id)
1871 if (model.rowCount() == 0)
1874 QModelIndexList lst = model.match(model.index(0, 0),
1875 peer_role_network_id, id);
1876 for (int i = 0; i < lst.size(); i++) {
1877 QStandardItem *item = model.itemFromIndex(lst[i]);
1878 int type = item->data(peer_role_type).toInt();
1879 if (type == PEER_TYPE_P2P_PERSISTENT_GROUP_GO ||
1880 type == PEER_TYPE_P2P_PERSISTENT_GROUP_CLIENT)
1881 item->setBackground(Qt::NoBrush);