xref: /freebsd/contrib/wpa/wpa_supplicant/dbus/dbus_new.c (revision 32a95656b51ebefcdf3e0b02c110825f59abd26f)
1d4f2939cSRui Paulo /*
2d4f2939cSRui Paulo  * WPA Supplicant / dbus-based control interface
3d4f2939cSRui Paulo  * Copyright (c) 2006, Dan Williams <dcbw@redhat.com> and Red Hat, Inc.
4d4f2939cSRui Paulo  * Copyright (c) 2009-2010, 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 "includes.h"
12d4f2939cSRui Paulo 
13d4f2939cSRui Paulo #include "common.h"
14d4f2939cSRui Paulo #include "common/ieee802_11_defs.h"
15d4f2939cSRui Paulo #include "wps/wps.h"
164bc52338SCy Schubert #include "ap/sta_info.h"
17d4f2939cSRui Paulo #include "../config.h"
18d4f2939cSRui Paulo #include "../wpa_supplicant_i.h"
19d4f2939cSRui Paulo #include "../bss.h"
20d4f2939cSRui Paulo #include "../wpas_glue.h"
21d4f2939cSRui Paulo #include "dbus_new_helpers.h"
22d4f2939cSRui Paulo #include "dbus_dict_helpers.h"
23d4f2939cSRui Paulo #include "dbus_new.h"
24d4f2939cSRui Paulo #include "dbus_new_handlers.h"
25d4f2939cSRui Paulo #include "dbus_common_i.h"
26d4f2939cSRui Paulo #include "dbus_new_handlers_p2p.h"
27d4f2939cSRui Paulo #include "p2p/p2p.h"
285b9c547cSRui Paulo #include "../p2p_supplicant.h"
29d4f2939cSRui Paulo 
30d4f2939cSRui Paulo #ifdef CONFIG_AP /* until needed by something else */
31d4f2939cSRui Paulo 
32d4f2939cSRui Paulo /*
33d4f2939cSRui Paulo  * NameOwnerChanged handling
34d4f2939cSRui Paulo  *
35d4f2939cSRui Paulo  * Some services we provide allow an application to register for
36d4f2939cSRui Paulo  * a signal that it needs. While it can also unregister, we must
37d4f2939cSRui Paulo  * be prepared for the case where the application simply crashes
38d4f2939cSRui Paulo  * and thus doesn't clean up properly. The way to handle this in
39d4f2939cSRui Paulo  * DBus is to register for the NameOwnerChanged signal which will
40d4f2939cSRui Paulo  * signal an owner change to NULL if the peer closes the socket
41d4f2939cSRui Paulo  * for whatever reason.
42d4f2939cSRui Paulo  *
43d4f2939cSRui Paulo  * Handle this signal via a filter function whenever necessary.
44d4f2939cSRui Paulo  * The code below also handles refcounting in case in the future
45d4f2939cSRui Paulo  * there will be multiple instances of this subscription scheme.
46d4f2939cSRui Paulo  */
47d4f2939cSRui Paulo static const char wpas_dbus_noc_filter_str[] =
48d4f2939cSRui Paulo 	"interface=org.freedesktop.DBus,member=NameOwnerChanged";
49d4f2939cSRui Paulo 
50d4f2939cSRui Paulo 
51d4f2939cSRui Paulo static DBusHandlerResult noc_filter(DBusConnection *conn,
52d4f2939cSRui Paulo 				    DBusMessage *message, void *data)
53d4f2939cSRui Paulo {
54d4f2939cSRui Paulo 	struct wpas_dbus_priv *priv = data;
55d4f2939cSRui Paulo 
56d4f2939cSRui Paulo 	if (dbus_message_get_type(message) != DBUS_MESSAGE_TYPE_SIGNAL)
57d4f2939cSRui Paulo 		return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
58d4f2939cSRui Paulo 
59d4f2939cSRui Paulo 	if (dbus_message_is_signal(message, DBUS_INTERFACE_DBUS,
60d4f2939cSRui Paulo 				   "NameOwnerChanged")) {
61d4f2939cSRui Paulo 		const char *name;
62d4f2939cSRui Paulo 		const char *prev_owner;
63d4f2939cSRui Paulo 		const char *new_owner;
64d4f2939cSRui Paulo 		DBusError derr;
65d4f2939cSRui Paulo 		struct wpa_supplicant *wpa_s;
66d4f2939cSRui Paulo 
67d4f2939cSRui Paulo 		dbus_error_init(&derr);
68d4f2939cSRui Paulo 
69d4f2939cSRui Paulo 		if (!dbus_message_get_args(message, &derr,
70d4f2939cSRui Paulo 					   DBUS_TYPE_STRING, &name,
71d4f2939cSRui Paulo 					   DBUS_TYPE_STRING, &prev_owner,
72d4f2939cSRui Paulo 					   DBUS_TYPE_STRING, &new_owner,
73d4f2939cSRui Paulo 					   DBUS_TYPE_INVALID)) {
74d4f2939cSRui Paulo 			/* Ignore this error */
75d4f2939cSRui Paulo 			dbus_error_free(&derr);
76d4f2939cSRui Paulo 			return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
77d4f2939cSRui Paulo 		}
78d4f2939cSRui Paulo 
795b9c547cSRui Paulo 		for (wpa_s = priv->global->ifaces; wpa_s; wpa_s = wpa_s->next) {
80d4f2939cSRui Paulo 			if (wpa_s->preq_notify_peer != NULL &&
81d4f2939cSRui Paulo 			    os_strcmp(name, wpa_s->preq_notify_peer) == 0 &&
82d4f2939cSRui Paulo 			    (new_owner == NULL || os_strlen(new_owner) == 0)) {
83d4f2939cSRui Paulo 				/* probe request owner disconnected */
84d4f2939cSRui Paulo 				os_free(wpa_s->preq_notify_peer);
85d4f2939cSRui Paulo 				wpa_s->preq_notify_peer = NULL;
86d4f2939cSRui Paulo 				wpas_dbus_unsubscribe_noc(priv);
87d4f2939cSRui Paulo 			}
88d4f2939cSRui Paulo 		}
89d4f2939cSRui Paulo 	}
90d4f2939cSRui Paulo 
91d4f2939cSRui Paulo 	return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
92d4f2939cSRui Paulo }
93d4f2939cSRui Paulo 
94d4f2939cSRui Paulo 
95d4f2939cSRui Paulo void wpas_dbus_subscribe_noc(struct wpas_dbus_priv *priv)
96d4f2939cSRui Paulo {
97d4f2939cSRui Paulo 	priv->dbus_noc_refcnt++;
98d4f2939cSRui Paulo 	if (priv->dbus_noc_refcnt > 1)
99d4f2939cSRui Paulo 		return;
100d4f2939cSRui Paulo 
101d4f2939cSRui Paulo 	if (!dbus_connection_add_filter(priv->con, noc_filter, priv, NULL)) {
102d4f2939cSRui Paulo 		wpa_printf(MSG_ERROR, "dbus: failed to add filter");
103d4f2939cSRui Paulo 		return;
104d4f2939cSRui Paulo 	}
105d4f2939cSRui Paulo 
106d4f2939cSRui Paulo 	dbus_bus_add_match(priv->con, wpas_dbus_noc_filter_str, NULL);
107d4f2939cSRui Paulo }
108d4f2939cSRui Paulo 
109d4f2939cSRui Paulo 
110d4f2939cSRui Paulo void wpas_dbus_unsubscribe_noc(struct wpas_dbus_priv *priv)
111d4f2939cSRui Paulo {
112d4f2939cSRui Paulo 	priv->dbus_noc_refcnt--;
113d4f2939cSRui Paulo 	if (priv->dbus_noc_refcnt > 0)
114d4f2939cSRui Paulo 		return;
115d4f2939cSRui Paulo 
116d4f2939cSRui Paulo 	dbus_bus_remove_match(priv->con, wpas_dbus_noc_filter_str, NULL);
117d4f2939cSRui Paulo 	dbus_connection_remove_filter(priv->con, noc_filter, priv);
118d4f2939cSRui Paulo }
119d4f2939cSRui Paulo 
120d4f2939cSRui Paulo #endif /* CONFIG_AP */
121d4f2939cSRui Paulo 
122d4f2939cSRui Paulo 
123d4f2939cSRui Paulo /**
124d4f2939cSRui Paulo  * wpas_dbus_signal_interface - Send a interface related event signal
125d4f2939cSRui Paulo  * @wpa_s: %wpa_supplicant network interface data
126d4f2939cSRui Paulo  * @sig_name: signal name - InterfaceAdded or InterfaceRemoved
127d4f2939cSRui Paulo  * @properties: Whether to add second argument with object properties
128d4f2939cSRui Paulo  *
129d4f2939cSRui Paulo  * Notify listeners about event related with interface
130d4f2939cSRui Paulo  */
131d4f2939cSRui Paulo static void wpas_dbus_signal_interface(struct wpa_supplicant *wpa_s,
1324bc52338SCy Schubert 				       const char *sig_name,
1334bc52338SCy Schubert 				       dbus_bool_t properties)
134d4f2939cSRui Paulo {
135d4f2939cSRui Paulo 	struct wpas_dbus_priv *iface;
136d4f2939cSRui Paulo 	DBusMessage *msg;
137d4f2939cSRui Paulo 	DBusMessageIter iter;
138d4f2939cSRui Paulo 
139d4f2939cSRui Paulo 	iface = wpa_s->global->dbus;
140d4f2939cSRui Paulo 
141d4f2939cSRui Paulo 	/* Do nothing if the control interface is not turned on */
142325151a3SRui Paulo 	if (iface == NULL || !wpa_s->dbus_new_path)
143d4f2939cSRui Paulo 		return;
144d4f2939cSRui Paulo 
145d4f2939cSRui Paulo 	msg = dbus_message_new_signal(WPAS_DBUS_NEW_PATH,
146d4f2939cSRui Paulo 				      WPAS_DBUS_NEW_INTERFACE, sig_name);
147d4f2939cSRui Paulo 	if (msg == NULL)
148d4f2939cSRui Paulo 		return;
149d4f2939cSRui Paulo 
150d4f2939cSRui Paulo 	dbus_message_iter_init_append(msg, &iter);
151d4f2939cSRui Paulo 	if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_OBJECT_PATH,
1525b9c547cSRui Paulo 					    &wpa_s->dbus_new_path) ||
1535b9c547cSRui Paulo 	    (properties &&
1545b9c547cSRui Paulo 	     !wpa_dbus_get_object_properties(
155d4f2939cSRui Paulo 		     iface, wpa_s->dbus_new_path,
1565b9c547cSRui Paulo 		     WPAS_DBUS_NEW_IFACE_INTERFACE, &iter)))
157d4f2939cSRui Paulo 		wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
1585b9c547cSRui Paulo 	else
1595b9c547cSRui Paulo 		dbus_connection_send(iface->con, msg, NULL);
160d4f2939cSRui Paulo 	dbus_message_unref(msg);
161d4f2939cSRui Paulo }
162d4f2939cSRui Paulo 
163d4f2939cSRui Paulo 
164d4f2939cSRui Paulo /**
165d4f2939cSRui Paulo  * wpas_dbus_signal_interface_added - Send a interface created signal
166d4f2939cSRui Paulo  * @wpa_s: %wpa_supplicant network interface data
167d4f2939cSRui Paulo  *
168d4f2939cSRui Paulo  * Notify listeners about creating new interface
169d4f2939cSRui Paulo  */
170d4f2939cSRui Paulo static void wpas_dbus_signal_interface_added(struct wpa_supplicant *wpa_s)
171d4f2939cSRui Paulo {
172d4f2939cSRui Paulo 	wpas_dbus_signal_interface(wpa_s, "InterfaceAdded", TRUE);
173d4f2939cSRui Paulo }
174d4f2939cSRui Paulo 
175d4f2939cSRui Paulo 
176d4f2939cSRui Paulo /**
177d4f2939cSRui Paulo  * wpas_dbus_signal_interface_removed - Send a interface removed signal
178d4f2939cSRui Paulo  * @wpa_s: %wpa_supplicant network interface data
179d4f2939cSRui Paulo  *
180d4f2939cSRui Paulo  * Notify listeners about removing interface
181d4f2939cSRui Paulo  */
182d4f2939cSRui Paulo static void wpas_dbus_signal_interface_removed(struct wpa_supplicant *wpa_s)
183d4f2939cSRui Paulo {
184d4f2939cSRui Paulo 	wpas_dbus_signal_interface(wpa_s, "InterfaceRemoved", FALSE);
185d4f2939cSRui Paulo 
186d4f2939cSRui Paulo }
187d4f2939cSRui Paulo 
188d4f2939cSRui Paulo 
189d4f2939cSRui Paulo /**
190d4f2939cSRui Paulo  * wpas_dbus_signal_scan_done - send scan done signal
191d4f2939cSRui Paulo  * @wpa_s: %wpa_supplicant network interface data
192d4f2939cSRui Paulo  * @success: indicates if scanning succeed or failed
193d4f2939cSRui Paulo  *
194d4f2939cSRui Paulo  * Notify listeners about finishing a scan
195d4f2939cSRui Paulo  */
196d4f2939cSRui Paulo void wpas_dbus_signal_scan_done(struct wpa_supplicant *wpa_s, int success)
197d4f2939cSRui Paulo {
198d4f2939cSRui Paulo 	struct wpas_dbus_priv *iface;
199d4f2939cSRui Paulo 	DBusMessage *msg;
200d4f2939cSRui Paulo 	dbus_bool_t succ;
201d4f2939cSRui Paulo 
202d4f2939cSRui Paulo 	iface = wpa_s->global->dbus;
203d4f2939cSRui Paulo 
204d4f2939cSRui Paulo 	/* Do nothing if the control interface is not turned on */
205325151a3SRui Paulo 	if (iface == NULL || !wpa_s->dbus_new_path)
206d4f2939cSRui Paulo 		return;
207d4f2939cSRui Paulo 
208d4f2939cSRui Paulo 	msg = dbus_message_new_signal(wpa_s->dbus_new_path,
209d4f2939cSRui Paulo 				      WPAS_DBUS_NEW_IFACE_INTERFACE,
210d4f2939cSRui Paulo 				      "ScanDone");
211d4f2939cSRui Paulo 	if (msg == NULL)
212d4f2939cSRui Paulo 		return;
213d4f2939cSRui Paulo 
214d4f2939cSRui Paulo 	succ = success ? TRUE : FALSE;
215d4f2939cSRui Paulo 	if (dbus_message_append_args(msg, DBUS_TYPE_BOOLEAN, &succ,
216d4f2939cSRui Paulo 				     DBUS_TYPE_INVALID))
217d4f2939cSRui Paulo 		dbus_connection_send(iface->con, msg, NULL);
218d4f2939cSRui Paulo 	else
219d4f2939cSRui Paulo 		wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
220d4f2939cSRui Paulo 	dbus_message_unref(msg);
221d4f2939cSRui Paulo }
222d4f2939cSRui Paulo 
223d4f2939cSRui Paulo 
224d4f2939cSRui Paulo /**
2255b9c547cSRui Paulo  * wpas_dbus_signal_bss - Send a BSS related event signal
226d4f2939cSRui Paulo  * @wpa_s: %wpa_supplicant network interface data
227d4f2939cSRui Paulo  * @bss_obj_path: BSS object path
228d4f2939cSRui Paulo  * @sig_name: signal name - BSSAdded or BSSRemoved
229d4f2939cSRui Paulo  * @properties: Whether to add second argument with object properties
230d4f2939cSRui Paulo  *
231d4f2939cSRui Paulo  * Notify listeners about event related with BSS
232d4f2939cSRui Paulo  */
233d4f2939cSRui Paulo static void wpas_dbus_signal_bss(struct wpa_supplicant *wpa_s,
234d4f2939cSRui Paulo 				 const char *bss_obj_path,
2354bc52338SCy Schubert 				 const char *sig_name, dbus_bool_t properties)
236d4f2939cSRui Paulo {
237d4f2939cSRui Paulo 	struct wpas_dbus_priv *iface;
238d4f2939cSRui Paulo 	DBusMessage *msg;
239d4f2939cSRui Paulo 	DBusMessageIter iter;
240d4f2939cSRui Paulo 
241d4f2939cSRui Paulo 	iface = wpa_s->global->dbus;
242d4f2939cSRui Paulo 
243d4f2939cSRui Paulo 	/* Do nothing if the control interface is not turned on */
244325151a3SRui Paulo 	if (iface == NULL || !wpa_s->dbus_new_path)
245d4f2939cSRui Paulo 		return;
246d4f2939cSRui Paulo 
247d4f2939cSRui Paulo 	msg = dbus_message_new_signal(wpa_s->dbus_new_path,
248d4f2939cSRui Paulo 				      WPAS_DBUS_NEW_IFACE_INTERFACE,
249d4f2939cSRui Paulo 				      sig_name);
250d4f2939cSRui Paulo 	if (msg == NULL)
251d4f2939cSRui Paulo 		return;
252d4f2939cSRui Paulo 
253d4f2939cSRui Paulo 	dbus_message_iter_init_append(msg, &iter);
254d4f2939cSRui Paulo 	if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_OBJECT_PATH,
2555b9c547cSRui Paulo 					    &bss_obj_path) ||
2565b9c547cSRui Paulo 	    (properties &&
2575b9c547cSRui Paulo 	     !wpa_dbus_get_object_properties(iface, bss_obj_path,
258d4f2939cSRui Paulo 					     WPAS_DBUS_NEW_IFACE_BSS,
2595b9c547cSRui Paulo 					     &iter)))
260d4f2939cSRui Paulo 		wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
2615b9c547cSRui Paulo 	else
2625b9c547cSRui Paulo 		dbus_connection_send(iface->con, msg, NULL);
263d4f2939cSRui Paulo 	dbus_message_unref(msg);
264d4f2939cSRui Paulo }
265d4f2939cSRui Paulo 
266d4f2939cSRui Paulo 
267d4f2939cSRui Paulo /**
268d4f2939cSRui Paulo  * wpas_dbus_signal_bss_added - Send a BSS added signal
269d4f2939cSRui Paulo  * @wpa_s: %wpa_supplicant network interface data
270d4f2939cSRui Paulo  * @bss_obj_path: new BSS object path
271d4f2939cSRui Paulo  *
272d4f2939cSRui Paulo  * Notify listeners about adding new BSS
273d4f2939cSRui Paulo  */
274d4f2939cSRui Paulo static void wpas_dbus_signal_bss_added(struct wpa_supplicant *wpa_s,
275d4f2939cSRui Paulo 				       const char *bss_obj_path)
276d4f2939cSRui Paulo {
277d4f2939cSRui Paulo 	wpas_dbus_signal_bss(wpa_s, bss_obj_path, "BSSAdded", TRUE);
278d4f2939cSRui Paulo }
279d4f2939cSRui Paulo 
280d4f2939cSRui Paulo 
281d4f2939cSRui Paulo /**
282d4f2939cSRui Paulo  * wpas_dbus_signal_bss_removed - Send a BSS removed signal
283d4f2939cSRui Paulo  * @wpa_s: %wpa_supplicant network interface data
284d4f2939cSRui Paulo  * @bss_obj_path: BSS object path
285d4f2939cSRui Paulo  *
286d4f2939cSRui Paulo  * Notify listeners about removing BSS
287d4f2939cSRui Paulo  */
288d4f2939cSRui Paulo static void wpas_dbus_signal_bss_removed(struct wpa_supplicant *wpa_s,
289d4f2939cSRui Paulo 					 const char *bss_obj_path)
290d4f2939cSRui Paulo {
291d4f2939cSRui Paulo 	wpas_dbus_signal_bss(wpa_s, bss_obj_path, "BSSRemoved", FALSE);
292d4f2939cSRui Paulo }
293d4f2939cSRui Paulo 
294d4f2939cSRui Paulo 
295d4f2939cSRui Paulo /**
296d4f2939cSRui Paulo  * wpas_dbus_signal_blob - Send a blob related event signal
297d4f2939cSRui Paulo  * @wpa_s: %wpa_supplicant network interface data
298d4f2939cSRui Paulo  * @name: blob name
299d4f2939cSRui Paulo  * @sig_name: signal name - BlobAdded or BlobRemoved
300d4f2939cSRui Paulo  *
301d4f2939cSRui Paulo  * Notify listeners about event related with blob
302d4f2939cSRui Paulo  */
303d4f2939cSRui Paulo static void wpas_dbus_signal_blob(struct wpa_supplicant *wpa_s,
304d4f2939cSRui Paulo 				  const char *name, const char *sig_name)
305d4f2939cSRui Paulo {
306d4f2939cSRui Paulo 	struct wpas_dbus_priv *iface;
307d4f2939cSRui Paulo 	DBusMessage *msg;
308d4f2939cSRui Paulo 
309d4f2939cSRui Paulo 	iface = wpa_s->global->dbus;
310d4f2939cSRui Paulo 
311d4f2939cSRui Paulo 	/* Do nothing if the control interface is not turned on */
312325151a3SRui Paulo 	if (iface == NULL || !wpa_s->dbus_new_path)
313d4f2939cSRui Paulo 		return;
314d4f2939cSRui Paulo 
315d4f2939cSRui Paulo 	msg = dbus_message_new_signal(wpa_s->dbus_new_path,
316d4f2939cSRui Paulo 				      WPAS_DBUS_NEW_IFACE_INTERFACE,
317d4f2939cSRui Paulo 				      sig_name);
318d4f2939cSRui Paulo 	if (msg == NULL)
319d4f2939cSRui Paulo 		return;
320d4f2939cSRui Paulo 
321d4f2939cSRui Paulo 	if (dbus_message_append_args(msg, DBUS_TYPE_STRING, &name,
322d4f2939cSRui Paulo 				     DBUS_TYPE_INVALID))
323d4f2939cSRui Paulo 		dbus_connection_send(iface->con, msg, NULL);
324d4f2939cSRui Paulo 	else
325d4f2939cSRui Paulo 		wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
326d4f2939cSRui Paulo 	dbus_message_unref(msg);
327d4f2939cSRui Paulo }
328d4f2939cSRui Paulo 
329d4f2939cSRui Paulo 
330d4f2939cSRui Paulo /**
331d4f2939cSRui Paulo  * wpas_dbus_signal_blob_added - Send a blob added signal
332d4f2939cSRui Paulo  * @wpa_s: %wpa_supplicant network interface data
333d4f2939cSRui Paulo  * @name: blob name
334d4f2939cSRui Paulo  *
335d4f2939cSRui Paulo  * Notify listeners about adding a new blob
336d4f2939cSRui Paulo  */
337d4f2939cSRui Paulo void wpas_dbus_signal_blob_added(struct wpa_supplicant *wpa_s,
338d4f2939cSRui Paulo 				 const char *name)
339d4f2939cSRui Paulo {
340d4f2939cSRui Paulo 	wpas_dbus_signal_blob(wpa_s, name, "BlobAdded");
341d4f2939cSRui Paulo }
342d4f2939cSRui Paulo 
343d4f2939cSRui Paulo 
344d4f2939cSRui Paulo /**
345d4f2939cSRui Paulo  * wpas_dbus_signal_blob_removed - Send a blob removed signal
346d4f2939cSRui Paulo  * @wpa_s: %wpa_supplicant network interface data
347d4f2939cSRui Paulo  * @name: blob name
348d4f2939cSRui Paulo  *
349d4f2939cSRui Paulo  * Notify listeners about removing blob
350d4f2939cSRui Paulo  */
351d4f2939cSRui Paulo void wpas_dbus_signal_blob_removed(struct wpa_supplicant *wpa_s,
352d4f2939cSRui Paulo 				   const char *name)
353d4f2939cSRui Paulo {
354d4f2939cSRui Paulo 	wpas_dbus_signal_blob(wpa_s, name, "BlobRemoved");
355d4f2939cSRui Paulo }
356d4f2939cSRui Paulo 
357d4f2939cSRui Paulo 
358d4f2939cSRui Paulo /**
359d4f2939cSRui Paulo  * wpas_dbus_signal_network - Send a network related event signal
360d4f2939cSRui Paulo  * @wpa_s: %wpa_supplicant network interface data
361d4f2939cSRui Paulo  * @id: new network id
362d4f2939cSRui Paulo  * @sig_name: signal name - NetworkAdded, NetworkRemoved or NetworkSelected
363d4f2939cSRui Paulo  * @properties: determines if add second argument with object properties
364d4f2939cSRui Paulo  *
365d4f2939cSRui Paulo  * Notify listeners about event related with configured network
366d4f2939cSRui Paulo  */
367d4f2939cSRui Paulo static void wpas_dbus_signal_network(struct wpa_supplicant *wpa_s,
368d4f2939cSRui Paulo 				     int id, const char *sig_name,
3694bc52338SCy Schubert 				     dbus_bool_t properties)
370d4f2939cSRui Paulo {
371d4f2939cSRui Paulo 	struct wpas_dbus_priv *iface;
372d4f2939cSRui Paulo 	DBusMessage *msg;
373d4f2939cSRui Paulo 	DBusMessageIter iter;
374d4f2939cSRui Paulo 	char net_obj_path[WPAS_DBUS_OBJECT_PATH_MAX], *path;
375d4f2939cSRui Paulo 
376d4f2939cSRui Paulo 	iface = wpa_s->global->dbus;
377d4f2939cSRui Paulo 
378d4f2939cSRui Paulo 	/* Do nothing if the control interface is not turned on */
379325151a3SRui Paulo 	if (iface == NULL || !wpa_s->dbus_new_path)
380d4f2939cSRui Paulo 		return;
381d4f2939cSRui Paulo 
382d4f2939cSRui Paulo 	os_snprintf(net_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
383d4f2939cSRui Paulo 		    "%s/" WPAS_DBUS_NEW_NETWORKS_PART "/%u",
384d4f2939cSRui Paulo 		    wpa_s->dbus_new_path, id);
385d4f2939cSRui Paulo 
386d4f2939cSRui Paulo 	msg = dbus_message_new_signal(wpa_s->dbus_new_path,
387d4f2939cSRui Paulo 				      WPAS_DBUS_NEW_IFACE_INTERFACE,
388d4f2939cSRui Paulo 				      sig_name);
389d4f2939cSRui Paulo 	if (msg == NULL)
390d4f2939cSRui Paulo 		return;
391d4f2939cSRui Paulo 
392d4f2939cSRui Paulo 	dbus_message_iter_init_append(msg, &iter);
393d4f2939cSRui Paulo 	path = net_obj_path;
394d4f2939cSRui Paulo 	if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_OBJECT_PATH,
3955b9c547cSRui Paulo 					    &path) ||
3965b9c547cSRui Paulo 	    (properties &&
3975b9c547cSRui Paulo 	     !wpa_dbus_get_object_properties(
398d4f2939cSRui Paulo 		     iface, net_obj_path, WPAS_DBUS_NEW_IFACE_NETWORK,
3995b9c547cSRui Paulo 		     &iter)))
400d4f2939cSRui Paulo 		wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
4015b9c547cSRui Paulo 	else
4025b9c547cSRui Paulo 		dbus_connection_send(iface->con, msg, NULL);
403d4f2939cSRui Paulo 	dbus_message_unref(msg);
404d4f2939cSRui Paulo }
405d4f2939cSRui Paulo 
406d4f2939cSRui Paulo 
407d4f2939cSRui Paulo /**
408d4f2939cSRui Paulo  * wpas_dbus_signal_network_added - Send a network added signal
409d4f2939cSRui Paulo  * @wpa_s: %wpa_supplicant network interface data
410d4f2939cSRui Paulo  * @id: new network id
411d4f2939cSRui Paulo  *
412d4f2939cSRui Paulo  * Notify listeners about adding new network
413d4f2939cSRui Paulo  */
414d4f2939cSRui Paulo static void wpas_dbus_signal_network_added(struct wpa_supplicant *wpa_s,
415d4f2939cSRui Paulo 					   int id)
416d4f2939cSRui Paulo {
417d4f2939cSRui Paulo 	wpas_dbus_signal_network(wpa_s, id, "NetworkAdded", TRUE);
418d4f2939cSRui Paulo }
419d4f2939cSRui Paulo 
420d4f2939cSRui Paulo 
421d4f2939cSRui Paulo /**
422d4f2939cSRui Paulo  * wpas_dbus_signal_network_removed - Send a network removed signal
423d4f2939cSRui Paulo  * @wpa_s: %wpa_supplicant network interface data
424d4f2939cSRui Paulo  * @id: network id
425d4f2939cSRui Paulo  *
426d4f2939cSRui Paulo  * Notify listeners about removing a network
427d4f2939cSRui Paulo  */
428d4f2939cSRui Paulo static void wpas_dbus_signal_network_removed(struct wpa_supplicant *wpa_s,
429d4f2939cSRui Paulo 					     int id)
430d4f2939cSRui Paulo {
431d4f2939cSRui Paulo 	wpas_dbus_signal_network(wpa_s, id, "NetworkRemoved", FALSE);
432d4f2939cSRui Paulo }
433d4f2939cSRui Paulo 
434d4f2939cSRui Paulo 
435d4f2939cSRui Paulo /**
436d4f2939cSRui Paulo  * wpas_dbus_signal_network_selected - Send a network selected signal
437d4f2939cSRui Paulo  * @wpa_s: %wpa_supplicant network interface data
438d4f2939cSRui Paulo  * @id: network id
439d4f2939cSRui Paulo  *
440d4f2939cSRui Paulo  * Notify listeners about selecting a network
441d4f2939cSRui Paulo  */
442d4f2939cSRui Paulo void wpas_dbus_signal_network_selected(struct wpa_supplicant *wpa_s, int id)
443d4f2939cSRui Paulo {
444d4f2939cSRui Paulo 	wpas_dbus_signal_network(wpa_s, id, "NetworkSelected", FALSE);
445d4f2939cSRui Paulo }
446d4f2939cSRui Paulo 
447d4f2939cSRui Paulo 
448d4f2939cSRui Paulo /**
449d4f2939cSRui Paulo  * wpas_dbus_signal_network_request - Indicate that additional information
450d4f2939cSRui Paulo  * (EAP password, etc.) is required to complete the association to this SSID
451d4f2939cSRui Paulo  * @wpa_s: %wpa_supplicant network interface data
452d4f2939cSRui Paulo  * @rtype: The specific additional information required
453d4f2939cSRui Paulo  * @default_text: Optional description of required information
454d4f2939cSRui Paulo  *
455d4f2939cSRui Paulo  * Request additional information or passwords to complete an association
456d4f2939cSRui Paulo  * request.
457d4f2939cSRui Paulo  */
458d4f2939cSRui Paulo void wpas_dbus_signal_network_request(struct wpa_supplicant *wpa_s,
459d4f2939cSRui Paulo 				      struct wpa_ssid *ssid,
460d4f2939cSRui Paulo 				      enum wpa_ctrl_req_type rtype,
461d4f2939cSRui Paulo 				      const char *default_txt)
462d4f2939cSRui Paulo {
463d4f2939cSRui Paulo 	struct wpas_dbus_priv *iface;
464d4f2939cSRui Paulo 	DBusMessage *msg;
465d4f2939cSRui Paulo 	DBusMessageIter iter;
466d4f2939cSRui Paulo 	char net_obj_path[WPAS_DBUS_OBJECT_PATH_MAX];
467d4f2939cSRui Paulo 	const char *field, *txt = NULL, *net_ptr;
468d4f2939cSRui Paulo 
469d4f2939cSRui Paulo 	iface = wpa_s->global->dbus;
470d4f2939cSRui Paulo 
471d4f2939cSRui Paulo 	/* Do nothing if the control interface is not turned on */
472325151a3SRui Paulo 	if (iface == NULL || !wpa_s->dbus_new_path)
473d4f2939cSRui Paulo 		return;
474d4f2939cSRui Paulo 
475d4f2939cSRui Paulo 	field = wpa_supplicant_ctrl_req_to_string(rtype, default_txt, &txt);
476d4f2939cSRui Paulo 	if (field == NULL)
477d4f2939cSRui Paulo 		return;
478d4f2939cSRui Paulo 
479d4f2939cSRui Paulo 	msg = dbus_message_new_signal(wpa_s->dbus_new_path,
480d4f2939cSRui Paulo 				      WPAS_DBUS_NEW_IFACE_INTERFACE,
481d4f2939cSRui Paulo 				      "NetworkRequest");
482d4f2939cSRui Paulo 	if (msg == NULL)
483d4f2939cSRui Paulo 		return;
484d4f2939cSRui Paulo 
485d4f2939cSRui Paulo 	os_snprintf(net_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
486d4f2939cSRui Paulo 		    "%s/" WPAS_DBUS_NEW_NETWORKS_PART "/%u",
487d4f2939cSRui Paulo 		    wpa_s->dbus_new_path, ssid->id);
488d4f2939cSRui Paulo 	net_ptr = &net_obj_path[0];
489d4f2939cSRui Paulo 
490d4f2939cSRui Paulo 	dbus_message_iter_init_append(msg, &iter);
491d4f2939cSRui Paulo 	if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_OBJECT_PATH,
4925b9c547cSRui Paulo 					    &net_ptr) ||
4935b9c547cSRui Paulo 	    !dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &field) ||
4945b9c547cSRui Paulo 	    !dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &txt))
495d4f2939cSRui Paulo 		wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
4965b9c547cSRui Paulo 	else
4975b9c547cSRui Paulo 		dbus_connection_send(iface->con, msg, NULL);
498d4f2939cSRui Paulo 	dbus_message_unref(msg);
499d4f2939cSRui Paulo }
500d4f2939cSRui Paulo 
501d4f2939cSRui Paulo 
502d4f2939cSRui Paulo /**
503d4f2939cSRui Paulo  * wpas_dbus_signal_network_enabled_changed - Signals Enabled property changes
504d4f2939cSRui Paulo  * @wpa_s: %wpa_supplicant network interface data
505d4f2939cSRui Paulo  * @ssid: configured network which Enabled property has changed
506d4f2939cSRui Paulo  *
507d4f2939cSRui Paulo  * Sends PropertyChanged signals containing new value of Enabled property
508d4f2939cSRui Paulo  * for specified network
509d4f2939cSRui Paulo  */
510d4f2939cSRui Paulo void wpas_dbus_signal_network_enabled_changed(struct wpa_supplicant *wpa_s,
511d4f2939cSRui Paulo 					      struct wpa_ssid *ssid)
512d4f2939cSRui Paulo {
513d4f2939cSRui Paulo 
514d4f2939cSRui Paulo 	char path[WPAS_DBUS_OBJECT_PATH_MAX];
5155b9c547cSRui Paulo 
516325151a3SRui Paulo 	if (!wpa_s->dbus_new_path)
517325151a3SRui Paulo 		return;
518d4f2939cSRui Paulo 	os_snprintf(path, WPAS_DBUS_OBJECT_PATH_MAX,
519d4f2939cSRui Paulo 		    "%s/" WPAS_DBUS_NEW_NETWORKS_PART "/%d",
520d4f2939cSRui Paulo 		    wpa_s->dbus_new_path, ssid->id);
521d4f2939cSRui Paulo 
522d4f2939cSRui Paulo 	wpa_dbus_mark_property_changed(wpa_s->global->dbus, path,
523d4f2939cSRui Paulo 				       WPAS_DBUS_NEW_IFACE_NETWORK, "Enabled");
524d4f2939cSRui Paulo }
525d4f2939cSRui Paulo 
526d4f2939cSRui Paulo 
527d4f2939cSRui Paulo #ifdef CONFIG_WPS
528d4f2939cSRui Paulo 
529d4f2939cSRui Paulo /**
530325151a3SRui Paulo  * wpas_dbus_signal_wps_event_pbc_overlap - Signals PBC overlap WPS event
531325151a3SRui Paulo  * @wpa_s: %wpa_supplicant network interface data
532325151a3SRui Paulo  *
533325151a3SRui Paulo  * Sends Event dbus signal with name "pbc-overlap" and empty dict as arguments
534325151a3SRui Paulo  */
535325151a3SRui Paulo void wpas_dbus_signal_wps_event_pbc_overlap(struct wpa_supplicant *wpa_s)
536325151a3SRui Paulo {
537325151a3SRui Paulo 
538325151a3SRui Paulo 	DBusMessage *msg;
539325151a3SRui Paulo 	DBusMessageIter iter, dict_iter;
540325151a3SRui Paulo 	struct wpas_dbus_priv *iface;
541325151a3SRui Paulo 	char *key = "pbc-overlap";
542325151a3SRui Paulo 
543325151a3SRui Paulo 	iface = wpa_s->global->dbus;
544325151a3SRui Paulo 
545325151a3SRui Paulo 	/* Do nothing if the control interface is not turned on */
546325151a3SRui Paulo 	if (iface == NULL || !wpa_s->dbus_new_path)
547325151a3SRui Paulo 		return;
548325151a3SRui Paulo 
549325151a3SRui Paulo 	msg = dbus_message_new_signal(wpa_s->dbus_new_path,
550325151a3SRui Paulo 				      WPAS_DBUS_NEW_IFACE_WPS, "Event");
551325151a3SRui Paulo 	if (msg == NULL)
552325151a3SRui Paulo 		return;
553325151a3SRui Paulo 
554325151a3SRui Paulo 	dbus_message_iter_init_append(msg, &iter);
555325151a3SRui Paulo 
556325151a3SRui Paulo 	if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &key) ||
557325151a3SRui Paulo 	    !wpa_dbus_dict_open_write(&iter, &dict_iter) ||
558325151a3SRui Paulo 	    !wpa_dbus_dict_close_write(&iter, &dict_iter))
559325151a3SRui Paulo 		wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
560325151a3SRui Paulo 	else
561325151a3SRui Paulo 		dbus_connection_send(iface->con, msg, NULL);
562325151a3SRui Paulo 
563325151a3SRui Paulo 	dbus_message_unref(msg);
564325151a3SRui Paulo }
565325151a3SRui Paulo 
566325151a3SRui Paulo 
567325151a3SRui Paulo /**
568d4f2939cSRui Paulo  * wpas_dbus_signal_wps_event_success - Signals Success WPS event
569d4f2939cSRui Paulo  * @wpa_s: %wpa_supplicant network interface data
570d4f2939cSRui Paulo  *
571d4f2939cSRui Paulo  * Sends Event dbus signal with name "success" and empty dict as arguments
572d4f2939cSRui Paulo  */
573d4f2939cSRui Paulo void wpas_dbus_signal_wps_event_success(struct wpa_supplicant *wpa_s)
574d4f2939cSRui Paulo {
575d4f2939cSRui Paulo 
576d4f2939cSRui Paulo 	DBusMessage *msg;
577d4f2939cSRui Paulo 	DBusMessageIter iter, dict_iter;
578d4f2939cSRui Paulo 	struct wpas_dbus_priv *iface;
579d4f2939cSRui Paulo 	char *key = "success";
580d4f2939cSRui Paulo 
581d4f2939cSRui Paulo 	iface = wpa_s->global->dbus;
582d4f2939cSRui Paulo 
583d4f2939cSRui Paulo 	/* Do nothing if the control interface is not turned on */
584325151a3SRui Paulo 	if (iface == NULL || !wpa_s->dbus_new_path)
585d4f2939cSRui Paulo 		return;
586d4f2939cSRui Paulo 
587d4f2939cSRui Paulo 	msg = dbus_message_new_signal(wpa_s->dbus_new_path,
588d4f2939cSRui Paulo 				      WPAS_DBUS_NEW_IFACE_WPS, "Event");
589d4f2939cSRui Paulo 	if (msg == NULL)
590d4f2939cSRui Paulo 		return;
591d4f2939cSRui Paulo 
592d4f2939cSRui Paulo 	dbus_message_iter_init_append(msg, &iter);
593d4f2939cSRui Paulo 
594d4f2939cSRui Paulo 	if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &key) ||
595d4f2939cSRui Paulo 	    !wpa_dbus_dict_open_write(&iter, &dict_iter) ||
596d4f2939cSRui Paulo 	    !wpa_dbus_dict_close_write(&iter, &dict_iter))
597d4f2939cSRui Paulo 		wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
598d4f2939cSRui Paulo 	else
599d4f2939cSRui Paulo 		dbus_connection_send(iface->con, msg, NULL);
600d4f2939cSRui Paulo 
601d4f2939cSRui Paulo 	dbus_message_unref(msg);
602d4f2939cSRui Paulo }
603d4f2939cSRui Paulo 
604d4f2939cSRui Paulo 
605d4f2939cSRui Paulo /**
606d4f2939cSRui Paulo  * wpas_dbus_signal_wps_event_fail - Signals Fail WPS event
607d4f2939cSRui Paulo  * @wpa_s: %wpa_supplicant network interface data
608325151a3SRui Paulo  * @fail: WPS failure information
609d4f2939cSRui Paulo  *
610d4f2939cSRui Paulo  * Sends Event dbus signal with name "fail" and dictionary containing
611d4f2939cSRui Paulo  * "msg field with fail message number (int32) as arguments
612d4f2939cSRui Paulo  */
613d4f2939cSRui Paulo void wpas_dbus_signal_wps_event_fail(struct wpa_supplicant *wpa_s,
614d4f2939cSRui Paulo 				     struct wps_event_fail *fail)
615d4f2939cSRui Paulo {
616d4f2939cSRui Paulo 
617d4f2939cSRui Paulo 	DBusMessage *msg;
618d4f2939cSRui Paulo 	DBusMessageIter iter, dict_iter;
619d4f2939cSRui Paulo 	struct wpas_dbus_priv *iface;
620d4f2939cSRui Paulo 	char *key = "fail";
621d4f2939cSRui Paulo 
622d4f2939cSRui Paulo 	iface = wpa_s->global->dbus;
623d4f2939cSRui Paulo 
624d4f2939cSRui Paulo 	/* Do nothing if the control interface is not turned on */
625325151a3SRui Paulo 	if (iface == NULL || !wpa_s->dbus_new_path)
626d4f2939cSRui Paulo 		return;
627d4f2939cSRui Paulo 
628d4f2939cSRui Paulo 	msg = dbus_message_new_signal(wpa_s->dbus_new_path,
629d4f2939cSRui Paulo 				      WPAS_DBUS_NEW_IFACE_WPS, "Event");
630d4f2939cSRui Paulo 	if (msg == NULL)
631d4f2939cSRui Paulo 		return;
632d4f2939cSRui Paulo 
633d4f2939cSRui Paulo 	dbus_message_iter_init_append(msg, &iter);
634d4f2939cSRui Paulo 
635d4f2939cSRui Paulo 	if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &key) ||
636d4f2939cSRui Paulo 	    !wpa_dbus_dict_open_write(&iter, &dict_iter) ||
637d4f2939cSRui Paulo 	    !wpa_dbus_dict_append_int32(&dict_iter, "msg", fail->msg) ||
638325151a3SRui Paulo 	    !wpa_dbus_dict_append_int32(&dict_iter, "config_error",
639325151a3SRui Paulo 					fail->config_error) ||
640325151a3SRui Paulo 	    !wpa_dbus_dict_append_int32(&dict_iter, "error_indication",
641325151a3SRui Paulo 					fail->error_indication) ||
642d4f2939cSRui Paulo 	    !wpa_dbus_dict_close_write(&iter, &dict_iter))
643d4f2939cSRui Paulo 		wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
644d4f2939cSRui Paulo 	else
645d4f2939cSRui Paulo 		dbus_connection_send(iface->con, msg, NULL);
646d4f2939cSRui Paulo 
647d4f2939cSRui Paulo 	dbus_message_unref(msg);
648d4f2939cSRui Paulo }
649d4f2939cSRui Paulo 
650d4f2939cSRui Paulo 
651d4f2939cSRui Paulo /**
652d4f2939cSRui Paulo  * wpas_dbus_signal_wps_event_m2d - Signals M2D WPS event
653d4f2939cSRui Paulo  * @wpa_s: %wpa_supplicant network interface data
654325151a3SRui Paulo  * @m2d: M2D event data information
655d4f2939cSRui Paulo  *
656d4f2939cSRui Paulo  * Sends Event dbus signal with name "m2d" and dictionary containing
657d4f2939cSRui Paulo  * fields of wps_event_m2d structure.
658d4f2939cSRui Paulo  */
659d4f2939cSRui Paulo void wpas_dbus_signal_wps_event_m2d(struct wpa_supplicant *wpa_s,
660d4f2939cSRui Paulo 				    struct wps_event_m2d *m2d)
661d4f2939cSRui Paulo {
662d4f2939cSRui Paulo 
663d4f2939cSRui Paulo 	DBusMessage *msg;
664d4f2939cSRui Paulo 	DBusMessageIter iter, dict_iter;
665d4f2939cSRui Paulo 	struct wpas_dbus_priv *iface;
666d4f2939cSRui Paulo 	char *key = "m2d";
667d4f2939cSRui Paulo 
668d4f2939cSRui Paulo 	iface = wpa_s->global->dbus;
669d4f2939cSRui Paulo 
670d4f2939cSRui Paulo 	/* Do nothing if the control interface is not turned on */
671325151a3SRui Paulo 	if (iface == NULL || !wpa_s->dbus_new_path)
672d4f2939cSRui Paulo 		return;
673d4f2939cSRui Paulo 
674d4f2939cSRui Paulo 	msg = dbus_message_new_signal(wpa_s->dbus_new_path,
675d4f2939cSRui Paulo 				      WPAS_DBUS_NEW_IFACE_WPS, "Event");
676d4f2939cSRui Paulo 	if (msg == NULL)
677d4f2939cSRui Paulo 		return;
678d4f2939cSRui Paulo 
679d4f2939cSRui Paulo 	dbus_message_iter_init_append(msg, &iter);
680d4f2939cSRui Paulo 
681d4f2939cSRui Paulo 	if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &key) ||
682d4f2939cSRui Paulo 	    !wpa_dbus_dict_open_write(&iter, &dict_iter) ||
683d4f2939cSRui Paulo 	    !wpa_dbus_dict_append_uint16(&dict_iter, "config_methods",
684d4f2939cSRui Paulo 					 m2d->config_methods) ||
685d4f2939cSRui Paulo 	    !wpa_dbus_dict_append_byte_array(&dict_iter, "manufacturer",
686d4f2939cSRui Paulo 					     (const char *) m2d->manufacturer,
687d4f2939cSRui Paulo 					     m2d->manufacturer_len) ||
688d4f2939cSRui Paulo 	    !wpa_dbus_dict_append_byte_array(&dict_iter, "model_name",
689d4f2939cSRui Paulo 					     (const char *) m2d->model_name,
690d4f2939cSRui Paulo 					     m2d->model_name_len) ||
691d4f2939cSRui Paulo 	    !wpa_dbus_dict_append_byte_array(&dict_iter, "model_number",
692d4f2939cSRui Paulo 					     (const char *) m2d->model_number,
693d4f2939cSRui Paulo 					     m2d->model_number_len) ||
694d4f2939cSRui Paulo 	    !wpa_dbus_dict_append_byte_array(&dict_iter, "serial_number",
695d4f2939cSRui Paulo 					     (const char *)
696d4f2939cSRui Paulo 					     m2d->serial_number,
697d4f2939cSRui Paulo 					     m2d->serial_number_len) ||
698d4f2939cSRui Paulo 	    !wpa_dbus_dict_append_byte_array(&dict_iter, "dev_name",
699d4f2939cSRui Paulo 					     (const char *) m2d->dev_name,
700d4f2939cSRui Paulo 					     m2d->dev_name_len) ||
701d4f2939cSRui Paulo 	    !wpa_dbus_dict_append_byte_array(&dict_iter, "primary_dev_type",
702d4f2939cSRui Paulo 					     (const char *)
703d4f2939cSRui Paulo 					     m2d->primary_dev_type, 8) ||
704d4f2939cSRui Paulo 	    !wpa_dbus_dict_append_uint16(&dict_iter, "config_error",
705d4f2939cSRui Paulo 					 m2d->config_error) ||
706d4f2939cSRui Paulo 	    !wpa_dbus_dict_append_uint16(&dict_iter, "dev_password_id",
707d4f2939cSRui Paulo 					 m2d->dev_password_id) ||
708d4f2939cSRui Paulo 	    !wpa_dbus_dict_close_write(&iter, &dict_iter))
709d4f2939cSRui Paulo 		wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
710d4f2939cSRui Paulo 	else
711d4f2939cSRui Paulo 		dbus_connection_send(iface->con, msg, NULL);
712d4f2939cSRui Paulo 
713d4f2939cSRui Paulo 	dbus_message_unref(msg);
714d4f2939cSRui Paulo }
715d4f2939cSRui Paulo 
716d4f2939cSRui Paulo 
717d4f2939cSRui Paulo /**
718d4f2939cSRui Paulo  * wpas_dbus_signal_wps_cred - Signals new credentials
719d4f2939cSRui Paulo  * @wpa_s: %wpa_supplicant network interface data
720325151a3SRui Paulo  * @cred: WPS Credential information
721d4f2939cSRui Paulo  *
722d4f2939cSRui Paulo  * Sends signal with credentials in directory argument
723d4f2939cSRui Paulo  */
724d4f2939cSRui Paulo void wpas_dbus_signal_wps_cred(struct wpa_supplicant *wpa_s,
725d4f2939cSRui Paulo 			       const struct wps_credential *cred)
726d4f2939cSRui Paulo {
727d4f2939cSRui Paulo 	DBusMessage *msg;
728d4f2939cSRui Paulo 	DBusMessageIter iter, dict_iter;
729d4f2939cSRui Paulo 	struct wpas_dbus_priv *iface;
7305b9c547cSRui Paulo 	char *auth_type[5]; /* we have five possible authentication types */
731d4f2939cSRui Paulo 	int at_num = 0;
7325b9c547cSRui Paulo 	char *encr_type[3]; /* we have three possible encryption types */
733d4f2939cSRui Paulo 	int et_num = 0;
734d4f2939cSRui Paulo 
735d4f2939cSRui Paulo 	iface = wpa_s->global->dbus;
736d4f2939cSRui Paulo 
737d4f2939cSRui Paulo 	/* Do nothing if the control interface is not turned on */
738325151a3SRui Paulo 	if (iface == NULL || !wpa_s->dbus_new_path)
739d4f2939cSRui Paulo 		return;
740d4f2939cSRui Paulo 
741d4f2939cSRui Paulo 	msg = dbus_message_new_signal(wpa_s->dbus_new_path,
742d4f2939cSRui Paulo 				      WPAS_DBUS_NEW_IFACE_WPS,
743d4f2939cSRui Paulo 				      "Credentials");
744d4f2939cSRui Paulo 	if (msg == NULL)
745d4f2939cSRui Paulo 		return;
746d4f2939cSRui Paulo 
747d4f2939cSRui Paulo 	dbus_message_iter_init_append(msg, &iter);
748d4f2939cSRui Paulo 	if (!wpa_dbus_dict_open_write(&iter, &dict_iter))
749d4f2939cSRui Paulo 		goto nomem;
750d4f2939cSRui Paulo 
751d4f2939cSRui Paulo 	if (cred->auth_type & WPS_AUTH_OPEN)
752d4f2939cSRui Paulo 		auth_type[at_num++] = "open";
753c1d255d3SCy Schubert #ifndef CONFIG_NO_TKIP
754d4f2939cSRui Paulo 	if (cred->auth_type & WPS_AUTH_WPAPSK)
755d4f2939cSRui Paulo 		auth_type[at_num++] = "wpa-psk";
756d4f2939cSRui Paulo 	if (cred->auth_type & WPS_AUTH_WPA)
757d4f2939cSRui Paulo 		auth_type[at_num++] = "wpa-eap";
758c1d255d3SCy Schubert #endif /* CONFIG_NO_TKIP */
759d4f2939cSRui Paulo 	if (cred->auth_type & WPS_AUTH_WPA2)
760d4f2939cSRui Paulo 		auth_type[at_num++] = "wpa2-eap";
761d4f2939cSRui Paulo 	if (cred->auth_type & WPS_AUTH_WPA2PSK)
7625b9c547cSRui Paulo 		auth_type[at_num++] = "wpa2-psk";
763d4f2939cSRui Paulo 
764d4f2939cSRui Paulo 	if (cred->encr_type & WPS_ENCR_NONE)
765d4f2939cSRui Paulo 		encr_type[et_num++] = "none";
766c1d255d3SCy Schubert #ifndef CONFIG_NO_TKIP
767d4f2939cSRui Paulo 	if (cred->encr_type & WPS_ENCR_TKIP)
768d4f2939cSRui Paulo 		encr_type[et_num++] = "tkip";
769c1d255d3SCy Schubert #endif /* CONFIG_NO_TKIP */
770d4f2939cSRui Paulo 	if (cred->encr_type & WPS_ENCR_AES)
771d4f2939cSRui Paulo 		encr_type[et_num++] = "aes";
772d4f2939cSRui Paulo 
7735b9c547cSRui Paulo 	if ((wpa_s->current_ssid &&
7745b9c547cSRui Paulo 	     !wpa_dbus_dict_append_byte_array(
775d4f2939cSRui Paulo 		     &dict_iter, "BSSID",
7765b9c547cSRui Paulo 		     (const char *) wpa_s->current_ssid->bssid, ETH_ALEN)) ||
7775b9c547cSRui Paulo 	    !wpa_dbus_dict_append_byte_array(&dict_iter, "SSID",
778d4f2939cSRui Paulo 					     (const char *) cred->ssid,
779d4f2939cSRui Paulo 					     cred->ssid_len) ||
780d4f2939cSRui Paulo 	    !wpa_dbus_dict_append_string_array(&dict_iter, "AuthType",
781d4f2939cSRui Paulo 					       (const char **) auth_type,
782d4f2939cSRui Paulo 					       at_num) ||
783d4f2939cSRui Paulo 	    !wpa_dbus_dict_append_string_array(&dict_iter, "EncrType",
784d4f2939cSRui Paulo 					       (const char **) encr_type,
785d4f2939cSRui Paulo 					       et_num) ||
786d4f2939cSRui Paulo 	    !wpa_dbus_dict_append_byte_array(&dict_iter, "Key",
787d4f2939cSRui Paulo 					     (const char *) cred->key,
788d4f2939cSRui Paulo 					     cred->key_len) ||
789d4f2939cSRui Paulo 	    !wpa_dbus_dict_append_uint32(&dict_iter, "KeyIndex",
790d4f2939cSRui Paulo 					 cred->key_idx) ||
791d4f2939cSRui Paulo 	    !wpa_dbus_dict_close_write(&iter, &dict_iter))
792d4f2939cSRui Paulo 		goto nomem;
793d4f2939cSRui Paulo 
794d4f2939cSRui Paulo 	dbus_connection_send(iface->con, msg, NULL);
795d4f2939cSRui Paulo 
796d4f2939cSRui Paulo nomem:
797d4f2939cSRui Paulo 	dbus_message_unref(msg);
798d4f2939cSRui Paulo }
799d4f2939cSRui Paulo 
800d4f2939cSRui Paulo #endif /* CONFIG_WPS */
801d4f2939cSRui Paulo 
80285732ac8SCy Schubert 
80385732ac8SCy Schubert #ifdef CONFIG_MESH
80485732ac8SCy Schubert 
80585732ac8SCy Schubert void wpas_dbus_signal_mesh_group_started(struct wpa_supplicant *wpa_s,
80685732ac8SCy Schubert 					 struct wpa_ssid *ssid)
80785732ac8SCy Schubert {
80885732ac8SCy Schubert 	struct wpas_dbus_priv *iface;
80985732ac8SCy Schubert 	DBusMessage *msg;
81085732ac8SCy Schubert 	DBusMessageIter iter, dict_iter;
81185732ac8SCy Schubert 
81285732ac8SCy Schubert 	iface = wpa_s->global->dbus;
81385732ac8SCy Schubert 
81485732ac8SCy Schubert 	/* Do nothing if the control interface is not turned on */
81585732ac8SCy Schubert 	if (!iface || !wpa_s->dbus_new_path)
81685732ac8SCy Schubert 		return;
81785732ac8SCy Schubert 
81885732ac8SCy Schubert 	msg = dbus_message_new_signal(wpa_s->dbus_new_path,
81985732ac8SCy Schubert 				      WPAS_DBUS_NEW_IFACE_MESH,
82085732ac8SCy Schubert 				      "MeshGroupStarted");
82185732ac8SCy Schubert 	if (!msg)
82285732ac8SCy Schubert 		return;
82385732ac8SCy Schubert 
82485732ac8SCy Schubert 	dbus_message_iter_init_append(msg, &iter);
82585732ac8SCy Schubert 	if (!wpa_dbus_dict_open_write(&iter, &dict_iter) ||
82685732ac8SCy Schubert 	    !wpa_dbus_dict_append_byte_array(&dict_iter, "SSID",
82785732ac8SCy Schubert 					     (const char *) ssid->ssid,
82885732ac8SCy Schubert 					     ssid->ssid_len) ||
82985732ac8SCy Schubert 	    !wpa_dbus_dict_close_write(&iter, &dict_iter))
83085732ac8SCy Schubert 		wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
83185732ac8SCy Schubert 	else
83285732ac8SCy Schubert 		dbus_connection_send(iface->con, msg, NULL);
83385732ac8SCy Schubert 	dbus_message_unref(msg);
83485732ac8SCy Schubert }
83585732ac8SCy Schubert 
83685732ac8SCy Schubert 
83785732ac8SCy Schubert void wpas_dbus_signal_mesh_group_removed(struct wpa_supplicant *wpa_s,
83885732ac8SCy Schubert 					 const u8 *meshid, u8 meshid_len,
83985732ac8SCy Schubert 					 int reason)
84085732ac8SCy Schubert {
84185732ac8SCy Schubert 	struct wpas_dbus_priv *iface;
84285732ac8SCy Schubert 	DBusMessage *msg;
84385732ac8SCy Schubert 	DBusMessageIter iter, dict_iter;
84485732ac8SCy Schubert 
84585732ac8SCy Schubert 	iface = wpa_s->global->dbus;
84685732ac8SCy Schubert 
84785732ac8SCy Schubert 	/* Do nothing if the control interface is not turned on */
84885732ac8SCy Schubert 	if (!iface || !wpa_s->dbus_new_path)
84985732ac8SCy Schubert 		return;
85085732ac8SCy Schubert 
85185732ac8SCy Schubert 	msg = dbus_message_new_signal(wpa_s->dbus_new_path,
85285732ac8SCy Schubert 				      WPAS_DBUS_NEW_IFACE_MESH,
85385732ac8SCy Schubert 				      "MeshGroupRemoved");
85485732ac8SCy Schubert 	if (!msg)
85585732ac8SCy Schubert 		return;
85685732ac8SCy Schubert 
85785732ac8SCy Schubert 	dbus_message_iter_init_append(msg, &iter);
85885732ac8SCy Schubert 	if (!wpa_dbus_dict_open_write(&iter, &dict_iter) ||
85985732ac8SCy Schubert 	    !wpa_dbus_dict_append_byte_array(&dict_iter, "SSID",
86085732ac8SCy Schubert 					     (const char *) meshid,
86185732ac8SCy Schubert 					     meshid_len) ||
86285732ac8SCy Schubert 	    !wpa_dbus_dict_append_int32(&dict_iter, "DisconnectReason",
86385732ac8SCy Schubert 					reason) ||
86485732ac8SCy Schubert 	    !wpa_dbus_dict_close_write(&iter, &dict_iter))
86585732ac8SCy Schubert 		wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
86685732ac8SCy Schubert 	else
86785732ac8SCy Schubert 		dbus_connection_send(iface->con, msg, NULL);
86885732ac8SCy Schubert 	dbus_message_unref(msg);
86985732ac8SCy Schubert }
87085732ac8SCy Schubert 
87185732ac8SCy Schubert 
87285732ac8SCy Schubert void wpas_dbus_signal_mesh_peer_connected(struct wpa_supplicant *wpa_s,
87385732ac8SCy Schubert 					  const u8 *peer_addr)
87485732ac8SCy Schubert {
87585732ac8SCy Schubert 	struct wpas_dbus_priv *iface;
87685732ac8SCy Schubert 	DBusMessage *msg;
87785732ac8SCy Schubert 	DBusMessageIter iter, dict_iter;
87885732ac8SCy Schubert 
87985732ac8SCy Schubert 	iface = wpa_s->global->dbus;
88085732ac8SCy Schubert 
88185732ac8SCy Schubert 	/* Do nothing if the control interface is not turned on */
88285732ac8SCy Schubert 	if (!iface || !wpa_s->dbus_new_path)
88385732ac8SCy Schubert 		return;
88485732ac8SCy Schubert 
88585732ac8SCy Schubert 	msg = dbus_message_new_signal(wpa_s->dbus_new_path,
88685732ac8SCy Schubert 				      WPAS_DBUS_NEW_IFACE_MESH,
88785732ac8SCy Schubert 				      "MeshPeerConnected");
88885732ac8SCy Schubert 	if (!msg)
88985732ac8SCy Schubert 		return;
89085732ac8SCy Schubert 
89185732ac8SCy Schubert 	dbus_message_iter_init_append(msg, &iter);
89285732ac8SCy Schubert 	if (!wpa_dbus_dict_open_write(&iter, &dict_iter) ||
89385732ac8SCy Schubert 	    !wpa_dbus_dict_append_byte_array(&dict_iter, "PeerAddress",
89485732ac8SCy Schubert 					     (const char *) peer_addr,
89585732ac8SCy Schubert 					     ETH_ALEN) ||
89685732ac8SCy Schubert 	    !wpa_dbus_dict_close_write(&iter, &dict_iter))
89785732ac8SCy Schubert 		wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
89885732ac8SCy Schubert 	else
89985732ac8SCy Schubert 		dbus_connection_send(iface->con, msg, NULL);
90085732ac8SCy Schubert 	dbus_message_unref(msg);
90185732ac8SCy Schubert }
90285732ac8SCy Schubert 
90385732ac8SCy Schubert 
90485732ac8SCy Schubert void wpas_dbus_signal_mesh_peer_disconnected(struct wpa_supplicant *wpa_s,
90585732ac8SCy Schubert 					     const u8 *peer_addr, int reason)
90685732ac8SCy Schubert {
90785732ac8SCy Schubert 	struct wpas_dbus_priv *iface;
90885732ac8SCy Schubert 	DBusMessage *msg;
90985732ac8SCy Schubert 	DBusMessageIter iter, dict_iter;
91085732ac8SCy Schubert 
91185732ac8SCy Schubert 	iface = wpa_s->global->dbus;
91285732ac8SCy Schubert 
91385732ac8SCy Schubert 	/* Do nothing if the control interface is not turned on */
91485732ac8SCy Schubert 	if (!iface || !wpa_s->dbus_new_path)
91585732ac8SCy Schubert 		return;
91685732ac8SCy Schubert 
91785732ac8SCy Schubert 	msg = dbus_message_new_signal(wpa_s->dbus_new_path,
91885732ac8SCy Schubert 				      WPAS_DBUS_NEW_IFACE_MESH,
91985732ac8SCy Schubert 				      "MeshPeerDisconnected");
92085732ac8SCy Schubert 	if (!msg)
92185732ac8SCy Schubert 		return;
92285732ac8SCy Schubert 
92385732ac8SCy Schubert 	dbus_message_iter_init_append(msg, &iter);
92485732ac8SCy Schubert 	if (!wpa_dbus_dict_open_write(&iter, &dict_iter) ||
92585732ac8SCy Schubert 	    !wpa_dbus_dict_append_byte_array(&dict_iter, "PeerAddress",
92685732ac8SCy Schubert 					     (const char *) peer_addr,
92785732ac8SCy Schubert 					     ETH_ALEN) ||
92885732ac8SCy Schubert 	    !wpa_dbus_dict_append_int32(&dict_iter, "DisconnectReason",
92985732ac8SCy Schubert 					reason) ||
93085732ac8SCy Schubert 	    !wpa_dbus_dict_close_write(&iter, &dict_iter))
93185732ac8SCy Schubert 		wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
93285732ac8SCy Schubert 	else
93385732ac8SCy Schubert 		dbus_connection_send(iface->con, msg, NULL);
93485732ac8SCy Schubert 	dbus_message_unref(msg);
93585732ac8SCy Schubert }
93685732ac8SCy Schubert 
93785732ac8SCy Schubert #endif /* CONFIG_MESH */
93885732ac8SCy Schubert 
93985732ac8SCy Schubert 
940*32a95656SCy Schubert #ifdef CONFIG_INTERWORKING
941*32a95656SCy Schubert 
942*32a95656SCy Schubert void wpas_dbus_signal_interworking_ap_added(struct wpa_supplicant *wpa_s,
943*32a95656SCy Schubert 					    struct wpa_bss *bss,
944*32a95656SCy Schubert 					    struct wpa_cred *cred,
945*32a95656SCy Schubert 					    const char *type,
946*32a95656SCy Schubert 					    int excluded,
947*32a95656SCy Schubert 					    int bh,
948*32a95656SCy Schubert 					    int bss_load,
949*32a95656SCy Schubert 					    int conn_capab)
950*32a95656SCy Schubert {
951*32a95656SCy Schubert 	struct wpas_dbus_priv *iface;
952*32a95656SCy Schubert 	DBusMessage *msg;
953*32a95656SCy Schubert 	DBusMessageIter iter, dict_iter;
954*32a95656SCy Schubert 	char bss_path[WPAS_DBUS_OBJECT_PATH_MAX], *bss_obj_path;
955*32a95656SCy Schubert 	char cred_path[WPAS_DBUS_OBJECT_PATH_MAX], *cred_obj_path;
956*32a95656SCy Schubert 
957*32a95656SCy Schubert 	iface = wpa_s->global->dbus;
958*32a95656SCy Schubert 
959*32a95656SCy Schubert 	/* Do nothing if the control interface is not turned on */
960*32a95656SCy Schubert 	if (!iface || !wpa_s->dbus_new_path)
961*32a95656SCy Schubert 		return;
962*32a95656SCy Schubert 
963*32a95656SCy Schubert 	msg = dbus_message_new_signal(wpa_s->dbus_new_path,
964*32a95656SCy Schubert 				      WPAS_DBUS_NEW_IFACE_INTERFACE,
965*32a95656SCy Schubert 				      "InterworkingAPAdded");
966*32a95656SCy Schubert 	if (!msg)
967*32a95656SCy Schubert 		return;
968*32a95656SCy Schubert 
969*32a95656SCy Schubert 	os_snprintf(bss_path, WPAS_DBUS_OBJECT_PATH_MAX,
970*32a95656SCy Schubert 		    "%s/" WPAS_DBUS_NEW_BSSIDS_PART "/%u",
971*32a95656SCy Schubert 		    wpa_s->dbus_new_path, bss->id);
972*32a95656SCy Schubert 	bss_obj_path = bss_path;
973*32a95656SCy Schubert 
974*32a95656SCy Schubert 	os_snprintf(cred_path, WPAS_DBUS_OBJECT_PATH_MAX,
975*32a95656SCy Schubert 		    "%s/" WPAS_DBUS_NEW_CREDENTIALS_PART "/%u",
976*32a95656SCy Schubert 		    wpa_s->dbus_new_path, cred->id);
977*32a95656SCy Schubert 	cred_obj_path = cred_path;
978*32a95656SCy Schubert 
979*32a95656SCy Schubert 	dbus_message_iter_init_append(msg, &iter);
980*32a95656SCy Schubert 	if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_OBJECT_PATH,
981*32a95656SCy Schubert 					    &bss_obj_path) ||
982*32a95656SCy Schubert 	    !dbus_message_iter_append_basic(&iter, DBUS_TYPE_OBJECT_PATH,
983*32a95656SCy Schubert 					    &cred_obj_path) ||
984*32a95656SCy Schubert 	    !wpa_dbus_dict_open_write(&iter, &dict_iter) ||
985*32a95656SCy Schubert 	    !wpa_dbus_dict_append_string(&dict_iter, "type", type) ||
986*32a95656SCy Schubert 	    !wpa_dbus_dict_append_int32(&dict_iter, "excluded", excluded) ||
987*32a95656SCy Schubert 	    !wpa_dbus_dict_append_int32(&dict_iter, "priority",
988*32a95656SCy Schubert 					cred->priority) ||
989*32a95656SCy Schubert 	    !wpa_dbus_dict_append_int32(&dict_iter, "sp_priority",
990*32a95656SCy Schubert 					cred->sp_priority) ||
991*32a95656SCy Schubert 	    !wpa_dbus_dict_append_int32(&dict_iter, "below_min_backhaul", bh) ||
992*32a95656SCy Schubert 	    !wpa_dbus_dict_append_int32(&dict_iter, "over_max_bss_load",
993*32a95656SCy Schubert 					bss_load) ||
994*32a95656SCy Schubert 	    !wpa_dbus_dict_append_int32(&dict_iter, "conn_capab_missing",
995*32a95656SCy Schubert 					conn_capab) ||
996*32a95656SCy Schubert 	    !wpa_dbus_dict_close_write(&iter, &dict_iter))
997*32a95656SCy Schubert 		wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
998*32a95656SCy Schubert 	else
999*32a95656SCy Schubert 		dbus_connection_send(iface->con, msg, NULL);
1000*32a95656SCy Schubert 	dbus_message_unref(msg);
1001*32a95656SCy Schubert }
1002*32a95656SCy Schubert 
1003*32a95656SCy Schubert 
1004*32a95656SCy Schubert void wpas_dbus_signal_interworking_select_done(struct wpa_supplicant *wpa_s)
1005*32a95656SCy Schubert {
1006*32a95656SCy Schubert 	struct wpas_dbus_priv *iface;
1007*32a95656SCy Schubert 	DBusMessage *msg;
1008*32a95656SCy Schubert 
1009*32a95656SCy Schubert 	iface = wpa_s->global->dbus;
1010*32a95656SCy Schubert 
1011*32a95656SCy Schubert 	/* Do nothing if the control interface is not turned on */
1012*32a95656SCy Schubert 	if (!iface || !wpa_s->dbus_new_path)
1013*32a95656SCy Schubert 		return;
1014*32a95656SCy Schubert 
1015*32a95656SCy Schubert 	msg = dbus_message_new_signal(wpa_s->dbus_new_path,
1016*32a95656SCy Schubert 				      WPAS_DBUS_NEW_IFACE_INTERFACE,
1017*32a95656SCy Schubert 				      "InterworkingSelectDone");
1018*32a95656SCy Schubert 	if (!msg)
1019*32a95656SCy Schubert 		return;
1020*32a95656SCy Schubert 
1021*32a95656SCy Schubert 	dbus_connection_send(iface->con, msg, NULL);
1022*32a95656SCy Schubert 
1023*32a95656SCy Schubert 	dbus_message_unref(msg);
1024*32a95656SCy Schubert }
1025*32a95656SCy Schubert 
1026*32a95656SCy Schubert #endif /* CONFIG_INTERWORKING */
1027*32a95656SCy Schubert 
1028*32a95656SCy Schubert 
1029d4f2939cSRui Paulo void wpas_dbus_signal_certification(struct wpa_supplicant *wpa_s,
1030d4f2939cSRui Paulo 				    int depth, const char *subject,
10315b9c547cSRui Paulo 				    const char *altsubject[],
10325b9c547cSRui Paulo 				    int num_altsubject,
1033d4f2939cSRui Paulo 				    const char *cert_hash,
1034d4f2939cSRui Paulo 				    const struct wpabuf *cert)
1035d4f2939cSRui Paulo {
1036d4f2939cSRui Paulo 	struct wpas_dbus_priv *iface;
1037d4f2939cSRui Paulo 	DBusMessage *msg;
1038d4f2939cSRui Paulo 	DBusMessageIter iter, dict_iter;
1039d4f2939cSRui Paulo 
1040d4f2939cSRui Paulo 	iface = wpa_s->global->dbus;
1041d4f2939cSRui Paulo 
1042d4f2939cSRui Paulo 	/* Do nothing if the control interface is not turned on */
1043325151a3SRui Paulo 	if (iface == NULL || !wpa_s->dbus_new_path)
1044d4f2939cSRui Paulo 		return;
1045d4f2939cSRui Paulo 
1046d4f2939cSRui Paulo 	msg = dbus_message_new_signal(wpa_s->dbus_new_path,
1047d4f2939cSRui Paulo 				      WPAS_DBUS_NEW_IFACE_INTERFACE,
1048d4f2939cSRui Paulo 				      "Certification");
1049d4f2939cSRui Paulo 	if (msg == NULL)
1050d4f2939cSRui Paulo 		return;
1051d4f2939cSRui Paulo 
1052d4f2939cSRui Paulo 	dbus_message_iter_init_append(msg, &iter);
10535b9c547cSRui Paulo 	if (!wpa_dbus_dict_open_write(&iter, &dict_iter) ||
10545b9c547cSRui Paulo 	    !wpa_dbus_dict_append_uint32(&dict_iter, "depth", depth) ||
10555b9c547cSRui Paulo 	    !wpa_dbus_dict_append_string(&dict_iter, "subject", subject) ||
10565b9c547cSRui Paulo 	    (altsubject && num_altsubject &&
10575b9c547cSRui Paulo 	     !wpa_dbus_dict_append_string_array(&dict_iter, "altsubject",
10585b9c547cSRui Paulo 						altsubject, num_altsubject)) ||
10595b9c547cSRui Paulo 	    (cert_hash &&
10605b9c547cSRui Paulo 	     !wpa_dbus_dict_append_string(&dict_iter, "cert_hash",
10615b9c547cSRui Paulo 					  cert_hash)) ||
10625b9c547cSRui Paulo 	    (cert &&
1063d4f2939cSRui Paulo 	     !wpa_dbus_dict_append_byte_array(&dict_iter, "cert",
1064d4f2939cSRui Paulo 					      wpabuf_head(cert),
10655b9c547cSRui Paulo 					      wpabuf_len(cert))) ||
10665b9c547cSRui Paulo 	    !wpa_dbus_dict_close_write(&iter, &dict_iter))
10675b9c547cSRui Paulo 		wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
10685b9c547cSRui Paulo 	else
1069d4f2939cSRui Paulo 		dbus_connection_send(iface->con, msg, NULL);
1070d4f2939cSRui Paulo 	dbus_message_unref(msg);
1071d4f2939cSRui Paulo }
1072d4f2939cSRui Paulo 
1073d4f2939cSRui Paulo 
1074d4f2939cSRui Paulo void wpas_dbus_signal_eap_status(struct wpa_supplicant *wpa_s,
1075d4f2939cSRui Paulo 				 const char *status, const char *parameter)
1076d4f2939cSRui Paulo {
1077d4f2939cSRui Paulo 	struct wpas_dbus_priv *iface;
1078d4f2939cSRui Paulo 	DBusMessage *msg;
1079d4f2939cSRui Paulo 	DBusMessageIter iter;
1080d4f2939cSRui Paulo 
1081d4f2939cSRui Paulo 	iface = wpa_s->global->dbus;
1082d4f2939cSRui Paulo 
1083d4f2939cSRui Paulo 	/* Do nothing if the control interface is not turned on */
1084325151a3SRui Paulo 	if (iface == NULL || !wpa_s->dbus_new_path)
1085d4f2939cSRui Paulo 		return;
1086d4f2939cSRui Paulo 
1087d4f2939cSRui Paulo 	msg = dbus_message_new_signal(wpa_s->dbus_new_path,
1088d4f2939cSRui Paulo 				      WPAS_DBUS_NEW_IFACE_INTERFACE,
1089d4f2939cSRui Paulo 				      "EAP");
1090d4f2939cSRui Paulo 	if (msg == NULL)
1091d4f2939cSRui Paulo 		return;
1092d4f2939cSRui Paulo 
1093d4f2939cSRui Paulo 	dbus_message_iter_init_append(msg, &iter);
1094d4f2939cSRui Paulo 
10955b9c547cSRui Paulo 	if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &status) ||
1096d4f2939cSRui Paulo 	    !dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING,
1097d4f2939cSRui Paulo 					    &parameter))
10985b9c547cSRui Paulo 		wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
10995b9c547cSRui Paulo 	else
1100d4f2939cSRui Paulo 		dbus_connection_send(iface->con, msg, NULL);
1101d4f2939cSRui Paulo 	dbus_message_unref(msg);
1102d4f2939cSRui Paulo }
1103d4f2939cSRui Paulo 
1104d4f2939cSRui Paulo 
11055b9c547cSRui Paulo /**
11065b9c547cSRui Paulo  * wpas_dbus_signal_sta - Send a station related event signal
11075b9c547cSRui Paulo  * @wpa_s: %wpa_supplicant network interface data
11085b9c547cSRui Paulo  * @sta: station mac address
11095b9c547cSRui Paulo  * @sig_name: signal name - StaAuthorized or StaDeauthorized
11105b9c547cSRui Paulo  *
11115b9c547cSRui Paulo  * Notify listeners about event related with station
11125b9c547cSRui Paulo  */
11135b9c547cSRui Paulo static void wpas_dbus_signal_sta(struct wpa_supplicant *wpa_s,
11145b9c547cSRui Paulo 				 const u8 *sta, const char *sig_name)
11155b9c547cSRui Paulo {
11165b9c547cSRui Paulo 	struct wpas_dbus_priv *iface;
11175b9c547cSRui Paulo 	DBusMessage *msg;
11185b9c547cSRui Paulo 	char sta_mac[WPAS_DBUS_OBJECT_PATH_MAX];
11195b9c547cSRui Paulo 	char *dev_mac;
11205b9c547cSRui Paulo 
11215b9c547cSRui Paulo 	os_snprintf(sta_mac, WPAS_DBUS_OBJECT_PATH_MAX, MACSTR, MAC2STR(sta));
11225b9c547cSRui Paulo 	dev_mac = sta_mac;
11235b9c547cSRui Paulo 
11245b9c547cSRui Paulo 	iface = wpa_s->global->dbus;
11255b9c547cSRui Paulo 
11265b9c547cSRui Paulo 	/* Do nothing if the control interface is not turned on */
1127325151a3SRui Paulo 	if (iface == NULL || !wpa_s->dbus_new_path)
11285b9c547cSRui Paulo 		return;
11295b9c547cSRui Paulo 
11305b9c547cSRui Paulo 	msg = dbus_message_new_signal(wpa_s->dbus_new_path,
11315b9c547cSRui Paulo 				      WPAS_DBUS_NEW_IFACE_INTERFACE, sig_name);
11325b9c547cSRui Paulo 	if (msg == NULL)
11335b9c547cSRui Paulo 		return;
11345b9c547cSRui Paulo 
11355b9c547cSRui Paulo 	if (dbus_message_append_args(msg, DBUS_TYPE_STRING, &dev_mac,
11365b9c547cSRui Paulo 				     DBUS_TYPE_INVALID))
11375b9c547cSRui Paulo 		dbus_connection_send(iface->con, msg, NULL);
11385b9c547cSRui Paulo 	else
11395b9c547cSRui Paulo 		wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
11405b9c547cSRui Paulo 	dbus_message_unref(msg);
11415b9c547cSRui Paulo 
11425b9c547cSRui Paulo 	wpa_printf(MSG_DEBUG, "dbus: Station MAC address '%s' '%s'",
11435b9c547cSRui Paulo 		   sta_mac, sig_name);
11445b9c547cSRui Paulo }
11455b9c547cSRui Paulo 
11465b9c547cSRui Paulo 
11475b9c547cSRui Paulo /**
11485b9c547cSRui Paulo  * wpas_dbus_signal_sta_authorized - Send a STA authorized signal
11495b9c547cSRui Paulo  * @wpa_s: %wpa_supplicant network interface data
11505b9c547cSRui Paulo  * @sta: station mac address
11515b9c547cSRui Paulo  *
11525b9c547cSRui Paulo  * Notify listeners a new station has been authorized
11535b9c547cSRui Paulo  */
11545b9c547cSRui Paulo void wpas_dbus_signal_sta_authorized(struct wpa_supplicant *wpa_s,
11555b9c547cSRui Paulo 				     const u8 *sta)
11565b9c547cSRui Paulo {
11575b9c547cSRui Paulo 	wpas_dbus_signal_sta(wpa_s, sta, "StaAuthorized");
11585b9c547cSRui Paulo }
11595b9c547cSRui Paulo 
11605b9c547cSRui Paulo 
11615b9c547cSRui Paulo /**
11625b9c547cSRui Paulo  * wpas_dbus_signal_sta_deauthorized - Send a STA deauthorized signal
11635b9c547cSRui Paulo  * @wpa_s: %wpa_supplicant network interface data
11645b9c547cSRui Paulo  * @sta: station mac address
11655b9c547cSRui Paulo  *
11665b9c547cSRui Paulo  * Notify listeners a station has been deauthorized
11675b9c547cSRui Paulo  */
11685b9c547cSRui Paulo void wpas_dbus_signal_sta_deauthorized(struct wpa_supplicant *wpa_s,
11695b9c547cSRui Paulo 				       const u8 *sta)
11705b9c547cSRui Paulo {
11715b9c547cSRui Paulo 	wpas_dbus_signal_sta(wpa_s, sta, "StaDeauthorized");
11725b9c547cSRui Paulo }
11735b9c547cSRui Paulo 
11745b9c547cSRui Paulo 
11754bc52338SCy Schubert /**
11764bc52338SCy Schubert  * wpas_dbus_signal_station - Send an event signal related to a station object
11774bc52338SCy Schubert  * @wpa_s: %wpa_supplicant network interface data
11784bc52338SCy Schubert  * @station_obj_path: Station object path
11794bc52338SCy Schubert  * @sig_name: signal name - StationAdded or StationRemoved
11804bc52338SCy Schubert  * @properties: Whether to add second argument with object properties
11814bc52338SCy Schubert  *
11824bc52338SCy Schubert  * Notify listeners about event related with station.
11834bc52338SCy Schubert  */
11844bc52338SCy Schubert static void wpas_dbus_signal_station(struct wpa_supplicant *wpa_s,
11854bc52338SCy Schubert 				     const char *station_obj_path,
11864bc52338SCy Schubert 				     const char *sig_name,
11874bc52338SCy Schubert 				     dbus_bool_t properties)
11884bc52338SCy Schubert {
11894bc52338SCy Schubert 	struct wpas_dbus_priv *iface;
11904bc52338SCy Schubert 	DBusMessage *msg;
11914bc52338SCy Schubert 	DBusMessageIter iter;
11924bc52338SCy Schubert 
11934bc52338SCy Schubert 	iface = wpa_s->global->dbus;
11944bc52338SCy Schubert 
11954bc52338SCy Schubert 	/* Do nothing if the control interface is not turned on */
11964bc52338SCy Schubert 	if (!iface || !wpa_s->dbus_new_path)
11974bc52338SCy Schubert 		return;
11984bc52338SCy Schubert 
11994bc52338SCy Schubert 	wpa_printf(MSG_DEBUG, "dbus: STA signal %s", sig_name);
12004bc52338SCy Schubert 	msg = dbus_message_new_signal(wpa_s->dbus_new_path,
12014bc52338SCy Schubert 				      WPAS_DBUS_NEW_IFACE_INTERFACE, sig_name);
12024bc52338SCy Schubert 	if (!msg)
12034bc52338SCy Schubert 		return;
12044bc52338SCy Schubert 
12054bc52338SCy Schubert 	dbus_message_iter_init_append(msg, &iter);
12064bc52338SCy Schubert 	if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_OBJECT_PATH,
12074bc52338SCy Schubert 					    &station_obj_path) ||
12084bc52338SCy Schubert 	    (properties &&
12094bc52338SCy Schubert 	     !wpa_dbus_get_object_properties(iface, station_obj_path,
12104bc52338SCy Schubert 					     WPAS_DBUS_NEW_IFACE_STA,
12114bc52338SCy Schubert 					     &iter)))
12124bc52338SCy Schubert 		wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
12134bc52338SCy Schubert 	else
12144bc52338SCy Schubert 		dbus_connection_send(iface->con, msg, NULL);
12154bc52338SCy Schubert 	dbus_message_unref(msg);
12164bc52338SCy Schubert }
12174bc52338SCy Schubert 
12184bc52338SCy Schubert 
12194bc52338SCy Schubert /**
12204bc52338SCy Schubert  * wpas_dbus_signal_station_added - Send a Station added signal
12214bc52338SCy Schubert  * @wpa_s: %wpa_supplicant network interface data
12224bc52338SCy Schubert  * @station_obj_path: new Station object path
12234bc52338SCy Schubert  *
12244bc52338SCy Schubert  * Notify listeners about adding new Station
12254bc52338SCy Schubert  */
12264bc52338SCy Schubert static void wpas_dbus_signal_station_added(struct wpa_supplicant *wpa_s,
12274bc52338SCy Schubert 					   const char *station_obj_path)
12284bc52338SCy Schubert {
12294bc52338SCy Schubert 	wpas_dbus_signal_station(wpa_s, station_obj_path, "StationAdded", TRUE);
12304bc52338SCy Schubert }
12314bc52338SCy Schubert 
12324bc52338SCy Schubert 
12334bc52338SCy Schubert /**
12344bc52338SCy Schubert  * wpas_dbus_signal_station_removed - Send a Station removed signal
12354bc52338SCy Schubert  * @wpa_s: %wpa_supplicant network interface data
12364bc52338SCy Schubert  * @station_obj_path: Station object path
12374bc52338SCy Schubert  *
12384bc52338SCy Schubert  * Notify listeners about removing Station
12394bc52338SCy Schubert  */
12404bc52338SCy Schubert static void wpas_dbus_signal_station_removed(struct wpa_supplicant *wpa_s,
12414bc52338SCy Schubert 					     const char *station_obj_path)
12424bc52338SCy Schubert {
12434bc52338SCy Schubert 	wpas_dbus_signal_station(wpa_s, station_obj_path, "StationRemoved",
12444bc52338SCy Schubert 				 FALSE);
12454bc52338SCy Schubert }
12464bc52338SCy Schubert 
12474bc52338SCy Schubert 
1248d4f2939cSRui Paulo #ifdef CONFIG_P2P
1249d4f2939cSRui Paulo 
1250d4f2939cSRui Paulo /**
1251d4f2939cSRui Paulo  * wpas_dbus_signal_p2p_group_removed - Signals P2P group was removed
1252d4f2939cSRui Paulo  * @wpa_s: %wpa_supplicant network interface data
1253d4f2939cSRui Paulo  * @role: role of this device (client or GO)
1254d4f2939cSRui Paulo  * Sends signal with i/f name and role as string arguments
1255d4f2939cSRui Paulo  */
1256d4f2939cSRui Paulo void wpas_dbus_signal_p2p_group_removed(struct wpa_supplicant *wpa_s,
1257d4f2939cSRui Paulo 					const char *role)
1258d4f2939cSRui Paulo {
1259d4f2939cSRui Paulo 	DBusMessage *msg;
12605b9c547cSRui Paulo 	DBusMessageIter iter, dict_iter;
1261d4f2939cSRui Paulo 	struct wpas_dbus_priv *iface = wpa_s->global->dbus;
12625b9c547cSRui Paulo 	struct wpa_supplicant *parent;
1263d4f2939cSRui Paulo 
1264d4f2939cSRui Paulo 	/* Do nothing if the control interface is not turned on */
1265d4f2939cSRui Paulo 	if (iface == NULL)
1266d4f2939cSRui Paulo 		return;
1267d4f2939cSRui Paulo 
12685b9c547cSRui Paulo 	parent = wpa_s->parent;
12695b9c547cSRui Paulo 	if (parent->p2p_mgmt)
12705b9c547cSRui Paulo 		parent = parent->parent;
12715b9c547cSRui Paulo 
1272325151a3SRui Paulo 	if (!wpa_s->dbus_groupobj_path || !wpa_s->dbus_new_path ||
1273325151a3SRui Paulo 	    !parent->dbus_new_path)
12745b9c547cSRui Paulo 		return;
12755b9c547cSRui Paulo 
12765b9c547cSRui Paulo 	msg = dbus_message_new_signal(parent->dbus_new_path,
1277d4f2939cSRui Paulo 				      WPAS_DBUS_NEW_IFACE_P2PDEVICE,
1278d4f2939cSRui Paulo 				      "GroupFinished");
1279d4f2939cSRui Paulo 	if (msg == NULL)
1280d4f2939cSRui Paulo 		return;
1281d4f2939cSRui Paulo 
1282d4f2939cSRui Paulo 	dbus_message_iter_init_append(msg, &iter);
12835b9c547cSRui Paulo 	if (!wpa_dbus_dict_open_write(&iter, &dict_iter) ||
12845b9c547cSRui Paulo 	    !wpa_dbus_dict_append_object_path(&dict_iter,
12855b9c547cSRui Paulo 					      "interface_object",
12865b9c547cSRui Paulo 					      wpa_s->dbus_new_path) ||
12875b9c547cSRui Paulo 	    !wpa_dbus_dict_append_string(&dict_iter, "role", role) ||
12885b9c547cSRui Paulo 	    !wpa_dbus_dict_append_object_path(&dict_iter, "group_object",
12895b9c547cSRui Paulo 					      wpa_s->dbus_groupobj_path) ||
12905b9c547cSRui Paulo 	    !wpa_dbus_dict_close_write(&iter, &dict_iter))
12915b9c547cSRui Paulo 		wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
1292d4f2939cSRui Paulo 	else
1293d4f2939cSRui Paulo 		dbus_connection_send(iface->con, msg, NULL);
1294d4f2939cSRui Paulo 	dbus_message_unref(msg);
1295d4f2939cSRui Paulo }
1296d4f2939cSRui Paulo 
1297d4f2939cSRui Paulo 
1298d4f2939cSRui Paulo /**
1299d4f2939cSRui Paulo  * wpas_dbus_signal_p2p_provision_discovery - Signals various PD events
1300d4f2939cSRui Paulo  *
1301d4f2939cSRui Paulo  * @dev_addr - who sent the request or responded to our request.
1302d4f2939cSRui Paulo  * @request - Will be 1 if request, 0 for response.
1303d4f2939cSRui Paulo  * @status - valid only in case of response
1304d4f2939cSRui Paulo  * @config_methods - wps config methods
1305d4f2939cSRui Paulo  * @generated_pin - pin to be displayed in case of WPS_CONFIG_DISPLAY method
1306d4f2939cSRui Paulo  *
1307d4f2939cSRui Paulo  * Sends following provision discovery related events:
1308d4f2939cSRui Paulo  *	ProvisionDiscoveryRequestDisplayPin
1309d4f2939cSRui Paulo  *	ProvisionDiscoveryResponseDisplayPin
1310d4f2939cSRui Paulo  *	ProvisionDiscoveryRequestEnterPin
1311d4f2939cSRui Paulo  *	ProvisionDiscoveryResponseEnterPin
1312d4f2939cSRui Paulo  *	ProvisionDiscoveryPBCRequest
1313d4f2939cSRui Paulo  *	ProvisionDiscoveryPBCResponse
1314d4f2939cSRui Paulo  *
1315d4f2939cSRui Paulo  *	TODO::
1316d4f2939cSRui Paulo  *	ProvisionDiscoveryFailure (timeout case)
1317d4f2939cSRui Paulo  */
1318d4f2939cSRui Paulo void wpas_dbus_signal_p2p_provision_discovery(struct wpa_supplicant *wpa_s,
1319d4f2939cSRui Paulo 					      const u8 *dev_addr, int request,
1320d4f2939cSRui Paulo 					      enum p2p_prov_disc_status status,
1321d4f2939cSRui Paulo 					      u16 config_methods,
1322d4f2939cSRui Paulo 					      unsigned int generated_pin)
1323d4f2939cSRui Paulo {
1324d4f2939cSRui Paulo 	DBusMessage *msg;
1325d4f2939cSRui Paulo 	DBusMessageIter iter;
1326d4f2939cSRui Paulo 	struct wpas_dbus_priv *iface;
1327d4f2939cSRui Paulo 	char *_signal;
1328d4f2939cSRui Paulo 	int add_pin = 0;
1329d4f2939cSRui Paulo 	char peer_obj_path[WPAS_DBUS_OBJECT_PATH_MAX], *path;
1330d4f2939cSRui Paulo 	int error_ret = 1;
1331d4f2939cSRui Paulo 	char pin[9], *p_pin = NULL;
1332d4f2939cSRui Paulo 
1333d4f2939cSRui Paulo 	iface = wpa_s->global->dbus;
1334d4f2939cSRui Paulo 
1335d4f2939cSRui Paulo 	/* Do nothing if the control interface is not turned on */
1336d4f2939cSRui Paulo 	if (iface == NULL)
1337d4f2939cSRui Paulo 		return;
1338d4f2939cSRui Paulo 
13395b9c547cSRui Paulo 	if (wpa_s->p2p_mgmt)
13405b9c547cSRui Paulo 		wpa_s = wpa_s->parent;
1341325151a3SRui Paulo 	if (!wpa_s->dbus_new_path)
1342325151a3SRui Paulo 		return;
13435b9c547cSRui Paulo 
1344d4f2939cSRui Paulo 	if (request || !status) {
1345d4f2939cSRui Paulo 		if (config_methods & WPS_CONFIG_DISPLAY)
1346d4f2939cSRui Paulo 			_signal = request ?
1347d4f2939cSRui Paulo 				 "ProvisionDiscoveryRequestDisplayPin" :
1348d4f2939cSRui Paulo 				 "ProvisionDiscoveryResponseEnterPin";
1349d4f2939cSRui Paulo 		else if (config_methods & WPS_CONFIG_KEYPAD)
1350d4f2939cSRui Paulo 			_signal = request ?
1351d4f2939cSRui Paulo 				 "ProvisionDiscoveryRequestEnterPin" :
1352d4f2939cSRui Paulo 				 "ProvisionDiscoveryResponseDisplayPin";
1353d4f2939cSRui Paulo 		else if (config_methods & WPS_CONFIG_PUSHBUTTON)
1354d4f2939cSRui Paulo 			_signal = request ? "ProvisionDiscoveryPBCRequest" :
1355d4f2939cSRui Paulo 				   "ProvisionDiscoveryPBCResponse";
1356d4f2939cSRui Paulo 		else
1357d4f2939cSRui Paulo 			return; /* Unknown or un-supported method */
13585b9c547cSRui Paulo 	} else {
1359d4f2939cSRui Paulo 		/* Explicit check for failure response */
1360d4f2939cSRui Paulo 		_signal = "ProvisionDiscoveryFailure";
13615b9c547cSRui Paulo 	}
1362d4f2939cSRui Paulo 
1363d4f2939cSRui Paulo 	add_pin = ((request && (config_methods & WPS_CONFIG_DISPLAY)) ||
1364d4f2939cSRui Paulo 		   (!request && !status &&
1365d4f2939cSRui Paulo 			(config_methods & WPS_CONFIG_KEYPAD)));
1366d4f2939cSRui Paulo 
1367d4f2939cSRui Paulo 	if (add_pin) {
1368d4f2939cSRui Paulo 		os_snprintf(pin, sizeof(pin), "%08d", generated_pin);
1369d4f2939cSRui Paulo 		p_pin = pin;
1370d4f2939cSRui Paulo 	}
1371d4f2939cSRui Paulo 
1372d4f2939cSRui Paulo 	msg = dbus_message_new_signal(wpa_s->dbus_new_path,
1373d4f2939cSRui Paulo 				      WPAS_DBUS_NEW_IFACE_P2PDEVICE, _signal);
1374d4f2939cSRui Paulo 	if (msg == NULL)
1375d4f2939cSRui Paulo 		return;
1376d4f2939cSRui Paulo 
1377d4f2939cSRui Paulo 	/* Check if this is a known peer */
1378d4f2939cSRui Paulo 	if (!p2p_peer_known(wpa_s->global->p2p, dev_addr))
1379d4f2939cSRui Paulo 		goto error;
1380d4f2939cSRui Paulo 
1381d4f2939cSRui Paulo 	os_snprintf(peer_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
1382d4f2939cSRui Paulo 			"%s/" WPAS_DBUS_NEW_P2P_PEERS_PART "/"
1383d4f2939cSRui Paulo 			COMPACT_MACSTR,
1384d4f2939cSRui Paulo 			wpa_s->dbus_new_path, MAC2STR(dev_addr));
1385d4f2939cSRui Paulo 
1386d4f2939cSRui Paulo 	path = peer_obj_path;
1387d4f2939cSRui Paulo 
1388d4f2939cSRui Paulo 	dbus_message_iter_init_append(msg, &iter);
1389d4f2939cSRui Paulo 
1390d4f2939cSRui Paulo 	if (!dbus_message_iter_append_basic(&iter,
1391d4f2939cSRui Paulo 					    DBUS_TYPE_OBJECT_PATH,
1392d4f2939cSRui Paulo 					    &path))
1393d4f2939cSRui Paulo 			goto error;
1394d4f2939cSRui Paulo 
1395d4f2939cSRui Paulo 	if (!request && status)
1396d4f2939cSRui Paulo 		/* Attach status to ProvisionDiscoveryFailure */
1397d4f2939cSRui Paulo 		error_ret = !dbus_message_iter_append_basic(&iter,
1398d4f2939cSRui Paulo 						    DBUS_TYPE_INT32,
1399d4f2939cSRui Paulo 						    &status);
1400d4f2939cSRui Paulo 	else
1401d4f2939cSRui Paulo 		error_ret = (add_pin &&
1402d4f2939cSRui Paulo 				 !dbus_message_iter_append_basic(&iter,
1403d4f2939cSRui Paulo 							DBUS_TYPE_STRING,
1404d4f2939cSRui Paulo 							&p_pin));
1405d4f2939cSRui Paulo 
1406d4f2939cSRui Paulo error:
1407d4f2939cSRui Paulo 	if (!error_ret)
1408d4f2939cSRui Paulo 		dbus_connection_send(iface->con, msg, NULL);
1409d4f2939cSRui Paulo 	else
1410d4f2939cSRui Paulo 		wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
1411d4f2939cSRui Paulo 
1412d4f2939cSRui Paulo 	dbus_message_unref(msg);
1413d4f2939cSRui Paulo }
1414d4f2939cSRui Paulo 
1415d4f2939cSRui Paulo 
1416325151a3SRui Paulo /**
1417325151a3SRui Paulo  * wpas_dbus_signal_p2p_go_neg_req - Signal P2P GO Negotiation Request RX
1418325151a3SRui Paulo  * @wpa_s: %wpa_supplicant network interface data
1419325151a3SRui Paulo  * @src: Source address of the message triggering this notification
1420325151a3SRui Paulo  * @dev_passwd_id: WPS Device Password Id
1421325151a3SRui Paulo  * @go_intent: Peer's GO Intent value
1422325151a3SRui Paulo  *
1423325151a3SRui Paulo  * Sends signal to notify that a peer P2P Device is requesting group owner
1424325151a3SRui Paulo  * negotiation with us.
1425325151a3SRui Paulo  */
1426d4f2939cSRui Paulo void wpas_dbus_signal_p2p_go_neg_req(struct wpa_supplicant *wpa_s,
1427325151a3SRui Paulo 				     const u8 *src, u16 dev_passwd_id,
1428325151a3SRui Paulo 				     u8 go_intent)
1429d4f2939cSRui Paulo {
1430d4f2939cSRui Paulo 	DBusMessage *msg;
1431d4f2939cSRui Paulo 	DBusMessageIter iter;
1432d4f2939cSRui Paulo 	struct wpas_dbus_priv *iface;
1433d4f2939cSRui Paulo 	char peer_obj_path[WPAS_DBUS_OBJECT_PATH_MAX], *path;
1434d4f2939cSRui Paulo 
1435d4f2939cSRui Paulo 	iface = wpa_s->global->dbus;
1436d4f2939cSRui Paulo 
1437d4f2939cSRui Paulo 	/* Do nothing if the control interface is not turned on */
1438d4f2939cSRui Paulo 	if (iface == NULL)
1439d4f2939cSRui Paulo 		return;
1440d4f2939cSRui Paulo 
14415b9c547cSRui Paulo 	if (wpa_s->p2p_mgmt)
14425b9c547cSRui Paulo 		wpa_s = wpa_s->parent;
1443325151a3SRui Paulo 	if (!wpa_s->dbus_new_path)
1444325151a3SRui Paulo 		return;
14455b9c547cSRui Paulo 
1446d4f2939cSRui Paulo 	os_snprintf(peer_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
1447d4f2939cSRui Paulo 		    "%s/" WPAS_DBUS_NEW_P2P_PEERS_PART "/" COMPACT_MACSTR,
1448d4f2939cSRui Paulo 		    wpa_s->dbus_new_path, MAC2STR(src));
1449d4f2939cSRui Paulo 	path = peer_obj_path;
1450d4f2939cSRui Paulo 
1451d4f2939cSRui Paulo 	msg = dbus_message_new_signal(wpa_s->dbus_new_path,
1452d4f2939cSRui Paulo 				      WPAS_DBUS_NEW_IFACE_P2PDEVICE,
1453d4f2939cSRui Paulo 				      "GONegotiationRequest");
1454d4f2939cSRui Paulo 	if (msg == NULL)
1455d4f2939cSRui Paulo 		return;
1456d4f2939cSRui Paulo 
1457d4f2939cSRui Paulo 	dbus_message_iter_init_append(msg, &iter);
1458d4f2939cSRui Paulo 
1459d4f2939cSRui Paulo 	if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_OBJECT_PATH,
1460d4f2939cSRui Paulo 					    &path) ||
1461d4f2939cSRui Paulo 	    !dbus_message_iter_append_basic(&iter, DBUS_TYPE_UINT16,
1462325151a3SRui Paulo 					    &dev_passwd_id) ||
1463325151a3SRui Paulo 	    !dbus_message_iter_append_basic(&iter, DBUS_TYPE_BYTE,
1464325151a3SRui Paulo 					    &go_intent))
1465d4f2939cSRui Paulo 		wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
1466d4f2939cSRui Paulo 	else
1467d4f2939cSRui Paulo 		dbus_connection_send(iface->con, msg, NULL);
1468d4f2939cSRui Paulo 
1469d4f2939cSRui Paulo 	dbus_message_unref(msg);
1470d4f2939cSRui Paulo }
1471d4f2939cSRui Paulo 
1472d4f2939cSRui Paulo 
1473d4f2939cSRui Paulo static int wpas_dbus_get_group_obj_path(struct wpa_supplicant *wpa_s,
1474d4f2939cSRui Paulo 					const struct wpa_ssid *ssid,
1475d4f2939cSRui Paulo 					char *group_obj_path)
1476d4f2939cSRui Paulo {
1477d4f2939cSRui Paulo 	char group_name[3];
1478d4f2939cSRui Paulo 
1479325151a3SRui Paulo 	if (!wpa_s->dbus_new_path ||
1480325151a3SRui Paulo 	    os_memcmp(ssid->ssid, P2P_WILDCARD_SSID, P2P_WILDCARD_SSID_LEN))
1481d4f2939cSRui Paulo 		return -1;
1482d4f2939cSRui Paulo 
1483d4f2939cSRui Paulo 	os_memcpy(group_name, ssid->ssid + P2P_WILDCARD_SSID_LEN, 2);
1484d4f2939cSRui Paulo 	group_name[2] = '\0';
1485d4f2939cSRui Paulo 
1486d4f2939cSRui Paulo 	os_snprintf(group_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
1487d4f2939cSRui Paulo 		    "%s/" WPAS_DBUS_NEW_P2P_GROUPS_PART "/%s",
1488d4f2939cSRui Paulo 		    wpa_s->dbus_new_path, group_name);
1489d4f2939cSRui Paulo 
1490d4f2939cSRui Paulo 	return 0;
1491d4f2939cSRui Paulo }
1492d4f2939cSRui Paulo 
1493d4f2939cSRui Paulo 
14945b9c547cSRui Paulo struct group_changed_data {
14955b9c547cSRui Paulo 	struct wpa_supplicant *wpa_s;
14965b9c547cSRui Paulo 	struct p2p_peer_info *info;
14975b9c547cSRui Paulo };
14985b9c547cSRui Paulo 
14995b9c547cSRui Paulo 
15005b9c547cSRui Paulo static int match_group_where_peer_is_client(struct p2p_group *group,
15015b9c547cSRui Paulo 					    void *user_data)
15025b9c547cSRui Paulo {
15035b9c547cSRui Paulo 	struct group_changed_data *data = user_data;
15045b9c547cSRui Paulo 	const struct p2p_group_config *cfg;
15055b9c547cSRui Paulo 	struct wpa_supplicant *wpa_s_go;
15065b9c547cSRui Paulo 
15075b9c547cSRui Paulo 	if (!p2p_group_is_client_connected(group, data->info->p2p_device_addr))
15085b9c547cSRui Paulo 		return 1;
15095b9c547cSRui Paulo 
15105b9c547cSRui Paulo 	cfg = p2p_group_get_config(group);
15115b9c547cSRui Paulo 
15125b9c547cSRui Paulo 	wpa_s_go = wpas_get_p2p_go_iface(data->wpa_s, cfg->ssid,
15135b9c547cSRui Paulo 					 cfg->ssid_len);
15145b9c547cSRui Paulo 	if (wpa_s_go != NULL && wpa_s_go == data->wpa_s) {
15155b9c547cSRui Paulo 		wpas_dbus_signal_peer_groups_changed(
1516780fb4a2SCy Schubert 			data->wpa_s->p2pdev, data->info->p2p_device_addr);
15175b9c547cSRui Paulo 		return 0;
15185b9c547cSRui Paulo 	}
15195b9c547cSRui Paulo 
15205b9c547cSRui Paulo 	return 1;
15215b9c547cSRui Paulo }
15225b9c547cSRui Paulo 
15235b9c547cSRui Paulo 
15245b9c547cSRui Paulo static void signal_peer_groups_changed(struct p2p_peer_info *info,
15255b9c547cSRui Paulo 				       void *user_data)
15265b9c547cSRui Paulo {
15275b9c547cSRui Paulo 	struct group_changed_data *data = user_data;
15285b9c547cSRui Paulo 	struct wpa_supplicant *wpa_s_go;
15295b9c547cSRui Paulo 
15305b9c547cSRui Paulo 	wpa_s_go = wpas_get_p2p_client_iface(data->wpa_s,
15315b9c547cSRui Paulo 					     info->p2p_device_addr);
15325b9c547cSRui Paulo 	if (wpa_s_go != NULL && wpa_s_go == data->wpa_s) {
1533780fb4a2SCy Schubert 		wpas_dbus_signal_peer_groups_changed(data->wpa_s->p2pdev,
15345b9c547cSRui Paulo 						     info->p2p_device_addr);
15355b9c547cSRui Paulo 		return;
15365b9c547cSRui Paulo 	}
15375b9c547cSRui Paulo 
15385b9c547cSRui Paulo 	data->info = info;
15395b9c547cSRui Paulo 	p2p_loop_on_all_groups(data->wpa_s->global->p2p,
15405b9c547cSRui Paulo 			       match_group_where_peer_is_client, data);
15415b9c547cSRui Paulo 	data->info = NULL;
15425b9c547cSRui Paulo }
15435b9c547cSRui Paulo 
15445b9c547cSRui Paulo 
15455b9c547cSRui Paulo static void peer_groups_changed(struct wpa_supplicant *wpa_s)
15465b9c547cSRui Paulo {
15475b9c547cSRui Paulo 	struct group_changed_data data;
15485b9c547cSRui Paulo 
15495b9c547cSRui Paulo 	os_memset(&data, 0, sizeof(data));
15505b9c547cSRui Paulo 	data.wpa_s = wpa_s;
15515b9c547cSRui Paulo 
15525b9c547cSRui Paulo 	p2p_loop_on_known_peers(wpa_s->global->p2p,
15535b9c547cSRui Paulo 				signal_peer_groups_changed, &data);
15545b9c547cSRui Paulo }
15555b9c547cSRui Paulo 
15565b9c547cSRui Paulo 
1557d4f2939cSRui Paulo /**
1558d4f2939cSRui Paulo  * wpas_dbus_signal_p2p_group_started - Signals P2P group has
1559d4f2939cSRui Paulo  * started. Emitted when a group is successfully started
1560d4f2939cSRui Paulo  * irrespective of the role (client/GO) of the current device
1561d4f2939cSRui Paulo  *
1562d4f2939cSRui Paulo  * @wpa_s: %wpa_supplicant network interface data
1563d4f2939cSRui Paulo  * @client: this device is P2P client
1564780fb4a2SCy Schubert  * @persistent: 0 - non persistent group, 1 - persistent group
156585732ac8SCy Schubert  * @ip: When group role is client, it contains local IP address, netmask, and
156685732ac8SCy Schubert  *	GO's IP address, if assigned; otherwise, NULL
1567d4f2939cSRui Paulo  */
1568d4f2939cSRui Paulo void wpas_dbus_signal_p2p_group_started(struct wpa_supplicant *wpa_s,
156985732ac8SCy Schubert 					int client, int persistent,
157085732ac8SCy Schubert 					const u8 *ip)
1571d4f2939cSRui Paulo {
1572d4f2939cSRui Paulo 	DBusMessage *msg;
1573d4f2939cSRui Paulo 	DBusMessageIter iter, dict_iter;
1574d4f2939cSRui Paulo 	struct wpas_dbus_priv *iface;
15755b9c547cSRui Paulo 	struct wpa_supplicant *parent;
1576d4f2939cSRui Paulo 
15775b9c547cSRui Paulo 	parent = wpa_s->parent;
15785b9c547cSRui Paulo 	if (parent->p2p_mgmt)
15795b9c547cSRui Paulo 		parent = parent->parent;
15805b9c547cSRui Paulo 
15815b9c547cSRui Paulo 	iface = parent->global->dbus;
1582d4f2939cSRui Paulo 
1583d4f2939cSRui Paulo 	/* Do nothing if the control interface is not turned on */
1584325151a3SRui Paulo 	if (iface == NULL || !parent->dbus_new_path || !wpa_s->dbus_new_path)
1585d4f2939cSRui Paulo 		return;
1586d4f2939cSRui Paulo 
15875b9c547cSRui Paulo 	if (wpa_s->dbus_groupobj_path == NULL)
1588d4f2939cSRui Paulo 		return;
1589d4f2939cSRui Paulo 
1590d4f2939cSRui Paulo 	/* New interface has been created for this group */
15915b9c547cSRui Paulo 	msg = dbus_message_new_signal(parent->dbus_new_path,
1592d4f2939cSRui Paulo 				      WPAS_DBUS_NEW_IFACE_P2PDEVICE,
1593d4f2939cSRui Paulo 				      "GroupStarted");
1594d4f2939cSRui Paulo 	if (msg == NULL)
1595d4f2939cSRui Paulo 		return;
1596d4f2939cSRui Paulo 
1597d4f2939cSRui Paulo 	dbus_message_iter_init_append(msg, &iter);
1598d4f2939cSRui Paulo 	/*
1599d4f2939cSRui Paulo 	 * In case the device supports creating a separate interface the
1600d4f2939cSRui Paulo 	 * DBus client will need to know the object path for the interface
1601d4f2939cSRui Paulo 	 * object this group was created on, so include it here.
1602d4f2939cSRui Paulo 	 */
16035b9c547cSRui Paulo 	if (!wpa_dbus_dict_open_write(&iter, &dict_iter) ||
16045b9c547cSRui Paulo 	    !wpa_dbus_dict_append_object_path(&dict_iter,
1605d4f2939cSRui Paulo 					      "interface_object",
16065b9c547cSRui Paulo 					      wpa_s->dbus_new_path) ||
16075b9c547cSRui Paulo 	    !wpa_dbus_dict_append_string(&dict_iter, "role",
16085b9c547cSRui Paulo 					 client ? "client" : "GO") ||
1609780fb4a2SCy Schubert 	    !wpa_dbus_dict_append_bool(&dict_iter, "persistent", persistent) ||
16105b9c547cSRui Paulo 	    !wpa_dbus_dict_append_object_path(&dict_iter, "group_object",
16115b9c547cSRui Paulo 					      wpa_s->dbus_groupobj_path) ||
161285732ac8SCy Schubert 	    (ip &&
161385732ac8SCy Schubert 	     (!wpa_dbus_dict_append_byte_array(&dict_iter, "IpAddr",
161485732ac8SCy Schubert 					       (char *) ip, 4) ||
161585732ac8SCy Schubert 	      !wpa_dbus_dict_append_byte_array(&dict_iter, "IpAddrMask",
161685732ac8SCy Schubert 					       (char *) ip + 4, 4) ||
161785732ac8SCy Schubert 	      !wpa_dbus_dict_append_byte_array(&dict_iter, "IpAddrGo",
161885732ac8SCy Schubert 					       (char *) ip + 8, 4))) ||
16195b9c547cSRui Paulo 	    !wpa_dbus_dict_close_write(&iter, &dict_iter)) {
16205b9c547cSRui Paulo 		wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
16215b9c547cSRui Paulo 	} else {
1622d4f2939cSRui Paulo 		dbus_connection_send(iface->con, msg, NULL);
16235b9c547cSRui Paulo 		if (client)
16245b9c547cSRui Paulo 			peer_groups_changed(wpa_s);
16255b9c547cSRui Paulo 	}
1626d4f2939cSRui Paulo 	dbus_message_unref(msg);
1627d4f2939cSRui Paulo }
1628d4f2939cSRui Paulo 
1629d4f2939cSRui Paulo 
1630d4f2939cSRui Paulo /**
1631325151a3SRui Paulo  * wpas_dbus_signal_p2p_go_neg_resp - Emit GONegotiation Success/Failure signal
1632325151a3SRui Paulo  * @wpa_s: %wpa_supplicant network interface data
1633325151a3SRui Paulo  * @res: Result of the GO Neg Request
1634d4f2939cSRui Paulo  */
1635d4f2939cSRui Paulo void wpas_dbus_signal_p2p_go_neg_resp(struct wpa_supplicant *wpa_s,
1636d4f2939cSRui Paulo 				      struct p2p_go_neg_results *res)
1637d4f2939cSRui Paulo {
1638d4f2939cSRui Paulo 	DBusMessage *msg;
1639d4f2939cSRui Paulo 	DBusMessageIter iter, dict_iter;
1640d4f2939cSRui Paulo 	DBusMessageIter iter_dict_entry, iter_dict_val, iter_dict_array;
1641d4f2939cSRui Paulo 	struct wpas_dbus_priv *iface;
1642d4f2939cSRui Paulo 	char peer_obj_path[WPAS_DBUS_OBJECT_PATH_MAX], *path;
1643d4f2939cSRui Paulo 	dbus_int32_t freqs[P2P_MAX_CHANNELS];
1644d4f2939cSRui Paulo 	dbus_int32_t *f_array = freqs;
1645d4f2939cSRui Paulo 
1646d4f2939cSRui Paulo 
1647d4f2939cSRui Paulo 	iface = wpa_s->global->dbus;
1648d4f2939cSRui Paulo 
16495b9c547cSRui Paulo 	if (wpa_s->p2p_mgmt)
16505b9c547cSRui Paulo 		wpa_s = wpa_s->parent;
16515b9c547cSRui Paulo 
1652d4f2939cSRui Paulo 	os_memset(freqs, 0, sizeof(freqs));
1653d4f2939cSRui Paulo 	/* Do nothing if the control interface is not turned on */
1654325151a3SRui Paulo 	if (iface == NULL || !wpa_s->dbus_new_path)
1655d4f2939cSRui Paulo 		return;
1656d4f2939cSRui Paulo 
1657d4f2939cSRui Paulo 	os_snprintf(peer_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
1658d4f2939cSRui Paulo 		    "%s/" WPAS_DBUS_NEW_P2P_PEERS_PART "/" COMPACT_MACSTR,
1659d4f2939cSRui Paulo 		    wpa_s->dbus_new_path, MAC2STR(res->peer_device_addr));
1660d4f2939cSRui Paulo 	path = peer_obj_path;
1661d4f2939cSRui Paulo 
1662d4f2939cSRui Paulo 	msg = dbus_message_new_signal(wpa_s->dbus_new_path,
1663d4f2939cSRui Paulo 				      WPAS_DBUS_NEW_IFACE_P2PDEVICE,
1664d4f2939cSRui Paulo 				      res->status ? "GONegotiationFailure" :
1665d4f2939cSRui Paulo 						    "GONegotiationSuccess");
1666d4f2939cSRui Paulo 	if (msg == NULL)
1667d4f2939cSRui Paulo 		return;
1668d4f2939cSRui Paulo 
1669d4f2939cSRui Paulo 	dbus_message_iter_init_append(msg, &iter);
16705b9c547cSRui Paulo 	if (!wpa_dbus_dict_open_write(&iter, &dict_iter) ||
16715b9c547cSRui Paulo 	    !wpa_dbus_dict_append_object_path(&dict_iter, "peer_object",
1672d4f2939cSRui Paulo 					      path) ||
1673d4f2939cSRui Paulo 	    !wpa_dbus_dict_append_int32(&dict_iter, "status", res->status))
1674d4f2939cSRui Paulo 		goto err;
1675d4f2939cSRui Paulo 
1676d4f2939cSRui Paulo 	if (!res->status) {
1677d4f2939cSRui Paulo 		int i = 0;
1678d4f2939cSRui Paulo 		int freq_list_num = 0;
1679d4f2939cSRui Paulo 
16805b9c547cSRui Paulo 		if ((res->role_go &&
16815b9c547cSRui Paulo 		     !wpa_dbus_dict_append_string(&dict_iter, "passphrase",
16825b9c547cSRui Paulo 						  res->passphrase)) ||
16835b9c547cSRui Paulo 		    !wpa_dbus_dict_append_string(&dict_iter, "role_go",
1684d4f2939cSRui Paulo 						 res->role_go ? "GO" :
1685d4f2939cSRui Paulo 						 "client") ||
1686d4f2939cSRui Paulo 		    !wpa_dbus_dict_append_int32(&dict_iter, "frequency",
1687d4f2939cSRui Paulo 						res->freq) ||
1688d4f2939cSRui Paulo 		    !wpa_dbus_dict_append_byte_array(&dict_iter, "ssid",
1689d4f2939cSRui Paulo 						     (const char *) res->ssid,
1690d4f2939cSRui Paulo 						     res->ssid_len) ||
1691d4f2939cSRui Paulo 		    !wpa_dbus_dict_append_byte_array(&dict_iter,
1692d4f2939cSRui Paulo 						     "peer_device_addr",
1693d4f2939cSRui Paulo 						     (const char *)
1694d4f2939cSRui Paulo 						     res->peer_device_addr,
1695d4f2939cSRui Paulo 						     ETH_ALEN) ||
1696d4f2939cSRui Paulo 		    !wpa_dbus_dict_append_byte_array(&dict_iter,
1697d4f2939cSRui Paulo 						     "peer_interface_addr",
1698d4f2939cSRui Paulo 						     (const char *)
1699d4f2939cSRui Paulo 						     res->peer_interface_addr,
1700d4f2939cSRui Paulo 						     ETH_ALEN) ||
1701d4f2939cSRui Paulo 		    !wpa_dbus_dict_append_string(&dict_iter, "wps_method",
1702d4f2939cSRui Paulo 						 p2p_wps_method_text(
1703d4f2939cSRui Paulo 							 res->wps_method)))
1704d4f2939cSRui Paulo 			goto err;
1705d4f2939cSRui Paulo 
1706d4f2939cSRui Paulo 		for (i = 0; i < P2P_MAX_CHANNELS; i++) {
1707d4f2939cSRui Paulo 			if (res->freq_list[i]) {
1708d4f2939cSRui Paulo 				freqs[i] = res->freq_list[i];
1709d4f2939cSRui Paulo 				freq_list_num++;
1710d4f2939cSRui Paulo 			}
1711d4f2939cSRui Paulo 		}
1712d4f2939cSRui Paulo 
1713d4f2939cSRui Paulo 		if (!wpa_dbus_dict_begin_array(&dict_iter,
1714d4f2939cSRui Paulo 					       "frequency_list",
1715d4f2939cSRui Paulo 					       DBUS_TYPE_INT32_AS_STRING,
1716d4f2939cSRui Paulo 					       &iter_dict_entry,
1717d4f2939cSRui Paulo 					       &iter_dict_val,
17185b9c547cSRui Paulo 					       &iter_dict_array) ||
17195b9c547cSRui Paulo 		    !dbus_message_iter_append_fixed_array(&iter_dict_array,
1720d4f2939cSRui Paulo 							  DBUS_TYPE_INT32,
1721d4f2939cSRui Paulo 							  &f_array,
17225b9c547cSRui Paulo 							  freq_list_num) ||
17235b9c547cSRui Paulo 		    !wpa_dbus_dict_end_array(&dict_iter,
1724d4f2939cSRui Paulo 					     &iter_dict_entry,
1725d4f2939cSRui Paulo 					     &iter_dict_val,
17265b9c547cSRui Paulo 					     &iter_dict_array) ||
17275b9c547cSRui Paulo 		    !wpa_dbus_dict_append_int32(&dict_iter, "persistent_group",
1728d4f2939cSRui Paulo 						res->persistent_group) ||
1729d4f2939cSRui Paulo 		    !wpa_dbus_dict_append_uint32(&dict_iter,
1730d4f2939cSRui Paulo 						 "peer_config_timeout",
1731d4f2939cSRui Paulo 						 res->peer_config_timeout))
1732d4f2939cSRui Paulo 			goto err;
1733d4f2939cSRui Paulo 	}
1734d4f2939cSRui Paulo 
1735d4f2939cSRui Paulo 	if (!wpa_dbus_dict_close_write(&iter, &dict_iter))
1736d4f2939cSRui Paulo 		goto err;
1737d4f2939cSRui Paulo 
1738d4f2939cSRui Paulo 	dbus_connection_send(iface->con, msg, NULL);
1739d4f2939cSRui Paulo err:
1740d4f2939cSRui Paulo 	dbus_message_unref(msg);
1741d4f2939cSRui Paulo }
1742d4f2939cSRui Paulo 
1743d4f2939cSRui Paulo 
1744d4f2939cSRui Paulo /**
1745325151a3SRui Paulo  * wpas_dbus_signal_p2p_invitation_result - Emit InvitationResult signal
1746325151a3SRui Paulo  * @wpa_s: %wpa_supplicant network interface data
1747325151a3SRui Paulo  * @status: Status of invitation process
1748d4f2939cSRui Paulo  * @bssid: Basic Service Set Identifier
1749d4f2939cSRui Paulo  */
1750d4f2939cSRui Paulo void wpas_dbus_signal_p2p_invitation_result(struct wpa_supplicant *wpa_s,
1751d4f2939cSRui Paulo 					    int status, const u8 *bssid)
1752d4f2939cSRui Paulo {
1753d4f2939cSRui Paulo 	DBusMessage *msg;
1754d4f2939cSRui Paulo 	DBusMessageIter iter, dict_iter;
1755d4f2939cSRui Paulo 	struct wpas_dbus_priv *iface;
1756d4f2939cSRui Paulo 
17575b9c547cSRui Paulo 	wpa_printf(MSG_DEBUG, "%s", __func__);
1758d4f2939cSRui Paulo 
1759d4f2939cSRui Paulo 	iface = wpa_s->global->dbus;
1760d4f2939cSRui Paulo 	/* Do nothing if the control interface is not turned on */
1761d4f2939cSRui Paulo 	if (iface == NULL)
1762d4f2939cSRui Paulo 		return;
1763d4f2939cSRui Paulo 
17645b9c547cSRui Paulo 	if (wpa_s->p2p_mgmt)
17655b9c547cSRui Paulo 		wpa_s = wpa_s->parent;
1766325151a3SRui Paulo 	if (!wpa_s->dbus_new_path)
1767325151a3SRui Paulo 		return;
17685b9c547cSRui Paulo 
1769d4f2939cSRui Paulo 	msg = dbus_message_new_signal(wpa_s->dbus_new_path,
1770d4f2939cSRui Paulo 				      WPAS_DBUS_NEW_IFACE_P2PDEVICE,
1771d4f2939cSRui Paulo 				      "InvitationResult");
1772d4f2939cSRui Paulo 
1773d4f2939cSRui Paulo 	if (msg == NULL)
1774d4f2939cSRui Paulo 		return;
1775d4f2939cSRui Paulo 
1776d4f2939cSRui Paulo 	dbus_message_iter_init_append(msg, &iter);
17775b9c547cSRui Paulo 	if (!wpa_dbus_dict_open_write(&iter, &dict_iter) ||
17785b9c547cSRui Paulo 	    !wpa_dbus_dict_append_int32(&dict_iter, "status", status) ||
17795b9c547cSRui Paulo 	    (bssid &&
17805b9c547cSRui Paulo 	     !wpa_dbus_dict_append_byte_array(&dict_iter, "BSSID",
1781d4f2939cSRui Paulo 					      (const char *) bssid,
17825b9c547cSRui Paulo 					      ETH_ALEN)) ||
17835b9c547cSRui Paulo 	    !wpa_dbus_dict_close_write(&iter, &dict_iter))
17845b9c547cSRui Paulo 		wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
17855b9c547cSRui Paulo 	else
1786d4f2939cSRui Paulo 		dbus_connection_send(iface->con, msg, NULL);
1787d4f2939cSRui Paulo 	dbus_message_unref(msg);
1788d4f2939cSRui Paulo }
1789d4f2939cSRui Paulo 
1790d4f2939cSRui Paulo 
1791d4f2939cSRui Paulo /**
1792d4f2939cSRui Paulo  *
1793d4f2939cSRui Paulo  * Method to emit a signal for a peer joining the group.
1794d4f2939cSRui Paulo  * The signal will carry path to the group member object
1795d4f2939cSRui Paulo  * constructed using p2p i/f addr used for connecting.
1796d4f2939cSRui Paulo  *
1797d4f2939cSRui Paulo  * @wpa_s: %wpa_supplicant network interface data
17985b9c547cSRui Paulo  * @peer_addr: P2P Device Address of the peer joining the group
1799d4f2939cSRui Paulo  */
1800d4f2939cSRui Paulo void wpas_dbus_signal_p2p_peer_joined(struct wpa_supplicant *wpa_s,
18015b9c547cSRui Paulo 				      const u8 *peer_addr)
1802d4f2939cSRui Paulo {
1803d4f2939cSRui Paulo 	struct wpas_dbus_priv *iface;
1804d4f2939cSRui Paulo 	DBusMessage *msg;
1805d4f2939cSRui Paulo 	DBusMessageIter iter;
18065b9c547cSRui Paulo 	char peer_obj_path[WPAS_DBUS_OBJECT_PATH_MAX], *path;
18075b9c547cSRui Paulo 	struct wpa_supplicant *parent;
1808d4f2939cSRui Paulo 
1809d4f2939cSRui Paulo 	iface = wpa_s->global->dbus;
1810d4f2939cSRui Paulo 
1811d4f2939cSRui Paulo 	/* Do nothing if the control interface is not turned on */
1812d4f2939cSRui Paulo 	if (iface == NULL)
1813d4f2939cSRui Paulo 		return;
1814d4f2939cSRui Paulo 
1815d4f2939cSRui Paulo 	if (!wpa_s->dbus_groupobj_path)
1816d4f2939cSRui Paulo 		return;
1817d4f2939cSRui Paulo 
18185b9c547cSRui Paulo 	parent = wpa_s->parent;
18195b9c547cSRui Paulo 	if (parent->p2p_mgmt)
18205b9c547cSRui Paulo 		parent = parent->parent;
1821325151a3SRui Paulo 	if (!parent->dbus_new_path)
1822325151a3SRui Paulo 		return;
18235b9c547cSRui Paulo 
18245b9c547cSRui Paulo 	os_snprintf(peer_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
18255b9c547cSRui Paulo 			"%s/" WPAS_DBUS_NEW_P2P_PEERS_PART "/"
1826d4f2939cSRui Paulo 			COMPACT_MACSTR,
18275b9c547cSRui Paulo 			parent->dbus_new_path, MAC2STR(peer_addr));
1828d4f2939cSRui Paulo 
1829d4f2939cSRui Paulo 	msg = dbus_message_new_signal(wpa_s->dbus_groupobj_path,
1830d4f2939cSRui Paulo 				      WPAS_DBUS_NEW_IFACE_P2P_GROUP,
1831d4f2939cSRui Paulo 				      "PeerJoined");
1832d4f2939cSRui Paulo 	if (msg == NULL)
1833d4f2939cSRui Paulo 		return;
1834d4f2939cSRui Paulo 
1835d4f2939cSRui Paulo 	dbus_message_iter_init_append(msg, &iter);
18365b9c547cSRui Paulo 	path = peer_obj_path;
1837d4f2939cSRui Paulo 	if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_OBJECT_PATH,
18385b9c547cSRui Paulo 					    &path)) {
1839d4f2939cSRui Paulo 		wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
18405b9c547cSRui Paulo 	} else {
18415b9c547cSRui Paulo 		dbus_connection_send(iface->con, msg, NULL);
18425b9c547cSRui Paulo 		wpas_dbus_signal_peer_groups_changed(parent, peer_addr);
18435b9c547cSRui Paulo 	}
1844d4f2939cSRui Paulo 	dbus_message_unref(msg);
1845d4f2939cSRui Paulo }
1846d4f2939cSRui Paulo 
1847d4f2939cSRui Paulo 
1848d4f2939cSRui Paulo /**
1849d4f2939cSRui Paulo  *
1850d4f2939cSRui Paulo  * Method to emit a signal for a peer disconnecting the group.
1851d4f2939cSRui Paulo  * The signal will carry path to the group member object
18525b9c547cSRui Paulo  * constructed using the P2P Device Address of the peer.
1853d4f2939cSRui Paulo  *
1854d4f2939cSRui Paulo  * @wpa_s: %wpa_supplicant network interface data
18555b9c547cSRui Paulo  * @peer_addr: P2P Device Address of the peer joining the group
1856d4f2939cSRui Paulo  */
1857d4f2939cSRui Paulo void wpas_dbus_signal_p2p_peer_disconnected(struct wpa_supplicant *wpa_s,
18585b9c547cSRui Paulo 					    const u8 *peer_addr)
1859d4f2939cSRui Paulo {
1860d4f2939cSRui Paulo 	struct wpas_dbus_priv *iface;
1861d4f2939cSRui Paulo 	DBusMessage *msg;
1862d4f2939cSRui Paulo 	DBusMessageIter iter;
18635b9c547cSRui Paulo 	char peer_obj_path[WPAS_DBUS_OBJECT_PATH_MAX], *path;
18645b9c547cSRui Paulo 	struct wpa_supplicant *parent;
1865d4f2939cSRui Paulo 
1866d4f2939cSRui Paulo 	iface = wpa_s->global->dbus;
1867d4f2939cSRui Paulo 
1868d4f2939cSRui Paulo 	/* Do nothing if the control interface is not turned on */
1869d4f2939cSRui Paulo 	if (iface == NULL)
1870d4f2939cSRui Paulo 		return;
1871d4f2939cSRui Paulo 
1872d4f2939cSRui Paulo 	if (!wpa_s->dbus_groupobj_path)
1873d4f2939cSRui Paulo 		return;
1874d4f2939cSRui Paulo 
18755b9c547cSRui Paulo 	parent = wpa_s->parent;
18765b9c547cSRui Paulo 	if (parent->p2p_mgmt)
18775b9c547cSRui Paulo 		parent = parent->parent;
1878325151a3SRui Paulo 	if (!parent->dbus_new_path)
1879325151a3SRui Paulo 		return;
18805b9c547cSRui Paulo 
18815b9c547cSRui Paulo 	os_snprintf(peer_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
18825b9c547cSRui Paulo 			"%s/" WPAS_DBUS_NEW_P2P_PEERS_PART "/"
1883d4f2939cSRui Paulo 			COMPACT_MACSTR,
18845b9c547cSRui Paulo 			parent->dbus_new_path, MAC2STR(peer_addr));
1885d4f2939cSRui Paulo 
1886d4f2939cSRui Paulo 	msg = dbus_message_new_signal(wpa_s->dbus_groupobj_path,
1887d4f2939cSRui Paulo 				      WPAS_DBUS_NEW_IFACE_P2P_GROUP,
1888d4f2939cSRui Paulo 				      "PeerDisconnected");
1889d4f2939cSRui Paulo 	if (msg == NULL)
1890d4f2939cSRui Paulo 		return;
1891d4f2939cSRui Paulo 
1892d4f2939cSRui Paulo 	dbus_message_iter_init_append(msg, &iter);
18935b9c547cSRui Paulo 	path = peer_obj_path;
1894d4f2939cSRui Paulo 	if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_OBJECT_PATH,
18955b9c547cSRui Paulo 					    &path)) {
18965b9c547cSRui Paulo 		wpa_printf(MSG_ERROR,
18975b9c547cSRui Paulo 			   "dbus: Failed to construct PeerDisconnected signal");
18985b9c547cSRui Paulo 	} else {
1899d4f2939cSRui Paulo 		dbus_connection_send(iface->con, msg, NULL);
19005b9c547cSRui Paulo 		wpas_dbus_signal_peer_groups_changed(parent, peer_addr);
19015b9c547cSRui Paulo 	}
1902d4f2939cSRui Paulo 	dbus_message_unref(msg);
1903d4f2939cSRui Paulo }
1904d4f2939cSRui Paulo 
1905d4f2939cSRui Paulo 
1906d4f2939cSRui Paulo /**
1907d4f2939cSRui Paulo  *
1908d4f2939cSRui Paulo  * Method to emit a signal for a service discovery request.
1909d4f2939cSRui Paulo  * The signal will carry station address, frequency, dialog token,
1910d4f2939cSRui Paulo  * update indicator and it tlvs
1911d4f2939cSRui Paulo  *
1912d4f2939cSRui Paulo  * @wpa_s: %wpa_supplicant network interface data
1913d4f2939cSRui Paulo  * @sa: station addr (p2p i/f) of the peer
1914d4f2939cSRui Paulo  * @dialog_token: service discovery request dialog token
1915d4f2939cSRui Paulo  * @update_indic: service discovery request update indicator
1916c1d255d3SCy Schubert  * @tlvs: service discovery request generated byte array of tlvs
1917d4f2939cSRui Paulo  * @tlvs_len: service discovery request tlvs length
1918d4f2939cSRui Paulo  */
1919d4f2939cSRui Paulo void wpas_dbus_signal_p2p_sd_request(struct wpa_supplicant *wpa_s,
1920d4f2939cSRui Paulo 				     int freq, const u8 *sa, u8 dialog_token,
1921d4f2939cSRui Paulo 				     u16 update_indic, const u8 *tlvs,
1922d4f2939cSRui Paulo 				     size_t tlvs_len)
1923d4f2939cSRui Paulo {
1924d4f2939cSRui Paulo 	DBusMessage *msg;
1925d4f2939cSRui Paulo 	DBusMessageIter iter, dict_iter;
1926d4f2939cSRui Paulo 	struct wpas_dbus_priv *iface;
1927d4f2939cSRui Paulo 	char peer_obj_path[WPAS_DBUS_OBJECT_PATH_MAX], *path;
19285b9c547cSRui Paulo 
1929d4f2939cSRui Paulo 	iface = wpa_s->global->dbus;
1930d4f2939cSRui Paulo 
1931d4f2939cSRui Paulo 	/* Do nothing if the control interface is not turned on */
1932d4f2939cSRui Paulo 	if (iface == NULL)
1933d4f2939cSRui Paulo 		return;
1934d4f2939cSRui Paulo 
19355b9c547cSRui Paulo 	if (wpa_s->p2p_mgmt)
19365b9c547cSRui Paulo 		wpa_s = wpa_s->parent;
1937325151a3SRui Paulo 	if (!wpa_s->dbus_new_path)
1938325151a3SRui Paulo 		return;
19395b9c547cSRui Paulo 
19405b9c547cSRui Paulo 	/* Check if this is a known peer */
19415b9c547cSRui Paulo 	if (!p2p_peer_known(wpa_s->global->p2p, sa))
19425b9c547cSRui Paulo 		return;
19435b9c547cSRui Paulo 
1944d4f2939cSRui Paulo 	msg = dbus_message_new_signal(wpa_s->dbus_new_path,
1945d4f2939cSRui Paulo 				      WPAS_DBUS_NEW_IFACE_P2PDEVICE,
1946d4f2939cSRui Paulo 				      "ServiceDiscoveryRequest");
1947d4f2939cSRui Paulo 	if (msg == NULL)
1948d4f2939cSRui Paulo 		return;
1949d4f2939cSRui Paulo 
1950d4f2939cSRui Paulo 	os_snprintf(peer_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
1951d4f2939cSRui Paulo 		    "%s/" WPAS_DBUS_NEW_P2P_PEERS_PART "/"
1952d4f2939cSRui Paulo 		    COMPACT_MACSTR, wpa_s->dbus_new_path, MAC2STR(sa));
1953d4f2939cSRui Paulo 
1954d4f2939cSRui Paulo 	path = peer_obj_path;
1955d4f2939cSRui Paulo 
1956d4f2939cSRui Paulo 	dbus_message_iter_init_append(msg, &iter);
19575b9c547cSRui Paulo 	if (!wpa_dbus_dict_open_write(&iter, &dict_iter) ||
19585b9c547cSRui Paulo 	    !wpa_dbus_dict_append_object_path(&dict_iter, "peer_object",
1959d4f2939cSRui Paulo 					      path) ||
1960d4f2939cSRui Paulo 	    !wpa_dbus_dict_append_int32(&dict_iter, "frequency", freq) ||
1961d4f2939cSRui Paulo 	    !wpa_dbus_dict_append_int32(&dict_iter, "dialog_token",
1962d4f2939cSRui Paulo 					dialog_token) ||
1963d4f2939cSRui Paulo 	    !wpa_dbus_dict_append_uint16(&dict_iter, "update_indicator",
1964d4f2939cSRui Paulo 					 update_indic) ||
1965d4f2939cSRui Paulo 	    !wpa_dbus_dict_append_byte_array(&dict_iter, "tlvs",
1966d4f2939cSRui Paulo 					     (const char *) tlvs,
1967d4f2939cSRui Paulo 					     tlvs_len) ||
1968d4f2939cSRui Paulo 	    !wpa_dbus_dict_close_write(&iter, &dict_iter))
1969d4f2939cSRui Paulo 		wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
19705b9c547cSRui Paulo 	else
19715b9c547cSRui Paulo 		dbus_connection_send(iface->con, msg, NULL);
1972d4f2939cSRui Paulo 	dbus_message_unref(msg);
1973d4f2939cSRui Paulo }
1974d4f2939cSRui Paulo 
1975d4f2939cSRui Paulo 
1976d4f2939cSRui Paulo /**
1977d4f2939cSRui Paulo  *
1978d4f2939cSRui Paulo  * Method to emit a signal for a service discovery response.
1979d4f2939cSRui Paulo  * The signal will carry station address, update indicator and it
1980d4f2939cSRui Paulo  * tlvs
1981d4f2939cSRui Paulo  *
1982d4f2939cSRui Paulo  * @wpa_s: %wpa_supplicant network interface data
1983d4f2939cSRui Paulo  * @sa: station addr (p2p i/f) of the peer
1984d4f2939cSRui Paulo  * @update_indic: service discovery request update indicator
1985c1d255d3SCy Schubert  * @tlvs: service discovery request generated byte array of tlvs
1986d4f2939cSRui Paulo  * @tlvs_len: service discovery request tlvs length
1987d4f2939cSRui Paulo  */
1988d4f2939cSRui Paulo void wpas_dbus_signal_p2p_sd_response(struct wpa_supplicant *wpa_s,
1989d4f2939cSRui Paulo 				      const u8 *sa, u16 update_indic,
1990d4f2939cSRui Paulo 				      const u8 *tlvs, size_t tlvs_len)
1991d4f2939cSRui Paulo {
1992d4f2939cSRui Paulo 	DBusMessage *msg;
1993d4f2939cSRui Paulo 	DBusMessageIter iter, dict_iter;
1994d4f2939cSRui Paulo 	struct wpas_dbus_priv *iface;
1995d4f2939cSRui Paulo 	char peer_obj_path[WPAS_DBUS_OBJECT_PATH_MAX], *path;
19965b9c547cSRui Paulo 
1997d4f2939cSRui Paulo 	iface = wpa_s->global->dbus;
1998d4f2939cSRui Paulo 
1999d4f2939cSRui Paulo 	/* Do nothing if the control interface is not turned on */
2000d4f2939cSRui Paulo 	if (iface == NULL)
2001d4f2939cSRui Paulo 		return;
2002d4f2939cSRui Paulo 
20035b9c547cSRui Paulo 	if (wpa_s->p2p_mgmt)
20045b9c547cSRui Paulo 		wpa_s = wpa_s->parent;
2005325151a3SRui Paulo 	if (!wpa_s->dbus_new_path)
2006325151a3SRui Paulo 		return;
20075b9c547cSRui Paulo 
20085b9c547cSRui Paulo 	/* Check if this is a known peer */
20095b9c547cSRui Paulo 	if (!p2p_peer_known(wpa_s->global->p2p, sa))
20105b9c547cSRui Paulo 		return;
20115b9c547cSRui Paulo 
2012d4f2939cSRui Paulo 	msg = dbus_message_new_signal(wpa_s->dbus_new_path,
2013d4f2939cSRui Paulo 				      WPAS_DBUS_NEW_IFACE_P2PDEVICE,
2014d4f2939cSRui Paulo 				      "ServiceDiscoveryResponse");
2015d4f2939cSRui Paulo 	if (msg == NULL)
2016d4f2939cSRui Paulo 		return;
2017d4f2939cSRui Paulo 
2018d4f2939cSRui Paulo 	os_snprintf(peer_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
2019d4f2939cSRui Paulo 		    "%s/" WPAS_DBUS_NEW_P2P_PEERS_PART "/"
2020d4f2939cSRui Paulo 		    COMPACT_MACSTR, wpa_s->dbus_new_path, MAC2STR(sa));
2021d4f2939cSRui Paulo 
2022d4f2939cSRui Paulo 	path = peer_obj_path;
2023d4f2939cSRui Paulo 
2024d4f2939cSRui Paulo 	dbus_message_iter_init_append(msg, &iter);
20255b9c547cSRui Paulo 	if (!wpa_dbus_dict_open_write(&iter, &dict_iter) ||
20265b9c547cSRui Paulo 	    !wpa_dbus_dict_append_object_path(&dict_iter, "peer_object",
2027d4f2939cSRui Paulo 					      path) ||
2028d4f2939cSRui Paulo 	    !wpa_dbus_dict_append_uint16(&dict_iter, "update_indicator",
2029d4f2939cSRui Paulo 					 update_indic) ||
2030d4f2939cSRui Paulo 	    !wpa_dbus_dict_append_byte_array(&dict_iter, "tlvs",
2031d4f2939cSRui Paulo 					     (const char *) tlvs,
2032d4f2939cSRui Paulo 					     tlvs_len) ||
2033d4f2939cSRui Paulo 	    !wpa_dbus_dict_close_write(&iter, &dict_iter))
20345b9c547cSRui Paulo 		wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
20355b9c547cSRui Paulo 	else
2036d4f2939cSRui Paulo 		dbus_connection_send(iface->con, msg, NULL);
2037d4f2939cSRui Paulo 	dbus_message_unref(msg);
2038d4f2939cSRui Paulo }
2039d4f2939cSRui Paulo 
20405b9c547cSRui Paulo 
2041d4f2939cSRui Paulo /**
2042d4f2939cSRui Paulo  * wpas_dbus_signal_persistent_group - Send a persistent group related
2043d4f2939cSRui Paulo  *	event signal
2044d4f2939cSRui Paulo  * @wpa_s: %wpa_supplicant network interface data
2045d4f2939cSRui Paulo  * @id: new persistent group id
2046d4f2939cSRui Paulo  * @sig_name: signal name - PersistentGroupAdded, PersistentGroupRemoved
2047d4f2939cSRui Paulo  * @properties: determines if add second argument with object properties
2048d4f2939cSRui Paulo  *
2049d4f2939cSRui Paulo  * Notify listeners about an event related to persistent groups.
2050d4f2939cSRui Paulo  */
2051d4f2939cSRui Paulo static void wpas_dbus_signal_persistent_group(struct wpa_supplicant *wpa_s,
2052d4f2939cSRui Paulo 					      int id, const char *sig_name,
20534bc52338SCy Schubert 					      dbus_bool_t properties)
2054d4f2939cSRui Paulo {
2055d4f2939cSRui Paulo 	struct wpas_dbus_priv *iface;
2056d4f2939cSRui Paulo 	DBusMessage *msg;
2057d4f2939cSRui Paulo 	DBusMessageIter iter;
2058d4f2939cSRui Paulo 	char pgrp_obj_path[WPAS_DBUS_OBJECT_PATH_MAX], *path;
2059d4f2939cSRui Paulo 
2060d4f2939cSRui Paulo 	iface = wpa_s->global->dbus;
2061d4f2939cSRui Paulo 
2062d4f2939cSRui Paulo 	/* Do nothing if the control interface is not turned on */
2063d4f2939cSRui Paulo 	if (iface == NULL)
2064d4f2939cSRui Paulo 		return;
2065d4f2939cSRui Paulo 
20665b9c547cSRui Paulo 	if (wpa_s->p2p_mgmt)
20675b9c547cSRui Paulo 		wpa_s = wpa_s->parent;
2068325151a3SRui Paulo 	if (!wpa_s->dbus_new_path)
2069325151a3SRui Paulo 		return;
20705b9c547cSRui Paulo 
2071d4f2939cSRui Paulo 	os_snprintf(pgrp_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
2072d4f2939cSRui Paulo 		    "%s/" WPAS_DBUS_NEW_PERSISTENT_GROUPS_PART "/%u",
2073d4f2939cSRui Paulo 		    wpa_s->dbus_new_path, id);
2074d4f2939cSRui Paulo 
2075d4f2939cSRui Paulo 	msg = dbus_message_new_signal(wpa_s->dbus_new_path,
2076d4f2939cSRui Paulo 				      WPAS_DBUS_NEW_IFACE_P2PDEVICE,
2077d4f2939cSRui Paulo 				      sig_name);
2078d4f2939cSRui Paulo 	if (msg == NULL)
2079d4f2939cSRui Paulo 		return;
2080d4f2939cSRui Paulo 
2081d4f2939cSRui Paulo 	dbus_message_iter_init_append(msg, &iter);
2082d4f2939cSRui Paulo 	path = pgrp_obj_path;
2083d4f2939cSRui Paulo 	if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_OBJECT_PATH,
20845b9c547cSRui Paulo 					    &path) ||
20855b9c547cSRui Paulo 	    (properties &&
20865b9c547cSRui Paulo 	     !wpa_dbus_get_object_properties(
2087d4f2939cSRui Paulo 		     iface, pgrp_obj_path,
20885b9c547cSRui Paulo 		     WPAS_DBUS_NEW_IFACE_PERSISTENT_GROUP, &iter)))
20895b9c547cSRui Paulo 		wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
20905b9c547cSRui Paulo 	else
2091d4f2939cSRui Paulo 		dbus_connection_send(iface->con, msg, NULL);
2092d4f2939cSRui Paulo 
2093d4f2939cSRui Paulo 	dbus_message_unref(msg);
2094d4f2939cSRui Paulo }
2095d4f2939cSRui Paulo 
2096d4f2939cSRui Paulo 
2097d4f2939cSRui Paulo /**
2098d4f2939cSRui Paulo  * wpas_dbus_signal_persistent_group_added - Send a persistent_group
2099d4f2939cSRui Paulo  *	added signal
2100d4f2939cSRui Paulo  * @wpa_s: %wpa_supplicant network interface data
2101d4f2939cSRui Paulo  * @id: new persistent group id
2102d4f2939cSRui Paulo  *
2103d4f2939cSRui Paulo  * Notify listeners about addition of a new persistent group.
2104d4f2939cSRui Paulo  */
2105d4f2939cSRui Paulo static void wpas_dbus_signal_persistent_group_added(
2106d4f2939cSRui Paulo 	struct wpa_supplicant *wpa_s, int id)
2107d4f2939cSRui Paulo {
2108d4f2939cSRui Paulo 	wpas_dbus_signal_persistent_group(wpa_s, id, "PersistentGroupAdded",
2109d4f2939cSRui Paulo 					  TRUE);
2110d4f2939cSRui Paulo }
2111d4f2939cSRui Paulo 
2112d4f2939cSRui Paulo 
2113d4f2939cSRui Paulo /**
2114d4f2939cSRui Paulo  * wpas_dbus_signal_persistent_group_removed - Send a persistent_group
2115d4f2939cSRui Paulo  *	removed signal
2116d4f2939cSRui Paulo  * @wpa_s: %wpa_supplicant network interface data
2117d4f2939cSRui Paulo  * @id: persistent group id
2118d4f2939cSRui Paulo  *
2119d4f2939cSRui Paulo  * Notify listeners about removal of a persistent group.
2120d4f2939cSRui Paulo  */
2121d4f2939cSRui Paulo static void wpas_dbus_signal_persistent_group_removed(
2122d4f2939cSRui Paulo 	struct wpa_supplicant *wpa_s, int id)
2123d4f2939cSRui Paulo {
2124d4f2939cSRui Paulo 	wpas_dbus_signal_persistent_group(wpa_s, id, "PersistentGroupRemoved",
2125d4f2939cSRui Paulo 					  FALSE);
2126d4f2939cSRui Paulo }
2127d4f2939cSRui Paulo 
2128d4f2939cSRui Paulo 
2129d4f2939cSRui Paulo /**
2130d4f2939cSRui Paulo  * wpas_dbus_signal_p2p_wps_failed - Signals WpsFailed event
2131d4f2939cSRui Paulo  * @wpa_s: %wpa_supplicant network interface data
2132325151a3SRui Paulo  * @fail: WPS failure information
2133d4f2939cSRui Paulo  *
2134d4f2939cSRui Paulo  * Sends Event dbus signal with name "fail" and dictionary containing
2135d4f2939cSRui Paulo  * "msg" field with fail message number (int32) as arguments
2136d4f2939cSRui Paulo  */
2137d4f2939cSRui Paulo void wpas_dbus_signal_p2p_wps_failed(struct wpa_supplicant *wpa_s,
2138d4f2939cSRui Paulo 				     struct wps_event_fail *fail)
2139d4f2939cSRui Paulo {
2140d4f2939cSRui Paulo 
2141d4f2939cSRui Paulo 	DBusMessage *msg;
2142d4f2939cSRui Paulo 	DBusMessageIter iter, dict_iter;
2143d4f2939cSRui Paulo 	struct wpas_dbus_priv *iface;
2144d4f2939cSRui Paulo 	char *key = "fail";
2145d4f2939cSRui Paulo 
2146d4f2939cSRui Paulo 	iface = wpa_s->global->dbus;
2147d4f2939cSRui Paulo 
2148d4f2939cSRui Paulo 	/* Do nothing if the control interface is not turned on */
2149d4f2939cSRui Paulo 	if (iface == NULL)
2150d4f2939cSRui Paulo 		return;
2151d4f2939cSRui Paulo 
21525b9c547cSRui Paulo 	if (wpa_s->p2p_mgmt)
21535b9c547cSRui Paulo 		wpa_s = wpa_s->parent;
21545b9c547cSRui Paulo 
2155325151a3SRui Paulo 	if (!wpa_s->dbus_new_path)
2156325151a3SRui Paulo 		return;
2157d4f2939cSRui Paulo 	msg = dbus_message_new_signal(wpa_s->dbus_new_path,
2158d4f2939cSRui Paulo 				      WPAS_DBUS_NEW_IFACE_P2PDEVICE,
2159d4f2939cSRui Paulo 				      "WpsFailed");
2160d4f2939cSRui Paulo 	if (msg == NULL)
2161d4f2939cSRui Paulo 		return;
2162d4f2939cSRui Paulo 
2163d4f2939cSRui Paulo 	dbus_message_iter_init_append(msg, &iter);
2164d4f2939cSRui Paulo 
2165d4f2939cSRui Paulo 	if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &key) ||
2166d4f2939cSRui Paulo 	    !wpa_dbus_dict_open_write(&iter, &dict_iter) ||
2167d4f2939cSRui Paulo 	    !wpa_dbus_dict_append_int32(&dict_iter, "msg", fail->msg) ||
2168d4f2939cSRui Paulo 	    !wpa_dbus_dict_append_int16(&dict_iter, "config_error",
2169d4f2939cSRui Paulo 					fail->config_error) ||
2170d4f2939cSRui Paulo 	    !wpa_dbus_dict_close_write(&iter, &dict_iter))
2171d4f2939cSRui Paulo 		wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
2172d4f2939cSRui Paulo 	else
2173d4f2939cSRui Paulo 		dbus_connection_send(iface->con, msg, NULL);
2174d4f2939cSRui Paulo 
2175d4f2939cSRui Paulo 	dbus_message_unref(msg);
2176d4f2939cSRui Paulo }
2177d4f2939cSRui Paulo 
2178325151a3SRui Paulo 
2179325151a3SRui Paulo /**
2180325151a3SRui Paulo  * wpas_dbus_signal_p2p_group_formation_failure - Signals GroupFormationFailure event
2181325151a3SRui Paulo  * @wpa_s: %wpa_supplicant network interface data
2182325151a3SRui Paulo  * @reason: indicates the reason code for group formation failure
2183325151a3SRui Paulo  *
2184325151a3SRui Paulo  * Sends Event dbus signal and string reason code when available.
2185325151a3SRui Paulo  */
2186325151a3SRui Paulo void wpas_dbus_signal_p2p_group_formation_failure(struct wpa_supplicant *wpa_s,
2187325151a3SRui Paulo 						  const char *reason)
2188325151a3SRui Paulo {
2189325151a3SRui Paulo 	DBusMessage *msg;
2190325151a3SRui Paulo 	struct wpas_dbus_priv *iface;
2191325151a3SRui Paulo 
2192325151a3SRui Paulo 	iface = wpa_s->global->dbus;
2193325151a3SRui Paulo 
2194325151a3SRui Paulo 	/* Do nothing if the control interface is not turned on */
2195325151a3SRui Paulo 	if (iface == NULL)
2196325151a3SRui Paulo 		return;
2197325151a3SRui Paulo 
219885732ac8SCy Schubert 	if (wpa_s->p2p_mgmt)
219985732ac8SCy Schubert 		wpa_s = wpa_s->parent;
220085732ac8SCy Schubert 
2201325151a3SRui Paulo 	msg = dbus_message_new_signal(wpa_s->dbus_new_path,
2202325151a3SRui Paulo 				      WPAS_DBUS_NEW_IFACE_P2PDEVICE,
2203325151a3SRui Paulo 				      "GroupFormationFailure");
2204325151a3SRui Paulo 	if (msg == NULL)
2205325151a3SRui Paulo 		return;
2206325151a3SRui Paulo 
2207325151a3SRui Paulo 	if (dbus_message_append_args(msg, DBUS_TYPE_STRING, &reason,
2208325151a3SRui Paulo 				     DBUS_TYPE_INVALID))
2209325151a3SRui Paulo 		dbus_connection_send(iface->con, msg, NULL);
2210325151a3SRui Paulo 	else
2211325151a3SRui Paulo 		wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
2212325151a3SRui Paulo 
2213325151a3SRui Paulo 	dbus_message_unref(msg);
2214325151a3SRui Paulo }
2215325151a3SRui Paulo 
2216325151a3SRui Paulo 
2217325151a3SRui Paulo /**
2218325151a3SRui Paulo  * wpas_dbus_signal_p2p_invitation_received - Emit InvitationReceived signal
2219325151a3SRui Paulo  * @wpa_s: %wpa_supplicant network interface data
2220325151a3SRui Paulo  * @sa: Source address of the Invitation Request
2221325151a3SRui Paulo  * @dev_add: GO Device Address
2222325151a3SRui Paulo  * @bssid: P2P Group BSSID or %NULL if not received
2223325151a3SRui Paulo  * @id: Persistent group id or %0 if not persistent group
2224325151a3SRui Paulo  * @op_freq: Operating frequency for the group
2225325151a3SRui Paulo  */
2226325151a3SRui Paulo 
2227325151a3SRui Paulo void wpas_dbus_signal_p2p_invitation_received(struct wpa_supplicant *wpa_s,
2228325151a3SRui Paulo 					      const u8 *sa, const u8 *dev_addr,
2229325151a3SRui Paulo 					      const u8 *bssid, int id,
2230325151a3SRui Paulo 					      int op_freq)
2231325151a3SRui Paulo {
2232325151a3SRui Paulo 	DBusMessage *msg;
2233325151a3SRui Paulo 	DBusMessageIter iter, dict_iter;
2234325151a3SRui Paulo 	struct wpas_dbus_priv *iface;
2235325151a3SRui Paulo 
2236325151a3SRui Paulo 	iface = wpa_s->global->dbus;
2237325151a3SRui Paulo 
2238325151a3SRui Paulo 	/* Do nothing if the control interface is not turned on */
2239325151a3SRui Paulo 	if (iface == NULL)
2240325151a3SRui Paulo 		return;
2241325151a3SRui Paulo 
224285732ac8SCy Schubert 	if (wpa_s->p2p_mgmt)
224385732ac8SCy Schubert 		wpa_s = wpa_s->parent;
224485732ac8SCy Schubert 
2245325151a3SRui Paulo 	msg = dbus_message_new_signal(wpa_s->dbus_new_path,
2246325151a3SRui Paulo 				      WPAS_DBUS_NEW_IFACE_P2PDEVICE,
2247325151a3SRui Paulo 				      "InvitationReceived");
2248325151a3SRui Paulo 	if (msg == NULL)
2249325151a3SRui Paulo 		return;
2250325151a3SRui Paulo 
2251325151a3SRui Paulo 	dbus_message_iter_init_append(msg, &iter);
2252325151a3SRui Paulo 	if (!wpa_dbus_dict_open_write(&iter, &dict_iter) ||
2253325151a3SRui Paulo 	    (sa &&
2254325151a3SRui Paulo 	     !wpa_dbus_dict_append_byte_array(&dict_iter, "sa",
2255325151a3SRui Paulo 					      (const char *) sa, ETH_ALEN)) ||
2256325151a3SRui Paulo 	    (dev_addr &&
2257325151a3SRui Paulo 	     !wpa_dbus_dict_append_byte_array(&dict_iter, "go_dev_addr",
2258325151a3SRui Paulo 					      (const char *) dev_addr,
2259325151a3SRui Paulo 					      ETH_ALEN)) ||
2260325151a3SRui Paulo 	    (bssid &&
2261325151a3SRui Paulo 	     !wpa_dbus_dict_append_byte_array(&dict_iter, "bssid",
2262325151a3SRui Paulo 					      (const char *) bssid,
2263325151a3SRui Paulo 					      ETH_ALEN)) ||
2264325151a3SRui Paulo 	    (id &&
2265325151a3SRui Paulo 	     !wpa_dbus_dict_append_int32(&dict_iter, "persistent_id", id)) ||
2266325151a3SRui Paulo 	    !wpa_dbus_dict_append_int32(&dict_iter, "op_freq", op_freq) ||
2267325151a3SRui Paulo 	    !wpa_dbus_dict_close_write(&iter, &dict_iter)) {
2268325151a3SRui Paulo 		dbus_message_unref(msg);
2269325151a3SRui Paulo 		return;
2270325151a3SRui Paulo 	}
2271325151a3SRui Paulo 
2272325151a3SRui Paulo 	dbus_connection_send(iface->con, msg, NULL);
2273780fb4a2SCy Schubert 	dbus_message_unref(msg);
2274325151a3SRui Paulo }
2275325151a3SRui Paulo 
2276325151a3SRui Paulo 
2277d4f2939cSRui Paulo #endif /* CONFIG_P2P */
2278d4f2939cSRui Paulo 
2279d4f2939cSRui Paulo 
2280d4f2939cSRui Paulo /**
2281d4f2939cSRui Paulo  * wpas_dbus_signal_prop_changed - Signals change of property
2282d4f2939cSRui Paulo  * @wpa_s: %wpa_supplicant network interface data
2283d4f2939cSRui Paulo  * @property: indicates which property has changed
2284d4f2939cSRui Paulo  *
2285d4f2939cSRui Paulo  * Sends PropertyChanged signals with path, interface and arguments
2286d4f2939cSRui Paulo  * depending on which property has changed.
2287d4f2939cSRui Paulo  */
2288d4f2939cSRui Paulo void wpas_dbus_signal_prop_changed(struct wpa_supplicant *wpa_s,
2289d4f2939cSRui Paulo 				   enum wpas_dbus_prop property)
2290d4f2939cSRui Paulo {
2291d4f2939cSRui Paulo 	char *prop;
2292d4f2939cSRui Paulo 	dbus_bool_t flush;
2293d4f2939cSRui Paulo 
2294d4f2939cSRui Paulo 	if (wpa_s->dbus_new_path == NULL)
2295d4f2939cSRui Paulo 		return; /* Skip signal since D-Bus setup is not yet ready */
2296d4f2939cSRui Paulo 
2297d4f2939cSRui Paulo 	flush = FALSE;
2298d4f2939cSRui Paulo 	switch (property) {
2299d4f2939cSRui Paulo 	case WPAS_DBUS_PROP_AP_SCAN:
2300d4f2939cSRui Paulo 		prop = "ApScan";
2301d4f2939cSRui Paulo 		break;
2302d4f2939cSRui Paulo 	case WPAS_DBUS_PROP_SCANNING:
2303d4f2939cSRui Paulo 		prop = "Scanning";
2304d4f2939cSRui Paulo 		break;
2305d4f2939cSRui Paulo 	case WPAS_DBUS_PROP_STATE:
2306d4f2939cSRui Paulo 		prop = "State";
2307d4f2939cSRui Paulo 		break;
2308d4f2939cSRui Paulo 	case WPAS_DBUS_PROP_CURRENT_BSS:
2309d4f2939cSRui Paulo 		prop = "CurrentBSS";
2310d4f2939cSRui Paulo 		break;
2311d4f2939cSRui Paulo 	case WPAS_DBUS_PROP_CURRENT_NETWORK:
2312d4f2939cSRui Paulo 		prop = "CurrentNetwork";
2313d4f2939cSRui Paulo 		break;
2314d4f2939cSRui Paulo 	case WPAS_DBUS_PROP_BSSS:
2315d4f2939cSRui Paulo 		prop = "BSSs";
2316d4f2939cSRui Paulo 		break;
23174bc52338SCy Schubert 	case WPAS_DBUS_PROP_STATIONS:
23184bc52338SCy Schubert 		prop = "Stations";
23194bc52338SCy Schubert 		break;
2320d4f2939cSRui Paulo 	case WPAS_DBUS_PROP_CURRENT_AUTH_MODE:
2321d4f2939cSRui Paulo 		prop = "CurrentAuthMode";
2322d4f2939cSRui Paulo 		break;
2323d4f2939cSRui Paulo 	case WPAS_DBUS_PROP_DISCONNECT_REASON:
2324d4f2939cSRui Paulo 		prop = "DisconnectReason";
2325d4f2939cSRui Paulo 		flush = TRUE;
2326d4f2939cSRui Paulo 		break;
23274bc52338SCy Schubert 	case WPAS_DBUS_PROP_AUTH_STATUS_CODE:
23284bc52338SCy Schubert 		prop = "AuthStatusCode";
23294bc52338SCy Schubert 		flush = TRUE;
23304bc52338SCy Schubert 		break;
2331780fb4a2SCy Schubert 	case WPAS_DBUS_PROP_ASSOC_STATUS_CODE:
2332780fb4a2SCy Schubert 		prop = "AssocStatusCode";
2333780fb4a2SCy Schubert 		flush = TRUE;
2334780fb4a2SCy Schubert 		break;
23354bc52338SCy Schubert 	case WPAS_DBUS_PROP_ROAM_TIME:
23364bc52338SCy Schubert 		prop = "RoamTime";
23374bc52338SCy Schubert 		break;
23384bc52338SCy Schubert 	case WPAS_DBUS_PROP_ROAM_COMPLETE:
23394bc52338SCy Schubert 		prop = "RoamComplete";
23404bc52338SCy Schubert 		break;
23414bc52338SCy Schubert 	case WPAS_DBUS_PROP_SESSION_LENGTH:
23424bc52338SCy Schubert 		prop = "SessionLength";
23434bc52338SCy Schubert 		break;
23444bc52338SCy Schubert 	case WPAS_DBUS_PROP_BSS_TM_STATUS:
23454bc52338SCy Schubert 		prop = "BSSTMStatus";
23464bc52338SCy Schubert 		break;
2347d4f2939cSRui Paulo 	default:
2348d4f2939cSRui Paulo 		wpa_printf(MSG_ERROR, "dbus: %s: Unknown Property value %d",
2349d4f2939cSRui Paulo 			   __func__, property);
2350d4f2939cSRui Paulo 		return;
2351d4f2939cSRui Paulo 	}
2352d4f2939cSRui Paulo 
2353d4f2939cSRui Paulo 	wpa_dbus_mark_property_changed(wpa_s->global->dbus,
2354d4f2939cSRui Paulo 				       wpa_s->dbus_new_path,
2355d4f2939cSRui Paulo 				       WPAS_DBUS_NEW_IFACE_INTERFACE, prop);
2356d4f2939cSRui Paulo 	if (flush) {
2357d4f2939cSRui Paulo 		wpa_dbus_flush_object_changed_properties(
2358d4f2939cSRui Paulo 			wpa_s->global->dbus->con, wpa_s->dbus_new_path);
2359d4f2939cSRui Paulo 	}
2360d4f2939cSRui Paulo }
2361d4f2939cSRui Paulo 
2362d4f2939cSRui Paulo 
2363d4f2939cSRui Paulo /**
2364d4f2939cSRui Paulo  * wpas_dbus_bss_signal_prop_changed - Signals change of BSS property
2365d4f2939cSRui Paulo  * @wpa_s: %wpa_supplicant network interface data
2366d4f2939cSRui Paulo  * @property: indicates which property has changed
2367d4f2939cSRui Paulo  * @id: unique BSS identifier
2368d4f2939cSRui Paulo  *
2369d4f2939cSRui Paulo  * Sends PropertyChanged signals with path, interface, and arguments depending
2370d4f2939cSRui Paulo  * on which property has changed.
2371d4f2939cSRui Paulo  */
2372d4f2939cSRui Paulo void wpas_dbus_bss_signal_prop_changed(struct wpa_supplicant *wpa_s,
2373d4f2939cSRui Paulo 				       enum wpas_dbus_bss_prop property,
2374d4f2939cSRui Paulo 				       unsigned int id)
2375d4f2939cSRui Paulo {
2376d4f2939cSRui Paulo 	char path[WPAS_DBUS_OBJECT_PATH_MAX];
2377d4f2939cSRui Paulo 	char *prop;
2378d4f2939cSRui Paulo 
2379325151a3SRui Paulo 	if (!wpa_s->dbus_new_path)
2380325151a3SRui Paulo 		return;
2381325151a3SRui Paulo 
2382d4f2939cSRui Paulo 	switch (property) {
2383d4f2939cSRui Paulo 	case WPAS_DBUS_BSS_PROP_SIGNAL:
2384d4f2939cSRui Paulo 		prop = "Signal";
2385d4f2939cSRui Paulo 		break;
2386d4f2939cSRui Paulo 	case WPAS_DBUS_BSS_PROP_FREQ:
2387d4f2939cSRui Paulo 		prop = "Frequency";
2388d4f2939cSRui Paulo 		break;
2389d4f2939cSRui Paulo 	case WPAS_DBUS_BSS_PROP_MODE:
2390d4f2939cSRui Paulo 		prop = "Mode";
2391d4f2939cSRui Paulo 		break;
2392d4f2939cSRui Paulo 	case WPAS_DBUS_BSS_PROP_PRIVACY:
2393d4f2939cSRui Paulo 		prop = "Privacy";
2394d4f2939cSRui Paulo 		break;
2395d4f2939cSRui Paulo 	case WPAS_DBUS_BSS_PROP_RATES:
2396d4f2939cSRui Paulo 		prop = "Rates";
2397d4f2939cSRui Paulo 		break;
2398d4f2939cSRui Paulo 	case WPAS_DBUS_BSS_PROP_WPA:
2399d4f2939cSRui Paulo 		prop = "WPA";
2400d4f2939cSRui Paulo 		break;
2401d4f2939cSRui Paulo 	case WPAS_DBUS_BSS_PROP_RSN:
2402d4f2939cSRui Paulo 		prop = "RSN";
2403d4f2939cSRui Paulo 		break;
24045b9c547cSRui Paulo 	case WPAS_DBUS_BSS_PROP_WPS:
24055b9c547cSRui Paulo 		prop = "WPS";
24065b9c547cSRui Paulo 		break;
2407d4f2939cSRui Paulo 	case WPAS_DBUS_BSS_PROP_IES:
2408d4f2939cSRui Paulo 		prop = "IEs";
2409d4f2939cSRui Paulo 		break;
24105b9c547cSRui Paulo 	case WPAS_DBUS_BSS_PROP_AGE:
24115b9c547cSRui Paulo 		prop = "Age";
24125b9c547cSRui Paulo 		break;
2413d4f2939cSRui Paulo 	default:
2414d4f2939cSRui Paulo 		wpa_printf(MSG_ERROR, "dbus: %s: Unknown Property value %d",
2415d4f2939cSRui Paulo 			   __func__, property);
2416d4f2939cSRui Paulo 		return;
2417d4f2939cSRui Paulo 	}
2418d4f2939cSRui Paulo 
2419d4f2939cSRui Paulo 	os_snprintf(path, WPAS_DBUS_OBJECT_PATH_MAX,
2420d4f2939cSRui Paulo 		    "%s/" WPAS_DBUS_NEW_BSSIDS_PART "/%u",
2421d4f2939cSRui Paulo 		    wpa_s->dbus_new_path, id);
2422d4f2939cSRui Paulo 
2423d4f2939cSRui Paulo 	wpa_dbus_mark_property_changed(wpa_s->global->dbus, path,
2424d4f2939cSRui Paulo 				       WPAS_DBUS_NEW_IFACE_BSS, prop);
2425d4f2939cSRui Paulo }
2426d4f2939cSRui Paulo 
2427d4f2939cSRui Paulo 
2428d4f2939cSRui Paulo /**
24294bc52338SCy Schubert  * wpas_dbus_sta_signal_prop_changed - Signals change of STA property
24304bc52338SCy Schubert  * @wpa_s: %wpa_supplicant network interface data
24314bc52338SCy Schubert  * @property: indicates which property has changed
24324bc52338SCy Schubert  * @address: unique BSS identifier
24334bc52338SCy Schubert  *
24344bc52338SCy Schubert  * Sends PropertyChanged signals with path, interface, and arguments depending
24354bc52338SCy Schubert  * on which property has changed.
24364bc52338SCy Schubert  */
24374bc52338SCy Schubert void wpas_dbus_sta_signal_prop_changed(struct wpa_supplicant *wpa_s,
24384bc52338SCy Schubert 				       enum wpas_dbus_bss_prop property,
24394bc52338SCy Schubert 				       u8 address[ETH_ALEN])
24404bc52338SCy Schubert {
24414bc52338SCy Schubert 	char path[WPAS_DBUS_OBJECT_PATH_MAX];
24424bc52338SCy Schubert 	char *prop;
24434bc52338SCy Schubert 
24444bc52338SCy Schubert 	switch (property) {
24454bc52338SCy Schubert 	case WPAS_DBUS_STA_PROP_ADDRESS:
24464bc52338SCy Schubert 		prop = "Address";
24474bc52338SCy Schubert 		break;
24484bc52338SCy Schubert 	default:
24494bc52338SCy Schubert 		wpa_printf(MSG_ERROR, "dbus: %s: Unknown Property value %d",
24504bc52338SCy Schubert 			   __func__, property);
24514bc52338SCy Schubert 		return;
24524bc52338SCy Schubert 	}
24534bc52338SCy Schubert 
24544bc52338SCy Schubert 	os_snprintf(path, WPAS_DBUS_OBJECT_PATH_MAX,
24554bc52338SCy Schubert 		    "%s/" WPAS_DBUS_NEW_STAS_PART "/" COMPACT_MACSTR,
24564bc52338SCy Schubert 		    wpa_s->dbus_new_path, MAC2STR(address));
24574bc52338SCy Schubert 
24584bc52338SCy Schubert 	wpa_dbus_mark_property_changed(wpa_s->global->dbus, path,
24594bc52338SCy Schubert 				       WPAS_DBUS_NEW_IFACE_STA, prop);
24604bc52338SCy Schubert }
24614bc52338SCy Schubert 
24624bc52338SCy Schubert 
24634bc52338SCy Schubert /**
2464d4f2939cSRui Paulo  * wpas_dbus_signal_debug_level_changed - Signals change of debug param
2465d4f2939cSRui Paulo  * @global: wpa_global structure
2466d4f2939cSRui Paulo  *
2467d4f2939cSRui Paulo  * Sends PropertyChanged signals informing that debug level has changed.
2468d4f2939cSRui Paulo  */
2469d4f2939cSRui Paulo void wpas_dbus_signal_debug_level_changed(struct wpa_global *global)
2470d4f2939cSRui Paulo {
2471d4f2939cSRui Paulo 	wpa_dbus_mark_property_changed(global->dbus, WPAS_DBUS_NEW_PATH,
2472d4f2939cSRui Paulo 				       WPAS_DBUS_NEW_INTERFACE,
2473d4f2939cSRui Paulo 				       "DebugLevel");
2474d4f2939cSRui Paulo }
2475d4f2939cSRui Paulo 
2476d4f2939cSRui Paulo 
2477d4f2939cSRui Paulo /**
2478d4f2939cSRui Paulo  * wpas_dbus_signal_debug_timestamp_changed - Signals change of debug param
2479d4f2939cSRui Paulo  * @global: wpa_global structure
2480d4f2939cSRui Paulo  *
2481d4f2939cSRui Paulo  * Sends PropertyChanged signals informing that debug timestamp has changed.
2482d4f2939cSRui Paulo  */
2483d4f2939cSRui Paulo void wpas_dbus_signal_debug_timestamp_changed(struct wpa_global *global)
2484d4f2939cSRui Paulo {
2485d4f2939cSRui Paulo 	wpa_dbus_mark_property_changed(global->dbus, WPAS_DBUS_NEW_PATH,
2486d4f2939cSRui Paulo 				       WPAS_DBUS_NEW_INTERFACE,
2487d4f2939cSRui Paulo 				       "DebugTimestamp");
2488d4f2939cSRui Paulo }
2489d4f2939cSRui Paulo 
2490d4f2939cSRui Paulo 
2491d4f2939cSRui Paulo /**
2492d4f2939cSRui Paulo  * wpas_dbus_signal_debug_show_keys_changed - Signals change of debug param
2493d4f2939cSRui Paulo  * @global: wpa_global structure
2494d4f2939cSRui Paulo  *
2495d4f2939cSRui Paulo  * Sends PropertyChanged signals informing that debug show_keys has changed.
2496d4f2939cSRui Paulo  */
2497d4f2939cSRui Paulo void wpas_dbus_signal_debug_show_keys_changed(struct wpa_global *global)
2498d4f2939cSRui Paulo {
2499d4f2939cSRui Paulo 	wpa_dbus_mark_property_changed(global->dbus, WPAS_DBUS_NEW_PATH,
2500d4f2939cSRui Paulo 				       WPAS_DBUS_NEW_INTERFACE,
2501d4f2939cSRui Paulo 				       "DebugShowKeys");
2502d4f2939cSRui Paulo }
2503d4f2939cSRui Paulo 
2504d4f2939cSRui Paulo 
2505d4f2939cSRui Paulo static void wpas_dbus_register(struct wpa_dbus_object_desc *obj_desc,
2506d4f2939cSRui Paulo 			       void *priv,
2507d4f2939cSRui Paulo 			       WPADBusArgumentFreeFunction priv_free,
2508d4f2939cSRui Paulo 			       const struct wpa_dbus_method_desc *methods,
2509d4f2939cSRui Paulo 			       const struct wpa_dbus_property_desc *properties,
2510d4f2939cSRui Paulo 			       const struct wpa_dbus_signal_desc *signals)
2511d4f2939cSRui Paulo {
2512d4f2939cSRui Paulo 	int n;
2513d4f2939cSRui Paulo 
2514d4f2939cSRui Paulo 	obj_desc->user_data = priv;
2515d4f2939cSRui Paulo 	obj_desc->user_data_free_func = priv_free;
2516d4f2939cSRui Paulo 	obj_desc->methods = methods;
2517d4f2939cSRui Paulo 	obj_desc->properties = properties;
2518d4f2939cSRui Paulo 	obj_desc->signals = signals;
2519d4f2939cSRui Paulo 
2520d4f2939cSRui Paulo 	for (n = 0; properties && properties->dbus_property; properties++)
2521d4f2939cSRui Paulo 		n++;
2522d4f2939cSRui Paulo 
2523d4f2939cSRui Paulo 	obj_desc->prop_changed_flags = os_zalloc(n);
2524d4f2939cSRui Paulo 	if (!obj_desc->prop_changed_flags)
2525d4f2939cSRui Paulo 		wpa_printf(MSG_DEBUG, "dbus: %s: can't register handlers",
2526d4f2939cSRui Paulo 			   __func__);
2527d4f2939cSRui Paulo }
2528d4f2939cSRui Paulo 
2529d4f2939cSRui Paulo 
2530d4f2939cSRui Paulo static const struct wpa_dbus_method_desc wpas_dbus_global_methods[] = {
2531d4f2939cSRui Paulo 	{ "CreateInterface", WPAS_DBUS_NEW_INTERFACE,
25325b9c547cSRui Paulo 	  (WPADBusMethodHandler) wpas_dbus_handler_create_interface,
2533d4f2939cSRui Paulo 	  {
2534d4f2939cSRui Paulo 		  { "args", "a{sv}", ARG_IN },
2535d4f2939cSRui Paulo 		  { "path", "o", ARG_OUT },
2536d4f2939cSRui Paulo 		  END_ARGS
2537d4f2939cSRui Paulo 	  }
2538d4f2939cSRui Paulo 	},
2539d4f2939cSRui Paulo 	{ "RemoveInterface", WPAS_DBUS_NEW_INTERFACE,
25405b9c547cSRui Paulo 	  (WPADBusMethodHandler) wpas_dbus_handler_remove_interface,
2541d4f2939cSRui Paulo 	  {
2542d4f2939cSRui Paulo 		  { "path", "o", ARG_IN },
2543d4f2939cSRui Paulo 		  END_ARGS
2544d4f2939cSRui Paulo 	  }
2545d4f2939cSRui Paulo 	},
2546d4f2939cSRui Paulo 	{ "GetInterface", WPAS_DBUS_NEW_INTERFACE,
25475b9c547cSRui Paulo 	  (WPADBusMethodHandler) wpas_dbus_handler_get_interface,
2548d4f2939cSRui Paulo 	  {
2549d4f2939cSRui Paulo 		  { "ifname", "s", ARG_IN },
2550d4f2939cSRui Paulo 		  { "path", "o", ARG_OUT },
2551d4f2939cSRui Paulo 		  END_ARGS
2552d4f2939cSRui Paulo 	  }
2553d4f2939cSRui Paulo 	},
2554780fb4a2SCy Schubert 	{ "ExpectDisconnect", WPAS_DBUS_NEW_INTERFACE,
2555780fb4a2SCy Schubert 	  (WPADBusMethodHandler) wpas_dbus_handler_expect_disconnect,
2556780fb4a2SCy Schubert 	  {
2557780fb4a2SCy Schubert 		END_ARGS
2558780fb4a2SCy Schubert 	  }
2559780fb4a2SCy Schubert 	},
2560d4f2939cSRui Paulo 	{ NULL, NULL, NULL, { END_ARGS } }
2561d4f2939cSRui Paulo };
2562d4f2939cSRui Paulo 
2563d4f2939cSRui Paulo static const struct wpa_dbus_property_desc wpas_dbus_global_properties[] = {
2564d4f2939cSRui Paulo 	{ "DebugLevel", WPAS_DBUS_NEW_INTERFACE, "s",
2565d4f2939cSRui Paulo 	  wpas_dbus_getter_debug_level,
2566780fb4a2SCy Schubert 	  wpas_dbus_setter_debug_level,
2567780fb4a2SCy Schubert 	  NULL
2568d4f2939cSRui Paulo 	},
2569d4f2939cSRui Paulo 	{ "DebugTimestamp", WPAS_DBUS_NEW_INTERFACE, "b",
2570d4f2939cSRui Paulo 	  wpas_dbus_getter_debug_timestamp,
2571780fb4a2SCy Schubert 	  wpas_dbus_setter_debug_timestamp,
2572780fb4a2SCy Schubert 	  NULL
2573d4f2939cSRui Paulo 	},
2574d4f2939cSRui Paulo 	{ "DebugShowKeys", WPAS_DBUS_NEW_INTERFACE, "b",
2575d4f2939cSRui Paulo 	  wpas_dbus_getter_debug_show_keys,
2576780fb4a2SCy Schubert 	  wpas_dbus_setter_debug_show_keys,
2577780fb4a2SCy Schubert 	  NULL
2578d4f2939cSRui Paulo 	},
2579d4f2939cSRui Paulo 	{ "Interfaces", WPAS_DBUS_NEW_INTERFACE, "ao",
2580d4f2939cSRui Paulo 	  wpas_dbus_getter_interfaces,
2581780fb4a2SCy Schubert 	  NULL,
2582d4f2939cSRui Paulo 	  NULL
2583d4f2939cSRui Paulo 	},
2584d4f2939cSRui Paulo 	{ "EapMethods", WPAS_DBUS_NEW_INTERFACE, "as",
2585d4f2939cSRui Paulo 	  wpas_dbus_getter_eap_methods,
2586780fb4a2SCy Schubert 	  NULL,
2587d4f2939cSRui Paulo 	  NULL
2588d4f2939cSRui Paulo 	},
2589d4f2939cSRui Paulo 	{ "Capabilities", WPAS_DBUS_NEW_INTERFACE, "as",
2590d4f2939cSRui Paulo 	  wpas_dbus_getter_global_capabilities,
2591780fb4a2SCy Schubert 	  NULL,
2592d4f2939cSRui Paulo 	  NULL
2593d4f2939cSRui Paulo 	},
25945b9c547cSRui Paulo #ifdef CONFIG_WIFI_DISPLAY
25955b9c547cSRui Paulo 	{ "WFDIEs", WPAS_DBUS_NEW_INTERFACE, "ay",
25965b9c547cSRui Paulo 	  wpas_dbus_getter_global_wfd_ies,
2597780fb4a2SCy Schubert 	  wpas_dbus_setter_global_wfd_ies,
2598780fb4a2SCy Schubert 	  NULL
25995b9c547cSRui Paulo 	},
26005b9c547cSRui Paulo #endif /* CONFIG_WIFI_DISPLAY */
2601780fb4a2SCy Schubert 	{ NULL, NULL, NULL, NULL, NULL, NULL }
2602d4f2939cSRui Paulo };
2603d4f2939cSRui Paulo 
2604d4f2939cSRui Paulo static const struct wpa_dbus_signal_desc wpas_dbus_global_signals[] = {
2605d4f2939cSRui Paulo 	{ "InterfaceAdded", WPAS_DBUS_NEW_INTERFACE,
2606d4f2939cSRui Paulo 	  {
2607d4f2939cSRui Paulo 		  { "path", "o", ARG_OUT },
2608d4f2939cSRui Paulo 		  { "properties", "a{sv}", ARG_OUT },
2609d4f2939cSRui Paulo 		  END_ARGS
2610d4f2939cSRui Paulo 	  }
2611d4f2939cSRui Paulo 	},
2612d4f2939cSRui Paulo 	{ "InterfaceRemoved", WPAS_DBUS_NEW_INTERFACE,
2613d4f2939cSRui Paulo 	  {
2614d4f2939cSRui Paulo 		  { "path", "o", ARG_OUT },
2615d4f2939cSRui Paulo 		  END_ARGS
2616d4f2939cSRui Paulo 	  }
2617d4f2939cSRui Paulo 	},
2618d4f2939cSRui Paulo 	/* Deprecated: use org.freedesktop.DBus.Properties.PropertiesChanged */
2619d4f2939cSRui Paulo 	{ "PropertiesChanged", WPAS_DBUS_NEW_INTERFACE,
2620d4f2939cSRui Paulo 	  {
2621d4f2939cSRui Paulo 		  { "properties", "a{sv}", ARG_OUT },
2622d4f2939cSRui Paulo 		  END_ARGS
2623d4f2939cSRui Paulo 	  }
2624d4f2939cSRui Paulo 	},
2625d4f2939cSRui Paulo 	{ NULL, NULL, { END_ARGS } }
2626d4f2939cSRui Paulo };
2627d4f2939cSRui Paulo 
2628d4f2939cSRui Paulo 
2629780fb4a2SCy Schubert static char * uscore_to_dbus(const char *uscore)
2630780fb4a2SCy Schubert {
2631780fb4a2SCy Schubert 	const char *p = uscore;
2632780fb4a2SCy Schubert 	char *str, *s;
2633780fb4a2SCy Schubert 	dbus_bool_t last_was_uscore = TRUE;
2634780fb4a2SCy Schubert 
2635780fb4a2SCy Schubert 	s = str = os_zalloc(os_strlen(uscore) + 1);
2636780fb4a2SCy Schubert 	if (!str)
2637780fb4a2SCy Schubert 		return NULL;
2638780fb4a2SCy Schubert 	while (p && *p) {
2639780fb4a2SCy Schubert 		if (*p == '_') {
2640780fb4a2SCy Schubert 			last_was_uscore = TRUE;
2641780fb4a2SCy Schubert 		} else {
2642780fb4a2SCy Schubert 			*s++ = last_was_uscore ? toupper(*p) : *p;
2643780fb4a2SCy Schubert 			last_was_uscore = FALSE;
2644780fb4a2SCy Schubert 		}
2645780fb4a2SCy Schubert 		p++;
2646780fb4a2SCy Schubert 	}
2647780fb4a2SCy Schubert 
2648780fb4a2SCy Schubert 	return str;
2649780fb4a2SCy Schubert }
2650780fb4a2SCy Schubert 
2651780fb4a2SCy Schubert 
2652780fb4a2SCy Schubert static int wpa_dbus_ctrl_iface_props_init(struct wpas_dbus_priv *priv);
2653780fb4a2SCy Schubert 
2654780fb4a2SCy Schubert 
2655780fb4a2SCy Schubert static void wpa_dbus_ctrl_iface_props_deinit(struct wpas_dbus_priv *priv)
2656780fb4a2SCy Schubert {
2657780fb4a2SCy Schubert 	int idx = priv->globals_start;
2658780fb4a2SCy Schubert 
2659780fb4a2SCy Schubert 	/* Free all allocated property values */
2660780fb4a2SCy Schubert 	while (priv->all_interface_properties[idx].dbus_property)
2661780fb4a2SCy Schubert 		os_free((char *)
2662780fb4a2SCy Schubert 			priv->all_interface_properties[idx++].dbus_property);
2663780fb4a2SCy Schubert 	os_free((char *) priv->all_interface_properties);
2664780fb4a2SCy Schubert }
2665780fb4a2SCy Schubert 
2666780fb4a2SCy Schubert 
2667d4f2939cSRui Paulo /**
2668d4f2939cSRui Paulo  * wpas_dbus_ctrl_iface_init - Initialize dbus control interface
2669d4f2939cSRui Paulo  * @global: Pointer to global data from wpa_supplicant_init()
2670d4f2939cSRui Paulo  * Returns: 0 on success or -1 on failure
2671d4f2939cSRui Paulo  *
2672780fb4a2SCy Schubert  * Initialize the dbus control interface for wpa_supplicant and start
2673d4f2939cSRui Paulo  * receiving commands from external programs over the bus.
2674d4f2939cSRui Paulo  */
2675d4f2939cSRui Paulo int wpas_dbus_ctrl_iface_init(struct wpas_dbus_priv *priv)
2676d4f2939cSRui Paulo {
2677d4f2939cSRui Paulo 	struct wpa_dbus_object_desc *obj_desc;
2678d4f2939cSRui Paulo 	int ret;
2679d4f2939cSRui Paulo 
2680780fb4a2SCy Schubert 	ret = wpa_dbus_ctrl_iface_props_init(priv);
2681780fb4a2SCy Schubert 	if (ret < 0) {
2682780fb4a2SCy Schubert 		wpa_printf(MSG_ERROR,
2683780fb4a2SCy Schubert 			   "dbus: Not enough memory to init interface properties");
2684780fb4a2SCy Schubert 		return -1;
2685780fb4a2SCy Schubert 	}
2686780fb4a2SCy Schubert 
2687d4f2939cSRui Paulo 	obj_desc = os_zalloc(sizeof(struct wpa_dbus_object_desc));
2688d4f2939cSRui Paulo 	if (!obj_desc) {
26895b9c547cSRui Paulo 		wpa_printf(MSG_ERROR,
26905b9c547cSRui Paulo 			   "Not enough memory to create object description");
2691780fb4a2SCy Schubert 		goto error;
2692d4f2939cSRui Paulo 	}
2693d4f2939cSRui Paulo 
2694d4f2939cSRui Paulo 	wpas_dbus_register(obj_desc, priv->global, NULL,
2695d4f2939cSRui Paulo 			   wpas_dbus_global_methods,
2696d4f2939cSRui Paulo 			   wpas_dbus_global_properties,
2697d4f2939cSRui Paulo 			   wpas_dbus_global_signals);
2698d4f2939cSRui Paulo 
2699d4f2939cSRui Paulo 	wpa_printf(MSG_DEBUG, "dbus: Register D-Bus object '%s'",
2700d4f2939cSRui Paulo 		   WPAS_DBUS_NEW_PATH);
2701d4f2939cSRui Paulo 	ret = wpa_dbus_ctrl_iface_init(priv, WPAS_DBUS_NEW_PATH,
2702d4f2939cSRui Paulo 				       WPAS_DBUS_NEW_SERVICE,
2703d4f2939cSRui Paulo 				       obj_desc);
2704780fb4a2SCy Schubert 	if (ret < 0) {
2705d4f2939cSRui Paulo 		free_dbus_object_desc(obj_desc);
2706780fb4a2SCy Schubert 		goto error;
2707780fb4a2SCy Schubert 	}
2708d4f2939cSRui Paulo 
2709780fb4a2SCy Schubert 	priv->dbus_new_initialized = 1;
2710780fb4a2SCy Schubert 	return 0;
2711780fb4a2SCy Schubert 
2712780fb4a2SCy Schubert error:
2713780fb4a2SCy Schubert 	wpa_dbus_ctrl_iface_props_deinit(priv);
2714780fb4a2SCy Schubert 	return -1;
2715d4f2939cSRui Paulo }
2716d4f2939cSRui Paulo 
2717d4f2939cSRui Paulo 
2718d4f2939cSRui Paulo /**
2719d4f2939cSRui Paulo  * wpas_dbus_ctrl_iface_deinit - Deinitialize dbus ctrl interface for
2720d4f2939cSRui Paulo  * wpa_supplicant
2721780fb4a2SCy Schubert  * @priv: Pointer to dbus private data from wpas_dbus_init()
2722d4f2939cSRui Paulo  *
2723d4f2939cSRui Paulo  * Deinitialize the dbus control interface that was initialized with
2724d4f2939cSRui Paulo  * wpas_dbus_ctrl_iface_init().
2725d4f2939cSRui Paulo  */
2726780fb4a2SCy Schubert void wpas_dbus_ctrl_iface_deinit(struct wpas_dbus_priv *priv)
2727d4f2939cSRui Paulo {
2728780fb4a2SCy Schubert 	if (!priv->dbus_new_initialized)
2729d4f2939cSRui Paulo 		return;
2730d4f2939cSRui Paulo 	wpa_printf(MSG_DEBUG, "dbus: Unregister D-Bus object '%s'",
2731d4f2939cSRui Paulo 		   WPAS_DBUS_NEW_PATH);
2732780fb4a2SCy Schubert 	dbus_connection_unregister_object_path(priv->con, WPAS_DBUS_NEW_PATH);
2733780fb4a2SCy Schubert 	wpa_dbus_ctrl_iface_props_deinit(priv);
2734d4f2939cSRui Paulo }
2735d4f2939cSRui Paulo 
2736d4f2939cSRui Paulo 
2737d4f2939cSRui Paulo static void wpa_dbus_free(void *ptr)
2738d4f2939cSRui Paulo {
2739d4f2939cSRui Paulo 	os_free(ptr);
2740d4f2939cSRui Paulo }
2741d4f2939cSRui Paulo 
2742d4f2939cSRui Paulo 
2743d4f2939cSRui Paulo static const struct wpa_dbus_property_desc wpas_dbus_network_properties[] = {
2744d4f2939cSRui Paulo 	{ "Properties", WPAS_DBUS_NEW_IFACE_NETWORK, "a{sv}",
2745d4f2939cSRui Paulo 	  wpas_dbus_getter_network_properties,
2746780fb4a2SCy Schubert 	  wpas_dbus_setter_network_properties,
2747780fb4a2SCy Schubert 	  NULL
2748d4f2939cSRui Paulo 	},
2749d4f2939cSRui Paulo 	{ "Enabled", WPAS_DBUS_NEW_IFACE_NETWORK, "b",
2750d4f2939cSRui Paulo 	  wpas_dbus_getter_enabled,
2751780fb4a2SCy Schubert 	  wpas_dbus_setter_enabled,
2752780fb4a2SCy Schubert 	  NULL
2753d4f2939cSRui Paulo 	},
2754780fb4a2SCy Schubert 	{ NULL, NULL, NULL, NULL, NULL, NULL }
2755d4f2939cSRui Paulo };
2756d4f2939cSRui Paulo 
2757d4f2939cSRui Paulo 
2758d4f2939cSRui Paulo static const struct wpa_dbus_signal_desc wpas_dbus_network_signals[] = {
2759d4f2939cSRui Paulo 	/* Deprecated: use org.freedesktop.DBus.Properties.PropertiesChanged */
2760d4f2939cSRui Paulo 	{ "PropertiesChanged", WPAS_DBUS_NEW_IFACE_NETWORK,
2761d4f2939cSRui Paulo 	  {
2762d4f2939cSRui Paulo 		  { "properties", "a{sv}", ARG_OUT },
2763d4f2939cSRui Paulo 		  END_ARGS
2764d4f2939cSRui Paulo 	  }
2765d4f2939cSRui Paulo 	},
2766d4f2939cSRui Paulo 	{ NULL, NULL, { END_ARGS } }
2767d4f2939cSRui Paulo };
2768d4f2939cSRui Paulo 
2769d4f2939cSRui Paulo 
2770d4f2939cSRui Paulo /**
2771d4f2939cSRui Paulo  * wpas_dbus_register_network - Register a configured network with dbus
2772d4f2939cSRui Paulo  * @wpa_s: wpa_supplicant interface structure
2773d4f2939cSRui Paulo  * @ssid: network configuration data
2774d4f2939cSRui Paulo  * Returns: 0 on success, -1 on failure
2775d4f2939cSRui Paulo  *
2776d4f2939cSRui Paulo  * Registers network representing object with dbus
2777d4f2939cSRui Paulo  */
2778d4f2939cSRui Paulo int wpas_dbus_register_network(struct wpa_supplicant *wpa_s,
2779d4f2939cSRui Paulo 			       struct wpa_ssid *ssid)
2780d4f2939cSRui Paulo {
2781d4f2939cSRui Paulo 	struct wpas_dbus_priv *ctrl_iface;
2782d4f2939cSRui Paulo 	struct wpa_dbus_object_desc *obj_desc;
2783d4f2939cSRui Paulo 	struct network_handler_args *arg;
2784d4f2939cSRui Paulo 	char net_obj_path[WPAS_DBUS_OBJECT_PATH_MAX];
2785d4f2939cSRui Paulo 
2786d4f2939cSRui Paulo #ifdef CONFIG_P2P
2787d4f2939cSRui Paulo 	/*
2788d4f2939cSRui Paulo 	 * If it is a persistent group register it as such.
2789d4f2939cSRui Paulo 	 * This is to handle cases where an interface is being initialized
2790d4f2939cSRui Paulo 	 * with a list of networks read from config.
2791d4f2939cSRui Paulo 	 */
2792d4f2939cSRui Paulo 	if (network_is_persistent_group(ssid))
2793d4f2939cSRui Paulo 		return wpas_dbus_register_persistent_group(wpa_s, ssid);
2794d4f2939cSRui Paulo #endif /* CONFIG_P2P */
2795d4f2939cSRui Paulo 
2796d4f2939cSRui Paulo 	/* Do nothing if the control interface is not turned on */
2797325151a3SRui Paulo 	if (wpa_s == NULL || wpa_s->global == NULL || !wpa_s->dbus_new_path)
2798d4f2939cSRui Paulo 		return 0;
2799d4f2939cSRui Paulo 	ctrl_iface = wpa_s->global->dbus;
2800d4f2939cSRui Paulo 	if (ctrl_iface == NULL)
2801d4f2939cSRui Paulo 		return 0;
2802d4f2939cSRui Paulo 
2803d4f2939cSRui Paulo 	os_snprintf(net_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
2804d4f2939cSRui Paulo 		    "%s/" WPAS_DBUS_NEW_NETWORKS_PART "/%u",
2805d4f2939cSRui Paulo 		    wpa_s->dbus_new_path, ssid->id);
2806d4f2939cSRui Paulo 
2807d4f2939cSRui Paulo 	wpa_printf(MSG_DEBUG, "dbus: Register network object '%s'",
2808d4f2939cSRui Paulo 		   net_obj_path);
2809d4f2939cSRui Paulo 	obj_desc = os_zalloc(sizeof(struct wpa_dbus_object_desc));
2810d4f2939cSRui Paulo 	if (!obj_desc) {
28115b9c547cSRui Paulo 		wpa_printf(MSG_ERROR,
28125b9c547cSRui Paulo 			   "Not enough memory to create object description");
2813d4f2939cSRui Paulo 		goto err;
2814d4f2939cSRui Paulo 	}
2815d4f2939cSRui Paulo 
2816d4f2939cSRui Paulo 	/* allocate memory for handlers arguments */
2817d4f2939cSRui Paulo 	arg = os_zalloc(sizeof(struct network_handler_args));
2818d4f2939cSRui Paulo 	if (!arg) {
28195b9c547cSRui Paulo 		wpa_printf(MSG_ERROR,
28205b9c547cSRui Paulo 			   "Not enough memory to create arguments for method");
2821d4f2939cSRui Paulo 		goto err;
2822d4f2939cSRui Paulo 	}
2823d4f2939cSRui Paulo 
2824d4f2939cSRui Paulo 	arg->wpa_s = wpa_s;
2825d4f2939cSRui Paulo 	arg->ssid = ssid;
2826d4f2939cSRui Paulo 
2827d4f2939cSRui Paulo 	wpas_dbus_register(obj_desc, arg, wpa_dbus_free, NULL,
2828d4f2939cSRui Paulo 			   wpas_dbus_network_properties,
2829d4f2939cSRui Paulo 			   wpas_dbus_network_signals);
2830d4f2939cSRui Paulo 
2831d4f2939cSRui Paulo 	if (wpa_dbus_register_object_per_iface(ctrl_iface, net_obj_path,
2832d4f2939cSRui Paulo 					       wpa_s->ifname, obj_desc))
2833d4f2939cSRui Paulo 		goto err;
2834d4f2939cSRui Paulo 
2835d4f2939cSRui Paulo 	wpas_dbus_signal_network_added(wpa_s, ssid->id);
2836d4f2939cSRui Paulo 
2837d4f2939cSRui Paulo 	return 0;
2838d4f2939cSRui Paulo 
2839d4f2939cSRui Paulo err:
2840d4f2939cSRui Paulo 	free_dbus_object_desc(obj_desc);
2841d4f2939cSRui Paulo 	return -1;
2842d4f2939cSRui Paulo }
2843d4f2939cSRui Paulo 
2844d4f2939cSRui Paulo 
2845d4f2939cSRui Paulo /**
2846d4f2939cSRui Paulo  * wpas_dbus_unregister_network - Unregister a configured network from dbus
2847d4f2939cSRui Paulo  * @wpa_s: wpa_supplicant interface structure
2848d4f2939cSRui Paulo  * @nid: network id
2849d4f2939cSRui Paulo  * Returns: 0 on success, -1 on failure
2850d4f2939cSRui Paulo  *
2851d4f2939cSRui Paulo  * Unregisters network representing object from dbus
2852d4f2939cSRui Paulo  */
2853d4f2939cSRui Paulo int wpas_dbus_unregister_network(struct wpa_supplicant *wpa_s, int nid)
2854d4f2939cSRui Paulo {
2855d4f2939cSRui Paulo 	struct wpas_dbus_priv *ctrl_iface;
2856d4f2939cSRui Paulo 	char net_obj_path[WPAS_DBUS_OBJECT_PATH_MAX];
2857d4f2939cSRui Paulo 	int ret;
2858d4f2939cSRui Paulo #ifdef CONFIG_P2P
2859d4f2939cSRui Paulo 	struct wpa_ssid *ssid;
2860d4f2939cSRui Paulo 
2861d4f2939cSRui Paulo 	ssid = wpa_config_get_network(wpa_s->conf, nid);
2862d4f2939cSRui Paulo 
2863d4f2939cSRui Paulo 	/* If it is a persistent group unregister it as such */
2864d4f2939cSRui Paulo 	if (ssid && network_is_persistent_group(ssid))
2865d4f2939cSRui Paulo 		return wpas_dbus_unregister_persistent_group(wpa_s, nid);
2866d4f2939cSRui Paulo #endif /* CONFIG_P2P */
2867d4f2939cSRui Paulo 
2868d4f2939cSRui Paulo 	/* Do nothing if the control interface is not turned on */
2869d4f2939cSRui Paulo 	if (wpa_s->global == NULL || wpa_s->dbus_new_path == NULL)
2870d4f2939cSRui Paulo 		return 0;
2871d4f2939cSRui Paulo 	ctrl_iface = wpa_s->global->dbus;
2872d4f2939cSRui Paulo 	if (ctrl_iface == NULL)
2873d4f2939cSRui Paulo 		return 0;
2874d4f2939cSRui Paulo 
2875d4f2939cSRui Paulo 	os_snprintf(net_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
2876d4f2939cSRui Paulo 		    "%s/" WPAS_DBUS_NEW_NETWORKS_PART "/%u",
2877d4f2939cSRui Paulo 		    wpa_s->dbus_new_path, nid);
2878d4f2939cSRui Paulo 
2879d4f2939cSRui Paulo 	wpa_printf(MSG_DEBUG, "dbus: Unregister network object '%s'",
2880d4f2939cSRui Paulo 		   net_obj_path);
2881d4f2939cSRui Paulo 	ret = wpa_dbus_unregister_object_per_iface(ctrl_iface, net_obj_path);
2882d4f2939cSRui Paulo 
2883d4f2939cSRui Paulo 	if (!ret)
2884d4f2939cSRui Paulo 		wpas_dbus_signal_network_removed(wpa_s, nid);
2885d4f2939cSRui Paulo 
2886d4f2939cSRui Paulo 	return ret;
2887d4f2939cSRui Paulo }
2888d4f2939cSRui Paulo 
2889d4f2939cSRui Paulo 
2890d4f2939cSRui Paulo static const struct wpa_dbus_property_desc wpas_dbus_bss_properties[] = {
2891d4f2939cSRui Paulo 	{ "SSID", WPAS_DBUS_NEW_IFACE_BSS, "ay",
2892d4f2939cSRui Paulo 	  wpas_dbus_getter_bss_ssid,
2893780fb4a2SCy Schubert 	  NULL,
2894d4f2939cSRui Paulo 	  NULL
2895d4f2939cSRui Paulo 	},
2896d4f2939cSRui Paulo 	{ "BSSID", WPAS_DBUS_NEW_IFACE_BSS, "ay",
2897d4f2939cSRui Paulo 	  wpas_dbus_getter_bss_bssid,
2898780fb4a2SCy Schubert 	  NULL,
2899d4f2939cSRui Paulo 	  NULL
2900d4f2939cSRui Paulo 	},
2901d4f2939cSRui Paulo 	{ "Privacy", WPAS_DBUS_NEW_IFACE_BSS, "b",
2902d4f2939cSRui Paulo 	  wpas_dbus_getter_bss_privacy,
2903780fb4a2SCy Schubert 	  NULL,
2904d4f2939cSRui Paulo 	  NULL
2905d4f2939cSRui Paulo 	},
2906d4f2939cSRui Paulo 	{ "Mode", WPAS_DBUS_NEW_IFACE_BSS, "s",
2907d4f2939cSRui Paulo 	  wpas_dbus_getter_bss_mode,
2908780fb4a2SCy Schubert 	  NULL,
2909d4f2939cSRui Paulo 	  NULL
2910d4f2939cSRui Paulo 	},
2911d4f2939cSRui Paulo 	{ "Signal", WPAS_DBUS_NEW_IFACE_BSS, "n",
2912d4f2939cSRui Paulo 	  wpas_dbus_getter_bss_signal,
2913780fb4a2SCy Schubert 	  NULL,
2914d4f2939cSRui Paulo 	  NULL
2915d4f2939cSRui Paulo 	},
2916d4f2939cSRui Paulo 	{ "Frequency", WPAS_DBUS_NEW_IFACE_BSS, "q",
2917d4f2939cSRui Paulo 	  wpas_dbus_getter_bss_frequency,
2918780fb4a2SCy Schubert 	  NULL,
2919d4f2939cSRui Paulo 	  NULL
2920d4f2939cSRui Paulo 	},
2921d4f2939cSRui Paulo 	{ "Rates", WPAS_DBUS_NEW_IFACE_BSS, "au",
2922d4f2939cSRui Paulo 	  wpas_dbus_getter_bss_rates,
2923780fb4a2SCy Schubert 	  NULL,
2924d4f2939cSRui Paulo 	  NULL
2925d4f2939cSRui Paulo 	},
2926d4f2939cSRui Paulo 	{ "WPA", WPAS_DBUS_NEW_IFACE_BSS, "a{sv}",
2927d4f2939cSRui Paulo 	  wpas_dbus_getter_bss_wpa,
2928780fb4a2SCy Schubert 	  NULL,
2929d4f2939cSRui Paulo 	  NULL
2930d4f2939cSRui Paulo 	},
2931d4f2939cSRui Paulo 	{ "RSN", WPAS_DBUS_NEW_IFACE_BSS, "a{sv}",
2932d4f2939cSRui Paulo 	  wpas_dbus_getter_bss_rsn,
2933780fb4a2SCy Schubert 	  NULL,
2934d4f2939cSRui Paulo 	  NULL
2935d4f2939cSRui Paulo 	},
2936d4f2939cSRui Paulo 	{ "WPS", WPAS_DBUS_NEW_IFACE_BSS, "a{sv}",
2937d4f2939cSRui Paulo 	  wpas_dbus_getter_bss_wps,
2938780fb4a2SCy Schubert 	  NULL,
2939d4f2939cSRui Paulo 	  NULL
2940d4f2939cSRui Paulo 	},
2941d4f2939cSRui Paulo 	{ "IEs", WPAS_DBUS_NEW_IFACE_BSS, "ay",
2942d4f2939cSRui Paulo 	  wpas_dbus_getter_bss_ies,
2943780fb4a2SCy Schubert 	  NULL,
2944d4f2939cSRui Paulo 	  NULL
2945d4f2939cSRui Paulo 	},
29465b9c547cSRui Paulo 	{ "Age", WPAS_DBUS_NEW_IFACE_BSS, "u",
29475b9c547cSRui Paulo 	  wpas_dbus_getter_bss_age,
2948780fb4a2SCy Schubert 	  NULL,
29495b9c547cSRui Paulo 	  NULL
29505b9c547cSRui Paulo 	},
2951780fb4a2SCy Schubert 	{ NULL, NULL, NULL, NULL, NULL, NULL }
2952d4f2939cSRui Paulo };
2953d4f2939cSRui Paulo 
2954d4f2939cSRui Paulo 
2955d4f2939cSRui Paulo static const struct wpa_dbus_signal_desc wpas_dbus_bss_signals[] = {
2956d4f2939cSRui Paulo 	/* Deprecated: use org.freedesktop.DBus.Properties.PropertiesChanged */
2957d4f2939cSRui Paulo 	{ "PropertiesChanged", WPAS_DBUS_NEW_IFACE_BSS,
2958d4f2939cSRui Paulo 	  {
2959d4f2939cSRui Paulo 		  { "properties", "a{sv}", ARG_OUT },
2960d4f2939cSRui Paulo 		  END_ARGS
2961d4f2939cSRui Paulo 	  }
2962d4f2939cSRui Paulo 	},
2963d4f2939cSRui Paulo 	{ NULL, NULL, { END_ARGS } }
2964d4f2939cSRui Paulo };
2965d4f2939cSRui Paulo 
2966d4f2939cSRui Paulo 
2967d4f2939cSRui Paulo /**
2968d4f2939cSRui Paulo  * wpas_dbus_unregister_bss - Unregister a scanned BSS from dbus
2969d4f2939cSRui Paulo  * @wpa_s: wpa_supplicant interface structure
2970d4f2939cSRui Paulo  * @bssid: scanned network bssid
2971d4f2939cSRui Paulo  * @id: unique BSS identifier
2972d4f2939cSRui Paulo  * Returns: 0 on success, -1 on failure
2973d4f2939cSRui Paulo  *
2974d4f2939cSRui Paulo  * Unregisters BSS representing object from dbus
2975d4f2939cSRui Paulo  */
2976d4f2939cSRui Paulo int wpas_dbus_unregister_bss(struct wpa_supplicant *wpa_s,
2977d4f2939cSRui Paulo 			     u8 bssid[ETH_ALEN], unsigned int id)
2978d4f2939cSRui Paulo {
2979d4f2939cSRui Paulo 	struct wpas_dbus_priv *ctrl_iface;
2980d4f2939cSRui Paulo 	char bss_obj_path[WPAS_DBUS_OBJECT_PATH_MAX];
2981d4f2939cSRui Paulo 
2982d4f2939cSRui Paulo 	/* Do nothing if the control interface is not turned on */
2983325151a3SRui Paulo 	if (wpa_s == NULL || wpa_s->global == NULL || !wpa_s->dbus_new_path)
2984d4f2939cSRui Paulo 		return 0;
2985d4f2939cSRui Paulo 	ctrl_iface = wpa_s->global->dbus;
2986d4f2939cSRui Paulo 	if (ctrl_iface == NULL)
2987d4f2939cSRui Paulo 		return 0;
2988d4f2939cSRui Paulo 
2989d4f2939cSRui Paulo 	os_snprintf(bss_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
2990d4f2939cSRui Paulo 		    "%s/" WPAS_DBUS_NEW_BSSIDS_PART "/%u",
2991d4f2939cSRui Paulo 		    wpa_s->dbus_new_path, id);
2992d4f2939cSRui Paulo 
2993d4f2939cSRui Paulo 	wpa_printf(MSG_DEBUG, "dbus: Unregister BSS object '%s'",
2994d4f2939cSRui Paulo 		   bss_obj_path);
2995d4f2939cSRui Paulo 	if (wpa_dbus_unregister_object_per_iface(ctrl_iface, bss_obj_path)) {
2996d4f2939cSRui Paulo 		wpa_printf(MSG_ERROR, "dbus: Cannot unregister BSS object %s",
2997d4f2939cSRui Paulo 			   bss_obj_path);
2998d4f2939cSRui Paulo 		return -1;
2999d4f2939cSRui Paulo 	}
3000d4f2939cSRui Paulo 
3001d4f2939cSRui Paulo 	wpas_dbus_signal_bss_removed(wpa_s, bss_obj_path);
3002d4f2939cSRui Paulo 	wpas_dbus_signal_prop_changed(wpa_s, WPAS_DBUS_PROP_BSSS);
3003d4f2939cSRui Paulo 
3004d4f2939cSRui Paulo 	return 0;
3005d4f2939cSRui Paulo }
3006d4f2939cSRui Paulo 
3007d4f2939cSRui Paulo 
3008d4f2939cSRui Paulo /**
3009d4f2939cSRui Paulo  * wpas_dbus_register_bss - Register a scanned BSS with dbus
3010d4f2939cSRui Paulo  * @wpa_s: wpa_supplicant interface structure
3011d4f2939cSRui Paulo  * @bssid: scanned network bssid
3012d4f2939cSRui Paulo  * @id: unique BSS identifier
3013d4f2939cSRui Paulo  * Returns: 0 on success, -1 on failure
3014d4f2939cSRui Paulo  *
3015d4f2939cSRui Paulo  * Registers BSS representing object with dbus
3016d4f2939cSRui Paulo  */
3017d4f2939cSRui Paulo int wpas_dbus_register_bss(struct wpa_supplicant *wpa_s,
3018d4f2939cSRui Paulo 			   u8 bssid[ETH_ALEN], unsigned int id)
3019d4f2939cSRui Paulo {
3020d4f2939cSRui Paulo 	struct wpas_dbus_priv *ctrl_iface;
3021d4f2939cSRui Paulo 	struct wpa_dbus_object_desc *obj_desc;
3022d4f2939cSRui Paulo 	char bss_obj_path[WPAS_DBUS_OBJECT_PATH_MAX];
3023d4f2939cSRui Paulo 	struct bss_handler_args *arg;
3024d4f2939cSRui Paulo 
3025d4f2939cSRui Paulo 	/* Do nothing if the control interface is not turned on */
3026325151a3SRui Paulo 	if (wpa_s == NULL || wpa_s->global == NULL || !wpa_s->dbus_new_path)
3027d4f2939cSRui Paulo 		return 0;
3028d4f2939cSRui Paulo 	ctrl_iface = wpa_s->global->dbus;
3029d4f2939cSRui Paulo 	if (ctrl_iface == NULL)
3030d4f2939cSRui Paulo 		return 0;
3031d4f2939cSRui Paulo 
3032d4f2939cSRui Paulo 	os_snprintf(bss_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
3033d4f2939cSRui Paulo 		    "%s/" WPAS_DBUS_NEW_BSSIDS_PART "/%u",
3034d4f2939cSRui Paulo 		    wpa_s->dbus_new_path, id);
3035d4f2939cSRui Paulo 
3036d4f2939cSRui Paulo 	obj_desc = os_zalloc(sizeof(struct wpa_dbus_object_desc));
3037d4f2939cSRui Paulo 	if (!obj_desc) {
30385b9c547cSRui Paulo 		wpa_printf(MSG_ERROR,
30395b9c547cSRui Paulo 			   "Not enough memory to create object description");
3040d4f2939cSRui Paulo 		goto err;
3041d4f2939cSRui Paulo 	}
3042d4f2939cSRui Paulo 
3043d4f2939cSRui Paulo 	arg = os_zalloc(sizeof(struct bss_handler_args));
3044d4f2939cSRui Paulo 	if (!arg) {
30455b9c547cSRui Paulo 		wpa_printf(MSG_ERROR,
30465b9c547cSRui Paulo 			   "Not enough memory to create arguments for handler");
3047d4f2939cSRui Paulo 		goto err;
3048d4f2939cSRui Paulo 	}
3049d4f2939cSRui Paulo 	arg->wpa_s = wpa_s;
3050d4f2939cSRui Paulo 	arg->id = id;
3051d4f2939cSRui Paulo 
3052d4f2939cSRui Paulo 	wpas_dbus_register(obj_desc, arg, wpa_dbus_free, NULL,
3053d4f2939cSRui Paulo 			   wpas_dbus_bss_properties,
3054d4f2939cSRui Paulo 			   wpas_dbus_bss_signals);
3055d4f2939cSRui Paulo 
3056d4f2939cSRui Paulo 	wpa_printf(MSG_DEBUG, "dbus: Register BSS object '%s'",
3057d4f2939cSRui Paulo 		   bss_obj_path);
3058d4f2939cSRui Paulo 	if (wpa_dbus_register_object_per_iface(ctrl_iface, bss_obj_path,
3059d4f2939cSRui Paulo 					       wpa_s->ifname, obj_desc)) {
3060d4f2939cSRui Paulo 		wpa_printf(MSG_ERROR,
3061d4f2939cSRui Paulo 			   "Cannot register BSSID dbus object %s.",
3062d4f2939cSRui Paulo 			   bss_obj_path);
3063d4f2939cSRui Paulo 		goto err;
3064d4f2939cSRui Paulo 	}
3065d4f2939cSRui Paulo 
3066d4f2939cSRui Paulo 	wpas_dbus_signal_bss_added(wpa_s, bss_obj_path);
3067d4f2939cSRui Paulo 	wpas_dbus_signal_prop_changed(wpa_s, WPAS_DBUS_PROP_BSSS);
3068d4f2939cSRui Paulo 
3069d4f2939cSRui Paulo 	return 0;
3070d4f2939cSRui Paulo 
3071d4f2939cSRui Paulo err:
3072d4f2939cSRui Paulo 	free_dbus_object_desc(obj_desc);
3073d4f2939cSRui Paulo 	return -1;
3074d4f2939cSRui Paulo }
3075d4f2939cSRui Paulo 
3076d4f2939cSRui Paulo 
30774bc52338SCy Schubert static const struct wpa_dbus_property_desc wpas_dbus_sta_properties[] = {
30784bc52338SCy Schubert 	{ "Address", WPAS_DBUS_NEW_IFACE_STA, "ay",
30794bc52338SCy Schubert 	  wpas_dbus_getter_sta_address,
30804bc52338SCy Schubert 	  NULL, NULL
30814bc52338SCy Schubert 	},
30824bc52338SCy Schubert 	{ "AID", WPAS_DBUS_NEW_IFACE_STA, "q",
30834bc52338SCy Schubert 	  wpas_dbus_getter_sta_aid,
30844bc52338SCy Schubert 	  NULL, NULL
30854bc52338SCy Schubert 	},
30864bc52338SCy Schubert 	{ "Capabilities", WPAS_DBUS_NEW_IFACE_STA, "q",
30874bc52338SCy Schubert 	  wpas_dbus_getter_sta_caps,
30884bc52338SCy Schubert 	  NULL, NULL
30894bc52338SCy Schubert 	},
30904bc52338SCy Schubert 	{ "RxPackets", WPAS_DBUS_NEW_IFACE_STA, "t",
30914bc52338SCy Schubert 	  wpas_dbus_getter_sta_rx_packets,
30924bc52338SCy Schubert 	  NULL, NULL
30934bc52338SCy Schubert 	},
30944bc52338SCy Schubert 	{ "TxPackets", WPAS_DBUS_NEW_IFACE_STA, "t",
30954bc52338SCy Schubert 	  wpas_dbus_getter_sta_tx_packets,
30964bc52338SCy Schubert 	  NULL, NULL
30974bc52338SCy Schubert 	},
30984bc52338SCy Schubert 	{ "RxBytes", WPAS_DBUS_NEW_IFACE_STA, "t",
30994bc52338SCy Schubert 	  wpas_dbus_getter_sta_rx_bytes,
31004bc52338SCy Schubert 	  NULL, NULL
31014bc52338SCy Schubert 	},
31024bc52338SCy Schubert 	{ "TxBytes", WPAS_DBUS_NEW_IFACE_STA, "t",
31034bc52338SCy Schubert 	  wpas_dbus_getter_sta_tx_bytes,
31044bc52338SCy Schubert 	  NULL, NULL
31054bc52338SCy Schubert 	},
31064bc52338SCy Schubert 	{ NULL, NULL, NULL, NULL, NULL, NULL }
31074bc52338SCy Schubert };
31084bc52338SCy Schubert 
31094bc52338SCy Schubert 
31104bc52338SCy Schubert static const struct wpa_dbus_signal_desc wpas_dbus_sta_signals[] = {
31114bc52338SCy Schubert 	/* Deprecated: use org.freedesktop.DBus.Properties.PropertiesChanged */
31124bc52338SCy Schubert 	{ "PropertiesChanged", WPAS_DBUS_NEW_IFACE_STA,
31134bc52338SCy Schubert 	  {
31144bc52338SCy Schubert 		  { "properties", "a{sv}", ARG_OUT },
31154bc52338SCy Schubert 		  END_ARGS
31164bc52338SCy Schubert 	  }
31174bc52338SCy Schubert 	},
31184bc52338SCy Schubert 	{ NULL, NULL, { END_ARGS } }
31194bc52338SCy Schubert };
31204bc52338SCy Schubert 
31214bc52338SCy Schubert 
31224bc52338SCy Schubert /**
31234bc52338SCy Schubert  * wpas_dbus_unregister_sta - Unregister a connected station from dbus
31244bc52338SCy Schubert  * @wpa_s: wpa_supplicant interface structure
31254bc52338SCy Schubert  * @sta: station MAC address
31264bc52338SCy Schubert  * Returns: 0 on success, -1 on failure
31274bc52338SCy Schubert  *
31284bc52338SCy Schubert  * Unregisters STA representing object from dbus.
31294bc52338SCy Schubert  */
31304bc52338SCy Schubert int wpas_dbus_unregister_sta(struct wpa_supplicant *wpa_s, const u8 *sta)
31314bc52338SCy Schubert {
31324bc52338SCy Schubert 	struct wpas_dbus_priv *ctrl_iface;
31334bc52338SCy Schubert 	char station_obj_path[WPAS_DBUS_OBJECT_PATH_MAX];
31344bc52338SCy Schubert 
31354bc52338SCy Schubert 	/* Do nothing if the control interface is not turned on */
31364bc52338SCy Schubert 	if (!wpa_s || !wpa_s->global)
31374bc52338SCy Schubert 		return 0;
31384bc52338SCy Schubert 	ctrl_iface = wpa_s->global->dbus;
31394bc52338SCy Schubert 	if (!ctrl_iface)
31404bc52338SCy Schubert 		return 0;
31414bc52338SCy Schubert 
31424bc52338SCy Schubert 	os_snprintf(station_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
31434bc52338SCy Schubert 		    "%s/" WPAS_DBUS_NEW_STAS_PART "/" COMPACT_MACSTR,
31444bc52338SCy Schubert 		    wpa_s->dbus_new_path, MAC2STR(sta));
31454bc52338SCy Schubert 
31464bc52338SCy Schubert 	wpa_printf(MSG_DEBUG, "dbus: Unregister STA object '%s'",
31474bc52338SCy Schubert 		   station_obj_path);
31484bc52338SCy Schubert 	if (wpa_dbus_unregister_object_per_iface(ctrl_iface,
31494bc52338SCy Schubert 						 station_obj_path)) {
31504bc52338SCy Schubert 		wpa_printf(MSG_ERROR, "dbus: Cannot unregister STA object %s",
31514bc52338SCy Schubert 			   station_obj_path);
31524bc52338SCy Schubert 		return -1;
31534bc52338SCy Schubert 	}
31544bc52338SCy Schubert 
31554bc52338SCy Schubert 	wpas_dbus_signal_station_removed(wpa_s, station_obj_path);
31564bc52338SCy Schubert 	wpas_dbus_signal_prop_changed(wpa_s, WPAS_DBUS_PROP_STATIONS);
31574bc52338SCy Schubert 
31584bc52338SCy Schubert 	return 0;
31594bc52338SCy Schubert }
31604bc52338SCy Schubert 
31614bc52338SCy Schubert 
31624bc52338SCy Schubert /**
31634bc52338SCy Schubert  * wpas_dbus_register_sta - Register a connected station with dbus
31644bc52338SCy Schubert  * @wpa_s: wpa_supplicant interface structure
31654bc52338SCy Schubert  * @sta: station MAC address
31664bc52338SCy Schubert  * Returns: 0 on success, -1 on failure
31674bc52338SCy Schubert  *
31684bc52338SCy Schubert  * Registers STA representing object with dbus.
31694bc52338SCy Schubert  */
31704bc52338SCy Schubert int wpas_dbus_register_sta(struct wpa_supplicant *wpa_s, const u8 *sta)
31714bc52338SCy Schubert {
31724bc52338SCy Schubert 	struct wpas_dbus_priv *ctrl_iface;
31734bc52338SCy Schubert 	struct wpa_dbus_object_desc *obj_desc;
31744bc52338SCy Schubert 	char station_obj_path[WPAS_DBUS_OBJECT_PATH_MAX];
31754bc52338SCy Schubert 	struct sta_handler_args *arg;
31764bc52338SCy Schubert 
31774bc52338SCy Schubert 	/* Do nothing if the control interface is not turned on */
31784bc52338SCy Schubert 	if (!wpa_s || !wpa_s->global)
31794bc52338SCy Schubert 		return 0;
31804bc52338SCy Schubert 	ctrl_iface = wpa_s->global->dbus;
31814bc52338SCy Schubert 	if (!ctrl_iface)
31824bc52338SCy Schubert 		return 0;
31834bc52338SCy Schubert 
31844bc52338SCy Schubert 	os_snprintf(station_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
31854bc52338SCy Schubert 		    "%s/" WPAS_DBUS_NEW_STAS_PART "/" COMPACT_MACSTR,
31864bc52338SCy Schubert 		    wpa_s->dbus_new_path, MAC2STR(sta));
31874bc52338SCy Schubert 
31884bc52338SCy Schubert 	obj_desc = os_zalloc(sizeof(struct wpa_dbus_object_desc));
31894bc52338SCy Schubert 	if (!obj_desc) {
31904bc52338SCy Schubert 		wpa_printf(MSG_ERROR,
31914bc52338SCy Schubert 			   "Not enough memory to create object description");
31924bc52338SCy Schubert 		goto err;
31934bc52338SCy Schubert 	}
31944bc52338SCy Schubert 
31954bc52338SCy Schubert 	arg = os_zalloc(sizeof(struct sta_handler_args));
31964bc52338SCy Schubert 	if (!arg) {
31974bc52338SCy Schubert 		wpa_printf(MSG_ERROR,
31984bc52338SCy Schubert 			   "Not enough memory to create arguments for handler");
31994bc52338SCy Schubert 		goto err;
32004bc52338SCy Schubert 	}
32014bc52338SCy Schubert 	arg->wpa_s = wpa_s;
32024bc52338SCy Schubert 	arg->sta = sta;
32034bc52338SCy Schubert 
32044bc52338SCy Schubert 	wpas_dbus_register(obj_desc, arg, wpa_dbus_free, NULL,
32054bc52338SCy Schubert 			   wpas_dbus_sta_properties, wpas_dbus_sta_signals);
32064bc52338SCy Schubert 
32074bc52338SCy Schubert 	wpa_printf(MSG_DEBUG, "dbus: Register STA object '%s'",
32084bc52338SCy Schubert 		   station_obj_path);
32094bc52338SCy Schubert 	if (wpa_dbus_register_object_per_iface(ctrl_iface, station_obj_path,
32104bc52338SCy Schubert 					       wpa_s->ifname, obj_desc)) {
32114bc52338SCy Schubert 		wpa_printf(MSG_ERROR,
32124bc52338SCy Schubert 			   "Cannot register STA dbus object %s",
32134bc52338SCy Schubert 			   station_obj_path);
32144bc52338SCy Schubert 		goto err;
32154bc52338SCy Schubert 	}
32164bc52338SCy Schubert 
32174bc52338SCy Schubert 	wpas_dbus_signal_station_added(wpa_s, station_obj_path);
32184bc52338SCy Schubert 	wpas_dbus_signal_prop_changed(wpa_s, WPAS_DBUS_PROP_STATIONS);
32194bc52338SCy Schubert 
32204bc52338SCy Schubert 	return 0;
32214bc52338SCy Schubert 
32224bc52338SCy Schubert err:
32234bc52338SCy Schubert 	free_dbus_object_desc(obj_desc);
32244bc52338SCy Schubert 	return -1;
32254bc52338SCy Schubert }
32264bc52338SCy Schubert 
32274bc52338SCy Schubert 
3228d4f2939cSRui Paulo static const struct wpa_dbus_method_desc wpas_dbus_interface_methods[] = {
3229d4f2939cSRui Paulo 	{ "Scan", WPAS_DBUS_NEW_IFACE_INTERFACE,
32305b9c547cSRui Paulo 	  (WPADBusMethodHandler) wpas_dbus_handler_scan,
3231d4f2939cSRui Paulo 	  {
3232d4f2939cSRui Paulo 		  { "args", "a{sv}", ARG_IN },
3233d4f2939cSRui Paulo 		  END_ARGS
3234d4f2939cSRui Paulo 	  }
3235d4f2939cSRui Paulo 	},
32365b9c547cSRui Paulo 	{ "SignalPoll", WPAS_DBUS_NEW_IFACE_INTERFACE,
32375b9c547cSRui Paulo 	  (WPADBusMethodHandler) wpas_dbus_handler_signal_poll,
32385b9c547cSRui Paulo 	  {
32395b9c547cSRui Paulo 		  { "args", "a{sv}", ARG_OUT },
32405b9c547cSRui Paulo 		  END_ARGS
32415b9c547cSRui Paulo 	  }
32425b9c547cSRui Paulo 	},
3243d4f2939cSRui Paulo 	{ "Disconnect", WPAS_DBUS_NEW_IFACE_INTERFACE,
32445b9c547cSRui Paulo 	  (WPADBusMethodHandler) wpas_dbus_handler_disconnect,
3245d4f2939cSRui Paulo 	  {
3246d4f2939cSRui Paulo 		  END_ARGS
3247d4f2939cSRui Paulo 	  }
3248d4f2939cSRui Paulo 	},
3249d4f2939cSRui Paulo 	{ "AddNetwork", WPAS_DBUS_NEW_IFACE_INTERFACE,
32505b9c547cSRui Paulo 	  (WPADBusMethodHandler) wpas_dbus_handler_add_network,
3251d4f2939cSRui Paulo 	  {
3252d4f2939cSRui Paulo 		  { "args", "a{sv}", ARG_IN },
3253d4f2939cSRui Paulo 		  { "path", "o", ARG_OUT },
3254d4f2939cSRui Paulo 		  END_ARGS
3255d4f2939cSRui Paulo 	  }
3256d4f2939cSRui Paulo 	},
3257d4f2939cSRui Paulo 	{ "Reassociate", WPAS_DBUS_NEW_IFACE_INTERFACE,
32585b9c547cSRui Paulo 	  (WPADBusMethodHandler) wpas_dbus_handler_reassociate,
32595b9c547cSRui Paulo 	  {
32605b9c547cSRui Paulo 		  END_ARGS
32615b9c547cSRui Paulo 	  }
32625b9c547cSRui Paulo 	},
32635b9c547cSRui Paulo 	{ "Reattach", WPAS_DBUS_NEW_IFACE_INTERFACE,
32645b9c547cSRui Paulo 	  (WPADBusMethodHandler) wpas_dbus_handler_reattach,
3265d4f2939cSRui Paulo 	  {
3266d4f2939cSRui Paulo 		  END_ARGS
3267d4f2939cSRui Paulo 	  }
3268d4f2939cSRui Paulo 	},
3269325151a3SRui Paulo 	{ "Reconnect", WPAS_DBUS_NEW_IFACE_INTERFACE,
3270325151a3SRui Paulo 	  (WPADBusMethodHandler) wpas_dbus_handler_reconnect,
3271325151a3SRui Paulo 	  {
3272325151a3SRui Paulo 		  END_ARGS
3273325151a3SRui Paulo 	  }
3274325151a3SRui Paulo 	},
3275d4f2939cSRui Paulo 	{ "RemoveNetwork", WPAS_DBUS_NEW_IFACE_INTERFACE,
32765b9c547cSRui Paulo 	  (WPADBusMethodHandler) wpas_dbus_handler_remove_network,
3277d4f2939cSRui Paulo 	  {
3278d4f2939cSRui Paulo 		  { "path", "o", ARG_IN },
3279d4f2939cSRui Paulo 		  END_ARGS
3280d4f2939cSRui Paulo 	  }
3281d4f2939cSRui Paulo 	},
3282d4f2939cSRui Paulo 	{ "RemoveAllNetworks", WPAS_DBUS_NEW_IFACE_INTERFACE,
32835b9c547cSRui Paulo 	  (WPADBusMethodHandler) wpas_dbus_handler_remove_all_networks,
3284d4f2939cSRui Paulo 	  {
3285d4f2939cSRui Paulo 		  END_ARGS
3286d4f2939cSRui Paulo 	  }
3287d4f2939cSRui Paulo 	},
3288d4f2939cSRui Paulo 	{ "SelectNetwork", WPAS_DBUS_NEW_IFACE_INTERFACE,
32895b9c547cSRui Paulo 	  (WPADBusMethodHandler) wpas_dbus_handler_select_network,
3290d4f2939cSRui Paulo 	  {
3291d4f2939cSRui Paulo 		  { "path", "o", ARG_IN },
3292d4f2939cSRui Paulo 		  END_ARGS
3293d4f2939cSRui Paulo 	  }
3294d4f2939cSRui Paulo 	},
3295d4f2939cSRui Paulo 	{ "NetworkReply", WPAS_DBUS_NEW_IFACE_INTERFACE,
32965b9c547cSRui Paulo 	  (WPADBusMethodHandler) wpas_dbus_handler_network_reply,
3297d4f2939cSRui Paulo 	  {
3298d4f2939cSRui Paulo 		  { "path", "o", ARG_IN },
3299d4f2939cSRui Paulo 		  { "field", "s", ARG_IN },
3300d4f2939cSRui Paulo 		  { "value", "s", ARG_IN },
3301d4f2939cSRui Paulo 		  END_ARGS
3302d4f2939cSRui Paulo 	  }
3303d4f2939cSRui Paulo 	},
3304c1d255d3SCy Schubert 	{ "Roam", WPAS_DBUS_NEW_IFACE_INTERFACE,
3305c1d255d3SCy Schubert 	  (WPADBusMethodHandler) wpas_dbus_handler_roam,
3306c1d255d3SCy Schubert 	  {
3307c1d255d3SCy Schubert 		  { "addr", "s", ARG_IN },
3308c1d255d3SCy Schubert 		  END_ARGS
3309c1d255d3SCy Schubert 	  }
3310c1d255d3SCy Schubert 	},
3311c1d255d3SCy Schubert 
33125b9c547cSRui Paulo #ifndef CONFIG_NO_CONFIG_BLOBS
3313d4f2939cSRui Paulo 	{ "AddBlob", WPAS_DBUS_NEW_IFACE_INTERFACE,
33145b9c547cSRui Paulo 	  (WPADBusMethodHandler) wpas_dbus_handler_add_blob,
3315d4f2939cSRui Paulo 	  {
3316d4f2939cSRui Paulo 		  { "name", "s", ARG_IN },
3317d4f2939cSRui Paulo 		  { "data", "ay", ARG_IN },
3318d4f2939cSRui Paulo 		  END_ARGS
3319d4f2939cSRui Paulo 	  }
3320d4f2939cSRui Paulo 	},
3321d4f2939cSRui Paulo 	{ "GetBlob", WPAS_DBUS_NEW_IFACE_INTERFACE,
33225b9c547cSRui Paulo 	  (WPADBusMethodHandler) wpas_dbus_handler_get_blob,
3323d4f2939cSRui Paulo 	  {
3324d4f2939cSRui Paulo 		  { "name", "s", ARG_IN },
3325d4f2939cSRui Paulo 		  { "data", "ay", ARG_OUT },
3326d4f2939cSRui Paulo 		  END_ARGS
3327d4f2939cSRui Paulo 	  }
3328d4f2939cSRui Paulo 	},
3329d4f2939cSRui Paulo 	{ "RemoveBlob", WPAS_DBUS_NEW_IFACE_INTERFACE,
33305b9c547cSRui Paulo 	  (WPADBusMethodHandler) wpas_dbus_handler_remove_blob,
3331d4f2939cSRui Paulo 	  {
3332d4f2939cSRui Paulo 		  { "name", "s", ARG_IN },
3333d4f2939cSRui Paulo 		  END_ARGS
3334d4f2939cSRui Paulo 	  }
3335d4f2939cSRui Paulo 	},
33365b9c547cSRui Paulo #endif /* CONFIG_NO_CONFIG_BLOBS */
33375b9c547cSRui Paulo 	{ "SetPKCS11EngineAndModulePath", WPAS_DBUS_NEW_IFACE_INTERFACE,
33385b9c547cSRui Paulo 	  (WPADBusMethodHandler)
33395b9c547cSRui Paulo 	  wpas_dbus_handler_set_pkcs11_engine_and_module_path,
33405b9c547cSRui Paulo 	  {
33415b9c547cSRui Paulo 		  { "pkcs11_engine_path", "s", ARG_IN },
33425b9c547cSRui Paulo 		  { "pkcs11_module_path", "s", ARG_IN },
33435b9c547cSRui Paulo 		  END_ARGS
33445b9c547cSRui Paulo 	  }
33455b9c547cSRui Paulo 	},
3346d4f2939cSRui Paulo #ifdef CONFIG_WPS
3347d4f2939cSRui Paulo 	{ "Start", WPAS_DBUS_NEW_IFACE_WPS,
33485b9c547cSRui Paulo 	  (WPADBusMethodHandler) wpas_dbus_handler_wps_start,
3349d4f2939cSRui Paulo 	  {
3350d4f2939cSRui Paulo 		  { "args", "a{sv}", ARG_IN },
3351d4f2939cSRui Paulo 		  { "output", "a{sv}", ARG_OUT },
3352d4f2939cSRui Paulo 		  END_ARGS
3353d4f2939cSRui Paulo 	  }
3354d4f2939cSRui Paulo 	},
3355325151a3SRui Paulo 	{ "Cancel", WPAS_DBUS_NEW_IFACE_WPS,
3356325151a3SRui Paulo 	  (WPADBusMethodHandler) wpas_dbus_handler_wps_cancel,
3357325151a3SRui Paulo 	  {
3358325151a3SRui Paulo 		  END_ARGS
3359325151a3SRui Paulo 	  }
3360325151a3SRui Paulo 	},
3361d4f2939cSRui Paulo #endif /* CONFIG_WPS */
3362d4f2939cSRui Paulo #ifdef CONFIG_P2P
3363d4f2939cSRui Paulo 	{ "Find", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
3364d4f2939cSRui Paulo 	  (WPADBusMethodHandler) wpas_dbus_handler_p2p_find,
3365d4f2939cSRui Paulo 	  {
3366d4f2939cSRui Paulo 		  { "args", "a{sv}", ARG_IN },
3367d4f2939cSRui Paulo 		  END_ARGS
3368d4f2939cSRui Paulo 	  }
3369d4f2939cSRui Paulo 	},
3370d4f2939cSRui Paulo 	{ "StopFind", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
3371d4f2939cSRui Paulo 	  (WPADBusMethodHandler) wpas_dbus_handler_p2p_stop_find,
3372d4f2939cSRui Paulo 	  {
3373d4f2939cSRui Paulo 		  END_ARGS
3374d4f2939cSRui Paulo 	  }
3375d4f2939cSRui Paulo 	},
3376d4f2939cSRui Paulo 	{ "Listen", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
3377d4f2939cSRui Paulo 	  (WPADBusMethodHandler) wpas_dbus_handler_p2p_listen,
3378d4f2939cSRui Paulo 	  {
3379d4f2939cSRui Paulo 		  { "timeout", "i", ARG_IN },
3380d4f2939cSRui Paulo 		  END_ARGS
3381d4f2939cSRui Paulo 	  }
3382d4f2939cSRui Paulo 	},
3383d4f2939cSRui Paulo 	{ "ExtendedListen", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
3384d4f2939cSRui Paulo 	  (WPADBusMethodHandler) wpas_dbus_handler_p2p_extendedlisten,
3385d4f2939cSRui Paulo 	  {
3386d4f2939cSRui Paulo 		  { "args", "a{sv}", ARG_IN },
3387d4f2939cSRui Paulo 		  END_ARGS
3388d4f2939cSRui Paulo 	  }
3389d4f2939cSRui Paulo 	},
3390d4f2939cSRui Paulo 	{ "PresenceRequest", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
3391d4f2939cSRui Paulo 	  (WPADBusMethodHandler) wpas_dbus_handler_p2p_presence_request,
3392d4f2939cSRui Paulo 	  {
3393d4f2939cSRui Paulo 		  { "args", "a{sv}", ARG_IN },
3394d4f2939cSRui Paulo 		  END_ARGS
3395d4f2939cSRui Paulo 	  }
3396d4f2939cSRui Paulo 	},
3397d4f2939cSRui Paulo 	{ "ProvisionDiscoveryRequest", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
3398d4f2939cSRui Paulo 	  (WPADBusMethodHandler) wpas_dbus_handler_p2p_prov_disc_req,
3399d4f2939cSRui Paulo 	  {
3400d4f2939cSRui Paulo 		  { "peer", "o", ARG_IN },
3401d4f2939cSRui Paulo 		  { "config_method", "s", ARG_IN },
3402d4f2939cSRui Paulo 		  END_ARGS
3403d4f2939cSRui Paulo 	  }
3404d4f2939cSRui Paulo 	},
3405d4f2939cSRui Paulo 	{ "Connect", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
3406d4f2939cSRui Paulo 	  (WPADBusMethodHandler) wpas_dbus_handler_p2p_connect,
3407d4f2939cSRui Paulo 	  {
3408d4f2939cSRui Paulo 		  { "args", "a{sv}", ARG_IN },
3409d4f2939cSRui Paulo 		  { "generated_pin", "s", ARG_OUT },
3410d4f2939cSRui Paulo 		  END_ARGS
3411d4f2939cSRui Paulo 	  }
3412d4f2939cSRui Paulo 	},
3413d4f2939cSRui Paulo 	{ "GroupAdd", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
3414d4f2939cSRui Paulo 	  (WPADBusMethodHandler) wpas_dbus_handler_p2p_group_add,
3415d4f2939cSRui Paulo 	  {
3416d4f2939cSRui Paulo 		  { "args", "a{sv}", ARG_IN },
3417d4f2939cSRui Paulo 		  END_ARGS
3418d4f2939cSRui Paulo 	  }
3419d4f2939cSRui Paulo 	},
3420325151a3SRui Paulo 	{ "Cancel", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
3421325151a3SRui Paulo 	  (WPADBusMethodHandler) wpas_dbus_handler_p2p_cancel,
3422325151a3SRui Paulo 	  {
3423325151a3SRui Paulo 		  END_ARGS
3424325151a3SRui Paulo 	  }
3425325151a3SRui Paulo 	},
3426d4f2939cSRui Paulo 	{ "Invite", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
3427d4f2939cSRui Paulo 	  (WPADBusMethodHandler) wpas_dbus_handler_p2p_invite,
3428d4f2939cSRui Paulo 	  {
3429d4f2939cSRui Paulo 		  { "args", "a{sv}", ARG_IN },
3430d4f2939cSRui Paulo 		  END_ARGS
3431d4f2939cSRui Paulo 	  }
3432d4f2939cSRui Paulo 	},
3433d4f2939cSRui Paulo 	{ "Disconnect", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
3434d4f2939cSRui Paulo 	  (WPADBusMethodHandler) wpas_dbus_handler_p2p_disconnect,
3435d4f2939cSRui Paulo 	  {
3436d4f2939cSRui Paulo 		  END_ARGS
3437d4f2939cSRui Paulo 	  }
3438d4f2939cSRui Paulo 	},
3439d4f2939cSRui Paulo 	{ "RejectPeer", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
3440d4f2939cSRui Paulo 	  (WPADBusMethodHandler) wpas_dbus_handler_p2p_rejectpeer,
3441d4f2939cSRui Paulo 	  {
3442d4f2939cSRui Paulo 		  { "peer", "o", ARG_IN },
3443d4f2939cSRui Paulo 		  END_ARGS
3444d4f2939cSRui Paulo 	  }
3445d4f2939cSRui Paulo 	},
3446325151a3SRui Paulo 	{ "RemoveClient", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
3447325151a3SRui Paulo 	  (WPADBusMethodHandler) wpas_dbus_handler_p2p_remove_client,
3448325151a3SRui Paulo 	  {
3449325151a3SRui Paulo 		  { "args", "a{sv}", ARG_IN },
3450325151a3SRui Paulo 		  END_ARGS
3451325151a3SRui Paulo 	  }
3452325151a3SRui Paulo 	},
3453d4f2939cSRui Paulo 	{ "Flush", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
3454d4f2939cSRui Paulo 	  (WPADBusMethodHandler) wpas_dbus_handler_p2p_flush,
3455d4f2939cSRui Paulo 	  {
3456d4f2939cSRui Paulo 		  END_ARGS
3457d4f2939cSRui Paulo 	  }
3458d4f2939cSRui Paulo 	},
3459d4f2939cSRui Paulo 	{ "AddService", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
3460d4f2939cSRui Paulo 	  (WPADBusMethodHandler) wpas_dbus_handler_p2p_add_service,
3461d4f2939cSRui Paulo 	  {
3462d4f2939cSRui Paulo 		  { "args", "a{sv}", ARG_IN },
3463d4f2939cSRui Paulo 		  END_ARGS
3464d4f2939cSRui Paulo 	  }
3465d4f2939cSRui Paulo 	},
3466d4f2939cSRui Paulo 	{ "DeleteService", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
3467d4f2939cSRui Paulo 	  (WPADBusMethodHandler) wpas_dbus_handler_p2p_delete_service,
3468d4f2939cSRui Paulo 	  {
3469d4f2939cSRui Paulo 		  { "args", "a{sv}", ARG_IN },
3470d4f2939cSRui Paulo 		  END_ARGS
3471d4f2939cSRui Paulo 	  }
3472d4f2939cSRui Paulo 	},
3473d4f2939cSRui Paulo 	{ "FlushService", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
3474d4f2939cSRui Paulo 	  (WPADBusMethodHandler) wpas_dbus_handler_p2p_flush_service,
3475d4f2939cSRui Paulo 	  {
3476d4f2939cSRui Paulo 		  END_ARGS
3477d4f2939cSRui Paulo 	  }
3478d4f2939cSRui Paulo 	},
3479d4f2939cSRui Paulo 	{ "ServiceDiscoveryRequest", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
3480d4f2939cSRui Paulo 	  (WPADBusMethodHandler) wpas_dbus_handler_p2p_service_sd_req,
3481d4f2939cSRui Paulo 	  {
3482d4f2939cSRui Paulo 		  { "args", "a{sv}", ARG_IN },
34835b9c547cSRui Paulo 		  { "ref", "t", ARG_OUT },
3484d4f2939cSRui Paulo 		  END_ARGS
3485d4f2939cSRui Paulo 	  }
3486d4f2939cSRui Paulo 	},
3487d4f2939cSRui Paulo 	{ "ServiceDiscoveryResponse", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
3488d4f2939cSRui Paulo 	  (WPADBusMethodHandler) wpas_dbus_handler_p2p_service_sd_res,
3489d4f2939cSRui Paulo 	  {
3490d4f2939cSRui Paulo 		  { "args", "a{sv}", ARG_IN },
3491d4f2939cSRui Paulo 		  END_ARGS
3492d4f2939cSRui Paulo 	  }
3493d4f2939cSRui Paulo 	},
3494d4f2939cSRui Paulo 	{ "ServiceDiscoveryCancelRequest", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
3495d4f2939cSRui Paulo 	  (WPADBusMethodHandler) wpas_dbus_handler_p2p_service_sd_cancel_req,
3496d4f2939cSRui Paulo 	  {
3497d4f2939cSRui Paulo 		  { "args", "t", ARG_IN },
3498d4f2939cSRui Paulo 		  END_ARGS
3499d4f2939cSRui Paulo 	  }
3500d4f2939cSRui Paulo 	},
3501d4f2939cSRui Paulo 	{ "ServiceUpdate", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
3502d4f2939cSRui Paulo 	  (WPADBusMethodHandler) wpas_dbus_handler_p2p_service_update,
3503d4f2939cSRui Paulo 	  {
3504d4f2939cSRui Paulo 		  END_ARGS
3505d4f2939cSRui Paulo 	  }
3506d4f2939cSRui Paulo 	},
3507d4f2939cSRui Paulo 	{ "ServiceDiscoveryExternal", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
3508d4f2939cSRui Paulo 	  (WPADBusMethodHandler) wpas_dbus_handler_p2p_serv_disc_external,
3509d4f2939cSRui Paulo 	  {
3510d4f2939cSRui Paulo 		  { "arg", "i", ARG_IN },
3511d4f2939cSRui Paulo 		  END_ARGS
3512d4f2939cSRui Paulo 	  }
3513d4f2939cSRui Paulo 	},
3514d4f2939cSRui Paulo 	{ "AddPersistentGroup", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
3515d4f2939cSRui Paulo 	  (WPADBusMethodHandler) wpas_dbus_handler_add_persistent_group,
3516d4f2939cSRui Paulo 	  {
3517d4f2939cSRui Paulo 		  { "args", "a{sv}", ARG_IN },
3518d4f2939cSRui Paulo 		  { "path", "o", ARG_OUT },
3519d4f2939cSRui Paulo 		  END_ARGS
3520d4f2939cSRui Paulo 	  }
3521d4f2939cSRui Paulo 	},
3522d4f2939cSRui Paulo 	{ "RemovePersistentGroup", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
3523d4f2939cSRui Paulo 	  (WPADBusMethodHandler) wpas_dbus_handler_remove_persistent_group,
3524d4f2939cSRui Paulo 	  {
3525d4f2939cSRui Paulo 		  { "path", "o", ARG_IN },
3526d4f2939cSRui Paulo 		  END_ARGS
3527d4f2939cSRui Paulo 	  }
3528d4f2939cSRui Paulo 	},
3529d4f2939cSRui Paulo 	{ "RemoveAllPersistentGroups", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
3530d4f2939cSRui Paulo 	  (WPADBusMethodHandler)
3531d4f2939cSRui Paulo 	  wpas_dbus_handler_remove_all_persistent_groups,
3532d4f2939cSRui Paulo 	  {
3533d4f2939cSRui Paulo 		  END_ARGS
3534d4f2939cSRui Paulo 	  }
3535d4f2939cSRui Paulo 	},
3536d4f2939cSRui Paulo #endif /* CONFIG_P2P */
3537d4f2939cSRui Paulo 	{ "FlushBSS", WPAS_DBUS_NEW_IFACE_INTERFACE,
35385b9c547cSRui Paulo 	  (WPADBusMethodHandler) wpas_dbus_handler_flush_bss,
3539d4f2939cSRui Paulo 	  {
3540d4f2939cSRui Paulo 		  { "age", "u", ARG_IN },
3541d4f2939cSRui Paulo 		  END_ARGS
3542d4f2939cSRui Paulo 	  }
3543d4f2939cSRui Paulo 	},
3544d4f2939cSRui Paulo #ifdef CONFIG_AP
3545d4f2939cSRui Paulo 	{ "SubscribeProbeReq", WPAS_DBUS_NEW_IFACE_INTERFACE,
3546d4f2939cSRui Paulo 	  (WPADBusMethodHandler) wpas_dbus_handler_subscribe_preq,
3547d4f2939cSRui Paulo 	  {
3548d4f2939cSRui Paulo 		  END_ARGS
3549d4f2939cSRui Paulo 	  }
3550d4f2939cSRui Paulo 	},
3551d4f2939cSRui Paulo 	{ "UnsubscribeProbeReq", WPAS_DBUS_NEW_IFACE_INTERFACE,
3552d4f2939cSRui Paulo 	  (WPADBusMethodHandler) wpas_dbus_handler_unsubscribe_preq,
3553d4f2939cSRui Paulo 	  {
3554d4f2939cSRui Paulo 		  END_ARGS
3555d4f2939cSRui Paulo 	  }
3556d4f2939cSRui Paulo 	},
3557d4f2939cSRui Paulo #endif /* CONFIG_AP */
35585b9c547cSRui Paulo 	{ "EAPLogoff", WPAS_DBUS_NEW_IFACE_INTERFACE,
35595b9c547cSRui Paulo 	  (WPADBusMethodHandler) wpas_dbus_handler_eap_logoff,
35605b9c547cSRui Paulo 	  {
35615b9c547cSRui Paulo 		  END_ARGS
35625b9c547cSRui Paulo 	  }
35635b9c547cSRui Paulo 	},
35645b9c547cSRui Paulo 	{ "EAPLogon", WPAS_DBUS_NEW_IFACE_INTERFACE,
35655b9c547cSRui Paulo 	  (WPADBusMethodHandler) wpas_dbus_handler_eap_logon,
35665b9c547cSRui Paulo 	  {
35675b9c547cSRui Paulo 		  END_ARGS
35685b9c547cSRui Paulo 	  }
35695b9c547cSRui Paulo 	},
35705b9c547cSRui Paulo #ifdef CONFIG_AUTOSCAN
35715b9c547cSRui Paulo 	{ "AutoScan", WPAS_DBUS_NEW_IFACE_INTERFACE,
35725b9c547cSRui Paulo 	  (WPADBusMethodHandler) wpas_dbus_handler_autoscan,
35735b9c547cSRui Paulo 	  {
35745b9c547cSRui Paulo 		  { "arg", "s", ARG_IN },
35755b9c547cSRui Paulo 		  END_ARGS
35765b9c547cSRui Paulo 	  }
35775b9c547cSRui Paulo 	},
35785b9c547cSRui Paulo #endif /* CONFIG_AUTOSCAN */
35795b9c547cSRui Paulo #ifdef CONFIG_TDLS
35805b9c547cSRui Paulo 	{ "TDLSDiscover", WPAS_DBUS_NEW_IFACE_INTERFACE,
35815b9c547cSRui Paulo 	  (WPADBusMethodHandler) wpas_dbus_handler_tdls_discover,
35825b9c547cSRui Paulo 	  {
35835b9c547cSRui Paulo 		  { "peer_address", "s", ARG_IN },
35845b9c547cSRui Paulo 		  END_ARGS
35855b9c547cSRui Paulo 	  }
35865b9c547cSRui Paulo 	},
35875b9c547cSRui Paulo 	{ "TDLSSetup", WPAS_DBUS_NEW_IFACE_INTERFACE,
35885b9c547cSRui Paulo 	  (WPADBusMethodHandler) wpas_dbus_handler_tdls_setup,
35895b9c547cSRui Paulo 	  {
35905b9c547cSRui Paulo 		  { "peer_address", "s", ARG_IN },
35915b9c547cSRui Paulo 		  END_ARGS
35925b9c547cSRui Paulo 	  }
35935b9c547cSRui Paulo 	},
35945b9c547cSRui Paulo 	{ "TDLSStatus", WPAS_DBUS_NEW_IFACE_INTERFACE,
35955b9c547cSRui Paulo 	  (WPADBusMethodHandler) wpas_dbus_handler_tdls_status,
35965b9c547cSRui Paulo 	  {
35975b9c547cSRui Paulo 		  { "peer_address", "s", ARG_IN },
35985b9c547cSRui Paulo 		  { "status", "s", ARG_OUT },
35995b9c547cSRui Paulo 		  END_ARGS
36005b9c547cSRui Paulo 	  }
36015b9c547cSRui Paulo 	},
36025b9c547cSRui Paulo 	{ "TDLSTeardown", WPAS_DBUS_NEW_IFACE_INTERFACE,
36035b9c547cSRui Paulo 	  (WPADBusMethodHandler) wpas_dbus_handler_tdls_teardown,
36045b9c547cSRui Paulo 	  {
36055b9c547cSRui Paulo 		  { "peer_address", "s", ARG_IN },
36065b9c547cSRui Paulo 		  END_ARGS
36075b9c547cSRui Paulo 	  }
36085b9c547cSRui Paulo 	},
360985732ac8SCy Schubert 	{ "TDLSChannelSwitch", WPAS_DBUS_NEW_IFACE_INTERFACE,
361085732ac8SCy Schubert 	  (WPADBusMethodHandler) wpas_dbus_handler_tdls_channel_switch,
361185732ac8SCy Schubert 	  {
361285732ac8SCy Schubert 		  { "args", "a{sv}", ARG_IN },
361385732ac8SCy Schubert 		  END_ARGS
361485732ac8SCy Schubert 	  }
361585732ac8SCy Schubert 	},
361685732ac8SCy Schubert 	{ "TDLSCancelChannelSwitch", WPAS_DBUS_NEW_IFACE_INTERFACE,
361785732ac8SCy Schubert 	  (WPADBusMethodHandler) wpas_dbus_handler_tdls_cancel_channel_switch,
361885732ac8SCy Schubert 	  {
361985732ac8SCy Schubert 		  { "peer_address", "s", ARG_IN },
362085732ac8SCy Schubert 		  END_ARGS
362185732ac8SCy Schubert 	  }
362285732ac8SCy Schubert 	},
36235b9c547cSRui Paulo #endif /* CONFIG_TDLS */
3624780fb4a2SCy Schubert 	{ "VendorElemAdd", WPAS_DBUS_NEW_IFACE_INTERFACE,
3625780fb4a2SCy Schubert 	  (WPADBusMethodHandler) wpas_dbus_handler_vendor_elem_add,
3626780fb4a2SCy Schubert 	  {
3627780fb4a2SCy Schubert 		  { "frame_id", "i", ARG_IN },
3628780fb4a2SCy Schubert 		  { "ielems", "ay", ARG_IN },
3629780fb4a2SCy Schubert 		  END_ARGS
3630780fb4a2SCy Schubert 	  }
3631780fb4a2SCy Schubert 	},
3632780fb4a2SCy Schubert 	{ "VendorElemGet", WPAS_DBUS_NEW_IFACE_INTERFACE,
3633780fb4a2SCy Schubert 	  (WPADBusMethodHandler) wpas_dbus_handler_vendor_elem_get,
3634780fb4a2SCy Schubert 	  {
3635780fb4a2SCy Schubert 		  { "frame_id", "i", ARG_IN },
3636780fb4a2SCy Schubert 		  { "ielems", "ay", ARG_OUT },
3637780fb4a2SCy Schubert 		  END_ARGS
3638780fb4a2SCy Schubert 	  }
3639780fb4a2SCy Schubert 	},
3640780fb4a2SCy Schubert 	{ "VendorElemRem", WPAS_DBUS_NEW_IFACE_INTERFACE,
3641780fb4a2SCy Schubert 	  (WPADBusMethodHandler) wpas_dbus_handler_vendor_elem_remove,
3642780fb4a2SCy Schubert 	  {
3643780fb4a2SCy Schubert 		  { "frame_id", "i", ARG_IN },
3644780fb4a2SCy Schubert 		  { "ielems", "ay", ARG_IN },
3645780fb4a2SCy Schubert 		  END_ARGS
3646780fb4a2SCy Schubert 	  }
3647780fb4a2SCy Schubert 	},
3648780fb4a2SCy Schubert #ifndef CONFIG_NO_CONFIG_WRITE
3649780fb4a2SCy Schubert 	{ "SaveConfig", WPAS_DBUS_NEW_IFACE_INTERFACE,
3650780fb4a2SCy Schubert 	  (WPADBusMethodHandler) wpas_dbus_handler_save_config,
3651780fb4a2SCy Schubert 	  {
3652780fb4a2SCy Schubert 		  END_ARGS
3653780fb4a2SCy Schubert 	  }
3654780fb4a2SCy Schubert 	},
3655780fb4a2SCy Schubert #endif /* CONFIG_NO_CONFIG_WRITE */
365685732ac8SCy Schubert 	{ "AbortScan", WPAS_DBUS_NEW_IFACE_INTERFACE,
365785732ac8SCy Schubert 	  (WPADBusMethodHandler) wpas_dbus_handler_abort_scan,
365885732ac8SCy Schubert 	  {
365985732ac8SCy Schubert 		  END_ARGS
366085732ac8SCy Schubert 	  }
366185732ac8SCy Schubert 	},
3662*32a95656SCy Schubert #ifdef CONFIG_INTERWORKING
3663*32a95656SCy Schubert 	{ "AddCred", WPAS_DBUS_NEW_IFACE_INTERFACE,
3664*32a95656SCy Schubert 	  (WPADBusMethodHandler) wpas_dbus_handler_add_cred,
3665*32a95656SCy Schubert 	  {
3666*32a95656SCy Schubert 		  { "args", "a{sv}", ARG_IN },
3667*32a95656SCy Schubert 		  { "path", "o", ARG_OUT },
3668*32a95656SCy Schubert 		  END_ARGS
3669*32a95656SCy Schubert 	  }
3670*32a95656SCy Schubert 	},
3671*32a95656SCy Schubert 	{ "RemoveCred", WPAS_DBUS_NEW_IFACE_INTERFACE,
3672*32a95656SCy Schubert 	  (WPADBusMethodHandler) wpas_dbus_handler_remove_cred,
3673*32a95656SCy Schubert 	  {
3674*32a95656SCy Schubert 		  { "path", "o", ARG_IN },
3675*32a95656SCy Schubert 		  END_ARGS
3676*32a95656SCy Schubert 	  }
3677*32a95656SCy Schubert 	},
3678*32a95656SCy Schubert 	{ "RemoveAllCreds", WPAS_DBUS_NEW_IFACE_INTERFACE,
3679*32a95656SCy Schubert 	  (WPADBusMethodHandler) wpas_dbus_handler_remove_all_creds,
3680*32a95656SCy Schubert 	  {
3681*32a95656SCy Schubert 		  END_ARGS
3682*32a95656SCy Schubert 	  }
3683*32a95656SCy Schubert 	},
3684*32a95656SCy Schubert 	{ "InterworkingSelect", WPAS_DBUS_NEW_IFACE_INTERFACE,
3685*32a95656SCy Schubert 	  (WPADBusMethodHandler) wpas_dbus_handler_interworking_select,
3686*32a95656SCy Schubert 	  {
3687*32a95656SCy Schubert 		  END_ARGS
3688*32a95656SCy Schubert 	  }
3689*32a95656SCy Schubert 	},
3690*32a95656SCy Schubert #endif /* CONFIG_INTERWORKING */
3691d4f2939cSRui Paulo 	{ NULL, NULL, NULL, { END_ARGS } }
3692d4f2939cSRui Paulo };
3693d4f2939cSRui Paulo 
3694d4f2939cSRui Paulo static const struct wpa_dbus_property_desc wpas_dbus_interface_properties[] = {
3695d4f2939cSRui Paulo 	{ "Capabilities", WPAS_DBUS_NEW_IFACE_INTERFACE, "a{sv}",
3696d4f2939cSRui Paulo 	  wpas_dbus_getter_capabilities,
3697780fb4a2SCy Schubert 	  NULL,
3698d4f2939cSRui Paulo 	  NULL
3699d4f2939cSRui Paulo 	},
3700d4f2939cSRui Paulo 	{ "State", WPAS_DBUS_NEW_IFACE_INTERFACE, "s",
3701d4f2939cSRui Paulo 	  wpas_dbus_getter_state,
3702780fb4a2SCy Schubert 	  NULL,
3703d4f2939cSRui Paulo 	  NULL
3704d4f2939cSRui Paulo 	},
3705d4f2939cSRui Paulo 	{ "Scanning", WPAS_DBUS_NEW_IFACE_INTERFACE, "b",
3706d4f2939cSRui Paulo 	  wpas_dbus_getter_scanning,
3707780fb4a2SCy Schubert 	  NULL,
3708d4f2939cSRui Paulo 	  NULL
3709d4f2939cSRui Paulo 	},
3710d4f2939cSRui Paulo 	{ "ApScan", WPAS_DBUS_NEW_IFACE_INTERFACE, "u",
3711d4f2939cSRui Paulo 	  wpas_dbus_getter_ap_scan,
3712780fb4a2SCy Schubert 	  wpas_dbus_setter_ap_scan,
3713780fb4a2SCy Schubert 	  NULL
3714d4f2939cSRui Paulo 	},
3715d4f2939cSRui Paulo 	{ "BSSExpireAge", WPAS_DBUS_NEW_IFACE_INTERFACE, "u",
3716d4f2939cSRui Paulo 	  wpas_dbus_getter_bss_expire_age,
3717780fb4a2SCy Schubert 	  wpas_dbus_setter_bss_expire_age,
3718780fb4a2SCy Schubert 	  NULL
3719d4f2939cSRui Paulo 	},
3720d4f2939cSRui Paulo 	{ "BSSExpireCount", WPAS_DBUS_NEW_IFACE_INTERFACE, "u",
3721d4f2939cSRui Paulo 	  wpas_dbus_getter_bss_expire_count,
3722780fb4a2SCy Schubert 	  wpas_dbus_setter_bss_expire_count,
3723780fb4a2SCy Schubert 	  NULL
3724d4f2939cSRui Paulo 	},
3725d4f2939cSRui Paulo 	{ "Country", WPAS_DBUS_NEW_IFACE_INTERFACE, "s",
3726d4f2939cSRui Paulo 	  wpas_dbus_getter_country,
3727780fb4a2SCy Schubert 	  wpas_dbus_setter_country,
3728780fb4a2SCy Schubert 	  NULL
3729d4f2939cSRui Paulo 	},
3730d4f2939cSRui Paulo 	{ "Ifname", WPAS_DBUS_NEW_IFACE_INTERFACE, "s",
3731d4f2939cSRui Paulo 	  wpas_dbus_getter_ifname,
3732780fb4a2SCy Schubert 	  NULL,
3733d4f2939cSRui Paulo 	  NULL
3734d4f2939cSRui Paulo 	},
3735d4f2939cSRui Paulo 	{ "Driver", WPAS_DBUS_NEW_IFACE_INTERFACE, "s",
3736d4f2939cSRui Paulo 	  wpas_dbus_getter_driver,
3737780fb4a2SCy Schubert 	  NULL,
3738d4f2939cSRui Paulo 	  NULL
3739d4f2939cSRui Paulo 	},
3740d4f2939cSRui Paulo 	{ "BridgeIfname", WPAS_DBUS_NEW_IFACE_INTERFACE, "s",
3741d4f2939cSRui Paulo 	  wpas_dbus_getter_bridge_ifname,
3742c1d255d3SCy Schubert 	  wpas_dbus_setter_bridge_ifname,
3743780fb4a2SCy Schubert 	  NULL
3744780fb4a2SCy Schubert 	},
3745780fb4a2SCy Schubert 	{ "ConfigFile", WPAS_DBUS_NEW_IFACE_INTERFACE, "s",
3746780fb4a2SCy Schubert 	  wpas_dbus_getter_config_file,
3747780fb4a2SCy Schubert 	  NULL,
3748d4f2939cSRui Paulo 	  NULL
3749d4f2939cSRui Paulo 	},
3750d4f2939cSRui Paulo 	{ "CurrentBSS", WPAS_DBUS_NEW_IFACE_INTERFACE, "o",
3751d4f2939cSRui Paulo 	  wpas_dbus_getter_current_bss,
3752780fb4a2SCy Schubert 	  NULL,
3753d4f2939cSRui Paulo 	  NULL
3754d4f2939cSRui Paulo 	},
3755d4f2939cSRui Paulo 	{ "CurrentNetwork", WPAS_DBUS_NEW_IFACE_INTERFACE, "o",
3756d4f2939cSRui Paulo 	  wpas_dbus_getter_current_network,
3757780fb4a2SCy Schubert 	  NULL,
3758d4f2939cSRui Paulo 	  NULL
3759d4f2939cSRui Paulo 	},
3760d4f2939cSRui Paulo 	{ "CurrentAuthMode", WPAS_DBUS_NEW_IFACE_INTERFACE, "s",
3761d4f2939cSRui Paulo 	  wpas_dbus_getter_current_auth_mode,
3762780fb4a2SCy Schubert 	  NULL,
3763d4f2939cSRui Paulo 	  NULL
3764d4f2939cSRui Paulo 	},
3765d4f2939cSRui Paulo 	{ "Blobs", WPAS_DBUS_NEW_IFACE_INTERFACE, "a{say}",
3766d4f2939cSRui Paulo 	  wpas_dbus_getter_blobs,
3767780fb4a2SCy Schubert 	  NULL,
3768d4f2939cSRui Paulo 	  NULL
3769d4f2939cSRui Paulo 	},
3770d4f2939cSRui Paulo 	{ "BSSs", WPAS_DBUS_NEW_IFACE_INTERFACE, "ao",
3771d4f2939cSRui Paulo 	  wpas_dbus_getter_bsss,
3772780fb4a2SCy Schubert 	  NULL,
3773d4f2939cSRui Paulo 	  NULL
3774d4f2939cSRui Paulo 	},
3775d4f2939cSRui Paulo 	{ "Networks", WPAS_DBUS_NEW_IFACE_INTERFACE, "ao",
3776d4f2939cSRui Paulo 	  wpas_dbus_getter_networks,
3777780fb4a2SCy Schubert 	  NULL,
3778d4f2939cSRui Paulo 	  NULL
3779d4f2939cSRui Paulo 	},
3780d4f2939cSRui Paulo 	{ "FastReauth", WPAS_DBUS_NEW_IFACE_INTERFACE, "b",
3781d4f2939cSRui Paulo 	  wpas_dbus_getter_fast_reauth,
3782780fb4a2SCy Schubert 	  wpas_dbus_setter_fast_reauth,
3783780fb4a2SCy Schubert 	  NULL
3784d4f2939cSRui Paulo 	},
3785d4f2939cSRui Paulo 	{ "ScanInterval", WPAS_DBUS_NEW_IFACE_INTERFACE, "i",
3786d4f2939cSRui Paulo 	  wpas_dbus_getter_scan_interval,
3787780fb4a2SCy Schubert 	  wpas_dbus_setter_scan_interval,
3788780fb4a2SCy Schubert 	  NULL
3789d4f2939cSRui Paulo 	},
37905b9c547cSRui Paulo 	{ "PKCS11EnginePath", WPAS_DBUS_NEW_IFACE_INTERFACE, "s",
37915b9c547cSRui Paulo 	  wpas_dbus_getter_pkcs11_engine_path,
3792780fb4a2SCy Schubert 	  NULL,
37935b9c547cSRui Paulo 	  NULL
37945b9c547cSRui Paulo 	},
37955b9c547cSRui Paulo 	{ "PKCS11ModulePath", WPAS_DBUS_NEW_IFACE_INTERFACE, "s",
37965b9c547cSRui Paulo 	  wpas_dbus_getter_pkcs11_module_path,
3797780fb4a2SCy Schubert 	  NULL,
37985b9c547cSRui Paulo 	  NULL
37995b9c547cSRui Paulo 	},
3800d4f2939cSRui Paulo #ifdef CONFIG_WPS
3801d4f2939cSRui Paulo 	{ "ProcessCredentials", WPAS_DBUS_NEW_IFACE_WPS, "b",
3802d4f2939cSRui Paulo 	  wpas_dbus_getter_process_credentials,
3803780fb4a2SCy Schubert 	  wpas_dbus_setter_process_credentials,
3804780fb4a2SCy Schubert 	  NULL
3805d4f2939cSRui Paulo 	},
38065b9c547cSRui Paulo 	{ "ConfigMethods", WPAS_DBUS_NEW_IFACE_WPS, "s",
38075b9c547cSRui Paulo 	  wpas_dbus_getter_config_methods,
3808780fb4a2SCy Schubert 	  wpas_dbus_setter_config_methods,
3809780fb4a2SCy Schubert 	  NULL
38105b9c547cSRui Paulo 	},
381185732ac8SCy Schubert 	{
381285732ac8SCy Schubert 	  "DeviceName", WPAS_DBUS_NEW_IFACE_WPS, "s",
381385732ac8SCy Schubert 	  wpas_dbus_getter_wps_device_name,
381485732ac8SCy Schubert 	  wpas_dbus_setter_wps_device_name,
381585732ac8SCy Schubert 	  NULL
381685732ac8SCy Schubert 	},
381785732ac8SCy Schubert 	{
381885732ac8SCy Schubert 	  "Manufacturer", WPAS_DBUS_NEW_IFACE_WPS, "s",
381985732ac8SCy Schubert 	  wpas_dbus_getter_wps_manufacturer,
382085732ac8SCy Schubert 	  wpas_dbus_setter_wps_manufacturer,
382185732ac8SCy Schubert 	  NULL
382285732ac8SCy Schubert 	},
382385732ac8SCy Schubert 	{
382485732ac8SCy Schubert 	  "ModelName", WPAS_DBUS_NEW_IFACE_WPS, "s",
382585732ac8SCy Schubert 	  wpas_dbus_getter_wps_device_model_name,
382685732ac8SCy Schubert 	  wpas_dbus_setter_wps_device_model_name,
382785732ac8SCy Schubert 	  NULL
382885732ac8SCy Schubert 	},
382985732ac8SCy Schubert 	{
383085732ac8SCy Schubert 	  "ModelNumber", WPAS_DBUS_NEW_IFACE_WPS, "s",
383185732ac8SCy Schubert 	  wpas_dbus_getter_wps_device_model_number,
383285732ac8SCy Schubert 	  wpas_dbus_setter_wps_device_model_number,
383385732ac8SCy Schubert 	  NULL
383485732ac8SCy Schubert 	},
383585732ac8SCy Schubert 	{
383685732ac8SCy Schubert 	  "SerialNumber", WPAS_DBUS_NEW_IFACE_WPS, "s",
383785732ac8SCy Schubert 	  wpas_dbus_getter_wps_device_serial_number,
383885732ac8SCy Schubert 	  wpas_dbus_setter_wps_device_serial_number,
383985732ac8SCy Schubert 	  NULL
384085732ac8SCy Schubert 	},
384185732ac8SCy Schubert 	{
384285732ac8SCy Schubert 	  "DeviceType", WPAS_DBUS_NEW_IFACE_WPS, "ay",
384385732ac8SCy Schubert 	  wpas_dbus_getter_wps_device_device_type,
384485732ac8SCy Schubert 	  wpas_dbus_setter_wps_device_device_type,
384585732ac8SCy Schubert 	  NULL
384685732ac8SCy Schubert 	},
3847d4f2939cSRui Paulo #endif /* CONFIG_WPS */
3848d4f2939cSRui Paulo #ifdef CONFIG_P2P
3849d4f2939cSRui Paulo 	{ "P2PDeviceConfig", WPAS_DBUS_NEW_IFACE_P2PDEVICE, "a{sv}",
3850d4f2939cSRui Paulo 	  wpas_dbus_getter_p2p_device_config,
3851780fb4a2SCy Schubert 	  wpas_dbus_setter_p2p_device_config,
3852780fb4a2SCy Schubert 	  NULL
3853d4f2939cSRui Paulo 	},
3854d4f2939cSRui Paulo 	{ "Peers", WPAS_DBUS_NEW_IFACE_P2PDEVICE, "ao",
3855d4f2939cSRui Paulo 	  wpas_dbus_getter_p2p_peers,
3856780fb4a2SCy Schubert 	  NULL,
3857d4f2939cSRui Paulo 	  NULL
3858d4f2939cSRui Paulo 	},
3859d4f2939cSRui Paulo 	{ "Role", WPAS_DBUS_NEW_IFACE_P2PDEVICE, "s",
3860d4f2939cSRui Paulo 	  wpas_dbus_getter_p2p_role,
3861780fb4a2SCy Schubert 	  NULL,
3862d4f2939cSRui Paulo 	  NULL
3863d4f2939cSRui Paulo 	},
3864d4f2939cSRui Paulo 	{ "Group", WPAS_DBUS_NEW_IFACE_P2PDEVICE, "o",
3865d4f2939cSRui Paulo 	  wpas_dbus_getter_p2p_group,
3866780fb4a2SCy Schubert 	  NULL,
3867d4f2939cSRui Paulo 	  NULL
3868d4f2939cSRui Paulo 	},
3869d4f2939cSRui Paulo 	{ "PeerGO", WPAS_DBUS_NEW_IFACE_P2PDEVICE, "o",
3870d4f2939cSRui Paulo 	  wpas_dbus_getter_p2p_peergo,
3871780fb4a2SCy Schubert 	  NULL,
3872d4f2939cSRui Paulo 	  NULL
3873d4f2939cSRui Paulo 	},
3874d4f2939cSRui Paulo 	{ "PersistentGroups", WPAS_DBUS_NEW_IFACE_P2PDEVICE, "ao",
3875d4f2939cSRui Paulo 	  wpas_dbus_getter_persistent_groups,
3876780fb4a2SCy Schubert 	  NULL,
3877d4f2939cSRui Paulo 	  NULL
3878d4f2939cSRui Paulo 	},
3879d4f2939cSRui Paulo #endif /* CONFIG_P2P */
3880d4f2939cSRui Paulo 	{ "DisconnectReason", WPAS_DBUS_NEW_IFACE_INTERFACE, "i",
3881d4f2939cSRui Paulo 	  wpas_dbus_getter_disconnect_reason,
3882780fb4a2SCy Schubert 	  NULL,
3883d4f2939cSRui Paulo 	  NULL
3884d4f2939cSRui Paulo 	},
38854bc52338SCy Schubert 	{ "AuthStatusCode", WPAS_DBUS_NEW_IFACE_INTERFACE, "i",
38864bc52338SCy Schubert 	  wpas_dbus_getter_auth_status_code,
38874bc52338SCy Schubert 	  NULL,
38884bc52338SCy Schubert 	  NULL
38894bc52338SCy Schubert 	},
3890780fb4a2SCy Schubert 	{ "AssocStatusCode", WPAS_DBUS_NEW_IFACE_INTERFACE, "i",
3891780fb4a2SCy Schubert 	  wpas_dbus_getter_assoc_status_code,
3892780fb4a2SCy Schubert 	  NULL,
3893780fb4a2SCy Schubert 	  NULL
3894780fb4a2SCy Schubert 	},
3895c1d255d3SCy Schubert 	{
3896c1d255d3SCy Schubert 	  "RoamTime", WPAS_DBUS_NEW_IFACE_INTERFACE, "u",
3897c1d255d3SCy Schubert 	  wpas_dbus_getter_roam_time,
3898c1d255d3SCy Schubert 	  NULL,
3899c1d255d3SCy Schubert 	  NULL
3900c1d255d3SCy Schubert 	},
3901c1d255d3SCy Schubert 	{
3902c1d255d3SCy Schubert 	  "RoamComplete", WPAS_DBUS_NEW_IFACE_INTERFACE, "b",
3903c1d255d3SCy Schubert 	  wpas_dbus_getter_roam_complete,
3904c1d255d3SCy Schubert 	  NULL,
3905c1d255d3SCy Schubert 	  NULL
3906c1d255d3SCy Schubert 	},
3907c1d255d3SCy Schubert 	{
3908c1d255d3SCy Schubert 	  "SessionLength", WPAS_DBUS_NEW_IFACE_INTERFACE, "u",
3909c1d255d3SCy Schubert 	  wpas_dbus_getter_session_length,
3910c1d255d3SCy Schubert 	  NULL,
3911c1d255d3SCy Schubert 	  NULL
3912c1d255d3SCy Schubert 	},
3913c1d255d3SCy Schubert 	{
3914c1d255d3SCy Schubert 	  "BSSTMStatus", WPAS_DBUS_NEW_IFACE_INTERFACE, "u",
3915c1d255d3SCy Schubert 	  wpas_dbus_getter_bss_tm_status,
3916c1d255d3SCy Schubert 	  NULL,
3917c1d255d3SCy Schubert 	  NULL
3918c1d255d3SCy Schubert 	},
391985732ac8SCy Schubert #ifdef CONFIG_MESH
392085732ac8SCy Schubert 	{ "MeshPeers", WPAS_DBUS_NEW_IFACE_MESH, "aay",
392185732ac8SCy Schubert 	  wpas_dbus_getter_mesh_peers,
392285732ac8SCy Schubert 	  NULL,
392385732ac8SCy Schubert 	  NULL
392485732ac8SCy Schubert 	},
392585732ac8SCy Schubert 	{ "MeshGroup", WPAS_DBUS_NEW_IFACE_MESH, "ay",
392685732ac8SCy Schubert 	  wpas_dbus_getter_mesh_group,
392785732ac8SCy Schubert 	  NULL,
392885732ac8SCy Schubert 	  NULL
392985732ac8SCy Schubert 	},
393085732ac8SCy Schubert #endif /* CONFIG_MESH */
39314bc52338SCy Schubert 	{ "Stations", WPAS_DBUS_NEW_IFACE_INTERFACE, "ao",
39324bc52338SCy Schubert 	  wpas_dbus_getter_stas,
39334bc52338SCy Schubert 	  NULL,
39344bc52338SCy Schubert 	  NULL
39354bc52338SCy Schubert 	},
3936c1d255d3SCy Schubert 	{ "MACAddressRandomizationMask", WPAS_DBUS_NEW_IFACE_INTERFACE,
3937c1d255d3SCy Schubert 	  "a{say}",
3938c1d255d3SCy Schubert 	  wpas_dbus_getter_mac_address_randomization_mask,
3939c1d255d3SCy Schubert 	  wpas_dbus_setter_mac_address_randomization_mask,
3940c1d255d3SCy Schubert 	  NULL
3941c1d255d3SCy Schubert 	},
3942780fb4a2SCy Schubert 	{ NULL, NULL, NULL, NULL, NULL, NULL }
3943d4f2939cSRui Paulo };
3944d4f2939cSRui Paulo 
3945d4f2939cSRui Paulo static const struct wpa_dbus_signal_desc wpas_dbus_interface_signals[] = {
3946d4f2939cSRui Paulo 	{ "ScanDone", WPAS_DBUS_NEW_IFACE_INTERFACE,
3947d4f2939cSRui Paulo 	  {
3948d4f2939cSRui Paulo 		  { "success", "b", ARG_OUT },
3949d4f2939cSRui Paulo 		  END_ARGS
3950d4f2939cSRui Paulo 	  }
3951d4f2939cSRui Paulo 	},
3952d4f2939cSRui Paulo 	{ "BSSAdded", WPAS_DBUS_NEW_IFACE_INTERFACE,
3953d4f2939cSRui Paulo 	  {
3954d4f2939cSRui Paulo 		  { "path", "o", ARG_OUT },
3955d4f2939cSRui Paulo 		  { "properties", "a{sv}", ARG_OUT },
3956d4f2939cSRui Paulo 		  END_ARGS
3957d4f2939cSRui Paulo 	  }
3958d4f2939cSRui Paulo 	},
3959d4f2939cSRui Paulo 	{ "BSSRemoved", WPAS_DBUS_NEW_IFACE_INTERFACE,
3960d4f2939cSRui Paulo 	  {
3961d4f2939cSRui Paulo 		  { "path", "o", ARG_OUT },
3962d4f2939cSRui Paulo 		  END_ARGS
3963d4f2939cSRui Paulo 	  }
3964d4f2939cSRui Paulo 	},
3965d4f2939cSRui Paulo 	{ "BlobAdded", WPAS_DBUS_NEW_IFACE_INTERFACE,
3966d4f2939cSRui Paulo 	  {
3967d4f2939cSRui Paulo 		  { "name", "s", ARG_OUT },
3968d4f2939cSRui Paulo 		  END_ARGS
3969d4f2939cSRui Paulo 	  }
3970d4f2939cSRui Paulo 	},
3971d4f2939cSRui Paulo 	{ "BlobRemoved", WPAS_DBUS_NEW_IFACE_INTERFACE,
3972d4f2939cSRui Paulo 	  {
3973d4f2939cSRui Paulo 		  { "name", "s", ARG_OUT },
3974d4f2939cSRui Paulo 		  END_ARGS
3975d4f2939cSRui Paulo 	  }
3976d4f2939cSRui Paulo 	},
3977d4f2939cSRui Paulo 	{ "NetworkAdded", WPAS_DBUS_NEW_IFACE_INTERFACE,
3978d4f2939cSRui Paulo 	  {
3979d4f2939cSRui Paulo 		  { "path", "o", ARG_OUT },
3980d4f2939cSRui Paulo 		  { "properties", "a{sv}", ARG_OUT },
3981d4f2939cSRui Paulo 		  END_ARGS
3982d4f2939cSRui Paulo 	  }
3983d4f2939cSRui Paulo 	},
3984d4f2939cSRui Paulo 	{ "NetworkRemoved", WPAS_DBUS_NEW_IFACE_INTERFACE,
3985d4f2939cSRui Paulo 	  {
3986d4f2939cSRui Paulo 		  { "path", "o", ARG_OUT },
3987d4f2939cSRui Paulo 		  END_ARGS
3988d4f2939cSRui Paulo 	  }
3989d4f2939cSRui Paulo 	},
3990d4f2939cSRui Paulo 	{ "NetworkSelected", WPAS_DBUS_NEW_IFACE_INTERFACE,
3991d4f2939cSRui Paulo 	  {
3992d4f2939cSRui Paulo 		  { "path", "o", ARG_OUT },
3993d4f2939cSRui Paulo 		  END_ARGS
3994d4f2939cSRui Paulo 	  }
3995d4f2939cSRui Paulo 	},
3996d4f2939cSRui Paulo 	/* Deprecated: use org.freedesktop.DBus.Properties.PropertiesChanged */
3997d4f2939cSRui Paulo 	{ "PropertiesChanged", WPAS_DBUS_NEW_IFACE_INTERFACE,
3998d4f2939cSRui Paulo 	  {
3999d4f2939cSRui Paulo 		  { "properties", "a{sv}", ARG_OUT },
4000d4f2939cSRui Paulo 		  END_ARGS
4001d4f2939cSRui Paulo 	  }
4002d4f2939cSRui Paulo 	},
4003d4f2939cSRui Paulo #ifdef CONFIG_WPS
4004d4f2939cSRui Paulo 	{ "Event", WPAS_DBUS_NEW_IFACE_WPS,
4005d4f2939cSRui Paulo 	  {
4006d4f2939cSRui Paulo 		  { "name", "s", ARG_OUT },
4007d4f2939cSRui Paulo 		  { "args", "a{sv}", ARG_OUT },
4008d4f2939cSRui Paulo 		  END_ARGS
4009d4f2939cSRui Paulo 	  }
4010d4f2939cSRui Paulo 	},
4011d4f2939cSRui Paulo 	{ "Credentials", WPAS_DBUS_NEW_IFACE_WPS,
4012d4f2939cSRui Paulo 	  {
4013d4f2939cSRui Paulo 		  { "credentials", "a{sv}", ARG_OUT },
4014d4f2939cSRui Paulo 		  END_ARGS
4015d4f2939cSRui Paulo 	  }
4016d4f2939cSRui Paulo 	},
4017d4f2939cSRui Paulo 	/* Deprecated: use org.freedesktop.DBus.Properties.PropertiesChanged */
4018d4f2939cSRui Paulo 	{ "PropertiesChanged", WPAS_DBUS_NEW_IFACE_WPS,
4019d4f2939cSRui Paulo 	  {
4020d4f2939cSRui Paulo 		  { "properties", "a{sv}", ARG_OUT },
4021d4f2939cSRui Paulo 		  END_ARGS
4022d4f2939cSRui Paulo 	  }
4023d4f2939cSRui Paulo 	},
4024d4f2939cSRui Paulo #endif /* CONFIG_WPS */
4025d4f2939cSRui Paulo #ifdef CONFIG_P2P
4026d4f2939cSRui Paulo 	{ "DeviceFound", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
4027d4f2939cSRui Paulo 	  {
4028d4f2939cSRui Paulo 		  { "path", "o", ARG_OUT },
4029d4f2939cSRui Paulo 		  END_ARGS
4030d4f2939cSRui Paulo 	  }
4031d4f2939cSRui Paulo 	},
4032780fb4a2SCy Schubert 	{ "DeviceFoundProperties", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
4033780fb4a2SCy Schubert 	  {
4034780fb4a2SCy Schubert 		  { "path", "o", ARG_OUT },
4035780fb4a2SCy Schubert 		  { "properties", "a{sv}", ARG_OUT },
4036780fb4a2SCy Schubert 		  END_ARGS
4037780fb4a2SCy Schubert 	  }
4038780fb4a2SCy Schubert 	},
4039d4f2939cSRui Paulo 	{ "DeviceLost", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
4040d4f2939cSRui Paulo 	  {
4041d4f2939cSRui Paulo 		  { "path", "o", ARG_OUT },
4042d4f2939cSRui Paulo 		  END_ARGS
4043d4f2939cSRui Paulo 	  }
4044d4f2939cSRui Paulo 	},
4045325151a3SRui Paulo 	{ "FindStopped", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
4046325151a3SRui Paulo 	  {
4047325151a3SRui Paulo 		  END_ARGS
4048325151a3SRui Paulo 	  }
4049325151a3SRui Paulo 	},
4050d4f2939cSRui Paulo 	{ "ProvisionDiscoveryRequestDisplayPin", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
4051d4f2939cSRui Paulo 	  {
4052d4f2939cSRui Paulo 		  { "peer_object", "o", ARG_OUT },
4053d4f2939cSRui Paulo 		  { "pin", "s", ARG_OUT },
4054d4f2939cSRui Paulo 		  END_ARGS
4055d4f2939cSRui Paulo 	  }
4056d4f2939cSRui Paulo 	},
4057d4f2939cSRui Paulo 	{ "ProvisionDiscoveryResponseDisplayPin", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
4058d4f2939cSRui Paulo 	  {
4059d4f2939cSRui Paulo 		  { "peer_object", "o", ARG_OUT },
4060d4f2939cSRui Paulo 		  { "pin", "s", ARG_OUT },
4061d4f2939cSRui Paulo 		  END_ARGS
4062d4f2939cSRui Paulo 	  }
4063d4f2939cSRui Paulo 	},
4064d4f2939cSRui Paulo 	{ "ProvisionDiscoveryRequestEnterPin", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
4065d4f2939cSRui Paulo 	  {
4066d4f2939cSRui Paulo 		  { "peer_object", "o", ARG_OUT },
4067d4f2939cSRui Paulo 		  END_ARGS
4068d4f2939cSRui Paulo 	  }
4069d4f2939cSRui Paulo 	},
4070d4f2939cSRui Paulo 	{ "ProvisionDiscoveryResponseEnterPin", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
4071d4f2939cSRui Paulo 	  {
4072d4f2939cSRui Paulo 		  { "peer_object", "o", ARG_OUT },
4073d4f2939cSRui Paulo 		  END_ARGS
4074d4f2939cSRui Paulo 	  }
4075d4f2939cSRui Paulo 	},
4076d4f2939cSRui Paulo 	{ "ProvisionDiscoveryPBCRequest", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
4077d4f2939cSRui Paulo 	  {
4078d4f2939cSRui Paulo 		  { "peer_object", "o", ARG_OUT },
4079d4f2939cSRui Paulo 		  END_ARGS
4080d4f2939cSRui Paulo 	  }
4081d4f2939cSRui Paulo 	},
4082d4f2939cSRui Paulo 	{ "ProvisionDiscoveryPBCResponse", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
4083d4f2939cSRui Paulo 	  {
4084d4f2939cSRui Paulo 		  { "peer_object", "o", ARG_OUT },
4085d4f2939cSRui Paulo 		  END_ARGS
4086d4f2939cSRui Paulo 	  }
4087d4f2939cSRui Paulo 	},
4088d4f2939cSRui Paulo 	{ "ProvisionDiscoveryFailure", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
4089d4f2939cSRui Paulo 	  {
4090d4f2939cSRui Paulo 		  { "peer_object", "o", ARG_OUT },
4091d4f2939cSRui Paulo 		  { "status", "i", ARG_OUT },
4092d4f2939cSRui Paulo 		  END_ARGS
4093d4f2939cSRui Paulo 	  }
4094d4f2939cSRui Paulo 	},
4095d4f2939cSRui Paulo 	{ "GroupStarted", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
4096d4f2939cSRui Paulo 	  {
4097d4f2939cSRui Paulo 		  { "properties", "a{sv}", ARG_OUT },
4098d4f2939cSRui Paulo 		  END_ARGS
4099d4f2939cSRui Paulo 	  }
4100d4f2939cSRui Paulo 	},
4101325151a3SRui Paulo 	{ "GroupFormationFailure", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
4102325151a3SRui Paulo 	  {
4103325151a3SRui Paulo 		  { "reason", "s", ARG_OUT },
4104325151a3SRui Paulo 		  END_ARGS
4105325151a3SRui Paulo 	  }
4106325151a3SRui Paulo 	},
4107d4f2939cSRui Paulo 	{ "GONegotiationSuccess", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
4108d4f2939cSRui Paulo 	  {
41095b9c547cSRui Paulo 		  { "properties", "a{sv}", ARG_OUT },
4110d4f2939cSRui Paulo 		  END_ARGS
4111d4f2939cSRui Paulo 	  }
4112d4f2939cSRui Paulo 	},
4113d4f2939cSRui Paulo 	{ "GONegotiationFailure", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
4114d4f2939cSRui Paulo 	  {
41155b9c547cSRui Paulo 		  { "properties", "a{sv}", ARG_OUT },
4116d4f2939cSRui Paulo 		  END_ARGS
4117d4f2939cSRui Paulo 	  }
4118d4f2939cSRui Paulo 	},
4119d4f2939cSRui Paulo 	{ "GONegotiationRequest", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
4120d4f2939cSRui Paulo 	  {
4121d4f2939cSRui Paulo 		  { "path", "o", ARG_OUT },
4122325151a3SRui Paulo 		  { "dev_passwd_id", "q", ARG_OUT },
4123325151a3SRui Paulo 		  { "device_go_intent", "y", ARG_OUT },
4124d4f2939cSRui Paulo 		  END_ARGS
4125d4f2939cSRui Paulo 	  }
4126d4f2939cSRui Paulo 	},
4127d4f2939cSRui Paulo 	{ "InvitationResult", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
4128d4f2939cSRui Paulo 	  {
4129d4f2939cSRui Paulo 		  { "invite_result", "a{sv}", ARG_OUT },
4130d4f2939cSRui Paulo 		  END_ARGS
4131d4f2939cSRui Paulo 	  }
4132d4f2939cSRui Paulo 	},
4133d4f2939cSRui Paulo 	{ "GroupFinished", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
4134d4f2939cSRui Paulo 	  {
41355b9c547cSRui Paulo 		  { "properties", "a{sv}", ARG_OUT },
4136d4f2939cSRui Paulo 		  END_ARGS
4137d4f2939cSRui Paulo 	  }
4138d4f2939cSRui Paulo 	},
4139d4f2939cSRui Paulo 	{ "ServiceDiscoveryRequest", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
4140d4f2939cSRui Paulo 	  {
4141d4f2939cSRui Paulo 		  { "sd_request", "a{sv}", ARG_OUT },
4142d4f2939cSRui Paulo 		  END_ARGS
4143d4f2939cSRui Paulo 	  }
4144d4f2939cSRui Paulo 	},
4145d4f2939cSRui Paulo 	{ "ServiceDiscoveryResponse", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
4146d4f2939cSRui Paulo 	  {
4147d4f2939cSRui Paulo 		  { "sd_response", "a{sv}", ARG_OUT },
4148d4f2939cSRui Paulo 		  END_ARGS
4149d4f2939cSRui Paulo 	  }
4150d4f2939cSRui Paulo 	},
4151d4f2939cSRui Paulo 	{ "PersistentGroupAdded", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
4152d4f2939cSRui Paulo 	  {
4153d4f2939cSRui Paulo 		  { "path", "o", ARG_OUT },
4154d4f2939cSRui Paulo 		  { "properties", "a{sv}", ARG_OUT },
4155d4f2939cSRui Paulo 		  END_ARGS
4156d4f2939cSRui Paulo 	  }
4157d4f2939cSRui Paulo 	},
4158d4f2939cSRui Paulo 	{ "PersistentGroupRemoved", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
4159d4f2939cSRui Paulo 	  {
4160d4f2939cSRui Paulo 		  { "path", "o", ARG_OUT },
4161d4f2939cSRui Paulo 		  END_ARGS
4162d4f2939cSRui Paulo 	  }
4163d4f2939cSRui Paulo 	},
4164d4f2939cSRui Paulo 	{ "WpsFailed", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
4165d4f2939cSRui Paulo 	  {
4166d4f2939cSRui Paulo 		  { "name", "s", ARG_OUT },
4167d4f2939cSRui Paulo 		  { "args", "a{sv}", ARG_OUT },
4168d4f2939cSRui Paulo 		  END_ARGS
4169d4f2939cSRui Paulo 	  }
4170d4f2939cSRui Paulo 	},
4171325151a3SRui Paulo 	{ "InvitationReceived", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
4172325151a3SRui Paulo 	  {
4173325151a3SRui Paulo 		  { "properties", "a{sv}", ARG_OUT },
4174325151a3SRui Paulo 		  END_ARGS
4175325151a3SRui Paulo 	  }
4176325151a3SRui Paulo 	},
4177d4f2939cSRui Paulo #endif /* CONFIG_P2P */
4178d4f2939cSRui Paulo #ifdef CONFIG_AP
4179d4f2939cSRui Paulo 	{ "ProbeRequest", WPAS_DBUS_NEW_IFACE_INTERFACE,
4180d4f2939cSRui Paulo 	  {
4181d4f2939cSRui Paulo 		  { "args", "a{sv}", ARG_OUT },
4182d4f2939cSRui Paulo 		  END_ARGS
4183d4f2939cSRui Paulo 	  }
4184d4f2939cSRui Paulo 	},
4185d4f2939cSRui Paulo #endif /* CONFIG_AP */
4186d4f2939cSRui Paulo 	{ "Certification", WPAS_DBUS_NEW_IFACE_INTERFACE,
4187d4f2939cSRui Paulo 	  {
4188d4f2939cSRui Paulo 		  { "certification", "a{sv}", ARG_OUT },
4189d4f2939cSRui Paulo 		  END_ARGS
4190d4f2939cSRui Paulo 	  }
4191d4f2939cSRui Paulo 	},
4192d4f2939cSRui Paulo 	{ "EAP", WPAS_DBUS_NEW_IFACE_INTERFACE,
4193d4f2939cSRui Paulo 	  {
4194d4f2939cSRui Paulo 		  { "status", "s", ARG_OUT },
4195d4f2939cSRui Paulo 		  { "parameter", "s", ARG_OUT },
4196d4f2939cSRui Paulo 		  END_ARGS
4197d4f2939cSRui Paulo 	  }
4198d4f2939cSRui Paulo 	},
41995b9c547cSRui Paulo 	{ "StaAuthorized", WPAS_DBUS_NEW_IFACE_INTERFACE,
42005b9c547cSRui Paulo 	  {
42015b9c547cSRui Paulo 		  { "name", "s", ARG_OUT },
42025b9c547cSRui Paulo 		  END_ARGS
42035b9c547cSRui Paulo 	  }
42045b9c547cSRui Paulo 	},
42055b9c547cSRui Paulo 	{ "StaDeauthorized", WPAS_DBUS_NEW_IFACE_INTERFACE,
42065b9c547cSRui Paulo 	  {
42075b9c547cSRui Paulo 		  { "name", "s", ARG_OUT },
42085b9c547cSRui Paulo 		  END_ARGS
42095b9c547cSRui Paulo 	  }
42105b9c547cSRui Paulo 	},
42114bc52338SCy Schubert 	{ "StationAdded", WPAS_DBUS_NEW_IFACE_INTERFACE,
42124bc52338SCy Schubert 	  {
42134bc52338SCy Schubert 		  { "path", "o", ARG_OUT },
42144bc52338SCy Schubert 		  { "properties", "a{sv}", ARG_OUT },
42154bc52338SCy Schubert 		  END_ARGS
42164bc52338SCy Schubert 	  }
42174bc52338SCy Schubert 	},
42184bc52338SCy Schubert 	{ "StationRemoved", WPAS_DBUS_NEW_IFACE_INTERFACE,
42194bc52338SCy Schubert 	  {
42204bc52338SCy Schubert 		  { "path", "o", ARG_OUT },
42214bc52338SCy Schubert 		  END_ARGS
42224bc52338SCy Schubert 	  }
42234bc52338SCy Schubert 	},
42245b9c547cSRui Paulo 	{ "NetworkRequest", WPAS_DBUS_NEW_IFACE_INTERFACE,
42255b9c547cSRui Paulo 	  {
42265b9c547cSRui Paulo 		  { "path", "o", ARG_OUT },
42275b9c547cSRui Paulo 		  { "field", "s", ARG_OUT },
42285b9c547cSRui Paulo 		  { "text", "s", ARG_OUT },
42295b9c547cSRui Paulo 		  END_ARGS
42305b9c547cSRui Paulo 	  }
42315b9c547cSRui Paulo 	},
423285732ac8SCy Schubert #ifdef CONFIG_MESH
423385732ac8SCy Schubert 	{ "MeshGroupStarted", WPAS_DBUS_NEW_IFACE_MESH,
423485732ac8SCy Schubert 	  {
423585732ac8SCy Schubert 		  { "args", "a{sv}", ARG_OUT },
423685732ac8SCy Schubert 		  END_ARGS
423785732ac8SCy Schubert 	  }
423885732ac8SCy Schubert 	},
423985732ac8SCy Schubert 	{ "MeshGroupRemoved", WPAS_DBUS_NEW_IFACE_MESH,
424085732ac8SCy Schubert 	  {
424185732ac8SCy Schubert 		  { "args", "a{sv}", ARG_OUT },
424285732ac8SCy Schubert 		  END_ARGS
424385732ac8SCy Schubert 	  }
424485732ac8SCy Schubert 	},
424585732ac8SCy Schubert 	{ "MeshPeerConnected", WPAS_DBUS_NEW_IFACE_MESH,
424685732ac8SCy Schubert 	  {
424785732ac8SCy Schubert 		  { "args", "a{sv}", ARG_OUT },
424885732ac8SCy Schubert 		  END_ARGS
424985732ac8SCy Schubert 	  }
425085732ac8SCy Schubert 	},
425185732ac8SCy Schubert 	{ "MeshPeerDisconnected", WPAS_DBUS_NEW_IFACE_MESH,
425285732ac8SCy Schubert 	  {
425385732ac8SCy Schubert 		  { "args", "a{sv}", ARG_OUT },
425485732ac8SCy Schubert 		  END_ARGS
425585732ac8SCy Schubert 	  }
425685732ac8SCy Schubert 	},
425785732ac8SCy Schubert #endif /* CONFIG_MESH */
4258*32a95656SCy Schubert #ifdef CONFIG_INTERWORKING
4259*32a95656SCy Schubert 	{ "InterworkingAPAdded", WPAS_DBUS_NEW_IFACE_INTERFACE,
4260*32a95656SCy Schubert 	  {
4261*32a95656SCy Schubert 		  { "bss", "o", ARG_OUT },
4262*32a95656SCy Schubert 		  { "cred", "o", ARG_OUT },
4263*32a95656SCy Schubert 		  { "properties", "a{sv}", ARG_OUT },
4264*32a95656SCy Schubert 		  END_ARGS
4265*32a95656SCy Schubert 	  }
4266*32a95656SCy Schubert 	},
4267*32a95656SCy Schubert 	{ "InterworkingSelectDone", WPAS_DBUS_NEW_IFACE_INTERFACE,
4268*32a95656SCy Schubert 	  {
4269*32a95656SCy Schubert 		  END_ARGS
4270*32a95656SCy Schubert 	  }
4271*32a95656SCy Schubert 	},
4272*32a95656SCy Schubert #endif /* CONFIG_INTERWORKING */
4273d4f2939cSRui Paulo 	{ NULL, NULL, { END_ARGS } }
4274d4f2939cSRui Paulo };
4275d4f2939cSRui Paulo 
4276d4f2939cSRui Paulo 
4277780fb4a2SCy Schubert static int wpa_dbus_ctrl_iface_props_init(struct wpas_dbus_priv *priv)
4278780fb4a2SCy Schubert {
4279780fb4a2SCy Schubert 	size_t all_size;
4280780fb4a2SCy Schubert 	unsigned int i, j, count, num_const, num_globals;
4281780fb4a2SCy Schubert 	const char *global_name;
4282780fb4a2SCy Schubert 	static const char * const ignored_globals[] = {
4283780fb4a2SCy Schubert 		"bss_expiration_age", "bss_expiration_scan_count",
4284780fb4a2SCy Schubert 		"ap_scan", "country", "fast_reauth",
4285780fb4a2SCy Schubert 		"pkcs11_engine_path", "pkcs11_module_path"
4286780fb4a2SCy Schubert 	};
4287780fb4a2SCy Schubert 
4288780fb4a2SCy Schubert 	/* wpas_dbus_interface_properties terminates with a NULL element */
4289780fb4a2SCy Schubert 	num_const = ARRAY_SIZE(wpas_dbus_interface_properties) - 1;
4290780fb4a2SCy Schubert 
4291780fb4a2SCy Schubert 	num_globals = wpa_config_get_num_global_field_names();
4292780fb4a2SCy Schubert 	priv->globals_start = num_const;
4293780fb4a2SCy Schubert 
4294780fb4a2SCy Schubert 	/* allocate enough for all properties + terminating NULL element */
4295780fb4a2SCy Schubert 	all_size = (num_globals + num_const + 1) *
4296780fb4a2SCy Schubert 		sizeof(wpas_dbus_interface_properties[0]);
4297780fb4a2SCy Schubert 	priv->all_interface_properties = os_zalloc(all_size);
4298780fb4a2SCy Schubert 	if (!priv->all_interface_properties) {
4299780fb4a2SCy Schubert 		wpa_printf(MSG_ERROR,
4300780fb4a2SCy Schubert 			   "dbus: Not enough memory for interface properties");
4301780fb4a2SCy Schubert 		return -1;
4302780fb4a2SCy Schubert 	}
4303780fb4a2SCy Schubert 
4304780fb4a2SCy Schubert 	/* Copy constant interface properties to the start of the array */
4305780fb4a2SCy Schubert 	os_memcpy(priv->all_interface_properties,
4306780fb4a2SCy Schubert 		  wpas_dbus_interface_properties,
4307780fb4a2SCy Schubert 		  sizeof(wpas_dbus_interface_properties));
4308780fb4a2SCy Schubert 
4309780fb4a2SCy Schubert 	/* Dynamically construct interface global properties */
4310780fb4a2SCy Schubert 	for (i = 0, count = num_const; i < num_globals; i++) {
4311780fb4a2SCy Schubert 		struct wpa_dbus_property_desc *desc;
4312780fb4a2SCy Schubert 		int no_var = 0;
4313780fb4a2SCy Schubert 
4314780fb4a2SCy Schubert 		/* ignore globals that are actually just methods */
4315780fb4a2SCy Schubert 		global_name = wpa_config_get_global_field_name(i, &no_var);
4316780fb4a2SCy Schubert 		if (no_var)
4317780fb4a2SCy Schubert 			continue;
4318780fb4a2SCy Schubert 		/* Ignore fields already explicitly exposed */
4319780fb4a2SCy Schubert 		for (j = 0; j < ARRAY_SIZE(ignored_globals); j++) {
4320780fb4a2SCy Schubert 			if (os_strcmp(global_name, ignored_globals[j]) == 0)
4321780fb4a2SCy Schubert 				break;
4322780fb4a2SCy Schubert 		}
4323780fb4a2SCy Schubert 		if (j < ARRAY_SIZE(ignored_globals))
4324780fb4a2SCy Schubert 			continue;
4325780fb4a2SCy Schubert 
4326780fb4a2SCy Schubert 		desc = &priv->all_interface_properties[count++];
4327780fb4a2SCy Schubert 		desc->dbus_property = uscore_to_dbus(global_name);
4328780fb4a2SCy Schubert 		if (!desc->dbus_property) {
4329780fb4a2SCy Schubert 			wpa_printf(MSG_ERROR,
4330780fb4a2SCy Schubert 				   "dbus: Not enough memory for D-Bus property name");
4331780fb4a2SCy Schubert 			goto error;
4332780fb4a2SCy Schubert 		}
4333780fb4a2SCy Schubert 		desc->dbus_interface = WPAS_DBUS_NEW_IFACE_INTERFACE;
4334780fb4a2SCy Schubert 		desc->type = "s";
4335780fb4a2SCy Schubert 		desc->getter = wpas_dbus_getter_iface_global;
4336780fb4a2SCy Schubert 		desc->setter = wpas_dbus_setter_iface_global;
4337780fb4a2SCy Schubert 		desc->data = global_name;
4338780fb4a2SCy Schubert 	}
4339780fb4a2SCy Schubert 
4340780fb4a2SCy Schubert 	return 0;
4341780fb4a2SCy Schubert 
4342780fb4a2SCy Schubert error:
4343780fb4a2SCy Schubert 	wpa_dbus_ctrl_iface_props_deinit(priv);
4344780fb4a2SCy Schubert 	return -1;
4345780fb4a2SCy Schubert }
4346780fb4a2SCy Schubert 
4347780fb4a2SCy Schubert 
4348325151a3SRui Paulo /**
4349325151a3SRui Paulo  * wpas_dbus_register_interface - Register an interface with D-Bus
4350325151a3SRui Paulo  * @wpa_s: wpa_supplicant interface structure
4351325151a3SRui Paulo  * Returns: 0 on success, -1 on failure
4352325151a3SRui Paulo  */
4353d4f2939cSRui Paulo int wpas_dbus_register_interface(struct wpa_supplicant *wpa_s)
4354d4f2939cSRui Paulo {
4355d4f2939cSRui Paulo 	struct wpa_dbus_object_desc *obj_desc = NULL;
4356d4f2939cSRui Paulo 	struct wpas_dbus_priv *ctrl_iface = wpa_s->global->dbus;
4357d4f2939cSRui Paulo 	int next;
4358d4f2939cSRui Paulo 
4359d4f2939cSRui Paulo 	/* Do nothing if the control interface is not turned on */
4360d4f2939cSRui Paulo 	if (ctrl_iface == NULL)
4361d4f2939cSRui Paulo 		return 0;
4362d4f2939cSRui Paulo 
4363d4f2939cSRui Paulo 	/* Create and set the interface's object path */
4364d4f2939cSRui Paulo 	wpa_s->dbus_new_path = os_zalloc(WPAS_DBUS_OBJECT_PATH_MAX);
4365d4f2939cSRui Paulo 	if (wpa_s->dbus_new_path == NULL)
4366d4f2939cSRui Paulo 		return -1;
4367d4f2939cSRui Paulo 	next = ctrl_iface->next_objid++;
4368d4f2939cSRui Paulo 	os_snprintf(wpa_s->dbus_new_path, WPAS_DBUS_OBJECT_PATH_MAX,
4369d4f2939cSRui Paulo 		    WPAS_DBUS_NEW_PATH_INTERFACES "/%u",
4370d4f2939cSRui Paulo 		    next);
4371d4f2939cSRui Paulo 
4372d4f2939cSRui Paulo 	obj_desc = os_zalloc(sizeof(struct wpa_dbus_object_desc));
4373d4f2939cSRui Paulo 	if (!obj_desc) {
43745b9c547cSRui Paulo 		wpa_printf(MSG_ERROR,
43755b9c547cSRui Paulo 			   "Not enough memory to create object description");
4376d4f2939cSRui Paulo 		goto err;
4377d4f2939cSRui Paulo 	}
4378d4f2939cSRui Paulo 
4379d4f2939cSRui Paulo 	wpas_dbus_register(obj_desc, wpa_s, NULL, wpas_dbus_interface_methods,
4380780fb4a2SCy Schubert 			   ctrl_iface->all_interface_properties,
4381d4f2939cSRui Paulo 			   wpas_dbus_interface_signals);
4382d4f2939cSRui Paulo 
4383d4f2939cSRui Paulo 	wpa_printf(MSG_DEBUG, "dbus: Register interface object '%s'",
4384d4f2939cSRui Paulo 		   wpa_s->dbus_new_path);
4385d4f2939cSRui Paulo 	if (wpa_dbus_register_object_per_iface(ctrl_iface,
4386d4f2939cSRui Paulo 					       wpa_s->dbus_new_path,
4387d4f2939cSRui Paulo 					       wpa_s->ifname, obj_desc))
4388d4f2939cSRui Paulo 		goto err;
4389d4f2939cSRui Paulo 
4390d4f2939cSRui Paulo 	wpas_dbus_signal_interface_added(wpa_s);
4391d4f2939cSRui Paulo 
4392d4f2939cSRui Paulo 	return 0;
4393d4f2939cSRui Paulo 
4394d4f2939cSRui Paulo err:
4395d4f2939cSRui Paulo 	os_free(wpa_s->dbus_new_path);
4396d4f2939cSRui Paulo 	wpa_s->dbus_new_path = NULL;
4397d4f2939cSRui Paulo 	free_dbus_object_desc(obj_desc);
4398d4f2939cSRui Paulo 	return -1;
4399d4f2939cSRui Paulo }
4400d4f2939cSRui Paulo 
4401d4f2939cSRui Paulo 
4402325151a3SRui Paulo /**
4403325151a3SRui Paulo  * wpas_dbus_unregister_interface - Unregister the interface from D-Bus
4404325151a3SRui Paulo  * @wpa_s: wpa_supplicant interface structure
4405325151a3SRui Paulo  * Returns: 0 on success, -1 on failure
4406325151a3SRui Paulo  */
4407d4f2939cSRui Paulo int wpas_dbus_unregister_interface(struct wpa_supplicant *wpa_s)
4408d4f2939cSRui Paulo {
4409d4f2939cSRui Paulo 	struct wpas_dbus_priv *ctrl_iface;
4410d4f2939cSRui Paulo 
4411d4f2939cSRui Paulo 	/* Do nothing if the control interface is not turned on */
4412d4f2939cSRui Paulo 	if (wpa_s == NULL || wpa_s->global == NULL)
4413d4f2939cSRui Paulo 		return 0;
4414d4f2939cSRui Paulo 	ctrl_iface = wpa_s->global->dbus;
44155b9c547cSRui Paulo 	if (ctrl_iface == NULL || wpa_s->dbus_new_path == NULL)
4416d4f2939cSRui Paulo 		return 0;
4417d4f2939cSRui Paulo 
4418d4f2939cSRui Paulo 	wpa_printf(MSG_DEBUG, "dbus: Unregister interface object '%s'",
4419d4f2939cSRui Paulo 		   wpa_s->dbus_new_path);
4420d4f2939cSRui Paulo 
4421d4f2939cSRui Paulo #ifdef CONFIG_AP
4422d4f2939cSRui Paulo 	if (wpa_s->preq_notify_peer) {
4423d4f2939cSRui Paulo 		wpas_dbus_unsubscribe_noc(ctrl_iface);
4424d4f2939cSRui Paulo 		os_free(wpa_s->preq_notify_peer);
4425d4f2939cSRui Paulo 		wpa_s->preq_notify_peer = NULL;
4426d4f2939cSRui Paulo 	}
4427d4f2939cSRui Paulo #endif /* CONFIG_AP */
4428d4f2939cSRui Paulo 
4429d4f2939cSRui Paulo 	if (wpa_dbus_unregister_object_per_iface(ctrl_iface,
4430d4f2939cSRui Paulo 						 wpa_s->dbus_new_path))
4431d4f2939cSRui Paulo 		return -1;
4432d4f2939cSRui Paulo 
4433d4f2939cSRui Paulo 	wpas_dbus_signal_interface_removed(wpa_s);
4434d4f2939cSRui Paulo 
4435d4f2939cSRui Paulo 	os_free(wpa_s->dbus_new_path);
4436d4f2939cSRui Paulo 	wpa_s->dbus_new_path = NULL;
4437d4f2939cSRui Paulo 
4438d4f2939cSRui Paulo 	return 0;
4439d4f2939cSRui Paulo }
4440d4f2939cSRui Paulo 
4441d4f2939cSRui Paulo #ifdef CONFIG_P2P
4442d4f2939cSRui Paulo 
4443d4f2939cSRui Paulo static const struct wpa_dbus_property_desc wpas_dbus_p2p_peer_properties[] = {
4444d4f2939cSRui Paulo 	{ "DeviceName", WPAS_DBUS_NEW_IFACE_P2P_PEER, "s",
4445d4f2939cSRui Paulo 	  wpas_dbus_getter_p2p_peer_device_name,
4446780fb4a2SCy Schubert 	  NULL,
4447d4f2939cSRui Paulo 	  NULL
4448d4f2939cSRui Paulo 	},
4449325151a3SRui Paulo 	{ "Manufacturer", WPAS_DBUS_NEW_IFACE_P2P_PEER, "s",
4450325151a3SRui Paulo 	  wpas_dbus_getter_p2p_peer_manufacturer,
4451780fb4a2SCy Schubert 	  NULL,
4452325151a3SRui Paulo 	  NULL
4453325151a3SRui Paulo 	},
4454325151a3SRui Paulo 	{ "ModelName", WPAS_DBUS_NEW_IFACE_P2P_PEER, "s",
4455325151a3SRui Paulo 	  wpas_dbus_getter_p2p_peer_modelname,
4456780fb4a2SCy Schubert 	  NULL,
4457325151a3SRui Paulo 	  NULL
4458325151a3SRui Paulo 	},
4459325151a3SRui Paulo 	{ "ModelNumber", WPAS_DBUS_NEW_IFACE_P2P_PEER, "s",
4460325151a3SRui Paulo 	  wpas_dbus_getter_p2p_peer_modelnumber,
4461780fb4a2SCy Schubert 	  NULL,
4462325151a3SRui Paulo 	  NULL
4463325151a3SRui Paulo 	},
4464325151a3SRui Paulo 	{ "SerialNumber", WPAS_DBUS_NEW_IFACE_P2P_PEER, "s",
4465325151a3SRui Paulo 	  wpas_dbus_getter_p2p_peer_serialnumber,
4466780fb4a2SCy Schubert 	  NULL,
4467325151a3SRui Paulo 	  NULL
4468325151a3SRui Paulo 	},
4469d4f2939cSRui Paulo 	{ "PrimaryDeviceType", WPAS_DBUS_NEW_IFACE_P2P_PEER, "ay",
4470d4f2939cSRui Paulo 	  wpas_dbus_getter_p2p_peer_primary_device_type,
4471780fb4a2SCy Schubert 	  NULL,
4472d4f2939cSRui Paulo 	  NULL
4473d4f2939cSRui Paulo 	},
4474d4f2939cSRui Paulo 	{ "config_method", WPAS_DBUS_NEW_IFACE_P2P_PEER, "q",
4475d4f2939cSRui Paulo 	  wpas_dbus_getter_p2p_peer_config_method,
4476780fb4a2SCy Schubert 	  NULL,
4477d4f2939cSRui Paulo 	  NULL
4478d4f2939cSRui Paulo 	},
4479d4f2939cSRui Paulo 	{ "level", WPAS_DBUS_NEW_IFACE_P2P_PEER, "i",
4480d4f2939cSRui Paulo 	  wpas_dbus_getter_p2p_peer_level,
4481780fb4a2SCy Schubert 	  NULL,
4482d4f2939cSRui Paulo 	  NULL
4483d4f2939cSRui Paulo 	},
4484d4f2939cSRui Paulo 	{ "devicecapability", WPAS_DBUS_NEW_IFACE_P2P_PEER, "y",
4485d4f2939cSRui Paulo 	  wpas_dbus_getter_p2p_peer_device_capability,
4486780fb4a2SCy Schubert 	  NULL,
4487d4f2939cSRui Paulo 	  NULL
4488d4f2939cSRui Paulo 	},
4489d4f2939cSRui Paulo 	{ "groupcapability", WPAS_DBUS_NEW_IFACE_P2P_PEER, "y",
4490d4f2939cSRui Paulo 	  wpas_dbus_getter_p2p_peer_group_capability,
4491780fb4a2SCy Schubert 	  NULL,
4492d4f2939cSRui Paulo 	  NULL
4493d4f2939cSRui Paulo 	},
4494d4f2939cSRui Paulo 	{ "SecondaryDeviceTypes", WPAS_DBUS_NEW_IFACE_P2P_PEER, "aay",
4495d4f2939cSRui Paulo 	  wpas_dbus_getter_p2p_peer_secondary_device_types,
4496780fb4a2SCy Schubert 	  NULL,
4497d4f2939cSRui Paulo 	  NULL
4498d4f2939cSRui Paulo 	},
4499d4f2939cSRui Paulo 	{ "VendorExtension", WPAS_DBUS_NEW_IFACE_P2P_PEER, "aay",
4500d4f2939cSRui Paulo 	  wpas_dbus_getter_p2p_peer_vendor_extension,
4501780fb4a2SCy Schubert 	  NULL,
4502d4f2939cSRui Paulo 	  NULL
4503d4f2939cSRui Paulo 	},
4504d4f2939cSRui Paulo 	{ "IEs", WPAS_DBUS_NEW_IFACE_P2P_PEER, "ay",
4505d4f2939cSRui Paulo 	  wpas_dbus_getter_p2p_peer_ies,
4506780fb4a2SCy Schubert 	  NULL,
4507d4f2939cSRui Paulo 	  NULL
4508d4f2939cSRui Paulo 	},
45095b9c547cSRui Paulo 	{ "DeviceAddress", WPAS_DBUS_NEW_IFACE_P2P_PEER, "ay",
45105b9c547cSRui Paulo 	  wpas_dbus_getter_p2p_peer_device_address,
4511780fb4a2SCy Schubert 	  NULL,
45125b9c547cSRui Paulo 	  NULL
45135b9c547cSRui Paulo 	},
45145b9c547cSRui Paulo 	{ "Groups", WPAS_DBUS_NEW_IFACE_P2P_PEER, "ao",
45155b9c547cSRui Paulo 	  wpas_dbus_getter_p2p_peer_groups,
4516780fb4a2SCy Schubert 	  NULL,
45175b9c547cSRui Paulo 	  NULL
45185b9c547cSRui Paulo 	},
45194bc52338SCy Schubert 	{ "VSIE", WPAS_DBUS_NEW_IFACE_P2P_PEER, "ay",
45204bc52338SCy Schubert 	  wpas_dbus_getter_p2p_peer_vsie,
45214bc52338SCy Schubert 	  NULL,
45224bc52338SCy Schubert 	  NULL
45234bc52338SCy Schubert 	},
4524780fb4a2SCy Schubert 	{ NULL, NULL, NULL, NULL, NULL, NULL }
4525d4f2939cSRui Paulo };
4526d4f2939cSRui Paulo 
4527d4f2939cSRui Paulo static const struct wpa_dbus_signal_desc wpas_dbus_p2p_peer_signals[] = {
45285b9c547cSRui Paulo 	/* Deprecated: use org.freedesktop.DBus.Properties.PropertiesChanged */
45295b9c547cSRui Paulo 	{ "PropertiesChanged", WPAS_DBUS_NEW_IFACE_P2P_PEER,
45305b9c547cSRui Paulo 	  {
45315b9c547cSRui Paulo 		  { "properties", "a{sv}", ARG_OUT },
45325b9c547cSRui Paulo 		  END_ARGS
45335b9c547cSRui Paulo 	  }
45345b9c547cSRui Paulo 	},
4535d4f2939cSRui Paulo 	{ NULL, NULL, { END_ARGS } }
4536d4f2939cSRui Paulo };
4537d4f2939cSRui Paulo 
4538d4f2939cSRui Paulo /**
4539d4f2939cSRui Paulo  * wpas_dbus_signal_peer - Send a peer related event signal
4540d4f2939cSRui Paulo  * @wpa_s: %wpa_supplicant network interface data
4541d4f2939cSRui Paulo  * @dev: peer device object
4542d4f2939cSRui Paulo  * @interface: name of the interface emitting this signal.
4543d4f2939cSRui Paulo  *	In case of peer objects, it would be emitted by either
4544d4f2939cSRui Paulo  *	the "interface object" or by "peer objects"
4545d4f2939cSRui Paulo  * @sig_name: signal name - DeviceFound
4546780fb4a2SCy Schubert  * @properties: Whether to add a second argument with object properties
4547d4f2939cSRui Paulo  *
4548780fb4a2SCy Schubert  * Notify listeners about event related with p2p peer device
4549d4f2939cSRui Paulo  */
4550d4f2939cSRui Paulo static void wpas_dbus_signal_peer(struct wpa_supplicant *wpa_s,
4551d4f2939cSRui Paulo 				  const u8 *dev_addr, const char *interface,
45524bc52338SCy Schubert 				  const char *sig_name, dbus_bool_t properties)
4553d4f2939cSRui Paulo {
4554d4f2939cSRui Paulo 	struct wpas_dbus_priv *iface;
4555d4f2939cSRui Paulo 	DBusMessage *msg;
4556d4f2939cSRui Paulo 	DBusMessageIter iter;
4557d4f2939cSRui Paulo 	char peer_obj_path[WPAS_DBUS_OBJECT_PATH_MAX], *path;
4558d4f2939cSRui Paulo 
45595b9c547cSRui Paulo 	if (wpa_s->p2p_mgmt)
45605b9c547cSRui Paulo 		wpa_s = wpa_s->parent;
45615b9c547cSRui Paulo 
4562d4f2939cSRui Paulo 	iface = wpa_s->global->dbus;
4563d4f2939cSRui Paulo 
4564d4f2939cSRui Paulo 	/* Do nothing if the control interface is not turned on */
4565325151a3SRui Paulo 	if (iface == NULL || !wpa_s->dbus_new_path)
4566d4f2939cSRui Paulo 		return;
4567d4f2939cSRui Paulo 
4568d4f2939cSRui Paulo 	os_snprintf(peer_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
4569d4f2939cSRui Paulo 		    "%s/" WPAS_DBUS_NEW_P2P_PEERS_PART "/" COMPACT_MACSTR,
4570d4f2939cSRui Paulo 		    wpa_s->dbus_new_path, MAC2STR(dev_addr));
4571d4f2939cSRui Paulo 
4572d4f2939cSRui Paulo 	msg = dbus_message_new_signal(wpa_s->dbus_new_path, interface,
4573d4f2939cSRui Paulo 				      sig_name);
4574d4f2939cSRui Paulo 	if (msg == NULL)
4575d4f2939cSRui Paulo 		return;
4576d4f2939cSRui Paulo 
4577d4f2939cSRui Paulo 	dbus_message_iter_init_append(msg, &iter);
4578d4f2939cSRui Paulo 	path = peer_obj_path;
4579d4f2939cSRui Paulo 	if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_OBJECT_PATH,
4580780fb4a2SCy Schubert 					    &path) ||
4581780fb4a2SCy Schubert 	    (properties && !wpa_dbus_get_object_properties(
4582780fb4a2SCy Schubert 		    iface, peer_obj_path, WPAS_DBUS_NEW_IFACE_P2P_PEER,
4583780fb4a2SCy Schubert 		    &iter)))
45845b9c547cSRui Paulo 		wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
45855b9c547cSRui Paulo 	else
4586d4f2939cSRui Paulo 		dbus_connection_send(iface->con, msg, NULL);
4587d4f2939cSRui Paulo 
4588d4f2939cSRui Paulo 	dbus_message_unref(msg);
4589d4f2939cSRui Paulo }
4590d4f2939cSRui Paulo 
4591d4f2939cSRui Paulo 
4592d4f2939cSRui Paulo /**
4593d4f2939cSRui Paulo  * wpas_dbus_signal_peer_found - Send a peer found signal
4594d4f2939cSRui Paulo  * @wpa_s: %wpa_supplicant network interface data
4595325151a3SRui Paulo  * @dev_addr: Peer P2P Device Address
4596d4f2939cSRui Paulo  *
4597d4f2939cSRui Paulo  * Notify listeners about find a p2p peer device found
4598d4f2939cSRui Paulo  */
4599d4f2939cSRui Paulo void wpas_dbus_signal_peer_device_found(struct wpa_supplicant *wpa_s,
4600d4f2939cSRui Paulo 					const u8 *dev_addr)
4601d4f2939cSRui Paulo {
4602d4f2939cSRui Paulo 	wpas_dbus_signal_peer(wpa_s, dev_addr,
4603d4f2939cSRui Paulo 			      WPAS_DBUS_NEW_IFACE_P2PDEVICE,
4604780fb4a2SCy Schubert 			      "DeviceFound", FALSE);
4605780fb4a2SCy Schubert 
4606780fb4a2SCy Schubert 	wpas_dbus_signal_peer(wpa_s, dev_addr,
4607780fb4a2SCy Schubert 			      WPAS_DBUS_NEW_IFACE_P2PDEVICE,
4608780fb4a2SCy Schubert 			      "DeviceFoundProperties", TRUE);
4609d4f2939cSRui Paulo }
4610d4f2939cSRui Paulo 
4611d4f2939cSRui Paulo /**
4612d4f2939cSRui Paulo  * wpas_dbus_signal_peer_lost - Send a peer lost signal
4613d4f2939cSRui Paulo  * @wpa_s: %wpa_supplicant network interface data
4614325151a3SRui Paulo  * @dev_addr: Peer P2P Device Address
4615d4f2939cSRui Paulo  *
4616d4f2939cSRui Paulo  * Notify listeners about lost a p2p peer device
4617d4f2939cSRui Paulo  */
4618d4f2939cSRui Paulo void wpas_dbus_signal_peer_device_lost(struct wpa_supplicant *wpa_s,
4619d4f2939cSRui Paulo 				       const u8 *dev_addr)
4620d4f2939cSRui Paulo {
4621d4f2939cSRui Paulo 	wpas_dbus_signal_peer(wpa_s, dev_addr,
4622d4f2939cSRui Paulo 			      WPAS_DBUS_NEW_IFACE_P2PDEVICE,
4623780fb4a2SCy Schubert 			      "DeviceLost", FALSE);
4624d4f2939cSRui Paulo }
4625d4f2939cSRui Paulo 
4626d4f2939cSRui Paulo /**
4627d4f2939cSRui Paulo  * wpas_dbus_register_peer - Register a discovered peer object with dbus
4628d4f2939cSRui Paulo  * @wpa_s: wpa_supplicant interface structure
4629325151a3SRui Paulo  * @dev_addr: P2P Device Address of the peer
4630d4f2939cSRui Paulo  * Returns: 0 on success, -1 on failure
4631d4f2939cSRui Paulo  *
4632d4f2939cSRui Paulo  * Registers network representing object with dbus
4633d4f2939cSRui Paulo  */
4634d4f2939cSRui Paulo int wpas_dbus_register_peer(struct wpa_supplicant *wpa_s, const u8 *dev_addr)
4635d4f2939cSRui Paulo {
4636d4f2939cSRui Paulo 	struct wpas_dbus_priv *ctrl_iface;
4637d4f2939cSRui Paulo 	struct wpa_dbus_object_desc *obj_desc;
4638d4f2939cSRui Paulo 	struct peer_handler_args *arg;
4639d4f2939cSRui Paulo 	char peer_obj_path[WPAS_DBUS_OBJECT_PATH_MAX];
4640d4f2939cSRui Paulo 
4641d4f2939cSRui Paulo 	/* Do nothing if the control interface is not turned on */
4642d4f2939cSRui Paulo 	if (wpa_s == NULL || wpa_s->global == NULL)
4643d4f2939cSRui Paulo 		return 0;
4644d4f2939cSRui Paulo 
4645d4f2939cSRui Paulo 	ctrl_iface = wpa_s->global->dbus;
4646d4f2939cSRui Paulo 	if (ctrl_iface == NULL)
4647d4f2939cSRui Paulo 		return 0;
4648d4f2939cSRui Paulo 
4649325151a3SRui Paulo 	wpa_s = wpa_s->parent->parent;
4650325151a3SRui Paulo 	if (!wpa_s->dbus_new_path)
4651325151a3SRui Paulo 		return 0;
46525b9c547cSRui Paulo 
4653d4f2939cSRui Paulo 	os_snprintf(peer_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
4654d4f2939cSRui Paulo 		    "%s/" WPAS_DBUS_NEW_P2P_PEERS_PART "/" COMPACT_MACSTR,
4655d4f2939cSRui Paulo 		    wpa_s->dbus_new_path, MAC2STR(dev_addr));
4656d4f2939cSRui Paulo 
4657d4f2939cSRui Paulo 	wpa_printf(MSG_INFO, "dbus: Register peer object '%s'",
4658d4f2939cSRui Paulo 		   peer_obj_path);
4659d4f2939cSRui Paulo 	obj_desc = os_zalloc(sizeof(struct wpa_dbus_object_desc));
4660d4f2939cSRui Paulo 	if (!obj_desc) {
46615b9c547cSRui Paulo 		wpa_printf(MSG_ERROR,
46625b9c547cSRui Paulo 			   "Not enough memory to create object description");
4663d4f2939cSRui Paulo 		goto err;
4664d4f2939cSRui Paulo 	}
4665d4f2939cSRui Paulo 
4666d4f2939cSRui Paulo 	/* allocate memory for handlers arguments */
4667d4f2939cSRui Paulo 	arg = os_zalloc(sizeof(struct peer_handler_args));
4668d4f2939cSRui Paulo 	if (!arg) {
46695b9c547cSRui Paulo 		wpa_printf(MSG_ERROR,
46705b9c547cSRui Paulo 			   "Not enough memory to create arguments for method");
4671d4f2939cSRui Paulo 		goto err;
4672d4f2939cSRui Paulo 	}
4673d4f2939cSRui Paulo 
4674d4f2939cSRui Paulo 	arg->wpa_s = wpa_s;
4675d4f2939cSRui Paulo 	os_memcpy(arg->p2p_device_addr, dev_addr, ETH_ALEN);
4676d4f2939cSRui Paulo 
4677d4f2939cSRui Paulo 	wpas_dbus_register(obj_desc, arg, wpa_dbus_free,
4678d4f2939cSRui Paulo 			   NULL,
4679d4f2939cSRui Paulo 			   wpas_dbus_p2p_peer_properties,
4680d4f2939cSRui Paulo 			   wpas_dbus_p2p_peer_signals);
4681d4f2939cSRui Paulo 
4682d4f2939cSRui Paulo 	if (wpa_dbus_register_object_per_iface(ctrl_iface, peer_obj_path,
4683d4f2939cSRui Paulo 					       wpa_s->ifname, obj_desc))
4684d4f2939cSRui Paulo 		goto err;
4685d4f2939cSRui Paulo 
4686d4f2939cSRui Paulo 	return 0;
4687d4f2939cSRui Paulo 
4688d4f2939cSRui Paulo err:
4689d4f2939cSRui Paulo 	free_dbus_object_desc(obj_desc);
4690d4f2939cSRui Paulo 	return -1;
4691d4f2939cSRui Paulo }
4692d4f2939cSRui Paulo 
4693d4f2939cSRui Paulo /**
4694d4f2939cSRui Paulo  * wpas_dbus_unregister_peer - Unregister a peer object with dbus
4695d4f2939cSRui Paulo  * @wpa_s: wpa_supplicant interface structure
4696d4f2939cSRui Paulo  * @dev_addr: p2p device addr
4697d4f2939cSRui Paulo  * Returns: 0 on success, -1 on failure
4698d4f2939cSRui Paulo  *
4699d4f2939cSRui Paulo  * Registers network representing object with dbus
4700d4f2939cSRui Paulo  */
4701d4f2939cSRui Paulo int wpas_dbus_unregister_peer(struct wpa_supplicant *wpa_s,
4702d4f2939cSRui Paulo 				  const u8 *dev_addr)
4703d4f2939cSRui Paulo {
4704d4f2939cSRui Paulo 	struct wpas_dbus_priv *ctrl_iface;
4705d4f2939cSRui Paulo 	char peer_obj_path[WPAS_DBUS_OBJECT_PATH_MAX];
4706d4f2939cSRui Paulo 	int ret;
4707d4f2939cSRui Paulo 
4708d4f2939cSRui Paulo 	/* Do nothing if the control interface is not turned on */
4709325151a3SRui Paulo 	if (wpa_s == NULL || wpa_s->global == NULL)
4710d4f2939cSRui Paulo 		return 0;
47115b9c547cSRui Paulo 
4712325151a3SRui Paulo 	wpa_s = wpa_s->parent->parent;
4713325151a3SRui Paulo 	if (!wpa_s->dbus_new_path)
4714325151a3SRui Paulo 		return 0;
47155b9c547cSRui Paulo 
4716d4f2939cSRui Paulo 	ctrl_iface = wpa_s->global->dbus;
4717d4f2939cSRui Paulo 	if (ctrl_iface == NULL)
4718d4f2939cSRui Paulo 		return 0;
4719d4f2939cSRui Paulo 
4720d4f2939cSRui Paulo 	os_snprintf(peer_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
4721d4f2939cSRui Paulo 		    "%s/" WPAS_DBUS_NEW_P2P_PEERS_PART "/" COMPACT_MACSTR,
4722d4f2939cSRui Paulo 		    wpa_s->dbus_new_path, MAC2STR(dev_addr));
4723d4f2939cSRui Paulo 
4724d4f2939cSRui Paulo 	wpa_printf(MSG_INFO, "dbus: Unregister peer object '%s'",
4725d4f2939cSRui Paulo 		   peer_obj_path);
4726d4f2939cSRui Paulo 	ret = wpa_dbus_unregister_object_per_iface(ctrl_iface, peer_obj_path);
4727d4f2939cSRui Paulo 
4728d4f2939cSRui Paulo 	return ret;
4729d4f2939cSRui Paulo }
4730d4f2939cSRui Paulo 
4731d4f2939cSRui Paulo 
4732325151a3SRui Paulo /**
4733325151a3SRui Paulo  * wpas_dbus_signal_p2p_find_stopped - Send P2P Find stopped signal
4734325151a3SRui Paulo  * @wpa_s: %wpa_supplicant network interface data
4735325151a3SRui Paulo  *
4736325151a3SRui Paulo  * Notify listeners about P2P Find stopped
4737325151a3SRui Paulo  */
4738325151a3SRui Paulo void wpas_dbus_signal_p2p_find_stopped(struct wpa_supplicant *wpa_s)
4739325151a3SRui Paulo {
4740325151a3SRui Paulo 	struct wpas_dbus_priv *iface;
4741325151a3SRui Paulo 	DBusMessage *msg;
4742325151a3SRui Paulo 
4743325151a3SRui Paulo 	iface = wpa_s->global->dbus;
4744325151a3SRui Paulo 
4745325151a3SRui Paulo 	/* Do nothing if the control interface is not turned on */
474685732ac8SCy Schubert 	if (iface == NULL)
474785732ac8SCy Schubert 		return;
474885732ac8SCy Schubert 
474985732ac8SCy Schubert 	if (wpa_s->p2p_mgmt)
475085732ac8SCy Schubert 		wpa_s = wpa_s->parent;
475185732ac8SCy Schubert 
475285732ac8SCy Schubert 	if (!wpa_s->dbus_new_path)
4753325151a3SRui Paulo 		return;
4754325151a3SRui Paulo 
4755325151a3SRui Paulo 	msg = dbus_message_new_signal(wpa_s->dbus_new_path,
4756325151a3SRui Paulo 				      WPAS_DBUS_NEW_IFACE_P2PDEVICE,
4757325151a3SRui Paulo 				      "FindStopped");
4758325151a3SRui Paulo 	if (msg == NULL)
4759325151a3SRui Paulo 		return;
4760325151a3SRui Paulo 
4761325151a3SRui Paulo 	dbus_connection_send(iface->con, msg, NULL);
4762325151a3SRui Paulo 
4763325151a3SRui Paulo 	dbus_message_unref(msg);
4764325151a3SRui Paulo }
4765325151a3SRui Paulo 
4766325151a3SRui Paulo 
4767325151a3SRui Paulo /**
4768325151a3SRui Paulo  * wpas_dbus_signal_peer_groups_changed - Send peer group change property signal
4769325151a3SRui Paulo  * @wpa_s: %wpa_supplicant network interface data
4770325151a3SRui Paulo  * @dev_addr: P2P Device Address
4771325151a3SRui Paulo  *
4772325151a3SRui Paulo  * Notify listeners about peer Groups property changes.
4773325151a3SRui Paulo  */
47745b9c547cSRui Paulo void wpas_dbus_signal_peer_groups_changed(struct wpa_supplicant *wpa_s,
47755b9c547cSRui Paulo 					  const u8 *dev_addr)
47765b9c547cSRui Paulo {
47775b9c547cSRui Paulo 	char peer_obj_path[WPAS_DBUS_OBJECT_PATH_MAX];
47785b9c547cSRui Paulo 
47795b9c547cSRui Paulo 	if (wpa_s->p2p_mgmt)
47805b9c547cSRui Paulo 		wpa_s = wpa_s->parent;
47815b9c547cSRui Paulo 
4782325151a3SRui Paulo 	if (!wpa_s->dbus_new_path)
4783325151a3SRui Paulo 		return;
47845b9c547cSRui Paulo 	os_snprintf(peer_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
47855b9c547cSRui Paulo 		    "%s/" WPAS_DBUS_NEW_P2P_PEERS_PART "/" COMPACT_MACSTR,
47865b9c547cSRui Paulo 		    wpa_s->dbus_new_path, MAC2STR(dev_addr));
47875b9c547cSRui Paulo 
47885b9c547cSRui Paulo 	wpa_dbus_mark_property_changed(wpa_s->global->dbus, peer_obj_path,
47895b9c547cSRui Paulo 				       WPAS_DBUS_NEW_IFACE_P2P_PEER, "Groups");
47905b9c547cSRui Paulo }
47915b9c547cSRui Paulo 
47925b9c547cSRui Paulo 
4793d4f2939cSRui Paulo static const struct wpa_dbus_property_desc wpas_dbus_p2p_group_properties[] = {
4794d4f2939cSRui Paulo 	{ "Members", WPAS_DBUS_NEW_IFACE_P2P_GROUP, "ao",
4795d4f2939cSRui Paulo 	  wpas_dbus_getter_p2p_group_members,
4796780fb4a2SCy Schubert 	  NULL,
4797d4f2939cSRui Paulo 	  NULL
4798d4f2939cSRui Paulo 	},
4799d4f2939cSRui Paulo 	{ "Group", WPAS_DBUS_NEW_IFACE_P2P_GROUP, "o",
4800d4f2939cSRui Paulo 	  wpas_dbus_getter_p2p_group,
4801780fb4a2SCy Schubert 	  NULL,
4802d4f2939cSRui Paulo 	  NULL
4803d4f2939cSRui Paulo 	},
4804d4f2939cSRui Paulo 	{ "Role", WPAS_DBUS_NEW_IFACE_P2P_GROUP, "s",
4805d4f2939cSRui Paulo 	  wpas_dbus_getter_p2p_role,
4806780fb4a2SCy Schubert 	  NULL,
4807d4f2939cSRui Paulo 	  NULL
4808d4f2939cSRui Paulo 	},
4809d4f2939cSRui Paulo 	{ "SSID", WPAS_DBUS_NEW_IFACE_P2P_GROUP, "ay",
4810d4f2939cSRui Paulo 	  wpas_dbus_getter_p2p_group_ssid,
4811780fb4a2SCy Schubert 	  NULL,
4812d4f2939cSRui Paulo 	  NULL
4813d4f2939cSRui Paulo 	},
4814d4f2939cSRui Paulo 	{ "BSSID", WPAS_DBUS_NEW_IFACE_P2P_GROUP, "ay",
4815d4f2939cSRui Paulo 	  wpas_dbus_getter_p2p_group_bssid,
4816780fb4a2SCy Schubert 	  NULL,
4817d4f2939cSRui Paulo 	  NULL
4818d4f2939cSRui Paulo 	},
4819d4f2939cSRui Paulo 	{ "Frequency", WPAS_DBUS_NEW_IFACE_P2P_GROUP, "q",
4820d4f2939cSRui Paulo 	  wpas_dbus_getter_p2p_group_frequency,
4821780fb4a2SCy Schubert 	  NULL,
4822d4f2939cSRui Paulo 	  NULL
4823d4f2939cSRui Paulo 	},
4824d4f2939cSRui Paulo 	{ "Passphrase", WPAS_DBUS_NEW_IFACE_P2P_GROUP, "s",
4825d4f2939cSRui Paulo 	  wpas_dbus_getter_p2p_group_passphrase,
4826780fb4a2SCy Schubert 	  NULL,
4827d4f2939cSRui Paulo 	  NULL
4828d4f2939cSRui Paulo 	},
4829d4f2939cSRui Paulo 	{ "PSK", WPAS_DBUS_NEW_IFACE_P2P_GROUP, "ay",
4830d4f2939cSRui Paulo 	  wpas_dbus_getter_p2p_group_psk,
4831780fb4a2SCy Schubert 	  NULL,
4832d4f2939cSRui Paulo 	  NULL
4833d4f2939cSRui Paulo 	},
4834d4f2939cSRui Paulo 	{ "WPSVendorExtensions", WPAS_DBUS_NEW_IFACE_P2P_GROUP, "aay",
4835d4f2939cSRui Paulo 	  wpas_dbus_getter_p2p_group_vendor_ext,
4836780fb4a2SCy Schubert 	  wpas_dbus_setter_p2p_group_vendor_ext,
4837780fb4a2SCy Schubert 	  NULL
4838d4f2939cSRui Paulo 	},
4839780fb4a2SCy Schubert 	{ NULL, NULL, NULL, NULL, NULL, NULL }
4840d4f2939cSRui Paulo };
4841d4f2939cSRui Paulo 
4842d4f2939cSRui Paulo static const struct wpa_dbus_signal_desc wpas_dbus_p2p_group_signals[] = {
4843d4f2939cSRui Paulo 	{ "PeerJoined", WPAS_DBUS_NEW_IFACE_P2P_GROUP,
4844d4f2939cSRui Paulo 	  {
4845d4f2939cSRui Paulo 		  { "peer", "o", ARG_OUT },
4846d4f2939cSRui Paulo 		  END_ARGS
4847d4f2939cSRui Paulo 	  }
4848d4f2939cSRui Paulo 	},
4849d4f2939cSRui Paulo 	{ "PeerDisconnected", WPAS_DBUS_NEW_IFACE_P2P_GROUP,
4850d4f2939cSRui Paulo 	  {
4851d4f2939cSRui Paulo 		  { "peer", "o", ARG_OUT },
4852d4f2939cSRui Paulo 		  END_ARGS
4853d4f2939cSRui Paulo 	  }
4854d4f2939cSRui Paulo 	},
4855d4f2939cSRui Paulo 	{ NULL, NULL, { END_ARGS } }
4856d4f2939cSRui Paulo };
4857d4f2939cSRui Paulo 
4858d4f2939cSRui Paulo /**
4859d4f2939cSRui Paulo  * wpas_dbus_register_p2p_group - Register a p2p group object with dbus
4860d4f2939cSRui Paulo  * @wpa_s: wpa_supplicant interface structure
4861d4f2939cSRui Paulo  * @ssid: SSID struct
4862d4f2939cSRui Paulo  * Returns: 0 on success, -1 on failure
4863d4f2939cSRui Paulo  *
4864d4f2939cSRui Paulo  * Registers p2p group representing object with dbus
4865d4f2939cSRui Paulo  */
4866d4f2939cSRui Paulo void wpas_dbus_register_p2p_group(struct wpa_supplicant *wpa_s,
4867d4f2939cSRui Paulo 				  struct wpa_ssid *ssid)
4868d4f2939cSRui Paulo {
4869d4f2939cSRui Paulo 	struct wpas_dbus_priv *ctrl_iface;
4870d4f2939cSRui Paulo 	struct wpa_dbus_object_desc *obj_desc;
4871d4f2939cSRui Paulo 	char group_obj_path[WPAS_DBUS_OBJECT_PATH_MAX];
4872d4f2939cSRui Paulo 
4873d4f2939cSRui Paulo 	/* Do nothing if the control interface is not turned on */
4874d4f2939cSRui Paulo 	if (wpa_s == NULL || wpa_s->global == NULL)
4875d4f2939cSRui Paulo 		return;
4876d4f2939cSRui Paulo 
4877d4f2939cSRui Paulo 	ctrl_iface = wpa_s->global->dbus;
4878d4f2939cSRui Paulo 	if (ctrl_iface == NULL)
4879d4f2939cSRui Paulo 		return;
4880d4f2939cSRui Paulo 
4881d4f2939cSRui Paulo 	if (wpa_s->dbus_groupobj_path) {
4882d4f2939cSRui Paulo 		wpa_printf(MSG_INFO, "%s: Group object '%s' already exists",
4883d4f2939cSRui Paulo 			   __func__, wpa_s->dbus_groupobj_path);
4884d4f2939cSRui Paulo 		return;
4885d4f2939cSRui Paulo 	}
4886d4f2939cSRui Paulo 
4887d4f2939cSRui Paulo 	if (wpas_dbus_get_group_obj_path(wpa_s, ssid, group_obj_path) < 0)
4888d4f2939cSRui Paulo 		return;
4889d4f2939cSRui Paulo 
4890d4f2939cSRui Paulo 	wpa_s->dbus_groupobj_path = os_strdup(group_obj_path);
4891d4f2939cSRui Paulo 	if (wpa_s->dbus_groupobj_path == NULL)
4892d4f2939cSRui Paulo 		return;
4893d4f2939cSRui Paulo 
4894d4f2939cSRui Paulo 	wpa_printf(MSG_INFO, "dbus: Register group object '%s'",
4895d4f2939cSRui Paulo 		   group_obj_path);
4896d4f2939cSRui Paulo 	obj_desc = os_zalloc(sizeof(struct wpa_dbus_object_desc));
4897d4f2939cSRui Paulo 	if (!obj_desc) {
48985b9c547cSRui Paulo 		wpa_printf(MSG_ERROR,
48995b9c547cSRui Paulo 			   "Not enough memory to create object description");
4900d4f2939cSRui Paulo 		goto err;
4901d4f2939cSRui Paulo 	}
4902d4f2939cSRui Paulo 
4903d4f2939cSRui Paulo 	wpas_dbus_register(obj_desc, wpa_s, NULL, NULL,
4904d4f2939cSRui Paulo 			   wpas_dbus_p2p_group_properties,
4905d4f2939cSRui Paulo 			   wpas_dbus_p2p_group_signals);
4906d4f2939cSRui Paulo 
4907d4f2939cSRui Paulo 	if (wpa_dbus_register_object_per_iface(ctrl_iface, group_obj_path,
4908d4f2939cSRui Paulo 					       wpa_s->ifname, obj_desc))
4909d4f2939cSRui Paulo 		goto err;
4910d4f2939cSRui Paulo 
4911d4f2939cSRui Paulo 	return;
4912d4f2939cSRui Paulo 
4913d4f2939cSRui Paulo err:
4914d4f2939cSRui Paulo 	if (wpa_s->dbus_groupobj_path) {
4915d4f2939cSRui Paulo 		os_free(wpa_s->dbus_groupobj_path);
4916d4f2939cSRui Paulo 		wpa_s->dbus_groupobj_path = NULL;
4917d4f2939cSRui Paulo 	}
4918d4f2939cSRui Paulo 
4919d4f2939cSRui Paulo 	free_dbus_object_desc(obj_desc);
4920d4f2939cSRui Paulo }
4921d4f2939cSRui Paulo 
4922d4f2939cSRui Paulo /**
4923d4f2939cSRui Paulo  * wpas_dbus_unregister_p2p_group - Unregister a p2p group object from dbus
4924d4f2939cSRui Paulo  * @wpa_s: wpa_supplicant interface structure
4925d4f2939cSRui Paulo  * @ssid: network name of the p2p group started
4926d4f2939cSRui Paulo  */
4927d4f2939cSRui Paulo void wpas_dbus_unregister_p2p_group(struct wpa_supplicant *wpa_s,
4928d4f2939cSRui Paulo 				    const struct wpa_ssid *ssid)
4929d4f2939cSRui Paulo {
4930d4f2939cSRui Paulo 	struct wpas_dbus_priv *ctrl_iface;
4931d4f2939cSRui Paulo 
4932d4f2939cSRui Paulo 	/* Do nothing if the control interface is not turned on */
4933d4f2939cSRui Paulo 	if (wpa_s == NULL || wpa_s->global == NULL)
4934d4f2939cSRui Paulo 		return;
4935d4f2939cSRui Paulo 
49365b9c547cSRui Paulo 	if (wpa_s->p2p_mgmt)
49375b9c547cSRui Paulo 		wpa_s = wpa_s->parent;
49385b9c547cSRui Paulo 
4939d4f2939cSRui Paulo 	ctrl_iface = wpa_s->global->dbus;
4940d4f2939cSRui Paulo 	if (ctrl_iface == NULL)
4941d4f2939cSRui Paulo 		return;
4942d4f2939cSRui Paulo 
4943d4f2939cSRui Paulo 	if (!wpa_s->dbus_groupobj_path) {
4944d4f2939cSRui Paulo 		wpa_printf(MSG_DEBUG,
4945c1d255d3SCy Schubert 			   "%s: Group object has already unregistered",
4946c1d255d3SCy Schubert 			   __func__);
4947d4f2939cSRui Paulo 		return;
4948d4f2939cSRui Paulo 	}
4949d4f2939cSRui Paulo 
49505b9c547cSRui Paulo 	peer_groups_changed(wpa_s);
49515b9c547cSRui Paulo 
4952d4f2939cSRui Paulo 	wpa_printf(MSG_DEBUG, "dbus: Unregister group object '%s'",
4953d4f2939cSRui Paulo 		   wpa_s->dbus_groupobj_path);
4954d4f2939cSRui Paulo 
4955d4f2939cSRui Paulo 	wpa_dbus_unregister_object_per_iface(ctrl_iface,
4956d4f2939cSRui Paulo 					     wpa_s->dbus_groupobj_path);
4957d4f2939cSRui Paulo 
4958d4f2939cSRui Paulo 	os_free(wpa_s->dbus_groupobj_path);
4959d4f2939cSRui Paulo 	wpa_s->dbus_groupobj_path = NULL;
4960d4f2939cSRui Paulo }
4961d4f2939cSRui Paulo 
4962d4f2939cSRui Paulo static const struct wpa_dbus_property_desc
4963d4f2939cSRui Paulo 	wpas_dbus_persistent_group_properties[] = {
4964d4f2939cSRui Paulo 	{ "Properties", WPAS_DBUS_NEW_IFACE_PERSISTENT_GROUP, "a{sv}",
4965d4f2939cSRui Paulo 	  wpas_dbus_getter_persistent_group_properties,
4966780fb4a2SCy Schubert 	  wpas_dbus_setter_persistent_group_properties,
4967780fb4a2SCy Schubert 	  NULL
4968d4f2939cSRui Paulo 	},
4969780fb4a2SCy Schubert 	{ NULL, NULL, NULL, NULL, NULL, NULL }
4970d4f2939cSRui Paulo };
4971d4f2939cSRui Paulo 
4972d4f2939cSRui Paulo /* No signals intended for persistent group objects */
4973d4f2939cSRui Paulo 
4974d4f2939cSRui Paulo /**
4975d4f2939cSRui Paulo  * wpas_dbus_register_persistent_group - Register a configured(saved)
4976d4f2939cSRui Paulo  *	persistent group with dbus
4977d4f2939cSRui Paulo  * @wpa_s: wpa_supplicant interface structure
4978d4f2939cSRui Paulo  * @ssid: persistent group (still represented as a network within wpa)
4979d4f2939cSRui Paulo  *	  configuration data
4980d4f2939cSRui Paulo  * Returns: 0 on success, -1 on failure
4981d4f2939cSRui Paulo  *
4982d4f2939cSRui Paulo  * Registers a persistent group representing object with dbus.
4983d4f2939cSRui Paulo  */
4984d4f2939cSRui Paulo int wpas_dbus_register_persistent_group(struct wpa_supplicant *wpa_s,
4985d4f2939cSRui Paulo 					struct wpa_ssid *ssid)
4986d4f2939cSRui Paulo {
4987d4f2939cSRui Paulo 	struct wpas_dbus_priv *ctrl_iface;
4988d4f2939cSRui Paulo 	struct wpa_dbus_object_desc *obj_desc;
4989d4f2939cSRui Paulo 	struct network_handler_args *arg;
4990d4f2939cSRui Paulo 	char pgrp_obj_path[WPAS_DBUS_OBJECT_PATH_MAX];
4991d4f2939cSRui Paulo 
4992d4f2939cSRui Paulo 	/* Do nothing if the control interface is not turned on */
4993d4f2939cSRui Paulo 	if (wpa_s == NULL || wpa_s->global == NULL)
4994d4f2939cSRui Paulo 		return 0;
4995325151a3SRui Paulo 	wpa_s = wpa_s->parent->parent;
4996325151a3SRui Paulo 	if (!wpa_s->dbus_new_path)
4997325151a3SRui Paulo 		return 0;
4998d4f2939cSRui Paulo 
4999d4f2939cSRui Paulo 	/* Make sure ssid is a persistent group */
5000d4f2939cSRui Paulo 	if (ssid->disabled != 2 && !ssid->p2p_persistent_group)
5001d4f2939cSRui Paulo 		return -1; /* should we return w/o complaining? */
5002d4f2939cSRui Paulo 
50035b9c547cSRui Paulo 	if (wpa_s->p2p_mgmt)
50045b9c547cSRui Paulo 		wpa_s = wpa_s->parent;
50055b9c547cSRui Paulo 
5006d4f2939cSRui Paulo 	ctrl_iface = wpa_s->global->dbus;
5007d4f2939cSRui Paulo 	if (ctrl_iface == NULL)
5008d4f2939cSRui Paulo 		return 0;
5009d4f2939cSRui Paulo 
5010d4f2939cSRui Paulo 	/*
5011d4f2939cSRui Paulo 	 * Intentionally not coming up with different numbering scheme
5012d4f2939cSRui Paulo 	 * for persistent groups.
5013d4f2939cSRui Paulo 	 */
5014d4f2939cSRui Paulo 	os_snprintf(pgrp_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
5015d4f2939cSRui Paulo 		    "%s/" WPAS_DBUS_NEW_PERSISTENT_GROUPS_PART "/%u",
5016d4f2939cSRui Paulo 		    wpa_s->dbus_new_path, ssid->id);
5017d4f2939cSRui Paulo 
5018d4f2939cSRui Paulo 	wpa_printf(MSG_DEBUG, "dbus: Register persistent group object '%s'",
5019d4f2939cSRui Paulo 		   pgrp_obj_path);
5020d4f2939cSRui Paulo 	obj_desc = os_zalloc(sizeof(struct wpa_dbus_object_desc));
5021d4f2939cSRui Paulo 	if (!obj_desc) {
50225b9c547cSRui Paulo 		wpa_printf(MSG_ERROR,
50235b9c547cSRui Paulo 			   "dbus: Not enough memory to create object description");
5024d4f2939cSRui Paulo 		goto err;
5025d4f2939cSRui Paulo 	}
5026d4f2939cSRui Paulo 
5027d4f2939cSRui Paulo 	/*
5028d4f2939cSRui Paulo 	 * Reusing the same context structure as that for networks
5029d4f2939cSRui Paulo 	 * since these are represented using same data structure.
5030d4f2939cSRui Paulo 	 */
5031d4f2939cSRui Paulo 	/* allocate memory for handlers arguments */
5032d4f2939cSRui Paulo 	arg = os_zalloc(sizeof(struct network_handler_args));
5033d4f2939cSRui Paulo 	if (!arg) {
50345b9c547cSRui Paulo 		wpa_printf(MSG_ERROR,
50355b9c547cSRui Paulo 			   "dbus: Not enough memory to create arguments for method");
5036d4f2939cSRui Paulo 		goto err;
5037d4f2939cSRui Paulo 	}
5038d4f2939cSRui Paulo 
5039d4f2939cSRui Paulo 	arg->wpa_s = wpa_s;
5040d4f2939cSRui Paulo 	arg->ssid = ssid;
5041d4f2939cSRui Paulo 
5042d4f2939cSRui Paulo 	wpas_dbus_register(obj_desc, arg, wpa_dbus_free, NULL,
5043d4f2939cSRui Paulo 			   wpas_dbus_persistent_group_properties,
5044d4f2939cSRui Paulo 			   NULL);
5045d4f2939cSRui Paulo 
5046d4f2939cSRui Paulo 	if (wpa_dbus_register_object_per_iface(ctrl_iface, pgrp_obj_path,
5047d4f2939cSRui Paulo 					       wpa_s->ifname, obj_desc))
5048d4f2939cSRui Paulo 		goto err;
5049d4f2939cSRui Paulo 
5050d4f2939cSRui Paulo 	wpas_dbus_signal_persistent_group_added(wpa_s, ssid->id);
5051d4f2939cSRui Paulo 
5052d4f2939cSRui Paulo 	return 0;
5053d4f2939cSRui Paulo 
5054d4f2939cSRui Paulo err:
5055d4f2939cSRui Paulo 	free_dbus_object_desc(obj_desc);
5056d4f2939cSRui Paulo 	return -1;
5057d4f2939cSRui Paulo }
5058d4f2939cSRui Paulo 
5059d4f2939cSRui Paulo 
5060d4f2939cSRui Paulo /**
5061d4f2939cSRui Paulo  * wpas_dbus_unregister_persistent_group - Unregister a persistent_group
5062d4f2939cSRui Paulo  *	from dbus
5063d4f2939cSRui Paulo  * @wpa_s: wpa_supplicant interface structure
5064d4f2939cSRui Paulo  * @nid: network id
5065d4f2939cSRui Paulo  * Returns: 0 on success, -1 on failure
5066d4f2939cSRui Paulo  *
5067d4f2939cSRui Paulo  * Unregisters persistent group representing object from dbus
5068d4f2939cSRui Paulo  *
5069d4f2939cSRui Paulo  * NOTE: There is a slight issue with the semantics here. While the
5070d4f2939cSRui Paulo  * implementation simply means the persistent group is unloaded from memory,
5071d4f2939cSRui Paulo  * it should not get interpreted as the group is actually being erased/removed
5072d4f2939cSRui Paulo  * from persistent storage as well.
5073d4f2939cSRui Paulo  */
5074d4f2939cSRui Paulo int wpas_dbus_unregister_persistent_group(struct wpa_supplicant *wpa_s,
5075d4f2939cSRui Paulo 					  int nid)
5076d4f2939cSRui Paulo {
5077d4f2939cSRui Paulo 	struct wpas_dbus_priv *ctrl_iface;
5078d4f2939cSRui Paulo 	char pgrp_obj_path[WPAS_DBUS_OBJECT_PATH_MAX];
5079d4f2939cSRui Paulo 	int ret;
5080d4f2939cSRui Paulo 
5081d4f2939cSRui Paulo 	/* Do nothing if the control interface is not turned on */
5082325151a3SRui Paulo 	if (wpa_s == NULL || wpa_s->global == NULL)
5083d4f2939cSRui Paulo 		return 0;
50845b9c547cSRui Paulo 
5085325151a3SRui Paulo 	wpa_s = wpa_s->parent->parent;
50865b9c547cSRui Paulo 
5087d4f2939cSRui Paulo 	ctrl_iface = wpa_s->global->dbus;
5088325151a3SRui Paulo 	if (ctrl_iface == NULL || !wpa_s->dbus_new_path)
5089d4f2939cSRui Paulo 		return 0;
5090d4f2939cSRui Paulo 
5091d4f2939cSRui Paulo 	os_snprintf(pgrp_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
5092d4f2939cSRui Paulo 		    "%s/" WPAS_DBUS_NEW_PERSISTENT_GROUPS_PART "/%u",
5093d4f2939cSRui Paulo 		    wpa_s->dbus_new_path, nid);
5094d4f2939cSRui Paulo 
5095d4f2939cSRui Paulo 	wpa_printf(MSG_DEBUG, "dbus: Unregister persistent group object '%s'",
5096d4f2939cSRui Paulo 		   pgrp_obj_path);
5097d4f2939cSRui Paulo 	ret = wpa_dbus_unregister_object_per_iface(ctrl_iface, pgrp_obj_path);
5098d4f2939cSRui Paulo 
5099d4f2939cSRui Paulo 	if (!ret)
5100d4f2939cSRui Paulo 		wpas_dbus_signal_persistent_group_removed(wpa_s, nid);
5101d4f2939cSRui Paulo 
5102d4f2939cSRui Paulo 	return ret;
5103d4f2939cSRui Paulo }
5104d4f2939cSRui Paulo 
5105d4f2939cSRui Paulo #endif /* CONFIG_P2P */
5106