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);
360 } else if (group_cipher) {
361 encr.append(group_cipher);
362 encr.append(" [group key only]");
366 textEncryption->setText(encr);
368 textEncryption->clear();
373 textAuthentication->clear();
379 textIpAddress->clear();
383 void WpaGui::updateNetworks()
385 char buf[2048], *start, *end, *id, *ssid, *bssid, *flags;
387 int first_active = -1;
388 bool selected = false;
390 if (!networkMayHaveChanged)
393 networkSelect->clear();
395 if (ctrl_conn == NULL)
398 len = sizeof(buf) - 1;
399 if (ctrlRequest("LIST_NETWORKS", buf, &len) < 0)
403 start = strchr(buf, '\n');
410 end = strchr(start, '\n');
414 while (end[0] && end[1])
420 ssid = strchr(id, '\t');
424 bssid = strchr(ssid, '\t');
428 flags = strchr(bssid, '\t');
434 network.append(": ");
435 network.append(ssid);
436 networkSelect->insertItem(network);
438 if (strstr(flags, "[CURRENT]")) {
439 networkSelect->setCurrentItem(networkSelect->count() - 1);
441 } else if (first_active < 0 && strstr(flags, "[DISABLED]") == NULL)
442 first_active = networkSelect->count() - 1;
449 if (!selected && first_active >= 0)
450 networkSelect->setCurrentItem(first_active);
452 networkMayHaveChanged = false;
456 void WpaGui::helpIndex()
458 printf("helpIndex\n");
462 void WpaGui::helpContents()
464 printf("helpContents\n");
468 void WpaGui::helpAbout()
470 QMessageBox::about(this, "wpa_gui for wpa_supplicant",
471 "Copyright (c) 2003-2008,\n"
472 "Jouni Malinen <j@w1.fi>\n"
473 "and contributors.\n"
475 "This program is free software. You can\n"
476 "distribute it and/or modify it under the terms of\n"
477 "the GNU General Public License version 2.\n"
479 "Alternatively, this software may be distributed\n"
480 "under the terms of the BSD license.\n"
482 "This product includes software developed\n"
483 "by the OpenSSL Project for use in the\n"
484 "OpenSSL Toolkit (http://www.openssl.org/)\n");
488 void WpaGui::disconnect()
491 size_t reply_len = sizeof(reply);
492 ctrlRequest("DISCONNECT", reply, &reply_len);
503 scanres = new ScanResults();
506 scanres->setWpaGui(this);
512 void WpaGui::eventHistory()
519 eh = new EventHistory();
533 #ifdef CONFIG_CTRL_IFACE_NAMED_PIPE
535 * QSocketNotifier cannot be used with Windows named pipes, so use a timer
536 * to check for received messages for now. This could be optimized be doing
537 * something specific to named pipes or Windows events, but it is not clear
538 * what would be the best way of doing that in Qt.
541 #endif /* CONFIG_CTRL_IFACE_NAMED_PIPE */
543 if (scanres && !scanres->isVisible()) {
548 if (eh && !eh->isVisible()) {
553 if (udr && !udr->isVisible()) {
558 len = sizeof(buf) - 1;
559 if (ctrlRequest("PING", buf, &len) < 0) {
560 printf("PING failed - trying to reconnect\n");
561 if (openCtrlConnection(ctrl_iface) >= 0) {
562 printf("Reconnected successfully\n");
563 pingsToStatusUpdate = 0;
567 pingsToStatusUpdate--;
568 if (pingsToStatusUpdate <= 0) {
575 static int str_match(const char *a, const char *b)
577 return strncmp(a, b, strlen(b)) == 0;
581 void WpaGui::processMsg(char *msg)
583 char *pos = msg, *pos2;
589 priority = atoi(pos);
590 pos = strchr(pos, '>');
597 WpaMsg wm(pos, priority);
601 while (msgs.count() > 100)
604 /* Update last message with truncated version of the event */
605 if (strncmp(pos, "CTRL-", 5) == 0) {
606 pos2 = strchr(pos, str_match(pos, WPA_CTRL_REQ) ? ':' : ' ');
613 QString lastmsg = pos2;
614 lastmsg.truncate(40);
615 textLastMessage->setText(lastmsg);
617 pingsToStatusUpdate = 0;
618 networkMayHaveChanged = true;
620 if (str_match(pos, WPA_CTRL_REQ))
621 processCtrlReq(pos + strlen(WPA_CTRL_REQ));
625 void WpaGui::processCtrlReq(const char *req)
631 udr = new UserDataRequest();
634 if (udr->setParams(this, req) < 0) {
644 void WpaGui::receiveMsgs()
649 while (monitor_conn && wpa_ctrl_pending(monitor_conn) > 0) {
650 len = sizeof(buf) - 1;
651 if (wpa_ctrl_recv(monitor_conn, buf, &len) == 0) {
659 void WpaGui::connectB()
662 size_t reply_len = sizeof(reply);
663 ctrlRequest("REASSOCIATE", reply, &reply_len);
667 void WpaGui::selectNetwork( const QString &sel )
671 size_t reply_len = sizeof(reply);
673 int pos = cmd.find(':');
675 printf("Invalid selectNetwork '%s'\n", cmd.ascii());
679 cmd.prepend("SELECT_NETWORK ");
680 ctrlRequest(cmd.ascii(), reply, &reply_len);
684 void WpaGui::editNetwork()
686 QString sel(networkSelect->currentText());
687 int pos = sel.find(':');
689 printf("Invalid selectNetwork '%s'\n", sel.ascii());
694 NetworkConfig *nc = new NetworkConfig();
699 nc->paramsFromConfig(sel.toInt());
705 void WpaGui::triggerUpdate()
708 networkMayHaveChanged = true;
713 void WpaGui::addNetwork()
715 NetworkConfig *nc = new NetworkConfig();
725 void WpaGui::selectAdapter( const QString & sel )
727 if (openCtrlConnection(sel.ascii()) < 0)
728 printf("Failed to open control connection to wpa_supplicant.\n");