peers.cpp 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756
  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. if (type == PEER_TYPE_ASSOCIATED_STATION ||
  120. type == PEER_TYPE_AP_WPS ||
  121. type == PEER_TYPE_WPS_PIN_NEEDED ||
  122. type == PEER_TYPE_WPS_ER_ENROLLEE) {
  123. /* TODO: only for peers that are requesting WPS PIN
  124. * method */
  125. menu->addAction(tr("Enter WPS PIN"), this,
  126. SLOT(enter_pin()));
  127. }
  128. menu->addAction(tr("Properties"), this, SLOT(properties()));
  129. } else {
  130. ctx_item = NULL;
  131. menu->addAction(QString("Refresh"), this, SLOT(ctx_refresh()));
  132. }
  133. menu->exec(peers->mapToGlobal(pos));
  134. }
  135. void Peers::enter_pin()
  136. {
  137. if (ctx_item == NULL)
  138. return;
  139. int peer_type = ctx_item->data(peer_role_type).toInt();
  140. QString uuid;
  141. QString addr;
  142. if (peer_type == PEER_TYPE_WPS_ER_ENROLLEE)
  143. uuid = ctx_item->data(peer_role_uuid).toString();
  144. else
  145. addr = ctx_item->data(peer_role_address).toString();
  146. StringQuery input(tr("PIN:"));
  147. input.setWindowTitle(tr("PIN for ") + ctx_item->text());
  148. if (input.exec() != QDialog::Accepted)
  149. return;
  150. char cmd[100];
  151. char reply[100];
  152. size_t reply_len;
  153. if (peer_type == PEER_TYPE_WPS_ER_ENROLLEE) {
  154. snprintf(cmd, sizeof(cmd), "WPS_ER_PIN %s %s",
  155. uuid.toAscii().constData(),
  156. input.get_string().toAscii().constData());
  157. } else {
  158. snprintf(cmd, sizeof(cmd), "WPS_PIN %s %s",
  159. addr.toAscii().constData(),
  160. input.get_string().toAscii().constData());
  161. }
  162. reply_len = sizeof(reply) - 1;
  163. if (wpagui->ctrlRequest(cmd, reply, &reply_len) < 0) {
  164. QMessageBox msg;
  165. msg.setIcon(QMessageBox::Warning);
  166. msg.setText("Failed to set the WPS PIN.");
  167. msg.exec();
  168. }
  169. }
  170. void Peers::ctx_refresh()
  171. {
  172. update_peers();
  173. }
  174. void Peers::add_station(QString info)
  175. {
  176. QStringList lines = info.split(QRegExp("\\n"));
  177. QString name;
  178. for (QStringList::Iterator it = lines.begin();
  179. it != lines.end(); it++) {
  180. int pos = (*it).indexOf('=') + 1;
  181. if (pos < 1)
  182. continue;
  183. if ((*it).startsWith("wpsDeviceName="))
  184. name = (*it).mid(pos);
  185. }
  186. if (name.isEmpty())
  187. name = lines[0];
  188. QStandardItem *item = new QStandardItem(*laptop_icon, name);
  189. if (item) {
  190. item->setData(lines[0], peer_role_address);
  191. item->setData(PEER_TYPE_ASSOCIATED_STATION,
  192. peer_role_type);
  193. item->setData(info, peer_role_details);
  194. item->setToolTip(ItemType(PEER_TYPE_ASSOCIATED_STATION));
  195. model.appendRow(item);
  196. }
  197. }
  198. void Peers::add_stations()
  199. {
  200. char reply[2048];
  201. size_t reply_len;
  202. char cmd[30];
  203. int res;
  204. reply_len = sizeof(reply) - 1;
  205. if (wpagui->ctrlRequest("STA-FIRST", reply, &reply_len) < 0)
  206. return;
  207. do {
  208. reply[reply_len] = '\0';
  209. QString info(reply);
  210. char *txt = reply;
  211. while (*txt != '\0' && *txt != '\n')
  212. txt++;
  213. *txt++ = '\0';
  214. if (strncmp(reply, "FAIL", 4) == 0 ||
  215. strncmp(reply, "UNKNOWN", 7) == 0)
  216. break;
  217. add_station(info);
  218. reply_len = sizeof(reply) - 1;
  219. snprintf(cmd, sizeof(cmd), "STA-NEXT %s", reply);
  220. res = wpagui->ctrlRequest(cmd, reply, &reply_len);
  221. } while (res >= 0);
  222. }
  223. void Peers::add_single_station(const char *addr)
  224. {
  225. char reply[2048];
  226. size_t reply_len;
  227. char cmd[30];
  228. reply_len = sizeof(reply) - 1;
  229. snprintf(cmd, sizeof(cmd), "STA %s", addr);
  230. if (wpagui->ctrlRequest(cmd, reply, &reply_len) < 0)
  231. return;
  232. reply[reply_len] = '\0';
  233. QString info(reply);
  234. char *txt = reply;
  235. while (*txt != '\0' && *txt != '\n')
  236. txt++;
  237. *txt++ = '\0';
  238. if (strncmp(reply, "FAIL", 4) == 0 ||
  239. strncmp(reply, "UNKNOWN", 7) == 0)
  240. return;
  241. add_station(info);
  242. }
  243. void Peers::add_scan_results()
  244. {
  245. char reply[2048];
  246. size_t reply_len;
  247. int index;
  248. char cmd[20];
  249. index = 0;
  250. while (wpagui) {
  251. snprintf(cmd, sizeof(cmd), "BSS %d", index++);
  252. if (index > 1000)
  253. break;
  254. reply_len = sizeof(reply) - 1;
  255. if (wpagui->ctrlRequest(cmd, reply, &reply_len) < 0)
  256. break;
  257. reply[reply_len] = '\0';
  258. QString bss(reply);
  259. if (bss.isEmpty() || bss.startsWith("FAIL"))
  260. break;
  261. QString ssid, bssid, flags, wps_name, pri_dev_type;
  262. QStringList lines = bss.split(QRegExp("\\n"));
  263. for (QStringList::Iterator it = lines.begin();
  264. it != lines.end(); it++) {
  265. int pos = (*it).indexOf('=') + 1;
  266. if (pos < 1)
  267. continue;
  268. if ((*it).startsWith("bssid="))
  269. bssid = (*it).mid(pos);
  270. else if ((*it).startsWith("flags="))
  271. flags = (*it).mid(pos);
  272. else if ((*it).startsWith("ssid="))
  273. ssid = (*it).mid(pos);
  274. else if ((*it).startsWith("wps_device_name="))
  275. wps_name = (*it).mid(pos);
  276. else if ((*it).startsWith("wps_primary_device_type="))
  277. pri_dev_type = (*it).mid(pos);
  278. }
  279. QString name = wps_name;
  280. if (name.isEmpty())
  281. name = ssid + "\n" + bssid;
  282. QStandardItem *item = new QStandardItem(*ap_icon, name);
  283. if (item) {
  284. item->setData(bssid, peer_role_address);
  285. int type;
  286. if (flags.contains("[WPS"))
  287. type = PEER_TYPE_AP_WPS;
  288. else
  289. type = PEER_TYPE_AP;
  290. item->setData(type, peer_role_type);
  291. for (int i = 0; i < lines.size(); i++) {
  292. if (lines[i].length() > 60) {
  293. lines[i].remove(
  294. 60, lines[i].length());
  295. lines[i] += "..";
  296. }
  297. }
  298. item->setToolTip(ItemType(type));
  299. item->setData(lines.join("\n"), peer_role_details);
  300. if (!pri_dev_type.isEmpty())
  301. item->setData(pri_dev_type,
  302. peer_role_pri_dev_type);
  303. if (!ssid.isEmpty())
  304. item->setData(ssid, peer_role_ssid);
  305. model.appendRow(item);
  306. }
  307. }
  308. }
  309. void Peers::update_peers()
  310. {
  311. model.clear();
  312. if (wpagui == NULL)
  313. return;
  314. char reply[20];
  315. size_t replylen = sizeof(reply) - 1;
  316. wpagui->ctrlRequest("WPS_ER_START", reply, &replylen);
  317. add_stations();
  318. add_scan_results();
  319. }
  320. QStandardItem * Peers::find_addr(QString addr)
  321. {
  322. if (model.rowCount() == 0)
  323. return NULL;
  324. QModelIndexList lst = model.match(model.index(0, 0), peer_role_address,
  325. addr);
  326. if (lst.size() == 0)
  327. return NULL;
  328. return model.itemFromIndex(lst[0]);
  329. }
  330. QStandardItem * Peers::find_uuid(QString uuid)
  331. {
  332. if (model.rowCount() == 0)
  333. return NULL;
  334. QModelIndexList lst = model.match(model.index(0, 0), peer_role_uuid,
  335. uuid);
  336. if (lst.size() == 0)
  337. return NULL;
  338. return model.itemFromIndex(lst[0]);
  339. }
  340. void Peers::event_notify(WpaMsg msg)
  341. {
  342. QString text = msg.getMsg();
  343. if (text.startsWith(WPS_EVENT_PIN_NEEDED)) {
  344. /*
  345. * WPS-PIN-NEEDED 5a02a5fa-9199-5e7c-bc46-e183d3cb32f7
  346. * 02:2a:c4:18:5b:f3
  347. * [Wireless Client|Company|cmodel|123|12345|1-0050F204-1]
  348. */
  349. QStringList items = text.split(' ');
  350. QString uuid = items[1];
  351. QString addr = items[2];
  352. QString name = "";
  353. QStandardItem *item = find_addr(addr);
  354. if (item)
  355. return;
  356. int pos = text.indexOf('[');
  357. if (pos >= 0) {
  358. int pos2 = text.lastIndexOf(']');
  359. if (pos2 >= pos) {
  360. items = text.mid(pos + 1, pos2 - pos - 1).
  361. split('|');
  362. name = items[0];
  363. items.append(addr);
  364. }
  365. }
  366. item = new QStandardItem(*laptop_icon, name);
  367. if (item) {
  368. item->setData(addr, peer_role_address);
  369. item->setData(PEER_TYPE_WPS_PIN_NEEDED,
  370. peer_role_type);
  371. item->setToolTip(ItemType(PEER_TYPE_WPS_PIN_NEEDED));
  372. item->setData(items.join("\n"), peer_role_details);
  373. item->setData(items[5], peer_role_pri_dev_type);
  374. model.appendRow(item);
  375. }
  376. return;
  377. }
  378. if (text.startsWith(AP_STA_CONNECTED)) {
  379. /* AP-STA-CONNECTED 02:2a:c4:18:5b:f3 */
  380. QStringList items = text.split(' ');
  381. QString addr = items[1];
  382. QStandardItem *item = find_addr(addr);
  383. if (item == NULL || item->data(peer_role_type).toInt() !=
  384. PEER_TYPE_ASSOCIATED_STATION)
  385. add_single_station(addr.toAscii().constData());
  386. return;
  387. }
  388. if (text.startsWith(AP_STA_DISCONNECTED)) {
  389. /* AP-STA-DISCONNECTED 02:2a:c4:18:5b:f3 */
  390. QStringList items = text.split(' ');
  391. QString addr = items[1];
  392. if (model.rowCount() == 0)
  393. return;
  394. QModelIndexList lst = model.match(model.index(0, 0),
  395. peer_role_address, addr);
  396. for (int i = 0; i < lst.size(); i++) {
  397. QStandardItem *item = model.itemFromIndex(lst[i]);
  398. if (item && item->data(peer_role_type).toInt() ==
  399. PEER_TYPE_ASSOCIATED_STATION)
  400. model.removeRow(lst[i].row());
  401. }
  402. return;
  403. }
  404. if (text.startsWith(WPS_EVENT_ER_AP_ADD)) {
  405. /*
  406. * WPS-ER-AP-ADD 87654321-9abc-def0-1234-56789abc0002
  407. * 02:11:22:33:44:55 pri_dev_type=6-0050F204-1 wps_state=1
  408. * |Very friendly name|Company|Long description of the model|
  409. * WAP|http://w1.fi/|http://w1.fi/hostapd/
  410. */
  411. QStringList items = text.split(' ');
  412. if (items.size() < 5)
  413. return;
  414. QString uuid = items[1];
  415. QString addr = items[2];
  416. QString pri_dev_type = items[3].mid(13);
  417. int wps_state = items[4].mid(10).toInt();
  418. int pos = text.indexOf('|');
  419. if (pos < 0)
  420. return;
  421. items = text.mid(pos + 1).split('|');
  422. if (items.size() < 1)
  423. return;
  424. QStandardItem *item = find_uuid(uuid);
  425. if (item)
  426. return;
  427. item = new QStandardItem(*ap_icon, items[0]);
  428. if (item) {
  429. item->setData(uuid, peer_role_uuid);
  430. item->setData(addr, peer_role_address);
  431. int type = wps_state == 2 ? PEER_TYPE_WPS_ER_AP:
  432. PEER_TYPE_WPS_ER_AP_UNCONFIGURED;
  433. item->setData(type, peer_role_type);
  434. item->setToolTip(ItemType(type));
  435. item->setData(pri_dev_type, peer_role_pri_dev_type);
  436. item->setData(items.join(QString("\n")),
  437. peer_role_details);
  438. model.appendRow(item);
  439. }
  440. return;
  441. }
  442. if (text.startsWith(WPS_EVENT_ER_AP_REMOVE)) {
  443. /* WPS-ER-AP-REMOVE 87654321-9abc-def0-1234-56789abc0002 */
  444. QStringList items = text.split(' ');
  445. if (items.size() < 2)
  446. return;
  447. if (model.rowCount() == 0)
  448. return;
  449. QModelIndexList lst = model.match(model.index(0, 0),
  450. peer_role_uuid, items[1]);
  451. for (int i = 0; i < lst.size(); i++) {
  452. QStandardItem *item = model.itemFromIndex(lst[i]);
  453. if (item &&
  454. (item->data(peer_role_type).toInt() ==
  455. PEER_TYPE_WPS_ER_AP ||
  456. item->data(peer_role_type).toInt() ==
  457. PEER_TYPE_WPS_ER_AP_UNCONFIGURED))
  458. model.removeRow(lst[i].row());
  459. }
  460. return;
  461. }
  462. if (text.startsWith(WPS_EVENT_ER_ENROLLEE_ADD)) {
  463. /*
  464. * WPS-ER-ENROLLEE-ADD 2b7093f1-d6fb-5108-adbb-bea66bb87333
  465. * 02:66:a0:ee:17:27 M1=1 config_methods=0x14d dev_passwd_id=0
  466. * pri_dev_type=1-0050F204-1
  467. * |Wireless Client|Company|cmodel|123|12345|
  468. */
  469. QStringList items = text.split(' ');
  470. if (items.size() < 3)
  471. return;
  472. QString uuid = items[1];
  473. QString addr = items[2];
  474. QString pri_dev_type = items[6].mid(13);
  475. int config_methods = -1;
  476. int dev_passwd_id = -1;
  477. for (int i = 3; i < items.size(); i++) {
  478. int pos = items[i].indexOf('=') + 1;
  479. if (pos < 1)
  480. continue;
  481. QString val = items[i].mid(pos);
  482. if (items[i].startsWith("config_methods=")) {
  483. config_methods = val.toInt(0, 0);
  484. } else if (items[i].startsWith("dev_passwd_id=")) {
  485. dev_passwd_id = val.toInt();
  486. }
  487. }
  488. int pos = text.indexOf('|');
  489. if (pos < 0)
  490. return;
  491. items = text.mid(pos + 1).split('|');
  492. if (items.size() < 1)
  493. return;
  494. QString name = items[0];
  495. if (name.length() == 0)
  496. name = addr;
  497. remove_enrollee_uuid(uuid);
  498. QStandardItem *item;
  499. item = new QStandardItem(*laptop_icon, name);
  500. if (item) {
  501. item->setData(uuid, peer_role_uuid);
  502. item->setData(addr, peer_role_address);
  503. item->setData(PEER_TYPE_WPS_ER_ENROLLEE,
  504. peer_role_type);
  505. item->setToolTip(ItemType(PEER_TYPE_WPS_ER_ENROLLEE));
  506. item->setData(items.join(QString("\n")),
  507. peer_role_details);
  508. item->setData(pri_dev_type, peer_role_pri_dev_type);
  509. if (config_methods >= 0)
  510. item->setData(config_methods,
  511. peer_role_config_methods);
  512. if (dev_passwd_id >= 0)
  513. item->setData(dev_passwd_id,
  514. peer_role_dev_passwd_id);
  515. model.appendRow(item);
  516. }
  517. return;
  518. }
  519. if (text.startsWith(WPS_EVENT_ER_ENROLLEE_REMOVE)) {
  520. /*
  521. * WPS-ER-ENROLLEE-REMOVE 2b7093f1-d6fb-5108-adbb-bea66bb87333
  522. * 02:66:a0:ee:17:27
  523. */
  524. QStringList items = text.split(' ');
  525. if (items.size() < 2)
  526. return;
  527. remove_enrollee_uuid(items[1]);
  528. return;
  529. }
  530. }
  531. void Peers::closeEvent(QCloseEvent *)
  532. {
  533. if (wpagui) {
  534. char reply[20];
  535. size_t replylen = sizeof(reply) - 1;
  536. wpagui->ctrlRequest("WPS_ER_STOP", reply, &replylen);
  537. }
  538. }
  539. void Peers::done(int r)
  540. {
  541. QDialog::done(r);
  542. close();
  543. }
  544. void Peers::remove_enrollee_uuid(QString uuid)
  545. {
  546. if (model.rowCount() == 0)
  547. return;
  548. QModelIndexList lst = model.match(model.index(0, 0),
  549. peer_role_uuid, uuid);
  550. for (int i = 0; i < lst.size(); i++) {
  551. QStandardItem *item = model.itemFromIndex(lst[i]);
  552. if (item && item->data(peer_role_type).toInt() ==
  553. PEER_TYPE_WPS_ER_ENROLLEE)
  554. model.removeRow(lst[i].row());
  555. }
  556. }
  557. void Peers::properties()
  558. {
  559. if (ctx_item == NULL)
  560. return;
  561. QMessageBox msg(this);
  562. msg.setStandardButtons(QMessageBox::Ok);
  563. msg.setDefaultButton(QMessageBox::Ok);
  564. msg.setEscapeButton(QMessageBox::Ok);
  565. msg.setWindowTitle(tr("Peer Properties"));
  566. int type = ctx_item->data(peer_role_type).toInt();
  567. QString title = Peers::ItemType(type);
  568. msg.setText(title + QString("\n") + tr("Name: ") + ctx_item->text());
  569. QVariant var;
  570. QString info;
  571. var = ctx_item->data(peer_role_address);
  572. if (var.isValid())
  573. info += tr("Address: ") + var.toString() + QString("\n");
  574. var = ctx_item->data(peer_role_uuid);
  575. if (var.isValid())
  576. info += tr("UUID: ") + var.toString() + QString("\n");
  577. var = ctx_item->data(peer_role_pri_dev_type);
  578. if (var.isValid())
  579. info += tr("Primary Device Type: ") + var.toString() +
  580. QString("\n");
  581. var = ctx_item->data(peer_role_ssid);
  582. if (var.isValid())
  583. info += tr("SSID: ") + var.toString() + QString("\n");
  584. var = ctx_item->data(peer_role_config_methods);
  585. if (var.isValid()) {
  586. int methods = var.toInt();
  587. info += tr("Configuration Methods: ");
  588. if (methods & 0x0001)
  589. info += tr("[USBA]");
  590. if (methods & 0x0002)
  591. info += tr("[Ethernet]");
  592. if (methods & 0x0004)
  593. info += tr("[Label]");
  594. if (methods & 0x0008)
  595. info += tr("[Display]");
  596. if (methods & 0x0010)
  597. info += tr("[Ext. NFC Token]");
  598. if (methods & 0x0020)
  599. info += tr("[Int. NFC Token]");
  600. if (methods & 0x0040)
  601. info += tr("[NFC Interface]");
  602. if (methods & 0x0080)
  603. info += tr("[Push Button]");
  604. if (methods & 0x0100)
  605. info += tr("[Keypad]");
  606. info += "\n";
  607. }
  608. var = ctx_item->data(peer_role_dev_passwd_id);
  609. if (var.isValid()) {
  610. info += tr("Device Password ID: ") + var.toString();
  611. switch (var.toInt()) {
  612. case 0:
  613. info += tr(" (Default PIN)");
  614. break;
  615. case 1:
  616. info += tr(" (User-specified PIN)");
  617. break;
  618. case 2:
  619. info += tr(" (Machine-specified PIN)");
  620. break;
  621. case 3:
  622. info += tr(" (Rekey)");
  623. break;
  624. case 4:
  625. info += tr(" (Push Button)");
  626. break;
  627. case 5:
  628. info += tr(" (Registrar-specified)");
  629. break;
  630. }
  631. info += "\n";
  632. }
  633. msg.setInformativeText(info);
  634. var = ctx_item->data(peer_role_details);
  635. if (var.isValid())
  636. msg.setDetailedText(var.toString());
  637. msg.exec();
  638. }