xref: /freebsd/contrib/wpa/wpa_supplicant/dbus/dbus_new.c (revision 4bc523382c7e72183c32be2c3aedecc1f5e844dd)
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"
16*4bc52338SCy Schubert #include "ap/sta_info.h"
17d4f2939cSRui Paulo #include "../config.h"
18d4f2939cSRui Paulo #include "../wpa_supplicant_i.h"
19d4f2939cSRui Paulo #include "../bss.h"
20d4f2939cSRui Paulo #include "../wpas_glue.h"
21d4f2939cSRui Paulo #include "dbus_new_helpers.h"
22d4f2939cSRui Paulo #include "dbus_dict_helpers.h"
23d4f2939cSRui Paulo #include "dbus_new.h"
24d4f2939cSRui Paulo #include "dbus_new_handlers.h"
25d4f2939cSRui Paulo #include "dbus_common_i.h"
26d4f2939cSRui Paulo #include "dbus_new_handlers_p2p.h"
27d4f2939cSRui Paulo #include "p2p/p2p.h"
285b9c547cSRui Paulo #include "../p2p_supplicant.h"
29d4f2939cSRui Paulo 
30d4f2939cSRui Paulo #ifdef CONFIG_AP /* until needed by something else */
31d4f2939cSRui Paulo 
32d4f2939cSRui Paulo /*
33d4f2939cSRui Paulo  * NameOwnerChanged handling
34d4f2939cSRui Paulo  *
35d4f2939cSRui Paulo  * Some services we provide allow an application to register for
36d4f2939cSRui Paulo  * a signal that it needs. While it can also unregister, we must
37d4f2939cSRui Paulo  * be prepared for the case where the application simply crashes
38d4f2939cSRui Paulo  * and thus doesn't clean up properly. The way to handle this in
39d4f2939cSRui Paulo  * DBus is to register for the NameOwnerChanged signal which will
40d4f2939cSRui Paulo  * signal an owner change to NULL if the peer closes the socket
41d4f2939cSRui Paulo  * for whatever reason.
42d4f2939cSRui Paulo  *
43d4f2939cSRui Paulo  * Handle this signal via a filter function whenever necessary.
44d4f2939cSRui Paulo  * The code below also handles refcounting in case in the future
45d4f2939cSRui Paulo  * there will be multiple instances of this subscription scheme.
46d4f2939cSRui Paulo  */
47d4f2939cSRui Paulo static const char wpas_dbus_noc_filter_str[] =
48d4f2939cSRui Paulo 	"interface=org.freedesktop.DBus,member=NameOwnerChanged";
49d4f2939cSRui Paulo 
50d4f2939cSRui Paulo 
51d4f2939cSRui Paulo static DBusHandlerResult noc_filter(DBusConnection *conn,
52d4f2939cSRui Paulo 				    DBusMessage *message, void *data)
53d4f2939cSRui Paulo {
54d4f2939cSRui Paulo 	struct wpas_dbus_priv *priv = data;
55d4f2939cSRui Paulo 
56d4f2939cSRui Paulo 	if (dbus_message_get_type(message) != DBUS_MESSAGE_TYPE_SIGNAL)
57d4f2939cSRui Paulo 		return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
58d4f2939cSRui Paulo 
59d4f2939cSRui Paulo 	if (dbus_message_is_signal(message, DBUS_INTERFACE_DBUS,
60d4f2939cSRui Paulo 				   "NameOwnerChanged")) {
61d4f2939cSRui Paulo 		const char *name;
62d4f2939cSRui Paulo 		const char *prev_owner;
63d4f2939cSRui Paulo 		const char *new_owner;
64d4f2939cSRui Paulo 		DBusError derr;
65d4f2939cSRui Paulo 		struct wpa_supplicant *wpa_s;
66d4f2939cSRui Paulo 
67d4f2939cSRui Paulo 		dbus_error_init(&derr);
68d4f2939cSRui Paulo 
69d4f2939cSRui Paulo 		if (!dbus_message_get_args(message, &derr,
70d4f2939cSRui Paulo 					   DBUS_TYPE_STRING, &name,
71d4f2939cSRui Paulo 					   DBUS_TYPE_STRING, &prev_owner,
72d4f2939cSRui Paulo 					   DBUS_TYPE_STRING, &new_owner,
73d4f2939cSRui Paulo 					   DBUS_TYPE_INVALID)) {
74d4f2939cSRui Paulo 			/* Ignore this error */
75d4f2939cSRui Paulo 			dbus_error_free(&derr);
76d4f2939cSRui Paulo 			return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
77d4f2939cSRui Paulo 		}
78d4f2939cSRui Paulo 
795b9c547cSRui Paulo 		for (wpa_s = priv->global->ifaces; wpa_s; wpa_s = wpa_s->next) {
80d4f2939cSRui Paulo 			if (wpa_s->preq_notify_peer != NULL &&
81d4f2939cSRui Paulo 			    os_strcmp(name, wpa_s->preq_notify_peer) == 0 &&
82d4f2939cSRui Paulo 			    (new_owner == NULL || os_strlen(new_owner) == 0)) {
83d4f2939cSRui Paulo 				/* probe request owner disconnected */
84d4f2939cSRui Paulo 				os_free(wpa_s->preq_notify_peer);
85d4f2939cSRui Paulo 				wpa_s->preq_notify_peer = NULL;
86d4f2939cSRui Paulo 				wpas_dbus_unsubscribe_noc(priv);
87d4f2939cSRui Paulo 			}
88d4f2939cSRui Paulo 		}
89d4f2939cSRui Paulo 	}
90d4f2939cSRui Paulo 
91d4f2939cSRui Paulo 	return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
92d4f2939cSRui Paulo }
93d4f2939cSRui Paulo 
94d4f2939cSRui Paulo 
95d4f2939cSRui Paulo void wpas_dbus_subscribe_noc(struct wpas_dbus_priv *priv)
96d4f2939cSRui Paulo {
97d4f2939cSRui Paulo 	priv->dbus_noc_refcnt++;
98d4f2939cSRui Paulo 	if (priv->dbus_noc_refcnt > 1)
99d4f2939cSRui Paulo 		return;
100d4f2939cSRui Paulo 
101d4f2939cSRui Paulo 	if (!dbus_connection_add_filter(priv->con, noc_filter, priv, NULL)) {
102d4f2939cSRui Paulo 		wpa_printf(MSG_ERROR, "dbus: failed to add filter");
103d4f2939cSRui Paulo 		return;
104d4f2939cSRui Paulo 	}
105d4f2939cSRui Paulo 
106d4f2939cSRui Paulo 	dbus_bus_add_match(priv->con, wpas_dbus_noc_filter_str, NULL);
107d4f2939cSRui Paulo }
108d4f2939cSRui Paulo 
109d4f2939cSRui Paulo 
110d4f2939cSRui Paulo void wpas_dbus_unsubscribe_noc(struct wpas_dbus_priv *priv)
111d4f2939cSRui Paulo {
112d4f2939cSRui Paulo 	priv->dbus_noc_refcnt--;
113d4f2939cSRui Paulo 	if (priv->dbus_noc_refcnt > 0)
114d4f2939cSRui Paulo 		return;
115d4f2939cSRui Paulo 
116d4f2939cSRui Paulo 	dbus_bus_remove_match(priv->con, wpas_dbus_noc_filter_str, NULL);
117d4f2939cSRui Paulo 	dbus_connection_remove_filter(priv->con, noc_filter, priv);
118d4f2939cSRui Paulo }
119d4f2939cSRui Paulo 
120d4f2939cSRui Paulo #endif /* CONFIG_AP */
121d4f2939cSRui Paulo 
122d4f2939cSRui Paulo 
123d4f2939cSRui Paulo /**
124d4f2939cSRui Paulo  * wpas_dbus_signal_interface - Send a interface related event signal
125d4f2939cSRui Paulo  * @wpa_s: %wpa_supplicant network interface data
126d4f2939cSRui Paulo  * @sig_name: signal name - InterfaceAdded or InterfaceRemoved
127d4f2939cSRui Paulo  * @properties: Whether to add second argument with object properties
128d4f2939cSRui Paulo  *
129d4f2939cSRui Paulo  * Notify listeners about event related with interface
130d4f2939cSRui Paulo  */
131d4f2939cSRui Paulo static void wpas_dbus_signal_interface(struct wpa_supplicant *wpa_s,
132*4bc52338SCy Schubert 				       const char *sig_name,
133*4bc52338SCy Schubert 				       dbus_bool_t properties)
134d4f2939cSRui Paulo {
135d4f2939cSRui Paulo 	struct wpas_dbus_priv *iface;
136d4f2939cSRui Paulo 	DBusMessage *msg;
137d4f2939cSRui Paulo 	DBusMessageIter iter;
138d4f2939cSRui Paulo 
139d4f2939cSRui Paulo 	iface = wpa_s->global->dbus;
140d4f2939cSRui Paulo 
141d4f2939cSRui Paulo 	/* Do nothing if the control interface is not turned on */
142325151a3SRui Paulo 	if (iface == NULL || !wpa_s->dbus_new_path)
143d4f2939cSRui Paulo 		return;
144d4f2939cSRui Paulo 
145d4f2939cSRui Paulo 	msg = dbus_message_new_signal(WPAS_DBUS_NEW_PATH,
146d4f2939cSRui Paulo 				      WPAS_DBUS_NEW_INTERFACE, sig_name);
147d4f2939cSRui Paulo 	if (msg == NULL)
148d4f2939cSRui Paulo 		return;
149d4f2939cSRui Paulo 
150d4f2939cSRui Paulo 	dbus_message_iter_init_append(msg, &iter);
151d4f2939cSRui Paulo 	if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_OBJECT_PATH,
1525b9c547cSRui Paulo 					    &wpa_s->dbus_new_path) ||
1535b9c547cSRui Paulo 	    (properties &&
1545b9c547cSRui Paulo 	     !wpa_dbus_get_object_properties(
155d4f2939cSRui Paulo 		     iface, wpa_s->dbus_new_path,
1565b9c547cSRui Paulo 		     WPAS_DBUS_NEW_IFACE_INTERFACE, &iter)))
157d4f2939cSRui Paulo 		wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
1585b9c547cSRui Paulo 	else
1595b9c547cSRui Paulo 		dbus_connection_send(iface->con, msg, NULL);
160d4f2939cSRui Paulo 	dbus_message_unref(msg);
161d4f2939cSRui Paulo }
162d4f2939cSRui Paulo 
163d4f2939cSRui Paulo 
164d4f2939cSRui Paulo /**
165d4f2939cSRui Paulo  * wpas_dbus_signal_interface_added - Send a interface created signal
166d4f2939cSRui Paulo  * @wpa_s: %wpa_supplicant network interface data
167d4f2939cSRui Paulo  *
168d4f2939cSRui Paulo  * Notify listeners about creating new interface
169d4f2939cSRui Paulo  */
170d4f2939cSRui Paulo static void wpas_dbus_signal_interface_added(struct wpa_supplicant *wpa_s)
171d4f2939cSRui Paulo {
172d4f2939cSRui Paulo 	wpas_dbus_signal_interface(wpa_s, "InterfaceAdded", TRUE);
173d4f2939cSRui Paulo }
174d4f2939cSRui Paulo 
175d4f2939cSRui Paulo 
176d4f2939cSRui Paulo /**
177d4f2939cSRui Paulo  * wpas_dbus_signal_interface_removed - Send a interface removed signal
178d4f2939cSRui Paulo  * @wpa_s: %wpa_supplicant network interface data
179d4f2939cSRui Paulo  *
180d4f2939cSRui Paulo  * Notify listeners about removing interface
181d4f2939cSRui Paulo  */
182d4f2939cSRui Paulo static void wpas_dbus_signal_interface_removed(struct wpa_supplicant *wpa_s)
183d4f2939cSRui Paulo {
184d4f2939cSRui Paulo 	wpas_dbus_signal_interface(wpa_s, "InterfaceRemoved", FALSE);
185d4f2939cSRui Paulo 
186d4f2939cSRui Paulo }
187d4f2939cSRui Paulo 
188d4f2939cSRui Paulo 
189d4f2939cSRui Paulo /**
190d4f2939cSRui Paulo  * wpas_dbus_signal_scan_done - send scan done signal
191d4f2939cSRui Paulo  * @wpa_s: %wpa_supplicant network interface data
192d4f2939cSRui Paulo  * @success: indicates if scanning succeed or failed
193d4f2939cSRui Paulo  *
194d4f2939cSRui Paulo  * Notify listeners about finishing a scan
195d4f2939cSRui Paulo  */
196d4f2939cSRui Paulo void wpas_dbus_signal_scan_done(struct wpa_supplicant *wpa_s, int success)
197d4f2939cSRui Paulo {
198d4f2939cSRui Paulo 	struct wpas_dbus_priv *iface;
199d4f2939cSRui Paulo 	DBusMessage *msg;
200d4f2939cSRui Paulo 	dbus_bool_t succ;
201d4f2939cSRui Paulo 
202d4f2939cSRui Paulo 	iface = wpa_s->global->dbus;
203d4f2939cSRui Paulo 
204d4f2939cSRui Paulo 	/* Do nothing if the control interface is not turned on */
205325151a3SRui Paulo 	if (iface == NULL || !wpa_s->dbus_new_path)
206d4f2939cSRui Paulo 		return;
207d4f2939cSRui Paulo 
208d4f2939cSRui Paulo 	msg = dbus_message_new_signal(wpa_s->dbus_new_path,
209d4f2939cSRui Paulo 				      WPAS_DBUS_NEW_IFACE_INTERFACE,
210d4f2939cSRui Paulo 				      "ScanDone");
211d4f2939cSRui Paulo 	if (msg == NULL)
212d4f2939cSRui Paulo 		return;
213d4f2939cSRui Paulo 
214d4f2939cSRui Paulo 	succ = success ? TRUE : FALSE;
215d4f2939cSRui Paulo 	if (dbus_message_append_args(msg, DBUS_TYPE_BOOLEAN, &succ,
216d4f2939cSRui Paulo 				     DBUS_TYPE_INVALID))
217d4f2939cSRui Paulo 		dbus_connection_send(iface->con, msg, NULL);
218d4f2939cSRui Paulo 	else
219d4f2939cSRui Paulo 		wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
220d4f2939cSRui Paulo 	dbus_message_unref(msg);
221d4f2939cSRui Paulo }
222d4f2939cSRui Paulo 
223d4f2939cSRui Paulo 
224d4f2939cSRui Paulo /**
2255b9c547cSRui Paulo  * wpas_dbus_signal_bss - Send a BSS related event signal
226d4f2939cSRui Paulo  * @wpa_s: %wpa_supplicant network interface data
227d4f2939cSRui Paulo  * @bss_obj_path: BSS object path
228d4f2939cSRui Paulo  * @sig_name: signal name - BSSAdded or BSSRemoved
229d4f2939cSRui Paulo  * @properties: Whether to add second argument with object properties
230d4f2939cSRui Paulo  *
231d4f2939cSRui Paulo  * Notify listeners about event related with BSS
232d4f2939cSRui Paulo  */
233d4f2939cSRui Paulo static void wpas_dbus_signal_bss(struct wpa_supplicant *wpa_s,
234d4f2939cSRui Paulo 				 const char *bss_obj_path,
235*4bc52338SCy Schubert 				 const char *sig_name, dbus_bool_t properties)
236d4f2939cSRui Paulo {
237d4f2939cSRui Paulo 	struct wpas_dbus_priv *iface;
238d4f2939cSRui Paulo 	DBusMessage *msg;
239d4f2939cSRui Paulo 	DBusMessageIter iter;
240d4f2939cSRui Paulo 
241d4f2939cSRui Paulo 	iface = wpa_s->global->dbus;
242d4f2939cSRui Paulo 
243d4f2939cSRui Paulo 	/* Do nothing if the control interface is not turned on */
244325151a3SRui Paulo 	if (iface == NULL || !wpa_s->dbus_new_path)
245d4f2939cSRui Paulo 		return;
246d4f2939cSRui Paulo 
247d4f2939cSRui Paulo 	msg = dbus_message_new_signal(wpa_s->dbus_new_path,
248d4f2939cSRui Paulo 				      WPAS_DBUS_NEW_IFACE_INTERFACE,
249d4f2939cSRui Paulo 				      sig_name);
250d4f2939cSRui Paulo 	if (msg == NULL)
251d4f2939cSRui Paulo 		return;
252d4f2939cSRui Paulo 
253d4f2939cSRui Paulo 	dbus_message_iter_init_append(msg, &iter);
254d4f2939cSRui Paulo 	if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_OBJECT_PATH,
2555b9c547cSRui Paulo 					    &bss_obj_path) ||
2565b9c547cSRui Paulo 	    (properties &&
2575b9c547cSRui Paulo 	     !wpa_dbus_get_object_properties(iface, bss_obj_path,
258d4f2939cSRui Paulo 					     WPAS_DBUS_NEW_IFACE_BSS,
2595b9c547cSRui Paulo 					     &iter)))
260d4f2939cSRui Paulo 		wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
2615b9c547cSRui Paulo 	else
2625b9c547cSRui Paulo 		dbus_connection_send(iface->con, msg, NULL);
263d4f2939cSRui Paulo 	dbus_message_unref(msg);
264d4f2939cSRui Paulo }
265d4f2939cSRui Paulo 
266d4f2939cSRui Paulo 
267d4f2939cSRui Paulo /**
268d4f2939cSRui Paulo  * wpas_dbus_signal_bss_added - Send a BSS added signal
269d4f2939cSRui Paulo  * @wpa_s: %wpa_supplicant network interface data
270d4f2939cSRui Paulo  * @bss_obj_path: new BSS object path
271d4f2939cSRui Paulo  *
272d4f2939cSRui Paulo  * Notify listeners about adding new BSS
273d4f2939cSRui Paulo  */
274d4f2939cSRui Paulo static void wpas_dbus_signal_bss_added(struct wpa_supplicant *wpa_s,
275d4f2939cSRui Paulo 				       const char *bss_obj_path)
276d4f2939cSRui Paulo {
277d4f2939cSRui Paulo 	wpas_dbus_signal_bss(wpa_s, bss_obj_path, "BSSAdded", TRUE);
278d4f2939cSRui Paulo }
279d4f2939cSRui Paulo 
280d4f2939cSRui Paulo 
281d4f2939cSRui Paulo /**
282d4f2939cSRui Paulo  * wpas_dbus_signal_bss_removed - Send a BSS removed signal
283d4f2939cSRui Paulo  * @wpa_s: %wpa_supplicant network interface data
284d4f2939cSRui Paulo  * @bss_obj_path: BSS object path
285d4f2939cSRui Paulo  *
286d4f2939cSRui Paulo  * Notify listeners about removing BSS
287d4f2939cSRui Paulo  */
288d4f2939cSRui Paulo static void wpas_dbus_signal_bss_removed(struct wpa_supplicant *wpa_s,
289d4f2939cSRui Paulo 					 const char *bss_obj_path)
290d4f2939cSRui Paulo {
291d4f2939cSRui Paulo 	wpas_dbus_signal_bss(wpa_s, bss_obj_path, "BSSRemoved", FALSE);
292d4f2939cSRui Paulo }
293d4f2939cSRui Paulo 
294d4f2939cSRui Paulo 
295d4f2939cSRui Paulo /**
296d4f2939cSRui Paulo  * wpas_dbus_signal_blob - Send a blob related event signal
297d4f2939cSRui Paulo  * @wpa_s: %wpa_supplicant network interface data
298d4f2939cSRui Paulo  * @name: blob name
299d4f2939cSRui Paulo  * @sig_name: signal name - BlobAdded or BlobRemoved
300d4f2939cSRui Paulo  *
301d4f2939cSRui Paulo  * Notify listeners about event related with blob
302d4f2939cSRui Paulo  */
303d4f2939cSRui Paulo static void wpas_dbus_signal_blob(struct wpa_supplicant *wpa_s,
304d4f2939cSRui Paulo 				  const char *name, const char *sig_name)
305d4f2939cSRui Paulo {
306d4f2939cSRui Paulo 	struct wpas_dbus_priv *iface;
307d4f2939cSRui Paulo 	DBusMessage *msg;
308d4f2939cSRui Paulo 
309d4f2939cSRui Paulo 	iface = wpa_s->global->dbus;
310d4f2939cSRui Paulo 
311d4f2939cSRui Paulo 	/* Do nothing if the control interface is not turned on */
312325151a3SRui Paulo 	if (iface == NULL || !wpa_s->dbus_new_path)
313d4f2939cSRui Paulo 		return;
314d4f2939cSRui Paulo 
315d4f2939cSRui Paulo 	msg = dbus_message_new_signal(wpa_s->dbus_new_path,
316d4f2939cSRui Paulo 				      WPAS_DBUS_NEW_IFACE_INTERFACE,
317d4f2939cSRui Paulo 				      sig_name);
318d4f2939cSRui Paulo 	if (msg == NULL)
319d4f2939cSRui Paulo 		return;
320d4f2939cSRui Paulo 
321d4f2939cSRui Paulo 	if (dbus_message_append_args(msg, DBUS_TYPE_STRING, &name,
322d4f2939cSRui Paulo 				     DBUS_TYPE_INVALID))
323d4f2939cSRui Paulo 		dbus_connection_send(iface->con, msg, NULL);
324d4f2939cSRui Paulo 	else
325d4f2939cSRui Paulo 		wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
326d4f2939cSRui Paulo 	dbus_message_unref(msg);
327d4f2939cSRui Paulo }
328d4f2939cSRui Paulo 
329d4f2939cSRui Paulo 
330d4f2939cSRui Paulo /**
331d4f2939cSRui Paulo  * wpas_dbus_signal_blob_added - Send a blob added signal
332d4f2939cSRui Paulo  * @wpa_s: %wpa_supplicant network interface data
333d4f2939cSRui Paulo  * @name: blob name
334d4f2939cSRui Paulo  *
335d4f2939cSRui Paulo  * Notify listeners about adding a new blob
336d4f2939cSRui Paulo  */
337d4f2939cSRui Paulo void wpas_dbus_signal_blob_added(struct wpa_supplicant *wpa_s,
338d4f2939cSRui Paulo 				 const char *name)
339d4f2939cSRui Paulo {
340d4f2939cSRui Paulo 	wpas_dbus_signal_blob(wpa_s, name, "BlobAdded");
341d4f2939cSRui Paulo }
342d4f2939cSRui Paulo 
343d4f2939cSRui Paulo 
344d4f2939cSRui Paulo /**
345d4f2939cSRui Paulo  * wpas_dbus_signal_blob_removed - Send a blob removed signal
346d4f2939cSRui Paulo  * @wpa_s: %wpa_supplicant network interface data
347d4f2939cSRui Paulo  * @name: blob name
348d4f2939cSRui Paulo  *
349d4f2939cSRui Paulo  * Notify listeners about removing blob
350d4f2939cSRui Paulo  */
351d4f2939cSRui Paulo void wpas_dbus_signal_blob_removed(struct wpa_supplicant *wpa_s,
352d4f2939cSRui Paulo 				   const char *name)
353d4f2939cSRui Paulo {
354d4f2939cSRui Paulo 	wpas_dbus_signal_blob(wpa_s, name, "BlobRemoved");
355d4f2939cSRui Paulo }
356d4f2939cSRui Paulo 
357d4f2939cSRui Paulo 
358d4f2939cSRui Paulo /**
359d4f2939cSRui Paulo  * wpas_dbus_signal_network - Send a network related event signal
360d4f2939cSRui Paulo  * @wpa_s: %wpa_supplicant network interface data
361d4f2939cSRui Paulo  * @id: new network id
362d4f2939cSRui Paulo  * @sig_name: signal name - NetworkAdded, NetworkRemoved or NetworkSelected
363d4f2939cSRui Paulo  * @properties: determines if add second argument with object properties
364d4f2939cSRui Paulo  *
365d4f2939cSRui Paulo  * Notify listeners about event related with configured network
366d4f2939cSRui Paulo  */
367d4f2939cSRui Paulo static void wpas_dbus_signal_network(struct wpa_supplicant *wpa_s,
368d4f2939cSRui Paulo 				     int id, const char *sig_name,
369*4bc52338SCy Schubert 				     dbus_bool_t properties)
370d4f2939cSRui Paulo {
371d4f2939cSRui Paulo 	struct wpas_dbus_priv *iface;
372d4f2939cSRui Paulo 	DBusMessage *msg;
373d4f2939cSRui Paulo 	DBusMessageIter iter;
374d4f2939cSRui Paulo 	char net_obj_path[WPAS_DBUS_OBJECT_PATH_MAX], *path;
375d4f2939cSRui Paulo 
376d4f2939cSRui Paulo 	iface = wpa_s->global->dbus;
377d4f2939cSRui Paulo 
378d4f2939cSRui Paulo 	/* Do nothing if the control interface is not turned on */
379325151a3SRui Paulo 	if (iface == NULL || !wpa_s->dbus_new_path)
380d4f2939cSRui Paulo 		return;
381d4f2939cSRui Paulo 
382d4f2939cSRui Paulo 	os_snprintf(net_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
383d4f2939cSRui Paulo 		    "%s/" WPAS_DBUS_NEW_NETWORKS_PART "/%u",
384d4f2939cSRui Paulo 		    wpa_s->dbus_new_path, id);
385d4f2939cSRui Paulo 
386d4f2939cSRui Paulo 	msg = dbus_message_new_signal(wpa_s->dbus_new_path,
387d4f2939cSRui Paulo 				      WPAS_DBUS_NEW_IFACE_INTERFACE,
388d4f2939cSRui Paulo 				      sig_name);
389d4f2939cSRui Paulo 	if (msg == NULL)
390d4f2939cSRui Paulo 		return;
391d4f2939cSRui Paulo 
392d4f2939cSRui Paulo 	dbus_message_iter_init_append(msg, &iter);
393d4f2939cSRui Paulo 	path = net_obj_path;
394d4f2939cSRui Paulo 	if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_OBJECT_PATH,
3955b9c547cSRui Paulo 					    &path) ||
3965b9c547cSRui Paulo 	    (properties &&
3975b9c547cSRui Paulo 	     !wpa_dbus_get_object_properties(
398d4f2939cSRui Paulo 		     iface, net_obj_path, WPAS_DBUS_NEW_IFACE_NETWORK,
3995b9c547cSRui Paulo 		     &iter)))
400d4f2939cSRui Paulo 		wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
4015b9c547cSRui Paulo 	else
4025b9c547cSRui Paulo 		dbus_connection_send(iface->con, msg, NULL);
403d4f2939cSRui Paulo 	dbus_message_unref(msg);
404d4f2939cSRui Paulo }
405d4f2939cSRui Paulo 
406d4f2939cSRui Paulo 
407d4f2939cSRui Paulo /**
408d4f2939cSRui Paulo  * wpas_dbus_signal_network_added - Send a network added signal
409d4f2939cSRui Paulo  * @wpa_s: %wpa_supplicant network interface data
410d4f2939cSRui Paulo  * @id: new network id
411d4f2939cSRui Paulo  *
412d4f2939cSRui Paulo  * Notify listeners about adding new network
413d4f2939cSRui Paulo  */
414d4f2939cSRui Paulo static void wpas_dbus_signal_network_added(struct wpa_supplicant *wpa_s,
415d4f2939cSRui Paulo 					   int id)
416d4f2939cSRui Paulo {
417d4f2939cSRui Paulo 	wpas_dbus_signal_network(wpa_s, id, "NetworkAdded", TRUE);
418d4f2939cSRui Paulo }
419d4f2939cSRui Paulo 
420d4f2939cSRui Paulo 
421d4f2939cSRui Paulo /**
422d4f2939cSRui Paulo  * wpas_dbus_signal_network_removed - Send a network removed signal
423d4f2939cSRui Paulo  * @wpa_s: %wpa_supplicant network interface data
424d4f2939cSRui Paulo  * @id: network id
425d4f2939cSRui Paulo  *
426d4f2939cSRui Paulo  * Notify listeners about removing a network
427d4f2939cSRui Paulo  */
428d4f2939cSRui Paulo static void wpas_dbus_signal_network_removed(struct wpa_supplicant *wpa_s,
429d4f2939cSRui Paulo 					     int id)
430d4f2939cSRui Paulo {
431d4f2939cSRui Paulo 	wpas_dbus_signal_network(wpa_s, id, "NetworkRemoved", FALSE);
432d4f2939cSRui Paulo }
433d4f2939cSRui Paulo 
434d4f2939cSRui Paulo 
435d4f2939cSRui Paulo /**
436d4f2939cSRui Paulo  * wpas_dbus_signal_network_selected - Send a network selected signal
437d4f2939cSRui Paulo  * @wpa_s: %wpa_supplicant network interface data
438d4f2939cSRui Paulo  * @id: network id
439d4f2939cSRui Paulo  *
440d4f2939cSRui Paulo  * Notify listeners about selecting a network
441d4f2939cSRui Paulo  */
442d4f2939cSRui Paulo void wpas_dbus_signal_network_selected(struct wpa_supplicant *wpa_s, int id)
443d4f2939cSRui Paulo {
444d4f2939cSRui Paulo 	wpas_dbus_signal_network(wpa_s, id, "NetworkSelected", FALSE);
445d4f2939cSRui Paulo }
446d4f2939cSRui Paulo 
447d4f2939cSRui Paulo 
448d4f2939cSRui Paulo /**
449d4f2939cSRui Paulo  * wpas_dbus_signal_network_request - Indicate that additional information
450d4f2939cSRui Paulo  * (EAP password, etc.) is required to complete the association to this SSID
451d4f2939cSRui Paulo  * @wpa_s: %wpa_supplicant network interface data
452d4f2939cSRui Paulo  * @rtype: The specific additional information required
453d4f2939cSRui Paulo  * @default_text: Optional description of required information
454d4f2939cSRui Paulo  *
455d4f2939cSRui Paulo  * Request additional information or passwords to complete an association
456d4f2939cSRui Paulo  * request.
457d4f2939cSRui Paulo  */
458d4f2939cSRui Paulo void wpas_dbus_signal_network_request(struct wpa_supplicant *wpa_s,
459d4f2939cSRui Paulo 				      struct wpa_ssid *ssid,
460d4f2939cSRui Paulo 				      enum wpa_ctrl_req_type rtype,
461d4f2939cSRui Paulo 				      const char *default_txt)
462d4f2939cSRui Paulo {
463d4f2939cSRui Paulo 	struct wpas_dbus_priv *iface;
464d4f2939cSRui Paulo 	DBusMessage *msg;
465d4f2939cSRui Paulo 	DBusMessageIter iter;
466d4f2939cSRui Paulo 	char net_obj_path[WPAS_DBUS_OBJECT_PATH_MAX];
467d4f2939cSRui Paulo 	const char *field, *txt = NULL, *net_ptr;
468d4f2939cSRui Paulo 
469d4f2939cSRui Paulo 	iface = wpa_s->global->dbus;
470d4f2939cSRui Paulo 
471d4f2939cSRui Paulo 	/* Do nothing if the control interface is not turned on */
472325151a3SRui Paulo 	if (iface == NULL || !wpa_s->dbus_new_path)
473d4f2939cSRui Paulo 		return;
474d4f2939cSRui Paulo 
475d4f2939cSRui Paulo 	field = wpa_supplicant_ctrl_req_to_string(rtype, default_txt, &txt);
476d4f2939cSRui Paulo 	if (field == NULL)
477d4f2939cSRui Paulo 		return;
478d4f2939cSRui Paulo 
479d4f2939cSRui Paulo 	msg = dbus_message_new_signal(wpa_s->dbus_new_path,
480d4f2939cSRui Paulo 				      WPAS_DBUS_NEW_IFACE_INTERFACE,
481d4f2939cSRui Paulo 				      "NetworkRequest");
482d4f2939cSRui Paulo 	if (msg == NULL)
483d4f2939cSRui Paulo 		return;
484d4f2939cSRui Paulo 
485d4f2939cSRui Paulo 	os_snprintf(net_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
486d4f2939cSRui Paulo 		    "%s/" WPAS_DBUS_NEW_NETWORKS_PART "/%u",
487d4f2939cSRui Paulo 		    wpa_s->dbus_new_path, ssid->id);
488d4f2939cSRui Paulo 	net_ptr = &net_obj_path[0];
489d4f2939cSRui Paulo 
490d4f2939cSRui Paulo 	dbus_message_iter_init_append(msg, &iter);
491d4f2939cSRui Paulo 	if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_OBJECT_PATH,
4925b9c547cSRui Paulo 					    &net_ptr) ||
4935b9c547cSRui Paulo 	    !dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &field) ||
4945b9c547cSRui Paulo 	    !dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &txt))
495d4f2939cSRui Paulo 		wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
4965b9c547cSRui Paulo 	else
4975b9c547cSRui Paulo 		dbus_connection_send(iface->con, msg, NULL);
498d4f2939cSRui Paulo 	dbus_message_unref(msg);
499d4f2939cSRui Paulo }
500d4f2939cSRui Paulo 
501d4f2939cSRui Paulo 
502d4f2939cSRui Paulo /**
503d4f2939cSRui Paulo  * wpas_dbus_signal_network_enabled_changed - Signals Enabled property changes
504d4f2939cSRui Paulo  * @wpa_s: %wpa_supplicant network interface data
505d4f2939cSRui Paulo  * @ssid: configured network which Enabled property has changed
506d4f2939cSRui Paulo  *
507d4f2939cSRui Paulo  * Sends PropertyChanged signals containing new value of Enabled property
508d4f2939cSRui Paulo  * for specified network
509d4f2939cSRui Paulo  */
510d4f2939cSRui Paulo void wpas_dbus_signal_network_enabled_changed(struct wpa_supplicant *wpa_s,
511d4f2939cSRui Paulo 					      struct wpa_ssid *ssid)
512d4f2939cSRui Paulo {
513d4f2939cSRui Paulo 
514d4f2939cSRui Paulo 	char path[WPAS_DBUS_OBJECT_PATH_MAX];
5155b9c547cSRui Paulo 
516325151a3SRui Paulo 	if (!wpa_s->dbus_new_path)
517325151a3SRui Paulo 		return;
518d4f2939cSRui Paulo 	os_snprintf(path, WPAS_DBUS_OBJECT_PATH_MAX,
519d4f2939cSRui Paulo 		    "%s/" WPAS_DBUS_NEW_NETWORKS_PART "/%d",
520d4f2939cSRui Paulo 		    wpa_s->dbus_new_path, ssid->id);
521d4f2939cSRui Paulo 
522d4f2939cSRui Paulo 	wpa_dbus_mark_property_changed(wpa_s->global->dbus, path,
523d4f2939cSRui Paulo 				       WPAS_DBUS_NEW_IFACE_NETWORK, "Enabled");
524d4f2939cSRui Paulo }
525d4f2939cSRui Paulo 
526d4f2939cSRui Paulo 
527d4f2939cSRui Paulo #ifdef CONFIG_WPS
528d4f2939cSRui Paulo 
529d4f2939cSRui Paulo /**
530325151a3SRui Paulo  * wpas_dbus_signal_wps_event_pbc_overlap - Signals PBC overlap WPS event
531325151a3SRui Paulo  * @wpa_s: %wpa_supplicant network interface data
532325151a3SRui Paulo  *
533325151a3SRui Paulo  * Sends Event dbus signal with name "pbc-overlap" and empty dict as arguments
534325151a3SRui Paulo  */
535325151a3SRui Paulo void wpas_dbus_signal_wps_event_pbc_overlap(struct wpa_supplicant *wpa_s)
536325151a3SRui Paulo {
537325151a3SRui Paulo 
538325151a3SRui Paulo 	DBusMessage *msg;
539325151a3SRui Paulo 	DBusMessageIter iter, dict_iter;
540325151a3SRui Paulo 	struct wpas_dbus_priv *iface;
541325151a3SRui Paulo 	char *key = "pbc-overlap";
542325151a3SRui Paulo 
543325151a3SRui Paulo 	iface = wpa_s->global->dbus;
544325151a3SRui Paulo 
545325151a3SRui Paulo 	/* Do nothing if the control interface is not turned on */
546325151a3SRui Paulo 	if (iface == NULL || !wpa_s->dbus_new_path)
547325151a3SRui Paulo 		return;
548325151a3SRui Paulo 
549325151a3SRui Paulo 	msg = dbus_message_new_signal(wpa_s->dbus_new_path,
550325151a3SRui Paulo 				      WPAS_DBUS_NEW_IFACE_WPS, "Event");
551325151a3SRui Paulo 	if (msg == NULL)
552325151a3SRui Paulo 		return;
553325151a3SRui Paulo 
554325151a3SRui Paulo 	dbus_message_iter_init_append(msg, &iter);
555325151a3SRui Paulo 
556325151a3SRui Paulo 	if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &key) ||
557325151a3SRui Paulo 	    !wpa_dbus_dict_open_write(&iter, &dict_iter) ||
558325151a3SRui Paulo 	    !wpa_dbus_dict_close_write(&iter, &dict_iter))
559325151a3SRui Paulo 		wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
560325151a3SRui Paulo 	else
561325151a3SRui Paulo 		dbus_connection_send(iface->con, msg, NULL);
562325151a3SRui Paulo 
563325151a3SRui Paulo 	dbus_message_unref(msg);
564325151a3SRui Paulo }
565325151a3SRui Paulo 
566325151a3SRui Paulo 
567325151a3SRui Paulo /**
568d4f2939cSRui Paulo  * wpas_dbus_signal_wps_event_success - Signals Success WPS event
569d4f2939cSRui Paulo  * @wpa_s: %wpa_supplicant network interface data
570d4f2939cSRui Paulo  *
571d4f2939cSRui Paulo  * Sends Event dbus signal with name "success" and empty dict as arguments
572d4f2939cSRui Paulo  */
573d4f2939cSRui Paulo void wpas_dbus_signal_wps_event_success(struct wpa_supplicant *wpa_s)
574d4f2939cSRui Paulo {
575d4f2939cSRui Paulo 
576d4f2939cSRui Paulo 	DBusMessage *msg;
577d4f2939cSRui Paulo 	DBusMessageIter iter, dict_iter;
578d4f2939cSRui Paulo 	struct wpas_dbus_priv *iface;
579d4f2939cSRui Paulo 	char *key = "success";
580d4f2939cSRui Paulo 
581d4f2939cSRui Paulo 	iface = wpa_s->global->dbus;
582d4f2939cSRui Paulo 
583d4f2939cSRui Paulo 	/* Do nothing if the control interface is not turned on */
584325151a3SRui Paulo 	if (iface == NULL || !wpa_s->dbus_new_path)
585d4f2939cSRui Paulo 		return;
586d4f2939cSRui Paulo 
587d4f2939cSRui Paulo 	msg = dbus_message_new_signal(wpa_s->dbus_new_path,
588d4f2939cSRui Paulo 				      WPAS_DBUS_NEW_IFACE_WPS, "Event");
589d4f2939cSRui Paulo 	if (msg == NULL)
590d4f2939cSRui Paulo 		return;
591d4f2939cSRui Paulo 
592d4f2939cSRui Paulo 	dbus_message_iter_init_append(msg, &iter);
593d4f2939cSRui Paulo 
594d4f2939cSRui Paulo 	if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &key) ||
595d4f2939cSRui Paulo 	    !wpa_dbus_dict_open_write(&iter, &dict_iter) ||
596d4f2939cSRui Paulo 	    !wpa_dbus_dict_close_write(&iter, &dict_iter))
597d4f2939cSRui Paulo 		wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
598d4f2939cSRui Paulo 	else
599d4f2939cSRui Paulo 		dbus_connection_send(iface->con, msg, NULL);
600d4f2939cSRui Paulo 
601d4f2939cSRui Paulo 	dbus_message_unref(msg);
602d4f2939cSRui Paulo }
603d4f2939cSRui Paulo 
604d4f2939cSRui Paulo 
605d4f2939cSRui Paulo /**
606d4f2939cSRui Paulo  * wpas_dbus_signal_wps_event_fail - Signals Fail WPS event
607d4f2939cSRui Paulo  * @wpa_s: %wpa_supplicant network interface data
608325151a3SRui Paulo  * @fail: WPS failure information
609d4f2939cSRui Paulo  *
610d4f2939cSRui Paulo  * Sends Event dbus signal with name "fail" and dictionary containing
611d4f2939cSRui Paulo  * "msg field with fail message number (int32) as arguments
612d4f2939cSRui Paulo  */
613d4f2939cSRui Paulo void wpas_dbus_signal_wps_event_fail(struct wpa_supplicant *wpa_s,
614d4f2939cSRui Paulo 				     struct wps_event_fail *fail)
615d4f2939cSRui Paulo {
616d4f2939cSRui Paulo 
617d4f2939cSRui Paulo 	DBusMessage *msg;
618d4f2939cSRui Paulo 	DBusMessageIter iter, dict_iter;
619d4f2939cSRui Paulo 	struct wpas_dbus_priv *iface;
620d4f2939cSRui Paulo 	char *key = "fail";
621d4f2939cSRui Paulo 
622d4f2939cSRui Paulo 	iface = wpa_s->global->dbus;
623d4f2939cSRui Paulo 
624d4f2939cSRui Paulo 	/* Do nothing if the control interface is not turned on */
625325151a3SRui Paulo 	if (iface == NULL || !wpa_s->dbus_new_path)
626d4f2939cSRui Paulo 		return;
627d4f2939cSRui Paulo 
628d4f2939cSRui Paulo 	msg = dbus_message_new_signal(wpa_s->dbus_new_path,
629d4f2939cSRui Paulo 				      WPAS_DBUS_NEW_IFACE_WPS, "Event");
630d4f2939cSRui Paulo 	if (msg == NULL)
631d4f2939cSRui Paulo 		return;
632d4f2939cSRui Paulo 
633d4f2939cSRui Paulo 	dbus_message_iter_init_append(msg, &iter);
634d4f2939cSRui Paulo 
635d4f2939cSRui Paulo 	if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &key) ||
636d4f2939cSRui Paulo 	    !wpa_dbus_dict_open_write(&iter, &dict_iter) ||
637d4f2939cSRui Paulo 	    !wpa_dbus_dict_append_int32(&dict_iter, "msg", fail->msg) ||
638325151a3SRui Paulo 	    !wpa_dbus_dict_append_int32(&dict_iter, "config_error",
639325151a3SRui Paulo 					fail->config_error) ||
640325151a3SRui Paulo 	    !wpa_dbus_dict_append_int32(&dict_iter, "error_indication",
641325151a3SRui Paulo 					fail->error_indication) ||
642d4f2939cSRui Paulo 	    !wpa_dbus_dict_close_write(&iter, &dict_iter))
643d4f2939cSRui Paulo 		wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
644d4f2939cSRui Paulo 	else
645d4f2939cSRui Paulo 		dbus_connection_send(iface->con, msg, NULL);
646d4f2939cSRui Paulo 
647d4f2939cSRui Paulo 	dbus_message_unref(msg);
648d4f2939cSRui Paulo }
649d4f2939cSRui Paulo 
650d4f2939cSRui Paulo 
651d4f2939cSRui Paulo /**
652d4f2939cSRui Paulo  * wpas_dbus_signal_wps_event_m2d - Signals M2D WPS event
653d4f2939cSRui Paulo  * @wpa_s: %wpa_supplicant network interface data
654325151a3SRui Paulo  * @m2d: M2D event data information
655d4f2939cSRui Paulo  *
656d4f2939cSRui Paulo  * Sends Event dbus signal with name "m2d" and dictionary containing
657d4f2939cSRui Paulo  * fields of wps_event_m2d structure.
658d4f2939cSRui Paulo  */
659d4f2939cSRui Paulo void wpas_dbus_signal_wps_event_m2d(struct wpa_supplicant *wpa_s,
660d4f2939cSRui Paulo 				    struct wps_event_m2d *m2d)
661d4f2939cSRui Paulo {
662d4f2939cSRui Paulo 
663d4f2939cSRui Paulo 	DBusMessage *msg;
664d4f2939cSRui Paulo 	DBusMessageIter iter, dict_iter;
665d4f2939cSRui Paulo 	struct wpas_dbus_priv *iface;
666d4f2939cSRui Paulo 	char *key = "m2d";
667d4f2939cSRui Paulo 
668d4f2939cSRui Paulo 	iface = wpa_s->global->dbus;
669d4f2939cSRui Paulo 
670d4f2939cSRui Paulo 	/* Do nothing if the control interface is not turned on */
671325151a3SRui Paulo 	if (iface == NULL || !wpa_s->dbus_new_path)
672d4f2939cSRui Paulo 		return;
673d4f2939cSRui Paulo 
674d4f2939cSRui Paulo 	msg = dbus_message_new_signal(wpa_s->dbus_new_path,
675d4f2939cSRui Paulo 				      WPAS_DBUS_NEW_IFACE_WPS, "Event");
676d4f2939cSRui Paulo 	if (msg == NULL)
677d4f2939cSRui Paulo 		return;
678d4f2939cSRui Paulo 
679d4f2939cSRui Paulo 	dbus_message_iter_init_append(msg, &iter);
680d4f2939cSRui Paulo 
681d4f2939cSRui Paulo 	if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &key) ||
682d4f2939cSRui Paulo 	    !wpa_dbus_dict_open_write(&iter, &dict_iter) ||
683d4f2939cSRui Paulo 	    !wpa_dbus_dict_append_uint16(&dict_iter, "config_methods",
684d4f2939cSRui Paulo 					 m2d->config_methods) ||
685d4f2939cSRui Paulo 	    !wpa_dbus_dict_append_byte_array(&dict_iter, "manufacturer",
686d4f2939cSRui Paulo 					     (const char *) m2d->manufacturer,
687d4f2939cSRui Paulo 					     m2d->manufacturer_len) ||
688d4f2939cSRui Paulo 	    !wpa_dbus_dict_append_byte_array(&dict_iter, "model_name",
689d4f2939cSRui Paulo 					     (const char *) m2d->model_name,
690d4f2939cSRui Paulo 					     m2d->model_name_len) ||
691d4f2939cSRui Paulo 	    !wpa_dbus_dict_append_byte_array(&dict_iter, "model_number",
692d4f2939cSRui Paulo 					     (const char *) m2d->model_number,
693d4f2939cSRui Paulo 					     m2d->model_number_len) ||
694d4f2939cSRui Paulo 	    !wpa_dbus_dict_append_byte_array(&dict_iter, "serial_number",
695d4f2939cSRui Paulo 					     (const char *)
696d4f2939cSRui Paulo 					     m2d->serial_number,
697d4f2939cSRui Paulo 					     m2d->serial_number_len) ||
698d4f2939cSRui Paulo 	    !wpa_dbus_dict_append_byte_array(&dict_iter, "dev_name",
699d4f2939cSRui Paulo 					     (const char *) m2d->dev_name,
700d4f2939cSRui Paulo 					     m2d->dev_name_len) ||
701d4f2939cSRui Paulo 	    !wpa_dbus_dict_append_byte_array(&dict_iter, "primary_dev_type",
702d4f2939cSRui Paulo 					     (const char *)
703d4f2939cSRui Paulo 					     m2d->primary_dev_type, 8) ||
704d4f2939cSRui Paulo 	    !wpa_dbus_dict_append_uint16(&dict_iter, "config_error",
705d4f2939cSRui Paulo 					 m2d->config_error) ||
706d4f2939cSRui Paulo 	    !wpa_dbus_dict_append_uint16(&dict_iter, "dev_password_id",
707d4f2939cSRui Paulo 					 m2d->dev_password_id) ||
708d4f2939cSRui Paulo 	    !wpa_dbus_dict_close_write(&iter, &dict_iter))
709d4f2939cSRui Paulo 		wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
710d4f2939cSRui Paulo 	else
711d4f2939cSRui Paulo 		dbus_connection_send(iface->con, msg, NULL);
712d4f2939cSRui Paulo 
713d4f2939cSRui Paulo 	dbus_message_unref(msg);
714d4f2939cSRui Paulo }
715d4f2939cSRui Paulo 
716d4f2939cSRui Paulo 
717d4f2939cSRui Paulo /**
718d4f2939cSRui Paulo  * wpas_dbus_signal_wps_cred - Signals new credentials
719d4f2939cSRui Paulo  * @wpa_s: %wpa_supplicant network interface data
720325151a3SRui Paulo  * @cred: WPS Credential information
721d4f2939cSRui Paulo  *
722d4f2939cSRui Paulo  * Sends signal with credentials in directory argument
723d4f2939cSRui Paulo  */
724d4f2939cSRui Paulo void wpas_dbus_signal_wps_cred(struct wpa_supplicant *wpa_s,
725d4f2939cSRui Paulo 			       const struct wps_credential *cred)
726d4f2939cSRui Paulo {
727d4f2939cSRui Paulo 	DBusMessage *msg;
728d4f2939cSRui Paulo 	DBusMessageIter iter, dict_iter;
729d4f2939cSRui Paulo 	struct wpas_dbus_priv *iface;
7305b9c547cSRui Paulo 	char *auth_type[5]; /* we have five possible authentication types */
731d4f2939cSRui Paulo 	int at_num = 0;
7325b9c547cSRui Paulo 	char *encr_type[3]; /* we have three possible encryption types */
733d4f2939cSRui Paulo 	int et_num = 0;
734d4f2939cSRui Paulo 
735d4f2939cSRui Paulo 	iface = wpa_s->global->dbus;
736d4f2939cSRui Paulo 
737d4f2939cSRui Paulo 	/* Do nothing if the control interface is not turned on */
738325151a3SRui Paulo 	if (iface == NULL || !wpa_s->dbus_new_path)
739d4f2939cSRui Paulo 		return;
740d4f2939cSRui Paulo 
741d4f2939cSRui Paulo 	msg = dbus_message_new_signal(wpa_s->dbus_new_path,
742d4f2939cSRui Paulo 				      WPAS_DBUS_NEW_IFACE_WPS,
743d4f2939cSRui Paulo 				      "Credentials");
744d4f2939cSRui Paulo 	if (msg == NULL)
745d4f2939cSRui Paulo 		return;
746d4f2939cSRui Paulo 
747d4f2939cSRui Paulo 	dbus_message_iter_init_append(msg, &iter);
748d4f2939cSRui Paulo 	if (!wpa_dbus_dict_open_write(&iter, &dict_iter))
749d4f2939cSRui Paulo 		goto nomem;
750d4f2939cSRui Paulo 
751d4f2939cSRui Paulo 	if (cred->auth_type & WPS_AUTH_OPEN)
752d4f2939cSRui Paulo 		auth_type[at_num++] = "open";
753d4f2939cSRui Paulo 	if (cred->auth_type & WPS_AUTH_WPAPSK)
754d4f2939cSRui Paulo 		auth_type[at_num++] = "wpa-psk";
755d4f2939cSRui Paulo 	if (cred->auth_type & WPS_AUTH_WPA)
756d4f2939cSRui Paulo 		auth_type[at_num++] = "wpa-eap";
757d4f2939cSRui Paulo 	if (cred->auth_type & WPS_AUTH_WPA2)
758d4f2939cSRui Paulo 		auth_type[at_num++] = "wpa2-eap";
759d4f2939cSRui Paulo 	if (cred->auth_type & WPS_AUTH_WPA2PSK)
7605b9c547cSRui Paulo 		auth_type[at_num++] = "wpa2-psk";
761d4f2939cSRui Paulo 
762d4f2939cSRui Paulo 	if (cred->encr_type & WPS_ENCR_NONE)
763d4f2939cSRui Paulo 		encr_type[et_num++] = "none";
764d4f2939cSRui Paulo 	if (cred->encr_type & WPS_ENCR_TKIP)
765d4f2939cSRui Paulo 		encr_type[et_num++] = "tkip";
766d4f2939cSRui Paulo 	if (cred->encr_type & WPS_ENCR_AES)
767d4f2939cSRui Paulo 		encr_type[et_num++] = "aes";
768d4f2939cSRui Paulo 
7695b9c547cSRui Paulo 	if ((wpa_s->current_ssid &&
7705b9c547cSRui Paulo 	     !wpa_dbus_dict_append_byte_array(
771d4f2939cSRui Paulo 		     &dict_iter, "BSSID",
7725b9c547cSRui Paulo 		     (const char *) wpa_s->current_ssid->bssid, ETH_ALEN)) ||
7735b9c547cSRui Paulo 	    !wpa_dbus_dict_append_byte_array(&dict_iter, "SSID",
774d4f2939cSRui Paulo 					     (const char *) cred->ssid,
775d4f2939cSRui Paulo 					     cred->ssid_len) ||
776d4f2939cSRui Paulo 	    !wpa_dbus_dict_append_string_array(&dict_iter, "AuthType",
777d4f2939cSRui Paulo 					       (const char **) auth_type,
778d4f2939cSRui Paulo 					       at_num) ||
779d4f2939cSRui Paulo 	    !wpa_dbus_dict_append_string_array(&dict_iter, "EncrType",
780d4f2939cSRui Paulo 					       (const char **) encr_type,
781d4f2939cSRui Paulo 					       et_num) ||
782d4f2939cSRui Paulo 	    !wpa_dbus_dict_append_byte_array(&dict_iter, "Key",
783d4f2939cSRui Paulo 					     (const char *) cred->key,
784d4f2939cSRui Paulo 					     cred->key_len) ||
785d4f2939cSRui Paulo 	    !wpa_dbus_dict_append_uint32(&dict_iter, "KeyIndex",
786d4f2939cSRui Paulo 					 cred->key_idx) ||
787d4f2939cSRui Paulo 	    !wpa_dbus_dict_close_write(&iter, &dict_iter))
788d4f2939cSRui Paulo 		goto nomem;
789d4f2939cSRui Paulo 
790d4f2939cSRui Paulo 	dbus_connection_send(iface->con, msg, NULL);
791d4f2939cSRui Paulo 
792d4f2939cSRui Paulo nomem:
793d4f2939cSRui Paulo 	dbus_message_unref(msg);
794d4f2939cSRui Paulo }
795d4f2939cSRui Paulo 
796d4f2939cSRui Paulo #endif /* CONFIG_WPS */
797d4f2939cSRui Paulo 
79885732ac8SCy Schubert 
79985732ac8SCy Schubert #ifdef CONFIG_MESH
80085732ac8SCy Schubert 
80185732ac8SCy Schubert void wpas_dbus_signal_mesh_group_started(struct wpa_supplicant *wpa_s,
80285732ac8SCy Schubert 					 struct wpa_ssid *ssid)
80385732ac8SCy Schubert {
80485732ac8SCy Schubert 	struct wpas_dbus_priv *iface;
80585732ac8SCy Schubert 	DBusMessage *msg;
80685732ac8SCy Schubert 	DBusMessageIter iter, dict_iter;
80785732ac8SCy Schubert 
80885732ac8SCy Schubert 	iface = wpa_s->global->dbus;
80985732ac8SCy Schubert 
81085732ac8SCy Schubert 	/* Do nothing if the control interface is not turned on */
81185732ac8SCy Schubert 	if (!iface || !wpa_s->dbus_new_path)
81285732ac8SCy Schubert 		return;
81385732ac8SCy Schubert 
81485732ac8SCy Schubert 	msg = dbus_message_new_signal(wpa_s->dbus_new_path,
81585732ac8SCy Schubert 				      WPAS_DBUS_NEW_IFACE_MESH,
81685732ac8SCy Schubert 				      "MeshGroupStarted");
81785732ac8SCy Schubert 	if (!msg)
81885732ac8SCy Schubert 		return;
81985732ac8SCy Schubert 
82085732ac8SCy Schubert 	dbus_message_iter_init_append(msg, &iter);
82185732ac8SCy Schubert 	if (!wpa_dbus_dict_open_write(&iter, &dict_iter) ||
82285732ac8SCy Schubert 	    !wpa_dbus_dict_append_byte_array(&dict_iter, "SSID",
82385732ac8SCy Schubert 					     (const char *) ssid->ssid,
82485732ac8SCy Schubert 					     ssid->ssid_len) ||
82585732ac8SCy Schubert 	    !wpa_dbus_dict_close_write(&iter, &dict_iter))
82685732ac8SCy Schubert 		wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
82785732ac8SCy Schubert 	else
82885732ac8SCy Schubert 		dbus_connection_send(iface->con, msg, NULL);
82985732ac8SCy Schubert 	dbus_message_unref(msg);
83085732ac8SCy Schubert }
83185732ac8SCy Schubert 
83285732ac8SCy Schubert 
83385732ac8SCy Schubert void wpas_dbus_signal_mesh_group_removed(struct wpa_supplicant *wpa_s,
83485732ac8SCy Schubert 					 const u8 *meshid, u8 meshid_len,
83585732ac8SCy Schubert 					 int reason)
83685732ac8SCy Schubert {
83785732ac8SCy Schubert 	struct wpas_dbus_priv *iface;
83885732ac8SCy Schubert 	DBusMessage *msg;
83985732ac8SCy Schubert 	DBusMessageIter iter, dict_iter;
84085732ac8SCy Schubert 
84185732ac8SCy Schubert 	iface = wpa_s->global->dbus;
84285732ac8SCy Schubert 
84385732ac8SCy Schubert 	/* Do nothing if the control interface is not turned on */
84485732ac8SCy Schubert 	if (!iface || !wpa_s->dbus_new_path)
84585732ac8SCy Schubert 		return;
84685732ac8SCy Schubert 
84785732ac8SCy Schubert 	msg = dbus_message_new_signal(wpa_s->dbus_new_path,
84885732ac8SCy Schubert 				      WPAS_DBUS_NEW_IFACE_MESH,
84985732ac8SCy Schubert 				      "MeshGroupRemoved");
85085732ac8SCy Schubert 	if (!msg)
85185732ac8SCy Schubert 		return;
85285732ac8SCy Schubert 
85385732ac8SCy Schubert 	dbus_message_iter_init_append(msg, &iter);
85485732ac8SCy Schubert 	if (!wpa_dbus_dict_open_write(&iter, &dict_iter) ||
85585732ac8SCy Schubert 	    !wpa_dbus_dict_append_byte_array(&dict_iter, "SSID",
85685732ac8SCy Schubert 					     (const char *) meshid,
85785732ac8SCy Schubert 					     meshid_len) ||
85885732ac8SCy Schubert 	    !wpa_dbus_dict_append_int32(&dict_iter, "DisconnectReason",
85985732ac8SCy Schubert 					reason) ||
86085732ac8SCy Schubert 	    !wpa_dbus_dict_close_write(&iter, &dict_iter))
86185732ac8SCy Schubert 		wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
86285732ac8SCy Schubert 	else
86385732ac8SCy Schubert 		dbus_connection_send(iface->con, msg, NULL);
86485732ac8SCy Schubert 	dbus_message_unref(msg);
86585732ac8SCy Schubert }
86685732ac8SCy Schubert 
86785732ac8SCy Schubert 
86885732ac8SCy Schubert void wpas_dbus_signal_mesh_peer_connected(struct wpa_supplicant *wpa_s,
86985732ac8SCy Schubert 					  const u8 *peer_addr)
87085732ac8SCy Schubert {
87185732ac8SCy Schubert 	struct wpas_dbus_priv *iface;
87285732ac8SCy Schubert 	DBusMessage *msg;
87385732ac8SCy Schubert 	DBusMessageIter iter, dict_iter;
87485732ac8SCy Schubert 
87585732ac8SCy Schubert 	iface = wpa_s->global->dbus;
87685732ac8SCy Schubert 
87785732ac8SCy Schubert 	/* Do nothing if the control interface is not turned on */
87885732ac8SCy Schubert 	if (!iface || !wpa_s->dbus_new_path)
87985732ac8SCy Schubert 		return;
88085732ac8SCy Schubert 
88185732ac8SCy Schubert 	msg = dbus_message_new_signal(wpa_s->dbus_new_path,
88285732ac8SCy Schubert 				      WPAS_DBUS_NEW_IFACE_MESH,
88385732ac8SCy Schubert 				      "MeshPeerConnected");
88485732ac8SCy Schubert 	if (!msg)
88585732ac8SCy Schubert 		return;
88685732ac8SCy Schubert 
88785732ac8SCy Schubert 	dbus_message_iter_init_append(msg, &iter);
88885732ac8SCy Schubert 	if (!wpa_dbus_dict_open_write(&iter, &dict_iter) ||
88985732ac8SCy Schubert 	    !wpa_dbus_dict_append_byte_array(&dict_iter, "PeerAddress",
89085732ac8SCy Schubert 					     (const char *) peer_addr,
89185732ac8SCy Schubert 					     ETH_ALEN) ||
89285732ac8SCy Schubert 	    !wpa_dbus_dict_close_write(&iter, &dict_iter))
89385732ac8SCy Schubert 		wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
89485732ac8SCy Schubert 	else
89585732ac8SCy Schubert 		dbus_connection_send(iface->con, msg, NULL);
89685732ac8SCy Schubert 	dbus_message_unref(msg);
89785732ac8SCy Schubert }
89885732ac8SCy Schubert 
89985732ac8SCy Schubert 
90085732ac8SCy Schubert void wpas_dbus_signal_mesh_peer_disconnected(struct wpa_supplicant *wpa_s,
90185732ac8SCy Schubert 					     const u8 *peer_addr, int reason)
90285732ac8SCy Schubert {
90385732ac8SCy Schubert 	struct wpas_dbus_priv *iface;
90485732ac8SCy Schubert 	DBusMessage *msg;
90585732ac8SCy Schubert 	DBusMessageIter iter, dict_iter;
90685732ac8SCy Schubert 
90785732ac8SCy Schubert 	iface = wpa_s->global->dbus;
90885732ac8SCy Schubert 
90985732ac8SCy Schubert 	/* Do nothing if the control interface is not turned on */
91085732ac8SCy Schubert 	if (!iface || !wpa_s->dbus_new_path)
91185732ac8SCy Schubert 		return;
91285732ac8SCy Schubert 
91385732ac8SCy Schubert 	msg = dbus_message_new_signal(wpa_s->dbus_new_path,
91485732ac8SCy Schubert 				      WPAS_DBUS_NEW_IFACE_MESH,
91585732ac8SCy Schubert 				      "MeshPeerDisconnected");
91685732ac8SCy Schubert 	if (!msg)
91785732ac8SCy Schubert 		return;
91885732ac8SCy Schubert 
91985732ac8SCy Schubert 	dbus_message_iter_init_append(msg, &iter);
92085732ac8SCy Schubert 	if (!wpa_dbus_dict_open_write(&iter, &dict_iter) ||
92185732ac8SCy Schubert 	    !wpa_dbus_dict_append_byte_array(&dict_iter, "PeerAddress",
92285732ac8SCy Schubert 					     (const char *) peer_addr,
92385732ac8SCy Schubert 					     ETH_ALEN) ||
92485732ac8SCy Schubert 	    !wpa_dbus_dict_append_int32(&dict_iter, "DisconnectReason",
92585732ac8SCy Schubert 					reason) ||
92685732ac8SCy Schubert 	    !wpa_dbus_dict_close_write(&iter, &dict_iter))
92785732ac8SCy Schubert 		wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
92885732ac8SCy Schubert 	else
92985732ac8SCy Schubert 		dbus_connection_send(iface->con, msg, NULL);
93085732ac8SCy Schubert 	dbus_message_unref(msg);
93185732ac8SCy Schubert }
93285732ac8SCy Schubert 
93385732ac8SCy Schubert #endif /* CONFIG_MESH */
93485732ac8SCy Schubert 
93585732ac8SCy Schubert 
936d4f2939cSRui Paulo void wpas_dbus_signal_certification(struct wpa_supplicant *wpa_s,
937d4f2939cSRui Paulo 				    int depth, const char *subject,
9385b9c547cSRui Paulo 				    const char *altsubject[],
9395b9c547cSRui Paulo 				    int num_altsubject,
940d4f2939cSRui Paulo 				    const char *cert_hash,
941d4f2939cSRui Paulo 				    const struct wpabuf *cert)
942d4f2939cSRui Paulo {
943d4f2939cSRui Paulo 	struct wpas_dbus_priv *iface;
944d4f2939cSRui Paulo 	DBusMessage *msg;
945d4f2939cSRui Paulo 	DBusMessageIter iter, dict_iter;
946d4f2939cSRui Paulo 
947d4f2939cSRui Paulo 	iface = wpa_s->global->dbus;
948d4f2939cSRui Paulo 
949d4f2939cSRui Paulo 	/* Do nothing if the control interface is not turned on */
950325151a3SRui Paulo 	if (iface == NULL || !wpa_s->dbus_new_path)
951d4f2939cSRui Paulo 		return;
952d4f2939cSRui Paulo 
953d4f2939cSRui Paulo 	msg = dbus_message_new_signal(wpa_s->dbus_new_path,
954d4f2939cSRui Paulo 				      WPAS_DBUS_NEW_IFACE_INTERFACE,
955d4f2939cSRui Paulo 				      "Certification");
956d4f2939cSRui Paulo 	if (msg == NULL)
957d4f2939cSRui Paulo 		return;
958d4f2939cSRui Paulo 
959d4f2939cSRui Paulo 	dbus_message_iter_init_append(msg, &iter);
9605b9c547cSRui Paulo 	if (!wpa_dbus_dict_open_write(&iter, &dict_iter) ||
9615b9c547cSRui Paulo 	    !wpa_dbus_dict_append_uint32(&dict_iter, "depth", depth) ||
9625b9c547cSRui Paulo 	    !wpa_dbus_dict_append_string(&dict_iter, "subject", subject) ||
9635b9c547cSRui Paulo 	    (altsubject && num_altsubject &&
9645b9c547cSRui Paulo 	     !wpa_dbus_dict_append_string_array(&dict_iter, "altsubject",
9655b9c547cSRui Paulo 						altsubject, num_altsubject)) ||
9665b9c547cSRui Paulo 	    (cert_hash &&
9675b9c547cSRui Paulo 	     !wpa_dbus_dict_append_string(&dict_iter, "cert_hash",
9685b9c547cSRui Paulo 					  cert_hash)) ||
9695b9c547cSRui Paulo 	    (cert &&
970d4f2939cSRui Paulo 	     !wpa_dbus_dict_append_byte_array(&dict_iter, "cert",
971d4f2939cSRui Paulo 					      wpabuf_head(cert),
9725b9c547cSRui Paulo 					      wpabuf_len(cert))) ||
9735b9c547cSRui Paulo 	    !wpa_dbus_dict_close_write(&iter, &dict_iter))
9745b9c547cSRui Paulo 		wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
9755b9c547cSRui Paulo 	else
976d4f2939cSRui Paulo 		dbus_connection_send(iface->con, msg, NULL);
977d4f2939cSRui Paulo 	dbus_message_unref(msg);
978d4f2939cSRui Paulo }
979d4f2939cSRui Paulo 
980d4f2939cSRui Paulo 
981d4f2939cSRui Paulo void wpas_dbus_signal_eap_status(struct wpa_supplicant *wpa_s,
982d4f2939cSRui Paulo 				 const char *status, const char *parameter)
983d4f2939cSRui Paulo {
984d4f2939cSRui Paulo 	struct wpas_dbus_priv *iface;
985d4f2939cSRui Paulo 	DBusMessage *msg;
986d4f2939cSRui Paulo 	DBusMessageIter iter;
987d4f2939cSRui Paulo 
988d4f2939cSRui Paulo 	iface = wpa_s->global->dbus;
989d4f2939cSRui Paulo 
990d4f2939cSRui Paulo 	/* Do nothing if the control interface is not turned on */
991325151a3SRui Paulo 	if (iface == NULL || !wpa_s->dbus_new_path)
992d4f2939cSRui Paulo 		return;
993d4f2939cSRui Paulo 
994d4f2939cSRui Paulo 	msg = dbus_message_new_signal(wpa_s->dbus_new_path,
995d4f2939cSRui Paulo 				      WPAS_DBUS_NEW_IFACE_INTERFACE,
996d4f2939cSRui Paulo 				      "EAP");
997d4f2939cSRui Paulo 	if (msg == NULL)
998d4f2939cSRui Paulo 		return;
999d4f2939cSRui Paulo 
1000d4f2939cSRui Paulo 	dbus_message_iter_init_append(msg, &iter);
1001d4f2939cSRui Paulo 
10025b9c547cSRui Paulo 	if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &status) ||
1003d4f2939cSRui Paulo 	    !dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING,
1004d4f2939cSRui Paulo 					    &parameter))
10055b9c547cSRui Paulo 		wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
10065b9c547cSRui Paulo 	else
1007d4f2939cSRui Paulo 		dbus_connection_send(iface->con, msg, NULL);
1008d4f2939cSRui Paulo 	dbus_message_unref(msg);
1009d4f2939cSRui Paulo }
1010d4f2939cSRui Paulo 
1011d4f2939cSRui Paulo 
10125b9c547cSRui Paulo /**
10135b9c547cSRui Paulo  * wpas_dbus_signal_sta - Send a station related event signal
10145b9c547cSRui Paulo  * @wpa_s: %wpa_supplicant network interface data
10155b9c547cSRui Paulo  * @sta: station mac address
10165b9c547cSRui Paulo  * @sig_name: signal name - StaAuthorized or StaDeauthorized
10175b9c547cSRui Paulo  *
10185b9c547cSRui Paulo  * Notify listeners about event related with station
10195b9c547cSRui Paulo  */
10205b9c547cSRui Paulo static void wpas_dbus_signal_sta(struct wpa_supplicant *wpa_s,
10215b9c547cSRui Paulo 				 const u8 *sta, const char *sig_name)
10225b9c547cSRui Paulo {
10235b9c547cSRui Paulo 	struct wpas_dbus_priv *iface;
10245b9c547cSRui Paulo 	DBusMessage *msg;
10255b9c547cSRui Paulo 	char sta_mac[WPAS_DBUS_OBJECT_PATH_MAX];
10265b9c547cSRui Paulo 	char *dev_mac;
10275b9c547cSRui Paulo 
10285b9c547cSRui Paulo 	os_snprintf(sta_mac, WPAS_DBUS_OBJECT_PATH_MAX, MACSTR, MAC2STR(sta));
10295b9c547cSRui Paulo 	dev_mac = sta_mac;
10305b9c547cSRui Paulo 
10315b9c547cSRui Paulo 	iface = wpa_s->global->dbus;
10325b9c547cSRui Paulo 
10335b9c547cSRui Paulo 	/* Do nothing if the control interface is not turned on */
1034325151a3SRui Paulo 	if (iface == NULL || !wpa_s->dbus_new_path)
10355b9c547cSRui Paulo 		return;
10365b9c547cSRui Paulo 
10375b9c547cSRui Paulo 	msg = dbus_message_new_signal(wpa_s->dbus_new_path,
10385b9c547cSRui Paulo 				      WPAS_DBUS_NEW_IFACE_INTERFACE, sig_name);
10395b9c547cSRui Paulo 	if (msg == NULL)
10405b9c547cSRui Paulo 		return;
10415b9c547cSRui Paulo 
10425b9c547cSRui Paulo 	if (dbus_message_append_args(msg, DBUS_TYPE_STRING, &dev_mac,
10435b9c547cSRui Paulo 				     DBUS_TYPE_INVALID))
10445b9c547cSRui Paulo 		dbus_connection_send(iface->con, msg, NULL);
10455b9c547cSRui Paulo 	else
10465b9c547cSRui Paulo 		wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
10475b9c547cSRui Paulo 	dbus_message_unref(msg);
10485b9c547cSRui Paulo 
10495b9c547cSRui Paulo 	wpa_printf(MSG_DEBUG, "dbus: Station MAC address '%s' '%s'",
10505b9c547cSRui Paulo 		   sta_mac, sig_name);
10515b9c547cSRui Paulo }
10525b9c547cSRui Paulo 
10535b9c547cSRui Paulo 
10545b9c547cSRui Paulo /**
10555b9c547cSRui Paulo  * wpas_dbus_signal_sta_authorized - Send a STA authorized signal
10565b9c547cSRui Paulo  * @wpa_s: %wpa_supplicant network interface data
10575b9c547cSRui Paulo  * @sta: station mac address
10585b9c547cSRui Paulo  *
10595b9c547cSRui Paulo  * Notify listeners a new station has been authorized
10605b9c547cSRui Paulo  */
10615b9c547cSRui Paulo void wpas_dbus_signal_sta_authorized(struct wpa_supplicant *wpa_s,
10625b9c547cSRui Paulo 				     const u8 *sta)
10635b9c547cSRui Paulo {
10645b9c547cSRui Paulo 	wpas_dbus_signal_sta(wpa_s, sta, "StaAuthorized");
10655b9c547cSRui Paulo }
10665b9c547cSRui Paulo 
10675b9c547cSRui Paulo 
10685b9c547cSRui Paulo /**
10695b9c547cSRui Paulo  * wpas_dbus_signal_sta_deauthorized - Send a STA deauthorized signal
10705b9c547cSRui Paulo  * @wpa_s: %wpa_supplicant network interface data
10715b9c547cSRui Paulo  * @sta: station mac address
10725b9c547cSRui Paulo  *
10735b9c547cSRui Paulo  * Notify listeners a station has been deauthorized
10745b9c547cSRui Paulo  */
10755b9c547cSRui Paulo void wpas_dbus_signal_sta_deauthorized(struct wpa_supplicant *wpa_s,
10765b9c547cSRui Paulo 				       const u8 *sta)
10775b9c547cSRui Paulo {
10785b9c547cSRui Paulo 	wpas_dbus_signal_sta(wpa_s, sta, "StaDeauthorized");
10795b9c547cSRui Paulo }
10805b9c547cSRui Paulo 
10815b9c547cSRui Paulo 
1082*4bc52338SCy Schubert /**
1083*4bc52338SCy Schubert  * wpas_dbus_signal_station - Send an event signal related to a station object
1084*4bc52338SCy Schubert  * @wpa_s: %wpa_supplicant network interface data
1085*4bc52338SCy Schubert  * @station_obj_path: Station object path
1086*4bc52338SCy Schubert  * @sig_name: signal name - StationAdded or StationRemoved
1087*4bc52338SCy Schubert  * @properties: Whether to add second argument with object properties
1088*4bc52338SCy Schubert  *
1089*4bc52338SCy Schubert  * Notify listeners about event related with station.
1090*4bc52338SCy Schubert  */
1091*4bc52338SCy Schubert static void wpas_dbus_signal_station(struct wpa_supplicant *wpa_s,
1092*4bc52338SCy Schubert 				     const char *station_obj_path,
1093*4bc52338SCy Schubert 				     const char *sig_name,
1094*4bc52338SCy Schubert 				     dbus_bool_t properties)
1095*4bc52338SCy Schubert {
1096*4bc52338SCy Schubert 	struct wpas_dbus_priv *iface;
1097*4bc52338SCy Schubert 	DBusMessage *msg;
1098*4bc52338SCy Schubert 	DBusMessageIter iter;
1099*4bc52338SCy Schubert 
1100*4bc52338SCy Schubert 	iface = wpa_s->global->dbus;
1101*4bc52338SCy Schubert 
1102*4bc52338SCy Schubert 	/* Do nothing if the control interface is not turned on */
1103*4bc52338SCy Schubert 	if (!iface || !wpa_s->dbus_new_path)
1104*4bc52338SCy Schubert 		return;
1105*4bc52338SCy Schubert 
1106*4bc52338SCy Schubert 	wpa_printf(MSG_DEBUG, "dbus: STA signal %s", sig_name);
1107*4bc52338SCy Schubert 	msg = dbus_message_new_signal(wpa_s->dbus_new_path,
1108*4bc52338SCy Schubert 				      WPAS_DBUS_NEW_IFACE_INTERFACE, sig_name);
1109*4bc52338SCy Schubert 	if (!msg)
1110*4bc52338SCy Schubert 		return;
1111*4bc52338SCy Schubert 
1112*4bc52338SCy Schubert 	dbus_message_iter_init_append(msg, &iter);
1113*4bc52338SCy Schubert 	if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_OBJECT_PATH,
1114*4bc52338SCy Schubert 					    &station_obj_path) ||
1115*4bc52338SCy Schubert 	    (properties &&
1116*4bc52338SCy Schubert 	     !wpa_dbus_get_object_properties(iface, station_obj_path,
1117*4bc52338SCy Schubert 					     WPAS_DBUS_NEW_IFACE_STA,
1118*4bc52338SCy Schubert 					     &iter)))
1119*4bc52338SCy Schubert 		wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
1120*4bc52338SCy Schubert 	else
1121*4bc52338SCy Schubert 		dbus_connection_send(iface->con, msg, NULL);
1122*4bc52338SCy Schubert 	dbus_message_unref(msg);
1123*4bc52338SCy Schubert }
1124*4bc52338SCy Schubert 
1125*4bc52338SCy Schubert 
1126*4bc52338SCy Schubert /**
1127*4bc52338SCy Schubert  * wpas_dbus_signal_station_added - Send a Station added signal
1128*4bc52338SCy Schubert  * @wpa_s: %wpa_supplicant network interface data
1129*4bc52338SCy Schubert  * @station_obj_path: new Station object path
1130*4bc52338SCy Schubert  *
1131*4bc52338SCy Schubert  * Notify listeners about adding new Station
1132*4bc52338SCy Schubert  */
1133*4bc52338SCy Schubert static void wpas_dbus_signal_station_added(struct wpa_supplicant *wpa_s,
1134*4bc52338SCy Schubert 					   const char *station_obj_path)
1135*4bc52338SCy Schubert {
1136*4bc52338SCy Schubert 	wpas_dbus_signal_station(wpa_s, station_obj_path, "StationAdded", TRUE);
1137*4bc52338SCy Schubert }
1138*4bc52338SCy Schubert 
1139*4bc52338SCy Schubert 
1140*4bc52338SCy Schubert /**
1141*4bc52338SCy Schubert  * wpas_dbus_signal_station_removed - Send a Station removed signal
1142*4bc52338SCy Schubert  * @wpa_s: %wpa_supplicant network interface data
1143*4bc52338SCy Schubert  * @station_obj_path: Station object path
1144*4bc52338SCy Schubert  *
1145*4bc52338SCy Schubert  * Notify listeners about removing Station
1146*4bc52338SCy Schubert  */
1147*4bc52338SCy Schubert static void wpas_dbus_signal_station_removed(struct wpa_supplicant *wpa_s,
1148*4bc52338SCy Schubert 					     const char *station_obj_path)
1149*4bc52338SCy Schubert {
1150*4bc52338SCy Schubert 	wpas_dbus_signal_station(wpa_s, station_obj_path, "StationRemoved",
1151*4bc52338SCy Schubert 				 FALSE);
1152*4bc52338SCy Schubert }
1153*4bc52338SCy Schubert 
1154*4bc52338SCy Schubert 
1155d4f2939cSRui Paulo #ifdef CONFIG_P2P
1156d4f2939cSRui Paulo 
1157d4f2939cSRui Paulo /**
1158d4f2939cSRui Paulo  * wpas_dbus_signal_p2p_group_removed - Signals P2P group was removed
1159d4f2939cSRui Paulo  * @wpa_s: %wpa_supplicant network interface data
1160d4f2939cSRui Paulo  * @role: role of this device (client or GO)
1161d4f2939cSRui Paulo  * Sends signal with i/f name and role as string arguments
1162d4f2939cSRui Paulo  */
1163d4f2939cSRui Paulo void wpas_dbus_signal_p2p_group_removed(struct wpa_supplicant *wpa_s,
1164d4f2939cSRui Paulo 					const char *role)
1165d4f2939cSRui Paulo {
1166d4f2939cSRui Paulo 	DBusMessage *msg;
11675b9c547cSRui Paulo 	DBusMessageIter iter, dict_iter;
1168d4f2939cSRui Paulo 	struct wpas_dbus_priv *iface = wpa_s->global->dbus;
11695b9c547cSRui Paulo 	struct wpa_supplicant *parent;
1170d4f2939cSRui Paulo 
1171d4f2939cSRui Paulo 	/* Do nothing if the control interface is not turned on */
1172d4f2939cSRui Paulo 	if (iface == NULL)
1173d4f2939cSRui Paulo 		return;
1174d4f2939cSRui Paulo 
11755b9c547cSRui Paulo 	parent = wpa_s->parent;
11765b9c547cSRui Paulo 	if (parent->p2p_mgmt)
11775b9c547cSRui Paulo 		parent = parent->parent;
11785b9c547cSRui Paulo 
1179325151a3SRui Paulo 	if (!wpa_s->dbus_groupobj_path || !wpa_s->dbus_new_path ||
1180325151a3SRui Paulo 	    !parent->dbus_new_path)
11815b9c547cSRui Paulo 		return;
11825b9c547cSRui Paulo 
11835b9c547cSRui Paulo 	msg = dbus_message_new_signal(parent->dbus_new_path,
1184d4f2939cSRui Paulo 				      WPAS_DBUS_NEW_IFACE_P2PDEVICE,
1185d4f2939cSRui Paulo 				      "GroupFinished");
1186d4f2939cSRui Paulo 	if (msg == NULL)
1187d4f2939cSRui Paulo 		return;
1188d4f2939cSRui Paulo 
1189d4f2939cSRui Paulo 	dbus_message_iter_init_append(msg, &iter);
11905b9c547cSRui Paulo 	if (!wpa_dbus_dict_open_write(&iter, &dict_iter) ||
11915b9c547cSRui Paulo 	    !wpa_dbus_dict_append_object_path(&dict_iter,
11925b9c547cSRui Paulo 					      "interface_object",
11935b9c547cSRui Paulo 					      wpa_s->dbus_new_path) ||
11945b9c547cSRui Paulo 	    !wpa_dbus_dict_append_string(&dict_iter, "role", role) ||
11955b9c547cSRui Paulo 	    !wpa_dbus_dict_append_object_path(&dict_iter, "group_object",
11965b9c547cSRui Paulo 					      wpa_s->dbus_groupobj_path) ||
11975b9c547cSRui Paulo 	    !wpa_dbus_dict_close_write(&iter, &dict_iter))
11985b9c547cSRui Paulo 		wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
1199d4f2939cSRui Paulo 	else
1200d4f2939cSRui Paulo 		dbus_connection_send(iface->con, msg, NULL);
1201d4f2939cSRui Paulo 	dbus_message_unref(msg);
1202d4f2939cSRui Paulo }
1203d4f2939cSRui Paulo 
1204d4f2939cSRui Paulo 
1205d4f2939cSRui Paulo /**
1206d4f2939cSRui Paulo  * wpas_dbus_signal_p2p_provision_discovery - Signals various PD events
1207d4f2939cSRui Paulo  *
1208d4f2939cSRui Paulo  * @dev_addr - who sent the request or responded to our request.
1209d4f2939cSRui Paulo  * @request - Will be 1 if request, 0 for response.
1210d4f2939cSRui Paulo  * @status - valid only in case of response
1211d4f2939cSRui Paulo  * @config_methods - wps config methods
1212d4f2939cSRui Paulo  * @generated_pin - pin to be displayed in case of WPS_CONFIG_DISPLAY method
1213d4f2939cSRui Paulo  *
1214d4f2939cSRui Paulo  * Sends following provision discovery related events:
1215d4f2939cSRui Paulo  *	ProvisionDiscoveryRequestDisplayPin
1216d4f2939cSRui Paulo  *	ProvisionDiscoveryResponseDisplayPin
1217d4f2939cSRui Paulo  *	ProvisionDiscoveryRequestEnterPin
1218d4f2939cSRui Paulo  *	ProvisionDiscoveryResponseEnterPin
1219d4f2939cSRui Paulo  *	ProvisionDiscoveryPBCRequest
1220d4f2939cSRui Paulo  *	ProvisionDiscoveryPBCResponse
1221d4f2939cSRui Paulo  *
1222d4f2939cSRui Paulo  *	TODO::
1223d4f2939cSRui Paulo  *	ProvisionDiscoveryFailure (timeout case)
1224d4f2939cSRui Paulo  */
1225d4f2939cSRui Paulo void wpas_dbus_signal_p2p_provision_discovery(struct wpa_supplicant *wpa_s,
1226d4f2939cSRui Paulo 					      const u8 *dev_addr, int request,
1227d4f2939cSRui Paulo 					      enum p2p_prov_disc_status status,
1228d4f2939cSRui Paulo 					      u16 config_methods,
1229d4f2939cSRui Paulo 					      unsigned int generated_pin)
1230d4f2939cSRui Paulo {
1231d4f2939cSRui Paulo 	DBusMessage *msg;
1232d4f2939cSRui Paulo 	DBusMessageIter iter;
1233d4f2939cSRui Paulo 	struct wpas_dbus_priv *iface;
1234d4f2939cSRui Paulo 	char *_signal;
1235d4f2939cSRui Paulo 	int add_pin = 0;
1236d4f2939cSRui Paulo 	char peer_obj_path[WPAS_DBUS_OBJECT_PATH_MAX], *path;
1237d4f2939cSRui Paulo 	int error_ret = 1;
1238d4f2939cSRui Paulo 	char pin[9], *p_pin = NULL;
1239d4f2939cSRui Paulo 
1240d4f2939cSRui Paulo 	iface = wpa_s->global->dbus;
1241d4f2939cSRui Paulo 
1242d4f2939cSRui Paulo 	/* Do nothing if the control interface is not turned on */
1243d4f2939cSRui Paulo 	if (iface == NULL)
1244d4f2939cSRui Paulo 		return;
1245d4f2939cSRui Paulo 
12465b9c547cSRui Paulo 	if (wpa_s->p2p_mgmt)
12475b9c547cSRui Paulo 		wpa_s = wpa_s->parent;
1248325151a3SRui Paulo 	if (!wpa_s->dbus_new_path)
1249325151a3SRui Paulo 		return;
12505b9c547cSRui Paulo 
1251d4f2939cSRui Paulo 	if (request || !status) {
1252d4f2939cSRui Paulo 		if (config_methods & WPS_CONFIG_DISPLAY)
1253d4f2939cSRui Paulo 			_signal = request ?
1254d4f2939cSRui Paulo 				 "ProvisionDiscoveryRequestDisplayPin" :
1255d4f2939cSRui Paulo 				 "ProvisionDiscoveryResponseEnterPin";
1256d4f2939cSRui Paulo 		else if (config_methods & WPS_CONFIG_KEYPAD)
1257d4f2939cSRui Paulo 			_signal = request ?
1258d4f2939cSRui Paulo 				 "ProvisionDiscoveryRequestEnterPin" :
1259d4f2939cSRui Paulo 				 "ProvisionDiscoveryResponseDisplayPin";
1260d4f2939cSRui Paulo 		else if (config_methods & WPS_CONFIG_PUSHBUTTON)
1261d4f2939cSRui Paulo 			_signal = request ? "ProvisionDiscoveryPBCRequest" :
1262d4f2939cSRui Paulo 				   "ProvisionDiscoveryPBCResponse";
1263d4f2939cSRui Paulo 		else
1264d4f2939cSRui Paulo 			return; /* Unknown or un-supported method */
12655b9c547cSRui Paulo 	} else {
1266d4f2939cSRui Paulo 		/* Explicit check for failure response */
1267d4f2939cSRui Paulo 		_signal = "ProvisionDiscoveryFailure";
12685b9c547cSRui Paulo 	}
1269d4f2939cSRui Paulo 
1270d4f2939cSRui Paulo 	add_pin = ((request && (config_methods & WPS_CONFIG_DISPLAY)) ||
1271d4f2939cSRui Paulo 		   (!request && !status &&
1272d4f2939cSRui Paulo 			(config_methods & WPS_CONFIG_KEYPAD)));
1273d4f2939cSRui Paulo 
1274d4f2939cSRui Paulo 	if (add_pin) {
1275d4f2939cSRui Paulo 		os_snprintf(pin, sizeof(pin), "%08d", generated_pin);
1276d4f2939cSRui Paulo 		p_pin = pin;
1277d4f2939cSRui Paulo 	}
1278d4f2939cSRui Paulo 
1279d4f2939cSRui Paulo 	msg = dbus_message_new_signal(wpa_s->dbus_new_path,
1280d4f2939cSRui Paulo 				      WPAS_DBUS_NEW_IFACE_P2PDEVICE, _signal);
1281d4f2939cSRui Paulo 	if (msg == NULL)
1282d4f2939cSRui Paulo 		return;
1283d4f2939cSRui Paulo 
1284d4f2939cSRui Paulo 	/* Check if this is a known peer */
1285d4f2939cSRui Paulo 	if (!p2p_peer_known(wpa_s->global->p2p, dev_addr))
1286d4f2939cSRui Paulo 		goto error;
1287d4f2939cSRui Paulo 
1288d4f2939cSRui Paulo 	os_snprintf(peer_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
1289d4f2939cSRui Paulo 			"%s/" WPAS_DBUS_NEW_P2P_PEERS_PART "/"
1290d4f2939cSRui Paulo 			COMPACT_MACSTR,
1291d4f2939cSRui Paulo 			wpa_s->dbus_new_path, MAC2STR(dev_addr));
1292d4f2939cSRui Paulo 
1293d4f2939cSRui Paulo 	path = peer_obj_path;
1294d4f2939cSRui Paulo 
1295d4f2939cSRui Paulo 	dbus_message_iter_init_append(msg, &iter);
1296d4f2939cSRui Paulo 
1297d4f2939cSRui Paulo 	if (!dbus_message_iter_append_basic(&iter,
1298d4f2939cSRui Paulo 					    DBUS_TYPE_OBJECT_PATH,
1299d4f2939cSRui Paulo 					    &path))
1300d4f2939cSRui Paulo 			goto error;
1301d4f2939cSRui Paulo 
1302d4f2939cSRui Paulo 	if (!request && status)
1303d4f2939cSRui Paulo 		/* Attach status to ProvisionDiscoveryFailure */
1304d4f2939cSRui Paulo 		error_ret = !dbus_message_iter_append_basic(&iter,
1305d4f2939cSRui Paulo 						    DBUS_TYPE_INT32,
1306d4f2939cSRui Paulo 						    &status);
1307d4f2939cSRui Paulo 	else
1308d4f2939cSRui Paulo 		error_ret = (add_pin &&
1309d4f2939cSRui Paulo 				 !dbus_message_iter_append_basic(&iter,
1310d4f2939cSRui Paulo 							DBUS_TYPE_STRING,
1311d4f2939cSRui Paulo 							&p_pin));
1312d4f2939cSRui Paulo 
1313d4f2939cSRui Paulo error:
1314d4f2939cSRui Paulo 	if (!error_ret)
1315d4f2939cSRui Paulo 		dbus_connection_send(iface->con, msg, NULL);
1316d4f2939cSRui Paulo 	else
1317d4f2939cSRui Paulo 		wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
1318d4f2939cSRui Paulo 
1319d4f2939cSRui Paulo 	dbus_message_unref(msg);
1320d4f2939cSRui Paulo }
1321d4f2939cSRui Paulo 
1322d4f2939cSRui Paulo 
1323325151a3SRui Paulo /**
1324325151a3SRui Paulo  * wpas_dbus_signal_p2p_go_neg_req - Signal P2P GO Negotiation Request RX
1325325151a3SRui Paulo  * @wpa_s: %wpa_supplicant network interface data
1326325151a3SRui Paulo  * @src: Source address of the message triggering this notification
1327325151a3SRui Paulo  * @dev_passwd_id: WPS Device Password Id
1328325151a3SRui Paulo  * @go_intent: Peer's GO Intent value
1329325151a3SRui Paulo  *
1330325151a3SRui Paulo  * Sends signal to notify that a peer P2P Device is requesting group owner
1331325151a3SRui Paulo  * negotiation with us.
1332325151a3SRui Paulo  */
1333d4f2939cSRui Paulo void wpas_dbus_signal_p2p_go_neg_req(struct wpa_supplicant *wpa_s,
1334325151a3SRui Paulo 				     const u8 *src, u16 dev_passwd_id,
1335325151a3SRui Paulo 				     u8 go_intent)
1336d4f2939cSRui Paulo {
1337d4f2939cSRui Paulo 	DBusMessage *msg;
1338d4f2939cSRui Paulo 	DBusMessageIter iter;
1339d4f2939cSRui Paulo 	struct wpas_dbus_priv *iface;
1340d4f2939cSRui Paulo 	char peer_obj_path[WPAS_DBUS_OBJECT_PATH_MAX], *path;
1341d4f2939cSRui Paulo 
1342d4f2939cSRui Paulo 	iface = wpa_s->global->dbus;
1343d4f2939cSRui Paulo 
1344d4f2939cSRui Paulo 	/* Do nothing if the control interface is not turned on */
1345d4f2939cSRui Paulo 	if (iface == NULL)
1346d4f2939cSRui Paulo 		return;
1347d4f2939cSRui Paulo 
13485b9c547cSRui Paulo 	if (wpa_s->p2p_mgmt)
13495b9c547cSRui Paulo 		wpa_s = wpa_s->parent;
1350325151a3SRui Paulo 	if (!wpa_s->dbus_new_path)
1351325151a3SRui Paulo 		return;
13525b9c547cSRui Paulo 
1353d4f2939cSRui Paulo 	os_snprintf(peer_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
1354d4f2939cSRui Paulo 		    "%s/" WPAS_DBUS_NEW_P2P_PEERS_PART "/" COMPACT_MACSTR,
1355d4f2939cSRui Paulo 		    wpa_s->dbus_new_path, MAC2STR(src));
1356d4f2939cSRui Paulo 	path = peer_obj_path;
1357d4f2939cSRui Paulo 
1358d4f2939cSRui Paulo 	msg = dbus_message_new_signal(wpa_s->dbus_new_path,
1359d4f2939cSRui Paulo 				      WPAS_DBUS_NEW_IFACE_P2PDEVICE,
1360d4f2939cSRui Paulo 				      "GONegotiationRequest");
1361d4f2939cSRui Paulo 	if (msg == NULL)
1362d4f2939cSRui Paulo 		return;
1363d4f2939cSRui Paulo 
1364d4f2939cSRui Paulo 	dbus_message_iter_init_append(msg, &iter);
1365d4f2939cSRui Paulo 
1366d4f2939cSRui Paulo 	if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_OBJECT_PATH,
1367d4f2939cSRui Paulo 					    &path) ||
1368d4f2939cSRui Paulo 	    !dbus_message_iter_append_basic(&iter, DBUS_TYPE_UINT16,
1369325151a3SRui Paulo 					    &dev_passwd_id) ||
1370325151a3SRui Paulo 	    !dbus_message_iter_append_basic(&iter, DBUS_TYPE_BYTE,
1371325151a3SRui Paulo 					    &go_intent))
1372d4f2939cSRui Paulo 		wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
1373d4f2939cSRui Paulo 	else
1374d4f2939cSRui Paulo 		dbus_connection_send(iface->con, msg, NULL);
1375d4f2939cSRui Paulo 
1376d4f2939cSRui Paulo 	dbus_message_unref(msg);
1377d4f2939cSRui Paulo }
1378d4f2939cSRui Paulo 
1379d4f2939cSRui Paulo 
1380d4f2939cSRui Paulo static int wpas_dbus_get_group_obj_path(struct wpa_supplicant *wpa_s,
1381d4f2939cSRui Paulo 					const struct wpa_ssid *ssid,
1382d4f2939cSRui Paulo 					char *group_obj_path)
1383d4f2939cSRui Paulo {
1384d4f2939cSRui Paulo 	char group_name[3];
1385d4f2939cSRui Paulo 
1386325151a3SRui Paulo 	if (!wpa_s->dbus_new_path ||
1387325151a3SRui Paulo 	    os_memcmp(ssid->ssid, P2P_WILDCARD_SSID, P2P_WILDCARD_SSID_LEN))
1388d4f2939cSRui Paulo 		return -1;
1389d4f2939cSRui Paulo 
1390d4f2939cSRui Paulo 	os_memcpy(group_name, ssid->ssid + P2P_WILDCARD_SSID_LEN, 2);
1391d4f2939cSRui Paulo 	group_name[2] = '\0';
1392d4f2939cSRui Paulo 
1393d4f2939cSRui Paulo 	os_snprintf(group_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
1394d4f2939cSRui Paulo 		    "%s/" WPAS_DBUS_NEW_P2P_GROUPS_PART "/%s",
1395d4f2939cSRui Paulo 		    wpa_s->dbus_new_path, group_name);
1396d4f2939cSRui Paulo 
1397d4f2939cSRui Paulo 	return 0;
1398d4f2939cSRui Paulo }
1399d4f2939cSRui Paulo 
1400d4f2939cSRui Paulo 
14015b9c547cSRui Paulo struct group_changed_data {
14025b9c547cSRui Paulo 	struct wpa_supplicant *wpa_s;
14035b9c547cSRui Paulo 	struct p2p_peer_info *info;
14045b9c547cSRui Paulo };
14055b9c547cSRui Paulo 
14065b9c547cSRui Paulo 
14075b9c547cSRui Paulo static int match_group_where_peer_is_client(struct p2p_group *group,
14085b9c547cSRui Paulo 					    void *user_data)
14095b9c547cSRui Paulo {
14105b9c547cSRui Paulo 	struct group_changed_data *data = user_data;
14115b9c547cSRui Paulo 	const struct p2p_group_config *cfg;
14125b9c547cSRui Paulo 	struct wpa_supplicant *wpa_s_go;
14135b9c547cSRui Paulo 
14145b9c547cSRui Paulo 	if (!p2p_group_is_client_connected(group, data->info->p2p_device_addr))
14155b9c547cSRui Paulo 		return 1;
14165b9c547cSRui Paulo 
14175b9c547cSRui Paulo 	cfg = p2p_group_get_config(group);
14185b9c547cSRui Paulo 
14195b9c547cSRui Paulo 	wpa_s_go = wpas_get_p2p_go_iface(data->wpa_s, cfg->ssid,
14205b9c547cSRui Paulo 					 cfg->ssid_len);
14215b9c547cSRui Paulo 	if (wpa_s_go != NULL && wpa_s_go == data->wpa_s) {
14225b9c547cSRui Paulo 		wpas_dbus_signal_peer_groups_changed(
1423780fb4a2SCy Schubert 			data->wpa_s->p2pdev, data->info->p2p_device_addr);
14245b9c547cSRui Paulo 		return 0;
14255b9c547cSRui Paulo 	}
14265b9c547cSRui Paulo 
14275b9c547cSRui Paulo 	return 1;
14285b9c547cSRui Paulo }
14295b9c547cSRui Paulo 
14305b9c547cSRui Paulo 
14315b9c547cSRui Paulo static void signal_peer_groups_changed(struct p2p_peer_info *info,
14325b9c547cSRui Paulo 				       void *user_data)
14335b9c547cSRui Paulo {
14345b9c547cSRui Paulo 	struct group_changed_data *data = user_data;
14355b9c547cSRui Paulo 	struct wpa_supplicant *wpa_s_go;
14365b9c547cSRui Paulo 
14375b9c547cSRui Paulo 	wpa_s_go = wpas_get_p2p_client_iface(data->wpa_s,
14385b9c547cSRui Paulo 					     info->p2p_device_addr);
14395b9c547cSRui Paulo 	if (wpa_s_go != NULL && wpa_s_go == data->wpa_s) {
1440780fb4a2SCy Schubert 		wpas_dbus_signal_peer_groups_changed(data->wpa_s->p2pdev,
14415b9c547cSRui Paulo 						     info->p2p_device_addr);
14425b9c547cSRui Paulo 		return;
14435b9c547cSRui Paulo 	}
14445b9c547cSRui Paulo 
14455b9c547cSRui Paulo 	data->info = info;
14465b9c547cSRui Paulo 	p2p_loop_on_all_groups(data->wpa_s->global->p2p,
14475b9c547cSRui Paulo 			       match_group_where_peer_is_client, data);
14485b9c547cSRui Paulo 	data->info = NULL;
14495b9c547cSRui Paulo }
14505b9c547cSRui Paulo 
14515b9c547cSRui Paulo 
14525b9c547cSRui Paulo static void peer_groups_changed(struct wpa_supplicant *wpa_s)
14535b9c547cSRui Paulo {
14545b9c547cSRui Paulo 	struct group_changed_data data;
14555b9c547cSRui Paulo 
14565b9c547cSRui Paulo 	os_memset(&data, 0, sizeof(data));
14575b9c547cSRui Paulo 	data.wpa_s = wpa_s;
14585b9c547cSRui Paulo 
14595b9c547cSRui Paulo 	p2p_loop_on_known_peers(wpa_s->global->p2p,
14605b9c547cSRui Paulo 				signal_peer_groups_changed, &data);
14615b9c547cSRui Paulo }
14625b9c547cSRui Paulo 
14635b9c547cSRui Paulo 
1464d4f2939cSRui Paulo /**
1465d4f2939cSRui Paulo  * wpas_dbus_signal_p2p_group_started - Signals P2P group has
1466d4f2939cSRui Paulo  * started. Emitted when a group is successfully started
1467d4f2939cSRui Paulo  * irrespective of the role (client/GO) of the current device
1468d4f2939cSRui Paulo  *
1469d4f2939cSRui Paulo  * @wpa_s: %wpa_supplicant network interface data
1470d4f2939cSRui Paulo  * @client: this device is P2P client
1471780fb4a2SCy Schubert  * @persistent: 0 - non persistent group, 1 - persistent group
147285732ac8SCy Schubert  * @ip: When group role is client, it contains local IP address, netmask, and
147385732ac8SCy Schubert  *	GO's IP address, if assigned; otherwise, NULL
1474d4f2939cSRui Paulo  */
1475d4f2939cSRui Paulo void wpas_dbus_signal_p2p_group_started(struct wpa_supplicant *wpa_s,
147685732ac8SCy Schubert 					int client, int persistent,
147785732ac8SCy Schubert 					const u8 *ip)
1478d4f2939cSRui Paulo {
1479d4f2939cSRui Paulo 	DBusMessage *msg;
1480d4f2939cSRui Paulo 	DBusMessageIter iter, dict_iter;
1481d4f2939cSRui Paulo 	struct wpas_dbus_priv *iface;
14825b9c547cSRui Paulo 	struct wpa_supplicant *parent;
1483d4f2939cSRui Paulo 
14845b9c547cSRui Paulo 	parent = wpa_s->parent;
14855b9c547cSRui Paulo 	if (parent->p2p_mgmt)
14865b9c547cSRui Paulo 		parent = parent->parent;
14875b9c547cSRui Paulo 
14885b9c547cSRui Paulo 	iface = parent->global->dbus;
1489d4f2939cSRui Paulo 
1490d4f2939cSRui Paulo 	/* Do nothing if the control interface is not turned on */
1491325151a3SRui Paulo 	if (iface == NULL || !parent->dbus_new_path || !wpa_s->dbus_new_path)
1492d4f2939cSRui Paulo 		return;
1493d4f2939cSRui Paulo 
14945b9c547cSRui Paulo 	if (wpa_s->dbus_groupobj_path == NULL)
1495d4f2939cSRui Paulo 		return;
1496d4f2939cSRui Paulo 
1497d4f2939cSRui Paulo 	/* New interface has been created for this group */
14985b9c547cSRui Paulo 	msg = dbus_message_new_signal(parent->dbus_new_path,
1499d4f2939cSRui Paulo 				      WPAS_DBUS_NEW_IFACE_P2PDEVICE,
1500d4f2939cSRui Paulo 				      "GroupStarted");
1501d4f2939cSRui Paulo 	if (msg == NULL)
1502d4f2939cSRui Paulo 		return;
1503d4f2939cSRui Paulo 
1504d4f2939cSRui Paulo 	dbus_message_iter_init_append(msg, &iter);
1505d4f2939cSRui Paulo 	/*
1506d4f2939cSRui Paulo 	 * In case the device supports creating a separate interface the
1507d4f2939cSRui Paulo 	 * DBus client will need to know the object path for the interface
1508d4f2939cSRui Paulo 	 * object this group was created on, so include it here.
1509d4f2939cSRui Paulo 	 */
15105b9c547cSRui Paulo 	if (!wpa_dbus_dict_open_write(&iter, &dict_iter) ||
15115b9c547cSRui Paulo 	    !wpa_dbus_dict_append_object_path(&dict_iter,
1512d4f2939cSRui Paulo 					      "interface_object",
15135b9c547cSRui Paulo 					      wpa_s->dbus_new_path) ||
15145b9c547cSRui Paulo 	    !wpa_dbus_dict_append_string(&dict_iter, "role",
15155b9c547cSRui Paulo 					 client ? "client" : "GO") ||
1516780fb4a2SCy Schubert 	    !wpa_dbus_dict_append_bool(&dict_iter, "persistent", persistent) ||
15175b9c547cSRui Paulo 	    !wpa_dbus_dict_append_object_path(&dict_iter, "group_object",
15185b9c547cSRui Paulo 					      wpa_s->dbus_groupobj_path) ||
151985732ac8SCy Schubert 	    (ip &&
152085732ac8SCy Schubert 	     (!wpa_dbus_dict_append_byte_array(&dict_iter, "IpAddr",
152185732ac8SCy Schubert 					       (char *) ip, 4) ||
152285732ac8SCy Schubert 	      !wpa_dbus_dict_append_byte_array(&dict_iter, "IpAddrMask",
152385732ac8SCy Schubert 					       (char *) ip + 4, 4) ||
152485732ac8SCy Schubert 	      !wpa_dbus_dict_append_byte_array(&dict_iter, "IpAddrGo",
152585732ac8SCy Schubert 					       (char *) ip + 8, 4))) ||
15265b9c547cSRui Paulo 	    !wpa_dbus_dict_close_write(&iter, &dict_iter)) {
15275b9c547cSRui Paulo 		wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
15285b9c547cSRui Paulo 	} else {
1529d4f2939cSRui Paulo 		dbus_connection_send(iface->con, msg, NULL);
15305b9c547cSRui Paulo 		if (client)
15315b9c547cSRui Paulo 			peer_groups_changed(wpa_s);
15325b9c547cSRui Paulo 	}
1533d4f2939cSRui Paulo 	dbus_message_unref(msg);
1534d4f2939cSRui Paulo }
1535d4f2939cSRui Paulo 
1536d4f2939cSRui Paulo 
1537d4f2939cSRui Paulo /**
1538325151a3SRui Paulo  * wpas_dbus_signal_p2p_go_neg_resp - Emit GONegotiation Success/Failure signal
1539325151a3SRui Paulo  * @wpa_s: %wpa_supplicant network interface data
1540325151a3SRui Paulo  * @res: Result of the GO Neg Request
1541d4f2939cSRui Paulo  */
1542d4f2939cSRui Paulo void wpas_dbus_signal_p2p_go_neg_resp(struct wpa_supplicant *wpa_s,
1543d4f2939cSRui Paulo 				      struct p2p_go_neg_results *res)
1544d4f2939cSRui Paulo {
1545d4f2939cSRui Paulo 	DBusMessage *msg;
1546d4f2939cSRui Paulo 	DBusMessageIter iter, dict_iter;
1547d4f2939cSRui Paulo 	DBusMessageIter iter_dict_entry, iter_dict_val, iter_dict_array;
1548d4f2939cSRui Paulo 	struct wpas_dbus_priv *iface;
1549d4f2939cSRui Paulo 	char peer_obj_path[WPAS_DBUS_OBJECT_PATH_MAX], *path;
1550d4f2939cSRui Paulo 	dbus_int32_t freqs[P2P_MAX_CHANNELS];
1551d4f2939cSRui Paulo 	dbus_int32_t *f_array = freqs;
1552d4f2939cSRui Paulo 
1553d4f2939cSRui Paulo 
1554d4f2939cSRui Paulo 	iface = wpa_s->global->dbus;
1555d4f2939cSRui Paulo 
15565b9c547cSRui Paulo 	if (wpa_s->p2p_mgmt)
15575b9c547cSRui Paulo 		wpa_s = wpa_s->parent;
15585b9c547cSRui Paulo 
1559d4f2939cSRui Paulo 	os_memset(freqs, 0, sizeof(freqs));
1560d4f2939cSRui Paulo 	/* Do nothing if the control interface is not turned on */
1561325151a3SRui Paulo 	if (iface == NULL || !wpa_s->dbus_new_path)
1562d4f2939cSRui Paulo 		return;
1563d4f2939cSRui Paulo 
1564d4f2939cSRui Paulo 	os_snprintf(peer_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
1565d4f2939cSRui Paulo 		    "%s/" WPAS_DBUS_NEW_P2P_PEERS_PART "/" COMPACT_MACSTR,
1566d4f2939cSRui Paulo 		    wpa_s->dbus_new_path, MAC2STR(res->peer_device_addr));
1567d4f2939cSRui Paulo 	path = peer_obj_path;
1568d4f2939cSRui Paulo 
1569d4f2939cSRui Paulo 	msg = dbus_message_new_signal(wpa_s->dbus_new_path,
1570d4f2939cSRui Paulo 				      WPAS_DBUS_NEW_IFACE_P2PDEVICE,
1571d4f2939cSRui Paulo 				      res->status ? "GONegotiationFailure" :
1572d4f2939cSRui Paulo 						    "GONegotiationSuccess");
1573d4f2939cSRui Paulo 	if (msg == NULL)
1574d4f2939cSRui Paulo 		return;
1575d4f2939cSRui Paulo 
1576d4f2939cSRui Paulo 	dbus_message_iter_init_append(msg, &iter);
15775b9c547cSRui Paulo 	if (!wpa_dbus_dict_open_write(&iter, &dict_iter) ||
15785b9c547cSRui Paulo 	    !wpa_dbus_dict_append_object_path(&dict_iter, "peer_object",
1579d4f2939cSRui Paulo 					      path) ||
1580d4f2939cSRui Paulo 	    !wpa_dbus_dict_append_int32(&dict_iter, "status", res->status))
1581d4f2939cSRui Paulo 		goto err;
1582d4f2939cSRui Paulo 
1583d4f2939cSRui Paulo 	if (!res->status) {
1584d4f2939cSRui Paulo 		int i = 0;
1585d4f2939cSRui Paulo 		int freq_list_num = 0;
1586d4f2939cSRui Paulo 
15875b9c547cSRui Paulo 		if ((res->role_go &&
15885b9c547cSRui Paulo 		     !wpa_dbus_dict_append_string(&dict_iter, "passphrase",
15895b9c547cSRui Paulo 						  res->passphrase)) ||
15905b9c547cSRui Paulo 		    !wpa_dbus_dict_append_string(&dict_iter, "role_go",
1591d4f2939cSRui Paulo 						 res->role_go ? "GO" :
1592d4f2939cSRui Paulo 						 "client") ||
1593d4f2939cSRui Paulo 		    !wpa_dbus_dict_append_int32(&dict_iter, "frequency",
1594d4f2939cSRui Paulo 						res->freq) ||
1595d4f2939cSRui Paulo 		    !wpa_dbus_dict_append_byte_array(&dict_iter, "ssid",
1596d4f2939cSRui Paulo 						     (const char *) res->ssid,
1597d4f2939cSRui Paulo 						     res->ssid_len) ||
1598d4f2939cSRui Paulo 		    !wpa_dbus_dict_append_byte_array(&dict_iter,
1599d4f2939cSRui Paulo 						     "peer_device_addr",
1600d4f2939cSRui Paulo 						     (const char *)
1601d4f2939cSRui Paulo 						     res->peer_device_addr,
1602d4f2939cSRui Paulo 						     ETH_ALEN) ||
1603d4f2939cSRui Paulo 		    !wpa_dbus_dict_append_byte_array(&dict_iter,
1604d4f2939cSRui Paulo 						     "peer_interface_addr",
1605d4f2939cSRui Paulo 						     (const char *)
1606d4f2939cSRui Paulo 						     res->peer_interface_addr,
1607d4f2939cSRui Paulo 						     ETH_ALEN) ||
1608d4f2939cSRui Paulo 		    !wpa_dbus_dict_append_string(&dict_iter, "wps_method",
1609d4f2939cSRui Paulo 						 p2p_wps_method_text(
1610d4f2939cSRui Paulo 							 res->wps_method)))
1611d4f2939cSRui Paulo 			goto err;
1612d4f2939cSRui Paulo 
1613d4f2939cSRui Paulo 		for (i = 0; i < P2P_MAX_CHANNELS; i++) {
1614d4f2939cSRui Paulo 			if (res->freq_list[i]) {
1615d4f2939cSRui Paulo 				freqs[i] = res->freq_list[i];
1616d4f2939cSRui Paulo 				freq_list_num++;
1617d4f2939cSRui Paulo 			}
1618d4f2939cSRui Paulo 		}
1619d4f2939cSRui Paulo 
1620d4f2939cSRui Paulo 		if (!wpa_dbus_dict_begin_array(&dict_iter,
1621d4f2939cSRui Paulo 					       "frequency_list",
1622d4f2939cSRui Paulo 					       DBUS_TYPE_INT32_AS_STRING,
1623d4f2939cSRui Paulo 					       &iter_dict_entry,
1624d4f2939cSRui Paulo 					       &iter_dict_val,
16255b9c547cSRui Paulo 					       &iter_dict_array) ||
16265b9c547cSRui Paulo 		    !dbus_message_iter_append_fixed_array(&iter_dict_array,
1627d4f2939cSRui Paulo 							  DBUS_TYPE_INT32,
1628d4f2939cSRui Paulo 							  &f_array,
16295b9c547cSRui Paulo 							  freq_list_num) ||
16305b9c547cSRui Paulo 		    !wpa_dbus_dict_end_array(&dict_iter,
1631d4f2939cSRui Paulo 					     &iter_dict_entry,
1632d4f2939cSRui Paulo 					     &iter_dict_val,
16335b9c547cSRui Paulo 					     &iter_dict_array) ||
16345b9c547cSRui Paulo 		    !wpa_dbus_dict_append_int32(&dict_iter, "persistent_group",
1635d4f2939cSRui Paulo 						res->persistent_group) ||
1636d4f2939cSRui Paulo 		    !wpa_dbus_dict_append_uint32(&dict_iter,
1637d4f2939cSRui Paulo 						 "peer_config_timeout",
1638d4f2939cSRui Paulo 						 res->peer_config_timeout))
1639d4f2939cSRui Paulo 			goto err;
1640d4f2939cSRui Paulo 	}
1641d4f2939cSRui Paulo 
1642d4f2939cSRui Paulo 	if (!wpa_dbus_dict_close_write(&iter, &dict_iter))
1643d4f2939cSRui Paulo 		goto err;
1644d4f2939cSRui Paulo 
1645d4f2939cSRui Paulo 	dbus_connection_send(iface->con, msg, NULL);
1646d4f2939cSRui Paulo err:
1647d4f2939cSRui Paulo 	dbus_message_unref(msg);
1648d4f2939cSRui Paulo }
1649d4f2939cSRui Paulo 
1650d4f2939cSRui Paulo 
1651d4f2939cSRui Paulo /**
1652325151a3SRui Paulo  * wpas_dbus_signal_p2p_invitation_result - Emit InvitationResult signal
1653325151a3SRui Paulo  * @wpa_s: %wpa_supplicant network interface data
1654325151a3SRui Paulo  * @status: Status of invitation process
1655d4f2939cSRui Paulo  * @bssid: Basic Service Set Identifier
1656d4f2939cSRui Paulo  */
1657d4f2939cSRui Paulo void wpas_dbus_signal_p2p_invitation_result(struct wpa_supplicant *wpa_s,
1658d4f2939cSRui Paulo 					    int status, const u8 *bssid)
1659d4f2939cSRui Paulo {
1660d4f2939cSRui Paulo 	DBusMessage *msg;
1661d4f2939cSRui Paulo 	DBusMessageIter iter, dict_iter;
1662d4f2939cSRui Paulo 	struct wpas_dbus_priv *iface;
1663d4f2939cSRui Paulo 
16645b9c547cSRui Paulo 	wpa_printf(MSG_DEBUG, "%s", __func__);
1665d4f2939cSRui Paulo 
1666d4f2939cSRui Paulo 	iface = wpa_s->global->dbus;
1667d4f2939cSRui Paulo 	/* Do nothing if the control interface is not turned on */
1668d4f2939cSRui Paulo 	if (iface == NULL)
1669d4f2939cSRui Paulo 		return;
1670d4f2939cSRui Paulo 
16715b9c547cSRui Paulo 	if (wpa_s->p2p_mgmt)
16725b9c547cSRui Paulo 		wpa_s = wpa_s->parent;
1673325151a3SRui Paulo 	if (!wpa_s->dbus_new_path)
1674325151a3SRui Paulo 		return;
16755b9c547cSRui Paulo 
1676d4f2939cSRui Paulo 	msg = dbus_message_new_signal(wpa_s->dbus_new_path,
1677d4f2939cSRui Paulo 				      WPAS_DBUS_NEW_IFACE_P2PDEVICE,
1678d4f2939cSRui Paulo 				      "InvitationResult");
1679d4f2939cSRui Paulo 
1680d4f2939cSRui Paulo 	if (msg == NULL)
1681d4f2939cSRui Paulo 		return;
1682d4f2939cSRui Paulo 
1683d4f2939cSRui Paulo 	dbus_message_iter_init_append(msg, &iter);
16845b9c547cSRui Paulo 	if (!wpa_dbus_dict_open_write(&iter, &dict_iter) ||
16855b9c547cSRui Paulo 	    !wpa_dbus_dict_append_int32(&dict_iter, "status", status) ||
16865b9c547cSRui Paulo 	    (bssid &&
16875b9c547cSRui Paulo 	     !wpa_dbus_dict_append_byte_array(&dict_iter, "BSSID",
1688d4f2939cSRui Paulo 					      (const char *) bssid,
16895b9c547cSRui Paulo 					      ETH_ALEN)) ||
16905b9c547cSRui Paulo 	    !wpa_dbus_dict_close_write(&iter, &dict_iter))
16915b9c547cSRui Paulo 		wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
16925b9c547cSRui Paulo 	else
1693d4f2939cSRui Paulo 		dbus_connection_send(iface->con, msg, NULL);
1694d4f2939cSRui Paulo 	dbus_message_unref(msg);
1695d4f2939cSRui Paulo }
1696d4f2939cSRui Paulo 
1697d4f2939cSRui Paulo 
1698d4f2939cSRui Paulo /**
1699d4f2939cSRui Paulo  *
1700d4f2939cSRui Paulo  * Method to emit a signal for a peer joining the group.
1701d4f2939cSRui Paulo  * The signal will carry path to the group member object
1702d4f2939cSRui Paulo  * constructed using p2p i/f addr used for connecting.
1703d4f2939cSRui Paulo  *
1704d4f2939cSRui Paulo  * @wpa_s: %wpa_supplicant network interface data
17055b9c547cSRui Paulo  * @peer_addr: P2P Device Address of the peer joining the group
1706d4f2939cSRui Paulo  */
1707d4f2939cSRui Paulo void wpas_dbus_signal_p2p_peer_joined(struct wpa_supplicant *wpa_s,
17085b9c547cSRui Paulo 				      const u8 *peer_addr)
1709d4f2939cSRui Paulo {
1710d4f2939cSRui Paulo 	struct wpas_dbus_priv *iface;
1711d4f2939cSRui Paulo 	DBusMessage *msg;
1712d4f2939cSRui Paulo 	DBusMessageIter iter;
17135b9c547cSRui Paulo 	char peer_obj_path[WPAS_DBUS_OBJECT_PATH_MAX], *path;
17145b9c547cSRui Paulo 	struct wpa_supplicant *parent;
1715d4f2939cSRui Paulo 
1716d4f2939cSRui Paulo 	iface = wpa_s->global->dbus;
1717d4f2939cSRui Paulo 
1718d4f2939cSRui Paulo 	/* Do nothing if the control interface is not turned on */
1719d4f2939cSRui Paulo 	if (iface == NULL)
1720d4f2939cSRui Paulo 		return;
1721d4f2939cSRui Paulo 
1722d4f2939cSRui Paulo 	if (!wpa_s->dbus_groupobj_path)
1723d4f2939cSRui Paulo 		return;
1724d4f2939cSRui Paulo 
17255b9c547cSRui Paulo 	parent = wpa_s->parent;
17265b9c547cSRui Paulo 	if (parent->p2p_mgmt)
17275b9c547cSRui Paulo 		parent = parent->parent;
1728325151a3SRui Paulo 	if (!parent->dbus_new_path)
1729325151a3SRui Paulo 		return;
17305b9c547cSRui Paulo 
17315b9c547cSRui Paulo 	os_snprintf(peer_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
17325b9c547cSRui Paulo 			"%s/" WPAS_DBUS_NEW_P2P_PEERS_PART "/"
1733d4f2939cSRui Paulo 			COMPACT_MACSTR,
17345b9c547cSRui Paulo 			parent->dbus_new_path, MAC2STR(peer_addr));
1735d4f2939cSRui Paulo 
1736d4f2939cSRui Paulo 	msg = dbus_message_new_signal(wpa_s->dbus_groupobj_path,
1737d4f2939cSRui Paulo 				      WPAS_DBUS_NEW_IFACE_P2P_GROUP,
1738d4f2939cSRui Paulo 				      "PeerJoined");
1739d4f2939cSRui Paulo 	if (msg == NULL)
1740d4f2939cSRui Paulo 		return;
1741d4f2939cSRui Paulo 
1742d4f2939cSRui Paulo 	dbus_message_iter_init_append(msg, &iter);
17435b9c547cSRui Paulo 	path = peer_obj_path;
1744d4f2939cSRui Paulo 	if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_OBJECT_PATH,
17455b9c547cSRui Paulo 					    &path)) {
1746d4f2939cSRui Paulo 		wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
17475b9c547cSRui Paulo 	} else {
17485b9c547cSRui Paulo 		dbus_connection_send(iface->con, msg, NULL);
17495b9c547cSRui Paulo 		wpas_dbus_signal_peer_groups_changed(parent, peer_addr);
17505b9c547cSRui Paulo 	}
1751d4f2939cSRui Paulo 	dbus_message_unref(msg);
1752d4f2939cSRui Paulo }
1753d4f2939cSRui Paulo 
1754d4f2939cSRui Paulo 
1755d4f2939cSRui Paulo /**
1756d4f2939cSRui Paulo  *
1757d4f2939cSRui Paulo  * Method to emit a signal for a peer disconnecting the group.
1758d4f2939cSRui Paulo  * The signal will carry path to the group member object
17595b9c547cSRui Paulo  * constructed using the P2P Device Address of the peer.
1760d4f2939cSRui Paulo  *
1761d4f2939cSRui Paulo  * @wpa_s: %wpa_supplicant network interface data
17625b9c547cSRui Paulo  * @peer_addr: P2P Device Address of the peer joining the group
1763d4f2939cSRui Paulo  */
1764d4f2939cSRui Paulo void wpas_dbus_signal_p2p_peer_disconnected(struct wpa_supplicant *wpa_s,
17655b9c547cSRui Paulo 					    const u8 *peer_addr)
1766d4f2939cSRui Paulo {
1767d4f2939cSRui Paulo 	struct wpas_dbus_priv *iface;
1768d4f2939cSRui Paulo 	DBusMessage *msg;
1769d4f2939cSRui Paulo 	DBusMessageIter iter;
17705b9c547cSRui Paulo 	char peer_obj_path[WPAS_DBUS_OBJECT_PATH_MAX], *path;
17715b9c547cSRui Paulo 	struct wpa_supplicant *parent;
1772d4f2939cSRui Paulo 
1773d4f2939cSRui Paulo 	iface = wpa_s->global->dbus;
1774d4f2939cSRui Paulo 
1775d4f2939cSRui Paulo 	/* Do nothing if the control interface is not turned on */
1776d4f2939cSRui Paulo 	if (iface == NULL)
1777d4f2939cSRui Paulo 		return;
1778d4f2939cSRui Paulo 
1779d4f2939cSRui Paulo 	if (!wpa_s->dbus_groupobj_path)
1780d4f2939cSRui Paulo 		return;
1781d4f2939cSRui Paulo 
17825b9c547cSRui Paulo 	parent = wpa_s->parent;
17835b9c547cSRui Paulo 	if (parent->p2p_mgmt)
17845b9c547cSRui Paulo 		parent = parent->parent;
1785325151a3SRui Paulo 	if (!parent->dbus_new_path)
1786325151a3SRui Paulo 		return;
17875b9c547cSRui Paulo 
17885b9c547cSRui Paulo 	os_snprintf(peer_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
17895b9c547cSRui Paulo 			"%s/" WPAS_DBUS_NEW_P2P_PEERS_PART "/"
1790d4f2939cSRui Paulo 			COMPACT_MACSTR,
17915b9c547cSRui Paulo 			parent->dbus_new_path, MAC2STR(peer_addr));
1792d4f2939cSRui Paulo 
1793d4f2939cSRui Paulo 	msg = dbus_message_new_signal(wpa_s->dbus_groupobj_path,
1794d4f2939cSRui Paulo 				      WPAS_DBUS_NEW_IFACE_P2P_GROUP,
1795d4f2939cSRui Paulo 				      "PeerDisconnected");
1796d4f2939cSRui Paulo 	if (msg == NULL)
1797d4f2939cSRui Paulo 		return;
1798d4f2939cSRui Paulo 
1799d4f2939cSRui Paulo 	dbus_message_iter_init_append(msg, &iter);
18005b9c547cSRui Paulo 	path = peer_obj_path;
1801d4f2939cSRui Paulo 	if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_OBJECT_PATH,
18025b9c547cSRui Paulo 					    &path)) {
18035b9c547cSRui Paulo 		wpa_printf(MSG_ERROR,
18045b9c547cSRui Paulo 			   "dbus: Failed to construct PeerDisconnected signal");
18055b9c547cSRui Paulo 	} else {
1806d4f2939cSRui Paulo 		dbus_connection_send(iface->con, msg, NULL);
18075b9c547cSRui Paulo 		wpas_dbus_signal_peer_groups_changed(parent, peer_addr);
18085b9c547cSRui Paulo 	}
1809d4f2939cSRui Paulo 	dbus_message_unref(msg);
1810d4f2939cSRui Paulo }
1811d4f2939cSRui Paulo 
1812d4f2939cSRui Paulo 
1813d4f2939cSRui Paulo /**
1814d4f2939cSRui Paulo  *
1815d4f2939cSRui Paulo  * Method to emit a signal for a service discovery request.
1816d4f2939cSRui Paulo  * The signal will carry station address, frequency, dialog token,
1817d4f2939cSRui Paulo  * update indicator and it tlvs
1818d4f2939cSRui Paulo  *
1819d4f2939cSRui Paulo  * @wpa_s: %wpa_supplicant network interface data
1820d4f2939cSRui Paulo  * @sa: station addr (p2p i/f) of the peer
1821d4f2939cSRui Paulo  * @dialog_token: service discovery request dialog token
1822d4f2939cSRui Paulo  * @update_indic: service discovery request update indicator
1823d4f2939cSRui Paulo  * @tlvs: service discovery request genrated byte array of tlvs
1824d4f2939cSRui Paulo  * @tlvs_len: service discovery request tlvs length
1825d4f2939cSRui Paulo  */
1826d4f2939cSRui Paulo void wpas_dbus_signal_p2p_sd_request(struct wpa_supplicant *wpa_s,
1827d4f2939cSRui Paulo 				     int freq, const u8 *sa, u8 dialog_token,
1828d4f2939cSRui Paulo 				     u16 update_indic, const u8 *tlvs,
1829d4f2939cSRui Paulo 				     size_t tlvs_len)
1830d4f2939cSRui Paulo {
1831d4f2939cSRui Paulo 	DBusMessage *msg;
1832d4f2939cSRui Paulo 	DBusMessageIter iter, dict_iter;
1833d4f2939cSRui Paulo 	struct wpas_dbus_priv *iface;
1834d4f2939cSRui Paulo 	char peer_obj_path[WPAS_DBUS_OBJECT_PATH_MAX], *path;
18355b9c547cSRui Paulo 
1836d4f2939cSRui Paulo 	iface = wpa_s->global->dbus;
1837d4f2939cSRui Paulo 
1838d4f2939cSRui Paulo 	/* Do nothing if the control interface is not turned on */
1839d4f2939cSRui Paulo 	if (iface == NULL)
1840d4f2939cSRui Paulo 		return;
1841d4f2939cSRui Paulo 
18425b9c547cSRui Paulo 	if (wpa_s->p2p_mgmt)
18435b9c547cSRui Paulo 		wpa_s = wpa_s->parent;
1844325151a3SRui Paulo 	if (!wpa_s->dbus_new_path)
1845325151a3SRui Paulo 		return;
18465b9c547cSRui Paulo 
18475b9c547cSRui Paulo 	/* Check if this is a known peer */
18485b9c547cSRui Paulo 	if (!p2p_peer_known(wpa_s->global->p2p, sa))
18495b9c547cSRui Paulo 		return;
18505b9c547cSRui Paulo 
1851d4f2939cSRui Paulo 	msg = dbus_message_new_signal(wpa_s->dbus_new_path,
1852d4f2939cSRui Paulo 				      WPAS_DBUS_NEW_IFACE_P2PDEVICE,
1853d4f2939cSRui Paulo 				      "ServiceDiscoveryRequest");
1854d4f2939cSRui Paulo 	if (msg == NULL)
1855d4f2939cSRui Paulo 		return;
1856d4f2939cSRui Paulo 
1857d4f2939cSRui Paulo 	os_snprintf(peer_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
1858d4f2939cSRui Paulo 		    "%s/" WPAS_DBUS_NEW_P2P_PEERS_PART "/"
1859d4f2939cSRui Paulo 		    COMPACT_MACSTR, wpa_s->dbus_new_path, MAC2STR(sa));
1860d4f2939cSRui Paulo 
1861d4f2939cSRui Paulo 	path = peer_obj_path;
1862d4f2939cSRui Paulo 
1863d4f2939cSRui Paulo 	dbus_message_iter_init_append(msg, &iter);
18645b9c547cSRui Paulo 	if (!wpa_dbus_dict_open_write(&iter, &dict_iter) ||
18655b9c547cSRui Paulo 	    !wpa_dbus_dict_append_object_path(&dict_iter, "peer_object",
1866d4f2939cSRui Paulo 					      path) ||
1867d4f2939cSRui Paulo 	    !wpa_dbus_dict_append_int32(&dict_iter, "frequency", freq) ||
1868d4f2939cSRui Paulo 	    !wpa_dbus_dict_append_int32(&dict_iter, "dialog_token",
1869d4f2939cSRui Paulo 					dialog_token) ||
1870d4f2939cSRui Paulo 	    !wpa_dbus_dict_append_uint16(&dict_iter, "update_indicator",
1871d4f2939cSRui Paulo 					 update_indic) ||
1872d4f2939cSRui Paulo 	    !wpa_dbus_dict_append_byte_array(&dict_iter, "tlvs",
1873d4f2939cSRui Paulo 					     (const char *) tlvs,
1874d4f2939cSRui Paulo 					     tlvs_len) ||
1875d4f2939cSRui Paulo 	    !wpa_dbus_dict_close_write(&iter, &dict_iter))
1876d4f2939cSRui Paulo 		wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
18775b9c547cSRui Paulo 	else
18785b9c547cSRui Paulo 		dbus_connection_send(iface->con, msg, NULL);
1879d4f2939cSRui Paulo 	dbus_message_unref(msg);
1880d4f2939cSRui Paulo }
1881d4f2939cSRui Paulo 
1882d4f2939cSRui Paulo 
1883d4f2939cSRui Paulo /**
1884d4f2939cSRui Paulo  *
1885d4f2939cSRui Paulo  * Method to emit a signal for a service discovery response.
1886d4f2939cSRui Paulo  * The signal will carry station address, update indicator and it
1887d4f2939cSRui Paulo  * tlvs
1888d4f2939cSRui Paulo  *
1889d4f2939cSRui Paulo  * @wpa_s: %wpa_supplicant network interface data
1890d4f2939cSRui Paulo  * @sa: station addr (p2p i/f) of the peer
1891d4f2939cSRui Paulo  * @update_indic: service discovery request update indicator
1892d4f2939cSRui Paulo  * @tlvs: service discovery request genrated byte array of tlvs
1893d4f2939cSRui Paulo  * @tlvs_len: service discovery request tlvs length
1894d4f2939cSRui Paulo  */
1895d4f2939cSRui Paulo void wpas_dbus_signal_p2p_sd_response(struct wpa_supplicant *wpa_s,
1896d4f2939cSRui Paulo 				      const u8 *sa, u16 update_indic,
1897d4f2939cSRui Paulo 				      const u8 *tlvs, size_t tlvs_len)
1898d4f2939cSRui Paulo {
1899d4f2939cSRui Paulo 	DBusMessage *msg;
1900d4f2939cSRui Paulo 	DBusMessageIter iter, dict_iter;
1901d4f2939cSRui Paulo 	struct wpas_dbus_priv *iface;
1902d4f2939cSRui Paulo 	char peer_obj_path[WPAS_DBUS_OBJECT_PATH_MAX], *path;
19035b9c547cSRui Paulo 
1904d4f2939cSRui Paulo 	iface = wpa_s->global->dbus;
1905d4f2939cSRui Paulo 
1906d4f2939cSRui Paulo 	/* Do nothing if the control interface is not turned on */
1907d4f2939cSRui Paulo 	if (iface == NULL)
1908d4f2939cSRui Paulo 		return;
1909d4f2939cSRui Paulo 
19105b9c547cSRui Paulo 	if (wpa_s->p2p_mgmt)
19115b9c547cSRui Paulo 		wpa_s = wpa_s->parent;
1912325151a3SRui Paulo 	if (!wpa_s->dbus_new_path)
1913325151a3SRui Paulo 		return;
19145b9c547cSRui Paulo 
19155b9c547cSRui Paulo 	/* Check if this is a known peer */
19165b9c547cSRui Paulo 	if (!p2p_peer_known(wpa_s->global->p2p, sa))
19175b9c547cSRui Paulo 		return;
19185b9c547cSRui Paulo 
1919d4f2939cSRui Paulo 	msg = dbus_message_new_signal(wpa_s->dbus_new_path,
1920d4f2939cSRui Paulo 				      WPAS_DBUS_NEW_IFACE_P2PDEVICE,
1921d4f2939cSRui Paulo 				      "ServiceDiscoveryResponse");
1922d4f2939cSRui Paulo 	if (msg == NULL)
1923d4f2939cSRui Paulo 		return;
1924d4f2939cSRui Paulo 
1925d4f2939cSRui Paulo 	os_snprintf(peer_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
1926d4f2939cSRui Paulo 		    "%s/" WPAS_DBUS_NEW_P2P_PEERS_PART "/"
1927d4f2939cSRui Paulo 		    COMPACT_MACSTR, wpa_s->dbus_new_path, MAC2STR(sa));
1928d4f2939cSRui Paulo 
1929d4f2939cSRui Paulo 	path = peer_obj_path;
1930d4f2939cSRui Paulo 
1931d4f2939cSRui Paulo 	dbus_message_iter_init_append(msg, &iter);
19325b9c547cSRui Paulo 	if (!wpa_dbus_dict_open_write(&iter, &dict_iter) ||
19335b9c547cSRui Paulo 	    !wpa_dbus_dict_append_object_path(&dict_iter, "peer_object",
1934d4f2939cSRui Paulo 					      path) ||
1935d4f2939cSRui Paulo 	    !wpa_dbus_dict_append_uint16(&dict_iter, "update_indicator",
1936d4f2939cSRui Paulo 					 update_indic) ||
1937d4f2939cSRui Paulo 	    !wpa_dbus_dict_append_byte_array(&dict_iter, "tlvs",
1938d4f2939cSRui Paulo 					     (const char *) tlvs,
1939d4f2939cSRui Paulo 					     tlvs_len) ||
1940d4f2939cSRui Paulo 	    !wpa_dbus_dict_close_write(&iter, &dict_iter))
19415b9c547cSRui Paulo 		wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
19425b9c547cSRui Paulo 	else
1943d4f2939cSRui Paulo 		dbus_connection_send(iface->con, msg, NULL);
1944d4f2939cSRui Paulo 	dbus_message_unref(msg);
1945d4f2939cSRui Paulo }
1946d4f2939cSRui Paulo 
19475b9c547cSRui Paulo 
1948d4f2939cSRui Paulo /**
1949d4f2939cSRui Paulo  * wpas_dbus_signal_persistent_group - Send a persistent group related
1950d4f2939cSRui Paulo  *	event signal
1951d4f2939cSRui Paulo  * @wpa_s: %wpa_supplicant network interface data
1952d4f2939cSRui Paulo  * @id: new persistent group id
1953d4f2939cSRui Paulo  * @sig_name: signal name - PersistentGroupAdded, PersistentGroupRemoved
1954d4f2939cSRui Paulo  * @properties: determines if add second argument with object properties
1955d4f2939cSRui Paulo  *
1956d4f2939cSRui Paulo  * Notify listeners about an event related to persistent groups.
1957d4f2939cSRui Paulo  */
1958d4f2939cSRui Paulo static void wpas_dbus_signal_persistent_group(struct wpa_supplicant *wpa_s,
1959d4f2939cSRui Paulo 					      int id, const char *sig_name,
1960*4bc52338SCy Schubert 					      dbus_bool_t properties)
1961d4f2939cSRui Paulo {
1962d4f2939cSRui Paulo 	struct wpas_dbus_priv *iface;
1963d4f2939cSRui Paulo 	DBusMessage *msg;
1964d4f2939cSRui Paulo 	DBusMessageIter iter;
1965d4f2939cSRui Paulo 	char pgrp_obj_path[WPAS_DBUS_OBJECT_PATH_MAX], *path;
1966d4f2939cSRui Paulo 
1967d4f2939cSRui Paulo 	iface = wpa_s->global->dbus;
1968d4f2939cSRui Paulo 
1969d4f2939cSRui Paulo 	/* Do nothing if the control interface is not turned on */
1970d4f2939cSRui Paulo 	if (iface == NULL)
1971d4f2939cSRui Paulo 		return;
1972d4f2939cSRui Paulo 
19735b9c547cSRui Paulo 	if (wpa_s->p2p_mgmt)
19745b9c547cSRui Paulo 		wpa_s = wpa_s->parent;
1975325151a3SRui Paulo 	if (!wpa_s->dbus_new_path)
1976325151a3SRui Paulo 		return;
19775b9c547cSRui Paulo 
1978d4f2939cSRui Paulo 	os_snprintf(pgrp_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
1979d4f2939cSRui Paulo 		    "%s/" WPAS_DBUS_NEW_PERSISTENT_GROUPS_PART "/%u",
1980d4f2939cSRui Paulo 		    wpa_s->dbus_new_path, id);
1981d4f2939cSRui Paulo 
1982d4f2939cSRui Paulo 	msg = dbus_message_new_signal(wpa_s->dbus_new_path,
1983d4f2939cSRui Paulo 				      WPAS_DBUS_NEW_IFACE_P2PDEVICE,
1984d4f2939cSRui Paulo 				      sig_name);
1985d4f2939cSRui Paulo 	if (msg == NULL)
1986d4f2939cSRui Paulo 		return;
1987d4f2939cSRui Paulo 
1988d4f2939cSRui Paulo 	dbus_message_iter_init_append(msg, &iter);
1989d4f2939cSRui Paulo 	path = pgrp_obj_path;
1990d4f2939cSRui Paulo 	if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_OBJECT_PATH,
19915b9c547cSRui Paulo 					    &path) ||
19925b9c547cSRui Paulo 	    (properties &&
19935b9c547cSRui Paulo 	     !wpa_dbus_get_object_properties(
1994d4f2939cSRui Paulo 		     iface, pgrp_obj_path,
19955b9c547cSRui Paulo 		     WPAS_DBUS_NEW_IFACE_PERSISTENT_GROUP, &iter)))
19965b9c547cSRui Paulo 		wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
19975b9c547cSRui Paulo 	else
1998d4f2939cSRui Paulo 		dbus_connection_send(iface->con, msg, NULL);
1999d4f2939cSRui Paulo 
2000d4f2939cSRui Paulo 	dbus_message_unref(msg);
2001d4f2939cSRui Paulo }
2002d4f2939cSRui Paulo 
2003d4f2939cSRui Paulo 
2004d4f2939cSRui Paulo /**
2005d4f2939cSRui Paulo  * wpas_dbus_signal_persistent_group_added - Send a persistent_group
2006d4f2939cSRui Paulo  *	added signal
2007d4f2939cSRui Paulo  * @wpa_s: %wpa_supplicant network interface data
2008d4f2939cSRui Paulo  * @id: new persistent group id
2009d4f2939cSRui Paulo  *
2010d4f2939cSRui Paulo  * Notify listeners about addition of a new persistent group.
2011d4f2939cSRui Paulo  */
2012d4f2939cSRui Paulo static void wpas_dbus_signal_persistent_group_added(
2013d4f2939cSRui Paulo 	struct wpa_supplicant *wpa_s, int id)
2014d4f2939cSRui Paulo {
2015d4f2939cSRui Paulo 	wpas_dbus_signal_persistent_group(wpa_s, id, "PersistentGroupAdded",
2016d4f2939cSRui Paulo 					  TRUE);
2017d4f2939cSRui Paulo }
2018d4f2939cSRui Paulo 
2019d4f2939cSRui Paulo 
2020d4f2939cSRui Paulo /**
2021d4f2939cSRui Paulo  * wpas_dbus_signal_persistent_group_removed - Send a persistent_group
2022d4f2939cSRui Paulo  *	removed signal
2023d4f2939cSRui Paulo  * @wpa_s: %wpa_supplicant network interface data
2024d4f2939cSRui Paulo  * @id: persistent group id
2025d4f2939cSRui Paulo  *
2026d4f2939cSRui Paulo  * Notify listeners about removal of a persistent group.
2027d4f2939cSRui Paulo  */
2028d4f2939cSRui Paulo static void wpas_dbus_signal_persistent_group_removed(
2029d4f2939cSRui Paulo 	struct wpa_supplicant *wpa_s, int id)
2030d4f2939cSRui Paulo {
2031d4f2939cSRui Paulo 	wpas_dbus_signal_persistent_group(wpa_s, id, "PersistentGroupRemoved",
2032d4f2939cSRui Paulo 					  FALSE);
2033d4f2939cSRui Paulo }
2034d4f2939cSRui Paulo 
2035d4f2939cSRui Paulo 
2036d4f2939cSRui Paulo /**
2037d4f2939cSRui Paulo  * wpas_dbus_signal_p2p_wps_failed - Signals WpsFailed event
2038d4f2939cSRui Paulo  * @wpa_s: %wpa_supplicant network interface data
2039325151a3SRui Paulo  * @fail: WPS failure information
2040d4f2939cSRui Paulo  *
2041d4f2939cSRui Paulo  * Sends Event dbus signal with name "fail" and dictionary containing
2042d4f2939cSRui Paulo  * "msg" field with fail message number (int32) as arguments
2043d4f2939cSRui Paulo  */
2044d4f2939cSRui Paulo void wpas_dbus_signal_p2p_wps_failed(struct wpa_supplicant *wpa_s,
2045d4f2939cSRui Paulo 				     struct wps_event_fail *fail)
2046d4f2939cSRui Paulo {
2047d4f2939cSRui Paulo 
2048d4f2939cSRui Paulo 	DBusMessage *msg;
2049d4f2939cSRui Paulo 	DBusMessageIter iter, dict_iter;
2050d4f2939cSRui Paulo 	struct wpas_dbus_priv *iface;
2051d4f2939cSRui Paulo 	char *key = "fail";
2052d4f2939cSRui Paulo 
2053d4f2939cSRui Paulo 	iface = wpa_s->global->dbus;
2054d4f2939cSRui Paulo 
2055d4f2939cSRui Paulo 	/* Do nothing if the control interface is not turned on */
2056d4f2939cSRui Paulo 	if (iface == NULL)
2057d4f2939cSRui Paulo 		return;
2058d4f2939cSRui Paulo 
20595b9c547cSRui Paulo 	if (wpa_s->p2p_mgmt)
20605b9c547cSRui Paulo 		wpa_s = wpa_s->parent;
20615b9c547cSRui Paulo 
2062325151a3SRui Paulo 	if (!wpa_s->dbus_new_path)
2063325151a3SRui Paulo 		return;
2064d4f2939cSRui Paulo 	msg = dbus_message_new_signal(wpa_s->dbus_new_path,
2065d4f2939cSRui Paulo 				      WPAS_DBUS_NEW_IFACE_P2PDEVICE,
2066d4f2939cSRui Paulo 				      "WpsFailed");
2067d4f2939cSRui Paulo 	if (msg == NULL)
2068d4f2939cSRui Paulo 		return;
2069d4f2939cSRui Paulo 
2070d4f2939cSRui Paulo 	dbus_message_iter_init_append(msg, &iter);
2071d4f2939cSRui Paulo 
2072d4f2939cSRui Paulo 	if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &key) ||
2073d4f2939cSRui Paulo 	    !wpa_dbus_dict_open_write(&iter, &dict_iter) ||
2074d4f2939cSRui Paulo 	    !wpa_dbus_dict_append_int32(&dict_iter, "msg", fail->msg) ||
2075d4f2939cSRui Paulo 	    !wpa_dbus_dict_append_int16(&dict_iter, "config_error",
2076d4f2939cSRui Paulo 					fail->config_error) ||
2077d4f2939cSRui Paulo 	    !wpa_dbus_dict_close_write(&iter, &dict_iter))
2078d4f2939cSRui Paulo 		wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
2079d4f2939cSRui Paulo 	else
2080d4f2939cSRui Paulo 		dbus_connection_send(iface->con, msg, NULL);
2081d4f2939cSRui Paulo 
2082d4f2939cSRui Paulo 	dbus_message_unref(msg);
2083d4f2939cSRui Paulo }
2084d4f2939cSRui Paulo 
2085325151a3SRui Paulo 
2086325151a3SRui Paulo /**
2087325151a3SRui Paulo  * wpas_dbus_signal_p2p_group_formation_failure - Signals GroupFormationFailure event
2088325151a3SRui Paulo  * @wpa_s: %wpa_supplicant network interface data
2089325151a3SRui Paulo  * @reason: indicates the reason code for group formation failure
2090325151a3SRui Paulo  *
2091325151a3SRui Paulo  * Sends Event dbus signal and string reason code when available.
2092325151a3SRui Paulo  */
2093325151a3SRui Paulo void wpas_dbus_signal_p2p_group_formation_failure(struct wpa_supplicant *wpa_s,
2094325151a3SRui Paulo 						  const char *reason)
2095325151a3SRui Paulo {
2096325151a3SRui Paulo 	DBusMessage *msg;
2097325151a3SRui Paulo 	struct wpas_dbus_priv *iface;
2098325151a3SRui Paulo 
2099325151a3SRui Paulo 	iface = wpa_s->global->dbus;
2100325151a3SRui Paulo 
2101325151a3SRui Paulo 	/* Do nothing if the control interface is not turned on */
2102325151a3SRui Paulo 	if (iface == NULL)
2103325151a3SRui Paulo 		return;
2104325151a3SRui Paulo 
210585732ac8SCy Schubert 	if (wpa_s->p2p_mgmt)
210685732ac8SCy Schubert 		wpa_s = wpa_s->parent;
210785732ac8SCy Schubert 
2108325151a3SRui Paulo 	msg = dbus_message_new_signal(wpa_s->dbus_new_path,
2109325151a3SRui Paulo 				      WPAS_DBUS_NEW_IFACE_P2PDEVICE,
2110325151a3SRui Paulo 				      "GroupFormationFailure");
2111325151a3SRui Paulo 	if (msg == NULL)
2112325151a3SRui Paulo 		return;
2113325151a3SRui Paulo 
2114325151a3SRui Paulo 	if (dbus_message_append_args(msg, DBUS_TYPE_STRING, &reason,
2115325151a3SRui Paulo 				     DBUS_TYPE_INVALID))
2116325151a3SRui Paulo 		dbus_connection_send(iface->con, msg, NULL);
2117325151a3SRui Paulo 	else
2118325151a3SRui Paulo 		wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
2119325151a3SRui Paulo 
2120325151a3SRui Paulo 	dbus_message_unref(msg);
2121325151a3SRui Paulo }
2122325151a3SRui Paulo 
2123325151a3SRui Paulo 
2124325151a3SRui Paulo /**
2125325151a3SRui Paulo  * wpas_dbus_signal_p2p_invitation_received - Emit InvitationReceived signal
2126325151a3SRui Paulo  * @wpa_s: %wpa_supplicant network interface data
2127325151a3SRui Paulo  * @sa: Source address of the Invitation Request
2128325151a3SRui Paulo  * @dev_add: GO Device Address
2129325151a3SRui Paulo  * @bssid: P2P Group BSSID or %NULL if not received
2130325151a3SRui Paulo  * @id: Persistent group id or %0 if not persistent group
2131325151a3SRui Paulo  * @op_freq: Operating frequency for the group
2132325151a3SRui Paulo  */
2133325151a3SRui Paulo 
2134325151a3SRui Paulo void wpas_dbus_signal_p2p_invitation_received(struct wpa_supplicant *wpa_s,
2135325151a3SRui Paulo 					      const u8 *sa, const u8 *dev_addr,
2136325151a3SRui Paulo 					      const u8 *bssid, int id,
2137325151a3SRui Paulo 					      int op_freq)
2138325151a3SRui Paulo {
2139325151a3SRui Paulo 	DBusMessage *msg;
2140325151a3SRui Paulo 	DBusMessageIter iter, dict_iter;
2141325151a3SRui Paulo 	struct wpas_dbus_priv *iface;
2142325151a3SRui Paulo 
2143325151a3SRui Paulo 	iface = wpa_s->global->dbus;
2144325151a3SRui Paulo 
2145325151a3SRui Paulo 	/* Do nothing if the control interface is not turned on */
2146325151a3SRui Paulo 	if (iface == NULL)
2147325151a3SRui Paulo 		return;
2148325151a3SRui Paulo 
214985732ac8SCy Schubert 	if (wpa_s->p2p_mgmt)
215085732ac8SCy Schubert 		wpa_s = wpa_s->parent;
215185732ac8SCy Schubert 
2152325151a3SRui Paulo 	msg = dbus_message_new_signal(wpa_s->dbus_new_path,
2153325151a3SRui Paulo 				      WPAS_DBUS_NEW_IFACE_P2PDEVICE,
2154325151a3SRui Paulo 				      "InvitationReceived");
2155325151a3SRui Paulo 	if (msg == NULL)
2156325151a3SRui Paulo 		return;
2157325151a3SRui Paulo 
2158325151a3SRui Paulo 	dbus_message_iter_init_append(msg, &iter);
2159325151a3SRui Paulo 	if (!wpa_dbus_dict_open_write(&iter, &dict_iter) ||
2160325151a3SRui Paulo 	    (sa &&
2161325151a3SRui Paulo 	     !wpa_dbus_dict_append_byte_array(&dict_iter, "sa",
2162325151a3SRui Paulo 					      (const char *) sa, ETH_ALEN)) ||
2163325151a3SRui Paulo 	    (dev_addr &&
2164325151a3SRui Paulo 	     !wpa_dbus_dict_append_byte_array(&dict_iter, "go_dev_addr",
2165325151a3SRui Paulo 					      (const char *) dev_addr,
2166325151a3SRui Paulo 					      ETH_ALEN)) ||
2167325151a3SRui Paulo 	    (bssid &&
2168325151a3SRui Paulo 	     !wpa_dbus_dict_append_byte_array(&dict_iter, "bssid",
2169325151a3SRui Paulo 					      (const char *) bssid,
2170325151a3SRui Paulo 					      ETH_ALEN)) ||
2171325151a3SRui Paulo 	    (id &&
2172325151a3SRui Paulo 	     !wpa_dbus_dict_append_int32(&dict_iter, "persistent_id", id)) ||
2173325151a3SRui Paulo 	    !wpa_dbus_dict_append_int32(&dict_iter, "op_freq", op_freq) ||
2174325151a3SRui Paulo 	    !wpa_dbus_dict_close_write(&iter, &dict_iter)) {
2175325151a3SRui Paulo 		dbus_message_unref(msg);
2176325151a3SRui Paulo 		return;
2177325151a3SRui Paulo 	}
2178325151a3SRui Paulo 
2179325151a3SRui Paulo 	dbus_connection_send(iface->con, msg, NULL);
2180780fb4a2SCy Schubert 	dbus_message_unref(msg);
2181325151a3SRui Paulo }
2182325151a3SRui Paulo 
2183325151a3SRui Paulo 
2184d4f2939cSRui Paulo #endif /* CONFIG_P2P */
2185d4f2939cSRui Paulo 
2186d4f2939cSRui Paulo 
2187d4f2939cSRui Paulo /**
2188d4f2939cSRui Paulo  * wpas_dbus_signal_prop_changed - Signals change of property
2189d4f2939cSRui Paulo  * @wpa_s: %wpa_supplicant network interface data
2190d4f2939cSRui Paulo  * @property: indicates which property has changed
2191d4f2939cSRui Paulo  *
2192d4f2939cSRui Paulo  * Sends PropertyChanged signals with path, interface and arguments
2193d4f2939cSRui Paulo  * depending on which property has changed.
2194d4f2939cSRui Paulo  */
2195d4f2939cSRui Paulo void wpas_dbus_signal_prop_changed(struct wpa_supplicant *wpa_s,
2196d4f2939cSRui Paulo 				   enum wpas_dbus_prop property)
2197d4f2939cSRui Paulo {
2198d4f2939cSRui Paulo 	char *prop;
2199d4f2939cSRui Paulo 	dbus_bool_t flush;
2200d4f2939cSRui Paulo 
2201d4f2939cSRui Paulo 	if (wpa_s->dbus_new_path == NULL)
2202d4f2939cSRui Paulo 		return; /* Skip signal since D-Bus setup is not yet ready */
2203d4f2939cSRui Paulo 
2204d4f2939cSRui Paulo 	flush = FALSE;
2205d4f2939cSRui Paulo 	switch (property) {
2206d4f2939cSRui Paulo 	case WPAS_DBUS_PROP_AP_SCAN:
2207d4f2939cSRui Paulo 		prop = "ApScan";
2208d4f2939cSRui Paulo 		break;
2209d4f2939cSRui Paulo 	case WPAS_DBUS_PROP_SCANNING:
2210d4f2939cSRui Paulo 		prop = "Scanning";
2211d4f2939cSRui Paulo 		break;
2212d4f2939cSRui Paulo 	case WPAS_DBUS_PROP_STATE:
2213d4f2939cSRui Paulo 		prop = "State";
2214d4f2939cSRui Paulo 		break;
2215d4f2939cSRui Paulo 	case WPAS_DBUS_PROP_CURRENT_BSS:
2216d4f2939cSRui Paulo 		prop = "CurrentBSS";
2217d4f2939cSRui Paulo 		break;
2218d4f2939cSRui Paulo 	case WPAS_DBUS_PROP_CURRENT_NETWORK:
2219d4f2939cSRui Paulo 		prop = "CurrentNetwork";
2220d4f2939cSRui Paulo 		break;
2221d4f2939cSRui Paulo 	case WPAS_DBUS_PROP_BSSS:
2222d4f2939cSRui Paulo 		prop = "BSSs";
2223d4f2939cSRui Paulo 		break;
2224*4bc52338SCy Schubert 	case WPAS_DBUS_PROP_STATIONS:
2225*4bc52338SCy Schubert 		prop = "Stations";
2226*4bc52338SCy Schubert 		break;
2227d4f2939cSRui Paulo 	case WPAS_DBUS_PROP_CURRENT_AUTH_MODE:
2228d4f2939cSRui Paulo 		prop = "CurrentAuthMode";
2229d4f2939cSRui Paulo 		break;
2230d4f2939cSRui Paulo 	case WPAS_DBUS_PROP_DISCONNECT_REASON:
2231d4f2939cSRui Paulo 		prop = "DisconnectReason";
2232d4f2939cSRui Paulo 		flush = TRUE;
2233d4f2939cSRui Paulo 		break;
2234*4bc52338SCy Schubert 	case WPAS_DBUS_PROP_AUTH_STATUS_CODE:
2235*4bc52338SCy Schubert 		prop = "AuthStatusCode";
2236*4bc52338SCy Schubert 		flush = TRUE;
2237*4bc52338SCy Schubert 		break;
2238780fb4a2SCy Schubert 	case WPAS_DBUS_PROP_ASSOC_STATUS_CODE:
2239780fb4a2SCy Schubert 		prop = "AssocStatusCode";
2240780fb4a2SCy Schubert 		flush = TRUE;
2241780fb4a2SCy Schubert 		break;
2242*4bc52338SCy Schubert 	case WPAS_DBUS_PROP_ROAM_TIME:
2243*4bc52338SCy Schubert 		prop = "RoamTime";
2244*4bc52338SCy Schubert 		break;
2245*4bc52338SCy Schubert 	case WPAS_DBUS_PROP_ROAM_COMPLETE:
2246*4bc52338SCy Schubert 		prop = "RoamComplete";
2247*4bc52338SCy Schubert 		break;
2248*4bc52338SCy Schubert 	case WPAS_DBUS_PROP_SESSION_LENGTH:
2249*4bc52338SCy Schubert 		prop = "SessionLength";
2250*4bc52338SCy Schubert 		break;
2251*4bc52338SCy Schubert 	case WPAS_DBUS_PROP_BSS_TM_STATUS:
2252*4bc52338SCy Schubert 		prop = "BSSTMStatus";
2253*4bc52338SCy Schubert 		break;
2254d4f2939cSRui Paulo 	default:
2255d4f2939cSRui Paulo 		wpa_printf(MSG_ERROR, "dbus: %s: Unknown Property value %d",
2256d4f2939cSRui Paulo 			   __func__, property);
2257d4f2939cSRui Paulo 		return;
2258d4f2939cSRui Paulo 	}
2259d4f2939cSRui Paulo 
2260d4f2939cSRui Paulo 	wpa_dbus_mark_property_changed(wpa_s->global->dbus,
2261d4f2939cSRui Paulo 				       wpa_s->dbus_new_path,
2262d4f2939cSRui Paulo 				       WPAS_DBUS_NEW_IFACE_INTERFACE, prop);
2263d4f2939cSRui Paulo 	if (flush) {
2264d4f2939cSRui Paulo 		wpa_dbus_flush_object_changed_properties(
2265d4f2939cSRui Paulo 			wpa_s->global->dbus->con, wpa_s->dbus_new_path);
2266d4f2939cSRui Paulo 	}
2267d4f2939cSRui Paulo }
2268d4f2939cSRui Paulo 
2269d4f2939cSRui Paulo 
2270d4f2939cSRui Paulo /**
2271d4f2939cSRui Paulo  * wpas_dbus_bss_signal_prop_changed - Signals change of BSS property
2272d4f2939cSRui Paulo  * @wpa_s: %wpa_supplicant network interface data
2273d4f2939cSRui Paulo  * @property: indicates which property has changed
2274d4f2939cSRui Paulo  * @id: unique BSS identifier
2275d4f2939cSRui Paulo  *
2276d4f2939cSRui Paulo  * Sends PropertyChanged signals with path, interface, and arguments depending
2277d4f2939cSRui Paulo  * on which property has changed.
2278d4f2939cSRui Paulo  */
2279d4f2939cSRui Paulo void wpas_dbus_bss_signal_prop_changed(struct wpa_supplicant *wpa_s,
2280d4f2939cSRui Paulo 				       enum wpas_dbus_bss_prop property,
2281d4f2939cSRui Paulo 				       unsigned int id)
2282d4f2939cSRui Paulo {
2283d4f2939cSRui Paulo 	char path[WPAS_DBUS_OBJECT_PATH_MAX];
2284d4f2939cSRui Paulo 	char *prop;
2285d4f2939cSRui Paulo 
2286325151a3SRui Paulo 	if (!wpa_s->dbus_new_path)
2287325151a3SRui Paulo 		return;
2288325151a3SRui Paulo 
2289d4f2939cSRui Paulo 	switch (property) {
2290d4f2939cSRui Paulo 	case WPAS_DBUS_BSS_PROP_SIGNAL:
2291d4f2939cSRui Paulo 		prop = "Signal";
2292d4f2939cSRui Paulo 		break;
2293d4f2939cSRui Paulo 	case WPAS_DBUS_BSS_PROP_FREQ:
2294d4f2939cSRui Paulo 		prop = "Frequency";
2295d4f2939cSRui Paulo 		break;
2296d4f2939cSRui Paulo 	case WPAS_DBUS_BSS_PROP_MODE:
2297d4f2939cSRui Paulo 		prop = "Mode";
2298d4f2939cSRui Paulo 		break;
2299d4f2939cSRui Paulo 	case WPAS_DBUS_BSS_PROP_PRIVACY:
2300d4f2939cSRui Paulo 		prop = "Privacy";
2301d4f2939cSRui Paulo 		break;
2302d4f2939cSRui Paulo 	case WPAS_DBUS_BSS_PROP_RATES:
2303d4f2939cSRui Paulo 		prop = "Rates";
2304d4f2939cSRui Paulo 		break;
2305d4f2939cSRui Paulo 	case WPAS_DBUS_BSS_PROP_WPA:
2306d4f2939cSRui Paulo 		prop = "WPA";
2307d4f2939cSRui Paulo 		break;
2308d4f2939cSRui Paulo 	case WPAS_DBUS_BSS_PROP_RSN:
2309d4f2939cSRui Paulo 		prop = "RSN";
2310d4f2939cSRui Paulo 		break;
23115b9c547cSRui Paulo 	case WPAS_DBUS_BSS_PROP_WPS:
23125b9c547cSRui Paulo 		prop = "WPS";
23135b9c547cSRui Paulo 		break;
2314d4f2939cSRui Paulo 	case WPAS_DBUS_BSS_PROP_IES:
2315d4f2939cSRui Paulo 		prop = "IEs";
2316d4f2939cSRui Paulo 		break;
23175b9c547cSRui Paulo 	case WPAS_DBUS_BSS_PROP_AGE:
23185b9c547cSRui Paulo 		prop = "Age";
23195b9c547cSRui Paulo 		break;
2320d4f2939cSRui Paulo 	default:
2321d4f2939cSRui Paulo 		wpa_printf(MSG_ERROR, "dbus: %s: Unknown Property value %d",
2322d4f2939cSRui Paulo 			   __func__, property);
2323d4f2939cSRui Paulo 		return;
2324d4f2939cSRui Paulo 	}
2325d4f2939cSRui Paulo 
2326d4f2939cSRui Paulo 	os_snprintf(path, WPAS_DBUS_OBJECT_PATH_MAX,
2327d4f2939cSRui Paulo 		    "%s/" WPAS_DBUS_NEW_BSSIDS_PART "/%u",
2328d4f2939cSRui Paulo 		    wpa_s->dbus_new_path, id);
2329d4f2939cSRui Paulo 
2330d4f2939cSRui Paulo 	wpa_dbus_mark_property_changed(wpa_s->global->dbus, path,
2331d4f2939cSRui Paulo 				       WPAS_DBUS_NEW_IFACE_BSS, prop);
2332d4f2939cSRui Paulo }
2333d4f2939cSRui Paulo 
2334d4f2939cSRui Paulo 
2335d4f2939cSRui Paulo /**
2336*4bc52338SCy Schubert  * wpas_dbus_sta_signal_prop_changed - Signals change of STA property
2337*4bc52338SCy Schubert  * @wpa_s: %wpa_supplicant network interface data
2338*4bc52338SCy Schubert  * @property: indicates which property has changed
2339*4bc52338SCy Schubert  * @address: unique BSS identifier
2340*4bc52338SCy Schubert  *
2341*4bc52338SCy Schubert  * Sends PropertyChanged signals with path, interface, and arguments depending
2342*4bc52338SCy Schubert  * on which property has changed.
2343*4bc52338SCy Schubert  */
2344*4bc52338SCy Schubert void wpas_dbus_sta_signal_prop_changed(struct wpa_supplicant *wpa_s,
2345*4bc52338SCy Schubert 				       enum wpas_dbus_bss_prop property,
2346*4bc52338SCy Schubert 				       u8 address[ETH_ALEN])
2347*4bc52338SCy Schubert {
2348*4bc52338SCy Schubert 	char path[WPAS_DBUS_OBJECT_PATH_MAX];
2349*4bc52338SCy Schubert 	char *prop;
2350*4bc52338SCy Schubert 
2351*4bc52338SCy Schubert 	switch (property) {
2352*4bc52338SCy Schubert 	case WPAS_DBUS_STA_PROP_ADDRESS:
2353*4bc52338SCy Schubert 		prop = "Address";
2354*4bc52338SCy Schubert 		break;
2355*4bc52338SCy Schubert 	default:
2356*4bc52338SCy Schubert 		wpa_printf(MSG_ERROR, "dbus: %s: Unknown Property value %d",
2357*4bc52338SCy Schubert 			   __func__, property);
2358*4bc52338SCy Schubert 		return;
2359*4bc52338SCy Schubert 	}
2360*4bc52338SCy Schubert 
2361*4bc52338SCy Schubert 	os_snprintf(path, WPAS_DBUS_OBJECT_PATH_MAX,
2362*4bc52338SCy Schubert 		    "%s/" WPAS_DBUS_NEW_STAS_PART "/" COMPACT_MACSTR,
2363*4bc52338SCy Schubert 		    wpa_s->dbus_new_path, MAC2STR(address));
2364*4bc52338SCy Schubert 
2365*4bc52338SCy Schubert 	wpa_dbus_mark_property_changed(wpa_s->global->dbus, path,
2366*4bc52338SCy Schubert 				       WPAS_DBUS_NEW_IFACE_STA, prop);
2367*4bc52338SCy Schubert }
2368*4bc52338SCy Schubert 
2369*4bc52338SCy Schubert 
2370*4bc52338SCy Schubert /**
2371d4f2939cSRui Paulo  * wpas_dbus_signal_debug_level_changed - Signals change of debug param
2372d4f2939cSRui Paulo  * @global: wpa_global structure
2373d4f2939cSRui Paulo  *
2374d4f2939cSRui Paulo  * Sends PropertyChanged signals informing that debug level has changed.
2375d4f2939cSRui Paulo  */
2376d4f2939cSRui Paulo void wpas_dbus_signal_debug_level_changed(struct wpa_global *global)
2377d4f2939cSRui Paulo {
2378d4f2939cSRui Paulo 	wpa_dbus_mark_property_changed(global->dbus, WPAS_DBUS_NEW_PATH,
2379d4f2939cSRui Paulo 				       WPAS_DBUS_NEW_INTERFACE,
2380d4f2939cSRui Paulo 				       "DebugLevel");
2381d4f2939cSRui Paulo }
2382d4f2939cSRui Paulo 
2383d4f2939cSRui Paulo 
2384d4f2939cSRui Paulo /**
2385d4f2939cSRui Paulo  * wpas_dbus_signal_debug_timestamp_changed - Signals change of debug param
2386d4f2939cSRui Paulo  * @global: wpa_global structure
2387d4f2939cSRui Paulo  *
2388d4f2939cSRui Paulo  * Sends PropertyChanged signals informing that debug timestamp has changed.
2389d4f2939cSRui Paulo  */
2390d4f2939cSRui Paulo void wpas_dbus_signal_debug_timestamp_changed(struct wpa_global *global)
2391d4f2939cSRui Paulo {
2392d4f2939cSRui Paulo 	wpa_dbus_mark_property_changed(global->dbus, WPAS_DBUS_NEW_PATH,
2393d4f2939cSRui Paulo 				       WPAS_DBUS_NEW_INTERFACE,
2394d4f2939cSRui Paulo 				       "DebugTimestamp");
2395d4f2939cSRui Paulo }
2396d4f2939cSRui Paulo 
2397d4f2939cSRui Paulo 
2398d4f2939cSRui Paulo /**
2399d4f2939cSRui Paulo  * wpas_dbus_signal_debug_show_keys_changed - Signals change of debug param
2400d4f2939cSRui Paulo  * @global: wpa_global structure
2401d4f2939cSRui Paulo  *
2402d4f2939cSRui Paulo  * Sends PropertyChanged signals informing that debug show_keys has changed.
2403d4f2939cSRui Paulo  */
2404d4f2939cSRui Paulo void wpas_dbus_signal_debug_show_keys_changed(struct wpa_global *global)
2405d4f2939cSRui Paulo {
2406d4f2939cSRui Paulo 	wpa_dbus_mark_property_changed(global->dbus, WPAS_DBUS_NEW_PATH,
2407d4f2939cSRui Paulo 				       WPAS_DBUS_NEW_INTERFACE,
2408d4f2939cSRui Paulo 				       "DebugShowKeys");
2409d4f2939cSRui Paulo }
2410d4f2939cSRui Paulo 
2411d4f2939cSRui Paulo 
2412d4f2939cSRui Paulo static void wpas_dbus_register(struct wpa_dbus_object_desc *obj_desc,
2413d4f2939cSRui Paulo 			       void *priv,
2414d4f2939cSRui Paulo 			       WPADBusArgumentFreeFunction priv_free,
2415d4f2939cSRui Paulo 			       const struct wpa_dbus_method_desc *methods,
2416d4f2939cSRui Paulo 			       const struct wpa_dbus_property_desc *properties,
2417d4f2939cSRui Paulo 			       const struct wpa_dbus_signal_desc *signals)
2418d4f2939cSRui Paulo {
2419d4f2939cSRui Paulo 	int n;
2420d4f2939cSRui Paulo 
2421d4f2939cSRui Paulo 	obj_desc->user_data = priv;
2422d4f2939cSRui Paulo 	obj_desc->user_data_free_func = priv_free;
2423d4f2939cSRui Paulo 	obj_desc->methods = methods;
2424d4f2939cSRui Paulo 	obj_desc->properties = properties;
2425d4f2939cSRui Paulo 	obj_desc->signals = signals;
2426d4f2939cSRui Paulo 
2427d4f2939cSRui Paulo 	for (n = 0; properties && properties->dbus_property; properties++)
2428d4f2939cSRui Paulo 		n++;
2429d4f2939cSRui Paulo 
2430d4f2939cSRui Paulo 	obj_desc->prop_changed_flags = os_zalloc(n);
2431d4f2939cSRui Paulo 	if (!obj_desc->prop_changed_flags)
2432d4f2939cSRui Paulo 		wpa_printf(MSG_DEBUG, "dbus: %s: can't register handlers",
2433d4f2939cSRui Paulo 			   __func__);
2434d4f2939cSRui Paulo }
2435d4f2939cSRui Paulo 
2436d4f2939cSRui Paulo 
2437d4f2939cSRui Paulo static const struct wpa_dbus_method_desc wpas_dbus_global_methods[] = {
2438d4f2939cSRui Paulo 	{ "CreateInterface", WPAS_DBUS_NEW_INTERFACE,
24395b9c547cSRui Paulo 	  (WPADBusMethodHandler) wpas_dbus_handler_create_interface,
2440d4f2939cSRui Paulo 	  {
2441d4f2939cSRui Paulo 		  { "args", "a{sv}", ARG_IN },
2442d4f2939cSRui Paulo 		  { "path", "o", ARG_OUT },
2443d4f2939cSRui Paulo 		  END_ARGS
2444d4f2939cSRui Paulo 	  }
2445d4f2939cSRui Paulo 	},
2446d4f2939cSRui Paulo 	{ "RemoveInterface", WPAS_DBUS_NEW_INTERFACE,
24475b9c547cSRui Paulo 	  (WPADBusMethodHandler) wpas_dbus_handler_remove_interface,
2448d4f2939cSRui Paulo 	  {
2449d4f2939cSRui Paulo 		  { "path", "o", ARG_IN },
2450d4f2939cSRui Paulo 		  END_ARGS
2451d4f2939cSRui Paulo 	  }
2452d4f2939cSRui Paulo 	},
2453d4f2939cSRui Paulo 	{ "GetInterface", WPAS_DBUS_NEW_INTERFACE,
24545b9c547cSRui Paulo 	  (WPADBusMethodHandler) wpas_dbus_handler_get_interface,
2455d4f2939cSRui Paulo 	  {
2456d4f2939cSRui Paulo 		  { "ifname", "s", ARG_IN },
2457d4f2939cSRui Paulo 		  { "path", "o", ARG_OUT },
2458d4f2939cSRui Paulo 		  END_ARGS
2459d4f2939cSRui Paulo 	  }
2460d4f2939cSRui Paulo 	},
2461780fb4a2SCy Schubert 	{ "ExpectDisconnect", WPAS_DBUS_NEW_INTERFACE,
2462780fb4a2SCy Schubert 	  (WPADBusMethodHandler) wpas_dbus_handler_expect_disconnect,
2463780fb4a2SCy Schubert 	  {
2464780fb4a2SCy Schubert 		END_ARGS
2465780fb4a2SCy Schubert 	  }
2466780fb4a2SCy Schubert 	},
2467d4f2939cSRui Paulo 	{ NULL, NULL, NULL, { END_ARGS } }
2468d4f2939cSRui Paulo };
2469d4f2939cSRui Paulo 
2470d4f2939cSRui Paulo static const struct wpa_dbus_property_desc wpas_dbus_global_properties[] = {
2471d4f2939cSRui Paulo 	{ "DebugLevel", WPAS_DBUS_NEW_INTERFACE, "s",
2472d4f2939cSRui Paulo 	  wpas_dbus_getter_debug_level,
2473780fb4a2SCy Schubert 	  wpas_dbus_setter_debug_level,
2474780fb4a2SCy Schubert 	  NULL
2475d4f2939cSRui Paulo 	},
2476d4f2939cSRui Paulo 	{ "DebugTimestamp", WPAS_DBUS_NEW_INTERFACE, "b",
2477d4f2939cSRui Paulo 	  wpas_dbus_getter_debug_timestamp,
2478780fb4a2SCy Schubert 	  wpas_dbus_setter_debug_timestamp,
2479780fb4a2SCy Schubert 	  NULL
2480d4f2939cSRui Paulo 	},
2481d4f2939cSRui Paulo 	{ "DebugShowKeys", WPAS_DBUS_NEW_INTERFACE, "b",
2482d4f2939cSRui Paulo 	  wpas_dbus_getter_debug_show_keys,
2483780fb4a2SCy Schubert 	  wpas_dbus_setter_debug_show_keys,
2484780fb4a2SCy Schubert 	  NULL
2485d4f2939cSRui Paulo 	},
2486d4f2939cSRui Paulo 	{ "Interfaces", WPAS_DBUS_NEW_INTERFACE, "ao",
2487d4f2939cSRui Paulo 	  wpas_dbus_getter_interfaces,
2488780fb4a2SCy Schubert 	  NULL,
2489d4f2939cSRui Paulo 	  NULL
2490d4f2939cSRui Paulo 	},
2491d4f2939cSRui Paulo 	{ "EapMethods", WPAS_DBUS_NEW_INTERFACE, "as",
2492d4f2939cSRui Paulo 	  wpas_dbus_getter_eap_methods,
2493780fb4a2SCy Schubert 	  NULL,
2494d4f2939cSRui Paulo 	  NULL
2495d4f2939cSRui Paulo 	},
2496d4f2939cSRui Paulo 	{ "Capabilities", WPAS_DBUS_NEW_INTERFACE, "as",
2497d4f2939cSRui Paulo 	  wpas_dbus_getter_global_capabilities,
2498780fb4a2SCy Schubert 	  NULL,
2499d4f2939cSRui Paulo 	  NULL
2500d4f2939cSRui Paulo 	},
25015b9c547cSRui Paulo #ifdef CONFIG_WIFI_DISPLAY
25025b9c547cSRui Paulo 	{ "WFDIEs", WPAS_DBUS_NEW_INTERFACE, "ay",
25035b9c547cSRui Paulo 	  wpas_dbus_getter_global_wfd_ies,
2504780fb4a2SCy Schubert 	  wpas_dbus_setter_global_wfd_ies,
2505780fb4a2SCy Schubert 	  NULL
25065b9c547cSRui Paulo 	},
25075b9c547cSRui Paulo #endif /* CONFIG_WIFI_DISPLAY */
2508780fb4a2SCy Schubert 	{ NULL, NULL, NULL, NULL, NULL, NULL }
2509d4f2939cSRui Paulo };
2510d4f2939cSRui Paulo 
2511d4f2939cSRui Paulo static const struct wpa_dbus_signal_desc wpas_dbus_global_signals[] = {
2512d4f2939cSRui Paulo 	{ "InterfaceAdded", WPAS_DBUS_NEW_INTERFACE,
2513d4f2939cSRui Paulo 	  {
2514d4f2939cSRui Paulo 		  { "path", "o", ARG_OUT },
2515d4f2939cSRui Paulo 		  { "properties", "a{sv}", ARG_OUT },
2516d4f2939cSRui Paulo 		  END_ARGS
2517d4f2939cSRui Paulo 	  }
2518d4f2939cSRui Paulo 	},
2519d4f2939cSRui Paulo 	{ "InterfaceRemoved", WPAS_DBUS_NEW_INTERFACE,
2520d4f2939cSRui Paulo 	  {
2521d4f2939cSRui Paulo 		  { "path", "o", ARG_OUT },
2522d4f2939cSRui Paulo 		  END_ARGS
2523d4f2939cSRui Paulo 	  }
2524d4f2939cSRui Paulo 	},
2525d4f2939cSRui Paulo 	/* Deprecated: use org.freedesktop.DBus.Properties.PropertiesChanged */
2526d4f2939cSRui Paulo 	{ "PropertiesChanged", WPAS_DBUS_NEW_INTERFACE,
2527d4f2939cSRui Paulo 	  {
2528d4f2939cSRui Paulo 		  { "properties", "a{sv}", ARG_OUT },
2529d4f2939cSRui Paulo 		  END_ARGS
2530d4f2939cSRui Paulo 	  }
2531d4f2939cSRui Paulo 	},
2532d4f2939cSRui Paulo 	{ NULL, NULL, { END_ARGS } }
2533d4f2939cSRui Paulo };
2534d4f2939cSRui Paulo 
2535d4f2939cSRui Paulo 
2536780fb4a2SCy Schubert static char * uscore_to_dbus(const char *uscore)
2537780fb4a2SCy Schubert {
2538780fb4a2SCy Schubert 	const char *p = uscore;
2539780fb4a2SCy Schubert 	char *str, *s;
2540780fb4a2SCy Schubert 	dbus_bool_t last_was_uscore = TRUE;
2541780fb4a2SCy Schubert 
2542780fb4a2SCy Schubert 	s = str = os_zalloc(os_strlen(uscore) + 1);
2543780fb4a2SCy Schubert 	if (!str)
2544780fb4a2SCy Schubert 		return NULL;
2545780fb4a2SCy Schubert 	while (p && *p) {
2546780fb4a2SCy Schubert 		if (*p == '_') {
2547780fb4a2SCy Schubert 			last_was_uscore = TRUE;
2548780fb4a2SCy Schubert 		} else {
2549780fb4a2SCy Schubert 			*s++ = last_was_uscore ? toupper(*p) : *p;
2550780fb4a2SCy Schubert 			last_was_uscore = FALSE;
2551780fb4a2SCy Schubert 		}
2552780fb4a2SCy Schubert 		p++;
2553780fb4a2SCy Schubert 	}
2554780fb4a2SCy Schubert 
2555780fb4a2SCy Schubert 	return str;
2556780fb4a2SCy Schubert }
2557780fb4a2SCy Schubert 
2558780fb4a2SCy Schubert 
2559780fb4a2SCy Schubert static int wpa_dbus_ctrl_iface_props_init(struct wpas_dbus_priv *priv);
2560780fb4a2SCy Schubert 
2561780fb4a2SCy Schubert 
2562780fb4a2SCy Schubert static void wpa_dbus_ctrl_iface_props_deinit(struct wpas_dbus_priv *priv)
2563780fb4a2SCy Schubert {
2564780fb4a2SCy Schubert 	int idx = priv->globals_start;
2565780fb4a2SCy Schubert 
2566780fb4a2SCy Schubert 	/* Free all allocated property values */
2567780fb4a2SCy Schubert 	while (priv->all_interface_properties[idx].dbus_property)
2568780fb4a2SCy Schubert 		os_free((char *)
2569780fb4a2SCy Schubert 			priv->all_interface_properties[idx++].dbus_property);
2570780fb4a2SCy Schubert 	os_free((char *) priv->all_interface_properties);
2571780fb4a2SCy Schubert }
2572780fb4a2SCy Schubert 
2573780fb4a2SCy Schubert 
2574d4f2939cSRui Paulo /**
2575d4f2939cSRui Paulo  * wpas_dbus_ctrl_iface_init - Initialize dbus control interface
2576d4f2939cSRui Paulo  * @global: Pointer to global data from wpa_supplicant_init()
2577d4f2939cSRui Paulo  * Returns: 0 on success or -1 on failure
2578d4f2939cSRui Paulo  *
2579780fb4a2SCy Schubert  * Initialize the dbus control interface for wpa_supplicant and start
2580d4f2939cSRui Paulo  * receiving commands from external programs over the bus.
2581d4f2939cSRui Paulo  */
2582d4f2939cSRui Paulo int wpas_dbus_ctrl_iface_init(struct wpas_dbus_priv *priv)
2583d4f2939cSRui Paulo {
2584d4f2939cSRui Paulo 	struct wpa_dbus_object_desc *obj_desc;
2585d4f2939cSRui Paulo 	int ret;
2586d4f2939cSRui Paulo 
2587780fb4a2SCy Schubert 	ret = wpa_dbus_ctrl_iface_props_init(priv);
2588780fb4a2SCy Schubert 	if (ret < 0) {
2589780fb4a2SCy Schubert 		wpa_printf(MSG_ERROR,
2590780fb4a2SCy Schubert 			   "dbus: Not enough memory to init interface properties");
2591780fb4a2SCy Schubert 		return -1;
2592780fb4a2SCy Schubert 	}
2593780fb4a2SCy Schubert 
2594d4f2939cSRui Paulo 	obj_desc = os_zalloc(sizeof(struct wpa_dbus_object_desc));
2595d4f2939cSRui Paulo 	if (!obj_desc) {
25965b9c547cSRui Paulo 		wpa_printf(MSG_ERROR,
25975b9c547cSRui Paulo 			   "Not enough memory to create object description");
2598780fb4a2SCy Schubert 		goto error;
2599d4f2939cSRui Paulo 	}
2600d4f2939cSRui Paulo 
2601d4f2939cSRui Paulo 	wpas_dbus_register(obj_desc, priv->global, NULL,
2602d4f2939cSRui Paulo 			   wpas_dbus_global_methods,
2603d4f2939cSRui Paulo 			   wpas_dbus_global_properties,
2604d4f2939cSRui Paulo 			   wpas_dbus_global_signals);
2605d4f2939cSRui Paulo 
2606d4f2939cSRui Paulo 	wpa_printf(MSG_DEBUG, "dbus: Register D-Bus object '%s'",
2607d4f2939cSRui Paulo 		   WPAS_DBUS_NEW_PATH);
2608d4f2939cSRui Paulo 	ret = wpa_dbus_ctrl_iface_init(priv, WPAS_DBUS_NEW_PATH,
2609d4f2939cSRui Paulo 				       WPAS_DBUS_NEW_SERVICE,
2610d4f2939cSRui Paulo 				       obj_desc);
2611780fb4a2SCy Schubert 	if (ret < 0) {
2612d4f2939cSRui Paulo 		free_dbus_object_desc(obj_desc);
2613780fb4a2SCy Schubert 		goto error;
2614780fb4a2SCy Schubert 	}
2615d4f2939cSRui Paulo 
2616780fb4a2SCy Schubert 	priv->dbus_new_initialized = 1;
2617780fb4a2SCy Schubert 	return 0;
2618780fb4a2SCy Schubert 
2619780fb4a2SCy Schubert error:
2620780fb4a2SCy Schubert 	wpa_dbus_ctrl_iface_props_deinit(priv);
2621780fb4a2SCy Schubert 	return -1;
2622d4f2939cSRui Paulo }
2623d4f2939cSRui Paulo 
2624d4f2939cSRui Paulo 
2625d4f2939cSRui Paulo /**
2626d4f2939cSRui Paulo  * wpas_dbus_ctrl_iface_deinit - Deinitialize dbus ctrl interface for
2627d4f2939cSRui Paulo  * wpa_supplicant
2628780fb4a2SCy Schubert  * @priv: Pointer to dbus private data from wpas_dbus_init()
2629d4f2939cSRui Paulo  *
2630d4f2939cSRui Paulo  * Deinitialize the dbus control interface that was initialized with
2631d4f2939cSRui Paulo  * wpas_dbus_ctrl_iface_init().
2632d4f2939cSRui Paulo  */
2633780fb4a2SCy Schubert void wpas_dbus_ctrl_iface_deinit(struct wpas_dbus_priv *priv)
2634d4f2939cSRui Paulo {
2635780fb4a2SCy Schubert 	if (!priv->dbus_new_initialized)
2636d4f2939cSRui Paulo 		return;
2637d4f2939cSRui Paulo 	wpa_printf(MSG_DEBUG, "dbus: Unregister D-Bus object '%s'",
2638d4f2939cSRui Paulo 		   WPAS_DBUS_NEW_PATH);
2639780fb4a2SCy Schubert 	dbus_connection_unregister_object_path(priv->con, WPAS_DBUS_NEW_PATH);
2640780fb4a2SCy Schubert 	wpa_dbus_ctrl_iface_props_deinit(priv);
2641d4f2939cSRui Paulo }
2642d4f2939cSRui Paulo 
2643d4f2939cSRui Paulo 
2644d4f2939cSRui Paulo static void wpa_dbus_free(void *ptr)
2645d4f2939cSRui Paulo {
2646d4f2939cSRui Paulo 	os_free(ptr);
2647d4f2939cSRui Paulo }
2648d4f2939cSRui Paulo 
2649d4f2939cSRui Paulo 
2650d4f2939cSRui Paulo static const struct wpa_dbus_property_desc wpas_dbus_network_properties[] = {
2651d4f2939cSRui Paulo 	{ "Properties", WPAS_DBUS_NEW_IFACE_NETWORK, "a{sv}",
2652d4f2939cSRui Paulo 	  wpas_dbus_getter_network_properties,
2653780fb4a2SCy Schubert 	  wpas_dbus_setter_network_properties,
2654780fb4a2SCy Schubert 	  NULL
2655d4f2939cSRui Paulo 	},
2656d4f2939cSRui Paulo 	{ "Enabled", WPAS_DBUS_NEW_IFACE_NETWORK, "b",
2657d4f2939cSRui Paulo 	  wpas_dbus_getter_enabled,
2658780fb4a2SCy Schubert 	  wpas_dbus_setter_enabled,
2659780fb4a2SCy Schubert 	  NULL
2660d4f2939cSRui Paulo 	},
2661780fb4a2SCy Schubert 	{ NULL, NULL, NULL, NULL, NULL, NULL }
2662d4f2939cSRui Paulo };
2663d4f2939cSRui Paulo 
2664d4f2939cSRui Paulo 
2665d4f2939cSRui Paulo static const struct wpa_dbus_signal_desc wpas_dbus_network_signals[] = {
2666d4f2939cSRui Paulo 	/* Deprecated: use org.freedesktop.DBus.Properties.PropertiesChanged */
2667d4f2939cSRui Paulo 	{ "PropertiesChanged", WPAS_DBUS_NEW_IFACE_NETWORK,
2668d4f2939cSRui Paulo 	  {
2669d4f2939cSRui Paulo 		  { "properties", "a{sv}", ARG_OUT },
2670d4f2939cSRui Paulo 		  END_ARGS
2671d4f2939cSRui Paulo 	  }
2672d4f2939cSRui Paulo 	},
2673d4f2939cSRui Paulo 	{ NULL, NULL, { END_ARGS } }
2674d4f2939cSRui Paulo };
2675d4f2939cSRui Paulo 
2676d4f2939cSRui Paulo 
2677d4f2939cSRui Paulo /**
2678d4f2939cSRui Paulo  * wpas_dbus_register_network - Register a configured network with dbus
2679d4f2939cSRui Paulo  * @wpa_s: wpa_supplicant interface structure
2680d4f2939cSRui Paulo  * @ssid: network configuration data
2681d4f2939cSRui Paulo  * Returns: 0 on success, -1 on failure
2682d4f2939cSRui Paulo  *
2683d4f2939cSRui Paulo  * Registers network representing object with dbus
2684d4f2939cSRui Paulo  */
2685d4f2939cSRui Paulo int wpas_dbus_register_network(struct wpa_supplicant *wpa_s,
2686d4f2939cSRui Paulo 			       struct wpa_ssid *ssid)
2687d4f2939cSRui Paulo {
2688d4f2939cSRui Paulo 	struct wpas_dbus_priv *ctrl_iface;
2689d4f2939cSRui Paulo 	struct wpa_dbus_object_desc *obj_desc;
2690d4f2939cSRui Paulo 	struct network_handler_args *arg;
2691d4f2939cSRui Paulo 	char net_obj_path[WPAS_DBUS_OBJECT_PATH_MAX];
2692d4f2939cSRui Paulo 
2693d4f2939cSRui Paulo #ifdef CONFIG_P2P
2694d4f2939cSRui Paulo 	/*
2695d4f2939cSRui Paulo 	 * If it is a persistent group register it as such.
2696d4f2939cSRui Paulo 	 * This is to handle cases where an interface is being initialized
2697d4f2939cSRui Paulo 	 * with a list of networks read from config.
2698d4f2939cSRui Paulo 	 */
2699d4f2939cSRui Paulo 	if (network_is_persistent_group(ssid))
2700d4f2939cSRui Paulo 		return wpas_dbus_register_persistent_group(wpa_s, ssid);
2701d4f2939cSRui Paulo #endif /* CONFIG_P2P */
2702d4f2939cSRui Paulo 
2703d4f2939cSRui Paulo 	/* Do nothing if the control interface is not turned on */
2704325151a3SRui Paulo 	if (wpa_s == NULL || wpa_s->global == NULL || !wpa_s->dbus_new_path)
2705d4f2939cSRui Paulo 		return 0;
2706d4f2939cSRui Paulo 	ctrl_iface = wpa_s->global->dbus;
2707d4f2939cSRui Paulo 	if (ctrl_iface == NULL)
2708d4f2939cSRui Paulo 		return 0;
2709d4f2939cSRui Paulo 
2710d4f2939cSRui Paulo 	os_snprintf(net_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
2711d4f2939cSRui Paulo 		    "%s/" WPAS_DBUS_NEW_NETWORKS_PART "/%u",
2712d4f2939cSRui Paulo 		    wpa_s->dbus_new_path, ssid->id);
2713d4f2939cSRui Paulo 
2714d4f2939cSRui Paulo 	wpa_printf(MSG_DEBUG, "dbus: Register network object '%s'",
2715d4f2939cSRui Paulo 		   net_obj_path);
2716d4f2939cSRui Paulo 	obj_desc = os_zalloc(sizeof(struct wpa_dbus_object_desc));
2717d4f2939cSRui Paulo 	if (!obj_desc) {
27185b9c547cSRui Paulo 		wpa_printf(MSG_ERROR,
27195b9c547cSRui Paulo 			   "Not enough memory to create object description");
2720d4f2939cSRui Paulo 		goto err;
2721d4f2939cSRui Paulo 	}
2722d4f2939cSRui Paulo 
2723d4f2939cSRui Paulo 	/* allocate memory for handlers arguments */
2724d4f2939cSRui Paulo 	arg = os_zalloc(sizeof(struct network_handler_args));
2725d4f2939cSRui Paulo 	if (!arg) {
27265b9c547cSRui Paulo 		wpa_printf(MSG_ERROR,
27275b9c547cSRui Paulo 			   "Not enough memory to create arguments for method");
2728d4f2939cSRui Paulo 		goto err;
2729d4f2939cSRui Paulo 	}
2730d4f2939cSRui Paulo 
2731d4f2939cSRui Paulo 	arg->wpa_s = wpa_s;
2732d4f2939cSRui Paulo 	arg->ssid = ssid;
2733d4f2939cSRui Paulo 
2734d4f2939cSRui Paulo 	wpas_dbus_register(obj_desc, arg, wpa_dbus_free, NULL,
2735d4f2939cSRui Paulo 			   wpas_dbus_network_properties,
2736d4f2939cSRui Paulo 			   wpas_dbus_network_signals);
2737d4f2939cSRui Paulo 
2738d4f2939cSRui Paulo 	if (wpa_dbus_register_object_per_iface(ctrl_iface, net_obj_path,
2739d4f2939cSRui Paulo 					       wpa_s->ifname, obj_desc))
2740d4f2939cSRui Paulo 		goto err;
2741d4f2939cSRui Paulo 
2742d4f2939cSRui Paulo 	wpas_dbus_signal_network_added(wpa_s, ssid->id);
2743d4f2939cSRui Paulo 
2744d4f2939cSRui Paulo 	return 0;
2745d4f2939cSRui Paulo 
2746d4f2939cSRui Paulo err:
2747d4f2939cSRui Paulo 	free_dbus_object_desc(obj_desc);
2748d4f2939cSRui Paulo 	return -1;
2749d4f2939cSRui Paulo }
2750d4f2939cSRui Paulo 
2751d4f2939cSRui Paulo 
2752d4f2939cSRui Paulo /**
2753d4f2939cSRui Paulo  * wpas_dbus_unregister_network - Unregister a configured network from dbus
2754d4f2939cSRui Paulo  * @wpa_s: wpa_supplicant interface structure
2755d4f2939cSRui Paulo  * @nid: network id
2756d4f2939cSRui Paulo  * Returns: 0 on success, -1 on failure
2757d4f2939cSRui Paulo  *
2758d4f2939cSRui Paulo  * Unregisters network representing object from dbus
2759d4f2939cSRui Paulo  */
2760d4f2939cSRui Paulo int wpas_dbus_unregister_network(struct wpa_supplicant *wpa_s, int nid)
2761d4f2939cSRui Paulo {
2762d4f2939cSRui Paulo 	struct wpas_dbus_priv *ctrl_iface;
2763d4f2939cSRui Paulo 	char net_obj_path[WPAS_DBUS_OBJECT_PATH_MAX];
2764d4f2939cSRui Paulo 	int ret;
2765d4f2939cSRui Paulo #ifdef CONFIG_P2P
2766d4f2939cSRui Paulo 	struct wpa_ssid *ssid;
2767d4f2939cSRui Paulo 
2768d4f2939cSRui Paulo 	ssid = wpa_config_get_network(wpa_s->conf, nid);
2769d4f2939cSRui Paulo 
2770d4f2939cSRui Paulo 	/* If it is a persistent group unregister it as such */
2771d4f2939cSRui Paulo 	if (ssid && network_is_persistent_group(ssid))
2772d4f2939cSRui Paulo 		return wpas_dbus_unregister_persistent_group(wpa_s, nid);
2773d4f2939cSRui Paulo #endif /* CONFIG_P2P */
2774d4f2939cSRui Paulo 
2775d4f2939cSRui Paulo 	/* Do nothing if the control interface is not turned on */
2776d4f2939cSRui Paulo 	if (wpa_s->global == NULL || wpa_s->dbus_new_path == NULL)
2777d4f2939cSRui Paulo 		return 0;
2778d4f2939cSRui Paulo 	ctrl_iface = wpa_s->global->dbus;
2779d4f2939cSRui Paulo 	if (ctrl_iface == NULL)
2780d4f2939cSRui Paulo 		return 0;
2781d4f2939cSRui Paulo 
2782d4f2939cSRui Paulo 	os_snprintf(net_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
2783d4f2939cSRui Paulo 		    "%s/" WPAS_DBUS_NEW_NETWORKS_PART "/%u",
2784d4f2939cSRui Paulo 		    wpa_s->dbus_new_path, nid);
2785d4f2939cSRui Paulo 
2786d4f2939cSRui Paulo 	wpa_printf(MSG_DEBUG, "dbus: Unregister network object '%s'",
2787d4f2939cSRui Paulo 		   net_obj_path);
2788d4f2939cSRui Paulo 	ret = wpa_dbus_unregister_object_per_iface(ctrl_iface, net_obj_path);
2789d4f2939cSRui Paulo 
2790d4f2939cSRui Paulo 	if (!ret)
2791d4f2939cSRui Paulo 		wpas_dbus_signal_network_removed(wpa_s, nid);
2792d4f2939cSRui Paulo 
2793d4f2939cSRui Paulo 	return ret;
2794d4f2939cSRui Paulo }
2795d4f2939cSRui Paulo 
2796d4f2939cSRui Paulo 
2797d4f2939cSRui Paulo static const struct wpa_dbus_property_desc wpas_dbus_bss_properties[] = {
2798d4f2939cSRui Paulo 	{ "SSID", WPAS_DBUS_NEW_IFACE_BSS, "ay",
2799d4f2939cSRui Paulo 	  wpas_dbus_getter_bss_ssid,
2800780fb4a2SCy Schubert 	  NULL,
2801d4f2939cSRui Paulo 	  NULL
2802d4f2939cSRui Paulo 	},
2803d4f2939cSRui Paulo 	{ "BSSID", WPAS_DBUS_NEW_IFACE_BSS, "ay",
2804d4f2939cSRui Paulo 	  wpas_dbus_getter_bss_bssid,
2805780fb4a2SCy Schubert 	  NULL,
2806d4f2939cSRui Paulo 	  NULL
2807d4f2939cSRui Paulo 	},
2808d4f2939cSRui Paulo 	{ "Privacy", WPAS_DBUS_NEW_IFACE_BSS, "b",
2809d4f2939cSRui Paulo 	  wpas_dbus_getter_bss_privacy,
2810780fb4a2SCy Schubert 	  NULL,
2811d4f2939cSRui Paulo 	  NULL
2812d4f2939cSRui Paulo 	},
2813d4f2939cSRui Paulo 	{ "Mode", WPAS_DBUS_NEW_IFACE_BSS, "s",
2814d4f2939cSRui Paulo 	  wpas_dbus_getter_bss_mode,
2815780fb4a2SCy Schubert 	  NULL,
2816d4f2939cSRui Paulo 	  NULL
2817d4f2939cSRui Paulo 	},
2818d4f2939cSRui Paulo 	{ "Signal", WPAS_DBUS_NEW_IFACE_BSS, "n",
2819d4f2939cSRui Paulo 	  wpas_dbus_getter_bss_signal,
2820780fb4a2SCy Schubert 	  NULL,
2821d4f2939cSRui Paulo 	  NULL
2822d4f2939cSRui Paulo 	},
2823d4f2939cSRui Paulo 	{ "Frequency", WPAS_DBUS_NEW_IFACE_BSS, "q",
2824d4f2939cSRui Paulo 	  wpas_dbus_getter_bss_frequency,
2825780fb4a2SCy Schubert 	  NULL,
2826d4f2939cSRui Paulo 	  NULL
2827d4f2939cSRui Paulo 	},
2828d4f2939cSRui Paulo 	{ "Rates", WPAS_DBUS_NEW_IFACE_BSS, "au",
2829d4f2939cSRui Paulo 	  wpas_dbus_getter_bss_rates,
2830780fb4a2SCy Schubert 	  NULL,
2831d4f2939cSRui Paulo 	  NULL
2832d4f2939cSRui Paulo 	},
2833d4f2939cSRui Paulo 	{ "WPA", WPAS_DBUS_NEW_IFACE_BSS, "a{sv}",
2834d4f2939cSRui Paulo 	  wpas_dbus_getter_bss_wpa,
2835780fb4a2SCy Schubert 	  NULL,
2836d4f2939cSRui Paulo 	  NULL
2837d4f2939cSRui Paulo 	},
2838d4f2939cSRui Paulo 	{ "RSN", WPAS_DBUS_NEW_IFACE_BSS, "a{sv}",
2839d4f2939cSRui Paulo 	  wpas_dbus_getter_bss_rsn,
2840780fb4a2SCy Schubert 	  NULL,
2841d4f2939cSRui Paulo 	  NULL
2842d4f2939cSRui Paulo 	},
2843d4f2939cSRui Paulo 	{ "WPS", WPAS_DBUS_NEW_IFACE_BSS, "a{sv}",
2844d4f2939cSRui Paulo 	  wpas_dbus_getter_bss_wps,
2845780fb4a2SCy Schubert 	  NULL,
2846d4f2939cSRui Paulo 	  NULL
2847d4f2939cSRui Paulo 	},
2848d4f2939cSRui Paulo 	{ "IEs", WPAS_DBUS_NEW_IFACE_BSS, "ay",
2849d4f2939cSRui Paulo 	  wpas_dbus_getter_bss_ies,
2850780fb4a2SCy Schubert 	  NULL,
2851d4f2939cSRui Paulo 	  NULL
2852d4f2939cSRui Paulo 	},
28535b9c547cSRui Paulo 	{ "Age", WPAS_DBUS_NEW_IFACE_BSS, "u",
28545b9c547cSRui Paulo 	  wpas_dbus_getter_bss_age,
2855780fb4a2SCy Schubert 	  NULL,
28565b9c547cSRui Paulo 	  NULL
28575b9c547cSRui Paulo 	},
2858*4bc52338SCy Schubert 	{
2859*4bc52338SCy Schubert 	  "RoamTime", WPAS_DBUS_NEW_IFACE_INTERFACE, "u",
2860*4bc52338SCy Schubert 	  wpas_dbus_getter_roam_time,
2861*4bc52338SCy Schubert 	  NULL,
2862*4bc52338SCy Schubert 	  NULL
2863*4bc52338SCy Schubert 	},
2864*4bc52338SCy Schubert 	{
2865*4bc52338SCy Schubert 	  "RoamComplete", WPAS_DBUS_NEW_IFACE_INTERFACE, "b",
2866*4bc52338SCy Schubert 	  wpas_dbus_getter_roam_complete,
2867*4bc52338SCy Schubert 	  NULL,
2868*4bc52338SCy Schubert 	  NULL
2869*4bc52338SCy Schubert 	},
2870*4bc52338SCy Schubert 	{
2871*4bc52338SCy Schubert 	  "SessionLength", WPAS_DBUS_NEW_IFACE_INTERFACE, "u",
2872*4bc52338SCy Schubert 	  wpas_dbus_getter_session_length,
2873*4bc52338SCy Schubert 	  NULL,
2874*4bc52338SCy Schubert 	  NULL
2875*4bc52338SCy Schubert 	},
2876*4bc52338SCy Schubert 	{
2877*4bc52338SCy Schubert 	  "BSSTMStatus", WPAS_DBUS_NEW_IFACE_INTERFACE, "u",
2878*4bc52338SCy Schubert 	  wpas_dbus_getter_bss_tm_status,
2879*4bc52338SCy Schubert 	  NULL,
2880*4bc52338SCy Schubert 	  NULL
2881*4bc52338SCy Schubert 	},
2882780fb4a2SCy Schubert 	{ NULL, NULL, NULL, NULL, NULL, NULL }
2883d4f2939cSRui Paulo };
2884d4f2939cSRui Paulo 
2885d4f2939cSRui Paulo 
2886d4f2939cSRui Paulo static const struct wpa_dbus_signal_desc wpas_dbus_bss_signals[] = {
2887d4f2939cSRui Paulo 	/* Deprecated: use org.freedesktop.DBus.Properties.PropertiesChanged */
2888d4f2939cSRui Paulo 	{ "PropertiesChanged", WPAS_DBUS_NEW_IFACE_BSS,
2889d4f2939cSRui Paulo 	  {
2890d4f2939cSRui Paulo 		  { "properties", "a{sv}", ARG_OUT },
2891d4f2939cSRui Paulo 		  END_ARGS
2892d4f2939cSRui Paulo 	  }
2893d4f2939cSRui Paulo 	},
2894d4f2939cSRui Paulo 	{ NULL, NULL, { END_ARGS } }
2895d4f2939cSRui Paulo };
2896d4f2939cSRui Paulo 
2897d4f2939cSRui Paulo 
2898d4f2939cSRui Paulo /**
2899d4f2939cSRui Paulo  * wpas_dbus_unregister_bss - Unregister a scanned BSS from dbus
2900d4f2939cSRui Paulo  * @wpa_s: wpa_supplicant interface structure
2901d4f2939cSRui Paulo  * @bssid: scanned network bssid
2902d4f2939cSRui Paulo  * @id: unique BSS identifier
2903d4f2939cSRui Paulo  * Returns: 0 on success, -1 on failure
2904d4f2939cSRui Paulo  *
2905d4f2939cSRui Paulo  * Unregisters BSS representing object from dbus
2906d4f2939cSRui Paulo  */
2907d4f2939cSRui Paulo int wpas_dbus_unregister_bss(struct wpa_supplicant *wpa_s,
2908d4f2939cSRui Paulo 			     u8 bssid[ETH_ALEN], unsigned int id)
2909d4f2939cSRui Paulo {
2910d4f2939cSRui Paulo 	struct wpas_dbus_priv *ctrl_iface;
2911d4f2939cSRui Paulo 	char bss_obj_path[WPAS_DBUS_OBJECT_PATH_MAX];
2912d4f2939cSRui Paulo 
2913d4f2939cSRui Paulo 	/* Do nothing if the control interface is not turned on */
2914325151a3SRui Paulo 	if (wpa_s == NULL || wpa_s->global == NULL || !wpa_s->dbus_new_path)
2915d4f2939cSRui Paulo 		return 0;
2916d4f2939cSRui Paulo 	ctrl_iface = wpa_s->global->dbus;
2917d4f2939cSRui Paulo 	if (ctrl_iface == NULL)
2918d4f2939cSRui Paulo 		return 0;
2919d4f2939cSRui Paulo 
2920d4f2939cSRui Paulo 	os_snprintf(bss_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
2921d4f2939cSRui Paulo 		    "%s/" WPAS_DBUS_NEW_BSSIDS_PART "/%u",
2922d4f2939cSRui Paulo 		    wpa_s->dbus_new_path, id);
2923d4f2939cSRui Paulo 
2924d4f2939cSRui Paulo 	wpa_printf(MSG_DEBUG, "dbus: Unregister BSS object '%s'",
2925d4f2939cSRui Paulo 		   bss_obj_path);
2926d4f2939cSRui Paulo 	if (wpa_dbus_unregister_object_per_iface(ctrl_iface, bss_obj_path)) {
2927d4f2939cSRui Paulo 		wpa_printf(MSG_ERROR, "dbus: Cannot unregister BSS object %s",
2928d4f2939cSRui Paulo 			   bss_obj_path);
2929d4f2939cSRui Paulo 		return -1;
2930d4f2939cSRui Paulo 	}
2931d4f2939cSRui Paulo 
2932d4f2939cSRui Paulo 	wpas_dbus_signal_bss_removed(wpa_s, bss_obj_path);
2933d4f2939cSRui Paulo 	wpas_dbus_signal_prop_changed(wpa_s, WPAS_DBUS_PROP_BSSS);
2934d4f2939cSRui Paulo 
2935d4f2939cSRui Paulo 	return 0;
2936d4f2939cSRui Paulo }
2937d4f2939cSRui Paulo 
2938d4f2939cSRui Paulo 
2939d4f2939cSRui Paulo /**
2940d4f2939cSRui Paulo  * wpas_dbus_register_bss - Register a scanned BSS with dbus
2941d4f2939cSRui Paulo  * @wpa_s: wpa_supplicant interface structure
2942d4f2939cSRui Paulo  * @bssid: scanned network bssid
2943d4f2939cSRui Paulo  * @id: unique BSS identifier
2944d4f2939cSRui Paulo  * Returns: 0 on success, -1 on failure
2945d4f2939cSRui Paulo  *
2946d4f2939cSRui Paulo  * Registers BSS representing object with dbus
2947d4f2939cSRui Paulo  */
2948d4f2939cSRui Paulo int wpas_dbus_register_bss(struct wpa_supplicant *wpa_s,
2949d4f2939cSRui Paulo 			   u8 bssid[ETH_ALEN], unsigned int id)
2950d4f2939cSRui Paulo {
2951d4f2939cSRui Paulo 	struct wpas_dbus_priv *ctrl_iface;
2952d4f2939cSRui Paulo 	struct wpa_dbus_object_desc *obj_desc;
2953d4f2939cSRui Paulo 	char bss_obj_path[WPAS_DBUS_OBJECT_PATH_MAX];
2954d4f2939cSRui Paulo 	struct bss_handler_args *arg;
2955d4f2939cSRui Paulo 
2956d4f2939cSRui Paulo 	/* Do nothing if the control interface is not turned on */
2957325151a3SRui Paulo 	if (wpa_s == NULL || wpa_s->global == NULL || !wpa_s->dbus_new_path)
2958d4f2939cSRui Paulo 		return 0;
2959d4f2939cSRui Paulo 	ctrl_iface = wpa_s->global->dbus;
2960d4f2939cSRui Paulo 	if (ctrl_iface == NULL)
2961d4f2939cSRui Paulo 		return 0;
2962d4f2939cSRui Paulo 
2963d4f2939cSRui Paulo 	os_snprintf(bss_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
2964d4f2939cSRui Paulo 		    "%s/" WPAS_DBUS_NEW_BSSIDS_PART "/%u",
2965d4f2939cSRui Paulo 		    wpa_s->dbus_new_path, id);
2966d4f2939cSRui Paulo 
2967d4f2939cSRui Paulo 	obj_desc = os_zalloc(sizeof(struct wpa_dbus_object_desc));
2968d4f2939cSRui Paulo 	if (!obj_desc) {
29695b9c547cSRui Paulo 		wpa_printf(MSG_ERROR,
29705b9c547cSRui Paulo 			   "Not enough memory to create object description");
2971d4f2939cSRui Paulo 		goto err;
2972d4f2939cSRui Paulo 	}
2973d4f2939cSRui Paulo 
2974d4f2939cSRui Paulo 	arg = os_zalloc(sizeof(struct bss_handler_args));
2975d4f2939cSRui Paulo 	if (!arg) {
29765b9c547cSRui Paulo 		wpa_printf(MSG_ERROR,
29775b9c547cSRui Paulo 			   "Not enough memory to create arguments for handler");
2978d4f2939cSRui Paulo 		goto err;
2979d4f2939cSRui Paulo 	}
2980d4f2939cSRui Paulo 	arg->wpa_s = wpa_s;
2981d4f2939cSRui Paulo 	arg->id = id;
2982d4f2939cSRui Paulo 
2983d4f2939cSRui Paulo 	wpas_dbus_register(obj_desc, arg, wpa_dbus_free, NULL,
2984d4f2939cSRui Paulo 			   wpas_dbus_bss_properties,
2985d4f2939cSRui Paulo 			   wpas_dbus_bss_signals);
2986d4f2939cSRui Paulo 
2987d4f2939cSRui Paulo 	wpa_printf(MSG_DEBUG, "dbus: Register BSS object '%s'",
2988d4f2939cSRui Paulo 		   bss_obj_path);
2989d4f2939cSRui Paulo 	if (wpa_dbus_register_object_per_iface(ctrl_iface, bss_obj_path,
2990d4f2939cSRui Paulo 					       wpa_s->ifname, obj_desc)) {
2991d4f2939cSRui Paulo 		wpa_printf(MSG_ERROR,
2992d4f2939cSRui Paulo 			   "Cannot register BSSID dbus object %s.",
2993d4f2939cSRui Paulo 			   bss_obj_path);
2994d4f2939cSRui Paulo 		goto err;
2995d4f2939cSRui Paulo 	}
2996d4f2939cSRui Paulo 
2997d4f2939cSRui Paulo 	wpas_dbus_signal_bss_added(wpa_s, bss_obj_path);
2998d4f2939cSRui Paulo 	wpas_dbus_signal_prop_changed(wpa_s, WPAS_DBUS_PROP_BSSS);
2999d4f2939cSRui Paulo 
3000d4f2939cSRui Paulo 	return 0;
3001d4f2939cSRui Paulo 
3002d4f2939cSRui Paulo err:
3003d4f2939cSRui Paulo 	free_dbus_object_desc(obj_desc);
3004d4f2939cSRui Paulo 	return -1;
3005d4f2939cSRui Paulo }
3006d4f2939cSRui Paulo 
3007d4f2939cSRui Paulo 
3008*4bc52338SCy Schubert static const struct wpa_dbus_property_desc wpas_dbus_sta_properties[] = {
3009*4bc52338SCy Schubert 	{ "Address", WPAS_DBUS_NEW_IFACE_STA, "ay",
3010*4bc52338SCy Schubert 	  wpas_dbus_getter_sta_address,
3011*4bc52338SCy Schubert 	  NULL, NULL
3012*4bc52338SCy Schubert 	},
3013*4bc52338SCy Schubert 	{ "AID", WPAS_DBUS_NEW_IFACE_STA, "q",
3014*4bc52338SCy Schubert 	  wpas_dbus_getter_sta_aid,
3015*4bc52338SCy Schubert 	  NULL, NULL
3016*4bc52338SCy Schubert 	},
3017*4bc52338SCy Schubert 	{ "Capabilities", WPAS_DBUS_NEW_IFACE_STA, "q",
3018*4bc52338SCy Schubert 	  wpas_dbus_getter_sta_caps,
3019*4bc52338SCy Schubert 	  NULL, NULL
3020*4bc52338SCy Schubert 	},
3021*4bc52338SCy Schubert 	{ "RxPackets", WPAS_DBUS_NEW_IFACE_STA, "t",
3022*4bc52338SCy Schubert 	  wpas_dbus_getter_sta_rx_packets,
3023*4bc52338SCy Schubert 	  NULL, NULL
3024*4bc52338SCy Schubert 	},
3025*4bc52338SCy Schubert 	{ "TxPackets", WPAS_DBUS_NEW_IFACE_STA, "t",
3026*4bc52338SCy Schubert 	  wpas_dbus_getter_sta_tx_packets,
3027*4bc52338SCy Schubert 	  NULL, NULL
3028*4bc52338SCy Schubert 	},
3029*4bc52338SCy Schubert 	{ "RxBytes", WPAS_DBUS_NEW_IFACE_STA, "t",
3030*4bc52338SCy Schubert 	  wpas_dbus_getter_sta_rx_bytes,
3031*4bc52338SCy Schubert 	  NULL, NULL
3032*4bc52338SCy Schubert 	},
3033*4bc52338SCy Schubert 	{ "TxBytes", WPAS_DBUS_NEW_IFACE_STA, "t",
3034*4bc52338SCy Schubert 	  wpas_dbus_getter_sta_tx_bytes,
3035*4bc52338SCy Schubert 	  NULL, NULL
3036*4bc52338SCy Schubert 	},
3037*4bc52338SCy Schubert 	{ NULL, NULL, NULL, NULL, NULL, NULL }
3038*4bc52338SCy Schubert };
3039*4bc52338SCy Schubert 
3040*4bc52338SCy Schubert 
3041*4bc52338SCy Schubert static const struct wpa_dbus_signal_desc wpas_dbus_sta_signals[] = {
3042*4bc52338SCy Schubert 	/* Deprecated: use org.freedesktop.DBus.Properties.PropertiesChanged */
3043*4bc52338SCy Schubert 	{ "PropertiesChanged", WPAS_DBUS_NEW_IFACE_STA,
3044*4bc52338SCy Schubert 	  {
3045*4bc52338SCy Schubert 		  { "properties", "a{sv}", ARG_OUT },
3046*4bc52338SCy Schubert 		  END_ARGS
3047*4bc52338SCy Schubert 	  }
3048*4bc52338SCy Schubert 	},
3049*4bc52338SCy Schubert 	{ NULL, NULL, { END_ARGS } }
3050*4bc52338SCy Schubert };
3051*4bc52338SCy Schubert 
3052*4bc52338SCy Schubert 
3053*4bc52338SCy Schubert /**
3054*4bc52338SCy Schubert  * wpas_dbus_unregister_sta - Unregister a connected station from dbus
3055*4bc52338SCy Schubert  * @wpa_s: wpa_supplicant interface structure
3056*4bc52338SCy Schubert  * @sta: station MAC address
3057*4bc52338SCy Schubert  * Returns: 0 on success, -1 on failure
3058*4bc52338SCy Schubert  *
3059*4bc52338SCy Schubert  * Unregisters STA representing object from dbus.
3060*4bc52338SCy Schubert  */
3061*4bc52338SCy Schubert int wpas_dbus_unregister_sta(struct wpa_supplicant *wpa_s, const u8 *sta)
3062*4bc52338SCy Schubert {
3063*4bc52338SCy Schubert 	struct wpas_dbus_priv *ctrl_iface;
3064*4bc52338SCy Schubert 	char station_obj_path[WPAS_DBUS_OBJECT_PATH_MAX];
3065*4bc52338SCy Schubert 
3066*4bc52338SCy Schubert 	/* Do nothing if the control interface is not turned on */
3067*4bc52338SCy Schubert 	if (!wpa_s || !wpa_s->global)
3068*4bc52338SCy Schubert 		return 0;
3069*4bc52338SCy Schubert 	ctrl_iface = wpa_s->global->dbus;
3070*4bc52338SCy Schubert 	if (!ctrl_iface)
3071*4bc52338SCy Schubert 		return 0;
3072*4bc52338SCy Schubert 
3073*4bc52338SCy Schubert 	os_snprintf(station_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
3074*4bc52338SCy Schubert 		    "%s/" WPAS_DBUS_NEW_STAS_PART "/" COMPACT_MACSTR,
3075*4bc52338SCy Schubert 		    wpa_s->dbus_new_path, MAC2STR(sta));
3076*4bc52338SCy Schubert 
3077*4bc52338SCy Schubert 	wpa_printf(MSG_DEBUG, "dbus: Unregister STA object '%s'",
3078*4bc52338SCy Schubert 		   station_obj_path);
3079*4bc52338SCy Schubert 	if (wpa_dbus_unregister_object_per_iface(ctrl_iface,
3080*4bc52338SCy Schubert 						 station_obj_path)) {
3081*4bc52338SCy Schubert 		wpa_printf(MSG_ERROR, "dbus: Cannot unregister STA object %s",
3082*4bc52338SCy Schubert 			   station_obj_path);
3083*4bc52338SCy Schubert 		return -1;
3084*4bc52338SCy Schubert 	}
3085*4bc52338SCy Schubert 
3086*4bc52338SCy Schubert 	wpas_dbus_signal_station_removed(wpa_s, station_obj_path);
3087*4bc52338SCy Schubert 	wpas_dbus_signal_prop_changed(wpa_s, WPAS_DBUS_PROP_STATIONS);
3088*4bc52338SCy Schubert 
3089*4bc52338SCy Schubert 	return 0;
3090*4bc52338SCy Schubert }
3091*4bc52338SCy Schubert 
3092*4bc52338SCy Schubert 
3093*4bc52338SCy Schubert /**
3094*4bc52338SCy Schubert  * wpas_dbus_register_sta - Register a connected station with dbus
3095*4bc52338SCy Schubert  * @wpa_s: wpa_supplicant interface structure
3096*4bc52338SCy Schubert  * @sta: station MAC address
3097*4bc52338SCy Schubert  * Returns: 0 on success, -1 on failure
3098*4bc52338SCy Schubert  *
3099*4bc52338SCy Schubert  * Registers STA representing object with dbus.
3100*4bc52338SCy Schubert  */
3101*4bc52338SCy Schubert int wpas_dbus_register_sta(struct wpa_supplicant *wpa_s, const u8 *sta)
3102*4bc52338SCy Schubert {
3103*4bc52338SCy Schubert 	struct wpas_dbus_priv *ctrl_iface;
3104*4bc52338SCy Schubert 	struct wpa_dbus_object_desc *obj_desc;
3105*4bc52338SCy Schubert 	char station_obj_path[WPAS_DBUS_OBJECT_PATH_MAX];
3106*4bc52338SCy Schubert 	struct sta_handler_args *arg;
3107*4bc52338SCy Schubert 
3108*4bc52338SCy Schubert 	/* Do nothing if the control interface is not turned on */
3109*4bc52338SCy Schubert 	if (!wpa_s || !wpa_s->global)
3110*4bc52338SCy Schubert 		return 0;
3111*4bc52338SCy Schubert 	ctrl_iface = wpa_s->global->dbus;
3112*4bc52338SCy Schubert 	if (!ctrl_iface)
3113*4bc52338SCy Schubert 		return 0;
3114*4bc52338SCy Schubert 
3115*4bc52338SCy Schubert 	os_snprintf(station_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
3116*4bc52338SCy Schubert 		    "%s/" WPAS_DBUS_NEW_STAS_PART "/" COMPACT_MACSTR,
3117*4bc52338SCy Schubert 		    wpa_s->dbus_new_path, MAC2STR(sta));
3118*4bc52338SCy Schubert 
3119*4bc52338SCy Schubert 	obj_desc = os_zalloc(sizeof(struct wpa_dbus_object_desc));
3120*4bc52338SCy Schubert 	if (!obj_desc) {
3121*4bc52338SCy Schubert 		wpa_printf(MSG_ERROR,
3122*4bc52338SCy Schubert 			   "Not enough memory to create object description");
3123*4bc52338SCy Schubert 		goto err;
3124*4bc52338SCy Schubert 	}
3125*4bc52338SCy Schubert 
3126*4bc52338SCy Schubert 	arg = os_zalloc(sizeof(struct sta_handler_args));
3127*4bc52338SCy Schubert 	if (!arg) {
3128*4bc52338SCy Schubert 		wpa_printf(MSG_ERROR,
3129*4bc52338SCy Schubert 			   "Not enough memory to create arguments for handler");
3130*4bc52338SCy Schubert 		goto err;
3131*4bc52338SCy Schubert 	}
3132*4bc52338SCy Schubert 	arg->wpa_s = wpa_s;
3133*4bc52338SCy Schubert 	arg->sta = sta;
3134*4bc52338SCy Schubert 
3135*4bc52338SCy Schubert 	wpas_dbus_register(obj_desc, arg, wpa_dbus_free, NULL,
3136*4bc52338SCy Schubert 			   wpas_dbus_sta_properties, wpas_dbus_sta_signals);
3137*4bc52338SCy Schubert 
3138*4bc52338SCy Schubert 	wpa_printf(MSG_DEBUG, "dbus: Register STA object '%s'",
3139*4bc52338SCy Schubert 		   station_obj_path);
3140*4bc52338SCy Schubert 	if (wpa_dbus_register_object_per_iface(ctrl_iface, station_obj_path,
3141*4bc52338SCy Schubert 					       wpa_s->ifname, obj_desc)) {
3142*4bc52338SCy Schubert 		wpa_printf(MSG_ERROR,
3143*4bc52338SCy Schubert 			   "Cannot register STA dbus object %s",
3144*4bc52338SCy Schubert 			   station_obj_path);
3145*4bc52338SCy Schubert 		goto err;
3146*4bc52338SCy Schubert 	}
3147*4bc52338SCy Schubert 
3148*4bc52338SCy Schubert 	wpas_dbus_signal_station_added(wpa_s, station_obj_path);
3149*4bc52338SCy Schubert 	wpas_dbus_signal_prop_changed(wpa_s, WPAS_DBUS_PROP_STATIONS);
3150*4bc52338SCy Schubert 
3151*4bc52338SCy Schubert 	return 0;
3152*4bc52338SCy Schubert 
3153*4bc52338SCy Schubert err:
3154*4bc52338SCy Schubert 	free_dbus_object_desc(obj_desc);
3155*4bc52338SCy Schubert 	return -1;
3156*4bc52338SCy Schubert }
3157*4bc52338SCy Schubert 
3158*4bc52338SCy Schubert 
3159d4f2939cSRui Paulo static const struct wpa_dbus_method_desc wpas_dbus_interface_methods[] = {
3160d4f2939cSRui Paulo 	{ "Scan", WPAS_DBUS_NEW_IFACE_INTERFACE,
31615b9c547cSRui Paulo 	  (WPADBusMethodHandler) wpas_dbus_handler_scan,
3162d4f2939cSRui Paulo 	  {
3163d4f2939cSRui Paulo 		  { "args", "a{sv}", ARG_IN },
3164d4f2939cSRui Paulo 		  END_ARGS
3165d4f2939cSRui Paulo 	  }
3166d4f2939cSRui Paulo 	},
31675b9c547cSRui Paulo 	{ "SignalPoll", WPAS_DBUS_NEW_IFACE_INTERFACE,
31685b9c547cSRui Paulo 	  (WPADBusMethodHandler) wpas_dbus_handler_signal_poll,
31695b9c547cSRui Paulo 	  {
31705b9c547cSRui Paulo 		  { "args", "a{sv}", ARG_OUT },
31715b9c547cSRui Paulo 		  END_ARGS
31725b9c547cSRui Paulo 	  }
31735b9c547cSRui Paulo 	},
3174d4f2939cSRui Paulo 	{ "Disconnect", WPAS_DBUS_NEW_IFACE_INTERFACE,
31755b9c547cSRui Paulo 	  (WPADBusMethodHandler) wpas_dbus_handler_disconnect,
3176d4f2939cSRui Paulo 	  {
3177d4f2939cSRui Paulo 		  END_ARGS
3178d4f2939cSRui Paulo 	  }
3179d4f2939cSRui Paulo 	},
3180d4f2939cSRui Paulo 	{ "AddNetwork", WPAS_DBUS_NEW_IFACE_INTERFACE,
31815b9c547cSRui Paulo 	  (WPADBusMethodHandler) wpas_dbus_handler_add_network,
3182d4f2939cSRui Paulo 	  {
3183d4f2939cSRui Paulo 		  { "args", "a{sv}", ARG_IN },
3184d4f2939cSRui Paulo 		  { "path", "o", ARG_OUT },
3185d4f2939cSRui Paulo 		  END_ARGS
3186d4f2939cSRui Paulo 	  }
3187d4f2939cSRui Paulo 	},
3188d4f2939cSRui Paulo 	{ "Reassociate", WPAS_DBUS_NEW_IFACE_INTERFACE,
31895b9c547cSRui Paulo 	  (WPADBusMethodHandler) wpas_dbus_handler_reassociate,
31905b9c547cSRui Paulo 	  {
31915b9c547cSRui Paulo 		  END_ARGS
31925b9c547cSRui Paulo 	  }
31935b9c547cSRui Paulo 	},
31945b9c547cSRui Paulo 	{ "Reattach", WPAS_DBUS_NEW_IFACE_INTERFACE,
31955b9c547cSRui Paulo 	  (WPADBusMethodHandler) wpas_dbus_handler_reattach,
3196d4f2939cSRui Paulo 	  {
3197d4f2939cSRui Paulo 		  END_ARGS
3198d4f2939cSRui Paulo 	  }
3199d4f2939cSRui Paulo 	},
3200325151a3SRui Paulo 	{ "Reconnect", WPAS_DBUS_NEW_IFACE_INTERFACE,
3201325151a3SRui Paulo 	  (WPADBusMethodHandler) wpas_dbus_handler_reconnect,
3202325151a3SRui Paulo 	  {
3203325151a3SRui Paulo 		  END_ARGS
3204325151a3SRui Paulo 	  }
3205325151a3SRui Paulo 	},
3206d4f2939cSRui Paulo 	{ "RemoveNetwork", WPAS_DBUS_NEW_IFACE_INTERFACE,
32075b9c547cSRui Paulo 	  (WPADBusMethodHandler) wpas_dbus_handler_remove_network,
3208d4f2939cSRui Paulo 	  {
3209d4f2939cSRui Paulo 		  { "path", "o", ARG_IN },
3210d4f2939cSRui Paulo 		  END_ARGS
3211d4f2939cSRui Paulo 	  }
3212d4f2939cSRui Paulo 	},
3213d4f2939cSRui Paulo 	{ "RemoveAllNetworks", WPAS_DBUS_NEW_IFACE_INTERFACE,
32145b9c547cSRui Paulo 	  (WPADBusMethodHandler) wpas_dbus_handler_remove_all_networks,
3215d4f2939cSRui Paulo 	  {
3216d4f2939cSRui Paulo 		  END_ARGS
3217d4f2939cSRui Paulo 	  }
3218d4f2939cSRui Paulo 	},
3219d4f2939cSRui Paulo 	{ "SelectNetwork", WPAS_DBUS_NEW_IFACE_INTERFACE,
32205b9c547cSRui Paulo 	  (WPADBusMethodHandler) wpas_dbus_handler_select_network,
3221d4f2939cSRui Paulo 	  {
3222d4f2939cSRui Paulo 		  { "path", "o", ARG_IN },
3223d4f2939cSRui Paulo 		  END_ARGS
3224d4f2939cSRui Paulo 	  }
3225d4f2939cSRui Paulo 	},
3226d4f2939cSRui Paulo 	{ "NetworkReply", WPAS_DBUS_NEW_IFACE_INTERFACE,
32275b9c547cSRui Paulo 	  (WPADBusMethodHandler) wpas_dbus_handler_network_reply,
3228d4f2939cSRui Paulo 	  {
3229d4f2939cSRui Paulo 		  { "path", "o", ARG_IN },
3230d4f2939cSRui Paulo 		  { "field", "s", ARG_IN },
3231d4f2939cSRui Paulo 		  { "value", "s", ARG_IN },
3232d4f2939cSRui Paulo 		  END_ARGS
3233d4f2939cSRui Paulo 	  }
3234d4f2939cSRui Paulo 	},
32355b9c547cSRui Paulo #ifndef CONFIG_NO_CONFIG_BLOBS
3236d4f2939cSRui Paulo 	{ "AddBlob", WPAS_DBUS_NEW_IFACE_INTERFACE,
32375b9c547cSRui Paulo 	  (WPADBusMethodHandler) wpas_dbus_handler_add_blob,
3238d4f2939cSRui Paulo 	  {
3239d4f2939cSRui Paulo 		  { "name", "s", ARG_IN },
3240d4f2939cSRui Paulo 		  { "data", "ay", ARG_IN },
3241d4f2939cSRui Paulo 		  END_ARGS
3242d4f2939cSRui Paulo 	  }
3243d4f2939cSRui Paulo 	},
3244d4f2939cSRui Paulo 	{ "GetBlob", WPAS_DBUS_NEW_IFACE_INTERFACE,
32455b9c547cSRui Paulo 	  (WPADBusMethodHandler) wpas_dbus_handler_get_blob,
3246d4f2939cSRui Paulo 	  {
3247d4f2939cSRui Paulo 		  { "name", "s", ARG_IN },
3248d4f2939cSRui Paulo 		  { "data", "ay", ARG_OUT },
3249d4f2939cSRui Paulo 		  END_ARGS
3250d4f2939cSRui Paulo 	  }
3251d4f2939cSRui Paulo 	},
3252d4f2939cSRui Paulo 	{ "RemoveBlob", WPAS_DBUS_NEW_IFACE_INTERFACE,
32535b9c547cSRui Paulo 	  (WPADBusMethodHandler) wpas_dbus_handler_remove_blob,
3254d4f2939cSRui Paulo 	  {
3255d4f2939cSRui Paulo 		  { "name", "s", ARG_IN },
3256d4f2939cSRui Paulo 		  END_ARGS
3257d4f2939cSRui Paulo 	  }
3258d4f2939cSRui Paulo 	},
32595b9c547cSRui Paulo #endif /* CONFIG_NO_CONFIG_BLOBS */
32605b9c547cSRui Paulo 	{ "SetPKCS11EngineAndModulePath", WPAS_DBUS_NEW_IFACE_INTERFACE,
32615b9c547cSRui Paulo 	  (WPADBusMethodHandler)
32625b9c547cSRui Paulo 	  wpas_dbus_handler_set_pkcs11_engine_and_module_path,
32635b9c547cSRui Paulo 	  {
32645b9c547cSRui Paulo 		  { "pkcs11_engine_path", "s", ARG_IN },
32655b9c547cSRui Paulo 		  { "pkcs11_module_path", "s", ARG_IN },
32665b9c547cSRui Paulo 		  END_ARGS
32675b9c547cSRui Paulo 	  }
32685b9c547cSRui Paulo 	},
3269d4f2939cSRui Paulo #ifdef CONFIG_WPS
3270d4f2939cSRui Paulo 	{ "Start", WPAS_DBUS_NEW_IFACE_WPS,
32715b9c547cSRui Paulo 	  (WPADBusMethodHandler) wpas_dbus_handler_wps_start,
3272d4f2939cSRui Paulo 	  {
3273d4f2939cSRui Paulo 		  { "args", "a{sv}", ARG_IN },
3274d4f2939cSRui Paulo 		  { "output", "a{sv}", ARG_OUT },
3275d4f2939cSRui Paulo 		  END_ARGS
3276d4f2939cSRui Paulo 	  }
3277d4f2939cSRui Paulo 	},
3278325151a3SRui Paulo 	{ "Cancel", WPAS_DBUS_NEW_IFACE_WPS,
3279325151a3SRui Paulo 	  (WPADBusMethodHandler) wpas_dbus_handler_wps_cancel,
3280325151a3SRui Paulo 	  {
3281325151a3SRui Paulo 		  END_ARGS
3282325151a3SRui Paulo 	  }
3283325151a3SRui Paulo 	},
3284d4f2939cSRui Paulo #endif /* CONFIG_WPS */
3285d4f2939cSRui Paulo #ifdef CONFIG_P2P
3286d4f2939cSRui Paulo 	{ "Find", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
3287d4f2939cSRui Paulo 	  (WPADBusMethodHandler) wpas_dbus_handler_p2p_find,
3288d4f2939cSRui Paulo 	  {
3289d4f2939cSRui Paulo 		  { "args", "a{sv}", ARG_IN },
3290d4f2939cSRui Paulo 		  END_ARGS
3291d4f2939cSRui Paulo 	  }
3292d4f2939cSRui Paulo 	},
3293d4f2939cSRui Paulo 	{ "StopFind", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
3294d4f2939cSRui Paulo 	  (WPADBusMethodHandler) wpas_dbus_handler_p2p_stop_find,
3295d4f2939cSRui Paulo 	  {
3296d4f2939cSRui Paulo 		  END_ARGS
3297d4f2939cSRui Paulo 	  }
3298d4f2939cSRui Paulo 	},
3299d4f2939cSRui Paulo 	{ "Listen", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
3300d4f2939cSRui Paulo 	  (WPADBusMethodHandler) wpas_dbus_handler_p2p_listen,
3301d4f2939cSRui Paulo 	  {
3302d4f2939cSRui Paulo 		  { "timeout", "i", ARG_IN },
3303d4f2939cSRui Paulo 		  END_ARGS
3304d4f2939cSRui Paulo 	  }
3305d4f2939cSRui Paulo 	},
3306d4f2939cSRui Paulo 	{ "ExtendedListen", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
3307d4f2939cSRui Paulo 	  (WPADBusMethodHandler) wpas_dbus_handler_p2p_extendedlisten,
3308d4f2939cSRui Paulo 	  {
3309d4f2939cSRui Paulo 		  { "args", "a{sv}", ARG_IN },
3310d4f2939cSRui Paulo 		  END_ARGS
3311d4f2939cSRui Paulo 	  }
3312d4f2939cSRui Paulo 	},
3313d4f2939cSRui Paulo 	{ "PresenceRequest", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
3314d4f2939cSRui Paulo 	  (WPADBusMethodHandler) wpas_dbus_handler_p2p_presence_request,
3315d4f2939cSRui Paulo 	  {
3316d4f2939cSRui Paulo 		  { "args", "a{sv}", ARG_IN },
3317d4f2939cSRui Paulo 		  END_ARGS
3318d4f2939cSRui Paulo 	  }
3319d4f2939cSRui Paulo 	},
3320d4f2939cSRui Paulo 	{ "ProvisionDiscoveryRequest", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
3321d4f2939cSRui Paulo 	  (WPADBusMethodHandler) wpas_dbus_handler_p2p_prov_disc_req,
3322d4f2939cSRui Paulo 	  {
3323d4f2939cSRui Paulo 		  { "peer", "o", ARG_IN },
3324d4f2939cSRui Paulo 		  { "config_method", "s", ARG_IN },
3325d4f2939cSRui Paulo 		  END_ARGS
3326d4f2939cSRui Paulo 	  }
3327d4f2939cSRui Paulo 	},
3328d4f2939cSRui Paulo 	{ "Connect", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
3329d4f2939cSRui Paulo 	  (WPADBusMethodHandler) wpas_dbus_handler_p2p_connect,
3330d4f2939cSRui Paulo 	  {
3331d4f2939cSRui Paulo 		  { "args", "a{sv}", ARG_IN },
3332d4f2939cSRui Paulo 		  { "generated_pin", "s", ARG_OUT },
3333d4f2939cSRui Paulo 		  END_ARGS
3334d4f2939cSRui Paulo 	  }
3335d4f2939cSRui Paulo 	},
3336d4f2939cSRui Paulo 	{ "GroupAdd", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
3337d4f2939cSRui Paulo 	  (WPADBusMethodHandler) wpas_dbus_handler_p2p_group_add,
3338d4f2939cSRui Paulo 	  {
3339d4f2939cSRui Paulo 		  { "args", "a{sv}", ARG_IN },
3340d4f2939cSRui Paulo 		  END_ARGS
3341d4f2939cSRui Paulo 	  }
3342d4f2939cSRui Paulo 	},
3343325151a3SRui Paulo 	{ "Cancel", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
3344325151a3SRui Paulo 	  (WPADBusMethodHandler) wpas_dbus_handler_p2p_cancel,
3345325151a3SRui Paulo 	  {
3346325151a3SRui Paulo 		  END_ARGS
3347325151a3SRui Paulo 	  }
3348325151a3SRui Paulo 	},
3349d4f2939cSRui Paulo 	{ "Invite", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
3350d4f2939cSRui Paulo 	  (WPADBusMethodHandler) wpas_dbus_handler_p2p_invite,
3351d4f2939cSRui Paulo 	  {
3352d4f2939cSRui Paulo 		  { "args", "a{sv}", ARG_IN },
3353d4f2939cSRui Paulo 		  END_ARGS
3354d4f2939cSRui Paulo 	  }
3355d4f2939cSRui Paulo 	},
3356d4f2939cSRui Paulo 	{ "Disconnect", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
3357d4f2939cSRui Paulo 	  (WPADBusMethodHandler) wpas_dbus_handler_p2p_disconnect,
3358d4f2939cSRui Paulo 	  {
3359d4f2939cSRui Paulo 		  END_ARGS
3360d4f2939cSRui Paulo 	  }
3361d4f2939cSRui Paulo 	},
3362d4f2939cSRui Paulo 	{ "RejectPeer", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
3363d4f2939cSRui Paulo 	  (WPADBusMethodHandler) wpas_dbus_handler_p2p_rejectpeer,
3364d4f2939cSRui Paulo 	  {
3365d4f2939cSRui Paulo 		  { "peer", "o", ARG_IN },
3366d4f2939cSRui Paulo 		  END_ARGS
3367d4f2939cSRui Paulo 	  }
3368d4f2939cSRui Paulo 	},
3369325151a3SRui Paulo 	{ "RemoveClient", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
3370325151a3SRui Paulo 	  (WPADBusMethodHandler) wpas_dbus_handler_p2p_remove_client,
3371325151a3SRui Paulo 	  {
3372325151a3SRui Paulo 		  { "args", "a{sv}", ARG_IN },
3373325151a3SRui Paulo 		  END_ARGS
3374325151a3SRui Paulo 	  }
3375325151a3SRui Paulo 	},
3376d4f2939cSRui Paulo 	{ "Flush", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
3377d4f2939cSRui Paulo 	  (WPADBusMethodHandler) wpas_dbus_handler_p2p_flush,
3378d4f2939cSRui Paulo 	  {
3379d4f2939cSRui Paulo 		  END_ARGS
3380d4f2939cSRui Paulo 	  }
3381d4f2939cSRui Paulo 	},
3382d4f2939cSRui Paulo 	{ "AddService", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
3383d4f2939cSRui Paulo 	  (WPADBusMethodHandler) wpas_dbus_handler_p2p_add_service,
3384d4f2939cSRui Paulo 	  {
3385d4f2939cSRui Paulo 		  { "args", "a{sv}", ARG_IN },
3386d4f2939cSRui Paulo 		  END_ARGS
3387d4f2939cSRui Paulo 	  }
3388d4f2939cSRui Paulo 	},
3389d4f2939cSRui Paulo 	{ "DeleteService", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
3390d4f2939cSRui Paulo 	  (WPADBusMethodHandler) wpas_dbus_handler_p2p_delete_service,
3391d4f2939cSRui Paulo 	  {
3392d4f2939cSRui Paulo 		  { "args", "a{sv}", ARG_IN },
3393d4f2939cSRui Paulo 		  END_ARGS
3394d4f2939cSRui Paulo 	  }
3395d4f2939cSRui Paulo 	},
3396d4f2939cSRui Paulo 	{ "FlushService", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
3397d4f2939cSRui Paulo 	  (WPADBusMethodHandler) wpas_dbus_handler_p2p_flush_service,
3398d4f2939cSRui Paulo 	  {
3399d4f2939cSRui Paulo 		  END_ARGS
3400d4f2939cSRui Paulo 	  }
3401d4f2939cSRui Paulo 	},
3402d4f2939cSRui Paulo 	{ "ServiceDiscoveryRequest", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
3403d4f2939cSRui Paulo 	  (WPADBusMethodHandler) wpas_dbus_handler_p2p_service_sd_req,
3404d4f2939cSRui Paulo 	  {
3405d4f2939cSRui Paulo 		  { "args", "a{sv}", ARG_IN },
34065b9c547cSRui Paulo 		  { "ref", "t", ARG_OUT },
3407d4f2939cSRui Paulo 		  END_ARGS
3408d4f2939cSRui Paulo 	  }
3409d4f2939cSRui Paulo 	},
3410d4f2939cSRui Paulo 	{ "ServiceDiscoveryResponse", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
3411d4f2939cSRui Paulo 	  (WPADBusMethodHandler) wpas_dbus_handler_p2p_service_sd_res,
3412d4f2939cSRui Paulo 	  {
3413d4f2939cSRui Paulo 		  { "args", "a{sv}", ARG_IN },
3414d4f2939cSRui Paulo 		  END_ARGS
3415d4f2939cSRui Paulo 	  }
3416d4f2939cSRui Paulo 	},
3417d4f2939cSRui Paulo 	{ "ServiceDiscoveryCancelRequest", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
3418d4f2939cSRui Paulo 	  (WPADBusMethodHandler) wpas_dbus_handler_p2p_service_sd_cancel_req,
3419d4f2939cSRui Paulo 	  {
3420d4f2939cSRui Paulo 		  { "args", "t", ARG_IN },
3421d4f2939cSRui Paulo 		  END_ARGS
3422d4f2939cSRui Paulo 	  }
3423d4f2939cSRui Paulo 	},
3424d4f2939cSRui Paulo 	{ "ServiceUpdate", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
3425d4f2939cSRui Paulo 	  (WPADBusMethodHandler) wpas_dbus_handler_p2p_service_update,
3426d4f2939cSRui Paulo 	  {
3427d4f2939cSRui Paulo 		  END_ARGS
3428d4f2939cSRui Paulo 	  }
3429d4f2939cSRui Paulo 	},
3430d4f2939cSRui Paulo 	{ "ServiceDiscoveryExternal", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
3431d4f2939cSRui Paulo 	  (WPADBusMethodHandler) wpas_dbus_handler_p2p_serv_disc_external,
3432d4f2939cSRui Paulo 	  {
3433d4f2939cSRui Paulo 		  { "arg", "i", ARG_IN },
3434d4f2939cSRui Paulo 		  END_ARGS
3435d4f2939cSRui Paulo 	  }
3436d4f2939cSRui Paulo 	},
3437d4f2939cSRui Paulo 	{ "AddPersistentGroup", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
3438d4f2939cSRui Paulo 	  (WPADBusMethodHandler) wpas_dbus_handler_add_persistent_group,
3439d4f2939cSRui Paulo 	  {
3440d4f2939cSRui Paulo 		  { "args", "a{sv}", ARG_IN },
3441d4f2939cSRui Paulo 		  { "path", "o", ARG_OUT },
3442d4f2939cSRui Paulo 		  END_ARGS
3443d4f2939cSRui Paulo 	  }
3444d4f2939cSRui Paulo 	},
3445d4f2939cSRui Paulo 	{ "RemovePersistentGroup", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
3446d4f2939cSRui Paulo 	  (WPADBusMethodHandler) wpas_dbus_handler_remove_persistent_group,
3447d4f2939cSRui Paulo 	  {
3448d4f2939cSRui Paulo 		  { "path", "o", ARG_IN },
3449d4f2939cSRui Paulo 		  END_ARGS
3450d4f2939cSRui Paulo 	  }
3451d4f2939cSRui Paulo 	},
3452d4f2939cSRui Paulo 	{ "RemoveAllPersistentGroups", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
3453d4f2939cSRui Paulo 	  (WPADBusMethodHandler)
3454d4f2939cSRui Paulo 	  wpas_dbus_handler_remove_all_persistent_groups,
3455d4f2939cSRui Paulo 	  {
3456d4f2939cSRui Paulo 		  END_ARGS
3457d4f2939cSRui Paulo 	  }
3458d4f2939cSRui Paulo 	},
3459d4f2939cSRui Paulo #endif /* CONFIG_P2P */
3460d4f2939cSRui Paulo 	{ "FlushBSS", WPAS_DBUS_NEW_IFACE_INTERFACE,
34615b9c547cSRui Paulo 	  (WPADBusMethodHandler) wpas_dbus_handler_flush_bss,
3462d4f2939cSRui Paulo 	  {
3463d4f2939cSRui Paulo 		  { "age", "u", ARG_IN },
3464d4f2939cSRui Paulo 		  END_ARGS
3465d4f2939cSRui Paulo 	  }
3466d4f2939cSRui Paulo 	},
3467d4f2939cSRui Paulo #ifdef CONFIG_AP
3468d4f2939cSRui Paulo 	{ "SubscribeProbeReq", WPAS_DBUS_NEW_IFACE_INTERFACE,
3469d4f2939cSRui Paulo 	  (WPADBusMethodHandler) wpas_dbus_handler_subscribe_preq,
3470d4f2939cSRui Paulo 	  {
3471d4f2939cSRui Paulo 		  END_ARGS
3472d4f2939cSRui Paulo 	  }
3473d4f2939cSRui Paulo 	},
3474d4f2939cSRui Paulo 	{ "UnsubscribeProbeReq", WPAS_DBUS_NEW_IFACE_INTERFACE,
3475d4f2939cSRui Paulo 	  (WPADBusMethodHandler) wpas_dbus_handler_unsubscribe_preq,
3476d4f2939cSRui Paulo 	  {
3477d4f2939cSRui Paulo 		  END_ARGS
3478d4f2939cSRui Paulo 	  }
3479d4f2939cSRui Paulo 	},
3480d4f2939cSRui Paulo #endif /* CONFIG_AP */
34815b9c547cSRui Paulo 	{ "EAPLogoff", WPAS_DBUS_NEW_IFACE_INTERFACE,
34825b9c547cSRui Paulo 	  (WPADBusMethodHandler) wpas_dbus_handler_eap_logoff,
34835b9c547cSRui Paulo 	  {
34845b9c547cSRui Paulo 		  END_ARGS
34855b9c547cSRui Paulo 	  }
34865b9c547cSRui Paulo 	},
34875b9c547cSRui Paulo 	{ "EAPLogon", WPAS_DBUS_NEW_IFACE_INTERFACE,
34885b9c547cSRui Paulo 	  (WPADBusMethodHandler) wpas_dbus_handler_eap_logon,
34895b9c547cSRui Paulo 	  {
34905b9c547cSRui Paulo 		  END_ARGS
34915b9c547cSRui Paulo 	  }
34925b9c547cSRui Paulo 	},
34935b9c547cSRui Paulo #ifdef CONFIG_AUTOSCAN
34945b9c547cSRui Paulo 	{ "AutoScan", WPAS_DBUS_NEW_IFACE_INTERFACE,
34955b9c547cSRui Paulo 	  (WPADBusMethodHandler) wpas_dbus_handler_autoscan,
34965b9c547cSRui Paulo 	  {
34975b9c547cSRui Paulo 		  { "arg", "s", ARG_IN },
34985b9c547cSRui Paulo 		  END_ARGS
34995b9c547cSRui Paulo 	  }
35005b9c547cSRui Paulo 	},
35015b9c547cSRui Paulo #endif /* CONFIG_AUTOSCAN */
35025b9c547cSRui Paulo #ifdef CONFIG_TDLS
35035b9c547cSRui Paulo 	{ "TDLSDiscover", WPAS_DBUS_NEW_IFACE_INTERFACE,
35045b9c547cSRui Paulo 	  (WPADBusMethodHandler) wpas_dbus_handler_tdls_discover,
35055b9c547cSRui Paulo 	  {
35065b9c547cSRui Paulo 		  { "peer_address", "s", ARG_IN },
35075b9c547cSRui Paulo 		  END_ARGS
35085b9c547cSRui Paulo 	  }
35095b9c547cSRui Paulo 	},
35105b9c547cSRui Paulo 	{ "TDLSSetup", WPAS_DBUS_NEW_IFACE_INTERFACE,
35115b9c547cSRui Paulo 	  (WPADBusMethodHandler) wpas_dbus_handler_tdls_setup,
35125b9c547cSRui Paulo 	  {
35135b9c547cSRui Paulo 		  { "peer_address", "s", ARG_IN },
35145b9c547cSRui Paulo 		  END_ARGS
35155b9c547cSRui Paulo 	  }
35165b9c547cSRui Paulo 	},
35175b9c547cSRui Paulo 	{ "TDLSStatus", WPAS_DBUS_NEW_IFACE_INTERFACE,
35185b9c547cSRui Paulo 	  (WPADBusMethodHandler) wpas_dbus_handler_tdls_status,
35195b9c547cSRui Paulo 	  {
35205b9c547cSRui Paulo 		  { "peer_address", "s", ARG_IN },
35215b9c547cSRui Paulo 		  { "status", "s", ARG_OUT },
35225b9c547cSRui Paulo 		  END_ARGS
35235b9c547cSRui Paulo 	  }
35245b9c547cSRui Paulo 	},
35255b9c547cSRui Paulo 	{ "TDLSTeardown", WPAS_DBUS_NEW_IFACE_INTERFACE,
35265b9c547cSRui Paulo 	  (WPADBusMethodHandler) wpas_dbus_handler_tdls_teardown,
35275b9c547cSRui Paulo 	  {
35285b9c547cSRui Paulo 		  { "peer_address", "s", ARG_IN },
35295b9c547cSRui Paulo 		  END_ARGS
35305b9c547cSRui Paulo 	  }
35315b9c547cSRui Paulo 	},
353285732ac8SCy Schubert 	{ "TDLSChannelSwitch", WPAS_DBUS_NEW_IFACE_INTERFACE,
353385732ac8SCy Schubert 	  (WPADBusMethodHandler) wpas_dbus_handler_tdls_channel_switch,
353485732ac8SCy Schubert 	  {
353585732ac8SCy Schubert 		  { "args", "a{sv}", ARG_IN },
353685732ac8SCy Schubert 		  END_ARGS
353785732ac8SCy Schubert 	  }
353885732ac8SCy Schubert 	},
353985732ac8SCy Schubert 	{ "TDLSCancelChannelSwitch", WPAS_DBUS_NEW_IFACE_INTERFACE,
354085732ac8SCy Schubert 	  (WPADBusMethodHandler) wpas_dbus_handler_tdls_cancel_channel_switch,
354185732ac8SCy Schubert 	  {
354285732ac8SCy Schubert 		  { "peer_address", "s", ARG_IN },
354385732ac8SCy Schubert 		  END_ARGS
354485732ac8SCy Schubert 	  }
354585732ac8SCy Schubert 	},
35465b9c547cSRui Paulo #endif /* CONFIG_TDLS */
3547780fb4a2SCy Schubert 	{ "VendorElemAdd", WPAS_DBUS_NEW_IFACE_INTERFACE,
3548780fb4a2SCy Schubert 	  (WPADBusMethodHandler) wpas_dbus_handler_vendor_elem_add,
3549780fb4a2SCy Schubert 	  {
3550780fb4a2SCy Schubert 		  { "frame_id", "i", ARG_IN },
3551780fb4a2SCy Schubert 		  { "ielems", "ay", ARG_IN },
3552780fb4a2SCy Schubert 		  END_ARGS
3553780fb4a2SCy Schubert 	  }
3554780fb4a2SCy Schubert 	},
3555780fb4a2SCy Schubert 	{ "VendorElemGet", WPAS_DBUS_NEW_IFACE_INTERFACE,
3556780fb4a2SCy Schubert 	  (WPADBusMethodHandler) wpas_dbus_handler_vendor_elem_get,
3557780fb4a2SCy Schubert 	  {
3558780fb4a2SCy Schubert 		  { "frame_id", "i", ARG_IN },
3559780fb4a2SCy Schubert 		  { "ielems", "ay", ARG_OUT },
3560780fb4a2SCy Schubert 		  END_ARGS
3561780fb4a2SCy Schubert 	  }
3562780fb4a2SCy Schubert 	},
3563780fb4a2SCy Schubert 	{ "VendorElemRem", WPAS_DBUS_NEW_IFACE_INTERFACE,
3564780fb4a2SCy Schubert 	  (WPADBusMethodHandler) wpas_dbus_handler_vendor_elem_remove,
3565780fb4a2SCy Schubert 	  {
3566780fb4a2SCy Schubert 		  { "frame_id", "i", ARG_IN },
3567780fb4a2SCy Schubert 		  { "ielems", "ay", ARG_IN },
3568780fb4a2SCy Schubert 		  END_ARGS
3569780fb4a2SCy Schubert 	  }
3570780fb4a2SCy Schubert 	},
3571780fb4a2SCy Schubert #ifndef CONFIG_NO_CONFIG_WRITE
3572780fb4a2SCy Schubert 	{ "SaveConfig", WPAS_DBUS_NEW_IFACE_INTERFACE,
3573780fb4a2SCy Schubert 	  (WPADBusMethodHandler) wpas_dbus_handler_save_config,
3574780fb4a2SCy Schubert 	  {
3575780fb4a2SCy Schubert 		  END_ARGS
3576780fb4a2SCy Schubert 	  }
3577780fb4a2SCy Schubert 	},
3578780fb4a2SCy Schubert #endif /* CONFIG_NO_CONFIG_WRITE */
357985732ac8SCy Schubert 	{ "AbortScan", WPAS_DBUS_NEW_IFACE_INTERFACE,
358085732ac8SCy Schubert 	  (WPADBusMethodHandler) wpas_dbus_handler_abort_scan,
358185732ac8SCy Schubert 	  {
358285732ac8SCy Schubert 		  END_ARGS
358385732ac8SCy Schubert 	  }
358485732ac8SCy Schubert 	},
3585d4f2939cSRui Paulo 	{ NULL, NULL, NULL, { END_ARGS } }
3586d4f2939cSRui Paulo };
3587d4f2939cSRui Paulo 
3588d4f2939cSRui Paulo static const struct wpa_dbus_property_desc wpas_dbus_interface_properties[] = {
3589d4f2939cSRui Paulo 	{ "Capabilities", WPAS_DBUS_NEW_IFACE_INTERFACE, "a{sv}",
3590d4f2939cSRui Paulo 	  wpas_dbus_getter_capabilities,
3591780fb4a2SCy Schubert 	  NULL,
3592d4f2939cSRui Paulo 	  NULL
3593d4f2939cSRui Paulo 	},
3594d4f2939cSRui Paulo 	{ "State", WPAS_DBUS_NEW_IFACE_INTERFACE, "s",
3595d4f2939cSRui Paulo 	  wpas_dbus_getter_state,
3596780fb4a2SCy Schubert 	  NULL,
3597d4f2939cSRui Paulo 	  NULL
3598d4f2939cSRui Paulo 	},
3599d4f2939cSRui Paulo 	{ "Scanning", WPAS_DBUS_NEW_IFACE_INTERFACE, "b",
3600d4f2939cSRui Paulo 	  wpas_dbus_getter_scanning,
3601780fb4a2SCy Schubert 	  NULL,
3602d4f2939cSRui Paulo 	  NULL
3603d4f2939cSRui Paulo 	},
3604d4f2939cSRui Paulo 	{ "ApScan", WPAS_DBUS_NEW_IFACE_INTERFACE, "u",
3605d4f2939cSRui Paulo 	  wpas_dbus_getter_ap_scan,
3606780fb4a2SCy Schubert 	  wpas_dbus_setter_ap_scan,
3607780fb4a2SCy Schubert 	  NULL
3608d4f2939cSRui Paulo 	},
3609d4f2939cSRui Paulo 	{ "BSSExpireAge", WPAS_DBUS_NEW_IFACE_INTERFACE, "u",
3610d4f2939cSRui Paulo 	  wpas_dbus_getter_bss_expire_age,
3611780fb4a2SCy Schubert 	  wpas_dbus_setter_bss_expire_age,
3612780fb4a2SCy Schubert 	  NULL
3613d4f2939cSRui Paulo 	},
3614d4f2939cSRui Paulo 	{ "BSSExpireCount", WPAS_DBUS_NEW_IFACE_INTERFACE, "u",
3615d4f2939cSRui Paulo 	  wpas_dbus_getter_bss_expire_count,
3616780fb4a2SCy Schubert 	  wpas_dbus_setter_bss_expire_count,
3617780fb4a2SCy Schubert 	  NULL
3618d4f2939cSRui Paulo 	},
3619d4f2939cSRui Paulo 	{ "Country", WPAS_DBUS_NEW_IFACE_INTERFACE, "s",
3620d4f2939cSRui Paulo 	  wpas_dbus_getter_country,
3621780fb4a2SCy Schubert 	  wpas_dbus_setter_country,
3622780fb4a2SCy Schubert 	  NULL
3623d4f2939cSRui Paulo 	},
3624d4f2939cSRui Paulo 	{ "Ifname", WPAS_DBUS_NEW_IFACE_INTERFACE, "s",
3625d4f2939cSRui Paulo 	  wpas_dbus_getter_ifname,
3626780fb4a2SCy Schubert 	  NULL,
3627d4f2939cSRui Paulo 	  NULL
3628d4f2939cSRui Paulo 	},
3629d4f2939cSRui Paulo 	{ "Driver", WPAS_DBUS_NEW_IFACE_INTERFACE, "s",
3630d4f2939cSRui Paulo 	  wpas_dbus_getter_driver,
3631780fb4a2SCy Schubert 	  NULL,
3632d4f2939cSRui Paulo 	  NULL
3633d4f2939cSRui Paulo 	},
3634d4f2939cSRui Paulo 	{ "BridgeIfname", WPAS_DBUS_NEW_IFACE_INTERFACE, "s",
3635d4f2939cSRui Paulo 	  wpas_dbus_getter_bridge_ifname,
3636780fb4a2SCy Schubert 	  NULL,
3637780fb4a2SCy Schubert 	  NULL
3638780fb4a2SCy Schubert 	},
3639780fb4a2SCy Schubert 	{ "ConfigFile", WPAS_DBUS_NEW_IFACE_INTERFACE, "s",
3640780fb4a2SCy Schubert 	  wpas_dbus_getter_config_file,
3641780fb4a2SCy Schubert 	  NULL,
3642d4f2939cSRui Paulo 	  NULL
3643d4f2939cSRui Paulo 	},
3644d4f2939cSRui Paulo 	{ "CurrentBSS", WPAS_DBUS_NEW_IFACE_INTERFACE, "o",
3645d4f2939cSRui Paulo 	  wpas_dbus_getter_current_bss,
3646780fb4a2SCy Schubert 	  NULL,
3647d4f2939cSRui Paulo 	  NULL
3648d4f2939cSRui Paulo 	},
3649d4f2939cSRui Paulo 	{ "CurrentNetwork", WPAS_DBUS_NEW_IFACE_INTERFACE, "o",
3650d4f2939cSRui Paulo 	  wpas_dbus_getter_current_network,
3651780fb4a2SCy Schubert 	  NULL,
3652d4f2939cSRui Paulo 	  NULL
3653d4f2939cSRui Paulo 	},
3654d4f2939cSRui Paulo 	{ "CurrentAuthMode", WPAS_DBUS_NEW_IFACE_INTERFACE, "s",
3655d4f2939cSRui Paulo 	  wpas_dbus_getter_current_auth_mode,
3656780fb4a2SCy Schubert 	  NULL,
3657d4f2939cSRui Paulo 	  NULL
3658d4f2939cSRui Paulo 	},
3659d4f2939cSRui Paulo 	{ "Blobs", WPAS_DBUS_NEW_IFACE_INTERFACE, "a{say}",
3660d4f2939cSRui Paulo 	  wpas_dbus_getter_blobs,
3661780fb4a2SCy Schubert 	  NULL,
3662d4f2939cSRui Paulo 	  NULL
3663d4f2939cSRui Paulo 	},
3664d4f2939cSRui Paulo 	{ "BSSs", WPAS_DBUS_NEW_IFACE_INTERFACE, "ao",
3665d4f2939cSRui Paulo 	  wpas_dbus_getter_bsss,
3666780fb4a2SCy Schubert 	  NULL,
3667d4f2939cSRui Paulo 	  NULL
3668d4f2939cSRui Paulo 	},
3669d4f2939cSRui Paulo 	{ "Networks", WPAS_DBUS_NEW_IFACE_INTERFACE, "ao",
3670d4f2939cSRui Paulo 	  wpas_dbus_getter_networks,
3671780fb4a2SCy Schubert 	  NULL,
3672d4f2939cSRui Paulo 	  NULL
3673d4f2939cSRui Paulo 	},
3674d4f2939cSRui Paulo 	{ "FastReauth", WPAS_DBUS_NEW_IFACE_INTERFACE, "b",
3675d4f2939cSRui Paulo 	  wpas_dbus_getter_fast_reauth,
3676780fb4a2SCy Schubert 	  wpas_dbus_setter_fast_reauth,
3677780fb4a2SCy Schubert 	  NULL
3678d4f2939cSRui Paulo 	},
3679d4f2939cSRui Paulo 	{ "ScanInterval", WPAS_DBUS_NEW_IFACE_INTERFACE, "i",
3680d4f2939cSRui Paulo 	  wpas_dbus_getter_scan_interval,
3681780fb4a2SCy Schubert 	  wpas_dbus_setter_scan_interval,
3682780fb4a2SCy Schubert 	  NULL
3683d4f2939cSRui Paulo 	},
36845b9c547cSRui Paulo 	{ "PKCS11EnginePath", WPAS_DBUS_NEW_IFACE_INTERFACE, "s",
36855b9c547cSRui Paulo 	  wpas_dbus_getter_pkcs11_engine_path,
3686780fb4a2SCy Schubert 	  NULL,
36875b9c547cSRui Paulo 	  NULL
36885b9c547cSRui Paulo 	},
36895b9c547cSRui Paulo 	{ "PKCS11ModulePath", WPAS_DBUS_NEW_IFACE_INTERFACE, "s",
36905b9c547cSRui Paulo 	  wpas_dbus_getter_pkcs11_module_path,
3691780fb4a2SCy Schubert 	  NULL,
36925b9c547cSRui Paulo 	  NULL
36935b9c547cSRui Paulo 	},
3694d4f2939cSRui Paulo #ifdef CONFIG_WPS
3695d4f2939cSRui Paulo 	{ "ProcessCredentials", WPAS_DBUS_NEW_IFACE_WPS, "b",
3696d4f2939cSRui Paulo 	  wpas_dbus_getter_process_credentials,
3697780fb4a2SCy Schubert 	  wpas_dbus_setter_process_credentials,
3698780fb4a2SCy Schubert 	  NULL
3699d4f2939cSRui Paulo 	},
37005b9c547cSRui Paulo 	{ "ConfigMethods", WPAS_DBUS_NEW_IFACE_WPS, "s",
37015b9c547cSRui Paulo 	  wpas_dbus_getter_config_methods,
3702780fb4a2SCy Schubert 	  wpas_dbus_setter_config_methods,
3703780fb4a2SCy Schubert 	  NULL
37045b9c547cSRui Paulo 	},
370585732ac8SCy Schubert 	{
370685732ac8SCy Schubert 	  "DeviceName", WPAS_DBUS_NEW_IFACE_WPS, "s",
370785732ac8SCy Schubert 	  wpas_dbus_getter_wps_device_name,
370885732ac8SCy Schubert 	  wpas_dbus_setter_wps_device_name,
370985732ac8SCy Schubert 	  NULL
371085732ac8SCy Schubert 	},
371185732ac8SCy Schubert 	{
371285732ac8SCy Schubert 	  "Manufacturer", WPAS_DBUS_NEW_IFACE_WPS, "s",
371385732ac8SCy Schubert 	  wpas_dbus_getter_wps_manufacturer,
371485732ac8SCy Schubert 	  wpas_dbus_setter_wps_manufacturer,
371585732ac8SCy Schubert 	  NULL
371685732ac8SCy Schubert 	},
371785732ac8SCy Schubert 	{
371885732ac8SCy Schubert 	  "ModelName", WPAS_DBUS_NEW_IFACE_WPS, "s",
371985732ac8SCy Schubert 	  wpas_dbus_getter_wps_device_model_name,
372085732ac8SCy Schubert 	  wpas_dbus_setter_wps_device_model_name,
372185732ac8SCy Schubert 	  NULL
372285732ac8SCy Schubert 	},
372385732ac8SCy Schubert 	{
372485732ac8SCy Schubert 	  "ModelNumber", WPAS_DBUS_NEW_IFACE_WPS, "s",
372585732ac8SCy Schubert 	  wpas_dbus_getter_wps_device_model_number,
372685732ac8SCy Schubert 	  wpas_dbus_setter_wps_device_model_number,
372785732ac8SCy Schubert 	  NULL
372885732ac8SCy Schubert 	},
372985732ac8SCy Schubert 	{
373085732ac8SCy Schubert 	  "SerialNumber", WPAS_DBUS_NEW_IFACE_WPS, "s",
373185732ac8SCy Schubert 	  wpas_dbus_getter_wps_device_serial_number,
373285732ac8SCy Schubert 	  wpas_dbus_setter_wps_device_serial_number,
373385732ac8SCy Schubert 	  NULL
373485732ac8SCy Schubert 	},
373585732ac8SCy Schubert 	{
373685732ac8SCy Schubert 	  "DeviceType", WPAS_DBUS_NEW_IFACE_WPS, "ay",
373785732ac8SCy Schubert 	  wpas_dbus_getter_wps_device_device_type,
373885732ac8SCy Schubert 	  wpas_dbus_setter_wps_device_device_type,
373985732ac8SCy Schubert 	  NULL
374085732ac8SCy Schubert 	},
3741d4f2939cSRui Paulo #endif /* CONFIG_WPS */
3742d4f2939cSRui Paulo #ifdef CONFIG_P2P
3743d4f2939cSRui Paulo 	{ "P2PDeviceConfig", WPAS_DBUS_NEW_IFACE_P2PDEVICE, "a{sv}",
3744d4f2939cSRui Paulo 	  wpas_dbus_getter_p2p_device_config,
3745780fb4a2SCy Schubert 	  wpas_dbus_setter_p2p_device_config,
3746780fb4a2SCy Schubert 	  NULL
3747d4f2939cSRui Paulo 	},
3748d4f2939cSRui Paulo 	{ "Peers", WPAS_DBUS_NEW_IFACE_P2PDEVICE, "ao",
3749d4f2939cSRui Paulo 	  wpas_dbus_getter_p2p_peers,
3750780fb4a2SCy Schubert 	  NULL,
3751d4f2939cSRui Paulo 	  NULL
3752d4f2939cSRui Paulo 	},
3753d4f2939cSRui Paulo 	{ "Role", WPAS_DBUS_NEW_IFACE_P2PDEVICE, "s",
3754d4f2939cSRui Paulo 	  wpas_dbus_getter_p2p_role,
3755780fb4a2SCy Schubert 	  NULL,
3756d4f2939cSRui Paulo 	  NULL
3757d4f2939cSRui Paulo 	},
3758d4f2939cSRui Paulo 	{ "Group", WPAS_DBUS_NEW_IFACE_P2PDEVICE, "o",
3759d4f2939cSRui Paulo 	  wpas_dbus_getter_p2p_group,
3760780fb4a2SCy Schubert 	  NULL,
3761d4f2939cSRui Paulo 	  NULL
3762d4f2939cSRui Paulo 	},
3763d4f2939cSRui Paulo 	{ "PeerGO", WPAS_DBUS_NEW_IFACE_P2PDEVICE, "o",
3764d4f2939cSRui Paulo 	  wpas_dbus_getter_p2p_peergo,
3765780fb4a2SCy Schubert 	  NULL,
3766d4f2939cSRui Paulo 	  NULL
3767d4f2939cSRui Paulo 	},
3768d4f2939cSRui Paulo 	{ "PersistentGroups", WPAS_DBUS_NEW_IFACE_P2PDEVICE, "ao",
3769d4f2939cSRui Paulo 	  wpas_dbus_getter_persistent_groups,
3770780fb4a2SCy Schubert 	  NULL,
3771d4f2939cSRui Paulo 	  NULL
3772d4f2939cSRui Paulo 	},
3773d4f2939cSRui Paulo #endif /* CONFIG_P2P */
3774d4f2939cSRui Paulo 	{ "DisconnectReason", WPAS_DBUS_NEW_IFACE_INTERFACE, "i",
3775d4f2939cSRui Paulo 	  wpas_dbus_getter_disconnect_reason,
3776780fb4a2SCy Schubert 	  NULL,
3777d4f2939cSRui Paulo 	  NULL
3778d4f2939cSRui Paulo 	},
3779*4bc52338SCy Schubert 	{ "AuthStatusCode", WPAS_DBUS_NEW_IFACE_INTERFACE, "i",
3780*4bc52338SCy Schubert 	  wpas_dbus_getter_auth_status_code,
3781*4bc52338SCy Schubert 	  NULL,
3782*4bc52338SCy Schubert 	  NULL
3783*4bc52338SCy Schubert 	},
3784780fb4a2SCy Schubert 	{ "AssocStatusCode", WPAS_DBUS_NEW_IFACE_INTERFACE, "i",
3785780fb4a2SCy Schubert 	  wpas_dbus_getter_assoc_status_code,
3786780fb4a2SCy Schubert 	  NULL,
3787780fb4a2SCy Schubert 	  NULL
3788780fb4a2SCy Schubert 	},
378985732ac8SCy Schubert #ifdef CONFIG_MESH
379085732ac8SCy Schubert 	{ "MeshPeers", WPAS_DBUS_NEW_IFACE_MESH, "aay",
379185732ac8SCy Schubert 	  wpas_dbus_getter_mesh_peers,
379285732ac8SCy Schubert 	  NULL,
379385732ac8SCy Schubert 	  NULL
379485732ac8SCy Schubert 	},
379585732ac8SCy Schubert 	{ "MeshGroup", WPAS_DBUS_NEW_IFACE_MESH, "ay",
379685732ac8SCy Schubert 	  wpas_dbus_getter_mesh_group,
379785732ac8SCy Schubert 	  NULL,
379885732ac8SCy Schubert 	  NULL
379985732ac8SCy Schubert 	},
380085732ac8SCy Schubert #endif /* CONFIG_MESH */
3801*4bc52338SCy Schubert 	{ "Stations", WPAS_DBUS_NEW_IFACE_INTERFACE, "ao",
3802*4bc52338SCy Schubert 	  wpas_dbus_getter_stas,
3803*4bc52338SCy Schubert 	  NULL,
3804*4bc52338SCy Schubert 	  NULL
3805*4bc52338SCy Schubert 	},
3806780fb4a2SCy Schubert 	{ NULL, NULL, NULL, NULL, NULL, NULL }
3807d4f2939cSRui Paulo };
3808d4f2939cSRui Paulo 
3809d4f2939cSRui Paulo static const struct wpa_dbus_signal_desc wpas_dbus_interface_signals[] = {
3810d4f2939cSRui Paulo 	{ "ScanDone", WPAS_DBUS_NEW_IFACE_INTERFACE,
3811d4f2939cSRui Paulo 	  {
3812d4f2939cSRui Paulo 		  { "success", "b", ARG_OUT },
3813d4f2939cSRui Paulo 		  END_ARGS
3814d4f2939cSRui Paulo 	  }
3815d4f2939cSRui Paulo 	},
3816d4f2939cSRui Paulo 	{ "BSSAdded", WPAS_DBUS_NEW_IFACE_INTERFACE,
3817d4f2939cSRui Paulo 	  {
3818d4f2939cSRui Paulo 		  { "path", "o", ARG_OUT },
3819d4f2939cSRui Paulo 		  { "properties", "a{sv}", ARG_OUT },
3820d4f2939cSRui Paulo 		  END_ARGS
3821d4f2939cSRui Paulo 	  }
3822d4f2939cSRui Paulo 	},
3823d4f2939cSRui Paulo 	{ "BSSRemoved", WPAS_DBUS_NEW_IFACE_INTERFACE,
3824d4f2939cSRui Paulo 	  {
3825d4f2939cSRui Paulo 		  { "path", "o", ARG_OUT },
3826d4f2939cSRui Paulo 		  END_ARGS
3827d4f2939cSRui Paulo 	  }
3828d4f2939cSRui Paulo 	},
3829d4f2939cSRui Paulo 	{ "BlobAdded", WPAS_DBUS_NEW_IFACE_INTERFACE,
3830d4f2939cSRui Paulo 	  {
3831d4f2939cSRui Paulo 		  { "name", "s", ARG_OUT },
3832d4f2939cSRui Paulo 		  END_ARGS
3833d4f2939cSRui Paulo 	  }
3834d4f2939cSRui Paulo 	},
3835d4f2939cSRui Paulo 	{ "BlobRemoved", WPAS_DBUS_NEW_IFACE_INTERFACE,
3836d4f2939cSRui Paulo 	  {
3837d4f2939cSRui Paulo 		  { "name", "s", ARG_OUT },
3838d4f2939cSRui Paulo 		  END_ARGS
3839d4f2939cSRui Paulo 	  }
3840d4f2939cSRui Paulo 	},
3841d4f2939cSRui Paulo 	{ "NetworkAdded", WPAS_DBUS_NEW_IFACE_INTERFACE,
3842d4f2939cSRui Paulo 	  {
3843d4f2939cSRui Paulo 		  { "path", "o", ARG_OUT },
3844d4f2939cSRui Paulo 		  { "properties", "a{sv}", ARG_OUT },
3845d4f2939cSRui Paulo 		  END_ARGS
3846d4f2939cSRui Paulo 	  }
3847d4f2939cSRui Paulo 	},
3848d4f2939cSRui Paulo 	{ "NetworkRemoved", WPAS_DBUS_NEW_IFACE_INTERFACE,
3849d4f2939cSRui Paulo 	  {
3850d4f2939cSRui Paulo 		  { "path", "o", ARG_OUT },
3851d4f2939cSRui Paulo 		  END_ARGS
3852d4f2939cSRui Paulo 	  }
3853d4f2939cSRui Paulo 	},
3854d4f2939cSRui Paulo 	{ "NetworkSelected", WPAS_DBUS_NEW_IFACE_INTERFACE,
3855d4f2939cSRui Paulo 	  {
3856d4f2939cSRui Paulo 		  { "path", "o", ARG_OUT },
3857d4f2939cSRui Paulo 		  END_ARGS
3858d4f2939cSRui Paulo 	  }
3859d4f2939cSRui Paulo 	},
3860d4f2939cSRui Paulo 	/* Deprecated: use org.freedesktop.DBus.Properties.PropertiesChanged */
3861d4f2939cSRui Paulo 	{ "PropertiesChanged", WPAS_DBUS_NEW_IFACE_INTERFACE,
3862d4f2939cSRui Paulo 	  {
3863d4f2939cSRui Paulo 		  { "properties", "a{sv}", ARG_OUT },
3864d4f2939cSRui Paulo 		  END_ARGS
3865d4f2939cSRui Paulo 	  }
3866d4f2939cSRui Paulo 	},
3867d4f2939cSRui Paulo #ifdef CONFIG_WPS
3868d4f2939cSRui Paulo 	{ "Event", WPAS_DBUS_NEW_IFACE_WPS,
3869d4f2939cSRui Paulo 	  {
3870d4f2939cSRui Paulo 		  { "name", "s", ARG_OUT },
3871d4f2939cSRui Paulo 		  { "args", "a{sv}", ARG_OUT },
3872d4f2939cSRui Paulo 		  END_ARGS
3873d4f2939cSRui Paulo 	  }
3874d4f2939cSRui Paulo 	},
3875d4f2939cSRui Paulo 	{ "Credentials", WPAS_DBUS_NEW_IFACE_WPS,
3876d4f2939cSRui Paulo 	  {
3877d4f2939cSRui Paulo 		  { "credentials", "a{sv}", ARG_OUT },
3878d4f2939cSRui Paulo 		  END_ARGS
3879d4f2939cSRui Paulo 	  }
3880d4f2939cSRui Paulo 	},
3881d4f2939cSRui Paulo 	/* Deprecated: use org.freedesktop.DBus.Properties.PropertiesChanged */
3882d4f2939cSRui Paulo 	{ "PropertiesChanged", WPAS_DBUS_NEW_IFACE_WPS,
3883d4f2939cSRui Paulo 	  {
3884d4f2939cSRui Paulo 		  { "properties", "a{sv}", ARG_OUT },
3885d4f2939cSRui Paulo 		  END_ARGS
3886d4f2939cSRui Paulo 	  }
3887d4f2939cSRui Paulo 	},
3888d4f2939cSRui Paulo #endif /* CONFIG_WPS */
3889d4f2939cSRui Paulo #ifdef CONFIG_P2P
3890d4f2939cSRui Paulo 	{ "DeviceFound", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
3891d4f2939cSRui Paulo 	  {
3892d4f2939cSRui Paulo 		  { "path", "o", ARG_OUT },
3893d4f2939cSRui Paulo 		  END_ARGS
3894d4f2939cSRui Paulo 	  }
3895d4f2939cSRui Paulo 	},
3896780fb4a2SCy Schubert 	{ "DeviceFoundProperties", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
3897780fb4a2SCy Schubert 	  {
3898780fb4a2SCy Schubert 		  { "path", "o", ARG_OUT },
3899780fb4a2SCy Schubert 		  { "properties", "a{sv}", ARG_OUT },
3900780fb4a2SCy Schubert 		  END_ARGS
3901780fb4a2SCy Schubert 	  }
3902780fb4a2SCy Schubert 	},
3903d4f2939cSRui Paulo 	{ "DeviceLost", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
3904d4f2939cSRui Paulo 	  {
3905d4f2939cSRui Paulo 		  { "path", "o", ARG_OUT },
3906d4f2939cSRui Paulo 		  END_ARGS
3907d4f2939cSRui Paulo 	  }
3908d4f2939cSRui Paulo 	},
3909325151a3SRui Paulo 	{ "FindStopped", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
3910325151a3SRui Paulo 	  {
3911325151a3SRui Paulo 		  END_ARGS
3912325151a3SRui Paulo 	  }
3913325151a3SRui Paulo 	},
3914d4f2939cSRui Paulo 	{ "ProvisionDiscoveryRequestDisplayPin", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
3915d4f2939cSRui Paulo 	  {
3916d4f2939cSRui Paulo 		  { "peer_object", "o", ARG_OUT },
3917d4f2939cSRui Paulo 		  { "pin", "s", ARG_OUT },
3918d4f2939cSRui Paulo 		  END_ARGS
3919d4f2939cSRui Paulo 	  }
3920d4f2939cSRui Paulo 	},
3921d4f2939cSRui Paulo 	{ "ProvisionDiscoveryResponseDisplayPin", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
3922d4f2939cSRui Paulo 	  {
3923d4f2939cSRui Paulo 		  { "peer_object", "o", ARG_OUT },
3924d4f2939cSRui Paulo 		  { "pin", "s", ARG_OUT },
3925d4f2939cSRui Paulo 		  END_ARGS
3926d4f2939cSRui Paulo 	  }
3927d4f2939cSRui Paulo 	},
3928d4f2939cSRui Paulo 	{ "ProvisionDiscoveryRequestEnterPin", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
3929d4f2939cSRui Paulo 	  {
3930d4f2939cSRui Paulo 		  { "peer_object", "o", ARG_OUT },
3931d4f2939cSRui Paulo 		  END_ARGS
3932d4f2939cSRui Paulo 	  }
3933d4f2939cSRui Paulo 	},
3934d4f2939cSRui Paulo 	{ "ProvisionDiscoveryResponseEnterPin", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
3935d4f2939cSRui Paulo 	  {
3936d4f2939cSRui Paulo 		  { "peer_object", "o", ARG_OUT },
3937d4f2939cSRui Paulo 		  END_ARGS
3938d4f2939cSRui Paulo 	  }
3939d4f2939cSRui Paulo 	},
3940d4f2939cSRui Paulo 	{ "ProvisionDiscoveryPBCRequest", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
3941d4f2939cSRui Paulo 	  {
3942d4f2939cSRui Paulo 		  { "peer_object", "o", ARG_OUT },
3943d4f2939cSRui Paulo 		  END_ARGS
3944d4f2939cSRui Paulo 	  }
3945d4f2939cSRui Paulo 	},
3946d4f2939cSRui Paulo 	{ "ProvisionDiscoveryPBCResponse", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
3947d4f2939cSRui Paulo 	  {
3948d4f2939cSRui Paulo 		  { "peer_object", "o", ARG_OUT },
3949d4f2939cSRui Paulo 		  END_ARGS
3950d4f2939cSRui Paulo 	  }
3951d4f2939cSRui Paulo 	},
3952d4f2939cSRui Paulo 	{ "ProvisionDiscoveryFailure", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
3953d4f2939cSRui Paulo 	  {
3954d4f2939cSRui Paulo 		  { "peer_object", "o", ARG_OUT },
3955d4f2939cSRui Paulo 		  { "status", "i", ARG_OUT },
3956d4f2939cSRui Paulo 		  END_ARGS
3957d4f2939cSRui Paulo 	  }
3958d4f2939cSRui Paulo 	},
3959d4f2939cSRui Paulo 	{ "GroupStarted", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
3960d4f2939cSRui Paulo 	  {
3961d4f2939cSRui Paulo 		  { "properties", "a{sv}", ARG_OUT },
3962d4f2939cSRui Paulo 		  END_ARGS
3963d4f2939cSRui Paulo 	  }
3964d4f2939cSRui Paulo 	},
3965325151a3SRui Paulo 	{ "GroupFormationFailure", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
3966325151a3SRui Paulo 	  {
3967325151a3SRui Paulo 		  { "reason", "s", ARG_OUT },
3968325151a3SRui Paulo 		  END_ARGS
3969325151a3SRui Paulo 	  }
3970325151a3SRui Paulo 	},
3971d4f2939cSRui Paulo 	{ "GONegotiationSuccess", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
3972d4f2939cSRui Paulo 	  {
39735b9c547cSRui Paulo 		  { "properties", "a{sv}", ARG_OUT },
3974d4f2939cSRui Paulo 		  END_ARGS
3975d4f2939cSRui Paulo 	  }
3976d4f2939cSRui Paulo 	},
3977d4f2939cSRui Paulo 	{ "GONegotiationFailure", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
3978d4f2939cSRui Paulo 	  {
39795b9c547cSRui Paulo 		  { "properties", "a{sv}", ARG_OUT },
3980d4f2939cSRui Paulo 		  END_ARGS
3981d4f2939cSRui Paulo 	  }
3982d4f2939cSRui Paulo 	},
3983d4f2939cSRui Paulo 	{ "GONegotiationRequest", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
3984d4f2939cSRui Paulo 	  {
3985d4f2939cSRui Paulo 		  { "path", "o", ARG_OUT },
3986325151a3SRui Paulo 		  { "dev_passwd_id", "q", ARG_OUT },
3987325151a3SRui Paulo 		  { "device_go_intent", "y", ARG_OUT },
3988d4f2939cSRui Paulo 		  END_ARGS
3989d4f2939cSRui Paulo 	  }
3990d4f2939cSRui Paulo 	},
3991d4f2939cSRui Paulo 	{ "InvitationResult", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
3992d4f2939cSRui Paulo 	  {
3993d4f2939cSRui Paulo 		  { "invite_result", "a{sv}", ARG_OUT },
3994d4f2939cSRui Paulo 		  END_ARGS
3995d4f2939cSRui Paulo 	  }
3996d4f2939cSRui Paulo 	},
3997d4f2939cSRui Paulo 	{ "GroupFinished", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
3998d4f2939cSRui Paulo 	  {
39995b9c547cSRui Paulo 		  { "properties", "a{sv}", ARG_OUT },
4000d4f2939cSRui Paulo 		  END_ARGS
4001d4f2939cSRui Paulo 	  }
4002d4f2939cSRui Paulo 	},
4003d4f2939cSRui Paulo 	{ "ServiceDiscoveryRequest", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
4004d4f2939cSRui Paulo 	  {
4005d4f2939cSRui Paulo 		  { "sd_request", "a{sv}", ARG_OUT },
4006d4f2939cSRui Paulo 		  END_ARGS
4007d4f2939cSRui Paulo 	  }
4008d4f2939cSRui Paulo 	},
4009d4f2939cSRui Paulo 	{ "ServiceDiscoveryResponse", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
4010d4f2939cSRui Paulo 	  {
4011d4f2939cSRui Paulo 		  { "sd_response", "a{sv}", ARG_OUT },
4012d4f2939cSRui Paulo 		  END_ARGS
4013d4f2939cSRui Paulo 	  }
4014d4f2939cSRui Paulo 	},
4015d4f2939cSRui Paulo 	{ "PersistentGroupAdded", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
4016d4f2939cSRui Paulo 	  {
4017d4f2939cSRui Paulo 		  { "path", "o", ARG_OUT },
4018d4f2939cSRui Paulo 		  { "properties", "a{sv}", ARG_OUT },
4019d4f2939cSRui Paulo 		  END_ARGS
4020d4f2939cSRui Paulo 	  }
4021d4f2939cSRui Paulo 	},
4022d4f2939cSRui Paulo 	{ "PersistentGroupRemoved", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
4023d4f2939cSRui Paulo 	  {
4024d4f2939cSRui Paulo 		  { "path", "o", ARG_OUT },
4025d4f2939cSRui Paulo 		  END_ARGS
4026d4f2939cSRui Paulo 	  }
4027d4f2939cSRui Paulo 	},
4028d4f2939cSRui Paulo 	{ "WpsFailed", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
4029d4f2939cSRui Paulo 	  {
4030d4f2939cSRui Paulo 		  { "name", "s", ARG_OUT },
4031d4f2939cSRui Paulo 		  { "args", "a{sv}", ARG_OUT },
4032d4f2939cSRui Paulo 		  END_ARGS
4033d4f2939cSRui Paulo 	  }
4034d4f2939cSRui Paulo 	},
4035325151a3SRui Paulo 	{ "InvitationReceived", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
4036325151a3SRui Paulo 	  {
4037325151a3SRui Paulo 		  { "properties", "a{sv}", ARG_OUT },
4038325151a3SRui Paulo 		  END_ARGS
4039325151a3SRui Paulo 	  }
4040325151a3SRui Paulo 	},
4041d4f2939cSRui Paulo #endif /* CONFIG_P2P */
4042d4f2939cSRui Paulo #ifdef CONFIG_AP
4043d4f2939cSRui Paulo 	{ "ProbeRequest", WPAS_DBUS_NEW_IFACE_INTERFACE,
4044d4f2939cSRui Paulo 	  {
4045d4f2939cSRui Paulo 		  { "args", "a{sv}", ARG_OUT },
4046d4f2939cSRui Paulo 		  END_ARGS
4047d4f2939cSRui Paulo 	  }
4048d4f2939cSRui Paulo 	},
4049d4f2939cSRui Paulo #endif /* CONFIG_AP */
4050d4f2939cSRui Paulo 	{ "Certification", WPAS_DBUS_NEW_IFACE_INTERFACE,
4051d4f2939cSRui Paulo 	  {
4052d4f2939cSRui Paulo 		  { "certification", "a{sv}", ARG_OUT },
4053d4f2939cSRui Paulo 		  END_ARGS
4054d4f2939cSRui Paulo 	  }
4055d4f2939cSRui Paulo 	},
4056d4f2939cSRui Paulo 	{ "EAP", WPAS_DBUS_NEW_IFACE_INTERFACE,
4057d4f2939cSRui Paulo 	  {
4058d4f2939cSRui Paulo 		  { "status", "s", ARG_OUT },
4059d4f2939cSRui Paulo 		  { "parameter", "s", ARG_OUT },
4060d4f2939cSRui Paulo 		  END_ARGS
4061d4f2939cSRui Paulo 	  }
4062d4f2939cSRui Paulo 	},
40635b9c547cSRui Paulo 	{ "StaAuthorized", WPAS_DBUS_NEW_IFACE_INTERFACE,
40645b9c547cSRui Paulo 	  {
40655b9c547cSRui Paulo 		  { "name", "s", ARG_OUT },
40665b9c547cSRui Paulo 		  END_ARGS
40675b9c547cSRui Paulo 	  }
40685b9c547cSRui Paulo 	},
40695b9c547cSRui Paulo 	{ "StaDeauthorized", WPAS_DBUS_NEW_IFACE_INTERFACE,
40705b9c547cSRui Paulo 	  {
40715b9c547cSRui Paulo 		  { "name", "s", ARG_OUT },
40725b9c547cSRui Paulo 		  END_ARGS
40735b9c547cSRui Paulo 	  }
40745b9c547cSRui Paulo 	},
4075*4bc52338SCy Schubert 	{ "StationAdded", WPAS_DBUS_NEW_IFACE_INTERFACE,
4076*4bc52338SCy Schubert 	  {
4077*4bc52338SCy Schubert 		  { "path", "o", ARG_OUT },
4078*4bc52338SCy Schubert 		  { "properties", "a{sv}", ARG_OUT },
4079*4bc52338SCy Schubert 		  END_ARGS
4080*4bc52338SCy Schubert 	  }
4081*4bc52338SCy Schubert 	},
4082*4bc52338SCy Schubert 	{ "StationRemoved", WPAS_DBUS_NEW_IFACE_INTERFACE,
4083*4bc52338SCy Schubert 	  {
4084*4bc52338SCy Schubert 		  { "path", "o", ARG_OUT },
4085*4bc52338SCy Schubert 		  END_ARGS
4086*4bc52338SCy Schubert 	  }
4087*4bc52338SCy Schubert 	},
40885b9c547cSRui Paulo 	{ "NetworkRequest", WPAS_DBUS_NEW_IFACE_INTERFACE,
40895b9c547cSRui Paulo 	  {
40905b9c547cSRui Paulo 		  { "path", "o", ARG_OUT },
40915b9c547cSRui Paulo 		  { "field", "s", ARG_OUT },
40925b9c547cSRui Paulo 		  { "text", "s", ARG_OUT },
40935b9c547cSRui Paulo 		  END_ARGS
40945b9c547cSRui Paulo 	  }
40955b9c547cSRui Paulo 	},
409685732ac8SCy Schubert #ifdef CONFIG_MESH
409785732ac8SCy Schubert 	{ "MeshGroupStarted", WPAS_DBUS_NEW_IFACE_MESH,
409885732ac8SCy Schubert 	  {
409985732ac8SCy Schubert 		  { "args", "a{sv}", ARG_OUT },
410085732ac8SCy Schubert 		  END_ARGS
410185732ac8SCy Schubert 	  }
410285732ac8SCy Schubert 	},
410385732ac8SCy Schubert 	{ "MeshGroupRemoved", WPAS_DBUS_NEW_IFACE_MESH,
410485732ac8SCy Schubert 	  {
410585732ac8SCy Schubert 		  { "args", "a{sv}", ARG_OUT },
410685732ac8SCy Schubert 		  END_ARGS
410785732ac8SCy Schubert 	  }
410885732ac8SCy Schubert 	},
410985732ac8SCy Schubert 	{ "MeshPeerConnected", WPAS_DBUS_NEW_IFACE_MESH,
411085732ac8SCy Schubert 	  {
411185732ac8SCy Schubert 		  { "args", "a{sv}", ARG_OUT },
411285732ac8SCy Schubert 		  END_ARGS
411385732ac8SCy Schubert 	  }
411485732ac8SCy Schubert 	},
411585732ac8SCy Schubert 	{ "MeshPeerDisconnected", WPAS_DBUS_NEW_IFACE_MESH,
411685732ac8SCy Schubert 	  {
411785732ac8SCy Schubert 		  { "args", "a{sv}", ARG_OUT },
411885732ac8SCy Schubert 		  END_ARGS
411985732ac8SCy Schubert 	  }
412085732ac8SCy Schubert 	},
412185732ac8SCy Schubert #endif /* CONFIG_MESH */
4122d4f2939cSRui Paulo 	{ NULL, NULL, { END_ARGS } }
4123d4f2939cSRui Paulo };
4124d4f2939cSRui Paulo 
4125d4f2939cSRui Paulo 
4126780fb4a2SCy Schubert static int wpa_dbus_ctrl_iface_props_init(struct wpas_dbus_priv *priv)
4127780fb4a2SCy Schubert {
4128780fb4a2SCy Schubert 	size_t all_size;
4129780fb4a2SCy Schubert 	unsigned int i, j, count, num_const, num_globals;
4130780fb4a2SCy Schubert 	const char *global_name;
4131780fb4a2SCy Schubert 	static const char * const ignored_globals[] = {
4132780fb4a2SCy Schubert 		"bss_expiration_age", "bss_expiration_scan_count",
4133780fb4a2SCy Schubert 		"ap_scan", "country", "fast_reauth",
4134780fb4a2SCy Schubert 		"pkcs11_engine_path", "pkcs11_module_path"
4135780fb4a2SCy Schubert 	};
4136780fb4a2SCy Schubert 
4137780fb4a2SCy Schubert 	/* wpas_dbus_interface_properties terminates with a NULL element */
4138780fb4a2SCy Schubert 	num_const = ARRAY_SIZE(wpas_dbus_interface_properties) - 1;
4139780fb4a2SCy Schubert 
4140780fb4a2SCy Schubert 	num_globals = wpa_config_get_num_global_field_names();
4141780fb4a2SCy Schubert 	priv->globals_start = num_const;
4142780fb4a2SCy Schubert 
4143780fb4a2SCy Schubert 	/* allocate enough for all properties + terminating NULL element */
4144780fb4a2SCy Schubert 	all_size = (num_globals + num_const + 1) *
4145780fb4a2SCy Schubert 		sizeof(wpas_dbus_interface_properties[0]);
4146780fb4a2SCy Schubert 	priv->all_interface_properties = os_zalloc(all_size);
4147780fb4a2SCy Schubert 	if (!priv->all_interface_properties) {
4148780fb4a2SCy Schubert 		wpa_printf(MSG_ERROR,
4149780fb4a2SCy Schubert 			   "dbus: Not enough memory for interface properties");
4150780fb4a2SCy Schubert 		return -1;
4151780fb4a2SCy Schubert 	}
4152780fb4a2SCy Schubert 
4153780fb4a2SCy Schubert 	/* Copy constant interface properties to the start of the array */
4154780fb4a2SCy Schubert 	os_memcpy(priv->all_interface_properties,
4155780fb4a2SCy Schubert 		  wpas_dbus_interface_properties,
4156780fb4a2SCy Schubert 		  sizeof(wpas_dbus_interface_properties));
4157780fb4a2SCy Schubert 
4158780fb4a2SCy Schubert 	/* Dynamically construct interface global properties */
4159780fb4a2SCy Schubert 	for (i = 0, count = num_const; i < num_globals; i++) {
4160780fb4a2SCy Schubert 		struct wpa_dbus_property_desc *desc;
4161780fb4a2SCy Schubert 		int no_var = 0;
4162780fb4a2SCy Schubert 
4163780fb4a2SCy Schubert 		/* ignore globals that are actually just methods */
4164780fb4a2SCy Schubert 		global_name = wpa_config_get_global_field_name(i, &no_var);
4165780fb4a2SCy Schubert 		if (no_var)
4166780fb4a2SCy Schubert 			continue;
4167780fb4a2SCy Schubert 		/* Ignore fields already explicitly exposed */
4168780fb4a2SCy Schubert 		for (j = 0; j < ARRAY_SIZE(ignored_globals); j++) {
4169780fb4a2SCy Schubert 			if (os_strcmp(global_name, ignored_globals[j]) == 0)
4170780fb4a2SCy Schubert 				break;
4171780fb4a2SCy Schubert 		}
4172780fb4a2SCy Schubert 		if (j < ARRAY_SIZE(ignored_globals))
4173780fb4a2SCy Schubert 			continue;
4174780fb4a2SCy Schubert 
4175780fb4a2SCy Schubert 		desc = &priv->all_interface_properties[count++];
4176780fb4a2SCy Schubert 		desc->dbus_property = uscore_to_dbus(global_name);
4177780fb4a2SCy Schubert 		if (!desc->dbus_property) {
4178780fb4a2SCy Schubert 			wpa_printf(MSG_ERROR,
4179780fb4a2SCy Schubert 				   "dbus: Not enough memory for D-Bus property name");
4180780fb4a2SCy Schubert 			goto error;
4181780fb4a2SCy Schubert 		}
4182780fb4a2SCy Schubert 		desc->dbus_interface = WPAS_DBUS_NEW_IFACE_INTERFACE;
4183780fb4a2SCy Schubert 		desc->type = "s";
4184780fb4a2SCy Schubert 		desc->getter = wpas_dbus_getter_iface_global;
4185780fb4a2SCy Schubert 		desc->setter = wpas_dbus_setter_iface_global;
4186780fb4a2SCy Schubert 		desc->data = global_name;
4187780fb4a2SCy Schubert 	}
4188780fb4a2SCy Schubert 
4189780fb4a2SCy Schubert 	return 0;
4190780fb4a2SCy Schubert 
4191780fb4a2SCy Schubert error:
4192780fb4a2SCy Schubert 	wpa_dbus_ctrl_iface_props_deinit(priv);
4193780fb4a2SCy Schubert 	return -1;
4194780fb4a2SCy Schubert }
4195780fb4a2SCy Schubert 
4196780fb4a2SCy Schubert 
4197325151a3SRui Paulo /**
4198325151a3SRui Paulo  * wpas_dbus_register_interface - Register an interface with D-Bus
4199325151a3SRui Paulo  * @wpa_s: wpa_supplicant interface structure
4200325151a3SRui Paulo  * Returns: 0 on success, -1 on failure
4201325151a3SRui Paulo  */
4202d4f2939cSRui Paulo int wpas_dbus_register_interface(struct wpa_supplicant *wpa_s)
4203d4f2939cSRui Paulo {
4204d4f2939cSRui Paulo 	struct wpa_dbus_object_desc *obj_desc = NULL;
4205d4f2939cSRui Paulo 	struct wpas_dbus_priv *ctrl_iface = wpa_s->global->dbus;
4206d4f2939cSRui Paulo 	int next;
4207d4f2939cSRui Paulo 
4208d4f2939cSRui Paulo 	/* Do nothing if the control interface is not turned on */
4209d4f2939cSRui Paulo 	if (ctrl_iface == NULL)
4210d4f2939cSRui Paulo 		return 0;
4211d4f2939cSRui Paulo 
4212d4f2939cSRui Paulo 	/* Create and set the interface's object path */
4213d4f2939cSRui Paulo 	wpa_s->dbus_new_path = os_zalloc(WPAS_DBUS_OBJECT_PATH_MAX);
4214d4f2939cSRui Paulo 	if (wpa_s->dbus_new_path == NULL)
4215d4f2939cSRui Paulo 		return -1;
4216d4f2939cSRui Paulo 	next = ctrl_iface->next_objid++;
4217d4f2939cSRui Paulo 	os_snprintf(wpa_s->dbus_new_path, WPAS_DBUS_OBJECT_PATH_MAX,
4218d4f2939cSRui Paulo 		    WPAS_DBUS_NEW_PATH_INTERFACES "/%u",
4219d4f2939cSRui Paulo 		    next);
4220d4f2939cSRui Paulo 
4221d4f2939cSRui Paulo 	obj_desc = os_zalloc(sizeof(struct wpa_dbus_object_desc));
4222d4f2939cSRui Paulo 	if (!obj_desc) {
42235b9c547cSRui Paulo 		wpa_printf(MSG_ERROR,
42245b9c547cSRui Paulo 			   "Not enough memory to create object description");
4225d4f2939cSRui Paulo 		goto err;
4226d4f2939cSRui Paulo 	}
4227d4f2939cSRui Paulo 
4228d4f2939cSRui Paulo 	wpas_dbus_register(obj_desc, wpa_s, NULL, wpas_dbus_interface_methods,
4229780fb4a2SCy Schubert 			   ctrl_iface->all_interface_properties,
4230d4f2939cSRui Paulo 			   wpas_dbus_interface_signals);
4231d4f2939cSRui Paulo 
4232d4f2939cSRui Paulo 	wpa_printf(MSG_DEBUG, "dbus: Register interface object '%s'",
4233d4f2939cSRui Paulo 		   wpa_s->dbus_new_path);
4234d4f2939cSRui Paulo 	if (wpa_dbus_register_object_per_iface(ctrl_iface,
4235d4f2939cSRui Paulo 					       wpa_s->dbus_new_path,
4236d4f2939cSRui Paulo 					       wpa_s->ifname, obj_desc))
4237d4f2939cSRui Paulo 		goto err;
4238d4f2939cSRui Paulo 
4239d4f2939cSRui Paulo 	wpas_dbus_signal_interface_added(wpa_s);
4240d4f2939cSRui Paulo 
4241d4f2939cSRui Paulo 	return 0;
4242d4f2939cSRui Paulo 
4243d4f2939cSRui Paulo err:
4244d4f2939cSRui Paulo 	os_free(wpa_s->dbus_new_path);
4245d4f2939cSRui Paulo 	wpa_s->dbus_new_path = NULL;
4246d4f2939cSRui Paulo 	free_dbus_object_desc(obj_desc);
4247d4f2939cSRui Paulo 	return -1;
4248d4f2939cSRui Paulo }
4249d4f2939cSRui Paulo 
4250d4f2939cSRui Paulo 
4251325151a3SRui Paulo /**
4252325151a3SRui Paulo  * wpas_dbus_unregister_interface - Unregister the interface from D-Bus
4253325151a3SRui Paulo  * @wpa_s: wpa_supplicant interface structure
4254325151a3SRui Paulo  * Returns: 0 on success, -1 on failure
4255325151a3SRui Paulo  */
4256d4f2939cSRui Paulo int wpas_dbus_unregister_interface(struct wpa_supplicant *wpa_s)
4257d4f2939cSRui Paulo {
4258d4f2939cSRui Paulo 	struct wpas_dbus_priv *ctrl_iface;
4259d4f2939cSRui Paulo 
4260d4f2939cSRui Paulo 	/* Do nothing if the control interface is not turned on */
4261d4f2939cSRui Paulo 	if (wpa_s == NULL || wpa_s->global == NULL)
4262d4f2939cSRui Paulo 		return 0;
4263d4f2939cSRui Paulo 	ctrl_iface = wpa_s->global->dbus;
42645b9c547cSRui Paulo 	if (ctrl_iface == NULL || wpa_s->dbus_new_path == NULL)
4265d4f2939cSRui Paulo 		return 0;
4266d4f2939cSRui Paulo 
4267d4f2939cSRui Paulo 	wpa_printf(MSG_DEBUG, "dbus: Unregister interface object '%s'",
4268d4f2939cSRui Paulo 		   wpa_s->dbus_new_path);
4269d4f2939cSRui Paulo 
4270d4f2939cSRui Paulo #ifdef CONFIG_AP
4271d4f2939cSRui Paulo 	if (wpa_s->preq_notify_peer) {
4272d4f2939cSRui Paulo 		wpas_dbus_unsubscribe_noc(ctrl_iface);
4273d4f2939cSRui Paulo 		os_free(wpa_s->preq_notify_peer);
4274d4f2939cSRui Paulo 		wpa_s->preq_notify_peer = NULL;
4275d4f2939cSRui Paulo 	}
4276d4f2939cSRui Paulo #endif /* CONFIG_AP */
4277d4f2939cSRui Paulo 
4278d4f2939cSRui Paulo 	if (wpa_dbus_unregister_object_per_iface(ctrl_iface,
4279d4f2939cSRui Paulo 						 wpa_s->dbus_new_path))
4280d4f2939cSRui Paulo 		return -1;
4281d4f2939cSRui Paulo 
4282d4f2939cSRui Paulo 	wpas_dbus_signal_interface_removed(wpa_s);
4283d4f2939cSRui Paulo 
4284d4f2939cSRui Paulo 	os_free(wpa_s->dbus_new_path);
4285d4f2939cSRui Paulo 	wpa_s->dbus_new_path = NULL;
4286d4f2939cSRui Paulo 
4287d4f2939cSRui Paulo 	return 0;
4288d4f2939cSRui Paulo }
4289d4f2939cSRui Paulo 
4290d4f2939cSRui Paulo #ifdef CONFIG_P2P
4291d4f2939cSRui Paulo 
4292d4f2939cSRui Paulo static const struct wpa_dbus_property_desc wpas_dbus_p2p_peer_properties[] = {
4293d4f2939cSRui Paulo 	{ "DeviceName", WPAS_DBUS_NEW_IFACE_P2P_PEER, "s",
4294d4f2939cSRui Paulo 	  wpas_dbus_getter_p2p_peer_device_name,
4295780fb4a2SCy Schubert 	  NULL,
4296d4f2939cSRui Paulo 	  NULL
4297d4f2939cSRui Paulo 	},
4298325151a3SRui Paulo 	{ "Manufacturer", WPAS_DBUS_NEW_IFACE_P2P_PEER, "s",
4299325151a3SRui Paulo 	  wpas_dbus_getter_p2p_peer_manufacturer,
4300780fb4a2SCy Schubert 	  NULL,
4301325151a3SRui Paulo 	  NULL
4302325151a3SRui Paulo 	},
4303325151a3SRui Paulo 	{ "ModelName", WPAS_DBUS_NEW_IFACE_P2P_PEER, "s",
4304325151a3SRui Paulo 	  wpas_dbus_getter_p2p_peer_modelname,
4305780fb4a2SCy Schubert 	  NULL,
4306325151a3SRui Paulo 	  NULL
4307325151a3SRui Paulo 	},
4308325151a3SRui Paulo 	{ "ModelNumber", WPAS_DBUS_NEW_IFACE_P2P_PEER, "s",
4309325151a3SRui Paulo 	  wpas_dbus_getter_p2p_peer_modelnumber,
4310780fb4a2SCy Schubert 	  NULL,
4311325151a3SRui Paulo 	  NULL
4312325151a3SRui Paulo 	},
4313325151a3SRui Paulo 	{ "SerialNumber", WPAS_DBUS_NEW_IFACE_P2P_PEER, "s",
4314325151a3SRui Paulo 	  wpas_dbus_getter_p2p_peer_serialnumber,
4315780fb4a2SCy Schubert 	  NULL,
4316325151a3SRui Paulo 	  NULL
4317325151a3SRui Paulo 	},
4318d4f2939cSRui Paulo 	{ "PrimaryDeviceType", WPAS_DBUS_NEW_IFACE_P2P_PEER, "ay",
4319d4f2939cSRui Paulo 	  wpas_dbus_getter_p2p_peer_primary_device_type,
4320780fb4a2SCy Schubert 	  NULL,
4321d4f2939cSRui Paulo 	  NULL
4322d4f2939cSRui Paulo 	},
4323d4f2939cSRui Paulo 	{ "config_method", WPAS_DBUS_NEW_IFACE_P2P_PEER, "q",
4324d4f2939cSRui Paulo 	  wpas_dbus_getter_p2p_peer_config_method,
4325780fb4a2SCy Schubert 	  NULL,
4326d4f2939cSRui Paulo 	  NULL
4327d4f2939cSRui Paulo 	},
4328d4f2939cSRui Paulo 	{ "level", WPAS_DBUS_NEW_IFACE_P2P_PEER, "i",
4329d4f2939cSRui Paulo 	  wpas_dbus_getter_p2p_peer_level,
4330780fb4a2SCy Schubert 	  NULL,
4331d4f2939cSRui Paulo 	  NULL
4332d4f2939cSRui Paulo 	},
4333d4f2939cSRui Paulo 	{ "devicecapability", WPAS_DBUS_NEW_IFACE_P2P_PEER, "y",
4334d4f2939cSRui Paulo 	  wpas_dbus_getter_p2p_peer_device_capability,
4335780fb4a2SCy Schubert 	  NULL,
4336d4f2939cSRui Paulo 	  NULL
4337d4f2939cSRui Paulo 	},
4338d4f2939cSRui Paulo 	{ "groupcapability", WPAS_DBUS_NEW_IFACE_P2P_PEER, "y",
4339d4f2939cSRui Paulo 	  wpas_dbus_getter_p2p_peer_group_capability,
4340780fb4a2SCy Schubert 	  NULL,
4341d4f2939cSRui Paulo 	  NULL
4342d4f2939cSRui Paulo 	},
4343d4f2939cSRui Paulo 	{ "SecondaryDeviceTypes", WPAS_DBUS_NEW_IFACE_P2P_PEER, "aay",
4344d4f2939cSRui Paulo 	  wpas_dbus_getter_p2p_peer_secondary_device_types,
4345780fb4a2SCy Schubert 	  NULL,
4346d4f2939cSRui Paulo 	  NULL
4347d4f2939cSRui Paulo 	},
4348d4f2939cSRui Paulo 	{ "VendorExtension", WPAS_DBUS_NEW_IFACE_P2P_PEER, "aay",
4349d4f2939cSRui Paulo 	  wpas_dbus_getter_p2p_peer_vendor_extension,
4350780fb4a2SCy Schubert 	  NULL,
4351d4f2939cSRui Paulo 	  NULL
4352d4f2939cSRui Paulo 	},
4353d4f2939cSRui Paulo 	{ "IEs", WPAS_DBUS_NEW_IFACE_P2P_PEER, "ay",
4354d4f2939cSRui Paulo 	  wpas_dbus_getter_p2p_peer_ies,
4355780fb4a2SCy Schubert 	  NULL,
4356d4f2939cSRui Paulo 	  NULL
4357d4f2939cSRui Paulo 	},
43585b9c547cSRui Paulo 	{ "DeviceAddress", WPAS_DBUS_NEW_IFACE_P2P_PEER, "ay",
43595b9c547cSRui Paulo 	  wpas_dbus_getter_p2p_peer_device_address,
4360780fb4a2SCy Schubert 	  NULL,
43615b9c547cSRui Paulo 	  NULL
43625b9c547cSRui Paulo 	},
43635b9c547cSRui Paulo 	{ "Groups", WPAS_DBUS_NEW_IFACE_P2P_PEER, "ao",
43645b9c547cSRui Paulo 	  wpas_dbus_getter_p2p_peer_groups,
4365780fb4a2SCy Schubert 	  NULL,
43665b9c547cSRui Paulo 	  NULL
43675b9c547cSRui Paulo 	},
4368*4bc52338SCy Schubert 	{ "VSIE", WPAS_DBUS_NEW_IFACE_P2P_PEER, "ay",
4369*4bc52338SCy Schubert 	  wpas_dbus_getter_p2p_peer_vsie,
4370*4bc52338SCy Schubert 	  NULL,
4371*4bc52338SCy Schubert 	  NULL
4372*4bc52338SCy Schubert 	},
4373780fb4a2SCy Schubert 	{ NULL, NULL, NULL, NULL, NULL, NULL }
4374d4f2939cSRui Paulo };
4375d4f2939cSRui Paulo 
4376d4f2939cSRui Paulo static const struct wpa_dbus_signal_desc wpas_dbus_p2p_peer_signals[] = {
43775b9c547cSRui Paulo 	/* Deprecated: use org.freedesktop.DBus.Properties.PropertiesChanged */
43785b9c547cSRui Paulo 	{ "PropertiesChanged", WPAS_DBUS_NEW_IFACE_P2P_PEER,
43795b9c547cSRui Paulo 	  {
43805b9c547cSRui Paulo 		  { "properties", "a{sv}", ARG_OUT },
43815b9c547cSRui Paulo 		  END_ARGS
43825b9c547cSRui Paulo 	  }
43835b9c547cSRui Paulo 	},
4384d4f2939cSRui Paulo 	{ NULL, NULL, { END_ARGS } }
4385d4f2939cSRui Paulo };
4386d4f2939cSRui Paulo 
4387d4f2939cSRui Paulo /**
4388d4f2939cSRui Paulo  * wpas_dbus_signal_peer - Send a peer related event signal
4389d4f2939cSRui Paulo  * @wpa_s: %wpa_supplicant network interface data
4390d4f2939cSRui Paulo  * @dev: peer device object
4391d4f2939cSRui Paulo  * @interface: name of the interface emitting this signal.
4392d4f2939cSRui Paulo  *	In case of peer objects, it would be emitted by either
4393d4f2939cSRui Paulo  *	the "interface object" or by "peer objects"
4394d4f2939cSRui Paulo  * @sig_name: signal name - DeviceFound
4395780fb4a2SCy Schubert  * @properties: Whether to add a second argument with object properties
4396d4f2939cSRui Paulo  *
4397780fb4a2SCy Schubert  * Notify listeners about event related with p2p peer device
4398d4f2939cSRui Paulo  */
4399d4f2939cSRui Paulo static void wpas_dbus_signal_peer(struct wpa_supplicant *wpa_s,
4400d4f2939cSRui Paulo 				  const u8 *dev_addr, const char *interface,
4401*4bc52338SCy Schubert 				  const char *sig_name, dbus_bool_t properties)
4402d4f2939cSRui Paulo {
4403d4f2939cSRui Paulo 	struct wpas_dbus_priv *iface;
4404d4f2939cSRui Paulo 	DBusMessage *msg;
4405d4f2939cSRui Paulo 	DBusMessageIter iter;
4406d4f2939cSRui Paulo 	char peer_obj_path[WPAS_DBUS_OBJECT_PATH_MAX], *path;
4407d4f2939cSRui Paulo 
44085b9c547cSRui Paulo 	if (wpa_s->p2p_mgmt)
44095b9c547cSRui Paulo 		wpa_s = wpa_s->parent;
44105b9c547cSRui Paulo 
4411d4f2939cSRui Paulo 	iface = wpa_s->global->dbus;
4412d4f2939cSRui Paulo 
4413d4f2939cSRui Paulo 	/* Do nothing if the control interface is not turned on */
4414325151a3SRui Paulo 	if (iface == NULL || !wpa_s->dbus_new_path)
4415d4f2939cSRui Paulo 		return;
4416d4f2939cSRui Paulo 
4417d4f2939cSRui Paulo 	os_snprintf(peer_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
4418d4f2939cSRui Paulo 		    "%s/" WPAS_DBUS_NEW_P2P_PEERS_PART "/" COMPACT_MACSTR,
4419d4f2939cSRui Paulo 		    wpa_s->dbus_new_path, MAC2STR(dev_addr));
4420d4f2939cSRui Paulo 
4421d4f2939cSRui Paulo 	msg = dbus_message_new_signal(wpa_s->dbus_new_path, interface,
4422d4f2939cSRui Paulo 				      sig_name);
4423d4f2939cSRui Paulo 	if (msg == NULL)
4424d4f2939cSRui Paulo 		return;
4425d4f2939cSRui Paulo 
4426d4f2939cSRui Paulo 	dbus_message_iter_init_append(msg, &iter);
4427d4f2939cSRui Paulo 	path = peer_obj_path;
4428d4f2939cSRui Paulo 	if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_OBJECT_PATH,
4429780fb4a2SCy Schubert 					    &path) ||
4430780fb4a2SCy Schubert 	    (properties && !wpa_dbus_get_object_properties(
4431780fb4a2SCy Schubert 		    iface, peer_obj_path, WPAS_DBUS_NEW_IFACE_P2P_PEER,
4432780fb4a2SCy Schubert 		    &iter)))
44335b9c547cSRui Paulo 		wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
44345b9c547cSRui Paulo 	else
4435d4f2939cSRui Paulo 		dbus_connection_send(iface->con, msg, NULL);
4436d4f2939cSRui Paulo 
4437d4f2939cSRui Paulo 	dbus_message_unref(msg);
4438d4f2939cSRui Paulo }
4439d4f2939cSRui Paulo 
4440d4f2939cSRui Paulo 
4441d4f2939cSRui Paulo /**
4442d4f2939cSRui Paulo  * wpas_dbus_signal_peer_found - Send a peer found signal
4443d4f2939cSRui Paulo  * @wpa_s: %wpa_supplicant network interface data
4444325151a3SRui Paulo  * @dev_addr: Peer P2P Device Address
4445d4f2939cSRui Paulo  *
4446d4f2939cSRui Paulo  * Notify listeners about find a p2p peer device found
4447d4f2939cSRui Paulo  */
4448d4f2939cSRui Paulo void wpas_dbus_signal_peer_device_found(struct wpa_supplicant *wpa_s,
4449d4f2939cSRui Paulo 					const u8 *dev_addr)
4450d4f2939cSRui Paulo {
4451d4f2939cSRui Paulo 	wpas_dbus_signal_peer(wpa_s, dev_addr,
4452d4f2939cSRui Paulo 			      WPAS_DBUS_NEW_IFACE_P2PDEVICE,
4453780fb4a2SCy Schubert 			      "DeviceFound", FALSE);
4454780fb4a2SCy Schubert 
4455780fb4a2SCy Schubert 	wpas_dbus_signal_peer(wpa_s, dev_addr,
4456780fb4a2SCy Schubert 			      WPAS_DBUS_NEW_IFACE_P2PDEVICE,
4457780fb4a2SCy Schubert 			      "DeviceFoundProperties", TRUE);
4458d4f2939cSRui Paulo }
4459d4f2939cSRui Paulo 
4460d4f2939cSRui Paulo /**
4461d4f2939cSRui Paulo  * wpas_dbus_signal_peer_lost - Send a peer lost signal
4462d4f2939cSRui Paulo  * @wpa_s: %wpa_supplicant network interface data
4463325151a3SRui Paulo  * @dev_addr: Peer P2P Device Address
4464d4f2939cSRui Paulo  *
4465d4f2939cSRui Paulo  * Notify listeners about lost a p2p peer device
4466d4f2939cSRui Paulo  */
4467d4f2939cSRui Paulo void wpas_dbus_signal_peer_device_lost(struct wpa_supplicant *wpa_s,
4468d4f2939cSRui Paulo 				       const u8 *dev_addr)
4469d4f2939cSRui Paulo {
4470d4f2939cSRui Paulo 	wpas_dbus_signal_peer(wpa_s, dev_addr,
4471d4f2939cSRui Paulo 			      WPAS_DBUS_NEW_IFACE_P2PDEVICE,
4472780fb4a2SCy Schubert 			      "DeviceLost", FALSE);
4473d4f2939cSRui Paulo }
4474d4f2939cSRui Paulo 
4475d4f2939cSRui Paulo /**
4476d4f2939cSRui Paulo  * wpas_dbus_register_peer - Register a discovered peer object with dbus
4477d4f2939cSRui Paulo  * @wpa_s: wpa_supplicant interface structure
4478325151a3SRui Paulo  * @dev_addr: P2P Device Address of the peer
4479d4f2939cSRui Paulo  * Returns: 0 on success, -1 on failure
4480d4f2939cSRui Paulo  *
4481d4f2939cSRui Paulo  * Registers network representing object with dbus
4482d4f2939cSRui Paulo  */
4483d4f2939cSRui Paulo int wpas_dbus_register_peer(struct wpa_supplicant *wpa_s, const u8 *dev_addr)
4484d4f2939cSRui Paulo {
4485d4f2939cSRui Paulo 	struct wpas_dbus_priv *ctrl_iface;
4486d4f2939cSRui Paulo 	struct wpa_dbus_object_desc *obj_desc;
4487d4f2939cSRui Paulo 	struct peer_handler_args *arg;
4488d4f2939cSRui Paulo 	char peer_obj_path[WPAS_DBUS_OBJECT_PATH_MAX];
4489d4f2939cSRui Paulo 
4490d4f2939cSRui Paulo 	/* Do nothing if the control interface is not turned on */
4491d4f2939cSRui Paulo 	if (wpa_s == NULL || wpa_s->global == NULL)
4492d4f2939cSRui Paulo 		return 0;
4493d4f2939cSRui Paulo 
4494d4f2939cSRui Paulo 	ctrl_iface = wpa_s->global->dbus;
4495d4f2939cSRui Paulo 	if (ctrl_iface == NULL)
4496d4f2939cSRui Paulo 		return 0;
4497d4f2939cSRui Paulo 
4498325151a3SRui Paulo 	wpa_s = wpa_s->parent->parent;
4499325151a3SRui Paulo 	if (!wpa_s->dbus_new_path)
4500325151a3SRui Paulo 		return 0;
45015b9c547cSRui Paulo 
4502d4f2939cSRui Paulo 	os_snprintf(peer_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
4503d4f2939cSRui Paulo 		    "%s/" WPAS_DBUS_NEW_P2P_PEERS_PART "/" COMPACT_MACSTR,
4504d4f2939cSRui Paulo 		    wpa_s->dbus_new_path, MAC2STR(dev_addr));
4505d4f2939cSRui Paulo 
4506d4f2939cSRui Paulo 	wpa_printf(MSG_INFO, "dbus: Register peer object '%s'",
4507d4f2939cSRui Paulo 		   peer_obj_path);
4508d4f2939cSRui Paulo 	obj_desc = os_zalloc(sizeof(struct wpa_dbus_object_desc));
4509d4f2939cSRui Paulo 	if (!obj_desc) {
45105b9c547cSRui Paulo 		wpa_printf(MSG_ERROR,
45115b9c547cSRui Paulo 			   "Not enough memory to create object description");
4512d4f2939cSRui Paulo 		goto err;
4513d4f2939cSRui Paulo 	}
4514d4f2939cSRui Paulo 
4515d4f2939cSRui Paulo 	/* allocate memory for handlers arguments */
4516d4f2939cSRui Paulo 	arg = os_zalloc(sizeof(struct peer_handler_args));
4517d4f2939cSRui Paulo 	if (!arg) {
45185b9c547cSRui Paulo 		wpa_printf(MSG_ERROR,
45195b9c547cSRui Paulo 			   "Not enough memory to create arguments for method");
4520d4f2939cSRui Paulo 		goto err;
4521d4f2939cSRui Paulo 	}
4522d4f2939cSRui Paulo 
4523d4f2939cSRui Paulo 	arg->wpa_s = wpa_s;
4524d4f2939cSRui Paulo 	os_memcpy(arg->p2p_device_addr, dev_addr, ETH_ALEN);
4525d4f2939cSRui Paulo 
4526d4f2939cSRui Paulo 	wpas_dbus_register(obj_desc, arg, wpa_dbus_free,
4527d4f2939cSRui Paulo 			   NULL,
4528d4f2939cSRui Paulo 			   wpas_dbus_p2p_peer_properties,
4529d4f2939cSRui Paulo 			   wpas_dbus_p2p_peer_signals);
4530d4f2939cSRui Paulo 
4531d4f2939cSRui Paulo 	if (wpa_dbus_register_object_per_iface(ctrl_iface, peer_obj_path,
4532d4f2939cSRui Paulo 					       wpa_s->ifname, obj_desc))
4533d4f2939cSRui Paulo 		goto err;
4534d4f2939cSRui Paulo 
4535d4f2939cSRui Paulo 	return 0;
4536d4f2939cSRui Paulo 
4537d4f2939cSRui Paulo err:
4538d4f2939cSRui Paulo 	free_dbus_object_desc(obj_desc);
4539d4f2939cSRui Paulo 	return -1;
4540d4f2939cSRui Paulo }
4541d4f2939cSRui Paulo 
4542d4f2939cSRui Paulo /**
4543d4f2939cSRui Paulo  * wpas_dbus_unregister_peer - Unregister a peer object with dbus
4544d4f2939cSRui Paulo  * @wpa_s: wpa_supplicant interface structure
4545d4f2939cSRui Paulo  * @dev_addr: p2p device addr
4546d4f2939cSRui Paulo  * Returns: 0 on success, -1 on failure
4547d4f2939cSRui Paulo  *
4548d4f2939cSRui Paulo  * Registers network representing object with dbus
4549d4f2939cSRui Paulo  */
4550d4f2939cSRui Paulo int wpas_dbus_unregister_peer(struct wpa_supplicant *wpa_s,
4551d4f2939cSRui Paulo 				  const u8 *dev_addr)
4552d4f2939cSRui Paulo {
4553d4f2939cSRui Paulo 	struct wpas_dbus_priv *ctrl_iface;
4554d4f2939cSRui Paulo 	char peer_obj_path[WPAS_DBUS_OBJECT_PATH_MAX];
4555d4f2939cSRui Paulo 	int ret;
4556d4f2939cSRui Paulo 
4557d4f2939cSRui Paulo 	/* Do nothing if the control interface is not turned on */
4558325151a3SRui Paulo 	if (wpa_s == NULL || wpa_s->global == NULL)
4559d4f2939cSRui Paulo 		return 0;
45605b9c547cSRui Paulo 
4561325151a3SRui Paulo 	wpa_s = wpa_s->parent->parent;
4562325151a3SRui Paulo 	if (!wpa_s->dbus_new_path)
4563325151a3SRui Paulo 		return 0;
45645b9c547cSRui Paulo 
4565d4f2939cSRui Paulo 	ctrl_iface = wpa_s->global->dbus;
4566d4f2939cSRui Paulo 	if (ctrl_iface == NULL)
4567d4f2939cSRui Paulo 		return 0;
4568d4f2939cSRui Paulo 
4569d4f2939cSRui Paulo 	os_snprintf(peer_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
4570d4f2939cSRui Paulo 		    "%s/" WPAS_DBUS_NEW_P2P_PEERS_PART "/" COMPACT_MACSTR,
4571d4f2939cSRui Paulo 		    wpa_s->dbus_new_path, MAC2STR(dev_addr));
4572d4f2939cSRui Paulo 
4573d4f2939cSRui Paulo 	wpa_printf(MSG_INFO, "dbus: Unregister peer object '%s'",
4574d4f2939cSRui Paulo 		   peer_obj_path);
4575d4f2939cSRui Paulo 	ret = wpa_dbus_unregister_object_per_iface(ctrl_iface, peer_obj_path);
4576d4f2939cSRui Paulo 
4577d4f2939cSRui Paulo 	return ret;
4578d4f2939cSRui Paulo }
4579d4f2939cSRui Paulo 
4580d4f2939cSRui Paulo 
4581325151a3SRui Paulo /**
4582325151a3SRui Paulo  * wpas_dbus_signal_p2p_find_stopped - Send P2P Find stopped signal
4583325151a3SRui Paulo  * @wpa_s: %wpa_supplicant network interface data
4584325151a3SRui Paulo  *
4585325151a3SRui Paulo  * Notify listeners about P2P Find stopped
4586325151a3SRui Paulo  */
4587325151a3SRui Paulo void wpas_dbus_signal_p2p_find_stopped(struct wpa_supplicant *wpa_s)
4588325151a3SRui Paulo {
4589325151a3SRui Paulo 	struct wpas_dbus_priv *iface;
4590325151a3SRui Paulo 	DBusMessage *msg;
4591325151a3SRui Paulo 
4592325151a3SRui Paulo 	iface = wpa_s->global->dbus;
4593325151a3SRui Paulo 
4594325151a3SRui Paulo 	/* Do nothing if the control interface is not turned on */
459585732ac8SCy Schubert 	if (iface == NULL)
459685732ac8SCy Schubert 		return;
459785732ac8SCy Schubert 
459885732ac8SCy Schubert 	if (wpa_s->p2p_mgmt)
459985732ac8SCy Schubert 		wpa_s = wpa_s->parent;
460085732ac8SCy Schubert 
460185732ac8SCy Schubert 	if (!wpa_s->dbus_new_path)
4602325151a3SRui Paulo 		return;
4603325151a3SRui Paulo 
4604325151a3SRui Paulo 	msg = dbus_message_new_signal(wpa_s->dbus_new_path,
4605325151a3SRui Paulo 				      WPAS_DBUS_NEW_IFACE_P2PDEVICE,
4606325151a3SRui Paulo 				      "FindStopped");
4607325151a3SRui Paulo 	if (msg == NULL)
4608325151a3SRui Paulo 		return;
4609325151a3SRui Paulo 
4610325151a3SRui Paulo 	dbus_connection_send(iface->con, msg, NULL);
4611325151a3SRui Paulo 
4612325151a3SRui Paulo 	dbus_message_unref(msg);
4613325151a3SRui Paulo }
4614325151a3SRui Paulo 
4615325151a3SRui Paulo 
4616325151a3SRui Paulo /**
4617325151a3SRui Paulo  * wpas_dbus_signal_peer_groups_changed - Send peer group change property signal
4618325151a3SRui Paulo  * @wpa_s: %wpa_supplicant network interface data
4619325151a3SRui Paulo  * @dev_addr: P2P Device Address
4620325151a3SRui Paulo  *
4621325151a3SRui Paulo  * Notify listeners about peer Groups property changes.
4622325151a3SRui Paulo  */
46235b9c547cSRui Paulo void wpas_dbus_signal_peer_groups_changed(struct wpa_supplicant *wpa_s,
46245b9c547cSRui Paulo 					  const u8 *dev_addr)
46255b9c547cSRui Paulo {
46265b9c547cSRui Paulo 	char peer_obj_path[WPAS_DBUS_OBJECT_PATH_MAX];
46275b9c547cSRui Paulo 
46285b9c547cSRui Paulo 	if (wpa_s->p2p_mgmt)
46295b9c547cSRui Paulo 		wpa_s = wpa_s->parent;
46305b9c547cSRui Paulo 
4631325151a3SRui Paulo 	if (!wpa_s->dbus_new_path)
4632325151a3SRui Paulo 		return;
46335b9c547cSRui Paulo 	os_snprintf(peer_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
46345b9c547cSRui Paulo 		    "%s/" WPAS_DBUS_NEW_P2P_PEERS_PART "/" COMPACT_MACSTR,
46355b9c547cSRui Paulo 		    wpa_s->dbus_new_path, MAC2STR(dev_addr));
46365b9c547cSRui Paulo 
46375b9c547cSRui Paulo 	wpa_dbus_mark_property_changed(wpa_s->global->dbus, peer_obj_path,
46385b9c547cSRui Paulo 				       WPAS_DBUS_NEW_IFACE_P2P_PEER, "Groups");
46395b9c547cSRui Paulo }
46405b9c547cSRui Paulo 
46415b9c547cSRui Paulo 
4642d4f2939cSRui Paulo static const struct wpa_dbus_property_desc wpas_dbus_p2p_group_properties[] = {
4643d4f2939cSRui Paulo 	{ "Members", WPAS_DBUS_NEW_IFACE_P2P_GROUP, "ao",
4644d4f2939cSRui Paulo 	  wpas_dbus_getter_p2p_group_members,
4645780fb4a2SCy Schubert 	  NULL,
4646d4f2939cSRui Paulo 	  NULL
4647d4f2939cSRui Paulo 	},
4648d4f2939cSRui Paulo 	{ "Group", WPAS_DBUS_NEW_IFACE_P2P_GROUP, "o",
4649d4f2939cSRui Paulo 	  wpas_dbus_getter_p2p_group,
4650780fb4a2SCy Schubert 	  NULL,
4651d4f2939cSRui Paulo 	  NULL
4652d4f2939cSRui Paulo 	},
4653d4f2939cSRui Paulo 	{ "Role", WPAS_DBUS_NEW_IFACE_P2P_GROUP, "s",
4654d4f2939cSRui Paulo 	  wpas_dbus_getter_p2p_role,
4655780fb4a2SCy Schubert 	  NULL,
4656d4f2939cSRui Paulo 	  NULL
4657d4f2939cSRui Paulo 	},
4658d4f2939cSRui Paulo 	{ "SSID", WPAS_DBUS_NEW_IFACE_P2P_GROUP, "ay",
4659d4f2939cSRui Paulo 	  wpas_dbus_getter_p2p_group_ssid,
4660780fb4a2SCy Schubert 	  NULL,
4661d4f2939cSRui Paulo 	  NULL
4662d4f2939cSRui Paulo 	},
4663d4f2939cSRui Paulo 	{ "BSSID", WPAS_DBUS_NEW_IFACE_P2P_GROUP, "ay",
4664d4f2939cSRui Paulo 	  wpas_dbus_getter_p2p_group_bssid,
4665780fb4a2SCy Schubert 	  NULL,
4666d4f2939cSRui Paulo 	  NULL
4667d4f2939cSRui Paulo 	},
4668d4f2939cSRui Paulo 	{ "Frequency", WPAS_DBUS_NEW_IFACE_P2P_GROUP, "q",
4669d4f2939cSRui Paulo 	  wpas_dbus_getter_p2p_group_frequency,
4670780fb4a2SCy Schubert 	  NULL,
4671d4f2939cSRui Paulo 	  NULL
4672d4f2939cSRui Paulo 	},
4673d4f2939cSRui Paulo 	{ "Passphrase", WPAS_DBUS_NEW_IFACE_P2P_GROUP, "s",
4674d4f2939cSRui Paulo 	  wpas_dbus_getter_p2p_group_passphrase,
4675780fb4a2SCy Schubert 	  NULL,
4676d4f2939cSRui Paulo 	  NULL
4677d4f2939cSRui Paulo 	},
4678d4f2939cSRui Paulo 	{ "PSK", WPAS_DBUS_NEW_IFACE_P2P_GROUP, "ay",
4679d4f2939cSRui Paulo 	  wpas_dbus_getter_p2p_group_psk,
4680780fb4a2SCy Schubert 	  NULL,
4681d4f2939cSRui Paulo 	  NULL
4682d4f2939cSRui Paulo 	},
4683d4f2939cSRui Paulo 	{ "WPSVendorExtensions", WPAS_DBUS_NEW_IFACE_P2P_GROUP, "aay",
4684d4f2939cSRui Paulo 	  wpas_dbus_getter_p2p_group_vendor_ext,
4685780fb4a2SCy Schubert 	  wpas_dbus_setter_p2p_group_vendor_ext,
4686780fb4a2SCy Schubert 	  NULL
4687d4f2939cSRui Paulo 	},
4688780fb4a2SCy Schubert 	{ NULL, NULL, NULL, NULL, NULL, NULL }
4689d4f2939cSRui Paulo };
4690d4f2939cSRui Paulo 
4691d4f2939cSRui Paulo static const struct wpa_dbus_signal_desc wpas_dbus_p2p_group_signals[] = {
4692d4f2939cSRui Paulo 	{ "PeerJoined", WPAS_DBUS_NEW_IFACE_P2P_GROUP,
4693d4f2939cSRui Paulo 	  {
4694d4f2939cSRui Paulo 		  { "peer", "o", ARG_OUT },
4695d4f2939cSRui Paulo 		  END_ARGS
4696d4f2939cSRui Paulo 	  }
4697d4f2939cSRui Paulo 	},
4698d4f2939cSRui Paulo 	{ "PeerDisconnected", WPAS_DBUS_NEW_IFACE_P2P_GROUP,
4699d4f2939cSRui Paulo 	  {
4700d4f2939cSRui Paulo 		  { "peer", "o", ARG_OUT },
4701d4f2939cSRui Paulo 		  END_ARGS
4702d4f2939cSRui Paulo 	  }
4703d4f2939cSRui Paulo 	},
4704d4f2939cSRui Paulo 	{ NULL, NULL, { END_ARGS } }
4705d4f2939cSRui Paulo };
4706d4f2939cSRui Paulo 
4707d4f2939cSRui Paulo /**
4708d4f2939cSRui Paulo  * wpas_dbus_register_p2p_group - Register a p2p group object with dbus
4709d4f2939cSRui Paulo  * @wpa_s: wpa_supplicant interface structure
4710d4f2939cSRui Paulo  * @ssid: SSID struct
4711d4f2939cSRui Paulo  * Returns: 0 on success, -1 on failure
4712d4f2939cSRui Paulo  *
4713d4f2939cSRui Paulo  * Registers p2p group representing object with dbus
4714d4f2939cSRui Paulo  */
4715d4f2939cSRui Paulo void wpas_dbus_register_p2p_group(struct wpa_supplicant *wpa_s,
4716d4f2939cSRui Paulo 				  struct wpa_ssid *ssid)
4717d4f2939cSRui Paulo {
4718d4f2939cSRui Paulo 	struct wpas_dbus_priv *ctrl_iface;
4719d4f2939cSRui Paulo 	struct wpa_dbus_object_desc *obj_desc;
4720d4f2939cSRui Paulo 	char group_obj_path[WPAS_DBUS_OBJECT_PATH_MAX];
4721d4f2939cSRui Paulo 
4722d4f2939cSRui Paulo 	/* Do nothing if the control interface is not turned on */
4723d4f2939cSRui Paulo 	if (wpa_s == NULL || wpa_s->global == NULL)
4724d4f2939cSRui Paulo 		return;
4725d4f2939cSRui Paulo 
4726d4f2939cSRui Paulo 	ctrl_iface = wpa_s->global->dbus;
4727d4f2939cSRui Paulo 	if (ctrl_iface == NULL)
4728d4f2939cSRui Paulo 		return;
4729d4f2939cSRui Paulo 
4730d4f2939cSRui Paulo 	if (wpa_s->dbus_groupobj_path) {
4731d4f2939cSRui Paulo 		wpa_printf(MSG_INFO, "%s: Group object '%s' already exists",
4732d4f2939cSRui Paulo 			   __func__, wpa_s->dbus_groupobj_path);
4733d4f2939cSRui Paulo 		return;
4734d4f2939cSRui Paulo 	}
4735d4f2939cSRui Paulo 
4736d4f2939cSRui Paulo 	if (wpas_dbus_get_group_obj_path(wpa_s, ssid, group_obj_path) < 0)
4737d4f2939cSRui Paulo 		return;
4738d4f2939cSRui Paulo 
4739d4f2939cSRui Paulo 	wpa_s->dbus_groupobj_path = os_strdup(group_obj_path);
4740d4f2939cSRui Paulo 	if (wpa_s->dbus_groupobj_path == NULL)
4741d4f2939cSRui Paulo 		return;
4742d4f2939cSRui Paulo 
4743d4f2939cSRui Paulo 	wpa_printf(MSG_INFO, "dbus: Register group object '%s'",
4744d4f2939cSRui Paulo 		   group_obj_path);
4745d4f2939cSRui Paulo 	obj_desc = os_zalloc(sizeof(struct wpa_dbus_object_desc));
4746d4f2939cSRui Paulo 	if (!obj_desc) {
47475b9c547cSRui Paulo 		wpa_printf(MSG_ERROR,
47485b9c547cSRui Paulo 			   "Not enough memory to create object description");
4749d4f2939cSRui Paulo 		goto err;
4750d4f2939cSRui Paulo 	}
4751d4f2939cSRui Paulo 
4752d4f2939cSRui Paulo 	wpas_dbus_register(obj_desc, wpa_s, NULL, NULL,
4753d4f2939cSRui Paulo 			   wpas_dbus_p2p_group_properties,
4754d4f2939cSRui Paulo 			   wpas_dbus_p2p_group_signals);
4755d4f2939cSRui Paulo 
4756d4f2939cSRui Paulo 	if (wpa_dbus_register_object_per_iface(ctrl_iface, group_obj_path,
4757d4f2939cSRui Paulo 					       wpa_s->ifname, obj_desc))
4758d4f2939cSRui Paulo 		goto err;
4759d4f2939cSRui Paulo 
4760d4f2939cSRui Paulo 	return;
4761d4f2939cSRui Paulo 
4762d4f2939cSRui Paulo err:
4763d4f2939cSRui Paulo 	if (wpa_s->dbus_groupobj_path) {
4764d4f2939cSRui Paulo 		os_free(wpa_s->dbus_groupobj_path);
4765d4f2939cSRui Paulo 		wpa_s->dbus_groupobj_path = NULL;
4766d4f2939cSRui Paulo 	}
4767d4f2939cSRui Paulo 
4768d4f2939cSRui Paulo 	free_dbus_object_desc(obj_desc);
4769d4f2939cSRui Paulo }
4770d4f2939cSRui Paulo 
4771d4f2939cSRui Paulo /**
4772d4f2939cSRui Paulo  * wpas_dbus_unregister_p2p_group - Unregister a p2p group object from dbus
4773d4f2939cSRui Paulo  * @wpa_s: wpa_supplicant interface structure
4774d4f2939cSRui Paulo  * @ssid: network name of the p2p group started
4775d4f2939cSRui Paulo  */
4776d4f2939cSRui Paulo void wpas_dbus_unregister_p2p_group(struct wpa_supplicant *wpa_s,
4777d4f2939cSRui Paulo 				    const struct wpa_ssid *ssid)
4778d4f2939cSRui Paulo {
4779d4f2939cSRui Paulo 	struct wpas_dbus_priv *ctrl_iface;
4780d4f2939cSRui Paulo 
4781d4f2939cSRui Paulo 	/* Do nothing if the control interface is not turned on */
4782d4f2939cSRui Paulo 	if (wpa_s == NULL || wpa_s->global == NULL)
4783d4f2939cSRui Paulo 		return;
4784d4f2939cSRui Paulo 
47855b9c547cSRui Paulo 	if (wpa_s->p2p_mgmt)
47865b9c547cSRui Paulo 		wpa_s = wpa_s->parent;
47875b9c547cSRui Paulo 
4788d4f2939cSRui Paulo 	ctrl_iface = wpa_s->global->dbus;
4789d4f2939cSRui Paulo 	if (ctrl_iface == NULL)
4790d4f2939cSRui Paulo 		return;
4791d4f2939cSRui Paulo 
4792d4f2939cSRui Paulo 	if (!wpa_s->dbus_groupobj_path) {
4793d4f2939cSRui Paulo 		wpa_printf(MSG_DEBUG,
4794d4f2939cSRui Paulo 			   "%s: Group object '%s' already unregistered",
4795d4f2939cSRui Paulo 			   __func__, wpa_s->dbus_groupobj_path);
4796d4f2939cSRui Paulo 		return;
4797d4f2939cSRui Paulo 	}
4798d4f2939cSRui Paulo 
47995b9c547cSRui Paulo 	peer_groups_changed(wpa_s);
48005b9c547cSRui Paulo 
4801d4f2939cSRui Paulo 	wpa_printf(MSG_DEBUG, "dbus: Unregister group object '%s'",
4802d4f2939cSRui Paulo 		   wpa_s->dbus_groupobj_path);
4803d4f2939cSRui Paulo 
4804d4f2939cSRui Paulo 	wpa_dbus_unregister_object_per_iface(ctrl_iface,
4805d4f2939cSRui Paulo 					     wpa_s->dbus_groupobj_path);
4806d4f2939cSRui Paulo 
4807d4f2939cSRui Paulo 	os_free(wpa_s->dbus_groupobj_path);
4808d4f2939cSRui Paulo 	wpa_s->dbus_groupobj_path = NULL;
4809d4f2939cSRui Paulo }
4810d4f2939cSRui Paulo 
4811d4f2939cSRui Paulo static const struct wpa_dbus_property_desc
4812d4f2939cSRui Paulo 	wpas_dbus_persistent_group_properties[] = {
4813d4f2939cSRui Paulo 	{ "Properties", WPAS_DBUS_NEW_IFACE_PERSISTENT_GROUP, "a{sv}",
4814d4f2939cSRui Paulo 	  wpas_dbus_getter_persistent_group_properties,
4815780fb4a2SCy Schubert 	  wpas_dbus_setter_persistent_group_properties,
4816780fb4a2SCy Schubert 	  NULL
4817d4f2939cSRui Paulo 	},
4818780fb4a2SCy Schubert 	{ NULL, NULL, NULL, NULL, NULL, NULL }
4819d4f2939cSRui Paulo };
4820d4f2939cSRui Paulo 
4821d4f2939cSRui Paulo /* No signals intended for persistent group objects */
4822d4f2939cSRui Paulo 
4823d4f2939cSRui Paulo /**
4824d4f2939cSRui Paulo  * wpas_dbus_register_persistent_group - Register a configured(saved)
4825d4f2939cSRui Paulo  *	persistent group with dbus
4826d4f2939cSRui Paulo  * @wpa_s: wpa_supplicant interface structure
4827d4f2939cSRui Paulo  * @ssid: persistent group (still represented as a network within wpa)
4828d4f2939cSRui Paulo  *	  configuration data
4829d4f2939cSRui Paulo  * Returns: 0 on success, -1 on failure
4830d4f2939cSRui Paulo  *
4831d4f2939cSRui Paulo  * Registers a persistent group representing object with dbus.
4832d4f2939cSRui Paulo  */
4833d4f2939cSRui Paulo int wpas_dbus_register_persistent_group(struct wpa_supplicant *wpa_s,
4834d4f2939cSRui Paulo 					struct wpa_ssid *ssid)
4835d4f2939cSRui Paulo {
4836d4f2939cSRui Paulo 	struct wpas_dbus_priv *ctrl_iface;
4837d4f2939cSRui Paulo 	struct wpa_dbus_object_desc *obj_desc;
4838d4f2939cSRui Paulo 	struct network_handler_args *arg;
4839d4f2939cSRui Paulo 	char pgrp_obj_path[WPAS_DBUS_OBJECT_PATH_MAX];
4840d4f2939cSRui Paulo 
4841d4f2939cSRui Paulo 	/* Do nothing if the control interface is not turned on */
4842d4f2939cSRui Paulo 	if (wpa_s == NULL || wpa_s->global == NULL)
4843d4f2939cSRui Paulo 		return 0;
4844325151a3SRui Paulo 	wpa_s = wpa_s->parent->parent;
4845325151a3SRui Paulo 	if (!wpa_s->dbus_new_path)
4846325151a3SRui Paulo 		return 0;
4847d4f2939cSRui Paulo 
4848d4f2939cSRui Paulo 	/* Make sure ssid is a persistent group */
4849d4f2939cSRui Paulo 	if (ssid->disabled != 2 && !ssid->p2p_persistent_group)
4850d4f2939cSRui Paulo 		return -1; /* should we return w/o complaining? */
4851d4f2939cSRui Paulo 
48525b9c547cSRui Paulo 	if (wpa_s->p2p_mgmt)
48535b9c547cSRui Paulo 		wpa_s = wpa_s->parent;
48545b9c547cSRui Paulo 
4855d4f2939cSRui Paulo 	ctrl_iface = wpa_s->global->dbus;
4856d4f2939cSRui Paulo 	if (ctrl_iface == NULL)
4857d4f2939cSRui Paulo 		return 0;
4858d4f2939cSRui Paulo 
4859d4f2939cSRui Paulo 	/*
4860d4f2939cSRui Paulo 	 * Intentionally not coming up with different numbering scheme
4861d4f2939cSRui Paulo 	 * for persistent groups.
4862d4f2939cSRui Paulo 	 */
4863d4f2939cSRui Paulo 	os_snprintf(pgrp_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
4864d4f2939cSRui Paulo 		    "%s/" WPAS_DBUS_NEW_PERSISTENT_GROUPS_PART "/%u",
4865d4f2939cSRui Paulo 		    wpa_s->dbus_new_path, ssid->id);
4866d4f2939cSRui Paulo 
4867d4f2939cSRui Paulo 	wpa_printf(MSG_DEBUG, "dbus: Register persistent group object '%s'",
4868d4f2939cSRui Paulo 		   pgrp_obj_path);
4869d4f2939cSRui Paulo 	obj_desc = os_zalloc(sizeof(struct wpa_dbus_object_desc));
4870d4f2939cSRui Paulo 	if (!obj_desc) {
48715b9c547cSRui Paulo 		wpa_printf(MSG_ERROR,
48725b9c547cSRui Paulo 			   "dbus: Not enough memory to create object description");
4873d4f2939cSRui Paulo 		goto err;
4874d4f2939cSRui Paulo 	}
4875d4f2939cSRui Paulo 
4876d4f2939cSRui Paulo 	/*
4877d4f2939cSRui Paulo 	 * Reusing the same context structure as that for networks
4878d4f2939cSRui Paulo 	 * since these are represented using same data structure.
4879d4f2939cSRui Paulo 	 */
4880d4f2939cSRui Paulo 	/* allocate memory for handlers arguments */
4881d4f2939cSRui Paulo 	arg = os_zalloc(sizeof(struct network_handler_args));
4882d4f2939cSRui Paulo 	if (!arg) {
48835b9c547cSRui Paulo 		wpa_printf(MSG_ERROR,
48845b9c547cSRui Paulo 			   "dbus: Not enough memory to create arguments for method");
4885d4f2939cSRui Paulo 		goto err;
4886d4f2939cSRui Paulo 	}
4887d4f2939cSRui Paulo 
4888d4f2939cSRui Paulo 	arg->wpa_s = wpa_s;
4889d4f2939cSRui Paulo 	arg->ssid = ssid;
4890d4f2939cSRui Paulo 
4891d4f2939cSRui Paulo 	wpas_dbus_register(obj_desc, arg, wpa_dbus_free, NULL,
4892d4f2939cSRui Paulo 			   wpas_dbus_persistent_group_properties,
4893d4f2939cSRui Paulo 			   NULL);
4894d4f2939cSRui Paulo 
4895d4f2939cSRui Paulo 	if (wpa_dbus_register_object_per_iface(ctrl_iface, pgrp_obj_path,
4896d4f2939cSRui Paulo 					       wpa_s->ifname, obj_desc))
4897d4f2939cSRui Paulo 		goto err;
4898d4f2939cSRui Paulo 
4899d4f2939cSRui Paulo 	wpas_dbus_signal_persistent_group_added(wpa_s, ssid->id);
4900d4f2939cSRui Paulo 
4901d4f2939cSRui Paulo 	return 0;
4902d4f2939cSRui Paulo 
4903d4f2939cSRui Paulo err:
4904d4f2939cSRui Paulo 	free_dbus_object_desc(obj_desc);
4905d4f2939cSRui Paulo 	return -1;
4906d4f2939cSRui Paulo }
4907d4f2939cSRui Paulo 
4908d4f2939cSRui Paulo 
4909d4f2939cSRui Paulo /**
4910d4f2939cSRui Paulo  * wpas_dbus_unregister_persistent_group - Unregister a persistent_group
4911d4f2939cSRui Paulo  *	from dbus
4912d4f2939cSRui Paulo  * @wpa_s: wpa_supplicant interface structure
4913d4f2939cSRui Paulo  * @nid: network id
4914d4f2939cSRui Paulo  * Returns: 0 on success, -1 on failure
4915d4f2939cSRui Paulo  *
4916d4f2939cSRui Paulo  * Unregisters persistent group representing object from dbus
4917d4f2939cSRui Paulo  *
4918d4f2939cSRui Paulo  * NOTE: There is a slight issue with the semantics here. While the
4919d4f2939cSRui Paulo  * implementation simply means the persistent group is unloaded from memory,
4920d4f2939cSRui Paulo  * it should not get interpreted as the group is actually being erased/removed
4921d4f2939cSRui Paulo  * from persistent storage as well.
4922d4f2939cSRui Paulo  */
4923d4f2939cSRui Paulo int wpas_dbus_unregister_persistent_group(struct wpa_supplicant *wpa_s,
4924d4f2939cSRui Paulo 					  int nid)
4925d4f2939cSRui Paulo {
4926d4f2939cSRui Paulo 	struct wpas_dbus_priv *ctrl_iface;
4927d4f2939cSRui Paulo 	char pgrp_obj_path[WPAS_DBUS_OBJECT_PATH_MAX];
4928d4f2939cSRui Paulo 	int ret;
4929d4f2939cSRui Paulo 
4930d4f2939cSRui Paulo 	/* Do nothing if the control interface is not turned on */
4931325151a3SRui Paulo 	if (wpa_s == NULL || wpa_s->global == NULL)
4932d4f2939cSRui Paulo 		return 0;
49335b9c547cSRui Paulo 
4934325151a3SRui Paulo 	wpa_s = wpa_s->parent->parent;
49355b9c547cSRui Paulo 
4936d4f2939cSRui Paulo 	ctrl_iface = wpa_s->global->dbus;
4937325151a3SRui Paulo 	if (ctrl_iface == NULL || !wpa_s->dbus_new_path)
4938d4f2939cSRui Paulo 		return 0;
4939d4f2939cSRui Paulo 
4940d4f2939cSRui Paulo 	os_snprintf(pgrp_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
4941d4f2939cSRui Paulo 		    "%s/" WPAS_DBUS_NEW_PERSISTENT_GROUPS_PART "/%u",
4942d4f2939cSRui Paulo 		    wpa_s->dbus_new_path, nid);
4943d4f2939cSRui Paulo 
4944d4f2939cSRui Paulo 	wpa_printf(MSG_DEBUG, "dbus: Unregister persistent group object '%s'",
4945d4f2939cSRui Paulo 		   pgrp_obj_path);
4946d4f2939cSRui Paulo 	ret = wpa_dbus_unregister_object_per_iface(ctrl_iface, pgrp_obj_path);
4947d4f2939cSRui Paulo 
4948d4f2939cSRui Paulo 	if (!ret)
4949d4f2939cSRui Paulo 		wpas_dbus_signal_persistent_group_removed(wpa_s, nid);
4950d4f2939cSRui Paulo 
4951d4f2939cSRui Paulo 	return ret;
4952d4f2939cSRui Paulo }
4953d4f2939cSRui Paulo 
4954d4f2939cSRui Paulo #endif /* CONFIG_P2P */
4955