xref: /freebsd/contrib/wpa/wpa_supplicant/dbus/dbus_common.c (revision c1d255d3ffdbe447de3ab875bf4e7d7accc5bfc5)
1d4f2939cSRui Paulo /*
2d4f2939cSRui Paulo  * wpa_supplicant D-Bus control interface - common functionality
3d4f2939cSRui Paulo  * Copyright (c) 2006, Dan Williams <dcbw@redhat.com> and Red Hat, Inc.
4d4f2939cSRui Paulo  * Copyright (c) 2009, Witold Sowa <witold.sowa@gmail.com>
5d4f2939cSRui Paulo  * Copyright (c) 2009, Jouni Malinen <j@w1.fi>
6d4f2939cSRui Paulo  *
7d4f2939cSRui Paulo  * This software may be distributed under the terms of the BSD license.
8d4f2939cSRui Paulo  * See README for more details.
9d4f2939cSRui Paulo  */
10d4f2939cSRui Paulo 
11d4f2939cSRui Paulo #include "utils/includes.h"
12d4f2939cSRui Paulo #include <dbus/dbus.h>
13d4f2939cSRui Paulo 
14d4f2939cSRui Paulo #include "utils/common.h"
15d4f2939cSRui Paulo #include "utils/eloop.h"
16d4f2939cSRui Paulo #include "dbus_common.h"
17d4f2939cSRui Paulo #include "dbus_common_i.h"
18d4f2939cSRui Paulo #include "dbus_new.h"
195b9c547cSRui Paulo #include "../wpa_supplicant_i.h"
20d4f2939cSRui Paulo 
21d4f2939cSRui Paulo 
22d4f2939cSRui Paulo #ifndef SIGPOLL
23d4f2939cSRui Paulo #ifdef SIGIO
24d4f2939cSRui Paulo /*
25d4f2939cSRui Paulo  * If we do not have SIGPOLL, try to use SIGIO instead. This is needed for
26d4f2939cSRui Paulo  * FreeBSD.
27d4f2939cSRui Paulo  */
28d4f2939cSRui Paulo #define SIGPOLL SIGIO
29d4f2939cSRui Paulo #endif
30d4f2939cSRui Paulo #endif
31d4f2939cSRui Paulo 
32d4f2939cSRui Paulo 
dispatch_data(DBusConnection * con)33d4f2939cSRui Paulo static void dispatch_data(DBusConnection *con)
34d4f2939cSRui Paulo {
35d4f2939cSRui Paulo 	while (dbus_connection_get_dispatch_status(con) ==
36d4f2939cSRui Paulo 	       DBUS_DISPATCH_DATA_REMAINS)
37d4f2939cSRui Paulo 		dbus_connection_dispatch(con);
38d4f2939cSRui Paulo }
39d4f2939cSRui Paulo 
40d4f2939cSRui Paulo 
41d4f2939cSRui Paulo /**
42d4f2939cSRui Paulo  * dispatch_initial_dbus_messages - Dispatch initial dbus messages after
43d4f2939cSRui Paulo  *     claiming bus name
44d4f2939cSRui Paulo  * @eloop_ctx: the DBusConnection to dispatch on
45d4f2939cSRui Paulo  * @timeout_ctx: unused
46d4f2939cSRui Paulo  *
47d4f2939cSRui Paulo  * If clients are quick to notice that service claimed its bus name,
48d4f2939cSRui Paulo  * there may have been messages that came in before initialization was
49d4f2939cSRui Paulo  * all finished.  Dispatch those here.
50d4f2939cSRui Paulo  */
dispatch_initial_dbus_messages(void * eloop_ctx,void * timeout_ctx)51d4f2939cSRui Paulo static void dispatch_initial_dbus_messages(void *eloop_ctx, void *timeout_ctx)
52d4f2939cSRui Paulo {
53d4f2939cSRui Paulo 	DBusConnection *con = eloop_ctx;
54d4f2939cSRui Paulo 	dispatch_data(con);
55d4f2939cSRui Paulo }
56d4f2939cSRui Paulo 
57d4f2939cSRui Paulo 
process_watch(struct wpas_dbus_priv * priv,DBusWatch * watch,eloop_event_type type)58d4f2939cSRui Paulo static void process_watch(struct wpas_dbus_priv *priv,
59d4f2939cSRui Paulo 			  DBusWatch *watch, eloop_event_type type)
60d4f2939cSRui Paulo {
61d4f2939cSRui Paulo 	dbus_connection_ref(priv->con);
62d4f2939cSRui Paulo 
63d4f2939cSRui Paulo 	priv->should_dispatch = 0;
64d4f2939cSRui Paulo 
65d4f2939cSRui Paulo 	if (type == EVENT_TYPE_READ)
66d4f2939cSRui Paulo 		dbus_watch_handle(watch, DBUS_WATCH_READABLE);
67d4f2939cSRui Paulo 	else if (type == EVENT_TYPE_WRITE)
68d4f2939cSRui Paulo 		dbus_watch_handle(watch, DBUS_WATCH_WRITABLE);
69d4f2939cSRui Paulo 	else if (type == EVENT_TYPE_EXCEPTION)
70d4f2939cSRui Paulo 		dbus_watch_handle(watch, DBUS_WATCH_ERROR);
71d4f2939cSRui Paulo 
72d4f2939cSRui Paulo 	if (priv->should_dispatch) {
73d4f2939cSRui Paulo 		dispatch_data(priv->con);
74d4f2939cSRui Paulo 		priv->should_dispatch = 0;
75d4f2939cSRui Paulo 	}
76d4f2939cSRui Paulo 
77d4f2939cSRui Paulo 	dbus_connection_unref(priv->con);
78d4f2939cSRui Paulo }
79d4f2939cSRui Paulo 
80d4f2939cSRui Paulo 
process_watch_exception(int sock,void * eloop_ctx,void * sock_ctx)81d4f2939cSRui Paulo static void process_watch_exception(int sock, void *eloop_ctx, void *sock_ctx)
82d4f2939cSRui Paulo {
83d4f2939cSRui Paulo 	process_watch(eloop_ctx, sock_ctx, EVENT_TYPE_EXCEPTION);
84d4f2939cSRui Paulo }
85d4f2939cSRui Paulo 
86d4f2939cSRui Paulo 
process_watch_read(int sock,void * eloop_ctx,void * sock_ctx)87d4f2939cSRui Paulo static void process_watch_read(int sock, void *eloop_ctx, void *sock_ctx)
88d4f2939cSRui Paulo {
89d4f2939cSRui Paulo 	process_watch(eloop_ctx, sock_ctx, EVENT_TYPE_READ);
90d4f2939cSRui Paulo }
91d4f2939cSRui Paulo 
92d4f2939cSRui Paulo 
process_watch_write(int sock,void * eloop_ctx,void * sock_ctx)93d4f2939cSRui Paulo static void process_watch_write(int sock, void *eloop_ctx, void *sock_ctx)
94d4f2939cSRui Paulo {
95d4f2939cSRui Paulo 	process_watch(eloop_ctx, sock_ctx, EVENT_TYPE_WRITE);
96d4f2939cSRui Paulo }
97d4f2939cSRui Paulo 
98d4f2939cSRui Paulo 
add_watch(DBusWatch * watch,void * data)99d4f2939cSRui Paulo static dbus_bool_t add_watch(DBusWatch *watch, void *data)
100d4f2939cSRui Paulo {
101d4f2939cSRui Paulo 	struct wpas_dbus_priv *priv = data;
102d4f2939cSRui Paulo 	unsigned int flags;
103d4f2939cSRui Paulo 	int fd;
104d4f2939cSRui Paulo 
105d4f2939cSRui Paulo 	if (!dbus_watch_get_enabled(watch))
106d4f2939cSRui Paulo 		return TRUE;
107d4f2939cSRui Paulo 
108d4f2939cSRui Paulo 	flags = dbus_watch_get_flags(watch);
109d4f2939cSRui Paulo 	fd = dbus_watch_get_unix_fd(watch);
110d4f2939cSRui Paulo 
111*c1d255d3SCy Schubert 	if (eloop_register_sock(fd, EVENT_TYPE_EXCEPTION,
112*c1d255d3SCy Schubert 				process_watch_exception, priv, watch) < 0)
113*c1d255d3SCy Schubert 		return FALSE;
114d4f2939cSRui Paulo 
115*c1d255d3SCy Schubert 	if ((flags & DBUS_WATCH_READABLE) &&
116d4f2939cSRui Paulo 	    eloop_register_sock(fd, EVENT_TYPE_READ, process_watch_read,
117*c1d255d3SCy Schubert 				priv, watch) < 0)
118*c1d255d3SCy Schubert 		return FALSE;
119*c1d255d3SCy Schubert 	if ((flags & DBUS_WATCH_WRITABLE) &&
120d4f2939cSRui Paulo 	    eloop_register_sock(fd, EVENT_TYPE_WRITE, process_watch_write,
121*c1d255d3SCy Schubert 				priv, watch) < 0)
122*c1d255d3SCy Schubert 		return FALSE;
123d4f2939cSRui Paulo 
124d4f2939cSRui Paulo 	dbus_watch_set_data(watch, priv, NULL);
125d4f2939cSRui Paulo 
126d4f2939cSRui Paulo 	return TRUE;
127d4f2939cSRui Paulo }
128d4f2939cSRui Paulo 
129d4f2939cSRui Paulo 
remove_watch(DBusWatch * watch,void * data)130d4f2939cSRui Paulo static void remove_watch(DBusWatch *watch, void *data)
131d4f2939cSRui Paulo {
132d4f2939cSRui Paulo 	unsigned int flags;
133d4f2939cSRui Paulo 	int fd;
134d4f2939cSRui Paulo 
135d4f2939cSRui Paulo 	flags = dbus_watch_get_flags(watch);
136d4f2939cSRui Paulo 	fd = dbus_watch_get_unix_fd(watch);
137d4f2939cSRui Paulo 
138d4f2939cSRui Paulo 	eloop_unregister_sock(fd, EVENT_TYPE_EXCEPTION);
139d4f2939cSRui Paulo 
140d4f2939cSRui Paulo 	if (flags & DBUS_WATCH_READABLE)
141d4f2939cSRui Paulo 		eloop_unregister_sock(fd, EVENT_TYPE_READ);
142d4f2939cSRui Paulo 	if (flags & DBUS_WATCH_WRITABLE)
143d4f2939cSRui Paulo 		eloop_unregister_sock(fd, EVENT_TYPE_WRITE);
144d4f2939cSRui Paulo 
145d4f2939cSRui Paulo 	dbus_watch_set_data(watch, NULL, NULL);
146d4f2939cSRui Paulo }
147d4f2939cSRui Paulo 
148d4f2939cSRui Paulo 
watch_toggled(DBusWatch * watch,void * data)149d4f2939cSRui Paulo static void watch_toggled(DBusWatch *watch, void *data)
150d4f2939cSRui Paulo {
151d4f2939cSRui Paulo 	if (dbus_watch_get_enabled(watch))
152d4f2939cSRui Paulo 		add_watch(watch, data);
153d4f2939cSRui Paulo 	else
154d4f2939cSRui Paulo 		remove_watch(watch, data);
155d4f2939cSRui Paulo }
156d4f2939cSRui Paulo 
157d4f2939cSRui Paulo 
process_timeout(void * eloop_ctx,void * sock_ctx)158d4f2939cSRui Paulo static void process_timeout(void *eloop_ctx, void *sock_ctx)
159d4f2939cSRui Paulo {
160d4f2939cSRui Paulo 	DBusTimeout *timeout = sock_ctx;
161d4f2939cSRui Paulo 	dbus_timeout_handle(timeout);
162d4f2939cSRui Paulo }
163d4f2939cSRui Paulo 
164d4f2939cSRui Paulo 
add_timeout(DBusTimeout * timeout,void * data)165d4f2939cSRui Paulo static dbus_bool_t add_timeout(DBusTimeout *timeout, void *data)
166d4f2939cSRui Paulo {
167d4f2939cSRui Paulo 	struct wpas_dbus_priv *priv = data;
1685b9c547cSRui Paulo 
169d4f2939cSRui Paulo 	if (!dbus_timeout_get_enabled(timeout))
170d4f2939cSRui Paulo 		return TRUE;
171d4f2939cSRui Paulo 
172d4f2939cSRui Paulo 	eloop_register_timeout(0, dbus_timeout_get_interval(timeout) * 1000,
173d4f2939cSRui Paulo 			       process_timeout, priv, timeout);
174d4f2939cSRui Paulo 
175d4f2939cSRui Paulo 	dbus_timeout_set_data(timeout, priv, NULL);
176d4f2939cSRui Paulo 
177d4f2939cSRui Paulo 	return TRUE;
178d4f2939cSRui Paulo }
179d4f2939cSRui Paulo 
180d4f2939cSRui Paulo 
remove_timeout(DBusTimeout * timeout,void * data)181d4f2939cSRui Paulo static void remove_timeout(DBusTimeout *timeout, void *data)
182d4f2939cSRui Paulo {
183d4f2939cSRui Paulo 	struct wpas_dbus_priv *priv = data;
1845b9c547cSRui Paulo 
185d4f2939cSRui Paulo 	eloop_cancel_timeout(process_timeout, priv, timeout);
186d4f2939cSRui Paulo 	dbus_timeout_set_data(timeout, NULL, NULL);
187d4f2939cSRui Paulo }
188d4f2939cSRui Paulo 
189d4f2939cSRui Paulo 
timeout_toggled(DBusTimeout * timeout,void * data)190d4f2939cSRui Paulo static void timeout_toggled(DBusTimeout *timeout, void *data)
191d4f2939cSRui Paulo {
192d4f2939cSRui Paulo 	if (dbus_timeout_get_enabled(timeout))
193d4f2939cSRui Paulo 		add_timeout(timeout, data);
194d4f2939cSRui Paulo 	else
195d4f2939cSRui Paulo 		remove_timeout(timeout, data);
196d4f2939cSRui Paulo }
197d4f2939cSRui Paulo 
198d4f2939cSRui Paulo 
process_wakeup_main(int sig,void * signal_ctx)199d4f2939cSRui Paulo static void process_wakeup_main(int sig, void *signal_ctx)
200d4f2939cSRui Paulo {
201d4f2939cSRui Paulo 	struct wpas_dbus_priv *priv = signal_ctx;
202d4f2939cSRui Paulo 
203d4f2939cSRui Paulo 	if (sig != SIGPOLL || !priv->con)
204d4f2939cSRui Paulo 		return;
205d4f2939cSRui Paulo 
206d4f2939cSRui Paulo 	if (dbus_connection_get_dispatch_status(priv->con) !=
207d4f2939cSRui Paulo 	    DBUS_DISPATCH_DATA_REMAINS)
208d4f2939cSRui Paulo 		return;
209d4f2939cSRui Paulo 
210d4f2939cSRui Paulo 	/* Only dispatch once - we do not want to starve other events */
211d4f2939cSRui Paulo 	dbus_connection_ref(priv->con);
212d4f2939cSRui Paulo 	dbus_connection_dispatch(priv->con);
213d4f2939cSRui Paulo 	dbus_connection_unref(priv->con);
214d4f2939cSRui Paulo }
215d4f2939cSRui Paulo 
216d4f2939cSRui Paulo 
217d4f2939cSRui Paulo /**
218d4f2939cSRui Paulo  * wakeup_main - Attempt to wake our mainloop up
219d4f2939cSRui Paulo  * @data: dbus control interface private data
220d4f2939cSRui Paulo  *
221d4f2939cSRui Paulo  * Try to wake up the main eloop so it will process
222d4f2939cSRui Paulo  * dbus events that may have happened.
223d4f2939cSRui Paulo  */
wakeup_main(void * data)224d4f2939cSRui Paulo static void wakeup_main(void *data)
225d4f2939cSRui Paulo {
226d4f2939cSRui Paulo 	struct wpas_dbus_priv *priv = data;
227d4f2939cSRui Paulo 
228d4f2939cSRui Paulo 	/* Use SIGPOLL to break out of the eloop select() */
229d4f2939cSRui Paulo 	raise(SIGPOLL);
230d4f2939cSRui Paulo 	priv->should_dispatch = 1;
231d4f2939cSRui Paulo }
232d4f2939cSRui Paulo 
233d4f2939cSRui Paulo 
234d4f2939cSRui Paulo /**
235d4f2939cSRui Paulo  * integrate_with_eloop - Register our mainloop integration with dbus
236d4f2939cSRui Paulo  * @connection: connection to the system message bus
237d4f2939cSRui Paulo  * @priv: a dbus control interface data structure
238d4f2939cSRui Paulo  * Returns: 0 on success, -1 on failure
239d4f2939cSRui Paulo  */
integrate_with_eloop(struct wpas_dbus_priv * priv)240d4f2939cSRui Paulo static int integrate_with_eloop(struct wpas_dbus_priv *priv)
241d4f2939cSRui Paulo {
242d4f2939cSRui Paulo 	if (!dbus_connection_set_watch_functions(priv->con, add_watch,
243d4f2939cSRui Paulo 						 remove_watch, watch_toggled,
244d4f2939cSRui Paulo 						 priv, NULL) ||
245d4f2939cSRui Paulo 	    !dbus_connection_set_timeout_functions(priv->con, add_timeout,
246d4f2939cSRui Paulo 						   remove_timeout,
247d4f2939cSRui Paulo 						   timeout_toggled, priv,
248d4f2939cSRui Paulo 						   NULL)) {
2495b9c547cSRui Paulo 		wpa_printf(MSG_ERROR, "dbus: Failed to set callback functions");
250d4f2939cSRui Paulo 		return -1;
251d4f2939cSRui Paulo 	}
252d4f2939cSRui Paulo 
253d4f2939cSRui Paulo 	if (eloop_register_signal(SIGPOLL, process_wakeup_main, priv))
254d4f2939cSRui Paulo 		return -1;
255d4f2939cSRui Paulo 	dbus_connection_set_wakeup_main_function(priv->con, wakeup_main,
256d4f2939cSRui Paulo 						 priv, NULL);
257d4f2939cSRui Paulo 
258d4f2939cSRui Paulo 	return 0;
259d4f2939cSRui Paulo }
260d4f2939cSRui Paulo 
261d4f2939cSRui Paulo 
disconnect_filter(DBusConnection * conn,DBusMessage * message,void * data)2625b9c547cSRui Paulo static DBusHandlerResult disconnect_filter(DBusConnection *conn,
2635b9c547cSRui Paulo 					   DBusMessage *message, void *data)
2645b9c547cSRui Paulo {
2655b9c547cSRui Paulo 	struct wpas_dbus_priv *priv = data;
2665b9c547cSRui Paulo 
2675b9c547cSRui Paulo 	if (dbus_message_is_signal(message, DBUS_INTERFACE_LOCAL,
2685b9c547cSRui Paulo 				   "Disconnected")) {
2695b9c547cSRui Paulo 		wpa_printf(MSG_DEBUG, "dbus: bus disconnected, terminating");
2705b9c547cSRui Paulo 		dbus_connection_set_exit_on_disconnect(conn, FALSE);
2715b9c547cSRui Paulo 		wpa_supplicant_terminate_proc(priv->global);
2725b9c547cSRui Paulo 		return DBUS_HANDLER_RESULT_HANDLED;
2735b9c547cSRui Paulo 	} else
2745b9c547cSRui Paulo 		return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
2755b9c547cSRui Paulo }
2765b9c547cSRui Paulo 
2775b9c547cSRui Paulo 
wpas_dbus_init_common(struct wpas_dbus_priv * priv)278d4f2939cSRui Paulo static int wpas_dbus_init_common(struct wpas_dbus_priv *priv)
279d4f2939cSRui Paulo {
280d4f2939cSRui Paulo 	DBusError error;
281d4f2939cSRui Paulo 	int ret = 0;
282d4f2939cSRui Paulo 
283d4f2939cSRui Paulo 	/* Get a reference to the system bus */
284d4f2939cSRui Paulo 	dbus_error_init(&error);
285d4f2939cSRui Paulo 	priv->con = dbus_bus_get(DBUS_BUS_SYSTEM, &error);
2865b9c547cSRui Paulo 	if (priv->con) {
2875b9c547cSRui Paulo 		dbus_connection_add_filter(priv->con, disconnect_filter, priv,
2885b9c547cSRui Paulo 					   NULL);
2895b9c547cSRui Paulo 	} else {
2905b9c547cSRui Paulo 		wpa_printf(MSG_ERROR,
2915b9c547cSRui Paulo 			   "dbus: Could not acquire the system bus: %s - %s",
2925b9c547cSRui Paulo 			   error.name, error.message);
293d4f2939cSRui Paulo 		ret = -1;
294d4f2939cSRui Paulo 	}
295d4f2939cSRui Paulo 	dbus_error_free(&error);
296d4f2939cSRui Paulo 
297d4f2939cSRui Paulo 	return ret;
298d4f2939cSRui Paulo }
299d4f2939cSRui Paulo 
300d4f2939cSRui Paulo 
wpas_dbus_init_common_finish(struct wpas_dbus_priv * priv)301d4f2939cSRui Paulo static int wpas_dbus_init_common_finish(struct wpas_dbus_priv *priv)
302d4f2939cSRui Paulo {
303d4f2939cSRui Paulo 	/* Tell dbus about our mainloop integration functions */
304d4f2939cSRui Paulo 	integrate_with_eloop(priv);
305d4f2939cSRui Paulo 
306d4f2939cSRui Paulo 	/*
307d4f2939cSRui Paulo 	 * Dispatch initial DBus messages that may have come in since the bus
308d4f2939cSRui Paulo 	 * name was claimed above. Happens when clients are quick to notice the
309d4f2939cSRui Paulo 	 * service.
310d4f2939cSRui Paulo 	 *
311d4f2939cSRui Paulo 	 * FIXME: is there a better solution to this problem?
312d4f2939cSRui Paulo 	 */
313d4f2939cSRui Paulo 	eloop_register_timeout(0, 50, dispatch_initial_dbus_messages,
314d4f2939cSRui Paulo 			       priv->con, NULL);
315d4f2939cSRui Paulo 
316d4f2939cSRui Paulo 	return 0;
317d4f2939cSRui Paulo }
318d4f2939cSRui Paulo 
319d4f2939cSRui Paulo 
wpas_dbus_deinit_common(struct wpas_dbus_priv * priv)320d4f2939cSRui Paulo static void wpas_dbus_deinit_common(struct wpas_dbus_priv *priv)
321d4f2939cSRui Paulo {
322d4f2939cSRui Paulo 	if (priv->con) {
323d4f2939cSRui Paulo 		eloop_cancel_timeout(dispatch_initial_dbus_messages,
324d4f2939cSRui Paulo 				     priv->con, NULL);
3255b9c547cSRui Paulo 		eloop_cancel_timeout(process_timeout, priv, ELOOP_ALL_CTX);
3265b9c547cSRui Paulo 
327d4f2939cSRui Paulo 		dbus_connection_set_watch_functions(priv->con, NULL, NULL,
328d4f2939cSRui Paulo 						    NULL, NULL, NULL);
329d4f2939cSRui Paulo 		dbus_connection_set_timeout_functions(priv->con, NULL, NULL,
330d4f2939cSRui Paulo 						      NULL, NULL, NULL);
3315b9c547cSRui Paulo 		dbus_connection_remove_filter(priv->con, disconnect_filter,
3325b9c547cSRui Paulo 					      priv);
3335b9c547cSRui Paulo 
334d4f2939cSRui Paulo 		dbus_connection_unref(priv->con);
335d4f2939cSRui Paulo 	}
336d4f2939cSRui Paulo 
337d4f2939cSRui Paulo 	os_free(priv);
338d4f2939cSRui Paulo }
339d4f2939cSRui Paulo 
340d4f2939cSRui Paulo 
wpas_dbus_init(struct wpa_global * global)341d4f2939cSRui Paulo struct wpas_dbus_priv * wpas_dbus_init(struct wpa_global *global)
342d4f2939cSRui Paulo {
343d4f2939cSRui Paulo 	struct wpas_dbus_priv *priv;
344d4f2939cSRui Paulo 
345d4f2939cSRui Paulo 	priv = os_zalloc(sizeof(*priv));
346d4f2939cSRui Paulo 	if (priv == NULL)
347d4f2939cSRui Paulo 		return NULL;
348d4f2939cSRui Paulo 	priv->global = global;
349d4f2939cSRui Paulo 
3505b9c547cSRui Paulo 	if (wpas_dbus_init_common(priv) < 0 ||
351d4f2939cSRui Paulo #ifdef CONFIG_CTRL_IFACE_DBUS_NEW
3525b9c547cSRui Paulo 	    wpas_dbus_ctrl_iface_init(priv) < 0 ||
353d4f2939cSRui Paulo #endif /* CONFIG_CTRL_IFACE_DBUS_NEW */
3545b9c547cSRui Paulo 	    wpas_dbus_init_common_finish(priv) < 0) {
355d4f2939cSRui Paulo 		wpas_dbus_deinit(priv);
356d4f2939cSRui Paulo 		return NULL;
357d4f2939cSRui Paulo 	}
358d4f2939cSRui Paulo 
359d4f2939cSRui Paulo 	return priv;
360d4f2939cSRui Paulo }
361d4f2939cSRui Paulo 
362d4f2939cSRui Paulo 
wpas_dbus_deinit(struct wpas_dbus_priv * priv)363d4f2939cSRui Paulo void wpas_dbus_deinit(struct wpas_dbus_priv *priv)
364d4f2939cSRui Paulo {
365d4f2939cSRui Paulo 	if (priv == NULL)
366d4f2939cSRui Paulo 		return;
367d4f2939cSRui Paulo 
368d4f2939cSRui Paulo #ifdef CONFIG_CTRL_IFACE_DBUS_NEW
369d4f2939cSRui Paulo 	wpas_dbus_ctrl_iface_deinit(priv);
370d4f2939cSRui Paulo #endif /* CONFIG_CTRL_IFACE_DBUS_NEW */
371d4f2939cSRui Paulo 
372d4f2939cSRui Paulo 	wpas_dbus_deinit_common(priv);
373d4f2939cSRui Paulo }
374