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>
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
10 * Alternatively, this software may be distributed under the terms of BSD
13 * See README and COPYING for more details.
19 #include "drivers/driver.h"
21 #include "../config.h"
22 #include "../wpa_supplicant_i.h"
23 #include "dbus_new_helpers.h"
24 #include "dbus_dict_helpers.h"
26 #include "dbus_new_handlers.h"
29 * wpas_dbus_set_path - Assign a dbus path to an interface
30 * @wpa_s: wpa_supplicant interface structure
31 * @path: dbus path to set on the interface
32 * Returns: 0 on success, -1 on error
34 static int wpas_dbus_set_path(struct wpa_supplicant
*wpa_s
,
37 u32 len
= os_strlen(path
);
38 if (len
>= WPAS_DBUS_OBJECT_PATH_MAX
)
40 if (wpa_s
->dbus_new_path
)
42 wpa_s
->dbus_new_path
= os_strdup(path
);
48 * wpas_dbus_signal_interface - Send a interface related event signal
49 * @wpa_s: %wpa_supplicant network interface data
50 * @sig_name: signal name - InterfaceAdded or InterfaceRemoved
52 * Notify listeners about event related with interface
54 static void wpas_dbus_signal_interface(struct wpa_supplicant
*wpa_s
,
57 struct ctrl_iface_dbus_new_priv
*iface
;
61 iface
= wpa_s
->global
->dbus_new_ctrl_iface
;
63 /* Do nothing if the control interface is not turned on */
67 path
= wpas_dbus_get_path(wpa_s
);
69 wpa_printf(MSG_ERROR
, "wpas_dbus_signal_interface[dbus]: "
70 "Interface doesn't have a dbus path. "
71 "Can't send signal.");
74 _signal
= dbus_message_new_signal(WPAS_DBUS_NEW_PATH
,
75 WPAS_DBUS_NEW_INTERFACE
, sig_name
);
76 if (_signal
== NULL
) {
77 wpa_printf(MSG_ERROR
, "wpas_dbus_signal_interface[dbus]: "
78 "enough memory to send scan results signal.");
82 if (dbus_message_append_args(_signal
, DBUS_TYPE_OBJECT_PATH
, &path
,
84 dbus_connection_send(iface
->con
, _signal
, NULL
);
86 wpa_printf(MSG_ERROR
, "wpas_dbus_signal_interface[dbus]: "
87 "not enough memory to construct signal.");
89 dbus_message_unref(_signal
);
94 * wpas_dbus_signal_interface_created - Send a interface created signal
95 * @wpa_s: %wpa_supplicant network interface data
97 * Notify listeners about creating new interface
99 static void wpas_dbus_signal_interface_created(struct wpa_supplicant
*wpa_s
)
101 wpas_dbus_signal_interface(wpa_s
, "InterfaceCreated");
106 * wpas_dbus_signal_interface_removed - Send a interface removed signal
107 * @wpa_s: %wpa_supplicant network interface data
109 * Notify listeners about removing interface
111 static void wpas_dbus_signal_interface_removed(struct wpa_supplicant
*wpa_s
)
113 wpas_dbus_signal_interface(wpa_s
, "InterfaceRemoved");
119 * wpas_dbus_signal_scan_done - send scan done signal
120 * @wpa_s: %wpa_supplicant network interface data
121 * @success: indicates if scanning succeed or failed
123 * Notify listeners about finishing a scan
125 static void wpas_dbus_signal_scan_done(struct wpa_supplicant
*wpa_s
,
128 struct ctrl_iface_dbus_new_priv
*iface
;
129 DBusMessage
*_signal
;
133 iface
= wpa_s
->global
->dbus_new_ctrl_iface
;
135 /* Do nothing if the control interface is not turned on */
139 path
= wpas_dbus_get_path(wpa_s
);
141 wpa_printf(MSG_ERROR
, "wpas_dbus_signal_scan_done[dbus]: "
142 "Interface doesn't have a dbus path. "
143 "Can't send signal.");
146 _signal
= dbus_message_new_signal(path
, WPAS_DBUS_NEW_IFACE_INTERFACE
,
148 if (_signal
== NULL
) {
149 wpa_printf(MSG_ERROR
, "wpas_dbus_signal_scan_done[dbus]: "
150 "enough memory to send signal.");
154 succ
= success
? TRUE
: FALSE
;
155 if (dbus_message_append_args(_signal
, DBUS_TYPE_BOOLEAN
, &succ
,
156 DBUS_TYPE_INVALID
)) {
157 dbus_connection_send(iface
->con
, _signal
, NULL
);
159 wpa_printf(MSG_ERROR
, "wpas_dbus_signal_scan_done[dbus]: "
160 "not enough memory to construct signal.");
162 dbus_message_unref(_signal
);
167 * wpas_dbus_signal_blob - Send a BSS related event signal
168 * @wpa_s: %wpa_supplicant network interface data
169 * @bss_obj_path: BSS object path
170 * @sig_name: signal name - BSSAdded or BSSRemoved
172 * Notify listeners about event related with BSS
174 static void wpas_dbus_signal_bss(struct wpa_supplicant
*wpa_s
,
175 const char *bss_obj_path
,
176 const char *sig_name
)
178 struct ctrl_iface_dbus_new_priv
*iface
;
179 DBusMessage
*_signal
;
182 iface
= wpa_s
->global
->dbus_new_ctrl_iface
;
184 /* Do nothing if the control interface is not turned on */
188 path
= wpas_dbus_get_path(wpa_s
);
190 wpa_printf(MSG_ERROR
, "wpas_dbus_signal_bss[dbus]: "
191 "Interface doesn't have a dbus path. "
192 "Can't send signal.");
195 _signal
= dbus_message_new_signal(path
, WPAS_DBUS_NEW_IFACE_INTERFACE
,
197 if (_signal
== NULL
) {
198 wpa_printf(MSG_ERROR
, "wpas_dbus_signal_bss[dbus]: "
199 "enough memory to send signal.");
203 if (dbus_message_append_args(_signal
, DBUS_TYPE_OBJECT_PATH
,
204 &bss_obj_path
, DBUS_TYPE_INVALID
)) {
205 dbus_connection_send(iface
->con
, _signal
, NULL
);
207 wpa_printf(MSG_ERROR
, "wpas_dbus_signal_bss[dbus]: "
208 "not enough memory to construct signal.");
210 dbus_message_unref(_signal
);
215 * wpas_dbus_signal_bss_added - Send a BSS added signal
216 * @wpa_s: %wpa_supplicant network interface data
217 * @bss_obj_path: new BSS object path
219 * Notify listeners about adding new BSS
221 static void wpas_dbus_signal_bss_added(struct wpa_supplicant
*wpa_s
,
222 const char *bss_obj_path
)
224 wpas_dbus_signal_bss(wpa_s
, bss_obj_path
, "BSSAdded");
229 * wpas_dbus_signal_bss_removed - Send a BSS removed signal
230 * @wpa_s: %wpa_supplicant network interface data
231 * @bss_obj_path: BSS object path
233 * Notify listeners about removing BSS
235 static void wpas_dbus_signal_bss_removed(struct wpa_supplicant
*wpa_s
,
236 const char *bss_obj_path
)
238 wpas_dbus_signal_bss(wpa_s
, bss_obj_path
, "BSSRemoved");
243 * wpas_dbus_signal_blob - Send a blob related event signal
244 * @wpa_s: %wpa_supplicant network interface data
246 * @sig_name: signal name - BlobAdded or BlobRemoved
248 * Notify listeners about event related with blob
250 static void wpas_dbus_signal_blob(struct wpa_supplicant
*wpa_s
,
251 const char *name
, const char *sig_name
)
253 struct ctrl_iface_dbus_new_priv
*iface
;
254 DBusMessage
*_signal
;
257 iface
= wpa_s
->global
->dbus_new_ctrl_iface
;
259 /* Do nothing if the control interface is not turned on */
263 path
= wpas_dbus_get_path(wpa_s
);
265 wpa_printf(MSG_ERROR
, "wpas_dbus_signal_blob[dbus]: "
266 "Interface doesn't have a dbus path. "
267 "Can't send signal.");
270 _signal
= dbus_message_new_signal(path
, WPAS_DBUS_NEW_IFACE_INTERFACE
,
272 if (_signal
== NULL
) {
273 wpa_printf(MSG_ERROR
, "wpas_dbus_signal_blob[dbus]: "
274 "enough memory to send signal.");
278 if (dbus_message_append_args(_signal
, DBUS_TYPE_STRING
, &name
,
279 DBUS_TYPE_INVALID
)) {
280 dbus_connection_send(iface
->con
, _signal
, NULL
);
282 wpa_printf(MSG_ERROR
, "wpas_dbus_signal_blob[dbus]: "
283 "not enough memory to construct signal.");
285 dbus_message_unref(_signal
);
290 * wpas_dbus_signal_blob_added - Send a blob added signal
291 * @wpa_s: %wpa_supplicant network interface data
294 * Notify listeners about adding a new blob
296 static void wpas_dbus_signal_blob_added(struct wpa_supplicant
*wpa_s
,
299 wpas_dbus_signal_blob(wpa_s
, name
, "BlobAdded");
304 * wpas_dbus_signal_blob_removed - Send a blob removed signal
305 * @wpa_s: %wpa_supplicant network interface data
308 * Notify listeners about removing blob
310 static void wpas_dbus_signal_blob_removed(struct wpa_supplicant
*wpa_s
,
313 wpas_dbus_signal_blob(wpa_s
, name
, "BlobRemoved");
318 * wpas_dbus_signal_network - Send a network related event signal
319 * @wpa_s: %wpa_supplicant network interface data
320 * @id: new network id
321 * @sig_name: signal name - NetworkAdded, NetworkRemoved or NetworkSelected
323 * Notify listeners about event related with configured network
325 static void wpas_dbus_signal_network(struct wpa_supplicant
*wpa_s
,
326 int id
, const char *sig_name
)
328 struct ctrl_iface_dbus_new_priv
*iface
;
329 DBusMessage
*_signal
;
333 iface
= wpa_s
->global
->dbus_new_ctrl_iface
;
335 /* Do nothing if the control interface is not turned on */
339 path
= wpas_dbus_get_path(wpa_s
);
341 wpa_printf(MSG_ERROR
, "wpas_dbus_signal_network[dbus]: "
342 "Interface doesn't have a dbus path. "
343 "Can't send signal.");
347 net_obj_path
= os_zalloc(WPAS_DBUS_OBJECT_PATH_MAX
);
348 if (net_obj_path
== NULL
)
350 os_snprintf(net_obj_path
, WPAS_DBUS_OBJECT_PATH_MAX
,
351 "%s/" WPAS_DBUS_NEW_NETWORKS_PART
"/%u", path
, id
);
353 _signal
= dbus_message_new_signal(path
, WPAS_DBUS_NEW_IFACE_INTERFACE
,
355 if (_signal
== NULL
) {
356 wpa_printf(MSG_ERROR
, "wpas_dbus_signal_network[dbus]: "
357 "enough memory to send signal.");
358 os_free(net_obj_path
);
362 if (dbus_message_append_args(_signal
, DBUS_TYPE_OBJECT_PATH
,
363 &net_obj_path
, DBUS_TYPE_INVALID
)) {
364 dbus_connection_send(iface
->con
, _signal
, NULL
);
366 wpa_printf(MSG_ERROR
, "wpas_dbus_signal_network[dbus]: "
367 "not enough memory to construct signal.");
370 os_free(net_obj_path
);
371 dbus_message_unref(_signal
);
376 * wpas_dbus_signal_network_added - Send a network added signal
377 * @wpa_s: %wpa_supplicant network interface data
378 * @id: new network id
380 * Notify listeners about adding new network
382 static void wpas_dbus_signal_network_added(struct wpa_supplicant
*wpa_s
,
385 wpas_dbus_signal_network(wpa_s
, id
, "NetworkAdded");
390 * wpas_dbus_signal_network_removed - Send a network removed signal
391 * @wpa_s: %wpa_supplicant network interface data
394 * Notify listeners about removing a network
396 static void wpas_dbus_signal_network_removed(struct wpa_supplicant
*wpa_s
,
399 wpas_dbus_signal_network(wpa_s
, id
, "NetworkRemoved");
404 * wpas_dbus_signal_network_selected - Send a network selected signal
405 * @wpa_s: %wpa_supplicant network interface data
408 * Notify listeners about selecting a network
410 static void wpas_dbus_signal_network_selected(struct wpa_supplicant
*wpa_s
,
413 wpas_dbus_signal_network(wpa_s
, id
, "NetworkSelected");
418 * wpas_dbus_signal_state_changed - Send a state changed signal
419 * @wpa_s: %wpa_supplicant network interface data
420 * @new_state: new state wpa_supplicant is entering
421 * @old_state: old state wpa_supplicant is leaving
423 * Notify listeners that wpa_supplicant has changed state
425 static void wpas_dbus_signal_state_changed(struct wpa_supplicant
*wpa_s
,
426 enum wpa_states new_state
,
427 enum wpa_states old_state
)
429 struct ctrl_iface_dbus_new_priv
*iface
;
430 DBusMessage
*_signal
= NULL
;
432 char *new_state_str
, *old_state_str
;
435 /* Do nothing if the control interface is not turned on */
436 if (wpa_s
->global
== NULL
)
438 iface
= wpa_s
->global
->dbus_new_ctrl_iface
;
442 /* Only send signal if state really changed */
443 if (new_state
== old_state
)
446 path
= wpas_dbus_get_path(wpa_s
);
448 perror("wpas_dbus_signal_state_changed[dbus]: "
449 "interface didn't have a dbus path");
450 wpa_printf(MSG_ERROR
,
451 "wpas_dbus_signal_state_changed[dbus]: "
452 "interface didn't have a dbus path; can't send "
456 _signal
= dbus_message_new_signal(path
, WPAS_DBUS_NEW_IFACE_INTERFACE
,
458 if (_signal
== NULL
) {
459 perror("wpas_dbus_signal_state_changed[dbus]: "
460 "couldn't create dbus signal; likely out of memory");
461 wpa_printf(MSG_ERROR
,
462 "wpas_dbus_signal_state_changed[dbus]: "
463 "couldn't create dbus signal; likely out of "
468 new_state_str
= os_strdup(wpa_supplicant_state_txt(new_state
));
469 old_state_str
= os_strdup(wpa_supplicant_state_txt(old_state
));
470 if (new_state_str
== NULL
|| old_state_str
== NULL
) {
471 perror("wpas_dbus_signal_state_changed[dbus]: "
472 "couldn't convert state strings");
473 wpa_printf(MSG_ERROR
,
474 "wpas_dbus_signal_state_changed[dbus]: "
475 "couldn't convert state strings.");
479 /* make state string lowercase to fit new DBus API convention */
482 *tmp
= tolower(*tmp
);
487 *tmp
= tolower(*tmp
);
491 if (!dbus_message_append_args(_signal
,
492 DBUS_TYPE_STRING
, &new_state_str
,
493 DBUS_TYPE_STRING
, &old_state_str
,
494 DBUS_TYPE_INVALID
)) {
495 perror("wpas_dbus_signal_state_changed[dbus]: "
496 "not enough memory to construct state change signal.");
497 wpa_printf(MSG_ERROR
,
498 "wpas_dbus_signal_state_changed[dbus]: "
499 "not enough memory to construct state change "
504 dbus_connection_send(iface
->con
, _signal
, NULL
);
507 dbus_message_unref(_signal
);
508 os_free(new_state_str
);
509 os_free(old_state_str
);
514 * wpas_dbus_signal_network_enabled_changed - Signals Enabled property changes
515 * @wpa_s: %wpa_supplicant network interface data
516 * @ssid: configured network which Enabled property has changed
518 * Sends PropertyChanged signals containing new value of Enabled property
519 * for specified network
521 static void wpas_dbus_signal_network_enabled_changed(
522 struct wpa_supplicant
*wpa_s
, struct wpa_ssid
*ssid
)
525 struct network_handler_args args
= {wpa_s
, ssid
};
527 char path
[WPAS_DBUS_OBJECT_PATH_MAX
];
528 os_snprintf(path
, WPAS_DBUS_OBJECT_PATH_MAX
,
529 "%s/" WPAS_DBUS_NEW_NETWORKS_PART
"/%d",
530 wpas_dbus_get_path(wpa_s
), ssid
->id
);
532 wpa_dbus_signal_property_changed(wpa_s
->global
->dbus_new_ctrl_iface
,
533 (WPADBusPropertyAccessor
)
534 wpas_dbus_getter_enabled
, &args
,
535 path
, WPAS_DBUS_NEW_IFACE_NETWORK
,
543 * wpas_dbus_signal_wps_event_success - Signals Success WPS event
544 * @wpa_s: %wpa_supplicant network interface data
546 * Sends Event dbus signal with name "success" and empty dict as arguments
548 static void wpas_dbus_signal_wps_event_success(struct wpa_supplicant
*wpa_s
)
551 DBusMessage
*_signal
= NULL
;
552 DBusMessageIter iter
, dict_iter
;
553 struct ctrl_iface_dbus_new_priv
*iface
;
554 char *key
= "success";
557 iface
= wpa_s
->global
->dbus_new_ctrl_iface
;
559 /* Do nothing if the control interface is not turned on */
563 path
= wpas_dbus_get_path(wpa_s
);
565 wpa_printf(MSG_ERROR
, "wpas_dbus_signal_wps_event_success"
566 "[dbus]: interface has no dbus path set");
570 _signal
= dbus_message_new_signal(path
, WPAS_DBUS_NEW_IFACE_WPS
,
573 wpa_printf(MSG_ERROR
, "wpas_dbus_signal_wps_event_success"
574 "[dbus]: out of memory when creating a signal");
578 dbus_message_iter_init_append(_signal
, &iter
);
580 if (!dbus_message_iter_append_basic(&iter
, DBUS_TYPE_STRING
, &key
) ||
581 !wpa_dbus_dict_open_write(&iter
, &dict_iter
) ||
582 !wpa_dbus_dict_close_write(&iter
, &dict_iter
)) {
583 wpa_printf(MSG_ERROR
, "wpas_dbus_signal_wps_event_success"
584 "[dbus]: out of memory");
588 dbus_connection_send(iface
->con
, _signal
, NULL
);
590 dbus_message_unref(_signal
);
595 * wpas_dbus_signal_wps_event_fail - Signals Fail WPS event
596 * @wpa_s: %wpa_supplicant network interface data
598 * Sends Event dbus signal with name "fail" and dictionary containing
599 * "msg field with fail message number (int32) as arguments
601 static void wpas_dbus_signal_wps_event_fail(struct wpa_supplicant
*wpa_s
,
602 struct wps_event_fail
*fail
)
605 DBusMessage
*_signal
= NULL
;
606 DBusMessageIter iter
, dict_iter
;
607 struct ctrl_iface_dbus_new_priv
*iface
;
611 iface
= wpa_s
->global
->dbus_new_ctrl_iface
;
613 /* Do nothing if the control interface is not turned on */
617 path
= wpas_dbus_get_path(wpa_s
);
619 wpa_printf(MSG_ERROR
, "wpas_dbus_signal_wps_event_fail[dbus]: "
620 "interface has no dbus path set");
624 _signal
= dbus_message_new_signal(path
, WPAS_DBUS_NEW_IFACE_WPS
,
627 wpa_printf(MSG_ERROR
, "wpas_dbus_signal_wps_event_fail[dbus]: "
628 "out of memory when creating a signal");
632 dbus_message_iter_init_append(_signal
, &iter
);
634 if (!dbus_message_iter_append_basic(&iter
, DBUS_TYPE_STRING
, &key
) ||
635 !wpa_dbus_dict_open_write(&iter
, &dict_iter
) ||
636 !wpa_dbus_dict_append_int32(&dict_iter
, "msg", fail
->msg
) ||
637 !wpa_dbus_dict_close_write(&iter
, &dict_iter
)) {
638 wpa_printf(MSG_ERROR
, "wpas_dbus_signal_wps_event_fail[dbus]: "
643 dbus_connection_send(iface
->con
, _signal
, NULL
);
645 dbus_message_unref(_signal
);
650 * wpas_dbus_signal_wps_event_m2d - Signals M2D WPS event
651 * @wpa_s: %wpa_supplicant network interface data
653 * Sends Event dbus signal with name "m2d" and dictionary containing
654 * fields of wps_event_m2d structure.
656 static void wpas_dbus_signal_wps_event_m2d(struct wpa_supplicant
*wpa_s
,
657 struct wps_event_m2d
*m2d
)
660 DBusMessage
*_signal
= NULL
;
661 DBusMessageIter iter
, dict_iter
;
662 struct ctrl_iface_dbus_new_priv
*iface
;
666 iface
= wpa_s
->global
->dbus_new_ctrl_iface
;
668 /* Do nothing if the control interface is not turned on */
672 path
= wpas_dbus_get_path(wpa_s
);
674 wpa_printf(MSG_ERROR
, "wpas_dbus_signal_wps_event_m2d[dbus]: "
675 "interface has no dbus path set");
679 _signal
= dbus_message_new_signal(path
, WPAS_DBUS_NEW_IFACE_WPS
,
682 wpa_printf(MSG_ERROR
, "wpas_dbus_signal_wps_event_m2d[dbus]: "
683 "out of memory when creating a signal");
687 dbus_message_iter_init_append(_signal
, &iter
);
689 if (!(dbus_message_iter_append_basic(&iter
, DBUS_TYPE_STRING
, &key
) &&
690 wpa_dbus_dict_open_write(&iter
, &dict_iter
) &&
691 wpa_dbus_dict_append_uint16(&dict_iter
, "config_methods",
692 m2d
->config_methods
) &&
693 wpa_dbus_dict_append_byte_array(&dict_iter
, "manufacturer",
694 (const char *) m2d
->manufacturer
,
695 m2d
->manufacturer_len
) &&
696 wpa_dbus_dict_append_byte_array(&dict_iter
, "model_name",
697 (const char *) m2d
->model_name
,
698 m2d
->model_name_len
) &&
699 wpa_dbus_dict_append_byte_array(&dict_iter
, "model_number",
700 (const char *) m2d
->model_number
,
701 m2d
->model_number_len
) &&
702 wpa_dbus_dict_append_byte_array(&dict_iter
, "serial_number",
705 m2d
->serial_number_len
) &&
706 wpa_dbus_dict_append_byte_array(&dict_iter
, "dev_name",
707 (const char *) m2d
->dev_name
,
708 m2d
->dev_name_len
) &&
709 wpa_dbus_dict_append_byte_array(&dict_iter
, "primary_dev_type",
711 m2d
->primary_dev_type
, 8) &&
712 wpa_dbus_dict_append_uint16(&dict_iter
, "config_error",
713 m2d
->config_error
) &&
714 wpa_dbus_dict_append_uint16(&dict_iter
, "dev_password_id",
715 m2d
->dev_password_id
) &&
716 wpa_dbus_dict_close_write(&iter
, &dict_iter
))) {
717 wpa_printf(MSG_ERROR
, "wpas_dbus_signal_wps_event_m2d[dbus]: "
722 dbus_connection_send(iface
->con
, _signal
, NULL
);
724 dbus_message_unref(_signal
);
729 * wpas_dbus_signal_wps_cred - Signals new credentials
730 * @wpa_s: %wpa_supplicant network interface data
732 * Sends signal with credentials in directory argument
734 static void wpas_dbus_signal_wps_cred(struct wpa_supplicant
*wpa_s
,
735 const struct wps_credential
*cred
)
737 DBusMessage
*_signal
= NULL
;
738 DBusMessageIter iter
, dict_iter
;
739 struct ctrl_iface_dbus_new_priv
*iface
;
741 char *auth_type
[6]; /* we have six possible authorization types */
743 char *encr_type
[4]; /* we have four possible encryption types */
746 iface
= wpa_s
->global
->dbus_new_ctrl_iface
;
748 /* Do nothing if the control interface is not turned on */
752 path
= wpas_dbus_get_path(wpa_s
);
754 wpa_printf(MSG_ERROR
, "wpas_dbus_signal_wps_cred[dbus]: "
755 "interface has no dbus path set");
759 _signal
= dbus_message_new_signal(path
, WPAS_DBUS_NEW_IFACE_WPS
,
762 wpa_printf(MSG_ERROR
, "wpas_dbus_signal_wps_cred[dbus]: "
763 "out of memory when creating a signal");
767 dbus_message_iter_init_append(_signal
, &iter
);
769 if (!wpa_dbus_dict_open_write(&iter
, &dict_iter
)) {
770 perror("wpas_dbus_signal_wps_cred[dbus]: out of memory "
771 "when opening a dictionary");
775 if (cred
->auth_type
& WPS_AUTH_OPEN
)
776 auth_type
[at_num
++] = "open";
777 if (cred
->auth_type
& WPS_AUTH_WPAPSK
)
778 auth_type
[at_num
++] = "wpa-psk";
779 if (cred
->auth_type
& WPS_AUTH_SHARED
)
780 auth_type
[at_num
++] = "shared";
781 if (cred
->auth_type
& WPS_AUTH_WPA
)
782 auth_type
[at_num
++] = "wpa-eap";
783 if (cred
->auth_type
& WPS_AUTH_WPA2
)
784 auth_type
[at_num
++] = "wpa2-eap";
785 if (cred
->auth_type
& WPS_AUTH_WPA2PSK
)
786 auth_type
[at_num
++] =
789 if (cred
->encr_type
& WPS_ENCR_NONE
)
790 encr_type
[et_num
++] = "none";
791 if (cred
->encr_type
& WPS_ENCR_WEP
)
792 encr_type
[et_num
++] = "wep";
793 if (cred
->encr_type
& WPS_ENCR_TKIP
)
794 encr_type
[et_num
++] = "tkip";
795 if (cred
->encr_type
& WPS_ENCR_AES
)
796 encr_type
[et_num
++] = "aes";
798 if (wpa_s
->current_ssid
) {
799 if (!wpa_dbus_dict_append_byte_array(
801 (const char *) wpa_s
->current_ssid
->bssid
,
803 perror("wpas_dbus_signal_wps_cred[dbus]: out of "
804 "memory when appending bssid to dictionary");
809 if (!(wpa_dbus_dict_append_byte_array(&dict_iter
, "SSID",
810 (const char *) cred
->ssid
,
812 wpa_dbus_dict_append_string_array(&dict_iter
, "AuthType",
813 (const char **) auth_type
,
815 wpa_dbus_dict_append_string_array(&dict_iter
, "EncrType",
816 (const char **) encr_type
,
818 wpa_dbus_dict_append_byte_array(&dict_iter
, "Key",
819 (const char *) cred
->key
,
821 wpa_dbus_dict_append_uint32(&dict_iter
, "KeyIndex",
823 perror("wpas_dbus_signal_wps_cred[dbus]: out of memory "
824 "when appending to dictionary");
828 if (!wpa_dbus_dict_close_write(&iter
, &dict_iter
)) {
829 perror("wpas_dbus_signal_wps_cred[dbus]: out of memory "
830 "when closing a dictionary");
834 dbus_connection_send(iface
->con
, _signal
, NULL
);
837 dbus_message_unref(_signal
);
840 #endif /* CONFIG_WPS */
844 * wpas_dbus_signal_prop_changed - Signals change of property
845 * @wpa_s: %wpa_supplicant network interface data
846 * @property: indicates which property has changed
848 * Sends ProertyChanged signals with path, interface and arguments
849 * depending on which property has changed.
851 static void wpas_dbus_signal_prop_changed(struct wpa_supplicant
*wpa_s
,
852 enum wpas_dbus_prop property
)
854 WPADBusPropertyAccessor getter
;
860 case WPAS_DBUS_PROP_AP_SCAN
:
861 getter
= (WPADBusPropertyAccessor
) wpas_dbus_getter_ap_scan
;
863 iface
= WPAS_DBUS_NEW_IFACE_INTERFACE
;
866 case WPAS_DBUS_PROP_SCANNING
:
867 getter
= (WPADBusPropertyAccessor
) wpas_dbus_getter_scanning
;
869 iface
= WPAS_DBUS_NEW_IFACE_INTERFACE
;
872 case WPAS_DBUS_PROP_CURRENT_BSS
:
873 getter
= (WPADBusPropertyAccessor
)
874 wpas_dbus_getter_current_bss
;
876 iface
= WPAS_DBUS_NEW_IFACE_INTERFACE
;
879 case WPAS_DBUS_PROP_CURRENT_NETWORK
:
880 getter
= (WPADBusPropertyAccessor
)
881 wpas_dbus_getter_current_network
;
883 iface
= WPAS_DBUS_NEW_IFACE_INTERFACE
;
884 prop
= "CurrentNetwork";
887 wpa_printf(MSG_ERROR
, "wpas_dbus_signal_prop_changed[dbus]: "
888 "Unknown Property enum value %d", property
);
892 wpa_dbus_signal_property_changed(wpa_s
->global
->dbus_new_ctrl_iface
,
894 wpas_dbus_get_path(wpa_s
), iface
,
900 * wpas_dbus_signal_debug_params_changed - Signals change of debug params
901 * @global: wpa_global structure
903 * Sends ProertyChanged signals informing that debug params has changed.
905 static void wpas_dbus_signal_debug_params_changed(struct wpa_global
*global
)
908 wpa_dbus_signal_property_changed(global
->dbus_new_ctrl_iface
,
909 (WPADBusPropertyAccessor
)
910 wpas_dbus_getter_debug_params
,
911 global
, WPAS_DBUS_NEW_PATH
,
912 WPAS_DBUS_NEW_INTERFACE
,
917 struct wpas_dbus_method
{
920 WPADBusMethodHandler handler
;
921 struct wpa_dbus_argument args
[3];
924 struct wpas_dbus_property
{
928 WPADBusPropertyAccessor getter
;
929 WPADBusPropertyAccessor setter
;
930 enum dbus_prop_access _access
;
933 struct wpas_dbus_signal
{
936 struct wpa_dbus_argument args
[3];
940 static void wpas_dbus_register(struct wpa_dbus_object_desc
*obj_desc
,
942 const struct wpas_dbus_method
*methods
,
943 const struct wpas_dbus_property
*properties
,
944 const struct wpas_dbus_signal
*signals
)
948 for (i
= 0; methods
&& methods
[i
].name
; i
++) {
949 wpa_dbus_method_register(obj_desc
, methods
[i
].iface
,
950 methods
[i
].name
, methods
[i
].handler
,
951 priv
, NULL
, methods
[i
].args
);
954 for (i
= 0; properties
&& properties
[i
].name
; i
++) {
955 wpa_dbus_property_register(obj_desc
, properties
[i
].iface
,
958 properties
[i
].getter
,
959 properties
[i
].setter
,
960 priv
, NULL
, properties
[i
]._access
);
963 for (i
= 0; signals
&& signals
[i
].name
; i
++) {
964 wpa_dbus_signal_register(obj_desc
, signals
[i
].iface
,
965 signals
[i
].name
, signals
[i
].args
);
970 static const struct wpas_dbus_method wpas_dbus_global_methods
[] = {
971 { "CreateInterface", WPAS_DBUS_NEW_INTERFACE
,
972 (WPADBusMethodHandler
) &wpas_dbus_handler_create_interface
,
974 { "args", "a{sv}", ARG_IN
},
975 { "path", "o", ARG_OUT
},
979 { "RemoveInterface", WPAS_DBUS_NEW_INTERFACE
,
980 (WPADBusMethodHandler
) &wpas_dbus_handler_remove_interface
,
982 { "path", "o", ARG_IN
},
986 { "GetInterface", WPAS_DBUS_NEW_INTERFACE
,
987 (WPADBusMethodHandler
) &wpas_dbus_handler_get_interface
,
989 { "ifname", "s", ARG_IN
},
990 { "path", "o", ARG_OUT
},
994 { NULL
, NULL
, NULL
, { END_ARGS
} }
997 static const struct wpas_dbus_property wpas_dbus_global_properties
[] = {
998 { "DebugParams", WPAS_DBUS_NEW_INTERFACE
, "(ibb)",
999 (WPADBusPropertyAccessor
) &wpas_dbus_getter_debug_params
,
1000 (WPADBusPropertyAccessor
) &wpas_dbus_setter_debug_params
,
1003 { "Interfaces", WPAS_DBUS_NEW_INTERFACE
, "ao",
1004 (WPADBusPropertyAccessor
) &wpas_dbus_getter_interfaces
,
1008 { "EapMethods", WPAS_DBUS_NEW_INTERFACE
, "as",
1009 wpas_dbus_getter_eap_methods
,
1013 { NULL
, NULL
, NULL
, NULL
, NULL
, 0 }
1016 static const struct wpas_dbus_signal wpas_dbus_global_signals
[] = {
1017 { "InterfaceAdded", WPAS_DBUS_NEW_INTERFACE
,
1019 { "path", "o", ARG_OUT
},
1023 { "InterfaceRemoved", WPAS_DBUS_NEW_INTERFACE
,
1025 { "path", "o", ARG_OUT
},
1029 { "PropertiesChanged", WPAS_DBUS_NEW_INTERFACE
,
1031 { "properties", "a{sv}", ARG_OUT
},
1035 { NULL
, NULL
, { END_ARGS
} }
1040 * wpas_dbus_ctrl_iface_init - Initialize dbus control interface
1041 * @global: Pointer to global data from wpa_supplicant_init()
1042 * Returns: Pointer to dbus_new_ctrl_iface date or %NULL on failure
1044 * Initialize the dbus control interface for wpa_supplicantand and start
1045 * receiving commands from external programs over the bus.
1047 static struct ctrl_iface_dbus_new_priv
* wpas_dbus_ctrl_iface_init(
1048 struct wpa_global
*global
)
1050 struct ctrl_iface_dbus_new_priv
*ctrl_iface
;
1051 struct wpa_dbus_object_desc
*obj_desc
;
1053 obj_desc
= os_zalloc(sizeof(struct wpa_dbus_object_desc
));
1055 wpa_printf(MSG_ERROR
, "Not enough memory "
1056 "to create object description");
1060 wpas_dbus_register(obj_desc
, global
, wpas_dbus_global_methods
,
1061 wpas_dbus_global_properties
,
1062 wpas_dbus_global_signals
);
1064 ctrl_iface
= wpa_dbus_ctrl_iface_init(global
, WPAS_DBUS_NEW_PATH
,
1065 WPAS_DBUS_NEW_SERVICE
,
1068 free_dbus_object_desc(obj_desc
);
1075 * wpas_dbus_ctrl_iface_deinit - Deinitialize dbus ctrl interface for
1077 * @iface: Pointer to dbus private data from
1078 * wpas_dbus_ctrl_iface_init()
1080 * Deinitialize the dbus control interface that was initialized with
1081 * wpas_dbus_ctrl_iface_init().
1083 static void wpas_dbus_ctrl_iface_deinit(struct ctrl_iface_dbus_new_priv
*iface
)
1086 dbus_connection_unregister_object_path(iface
->con
,
1087 WPAS_DBUS_NEW_PATH
);
1088 wpa_dbus_ctrl_iface_deinit(iface
);
1094 * wpas_dbus_register_network - Register a configured network with dbus
1095 * @wpa_s: wpa_supplicant interface structure
1096 * @ssid: network configuration data
1097 * Returns: 0 on success, -1 on failure
1099 * Registers network representing object with dbus
1101 static int wpas_dbus_register_network(struct wpa_supplicant
*wpa_s
,
1102 struct wpa_ssid
*ssid
)
1104 struct ctrl_iface_dbus_new_priv
*ctrl_iface
;
1105 struct wpa_dbus_object_desc
*obj_desc
;
1107 struct network_handler_args
*arg1
= NULL
;
1108 struct network_handler_args
*arg2
= NULL
;
1112 struct wpa_dbus_argument sargs
[] = {
1113 { "properties", "a{sv}", ARG_OUT
},
1117 /* Do nothing if the control interface is not turned on */
1118 if (wpa_s
== NULL
|| wpa_s
->global
== NULL
)
1120 ctrl_iface
= wpa_s
->global
->dbus_new_ctrl_iface
;
1121 if (ctrl_iface
== NULL
)
1124 net_obj_path
= os_zalloc(WPAS_DBUS_OBJECT_PATH_MAX
);
1125 if (net_obj_path
== NULL
)
1127 os_snprintf(net_obj_path
, WPAS_DBUS_OBJECT_PATH_MAX
,
1128 "%s/" WPAS_DBUS_NEW_NETWORKS_PART
"/%u",
1129 wpas_dbus_get_path(wpa_s
), ssid
->id
);
1131 obj_desc
= os_zalloc(sizeof(struct wpa_dbus_object_desc
));
1133 wpa_printf(MSG_ERROR
, "Not enough memory "
1134 "to create object description");
1138 /* allocate memory for handlers arguments */
1139 arg1
= os_zalloc(sizeof(struct network_handler_args
));
1141 wpa_printf(MSG_ERROR
, "Not enough memory "
1142 "to create arguments for method");
1145 arg2
= os_zalloc(sizeof(struct network_handler_args
));
1147 wpa_printf(MSG_ERROR
, "Not enough memory "
1148 "to create arguments for method");
1152 arg1
->wpa_s
= wpa_s
;
1154 arg2
->wpa_s
= wpa_s
;
1157 /* Enabled property */
1158 wpa_dbus_property_register(obj_desc
, WPAS_DBUS_NEW_IFACE_NETWORK
,
1160 (WPADBusPropertyAccessor
)
1161 wpas_dbus_getter_enabled
,
1162 (WPADBusPropertyAccessor
)
1163 wpas_dbus_setter_enabled
,
1166 /* Properties property */
1167 wpa_dbus_property_register(obj_desc
, WPAS_DBUS_NEW_IFACE_NETWORK
,
1168 "Properties", "a{sv}",
1169 (WPADBusPropertyAccessor
)
1170 wpas_dbus_getter_network_properties
,
1171 (WPADBusPropertyAccessor
)
1172 wpas_dbus_setter_network_properties
,
1175 /* PropertiesChanged signal */
1176 wpa_dbus_signal_register(obj_desc
, WPAS_DBUS_NEW_IFACE_NETWORK
,
1177 "PropertiesChanged", sargs
);
1179 if (wpa_dbus_register_object_per_iface(ctrl_iface
, net_obj_path
,
1180 wpa_s
->ifname
, obj_desc
))
1183 wpas_dbus_signal_network_added(wpa_s
, ssid
->id
);
1185 os_free(net_obj_path
);
1189 os_free(net_obj_path
);
1198 * wpas_dbus_unregister_network - Unregister a configured network from dbus
1199 * @wpa_s: wpa_supplicant interface structure
1201 * Returns: 0 on success, -1 on failure
1203 * Unregisters network representing object from dbus
1205 static int wpas_dbus_unregister_network(struct wpa_supplicant
*wpa_s
, int nid
)
1207 struct ctrl_iface_dbus_new_priv
*ctrl_iface
;
1211 /* Do nothing if the control interface is not turned on */
1212 if (wpa_s
== NULL
|| wpa_s
->global
== NULL
)
1214 ctrl_iface
= wpa_s
->global
->dbus_new_ctrl_iface
;
1215 if (ctrl_iface
== NULL
)
1218 net_obj_path
= os_zalloc(WPAS_DBUS_OBJECT_PATH_MAX
);
1219 if (net_obj_path
== NULL
)
1221 os_snprintf(net_obj_path
, WPAS_DBUS_OBJECT_PATH_MAX
,
1222 "%s/" WPAS_DBUS_NEW_NETWORKS_PART
"/%u",
1223 wpas_dbus_get_path(wpa_s
), nid
);
1225 ret
= wpa_dbus_unregister_object_per_iface(ctrl_iface
, net_obj_path
);
1228 wpas_dbus_signal_network_removed(wpa_s
, nid
);
1230 os_free(net_obj_path
);
1236 * wpas_dbus_unregister_bss - Unregister a scanned BSS from dbus
1237 * @wpa_s: wpa_supplicant interface structure
1238 * @bssid: scanned network bssid
1239 * Returns: 0 on success, -1 on failure
1241 * Unregisters BSS representing object from dbus
1243 static int wpas_dbus_unregister_bss(struct wpa_supplicant
*wpa_s
,
1246 struct ctrl_iface_dbus_new_priv
*ctrl_iface
;
1249 /* Do nothing if the control interface is not turned on */
1250 if (wpa_s
== NULL
|| wpa_s
->global
== NULL
)
1252 ctrl_iface
= wpa_s
->global
->dbus_new_ctrl_iface
;
1253 if (ctrl_iface
== NULL
)
1256 bss_obj_path
= os_zalloc(WPAS_DBUS_OBJECT_PATH_MAX
);
1257 if (bss_obj_path
== NULL
)
1260 os_snprintf(bss_obj_path
, WPAS_DBUS_OBJECT_PATH_MAX
,
1261 "%s/" WPAS_DBUS_NEW_BSSIDS_PART
"/" WPAS_DBUS_BSSID_FORMAT
,
1262 wpas_dbus_get_path(wpa_s
), MAC2STR(bssid
));
1264 if (wpa_dbus_unregister_object_per_iface(ctrl_iface
, bss_obj_path
)) {
1265 wpa_printf(MSG_ERROR
,
1266 "Cannot unregister BSSID dbus object %s.",
1268 os_free(bss_obj_path
);
1272 wpas_dbus_signal_bss_removed(wpa_s
, bss_obj_path
);
1274 os_free(bss_obj_path
);
1280 * wpas_dbus_register_bss - Register a scanned BSS with dbus
1281 * @wpa_s: wpa_supplicant interface structure
1282 * @bssid: scanned network bssid
1283 * Returns: 0 on success, -1 on failure
1285 * Registers BSS representing object with dbus
1287 static int wpas_dbus_register_bss(struct wpa_supplicant
*wpa_s
,
1290 struct ctrl_iface_dbus_new_priv
*ctrl_iface
;
1291 struct wpa_dbus_object_desc
*obj_desc
;
1294 struct bss_handler_args
*arg
= NULL
;
1296 /* Do nothing if the control interface is not turned on */
1297 if (wpa_s
== NULL
|| wpa_s
->global
== NULL
)
1299 ctrl_iface
= wpa_s
->global
->dbus_new_ctrl_iface
;
1300 if (ctrl_iface
== NULL
)
1303 bss_obj_path
= os_zalloc(WPAS_DBUS_OBJECT_PATH_MAX
);
1304 if (bss_obj_path
== NULL
)
1307 os_snprintf(bss_obj_path
, WPAS_DBUS_OBJECT_PATH_MAX
,
1308 "%s/" WPAS_DBUS_NEW_BSSIDS_PART
"/" WPAS_DBUS_BSSID_FORMAT
,
1309 wpas_dbus_get_path(wpa_s
), MAC2STR(bssid
));
1311 obj_desc
= os_zalloc(sizeof(struct wpa_dbus_object_desc
));
1313 wpa_printf(MSG_ERROR
, "Not enough memory "
1314 "to create object description");
1318 arg
= os_zalloc(sizeof(struct bss_handler_args
));
1320 wpa_printf(MSG_ERROR
, "Not enough memory "
1321 "to create arguments for handler");
1325 os_memcpy(arg
->bssid
, bssid
, ETH_ALEN
);
1327 /* Properties property */
1328 wpa_dbus_property_register(obj_desc
, WPAS_DBUS_NEW_IFACE_BSSID
,
1329 "Properties", "a{sv}",
1330 (WPADBusPropertyAccessor
)
1331 wpas_dbus_getter_bss_properties
, NULL
,
1334 if (wpa_dbus_register_object_per_iface(ctrl_iface
, bss_obj_path
,
1335 wpa_s
->ifname
, obj_desc
)) {
1336 wpa_printf(MSG_ERROR
,
1337 "Cannot register BSSID dbus object %s.",
1342 wpas_dbus_signal_bss_added(wpa_s
, bss_obj_path
);
1344 os_free(bss_obj_path
);
1348 os_free(bss_obj_path
);
1355 static const struct wpas_dbus_method wpas_dbus_interface_methods
[] = {
1356 { "Scan", WPAS_DBUS_NEW_IFACE_INTERFACE
,
1357 (WPADBusMethodHandler
) &wpas_dbus_handler_scan
,
1359 { "args", "a{sv}", ARG_IN
},
1363 { "Disconnect", WPAS_DBUS_NEW_IFACE_INTERFACE
,
1364 (WPADBusMethodHandler
) &wpas_dbus_handler_disconnect
,
1369 { "AddNetwork", WPAS_DBUS_NEW_IFACE_INTERFACE
,
1370 (WPADBusMethodHandler
) &wpas_dbus_handler_add_network
,
1372 { "args", "a{sv}", ARG_IN
},
1373 { "path", "o", ARG_OUT
},
1377 { "RemoveNetwork", WPAS_DBUS_NEW_IFACE_INTERFACE
,
1378 (WPADBusMethodHandler
) &wpas_dbus_handler_remove_network
,
1380 { "path", "o", ARG_IN
},
1384 { "SelectNetwork", WPAS_DBUS_NEW_IFACE_INTERFACE
,
1385 (WPADBusMethodHandler
) &wpas_dbus_handler_select_network
,
1387 { "path", "o", ARG_IN
},
1391 { "AddBlob", WPAS_DBUS_NEW_IFACE_INTERFACE
,
1392 (WPADBusMethodHandler
) &wpas_dbus_handler_add_blob
,
1394 { "name", "s", ARG_IN
},
1395 { "data", "ay", ARG_IN
},
1399 { "GetBlob", WPAS_DBUS_NEW_IFACE_INTERFACE
,
1400 (WPADBusMethodHandler
) &wpas_dbus_handler_get_blob
,
1402 { "name", "s", ARG_IN
},
1403 { "data", "ay", ARG_OUT
},
1407 { "RemoveBlob", WPAS_DBUS_NEW_IFACE_INTERFACE
,
1408 (WPADBusMethodHandler
) &wpas_dbus_handler_remove_blob
,
1410 { "name", "s", ARG_IN
},
1415 { "Start", WPAS_DBUS_NEW_IFACE_WPS
,
1416 (WPADBusMethodHandler
) &wpas_dbus_handler_wps_start
,
1418 { "args", "a{sv}", ARG_IN
},
1419 { "output", "a{sv}", ARG_OUT
},
1423 #endif /* CONFIG_WPS */
1424 { NULL
, NULL
, NULL
, { END_ARGS
} }
1427 static const struct wpas_dbus_property wpas_dbus_interface_properties
[] = {
1428 { "Capabilities", WPAS_DBUS_NEW_IFACE_INTERFACE
, "a{sv}",
1429 (WPADBusPropertyAccessor
) wpas_dbus_getter_capabilities
,
1432 { "State", WPAS_DBUS_NEW_IFACE_INTERFACE
, "s",
1433 (WPADBusPropertyAccessor
) wpas_dbus_getter_state
,
1436 { "Scanning", WPAS_DBUS_NEW_IFACE_INTERFACE
, "b",
1437 (WPADBusPropertyAccessor
) wpas_dbus_getter_scanning
,
1440 { "ApScan", WPAS_DBUS_NEW_IFACE_INTERFACE
, "u",
1441 (WPADBusPropertyAccessor
) wpas_dbus_getter_ap_scan
,
1442 (WPADBusPropertyAccessor
) wpas_dbus_setter_ap_scan
,
1445 { "Ifname", WPAS_DBUS_NEW_IFACE_INTERFACE
, "s",
1446 (WPADBusPropertyAccessor
) wpas_dbus_getter_ifname
,
1449 { "Driver", WPAS_DBUS_NEW_IFACE_INTERFACE
, "s",
1450 (WPADBusPropertyAccessor
) wpas_dbus_getter_driver
,
1453 { "BridgeIfname", WPAS_DBUS_NEW_IFACE_INTERFACE
, "s",
1454 (WPADBusPropertyAccessor
) wpas_dbus_getter_bridge_ifname
,
1457 { "CurrentBSS", WPAS_DBUS_NEW_IFACE_INTERFACE
, "o",
1458 (WPADBusPropertyAccessor
) wpas_dbus_getter_current_bss
,
1461 { "CurrentNetwork", WPAS_DBUS_NEW_IFACE_INTERFACE
, "o",
1462 (WPADBusPropertyAccessor
) wpas_dbus_getter_current_network
,
1465 { "Blobs", WPAS_DBUS_NEW_IFACE_INTERFACE
, "a{say}",
1466 (WPADBusPropertyAccessor
) wpas_dbus_getter_blobs
,
1469 { "BSSs", WPAS_DBUS_NEW_IFACE_INTERFACE
, "ao",
1470 (WPADBusPropertyAccessor
) wpas_dbus_getter_bsss
,
1473 { "Networks", WPAS_DBUS_NEW_IFACE_INTERFACE
, "ao",
1474 (WPADBusPropertyAccessor
) wpas_dbus_getter_networks
,
1478 { "ProcessCredentials", WPAS_DBUS_NEW_IFACE_WPS
, "b",
1479 (WPADBusPropertyAccessor
) wpas_dbus_getter_process_credentials
,
1480 (WPADBusPropertyAccessor
) wpas_dbus_setter_process_credentials
,
1483 #endif /* CONFIG_WPS */
1484 { NULL
, NULL
, NULL
, NULL
, NULL
, 0 }
1487 static const struct wpas_dbus_signal wpas_dbus_interface_signals
[] = {
1488 { "ScanDone", WPAS_DBUS_NEW_IFACE_INTERFACE
,
1490 { "success", "b", ARG_OUT
},
1494 { "StateChanged", WPAS_DBUS_NEW_IFACE_INTERFACE
,
1496 { "newState", "s", ARG_OUT
},
1497 { "oldState", "s", ARG_OUT
},
1501 { "BSSAdded", WPAS_DBUS_NEW_IFACE_INTERFACE
,
1503 { "path", "o", ARG_OUT
},
1507 { "BSSRemoved", WPAS_DBUS_NEW_IFACE_INTERFACE
,
1509 { "path", "o", ARG_OUT
},
1513 { "BlobAdded", WPAS_DBUS_NEW_IFACE_INTERFACE
,
1515 { "name", "s", ARG_OUT
},
1519 { "BlobRemoved", WPAS_DBUS_NEW_IFACE_INTERFACE
,
1521 { "name", "s", ARG_OUT
},
1525 { "NetworkAdded", WPAS_DBUS_NEW_IFACE_INTERFACE
,
1527 { "path", "o", ARG_OUT
},
1531 { "NetworkRemoved", WPAS_DBUS_NEW_IFACE_INTERFACE
,
1533 { "path", "o", ARG_OUT
},
1537 { "NetworkSelected", WPAS_DBUS_NEW_IFACE_INTERFACE
,
1539 { "path", "o", ARG_OUT
},
1543 { "PropertiesChanged", WPAS_DBUS_NEW_IFACE_INTERFACE
,
1545 { "properties", "a{sv}", ARG_OUT
},
1550 { "Event", WPAS_DBUS_NEW_IFACE_WPS
,
1552 { "name", "s", ARG_OUT
},
1553 { "args", "a{sv}", ARG_OUT
},
1557 { "Credentials", WPAS_DBUS_NEW_IFACE_WPS
,
1559 { "credentials", "a{sv}", ARG_OUT
},
1563 { "PropertiesChanged", WPAS_DBUS_NEW_IFACE_WPS
,
1565 { "properties", "a{sv}", ARG_OUT
},
1569 #endif /* CONFIG_WPS */
1570 { NULL
, NULL
, { END_ARGS
} }
1574 static int wpas_dbus_register_interface(struct wpa_supplicant
*wpa_s
)
1577 struct wpa_dbus_object_desc
*obj_desc
= NULL
;
1579 struct ctrl_iface_dbus_new_priv
*ctrl_iface
=
1580 wpa_s
->global
->dbus_new_ctrl_iface
;
1583 /* Do nothing if the control interface is not turned on */
1584 if (ctrl_iface
== NULL
)
1587 /* Create and set the interface's object path */
1588 path
= os_zalloc(WPAS_DBUS_OBJECT_PATH_MAX
);
1591 next
= wpa_dbus_next_objid(ctrl_iface
);
1592 os_snprintf(path
, WPAS_DBUS_OBJECT_PATH_MAX
,
1593 WPAS_DBUS_NEW_PATH_INTERFACES
"/%u",
1595 if (wpas_dbus_set_path(wpa_s
, path
)) {
1596 wpa_printf(MSG_DEBUG
,
1597 "Failed to set dbus path for interface %s",
1602 obj_desc
= os_zalloc(sizeof(struct wpa_dbus_object_desc
));
1604 wpa_printf(MSG_ERROR
, "Not enough memory "
1605 "to create object description");
1609 wpas_dbus_register(obj_desc
, wpa_s
, wpas_dbus_interface_methods
,
1610 wpas_dbus_interface_properties
,
1611 wpas_dbus_interface_signals
);
1613 if (wpa_dbus_register_object_per_iface(ctrl_iface
, path
, wpa_s
->ifname
,
1617 wpas_dbus_signal_interface_created(wpa_s
);
1629 static int wpas_dbus_unregister_interface(struct wpa_supplicant
*wpa_s
)
1631 struct ctrl_iface_dbus_new_priv
*ctrl_iface
;
1632 struct wpa_ssid
*ssid
;
1635 /* Do nothing if the control interface is not turned on */
1636 if (wpa_s
== NULL
|| wpa_s
->global
== NULL
)
1638 ctrl_iface
= wpa_s
->global
->dbus_new_ctrl_iface
;
1639 if (ctrl_iface
== NULL
)
1642 /* unregister all BSSs and networks from dbus */
1643 for (i
= 0; i
< wpa_s
->scan_res
->num
; i
++) {
1644 wpas_dbus_unregister_bss(wpa_s
,
1645 wpa_s
->scan_res
->res
[i
]->bssid
);
1648 ssid
= wpa_s
->conf
->ssid
;
1650 wpas_dbus_unregister_network(wpa_s
, ssid
->id
);
1654 if (wpa_dbus_unregister_object_per_iface(ctrl_iface
,
1655 wpas_dbus_get_path(wpa_s
)))
1658 wpas_dbus_signal_interface_removed(wpa_s
);
1660 os_free(wpa_s
->dbus_new_path
);
1661 wpa_s
->dbus_new_path
= NULL
;
1667 static struct wpas_dbus_callbacks callbacks
=
1669 .dbus_ctrl_init
= wpas_dbus_ctrl_iface_init
,
1670 .dbus_ctrl_deinit
= wpas_dbus_ctrl_iface_deinit
,
1672 .signal_interface_created
= wpas_dbus_signal_interface_created
,
1673 .signal_interface_removed
= wpas_dbus_signal_interface_removed
,
1675 .register_interface
= wpas_dbus_register_interface
,
1676 .unregister_interface
= wpas_dbus_unregister_interface
,
1678 .signal_scan_done
= wpas_dbus_signal_scan_done
,
1680 .signal_blob_added
= wpas_dbus_signal_blob_added
,
1681 .signal_blob_removed
= wpas_dbus_signal_blob_removed
,
1683 .signal_network_selected
= wpas_dbus_signal_network_selected
,
1685 .signal_state_changed
= wpas_dbus_signal_state_changed
,
1686 .register_network
= wpas_dbus_register_network
,
1687 .unregister_network
= wpas_dbus_unregister_network
,
1689 .signal_network_enabled_changed
=
1690 wpas_dbus_signal_network_enabled_changed
,
1692 .register_bss
= wpas_dbus_register_bss
,
1693 .unregister_bss
= wpas_dbus_unregister_bss
,
1695 .signal_prop_changed
= wpas_dbus_signal_prop_changed
,
1696 .signal_debug_params_changed
= wpas_dbus_signal_debug_params_changed
,
1699 .signal_wps_event_success
= wpas_dbus_signal_wps_event_success
,
1700 .signal_wps_event_fail
= wpas_dbus_signal_wps_event_fail
,
1701 .signal_wps_event_m2d
= wpas_dbus_signal_wps_event_m2d
,
1702 .signal_wps_credentials
= wpas_dbus_signal_wps_cred
,
1703 #endif /* CONFIG_WPS */
1707 struct wpas_dbus_callbacks
* wpas_dbus_get_callbacks(void)
1714 * wpas_dbus_get_path - Get an interface's dbus path
1715 * @wpa_s: %wpa_supplicant interface structure
1716 * Returns: Interface's dbus object path, or %NULL on error
1718 const char * wpas_dbus_get_path(struct wpa_supplicant
*wpa_s
)
1720 return wpa_s
->dbus_new_path
;