peers.cpp 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799
  1. /*
  2. * wpa_gui - Peers class
  3. * Copyright (c) 2009, Atheros Communications
  4. *
  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.
  8. *
  9. * Alternatively, this software may be distributed under the terms of BSD
  10. * license.
  11. *
  12. * See README and COPYING for more details.
  13. */
  14. #include <cstdio>
  15. #include <QImageReader>
  16. #include <QMessageBox>
  17. #include "wpa_ctrl.h"
  18. #include "wpagui.h"
  19. #include "stringquery.h"
  20. #include "peers.h"
  21. enum {
  22. peer_role_address = Qt::UserRole + 1,
  23. peer_role_type,
  24. peer_role_uuid,
  25. peer_role_details,
  26. peer_role_pri_dev_type,
  27. peer_role_ssid,
  28. peer_role_config_methods,
  29. peer_role_dev_passwd_id
  30. };
  31. /*
  32. * TODO:
  33. * - add current AP info (e.g., from WPS) in station mode
  34. */
  35. enum peer_type {
  36. PEER_TYPE_ASSOCIATED_STATION,
  37. PEER_TYPE_AP,
  38. PEER_TYPE_AP_WPS,
  39. PEER_TYPE_WPS_PIN_NEEDED,
  40. PEER_TYPE_WPS_ER_AP,
  41. PEER_TYPE_WPS_ER_AP_UNCONFIGURED,
  42. PEER_TYPE_WPS_ER_ENROLLEE
  43. };
  44. Peers::Peers(QWidget *parent, const char *, bool, Qt::WFlags)
  45. : QDialog(parent)
  46. {
  47. setupUi(this);
  48. if (QImageReader::supportedImageFormats().contains(QByteArray("svg")))
  49. {
  50. default_icon = new QIcon(":/icons/wpa_gui.svg");
  51. ap_icon = new QIcon(":/icons/ap.svg");
  52. laptop_icon = new QIcon(":/icons/laptop.svg");
  53. } else {
  54. default_icon = new QIcon(":/icons/wpa_gui.png");
  55. ap_icon = new QIcon(":/icons/ap.png");
  56. laptop_icon = new QIcon(":/icons/laptop.png");
  57. }
  58. peers->setModel(&model);
  59. peers->setResizeMode(QListView::Adjust);
  60. peers->setContextMenuPolicy(Qt::CustomContextMenu);
  61. connect(peers, SIGNAL(customContextMenuRequested(const QPoint &)),
  62. this, SLOT(context_menu(const QPoint &)));
  63. wpagui = NULL;
  64. }
  65. void Peers::setWpaGui(WpaGui *_wpagui)
  66. {
  67. wpagui = _wpagui;
  68. update_peers();
  69. }
  70. Peers::~Peers()
  71. {
  72. delete default_icon;
  73. delete ap_icon;
  74. delete laptop_icon;
  75. }
  76. void Peers::languageChange()
  77. {
  78. retranslateUi(this);
  79. }
  80. QString Peers::ItemType(int type)
  81. {
  82. QString title;
  83. switch (type) {
  84. case PEER_TYPE_ASSOCIATED_STATION:
  85. title = tr("Associated station");
  86. break;
  87. case PEER_TYPE_AP:
  88. title = tr("AP");
  89. break;
  90. case PEER_TYPE_AP_WPS:
  91. title = tr("WPS AP");
  92. break;
  93. case PEER_TYPE_WPS_PIN_NEEDED:
  94. title = tr("WPS PIN needed");
  95. break;
  96. case PEER_TYPE_WPS_ER_AP:
  97. title = tr("ER: WPS AP");
  98. break;
  99. case PEER_TYPE_WPS_ER_AP_UNCONFIGURED:
  100. title = tr("ER: WPS AP (Unconfigured)");
  101. break;
  102. case PEER_TYPE_WPS_ER_ENROLLEE:
  103. title = tr("ER: WPS Enrollee");
  104. break;
  105. }
  106. return title;
  107. }
  108. void Peers::context_menu(const QPoint &pos)
  109. {
  110. QMenu *menu = new QMenu;
  111. if (menu == NULL)
  112. return;
  113. QModelIndex idx = peers->indexAt(pos);
  114. if (idx.isValid()) {
  115. ctx_item = model.itemFromIndex(idx);
  116. int type = ctx_item->data(peer_role_type).toInt();
  117. menu->addAction(Peers::ItemType(type))->setEnabled(false);
  118. menu->addSeparator();
  119. int config_methods = -1;
  120. QVariant var = ctx_item->data(peer_role_config_methods);
  121. if (var.isValid())
  122. config_methods = var.toInt();
  123. if ((type == PEER_TYPE_ASSOCIATED_STATION ||
  124. type == PEER_TYPE_AP_WPS ||
  125. type == PEER_TYPE_WPS_PIN_NEEDED ||
  126. type == PEER_TYPE_WPS_ER_ENROLLEE) &&
  127. (config_methods == -1 || (config_methods & 0x010c))) {
  128. menu->addAction(tr("Enter WPS PIN"), this,
  129. SLOT(enter_pin()));
  130. }
  131. if (type == PEER_TYPE_AP_WPS) {
  132. menu->addAction(tr("Connect (PBC)"), this,
  133. SLOT(connect_pbc()));
  134. }
  135. if ((type == PEER_TYPE_ASSOCIATED_STATION ||
  136. type == PEER_TYPE_WPS_ER_ENROLLEE) &&
  137. config_methods >= 0 && (config_methods & 0x0080)) {
  138. menu->addAction(tr("Enroll (PBC)"), this,
  139. SLOT(connect_pbc()));
  140. }
  141. menu->addAction(tr("Properties"), this, SLOT(properties()));
  142. } else {
  143. ctx_item = NULL;
  144. menu->addAction(QString("Refresh"), this, SLOT(ctx_refresh()));
  145. }
  146. menu->exec(peers->mapToGlobal(pos));
  147. }
  148. void Peers::enter_pin()
  149. {
  150. if (ctx_item == NULL)
  151. return;
  152. int peer_type = ctx_item->data(peer_role_type).toInt();
  153. QString uuid;
  154. QString addr;
  155. if (peer_type == PEER_TYPE_WPS_ER_ENROLLEE)
  156. uuid = ctx_item->data(peer_role_uuid).toString();
  157. else
  158. addr = ctx_item->data(peer_role_address).toString();
  159. StringQuery input(tr("PIN:"));
  160. input.setWindowTitle(tr("PIN for ") + ctx_item->text());
  161. if (input.exec() != QDialog::Accepted)
  162. return;
  163. char cmd[100];
  164. char reply[100];
  165. size_t reply_len;
  166. if (peer_type == PEER_TYPE_WPS_ER_ENROLLEE) {
  167. snprintf(cmd, sizeof(cmd), "WPS_ER_PIN %s %s",
  168. uuid.toAscii().constData(),
  169. input.get_string().toAscii().constData());
  170. } else {
  171. snprintf(cmd, sizeof(cmd), "WPS_PIN %s %s",
  172. addr.toAscii().constData(),
  173. input.get_string().toAscii().constData());
  174. }
  175. reply_len = sizeof(reply) - 1;
  176. if (wpagui->ctrlRequest(cmd, reply, &reply_len) < 0) {
  177. QMessageBox msg;
  178. msg.setIcon(QMessageBox::Warning);
  179. msg.setText("Failed to set the WPS PIN.");
  180. msg.exec();
  181. }
  182. }
  183. void Peers::ctx_refresh()
  184. {
  185. update_peers();
  186. }
  187. void Peers::add_station(QString info)
  188. {
  189. QStringList lines = info.split(QRegExp("\\n"));
  190. QString name;
  191. for (QStringList::Iterator it = lines.begin();
  192. it != lines.end(); it++) {
  193. int pos = (*it).indexOf('=') + 1;
  194. if (pos < 1)
  195. continue;
  196. if ((*it).startsWith("wpsDeviceName="))
  197. name = (*it).mid(pos);
  198. }
  199. if (name.isEmpty())
  200. name = lines[0];
  201. QStandardItem *item = new QStandardItem(*laptop_icon, name);
  202. if (item) {
  203. item->setData(lines[0], peer_role_address);
  204. item->setData(PEER_TYPE_ASSOCIATED_STATION,
  205. peer_role_type);
  206. item->setData(info, peer_role_details);
  207. item->setToolTip(ItemType(PEER_TYPE_ASSOCIATED_STATION));
  208. model.appendRow(item);
  209. }
  210. }
  211. void Peers::add_stations()
  212. {
  213. char reply[2048];
  214. size_t reply_len;
  215. char cmd[30];
  216. int res;
  217. reply_len = sizeof(reply) - 1;
  218. if (wpagui->ctrlRequest("STA-FIRST", reply, &reply_len) < 0)
  219. return;
  220. do {
  221. reply[reply_len] = '\0';
  222. QString info(reply);
  223. char *txt = reply;
  224. while (*txt != '\0' && *txt != '\n')
  225. txt++;
  226. *txt++ = '\0';
  227. if (strncmp(reply, "FAIL", 4) == 0 ||
  228. strncmp(reply, "UNKNOWN", 7) == 0)
  229. break;
  230. add_station(info);
  231. reply_len = sizeof(reply) - 1;
  232. snprintf(cmd, sizeof(cmd), "STA-NEXT %s", reply);
  233. res = wpagui->ctrlRequest(cmd, reply, &reply_len);
  234. } while (res >= 0);
  235. }
  236. void Peers::add_single_station(const char *addr)
  237. {
  238. char reply[2048];
  239. size_t reply_len;
  240. char cmd[30];
  241. reply_len = sizeof(reply) - 1;
  242. snprintf(cmd, sizeof(cmd), "STA %s", addr);
  243. if (wpagui->ctrlRequest(cmd, reply, &reply_len) < 0)
  244. return;
  245. reply[reply_len] = '\0';
  246. QString info(reply);
  247. char *txt = reply;
  248. while (*txt != '\0' && *txt != '\n')
  249. txt++;
  250. *txt++ = '\0';
  251. if (strncmp(reply, "FAIL", 4) == 0 ||
  252. strncmp(reply, "UNKNOWN", 7) == 0)
  253. return;
  254. add_station(info);
  255. }
  256. void Peers::add_scan_results()
  257. {
  258. char reply[2048];
  259. size_t reply_len;
  260. int index;
  261. char cmd[20];
  262. index = 0;
  263. while (wpagui) {
  264. snprintf(cmd, sizeof(cmd), "BSS %d", index++);
  265. if (index > 1000)
  266. break;
  267. reply_len = sizeof(reply) - 1;
  268. if (wpagui->ctrlRequest(cmd, reply, &reply_len) < 0)
  269. break;
  270. reply[reply_len] = '\0';
  271. QString bss(reply);
  272. if (bss.isEmpty() || bss.startsWith("FAIL"))
  273. break;
  274. QString ssid, bssid, flags, wps_name, pri_dev_type;
  275. QStringList lines = bss.split(QRegExp("\\n"));
  276. for (QStringList::Iterator it = lines.begin();
  277. it != lines.end(); it++) {
  278. int pos = (*it).indexOf('=') + 1;
  279. if (pos < 1)
  280. continue;
  281. if ((*it).startsWith("bssid="))
  282. bssid = (*it).mid(pos);
  283. else if ((*it).startsWith("flags="))
  284. flags = (*it).mid(pos);
  285. else if ((*it).startsWith("ssid="))
  286. ssid = (*it).mid(pos);
  287. else if ((*it).startsWith("wps_device_name="))
  288. wps_name = (*it).mid(pos);
  289. else if ((*it).startsWith("wps_primary_device_type="))
  290. pri_dev_type = (*it).mid(pos);
  291. }
  292. QString name = wps_name;
  293. if (name.isEmpty())
  294. name = ssid + "\n" + bssid;
  295. QStandardItem *item = new QStandardItem(*ap_icon, name);
  296. if (item) {
  297. item->setData(bssid, peer_role_address);
  298. int type;
  299. if (flags.contains("[WPS"))
  300. type = PEER_TYPE_AP_WPS;
  301. else
  302. type = PEER_TYPE_AP;
  303. item->setData(type, peer_role_type);
  304. for (int i = 0; i < lines.size(); i++) {
  305. if (lines[i].length() > 60) {
  306. lines[i].remove(
  307. 60, lines[i].length());
  308. lines[i] += "..";
  309. }
  310. }
  311. item->setToolTip(ItemType(type));
  312. item->setData(lines.join("\n"), peer_role_details);
  313. if (!pri_dev_type.isEmpty())
  314. item->setData(pri_dev_type,
  315. peer_role_pri_dev_type);
  316. if (!ssid.isEmpty())
  317. item->setData(ssid, peer_role_ssid);
  318. model.appendRow(item);
  319. }
  320. }
  321. }
  322. void Peers::update_peers()
  323. {
  324. model.clear();
  325. if (wpagui == NULL)
  326. return;
  327. char reply[20];
  328. size_t replylen = sizeof(reply) - 1;
  329. wpagui->ctrlRequest("WPS_ER_START", reply, &replylen);
  330. add_stations();
  331. add_scan_results();
  332. }
  333. QStandardItem * Peers::find_addr(QString addr)
  334. {
  335. if (model.rowCount() == 0)
  336. return NULL;
  337. QModelIndexList lst = model.match(model.index(0, 0), peer_role_address,
  338. addr);
  339. if (lst.size() == 0)
  340. return NULL;
  341. return model.itemFromIndex(lst[0]);
  342. }
  343. QStandardItem * Peers::find_uuid(QString uuid)
  344. {
  345. if (model.rowCount() == 0)
  346. return NULL;
  347. QModelIndexList lst = model.match(model.index(0, 0), peer_role_uuid,
  348. uuid);
  349. if (lst.size() == 0)
  350. return NULL;
  351. return model.itemFromIndex(lst[0]);
  352. }
  353. void Peers::event_notify(WpaMsg msg)
  354. {
  355. QString text = msg.getMsg();
  356. if (text.startsWith(WPS_EVENT_PIN_NEEDED)) {
  357. /*
  358. * WPS-PIN-NEEDED 5a02a5fa-9199-5e7c-bc46-e183d3cb32f7
  359. * 02:2a:c4:18:5b:f3
  360. * [Wireless Client|Company|cmodel|123|12345|1-0050F204-1]
  361. */
  362. QStringList items = text.split(' ');
  363. QString uuid = items[1];
  364. QString addr = items[2];
  365. QString name = "";
  366. QStandardItem *item = find_addr(addr);
  367. if (item)
  368. return;
  369. int pos = text.indexOf('[');
  370. if (pos >= 0) {
  371. int pos2 = text.lastIndexOf(']');
  372. if (pos2 >= pos) {
  373. items = text.mid(pos + 1, pos2 - pos - 1).
  374. split('|');
  375. name = items[0];
  376. items.append(addr);
  377. }
  378. }
  379. item = new QStandardItem(*laptop_icon, name);
  380. if (item) {
  381. item->setData(addr, peer_role_address);
  382. item->setData(PEER_TYPE_WPS_PIN_NEEDED,
  383. peer_role_type);
  384. item->setToolTip(ItemType(PEER_TYPE_WPS_PIN_NEEDED));
  385. item->setData(items.join("\n"), peer_role_details);
  386. item->setData(items[5], peer_role_pri_dev_type);
  387. model.appendRow(item);
  388. }
  389. return;
  390. }
  391. if (text.startsWith(AP_STA_CONNECTED)) {
  392. /* AP-STA-CONNECTED 02:2a:c4:18:5b:f3 */
  393. QStringList items = text.split(' ');
  394. QString addr = items[1];
  395. QStandardItem *item = find_addr(addr);
  396. if (item == NULL || item->data(peer_role_type).toInt() !=
  397. PEER_TYPE_ASSOCIATED_STATION)
  398. add_single_station(addr.toAscii().constData());
  399. return;
  400. }
  401. if (text.startsWith(AP_STA_DISCONNECTED)) {
  402. /* AP-STA-DISCONNECTED 02:2a:c4:18:5b:f3 */
  403. QStringList items = text.split(' ');
  404. QString addr = items[1];
  405. if (model.rowCount() == 0)
  406. return;
  407. QModelIndexList lst = model.match(model.index(0, 0),
  408. peer_role_address, addr);
  409. for (int i = 0; i < lst.size(); i++) {
  410. QStandardItem *item = model.itemFromIndex(lst[i]);
  411. if (item && item->data(peer_role_type).toInt() ==
  412. PEER_TYPE_ASSOCIATED_STATION)
  413. model.removeRow(lst[i].row());
  414. }
  415. return;
  416. }
  417. if (text.startsWith(WPS_EVENT_ER_AP_ADD)) {
  418. /*
  419. * WPS-ER-AP-ADD 87654321-9abc-def0-1234-56789abc0002
  420. * 02:11:22:33:44:55 pri_dev_type=6-0050F204-1 wps_state=1
  421. * |Very friendly name|Company|Long description of the model|
  422. * WAP|http://w1.fi/|http://w1.fi/hostapd/
  423. */
  424. QStringList items = text.split(' ');
  425. if (items.size() < 5)
  426. return;
  427. QString uuid = items[1];
  428. QString addr = items[2];
  429. QString pri_dev_type = items[3].mid(13);
  430. int wps_state = items[4].mid(10).toInt();
  431. int pos = text.indexOf('|');
  432. if (pos < 0)
  433. return;
  434. items = text.mid(pos + 1).split('|');
  435. if (items.size() < 1)
  436. return;
  437. QStandardItem *item = find_uuid(uuid);
  438. if (item)
  439. return;
  440. item = new QStandardItem(*ap_icon, items[0]);
  441. if (item) {
  442. item->setData(uuid, peer_role_uuid);
  443. item->setData(addr, peer_role_address);
  444. int type = wps_state == 2 ? PEER_TYPE_WPS_ER_AP:
  445. PEER_TYPE_WPS_ER_AP_UNCONFIGURED;
  446. item->setData(type, peer_role_type);
  447. item->setToolTip(ItemType(type));
  448. item->setData(pri_dev_type, peer_role_pri_dev_type);
  449. item->setData(items.join(QString("\n")),
  450. peer_role_details);
  451. model.appendRow(item);
  452. }
  453. return;
  454. }
  455. if (text.startsWith(WPS_EVENT_ER_AP_REMOVE)) {
  456. /* WPS-ER-AP-REMOVE 87654321-9abc-def0-1234-56789abc0002 */
  457. QStringList items = text.split(' ');
  458. if (items.size() < 2)
  459. return;
  460. if (model.rowCount() == 0)
  461. return;
  462. QModelIndexList lst = model.match(model.index(0, 0),
  463. peer_role_uuid, items[1]);
  464. for (int i = 0; i < lst.size(); i++) {
  465. QStandardItem *item = model.itemFromIndex(lst[i]);
  466. if (item &&
  467. (item->data(peer_role_type).toInt() ==
  468. PEER_TYPE_WPS_ER_AP ||
  469. item->data(peer_role_type).toInt() ==
  470. PEER_TYPE_WPS_ER_AP_UNCONFIGURED))
  471. model.removeRow(lst[i].row());
  472. }
  473. return;
  474. }
  475. if (text.startsWith(WPS_EVENT_ER_ENROLLEE_ADD)) {
  476. /*
  477. * WPS-ER-ENROLLEE-ADD 2b7093f1-d6fb-5108-adbb-bea66bb87333
  478. * 02:66:a0:ee:17:27 M1=1 config_methods=0x14d dev_passwd_id=0
  479. * pri_dev_type=1-0050F204-1
  480. * |Wireless Client|Company|cmodel|123|12345|
  481. */
  482. QStringList items = text.split(' ');
  483. if (items.size() < 3)
  484. return;
  485. QString uuid = items[1];
  486. QString addr = items[2];
  487. QString pri_dev_type = items[6].mid(13);
  488. int config_methods = -1;
  489. int dev_passwd_id = -1;
  490. for (int i = 3; i < items.size(); i++) {
  491. int pos = items[i].indexOf('=') + 1;
  492. if (pos < 1)
  493. continue;
  494. QString val = items[i].mid(pos);
  495. if (items[i].startsWith("config_methods=")) {
  496. config_methods = val.toInt(0, 0);
  497. } else if (items[i].startsWith("dev_passwd_id=")) {
  498. dev_passwd_id = val.toInt();
  499. }
  500. }
  501. int pos = text.indexOf('|');
  502. if (pos < 0)
  503. return;
  504. items = text.mid(pos + 1).split('|');
  505. if (items.size() < 1)
  506. return;
  507. QString name = items[0];
  508. if (name.length() == 0)
  509. name = addr;
  510. remove_enrollee_uuid(uuid);
  511. QStandardItem *item;
  512. item = new QStandardItem(*laptop_icon, name);
  513. if (item) {
  514. item->setData(uuid, peer_role_uuid);
  515. item->setData(addr, peer_role_address);
  516. item->setData(PEER_TYPE_WPS_ER_ENROLLEE,
  517. peer_role_type);
  518. item->setToolTip(ItemType(PEER_TYPE_WPS_ER_ENROLLEE));
  519. item->setData(items.join(QString("\n")),
  520. peer_role_details);
  521. item->setData(pri_dev_type, peer_role_pri_dev_type);
  522. if (config_methods >= 0)
  523. item->setData(config_methods,
  524. peer_role_config_methods);
  525. if (dev_passwd_id >= 0)
  526. item->setData(dev_passwd_id,
  527. peer_role_dev_passwd_id);
  528. model.appendRow(item);
  529. }
  530. return;
  531. }
  532. if (text.startsWith(WPS_EVENT_ER_ENROLLEE_REMOVE)) {
  533. /*
  534. * WPS-ER-ENROLLEE-REMOVE 2b7093f1-d6fb-5108-adbb-bea66bb87333
  535. * 02:66:a0:ee:17:27
  536. */
  537. QStringList items = text.split(' ');
  538. if (items.size() < 2)
  539. return;
  540. remove_enrollee_uuid(items[1]);
  541. return;
  542. }
  543. }
  544. void Peers::closeEvent(QCloseEvent *)
  545. {
  546. if (wpagui) {
  547. char reply[20];
  548. size_t replylen = sizeof(reply) - 1;
  549. wpagui->ctrlRequest("WPS_ER_STOP", reply, &replylen);
  550. }
  551. }
  552. void Peers::done(int r)
  553. {
  554. QDialog::done(r);
  555. close();
  556. }
  557. void Peers::remove_enrollee_uuid(QString uuid)
  558. {
  559. if (model.rowCount() == 0)
  560. return;
  561. QModelIndexList lst = model.match(model.index(0, 0),
  562. peer_role_uuid, uuid);
  563. for (int i = 0; i < lst.size(); i++) {
  564. QStandardItem *item = model.itemFromIndex(lst[i]);
  565. if (item && item->data(peer_role_type).toInt() ==
  566. PEER_TYPE_WPS_ER_ENROLLEE)
  567. model.removeRow(lst[i].row());
  568. }
  569. }
  570. void Peers::properties()
  571. {
  572. if (ctx_item == NULL)
  573. return;
  574. QMessageBox msg(this);
  575. msg.setStandardButtons(QMessageBox::Ok);
  576. msg.setDefaultButton(QMessageBox::Ok);
  577. msg.setEscapeButton(QMessageBox::Ok);
  578. msg.setWindowTitle(tr("Peer Properties"));
  579. int type = ctx_item->data(peer_role_type).toInt();
  580. QString title = Peers::ItemType(type);
  581. msg.setText(title + QString("\n") + tr("Name: ") + ctx_item->text());
  582. QVariant var;
  583. QString info;
  584. var = ctx_item->data(peer_role_address);
  585. if (var.isValid())
  586. info += tr("Address: ") + var.toString() + QString("\n");
  587. var = ctx_item->data(peer_role_uuid);
  588. if (var.isValid())
  589. info += tr("UUID: ") + var.toString() + QString("\n");
  590. var = ctx_item->data(peer_role_pri_dev_type);
  591. if (var.isValid())
  592. info += tr("Primary Device Type: ") + var.toString() +
  593. QString("\n");
  594. var = ctx_item->data(peer_role_ssid);
  595. if (var.isValid())
  596. info += tr("SSID: ") + var.toString() + QString("\n");
  597. var = ctx_item->data(peer_role_config_methods);
  598. if (var.isValid()) {
  599. int methods = var.toInt();
  600. info += tr("Configuration Methods: ");
  601. if (methods & 0x0001)
  602. info += tr("[USBA]");
  603. if (methods & 0x0002)
  604. info += tr("[Ethernet]");
  605. if (methods & 0x0004)
  606. info += tr("[Label]");
  607. if (methods & 0x0008)
  608. info += tr("[Display]");
  609. if (methods & 0x0010)
  610. info += tr("[Ext. NFC Token]");
  611. if (methods & 0x0020)
  612. info += tr("[Int. NFC Token]");
  613. if (methods & 0x0040)
  614. info += tr("[NFC Interface]");
  615. if (methods & 0x0080)
  616. info += tr("[Push Button]");
  617. if (methods & 0x0100)
  618. info += tr("[Keypad]");
  619. info += "\n";
  620. }
  621. var = ctx_item->data(peer_role_dev_passwd_id);
  622. if (var.isValid()) {
  623. info += tr("Device Password ID: ") + var.toString();
  624. switch (var.toInt()) {
  625. case 0:
  626. info += tr(" (Default PIN)");
  627. break;
  628. case 1:
  629. info += tr(" (User-specified PIN)");
  630. break;
  631. case 2:
  632. info += tr(" (Machine-specified PIN)");
  633. break;
  634. case 3:
  635. info += tr(" (Rekey)");
  636. break;
  637. case 4:
  638. info += tr(" (Push Button)");
  639. break;
  640. case 5:
  641. info += tr(" (Registrar-specified)");
  642. break;
  643. }
  644. info += "\n";
  645. }
  646. msg.setInformativeText(info);
  647. var = ctx_item->data(peer_role_details);
  648. if (var.isValid())
  649. msg.setDetailedText(var.toString());
  650. msg.exec();
  651. }
  652. void Peers::connect_pbc()
  653. {
  654. if (ctx_item == NULL)
  655. return;
  656. char cmd[100];
  657. char reply[100];
  658. size_t reply_len;
  659. int peer_type = ctx_item->data(peer_role_type).toInt();
  660. if (peer_type == PEER_TYPE_WPS_ER_ENROLLEE) {
  661. snprintf(cmd, sizeof(cmd), "WPS_ER_PBC %s",
  662. ctx_item->data(peer_role_uuid).toString().toAscii().
  663. constData());
  664. } else {
  665. snprintf(cmd, sizeof(cmd), "WPS_PBC");
  666. }
  667. reply_len = sizeof(reply) - 1;
  668. if (wpagui->ctrlRequest(cmd, reply, &reply_len) < 0) {
  669. QMessageBox msg;
  670. msg.setIcon(QMessageBox::Warning);
  671. msg.setText("Failed to start WPS PBC.");
  672. msg.exec();
  673. }
  674. }