xref: /freebsd/contrib/wpa/wpa_supplicant/dbus/dbus_new.c (revision 780fb4a2fa9a9aee5ac48a60b790f567c0dc13e9)
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"
16d4f2939cSRui Paulo #include "../config.h"
17d4f2939cSRui Paulo #include "../wpa_supplicant_i.h"
18d4f2939cSRui Paulo #include "../bss.h"
19d4f2939cSRui Paulo #include "../wpas_glue.h"
20d4f2939cSRui Paulo #include "dbus_new_helpers.h"
21d4f2939cSRui Paulo #include "dbus_dict_helpers.h"
22d4f2939cSRui Paulo #include "dbus_new.h"
23d4f2939cSRui Paulo #include "dbus_new_handlers.h"
24d4f2939cSRui Paulo #include "dbus_common_i.h"
25d4f2939cSRui Paulo #include "dbus_new_handlers_p2p.h"
26d4f2939cSRui Paulo #include "p2p/p2p.h"
275b9c547cSRui Paulo #include "../p2p_supplicant.h"
28d4f2939cSRui Paulo 
29d4f2939cSRui Paulo #ifdef CONFIG_AP /* until needed by something else */
30d4f2939cSRui Paulo 
31d4f2939cSRui Paulo /*
32d4f2939cSRui Paulo  * NameOwnerChanged handling
33d4f2939cSRui Paulo  *
34d4f2939cSRui Paulo  * Some services we provide allow an application to register for
35d4f2939cSRui Paulo  * a signal that it needs. While it can also unregister, we must
36d4f2939cSRui Paulo  * be prepared for the case where the application simply crashes
37d4f2939cSRui Paulo  * and thus doesn't clean up properly. The way to handle this in
38d4f2939cSRui Paulo  * DBus is to register for the NameOwnerChanged signal which will
39d4f2939cSRui Paulo  * signal an owner change to NULL if the peer closes the socket
40d4f2939cSRui Paulo  * for whatever reason.
41d4f2939cSRui Paulo  *
42d4f2939cSRui Paulo  * Handle this signal via a filter function whenever necessary.
43d4f2939cSRui Paulo  * The code below also handles refcounting in case in the future
44d4f2939cSRui Paulo  * there will be multiple instances of this subscription scheme.
45d4f2939cSRui Paulo  */
46d4f2939cSRui Paulo static const char wpas_dbus_noc_filter_str[] =
47d4f2939cSRui Paulo 	"interface=org.freedesktop.DBus,member=NameOwnerChanged";
48d4f2939cSRui Paulo 
49d4f2939cSRui Paulo 
50d4f2939cSRui Paulo static DBusHandlerResult noc_filter(DBusConnection *conn,
51d4f2939cSRui Paulo 				    DBusMessage *message, void *data)
52d4f2939cSRui Paulo {
53d4f2939cSRui Paulo 	struct wpas_dbus_priv *priv = data;
54d4f2939cSRui Paulo 
55d4f2939cSRui Paulo 	if (dbus_message_get_type(message) != DBUS_MESSAGE_TYPE_SIGNAL)
56d4f2939cSRui Paulo 		return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
57d4f2939cSRui Paulo 
58d4f2939cSRui Paulo 	if (dbus_message_is_signal(message, DBUS_INTERFACE_DBUS,
59d4f2939cSRui Paulo 				   "NameOwnerChanged")) {
60d4f2939cSRui Paulo 		const char *name;
61d4f2939cSRui Paulo 		const char *prev_owner;
62d4f2939cSRui Paulo 		const char *new_owner;
63d4f2939cSRui Paulo 		DBusError derr;
64d4f2939cSRui Paulo 		struct wpa_supplicant *wpa_s;
65d4f2939cSRui Paulo 
66d4f2939cSRui Paulo 		dbus_error_init(&derr);
67d4f2939cSRui Paulo 
68d4f2939cSRui Paulo 		if (!dbus_message_get_args(message, &derr,
69d4f2939cSRui Paulo 					   DBUS_TYPE_STRING, &name,
70d4f2939cSRui Paulo 					   DBUS_TYPE_STRING, &prev_owner,
71d4f2939cSRui Paulo 					   DBUS_TYPE_STRING, &new_owner,
72d4f2939cSRui Paulo 					   DBUS_TYPE_INVALID)) {
73d4f2939cSRui Paulo 			/* Ignore this error */
74d4f2939cSRui Paulo 			dbus_error_free(&derr);
75d4f2939cSRui Paulo 			return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
76d4f2939cSRui Paulo 		}
77d4f2939cSRui Paulo 
785b9c547cSRui Paulo 		for (wpa_s = priv->global->ifaces; wpa_s; wpa_s = wpa_s->next) {
79d4f2939cSRui Paulo 			if (wpa_s->preq_notify_peer != NULL &&
80d4f2939cSRui Paulo 			    os_strcmp(name, wpa_s->preq_notify_peer) == 0 &&
81d4f2939cSRui Paulo 			    (new_owner == NULL || os_strlen(new_owner) == 0)) {
82d4f2939cSRui Paulo 				/* probe request owner disconnected */
83d4f2939cSRui Paulo 				os_free(wpa_s->preq_notify_peer);
84d4f2939cSRui Paulo 				wpa_s->preq_notify_peer = NULL;
85d4f2939cSRui Paulo 				wpas_dbus_unsubscribe_noc(priv);
86d4f2939cSRui Paulo 			}
87d4f2939cSRui Paulo 		}
88d4f2939cSRui Paulo 	}
89d4f2939cSRui Paulo 
90d4f2939cSRui Paulo 	return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
91d4f2939cSRui Paulo }
92d4f2939cSRui Paulo 
93d4f2939cSRui Paulo 
94d4f2939cSRui Paulo void wpas_dbus_subscribe_noc(struct wpas_dbus_priv *priv)
95d4f2939cSRui Paulo {
96d4f2939cSRui Paulo 	priv->dbus_noc_refcnt++;
97d4f2939cSRui Paulo 	if (priv->dbus_noc_refcnt > 1)
98d4f2939cSRui Paulo 		return;
99d4f2939cSRui Paulo 
100d4f2939cSRui Paulo 	if (!dbus_connection_add_filter(priv->con, noc_filter, priv, NULL)) {
101d4f2939cSRui Paulo 		wpa_printf(MSG_ERROR, "dbus: failed to add filter");
102d4f2939cSRui Paulo 		return;
103d4f2939cSRui Paulo 	}
104d4f2939cSRui Paulo 
105d4f2939cSRui Paulo 	dbus_bus_add_match(priv->con, wpas_dbus_noc_filter_str, NULL);
106d4f2939cSRui Paulo }
107d4f2939cSRui Paulo 
108d4f2939cSRui Paulo 
109d4f2939cSRui Paulo void wpas_dbus_unsubscribe_noc(struct wpas_dbus_priv *priv)
110d4f2939cSRui Paulo {
111d4f2939cSRui Paulo 	priv->dbus_noc_refcnt--;
112d4f2939cSRui Paulo 	if (priv->dbus_noc_refcnt > 0)
113d4f2939cSRui Paulo 		return;
114d4f2939cSRui Paulo 
115d4f2939cSRui Paulo 	dbus_bus_remove_match(priv->con, wpas_dbus_noc_filter_str, NULL);
116d4f2939cSRui Paulo 	dbus_connection_remove_filter(priv->con, noc_filter, priv);
117d4f2939cSRui Paulo }
118d4f2939cSRui Paulo 
119d4f2939cSRui Paulo #endif /* CONFIG_AP */
120d4f2939cSRui Paulo 
121d4f2939cSRui Paulo 
122d4f2939cSRui Paulo /**
123d4f2939cSRui Paulo  * wpas_dbus_signal_interface - Send a interface related event signal
124d4f2939cSRui Paulo  * @wpa_s: %wpa_supplicant network interface data
125d4f2939cSRui Paulo  * @sig_name: signal name - InterfaceAdded or InterfaceRemoved
126d4f2939cSRui Paulo  * @properties: Whether to add second argument with object properties
127d4f2939cSRui Paulo  *
128d4f2939cSRui Paulo  * Notify listeners about event related with interface
129d4f2939cSRui Paulo  */
130d4f2939cSRui Paulo static void wpas_dbus_signal_interface(struct wpa_supplicant *wpa_s,
131d4f2939cSRui Paulo 				       const char *sig_name, int properties)
132d4f2939cSRui Paulo {
133d4f2939cSRui Paulo 	struct wpas_dbus_priv *iface;
134d4f2939cSRui Paulo 	DBusMessage *msg;
135d4f2939cSRui Paulo 	DBusMessageIter iter;
136d4f2939cSRui Paulo 
137d4f2939cSRui Paulo 	iface = wpa_s->global->dbus;
138d4f2939cSRui Paulo 
139d4f2939cSRui Paulo 	/* Do nothing if the control interface is not turned on */
140325151a3SRui Paulo 	if (iface == NULL || !wpa_s->dbus_new_path)
141d4f2939cSRui Paulo 		return;
142d4f2939cSRui Paulo 
143d4f2939cSRui Paulo 	msg = dbus_message_new_signal(WPAS_DBUS_NEW_PATH,
144d4f2939cSRui Paulo 				      WPAS_DBUS_NEW_INTERFACE, sig_name);
145d4f2939cSRui Paulo 	if (msg == NULL)
146d4f2939cSRui Paulo 		return;
147d4f2939cSRui Paulo 
148d4f2939cSRui Paulo 	dbus_message_iter_init_append(msg, &iter);
149d4f2939cSRui Paulo 	if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_OBJECT_PATH,
1505b9c547cSRui Paulo 					    &wpa_s->dbus_new_path) ||
1515b9c547cSRui Paulo 	    (properties &&
1525b9c547cSRui Paulo 	     !wpa_dbus_get_object_properties(
153d4f2939cSRui Paulo 		     iface, wpa_s->dbus_new_path,
1545b9c547cSRui Paulo 		     WPAS_DBUS_NEW_IFACE_INTERFACE, &iter)))
155d4f2939cSRui Paulo 		wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
1565b9c547cSRui Paulo 	else
1575b9c547cSRui Paulo 		dbus_connection_send(iface->con, msg, NULL);
158d4f2939cSRui Paulo 	dbus_message_unref(msg);
159d4f2939cSRui Paulo }
160d4f2939cSRui Paulo 
161d4f2939cSRui Paulo 
162d4f2939cSRui Paulo /**
163d4f2939cSRui Paulo  * wpas_dbus_signal_interface_added - Send a interface created signal
164d4f2939cSRui Paulo  * @wpa_s: %wpa_supplicant network interface data
165d4f2939cSRui Paulo  *
166d4f2939cSRui Paulo  * Notify listeners about creating new interface
167d4f2939cSRui Paulo  */
168d4f2939cSRui Paulo static void wpas_dbus_signal_interface_added(struct wpa_supplicant *wpa_s)
169d4f2939cSRui Paulo {
170d4f2939cSRui Paulo 	wpas_dbus_signal_interface(wpa_s, "InterfaceAdded", TRUE);
171d4f2939cSRui Paulo }
172d4f2939cSRui Paulo 
173d4f2939cSRui Paulo 
174d4f2939cSRui Paulo /**
175d4f2939cSRui Paulo  * wpas_dbus_signal_interface_removed - Send a interface removed signal
176d4f2939cSRui Paulo  * @wpa_s: %wpa_supplicant network interface data
177d4f2939cSRui Paulo  *
178d4f2939cSRui Paulo  * Notify listeners about removing interface
179d4f2939cSRui Paulo  */
180d4f2939cSRui Paulo static void wpas_dbus_signal_interface_removed(struct wpa_supplicant *wpa_s)
181d4f2939cSRui Paulo {
182d4f2939cSRui Paulo 	wpas_dbus_signal_interface(wpa_s, "InterfaceRemoved", FALSE);
183d4f2939cSRui Paulo 
184d4f2939cSRui Paulo }
185d4f2939cSRui Paulo 
186d4f2939cSRui Paulo 
187d4f2939cSRui Paulo /**
188d4f2939cSRui Paulo  * wpas_dbus_signal_scan_done - send scan done signal
189d4f2939cSRui Paulo  * @wpa_s: %wpa_supplicant network interface data
190d4f2939cSRui Paulo  * @success: indicates if scanning succeed or failed
191d4f2939cSRui Paulo  *
192d4f2939cSRui Paulo  * Notify listeners about finishing a scan
193d4f2939cSRui Paulo  */
194d4f2939cSRui Paulo void wpas_dbus_signal_scan_done(struct wpa_supplicant *wpa_s, int success)
195d4f2939cSRui Paulo {
196d4f2939cSRui Paulo 	struct wpas_dbus_priv *iface;
197d4f2939cSRui Paulo 	DBusMessage *msg;
198d4f2939cSRui Paulo 	dbus_bool_t succ;
199d4f2939cSRui Paulo 
200d4f2939cSRui Paulo 	iface = wpa_s->global->dbus;
201d4f2939cSRui Paulo 
202d4f2939cSRui Paulo 	/* Do nothing if the control interface is not turned on */
203325151a3SRui Paulo 	if (iface == NULL || !wpa_s->dbus_new_path)
204d4f2939cSRui Paulo 		return;
205d4f2939cSRui Paulo 
206d4f2939cSRui Paulo 	msg = dbus_message_new_signal(wpa_s->dbus_new_path,
207d4f2939cSRui Paulo 				      WPAS_DBUS_NEW_IFACE_INTERFACE,
208d4f2939cSRui Paulo 				      "ScanDone");
209d4f2939cSRui Paulo 	if (msg == NULL)
210d4f2939cSRui Paulo 		return;
211d4f2939cSRui Paulo 
212d4f2939cSRui Paulo 	succ = success ? TRUE : FALSE;
213d4f2939cSRui Paulo 	if (dbus_message_append_args(msg, DBUS_TYPE_BOOLEAN, &succ,
214d4f2939cSRui Paulo 				     DBUS_TYPE_INVALID))
215d4f2939cSRui Paulo 		dbus_connection_send(iface->con, msg, NULL);
216d4f2939cSRui Paulo 	else
217d4f2939cSRui Paulo 		wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
218d4f2939cSRui Paulo 	dbus_message_unref(msg);
219d4f2939cSRui Paulo }
220d4f2939cSRui Paulo 
221d4f2939cSRui Paulo 
222d4f2939cSRui Paulo /**
2235b9c547cSRui Paulo  * wpas_dbus_signal_bss - Send a BSS related event signal
224d4f2939cSRui Paulo  * @wpa_s: %wpa_supplicant network interface data
225d4f2939cSRui Paulo  * @bss_obj_path: BSS object path
226d4f2939cSRui Paulo  * @sig_name: signal name - BSSAdded or BSSRemoved
227d4f2939cSRui Paulo  * @properties: Whether to add second argument with object properties
228d4f2939cSRui Paulo  *
229d4f2939cSRui Paulo  * Notify listeners about event related with BSS
230d4f2939cSRui Paulo  */
231d4f2939cSRui Paulo static void wpas_dbus_signal_bss(struct wpa_supplicant *wpa_s,
232d4f2939cSRui Paulo 				 const char *bss_obj_path,
233d4f2939cSRui Paulo 				 const char *sig_name, int properties)
234d4f2939cSRui Paulo {
235d4f2939cSRui Paulo 	struct wpas_dbus_priv *iface;
236d4f2939cSRui Paulo 	DBusMessage *msg;
237d4f2939cSRui Paulo 	DBusMessageIter iter;
238d4f2939cSRui Paulo 
239d4f2939cSRui Paulo 	iface = wpa_s->global->dbus;
240d4f2939cSRui Paulo 
241d4f2939cSRui Paulo 	/* Do nothing if the control interface is not turned on */
242325151a3SRui Paulo 	if (iface == NULL || !wpa_s->dbus_new_path)
243d4f2939cSRui Paulo 		return;
244d4f2939cSRui Paulo 
245d4f2939cSRui Paulo 	msg = dbus_message_new_signal(wpa_s->dbus_new_path,
246d4f2939cSRui Paulo 				      WPAS_DBUS_NEW_IFACE_INTERFACE,
247d4f2939cSRui Paulo 				      sig_name);
248d4f2939cSRui Paulo 	if (msg == NULL)
249d4f2939cSRui Paulo 		return;
250d4f2939cSRui Paulo 
251d4f2939cSRui Paulo 	dbus_message_iter_init_append(msg, &iter);
252d4f2939cSRui Paulo 	if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_OBJECT_PATH,
2535b9c547cSRui Paulo 					    &bss_obj_path) ||
2545b9c547cSRui Paulo 	    (properties &&
2555b9c547cSRui Paulo 	     !wpa_dbus_get_object_properties(iface, bss_obj_path,
256d4f2939cSRui Paulo 					     WPAS_DBUS_NEW_IFACE_BSS,
2575b9c547cSRui Paulo 					     &iter)))
258d4f2939cSRui Paulo 		wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
2595b9c547cSRui Paulo 	else
2605b9c547cSRui Paulo 		dbus_connection_send(iface->con, msg, NULL);
261d4f2939cSRui Paulo 	dbus_message_unref(msg);
262d4f2939cSRui Paulo }
263d4f2939cSRui Paulo 
264d4f2939cSRui Paulo 
265d4f2939cSRui Paulo /**
266d4f2939cSRui Paulo  * wpas_dbus_signal_bss_added - Send a BSS added signal
267d4f2939cSRui Paulo  * @wpa_s: %wpa_supplicant network interface data
268d4f2939cSRui Paulo  * @bss_obj_path: new BSS object path
269d4f2939cSRui Paulo  *
270d4f2939cSRui Paulo  * Notify listeners about adding new BSS
271d4f2939cSRui Paulo  */
272d4f2939cSRui Paulo static void wpas_dbus_signal_bss_added(struct wpa_supplicant *wpa_s,
273d4f2939cSRui Paulo 				       const char *bss_obj_path)
274d4f2939cSRui Paulo {
275d4f2939cSRui Paulo 	wpas_dbus_signal_bss(wpa_s, bss_obj_path, "BSSAdded", TRUE);
276d4f2939cSRui Paulo }
277d4f2939cSRui Paulo 
278d4f2939cSRui Paulo 
279d4f2939cSRui Paulo /**
280d4f2939cSRui Paulo  * wpas_dbus_signal_bss_removed - Send a BSS removed signal
281d4f2939cSRui Paulo  * @wpa_s: %wpa_supplicant network interface data
282d4f2939cSRui Paulo  * @bss_obj_path: BSS object path
283d4f2939cSRui Paulo  *
284d4f2939cSRui Paulo  * Notify listeners about removing BSS
285d4f2939cSRui Paulo  */
286d4f2939cSRui Paulo static void wpas_dbus_signal_bss_removed(struct wpa_supplicant *wpa_s,
287d4f2939cSRui Paulo 					 const char *bss_obj_path)
288d4f2939cSRui Paulo {
289d4f2939cSRui Paulo 	wpas_dbus_signal_bss(wpa_s, bss_obj_path, "BSSRemoved", FALSE);
290d4f2939cSRui Paulo }
291d4f2939cSRui Paulo 
292d4f2939cSRui Paulo 
293d4f2939cSRui Paulo /**
294d4f2939cSRui Paulo  * wpas_dbus_signal_blob - Send a blob related event signal
295d4f2939cSRui Paulo  * @wpa_s: %wpa_supplicant network interface data
296d4f2939cSRui Paulo  * @name: blob name
297d4f2939cSRui Paulo  * @sig_name: signal name - BlobAdded or BlobRemoved
298d4f2939cSRui Paulo  *
299d4f2939cSRui Paulo  * Notify listeners about event related with blob
300d4f2939cSRui Paulo  */
301d4f2939cSRui Paulo static void wpas_dbus_signal_blob(struct wpa_supplicant *wpa_s,
302d4f2939cSRui Paulo 				  const char *name, const char *sig_name)
303d4f2939cSRui Paulo {
304d4f2939cSRui Paulo 	struct wpas_dbus_priv *iface;
305d4f2939cSRui Paulo 	DBusMessage *msg;
306d4f2939cSRui Paulo 
307d4f2939cSRui Paulo 	iface = wpa_s->global->dbus;
308d4f2939cSRui Paulo 
309d4f2939cSRui Paulo 	/* Do nothing if the control interface is not turned on */
310325151a3SRui Paulo 	if (iface == NULL || !wpa_s->dbus_new_path)
311d4f2939cSRui Paulo 		return;
312d4f2939cSRui Paulo 
313d4f2939cSRui Paulo 	msg = dbus_message_new_signal(wpa_s->dbus_new_path,
314d4f2939cSRui Paulo 				      WPAS_DBUS_NEW_IFACE_INTERFACE,
315d4f2939cSRui Paulo 				      sig_name);
316d4f2939cSRui Paulo 	if (msg == NULL)
317d4f2939cSRui Paulo 		return;
318d4f2939cSRui Paulo 
319d4f2939cSRui Paulo 	if (dbus_message_append_args(msg, DBUS_TYPE_STRING, &name,
320d4f2939cSRui Paulo 				     DBUS_TYPE_INVALID))
321d4f2939cSRui Paulo 		dbus_connection_send(iface->con, msg, NULL);
322d4f2939cSRui Paulo 	else
323d4f2939cSRui Paulo 		wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
324d4f2939cSRui Paulo 	dbus_message_unref(msg);
325d4f2939cSRui Paulo }
326d4f2939cSRui Paulo 
327d4f2939cSRui Paulo 
328d4f2939cSRui Paulo /**
329d4f2939cSRui Paulo  * wpas_dbus_signal_blob_added - Send a blob added signal
330d4f2939cSRui Paulo  * @wpa_s: %wpa_supplicant network interface data
331d4f2939cSRui Paulo  * @name: blob name
332d4f2939cSRui Paulo  *
333d4f2939cSRui Paulo  * Notify listeners about adding a new blob
334d4f2939cSRui Paulo  */
335d4f2939cSRui Paulo void wpas_dbus_signal_blob_added(struct wpa_supplicant *wpa_s,
336d4f2939cSRui Paulo 				 const char *name)
337d4f2939cSRui Paulo {
338d4f2939cSRui Paulo 	wpas_dbus_signal_blob(wpa_s, name, "BlobAdded");
339d4f2939cSRui Paulo }
340d4f2939cSRui Paulo 
341d4f2939cSRui Paulo 
342d4f2939cSRui Paulo /**
343d4f2939cSRui Paulo  * wpas_dbus_signal_blob_removed - Send a blob removed signal
344d4f2939cSRui Paulo  * @wpa_s: %wpa_supplicant network interface data
345d4f2939cSRui Paulo  * @name: blob name
346d4f2939cSRui Paulo  *
347d4f2939cSRui Paulo  * Notify listeners about removing blob
348d4f2939cSRui Paulo  */
349d4f2939cSRui Paulo void wpas_dbus_signal_blob_removed(struct wpa_supplicant *wpa_s,
350d4f2939cSRui Paulo 				   const char *name)
351d4f2939cSRui Paulo {
352d4f2939cSRui Paulo 	wpas_dbus_signal_blob(wpa_s, name, "BlobRemoved");
353d4f2939cSRui Paulo }
354d4f2939cSRui Paulo 
355d4f2939cSRui Paulo 
356d4f2939cSRui Paulo /**
357d4f2939cSRui Paulo  * wpas_dbus_signal_network - Send a network related event signal
358d4f2939cSRui Paulo  * @wpa_s: %wpa_supplicant network interface data
359d4f2939cSRui Paulo  * @id: new network id
360d4f2939cSRui Paulo  * @sig_name: signal name - NetworkAdded, NetworkRemoved or NetworkSelected
361d4f2939cSRui Paulo  * @properties: determines if add second argument with object properties
362d4f2939cSRui Paulo  *
363d4f2939cSRui Paulo  * Notify listeners about event related with configured network
364d4f2939cSRui Paulo  */
365d4f2939cSRui Paulo static void wpas_dbus_signal_network(struct wpa_supplicant *wpa_s,
366d4f2939cSRui Paulo 				     int id, const char *sig_name,
367d4f2939cSRui Paulo 				     int properties)
368d4f2939cSRui Paulo {
369d4f2939cSRui Paulo 	struct wpas_dbus_priv *iface;
370d4f2939cSRui Paulo 	DBusMessage *msg;
371d4f2939cSRui Paulo 	DBusMessageIter iter;
372d4f2939cSRui Paulo 	char net_obj_path[WPAS_DBUS_OBJECT_PATH_MAX], *path;
373d4f2939cSRui Paulo 
374d4f2939cSRui Paulo 	iface = wpa_s->global->dbus;
375d4f2939cSRui Paulo 
376d4f2939cSRui Paulo 	/* Do nothing if the control interface is not turned on */
377325151a3SRui Paulo 	if (iface == NULL || !wpa_s->dbus_new_path)
378d4f2939cSRui Paulo 		return;
379d4f2939cSRui Paulo 
380d4f2939cSRui Paulo 	os_snprintf(net_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
381d4f2939cSRui Paulo 		    "%s/" WPAS_DBUS_NEW_NETWORKS_PART "/%u",
382d4f2939cSRui Paulo 		    wpa_s->dbus_new_path, id);
383d4f2939cSRui Paulo 
384d4f2939cSRui Paulo 	msg = dbus_message_new_signal(wpa_s->dbus_new_path,
385d4f2939cSRui Paulo 				      WPAS_DBUS_NEW_IFACE_INTERFACE,
386d4f2939cSRui Paulo 				      sig_name);
387d4f2939cSRui Paulo 	if (msg == NULL)
388d4f2939cSRui Paulo 		return;
389d4f2939cSRui Paulo 
390d4f2939cSRui Paulo 	dbus_message_iter_init_append(msg, &iter);
391d4f2939cSRui Paulo 	path = net_obj_path;
392d4f2939cSRui Paulo 	if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_OBJECT_PATH,
3935b9c547cSRui Paulo 					    &path) ||
3945b9c547cSRui Paulo 	    (properties &&
3955b9c547cSRui Paulo 	     !wpa_dbus_get_object_properties(
396d4f2939cSRui Paulo 		     iface, net_obj_path, WPAS_DBUS_NEW_IFACE_NETWORK,
3975b9c547cSRui Paulo 		     &iter)))
398d4f2939cSRui Paulo 		wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
3995b9c547cSRui Paulo 	else
4005b9c547cSRui Paulo 		dbus_connection_send(iface->con, msg, NULL);
401d4f2939cSRui Paulo 	dbus_message_unref(msg);
402d4f2939cSRui Paulo }
403d4f2939cSRui Paulo 
404d4f2939cSRui Paulo 
405d4f2939cSRui Paulo /**
406d4f2939cSRui Paulo  * wpas_dbus_signal_network_added - Send a network added signal
407d4f2939cSRui Paulo  * @wpa_s: %wpa_supplicant network interface data
408d4f2939cSRui Paulo  * @id: new network id
409d4f2939cSRui Paulo  *
410d4f2939cSRui Paulo  * Notify listeners about adding new network
411d4f2939cSRui Paulo  */
412d4f2939cSRui Paulo static void wpas_dbus_signal_network_added(struct wpa_supplicant *wpa_s,
413d4f2939cSRui Paulo 					   int id)
414d4f2939cSRui Paulo {
415d4f2939cSRui Paulo 	wpas_dbus_signal_network(wpa_s, id, "NetworkAdded", TRUE);
416d4f2939cSRui Paulo }
417d4f2939cSRui Paulo 
418d4f2939cSRui Paulo 
419d4f2939cSRui Paulo /**
420d4f2939cSRui Paulo  * wpas_dbus_signal_network_removed - Send a network removed signal
421d4f2939cSRui Paulo  * @wpa_s: %wpa_supplicant network interface data
422d4f2939cSRui Paulo  * @id: network id
423d4f2939cSRui Paulo  *
424d4f2939cSRui Paulo  * Notify listeners about removing a network
425d4f2939cSRui Paulo  */
426d4f2939cSRui Paulo static void wpas_dbus_signal_network_removed(struct wpa_supplicant *wpa_s,
427d4f2939cSRui Paulo 					     int id)
428d4f2939cSRui Paulo {
429d4f2939cSRui Paulo 	wpas_dbus_signal_network(wpa_s, id, "NetworkRemoved", FALSE);
430d4f2939cSRui Paulo }
431d4f2939cSRui Paulo 
432d4f2939cSRui Paulo 
433d4f2939cSRui Paulo /**
434d4f2939cSRui Paulo  * wpas_dbus_signal_network_selected - Send a network selected signal
435d4f2939cSRui Paulo  * @wpa_s: %wpa_supplicant network interface data
436d4f2939cSRui Paulo  * @id: network id
437d4f2939cSRui Paulo  *
438d4f2939cSRui Paulo  * Notify listeners about selecting a network
439d4f2939cSRui Paulo  */
440d4f2939cSRui Paulo void wpas_dbus_signal_network_selected(struct wpa_supplicant *wpa_s, int id)
441d4f2939cSRui Paulo {
442d4f2939cSRui Paulo 	wpas_dbus_signal_network(wpa_s, id, "NetworkSelected", FALSE);
443d4f2939cSRui Paulo }
444d4f2939cSRui Paulo 
445d4f2939cSRui Paulo 
446d4f2939cSRui Paulo /**
447d4f2939cSRui Paulo  * wpas_dbus_signal_network_request - Indicate that additional information
448d4f2939cSRui Paulo  * (EAP password, etc.) is required to complete the association to this SSID
449d4f2939cSRui Paulo  * @wpa_s: %wpa_supplicant network interface data
450d4f2939cSRui Paulo  * @rtype: The specific additional information required
451d4f2939cSRui Paulo  * @default_text: Optional description of required information
452d4f2939cSRui Paulo  *
453d4f2939cSRui Paulo  * Request additional information or passwords to complete an association
454d4f2939cSRui Paulo  * request.
455d4f2939cSRui Paulo  */
456d4f2939cSRui Paulo void wpas_dbus_signal_network_request(struct wpa_supplicant *wpa_s,
457d4f2939cSRui Paulo 				      struct wpa_ssid *ssid,
458d4f2939cSRui Paulo 				      enum wpa_ctrl_req_type rtype,
459d4f2939cSRui Paulo 				      const char *default_txt)
460d4f2939cSRui Paulo {
461d4f2939cSRui Paulo 	struct wpas_dbus_priv *iface;
462d4f2939cSRui Paulo 	DBusMessage *msg;
463d4f2939cSRui Paulo 	DBusMessageIter iter;
464d4f2939cSRui Paulo 	char net_obj_path[WPAS_DBUS_OBJECT_PATH_MAX];
465d4f2939cSRui Paulo 	const char *field, *txt = NULL, *net_ptr;
466d4f2939cSRui Paulo 
467d4f2939cSRui Paulo 	iface = wpa_s->global->dbus;
468d4f2939cSRui Paulo 
469d4f2939cSRui Paulo 	/* Do nothing if the control interface is not turned on */
470325151a3SRui Paulo 	if (iface == NULL || !wpa_s->dbus_new_path)
471d4f2939cSRui Paulo 		return;
472d4f2939cSRui Paulo 
473d4f2939cSRui Paulo 	field = wpa_supplicant_ctrl_req_to_string(rtype, default_txt, &txt);
474d4f2939cSRui Paulo 	if (field == NULL)
475d4f2939cSRui Paulo 		return;
476d4f2939cSRui Paulo 
477d4f2939cSRui Paulo 	msg = dbus_message_new_signal(wpa_s->dbus_new_path,
478d4f2939cSRui Paulo 				      WPAS_DBUS_NEW_IFACE_INTERFACE,
479d4f2939cSRui Paulo 				      "NetworkRequest");
480d4f2939cSRui Paulo 	if (msg == NULL)
481d4f2939cSRui Paulo 		return;
482d4f2939cSRui Paulo 
483d4f2939cSRui Paulo 	os_snprintf(net_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
484d4f2939cSRui Paulo 		    "%s/" WPAS_DBUS_NEW_NETWORKS_PART "/%u",
485d4f2939cSRui Paulo 		    wpa_s->dbus_new_path, ssid->id);
486d4f2939cSRui Paulo 	net_ptr = &net_obj_path[0];
487d4f2939cSRui Paulo 
488d4f2939cSRui Paulo 	dbus_message_iter_init_append(msg, &iter);
489d4f2939cSRui Paulo 	if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_OBJECT_PATH,
4905b9c547cSRui Paulo 					    &net_ptr) ||
4915b9c547cSRui Paulo 	    !dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &field) ||
4925b9c547cSRui Paulo 	    !dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &txt))
493d4f2939cSRui Paulo 		wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
4945b9c547cSRui Paulo 	else
4955b9c547cSRui Paulo 		dbus_connection_send(iface->con, msg, NULL);
496d4f2939cSRui Paulo 	dbus_message_unref(msg);
497d4f2939cSRui Paulo }
498d4f2939cSRui Paulo 
499d4f2939cSRui Paulo 
500d4f2939cSRui Paulo /**
501d4f2939cSRui Paulo  * wpas_dbus_signal_network_enabled_changed - Signals Enabled property changes
502d4f2939cSRui Paulo  * @wpa_s: %wpa_supplicant network interface data
503d4f2939cSRui Paulo  * @ssid: configured network which Enabled property has changed
504d4f2939cSRui Paulo  *
505d4f2939cSRui Paulo  * Sends PropertyChanged signals containing new value of Enabled property
506d4f2939cSRui Paulo  * for specified network
507d4f2939cSRui Paulo  */
508d4f2939cSRui Paulo void wpas_dbus_signal_network_enabled_changed(struct wpa_supplicant *wpa_s,
509d4f2939cSRui Paulo 					      struct wpa_ssid *ssid)
510d4f2939cSRui Paulo {
511d4f2939cSRui Paulo 
512d4f2939cSRui Paulo 	char path[WPAS_DBUS_OBJECT_PATH_MAX];
5135b9c547cSRui Paulo 
514325151a3SRui Paulo 	if (!wpa_s->dbus_new_path)
515325151a3SRui Paulo 		return;
516d4f2939cSRui Paulo 	os_snprintf(path, WPAS_DBUS_OBJECT_PATH_MAX,
517d4f2939cSRui Paulo 		    "%s/" WPAS_DBUS_NEW_NETWORKS_PART "/%d",
518d4f2939cSRui Paulo 		    wpa_s->dbus_new_path, ssid->id);
519d4f2939cSRui Paulo 
520d4f2939cSRui Paulo 	wpa_dbus_mark_property_changed(wpa_s->global->dbus, path,
521d4f2939cSRui Paulo 				       WPAS_DBUS_NEW_IFACE_NETWORK, "Enabled");
522d4f2939cSRui Paulo }
523d4f2939cSRui Paulo 
524d4f2939cSRui Paulo 
525d4f2939cSRui Paulo #ifdef CONFIG_WPS
526d4f2939cSRui Paulo 
527d4f2939cSRui Paulo /**
528325151a3SRui Paulo  * wpas_dbus_signal_wps_event_pbc_overlap - Signals PBC overlap WPS event
529325151a3SRui Paulo  * @wpa_s: %wpa_supplicant network interface data
530325151a3SRui Paulo  *
531325151a3SRui Paulo  * Sends Event dbus signal with name "pbc-overlap" and empty dict as arguments
532325151a3SRui Paulo  */
533325151a3SRui Paulo void wpas_dbus_signal_wps_event_pbc_overlap(struct wpa_supplicant *wpa_s)
534325151a3SRui Paulo {
535325151a3SRui Paulo 
536325151a3SRui Paulo 	DBusMessage *msg;
537325151a3SRui Paulo 	DBusMessageIter iter, dict_iter;
538325151a3SRui Paulo 	struct wpas_dbus_priv *iface;
539325151a3SRui Paulo 	char *key = "pbc-overlap";
540325151a3SRui Paulo 
541325151a3SRui Paulo 	iface = wpa_s->global->dbus;
542325151a3SRui Paulo 
543325151a3SRui Paulo 	/* Do nothing if the control interface is not turned on */
544325151a3SRui Paulo 	if (iface == NULL || !wpa_s->dbus_new_path)
545325151a3SRui Paulo 		return;
546325151a3SRui Paulo 
547325151a3SRui Paulo 	msg = dbus_message_new_signal(wpa_s->dbus_new_path,
548325151a3SRui Paulo 				      WPAS_DBUS_NEW_IFACE_WPS, "Event");
549325151a3SRui Paulo 	if (msg == NULL)
550325151a3SRui Paulo 		return;
551325151a3SRui Paulo 
552325151a3SRui Paulo 	dbus_message_iter_init_append(msg, &iter);
553325151a3SRui Paulo 
554325151a3SRui Paulo 	if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &key) ||
555325151a3SRui Paulo 	    !wpa_dbus_dict_open_write(&iter, &dict_iter) ||
556325151a3SRui Paulo 	    !wpa_dbus_dict_close_write(&iter, &dict_iter))
557325151a3SRui Paulo 		wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
558325151a3SRui Paulo 	else
559325151a3SRui Paulo 		dbus_connection_send(iface->con, msg, NULL);
560325151a3SRui Paulo 
561325151a3SRui Paulo 	dbus_message_unref(msg);
562325151a3SRui Paulo }
563325151a3SRui Paulo 
564325151a3SRui Paulo 
565325151a3SRui Paulo /**
566d4f2939cSRui Paulo  * wpas_dbus_signal_wps_event_success - Signals Success WPS event
567d4f2939cSRui Paulo  * @wpa_s: %wpa_supplicant network interface data
568d4f2939cSRui Paulo  *
569d4f2939cSRui Paulo  * Sends Event dbus signal with name "success" and empty dict as arguments
570d4f2939cSRui Paulo  */
571d4f2939cSRui Paulo void wpas_dbus_signal_wps_event_success(struct wpa_supplicant *wpa_s)
572d4f2939cSRui Paulo {
573d4f2939cSRui Paulo 
574d4f2939cSRui Paulo 	DBusMessage *msg;
575d4f2939cSRui Paulo 	DBusMessageIter iter, dict_iter;
576d4f2939cSRui Paulo 	struct wpas_dbus_priv *iface;
577d4f2939cSRui Paulo 	char *key = "success";
578d4f2939cSRui Paulo 
579d4f2939cSRui Paulo 	iface = wpa_s->global->dbus;
580d4f2939cSRui Paulo 
581d4f2939cSRui Paulo 	/* Do nothing if the control interface is not turned on */
582325151a3SRui Paulo 	if (iface == NULL || !wpa_s->dbus_new_path)
583d4f2939cSRui Paulo 		return;
584d4f2939cSRui Paulo 
585d4f2939cSRui Paulo 	msg = dbus_message_new_signal(wpa_s->dbus_new_path,
586d4f2939cSRui Paulo 				      WPAS_DBUS_NEW_IFACE_WPS, "Event");
587d4f2939cSRui Paulo 	if (msg == NULL)
588d4f2939cSRui Paulo 		return;
589d4f2939cSRui Paulo 
590d4f2939cSRui Paulo 	dbus_message_iter_init_append(msg, &iter);
591d4f2939cSRui Paulo 
592d4f2939cSRui Paulo 	if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &key) ||
593d4f2939cSRui Paulo 	    !wpa_dbus_dict_open_write(&iter, &dict_iter) ||
594d4f2939cSRui Paulo 	    !wpa_dbus_dict_close_write(&iter, &dict_iter))
595d4f2939cSRui Paulo 		wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
596d4f2939cSRui Paulo 	else
597d4f2939cSRui Paulo 		dbus_connection_send(iface->con, msg, NULL);
598d4f2939cSRui Paulo 
599d4f2939cSRui Paulo 	dbus_message_unref(msg);
600d4f2939cSRui Paulo }
601d4f2939cSRui Paulo 
602d4f2939cSRui Paulo 
603d4f2939cSRui Paulo /**
604d4f2939cSRui Paulo  * wpas_dbus_signal_wps_event_fail - Signals Fail WPS event
605d4f2939cSRui Paulo  * @wpa_s: %wpa_supplicant network interface data
606325151a3SRui Paulo  * @fail: WPS failure information
607d4f2939cSRui Paulo  *
608d4f2939cSRui Paulo  * Sends Event dbus signal with name "fail" and dictionary containing
609d4f2939cSRui Paulo  * "msg field with fail message number (int32) as arguments
610d4f2939cSRui Paulo  */
611d4f2939cSRui Paulo void wpas_dbus_signal_wps_event_fail(struct wpa_supplicant *wpa_s,
612d4f2939cSRui Paulo 				     struct wps_event_fail *fail)
613d4f2939cSRui Paulo {
614d4f2939cSRui Paulo 
615d4f2939cSRui Paulo 	DBusMessage *msg;
616d4f2939cSRui Paulo 	DBusMessageIter iter, dict_iter;
617d4f2939cSRui Paulo 	struct wpas_dbus_priv *iface;
618d4f2939cSRui Paulo 	char *key = "fail";
619d4f2939cSRui Paulo 
620d4f2939cSRui Paulo 	iface = wpa_s->global->dbus;
621d4f2939cSRui Paulo 
622d4f2939cSRui Paulo 	/* Do nothing if the control interface is not turned on */
623325151a3SRui Paulo 	if (iface == NULL || !wpa_s->dbus_new_path)
624d4f2939cSRui Paulo 		return;
625d4f2939cSRui Paulo 
626d4f2939cSRui Paulo 	msg = dbus_message_new_signal(wpa_s->dbus_new_path,
627d4f2939cSRui Paulo 				      WPAS_DBUS_NEW_IFACE_WPS, "Event");
628d4f2939cSRui Paulo 	if (msg == NULL)
629d4f2939cSRui Paulo 		return;
630d4f2939cSRui Paulo 
631d4f2939cSRui Paulo 	dbus_message_iter_init_append(msg, &iter);
632d4f2939cSRui Paulo 
633d4f2939cSRui Paulo 	if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &key) ||
634d4f2939cSRui Paulo 	    !wpa_dbus_dict_open_write(&iter, &dict_iter) ||
635d4f2939cSRui Paulo 	    !wpa_dbus_dict_append_int32(&dict_iter, "msg", fail->msg) ||
636325151a3SRui Paulo 	    !wpa_dbus_dict_append_int32(&dict_iter, "config_error",
637325151a3SRui Paulo 					fail->config_error) ||
638325151a3SRui Paulo 	    !wpa_dbus_dict_append_int32(&dict_iter, "error_indication",
639325151a3SRui Paulo 					fail->error_indication) ||
640d4f2939cSRui Paulo 	    !wpa_dbus_dict_close_write(&iter, &dict_iter))
641d4f2939cSRui Paulo 		wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
642d4f2939cSRui Paulo 	else
643d4f2939cSRui Paulo 		dbus_connection_send(iface->con, msg, NULL);
644d4f2939cSRui Paulo 
645d4f2939cSRui Paulo 	dbus_message_unref(msg);
646d4f2939cSRui Paulo }
647d4f2939cSRui Paulo 
648d4f2939cSRui Paulo 
649d4f2939cSRui Paulo /**
650d4f2939cSRui Paulo  * wpas_dbus_signal_wps_event_m2d - Signals M2D WPS event
651d4f2939cSRui Paulo  * @wpa_s: %wpa_supplicant network interface data
652325151a3SRui Paulo  * @m2d: M2D event data information
653d4f2939cSRui Paulo  *
654d4f2939cSRui Paulo  * Sends Event dbus signal with name "m2d" and dictionary containing
655d4f2939cSRui Paulo  * fields of wps_event_m2d structure.
656d4f2939cSRui Paulo  */
657d4f2939cSRui Paulo void wpas_dbus_signal_wps_event_m2d(struct wpa_supplicant *wpa_s,
658d4f2939cSRui Paulo 				    struct wps_event_m2d *m2d)
659d4f2939cSRui Paulo {
660d4f2939cSRui Paulo 
661d4f2939cSRui Paulo 	DBusMessage *msg;
662d4f2939cSRui Paulo 	DBusMessageIter iter, dict_iter;
663d4f2939cSRui Paulo 	struct wpas_dbus_priv *iface;
664d4f2939cSRui Paulo 	char *key = "m2d";
665d4f2939cSRui Paulo 
666d4f2939cSRui Paulo 	iface = wpa_s->global->dbus;
667d4f2939cSRui Paulo 
668d4f2939cSRui Paulo 	/* Do nothing if the control interface is not turned on */
669325151a3SRui Paulo 	if (iface == NULL || !wpa_s->dbus_new_path)
670d4f2939cSRui Paulo 		return;
671d4f2939cSRui Paulo 
672d4f2939cSRui Paulo 	msg = dbus_message_new_signal(wpa_s->dbus_new_path,
673d4f2939cSRui Paulo 				      WPAS_DBUS_NEW_IFACE_WPS, "Event");
674d4f2939cSRui Paulo 	if (msg == NULL)
675d4f2939cSRui Paulo 		return;
676d4f2939cSRui Paulo 
677d4f2939cSRui Paulo 	dbus_message_iter_init_append(msg, &iter);
678d4f2939cSRui Paulo 
679d4f2939cSRui Paulo 	if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &key) ||
680d4f2939cSRui Paulo 	    !wpa_dbus_dict_open_write(&iter, &dict_iter) ||
681d4f2939cSRui Paulo 	    !wpa_dbus_dict_append_uint16(&dict_iter, "config_methods",
682d4f2939cSRui Paulo 					 m2d->config_methods) ||
683d4f2939cSRui Paulo 	    !wpa_dbus_dict_append_byte_array(&dict_iter, "manufacturer",
684d4f2939cSRui Paulo 					     (const char *) m2d->manufacturer,
685d4f2939cSRui Paulo 					     m2d->manufacturer_len) ||
686d4f2939cSRui Paulo 	    !wpa_dbus_dict_append_byte_array(&dict_iter, "model_name",
687d4f2939cSRui Paulo 					     (const char *) m2d->model_name,
688d4f2939cSRui Paulo 					     m2d->model_name_len) ||
689d4f2939cSRui Paulo 	    !wpa_dbus_dict_append_byte_array(&dict_iter, "model_number",
690d4f2939cSRui Paulo 					     (const char *) m2d->model_number,
691d4f2939cSRui Paulo 					     m2d->model_number_len) ||
692d4f2939cSRui Paulo 	    !wpa_dbus_dict_append_byte_array(&dict_iter, "serial_number",
693d4f2939cSRui Paulo 					     (const char *)
694d4f2939cSRui Paulo 					     m2d->serial_number,
695d4f2939cSRui Paulo 					     m2d->serial_number_len) ||
696d4f2939cSRui Paulo 	    !wpa_dbus_dict_append_byte_array(&dict_iter, "dev_name",
697d4f2939cSRui Paulo 					     (const char *) m2d->dev_name,
698d4f2939cSRui Paulo 					     m2d->dev_name_len) ||
699d4f2939cSRui Paulo 	    !wpa_dbus_dict_append_byte_array(&dict_iter, "primary_dev_type",
700d4f2939cSRui Paulo 					     (const char *)
701d4f2939cSRui Paulo 					     m2d->primary_dev_type, 8) ||
702d4f2939cSRui Paulo 	    !wpa_dbus_dict_append_uint16(&dict_iter, "config_error",
703d4f2939cSRui Paulo 					 m2d->config_error) ||
704d4f2939cSRui Paulo 	    !wpa_dbus_dict_append_uint16(&dict_iter, "dev_password_id",
705d4f2939cSRui Paulo 					 m2d->dev_password_id) ||
706d4f2939cSRui Paulo 	    !wpa_dbus_dict_close_write(&iter, &dict_iter))
707d4f2939cSRui Paulo 		wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
708d4f2939cSRui Paulo 	else
709d4f2939cSRui Paulo 		dbus_connection_send(iface->con, msg, NULL);
710d4f2939cSRui Paulo 
711d4f2939cSRui Paulo 	dbus_message_unref(msg);
712d4f2939cSRui Paulo }
713d4f2939cSRui Paulo 
714d4f2939cSRui Paulo 
715d4f2939cSRui Paulo /**
716d4f2939cSRui Paulo  * wpas_dbus_signal_wps_cred - Signals new credentials
717d4f2939cSRui Paulo  * @wpa_s: %wpa_supplicant network interface data
718325151a3SRui Paulo  * @cred: WPS Credential information
719d4f2939cSRui Paulo  *
720d4f2939cSRui Paulo  * Sends signal with credentials in directory argument
721d4f2939cSRui Paulo  */
722d4f2939cSRui Paulo void wpas_dbus_signal_wps_cred(struct wpa_supplicant *wpa_s,
723d4f2939cSRui Paulo 			       const struct wps_credential *cred)
724d4f2939cSRui Paulo {
725d4f2939cSRui Paulo 	DBusMessage *msg;
726d4f2939cSRui Paulo 	DBusMessageIter iter, dict_iter;
727d4f2939cSRui Paulo 	struct wpas_dbus_priv *iface;
7285b9c547cSRui Paulo 	char *auth_type[5]; /* we have five possible authentication types */
729d4f2939cSRui Paulo 	int at_num = 0;
7305b9c547cSRui Paulo 	char *encr_type[3]; /* we have three possible encryption types */
731d4f2939cSRui Paulo 	int et_num = 0;
732d4f2939cSRui Paulo 
733d4f2939cSRui Paulo 	iface = wpa_s->global->dbus;
734d4f2939cSRui Paulo 
735d4f2939cSRui Paulo 	/* Do nothing if the control interface is not turned on */
736325151a3SRui Paulo 	if (iface == NULL || !wpa_s->dbus_new_path)
737d4f2939cSRui Paulo 		return;
738d4f2939cSRui Paulo 
739d4f2939cSRui Paulo 	msg = dbus_message_new_signal(wpa_s->dbus_new_path,
740d4f2939cSRui Paulo 				      WPAS_DBUS_NEW_IFACE_WPS,
741d4f2939cSRui Paulo 				      "Credentials");
742d4f2939cSRui Paulo 	if (msg == NULL)
743d4f2939cSRui Paulo 		return;
744d4f2939cSRui Paulo 
745d4f2939cSRui Paulo 	dbus_message_iter_init_append(msg, &iter);
746d4f2939cSRui Paulo 	if (!wpa_dbus_dict_open_write(&iter, &dict_iter))
747d4f2939cSRui Paulo 		goto nomem;
748d4f2939cSRui Paulo 
749d4f2939cSRui Paulo 	if (cred->auth_type & WPS_AUTH_OPEN)
750d4f2939cSRui Paulo 		auth_type[at_num++] = "open";
751d4f2939cSRui Paulo 	if (cred->auth_type & WPS_AUTH_WPAPSK)
752d4f2939cSRui Paulo 		auth_type[at_num++] = "wpa-psk";
753d4f2939cSRui Paulo 	if (cred->auth_type & WPS_AUTH_WPA)
754d4f2939cSRui Paulo 		auth_type[at_num++] = "wpa-eap";
755d4f2939cSRui Paulo 	if (cred->auth_type & WPS_AUTH_WPA2)
756d4f2939cSRui Paulo 		auth_type[at_num++] = "wpa2-eap";
757d4f2939cSRui Paulo 	if (cred->auth_type & WPS_AUTH_WPA2PSK)
7585b9c547cSRui Paulo 		auth_type[at_num++] = "wpa2-psk";
759d4f2939cSRui Paulo 
760d4f2939cSRui Paulo 	if (cred->encr_type & WPS_ENCR_NONE)
761d4f2939cSRui Paulo 		encr_type[et_num++] = "none";
762d4f2939cSRui Paulo 	if (cred->encr_type & WPS_ENCR_TKIP)
763d4f2939cSRui Paulo 		encr_type[et_num++] = "tkip";
764d4f2939cSRui Paulo 	if (cred->encr_type & WPS_ENCR_AES)
765d4f2939cSRui Paulo 		encr_type[et_num++] = "aes";
766d4f2939cSRui Paulo 
7675b9c547cSRui Paulo 	if ((wpa_s->current_ssid &&
7685b9c547cSRui Paulo 	     !wpa_dbus_dict_append_byte_array(
769d4f2939cSRui Paulo 		     &dict_iter, "BSSID",
7705b9c547cSRui Paulo 		     (const char *) wpa_s->current_ssid->bssid, ETH_ALEN)) ||
7715b9c547cSRui Paulo 	    !wpa_dbus_dict_append_byte_array(&dict_iter, "SSID",
772d4f2939cSRui Paulo 					     (const char *) cred->ssid,
773d4f2939cSRui Paulo 					     cred->ssid_len) ||
774d4f2939cSRui Paulo 	    !wpa_dbus_dict_append_string_array(&dict_iter, "AuthType",
775d4f2939cSRui Paulo 					       (const char **) auth_type,
776d4f2939cSRui Paulo 					       at_num) ||
777d4f2939cSRui Paulo 	    !wpa_dbus_dict_append_string_array(&dict_iter, "EncrType",
778d4f2939cSRui Paulo 					       (const char **) encr_type,
779d4f2939cSRui Paulo 					       et_num) ||
780d4f2939cSRui Paulo 	    !wpa_dbus_dict_append_byte_array(&dict_iter, "Key",
781d4f2939cSRui Paulo 					     (const char *) cred->key,
782d4f2939cSRui Paulo 					     cred->key_len) ||
783d4f2939cSRui Paulo 	    !wpa_dbus_dict_append_uint32(&dict_iter, "KeyIndex",
784d4f2939cSRui Paulo 					 cred->key_idx) ||
785d4f2939cSRui Paulo 	    !wpa_dbus_dict_close_write(&iter, &dict_iter))
786d4f2939cSRui Paulo 		goto nomem;
787d4f2939cSRui Paulo 
788d4f2939cSRui Paulo 	dbus_connection_send(iface->con, msg, NULL);
789d4f2939cSRui Paulo 
790d4f2939cSRui Paulo nomem:
791d4f2939cSRui Paulo 	dbus_message_unref(msg);
792d4f2939cSRui Paulo }
793d4f2939cSRui Paulo 
794d4f2939cSRui Paulo #endif /* CONFIG_WPS */
795d4f2939cSRui Paulo 
796d4f2939cSRui Paulo void wpas_dbus_signal_certification(struct wpa_supplicant *wpa_s,
797d4f2939cSRui Paulo 				    int depth, const char *subject,
7985b9c547cSRui Paulo 				    const char *altsubject[],
7995b9c547cSRui Paulo 				    int num_altsubject,
800d4f2939cSRui Paulo 				    const char *cert_hash,
801d4f2939cSRui Paulo 				    const struct wpabuf *cert)
802d4f2939cSRui Paulo {
803d4f2939cSRui Paulo 	struct wpas_dbus_priv *iface;
804d4f2939cSRui Paulo 	DBusMessage *msg;
805d4f2939cSRui Paulo 	DBusMessageIter iter, dict_iter;
806d4f2939cSRui Paulo 
807d4f2939cSRui Paulo 	iface = wpa_s->global->dbus;
808d4f2939cSRui Paulo 
809d4f2939cSRui Paulo 	/* Do nothing if the control interface is not turned on */
810325151a3SRui Paulo 	if (iface == NULL || !wpa_s->dbus_new_path)
811d4f2939cSRui Paulo 		return;
812d4f2939cSRui Paulo 
813d4f2939cSRui Paulo 	msg = dbus_message_new_signal(wpa_s->dbus_new_path,
814d4f2939cSRui Paulo 				      WPAS_DBUS_NEW_IFACE_INTERFACE,
815d4f2939cSRui Paulo 				      "Certification");
816d4f2939cSRui Paulo 	if (msg == NULL)
817d4f2939cSRui Paulo 		return;
818d4f2939cSRui Paulo 
819d4f2939cSRui Paulo 	dbus_message_iter_init_append(msg, &iter);
8205b9c547cSRui Paulo 	if (!wpa_dbus_dict_open_write(&iter, &dict_iter) ||
8215b9c547cSRui Paulo 	    !wpa_dbus_dict_append_uint32(&dict_iter, "depth", depth) ||
8225b9c547cSRui Paulo 	    !wpa_dbus_dict_append_string(&dict_iter, "subject", subject) ||
8235b9c547cSRui Paulo 	    (altsubject && num_altsubject &&
8245b9c547cSRui Paulo 	     !wpa_dbus_dict_append_string_array(&dict_iter, "altsubject",
8255b9c547cSRui Paulo 						altsubject, num_altsubject)) ||
8265b9c547cSRui Paulo 	    (cert_hash &&
8275b9c547cSRui Paulo 	     !wpa_dbus_dict_append_string(&dict_iter, "cert_hash",
8285b9c547cSRui Paulo 					  cert_hash)) ||
8295b9c547cSRui Paulo 	    (cert &&
830d4f2939cSRui Paulo 	     !wpa_dbus_dict_append_byte_array(&dict_iter, "cert",
831d4f2939cSRui Paulo 					      wpabuf_head(cert),
8325b9c547cSRui Paulo 					      wpabuf_len(cert))) ||
8335b9c547cSRui Paulo 	    !wpa_dbus_dict_close_write(&iter, &dict_iter))
8345b9c547cSRui Paulo 		wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
8355b9c547cSRui Paulo 	else
836d4f2939cSRui Paulo 		dbus_connection_send(iface->con, msg, NULL);
837d4f2939cSRui Paulo 	dbus_message_unref(msg);
838d4f2939cSRui Paulo }
839d4f2939cSRui Paulo 
840d4f2939cSRui Paulo 
841d4f2939cSRui Paulo void wpas_dbus_signal_eap_status(struct wpa_supplicant *wpa_s,
842d4f2939cSRui Paulo 				 const char *status, const char *parameter)
843d4f2939cSRui Paulo {
844d4f2939cSRui Paulo 	struct wpas_dbus_priv *iface;
845d4f2939cSRui Paulo 	DBusMessage *msg;
846d4f2939cSRui Paulo 	DBusMessageIter iter;
847d4f2939cSRui Paulo 
848d4f2939cSRui Paulo 	iface = wpa_s->global->dbus;
849d4f2939cSRui Paulo 
850d4f2939cSRui Paulo 	/* Do nothing if the control interface is not turned on */
851325151a3SRui Paulo 	if (iface == NULL || !wpa_s->dbus_new_path)
852d4f2939cSRui Paulo 		return;
853d4f2939cSRui Paulo 
854d4f2939cSRui Paulo 	msg = dbus_message_new_signal(wpa_s->dbus_new_path,
855d4f2939cSRui Paulo 				      WPAS_DBUS_NEW_IFACE_INTERFACE,
856d4f2939cSRui Paulo 				      "EAP");
857d4f2939cSRui Paulo 	if (msg == NULL)
858d4f2939cSRui Paulo 		return;
859d4f2939cSRui Paulo 
860d4f2939cSRui Paulo 	dbus_message_iter_init_append(msg, &iter);
861d4f2939cSRui Paulo 
8625b9c547cSRui Paulo 	if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &status) ||
863d4f2939cSRui Paulo 	    !dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING,
864d4f2939cSRui Paulo 					    &parameter))
8655b9c547cSRui Paulo 		wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
8665b9c547cSRui Paulo 	else
867d4f2939cSRui Paulo 		dbus_connection_send(iface->con, msg, NULL);
868d4f2939cSRui Paulo 	dbus_message_unref(msg);
869d4f2939cSRui Paulo }
870d4f2939cSRui Paulo 
871d4f2939cSRui Paulo 
8725b9c547cSRui Paulo /**
8735b9c547cSRui Paulo  * wpas_dbus_signal_sta - Send a station related event signal
8745b9c547cSRui Paulo  * @wpa_s: %wpa_supplicant network interface data
8755b9c547cSRui Paulo  * @sta: station mac address
8765b9c547cSRui Paulo  * @sig_name: signal name - StaAuthorized or StaDeauthorized
8775b9c547cSRui Paulo  *
8785b9c547cSRui Paulo  * Notify listeners about event related with station
8795b9c547cSRui Paulo  */
8805b9c547cSRui Paulo static void wpas_dbus_signal_sta(struct wpa_supplicant *wpa_s,
8815b9c547cSRui Paulo 				 const u8 *sta, const char *sig_name)
8825b9c547cSRui Paulo {
8835b9c547cSRui Paulo 	struct wpas_dbus_priv *iface;
8845b9c547cSRui Paulo 	DBusMessage *msg;
8855b9c547cSRui Paulo 	char sta_mac[WPAS_DBUS_OBJECT_PATH_MAX];
8865b9c547cSRui Paulo 	char *dev_mac;
8875b9c547cSRui Paulo 
8885b9c547cSRui Paulo 	os_snprintf(sta_mac, WPAS_DBUS_OBJECT_PATH_MAX, MACSTR, MAC2STR(sta));
8895b9c547cSRui Paulo 	dev_mac = sta_mac;
8905b9c547cSRui Paulo 
8915b9c547cSRui Paulo 	iface = wpa_s->global->dbus;
8925b9c547cSRui Paulo 
8935b9c547cSRui Paulo 	/* Do nothing if the control interface is not turned on */
894325151a3SRui Paulo 	if (iface == NULL || !wpa_s->dbus_new_path)
8955b9c547cSRui Paulo 		return;
8965b9c547cSRui Paulo 
8975b9c547cSRui Paulo 	msg = dbus_message_new_signal(wpa_s->dbus_new_path,
8985b9c547cSRui Paulo 				      WPAS_DBUS_NEW_IFACE_INTERFACE, sig_name);
8995b9c547cSRui Paulo 	if (msg == NULL)
9005b9c547cSRui Paulo 		return;
9015b9c547cSRui Paulo 
9025b9c547cSRui Paulo 	if (dbus_message_append_args(msg, DBUS_TYPE_STRING, &dev_mac,
9035b9c547cSRui Paulo 				     DBUS_TYPE_INVALID))
9045b9c547cSRui Paulo 		dbus_connection_send(iface->con, msg, NULL);
9055b9c547cSRui Paulo 	else
9065b9c547cSRui Paulo 		wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
9075b9c547cSRui Paulo 	dbus_message_unref(msg);
9085b9c547cSRui Paulo 
9095b9c547cSRui Paulo 	wpa_printf(MSG_DEBUG, "dbus: Station MAC address '%s' '%s'",
9105b9c547cSRui Paulo 		   sta_mac, sig_name);
9115b9c547cSRui Paulo }
9125b9c547cSRui Paulo 
9135b9c547cSRui Paulo 
9145b9c547cSRui Paulo /**
9155b9c547cSRui Paulo  * wpas_dbus_signal_sta_authorized - Send a STA authorized signal
9165b9c547cSRui Paulo  * @wpa_s: %wpa_supplicant network interface data
9175b9c547cSRui Paulo  * @sta: station mac address
9185b9c547cSRui Paulo  *
9195b9c547cSRui Paulo  * Notify listeners a new station has been authorized
9205b9c547cSRui Paulo  */
9215b9c547cSRui Paulo void wpas_dbus_signal_sta_authorized(struct wpa_supplicant *wpa_s,
9225b9c547cSRui Paulo 				     const u8 *sta)
9235b9c547cSRui Paulo {
9245b9c547cSRui Paulo 	wpas_dbus_signal_sta(wpa_s, sta, "StaAuthorized");
9255b9c547cSRui Paulo }
9265b9c547cSRui Paulo 
9275b9c547cSRui Paulo 
9285b9c547cSRui Paulo /**
9295b9c547cSRui Paulo  * wpas_dbus_signal_sta_deauthorized - Send a STA deauthorized signal
9305b9c547cSRui Paulo  * @wpa_s: %wpa_supplicant network interface data
9315b9c547cSRui Paulo  * @sta: station mac address
9325b9c547cSRui Paulo  *
9335b9c547cSRui Paulo  * Notify listeners a station has been deauthorized
9345b9c547cSRui Paulo  */
9355b9c547cSRui Paulo void wpas_dbus_signal_sta_deauthorized(struct wpa_supplicant *wpa_s,
9365b9c547cSRui Paulo 				       const u8 *sta)
9375b9c547cSRui Paulo {
9385b9c547cSRui Paulo 	wpas_dbus_signal_sta(wpa_s, sta, "StaDeauthorized");
9395b9c547cSRui Paulo }
9405b9c547cSRui Paulo 
9415b9c547cSRui Paulo 
942d4f2939cSRui Paulo #ifdef CONFIG_P2P
943d4f2939cSRui Paulo 
944d4f2939cSRui Paulo /**
945d4f2939cSRui Paulo  * wpas_dbus_signal_p2p_group_removed - Signals P2P group was removed
946d4f2939cSRui Paulo  * @wpa_s: %wpa_supplicant network interface data
947d4f2939cSRui Paulo  * @role: role of this device (client or GO)
948d4f2939cSRui Paulo  * Sends signal with i/f name and role as string arguments
949d4f2939cSRui Paulo  */
950d4f2939cSRui Paulo void wpas_dbus_signal_p2p_group_removed(struct wpa_supplicant *wpa_s,
951d4f2939cSRui Paulo 					const char *role)
952d4f2939cSRui Paulo {
953d4f2939cSRui Paulo 	DBusMessage *msg;
9545b9c547cSRui Paulo 	DBusMessageIter iter, dict_iter;
955d4f2939cSRui Paulo 	struct wpas_dbus_priv *iface = wpa_s->global->dbus;
9565b9c547cSRui Paulo 	struct wpa_supplicant *parent;
957d4f2939cSRui Paulo 
958d4f2939cSRui Paulo 	/* Do nothing if the control interface is not turned on */
959d4f2939cSRui Paulo 	if (iface == NULL)
960d4f2939cSRui Paulo 		return;
961d4f2939cSRui Paulo 
9625b9c547cSRui Paulo 	parent = wpa_s->parent;
9635b9c547cSRui Paulo 	if (parent->p2p_mgmt)
9645b9c547cSRui Paulo 		parent = parent->parent;
9655b9c547cSRui Paulo 
966325151a3SRui Paulo 	if (!wpa_s->dbus_groupobj_path || !wpa_s->dbus_new_path ||
967325151a3SRui Paulo 	    !parent->dbus_new_path)
9685b9c547cSRui Paulo 		return;
9695b9c547cSRui Paulo 
9705b9c547cSRui Paulo 	msg = dbus_message_new_signal(parent->dbus_new_path,
971d4f2939cSRui Paulo 				      WPAS_DBUS_NEW_IFACE_P2PDEVICE,
972d4f2939cSRui Paulo 				      "GroupFinished");
973d4f2939cSRui Paulo 	if (msg == NULL)
974d4f2939cSRui Paulo 		return;
975d4f2939cSRui Paulo 
976d4f2939cSRui Paulo 	dbus_message_iter_init_append(msg, &iter);
9775b9c547cSRui Paulo 	if (!wpa_dbus_dict_open_write(&iter, &dict_iter) ||
9785b9c547cSRui Paulo 	    !wpa_dbus_dict_append_object_path(&dict_iter,
9795b9c547cSRui Paulo 					      "interface_object",
9805b9c547cSRui Paulo 					      wpa_s->dbus_new_path) ||
9815b9c547cSRui Paulo 	    !wpa_dbus_dict_append_string(&dict_iter, "role", role) ||
9825b9c547cSRui Paulo 	    !wpa_dbus_dict_append_object_path(&dict_iter, "group_object",
9835b9c547cSRui Paulo 					      wpa_s->dbus_groupobj_path) ||
9845b9c547cSRui Paulo 	    !wpa_dbus_dict_close_write(&iter, &dict_iter))
9855b9c547cSRui Paulo 		wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
986d4f2939cSRui Paulo 	else
987d4f2939cSRui Paulo 		dbus_connection_send(iface->con, msg, NULL);
988d4f2939cSRui Paulo 	dbus_message_unref(msg);
989d4f2939cSRui Paulo }
990d4f2939cSRui Paulo 
991d4f2939cSRui Paulo 
992d4f2939cSRui Paulo /**
993d4f2939cSRui Paulo  * wpas_dbus_signal_p2p_provision_discovery - Signals various PD events
994d4f2939cSRui Paulo  *
995d4f2939cSRui Paulo  * @dev_addr - who sent the request or responded to our request.
996d4f2939cSRui Paulo  * @request - Will be 1 if request, 0 for response.
997d4f2939cSRui Paulo  * @status - valid only in case of response
998d4f2939cSRui Paulo  * @config_methods - wps config methods
999d4f2939cSRui Paulo  * @generated_pin - pin to be displayed in case of WPS_CONFIG_DISPLAY method
1000d4f2939cSRui Paulo  *
1001d4f2939cSRui Paulo  * Sends following provision discovery related events:
1002d4f2939cSRui Paulo  *	ProvisionDiscoveryRequestDisplayPin
1003d4f2939cSRui Paulo  *	ProvisionDiscoveryResponseDisplayPin
1004d4f2939cSRui Paulo  *	ProvisionDiscoveryRequestEnterPin
1005d4f2939cSRui Paulo  *	ProvisionDiscoveryResponseEnterPin
1006d4f2939cSRui Paulo  *	ProvisionDiscoveryPBCRequest
1007d4f2939cSRui Paulo  *	ProvisionDiscoveryPBCResponse
1008d4f2939cSRui Paulo  *
1009d4f2939cSRui Paulo  *	TODO::
1010d4f2939cSRui Paulo  *	ProvisionDiscoveryFailure (timeout case)
1011d4f2939cSRui Paulo  */
1012d4f2939cSRui Paulo void wpas_dbus_signal_p2p_provision_discovery(struct wpa_supplicant *wpa_s,
1013d4f2939cSRui Paulo 					      const u8 *dev_addr, int request,
1014d4f2939cSRui Paulo 					      enum p2p_prov_disc_status status,
1015d4f2939cSRui Paulo 					      u16 config_methods,
1016d4f2939cSRui Paulo 					      unsigned int generated_pin)
1017d4f2939cSRui Paulo {
1018d4f2939cSRui Paulo 	DBusMessage *msg;
1019d4f2939cSRui Paulo 	DBusMessageIter iter;
1020d4f2939cSRui Paulo 	struct wpas_dbus_priv *iface;
1021d4f2939cSRui Paulo 	char *_signal;
1022d4f2939cSRui Paulo 	int add_pin = 0;
1023d4f2939cSRui Paulo 	char peer_obj_path[WPAS_DBUS_OBJECT_PATH_MAX], *path;
1024d4f2939cSRui Paulo 	int error_ret = 1;
1025d4f2939cSRui Paulo 	char pin[9], *p_pin = NULL;
1026d4f2939cSRui Paulo 
1027d4f2939cSRui Paulo 	iface = wpa_s->global->dbus;
1028d4f2939cSRui Paulo 
1029d4f2939cSRui Paulo 	/* Do nothing if the control interface is not turned on */
1030d4f2939cSRui Paulo 	if (iface == NULL)
1031d4f2939cSRui Paulo 		return;
1032d4f2939cSRui Paulo 
10335b9c547cSRui Paulo 	if (wpa_s->p2p_mgmt)
10345b9c547cSRui Paulo 		wpa_s = wpa_s->parent;
1035325151a3SRui Paulo 	if (!wpa_s->dbus_new_path)
1036325151a3SRui Paulo 		return;
10375b9c547cSRui Paulo 
1038d4f2939cSRui Paulo 	if (request || !status) {
1039d4f2939cSRui Paulo 		if (config_methods & WPS_CONFIG_DISPLAY)
1040d4f2939cSRui Paulo 			_signal = request ?
1041d4f2939cSRui Paulo 				 "ProvisionDiscoveryRequestDisplayPin" :
1042d4f2939cSRui Paulo 				 "ProvisionDiscoveryResponseEnterPin";
1043d4f2939cSRui Paulo 		else if (config_methods & WPS_CONFIG_KEYPAD)
1044d4f2939cSRui Paulo 			_signal = request ?
1045d4f2939cSRui Paulo 				 "ProvisionDiscoveryRequestEnterPin" :
1046d4f2939cSRui Paulo 				 "ProvisionDiscoveryResponseDisplayPin";
1047d4f2939cSRui Paulo 		else if (config_methods & WPS_CONFIG_PUSHBUTTON)
1048d4f2939cSRui Paulo 			_signal = request ? "ProvisionDiscoveryPBCRequest" :
1049d4f2939cSRui Paulo 				   "ProvisionDiscoveryPBCResponse";
1050d4f2939cSRui Paulo 		else
1051d4f2939cSRui Paulo 			return; /* Unknown or un-supported method */
10525b9c547cSRui Paulo 	} else {
1053d4f2939cSRui Paulo 		/* Explicit check for failure response */
1054d4f2939cSRui Paulo 		_signal = "ProvisionDiscoveryFailure";
10555b9c547cSRui Paulo 	}
1056d4f2939cSRui Paulo 
1057d4f2939cSRui Paulo 	add_pin = ((request && (config_methods & WPS_CONFIG_DISPLAY)) ||
1058d4f2939cSRui Paulo 		   (!request && !status &&
1059d4f2939cSRui Paulo 			(config_methods & WPS_CONFIG_KEYPAD)));
1060d4f2939cSRui Paulo 
1061d4f2939cSRui Paulo 	if (add_pin) {
1062d4f2939cSRui Paulo 		os_snprintf(pin, sizeof(pin), "%08d", generated_pin);
1063d4f2939cSRui Paulo 		p_pin = pin;
1064d4f2939cSRui Paulo 	}
1065d4f2939cSRui Paulo 
1066d4f2939cSRui Paulo 	msg = dbus_message_new_signal(wpa_s->dbus_new_path,
1067d4f2939cSRui Paulo 				      WPAS_DBUS_NEW_IFACE_P2PDEVICE, _signal);
1068d4f2939cSRui Paulo 	if (msg == NULL)
1069d4f2939cSRui Paulo 		return;
1070d4f2939cSRui Paulo 
1071d4f2939cSRui Paulo 	/* Check if this is a known peer */
1072d4f2939cSRui Paulo 	if (!p2p_peer_known(wpa_s->global->p2p, dev_addr))
1073d4f2939cSRui Paulo 		goto error;
1074d4f2939cSRui Paulo 
1075d4f2939cSRui Paulo 	os_snprintf(peer_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
1076d4f2939cSRui Paulo 			"%s/" WPAS_DBUS_NEW_P2P_PEERS_PART "/"
1077d4f2939cSRui Paulo 			COMPACT_MACSTR,
1078d4f2939cSRui Paulo 			wpa_s->dbus_new_path, MAC2STR(dev_addr));
1079d4f2939cSRui Paulo 
1080d4f2939cSRui Paulo 	path = peer_obj_path;
1081d4f2939cSRui Paulo 
1082d4f2939cSRui Paulo 	dbus_message_iter_init_append(msg, &iter);
1083d4f2939cSRui Paulo 
1084d4f2939cSRui Paulo 	if (!dbus_message_iter_append_basic(&iter,
1085d4f2939cSRui Paulo 					    DBUS_TYPE_OBJECT_PATH,
1086d4f2939cSRui Paulo 					    &path))
1087d4f2939cSRui Paulo 			goto error;
1088d4f2939cSRui Paulo 
1089d4f2939cSRui Paulo 	if (!request && status)
1090d4f2939cSRui Paulo 		/* Attach status to ProvisionDiscoveryFailure */
1091d4f2939cSRui Paulo 		error_ret = !dbus_message_iter_append_basic(&iter,
1092d4f2939cSRui Paulo 						    DBUS_TYPE_INT32,
1093d4f2939cSRui Paulo 						    &status);
1094d4f2939cSRui Paulo 	else
1095d4f2939cSRui Paulo 		error_ret = (add_pin &&
1096d4f2939cSRui Paulo 				 !dbus_message_iter_append_basic(&iter,
1097d4f2939cSRui Paulo 							DBUS_TYPE_STRING,
1098d4f2939cSRui Paulo 							&p_pin));
1099d4f2939cSRui Paulo 
1100d4f2939cSRui Paulo error:
1101d4f2939cSRui Paulo 	if (!error_ret)
1102d4f2939cSRui Paulo 		dbus_connection_send(iface->con, msg, NULL);
1103d4f2939cSRui Paulo 	else
1104d4f2939cSRui Paulo 		wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
1105d4f2939cSRui Paulo 
1106d4f2939cSRui Paulo 	dbus_message_unref(msg);
1107d4f2939cSRui Paulo }
1108d4f2939cSRui Paulo 
1109d4f2939cSRui Paulo 
1110325151a3SRui Paulo /**
1111325151a3SRui Paulo  * wpas_dbus_signal_p2p_go_neg_req - Signal P2P GO Negotiation Request RX
1112325151a3SRui Paulo  * @wpa_s: %wpa_supplicant network interface data
1113325151a3SRui Paulo  * @src: Source address of the message triggering this notification
1114325151a3SRui Paulo  * @dev_passwd_id: WPS Device Password Id
1115325151a3SRui Paulo  * @go_intent: Peer's GO Intent value
1116325151a3SRui Paulo  *
1117325151a3SRui Paulo  * Sends signal to notify that a peer P2P Device is requesting group owner
1118325151a3SRui Paulo  * negotiation with us.
1119325151a3SRui Paulo  */
1120d4f2939cSRui Paulo void wpas_dbus_signal_p2p_go_neg_req(struct wpa_supplicant *wpa_s,
1121325151a3SRui Paulo 				     const u8 *src, u16 dev_passwd_id,
1122325151a3SRui Paulo 				     u8 go_intent)
1123d4f2939cSRui Paulo {
1124d4f2939cSRui Paulo 	DBusMessage *msg;
1125d4f2939cSRui Paulo 	DBusMessageIter iter;
1126d4f2939cSRui Paulo 	struct wpas_dbus_priv *iface;
1127d4f2939cSRui Paulo 	char peer_obj_path[WPAS_DBUS_OBJECT_PATH_MAX], *path;
1128d4f2939cSRui Paulo 
1129d4f2939cSRui Paulo 	iface = wpa_s->global->dbus;
1130d4f2939cSRui Paulo 
1131d4f2939cSRui Paulo 	/* Do nothing if the control interface is not turned on */
1132d4f2939cSRui Paulo 	if (iface == NULL)
1133d4f2939cSRui Paulo 		return;
1134d4f2939cSRui Paulo 
11355b9c547cSRui Paulo 	if (wpa_s->p2p_mgmt)
11365b9c547cSRui Paulo 		wpa_s = wpa_s->parent;
1137325151a3SRui Paulo 	if (!wpa_s->dbus_new_path)
1138325151a3SRui Paulo 		return;
11395b9c547cSRui Paulo 
1140d4f2939cSRui Paulo 	os_snprintf(peer_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
1141d4f2939cSRui Paulo 		    "%s/" WPAS_DBUS_NEW_P2P_PEERS_PART "/" COMPACT_MACSTR,
1142d4f2939cSRui Paulo 		    wpa_s->dbus_new_path, MAC2STR(src));
1143d4f2939cSRui Paulo 	path = peer_obj_path;
1144d4f2939cSRui Paulo 
1145d4f2939cSRui Paulo 	msg = dbus_message_new_signal(wpa_s->dbus_new_path,
1146d4f2939cSRui Paulo 				      WPAS_DBUS_NEW_IFACE_P2PDEVICE,
1147d4f2939cSRui Paulo 				      "GONegotiationRequest");
1148d4f2939cSRui Paulo 	if (msg == NULL)
1149d4f2939cSRui Paulo 		return;
1150d4f2939cSRui Paulo 
1151d4f2939cSRui Paulo 	dbus_message_iter_init_append(msg, &iter);
1152d4f2939cSRui Paulo 
1153d4f2939cSRui Paulo 	if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_OBJECT_PATH,
1154d4f2939cSRui Paulo 					    &path) ||
1155d4f2939cSRui Paulo 	    !dbus_message_iter_append_basic(&iter, DBUS_TYPE_UINT16,
1156325151a3SRui Paulo 					    &dev_passwd_id) ||
1157325151a3SRui Paulo 	    !dbus_message_iter_append_basic(&iter, DBUS_TYPE_BYTE,
1158325151a3SRui Paulo 					    &go_intent))
1159d4f2939cSRui Paulo 		wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
1160d4f2939cSRui Paulo 	else
1161d4f2939cSRui Paulo 		dbus_connection_send(iface->con, msg, NULL);
1162d4f2939cSRui Paulo 
1163d4f2939cSRui Paulo 	dbus_message_unref(msg);
1164d4f2939cSRui Paulo }
1165d4f2939cSRui Paulo 
1166d4f2939cSRui Paulo 
1167d4f2939cSRui Paulo static int wpas_dbus_get_group_obj_path(struct wpa_supplicant *wpa_s,
1168d4f2939cSRui Paulo 					const struct wpa_ssid *ssid,
1169d4f2939cSRui Paulo 					char *group_obj_path)
1170d4f2939cSRui Paulo {
1171d4f2939cSRui Paulo 	char group_name[3];
1172d4f2939cSRui Paulo 
1173325151a3SRui Paulo 	if (!wpa_s->dbus_new_path ||
1174325151a3SRui Paulo 	    os_memcmp(ssid->ssid, P2P_WILDCARD_SSID, P2P_WILDCARD_SSID_LEN))
1175d4f2939cSRui Paulo 		return -1;
1176d4f2939cSRui Paulo 
1177d4f2939cSRui Paulo 	os_memcpy(group_name, ssid->ssid + P2P_WILDCARD_SSID_LEN, 2);
1178d4f2939cSRui Paulo 	group_name[2] = '\0';
1179d4f2939cSRui Paulo 
1180d4f2939cSRui Paulo 	os_snprintf(group_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
1181d4f2939cSRui Paulo 		    "%s/" WPAS_DBUS_NEW_P2P_GROUPS_PART "/%s",
1182d4f2939cSRui Paulo 		    wpa_s->dbus_new_path, group_name);
1183d4f2939cSRui Paulo 
1184d4f2939cSRui Paulo 	return 0;
1185d4f2939cSRui Paulo }
1186d4f2939cSRui Paulo 
1187d4f2939cSRui Paulo 
11885b9c547cSRui Paulo struct group_changed_data {
11895b9c547cSRui Paulo 	struct wpa_supplicant *wpa_s;
11905b9c547cSRui Paulo 	struct p2p_peer_info *info;
11915b9c547cSRui Paulo };
11925b9c547cSRui Paulo 
11935b9c547cSRui Paulo 
11945b9c547cSRui Paulo static int match_group_where_peer_is_client(struct p2p_group *group,
11955b9c547cSRui Paulo 					    void *user_data)
11965b9c547cSRui Paulo {
11975b9c547cSRui Paulo 	struct group_changed_data *data = user_data;
11985b9c547cSRui Paulo 	const struct p2p_group_config *cfg;
11995b9c547cSRui Paulo 	struct wpa_supplicant *wpa_s_go;
12005b9c547cSRui Paulo 
12015b9c547cSRui Paulo 	if (!p2p_group_is_client_connected(group, data->info->p2p_device_addr))
12025b9c547cSRui Paulo 		return 1;
12035b9c547cSRui Paulo 
12045b9c547cSRui Paulo 	cfg = p2p_group_get_config(group);
12055b9c547cSRui Paulo 
12065b9c547cSRui Paulo 	wpa_s_go = wpas_get_p2p_go_iface(data->wpa_s, cfg->ssid,
12075b9c547cSRui Paulo 					 cfg->ssid_len);
12085b9c547cSRui Paulo 	if (wpa_s_go != NULL && wpa_s_go == data->wpa_s) {
12095b9c547cSRui Paulo 		wpas_dbus_signal_peer_groups_changed(
1210*780fb4a2SCy Schubert 			data->wpa_s->p2pdev, data->info->p2p_device_addr);
12115b9c547cSRui Paulo 		return 0;
12125b9c547cSRui Paulo 	}
12135b9c547cSRui Paulo 
12145b9c547cSRui Paulo 	return 1;
12155b9c547cSRui Paulo }
12165b9c547cSRui Paulo 
12175b9c547cSRui Paulo 
12185b9c547cSRui Paulo static void signal_peer_groups_changed(struct p2p_peer_info *info,
12195b9c547cSRui Paulo 				       void *user_data)
12205b9c547cSRui Paulo {
12215b9c547cSRui Paulo 	struct group_changed_data *data = user_data;
12225b9c547cSRui Paulo 	struct wpa_supplicant *wpa_s_go;
12235b9c547cSRui Paulo 
12245b9c547cSRui Paulo 	wpa_s_go = wpas_get_p2p_client_iface(data->wpa_s,
12255b9c547cSRui Paulo 					     info->p2p_device_addr);
12265b9c547cSRui Paulo 	if (wpa_s_go != NULL && wpa_s_go == data->wpa_s) {
1227*780fb4a2SCy Schubert 		wpas_dbus_signal_peer_groups_changed(data->wpa_s->p2pdev,
12285b9c547cSRui Paulo 						     info->p2p_device_addr);
12295b9c547cSRui Paulo 		return;
12305b9c547cSRui Paulo 	}
12315b9c547cSRui Paulo 
12325b9c547cSRui Paulo 	data->info = info;
12335b9c547cSRui Paulo 	p2p_loop_on_all_groups(data->wpa_s->global->p2p,
12345b9c547cSRui Paulo 			       match_group_where_peer_is_client, data);
12355b9c547cSRui Paulo 	data->info = NULL;
12365b9c547cSRui Paulo }
12375b9c547cSRui Paulo 
12385b9c547cSRui Paulo 
12395b9c547cSRui Paulo static void peer_groups_changed(struct wpa_supplicant *wpa_s)
12405b9c547cSRui Paulo {
12415b9c547cSRui Paulo 	struct group_changed_data data;
12425b9c547cSRui Paulo 
12435b9c547cSRui Paulo 	os_memset(&data, 0, sizeof(data));
12445b9c547cSRui Paulo 	data.wpa_s = wpa_s;
12455b9c547cSRui Paulo 
12465b9c547cSRui Paulo 	p2p_loop_on_known_peers(wpa_s->global->p2p,
12475b9c547cSRui Paulo 				signal_peer_groups_changed, &data);
12485b9c547cSRui Paulo }
12495b9c547cSRui Paulo 
12505b9c547cSRui Paulo 
1251d4f2939cSRui Paulo /**
1252d4f2939cSRui Paulo  * wpas_dbus_signal_p2p_group_started - Signals P2P group has
1253d4f2939cSRui Paulo  * started. Emitted when a group is successfully started
1254d4f2939cSRui Paulo  * irrespective of the role (client/GO) of the current device
1255d4f2939cSRui Paulo  *
1256d4f2939cSRui Paulo  * @wpa_s: %wpa_supplicant network interface data
1257d4f2939cSRui Paulo  * @client: this device is P2P client
1258*780fb4a2SCy Schubert  * @persistent: 0 - non persistent group, 1 - persistent group
1259d4f2939cSRui Paulo  */
1260d4f2939cSRui Paulo void wpas_dbus_signal_p2p_group_started(struct wpa_supplicant *wpa_s,
1261*780fb4a2SCy Schubert 					int client, int persistent)
1262d4f2939cSRui Paulo {
1263d4f2939cSRui Paulo 	DBusMessage *msg;
1264d4f2939cSRui Paulo 	DBusMessageIter iter, dict_iter;
1265d4f2939cSRui Paulo 	struct wpas_dbus_priv *iface;
12665b9c547cSRui Paulo 	struct wpa_supplicant *parent;
1267d4f2939cSRui Paulo 
12685b9c547cSRui Paulo 	parent = wpa_s->parent;
12695b9c547cSRui Paulo 	if (parent->p2p_mgmt)
12705b9c547cSRui Paulo 		parent = parent->parent;
12715b9c547cSRui Paulo 
12725b9c547cSRui Paulo 	iface = parent->global->dbus;
1273d4f2939cSRui Paulo 
1274d4f2939cSRui Paulo 	/* Do nothing if the control interface is not turned on */
1275325151a3SRui Paulo 	if (iface == NULL || !parent->dbus_new_path || !wpa_s->dbus_new_path)
1276d4f2939cSRui Paulo 		return;
1277d4f2939cSRui Paulo 
12785b9c547cSRui Paulo 	if (wpa_s->dbus_groupobj_path == NULL)
1279d4f2939cSRui Paulo 		return;
1280d4f2939cSRui Paulo 
1281d4f2939cSRui Paulo 	/* New interface has been created for this group */
12825b9c547cSRui Paulo 	msg = dbus_message_new_signal(parent->dbus_new_path,
1283d4f2939cSRui Paulo 				      WPAS_DBUS_NEW_IFACE_P2PDEVICE,
1284d4f2939cSRui Paulo 				      "GroupStarted");
1285d4f2939cSRui Paulo 	if (msg == NULL)
1286d4f2939cSRui Paulo 		return;
1287d4f2939cSRui Paulo 
1288d4f2939cSRui Paulo 	dbus_message_iter_init_append(msg, &iter);
1289d4f2939cSRui Paulo 	/*
1290d4f2939cSRui Paulo 	 * In case the device supports creating a separate interface the
1291d4f2939cSRui Paulo 	 * DBus client will need to know the object path for the interface
1292d4f2939cSRui Paulo 	 * object this group was created on, so include it here.
1293d4f2939cSRui Paulo 	 */
12945b9c547cSRui Paulo 	if (!wpa_dbus_dict_open_write(&iter, &dict_iter) ||
12955b9c547cSRui Paulo 	    !wpa_dbus_dict_append_object_path(&dict_iter,
1296d4f2939cSRui Paulo 					      "interface_object",
12975b9c547cSRui Paulo 					      wpa_s->dbus_new_path) ||
12985b9c547cSRui Paulo 	    !wpa_dbus_dict_append_string(&dict_iter, "role",
12995b9c547cSRui Paulo 					 client ? "client" : "GO") ||
1300*780fb4a2SCy Schubert 	    !wpa_dbus_dict_append_bool(&dict_iter, "persistent", persistent) ||
13015b9c547cSRui Paulo 	    !wpa_dbus_dict_append_object_path(&dict_iter, "group_object",
13025b9c547cSRui Paulo 					      wpa_s->dbus_groupobj_path) ||
13035b9c547cSRui Paulo 	    !wpa_dbus_dict_close_write(&iter, &dict_iter)) {
13045b9c547cSRui Paulo 		wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
13055b9c547cSRui Paulo 	} else {
1306d4f2939cSRui Paulo 		dbus_connection_send(iface->con, msg, NULL);
13075b9c547cSRui Paulo 		if (client)
13085b9c547cSRui Paulo 			peer_groups_changed(wpa_s);
13095b9c547cSRui Paulo 	}
1310d4f2939cSRui Paulo 	dbus_message_unref(msg);
1311d4f2939cSRui Paulo }
1312d4f2939cSRui Paulo 
1313d4f2939cSRui Paulo 
1314d4f2939cSRui Paulo /**
1315325151a3SRui Paulo  * wpas_dbus_signal_p2p_go_neg_resp - Emit GONegotiation Success/Failure signal
1316325151a3SRui Paulo  * @wpa_s: %wpa_supplicant network interface data
1317325151a3SRui Paulo  * @res: Result of the GO Neg Request
1318d4f2939cSRui Paulo  */
1319d4f2939cSRui Paulo void wpas_dbus_signal_p2p_go_neg_resp(struct wpa_supplicant *wpa_s,
1320d4f2939cSRui Paulo 				      struct p2p_go_neg_results *res)
1321d4f2939cSRui Paulo {
1322d4f2939cSRui Paulo 	DBusMessage *msg;
1323d4f2939cSRui Paulo 	DBusMessageIter iter, dict_iter;
1324d4f2939cSRui Paulo 	DBusMessageIter iter_dict_entry, iter_dict_val, iter_dict_array;
1325d4f2939cSRui Paulo 	struct wpas_dbus_priv *iface;
1326d4f2939cSRui Paulo 	char peer_obj_path[WPAS_DBUS_OBJECT_PATH_MAX], *path;
1327d4f2939cSRui Paulo 	dbus_int32_t freqs[P2P_MAX_CHANNELS];
1328d4f2939cSRui Paulo 	dbus_int32_t *f_array = freqs;
1329d4f2939cSRui Paulo 
1330d4f2939cSRui Paulo 
1331d4f2939cSRui Paulo 	iface = wpa_s->global->dbus;
1332d4f2939cSRui Paulo 
13335b9c547cSRui Paulo 	if (wpa_s->p2p_mgmt)
13345b9c547cSRui Paulo 		wpa_s = wpa_s->parent;
13355b9c547cSRui Paulo 
1336d4f2939cSRui Paulo 	os_memset(freqs, 0, sizeof(freqs));
1337d4f2939cSRui Paulo 	/* Do nothing if the control interface is not turned on */
1338325151a3SRui Paulo 	if (iface == NULL || !wpa_s->dbus_new_path)
1339d4f2939cSRui Paulo 		return;
1340d4f2939cSRui Paulo 
1341d4f2939cSRui Paulo 	os_snprintf(peer_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
1342d4f2939cSRui Paulo 		    "%s/" WPAS_DBUS_NEW_P2P_PEERS_PART "/" COMPACT_MACSTR,
1343d4f2939cSRui Paulo 		    wpa_s->dbus_new_path, MAC2STR(res->peer_device_addr));
1344d4f2939cSRui Paulo 	path = peer_obj_path;
1345d4f2939cSRui Paulo 
1346d4f2939cSRui Paulo 	msg = dbus_message_new_signal(wpa_s->dbus_new_path,
1347d4f2939cSRui Paulo 				      WPAS_DBUS_NEW_IFACE_P2PDEVICE,
1348d4f2939cSRui Paulo 				      res->status ? "GONegotiationFailure" :
1349d4f2939cSRui Paulo 						    "GONegotiationSuccess");
1350d4f2939cSRui Paulo 	if (msg == NULL)
1351d4f2939cSRui Paulo 		return;
1352d4f2939cSRui Paulo 
1353d4f2939cSRui Paulo 	dbus_message_iter_init_append(msg, &iter);
13545b9c547cSRui Paulo 	if (!wpa_dbus_dict_open_write(&iter, &dict_iter) ||
13555b9c547cSRui Paulo 	    !wpa_dbus_dict_append_object_path(&dict_iter, "peer_object",
1356d4f2939cSRui Paulo 					      path) ||
1357d4f2939cSRui Paulo 	    !wpa_dbus_dict_append_int32(&dict_iter, "status", res->status))
1358d4f2939cSRui Paulo 		goto err;
1359d4f2939cSRui Paulo 
1360d4f2939cSRui Paulo 	if (!res->status) {
1361d4f2939cSRui Paulo 		int i = 0;
1362d4f2939cSRui Paulo 		int freq_list_num = 0;
1363d4f2939cSRui Paulo 
13645b9c547cSRui Paulo 		if ((res->role_go &&
13655b9c547cSRui Paulo 		     !wpa_dbus_dict_append_string(&dict_iter, "passphrase",
13665b9c547cSRui Paulo 						  res->passphrase)) ||
13675b9c547cSRui Paulo 		    !wpa_dbus_dict_append_string(&dict_iter, "role_go",
1368d4f2939cSRui Paulo 						 res->role_go ? "GO" :
1369d4f2939cSRui Paulo 						 "client") ||
1370d4f2939cSRui Paulo 		    !wpa_dbus_dict_append_int32(&dict_iter, "frequency",
1371d4f2939cSRui Paulo 						res->freq) ||
1372d4f2939cSRui Paulo 		    !wpa_dbus_dict_append_byte_array(&dict_iter, "ssid",
1373d4f2939cSRui Paulo 						     (const char *) res->ssid,
1374d4f2939cSRui Paulo 						     res->ssid_len) ||
1375d4f2939cSRui Paulo 		    !wpa_dbus_dict_append_byte_array(&dict_iter,
1376d4f2939cSRui Paulo 						     "peer_device_addr",
1377d4f2939cSRui Paulo 						     (const char *)
1378d4f2939cSRui Paulo 						     res->peer_device_addr,
1379d4f2939cSRui Paulo 						     ETH_ALEN) ||
1380d4f2939cSRui Paulo 		    !wpa_dbus_dict_append_byte_array(&dict_iter,
1381d4f2939cSRui Paulo 						     "peer_interface_addr",
1382d4f2939cSRui Paulo 						     (const char *)
1383d4f2939cSRui Paulo 						     res->peer_interface_addr,
1384d4f2939cSRui Paulo 						     ETH_ALEN) ||
1385d4f2939cSRui Paulo 		    !wpa_dbus_dict_append_string(&dict_iter, "wps_method",
1386d4f2939cSRui Paulo 						 p2p_wps_method_text(
1387d4f2939cSRui Paulo 							 res->wps_method)))
1388d4f2939cSRui Paulo 			goto err;
1389d4f2939cSRui Paulo 
1390d4f2939cSRui Paulo 		for (i = 0; i < P2P_MAX_CHANNELS; i++) {
1391d4f2939cSRui Paulo 			if (res->freq_list[i]) {
1392d4f2939cSRui Paulo 				freqs[i] = res->freq_list[i];
1393d4f2939cSRui Paulo 				freq_list_num++;
1394d4f2939cSRui Paulo 			}
1395d4f2939cSRui Paulo 		}
1396d4f2939cSRui Paulo 
1397d4f2939cSRui Paulo 		if (!wpa_dbus_dict_begin_array(&dict_iter,
1398d4f2939cSRui Paulo 					       "frequency_list",
1399d4f2939cSRui Paulo 					       DBUS_TYPE_INT32_AS_STRING,
1400d4f2939cSRui Paulo 					       &iter_dict_entry,
1401d4f2939cSRui Paulo 					       &iter_dict_val,
14025b9c547cSRui Paulo 					       &iter_dict_array) ||
14035b9c547cSRui Paulo 		    !dbus_message_iter_append_fixed_array(&iter_dict_array,
1404d4f2939cSRui Paulo 							  DBUS_TYPE_INT32,
1405d4f2939cSRui Paulo 							  &f_array,
14065b9c547cSRui Paulo 							  freq_list_num) ||
14075b9c547cSRui Paulo 		    !wpa_dbus_dict_end_array(&dict_iter,
1408d4f2939cSRui Paulo 					     &iter_dict_entry,
1409d4f2939cSRui Paulo 					     &iter_dict_val,
14105b9c547cSRui Paulo 					     &iter_dict_array) ||
14115b9c547cSRui Paulo 		    !wpa_dbus_dict_append_int32(&dict_iter, "persistent_group",
1412d4f2939cSRui Paulo 						res->persistent_group) ||
1413d4f2939cSRui Paulo 		    !wpa_dbus_dict_append_uint32(&dict_iter,
1414d4f2939cSRui Paulo 						 "peer_config_timeout",
1415d4f2939cSRui Paulo 						 res->peer_config_timeout))
1416d4f2939cSRui Paulo 			goto err;
1417d4f2939cSRui Paulo 	}
1418d4f2939cSRui Paulo 
1419d4f2939cSRui Paulo 	if (!wpa_dbus_dict_close_write(&iter, &dict_iter))
1420d4f2939cSRui Paulo 		goto err;
1421d4f2939cSRui Paulo 
1422d4f2939cSRui Paulo 	dbus_connection_send(iface->con, msg, NULL);
1423d4f2939cSRui Paulo err:
1424d4f2939cSRui Paulo 	dbus_message_unref(msg);
1425d4f2939cSRui Paulo }
1426d4f2939cSRui Paulo 
1427d4f2939cSRui Paulo 
1428d4f2939cSRui Paulo /**
1429325151a3SRui Paulo  * wpas_dbus_signal_p2p_invitation_result - Emit InvitationResult signal
1430325151a3SRui Paulo  * @wpa_s: %wpa_supplicant network interface data
1431325151a3SRui Paulo  * @status: Status of invitation process
1432d4f2939cSRui Paulo  * @bssid: Basic Service Set Identifier
1433d4f2939cSRui Paulo  */
1434d4f2939cSRui Paulo void wpas_dbus_signal_p2p_invitation_result(struct wpa_supplicant *wpa_s,
1435d4f2939cSRui Paulo 					    int status, const u8 *bssid)
1436d4f2939cSRui Paulo {
1437d4f2939cSRui Paulo 	DBusMessage *msg;
1438d4f2939cSRui Paulo 	DBusMessageIter iter, dict_iter;
1439d4f2939cSRui Paulo 	struct wpas_dbus_priv *iface;
1440d4f2939cSRui Paulo 
14415b9c547cSRui Paulo 	wpa_printf(MSG_DEBUG, "%s", __func__);
1442d4f2939cSRui Paulo 
1443d4f2939cSRui Paulo 	iface = wpa_s->global->dbus;
1444d4f2939cSRui Paulo 	/* Do nothing if the control interface is not turned on */
1445d4f2939cSRui Paulo 	if (iface == NULL)
1446d4f2939cSRui Paulo 		return;
1447d4f2939cSRui Paulo 
14485b9c547cSRui Paulo 	if (wpa_s->p2p_mgmt)
14495b9c547cSRui Paulo 		wpa_s = wpa_s->parent;
1450325151a3SRui Paulo 	if (!wpa_s->dbus_new_path)
1451325151a3SRui Paulo 		return;
14525b9c547cSRui Paulo 
1453d4f2939cSRui Paulo 	msg = dbus_message_new_signal(wpa_s->dbus_new_path,
1454d4f2939cSRui Paulo 				      WPAS_DBUS_NEW_IFACE_P2PDEVICE,
1455d4f2939cSRui Paulo 				      "InvitationResult");
1456d4f2939cSRui Paulo 
1457d4f2939cSRui Paulo 	if (msg == NULL)
1458d4f2939cSRui Paulo 		return;
1459d4f2939cSRui Paulo 
1460d4f2939cSRui Paulo 	dbus_message_iter_init_append(msg, &iter);
14615b9c547cSRui Paulo 	if (!wpa_dbus_dict_open_write(&iter, &dict_iter) ||
14625b9c547cSRui Paulo 	    !wpa_dbus_dict_append_int32(&dict_iter, "status", status) ||
14635b9c547cSRui Paulo 	    (bssid &&
14645b9c547cSRui Paulo 	     !wpa_dbus_dict_append_byte_array(&dict_iter, "BSSID",
1465d4f2939cSRui Paulo 					      (const char *) bssid,
14665b9c547cSRui Paulo 					      ETH_ALEN)) ||
14675b9c547cSRui Paulo 	    !wpa_dbus_dict_close_write(&iter, &dict_iter))
14685b9c547cSRui Paulo 		wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
14695b9c547cSRui Paulo 	else
1470d4f2939cSRui Paulo 		dbus_connection_send(iface->con, msg, NULL);
1471d4f2939cSRui Paulo 	dbus_message_unref(msg);
1472d4f2939cSRui Paulo }
1473d4f2939cSRui Paulo 
1474d4f2939cSRui Paulo 
1475d4f2939cSRui Paulo /**
1476d4f2939cSRui Paulo  *
1477d4f2939cSRui Paulo  * Method to emit a signal for a peer joining the group.
1478d4f2939cSRui Paulo  * The signal will carry path to the group member object
1479d4f2939cSRui Paulo  * constructed using p2p i/f addr used for connecting.
1480d4f2939cSRui Paulo  *
1481d4f2939cSRui Paulo  * @wpa_s: %wpa_supplicant network interface data
14825b9c547cSRui Paulo  * @peer_addr: P2P Device Address of the peer joining the group
1483d4f2939cSRui Paulo  */
1484d4f2939cSRui Paulo void wpas_dbus_signal_p2p_peer_joined(struct wpa_supplicant *wpa_s,
14855b9c547cSRui Paulo 				      const u8 *peer_addr)
1486d4f2939cSRui Paulo {
1487d4f2939cSRui Paulo 	struct wpas_dbus_priv *iface;
1488d4f2939cSRui Paulo 	DBusMessage *msg;
1489d4f2939cSRui Paulo 	DBusMessageIter iter;
14905b9c547cSRui Paulo 	char peer_obj_path[WPAS_DBUS_OBJECT_PATH_MAX], *path;
14915b9c547cSRui Paulo 	struct wpa_supplicant *parent;
1492d4f2939cSRui Paulo 
1493d4f2939cSRui Paulo 	iface = wpa_s->global->dbus;
1494d4f2939cSRui Paulo 
1495d4f2939cSRui Paulo 	/* Do nothing if the control interface is not turned on */
1496d4f2939cSRui Paulo 	if (iface == NULL)
1497d4f2939cSRui Paulo 		return;
1498d4f2939cSRui Paulo 
1499d4f2939cSRui Paulo 	if (!wpa_s->dbus_groupobj_path)
1500d4f2939cSRui Paulo 		return;
1501d4f2939cSRui Paulo 
15025b9c547cSRui Paulo 	parent = wpa_s->parent;
15035b9c547cSRui Paulo 	if (parent->p2p_mgmt)
15045b9c547cSRui Paulo 		parent = parent->parent;
1505325151a3SRui Paulo 	if (!parent->dbus_new_path)
1506325151a3SRui Paulo 		return;
15075b9c547cSRui Paulo 
15085b9c547cSRui Paulo 	os_snprintf(peer_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
15095b9c547cSRui Paulo 			"%s/" WPAS_DBUS_NEW_P2P_PEERS_PART "/"
1510d4f2939cSRui Paulo 			COMPACT_MACSTR,
15115b9c547cSRui Paulo 			parent->dbus_new_path, MAC2STR(peer_addr));
1512d4f2939cSRui Paulo 
1513d4f2939cSRui Paulo 	msg = dbus_message_new_signal(wpa_s->dbus_groupobj_path,
1514d4f2939cSRui Paulo 				      WPAS_DBUS_NEW_IFACE_P2P_GROUP,
1515d4f2939cSRui Paulo 				      "PeerJoined");
1516d4f2939cSRui Paulo 	if (msg == NULL)
1517d4f2939cSRui Paulo 		return;
1518d4f2939cSRui Paulo 
1519d4f2939cSRui Paulo 	dbus_message_iter_init_append(msg, &iter);
15205b9c547cSRui Paulo 	path = peer_obj_path;
1521d4f2939cSRui Paulo 	if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_OBJECT_PATH,
15225b9c547cSRui Paulo 					    &path)) {
1523d4f2939cSRui Paulo 		wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
15245b9c547cSRui Paulo 	} else {
15255b9c547cSRui Paulo 		dbus_connection_send(iface->con, msg, NULL);
15265b9c547cSRui Paulo 		wpas_dbus_signal_peer_groups_changed(parent, peer_addr);
15275b9c547cSRui Paulo 	}
1528d4f2939cSRui Paulo 	dbus_message_unref(msg);
1529d4f2939cSRui Paulo }
1530d4f2939cSRui Paulo 
1531d4f2939cSRui Paulo 
1532d4f2939cSRui Paulo /**
1533d4f2939cSRui Paulo  *
1534d4f2939cSRui Paulo  * Method to emit a signal for a peer disconnecting the group.
1535d4f2939cSRui Paulo  * The signal will carry path to the group member object
15365b9c547cSRui Paulo  * constructed using the P2P Device Address of the peer.
1537d4f2939cSRui Paulo  *
1538d4f2939cSRui Paulo  * @wpa_s: %wpa_supplicant network interface data
15395b9c547cSRui Paulo  * @peer_addr: P2P Device Address of the peer joining the group
1540d4f2939cSRui Paulo  */
1541d4f2939cSRui Paulo void wpas_dbus_signal_p2p_peer_disconnected(struct wpa_supplicant *wpa_s,
15425b9c547cSRui Paulo 					    const u8 *peer_addr)
1543d4f2939cSRui Paulo {
1544d4f2939cSRui Paulo 	struct wpas_dbus_priv *iface;
1545d4f2939cSRui Paulo 	DBusMessage *msg;
1546d4f2939cSRui Paulo 	DBusMessageIter iter;
15475b9c547cSRui Paulo 	char peer_obj_path[WPAS_DBUS_OBJECT_PATH_MAX], *path;
15485b9c547cSRui Paulo 	struct wpa_supplicant *parent;
1549d4f2939cSRui Paulo 
1550d4f2939cSRui Paulo 	iface = wpa_s->global->dbus;
1551d4f2939cSRui Paulo 
1552d4f2939cSRui Paulo 	/* Do nothing if the control interface is not turned on */
1553d4f2939cSRui Paulo 	if (iface == NULL)
1554d4f2939cSRui Paulo 		return;
1555d4f2939cSRui Paulo 
1556d4f2939cSRui Paulo 	if (!wpa_s->dbus_groupobj_path)
1557d4f2939cSRui Paulo 		return;
1558d4f2939cSRui Paulo 
15595b9c547cSRui Paulo 	parent = wpa_s->parent;
15605b9c547cSRui Paulo 	if (parent->p2p_mgmt)
15615b9c547cSRui Paulo 		parent = parent->parent;
1562325151a3SRui Paulo 	if (!parent->dbus_new_path)
1563325151a3SRui Paulo 		return;
15645b9c547cSRui Paulo 
15655b9c547cSRui Paulo 	os_snprintf(peer_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
15665b9c547cSRui Paulo 			"%s/" WPAS_DBUS_NEW_P2P_PEERS_PART "/"
1567d4f2939cSRui Paulo 			COMPACT_MACSTR,
15685b9c547cSRui Paulo 			parent->dbus_new_path, MAC2STR(peer_addr));
1569d4f2939cSRui Paulo 
1570d4f2939cSRui Paulo 	msg = dbus_message_new_signal(wpa_s->dbus_groupobj_path,
1571d4f2939cSRui Paulo 				      WPAS_DBUS_NEW_IFACE_P2P_GROUP,
1572d4f2939cSRui Paulo 				      "PeerDisconnected");
1573d4f2939cSRui Paulo 	if (msg == NULL)
1574d4f2939cSRui Paulo 		return;
1575d4f2939cSRui Paulo 
1576d4f2939cSRui Paulo 	dbus_message_iter_init_append(msg, &iter);
15775b9c547cSRui Paulo 	path = peer_obj_path;
1578d4f2939cSRui Paulo 	if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_OBJECT_PATH,
15795b9c547cSRui Paulo 					    &path)) {
15805b9c547cSRui Paulo 		wpa_printf(MSG_ERROR,
15815b9c547cSRui Paulo 			   "dbus: Failed to construct PeerDisconnected signal");
15825b9c547cSRui Paulo 	} else {
1583d4f2939cSRui Paulo 		dbus_connection_send(iface->con, msg, NULL);
15845b9c547cSRui Paulo 		wpas_dbus_signal_peer_groups_changed(parent, peer_addr);
15855b9c547cSRui Paulo 	}
1586d4f2939cSRui Paulo 	dbus_message_unref(msg);
1587d4f2939cSRui Paulo }
1588d4f2939cSRui Paulo 
1589d4f2939cSRui Paulo 
1590d4f2939cSRui Paulo /**
1591d4f2939cSRui Paulo  *
1592d4f2939cSRui Paulo  * Method to emit a signal for a service discovery request.
1593d4f2939cSRui Paulo  * The signal will carry station address, frequency, dialog token,
1594d4f2939cSRui Paulo  * update indicator and it tlvs
1595d4f2939cSRui Paulo  *
1596d4f2939cSRui Paulo  * @wpa_s: %wpa_supplicant network interface data
1597d4f2939cSRui Paulo  * @sa: station addr (p2p i/f) of the peer
1598d4f2939cSRui Paulo  * @dialog_token: service discovery request dialog token
1599d4f2939cSRui Paulo  * @update_indic: service discovery request update indicator
1600d4f2939cSRui Paulo  * @tlvs: service discovery request genrated byte array of tlvs
1601d4f2939cSRui Paulo  * @tlvs_len: service discovery request tlvs length
1602d4f2939cSRui Paulo  */
1603d4f2939cSRui Paulo void wpas_dbus_signal_p2p_sd_request(struct wpa_supplicant *wpa_s,
1604d4f2939cSRui Paulo 				     int freq, const u8 *sa, u8 dialog_token,
1605d4f2939cSRui Paulo 				     u16 update_indic, const u8 *tlvs,
1606d4f2939cSRui Paulo 				     size_t tlvs_len)
1607d4f2939cSRui Paulo {
1608d4f2939cSRui Paulo 	DBusMessage *msg;
1609d4f2939cSRui Paulo 	DBusMessageIter iter, dict_iter;
1610d4f2939cSRui Paulo 	struct wpas_dbus_priv *iface;
1611d4f2939cSRui Paulo 	char peer_obj_path[WPAS_DBUS_OBJECT_PATH_MAX], *path;
16125b9c547cSRui Paulo 
1613d4f2939cSRui Paulo 	iface = wpa_s->global->dbus;
1614d4f2939cSRui Paulo 
1615d4f2939cSRui Paulo 	/* Do nothing if the control interface is not turned on */
1616d4f2939cSRui Paulo 	if (iface == NULL)
1617d4f2939cSRui Paulo 		return;
1618d4f2939cSRui Paulo 
16195b9c547cSRui Paulo 	if (wpa_s->p2p_mgmt)
16205b9c547cSRui Paulo 		wpa_s = wpa_s->parent;
1621325151a3SRui Paulo 	if (!wpa_s->dbus_new_path)
1622325151a3SRui Paulo 		return;
16235b9c547cSRui Paulo 
16245b9c547cSRui Paulo 	/* Check if this is a known peer */
16255b9c547cSRui Paulo 	if (!p2p_peer_known(wpa_s->global->p2p, sa))
16265b9c547cSRui Paulo 		return;
16275b9c547cSRui Paulo 
1628d4f2939cSRui Paulo 	msg = dbus_message_new_signal(wpa_s->dbus_new_path,
1629d4f2939cSRui Paulo 				      WPAS_DBUS_NEW_IFACE_P2PDEVICE,
1630d4f2939cSRui Paulo 				      "ServiceDiscoveryRequest");
1631d4f2939cSRui Paulo 	if (msg == NULL)
1632d4f2939cSRui Paulo 		return;
1633d4f2939cSRui Paulo 
1634d4f2939cSRui Paulo 	os_snprintf(peer_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
1635d4f2939cSRui Paulo 		    "%s/" WPAS_DBUS_NEW_P2P_PEERS_PART "/"
1636d4f2939cSRui Paulo 		    COMPACT_MACSTR, wpa_s->dbus_new_path, MAC2STR(sa));
1637d4f2939cSRui Paulo 
1638d4f2939cSRui Paulo 	path = peer_obj_path;
1639d4f2939cSRui Paulo 
1640d4f2939cSRui Paulo 	dbus_message_iter_init_append(msg, &iter);
16415b9c547cSRui Paulo 	if (!wpa_dbus_dict_open_write(&iter, &dict_iter) ||
16425b9c547cSRui Paulo 	    !wpa_dbus_dict_append_object_path(&dict_iter, "peer_object",
1643d4f2939cSRui Paulo 					      path) ||
1644d4f2939cSRui Paulo 	    !wpa_dbus_dict_append_int32(&dict_iter, "frequency", freq) ||
1645d4f2939cSRui Paulo 	    !wpa_dbus_dict_append_int32(&dict_iter, "dialog_token",
1646d4f2939cSRui Paulo 					dialog_token) ||
1647d4f2939cSRui Paulo 	    !wpa_dbus_dict_append_uint16(&dict_iter, "update_indicator",
1648d4f2939cSRui Paulo 					 update_indic) ||
1649d4f2939cSRui Paulo 	    !wpa_dbus_dict_append_byte_array(&dict_iter, "tlvs",
1650d4f2939cSRui Paulo 					     (const char *) tlvs,
1651d4f2939cSRui Paulo 					     tlvs_len) ||
1652d4f2939cSRui Paulo 	    !wpa_dbus_dict_close_write(&iter, &dict_iter))
1653d4f2939cSRui Paulo 		wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
16545b9c547cSRui Paulo 	else
16555b9c547cSRui Paulo 		dbus_connection_send(iface->con, msg, NULL);
1656d4f2939cSRui Paulo 	dbus_message_unref(msg);
1657d4f2939cSRui Paulo }
1658d4f2939cSRui Paulo 
1659d4f2939cSRui Paulo 
1660d4f2939cSRui Paulo /**
1661d4f2939cSRui Paulo  *
1662d4f2939cSRui Paulo  * Method to emit a signal for a service discovery response.
1663d4f2939cSRui Paulo  * The signal will carry station address, update indicator and it
1664d4f2939cSRui Paulo  * tlvs
1665d4f2939cSRui Paulo  *
1666d4f2939cSRui Paulo  * @wpa_s: %wpa_supplicant network interface data
1667d4f2939cSRui Paulo  * @sa: station addr (p2p i/f) of the peer
1668d4f2939cSRui Paulo  * @update_indic: service discovery request update indicator
1669d4f2939cSRui Paulo  * @tlvs: service discovery request genrated byte array of tlvs
1670d4f2939cSRui Paulo  * @tlvs_len: service discovery request tlvs length
1671d4f2939cSRui Paulo  */
1672d4f2939cSRui Paulo void wpas_dbus_signal_p2p_sd_response(struct wpa_supplicant *wpa_s,
1673d4f2939cSRui Paulo 				      const u8 *sa, u16 update_indic,
1674d4f2939cSRui Paulo 				      const u8 *tlvs, size_t tlvs_len)
1675d4f2939cSRui Paulo {
1676d4f2939cSRui Paulo 	DBusMessage *msg;
1677d4f2939cSRui Paulo 	DBusMessageIter iter, dict_iter;
1678d4f2939cSRui Paulo 	struct wpas_dbus_priv *iface;
1679d4f2939cSRui Paulo 	char peer_obj_path[WPAS_DBUS_OBJECT_PATH_MAX], *path;
16805b9c547cSRui Paulo 
1681d4f2939cSRui Paulo 	iface = wpa_s->global->dbus;
1682d4f2939cSRui Paulo 
1683d4f2939cSRui Paulo 	/* Do nothing if the control interface is not turned on */
1684d4f2939cSRui Paulo 	if (iface == NULL)
1685d4f2939cSRui Paulo 		return;
1686d4f2939cSRui Paulo 
16875b9c547cSRui Paulo 	if (wpa_s->p2p_mgmt)
16885b9c547cSRui Paulo 		wpa_s = wpa_s->parent;
1689325151a3SRui Paulo 	if (!wpa_s->dbus_new_path)
1690325151a3SRui Paulo 		return;
16915b9c547cSRui Paulo 
16925b9c547cSRui Paulo 	/* Check if this is a known peer */
16935b9c547cSRui Paulo 	if (!p2p_peer_known(wpa_s->global->p2p, sa))
16945b9c547cSRui Paulo 		return;
16955b9c547cSRui Paulo 
1696d4f2939cSRui Paulo 	msg = dbus_message_new_signal(wpa_s->dbus_new_path,
1697d4f2939cSRui Paulo 				      WPAS_DBUS_NEW_IFACE_P2PDEVICE,
1698d4f2939cSRui Paulo 				      "ServiceDiscoveryResponse");
1699d4f2939cSRui Paulo 	if (msg == NULL)
1700d4f2939cSRui Paulo 		return;
1701d4f2939cSRui Paulo 
1702d4f2939cSRui Paulo 	os_snprintf(peer_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
1703d4f2939cSRui Paulo 		    "%s/" WPAS_DBUS_NEW_P2P_PEERS_PART "/"
1704d4f2939cSRui Paulo 		    COMPACT_MACSTR, wpa_s->dbus_new_path, MAC2STR(sa));
1705d4f2939cSRui Paulo 
1706d4f2939cSRui Paulo 	path = peer_obj_path;
1707d4f2939cSRui Paulo 
1708d4f2939cSRui Paulo 	dbus_message_iter_init_append(msg, &iter);
17095b9c547cSRui Paulo 	if (!wpa_dbus_dict_open_write(&iter, &dict_iter) ||
17105b9c547cSRui Paulo 	    !wpa_dbus_dict_append_object_path(&dict_iter, "peer_object",
1711d4f2939cSRui Paulo 					      path) ||
1712d4f2939cSRui Paulo 	    !wpa_dbus_dict_append_uint16(&dict_iter, "update_indicator",
1713d4f2939cSRui Paulo 					 update_indic) ||
1714d4f2939cSRui Paulo 	    !wpa_dbus_dict_append_byte_array(&dict_iter, "tlvs",
1715d4f2939cSRui Paulo 					     (const char *) tlvs,
1716d4f2939cSRui Paulo 					     tlvs_len) ||
1717d4f2939cSRui Paulo 	    !wpa_dbus_dict_close_write(&iter, &dict_iter))
17185b9c547cSRui Paulo 		wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
17195b9c547cSRui Paulo 	else
1720d4f2939cSRui Paulo 		dbus_connection_send(iface->con, msg, NULL);
1721d4f2939cSRui Paulo 	dbus_message_unref(msg);
1722d4f2939cSRui Paulo }
1723d4f2939cSRui Paulo 
17245b9c547cSRui Paulo 
1725d4f2939cSRui Paulo /**
1726d4f2939cSRui Paulo  * wpas_dbus_signal_persistent_group - Send a persistent group related
1727d4f2939cSRui Paulo  *	event signal
1728d4f2939cSRui Paulo  * @wpa_s: %wpa_supplicant network interface data
1729d4f2939cSRui Paulo  * @id: new persistent group id
1730d4f2939cSRui Paulo  * @sig_name: signal name - PersistentGroupAdded, PersistentGroupRemoved
1731d4f2939cSRui Paulo  * @properties: determines if add second argument with object properties
1732d4f2939cSRui Paulo  *
1733d4f2939cSRui Paulo  * Notify listeners about an event related to persistent groups.
1734d4f2939cSRui Paulo  */
1735d4f2939cSRui Paulo static void wpas_dbus_signal_persistent_group(struct wpa_supplicant *wpa_s,
1736d4f2939cSRui Paulo 					      int id, const char *sig_name,
1737d4f2939cSRui Paulo 					      int properties)
1738d4f2939cSRui Paulo {
1739d4f2939cSRui Paulo 	struct wpas_dbus_priv *iface;
1740d4f2939cSRui Paulo 	DBusMessage *msg;
1741d4f2939cSRui Paulo 	DBusMessageIter iter;
1742d4f2939cSRui Paulo 	char pgrp_obj_path[WPAS_DBUS_OBJECT_PATH_MAX], *path;
1743d4f2939cSRui Paulo 
1744d4f2939cSRui Paulo 	iface = wpa_s->global->dbus;
1745d4f2939cSRui Paulo 
1746d4f2939cSRui Paulo 	/* Do nothing if the control interface is not turned on */
1747d4f2939cSRui Paulo 	if (iface == NULL)
1748d4f2939cSRui Paulo 		return;
1749d4f2939cSRui Paulo 
17505b9c547cSRui Paulo 	if (wpa_s->p2p_mgmt)
17515b9c547cSRui Paulo 		wpa_s = wpa_s->parent;
1752325151a3SRui Paulo 	if (!wpa_s->dbus_new_path)
1753325151a3SRui Paulo 		return;
17545b9c547cSRui Paulo 
1755d4f2939cSRui Paulo 	os_snprintf(pgrp_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
1756d4f2939cSRui Paulo 		    "%s/" WPAS_DBUS_NEW_PERSISTENT_GROUPS_PART "/%u",
1757d4f2939cSRui Paulo 		    wpa_s->dbus_new_path, id);
1758d4f2939cSRui Paulo 
1759d4f2939cSRui Paulo 	msg = dbus_message_new_signal(wpa_s->dbus_new_path,
1760d4f2939cSRui Paulo 				      WPAS_DBUS_NEW_IFACE_P2PDEVICE,
1761d4f2939cSRui Paulo 				      sig_name);
1762d4f2939cSRui Paulo 	if (msg == NULL)
1763d4f2939cSRui Paulo 		return;
1764d4f2939cSRui Paulo 
1765d4f2939cSRui Paulo 	dbus_message_iter_init_append(msg, &iter);
1766d4f2939cSRui Paulo 	path = pgrp_obj_path;
1767d4f2939cSRui Paulo 	if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_OBJECT_PATH,
17685b9c547cSRui Paulo 					    &path) ||
17695b9c547cSRui Paulo 	    (properties &&
17705b9c547cSRui Paulo 	     !wpa_dbus_get_object_properties(
1771d4f2939cSRui Paulo 		     iface, pgrp_obj_path,
17725b9c547cSRui Paulo 		     WPAS_DBUS_NEW_IFACE_PERSISTENT_GROUP, &iter)))
17735b9c547cSRui Paulo 		wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
17745b9c547cSRui Paulo 	else
1775d4f2939cSRui Paulo 		dbus_connection_send(iface->con, msg, NULL);
1776d4f2939cSRui Paulo 
1777d4f2939cSRui Paulo 	dbus_message_unref(msg);
1778d4f2939cSRui Paulo }
1779d4f2939cSRui Paulo 
1780d4f2939cSRui Paulo 
1781d4f2939cSRui Paulo /**
1782d4f2939cSRui Paulo  * wpas_dbus_signal_persistent_group_added - Send a persistent_group
1783d4f2939cSRui Paulo  *	added signal
1784d4f2939cSRui Paulo  * @wpa_s: %wpa_supplicant network interface data
1785d4f2939cSRui Paulo  * @id: new persistent group id
1786d4f2939cSRui Paulo  *
1787d4f2939cSRui Paulo  * Notify listeners about addition of a new persistent group.
1788d4f2939cSRui Paulo  */
1789d4f2939cSRui Paulo static void wpas_dbus_signal_persistent_group_added(
1790d4f2939cSRui Paulo 	struct wpa_supplicant *wpa_s, int id)
1791d4f2939cSRui Paulo {
1792d4f2939cSRui Paulo 	wpas_dbus_signal_persistent_group(wpa_s, id, "PersistentGroupAdded",
1793d4f2939cSRui Paulo 					  TRUE);
1794d4f2939cSRui Paulo }
1795d4f2939cSRui Paulo 
1796d4f2939cSRui Paulo 
1797d4f2939cSRui Paulo /**
1798d4f2939cSRui Paulo  * wpas_dbus_signal_persistent_group_removed - Send a persistent_group
1799d4f2939cSRui Paulo  *	removed signal
1800d4f2939cSRui Paulo  * @wpa_s: %wpa_supplicant network interface data
1801d4f2939cSRui Paulo  * @id: persistent group id
1802d4f2939cSRui Paulo  *
1803d4f2939cSRui Paulo  * Notify listeners about removal of a persistent group.
1804d4f2939cSRui Paulo  */
1805d4f2939cSRui Paulo static void wpas_dbus_signal_persistent_group_removed(
1806d4f2939cSRui Paulo 	struct wpa_supplicant *wpa_s, int id)
1807d4f2939cSRui Paulo {
1808d4f2939cSRui Paulo 	wpas_dbus_signal_persistent_group(wpa_s, id, "PersistentGroupRemoved",
1809d4f2939cSRui Paulo 					  FALSE);
1810d4f2939cSRui Paulo }
1811d4f2939cSRui Paulo 
1812d4f2939cSRui Paulo 
1813d4f2939cSRui Paulo /**
1814d4f2939cSRui Paulo  * wpas_dbus_signal_p2p_wps_failed - Signals WpsFailed event
1815d4f2939cSRui Paulo  * @wpa_s: %wpa_supplicant network interface data
1816325151a3SRui Paulo  * @fail: WPS failure information
1817d4f2939cSRui Paulo  *
1818d4f2939cSRui Paulo  * Sends Event dbus signal with name "fail" and dictionary containing
1819d4f2939cSRui Paulo  * "msg" field with fail message number (int32) as arguments
1820d4f2939cSRui Paulo  */
1821d4f2939cSRui Paulo void wpas_dbus_signal_p2p_wps_failed(struct wpa_supplicant *wpa_s,
1822d4f2939cSRui Paulo 				     struct wps_event_fail *fail)
1823d4f2939cSRui Paulo {
1824d4f2939cSRui Paulo 
1825d4f2939cSRui Paulo 	DBusMessage *msg;
1826d4f2939cSRui Paulo 	DBusMessageIter iter, dict_iter;
1827d4f2939cSRui Paulo 	struct wpas_dbus_priv *iface;
1828d4f2939cSRui Paulo 	char *key = "fail";
1829d4f2939cSRui Paulo 
1830d4f2939cSRui Paulo 	iface = wpa_s->global->dbus;
1831d4f2939cSRui Paulo 
1832d4f2939cSRui Paulo 	/* Do nothing if the control interface is not turned on */
1833d4f2939cSRui Paulo 	if (iface == NULL)
1834d4f2939cSRui Paulo 		return;
1835d4f2939cSRui Paulo 
18365b9c547cSRui Paulo 	if (wpa_s->p2p_mgmt)
18375b9c547cSRui Paulo 		wpa_s = wpa_s->parent;
18385b9c547cSRui Paulo 
1839325151a3SRui Paulo 	if (!wpa_s->dbus_new_path)
1840325151a3SRui Paulo 		return;
1841d4f2939cSRui Paulo 	msg = dbus_message_new_signal(wpa_s->dbus_new_path,
1842d4f2939cSRui Paulo 				      WPAS_DBUS_NEW_IFACE_P2PDEVICE,
1843d4f2939cSRui Paulo 				      "WpsFailed");
1844d4f2939cSRui Paulo 	if (msg == NULL)
1845d4f2939cSRui Paulo 		return;
1846d4f2939cSRui Paulo 
1847d4f2939cSRui Paulo 	dbus_message_iter_init_append(msg, &iter);
1848d4f2939cSRui Paulo 
1849d4f2939cSRui Paulo 	if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &key) ||
1850d4f2939cSRui Paulo 	    !wpa_dbus_dict_open_write(&iter, &dict_iter) ||
1851d4f2939cSRui Paulo 	    !wpa_dbus_dict_append_int32(&dict_iter, "msg", fail->msg) ||
1852d4f2939cSRui Paulo 	    !wpa_dbus_dict_append_int16(&dict_iter, "config_error",
1853d4f2939cSRui Paulo 					fail->config_error) ||
1854d4f2939cSRui Paulo 	    !wpa_dbus_dict_close_write(&iter, &dict_iter))
1855d4f2939cSRui Paulo 		wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
1856d4f2939cSRui Paulo 	else
1857d4f2939cSRui Paulo 		dbus_connection_send(iface->con, msg, NULL);
1858d4f2939cSRui Paulo 
1859d4f2939cSRui Paulo 	dbus_message_unref(msg);
1860d4f2939cSRui Paulo }
1861d4f2939cSRui Paulo 
1862325151a3SRui Paulo 
1863325151a3SRui Paulo /**
1864325151a3SRui Paulo  * wpas_dbus_signal_p2p_group_formation_failure - Signals GroupFormationFailure event
1865325151a3SRui Paulo  * @wpa_s: %wpa_supplicant network interface data
1866325151a3SRui Paulo  * @reason: indicates the reason code for group formation failure
1867325151a3SRui Paulo  *
1868325151a3SRui Paulo  * Sends Event dbus signal and string reason code when available.
1869325151a3SRui Paulo  */
1870325151a3SRui Paulo void wpas_dbus_signal_p2p_group_formation_failure(struct wpa_supplicant *wpa_s,
1871325151a3SRui Paulo 						  const char *reason)
1872325151a3SRui Paulo {
1873325151a3SRui Paulo 	DBusMessage *msg;
1874325151a3SRui Paulo 	struct wpas_dbus_priv *iface;
1875325151a3SRui Paulo 
1876325151a3SRui Paulo 	iface = wpa_s->global->dbus;
1877325151a3SRui Paulo 
1878325151a3SRui Paulo 	/* Do nothing if the control interface is not turned on */
1879325151a3SRui Paulo 	if (iface == NULL)
1880325151a3SRui Paulo 		return;
1881325151a3SRui Paulo 
1882325151a3SRui Paulo 	msg = dbus_message_new_signal(wpa_s->dbus_new_path,
1883325151a3SRui Paulo 				      WPAS_DBUS_NEW_IFACE_P2PDEVICE,
1884325151a3SRui Paulo 				      "GroupFormationFailure");
1885325151a3SRui Paulo 	if (msg == NULL)
1886325151a3SRui Paulo 		return;
1887325151a3SRui Paulo 
1888325151a3SRui Paulo 	if (dbus_message_append_args(msg, DBUS_TYPE_STRING, &reason,
1889325151a3SRui Paulo 				     DBUS_TYPE_INVALID))
1890325151a3SRui Paulo 		dbus_connection_send(iface->con, msg, NULL);
1891325151a3SRui Paulo 	else
1892325151a3SRui Paulo 		wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
1893325151a3SRui Paulo 
1894325151a3SRui Paulo 	dbus_message_unref(msg);
1895325151a3SRui Paulo }
1896325151a3SRui Paulo 
1897325151a3SRui Paulo 
1898325151a3SRui Paulo /**
1899325151a3SRui Paulo  * wpas_dbus_signal_p2p_invitation_received - Emit InvitationReceived signal
1900325151a3SRui Paulo  * @wpa_s: %wpa_supplicant network interface data
1901325151a3SRui Paulo  * @sa: Source address of the Invitation Request
1902325151a3SRui Paulo  * @dev_add: GO Device Address
1903325151a3SRui Paulo  * @bssid: P2P Group BSSID or %NULL if not received
1904325151a3SRui Paulo  * @id: Persistent group id or %0 if not persistent group
1905325151a3SRui Paulo  * @op_freq: Operating frequency for the group
1906325151a3SRui Paulo  */
1907325151a3SRui Paulo 
1908325151a3SRui Paulo void wpas_dbus_signal_p2p_invitation_received(struct wpa_supplicant *wpa_s,
1909325151a3SRui Paulo 					      const u8 *sa, const u8 *dev_addr,
1910325151a3SRui Paulo 					      const u8 *bssid, int id,
1911325151a3SRui Paulo 					      int op_freq)
1912325151a3SRui Paulo {
1913325151a3SRui Paulo 	DBusMessage *msg;
1914325151a3SRui Paulo 	DBusMessageIter iter, dict_iter;
1915325151a3SRui Paulo 	struct wpas_dbus_priv *iface;
1916325151a3SRui Paulo 
1917325151a3SRui Paulo 	iface = wpa_s->global->dbus;
1918325151a3SRui Paulo 
1919325151a3SRui Paulo 	/* Do nothing if the control interface is not turned on */
1920325151a3SRui Paulo 	if (iface == NULL)
1921325151a3SRui Paulo 		return;
1922325151a3SRui Paulo 
1923325151a3SRui Paulo 	msg = dbus_message_new_signal(wpa_s->dbus_new_path,
1924325151a3SRui Paulo 				      WPAS_DBUS_NEW_IFACE_P2PDEVICE,
1925325151a3SRui Paulo 				      "InvitationReceived");
1926325151a3SRui Paulo 	if (msg == NULL)
1927325151a3SRui Paulo 		return;
1928325151a3SRui Paulo 
1929325151a3SRui Paulo 	dbus_message_iter_init_append(msg, &iter);
1930325151a3SRui Paulo 	if (!wpa_dbus_dict_open_write(&iter, &dict_iter) ||
1931325151a3SRui Paulo 	    (sa &&
1932325151a3SRui Paulo 	     !wpa_dbus_dict_append_byte_array(&dict_iter, "sa",
1933325151a3SRui Paulo 					      (const char *) sa, ETH_ALEN)) ||
1934325151a3SRui Paulo 	    (dev_addr &&
1935325151a3SRui Paulo 	     !wpa_dbus_dict_append_byte_array(&dict_iter, "go_dev_addr",
1936325151a3SRui Paulo 					      (const char *) dev_addr,
1937325151a3SRui Paulo 					      ETH_ALEN)) ||
1938325151a3SRui Paulo 	    (bssid &&
1939325151a3SRui Paulo 	     !wpa_dbus_dict_append_byte_array(&dict_iter, "bssid",
1940325151a3SRui Paulo 					      (const char *) bssid,
1941325151a3SRui Paulo 					      ETH_ALEN)) ||
1942325151a3SRui Paulo 	    (id &&
1943325151a3SRui Paulo 	     !wpa_dbus_dict_append_int32(&dict_iter, "persistent_id", id)) ||
1944325151a3SRui Paulo 	    !wpa_dbus_dict_append_int32(&dict_iter, "op_freq", op_freq) ||
1945325151a3SRui Paulo 	    !wpa_dbus_dict_close_write(&iter, &dict_iter)) {
1946325151a3SRui Paulo 		dbus_message_unref(msg);
1947325151a3SRui Paulo 		return;
1948325151a3SRui Paulo 	}
1949325151a3SRui Paulo 
1950325151a3SRui Paulo 	dbus_connection_send(iface->con, msg, NULL);
1951*780fb4a2SCy Schubert 	dbus_message_unref(msg);
1952325151a3SRui Paulo }
1953325151a3SRui Paulo 
1954325151a3SRui Paulo 
1955d4f2939cSRui Paulo #endif /* CONFIG_P2P */
1956d4f2939cSRui Paulo 
1957d4f2939cSRui Paulo 
1958d4f2939cSRui Paulo /**
1959d4f2939cSRui Paulo  * wpas_dbus_signal_prop_changed - Signals change of property
1960d4f2939cSRui Paulo  * @wpa_s: %wpa_supplicant network interface data
1961d4f2939cSRui Paulo  * @property: indicates which property has changed
1962d4f2939cSRui Paulo  *
1963d4f2939cSRui Paulo  * Sends PropertyChanged signals with path, interface and arguments
1964d4f2939cSRui Paulo  * depending on which property has changed.
1965d4f2939cSRui Paulo  */
1966d4f2939cSRui Paulo void wpas_dbus_signal_prop_changed(struct wpa_supplicant *wpa_s,
1967d4f2939cSRui Paulo 				   enum wpas_dbus_prop property)
1968d4f2939cSRui Paulo {
1969d4f2939cSRui Paulo 	char *prop;
1970d4f2939cSRui Paulo 	dbus_bool_t flush;
1971d4f2939cSRui Paulo 
1972d4f2939cSRui Paulo 	if (wpa_s->dbus_new_path == NULL)
1973d4f2939cSRui Paulo 		return; /* Skip signal since D-Bus setup is not yet ready */
1974d4f2939cSRui Paulo 
1975d4f2939cSRui Paulo 	flush = FALSE;
1976d4f2939cSRui Paulo 	switch (property) {
1977d4f2939cSRui Paulo 	case WPAS_DBUS_PROP_AP_SCAN:
1978d4f2939cSRui Paulo 		prop = "ApScan";
1979d4f2939cSRui Paulo 		break;
1980d4f2939cSRui Paulo 	case WPAS_DBUS_PROP_SCANNING:
1981d4f2939cSRui Paulo 		prop = "Scanning";
1982d4f2939cSRui Paulo 		break;
1983d4f2939cSRui Paulo 	case WPAS_DBUS_PROP_STATE:
1984d4f2939cSRui Paulo 		prop = "State";
1985d4f2939cSRui Paulo 		break;
1986d4f2939cSRui Paulo 	case WPAS_DBUS_PROP_CURRENT_BSS:
1987d4f2939cSRui Paulo 		prop = "CurrentBSS";
1988d4f2939cSRui Paulo 		break;
1989d4f2939cSRui Paulo 	case WPAS_DBUS_PROP_CURRENT_NETWORK:
1990d4f2939cSRui Paulo 		prop = "CurrentNetwork";
1991d4f2939cSRui Paulo 		break;
1992d4f2939cSRui Paulo 	case WPAS_DBUS_PROP_BSSS:
1993d4f2939cSRui Paulo 		prop = "BSSs";
1994d4f2939cSRui Paulo 		break;
1995d4f2939cSRui Paulo 	case WPAS_DBUS_PROP_CURRENT_AUTH_MODE:
1996d4f2939cSRui Paulo 		prop = "CurrentAuthMode";
1997d4f2939cSRui Paulo 		break;
1998d4f2939cSRui Paulo 	case WPAS_DBUS_PROP_DISCONNECT_REASON:
1999d4f2939cSRui Paulo 		prop = "DisconnectReason";
2000d4f2939cSRui Paulo 		flush = TRUE;
2001d4f2939cSRui Paulo 		break;
2002*780fb4a2SCy Schubert 	case WPAS_DBUS_PROP_ASSOC_STATUS_CODE:
2003*780fb4a2SCy Schubert 		prop = "AssocStatusCode";
2004*780fb4a2SCy Schubert 		flush = TRUE;
2005*780fb4a2SCy Schubert 		break;
2006d4f2939cSRui Paulo 	default:
2007d4f2939cSRui Paulo 		wpa_printf(MSG_ERROR, "dbus: %s: Unknown Property value %d",
2008d4f2939cSRui Paulo 			   __func__, property);
2009d4f2939cSRui Paulo 		return;
2010d4f2939cSRui Paulo 	}
2011d4f2939cSRui Paulo 
2012d4f2939cSRui Paulo 	wpa_dbus_mark_property_changed(wpa_s->global->dbus,
2013d4f2939cSRui Paulo 				       wpa_s->dbus_new_path,
2014d4f2939cSRui Paulo 				       WPAS_DBUS_NEW_IFACE_INTERFACE, prop);
2015d4f2939cSRui Paulo 	if (flush) {
2016d4f2939cSRui Paulo 		wpa_dbus_flush_object_changed_properties(
2017d4f2939cSRui Paulo 			wpa_s->global->dbus->con, wpa_s->dbus_new_path);
2018d4f2939cSRui Paulo 	}
2019d4f2939cSRui Paulo }
2020d4f2939cSRui Paulo 
2021d4f2939cSRui Paulo 
2022d4f2939cSRui Paulo /**
2023d4f2939cSRui Paulo  * wpas_dbus_bss_signal_prop_changed - Signals change of BSS property
2024d4f2939cSRui Paulo  * @wpa_s: %wpa_supplicant network interface data
2025d4f2939cSRui Paulo  * @property: indicates which property has changed
2026d4f2939cSRui Paulo  * @id: unique BSS identifier
2027d4f2939cSRui Paulo  *
2028d4f2939cSRui Paulo  * Sends PropertyChanged signals with path, interface, and arguments depending
2029d4f2939cSRui Paulo  * on which property has changed.
2030d4f2939cSRui Paulo  */
2031d4f2939cSRui Paulo void wpas_dbus_bss_signal_prop_changed(struct wpa_supplicant *wpa_s,
2032d4f2939cSRui Paulo 				       enum wpas_dbus_bss_prop property,
2033d4f2939cSRui Paulo 				       unsigned int id)
2034d4f2939cSRui Paulo {
2035d4f2939cSRui Paulo 	char path[WPAS_DBUS_OBJECT_PATH_MAX];
2036d4f2939cSRui Paulo 	char *prop;
2037d4f2939cSRui Paulo 
2038325151a3SRui Paulo 	if (!wpa_s->dbus_new_path)
2039325151a3SRui Paulo 		return;
2040325151a3SRui Paulo 
2041d4f2939cSRui Paulo 	switch (property) {
2042d4f2939cSRui Paulo 	case WPAS_DBUS_BSS_PROP_SIGNAL:
2043d4f2939cSRui Paulo 		prop = "Signal";
2044d4f2939cSRui Paulo 		break;
2045d4f2939cSRui Paulo 	case WPAS_DBUS_BSS_PROP_FREQ:
2046d4f2939cSRui Paulo 		prop = "Frequency";
2047d4f2939cSRui Paulo 		break;
2048d4f2939cSRui Paulo 	case WPAS_DBUS_BSS_PROP_MODE:
2049d4f2939cSRui Paulo 		prop = "Mode";
2050d4f2939cSRui Paulo 		break;
2051d4f2939cSRui Paulo 	case WPAS_DBUS_BSS_PROP_PRIVACY:
2052d4f2939cSRui Paulo 		prop = "Privacy";
2053d4f2939cSRui Paulo 		break;
2054d4f2939cSRui Paulo 	case WPAS_DBUS_BSS_PROP_RATES:
2055d4f2939cSRui Paulo 		prop = "Rates";
2056d4f2939cSRui Paulo 		break;
2057d4f2939cSRui Paulo 	case WPAS_DBUS_BSS_PROP_WPA:
2058d4f2939cSRui Paulo 		prop = "WPA";
2059d4f2939cSRui Paulo 		break;
2060d4f2939cSRui Paulo 	case WPAS_DBUS_BSS_PROP_RSN:
2061d4f2939cSRui Paulo 		prop = "RSN";
2062d4f2939cSRui Paulo 		break;
20635b9c547cSRui Paulo 	case WPAS_DBUS_BSS_PROP_WPS:
20645b9c547cSRui Paulo 		prop = "WPS";
20655b9c547cSRui Paulo 		break;
2066d4f2939cSRui Paulo 	case WPAS_DBUS_BSS_PROP_IES:
2067d4f2939cSRui Paulo 		prop = "IEs";
2068d4f2939cSRui Paulo 		break;
20695b9c547cSRui Paulo 	case WPAS_DBUS_BSS_PROP_AGE:
20705b9c547cSRui Paulo 		prop = "Age";
20715b9c547cSRui Paulo 		break;
2072d4f2939cSRui Paulo 	default:
2073d4f2939cSRui Paulo 		wpa_printf(MSG_ERROR, "dbus: %s: Unknown Property value %d",
2074d4f2939cSRui Paulo 			   __func__, property);
2075d4f2939cSRui Paulo 		return;
2076d4f2939cSRui Paulo 	}
2077d4f2939cSRui Paulo 
2078d4f2939cSRui Paulo 	os_snprintf(path, WPAS_DBUS_OBJECT_PATH_MAX,
2079d4f2939cSRui Paulo 		    "%s/" WPAS_DBUS_NEW_BSSIDS_PART "/%u",
2080d4f2939cSRui Paulo 		    wpa_s->dbus_new_path, id);
2081d4f2939cSRui Paulo 
2082d4f2939cSRui Paulo 	wpa_dbus_mark_property_changed(wpa_s->global->dbus, path,
2083d4f2939cSRui Paulo 				       WPAS_DBUS_NEW_IFACE_BSS, prop);
2084d4f2939cSRui Paulo }
2085d4f2939cSRui Paulo 
2086d4f2939cSRui Paulo 
2087d4f2939cSRui Paulo /**
2088d4f2939cSRui Paulo  * wpas_dbus_signal_debug_level_changed - Signals change of debug param
2089d4f2939cSRui Paulo  * @global: wpa_global structure
2090d4f2939cSRui Paulo  *
2091d4f2939cSRui Paulo  * Sends PropertyChanged signals informing that debug level has changed.
2092d4f2939cSRui Paulo  */
2093d4f2939cSRui Paulo void wpas_dbus_signal_debug_level_changed(struct wpa_global *global)
2094d4f2939cSRui Paulo {
2095d4f2939cSRui Paulo 	wpa_dbus_mark_property_changed(global->dbus, WPAS_DBUS_NEW_PATH,
2096d4f2939cSRui Paulo 				       WPAS_DBUS_NEW_INTERFACE,
2097d4f2939cSRui Paulo 				       "DebugLevel");
2098d4f2939cSRui Paulo }
2099d4f2939cSRui Paulo 
2100d4f2939cSRui Paulo 
2101d4f2939cSRui Paulo /**
2102d4f2939cSRui Paulo  * wpas_dbus_signal_debug_timestamp_changed - Signals change of debug param
2103d4f2939cSRui Paulo  * @global: wpa_global structure
2104d4f2939cSRui Paulo  *
2105d4f2939cSRui Paulo  * Sends PropertyChanged signals informing that debug timestamp has changed.
2106d4f2939cSRui Paulo  */
2107d4f2939cSRui Paulo void wpas_dbus_signal_debug_timestamp_changed(struct wpa_global *global)
2108d4f2939cSRui Paulo {
2109d4f2939cSRui Paulo 	wpa_dbus_mark_property_changed(global->dbus, WPAS_DBUS_NEW_PATH,
2110d4f2939cSRui Paulo 				       WPAS_DBUS_NEW_INTERFACE,
2111d4f2939cSRui Paulo 				       "DebugTimestamp");
2112d4f2939cSRui Paulo }
2113d4f2939cSRui Paulo 
2114d4f2939cSRui Paulo 
2115d4f2939cSRui Paulo /**
2116d4f2939cSRui Paulo  * wpas_dbus_signal_debug_show_keys_changed - Signals change of debug param
2117d4f2939cSRui Paulo  * @global: wpa_global structure
2118d4f2939cSRui Paulo  *
2119d4f2939cSRui Paulo  * Sends PropertyChanged signals informing that debug show_keys has changed.
2120d4f2939cSRui Paulo  */
2121d4f2939cSRui Paulo void wpas_dbus_signal_debug_show_keys_changed(struct wpa_global *global)
2122d4f2939cSRui Paulo {
2123d4f2939cSRui Paulo 	wpa_dbus_mark_property_changed(global->dbus, WPAS_DBUS_NEW_PATH,
2124d4f2939cSRui Paulo 				       WPAS_DBUS_NEW_INTERFACE,
2125d4f2939cSRui Paulo 				       "DebugShowKeys");
2126d4f2939cSRui Paulo }
2127d4f2939cSRui Paulo 
2128d4f2939cSRui Paulo 
2129d4f2939cSRui Paulo static void wpas_dbus_register(struct wpa_dbus_object_desc *obj_desc,
2130d4f2939cSRui Paulo 			       void *priv,
2131d4f2939cSRui Paulo 			       WPADBusArgumentFreeFunction priv_free,
2132d4f2939cSRui Paulo 			       const struct wpa_dbus_method_desc *methods,
2133d4f2939cSRui Paulo 			       const struct wpa_dbus_property_desc *properties,
2134d4f2939cSRui Paulo 			       const struct wpa_dbus_signal_desc *signals)
2135d4f2939cSRui Paulo {
2136d4f2939cSRui Paulo 	int n;
2137d4f2939cSRui Paulo 
2138d4f2939cSRui Paulo 	obj_desc->user_data = priv;
2139d4f2939cSRui Paulo 	obj_desc->user_data_free_func = priv_free;
2140d4f2939cSRui Paulo 	obj_desc->methods = methods;
2141d4f2939cSRui Paulo 	obj_desc->properties = properties;
2142d4f2939cSRui Paulo 	obj_desc->signals = signals;
2143d4f2939cSRui Paulo 
2144d4f2939cSRui Paulo 	for (n = 0; properties && properties->dbus_property; properties++)
2145d4f2939cSRui Paulo 		n++;
2146d4f2939cSRui Paulo 
2147d4f2939cSRui Paulo 	obj_desc->prop_changed_flags = os_zalloc(n);
2148d4f2939cSRui Paulo 	if (!obj_desc->prop_changed_flags)
2149d4f2939cSRui Paulo 		wpa_printf(MSG_DEBUG, "dbus: %s: can't register handlers",
2150d4f2939cSRui Paulo 			   __func__);
2151d4f2939cSRui Paulo }
2152d4f2939cSRui Paulo 
2153d4f2939cSRui Paulo 
2154d4f2939cSRui Paulo static const struct wpa_dbus_method_desc wpas_dbus_global_methods[] = {
2155d4f2939cSRui Paulo 	{ "CreateInterface", WPAS_DBUS_NEW_INTERFACE,
21565b9c547cSRui Paulo 	  (WPADBusMethodHandler) wpas_dbus_handler_create_interface,
2157d4f2939cSRui Paulo 	  {
2158d4f2939cSRui Paulo 		  { "args", "a{sv}", ARG_IN },
2159d4f2939cSRui Paulo 		  { "path", "o", ARG_OUT },
2160d4f2939cSRui Paulo 		  END_ARGS
2161d4f2939cSRui Paulo 	  }
2162d4f2939cSRui Paulo 	},
2163d4f2939cSRui Paulo 	{ "RemoveInterface", WPAS_DBUS_NEW_INTERFACE,
21645b9c547cSRui Paulo 	  (WPADBusMethodHandler) wpas_dbus_handler_remove_interface,
2165d4f2939cSRui Paulo 	  {
2166d4f2939cSRui Paulo 		  { "path", "o", ARG_IN },
2167d4f2939cSRui Paulo 		  END_ARGS
2168d4f2939cSRui Paulo 	  }
2169d4f2939cSRui Paulo 	},
2170d4f2939cSRui Paulo 	{ "GetInterface", WPAS_DBUS_NEW_INTERFACE,
21715b9c547cSRui Paulo 	  (WPADBusMethodHandler) wpas_dbus_handler_get_interface,
2172d4f2939cSRui Paulo 	  {
2173d4f2939cSRui Paulo 		  { "ifname", "s", ARG_IN },
2174d4f2939cSRui Paulo 		  { "path", "o", ARG_OUT },
2175d4f2939cSRui Paulo 		  END_ARGS
2176d4f2939cSRui Paulo 	  }
2177d4f2939cSRui Paulo 	},
2178*780fb4a2SCy Schubert 	{ "ExpectDisconnect", WPAS_DBUS_NEW_INTERFACE,
2179*780fb4a2SCy Schubert 	  (WPADBusMethodHandler) wpas_dbus_handler_expect_disconnect,
2180*780fb4a2SCy Schubert 	  {
2181*780fb4a2SCy Schubert 		END_ARGS
2182*780fb4a2SCy Schubert 	  }
2183*780fb4a2SCy Schubert 	},
2184d4f2939cSRui Paulo 	{ NULL, NULL, NULL, { END_ARGS } }
2185d4f2939cSRui Paulo };
2186d4f2939cSRui Paulo 
2187d4f2939cSRui Paulo static const struct wpa_dbus_property_desc wpas_dbus_global_properties[] = {
2188d4f2939cSRui Paulo 	{ "DebugLevel", WPAS_DBUS_NEW_INTERFACE, "s",
2189d4f2939cSRui Paulo 	  wpas_dbus_getter_debug_level,
2190*780fb4a2SCy Schubert 	  wpas_dbus_setter_debug_level,
2191*780fb4a2SCy Schubert 	  NULL
2192d4f2939cSRui Paulo 	},
2193d4f2939cSRui Paulo 	{ "DebugTimestamp", WPAS_DBUS_NEW_INTERFACE, "b",
2194d4f2939cSRui Paulo 	  wpas_dbus_getter_debug_timestamp,
2195*780fb4a2SCy Schubert 	  wpas_dbus_setter_debug_timestamp,
2196*780fb4a2SCy Schubert 	  NULL
2197d4f2939cSRui Paulo 	},
2198d4f2939cSRui Paulo 	{ "DebugShowKeys", WPAS_DBUS_NEW_INTERFACE, "b",
2199d4f2939cSRui Paulo 	  wpas_dbus_getter_debug_show_keys,
2200*780fb4a2SCy Schubert 	  wpas_dbus_setter_debug_show_keys,
2201*780fb4a2SCy Schubert 	  NULL
2202d4f2939cSRui Paulo 	},
2203d4f2939cSRui Paulo 	{ "Interfaces", WPAS_DBUS_NEW_INTERFACE, "ao",
2204d4f2939cSRui Paulo 	  wpas_dbus_getter_interfaces,
2205*780fb4a2SCy Schubert 	  NULL,
2206d4f2939cSRui Paulo 	  NULL
2207d4f2939cSRui Paulo 	},
2208d4f2939cSRui Paulo 	{ "EapMethods", WPAS_DBUS_NEW_INTERFACE, "as",
2209d4f2939cSRui Paulo 	  wpas_dbus_getter_eap_methods,
2210*780fb4a2SCy Schubert 	  NULL,
2211d4f2939cSRui Paulo 	  NULL
2212d4f2939cSRui Paulo 	},
2213d4f2939cSRui Paulo 	{ "Capabilities", WPAS_DBUS_NEW_INTERFACE, "as",
2214d4f2939cSRui Paulo 	  wpas_dbus_getter_global_capabilities,
2215*780fb4a2SCy Schubert 	  NULL,
2216d4f2939cSRui Paulo 	  NULL
2217d4f2939cSRui Paulo 	},
22185b9c547cSRui Paulo #ifdef CONFIG_WIFI_DISPLAY
22195b9c547cSRui Paulo 	{ "WFDIEs", WPAS_DBUS_NEW_INTERFACE, "ay",
22205b9c547cSRui Paulo 	  wpas_dbus_getter_global_wfd_ies,
2221*780fb4a2SCy Schubert 	  wpas_dbus_setter_global_wfd_ies,
2222*780fb4a2SCy Schubert 	  NULL
22235b9c547cSRui Paulo 	},
22245b9c547cSRui Paulo #endif /* CONFIG_WIFI_DISPLAY */
2225*780fb4a2SCy Schubert 	{ NULL, NULL, NULL, NULL, NULL, NULL }
2226d4f2939cSRui Paulo };
2227d4f2939cSRui Paulo 
2228d4f2939cSRui Paulo static const struct wpa_dbus_signal_desc wpas_dbus_global_signals[] = {
2229d4f2939cSRui Paulo 	{ "InterfaceAdded", WPAS_DBUS_NEW_INTERFACE,
2230d4f2939cSRui Paulo 	  {
2231d4f2939cSRui Paulo 		  { "path", "o", ARG_OUT },
2232d4f2939cSRui Paulo 		  { "properties", "a{sv}", ARG_OUT },
2233d4f2939cSRui Paulo 		  END_ARGS
2234d4f2939cSRui Paulo 	  }
2235d4f2939cSRui Paulo 	},
2236d4f2939cSRui Paulo 	{ "InterfaceRemoved", WPAS_DBUS_NEW_INTERFACE,
2237d4f2939cSRui Paulo 	  {
2238d4f2939cSRui Paulo 		  { "path", "o", ARG_OUT },
2239d4f2939cSRui Paulo 		  END_ARGS
2240d4f2939cSRui Paulo 	  }
2241d4f2939cSRui Paulo 	},
2242d4f2939cSRui Paulo 	/* Deprecated: use org.freedesktop.DBus.Properties.PropertiesChanged */
2243d4f2939cSRui Paulo 	{ "PropertiesChanged", WPAS_DBUS_NEW_INTERFACE,
2244d4f2939cSRui Paulo 	  {
2245d4f2939cSRui Paulo 		  { "properties", "a{sv}", ARG_OUT },
2246d4f2939cSRui Paulo 		  END_ARGS
2247d4f2939cSRui Paulo 	  }
2248d4f2939cSRui Paulo 	},
2249d4f2939cSRui Paulo 	{ NULL, NULL, { END_ARGS } }
2250d4f2939cSRui Paulo };
2251d4f2939cSRui Paulo 
2252d4f2939cSRui Paulo 
2253*780fb4a2SCy Schubert static char * uscore_to_dbus(const char *uscore)
2254*780fb4a2SCy Schubert {
2255*780fb4a2SCy Schubert 	const char *p = uscore;
2256*780fb4a2SCy Schubert 	char *str, *s;
2257*780fb4a2SCy Schubert 	dbus_bool_t last_was_uscore = TRUE;
2258*780fb4a2SCy Schubert 
2259*780fb4a2SCy Schubert 	s = str = os_zalloc(os_strlen(uscore) + 1);
2260*780fb4a2SCy Schubert 	if (!str)
2261*780fb4a2SCy Schubert 		return NULL;
2262*780fb4a2SCy Schubert 	while (p && *p) {
2263*780fb4a2SCy Schubert 		if (*p == '_') {
2264*780fb4a2SCy Schubert 			last_was_uscore = TRUE;
2265*780fb4a2SCy Schubert 		} else {
2266*780fb4a2SCy Schubert 			*s++ = last_was_uscore ? toupper(*p) : *p;
2267*780fb4a2SCy Schubert 			last_was_uscore = FALSE;
2268*780fb4a2SCy Schubert 		}
2269*780fb4a2SCy Schubert 		p++;
2270*780fb4a2SCy Schubert 	}
2271*780fb4a2SCy Schubert 
2272*780fb4a2SCy Schubert 	return str;
2273*780fb4a2SCy Schubert }
2274*780fb4a2SCy Schubert 
2275*780fb4a2SCy Schubert 
2276*780fb4a2SCy Schubert static int wpa_dbus_ctrl_iface_props_init(struct wpas_dbus_priv *priv);
2277*780fb4a2SCy Schubert 
2278*780fb4a2SCy Schubert 
2279*780fb4a2SCy Schubert static void wpa_dbus_ctrl_iface_props_deinit(struct wpas_dbus_priv *priv)
2280*780fb4a2SCy Schubert {
2281*780fb4a2SCy Schubert 	int idx = priv->globals_start;
2282*780fb4a2SCy Schubert 
2283*780fb4a2SCy Schubert 	/* Free all allocated property values */
2284*780fb4a2SCy Schubert 	while (priv->all_interface_properties[idx].dbus_property)
2285*780fb4a2SCy Schubert 		os_free((char *)
2286*780fb4a2SCy Schubert 			priv->all_interface_properties[idx++].dbus_property);
2287*780fb4a2SCy Schubert 	os_free((char *) priv->all_interface_properties);
2288*780fb4a2SCy Schubert }
2289*780fb4a2SCy Schubert 
2290*780fb4a2SCy Schubert 
2291d4f2939cSRui Paulo /**
2292d4f2939cSRui Paulo  * wpas_dbus_ctrl_iface_init - Initialize dbus control interface
2293d4f2939cSRui Paulo  * @global: Pointer to global data from wpa_supplicant_init()
2294d4f2939cSRui Paulo  * Returns: 0 on success or -1 on failure
2295d4f2939cSRui Paulo  *
2296*780fb4a2SCy Schubert  * Initialize the dbus control interface for wpa_supplicant and start
2297d4f2939cSRui Paulo  * receiving commands from external programs over the bus.
2298d4f2939cSRui Paulo  */
2299d4f2939cSRui Paulo int wpas_dbus_ctrl_iface_init(struct wpas_dbus_priv *priv)
2300d4f2939cSRui Paulo {
2301d4f2939cSRui Paulo 	struct wpa_dbus_object_desc *obj_desc;
2302d4f2939cSRui Paulo 	int ret;
2303d4f2939cSRui Paulo 
2304*780fb4a2SCy Schubert 	ret = wpa_dbus_ctrl_iface_props_init(priv);
2305*780fb4a2SCy Schubert 	if (ret < 0) {
2306*780fb4a2SCy Schubert 		wpa_printf(MSG_ERROR,
2307*780fb4a2SCy Schubert 			   "dbus: Not enough memory to init interface properties");
2308*780fb4a2SCy Schubert 		return -1;
2309*780fb4a2SCy Schubert 	}
2310*780fb4a2SCy Schubert 
2311d4f2939cSRui Paulo 	obj_desc = os_zalloc(sizeof(struct wpa_dbus_object_desc));
2312d4f2939cSRui Paulo 	if (!obj_desc) {
23135b9c547cSRui Paulo 		wpa_printf(MSG_ERROR,
23145b9c547cSRui Paulo 			   "Not enough memory to create object description");
2315*780fb4a2SCy Schubert 		goto error;
2316d4f2939cSRui Paulo 	}
2317d4f2939cSRui Paulo 
2318d4f2939cSRui Paulo 	wpas_dbus_register(obj_desc, priv->global, NULL,
2319d4f2939cSRui Paulo 			   wpas_dbus_global_methods,
2320d4f2939cSRui Paulo 			   wpas_dbus_global_properties,
2321d4f2939cSRui Paulo 			   wpas_dbus_global_signals);
2322d4f2939cSRui Paulo 
2323d4f2939cSRui Paulo 	wpa_printf(MSG_DEBUG, "dbus: Register D-Bus object '%s'",
2324d4f2939cSRui Paulo 		   WPAS_DBUS_NEW_PATH);
2325d4f2939cSRui Paulo 	ret = wpa_dbus_ctrl_iface_init(priv, WPAS_DBUS_NEW_PATH,
2326d4f2939cSRui Paulo 				       WPAS_DBUS_NEW_SERVICE,
2327d4f2939cSRui Paulo 				       obj_desc);
2328*780fb4a2SCy Schubert 	if (ret < 0) {
2329d4f2939cSRui Paulo 		free_dbus_object_desc(obj_desc);
2330*780fb4a2SCy Schubert 		goto error;
2331*780fb4a2SCy Schubert 	}
2332d4f2939cSRui Paulo 
2333*780fb4a2SCy Schubert 	priv->dbus_new_initialized = 1;
2334*780fb4a2SCy Schubert 	return 0;
2335*780fb4a2SCy Schubert 
2336*780fb4a2SCy Schubert error:
2337*780fb4a2SCy Schubert 	wpa_dbus_ctrl_iface_props_deinit(priv);
2338*780fb4a2SCy Schubert 	return -1;
2339d4f2939cSRui Paulo }
2340d4f2939cSRui Paulo 
2341d4f2939cSRui Paulo 
2342d4f2939cSRui Paulo /**
2343d4f2939cSRui Paulo  * wpas_dbus_ctrl_iface_deinit - Deinitialize dbus ctrl interface for
2344d4f2939cSRui Paulo  * wpa_supplicant
2345*780fb4a2SCy Schubert  * @priv: Pointer to dbus private data from wpas_dbus_init()
2346d4f2939cSRui Paulo  *
2347d4f2939cSRui Paulo  * Deinitialize the dbus control interface that was initialized with
2348d4f2939cSRui Paulo  * wpas_dbus_ctrl_iface_init().
2349d4f2939cSRui Paulo  */
2350*780fb4a2SCy Schubert void wpas_dbus_ctrl_iface_deinit(struct wpas_dbus_priv *priv)
2351d4f2939cSRui Paulo {
2352*780fb4a2SCy Schubert 	if (!priv->dbus_new_initialized)
2353d4f2939cSRui Paulo 		return;
2354d4f2939cSRui Paulo 	wpa_printf(MSG_DEBUG, "dbus: Unregister D-Bus object '%s'",
2355d4f2939cSRui Paulo 		   WPAS_DBUS_NEW_PATH);
2356*780fb4a2SCy Schubert 	dbus_connection_unregister_object_path(priv->con, WPAS_DBUS_NEW_PATH);
2357*780fb4a2SCy Schubert 	wpa_dbus_ctrl_iface_props_deinit(priv);
2358d4f2939cSRui Paulo }
2359d4f2939cSRui Paulo 
2360d4f2939cSRui Paulo 
2361d4f2939cSRui Paulo static void wpa_dbus_free(void *ptr)
2362d4f2939cSRui Paulo {
2363d4f2939cSRui Paulo 	os_free(ptr);
2364d4f2939cSRui Paulo }
2365d4f2939cSRui Paulo 
2366d4f2939cSRui Paulo 
2367d4f2939cSRui Paulo static const struct wpa_dbus_property_desc wpas_dbus_network_properties[] = {
2368d4f2939cSRui Paulo 	{ "Properties", WPAS_DBUS_NEW_IFACE_NETWORK, "a{sv}",
2369d4f2939cSRui Paulo 	  wpas_dbus_getter_network_properties,
2370*780fb4a2SCy Schubert 	  wpas_dbus_setter_network_properties,
2371*780fb4a2SCy Schubert 	  NULL
2372d4f2939cSRui Paulo 	},
2373d4f2939cSRui Paulo 	{ "Enabled", WPAS_DBUS_NEW_IFACE_NETWORK, "b",
2374d4f2939cSRui Paulo 	  wpas_dbus_getter_enabled,
2375*780fb4a2SCy Schubert 	  wpas_dbus_setter_enabled,
2376*780fb4a2SCy Schubert 	  NULL
2377d4f2939cSRui Paulo 	},
2378*780fb4a2SCy Schubert 	{ NULL, NULL, NULL, NULL, NULL, NULL }
2379d4f2939cSRui Paulo };
2380d4f2939cSRui Paulo 
2381d4f2939cSRui Paulo 
2382d4f2939cSRui Paulo static const struct wpa_dbus_signal_desc wpas_dbus_network_signals[] = {
2383d4f2939cSRui Paulo 	/* Deprecated: use org.freedesktop.DBus.Properties.PropertiesChanged */
2384d4f2939cSRui Paulo 	{ "PropertiesChanged", WPAS_DBUS_NEW_IFACE_NETWORK,
2385d4f2939cSRui Paulo 	  {
2386d4f2939cSRui Paulo 		  { "properties", "a{sv}", ARG_OUT },
2387d4f2939cSRui Paulo 		  END_ARGS
2388d4f2939cSRui Paulo 	  }
2389d4f2939cSRui Paulo 	},
2390d4f2939cSRui Paulo 	{ NULL, NULL, { END_ARGS } }
2391d4f2939cSRui Paulo };
2392d4f2939cSRui Paulo 
2393d4f2939cSRui Paulo 
2394d4f2939cSRui Paulo /**
2395d4f2939cSRui Paulo  * wpas_dbus_register_network - Register a configured network with dbus
2396d4f2939cSRui Paulo  * @wpa_s: wpa_supplicant interface structure
2397d4f2939cSRui Paulo  * @ssid: network configuration data
2398d4f2939cSRui Paulo  * Returns: 0 on success, -1 on failure
2399d4f2939cSRui Paulo  *
2400d4f2939cSRui Paulo  * Registers network representing object with dbus
2401d4f2939cSRui Paulo  */
2402d4f2939cSRui Paulo int wpas_dbus_register_network(struct wpa_supplicant *wpa_s,
2403d4f2939cSRui Paulo 			       struct wpa_ssid *ssid)
2404d4f2939cSRui Paulo {
2405d4f2939cSRui Paulo 	struct wpas_dbus_priv *ctrl_iface;
2406d4f2939cSRui Paulo 	struct wpa_dbus_object_desc *obj_desc;
2407d4f2939cSRui Paulo 	struct network_handler_args *arg;
2408d4f2939cSRui Paulo 	char net_obj_path[WPAS_DBUS_OBJECT_PATH_MAX];
2409d4f2939cSRui Paulo 
2410d4f2939cSRui Paulo #ifdef CONFIG_P2P
2411d4f2939cSRui Paulo 	/*
2412d4f2939cSRui Paulo 	 * If it is a persistent group register it as such.
2413d4f2939cSRui Paulo 	 * This is to handle cases where an interface is being initialized
2414d4f2939cSRui Paulo 	 * with a list of networks read from config.
2415d4f2939cSRui Paulo 	 */
2416d4f2939cSRui Paulo 	if (network_is_persistent_group(ssid))
2417d4f2939cSRui Paulo 		return wpas_dbus_register_persistent_group(wpa_s, ssid);
2418d4f2939cSRui Paulo #endif /* CONFIG_P2P */
2419d4f2939cSRui Paulo 
2420d4f2939cSRui Paulo 	/* Do nothing if the control interface is not turned on */
2421325151a3SRui Paulo 	if (wpa_s == NULL || wpa_s->global == NULL || !wpa_s->dbus_new_path)
2422d4f2939cSRui Paulo 		return 0;
2423d4f2939cSRui Paulo 	ctrl_iface = wpa_s->global->dbus;
2424d4f2939cSRui Paulo 	if (ctrl_iface == NULL)
2425d4f2939cSRui Paulo 		return 0;
2426d4f2939cSRui Paulo 
2427d4f2939cSRui Paulo 	os_snprintf(net_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
2428d4f2939cSRui Paulo 		    "%s/" WPAS_DBUS_NEW_NETWORKS_PART "/%u",
2429d4f2939cSRui Paulo 		    wpa_s->dbus_new_path, ssid->id);
2430d4f2939cSRui Paulo 
2431d4f2939cSRui Paulo 	wpa_printf(MSG_DEBUG, "dbus: Register network object '%s'",
2432d4f2939cSRui Paulo 		   net_obj_path);
2433d4f2939cSRui Paulo 	obj_desc = os_zalloc(sizeof(struct wpa_dbus_object_desc));
2434d4f2939cSRui Paulo 	if (!obj_desc) {
24355b9c547cSRui Paulo 		wpa_printf(MSG_ERROR,
24365b9c547cSRui Paulo 			   "Not enough memory to create object description");
2437d4f2939cSRui Paulo 		goto err;
2438d4f2939cSRui Paulo 	}
2439d4f2939cSRui Paulo 
2440d4f2939cSRui Paulo 	/* allocate memory for handlers arguments */
2441d4f2939cSRui Paulo 	arg = os_zalloc(sizeof(struct network_handler_args));
2442d4f2939cSRui Paulo 	if (!arg) {
24435b9c547cSRui Paulo 		wpa_printf(MSG_ERROR,
24445b9c547cSRui Paulo 			   "Not enough memory to create arguments for method");
2445d4f2939cSRui Paulo 		goto err;
2446d4f2939cSRui Paulo 	}
2447d4f2939cSRui Paulo 
2448d4f2939cSRui Paulo 	arg->wpa_s = wpa_s;
2449d4f2939cSRui Paulo 	arg->ssid = ssid;
2450d4f2939cSRui Paulo 
2451d4f2939cSRui Paulo 	wpas_dbus_register(obj_desc, arg, wpa_dbus_free, NULL,
2452d4f2939cSRui Paulo 			   wpas_dbus_network_properties,
2453d4f2939cSRui Paulo 			   wpas_dbus_network_signals);
2454d4f2939cSRui Paulo 
2455d4f2939cSRui Paulo 	if (wpa_dbus_register_object_per_iface(ctrl_iface, net_obj_path,
2456d4f2939cSRui Paulo 					       wpa_s->ifname, obj_desc))
2457d4f2939cSRui Paulo 		goto err;
2458d4f2939cSRui Paulo 
2459d4f2939cSRui Paulo 	wpas_dbus_signal_network_added(wpa_s, ssid->id);
2460d4f2939cSRui Paulo 
2461d4f2939cSRui Paulo 	return 0;
2462d4f2939cSRui Paulo 
2463d4f2939cSRui Paulo err:
2464d4f2939cSRui Paulo 	free_dbus_object_desc(obj_desc);
2465d4f2939cSRui Paulo 	return -1;
2466d4f2939cSRui Paulo }
2467d4f2939cSRui Paulo 
2468d4f2939cSRui Paulo 
2469d4f2939cSRui Paulo /**
2470d4f2939cSRui Paulo  * wpas_dbus_unregister_network - Unregister a configured network from dbus
2471d4f2939cSRui Paulo  * @wpa_s: wpa_supplicant interface structure
2472d4f2939cSRui Paulo  * @nid: network id
2473d4f2939cSRui Paulo  * Returns: 0 on success, -1 on failure
2474d4f2939cSRui Paulo  *
2475d4f2939cSRui Paulo  * Unregisters network representing object from dbus
2476d4f2939cSRui Paulo  */
2477d4f2939cSRui Paulo int wpas_dbus_unregister_network(struct wpa_supplicant *wpa_s, int nid)
2478d4f2939cSRui Paulo {
2479d4f2939cSRui Paulo 	struct wpas_dbus_priv *ctrl_iface;
2480d4f2939cSRui Paulo 	char net_obj_path[WPAS_DBUS_OBJECT_PATH_MAX];
2481d4f2939cSRui Paulo 	int ret;
2482d4f2939cSRui Paulo #ifdef CONFIG_P2P
2483d4f2939cSRui Paulo 	struct wpa_ssid *ssid;
2484d4f2939cSRui Paulo 
2485d4f2939cSRui Paulo 	ssid = wpa_config_get_network(wpa_s->conf, nid);
2486d4f2939cSRui Paulo 
2487d4f2939cSRui Paulo 	/* If it is a persistent group unregister it as such */
2488d4f2939cSRui Paulo 	if (ssid && network_is_persistent_group(ssid))
2489d4f2939cSRui Paulo 		return wpas_dbus_unregister_persistent_group(wpa_s, nid);
2490d4f2939cSRui Paulo #endif /* CONFIG_P2P */
2491d4f2939cSRui Paulo 
2492d4f2939cSRui Paulo 	/* Do nothing if the control interface is not turned on */
2493d4f2939cSRui Paulo 	if (wpa_s->global == NULL || wpa_s->dbus_new_path == NULL)
2494d4f2939cSRui Paulo 		return 0;
2495d4f2939cSRui Paulo 	ctrl_iface = wpa_s->global->dbus;
2496d4f2939cSRui Paulo 	if (ctrl_iface == NULL)
2497d4f2939cSRui Paulo 		return 0;
2498d4f2939cSRui Paulo 
2499d4f2939cSRui Paulo 	os_snprintf(net_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
2500d4f2939cSRui Paulo 		    "%s/" WPAS_DBUS_NEW_NETWORKS_PART "/%u",
2501d4f2939cSRui Paulo 		    wpa_s->dbus_new_path, nid);
2502d4f2939cSRui Paulo 
2503d4f2939cSRui Paulo 	wpa_printf(MSG_DEBUG, "dbus: Unregister network object '%s'",
2504d4f2939cSRui Paulo 		   net_obj_path);
2505d4f2939cSRui Paulo 	ret = wpa_dbus_unregister_object_per_iface(ctrl_iface, net_obj_path);
2506d4f2939cSRui Paulo 
2507d4f2939cSRui Paulo 	if (!ret)
2508d4f2939cSRui Paulo 		wpas_dbus_signal_network_removed(wpa_s, nid);
2509d4f2939cSRui Paulo 
2510d4f2939cSRui Paulo 	return ret;
2511d4f2939cSRui Paulo }
2512d4f2939cSRui Paulo 
2513d4f2939cSRui Paulo 
2514d4f2939cSRui Paulo static const struct wpa_dbus_property_desc wpas_dbus_bss_properties[] = {
2515d4f2939cSRui Paulo 	{ "SSID", WPAS_DBUS_NEW_IFACE_BSS, "ay",
2516d4f2939cSRui Paulo 	  wpas_dbus_getter_bss_ssid,
2517*780fb4a2SCy Schubert 	  NULL,
2518d4f2939cSRui Paulo 	  NULL
2519d4f2939cSRui Paulo 	},
2520d4f2939cSRui Paulo 	{ "BSSID", WPAS_DBUS_NEW_IFACE_BSS, "ay",
2521d4f2939cSRui Paulo 	  wpas_dbus_getter_bss_bssid,
2522*780fb4a2SCy Schubert 	  NULL,
2523d4f2939cSRui Paulo 	  NULL
2524d4f2939cSRui Paulo 	},
2525d4f2939cSRui Paulo 	{ "Privacy", WPAS_DBUS_NEW_IFACE_BSS, "b",
2526d4f2939cSRui Paulo 	  wpas_dbus_getter_bss_privacy,
2527*780fb4a2SCy Schubert 	  NULL,
2528d4f2939cSRui Paulo 	  NULL
2529d4f2939cSRui Paulo 	},
2530d4f2939cSRui Paulo 	{ "Mode", WPAS_DBUS_NEW_IFACE_BSS, "s",
2531d4f2939cSRui Paulo 	  wpas_dbus_getter_bss_mode,
2532*780fb4a2SCy Schubert 	  NULL,
2533d4f2939cSRui Paulo 	  NULL
2534d4f2939cSRui Paulo 	},
2535d4f2939cSRui Paulo 	{ "Signal", WPAS_DBUS_NEW_IFACE_BSS, "n",
2536d4f2939cSRui Paulo 	  wpas_dbus_getter_bss_signal,
2537*780fb4a2SCy Schubert 	  NULL,
2538d4f2939cSRui Paulo 	  NULL
2539d4f2939cSRui Paulo 	},
2540d4f2939cSRui Paulo 	{ "Frequency", WPAS_DBUS_NEW_IFACE_BSS, "q",
2541d4f2939cSRui Paulo 	  wpas_dbus_getter_bss_frequency,
2542*780fb4a2SCy Schubert 	  NULL,
2543d4f2939cSRui Paulo 	  NULL
2544d4f2939cSRui Paulo 	},
2545d4f2939cSRui Paulo 	{ "Rates", WPAS_DBUS_NEW_IFACE_BSS, "au",
2546d4f2939cSRui Paulo 	  wpas_dbus_getter_bss_rates,
2547*780fb4a2SCy Schubert 	  NULL,
2548d4f2939cSRui Paulo 	  NULL
2549d4f2939cSRui Paulo 	},
2550d4f2939cSRui Paulo 	{ "WPA", WPAS_DBUS_NEW_IFACE_BSS, "a{sv}",
2551d4f2939cSRui Paulo 	  wpas_dbus_getter_bss_wpa,
2552*780fb4a2SCy Schubert 	  NULL,
2553d4f2939cSRui Paulo 	  NULL
2554d4f2939cSRui Paulo 	},
2555d4f2939cSRui Paulo 	{ "RSN", WPAS_DBUS_NEW_IFACE_BSS, "a{sv}",
2556d4f2939cSRui Paulo 	  wpas_dbus_getter_bss_rsn,
2557*780fb4a2SCy Schubert 	  NULL,
2558d4f2939cSRui Paulo 	  NULL
2559d4f2939cSRui Paulo 	},
2560d4f2939cSRui Paulo 	{ "WPS", WPAS_DBUS_NEW_IFACE_BSS, "a{sv}",
2561d4f2939cSRui Paulo 	  wpas_dbus_getter_bss_wps,
2562*780fb4a2SCy Schubert 	  NULL,
2563d4f2939cSRui Paulo 	  NULL
2564d4f2939cSRui Paulo 	},
2565d4f2939cSRui Paulo 	{ "IEs", WPAS_DBUS_NEW_IFACE_BSS, "ay",
2566d4f2939cSRui Paulo 	  wpas_dbus_getter_bss_ies,
2567*780fb4a2SCy Schubert 	  NULL,
2568d4f2939cSRui Paulo 	  NULL
2569d4f2939cSRui Paulo 	},
25705b9c547cSRui Paulo 	{ "Age", WPAS_DBUS_NEW_IFACE_BSS, "u",
25715b9c547cSRui Paulo 	  wpas_dbus_getter_bss_age,
2572*780fb4a2SCy Schubert 	  NULL,
25735b9c547cSRui Paulo 	  NULL
25745b9c547cSRui Paulo 	},
2575*780fb4a2SCy Schubert 	{ NULL, NULL, NULL, NULL, NULL, NULL }
2576d4f2939cSRui Paulo };
2577d4f2939cSRui Paulo 
2578d4f2939cSRui Paulo 
2579d4f2939cSRui Paulo static const struct wpa_dbus_signal_desc wpas_dbus_bss_signals[] = {
2580d4f2939cSRui Paulo 	/* Deprecated: use org.freedesktop.DBus.Properties.PropertiesChanged */
2581d4f2939cSRui Paulo 	{ "PropertiesChanged", WPAS_DBUS_NEW_IFACE_BSS,
2582d4f2939cSRui Paulo 	  {
2583d4f2939cSRui Paulo 		  { "properties", "a{sv}", ARG_OUT },
2584d4f2939cSRui Paulo 		  END_ARGS
2585d4f2939cSRui Paulo 	  }
2586d4f2939cSRui Paulo 	},
2587d4f2939cSRui Paulo 	{ NULL, NULL, { END_ARGS } }
2588d4f2939cSRui Paulo };
2589d4f2939cSRui Paulo 
2590d4f2939cSRui Paulo 
2591d4f2939cSRui Paulo /**
2592d4f2939cSRui Paulo  * wpas_dbus_unregister_bss - Unregister a scanned BSS from dbus
2593d4f2939cSRui Paulo  * @wpa_s: wpa_supplicant interface structure
2594d4f2939cSRui Paulo  * @bssid: scanned network bssid
2595d4f2939cSRui Paulo  * @id: unique BSS identifier
2596d4f2939cSRui Paulo  * Returns: 0 on success, -1 on failure
2597d4f2939cSRui Paulo  *
2598d4f2939cSRui Paulo  * Unregisters BSS representing object from dbus
2599d4f2939cSRui Paulo  */
2600d4f2939cSRui Paulo int wpas_dbus_unregister_bss(struct wpa_supplicant *wpa_s,
2601d4f2939cSRui Paulo 			     u8 bssid[ETH_ALEN], unsigned int id)
2602d4f2939cSRui Paulo {
2603d4f2939cSRui Paulo 	struct wpas_dbus_priv *ctrl_iface;
2604d4f2939cSRui Paulo 	char bss_obj_path[WPAS_DBUS_OBJECT_PATH_MAX];
2605d4f2939cSRui Paulo 
2606d4f2939cSRui Paulo 	/* Do nothing if the control interface is not turned on */
2607325151a3SRui Paulo 	if (wpa_s == NULL || wpa_s->global == NULL || !wpa_s->dbus_new_path)
2608d4f2939cSRui Paulo 		return 0;
2609d4f2939cSRui Paulo 	ctrl_iface = wpa_s->global->dbus;
2610d4f2939cSRui Paulo 	if (ctrl_iface == NULL)
2611d4f2939cSRui Paulo 		return 0;
2612d4f2939cSRui Paulo 
2613d4f2939cSRui Paulo 	os_snprintf(bss_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
2614d4f2939cSRui Paulo 		    "%s/" WPAS_DBUS_NEW_BSSIDS_PART "/%u",
2615d4f2939cSRui Paulo 		    wpa_s->dbus_new_path, id);
2616d4f2939cSRui Paulo 
2617d4f2939cSRui Paulo 	wpa_printf(MSG_DEBUG, "dbus: Unregister BSS object '%s'",
2618d4f2939cSRui Paulo 		   bss_obj_path);
2619d4f2939cSRui Paulo 	if (wpa_dbus_unregister_object_per_iface(ctrl_iface, bss_obj_path)) {
2620d4f2939cSRui Paulo 		wpa_printf(MSG_ERROR, "dbus: Cannot unregister BSS object %s",
2621d4f2939cSRui Paulo 			   bss_obj_path);
2622d4f2939cSRui Paulo 		return -1;
2623d4f2939cSRui Paulo 	}
2624d4f2939cSRui Paulo 
2625d4f2939cSRui Paulo 	wpas_dbus_signal_bss_removed(wpa_s, bss_obj_path);
2626d4f2939cSRui Paulo 	wpas_dbus_signal_prop_changed(wpa_s, WPAS_DBUS_PROP_BSSS);
2627d4f2939cSRui Paulo 
2628d4f2939cSRui Paulo 	return 0;
2629d4f2939cSRui Paulo }
2630d4f2939cSRui Paulo 
2631d4f2939cSRui Paulo 
2632d4f2939cSRui Paulo /**
2633d4f2939cSRui Paulo  * wpas_dbus_register_bss - Register a scanned BSS with dbus
2634d4f2939cSRui Paulo  * @wpa_s: wpa_supplicant interface structure
2635d4f2939cSRui Paulo  * @bssid: scanned network bssid
2636d4f2939cSRui Paulo  * @id: unique BSS identifier
2637d4f2939cSRui Paulo  * Returns: 0 on success, -1 on failure
2638d4f2939cSRui Paulo  *
2639d4f2939cSRui Paulo  * Registers BSS representing object with dbus
2640d4f2939cSRui Paulo  */
2641d4f2939cSRui Paulo int wpas_dbus_register_bss(struct wpa_supplicant *wpa_s,
2642d4f2939cSRui Paulo 			   u8 bssid[ETH_ALEN], unsigned int id)
2643d4f2939cSRui Paulo {
2644d4f2939cSRui Paulo 	struct wpas_dbus_priv *ctrl_iface;
2645d4f2939cSRui Paulo 	struct wpa_dbus_object_desc *obj_desc;
2646d4f2939cSRui Paulo 	char bss_obj_path[WPAS_DBUS_OBJECT_PATH_MAX];
2647d4f2939cSRui Paulo 	struct bss_handler_args *arg;
2648d4f2939cSRui Paulo 
2649d4f2939cSRui Paulo 	/* Do nothing if the control interface is not turned on */
2650325151a3SRui Paulo 	if (wpa_s == NULL || wpa_s->global == NULL || !wpa_s->dbus_new_path)
2651d4f2939cSRui Paulo 		return 0;
2652d4f2939cSRui Paulo 	ctrl_iface = wpa_s->global->dbus;
2653d4f2939cSRui Paulo 	if (ctrl_iface == NULL)
2654d4f2939cSRui Paulo 		return 0;
2655d4f2939cSRui Paulo 
2656d4f2939cSRui Paulo 	os_snprintf(bss_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
2657d4f2939cSRui Paulo 		    "%s/" WPAS_DBUS_NEW_BSSIDS_PART "/%u",
2658d4f2939cSRui Paulo 		    wpa_s->dbus_new_path, id);
2659d4f2939cSRui Paulo 
2660d4f2939cSRui Paulo 	obj_desc = os_zalloc(sizeof(struct wpa_dbus_object_desc));
2661d4f2939cSRui Paulo 	if (!obj_desc) {
26625b9c547cSRui Paulo 		wpa_printf(MSG_ERROR,
26635b9c547cSRui Paulo 			   "Not enough memory to create object description");
2664d4f2939cSRui Paulo 		goto err;
2665d4f2939cSRui Paulo 	}
2666d4f2939cSRui Paulo 
2667d4f2939cSRui Paulo 	arg = os_zalloc(sizeof(struct bss_handler_args));
2668d4f2939cSRui Paulo 	if (!arg) {
26695b9c547cSRui Paulo 		wpa_printf(MSG_ERROR,
26705b9c547cSRui Paulo 			   "Not enough memory to create arguments for handler");
2671d4f2939cSRui Paulo 		goto err;
2672d4f2939cSRui Paulo 	}
2673d4f2939cSRui Paulo 	arg->wpa_s = wpa_s;
2674d4f2939cSRui Paulo 	arg->id = id;
2675d4f2939cSRui Paulo 
2676d4f2939cSRui Paulo 	wpas_dbus_register(obj_desc, arg, wpa_dbus_free, NULL,
2677d4f2939cSRui Paulo 			   wpas_dbus_bss_properties,
2678d4f2939cSRui Paulo 			   wpas_dbus_bss_signals);
2679d4f2939cSRui Paulo 
2680d4f2939cSRui Paulo 	wpa_printf(MSG_DEBUG, "dbus: Register BSS object '%s'",
2681d4f2939cSRui Paulo 		   bss_obj_path);
2682d4f2939cSRui Paulo 	if (wpa_dbus_register_object_per_iface(ctrl_iface, bss_obj_path,
2683d4f2939cSRui Paulo 					       wpa_s->ifname, obj_desc)) {
2684d4f2939cSRui Paulo 		wpa_printf(MSG_ERROR,
2685d4f2939cSRui Paulo 			   "Cannot register BSSID dbus object %s.",
2686d4f2939cSRui Paulo 			   bss_obj_path);
2687d4f2939cSRui Paulo 		goto err;
2688d4f2939cSRui Paulo 	}
2689d4f2939cSRui Paulo 
2690d4f2939cSRui Paulo 	wpas_dbus_signal_bss_added(wpa_s, bss_obj_path);
2691d4f2939cSRui Paulo 	wpas_dbus_signal_prop_changed(wpa_s, WPAS_DBUS_PROP_BSSS);
2692d4f2939cSRui Paulo 
2693d4f2939cSRui Paulo 	return 0;
2694d4f2939cSRui Paulo 
2695d4f2939cSRui Paulo err:
2696d4f2939cSRui Paulo 	free_dbus_object_desc(obj_desc);
2697d4f2939cSRui Paulo 	return -1;
2698d4f2939cSRui Paulo }
2699d4f2939cSRui Paulo 
2700d4f2939cSRui Paulo 
2701d4f2939cSRui Paulo static const struct wpa_dbus_method_desc wpas_dbus_interface_methods[] = {
2702d4f2939cSRui Paulo 	{ "Scan", WPAS_DBUS_NEW_IFACE_INTERFACE,
27035b9c547cSRui Paulo 	  (WPADBusMethodHandler) wpas_dbus_handler_scan,
2704d4f2939cSRui Paulo 	  {
2705d4f2939cSRui Paulo 		  { "args", "a{sv}", ARG_IN },
2706d4f2939cSRui Paulo 		  END_ARGS
2707d4f2939cSRui Paulo 	  }
2708d4f2939cSRui Paulo 	},
27095b9c547cSRui Paulo 	{ "SignalPoll", WPAS_DBUS_NEW_IFACE_INTERFACE,
27105b9c547cSRui Paulo 	  (WPADBusMethodHandler) wpas_dbus_handler_signal_poll,
27115b9c547cSRui Paulo 	  {
27125b9c547cSRui Paulo 		  { "args", "a{sv}", ARG_OUT },
27135b9c547cSRui Paulo 		  END_ARGS
27145b9c547cSRui Paulo 	  }
27155b9c547cSRui Paulo 	},
2716d4f2939cSRui Paulo 	{ "Disconnect", WPAS_DBUS_NEW_IFACE_INTERFACE,
27175b9c547cSRui Paulo 	  (WPADBusMethodHandler) wpas_dbus_handler_disconnect,
2718d4f2939cSRui Paulo 	  {
2719d4f2939cSRui Paulo 		  END_ARGS
2720d4f2939cSRui Paulo 	  }
2721d4f2939cSRui Paulo 	},
2722d4f2939cSRui Paulo 	{ "AddNetwork", WPAS_DBUS_NEW_IFACE_INTERFACE,
27235b9c547cSRui Paulo 	  (WPADBusMethodHandler) wpas_dbus_handler_add_network,
2724d4f2939cSRui Paulo 	  {
2725d4f2939cSRui Paulo 		  { "args", "a{sv}", ARG_IN },
2726d4f2939cSRui Paulo 		  { "path", "o", ARG_OUT },
2727d4f2939cSRui Paulo 		  END_ARGS
2728d4f2939cSRui Paulo 	  }
2729d4f2939cSRui Paulo 	},
2730d4f2939cSRui Paulo 	{ "Reassociate", WPAS_DBUS_NEW_IFACE_INTERFACE,
27315b9c547cSRui Paulo 	  (WPADBusMethodHandler) wpas_dbus_handler_reassociate,
27325b9c547cSRui Paulo 	  {
27335b9c547cSRui Paulo 		  END_ARGS
27345b9c547cSRui Paulo 	  }
27355b9c547cSRui Paulo 	},
27365b9c547cSRui Paulo 	{ "Reattach", WPAS_DBUS_NEW_IFACE_INTERFACE,
27375b9c547cSRui Paulo 	  (WPADBusMethodHandler) wpas_dbus_handler_reattach,
2738d4f2939cSRui Paulo 	  {
2739d4f2939cSRui Paulo 		  END_ARGS
2740d4f2939cSRui Paulo 	  }
2741d4f2939cSRui Paulo 	},
2742325151a3SRui Paulo 	{ "Reconnect", WPAS_DBUS_NEW_IFACE_INTERFACE,
2743325151a3SRui Paulo 	  (WPADBusMethodHandler) wpas_dbus_handler_reconnect,
2744325151a3SRui Paulo 	  {
2745325151a3SRui Paulo 		  END_ARGS
2746325151a3SRui Paulo 	  }
2747325151a3SRui Paulo 	},
2748d4f2939cSRui Paulo 	{ "RemoveNetwork", WPAS_DBUS_NEW_IFACE_INTERFACE,
27495b9c547cSRui Paulo 	  (WPADBusMethodHandler) wpas_dbus_handler_remove_network,
2750d4f2939cSRui Paulo 	  {
2751d4f2939cSRui Paulo 		  { "path", "o", ARG_IN },
2752d4f2939cSRui Paulo 		  END_ARGS
2753d4f2939cSRui Paulo 	  }
2754d4f2939cSRui Paulo 	},
2755d4f2939cSRui Paulo 	{ "RemoveAllNetworks", WPAS_DBUS_NEW_IFACE_INTERFACE,
27565b9c547cSRui Paulo 	  (WPADBusMethodHandler) wpas_dbus_handler_remove_all_networks,
2757d4f2939cSRui Paulo 	  {
2758d4f2939cSRui Paulo 		  END_ARGS
2759d4f2939cSRui Paulo 	  }
2760d4f2939cSRui Paulo 	},
2761d4f2939cSRui Paulo 	{ "SelectNetwork", WPAS_DBUS_NEW_IFACE_INTERFACE,
27625b9c547cSRui Paulo 	  (WPADBusMethodHandler) wpas_dbus_handler_select_network,
2763d4f2939cSRui Paulo 	  {
2764d4f2939cSRui Paulo 		  { "path", "o", ARG_IN },
2765d4f2939cSRui Paulo 		  END_ARGS
2766d4f2939cSRui Paulo 	  }
2767d4f2939cSRui Paulo 	},
2768d4f2939cSRui Paulo 	{ "NetworkReply", WPAS_DBUS_NEW_IFACE_INTERFACE,
27695b9c547cSRui Paulo 	  (WPADBusMethodHandler) wpas_dbus_handler_network_reply,
2770d4f2939cSRui Paulo 	  {
2771d4f2939cSRui Paulo 		  { "path", "o", ARG_IN },
2772d4f2939cSRui Paulo 		  { "field", "s", ARG_IN },
2773d4f2939cSRui Paulo 		  { "value", "s", ARG_IN },
2774d4f2939cSRui Paulo 		  END_ARGS
2775d4f2939cSRui Paulo 	  }
2776d4f2939cSRui Paulo 	},
27775b9c547cSRui Paulo #ifndef CONFIG_NO_CONFIG_BLOBS
2778d4f2939cSRui Paulo 	{ "AddBlob", WPAS_DBUS_NEW_IFACE_INTERFACE,
27795b9c547cSRui Paulo 	  (WPADBusMethodHandler) wpas_dbus_handler_add_blob,
2780d4f2939cSRui Paulo 	  {
2781d4f2939cSRui Paulo 		  { "name", "s", ARG_IN },
2782d4f2939cSRui Paulo 		  { "data", "ay", ARG_IN },
2783d4f2939cSRui Paulo 		  END_ARGS
2784d4f2939cSRui Paulo 	  }
2785d4f2939cSRui Paulo 	},
2786d4f2939cSRui Paulo 	{ "GetBlob", WPAS_DBUS_NEW_IFACE_INTERFACE,
27875b9c547cSRui Paulo 	  (WPADBusMethodHandler) wpas_dbus_handler_get_blob,
2788d4f2939cSRui Paulo 	  {
2789d4f2939cSRui Paulo 		  { "name", "s", ARG_IN },
2790d4f2939cSRui Paulo 		  { "data", "ay", ARG_OUT },
2791d4f2939cSRui Paulo 		  END_ARGS
2792d4f2939cSRui Paulo 	  }
2793d4f2939cSRui Paulo 	},
2794d4f2939cSRui Paulo 	{ "RemoveBlob", WPAS_DBUS_NEW_IFACE_INTERFACE,
27955b9c547cSRui Paulo 	  (WPADBusMethodHandler) wpas_dbus_handler_remove_blob,
2796d4f2939cSRui Paulo 	  {
2797d4f2939cSRui Paulo 		  { "name", "s", ARG_IN },
2798d4f2939cSRui Paulo 		  END_ARGS
2799d4f2939cSRui Paulo 	  }
2800d4f2939cSRui Paulo 	},
28015b9c547cSRui Paulo #endif /* CONFIG_NO_CONFIG_BLOBS */
28025b9c547cSRui Paulo 	{ "SetPKCS11EngineAndModulePath", WPAS_DBUS_NEW_IFACE_INTERFACE,
28035b9c547cSRui Paulo 	  (WPADBusMethodHandler)
28045b9c547cSRui Paulo 	  wpas_dbus_handler_set_pkcs11_engine_and_module_path,
28055b9c547cSRui Paulo 	  {
28065b9c547cSRui Paulo 		  { "pkcs11_engine_path", "s", ARG_IN },
28075b9c547cSRui Paulo 		  { "pkcs11_module_path", "s", ARG_IN },
28085b9c547cSRui Paulo 		  END_ARGS
28095b9c547cSRui Paulo 	  }
28105b9c547cSRui Paulo 	},
2811d4f2939cSRui Paulo #ifdef CONFIG_WPS
2812d4f2939cSRui Paulo 	{ "Start", WPAS_DBUS_NEW_IFACE_WPS,
28135b9c547cSRui Paulo 	  (WPADBusMethodHandler) wpas_dbus_handler_wps_start,
2814d4f2939cSRui Paulo 	  {
2815d4f2939cSRui Paulo 		  { "args", "a{sv}", ARG_IN },
2816d4f2939cSRui Paulo 		  { "output", "a{sv}", ARG_OUT },
2817d4f2939cSRui Paulo 		  END_ARGS
2818d4f2939cSRui Paulo 	  }
2819d4f2939cSRui Paulo 	},
2820325151a3SRui Paulo 	{ "Cancel", WPAS_DBUS_NEW_IFACE_WPS,
2821325151a3SRui Paulo 	  (WPADBusMethodHandler) wpas_dbus_handler_wps_cancel,
2822325151a3SRui Paulo 	  {
2823325151a3SRui Paulo 		  END_ARGS
2824325151a3SRui Paulo 	  }
2825325151a3SRui Paulo 	},
2826d4f2939cSRui Paulo #endif /* CONFIG_WPS */
2827d4f2939cSRui Paulo #ifdef CONFIG_P2P
2828d4f2939cSRui Paulo 	{ "Find", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
2829d4f2939cSRui Paulo 	  (WPADBusMethodHandler) wpas_dbus_handler_p2p_find,
2830d4f2939cSRui Paulo 	  {
2831d4f2939cSRui Paulo 		  { "args", "a{sv}", ARG_IN },
2832d4f2939cSRui Paulo 		  END_ARGS
2833d4f2939cSRui Paulo 	  }
2834d4f2939cSRui Paulo 	},
2835d4f2939cSRui Paulo 	{ "StopFind", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
2836d4f2939cSRui Paulo 	  (WPADBusMethodHandler) wpas_dbus_handler_p2p_stop_find,
2837d4f2939cSRui Paulo 	  {
2838d4f2939cSRui Paulo 		  END_ARGS
2839d4f2939cSRui Paulo 	  }
2840d4f2939cSRui Paulo 	},
2841d4f2939cSRui Paulo 	{ "Listen", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
2842d4f2939cSRui Paulo 	  (WPADBusMethodHandler) wpas_dbus_handler_p2p_listen,
2843d4f2939cSRui Paulo 	  {
2844d4f2939cSRui Paulo 		  { "timeout", "i", ARG_IN },
2845d4f2939cSRui Paulo 		  END_ARGS
2846d4f2939cSRui Paulo 	  }
2847d4f2939cSRui Paulo 	},
2848d4f2939cSRui Paulo 	{ "ExtendedListen", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
2849d4f2939cSRui Paulo 	  (WPADBusMethodHandler) wpas_dbus_handler_p2p_extendedlisten,
2850d4f2939cSRui Paulo 	  {
2851d4f2939cSRui Paulo 		  { "args", "a{sv}", ARG_IN },
2852d4f2939cSRui Paulo 		  END_ARGS
2853d4f2939cSRui Paulo 	  }
2854d4f2939cSRui Paulo 	},
2855d4f2939cSRui Paulo 	{ "PresenceRequest", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
2856d4f2939cSRui Paulo 	  (WPADBusMethodHandler) wpas_dbus_handler_p2p_presence_request,
2857d4f2939cSRui Paulo 	  {
2858d4f2939cSRui Paulo 		  { "args", "a{sv}", ARG_IN },
2859d4f2939cSRui Paulo 		  END_ARGS
2860d4f2939cSRui Paulo 	  }
2861d4f2939cSRui Paulo 	},
2862d4f2939cSRui Paulo 	{ "ProvisionDiscoveryRequest", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
2863d4f2939cSRui Paulo 	  (WPADBusMethodHandler) wpas_dbus_handler_p2p_prov_disc_req,
2864d4f2939cSRui Paulo 	  {
2865d4f2939cSRui Paulo 		  { "peer", "o", ARG_IN },
2866d4f2939cSRui Paulo 		  { "config_method", "s", ARG_IN },
2867d4f2939cSRui Paulo 		  END_ARGS
2868d4f2939cSRui Paulo 	  }
2869d4f2939cSRui Paulo 	},
2870d4f2939cSRui Paulo 	{ "Connect", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
2871d4f2939cSRui Paulo 	  (WPADBusMethodHandler) wpas_dbus_handler_p2p_connect,
2872d4f2939cSRui Paulo 	  {
2873d4f2939cSRui Paulo 		  { "args", "a{sv}", ARG_IN },
2874d4f2939cSRui Paulo 		  { "generated_pin", "s", ARG_OUT },
2875d4f2939cSRui Paulo 		  END_ARGS
2876d4f2939cSRui Paulo 	  }
2877d4f2939cSRui Paulo 	},
2878d4f2939cSRui Paulo 	{ "GroupAdd", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
2879d4f2939cSRui Paulo 	  (WPADBusMethodHandler) wpas_dbus_handler_p2p_group_add,
2880d4f2939cSRui Paulo 	  {
2881d4f2939cSRui Paulo 		  { "args", "a{sv}", ARG_IN },
2882d4f2939cSRui Paulo 		  END_ARGS
2883d4f2939cSRui Paulo 	  }
2884d4f2939cSRui Paulo 	},
2885325151a3SRui Paulo 	{ "Cancel", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
2886325151a3SRui Paulo 	  (WPADBusMethodHandler) wpas_dbus_handler_p2p_cancel,
2887325151a3SRui Paulo 	  {
2888325151a3SRui Paulo 		  END_ARGS
2889325151a3SRui Paulo 	  }
2890325151a3SRui Paulo 	},
2891d4f2939cSRui Paulo 	{ "Invite", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
2892d4f2939cSRui Paulo 	  (WPADBusMethodHandler) wpas_dbus_handler_p2p_invite,
2893d4f2939cSRui Paulo 	  {
2894d4f2939cSRui Paulo 		  { "args", "a{sv}", ARG_IN },
2895d4f2939cSRui Paulo 		  END_ARGS
2896d4f2939cSRui Paulo 	  }
2897d4f2939cSRui Paulo 	},
2898d4f2939cSRui Paulo 	{ "Disconnect", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
2899d4f2939cSRui Paulo 	  (WPADBusMethodHandler) wpas_dbus_handler_p2p_disconnect,
2900d4f2939cSRui Paulo 	  {
2901d4f2939cSRui Paulo 		  END_ARGS
2902d4f2939cSRui Paulo 	  }
2903d4f2939cSRui Paulo 	},
2904d4f2939cSRui Paulo 	{ "RejectPeer", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
2905d4f2939cSRui Paulo 	  (WPADBusMethodHandler) wpas_dbus_handler_p2p_rejectpeer,
2906d4f2939cSRui Paulo 	  {
2907d4f2939cSRui Paulo 		  { "peer", "o", ARG_IN },
2908d4f2939cSRui Paulo 		  END_ARGS
2909d4f2939cSRui Paulo 	  }
2910d4f2939cSRui Paulo 	},
2911325151a3SRui Paulo 	{ "RemoveClient", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
2912325151a3SRui Paulo 	  (WPADBusMethodHandler) wpas_dbus_handler_p2p_remove_client,
2913325151a3SRui Paulo 	  {
2914325151a3SRui Paulo 		  { "args", "a{sv}", ARG_IN },
2915325151a3SRui Paulo 		  END_ARGS
2916325151a3SRui Paulo 	  }
2917325151a3SRui Paulo 	},
2918d4f2939cSRui Paulo 	{ "Flush", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
2919d4f2939cSRui Paulo 	  (WPADBusMethodHandler) wpas_dbus_handler_p2p_flush,
2920d4f2939cSRui Paulo 	  {
2921d4f2939cSRui Paulo 		  END_ARGS
2922d4f2939cSRui Paulo 	  }
2923d4f2939cSRui Paulo 	},
2924d4f2939cSRui Paulo 	{ "AddService", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
2925d4f2939cSRui Paulo 	  (WPADBusMethodHandler) wpas_dbus_handler_p2p_add_service,
2926d4f2939cSRui Paulo 	  {
2927d4f2939cSRui Paulo 		  { "args", "a{sv}", ARG_IN },
2928d4f2939cSRui Paulo 		  END_ARGS
2929d4f2939cSRui Paulo 	  }
2930d4f2939cSRui Paulo 	},
2931d4f2939cSRui Paulo 	{ "DeleteService", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
2932d4f2939cSRui Paulo 	  (WPADBusMethodHandler) wpas_dbus_handler_p2p_delete_service,
2933d4f2939cSRui Paulo 	  {
2934d4f2939cSRui Paulo 		  { "args", "a{sv}", ARG_IN },
2935d4f2939cSRui Paulo 		  END_ARGS
2936d4f2939cSRui Paulo 	  }
2937d4f2939cSRui Paulo 	},
2938d4f2939cSRui Paulo 	{ "FlushService", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
2939d4f2939cSRui Paulo 	  (WPADBusMethodHandler) wpas_dbus_handler_p2p_flush_service,
2940d4f2939cSRui Paulo 	  {
2941d4f2939cSRui Paulo 		  END_ARGS
2942d4f2939cSRui Paulo 	  }
2943d4f2939cSRui Paulo 	},
2944d4f2939cSRui Paulo 	{ "ServiceDiscoveryRequest", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
2945d4f2939cSRui Paulo 	  (WPADBusMethodHandler) wpas_dbus_handler_p2p_service_sd_req,
2946d4f2939cSRui Paulo 	  {
2947d4f2939cSRui Paulo 		  { "args", "a{sv}", ARG_IN },
29485b9c547cSRui Paulo 		  { "ref", "t", ARG_OUT },
2949d4f2939cSRui Paulo 		  END_ARGS
2950d4f2939cSRui Paulo 	  }
2951d4f2939cSRui Paulo 	},
2952d4f2939cSRui Paulo 	{ "ServiceDiscoveryResponse", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
2953d4f2939cSRui Paulo 	  (WPADBusMethodHandler) wpas_dbus_handler_p2p_service_sd_res,
2954d4f2939cSRui Paulo 	  {
2955d4f2939cSRui Paulo 		  { "args", "a{sv}", ARG_IN },
2956d4f2939cSRui Paulo 		  END_ARGS
2957d4f2939cSRui Paulo 	  }
2958d4f2939cSRui Paulo 	},
2959d4f2939cSRui Paulo 	{ "ServiceDiscoveryCancelRequest", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
2960d4f2939cSRui Paulo 	  (WPADBusMethodHandler) wpas_dbus_handler_p2p_service_sd_cancel_req,
2961d4f2939cSRui Paulo 	  {
2962d4f2939cSRui Paulo 		  { "args", "t", ARG_IN },
2963d4f2939cSRui Paulo 		  END_ARGS
2964d4f2939cSRui Paulo 	  }
2965d4f2939cSRui Paulo 	},
2966d4f2939cSRui Paulo 	{ "ServiceUpdate", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
2967d4f2939cSRui Paulo 	  (WPADBusMethodHandler) wpas_dbus_handler_p2p_service_update,
2968d4f2939cSRui Paulo 	  {
2969d4f2939cSRui Paulo 		  END_ARGS
2970d4f2939cSRui Paulo 	  }
2971d4f2939cSRui Paulo 	},
2972d4f2939cSRui Paulo 	{ "ServiceDiscoveryExternal", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
2973d4f2939cSRui Paulo 	  (WPADBusMethodHandler) wpas_dbus_handler_p2p_serv_disc_external,
2974d4f2939cSRui Paulo 	  {
2975d4f2939cSRui Paulo 		  { "arg", "i", ARG_IN },
2976d4f2939cSRui Paulo 		  END_ARGS
2977d4f2939cSRui Paulo 	  }
2978d4f2939cSRui Paulo 	},
2979d4f2939cSRui Paulo 	{ "AddPersistentGroup", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
2980d4f2939cSRui Paulo 	  (WPADBusMethodHandler) wpas_dbus_handler_add_persistent_group,
2981d4f2939cSRui Paulo 	  {
2982d4f2939cSRui Paulo 		  { "args", "a{sv}", ARG_IN },
2983d4f2939cSRui Paulo 		  { "path", "o", ARG_OUT },
2984d4f2939cSRui Paulo 		  END_ARGS
2985d4f2939cSRui Paulo 	  }
2986d4f2939cSRui Paulo 	},
2987d4f2939cSRui Paulo 	{ "RemovePersistentGroup", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
2988d4f2939cSRui Paulo 	  (WPADBusMethodHandler) wpas_dbus_handler_remove_persistent_group,
2989d4f2939cSRui Paulo 	  {
2990d4f2939cSRui Paulo 		  { "path", "o", ARG_IN },
2991d4f2939cSRui Paulo 		  END_ARGS
2992d4f2939cSRui Paulo 	  }
2993d4f2939cSRui Paulo 	},
2994d4f2939cSRui Paulo 	{ "RemoveAllPersistentGroups", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
2995d4f2939cSRui Paulo 	  (WPADBusMethodHandler)
2996d4f2939cSRui Paulo 	  wpas_dbus_handler_remove_all_persistent_groups,
2997d4f2939cSRui Paulo 	  {
2998d4f2939cSRui Paulo 		  END_ARGS
2999d4f2939cSRui Paulo 	  }
3000d4f2939cSRui Paulo 	},
3001d4f2939cSRui Paulo #endif /* CONFIG_P2P */
3002d4f2939cSRui Paulo 	{ "FlushBSS", WPAS_DBUS_NEW_IFACE_INTERFACE,
30035b9c547cSRui Paulo 	  (WPADBusMethodHandler) wpas_dbus_handler_flush_bss,
3004d4f2939cSRui Paulo 	  {
3005d4f2939cSRui Paulo 		  { "age", "u", ARG_IN },
3006d4f2939cSRui Paulo 		  END_ARGS
3007d4f2939cSRui Paulo 	  }
3008d4f2939cSRui Paulo 	},
3009d4f2939cSRui Paulo #ifdef CONFIG_AP
3010d4f2939cSRui Paulo 	{ "SubscribeProbeReq", WPAS_DBUS_NEW_IFACE_INTERFACE,
3011d4f2939cSRui Paulo 	  (WPADBusMethodHandler) wpas_dbus_handler_subscribe_preq,
3012d4f2939cSRui Paulo 	  {
3013d4f2939cSRui Paulo 		  END_ARGS
3014d4f2939cSRui Paulo 	  }
3015d4f2939cSRui Paulo 	},
3016d4f2939cSRui Paulo 	{ "UnsubscribeProbeReq", WPAS_DBUS_NEW_IFACE_INTERFACE,
3017d4f2939cSRui Paulo 	  (WPADBusMethodHandler) wpas_dbus_handler_unsubscribe_preq,
3018d4f2939cSRui Paulo 	  {
3019d4f2939cSRui Paulo 		  END_ARGS
3020d4f2939cSRui Paulo 	  }
3021d4f2939cSRui Paulo 	},
3022d4f2939cSRui Paulo #endif /* CONFIG_AP */
30235b9c547cSRui Paulo 	{ "EAPLogoff", WPAS_DBUS_NEW_IFACE_INTERFACE,
30245b9c547cSRui Paulo 	  (WPADBusMethodHandler) wpas_dbus_handler_eap_logoff,
30255b9c547cSRui Paulo 	  {
30265b9c547cSRui Paulo 		  END_ARGS
30275b9c547cSRui Paulo 	  }
30285b9c547cSRui Paulo 	},
30295b9c547cSRui Paulo 	{ "EAPLogon", WPAS_DBUS_NEW_IFACE_INTERFACE,
30305b9c547cSRui Paulo 	  (WPADBusMethodHandler) wpas_dbus_handler_eap_logon,
30315b9c547cSRui Paulo 	  {
30325b9c547cSRui Paulo 		  END_ARGS
30335b9c547cSRui Paulo 	  }
30345b9c547cSRui Paulo 	},
30355b9c547cSRui Paulo #ifdef CONFIG_AUTOSCAN
30365b9c547cSRui Paulo 	{ "AutoScan", WPAS_DBUS_NEW_IFACE_INTERFACE,
30375b9c547cSRui Paulo 	  (WPADBusMethodHandler) wpas_dbus_handler_autoscan,
30385b9c547cSRui Paulo 	  {
30395b9c547cSRui Paulo 		  { "arg", "s", ARG_IN },
30405b9c547cSRui Paulo 		  END_ARGS
30415b9c547cSRui Paulo 	  }
30425b9c547cSRui Paulo 	},
30435b9c547cSRui Paulo #endif /* CONFIG_AUTOSCAN */
30445b9c547cSRui Paulo #ifdef CONFIG_TDLS
30455b9c547cSRui Paulo 	{ "TDLSDiscover", WPAS_DBUS_NEW_IFACE_INTERFACE,
30465b9c547cSRui Paulo 	  (WPADBusMethodHandler) wpas_dbus_handler_tdls_discover,
30475b9c547cSRui Paulo 	  {
30485b9c547cSRui Paulo 		  { "peer_address", "s", ARG_IN },
30495b9c547cSRui Paulo 		  END_ARGS
30505b9c547cSRui Paulo 	  }
30515b9c547cSRui Paulo 	},
30525b9c547cSRui Paulo 	{ "TDLSSetup", WPAS_DBUS_NEW_IFACE_INTERFACE,
30535b9c547cSRui Paulo 	  (WPADBusMethodHandler) wpas_dbus_handler_tdls_setup,
30545b9c547cSRui Paulo 	  {
30555b9c547cSRui Paulo 		  { "peer_address", "s", ARG_IN },
30565b9c547cSRui Paulo 		  END_ARGS
30575b9c547cSRui Paulo 	  }
30585b9c547cSRui Paulo 	},
30595b9c547cSRui Paulo 	{ "TDLSStatus", WPAS_DBUS_NEW_IFACE_INTERFACE,
30605b9c547cSRui Paulo 	  (WPADBusMethodHandler) wpas_dbus_handler_tdls_status,
30615b9c547cSRui Paulo 	  {
30625b9c547cSRui Paulo 		  { "peer_address", "s", ARG_IN },
30635b9c547cSRui Paulo 		  { "status", "s", ARG_OUT },
30645b9c547cSRui Paulo 		  END_ARGS
30655b9c547cSRui Paulo 	  }
30665b9c547cSRui Paulo 	},
30675b9c547cSRui Paulo 	{ "TDLSTeardown", WPAS_DBUS_NEW_IFACE_INTERFACE,
30685b9c547cSRui Paulo 	  (WPADBusMethodHandler) wpas_dbus_handler_tdls_teardown,
30695b9c547cSRui Paulo 	  {
30705b9c547cSRui Paulo 		  { "peer_address", "s", ARG_IN },
30715b9c547cSRui Paulo 		  END_ARGS
30725b9c547cSRui Paulo 	  }
30735b9c547cSRui Paulo 	},
30745b9c547cSRui Paulo #endif /* CONFIG_TDLS */
3075*780fb4a2SCy Schubert 	{ "VendorElemAdd", WPAS_DBUS_NEW_IFACE_INTERFACE,
3076*780fb4a2SCy Schubert 	  (WPADBusMethodHandler) wpas_dbus_handler_vendor_elem_add,
3077*780fb4a2SCy Schubert 	  {
3078*780fb4a2SCy Schubert 		  { "frame_id", "i", ARG_IN },
3079*780fb4a2SCy Schubert 		  { "ielems", "ay", ARG_IN },
3080*780fb4a2SCy Schubert 		  END_ARGS
3081*780fb4a2SCy Schubert 	  }
3082*780fb4a2SCy Schubert 	},
3083*780fb4a2SCy Schubert 	{ "VendorElemGet", WPAS_DBUS_NEW_IFACE_INTERFACE,
3084*780fb4a2SCy Schubert 	  (WPADBusMethodHandler) wpas_dbus_handler_vendor_elem_get,
3085*780fb4a2SCy Schubert 	  {
3086*780fb4a2SCy Schubert 		  { "frame_id", "i", ARG_IN },
3087*780fb4a2SCy Schubert 		  { "ielems", "ay", ARG_OUT },
3088*780fb4a2SCy Schubert 		  END_ARGS
3089*780fb4a2SCy Schubert 	  }
3090*780fb4a2SCy Schubert 	},
3091*780fb4a2SCy Schubert 	{ "VendorElemRem", WPAS_DBUS_NEW_IFACE_INTERFACE,
3092*780fb4a2SCy Schubert 	  (WPADBusMethodHandler) wpas_dbus_handler_vendor_elem_remove,
3093*780fb4a2SCy Schubert 	  {
3094*780fb4a2SCy Schubert 		  { "frame_id", "i", ARG_IN },
3095*780fb4a2SCy Schubert 		  { "ielems", "ay", ARG_IN },
3096*780fb4a2SCy Schubert 		  END_ARGS
3097*780fb4a2SCy Schubert 	  }
3098*780fb4a2SCy Schubert 	},
3099*780fb4a2SCy Schubert #ifndef CONFIG_NO_CONFIG_WRITE
3100*780fb4a2SCy Schubert 	{ "SaveConfig", WPAS_DBUS_NEW_IFACE_INTERFACE,
3101*780fb4a2SCy Schubert 	  (WPADBusMethodHandler) wpas_dbus_handler_save_config,
3102*780fb4a2SCy Schubert 	  {
3103*780fb4a2SCy Schubert 		  END_ARGS
3104*780fb4a2SCy Schubert 	  }
3105*780fb4a2SCy Schubert 	},
3106*780fb4a2SCy Schubert #endif /* CONFIG_NO_CONFIG_WRITE */
3107d4f2939cSRui Paulo 	{ NULL, NULL, NULL, { END_ARGS } }
3108d4f2939cSRui Paulo };
3109d4f2939cSRui Paulo 
3110d4f2939cSRui Paulo static const struct wpa_dbus_property_desc wpas_dbus_interface_properties[] = {
3111d4f2939cSRui Paulo 	{ "Capabilities", WPAS_DBUS_NEW_IFACE_INTERFACE, "a{sv}",
3112d4f2939cSRui Paulo 	  wpas_dbus_getter_capabilities,
3113*780fb4a2SCy Schubert 	  NULL,
3114d4f2939cSRui Paulo 	  NULL
3115d4f2939cSRui Paulo 	},
3116d4f2939cSRui Paulo 	{ "State", WPAS_DBUS_NEW_IFACE_INTERFACE, "s",
3117d4f2939cSRui Paulo 	  wpas_dbus_getter_state,
3118*780fb4a2SCy Schubert 	  NULL,
3119d4f2939cSRui Paulo 	  NULL
3120d4f2939cSRui Paulo 	},
3121d4f2939cSRui Paulo 	{ "Scanning", WPAS_DBUS_NEW_IFACE_INTERFACE, "b",
3122d4f2939cSRui Paulo 	  wpas_dbus_getter_scanning,
3123*780fb4a2SCy Schubert 	  NULL,
3124d4f2939cSRui Paulo 	  NULL
3125d4f2939cSRui Paulo 	},
3126d4f2939cSRui Paulo 	{ "ApScan", WPAS_DBUS_NEW_IFACE_INTERFACE, "u",
3127d4f2939cSRui Paulo 	  wpas_dbus_getter_ap_scan,
3128*780fb4a2SCy Schubert 	  wpas_dbus_setter_ap_scan,
3129*780fb4a2SCy Schubert 	  NULL
3130d4f2939cSRui Paulo 	},
3131d4f2939cSRui Paulo 	{ "BSSExpireAge", WPAS_DBUS_NEW_IFACE_INTERFACE, "u",
3132d4f2939cSRui Paulo 	  wpas_dbus_getter_bss_expire_age,
3133*780fb4a2SCy Schubert 	  wpas_dbus_setter_bss_expire_age,
3134*780fb4a2SCy Schubert 	  NULL
3135d4f2939cSRui Paulo 	},
3136d4f2939cSRui Paulo 	{ "BSSExpireCount", WPAS_DBUS_NEW_IFACE_INTERFACE, "u",
3137d4f2939cSRui Paulo 	  wpas_dbus_getter_bss_expire_count,
3138*780fb4a2SCy Schubert 	  wpas_dbus_setter_bss_expire_count,
3139*780fb4a2SCy Schubert 	  NULL
3140d4f2939cSRui Paulo 	},
3141d4f2939cSRui Paulo 	{ "Country", WPAS_DBUS_NEW_IFACE_INTERFACE, "s",
3142d4f2939cSRui Paulo 	  wpas_dbus_getter_country,
3143*780fb4a2SCy Schubert 	  wpas_dbus_setter_country,
3144*780fb4a2SCy Schubert 	  NULL
3145d4f2939cSRui Paulo 	},
3146d4f2939cSRui Paulo 	{ "Ifname", WPAS_DBUS_NEW_IFACE_INTERFACE, "s",
3147d4f2939cSRui Paulo 	  wpas_dbus_getter_ifname,
3148*780fb4a2SCy Schubert 	  NULL,
3149d4f2939cSRui Paulo 	  NULL
3150d4f2939cSRui Paulo 	},
3151d4f2939cSRui Paulo 	{ "Driver", WPAS_DBUS_NEW_IFACE_INTERFACE, "s",
3152d4f2939cSRui Paulo 	  wpas_dbus_getter_driver,
3153*780fb4a2SCy Schubert 	  NULL,
3154d4f2939cSRui Paulo 	  NULL
3155d4f2939cSRui Paulo 	},
3156d4f2939cSRui Paulo 	{ "BridgeIfname", WPAS_DBUS_NEW_IFACE_INTERFACE, "s",
3157d4f2939cSRui Paulo 	  wpas_dbus_getter_bridge_ifname,
3158*780fb4a2SCy Schubert 	  NULL,
3159*780fb4a2SCy Schubert 	  NULL
3160*780fb4a2SCy Schubert 	},
3161*780fb4a2SCy Schubert 	{ "ConfigFile", WPAS_DBUS_NEW_IFACE_INTERFACE, "s",
3162*780fb4a2SCy Schubert 	  wpas_dbus_getter_config_file,
3163*780fb4a2SCy Schubert 	  NULL,
3164d4f2939cSRui Paulo 	  NULL
3165d4f2939cSRui Paulo 	},
3166d4f2939cSRui Paulo 	{ "CurrentBSS", WPAS_DBUS_NEW_IFACE_INTERFACE, "o",
3167d4f2939cSRui Paulo 	  wpas_dbus_getter_current_bss,
3168*780fb4a2SCy Schubert 	  NULL,
3169d4f2939cSRui Paulo 	  NULL
3170d4f2939cSRui Paulo 	},
3171d4f2939cSRui Paulo 	{ "CurrentNetwork", WPAS_DBUS_NEW_IFACE_INTERFACE, "o",
3172d4f2939cSRui Paulo 	  wpas_dbus_getter_current_network,
3173*780fb4a2SCy Schubert 	  NULL,
3174d4f2939cSRui Paulo 	  NULL
3175d4f2939cSRui Paulo 	},
3176d4f2939cSRui Paulo 	{ "CurrentAuthMode", WPAS_DBUS_NEW_IFACE_INTERFACE, "s",
3177d4f2939cSRui Paulo 	  wpas_dbus_getter_current_auth_mode,
3178*780fb4a2SCy Schubert 	  NULL,
3179d4f2939cSRui Paulo 	  NULL
3180d4f2939cSRui Paulo 	},
3181d4f2939cSRui Paulo 	{ "Blobs", WPAS_DBUS_NEW_IFACE_INTERFACE, "a{say}",
3182d4f2939cSRui Paulo 	  wpas_dbus_getter_blobs,
3183*780fb4a2SCy Schubert 	  NULL,
3184d4f2939cSRui Paulo 	  NULL
3185d4f2939cSRui Paulo 	},
3186d4f2939cSRui Paulo 	{ "BSSs", WPAS_DBUS_NEW_IFACE_INTERFACE, "ao",
3187d4f2939cSRui Paulo 	  wpas_dbus_getter_bsss,
3188*780fb4a2SCy Schubert 	  NULL,
3189d4f2939cSRui Paulo 	  NULL
3190d4f2939cSRui Paulo 	},
3191d4f2939cSRui Paulo 	{ "Networks", WPAS_DBUS_NEW_IFACE_INTERFACE, "ao",
3192d4f2939cSRui Paulo 	  wpas_dbus_getter_networks,
3193*780fb4a2SCy Schubert 	  NULL,
3194d4f2939cSRui Paulo 	  NULL
3195d4f2939cSRui Paulo 	},
3196d4f2939cSRui Paulo 	{ "FastReauth", WPAS_DBUS_NEW_IFACE_INTERFACE, "b",
3197d4f2939cSRui Paulo 	  wpas_dbus_getter_fast_reauth,
3198*780fb4a2SCy Schubert 	  wpas_dbus_setter_fast_reauth,
3199*780fb4a2SCy Schubert 	  NULL
3200d4f2939cSRui Paulo 	},
3201d4f2939cSRui Paulo 	{ "ScanInterval", WPAS_DBUS_NEW_IFACE_INTERFACE, "i",
3202d4f2939cSRui Paulo 	  wpas_dbus_getter_scan_interval,
3203*780fb4a2SCy Schubert 	  wpas_dbus_setter_scan_interval,
3204*780fb4a2SCy Schubert 	  NULL
3205d4f2939cSRui Paulo 	},
32065b9c547cSRui Paulo 	{ "PKCS11EnginePath", WPAS_DBUS_NEW_IFACE_INTERFACE, "s",
32075b9c547cSRui Paulo 	  wpas_dbus_getter_pkcs11_engine_path,
3208*780fb4a2SCy Schubert 	  NULL,
32095b9c547cSRui Paulo 	  NULL
32105b9c547cSRui Paulo 	},
32115b9c547cSRui Paulo 	{ "PKCS11ModulePath", WPAS_DBUS_NEW_IFACE_INTERFACE, "s",
32125b9c547cSRui Paulo 	  wpas_dbus_getter_pkcs11_module_path,
3213*780fb4a2SCy Schubert 	  NULL,
32145b9c547cSRui Paulo 	  NULL
32155b9c547cSRui Paulo 	},
3216d4f2939cSRui Paulo #ifdef CONFIG_WPS
3217d4f2939cSRui Paulo 	{ "ProcessCredentials", WPAS_DBUS_NEW_IFACE_WPS, "b",
3218d4f2939cSRui Paulo 	  wpas_dbus_getter_process_credentials,
3219*780fb4a2SCy Schubert 	  wpas_dbus_setter_process_credentials,
3220*780fb4a2SCy Schubert 	  NULL
3221d4f2939cSRui Paulo 	},
32225b9c547cSRui Paulo 	{ "ConfigMethods", WPAS_DBUS_NEW_IFACE_WPS, "s",
32235b9c547cSRui Paulo 	  wpas_dbus_getter_config_methods,
3224*780fb4a2SCy Schubert 	  wpas_dbus_setter_config_methods,
3225*780fb4a2SCy Schubert 	  NULL
32265b9c547cSRui Paulo 	},
3227d4f2939cSRui Paulo #endif /* CONFIG_WPS */
3228d4f2939cSRui Paulo #ifdef CONFIG_P2P
3229d4f2939cSRui Paulo 	{ "P2PDeviceConfig", WPAS_DBUS_NEW_IFACE_P2PDEVICE, "a{sv}",
3230d4f2939cSRui Paulo 	  wpas_dbus_getter_p2p_device_config,
3231*780fb4a2SCy Schubert 	  wpas_dbus_setter_p2p_device_config,
3232*780fb4a2SCy Schubert 	  NULL
3233d4f2939cSRui Paulo 	},
3234d4f2939cSRui Paulo 	{ "Peers", WPAS_DBUS_NEW_IFACE_P2PDEVICE, "ao",
3235d4f2939cSRui Paulo 	  wpas_dbus_getter_p2p_peers,
3236*780fb4a2SCy Schubert 	  NULL,
3237d4f2939cSRui Paulo 	  NULL
3238d4f2939cSRui Paulo 	},
3239d4f2939cSRui Paulo 	{ "Role", WPAS_DBUS_NEW_IFACE_P2PDEVICE, "s",
3240d4f2939cSRui Paulo 	  wpas_dbus_getter_p2p_role,
3241*780fb4a2SCy Schubert 	  NULL,
3242d4f2939cSRui Paulo 	  NULL
3243d4f2939cSRui Paulo 	},
3244d4f2939cSRui Paulo 	{ "Group", WPAS_DBUS_NEW_IFACE_P2PDEVICE, "o",
3245d4f2939cSRui Paulo 	  wpas_dbus_getter_p2p_group,
3246*780fb4a2SCy Schubert 	  NULL,
3247d4f2939cSRui Paulo 	  NULL
3248d4f2939cSRui Paulo 	},
3249d4f2939cSRui Paulo 	{ "PeerGO", WPAS_DBUS_NEW_IFACE_P2PDEVICE, "o",
3250d4f2939cSRui Paulo 	  wpas_dbus_getter_p2p_peergo,
3251*780fb4a2SCy Schubert 	  NULL,
3252d4f2939cSRui Paulo 	  NULL
3253d4f2939cSRui Paulo 	},
3254d4f2939cSRui Paulo 	{ "PersistentGroups", WPAS_DBUS_NEW_IFACE_P2PDEVICE, "ao",
3255d4f2939cSRui Paulo 	  wpas_dbus_getter_persistent_groups,
3256*780fb4a2SCy Schubert 	  NULL,
3257d4f2939cSRui Paulo 	  NULL
3258d4f2939cSRui Paulo 	},
3259d4f2939cSRui Paulo #endif /* CONFIG_P2P */
3260d4f2939cSRui Paulo 	{ "DisconnectReason", WPAS_DBUS_NEW_IFACE_INTERFACE, "i",
3261d4f2939cSRui Paulo 	  wpas_dbus_getter_disconnect_reason,
3262*780fb4a2SCy Schubert 	  NULL,
3263d4f2939cSRui Paulo 	  NULL
3264d4f2939cSRui Paulo 	},
3265*780fb4a2SCy Schubert 	{ "AssocStatusCode", WPAS_DBUS_NEW_IFACE_INTERFACE, "i",
3266*780fb4a2SCy Schubert 	  wpas_dbus_getter_assoc_status_code,
3267*780fb4a2SCy Schubert 	  NULL,
3268*780fb4a2SCy Schubert 	  NULL
3269*780fb4a2SCy Schubert 	},
3270*780fb4a2SCy Schubert 	{ NULL, NULL, NULL, NULL, NULL, NULL }
3271d4f2939cSRui Paulo };
3272d4f2939cSRui Paulo 
3273d4f2939cSRui Paulo static const struct wpa_dbus_signal_desc wpas_dbus_interface_signals[] = {
3274d4f2939cSRui Paulo 	{ "ScanDone", WPAS_DBUS_NEW_IFACE_INTERFACE,
3275d4f2939cSRui Paulo 	  {
3276d4f2939cSRui Paulo 		  { "success", "b", ARG_OUT },
3277d4f2939cSRui Paulo 		  END_ARGS
3278d4f2939cSRui Paulo 	  }
3279d4f2939cSRui Paulo 	},
3280d4f2939cSRui Paulo 	{ "BSSAdded", WPAS_DBUS_NEW_IFACE_INTERFACE,
3281d4f2939cSRui Paulo 	  {
3282d4f2939cSRui Paulo 		  { "path", "o", ARG_OUT },
3283d4f2939cSRui Paulo 		  { "properties", "a{sv}", ARG_OUT },
3284d4f2939cSRui Paulo 		  END_ARGS
3285d4f2939cSRui Paulo 	  }
3286d4f2939cSRui Paulo 	},
3287d4f2939cSRui Paulo 	{ "BSSRemoved", WPAS_DBUS_NEW_IFACE_INTERFACE,
3288d4f2939cSRui Paulo 	  {
3289d4f2939cSRui Paulo 		  { "path", "o", ARG_OUT },
3290d4f2939cSRui Paulo 		  END_ARGS
3291d4f2939cSRui Paulo 	  }
3292d4f2939cSRui Paulo 	},
3293d4f2939cSRui Paulo 	{ "BlobAdded", WPAS_DBUS_NEW_IFACE_INTERFACE,
3294d4f2939cSRui Paulo 	  {
3295d4f2939cSRui Paulo 		  { "name", "s", ARG_OUT },
3296d4f2939cSRui Paulo 		  END_ARGS
3297d4f2939cSRui Paulo 	  }
3298d4f2939cSRui Paulo 	},
3299d4f2939cSRui Paulo 	{ "BlobRemoved", WPAS_DBUS_NEW_IFACE_INTERFACE,
3300d4f2939cSRui Paulo 	  {
3301d4f2939cSRui Paulo 		  { "name", "s", ARG_OUT },
3302d4f2939cSRui Paulo 		  END_ARGS
3303d4f2939cSRui Paulo 	  }
3304d4f2939cSRui Paulo 	},
3305d4f2939cSRui Paulo 	{ "NetworkAdded", WPAS_DBUS_NEW_IFACE_INTERFACE,
3306d4f2939cSRui Paulo 	  {
3307d4f2939cSRui Paulo 		  { "path", "o", ARG_OUT },
3308d4f2939cSRui Paulo 		  { "properties", "a{sv}", ARG_OUT },
3309d4f2939cSRui Paulo 		  END_ARGS
3310d4f2939cSRui Paulo 	  }
3311d4f2939cSRui Paulo 	},
3312d4f2939cSRui Paulo 	{ "NetworkRemoved", WPAS_DBUS_NEW_IFACE_INTERFACE,
3313d4f2939cSRui Paulo 	  {
3314d4f2939cSRui Paulo 		  { "path", "o", ARG_OUT },
3315d4f2939cSRui Paulo 		  END_ARGS
3316d4f2939cSRui Paulo 	  }
3317d4f2939cSRui Paulo 	},
3318d4f2939cSRui Paulo 	{ "NetworkSelected", WPAS_DBUS_NEW_IFACE_INTERFACE,
3319d4f2939cSRui Paulo 	  {
3320d4f2939cSRui Paulo 		  { "path", "o", ARG_OUT },
3321d4f2939cSRui Paulo 		  END_ARGS
3322d4f2939cSRui Paulo 	  }
3323d4f2939cSRui Paulo 	},
3324d4f2939cSRui Paulo 	/* Deprecated: use org.freedesktop.DBus.Properties.PropertiesChanged */
3325d4f2939cSRui Paulo 	{ "PropertiesChanged", WPAS_DBUS_NEW_IFACE_INTERFACE,
3326d4f2939cSRui Paulo 	  {
3327d4f2939cSRui Paulo 		  { "properties", "a{sv}", ARG_OUT },
3328d4f2939cSRui Paulo 		  END_ARGS
3329d4f2939cSRui Paulo 	  }
3330d4f2939cSRui Paulo 	},
3331d4f2939cSRui Paulo #ifdef CONFIG_WPS
3332d4f2939cSRui Paulo 	{ "Event", WPAS_DBUS_NEW_IFACE_WPS,
3333d4f2939cSRui Paulo 	  {
3334d4f2939cSRui Paulo 		  { "name", "s", ARG_OUT },
3335d4f2939cSRui Paulo 		  { "args", "a{sv}", ARG_OUT },
3336d4f2939cSRui Paulo 		  END_ARGS
3337d4f2939cSRui Paulo 	  }
3338d4f2939cSRui Paulo 	},
3339d4f2939cSRui Paulo 	{ "Credentials", WPAS_DBUS_NEW_IFACE_WPS,
3340d4f2939cSRui Paulo 	  {
3341d4f2939cSRui Paulo 		  { "credentials", "a{sv}", ARG_OUT },
3342d4f2939cSRui Paulo 		  END_ARGS
3343d4f2939cSRui Paulo 	  }
3344d4f2939cSRui Paulo 	},
3345d4f2939cSRui Paulo 	/* Deprecated: use org.freedesktop.DBus.Properties.PropertiesChanged */
3346d4f2939cSRui Paulo 	{ "PropertiesChanged", WPAS_DBUS_NEW_IFACE_WPS,
3347d4f2939cSRui Paulo 	  {
3348d4f2939cSRui Paulo 		  { "properties", "a{sv}", ARG_OUT },
3349d4f2939cSRui Paulo 		  END_ARGS
3350d4f2939cSRui Paulo 	  }
3351d4f2939cSRui Paulo 	},
3352d4f2939cSRui Paulo #endif /* CONFIG_WPS */
3353d4f2939cSRui Paulo #ifdef CONFIG_P2P
3354d4f2939cSRui Paulo 	{ "DeviceFound", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
3355d4f2939cSRui Paulo 	  {
3356d4f2939cSRui Paulo 		  { "path", "o", ARG_OUT },
3357d4f2939cSRui Paulo 		  END_ARGS
3358d4f2939cSRui Paulo 	  }
3359d4f2939cSRui Paulo 	},
3360*780fb4a2SCy Schubert 	{ "DeviceFoundProperties", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
3361*780fb4a2SCy Schubert 	  {
3362*780fb4a2SCy Schubert 		  { "path", "o", ARG_OUT },
3363*780fb4a2SCy Schubert 		  { "properties", "a{sv}", ARG_OUT },
3364*780fb4a2SCy Schubert 		  END_ARGS
3365*780fb4a2SCy Schubert 	  }
3366*780fb4a2SCy Schubert 	},
3367d4f2939cSRui Paulo 	{ "DeviceLost", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
3368d4f2939cSRui Paulo 	  {
3369d4f2939cSRui Paulo 		  { "path", "o", ARG_OUT },
3370d4f2939cSRui Paulo 		  END_ARGS
3371d4f2939cSRui Paulo 	  }
3372d4f2939cSRui Paulo 	},
3373325151a3SRui Paulo 	{ "FindStopped", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
3374325151a3SRui Paulo 	  {
3375325151a3SRui Paulo 		  END_ARGS
3376325151a3SRui Paulo 	  }
3377325151a3SRui Paulo 	},
3378d4f2939cSRui Paulo 	{ "ProvisionDiscoveryRequestDisplayPin", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
3379d4f2939cSRui Paulo 	  {
3380d4f2939cSRui Paulo 		  { "peer_object", "o", ARG_OUT },
3381d4f2939cSRui Paulo 		  { "pin", "s", ARG_OUT },
3382d4f2939cSRui Paulo 		  END_ARGS
3383d4f2939cSRui Paulo 	  }
3384d4f2939cSRui Paulo 	},
3385d4f2939cSRui Paulo 	{ "ProvisionDiscoveryResponseDisplayPin", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
3386d4f2939cSRui Paulo 	  {
3387d4f2939cSRui Paulo 		  { "peer_object", "o", ARG_OUT },
3388d4f2939cSRui Paulo 		  { "pin", "s", ARG_OUT },
3389d4f2939cSRui Paulo 		  END_ARGS
3390d4f2939cSRui Paulo 	  }
3391d4f2939cSRui Paulo 	},
3392d4f2939cSRui Paulo 	{ "ProvisionDiscoveryRequestEnterPin", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
3393d4f2939cSRui Paulo 	  {
3394d4f2939cSRui Paulo 		  { "peer_object", "o", ARG_OUT },
3395d4f2939cSRui Paulo 		  END_ARGS
3396d4f2939cSRui Paulo 	  }
3397d4f2939cSRui Paulo 	},
3398d4f2939cSRui Paulo 	{ "ProvisionDiscoveryResponseEnterPin", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
3399d4f2939cSRui Paulo 	  {
3400d4f2939cSRui Paulo 		  { "peer_object", "o", ARG_OUT },
3401d4f2939cSRui Paulo 		  END_ARGS
3402d4f2939cSRui Paulo 	  }
3403d4f2939cSRui Paulo 	},
3404d4f2939cSRui Paulo 	{ "ProvisionDiscoveryPBCRequest", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
3405d4f2939cSRui Paulo 	  {
3406d4f2939cSRui Paulo 		  { "peer_object", "o", ARG_OUT },
3407d4f2939cSRui Paulo 		  END_ARGS
3408d4f2939cSRui Paulo 	  }
3409d4f2939cSRui Paulo 	},
3410d4f2939cSRui Paulo 	{ "ProvisionDiscoveryPBCResponse", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
3411d4f2939cSRui Paulo 	  {
3412d4f2939cSRui Paulo 		  { "peer_object", "o", ARG_OUT },
3413d4f2939cSRui Paulo 		  END_ARGS
3414d4f2939cSRui Paulo 	  }
3415d4f2939cSRui Paulo 	},
3416d4f2939cSRui Paulo 	{ "ProvisionDiscoveryFailure", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
3417d4f2939cSRui Paulo 	  {
3418d4f2939cSRui Paulo 		  { "peer_object", "o", ARG_OUT },
3419d4f2939cSRui Paulo 		  { "status", "i", ARG_OUT },
3420d4f2939cSRui Paulo 		  END_ARGS
3421d4f2939cSRui Paulo 	  }
3422d4f2939cSRui Paulo 	},
3423d4f2939cSRui Paulo 	{ "GroupStarted", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
3424d4f2939cSRui Paulo 	  {
3425d4f2939cSRui Paulo 		  { "properties", "a{sv}", ARG_OUT },
3426d4f2939cSRui Paulo 		  END_ARGS
3427d4f2939cSRui Paulo 	  }
3428d4f2939cSRui Paulo 	},
3429325151a3SRui Paulo 	{ "GroupFormationFailure", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
3430325151a3SRui Paulo 	  {
3431325151a3SRui Paulo 		  { "reason", "s", ARG_OUT },
3432325151a3SRui Paulo 		  END_ARGS
3433325151a3SRui Paulo 	  }
3434325151a3SRui Paulo 	},
3435d4f2939cSRui Paulo 	{ "GONegotiationSuccess", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
3436d4f2939cSRui Paulo 	  {
34375b9c547cSRui Paulo 		  { "properties", "a{sv}", ARG_OUT },
3438d4f2939cSRui Paulo 		  END_ARGS
3439d4f2939cSRui Paulo 	  }
3440d4f2939cSRui Paulo 	},
3441d4f2939cSRui Paulo 	{ "GONegotiationFailure", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
3442d4f2939cSRui Paulo 	  {
34435b9c547cSRui Paulo 		  { "properties", "a{sv}", ARG_OUT },
3444d4f2939cSRui Paulo 		  END_ARGS
3445d4f2939cSRui Paulo 	  }
3446d4f2939cSRui Paulo 	},
3447d4f2939cSRui Paulo 	{ "GONegotiationRequest", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
3448d4f2939cSRui Paulo 	  {
3449d4f2939cSRui Paulo 		  { "path", "o", ARG_OUT },
3450325151a3SRui Paulo 		  { "dev_passwd_id", "q", ARG_OUT },
3451325151a3SRui Paulo 		  { "device_go_intent", "y", ARG_OUT },
3452d4f2939cSRui Paulo 		  END_ARGS
3453d4f2939cSRui Paulo 	  }
3454d4f2939cSRui Paulo 	},
3455d4f2939cSRui Paulo 	{ "InvitationResult", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
3456d4f2939cSRui Paulo 	  {
3457d4f2939cSRui Paulo 		  { "invite_result", "a{sv}", ARG_OUT },
3458d4f2939cSRui Paulo 		  END_ARGS
3459d4f2939cSRui Paulo 	  }
3460d4f2939cSRui Paulo 	},
3461d4f2939cSRui Paulo 	{ "GroupFinished", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
3462d4f2939cSRui Paulo 	  {
34635b9c547cSRui Paulo 		  { "properties", "a{sv}", ARG_OUT },
3464d4f2939cSRui Paulo 		  END_ARGS
3465d4f2939cSRui Paulo 	  }
3466d4f2939cSRui Paulo 	},
3467d4f2939cSRui Paulo 	{ "ServiceDiscoveryRequest", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
3468d4f2939cSRui Paulo 	  {
3469d4f2939cSRui Paulo 		  { "sd_request", "a{sv}", ARG_OUT },
3470d4f2939cSRui Paulo 		  END_ARGS
3471d4f2939cSRui Paulo 	  }
3472d4f2939cSRui Paulo 	},
3473d4f2939cSRui Paulo 	{ "ServiceDiscoveryResponse", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
3474d4f2939cSRui Paulo 	  {
3475d4f2939cSRui Paulo 		  { "sd_response", "a{sv}", ARG_OUT },
3476d4f2939cSRui Paulo 		  END_ARGS
3477d4f2939cSRui Paulo 	  }
3478d4f2939cSRui Paulo 	},
3479d4f2939cSRui Paulo 	{ "PersistentGroupAdded", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
3480d4f2939cSRui Paulo 	  {
3481d4f2939cSRui Paulo 		  { "path", "o", ARG_OUT },
3482d4f2939cSRui Paulo 		  { "properties", "a{sv}", ARG_OUT },
3483d4f2939cSRui Paulo 		  END_ARGS
3484d4f2939cSRui Paulo 	  }
3485d4f2939cSRui Paulo 	},
3486d4f2939cSRui Paulo 	{ "PersistentGroupRemoved", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
3487d4f2939cSRui Paulo 	  {
3488d4f2939cSRui Paulo 		  { "path", "o", ARG_OUT },
3489d4f2939cSRui Paulo 		  END_ARGS
3490d4f2939cSRui Paulo 	  }
3491d4f2939cSRui Paulo 	},
3492d4f2939cSRui Paulo 	{ "WpsFailed", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
3493d4f2939cSRui Paulo 	  {
3494d4f2939cSRui Paulo 		  { "name", "s", ARG_OUT },
3495d4f2939cSRui Paulo 		  { "args", "a{sv}", ARG_OUT },
3496d4f2939cSRui Paulo 		  END_ARGS
3497d4f2939cSRui Paulo 	  }
3498d4f2939cSRui Paulo 	},
3499325151a3SRui Paulo 	{ "InvitationReceived", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
3500325151a3SRui Paulo 	  {
3501325151a3SRui Paulo 		  { "properties", "a{sv}", ARG_OUT },
3502325151a3SRui Paulo 		  END_ARGS
3503325151a3SRui Paulo 	  }
3504325151a3SRui Paulo 	},
3505d4f2939cSRui Paulo #endif /* CONFIG_P2P */
3506d4f2939cSRui Paulo #ifdef CONFIG_AP
3507d4f2939cSRui Paulo 	{ "ProbeRequest", WPAS_DBUS_NEW_IFACE_INTERFACE,
3508d4f2939cSRui Paulo 	  {
3509d4f2939cSRui Paulo 		  { "args", "a{sv}", ARG_OUT },
3510d4f2939cSRui Paulo 		  END_ARGS
3511d4f2939cSRui Paulo 	  }
3512d4f2939cSRui Paulo 	},
3513d4f2939cSRui Paulo #endif /* CONFIG_AP */
3514d4f2939cSRui Paulo 	{ "Certification", WPAS_DBUS_NEW_IFACE_INTERFACE,
3515d4f2939cSRui Paulo 	  {
3516d4f2939cSRui Paulo 		  { "certification", "a{sv}", ARG_OUT },
3517d4f2939cSRui Paulo 		  END_ARGS
3518d4f2939cSRui Paulo 	  }
3519d4f2939cSRui Paulo 	},
3520d4f2939cSRui Paulo 	{ "EAP", WPAS_DBUS_NEW_IFACE_INTERFACE,
3521d4f2939cSRui Paulo 	  {
3522d4f2939cSRui Paulo 		  { "status", "s", ARG_OUT },
3523d4f2939cSRui Paulo 		  { "parameter", "s", ARG_OUT },
3524d4f2939cSRui Paulo 		  END_ARGS
3525d4f2939cSRui Paulo 	  }
3526d4f2939cSRui Paulo 	},
35275b9c547cSRui Paulo 	{ "StaAuthorized", WPAS_DBUS_NEW_IFACE_INTERFACE,
35285b9c547cSRui Paulo 	  {
35295b9c547cSRui Paulo 		  { "name", "s", ARG_OUT },
35305b9c547cSRui Paulo 		  END_ARGS
35315b9c547cSRui Paulo 	  }
35325b9c547cSRui Paulo 	},
35335b9c547cSRui Paulo 	{ "StaDeauthorized", WPAS_DBUS_NEW_IFACE_INTERFACE,
35345b9c547cSRui Paulo 	  {
35355b9c547cSRui Paulo 		  { "name", "s", ARG_OUT },
35365b9c547cSRui Paulo 		  END_ARGS
35375b9c547cSRui Paulo 	  }
35385b9c547cSRui Paulo 	},
35395b9c547cSRui Paulo 	{ "NetworkRequest", WPAS_DBUS_NEW_IFACE_INTERFACE,
35405b9c547cSRui Paulo 	  {
35415b9c547cSRui Paulo 		  { "path", "o", ARG_OUT },
35425b9c547cSRui Paulo 		  { "field", "s", ARG_OUT },
35435b9c547cSRui Paulo 		  { "text", "s", ARG_OUT },
35445b9c547cSRui Paulo 		  END_ARGS
35455b9c547cSRui Paulo 	  }
35465b9c547cSRui Paulo 	},
3547d4f2939cSRui Paulo 	{ NULL, NULL, { END_ARGS } }
3548d4f2939cSRui Paulo };
3549d4f2939cSRui Paulo 
3550d4f2939cSRui Paulo 
3551*780fb4a2SCy Schubert static int wpa_dbus_ctrl_iface_props_init(struct wpas_dbus_priv *priv)
3552*780fb4a2SCy Schubert {
3553*780fb4a2SCy Schubert 	size_t all_size;
3554*780fb4a2SCy Schubert 	unsigned int i, j, count, num_const, num_globals;
3555*780fb4a2SCy Schubert 	const char *global_name;
3556*780fb4a2SCy Schubert 	static const char * const ignored_globals[] = {
3557*780fb4a2SCy Schubert 		"bss_expiration_age", "bss_expiration_scan_count",
3558*780fb4a2SCy Schubert 		"ap_scan", "country", "fast_reauth",
3559*780fb4a2SCy Schubert 		"pkcs11_engine_path", "pkcs11_module_path"
3560*780fb4a2SCy Schubert 	};
3561*780fb4a2SCy Schubert 
3562*780fb4a2SCy Schubert 	/* wpas_dbus_interface_properties terminates with a NULL element */
3563*780fb4a2SCy Schubert 	num_const = ARRAY_SIZE(wpas_dbus_interface_properties) - 1;
3564*780fb4a2SCy Schubert 
3565*780fb4a2SCy Schubert 	num_globals = wpa_config_get_num_global_field_names();
3566*780fb4a2SCy Schubert 	priv->globals_start = num_const;
3567*780fb4a2SCy Schubert 
3568*780fb4a2SCy Schubert 	/* allocate enough for all properties + terminating NULL element */
3569*780fb4a2SCy Schubert 	all_size = (num_globals + num_const + 1) *
3570*780fb4a2SCy Schubert 		sizeof(wpas_dbus_interface_properties[0]);
3571*780fb4a2SCy Schubert 	priv->all_interface_properties = os_zalloc(all_size);
3572*780fb4a2SCy Schubert 	if (!priv->all_interface_properties) {
3573*780fb4a2SCy Schubert 		wpa_printf(MSG_ERROR,
3574*780fb4a2SCy Schubert 			   "dbus: Not enough memory for interface properties");
3575*780fb4a2SCy Schubert 		return -1;
3576*780fb4a2SCy Schubert 	}
3577*780fb4a2SCy Schubert 
3578*780fb4a2SCy Schubert 	/* Copy constant interface properties to the start of the array */
3579*780fb4a2SCy Schubert 	os_memcpy(priv->all_interface_properties,
3580*780fb4a2SCy Schubert 		  wpas_dbus_interface_properties,
3581*780fb4a2SCy Schubert 		  sizeof(wpas_dbus_interface_properties));
3582*780fb4a2SCy Schubert 
3583*780fb4a2SCy Schubert 	/* Dynamically construct interface global properties */
3584*780fb4a2SCy Schubert 	for (i = 0, count = num_const; i < num_globals; i++) {
3585*780fb4a2SCy Schubert 		struct wpa_dbus_property_desc *desc;
3586*780fb4a2SCy Schubert 		int no_var = 0;
3587*780fb4a2SCy Schubert 
3588*780fb4a2SCy Schubert 		/* ignore globals that are actually just methods */
3589*780fb4a2SCy Schubert 		global_name = wpa_config_get_global_field_name(i, &no_var);
3590*780fb4a2SCy Schubert 		if (no_var)
3591*780fb4a2SCy Schubert 			continue;
3592*780fb4a2SCy Schubert 		/* Ignore fields already explicitly exposed */
3593*780fb4a2SCy Schubert 		for (j = 0; j < ARRAY_SIZE(ignored_globals); j++) {
3594*780fb4a2SCy Schubert 			if (os_strcmp(global_name, ignored_globals[j]) == 0)
3595*780fb4a2SCy Schubert 				break;
3596*780fb4a2SCy Schubert 		}
3597*780fb4a2SCy Schubert 		if (j < ARRAY_SIZE(ignored_globals))
3598*780fb4a2SCy Schubert 			continue;
3599*780fb4a2SCy Schubert 
3600*780fb4a2SCy Schubert 		desc = &priv->all_interface_properties[count++];
3601*780fb4a2SCy Schubert 		desc->dbus_property = uscore_to_dbus(global_name);
3602*780fb4a2SCy Schubert 		if (!desc->dbus_property) {
3603*780fb4a2SCy Schubert 			wpa_printf(MSG_ERROR,
3604*780fb4a2SCy Schubert 				   "dbus: Not enough memory for D-Bus property name");
3605*780fb4a2SCy Schubert 			goto error;
3606*780fb4a2SCy Schubert 		}
3607*780fb4a2SCy Schubert 		desc->dbus_interface = WPAS_DBUS_NEW_IFACE_INTERFACE;
3608*780fb4a2SCy Schubert 		desc->type = "s";
3609*780fb4a2SCy Schubert 		desc->getter = wpas_dbus_getter_iface_global;
3610*780fb4a2SCy Schubert 		desc->setter = wpas_dbus_setter_iface_global;
3611*780fb4a2SCy Schubert 		desc->data = global_name;
3612*780fb4a2SCy Schubert 	}
3613*780fb4a2SCy Schubert 
3614*780fb4a2SCy Schubert 	return 0;
3615*780fb4a2SCy Schubert 
3616*780fb4a2SCy Schubert error:
3617*780fb4a2SCy Schubert 	wpa_dbus_ctrl_iface_props_deinit(priv);
3618*780fb4a2SCy Schubert 	return -1;
3619*780fb4a2SCy Schubert }
3620*780fb4a2SCy Schubert 
3621*780fb4a2SCy Schubert 
3622325151a3SRui Paulo /**
3623325151a3SRui Paulo  * wpas_dbus_register_interface - Register an interface with D-Bus
3624325151a3SRui Paulo  * @wpa_s: wpa_supplicant interface structure
3625325151a3SRui Paulo  * Returns: 0 on success, -1 on failure
3626325151a3SRui Paulo  */
3627d4f2939cSRui Paulo int wpas_dbus_register_interface(struct wpa_supplicant *wpa_s)
3628d4f2939cSRui Paulo {
3629d4f2939cSRui Paulo 	struct wpa_dbus_object_desc *obj_desc = NULL;
3630d4f2939cSRui Paulo 	struct wpas_dbus_priv *ctrl_iface = wpa_s->global->dbus;
3631d4f2939cSRui Paulo 	int next;
3632d4f2939cSRui Paulo 
3633d4f2939cSRui Paulo 	/* Do nothing if the control interface is not turned on */
3634d4f2939cSRui Paulo 	if (ctrl_iface == NULL)
3635d4f2939cSRui Paulo 		return 0;
3636d4f2939cSRui Paulo 
3637d4f2939cSRui Paulo 	/* Create and set the interface's object path */
3638d4f2939cSRui Paulo 	wpa_s->dbus_new_path = os_zalloc(WPAS_DBUS_OBJECT_PATH_MAX);
3639d4f2939cSRui Paulo 	if (wpa_s->dbus_new_path == NULL)
3640d4f2939cSRui Paulo 		return -1;
3641d4f2939cSRui Paulo 	next = ctrl_iface->next_objid++;
3642d4f2939cSRui Paulo 	os_snprintf(wpa_s->dbus_new_path, WPAS_DBUS_OBJECT_PATH_MAX,
3643d4f2939cSRui Paulo 		    WPAS_DBUS_NEW_PATH_INTERFACES "/%u",
3644d4f2939cSRui Paulo 		    next);
3645d4f2939cSRui Paulo 
3646d4f2939cSRui Paulo 	obj_desc = os_zalloc(sizeof(struct wpa_dbus_object_desc));
3647d4f2939cSRui Paulo 	if (!obj_desc) {
36485b9c547cSRui Paulo 		wpa_printf(MSG_ERROR,
36495b9c547cSRui Paulo 			   "Not enough memory to create object description");
3650d4f2939cSRui Paulo 		goto err;
3651d4f2939cSRui Paulo 	}
3652d4f2939cSRui Paulo 
3653d4f2939cSRui Paulo 	wpas_dbus_register(obj_desc, wpa_s, NULL, wpas_dbus_interface_methods,
3654*780fb4a2SCy Schubert 			   ctrl_iface->all_interface_properties,
3655d4f2939cSRui Paulo 			   wpas_dbus_interface_signals);
3656d4f2939cSRui Paulo 
3657d4f2939cSRui Paulo 	wpa_printf(MSG_DEBUG, "dbus: Register interface object '%s'",
3658d4f2939cSRui Paulo 		   wpa_s->dbus_new_path);
3659d4f2939cSRui Paulo 	if (wpa_dbus_register_object_per_iface(ctrl_iface,
3660d4f2939cSRui Paulo 					       wpa_s->dbus_new_path,
3661d4f2939cSRui Paulo 					       wpa_s->ifname, obj_desc))
3662d4f2939cSRui Paulo 		goto err;
3663d4f2939cSRui Paulo 
3664d4f2939cSRui Paulo 	wpas_dbus_signal_interface_added(wpa_s);
3665d4f2939cSRui Paulo 
3666d4f2939cSRui Paulo 	return 0;
3667d4f2939cSRui Paulo 
3668d4f2939cSRui Paulo err:
3669d4f2939cSRui Paulo 	os_free(wpa_s->dbus_new_path);
3670d4f2939cSRui Paulo 	wpa_s->dbus_new_path = NULL;
3671d4f2939cSRui Paulo 	free_dbus_object_desc(obj_desc);
3672d4f2939cSRui Paulo 	return -1;
3673d4f2939cSRui Paulo }
3674d4f2939cSRui Paulo 
3675d4f2939cSRui Paulo 
3676325151a3SRui Paulo /**
3677325151a3SRui Paulo  * wpas_dbus_unregister_interface - Unregister the interface from D-Bus
3678325151a3SRui Paulo  * @wpa_s: wpa_supplicant interface structure
3679325151a3SRui Paulo  * Returns: 0 on success, -1 on failure
3680325151a3SRui Paulo  */
3681d4f2939cSRui Paulo int wpas_dbus_unregister_interface(struct wpa_supplicant *wpa_s)
3682d4f2939cSRui Paulo {
3683d4f2939cSRui Paulo 	struct wpas_dbus_priv *ctrl_iface;
3684d4f2939cSRui Paulo 
3685d4f2939cSRui Paulo 	/* Do nothing if the control interface is not turned on */
3686d4f2939cSRui Paulo 	if (wpa_s == NULL || wpa_s->global == NULL)
3687d4f2939cSRui Paulo 		return 0;
3688d4f2939cSRui Paulo 	ctrl_iface = wpa_s->global->dbus;
36895b9c547cSRui Paulo 	if (ctrl_iface == NULL || wpa_s->dbus_new_path == NULL)
3690d4f2939cSRui Paulo 		return 0;
3691d4f2939cSRui Paulo 
3692d4f2939cSRui Paulo 	wpa_printf(MSG_DEBUG, "dbus: Unregister interface object '%s'",
3693d4f2939cSRui Paulo 		   wpa_s->dbus_new_path);
3694d4f2939cSRui Paulo 
3695d4f2939cSRui Paulo #ifdef CONFIG_AP
3696d4f2939cSRui Paulo 	if (wpa_s->preq_notify_peer) {
3697d4f2939cSRui Paulo 		wpas_dbus_unsubscribe_noc(ctrl_iface);
3698d4f2939cSRui Paulo 		os_free(wpa_s->preq_notify_peer);
3699d4f2939cSRui Paulo 		wpa_s->preq_notify_peer = NULL;
3700d4f2939cSRui Paulo 	}
3701d4f2939cSRui Paulo #endif /* CONFIG_AP */
3702d4f2939cSRui Paulo 
3703d4f2939cSRui Paulo 	if (wpa_dbus_unregister_object_per_iface(ctrl_iface,
3704d4f2939cSRui Paulo 						 wpa_s->dbus_new_path))
3705d4f2939cSRui Paulo 		return -1;
3706d4f2939cSRui Paulo 
3707d4f2939cSRui Paulo 	wpas_dbus_signal_interface_removed(wpa_s);
3708d4f2939cSRui Paulo 
3709d4f2939cSRui Paulo 	os_free(wpa_s->dbus_new_path);
3710d4f2939cSRui Paulo 	wpa_s->dbus_new_path = NULL;
3711d4f2939cSRui Paulo 
3712d4f2939cSRui Paulo 	return 0;
3713d4f2939cSRui Paulo }
3714d4f2939cSRui Paulo 
3715d4f2939cSRui Paulo #ifdef CONFIG_P2P
3716d4f2939cSRui Paulo 
3717d4f2939cSRui Paulo static const struct wpa_dbus_property_desc wpas_dbus_p2p_peer_properties[] = {
3718d4f2939cSRui Paulo 	{ "DeviceName", WPAS_DBUS_NEW_IFACE_P2P_PEER, "s",
3719d4f2939cSRui Paulo 	  wpas_dbus_getter_p2p_peer_device_name,
3720*780fb4a2SCy Schubert 	  NULL,
3721d4f2939cSRui Paulo 	  NULL
3722d4f2939cSRui Paulo 	},
3723325151a3SRui Paulo 	{ "Manufacturer", WPAS_DBUS_NEW_IFACE_P2P_PEER, "s",
3724325151a3SRui Paulo 	  wpas_dbus_getter_p2p_peer_manufacturer,
3725*780fb4a2SCy Schubert 	  NULL,
3726325151a3SRui Paulo 	  NULL
3727325151a3SRui Paulo 	},
3728325151a3SRui Paulo 	{ "ModelName", WPAS_DBUS_NEW_IFACE_P2P_PEER, "s",
3729325151a3SRui Paulo 	  wpas_dbus_getter_p2p_peer_modelname,
3730*780fb4a2SCy Schubert 	  NULL,
3731325151a3SRui Paulo 	  NULL
3732325151a3SRui Paulo 	},
3733325151a3SRui Paulo 	{ "ModelNumber", WPAS_DBUS_NEW_IFACE_P2P_PEER, "s",
3734325151a3SRui Paulo 	  wpas_dbus_getter_p2p_peer_modelnumber,
3735*780fb4a2SCy Schubert 	  NULL,
3736325151a3SRui Paulo 	  NULL
3737325151a3SRui Paulo 	},
3738325151a3SRui Paulo 	{ "SerialNumber", WPAS_DBUS_NEW_IFACE_P2P_PEER, "s",
3739325151a3SRui Paulo 	  wpas_dbus_getter_p2p_peer_serialnumber,
3740*780fb4a2SCy Schubert 	  NULL,
3741325151a3SRui Paulo 	  NULL
3742325151a3SRui Paulo 	},
3743d4f2939cSRui Paulo 	{ "PrimaryDeviceType", WPAS_DBUS_NEW_IFACE_P2P_PEER, "ay",
3744d4f2939cSRui Paulo 	  wpas_dbus_getter_p2p_peer_primary_device_type,
3745*780fb4a2SCy Schubert 	  NULL,
3746d4f2939cSRui Paulo 	  NULL
3747d4f2939cSRui Paulo 	},
3748d4f2939cSRui Paulo 	{ "config_method", WPAS_DBUS_NEW_IFACE_P2P_PEER, "q",
3749d4f2939cSRui Paulo 	  wpas_dbus_getter_p2p_peer_config_method,
3750*780fb4a2SCy Schubert 	  NULL,
3751d4f2939cSRui Paulo 	  NULL
3752d4f2939cSRui Paulo 	},
3753d4f2939cSRui Paulo 	{ "level", WPAS_DBUS_NEW_IFACE_P2P_PEER, "i",
3754d4f2939cSRui Paulo 	  wpas_dbus_getter_p2p_peer_level,
3755*780fb4a2SCy Schubert 	  NULL,
3756d4f2939cSRui Paulo 	  NULL
3757d4f2939cSRui Paulo 	},
3758d4f2939cSRui Paulo 	{ "devicecapability", WPAS_DBUS_NEW_IFACE_P2P_PEER, "y",
3759d4f2939cSRui Paulo 	  wpas_dbus_getter_p2p_peer_device_capability,
3760*780fb4a2SCy Schubert 	  NULL,
3761d4f2939cSRui Paulo 	  NULL
3762d4f2939cSRui Paulo 	},
3763d4f2939cSRui Paulo 	{ "groupcapability", WPAS_DBUS_NEW_IFACE_P2P_PEER, "y",
3764d4f2939cSRui Paulo 	  wpas_dbus_getter_p2p_peer_group_capability,
3765*780fb4a2SCy Schubert 	  NULL,
3766d4f2939cSRui Paulo 	  NULL
3767d4f2939cSRui Paulo 	},
3768d4f2939cSRui Paulo 	{ "SecondaryDeviceTypes", WPAS_DBUS_NEW_IFACE_P2P_PEER, "aay",
3769d4f2939cSRui Paulo 	  wpas_dbus_getter_p2p_peer_secondary_device_types,
3770*780fb4a2SCy Schubert 	  NULL,
3771d4f2939cSRui Paulo 	  NULL
3772d4f2939cSRui Paulo 	},
3773d4f2939cSRui Paulo 	{ "VendorExtension", WPAS_DBUS_NEW_IFACE_P2P_PEER, "aay",
3774d4f2939cSRui Paulo 	  wpas_dbus_getter_p2p_peer_vendor_extension,
3775*780fb4a2SCy Schubert 	  NULL,
3776d4f2939cSRui Paulo 	  NULL
3777d4f2939cSRui Paulo 	},
3778d4f2939cSRui Paulo 	{ "IEs", WPAS_DBUS_NEW_IFACE_P2P_PEER, "ay",
3779d4f2939cSRui Paulo 	  wpas_dbus_getter_p2p_peer_ies,
3780*780fb4a2SCy Schubert 	  NULL,
3781d4f2939cSRui Paulo 	  NULL
3782d4f2939cSRui Paulo 	},
37835b9c547cSRui Paulo 	{ "DeviceAddress", WPAS_DBUS_NEW_IFACE_P2P_PEER, "ay",
37845b9c547cSRui Paulo 	  wpas_dbus_getter_p2p_peer_device_address,
3785*780fb4a2SCy Schubert 	  NULL,
37865b9c547cSRui Paulo 	  NULL
37875b9c547cSRui Paulo 	},
37885b9c547cSRui Paulo 	{ "Groups", WPAS_DBUS_NEW_IFACE_P2P_PEER, "ao",
37895b9c547cSRui Paulo 	  wpas_dbus_getter_p2p_peer_groups,
3790*780fb4a2SCy Schubert 	  NULL,
37915b9c547cSRui Paulo 	  NULL
37925b9c547cSRui Paulo 	},
3793*780fb4a2SCy Schubert 	{ NULL, NULL, NULL, NULL, NULL, NULL }
3794d4f2939cSRui Paulo };
3795d4f2939cSRui Paulo 
3796d4f2939cSRui Paulo static const struct wpa_dbus_signal_desc wpas_dbus_p2p_peer_signals[] = {
37975b9c547cSRui Paulo 	/* Deprecated: use org.freedesktop.DBus.Properties.PropertiesChanged */
37985b9c547cSRui Paulo 	{ "PropertiesChanged", WPAS_DBUS_NEW_IFACE_P2P_PEER,
37995b9c547cSRui Paulo 	  {
38005b9c547cSRui Paulo 		  { "properties", "a{sv}", ARG_OUT },
38015b9c547cSRui Paulo 		  END_ARGS
38025b9c547cSRui Paulo 	  }
38035b9c547cSRui Paulo 	},
3804d4f2939cSRui Paulo 	{ NULL, NULL, { END_ARGS } }
3805d4f2939cSRui Paulo };
3806d4f2939cSRui Paulo 
3807d4f2939cSRui Paulo /**
3808d4f2939cSRui Paulo  * wpas_dbus_signal_peer - Send a peer related event signal
3809d4f2939cSRui Paulo  * @wpa_s: %wpa_supplicant network interface data
3810d4f2939cSRui Paulo  * @dev: peer device object
3811d4f2939cSRui Paulo  * @interface: name of the interface emitting this signal.
3812d4f2939cSRui Paulo  *	In case of peer objects, it would be emitted by either
3813d4f2939cSRui Paulo  *	the "interface object" or by "peer objects"
3814d4f2939cSRui Paulo  * @sig_name: signal name - DeviceFound
3815*780fb4a2SCy Schubert  * @properties: Whether to add a second argument with object properties
3816d4f2939cSRui Paulo  *
3817*780fb4a2SCy Schubert  * Notify listeners about event related with p2p peer device
3818d4f2939cSRui Paulo  */
3819d4f2939cSRui Paulo static void wpas_dbus_signal_peer(struct wpa_supplicant *wpa_s,
3820d4f2939cSRui Paulo 				  const u8 *dev_addr, const char *interface,
3821*780fb4a2SCy Schubert 				  const char *sig_name, int properties)
3822d4f2939cSRui Paulo {
3823d4f2939cSRui Paulo 	struct wpas_dbus_priv *iface;
3824d4f2939cSRui Paulo 	DBusMessage *msg;
3825d4f2939cSRui Paulo 	DBusMessageIter iter;
3826d4f2939cSRui Paulo 	char peer_obj_path[WPAS_DBUS_OBJECT_PATH_MAX], *path;
3827d4f2939cSRui Paulo 
38285b9c547cSRui Paulo 	if (wpa_s->p2p_mgmt)
38295b9c547cSRui Paulo 		wpa_s = wpa_s->parent;
38305b9c547cSRui Paulo 
3831d4f2939cSRui Paulo 	iface = wpa_s->global->dbus;
3832d4f2939cSRui Paulo 
3833d4f2939cSRui Paulo 	/* Do nothing if the control interface is not turned on */
3834325151a3SRui Paulo 	if (iface == NULL || !wpa_s->dbus_new_path)
3835d4f2939cSRui Paulo 		return;
3836d4f2939cSRui Paulo 
3837d4f2939cSRui Paulo 	os_snprintf(peer_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
3838d4f2939cSRui Paulo 		    "%s/" WPAS_DBUS_NEW_P2P_PEERS_PART "/" COMPACT_MACSTR,
3839d4f2939cSRui Paulo 		    wpa_s->dbus_new_path, MAC2STR(dev_addr));
3840d4f2939cSRui Paulo 
3841d4f2939cSRui Paulo 	msg = dbus_message_new_signal(wpa_s->dbus_new_path, interface,
3842d4f2939cSRui Paulo 				      sig_name);
3843d4f2939cSRui Paulo 	if (msg == NULL)
3844d4f2939cSRui Paulo 		return;
3845d4f2939cSRui Paulo 
3846d4f2939cSRui Paulo 	dbus_message_iter_init_append(msg, &iter);
3847d4f2939cSRui Paulo 	path = peer_obj_path;
3848d4f2939cSRui Paulo 	if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_OBJECT_PATH,
3849*780fb4a2SCy Schubert 					    &path) ||
3850*780fb4a2SCy Schubert 	    (properties && !wpa_dbus_get_object_properties(
3851*780fb4a2SCy Schubert 		    iface, peer_obj_path, WPAS_DBUS_NEW_IFACE_P2P_PEER,
3852*780fb4a2SCy Schubert 		    &iter)))
38535b9c547cSRui Paulo 		wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
38545b9c547cSRui Paulo 	else
3855d4f2939cSRui Paulo 		dbus_connection_send(iface->con, msg, NULL);
3856d4f2939cSRui Paulo 
3857d4f2939cSRui Paulo 	dbus_message_unref(msg);
3858d4f2939cSRui Paulo }
3859d4f2939cSRui Paulo 
3860d4f2939cSRui Paulo 
3861d4f2939cSRui Paulo /**
3862d4f2939cSRui Paulo  * wpas_dbus_signal_peer_found - Send a peer found signal
3863d4f2939cSRui Paulo  * @wpa_s: %wpa_supplicant network interface data
3864325151a3SRui Paulo  * @dev_addr: Peer P2P Device Address
3865d4f2939cSRui Paulo  *
3866d4f2939cSRui Paulo  * Notify listeners about find a p2p peer device found
3867d4f2939cSRui Paulo  */
3868d4f2939cSRui Paulo void wpas_dbus_signal_peer_device_found(struct wpa_supplicant *wpa_s,
3869d4f2939cSRui Paulo 					const u8 *dev_addr)
3870d4f2939cSRui Paulo {
3871d4f2939cSRui Paulo 	wpas_dbus_signal_peer(wpa_s, dev_addr,
3872d4f2939cSRui Paulo 			      WPAS_DBUS_NEW_IFACE_P2PDEVICE,
3873*780fb4a2SCy Schubert 			      "DeviceFound", FALSE);
3874*780fb4a2SCy Schubert 
3875*780fb4a2SCy Schubert 	wpas_dbus_signal_peer(wpa_s, dev_addr,
3876*780fb4a2SCy Schubert 			      WPAS_DBUS_NEW_IFACE_P2PDEVICE,
3877*780fb4a2SCy Schubert 			      "DeviceFoundProperties", TRUE);
3878d4f2939cSRui Paulo }
3879d4f2939cSRui Paulo 
3880d4f2939cSRui Paulo /**
3881d4f2939cSRui Paulo  * wpas_dbus_signal_peer_lost - Send a peer lost signal
3882d4f2939cSRui Paulo  * @wpa_s: %wpa_supplicant network interface data
3883325151a3SRui Paulo  * @dev_addr: Peer P2P Device Address
3884d4f2939cSRui Paulo  *
3885d4f2939cSRui Paulo  * Notify listeners about lost a p2p peer device
3886d4f2939cSRui Paulo  */
3887d4f2939cSRui Paulo void wpas_dbus_signal_peer_device_lost(struct wpa_supplicant *wpa_s,
3888d4f2939cSRui Paulo 				       const u8 *dev_addr)
3889d4f2939cSRui Paulo {
3890d4f2939cSRui Paulo 	wpas_dbus_signal_peer(wpa_s, dev_addr,
3891d4f2939cSRui Paulo 			      WPAS_DBUS_NEW_IFACE_P2PDEVICE,
3892*780fb4a2SCy Schubert 			      "DeviceLost", FALSE);
3893d4f2939cSRui Paulo }
3894d4f2939cSRui Paulo 
3895d4f2939cSRui Paulo /**
3896d4f2939cSRui Paulo  * wpas_dbus_register_peer - Register a discovered peer object with dbus
3897d4f2939cSRui Paulo  * @wpa_s: wpa_supplicant interface structure
3898325151a3SRui Paulo  * @dev_addr: P2P Device Address of the peer
3899d4f2939cSRui Paulo  * Returns: 0 on success, -1 on failure
3900d4f2939cSRui Paulo  *
3901d4f2939cSRui Paulo  * Registers network representing object with dbus
3902d4f2939cSRui Paulo  */
3903d4f2939cSRui Paulo int wpas_dbus_register_peer(struct wpa_supplicant *wpa_s, const u8 *dev_addr)
3904d4f2939cSRui Paulo {
3905d4f2939cSRui Paulo 	struct wpas_dbus_priv *ctrl_iface;
3906d4f2939cSRui Paulo 	struct wpa_dbus_object_desc *obj_desc;
3907d4f2939cSRui Paulo 	struct peer_handler_args *arg;
3908d4f2939cSRui Paulo 	char peer_obj_path[WPAS_DBUS_OBJECT_PATH_MAX];
3909d4f2939cSRui Paulo 
3910d4f2939cSRui Paulo 	/* Do nothing if the control interface is not turned on */
3911d4f2939cSRui Paulo 	if (wpa_s == NULL || wpa_s->global == NULL)
3912d4f2939cSRui Paulo 		return 0;
3913d4f2939cSRui Paulo 
3914d4f2939cSRui Paulo 	ctrl_iface = wpa_s->global->dbus;
3915d4f2939cSRui Paulo 	if (ctrl_iface == NULL)
3916d4f2939cSRui Paulo 		return 0;
3917d4f2939cSRui Paulo 
3918325151a3SRui Paulo 	wpa_s = wpa_s->parent->parent;
3919325151a3SRui Paulo 	if (!wpa_s->dbus_new_path)
3920325151a3SRui Paulo 		return 0;
39215b9c547cSRui Paulo 
3922d4f2939cSRui Paulo 	os_snprintf(peer_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
3923d4f2939cSRui Paulo 		    "%s/" WPAS_DBUS_NEW_P2P_PEERS_PART "/" COMPACT_MACSTR,
3924d4f2939cSRui Paulo 		    wpa_s->dbus_new_path, MAC2STR(dev_addr));
3925d4f2939cSRui Paulo 
3926d4f2939cSRui Paulo 	wpa_printf(MSG_INFO, "dbus: Register peer object '%s'",
3927d4f2939cSRui Paulo 		   peer_obj_path);
3928d4f2939cSRui Paulo 	obj_desc = os_zalloc(sizeof(struct wpa_dbus_object_desc));
3929d4f2939cSRui Paulo 	if (!obj_desc) {
39305b9c547cSRui Paulo 		wpa_printf(MSG_ERROR,
39315b9c547cSRui Paulo 			   "Not enough memory to create object description");
3932d4f2939cSRui Paulo 		goto err;
3933d4f2939cSRui Paulo 	}
3934d4f2939cSRui Paulo 
3935d4f2939cSRui Paulo 	/* allocate memory for handlers arguments */
3936d4f2939cSRui Paulo 	arg = os_zalloc(sizeof(struct peer_handler_args));
3937d4f2939cSRui Paulo 	if (!arg) {
39385b9c547cSRui Paulo 		wpa_printf(MSG_ERROR,
39395b9c547cSRui Paulo 			   "Not enough memory to create arguments for method");
3940d4f2939cSRui Paulo 		goto err;
3941d4f2939cSRui Paulo 	}
3942d4f2939cSRui Paulo 
3943d4f2939cSRui Paulo 	arg->wpa_s = wpa_s;
3944d4f2939cSRui Paulo 	os_memcpy(arg->p2p_device_addr, dev_addr, ETH_ALEN);
3945d4f2939cSRui Paulo 
3946d4f2939cSRui Paulo 	wpas_dbus_register(obj_desc, arg, wpa_dbus_free,
3947d4f2939cSRui Paulo 			   NULL,
3948d4f2939cSRui Paulo 			   wpas_dbus_p2p_peer_properties,
3949d4f2939cSRui Paulo 			   wpas_dbus_p2p_peer_signals);
3950d4f2939cSRui Paulo 
3951d4f2939cSRui Paulo 	if (wpa_dbus_register_object_per_iface(ctrl_iface, peer_obj_path,
3952d4f2939cSRui Paulo 					       wpa_s->ifname, obj_desc))
3953d4f2939cSRui Paulo 		goto err;
3954d4f2939cSRui Paulo 
3955d4f2939cSRui Paulo 	return 0;
3956d4f2939cSRui Paulo 
3957d4f2939cSRui Paulo err:
3958d4f2939cSRui Paulo 	free_dbus_object_desc(obj_desc);
3959d4f2939cSRui Paulo 	return -1;
3960d4f2939cSRui Paulo }
3961d4f2939cSRui Paulo 
3962d4f2939cSRui Paulo /**
3963d4f2939cSRui Paulo  * wpas_dbus_unregister_peer - Unregister a peer object with dbus
3964d4f2939cSRui Paulo  * @wpa_s: wpa_supplicant interface structure
3965d4f2939cSRui Paulo  * @dev_addr: p2p device addr
3966d4f2939cSRui Paulo  * Returns: 0 on success, -1 on failure
3967d4f2939cSRui Paulo  *
3968d4f2939cSRui Paulo  * Registers network representing object with dbus
3969d4f2939cSRui Paulo  */
3970d4f2939cSRui Paulo int wpas_dbus_unregister_peer(struct wpa_supplicant *wpa_s,
3971d4f2939cSRui Paulo 				  const u8 *dev_addr)
3972d4f2939cSRui Paulo {
3973d4f2939cSRui Paulo 	struct wpas_dbus_priv *ctrl_iface;
3974d4f2939cSRui Paulo 	char peer_obj_path[WPAS_DBUS_OBJECT_PATH_MAX];
3975d4f2939cSRui Paulo 	int ret;
3976d4f2939cSRui Paulo 
3977d4f2939cSRui Paulo 	/* Do nothing if the control interface is not turned on */
3978325151a3SRui Paulo 	if (wpa_s == NULL || wpa_s->global == NULL)
3979d4f2939cSRui Paulo 		return 0;
39805b9c547cSRui Paulo 
3981325151a3SRui Paulo 	wpa_s = wpa_s->parent->parent;
3982325151a3SRui Paulo 	if (!wpa_s->dbus_new_path)
3983325151a3SRui Paulo 		return 0;
39845b9c547cSRui Paulo 
3985d4f2939cSRui Paulo 	ctrl_iface = wpa_s->global->dbus;
3986d4f2939cSRui Paulo 	if (ctrl_iface == NULL)
3987d4f2939cSRui Paulo 		return 0;
3988d4f2939cSRui Paulo 
3989d4f2939cSRui Paulo 	os_snprintf(peer_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
3990d4f2939cSRui Paulo 		    "%s/" WPAS_DBUS_NEW_P2P_PEERS_PART "/" COMPACT_MACSTR,
3991d4f2939cSRui Paulo 		    wpa_s->dbus_new_path, MAC2STR(dev_addr));
3992d4f2939cSRui Paulo 
3993d4f2939cSRui Paulo 	wpa_printf(MSG_INFO, "dbus: Unregister peer object '%s'",
3994d4f2939cSRui Paulo 		   peer_obj_path);
3995d4f2939cSRui Paulo 	ret = wpa_dbus_unregister_object_per_iface(ctrl_iface, peer_obj_path);
3996d4f2939cSRui Paulo 
3997d4f2939cSRui Paulo 	return ret;
3998d4f2939cSRui Paulo }
3999d4f2939cSRui Paulo 
4000d4f2939cSRui Paulo 
4001325151a3SRui Paulo /**
4002325151a3SRui Paulo  * wpas_dbus_signal_p2p_find_stopped - Send P2P Find stopped signal
4003325151a3SRui Paulo  * @wpa_s: %wpa_supplicant network interface data
4004325151a3SRui Paulo  *
4005325151a3SRui Paulo  * Notify listeners about P2P Find stopped
4006325151a3SRui Paulo  */
4007325151a3SRui Paulo void wpas_dbus_signal_p2p_find_stopped(struct wpa_supplicant *wpa_s)
4008325151a3SRui Paulo {
4009325151a3SRui Paulo 	struct wpas_dbus_priv *iface;
4010325151a3SRui Paulo 	DBusMessage *msg;
4011325151a3SRui Paulo 
4012325151a3SRui Paulo 	iface = wpa_s->global->dbus;
4013325151a3SRui Paulo 
4014325151a3SRui Paulo 	/* Do nothing if the control interface is not turned on */
4015325151a3SRui Paulo 	if (iface == NULL || !wpa_s->dbus_new_path)
4016325151a3SRui Paulo 		return;
4017325151a3SRui Paulo 
4018325151a3SRui Paulo 	msg = dbus_message_new_signal(wpa_s->dbus_new_path,
4019325151a3SRui Paulo 				      WPAS_DBUS_NEW_IFACE_P2PDEVICE,
4020325151a3SRui Paulo 				      "FindStopped");
4021325151a3SRui Paulo 	if (msg == NULL)
4022325151a3SRui Paulo 		return;
4023325151a3SRui Paulo 
4024325151a3SRui Paulo 	dbus_connection_send(iface->con, msg, NULL);
4025325151a3SRui Paulo 
4026325151a3SRui Paulo 	dbus_message_unref(msg);
4027325151a3SRui Paulo }
4028325151a3SRui Paulo 
4029325151a3SRui Paulo 
4030325151a3SRui Paulo /**
4031325151a3SRui Paulo  * wpas_dbus_signal_peer_groups_changed - Send peer group change property signal
4032325151a3SRui Paulo  * @wpa_s: %wpa_supplicant network interface data
4033325151a3SRui Paulo  * @dev_addr: P2P Device Address
4034325151a3SRui Paulo  *
4035325151a3SRui Paulo  * Notify listeners about peer Groups property changes.
4036325151a3SRui Paulo  */
40375b9c547cSRui Paulo void wpas_dbus_signal_peer_groups_changed(struct wpa_supplicant *wpa_s,
40385b9c547cSRui Paulo 					  const u8 *dev_addr)
40395b9c547cSRui Paulo {
40405b9c547cSRui Paulo 	char peer_obj_path[WPAS_DBUS_OBJECT_PATH_MAX];
40415b9c547cSRui Paulo 
40425b9c547cSRui Paulo 	if (wpa_s->p2p_mgmt)
40435b9c547cSRui Paulo 		wpa_s = wpa_s->parent;
40445b9c547cSRui Paulo 
4045325151a3SRui Paulo 	if (!wpa_s->dbus_new_path)
4046325151a3SRui Paulo 		return;
40475b9c547cSRui Paulo 	os_snprintf(peer_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
40485b9c547cSRui Paulo 		    "%s/" WPAS_DBUS_NEW_P2P_PEERS_PART "/" COMPACT_MACSTR,
40495b9c547cSRui Paulo 		    wpa_s->dbus_new_path, MAC2STR(dev_addr));
40505b9c547cSRui Paulo 
40515b9c547cSRui Paulo 	wpa_dbus_mark_property_changed(wpa_s->global->dbus, peer_obj_path,
40525b9c547cSRui Paulo 				       WPAS_DBUS_NEW_IFACE_P2P_PEER, "Groups");
40535b9c547cSRui Paulo }
40545b9c547cSRui Paulo 
40555b9c547cSRui Paulo 
4056d4f2939cSRui Paulo static const struct wpa_dbus_property_desc wpas_dbus_p2p_group_properties[] = {
4057d4f2939cSRui Paulo 	{ "Members", WPAS_DBUS_NEW_IFACE_P2P_GROUP, "ao",
4058d4f2939cSRui Paulo 	  wpas_dbus_getter_p2p_group_members,
4059*780fb4a2SCy Schubert 	  NULL,
4060d4f2939cSRui Paulo 	  NULL
4061d4f2939cSRui Paulo 	},
4062d4f2939cSRui Paulo 	{ "Group", WPAS_DBUS_NEW_IFACE_P2P_GROUP, "o",
4063d4f2939cSRui Paulo 	  wpas_dbus_getter_p2p_group,
4064*780fb4a2SCy Schubert 	  NULL,
4065d4f2939cSRui Paulo 	  NULL
4066d4f2939cSRui Paulo 	},
4067d4f2939cSRui Paulo 	{ "Role", WPAS_DBUS_NEW_IFACE_P2P_GROUP, "s",
4068d4f2939cSRui Paulo 	  wpas_dbus_getter_p2p_role,
4069*780fb4a2SCy Schubert 	  NULL,
4070d4f2939cSRui Paulo 	  NULL
4071d4f2939cSRui Paulo 	},
4072d4f2939cSRui Paulo 	{ "SSID", WPAS_DBUS_NEW_IFACE_P2P_GROUP, "ay",
4073d4f2939cSRui Paulo 	  wpas_dbus_getter_p2p_group_ssid,
4074*780fb4a2SCy Schubert 	  NULL,
4075d4f2939cSRui Paulo 	  NULL
4076d4f2939cSRui Paulo 	},
4077d4f2939cSRui Paulo 	{ "BSSID", WPAS_DBUS_NEW_IFACE_P2P_GROUP, "ay",
4078d4f2939cSRui Paulo 	  wpas_dbus_getter_p2p_group_bssid,
4079*780fb4a2SCy Schubert 	  NULL,
4080d4f2939cSRui Paulo 	  NULL
4081d4f2939cSRui Paulo 	},
4082d4f2939cSRui Paulo 	{ "Frequency", WPAS_DBUS_NEW_IFACE_P2P_GROUP, "q",
4083d4f2939cSRui Paulo 	  wpas_dbus_getter_p2p_group_frequency,
4084*780fb4a2SCy Schubert 	  NULL,
4085d4f2939cSRui Paulo 	  NULL
4086d4f2939cSRui Paulo 	},
4087d4f2939cSRui Paulo 	{ "Passphrase", WPAS_DBUS_NEW_IFACE_P2P_GROUP, "s",
4088d4f2939cSRui Paulo 	  wpas_dbus_getter_p2p_group_passphrase,
4089*780fb4a2SCy Schubert 	  NULL,
4090d4f2939cSRui Paulo 	  NULL
4091d4f2939cSRui Paulo 	},
4092d4f2939cSRui Paulo 	{ "PSK", WPAS_DBUS_NEW_IFACE_P2P_GROUP, "ay",
4093d4f2939cSRui Paulo 	  wpas_dbus_getter_p2p_group_psk,
4094*780fb4a2SCy Schubert 	  NULL,
4095d4f2939cSRui Paulo 	  NULL
4096d4f2939cSRui Paulo 	},
4097d4f2939cSRui Paulo 	{ "WPSVendorExtensions", WPAS_DBUS_NEW_IFACE_P2P_GROUP, "aay",
4098d4f2939cSRui Paulo 	  wpas_dbus_getter_p2p_group_vendor_ext,
4099*780fb4a2SCy Schubert 	  wpas_dbus_setter_p2p_group_vendor_ext,
4100*780fb4a2SCy Schubert 	  NULL
4101d4f2939cSRui Paulo 	},
4102*780fb4a2SCy Schubert 	{ NULL, NULL, NULL, NULL, NULL, NULL }
4103d4f2939cSRui Paulo };
4104d4f2939cSRui Paulo 
4105d4f2939cSRui Paulo static const struct wpa_dbus_signal_desc wpas_dbus_p2p_group_signals[] = {
4106d4f2939cSRui Paulo 	{ "PeerJoined", WPAS_DBUS_NEW_IFACE_P2P_GROUP,
4107d4f2939cSRui Paulo 	  {
4108d4f2939cSRui Paulo 		  { "peer", "o", ARG_OUT },
4109d4f2939cSRui Paulo 		  END_ARGS
4110d4f2939cSRui Paulo 	  }
4111d4f2939cSRui Paulo 	},
4112d4f2939cSRui Paulo 	{ "PeerDisconnected", WPAS_DBUS_NEW_IFACE_P2P_GROUP,
4113d4f2939cSRui Paulo 	  {
4114d4f2939cSRui Paulo 		  { "peer", "o", ARG_OUT },
4115d4f2939cSRui Paulo 		  END_ARGS
4116d4f2939cSRui Paulo 	  }
4117d4f2939cSRui Paulo 	},
4118d4f2939cSRui Paulo 	{ NULL, NULL, { END_ARGS } }
4119d4f2939cSRui Paulo };
4120d4f2939cSRui Paulo 
4121d4f2939cSRui Paulo /**
4122d4f2939cSRui Paulo  * wpas_dbus_register_p2p_group - Register a p2p group object with dbus
4123d4f2939cSRui Paulo  * @wpa_s: wpa_supplicant interface structure
4124d4f2939cSRui Paulo  * @ssid: SSID struct
4125d4f2939cSRui Paulo  * Returns: 0 on success, -1 on failure
4126d4f2939cSRui Paulo  *
4127d4f2939cSRui Paulo  * Registers p2p group representing object with dbus
4128d4f2939cSRui Paulo  */
4129d4f2939cSRui Paulo void wpas_dbus_register_p2p_group(struct wpa_supplicant *wpa_s,
4130d4f2939cSRui Paulo 				  struct wpa_ssid *ssid)
4131d4f2939cSRui Paulo {
4132d4f2939cSRui Paulo 	struct wpas_dbus_priv *ctrl_iface;
4133d4f2939cSRui Paulo 	struct wpa_dbus_object_desc *obj_desc;
4134d4f2939cSRui Paulo 	char group_obj_path[WPAS_DBUS_OBJECT_PATH_MAX];
4135d4f2939cSRui Paulo 
4136d4f2939cSRui Paulo 	/* Do nothing if the control interface is not turned on */
4137d4f2939cSRui Paulo 	if (wpa_s == NULL || wpa_s->global == NULL)
4138d4f2939cSRui Paulo 		return;
4139d4f2939cSRui Paulo 
4140d4f2939cSRui Paulo 	ctrl_iface = wpa_s->global->dbus;
4141d4f2939cSRui Paulo 	if (ctrl_iface == NULL)
4142d4f2939cSRui Paulo 		return;
4143d4f2939cSRui Paulo 
4144d4f2939cSRui Paulo 	if (wpa_s->dbus_groupobj_path) {
4145d4f2939cSRui Paulo 		wpa_printf(MSG_INFO, "%s: Group object '%s' already exists",
4146d4f2939cSRui Paulo 			   __func__, wpa_s->dbus_groupobj_path);
4147d4f2939cSRui Paulo 		return;
4148d4f2939cSRui Paulo 	}
4149d4f2939cSRui Paulo 
4150d4f2939cSRui Paulo 	if (wpas_dbus_get_group_obj_path(wpa_s, ssid, group_obj_path) < 0)
4151d4f2939cSRui Paulo 		return;
4152d4f2939cSRui Paulo 
4153d4f2939cSRui Paulo 	wpa_s->dbus_groupobj_path = os_strdup(group_obj_path);
4154d4f2939cSRui Paulo 	if (wpa_s->dbus_groupobj_path == NULL)
4155d4f2939cSRui Paulo 		return;
4156d4f2939cSRui Paulo 
4157d4f2939cSRui Paulo 	wpa_printf(MSG_INFO, "dbus: Register group object '%s'",
4158d4f2939cSRui Paulo 		   group_obj_path);
4159d4f2939cSRui Paulo 	obj_desc = os_zalloc(sizeof(struct wpa_dbus_object_desc));
4160d4f2939cSRui Paulo 	if (!obj_desc) {
41615b9c547cSRui Paulo 		wpa_printf(MSG_ERROR,
41625b9c547cSRui Paulo 			   "Not enough memory to create object description");
4163d4f2939cSRui Paulo 		goto err;
4164d4f2939cSRui Paulo 	}
4165d4f2939cSRui Paulo 
4166d4f2939cSRui Paulo 	wpas_dbus_register(obj_desc, wpa_s, NULL, NULL,
4167d4f2939cSRui Paulo 			   wpas_dbus_p2p_group_properties,
4168d4f2939cSRui Paulo 			   wpas_dbus_p2p_group_signals);
4169d4f2939cSRui Paulo 
4170d4f2939cSRui Paulo 	if (wpa_dbus_register_object_per_iface(ctrl_iface, group_obj_path,
4171d4f2939cSRui Paulo 					       wpa_s->ifname, obj_desc))
4172d4f2939cSRui Paulo 		goto err;
4173d4f2939cSRui Paulo 
4174d4f2939cSRui Paulo 	return;
4175d4f2939cSRui Paulo 
4176d4f2939cSRui Paulo err:
4177d4f2939cSRui Paulo 	if (wpa_s->dbus_groupobj_path) {
4178d4f2939cSRui Paulo 		os_free(wpa_s->dbus_groupobj_path);
4179d4f2939cSRui Paulo 		wpa_s->dbus_groupobj_path = NULL;
4180d4f2939cSRui Paulo 	}
4181d4f2939cSRui Paulo 
4182d4f2939cSRui Paulo 	free_dbus_object_desc(obj_desc);
4183d4f2939cSRui Paulo }
4184d4f2939cSRui Paulo 
4185d4f2939cSRui Paulo /**
4186d4f2939cSRui Paulo  * wpas_dbus_unregister_p2p_group - Unregister a p2p group object from dbus
4187d4f2939cSRui Paulo  * @wpa_s: wpa_supplicant interface structure
4188d4f2939cSRui Paulo  * @ssid: network name of the p2p group started
4189d4f2939cSRui Paulo  */
4190d4f2939cSRui Paulo void wpas_dbus_unregister_p2p_group(struct wpa_supplicant *wpa_s,
4191d4f2939cSRui Paulo 				    const struct wpa_ssid *ssid)
4192d4f2939cSRui Paulo {
4193d4f2939cSRui Paulo 	struct wpas_dbus_priv *ctrl_iface;
4194d4f2939cSRui Paulo 
4195d4f2939cSRui Paulo 	/* Do nothing if the control interface is not turned on */
4196d4f2939cSRui Paulo 	if (wpa_s == NULL || wpa_s->global == NULL)
4197d4f2939cSRui Paulo 		return;
4198d4f2939cSRui Paulo 
41995b9c547cSRui Paulo 	if (wpa_s->p2p_mgmt)
42005b9c547cSRui Paulo 		wpa_s = wpa_s->parent;
42015b9c547cSRui Paulo 
4202d4f2939cSRui Paulo 	ctrl_iface = wpa_s->global->dbus;
4203d4f2939cSRui Paulo 	if (ctrl_iface == NULL)
4204d4f2939cSRui Paulo 		return;
4205d4f2939cSRui Paulo 
4206d4f2939cSRui Paulo 	if (!wpa_s->dbus_groupobj_path) {
4207d4f2939cSRui Paulo 		wpa_printf(MSG_DEBUG,
4208d4f2939cSRui Paulo 			   "%s: Group object '%s' already unregistered",
4209d4f2939cSRui Paulo 			   __func__, wpa_s->dbus_groupobj_path);
4210d4f2939cSRui Paulo 		return;
4211d4f2939cSRui Paulo 	}
4212d4f2939cSRui Paulo 
42135b9c547cSRui Paulo 	peer_groups_changed(wpa_s);
42145b9c547cSRui Paulo 
4215d4f2939cSRui Paulo 	wpa_printf(MSG_DEBUG, "dbus: Unregister group object '%s'",
4216d4f2939cSRui Paulo 		   wpa_s->dbus_groupobj_path);
4217d4f2939cSRui Paulo 
4218d4f2939cSRui Paulo 	wpa_dbus_unregister_object_per_iface(ctrl_iface,
4219d4f2939cSRui Paulo 					     wpa_s->dbus_groupobj_path);
4220d4f2939cSRui Paulo 
4221d4f2939cSRui Paulo 	os_free(wpa_s->dbus_groupobj_path);
4222d4f2939cSRui Paulo 	wpa_s->dbus_groupobj_path = NULL;
4223d4f2939cSRui Paulo }
4224d4f2939cSRui Paulo 
4225d4f2939cSRui Paulo static const struct wpa_dbus_property_desc
4226d4f2939cSRui Paulo 	wpas_dbus_persistent_group_properties[] = {
4227d4f2939cSRui Paulo 	{ "Properties", WPAS_DBUS_NEW_IFACE_PERSISTENT_GROUP, "a{sv}",
4228d4f2939cSRui Paulo 	  wpas_dbus_getter_persistent_group_properties,
4229*780fb4a2SCy Schubert 	  wpas_dbus_setter_persistent_group_properties,
4230*780fb4a2SCy Schubert 	  NULL
4231d4f2939cSRui Paulo 	},
4232*780fb4a2SCy Schubert 	{ NULL, NULL, NULL, NULL, NULL, NULL }
4233d4f2939cSRui Paulo };
4234d4f2939cSRui Paulo 
4235d4f2939cSRui Paulo /* No signals intended for persistent group objects */
4236d4f2939cSRui Paulo 
4237d4f2939cSRui Paulo /**
4238d4f2939cSRui Paulo  * wpas_dbus_register_persistent_group - Register a configured(saved)
4239d4f2939cSRui Paulo  *	persistent group with dbus
4240d4f2939cSRui Paulo  * @wpa_s: wpa_supplicant interface structure
4241d4f2939cSRui Paulo  * @ssid: persistent group (still represented as a network within wpa)
4242d4f2939cSRui Paulo  *	  configuration data
4243d4f2939cSRui Paulo  * Returns: 0 on success, -1 on failure
4244d4f2939cSRui Paulo  *
4245d4f2939cSRui Paulo  * Registers a persistent group representing object with dbus.
4246d4f2939cSRui Paulo  */
4247d4f2939cSRui Paulo int wpas_dbus_register_persistent_group(struct wpa_supplicant *wpa_s,
4248d4f2939cSRui Paulo 					struct wpa_ssid *ssid)
4249d4f2939cSRui Paulo {
4250d4f2939cSRui Paulo 	struct wpas_dbus_priv *ctrl_iface;
4251d4f2939cSRui Paulo 	struct wpa_dbus_object_desc *obj_desc;
4252d4f2939cSRui Paulo 	struct network_handler_args *arg;
4253d4f2939cSRui Paulo 	char pgrp_obj_path[WPAS_DBUS_OBJECT_PATH_MAX];
4254d4f2939cSRui Paulo 
4255d4f2939cSRui Paulo 	/* Do nothing if the control interface is not turned on */
4256d4f2939cSRui Paulo 	if (wpa_s == NULL || wpa_s->global == NULL)
4257d4f2939cSRui Paulo 		return 0;
4258325151a3SRui Paulo 	wpa_s = wpa_s->parent->parent;
4259325151a3SRui Paulo 	if (!wpa_s->dbus_new_path)
4260325151a3SRui Paulo 		return 0;
4261d4f2939cSRui Paulo 
4262d4f2939cSRui Paulo 	/* Make sure ssid is a persistent group */
4263d4f2939cSRui Paulo 	if (ssid->disabled != 2 && !ssid->p2p_persistent_group)
4264d4f2939cSRui Paulo 		return -1; /* should we return w/o complaining? */
4265d4f2939cSRui Paulo 
42665b9c547cSRui Paulo 	if (wpa_s->p2p_mgmt)
42675b9c547cSRui Paulo 		wpa_s = wpa_s->parent;
42685b9c547cSRui Paulo 
4269d4f2939cSRui Paulo 	ctrl_iface = wpa_s->global->dbus;
4270d4f2939cSRui Paulo 	if (ctrl_iface == NULL)
4271d4f2939cSRui Paulo 		return 0;
4272d4f2939cSRui Paulo 
4273d4f2939cSRui Paulo 	/*
4274d4f2939cSRui Paulo 	 * Intentionally not coming up with different numbering scheme
4275d4f2939cSRui Paulo 	 * for persistent groups.
4276d4f2939cSRui Paulo 	 */
4277d4f2939cSRui Paulo 	os_snprintf(pgrp_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
4278d4f2939cSRui Paulo 		    "%s/" WPAS_DBUS_NEW_PERSISTENT_GROUPS_PART "/%u",
4279d4f2939cSRui Paulo 		    wpa_s->dbus_new_path, ssid->id);
4280d4f2939cSRui Paulo 
4281d4f2939cSRui Paulo 	wpa_printf(MSG_DEBUG, "dbus: Register persistent group object '%s'",
4282d4f2939cSRui Paulo 		   pgrp_obj_path);
4283d4f2939cSRui Paulo 	obj_desc = os_zalloc(sizeof(struct wpa_dbus_object_desc));
4284d4f2939cSRui Paulo 	if (!obj_desc) {
42855b9c547cSRui Paulo 		wpa_printf(MSG_ERROR,
42865b9c547cSRui Paulo 			   "dbus: Not enough memory to create object description");
4287d4f2939cSRui Paulo 		goto err;
4288d4f2939cSRui Paulo 	}
4289d4f2939cSRui Paulo 
4290d4f2939cSRui Paulo 	/*
4291d4f2939cSRui Paulo 	 * Reusing the same context structure as that for networks
4292d4f2939cSRui Paulo 	 * since these are represented using same data structure.
4293d4f2939cSRui Paulo 	 */
4294d4f2939cSRui Paulo 	/* allocate memory for handlers arguments */
4295d4f2939cSRui Paulo 	arg = os_zalloc(sizeof(struct network_handler_args));
4296d4f2939cSRui Paulo 	if (!arg) {
42975b9c547cSRui Paulo 		wpa_printf(MSG_ERROR,
42985b9c547cSRui Paulo 			   "dbus: Not enough memory to create arguments for method");
4299d4f2939cSRui Paulo 		goto err;
4300d4f2939cSRui Paulo 	}
4301d4f2939cSRui Paulo 
4302d4f2939cSRui Paulo 	arg->wpa_s = wpa_s;
4303d4f2939cSRui Paulo 	arg->ssid = ssid;
4304d4f2939cSRui Paulo 
4305d4f2939cSRui Paulo 	wpas_dbus_register(obj_desc, arg, wpa_dbus_free, NULL,
4306d4f2939cSRui Paulo 			   wpas_dbus_persistent_group_properties,
4307d4f2939cSRui Paulo 			   NULL);
4308d4f2939cSRui Paulo 
4309d4f2939cSRui Paulo 	if (wpa_dbus_register_object_per_iface(ctrl_iface, pgrp_obj_path,
4310d4f2939cSRui Paulo 					       wpa_s->ifname, obj_desc))
4311d4f2939cSRui Paulo 		goto err;
4312d4f2939cSRui Paulo 
4313d4f2939cSRui Paulo 	wpas_dbus_signal_persistent_group_added(wpa_s, ssid->id);
4314d4f2939cSRui Paulo 
4315d4f2939cSRui Paulo 	return 0;
4316d4f2939cSRui Paulo 
4317d4f2939cSRui Paulo err:
4318d4f2939cSRui Paulo 	free_dbus_object_desc(obj_desc);
4319d4f2939cSRui Paulo 	return -1;
4320d4f2939cSRui Paulo }
4321d4f2939cSRui Paulo 
4322d4f2939cSRui Paulo 
4323d4f2939cSRui Paulo /**
4324d4f2939cSRui Paulo  * wpas_dbus_unregister_persistent_group - Unregister a persistent_group
4325d4f2939cSRui Paulo  *	from dbus
4326d4f2939cSRui Paulo  * @wpa_s: wpa_supplicant interface structure
4327d4f2939cSRui Paulo  * @nid: network id
4328d4f2939cSRui Paulo  * Returns: 0 on success, -1 on failure
4329d4f2939cSRui Paulo  *
4330d4f2939cSRui Paulo  * Unregisters persistent group representing object from dbus
4331d4f2939cSRui Paulo  *
4332d4f2939cSRui Paulo  * NOTE: There is a slight issue with the semantics here. While the
4333d4f2939cSRui Paulo  * implementation simply means the persistent group is unloaded from memory,
4334d4f2939cSRui Paulo  * it should not get interpreted as the group is actually being erased/removed
4335d4f2939cSRui Paulo  * from persistent storage as well.
4336d4f2939cSRui Paulo  */
4337d4f2939cSRui Paulo int wpas_dbus_unregister_persistent_group(struct wpa_supplicant *wpa_s,
4338d4f2939cSRui Paulo 					  int nid)
4339d4f2939cSRui Paulo {
4340d4f2939cSRui Paulo 	struct wpas_dbus_priv *ctrl_iface;
4341d4f2939cSRui Paulo 	char pgrp_obj_path[WPAS_DBUS_OBJECT_PATH_MAX];
4342d4f2939cSRui Paulo 	int ret;
4343d4f2939cSRui Paulo 
4344d4f2939cSRui Paulo 	/* Do nothing if the control interface is not turned on */
4345325151a3SRui Paulo 	if (wpa_s == NULL || wpa_s->global == NULL)
4346d4f2939cSRui Paulo 		return 0;
43475b9c547cSRui Paulo 
4348325151a3SRui Paulo 	wpa_s = wpa_s->parent->parent;
43495b9c547cSRui Paulo 
4350d4f2939cSRui Paulo 	ctrl_iface = wpa_s->global->dbus;
4351325151a3SRui Paulo 	if (ctrl_iface == NULL || !wpa_s->dbus_new_path)
4352d4f2939cSRui Paulo 		return 0;
4353d4f2939cSRui Paulo 
4354d4f2939cSRui Paulo 	os_snprintf(pgrp_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
4355d4f2939cSRui Paulo 		    "%s/" WPAS_DBUS_NEW_PERSISTENT_GROUPS_PART "/%u",
4356d4f2939cSRui Paulo 		    wpa_s->dbus_new_path, nid);
4357d4f2939cSRui Paulo 
4358d4f2939cSRui Paulo 	wpa_printf(MSG_DEBUG, "dbus: Unregister persistent group object '%s'",
4359d4f2939cSRui Paulo 		   pgrp_obj_path);
4360d4f2939cSRui Paulo 	ret = wpa_dbus_unregister_object_per_iface(ctrl_iface, pgrp_obj_path);
4361d4f2939cSRui Paulo 
4362d4f2939cSRui Paulo 	if (!ret)
4363d4f2939cSRui Paulo 		wpas_dbus_signal_persistent_group_removed(wpa_s, nid);
4364d4f2939cSRui Paulo 
4365d4f2939cSRui Paulo 	return ret;
4366d4f2939cSRui Paulo }
4367d4f2939cSRui Paulo 
4368d4f2939cSRui Paulo #endif /* CONFIG_P2P */
4369