wpagui.ui.h
Go to the documentation of this file.
00001 /****************************************************************************
00002 ** ui.h extension file, included from the uic-generated form implementation.
00003 **
00004 ** If you want to add, delete, or rename functions or slots, use
00005 ** Qt Designer to update this file, preserving your code.
00006 **
00007 ** You should not define a constructor or destructor in this file.
00008 ** Instead, write your code in functions called init() and destroy().
00009 ** These will automatically be called by the form's constructor and
00010 ** destructor.
00011 *****************************************************************************/
00012 
00013 
00014 #ifdef __MINGW32__
00015 /* Need to get getopt() */
00016 #include <unistd.h>
00017 #endif
00018 
00019 #include <stdlib.h>
00020 
00021 void WpaGui::init()
00022 {
00023     eh = NULL;
00024     scanres = NULL;
00025     udr = NULL;
00026     ctrl_iface = NULL;
00027     ctrl_conn = NULL;
00028     monitor_conn = NULL;
00029     msgNotifier = NULL;
00030     ctrl_iface_dir = strdup("/var/run/wpa_supplicant");
00031     
00032     parse_argv();
00033 
00034     textStatus->setText("connecting to wpa_supplicant");
00035     timer = new QTimer(this);
00036     connect(timer, SIGNAL(timeout()), SLOT(ping()));
00037     timer->start(1000, FALSE);
00038     
00039     if (openCtrlConnection(ctrl_iface) < 0) {
00040         printf("Failed to open control connection to wpa_supplicant.\n");
00041     }
00042     
00043     updateStatus();
00044     networkMayHaveChanged = true;
00045     updateNetworks();
00046 }
00047 
00048 
00049 void WpaGui::destroy()
00050 {
00051     delete msgNotifier;
00052 
00053     if (monitor_conn) {
00054         wpa_ctrl_detach(monitor_conn);
00055         wpa_ctrl_close(monitor_conn);
00056         monitor_conn = NULL;
00057     }
00058     if (ctrl_conn) {
00059         wpa_ctrl_close(ctrl_conn);
00060         ctrl_conn = NULL;
00061     }
00062     
00063     if (eh) {
00064         eh->close();
00065         delete eh;
00066         eh = NULL;
00067     }
00068     
00069     if (scanres) {
00070         scanres->close();
00071         delete scanres;
00072         scanres = NULL;
00073     }
00074     
00075     if (udr) {
00076         udr->close();
00077         delete udr;
00078         udr = NULL;
00079     }
00080     
00081     free(ctrl_iface);
00082     ctrl_iface = NULL;
00083     
00084     free(ctrl_iface_dir);
00085     ctrl_iface_dir = NULL;
00086 }
00087 
00088 
00089 void WpaGui::parse_argv()
00090 {
00091     int c;
00092     for (;;) {
00093         c = getopt(qApp->argc(), qApp->argv(), "i:p:");
00094         if (c < 0)
00095             break;
00096         switch (c) {
00097         case 'i':
00098             free(ctrl_iface);
00099             ctrl_iface = strdup(optarg);
00100             break;
00101         case 'p':
00102             free(ctrl_iface_dir);
00103             ctrl_iface_dir = strdup(optarg);
00104             break;
00105         }
00106     }
00107 }
00108 
00109 
00110 int WpaGui::openCtrlConnection(const char *ifname)
00111 {
00112     char *cfile;
00113     int flen;
00114     char buf[2048], *pos, *pos2;
00115     size_t len;
00116 
00117     if (ifname) {
00118         if (ifname != ctrl_iface) {
00119             free(ctrl_iface);
00120             ctrl_iface = strdup(ifname);
00121         }
00122     } else {
00123 #ifdef CONFIG_CTRL_IFACE_UDP
00124         free(ctrl_iface);
00125         ctrl_iface = strdup("udp");
00126 #endif /* CONFIG_CTRL_IFACE_UDP */
00127 #ifdef CONFIG_CTRL_IFACE_UNIX
00128         struct dirent *dent;
00129         DIR *dir = opendir(ctrl_iface_dir);
00130         free(ctrl_iface);
00131         ctrl_iface = NULL;
00132         if (dir) {
00133             while ((dent = readdir(dir))) {
00134 #ifdef _DIRENT_HAVE_D_TYPE
00135                 /* Skip the file if it is not a socket.
00136                  * Also accept DT_UNKNOWN (0) in case
00137                  * the C library or underlying file
00138                  * system does not support d_type. */
00139                 if (dent->d_type != DT_SOCK &&
00140                     dent->d_type != DT_UNKNOWN)
00141                     continue;
00142 #endif /* _DIRENT_HAVE_D_TYPE */
00143 
00144                 if (strcmp(dent->d_name, ".") == 0 ||
00145                     strcmp(dent->d_name, "..") == 0)
00146                     continue;
00147                 printf("Selected interface '%s'\n", dent->d_name);
00148                 ctrl_iface = strdup(dent->d_name);
00149                 break;
00150             }
00151             closedir(dir);
00152         }
00153 #endif /* CONFIG_CTRL_IFACE_UNIX */
00154 #ifdef CONFIG_CTRL_IFACE_NAMED_PIPE
00155         struct wpa_ctrl *ctrl;
00156         int ret;
00157 
00158         free(ctrl_iface);
00159         ctrl_iface = NULL;
00160 
00161         ctrl = wpa_ctrl_open(NULL);
00162         if (ctrl) {
00163             len = sizeof(buf) - 1;
00164             ret = wpa_ctrl_request(ctrl, "INTERFACES", 10, buf, &len, NULL);
00165             if (ret >= 0) {
00166                 buf[len] = '\0';
00167                 pos = strchr(buf, '\n');
00168                 if (pos)
00169                     *pos = '\0';
00170                 ctrl_iface = strdup(buf);
00171             }
00172             wpa_ctrl_close(ctrl);
00173         }
00174 #endif /* CONFIG_CTRL_IFACE_NAMED_PIPE */
00175     }
00176     
00177     if (ctrl_iface == NULL)
00178         return -1;
00179 
00180 #ifdef CONFIG_CTRL_IFACE_UNIX
00181     flen = strlen(ctrl_iface_dir) + strlen(ctrl_iface) + 2;
00182     cfile = (char *) malloc(flen);
00183     if (cfile == NULL)
00184         return -1;
00185     snprintf(cfile, flen, "%s/%s", ctrl_iface_dir, ctrl_iface);
00186 #else /* CONFIG_CTRL_IFACE_UNIX */
00187     flen = strlen(ctrl_iface) + 1;
00188     cfile = (char *) malloc(flen);
00189     if (cfile == NULL)
00190         return -1;
00191     snprintf(cfile, flen, "%s", ctrl_iface);
00192 #endif /* CONFIG_CTRL_IFACE_UNIX */
00193 
00194     if (ctrl_conn) {
00195         wpa_ctrl_close(ctrl_conn);
00196         ctrl_conn = NULL;
00197     }
00198 
00199     if (monitor_conn) {
00200         delete msgNotifier;
00201         msgNotifier = NULL;
00202         wpa_ctrl_detach(monitor_conn);
00203         wpa_ctrl_close(monitor_conn);
00204         monitor_conn = NULL;
00205     }
00206 
00207     printf("Trying to connect to '%s'\n", cfile);
00208     ctrl_conn = wpa_ctrl_open(cfile);
00209     if (ctrl_conn == NULL) {
00210         free(cfile);
00211         return -1;
00212     }
00213     monitor_conn = wpa_ctrl_open(cfile);
00214     free(cfile);
00215     if (monitor_conn == NULL) {
00216         wpa_ctrl_close(ctrl_conn);
00217         return -1;
00218     }
00219     if (wpa_ctrl_attach(monitor_conn)) {
00220         printf("Failed to attach to wpa_supplicant\n");
00221         wpa_ctrl_close(monitor_conn);
00222         monitor_conn = NULL;
00223         wpa_ctrl_close(ctrl_conn);
00224         ctrl_conn = NULL;
00225         return -1;
00226     }
00227 
00228 #if defined(CONFIG_CTRL_IFACE_UNIX) || defined(CONFIG_CTRL_IFACE_UDP)
00229     msgNotifier = new QSocketNotifier(wpa_ctrl_get_fd(monitor_conn),
00230                                       QSocketNotifier::Read, this);
00231     connect(msgNotifier, SIGNAL(activated(int)), SLOT(receiveMsgs()));
00232 #endif
00233 
00234     adapterSelect->clear();
00235     adapterSelect->insertItem(ctrl_iface);
00236     adapterSelect->setCurrentItem(0);
00237 
00238     len = sizeof(buf) - 1;
00239     if (wpa_ctrl_request(ctrl_conn, "INTERFACES", 10, buf, &len, NULL) >= 0) {
00240         buf[len] = '\0';
00241         pos = buf;
00242         while (*pos) {
00243                 pos2 = strchr(pos, '\n');
00244                 if (pos2)
00245                         *pos2 = '\0';
00246                 if (strcmp(pos, ctrl_iface) != 0)
00247                         adapterSelect->insertItem(pos);
00248                 if (pos2)
00249                         pos = pos2 + 1;
00250                 else
00251                         break;
00252         }
00253     }
00254 
00255     return 0;
00256 }
00257 
00258 
00259 static void wpa_gui_msg_cb(char *msg, size_t)
00260 {
00261     /* This should not happen anymore since two control connections are used. */
00262     printf("missed message: %s\n", msg);
00263 }
00264 
00265 
00266 int WpaGui::ctrlRequest(const char *cmd, char *buf, size_t *buflen)
00267 {
00268     int ret;
00269     
00270     if (ctrl_conn == NULL)
00271         return -3;
00272     ret = wpa_ctrl_request(ctrl_conn, cmd, strlen(cmd), buf, buflen,
00273                            wpa_gui_msg_cb);
00274     if (ret == -2) {
00275         printf("'%s' command timed out.\n", cmd);
00276     } else if (ret < 0) {
00277         printf("'%s' command failed.\n", cmd);
00278     }
00279     
00280     return ret;
00281 }
00282 
00283 
00284 void WpaGui::updateStatus()
00285 {
00286     char buf[2048], *start, *end, *pos;
00287     size_t len;
00288 
00289     pingsToStatusUpdate = 10;
00290 
00291     len = sizeof(buf) - 1;
00292     if (ctrl_conn == NULL || ctrlRequest("STATUS", buf, &len) < 0) {
00293         textStatus->setText("Could not get status from wpa_supplicant");
00294         textAuthentication->clear();
00295         textEncryption->clear();
00296         textSsid->clear();
00297         textBssid->clear();
00298         textIpAddress->clear();
00299         return;
00300     }
00301     
00302     buf[len] = '\0';
00303     
00304     bool auth_updated = false, ssid_updated = false;
00305     bool bssid_updated = false, ipaddr_updated = false;
00306     bool status_updated = false;
00307     char *pairwise_cipher = NULL, *group_cipher = NULL;
00308     
00309     start = buf;
00310     while (*start) {
00311         bool last = false;
00312         end = strchr(start, '\n');
00313         if (end == NULL) {
00314             last = true;
00315             end = start;
00316             while (end[0] && end[1])
00317                 end++;
00318         }
00319         *end = '\0';
00320         
00321         pos = strchr(start, '=');
00322         if (pos) {
00323             *pos++ = '\0';
00324             if (strcmp(start, "bssid") == 0) {
00325                 bssid_updated = true;
00326                 textBssid->setText(pos);
00327             } else if (strcmp(start, "ssid") == 0) {
00328                 ssid_updated = true;
00329                 textSsid->setText(pos);
00330             } else if (strcmp(start, "ip_address") == 0) {
00331                 ipaddr_updated = true;
00332                 textIpAddress->setText(pos);
00333             } else if (strcmp(start, "wpa_state") == 0) {
00334                 status_updated = true;
00335                 textStatus->setText(pos);
00336             } else if (strcmp(start, "key_mgmt") == 0) {
00337                 auth_updated = true;
00338                 textAuthentication->setText(pos);
00339                 /* TODO: could add EAP status to this */
00340             } else if (strcmp(start, "pairwise_cipher") == 0) {
00341                 pairwise_cipher = pos;
00342             } else if (strcmp(start, "group_cipher") == 0) {
00343                 group_cipher = pos;
00344             }
00345         }
00346         
00347         if (last)
00348             break;
00349         start = end + 1;
00350     }
00351     
00352     if (pairwise_cipher || group_cipher) {
00353         QString encr;
00354         if (pairwise_cipher && group_cipher &&
00355             strcmp(pairwise_cipher, group_cipher) != 0) {
00356             encr.append(pairwise_cipher);
00357             encr.append(" + ");
00358             encr.append(group_cipher);
00359         } else if (pairwise_cipher) {
00360             encr.append(pairwise_cipher);
00361         } else {
00362             encr.append(group_cipher);
00363             encr.append(" [group key only]");
00364         }
00365         textEncryption->setText(encr);
00366     } else
00367         textEncryption->clear();
00368 
00369     if (!status_updated)
00370         textStatus->clear();
00371     if (!auth_updated)
00372         textAuthentication->clear();
00373     if (!ssid_updated)
00374         textSsid->clear();
00375     if (!bssid_updated)
00376         textBssid->clear();
00377     if (!ipaddr_updated)
00378         textIpAddress->clear();
00379 }
00380 
00381 
00382 void WpaGui::updateNetworks()
00383 {
00384     char buf[2048], *start, *end, *id, *ssid, *bssid, *flags;
00385     size_t len;
00386     int first_active = -1;
00387     bool selected = false;
00388 
00389     if (!networkMayHaveChanged)
00390         return;
00391 
00392     networkSelect->clear();
00393 
00394     if (ctrl_conn == NULL)
00395         return;
00396     
00397     len = sizeof(buf) - 1;
00398     if (ctrlRequest("LIST_NETWORKS", buf, &len) < 0)
00399         return;
00400     
00401     buf[len] = '\0';
00402     start = strchr(buf, '\n');
00403     if (start == NULL)
00404         return;
00405     start++;
00406 
00407     while (*start) {
00408         bool last = false;
00409         end = strchr(start, '\n');
00410         if (end == NULL) {
00411             last = true;
00412             end = start;
00413             while (end[0] && end[1])
00414                 end++;
00415         }
00416         *end = '\0';
00417         
00418         id = start;
00419         ssid = strchr(id, '\t');
00420         if (ssid == NULL)
00421             break;
00422         *ssid++ = '\0';
00423         bssid = strchr(ssid, '\t');
00424         if (bssid == NULL)
00425             break;
00426         *bssid++ = '\0';
00427         flags = strchr(bssid, '\t');
00428         if (flags == NULL)
00429             break;
00430         *flags++ = '\0';
00431         
00432         QString network(id);
00433         network.append(": ");
00434         network.append(ssid);
00435         networkSelect->insertItem(network);
00436         
00437         if (strstr(flags, "[CURRENT]")) {
00438             networkSelect->setCurrentItem(networkSelect->count() - 1);
00439             selected = true;
00440         } else if (first_active < 0 && strstr(flags, "[DISABLED]") == NULL)
00441             first_active = networkSelect->count() - 1;
00442         
00443         if (last)
00444             break;
00445         start = end + 1;
00446     }
00447 
00448     if (!selected && first_active >= 0)
00449         networkSelect->setCurrentItem(first_active);
00450 
00451     networkMayHaveChanged = false;
00452 }
00453 
00454 
00455 void WpaGui::helpIndex()
00456 {
00457     printf("helpIndex\n");
00458 }
00459 
00460 
00461 void WpaGui::helpContents()
00462 {
00463     printf("helpContents\n");
00464 }
00465 
00466 
00467 void WpaGui::helpAbout()
00468 {
00469     QMessageBox::about(this, "wpa_gui for wpa_supplicant",
00470                        "Copyright (c) 2003-2008,\n"
00471                        "Jouni Malinen <j@w1.fi>\n"
00472                        "and contributors.\n"
00473                        "\n"
00474                        "This program is free software. You can\n"
00475                        "distribute it and/or modify it under the terms of\n"
00476                        "the GNU General Public License version 2.\n"
00477                        "\n"
00478                        "Alternatively, this software may be distributed\n"
00479                        "under the terms of the BSD license.\n"
00480                        "\n"
00481                        "This product includes software developed\n"
00482                        "by the OpenSSL Project for use in the\n"
00483                        "OpenSSL Toolkit (http://www.openssl.org/)\n");
00484 }
00485 
00486 
00487 void WpaGui::disconnect()
00488 {
00489     char reply[10];
00490     size_t reply_len = sizeof(reply);
00491     ctrlRequest("DISCONNECT", reply, &reply_len);
00492 }
00493 
00494 
00495 void WpaGui::scan()
00496 {
00497     if (scanres) {
00498         scanres->close();
00499         delete scanres;
00500     }
00501 
00502     scanres = new ScanResults();
00503     if (scanres == NULL)
00504         return;
00505     scanres->setWpaGui(this);
00506     scanres->show();
00507     scanres->exec();
00508 }
00509 
00510 
00511 void WpaGui::eventHistory()
00512 {
00513     if (eh) {
00514         eh->close();
00515         delete eh;
00516     }
00517 
00518     eh = new EventHistory();
00519     if (eh == NULL)
00520         return;
00521     eh->addEvents(msgs);
00522     eh->show();
00523     eh->exec();
00524 }
00525 
00526 
00527 void WpaGui::ping()
00528 {
00529     char buf[10];
00530     size_t len;
00531     
00532 #ifdef CONFIG_CTRL_IFACE_NAMED_PIPE
00533     /*
00534      * QSocketNotifier cannot be used with Windows named pipes, so use a timer
00535      * to check for received messages for now. This could be optimized be doing
00536      * something specific to named pipes or Windows events, but it is not clear
00537      * what would be the best way of doing that in Qt.
00538      */
00539     receiveMsgs();
00540 #endif /* CONFIG_CTRL_IFACE_NAMED_PIPE */
00541 
00542     if (scanres && !scanres->isVisible()) {
00543         delete scanres;
00544         scanres = NULL;
00545     }
00546     
00547     if (eh && !eh->isVisible()) {
00548         delete eh;
00549         eh = NULL;
00550     }
00551     
00552     if (udr && !udr->isVisible()) {
00553         delete udr;
00554         udr = NULL;
00555     }
00556     
00557     len = sizeof(buf) - 1;
00558     if (ctrlRequest("PING", buf, &len) < 0) {
00559         printf("PING failed - trying to reconnect\n");
00560         if (openCtrlConnection(ctrl_iface) >= 0) {
00561             printf("Reconnected successfully\n");
00562             pingsToStatusUpdate = 0;
00563         }
00564     }
00565 
00566     pingsToStatusUpdate--;
00567     if (pingsToStatusUpdate <= 0) {
00568         updateStatus();
00569         updateNetworks();
00570     }
00571 }
00572 
00573 
00574 static int str_match(const char *a, const char *b)
00575 {
00576     return strncmp(a, b, strlen(b)) == 0;
00577 }
00578 
00579 
00580 void WpaGui::processMsg(char *msg)
00581 {
00582     char *pos = msg, *pos2;
00583     int priority = 2;
00584     
00585     if (*pos == '<') {
00586         /* skip priority */
00587         pos++;
00588         priority = atoi(pos);
00589         pos = strchr(pos, '>');
00590         if (pos)
00591             pos++;
00592         else
00593             pos = msg;
00594     }
00595 
00596     WpaMsg wm(pos, priority);
00597     if (eh)
00598         eh->addEvent(wm);
00599     msgs.append(wm);
00600     while (msgs.count() > 100)
00601         msgs.pop_front();
00602     
00603     /* Update last message with truncated version of the event */
00604     if (strncmp(pos, "CTRL-", 5) == 0) {
00605         pos2 = strchr(pos, str_match(pos, WPA_CTRL_REQ) ? ':' : ' ');
00606         if (pos2)
00607             pos2++;
00608         else
00609             pos2 = pos;
00610     } else
00611         pos2 = pos;
00612     QString lastmsg = pos2;
00613     lastmsg.truncate(40);
00614     textLastMessage->setText(lastmsg);
00615     
00616     pingsToStatusUpdate = 0;
00617     networkMayHaveChanged = true;
00618     
00619     if (str_match(pos, WPA_CTRL_REQ))
00620         processCtrlReq(pos + strlen(WPA_CTRL_REQ));
00621 }
00622 
00623 
00624 void WpaGui::processCtrlReq(const char *req)
00625 {
00626     if (udr) {
00627         udr->close();
00628         delete udr;
00629     }
00630     udr = new UserDataRequest();
00631     if (udr == NULL)
00632         return;
00633     if (udr->setParams(this, req) < 0) {
00634         delete udr;
00635         udr = NULL;
00636         return;
00637     }
00638     udr->show();
00639     udr->exec();
00640 }
00641 
00642 
00643 void WpaGui::receiveMsgs()
00644 {
00645     char buf[256];
00646     size_t len;
00647     
00648     while (monitor_conn && wpa_ctrl_pending(monitor_conn) > 0) {
00649         len = sizeof(buf) - 1;
00650         if (wpa_ctrl_recv(monitor_conn, buf, &len) == 0) {
00651             buf[len] = '\0';
00652             processMsg(buf);
00653         }
00654     }
00655 }
00656 
00657 
00658 void WpaGui::connectB()
00659 {
00660     char reply[10];
00661     size_t reply_len = sizeof(reply);
00662     ctrlRequest("REASSOCIATE", reply, &reply_len);
00663 }
00664 
00665 
00666 void WpaGui::selectNetwork( const QString &sel )
00667 {
00668     QString cmd(sel);
00669     char reply[10];
00670     size_t reply_len = sizeof(reply);
00671     
00672     int pos = cmd.find(':');
00673     if (pos < 0) {
00674         printf("Invalid selectNetwork '%s'\n", cmd.ascii());
00675         return;
00676     }
00677     cmd.truncate(pos);
00678     cmd.prepend("SELECT_NETWORK ");
00679     ctrlRequest(cmd.ascii(), reply, &reply_len);
00680 }
00681 
00682 
00683 void WpaGui::editNetwork()
00684 {
00685     QString sel(networkSelect->currentText());
00686     int pos = sel.find(':');
00687     if (pos < 0) {
00688         printf("Invalid selectNetwork '%s'\n", sel.ascii());
00689         return;
00690     }
00691     sel.truncate(pos);
00692     
00693     NetworkConfig *nc = new NetworkConfig();
00694     if (nc == NULL)
00695         return;
00696     nc->setWpaGui(this);
00697     
00698     nc->paramsFromConfig(sel.toInt());
00699     nc->show();
00700     nc->exec();
00701 }
00702 
00703 
00704 void WpaGui::triggerUpdate()
00705 {
00706     updateStatus();
00707     networkMayHaveChanged = true;
00708     updateNetworks();
00709 }
00710 
00711 
00712 void WpaGui::addNetwork()
00713 {
00714     NetworkConfig *nc = new NetworkConfig();
00715     if (nc == NULL)
00716         return;
00717     nc->setWpaGui(this);
00718     nc->newNetwork();
00719     nc->show();
00720     nc->exec();
00721 }
00722 
00723 
00724 void WpaGui::selectAdapter( const QString & sel )
00725 {
00726     if (openCtrlConnection(sel.ascii()) < 0)
00727         printf("Failed to open control connection to wpa_supplicant.\n");
00728     updateStatus();
00729     updateNetworks();
00730 }


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