peers.cpp
Go to the documentation of this file.
00001 /*
00002  * wpa_gui - Peers class
00003  * Copyright (c) 2009, Atheros Communications
00004  *
00005  * This program is free software; you can redistribute it and/or modify
00006  * it under the terms of the GNU General Public License version 2 as
00007  * published by the Free Software Foundation.
00008  *
00009  * Alternatively, this software may be distributed under the terms of BSD
00010  * license.
00011  *
00012  * See README and COPYING for more details.
00013  */
00014 
00015 #include <cstdio>
00016 #include <QImageReader>
00017 #include <QMessageBox>
00018 
00019 #include "common/wpa_ctrl.h"
00020 #include "wpagui.h"
00021 #include "stringquery.h"
00022 #include "peers.h"
00023 
00024 
00025 enum {
00026         peer_role_address = Qt::UserRole + 1,
00027         peer_role_type,
00028         peer_role_uuid,
00029         peer_role_details,
00030         peer_role_pri_dev_type,
00031         peer_role_ssid,
00032         peer_role_config_methods,
00033         peer_role_dev_passwd_id,
00034         peer_role_bss_id
00035 };
00036 
00037 /*
00038  * TODO:
00039  * - add current AP info (e.g., from WPS) in station mode
00040  */
00041 
00042 enum peer_type {
00043         PEER_TYPE_ASSOCIATED_STATION,
00044         PEER_TYPE_AP,
00045         PEER_TYPE_AP_WPS,
00046         PEER_TYPE_WPS_PIN_NEEDED,
00047         PEER_TYPE_WPS_ER_AP,
00048         PEER_TYPE_WPS_ER_AP_UNCONFIGURED,
00049         PEER_TYPE_WPS_ER_ENROLLEE,
00050         PEER_TYPE_WPS_ENROLLEE
00051 };
00052 
00053 
00054 Peers::Peers(QWidget *parent, const char *, bool, Qt::WFlags)
00055         : QDialog(parent)
00056 {
00057         setupUi(this);
00058 
00059         if (QImageReader::supportedImageFormats().contains(QByteArray("svg")))
00060         {
00061                 default_icon = new QIcon(":/icons/wpa_gui.svg");
00062                 ap_icon = new QIcon(":/icons/ap.svg");
00063                 laptop_icon = new QIcon(":/icons/laptop.svg");
00064         } else {
00065                 default_icon = new QIcon(":/icons/wpa_gui.png");
00066                 ap_icon = new QIcon(":/icons/ap.png");
00067                 laptop_icon = new QIcon(":/icons/laptop.png");
00068         }
00069 
00070         peers->setModel(&model);
00071         peers->setResizeMode(QListView::Adjust);
00072 
00073         peers->setContextMenuPolicy(Qt::CustomContextMenu);
00074         connect(peers, SIGNAL(customContextMenuRequested(const QPoint &)),
00075                 this, SLOT(context_menu(const QPoint &)));
00076 
00077         wpagui = NULL;
00078 }
00079 
00080 
00081 void Peers::setWpaGui(WpaGui *_wpagui)
00082 {
00083         wpagui = _wpagui;
00084         update_peers();
00085 }
00086 
00087 
00088 Peers::~Peers()
00089 {
00090         delete default_icon;
00091         delete ap_icon;
00092         delete laptop_icon;
00093 }
00094 
00095 
00096 void Peers::languageChange()
00097 {
00098         retranslateUi(this);
00099 }
00100 
00101 
00102 QString Peers::ItemType(int type)
00103 {
00104         QString title;
00105         switch (type) {
00106         case PEER_TYPE_ASSOCIATED_STATION:
00107                 title = tr("Associated station");
00108                 break;
00109         case PEER_TYPE_AP:
00110                 title = tr("AP");
00111                 break;
00112         case PEER_TYPE_AP_WPS:
00113                 title = tr("WPS AP");
00114                 break;
00115         case PEER_TYPE_WPS_PIN_NEEDED:
00116                 title = tr("WPS PIN needed");
00117                 break;
00118         case PEER_TYPE_WPS_ER_AP:
00119                 title = tr("ER: WPS AP");
00120                 break;
00121         case PEER_TYPE_WPS_ER_AP_UNCONFIGURED:
00122                 title = tr("ER: WPS AP (Unconfigured)");
00123                 break;
00124         case PEER_TYPE_WPS_ER_ENROLLEE:
00125                 title = tr("ER: WPS Enrollee");
00126                 break;
00127         case PEER_TYPE_WPS_ENROLLEE:
00128                 title = tr("WPS Enrollee");
00129                 break;
00130         }
00131         return title;
00132 }
00133 
00134 
00135 void Peers::context_menu(const QPoint &pos)
00136 {
00137         QMenu *menu = new QMenu;
00138         if (menu == NULL)
00139                 return;
00140 
00141         QModelIndex idx = peers->indexAt(pos);
00142         if (idx.isValid()) {
00143                 ctx_item = model.itemFromIndex(idx);
00144                 int type = ctx_item->data(peer_role_type).toInt();
00145                 menu->addAction(Peers::ItemType(type))->setEnabled(false);
00146                 menu->addSeparator();
00147 
00148                 int config_methods = -1;
00149                 QVariant var = ctx_item->data(peer_role_config_methods);
00150                 if (var.isValid())
00151                         config_methods = var.toInt();
00152 
00153                 if ((type == PEER_TYPE_ASSOCIATED_STATION ||
00154                      type == PEER_TYPE_AP_WPS ||
00155                      type == PEER_TYPE_WPS_PIN_NEEDED ||
00156                      type == PEER_TYPE_WPS_ER_ENROLLEE ||
00157                      type == PEER_TYPE_WPS_ENROLLEE) &&
00158                     (config_methods == -1 || (config_methods & 0x010c))) {
00159                         menu->addAction(tr("Enter WPS PIN"), this,
00160                                         SLOT(enter_pin()));
00161                 }
00162 
00163                 if (type == PEER_TYPE_AP_WPS) {
00164                         menu->addAction(tr("Connect (PBC)"), this,
00165                                         SLOT(connect_pbc()));
00166                 }
00167 
00168                 if ((type == PEER_TYPE_ASSOCIATED_STATION ||
00169                      type == PEER_TYPE_WPS_ER_ENROLLEE ||
00170                      type == PEER_TYPE_WPS_ENROLLEE) &&
00171                     config_methods >= 0 && (config_methods & 0x0080)) {
00172                         menu->addAction(tr("Enroll (PBC)"), this,
00173                                         SLOT(connect_pbc()));
00174                 }
00175 
00176                 if (type == PEER_TYPE_WPS_ER_AP) {
00177                         menu->addAction(tr("Learn Configuration"), this,
00178                                         SLOT(learn_ap_config()));
00179                 }
00180 
00181                 menu->addAction(tr("Properties"), this, SLOT(properties()));
00182         } else {
00183                 ctx_item = NULL;
00184                 menu->addAction(QString(tr("Refresh")), this,
00185                                 SLOT(ctx_refresh()));
00186         }
00187 
00188         menu->exec(peers->mapToGlobal(pos));
00189 }
00190 
00191 
00192 void Peers::enter_pin()
00193 {
00194         if (ctx_item == NULL)
00195                 return;
00196 
00197         int peer_type = ctx_item->data(peer_role_type).toInt();
00198         QString uuid;
00199         QString addr;
00200         if (peer_type == PEER_TYPE_WPS_ER_ENROLLEE)
00201                 uuid = ctx_item->data(peer_role_uuid).toString();
00202         else
00203                 addr = ctx_item->data(peer_role_address).toString();
00204 
00205         StringQuery input(tr("PIN:"));
00206         input.setWindowTitle(tr("PIN for ") + ctx_item->text());
00207         if (input.exec() != QDialog::Accepted)
00208                 return;
00209 
00210         char cmd[100];
00211         char reply[100];
00212         size_t reply_len;
00213 
00214         if (peer_type == PEER_TYPE_WPS_ER_ENROLLEE) {
00215                 snprintf(cmd, sizeof(cmd), "WPS_ER_PIN %s %s",
00216                          uuid.toAscii().constData(),
00217                          input.get_string().toAscii().constData());
00218         } else {
00219                 snprintf(cmd, sizeof(cmd), "WPS_PIN %s %s",
00220                          addr.toAscii().constData(),
00221                          input.get_string().toAscii().constData());
00222         }
00223         reply_len = sizeof(reply) - 1;
00224         if (wpagui->ctrlRequest(cmd, reply, &reply_len) < 0) {
00225                 QMessageBox msg;
00226                 msg.setIcon(QMessageBox::Warning);
00227                 msg.setText(tr("Failed to set the WPS PIN."));
00228                 msg.exec();
00229         }
00230 }
00231 
00232 
00233 void Peers::ctx_refresh()
00234 {
00235         update_peers();
00236 }
00237 
00238 
00239 void Peers::add_station(QString info)
00240 {
00241         QStringList lines = info.split(QRegExp("\\n"));
00242         QString name;
00243 
00244         for (QStringList::Iterator it = lines.begin();
00245              it != lines.end(); it++) {
00246                 int pos = (*it).indexOf('=') + 1;
00247                 if (pos < 1)
00248                         continue;
00249 
00250                 if ((*it).startsWith("wpsDeviceName="))
00251                         name = (*it).mid(pos);
00252         }
00253 
00254         if (name.isEmpty())
00255                 name = lines[0];
00256 
00257         QStandardItem *item = new QStandardItem(*laptop_icon, name);
00258         if (item) {
00259                 item->setData(lines[0], peer_role_address);
00260                 item->setData(PEER_TYPE_ASSOCIATED_STATION,
00261                               peer_role_type);
00262                 item->setData(info, peer_role_details);
00263                 item->setToolTip(ItemType(PEER_TYPE_ASSOCIATED_STATION));
00264                 model.appendRow(item);
00265         }
00266 }
00267 
00268 
00269 void Peers::add_stations()
00270 {
00271         char reply[2048];
00272         size_t reply_len;
00273         char cmd[30];
00274         int res;
00275 
00276         reply_len = sizeof(reply) - 1;
00277         if (wpagui->ctrlRequest("STA-FIRST", reply, &reply_len) < 0)
00278                 return;
00279 
00280         do {
00281                 reply[reply_len] = '\0';
00282                 QString info(reply);
00283                 char *txt = reply;
00284                 while (*txt != '\0' && *txt != '\n')
00285                         txt++;
00286                 *txt++ = '\0';
00287                 if (strncmp(reply, "FAIL", 4) == 0 ||
00288                     strncmp(reply, "UNKNOWN", 7) == 0)
00289                         break;
00290 
00291                 add_station(info);
00292 
00293                 reply_len = sizeof(reply) - 1;
00294                 snprintf(cmd, sizeof(cmd), "STA-NEXT %s", reply);
00295                 res = wpagui->ctrlRequest(cmd, reply, &reply_len);
00296         } while (res >= 0);
00297 }
00298 
00299 
00300 void Peers::add_single_station(const char *addr)
00301 {
00302         char reply[2048];
00303         size_t reply_len;
00304         char cmd[30];
00305 
00306         reply_len = sizeof(reply) - 1;
00307         snprintf(cmd, sizeof(cmd), "STA %s", addr);
00308         if (wpagui->ctrlRequest(cmd, reply, &reply_len) < 0)
00309                 return;
00310 
00311         reply[reply_len] = '\0';
00312         QString info(reply);
00313         char *txt = reply;
00314         while (*txt != '\0' && *txt != '\n')
00315                 txt++;
00316         *txt++ = '\0';
00317         if (strncmp(reply, "FAIL", 4) == 0 ||
00318             strncmp(reply, "UNKNOWN", 7) == 0)
00319                 return;
00320 
00321         add_station(info);
00322 }
00323 
00324 
00325 void Peers::remove_bss(int id)
00326 {
00327         if (model.rowCount() == 0)
00328                 return;
00329 
00330         QModelIndexList lst = model.match(model.index(0, 0), peer_role_bss_id,
00331                                           id);
00332         if (lst.size() == 0)
00333                 return;
00334         model.removeRow(lst[0].row());
00335 }
00336 
00337 
00338 bool Peers::add_bss(const char *cmd)
00339 {
00340         char reply[2048];
00341         size_t reply_len;
00342 
00343         reply_len = sizeof(reply) - 1;
00344         if (wpagui->ctrlRequest(cmd, reply, &reply_len) < 0)
00345                 return false;
00346         reply[reply_len] = '\0';
00347 
00348         QString bss(reply);
00349         if (bss.isEmpty() || bss.startsWith("FAIL"))
00350                 return false;
00351 
00352         QString ssid, bssid, flags, wps_name, pri_dev_type;
00353         int id = -1;
00354 
00355         QStringList lines = bss.split(QRegExp("\\n"));
00356         for (QStringList::Iterator it = lines.begin();
00357              it != lines.end(); it++) {
00358                 int pos = (*it).indexOf('=') + 1;
00359                 if (pos < 1)
00360                         continue;
00361 
00362                 if ((*it).startsWith("bssid="))
00363                         bssid = (*it).mid(pos);
00364                 else if ((*it).startsWith("id="))
00365                         id = (*it).mid(pos).toInt();
00366                 else if ((*it).startsWith("flags="))
00367                         flags = (*it).mid(pos);
00368                 else if ((*it).startsWith("ssid="))
00369                         ssid = (*it).mid(pos);
00370                 else if ((*it).startsWith("wps_device_name="))
00371                         wps_name = (*it).mid(pos);
00372                 else if ((*it).startsWith("wps_primary_device_type="))
00373                         pri_dev_type = (*it).mid(pos);
00374         }
00375 
00376         QString name = wps_name;
00377         if (name.isEmpty())
00378                 name = ssid + "\n" + bssid;
00379 
00380         QStandardItem *item = new QStandardItem(*ap_icon, name);
00381         if (item) {
00382                 item->setData(bssid, peer_role_address);
00383                 if (id >= 0)
00384                         item->setData(id, peer_role_bss_id);
00385                 int type;
00386                 if (flags.contains("[WPS"))
00387                         type = PEER_TYPE_AP_WPS;
00388                 else
00389                         type = PEER_TYPE_AP;
00390                 item->setData(type, peer_role_type);
00391 
00392                 for (int i = 0; i < lines.size(); i++) {
00393                         if (lines[i].length() > 60) {
00394                                 lines[i].remove(60, lines[i].length());
00395                                 lines[i] += "..";
00396                         }
00397                 }
00398                 item->setToolTip(ItemType(type));
00399                 item->setData(lines.join("\n"), peer_role_details);
00400                 if (!pri_dev_type.isEmpty())
00401                         item->setData(pri_dev_type,
00402                                       peer_role_pri_dev_type);
00403                 if (!ssid.isEmpty())
00404                         item->setData(ssid, peer_role_ssid);
00405                 model.appendRow(item);
00406         }
00407 
00408         return true;
00409 }
00410 
00411 
00412 void Peers::add_scan_results()
00413 {
00414         int index;
00415         char cmd[20];
00416 
00417         index = 0;
00418         while (wpagui) {
00419                 snprintf(cmd, sizeof(cmd), "BSS %d", index++);
00420                 if (index > 1000)
00421                         break;
00422 
00423                 if (!add_bss(cmd))
00424                         break;
00425         }
00426 }
00427 
00428 
00429 void Peers::update_peers()
00430 {
00431         model.clear();
00432         if (wpagui == NULL)
00433                 return;
00434 
00435         char reply[20];
00436         size_t replylen = sizeof(reply) - 1;
00437         wpagui->ctrlRequest("WPS_ER_START", reply, &replylen);
00438 
00439         add_stations();
00440         add_scan_results();
00441 }
00442 
00443 
00444 QStandardItem * Peers::find_addr(QString addr)
00445 {
00446         if (model.rowCount() == 0)
00447                 return NULL;
00448 
00449         QModelIndexList lst = model.match(model.index(0, 0), peer_role_address,
00450                                           addr);
00451         if (lst.size() == 0)
00452                 return NULL;
00453         return model.itemFromIndex(lst[0]);
00454 }
00455 
00456 
00457 QStandardItem * Peers::find_uuid(QString uuid)
00458 {
00459         if (model.rowCount() == 0)
00460                 return NULL;
00461 
00462         QModelIndexList lst = model.match(model.index(0, 0), peer_role_uuid,
00463                                           uuid);
00464         if (lst.size() == 0)
00465                 return NULL;
00466         return model.itemFromIndex(lst[0]);
00467 }
00468 
00469 
00470 void Peers::event_notify(WpaMsg msg)
00471 {
00472         QString text = msg.getMsg();
00473 
00474         if (text.startsWith(WPS_EVENT_PIN_NEEDED)) {
00475                 /*
00476                  * WPS-PIN-NEEDED 5a02a5fa-9199-5e7c-bc46-e183d3cb32f7
00477                  * 02:2a:c4:18:5b:f3
00478                  * [Wireless Client|Company|cmodel|123|12345|1-0050F204-1]
00479                  */
00480                 QStringList items = text.split(' ');
00481                 QString uuid = items[1];
00482                 QString addr = items[2];
00483                 QString name = "";
00484 
00485                 QStandardItem *item = find_addr(addr);
00486                 if (item)
00487                         return;
00488 
00489                 int pos = text.indexOf('[');
00490                 if (pos >= 0) {
00491                         int pos2 = text.lastIndexOf(']');
00492                         if (pos2 >= pos) {
00493                                 items = text.mid(pos + 1, pos2 - pos - 1).
00494                                         split('|');
00495                                 name = items[0];
00496                                 items.append(addr);
00497                         }
00498                 }
00499 
00500                 item = new QStandardItem(*laptop_icon, name);
00501                 if (item) {
00502                         item->setData(addr, peer_role_address);
00503                         item->setData(PEER_TYPE_WPS_PIN_NEEDED,
00504                                       peer_role_type);
00505                         item->setToolTip(ItemType(PEER_TYPE_WPS_PIN_NEEDED));
00506                         item->setData(items.join("\n"), peer_role_details);
00507                         item->setData(items[5], peer_role_pri_dev_type);
00508                         model.appendRow(item);
00509                 }
00510                 return;
00511         }
00512 
00513         if (text.startsWith(AP_STA_CONNECTED)) {
00514                 /* AP-STA-CONNECTED 02:2a:c4:18:5b:f3 */
00515                 QStringList items = text.split(' ');
00516                 QString addr = items[1];
00517                 QStandardItem *item = find_addr(addr);
00518                 if (item == NULL || item->data(peer_role_type).toInt() !=
00519                     PEER_TYPE_ASSOCIATED_STATION)
00520                         add_single_station(addr.toAscii().constData());
00521                 return;
00522         }
00523 
00524         if (text.startsWith(AP_STA_DISCONNECTED)) {
00525                 /* AP-STA-DISCONNECTED 02:2a:c4:18:5b:f3 */
00526                 QStringList items = text.split(' ');
00527                 QString addr = items[1];
00528 
00529                 if (model.rowCount() == 0)
00530                         return;
00531 
00532                 QModelIndexList lst = model.match(model.index(0, 0),
00533                                                   peer_role_address, addr);
00534                 for (int i = 0; i < lst.size(); i++) {
00535                         QStandardItem *item = model.itemFromIndex(lst[i]);
00536                         if (item && item->data(peer_role_type).toInt() ==
00537                             PEER_TYPE_ASSOCIATED_STATION)
00538                                 model.removeRow(lst[i].row());
00539                 }
00540                 return;
00541         }
00542 
00543         if (text.startsWith(WPS_EVENT_ER_AP_ADD)) {
00544                 /*
00545                  * WPS-ER-AP-ADD 87654321-9abc-def0-1234-56789abc0002
00546                  * 02:11:22:33:44:55 pri_dev_type=6-0050F204-1 wps_state=1
00547                  * |Very friendly name|Company|Long description of the model|
00548                  * WAP|http://w1.fi/|http://w1.fi/hostapd/
00549                  */
00550                 QStringList items = text.split(' ');
00551                 if (items.size() < 5)
00552                         return;
00553                 QString uuid = items[1];
00554                 QString addr = items[2];
00555                 QString pri_dev_type = items[3].mid(13);
00556                 int wps_state = items[4].mid(10).toInt();
00557 
00558                 int pos = text.indexOf('|');
00559                 if (pos < 0)
00560                         return;
00561                 items = text.mid(pos + 1).split('|');
00562                 if (items.size() < 1)
00563                         return;
00564 
00565                 QStandardItem *item = find_uuid(uuid);
00566                 if (item)
00567                         return;
00568 
00569                 item = new QStandardItem(*ap_icon, items[0]);
00570                 if (item) {
00571                         item->setData(uuid, peer_role_uuid);
00572                         item->setData(addr, peer_role_address);
00573                         int type = wps_state == 2 ? PEER_TYPE_WPS_ER_AP:
00574                                 PEER_TYPE_WPS_ER_AP_UNCONFIGURED;
00575                         item->setData(type, peer_role_type);
00576                         item->setToolTip(ItemType(type));
00577                         item->setData(pri_dev_type, peer_role_pri_dev_type);
00578                         item->setData(items.join(QString("\n")),
00579                                       peer_role_details);
00580                         model.appendRow(item);
00581                 }
00582 
00583                 return;
00584         }
00585 
00586         if (text.startsWith(WPS_EVENT_ER_AP_REMOVE)) {
00587                 /* WPS-ER-AP-REMOVE 87654321-9abc-def0-1234-56789abc0002 */
00588                 QStringList items = text.split(' ');
00589                 if (items.size() < 2)
00590                         return;
00591                 if (model.rowCount() == 0)
00592                         return;
00593 
00594                 QModelIndexList lst = model.match(model.index(0, 0),
00595                                                   peer_role_uuid, items[1]);
00596                 for (int i = 0; i < lst.size(); i++) {
00597                         QStandardItem *item = model.itemFromIndex(lst[i]);
00598                         if (item &&
00599                             (item->data(peer_role_type).toInt() ==
00600                              PEER_TYPE_WPS_ER_AP ||
00601                              item->data(peer_role_type).toInt() ==
00602                              PEER_TYPE_WPS_ER_AP_UNCONFIGURED))
00603                                 model.removeRow(lst[i].row());
00604                 }
00605                 return;
00606         }
00607 
00608         if (text.startsWith(WPS_EVENT_ER_ENROLLEE_ADD)) {
00609                 /*
00610                  * WPS-ER-ENROLLEE-ADD 2b7093f1-d6fb-5108-adbb-bea66bb87333
00611                  * 02:66:a0:ee:17:27 M1=1 config_methods=0x14d dev_passwd_id=0
00612                  * pri_dev_type=1-0050F204-1
00613                  * |Wireless Client|Company|cmodel|123|12345|
00614                  */
00615                 QStringList items = text.split(' ');
00616                 if (items.size() < 3)
00617                         return;
00618                 QString uuid = items[1];
00619                 QString addr = items[2];
00620                 QString pri_dev_type = items[6].mid(13);
00621                 int config_methods = -1;
00622                 int dev_passwd_id = -1;
00623 
00624                 for (int i = 3; i < items.size(); i++) {
00625                         int pos = items[i].indexOf('=') + 1;
00626                         if (pos < 1)
00627                                 continue;
00628                         QString val = items[i].mid(pos);
00629                         if (items[i].startsWith("config_methods=")) {
00630                                 config_methods = val.toInt(0, 0);
00631                         } else if (items[i].startsWith("dev_passwd_id=")) {
00632                                 dev_passwd_id = val.toInt();
00633                         }
00634                 }
00635 
00636                 int pos = text.indexOf('|');
00637                 if (pos < 0)
00638                         return;
00639                 items = text.mid(pos + 1).split('|');
00640                 if (items.size() < 1)
00641                         return;
00642                 QString name = items[0];
00643                 if (name.length() == 0)
00644                         name = addr;
00645 
00646                 remove_enrollee_uuid(uuid);
00647 
00648                 QStandardItem *item;
00649                 item = new QStandardItem(*laptop_icon, name);
00650                 if (item) {
00651                         item->setData(uuid, peer_role_uuid);
00652                         item->setData(addr, peer_role_address);
00653                         item->setData(PEER_TYPE_WPS_ER_ENROLLEE,
00654                                       peer_role_type);
00655                         item->setToolTip(ItemType(PEER_TYPE_WPS_ER_ENROLLEE));
00656                         item->setData(items.join(QString("\n")),
00657                                       peer_role_details);
00658                         item->setData(pri_dev_type, peer_role_pri_dev_type);
00659                         if (config_methods >= 0)
00660                                 item->setData(config_methods,
00661                                               peer_role_config_methods);
00662                         if (dev_passwd_id >= 0)
00663                                 item->setData(dev_passwd_id,
00664                                               peer_role_dev_passwd_id);
00665                         model.appendRow(item);
00666                 }
00667 
00668                 return;
00669         }
00670 
00671         if (text.startsWith(WPS_EVENT_ER_ENROLLEE_REMOVE)) {
00672                 /*
00673                  * WPS-ER-ENROLLEE-REMOVE 2b7093f1-d6fb-5108-adbb-bea66bb87333
00674                  * 02:66:a0:ee:17:27
00675                  */
00676                 QStringList items = text.split(' ');
00677                 if (items.size() < 2)
00678                         return;
00679                 remove_enrollee_uuid(items[1]);
00680                 return;
00681         }
00682 
00683         if (text.startsWith(WPS_EVENT_ENROLLEE_SEEN)) {
00684                 /* TODO: need to time out this somehow or remove on successful
00685                  * WPS run, etc. */
00686                 /*
00687                  * WPS-ENROLLEE-SEEN 02:00:00:00:01:00
00688                  * 572cf82f-c957-5653-9b16-b5cfb298abf1 1-0050F204-1 0x80 4 1
00689                  * [Wireless Client]
00690                  * (MAC addr, UUID-E, pri dev type, config methods,
00691                  * dev passwd id, request type, [dev name])
00692                  */
00693                 QStringList items = text.split(' ');
00694                 if (items.size() < 7)
00695                         return;
00696                 QString addr = items[1];
00697                 QString uuid = items[2];
00698                 QString pri_dev_type = items[3];
00699                 int config_methods = items[4].toInt(0, 0);
00700                 int dev_passwd_id = items[5].toInt();
00701                 QString name;
00702 
00703                 int pos = text.indexOf('[');
00704                 if (pos >= 0) {
00705                         int pos2 = text.lastIndexOf(']');
00706                         if (pos2 >= pos) {
00707                                 QStringList items2 =
00708                                         text.mid(pos + 1, pos2 - pos - 1).
00709                                         split('|');
00710                                 name = items2[0];
00711                         }
00712                 }
00713                 if (name.isEmpty())
00714                         name = addr;
00715 
00716                 QStandardItem *item;
00717 
00718                 item = find_uuid(uuid);
00719                 if (item) {
00720                         QVariant var = item->data(peer_role_config_methods);
00721                         QVariant var2 = item->data(peer_role_dev_passwd_id);
00722                         if ((var.isValid() && config_methods != var.toInt()) ||
00723                             (var2.isValid() && dev_passwd_id != var2.toInt()))
00724                                 remove_enrollee_uuid(uuid);
00725                         else
00726                                 return;
00727                 }
00728 
00729                 item = new QStandardItem(*laptop_icon, name);
00730                 if (item) {
00731                         item->setData(uuid, peer_role_uuid);
00732                         item->setData(addr, peer_role_address);
00733                         item->setData(PEER_TYPE_WPS_ENROLLEE,
00734                                       peer_role_type);
00735                         item->setToolTip(ItemType(PEER_TYPE_WPS_ENROLLEE));
00736                         item->setData(items.join(QString("\n")),
00737                                       peer_role_details);
00738                         item->setData(pri_dev_type, peer_role_pri_dev_type);
00739                         item->setData(config_methods,
00740                                       peer_role_config_methods);
00741                         item->setData(dev_passwd_id, peer_role_dev_passwd_id);
00742                         model.appendRow(item);
00743                 }
00744 
00745                 return;
00746         }
00747 
00748         if (text.startsWith(WPA_EVENT_BSS_ADDED)) {
00749                 /* CTRL-EVENT-BSS-ADDED 34 00:11:22:33:44:55 */
00750                 QStringList items = text.split(' ');
00751                 if (items.size() < 2)
00752                         return;
00753                 char cmd[20];
00754                 snprintf(cmd, sizeof(cmd), "BSS ID-%d", items[1].toInt());
00755                 add_bss(cmd);
00756                 return;
00757         }
00758 
00759         if (text.startsWith(WPA_EVENT_BSS_REMOVED)) {
00760                 /* CTRL-EVENT-BSS-REMOVED 34 00:11:22:33:44:55 */
00761                 QStringList items = text.split(' ');
00762                 if (items.size() < 2)
00763                         return;
00764                 remove_bss(items[1].toInt());
00765                 return;
00766         }
00767 }
00768 
00769 
00770 void Peers::closeEvent(QCloseEvent *)
00771 {
00772         if (wpagui) {
00773                 char reply[20];
00774                 size_t replylen = sizeof(reply) - 1;
00775                 wpagui->ctrlRequest("WPS_ER_STOP", reply, &replylen);
00776         }
00777 }
00778 
00779 
00780 void Peers::done(int r)
00781 {
00782         QDialog::done(r);
00783         close();
00784 }
00785 
00786 
00787 void Peers::remove_enrollee_uuid(QString uuid)
00788 {
00789         if (model.rowCount() == 0)
00790                 return;
00791 
00792         QModelIndexList lst = model.match(model.index(0, 0),
00793                                           peer_role_uuid, uuid);
00794         for (int i = 0; i < lst.size(); i++) {
00795                 QStandardItem *item = model.itemFromIndex(lst[i]);
00796                 if (item == NULL)
00797                         continue;
00798                 int type = item->data(peer_role_type).toInt();
00799                 if (type == PEER_TYPE_WPS_ER_ENROLLEE ||
00800                     type == PEER_TYPE_WPS_ENROLLEE)
00801                         model.removeRow(lst[i].row());
00802         }
00803 }
00804 
00805 
00806 void Peers::properties()
00807 {
00808         if (ctx_item == NULL)
00809                 return;
00810 
00811         QMessageBox msg(this);
00812         msg.setStandardButtons(QMessageBox::Ok);
00813         msg.setDefaultButton(QMessageBox::Ok);
00814         msg.setEscapeButton(QMessageBox::Ok);
00815         msg.setWindowTitle(tr("Peer Properties"));
00816 
00817         int type = ctx_item->data(peer_role_type).toInt();
00818         QString title = Peers::ItemType(type);
00819 
00820         msg.setText(title + QString("\n") + tr("Name: ") + ctx_item->text());
00821 
00822         QVariant var;
00823         QString info;
00824 
00825         var = ctx_item->data(peer_role_address);
00826         if (var.isValid())
00827                 info += tr("Address: ") + var.toString() + QString("\n");
00828 
00829         var = ctx_item->data(peer_role_uuid);
00830         if (var.isValid())
00831                 info += tr("UUID: ") + var.toString() + QString("\n");
00832 
00833         var = ctx_item->data(peer_role_pri_dev_type);
00834         if (var.isValid())
00835                 info += tr("Primary Device Type: ") + var.toString() +
00836                         QString("\n");
00837 
00838         var = ctx_item->data(peer_role_ssid);
00839         if (var.isValid())
00840                 info += tr("SSID: ") + var.toString() + QString("\n");
00841 
00842         var = ctx_item->data(peer_role_config_methods);
00843         if (var.isValid()) {
00844                 int methods = var.toInt();
00845                 info += tr("Configuration Methods: ");
00846                 if (methods & 0x0001)
00847                         info += tr("[USBA]");
00848                 if (methods & 0x0002)
00849                         info += tr("[Ethernet]");
00850                 if (methods & 0x0004)
00851                         info += tr("[Label]");
00852                 if (methods & 0x0008)
00853                         info += tr("[Display]");
00854                 if (methods & 0x0010)
00855                         info += tr("[Ext. NFC Token]");
00856                 if (methods & 0x0020)
00857                         info += tr("[Int. NFC Token]");
00858                 if (methods & 0x0040)
00859                         info += tr("[NFC Interface]");
00860                 if (methods & 0x0080)
00861                         info += tr("[Push Button]");
00862                 if (methods & 0x0100)
00863                         info += tr("[Keypad]");
00864                 info += "\n";
00865         }
00866 
00867         var = ctx_item->data(peer_role_dev_passwd_id);
00868         if (var.isValid()) {
00869                 info += tr("Device Password ID: ") + var.toString();
00870                 switch (var.toInt()) {
00871                 case 0:
00872                         info += tr(" (Default PIN)");
00873                         break;
00874                 case 1:
00875                         info += tr(" (User-specified PIN)");
00876                         break;
00877                 case 2:
00878                         info += tr(" (Machine-specified PIN)");
00879                         break;
00880                 case 3:
00881                         info += tr(" (Rekey)");
00882                         break;
00883                 case 4:
00884                         info += tr(" (Push Button)");
00885                         break;
00886                 case 5:
00887                         info += tr(" (Registrar-specified)");
00888                         break;
00889                 }
00890                 info += "\n";
00891         }
00892 
00893         msg.setInformativeText(info);
00894 
00895         var = ctx_item->data(peer_role_details);
00896         if (var.isValid())
00897                 msg.setDetailedText(var.toString());
00898 
00899         msg.exec();
00900 }
00901 
00902 
00903 void Peers::connect_pbc()
00904 {
00905         if (ctx_item == NULL)
00906                 return;
00907 
00908         char cmd[100];
00909         char reply[100];
00910         size_t reply_len;
00911 
00912         int peer_type = ctx_item->data(peer_role_type).toInt();
00913         if (peer_type == PEER_TYPE_WPS_ER_ENROLLEE) {
00914                 snprintf(cmd, sizeof(cmd), "WPS_ER_PBC %s",
00915                          ctx_item->data(peer_role_uuid).toString().toAscii().
00916                          constData());
00917         } else {
00918                 snprintf(cmd, sizeof(cmd), "WPS_PBC");
00919         }
00920         reply_len = sizeof(reply) - 1;
00921         if (wpagui->ctrlRequest(cmd, reply, &reply_len) < 0) {
00922                 QMessageBox msg;
00923                 msg.setIcon(QMessageBox::Warning);
00924                 msg.setText(tr("Failed to start WPS PBC."));
00925                 msg.exec();
00926         }
00927 }
00928 
00929 
00930 void Peers::learn_ap_config()
00931 {
00932         if (ctx_item == NULL)
00933                 return;
00934 
00935         QString uuid = ctx_item->data(peer_role_uuid).toString();
00936 
00937         StringQuery input(tr("AP PIN:"));
00938         input.setWindowTitle(tr("AP PIN for ") + ctx_item->text());
00939         if (input.exec() != QDialog::Accepted)
00940                 return;
00941 
00942         char cmd[100];
00943         char reply[100];
00944         size_t reply_len;
00945 
00946         snprintf(cmd, sizeof(cmd), "WPS_ER_LEARN %s %s",
00947                  uuid.toAscii().constData(),
00948                  input.get_string().toAscii().constData());
00949         reply_len = sizeof(reply) - 1;
00950         if (wpagui->ctrlRequest(cmd, reply, &reply_len) < 0) {
00951                 QMessageBox msg;
00952                 msg.setIcon(QMessageBox::Warning);
00953                 msg.setText(tr("Failed to start learning AP configuration."));
00954                 msg.exec();
00955         }
00956 }


wpa_supplicant
Author(s): Package maintained by Blaise Gassend
autogenerated on Thu Apr 24 2014 15:34:35