Share a single Linux ioctl helper fo setting interface up/down
[hostap-gosc2009.git] / wpa_supplicant / wpa_gui / wpagui.ui.h
blob678ff1be354b43396c8a035b8f883b2b97189a42
1 /****************************************************************************
2 ** ui.h extension file, included from the uic-generated form implementation.
3 **
4 ** If you want to add, delete, or rename functions or slots, use
5 ** Qt Designer to update this file, preserving your code.
6 **
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
10 ** destructor.
11 *****************************************************************************/
14 #ifdef __MINGW32__
15 /* Need to get getopt() */
16 #include <unistd.h>
17 #endif
19 #include <stdlib.h>
21 void WpaGui::init()
23 eh = NULL;
24 scanres = NULL;
25 udr = NULL;
26 ctrl_iface = NULL;
27 ctrl_conn = NULL;
28 monitor_conn = NULL;
29 msgNotifier = NULL;
30 ctrl_iface_dir = strdup("/var/run/wpa_supplicant");
32 parse_argv();
34 textStatus->setText("connecting to wpa_supplicant");
35 timer = new QTimer(this);
36 connect(timer, SIGNAL(timeout()), SLOT(ping()));
37 timer->start(1000, FALSE);
39 if (openCtrlConnection(ctrl_iface) < 0) {
40 printf("Failed to open control connection to wpa_supplicant.\n");
43 updateStatus();
44 networkMayHaveChanged = true;
45 updateNetworks();
49 void WpaGui::destroy()
51 delete msgNotifier;
53 if (monitor_conn) {
54 wpa_ctrl_detach(monitor_conn);
55 wpa_ctrl_close(monitor_conn);
56 monitor_conn = NULL;
58 if (ctrl_conn) {
59 wpa_ctrl_close(ctrl_conn);
60 ctrl_conn = NULL;
63 if (eh) {
64 eh->close();
65 delete eh;
66 eh = NULL;
69 if (scanres) {
70 scanres->close();
71 delete scanres;
72 scanres = NULL;
75 if (udr) {
76 udr->close();
77 delete udr;
78 udr = NULL;
81 free(ctrl_iface);
82 ctrl_iface = NULL;
84 free(ctrl_iface_dir);
85 ctrl_iface_dir = NULL;
89 void WpaGui::parse_argv()
91 int c;
92 for (;;) {
93 c = getopt(qApp->argc(), qApp->argv(), "i:p:");
94 if (c < 0)
95 break;
96 switch (c) {
97 case 'i':
98 free(ctrl_iface);
99 ctrl_iface = strdup(optarg);
100 break;
101 case 'p':
102 free(ctrl_iface_dir);
103 ctrl_iface_dir = strdup(optarg);
104 break;
110 int WpaGui::openCtrlConnection(const char *ifname)
112 char *cfile;
113 int flen;
114 char buf[2048], *pos, *pos2;
115 size_t len;
117 if (ifname) {
118 if (ifname != ctrl_iface) {
119 free(ctrl_iface);
120 ctrl_iface = strdup(ifname);
122 } else {
123 #ifdef CONFIG_CTRL_IFACE_UDP
124 free(ctrl_iface);
125 ctrl_iface = strdup("udp");
126 #endif /* CONFIG_CTRL_IFACE_UDP */
127 #ifdef CONFIG_CTRL_IFACE_UNIX
128 struct dirent *dent;
129 DIR *dir = opendir(ctrl_iface_dir);
130 free(ctrl_iface);
131 ctrl_iface = NULL;
132 if (dir) {
133 while ((dent = readdir(dir))) {
134 #ifdef _DIRENT_HAVE_D_TYPE
135 /* Skip the file if it is not a socket.
136 * Also accept DT_UNKNOWN (0) in case
137 * the C library or underlying file
138 * system does not support d_type. */
139 if (dent->d_type != DT_SOCK &&
140 dent->d_type != DT_UNKNOWN)
141 continue;
142 #endif /* _DIRENT_HAVE_D_TYPE */
144 if (strcmp(dent->d_name, ".") == 0 ||
145 strcmp(dent->d_name, "..") == 0)
146 continue;
147 printf("Selected interface '%s'\n", dent->d_name);
148 ctrl_iface = strdup(dent->d_name);
149 break;
151 closedir(dir);
153 #endif /* CONFIG_CTRL_IFACE_UNIX */
154 #ifdef CONFIG_CTRL_IFACE_NAMED_PIPE
155 struct wpa_ctrl *ctrl;
156 int ret;
158 free(ctrl_iface);
159 ctrl_iface = NULL;
161 ctrl = wpa_ctrl_open(NULL);
162 if (ctrl) {
163 len = sizeof(buf) - 1;
164 ret = wpa_ctrl_request(ctrl, "INTERFACES", 10, buf, &len, NULL);
165 if (ret >= 0) {
166 buf[len] = '\0';
167 pos = strchr(buf, '\n');
168 if (pos)
169 *pos = '\0';
170 ctrl_iface = strdup(buf);
172 wpa_ctrl_close(ctrl);
174 #endif /* CONFIG_CTRL_IFACE_NAMED_PIPE */
177 if (ctrl_iface == NULL)
178 return -1;
180 #ifdef CONFIG_CTRL_IFACE_UNIX
181 flen = strlen(ctrl_iface_dir) + strlen(ctrl_iface) + 2;
182 cfile = (char *) malloc(flen);
183 if (cfile == NULL)
184 return -1;
185 snprintf(cfile, flen, "%s/%s", ctrl_iface_dir, ctrl_iface);
186 #else /* CONFIG_CTRL_IFACE_UNIX */
187 flen = strlen(ctrl_iface) + 1;
188 cfile = (char *) malloc(flen);
189 if (cfile == NULL)
190 return -1;
191 snprintf(cfile, flen, "%s", ctrl_iface);
192 #endif /* CONFIG_CTRL_IFACE_UNIX */
194 if (ctrl_conn) {
195 wpa_ctrl_close(ctrl_conn);
196 ctrl_conn = NULL;
199 if (monitor_conn) {
200 delete msgNotifier;
201 msgNotifier = NULL;
202 wpa_ctrl_detach(monitor_conn);
203 wpa_ctrl_close(monitor_conn);
204 monitor_conn = NULL;
207 printf("Trying to connect to '%s'\n", cfile);
208 ctrl_conn = wpa_ctrl_open(cfile);
209 if (ctrl_conn == NULL) {
210 free(cfile);
211 return -1;
213 monitor_conn = wpa_ctrl_open(cfile);
214 free(cfile);
215 if (monitor_conn == NULL) {
216 wpa_ctrl_close(ctrl_conn);
217 return -1;
219 if (wpa_ctrl_attach(monitor_conn)) {
220 printf("Failed to attach to wpa_supplicant\n");
221 wpa_ctrl_close(monitor_conn);
222 monitor_conn = NULL;
223 wpa_ctrl_close(ctrl_conn);
224 ctrl_conn = NULL;
225 return -1;
228 #if defined(CONFIG_CTRL_IFACE_UNIX) || defined(CONFIG_CTRL_IFACE_UDP)
229 msgNotifier = new QSocketNotifier(wpa_ctrl_get_fd(monitor_conn),
230 QSocketNotifier::Read, this);
231 connect(msgNotifier, SIGNAL(activated(int)), SLOT(receiveMsgs()));
232 #endif
234 adapterSelect->clear();
235 adapterSelect->insertItem(ctrl_iface);
236 adapterSelect->setCurrentItem(0);
238 len = sizeof(buf) - 1;
239 if (wpa_ctrl_request(ctrl_conn, "INTERFACES", 10, buf, &len, NULL) >= 0) {
240 buf[len] = '\0';
241 pos = buf;
242 while (*pos) {
243 pos2 = strchr(pos, '\n');
244 if (pos2)
245 *pos2 = '\0';
246 if (strcmp(pos, ctrl_iface) != 0)
247 adapterSelect->insertItem(pos);
248 if (pos2)
249 pos = pos2 + 1;
250 else
251 break;
255 return 0;
259 static void wpa_gui_msg_cb(char *msg, size_t)
261 /* This should not happen anymore since two control connections are used. */
262 printf("missed message: %s\n", msg);
266 int WpaGui::ctrlRequest(const char *cmd, char *buf, size_t *buflen)
268 int ret;
270 if (ctrl_conn == NULL)
271 return -3;
272 ret = wpa_ctrl_request(ctrl_conn, cmd, strlen(cmd), buf, buflen,
273 wpa_gui_msg_cb);
274 if (ret == -2) {
275 printf("'%s' command timed out.\n", cmd);
276 } else if (ret < 0) {
277 printf("'%s' command failed.\n", cmd);
280 return ret;
284 void WpaGui::updateStatus()
286 char buf[2048], *start, *end, *pos;
287 size_t len;
289 pingsToStatusUpdate = 10;
291 len = sizeof(buf) - 1;
292 if (ctrl_conn == NULL || ctrlRequest("STATUS", buf, &len) < 0) {
293 textStatus->setText("Could not get status from wpa_supplicant");
294 textAuthentication->clear();
295 textEncryption->clear();
296 textSsid->clear();
297 textBssid->clear();
298 textIpAddress->clear();
299 return;
302 buf[len] = '\0';
304 bool auth_updated = false, ssid_updated = false;
305 bool bssid_updated = false, ipaddr_updated = false;
306 bool status_updated = false;
307 char *pairwise_cipher = NULL, *group_cipher = NULL;
309 start = buf;
310 while (*start) {
311 bool last = false;
312 end = strchr(start, '\n');
313 if (end == NULL) {
314 last = true;
315 end = start;
316 while (end[0] && end[1])
317 end++;
319 *end = '\0';
321 pos = strchr(start, '=');
322 if (pos) {
323 *pos++ = '\0';
324 if (strcmp(start, "bssid") == 0) {
325 bssid_updated = true;
326 textBssid->setText(pos);
327 } else if (strcmp(start, "ssid") == 0) {
328 ssid_updated = true;
329 textSsid->setText(pos);
330 } else if (strcmp(start, "ip_address") == 0) {
331 ipaddr_updated = true;
332 textIpAddress->setText(pos);
333 } else if (strcmp(start, "wpa_state") == 0) {
334 status_updated = true;
335 textStatus->setText(pos);
336 } else if (strcmp(start, "key_mgmt") == 0) {
337 auth_updated = true;
338 textAuthentication->setText(pos);
339 /* TODO: could add EAP status to this */
340 } else if (strcmp(start, "pairwise_cipher") == 0) {
341 pairwise_cipher = pos;
342 } else if (strcmp(start, "group_cipher") == 0) {
343 group_cipher = pos;
347 if (last)
348 break;
349 start = end + 1;
352 if (pairwise_cipher || group_cipher) {
353 QString encr;
354 if (pairwise_cipher && group_cipher &&
355 strcmp(pairwise_cipher, group_cipher) != 0) {
356 encr.append(pairwise_cipher);
357 encr.append(" + ");
358 encr.append(group_cipher);
359 } else if (pairwise_cipher) {
360 encr.append(pairwise_cipher);
361 } else {
362 encr.append(group_cipher);
363 encr.append(" [group key only]");
365 textEncryption->setText(encr);
366 } else
367 textEncryption->clear();
369 if (!status_updated)
370 textStatus->clear();
371 if (!auth_updated)
372 textAuthentication->clear();
373 if (!ssid_updated)
374 textSsid->clear();
375 if (!bssid_updated)
376 textBssid->clear();
377 if (!ipaddr_updated)
378 textIpAddress->clear();
382 void WpaGui::updateNetworks()
384 char buf[2048], *start, *end, *id, *ssid, *bssid, *flags;
385 size_t len;
386 int first_active = -1;
387 bool selected = false;
389 if (!networkMayHaveChanged)
390 return;
392 networkSelect->clear();
394 if (ctrl_conn == NULL)
395 return;
397 len = sizeof(buf) - 1;
398 if (ctrlRequest("LIST_NETWORKS", buf, &len) < 0)
399 return;
401 buf[len] = '\0';
402 start = strchr(buf, '\n');
403 if (start == NULL)
404 return;
405 start++;
407 while (*start) {
408 bool last = false;
409 end = strchr(start, '\n');
410 if (end == NULL) {
411 last = true;
412 end = start;
413 while (end[0] && end[1])
414 end++;
416 *end = '\0';
418 id = start;
419 ssid = strchr(id, '\t');
420 if (ssid == NULL)
421 break;
422 *ssid++ = '\0';
423 bssid = strchr(ssid, '\t');
424 if (bssid == NULL)
425 break;
426 *bssid++ = '\0';
427 flags = strchr(bssid, '\t');
428 if (flags == NULL)
429 break;
430 *flags++ = '\0';
432 QString network(id);
433 network.append(": ");
434 network.append(ssid);
435 networkSelect->insertItem(network);
437 if (strstr(flags, "[CURRENT]")) {
438 networkSelect->setCurrentItem(networkSelect->count() - 1);
439 selected = true;
440 } else if (first_active < 0 && strstr(flags, "[DISABLED]") == NULL)
441 first_active = networkSelect->count() - 1;
443 if (last)
444 break;
445 start = end + 1;
448 if (!selected && first_active >= 0)
449 networkSelect->setCurrentItem(first_active);
451 networkMayHaveChanged = false;
455 void WpaGui::helpIndex()
457 printf("helpIndex\n");
461 void WpaGui::helpContents()
463 printf("helpContents\n");
467 void WpaGui::helpAbout()
469 QMessageBox::about(this, "wpa_gui for wpa_supplicant",
470 "Copyright (c) 2003-2008,\n"
471 "Jouni Malinen <j@w1.fi>\n"
472 "and contributors.\n"
473 "\n"
474 "This program is free software. You can\n"
475 "distribute it and/or modify it under the terms of\n"
476 "the GNU General Public License version 2.\n"
477 "\n"
478 "Alternatively, this software may be distributed\n"
479 "under the terms of the BSD license.\n"
480 "\n"
481 "This product includes software developed\n"
482 "by the OpenSSL Project for use in the\n"
483 "OpenSSL Toolkit (http://www.openssl.org/)\n");
487 void WpaGui::disconnect()
489 char reply[10];
490 size_t reply_len = sizeof(reply);
491 ctrlRequest("DISCONNECT", reply, &reply_len);
495 void WpaGui::scan()
497 if (scanres) {
498 scanres->close();
499 delete scanres;
502 scanres = new ScanResults();
503 if (scanres == NULL)
504 return;
505 scanres->setWpaGui(this);
506 scanres->show();
507 scanres->exec();
511 void WpaGui::eventHistory()
513 if (eh) {
514 eh->close();
515 delete eh;
518 eh = new EventHistory();
519 if (eh == NULL)
520 return;
521 eh->addEvents(msgs);
522 eh->show();
523 eh->exec();
527 void WpaGui::ping()
529 char buf[10];
530 size_t len;
532 #ifdef CONFIG_CTRL_IFACE_NAMED_PIPE
534 * QSocketNotifier cannot be used with Windows named pipes, so use a timer
535 * to check for received messages for now. This could be optimized be doing
536 * something specific to named pipes or Windows events, but it is not clear
537 * what would be the best way of doing that in Qt.
539 receiveMsgs();
540 #endif /* CONFIG_CTRL_IFACE_NAMED_PIPE */
542 if (scanres && !scanres->isVisible()) {
543 delete scanres;
544 scanres = NULL;
547 if (eh && !eh->isVisible()) {
548 delete eh;
549 eh = NULL;
552 if (udr && !udr->isVisible()) {
553 delete udr;
554 udr = NULL;
557 len = sizeof(buf) - 1;
558 if (ctrlRequest("PING", buf, &len) < 0) {
559 printf("PING failed - trying to reconnect\n");
560 if (openCtrlConnection(ctrl_iface) >= 0) {
561 printf("Reconnected successfully\n");
562 pingsToStatusUpdate = 0;
566 pingsToStatusUpdate--;
567 if (pingsToStatusUpdate <= 0) {
568 updateStatus();
569 updateNetworks();
574 static int str_match(const char *a, const char *b)
576 return strncmp(a, b, strlen(b)) == 0;
580 void WpaGui::processMsg(char *msg)
582 char *pos = msg, *pos2;
583 int priority = 2;
585 if (*pos == '<') {
586 /* skip priority */
587 pos++;
588 priority = atoi(pos);
589 pos = strchr(pos, '>');
590 if (pos)
591 pos++;
592 else
593 pos = msg;
596 WpaMsg wm(pos, priority);
597 if (eh)
598 eh->addEvent(wm);
599 msgs.append(wm);
600 while (msgs.count() > 100)
601 msgs.pop_front();
603 /* Update last message with truncated version of the event */
604 if (strncmp(pos, "CTRL-", 5) == 0) {
605 pos2 = strchr(pos, str_match(pos, WPA_CTRL_REQ) ? ':' : ' ');
606 if (pos2)
607 pos2++;
608 else
609 pos2 = pos;
610 } else
611 pos2 = pos;
612 QString lastmsg = pos2;
613 lastmsg.truncate(40);
614 textLastMessage->setText(lastmsg);
616 pingsToStatusUpdate = 0;
617 networkMayHaveChanged = true;
619 if (str_match(pos, WPA_CTRL_REQ))
620 processCtrlReq(pos + strlen(WPA_CTRL_REQ));
624 void WpaGui::processCtrlReq(const char *req)
626 if (udr) {
627 udr->close();
628 delete udr;
630 udr = new UserDataRequest();
631 if (udr == NULL)
632 return;
633 if (udr->setParams(this, req) < 0) {
634 delete udr;
635 udr = NULL;
636 return;
638 udr->show();
639 udr->exec();
643 void WpaGui::receiveMsgs()
645 char buf[256];
646 size_t len;
648 while (monitor_conn && wpa_ctrl_pending(monitor_conn) > 0) {
649 len = sizeof(buf) - 1;
650 if (wpa_ctrl_recv(monitor_conn, buf, &len) == 0) {
651 buf[len] = '\0';
652 processMsg(buf);
658 void WpaGui::connectB()
660 char reply[10];
661 size_t reply_len = sizeof(reply);
662 ctrlRequest("REASSOCIATE", reply, &reply_len);
666 void WpaGui::selectNetwork( const QString &sel )
668 QString cmd(sel);
669 char reply[10];
670 size_t reply_len = sizeof(reply);
672 int pos = cmd.find(':');
673 if (pos < 0) {
674 printf("Invalid selectNetwork '%s'\n", cmd.ascii());
675 return;
677 cmd.truncate(pos);
678 cmd.prepend("SELECT_NETWORK ");
679 ctrlRequest(cmd.ascii(), reply, &reply_len);
683 void WpaGui::editNetwork()
685 QString sel(networkSelect->currentText());
686 int pos = sel.find(':');
687 if (pos < 0) {
688 printf("Invalid selectNetwork '%s'\n", sel.ascii());
689 return;
691 sel.truncate(pos);
693 NetworkConfig *nc = new NetworkConfig();
694 if (nc == NULL)
695 return;
696 nc->setWpaGui(this);
698 nc->paramsFromConfig(sel.toInt());
699 nc->show();
700 nc->exec();
704 void WpaGui::triggerUpdate()
706 updateStatus();
707 networkMayHaveChanged = true;
708 updateNetworks();
712 void WpaGui::addNetwork()
714 NetworkConfig *nc = new NetworkConfig();
715 if (nc == NULL)
716 return;
717 nc->setWpaGui(this);
718 nc->newNetwork();
719 nc->show();
720 nc->exec();
724 void WpaGui::selectAdapter( const QString & sel )
726 if (openCtrlConnection(sel.ascii()) < 0)
727 printf("Failed to open control connection to wpa_supplicant.\n");
728 updateStatus();
729 updateNetworks();