1 /****************************************************************************
2 ** ui.h extension file, included from the uic-generated form implementation.
4 ** If you want to add, delete, or rename functions or slots, use
5 ** Qt Designer to update this file, preserving your code.
7 ** You should not define a constructor or destructor in this file.
8 ** Instead, write your code in functions called init() and destroy().
9 ** These will automatically be called by the form's constructor and
11 *****************************************************************************/
15 /* Need to get getopt() */
29 ctrl_iface_dir = strdup("/var/run/wpa_supplicant");
33 textStatus->setText("connecting to wpa_supplicant");
34 timer = new QTimer(this);
35 connect(timer, SIGNAL(timeout()), SLOT(ping()));
36 timer->start(1000, FALSE);
38 if (openCtrlConnection(ctrl_iface) < 0) {
39 printf("Failed to open control connection to wpa_supplicant.\n");
43 networkMayHaveChanged = true;
48 void WpaGui::destroy()
53 wpa_ctrl_detach(monitor_conn);
54 wpa_ctrl_close(monitor_conn);
58 wpa_ctrl_close(ctrl_conn);
84 ctrl_iface_dir = NULL;
88 void WpaGui::parse_argv()
92 c = getopt(qApp->argc(), qApp->argv(), "i:p:");
98 ctrl_iface = strdup(optarg);
101 free(ctrl_iface_dir);
102 ctrl_iface_dir = strdup(optarg);
109 int WpaGui::openCtrlConnection(const char *ifname)
113 char buf[2048], *pos, *pos2;
117 if (ifname != ctrl_iface) {
119 ctrl_iface = strdup(ifname);
122 #ifdef CONFIG_CTRL_IFACE_UDP
124 ctrl_iface = strdup("udp");
125 #endif /* CONFIG_CTRL_IFACE_UDP */
126 #ifdef CONFIG_CTRL_IFACE_UNIX
128 DIR *dir = opendir(ctrl_iface_dir);
132 while ((dent = readdir(dir))) {
133 #ifdef _DIRENT_HAVE_D_TYPE
134 /* Skip the file if it is not a socket.
135 * Also accept DT_UNKNOWN (0) in case
136 * the C library or underlying file
137 * system does not support d_type. */
138 if (dent->d_type != DT_SOCK &&
139 dent->d_type != DT_UNKNOWN)
141 #endif /* _DIRENT_HAVE_D_TYPE */
143 if (strcmp(dent->d_name, ".") == 0 ||
144 strcmp(dent->d_name, "..") == 0)
146 printf("Selected interface '%s'\n", dent->d_name);
147 ctrl_iface = strdup(dent->d_name);
152 #endif /* CONFIG_CTRL_IFACE_UNIX */
153 #ifdef CONFIG_CTRL_IFACE_NAMED_PIPE
154 struct wpa_ctrl *ctrl;
160 ctrl = wpa_ctrl_open(NULL);
162 len = sizeof(buf) - 1;
163 ret = wpa_ctrl_request(ctrl, "INTERFACES", 10, buf, &len, NULL);
166 pos = strchr(buf, '\n');
169 ctrl_iface = strdup(buf);
171 wpa_ctrl_close(ctrl);
173 #endif /* CONFIG_CTRL_IFACE_NAMED_PIPE */
176 if (ctrl_iface == NULL)
179 #ifdef CONFIG_CTRL_IFACE_UNIX
180 flen = strlen(ctrl_iface_dir) + strlen(ctrl_iface) + 2;
181 cfile = (char *) malloc(flen);
184 snprintf(cfile, flen, "%s/%s", ctrl_iface_dir, ctrl_iface);
185 #else /* CONFIG_CTRL_IFACE_UNIX */
186 flen = strlen(ctrl_iface) + 1;
187 cfile = (char *) malloc(flen);
190 snprintf(cfile, flen, "%s", ctrl_iface);
191 #endif /* CONFIG_CTRL_IFACE_UNIX */
194 wpa_ctrl_close(ctrl_conn);
201 wpa_ctrl_detach(monitor_conn);
202 wpa_ctrl_close(monitor_conn);
206 printf("Trying to connect to '%s'\n", cfile);
207 ctrl_conn = wpa_ctrl_open(cfile);
208 if (ctrl_conn == NULL) {
212 monitor_conn = wpa_ctrl_open(cfile);
214 if (monitor_conn == NULL) {
215 wpa_ctrl_close(ctrl_conn);
218 if (wpa_ctrl_attach(monitor_conn)) {
219 printf("Failed to attach to wpa_supplicant\n");
220 wpa_ctrl_close(monitor_conn);
222 wpa_ctrl_close(ctrl_conn);
227 #if defined(CONFIG_CTRL_IFACE_UNIX) || defined(CONFIG_CTRL_IFACE_UDP)
228 msgNotifier = new QSocketNotifier(wpa_ctrl_get_fd(monitor_conn),
229 QSocketNotifier::Read, this);
230 connect(msgNotifier, SIGNAL(activated(int)), SLOT(receiveMsgs()));
233 adapterSelect->clear();
234 adapterSelect->insertItem(ctrl_iface);
235 adapterSelect->setCurrentItem(0);
237 len = sizeof(buf) - 1;
238 if (wpa_ctrl_request(ctrl_conn, "INTERFACES", 10, buf, &len, NULL) >= 0) {
242 pos2 = strchr(pos, '\n');
245 if (strcmp(pos, ctrl_iface) != 0)
246 adapterSelect->insertItem(pos);
258 static void wpa_gui_msg_cb(char *msg, size_t)
260 /* This should not happen anymore since two control connections are used. */
261 printf("missed message: %s\n", msg);
265 int WpaGui::ctrlRequest(const char *cmd, char *buf, size_t *buflen)
269 if (ctrl_conn == NULL)
271 ret = wpa_ctrl_request(ctrl_conn, cmd, strlen(cmd), buf, buflen,
274 printf("'%s' command timed out.\n", cmd);
275 } else if (ret < 0) {
276 printf("'%s' command failed.\n", cmd);
283 void WpaGui::updateStatus()
285 char buf[2048], *start, *end, *pos;
288 pingsToStatusUpdate = 10;
290 len = sizeof(buf) - 1;
291 if (ctrl_conn == NULL || ctrlRequest("STATUS", buf, &len) < 0) {
292 textStatus->setText("Could not get status from wpa_supplicant");
293 textAuthentication->clear();
294 textEncryption->clear();
297 textIpAddress->clear();
303 bool auth_updated = false, ssid_updated = false;
304 bool bssid_updated = false, ipaddr_updated = false;
305 bool status_updated = false;
306 char *pairwise_cipher = NULL, *group_cipher = NULL;
311 end = strchr(start, '\n');
315 while (end[0] && end[1])
320 pos = strchr(start, '=');
323 if (strcmp(start, "bssid") == 0) {
324 bssid_updated = true;
325 textBssid->setText(pos);
326 } else if (strcmp(start, "ssid") == 0) {
328 textSsid->setText(pos);
329 } else if (strcmp(start, "ip_address") == 0) {
330 ipaddr_updated = true;
331 textIpAddress->setText(pos);
332 } else if (strcmp(start, "wpa_state") == 0) {
333 status_updated = true;
334 textStatus->setText(pos);
335 } else if (strcmp(start, "key_mgmt") == 0) {
337 textAuthentication->setText(pos);
338 /* TODO: could add EAP status to this */
339 } else if (strcmp(start, "pairwise_cipher") == 0) {
340 pairwise_cipher = pos;
341 } else if (strcmp(start, "group_cipher") == 0) {
351 if (pairwise_cipher || group_cipher) {
353 if (pairwise_cipher && group_cipher &&
354 strcmp(pairwise_cipher, group_cipher) != 0) {
355 encr.append(pairwise_cipher);
357 encr.append(group_cipher);
358 } else if (pairwise_cipher) {
359 encr.append(pairwise_cipher);
361 encr.append(group_cipher);
362 encr.append(" [group key only]");
364 textEncryption->setText(encr);
366 textEncryption->clear();
371 textAuthentication->clear();
377 textIpAddress->clear();
381 void WpaGui::updateNetworks()
383 char buf[2048], *start, *end, *id, *ssid, *bssid, *flags;
385 int first_active = -1;
386 bool selected = false;
388 if (!networkMayHaveChanged)
391 networkSelect->clear();
393 if (ctrl_conn == NULL)
396 len = sizeof(buf) - 1;
397 if (ctrlRequest("LIST_NETWORKS", buf, &len) < 0)
401 start = strchr(buf, '\n');
408 end = strchr(start, '\n');
412 while (end[0] && end[1])
418 ssid = strchr(id, '\t');
422 bssid = strchr(ssid, '\t');
426 flags = strchr(bssid, '\t');
432 network.append(": ");
433 network.append(ssid);
434 networkSelect->insertItem(network);
436 if (strstr(flags, "[CURRENT]")) {
437 networkSelect->setCurrentItem(networkSelect->count() - 1);
439 } else if (first_active < 0 && strstr(flags, "[DISABLED]") == NULL)
440 first_active = networkSelect->count() - 1;
447 if (!selected && first_active >= 0)
448 networkSelect->setCurrentItem(first_active);
450 networkMayHaveChanged = false;
454 void WpaGui::helpIndex()
456 printf("helpIndex\n");
460 void WpaGui::helpContents()
462 printf("helpContents\n");
466 void WpaGui::helpAbout()
468 QMessageBox::about(this, "wpa_gui for wpa_supplicant",
469 "Copyright (c) 2003-2008,\n"
470 "Jouni Malinen <j@w1.fi>\n"
471 "and contributors.\n"
473 "This program is free software. You can\n"
474 "distribute it and/or modify it under the terms of\n"
475 "the GNU General Public License version 2.\n"
477 "Alternatively, this software may be distributed\n"
478 "under the terms of the BSD license.\n"
480 "This product includes software developed\n"
481 "by the OpenSSL Project for use in the\n"
482 "OpenSSL Toolkit (http://www.openssl.org/)\n");
486 void WpaGui::disconnect()
489 size_t reply_len = sizeof(reply);
490 ctrlRequest("DISCONNECT", reply, &reply_len);
501 scanres = new ScanResults();
504 scanres->setWpaGui(this);
510 void WpaGui::eventHistory()
517 eh = new EventHistory();
531 #ifdef CONFIG_CTRL_IFACE_NAMED_PIPE
533 * QSocketNotifier cannot be used with Windows named pipes, so use a timer
534 * to check for received messages for now. This could be optimized be doing
535 * something specific to named pipes or Windows events, but it is not clear
536 * what would be the best way of doing that in Qt.
539 #endif /* CONFIG_CTRL_IFACE_NAMED_PIPE */
541 if (scanres && !scanres->isVisible()) {
546 if (eh && !eh->isVisible()) {
551 if (udr && !udr->isVisible()) {
556 len = sizeof(buf) - 1;
557 if (ctrlRequest("PING", buf, &len) < 0) {
558 printf("PING failed - trying to reconnect\n");
559 if (openCtrlConnection(ctrl_iface) >= 0) {
560 printf("Reconnected successfully\n");
561 pingsToStatusUpdate = 0;
565 pingsToStatusUpdate--;
566 if (pingsToStatusUpdate <= 0) {
573 static int str_match(const char *a, const char *b)
575 return strncmp(a, b, strlen(b)) == 0;
579 void WpaGui::processMsg(char *msg)
581 char *pos = msg, *pos2;
587 priority = atoi(pos);
588 pos = strchr(pos, '>');
595 WpaMsg wm(pos, priority);
599 while (msgs.count() > 100)
602 /* Update last message with truncated version of the event */
603 if (strncmp(pos, "CTRL-", 5) == 0) {
604 pos2 = strchr(pos, str_match(pos, WPA_CTRL_REQ) ? ':' : ' ');
611 QString lastmsg = pos2;
612 lastmsg.truncate(40);
613 textLastMessage->setText(lastmsg);
615 pingsToStatusUpdate = 0;
616 networkMayHaveChanged = true;
618 if (str_match(pos, WPA_CTRL_REQ))
619 processCtrlReq(pos + strlen(WPA_CTRL_REQ));
623 void WpaGui::processCtrlReq(const char *req)
629 udr = new UserDataRequest();
632 if (udr->setParams(this, req) < 0) {
642 void WpaGui::receiveMsgs()
647 while (monitor_conn && wpa_ctrl_pending(monitor_conn) > 0) {
648 len = sizeof(buf) - 1;
649 if (wpa_ctrl_recv(monitor_conn, buf, &len) == 0) {
657 void WpaGui::connectB()
660 size_t reply_len = sizeof(reply);
661 ctrlRequest("REASSOCIATE", reply, &reply_len);
665 void WpaGui::selectNetwork( const QString &sel )
669 size_t reply_len = sizeof(reply);
671 int pos = cmd.find(':');
673 printf("Invalid selectNetwork '%s'\n", cmd.ascii());
677 cmd.prepend("SELECT_NETWORK ");
678 ctrlRequest(cmd.ascii(), reply, &reply_len);
682 void WpaGui::editNetwork()
684 QString sel(networkSelect->currentText());
685 int pos = sel.find(':');
687 printf("Invalid selectNetwork '%s'\n", sel.ascii());
692 NetworkConfig *nc = new NetworkConfig();
697 nc->paramsFromConfig(sel.toInt());
703 void WpaGui::triggerUpdate()
706 networkMayHaveChanged = true;
711 void WpaGui::addNetwork()
713 NetworkConfig *nc = new NetworkConfig();
723 void WpaGui::selectAdapter( const QString & sel )
725 if (openCtrlConnection(sel.ascii()) < 0)
726 printf("Failed to open control connection to wpa_supplicant.\n");