Re-initialize hostapd/wpa_supplicant git repository based on 0.6.3 release
[mech_eap.git] / wpa_supplicant / wpa_gui / wpagui.ui.h
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 *****************************************************************************/
12
13
14 #ifdef __MINGW32__
15 /* Need to get getopt() */
16 #include <unistd.h>
17 #endif
18
19
20 void WpaGui::init()
21 {
22     eh = NULL;
23     scanres = NULL;
24     udr = NULL;
25     ctrl_iface = NULL;
26     ctrl_conn = NULL;
27     monitor_conn = NULL;
28     msgNotifier = NULL;
29     ctrl_iface_dir = strdup("/var/run/wpa_supplicant");
30     
31     parse_argv();
32
33     textStatus->setText("connecting to wpa_supplicant");
34     timer = new QTimer(this);
35     connect(timer, SIGNAL(timeout()), SLOT(ping()));
36     timer->start(1000, FALSE);
37     
38     if (openCtrlConnection(ctrl_iface) < 0) {
39         printf("Failed to open control connection to wpa_supplicant.\n");
40     }
41     
42     updateStatus();
43     networkMayHaveChanged = true;
44     updateNetworks();
45 }
46
47
48 void WpaGui::destroy()
49 {
50     delete msgNotifier;
51
52     if (monitor_conn) {
53         wpa_ctrl_detach(monitor_conn);
54         wpa_ctrl_close(monitor_conn);
55         monitor_conn = NULL;
56     }
57     if (ctrl_conn) {
58         wpa_ctrl_close(ctrl_conn);
59         ctrl_conn = NULL;
60     }
61     
62     if (eh) {
63         eh->close();
64         delete eh;
65         eh = NULL;
66     }
67     
68     if (scanres) {
69         scanres->close();
70         delete scanres;
71         scanres = NULL;
72     }
73     
74     if (udr) {
75         udr->close();
76         delete udr;
77         udr = NULL;
78     }
79     
80     free(ctrl_iface);
81     ctrl_iface = NULL;
82     
83     free(ctrl_iface_dir);
84     ctrl_iface_dir = NULL;
85 }
86
87
88 void WpaGui::parse_argv()
89 {
90     int c;
91     for (;;) {
92         c = getopt(qApp->argc(), qApp->argv(), "i:p:");
93         if (c < 0)
94             break;
95         switch (c) {
96         case 'i':
97             free(ctrl_iface);
98             ctrl_iface = strdup(optarg);
99             break;
100         case 'p':
101             free(ctrl_iface_dir);
102             ctrl_iface_dir = strdup(optarg);
103             break;
104         }
105     }
106 }
107
108
109 int WpaGui::openCtrlConnection(const char *ifname)
110 {
111     char *cfile;
112     int flen;
113     char buf[2048], *pos, *pos2;
114     size_t len;
115
116     if (ifname) {
117         if (ifname != ctrl_iface) {
118             free(ctrl_iface);
119             ctrl_iface = strdup(ifname);
120         }
121     } else {
122 #ifdef CONFIG_CTRL_IFACE_UDP
123         free(ctrl_iface);
124         ctrl_iface = strdup("udp");
125 #endif /* CONFIG_CTRL_IFACE_UDP */
126 #ifdef CONFIG_CTRL_IFACE_UNIX
127         struct dirent *dent;
128         DIR *dir = opendir(ctrl_iface_dir);
129         free(ctrl_iface);
130         ctrl_iface = NULL;
131         if (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)
140                     continue;
141 #endif /* _DIRENT_HAVE_D_TYPE */
142
143                 if (strcmp(dent->d_name, ".") == 0 ||
144                     strcmp(dent->d_name, "..") == 0)
145                     continue;
146                 printf("Selected interface '%s'\n", dent->d_name);
147                 ctrl_iface = strdup(dent->d_name);
148                 break;
149             }
150             closedir(dir);
151         }
152 #endif /* CONFIG_CTRL_IFACE_UNIX */
153 #ifdef CONFIG_CTRL_IFACE_NAMED_PIPE
154         struct wpa_ctrl *ctrl;
155         int ret;
156
157         free(ctrl_iface);
158         ctrl_iface = NULL;
159
160         ctrl = wpa_ctrl_open(NULL);
161         if (ctrl) {
162             len = sizeof(buf) - 1;
163             ret = wpa_ctrl_request(ctrl, "INTERFACES", 10, buf, &len, NULL);
164             if (ret >= 0) {
165                 buf[len] = '\0';
166                 pos = strchr(buf, '\n');
167                 if (pos)
168                     *pos = '\0';
169                 ctrl_iface = strdup(buf);
170             }
171             wpa_ctrl_close(ctrl);
172         }
173 #endif /* CONFIG_CTRL_IFACE_NAMED_PIPE */
174     }
175     
176     if (ctrl_iface == NULL)
177         return -1;
178
179 #ifdef CONFIG_CTRL_IFACE_UNIX
180     flen = strlen(ctrl_iface_dir) + strlen(ctrl_iface) + 2;
181     cfile = (char *) malloc(flen);
182     if (cfile == NULL)
183         return -1;
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);
188     if (cfile == NULL)
189         return -1;
190     snprintf(cfile, flen, "%s", ctrl_iface);
191 #endif /* CONFIG_CTRL_IFACE_UNIX */
192
193     if (ctrl_conn) {
194         wpa_ctrl_close(ctrl_conn);
195         ctrl_conn = NULL;
196     }
197
198     if (monitor_conn) {
199         delete msgNotifier;
200         msgNotifier = NULL;
201         wpa_ctrl_detach(monitor_conn);
202         wpa_ctrl_close(monitor_conn);
203         monitor_conn = NULL;
204     }
205
206     printf("Trying to connect to '%s'\n", cfile);
207     ctrl_conn = wpa_ctrl_open(cfile);
208     if (ctrl_conn == NULL) {
209         free(cfile);
210         return -1;
211     }
212     monitor_conn = wpa_ctrl_open(cfile);
213     free(cfile);
214     if (monitor_conn == NULL) {
215         wpa_ctrl_close(ctrl_conn);
216         return -1;
217     }
218     if (wpa_ctrl_attach(monitor_conn)) {
219         printf("Failed to attach to wpa_supplicant\n");
220         wpa_ctrl_close(monitor_conn);
221         monitor_conn = NULL;
222         wpa_ctrl_close(ctrl_conn);
223         ctrl_conn = NULL;
224         return -1;
225     }
226
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()));
231 #endif
232
233     adapterSelect->clear();
234     adapterSelect->insertItem(ctrl_iface);
235     adapterSelect->setCurrentItem(0);
236
237     len = sizeof(buf) - 1;
238     if (wpa_ctrl_request(ctrl_conn, "INTERFACES", 10, buf, &len, NULL) >= 0) {
239         buf[len] = '\0';
240         pos = buf;
241         while (*pos) {
242                 pos2 = strchr(pos, '\n');
243                 if (pos2)
244                         *pos2 = '\0';
245                 if (strcmp(pos, ctrl_iface) != 0)
246                         adapterSelect->insertItem(pos);
247                 if (pos2)
248                         pos = pos2 + 1;
249                 else
250                         break;
251         }
252     }
253
254     return 0;
255 }
256
257
258 static void wpa_gui_msg_cb(char *msg, size_t)
259 {
260     /* This should not happen anymore since two control connections are used. */
261     printf("missed message: %s\n", msg);
262 }
263
264
265 int WpaGui::ctrlRequest(const char *cmd, char *buf, size_t *buflen)
266 {
267     int ret;
268     
269     if (ctrl_conn == NULL)
270         return -3;
271     ret = wpa_ctrl_request(ctrl_conn, cmd, strlen(cmd), buf, buflen,
272                            wpa_gui_msg_cb);
273     if (ret == -2) {
274         printf("'%s' command timed out.\n", cmd);
275     } else if (ret < 0) {
276         printf("'%s' command failed.\n", cmd);
277     }
278     
279     return ret;
280 }
281
282
283 void WpaGui::updateStatus()
284 {
285     char buf[2048], *start, *end, *pos;
286     size_t len;
287
288     pingsToStatusUpdate = 10;
289
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();
295         textSsid->clear();
296         textBssid->clear();
297         textIpAddress->clear();
298         return;
299     }
300     
301     buf[len] = '\0';
302     
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;
307     
308     start = buf;
309     while (*start) {
310         bool last = false;
311         end = strchr(start, '\n');
312         if (end == NULL) {
313             last = true;
314             end = start;
315             while (end[0] && end[1])
316                 end++;
317         }
318         *end = '\0';
319         
320         pos = strchr(start, '=');
321         if (pos) {
322             *pos++ = '\0';
323             if (strcmp(start, "bssid") == 0) {
324                 bssid_updated = true;
325                 textBssid->setText(pos);
326             } else if (strcmp(start, "ssid") == 0) {
327                 ssid_updated = true;
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) {
336                 auth_updated = true;
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) {
342                 group_cipher = pos;
343             }
344         }
345         
346         if (last)
347             break;
348         start = end + 1;
349     }
350     
351     if (pairwise_cipher || group_cipher) {
352         QString encr;
353         if (pairwise_cipher && group_cipher &&
354             strcmp(pairwise_cipher, group_cipher) != 0) {
355             encr.append(pairwise_cipher);
356             encr.append(" + ");
357             encr.append(group_cipher);
358         } else if (pairwise_cipher) {
359             encr.append(pairwise_cipher);
360         } else {
361             encr.append(group_cipher);
362             encr.append(" [group key only]");
363         }
364         textEncryption->setText(encr);
365     } else
366         textEncryption->clear();
367
368     if (!status_updated)
369         textStatus->clear();
370     if (!auth_updated)
371         textAuthentication->clear();
372     if (!ssid_updated)
373         textSsid->clear();
374     if (!bssid_updated)
375         textBssid->clear();
376     if (!ipaddr_updated)
377         textIpAddress->clear();
378 }
379
380
381 void WpaGui::updateNetworks()
382 {
383     char buf[2048], *start, *end, *id, *ssid, *bssid, *flags;
384     size_t len;
385     int first_active = -1;
386     bool selected = false;
387
388     if (!networkMayHaveChanged)
389         return;
390
391     networkSelect->clear();
392
393     if (ctrl_conn == NULL)
394         return;
395     
396     len = sizeof(buf) - 1;
397     if (ctrlRequest("LIST_NETWORKS", buf, &len) < 0)
398         return;
399     
400     buf[len] = '\0';
401     start = strchr(buf, '\n');
402     if (start == NULL)
403         return;
404     start++;
405
406     while (*start) {
407         bool last = false;
408         end = strchr(start, '\n');
409         if (end == NULL) {
410             last = true;
411             end = start;
412             while (end[0] && end[1])
413                 end++;
414         }
415         *end = '\0';
416         
417         id = start;
418         ssid = strchr(id, '\t');
419         if (ssid == NULL)
420             break;
421         *ssid++ = '\0';
422         bssid = strchr(ssid, '\t');
423         if (bssid == NULL)
424             break;
425         *bssid++ = '\0';
426         flags = strchr(bssid, '\t');
427         if (flags == NULL)
428             break;
429         *flags++ = '\0';
430         
431         QString network(id);
432         network.append(": ");
433         network.append(ssid);
434         networkSelect->insertItem(network);
435         
436         if (strstr(flags, "[CURRENT]")) {
437             networkSelect->setCurrentItem(networkSelect->count() - 1);
438             selected = true;
439         } else if (first_active < 0 && strstr(flags, "[DISABLED]") == NULL)
440             first_active = networkSelect->count() - 1;
441         
442         if (last)
443             break;
444         start = end + 1;
445     }
446
447     if (!selected && first_active >= 0)
448         networkSelect->setCurrentItem(first_active);
449
450     networkMayHaveChanged = false;
451 }
452
453
454 void WpaGui::helpIndex()
455 {
456     printf("helpIndex\n");
457 }
458
459
460 void WpaGui::helpContents()
461 {
462     printf("helpContents\n");
463 }
464
465
466 void WpaGui::helpAbout()
467 {
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"
472                        "\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"
476                        "\n"
477                        "Alternatively, this software may be distributed\n"
478                        "under the terms of the BSD license.\n"
479                        "\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");
483 }
484
485
486 void WpaGui::disconnect()
487 {
488     char reply[10];
489     size_t reply_len = sizeof(reply);
490     ctrlRequest("DISCONNECT", reply, &reply_len);
491 }
492
493
494 void WpaGui::scan()
495 {
496     if (scanres) {
497         scanres->close();
498         delete scanres;
499     }
500
501     scanres = new ScanResults();
502     if (scanres == NULL)
503         return;
504     scanres->setWpaGui(this);
505     scanres->show();
506     scanres->exec();
507 }
508
509
510 void WpaGui::eventHistory()
511 {
512     if (eh) {
513         eh->close();
514         delete eh;
515     }
516
517     eh = new EventHistory();
518     if (eh == NULL)
519         return;
520     eh->addEvents(msgs);
521     eh->show();
522     eh->exec();
523 }
524
525
526 void WpaGui::ping()
527 {
528     char buf[10];
529     size_t len;
530     
531 #ifdef CONFIG_CTRL_IFACE_NAMED_PIPE
532     /*
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.
537      */
538     receiveMsgs();
539 #endif /* CONFIG_CTRL_IFACE_NAMED_PIPE */
540
541     if (scanres && !scanres->isVisible()) {
542         delete scanres;
543         scanres = NULL;
544     }
545     
546     if (eh && !eh->isVisible()) {
547         delete eh;
548         eh = NULL;
549     }
550     
551     if (udr && !udr->isVisible()) {
552         delete udr;
553         udr = NULL;
554     }
555     
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;
562         }
563     }
564
565     pingsToStatusUpdate--;
566     if (pingsToStatusUpdate <= 0) {
567         updateStatus();
568         updateNetworks();
569     }
570 }
571
572
573 static int str_match(const char *a, const char *b)
574 {
575     return strncmp(a, b, strlen(b)) == 0;
576 }
577
578
579 void WpaGui::processMsg(char *msg)
580 {
581     char *pos = msg, *pos2;
582     int priority = 2;
583     
584     if (*pos == '<') {
585         /* skip priority */
586         pos++;
587         priority = atoi(pos);
588         pos = strchr(pos, '>');
589         if (pos)
590             pos++;
591         else
592             pos = msg;
593     }
594
595     WpaMsg wm(pos, priority);
596     if (eh)
597         eh->addEvent(wm);
598     msgs.append(wm);
599     while (msgs.count() > 100)
600         msgs.pop_front();
601     
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) ? ':' : ' ');
605         if (pos2)
606             pos2++;
607         else
608             pos2 = pos;
609     } else
610         pos2 = pos;
611     QString lastmsg = pos2;
612     lastmsg.truncate(40);
613     textLastMessage->setText(lastmsg);
614     
615     pingsToStatusUpdate = 0;
616     networkMayHaveChanged = true;
617     
618     if (str_match(pos, WPA_CTRL_REQ))
619         processCtrlReq(pos + strlen(WPA_CTRL_REQ));
620 }
621
622
623 void WpaGui::processCtrlReq(const char *req)
624 {
625     if (udr) {
626         udr->close();
627         delete udr;
628     }
629     udr = new UserDataRequest();
630     if (udr == NULL)
631         return;
632     if (udr->setParams(this, req) < 0) {
633         delete udr;
634         udr = NULL;
635         return;
636     }
637     udr->show();
638     udr->exec();
639 }
640
641
642 void WpaGui::receiveMsgs()
643 {
644     char buf[256];
645     size_t len;
646     
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) {
650             buf[len] = '\0';
651             processMsg(buf);
652         }
653     }
654 }
655
656
657 void WpaGui::connectB()
658 {
659     char reply[10];
660     size_t reply_len = sizeof(reply);
661     ctrlRequest("REASSOCIATE", reply, &reply_len);
662 }
663
664
665 void WpaGui::selectNetwork( const QString &sel )
666 {
667     QString cmd(sel);
668     char reply[10];
669     size_t reply_len = sizeof(reply);
670     
671     int pos = cmd.find(':');
672     if (pos < 0) {
673         printf("Invalid selectNetwork '%s'\n", cmd.ascii());
674         return;
675     }
676     cmd.truncate(pos);
677     cmd.prepend("SELECT_NETWORK ");
678     ctrlRequest(cmd.ascii(), reply, &reply_len);
679 }
680
681
682 void WpaGui::editNetwork()
683 {
684     QString sel(networkSelect->currentText());
685     int pos = sel.find(':');
686     if (pos < 0) {
687         printf("Invalid selectNetwork '%s'\n", sel.ascii());
688         return;
689     }
690     sel.truncate(pos);
691     
692     NetworkConfig *nc = new NetworkConfig();
693     if (nc == NULL)
694         return;
695     nc->setWpaGui(this);
696     
697     nc->paramsFromConfig(sel.toInt());
698     nc->show();
699     nc->exec();
700 }
701
702
703 void WpaGui::triggerUpdate()
704 {
705     updateStatus();
706     networkMayHaveChanged = true;
707     updateNetworks();
708 }
709
710
711 void WpaGui::addNetwork()
712 {
713     NetworkConfig *nc = new NetworkConfig();
714     if (nc == NULL)
715         return;
716     nc->setWpaGui(this);
717     nc->newNetwork();
718     nc->show();
719     nc->exec();
720 }
721
722
723 void WpaGui::selectAdapter( const QString & sel )
724 {
725     if (openCtrlConnection(sel.ascii()) < 0)
726         printf("Failed to open control connection to wpa_supplicant.\n");
727     updateStatus();
728     updateNetworks();
729 }