2 * wpa_gui - Peers class
3 * Copyright (c) 2009-2010, Atheros Communications
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 as
7 * published by the Free Software Foundation.
9 * Alternatively, this software may be distributed under the terms of BSD
12 * See README and COPYING for more details.
16 #include <QImageReader>
17 #include <QMessageBox>
19 #include "common/wpa_ctrl.h"
21 #include "stringquery.h"
26 peer_role_address = Qt::UserRole + 1,
31 peer_role_pri_dev_type,
33 peer_role_config_methods,
34 peer_role_dev_passwd_id,
36 peer_role_selected_method,
37 peer_role_selected_pin,
38 peer_role_requested_method,
42 enum selected_method {
44 SEL_METHOD_PIN_PEER_DISPLAY,
45 SEL_METHOD_PIN_LOCAL_DISPLAY
50 * - add current AP info (e.g., from WPS) in station mode
54 PEER_TYPE_ASSOCIATED_STATION,
57 PEER_TYPE_WPS_PIN_NEEDED,
61 PEER_TYPE_P2P_PERSISTENT_GROUP_GO,
62 PEER_TYPE_P2P_PERSISTENT_GROUP_CLIENT,
63 PEER_TYPE_P2P_INVITATION,
65 PEER_TYPE_WPS_ER_AP_UNCONFIGURED,
66 PEER_TYPE_WPS_ER_ENROLLEE,
67 PEER_TYPE_WPS_ENROLLEE
71 Peers::Peers(QWidget *parent, const char *, bool, Qt::WFlags)
76 if (QImageReader::supportedImageFormats().contains(QByteArray("svg")))
78 default_icon = new QIcon(":/icons/wpa_gui.svg");
79 ap_icon = new QIcon(":/icons/ap.svg");
80 laptop_icon = new QIcon(":/icons/laptop.svg");
81 group_icon = new QIcon(":/icons/group.svg");
82 invitation_icon = new QIcon(":/icons/invitation.svg");
84 default_icon = new QIcon(":/icons/wpa_gui.png");
85 ap_icon = new QIcon(":/icons/ap.png");
86 laptop_icon = new QIcon(":/icons/laptop.png");
87 group_icon = new QIcon(":/icons/group.png");
88 invitation_icon = new QIcon(":/icons/invitation.png");
91 peers->setModel(&model);
92 peers->setResizeMode(QListView::Adjust);
93 peers->setDragEnabled(false);
94 peers->setSelectionMode(QAbstractItemView::NoSelection);
96 peers->setContextMenuPolicy(Qt::CustomContextMenu);
97 connect(peers, SIGNAL(customContextMenuRequested(const QPoint &)),
98 this, SLOT(context_menu(const QPoint &)));
105 void Peers::setWpaGui(WpaGui *_wpagui)
118 delete invitation_icon;
122 void Peers::languageChange()
128 QString Peers::ItemType(int type)
132 case PEER_TYPE_ASSOCIATED_STATION:
133 title = tr("Associated station");
138 case PEER_TYPE_AP_WPS:
139 title = tr("WPS AP");
141 case PEER_TYPE_WPS_PIN_NEEDED:
142 title = tr("WPS PIN needed");
145 title = tr("P2P Device");
147 case PEER_TYPE_P2P_CLIENT:
148 title = tr("P2P Device (group client)");
150 case PEER_TYPE_P2P_GROUP:
151 title = tr("P2P Group");
153 case PEER_TYPE_P2P_PERSISTENT_GROUP_GO:
154 title = tr("P2P Persistent Group (GO)");
156 case PEER_TYPE_P2P_PERSISTENT_GROUP_CLIENT:
157 title = tr("P2P Persistent Group (client)");
159 case PEER_TYPE_P2P_INVITATION:
160 title = tr("P2P Invitation");
162 case PEER_TYPE_WPS_ER_AP:
163 title = tr("ER: WPS AP");
165 case PEER_TYPE_WPS_ER_AP_UNCONFIGURED:
166 title = tr("ER: WPS AP (Unconfigured)");
168 case PEER_TYPE_WPS_ER_ENROLLEE:
169 title = tr("ER: WPS Enrollee");
171 case PEER_TYPE_WPS_ENROLLEE:
172 title = tr("WPS Enrollee");
179 void Peers::context_menu(const QPoint &pos)
181 QMenu *menu = new QMenu;
185 QModelIndex idx = peers->indexAt(pos);
187 ctx_item = model.itemFromIndex(idx);
188 int type = ctx_item->data(peer_role_type).toInt();
189 menu->addAction(Peers::ItemType(type))->setEnabled(false);
190 menu->addSeparator();
192 int config_methods = -1;
193 QVariant var = ctx_item->data(peer_role_config_methods);
195 config_methods = var.toInt();
197 enum selected_method method = SEL_METHOD_NONE;
198 var = ctx_item->data(peer_role_selected_method);
200 method = (enum selected_method) var.toInt();
202 if ((type == PEER_TYPE_ASSOCIATED_STATION ||
203 type == PEER_TYPE_AP_WPS ||
204 type == PEER_TYPE_WPS_PIN_NEEDED ||
205 type == PEER_TYPE_WPS_ER_ENROLLEE ||
206 type == PEER_TYPE_WPS_ENROLLEE) &&
207 (config_methods == -1 || (config_methods & 0x010c))) {
208 menu->addAction(tr("Enter WPS PIN"), this,
212 if (type == PEER_TYPE_P2P || type == PEER_TYPE_P2P_CLIENT) {
213 menu->addAction(tr("P2P Connect"), this,
214 SLOT(ctx_p2p_connect()));
215 if (method == SEL_METHOD_NONE &&
216 config_methods > -1 &&
217 config_methods & 0x0080 /* PBC */ &&
218 config_methods != 0x0080)
219 menu->addAction(tr("P2P Connect (PBC)"), this,
220 SLOT(connect_pbc()));
221 if (method == SEL_METHOD_NONE) {
222 menu->addAction(tr("P2P Request PIN"), this,
223 SLOT(ctx_p2p_req_pin()));
224 menu->addAction(tr("P2P Show PIN"), this,
225 SLOT(ctx_p2p_show_pin()));
228 if (config_methods > -1 && (config_methods & 0x0100)) {
229 /* Peer has Keypad */
230 menu->addAction(tr("P2P Display PIN"), this,
231 SLOT(ctx_p2p_display_pin()));
234 if (config_methods > -1 && (config_methods & 0x000c)) {
235 /* Peer has Label or Display */
236 menu->addAction(tr("P2P Enter PIN"), this,
237 SLOT(ctx_p2p_enter_pin()));
241 if (type == PEER_TYPE_P2P_GROUP) {
242 menu->addAction(tr("Show passphrase"), this,
243 SLOT(ctx_p2p_show_passphrase()));
244 menu->addAction(tr("Remove P2P Group"), this,
245 SLOT(ctx_p2p_remove_group()));
248 if (type == PEER_TYPE_P2P_PERSISTENT_GROUP_GO ||
249 type == PEER_TYPE_P2P_PERSISTENT_GROUP_CLIENT ||
250 type == PEER_TYPE_P2P_INVITATION) {
251 menu->addAction(tr("Start group"), this,
252 SLOT(ctx_p2p_start_persistent()));
255 if (type == PEER_TYPE_P2P_PERSISTENT_GROUP_GO ||
256 type == PEER_TYPE_P2P_PERSISTENT_GROUP_CLIENT) {
257 menu->addAction(tr("Invite"), this,
258 SLOT(ctx_p2p_invite()));
261 if (type == PEER_TYPE_P2P_INVITATION) {
262 menu->addAction(tr("Ignore"), this,
263 SLOT(ctx_p2p_delete()));
266 if (type == PEER_TYPE_AP_WPS) {
267 menu->addAction(tr("Connect (PBC)"), this,
268 SLOT(connect_pbc()));
271 if ((type == PEER_TYPE_ASSOCIATED_STATION ||
272 type == PEER_TYPE_WPS_ER_ENROLLEE ||
273 type == PEER_TYPE_WPS_ENROLLEE) &&
274 config_methods >= 0 && (config_methods & 0x0080)) {
275 menu->addAction(tr("Enroll (PBC)"), this,
276 SLOT(connect_pbc()));
279 if (type == PEER_TYPE_WPS_ER_AP) {
280 menu->addAction(tr("Learn Configuration"), this,
281 SLOT(learn_ap_config()));
284 menu->addAction(tr("Properties"), this, SLOT(properties()));
287 menu->addAction(QString(tr("Refresh")), this,
288 SLOT(ctx_refresh()));
289 menu->addAction(tr("Start P2P discovery"), this,
290 SLOT(ctx_p2p_start()));
291 menu->addAction(tr("Stop P2P discovery"), this,
292 SLOT(ctx_p2p_stop()));
293 menu->addAction(tr("P2P listen only"), this,
294 SLOT(ctx_p2p_listen()));
295 menu->addAction(tr("Start P2P group"), this,
296 SLOT(ctx_p2p_start_group()));
298 menu->addAction(tr("Show AP entries"), this,
299 SLOT(ctx_show_ap()));
301 menu->addAction(tr("Hide AP entries"), this,
302 SLOT(ctx_hide_ap()));
305 menu->exec(peers->mapToGlobal(pos));
309 void Peers::enter_pin()
311 if (ctx_item == NULL)
314 int peer_type = ctx_item->data(peer_role_type).toInt();
317 addr = ctx_item->data(peer_role_address).toString();
318 if (peer_type == PEER_TYPE_WPS_ER_ENROLLEE)
319 uuid = ctx_item->data(peer_role_uuid).toString();
321 StringQuery input(tr("PIN:"));
322 input.setWindowTitle(tr("PIN for ") + ctx_item->text());
323 if (input.exec() != QDialog::Accepted)
330 if (peer_type == PEER_TYPE_WPS_ER_ENROLLEE) {
331 snprintf(cmd, sizeof(cmd), "WPS_ER_PIN %s %s %s",
332 uuid.toAscii().constData(),
333 input.get_string().toAscii().constData(),
334 addr.toAscii().constData());
336 snprintf(cmd, sizeof(cmd), "WPS_PIN %s %s",
337 addr.toAscii().constData(),
338 input.get_string().toAscii().constData());
340 reply_len = sizeof(reply) - 1;
341 if (wpagui->ctrlRequest(cmd, reply, &reply_len) < 0) {
343 msg.setIcon(QMessageBox::Warning);
344 msg.setText(tr("Failed to set the WPS PIN."));
350 void Peers::ctx_refresh()
356 void Peers::ctx_p2p_start()
360 reply_len = sizeof(reply) - 1;
361 if (wpagui->ctrlRequest("P2P_FIND", reply, &reply_len) < 0 ||
362 memcmp(reply, "FAIL", 4) == 0) {
364 msg.setIcon(QMessageBox::Warning);
365 msg.setText("Failed to start P2P discovery.");
371 void Peers::ctx_p2p_stop()
375 reply_len = sizeof(reply) - 1;
376 wpagui->ctrlRequest("P2P_STOP_FIND", reply, &reply_len);
380 void Peers::ctx_p2p_listen()
384 reply_len = sizeof(reply) - 1;
385 if (wpagui->ctrlRequest("P2P_LISTEN 3600", reply, &reply_len) < 0 ||
386 memcmp(reply, "FAIL", 4) == 0) {
388 msg.setIcon(QMessageBox::Warning);
389 msg.setText("Failed to start P2P listen.");
395 void Peers::ctx_p2p_start_group()
399 reply_len = sizeof(reply) - 1;
400 if (wpagui->ctrlRequest("P2P_GROUP_ADD", reply, &reply_len) < 0 ||
401 memcmp(reply, "FAIL", 4) == 0) {
403 msg.setIcon(QMessageBox::Warning);
404 msg.setText("Failed to start P2P group.");
410 void Peers::add_station(QString info)
412 QStringList lines = info.split(QRegExp("\\n"));
415 for (QStringList::Iterator it = lines.begin();
416 it != lines.end(); it++) {
417 int pos = (*it).indexOf('=') + 1;
421 if ((*it).startsWith("wpsDeviceName="))
422 name = (*it).mid(pos);
423 else if ((*it).startsWith("p2p_device_name="))
424 name = (*it).mid(pos);
430 QStandardItem *item = new QStandardItem(*laptop_icon, name);
432 /* Remove WPS enrollee entry if one is still pending */
433 if (model.rowCount() > 0) {
434 QModelIndexList lst = model.match(model.index(0, 0),
437 for (int i = 0; i < lst.size(); i++) {
439 item = model.itemFromIndex(lst[i]);
442 int type = item->data(peer_role_type).toInt();
443 if (type == PEER_TYPE_WPS_ENROLLEE) {
444 model.removeRow(lst[i].row());
450 item->setData(lines[0], peer_role_address);
451 item->setData(PEER_TYPE_ASSOCIATED_STATION,
453 item->setData(info, peer_role_details);
454 item->setToolTip(ItemType(PEER_TYPE_ASSOCIATED_STATION));
455 model.appendRow(item);
460 void Peers::add_stations()
467 reply_len = sizeof(reply) - 1;
468 if (wpagui->ctrlRequest("STA-FIRST", reply, &reply_len) < 0)
472 reply[reply_len] = '\0';
475 while (*txt != '\0' && *txt != '\n')
478 if (strncmp(reply, "FAIL", 4) == 0 ||
479 strncmp(reply, "UNKNOWN", 7) == 0)
484 reply_len = sizeof(reply) - 1;
485 snprintf(cmd, sizeof(cmd), "STA-NEXT %s", reply);
486 res = wpagui->ctrlRequest(cmd, reply, &reply_len);
491 void Peers::add_single_station(const char *addr)
497 reply_len = sizeof(reply) - 1;
498 snprintf(cmd, sizeof(cmd), "STA %s", addr);
499 if (wpagui->ctrlRequest(cmd, reply, &reply_len) < 0)
502 reply[reply_len] = '\0';
505 while (*txt != '\0' && *txt != '\n')
508 if (strncmp(reply, "FAIL", 4) == 0 ||
509 strncmp(reply, "UNKNOWN", 7) == 0)
516 void Peers::add_p2p_group_client(QStandardItem * /*parent*/, QString params)
519 * dev=02:b5:64:63:30:63 iface=02:b5:64:63:30:63 dev_capab=0x0
520 * dev_type=1-0050f204-1 dev_name='Wireless Client'
521 * config_methods=0x8c
525 params.split(QRegExp(" (?=[^']*('[^']*'[^']*)*$)"));
528 int config_methods = 0;
531 for (int i = 0; i < items.size(); i++) {
532 QString str = items.at(i);
533 int pos = str.indexOf('=') + 1;
534 if (str.startsWith("dev_name='"))
535 name = str.section('\'', 1, -2);
536 else if (str.startsWith("config_methods="))
538 str.section('=', 1).toInt(0, 0);
539 else if (str.startsWith("dev="))
541 else if (str.startsWith("dev_type=") && dev_type.isEmpty())
542 dev_type = str.mid(pos);
545 QStandardItem *item = find_addr(addr);
549 item = new QStandardItem(*default_icon, name);
551 /* TODO: indicate somehow the relationship to the group owner
553 item->setData(addr, peer_role_address);
554 item->setData(config_methods, peer_role_config_methods);
555 item->setData(PEER_TYPE_P2P_CLIENT, peer_role_type);
556 if (!dev_type.isEmpty())
557 item->setData(dev_type, peer_role_pri_dev_type);
558 item->setData(items.join(QString("\n")), peer_role_details);
559 item->setToolTip(ItemType(PEER_TYPE_P2P_CLIENT));
560 model.appendRow(item);
565 void Peers::remove_bss(int id)
567 if (model.rowCount() == 0)
570 QModelIndexList lst = model.match(model.index(0, 0), peer_role_bss_id,
574 model.removeRow(lst[0].row());
578 bool Peers::add_bss(const char *cmd)
586 reply_len = sizeof(reply) - 1;
587 if (wpagui->ctrlRequest(cmd, reply, &reply_len) < 0)
589 reply[reply_len] = '\0';
592 if (bss.isEmpty() || bss.startsWith("FAIL"))
595 QString ssid, bssid, flags, wps_name, pri_dev_type;
598 QStringList lines = bss.split(QRegExp("\\n"));
599 for (QStringList::Iterator it = lines.begin();
600 it != lines.end(); it++) {
601 int pos = (*it).indexOf('=') + 1;
605 if ((*it).startsWith("bssid="))
606 bssid = (*it).mid(pos);
607 else if ((*it).startsWith("id="))
608 id = (*it).mid(pos).toInt();
609 else if ((*it).startsWith("flags="))
610 flags = (*it).mid(pos);
611 else if ((*it).startsWith("ssid="))
612 ssid = (*it).mid(pos);
613 else if ((*it).startsWith("wps_device_name="))
614 wps_name = (*it).mid(pos);
615 else if ((*it).startsWith("wps_primary_device_type="))
616 pri_dev_type = (*it).mid(pos);
619 QString name = wps_name;
621 name = ssid + "\n" + bssid;
623 QStandardItem *item = new QStandardItem(*ap_icon, name);
625 item->setData(bssid, peer_role_address);
627 item->setData(id, peer_role_bss_id);
629 if (flags.contains("[WPS"))
630 type = PEER_TYPE_AP_WPS;
633 item->setData(type, peer_role_type);
635 for (int i = 0; i < lines.size(); i++) {
636 if (lines[i].length() > 60) {
637 lines[i].remove(60, lines[i].length());
641 item->setToolTip(ItemType(type));
642 item->setData(lines.join("\n"), peer_role_details);
643 if (!pri_dev_type.isEmpty())
644 item->setData(pri_dev_type,
645 peer_role_pri_dev_type);
647 item->setData(ssid, peer_role_ssid);
648 model.appendRow(item);
650 lines = bss.split(QRegExp("\\n"));
651 for (QStringList::Iterator it = lines.begin();
652 it != lines.end(); it++) {
653 if ((*it).startsWith("p2p_group_client:"))
654 add_p2p_group_client(item,
663 void Peers::add_scan_results()
670 snprintf(cmd, sizeof(cmd), "BSS %d", index++);
680 void Peers::add_persistent(int id, const char *ssid, const char *bssid)
687 snprintf(cmd, sizeof(cmd), "GET_NETWORK %d mode", id);
688 if (wpagui->ctrlRequest(cmd, reply, &reply_len) < 0)
690 reply[reply_len] = '\0';
694 name = '[' + name + ']';
696 QStandardItem *item = new QStandardItem(*group_icon, name);
702 type = PEER_TYPE_P2P_PERSISTENT_GROUP_GO;
704 type = PEER_TYPE_P2P_PERSISTENT_GROUP_CLIENT;
705 item->setData(type, peer_role_type);
706 item->setToolTip(ItemType(type));
707 item->setData(ssid, peer_role_ssid);
708 if (bssid && strcmp(bssid, "any") == 0)
711 item->setData(bssid, peer_role_address);
712 item->setData(id, peer_role_network_id);
713 item->setBackground(Qt::BDiagPattern);
715 model.appendRow(item);
719 void Peers::add_persistent_groups()
721 char buf[2048], *start, *end, *id, *ssid, *bssid, *flags;
724 len = sizeof(buf) - 1;
725 if (wpagui->ctrlRequest("LIST_NETWORKS", buf, &len) < 0)
729 start = strchr(buf, '\n');
736 end = strchr(start, '\n');
740 while (end[0] && end[1])
746 ssid = strchr(id, '\t');
750 bssid = strchr(ssid, '\t');
754 flags = strchr(bssid, '\t');
759 if (strstr(flags, "[DISABLED][P2P-PERSISTENT]"))
760 add_persistent(atoi(id), ssid, bssid);
769 void Peers::update_peers()
776 size_t replylen = sizeof(reply) - 1;
777 wpagui->ctrlRequest("WPS_ER_START", reply, &replylen);
781 add_persistent_groups();
785 QStandardItem * Peers::find_addr(QString addr)
787 if (model.rowCount() == 0)
790 QModelIndexList lst = model.match(model.index(0, 0), peer_role_address,
794 return model.itemFromIndex(lst[0]);
798 QStandardItem * Peers::find_addr_type(QString addr, int type)
800 if (model.rowCount() == 0)
803 QModelIndexList lst = model.match(model.index(0, 0), peer_role_address,
805 for (int i = 0; i < lst.size(); i++) {
806 QStandardItem *item = model.itemFromIndex(lst[i]);
807 if (item->data(peer_role_type).toInt() == type)
814 QStandardItem * Peers::find_uuid(QString uuid)
816 if (model.rowCount() == 0)
819 QModelIndexList lst = model.match(model.index(0, 0), peer_role_uuid,
823 return model.itemFromIndex(lst[0]);
827 void Peers::event_notify(WpaMsg msg)
829 QString text = msg.getMsg();
831 if (text.startsWith(WPS_EVENT_PIN_NEEDED)) {
833 * WPS-PIN-NEEDED 5a02a5fa-9199-5e7c-bc46-e183d3cb32f7
835 * [Wireless Client|Company|cmodel|123|12345|1-0050F204-1]
837 QStringList items = text.split(' ');
838 QString uuid = items[1];
839 QString addr = items[2];
842 QStandardItem *item = find_addr(addr);
846 int pos = text.indexOf('[');
848 int pos2 = text.lastIndexOf(']');
850 items = text.mid(pos + 1, pos2 - pos - 1).
857 item = new QStandardItem(*laptop_icon, name);
859 item->setData(addr, peer_role_address);
860 item->setData(PEER_TYPE_WPS_PIN_NEEDED,
862 item->setToolTip(ItemType(PEER_TYPE_WPS_PIN_NEEDED));
863 item->setData(items.join("\n"), peer_role_details);
864 item->setData(items[5], peer_role_pri_dev_type);
865 model.appendRow(item);
870 if (text.startsWith(AP_STA_CONNECTED)) {
871 /* AP-STA-CONNECTED 02:2a:c4:18:5b:f3 */
872 QStringList items = text.split(' ');
873 QString addr = items[1];
874 QStandardItem *item = find_addr(addr);
875 if (item == NULL || item->data(peer_role_type).toInt() !=
876 PEER_TYPE_ASSOCIATED_STATION)
877 add_single_station(addr.toAscii().constData());
881 if (text.startsWith(AP_STA_DISCONNECTED)) {
882 /* AP-STA-DISCONNECTED 02:2a:c4:18:5b:f3 */
883 QStringList items = text.split(' ');
884 QString addr = items[1];
886 if (model.rowCount() == 0)
889 QModelIndexList lst = model.match(model.index(0, 0),
890 peer_role_address, addr, -1);
891 for (int i = 0; i < lst.size(); i++) {
892 QStandardItem *item = model.itemFromIndex(lst[i]);
893 if (item && item->data(peer_role_type).toInt() ==
894 PEER_TYPE_ASSOCIATED_STATION) {
895 model.removeRow(lst[i].row());
902 if (text.startsWith(P2P_EVENT_DEVICE_FOUND)) {
904 * P2P-DEVICE-FOUND 02:b5:64:63:30:63
905 * p2p_dev_addr=02:b5:64:63:30:63 pri_dev_type=1-0050f204-1
906 * name='Wireless Client' config_methods=0x84 dev_capab=0x21
910 text.split(QRegExp(" (?=[^']*('[^']*'[^']*)*$)"));
911 QString addr = items[1];
913 QString pri_dev_type;
914 int config_methods = 0;
915 for (int i = 0; i < items.size(); i++) {
916 QString str = items.at(i);
917 if (str.startsWith("name='"))
918 name = str.section('\'', 1, -2);
919 else if (str.startsWith("config_methods="))
921 str.section('=', 1).toInt(0, 0);
922 else if (str.startsWith("pri_dev_type="))
923 pri_dev_type = str.section('=', 1);
926 QStandardItem *item = find_addr(addr);
928 int type = item->data(peer_role_type).toInt();
929 if (type == PEER_TYPE_P2P)
933 item = new QStandardItem(*default_icon, name);
935 item->setData(addr, peer_role_address);
936 item->setData(config_methods,
937 peer_role_config_methods);
938 item->setData(PEER_TYPE_P2P, peer_role_type);
939 if (!pri_dev_type.isEmpty())
940 item->setData(pri_dev_type,
941 peer_role_pri_dev_type);
942 item->setData(items.join(QString("\n")),
944 item->setToolTip(ItemType(PEER_TYPE_P2P));
945 model.appendRow(item);
948 item = find_addr_type(addr,
949 PEER_TYPE_P2P_PERSISTENT_GROUP_CLIENT);
951 item->setBackground(Qt::NoBrush);
954 if (text.startsWith(P2P_EVENT_GROUP_STARTED)) {
955 /* P2P-GROUP-STARTED wlan0-p2p-0 GO ssid="DIRECT-3F"
956 * passphrase="YOyTkxID" go_dev_addr=02:40:61:c2:f3:b7
958 QStringList items = text.split(' ');
959 if (items.size() < 4)
962 int pos = text.indexOf(" ssid=\"");
965 QString ssid = text.mid(pos + 7);
966 pos = ssid.indexOf(" passphrase=\"");
968 pos = ssid.indexOf(" psk=");
971 pos = ssid.lastIndexOf('"');
975 QStandardItem *item = new QStandardItem(*group_icon, ssid);
977 item->setData(PEER_TYPE_P2P_GROUP, peer_role_type);
978 item->setData(items[1], peer_role_ifname);
980 if (items[2] == "GO") {
981 details = tr("P2P GO for interface ") +
984 details = tr("P2P client for interface ") +
987 if (text.contains(" [PERSISTENT]"))
988 details += "\nPersistent group";
989 item->setData(details, peer_role_details);
990 item->setToolTip(ItemType(PEER_TYPE_P2P_GROUP));
991 model.appendRow(item);
995 if (text.startsWith(P2P_EVENT_GROUP_REMOVED)) {
996 /* P2P-GROUP-REMOVED wlan0-p2p-0 GO */
997 QStringList items = text.split(' ');
998 if (items.size() < 2)
1001 if (model.rowCount() == 0)
1004 QModelIndexList lst = model.match(model.index(0, 0),
1005 peer_role_ifname, items[1]);
1006 for (int i = 0; i < lst.size(); i++)
1007 model.removeRow(lst[i].row());
1011 if (text.startsWith(P2P_EVENT_PROV_DISC_SHOW_PIN)) {
1012 /* P2P-PROV-DISC-SHOW-PIN 02:40:61:c2:f3:b7 12345670 */
1013 QStringList items = text.split(' ');
1014 if (items.size() < 3)
1016 QString addr = items[1];
1017 QString pin = items[2];
1019 QStandardItem *item = find_addr_type(addr, PEER_TYPE_P2P);
1022 item->setData(SEL_METHOD_PIN_LOCAL_DISPLAY,
1023 peer_role_selected_method);
1024 item->setData(pin, peer_role_selected_pin);
1025 QVariant var = item->data(peer_role_requested_method);
1026 if (var.isValid() &&
1027 var.toInt() == SEL_METHOD_PIN_LOCAL_DISPLAY) {
1029 ctx_p2p_display_pin_pd();
1034 if (text.startsWith(P2P_EVENT_PROV_DISC_ENTER_PIN)) {
1035 /* P2P-PROV-DISC-ENTER-PIN 02:40:61:c2:f3:b7 */
1036 QStringList items = text.split(' ');
1037 if (items.size() < 2)
1039 QString addr = items[1];
1041 QStandardItem *item = find_addr_type(addr, PEER_TYPE_P2P);
1044 item->setData(SEL_METHOD_PIN_PEER_DISPLAY,
1045 peer_role_selected_method);
1046 QVariant var = item->data(peer_role_requested_method);
1047 if (var.isValid() &&
1048 var.toInt() == SEL_METHOD_PIN_PEER_DISPLAY) {
1055 if (text.startsWith(P2P_EVENT_INVITATION_RECEIVED)) {
1056 /* P2P-INVITATION-RECEIVED sa=02:f0:bc:44:87:62 persistent=4 */
1057 QStringList items = text.split(' ');
1058 if (items.size() < 3)
1060 if (!items[1].startsWith("sa=") ||
1061 !items[2].startsWith("persistent="))
1063 QString addr = items[1].mid(3);
1064 int id = items[2].mid(11).toInt();
1070 snprintf(cmd, sizeof(cmd), "GET_NETWORK %d ssid", id);
1071 reply_len = sizeof(reply) - 1;
1072 if (wpagui->ctrlRequest(cmd, reply, &reply_len) < 0)
1074 reply[reply_len] = '\0';
1076 char *pos = strrchr(reply, '"');
1077 if (pos && reply[0] == '"') {
1083 QStandardItem *item;
1084 item = find_addr_type(addr, PEER_TYPE_P2P_INVITATION);
1086 model.removeRow(item->row());
1088 item = new QStandardItem(*invitation_icon, name);
1091 item->setData(PEER_TYPE_P2P_INVITATION, peer_role_type);
1092 item->setToolTip(ItemType(PEER_TYPE_P2P_INVITATION));
1093 item->setData(addr, peer_role_address);
1094 item->setData(id, peer_role_network_id);
1096 model.appendRow(item);
1098 enable_persistent(id);
1103 if (text.startsWith(P2P_EVENT_INVITATION_RESULT)) {
1104 /* P2P-INVITATION-RESULT status=1 */
1109 if (text.startsWith(WPS_EVENT_ER_AP_ADD)) {
1111 * WPS-ER-AP-ADD 87654321-9abc-def0-1234-56789abc0002
1112 * 02:11:22:33:44:55 pri_dev_type=6-0050F204-1 wps_state=1
1113 * |Very friendly name|Company|Long description of the model|
1114 * WAP|http://w1.fi/|http://w1.fi/hostapd/
1116 QStringList items = text.split(' ');
1117 if (items.size() < 5)
1119 QString uuid = items[1];
1120 QString addr = items[2];
1121 QString pri_dev_type = items[3].mid(13);
1122 int wps_state = items[4].mid(10).toInt();
1124 int pos = text.indexOf('|');
1127 items = text.mid(pos + 1).split('|');
1128 if (items.size() < 1)
1131 QStandardItem *item = find_uuid(uuid);
1135 item = new QStandardItem(*ap_icon, items[0]);
1137 item->setData(uuid, peer_role_uuid);
1138 item->setData(addr, peer_role_address);
1139 int type = wps_state == 2 ? PEER_TYPE_WPS_ER_AP:
1140 PEER_TYPE_WPS_ER_AP_UNCONFIGURED;
1141 item->setData(type, peer_role_type);
1142 item->setToolTip(ItemType(type));
1143 item->setData(pri_dev_type, peer_role_pri_dev_type);
1144 item->setData(items.join(QString("\n")),
1146 model.appendRow(item);
1152 if (text.startsWith(WPS_EVENT_ER_AP_REMOVE)) {
1153 /* WPS-ER-AP-REMOVE 87654321-9abc-def0-1234-56789abc0002 */
1154 QStringList items = text.split(' ');
1155 if (items.size() < 2)
1157 if (model.rowCount() == 0)
1160 QModelIndexList lst = model.match(model.index(0, 0),
1161 peer_role_uuid, items[1]);
1162 for (int i = 0; i < lst.size(); i++) {
1163 QStandardItem *item = model.itemFromIndex(lst[i]);
1165 (item->data(peer_role_type).toInt() ==
1166 PEER_TYPE_WPS_ER_AP ||
1167 item->data(peer_role_type).toInt() ==
1168 PEER_TYPE_WPS_ER_AP_UNCONFIGURED))
1169 model.removeRow(lst[i].row());
1174 if (text.startsWith(WPS_EVENT_ER_ENROLLEE_ADD)) {
1176 * WPS-ER-ENROLLEE-ADD 2b7093f1-d6fb-5108-adbb-bea66bb87333
1177 * 02:66:a0:ee:17:27 M1=1 config_methods=0x14d dev_passwd_id=0
1178 * pri_dev_type=1-0050F204-1
1179 * |Wireless Client|Company|cmodel|123|12345|
1181 QStringList items = text.split(' ');
1182 if (items.size() < 3)
1184 QString uuid = items[1];
1185 QString addr = items[2];
1186 QString pri_dev_type = items[6].mid(13);
1187 int config_methods = -1;
1188 int dev_passwd_id = -1;
1190 for (int i = 3; i < items.size(); i++) {
1191 int pos = items[i].indexOf('=') + 1;
1194 QString val = items[i].mid(pos);
1195 if (items[i].startsWith("config_methods=")) {
1196 config_methods = val.toInt(0, 0);
1197 } else if (items[i].startsWith("dev_passwd_id=")) {
1198 dev_passwd_id = val.toInt();
1202 int pos = text.indexOf('|');
1205 items = text.mid(pos + 1).split('|');
1206 if (items.size() < 1)
1208 QString name = items[0];
1209 if (name.length() == 0)
1212 remove_enrollee_uuid(uuid);
1214 QStandardItem *item;
1215 item = new QStandardItem(*laptop_icon, name);
1217 item->setData(uuid, peer_role_uuid);
1218 item->setData(addr, peer_role_address);
1219 item->setData(PEER_TYPE_WPS_ER_ENROLLEE,
1221 item->setToolTip(ItemType(PEER_TYPE_WPS_ER_ENROLLEE));
1222 item->setData(items.join(QString("\n")),
1224 item->setData(pri_dev_type, peer_role_pri_dev_type);
1225 if (config_methods >= 0)
1226 item->setData(config_methods,
1227 peer_role_config_methods);
1228 if (dev_passwd_id >= 0)
1229 item->setData(dev_passwd_id,
1230 peer_role_dev_passwd_id);
1231 model.appendRow(item);
1237 if (text.startsWith(WPS_EVENT_ER_ENROLLEE_REMOVE)) {
1239 * WPS-ER-ENROLLEE-REMOVE 2b7093f1-d6fb-5108-adbb-bea66bb87333
1242 QStringList items = text.split(' ');
1243 if (items.size() < 2)
1245 remove_enrollee_uuid(items[1]);
1249 if (text.startsWith(WPS_EVENT_ENROLLEE_SEEN)) {
1250 /* TODO: need to time out this somehow or remove on successful
1253 * WPS-ENROLLEE-SEEN 02:00:00:00:01:00
1254 * 572cf82f-c957-5653-9b16-b5cfb298abf1 1-0050F204-1 0x80 4 1
1256 * (MAC addr, UUID-E, pri dev type, config methods,
1257 * dev passwd id, request type, [dev name])
1259 QStringList items = text.split(' ');
1260 if (items.size() < 7)
1262 QString addr = items[1];
1263 QString uuid = items[2];
1264 QString pri_dev_type = items[3];
1265 int config_methods = items[4].toInt(0, 0);
1266 int dev_passwd_id = items[5].toInt();
1269 QStandardItem *item = find_addr(addr);
1271 int type = item->data(peer_role_type).toInt();
1272 if (type == PEER_TYPE_ASSOCIATED_STATION)
1273 return; /* already associated */
1276 int pos = text.indexOf('[');
1278 int pos2 = text.lastIndexOf(']');
1280 QStringList items2 =
1281 text.mid(pos + 1, pos2 - pos - 1).
1289 item = find_uuid(uuid);
1291 QVariant var = item->data(peer_role_config_methods);
1292 QVariant var2 = item->data(peer_role_dev_passwd_id);
1293 if ((var.isValid() && config_methods != var.toInt()) ||
1294 (var2.isValid() && dev_passwd_id != var2.toInt()))
1295 remove_enrollee_uuid(uuid);
1300 item = new QStandardItem(*laptop_icon, name);
1302 item->setData(uuid, peer_role_uuid);
1303 item->setData(addr, peer_role_address);
1304 item->setData(PEER_TYPE_WPS_ENROLLEE,
1306 item->setToolTip(ItemType(PEER_TYPE_WPS_ENROLLEE));
1307 item->setData(items.join(QString("\n")),
1309 item->setData(pri_dev_type, peer_role_pri_dev_type);
1310 item->setData(config_methods,
1311 peer_role_config_methods);
1312 item->setData(dev_passwd_id, peer_role_dev_passwd_id);
1313 model.appendRow(item);
1319 if (text.startsWith(WPA_EVENT_BSS_ADDED)) {
1320 /* CTRL-EVENT-BSS-ADDED 34 00:11:22:33:44:55 */
1321 QStringList items = text.split(' ');
1322 if (items.size() < 2)
1325 snprintf(cmd, sizeof(cmd), "BSS ID-%d", items[1].toInt());
1330 if (text.startsWith(WPA_EVENT_BSS_REMOVED)) {
1331 /* CTRL-EVENT-BSS-REMOVED 34 00:11:22:33:44:55 */
1332 QStringList items = text.split(' ');
1333 if (items.size() < 2)
1335 remove_bss(items[1].toInt());
1341 void Peers::ctx_p2p_connect()
1343 if (ctx_item == NULL)
1345 QString addr = ctx_item->data(peer_role_address).toString();
1347 int config_methods =
1348 ctx_item->data(peer_role_config_methods).toInt();
1349 enum selected_method method = SEL_METHOD_NONE;
1350 QVariant var = ctx_item->data(peer_role_selected_method);
1352 method = (enum selected_method) var.toInt();
1353 if (method == SEL_METHOD_PIN_LOCAL_DISPLAY) {
1354 arg = ctx_item->data(peer_role_selected_pin).toString();
1358 snprintf(cmd, sizeof(cmd), "P2P_CONNECT %s %s display",
1359 addr.toAscii().constData(),
1360 arg.toAscii().constData());
1361 reply_len = sizeof(reply) - 1;
1362 if (wpagui->ctrlRequest(cmd, reply, &reply_len) < 0) {
1364 msg.setIcon(QMessageBox::Warning);
1365 msg.setText("Failed to initiate P2P connect.");
1369 QMessageBox::information(this,
1370 tr("PIN for ") + ctx_item->text(),
1371 tr("Enter the following PIN on the\n"
1372 "peer device: ") + arg);
1373 } else if (method == SEL_METHOD_PIN_PEER_DISPLAY) {
1374 StringQuery input(tr("PIN from peer display:"));
1375 input.setWindowTitle(tr("PIN for ") + ctx_item->text());
1376 if (input.exec() != QDialog::Accepted)
1378 arg = input.get_string();
1379 } else if (config_methods == 0x0080 /* PBC */) {
1382 StringQuery input(tr("PIN:"));
1383 input.setWindowTitle(tr("PIN for ") + ctx_item->text());
1384 if (input.exec() != QDialog::Accepted)
1386 arg = input.get_string();
1392 snprintf(cmd, sizeof(cmd), "P2P_CONNECT %s %s",
1393 addr.toAscii().constData(),
1394 arg.toAscii().constData());
1395 reply_len = sizeof(reply) - 1;
1396 if (wpagui->ctrlRequest(cmd, reply, &reply_len) < 0) {
1398 msg.setIcon(QMessageBox::Warning);
1399 msg.setText("Failed to initiate P2P connect.");
1405 void Peers::ctx_p2p_req_pin()
1407 if (ctx_item == NULL)
1409 QString addr = ctx_item->data(peer_role_address).toString();
1410 ctx_item->setData(SEL_METHOD_PIN_PEER_DISPLAY,
1411 peer_role_requested_method);
1416 snprintf(cmd, sizeof(cmd), "P2P_PROV_DISC %s display",
1417 addr.toAscii().constData());
1418 reply_len = sizeof(reply) - 1;
1419 if (wpagui->ctrlRequest(cmd, reply, &reply_len) < 0) {
1421 msg.setIcon(QMessageBox::Warning);
1422 msg.setText(tr("Failed to request PIN from peer."));
1428 void Peers::ctx_p2p_show_pin()
1430 if (ctx_item == NULL)
1432 QString addr = ctx_item->data(peer_role_address).toString();
1433 ctx_item->setData(SEL_METHOD_PIN_LOCAL_DISPLAY,
1434 peer_role_requested_method);
1439 snprintf(cmd, sizeof(cmd), "P2P_PROV_DISC %s keypad",
1440 addr.toAscii().constData());
1441 reply_len = sizeof(reply) - 1;
1442 if (wpagui->ctrlRequest(cmd, reply, &reply_len) < 0) {
1444 msg.setIcon(QMessageBox::Warning);
1445 msg.setText(tr("Failed to request peer to enter PIN."));
1451 void Peers::ctx_p2p_display_pin()
1453 if (ctx_item == NULL)
1455 QString addr = ctx_item->data(peer_role_address).toString();
1460 snprintf(cmd, sizeof(cmd), "P2P_CONNECT %s pin",
1461 addr.toAscii().constData());
1462 reply_len = sizeof(reply) - 1;
1463 if (wpagui->ctrlRequest(cmd, reply, &reply_len) < 0) {
1465 msg.setIcon(QMessageBox::Warning);
1466 msg.setText("Failed to initiate P2P connect.");
1470 reply[reply_len] = '\0';
1471 QMessageBox::information(this,
1472 tr("PIN for ") + ctx_item->text(),
1473 tr("Enter the following PIN on the\n"
1474 "peer device: ") + reply);
1478 void Peers::ctx_p2p_display_pin_pd()
1480 if (ctx_item == NULL)
1482 QString addr = ctx_item->data(peer_role_address).toString();
1483 QString arg = ctx_item->data(peer_role_selected_pin).toString();
1488 snprintf(cmd, sizeof(cmd), "P2P_CONNECT %s %s display",
1489 addr.toAscii().constData(),
1490 arg.toAscii().constData());
1491 reply_len = sizeof(reply) - 1;
1492 if (wpagui->ctrlRequest(cmd, reply, &reply_len) < 0) {
1494 msg.setIcon(QMessageBox::Warning);
1495 msg.setText("Failed to initiate P2P connect.");
1499 reply[reply_len] = '\0';
1500 QMessageBox::information(this,
1501 tr("PIN for ") + ctx_item->text(),
1502 tr("Enter the following PIN on the\n"
1503 "peer device: ") + arg);
1507 void Peers::ctx_p2p_enter_pin()
1509 if (ctx_item == NULL)
1511 QString addr = ctx_item->data(peer_role_address).toString();
1514 StringQuery input(tr("PIN from peer:"));
1515 input.setWindowTitle(tr("PIN for ") + ctx_item->text());
1516 if (input.exec() != QDialog::Accepted)
1518 arg = input.get_string();
1523 snprintf(cmd, sizeof(cmd), "P2P_CONNECT %s %s keypad",
1524 addr.toAscii().constData(),
1525 arg.toAscii().constData());
1526 reply_len = sizeof(reply) - 1;
1527 if (wpagui->ctrlRequest(cmd, reply, &reply_len) < 0) {
1529 msg.setIcon(QMessageBox::Warning);
1530 msg.setText("Failed to initiate P2P connect.");
1536 void Peers::ctx_p2p_remove_group()
1538 if (ctx_item == NULL)
1543 snprintf(cmd, sizeof(cmd), "P2P_GROUP_REMOVE %s",
1544 ctx_item->data(peer_role_ifname).toString().toAscii().
1546 reply_len = sizeof(reply) - 1;
1547 if (wpagui->ctrlRequest(cmd, reply, &reply_len) < 0) {
1549 msg.setIcon(QMessageBox::Warning);
1550 msg.setText("Failed to remove P2P Group.");
1556 void Peers::closeEvent(QCloseEvent *)
1560 size_t replylen = sizeof(reply) - 1;
1561 wpagui->ctrlRequest("WPS_ER_STOP", reply, &replylen);
1566 void Peers::done(int r)
1573 void Peers::remove_enrollee_uuid(QString uuid)
1575 if (model.rowCount() == 0)
1578 QModelIndexList lst = model.match(model.index(0, 0),
1579 peer_role_uuid, uuid);
1580 for (int i = 0; i < lst.size(); i++) {
1581 QStandardItem *item = model.itemFromIndex(lst[i]);
1584 int type = item->data(peer_role_type).toInt();
1585 if (type == PEER_TYPE_WPS_ER_ENROLLEE ||
1586 type == PEER_TYPE_WPS_ENROLLEE)
1587 model.removeRow(lst[i].row());
1592 void Peers::properties()
1594 if (ctx_item == NULL)
1597 QMessageBox msg(this);
1598 msg.setStandardButtons(QMessageBox::Ok);
1599 msg.setDefaultButton(QMessageBox::Ok);
1600 msg.setEscapeButton(QMessageBox::Ok);
1601 msg.setWindowTitle(tr("Peer Properties"));
1603 int type = ctx_item->data(peer_role_type).toInt();
1604 QString title = Peers::ItemType(type);
1606 msg.setText(title + QString("\n") + tr("Name: ") + ctx_item->text());
1611 var = ctx_item->data(peer_role_address);
1613 info += tr("Address: ") + var.toString() + QString("\n");
1615 var = ctx_item->data(peer_role_uuid);
1617 info += tr("UUID: ") + var.toString() + QString("\n");
1619 var = ctx_item->data(peer_role_pri_dev_type);
1621 info += tr("Primary Device Type: ") + var.toString() +
1624 var = ctx_item->data(peer_role_ssid);
1626 info += tr("SSID: ") + var.toString() + QString("\n");
1628 var = ctx_item->data(peer_role_config_methods);
1629 if (var.isValid()) {
1630 int methods = var.toInt();
1631 info += tr("Configuration Methods: ");
1632 if (methods & 0x0001)
1633 info += tr("[USBA]");
1634 if (methods & 0x0002)
1635 info += tr("[Ethernet]");
1636 if (methods & 0x0004)
1637 info += tr("[Label]");
1638 if (methods & 0x0008)
1639 info += tr("[Display]");
1640 if (methods & 0x0010)
1641 info += tr("[Ext. NFC Token]");
1642 if (methods & 0x0020)
1643 info += tr("[Int. NFC Token]");
1644 if (methods & 0x0040)
1645 info += tr("[NFC Interface]");
1646 if (methods & 0x0080)
1647 info += tr("[Push Button]");
1648 if (methods & 0x0100)
1649 info += tr("[Keypad]");
1653 var = ctx_item->data(peer_role_selected_method);
1654 if (var.isValid()) {
1655 enum selected_method method =
1656 (enum selected_method) var.toInt();
1658 case SEL_METHOD_NONE:
1660 case SEL_METHOD_PIN_PEER_DISPLAY:
1661 info += tr("Selected Method: PIN on peer display\n");
1663 case SEL_METHOD_PIN_LOCAL_DISPLAY:
1664 info += tr("Selected Method: PIN on local display\n");
1669 var = ctx_item->data(peer_role_selected_pin);
1670 if (var.isValid()) {
1671 info += tr("PIN to enter on peer: ") + var.toString() + "\n";
1674 var = ctx_item->data(peer_role_dev_passwd_id);
1675 if (var.isValid()) {
1676 info += tr("Device Password ID: ") + var.toString();
1677 switch (var.toInt()) {
1679 info += tr(" (Default PIN)");
1682 info += tr(" (User-specified PIN)");
1685 info += tr(" (Machine-specified PIN)");
1688 info += tr(" (Rekey)");
1691 info += tr(" (Push Button)");
1694 info += tr(" (Registrar-specified)");
1700 msg.setInformativeText(info);
1702 var = ctx_item->data(peer_role_details);
1704 msg.setDetailedText(var.toString());
1710 void Peers::connect_pbc()
1712 if (ctx_item == NULL)
1719 int peer_type = ctx_item->data(peer_role_type).toInt();
1720 if (peer_type == PEER_TYPE_WPS_ER_ENROLLEE) {
1721 snprintf(cmd, sizeof(cmd), "WPS_ER_PBC %s",
1722 ctx_item->data(peer_role_uuid).toString().toAscii().
1724 } else if (peer_type == PEER_TYPE_P2P ||
1725 peer_type == PEER_TYPE_P2P_CLIENT) {
1726 snprintf(cmd, sizeof(cmd), "P2P_CONNECT %s pbc",
1727 ctx_item->data(peer_role_address).toString().
1728 toAscii().constData());
1730 snprintf(cmd, sizeof(cmd), "WPS_PBC");
1732 reply_len = sizeof(reply) - 1;
1733 if (wpagui->ctrlRequest(cmd, reply, &reply_len) < 0) {
1735 msg.setIcon(QMessageBox::Warning);
1736 msg.setText(tr("Failed to start WPS PBC."));
1742 void Peers::learn_ap_config()
1744 if (ctx_item == NULL)
1747 QString uuid = ctx_item->data(peer_role_uuid).toString();
1749 StringQuery input(tr("AP PIN:"));
1750 input.setWindowTitle(tr("AP PIN for ") + ctx_item->text());
1751 if (input.exec() != QDialog::Accepted)
1758 snprintf(cmd, sizeof(cmd), "WPS_ER_LEARN %s %s",
1759 uuid.toAscii().constData(),
1760 input.get_string().toAscii().constData());
1761 reply_len = sizeof(reply) - 1;
1762 if (wpagui->ctrlRequest(cmd, reply, &reply_len) < 0) {
1764 msg.setIcon(QMessageBox::Warning);
1765 msg.setText(tr("Failed to start learning AP configuration."));
1771 void Peers::ctx_hide_ap()
1775 if (model.rowCount() == 0)
1779 QModelIndexList lst;
1780 lst = model.match(model.index(0, 0),
1781 peer_role_type, PEER_TYPE_AP);
1782 if (lst.size() == 0) {
1783 lst = model.match(model.index(0, 0),
1784 peer_role_type, PEER_TYPE_AP_WPS);
1785 if (lst.size() == 0)
1789 model.removeRow(lst[0].row());
1794 void Peers::ctx_show_ap()
1801 void Peers::ctx_p2p_show_passphrase()
1806 reply_len = sizeof(reply) - 1;
1807 if (wpagui->ctrlRequest("P2P_GET_PASSPHRASE", reply, &reply_len) < 0 ||
1808 memcmp(reply, "FAIL", 4) == 0) {
1810 msg.setIcon(QMessageBox::Warning);
1811 msg.setText("Failed to get P2P group passphrase.");
1814 reply[reply_len] = '\0';
1815 QMessageBox::information(this, tr("Passphrase"),
1816 tr("P2P group passphrase:\n") +
1822 void Peers::ctx_p2p_start_persistent()
1824 if (ctx_item == NULL)
1831 snprintf(cmd, sizeof(cmd), "P2P_GROUP_ADD persistent=%d",
1832 ctx_item->data(peer_role_network_id).toInt());
1833 if (wpagui->ctrlRequest(cmd, reply, &reply_len) < 0 ||
1834 memcmp(reply, "FAIL", 4) == 0) {
1836 msg.setIcon(QMessageBox::Warning);
1837 msg.setText(tr("Failed to start persistent P2P Group."));
1839 } else if (ctx_item->data(peer_role_type).toInt() ==
1840 PEER_TYPE_P2P_INVITATION)
1841 model.removeRow(ctx_item->row());
1845 void Peers::ctx_p2p_invite()
1847 if (ctx_item == NULL)
1854 snprintf(cmd, sizeof(cmd), "P2P_INVITE persistent=%d",
1855 ctx_item->data(peer_role_network_id).toInt());
1856 if (wpagui->ctrlRequest(cmd, reply, &reply_len) < 0 ||
1857 memcmp(reply, "FAIL", 4) == 0) {
1859 msg.setIcon(QMessageBox::Warning);
1860 msg.setText(tr("Failed to invite peer to start persistent "
1867 void Peers::ctx_p2p_delete()
1869 if (ctx_item == NULL)
1871 model.removeRow(ctx_item->row());
1875 void Peers::enable_persistent(int id)
1877 if (model.rowCount() == 0)
1880 QModelIndexList lst = model.match(model.index(0, 0),
1881 peer_role_network_id, id);
1882 for (int i = 0; i < lst.size(); i++) {
1883 QStandardItem *item = model.itemFromIndex(lst[i]);
1884 int type = item->data(peer_role_type).toInt();
1885 if (type == PEER_TYPE_P2P_PERSISTENT_GROUP_GO ||
1886 type == PEER_TYPE_P2P_PERSISTENT_GROUP_CLIENT)
1887 item->setBackground(Qt::NoBrush);