$search
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 }