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() */
30 ctrl_iface_dir = strdup("/var/run/wpa_supplicant");
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");
44 networkMayHaveChanged = true;
49 void WpaGui::destroy()
54 wpa_ctrl_detach(monitor_conn);
55 wpa_ctrl_close(monitor_conn);
59 wpa_ctrl_close(ctrl_conn);
85 ctrl_iface_dir = NULL;
89 void WpaGui::parse_argv()
93 c = getopt(qApp->argc(), qApp->argv(), "i:p:");
99 ctrl_iface = strdup(optarg);
102 free(ctrl_iface_dir);
103 ctrl_iface_dir = strdup(optarg);
110 int WpaGui::openCtrlConnection(const char *ifname)
114 char buf[2048], *pos, *pos2;
118 if (ifname != ctrl_iface) {
120 ctrl_iface = strdup(ifname);
123 #ifdef CONFIG_CTRL_IFACE_UDP
125 ctrl_iface = strdup("udp");
126 #endif /* CONFIG_CTRL_IFACE_UDP */
127 #ifdef CONFIG_CTRL_IFACE_UNIX
129 DIR *dir = opendir(ctrl_iface_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)
142 #endif /* _DIRENT_HAVE_D_TYPE */
144 if (strcmp(dent->d_name, ".") == 0 ||
145 strcmp(dent->d_name, "..") == 0)
147 printf("Selected interface '%s'\n", dent->d_name);
148 ctrl_iface = strdup(dent->d_name);
153 #endif /* CONFIG_CTRL_IFACE_UNIX */
154 #ifdef CONFIG_CTRL_IFACE_NAMED_PIPE
155 struct wpa_ctrl *ctrl;
161 ctrl = wpa_ctrl_open(NULL);
163 len = sizeof(buf) - 1;
164 ret = wpa_ctrl_request(ctrl, "INTERFACES", 10, buf, &len, NULL);
167 pos = strchr(buf, '\n');
170 ctrl_iface = strdup(buf);
172 wpa_ctrl_close(ctrl);
174 #endif /* CONFIG_CTRL_IFACE_NAMED_PIPE */
177 if (ctrl_iface == NULL)
180 #ifdef CONFIG_CTRL_IFACE_UNIX
181 flen = strlen(ctrl_iface_dir) + strlen(ctrl_iface) + 2;
182 cfile = (char *) malloc(flen);
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);
191 snprintf(cfile, flen, "%s", ctrl_iface);
192 #endif /* CONFIG_CTRL_IFACE_UNIX */
195 wpa_ctrl_close(ctrl_conn);
202 wpa_ctrl_detach(monitor_conn);
203 wpa_ctrl_close(monitor_conn);
207 printf("Trying to connect to '%s'\n", cfile);
208 ctrl_conn = wpa_ctrl_open(cfile);
209 if (ctrl_conn == NULL) {
213 monitor_conn = wpa_ctrl_open(cfile);
215 if (monitor_conn == NULL) {
216 wpa_ctrl_close(ctrl_conn);
219 if (wpa_ctrl_attach(monitor_conn)) {
220 printf("Failed to attach to wpa_supplicant\n");
221 wpa_ctrl_close(monitor_conn);
223 wpa_ctrl_close(ctrl_conn);
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()));
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) {
243 pos2 = strchr(pos, '\n');
246 if (strcmp(pos, ctrl_iface) != 0)
247 adapterSelect->insertItem(pos);
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)
270 if (ctrl_conn == NULL)
272 ret = wpa_ctrl_request(ctrl_conn, cmd, strlen(cmd), buf, buflen,
275 printf("'%s' command timed out.\n", cmd);
276 } else if (ret < 0) {
277 printf("'%s' command failed.\n", cmd);
284 void WpaGui::updateStatus()
286 char buf[2048], *start, *end, *pos;
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();
298 textIpAddress->clear();
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;
312 end = strchr(start, '\n');
316 while (end[0] && end[1])
321 pos = strchr(start, '=');
324 if (strcmp(start, "bssid") == 0) {
325 bssid_updated = true;
326 textBssid->setText(pos);
327 } else if (strcmp(start, "ssid") == 0) {
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) {
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) {
352 if (pairwise_cipher || group_cipher) {
354 if (pairwise_cipher && group_cipher &&
355 strcmp(pairwise_cipher, group_cipher) != 0) {
356 encr.append(pairwise_cipher);
358 encr.append(group_cipher);
359 } else if (pairwise_cipher) {
360 encr.append(pairwise_cipher);
361 } else if (group_cipher) {
362 encr.append(group_cipher);
363 encr.append(" [group key only]");
367 textEncryption->setText(encr);
369 textEncryption->clear();
374 textAuthentication->clear();
380 textIpAddress->clear();
384 void WpaGui::updateNetworks()
386 char buf[2048], *start, *end, *id, *ssid, *bssid, *flags;
388 int first_active = -1;
389 bool selected = false;
391 if (!networkMayHaveChanged)
394 networkSelect->clear();
396 if (ctrl_conn == NULL)
399 len = sizeof(buf) - 1;
400 if (ctrlRequest("LIST_NETWORKS", buf, &len) < 0)
404 start = strchr(buf, '\n');
411 end = strchr(start, '\n');
415 while (end[0] && end[1])
421 ssid = strchr(id, '\t');
425 bssid = strchr(ssid, '\t');
429 flags = strchr(bssid, '\t');
435 network.append(": ");
436 network.append(ssid);
437 networkSelect->insertItem(network);
439 if (strstr(flags, "[CURRENT]")) {
440 networkSelect->setCurrentItem(networkSelect->count() - 1);
442 } else if (first_active < 0 && strstr(flags, "[DISABLED]") == NULL)
443 first_active = networkSelect->count() - 1;
450 if (!selected && first_active >= 0)
451 networkSelect->setCurrentItem(first_active);
453 networkMayHaveChanged = false;
457 void WpaGui::helpIndex()
459 printf("helpIndex\n");
463 void WpaGui::helpContents()
465 printf("helpContents\n");
469 void WpaGui::helpAbout()
471 QMessageBox::about(this, "wpa_gui for wpa_supplicant",
472 "Copyright (c) 2003-2008,\n"
473 "Jouni Malinen <j@w1.fi>\n"
474 "and contributors.\n"
476 "This program is free software. You can\n"
477 "distribute it and/or modify it under the terms of\n"
478 "the GNU General Public License version 2.\n"
480 "Alternatively, this software may be distributed\n"
481 "under the terms of the BSD license.\n"
483 "This product includes software developed\n"
484 "by the OpenSSL Project for use in the\n"
485 "OpenSSL Toolkit (http://www.openssl.org/)\n");
489 void WpaGui::disconnect()
492 size_t reply_len = sizeof(reply);
493 ctrlRequest("DISCONNECT", reply, &reply_len);
504 scanres = new ScanResults();
507 scanres->setWpaGui(this);
513 void WpaGui::eventHistory()
520 eh = new EventHistory();
534 #ifdef CONFIG_CTRL_IFACE_NAMED_PIPE
536 * QSocketNotifier cannot be used with Windows named pipes, so use a timer
537 * to check for received messages for now. This could be optimized be doing
538 * something specific to named pipes or Windows events, but it is not clear
539 * what would be the best way of doing that in Qt.
542 #endif /* CONFIG_CTRL_IFACE_NAMED_PIPE */
544 if (scanres && !scanres->isVisible()) {
549 if (eh && !eh->isVisible()) {
554 if (udr && !udr->isVisible()) {
559 len = sizeof(buf) - 1;
560 if (ctrlRequest("PING", buf, &len) < 0) {
561 printf("PING failed - trying to reconnect\n");
562 if (openCtrlConnection(ctrl_iface) >= 0) {
563 printf("Reconnected successfully\n");
564 pingsToStatusUpdate = 0;
568 pingsToStatusUpdate--;
569 if (pingsToStatusUpdate <= 0) {
576 static int str_match(const char *a, const char *b)
578 return strncmp(a, b, strlen(b)) == 0;
582 void WpaGui::processMsg(char *msg)
584 char *pos = msg, *pos2;
590 priority = atoi(pos);
591 pos = strchr(pos, '>');
598 WpaMsg wm(pos, priority);
602 while (msgs.count() > 100)
605 /* Update last message with truncated version of the event */
606 if (strncmp(pos, "CTRL-", 5) == 0) {
607 pos2 = strchr(pos, str_match(pos, WPA_CTRL_REQ) ? ':' : ' ');
614 QString lastmsg = pos2;
615 lastmsg.truncate(40);
616 textLastMessage->setText(lastmsg);
618 pingsToStatusUpdate = 0;
619 networkMayHaveChanged = true;
621 if (str_match(pos, WPA_CTRL_REQ))
622 processCtrlReq(pos + strlen(WPA_CTRL_REQ));
626 void WpaGui::processCtrlReq(const char *req)
632 udr = new UserDataRequest();
635 if (udr->setParams(this, req) < 0) {
645 void WpaGui::receiveMsgs()
650 while (monitor_conn && wpa_ctrl_pending(monitor_conn) > 0) {
651 len = sizeof(buf) - 1;
652 if (wpa_ctrl_recv(monitor_conn, buf, &len) == 0) {
660 void WpaGui::connectB()
663 size_t reply_len = sizeof(reply);
664 ctrlRequest("REASSOCIATE", reply, &reply_len);
668 void WpaGui::selectNetwork( const QString &sel )
672 size_t reply_len = sizeof(reply);
674 int pos = cmd.find(':');
676 printf("Invalid selectNetwork '%s'\n", cmd.ascii());
680 cmd.prepend("SELECT_NETWORK ");
681 ctrlRequest(cmd.ascii(), reply, &reply_len);
685 void WpaGui::editNetwork()
687 QString sel(networkSelect->currentText());
688 int pos = sel.find(':');
690 printf("Invalid selectNetwork '%s'\n", sel.ascii());
695 NetworkConfig *nc = new NetworkConfig();
700 nc->paramsFromConfig(sel.toInt());
706 void WpaGui::triggerUpdate()
709 networkMayHaveChanged = true;
714 void WpaGui::addNetwork()
716 NetworkConfig *nc = new NetworkConfig();
726 void WpaGui::selectAdapter( const QString & sel )
728 if (openCtrlConnection(sel.ascii()) < 0)
729 printf("Failed to open control connection to wpa_supplicant.\n");