2 * WPA Supplicant / dbus-based control interface
3 * Copyright (c) 2006, Dan Williams <dcbw@redhat.com> and Red Hat, Inc.
4 * Copyright (c) 2009, Witold Sowa <witold.sowa@gmail.com>
5 * Copyright (c) 2009, Jouni Malinen <j@w1.fi>
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
11 * Alternatively, this software may be distributed under the terms of BSD
14 * See README and COPYING for more details.
21 #include "../config.h"
22 #include "../wpa_supplicant_i.h"
24 #include "dbus_new_helpers.h"
25 #include "dbus_dict_helpers.h"
27 #include "dbus_new_handlers.h"
28 #include "dbus_common.h"
29 #include "dbus_common_i.h"
33 * wpas_dbus_signal_interface - Send a interface related event signal
34 * @wpa_s: %wpa_supplicant network interface data
35 * @sig_name: signal name - InterfaceAdded or InterfaceRemoved
36 * @properties: determines if add second argument with object properties
38 * Notify listeners about event related with interface
40 static void wpas_dbus_signal_interface(struct wpa_supplicant
*wpa_s
,
41 const char *sig_name
, int properties
)
43 struct wpas_dbus_priv
*iface
;
45 DBusMessageIter iter
, iter_dict
;
48 iface
= wpa_s
->global
->dbus
;
50 /* Do nothing if the control interface is not turned on */
54 path
= wpas_dbus_get_path(wpa_s
);
56 wpa_printf(MSG_ERROR
, "wpas_dbus_signal_interface[dbus]: "
57 "Interface doesn't have a dbus path. "
58 "Can't send signal.");
61 _signal
= dbus_message_new_signal(WPAS_DBUS_NEW_PATH
,
62 WPAS_DBUS_NEW_INTERFACE
, sig_name
);
63 if (_signal
== NULL
) {
64 wpa_printf(MSG_ERROR
, "wpas_dbus_signal_interface[dbus]: "
65 "enough memory to send scan results signal.");
69 dbus_message_iter_init_append(_signal
, &iter
);
71 if(!dbus_message_iter_append_basic(&iter
, DBUS_TYPE_OBJECT_PATH
,
76 if (!wpa_dbus_dict_open_write(&iter
, &iter_dict
))
79 wpa_dbus_get_object_properties(iface
, path
,
80 WPAS_DBUS_NEW_IFACE_INTERFACE
,
83 if (!wpa_dbus_dict_close_write(&iter
, &iter_dict
))
87 dbus_connection_send(iface
->con
, _signal
, NULL
);
89 dbus_message_unref(_signal
);
93 wpa_printf(MSG_ERROR
, "wpas_dbus_signal_interface[dbus]: "
94 "not enough memory to construct signal.");
95 dbus_message_unref(_signal
);
100 * wpas_dbus_signal_interface_added - Send a interface created signal
101 * @wpa_s: %wpa_supplicant network interface data
103 * Notify listeners about creating new interface
105 static void wpas_dbus_signal_interface_added(struct wpa_supplicant
*wpa_s
)
107 wpas_dbus_signal_interface(wpa_s
, "InterfaceAdded", TRUE
);
112 * wpas_dbus_signal_interface_removed - Send a interface removed signal
113 * @wpa_s: %wpa_supplicant network interface data
115 * Notify listeners about removing interface
117 static void wpas_dbus_signal_interface_removed(struct wpa_supplicant
*wpa_s
)
119 wpas_dbus_signal_interface(wpa_s
, "InterfaceRemoved", FALSE
);
125 * wpas_dbus_signal_scan_done - send scan done signal
126 * @wpa_s: %wpa_supplicant network interface data
127 * @success: indicates if scanning succeed or failed
129 * Notify listeners about finishing a scan
131 void wpas_dbus_signal_scan_done(struct wpa_supplicant
*wpa_s
, int success
)
133 struct wpas_dbus_priv
*iface
;
134 DBusMessage
*_signal
;
138 iface
= wpa_s
->global
->dbus
;
140 /* Do nothing if the control interface is not turned on */
144 path
= wpas_dbus_get_path(wpa_s
);
146 wpa_printf(MSG_ERROR
, "wpas_dbus_signal_scan_done[dbus]: "
147 "Interface doesn't have a dbus path. "
148 "Can't send signal.");
151 _signal
= dbus_message_new_signal(path
, WPAS_DBUS_NEW_IFACE_INTERFACE
,
153 if (_signal
== NULL
) {
154 wpa_printf(MSG_ERROR
, "wpas_dbus_signal_scan_done[dbus]: "
155 "enough memory to send signal.");
159 succ
= success
? TRUE
: FALSE
;
160 if (dbus_message_append_args(_signal
, DBUS_TYPE_BOOLEAN
, &succ
,
161 DBUS_TYPE_INVALID
)) {
162 dbus_connection_send(iface
->con
, _signal
, NULL
);
164 wpa_printf(MSG_ERROR
, "wpas_dbus_signal_scan_done[dbus]: "
165 "not enough memory to construct signal.");
167 dbus_message_unref(_signal
);
172 * wpas_dbus_signal_blob - Send a BSS related event signal
173 * @wpa_s: %wpa_supplicant network interface data
174 * @bss_obj_path: BSS object path
175 * @sig_name: signal name - BSSAdded or BSSRemoved
176 * @properties: determines if add second argument with object properties
178 * Notify listeners about event related with BSS
180 static void wpas_dbus_signal_bss(struct wpa_supplicant
*wpa_s
,
181 const char *bss_obj_path
,
182 const char *sig_name
, int properties
)
184 struct wpas_dbus_priv
*iface
;
185 DBusMessage
*_signal
;
186 DBusMessageIter iter
, iter_dict
;
189 iface
= wpa_s
->global
->dbus
;
191 /* Do nothing if the control interface is not turned on */
195 path
= wpas_dbus_get_path(wpa_s
);
197 wpa_printf(MSG_ERROR
, "wpas_dbus_signal_bss[dbus]: "
198 "Interface doesn't have a dbus path. "
199 "Can't send signal.");
202 _signal
= dbus_message_new_signal(path
, WPAS_DBUS_NEW_IFACE_INTERFACE
,
204 if (_signal
== NULL
) {
205 wpa_printf(MSG_ERROR
, "wpas_dbus_signal_bss[dbus]: "
206 "enough memory to send signal.");
210 dbus_message_iter_init_append(_signal
, &iter
);
212 if (!dbus_message_iter_append_basic(&iter
, DBUS_TYPE_OBJECT_PATH
,
217 if (!wpa_dbus_dict_open_write(&iter
, &iter_dict
))
220 wpa_dbus_get_object_properties(iface
, bss_obj_path
,
221 WPAS_DBUS_NEW_IFACE_BSSID
,
224 if (!wpa_dbus_dict_close_write(&iter
, &iter_dict
))
228 dbus_connection_send(iface
->con
, _signal
, NULL
);
230 dbus_message_unref(_signal
);
234 wpa_printf(MSG_ERROR
, "wpas_dbus_signal_bss[dbus]: "
235 "not enough memory to construct signal.");
236 dbus_message_unref(_signal
);
241 * wpas_dbus_signal_bss_added - Send a BSS added signal
242 * @wpa_s: %wpa_supplicant network interface data
243 * @bss_obj_path: new BSS object path
245 * Notify listeners about adding new BSS
247 static void wpas_dbus_signal_bss_added(struct wpa_supplicant
*wpa_s
,
248 const char *bss_obj_path
)
250 wpas_dbus_signal_bss(wpa_s
, bss_obj_path
, "BSSAdded", TRUE
);
255 * wpas_dbus_signal_bss_removed - Send a BSS removed signal
256 * @wpa_s: %wpa_supplicant network interface data
257 * @bss_obj_path: BSS object path
259 * Notify listeners about removing BSS
261 static void wpas_dbus_signal_bss_removed(struct wpa_supplicant
*wpa_s
,
262 const char *bss_obj_path
)
264 wpas_dbus_signal_bss(wpa_s
, bss_obj_path
, "BSSRemoved", FALSE
);
269 * wpas_dbus_signal_blob - Send a blob related event signal
270 * @wpa_s: %wpa_supplicant network interface data
272 * @sig_name: signal name - BlobAdded or BlobRemoved
274 * Notify listeners about event related with blob
276 static void wpas_dbus_signal_blob(struct wpa_supplicant
*wpa_s
,
277 const char *name
, const char *sig_name
)
279 struct wpas_dbus_priv
*iface
;
280 DBusMessage
*_signal
;
283 iface
= wpa_s
->global
->dbus
;
285 /* Do nothing if the control interface is not turned on */
289 path
= wpas_dbus_get_path(wpa_s
);
291 wpa_printf(MSG_ERROR
, "wpas_dbus_signal_blob[dbus]: "
292 "Interface doesn't have a dbus path. "
293 "Can't send signal.");
296 _signal
= dbus_message_new_signal(path
, WPAS_DBUS_NEW_IFACE_INTERFACE
,
298 if (_signal
== NULL
) {
299 wpa_printf(MSG_ERROR
, "wpas_dbus_signal_blob[dbus]: "
300 "enough memory to send signal.");
304 if (dbus_message_append_args(_signal
, DBUS_TYPE_STRING
, &name
,
305 DBUS_TYPE_INVALID
)) {
306 dbus_connection_send(iface
->con
, _signal
, NULL
);
308 wpa_printf(MSG_ERROR
, "wpas_dbus_signal_blob[dbus]: "
309 "not enough memory to construct signal.");
311 dbus_message_unref(_signal
);
316 * wpas_dbus_signal_blob_added - Send a blob added signal
317 * @wpa_s: %wpa_supplicant network interface data
320 * Notify listeners about adding a new blob
322 void wpas_dbus_signal_blob_added(struct wpa_supplicant
*wpa_s
,
325 wpas_dbus_signal_blob(wpa_s
, name
, "BlobAdded");
330 * wpas_dbus_signal_blob_removed - Send a blob removed signal
331 * @wpa_s: %wpa_supplicant network interface data
334 * Notify listeners about removing blob
336 void wpas_dbus_signal_blob_removed(struct wpa_supplicant
*wpa_s
,
339 wpas_dbus_signal_blob(wpa_s
, name
, "BlobRemoved");
344 * wpas_dbus_signal_network - Send a network related event signal
345 * @wpa_s: %wpa_supplicant network interface data
346 * @id: new network id
347 * @sig_name: signal name - NetworkAdded, NetworkRemoved or NetworkSelected
348 * @properties: determines if add second argument with object properties
350 * Notify listeners about event related with configured network
352 static void wpas_dbus_signal_network(struct wpa_supplicant
*wpa_s
,
353 int id
, const char *sig_name
,
356 struct wpas_dbus_priv
*iface
;
357 DBusMessage
*_signal
;
358 DBusMessageIter iter
, iter_dict
;
362 iface
= wpa_s
->global
->dbus
;
364 /* Do nothing if the control interface is not turned on */
368 path
= wpas_dbus_get_path(wpa_s
);
370 wpa_printf(MSG_ERROR
, "wpas_dbus_signal_network[dbus]: "
371 "Interface doesn't have a dbus path. "
372 "Can't send signal.");
376 net_obj_path
= os_zalloc(WPAS_DBUS_OBJECT_PATH_MAX
);
377 if (net_obj_path
== NULL
)
379 os_snprintf(net_obj_path
, WPAS_DBUS_OBJECT_PATH_MAX
,
380 "%s/" WPAS_DBUS_NEW_NETWORKS_PART
"/%u", path
, id
);
382 _signal
= dbus_message_new_signal(path
, WPAS_DBUS_NEW_IFACE_INTERFACE
,
384 if (_signal
== NULL
) {
385 wpa_printf(MSG_ERROR
, "wpas_dbus_signal_network[dbus]: "
386 "enough memory to send signal.");
387 os_free(net_obj_path
);
391 dbus_message_iter_init_append(_signal
, &iter
);
393 if (!dbus_message_iter_append_basic(&iter
, DBUS_TYPE_OBJECT_PATH
,
398 if (!wpa_dbus_dict_open_write(&iter
, &iter_dict
))
401 wpa_dbus_get_object_properties(iface
, net_obj_path
,
402 WPAS_DBUS_NEW_IFACE_NETWORK
,
405 if (!wpa_dbus_dict_close_write(&iter
, &iter_dict
))
409 dbus_connection_send(iface
->con
, _signal
, NULL
);
411 os_free(net_obj_path
);
412 dbus_message_unref(_signal
);
416 wpa_printf(MSG_ERROR
, "wpas_dbus_signal_network[dbus]: "
417 "not enough memory to construct signal.");
418 os_free(net_obj_path
);
419 dbus_message_unref(_signal
);
424 * wpas_dbus_signal_network_added - Send a network added signal
425 * @wpa_s: %wpa_supplicant network interface data
426 * @id: new network id
428 * Notify listeners about adding new network
430 static void wpas_dbus_signal_network_added(struct wpa_supplicant
*wpa_s
,
433 wpas_dbus_signal_network(wpa_s
, id
, "NetworkAdded", TRUE
);
438 * wpas_dbus_signal_network_removed - Send a network removed signal
439 * @wpa_s: %wpa_supplicant network interface data
442 * Notify listeners about removing a network
444 static void wpas_dbus_signal_network_removed(struct wpa_supplicant
*wpa_s
,
447 wpas_dbus_signal_network(wpa_s
, id
, "NetworkRemoved", FALSE
);
452 * wpas_dbus_signal_network_selected - Send a network selected signal
453 * @wpa_s: %wpa_supplicant network interface data
456 * Notify listeners about selecting a network
458 void wpas_dbus_signal_network_selected(struct wpa_supplicant
*wpa_s
, int id
)
460 wpas_dbus_signal_network(wpa_s
, id
, "NetworkSelected", FALSE
);
465 * wpas_dbus_signal_state_changed - Send a state changed signal
466 * @wpa_s: %wpa_supplicant network interface data
467 * @new_state: new state wpa_supplicant is entering
468 * @old_state: old state wpa_supplicant is leaving
470 * Notify listeners that wpa_supplicant has changed state
472 void wpas_dbus_signal_state_changed(struct wpa_supplicant
*wpa_s
,
473 enum wpa_states new_state
,
474 enum wpa_states old_state
)
476 struct wpas_dbus_priv
*iface
;
477 DBusMessage
*_signal
= NULL
;
479 char *new_state_str
, *old_state_str
;
482 /* Do nothing if the control interface is not turned on */
483 if (wpa_s
->global
== NULL
)
485 iface
= wpa_s
->global
->dbus
;
489 /* Only send signal if state really changed */
490 if (new_state
== old_state
)
493 path
= wpas_dbus_get_path(wpa_s
);
495 perror("wpas_dbus_signal_state_changed[dbus]: "
496 "interface didn't have a dbus path");
497 wpa_printf(MSG_ERROR
,
498 "wpas_dbus_signal_state_changed[dbus]: "
499 "interface didn't have a dbus path; can't send "
503 _signal
= dbus_message_new_signal(path
, WPAS_DBUS_NEW_IFACE_INTERFACE
,
505 if (_signal
== NULL
) {
506 perror("wpas_dbus_signal_state_changed[dbus]: "
507 "couldn't create dbus signal; likely out of memory");
508 wpa_printf(MSG_ERROR
,
509 "wpas_dbus_signal_state_changed[dbus]: "
510 "couldn't create dbus signal; likely out of "
515 new_state_str
= os_strdup(wpa_supplicant_state_txt(new_state
));
516 old_state_str
= os_strdup(wpa_supplicant_state_txt(old_state
));
517 if (new_state_str
== NULL
|| old_state_str
== NULL
) {
518 perror("wpas_dbus_signal_state_changed[dbus]: "
519 "couldn't convert state strings");
520 wpa_printf(MSG_ERROR
,
521 "wpas_dbus_signal_state_changed[dbus]: "
522 "couldn't convert state strings.");
526 /* make state string lowercase to fit new DBus API convention */
529 *tmp
= tolower(*tmp
);
534 *tmp
= tolower(*tmp
);
538 if (!dbus_message_append_args(_signal
,
539 DBUS_TYPE_STRING
, &new_state_str
,
540 DBUS_TYPE_STRING
, &old_state_str
,
541 DBUS_TYPE_INVALID
)) {
542 perror("wpas_dbus_signal_state_changed[dbus]: "
543 "not enough memory to construct state change signal.");
544 wpa_printf(MSG_ERROR
,
545 "wpas_dbus_signal_state_changed[dbus]: "
546 "not enough memory to construct state change "
551 dbus_connection_send(iface
->con
, _signal
, NULL
);
554 dbus_message_unref(_signal
);
555 os_free(new_state_str
);
556 os_free(old_state_str
);
561 * wpas_dbus_signal_network_enabled_changed - Signals Enabled property changes
562 * @wpa_s: %wpa_supplicant network interface data
563 * @ssid: configured network which Enabled property has changed
565 * Sends PropertyChanged signals containing new value of Enabled property
566 * for specified network
568 void wpas_dbus_signal_network_enabled_changed(struct wpa_supplicant
*wpa_s
,
569 struct wpa_ssid
*ssid
)
572 struct network_handler_args args
= {wpa_s
, ssid
};
574 char path
[WPAS_DBUS_OBJECT_PATH_MAX
];
575 os_snprintf(path
, WPAS_DBUS_OBJECT_PATH_MAX
,
576 "%s/" WPAS_DBUS_NEW_NETWORKS_PART
"/%d",
577 wpas_dbus_get_path(wpa_s
), ssid
->id
);
579 wpa_dbus_signal_property_changed(wpa_s
->global
->dbus
,
580 (WPADBusPropertyAccessor
)
581 wpas_dbus_getter_enabled
, &args
,
582 path
, WPAS_DBUS_NEW_IFACE_NETWORK
,
590 * wpas_dbus_signal_wps_event_success - Signals Success WPS event
591 * @wpa_s: %wpa_supplicant network interface data
593 * Sends Event dbus signal with name "success" and empty dict as arguments
595 void wpas_dbus_signal_wps_event_success(struct wpa_supplicant
*wpa_s
)
598 DBusMessage
*_signal
= NULL
;
599 DBusMessageIter iter
, dict_iter
;
600 struct wpas_dbus_priv
*iface
;
601 char *key
= "success";
604 iface
= wpa_s
->global
->dbus
;
606 /* Do nothing if the control interface is not turned on */
610 path
= wpas_dbus_get_path(wpa_s
);
612 wpa_printf(MSG_ERROR
, "wpas_dbus_signal_wps_event_success"
613 "[dbus]: interface has no dbus path set");
617 _signal
= dbus_message_new_signal(path
, WPAS_DBUS_NEW_IFACE_WPS
,
620 wpa_printf(MSG_ERROR
, "wpas_dbus_signal_wps_event_success"
621 "[dbus]: out of memory when creating a signal");
625 dbus_message_iter_init_append(_signal
, &iter
);
627 if (!dbus_message_iter_append_basic(&iter
, DBUS_TYPE_STRING
, &key
) ||
628 !wpa_dbus_dict_open_write(&iter
, &dict_iter
) ||
629 !wpa_dbus_dict_close_write(&iter
, &dict_iter
)) {
630 wpa_printf(MSG_ERROR
, "wpas_dbus_signal_wps_event_success"
631 "[dbus]: out of memory");
635 dbus_connection_send(iface
->con
, _signal
, NULL
);
637 dbus_message_unref(_signal
);
642 * wpas_dbus_signal_wps_event_fail - Signals Fail WPS event
643 * @wpa_s: %wpa_supplicant network interface data
645 * Sends Event dbus signal with name "fail" and dictionary containing
646 * "msg field with fail message number (int32) as arguments
648 void wpas_dbus_signal_wps_event_fail(struct wpa_supplicant
*wpa_s
,
649 struct wps_event_fail
*fail
)
652 DBusMessage
*_signal
= NULL
;
653 DBusMessageIter iter
, dict_iter
;
654 struct wpas_dbus_priv
*iface
;
658 iface
= wpa_s
->global
->dbus
;
660 /* Do nothing if the control interface is not turned on */
664 path
= wpas_dbus_get_path(wpa_s
);
666 wpa_printf(MSG_ERROR
, "wpas_dbus_signal_wps_event_fail[dbus]: "
667 "interface has no dbus path set");
671 _signal
= dbus_message_new_signal(path
, WPAS_DBUS_NEW_IFACE_WPS
,
674 wpa_printf(MSG_ERROR
, "wpas_dbus_signal_wps_event_fail[dbus]: "
675 "out of memory when creating a signal");
679 dbus_message_iter_init_append(_signal
, &iter
);
681 if (!dbus_message_iter_append_basic(&iter
, DBUS_TYPE_STRING
, &key
) ||
682 !wpa_dbus_dict_open_write(&iter
, &dict_iter
) ||
683 !wpa_dbus_dict_append_int32(&dict_iter
, "msg", fail
->msg
) ||
684 !wpa_dbus_dict_close_write(&iter
, &dict_iter
)) {
685 wpa_printf(MSG_ERROR
, "wpas_dbus_signal_wps_event_fail[dbus]: "
690 dbus_connection_send(iface
->con
, _signal
, NULL
);
692 dbus_message_unref(_signal
);
697 * wpas_dbus_signal_wps_event_m2d - Signals M2D WPS event
698 * @wpa_s: %wpa_supplicant network interface data
700 * Sends Event dbus signal with name "m2d" and dictionary containing
701 * fields of wps_event_m2d structure.
703 void wpas_dbus_signal_wps_event_m2d(struct wpa_supplicant
*wpa_s
,
704 struct wps_event_m2d
*m2d
)
707 DBusMessage
*_signal
= NULL
;
708 DBusMessageIter iter
, dict_iter
;
709 struct wpas_dbus_priv
*iface
;
713 iface
= wpa_s
->global
->dbus
;
715 /* Do nothing if the control interface is not turned on */
719 path
= wpas_dbus_get_path(wpa_s
);
721 wpa_printf(MSG_ERROR
, "wpas_dbus_signal_wps_event_m2d[dbus]: "
722 "interface has no dbus path set");
726 _signal
= dbus_message_new_signal(path
, WPAS_DBUS_NEW_IFACE_WPS
,
729 wpa_printf(MSG_ERROR
, "wpas_dbus_signal_wps_event_m2d[dbus]: "
730 "out of memory when creating a signal");
734 dbus_message_iter_init_append(_signal
, &iter
);
736 if (!(dbus_message_iter_append_basic(&iter
, DBUS_TYPE_STRING
, &key
) &&
737 wpa_dbus_dict_open_write(&iter
, &dict_iter
) &&
738 wpa_dbus_dict_append_uint16(&dict_iter
, "config_methods",
739 m2d
->config_methods
) &&
740 wpa_dbus_dict_append_byte_array(&dict_iter
, "manufacturer",
741 (const char *) m2d
->manufacturer
,
742 m2d
->manufacturer_len
) &&
743 wpa_dbus_dict_append_byte_array(&dict_iter
, "model_name",
744 (const char *) m2d
->model_name
,
745 m2d
->model_name_len
) &&
746 wpa_dbus_dict_append_byte_array(&dict_iter
, "model_number",
747 (const char *) m2d
->model_number
,
748 m2d
->model_number_len
) &&
749 wpa_dbus_dict_append_byte_array(&dict_iter
, "serial_number",
752 m2d
->serial_number_len
) &&
753 wpa_dbus_dict_append_byte_array(&dict_iter
, "dev_name",
754 (const char *) m2d
->dev_name
,
755 m2d
->dev_name_len
) &&
756 wpa_dbus_dict_append_byte_array(&dict_iter
, "primary_dev_type",
758 m2d
->primary_dev_type
, 8) &&
759 wpa_dbus_dict_append_uint16(&dict_iter
, "config_error",
760 m2d
->config_error
) &&
761 wpa_dbus_dict_append_uint16(&dict_iter
, "dev_password_id",
762 m2d
->dev_password_id
) &&
763 wpa_dbus_dict_close_write(&iter
, &dict_iter
))) {
764 wpa_printf(MSG_ERROR
, "wpas_dbus_signal_wps_event_m2d[dbus]: "
769 dbus_connection_send(iface
->con
, _signal
, NULL
);
771 dbus_message_unref(_signal
);
776 * wpas_dbus_signal_wps_cred - Signals new credentials
777 * @wpa_s: %wpa_supplicant network interface data
779 * Sends signal with credentials in directory argument
781 void wpas_dbus_signal_wps_cred(struct wpa_supplicant
*wpa_s
,
782 const struct wps_credential
*cred
)
784 DBusMessage
*_signal
= NULL
;
785 DBusMessageIter iter
, dict_iter
;
786 struct wpas_dbus_priv
*iface
;
788 char *auth_type
[6]; /* we have six possible authorization types */
790 char *encr_type
[4]; /* we have four possible encryption types */
793 iface
= wpa_s
->global
->dbus
;
795 /* Do nothing if the control interface is not turned on */
799 path
= wpas_dbus_get_path(wpa_s
);
801 wpa_printf(MSG_ERROR
, "wpas_dbus_signal_wps_cred[dbus]: "
802 "interface has no dbus path set");
806 _signal
= dbus_message_new_signal(path
, WPAS_DBUS_NEW_IFACE_WPS
,
809 wpa_printf(MSG_ERROR
, "wpas_dbus_signal_wps_cred[dbus]: "
810 "out of memory when creating a signal");
814 dbus_message_iter_init_append(_signal
, &iter
);
816 if (!wpa_dbus_dict_open_write(&iter
, &dict_iter
)) {
817 perror("wpas_dbus_signal_wps_cred[dbus]: out of memory "
818 "when opening a dictionary");
822 if (cred
->auth_type
& WPS_AUTH_OPEN
)
823 auth_type
[at_num
++] = "open";
824 if (cred
->auth_type
& WPS_AUTH_WPAPSK
)
825 auth_type
[at_num
++] = "wpa-psk";
826 if (cred
->auth_type
& WPS_AUTH_SHARED
)
827 auth_type
[at_num
++] = "shared";
828 if (cred
->auth_type
& WPS_AUTH_WPA
)
829 auth_type
[at_num
++] = "wpa-eap";
830 if (cred
->auth_type
& WPS_AUTH_WPA2
)
831 auth_type
[at_num
++] = "wpa2-eap";
832 if (cred
->auth_type
& WPS_AUTH_WPA2PSK
)
833 auth_type
[at_num
++] =
836 if (cred
->encr_type
& WPS_ENCR_NONE
)
837 encr_type
[et_num
++] = "none";
838 if (cred
->encr_type
& WPS_ENCR_WEP
)
839 encr_type
[et_num
++] = "wep";
840 if (cred
->encr_type
& WPS_ENCR_TKIP
)
841 encr_type
[et_num
++] = "tkip";
842 if (cred
->encr_type
& WPS_ENCR_AES
)
843 encr_type
[et_num
++] = "aes";
845 if (wpa_s
->current_ssid
) {
846 if (!wpa_dbus_dict_append_byte_array(
848 (const char *) wpa_s
->current_ssid
->bssid
,
850 perror("wpas_dbus_signal_wps_cred[dbus]: out of "
851 "memory when appending bssid to dictionary");
856 if (!(wpa_dbus_dict_append_byte_array(&dict_iter
, "SSID",
857 (const char *) cred
->ssid
,
859 wpa_dbus_dict_append_string_array(&dict_iter
, "AuthType",
860 (const char **) auth_type
,
862 wpa_dbus_dict_append_string_array(&dict_iter
, "EncrType",
863 (const char **) encr_type
,
865 wpa_dbus_dict_append_byte_array(&dict_iter
, "Key",
866 (const char *) cred
->key
,
868 wpa_dbus_dict_append_uint32(&dict_iter
, "KeyIndex",
870 perror("wpas_dbus_signal_wps_cred[dbus]: out of memory "
871 "when appending to dictionary");
875 if (!wpa_dbus_dict_close_write(&iter
, &dict_iter
)) {
876 perror("wpas_dbus_signal_wps_cred[dbus]: out of memory "
877 "when closing a dictionary");
881 dbus_connection_send(iface
->con
, _signal
, NULL
);
884 dbus_message_unref(_signal
);
887 #endif /* CONFIG_WPS */
891 * wpas_dbus_signal_prop_changed - Signals change of property
892 * @wpa_s: %wpa_supplicant network interface data
893 * @property: indicates which property has changed
895 * Sends ProertyChanged signals with path, interface and arguments
896 * depending on which property has changed.
898 void wpas_dbus_signal_prop_changed(struct wpa_supplicant
*wpa_s
,
899 enum wpas_dbus_prop property
)
901 WPADBusPropertyAccessor getter
;
907 case WPAS_DBUS_PROP_AP_SCAN
:
908 getter
= (WPADBusPropertyAccessor
) wpas_dbus_getter_ap_scan
;
910 iface
= WPAS_DBUS_NEW_IFACE_INTERFACE
;
913 case WPAS_DBUS_PROP_SCANNING
:
914 getter
= (WPADBusPropertyAccessor
) wpas_dbus_getter_scanning
;
916 iface
= WPAS_DBUS_NEW_IFACE_INTERFACE
;
919 case WPAS_DBUS_PROP_CURRENT_BSS
:
920 getter
= (WPADBusPropertyAccessor
)
921 wpas_dbus_getter_current_bss
;
923 iface
= WPAS_DBUS_NEW_IFACE_INTERFACE
;
926 case WPAS_DBUS_PROP_CURRENT_NETWORK
:
927 getter
= (WPADBusPropertyAccessor
)
928 wpas_dbus_getter_current_network
;
930 iface
= WPAS_DBUS_NEW_IFACE_INTERFACE
;
931 prop
= "CurrentNetwork";
934 wpa_printf(MSG_ERROR
, "wpas_dbus_signal_prop_changed[dbus]: "
935 "Unknown Property enum value %d", property
);
939 wpa_dbus_signal_property_changed(wpa_s
->global
->dbus
,
941 wpas_dbus_get_path(wpa_s
), iface
,
947 * wpas_dbus_signal_debug_level_changed - Signals change of debug param
948 * @global: wpa_global structure
950 * Sends ProertyChanged signals informing that debug level has changed.
952 void wpas_dbus_signal_debug_level_changed(struct wpa_global
*global
)
954 wpa_dbus_signal_property_changed(global
->dbus
,
955 (WPADBusPropertyAccessor
)
956 wpas_dbus_getter_debug_level
,
957 global
, WPAS_DBUS_NEW_PATH
,
958 WPAS_DBUS_NEW_INTERFACE
,
964 * wpas_dbus_signal_debug_timestamp_changed - Signals change of debug param
965 * @global: wpa_global structure
967 * Sends ProertyChanged signals informing that debug timestamp has changed.
969 void wpas_dbus_signal_debug_timestamp_changed(struct wpa_global
*global
)
971 wpa_dbus_signal_property_changed(global
->dbus
,
972 (WPADBusPropertyAccessor
)
973 wpas_dbus_getter_debug_timestamp
,
974 global
, WPAS_DBUS_NEW_PATH
,
975 WPAS_DBUS_NEW_INTERFACE
,
981 * wpas_dbus_signal_debug_show_keys_changed - Signals change of debug param
982 * @global: wpa_global structure
984 * Sends ProertyChanged signals informing that debug show_keys has changed.
986 void wpas_dbus_signal_debug_show_keys_changed(struct wpa_global
*global
)
988 wpa_dbus_signal_property_changed(global
->dbus
,
989 (WPADBusPropertyAccessor
)
990 wpas_dbus_getter_debug_show_keys
,
991 global
, WPAS_DBUS_NEW_PATH
,
992 WPAS_DBUS_NEW_INTERFACE
,
997 struct wpas_dbus_method
{
1000 WPADBusMethodHandler handler
;
1001 struct wpa_dbus_argument args
[3];
1004 struct wpas_dbus_property
{
1008 WPADBusPropertyAccessor getter
;
1009 WPADBusPropertyAccessor setter
;
1010 enum dbus_prop_access _access
;
1013 struct wpas_dbus_signal
{
1016 struct wpa_dbus_argument args
[3];
1020 static void wpas_dbus_register(struct wpa_dbus_object_desc
*obj_desc
,
1022 WPADBusArgumentFreeFunction priv_free
,
1023 const struct wpas_dbus_method
*methods
,
1024 const struct wpas_dbus_property
*properties
,
1025 const struct wpas_dbus_signal
*signals
)
1029 obj_desc
->user_data
= priv
;
1030 obj_desc
->user_data_free_func
= priv_free
;
1032 for (i
= 0; methods
&& methods
[i
].name
; i
++) {
1033 wpa_dbus_method_register(obj_desc
, methods
[i
].iface
,
1034 methods
[i
].name
, methods
[i
].handler
,
1038 for (i
= 0; properties
&& properties
[i
].name
; i
++) {
1039 wpa_dbus_property_register(obj_desc
, properties
[i
].iface
,
1042 properties
[i
].getter
,
1043 properties
[i
].setter
,
1044 properties
[i
]._access
);
1047 for (i
= 0; signals
&& signals
[i
].name
; i
++) {
1048 wpa_dbus_signal_register(obj_desc
, signals
[i
].iface
,
1049 signals
[i
].name
, signals
[i
].args
);
1054 static const struct wpas_dbus_method wpas_dbus_global_methods
[] = {
1055 { "CreateInterface", WPAS_DBUS_NEW_INTERFACE
,
1056 (WPADBusMethodHandler
) &wpas_dbus_handler_create_interface
,
1058 { "args", "a{sv}", ARG_IN
},
1059 { "path", "o", ARG_OUT
},
1063 { "RemoveInterface", WPAS_DBUS_NEW_INTERFACE
,
1064 (WPADBusMethodHandler
) &wpas_dbus_handler_remove_interface
,
1066 { "path", "o", ARG_IN
},
1070 { "GetInterface", WPAS_DBUS_NEW_INTERFACE
,
1071 (WPADBusMethodHandler
) &wpas_dbus_handler_get_interface
,
1073 { "ifname", "s", ARG_IN
},
1074 { "path", "o", ARG_OUT
},
1078 { NULL
, NULL
, NULL
, { END_ARGS
} }
1081 static const struct wpas_dbus_property wpas_dbus_global_properties
[] = {
1082 { "DebugLevel", WPAS_DBUS_NEW_INTERFACE
, "y",
1083 (WPADBusPropertyAccessor
) wpas_dbus_getter_debug_level
,
1084 (WPADBusPropertyAccessor
) wpas_dbus_setter_debug_level
,
1087 { "DebugTimestamp", WPAS_DBUS_NEW_INTERFACE
, "b",
1088 (WPADBusPropertyAccessor
) wpas_dbus_getter_debug_timestamp
,
1089 (WPADBusPropertyAccessor
) wpas_dbus_setter_debug_timestamp
,
1092 { "DebugShowKeys", WPAS_DBUS_NEW_INTERFACE
, "b",
1093 (WPADBusPropertyAccessor
) wpas_dbus_getter_debug_show_keys
,
1094 (WPADBusPropertyAccessor
) wpas_dbus_setter_debug_show_keys
,
1097 { "Interfaces", WPAS_DBUS_NEW_INTERFACE
, "ao",
1098 (WPADBusPropertyAccessor
) &wpas_dbus_getter_interfaces
,
1102 { "EapMethods", WPAS_DBUS_NEW_INTERFACE
, "as",
1103 (WPADBusPropertyAccessor
) wpas_dbus_getter_eap_methods
,
1107 { NULL
, NULL
, NULL
, NULL
, NULL
, 0 }
1110 static const struct wpas_dbus_signal wpas_dbus_global_signals
[] = {
1111 { "InterfaceAdded", WPAS_DBUS_NEW_INTERFACE
,
1113 { "path", "o", ARG_OUT
},
1114 { "properties", "a{sv}", ARG_OUT
},
1118 { "InterfaceRemoved", WPAS_DBUS_NEW_INTERFACE
,
1120 { "path", "o", ARG_OUT
},
1124 { "PropertiesChanged", WPAS_DBUS_NEW_INTERFACE
,
1126 { "properties", "a{sv}", ARG_OUT
},
1130 { NULL
, NULL
, { END_ARGS
} }
1135 * wpas_dbus_ctrl_iface_init - Initialize dbus control interface
1136 * @global: Pointer to global data from wpa_supplicant_init()
1137 * Returns: 0 on success or -1 on failure
1139 * Initialize the dbus control interface for wpa_supplicantand and start
1140 * receiving commands from external programs over the bus.
1142 int wpas_dbus_ctrl_iface_init(struct wpas_dbus_priv
*priv
)
1144 struct wpa_dbus_object_desc
*obj_desc
;
1147 obj_desc
= os_zalloc(sizeof(struct wpa_dbus_object_desc
));
1149 wpa_printf(MSG_ERROR
, "Not enough memory "
1150 "to create object description");
1154 wpas_dbus_register(obj_desc
, priv
->global
, NULL
,
1155 wpas_dbus_global_methods
,
1156 wpas_dbus_global_properties
,
1157 wpas_dbus_global_signals
);
1159 wpa_printf(MSG_DEBUG
, "dbus: Register D-Bus object '%s'",
1160 WPAS_DBUS_NEW_PATH
);
1161 ret
= wpa_dbus_ctrl_iface_init(priv
, WPAS_DBUS_NEW_PATH
,
1162 WPAS_DBUS_NEW_SERVICE
,
1165 free_dbus_object_desc(obj_desc
);
1167 priv
->dbus_new_initialized
= 1;
1174 * wpas_dbus_ctrl_iface_deinit - Deinitialize dbus ctrl interface for
1176 * @iface: Pointer to dbus private data from wpas_dbus_init()
1178 * Deinitialize the dbus control interface that was initialized with
1179 * wpas_dbus_ctrl_iface_init().
1181 void wpas_dbus_ctrl_iface_deinit(struct wpas_dbus_priv
*iface
)
1183 if (!iface
->dbus_new_initialized
)
1185 wpa_printf(MSG_DEBUG
, "dbus: Unregister D-Bus object '%s'",
1186 WPAS_DBUS_NEW_PATH
);
1187 dbus_connection_unregister_object_path(iface
->con
,
1188 WPAS_DBUS_NEW_PATH
);
1192 static void wpa_dbus_free(void *ptr
)
1198 static const struct wpas_dbus_property wpas_dbus_network_properties
[] = {
1199 { "Properties", WPAS_DBUS_NEW_IFACE_NETWORK
, "a{sv}",
1200 (WPADBusPropertyAccessor
) wpas_dbus_getter_network_properties
,
1201 (WPADBusPropertyAccessor
) wpas_dbus_setter_network_properties
,
1204 { "Enabled", WPAS_DBUS_NEW_IFACE_NETWORK
, "b",
1205 (WPADBusPropertyAccessor
) wpas_dbus_getter_enabled
,
1206 (WPADBusPropertyAccessor
) wpas_dbus_setter_enabled
,
1209 { NULL
, NULL
, NULL
, NULL
, NULL
, 0 }
1213 static const struct wpas_dbus_signal wpas_dbus_network_signals
[] = {
1214 { "PropertiesChanged", WPAS_DBUS_NEW_IFACE_NETWORK
,
1216 { "properties", "a{sv}", ARG_OUT
},
1220 { NULL
, NULL
, { END_ARGS
} }
1225 * wpas_dbus_register_network - Register a configured network with dbus
1226 * @wpa_s: wpa_supplicant interface structure
1227 * @ssid: network configuration data
1228 * Returns: 0 on success, -1 on failure
1230 * Registers network representing object with dbus
1232 int wpas_dbus_register_network(struct wpa_supplicant
*wpa_s
,
1233 struct wpa_ssid
*ssid
)
1235 struct wpas_dbus_priv
*ctrl_iface
;
1236 struct wpa_dbus_object_desc
*obj_desc
;
1238 struct network_handler_args
*arg
= NULL
;
1242 /* Do nothing if the control interface is not turned on */
1243 if (wpa_s
== NULL
|| wpa_s
->global
== NULL
)
1245 ctrl_iface
= wpa_s
->global
->dbus
;
1246 if (ctrl_iface
== NULL
)
1249 net_obj_path
= os_zalloc(WPAS_DBUS_OBJECT_PATH_MAX
);
1250 if (net_obj_path
== NULL
)
1252 os_snprintf(net_obj_path
, WPAS_DBUS_OBJECT_PATH_MAX
,
1253 "%s/" WPAS_DBUS_NEW_NETWORKS_PART
"/%u",
1254 wpas_dbus_get_path(wpa_s
), ssid
->id
);
1256 wpa_printf(MSG_DEBUG
, "dbus: Register network object '%s'",
1258 obj_desc
= os_zalloc(sizeof(struct wpa_dbus_object_desc
));
1260 wpa_printf(MSG_ERROR
, "Not enough memory "
1261 "to create object description");
1265 /* allocate memory for handlers arguments */
1266 arg
= os_zalloc(sizeof(struct network_handler_args
));
1268 wpa_printf(MSG_ERROR
, "Not enough memory "
1269 "to create arguments for method");
1276 wpas_dbus_register(obj_desc
, arg
, wpa_dbus_free
, NULL
,
1277 wpas_dbus_network_properties
,
1278 wpas_dbus_network_signals
);
1280 if (wpa_dbus_register_object_per_iface(ctrl_iface
, net_obj_path
,
1281 wpa_s
->ifname
, obj_desc
))
1284 wpas_dbus_signal_network_added(wpa_s
, ssid
->id
);
1286 os_free(net_obj_path
);
1290 os_free(net_obj_path
);
1298 * wpas_dbus_unregister_network - Unregister a configured network from dbus
1299 * @wpa_s: wpa_supplicant interface structure
1301 * Returns: 0 on success, -1 on failure
1303 * Unregisters network representing object from dbus
1305 int wpas_dbus_unregister_network(struct wpa_supplicant
*wpa_s
, int nid
)
1307 struct wpas_dbus_priv
*ctrl_iface
;
1311 /* Do nothing if the control interface is not turned on */
1312 if (wpa_s
== NULL
|| wpa_s
->global
== NULL
)
1314 ctrl_iface
= wpa_s
->global
->dbus
;
1315 if (ctrl_iface
== NULL
)
1318 net_obj_path
= os_zalloc(WPAS_DBUS_OBJECT_PATH_MAX
);
1319 if (net_obj_path
== NULL
)
1321 os_snprintf(net_obj_path
, WPAS_DBUS_OBJECT_PATH_MAX
,
1322 "%s/" WPAS_DBUS_NEW_NETWORKS_PART
"/%u",
1323 wpas_dbus_get_path(wpa_s
), nid
);
1325 wpa_printf(MSG_DEBUG
, "dbus: Unregister network object '%s'",
1327 ret
= wpa_dbus_unregister_object_per_iface(ctrl_iface
, net_obj_path
);
1330 wpas_dbus_signal_network_removed(wpa_s
, nid
);
1332 os_free(net_obj_path
);
1337 static const struct wpas_dbus_property wpas_dbus_bss_properties
[] = {
1338 { "SSID", WPAS_DBUS_NEW_IFACE_BSSID
, "ay",
1339 (WPADBusPropertyAccessor
) wpas_dbus_getter_bss_ssid
,
1343 { "BSSID", WPAS_DBUS_NEW_IFACE_BSSID
, "ay",
1344 (WPADBusPropertyAccessor
) wpas_dbus_getter_bss_bssid
,
1348 { "Privacy", WPAS_DBUS_NEW_IFACE_BSSID
, "b",
1349 (WPADBusPropertyAccessor
) wpas_dbus_getter_bss_privacy
,
1353 { "Mode", WPAS_DBUS_NEW_IFACE_BSSID
, "s",
1354 (WPADBusPropertyAccessor
) wpas_dbus_getter_bss_mode
,
1358 { "Signal", WPAS_DBUS_NEW_IFACE_BSSID
, "n",
1359 (WPADBusPropertyAccessor
) wpas_dbus_getter_bss_signal
,
1363 { "Frequency", WPAS_DBUS_NEW_IFACE_BSSID
, "q",
1364 (WPADBusPropertyAccessor
) wpas_dbus_getter_bss_frequency
,
1368 { "MaxRate", WPAS_DBUS_NEW_IFACE_BSSID
, "q",
1369 (WPADBusPropertyAccessor
) wpas_dbus_getter_bss_max_rate
,
1373 { "WPAIE", WPAS_DBUS_NEW_IFACE_BSSID
, "ay",
1374 (WPADBusPropertyAccessor
) wpas_dbus_getter_bss_wpaie
,
1378 { "RSNIE", WPAS_DBUS_NEW_IFACE_BSSID
, "ay",
1379 (WPADBusPropertyAccessor
) wpas_dbus_getter_bss_rsnie
,
1383 { "WPSIE", WPAS_DBUS_NEW_IFACE_BSSID
, "ay",
1384 (WPADBusPropertyAccessor
) wpas_dbus_getter_bss_wpsie
,
1388 { NULL
, NULL
, NULL
, NULL
, NULL
, 0 }
1392 static const struct wpas_dbus_signal wpas_dbus_bss_signals
[] = {
1393 { "PropertiesChanged", WPAS_DBUS_NEW_IFACE_BSSID
,
1395 { "properties", "a{sv}", ARG_OUT
},
1399 { NULL
, NULL
, { END_ARGS
} }
1404 * wpas_dbus_unregister_bss - Unregister a scanned BSS from dbus
1405 * @wpa_s: wpa_supplicant interface structure
1406 * @bssid: scanned network bssid
1407 * @id: unique BSS identifier
1408 * Returns: 0 on success, -1 on failure
1410 * Unregisters BSS representing object from dbus
1412 int wpas_dbus_unregister_bss(struct wpa_supplicant
*wpa_s
,
1413 u8 bssid
[ETH_ALEN
], unsigned int id
)
1415 struct wpas_dbus_priv
*ctrl_iface
;
1418 /* Do nothing if the control interface is not turned on */
1419 if (wpa_s
== NULL
|| wpa_s
->global
== NULL
)
1421 ctrl_iface
= wpa_s
->global
->dbus
;
1422 if (ctrl_iface
== NULL
)
1425 bss_obj_path
= os_zalloc(WPAS_DBUS_OBJECT_PATH_MAX
);
1426 if (bss_obj_path
== NULL
)
1429 os_snprintf(bss_obj_path
, WPAS_DBUS_OBJECT_PATH_MAX
,
1430 "%s/" WPAS_DBUS_NEW_BSSIDS_PART
"/%u",
1431 wpas_dbus_get_path(wpa_s
), id
);
1433 wpa_printf(MSG_DEBUG
, "dbus: Unregister BSS object '%s'",
1435 if (wpa_dbus_unregister_object_per_iface(ctrl_iface
, bss_obj_path
)) {
1436 wpa_printf(MSG_ERROR
,
1437 "Cannot unregister BSSID dbus object %s.",
1439 os_free(bss_obj_path
);
1443 wpas_dbus_signal_bss_removed(wpa_s
, bss_obj_path
);
1445 os_free(bss_obj_path
);
1451 * wpas_dbus_register_bss - Register a scanned BSS with dbus
1452 * @wpa_s: wpa_supplicant interface structure
1453 * @bssid: scanned network bssid
1454 * @id: unique BSS identifier
1455 * Returns: 0 on success, -1 on failure
1457 * Registers BSS representing object with dbus
1459 int wpas_dbus_register_bss(struct wpa_supplicant
*wpa_s
,
1460 u8 bssid
[ETH_ALEN
], unsigned int id
)
1462 struct wpas_dbus_priv
*ctrl_iface
;
1463 struct wpa_dbus_object_desc
*obj_desc
;
1466 struct bss_handler_args
*arg
= NULL
;
1468 /* Do nothing if the control interface is not turned on */
1469 if (wpa_s
== NULL
|| wpa_s
->global
== NULL
)
1471 ctrl_iface
= wpa_s
->global
->dbus
;
1472 if (ctrl_iface
== NULL
)
1475 bss_obj_path
= os_zalloc(WPAS_DBUS_OBJECT_PATH_MAX
);
1476 if (bss_obj_path
== NULL
)
1479 os_snprintf(bss_obj_path
, WPAS_DBUS_OBJECT_PATH_MAX
,
1480 "%s/" WPAS_DBUS_NEW_BSSIDS_PART
"/%u",
1481 wpas_dbus_get_path(wpa_s
), id
);
1483 obj_desc
= os_zalloc(sizeof(struct wpa_dbus_object_desc
));
1485 wpa_printf(MSG_ERROR
, "Not enough memory "
1486 "to create object description");
1490 arg
= os_zalloc(sizeof(struct bss_handler_args
));
1492 wpa_printf(MSG_ERROR
, "Not enough memory "
1493 "to create arguments for handler");
1499 wpas_dbus_register(obj_desc
, arg
, wpa_dbus_free
, NULL
,
1500 wpas_dbus_bss_properties
,
1501 wpas_dbus_bss_signals
);
1503 wpa_printf(MSG_DEBUG
, "dbus: Register BSS object '%s'",
1505 if (wpa_dbus_register_object_per_iface(ctrl_iface
, bss_obj_path
,
1506 wpa_s
->ifname
, obj_desc
)) {
1507 wpa_printf(MSG_ERROR
,
1508 "Cannot register BSSID dbus object %s.",
1513 wpas_dbus_signal_bss_added(wpa_s
, bss_obj_path
);
1515 os_free(bss_obj_path
);
1519 os_free(bss_obj_path
);
1526 static const struct wpas_dbus_method wpas_dbus_interface_methods
[] = {
1527 { "Scan", WPAS_DBUS_NEW_IFACE_INTERFACE
,
1528 (WPADBusMethodHandler
) &wpas_dbus_handler_scan
,
1530 { "args", "a{sv}", ARG_IN
},
1534 { "Disconnect", WPAS_DBUS_NEW_IFACE_INTERFACE
,
1535 (WPADBusMethodHandler
) &wpas_dbus_handler_disconnect
,
1540 { "AddNetwork", WPAS_DBUS_NEW_IFACE_INTERFACE
,
1541 (WPADBusMethodHandler
) &wpas_dbus_handler_add_network
,
1543 { "args", "a{sv}", ARG_IN
},
1544 { "path", "o", ARG_OUT
},
1548 { "RemoveNetwork", WPAS_DBUS_NEW_IFACE_INTERFACE
,
1549 (WPADBusMethodHandler
) &wpas_dbus_handler_remove_network
,
1551 { "path", "o", ARG_IN
},
1555 { "SelectNetwork", WPAS_DBUS_NEW_IFACE_INTERFACE
,
1556 (WPADBusMethodHandler
) &wpas_dbus_handler_select_network
,
1558 { "path", "o", ARG_IN
},
1562 { "AddBlob", WPAS_DBUS_NEW_IFACE_INTERFACE
,
1563 (WPADBusMethodHandler
) &wpas_dbus_handler_add_blob
,
1565 { "name", "s", ARG_IN
},
1566 { "data", "ay", ARG_IN
},
1570 { "GetBlob", WPAS_DBUS_NEW_IFACE_INTERFACE
,
1571 (WPADBusMethodHandler
) &wpas_dbus_handler_get_blob
,
1573 { "name", "s", ARG_IN
},
1574 { "data", "ay", ARG_OUT
},
1578 { "RemoveBlob", WPAS_DBUS_NEW_IFACE_INTERFACE
,
1579 (WPADBusMethodHandler
) &wpas_dbus_handler_remove_blob
,
1581 { "name", "s", ARG_IN
},
1586 { "Start", WPAS_DBUS_NEW_IFACE_WPS
,
1587 (WPADBusMethodHandler
) &wpas_dbus_handler_wps_start
,
1589 { "args", "a{sv}", ARG_IN
},
1590 { "output", "a{sv}", ARG_OUT
},
1594 #endif /* CONFIG_WPS */
1595 { NULL
, NULL
, NULL
, { END_ARGS
} }
1598 static const struct wpas_dbus_property wpas_dbus_interface_properties
[] = {
1599 { "Capabilities", WPAS_DBUS_NEW_IFACE_INTERFACE
, "a{sv}",
1600 (WPADBusPropertyAccessor
) wpas_dbus_getter_capabilities
,
1603 { "State", WPAS_DBUS_NEW_IFACE_INTERFACE
, "s",
1604 (WPADBusPropertyAccessor
) wpas_dbus_getter_state
,
1607 { "Scanning", WPAS_DBUS_NEW_IFACE_INTERFACE
, "b",
1608 (WPADBusPropertyAccessor
) wpas_dbus_getter_scanning
,
1611 { "ApScan", WPAS_DBUS_NEW_IFACE_INTERFACE
, "u",
1612 (WPADBusPropertyAccessor
) wpas_dbus_getter_ap_scan
,
1613 (WPADBusPropertyAccessor
) wpas_dbus_setter_ap_scan
,
1616 { "Ifname", WPAS_DBUS_NEW_IFACE_INTERFACE
, "s",
1617 (WPADBusPropertyAccessor
) wpas_dbus_getter_ifname
,
1620 { "Driver", WPAS_DBUS_NEW_IFACE_INTERFACE
, "s",
1621 (WPADBusPropertyAccessor
) wpas_dbus_getter_driver
,
1624 { "BridgeIfname", WPAS_DBUS_NEW_IFACE_INTERFACE
, "s",
1625 (WPADBusPropertyAccessor
) wpas_dbus_getter_bridge_ifname
,
1628 { "CurrentBSS", WPAS_DBUS_NEW_IFACE_INTERFACE
, "o",
1629 (WPADBusPropertyAccessor
) wpas_dbus_getter_current_bss
,
1632 { "CurrentNetwork", WPAS_DBUS_NEW_IFACE_INTERFACE
, "o",
1633 (WPADBusPropertyAccessor
) wpas_dbus_getter_current_network
,
1636 { "Blobs", WPAS_DBUS_NEW_IFACE_INTERFACE
, "a{say}",
1637 (WPADBusPropertyAccessor
) wpas_dbus_getter_blobs
,
1640 { "BSSs", WPAS_DBUS_NEW_IFACE_INTERFACE
, "ao",
1641 (WPADBusPropertyAccessor
) wpas_dbus_getter_bsss
,
1644 { "Networks", WPAS_DBUS_NEW_IFACE_INTERFACE
, "ao",
1645 (WPADBusPropertyAccessor
) wpas_dbus_getter_networks
,
1649 { "ProcessCredentials", WPAS_DBUS_NEW_IFACE_WPS
, "b",
1650 (WPADBusPropertyAccessor
) wpas_dbus_getter_process_credentials
,
1651 (WPADBusPropertyAccessor
) wpas_dbus_setter_process_credentials
,
1654 #endif /* CONFIG_WPS */
1655 { NULL
, NULL
, NULL
, NULL
, NULL
, 0 }
1658 static const struct wpas_dbus_signal wpas_dbus_interface_signals
[] = {
1659 { "ScanDone", WPAS_DBUS_NEW_IFACE_INTERFACE
,
1661 { "success", "b", ARG_OUT
},
1665 { "StateChanged", WPAS_DBUS_NEW_IFACE_INTERFACE
,
1667 { "newState", "s", ARG_OUT
},
1668 { "oldState", "s", ARG_OUT
},
1672 { "BSSAdded", WPAS_DBUS_NEW_IFACE_INTERFACE
,
1674 { "path", "o", ARG_OUT
},
1675 { "properties", "a{sv}", ARG_OUT
},
1679 { "BSSRemoved", WPAS_DBUS_NEW_IFACE_INTERFACE
,
1681 { "path", "o", ARG_OUT
},
1685 { "BlobAdded", WPAS_DBUS_NEW_IFACE_INTERFACE
,
1687 { "name", "s", ARG_OUT
},
1691 { "BlobRemoved", WPAS_DBUS_NEW_IFACE_INTERFACE
,
1693 { "name", "s", ARG_OUT
},
1697 { "NetworkAdded", WPAS_DBUS_NEW_IFACE_INTERFACE
,
1699 { "path", "o", ARG_OUT
},
1700 { "properties", "a{sv}", ARG_OUT
},
1704 { "NetworkRemoved", WPAS_DBUS_NEW_IFACE_INTERFACE
,
1706 { "path", "o", ARG_OUT
},
1710 { "NetworkSelected", WPAS_DBUS_NEW_IFACE_INTERFACE
,
1712 { "path", "o", ARG_OUT
},
1716 { "PropertiesChanged", WPAS_DBUS_NEW_IFACE_INTERFACE
,
1718 { "properties", "a{sv}", ARG_OUT
},
1723 { "Event", WPAS_DBUS_NEW_IFACE_WPS
,
1725 { "name", "s", ARG_OUT
},
1726 { "args", "a{sv}", ARG_OUT
},
1730 { "Credentials", WPAS_DBUS_NEW_IFACE_WPS
,
1732 { "credentials", "a{sv}", ARG_OUT
},
1736 { "PropertiesChanged", WPAS_DBUS_NEW_IFACE_WPS
,
1738 { "properties", "a{sv}", ARG_OUT
},
1742 #endif /* CONFIG_WPS */
1743 { NULL
, NULL
, { END_ARGS
} }
1747 int wpas_dbus_register_interface(struct wpa_supplicant
*wpa_s
)
1750 struct wpa_dbus_object_desc
*obj_desc
= NULL
;
1751 struct wpas_dbus_priv
*ctrl_iface
= wpa_s
->global
->dbus
;
1754 /* Do nothing if the control interface is not turned on */
1755 if (ctrl_iface
== NULL
)
1758 /* Create and set the interface's object path */
1759 wpa_s
->dbus_new_path
= os_zalloc(WPAS_DBUS_OBJECT_PATH_MAX
);
1760 if (wpa_s
->dbus_new_path
== NULL
)
1762 next
= ctrl_iface
->next_objid
++;
1763 os_snprintf(wpa_s
->dbus_new_path
, WPAS_DBUS_OBJECT_PATH_MAX
,
1764 WPAS_DBUS_NEW_PATH_INTERFACES
"/%u",
1767 obj_desc
= os_zalloc(sizeof(struct wpa_dbus_object_desc
));
1769 wpa_printf(MSG_ERROR
, "Not enough memory "
1770 "to create object description");
1774 wpas_dbus_register(obj_desc
, wpa_s
, NULL
, wpas_dbus_interface_methods
,
1775 wpas_dbus_interface_properties
,
1776 wpas_dbus_interface_signals
);
1778 wpa_printf(MSG_DEBUG
, "dbus: Register interface object '%s'",
1779 wpa_s
->dbus_new_path
);
1780 if (wpa_dbus_register_object_per_iface(ctrl_iface
,
1781 wpa_s
->dbus_new_path
,
1782 wpa_s
->ifname
, obj_desc
))
1785 wpas_dbus_signal_interface_added(wpa_s
);
1790 os_free(wpa_s
->dbus_new_path
);
1791 wpa_s
->dbus_new_path
= NULL
;
1797 int wpas_dbus_unregister_interface(struct wpa_supplicant
*wpa_s
)
1799 struct wpas_dbus_priv
*ctrl_iface
;
1801 /* Do nothing if the control interface is not turned on */
1802 if (wpa_s
== NULL
|| wpa_s
->global
== NULL
)
1804 ctrl_iface
= wpa_s
->global
->dbus
;
1805 if (ctrl_iface
== NULL
)
1808 wpa_printf(MSG_DEBUG
, "dbus: Unregister interface object '%s'",
1809 wpas_dbus_get_path(wpa_s
));
1810 if (wpa_dbus_unregister_object_per_iface(ctrl_iface
,
1811 wpas_dbus_get_path(wpa_s
)))
1814 wpas_dbus_signal_interface_removed(wpa_s
);
1816 os_free(wpa_s
->dbus_new_path
);
1817 wpa_s
->dbus_new_path
= NULL
;
1824 * wpas_dbus_get_path - Get an interface's dbus path
1825 * @wpa_s: %wpa_supplicant interface structure
1826 * Returns: Interface's dbus object path, or %NULL on error
1828 const char * wpas_dbus_get_path(struct wpa_supplicant
*wpa_s
)
1830 return wpa_s
->dbus_new_path
;