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
);
362 encr
.append(group_cipher
);
363 encr
.append(" [group key only]");
365 textEncryption
->setText(encr
);
367 textEncryption
->clear();
372 textAuthentication
->clear();
378 textIpAddress
->clear();
382 void WpaGui::updateNetworks()
384 char buf
[2048], *start
, *end
, *id
, *ssid
, *bssid
, *flags
;
386 int first_active
= -1;
387 bool selected
= false;
389 if (!networkMayHaveChanged
)
392 networkSelect
->clear();
394 if (ctrl_conn
== NULL
)
397 len
= sizeof(buf
) - 1;
398 if (ctrlRequest("LIST_NETWORKS", buf
, &len
) < 0)
402 start
= strchr(buf
, '\n');
409 end
= strchr(start
, '\n');
413 while (end
[0] && end
[1])
419 ssid
= strchr(id
, '\t');
423 bssid
= strchr(ssid
, '\t');
427 flags
= strchr(bssid
, '\t');
433 network
.append(": ");
434 network
.append(ssid
);
435 networkSelect
->insertItem(network
);
437 if (strstr(flags
, "[CURRENT]")) {
438 networkSelect
->setCurrentItem(networkSelect
->count() - 1);
440 } else if (first_active
< 0 && strstr(flags
, "[DISABLED]") == NULL
)
441 first_active
= networkSelect
->count() - 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"
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"
478 "Alternatively, this software may be distributed\n"
479 "under the terms of the BSD license.\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()
490 size_t reply_len
= sizeof(reply
);
491 ctrlRequest("DISCONNECT", reply
, &reply_len
);
502 scanres
= new ScanResults();
505 scanres
->setWpaGui(this);
511 void WpaGui::eventHistory()
518 eh
= new EventHistory();
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.
540 #endif /* CONFIG_CTRL_IFACE_NAMED_PIPE */
542 if (scanres
&& !scanres
->isVisible()) {
547 if (eh
&& !eh
->isVisible()) {
552 if (udr
&& !udr
->isVisible()) {
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) {
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
;
588 priority
= atoi(pos
);
589 pos
= strchr(pos
, '>');
596 WpaMsg
wm(pos
, priority
);
600 while (msgs
.count() > 100)
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
) ? ':' : ' ');
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
)
630 udr
= new UserDataRequest();
633 if (udr
->setParams(this, req
) < 0) {
643 void WpaGui::receiveMsgs()
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) {
658 void WpaGui::connectB()
661 size_t reply_len
= sizeof(reply
);
662 ctrlRequest("REASSOCIATE", reply
, &reply_len
);
666 void WpaGui::selectNetwork( const QString
&sel
)
670 size_t reply_len
= sizeof(reply
);
672 int pos
= cmd
.find(':');
674 printf("Invalid selectNetwork '%s'\n", cmd
.ascii());
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(':');
688 printf("Invalid selectNetwork '%s'\n", sel
.ascii());
693 NetworkConfig
*nc
= new NetworkConfig();
698 nc
->paramsFromConfig(sel
.toInt());
704 void WpaGui::triggerUpdate()
707 networkMayHaveChanged
= true;
712 void WpaGui::addNetwork()
714 NetworkConfig
*nc
= new NetworkConfig();
724 void WpaGui::selectAdapter( const QString
& sel
)
726 if (openCtrlConnection(sel
.ascii()) < 0)
727 printf("Failed to open control connection to wpa_supplicant.\n");