peers.cpp 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179
  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 "wpagui.h"
  18. #include "stringquery.h"
  19. #include "peers.h"
  20. static const int peer_role_address = Qt::UserRole + 1;
  21. /*
  22. * TODO:
  23. * - add pending WPS queries (from M1/PIN, PBC?)
  24. * - add current AP info (e.g., from WPS) in station mode
  25. * - different icons to indicate peer type
  26. */
  27. Peers::Peers(QWidget *parent, const char *, bool, Qt::WFlags)
  28. : QDialog(parent)
  29. {
  30. setupUi(this);
  31. if (QImageReader::supportedImageFormats().contains(QByteArray("svg")))
  32. default_icon = new QIcon(":/icons/wpa_gui.svg");
  33. else
  34. default_icon = new QIcon(":/icons/wpa_gui.png");
  35. peers->setModel(&model);
  36. peers->setResizeMode(QListView::Adjust);
  37. peers->setContextMenuPolicy(Qt::CustomContextMenu);
  38. connect(peers, SIGNAL(customContextMenuRequested(const QPoint &)),
  39. this, SLOT(context_menu(const QPoint &)));
  40. wpagui = NULL;
  41. }
  42. void Peers::setWpaGui(WpaGui *_wpagui)
  43. {
  44. wpagui = _wpagui;
  45. update_peers();
  46. }
  47. Peers::~Peers()
  48. {
  49. delete default_icon;
  50. }
  51. void Peers::languageChange()
  52. {
  53. retranslateUi(this);
  54. }
  55. void Peers::context_menu(const QPoint &pos)
  56. {
  57. QMenu *menu = new QMenu;
  58. if (menu == NULL)
  59. return;
  60. QModelIndex idx = peers->indexAt(pos);
  61. if (idx.isValid()) {
  62. ctx_item = model.itemFromIndex(idx);
  63. /* TODO: only for peers that are requesting WPS PIN method */
  64. menu->addAction(QString("Enter WPS PIN"), this,
  65. SLOT(enter_pin()));
  66. } else {
  67. ctx_item = NULL;
  68. menu->addAction(QString("Refresh"), this, SLOT(ctx_refresh()));
  69. }
  70. menu->exec(peers->mapToGlobal(pos));
  71. }
  72. void Peers::enter_pin()
  73. {
  74. if (ctx_item == NULL)
  75. return;
  76. QString addr = ctx_item->data(peer_role_address).toString();
  77. StringQuery input(tr("PIN:"));
  78. input.setWindowTitle(tr("PIN for ") + ctx_item->text());
  79. if (input.exec() != QDialog::Accepted)
  80. return;
  81. char cmd[100];
  82. char reply[100];
  83. size_t reply_len;
  84. snprintf(cmd, sizeof(cmd), "WPS_PIN %s %s",
  85. addr.toAscii().constData(),
  86. input.get_string().toAscii().constData());
  87. reply_len = sizeof(reply) - 1;
  88. if (wpagui->ctrlRequest(cmd, reply, &reply_len) < 0) {
  89. QMessageBox msg;
  90. msg.setIcon(QMessageBox::Warning);
  91. msg.setText("Failed to set the WPS PIN.");
  92. msg.exec();
  93. }
  94. }
  95. void Peers::ctx_refresh()
  96. {
  97. update_peers();
  98. }
  99. void Peers::update_peers()
  100. {
  101. char reply[2048];
  102. size_t reply_len;
  103. char cmd[20];
  104. int res;
  105. model.clear();
  106. if (wpagui == NULL)
  107. return;
  108. reply_len = sizeof(reply) - 1;
  109. if (wpagui->ctrlRequest("STA-FIRST", reply, &reply_len) < 0)
  110. return;
  111. do {
  112. reply[reply_len] = '\0';
  113. QString info(reply);
  114. char *txt = reply;
  115. while (*txt != '\0' && *txt != '\n')
  116. txt++;
  117. *txt++ = '\0';
  118. if (strncmp(reply, "FAIL", 4) == 0 ||
  119. strncmp(reply, "UNKNOWN", 7) == 0)
  120. break;
  121. QStringList lines = info.split(QRegExp("\\n"));
  122. QString name;
  123. for (QStringList::Iterator it = lines.begin();
  124. it != lines.end(); it++) {
  125. int pos = (*it).indexOf('=') + 1;
  126. if (pos < 1)
  127. continue;
  128. if ((*it).startsWith("wpsDeviceName="))
  129. name = (*it).mid(pos);
  130. }
  131. if (name.isEmpty())
  132. name = reply;
  133. QStandardItem *item = new QStandardItem(*default_icon, name);
  134. if (item) {
  135. item->setData(QString(reply), peer_role_address);
  136. item->setToolTip(info);
  137. model.appendRow(item);
  138. }
  139. reply_len = sizeof(reply) - 1;
  140. snprintf(cmd, sizeof(cmd), "STA-NEXT %s", reply);
  141. res = wpagui->ctrlRequest(cmd, reply, &reply_len);
  142. } while (res >= 0);
  143. }