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"
32 * wpas_dbus_set_path - Assign a dbus path to an interface
33 * @wpa_s: wpa_supplicant interface structure
34 * @path: dbus path to set on the interface
35 * Returns: 0 on success, -1 on error
37 static int wpas_dbus_set_path(struct wpa_supplicant
*wpa_s
,
40 u32 len
= os_strlen(path
);
41 if (len
>= WPAS_DBUS_OBJECT_PATH_MAX
)
43 if (wpa_s
->dbus_new_path
)
45 wpa_s
->dbus_new_path
= os_strdup(path
);
51 * wpas_dbus_signal_interface - Send a interface related event signal
52 * @wpa_s: %wpa_supplicant network interface data
53 * @sig_name: signal name - InterfaceAdded or InterfaceRemoved
54 * @properties: determines if add second argument with object properties
56 * Notify listeners about event related with interface
58 static void wpas_dbus_signal_interface(struct wpa_supplicant
*wpa_s
,
59 const char *sig_name
, int properties
)
61 struct wpas_dbus_priv
*iface
;
63 DBusMessageIter iter
, iter_dict
;
66 iface
= wpa_s
->global
->dbus
;
68 /* Do nothing if the control interface is not turned on */
72 path
= wpas_dbus_get_path(wpa_s
);
74 wpa_printf(MSG_ERROR
, "wpas_dbus_signal_interface[dbus]: "
75 "Interface doesn't have a dbus path. "
76 "Can't send signal.");
79 _signal
= dbus_message_new_signal(WPAS_DBUS_NEW_PATH
,
80 WPAS_DBUS_NEW_INTERFACE
, sig_name
);
81 if (_signal
== NULL
) {
82 wpa_printf(MSG_ERROR
, "wpas_dbus_signal_interface[dbus]: "
83 "enough memory to send scan results signal.");
87 dbus_message_iter_init_append(_signal
, &iter
);
89 if(!dbus_message_iter_append_basic(&iter
, DBUS_TYPE_OBJECT_PATH
,
94 if (!wpa_dbus_dict_open_write(&iter
, &iter_dict
))
97 wpa_dbus_get_object_properties(iface
, path
,
98 WPAS_DBUS_NEW_IFACE_INTERFACE
,
101 if (!wpa_dbus_dict_close_write(&iter
, &iter_dict
))
105 dbus_connection_send(iface
->con
, _signal
, NULL
);
107 dbus_message_unref(_signal
);
111 wpa_printf(MSG_ERROR
, "wpas_dbus_signal_interface[dbus]: "
112 "not enough memory to construct signal.");
113 dbus_message_unref(_signal
);
118 * wpas_dbus_signal_interface_added - Send a interface created signal
119 * @wpa_s: %wpa_supplicant network interface data
121 * Notify listeners about creating new interface
123 static void wpas_dbus_signal_interface_added(struct wpa_supplicant
*wpa_s
)
125 wpas_dbus_signal_interface(wpa_s
, "InterfaceAdded", TRUE
);
130 * wpas_dbus_signal_interface_removed - Send a interface removed signal
131 * @wpa_s: %wpa_supplicant network interface data
133 * Notify listeners about removing interface
135 static void wpas_dbus_signal_interface_removed(struct wpa_supplicant
*wpa_s
)
137 wpas_dbus_signal_interface(wpa_s
, "InterfaceRemoved", FALSE
);
143 * wpas_dbus_signal_scan_done - send scan done signal
144 * @wpa_s: %wpa_supplicant network interface data
145 * @success: indicates if scanning succeed or failed
147 * Notify listeners about finishing a scan
149 static void wpas_dbus_signal_scan_done(struct wpa_supplicant
*wpa_s
,
152 struct wpas_dbus_priv
*iface
;
153 DBusMessage
*_signal
;
157 iface
= wpa_s
->global
->dbus
;
159 /* Do nothing if the control interface is not turned on */
163 path
= wpas_dbus_get_path(wpa_s
);
165 wpa_printf(MSG_ERROR
, "wpas_dbus_signal_scan_done[dbus]: "
166 "Interface doesn't have a dbus path. "
167 "Can't send signal.");
170 _signal
= dbus_message_new_signal(path
, WPAS_DBUS_NEW_IFACE_INTERFACE
,
172 if (_signal
== NULL
) {
173 wpa_printf(MSG_ERROR
, "wpas_dbus_signal_scan_done[dbus]: "
174 "enough memory to send signal.");
178 succ
= success
? TRUE
: FALSE
;
179 if (dbus_message_append_args(_signal
, DBUS_TYPE_BOOLEAN
, &succ
,
180 DBUS_TYPE_INVALID
)) {
181 dbus_connection_send(iface
->con
, _signal
, NULL
);
183 wpa_printf(MSG_ERROR
, "wpas_dbus_signal_scan_done[dbus]: "
184 "not enough memory to construct signal.");
186 dbus_message_unref(_signal
);
191 * wpas_dbus_signal_blob - Send a BSS related event signal
192 * @wpa_s: %wpa_supplicant network interface data
193 * @bss_obj_path: BSS object path
194 * @sig_name: signal name - BSSAdded or BSSRemoved
195 * @properties: determines if add second argument with object properties
197 * Notify listeners about event related with BSS
199 static void wpas_dbus_signal_bss(struct wpa_supplicant
*wpa_s
,
200 const char *bss_obj_path
,
201 const char *sig_name
, int properties
)
203 struct wpas_dbus_priv
*iface
;
204 DBusMessage
*_signal
;
205 DBusMessageIter iter
, iter_dict
;
208 iface
= wpa_s
->global
->dbus
;
210 /* Do nothing if the control interface is not turned on */
214 path
= wpas_dbus_get_path(wpa_s
);
216 wpa_printf(MSG_ERROR
, "wpas_dbus_signal_bss[dbus]: "
217 "Interface doesn't have a dbus path. "
218 "Can't send signal.");
221 _signal
= dbus_message_new_signal(path
, WPAS_DBUS_NEW_IFACE_INTERFACE
,
223 if (_signal
== NULL
) {
224 wpa_printf(MSG_ERROR
, "wpas_dbus_signal_bss[dbus]: "
225 "enough memory to send signal.");
229 dbus_message_iter_init_append(_signal
, &iter
);
231 if (!dbus_message_iter_append_basic(&iter
, DBUS_TYPE_OBJECT_PATH
,
236 if (!wpa_dbus_dict_open_write(&iter
, &iter_dict
))
239 wpa_dbus_get_object_properties(iface
, bss_obj_path
,
240 WPAS_DBUS_NEW_IFACE_BSSID
,
243 if (!wpa_dbus_dict_close_write(&iter
, &iter_dict
))
247 dbus_connection_send(iface
->con
, _signal
, NULL
);
249 dbus_message_unref(_signal
);
253 wpa_printf(MSG_ERROR
, "wpas_dbus_signal_bss[dbus]: "
254 "not enough memory to construct signal.");
255 dbus_message_unref(_signal
);
260 * wpas_dbus_signal_bss_added - Send a BSS added signal
261 * @wpa_s: %wpa_supplicant network interface data
262 * @bss_obj_path: new BSS object path
264 * Notify listeners about adding new BSS
266 static void wpas_dbus_signal_bss_added(struct wpa_supplicant
*wpa_s
,
267 const char *bss_obj_path
)
269 wpas_dbus_signal_bss(wpa_s
, bss_obj_path
, "BSSAdded", TRUE
);
274 * wpas_dbus_signal_bss_removed - Send a BSS removed signal
275 * @wpa_s: %wpa_supplicant network interface data
276 * @bss_obj_path: BSS object path
278 * Notify listeners about removing BSS
280 static void wpas_dbus_signal_bss_removed(struct wpa_supplicant
*wpa_s
,
281 const char *bss_obj_path
)
283 wpas_dbus_signal_bss(wpa_s
, bss_obj_path
, "BSSRemoved", FALSE
);
288 * wpas_dbus_signal_blob - Send a blob related event signal
289 * @wpa_s: %wpa_supplicant network interface data
291 * @sig_name: signal name - BlobAdded or BlobRemoved
293 * Notify listeners about event related with blob
295 static void wpas_dbus_signal_blob(struct wpa_supplicant
*wpa_s
,
296 const char *name
, const char *sig_name
)
298 struct wpas_dbus_priv
*iface
;
299 DBusMessage
*_signal
;
302 iface
= wpa_s
->global
->dbus
;
304 /* Do nothing if the control interface is not turned on */
308 path
= wpas_dbus_get_path(wpa_s
);
310 wpa_printf(MSG_ERROR
, "wpas_dbus_signal_blob[dbus]: "
311 "Interface doesn't have a dbus path. "
312 "Can't send signal.");
315 _signal
= dbus_message_new_signal(path
, WPAS_DBUS_NEW_IFACE_INTERFACE
,
317 if (_signal
== NULL
) {
318 wpa_printf(MSG_ERROR
, "wpas_dbus_signal_blob[dbus]: "
319 "enough memory to send signal.");
323 if (dbus_message_append_args(_signal
, DBUS_TYPE_STRING
, &name
,
324 DBUS_TYPE_INVALID
)) {
325 dbus_connection_send(iface
->con
, _signal
, NULL
);
327 wpa_printf(MSG_ERROR
, "wpas_dbus_signal_blob[dbus]: "
328 "not enough memory to construct signal.");
330 dbus_message_unref(_signal
);
335 * wpas_dbus_signal_blob_added - Send a blob added signal
336 * @wpa_s: %wpa_supplicant network interface data
339 * Notify listeners about adding a new blob
341 static void wpas_dbus_signal_blob_added(struct wpa_supplicant
*wpa_s
,
344 wpas_dbus_signal_blob(wpa_s
, name
, "BlobAdded");
349 * wpas_dbus_signal_blob_removed - Send a blob removed signal
350 * @wpa_s: %wpa_supplicant network interface data
353 * Notify listeners about removing blob
355 static void wpas_dbus_signal_blob_removed(struct wpa_supplicant
*wpa_s
,
358 wpas_dbus_signal_blob(wpa_s
, name
, "BlobRemoved");
363 * wpas_dbus_signal_network - Send a network related event signal
364 * @wpa_s: %wpa_supplicant network interface data
365 * @id: new network id
366 * @sig_name: signal name - NetworkAdded, NetworkRemoved or NetworkSelected
367 * @properties: determines if add second argument with object properties
369 * Notify listeners about event related with configured network
371 static void wpas_dbus_signal_network(struct wpa_supplicant
*wpa_s
,
372 int id
, const char *sig_name
,
375 struct wpas_dbus_priv
*iface
;
376 DBusMessage
*_signal
;
377 DBusMessageIter iter
, iter_dict
;
381 iface
= wpa_s
->global
->dbus
;
383 /* Do nothing if the control interface is not turned on */
387 path
= wpas_dbus_get_path(wpa_s
);
389 wpa_printf(MSG_ERROR
, "wpas_dbus_signal_network[dbus]: "
390 "Interface doesn't have a dbus path. "
391 "Can't send signal.");
395 net_obj_path
= os_zalloc(WPAS_DBUS_OBJECT_PATH_MAX
);
396 if (net_obj_path
== NULL
)
398 os_snprintf(net_obj_path
, WPAS_DBUS_OBJECT_PATH_MAX
,
399 "%s/" WPAS_DBUS_NEW_NETWORKS_PART
"/%u", path
, id
);
401 _signal
= dbus_message_new_signal(path
, WPAS_DBUS_NEW_IFACE_INTERFACE
,
403 if (_signal
== NULL
) {
404 wpa_printf(MSG_ERROR
, "wpas_dbus_signal_network[dbus]: "
405 "enough memory to send signal.");
406 os_free(net_obj_path
);
410 dbus_message_iter_init_append(_signal
, &iter
);
412 if (!dbus_message_iter_append_basic(&iter
, DBUS_TYPE_OBJECT_PATH
,
417 if (!wpa_dbus_dict_open_write(&iter
, &iter_dict
))
420 wpa_dbus_get_object_properties(iface
, net_obj_path
,
421 WPAS_DBUS_NEW_IFACE_NETWORK
,
424 if (!wpa_dbus_dict_close_write(&iter
, &iter_dict
))
428 dbus_connection_send(iface
->con
, _signal
, NULL
);
430 os_free(net_obj_path
);
431 dbus_message_unref(_signal
);
435 wpa_printf(MSG_ERROR
, "wpas_dbus_signal_network[dbus]: "
436 "not enough memory to construct signal.");
437 os_free(net_obj_path
);
438 dbus_message_unref(_signal
);
443 * wpas_dbus_signal_network_added - Send a network added signal
444 * @wpa_s: %wpa_supplicant network interface data
445 * @id: new network id
447 * Notify listeners about adding new network
449 static void wpas_dbus_signal_network_added(struct wpa_supplicant
*wpa_s
,
452 wpas_dbus_signal_network(wpa_s
, id
, "NetworkAdded", TRUE
);
457 * wpas_dbus_signal_network_removed - Send a network removed signal
458 * @wpa_s: %wpa_supplicant network interface data
461 * Notify listeners about removing a network
463 static void wpas_dbus_signal_network_removed(struct wpa_supplicant
*wpa_s
,
466 wpas_dbus_signal_network(wpa_s
, id
, "NetworkRemoved", FALSE
);
471 * wpas_dbus_signal_network_selected - Send a network selected signal
472 * @wpa_s: %wpa_supplicant network interface data
475 * Notify listeners about selecting a network
477 static void wpas_dbus_signal_network_selected(struct wpa_supplicant
*wpa_s
,
480 wpas_dbus_signal_network(wpa_s
, id
, "NetworkSelected", FALSE
);
485 * wpas_dbus_signal_state_changed - Send a state changed signal
486 * @wpa_s: %wpa_supplicant network interface data
487 * @new_state: new state wpa_supplicant is entering
488 * @old_state: old state wpa_supplicant is leaving
490 * Notify listeners that wpa_supplicant has changed state
492 static void wpas_dbus_signal_state_changed(struct wpa_supplicant
*wpa_s
,
493 enum wpa_states new_state
,
494 enum wpa_states old_state
)
496 struct wpas_dbus_priv
*iface
;
497 DBusMessage
*_signal
= NULL
;
499 char *new_state_str
, *old_state_str
;
502 /* Do nothing if the control interface is not turned on */
503 if (wpa_s
->global
== NULL
)
505 iface
= wpa_s
->global
->dbus
;
509 /* Only send signal if state really changed */
510 if (new_state
== old_state
)
513 path
= wpas_dbus_get_path(wpa_s
);
515 perror("wpas_dbus_signal_state_changed[dbus]: "
516 "interface didn't have a dbus path");
517 wpa_printf(MSG_ERROR
,
518 "wpas_dbus_signal_state_changed[dbus]: "
519 "interface didn't have a dbus path; can't send "
523 _signal
= dbus_message_new_signal(path
, WPAS_DBUS_NEW_IFACE_INTERFACE
,
525 if (_signal
== NULL
) {
526 perror("wpas_dbus_signal_state_changed[dbus]: "
527 "couldn't create dbus signal; likely out of memory");
528 wpa_printf(MSG_ERROR
,
529 "wpas_dbus_signal_state_changed[dbus]: "
530 "couldn't create dbus signal; likely out of "
535 new_state_str
= os_strdup(wpa_supplicant_state_txt(new_state
));
536 old_state_str
= os_strdup(wpa_supplicant_state_txt(old_state
));
537 if (new_state_str
== NULL
|| old_state_str
== NULL
) {
538 perror("wpas_dbus_signal_state_changed[dbus]: "
539 "couldn't convert state strings");
540 wpa_printf(MSG_ERROR
,
541 "wpas_dbus_signal_state_changed[dbus]: "
542 "couldn't convert state strings.");
546 /* make state string lowercase to fit new DBus API convention */
549 *tmp
= tolower(*tmp
);
554 *tmp
= tolower(*tmp
);
558 if (!dbus_message_append_args(_signal
,
559 DBUS_TYPE_STRING
, &new_state_str
,
560 DBUS_TYPE_STRING
, &old_state_str
,
561 DBUS_TYPE_INVALID
)) {
562 perror("wpas_dbus_signal_state_changed[dbus]: "
563 "not enough memory to construct state change signal.");
564 wpa_printf(MSG_ERROR
,
565 "wpas_dbus_signal_state_changed[dbus]: "
566 "not enough memory to construct state change "
571 dbus_connection_send(iface
->con
, _signal
, NULL
);
574 dbus_message_unref(_signal
);
575 os_free(new_state_str
);
576 os_free(old_state_str
);
581 * wpas_dbus_signal_network_enabled_changed - Signals Enabled property changes
582 * @wpa_s: %wpa_supplicant network interface data
583 * @ssid: configured network which Enabled property has changed
585 * Sends PropertyChanged signals containing new value of Enabled property
586 * for specified network
588 static void wpas_dbus_signal_network_enabled_changed(
589 struct wpa_supplicant
*wpa_s
, struct wpa_ssid
*ssid
)
592 struct network_handler_args args
= {wpa_s
, ssid
};
594 char path
[WPAS_DBUS_OBJECT_PATH_MAX
];
595 os_snprintf(path
, WPAS_DBUS_OBJECT_PATH_MAX
,
596 "%s/" WPAS_DBUS_NEW_NETWORKS_PART
"/%d",
597 wpas_dbus_get_path(wpa_s
), ssid
->id
);
599 wpa_dbus_signal_property_changed(wpa_s
->global
->dbus
,
600 (WPADBusPropertyAccessor
)
601 wpas_dbus_getter_enabled
, &args
,
602 path
, WPAS_DBUS_NEW_IFACE_NETWORK
,
610 * wpas_dbus_signal_wps_event_success - Signals Success WPS event
611 * @wpa_s: %wpa_supplicant network interface data
613 * Sends Event dbus signal with name "success" and empty dict as arguments
615 static void wpas_dbus_signal_wps_event_success(struct wpa_supplicant
*wpa_s
)
618 DBusMessage
*_signal
= NULL
;
619 DBusMessageIter iter
, dict_iter
;
620 struct wpas_dbus_priv
*iface
;
621 char *key
= "success";
624 iface
= wpa_s
->global
->dbus
;
626 /* Do nothing if the control interface is not turned on */
630 path
= wpas_dbus_get_path(wpa_s
);
632 wpa_printf(MSG_ERROR
, "wpas_dbus_signal_wps_event_success"
633 "[dbus]: interface has no dbus path set");
637 _signal
= dbus_message_new_signal(path
, WPAS_DBUS_NEW_IFACE_WPS
,
640 wpa_printf(MSG_ERROR
, "wpas_dbus_signal_wps_event_success"
641 "[dbus]: out of memory when creating a signal");
645 dbus_message_iter_init_append(_signal
, &iter
);
647 if (!dbus_message_iter_append_basic(&iter
, DBUS_TYPE_STRING
, &key
) ||
648 !wpa_dbus_dict_open_write(&iter
, &dict_iter
) ||
649 !wpa_dbus_dict_close_write(&iter
, &dict_iter
)) {
650 wpa_printf(MSG_ERROR
, "wpas_dbus_signal_wps_event_success"
651 "[dbus]: out of memory");
655 dbus_connection_send(iface
->con
, _signal
, NULL
);
657 dbus_message_unref(_signal
);
662 * wpas_dbus_signal_wps_event_fail - Signals Fail WPS event
663 * @wpa_s: %wpa_supplicant network interface data
665 * Sends Event dbus signal with name "fail" and dictionary containing
666 * "msg field with fail message number (int32) as arguments
668 static void wpas_dbus_signal_wps_event_fail(struct wpa_supplicant
*wpa_s
,
669 struct wps_event_fail
*fail
)
672 DBusMessage
*_signal
= NULL
;
673 DBusMessageIter iter
, dict_iter
;
674 struct wpas_dbus_priv
*iface
;
678 iface
= wpa_s
->global
->dbus
;
680 /* Do nothing if the control interface is not turned on */
684 path
= wpas_dbus_get_path(wpa_s
);
686 wpa_printf(MSG_ERROR
, "wpas_dbus_signal_wps_event_fail[dbus]: "
687 "interface has no dbus path set");
691 _signal
= dbus_message_new_signal(path
, WPAS_DBUS_NEW_IFACE_WPS
,
694 wpa_printf(MSG_ERROR
, "wpas_dbus_signal_wps_event_fail[dbus]: "
695 "out of memory when creating a signal");
699 dbus_message_iter_init_append(_signal
, &iter
);
701 if (!dbus_message_iter_append_basic(&iter
, DBUS_TYPE_STRING
, &key
) ||
702 !wpa_dbus_dict_open_write(&iter
, &dict_iter
) ||
703 !wpa_dbus_dict_append_int32(&dict_iter
, "msg", fail
->msg
) ||
704 !wpa_dbus_dict_close_write(&iter
, &dict_iter
)) {
705 wpa_printf(MSG_ERROR
, "wpas_dbus_signal_wps_event_fail[dbus]: "
710 dbus_connection_send(iface
->con
, _signal
, NULL
);
712 dbus_message_unref(_signal
);
717 * wpas_dbus_signal_wps_event_m2d - Signals M2D WPS event
718 * @wpa_s: %wpa_supplicant network interface data
720 * Sends Event dbus signal with name "m2d" and dictionary containing
721 * fields of wps_event_m2d structure.
723 static void wpas_dbus_signal_wps_event_m2d(struct wpa_supplicant
*wpa_s
,
724 struct wps_event_m2d
*m2d
)
727 DBusMessage
*_signal
= NULL
;
728 DBusMessageIter iter
, dict_iter
;
729 struct wpas_dbus_priv
*iface
;
733 iface
= wpa_s
->global
->dbus
;
735 /* Do nothing if the control interface is not turned on */
739 path
= wpas_dbus_get_path(wpa_s
);
741 wpa_printf(MSG_ERROR
, "wpas_dbus_signal_wps_event_m2d[dbus]: "
742 "interface has no dbus path set");
746 _signal
= dbus_message_new_signal(path
, WPAS_DBUS_NEW_IFACE_WPS
,
749 wpa_printf(MSG_ERROR
, "wpas_dbus_signal_wps_event_m2d[dbus]: "
750 "out of memory when creating a signal");
754 dbus_message_iter_init_append(_signal
, &iter
);
756 if (!(dbus_message_iter_append_basic(&iter
, DBUS_TYPE_STRING
, &key
) &&
757 wpa_dbus_dict_open_write(&iter
, &dict_iter
) &&
758 wpa_dbus_dict_append_uint16(&dict_iter
, "config_methods",
759 m2d
->config_methods
) &&
760 wpa_dbus_dict_append_byte_array(&dict_iter
, "manufacturer",
761 (const char *) m2d
->manufacturer
,
762 m2d
->manufacturer_len
) &&
763 wpa_dbus_dict_append_byte_array(&dict_iter
, "model_name",
764 (const char *) m2d
->model_name
,
765 m2d
->model_name_len
) &&
766 wpa_dbus_dict_append_byte_array(&dict_iter
, "model_number",
767 (const char *) m2d
->model_number
,
768 m2d
->model_number_len
) &&
769 wpa_dbus_dict_append_byte_array(&dict_iter
, "serial_number",
772 m2d
->serial_number_len
) &&
773 wpa_dbus_dict_append_byte_array(&dict_iter
, "dev_name",
774 (const char *) m2d
->dev_name
,
775 m2d
->dev_name_len
) &&
776 wpa_dbus_dict_append_byte_array(&dict_iter
, "primary_dev_type",
778 m2d
->primary_dev_type
, 8) &&
779 wpa_dbus_dict_append_uint16(&dict_iter
, "config_error",
780 m2d
->config_error
) &&
781 wpa_dbus_dict_append_uint16(&dict_iter
, "dev_password_id",
782 m2d
->dev_password_id
) &&
783 wpa_dbus_dict_close_write(&iter
, &dict_iter
))) {
784 wpa_printf(MSG_ERROR
, "wpas_dbus_signal_wps_event_m2d[dbus]: "
789 dbus_connection_send(iface
->con
, _signal
, NULL
);
791 dbus_message_unref(_signal
);
796 * wpas_dbus_signal_wps_cred - Signals new credentials
797 * @wpa_s: %wpa_supplicant network interface data
799 * Sends signal with credentials in directory argument
801 static void wpas_dbus_signal_wps_cred(struct wpa_supplicant
*wpa_s
,
802 const struct wps_credential
*cred
)
804 DBusMessage
*_signal
= NULL
;
805 DBusMessageIter iter
, dict_iter
;
806 struct wpas_dbus_priv
*iface
;
808 char *auth_type
[6]; /* we have six possible authorization types */
810 char *encr_type
[4]; /* we have four possible encryption types */
813 iface
= wpa_s
->global
->dbus
;
815 /* Do nothing if the control interface is not turned on */
819 path
= wpas_dbus_get_path(wpa_s
);
821 wpa_printf(MSG_ERROR
, "wpas_dbus_signal_wps_cred[dbus]: "
822 "interface has no dbus path set");
826 _signal
= dbus_message_new_signal(path
, WPAS_DBUS_NEW_IFACE_WPS
,
829 wpa_printf(MSG_ERROR
, "wpas_dbus_signal_wps_cred[dbus]: "
830 "out of memory when creating a signal");
834 dbus_message_iter_init_append(_signal
, &iter
);
836 if (!wpa_dbus_dict_open_write(&iter
, &dict_iter
)) {
837 perror("wpas_dbus_signal_wps_cred[dbus]: out of memory "
838 "when opening a dictionary");
842 if (cred
->auth_type
& WPS_AUTH_OPEN
)
843 auth_type
[at_num
++] = "open";
844 if (cred
->auth_type
& WPS_AUTH_WPAPSK
)
845 auth_type
[at_num
++] = "wpa-psk";
846 if (cred
->auth_type
& WPS_AUTH_SHARED
)
847 auth_type
[at_num
++] = "shared";
848 if (cred
->auth_type
& WPS_AUTH_WPA
)
849 auth_type
[at_num
++] = "wpa-eap";
850 if (cred
->auth_type
& WPS_AUTH_WPA2
)
851 auth_type
[at_num
++] = "wpa2-eap";
852 if (cred
->auth_type
& WPS_AUTH_WPA2PSK
)
853 auth_type
[at_num
++] =
856 if (cred
->encr_type
& WPS_ENCR_NONE
)
857 encr_type
[et_num
++] = "none";
858 if (cred
->encr_type
& WPS_ENCR_WEP
)
859 encr_type
[et_num
++] = "wep";
860 if (cred
->encr_type
& WPS_ENCR_TKIP
)
861 encr_type
[et_num
++] = "tkip";
862 if (cred
->encr_type
& WPS_ENCR_AES
)
863 encr_type
[et_num
++] = "aes";
865 if (wpa_s
->current_ssid
) {
866 if (!wpa_dbus_dict_append_byte_array(
868 (const char *) wpa_s
->current_ssid
->bssid
,
870 perror("wpas_dbus_signal_wps_cred[dbus]: out of "
871 "memory when appending bssid to dictionary");
876 if (!(wpa_dbus_dict_append_byte_array(&dict_iter
, "SSID",
877 (const char *) cred
->ssid
,
879 wpa_dbus_dict_append_string_array(&dict_iter
, "AuthType",
880 (const char **) auth_type
,
882 wpa_dbus_dict_append_string_array(&dict_iter
, "EncrType",
883 (const char **) encr_type
,
885 wpa_dbus_dict_append_byte_array(&dict_iter
, "Key",
886 (const char *) cred
->key
,
888 wpa_dbus_dict_append_uint32(&dict_iter
, "KeyIndex",
890 perror("wpas_dbus_signal_wps_cred[dbus]: out of memory "
891 "when appending to dictionary");
895 if (!wpa_dbus_dict_close_write(&iter
, &dict_iter
)) {
896 perror("wpas_dbus_signal_wps_cred[dbus]: out of memory "
897 "when closing a dictionary");
901 dbus_connection_send(iface
->con
, _signal
, NULL
);
904 dbus_message_unref(_signal
);
907 #endif /* CONFIG_WPS */
911 * wpas_dbus_signal_prop_changed - Signals change of property
912 * @wpa_s: %wpa_supplicant network interface data
913 * @property: indicates which property has changed
915 * Sends ProertyChanged signals with path, interface and arguments
916 * depending on which property has changed.
918 static void wpas_dbus_signal_prop_changed(struct wpa_supplicant
*wpa_s
,
919 enum wpas_dbus_prop property
)
921 WPADBusPropertyAccessor getter
;
927 case WPAS_DBUS_PROP_AP_SCAN
:
928 getter
= (WPADBusPropertyAccessor
) wpas_dbus_getter_ap_scan
;
930 iface
= WPAS_DBUS_NEW_IFACE_INTERFACE
;
933 case WPAS_DBUS_PROP_SCANNING
:
934 getter
= (WPADBusPropertyAccessor
) wpas_dbus_getter_scanning
;
936 iface
= WPAS_DBUS_NEW_IFACE_INTERFACE
;
939 case WPAS_DBUS_PROP_CURRENT_BSS
:
940 getter
= (WPADBusPropertyAccessor
)
941 wpas_dbus_getter_current_bss
;
943 iface
= WPAS_DBUS_NEW_IFACE_INTERFACE
;
946 case WPAS_DBUS_PROP_CURRENT_NETWORK
:
947 getter
= (WPADBusPropertyAccessor
)
948 wpas_dbus_getter_current_network
;
950 iface
= WPAS_DBUS_NEW_IFACE_INTERFACE
;
951 prop
= "CurrentNetwork";
954 wpa_printf(MSG_ERROR
, "wpas_dbus_signal_prop_changed[dbus]: "
955 "Unknown Property enum value %d", property
);
959 wpa_dbus_signal_property_changed(wpa_s
->global
->dbus
,
961 wpas_dbus_get_path(wpa_s
), iface
,
967 * wpas_dbus_signal_debug_level_changed - Signals change of debug param
968 * @global: wpa_global structure
970 * Sends ProertyChanged signals informing that debug level has changed.
972 static void wpas_dbus_signal_debug_level_changed(struct wpa_global
*global
)
974 wpa_dbus_signal_property_changed(global
->dbus
,
975 (WPADBusPropertyAccessor
)
976 wpas_dbus_getter_debug_level
,
977 global
, WPAS_DBUS_NEW_PATH
,
978 WPAS_DBUS_NEW_INTERFACE
,
984 * wpas_dbus_signal_debug_timestamp_changed - Signals change of debug param
985 * @global: wpa_global structure
987 * Sends ProertyChanged signals informing that debug timestamp has changed.
989 static void wpas_dbus_signal_debug_timestamp_changed(struct wpa_global
*global
)
991 wpa_dbus_signal_property_changed(global
->dbus
,
992 (WPADBusPropertyAccessor
)
993 wpas_dbus_getter_debug_timestamp
,
994 global
, WPAS_DBUS_NEW_PATH
,
995 WPAS_DBUS_NEW_INTERFACE
,
1001 * wpas_dbus_signal_debug_show_keys_changed - Signals change of debug param
1002 * @global: wpa_global structure
1004 * Sends ProertyChanged signals informing that debug show_keys has changed.
1006 static void wpas_dbus_signal_debug_show_keys_changed(struct wpa_global
*global
)
1008 wpa_dbus_signal_property_changed(global
->dbus
,
1009 (WPADBusPropertyAccessor
)
1010 wpas_dbus_getter_debug_show_keys
,
1011 global
, WPAS_DBUS_NEW_PATH
,
1012 WPAS_DBUS_NEW_INTERFACE
,
1017 struct wpas_dbus_method
{
1020 WPADBusMethodHandler handler
;
1021 struct wpa_dbus_argument args
[3];
1024 struct wpas_dbus_property
{
1028 WPADBusPropertyAccessor getter
;
1029 WPADBusPropertyAccessor setter
;
1030 enum dbus_prop_access _access
;
1033 struct wpas_dbus_signal
{
1036 struct wpa_dbus_argument args
[3];
1040 static void wpas_dbus_register(struct wpa_dbus_object_desc
*obj_desc
,
1042 WPADBusArgumentFreeFunction priv_free
,
1043 const struct wpas_dbus_method
*methods
,
1044 const struct wpas_dbus_property
*properties
,
1045 const struct wpas_dbus_signal
*signals
)
1049 obj_desc
->user_data
= priv
;
1050 obj_desc
->user_data_free_func
= priv_free
;
1052 for (i
= 0; methods
&& methods
[i
].name
; i
++) {
1053 wpa_dbus_method_register(obj_desc
, methods
[i
].iface
,
1054 methods
[i
].name
, methods
[i
].handler
,
1058 for (i
= 0; properties
&& properties
[i
].name
; i
++) {
1059 wpa_dbus_property_register(obj_desc
, properties
[i
].iface
,
1062 properties
[i
].getter
,
1063 properties
[i
].setter
,
1064 properties
[i
]._access
);
1067 for (i
= 0; signals
&& signals
[i
].name
; i
++) {
1068 wpa_dbus_signal_register(obj_desc
, signals
[i
].iface
,
1069 signals
[i
].name
, signals
[i
].args
);
1074 static const struct wpas_dbus_method wpas_dbus_global_methods
[] = {
1075 { "CreateInterface", WPAS_DBUS_NEW_INTERFACE
,
1076 (WPADBusMethodHandler
) &wpas_dbus_handler_create_interface
,
1078 { "args", "a{sv}", ARG_IN
},
1079 { "path", "o", ARG_OUT
},
1083 { "RemoveInterface", WPAS_DBUS_NEW_INTERFACE
,
1084 (WPADBusMethodHandler
) &wpas_dbus_handler_remove_interface
,
1086 { "path", "o", ARG_IN
},
1090 { "GetInterface", WPAS_DBUS_NEW_INTERFACE
,
1091 (WPADBusMethodHandler
) &wpas_dbus_handler_get_interface
,
1093 { "ifname", "s", ARG_IN
},
1094 { "path", "o", ARG_OUT
},
1098 { NULL
, NULL
, NULL
, { END_ARGS
} }
1101 static const struct wpas_dbus_property wpas_dbus_global_properties
[] = {
1102 { "DebugLevel", WPAS_DBUS_NEW_INTERFACE
, "y",
1103 (WPADBusPropertyAccessor
) wpas_dbus_getter_debug_level
,
1104 (WPADBusPropertyAccessor
) wpas_dbus_setter_debug_level
,
1107 { "DebugTimestamp", WPAS_DBUS_NEW_INTERFACE
, "b",
1108 (WPADBusPropertyAccessor
) wpas_dbus_getter_debug_timestamp
,
1109 (WPADBusPropertyAccessor
) wpas_dbus_setter_debug_timestamp
,
1112 { "DebugShowKeys", WPAS_DBUS_NEW_INTERFACE
, "b",
1113 (WPADBusPropertyAccessor
) wpas_dbus_getter_debug_show_keys
,
1114 (WPADBusPropertyAccessor
) wpas_dbus_setter_debug_show_keys
,
1117 { "Interfaces", WPAS_DBUS_NEW_INTERFACE
, "ao",
1118 (WPADBusPropertyAccessor
) &wpas_dbus_getter_interfaces
,
1122 { "EapMethods", WPAS_DBUS_NEW_INTERFACE
, "as",
1123 (WPADBusPropertyAccessor
) wpas_dbus_getter_eap_methods
,
1127 { NULL
, NULL
, NULL
, NULL
, NULL
, 0 }
1130 static const struct wpas_dbus_signal wpas_dbus_global_signals
[] = {
1131 { "InterfaceAdded", WPAS_DBUS_NEW_INTERFACE
,
1133 { "path", "o", ARG_OUT
},
1134 { "properties", "a{sv}", ARG_OUT
},
1138 { "InterfaceRemoved", WPAS_DBUS_NEW_INTERFACE
,
1140 { "path", "o", ARG_OUT
},
1144 { "PropertiesChanged", WPAS_DBUS_NEW_INTERFACE
,
1146 { "properties", "a{sv}", ARG_OUT
},
1150 { NULL
, NULL
, { END_ARGS
} }
1155 * wpas_dbus_ctrl_iface_init - Initialize dbus control interface
1156 * @global: Pointer to global data from wpa_supplicant_init()
1157 * Returns: 0 on success or -1 on failure
1159 * Initialize the dbus control interface for wpa_supplicantand and start
1160 * receiving commands from external programs over the bus.
1162 int wpas_dbus_ctrl_iface_init(struct wpas_dbus_priv
*priv
)
1164 struct wpa_dbus_object_desc
*obj_desc
;
1167 obj_desc
= os_zalloc(sizeof(struct wpa_dbus_object_desc
));
1169 wpa_printf(MSG_ERROR
, "Not enough memory "
1170 "to create object description");
1174 wpas_dbus_register(obj_desc
, priv
->global
, NULL
,
1175 wpas_dbus_global_methods
,
1176 wpas_dbus_global_properties
,
1177 wpas_dbus_global_signals
);
1179 wpa_printf(MSG_DEBUG
, "dbus: Register D-Bus object '%s'",
1180 WPAS_DBUS_NEW_PATH
);
1181 ret
= wpa_dbus_ctrl_iface_init(priv
, WPAS_DBUS_NEW_PATH
,
1182 WPAS_DBUS_NEW_SERVICE
,
1185 free_dbus_object_desc(obj_desc
);
1187 priv
->dbus_new_initialized
= 1;
1194 * wpas_dbus_ctrl_iface_deinit - Deinitialize dbus ctrl interface for
1196 * @iface: Pointer to dbus private data from wpas_dbus_init()
1198 * Deinitialize the dbus control interface that was initialized with
1199 * wpas_dbus_ctrl_iface_init().
1201 void wpas_dbus_ctrl_iface_deinit(struct wpas_dbus_priv
*iface
)
1203 if (!iface
->dbus_new_initialized
)
1205 wpa_printf(MSG_DEBUG
, "dbus: Unregister D-Bus object '%s'",
1206 WPAS_DBUS_NEW_PATH
);
1207 dbus_connection_unregister_object_path(iface
->con
,
1208 WPAS_DBUS_NEW_PATH
);
1212 static void wpa_dbus_free(void *ptr
)
1218 static const struct wpas_dbus_property wpas_dbus_network_properties
[] = {
1219 { "Properties", WPAS_DBUS_NEW_IFACE_NETWORK
, "a{sv}",
1220 (WPADBusPropertyAccessor
) wpas_dbus_getter_network_properties
,
1221 (WPADBusPropertyAccessor
) wpas_dbus_setter_network_properties
,
1224 { "Enabled", WPAS_DBUS_NEW_IFACE_NETWORK
, "b",
1225 (WPADBusPropertyAccessor
) wpas_dbus_getter_enabled
,
1226 (WPADBusPropertyAccessor
) wpas_dbus_setter_enabled
,
1229 { NULL
, NULL
, NULL
, NULL
, NULL
, 0 }
1233 static const struct wpas_dbus_signal wpas_dbus_network_signals
[] = {
1234 { "PropertiesChanged", WPAS_DBUS_NEW_IFACE_NETWORK
,
1236 { "properties", "a{sv}", ARG_OUT
},
1240 { NULL
, NULL
, { END_ARGS
} }
1245 * wpas_dbus_register_network - Register a configured network with dbus
1246 * @wpa_s: wpa_supplicant interface structure
1247 * @ssid: network configuration data
1248 * Returns: 0 on success, -1 on failure
1250 * Registers network representing object with dbus
1252 static int wpas_dbus_register_network(struct wpa_supplicant
*wpa_s
,
1253 struct wpa_ssid
*ssid
)
1255 struct wpas_dbus_priv
*ctrl_iface
;
1256 struct wpa_dbus_object_desc
*obj_desc
;
1258 struct network_handler_args
*arg
= NULL
;
1262 /* Do nothing if the control interface is not turned on */
1263 if (wpa_s
== NULL
|| wpa_s
->global
== NULL
)
1265 ctrl_iface
= wpa_s
->global
->dbus
;
1266 if (ctrl_iface
== NULL
)
1269 net_obj_path
= os_zalloc(WPAS_DBUS_OBJECT_PATH_MAX
);
1270 if (net_obj_path
== NULL
)
1272 os_snprintf(net_obj_path
, WPAS_DBUS_OBJECT_PATH_MAX
,
1273 "%s/" WPAS_DBUS_NEW_NETWORKS_PART
"/%u",
1274 wpas_dbus_get_path(wpa_s
), ssid
->id
);
1276 wpa_printf(MSG_DEBUG
, "dbus: Register network object '%s'",
1278 obj_desc
= os_zalloc(sizeof(struct wpa_dbus_object_desc
));
1280 wpa_printf(MSG_ERROR
, "Not enough memory "
1281 "to create object description");
1285 /* allocate memory for handlers arguments */
1286 arg
= os_zalloc(sizeof(struct network_handler_args
));
1288 wpa_printf(MSG_ERROR
, "Not enough memory "
1289 "to create arguments for method");
1296 wpas_dbus_register(obj_desc
, arg
, wpa_dbus_free
, NULL
,
1297 wpas_dbus_network_properties
,
1298 wpas_dbus_network_signals
);
1300 if (wpa_dbus_register_object_per_iface(ctrl_iface
, net_obj_path
,
1301 wpa_s
->ifname
, obj_desc
))
1304 wpas_dbus_signal_network_added(wpa_s
, ssid
->id
);
1306 os_free(net_obj_path
);
1310 os_free(net_obj_path
);
1318 * wpas_dbus_unregister_network - Unregister a configured network from dbus
1319 * @wpa_s: wpa_supplicant interface structure
1321 * Returns: 0 on success, -1 on failure
1323 * Unregisters network representing object from dbus
1325 static int wpas_dbus_unregister_network(struct wpa_supplicant
*wpa_s
, int nid
)
1327 struct wpas_dbus_priv
*ctrl_iface
;
1331 /* Do nothing if the control interface is not turned on */
1332 if (wpa_s
== NULL
|| wpa_s
->global
== NULL
)
1334 ctrl_iface
= wpa_s
->global
->dbus
;
1335 if (ctrl_iface
== NULL
)
1338 net_obj_path
= os_zalloc(WPAS_DBUS_OBJECT_PATH_MAX
);
1339 if (net_obj_path
== NULL
)
1341 os_snprintf(net_obj_path
, WPAS_DBUS_OBJECT_PATH_MAX
,
1342 "%s/" WPAS_DBUS_NEW_NETWORKS_PART
"/%u",
1343 wpas_dbus_get_path(wpa_s
), nid
);
1345 wpa_printf(MSG_DEBUG
, "dbus: Unregister network object '%s'",
1347 ret
= wpa_dbus_unregister_object_per_iface(ctrl_iface
, net_obj_path
);
1350 wpas_dbus_signal_network_removed(wpa_s
, nid
);
1352 os_free(net_obj_path
);
1357 static const struct wpas_dbus_property wpas_dbus_bss_properties
[] = {
1358 { "SSID", WPAS_DBUS_NEW_IFACE_BSSID
, "ay",
1359 (WPADBusPropertyAccessor
) wpas_dbus_getter_bss_ssid
,
1363 { "BSSID", WPAS_DBUS_NEW_IFACE_BSSID
, "ay",
1364 (WPADBusPropertyAccessor
) wpas_dbus_getter_bss_bssid
,
1368 { "Privacy", WPAS_DBUS_NEW_IFACE_BSSID
, "b",
1369 (WPADBusPropertyAccessor
) wpas_dbus_getter_bss_privacy
,
1373 { "Mode", WPAS_DBUS_NEW_IFACE_BSSID
, "s",
1374 (WPADBusPropertyAccessor
) wpas_dbus_getter_bss_mode
,
1378 { "Signal", WPAS_DBUS_NEW_IFACE_BSSID
, "n",
1379 (WPADBusPropertyAccessor
) wpas_dbus_getter_bss_signal
,
1383 { "Frequency", WPAS_DBUS_NEW_IFACE_BSSID
, "q",
1384 (WPADBusPropertyAccessor
) wpas_dbus_getter_bss_frequency
,
1388 { "MaxRate", WPAS_DBUS_NEW_IFACE_BSSID
, "q",
1389 (WPADBusPropertyAccessor
) wpas_dbus_getter_bss_max_rate
,
1393 { "WPAIE", WPAS_DBUS_NEW_IFACE_BSSID
, "ay",
1394 (WPADBusPropertyAccessor
) wpas_dbus_getter_bss_wpaie
,
1398 { "RSNIE", WPAS_DBUS_NEW_IFACE_BSSID
, "ay",
1399 (WPADBusPropertyAccessor
) wpas_dbus_getter_bss_rsnie
,
1403 { "WPSIE", WPAS_DBUS_NEW_IFACE_BSSID
, "ay",
1404 (WPADBusPropertyAccessor
) wpas_dbus_getter_bss_wpsie
,
1408 { NULL
, NULL
, NULL
, NULL
, NULL
, 0 }
1412 static const struct wpas_dbus_signal wpas_dbus_bss_signals
[] = {
1413 { "PropertiesChanged", WPAS_DBUS_NEW_IFACE_BSSID
,
1415 { "properties", "a{sv}", ARG_OUT
},
1419 { NULL
, NULL
, { END_ARGS
} }
1424 * wpas_dbus_unregister_bss - Unregister a scanned BSS from dbus
1425 * @wpa_s: wpa_supplicant interface structure
1426 * @bssid: scanned network bssid
1427 * @id: unique BSS identifier
1428 * Returns: 0 on success, -1 on failure
1430 * Unregisters BSS representing object from dbus
1432 static int wpas_dbus_unregister_bss(struct wpa_supplicant
*wpa_s
,
1433 u8 bssid
[ETH_ALEN
], unsigned int id
)
1435 struct wpas_dbus_priv
*ctrl_iface
;
1438 /* Do nothing if the control interface is not turned on */
1439 if (wpa_s
== NULL
|| wpa_s
->global
== NULL
)
1441 ctrl_iface
= wpa_s
->global
->dbus
;
1442 if (ctrl_iface
== NULL
)
1445 bss_obj_path
= os_zalloc(WPAS_DBUS_OBJECT_PATH_MAX
);
1446 if (bss_obj_path
== NULL
)
1449 os_snprintf(bss_obj_path
, WPAS_DBUS_OBJECT_PATH_MAX
,
1450 "%s/" WPAS_DBUS_NEW_BSSIDS_PART
"/%u",
1451 wpas_dbus_get_path(wpa_s
), id
);
1453 wpa_printf(MSG_DEBUG
, "dbus: Unregister BSS object '%s'",
1455 if (wpa_dbus_unregister_object_per_iface(ctrl_iface
, bss_obj_path
)) {
1456 wpa_printf(MSG_ERROR
,
1457 "Cannot unregister BSSID dbus object %s.",
1459 os_free(bss_obj_path
);
1463 wpas_dbus_signal_bss_removed(wpa_s
, bss_obj_path
);
1465 os_free(bss_obj_path
);
1471 * wpas_dbus_register_bss - Register a scanned BSS with dbus
1472 * @wpa_s: wpa_supplicant interface structure
1473 * @bssid: scanned network bssid
1474 * @id: unique BSS identifier
1475 * Returns: 0 on success, -1 on failure
1477 * Registers BSS representing object with dbus
1479 static int wpas_dbus_register_bss(struct wpa_supplicant
*wpa_s
,
1480 u8 bssid
[ETH_ALEN
], unsigned int id
)
1482 struct wpas_dbus_priv
*ctrl_iface
;
1483 struct wpa_dbus_object_desc
*obj_desc
;
1486 struct bss_handler_args
*arg
= NULL
;
1488 /* Do nothing if the control interface is not turned on */
1489 if (wpa_s
== NULL
|| wpa_s
->global
== NULL
)
1491 ctrl_iface
= wpa_s
->global
->dbus
;
1492 if (ctrl_iface
== NULL
)
1495 bss_obj_path
= os_zalloc(WPAS_DBUS_OBJECT_PATH_MAX
);
1496 if (bss_obj_path
== NULL
)
1499 os_snprintf(bss_obj_path
, WPAS_DBUS_OBJECT_PATH_MAX
,
1500 "%s/" WPAS_DBUS_NEW_BSSIDS_PART
"/%u",
1501 wpas_dbus_get_path(wpa_s
), id
);
1503 obj_desc
= os_zalloc(sizeof(struct wpa_dbus_object_desc
));
1505 wpa_printf(MSG_ERROR
, "Not enough memory "
1506 "to create object description");
1510 arg
= os_zalloc(sizeof(struct bss_handler_args
));
1512 wpa_printf(MSG_ERROR
, "Not enough memory "
1513 "to create arguments for handler");
1519 wpas_dbus_register(obj_desc
, arg
, wpa_dbus_free
, NULL
,
1520 wpas_dbus_bss_properties
,
1521 wpas_dbus_bss_signals
);
1523 wpa_printf(MSG_DEBUG
, "dbus: Register BSS object '%s'",
1525 if (wpa_dbus_register_object_per_iface(ctrl_iface
, bss_obj_path
,
1526 wpa_s
->ifname
, obj_desc
)) {
1527 wpa_printf(MSG_ERROR
,
1528 "Cannot register BSSID dbus object %s.",
1533 wpas_dbus_signal_bss_added(wpa_s
, bss_obj_path
);
1535 os_free(bss_obj_path
);
1539 os_free(bss_obj_path
);
1546 static const struct wpas_dbus_method wpas_dbus_interface_methods
[] = {
1547 { "Scan", WPAS_DBUS_NEW_IFACE_INTERFACE
,
1548 (WPADBusMethodHandler
) &wpas_dbus_handler_scan
,
1550 { "args", "a{sv}", ARG_IN
},
1554 { "Disconnect", WPAS_DBUS_NEW_IFACE_INTERFACE
,
1555 (WPADBusMethodHandler
) &wpas_dbus_handler_disconnect
,
1560 { "AddNetwork", WPAS_DBUS_NEW_IFACE_INTERFACE
,
1561 (WPADBusMethodHandler
) &wpas_dbus_handler_add_network
,
1563 { "args", "a{sv}", ARG_IN
},
1564 { "path", "o", ARG_OUT
},
1568 { "RemoveNetwork", WPAS_DBUS_NEW_IFACE_INTERFACE
,
1569 (WPADBusMethodHandler
) &wpas_dbus_handler_remove_network
,
1571 { "path", "o", ARG_IN
},
1575 { "SelectNetwork", WPAS_DBUS_NEW_IFACE_INTERFACE
,
1576 (WPADBusMethodHandler
) &wpas_dbus_handler_select_network
,
1578 { "path", "o", ARG_IN
},
1582 { "AddBlob", WPAS_DBUS_NEW_IFACE_INTERFACE
,
1583 (WPADBusMethodHandler
) &wpas_dbus_handler_add_blob
,
1585 { "name", "s", ARG_IN
},
1586 { "data", "ay", ARG_IN
},
1590 { "GetBlob", WPAS_DBUS_NEW_IFACE_INTERFACE
,
1591 (WPADBusMethodHandler
) &wpas_dbus_handler_get_blob
,
1593 { "name", "s", ARG_IN
},
1594 { "data", "ay", ARG_OUT
},
1598 { "RemoveBlob", WPAS_DBUS_NEW_IFACE_INTERFACE
,
1599 (WPADBusMethodHandler
) &wpas_dbus_handler_remove_blob
,
1601 { "name", "s", ARG_IN
},
1606 { "Start", WPAS_DBUS_NEW_IFACE_WPS
,
1607 (WPADBusMethodHandler
) &wpas_dbus_handler_wps_start
,
1609 { "args", "a{sv}", ARG_IN
},
1610 { "output", "a{sv}", ARG_OUT
},
1614 #endif /* CONFIG_WPS */
1615 { NULL
, NULL
, NULL
, { END_ARGS
} }
1618 static const struct wpas_dbus_property wpas_dbus_interface_properties
[] = {
1619 { "Capabilities", WPAS_DBUS_NEW_IFACE_INTERFACE
, "a{sv}",
1620 (WPADBusPropertyAccessor
) wpas_dbus_getter_capabilities
,
1623 { "State", WPAS_DBUS_NEW_IFACE_INTERFACE
, "s",
1624 (WPADBusPropertyAccessor
) wpas_dbus_getter_state
,
1627 { "Scanning", WPAS_DBUS_NEW_IFACE_INTERFACE
, "b",
1628 (WPADBusPropertyAccessor
) wpas_dbus_getter_scanning
,
1631 { "ApScan", WPAS_DBUS_NEW_IFACE_INTERFACE
, "u",
1632 (WPADBusPropertyAccessor
) wpas_dbus_getter_ap_scan
,
1633 (WPADBusPropertyAccessor
) wpas_dbus_setter_ap_scan
,
1636 { "Ifname", WPAS_DBUS_NEW_IFACE_INTERFACE
, "s",
1637 (WPADBusPropertyAccessor
) wpas_dbus_getter_ifname
,
1640 { "Driver", WPAS_DBUS_NEW_IFACE_INTERFACE
, "s",
1641 (WPADBusPropertyAccessor
) wpas_dbus_getter_driver
,
1644 { "BridgeIfname", WPAS_DBUS_NEW_IFACE_INTERFACE
, "s",
1645 (WPADBusPropertyAccessor
) wpas_dbus_getter_bridge_ifname
,
1648 { "CurrentBSS", WPAS_DBUS_NEW_IFACE_INTERFACE
, "o",
1649 (WPADBusPropertyAccessor
) wpas_dbus_getter_current_bss
,
1652 { "CurrentNetwork", WPAS_DBUS_NEW_IFACE_INTERFACE
, "o",
1653 (WPADBusPropertyAccessor
) wpas_dbus_getter_current_network
,
1656 { "Blobs", WPAS_DBUS_NEW_IFACE_INTERFACE
, "a{say}",
1657 (WPADBusPropertyAccessor
) wpas_dbus_getter_blobs
,
1660 { "BSSs", WPAS_DBUS_NEW_IFACE_INTERFACE
, "ao",
1661 (WPADBusPropertyAccessor
) wpas_dbus_getter_bsss
,
1664 { "Networks", WPAS_DBUS_NEW_IFACE_INTERFACE
, "ao",
1665 (WPADBusPropertyAccessor
) wpas_dbus_getter_networks
,
1669 { "ProcessCredentials", WPAS_DBUS_NEW_IFACE_WPS
, "b",
1670 (WPADBusPropertyAccessor
) wpas_dbus_getter_process_credentials
,
1671 (WPADBusPropertyAccessor
) wpas_dbus_setter_process_credentials
,
1674 #endif /* CONFIG_WPS */
1675 { NULL
, NULL
, NULL
, NULL
, NULL
, 0 }
1678 static const struct wpas_dbus_signal wpas_dbus_interface_signals
[] = {
1679 { "ScanDone", WPAS_DBUS_NEW_IFACE_INTERFACE
,
1681 { "success", "b", ARG_OUT
},
1685 { "StateChanged", WPAS_DBUS_NEW_IFACE_INTERFACE
,
1687 { "newState", "s", ARG_OUT
},
1688 { "oldState", "s", ARG_OUT
},
1692 { "BSSAdded", WPAS_DBUS_NEW_IFACE_INTERFACE
,
1694 { "path", "o", ARG_OUT
},
1695 { "properties", "a{sv}", ARG_OUT
},
1699 { "BSSRemoved", WPAS_DBUS_NEW_IFACE_INTERFACE
,
1701 { "path", "o", ARG_OUT
},
1705 { "BlobAdded", WPAS_DBUS_NEW_IFACE_INTERFACE
,
1707 { "name", "s", ARG_OUT
},
1711 { "BlobRemoved", WPAS_DBUS_NEW_IFACE_INTERFACE
,
1713 { "name", "s", ARG_OUT
},
1717 { "NetworkAdded", WPAS_DBUS_NEW_IFACE_INTERFACE
,
1719 { "path", "o", ARG_OUT
},
1720 { "properties", "a{sv}", ARG_OUT
},
1724 { "NetworkRemoved", WPAS_DBUS_NEW_IFACE_INTERFACE
,
1726 { "path", "o", ARG_OUT
},
1730 { "NetworkSelected", WPAS_DBUS_NEW_IFACE_INTERFACE
,
1732 { "path", "o", ARG_OUT
},
1736 { "PropertiesChanged", WPAS_DBUS_NEW_IFACE_INTERFACE
,
1738 { "properties", "a{sv}", ARG_OUT
},
1743 { "Event", WPAS_DBUS_NEW_IFACE_WPS
,
1745 { "name", "s", ARG_OUT
},
1746 { "args", "a{sv}", ARG_OUT
},
1750 { "Credentials", WPAS_DBUS_NEW_IFACE_WPS
,
1752 { "credentials", "a{sv}", ARG_OUT
},
1756 { "PropertiesChanged", WPAS_DBUS_NEW_IFACE_WPS
,
1758 { "properties", "a{sv}", ARG_OUT
},
1762 #endif /* CONFIG_WPS */
1763 { NULL
, NULL
, { END_ARGS
} }
1767 static int wpas_dbus_register_interface(struct wpa_supplicant
*wpa_s
)
1770 struct wpa_dbus_object_desc
*obj_desc
= NULL
;
1772 struct wpas_dbus_priv
*ctrl_iface
= wpa_s
->global
->dbus
;
1775 /* Do nothing if the control interface is not turned on */
1776 if (ctrl_iface
== NULL
)
1779 /* Create and set the interface's object path */
1780 path
= os_zalloc(WPAS_DBUS_OBJECT_PATH_MAX
);
1783 next
= ctrl_iface
->next_objid
++;
1784 os_snprintf(path
, WPAS_DBUS_OBJECT_PATH_MAX
,
1785 WPAS_DBUS_NEW_PATH_INTERFACES
"/%u",
1787 if (wpas_dbus_set_path(wpa_s
, path
)) {
1788 wpa_printf(MSG_DEBUG
,
1789 "Failed to set dbus path for interface %s",
1794 obj_desc
= os_zalloc(sizeof(struct wpa_dbus_object_desc
));
1796 wpa_printf(MSG_ERROR
, "Not enough memory "
1797 "to create object description");
1801 wpas_dbus_register(obj_desc
, wpa_s
, NULL
, wpas_dbus_interface_methods
,
1802 wpas_dbus_interface_properties
,
1803 wpas_dbus_interface_signals
);
1805 wpa_printf(MSG_DEBUG
, "dbus: Register interface object '%s'", path
);
1806 if (wpa_dbus_register_object_per_iface(ctrl_iface
, path
, wpa_s
->ifname
,
1810 wpas_dbus_signal_interface_added(wpa_s
);
1822 static int wpas_dbus_unregister_interface(struct wpa_supplicant
*wpa_s
)
1824 struct wpas_dbus_priv
*ctrl_iface
;
1826 /* Do nothing if the control interface is not turned on */
1827 if (wpa_s
== NULL
|| wpa_s
->global
== NULL
)
1829 ctrl_iface
= wpa_s
->global
->dbus
;
1830 if (ctrl_iface
== NULL
)
1833 wpa_printf(MSG_DEBUG
, "dbus: Unregister interface object '%s'",
1834 wpas_dbus_get_path(wpa_s
));
1835 if (wpa_dbus_unregister_object_per_iface(ctrl_iface
,
1836 wpas_dbus_get_path(wpa_s
)))
1839 wpas_dbus_signal_interface_removed(wpa_s
);
1841 os_free(wpa_s
->dbus_new_path
);
1842 wpa_s
->dbus_new_path
= NULL
;
1848 static struct wpas_dbus_callbacks callbacks
=
1850 .signal_interface_added
= wpas_dbus_signal_interface_added
,
1851 .signal_interface_removed
= wpas_dbus_signal_interface_removed
,
1853 .register_interface
= wpas_dbus_register_interface
,
1854 .unregister_interface
= wpas_dbus_unregister_interface
,
1856 .signal_scan_done
= wpas_dbus_signal_scan_done
,
1858 .signal_blob_added
= wpas_dbus_signal_blob_added
,
1859 .signal_blob_removed
= wpas_dbus_signal_blob_removed
,
1861 .signal_network_selected
= wpas_dbus_signal_network_selected
,
1863 .signal_state_changed
= wpas_dbus_signal_state_changed
,
1864 .register_network
= wpas_dbus_register_network
,
1865 .unregister_network
= wpas_dbus_unregister_network
,
1867 .signal_network_enabled_changed
=
1868 wpas_dbus_signal_network_enabled_changed
,
1870 .register_bss
= wpas_dbus_register_bss
,
1871 .unregister_bss
= wpas_dbus_unregister_bss
,
1873 .signal_prop_changed
= wpas_dbus_signal_prop_changed
,
1875 .signal_debug_level_changed
= wpas_dbus_signal_debug_level_changed
,
1876 .signal_debug_timestamp_changed
=
1877 wpas_dbus_signal_debug_timestamp_changed
,
1878 .signal_debug_show_keys_changed
=
1879 wpas_dbus_signal_debug_show_keys_changed
,
1882 .signal_wps_event_success
= wpas_dbus_signal_wps_event_success
,
1883 .signal_wps_event_fail
= wpas_dbus_signal_wps_event_fail
,
1884 .signal_wps_event_m2d
= wpas_dbus_signal_wps_event_m2d
,
1885 .signal_wps_credentials
= wpas_dbus_signal_wps_cred
,
1886 #endif /* CONFIG_WPS */
1890 struct wpas_dbus_callbacks
* wpas_dbus_get_callbacks(void)
1897 * wpas_dbus_get_path - Get an interface's dbus path
1898 * @wpa_s: %wpa_supplicant interface structure
1899 * Returns: Interface's dbus object path, or %NULL on error
1901 const char * wpas_dbus_get_path(struct wpa_supplicant
*wpa_s
)
1903 return wpa_s
->dbus_new_path
;