2 * WPA Supplicant / dbus-based control interface
3 * Copyright (c) 2006, Dan Williams <dcbw@redhat.com> and Red Hat, Inc.
4 * Copyright (c) 2009, Witold Sowa <witold.sowa@gmail.com>
5 * Copyright (c) 2009, Jouni Malinen <j@w1.fi>
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
11 * Alternatively, this software may be distributed under the terms of BSD
14 * See README and COPYING for more details.
21 #include "../config.h"
22 #include "../wpa_supplicant_i.h"
24 #include "dbus_new_helpers.h"
25 #include "dbus_dict_helpers.h"
27 #include "dbus_new_handlers.h"
28 #include "dbus_common.h"
29 #include "dbus_common_i.h"
33 * wpas_dbus_signal_interface - Send a interface related event signal
34 * @wpa_s: %wpa_supplicant network interface data
35 * @sig_name: signal name - InterfaceAdded or InterfaceRemoved
36 * @properties: Whether to add second argument with object properties
38 * Notify listeners about event related with interface
40 static void wpas_dbus_signal_interface(struct wpa_supplicant *wpa_s,
41 const char *sig_name, int properties)
43 struct wpas_dbus_priv *iface;
45 DBusMessageIter iter, iter_dict;
47 iface = wpa_s->global->dbus;
49 /* Do nothing if the control interface is not turned on */
53 msg = dbus_message_new_signal(WPAS_DBUS_NEW_PATH,
54 WPAS_DBUS_NEW_INTERFACE, sig_name);
58 dbus_message_iter_init_append(msg, &iter);
59 if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_OBJECT_PATH,
60 &wpa_s->dbus_new_path))
64 if (!wpa_dbus_dict_open_write(&iter, &iter_dict))
67 wpa_dbus_get_object_properties(iface, wpa_s->dbus_new_path,
68 WPAS_DBUS_NEW_IFACE_INTERFACE,
71 if (!wpa_dbus_dict_close_write(&iter, &iter_dict))
75 dbus_connection_send(iface->con, msg, NULL);
76 dbus_message_unref(msg);
80 wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
81 dbus_message_unref(msg);
86 * wpas_dbus_signal_interface_added - Send a interface created signal
87 * @wpa_s: %wpa_supplicant network interface data
89 * Notify listeners about creating new interface
91 static void wpas_dbus_signal_interface_added(struct wpa_supplicant *wpa_s)
93 wpas_dbus_signal_interface(wpa_s, "InterfaceAdded", TRUE);
98 * wpas_dbus_signal_interface_removed - Send a interface removed signal
99 * @wpa_s: %wpa_supplicant network interface data
101 * Notify listeners about removing interface
103 static void wpas_dbus_signal_interface_removed(struct wpa_supplicant *wpa_s)
105 wpas_dbus_signal_interface(wpa_s, "InterfaceRemoved", FALSE);
111 * wpas_dbus_signal_scan_done - send scan done signal
112 * @wpa_s: %wpa_supplicant network interface data
113 * @success: indicates if scanning succeed or failed
115 * Notify listeners about finishing a scan
117 void wpas_dbus_signal_scan_done(struct wpa_supplicant *wpa_s, int success)
119 struct wpas_dbus_priv *iface;
123 iface = wpa_s->global->dbus;
125 /* Do nothing if the control interface is not turned on */
129 msg = dbus_message_new_signal(wpa_s->dbus_new_path,
130 WPAS_DBUS_NEW_IFACE_INTERFACE,
135 succ = success ? TRUE : FALSE;
136 if (dbus_message_append_args(msg, DBUS_TYPE_BOOLEAN, &succ,
138 dbus_connection_send(iface->con, msg, NULL);
140 wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
141 dbus_message_unref(msg);
146 * wpas_dbus_signal_blob - Send a BSS related event signal
147 * @wpa_s: %wpa_supplicant network interface data
148 * @bss_obj_path: BSS object path
149 * @sig_name: signal name - BSSAdded or BSSRemoved
150 * @properties: Whether to add second argument with object properties
152 * Notify listeners about event related with BSS
154 static void wpas_dbus_signal_bss(struct wpa_supplicant *wpa_s,
155 const char *bss_obj_path,
156 const char *sig_name, int properties)
158 struct wpas_dbus_priv *iface;
160 DBusMessageIter iter, iter_dict;
162 iface = wpa_s->global->dbus;
164 /* Do nothing if the control interface is not turned on */
168 msg = dbus_message_new_signal(wpa_s->dbus_new_path,
169 WPAS_DBUS_NEW_IFACE_INTERFACE,
174 dbus_message_iter_init_append(msg, &iter);
175 if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_OBJECT_PATH,
180 if (!wpa_dbus_dict_open_write(&iter, &iter_dict))
183 wpa_dbus_get_object_properties(iface, bss_obj_path,
184 WPAS_DBUS_NEW_IFACE_BSSID,
187 if (!wpa_dbus_dict_close_write(&iter, &iter_dict))
191 dbus_connection_send(iface->con, msg, NULL);
192 dbus_message_unref(msg);
196 wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
197 dbus_message_unref(msg);
202 * wpas_dbus_signal_bss_added - Send a BSS added signal
203 * @wpa_s: %wpa_supplicant network interface data
204 * @bss_obj_path: new BSS object path
206 * Notify listeners about adding new BSS
208 static void wpas_dbus_signal_bss_added(struct wpa_supplicant *wpa_s,
209 const char *bss_obj_path)
211 wpas_dbus_signal_bss(wpa_s, bss_obj_path, "BSSAdded", TRUE);
216 * wpas_dbus_signal_bss_removed - Send a BSS removed signal
217 * @wpa_s: %wpa_supplicant network interface data
218 * @bss_obj_path: BSS object path
220 * Notify listeners about removing BSS
222 static void wpas_dbus_signal_bss_removed(struct wpa_supplicant *wpa_s,
223 const char *bss_obj_path)
225 wpas_dbus_signal_bss(wpa_s, bss_obj_path, "BSSRemoved", FALSE);
230 * wpas_dbus_signal_blob - Send a blob related event signal
231 * @wpa_s: %wpa_supplicant network interface data
233 * @sig_name: signal name - BlobAdded or BlobRemoved
235 * Notify listeners about event related with blob
237 static void wpas_dbus_signal_blob(struct wpa_supplicant *wpa_s,
238 const char *name, const char *sig_name)
240 struct wpas_dbus_priv *iface;
243 iface = wpa_s->global->dbus;
245 /* Do nothing if the control interface is not turned on */
249 msg = dbus_message_new_signal(wpa_s->dbus_new_path,
250 WPAS_DBUS_NEW_IFACE_INTERFACE,
255 if (dbus_message_append_args(msg, DBUS_TYPE_STRING, &name,
257 dbus_connection_send(iface->con, msg, NULL);
259 wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
260 dbus_message_unref(msg);
265 * wpas_dbus_signal_blob_added - Send a blob added signal
266 * @wpa_s: %wpa_supplicant network interface data
269 * Notify listeners about adding a new blob
271 void wpas_dbus_signal_blob_added(struct wpa_supplicant *wpa_s,
274 wpas_dbus_signal_blob(wpa_s, name, "BlobAdded");
279 * wpas_dbus_signal_blob_removed - Send a blob removed signal
280 * @wpa_s: %wpa_supplicant network interface data
283 * Notify listeners about removing blob
285 void wpas_dbus_signal_blob_removed(struct wpa_supplicant *wpa_s,
288 wpas_dbus_signal_blob(wpa_s, name, "BlobRemoved");
293 * wpas_dbus_signal_network - Send a network related event signal
294 * @wpa_s: %wpa_supplicant network interface data
295 * @id: new network id
296 * @sig_name: signal name - NetworkAdded, NetworkRemoved or NetworkSelected
297 * @properties: determines if add second argument with object properties
299 * Notify listeners about event related with configured network
301 static void wpas_dbus_signal_network(struct wpa_supplicant *wpa_s,
302 int id, const char *sig_name,
305 struct wpas_dbus_priv *iface;
307 DBusMessageIter iter, iter_dict;
308 char net_obj_path[WPAS_DBUS_OBJECT_PATH_MAX], *path;
310 iface = wpa_s->global->dbus;
312 /* Do nothing if the control interface is not turned on */
316 os_snprintf(net_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
317 "%s/" WPAS_DBUS_NEW_NETWORKS_PART "/%u",
318 wpa_s->dbus_new_path, id);
320 msg = dbus_message_new_signal(wpa_s->dbus_new_path,
321 WPAS_DBUS_NEW_IFACE_INTERFACE,
326 dbus_message_iter_init_append(msg, &iter);
328 if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_OBJECT_PATH,
333 if (!wpa_dbus_dict_open_write(&iter, &iter_dict))
336 wpa_dbus_get_object_properties(iface, net_obj_path,
337 WPAS_DBUS_NEW_IFACE_NETWORK,
340 if (!wpa_dbus_dict_close_write(&iter, &iter_dict))
344 dbus_connection_send(iface->con, msg, NULL);
346 dbus_message_unref(msg);
350 wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
351 dbus_message_unref(msg);
356 * wpas_dbus_signal_network_added - Send a network added signal
357 * @wpa_s: %wpa_supplicant network interface data
358 * @id: new network id
360 * Notify listeners about adding new network
362 static void wpas_dbus_signal_network_added(struct wpa_supplicant *wpa_s,
365 wpas_dbus_signal_network(wpa_s, id, "NetworkAdded", TRUE);
370 * wpas_dbus_signal_network_removed - Send a network removed signal
371 * @wpa_s: %wpa_supplicant network interface data
374 * Notify listeners about removing a network
376 static void wpas_dbus_signal_network_removed(struct wpa_supplicant *wpa_s,
379 wpas_dbus_signal_network(wpa_s, id, "NetworkRemoved", FALSE);
384 * wpas_dbus_signal_network_selected - Send a network selected signal
385 * @wpa_s: %wpa_supplicant network interface data
388 * Notify listeners about selecting a network
390 void wpas_dbus_signal_network_selected(struct wpa_supplicant *wpa_s, int id)
392 wpas_dbus_signal_network(wpa_s, id, "NetworkSelected", FALSE);
396 static void str_to_lower(char *s)
406 * wpas_dbus_signal_state_changed - Send a state changed signal
407 * @wpa_s: %wpa_supplicant network interface data
408 * @new_state: new state wpa_supplicant is entering
409 * @old_state: old state wpa_supplicant is leaving
411 * Notify listeners that wpa_supplicant has changed state
413 void wpas_dbus_signal_state_changed(struct wpa_supplicant *wpa_s,
414 enum wpa_states new_state,
415 enum wpa_states old_state)
417 struct wpas_dbus_priv *iface;
419 char *new_state_str, *old_state_str;
421 /* Do nothing if the control interface is not turned on */
422 if (wpa_s->global == NULL)
424 iface = wpa_s->global->dbus;
428 /* Only send signal if state really changed */
429 if (new_state == old_state)
432 msg = dbus_message_new_signal(wpa_s->dbus_new_path,
433 WPAS_DBUS_NEW_IFACE_INTERFACE,
438 new_state_str = os_strdup(wpa_supplicant_state_txt(new_state));
439 old_state_str = os_strdup(wpa_supplicant_state_txt(old_state));
440 if (new_state_str == NULL || old_state_str == NULL)
443 /* make state string lowercase to fit new DBus API convention */
444 str_to_lower(new_state_str);
445 str_to_lower(old_state_str);
447 if (!dbus_message_append_args(msg,
448 DBUS_TYPE_STRING, &new_state_str,
449 DBUS_TYPE_STRING, &old_state_str,
450 DBUS_TYPE_INVALID)) {
451 wpa_printf(MSG_ERROR, "dbus: Failed to construct state change "
456 dbus_connection_send(iface->con, msg, NULL);
459 dbus_message_unref(msg);
460 os_free(new_state_str);
461 os_free(old_state_str);
466 * wpas_dbus_signal_network_enabled_changed - Signals Enabled property changes
467 * @wpa_s: %wpa_supplicant network interface data
468 * @ssid: configured network which Enabled property has changed
470 * Sends PropertyChanged signals containing new value of Enabled property
471 * for specified network
473 void wpas_dbus_signal_network_enabled_changed(struct wpa_supplicant *wpa_s,
474 struct wpa_ssid *ssid)
477 struct network_handler_args args = { wpa_s, ssid };
478 char path[WPAS_DBUS_OBJECT_PATH_MAX];
479 os_snprintf(path, WPAS_DBUS_OBJECT_PATH_MAX,
480 "%s/" WPAS_DBUS_NEW_NETWORKS_PART "/%d",
481 wpa_s->dbus_new_path, ssid->id);
483 wpa_dbus_signal_property_changed(wpa_s->global->dbus,
484 (WPADBusPropertyAccessor)
485 wpas_dbus_getter_enabled, &args,
486 path, WPAS_DBUS_NEW_IFACE_NETWORK,
494 * wpas_dbus_signal_wps_event_success - Signals Success WPS event
495 * @wpa_s: %wpa_supplicant network interface data
497 * Sends Event dbus signal with name "success" and empty dict as arguments
499 void wpas_dbus_signal_wps_event_success(struct wpa_supplicant *wpa_s)
503 DBusMessageIter iter, dict_iter;
504 struct wpas_dbus_priv *iface;
505 char *key = "success";
507 iface = wpa_s->global->dbus;
509 /* Do nothing if the control interface is not turned on */
513 msg = dbus_message_new_signal(wpa_s->dbus_new_path,
514 WPAS_DBUS_NEW_IFACE_WPS, "Event");
518 dbus_message_iter_init_append(msg, &iter);
520 if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &key) ||
521 !wpa_dbus_dict_open_write(&iter, &dict_iter) ||
522 !wpa_dbus_dict_close_write(&iter, &dict_iter))
523 wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
525 dbus_connection_send(iface->con, msg, NULL);
527 dbus_message_unref(msg);
532 * wpas_dbus_signal_wps_event_fail - Signals Fail WPS event
533 * @wpa_s: %wpa_supplicant network interface data
535 * Sends Event dbus signal with name "fail" and dictionary containing
536 * "msg field with fail message number (int32) as arguments
538 void wpas_dbus_signal_wps_event_fail(struct wpa_supplicant *wpa_s,
539 struct wps_event_fail *fail)
543 DBusMessageIter iter, dict_iter;
544 struct wpas_dbus_priv *iface;
547 iface = wpa_s->global->dbus;
549 /* Do nothing if the control interface is not turned on */
553 msg = dbus_message_new_signal(wpa_s->dbus_new_path,
554 WPAS_DBUS_NEW_IFACE_WPS, "Event");
558 dbus_message_iter_init_append(msg, &iter);
560 if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &key) ||
561 !wpa_dbus_dict_open_write(&iter, &dict_iter) ||
562 !wpa_dbus_dict_append_int32(&dict_iter, "msg", fail->msg) ||
563 !wpa_dbus_dict_close_write(&iter, &dict_iter))
564 wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
566 dbus_connection_send(iface->con, msg, NULL);
568 dbus_message_unref(msg);
573 * wpas_dbus_signal_wps_event_m2d - Signals M2D WPS event
574 * @wpa_s: %wpa_supplicant network interface data
576 * Sends Event dbus signal with name "m2d" and dictionary containing
577 * fields of wps_event_m2d structure.
579 void wpas_dbus_signal_wps_event_m2d(struct wpa_supplicant *wpa_s,
580 struct wps_event_m2d *m2d)
584 DBusMessageIter iter, dict_iter;
585 struct wpas_dbus_priv *iface;
588 iface = wpa_s->global->dbus;
590 /* Do nothing if the control interface is not turned on */
594 msg = dbus_message_new_signal(wpa_s->dbus_new_path,
595 WPAS_DBUS_NEW_IFACE_WPS, "Event");
599 dbus_message_iter_init_append(msg, &iter);
601 if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &key) ||
602 !wpa_dbus_dict_open_write(&iter, &dict_iter) ||
603 !wpa_dbus_dict_append_uint16(&dict_iter, "config_methods",
604 m2d->config_methods) ||
605 !wpa_dbus_dict_append_byte_array(&dict_iter, "manufacturer",
606 (const char *) m2d->manufacturer,
607 m2d->manufacturer_len) ||
608 !wpa_dbus_dict_append_byte_array(&dict_iter, "model_name",
609 (const char *) m2d->model_name,
610 m2d->model_name_len) ||
611 !wpa_dbus_dict_append_byte_array(&dict_iter, "model_number",
612 (const char *) m2d->model_number,
613 m2d->model_number_len) ||
614 !wpa_dbus_dict_append_byte_array(&dict_iter, "serial_number",
617 m2d->serial_number_len) ||
618 !wpa_dbus_dict_append_byte_array(&dict_iter, "dev_name",
619 (const char *) m2d->dev_name,
620 m2d->dev_name_len) ||
621 !wpa_dbus_dict_append_byte_array(&dict_iter, "primary_dev_type",
623 m2d->primary_dev_type, 8) ||
624 !wpa_dbus_dict_append_uint16(&dict_iter, "config_error",
625 m2d->config_error) ||
626 !wpa_dbus_dict_append_uint16(&dict_iter, "dev_password_id",
627 m2d->dev_password_id) ||
628 !wpa_dbus_dict_close_write(&iter, &dict_iter))
629 wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
631 dbus_connection_send(iface->con, msg, NULL);
633 dbus_message_unref(msg);
638 * wpas_dbus_signal_wps_cred - Signals new credentials
639 * @wpa_s: %wpa_supplicant network interface data
641 * Sends signal with credentials in directory argument
643 void wpas_dbus_signal_wps_cred(struct wpa_supplicant *wpa_s,
644 const struct wps_credential *cred)
647 DBusMessageIter iter, dict_iter;
648 struct wpas_dbus_priv *iface;
649 char *auth_type[6]; /* we have six possible authorization types */
651 char *encr_type[4]; /* we have four possible encryption types */
654 iface = wpa_s->global->dbus;
656 /* Do nothing if the control interface is not turned on */
660 msg = dbus_message_new_signal(wpa_s->dbus_new_path,
661 WPAS_DBUS_NEW_IFACE_WPS,
666 dbus_message_iter_init_append(msg, &iter);
667 if (!wpa_dbus_dict_open_write(&iter, &dict_iter))
670 if (cred->auth_type & WPS_AUTH_OPEN)
671 auth_type[at_num++] = "open";
672 if (cred->auth_type & WPS_AUTH_WPAPSK)
673 auth_type[at_num++] = "wpa-psk";
674 if (cred->auth_type & WPS_AUTH_SHARED)
675 auth_type[at_num++] = "shared";
676 if (cred->auth_type & WPS_AUTH_WPA)
677 auth_type[at_num++] = "wpa-eap";
678 if (cred->auth_type & WPS_AUTH_WPA2)
679 auth_type[at_num++] = "wpa2-eap";
680 if (cred->auth_type & WPS_AUTH_WPA2PSK)
681 auth_type[at_num++] =
684 if (cred->encr_type & WPS_ENCR_NONE)
685 encr_type[et_num++] = "none";
686 if (cred->encr_type & WPS_ENCR_WEP)
687 encr_type[et_num++] = "wep";
688 if (cred->encr_type & WPS_ENCR_TKIP)
689 encr_type[et_num++] = "tkip";
690 if (cred->encr_type & WPS_ENCR_AES)
691 encr_type[et_num++] = "aes";
693 if (wpa_s->current_ssid) {
694 if (!wpa_dbus_dict_append_byte_array(
696 (const char *) wpa_s->current_ssid->bssid,
701 if (!wpa_dbus_dict_append_byte_array(&dict_iter, "SSID",
702 (const char *) cred->ssid,
704 !wpa_dbus_dict_append_string_array(&dict_iter, "AuthType",
705 (const char **) auth_type,
707 !wpa_dbus_dict_append_string_array(&dict_iter, "EncrType",
708 (const char **) encr_type,
710 !wpa_dbus_dict_append_byte_array(&dict_iter, "Key",
711 (const char *) cred->key,
713 !wpa_dbus_dict_append_uint32(&dict_iter, "KeyIndex",
715 !wpa_dbus_dict_close_write(&iter, &dict_iter))
718 dbus_connection_send(iface->con, msg, NULL);
721 dbus_message_unref(msg);
724 #endif /* CONFIG_WPS */
728 * wpas_dbus_signal_prop_changed - Signals change of property
729 * @wpa_s: %wpa_supplicant network interface data
730 * @property: indicates which property has changed
732 * Sends ProertyChanged signals with path, interface and arguments
733 * depending on which property has changed.
735 void wpas_dbus_signal_prop_changed(struct wpa_supplicant *wpa_s,
736 enum wpas_dbus_prop property)
738 WPADBusPropertyAccessor getter;
742 case WPAS_DBUS_PROP_AP_SCAN:
743 getter = (WPADBusPropertyAccessor) wpas_dbus_getter_ap_scan;
746 case WPAS_DBUS_PROP_SCANNING:
747 getter = (WPADBusPropertyAccessor) wpas_dbus_getter_scanning;
750 case WPAS_DBUS_PROP_CURRENT_BSS:
751 getter = (WPADBusPropertyAccessor)
752 wpas_dbus_getter_current_bss;
755 case WPAS_DBUS_PROP_CURRENT_NETWORK:
756 getter = (WPADBusPropertyAccessor)
757 wpas_dbus_getter_current_network;
758 prop = "CurrentNetwork";
761 wpa_printf(MSG_ERROR, "dbus: %s: Unknown Property value %d",
766 wpa_dbus_signal_property_changed(wpa_s->global->dbus,
767 getter, wpa_s, wpa_s->dbus_new_path,
768 WPAS_DBUS_NEW_IFACE_INTERFACE, prop);
773 * wpas_dbus_signal_debug_level_changed - Signals change of debug param
774 * @global: wpa_global structure
776 * Sends ProertyChanged signals informing that debug level has changed.
778 void wpas_dbus_signal_debug_level_changed(struct wpa_global *global)
780 wpa_dbus_signal_property_changed(global->dbus,
781 (WPADBusPropertyAccessor)
782 wpas_dbus_getter_debug_level,
783 global, WPAS_DBUS_NEW_PATH,
784 WPAS_DBUS_NEW_INTERFACE,
790 * wpas_dbus_signal_debug_timestamp_changed - Signals change of debug param
791 * @global: wpa_global structure
793 * Sends ProertyChanged signals informing that debug timestamp has changed.
795 void wpas_dbus_signal_debug_timestamp_changed(struct wpa_global *global)
797 wpa_dbus_signal_property_changed(global->dbus,
798 (WPADBusPropertyAccessor)
799 wpas_dbus_getter_debug_timestamp,
800 global, WPAS_DBUS_NEW_PATH,
801 WPAS_DBUS_NEW_INTERFACE,
807 * wpas_dbus_signal_debug_show_keys_changed - Signals change of debug param
808 * @global: wpa_global structure
810 * Sends ProertyChanged signals informing that debug show_keys has changed.
812 void wpas_dbus_signal_debug_show_keys_changed(struct wpa_global *global)
814 wpa_dbus_signal_property_changed(global->dbus,
815 (WPADBusPropertyAccessor)
816 wpas_dbus_getter_debug_show_keys,
817 global, WPAS_DBUS_NEW_PATH,
818 WPAS_DBUS_NEW_INTERFACE,
823 struct wpas_dbus_method {
826 WPADBusMethodHandler handler;
827 struct wpa_dbus_argument args[3];
830 struct wpas_dbus_property {
834 WPADBusPropertyAccessor getter;
835 WPADBusPropertyAccessor setter;
836 enum dbus_prop_access _access;
839 struct wpas_dbus_signal {
842 struct wpa_dbus_argument args[3];
846 static void wpas_dbus_register(struct wpa_dbus_object_desc *obj_desc,
848 WPADBusArgumentFreeFunction priv_free,
849 const struct wpas_dbus_method *methods,
850 const struct wpas_dbus_property *properties,
851 const struct wpas_dbus_signal *signals)
855 obj_desc->user_data = priv;
856 obj_desc->user_data_free_func = priv_free;
858 for (i = 0; methods && methods[i].name; i++) {
859 wpa_dbus_method_register(obj_desc, methods[i].iface,
860 methods[i].name, methods[i].handler,
864 for (i = 0; properties && properties[i].name; i++) {
865 wpa_dbus_property_register(obj_desc, properties[i].iface,
868 properties[i].getter,
869 properties[i].setter,
870 properties[i]._access);
873 for (i = 0; signals && signals[i].name; i++) {
874 wpa_dbus_signal_register(obj_desc, signals[i].iface,
875 signals[i].name, signals[i].args);
880 static const struct wpas_dbus_method wpas_dbus_global_methods[] = {
881 { "CreateInterface", WPAS_DBUS_NEW_INTERFACE,
882 (WPADBusMethodHandler) &wpas_dbus_handler_create_interface,
884 { "args", "a{sv}", ARG_IN },
885 { "path", "o", ARG_OUT },
889 { "RemoveInterface", WPAS_DBUS_NEW_INTERFACE,
890 (WPADBusMethodHandler) &wpas_dbus_handler_remove_interface,
892 { "path", "o", ARG_IN },
896 { "GetInterface", WPAS_DBUS_NEW_INTERFACE,
897 (WPADBusMethodHandler) &wpas_dbus_handler_get_interface,
899 { "ifname", "s", ARG_IN },
900 { "path", "o", ARG_OUT },
904 { NULL, NULL, NULL, { END_ARGS } }
907 static const struct wpas_dbus_property wpas_dbus_global_properties[] = {
908 { "DebugLevel", WPAS_DBUS_NEW_INTERFACE, "y",
909 (WPADBusPropertyAccessor) wpas_dbus_getter_debug_level,
910 (WPADBusPropertyAccessor) wpas_dbus_setter_debug_level,
913 { "DebugTimestamp", WPAS_DBUS_NEW_INTERFACE, "b",
914 (WPADBusPropertyAccessor) wpas_dbus_getter_debug_timestamp,
915 (WPADBusPropertyAccessor) wpas_dbus_setter_debug_timestamp,
918 { "DebugShowKeys", WPAS_DBUS_NEW_INTERFACE, "b",
919 (WPADBusPropertyAccessor) wpas_dbus_getter_debug_show_keys,
920 (WPADBusPropertyAccessor) wpas_dbus_setter_debug_show_keys,
923 { "Interfaces", WPAS_DBUS_NEW_INTERFACE, "ao",
924 (WPADBusPropertyAccessor) &wpas_dbus_getter_interfaces,
928 { "EapMethods", WPAS_DBUS_NEW_INTERFACE, "as",
929 (WPADBusPropertyAccessor) wpas_dbus_getter_eap_methods,
933 { NULL, NULL, NULL, NULL, NULL, 0 }
936 static const struct wpas_dbus_signal wpas_dbus_global_signals[] = {
937 { "InterfaceAdded", WPAS_DBUS_NEW_INTERFACE,
939 { "path", "o", ARG_OUT },
940 { "properties", "a{sv}", ARG_OUT },
944 { "InterfaceRemoved", WPAS_DBUS_NEW_INTERFACE,
946 { "path", "o", ARG_OUT },
950 { "PropertiesChanged", WPAS_DBUS_NEW_INTERFACE,
952 { "properties", "a{sv}", ARG_OUT },
956 { NULL, NULL, { END_ARGS } }
961 * wpas_dbus_ctrl_iface_init - Initialize dbus control interface
962 * @global: Pointer to global data from wpa_supplicant_init()
963 * Returns: 0 on success or -1 on failure
965 * Initialize the dbus control interface for wpa_supplicantand and start
966 * receiving commands from external programs over the bus.
968 int wpas_dbus_ctrl_iface_init(struct wpas_dbus_priv *priv)
970 struct wpa_dbus_object_desc *obj_desc;
973 obj_desc = os_zalloc(sizeof(struct wpa_dbus_object_desc));
975 wpa_printf(MSG_ERROR, "Not enough memory "
976 "to create object description");
980 wpas_dbus_register(obj_desc, priv->global, NULL,
981 wpas_dbus_global_methods,
982 wpas_dbus_global_properties,
983 wpas_dbus_global_signals);
985 wpa_printf(MSG_DEBUG, "dbus: Register D-Bus object '%s'",
987 ret = wpa_dbus_ctrl_iface_init(priv, WPAS_DBUS_NEW_PATH,
988 WPAS_DBUS_NEW_SERVICE,
991 free_dbus_object_desc(obj_desc);
993 priv->dbus_new_initialized = 1;
1000 * wpas_dbus_ctrl_iface_deinit - Deinitialize dbus ctrl interface for
1002 * @iface: Pointer to dbus private data from wpas_dbus_init()
1004 * Deinitialize the dbus control interface that was initialized with
1005 * wpas_dbus_ctrl_iface_init().
1007 void wpas_dbus_ctrl_iface_deinit(struct wpas_dbus_priv *iface)
1009 if (!iface->dbus_new_initialized)
1011 wpa_printf(MSG_DEBUG, "dbus: Unregister D-Bus object '%s'",
1012 WPAS_DBUS_NEW_PATH);
1013 dbus_connection_unregister_object_path(iface->con,
1014 WPAS_DBUS_NEW_PATH);
1018 static void wpa_dbus_free(void *ptr)
1024 static const struct wpas_dbus_property wpas_dbus_network_properties[] = {
1025 { "Properties", WPAS_DBUS_NEW_IFACE_NETWORK, "a{sv}",
1026 (WPADBusPropertyAccessor) wpas_dbus_getter_network_properties,
1027 (WPADBusPropertyAccessor) wpas_dbus_setter_network_properties,
1030 { "Enabled", WPAS_DBUS_NEW_IFACE_NETWORK, "b",
1031 (WPADBusPropertyAccessor) wpas_dbus_getter_enabled,
1032 (WPADBusPropertyAccessor) wpas_dbus_setter_enabled,
1035 { NULL, NULL, NULL, NULL, NULL, 0 }
1039 static const struct wpas_dbus_signal wpas_dbus_network_signals[] = {
1040 { "PropertiesChanged", WPAS_DBUS_NEW_IFACE_NETWORK,
1042 { "properties", "a{sv}", ARG_OUT },
1046 { NULL, NULL, { END_ARGS } }
1051 * wpas_dbus_register_network - Register a configured network with dbus
1052 * @wpa_s: wpa_supplicant interface structure
1053 * @ssid: network configuration data
1054 * Returns: 0 on success, -1 on failure
1056 * Registers network representing object with dbus
1058 int wpas_dbus_register_network(struct wpa_supplicant *wpa_s,
1059 struct wpa_ssid *ssid)
1061 struct wpas_dbus_priv *ctrl_iface;
1062 struct wpa_dbus_object_desc *obj_desc;
1063 struct network_handler_args *arg = NULL;
1064 char net_obj_path[WPAS_DBUS_OBJECT_PATH_MAX];
1066 /* Do nothing if the control interface is not turned on */
1067 if (wpa_s == NULL || wpa_s->global == NULL)
1069 ctrl_iface = wpa_s->global->dbus;
1070 if (ctrl_iface == NULL)
1073 os_snprintf(net_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
1074 "%s/" WPAS_DBUS_NEW_NETWORKS_PART "/%u",
1075 wpa_s->dbus_new_path, ssid->id);
1077 wpa_printf(MSG_DEBUG, "dbus: Register network object '%s'",
1079 obj_desc = os_zalloc(sizeof(struct wpa_dbus_object_desc));
1081 wpa_printf(MSG_ERROR, "Not enough memory "
1082 "to create object description");
1086 /* allocate memory for handlers arguments */
1087 arg = os_zalloc(sizeof(struct network_handler_args));
1089 wpa_printf(MSG_ERROR, "Not enough memory "
1090 "to create arguments for method");
1097 wpas_dbus_register(obj_desc, arg, wpa_dbus_free, NULL,
1098 wpas_dbus_network_properties,
1099 wpas_dbus_network_signals);
1101 if (wpa_dbus_register_object_per_iface(ctrl_iface, net_obj_path,
1102 wpa_s->ifname, obj_desc))
1105 wpas_dbus_signal_network_added(wpa_s, ssid->id);
1117 * wpas_dbus_unregister_network - Unregister a configured network from dbus
1118 * @wpa_s: wpa_supplicant interface structure
1120 * Returns: 0 on success, -1 on failure
1122 * Unregisters network representing object from dbus
1124 int wpas_dbus_unregister_network(struct wpa_supplicant *wpa_s, int nid)
1126 struct wpas_dbus_priv *ctrl_iface;
1127 char net_obj_path[WPAS_DBUS_OBJECT_PATH_MAX];
1130 /* Do nothing if the control interface is not turned on */
1131 if (wpa_s == NULL || wpa_s->global == NULL)
1133 ctrl_iface = wpa_s->global->dbus;
1134 if (ctrl_iface == NULL)
1137 os_snprintf(net_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
1138 "%s/" WPAS_DBUS_NEW_NETWORKS_PART "/%u",
1139 wpa_s->dbus_new_path, nid);
1141 wpa_printf(MSG_DEBUG, "dbus: Unregister network object '%s'",
1143 ret = wpa_dbus_unregister_object_per_iface(ctrl_iface, net_obj_path);
1146 wpas_dbus_signal_network_removed(wpa_s, nid);
1152 static const struct wpas_dbus_property wpas_dbus_bss_properties[] = {
1153 { "SSID", WPAS_DBUS_NEW_IFACE_BSSID, "ay",
1154 (WPADBusPropertyAccessor) wpas_dbus_getter_bss_ssid,
1158 { "BSSID", WPAS_DBUS_NEW_IFACE_BSSID, "ay",
1159 (WPADBusPropertyAccessor) wpas_dbus_getter_bss_bssid,
1163 { "Privacy", WPAS_DBUS_NEW_IFACE_BSSID, "b",
1164 (WPADBusPropertyAccessor) wpas_dbus_getter_bss_privacy,
1168 { "Mode", WPAS_DBUS_NEW_IFACE_BSSID, "s",
1169 (WPADBusPropertyAccessor) wpas_dbus_getter_bss_mode,
1173 { "Signal", WPAS_DBUS_NEW_IFACE_BSSID, "n",
1174 (WPADBusPropertyAccessor) wpas_dbus_getter_bss_signal,
1178 { "Frequency", WPAS_DBUS_NEW_IFACE_BSSID, "q",
1179 (WPADBusPropertyAccessor) wpas_dbus_getter_bss_frequency,
1183 { "MaxRate", WPAS_DBUS_NEW_IFACE_BSSID, "q",
1184 (WPADBusPropertyAccessor) wpas_dbus_getter_bss_max_rate,
1188 { "WPAIE", WPAS_DBUS_NEW_IFACE_BSSID, "ay",
1189 (WPADBusPropertyAccessor) wpas_dbus_getter_bss_wpaie,
1193 { "RSNIE", WPAS_DBUS_NEW_IFACE_BSSID, "ay",
1194 (WPADBusPropertyAccessor) wpas_dbus_getter_bss_rsnie,
1198 { "WPSIE", WPAS_DBUS_NEW_IFACE_BSSID, "ay",
1199 (WPADBusPropertyAccessor) wpas_dbus_getter_bss_wpsie,
1203 { NULL, NULL, NULL, NULL, NULL, 0 }
1207 static const struct wpas_dbus_signal wpas_dbus_bss_signals[] = {
1208 { "PropertiesChanged", WPAS_DBUS_NEW_IFACE_BSSID,
1210 { "properties", "a{sv}", ARG_OUT },
1214 { NULL, NULL, { END_ARGS } }
1219 * wpas_dbus_unregister_bss - Unregister a scanned BSS from dbus
1220 * @wpa_s: wpa_supplicant interface structure
1221 * @bssid: scanned network bssid
1222 * @id: unique BSS identifier
1223 * Returns: 0 on success, -1 on failure
1225 * Unregisters BSS representing object from dbus
1227 int wpas_dbus_unregister_bss(struct wpa_supplicant *wpa_s,
1228 u8 bssid[ETH_ALEN], unsigned int id)
1230 struct wpas_dbus_priv *ctrl_iface;
1231 char bss_obj_path[WPAS_DBUS_OBJECT_PATH_MAX];
1233 /* Do nothing if the control interface is not turned on */
1234 if (wpa_s == NULL || wpa_s->global == NULL)
1236 ctrl_iface = wpa_s->global->dbus;
1237 if (ctrl_iface == NULL)
1240 os_snprintf(bss_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
1241 "%s/" WPAS_DBUS_NEW_BSSIDS_PART "/%u",
1242 wpa_s->dbus_new_path, id);
1244 wpa_printf(MSG_DEBUG, "dbus: Unregister BSS object '%s'",
1246 if (wpa_dbus_unregister_object_per_iface(ctrl_iface, bss_obj_path)) {
1247 wpa_printf(MSG_ERROR, "dbus: Cannot unregister BSS object %s",
1252 wpas_dbus_signal_bss_removed(wpa_s, bss_obj_path);
1259 * wpas_dbus_register_bss - Register a scanned BSS with dbus
1260 * @wpa_s: wpa_supplicant interface structure
1261 * @bssid: scanned network bssid
1262 * @id: unique BSS identifier
1263 * Returns: 0 on success, -1 on failure
1265 * Registers BSS representing object with dbus
1267 int wpas_dbus_register_bss(struct wpa_supplicant *wpa_s,
1268 u8 bssid[ETH_ALEN], unsigned int id)
1270 struct wpas_dbus_priv *ctrl_iface;
1271 struct wpa_dbus_object_desc *obj_desc;
1272 char bss_obj_path[WPAS_DBUS_OBJECT_PATH_MAX];
1273 struct bss_handler_args *arg = NULL;
1275 /* Do nothing if the control interface is not turned on */
1276 if (wpa_s == NULL || wpa_s->global == NULL)
1278 ctrl_iface = wpa_s->global->dbus;
1279 if (ctrl_iface == NULL)
1282 os_snprintf(bss_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
1283 "%s/" WPAS_DBUS_NEW_BSSIDS_PART "/%u",
1284 wpa_s->dbus_new_path, id);
1286 obj_desc = os_zalloc(sizeof(struct wpa_dbus_object_desc));
1288 wpa_printf(MSG_ERROR, "Not enough memory "
1289 "to create object description");
1293 arg = os_zalloc(sizeof(struct bss_handler_args));
1295 wpa_printf(MSG_ERROR, "Not enough memory "
1296 "to create arguments for handler");
1302 wpas_dbus_register(obj_desc, arg, wpa_dbus_free, NULL,
1303 wpas_dbus_bss_properties,
1304 wpas_dbus_bss_signals);
1306 wpa_printf(MSG_DEBUG, "dbus: Register BSS object '%s'",
1308 if (wpa_dbus_register_object_per_iface(ctrl_iface, bss_obj_path,
1309 wpa_s->ifname, obj_desc)) {
1310 wpa_printf(MSG_ERROR,
1311 "Cannot register BSSID dbus object %s.",
1316 wpas_dbus_signal_bss_added(wpa_s, bss_obj_path);
1327 static const struct wpas_dbus_method wpas_dbus_interface_methods[] = {
1328 { "Scan", WPAS_DBUS_NEW_IFACE_INTERFACE,
1329 (WPADBusMethodHandler) &wpas_dbus_handler_scan,
1331 { "args", "a{sv}", ARG_IN },
1335 { "Disconnect", WPAS_DBUS_NEW_IFACE_INTERFACE,
1336 (WPADBusMethodHandler) &wpas_dbus_handler_disconnect,
1341 { "AddNetwork", WPAS_DBUS_NEW_IFACE_INTERFACE,
1342 (WPADBusMethodHandler) &wpas_dbus_handler_add_network,
1344 { "args", "a{sv}", ARG_IN },
1345 { "path", "o", ARG_OUT },
1349 { "RemoveNetwork", WPAS_DBUS_NEW_IFACE_INTERFACE,
1350 (WPADBusMethodHandler) &wpas_dbus_handler_remove_network,
1352 { "path", "o", ARG_IN },
1356 { "SelectNetwork", WPAS_DBUS_NEW_IFACE_INTERFACE,
1357 (WPADBusMethodHandler) &wpas_dbus_handler_select_network,
1359 { "path", "o", ARG_IN },
1363 { "AddBlob", WPAS_DBUS_NEW_IFACE_INTERFACE,
1364 (WPADBusMethodHandler) &wpas_dbus_handler_add_blob,
1366 { "name", "s", ARG_IN },
1367 { "data", "ay", ARG_IN },
1371 { "GetBlob", WPAS_DBUS_NEW_IFACE_INTERFACE,
1372 (WPADBusMethodHandler) &wpas_dbus_handler_get_blob,
1374 { "name", "s", ARG_IN },
1375 { "data", "ay", ARG_OUT },
1379 { "RemoveBlob", WPAS_DBUS_NEW_IFACE_INTERFACE,
1380 (WPADBusMethodHandler) &wpas_dbus_handler_remove_blob,
1382 { "name", "s", ARG_IN },
1387 { "Start", WPAS_DBUS_NEW_IFACE_WPS,
1388 (WPADBusMethodHandler) &wpas_dbus_handler_wps_start,
1390 { "args", "a{sv}", ARG_IN },
1391 { "output", "a{sv}", ARG_OUT },
1395 #endif /* CONFIG_WPS */
1396 { NULL, NULL, NULL, { END_ARGS } }
1399 static const struct wpas_dbus_property wpas_dbus_interface_properties[] = {
1400 { "Capabilities", WPAS_DBUS_NEW_IFACE_INTERFACE, "a{sv}",
1401 (WPADBusPropertyAccessor) wpas_dbus_getter_capabilities,
1404 { "State", WPAS_DBUS_NEW_IFACE_INTERFACE, "s",
1405 (WPADBusPropertyAccessor) wpas_dbus_getter_state,
1408 { "Scanning", WPAS_DBUS_NEW_IFACE_INTERFACE, "b",
1409 (WPADBusPropertyAccessor) wpas_dbus_getter_scanning,
1412 { "ApScan", WPAS_DBUS_NEW_IFACE_INTERFACE, "u",
1413 (WPADBusPropertyAccessor) wpas_dbus_getter_ap_scan,
1414 (WPADBusPropertyAccessor) wpas_dbus_setter_ap_scan,
1417 { "Ifname", WPAS_DBUS_NEW_IFACE_INTERFACE, "s",
1418 (WPADBusPropertyAccessor) wpas_dbus_getter_ifname,
1421 { "Driver", WPAS_DBUS_NEW_IFACE_INTERFACE, "s",
1422 (WPADBusPropertyAccessor) wpas_dbus_getter_driver,
1425 { "BridgeIfname", WPAS_DBUS_NEW_IFACE_INTERFACE, "s",
1426 (WPADBusPropertyAccessor) wpas_dbus_getter_bridge_ifname,
1429 { "CurrentBSS", WPAS_DBUS_NEW_IFACE_INTERFACE, "o",
1430 (WPADBusPropertyAccessor) wpas_dbus_getter_current_bss,
1433 { "CurrentNetwork", WPAS_DBUS_NEW_IFACE_INTERFACE, "o",
1434 (WPADBusPropertyAccessor) wpas_dbus_getter_current_network,
1437 { "Blobs", WPAS_DBUS_NEW_IFACE_INTERFACE, "a{say}",
1438 (WPADBusPropertyAccessor) wpas_dbus_getter_blobs,
1441 { "BSSs", WPAS_DBUS_NEW_IFACE_INTERFACE, "ao",
1442 (WPADBusPropertyAccessor) wpas_dbus_getter_bsss,
1445 { "Networks", WPAS_DBUS_NEW_IFACE_INTERFACE, "ao",
1446 (WPADBusPropertyAccessor) wpas_dbus_getter_networks,
1450 { "ProcessCredentials", WPAS_DBUS_NEW_IFACE_WPS, "b",
1451 (WPADBusPropertyAccessor) wpas_dbus_getter_process_credentials,
1452 (WPADBusPropertyAccessor) wpas_dbus_setter_process_credentials,
1455 #endif /* CONFIG_WPS */
1456 { NULL, NULL, NULL, NULL, NULL, 0 }
1459 static const struct wpas_dbus_signal wpas_dbus_interface_signals[] = {
1460 { "ScanDone", WPAS_DBUS_NEW_IFACE_INTERFACE,
1462 { "success", "b", ARG_OUT },
1466 { "StateChanged", WPAS_DBUS_NEW_IFACE_INTERFACE,
1468 { "newState", "s", ARG_OUT },
1469 { "oldState", "s", ARG_OUT },
1473 { "BSSAdded", WPAS_DBUS_NEW_IFACE_INTERFACE,
1475 { "path", "o", ARG_OUT },
1476 { "properties", "a{sv}", ARG_OUT },
1480 { "BSSRemoved", WPAS_DBUS_NEW_IFACE_INTERFACE,
1482 { "path", "o", ARG_OUT },
1486 { "BlobAdded", WPAS_DBUS_NEW_IFACE_INTERFACE,
1488 { "name", "s", ARG_OUT },
1492 { "BlobRemoved", WPAS_DBUS_NEW_IFACE_INTERFACE,
1494 { "name", "s", ARG_OUT },
1498 { "NetworkAdded", WPAS_DBUS_NEW_IFACE_INTERFACE,
1500 { "path", "o", ARG_OUT },
1501 { "properties", "a{sv}", ARG_OUT },
1505 { "NetworkRemoved", WPAS_DBUS_NEW_IFACE_INTERFACE,
1507 { "path", "o", ARG_OUT },
1511 { "NetworkSelected", WPAS_DBUS_NEW_IFACE_INTERFACE,
1513 { "path", "o", ARG_OUT },
1517 { "PropertiesChanged", WPAS_DBUS_NEW_IFACE_INTERFACE,
1519 { "properties", "a{sv}", ARG_OUT },
1524 { "Event", WPAS_DBUS_NEW_IFACE_WPS,
1526 { "name", "s", ARG_OUT },
1527 { "args", "a{sv}", ARG_OUT },
1531 { "Credentials", WPAS_DBUS_NEW_IFACE_WPS,
1533 { "credentials", "a{sv}", ARG_OUT },
1537 { "PropertiesChanged", WPAS_DBUS_NEW_IFACE_WPS,
1539 { "properties", "a{sv}", ARG_OUT },
1543 #endif /* CONFIG_WPS */
1544 { NULL, NULL, { END_ARGS } }
1548 int wpas_dbus_register_interface(struct wpa_supplicant *wpa_s)
1551 struct wpa_dbus_object_desc *obj_desc = NULL;
1552 struct wpas_dbus_priv *ctrl_iface = wpa_s->global->dbus;
1555 /* Do nothing if the control interface is not turned on */
1556 if (ctrl_iface == NULL)
1559 /* Create and set the interface's object path */
1560 wpa_s->dbus_new_path = os_zalloc(WPAS_DBUS_OBJECT_PATH_MAX);
1561 if (wpa_s->dbus_new_path == NULL)
1563 next = ctrl_iface->next_objid++;
1564 os_snprintf(wpa_s->dbus_new_path, WPAS_DBUS_OBJECT_PATH_MAX,
1565 WPAS_DBUS_NEW_PATH_INTERFACES "/%u",
1568 obj_desc = os_zalloc(sizeof(struct wpa_dbus_object_desc));
1570 wpa_printf(MSG_ERROR, "Not enough memory "
1571 "to create object description");
1575 wpas_dbus_register(obj_desc, wpa_s, NULL, wpas_dbus_interface_methods,
1576 wpas_dbus_interface_properties,
1577 wpas_dbus_interface_signals);
1579 wpa_printf(MSG_DEBUG, "dbus: Register interface object '%s'",
1580 wpa_s->dbus_new_path);
1581 if (wpa_dbus_register_object_per_iface(ctrl_iface,
1582 wpa_s->dbus_new_path,
1583 wpa_s->ifname, obj_desc))
1586 wpas_dbus_signal_interface_added(wpa_s);
1591 os_free(wpa_s->dbus_new_path);
1592 wpa_s->dbus_new_path = NULL;
1598 int wpas_dbus_unregister_interface(struct wpa_supplicant *wpa_s)
1600 struct wpas_dbus_priv *ctrl_iface;
1602 /* Do nothing if the control interface is not turned on */
1603 if (wpa_s == NULL || wpa_s->global == NULL)
1605 ctrl_iface = wpa_s->global->dbus;
1606 if (ctrl_iface == NULL)
1609 wpa_printf(MSG_DEBUG, "dbus: Unregister interface object '%s'",
1610 wpa_s->dbus_new_path);
1611 if (wpa_dbus_unregister_object_per_iface(ctrl_iface,
1612 wpa_s->dbus_new_path))
1615 wpas_dbus_signal_interface_removed(wpa_s);
1617 os_free(wpa_s->dbus_new_path);
1618 wpa_s->dbus_new_path = NULL;