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_params_changed - Signals change of debug params
968 * @global: wpa_global structure
970 * Sends ProertyChanged signals informing that debug params has changed.
972 static void wpas_dbus_signal_debug_params_changed(struct wpa_global
*global
)
975 wpa_dbus_signal_property_changed(global
->dbus
,
976 (WPADBusPropertyAccessor
)
977 wpas_dbus_getter_debug_params
,
978 global
, WPAS_DBUS_NEW_PATH
,
979 WPAS_DBUS_NEW_INTERFACE
,
984 struct wpas_dbus_method
{
987 WPADBusMethodHandler handler
;
988 struct wpa_dbus_argument args
[3];
991 struct wpas_dbus_property
{
995 WPADBusPropertyAccessor getter
;
996 WPADBusPropertyAccessor setter
;
997 enum dbus_prop_access _access
;
1000 struct wpas_dbus_signal
{
1003 struct wpa_dbus_argument args
[3];
1007 static void wpas_dbus_register(struct wpa_dbus_object_desc
*obj_desc
,
1009 WPADBusArgumentFreeFunction priv_free
,
1010 const struct wpas_dbus_method
*methods
,
1011 const struct wpas_dbus_property
*properties
,
1012 const struct wpas_dbus_signal
*signals
)
1016 obj_desc
->user_data
= priv
;
1017 obj_desc
->user_data_free_func
= priv_free
;
1019 for (i
= 0; methods
&& methods
[i
].name
; i
++) {
1020 wpa_dbus_method_register(obj_desc
, methods
[i
].iface
,
1021 methods
[i
].name
, methods
[i
].handler
,
1025 for (i
= 0; properties
&& properties
[i
].name
; i
++) {
1026 wpa_dbus_property_register(obj_desc
, properties
[i
].iface
,
1029 properties
[i
].getter
,
1030 properties
[i
].setter
,
1031 properties
[i
]._access
);
1034 for (i
= 0; signals
&& signals
[i
].name
; i
++) {
1035 wpa_dbus_signal_register(obj_desc
, signals
[i
].iface
,
1036 signals
[i
].name
, signals
[i
].args
);
1041 static const struct wpas_dbus_method wpas_dbus_global_methods
[] = {
1042 { "CreateInterface", WPAS_DBUS_NEW_INTERFACE
,
1043 (WPADBusMethodHandler
) &wpas_dbus_handler_create_interface
,
1045 { "args", "a{sv}", ARG_IN
},
1046 { "path", "o", ARG_OUT
},
1050 { "RemoveInterface", WPAS_DBUS_NEW_INTERFACE
,
1051 (WPADBusMethodHandler
) &wpas_dbus_handler_remove_interface
,
1053 { "path", "o", ARG_IN
},
1057 { "GetInterface", WPAS_DBUS_NEW_INTERFACE
,
1058 (WPADBusMethodHandler
) &wpas_dbus_handler_get_interface
,
1060 { "ifname", "s", ARG_IN
},
1061 { "path", "o", ARG_OUT
},
1065 { NULL
, NULL
, NULL
, { END_ARGS
} }
1068 static const struct wpas_dbus_property wpas_dbus_global_properties
[] = {
1069 { "DebugParams", WPAS_DBUS_NEW_INTERFACE
, "(ibb)",
1070 (WPADBusPropertyAccessor
) &wpas_dbus_getter_debug_params
,
1071 (WPADBusPropertyAccessor
) &wpas_dbus_setter_debug_params
,
1074 { "Interfaces", WPAS_DBUS_NEW_INTERFACE
, "ao",
1075 (WPADBusPropertyAccessor
) &wpas_dbus_getter_interfaces
,
1079 { "EapMethods", WPAS_DBUS_NEW_INTERFACE
, "as",
1080 (WPADBusPropertyAccessor
) wpas_dbus_getter_eap_methods
,
1084 { NULL
, NULL
, NULL
, NULL
, NULL
, 0 }
1087 static const struct wpas_dbus_signal wpas_dbus_global_signals
[] = {
1088 { "InterfaceAdded", WPAS_DBUS_NEW_INTERFACE
,
1090 { "path", "o", ARG_OUT
},
1091 { "properties", "a{sv}", ARG_OUT
},
1095 { "InterfaceRemoved", WPAS_DBUS_NEW_INTERFACE
,
1097 { "path", "o", ARG_OUT
},
1101 { "PropertiesChanged", WPAS_DBUS_NEW_INTERFACE
,
1103 { "properties", "a{sv}", ARG_OUT
},
1107 { NULL
, NULL
, { END_ARGS
} }
1112 * wpas_dbus_ctrl_iface_init - Initialize dbus control interface
1113 * @global: Pointer to global data from wpa_supplicant_init()
1114 * Returns: 0 on success or -1 on failure
1116 * Initialize the dbus control interface for wpa_supplicantand and start
1117 * receiving commands from external programs over the bus.
1119 int wpas_dbus_ctrl_iface_init(struct wpas_dbus_priv
*priv
)
1121 struct wpa_dbus_object_desc
*obj_desc
;
1124 obj_desc
= os_zalloc(sizeof(struct wpa_dbus_object_desc
));
1126 wpa_printf(MSG_ERROR
, "Not enough memory "
1127 "to create object description");
1131 wpas_dbus_register(obj_desc
, priv
->global
, NULL
,
1132 wpas_dbus_global_methods
,
1133 wpas_dbus_global_properties
,
1134 wpas_dbus_global_signals
);
1136 wpa_printf(MSG_DEBUG
, "dbus: Register D-Bus object '%s'",
1137 WPAS_DBUS_NEW_PATH
);
1138 ret
= wpa_dbus_ctrl_iface_init(priv
, WPAS_DBUS_NEW_PATH
,
1139 WPAS_DBUS_NEW_SERVICE
,
1142 free_dbus_object_desc(obj_desc
);
1144 priv
->dbus_new_initialized
= 1;
1151 * wpas_dbus_ctrl_iface_deinit - Deinitialize dbus ctrl interface for
1153 * @iface: Pointer to dbus private data from wpas_dbus_init()
1155 * Deinitialize the dbus control interface that was initialized with
1156 * wpas_dbus_ctrl_iface_init().
1158 void wpas_dbus_ctrl_iface_deinit(struct wpas_dbus_priv
*iface
)
1160 if (!iface
->dbus_new_initialized
)
1162 wpa_printf(MSG_DEBUG
, "dbus: Unregister D-Bus object '%s'",
1163 WPAS_DBUS_NEW_PATH
);
1164 dbus_connection_unregister_object_path(iface
->con
,
1165 WPAS_DBUS_NEW_PATH
);
1169 static void wpa_dbus_free(void *ptr
)
1175 static const struct wpas_dbus_property wpas_dbus_network_properties
[] = {
1176 { "Properties", WPAS_DBUS_NEW_IFACE_NETWORK
, "a{sv}",
1177 (WPADBusPropertyAccessor
) wpas_dbus_getter_network_properties
,
1178 (WPADBusPropertyAccessor
) wpas_dbus_setter_network_properties
,
1181 { "Enabled", WPAS_DBUS_NEW_IFACE_NETWORK
, "b",
1182 (WPADBusPropertyAccessor
) wpas_dbus_getter_enabled
,
1183 (WPADBusPropertyAccessor
) wpas_dbus_setter_enabled
,
1186 { NULL
, NULL
, NULL
, NULL
, NULL
, 0 }
1190 static const struct wpas_dbus_signal wpas_dbus_network_signals
[] = {
1191 { "PropertiesChanged", WPAS_DBUS_NEW_IFACE_NETWORK
,
1193 { "properties", "a{sv}", ARG_OUT
},
1197 { NULL
, NULL
, { END_ARGS
} }
1202 * wpas_dbus_register_network - Register a configured network with dbus
1203 * @wpa_s: wpa_supplicant interface structure
1204 * @ssid: network configuration data
1205 * Returns: 0 on success, -1 on failure
1207 * Registers network representing object with dbus
1209 static int wpas_dbus_register_network(struct wpa_supplicant
*wpa_s
,
1210 struct wpa_ssid
*ssid
)
1212 struct wpas_dbus_priv
*ctrl_iface
;
1213 struct wpa_dbus_object_desc
*obj_desc
;
1215 struct network_handler_args
*arg
= NULL
;
1219 /* Do nothing if the control interface is not turned on */
1220 if (wpa_s
== NULL
|| wpa_s
->global
== NULL
)
1222 ctrl_iface
= wpa_s
->global
->dbus
;
1223 if (ctrl_iface
== NULL
)
1226 net_obj_path
= os_zalloc(WPAS_DBUS_OBJECT_PATH_MAX
);
1227 if (net_obj_path
== NULL
)
1229 os_snprintf(net_obj_path
, WPAS_DBUS_OBJECT_PATH_MAX
,
1230 "%s/" WPAS_DBUS_NEW_NETWORKS_PART
"/%u",
1231 wpas_dbus_get_path(wpa_s
), ssid
->id
);
1233 wpa_printf(MSG_DEBUG
, "dbus: Register network object '%s'",
1235 obj_desc
= os_zalloc(sizeof(struct wpa_dbus_object_desc
));
1237 wpa_printf(MSG_ERROR
, "Not enough memory "
1238 "to create object description");
1242 /* allocate memory for handlers arguments */
1243 arg
= os_zalloc(sizeof(struct network_handler_args
));
1245 wpa_printf(MSG_ERROR
, "Not enough memory "
1246 "to create arguments for method");
1253 wpas_dbus_register(obj_desc
, arg
, wpa_dbus_free
, NULL
,
1254 wpas_dbus_network_properties
,
1255 wpas_dbus_network_signals
);
1257 if (wpa_dbus_register_object_per_iface(ctrl_iface
, net_obj_path
,
1258 wpa_s
->ifname
, obj_desc
))
1261 wpas_dbus_signal_network_added(wpa_s
, ssid
->id
);
1263 os_free(net_obj_path
);
1267 os_free(net_obj_path
);
1275 * wpas_dbus_unregister_network - Unregister a configured network from dbus
1276 * @wpa_s: wpa_supplicant interface structure
1278 * Returns: 0 on success, -1 on failure
1280 * Unregisters network representing object from dbus
1282 static int wpas_dbus_unregister_network(struct wpa_supplicant
*wpa_s
, int nid
)
1284 struct wpas_dbus_priv
*ctrl_iface
;
1288 /* Do nothing if the control interface is not turned on */
1289 if (wpa_s
== NULL
|| wpa_s
->global
== NULL
)
1291 ctrl_iface
= wpa_s
->global
->dbus
;
1292 if (ctrl_iface
== NULL
)
1295 net_obj_path
= os_zalloc(WPAS_DBUS_OBJECT_PATH_MAX
);
1296 if (net_obj_path
== NULL
)
1298 os_snprintf(net_obj_path
, WPAS_DBUS_OBJECT_PATH_MAX
,
1299 "%s/" WPAS_DBUS_NEW_NETWORKS_PART
"/%u",
1300 wpas_dbus_get_path(wpa_s
), nid
);
1302 wpa_printf(MSG_DEBUG
, "dbus: Unregister network object '%s'",
1304 ret
= wpa_dbus_unregister_object_per_iface(ctrl_iface
, net_obj_path
);
1307 wpas_dbus_signal_network_removed(wpa_s
, nid
);
1309 os_free(net_obj_path
);
1314 static const struct wpas_dbus_property wpas_dbus_bss_properties
[] = {
1315 { "SSID", WPAS_DBUS_NEW_IFACE_BSSID
, "ay",
1316 (WPADBusPropertyAccessor
) wpas_dbus_getter_bss_ssid
,
1320 { "BSSID", WPAS_DBUS_NEW_IFACE_BSSID
, "ay",
1321 (WPADBusPropertyAccessor
) wpas_dbus_getter_bss_bssid
,
1325 { "Privacy", WPAS_DBUS_NEW_IFACE_BSSID
, "b",
1326 (WPADBusPropertyAccessor
) wpas_dbus_getter_bss_privacy
,
1330 { "Mode", WPAS_DBUS_NEW_IFACE_BSSID
, "s",
1331 (WPADBusPropertyAccessor
) wpas_dbus_getter_bss_mode
,
1335 { "Signal", WPAS_DBUS_NEW_IFACE_BSSID
, "n",
1336 (WPADBusPropertyAccessor
) wpas_dbus_getter_bss_signal
,
1340 { "Frequency", WPAS_DBUS_NEW_IFACE_BSSID
, "q",
1341 (WPADBusPropertyAccessor
) wpas_dbus_getter_bss_frequency
,
1345 { "MaxRate", WPAS_DBUS_NEW_IFACE_BSSID
, "q",
1346 (WPADBusPropertyAccessor
) wpas_dbus_getter_bss_max_rate
,
1350 { "WPAIE", WPAS_DBUS_NEW_IFACE_BSSID
, "ay",
1351 (WPADBusPropertyAccessor
) wpas_dbus_getter_bss_wpaie
,
1355 { "RSNIE", WPAS_DBUS_NEW_IFACE_BSSID
, "ay",
1356 (WPADBusPropertyAccessor
) wpas_dbus_getter_bss_rsnie
,
1360 { "WPSIE", WPAS_DBUS_NEW_IFACE_BSSID
, "ay",
1361 (WPADBusPropertyAccessor
) wpas_dbus_getter_bss_wpsie
,
1365 { NULL
, NULL
, NULL
, NULL
, NULL
, 0 }
1369 static const struct wpas_dbus_signal wpas_dbus_bss_signals
[] = {
1370 { "PropertiesChanged", WPAS_DBUS_NEW_IFACE_BSSID
,
1372 { "properties", "a{sv}", ARG_OUT
},
1376 { NULL
, NULL
, { END_ARGS
} }
1381 * wpas_dbus_unregister_bss - Unregister a scanned BSS from dbus
1382 * @wpa_s: wpa_supplicant interface structure
1383 * @bssid: scanned network bssid
1384 * @id: unique BSS identifier
1385 * Returns: 0 on success, -1 on failure
1387 * Unregisters BSS representing object from dbus
1389 static int wpas_dbus_unregister_bss(struct wpa_supplicant
*wpa_s
,
1390 u8 bssid
[ETH_ALEN
], unsigned int id
)
1392 struct wpas_dbus_priv
*ctrl_iface
;
1395 /* Do nothing if the control interface is not turned on */
1396 if (wpa_s
== NULL
|| wpa_s
->global
== NULL
)
1398 ctrl_iface
= wpa_s
->global
->dbus
;
1399 if (ctrl_iface
== NULL
)
1402 bss_obj_path
= os_zalloc(WPAS_DBUS_OBJECT_PATH_MAX
);
1403 if (bss_obj_path
== NULL
)
1406 os_snprintf(bss_obj_path
, WPAS_DBUS_OBJECT_PATH_MAX
,
1407 "%s/" WPAS_DBUS_NEW_BSSIDS_PART
"/%u",
1408 wpas_dbus_get_path(wpa_s
), id
);
1410 wpa_printf(MSG_DEBUG
, "dbus: Unregister BSS object '%s'",
1412 if (wpa_dbus_unregister_object_per_iface(ctrl_iface
, bss_obj_path
)) {
1413 wpa_printf(MSG_ERROR
,
1414 "Cannot unregister BSSID dbus object %s.",
1416 os_free(bss_obj_path
);
1420 wpas_dbus_signal_bss_removed(wpa_s
, bss_obj_path
);
1422 os_free(bss_obj_path
);
1428 * wpas_dbus_register_bss - Register a scanned BSS with dbus
1429 * @wpa_s: wpa_supplicant interface structure
1430 * @bssid: scanned network bssid
1431 * @id: unique BSS identifier
1432 * Returns: 0 on success, -1 on failure
1434 * Registers BSS representing object with dbus
1436 static int wpas_dbus_register_bss(struct wpa_supplicant
*wpa_s
,
1437 u8 bssid
[ETH_ALEN
], unsigned int id
)
1439 struct wpas_dbus_priv
*ctrl_iface
;
1440 struct wpa_dbus_object_desc
*obj_desc
;
1443 struct bss_handler_args
*arg
= NULL
;
1445 /* Do nothing if the control interface is not turned on */
1446 if (wpa_s
== NULL
|| wpa_s
->global
== NULL
)
1448 ctrl_iface
= wpa_s
->global
->dbus
;
1449 if (ctrl_iface
== NULL
)
1452 bss_obj_path
= os_zalloc(WPAS_DBUS_OBJECT_PATH_MAX
);
1453 if (bss_obj_path
== NULL
)
1456 os_snprintf(bss_obj_path
, WPAS_DBUS_OBJECT_PATH_MAX
,
1457 "%s/" WPAS_DBUS_NEW_BSSIDS_PART
"/%u",
1458 wpas_dbus_get_path(wpa_s
), id
);
1460 obj_desc
= os_zalloc(sizeof(struct wpa_dbus_object_desc
));
1462 wpa_printf(MSG_ERROR
, "Not enough memory "
1463 "to create object description");
1467 arg
= os_zalloc(sizeof(struct bss_handler_args
));
1469 wpa_printf(MSG_ERROR
, "Not enough memory "
1470 "to create arguments for handler");
1476 wpas_dbus_register(obj_desc
, arg
, wpa_dbus_free
, NULL
,
1477 wpas_dbus_bss_properties
,
1478 wpas_dbus_bss_signals
);
1480 wpa_printf(MSG_DEBUG
, "dbus: Register BSS object '%s'",
1482 if (wpa_dbus_register_object_per_iface(ctrl_iface
, bss_obj_path
,
1483 wpa_s
->ifname
, obj_desc
)) {
1484 wpa_printf(MSG_ERROR
,
1485 "Cannot register BSSID dbus object %s.",
1490 wpas_dbus_signal_bss_added(wpa_s
, bss_obj_path
);
1492 os_free(bss_obj_path
);
1496 os_free(bss_obj_path
);
1503 static const struct wpas_dbus_method wpas_dbus_interface_methods
[] = {
1504 { "Scan", WPAS_DBUS_NEW_IFACE_INTERFACE
,
1505 (WPADBusMethodHandler
) &wpas_dbus_handler_scan
,
1507 { "args", "a{sv}", ARG_IN
},
1511 { "Disconnect", WPAS_DBUS_NEW_IFACE_INTERFACE
,
1512 (WPADBusMethodHandler
) &wpas_dbus_handler_disconnect
,
1517 { "AddNetwork", WPAS_DBUS_NEW_IFACE_INTERFACE
,
1518 (WPADBusMethodHandler
) &wpas_dbus_handler_add_network
,
1520 { "args", "a{sv}", ARG_IN
},
1521 { "path", "o", ARG_OUT
},
1525 { "RemoveNetwork", WPAS_DBUS_NEW_IFACE_INTERFACE
,
1526 (WPADBusMethodHandler
) &wpas_dbus_handler_remove_network
,
1528 { "path", "o", ARG_IN
},
1532 { "SelectNetwork", WPAS_DBUS_NEW_IFACE_INTERFACE
,
1533 (WPADBusMethodHandler
) &wpas_dbus_handler_select_network
,
1535 { "path", "o", ARG_IN
},
1539 { "AddBlob", WPAS_DBUS_NEW_IFACE_INTERFACE
,
1540 (WPADBusMethodHandler
) &wpas_dbus_handler_add_blob
,
1542 { "name", "s", ARG_IN
},
1543 { "data", "ay", ARG_IN
},
1547 { "GetBlob", WPAS_DBUS_NEW_IFACE_INTERFACE
,
1548 (WPADBusMethodHandler
) &wpas_dbus_handler_get_blob
,
1550 { "name", "s", ARG_IN
},
1551 { "data", "ay", ARG_OUT
},
1555 { "RemoveBlob", WPAS_DBUS_NEW_IFACE_INTERFACE
,
1556 (WPADBusMethodHandler
) &wpas_dbus_handler_remove_blob
,
1558 { "name", "s", ARG_IN
},
1563 { "Start", WPAS_DBUS_NEW_IFACE_WPS
,
1564 (WPADBusMethodHandler
) &wpas_dbus_handler_wps_start
,
1566 { "args", "a{sv}", ARG_IN
},
1567 { "output", "a{sv}", ARG_OUT
},
1571 #endif /* CONFIG_WPS */
1572 { NULL
, NULL
, NULL
, { END_ARGS
} }
1575 static const struct wpas_dbus_property wpas_dbus_interface_properties
[] = {
1576 { "Capabilities", WPAS_DBUS_NEW_IFACE_INTERFACE
, "a{sv}",
1577 (WPADBusPropertyAccessor
) wpas_dbus_getter_capabilities
,
1580 { "State", WPAS_DBUS_NEW_IFACE_INTERFACE
, "s",
1581 (WPADBusPropertyAccessor
) wpas_dbus_getter_state
,
1584 { "Scanning", WPAS_DBUS_NEW_IFACE_INTERFACE
, "b",
1585 (WPADBusPropertyAccessor
) wpas_dbus_getter_scanning
,
1588 { "ApScan", WPAS_DBUS_NEW_IFACE_INTERFACE
, "u",
1589 (WPADBusPropertyAccessor
) wpas_dbus_getter_ap_scan
,
1590 (WPADBusPropertyAccessor
) wpas_dbus_setter_ap_scan
,
1593 { "Ifname", WPAS_DBUS_NEW_IFACE_INTERFACE
, "s",
1594 (WPADBusPropertyAccessor
) wpas_dbus_getter_ifname
,
1597 { "Driver", WPAS_DBUS_NEW_IFACE_INTERFACE
, "s",
1598 (WPADBusPropertyAccessor
) wpas_dbus_getter_driver
,
1601 { "BridgeIfname", WPAS_DBUS_NEW_IFACE_INTERFACE
, "s",
1602 (WPADBusPropertyAccessor
) wpas_dbus_getter_bridge_ifname
,
1605 { "CurrentBSS", WPAS_DBUS_NEW_IFACE_INTERFACE
, "o",
1606 (WPADBusPropertyAccessor
) wpas_dbus_getter_current_bss
,
1609 { "CurrentNetwork", WPAS_DBUS_NEW_IFACE_INTERFACE
, "o",
1610 (WPADBusPropertyAccessor
) wpas_dbus_getter_current_network
,
1613 { "Blobs", WPAS_DBUS_NEW_IFACE_INTERFACE
, "a{say}",
1614 (WPADBusPropertyAccessor
) wpas_dbus_getter_blobs
,
1617 { "BSSs", WPAS_DBUS_NEW_IFACE_INTERFACE
, "ao",
1618 (WPADBusPropertyAccessor
) wpas_dbus_getter_bsss
,
1621 { "Networks", WPAS_DBUS_NEW_IFACE_INTERFACE
, "ao",
1622 (WPADBusPropertyAccessor
) wpas_dbus_getter_networks
,
1626 { "ProcessCredentials", WPAS_DBUS_NEW_IFACE_WPS
, "b",
1627 (WPADBusPropertyAccessor
) wpas_dbus_getter_process_credentials
,
1628 (WPADBusPropertyAccessor
) wpas_dbus_setter_process_credentials
,
1631 #endif /* CONFIG_WPS */
1632 { NULL
, NULL
, NULL
, NULL
, NULL
, 0 }
1635 static const struct wpas_dbus_signal wpas_dbus_interface_signals
[] = {
1636 { "ScanDone", WPAS_DBUS_NEW_IFACE_INTERFACE
,
1638 { "success", "b", ARG_OUT
},
1642 { "StateChanged", WPAS_DBUS_NEW_IFACE_INTERFACE
,
1644 { "newState", "s", ARG_OUT
},
1645 { "oldState", "s", ARG_OUT
},
1649 { "BSSAdded", WPAS_DBUS_NEW_IFACE_INTERFACE
,
1651 { "path", "o", ARG_OUT
},
1652 { "properties", "a{sv}", ARG_OUT
},
1656 { "BSSRemoved", WPAS_DBUS_NEW_IFACE_INTERFACE
,
1658 { "path", "o", ARG_OUT
},
1662 { "BlobAdded", WPAS_DBUS_NEW_IFACE_INTERFACE
,
1664 { "name", "s", ARG_OUT
},
1668 { "BlobRemoved", WPAS_DBUS_NEW_IFACE_INTERFACE
,
1670 { "name", "s", ARG_OUT
},
1674 { "NetworkAdded", WPAS_DBUS_NEW_IFACE_INTERFACE
,
1676 { "path", "o", ARG_OUT
},
1677 { "properties", "a{sv}", ARG_OUT
},
1681 { "NetworkRemoved", WPAS_DBUS_NEW_IFACE_INTERFACE
,
1683 { "path", "o", ARG_OUT
},
1687 { "NetworkSelected", WPAS_DBUS_NEW_IFACE_INTERFACE
,
1689 { "path", "o", ARG_OUT
},
1693 { "PropertiesChanged", WPAS_DBUS_NEW_IFACE_INTERFACE
,
1695 { "properties", "a{sv}", ARG_OUT
},
1700 { "Event", WPAS_DBUS_NEW_IFACE_WPS
,
1702 { "name", "s", ARG_OUT
},
1703 { "args", "a{sv}", ARG_OUT
},
1707 { "Credentials", WPAS_DBUS_NEW_IFACE_WPS
,
1709 { "credentials", "a{sv}", ARG_OUT
},
1713 { "PropertiesChanged", WPAS_DBUS_NEW_IFACE_WPS
,
1715 { "properties", "a{sv}", ARG_OUT
},
1719 #endif /* CONFIG_WPS */
1720 { NULL
, NULL
, { END_ARGS
} }
1724 static int wpas_dbus_register_interface(struct wpa_supplicant
*wpa_s
)
1727 struct wpa_dbus_object_desc
*obj_desc
= NULL
;
1729 struct wpas_dbus_priv
*ctrl_iface
= wpa_s
->global
->dbus
;
1732 /* Do nothing if the control interface is not turned on */
1733 if (ctrl_iface
== NULL
)
1736 /* Create and set the interface's object path */
1737 path
= os_zalloc(WPAS_DBUS_OBJECT_PATH_MAX
);
1740 next
= ctrl_iface
->next_objid
++;
1741 os_snprintf(path
, WPAS_DBUS_OBJECT_PATH_MAX
,
1742 WPAS_DBUS_NEW_PATH_INTERFACES
"/%u",
1744 if (wpas_dbus_set_path(wpa_s
, path
)) {
1745 wpa_printf(MSG_DEBUG
,
1746 "Failed to set dbus path for interface %s",
1751 obj_desc
= os_zalloc(sizeof(struct wpa_dbus_object_desc
));
1753 wpa_printf(MSG_ERROR
, "Not enough memory "
1754 "to create object description");
1758 wpas_dbus_register(obj_desc
, wpa_s
, NULL
, wpas_dbus_interface_methods
,
1759 wpas_dbus_interface_properties
,
1760 wpas_dbus_interface_signals
);
1762 wpa_printf(MSG_DEBUG
, "dbus: Register interface object '%s'", path
);
1763 if (wpa_dbus_register_object_per_iface(ctrl_iface
, path
, wpa_s
->ifname
,
1767 wpas_dbus_signal_interface_added(wpa_s
);
1779 static int wpas_dbus_unregister_interface(struct wpa_supplicant
*wpa_s
)
1781 struct wpas_dbus_priv
*ctrl_iface
;
1783 /* Do nothing if the control interface is not turned on */
1784 if (wpa_s
== NULL
|| wpa_s
->global
== NULL
)
1786 ctrl_iface
= wpa_s
->global
->dbus
;
1787 if (ctrl_iface
== NULL
)
1790 wpa_printf(MSG_DEBUG
, "dbus: Unregister interface object '%s'",
1791 wpas_dbus_get_path(wpa_s
));
1792 if (wpa_dbus_unregister_object_per_iface(ctrl_iface
,
1793 wpas_dbus_get_path(wpa_s
)))
1796 wpas_dbus_signal_interface_removed(wpa_s
);
1798 os_free(wpa_s
->dbus_new_path
);
1799 wpa_s
->dbus_new_path
= NULL
;
1805 static struct wpas_dbus_callbacks callbacks
=
1807 .signal_interface_added
= wpas_dbus_signal_interface_added
,
1808 .signal_interface_removed
= wpas_dbus_signal_interface_removed
,
1810 .register_interface
= wpas_dbus_register_interface
,
1811 .unregister_interface
= wpas_dbus_unregister_interface
,
1813 .signal_scan_done
= wpas_dbus_signal_scan_done
,
1815 .signal_blob_added
= wpas_dbus_signal_blob_added
,
1816 .signal_blob_removed
= wpas_dbus_signal_blob_removed
,
1818 .signal_network_selected
= wpas_dbus_signal_network_selected
,
1820 .signal_state_changed
= wpas_dbus_signal_state_changed
,
1821 .register_network
= wpas_dbus_register_network
,
1822 .unregister_network
= wpas_dbus_unregister_network
,
1824 .signal_network_enabled_changed
=
1825 wpas_dbus_signal_network_enabled_changed
,
1827 .register_bss
= wpas_dbus_register_bss
,
1828 .unregister_bss
= wpas_dbus_unregister_bss
,
1830 .signal_prop_changed
= wpas_dbus_signal_prop_changed
,
1831 .signal_debug_params_changed
= wpas_dbus_signal_debug_params_changed
,
1834 .signal_wps_event_success
= wpas_dbus_signal_wps_event_success
,
1835 .signal_wps_event_fail
= wpas_dbus_signal_wps_event_fail
,
1836 .signal_wps_event_m2d
= wpas_dbus_signal_wps_event_m2d
,
1837 .signal_wps_credentials
= wpas_dbus_signal_wps_cred
,
1838 #endif /* CONFIG_WPS */
1842 struct wpas_dbus_callbacks
* wpas_dbus_get_callbacks(void)
1849 * wpas_dbus_get_path - Get an interface's dbus path
1850 * @wpa_s: %wpa_supplicant interface structure
1851 * Returns: Interface's dbus object path, or %NULL on error
1853 const char * wpas_dbus_get_path(struct wpa_supplicant
*wpa_s
)
1855 return wpa_s
->dbus_new_path
;