xref: /freebsd/contrib/wpa/wpa_supplicant/dbus/dbus_new.c (revision c1d255d3ffdbe447de3ab875bf4e7d7accc5bfc5)
1d4f2939cSRui Paulo /*
2d4f2939cSRui Paulo  * WPA Supplicant / dbus-based control interface
3d4f2939cSRui Paulo  * Copyright (c) 2006, Dan Williams <dcbw@redhat.com> and Red Hat, Inc.
4d4f2939cSRui Paulo  * Copyright (c) 2009-2010, Witold Sowa <witold.sowa@gmail.com>
5d4f2939cSRui Paulo  * Copyright (c) 2009, Jouni Malinen <j@w1.fi>
6d4f2939cSRui Paulo  *
7d4f2939cSRui Paulo  * This software may be distributed under the terms of the BSD license.
8d4f2939cSRui Paulo  * See README for more details.
9d4f2939cSRui Paulo  */
10d4f2939cSRui Paulo 
11d4f2939cSRui Paulo #include "includes.h"
12d4f2939cSRui Paulo 
13d4f2939cSRui Paulo #include "common.h"
14d4f2939cSRui Paulo #include "common/ieee802_11_defs.h"
15d4f2939cSRui Paulo #include "wps/wps.h"
164bc52338SCy Schubert #include "ap/sta_info.h"
17d4f2939cSRui Paulo #include "../config.h"
18d4f2939cSRui Paulo #include "../wpa_supplicant_i.h"
19d4f2939cSRui Paulo #include "../bss.h"
20d4f2939cSRui Paulo #include "../wpas_glue.h"
21d4f2939cSRui Paulo #include "dbus_new_helpers.h"
22d4f2939cSRui Paulo #include "dbus_dict_helpers.h"
23d4f2939cSRui Paulo #include "dbus_new.h"
24d4f2939cSRui Paulo #include "dbus_new_handlers.h"
25d4f2939cSRui Paulo #include "dbus_common_i.h"
26d4f2939cSRui Paulo #include "dbus_new_handlers_p2p.h"
27d4f2939cSRui Paulo #include "p2p/p2p.h"
285b9c547cSRui Paulo #include "../p2p_supplicant.h"
29d4f2939cSRui Paulo 
30d4f2939cSRui Paulo #ifdef CONFIG_AP /* until needed by something else */
31d4f2939cSRui Paulo 
32d4f2939cSRui Paulo /*
33d4f2939cSRui Paulo  * NameOwnerChanged handling
34d4f2939cSRui Paulo  *
35d4f2939cSRui Paulo  * Some services we provide allow an application to register for
36d4f2939cSRui Paulo  * a signal that it needs. While it can also unregister, we must
37d4f2939cSRui Paulo  * be prepared for the case where the application simply crashes
38d4f2939cSRui Paulo  * and thus doesn't clean up properly. The way to handle this in
39d4f2939cSRui Paulo  * DBus is to register for the NameOwnerChanged signal which will
40d4f2939cSRui Paulo  * signal an owner change to NULL if the peer closes the socket
41d4f2939cSRui Paulo  * for whatever reason.
42d4f2939cSRui Paulo  *
43d4f2939cSRui Paulo  * Handle this signal via a filter function whenever necessary.
44d4f2939cSRui Paulo  * The code below also handles refcounting in case in the future
45d4f2939cSRui Paulo  * there will be multiple instances of this subscription scheme.
46d4f2939cSRui Paulo  */
47d4f2939cSRui Paulo static const char wpas_dbus_noc_filter_str[] =
48d4f2939cSRui Paulo 	"interface=org.freedesktop.DBus,member=NameOwnerChanged";
49d4f2939cSRui Paulo 
50d4f2939cSRui Paulo 
51d4f2939cSRui Paulo static DBusHandlerResult noc_filter(DBusConnection *conn,
52d4f2939cSRui Paulo 				    DBusMessage *message, void *data)
53d4f2939cSRui Paulo {
54d4f2939cSRui Paulo 	struct wpas_dbus_priv *priv = data;
55d4f2939cSRui Paulo 
56d4f2939cSRui Paulo 	if (dbus_message_get_type(message) != DBUS_MESSAGE_TYPE_SIGNAL)
57d4f2939cSRui Paulo 		return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
58d4f2939cSRui Paulo 
59d4f2939cSRui Paulo 	if (dbus_message_is_signal(message, DBUS_INTERFACE_DBUS,
60d4f2939cSRui Paulo 				   "NameOwnerChanged")) {
61d4f2939cSRui Paulo 		const char *name;
62d4f2939cSRui Paulo 		const char *prev_owner;
63d4f2939cSRui Paulo 		const char *new_owner;
64d4f2939cSRui Paulo 		DBusError derr;
65d4f2939cSRui Paulo 		struct wpa_supplicant *wpa_s;
66d4f2939cSRui Paulo 
67d4f2939cSRui Paulo 		dbus_error_init(&derr);
68d4f2939cSRui Paulo 
69d4f2939cSRui Paulo 		if (!dbus_message_get_args(message, &derr,
70d4f2939cSRui Paulo 					   DBUS_TYPE_STRING, &name,
71d4f2939cSRui Paulo 					   DBUS_TYPE_STRING, &prev_owner,
72d4f2939cSRui Paulo 					   DBUS_TYPE_STRING, &new_owner,
73d4f2939cSRui Paulo 					   DBUS_TYPE_INVALID)) {
74d4f2939cSRui Paulo 			/* Ignore this error */
75d4f2939cSRui Paulo 			dbus_error_free(&derr);
76d4f2939cSRui Paulo 			return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
77d4f2939cSRui Paulo 		}
78d4f2939cSRui Paulo 
795b9c547cSRui Paulo 		for (wpa_s = priv->global->ifaces; wpa_s; wpa_s = wpa_s->next) {
80d4f2939cSRui Paulo 			if (wpa_s->preq_notify_peer != NULL &&
81d4f2939cSRui Paulo 			    os_strcmp(name, wpa_s->preq_notify_peer) == 0 &&
82d4f2939cSRui Paulo 			    (new_owner == NULL || os_strlen(new_owner) == 0)) {
83d4f2939cSRui Paulo 				/* probe request owner disconnected */
84d4f2939cSRui Paulo 				os_free(wpa_s->preq_notify_peer);
85d4f2939cSRui Paulo 				wpa_s->preq_notify_peer = NULL;
86d4f2939cSRui Paulo 				wpas_dbus_unsubscribe_noc(priv);
87d4f2939cSRui Paulo 			}
88d4f2939cSRui Paulo 		}
89d4f2939cSRui Paulo 	}
90d4f2939cSRui Paulo 
91d4f2939cSRui Paulo 	return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
92d4f2939cSRui Paulo }
93d4f2939cSRui Paulo 
94d4f2939cSRui Paulo 
95d4f2939cSRui Paulo void wpas_dbus_subscribe_noc(struct wpas_dbus_priv *priv)
96d4f2939cSRui Paulo {
97d4f2939cSRui Paulo 	priv->dbus_noc_refcnt++;
98d4f2939cSRui Paulo 	if (priv->dbus_noc_refcnt > 1)
99d4f2939cSRui Paulo 		return;
100d4f2939cSRui Paulo 
101d4f2939cSRui Paulo 	if (!dbus_connection_add_filter(priv->con, noc_filter, priv, NULL)) {
102d4f2939cSRui Paulo 		wpa_printf(MSG_ERROR, "dbus: failed to add filter");
103d4f2939cSRui Paulo 		return;
104d4f2939cSRui Paulo 	}
105d4f2939cSRui Paulo 
106d4f2939cSRui Paulo 	dbus_bus_add_match(priv->con, wpas_dbus_noc_filter_str, NULL);
107d4f2939cSRui Paulo }
108d4f2939cSRui Paulo 
109d4f2939cSRui Paulo 
110d4f2939cSRui Paulo void wpas_dbus_unsubscribe_noc(struct wpas_dbus_priv *priv)
111d4f2939cSRui Paulo {
112d4f2939cSRui Paulo 	priv->dbus_noc_refcnt--;
113d4f2939cSRui Paulo 	if (priv->dbus_noc_refcnt > 0)
114d4f2939cSRui Paulo 		return;
115d4f2939cSRui Paulo 
116d4f2939cSRui Paulo 	dbus_bus_remove_match(priv->con, wpas_dbus_noc_filter_str, NULL);
117d4f2939cSRui Paulo 	dbus_connection_remove_filter(priv->con, noc_filter, priv);
118d4f2939cSRui Paulo }
119d4f2939cSRui Paulo 
120d4f2939cSRui Paulo #endif /* CONFIG_AP */
121d4f2939cSRui Paulo 
122d4f2939cSRui Paulo 
123d4f2939cSRui Paulo /**
124d4f2939cSRui Paulo  * wpas_dbus_signal_interface - Send a interface related event signal
125d4f2939cSRui Paulo  * @wpa_s: %wpa_supplicant network interface data
126d4f2939cSRui Paulo  * @sig_name: signal name - InterfaceAdded or InterfaceRemoved
127d4f2939cSRui Paulo  * @properties: Whether to add second argument with object properties
128d4f2939cSRui Paulo  *
129d4f2939cSRui Paulo  * Notify listeners about event related with interface
130d4f2939cSRui Paulo  */
131d4f2939cSRui Paulo static void wpas_dbus_signal_interface(struct wpa_supplicant *wpa_s,
1324bc52338SCy Schubert 				       const char *sig_name,
1334bc52338SCy Schubert 				       dbus_bool_t properties)
134d4f2939cSRui Paulo {
135d4f2939cSRui Paulo 	struct wpas_dbus_priv *iface;
136d4f2939cSRui Paulo 	DBusMessage *msg;
137d4f2939cSRui Paulo 	DBusMessageIter iter;
138d4f2939cSRui Paulo 
139d4f2939cSRui Paulo 	iface = wpa_s->global->dbus;
140d4f2939cSRui Paulo 
141d4f2939cSRui Paulo 	/* Do nothing if the control interface is not turned on */
142325151a3SRui Paulo 	if (iface == NULL || !wpa_s->dbus_new_path)
143d4f2939cSRui Paulo 		return;
144d4f2939cSRui Paulo 
145d4f2939cSRui Paulo 	msg = dbus_message_new_signal(WPAS_DBUS_NEW_PATH,
146d4f2939cSRui Paulo 				      WPAS_DBUS_NEW_INTERFACE, sig_name);
147d4f2939cSRui Paulo 	if (msg == NULL)
148d4f2939cSRui Paulo 		return;
149d4f2939cSRui Paulo 
150d4f2939cSRui Paulo 	dbus_message_iter_init_append(msg, &iter);
151d4f2939cSRui Paulo 	if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_OBJECT_PATH,
1525b9c547cSRui Paulo 					    &wpa_s->dbus_new_path) ||
1535b9c547cSRui Paulo 	    (properties &&
1545b9c547cSRui Paulo 	     !wpa_dbus_get_object_properties(
155d4f2939cSRui Paulo 		     iface, wpa_s->dbus_new_path,
1565b9c547cSRui Paulo 		     WPAS_DBUS_NEW_IFACE_INTERFACE, &iter)))
157d4f2939cSRui Paulo 		wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
1585b9c547cSRui Paulo 	else
1595b9c547cSRui Paulo 		dbus_connection_send(iface->con, msg, NULL);
160d4f2939cSRui Paulo 	dbus_message_unref(msg);
161d4f2939cSRui Paulo }
162d4f2939cSRui Paulo 
163d4f2939cSRui Paulo 
164d4f2939cSRui Paulo /**
165d4f2939cSRui Paulo  * wpas_dbus_signal_interface_added - Send a interface created signal
166d4f2939cSRui Paulo  * @wpa_s: %wpa_supplicant network interface data
167d4f2939cSRui Paulo  *
168d4f2939cSRui Paulo  * Notify listeners about creating new interface
169d4f2939cSRui Paulo  */
170d4f2939cSRui Paulo static void wpas_dbus_signal_interface_added(struct wpa_supplicant *wpa_s)
171d4f2939cSRui Paulo {
172d4f2939cSRui Paulo 	wpas_dbus_signal_interface(wpa_s, "InterfaceAdded", TRUE);
173d4f2939cSRui Paulo }
174d4f2939cSRui Paulo 
175d4f2939cSRui Paulo 
176d4f2939cSRui Paulo /**
177d4f2939cSRui Paulo  * wpas_dbus_signal_interface_removed - Send a interface removed signal
178d4f2939cSRui Paulo  * @wpa_s: %wpa_supplicant network interface data
179d4f2939cSRui Paulo  *
180d4f2939cSRui Paulo  * Notify listeners about removing interface
181d4f2939cSRui Paulo  */
182d4f2939cSRui Paulo static void wpas_dbus_signal_interface_removed(struct wpa_supplicant *wpa_s)
183d4f2939cSRui Paulo {
184d4f2939cSRui Paulo 	wpas_dbus_signal_interface(wpa_s, "InterfaceRemoved", FALSE);
185d4f2939cSRui Paulo 
186d4f2939cSRui Paulo }
187d4f2939cSRui Paulo 
188d4f2939cSRui Paulo 
189d4f2939cSRui Paulo /**
190d4f2939cSRui Paulo  * wpas_dbus_signal_scan_done - send scan done signal
191d4f2939cSRui Paulo  * @wpa_s: %wpa_supplicant network interface data
192d4f2939cSRui Paulo  * @success: indicates if scanning succeed or failed
193d4f2939cSRui Paulo  *
194d4f2939cSRui Paulo  * Notify listeners about finishing a scan
195d4f2939cSRui Paulo  */
196d4f2939cSRui Paulo void wpas_dbus_signal_scan_done(struct wpa_supplicant *wpa_s, int success)
197d4f2939cSRui Paulo {
198d4f2939cSRui Paulo 	struct wpas_dbus_priv *iface;
199d4f2939cSRui Paulo 	DBusMessage *msg;
200d4f2939cSRui Paulo 	dbus_bool_t succ;
201d4f2939cSRui Paulo 
202d4f2939cSRui Paulo 	iface = wpa_s->global->dbus;
203d4f2939cSRui Paulo 
204d4f2939cSRui Paulo 	/* Do nothing if the control interface is not turned on */
205325151a3SRui Paulo 	if (iface == NULL || !wpa_s->dbus_new_path)
206d4f2939cSRui Paulo 		return;
207d4f2939cSRui Paulo 
208d4f2939cSRui Paulo 	msg = dbus_message_new_signal(wpa_s->dbus_new_path,
209d4f2939cSRui Paulo 				      WPAS_DBUS_NEW_IFACE_INTERFACE,
210d4f2939cSRui Paulo 				      "ScanDone");
211d4f2939cSRui Paulo 	if (msg == NULL)
212d4f2939cSRui Paulo 		return;
213d4f2939cSRui Paulo 
214d4f2939cSRui Paulo 	succ = success ? TRUE : FALSE;
215d4f2939cSRui Paulo 	if (dbus_message_append_args(msg, DBUS_TYPE_BOOLEAN, &succ,
216d4f2939cSRui Paulo 				     DBUS_TYPE_INVALID))
217d4f2939cSRui Paulo 		dbus_connection_send(iface->con, msg, NULL);
218d4f2939cSRui Paulo 	else
219d4f2939cSRui Paulo 		wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
220d4f2939cSRui Paulo 	dbus_message_unref(msg);
221d4f2939cSRui Paulo }
222d4f2939cSRui Paulo 
223d4f2939cSRui Paulo 
224d4f2939cSRui Paulo /**
2255b9c547cSRui Paulo  * wpas_dbus_signal_bss - Send a BSS related event signal
226d4f2939cSRui Paulo  * @wpa_s: %wpa_supplicant network interface data
227d4f2939cSRui Paulo  * @bss_obj_path: BSS object path
228d4f2939cSRui Paulo  * @sig_name: signal name - BSSAdded or BSSRemoved
229d4f2939cSRui Paulo  * @properties: Whether to add second argument with object properties
230d4f2939cSRui Paulo  *
231d4f2939cSRui Paulo  * Notify listeners about event related with BSS
232d4f2939cSRui Paulo  */
233d4f2939cSRui Paulo static void wpas_dbus_signal_bss(struct wpa_supplicant *wpa_s,
234d4f2939cSRui Paulo 				 const char *bss_obj_path,
2354bc52338SCy Schubert 				 const char *sig_name, dbus_bool_t properties)
236d4f2939cSRui Paulo {
237d4f2939cSRui Paulo 	struct wpas_dbus_priv *iface;
238d4f2939cSRui Paulo 	DBusMessage *msg;
239d4f2939cSRui Paulo 	DBusMessageIter iter;
240d4f2939cSRui Paulo 
241d4f2939cSRui Paulo 	iface = wpa_s->global->dbus;
242d4f2939cSRui Paulo 
243d4f2939cSRui Paulo 	/* Do nothing if the control interface is not turned on */
244325151a3SRui Paulo 	if (iface == NULL || !wpa_s->dbus_new_path)
245d4f2939cSRui Paulo 		return;
246d4f2939cSRui Paulo 
247d4f2939cSRui Paulo 	msg = dbus_message_new_signal(wpa_s->dbus_new_path,
248d4f2939cSRui Paulo 				      WPAS_DBUS_NEW_IFACE_INTERFACE,
249d4f2939cSRui Paulo 				      sig_name);
250d4f2939cSRui Paulo 	if (msg == NULL)
251d4f2939cSRui Paulo 		return;
252d4f2939cSRui Paulo 
253d4f2939cSRui Paulo 	dbus_message_iter_init_append(msg, &iter);
254d4f2939cSRui Paulo 	if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_OBJECT_PATH,
2555b9c547cSRui Paulo 					    &bss_obj_path) ||
2565b9c547cSRui Paulo 	    (properties &&
2575b9c547cSRui Paulo 	     !wpa_dbus_get_object_properties(iface, bss_obj_path,
258d4f2939cSRui Paulo 					     WPAS_DBUS_NEW_IFACE_BSS,
2595b9c547cSRui Paulo 					     &iter)))
260d4f2939cSRui Paulo 		wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
2615b9c547cSRui Paulo 	else
2625b9c547cSRui Paulo 		dbus_connection_send(iface->con, msg, NULL);
263d4f2939cSRui Paulo 	dbus_message_unref(msg);
264d4f2939cSRui Paulo }
265d4f2939cSRui Paulo 
266d4f2939cSRui Paulo 
267d4f2939cSRui Paulo /**
268d4f2939cSRui Paulo  * wpas_dbus_signal_bss_added - Send a BSS added signal
269d4f2939cSRui Paulo  * @wpa_s: %wpa_supplicant network interface data
270d4f2939cSRui Paulo  * @bss_obj_path: new BSS object path
271d4f2939cSRui Paulo  *
272d4f2939cSRui Paulo  * Notify listeners about adding new BSS
273d4f2939cSRui Paulo  */
274d4f2939cSRui Paulo static void wpas_dbus_signal_bss_added(struct wpa_supplicant *wpa_s,
275d4f2939cSRui Paulo 				       const char *bss_obj_path)
276d4f2939cSRui Paulo {
277d4f2939cSRui Paulo 	wpas_dbus_signal_bss(wpa_s, bss_obj_path, "BSSAdded", TRUE);
278d4f2939cSRui Paulo }
279d4f2939cSRui Paulo 
280d4f2939cSRui Paulo 
281d4f2939cSRui Paulo /**
282d4f2939cSRui Paulo  * wpas_dbus_signal_bss_removed - Send a BSS removed signal
283d4f2939cSRui Paulo  * @wpa_s: %wpa_supplicant network interface data
284d4f2939cSRui Paulo  * @bss_obj_path: BSS object path
285d4f2939cSRui Paulo  *
286d4f2939cSRui Paulo  * Notify listeners about removing BSS
287d4f2939cSRui Paulo  */
288d4f2939cSRui Paulo static void wpas_dbus_signal_bss_removed(struct wpa_supplicant *wpa_s,
289d4f2939cSRui Paulo 					 const char *bss_obj_path)
290d4f2939cSRui Paulo {
291d4f2939cSRui Paulo 	wpas_dbus_signal_bss(wpa_s, bss_obj_path, "BSSRemoved", FALSE);
292d4f2939cSRui Paulo }
293d4f2939cSRui Paulo 
294d4f2939cSRui Paulo 
295d4f2939cSRui Paulo /**
296d4f2939cSRui Paulo  * wpas_dbus_signal_blob - Send a blob related event signal
297d4f2939cSRui Paulo  * @wpa_s: %wpa_supplicant network interface data
298d4f2939cSRui Paulo  * @name: blob name
299d4f2939cSRui Paulo  * @sig_name: signal name - BlobAdded or BlobRemoved
300d4f2939cSRui Paulo  *
301d4f2939cSRui Paulo  * Notify listeners about event related with blob
302d4f2939cSRui Paulo  */
303d4f2939cSRui Paulo static void wpas_dbus_signal_blob(struct wpa_supplicant *wpa_s,
304d4f2939cSRui Paulo 				  const char *name, const char *sig_name)
305d4f2939cSRui Paulo {
306d4f2939cSRui Paulo 	struct wpas_dbus_priv *iface;
307d4f2939cSRui Paulo 	DBusMessage *msg;
308d4f2939cSRui Paulo 
309d4f2939cSRui Paulo 	iface = wpa_s->global->dbus;
310d4f2939cSRui Paulo 
311d4f2939cSRui Paulo 	/* Do nothing if the control interface is not turned on */
312325151a3SRui Paulo 	if (iface == NULL || !wpa_s->dbus_new_path)
313d4f2939cSRui Paulo 		return;
314d4f2939cSRui Paulo 
315d4f2939cSRui Paulo 	msg = dbus_message_new_signal(wpa_s->dbus_new_path,
316d4f2939cSRui Paulo 				      WPAS_DBUS_NEW_IFACE_INTERFACE,
317d4f2939cSRui Paulo 				      sig_name);
318d4f2939cSRui Paulo 	if (msg == NULL)
319d4f2939cSRui Paulo 		return;
320d4f2939cSRui Paulo 
321d4f2939cSRui Paulo 	if (dbus_message_append_args(msg, DBUS_TYPE_STRING, &name,
322d4f2939cSRui Paulo 				     DBUS_TYPE_INVALID))
323d4f2939cSRui Paulo 		dbus_connection_send(iface->con, msg, NULL);
324d4f2939cSRui Paulo 	else
325d4f2939cSRui Paulo 		wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
326d4f2939cSRui Paulo 	dbus_message_unref(msg);
327d4f2939cSRui Paulo }
328d4f2939cSRui Paulo 
329d4f2939cSRui Paulo 
330d4f2939cSRui Paulo /**
331d4f2939cSRui Paulo  * wpas_dbus_signal_blob_added - Send a blob added signal
332d4f2939cSRui Paulo  * @wpa_s: %wpa_supplicant network interface data
333d4f2939cSRui Paulo  * @name: blob name
334d4f2939cSRui Paulo  *
335d4f2939cSRui Paulo  * Notify listeners about adding a new blob
336d4f2939cSRui Paulo  */
337d4f2939cSRui Paulo void wpas_dbus_signal_blob_added(struct wpa_supplicant *wpa_s,
338d4f2939cSRui Paulo 				 const char *name)
339d4f2939cSRui Paulo {
340d4f2939cSRui Paulo 	wpas_dbus_signal_blob(wpa_s, name, "BlobAdded");
341d4f2939cSRui Paulo }
342d4f2939cSRui Paulo 
343d4f2939cSRui Paulo 
344d4f2939cSRui Paulo /**
345d4f2939cSRui Paulo  * wpas_dbus_signal_blob_removed - Send a blob removed signal
346d4f2939cSRui Paulo  * @wpa_s: %wpa_supplicant network interface data
347d4f2939cSRui Paulo  * @name: blob name
348d4f2939cSRui Paulo  *
349d4f2939cSRui Paulo  * Notify listeners about removing blob
350d4f2939cSRui Paulo  */
351d4f2939cSRui Paulo void wpas_dbus_signal_blob_removed(struct wpa_supplicant *wpa_s,
352d4f2939cSRui Paulo 				   const char *name)
353d4f2939cSRui Paulo {
354d4f2939cSRui Paulo 	wpas_dbus_signal_blob(wpa_s, name, "BlobRemoved");
355d4f2939cSRui Paulo }
356d4f2939cSRui Paulo 
357d4f2939cSRui Paulo 
358d4f2939cSRui Paulo /**
359d4f2939cSRui Paulo  * wpas_dbus_signal_network - Send a network related event signal
360d4f2939cSRui Paulo  * @wpa_s: %wpa_supplicant network interface data
361d4f2939cSRui Paulo  * @id: new network id
362d4f2939cSRui Paulo  * @sig_name: signal name - NetworkAdded, NetworkRemoved or NetworkSelected
363d4f2939cSRui Paulo  * @properties: determines if add second argument with object properties
364d4f2939cSRui Paulo  *
365d4f2939cSRui Paulo  * Notify listeners about event related with configured network
366d4f2939cSRui Paulo  */
367d4f2939cSRui Paulo static void wpas_dbus_signal_network(struct wpa_supplicant *wpa_s,
368d4f2939cSRui Paulo 				     int id, const char *sig_name,
3694bc52338SCy Schubert 				     dbus_bool_t properties)
370d4f2939cSRui Paulo {
371d4f2939cSRui Paulo 	struct wpas_dbus_priv *iface;
372d4f2939cSRui Paulo 	DBusMessage *msg;
373d4f2939cSRui Paulo 	DBusMessageIter iter;
374d4f2939cSRui Paulo 	char net_obj_path[WPAS_DBUS_OBJECT_PATH_MAX], *path;
375d4f2939cSRui Paulo 
376d4f2939cSRui Paulo 	iface = wpa_s->global->dbus;
377d4f2939cSRui Paulo 
378d4f2939cSRui Paulo 	/* Do nothing if the control interface is not turned on */
379325151a3SRui Paulo 	if (iface == NULL || !wpa_s->dbus_new_path)
380d4f2939cSRui Paulo 		return;
381d4f2939cSRui Paulo 
382d4f2939cSRui Paulo 	os_snprintf(net_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
383d4f2939cSRui Paulo 		    "%s/" WPAS_DBUS_NEW_NETWORKS_PART "/%u",
384d4f2939cSRui Paulo 		    wpa_s->dbus_new_path, id);
385d4f2939cSRui Paulo 
386d4f2939cSRui Paulo 	msg = dbus_message_new_signal(wpa_s->dbus_new_path,
387d4f2939cSRui Paulo 				      WPAS_DBUS_NEW_IFACE_INTERFACE,
388d4f2939cSRui Paulo 				      sig_name);
389d4f2939cSRui Paulo 	if (msg == NULL)
390d4f2939cSRui Paulo 		return;
391d4f2939cSRui Paulo 
392d4f2939cSRui Paulo 	dbus_message_iter_init_append(msg, &iter);
393d4f2939cSRui Paulo 	path = net_obj_path;
394d4f2939cSRui Paulo 	if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_OBJECT_PATH,
3955b9c547cSRui Paulo 					    &path) ||
3965b9c547cSRui Paulo 	    (properties &&
3975b9c547cSRui Paulo 	     !wpa_dbus_get_object_properties(
398d4f2939cSRui Paulo 		     iface, net_obj_path, WPAS_DBUS_NEW_IFACE_NETWORK,
3995b9c547cSRui Paulo 		     &iter)))
400d4f2939cSRui Paulo 		wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
4015b9c547cSRui Paulo 	else
4025b9c547cSRui Paulo 		dbus_connection_send(iface->con, msg, NULL);
403d4f2939cSRui Paulo 	dbus_message_unref(msg);
404d4f2939cSRui Paulo }
405d4f2939cSRui Paulo 
406d4f2939cSRui Paulo 
407d4f2939cSRui Paulo /**
408d4f2939cSRui Paulo  * wpas_dbus_signal_network_added - Send a network added signal
409d4f2939cSRui Paulo  * @wpa_s: %wpa_supplicant network interface data
410d4f2939cSRui Paulo  * @id: new network id
411d4f2939cSRui Paulo  *
412d4f2939cSRui Paulo  * Notify listeners about adding new network
413d4f2939cSRui Paulo  */
414d4f2939cSRui Paulo static void wpas_dbus_signal_network_added(struct wpa_supplicant *wpa_s,
415d4f2939cSRui Paulo 					   int id)
416d4f2939cSRui Paulo {
417d4f2939cSRui Paulo 	wpas_dbus_signal_network(wpa_s, id, "NetworkAdded", TRUE);
418d4f2939cSRui Paulo }
419d4f2939cSRui Paulo 
420d4f2939cSRui Paulo 
421d4f2939cSRui Paulo /**
422d4f2939cSRui Paulo  * wpas_dbus_signal_network_removed - Send a network removed signal
423d4f2939cSRui Paulo  * @wpa_s: %wpa_supplicant network interface data
424d4f2939cSRui Paulo  * @id: network id
425d4f2939cSRui Paulo  *
426d4f2939cSRui Paulo  * Notify listeners about removing a network
427d4f2939cSRui Paulo  */
428d4f2939cSRui Paulo static void wpas_dbus_signal_network_removed(struct wpa_supplicant *wpa_s,
429d4f2939cSRui Paulo 					     int id)
430d4f2939cSRui Paulo {
431d4f2939cSRui Paulo 	wpas_dbus_signal_network(wpa_s, id, "NetworkRemoved", FALSE);
432d4f2939cSRui Paulo }
433d4f2939cSRui Paulo 
434d4f2939cSRui Paulo 
435d4f2939cSRui Paulo /**
436d4f2939cSRui Paulo  * wpas_dbus_signal_network_selected - Send a network selected signal
437d4f2939cSRui Paulo  * @wpa_s: %wpa_supplicant network interface data
438d4f2939cSRui Paulo  * @id: network id
439d4f2939cSRui Paulo  *
440d4f2939cSRui Paulo  * Notify listeners about selecting a network
441d4f2939cSRui Paulo  */
442d4f2939cSRui Paulo void wpas_dbus_signal_network_selected(struct wpa_supplicant *wpa_s, int id)
443d4f2939cSRui Paulo {
444d4f2939cSRui Paulo 	wpas_dbus_signal_network(wpa_s, id, "NetworkSelected", FALSE);
445d4f2939cSRui Paulo }
446d4f2939cSRui Paulo 
447d4f2939cSRui Paulo 
448d4f2939cSRui Paulo /**
449d4f2939cSRui Paulo  * wpas_dbus_signal_network_request - Indicate that additional information
450d4f2939cSRui Paulo  * (EAP password, etc.) is required to complete the association to this SSID
451d4f2939cSRui Paulo  * @wpa_s: %wpa_supplicant network interface data
452d4f2939cSRui Paulo  * @rtype: The specific additional information required
453d4f2939cSRui Paulo  * @default_text: Optional description of required information
454d4f2939cSRui Paulo  *
455d4f2939cSRui Paulo  * Request additional information or passwords to complete an association
456d4f2939cSRui Paulo  * request.
457d4f2939cSRui Paulo  */
458d4f2939cSRui Paulo void wpas_dbus_signal_network_request(struct wpa_supplicant *wpa_s,
459d4f2939cSRui Paulo 				      struct wpa_ssid *ssid,
460d4f2939cSRui Paulo 				      enum wpa_ctrl_req_type rtype,
461d4f2939cSRui Paulo 				      const char *default_txt)
462d4f2939cSRui Paulo {
463d4f2939cSRui Paulo 	struct wpas_dbus_priv *iface;
464d4f2939cSRui Paulo 	DBusMessage *msg;
465d4f2939cSRui Paulo 	DBusMessageIter iter;
466d4f2939cSRui Paulo 	char net_obj_path[WPAS_DBUS_OBJECT_PATH_MAX];
467d4f2939cSRui Paulo 	const char *field, *txt = NULL, *net_ptr;
468d4f2939cSRui Paulo 
469d4f2939cSRui Paulo 	iface = wpa_s->global->dbus;
470d4f2939cSRui Paulo 
471d4f2939cSRui Paulo 	/* Do nothing if the control interface is not turned on */
472325151a3SRui Paulo 	if (iface == NULL || !wpa_s->dbus_new_path)
473d4f2939cSRui Paulo 		return;
474d4f2939cSRui Paulo 
475d4f2939cSRui Paulo 	field = wpa_supplicant_ctrl_req_to_string(rtype, default_txt, &txt);
476d4f2939cSRui Paulo 	if (field == NULL)
477d4f2939cSRui Paulo 		return;
478d4f2939cSRui Paulo 
479d4f2939cSRui Paulo 	msg = dbus_message_new_signal(wpa_s->dbus_new_path,
480d4f2939cSRui Paulo 				      WPAS_DBUS_NEW_IFACE_INTERFACE,
481d4f2939cSRui Paulo 				      "NetworkRequest");
482d4f2939cSRui Paulo 	if (msg == NULL)
483d4f2939cSRui Paulo 		return;
484d4f2939cSRui Paulo 
485d4f2939cSRui Paulo 	os_snprintf(net_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
486d4f2939cSRui Paulo 		    "%s/" WPAS_DBUS_NEW_NETWORKS_PART "/%u",
487d4f2939cSRui Paulo 		    wpa_s->dbus_new_path, ssid->id);
488d4f2939cSRui Paulo 	net_ptr = &net_obj_path[0];
489d4f2939cSRui Paulo 
490d4f2939cSRui Paulo 	dbus_message_iter_init_append(msg, &iter);
491d4f2939cSRui Paulo 	if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_OBJECT_PATH,
4925b9c547cSRui Paulo 					    &net_ptr) ||
4935b9c547cSRui Paulo 	    !dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &field) ||
4945b9c547cSRui Paulo 	    !dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &txt))
495d4f2939cSRui Paulo 		wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
4965b9c547cSRui Paulo 	else
4975b9c547cSRui Paulo 		dbus_connection_send(iface->con, msg, NULL);
498d4f2939cSRui Paulo 	dbus_message_unref(msg);
499d4f2939cSRui Paulo }
500d4f2939cSRui Paulo 
501d4f2939cSRui Paulo 
502d4f2939cSRui Paulo /**
503d4f2939cSRui Paulo  * wpas_dbus_signal_network_enabled_changed - Signals Enabled property changes
504d4f2939cSRui Paulo  * @wpa_s: %wpa_supplicant network interface data
505d4f2939cSRui Paulo  * @ssid: configured network which Enabled property has changed
506d4f2939cSRui Paulo  *
507d4f2939cSRui Paulo  * Sends PropertyChanged signals containing new value of Enabled property
508d4f2939cSRui Paulo  * for specified network
509d4f2939cSRui Paulo  */
510d4f2939cSRui Paulo void wpas_dbus_signal_network_enabled_changed(struct wpa_supplicant *wpa_s,
511d4f2939cSRui Paulo 					      struct wpa_ssid *ssid)
512d4f2939cSRui Paulo {
513d4f2939cSRui Paulo 
514d4f2939cSRui Paulo 	char path[WPAS_DBUS_OBJECT_PATH_MAX];
5155b9c547cSRui Paulo 
516325151a3SRui Paulo 	if (!wpa_s->dbus_new_path)
517325151a3SRui Paulo 		return;
518d4f2939cSRui Paulo 	os_snprintf(path, WPAS_DBUS_OBJECT_PATH_MAX,
519d4f2939cSRui Paulo 		    "%s/" WPAS_DBUS_NEW_NETWORKS_PART "/%d",
520d4f2939cSRui Paulo 		    wpa_s->dbus_new_path, ssid->id);
521d4f2939cSRui Paulo 
522d4f2939cSRui Paulo 	wpa_dbus_mark_property_changed(wpa_s->global->dbus, path,
523d4f2939cSRui Paulo 				       WPAS_DBUS_NEW_IFACE_NETWORK, "Enabled");
524d4f2939cSRui Paulo }
525d4f2939cSRui Paulo 
526d4f2939cSRui Paulo 
527d4f2939cSRui Paulo #ifdef CONFIG_WPS
528d4f2939cSRui Paulo 
529d4f2939cSRui Paulo /**
530325151a3SRui Paulo  * wpas_dbus_signal_wps_event_pbc_overlap - Signals PBC overlap WPS event
531325151a3SRui Paulo  * @wpa_s: %wpa_supplicant network interface data
532325151a3SRui Paulo  *
533325151a3SRui Paulo  * Sends Event dbus signal with name "pbc-overlap" and empty dict as arguments
534325151a3SRui Paulo  */
535325151a3SRui Paulo void wpas_dbus_signal_wps_event_pbc_overlap(struct wpa_supplicant *wpa_s)
536325151a3SRui Paulo {
537325151a3SRui Paulo 
538325151a3SRui Paulo 	DBusMessage *msg;
539325151a3SRui Paulo 	DBusMessageIter iter, dict_iter;
540325151a3SRui Paulo 	struct wpas_dbus_priv *iface;
541325151a3SRui Paulo 	char *key = "pbc-overlap";
542325151a3SRui Paulo 
543325151a3SRui Paulo 	iface = wpa_s->global->dbus;
544325151a3SRui Paulo 
545325151a3SRui Paulo 	/* Do nothing if the control interface is not turned on */
546325151a3SRui Paulo 	if (iface == NULL || !wpa_s->dbus_new_path)
547325151a3SRui Paulo 		return;
548325151a3SRui Paulo 
549325151a3SRui Paulo 	msg = dbus_message_new_signal(wpa_s->dbus_new_path,
550325151a3SRui Paulo 				      WPAS_DBUS_NEW_IFACE_WPS, "Event");
551325151a3SRui Paulo 	if (msg == NULL)
552325151a3SRui Paulo 		return;
553325151a3SRui Paulo 
554325151a3SRui Paulo 	dbus_message_iter_init_append(msg, &iter);
555325151a3SRui Paulo 
556325151a3SRui Paulo 	if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &key) ||
557325151a3SRui Paulo 	    !wpa_dbus_dict_open_write(&iter, &dict_iter) ||
558325151a3SRui Paulo 	    !wpa_dbus_dict_close_write(&iter, &dict_iter))
559325151a3SRui Paulo 		wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
560325151a3SRui Paulo 	else
561325151a3SRui Paulo 		dbus_connection_send(iface->con, msg, NULL);
562325151a3SRui Paulo 
563325151a3SRui Paulo 	dbus_message_unref(msg);
564325151a3SRui Paulo }
565325151a3SRui Paulo 
566325151a3SRui Paulo 
567325151a3SRui Paulo /**
568d4f2939cSRui Paulo  * wpas_dbus_signal_wps_event_success - Signals Success WPS event
569d4f2939cSRui Paulo  * @wpa_s: %wpa_supplicant network interface data
570d4f2939cSRui Paulo  *
571d4f2939cSRui Paulo  * Sends Event dbus signal with name "success" and empty dict as arguments
572d4f2939cSRui Paulo  */
573d4f2939cSRui Paulo void wpas_dbus_signal_wps_event_success(struct wpa_supplicant *wpa_s)
574d4f2939cSRui Paulo {
575d4f2939cSRui Paulo 
576d4f2939cSRui Paulo 	DBusMessage *msg;
577d4f2939cSRui Paulo 	DBusMessageIter iter, dict_iter;
578d4f2939cSRui Paulo 	struct wpas_dbus_priv *iface;
579d4f2939cSRui Paulo 	char *key = "success";
580d4f2939cSRui Paulo 
581d4f2939cSRui Paulo 	iface = wpa_s->global->dbus;
582d4f2939cSRui Paulo 
583d4f2939cSRui Paulo 	/* Do nothing if the control interface is not turned on */
584325151a3SRui Paulo 	if (iface == NULL || !wpa_s->dbus_new_path)
585d4f2939cSRui Paulo 		return;
586d4f2939cSRui Paulo 
587d4f2939cSRui Paulo 	msg = dbus_message_new_signal(wpa_s->dbus_new_path,
588d4f2939cSRui Paulo 				      WPAS_DBUS_NEW_IFACE_WPS, "Event");
589d4f2939cSRui Paulo 	if (msg == NULL)
590d4f2939cSRui Paulo 		return;
591d4f2939cSRui Paulo 
592d4f2939cSRui Paulo 	dbus_message_iter_init_append(msg, &iter);
593d4f2939cSRui Paulo 
594d4f2939cSRui Paulo 	if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &key) ||
595d4f2939cSRui Paulo 	    !wpa_dbus_dict_open_write(&iter, &dict_iter) ||
596d4f2939cSRui Paulo 	    !wpa_dbus_dict_close_write(&iter, &dict_iter))
597d4f2939cSRui Paulo 		wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
598d4f2939cSRui Paulo 	else
599d4f2939cSRui Paulo 		dbus_connection_send(iface->con, msg, NULL);
600d4f2939cSRui Paulo 
601d4f2939cSRui Paulo 	dbus_message_unref(msg);
602d4f2939cSRui Paulo }
603d4f2939cSRui Paulo 
604d4f2939cSRui Paulo 
605d4f2939cSRui Paulo /**
606d4f2939cSRui Paulo  * wpas_dbus_signal_wps_event_fail - Signals Fail WPS event
607d4f2939cSRui Paulo  * @wpa_s: %wpa_supplicant network interface data
608325151a3SRui Paulo  * @fail: WPS failure information
609d4f2939cSRui Paulo  *
610d4f2939cSRui Paulo  * Sends Event dbus signal with name "fail" and dictionary containing
611d4f2939cSRui Paulo  * "msg field with fail message number (int32) as arguments
612d4f2939cSRui Paulo  */
613d4f2939cSRui Paulo void wpas_dbus_signal_wps_event_fail(struct wpa_supplicant *wpa_s,
614d4f2939cSRui Paulo 				     struct wps_event_fail *fail)
615d4f2939cSRui Paulo {
616d4f2939cSRui Paulo 
617d4f2939cSRui Paulo 	DBusMessage *msg;
618d4f2939cSRui Paulo 	DBusMessageIter iter, dict_iter;
619d4f2939cSRui Paulo 	struct wpas_dbus_priv *iface;
620d4f2939cSRui Paulo 	char *key = "fail";
621d4f2939cSRui Paulo 
622d4f2939cSRui Paulo 	iface = wpa_s->global->dbus;
623d4f2939cSRui Paulo 
624d4f2939cSRui Paulo 	/* Do nothing if the control interface is not turned on */
625325151a3SRui Paulo 	if (iface == NULL || !wpa_s->dbus_new_path)
626d4f2939cSRui Paulo 		return;
627d4f2939cSRui Paulo 
628d4f2939cSRui Paulo 	msg = dbus_message_new_signal(wpa_s->dbus_new_path,
629d4f2939cSRui Paulo 				      WPAS_DBUS_NEW_IFACE_WPS, "Event");
630d4f2939cSRui Paulo 	if (msg == NULL)
631d4f2939cSRui Paulo 		return;
632d4f2939cSRui Paulo 
633d4f2939cSRui Paulo 	dbus_message_iter_init_append(msg, &iter);
634d4f2939cSRui Paulo 
635d4f2939cSRui Paulo 	if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &key) ||
636d4f2939cSRui Paulo 	    !wpa_dbus_dict_open_write(&iter, &dict_iter) ||
637d4f2939cSRui Paulo 	    !wpa_dbus_dict_append_int32(&dict_iter, "msg", fail->msg) ||
638325151a3SRui Paulo 	    !wpa_dbus_dict_append_int32(&dict_iter, "config_error",
639325151a3SRui Paulo 					fail->config_error) ||
640325151a3SRui Paulo 	    !wpa_dbus_dict_append_int32(&dict_iter, "error_indication",
641325151a3SRui Paulo 					fail->error_indication) ||
642d4f2939cSRui Paulo 	    !wpa_dbus_dict_close_write(&iter, &dict_iter))
643d4f2939cSRui Paulo 		wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
644d4f2939cSRui Paulo 	else
645d4f2939cSRui Paulo 		dbus_connection_send(iface->con, msg, NULL);
646d4f2939cSRui Paulo 
647d4f2939cSRui Paulo 	dbus_message_unref(msg);
648d4f2939cSRui Paulo }
649d4f2939cSRui Paulo 
650d4f2939cSRui Paulo 
651d4f2939cSRui Paulo /**
652d4f2939cSRui Paulo  * wpas_dbus_signal_wps_event_m2d - Signals M2D WPS event
653d4f2939cSRui Paulo  * @wpa_s: %wpa_supplicant network interface data
654325151a3SRui Paulo  * @m2d: M2D event data information
655d4f2939cSRui Paulo  *
656d4f2939cSRui Paulo  * Sends Event dbus signal with name "m2d" and dictionary containing
657d4f2939cSRui Paulo  * fields of wps_event_m2d structure.
658d4f2939cSRui Paulo  */
659d4f2939cSRui Paulo void wpas_dbus_signal_wps_event_m2d(struct wpa_supplicant *wpa_s,
660d4f2939cSRui Paulo 				    struct wps_event_m2d *m2d)
661d4f2939cSRui Paulo {
662d4f2939cSRui Paulo 
663d4f2939cSRui Paulo 	DBusMessage *msg;
664d4f2939cSRui Paulo 	DBusMessageIter iter, dict_iter;
665d4f2939cSRui Paulo 	struct wpas_dbus_priv *iface;
666d4f2939cSRui Paulo 	char *key = "m2d";
667d4f2939cSRui Paulo 
668d4f2939cSRui Paulo 	iface = wpa_s->global->dbus;
669d4f2939cSRui Paulo 
670d4f2939cSRui Paulo 	/* Do nothing if the control interface is not turned on */
671325151a3SRui Paulo 	if (iface == NULL || !wpa_s->dbus_new_path)
672d4f2939cSRui Paulo 		return;
673d4f2939cSRui Paulo 
674d4f2939cSRui Paulo 	msg = dbus_message_new_signal(wpa_s->dbus_new_path,
675d4f2939cSRui Paulo 				      WPAS_DBUS_NEW_IFACE_WPS, "Event");
676d4f2939cSRui Paulo 	if (msg == NULL)
677d4f2939cSRui Paulo 		return;
678d4f2939cSRui Paulo 
679d4f2939cSRui Paulo 	dbus_message_iter_init_append(msg, &iter);
680d4f2939cSRui Paulo 
681d4f2939cSRui Paulo 	if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &key) ||
682d4f2939cSRui Paulo 	    !wpa_dbus_dict_open_write(&iter, &dict_iter) ||
683d4f2939cSRui Paulo 	    !wpa_dbus_dict_append_uint16(&dict_iter, "config_methods",
684d4f2939cSRui Paulo 					 m2d->config_methods) ||
685d4f2939cSRui Paulo 	    !wpa_dbus_dict_append_byte_array(&dict_iter, "manufacturer",
686d4f2939cSRui Paulo 					     (const char *) m2d->manufacturer,
687d4f2939cSRui Paulo 					     m2d->manufacturer_len) ||
688d4f2939cSRui Paulo 	    !wpa_dbus_dict_append_byte_array(&dict_iter, "model_name",
689d4f2939cSRui Paulo 					     (const char *) m2d->model_name,
690d4f2939cSRui Paulo 					     m2d->model_name_len) ||
691d4f2939cSRui Paulo 	    !wpa_dbus_dict_append_byte_array(&dict_iter, "model_number",
692d4f2939cSRui Paulo 					     (const char *) m2d->model_number,
693d4f2939cSRui Paulo 					     m2d->model_number_len) ||
694d4f2939cSRui Paulo 	    !wpa_dbus_dict_append_byte_array(&dict_iter, "serial_number",
695d4f2939cSRui Paulo 					     (const char *)
696d4f2939cSRui Paulo 					     m2d->serial_number,
697d4f2939cSRui Paulo 					     m2d->serial_number_len) ||
698d4f2939cSRui Paulo 	    !wpa_dbus_dict_append_byte_array(&dict_iter, "dev_name",
699d4f2939cSRui Paulo 					     (const char *) m2d->dev_name,
700d4f2939cSRui Paulo 					     m2d->dev_name_len) ||
701d4f2939cSRui Paulo 	    !wpa_dbus_dict_append_byte_array(&dict_iter, "primary_dev_type",
702d4f2939cSRui Paulo 					     (const char *)
703d4f2939cSRui Paulo 					     m2d->primary_dev_type, 8) ||
704d4f2939cSRui Paulo 	    !wpa_dbus_dict_append_uint16(&dict_iter, "config_error",
705d4f2939cSRui Paulo 					 m2d->config_error) ||
706d4f2939cSRui Paulo 	    !wpa_dbus_dict_append_uint16(&dict_iter, "dev_password_id",
707d4f2939cSRui Paulo 					 m2d->dev_password_id) ||
708d4f2939cSRui Paulo 	    !wpa_dbus_dict_close_write(&iter, &dict_iter))
709d4f2939cSRui Paulo 		wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
710d4f2939cSRui Paulo 	else
711d4f2939cSRui Paulo 		dbus_connection_send(iface->con, msg, NULL);
712d4f2939cSRui Paulo 
713d4f2939cSRui Paulo 	dbus_message_unref(msg);
714d4f2939cSRui Paulo }
715d4f2939cSRui Paulo 
716d4f2939cSRui Paulo 
717d4f2939cSRui Paulo /**
718d4f2939cSRui Paulo  * wpas_dbus_signal_wps_cred - Signals new credentials
719d4f2939cSRui Paulo  * @wpa_s: %wpa_supplicant network interface data
720325151a3SRui Paulo  * @cred: WPS Credential information
721d4f2939cSRui Paulo  *
722d4f2939cSRui Paulo  * Sends signal with credentials in directory argument
723d4f2939cSRui Paulo  */
724d4f2939cSRui Paulo void wpas_dbus_signal_wps_cred(struct wpa_supplicant *wpa_s,
725d4f2939cSRui Paulo 			       const struct wps_credential *cred)
726d4f2939cSRui Paulo {
727d4f2939cSRui Paulo 	DBusMessage *msg;
728d4f2939cSRui Paulo 	DBusMessageIter iter, dict_iter;
729d4f2939cSRui Paulo 	struct wpas_dbus_priv *iface;
7305b9c547cSRui Paulo 	char *auth_type[5]; /* we have five possible authentication types */
731d4f2939cSRui Paulo 	int at_num = 0;
7325b9c547cSRui Paulo 	char *encr_type[3]; /* we have three possible encryption types */
733d4f2939cSRui Paulo 	int et_num = 0;
734d4f2939cSRui Paulo 
735d4f2939cSRui Paulo 	iface = wpa_s->global->dbus;
736d4f2939cSRui Paulo 
737d4f2939cSRui Paulo 	/* Do nothing if the control interface is not turned on */
738325151a3SRui Paulo 	if (iface == NULL || !wpa_s->dbus_new_path)
739d4f2939cSRui Paulo 		return;
740d4f2939cSRui Paulo 
741d4f2939cSRui Paulo 	msg = dbus_message_new_signal(wpa_s->dbus_new_path,
742d4f2939cSRui Paulo 				      WPAS_DBUS_NEW_IFACE_WPS,
743d4f2939cSRui Paulo 				      "Credentials");
744d4f2939cSRui Paulo 	if (msg == NULL)
745d4f2939cSRui Paulo 		return;
746d4f2939cSRui Paulo 
747d4f2939cSRui Paulo 	dbus_message_iter_init_append(msg, &iter);
748d4f2939cSRui Paulo 	if (!wpa_dbus_dict_open_write(&iter, &dict_iter))
749d4f2939cSRui Paulo 		goto nomem;
750d4f2939cSRui Paulo 
751d4f2939cSRui Paulo 	if (cred->auth_type & WPS_AUTH_OPEN)
752d4f2939cSRui Paulo 		auth_type[at_num++] = "open";
753*c1d255d3SCy Schubert #ifndef CONFIG_NO_TKIP
754d4f2939cSRui Paulo 	if (cred->auth_type & WPS_AUTH_WPAPSK)
755d4f2939cSRui Paulo 		auth_type[at_num++] = "wpa-psk";
756d4f2939cSRui Paulo 	if (cred->auth_type & WPS_AUTH_WPA)
757d4f2939cSRui Paulo 		auth_type[at_num++] = "wpa-eap";
758*c1d255d3SCy Schubert #endif /* CONFIG_NO_TKIP */
759d4f2939cSRui Paulo 	if (cred->auth_type & WPS_AUTH_WPA2)
760d4f2939cSRui Paulo 		auth_type[at_num++] = "wpa2-eap";
761d4f2939cSRui Paulo 	if (cred->auth_type & WPS_AUTH_WPA2PSK)
7625b9c547cSRui Paulo 		auth_type[at_num++] = "wpa2-psk";
763d4f2939cSRui Paulo 
764d4f2939cSRui Paulo 	if (cred->encr_type & WPS_ENCR_NONE)
765d4f2939cSRui Paulo 		encr_type[et_num++] = "none";
766*c1d255d3SCy Schubert #ifndef CONFIG_NO_TKIP
767d4f2939cSRui Paulo 	if (cred->encr_type & WPS_ENCR_TKIP)
768d4f2939cSRui Paulo 		encr_type[et_num++] = "tkip";
769*c1d255d3SCy Schubert #endif /* CONFIG_NO_TKIP */
770d4f2939cSRui Paulo 	if (cred->encr_type & WPS_ENCR_AES)
771d4f2939cSRui Paulo 		encr_type[et_num++] = "aes";
772d4f2939cSRui Paulo 
7735b9c547cSRui Paulo 	if ((wpa_s->current_ssid &&
7745b9c547cSRui Paulo 	     !wpa_dbus_dict_append_byte_array(
775d4f2939cSRui Paulo 		     &dict_iter, "BSSID",
7765b9c547cSRui Paulo 		     (const char *) wpa_s->current_ssid->bssid, ETH_ALEN)) ||
7775b9c547cSRui Paulo 	    !wpa_dbus_dict_append_byte_array(&dict_iter, "SSID",
778d4f2939cSRui Paulo 					     (const char *) cred->ssid,
779d4f2939cSRui Paulo 					     cred->ssid_len) ||
780d4f2939cSRui Paulo 	    !wpa_dbus_dict_append_string_array(&dict_iter, "AuthType",
781d4f2939cSRui Paulo 					       (const char **) auth_type,
782d4f2939cSRui Paulo 					       at_num) ||
783d4f2939cSRui Paulo 	    !wpa_dbus_dict_append_string_array(&dict_iter, "EncrType",
784d4f2939cSRui Paulo 					       (const char **) encr_type,
785d4f2939cSRui Paulo 					       et_num) ||
786d4f2939cSRui Paulo 	    !wpa_dbus_dict_append_byte_array(&dict_iter, "Key",
787d4f2939cSRui Paulo 					     (const char *) cred->key,
788d4f2939cSRui Paulo 					     cred->key_len) ||
789d4f2939cSRui Paulo 	    !wpa_dbus_dict_append_uint32(&dict_iter, "KeyIndex",
790d4f2939cSRui Paulo 					 cred->key_idx) ||
791d4f2939cSRui Paulo 	    !wpa_dbus_dict_close_write(&iter, &dict_iter))
792d4f2939cSRui Paulo 		goto nomem;
793d4f2939cSRui Paulo 
794d4f2939cSRui Paulo 	dbus_connection_send(iface->con, msg, NULL);
795d4f2939cSRui Paulo 
796d4f2939cSRui Paulo nomem:
797d4f2939cSRui Paulo 	dbus_message_unref(msg);
798d4f2939cSRui Paulo }
799d4f2939cSRui Paulo 
800d4f2939cSRui Paulo #endif /* CONFIG_WPS */
801d4f2939cSRui Paulo 
80285732ac8SCy Schubert 
80385732ac8SCy Schubert #ifdef CONFIG_MESH
80485732ac8SCy Schubert 
80585732ac8SCy Schubert void wpas_dbus_signal_mesh_group_started(struct wpa_supplicant *wpa_s,
80685732ac8SCy Schubert 					 struct wpa_ssid *ssid)
80785732ac8SCy Schubert {
80885732ac8SCy Schubert 	struct wpas_dbus_priv *iface;
80985732ac8SCy Schubert 	DBusMessage *msg;
81085732ac8SCy Schubert 	DBusMessageIter iter, dict_iter;
81185732ac8SCy Schubert 
81285732ac8SCy Schubert 	iface = wpa_s->global->dbus;
81385732ac8SCy Schubert 
81485732ac8SCy Schubert 	/* Do nothing if the control interface is not turned on */
81585732ac8SCy Schubert 	if (!iface || !wpa_s->dbus_new_path)
81685732ac8SCy Schubert 		return;
81785732ac8SCy Schubert 
81885732ac8SCy Schubert 	msg = dbus_message_new_signal(wpa_s->dbus_new_path,
81985732ac8SCy Schubert 				      WPAS_DBUS_NEW_IFACE_MESH,
82085732ac8SCy Schubert 				      "MeshGroupStarted");
82185732ac8SCy Schubert 	if (!msg)
82285732ac8SCy Schubert 		return;
82385732ac8SCy Schubert 
82485732ac8SCy Schubert 	dbus_message_iter_init_append(msg, &iter);
82585732ac8SCy Schubert 	if (!wpa_dbus_dict_open_write(&iter, &dict_iter) ||
82685732ac8SCy Schubert 	    !wpa_dbus_dict_append_byte_array(&dict_iter, "SSID",
82785732ac8SCy Schubert 					     (const char *) ssid->ssid,
82885732ac8SCy Schubert 					     ssid->ssid_len) ||
82985732ac8SCy Schubert 	    !wpa_dbus_dict_close_write(&iter, &dict_iter))
83085732ac8SCy Schubert 		wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
83185732ac8SCy Schubert 	else
83285732ac8SCy Schubert 		dbus_connection_send(iface->con, msg, NULL);
83385732ac8SCy Schubert 	dbus_message_unref(msg);
83485732ac8SCy Schubert }
83585732ac8SCy Schubert 
83685732ac8SCy Schubert 
83785732ac8SCy Schubert void wpas_dbus_signal_mesh_group_removed(struct wpa_supplicant *wpa_s,
83885732ac8SCy Schubert 					 const u8 *meshid, u8 meshid_len,
83985732ac8SCy Schubert 					 int reason)
84085732ac8SCy Schubert {
84185732ac8SCy Schubert 	struct wpas_dbus_priv *iface;
84285732ac8SCy Schubert 	DBusMessage *msg;
84385732ac8SCy Schubert 	DBusMessageIter iter, dict_iter;
84485732ac8SCy Schubert 
84585732ac8SCy Schubert 	iface = wpa_s->global->dbus;
84685732ac8SCy Schubert 
84785732ac8SCy Schubert 	/* Do nothing if the control interface is not turned on */
84885732ac8SCy Schubert 	if (!iface || !wpa_s->dbus_new_path)
84985732ac8SCy Schubert 		return;
85085732ac8SCy Schubert 
85185732ac8SCy Schubert 	msg = dbus_message_new_signal(wpa_s->dbus_new_path,
85285732ac8SCy Schubert 				      WPAS_DBUS_NEW_IFACE_MESH,
85385732ac8SCy Schubert 				      "MeshGroupRemoved");
85485732ac8SCy Schubert 	if (!msg)
85585732ac8SCy Schubert 		return;
85685732ac8SCy Schubert 
85785732ac8SCy Schubert 	dbus_message_iter_init_append(msg, &iter);
85885732ac8SCy Schubert 	if (!wpa_dbus_dict_open_write(&iter, &dict_iter) ||
85985732ac8SCy Schubert 	    !wpa_dbus_dict_append_byte_array(&dict_iter, "SSID",
86085732ac8SCy Schubert 					     (const char *) meshid,
86185732ac8SCy Schubert 					     meshid_len) ||
86285732ac8SCy Schubert 	    !wpa_dbus_dict_append_int32(&dict_iter, "DisconnectReason",
86385732ac8SCy Schubert 					reason) ||
86485732ac8SCy Schubert 	    !wpa_dbus_dict_close_write(&iter, &dict_iter))
86585732ac8SCy Schubert 		wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
86685732ac8SCy Schubert 	else
86785732ac8SCy Schubert 		dbus_connection_send(iface->con, msg, NULL);
86885732ac8SCy Schubert 	dbus_message_unref(msg);
86985732ac8SCy Schubert }
87085732ac8SCy Schubert 
87185732ac8SCy Schubert 
87285732ac8SCy Schubert void wpas_dbus_signal_mesh_peer_connected(struct wpa_supplicant *wpa_s,
87385732ac8SCy Schubert 					  const u8 *peer_addr)
87485732ac8SCy Schubert {
87585732ac8SCy Schubert 	struct wpas_dbus_priv *iface;
87685732ac8SCy Schubert 	DBusMessage *msg;
87785732ac8SCy Schubert 	DBusMessageIter iter, dict_iter;
87885732ac8SCy Schubert 
87985732ac8SCy Schubert 	iface = wpa_s->global->dbus;
88085732ac8SCy Schubert 
88185732ac8SCy Schubert 	/* Do nothing if the control interface is not turned on */
88285732ac8SCy Schubert 	if (!iface || !wpa_s->dbus_new_path)
88385732ac8SCy Schubert 		return;
88485732ac8SCy Schubert 
88585732ac8SCy Schubert 	msg = dbus_message_new_signal(wpa_s->dbus_new_path,
88685732ac8SCy Schubert 				      WPAS_DBUS_NEW_IFACE_MESH,
88785732ac8SCy Schubert 				      "MeshPeerConnected");
88885732ac8SCy Schubert 	if (!msg)
88985732ac8SCy Schubert 		return;
89085732ac8SCy Schubert 
89185732ac8SCy Schubert 	dbus_message_iter_init_append(msg, &iter);
89285732ac8SCy Schubert 	if (!wpa_dbus_dict_open_write(&iter, &dict_iter) ||
89385732ac8SCy Schubert 	    !wpa_dbus_dict_append_byte_array(&dict_iter, "PeerAddress",
89485732ac8SCy Schubert 					     (const char *) peer_addr,
89585732ac8SCy Schubert 					     ETH_ALEN) ||
89685732ac8SCy Schubert 	    !wpa_dbus_dict_close_write(&iter, &dict_iter))
89785732ac8SCy Schubert 		wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
89885732ac8SCy Schubert 	else
89985732ac8SCy Schubert 		dbus_connection_send(iface->con, msg, NULL);
90085732ac8SCy Schubert 	dbus_message_unref(msg);
90185732ac8SCy Schubert }
90285732ac8SCy Schubert 
90385732ac8SCy Schubert 
90485732ac8SCy Schubert void wpas_dbus_signal_mesh_peer_disconnected(struct wpa_supplicant *wpa_s,
90585732ac8SCy Schubert 					     const u8 *peer_addr, int reason)
90685732ac8SCy Schubert {
90785732ac8SCy Schubert 	struct wpas_dbus_priv *iface;
90885732ac8SCy Schubert 	DBusMessage *msg;
90985732ac8SCy Schubert 	DBusMessageIter iter, dict_iter;
91085732ac8SCy Schubert 
91185732ac8SCy Schubert 	iface = wpa_s->global->dbus;
91285732ac8SCy Schubert 
91385732ac8SCy Schubert 	/* Do nothing if the control interface is not turned on */
91485732ac8SCy Schubert 	if (!iface || !wpa_s->dbus_new_path)
91585732ac8SCy Schubert 		return;
91685732ac8SCy Schubert 
91785732ac8SCy Schubert 	msg = dbus_message_new_signal(wpa_s->dbus_new_path,
91885732ac8SCy Schubert 				      WPAS_DBUS_NEW_IFACE_MESH,
91985732ac8SCy Schubert 				      "MeshPeerDisconnected");
92085732ac8SCy Schubert 	if (!msg)
92185732ac8SCy Schubert 		return;
92285732ac8SCy Schubert 
92385732ac8SCy Schubert 	dbus_message_iter_init_append(msg, &iter);
92485732ac8SCy Schubert 	if (!wpa_dbus_dict_open_write(&iter, &dict_iter) ||
92585732ac8SCy Schubert 	    !wpa_dbus_dict_append_byte_array(&dict_iter, "PeerAddress",
92685732ac8SCy Schubert 					     (const char *) peer_addr,
92785732ac8SCy Schubert 					     ETH_ALEN) ||
92885732ac8SCy Schubert 	    !wpa_dbus_dict_append_int32(&dict_iter, "DisconnectReason",
92985732ac8SCy Schubert 					reason) ||
93085732ac8SCy Schubert 	    !wpa_dbus_dict_close_write(&iter, &dict_iter))
93185732ac8SCy Schubert 		wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
93285732ac8SCy Schubert 	else
93385732ac8SCy Schubert 		dbus_connection_send(iface->con, msg, NULL);
93485732ac8SCy Schubert 	dbus_message_unref(msg);
93585732ac8SCy Schubert }
93685732ac8SCy Schubert 
93785732ac8SCy Schubert #endif /* CONFIG_MESH */
93885732ac8SCy Schubert 
93985732ac8SCy Schubert 
940d4f2939cSRui Paulo void wpas_dbus_signal_certification(struct wpa_supplicant *wpa_s,
941d4f2939cSRui Paulo 				    int depth, const char *subject,
9425b9c547cSRui Paulo 				    const char *altsubject[],
9435b9c547cSRui Paulo 				    int num_altsubject,
944d4f2939cSRui Paulo 				    const char *cert_hash,
945d4f2939cSRui Paulo 				    const struct wpabuf *cert)
946d4f2939cSRui Paulo {
947d4f2939cSRui Paulo 	struct wpas_dbus_priv *iface;
948d4f2939cSRui Paulo 	DBusMessage *msg;
949d4f2939cSRui Paulo 	DBusMessageIter iter, dict_iter;
950d4f2939cSRui Paulo 
951d4f2939cSRui Paulo 	iface = wpa_s->global->dbus;
952d4f2939cSRui Paulo 
953d4f2939cSRui Paulo 	/* Do nothing if the control interface is not turned on */
954325151a3SRui Paulo 	if (iface == NULL || !wpa_s->dbus_new_path)
955d4f2939cSRui Paulo 		return;
956d4f2939cSRui Paulo 
957d4f2939cSRui Paulo 	msg = dbus_message_new_signal(wpa_s->dbus_new_path,
958d4f2939cSRui Paulo 				      WPAS_DBUS_NEW_IFACE_INTERFACE,
959d4f2939cSRui Paulo 				      "Certification");
960d4f2939cSRui Paulo 	if (msg == NULL)
961d4f2939cSRui Paulo 		return;
962d4f2939cSRui Paulo 
963d4f2939cSRui Paulo 	dbus_message_iter_init_append(msg, &iter);
9645b9c547cSRui Paulo 	if (!wpa_dbus_dict_open_write(&iter, &dict_iter) ||
9655b9c547cSRui Paulo 	    !wpa_dbus_dict_append_uint32(&dict_iter, "depth", depth) ||
9665b9c547cSRui Paulo 	    !wpa_dbus_dict_append_string(&dict_iter, "subject", subject) ||
9675b9c547cSRui Paulo 	    (altsubject && num_altsubject &&
9685b9c547cSRui Paulo 	     !wpa_dbus_dict_append_string_array(&dict_iter, "altsubject",
9695b9c547cSRui Paulo 						altsubject, num_altsubject)) ||
9705b9c547cSRui Paulo 	    (cert_hash &&
9715b9c547cSRui Paulo 	     !wpa_dbus_dict_append_string(&dict_iter, "cert_hash",
9725b9c547cSRui Paulo 					  cert_hash)) ||
9735b9c547cSRui Paulo 	    (cert &&
974d4f2939cSRui Paulo 	     !wpa_dbus_dict_append_byte_array(&dict_iter, "cert",
975d4f2939cSRui Paulo 					      wpabuf_head(cert),
9765b9c547cSRui Paulo 					      wpabuf_len(cert))) ||
9775b9c547cSRui Paulo 	    !wpa_dbus_dict_close_write(&iter, &dict_iter))
9785b9c547cSRui Paulo 		wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
9795b9c547cSRui Paulo 	else
980d4f2939cSRui Paulo 		dbus_connection_send(iface->con, msg, NULL);
981d4f2939cSRui Paulo 	dbus_message_unref(msg);
982d4f2939cSRui Paulo }
983d4f2939cSRui Paulo 
984d4f2939cSRui Paulo 
985d4f2939cSRui Paulo void wpas_dbus_signal_eap_status(struct wpa_supplicant *wpa_s,
986d4f2939cSRui Paulo 				 const char *status, const char *parameter)
987d4f2939cSRui Paulo {
988d4f2939cSRui Paulo 	struct wpas_dbus_priv *iface;
989d4f2939cSRui Paulo 	DBusMessage *msg;
990d4f2939cSRui Paulo 	DBusMessageIter iter;
991d4f2939cSRui Paulo 
992d4f2939cSRui Paulo 	iface = wpa_s->global->dbus;
993d4f2939cSRui Paulo 
994d4f2939cSRui Paulo 	/* Do nothing if the control interface is not turned on */
995325151a3SRui Paulo 	if (iface == NULL || !wpa_s->dbus_new_path)
996d4f2939cSRui Paulo 		return;
997d4f2939cSRui Paulo 
998d4f2939cSRui Paulo 	msg = dbus_message_new_signal(wpa_s->dbus_new_path,
999d4f2939cSRui Paulo 				      WPAS_DBUS_NEW_IFACE_INTERFACE,
1000d4f2939cSRui Paulo 				      "EAP");
1001d4f2939cSRui Paulo 	if (msg == NULL)
1002d4f2939cSRui Paulo 		return;
1003d4f2939cSRui Paulo 
1004d4f2939cSRui Paulo 	dbus_message_iter_init_append(msg, &iter);
1005d4f2939cSRui Paulo 
10065b9c547cSRui Paulo 	if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &status) ||
1007d4f2939cSRui Paulo 	    !dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING,
1008d4f2939cSRui Paulo 					    &parameter))
10095b9c547cSRui Paulo 		wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
10105b9c547cSRui Paulo 	else
1011d4f2939cSRui Paulo 		dbus_connection_send(iface->con, msg, NULL);
1012d4f2939cSRui Paulo 	dbus_message_unref(msg);
1013d4f2939cSRui Paulo }
1014d4f2939cSRui Paulo 
1015d4f2939cSRui Paulo 
10165b9c547cSRui Paulo /**
10175b9c547cSRui Paulo  * wpas_dbus_signal_sta - Send a station related event signal
10185b9c547cSRui Paulo  * @wpa_s: %wpa_supplicant network interface data
10195b9c547cSRui Paulo  * @sta: station mac address
10205b9c547cSRui Paulo  * @sig_name: signal name - StaAuthorized or StaDeauthorized
10215b9c547cSRui Paulo  *
10225b9c547cSRui Paulo  * Notify listeners about event related with station
10235b9c547cSRui Paulo  */
10245b9c547cSRui Paulo static void wpas_dbus_signal_sta(struct wpa_supplicant *wpa_s,
10255b9c547cSRui Paulo 				 const u8 *sta, const char *sig_name)
10265b9c547cSRui Paulo {
10275b9c547cSRui Paulo 	struct wpas_dbus_priv *iface;
10285b9c547cSRui Paulo 	DBusMessage *msg;
10295b9c547cSRui Paulo 	char sta_mac[WPAS_DBUS_OBJECT_PATH_MAX];
10305b9c547cSRui Paulo 	char *dev_mac;
10315b9c547cSRui Paulo 
10325b9c547cSRui Paulo 	os_snprintf(sta_mac, WPAS_DBUS_OBJECT_PATH_MAX, MACSTR, MAC2STR(sta));
10335b9c547cSRui Paulo 	dev_mac = sta_mac;
10345b9c547cSRui Paulo 
10355b9c547cSRui Paulo 	iface = wpa_s->global->dbus;
10365b9c547cSRui Paulo 
10375b9c547cSRui Paulo 	/* Do nothing if the control interface is not turned on */
1038325151a3SRui Paulo 	if (iface == NULL || !wpa_s->dbus_new_path)
10395b9c547cSRui Paulo 		return;
10405b9c547cSRui Paulo 
10415b9c547cSRui Paulo 	msg = dbus_message_new_signal(wpa_s->dbus_new_path,
10425b9c547cSRui Paulo 				      WPAS_DBUS_NEW_IFACE_INTERFACE, sig_name);
10435b9c547cSRui Paulo 	if (msg == NULL)
10445b9c547cSRui Paulo 		return;
10455b9c547cSRui Paulo 
10465b9c547cSRui Paulo 	if (dbus_message_append_args(msg, DBUS_TYPE_STRING, &dev_mac,
10475b9c547cSRui Paulo 				     DBUS_TYPE_INVALID))
10485b9c547cSRui Paulo 		dbus_connection_send(iface->con, msg, NULL);
10495b9c547cSRui Paulo 	else
10505b9c547cSRui Paulo 		wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
10515b9c547cSRui Paulo 	dbus_message_unref(msg);
10525b9c547cSRui Paulo 
10535b9c547cSRui Paulo 	wpa_printf(MSG_DEBUG, "dbus: Station MAC address '%s' '%s'",
10545b9c547cSRui Paulo 		   sta_mac, sig_name);
10555b9c547cSRui Paulo }
10565b9c547cSRui Paulo 
10575b9c547cSRui Paulo 
10585b9c547cSRui Paulo /**
10595b9c547cSRui Paulo  * wpas_dbus_signal_sta_authorized - Send a STA authorized signal
10605b9c547cSRui Paulo  * @wpa_s: %wpa_supplicant network interface data
10615b9c547cSRui Paulo  * @sta: station mac address
10625b9c547cSRui Paulo  *
10635b9c547cSRui Paulo  * Notify listeners a new station has been authorized
10645b9c547cSRui Paulo  */
10655b9c547cSRui Paulo void wpas_dbus_signal_sta_authorized(struct wpa_supplicant *wpa_s,
10665b9c547cSRui Paulo 				     const u8 *sta)
10675b9c547cSRui Paulo {
10685b9c547cSRui Paulo 	wpas_dbus_signal_sta(wpa_s, sta, "StaAuthorized");
10695b9c547cSRui Paulo }
10705b9c547cSRui Paulo 
10715b9c547cSRui Paulo 
10725b9c547cSRui Paulo /**
10735b9c547cSRui Paulo  * wpas_dbus_signal_sta_deauthorized - Send a STA deauthorized signal
10745b9c547cSRui Paulo  * @wpa_s: %wpa_supplicant network interface data
10755b9c547cSRui Paulo  * @sta: station mac address
10765b9c547cSRui Paulo  *
10775b9c547cSRui Paulo  * Notify listeners a station has been deauthorized
10785b9c547cSRui Paulo  */
10795b9c547cSRui Paulo void wpas_dbus_signal_sta_deauthorized(struct wpa_supplicant *wpa_s,
10805b9c547cSRui Paulo 				       const u8 *sta)
10815b9c547cSRui Paulo {
10825b9c547cSRui Paulo 	wpas_dbus_signal_sta(wpa_s, sta, "StaDeauthorized");
10835b9c547cSRui Paulo }
10845b9c547cSRui Paulo 
10855b9c547cSRui Paulo 
10864bc52338SCy Schubert /**
10874bc52338SCy Schubert  * wpas_dbus_signal_station - Send an event signal related to a station object
10884bc52338SCy Schubert  * @wpa_s: %wpa_supplicant network interface data
10894bc52338SCy Schubert  * @station_obj_path: Station object path
10904bc52338SCy Schubert  * @sig_name: signal name - StationAdded or StationRemoved
10914bc52338SCy Schubert  * @properties: Whether to add second argument with object properties
10924bc52338SCy Schubert  *
10934bc52338SCy Schubert  * Notify listeners about event related with station.
10944bc52338SCy Schubert  */
10954bc52338SCy Schubert static void wpas_dbus_signal_station(struct wpa_supplicant *wpa_s,
10964bc52338SCy Schubert 				     const char *station_obj_path,
10974bc52338SCy Schubert 				     const char *sig_name,
10984bc52338SCy Schubert 				     dbus_bool_t properties)
10994bc52338SCy Schubert {
11004bc52338SCy Schubert 	struct wpas_dbus_priv *iface;
11014bc52338SCy Schubert 	DBusMessage *msg;
11024bc52338SCy Schubert 	DBusMessageIter iter;
11034bc52338SCy Schubert 
11044bc52338SCy Schubert 	iface = wpa_s->global->dbus;
11054bc52338SCy Schubert 
11064bc52338SCy Schubert 	/* Do nothing if the control interface is not turned on */
11074bc52338SCy Schubert 	if (!iface || !wpa_s->dbus_new_path)
11084bc52338SCy Schubert 		return;
11094bc52338SCy Schubert 
11104bc52338SCy Schubert 	wpa_printf(MSG_DEBUG, "dbus: STA signal %s", sig_name);
11114bc52338SCy Schubert 	msg = dbus_message_new_signal(wpa_s->dbus_new_path,
11124bc52338SCy Schubert 				      WPAS_DBUS_NEW_IFACE_INTERFACE, sig_name);
11134bc52338SCy Schubert 	if (!msg)
11144bc52338SCy Schubert 		return;
11154bc52338SCy Schubert 
11164bc52338SCy Schubert 	dbus_message_iter_init_append(msg, &iter);
11174bc52338SCy Schubert 	if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_OBJECT_PATH,
11184bc52338SCy Schubert 					    &station_obj_path) ||
11194bc52338SCy Schubert 	    (properties &&
11204bc52338SCy Schubert 	     !wpa_dbus_get_object_properties(iface, station_obj_path,
11214bc52338SCy Schubert 					     WPAS_DBUS_NEW_IFACE_STA,
11224bc52338SCy Schubert 					     &iter)))
11234bc52338SCy Schubert 		wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
11244bc52338SCy Schubert 	else
11254bc52338SCy Schubert 		dbus_connection_send(iface->con, msg, NULL);
11264bc52338SCy Schubert 	dbus_message_unref(msg);
11274bc52338SCy Schubert }
11284bc52338SCy Schubert 
11294bc52338SCy Schubert 
11304bc52338SCy Schubert /**
11314bc52338SCy Schubert  * wpas_dbus_signal_station_added - Send a Station added signal
11324bc52338SCy Schubert  * @wpa_s: %wpa_supplicant network interface data
11334bc52338SCy Schubert  * @station_obj_path: new Station object path
11344bc52338SCy Schubert  *
11354bc52338SCy Schubert  * Notify listeners about adding new Station
11364bc52338SCy Schubert  */
11374bc52338SCy Schubert static void wpas_dbus_signal_station_added(struct wpa_supplicant *wpa_s,
11384bc52338SCy Schubert 					   const char *station_obj_path)
11394bc52338SCy Schubert {
11404bc52338SCy Schubert 	wpas_dbus_signal_station(wpa_s, station_obj_path, "StationAdded", TRUE);
11414bc52338SCy Schubert }
11424bc52338SCy Schubert 
11434bc52338SCy Schubert 
11444bc52338SCy Schubert /**
11454bc52338SCy Schubert  * wpas_dbus_signal_station_removed - Send a Station removed signal
11464bc52338SCy Schubert  * @wpa_s: %wpa_supplicant network interface data
11474bc52338SCy Schubert  * @station_obj_path: Station object path
11484bc52338SCy Schubert  *
11494bc52338SCy Schubert  * Notify listeners about removing Station
11504bc52338SCy Schubert  */
11514bc52338SCy Schubert static void wpas_dbus_signal_station_removed(struct wpa_supplicant *wpa_s,
11524bc52338SCy Schubert 					     const char *station_obj_path)
11534bc52338SCy Schubert {
11544bc52338SCy Schubert 	wpas_dbus_signal_station(wpa_s, station_obj_path, "StationRemoved",
11554bc52338SCy Schubert 				 FALSE);
11564bc52338SCy Schubert }
11574bc52338SCy Schubert 
11584bc52338SCy Schubert 
1159d4f2939cSRui Paulo #ifdef CONFIG_P2P
1160d4f2939cSRui Paulo 
1161d4f2939cSRui Paulo /**
1162d4f2939cSRui Paulo  * wpas_dbus_signal_p2p_group_removed - Signals P2P group was removed
1163d4f2939cSRui Paulo  * @wpa_s: %wpa_supplicant network interface data
1164d4f2939cSRui Paulo  * @role: role of this device (client or GO)
1165d4f2939cSRui Paulo  * Sends signal with i/f name and role as string arguments
1166d4f2939cSRui Paulo  */
1167d4f2939cSRui Paulo void wpas_dbus_signal_p2p_group_removed(struct wpa_supplicant *wpa_s,
1168d4f2939cSRui Paulo 					const char *role)
1169d4f2939cSRui Paulo {
1170d4f2939cSRui Paulo 	DBusMessage *msg;
11715b9c547cSRui Paulo 	DBusMessageIter iter, dict_iter;
1172d4f2939cSRui Paulo 	struct wpas_dbus_priv *iface = wpa_s->global->dbus;
11735b9c547cSRui Paulo 	struct wpa_supplicant *parent;
1174d4f2939cSRui Paulo 
1175d4f2939cSRui Paulo 	/* Do nothing if the control interface is not turned on */
1176d4f2939cSRui Paulo 	if (iface == NULL)
1177d4f2939cSRui Paulo 		return;
1178d4f2939cSRui Paulo 
11795b9c547cSRui Paulo 	parent = wpa_s->parent;
11805b9c547cSRui Paulo 	if (parent->p2p_mgmt)
11815b9c547cSRui Paulo 		parent = parent->parent;
11825b9c547cSRui Paulo 
1183325151a3SRui Paulo 	if (!wpa_s->dbus_groupobj_path || !wpa_s->dbus_new_path ||
1184325151a3SRui Paulo 	    !parent->dbus_new_path)
11855b9c547cSRui Paulo 		return;
11865b9c547cSRui Paulo 
11875b9c547cSRui Paulo 	msg = dbus_message_new_signal(parent->dbus_new_path,
1188d4f2939cSRui Paulo 				      WPAS_DBUS_NEW_IFACE_P2PDEVICE,
1189d4f2939cSRui Paulo 				      "GroupFinished");
1190d4f2939cSRui Paulo 	if (msg == NULL)
1191d4f2939cSRui Paulo 		return;
1192d4f2939cSRui Paulo 
1193d4f2939cSRui Paulo 	dbus_message_iter_init_append(msg, &iter);
11945b9c547cSRui Paulo 	if (!wpa_dbus_dict_open_write(&iter, &dict_iter) ||
11955b9c547cSRui Paulo 	    !wpa_dbus_dict_append_object_path(&dict_iter,
11965b9c547cSRui Paulo 					      "interface_object",
11975b9c547cSRui Paulo 					      wpa_s->dbus_new_path) ||
11985b9c547cSRui Paulo 	    !wpa_dbus_dict_append_string(&dict_iter, "role", role) ||
11995b9c547cSRui Paulo 	    !wpa_dbus_dict_append_object_path(&dict_iter, "group_object",
12005b9c547cSRui Paulo 					      wpa_s->dbus_groupobj_path) ||
12015b9c547cSRui Paulo 	    !wpa_dbus_dict_close_write(&iter, &dict_iter))
12025b9c547cSRui Paulo 		wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
1203d4f2939cSRui Paulo 	else
1204d4f2939cSRui Paulo 		dbus_connection_send(iface->con, msg, NULL);
1205d4f2939cSRui Paulo 	dbus_message_unref(msg);
1206d4f2939cSRui Paulo }
1207d4f2939cSRui Paulo 
1208d4f2939cSRui Paulo 
1209d4f2939cSRui Paulo /**
1210d4f2939cSRui Paulo  * wpas_dbus_signal_p2p_provision_discovery - Signals various PD events
1211d4f2939cSRui Paulo  *
1212d4f2939cSRui Paulo  * @dev_addr - who sent the request or responded to our request.
1213d4f2939cSRui Paulo  * @request - Will be 1 if request, 0 for response.
1214d4f2939cSRui Paulo  * @status - valid only in case of response
1215d4f2939cSRui Paulo  * @config_methods - wps config methods
1216d4f2939cSRui Paulo  * @generated_pin - pin to be displayed in case of WPS_CONFIG_DISPLAY method
1217d4f2939cSRui Paulo  *
1218d4f2939cSRui Paulo  * Sends following provision discovery related events:
1219d4f2939cSRui Paulo  *	ProvisionDiscoveryRequestDisplayPin
1220d4f2939cSRui Paulo  *	ProvisionDiscoveryResponseDisplayPin
1221d4f2939cSRui Paulo  *	ProvisionDiscoveryRequestEnterPin
1222d4f2939cSRui Paulo  *	ProvisionDiscoveryResponseEnterPin
1223d4f2939cSRui Paulo  *	ProvisionDiscoveryPBCRequest
1224d4f2939cSRui Paulo  *	ProvisionDiscoveryPBCResponse
1225d4f2939cSRui Paulo  *
1226d4f2939cSRui Paulo  *	TODO::
1227d4f2939cSRui Paulo  *	ProvisionDiscoveryFailure (timeout case)
1228d4f2939cSRui Paulo  */
1229d4f2939cSRui Paulo void wpas_dbus_signal_p2p_provision_discovery(struct wpa_supplicant *wpa_s,
1230d4f2939cSRui Paulo 					      const u8 *dev_addr, int request,
1231d4f2939cSRui Paulo 					      enum p2p_prov_disc_status status,
1232d4f2939cSRui Paulo 					      u16 config_methods,
1233d4f2939cSRui Paulo 					      unsigned int generated_pin)
1234d4f2939cSRui Paulo {
1235d4f2939cSRui Paulo 	DBusMessage *msg;
1236d4f2939cSRui Paulo 	DBusMessageIter iter;
1237d4f2939cSRui Paulo 	struct wpas_dbus_priv *iface;
1238d4f2939cSRui Paulo 	char *_signal;
1239d4f2939cSRui Paulo 	int add_pin = 0;
1240d4f2939cSRui Paulo 	char peer_obj_path[WPAS_DBUS_OBJECT_PATH_MAX], *path;
1241d4f2939cSRui Paulo 	int error_ret = 1;
1242d4f2939cSRui Paulo 	char pin[9], *p_pin = NULL;
1243d4f2939cSRui Paulo 
1244d4f2939cSRui Paulo 	iface = wpa_s->global->dbus;
1245d4f2939cSRui Paulo 
1246d4f2939cSRui Paulo 	/* Do nothing if the control interface is not turned on */
1247d4f2939cSRui Paulo 	if (iface == NULL)
1248d4f2939cSRui Paulo 		return;
1249d4f2939cSRui Paulo 
12505b9c547cSRui Paulo 	if (wpa_s->p2p_mgmt)
12515b9c547cSRui Paulo 		wpa_s = wpa_s->parent;
1252325151a3SRui Paulo 	if (!wpa_s->dbus_new_path)
1253325151a3SRui Paulo 		return;
12545b9c547cSRui Paulo 
1255d4f2939cSRui Paulo 	if (request || !status) {
1256d4f2939cSRui Paulo 		if (config_methods & WPS_CONFIG_DISPLAY)
1257d4f2939cSRui Paulo 			_signal = request ?
1258d4f2939cSRui Paulo 				 "ProvisionDiscoveryRequestDisplayPin" :
1259d4f2939cSRui Paulo 				 "ProvisionDiscoveryResponseEnterPin";
1260d4f2939cSRui Paulo 		else if (config_methods & WPS_CONFIG_KEYPAD)
1261d4f2939cSRui Paulo 			_signal = request ?
1262d4f2939cSRui Paulo 				 "ProvisionDiscoveryRequestEnterPin" :
1263d4f2939cSRui Paulo 				 "ProvisionDiscoveryResponseDisplayPin";
1264d4f2939cSRui Paulo 		else if (config_methods & WPS_CONFIG_PUSHBUTTON)
1265d4f2939cSRui Paulo 			_signal = request ? "ProvisionDiscoveryPBCRequest" :
1266d4f2939cSRui Paulo 				   "ProvisionDiscoveryPBCResponse";
1267d4f2939cSRui Paulo 		else
1268d4f2939cSRui Paulo 			return; /* Unknown or un-supported method */
12695b9c547cSRui Paulo 	} else {
1270d4f2939cSRui Paulo 		/* Explicit check for failure response */
1271d4f2939cSRui Paulo 		_signal = "ProvisionDiscoveryFailure";
12725b9c547cSRui Paulo 	}
1273d4f2939cSRui Paulo 
1274d4f2939cSRui Paulo 	add_pin = ((request && (config_methods & WPS_CONFIG_DISPLAY)) ||
1275d4f2939cSRui Paulo 		   (!request && !status &&
1276d4f2939cSRui Paulo 			(config_methods & WPS_CONFIG_KEYPAD)));
1277d4f2939cSRui Paulo 
1278d4f2939cSRui Paulo 	if (add_pin) {
1279d4f2939cSRui Paulo 		os_snprintf(pin, sizeof(pin), "%08d", generated_pin);
1280d4f2939cSRui Paulo 		p_pin = pin;
1281d4f2939cSRui Paulo 	}
1282d4f2939cSRui Paulo 
1283d4f2939cSRui Paulo 	msg = dbus_message_new_signal(wpa_s->dbus_new_path,
1284d4f2939cSRui Paulo 				      WPAS_DBUS_NEW_IFACE_P2PDEVICE, _signal);
1285d4f2939cSRui Paulo 	if (msg == NULL)
1286d4f2939cSRui Paulo 		return;
1287d4f2939cSRui Paulo 
1288d4f2939cSRui Paulo 	/* Check if this is a known peer */
1289d4f2939cSRui Paulo 	if (!p2p_peer_known(wpa_s->global->p2p, dev_addr))
1290d4f2939cSRui Paulo 		goto error;
1291d4f2939cSRui Paulo 
1292d4f2939cSRui Paulo 	os_snprintf(peer_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
1293d4f2939cSRui Paulo 			"%s/" WPAS_DBUS_NEW_P2P_PEERS_PART "/"
1294d4f2939cSRui Paulo 			COMPACT_MACSTR,
1295d4f2939cSRui Paulo 			wpa_s->dbus_new_path, MAC2STR(dev_addr));
1296d4f2939cSRui Paulo 
1297d4f2939cSRui Paulo 	path = peer_obj_path;
1298d4f2939cSRui Paulo 
1299d4f2939cSRui Paulo 	dbus_message_iter_init_append(msg, &iter);
1300d4f2939cSRui Paulo 
1301d4f2939cSRui Paulo 	if (!dbus_message_iter_append_basic(&iter,
1302d4f2939cSRui Paulo 					    DBUS_TYPE_OBJECT_PATH,
1303d4f2939cSRui Paulo 					    &path))
1304d4f2939cSRui Paulo 			goto error;
1305d4f2939cSRui Paulo 
1306d4f2939cSRui Paulo 	if (!request && status)
1307d4f2939cSRui Paulo 		/* Attach status to ProvisionDiscoveryFailure */
1308d4f2939cSRui Paulo 		error_ret = !dbus_message_iter_append_basic(&iter,
1309d4f2939cSRui Paulo 						    DBUS_TYPE_INT32,
1310d4f2939cSRui Paulo 						    &status);
1311d4f2939cSRui Paulo 	else
1312d4f2939cSRui Paulo 		error_ret = (add_pin &&
1313d4f2939cSRui Paulo 				 !dbus_message_iter_append_basic(&iter,
1314d4f2939cSRui Paulo 							DBUS_TYPE_STRING,
1315d4f2939cSRui Paulo 							&p_pin));
1316d4f2939cSRui Paulo 
1317d4f2939cSRui Paulo error:
1318d4f2939cSRui Paulo 	if (!error_ret)
1319d4f2939cSRui Paulo 		dbus_connection_send(iface->con, msg, NULL);
1320d4f2939cSRui Paulo 	else
1321d4f2939cSRui Paulo 		wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
1322d4f2939cSRui Paulo 
1323d4f2939cSRui Paulo 	dbus_message_unref(msg);
1324d4f2939cSRui Paulo }
1325d4f2939cSRui Paulo 
1326d4f2939cSRui Paulo 
1327325151a3SRui Paulo /**
1328325151a3SRui Paulo  * wpas_dbus_signal_p2p_go_neg_req - Signal P2P GO Negotiation Request RX
1329325151a3SRui Paulo  * @wpa_s: %wpa_supplicant network interface data
1330325151a3SRui Paulo  * @src: Source address of the message triggering this notification
1331325151a3SRui Paulo  * @dev_passwd_id: WPS Device Password Id
1332325151a3SRui Paulo  * @go_intent: Peer's GO Intent value
1333325151a3SRui Paulo  *
1334325151a3SRui Paulo  * Sends signal to notify that a peer P2P Device is requesting group owner
1335325151a3SRui Paulo  * negotiation with us.
1336325151a3SRui Paulo  */
1337d4f2939cSRui Paulo void wpas_dbus_signal_p2p_go_neg_req(struct wpa_supplicant *wpa_s,
1338325151a3SRui Paulo 				     const u8 *src, u16 dev_passwd_id,
1339325151a3SRui Paulo 				     u8 go_intent)
1340d4f2939cSRui Paulo {
1341d4f2939cSRui Paulo 	DBusMessage *msg;
1342d4f2939cSRui Paulo 	DBusMessageIter iter;
1343d4f2939cSRui Paulo 	struct wpas_dbus_priv *iface;
1344d4f2939cSRui Paulo 	char peer_obj_path[WPAS_DBUS_OBJECT_PATH_MAX], *path;
1345d4f2939cSRui Paulo 
1346d4f2939cSRui Paulo 	iface = wpa_s->global->dbus;
1347d4f2939cSRui Paulo 
1348d4f2939cSRui Paulo 	/* Do nothing if the control interface is not turned on */
1349d4f2939cSRui Paulo 	if (iface == NULL)
1350d4f2939cSRui Paulo 		return;
1351d4f2939cSRui Paulo 
13525b9c547cSRui Paulo 	if (wpa_s->p2p_mgmt)
13535b9c547cSRui Paulo 		wpa_s = wpa_s->parent;
1354325151a3SRui Paulo 	if (!wpa_s->dbus_new_path)
1355325151a3SRui Paulo 		return;
13565b9c547cSRui Paulo 
1357d4f2939cSRui Paulo 	os_snprintf(peer_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
1358d4f2939cSRui Paulo 		    "%s/" WPAS_DBUS_NEW_P2P_PEERS_PART "/" COMPACT_MACSTR,
1359d4f2939cSRui Paulo 		    wpa_s->dbus_new_path, MAC2STR(src));
1360d4f2939cSRui Paulo 	path = peer_obj_path;
1361d4f2939cSRui Paulo 
1362d4f2939cSRui Paulo 	msg = dbus_message_new_signal(wpa_s->dbus_new_path,
1363d4f2939cSRui Paulo 				      WPAS_DBUS_NEW_IFACE_P2PDEVICE,
1364d4f2939cSRui Paulo 				      "GONegotiationRequest");
1365d4f2939cSRui Paulo 	if (msg == NULL)
1366d4f2939cSRui Paulo 		return;
1367d4f2939cSRui Paulo 
1368d4f2939cSRui Paulo 	dbus_message_iter_init_append(msg, &iter);
1369d4f2939cSRui Paulo 
1370d4f2939cSRui Paulo 	if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_OBJECT_PATH,
1371d4f2939cSRui Paulo 					    &path) ||
1372d4f2939cSRui Paulo 	    !dbus_message_iter_append_basic(&iter, DBUS_TYPE_UINT16,
1373325151a3SRui Paulo 					    &dev_passwd_id) ||
1374325151a3SRui Paulo 	    !dbus_message_iter_append_basic(&iter, DBUS_TYPE_BYTE,
1375325151a3SRui Paulo 					    &go_intent))
1376d4f2939cSRui Paulo 		wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
1377d4f2939cSRui Paulo 	else
1378d4f2939cSRui Paulo 		dbus_connection_send(iface->con, msg, NULL);
1379d4f2939cSRui Paulo 
1380d4f2939cSRui Paulo 	dbus_message_unref(msg);
1381d4f2939cSRui Paulo }
1382d4f2939cSRui Paulo 
1383d4f2939cSRui Paulo 
1384d4f2939cSRui Paulo static int wpas_dbus_get_group_obj_path(struct wpa_supplicant *wpa_s,
1385d4f2939cSRui Paulo 					const struct wpa_ssid *ssid,
1386d4f2939cSRui Paulo 					char *group_obj_path)
1387d4f2939cSRui Paulo {
1388d4f2939cSRui Paulo 	char group_name[3];
1389d4f2939cSRui Paulo 
1390325151a3SRui Paulo 	if (!wpa_s->dbus_new_path ||
1391325151a3SRui Paulo 	    os_memcmp(ssid->ssid, P2P_WILDCARD_SSID, P2P_WILDCARD_SSID_LEN))
1392d4f2939cSRui Paulo 		return -1;
1393d4f2939cSRui Paulo 
1394d4f2939cSRui Paulo 	os_memcpy(group_name, ssid->ssid + P2P_WILDCARD_SSID_LEN, 2);
1395d4f2939cSRui Paulo 	group_name[2] = '\0';
1396d4f2939cSRui Paulo 
1397d4f2939cSRui Paulo 	os_snprintf(group_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
1398d4f2939cSRui Paulo 		    "%s/" WPAS_DBUS_NEW_P2P_GROUPS_PART "/%s",
1399d4f2939cSRui Paulo 		    wpa_s->dbus_new_path, group_name);
1400d4f2939cSRui Paulo 
1401d4f2939cSRui Paulo 	return 0;
1402d4f2939cSRui Paulo }
1403d4f2939cSRui Paulo 
1404d4f2939cSRui Paulo 
14055b9c547cSRui Paulo struct group_changed_data {
14065b9c547cSRui Paulo 	struct wpa_supplicant *wpa_s;
14075b9c547cSRui Paulo 	struct p2p_peer_info *info;
14085b9c547cSRui Paulo };
14095b9c547cSRui Paulo 
14105b9c547cSRui Paulo 
14115b9c547cSRui Paulo static int match_group_where_peer_is_client(struct p2p_group *group,
14125b9c547cSRui Paulo 					    void *user_data)
14135b9c547cSRui Paulo {
14145b9c547cSRui Paulo 	struct group_changed_data *data = user_data;
14155b9c547cSRui Paulo 	const struct p2p_group_config *cfg;
14165b9c547cSRui Paulo 	struct wpa_supplicant *wpa_s_go;
14175b9c547cSRui Paulo 
14185b9c547cSRui Paulo 	if (!p2p_group_is_client_connected(group, data->info->p2p_device_addr))
14195b9c547cSRui Paulo 		return 1;
14205b9c547cSRui Paulo 
14215b9c547cSRui Paulo 	cfg = p2p_group_get_config(group);
14225b9c547cSRui Paulo 
14235b9c547cSRui Paulo 	wpa_s_go = wpas_get_p2p_go_iface(data->wpa_s, cfg->ssid,
14245b9c547cSRui Paulo 					 cfg->ssid_len);
14255b9c547cSRui Paulo 	if (wpa_s_go != NULL && wpa_s_go == data->wpa_s) {
14265b9c547cSRui Paulo 		wpas_dbus_signal_peer_groups_changed(
1427780fb4a2SCy Schubert 			data->wpa_s->p2pdev, data->info->p2p_device_addr);
14285b9c547cSRui Paulo 		return 0;
14295b9c547cSRui Paulo 	}
14305b9c547cSRui Paulo 
14315b9c547cSRui Paulo 	return 1;
14325b9c547cSRui Paulo }
14335b9c547cSRui Paulo 
14345b9c547cSRui Paulo 
14355b9c547cSRui Paulo static void signal_peer_groups_changed(struct p2p_peer_info *info,
14365b9c547cSRui Paulo 				       void *user_data)
14375b9c547cSRui Paulo {
14385b9c547cSRui Paulo 	struct group_changed_data *data = user_data;
14395b9c547cSRui Paulo 	struct wpa_supplicant *wpa_s_go;
14405b9c547cSRui Paulo 
14415b9c547cSRui Paulo 	wpa_s_go = wpas_get_p2p_client_iface(data->wpa_s,
14425b9c547cSRui Paulo 					     info->p2p_device_addr);
14435b9c547cSRui Paulo 	if (wpa_s_go != NULL && wpa_s_go == data->wpa_s) {
1444780fb4a2SCy Schubert 		wpas_dbus_signal_peer_groups_changed(data->wpa_s->p2pdev,
14455b9c547cSRui Paulo 						     info->p2p_device_addr);
14465b9c547cSRui Paulo 		return;
14475b9c547cSRui Paulo 	}
14485b9c547cSRui Paulo 
14495b9c547cSRui Paulo 	data->info = info;
14505b9c547cSRui Paulo 	p2p_loop_on_all_groups(data->wpa_s->global->p2p,
14515b9c547cSRui Paulo 			       match_group_where_peer_is_client, data);
14525b9c547cSRui Paulo 	data->info = NULL;
14535b9c547cSRui Paulo }
14545b9c547cSRui Paulo 
14555b9c547cSRui Paulo 
14565b9c547cSRui Paulo static void peer_groups_changed(struct wpa_supplicant *wpa_s)
14575b9c547cSRui Paulo {
14585b9c547cSRui Paulo 	struct group_changed_data data;
14595b9c547cSRui Paulo 
14605b9c547cSRui Paulo 	os_memset(&data, 0, sizeof(data));
14615b9c547cSRui Paulo 	data.wpa_s = wpa_s;
14625b9c547cSRui Paulo 
14635b9c547cSRui Paulo 	p2p_loop_on_known_peers(wpa_s->global->p2p,
14645b9c547cSRui Paulo 				signal_peer_groups_changed, &data);
14655b9c547cSRui Paulo }
14665b9c547cSRui Paulo 
14675b9c547cSRui Paulo 
1468d4f2939cSRui Paulo /**
1469d4f2939cSRui Paulo  * wpas_dbus_signal_p2p_group_started - Signals P2P group has
1470d4f2939cSRui Paulo  * started. Emitted when a group is successfully started
1471d4f2939cSRui Paulo  * irrespective of the role (client/GO) of the current device
1472d4f2939cSRui Paulo  *
1473d4f2939cSRui Paulo  * @wpa_s: %wpa_supplicant network interface data
1474d4f2939cSRui Paulo  * @client: this device is P2P client
1475780fb4a2SCy Schubert  * @persistent: 0 - non persistent group, 1 - persistent group
147685732ac8SCy Schubert  * @ip: When group role is client, it contains local IP address, netmask, and
147785732ac8SCy Schubert  *	GO's IP address, if assigned; otherwise, NULL
1478d4f2939cSRui Paulo  */
1479d4f2939cSRui Paulo void wpas_dbus_signal_p2p_group_started(struct wpa_supplicant *wpa_s,
148085732ac8SCy Schubert 					int client, int persistent,
148185732ac8SCy Schubert 					const u8 *ip)
1482d4f2939cSRui Paulo {
1483d4f2939cSRui Paulo 	DBusMessage *msg;
1484d4f2939cSRui Paulo 	DBusMessageIter iter, dict_iter;
1485d4f2939cSRui Paulo 	struct wpas_dbus_priv *iface;
14865b9c547cSRui Paulo 	struct wpa_supplicant *parent;
1487d4f2939cSRui Paulo 
14885b9c547cSRui Paulo 	parent = wpa_s->parent;
14895b9c547cSRui Paulo 	if (parent->p2p_mgmt)
14905b9c547cSRui Paulo 		parent = parent->parent;
14915b9c547cSRui Paulo 
14925b9c547cSRui Paulo 	iface = parent->global->dbus;
1493d4f2939cSRui Paulo 
1494d4f2939cSRui Paulo 	/* Do nothing if the control interface is not turned on */
1495325151a3SRui Paulo 	if (iface == NULL || !parent->dbus_new_path || !wpa_s->dbus_new_path)
1496d4f2939cSRui Paulo 		return;
1497d4f2939cSRui Paulo 
14985b9c547cSRui Paulo 	if (wpa_s->dbus_groupobj_path == NULL)
1499d4f2939cSRui Paulo 		return;
1500d4f2939cSRui Paulo 
1501d4f2939cSRui Paulo 	/* New interface has been created for this group */
15025b9c547cSRui Paulo 	msg = dbus_message_new_signal(parent->dbus_new_path,
1503d4f2939cSRui Paulo 				      WPAS_DBUS_NEW_IFACE_P2PDEVICE,
1504d4f2939cSRui Paulo 				      "GroupStarted");
1505d4f2939cSRui Paulo 	if (msg == NULL)
1506d4f2939cSRui Paulo 		return;
1507d4f2939cSRui Paulo 
1508d4f2939cSRui Paulo 	dbus_message_iter_init_append(msg, &iter);
1509d4f2939cSRui Paulo 	/*
1510d4f2939cSRui Paulo 	 * In case the device supports creating a separate interface the
1511d4f2939cSRui Paulo 	 * DBus client will need to know the object path for the interface
1512d4f2939cSRui Paulo 	 * object this group was created on, so include it here.
1513d4f2939cSRui Paulo 	 */
15145b9c547cSRui Paulo 	if (!wpa_dbus_dict_open_write(&iter, &dict_iter) ||
15155b9c547cSRui Paulo 	    !wpa_dbus_dict_append_object_path(&dict_iter,
1516d4f2939cSRui Paulo 					      "interface_object",
15175b9c547cSRui Paulo 					      wpa_s->dbus_new_path) ||
15185b9c547cSRui Paulo 	    !wpa_dbus_dict_append_string(&dict_iter, "role",
15195b9c547cSRui Paulo 					 client ? "client" : "GO") ||
1520780fb4a2SCy Schubert 	    !wpa_dbus_dict_append_bool(&dict_iter, "persistent", persistent) ||
15215b9c547cSRui Paulo 	    !wpa_dbus_dict_append_object_path(&dict_iter, "group_object",
15225b9c547cSRui Paulo 					      wpa_s->dbus_groupobj_path) ||
152385732ac8SCy Schubert 	    (ip &&
152485732ac8SCy Schubert 	     (!wpa_dbus_dict_append_byte_array(&dict_iter, "IpAddr",
152585732ac8SCy Schubert 					       (char *) ip, 4) ||
152685732ac8SCy Schubert 	      !wpa_dbus_dict_append_byte_array(&dict_iter, "IpAddrMask",
152785732ac8SCy Schubert 					       (char *) ip + 4, 4) ||
152885732ac8SCy Schubert 	      !wpa_dbus_dict_append_byte_array(&dict_iter, "IpAddrGo",
152985732ac8SCy Schubert 					       (char *) ip + 8, 4))) ||
15305b9c547cSRui Paulo 	    !wpa_dbus_dict_close_write(&iter, &dict_iter)) {
15315b9c547cSRui Paulo 		wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
15325b9c547cSRui Paulo 	} else {
1533d4f2939cSRui Paulo 		dbus_connection_send(iface->con, msg, NULL);
15345b9c547cSRui Paulo 		if (client)
15355b9c547cSRui Paulo 			peer_groups_changed(wpa_s);
15365b9c547cSRui Paulo 	}
1537d4f2939cSRui Paulo 	dbus_message_unref(msg);
1538d4f2939cSRui Paulo }
1539d4f2939cSRui Paulo 
1540d4f2939cSRui Paulo 
1541d4f2939cSRui Paulo /**
1542325151a3SRui Paulo  * wpas_dbus_signal_p2p_go_neg_resp - Emit GONegotiation Success/Failure signal
1543325151a3SRui Paulo  * @wpa_s: %wpa_supplicant network interface data
1544325151a3SRui Paulo  * @res: Result of the GO Neg Request
1545d4f2939cSRui Paulo  */
1546d4f2939cSRui Paulo void wpas_dbus_signal_p2p_go_neg_resp(struct wpa_supplicant *wpa_s,
1547d4f2939cSRui Paulo 				      struct p2p_go_neg_results *res)
1548d4f2939cSRui Paulo {
1549d4f2939cSRui Paulo 	DBusMessage *msg;
1550d4f2939cSRui Paulo 	DBusMessageIter iter, dict_iter;
1551d4f2939cSRui Paulo 	DBusMessageIter iter_dict_entry, iter_dict_val, iter_dict_array;
1552d4f2939cSRui Paulo 	struct wpas_dbus_priv *iface;
1553d4f2939cSRui Paulo 	char peer_obj_path[WPAS_DBUS_OBJECT_PATH_MAX], *path;
1554d4f2939cSRui Paulo 	dbus_int32_t freqs[P2P_MAX_CHANNELS];
1555d4f2939cSRui Paulo 	dbus_int32_t *f_array = freqs;
1556d4f2939cSRui Paulo 
1557d4f2939cSRui Paulo 
1558d4f2939cSRui Paulo 	iface = wpa_s->global->dbus;
1559d4f2939cSRui Paulo 
15605b9c547cSRui Paulo 	if (wpa_s->p2p_mgmt)
15615b9c547cSRui Paulo 		wpa_s = wpa_s->parent;
15625b9c547cSRui Paulo 
1563d4f2939cSRui Paulo 	os_memset(freqs, 0, sizeof(freqs));
1564d4f2939cSRui Paulo 	/* Do nothing if the control interface is not turned on */
1565325151a3SRui Paulo 	if (iface == NULL || !wpa_s->dbus_new_path)
1566d4f2939cSRui Paulo 		return;
1567d4f2939cSRui Paulo 
1568d4f2939cSRui Paulo 	os_snprintf(peer_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
1569d4f2939cSRui Paulo 		    "%s/" WPAS_DBUS_NEW_P2P_PEERS_PART "/" COMPACT_MACSTR,
1570d4f2939cSRui Paulo 		    wpa_s->dbus_new_path, MAC2STR(res->peer_device_addr));
1571d4f2939cSRui Paulo 	path = peer_obj_path;
1572d4f2939cSRui Paulo 
1573d4f2939cSRui Paulo 	msg = dbus_message_new_signal(wpa_s->dbus_new_path,
1574d4f2939cSRui Paulo 				      WPAS_DBUS_NEW_IFACE_P2PDEVICE,
1575d4f2939cSRui Paulo 				      res->status ? "GONegotiationFailure" :
1576d4f2939cSRui Paulo 						    "GONegotiationSuccess");
1577d4f2939cSRui Paulo 	if (msg == NULL)
1578d4f2939cSRui Paulo 		return;
1579d4f2939cSRui Paulo 
1580d4f2939cSRui Paulo 	dbus_message_iter_init_append(msg, &iter);
15815b9c547cSRui Paulo 	if (!wpa_dbus_dict_open_write(&iter, &dict_iter) ||
15825b9c547cSRui Paulo 	    !wpa_dbus_dict_append_object_path(&dict_iter, "peer_object",
1583d4f2939cSRui Paulo 					      path) ||
1584d4f2939cSRui Paulo 	    !wpa_dbus_dict_append_int32(&dict_iter, "status", res->status))
1585d4f2939cSRui Paulo 		goto err;
1586d4f2939cSRui Paulo 
1587d4f2939cSRui Paulo 	if (!res->status) {
1588d4f2939cSRui Paulo 		int i = 0;
1589d4f2939cSRui Paulo 		int freq_list_num = 0;
1590d4f2939cSRui Paulo 
15915b9c547cSRui Paulo 		if ((res->role_go &&
15925b9c547cSRui Paulo 		     !wpa_dbus_dict_append_string(&dict_iter, "passphrase",
15935b9c547cSRui Paulo 						  res->passphrase)) ||
15945b9c547cSRui Paulo 		    !wpa_dbus_dict_append_string(&dict_iter, "role_go",
1595d4f2939cSRui Paulo 						 res->role_go ? "GO" :
1596d4f2939cSRui Paulo 						 "client") ||
1597d4f2939cSRui Paulo 		    !wpa_dbus_dict_append_int32(&dict_iter, "frequency",
1598d4f2939cSRui Paulo 						res->freq) ||
1599d4f2939cSRui Paulo 		    !wpa_dbus_dict_append_byte_array(&dict_iter, "ssid",
1600d4f2939cSRui Paulo 						     (const char *) res->ssid,
1601d4f2939cSRui Paulo 						     res->ssid_len) ||
1602d4f2939cSRui Paulo 		    !wpa_dbus_dict_append_byte_array(&dict_iter,
1603d4f2939cSRui Paulo 						     "peer_device_addr",
1604d4f2939cSRui Paulo 						     (const char *)
1605d4f2939cSRui Paulo 						     res->peer_device_addr,
1606d4f2939cSRui Paulo 						     ETH_ALEN) ||
1607d4f2939cSRui Paulo 		    !wpa_dbus_dict_append_byte_array(&dict_iter,
1608d4f2939cSRui Paulo 						     "peer_interface_addr",
1609d4f2939cSRui Paulo 						     (const char *)
1610d4f2939cSRui Paulo 						     res->peer_interface_addr,
1611d4f2939cSRui Paulo 						     ETH_ALEN) ||
1612d4f2939cSRui Paulo 		    !wpa_dbus_dict_append_string(&dict_iter, "wps_method",
1613d4f2939cSRui Paulo 						 p2p_wps_method_text(
1614d4f2939cSRui Paulo 							 res->wps_method)))
1615d4f2939cSRui Paulo 			goto err;
1616d4f2939cSRui Paulo 
1617d4f2939cSRui Paulo 		for (i = 0; i < P2P_MAX_CHANNELS; i++) {
1618d4f2939cSRui Paulo 			if (res->freq_list[i]) {
1619d4f2939cSRui Paulo 				freqs[i] = res->freq_list[i];
1620d4f2939cSRui Paulo 				freq_list_num++;
1621d4f2939cSRui Paulo 			}
1622d4f2939cSRui Paulo 		}
1623d4f2939cSRui Paulo 
1624d4f2939cSRui Paulo 		if (!wpa_dbus_dict_begin_array(&dict_iter,
1625d4f2939cSRui Paulo 					       "frequency_list",
1626d4f2939cSRui Paulo 					       DBUS_TYPE_INT32_AS_STRING,
1627d4f2939cSRui Paulo 					       &iter_dict_entry,
1628d4f2939cSRui Paulo 					       &iter_dict_val,
16295b9c547cSRui Paulo 					       &iter_dict_array) ||
16305b9c547cSRui Paulo 		    !dbus_message_iter_append_fixed_array(&iter_dict_array,
1631d4f2939cSRui Paulo 							  DBUS_TYPE_INT32,
1632d4f2939cSRui Paulo 							  &f_array,
16335b9c547cSRui Paulo 							  freq_list_num) ||
16345b9c547cSRui Paulo 		    !wpa_dbus_dict_end_array(&dict_iter,
1635d4f2939cSRui Paulo 					     &iter_dict_entry,
1636d4f2939cSRui Paulo 					     &iter_dict_val,
16375b9c547cSRui Paulo 					     &iter_dict_array) ||
16385b9c547cSRui Paulo 		    !wpa_dbus_dict_append_int32(&dict_iter, "persistent_group",
1639d4f2939cSRui Paulo 						res->persistent_group) ||
1640d4f2939cSRui Paulo 		    !wpa_dbus_dict_append_uint32(&dict_iter,
1641d4f2939cSRui Paulo 						 "peer_config_timeout",
1642d4f2939cSRui Paulo 						 res->peer_config_timeout))
1643d4f2939cSRui Paulo 			goto err;
1644d4f2939cSRui Paulo 	}
1645d4f2939cSRui Paulo 
1646d4f2939cSRui Paulo 	if (!wpa_dbus_dict_close_write(&iter, &dict_iter))
1647d4f2939cSRui Paulo 		goto err;
1648d4f2939cSRui Paulo 
1649d4f2939cSRui Paulo 	dbus_connection_send(iface->con, msg, NULL);
1650d4f2939cSRui Paulo err:
1651d4f2939cSRui Paulo 	dbus_message_unref(msg);
1652d4f2939cSRui Paulo }
1653d4f2939cSRui Paulo 
1654d4f2939cSRui Paulo 
1655d4f2939cSRui Paulo /**
1656325151a3SRui Paulo  * wpas_dbus_signal_p2p_invitation_result - Emit InvitationResult signal
1657325151a3SRui Paulo  * @wpa_s: %wpa_supplicant network interface data
1658325151a3SRui Paulo  * @status: Status of invitation process
1659d4f2939cSRui Paulo  * @bssid: Basic Service Set Identifier
1660d4f2939cSRui Paulo  */
1661d4f2939cSRui Paulo void wpas_dbus_signal_p2p_invitation_result(struct wpa_supplicant *wpa_s,
1662d4f2939cSRui Paulo 					    int status, const u8 *bssid)
1663d4f2939cSRui Paulo {
1664d4f2939cSRui Paulo 	DBusMessage *msg;
1665d4f2939cSRui Paulo 	DBusMessageIter iter, dict_iter;
1666d4f2939cSRui Paulo 	struct wpas_dbus_priv *iface;
1667d4f2939cSRui Paulo 
16685b9c547cSRui Paulo 	wpa_printf(MSG_DEBUG, "%s", __func__);
1669d4f2939cSRui Paulo 
1670d4f2939cSRui Paulo 	iface = wpa_s->global->dbus;
1671d4f2939cSRui Paulo 	/* Do nothing if the control interface is not turned on */
1672d4f2939cSRui Paulo 	if (iface == NULL)
1673d4f2939cSRui Paulo 		return;
1674d4f2939cSRui Paulo 
16755b9c547cSRui Paulo 	if (wpa_s->p2p_mgmt)
16765b9c547cSRui Paulo 		wpa_s = wpa_s->parent;
1677325151a3SRui Paulo 	if (!wpa_s->dbus_new_path)
1678325151a3SRui Paulo 		return;
16795b9c547cSRui Paulo 
1680d4f2939cSRui Paulo 	msg = dbus_message_new_signal(wpa_s->dbus_new_path,
1681d4f2939cSRui Paulo 				      WPAS_DBUS_NEW_IFACE_P2PDEVICE,
1682d4f2939cSRui Paulo 				      "InvitationResult");
1683d4f2939cSRui Paulo 
1684d4f2939cSRui Paulo 	if (msg == NULL)
1685d4f2939cSRui Paulo 		return;
1686d4f2939cSRui Paulo 
1687d4f2939cSRui Paulo 	dbus_message_iter_init_append(msg, &iter);
16885b9c547cSRui Paulo 	if (!wpa_dbus_dict_open_write(&iter, &dict_iter) ||
16895b9c547cSRui Paulo 	    !wpa_dbus_dict_append_int32(&dict_iter, "status", status) ||
16905b9c547cSRui Paulo 	    (bssid &&
16915b9c547cSRui Paulo 	     !wpa_dbus_dict_append_byte_array(&dict_iter, "BSSID",
1692d4f2939cSRui Paulo 					      (const char *) bssid,
16935b9c547cSRui Paulo 					      ETH_ALEN)) ||
16945b9c547cSRui Paulo 	    !wpa_dbus_dict_close_write(&iter, &dict_iter))
16955b9c547cSRui Paulo 		wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
16965b9c547cSRui Paulo 	else
1697d4f2939cSRui Paulo 		dbus_connection_send(iface->con, msg, NULL);
1698d4f2939cSRui Paulo 	dbus_message_unref(msg);
1699d4f2939cSRui Paulo }
1700d4f2939cSRui Paulo 
1701d4f2939cSRui Paulo 
1702d4f2939cSRui Paulo /**
1703d4f2939cSRui Paulo  *
1704d4f2939cSRui Paulo  * Method to emit a signal for a peer joining the group.
1705d4f2939cSRui Paulo  * The signal will carry path to the group member object
1706d4f2939cSRui Paulo  * constructed using p2p i/f addr used for connecting.
1707d4f2939cSRui Paulo  *
1708d4f2939cSRui Paulo  * @wpa_s: %wpa_supplicant network interface data
17095b9c547cSRui Paulo  * @peer_addr: P2P Device Address of the peer joining the group
1710d4f2939cSRui Paulo  */
1711d4f2939cSRui Paulo void wpas_dbus_signal_p2p_peer_joined(struct wpa_supplicant *wpa_s,
17125b9c547cSRui Paulo 				      const u8 *peer_addr)
1713d4f2939cSRui Paulo {
1714d4f2939cSRui Paulo 	struct wpas_dbus_priv *iface;
1715d4f2939cSRui Paulo 	DBusMessage *msg;
1716d4f2939cSRui Paulo 	DBusMessageIter iter;
17175b9c547cSRui Paulo 	char peer_obj_path[WPAS_DBUS_OBJECT_PATH_MAX], *path;
17185b9c547cSRui Paulo 	struct wpa_supplicant *parent;
1719d4f2939cSRui Paulo 
1720d4f2939cSRui Paulo 	iface = wpa_s->global->dbus;
1721d4f2939cSRui Paulo 
1722d4f2939cSRui Paulo 	/* Do nothing if the control interface is not turned on */
1723d4f2939cSRui Paulo 	if (iface == NULL)
1724d4f2939cSRui Paulo 		return;
1725d4f2939cSRui Paulo 
1726d4f2939cSRui Paulo 	if (!wpa_s->dbus_groupobj_path)
1727d4f2939cSRui Paulo 		return;
1728d4f2939cSRui Paulo 
17295b9c547cSRui Paulo 	parent = wpa_s->parent;
17305b9c547cSRui Paulo 	if (parent->p2p_mgmt)
17315b9c547cSRui Paulo 		parent = parent->parent;
1732325151a3SRui Paulo 	if (!parent->dbus_new_path)
1733325151a3SRui Paulo 		return;
17345b9c547cSRui Paulo 
17355b9c547cSRui Paulo 	os_snprintf(peer_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
17365b9c547cSRui Paulo 			"%s/" WPAS_DBUS_NEW_P2P_PEERS_PART "/"
1737d4f2939cSRui Paulo 			COMPACT_MACSTR,
17385b9c547cSRui Paulo 			parent->dbus_new_path, MAC2STR(peer_addr));
1739d4f2939cSRui Paulo 
1740d4f2939cSRui Paulo 	msg = dbus_message_new_signal(wpa_s->dbus_groupobj_path,
1741d4f2939cSRui Paulo 				      WPAS_DBUS_NEW_IFACE_P2P_GROUP,
1742d4f2939cSRui Paulo 				      "PeerJoined");
1743d4f2939cSRui Paulo 	if (msg == NULL)
1744d4f2939cSRui Paulo 		return;
1745d4f2939cSRui Paulo 
1746d4f2939cSRui Paulo 	dbus_message_iter_init_append(msg, &iter);
17475b9c547cSRui Paulo 	path = peer_obj_path;
1748d4f2939cSRui Paulo 	if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_OBJECT_PATH,
17495b9c547cSRui Paulo 					    &path)) {
1750d4f2939cSRui Paulo 		wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
17515b9c547cSRui Paulo 	} else {
17525b9c547cSRui Paulo 		dbus_connection_send(iface->con, msg, NULL);
17535b9c547cSRui Paulo 		wpas_dbus_signal_peer_groups_changed(parent, peer_addr);
17545b9c547cSRui Paulo 	}
1755d4f2939cSRui Paulo 	dbus_message_unref(msg);
1756d4f2939cSRui Paulo }
1757d4f2939cSRui Paulo 
1758d4f2939cSRui Paulo 
1759d4f2939cSRui Paulo /**
1760d4f2939cSRui Paulo  *
1761d4f2939cSRui Paulo  * Method to emit a signal for a peer disconnecting the group.
1762d4f2939cSRui Paulo  * The signal will carry path to the group member object
17635b9c547cSRui Paulo  * constructed using the P2P Device Address of the peer.
1764d4f2939cSRui Paulo  *
1765d4f2939cSRui Paulo  * @wpa_s: %wpa_supplicant network interface data
17665b9c547cSRui Paulo  * @peer_addr: P2P Device Address of the peer joining the group
1767d4f2939cSRui Paulo  */
1768d4f2939cSRui Paulo void wpas_dbus_signal_p2p_peer_disconnected(struct wpa_supplicant *wpa_s,
17695b9c547cSRui Paulo 					    const u8 *peer_addr)
1770d4f2939cSRui Paulo {
1771d4f2939cSRui Paulo 	struct wpas_dbus_priv *iface;
1772d4f2939cSRui Paulo 	DBusMessage *msg;
1773d4f2939cSRui Paulo 	DBusMessageIter iter;
17745b9c547cSRui Paulo 	char peer_obj_path[WPAS_DBUS_OBJECT_PATH_MAX], *path;
17755b9c547cSRui Paulo 	struct wpa_supplicant *parent;
1776d4f2939cSRui Paulo 
1777d4f2939cSRui Paulo 	iface = wpa_s->global->dbus;
1778d4f2939cSRui Paulo 
1779d4f2939cSRui Paulo 	/* Do nothing if the control interface is not turned on */
1780d4f2939cSRui Paulo 	if (iface == NULL)
1781d4f2939cSRui Paulo 		return;
1782d4f2939cSRui Paulo 
1783d4f2939cSRui Paulo 	if (!wpa_s->dbus_groupobj_path)
1784d4f2939cSRui Paulo 		return;
1785d4f2939cSRui Paulo 
17865b9c547cSRui Paulo 	parent = wpa_s->parent;
17875b9c547cSRui Paulo 	if (parent->p2p_mgmt)
17885b9c547cSRui Paulo 		parent = parent->parent;
1789325151a3SRui Paulo 	if (!parent->dbus_new_path)
1790325151a3SRui Paulo 		return;
17915b9c547cSRui Paulo 
17925b9c547cSRui Paulo 	os_snprintf(peer_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
17935b9c547cSRui Paulo 			"%s/" WPAS_DBUS_NEW_P2P_PEERS_PART "/"
1794d4f2939cSRui Paulo 			COMPACT_MACSTR,
17955b9c547cSRui Paulo 			parent->dbus_new_path, MAC2STR(peer_addr));
1796d4f2939cSRui Paulo 
1797d4f2939cSRui Paulo 	msg = dbus_message_new_signal(wpa_s->dbus_groupobj_path,
1798d4f2939cSRui Paulo 				      WPAS_DBUS_NEW_IFACE_P2P_GROUP,
1799d4f2939cSRui Paulo 				      "PeerDisconnected");
1800d4f2939cSRui Paulo 	if (msg == NULL)
1801d4f2939cSRui Paulo 		return;
1802d4f2939cSRui Paulo 
1803d4f2939cSRui Paulo 	dbus_message_iter_init_append(msg, &iter);
18045b9c547cSRui Paulo 	path = peer_obj_path;
1805d4f2939cSRui Paulo 	if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_OBJECT_PATH,
18065b9c547cSRui Paulo 					    &path)) {
18075b9c547cSRui Paulo 		wpa_printf(MSG_ERROR,
18085b9c547cSRui Paulo 			   "dbus: Failed to construct PeerDisconnected signal");
18095b9c547cSRui Paulo 	} else {
1810d4f2939cSRui Paulo 		dbus_connection_send(iface->con, msg, NULL);
18115b9c547cSRui Paulo 		wpas_dbus_signal_peer_groups_changed(parent, peer_addr);
18125b9c547cSRui Paulo 	}
1813d4f2939cSRui Paulo 	dbus_message_unref(msg);
1814d4f2939cSRui Paulo }
1815d4f2939cSRui Paulo 
1816d4f2939cSRui Paulo 
1817d4f2939cSRui Paulo /**
1818d4f2939cSRui Paulo  *
1819d4f2939cSRui Paulo  * Method to emit a signal for a service discovery request.
1820d4f2939cSRui Paulo  * The signal will carry station address, frequency, dialog token,
1821d4f2939cSRui Paulo  * update indicator and it tlvs
1822d4f2939cSRui Paulo  *
1823d4f2939cSRui Paulo  * @wpa_s: %wpa_supplicant network interface data
1824d4f2939cSRui Paulo  * @sa: station addr (p2p i/f) of the peer
1825d4f2939cSRui Paulo  * @dialog_token: service discovery request dialog token
1826d4f2939cSRui Paulo  * @update_indic: service discovery request update indicator
1827*c1d255d3SCy Schubert  * @tlvs: service discovery request generated byte array of tlvs
1828d4f2939cSRui Paulo  * @tlvs_len: service discovery request tlvs length
1829d4f2939cSRui Paulo  */
1830d4f2939cSRui Paulo void wpas_dbus_signal_p2p_sd_request(struct wpa_supplicant *wpa_s,
1831d4f2939cSRui Paulo 				     int freq, const u8 *sa, u8 dialog_token,
1832d4f2939cSRui Paulo 				     u16 update_indic, const u8 *tlvs,
1833d4f2939cSRui Paulo 				     size_t tlvs_len)
1834d4f2939cSRui Paulo {
1835d4f2939cSRui Paulo 	DBusMessage *msg;
1836d4f2939cSRui Paulo 	DBusMessageIter iter, dict_iter;
1837d4f2939cSRui Paulo 	struct wpas_dbus_priv *iface;
1838d4f2939cSRui Paulo 	char peer_obj_path[WPAS_DBUS_OBJECT_PATH_MAX], *path;
18395b9c547cSRui Paulo 
1840d4f2939cSRui Paulo 	iface = wpa_s->global->dbus;
1841d4f2939cSRui Paulo 
1842d4f2939cSRui Paulo 	/* Do nothing if the control interface is not turned on */
1843d4f2939cSRui Paulo 	if (iface == NULL)
1844d4f2939cSRui Paulo 		return;
1845d4f2939cSRui Paulo 
18465b9c547cSRui Paulo 	if (wpa_s->p2p_mgmt)
18475b9c547cSRui Paulo 		wpa_s = wpa_s->parent;
1848325151a3SRui Paulo 	if (!wpa_s->dbus_new_path)
1849325151a3SRui Paulo 		return;
18505b9c547cSRui Paulo 
18515b9c547cSRui Paulo 	/* Check if this is a known peer */
18525b9c547cSRui Paulo 	if (!p2p_peer_known(wpa_s->global->p2p, sa))
18535b9c547cSRui Paulo 		return;
18545b9c547cSRui Paulo 
1855d4f2939cSRui Paulo 	msg = dbus_message_new_signal(wpa_s->dbus_new_path,
1856d4f2939cSRui Paulo 				      WPAS_DBUS_NEW_IFACE_P2PDEVICE,
1857d4f2939cSRui Paulo 				      "ServiceDiscoveryRequest");
1858d4f2939cSRui Paulo 	if (msg == NULL)
1859d4f2939cSRui Paulo 		return;
1860d4f2939cSRui Paulo 
1861d4f2939cSRui Paulo 	os_snprintf(peer_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
1862d4f2939cSRui Paulo 		    "%s/" WPAS_DBUS_NEW_P2P_PEERS_PART "/"
1863d4f2939cSRui Paulo 		    COMPACT_MACSTR, wpa_s->dbus_new_path, MAC2STR(sa));
1864d4f2939cSRui Paulo 
1865d4f2939cSRui Paulo 	path = peer_obj_path;
1866d4f2939cSRui Paulo 
1867d4f2939cSRui Paulo 	dbus_message_iter_init_append(msg, &iter);
18685b9c547cSRui Paulo 	if (!wpa_dbus_dict_open_write(&iter, &dict_iter) ||
18695b9c547cSRui Paulo 	    !wpa_dbus_dict_append_object_path(&dict_iter, "peer_object",
1870d4f2939cSRui Paulo 					      path) ||
1871d4f2939cSRui Paulo 	    !wpa_dbus_dict_append_int32(&dict_iter, "frequency", freq) ||
1872d4f2939cSRui Paulo 	    !wpa_dbus_dict_append_int32(&dict_iter, "dialog_token",
1873d4f2939cSRui Paulo 					dialog_token) ||
1874d4f2939cSRui Paulo 	    !wpa_dbus_dict_append_uint16(&dict_iter, "update_indicator",
1875d4f2939cSRui Paulo 					 update_indic) ||
1876d4f2939cSRui Paulo 	    !wpa_dbus_dict_append_byte_array(&dict_iter, "tlvs",
1877d4f2939cSRui Paulo 					     (const char *) tlvs,
1878d4f2939cSRui Paulo 					     tlvs_len) ||
1879d4f2939cSRui Paulo 	    !wpa_dbus_dict_close_write(&iter, &dict_iter))
1880d4f2939cSRui Paulo 		wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
18815b9c547cSRui Paulo 	else
18825b9c547cSRui Paulo 		dbus_connection_send(iface->con, msg, NULL);
1883d4f2939cSRui Paulo 	dbus_message_unref(msg);
1884d4f2939cSRui Paulo }
1885d4f2939cSRui Paulo 
1886d4f2939cSRui Paulo 
1887d4f2939cSRui Paulo /**
1888d4f2939cSRui Paulo  *
1889d4f2939cSRui Paulo  * Method to emit a signal for a service discovery response.
1890d4f2939cSRui Paulo  * The signal will carry station address, update indicator and it
1891d4f2939cSRui Paulo  * tlvs
1892d4f2939cSRui Paulo  *
1893d4f2939cSRui Paulo  * @wpa_s: %wpa_supplicant network interface data
1894d4f2939cSRui Paulo  * @sa: station addr (p2p i/f) of the peer
1895d4f2939cSRui Paulo  * @update_indic: service discovery request update indicator
1896*c1d255d3SCy Schubert  * @tlvs: service discovery request generated byte array of tlvs
1897d4f2939cSRui Paulo  * @tlvs_len: service discovery request tlvs length
1898d4f2939cSRui Paulo  */
1899d4f2939cSRui Paulo void wpas_dbus_signal_p2p_sd_response(struct wpa_supplicant *wpa_s,
1900d4f2939cSRui Paulo 				      const u8 *sa, u16 update_indic,
1901d4f2939cSRui Paulo 				      const u8 *tlvs, size_t tlvs_len)
1902d4f2939cSRui Paulo {
1903d4f2939cSRui Paulo 	DBusMessage *msg;
1904d4f2939cSRui Paulo 	DBusMessageIter iter, dict_iter;
1905d4f2939cSRui Paulo 	struct wpas_dbus_priv *iface;
1906d4f2939cSRui Paulo 	char peer_obj_path[WPAS_DBUS_OBJECT_PATH_MAX], *path;
19075b9c547cSRui Paulo 
1908d4f2939cSRui Paulo 	iface = wpa_s->global->dbus;
1909d4f2939cSRui Paulo 
1910d4f2939cSRui Paulo 	/* Do nothing if the control interface is not turned on */
1911d4f2939cSRui Paulo 	if (iface == NULL)
1912d4f2939cSRui Paulo 		return;
1913d4f2939cSRui Paulo 
19145b9c547cSRui Paulo 	if (wpa_s->p2p_mgmt)
19155b9c547cSRui Paulo 		wpa_s = wpa_s->parent;
1916325151a3SRui Paulo 	if (!wpa_s->dbus_new_path)
1917325151a3SRui Paulo 		return;
19185b9c547cSRui Paulo 
19195b9c547cSRui Paulo 	/* Check if this is a known peer */
19205b9c547cSRui Paulo 	if (!p2p_peer_known(wpa_s->global->p2p, sa))
19215b9c547cSRui Paulo 		return;
19225b9c547cSRui Paulo 
1923d4f2939cSRui Paulo 	msg = dbus_message_new_signal(wpa_s->dbus_new_path,
1924d4f2939cSRui Paulo 				      WPAS_DBUS_NEW_IFACE_P2PDEVICE,
1925d4f2939cSRui Paulo 				      "ServiceDiscoveryResponse");
1926d4f2939cSRui Paulo 	if (msg == NULL)
1927d4f2939cSRui Paulo 		return;
1928d4f2939cSRui Paulo 
1929d4f2939cSRui Paulo 	os_snprintf(peer_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
1930d4f2939cSRui Paulo 		    "%s/" WPAS_DBUS_NEW_P2P_PEERS_PART "/"
1931d4f2939cSRui Paulo 		    COMPACT_MACSTR, wpa_s->dbus_new_path, MAC2STR(sa));
1932d4f2939cSRui Paulo 
1933d4f2939cSRui Paulo 	path = peer_obj_path;
1934d4f2939cSRui Paulo 
1935d4f2939cSRui Paulo 	dbus_message_iter_init_append(msg, &iter);
19365b9c547cSRui Paulo 	if (!wpa_dbus_dict_open_write(&iter, &dict_iter) ||
19375b9c547cSRui Paulo 	    !wpa_dbus_dict_append_object_path(&dict_iter, "peer_object",
1938d4f2939cSRui Paulo 					      path) ||
1939d4f2939cSRui Paulo 	    !wpa_dbus_dict_append_uint16(&dict_iter, "update_indicator",
1940d4f2939cSRui Paulo 					 update_indic) ||
1941d4f2939cSRui Paulo 	    !wpa_dbus_dict_append_byte_array(&dict_iter, "tlvs",
1942d4f2939cSRui Paulo 					     (const char *) tlvs,
1943d4f2939cSRui Paulo 					     tlvs_len) ||
1944d4f2939cSRui Paulo 	    !wpa_dbus_dict_close_write(&iter, &dict_iter))
19455b9c547cSRui Paulo 		wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
19465b9c547cSRui Paulo 	else
1947d4f2939cSRui Paulo 		dbus_connection_send(iface->con, msg, NULL);
1948d4f2939cSRui Paulo 	dbus_message_unref(msg);
1949d4f2939cSRui Paulo }
1950d4f2939cSRui Paulo 
19515b9c547cSRui Paulo 
1952d4f2939cSRui Paulo /**
1953d4f2939cSRui Paulo  * wpas_dbus_signal_persistent_group - Send a persistent group related
1954d4f2939cSRui Paulo  *	event signal
1955d4f2939cSRui Paulo  * @wpa_s: %wpa_supplicant network interface data
1956d4f2939cSRui Paulo  * @id: new persistent group id
1957d4f2939cSRui Paulo  * @sig_name: signal name - PersistentGroupAdded, PersistentGroupRemoved
1958d4f2939cSRui Paulo  * @properties: determines if add second argument with object properties
1959d4f2939cSRui Paulo  *
1960d4f2939cSRui Paulo  * Notify listeners about an event related to persistent groups.
1961d4f2939cSRui Paulo  */
1962d4f2939cSRui Paulo static void wpas_dbus_signal_persistent_group(struct wpa_supplicant *wpa_s,
1963d4f2939cSRui Paulo 					      int id, const char *sig_name,
19644bc52338SCy Schubert 					      dbus_bool_t properties)
1965d4f2939cSRui Paulo {
1966d4f2939cSRui Paulo 	struct wpas_dbus_priv *iface;
1967d4f2939cSRui Paulo 	DBusMessage *msg;
1968d4f2939cSRui Paulo 	DBusMessageIter iter;
1969d4f2939cSRui Paulo 	char pgrp_obj_path[WPAS_DBUS_OBJECT_PATH_MAX], *path;
1970d4f2939cSRui Paulo 
1971d4f2939cSRui Paulo 	iface = wpa_s->global->dbus;
1972d4f2939cSRui Paulo 
1973d4f2939cSRui Paulo 	/* Do nothing if the control interface is not turned on */
1974d4f2939cSRui Paulo 	if (iface == NULL)
1975d4f2939cSRui Paulo 		return;
1976d4f2939cSRui Paulo 
19775b9c547cSRui Paulo 	if (wpa_s->p2p_mgmt)
19785b9c547cSRui Paulo 		wpa_s = wpa_s->parent;
1979325151a3SRui Paulo 	if (!wpa_s->dbus_new_path)
1980325151a3SRui Paulo 		return;
19815b9c547cSRui Paulo 
1982d4f2939cSRui Paulo 	os_snprintf(pgrp_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
1983d4f2939cSRui Paulo 		    "%s/" WPAS_DBUS_NEW_PERSISTENT_GROUPS_PART "/%u",
1984d4f2939cSRui Paulo 		    wpa_s->dbus_new_path, id);
1985d4f2939cSRui Paulo 
1986d4f2939cSRui Paulo 	msg = dbus_message_new_signal(wpa_s->dbus_new_path,
1987d4f2939cSRui Paulo 				      WPAS_DBUS_NEW_IFACE_P2PDEVICE,
1988d4f2939cSRui Paulo 				      sig_name);
1989d4f2939cSRui Paulo 	if (msg == NULL)
1990d4f2939cSRui Paulo 		return;
1991d4f2939cSRui Paulo 
1992d4f2939cSRui Paulo 	dbus_message_iter_init_append(msg, &iter);
1993d4f2939cSRui Paulo 	path = pgrp_obj_path;
1994d4f2939cSRui Paulo 	if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_OBJECT_PATH,
19955b9c547cSRui Paulo 					    &path) ||
19965b9c547cSRui Paulo 	    (properties &&
19975b9c547cSRui Paulo 	     !wpa_dbus_get_object_properties(
1998d4f2939cSRui Paulo 		     iface, pgrp_obj_path,
19995b9c547cSRui Paulo 		     WPAS_DBUS_NEW_IFACE_PERSISTENT_GROUP, &iter)))
20005b9c547cSRui Paulo 		wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
20015b9c547cSRui Paulo 	else
2002d4f2939cSRui Paulo 		dbus_connection_send(iface->con, msg, NULL);
2003d4f2939cSRui Paulo 
2004d4f2939cSRui Paulo 	dbus_message_unref(msg);
2005d4f2939cSRui Paulo }
2006d4f2939cSRui Paulo 
2007d4f2939cSRui Paulo 
2008d4f2939cSRui Paulo /**
2009d4f2939cSRui Paulo  * wpas_dbus_signal_persistent_group_added - Send a persistent_group
2010d4f2939cSRui Paulo  *	added signal
2011d4f2939cSRui Paulo  * @wpa_s: %wpa_supplicant network interface data
2012d4f2939cSRui Paulo  * @id: new persistent group id
2013d4f2939cSRui Paulo  *
2014d4f2939cSRui Paulo  * Notify listeners about addition of a new persistent group.
2015d4f2939cSRui Paulo  */
2016d4f2939cSRui Paulo static void wpas_dbus_signal_persistent_group_added(
2017d4f2939cSRui Paulo 	struct wpa_supplicant *wpa_s, int id)
2018d4f2939cSRui Paulo {
2019d4f2939cSRui Paulo 	wpas_dbus_signal_persistent_group(wpa_s, id, "PersistentGroupAdded",
2020d4f2939cSRui Paulo 					  TRUE);
2021d4f2939cSRui Paulo }
2022d4f2939cSRui Paulo 
2023d4f2939cSRui Paulo 
2024d4f2939cSRui Paulo /**
2025d4f2939cSRui Paulo  * wpas_dbus_signal_persistent_group_removed - Send a persistent_group
2026d4f2939cSRui Paulo  *	removed signal
2027d4f2939cSRui Paulo  * @wpa_s: %wpa_supplicant network interface data
2028d4f2939cSRui Paulo  * @id: persistent group id
2029d4f2939cSRui Paulo  *
2030d4f2939cSRui Paulo  * Notify listeners about removal of a persistent group.
2031d4f2939cSRui Paulo  */
2032d4f2939cSRui Paulo static void wpas_dbus_signal_persistent_group_removed(
2033d4f2939cSRui Paulo 	struct wpa_supplicant *wpa_s, int id)
2034d4f2939cSRui Paulo {
2035d4f2939cSRui Paulo 	wpas_dbus_signal_persistent_group(wpa_s, id, "PersistentGroupRemoved",
2036d4f2939cSRui Paulo 					  FALSE);
2037d4f2939cSRui Paulo }
2038d4f2939cSRui Paulo 
2039d4f2939cSRui Paulo 
2040d4f2939cSRui Paulo /**
2041d4f2939cSRui Paulo  * wpas_dbus_signal_p2p_wps_failed - Signals WpsFailed event
2042d4f2939cSRui Paulo  * @wpa_s: %wpa_supplicant network interface data
2043325151a3SRui Paulo  * @fail: WPS failure information
2044d4f2939cSRui Paulo  *
2045d4f2939cSRui Paulo  * Sends Event dbus signal with name "fail" and dictionary containing
2046d4f2939cSRui Paulo  * "msg" field with fail message number (int32) as arguments
2047d4f2939cSRui Paulo  */
2048d4f2939cSRui Paulo void wpas_dbus_signal_p2p_wps_failed(struct wpa_supplicant *wpa_s,
2049d4f2939cSRui Paulo 				     struct wps_event_fail *fail)
2050d4f2939cSRui Paulo {
2051d4f2939cSRui Paulo 
2052d4f2939cSRui Paulo 	DBusMessage *msg;
2053d4f2939cSRui Paulo 	DBusMessageIter iter, dict_iter;
2054d4f2939cSRui Paulo 	struct wpas_dbus_priv *iface;
2055d4f2939cSRui Paulo 	char *key = "fail";
2056d4f2939cSRui Paulo 
2057d4f2939cSRui Paulo 	iface = wpa_s->global->dbus;
2058d4f2939cSRui Paulo 
2059d4f2939cSRui Paulo 	/* Do nothing if the control interface is not turned on */
2060d4f2939cSRui Paulo 	if (iface == NULL)
2061d4f2939cSRui Paulo 		return;
2062d4f2939cSRui Paulo 
20635b9c547cSRui Paulo 	if (wpa_s->p2p_mgmt)
20645b9c547cSRui Paulo 		wpa_s = wpa_s->parent;
20655b9c547cSRui Paulo 
2066325151a3SRui Paulo 	if (!wpa_s->dbus_new_path)
2067325151a3SRui Paulo 		return;
2068d4f2939cSRui Paulo 	msg = dbus_message_new_signal(wpa_s->dbus_new_path,
2069d4f2939cSRui Paulo 				      WPAS_DBUS_NEW_IFACE_P2PDEVICE,
2070d4f2939cSRui Paulo 				      "WpsFailed");
2071d4f2939cSRui Paulo 	if (msg == NULL)
2072d4f2939cSRui Paulo 		return;
2073d4f2939cSRui Paulo 
2074d4f2939cSRui Paulo 	dbus_message_iter_init_append(msg, &iter);
2075d4f2939cSRui Paulo 
2076d4f2939cSRui Paulo 	if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &key) ||
2077d4f2939cSRui Paulo 	    !wpa_dbus_dict_open_write(&iter, &dict_iter) ||
2078d4f2939cSRui Paulo 	    !wpa_dbus_dict_append_int32(&dict_iter, "msg", fail->msg) ||
2079d4f2939cSRui Paulo 	    !wpa_dbus_dict_append_int16(&dict_iter, "config_error",
2080d4f2939cSRui Paulo 					fail->config_error) ||
2081d4f2939cSRui Paulo 	    !wpa_dbus_dict_close_write(&iter, &dict_iter))
2082d4f2939cSRui Paulo 		wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
2083d4f2939cSRui Paulo 	else
2084d4f2939cSRui Paulo 		dbus_connection_send(iface->con, msg, NULL);
2085d4f2939cSRui Paulo 
2086d4f2939cSRui Paulo 	dbus_message_unref(msg);
2087d4f2939cSRui Paulo }
2088d4f2939cSRui Paulo 
2089325151a3SRui Paulo 
2090325151a3SRui Paulo /**
2091325151a3SRui Paulo  * wpas_dbus_signal_p2p_group_formation_failure - Signals GroupFormationFailure event
2092325151a3SRui Paulo  * @wpa_s: %wpa_supplicant network interface data
2093325151a3SRui Paulo  * @reason: indicates the reason code for group formation failure
2094325151a3SRui Paulo  *
2095325151a3SRui Paulo  * Sends Event dbus signal and string reason code when available.
2096325151a3SRui Paulo  */
2097325151a3SRui Paulo void wpas_dbus_signal_p2p_group_formation_failure(struct wpa_supplicant *wpa_s,
2098325151a3SRui Paulo 						  const char *reason)
2099325151a3SRui Paulo {
2100325151a3SRui Paulo 	DBusMessage *msg;
2101325151a3SRui Paulo 	struct wpas_dbus_priv *iface;
2102325151a3SRui Paulo 
2103325151a3SRui Paulo 	iface = wpa_s->global->dbus;
2104325151a3SRui Paulo 
2105325151a3SRui Paulo 	/* Do nothing if the control interface is not turned on */
2106325151a3SRui Paulo 	if (iface == NULL)
2107325151a3SRui Paulo 		return;
2108325151a3SRui Paulo 
210985732ac8SCy Schubert 	if (wpa_s->p2p_mgmt)
211085732ac8SCy Schubert 		wpa_s = wpa_s->parent;
211185732ac8SCy Schubert 
2112325151a3SRui Paulo 	msg = dbus_message_new_signal(wpa_s->dbus_new_path,
2113325151a3SRui Paulo 				      WPAS_DBUS_NEW_IFACE_P2PDEVICE,
2114325151a3SRui Paulo 				      "GroupFormationFailure");
2115325151a3SRui Paulo 	if (msg == NULL)
2116325151a3SRui Paulo 		return;
2117325151a3SRui Paulo 
2118325151a3SRui Paulo 	if (dbus_message_append_args(msg, DBUS_TYPE_STRING, &reason,
2119325151a3SRui Paulo 				     DBUS_TYPE_INVALID))
2120325151a3SRui Paulo 		dbus_connection_send(iface->con, msg, NULL);
2121325151a3SRui Paulo 	else
2122325151a3SRui Paulo 		wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
2123325151a3SRui Paulo 
2124325151a3SRui Paulo 	dbus_message_unref(msg);
2125325151a3SRui Paulo }
2126325151a3SRui Paulo 
2127325151a3SRui Paulo 
2128325151a3SRui Paulo /**
2129325151a3SRui Paulo  * wpas_dbus_signal_p2p_invitation_received - Emit InvitationReceived signal
2130325151a3SRui Paulo  * @wpa_s: %wpa_supplicant network interface data
2131325151a3SRui Paulo  * @sa: Source address of the Invitation Request
2132325151a3SRui Paulo  * @dev_add: GO Device Address
2133325151a3SRui Paulo  * @bssid: P2P Group BSSID or %NULL if not received
2134325151a3SRui Paulo  * @id: Persistent group id or %0 if not persistent group
2135325151a3SRui Paulo  * @op_freq: Operating frequency for the group
2136325151a3SRui Paulo  */
2137325151a3SRui Paulo 
2138325151a3SRui Paulo void wpas_dbus_signal_p2p_invitation_received(struct wpa_supplicant *wpa_s,
2139325151a3SRui Paulo 					      const u8 *sa, const u8 *dev_addr,
2140325151a3SRui Paulo 					      const u8 *bssid, int id,
2141325151a3SRui Paulo 					      int op_freq)
2142325151a3SRui Paulo {
2143325151a3SRui Paulo 	DBusMessage *msg;
2144325151a3SRui Paulo 	DBusMessageIter iter, dict_iter;
2145325151a3SRui Paulo 	struct wpas_dbus_priv *iface;
2146325151a3SRui Paulo 
2147325151a3SRui Paulo 	iface = wpa_s->global->dbus;
2148325151a3SRui Paulo 
2149325151a3SRui Paulo 	/* Do nothing if the control interface is not turned on */
2150325151a3SRui Paulo 	if (iface == NULL)
2151325151a3SRui Paulo 		return;
2152325151a3SRui Paulo 
215385732ac8SCy Schubert 	if (wpa_s->p2p_mgmt)
215485732ac8SCy Schubert 		wpa_s = wpa_s->parent;
215585732ac8SCy Schubert 
2156325151a3SRui Paulo 	msg = dbus_message_new_signal(wpa_s->dbus_new_path,
2157325151a3SRui Paulo 				      WPAS_DBUS_NEW_IFACE_P2PDEVICE,
2158325151a3SRui Paulo 				      "InvitationReceived");
2159325151a3SRui Paulo 	if (msg == NULL)
2160325151a3SRui Paulo 		return;
2161325151a3SRui Paulo 
2162325151a3SRui Paulo 	dbus_message_iter_init_append(msg, &iter);
2163325151a3SRui Paulo 	if (!wpa_dbus_dict_open_write(&iter, &dict_iter) ||
2164325151a3SRui Paulo 	    (sa &&
2165325151a3SRui Paulo 	     !wpa_dbus_dict_append_byte_array(&dict_iter, "sa",
2166325151a3SRui Paulo 					      (const char *) sa, ETH_ALEN)) ||
2167325151a3SRui Paulo 	    (dev_addr &&
2168325151a3SRui Paulo 	     !wpa_dbus_dict_append_byte_array(&dict_iter, "go_dev_addr",
2169325151a3SRui Paulo 					      (const char *) dev_addr,
2170325151a3SRui Paulo 					      ETH_ALEN)) ||
2171325151a3SRui Paulo 	    (bssid &&
2172325151a3SRui Paulo 	     !wpa_dbus_dict_append_byte_array(&dict_iter, "bssid",
2173325151a3SRui Paulo 					      (const char *) bssid,
2174325151a3SRui Paulo 					      ETH_ALEN)) ||
2175325151a3SRui Paulo 	    (id &&
2176325151a3SRui Paulo 	     !wpa_dbus_dict_append_int32(&dict_iter, "persistent_id", id)) ||
2177325151a3SRui Paulo 	    !wpa_dbus_dict_append_int32(&dict_iter, "op_freq", op_freq) ||
2178325151a3SRui Paulo 	    !wpa_dbus_dict_close_write(&iter, &dict_iter)) {
2179325151a3SRui Paulo 		dbus_message_unref(msg);
2180325151a3SRui Paulo 		return;
2181325151a3SRui Paulo 	}
2182325151a3SRui Paulo 
2183325151a3SRui Paulo 	dbus_connection_send(iface->con, msg, NULL);
2184780fb4a2SCy Schubert 	dbus_message_unref(msg);
2185325151a3SRui Paulo }
2186325151a3SRui Paulo 
2187325151a3SRui Paulo 
2188d4f2939cSRui Paulo #endif /* CONFIG_P2P */
2189d4f2939cSRui Paulo 
2190d4f2939cSRui Paulo 
2191d4f2939cSRui Paulo /**
2192d4f2939cSRui Paulo  * wpas_dbus_signal_prop_changed - Signals change of property
2193d4f2939cSRui Paulo  * @wpa_s: %wpa_supplicant network interface data
2194d4f2939cSRui Paulo  * @property: indicates which property has changed
2195d4f2939cSRui Paulo  *
2196d4f2939cSRui Paulo  * Sends PropertyChanged signals with path, interface and arguments
2197d4f2939cSRui Paulo  * depending on which property has changed.
2198d4f2939cSRui Paulo  */
2199d4f2939cSRui Paulo void wpas_dbus_signal_prop_changed(struct wpa_supplicant *wpa_s,
2200d4f2939cSRui Paulo 				   enum wpas_dbus_prop property)
2201d4f2939cSRui Paulo {
2202d4f2939cSRui Paulo 	char *prop;
2203d4f2939cSRui Paulo 	dbus_bool_t flush;
2204d4f2939cSRui Paulo 
2205d4f2939cSRui Paulo 	if (wpa_s->dbus_new_path == NULL)
2206d4f2939cSRui Paulo 		return; /* Skip signal since D-Bus setup is not yet ready */
2207d4f2939cSRui Paulo 
2208d4f2939cSRui Paulo 	flush = FALSE;
2209d4f2939cSRui Paulo 	switch (property) {
2210d4f2939cSRui Paulo 	case WPAS_DBUS_PROP_AP_SCAN:
2211d4f2939cSRui Paulo 		prop = "ApScan";
2212d4f2939cSRui Paulo 		break;
2213d4f2939cSRui Paulo 	case WPAS_DBUS_PROP_SCANNING:
2214d4f2939cSRui Paulo 		prop = "Scanning";
2215d4f2939cSRui Paulo 		break;
2216d4f2939cSRui Paulo 	case WPAS_DBUS_PROP_STATE:
2217d4f2939cSRui Paulo 		prop = "State";
2218d4f2939cSRui Paulo 		break;
2219d4f2939cSRui Paulo 	case WPAS_DBUS_PROP_CURRENT_BSS:
2220d4f2939cSRui Paulo 		prop = "CurrentBSS";
2221d4f2939cSRui Paulo 		break;
2222d4f2939cSRui Paulo 	case WPAS_DBUS_PROP_CURRENT_NETWORK:
2223d4f2939cSRui Paulo 		prop = "CurrentNetwork";
2224d4f2939cSRui Paulo 		break;
2225d4f2939cSRui Paulo 	case WPAS_DBUS_PROP_BSSS:
2226d4f2939cSRui Paulo 		prop = "BSSs";
2227d4f2939cSRui Paulo 		break;
22284bc52338SCy Schubert 	case WPAS_DBUS_PROP_STATIONS:
22294bc52338SCy Schubert 		prop = "Stations";
22304bc52338SCy Schubert 		break;
2231d4f2939cSRui Paulo 	case WPAS_DBUS_PROP_CURRENT_AUTH_MODE:
2232d4f2939cSRui Paulo 		prop = "CurrentAuthMode";
2233d4f2939cSRui Paulo 		break;
2234d4f2939cSRui Paulo 	case WPAS_DBUS_PROP_DISCONNECT_REASON:
2235d4f2939cSRui Paulo 		prop = "DisconnectReason";
2236d4f2939cSRui Paulo 		flush = TRUE;
2237d4f2939cSRui Paulo 		break;
22384bc52338SCy Schubert 	case WPAS_DBUS_PROP_AUTH_STATUS_CODE:
22394bc52338SCy Schubert 		prop = "AuthStatusCode";
22404bc52338SCy Schubert 		flush = TRUE;
22414bc52338SCy Schubert 		break;
2242780fb4a2SCy Schubert 	case WPAS_DBUS_PROP_ASSOC_STATUS_CODE:
2243780fb4a2SCy Schubert 		prop = "AssocStatusCode";
2244780fb4a2SCy Schubert 		flush = TRUE;
2245780fb4a2SCy Schubert 		break;
22464bc52338SCy Schubert 	case WPAS_DBUS_PROP_ROAM_TIME:
22474bc52338SCy Schubert 		prop = "RoamTime";
22484bc52338SCy Schubert 		break;
22494bc52338SCy Schubert 	case WPAS_DBUS_PROP_ROAM_COMPLETE:
22504bc52338SCy Schubert 		prop = "RoamComplete";
22514bc52338SCy Schubert 		break;
22524bc52338SCy Schubert 	case WPAS_DBUS_PROP_SESSION_LENGTH:
22534bc52338SCy Schubert 		prop = "SessionLength";
22544bc52338SCy Schubert 		break;
22554bc52338SCy Schubert 	case WPAS_DBUS_PROP_BSS_TM_STATUS:
22564bc52338SCy Schubert 		prop = "BSSTMStatus";
22574bc52338SCy Schubert 		break;
2258d4f2939cSRui Paulo 	default:
2259d4f2939cSRui Paulo 		wpa_printf(MSG_ERROR, "dbus: %s: Unknown Property value %d",
2260d4f2939cSRui Paulo 			   __func__, property);
2261d4f2939cSRui Paulo 		return;
2262d4f2939cSRui Paulo 	}
2263d4f2939cSRui Paulo 
2264d4f2939cSRui Paulo 	wpa_dbus_mark_property_changed(wpa_s->global->dbus,
2265d4f2939cSRui Paulo 				       wpa_s->dbus_new_path,
2266d4f2939cSRui Paulo 				       WPAS_DBUS_NEW_IFACE_INTERFACE, prop);
2267d4f2939cSRui Paulo 	if (flush) {
2268d4f2939cSRui Paulo 		wpa_dbus_flush_object_changed_properties(
2269d4f2939cSRui Paulo 			wpa_s->global->dbus->con, wpa_s->dbus_new_path);
2270d4f2939cSRui Paulo 	}
2271d4f2939cSRui Paulo }
2272d4f2939cSRui Paulo 
2273d4f2939cSRui Paulo 
2274d4f2939cSRui Paulo /**
2275d4f2939cSRui Paulo  * wpas_dbus_bss_signal_prop_changed - Signals change of BSS property
2276d4f2939cSRui Paulo  * @wpa_s: %wpa_supplicant network interface data
2277d4f2939cSRui Paulo  * @property: indicates which property has changed
2278d4f2939cSRui Paulo  * @id: unique BSS identifier
2279d4f2939cSRui Paulo  *
2280d4f2939cSRui Paulo  * Sends PropertyChanged signals with path, interface, and arguments depending
2281d4f2939cSRui Paulo  * on which property has changed.
2282d4f2939cSRui Paulo  */
2283d4f2939cSRui Paulo void wpas_dbus_bss_signal_prop_changed(struct wpa_supplicant *wpa_s,
2284d4f2939cSRui Paulo 				       enum wpas_dbus_bss_prop property,
2285d4f2939cSRui Paulo 				       unsigned int id)
2286d4f2939cSRui Paulo {
2287d4f2939cSRui Paulo 	char path[WPAS_DBUS_OBJECT_PATH_MAX];
2288d4f2939cSRui Paulo 	char *prop;
2289d4f2939cSRui Paulo 
2290325151a3SRui Paulo 	if (!wpa_s->dbus_new_path)
2291325151a3SRui Paulo 		return;
2292325151a3SRui Paulo 
2293d4f2939cSRui Paulo 	switch (property) {
2294d4f2939cSRui Paulo 	case WPAS_DBUS_BSS_PROP_SIGNAL:
2295d4f2939cSRui Paulo 		prop = "Signal";
2296d4f2939cSRui Paulo 		break;
2297d4f2939cSRui Paulo 	case WPAS_DBUS_BSS_PROP_FREQ:
2298d4f2939cSRui Paulo 		prop = "Frequency";
2299d4f2939cSRui Paulo 		break;
2300d4f2939cSRui Paulo 	case WPAS_DBUS_BSS_PROP_MODE:
2301d4f2939cSRui Paulo 		prop = "Mode";
2302d4f2939cSRui Paulo 		break;
2303d4f2939cSRui Paulo 	case WPAS_DBUS_BSS_PROP_PRIVACY:
2304d4f2939cSRui Paulo 		prop = "Privacy";
2305d4f2939cSRui Paulo 		break;
2306d4f2939cSRui Paulo 	case WPAS_DBUS_BSS_PROP_RATES:
2307d4f2939cSRui Paulo 		prop = "Rates";
2308d4f2939cSRui Paulo 		break;
2309d4f2939cSRui Paulo 	case WPAS_DBUS_BSS_PROP_WPA:
2310d4f2939cSRui Paulo 		prop = "WPA";
2311d4f2939cSRui Paulo 		break;
2312d4f2939cSRui Paulo 	case WPAS_DBUS_BSS_PROP_RSN:
2313d4f2939cSRui Paulo 		prop = "RSN";
2314d4f2939cSRui Paulo 		break;
23155b9c547cSRui Paulo 	case WPAS_DBUS_BSS_PROP_WPS:
23165b9c547cSRui Paulo 		prop = "WPS";
23175b9c547cSRui Paulo 		break;
2318d4f2939cSRui Paulo 	case WPAS_DBUS_BSS_PROP_IES:
2319d4f2939cSRui Paulo 		prop = "IEs";
2320d4f2939cSRui Paulo 		break;
23215b9c547cSRui Paulo 	case WPAS_DBUS_BSS_PROP_AGE:
23225b9c547cSRui Paulo 		prop = "Age";
23235b9c547cSRui Paulo 		break;
2324d4f2939cSRui Paulo 	default:
2325d4f2939cSRui Paulo 		wpa_printf(MSG_ERROR, "dbus: %s: Unknown Property value %d",
2326d4f2939cSRui Paulo 			   __func__, property);
2327d4f2939cSRui Paulo 		return;
2328d4f2939cSRui Paulo 	}
2329d4f2939cSRui Paulo 
2330d4f2939cSRui Paulo 	os_snprintf(path, WPAS_DBUS_OBJECT_PATH_MAX,
2331d4f2939cSRui Paulo 		    "%s/" WPAS_DBUS_NEW_BSSIDS_PART "/%u",
2332d4f2939cSRui Paulo 		    wpa_s->dbus_new_path, id);
2333d4f2939cSRui Paulo 
2334d4f2939cSRui Paulo 	wpa_dbus_mark_property_changed(wpa_s->global->dbus, path,
2335d4f2939cSRui Paulo 				       WPAS_DBUS_NEW_IFACE_BSS, prop);
2336d4f2939cSRui Paulo }
2337d4f2939cSRui Paulo 
2338d4f2939cSRui Paulo 
2339d4f2939cSRui Paulo /**
23404bc52338SCy Schubert  * wpas_dbus_sta_signal_prop_changed - Signals change of STA property
23414bc52338SCy Schubert  * @wpa_s: %wpa_supplicant network interface data
23424bc52338SCy Schubert  * @property: indicates which property has changed
23434bc52338SCy Schubert  * @address: unique BSS identifier
23444bc52338SCy Schubert  *
23454bc52338SCy Schubert  * Sends PropertyChanged signals with path, interface, and arguments depending
23464bc52338SCy Schubert  * on which property has changed.
23474bc52338SCy Schubert  */
23484bc52338SCy Schubert void wpas_dbus_sta_signal_prop_changed(struct wpa_supplicant *wpa_s,
23494bc52338SCy Schubert 				       enum wpas_dbus_bss_prop property,
23504bc52338SCy Schubert 				       u8 address[ETH_ALEN])
23514bc52338SCy Schubert {
23524bc52338SCy Schubert 	char path[WPAS_DBUS_OBJECT_PATH_MAX];
23534bc52338SCy Schubert 	char *prop;
23544bc52338SCy Schubert 
23554bc52338SCy Schubert 	switch (property) {
23564bc52338SCy Schubert 	case WPAS_DBUS_STA_PROP_ADDRESS:
23574bc52338SCy Schubert 		prop = "Address";
23584bc52338SCy Schubert 		break;
23594bc52338SCy Schubert 	default:
23604bc52338SCy Schubert 		wpa_printf(MSG_ERROR, "dbus: %s: Unknown Property value %d",
23614bc52338SCy Schubert 			   __func__, property);
23624bc52338SCy Schubert 		return;
23634bc52338SCy Schubert 	}
23644bc52338SCy Schubert 
23654bc52338SCy Schubert 	os_snprintf(path, WPAS_DBUS_OBJECT_PATH_MAX,
23664bc52338SCy Schubert 		    "%s/" WPAS_DBUS_NEW_STAS_PART "/" COMPACT_MACSTR,
23674bc52338SCy Schubert 		    wpa_s->dbus_new_path, MAC2STR(address));
23684bc52338SCy Schubert 
23694bc52338SCy Schubert 	wpa_dbus_mark_property_changed(wpa_s->global->dbus, path,
23704bc52338SCy Schubert 				       WPAS_DBUS_NEW_IFACE_STA, prop);
23714bc52338SCy Schubert }
23724bc52338SCy Schubert 
23734bc52338SCy Schubert 
23744bc52338SCy Schubert /**
2375d4f2939cSRui Paulo  * wpas_dbus_signal_debug_level_changed - Signals change of debug param
2376d4f2939cSRui Paulo  * @global: wpa_global structure
2377d4f2939cSRui Paulo  *
2378d4f2939cSRui Paulo  * Sends PropertyChanged signals informing that debug level has changed.
2379d4f2939cSRui Paulo  */
2380d4f2939cSRui Paulo void wpas_dbus_signal_debug_level_changed(struct wpa_global *global)
2381d4f2939cSRui Paulo {
2382d4f2939cSRui Paulo 	wpa_dbus_mark_property_changed(global->dbus, WPAS_DBUS_NEW_PATH,
2383d4f2939cSRui Paulo 				       WPAS_DBUS_NEW_INTERFACE,
2384d4f2939cSRui Paulo 				       "DebugLevel");
2385d4f2939cSRui Paulo }
2386d4f2939cSRui Paulo 
2387d4f2939cSRui Paulo 
2388d4f2939cSRui Paulo /**
2389d4f2939cSRui Paulo  * wpas_dbus_signal_debug_timestamp_changed - Signals change of debug param
2390d4f2939cSRui Paulo  * @global: wpa_global structure
2391d4f2939cSRui Paulo  *
2392d4f2939cSRui Paulo  * Sends PropertyChanged signals informing that debug timestamp has changed.
2393d4f2939cSRui Paulo  */
2394d4f2939cSRui Paulo void wpas_dbus_signal_debug_timestamp_changed(struct wpa_global *global)
2395d4f2939cSRui Paulo {
2396d4f2939cSRui Paulo 	wpa_dbus_mark_property_changed(global->dbus, WPAS_DBUS_NEW_PATH,
2397d4f2939cSRui Paulo 				       WPAS_DBUS_NEW_INTERFACE,
2398d4f2939cSRui Paulo 				       "DebugTimestamp");
2399d4f2939cSRui Paulo }
2400d4f2939cSRui Paulo 
2401d4f2939cSRui Paulo 
2402d4f2939cSRui Paulo /**
2403d4f2939cSRui Paulo  * wpas_dbus_signal_debug_show_keys_changed - Signals change of debug param
2404d4f2939cSRui Paulo  * @global: wpa_global structure
2405d4f2939cSRui Paulo  *
2406d4f2939cSRui Paulo  * Sends PropertyChanged signals informing that debug show_keys has changed.
2407d4f2939cSRui Paulo  */
2408d4f2939cSRui Paulo void wpas_dbus_signal_debug_show_keys_changed(struct wpa_global *global)
2409d4f2939cSRui Paulo {
2410d4f2939cSRui Paulo 	wpa_dbus_mark_property_changed(global->dbus, WPAS_DBUS_NEW_PATH,
2411d4f2939cSRui Paulo 				       WPAS_DBUS_NEW_INTERFACE,
2412d4f2939cSRui Paulo 				       "DebugShowKeys");
2413d4f2939cSRui Paulo }
2414d4f2939cSRui Paulo 
2415d4f2939cSRui Paulo 
2416d4f2939cSRui Paulo static void wpas_dbus_register(struct wpa_dbus_object_desc *obj_desc,
2417d4f2939cSRui Paulo 			       void *priv,
2418d4f2939cSRui Paulo 			       WPADBusArgumentFreeFunction priv_free,
2419d4f2939cSRui Paulo 			       const struct wpa_dbus_method_desc *methods,
2420d4f2939cSRui Paulo 			       const struct wpa_dbus_property_desc *properties,
2421d4f2939cSRui Paulo 			       const struct wpa_dbus_signal_desc *signals)
2422d4f2939cSRui Paulo {
2423d4f2939cSRui Paulo 	int n;
2424d4f2939cSRui Paulo 
2425d4f2939cSRui Paulo 	obj_desc->user_data = priv;
2426d4f2939cSRui Paulo 	obj_desc->user_data_free_func = priv_free;
2427d4f2939cSRui Paulo 	obj_desc->methods = methods;
2428d4f2939cSRui Paulo 	obj_desc->properties = properties;
2429d4f2939cSRui Paulo 	obj_desc->signals = signals;
2430d4f2939cSRui Paulo 
2431d4f2939cSRui Paulo 	for (n = 0; properties && properties->dbus_property; properties++)
2432d4f2939cSRui Paulo 		n++;
2433d4f2939cSRui Paulo 
2434d4f2939cSRui Paulo 	obj_desc->prop_changed_flags = os_zalloc(n);
2435d4f2939cSRui Paulo 	if (!obj_desc->prop_changed_flags)
2436d4f2939cSRui Paulo 		wpa_printf(MSG_DEBUG, "dbus: %s: can't register handlers",
2437d4f2939cSRui Paulo 			   __func__);
2438d4f2939cSRui Paulo }
2439d4f2939cSRui Paulo 
2440d4f2939cSRui Paulo 
2441d4f2939cSRui Paulo static const struct wpa_dbus_method_desc wpas_dbus_global_methods[] = {
2442d4f2939cSRui Paulo 	{ "CreateInterface", WPAS_DBUS_NEW_INTERFACE,
24435b9c547cSRui Paulo 	  (WPADBusMethodHandler) wpas_dbus_handler_create_interface,
2444d4f2939cSRui Paulo 	  {
2445d4f2939cSRui Paulo 		  { "args", "a{sv}", ARG_IN },
2446d4f2939cSRui Paulo 		  { "path", "o", ARG_OUT },
2447d4f2939cSRui Paulo 		  END_ARGS
2448d4f2939cSRui Paulo 	  }
2449d4f2939cSRui Paulo 	},
2450d4f2939cSRui Paulo 	{ "RemoveInterface", WPAS_DBUS_NEW_INTERFACE,
24515b9c547cSRui Paulo 	  (WPADBusMethodHandler) wpas_dbus_handler_remove_interface,
2452d4f2939cSRui Paulo 	  {
2453d4f2939cSRui Paulo 		  { "path", "o", ARG_IN },
2454d4f2939cSRui Paulo 		  END_ARGS
2455d4f2939cSRui Paulo 	  }
2456d4f2939cSRui Paulo 	},
2457d4f2939cSRui Paulo 	{ "GetInterface", WPAS_DBUS_NEW_INTERFACE,
24585b9c547cSRui Paulo 	  (WPADBusMethodHandler) wpas_dbus_handler_get_interface,
2459d4f2939cSRui Paulo 	  {
2460d4f2939cSRui Paulo 		  { "ifname", "s", ARG_IN },
2461d4f2939cSRui Paulo 		  { "path", "o", ARG_OUT },
2462d4f2939cSRui Paulo 		  END_ARGS
2463d4f2939cSRui Paulo 	  }
2464d4f2939cSRui Paulo 	},
2465780fb4a2SCy Schubert 	{ "ExpectDisconnect", WPAS_DBUS_NEW_INTERFACE,
2466780fb4a2SCy Schubert 	  (WPADBusMethodHandler) wpas_dbus_handler_expect_disconnect,
2467780fb4a2SCy Schubert 	  {
2468780fb4a2SCy Schubert 		END_ARGS
2469780fb4a2SCy Schubert 	  }
2470780fb4a2SCy Schubert 	},
2471d4f2939cSRui Paulo 	{ NULL, NULL, NULL, { END_ARGS } }
2472d4f2939cSRui Paulo };
2473d4f2939cSRui Paulo 
2474d4f2939cSRui Paulo static const struct wpa_dbus_property_desc wpas_dbus_global_properties[] = {
2475d4f2939cSRui Paulo 	{ "DebugLevel", WPAS_DBUS_NEW_INTERFACE, "s",
2476d4f2939cSRui Paulo 	  wpas_dbus_getter_debug_level,
2477780fb4a2SCy Schubert 	  wpas_dbus_setter_debug_level,
2478780fb4a2SCy Schubert 	  NULL
2479d4f2939cSRui Paulo 	},
2480d4f2939cSRui Paulo 	{ "DebugTimestamp", WPAS_DBUS_NEW_INTERFACE, "b",
2481d4f2939cSRui Paulo 	  wpas_dbus_getter_debug_timestamp,
2482780fb4a2SCy Schubert 	  wpas_dbus_setter_debug_timestamp,
2483780fb4a2SCy Schubert 	  NULL
2484d4f2939cSRui Paulo 	},
2485d4f2939cSRui Paulo 	{ "DebugShowKeys", WPAS_DBUS_NEW_INTERFACE, "b",
2486d4f2939cSRui Paulo 	  wpas_dbus_getter_debug_show_keys,
2487780fb4a2SCy Schubert 	  wpas_dbus_setter_debug_show_keys,
2488780fb4a2SCy Schubert 	  NULL
2489d4f2939cSRui Paulo 	},
2490d4f2939cSRui Paulo 	{ "Interfaces", WPAS_DBUS_NEW_INTERFACE, "ao",
2491d4f2939cSRui Paulo 	  wpas_dbus_getter_interfaces,
2492780fb4a2SCy Schubert 	  NULL,
2493d4f2939cSRui Paulo 	  NULL
2494d4f2939cSRui Paulo 	},
2495d4f2939cSRui Paulo 	{ "EapMethods", WPAS_DBUS_NEW_INTERFACE, "as",
2496d4f2939cSRui Paulo 	  wpas_dbus_getter_eap_methods,
2497780fb4a2SCy Schubert 	  NULL,
2498d4f2939cSRui Paulo 	  NULL
2499d4f2939cSRui Paulo 	},
2500d4f2939cSRui Paulo 	{ "Capabilities", WPAS_DBUS_NEW_INTERFACE, "as",
2501d4f2939cSRui Paulo 	  wpas_dbus_getter_global_capabilities,
2502780fb4a2SCy Schubert 	  NULL,
2503d4f2939cSRui Paulo 	  NULL
2504d4f2939cSRui Paulo 	},
25055b9c547cSRui Paulo #ifdef CONFIG_WIFI_DISPLAY
25065b9c547cSRui Paulo 	{ "WFDIEs", WPAS_DBUS_NEW_INTERFACE, "ay",
25075b9c547cSRui Paulo 	  wpas_dbus_getter_global_wfd_ies,
2508780fb4a2SCy Schubert 	  wpas_dbus_setter_global_wfd_ies,
2509780fb4a2SCy Schubert 	  NULL
25105b9c547cSRui Paulo 	},
25115b9c547cSRui Paulo #endif /* CONFIG_WIFI_DISPLAY */
2512780fb4a2SCy Schubert 	{ NULL, NULL, NULL, NULL, NULL, NULL }
2513d4f2939cSRui Paulo };
2514d4f2939cSRui Paulo 
2515d4f2939cSRui Paulo static const struct wpa_dbus_signal_desc wpas_dbus_global_signals[] = {
2516d4f2939cSRui Paulo 	{ "InterfaceAdded", WPAS_DBUS_NEW_INTERFACE,
2517d4f2939cSRui Paulo 	  {
2518d4f2939cSRui Paulo 		  { "path", "o", ARG_OUT },
2519d4f2939cSRui Paulo 		  { "properties", "a{sv}", ARG_OUT },
2520d4f2939cSRui Paulo 		  END_ARGS
2521d4f2939cSRui Paulo 	  }
2522d4f2939cSRui Paulo 	},
2523d4f2939cSRui Paulo 	{ "InterfaceRemoved", WPAS_DBUS_NEW_INTERFACE,
2524d4f2939cSRui Paulo 	  {
2525d4f2939cSRui Paulo 		  { "path", "o", ARG_OUT },
2526d4f2939cSRui Paulo 		  END_ARGS
2527d4f2939cSRui Paulo 	  }
2528d4f2939cSRui Paulo 	},
2529d4f2939cSRui Paulo 	/* Deprecated: use org.freedesktop.DBus.Properties.PropertiesChanged */
2530d4f2939cSRui Paulo 	{ "PropertiesChanged", WPAS_DBUS_NEW_INTERFACE,
2531d4f2939cSRui Paulo 	  {
2532d4f2939cSRui Paulo 		  { "properties", "a{sv}", ARG_OUT },
2533d4f2939cSRui Paulo 		  END_ARGS
2534d4f2939cSRui Paulo 	  }
2535d4f2939cSRui Paulo 	},
2536d4f2939cSRui Paulo 	{ NULL, NULL, { END_ARGS } }
2537d4f2939cSRui Paulo };
2538d4f2939cSRui Paulo 
2539d4f2939cSRui Paulo 
2540780fb4a2SCy Schubert static char * uscore_to_dbus(const char *uscore)
2541780fb4a2SCy Schubert {
2542780fb4a2SCy Schubert 	const char *p = uscore;
2543780fb4a2SCy Schubert 	char *str, *s;
2544780fb4a2SCy Schubert 	dbus_bool_t last_was_uscore = TRUE;
2545780fb4a2SCy Schubert 
2546780fb4a2SCy Schubert 	s = str = os_zalloc(os_strlen(uscore) + 1);
2547780fb4a2SCy Schubert 	if (!str)
2548780fb4a2SCy Schubert 		return NULL;
2549780fb4a2SCy Schubert 	while (p && *p) {
2550780fb4a2SCy Schubert 		if (*p == '_') {
2551780fb4a2SCy Schubert 			last_was_uscore = TRUE;
2552780fb4a2SCy Schubert 		} else {
2553780fb4a2SCy Schubert 			*s++ = last_was_uscore ? toupper(*p) : *p;
2554780fb4a2SCy Schubert 			last_was_uscore = FALSE;
2555780fb4a2SCy Schubert 		}
2556780fb4a2SCy Schubert 		p++;
2557780fb4a2SCy Schubert 	}
2558780fb4a2SCy Schubert 
2559780fb4a2SCy Schubert 	return str;
2560780fb4a2SCy Schubert }
2561780fb4a2SCy Schubert 
2562780fb4a2SCy Schubert 
2563780fb4a2SCy Schubert static int wpa_dbus_ctrl_iface_props_init(struct wpas_dbus_priv *priv);
2564780fb4a2SCy Schubert 
2565780fb4a2SCy Schubert 
2566780fb4a2SCy Schubert static void wpa_dbus_ctrl_iface_props_deinit(struct wpas_dbus_priv *priv)
2567780fb4a2SCy Schubert {
2568780fb4a2SCy Schubert 	int idx = priv->globals_start;
2569780fb4a2SCy Schubert 
2570780fb4a2SCy Schubert 	/* Free all allocated property values */
2571780fb4a2SCy Schubert 	while (priv->all_interface_properties[idx].dbus_property)
2572780fb4a2SCy Schubert 		os_free((char *)
2573780fb4a2SCy Schubert 			priv->all_interface_properties[idx++].dbus_property);
2574780fb4a2SCy Schubert 	os_free((char *) priv->all_interface_properties);
2575780fb4a2SCy Schubert }
2576780fb4a2SCy Schubert 
2577780fb4a2SCy Schubert 
2578d4f2939cSRui Paulo /**
2579d4f2939cSRui Paulo  * wpas_dbus_ctrl_iface_init - Initialize dbus control interface
2580d4f2939cSRui Paulo  * @global: Pointer to global data from wpa_supplicant_init()
2581d4f2939cSRui Paulo  * Returns: 0 on success or -1 on failure
2582d4f2939cSRui Paulo  *
2583780fb4a2SCy Schubert  * Initialize the dbus control interface for wpa_supplicant and start
2584d4f2939cSRui Paulo  * receiving commands from external programs over the bus.
2585d4f2939cSRui Paulo  */
2586d4f2939cSRui Paulo int wpas_dbus_ctrl_iface_init(struct wpas_dbus_priv *priv)
2587d4f2939cSRui Paulo {
2588d4f2939cSRui Paulo 	struct wpa_dbus_object_desc *obj_desc;
2589d4f2939cSRui Paulo 	int ret;
2590d4f2939cSRui Paulo 
2591780fb4a2SCy Schubert 	ret = wpa_dbus_ctrl_iface_props_init(priv);
2592780fb4a2SCy Schubert 	if (ret < 0) {
2593780fb4a2SCy Schubert 		wpa_printf(MSG_ERROR,
2594780fb4a2SCy Schubert 			   "dbus: Not enough memory to init interface properties");
2595780fb4a2SCy Schubert 		return -1;
2596780fb4a2SCy Schubert 	}
2597780fb4a2SCy Schubert 
2598d4f2939cSRui Paulo 	obj_desc = os_zalloc(sizeof(struct wpa_dbus_object_desc));
2599d4f2939cSRui Paulo 	if (!obj_desc) {
26005b9c547cSRui Paulo 		wpa_printf(MSG_ERROR,
26015b9c547cSRui Paulo 			   "Not enough memory to create object description");
2602780fb4a2SCy Schubert 		goto error;
2603d4f2939cSRui Paulo 	}
2604d4f2939cSRui Paulo 
2605d4f2939cSRui Paulo 	wpas_dbus_register(obj_desc, priv->global, NULL,
2606d4f2939cSRui Paulo 			   wpas_dbus_global_methods,
2607d4f2939cSRui Paulo 			   wpas_dbus_global_properties,
2608d4f2939cSRui Paulo 			   wpas_dbus_global_signals);
2609d4f2939cSRui Paulo 
2610d4f2939cSRui Paulo 	wpa_printf(MSG_DEBUG, "dbus: Register D-Bus object '%s'",
2611d4f2939cSRui Paulo 		   WPAS_DBUS_NEW_PATH);
2612d4f2939cSRui Paulo 	ret = wpa_dbus_ctrl_iface_init(priv, WPAS_DBUS_NEW_PATH,
2613d4f2939cSRui Paulo 				       WPAS_DBUS_NEW_SERVICE,
2614d4f2939cSRui Paulo 				       obj_desc);
2615780fb4a2SCy Schubert 	if (ret < 0) {
2616d4f2939cSRui Paulo 		free_dbus_object_desc(obj_desc);
2617780fb4a2SCy Schubert 		goto error;
2618780fb4a2SCy Schubert 	}
2619d4f2939cSRui Paulo 
2620780fb4a2SCy Schubert 	priv->dbus_new_initialized = 1;
2621780fb4a2SCy Schubert 	return 0;
2622780fb4a2SCy Schubert 
2623780fb4a2SCy Schubert error:
2624780fb4a2SCy Schubert 	wpa_dbus_ctrl_iface_props_deinit(priv);
2625780fb4a2SCy Schubert 	return -1;
2626d4f2939cSRui Paulo }
2627d4f2939cSRui Paulo 
2628d4f2939cSRui Paulo 
2629d4f2939cSRui Paulo /**
2630d4f2939cSRui Paulo  * wpas_dbus_ctrl_iface_deinit - Deinitialize dbus ctrl interface for
2631d4f2939cSRui Paulo  * wpa_supplicant
2632780fb4a2SCy Schubert  * @priv: Pointer to dbus private data from wpas_dbus_init()
2633d4f2939cSRui Paulo  *
2634d4f2939cSRui Paulo  * Deinitialize the dbus control interface that was initialized with
2635d4f2939cSRui Paulo  * wpas_dbus_ctrl_iface_init().
2636d4f2939cSRui Paulo  */
2637780fb4a2SCy Schubert void wpas_dbus_ctrl_iface_deinit(struct wpas_dbus_priv *priv)
2638d4f2939cSRui Paulo {
2639780fb4a2SCy Schubert 	if (!priv->dbus_new_initialized)
2640d4f2939cSRui Paulo 		return;
2641d4f2939cSRui Paulo 	wpa_printf(MSG_DEBUG, "dbus: Unregister D-Bus object '%s'",
2642d4f2939cSRui Paulo 		   WPAS_DBUS_NEW_PATH);
2643780fb4a2SCy Schubert 	dbus_connection_unregister_object_path(priv->con, WPAS_DBUS_NEW_PATH);
2644780fb4a2SCy Schubert 	wpa_dbus_ctrl_iface_props_deinit(priv);
2645d4f2939cSRui Paulo }
2646d4f2939cSRui Paulo 
2647d4f2939cSRui Paulo 
2648d4f2939cSRui Paulo static void wpa_dbus_free(void *ptr)
2649d4f2939cSRui Paulo {
2650d4f2939cSRui Paulo 	os_free(ptr);
2651d4f2939cSRui Paulo }
2652d4f2939cSRui Paulo 
2653d4f2939cSRui Paulo 
2654d4f2939cSRui Paulo static const struct wpa_dbus_property_desc wpas_dbus_network_properties[] = {
2655d4f2939cSRui Paulo 	{ "Properties", WPAS_DBUS_NEW_IFACE_NETWORK, "a{sv}",
2656d4f2939cSRui Paulo 	  wpas_dbus_getter_network_properties,
2657780fb4a2SCy Schubert 	  wpas_dbus_setter_network_properties,
2658780fb4a2SCy Schubert 	  NULL
2659d4f2939cSRui Paulo 	},
2660d4f2939cSRui Paulo 	{ "Enabled", WPAS_DBUS_NEW_IFACE_NETWORK, "b",
2661d4f2939cSRui Paulo 	  wpas_dbus_getter_enabled,
2662780fb4a2SCy Schubert 	  wpas_dbus_setter_enabled,
2663780fb4a2SCy Schubert 	  NULL
2664d4f2939cSRui Paulo 	},
2665780fb4a2SCy Schubert 	{ NULL, NULL, NULL, NULL, NULL, NULL }
2666d4f2939cSRui Paulo };
2667d4f2939cSRui Paulo 
2668d4f2939cSRui Paulo 
2669d4f2939cSRui Paulo static const struct wpa_dbus_signal_desc wpas_dbus_network_signals[] = {
2670d4f2939cSRui Paulo 	/* Deprecated: use org.freedesktop.DBus.Properties.PropertiesChanged */
2671d4f2939cSRui Paulo 	{ "PropertiesChanged", WPAS_DBUS_NEW_IFACE_NETWORK,
2672d4f2939cSRui Paulo 	  {
2673d4f2939cSRui Paulo 		  { "properties", "a{sv}", ARG_OUT },
2674d4f2939cSRui Paulo 		  END_ARGS
2675d4f2939cSRui Paulo 	  }
2676d4f2939cSRui Paulo 	},
2677d4f2939cSRui Paulo 	{ NULL, NULL, { END_ARGS } }
2678d4f2939cSRui Paulo };
2679d4f2939cSRui Paulo 
2680d4f2939cSRui Paulo 
2681d4f2939cSRui Paulo /**
2682d4f2939cSRui Paulo  * wpas_dbus_register_network - Register a configured network with dbus
2683d4f2939cSRui Paulo  * @wpa_s: wpa_supplicant interface structure
2684d4f2939cSRui Paulo  * @ssid: network configuration data
2685d4f2939cSRui Paulo  * Returns: 0 on success, -1 on failure
2686d4f2939cSRui Paulo  *
2687d4f2939cSRui Paulo  * Registers network representing object with dbus
2688d4f2939cSRui Paulo  */
2689d4f2939cSRui Paulo int wpas_dbus_register_network(struct wpa_supplicant *wpa_s,
2690d4f2939cSRui Paulo 			       struct wpa_ssid *ssid)
2691d4f2939cSRui Paulo {
2692d4f2939cSRui Paulo 	struct wpas_dbus_priv *ctrl_iface;
2693d4f2939cSRui Paulo 	struct wpa_dbus_object_desc *obj_desc;
2694d4f2939cSRui Paulo 	struct network_handler_args *arg;
2695d4f2939cSRui Paulo 	char net_obj_path[WPAS_DBUS_OBJECT_PATH_MAX];
2696d4f2939cSRui Paulo 
2697d4f2939cSRui Paulo #ifdef CONFIG_P2P
2698d4f2939cSRui Paulo 	/*
2699d4f2939cSRui Paulo 	 * If it is a persistent group register it as such.
2700d4f2939cSRui Paulo 	 * This is to handle cases where an interface is being initialized
2701d4f2939cSRui Paulo 	 * with a list of networks read from config.
2702d4f2939cSRui Paulo 	 */
2703d4f2939cSRui Paulo 	if (network_is_persistent_group(ssid))
2704d4f2939cSRui Paulo 		return wpas_dbus_register_persistent_group(wpa_s, ssid);
2705d4f2939cSRui Paulo #endif /* CONFIG_P2P */
2706d4f2939cSRui Paulo 
2707d4f2939cSRui Paulo 	/* Do nothing if the control interface is not turned on */
2708325151a3SRui Paulo 	if (wpa_s == NULL || wpa_s->global == NULL || !wpa_s->dbus_new_path)
2709d4f2939cSRui Paulo 		return 0;
2710d4f2939cSRui Paulo 	ctrl_iface = wpa_s->global->dbus;
2711d4f2939cSRui Paulo 	if (ctrl_iface == NULL)
2712d4f2939cSRui Paulo 		return 0;
2713d4f2939cSRui Paulo 
2714d4f2939cSRui Paulo 	os_snprintf(net_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
2715d4f2939cSRui Paulo 		    "%s/" WPAS_DBUS_NEW_NETWORKS_PART "/%u",
2716d4f2939cSRui Paulo 		    wpa_s->dbus_new_path, ssid->id);
2717d4f2939cSRui Paulo 
2718d4f2939cSRui Paulo 	wpa_printf(MSG_DEBUG, "dbus: Register network object '%s'",
2719d4f2939cSRui Paulo 		   net_obj_path);
2720d4f2939cSRui Paulo 	obj_desc = os_zalloc(sizeof(struct wpa_dbus_object_desc));
2721d4f2939cSRui Paulo 	if (!obj_desc) {
27225b9c547cSRui Paulo 		wpa_printf(MSG_ERROR,
27235b9c547cSRui Paulo 			   "Not enough memory to create object description");
2724d4f2939cSRui Paulo 		goto err;
2725d4f2939cSRui Paulo 	}
2726d4f2939cSRui Paulo 
2727d4f2939cSRui Paulo 	/* allocate memory for handlers arguments */
2728d4f2939cSRui Paulo 	arg = os_zalloc(sizeof(struct network_handler_args));
2729d4f2939cSRui Paulo 	if (!arg) {
27305b9c547cSRui Paulo 		wpa_printf(MSG_ERROR,
27315b9c547cSRui Paulo 			   "Not enough memory to create arguments for method");
2732d4f2939cSRui Paulo 		goto err;
2733d4f2939cSRui Paulo 	}
2734d4f2939cSRui Paulo 
2735d4f2939cSRui Paulo 	arg->wpa_s = wpa_s;
2736d4f2939cSRui Paulo 	arg->ssid = ssid;
2737d4f2939cSRui Paulo 
2738d4f2939cSRui Paulo 	wpas_dbus_register(obj_desc, arg, wpa_dbus_free, NULL,
2739d4f2939cSRui Paulo 			   wpas_dbus_network_properties,
2740d4f2939cSRui Paulo 			   wpas_dbus_network_signals);
2741d4f2939cSRui Paulo 
2742d4f2939cSRui Paulo 	if (wpa_dbus_register_object_per_iface(ctrl_iface, net_obj_path,
2743d4f2939cSRui Paulo 					       wpa_s->ifname, obj_desc))
2744d4f2939cSRui Paulo 		goto err;
2745d4f2939cSRui Paulo 
2746d4f2939cSRui Paulo 	wpas_dbus_signal_network_added(wpa_s, ssid->id);
2747d4f2939cSRui Paulo 
2748d4f2939cSRui Paulo 	return 0;
2749d4f2939cSRui Paulo 
2750d4f2939cSRui Paulo err:
2751d4f2939cSRui Paulo 	free_dbus_object_desc(obj_desc);
2752d4f2939cSRui Paulo 	return -1;
2753d4f2939cSRui Paulo }
2754d4f2939cSRui Paulo 
2755d4f2939cSRui Paulo 
2756d4f2939cSRui Paulo /**
2757d4f2939cSRui Paulo  * wpas_dbus_unregister_network - Unregister a configured network from dbus
2758d4f2939cSRui Paulo  * @wpa_s: wpa_supplicant interface structure
2759d4f2939cSRui Paulo  * @nid: network id
2760d4f2939cSRui Paulo  * Returns: 0 on success, -1 on failure
2761d4f2939cSRui Paulo  *
2762d4f2939cSRui Paulo  * Unregisters network representing object from dbus
2763d4f2939cSRui Paulo  */
2764d4f2939cSRui Paulo int wpas_dbus_unregister_network(struct wpa_supplicant *wpa_s, int nid)
2765d4f2939cSRui Paulo {
2766d4f2939cSRui Paulo 	struct wpas_dbus_priv *ctrl_iface;
2767d4f2939cSRui Paulo 	char net_obj_path[WPAS_DBUS_OBJECT_PATH_MAX];
2768d4f2939cSRui Paulo 	int ret;
2769d4f2939cSRui Paulo #ifdef CONFIG_P2P
2770d4f2939cSRui Paulo 	struct wpa_ssid *ssid;
2771d4f2939cSRui Paulo 
2772d4f2939cSRui Paulo 	ssid = wpa_config_get_network(wpa_s->conf, nid);
2773d4f2939cSRui Paulo 
2774d4f2939cSRui Paulo 	/* If it is a persistent group unregister it as such */
2775d4f2939cSRui Paulo 	if (ssid && network_is_persistent_group(ssid))
2776d4f2939cSRui Paulo 		return wpas_dbus_unregister_persistent_group(wpa_s, nid);
2777d4f2939cSRui Paulo #endif /* CONFIG_P2P */
2778d4f2939cSRui Paulo 
2779d4f2939cSRui Paulo 	/* Do nothing if the control interface is not turned on */
2780d4f2939cSRui Paulo 	if (wpa_s->global == NULL || wpa_s->dbus_new_path == NULL)
2781d4f2939cSRui Paulo 		return 0;
2782d4f2939cSRui Paulo 	ctrl_iface = wpa_s->global->dbus;
2783d4f2939cSRui Paulo 	if (ctrl_iface == NULL)
2784d4f2939cSRui Paulo 		return 0;
2785d4f2939cSRui Paulo 
2786d4f2939cSRui Paulo 	os_snprintf(net_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
2787d4f2939cSRui Paulo 		    "%s/" WPAS_DBUS_NEW_NETWORKS_PART "/%u",
2788d4f2939cSRui Paulo 		    wpa_s->dbus_new_path, nid);
2789d4f2939cSRui Paulo 
2790d4f2939cSRui Paulo 	wpa_printf(MSG_DEBUG, "dbus: Unregister network object '%s'",
2791d4f2939cSRui Paulo 		   net_obj_path);
2792d4f2939cSRui Paulo 	ret = wpa_dbus_unregister_object_per_iface(ctrl_iface, net_obj_path);
2793d4f2939cSRui Paulo 
2794d4f2939cSRui Paulo 	if (!ret)
2795d4f2939cSRui Paulo 		wpas_dbus_signal_network_removed(wpa_s, nid);
2796d4f2939cSRui Paulo 
2797d4f2939cSRui Paulo 	return ret;
2798d4f2939cSRui Paulo }
2799d4f2939cSRui Paulo 
2800d4f2939cSRui Paulo 
2801d4f2939cSRui Paulo static const struct wpa_dbus_property_desc wpas_dbus_bss_properties[] = {
2802d4f2939cSRui Paulo 	{ "SSID", WPAS_DBUS_NEW_IFACE_BSS, "ay",
2803d4f2939cSRui Paulo 	  wpas_dbus_getter_bss_ssid,
2804780fb4a2SCy Schubert 	  NULL,
2805d4f2939cSRui Paulo 	  NULL
2806d4f2939cSRui Paulo 	},
2807d4f2939cSRui Paulo 	{ "BSSID", WPAS_DBUS_NEW_IFACE_BSS, "ay",
2808d4f2939cSRui Paulo 	  wpas_dbus_getter_bss_bssid,
2809780fb4a2SCy Schubert 	  NULL,
2810d4f2939cSRui Paulo 	  NULL
2811d4f2939cSRui Paulo 	},
2812d4f2939cSRui Paulo 	{ "Privacy", WPAS_DBUS_NEW_IFACE_BSS, "b",
2813d4f2939cSRui Paulo 	  wpas_dbus_getter_bss_privacy,
2814780fb4a2SCy Schubert 	  NULL,
2815d4f2939cSRui Paulo 	  NULL
2816d4f2939cSRui Paulo 	},
2817d4f2939cSRui Paulo 	{ "Mode", WPAS_DBUS_NEW_IFACE_BSS, "s",
2818d4f2939cSRui Paulo 	  wpas_dbus_getter_bss_mode,
2819780fb4a2SCy Schubert 	  NULL,
2820d4f2939cSRui Paulo 	  NULL
2821d4f2939cSRui Paulo 	},
2822d4f2939cSRui Paulo 	{ "Signal", WPAS_DBUS_NEW_IFACE_BSS, "n",
2823d4f2939cSRui Paulo 	  wpas_dbus_getter_bss_signal,
2824780fb4a2SCy Schubert 	  NULL,
2825d4f2939cSRui Paulo 	  NULL
2826d4f2939cSRui Paulo 	},
2827d4f2939cSRui Paulo 	{ "Frequency", WPAS_DBUS_NEW_IFACE_BSS, "q",
2828d4f2939cSRui Paulo 	  wpas_dbus_getter_bss_frequency,
2829780fb4a2SCy Schubert 	  NULL,
2830d4f2939cSRui Paulo 	  NULL
2831d4f2939cSRui Paulo 	},
2832d4f2939cSRui Paulo 	{ "Rates", WPAS_DBUS_NEW_IFACE_BSS, "au",
2833d4f2939cSRui Paulo 	  wpas_dbus_getter_bss_rates,
2834780fb4a2SCy Schubert 	  NULL,
2835d4f2939cSRui Paulo 	  NULL
2836d4f2939cSRui Paulo 	},
2837d4f2939cSRui Paulo 	{ "WPA", WPAS_DBUS_NEW_IFACE_BSS, "a{sv}",
2838d4f2939cSRui Paulo 	  wpas_dbus_getter_bss_wpa,
2839780fb4a2SCy Schubert 	  NULL,
2840d4f2939cSRui Paulo 	  NULL
2841d4f2939cSRui Paulo 	},
2842d4f2939cSRui Paulo 	{ "RSN", WPAS_DBUS_NEW_IFACE_BSS, "a{sv}",
2843d4f2939cSRui Paulo 	  wpas_dbus_getter_bss_rsn,
2844780fb4a2SCy Schubert 	  NULL,
2845d4f2939cSRui Paulo 	  NULL
2846d4f2939cSRui Paulo 	},
2847d4f2939cSRui Paulo 	{ "WPS", WPAS_DBUS_NEW_IFACE_BSS, "a{sv}",
2848d4f2939cSRui Paulo 	  wpas_dbus_getter_bss_wps,
2849780fb4a2SCy Schubert 	  NULL,
2850d4f2939cSRui Paulo 	  NULL
2851d4f2939cSRui Paulo 	},
2852d4f2939cSRui Paulo 	{ "IEs", WPAS_DBUS_NEW_IFACE_BSS, "ay",
2853d4f2939cSRui Paulo 	  wpas_dbus_getter_bss_ies,
2854780fb4a2SCy Schubert 	  NULL,
2855d4f2939cSRui Paulo 	  NULL
2856d4f2939cSRui Paulo 	},
28575b9c547cSRui Paulo 	{ "Age", WPAS_DBUS_NEW_IFACE_BSS, "u",
28585b9c547cSRui Paulo 	  wpas_dbus_getter_bss_age,
2859780fb4a2SCy Schubert 	  NULL,
28605b9c547cSRui Paulo 	  NULL
28615b9c547cSRui Paulo 	},
2862780fb4a2SCy Schubert 	{ NULL, NULL, NULL, NULL, NULL, NULL }
2863d4f2939cSRui Paulo };
2864d4f2939cSRui Paulo 
2865d4f2939cSRui Paulo 
2866d4f2939cSRui Paulo static const struct wpa_dbus_signal_desc wpas_dbus_bss_signals[] = {
2867d4f2939cSRui Paulo 	/* Deprecated: use org.freedesktop.DBus.Properties.PropertiesChanged */
2868d4f2939cSRui Paulo 	{ "PropertiesChanged", WPAS_DBUS_NEW_IFACE_BSS,
2869d4f2939cSRui Paulo 	  {
2870d4f2939cSRui Paulo 		  { "properties", "a{sv}", ARG_OUT },
2871d4f2939cSRui Paulo 		  END_ARGS
2872d4f2939cSRui Paulo 	  }
2873d4f2939cSRui Paulo 	},
2874d4f2939cSRui Paulo 	{ NULL, NULL, { END_ARGS } }
2875d4f2939cSRui Paulo };
2876d4f2939cSRui Paulo 
2877d4f2939cSRui Paulo 
2878d4f2939cSRui Paulo /**
2879d4f2939cSRui Paulo  * wpas_dbus_unregister_bss - Unregister a scanned BSS from dbus
2880d4f2939cSRui Paulo  * @wpa_s: wpa_supplicant interface structure
2881d4f2939cSRui Paulo  * @bssid: scanned network bssid
2882d4f2939cSRui Paulo  * @id: unique BSS identifier
2883d4f2939cSRui Paulo  * Returns: 0 on success, -1 on failure
2884d4f2939cSRui Paulo  *
2885d4f2939cSRui Paulo  * Unregisters BSS representing object from dbus
2886d4f2939cSRui Paulo  */
2887d4f2939cSRui Paulo int wpas_dbus_unregister_bss(struct wpa_supplicant *wpa_s,
2888d4f2939cSRui Paulo 			     u8 bssid[ETH_ALEN], unsigned int id)
2889d4f2939cSRui Paulo {
2890d4f2939cSRui Paulo 	struct wpas_dbus_priv *ctrl_iface;
2891d4f2939cSRui Paulo 	char bss_obj_path[WPAS_DBUS_OBJECT_PATH_MAX];
2892d4f2939cSRui Paulo 
2893d4f2939cSRui Paulo 	/* Do nothing if the control interface is not turned on */
2894325151a3SRui Paulo 	if (wpa_s == NULL || wpa_s->global == NULL || !wpa_s->dbus_new_path)
2895d4f2939cSRui Paulo 		return 0;
2896d4f2939cSRui Paulo 	ctrl_iface = wpa_s->global->dbus;
2897d4f2939cSRui Paulo 	if (ctrl_iface == NULL)
2898d4f2939cSRui Paulo 		return 0;
2899d4f2939cSRui Paulo 
2900d4f2939cSRui Paulo 	os_snprintf(bss_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
2901d4f2939cSRui Paulo 		    "%s/" WPAS_DBUS_NEW_BSSIDS_PART "/%u",
2902d4f2939cSRui Paulo 		    wpa_s->dbus_new_path, id);
2903d4f2939cSRui Paulo 
2904d4f2939cSRui Paulo 	wpa_printf(MSG_DEBUG, "dbus: Unregister BSS object '%s'",
2905d4f2939cSRui Paulo 		   bss_obj_path);
2906d4f2939cSRui Paulo 	if (wpa_dbus_unregister_object_per_iface(ctrl_iface, bss_obj_path)) {
2907d4f2939cSRui Paulo 		wpa_printf(MSG_ERROR, "dbus: Cannot unregister BSS object %s",
2908d4f2939cSRui Paulo 			   bss_obj_path);
2909d4f2939cSRui Paulo 		return -1;
2910d4f2939cSRui Paulo 	}
2911d4f2939cSRui Paulo 
2912d4f2939cSRui Paulo 	wpas_dbus_signal_bss_removed(wpa_s, bss_obj_path);
2913d4f2939cSRui Paulo 	wpas_dbus_signal_prop_changed(wpa_s, WPAS_DBUS_PROP_BSSS);
2914d4f2939cSRui Paulo 
2915d4f2939cSRui Paulo 	return 0;
2916d4f2939cSRui Paulo }
2917d4f2939cSRui Paulo 
2918d4f2939cSRui Paulo 
2919d4f2939cSRui Paulo /**
2920d4f2939cSRui Paulo  * wpas_dbus_register_bss - Register a scanned BSS with dbus
2921d4f2939cSRui Paulo  * @wpa_s: wpa_supplicant interface structure
2922d4f2939cSRui Paulo  * @bssid: scanned network bssid
2923d4f2939cSRui Paulo  * @id: unique BSS identifier
2924d4f2939cSRui Paulo  * Returns: 0 on success, -1 on failure
2925d4f2939cSRui Paulo  *
2926d4f2939cSRui Paulo  * Registers BSS representing object with dbus
2927d4f2939cSRui Paulo  */
2928d4f2939cSRui Paulo int wpas_dbus_register_bss(struct wpa_supplicant *wpa_s,
2929d4f2939cSRui Paulo 			   u8 bssid[ETH_ALEN], unsigned int id)
2930d4f2939cSRui Paulo {
2931d4f2939cSRui Paulo 	struct wpas_dbus_priv *ctrl_iface;
2932d4f2939cSRui Paulo 	struct wpa_dbus_object_desc *obj_desc;
2933d4f2939cSRui Paulo 	char bss_obj_path[WPAS_DBUS_OBJECT_PATH_MAX];
2934d4f2939cSRui Paulo 	struct bss_handler_args *arg;
2935d4f2939cSRui Paulo 
2936d4f2939cSRui Paulo 	/* Do nothing if the control interface is not turned on */
2937325151a3SRui Paulo 	if (wpa_s == NULL || wpa_s->global == NULL || !wpa_s->dbus_new_path)
2938d4f2939cSRui Paulo 		return 0;
2939d4f2939cSRui Paulo 	ctrl_iface = wpa_s->global->dbus;
2940d4f2939cSRui Paulo 	if (ctrl_iface == NULL)
2941d4f2939cSRui Paulo 		return 0;
2942d4f2939cSRui Paulo 
2943d4f2939cSRui Paulo 	os_snprintf(bss_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
2944d4f2939cSRui Paulo 		    "%s/" WPAS_DBUS_NEW_BSSIDS_PART "/%u",
2945d4f2939cSRui Paulo 		    wpa_s->dbus_new_path, id);
2946d4f2939cSRui Paulo 
2947d4f2939cSRui Paulo 	obj_desc = os_zalloc(sizeof(struct wpa_dbus_object_desc));
2948d4f2939cSRui Paulo 	if (!obj_desc) {
29495b9c547cSRui Paulo 		wpa_printf(MSG_ERROR,
29505b9c547cSRui Paulo 			   "Not enough memory to create object description");
2951d4f2939cSRui Paulo 		goto err;
2952d4f2939cSRui Paulo 	}
2953d4f2939cSRui Paulo 
2954d4f2939cSRui Paulo 	arg = os_zalloc(sizeof(struct bss_handler_args));
2955d4f2939cSRui Paulo 	if (!arg) {
29565b9c547cSRui Paulo 		wpa_printf(MSG_ERROR,
29575b9c547cSRui Paulo 			   "Not enough memory to create arguments for handler");
2958d4f2939cSRui Paulo 		goto err;
2959d4f2939cSRui Paulo 	}
2960d4f2939cSRui Paulo 	arg->wpa_s = wpa_s;
2961d4f2939cSRui Paulo 	arg->id = id;
2962d4f2939cSRui Paulo 
2963d4f2939cSRui Paulo 	wpas_dbus_register(obj_desc, arg, wpa_dbus_free, NULL,
2964d4f2939cSRui Paulo 			   wpas_dbus_bss_properties,
2965d4f2939cSRui Paulo 			   wpas_dbus_bss_signals);
2966d4f2939cSRui Paulo 
2967d4f2939cSRui Paulo 	wpa_printf(MSG_DEBUG, "dbus: Register BSS object '%s'",
2968d4f2939cSRui Paulo 		   bss_obj_path);
2969d4f2939cSRui Paulo 	if (wpa_dbus_register_object_per_iface(ctrl_iface, bss_obj_path,
2970d4f2939cSRui Paulo 					       wpa_s->ifname, obj_desc)) {
2971d4f2939cSRui Paulo 		wpa_printf(MSG_ERROR,
2972d4f2939cSRui Paulo 			   "Cannot register BSSID dbus object %s.",
2973d4f2939cSRui Paulo 			   bss_obj_path);
2974d4f2939cSRui Paulo 		goto err;
2975d4f2939cSRui Paulo 	}
2976d4f2939cSRui Paulo 
2977d4f2939cSRui Paulo 	wpas_dbus_signal_bss_added(wpa_s, bss_obj_path);
2978d4f2939cSRui Paulo 	wpas_dbus_signal_prop_changed(wpa_s, WPAS_DBUS_PROP_BSSS);
2979d4f2939cSRui Paulo 
2980d4f2939cSRui Paulo 	return 0;
2981d4f2939cSRui Paulo 
2982d4f2939cSRui Paulo err:
2983d4f2939cSRui Paulo 	free_dbus_object_desc(obj_desc);
2984d4f2939cSRui Paulo 	return -1;
2985d4f2939cSRui Paulo }
2986d4f2939cSRui Paulo 
2987d4f2939cSRui Paulo 
29884bc52338SCy Schubert static const struct wpa_dbus_property_desc wpas_dbus_sta_properties[] = {
29894bc52338SCy Schubert 	{ "Address", WPAS_DBUS_NEW_IFACE_STA, "ay",
29904bc52338SCy Schubert 	  wpas_dbus_getter_sta_address,
29914bc52338SCy Schubert 	  NULL, NULL
29924bc52338SCy Schubert 	},
29934bc52338SCy Schubert 	{ "AID", WPAS_DBUS_NEW_IFACE_STA, "q",
29944bc52338SCy Schubert 	  wpas_dbus_getter_sta_aid,
29954bc52338SCy Schubert 	  NULL, NULL
29964bc52338SCy Schubert 	},
29974bc52338SCy Schubert 	{ "Capabilities", WPAS_DBUS_NEW_IFACE_STA, "q",
29984bc52338SCy Schubert 	  wpas_dbus_getter_sta_caps,
29994bc52338SCy Schubert 	  NULL, NULL
30004bc52338SCy Schubert 	},
30014bc52338SCy Schubert 	{ "RxPackets", WPAS_DBUS_NEW_IFACE_STA, "t",
30024bc52338SCy Schubert 	  wpas_dbus_getter_sta_rx_packets,
30034bc52338SCy Schubert 	  NULL, NULL
30044bc52338SCy Schubert 	},
30054bc52338SCy Schubert 	{ "TxPackets", WPAS_DBUS_NEW_IFACE_STA, "t",
30064bc52338SCy Schubert 	  wpas_dbus_getter_sta_tx_packets,
30074bc52338SCy Schubert 	  NULL, NULL
30084bc52338SCy Schubert 	},
30094bc52338SCy Schubert 	{ "RxBytes", WPAS_DBUS_NEW_IFACE_STA, "t",
30104bc52338SCy Schubert 	  wpas_dbus_getter_sta_rx_bytes,
30114bc52338SCy Schubert 	  NULL, NULL
30124bc52338SCy Schubert 	},
30134bc52338SCy Schubert 	{ "TxBytes", WPAS_DBUS_NEW_IFACE_STA, "t",
30144bc52338SCy Schubert 	  wpas_dbus_getter_sta_tx_bytes,
30154bc52338SCy Schubert 	  NULL, NULL
30164bc52338SCy Schubert 	},
30174bc52338SCy Schubert 	{ NULL, NULL, NULL, NULL, NULL, NULL }
30184bc52338SCy Schubert };
30194bc52338SCy Schubert 
30204bc52338SCy Schubert 
30214bc52338SCy Schubert static const struct wpa_dbus_signal_desc wpas_dbus_sta_signals[] = {
30224bc52338SCy Schubert 	/* Deprecated: use org.freedesktop.DBus.Properties.PropertiesChanged */
30234bc52338SCy Schubert 	{ "PropertiesChanged", WPAS_DBUS_NEW_IFACE_STA,
30244bc52338SCy Schubert 	  {
30254bc52338SCy Schubert 		  { "properties", "a{sv}", ARG_OUT },
30264bc52338SCy Schubert 		  END_ARGS
30274bc52338SCy Schubert 	  }
30284bc52338SCy Schubert 	},
30294bc52338SCy Schubert 	{ NULL, NULL, { END_ARGS } }
30304bc52338SCy Schubert };
30314bc52338SCy Schubert 
30324bc52338SCy Schubert 
30334bc52338SCy Schubert /**
30344bc52338SCy Schubert  * wpas_dbus_unregister_sta - Unregister a connected station from dbus
30354bc52338SCy Schubert  * @wpa_s: wpa_supplicant interface structure
30364bc52338SCy Schubert  * @sta: station MAC address
30374bc52338SCy Schubert  * Returns: 0 on success, -1 on failure
30384bc52338SCy Schubert  *
30394bc52338SCy Schubert  * Unregisters STA representing object from dbus.
30404bc52338SCy Schubert  */
30414bc52338SCy Schubert int wpas_dbus_unregister_sta(struct wpa_supplicant *wpa_s, const u8 *sta)
30424bc52338SCy Schubert {
30434bc52338SCy Schubert 	struct wpas_dbus_priv *ctrl_iface;
30444bc52338SCy Schubert 	char station_obj_path[WPAS_DBUS_OBJECT_PATH_MAX];
30454bc52338SCy Schubert 
30464bc52338SCy Schubert 	/* Do nothing if the control interface is not turned on */
30474bc52338SCy Schubert 	if (!wpa_s || !wpa_s->global)
30484bc52338SCy Schubert 		return 0;
30494bc52338SCy Schubert 	ctrl_iface = wpa_s->global->dbus;
30504bc52338SCy Schubert 	if (!ctrl_iface)
30514bc52338SCy Schubert 		return 0;
30524bc52338SCy Schubert 
30534bc52338SCy Schubert 	os_snprintf(station_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
30544bc52338SCy Schubert 		    "%s/" WPAS_DBUS_NEW_STAS_PART "/" COMPACT_MACSTR,
30554bc52338SCy Schubert 		    wpa_s->dbus_new_path, MAC2STR(sta));
30564bc52338SCy Schubert 
30574bc52338SCy Schubert 	wpa_printf(MSG_DEBUG, "dbus: Unregister STA object '%s'",
30584bc52338SCy Schubert 		   station_obj_path);
30594bc52338SCy Schubert 	if (wpa_dbus_unregister_object_per_iface(ctrl_iface,
30604bc52338SCy Schubert 						 station_obj_path)) {
30614bc52338SCy Schubert 		wpa_printf(MSG_ERROR, "dbus: Cannot unregister STA object %s",
30624bc52338SCy Schubert 			   station_obj_path);
30634bc52338SCy Schubert 		return -1;
30644bc52338SCy Schubert 	}
30654bc52338SCy Schubert 
30664bc52338SCy Schubert 	wpas_dbus_signal_station_removed(wpa_s, station_obj_path);
30674bc52338SCy Schubert 	wpas_dbus_signal_prop_changed(wpa_s, WPAS_DBUS_PROP_STATIONS);
30684bc52338SCy Schubert 
30694bc52338SCy Schubert 	return 0;
30704bc52338SCy Schubert }
30714bc52338SCy Schubert 
30724bc52338SCy Schubert 
30734bc52338SCy Schubert /**
30744bc52338SCy Schubert  * wpas_dbus_register_sta - Register a connected station with dbus
30754bc52338SCy Schubert  * @wpa_s: wpa_supplicant interface structure
30764bc52338SCy Schubert  * @sta: station MAC address
30774bc52338SCy Schubert  * Returns: 0 on success, -1 on failure
30784bc52338SCy Schubert  *
30794bc52338SCy Schubert  * Registers STA representing object with dbus.
30804bc52338SCy Schubert  */
30814bc52338SCy Schubert int wpas_dbus_register_sta(struct wpa_supplicant *wpa_s, const u8 *sta)
30824bc52338SCy Schubert {
30834bc52338SCy Schubert 	struct wpas_dbus_priv *ctrl_iface;
30844bc52338SCy Schubert 	struct wpa_dbus_object_desc *obj_desc;
30854bc52338SCy Schubert 	char station_obj_path[WPAS_DBUS_OBJECT_PATH_MAX];
30864bc52338SCy Schubert 	struct sta_handler_args *arg;
30874bc52338SCy Schubert 
30884bc52338SCy Schubert 	/* Do nothing if the control interface is not turned on */
30894bc52338SCy Schubert 	if (!wpa_s || !wpa_s->global)
30904bc52338SCy Schubert 		return 0;
30914bc52338SCy Schubert 	ctrl_iface = wpa_s->global->dbus;
30924bc52338SCy Schubert 	if (!ctrl_iface)
30934bc52338SCy Schubert 		return 0;
30944bc52338SCy Schubert 
30954bc52338SCy Schubert 	os_snprintf(station_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
30964bc52338SCy Schubert 		    "%s/" WPAS_DBUS_NEW_STAS_PART "/" COMPACT_MACSTR,
30974bc52338SCy Schubert 		    wpa_s->dbus_new_path, MAC2STR(sta));
30984bc52338SCy Schubert 
30994bc52338SCy Schubert 	obj_desc = os_zalloc(sizeof(struct wpa_dbus_object_desc));
31004bc52338SCy Schubert 	if (!obj_desc) {
31014bc52338SCy Schubert 		wpa_printf(MSG_ERROR,
31024bc52338SCy Schubert 			   "Not enough memory to create object description");
31034bc52338SCy Schubert 		goto err;
31044bc52338SCy Schubert 	}
31054bc52338SCy Schubert 
31064bc52338SCy Schubert 	arg = os_zalloc(sizeof(struct sta_handler_args));
31074bc52338SCy Schubert 	if (!arg) {
31084bc52338SCy Schubert 		wpa_printf(MSG_ERROR,
31094bc52338SCy Schubert 			   "Not enough memory to create arguments for handler");
31104bc52338SCy Schubert 		goto err;
31114bc52338SCy Schubert 	}
31124bc52338SCy Schubert 	arg->wpa_s = wpa_s;
31134bc52338SCy Schubert 	arg->sta = sta;
31144bc52338SCy Schubert 
31154bc52338SCy Schubert 	wpas_dbus_register(obj_desc, arg, wpa_dbus_free, NULL,
31164bc52338SCy Schubert 			   wpas_dbus_sta_properties, wpas_dbus_sta_signals);
31174bc52338SCy Schubert 
31184bc52338SCy Schubert 	wpa_printf(MSG_DEBUG, "dbus: Register STA object '%s'",
31194bc52338SCy Schubert 		   station_obj_path);
31204bc52338SCy Schubert 	if (wpa_dbus_register_object_per_iface(ctrl_iface, station_obj_path,
31214bc52338SCy Schubert 					       wpa_s->ifname, obj_desc)) {
31224bc52338SCy Schubert 		wpa_printf(MSG_ERROR,
31234bc52338SCy Schubert 			   "Cannot register STA dbus object %s",
31244bc52338SCy Schubert 			   station_obj_path);
31254bc52338SCy Schubert 		goto err;
31264bc52338SCy Schubert 	}
31274bc52338SCy Schubert 
31284bc52338SCy Schubert 	wpas_dbus_signal_station_added(wpa_s, station_obj_path);
31294bc52338SCy Schubert 	wpas_dbus_signal_prop_changed(wpa_s, WPAS_DBUS_PROP_STATIONS);
31304bc52338SCy Schubert 
31314bc52338SCy Schubert 	return 0;
31324bc52338SCy Schubert 
31334bc52338SCy Schubert err:
31344bc52338SCy Schubert 	free_dbus_object_desc(obj_desc);
31354bc52338SCy Schubert 	return -1;
31364bc52338SCy Schubert }
31374bc52338SCy Schubert 
31384bc52338SCy Schubert 
3139d4f2939cSRui Paulo static const struct wpa_dbus_method_desc wpas_dbus_interface_methods[] = {
3140d4f2939cSRui Paulo 	{ "Scan", WPAS_DBUS_NEW_IFACE_INTERFACE,
31415b9c547cSRui Paulo 	  (WPADBusMethodHandler) wpas_dbus_handler_scan,
3142d4f2939cSRui Paulo 	  {
3143d4f2939cSRui Paulo 		  { "args", "a{sv}", ARG_IN },
3144d4f2939cSRui Paulo 		  END_ARGS
3145d4f2939cSRui Paulo 	  }
3146d4f2939cSRui Paulo 	},
31475b9c547cSRui Paulo 	{ "SignalPoll", WPAS_DBUS_NEW_IFACE_INTERFACE,
31485b9c547cSRui Paulo 	  (WPADBusMethodHandler) wpas_dbus_handler_signal_poll,
31495b9c547cSRui Paulo 	  {
31505b9c547cSRui Paulo 		  { "args", "a{sv}", ARG_OUT },
31515b9c547cSRui Paulo 		  END_ARGS
31525b9c547cSRui Paulo 	  }
31535b9c547cSRui Paulo 	},
3154d4f2939cSRui Paulo 	{ "Disconnect", WPAS_DBUS_NEW_IFACE_INTERFACE,
31555b9c547cSRui Paulo 	  (WPADBusMethodHandler) wpas_dbus_handler_disconnect,
3156d4f2939cSRui Paulo 	  {
3157d4f2939cSRui Paulo 		  END_ARGS
3158d4f2939cSRui Paulo 	  }
3159d4f2939cSRui Paulo 	},
3160d4f2939cSRui Paulo 	{ "AddNetwork", WPAS_DBUS_NEW_IFACE_INTERFACE,
31615b9c547cSRui Paulo 	  (WPADBusMethodHandler) wpas_dbus_handler_add_network,
3162d4f2939cSRui Paulo 	  {
3163d4f2939cSRui Paulo 		  { "args", "a{sv}", ARG_IN },
3164d4f2939cSRui Paulo 		  { "path", "o", ARG_OUT },
3165d4f2939cSRui Paulo 		  END_ARGS
3166d4f2939cSRui Paulo 	  }
3167d4f2939cSRui Paulo 	},
3168d4f2939cSRui Paulo 	{ "Reassociate", WPAS_DBUS_NEW_IFACE_INTERFACE,
31695b9c547cSRui Paulo 	  (WPADBusMethodHandler) wpas_dbus_handler_reassociate,
31705b9c547cSRui Paulo 	  {
31715b9c547cSRui Paulo 		  END_ARGS
31725b9c547cSRui Paulo 	  }
31735b9c547cSRui Paulo 	},
31745b9c547cSRui Paulo 	{ "Reattach", WPAS_DBUS_NEW_IFACE_INTERFACE,
31755b9c547cSRui Paulo 	  (WPADBusMethodHandler) wpas_dbus_handler_reattach,
3176d4f2939cSRui Paulo 	  {
3177d4f2939cSRui Paulo 		  END_ARGS
3178d4f2939cSRui Paulo 	  }
3179d4f2939cSRui Paulo 	},
3180325151a3SRui Paulo 	{ "Reconnect", WPAS_DBUS_NEW_IFACE_INTERFACE,
3181325151a3SRui Paulo 	  (WPADBusMethodHandler) wpas_dbus_handler_reconnect,
3182325151a3SRui Paulo 	  {
3183325151a3SRui Paulo 		  END_ARGS
3184325151a3SRui Paulo 	  }
3185325151a3SRui Paulo 	},
3186d4f2939cSRui Paulo 	{ "RemoveNetwork", WPAS_DBUS_NEW_IFACE_INTERFACE,
31875b9c547cSRui Paulo 	  (WPADBusMethodHandler) wpas_dbus_handler_remove_network,
3188d4f2939cSRui Paulo 	  {
3189d4f2939cSRui Paulo 		  { "path", "o", ARG_IN },
3190d4f2939cSRui Paulo 		  END_ARGS
3191d4f2939cSRui Paulo 	  }
3192d4f2939cSRui Paulo 	},
3193d4f2939cSRui Paulo 	{ "RemoveAllNetworks", WPAS_DBUS_NEW_IFACE_INTERFACE,
31945b9c547cSRui Paulo 	  (WPADBusMethodHandler) wpas_dbus_handler_remove_all_networks,
3195d4f2939cSRui Paulo 	  {
3196d4f2939cSRui Paulo 		  END_ARGS
3197d4f2939cSRui Paulo 	  }
3198d4f2939cSRui Paulo 	},
3199d4f2939cSRui Paulo 	{ "SelectNetwork", WPAS_DBUS_NEW_IFACE_INTERFACE,
32005b9c547cSRui Paulo 	  (WPADBusMethodHandler) wpas_dbus_handler_select_network,
3201d4f2939cSRui Paulo 	  {
3202d4f2939cSRui Paulo 		  { "path", "o", ARG_IN },
3203d4f2939cSRui Paulo 		  END_ARGS
3204d4f2939cSRui Paulo 	  }
3205d4f2939cSRui Paulo 	},
3206d4f2939cSRui Paulo 	{ "NetworkReply", WPAS_DBUS_NEW_IFACE_INTERFACE,
32075b9c547cSRui Paulo 	  (WPADBusMethodHandler) wpas_dbus_handler_network_reply,
3208d4f2939cSRui Paulo 	  {
3209d4f2939cSRui Paulo 		  { "path", "o", ARG_IN },
3210d4f2939cSRui Paulo 		  { "field", "s", ARG_IN },
3211d4f2939cSRui Paulo 		  { "value", "s", ARG_IN },
3212d4f2939cSRui Paulo 		  END_ARGS
3213d4f2939cSRui Paulo 	  }
3214d4f2939cSRui Paulo 	},
3215*c1d255d3SCy Schubert 	{ "Roam", WPAS_DBUS_NEW_IFACE_INTERFACE,
3216*c1d255d3SCy Schubert 	  (WPADBusMethodHandler) wpas_dbus_handler_roam,
3217*c1d255d3SCy Schubert 	  {
3218*c1d255d3SCy Schubert 		  { "addr", "s", ARG_IN },
3219*c1d255d3SCy Schubert 		  END_ARGS
3220*c1d255d3SCy Schubert 	  }
3221*c1d255d3SCy Schubert 	},
3222*c1d255d3SCy Schubert 
32235b9c547cSRui Paulo #ifndef CONFIG_NO_CONFIG_BLOBS
3224d4f2939cSRui Paulo 	{ "AddBlob", WPAS_DBUS_NEW_IFACE_INTERFACE,
32255b9c547cSRui Paulo 	  (WPADBusMethodHandler) wpas_dbus_handler_add_blob,
3226d4f2939cSRui Paulo 	  {
3227d4f2939cSRui Paulo 		  { "name", "s", ARG_IN },
3228d4f2939cSRui Paulo 		  { "data", "ay", ARG_IN },
3229d4f2939cSRui Paulo 		  END_ARGS
3230d4f2939cSRui Paulo 	  }
3231d4f2939cSRui Paulo 	},
3232d4f2939cSRui Paulo 	{ "GetBlob", WPAS_DBUS_NEW_IFACE_INTERFACE,
32335b9c547cSRui Paulo 	  (WPADBusMethodHandler) wpas_dbus_handler_get_blob,
3234d4f2939cSRui Paulo 	  {
3235d4f2939cSRui Paulo 		  { "name", "s", ARG_IN },
3236d4f2939cSRui Paulo 		  { "data", "ay", ARG_OUT },
3237d4f2939cSRui Paulo 		  END_ARGS
3238d4f2939cSRui Paulo 	  }
3239d4f2939cSRui Paulo 	},
3240d4f2939cSRui Paulo 	{ "RemoveBlob", WPAS_DBUS_NEW_IFACE_INTERFACE,
32415b9c547cSRui Paulo 	  (WPADBusMethodHandler) wpas_dbus_handler_remove_blob,
3242d4f2939cSRui Paulo 	  {
3243d4f2939cSRui Paulo 		  { "name", "s", ARG_IN },
3244d4f2939cSRui Paulo 		  END_ARGS
3245d4f2939cSRui Paulo 	  }
3246d4f2939cSRui Paulo 	},
32475b9c547cSRui Paulo #endif /* CONFIG_NO_CONFIG_BLOBS */
32485b9c547cSRui Paulo 	{ "SetPKCS11EngineAndModulePath", WPAS_DBUS_NEW_IFACE_INTERFACE,
32495b9c547cSRui Paulo 	  (WPADBusMethodHandler)
32505b9c547cSRui Paulo 	  wpas_dbus_handler_set_pkcs11_engine_and_module_path,
32515b9c547cSRui Paulo 	  {
32525b9c547cSRui Paulo 		  { "pkcs11_engine_path", "s", ARG_IN },
32535b9c547cSRui Paulo 		  { "pkcs11_module_path", "s", ARG_IN },
32545b9c547cSRui Paulo 		  END_ARGS
32555b9c547cSRui Paulo 	  }
32565b9c547cSRui Paulo 	},
3257d4f2939cSRui Paulo #ifdef CONFIG_WPS
3258d4f2939cSRui Paulo 	{ "Start", WPAS_DBUS_NEW_IFACE_WPS,
32595b9c547cSRui Paulo 	  (WPADBusMethodHandler) wpas_dbus_handler_wps_start,
3260d4f2939cSRui Paulo 	  {
3261d4f2939cSRui Paulo 		  { "args", "a{sv}", ARG_IN },
3262d4f2939cSRui Paulo 		  { "output", "a{sv}", ARG_OUT },
3263d4f2939cSRui Paulo 		  END_ARGS
3264d4f2939cSRui Paulo 	  }
3265d4f2939cSRui Paulo 	},
3266325151a3SRui Paulo 	{ "Cancel", WPAS_DBUS_NEW_IFACE_WPS,
3267325151a3SRui Paulo 	  (WPADBusMethodHandler) wpas_dbus_handler_wps_cancel,
3268325151a3SRui Paulo 	  {
3269325151a3SRui Paulo 		  END_ARGS
3270325151a3SRui Paulo 	  }
3271325151a3SRui Paulo 	},
3272d4f2939cSRui Paulo #endif /* CONFIG_WPS */
3273d4f2939cSRui Paulo #ifdef CONFIG_P2P
3274d4f2939cSRui Paulo 	{ "Find", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
3275d4f2939cSRui Paulo 	  (WPADBusMethodHandler) wpas_dbus_handler_p2p_find,
3276d4f2939cSRui Paulo 	  {
3277d4f2939cSRui Paulo 		  { "args", "a{sv}", ARG_IN },
3278d4f2939cSRui Paulo 		  END_ARGS
3279d4f2939cSRui Paulo 	  }
3280d4f2939cSRui Paulo 	},
3281d4f2939cSRui Paulo 	{ "StopFind", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
3282d4f2939cSRui Paulo 	  (WPADBusMethodHandler) wpas_dbus_handler_p2p_stop_find,
3283d4f2939cSRui Paulo 	  {
3284d4f2939cSRui Paulo 		  END_ARGS
3285d4f2939cSRui Paulo 	  }
3286d4f2939cSRui Paulo 	},
3287d4f2939cSRui Paulo 	{ "Listen", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
3288d4f2939cSRui Paulo 	  (WPADBusMethodHandler) wpas_dbus_handler_p2p_listen,
3289d4f2939cSRui Paulo 	  {
3290d4f2939cSRui Paulo 		  { "timeout", "i", ARG_IN },
3291d4f2939cSRui Paulo 		  END_ARGS
3292d4f2939cSRui Paulo 	  }
3293d4f2939cSRui Paulo 	},
3294d4f2939cSRui Paulo 	{ "ExtendedListen", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
3295d4f2939cSRui Paulo 	  (WPADBusMethodHandler) wpas_dbus_handler_p2p_extendedlisten,
3296d4f2939cSRui Paulo 	  {
3297d4f2939cSRui Paulo 		  { "args", "a{sv}", ARG_IN },
3298d4f2939cSRui Paulo 		  END_ARGS
3299d4f2939cSRui Paulo 	  }
3300d4f2939cSRui Paulo 	},
3301d4f2939cSRui Paulo 	{ "PresenceRequest", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
3302d4f2939cSRui Paulo 	  (WPADBusMethodHandler) wpas_dbus_handler_p2p_presence_request,
3303d4f2939cSRui Paulo 	  {
3304d4f2939cSRui Paulo 		  { "args", "a{sv}", ARG_IN },
3305d4f2939cSRui Paulo 		  END_ARGS
3306d4f2939cSRui Paulo 	  }
3307d4f2939cSRui Paulo 	},
3308d4f2939cSRui Paulo 	{ "ProvisionDiscoveryRequest", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
3309d4f2939cSRui Paulo 	  (WPADBusMethodHandler) wpas_dbus_handler_p2p_prov_disc_req,
3310d4f2939cSRui Paulo 	  {
3311d4f2939cSRui Paulo 		  { "peer", "o", ARG_IN },
3312d4f2939cSRui Paulo 		  { "config_method", "s", ARG_IN },
3313d4f2939cSRui Paulo 		  END_ARGS
3314d4f2939cSRui Paulo 	  }
3315d4f2939cSRui Paulo 	},
3316d4f2939cSRui Paulo 	{ "Connect", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
3317d4f2939cSRui Paulo 	  (WPADBusMethodHandler) wpas_dbus_handler_p2p_connect,
3318d4f2939cSRui Paulo 	  {
3319d4f2939cSRui Paulo 		  { "args", "a{sv}", ARG_IN },
3320d4f2939cSRui Paulo 		  { "generated_pin", "s", ARG_OUT },
3321d4f2939cSRui Paulo 		  END_ARGS
3322d4f2939cSRui Paulo 	  }
3323d4f2939cSRui Paulo 	},
3324d4f2939cSRui Paulo 	{ "GroupAdd", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
3325d4f2939cSRui Paulo 	  (WPADBusMethodHandler) wpas_dbus_handler_p2p_group_add,
3326d4f2939cSRui Paulo 	  {
3327d4f2939cSRui Paulo 		  { "args", "a{sv}", ARG_IN },
3328d4f2939cSRui Paulo 		  END_ARGS
3329d4f2939cSRui Paulo 	  }
3330d4f2939cSRui Paulo 	},
3331325151a3SRui Paulo 	{ "Cancel", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
3332325151a3SRui Paulo 	  (WPADBusMethodHandler) wpas_dbus_handler_p2p_cancel,
3333325151a3SRui Paulo 	  {
3334325151a3SRui Paulo 		  END_ARGS
3335325151a3SRui Paulo 	  }
3336325151a3SRui Paulo 	},
3337d4f2939cSRui Paulo 	{ "Invite", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
3338d4f2939cSRui Paulo 	  (WPADBusMethodHandler) wpas_dbus_handler_p2p_invite,
3339d4f2939cSRui Paulo 	  {
3340d4f2939cSRui Paulo 		  { "args", "a{sv}", ARG_IN },
3341d4f2939cSRui Paulo 		  END_ARGS
3342d4f2939cSRui Paulo 	  }
3343d4f2939cSRui Paulo 	},
3344d4f2939cSRui Paulo 	{ "Disconnect", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
3345d4f2939cSRui Paulo 	  (WPADBusMethodHandler) wpas_dbus_handler_p2p_disconnect,
3346d4f2939cSRui Paulo 	  {
3347d4f2939cSRui Paulo 		  END_ARGS
3348d4f2939cSRui Paulo 	  }
3349d4f2939cSRui Paulo 	},
3350d4f2939cSRui Paulo 	{ "RejectPeer", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
3351d4f2939cSRui Paulo 	  (WPADBusMethodHandler) wpas_dbus_handler_p2p_rejectpeer,
3352d4f2939cSRui Paulo 	  {
3353d4f2939cSRui Paulo 		  { "peer", "o", ARG_IN },
3354d4f2939cSRui Paulo 		  END_ARGS
3355d4f2939cSRui Paulo 	  }
3356d4f2939cSRui Paulo 	},
3357325151a3SRui Paulo 	{ "RemoveClient", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
3358325151a3SRui Paulo 	  (WPADBusMethodHandler) wpas_dbus_handler_p2p_remove_client,
3359325151a3SRui Paulo 	  {
3360325151a3SRui Paulo 		  { "args", "a{sv}", ARG_IN },
3361325151a3SRui Paulo 		  END_ARGS
3362325151a3SRui Paulo 	  }
3363325151a3SRui Paulo 	},
3364d4f2939cSRui Paulo 	{ "Flush", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
3365d4f2939cSRui Paulo 	  (WPADBusMethodHandler) wpas_dbus_handler_p2p_flush,
3366d4f2939cSRui Paulo 	  {
3367d4f2939cSRui Paulo 		  END_ARGS
3368d4f2939cSRui Paulo 	  }
3369d4f2939cSRui Paulo 	},
3370d4f2939cSRui Paulo 	{ "AddService", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
3371d4f2939cSRui Paulo 	  (WPADBusMethodHandler) wpas_dbus_handler_p2p_add_service,
3372d4f2939cSRui Paulo 	  {
3373d4f2939cSRui Paulo 		  { "args", "a{sv}", ARG_IN },
3374d4f2939cSRui Paulo 		  END_ARGS
3375d4f2939cSRui Paulo 	  }
3376d4f2939cSRui Paulo 	},
3377d4f2939cSRui Paulo 	{ "DeleteService", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
3378d4f2939cSRui Paulo 	  (WPADBusMethodHandler) wpas_dbus_handler_p2p_delete_service,
3379d4f2939cSRui Paulo 	  {
3380d4f2939cSRui Paulo 		  { "args", "a{sv}", ARG_IN },
3381d4f2939cSRui Paulo 		  END_ARGS
3382d4f2939cSRui Paulo 	  }
3383d4f2939cSRui Paulo 	},
3384d4f2939cSRui Paulo 	{ "FlushService", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
3385d4f2939cSRui Paulo 	  (WPADBusMethodHandler) wpas_dbus_handler_p2p_flush_service,
3386d4f2939cSRui Paulo 	  {
3387d4f2939cSRui Paulo 		  END_ARGS
3388d4f2939cSRui Paulo 	  }
3389d4f2939cSRui Paulo 	},
3390d4f2939cSRui Paulo 	{ "ServiceDiscoveryRequest", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
3391d4f2939cSRui Paulo 	  (WPADBusMethodHandler) wpas_dbus_handler_p2p_service_sd_req,
3392d4f2939cSRui Paulo 	  {
3393d4f2939cSRui Paulo 		  { "args", "a{sv}", ARG_IN },
33945b9c547cSRui Paulo 		  { "ref", "t", ARG_OUT },
3395d4f2939cSRui Paulo 		  END_ARGS
3396d4f2939cSRui Paulo 	  }
3397d4f2939cSRui Paulo 	},
3398d4f2939cSRui Paulo 	{ "ServiceDiscoveryResponse", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
3399d4f2939cSRui Paulo 	  (WPADBusMethodHandler) wpas_dbus_handler_p2p_service_sd_res,
3400d4f2939cSRui Paulo 	  {
3401d4f2939cSRui Paulo 		  { "args", "a{sv}", ARG_IN },
3402d4f2939cSRui Paulo 		  END_ARGS
3403d4f2939cSRui Paulo 	  }
3404d4f2939cSRui Paulo 	},
3405d4f2939cSRui Paulo 	{ "ServiceDiscoveryCancelRequest", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
3406d4f2939cSRui Paulo 	  (WPADBusMethodHandler) wpas_dbus_handler_p2p_service_sd_cancel_req,
3407d4f2939cSRui Paulo 	  {
3408d4f2939cSRui Paulo 		  { "args", "t", ARG_IN },
3409d4f2939cSRui Paulo 		  END_ARGS
3410d4f2939cSRui Paulo 	  }
3411d4f2939cSRui Paulo 	},
3412d4f2939cSRui Paulo 	{ "ServiceUpdate", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
3413d4f2939cSRui Paulo 	  (WPADBusMethodHandler) wpas_dbus_handler_p2p_service_update,
3414d4f2939cSRui Paulo 	  {
3415d4f2939cSRui Paulo 		  END_ARGS
3416d4f2939cSRui Paulo 	  }
3417d4f2939cSRui Paulo 	},
3418d4f2939cSRui Paulo 	{ "ServiceDiscoveryExternal", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
3419d4f2939cSRui Paulo 	  (WPADBusMethodHandler) wpas_dbus_handler_p2p_serv_disc_external,
3420d4f2939cSRui Paulo 	  {
3421d4f2939cSRui Paulo 		  { "arg", "i", ARG_IN },
3422d4f2939cSRui Paulo 		  END_ARGS
3423d4f2939cSRui Paulo 	  }
3424d4f2939cSRui Paulo 	},
3425d4f2939cSRui Paulo 	{ "AddPersistentGroup", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
3426d4f2939cSRui Paulo 	  (WPADBusMethodHandler) wpas_dbus_handler_add_persistent_group,
3427d4f2939cSRui Paulo 	  {
3428d4f2939cSRui Paulo 		  { "args", "a{sv}", ARG_IN },
3429d4f2939cSRui Paulo 		  { "path", "o", ARG_OUT },
3430d4f2939cSRui Paulo 		  END_ARGS
3431d4f2939cSRui Paulo 	  }
3432d4f2939cSRui Paulo 	},
3433d4f2939cSRui Paulo 	{ "RemovePersistentGroup", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
3434d4f2939cSRui Paulo 	  (WPADBusMethodHandler) wpas_dbus_handler_remove_persistent_group,
3435d4f2939cSRui Paulo 	  {
3436d4f2939cSRui Paulo 		  { "path", "o", ARG_IN },
3437d4f2939cSRui Paulo 		  END_ARGS
3438d4f2939cSRui Paulo 	  }
3439d4f2939cSRui Paulo 	},
3440d4f2939cSRui Paulo 	{ "RemoveAllPersistentGroups", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
3441d4f2939cSRui Paulo 	  (WPADBusMethodHandler)
3442d4f2939cSRui Paulo 	  wpas_dbus_handler_remove_all_persistent_groups,
3443d4f2939cSRui Paulo 	  {
3444d4f2939cSRui Paulo 		  END_ARGS
3445d4f2939cSRui Paulo 	  }
3446d4f2939cSRui Paulo 	},
3447d4f2939cSRui Paulo #endif /* CONFIG_P2P */
3448d4f2939cSRui Paulo 	{ "FlushBSS", WPAS_DBUS_NEW_IFACE_INTERFACE,
34495b9c547cSRui Paulo 	  (WPADBusMethodHandler) wpas_dbus_handler_flush_bss,
3450d4f2939cSRui Paulo 	  {
3451d4f2939cSRui Paulo 		  { "age", "u", ARG_IN },
3452d4f2939cSRui Paulo 		  END_ARGS
3453d4f2939cSRui Paulo 	  }
3454d4f2939cSRui Paulo 	},
3455d4f2939cSRui Paulo #ifdef CONFIG_AP
3456d4f2939cSRui Paulo 	{ "SubscribeProbeReq", WPAS_DBUS_NEW_IFACE_INTERFACE,
3457d4f2939cSRui Paulo 	  (WPADBusMethodHandler) wpas_dbus_handler_subscribe_preq,
3458d4f2939cSRui Paulo 	  {
3459d4f2939cSRui Paulo 		  END_ARGS
3460d4f2939cSRui Paulo 	  }
3461d4f2939cSRui Paulo 	},
3462d4f2939cSRui Paulo 	{ "UnsubscribeProbeReq", WPAS_DBUS_NEW_IFACE_INTERFACE,
3463d4f2939cSRui Paulo 	  (WPADBusMethodHandler) wpas_dbus_handler_unsubscribe_preq,
3464d4f2939cSRui Paulo 	  {
3465d4f2939cSRui Paulo 		  END_ARGS
3466d4f2939cSRui Paulo 	  }
3467d4f2939cSRui Paulo 	},
3468d4f2939cSRui Paulo #endif /* CONFIG_AP */
34695b9c547cSRui Paulo 	{ "EAPLogoff", WPAS_DBUS_NEW_IFACE_INTERFACE,
34705b9c547cSRui Paulo 	  (WPADBusMethodHandler) wpas_dbus_handler_eap_logoff,
34715b9c547cSRui Paulo 	  {
34725b9c547cSRui Paulo 		  END_ARGS
34735b9c547cSRui Paulo 	  }
34745b9c547cSRui Paulo 	},
34755b9c547cSRui Paulo 	{ "EAPLogon", WPAS_DBUS_NEW_IFACE_INTERFACE,
34765b9c547cSRui Paulo 	  (WPADBusMethodHandler) wpas_dbus_handler_eap_logon,
34775b9c547cSRui Paulo 	  {
34785b9c547cSRui Paulo 		  END_ARGS
34795b9c547cSRui Paulo 	  }
34805b9c547cSRui Paulo 	},
34815b9c547cSRui Paulo #ifdef CONFIG_AUTOSCAN
34825b9c547cSRui Paulo 	{ "AutoScan", WPAS_DBUS_NEW_IFACE_INTERFACE,
34835b9c547cSRui Paulo 	  (WPADBusMethodHandler) wpas_dbus_handler_autoscan,
34845b9c547cSRui Paulo 	  {
34855b9c547cSRui Paulo 		  { "arg", "s", ARG_IN },
34865b9c547cSRui Paulo 		  END_ARGS
34875b9c547cSRui Paulo 	  }
34885b9c547cSRui Paulo 	},
34895b9c547cSRui Paulo #endif /* CONFIG_AUTOSCAN */
34905b9c547cSRui Paulo #ifdef CONFIG_TDLS
34915b9c547cSRui Paulo 	{ "TDLSDiscover", WPAS_DBUS_NEW_IFACE_INTERFACE,
34925b9c547cSRui Paulo 	  (WPADBusMethodHandler) wpas_dbus_handler_tdls_discover,
34935b9c547cSRui Paulo 	  {
34945b9c547cSRui Paulo 		  { "peer_address", "s", ARG_IN },
34955b9c547cSRui Paulo 		  END_ARGS
34965b9c547cSRui Paulo 	  }
34975b9c547cSRui Paulo 	},
34985b9c547cSRui Paulo 	{ "TDLSSetup", WPAS_DBUS_NEW_IFACE_INTERFACE,
34995b9c547cSRui Paulo 	  (WPADBusMethodHandler) wpas_dbus_handler_tdls_setup,
35005b9c547cSRui Paulo 	  {
35015b9c547cSRui Paulo 		  { "peer_address", "s", ARG_IN },
35025b9c547cSRui Paulo 		  END_ARGS
35035b9c547cSRui Paulo 	  }
35045b9c547cSRui Paulo 	},
35055b9c547cSRui Paulo 	{ "TDLSStatus", WPAS_DBUS_NEW_IFACE_INTERFACE,
35065b9c547cSRui Paulo 	  (WPADBusMethodHandler) wpas_dbus_handler_tdls_status,
35075b9c547cSRui Paulo 	  {
35085b9c547cSRui Paulo 		  { "peer_address", "s", ARG_IN },
35095b9c547cSRui Paulo 		  { "status", "s", ARG_OUT },
35105b9c547cSRui Paulo 		  END_ARGS
35115b9c547cSRui Paulo 	  }
35125b9c547cSRui Paulo 	},
35135b9c547cSRui Paulo 	{ "TDLSTeardown", WPAS_DBUS_NEW_IFACE_INTERFACE,
35145b9c547cSRui Paulo 	  (WPADBusMethodHandler) wpas_dbus_handler_tdls_teardown,
35155b9c547cSRui Paulo 	  {
35165b9c547cSRui Paulo 		  { "peer_address", "s", ARG_IN },
35175b9c547cSRui Paulo 		  END_ARGS
35185b9c547cSRui Paulo 	  }
35195b9c547cSRui Paulo 	},
352085732ac8SCy Schubert 	{ "TDLSChannelSwitch", WPAS_DBUS_NEW_IFACE_INTERFACE,
352185732ac8SCy Schubert 	  (WPADBusMethodHandler) wpas_dbus_handler_tdls_channel_switch,
352285732ac8SCy Schubert 	  {
352385732ac8SCy Schubert 		  { "args", "a{sv}", ARG_IN },
352485732ac8SCy Schubert 		  END_ARGS
352585732ac8SCy Schubert 	  }
352685732ac8SCy Schubert 	},
352785732ac8SCy Schubert 	{ "TDLSCancelChannelSwitch", WPAS_DBUS_NEW_IFACE_INTERFACE,
352885732ac8SCy Schubert 	  (WPADBusMethodHandler) wpas_dbus_handler_tdls_cancel_channel_switch,
352985732ac8SCy Schubert 	  {
353085732ac8SCy Schubert 		  { "peer_address", "s", ARG_IN },
353185732ac8SCy Schubert 		  END_ARGS
353285732ac8SCy Schubert 	  }
353385732ac8SCy Schubert 	},
35345b9c547cSRui Paulo #endif /* CONFIG_TDLS */
3535780fb4a2SCy Schubert 	{ "VendorElemAdd", WPAS_DBUS_NEW_IFACE_INTERFACE,
3536780fb4a2SCy Schubert 	  (WPADBusMethodHandler) wpas_dbus_handler_vendor_elem_add,
3537780fb4a2SCy Schubert 	  {
3538780fb4a2SCy Schubert 		  { "frame_id", "i", ARG_IN },
3539780fb4a2SCy Schubert 		  { "ielems", "ay", ARG_IN },
3540780fb4a2SCy Schubert 		  END_ARGS
3541780fb4a2SCy Schubert 	  }
3542780fb4a2SCy Schubert 	},
3543780fb4a2SCy Schubert 	{ "VendorElemGet", WPAS_DBUS_NEW_IFACE_INTERFACE,
3544780fb4a2SCy Schubert 	  (WPADBusMethodHandler) wpas_dbus_handler_vendor_elem_get,
3545780fb4a2SCy Schubert 	  {
3546780fb4a2SCy Schubert 		  { "frame_id", "i", ARG_IN },
3547780fb4a2SCy Schubert 		  { "ielems", "ay", ARG_OUT },
3548780fb4a2SCy Schubert 		  END_ARGS
3549780fb4a2SCy Schubert 	  }
3550780fb4a2SCy Schubert 	},
3551780fb4a2SCy Schubert 	{ "VendorElemRem", WPAS_DBUS_NEW_IFACE_INTERFACE,
3552780fb4a2SCy Schubert 	  (WPADBusMethodHandler) wpas_dbus_handler_vendor_elem_remove,
3553780fb4a2SCy Schubert 	  {
3554780fb4a2SCy Schubert 		  { "frame_id", "i", ARG_IN },
3555780fb4a2SCy Schubert 		  { "ielems", "ay", ARG_IN },
3556780fb4a2SCy Schubert 		  END_ARGS
3557780fb4a2SCy Schubert 	  }
3558780fb4a2SCy Schubert 	},
3559780fb4a2SCy Schubert #ifndef CONFIG_NO_CONFIG_WRITE
3560780fb4a2SCy Schubert 	{ "SaveConfig", WPAS_DBUS_NEW_IFACE_INTERFACE,
3561780fb4a2SCy Schubert 	  (WPADBusMethodHandler) wpas_dbus_handler_save_config,
3562780fb4a2SCy Schubert 	  {
3563780fb4a2SCy Schubert 		  END_ARGS
3564780fb4a2SCy Schubert 	  }
3565780fb4a2SCy Schubert 	},
3566780fb4a2SCy Schubert #endif /* CONFIG_NO_CONFIG_WRITE */
356785732ac8SCy Schubert 	{ "AbortScan", WPAS_DBUS_NEW_IFACE_INTERFACE,
356885732ac8SCy Schubert 	  (WPADBusMethodHandler) wpas_dbus_handler_abort_scan,
356985732ac8SCy Schubert 	  {
357085732ac8SCy Schubert 		  END_ARGS
357185732ac8SCy Schubert 	  }
357285732ac8SCy Schubert 	},
3573d4f2939cSRui Paulo 	{ NULL, NULL, NULL, { END_ARGS } }
3574d4f2939cSRui Paulo };
3575d4f2939cSRui Paulo 
3576d4f2939cSRui Paulo static const struct wpa_dbus_property_desc wpas_dbus_interface_properties[] = {
3577d4f2939cSRui Paulo 	{ "Capabilities", WPAS_DBUS_NEW_IFACE_INTERFACE, "a{sv}",
3578d4f2939cSRui Paulo 	  wpas_dbus_getter_capabilities,
3579780fb4a2SCy Schubert 	  NULL,
3580d4f2939cSRui Paulo 	  NULL
3581d4f2939cSRui Paulo 	},
3582d4f2939cSRui Paulo 	{ "State", WPAS_DBUS_NEW_IFACE_INTERFACE, "s",
3583d4f2939cSRui Paulo 	  wpas_dbus_getter_state,
3584780fb4a2SCy Schubert 	  NULL,
3585d4f2939cSRui Paulo 	  NULL
3586d4f2939cSRui Paulo 	},
3587d4f2939cSRui Paulo 	{ "Scanning", WPAS_DBUS_NEW_IFACE_INTERFACE, "b",
3588d4f2939cSRui Paulo 	  wpas_dbus_getter_scanning,
3589780fb4a2SCy Schubert 	  NULL,
3590d4f2939cSRui Paulo 	  NULL
3591d4f2939cSRui Paulo 	},
3592d4f2939cSRui Paulo 	{ "ApScan", WPAS_DBUS_NEW_IFACE_INTERFACE, "u",
3593d4f2939cSRui Paulo 	  wpas_dbus_getter_ap_scan,
3594780fb4a2SCy Schubert 	  wpas_dbus_setter_ap_scan,
3595780fb4a2SCy Schubert 	  NULL
3596d4f2939cSRui Paulo 	},
3597d4f2939cSRui Paulo 	{ "BSSExpireAge", WPAS_DBUS_NEW_IFACE_INTERFACE, "u",
3598d4f2939cSRui Paulo 	  wpas_dbus_getter_bss_expire_age,
3599780fb4a2SCy Schubert 	  wpas_dbus_setter_bss_expire_age,
3600780fb4a2SCy Schubert 	  NULL
3601d4f2939cSRui Paulo 	},
3602d4f2939cSRui Paulo 	{ "BSSExpireCount", WPAS_DBUS_NEW_IFACE_INTERFACE, "u",
3603d4f2939cSRui Paulo 	  wpas_dbus_getter_bss_expire_count,
3604780fb4a2SCy Schubert 	  wpas_dbus_setter_bss_expire_count,
3605780fb4a2SCy Schubert 	  NULL
3606d4f2939cSRui Paulo 	},
3607d4f2939cSRui Paulo 	{ "Country", WPAS_DBUS_NEW_IFACE_INTERFACE, "s",
3608d4f2939cSRui Paulo 	  wpas_dbus_getter_country,
3609780fb4a2SCy Schubert 	  wpas_dbus_setter_country,
3610780fb4a2SCy Schubert 	  NULL
3611d4f2939cSRui Paulo 	},
3612d4f2939cSRui Paulo 	{ "Ifname", WPAS_DBUS_NEW_IFACE_INTERFACE, "s",
3613d4f2939cSRui Paulo 	  wpas_dbus_getter_ifname,
3614780fb4a2SCy Schubert 	  NULL,
3615d4f2939cSRui Paulo 	  NULL
3616d4f2939cSRui Paulo 	},
3617d4f2939cSRui Paulo 	{ "Driver", WPAS_DBUS_NEW_IFACE_INTERFACE, "s",
3618d4f2939cSRui Paulo 	  wpas_dbus_getter_driver,
3619780fb4a2SCy Schubert 	  NULL,
3620d4f2939cSRui Paulo 	  NULL
3621d4f2939cSRui Paulo 	},
3622d4f2939cSRui Paulo 	{ "BridgeIfname", WPAS_DBUS_NEW_IFACE_INTERFACE, "s",
3623d4f2939cSRui Paulo 	  wpas_dbus_getter_bridge_ifname,
3624*c1d255d3SCy Schubert 	  wpas_dbus_setter_bridge_ifname,
3625780fb4a2SCy Schubert 	  NULL
3626780fb4a2SCy Schubert 	},
3627780fb4a2SCy Schubert 	{ "ConfigFile", WPAS_DBUS_NEW_IFACE_INTERFACE, "s",
3628780fb4a2SCy Schubert 	  wpas_dbus_getter_config_file,
3629780fb4a2SCy Schubert 	  NULL,
3630d4f2939cSRui Paulo 	  NULL
3631d4f2939cSRui Paulo 	},
3632d4f2939cSRui Paulo 	{ "CurrentBSS", WPAS_DBUS_NEW_IFACE_INTERFACE, "o",
3633d4f2939cSRui Paulo 	  wpas_dbus_getter_current_bss,
3634780fb4a2SCy Schubert 	  NULL,
3635d4f2939cSRui Paulo 	  NULL
3636d4f2939cSRui Paulo 	},
3637d4f2939cSRui Paulo 	{ "CurrentNetwork", WPAS_DBUS_NEW_IFACE_INTERFACE, "o",
3638d4f2939cSRui Paulo 	  wpas_dbus_getter_current_network,
3639780fb4a2SCy Schubert 	  NULL,
3640d4f2939cSRui Paulo 	  NULL
3641d4f2939cSRui Paulo 	},
3642d4f2939cSRui Paulo 	{ "CurrentAuthMode", WPAS_DBUS_NEW_IFACE_INTERFACE, "s",
3643d4f2939cSRui Paulo 	  wpas_dbus_getter_current_auth_mode,
3644780fb4a2SCy Schubert 	  NULL,
3645d4f2939cSRui Paulo 	  NULL
3646d4f2939cSRui Paulo 	},
3647d4f2939cSRui Paulo 	{ "Blobs", WPAS_DBUS_NEW_IFACE_INTERFACE, "a{say}",
3648d4f2939cSRui Paulo 	  wpas_dbus_getter_blobs,
3649780fb4a2SCy Schubert 	  NULL,
3650d4f2939cSRui Paulo 	  NULL
3651d4f2939cSRui Paulo 	},
3652d4f2939cSRui Paulo 	{ "BSSs", WPAS_DBUS_NEW_IFACE_INTERFACE, "ao",
3653d4f2939cSRui Paulo 	  wpas_dbus_getter_bsss,
3654780fb4a2SCy Schubert 	  NULL,
3655d4f2939cSRui Paulo 	  NULL
3656d4f2939cSRui Paulo 	},
3657d4f2939cSRui Paulo 	{ "Networks", WPAS_DBUS_NEW_IFACE_INTERFACE, "ao",
3658d4f2939cSRui Paulo 	  wpas_dbus_getter_networks,
3659780fb4a2SCy Schubert 	  NULL,
3660d4f2939cSRui Paulo 	  NULL
3661d4f2939cSRui Paulo 	},
3662d4f2939cSRui Paulo 	{ "FastReauth", WPAS_DBUS_NEW_IFACE_INTERFACE, "b",
3663d4f2939cSRui Paulo 	  wpas_dbus_getter_fast_reauth,
3664780fb4a2SCy Schubert 	  wpas_dbus_setter_fast_reauth,
3665780fb4a2SCy Schubert 	  NULL
3666d4f2939cSRui Paulo 	},
3667d4f2939cSRui Paulo 	{ "ScanInterval", WPAS_DBUS_NEW_IFACE_INTERFACE, "i",
3668d4f2939cSRui Paulo 	  wpas_dbus_getter_scan_interval,
3669780fb4a2SCy Schubert 	  wpas_dbus_setter_scan_interval,
3670780fb4a2SCy Schubert 	  NULL
3671d4f2939cSRui Paulo 	},
36725b9c547cSRui Paulo 	{ "PKCS11EnginePath", WPAS_DBUS_NEW_IFACE_INTERFACE, "s",
36735b9c547cSRui Paulo 	  wpas_dbus_getter_pkcs11_engine_path,
3674780fb4a2SCy Schubert 	  NULL,
36755b9c547cSRui Paulo 	  NULL
36765b9c547cSRui Paulo 	},
36775b9c547cSRui Paulo 	{ "PKCS11ModulePath", WPAS_DBUS_NEW_IFACE_INTERFACE, "s",
36785b9c547cSRui Paulo 	  wpas_dbus_getter_pkcs11_module_path,
3679780fb4a2SCy Schubert 	  NULL,
36805b9c547cSRui Paulo 	  NULL
36815b9c547cSRui Paulo 	},
3682d4f2939cSRui Paulo #ifdef CONFIG_WPS
3683d4f2939cSRui Paulo 	{ "ProcessCredentials", WPAS_DBUS_NEW_IFACE_WPS, "b",
3684d4f2939cSRui Paulo 	  wpas_dbus_getter_process_credentials,
3685780fb4a2SCy Schubert 	  wpas_dbus_setter_process_credentials,
3686780fb4a2SCy Schubert 	  NULL
3687d4f2939cSRui Paulo 	},
36885b9c547cSRui Paulo 	{ "ConfigMethods", WPAS_DBUS_NEW_IFACE_WPS, "s",
36895b9c547cSRui Paulo 	  wpas_dbus_getter_config_methods,
3690780fb4a2SCy Schubert 	  wpas_dbus_setter_config_methods,
3691780fb4a2SCy Schubert 	  NULL
36925b9c547cSRui Paulo 	},
369385732ac8SCy Schubert 	{
369485732ac8SCy Schubert 	  "DeviceName", WPAS_DBUS_NEW_IFACE_WPS, "s",
369585732ac8SCy Schubert 	  wpas_dbus_getter_wps_device_name,
369685732ac8SCy Schubert 	  wpas_dbus_setter_wps_device_name,
369785732ac8SCy Schubert 	  NULL
369885732ac8SCy Schubert 	},
369985732ac8SCy Schubert 	{
370085732ac8SCy Schubert 	  "Manufacturer", WPAS_DBUS_NEW_IFACE_WPS, "s",
370185732ac8SCy Schubert 	  wpas_dbus_getter_wps_manufacturer,
370285732ac8SCy Schubert 	  wpas_dbus_setter_wps_manufacturer,
370385732ac8SCy Schubert 	  NULL
370485732ac8SCy Schubert 	},
370585732ac8SCy Schubert 	{
370685732ac8SCy Schubert 	  "ModelName", WPAS_DBUS_NEW_IFACE_WPS, "s",
370785732ac8SCy Schubert 	  wpas_dbus_getter_wps_device_model_name,
370885732ac8SCy Schubert 	  wpas_dbus_setter_wps_device_model_name,
370985732ac8SCy Schubert 	  NULL
371085732ac8SCy Schubert 	},
371185732ac8SCy Schubert 	{
371285732ac8SCy Schubert 	  "ModelNumber", WPAS_DBUS_NEW_IFACE_WPS, "s",
371385732ac8SCy Schubert 	  wpas_dbus_getter_wps_device_model_number,
371485732ac8SCy Schubert 	  wpas_dbus_setter_wps_device_model_number,
371585732ac8SCy Schubert 	  NULL
371685732ac8SCy Schubert 	},
371785732ac8SCy Schubert 	{
371885732ac8SCy Schubert 	  "SerialNumber", WPAS_DBUS_NEW_IFACE_WPS, "s",
371985732ac8SCy Schubert 	  wpas_dbus_getter_wps_device_serial_number,
372085732ac8SCy Schubert 	  wpas_dbus_setter_wps_device_serial_number,
372185732ac8SCy Schubert 	  NULL
372285732ac8SCy Schubert 	},
372385732ac8SCy Schubert 	{
372485732ac8SCy Schubert 	  "DeviceType", WPAS_DBUS_NEW_IFACE_WPS, "ay",
372585732ac8SCy Schubert 	  wpas_dbus_getter_wps_device_device_type,
372685732ac8SCy Schubert 	  wpas_dbus_setter_wps_device_device_type,
372785732ac8SCy Schubert 	  NULL
372885732ac8SCy Schubert 	},
3729d4f2939cSRui Paulo #endif /* CONFIG_WPS */
3730d4f2939cSRui Paulo #ifdef CONFIG_P2P
3731d4f2939cSRui Paulo 	{ "P2PDeviceConfig", WPAS_DBUS_NEW_IFACE_P2PDEVICE, "a{sv}",
3732d4f2939cSRui Paulo 	  wpas_dbus_getter_p2p_device_config,
3733780fb4a2SCy Schubert 	  wpas_dbus_setter_p2p_device_config,
3734780fb4a2SCy Schubert 	  NULL
3735d4f2939cSRui Paulo 	},
3736d4f2939cSRui Paulo 	{ "Peers", WPAS_DBUS_NEW_IFACE_P2PDEVICE, "ao",
3737d4f2939cSRui Paulo 	  wpas_dbus_getter_p2p_peers,
3738780fb4a2SCy Schubert 	  NULL,
3739d4f2939cSRui Paulo 	  NULL
3740d4f2939cSRui Paulo 	},
3741d4f2939cSRui Paulo 	{ "Role", WPAS_DBUS_NEW_IFACE_P2PDEVICE, "s",
3742d4f2939cSRui Paulo 	  wpas_dbus_getter_p2p_role,
3743780fb4a2SCy Schubert 	  NULL,
3744d4f2939cSRui Paulo 	  NULL
3745d4f2939cSRui Paulo 	},
3746d4f2939cSRui Paulo 	{ "Group", WPAS_DBUS_NEW_IFACE_P2PDEVICE, "o",
3747d4f2939cSRui Paulo 	  wpas_dbus_getter_p2p_group,
3748780fb4a2SCy Schubert 	  NULL,
3749d4f2939cSRui Paulo 	  NULL
3750d4f2939cSRui Paulo 	},
3751d4f2939cSRui Paulo 	{ "PeerGO", WPAS_DBUS_NEW_IFACE_P2PDEVICE, "o",
3752d4f2939cSRui Paulo 	  wpas_dbus_getter_p2p_peergo,
3753780fb4a2SCy Schubert 	  NULL,
3754d4f2939cSRui Paulo 	  NULL
3755d4f2939cSRui Paulo 	},
3756d4f2939cSRui Paulo 	{ "PersistentGroups", WPAS_DBUS_NEW_IFACE_P2PDEVICE, "ao",
3757d4f2939cSRui Paulo 	  wpas_dbus_getter_persistent_groups,
3758780fb4a2SCy Schubert 	  NULL,
3759d4f2939cSRui Paulo 	  NULL
3760d4f2939cSRui Paulo 	},
3761d4f2939cSRui Paulo #endif /* CONFIG_P2P */
3762d4f2939cSRui Paulo 	{ "DisconnectReason", WPAS_DBUS_NEW_IFACE_INTERFACE, "i",
3763d4f2939cSRui Paulo 	  wpas_dbus_getter_disconnect_reason,
3764780fb4a2SCy Schubert 	  NULL,
3765d4f2939cSRui Paulo 	  NULL
3766d4f2939cSRui Paulo 	},
37674bc52338SCy Schubert 	{ "AuthStatusCode", WPAS_DBUS_NEW_IFACE_INTERFACE, "i",
37684bc52338SCy Schubert 	  wpas_dbus_getter_auth_status_code,
37694bc52338SCy Schubert 	  NULL,
37704bc52338SCy Schubert 	  NULL
37714bc52338SCy Schubert 	},
3772780fb4a2SCy Schubert 	{ "AssocStatusCode", WPAS_DBUS_NEW_IFACE_INTERFACE, "i",
3773780fb4a2SCy Schubert 	  wpas_dbus_getter_assoc_status_code,
3774780fb4a2SCy Schubert 	  NULL,
3775780fb4a2SCy Schubert 	  NULL
3776780fb4a2SCy Schubert 	},
3777*c1d255d3SCy Schubert 	{
3778*c1d255d3SCy Schubert 	  "RoamTime", WPAS_DBUS_NEW_IFACE_INTERFACE, "u",
3779*c1d255d3SCy Schubert 	  wpas_dbus_getter_roam_time,
3780*c1d255d3SCy Schubert 	  NULL,
3781*c1d255d3SCy Schubert 	  NULL
3782*c1d255d3SCy Schubert 	},
3783*c1d255d3SCy Schubert 	{
3784*c1d255d3SCy Schubert 	  "RoamComplete", WPAS_DBUS_NEW_IFACE_INTERFACE, "b",
3785*c1d255d3SCy Schubert 	  wpas_dbus_getter_roam_complete,
3786*c1d255d3SCy Schubert 	  NULL,
3787*c1d255d3SCy Schubert 	  NULL
3788*c1d255d3SCy Schubert 	},
3789*c1d255d3SCy Schubert 	{
3790*c1d255d3SCy Schubert 	  "SessionLength", WPAS_DBUS_NEW_IFACE_INTERFACE, "u",
3791*c1d255d3SCy Schubert 	  wpas_dbus_getter_session_length,
3792*c1d255d3SCy Schubert 	  NULL,
3793*c1d255d3SCy Schubert 	  NULL
3794*c1d255d3SCy Schubert 	},
3795*c1d255d3SCy Schubert 	{
3796*c1d255d3SCy Schubert 	  "BSSTMStatus", WPAS_DBUS_NEW_IFACE_INTERFACE, "u",
3797*c1d255d3SCy Schubert 	  wpas_dbus_getter_bss_tm_status,
3798*c1d255d3SCy Schubert 	  NULL,
3799*c1d255d3SCy Schubert 	  NULL
3800*c1d255d3SCy Schubert 	},
380185732ac8SCy Schubert #ifdef CONFIG_MESH
380285732ac8SCy Schubert 	{ "MeshPeers", WPAS_DBUS_NEW_IFACE_MESH, "aay",
380385732ac8SCy Schubert 	  wpas_dbus_getter_mesh_peers,
380485732ac8SCy Schubert 	  NULL,
380585732ac8SCy Schubert 	  NULL
380685732ac8SCy Schubert 	},
380785732ac8SCy Schubert 	{ "MeshGroup", WPAS_DBUS_NEW_IFACE_MESH, "ay",
380885732ac8SCy Schubert 	  wpas_dbus_getter_mesh_group,
380985732ac8SCy Schubert 	  NULL,
381085732ac8SCy Schubert 	  NULL
381185732ac8SCy Schubert 	},
381285732ac8SCy Schubert #endif /* CONFIG_MESH */
38134bc52338SCy Schubert 	{ "Stations", WPAS_DBUS_NEW_IFACE_INTERFACE, "ao",
38144bc52338SCy Schubert 	  wpas_dbus_getter_stas,
38154bc52338SCy Schubert 	  NULL,
38164bc52338SCy Schubert 	  NULL
38174bc52338SCy Schubert 	},
3818*c1d255d3SCy Schubert 	{ "MACAddressRandomizationMask", WPAS_DBUS_NEW_IFACE_INTERFACE,
3819*c1d255d3SCy Schubert 	  "a{say}",
3820*c1d255d3SCy Schubert 	  wpas_dbus_getter_mac_address_randomization_mask,
3821*c1d255d3SCy Schubert 	  wpas_dbus_setter_mac_address_randomization_mask,
3822*c1d255d3SCy Schubert 	  NULL
3823*c1d255d3SCy Schubert 	},
3824780fb4a2SCy Schubert 	{ NULL, NULL, NULL, NULL, NULL, NULL }
3825d4f2939cSRui Paulo };
3826d4f2939cSRui Paulo 
3827d4f2939cSRui Paulo static const struct wpa_dbus_signal_desc wpas_dbus_interface_signals[] = {
3828d4f2939cSRui Paulo 	{ "ScanDone", WPAS_DBUS_NEW_IFACE_INTERFACE,
3829d4f2939cSRui Paulo 	  {
3830d4f2939cSRui Paulo 		  { "success", "b", ARG_OUT },
3831d4f2939cSRui Paulo 		  END_ARGS
3832d4f2939cSRui Paulo 	  }
3833d4f2939cSRui Paulo 	},
3834d4f2939cSRui Paulo 	{ "BSSAdded", WPAS_DBUS_NEW_IFACE_INTERFACE,
3835d4f2939cSRui Paulo 	  {
3836d4f2939cSRui Paulo 		  { "path", "o", ARG_OUT },
3837d4f2939cSRui Paulo 		  { "properties", "a{sv}", ARG_OUT },
3838d4f2939cSRui Paulo 		  END_ARGS
3839d4f2939cSRui Paulo 	  }
3840d4f2939cSRui Paulo 	},
3841d4f2939cSRui Paulo 	{ "BSSRemoved", WPAS_DBUS_NEW_IFACE_INTERFACE,
3842d4f2939cSRui Paulo 	  {
3843d4f2939cSRui Paulo 		  { "path", "o", ARG_OUT },
3844d4f2939cSRui Paulo 		  END_ARGS
3845d4f2939cSRui Paulo 	  }
3846d4f2939cSRui Paulo 	},
3847d4f2939cSRui Paulo 	{ "BlobAdded", WPAS_DBUS_NEW_IFACE_INTERFACE,
3848d4f2939cSRui Paulo 	  {
3849d4f2939cSRui Paulo 		  { "name", "s", ARG_OUT },
3850d4f2939cSRui Paulo 		  END_ARGS
3851d4f2939cSRui Paulo 	  }
3852d4f2939cSRui Paulo 	},
3853d4f2939cSRui Paulo 	{ "BlobRemoved", WPAS_DBUS_NEW_IFACE_INTERFACE,
3854d4f2939cSRui Paulo 	  {
3855d4f2939cSRui Paulo 		  { "name", "s", ARG_OUT },
3856d4f2939cSRui Paulo 		  END_ARGS
3857d4f2939cSRui Paulo 	  }
3858d4f2939cSRui Paulo 	},
3859d4f2939cSRui Paulo 	{ "NetworkAdded", WPAS_DBUS_NEW_IFACE_INTERFACE,
3860d4f2939cSRui Paulo 	  {
3861d4f2939cSRui Paulo 		  { "path", "o", ARG_OUT },
3862d4f2939cSRui Paulo 		  { "properties", "a{sv}", ARG_OUT },
3863d4f2939cSRui Paulo 		  END_ARGS
3864d4f2939cSRui Paulo 	  }
3865d4f2939cSRui Paulo 	},
3866d4f2939cSRui Paulo 	{ "NetworkRemoved", WPAS_DBUS_NEW_IFACE_INTERFACE,
3867d4f2939cSRui Paulo 	  {
3868d4f2939cSRui Paulo 		  { "path", "o", ARG_OUT },
3869d4f2939cSRui Paulo 		  END_ARGS
3870d4f2939cSRui Paulo 	  }
3871d4f2939cSRui Paulo 	},
3872d4f2939cSRui Paulo 	{ "NetworkSelected", WPAS_DBUS_NEW_IFACE_INTERFACE,
3873d4f2939cSRui Paulo 	  {
3874d4f2939cSRui Paulo 		  { "path", "o", ARG_OUT },
3875d4f2939cSRui Paulo 		  END_ARGS
3876d4f2939cSRui Paulo 	  }
3877d4f2939cSRui Paulo 	},
3878d4f2939cSRui Paulo 	/* Deprecated: use org.freedesktop.DBus.Properties.PropertiesChanged */
3879d4f2939cSRui Paulo 	{ "PropertiesChanged", WPAS_DBUS_NEW_IFACE_INTERFACE,
3880d4f2939cSRui Paulo 	  {
3881d4f2939cSRui Paulo 		  { "properties", "a{sv}", ARG_OUT },
3882d4f2939cSRui Paulo 		  END_ARGS
3883d4f2939cSRui Paulo 	  }
3884d4f2939cSRui Paulo 	},
3885d4f2939cSRui Paulo #ifdef CONFIG_WPS
3886d4f2939cSRui Paulo 	{ "Event", WPAS_DBUS_NEW_IFACE_WPS,
3887d4f2939cSRui Paulo 	  {
3888d4f2939cSRui Paulo 		  { "name", "s", ARG_OUT },
3889d4f2939cSRui Paulo 		  { "args", "a{sv}", ARG_OUT },
3890d4f2939cSRui Paulo 		  END_ARGS
3891d4f2939cSRui Paulo 	  }
3892d4f2939cSRui Paulo 	},
3893d4f2939cSRui Paulo 	{ "Credentials", WPAS_DBUS_NEW_IFACE_WPS,
3894d4f2939cSRui Paulo 	  {
3895d4f2939cSRui Paulo 		  { "credentials", "a{sv}", ARG_OUT },
3896d4f2939cSRui Paulo 		  END_ARGS
3897d4f2939cSRui Paulo 	  }
3898d4f2939cSRui Paulo 	},
3899d4f2939cSRui Paulo 	/* Deprecated: use org.freedesktop.DBus.Properties.PropertiesChanged */
3900d4f2939cSRui Paulo 	{ "PropertiesChanged", WPAS_DBUS_NEW_IFACE_WPS,
3901d4f2939cSRui Paulo 	  {
3902d4f2939cSRui Paulo 		  { "properties", "a{sv}", ARG_OUT },
3903d4f2939cSRui Paulo 		  END_ARGS
3904d4f2939cSRui Paulo 	  }
3905d4f2939cSRui Paulo 	},
3906d4f2939cSRui Paulo #endif /* CONFIG_WPS */
3907d4f2939cSRui Paulo #ifdef CONFIG_P2P
3908d4f2939cSRui Paulo 	{ "DeviceFound", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
3909d4f2939cSRui Paulo 	  {
3910d4f2939cSRui Paulo 		  { "path", "o", ARG_OUT },
3911d4f2939cSRui Paulo 		  END_ARGS
3912d4f2939cSRui Paulo 	  }
3913d4f2939cSRui Paulo 	},
3914780fb4a2SCy Schubert 	{ "DeviceFoundProperties", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
3915780fb4a2SCy Schubert 	  {
3916780fb4a2SCy Schubert 		  { "path", "o", ARG_OUT },
3917780fb4a2SCy Schubert 		  { "properties", "a{sv}", ARG_OUT },
3918780fb4a2SCy Schubert 		  END_ARGS
3919780fb4a2SCy Schubert 	  }
3920780fb4a2SCy Schubert 	},
3921d4f2939cSRui Paulo 	{ "DeviceLost", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
3922d4f2939cSRui Paulo 	  {
3923d4f2939cSRui Paulo 		  { "path", "o", ARG_OUT },
3924d4f2939cSRui Paulo 		  END_ARGS
3925d4f2939cSRui Paulo 	  }
3926d4f2939cSRui Paulo 	},
3927325151a3SRui Paulo 	{ "FindStopped", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
3928325151a3SRui Paulo 	  {
3929325151a3SRui Paulo 		  END_ARGS
3930325151a3SRui Paulo 	  }
3931325151a3SRui Paulo 	},
3932d4f2939cSRui Paulo 	{ "ProvisionDiscoveryRequestDisplayPin", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
3933d4f2939cSRui Paulo 	  {
3934d4f2939cSRui Paulo 		  { "peer_object", "o", ARG_OUT },
3935d4f2939cSRui Paulo 		  { "pin", "s", ARG_OUT },
3936d4f2939cSRui Paulo 		  END_ARGS
3937d4f2939cSRui Paulo 	  }
3938d4f2939cSRui Paulo 	},
3939d4f2939cSRui Paulo 	{ "ProvisionDiscoveryResponseDisplayPin", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
3940d4f2939cSRui Paulo 	  {
3941d4f2939cSRui Paulo 		  { "peer_object", "o", ARG_OUT },
3942d4f2939cSRui Paulo 		  { "pin", "s", ARG_OUT },
3943d4f2939cSRui Paulo 		  END_ARGS
3944d4f2939cSRui Paulo 	  }
3945d4f2939cSRui Paulo 	},
3946d4f2939cSRui Paulo 	{ "ProvisionDiscoveryRequestEnterPin", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
3947d4f2939cSRui Paulo 	  {
3948d4f2939cSRui Paulo 		  { "peer_object", "o", ARG_OUT },
3949d4f2939cSRui Paulo 		  END_ARGS
3950d4f2939cSRui Paulo 	  }
3951d4f2939cSRui Paulo 	},
3952d4f2939cSRui Paulo 	{ "ProvisionDiscoveryResponseEnterPin", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
3953d4f2939cSRui Paulo 	  {
3954d4f2939cSRui Paulo 		  { "peer_object", "o", ARG_OUT },
3955d4f2939cSRui Paulo 		  END_ARGS
3956d4f2939cSRui Paulo 	  }
3957d4f2939cSRui Paulo 	},
3958d4f2939cSRui Paulo 	{ "ProvisionDiscoveryPBCRequest", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
3959d4f2939cSRui Paulo 	  {
3960d4f2939cSRui Paulo 		  { "peer_object", "o", ARG_OUT },
3961d4f2939cSRui Paulo 		  END_ARGS
3962d4f2939cSRui Paulo 	  }
3963d4f2939cSRui Paulo 	},
3964d4f2939cSRui Paulo 	{ "ProvisionDiscoveryPBCResponse", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
3965d4f2939cSRui Paulo 	  {
3966d4f2939cSRui Paulo 		  { "peer_object", "o", ARG_OUT },
3967d4f2939cSRui Paulo 		  END_ARGS
3968d4f2939cSRui Paulo 	  }
3969d4f2939cSRui Paulo 	},
3970d4f2939cSRui Paulo 	{ "ProvisionDiscoveryFailure", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
3971d4f2939cSRui Paulo 	  {
3972d4f2939cSRui Paulo 		  { "peer_object", "o", ARG_OUT },
3973d4f2939cSRui Paulo 		  { "status", "i", ARG_OUT },
3974d4f2939cSRui Paulo 		  END_ARGS
3975d4f2939cSRui Paulo 	  }
3976d4f2939cSRui Paulo 	},
3977d4f2939cSRui Paulo 	{ "GroupStarted", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
3978d4f2939cSRui Paulo 	  {
3979d4f2939cSRui Paulo 		  { "properties", "a{sv}", ARG_OUT },
3980d4f2939cSRui Paulo 		  END_ARGS
3981d4f2939cSRui Paulo 	  }
3982d4f2939cSRui Paulo 	},
3983325151a3SRui Paulo 	{ "GroupFormationFailure", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
3984325151a3SRui Paulo 	  {
3985325151a3SRui Paulo 		  { "reason", "s", ARG_OUT },
3986325151a3SRui Paulo 		  END_ARGS
3987325151a3SRui Paulo 	  }
3988325151a3SRui Paulo 	},
3989d4f2939cSRui Paulo 	{ "GONegotiationSuccess", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
3990d4f2939cSRui Paulo 	  {
39915b9c547cSRui Paulo 		  { "properties", "a{sv}", ARG_OUT },
3992d4f2939cSRui Paulo 		  END_ARGS
3993d4f2939cSRui Paulo 	  }
3994d4f2939cSRui Paulo 	},
3995d4f2939cSRui Paulo 	{ "GONegotiationFailure", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
3996d4f2939cSRui Paulo 	  {
39975b9c547cSRui Paulo 		  { "properties", "a{sv}", ARG_OUT },
3998d4f2939cSRui Paulo 		  END_ARGS
3999d4f2939cSRui Paulo 	  }
4000d4f2939cSRui Paulo 	},
4001d4f2939cSRui Paulo 	{ "GONegotiationRequest", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
4002d4f2939cSRui Paulo 	  {
4003d4f2939cSRui Paulo 		  { "path", "o", ARG_OUT },
4004325151a3SRui Paulo 		  { "dev_passwd_id", "q", ARG_OUT },
4005325151a3SRui Paulo 		  { "device_go_intent", "y", ARG_OUT },
4006d4f2939cSRui Paulo 		  END_ARGS
4007d4f2939cSRui Paulo 	  }
4008d4f2939cSRui Paulo 	},
4009d4f2939cSRui Paulo 	{ "InvitationResult", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
4010d4f2939cSRui Paulo 	  {
4011d4f2939cSRui Paulo 		  { "invite_result", "a{sv}", ARG_OUT },
4012d4f2939cSRui Paulo 		  END_ARGS
4013d4f2939cSRui Paulo 	  }
4014d4f2939cSRui Paulo 	},
4015d4f2939cSRui Paulo 	{ "GroupFinished", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
4016d4f2939cSRui Paulo 	  {
40175b9c547cSRui Paulo 		  { "properties", "a{sv}", ARG_OUT },
4018d4f2939cSRui Paulo 		  END_ARGS
4019d4f2939cSRui Paulo 	  }
4020d4f2939cSRui Paulo 	},
4021d4f2939cSRui Paulo 	{ "ServiceDiscoveryRequest", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
4022d4f2939cSRui Paulo 	  {
4023d4f2939cSRui Paulo 		  { "sd_request", "a{sv}", ARG_OUT },
4024d4f2939cSRui Paulo 		  END_ARGS
4025d4f2939cSRui Paulo 	  }
4026d4f2939cSRui Paulo 	},
4027d4f2939cSRui Paulo 	{ "ServiceDiscoveryResponse", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
4028d4f2939cSRui Paulo 	  {
4029d4f2939cSRui Paulo 		  { "sd_response", "a{sv}", ARG_OUT },
4030d4f2939cSRui Paulo 		  END_ARGS
4031d4f2939cSRui Paulo 	  }
4032d4f2939cSRui Paulo 	},
4033d4f2939cSRui Paulo 	{ "PersistentGroupAdded", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
4034d4f2939cSRui Paulo 	  {
4035d4f2939cSRui Paulo 		  { "path", "o", ARG_OUT },
4036d4f2939cSRui Paulo 		  { "properties", "a{sv}", ARG_OUT },
4037d4f2939cSRui Paulo 		  END_ARGS
4038d4f2939cSRui Paulo 	  }
4039d4f2939cSRui Paulo 	},
4040d4f2939cSRui Paulo 	{ "PersistentGroupRemoved", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
4041d4f2939cSRui Paulo 	  {
4042d4f2939cSRui Paulo 		  { "path", "o", ARG_OUT },
4043d4f2939cSRui Paulo 		  END_ARGS
4044d4f2939cSRui Paulo 	  }
4045d4f2939cSRui Paulo 	},
4046d4f2939cSRui Paulo 	{ "WpsFailed", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
4047d4f2939cSRui Paulo 	  {
4048d4f2939cSRui Paulo 		  { "name", "s", ARG_OUT },
4049d4f2939cSRui Paulo 		  { "args", "a{sv}", ARG_OUT },
4050d4f2939cSRui Paulo 		  END_ARGS
4051d4f2939cSRui Paulo 	  }
4052d4f2939cSRui Paulo 	},
4053325151a3SRui Paulo 	{ "InvitationReceived", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
4054325151a3SRui Paulo 	  {
4055325151a3SRui Paulo 		  { "properties", "a{sv}", ARG_OUT },
4056325151a3SRui Paulo 		  END_ARGS
4057325151a3SRui Paulo 	  }
4058325151a3SRui Paulo 	},
4059d4f2939cSRui Paulo #endif /* CONFIG_P2P */
4060d4f2939cSRui Paulo #ifdef CONFIG_AP
4061d4f2939cSRui Paulo 	{ "ProbeRequest", WPAS_DBUS_NEW_IFACE_INTERFACE,
4062d4f2939cSRui Paulo 	  {
4063d4f2939cSRui Paulo 		  { "args", "a{sv}", ARG_OUT },
4064d4f2939cSRui Paulo 		  END_ARGS
4065d4f2939cSRui Paulo 	  }
4066d4f2939cSRui Paulo 	},
4067d4f2939cSRui Paulo #endif /* CONFIG_AP */
4068d4f2939cSRui Paulo 	{ "Certification", WPAS_DBUS_NEW_IFACE_INTERFACE,
4069d4f2939cSRui Paulo 	  {
4070d4f2939cSRui Paulo 		  { "certification", "a{sv}", ARG_OUT },
4071d4f2939cSRui Paulo 		  END_ARGS
4072d4f2939cSRui Paulo 	  }
4073d4f2939cSRui Paulo 	},
4074d4f2939cSRui Paulo 	{ "EAP", WPAS_DBUS_NEW_IFACE_INTERFACE,
4075d4f2939cSRui Paulo 	  {
4076d4f2939cSRui Paulo 		  { "status", "s", ARG_OUT },
4077d4f2939cSRui Paulo 		  { "parameter", "s", ARG_OUT },
4078d4f2939cSRui Paulo 		  END_ARGS
4079d4f2939cSRui Paulo 	  }
4080d4f2939cSRui Paulo 	},
40815b9c547cSRui Paulo 	{ "StaAuthorized", WPAS_DBUS_NEW_IFACE_INTERFACE,
40825b9c547cSRui Paulo 	  {
40835b9c547cSRui Paulo 		  { "name", "s", ARG_OUT },
40845b9c547cSRui Paulo 		  END_ARGS
40855b9c547cSRui Paulo 	  }
40865b9c547cSRui Paulo 	},
40875b9c547cSRui Paulo 	{ "StaDeauthorized", WPAS_DBUS_NEW_IFACE_INTERFACE,
40885b9c547cSRui Paulo 	  {
40895b9c547cSRui Paulo 		  { "name", "s", ARG_OUT },
40905b9c547cSRui Paulo 		  END_ARGS
40915b9c547cSRui Paulo 	  }
40925b9c547cSRui Paulo 	},
40934bc52338SCy Schubert 	{ "StationAdded", WPAS_DBUS_NEW_IFACE_INTERFACE,
40944bc52338SCy Schubert 	  {
40954bc52338SCy Schubert 		  { "path", "o", ARG_OUT },
40964bc52338SCy Schubert 		  { "properties", "a{sv}", ARG_OUT },
40974bc52338SCy Schubert 		  END_ARGS
40984bc52338SCy Schubert 	  }
40994bc52338SCy Schubert 	},
41004bc52338SCy Schubert 	{ "StationRemoved", WPAS_DBUS_NEW_IFACE_INTERFACE,
41014bc52338SCy Schubert 	  {
41024bc52338SCy Schubert 		  { "path", "o", ARG_OUT },
41034bc52338SCy Schubert 		  END_ARGS
41044bc52338SCy Schubert 	  }
41054bc52338SCy Schubert 	},
41065b9c547cSRui Paulo 	{ "NetworkRequest", WPAS_DBUS_NEW_IFACE_INTERFACE,
41075b9c547cSRui Paulo 	  {
41085b9c547cSRui Paulo 		  { "path", "o", ARG_OUT },
41095b9c547cSRui Paulo 		  { "field", "s", ARG_OUT },
41105b9c547cSRui Paulo 		  { "text", "s", ARG_OUT },
41115b9c547cSRui Paulo 		  END_ARGS
41125b9c547cSRui Paulo 	  }
41135b9c547cSRui Paulo 	},
411485732ac8SCy Schubert #ifdef CONFIG_MESH
411585732ac8SCy Schubert 	{ "MeshGroupStarted", WPAS_DBUS_NEW_IFACE_MESH,
411685732ac8SCy Schubert 	  {
411785732ac8SCy Schubert 		  { "args", "a{sv}", ARG_OUT },
411885732ac8SCy Schubert 		  END_ARGS
411985732ac8SCy Schubert 	  }
412085732ac8SCy Schubert 	},
412185732ac8SCy Schubert 	{ "MeshGroupRemoved", WPAS_DBUS_NEW_IFACE_MESH,
412285732ac8SCy Schubert 	  {
412385732ac8SCy Schubert 		  { "args", "a{sv}", ARG_OUT },
412485732ac8SCy Schubert 		  END_ARGS
412585732ac8SCy Schubert 	  }
412685732ac8SCy Schubert 	},
412785732ac8SCy Schubert 	{ "MeshPeerConnected", WPAS_DBUS_NEW_IFACE_MESH,
412885732ac8SCy Schubert 	  {
412985732ac8SCy Schubert 		  { "args", "a{sv}", ARG_OUT },
413085732ac8SCy Schubert 		  END_ARGS
413185732ac8SCy Schubert 	  }
413285732ac8SCy Schubert 	},
413385732ac8SCy Schubert 	{ "MeshPeerDisconnected", WPAS_DBUS_NEW_IFACE_MESH,
413485732ac8SCy Schubert 	  {
413585732ac8SCy Schubert 		  { "args", "a{sv}", ARG_OUT },
413685732ac8SCy Schubert 		  END_ARGS
413785732ac8SCy Schubert 	  }
413885732ac8SCy Schubert 	},
413985732ac8SCy Schubert #endif /* CONFIG_MESH */
4140d4f2939cSRui Paulo 	{ NULL, NULL, { END_ARGS } }
4141d4f2939cSRui Paulo };
4142d4f2939cSRui Paulo 
4143d4f2939cSRui Paulo 
4144780fb4a2SCy Schubert static int wpa_dbus_ctrl_iface_props_init(struct wpas_dbus_priv *priv)
4145780fb4a2SCy Schubert {
4146780fb4a2SCy Schubert 	size_t all_size;
4147780fb4a2SCy Schubert 	unsigned int i, j, count, num_const, num_globals;
4148780fb4a2SCy Schubert 	const char *global_name;
4149780fb4a2SCy Schubert 	static const char * const ignored_globals[] = {
4150780fb4a2SCy Schubert 		"bss_expiration_age", "bss_expiration_scan_count",
4151780fb4a2SCy Schubert 		"ap_scan", "country", "fast_reauth",
4152780fb4a2SCy Schubert 		"pkcs11_engine_path", "pkcs11_module_path"
4153780fb4a2SCy Schubert 	};
4154780fb4a2SCy Schubert 
4155780fb4a2SCy Schubert 	/* wpas_dbus_interface_properties terminates with a NULL element */
4156780fb4a2SCy Schubert 	num_const = ARRAY_SIZE(wpas_dbus_interface_properties) - 1;
4157780fb4a2SCy Schubert 
4158780fb4a2SCy Schubert 	num_globals = wpa_config_get_num_global_field_names();
4159780fb4a2SCy Schubert 	priv->globals_start = num_const;
4160780fb4a2SCy Schubert 
4161780fb4a2SCy Schubert 	/* allocate enough for all properties + terminating NULL element */
4162780fb4a2SCy Schubert 	all_size = (num_globals + num_const + 1) *
4163780fb4a2SCy Schubert 		sizeof(wpas_dbus_interface_properties[0]);
4164780fb4a2SCy Schubert 	priv->all_interface_properties = os_zalloc(all_size);
4165780fb4a2SCy Schubert 	if (!priv->all_interface_properties) {
4166780fb4a2SCy Schubert 		wpa_printf(MSG_ERROR,
4167780fb4a2SCy Schubert 			   "dbus: Not enough memory for interface properties");
4168780fb4a2SCy Schubert 		return -1;
4169780fb4a2SCy Schubert 	}
4170780fb4a2SCy Schubert 
4171780fb4a2SCy Schubert 	/* Copy constant interface properties to the start of the array */
4172780fb4a2SCy Schubert 	os_memcpy(priv->all_interface_properties,
4173780fb4a2SCy Schubert 		  wpas_dbus_interface_properties,
4174780fb4a2SCy Schubert 		  sizeof(wpas_dbus_interface_properties));
4175780fb4a2SCy Schubert 
4176780fb4a2SCy Schubert 	/* Dynamically construct interface global properties */
4177780fb4a2SCy Schubert 	for (i = 0, count = num_const; i < num_globals; i++) {
4178780fb4a2SCy Schubert 		struct wpa_dbus_property_desc *desc;
4179780fb4a2SCy Schubert 		int no_var = 0;
4180780fb4a2SCy Schubert 
4181780fb4a2SCy Schubert 		/* ignore globals that are actually just methods */
4182780fb4a2SCy Schubert 		global_name = wpa_config_get_global_field_name(i, &no_var);
4183780fb4a2SCy Schubert 		if (no_var)
4184780fb4a2SCy Schubert 			continue;
4185780fb4a2SCy Schubert 		/* Ignore fields already explicitly exposed */
4186780fb4a2SCy Schubert 		for (j = 0; j < ARRAY_SIZE(ignored_globals); j++) {
4187780fb4a2SCy Schubert 			if (os_strcmp(global_name, ignored_globals[j]) == 0)
4188780fb4a2SCy Schubert 				break;
4189780fb4a2SCy Schubert 		}
4190780fb4a2SCy Schubert 		if (j < ARRAY_SIZE(ignored_globals))
4191780fb4a2SCy Schubert 			continue;
4192780fb4a2SCy Schubert 
4193780fb4a2SCy Schubert 		desc = &priv->all_interface_properties[count++];
4194780fb4a2SCy Schubert 		desc->dbus_property = uscore_to_dbus(global_name);
4195780fb4a2SCy Schubert 		if (!desc->dbus_property) {
4196780fb4a2SCy Schubert 			wpa_printf(MSG_ERROR,
4197780fb4a2SCy Schubert 				   "dbus: Not enough memory for D-Bus property name");
4198780fb4a2SCy Schubert 			goto error;
4199780fb4a2SCy Schubert 		}
4200780fb4a2SCy Schubert 		desc->dbus_interface = WPAS_DBUS_NEW_IFACE_INTERFACE;
4201780fb4a2SCy Schubert 		desc->type = "s";
4202780fb4a2SCy Schubert 		desc->getter = wpas_dbus_getter_iface_global;
4203780fb4a2SCy Schubert 		desc->setter = wpas_dbus_setter_iface_global;
4204780fb4a2SCy Schubert 		desc->data = global_name;
4205780fb4a2SCy Schubert 	}
4206780fb4a2SCy Schubert 
4207780fb4a2SCy Schubert 	return 0;
4208780fb4a2SCy Schubert 
4209780fb4a2SCy Schubert error:
4210780fb4a2SCy Schubert 	wpa_dbus_ctrl_iface_props_deinit(priv);
4211780fb4a2SCy Schubert 	return -1;
4212780fb4a2SCy Schubert }
4213780fb4a2SCy Schubert 
4214780fb4a2SCy Schubert 
4215325151a3SRui Paulo /**
4216325151a3SRui Paulo  * wpas_dbus_register_interface - Register an interface with D-Bus
4217325151a3SRui Paulo  * @wpa_s: wpa_supplicant interface structure
4218325151a3SRui Paulo  * Returns: 0 on success, -1 on failure
4219325151a3SRui Paulo  */
4220d4f2939cSRui Paulo int wpas_dbus_register_interface(struct wpa_supplicant *wpa_s)
4221d4f2939cSRui Paulo {
4222d4f2939cSRui Paulo 	struct wpa_dbus_object_desc *obj_desc = NULL;
4223d4f2939cSRui Paulo 	struct wpas_dbus_priv *ctrl_iface = wpa_s->global->dbus;
4224d4f2939cSRui Paulo 	int next;
4225d4f2939cSRui Paulo 
4226d4f2939cSRui Paulo 	/* Do nothing if the control interface is not turned on */
4227d4f2939cSRui Paulo 	if (ctrl_iface == NULL)
4228d4f2939cSRui Paulo 		return 0;
4229d4f2939cSRui Paulo 
4230d4f2939cSRui Paulo 	/* Create and set the interface's object path */
4231d4f2939cSRui Paulo 	wpa_s->dbus_new_path = os_zalloc(WPAS_DBUS_OBJECT_PATH_MAX);
4232d4f2939cSRui Paulo 	if (wpa_s->dbus_new_path == NULL)
4233d4f2939cSRui Paulo 		return -1;
4234d4f2939cSRui Paulo 	next = ctrl_iface->next_objid++;
4235d4f2939cSRui Paulo 	os_snprintf(wpa_s->dbus_new_path, WPAS_DBUS_OBJECT_PATH_MAX,
4236d4f2939cSRui Paulo 		    WPAS_DBUS_NEW_PATH_INTERFACES "/%u",
4237d4f2939cSRui Paulo 		    next);
4238d4f2939cSRui Paulo 
4239d4f2939cSRui Paulo 	obj_desc = os_zalloc(sizeof(struct wpa_dbus_object_desc));
4240d4f2939cSRui Paulo 	if (!obj_desc) {
42415b9c547cSRui Paulo 		wpa_printf(MSG_ERROR,
42425b9c547cSRui Paulo 			   "Not enough memory to create object description");
4243d4f2939cSRui Paulo 		goto err;
4244d4f2939cSRui Paulo 	}
4245d4f2939cSRui Paulo 
4246d4f2939cSRui Paulo 	wpas_dbus_register(obj_desc, wpa_s, NULL, wpas_dbus_interface_methods,
4247780fb4a2SCy Schubert 			   ctrl_iface->all_interface_properties,
4248d4f2939cSRui Paulo 			   wpas_dbus_interface_signals);
4249d4f2939cSRui Paulo 
4250d4f2939cSRui Paulo 	wpa_printf(MSG_DEBUG, "dbus: Register interface object '%s'",
4251d4f2939cSRui Paulo 		   wpa_s->dbus_new_path);
4252d4f2939cSRui Paulo 	if (wpa_dbus_register_object_per_iface(ctrl_iface,
4253d4f2939cSRui Paulo 					       wpa_s->dbus_new_path,
4254d4f2939cSRui Paulo 					       wpa_s->ifname, obj_desc))
4255d4f2939cSRui Paulo 		goto err;
4256d4f2939cSRui Paulo 
4257d4f2939cSRui Paulo 	wpas_dbus_signal_interface_added(wpa_s);
4258d4f2939cSRui Paulo 
4259d4f2939cSRui Paulo 	return 0;
4260d4f2939cSRui Paulo 
4261d4f2939cSRui Paulo err:
4262d4f2939cSRui Paulo 	os_free(wpa_s->dbus_new_path);
4263d4f2939cSRui Paulo 	wpa_s->dbus_new_path = NULL;
4264d4f2939cSRui Paulo 	free_dbus_object_desc(obj_desc);
4265d4f2939cSRui Paulo 	return -1;
4266d4f2939cSRui Paulo }
4267d4f2939cSRui Paulo 
4268d4f2939cSRui Paulo 
4269325151a3SRui Paulo /**
4270325151a3SRui Paulo  * wpas_dbus_unregister_interface - Unregister the interface from D-Bus
4271325151a3SRui Paulo  * @wpa_s: wpa_supplicant interface structure
4272325151a3SRui Paulo  * Returns: 0 on success, -1 on failure
4273325151a3SRui Paulo  */
4274d4f2939cSRui Paulo int wpas_dbus_unregister_interface(struct wpa_supplicant *wpa_s)
4275d4f2939cSRui Paulo {
4276d4f2939cSRui Paulo 	struct wpas_dbus_priv *ctrl_iface;
4277d4f2939cSRui Paulo 
4278d4f2939cSRui Paulo 	/* Do nothing if the control interface is not turned on */
4279d4f2939cSRui Paulo 	if (wpa_s == NULL || wpa_s->global == NULL)
4280d4f2939cSRui Paulo 		return 0;
4281d4f2939cSRui Paulo 	ctrl_iface = wpa_s->global->dbus;
42825b9c547cSRui Paulo 	if (ctrl_iface == NULL || wpa_s->dbus_new_path == NULL)
4283d4f2939cSRui Paulo 		return 0;
4284d4f2939cSRui Paulo 
4285d4f2939cSRui Paulo 	wpa_printf(MSG_DEBUG, "dbus: Unregister interface object '%s'",
4286d4f2939cSRui Paulo 		   wpa_s->dbus_new_path);
4287d4f2939cSRui Paulo 
4288d4f2939cSRui Paulo #ifdef CONFIG_AP
4289d4f2939cSRui Paulo 	if (wpa_s->preq_notify_peer) {
4290d4f2939cSRui Paulo 		wpas_dbus_unsubscribe_noc(ctrl_iface);
4291d4f2939cSRui Paulo 		os_free(wpa_s->preq_notify_peer);
4292d4f2939cSRui Paulo 		wpa_s->preq_notify_peer = NULL;
4293d4f2939cSRui Paulo 	}
4294d4f2939cSRui Paulo #endif /* CONFIG_AP */
4295d4f2939cSRui Paulo 
4296d4f2939cSRui Paulo 	if (wpa_dbus_unregister_object_per_iface(ctrl_iface,
4297d4f2939cSRui Paulo 						 wpa_s->dbus_new_path))
4298d4f2939cSRui Paulo 		return -1;
4299d4f2939cSRui Paulo 
4300d4f2939cSRui Paulo 	wpas_dbus_signal_interface_removed(wpa_s);
4301d4f2939cSRui Paulo 
4302d4f2939cSRui Paulo 	os_free(wpa_s->dbus_new_path);
4303d4f2939cSRui Paulo 	wpa_s->dbus_new_path = NULL;
4304d4f2939cSRui Paulo 
4305d4f2939cSRui Paulo 	return 0;
4306d4f2939cSRui Paulo }
4307d4f2939cSRui Paulo 
4308d4f2939cSRui Paulo #ifdef CONFIG_P2P
4309d4f2939cSRui Paulo 
4310d4f2939cSRui Paulo static const struct wpa_dbus_property_desc wpas_dbus_p2p_peer_properties[] = {
4311d4f2939cSRui Paulo 	{ "DeviceName", WPAS_DBUS_NEW_IFACE_P2P_PEER, "s",
4312d4f2939cSRui Paulo 	  wpas_dbus_getter_p2p_peer_device_name,
4313780fb4a2SCy Schubert 	  NULL,
4314d4f2939cSRui Paulo 	  NULL
4315d4f2939cSRui Paulo 	},
4316325151a3SRui Paulo 	{ "Manufacturer", WPAS_DBUS_NEW_IFACE_P2P_PEER, "s",
4317325151a3SRui Paulo 	  wpas_dbus_getter_p2p_peer_manufacturer,
4318780fb4a2SCy Schubert 	  NULL,
4319325151a3SRui Paulo 	  NULL
4320325151a3SRui Paulo 	},
4321325151a3SRui Paulo 	{ "ModelName", WPAS_DBUS_NEW_IFACE_P2P_PEER, "s",
4322325151a3SRui Paulo 	  wpas_dbus_getter_p2p_peer_modelname,
4323780fb4a2SCy Schubert 	  NULL,
4324325151a3SRui Paulo 	  NULL
4325325151a3SRui Paulo 	},
4326325151a3SRui Paulo 	{ "ModelNumber", WPAS_DBUS_NEW_IFACE_P2P_PEER, "s",
4327325151a3SRui Paulo 	  wpas_dbus_getter_p2p_peer_modelnumber,
4328780fb4a2SCy Schubert 	  NULL,
4329325151a3SRui Paulo 	  NULL
4330325151a3SRui Paulo 	},
4331325151a3SRui Paulo 	{ "SerialNumber", WPAS_DBUS_NEW_IFACE_P2P_PEER, "s",
4332325151a3SRui Paulo 	  wpas_dbus_getter_p2p_peer_serialnumber,
4333780fb4a2SCy Schubert 	  NULL,
4334325151a3SRui Paulo 	  NULL
4335325151a3SRui Paulo 	},
4336d4f2939cSRui Paulo 	{ "PrimaryDeviceType", WPAS_DBUS_NEW_IFACE_P2P_PEER, "ay",
4337d4f2939cSRui Paulo 	  wpas_dbus_getter_p2p_peer_primary_device_type,
4338780fb4a2SCy Schubert 	  NULL,
4339d4f2939cSRui Paulo 	  NULL
4340d4f2939cSRui Paulo 	},
4341d4f2939cSRui Paulo 	{ "config_method", WPAS_DBUS_NEW_IFACE_P2P_PEER, "q",
4342d4f2939cSRui Paulo 	  wpas_dbus_getter_p2p_peer_config_method,
4343780fb4a2SCy Schubert 	  NULL,
4344d4f2939cSRui Paulo 	  NULL
4345d4f2939cSRui Paulo 	},
4346d4f2939cSRui Paulo 	{ "level", WPAS_DBUS_NEW_IFACE_P2P_PEER, "i",
4347d4f2939cSRui Paulo 	  wpas_dbus_getter_p2p_peer_level,
4348780fb4a2SCy Schubert 	  NULL,
4349d4f2939cSRui Paulo 	  NULL
4350d4f2939cSRui Paulo 	},
4351d4f2939cSRui Paulo 	{ "devicecapability", WPAS_DBUS_NEW_IFACE_P2P_PEER, "y",
4352d4f2939cSRui Paulo 	  wpas_dbus_getter_p2p_peer_device_capability,
4353780fb4a2SCy Schubert 	  NULL,
4354d4f2939cSRui Paulo 	  NULL
4355d4f2939cSRui Paulo 	},
4356d4f2939cSRui Paulo 	{ "groupcapability", WPAS_DBUS_NEW_IFACE_P2P_PEER, "y",
4357d4f2939cSRui Paulo 	  wpas_dbus_getter_p2p_peer_group_capability,
4358780fb4a2SCy Schubert 	  NULL,
4359d4f2939cSRui Paulo 	  NULL
4360d4f2939cSRui Paulo 	},
4361d4f2939cSRui Paulo 	{ "SecondaryDeviceTypes", WPAS_DBUS_NEW_IFACE_P2P_PEER, "aay",
4362d4f2939cSRui Paulo 	  wpas_dbus_getter_p2p_peer_secondary_device_types,
4363780fb4a2SCy Schubert 	  NULL,
4364d4f2939cSRui Paulo 	  NULL
4365d4f2939cSRui Paulo 	},
4366d4f2939cSRui Paulo 	{ "VendorExtension", WPAS_DBUS_NEW_IFACE_P2P_PEER, "aay",
4367d4f2939cSRui Paulo 	  wpas_dbus_getter_p2p_peer_vendor_extension,
4368780fb4a2SCy Schubert 	  NULL,
4369d4f2939cSRui Paulo 	  NULL
4370d4f2939cSRui Paulo 	},
4371d4f2939cSRui Paulo 	{ "IEs", WPAS_DBUS_NEW_IFACE_P2P_PEER, "ay",
4372d4f2939cSRui Paulo 	  wpas_dbus_getter_p2p_peer_ies,
4373780fb4a2SCy Schubert 	  NULL,
4374d4f2939cSRui Paulo 	  NULL
4375d4f2939cSRui Paulo 	},
43765b9c547cSRui Paulo 	{ "DeviceAddress", WPAS_DBUS_NEW_IFACE_P2P_PEER, "ay",
43775b9c547cSRui Paulo 	  wpas_dbus_getter_p2p_peer_device_address,
4378780fb4a2SCy Schubert 	  NULL,
43795b9c547cSRui Paulo 	  NULL
43805b9c547cSRui Paulo 	},
43815b9c547cSRui Paulo 	{ "Groups", WPAS_DBUS_NEW_IFACE_P2P_PEER, "ao",
43825b9c547cSRui Paulo 	  wpas_dbus_getter_p2p_peer_groups,
4383780fb4a2SCy Schubert 	  NULL,
43845b9c547cSRui Paulo 	  NULL
43855b9c547cSRui Paulo 	},
43864bc52338SCy Schubert 	{ "VSIE", WPAS_DBUS_NEW_IFACE_P2P_PEER, "ay",
43874bc52338SCy Schubert 	  wpas_dbus_getter_p2p_peer_vsie,
43884bc52338SCy Schubert 	  NULL,
43894bc52338SCy Schubert 	  NULL
43904bc52338SCy Schubert 	},
4391780fb4a2SCy Schubert 	{ NULL, NULL, NULL, NULL, NULL, NULL }
4392d4f2939cSRui Paulo };
4393d4f2939cSRui Paulo 
4394d4f2939cSRui Paulo static const struct wpa_dbus_signal_desc wpas_dbus_p2p_peer_signals[] = {
43955b9c547cSRui Paulo 	/* Deprecated: use org.freedesktop.DBus.Properties.PropertiesChanged */
43965b9c547cSRui Paulo 	{ "PropertiesChanged", WPAS_DBUS_NEW_IFACE_P2P_PEER,
43975b9c547cSRui Paulo 	  {
43985b9c547cSRui Paulo 		  { "properties", "a{sv}", ARG_OUT },
43995b9c547cSRui Paulo 		  END_ARGS
44005b9c547cSRui Paulo 	  }
44015b9c547cSRui Paulo 	},
4402d4f2939cSRui Paulo 	{ NULL, NULL, { END_ARGS } }
4403d4f2939cSRui Paulo };
4404d4f2939cSRui Paulo 
4405d4f2939cSRui Paulo /**
4406d4f2939cSRui Paulo  * wpas_dbus_signal_peer - Send a peer related event signal
4407d4f2939cSRui Paulo  * @wpa_s: %wpa_supplicant network interface data
4408d4f2939cSRui Paulo  * @dev: peer device object
4409d4f2939cSRui Paulo  * @interface: name of the interface emitting this signal.
4410d4f2939cSRui Paulo  *	In case of peer objects, it would be emitted by either
4411d4f2939cSRui Paulo  *	the "interface object" or by "peer objects"
4412d4f2939cSRui Paulo  * @sig_name: signal name - DeviceFound
4413780fb4a2SCy Schubert  * @properties: Whether to add a second argument with object properties
4414d4f2939cSRui Paulo  *
4415780fb4a2SCy Schubert  * Notify listeners about event related with p2p peer device
4416d4f2939cSRui Paulo  */
4417d4f2939cSRui Paulo static void wpas_dbus_signal_peer(struct wpa_supplicant *wpa_s,
4418d4f2939cSRui Paulo 				  const u8 *dev_addr, const char *interface,
44194bc52338SCy Schubert 				  const char *sig_name, dbus_bool_t properties)
4420d4f2939cSRui Paulo {
4421d4f2939cSRui Paulo 	struct wpas_dbus_priv *iface;
4422d4f2939cSRui Paulo 	DBusMessage *msg;
4423d4f2939cSRui Paulo 	DBusMessageIter iter;
4424d4f2939cSRui Paulo 	char peer_obj_path[WPAS_DBUS_OBJECT_PATH_MAX], *path;
4425d4f2939cSRui Paulo 
44265b9c547cSRui Paulo 	if (wpa_s->p2p_mgmt)
44275b9c547cSRui Paulo 		wpa_s = wpa_s->parent;
44285b9c547cSRui Paulo 
4429d4f2939cSRui Paulo 	iface = wpa_s->global->dbus;
4430d4f2939cSRui Paulo 
4431d4f2939cSRui Paulo 	/* Do nothing if the control interface is not turned on */
4432325151a3SRui Paulo 	if (iface == NULL || !wpa_s->dbus_new_path)
4433d4f2939cSRui Paulo 		return;
4434d4f2939cSRui Paulo 
4435d4f2939cSRui Paulo 	os_snprintf(peer_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
4436d4f2939cSRui Paulo 		    "%s/" WPAS_DBUS_NEW_P2P_PEERS_PART "/" COMPACT_MACSTR,
4437d4f2939cSRui Paulo 		    wpa_s->dbus_new_path, MAC2STR(dev_addr));
4438d4f2939cSRui Paulo 
4439d4f2939cSRui Paulo 	msg = dbus_message_new_signal(wpa_s->dbus_new_path, interface,
4440d4f2939cSRui Paulo 				      sig_name);
4441d4f2939cSRui Paulo 	if (msg == NULL)
4442d4f2939cSRui Paulo 		return;
4443d4f2939cSRui Paulo 
4444d4f2939cSRui Paulo 	dbus_message_iter_init_append(msg, &iter);
4445d4f2939cSRui Paulo 	path = peer_obj_path;
4446d4f2939cSRui Paulo 	if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_OBJECT_PATH,
4447780fb4a2SCy Schubert 					    &path) ||
4448780fb4a2SCy Schubert 	    (properties && !wpa_dbus_get_object_properties(
4449780fb4a2SCy Schubert 		    iface, peer_obj_path, WPAS_DBUS_NEW_IFACE_P2P_PEER,
4450780fb4a2SCy Schubert 		    &iter)))
44515b9c547cSRui Paulo 		wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
44525b9c547cSRui Paulo 	else
4453d4f2939cSRui Paulo 		dbus_connection_send(iface->con, msg, NULL);
4454d4f2939cSRui Paulo 
4455d4f2939cSRui Paulo 	dbus_message_unref(msg);
4456d4f2939cSRui Paulo }
4457d4f2939cSRui Paulo 
4458d4f2939cSRui Paulo 
4459d4f2939cSRui Paulo /**
4460d4f2939cSRui Paulo  * wpas_dbus_signal_peer_found - Send a peer found signal
4461d4f2939cSRui Paulo  * @wpa_s: %wpa_supplicant network interface data
4462325151a3SRui Paulo  * @dev_addr: Peer P2P Device Address
4463d4f2939cSRui Paulo  *
4464d4f2939cSRui Paulo  * Notify listeners about find a p2p peer device found
4465d4f2939cSRui Paulo  */
4466d4f2939cSRui Paulo void wpas_dbus_signal_peer_device_found(struct wpa_supplicant *wpa_s,
4467d4f2939cSRui Paulo 					const u8 *dev_addr)
4468d4f2939cSRui Paulo {
4469d4f2939cSRui Paulo 	wpas_dbus_signal_peer(wpa_s, dev_addr,
4470d4f2939cSRui Paulo 			      WPAS_DBUS_NEW_IFACE_P2PDEVICE,
4471780fb4a2SCy Schubert 			      "DeviceFound", FALSE);
4472780fb4a2SCy Schubert 
4473780fb4a2SCy Schubert 	wpas_dbus_signal_peer(wpa_s, dev_addr,
4474780fb4a2SCy Schubert 			      WPAS_DBUS_NEW_IFACE_P2PDEVICE,
4475780fb4a2SCy Schubert 			      "DeviceFoundProperties", TRUE);
4476d4f2939cSRui Paulo }
4477d4f2939cSRui Paulo 
4478d4f2939cSRui Paulo /**
4479d4f2939cSRui Paulo  * wpas_dbus_signal_peer_lost - Send a peer lost signal
4480d4f2939cSRui Paulo  * @wpa_s: %wpa_supplicant network interface data
4481325151a3SRui Paulo  * @dev_addr: Peer P2P Device Address
4482d4f2939cSRui Paulo  *
4483d4f2939cSRui Paulo  * Notify listeners about lost a p2p peer device
4484d4f2939cSRui Paulo  */
4485d4f2939cSRui Paulo void wpas_dbus_signal_peer_device_lost(struct wpa_supplicant *wpa_s,
4486d4f2939cSRui Paulo 				       const u8 *dev_addr)
4487d4f2939cSRui Paulo {
4488d4f2939cSRui Paulo 	wpas_dbus_signal_peer(wpa_s, dev_addr,
4489d4f2939cSRui Paulo 			      WPAS_DBUS_NEW_IFACE_P2PDEVICE,
4490780fb4a2SCy Schubert 			      "DeviceLost", FALSE);
4491d4f2939cSRui Paulo }
4492d4f2939cSRui Paulo 
4493d4f2939cSRui Paulo /**
4494d4f2939cSRui Paulo  * wpas_dbus_register_peer - Register a discovered peer object with dbus
4495d4f2939cSRui Paulo  * @wpa_s: wpa_supplicant interface structure
4496325151a3SRui Paulo  * @dev_addr: P2P Device Address of the peer
4497d4f2939cSRui Paulo  * Returns: 0 on success, -1 on failure
4498d4f2939cSRui Paulo  *
4499d4f2939cSRui Paulo  * Registers network representing object with dbus
4500d4f2939cSRui Paulo  */
4501d4f2939cSRui Paulo int wpas_dbus_register_peer(struct wpa_supplicant *wpa_s, const u8 *dev_addr)
4502d4f2939cSRui Paulo {
4503d4f2939cSRui Paulo 	struct wpas_dbus_priv *ctrl_iface;
4504d4f2939cSRui Paulo 	struct wpa_dbus_object_desc *obj_desc;
4505d4f2939cSRui Paulo 	struct peer_handler_args *arg;
4506d4f2939cSRui Paulo 	char peer_obj_path[WPAS_DBUS_OBJECT_PATH_MAX];
4507d4f2939cSRui Paulo 
4508d4f2939cSRui Paulo 	/* Do nothing if the control interface is not turned on */
4509d4f2939cSRui Paulo 	if (wpa_s == NULL || wpa_s->global == NULL)
4510d4f2939cSRui Paulo 		return 0;
4511d4f2939cSRui Paulo 
4512d4f2939cSRui Paulo 	ctrl_iface = wpa_s->global->dbus;
4513d4f2939cSRui Paulo 	if (ctrl_iface == NULL)
4514d4f2939cSRui Paulo 		return 0;
4515d4f2939cSRui Paulo 
4516325151a3SRui Paulo 	wpa_s = wpa_s->parent->parent;
4517325151a3SRui Paulo 	if (!wpa_s->dbus_new_path)
4518325151a3SRui Paulo 		return 0;
45195b9c547cSRui Paulo 
4520d4f2939cSRui Paulo 	os_snprintf(peer_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
4521d4f2939cSRui Paulo 		    "%s/" WPAS_DBUS_NEW_P2P_PEERS_PART "/" COMPACT_MACSTR,
4522d4f2939cSRui Paulo 		    wpa_s->dbus_new_path, MAC2STR(dev_addr));
4523d4f2939cSRui Paulo 
4524d4f2939cSRui Paulo 	wpa_printf(MSG_INFO, "dbus: Register peer object '%s'",
4525d4f2939cSRui Paulo 		   peer_obj_path);
4526d4f2939cSRui Paulo 	obj_desc = os_zalloc(sizeof(struct wpa_dbus_object_desc));
4527d4f2939cSRui Paulo 	if (!obj_desc) {
45285b9c547cSRui Paulo 		wpa_printf(MSG_ERROR,
45295b9c547cSRui Paulo 			   "Not enough memory to create object description");
4530d4f2939cSRui Paulo 		goto err;
4531d4f2939cSRui Paulo 	}
4532d4f2939cSRui Paulo 
4533d4f2939cSRui Paulo 	/* allocate memory for handlers arguments */
4534d4f2939cSRui Paulo 	arg = os_zalloc(sizeof(struct peer_handler_args));
4535d4f2939cSRui Paulo 	if (!arg) {
45365b9c547cSRui Paulo 		wpa_printf(MSG_ERROR,
45375b9c547cSRui Paulo 			   "Not enough memory to create arguments for method");
4538d4f2939cSRui Paulo 		goto err;
4539d4f2939cSRui Paulo 	}
4540d4f2939cSRui Paulo 
4541d4f2939cSRui Paulo 	arg->wpa_s = wpa_s;
4542d4f2939cSRui Paulo 	os_memcpy(arg->p2p_device_addr, dev_addr, ETH_ALEN);
4543d4f2939cSRui Paulo 
4544d4f2939cSRui Paulo 	wpas_dbus_register(obj_desc, arg, wpa_dbus_free,
4545d4f2939cSRui Paulo 			   NULL,
4546d4f2939cSRui Paulo 			   wpas_dbus_p2p_peer_properties,
4547d4f2939cSRui Paulo 			   wpas_dbus_p2p_peer_signals);
4548d4f2939cSRui Paulo 
4549d4f2939cSRui Paulo 	if (wpa_dbus_register_object_per_iface(ctrl_iface, peer_obj_path,
4550d4f2939cSRui Paulo 					       wpa_s->ifname, obj_desc))
4551d4f2939cSRui Paulo 		goto err;
4552d4f2939cSRui Paulo 
4553d4f2939cSRui Paulo 	return 0;
4554d4f2939cSRui Paulo 
4555d4f2939cSRui Paulo err:
4556d4f2939cSRui Paulo 	free_dbus_object_desc(obj_desc);
4557d4f2939cSRui Paulo 	return -1;
4558d4f2939cSRui Paulo }
4559d4f2939cSRui Paulo 
4560d4f2939cSRui Paulo /**
4561d4f2939cSRui Paulo  * wpas_dbus_unregister_peer - Unregister a peer object with dbus
4562d4f2939cSRui Paulo  * @wpa_s: wpa_supplicant interface structure
4563d4f2939cSRui Paulo  * @dev_addr: p2p device addr
4564d4f2939cSRui Paulo  * Returns: 0 on success, -1 on failure
4565d4f2939cSRui Paulo  *
4566d4f2939cSRui Paulo  * Registers network representing object with dbus
4567d4f2939cSRui Paulo  */
4568d4f2939cSRui Paulo int wpas_dbus_unregister_peer(struct wpa_supplicant *wpa_s,
4569d4f2939cSRui Paulo 				  const u8 *dev_addr)
4570d4f2939cSRui Paulo {
4571d4f2939cSRui Paulo 	struct wpas_dbus_priv *ctrl_iface;
4572d4f2939cSRui Paulo 	char peer_obj_path[WPAS_DBUS_OBJECT_PATH_MAX];
4573d4f2939cSRui Paulo 	int ret;
4574d4f2939cSRui Paulo 
4575d4f2939cSRui Paulo 	/* Do nothing if the control interface is not turned on */
4576325151a3SRui Paulo 	if (wpa_s == NULL || wpa_s->global == NULL)
4577d4f2939cSRui Paulo 		return 0;
45785b9c547cSRui Paulo 
4579325151a3SRui Paulo 	wpa_s = wpa_s->parent->parent;
4580325151a3SRui Paulo 	if (!wpa_s->dbus_new_path)
4581325151a3SRui Paulo 		return 0;
45825b9c547cSRui Paulo 
4583d4f2939cSRui Paulo 	ctrl_iface = wpa_s->global->dbus;
4584d4f2939cSRui Paulo 	if (ctrl_iface == NULL)
4585d4f2939cSRui Paulo 		return 0;
4586d4f2939cSRui Paulo 
4587d4f2939cSRui Paulo 	os_snprintf(peer_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
4588d4f2939cSRui Paulo 		    "%s/" WPAS_DBUS_NEW_P2P_PEERS_PART "/" COMPACT_MACSTR,
4589d4f2939cSRui Paulo 		    wpa_s->dbus_new_path, MAC2STR(dev_addr));
4590d4f2939cSRui Paulo 
4591d4f2939cSRui Paulo 	wpa_printf(MSG_INFO, "dbus: Unregister peer object '%s'",
4592d4f2939cSRui Paulo 		   peer_obj_path);
4593d4f2939cSRui Paulo 	ret = wpa_dbus_unregister_object_per_iface(ctrl_iface, peer_obj_path);
4594d4f2939cSRui Paulo 
4595d4f2939cSRui Paulo 	return ret;
4596d4f2939cSRui Paulo }
4597d4f2939cSRui Paulo 
4598d4f2939cSRui Paulo 
4599325151a3SRui Paulo /**
4600325151a3SRui Paulo  * wpas_dbus_signal_p2p_find_stopped - Send P2P Find stopped signal
4601325151a3SRui Paulo  * @wpa_s: %wpa_supplicant network interface data
4602325151a3SRui Paulo  *
4603325151a3SRui Paulo  * Notify listeners about P2P Find stopped
4604325151a3SRui Paulo  */
4605325151a3SRui Paulo void wpas_dbus_signal_p2p_find_stopped(struct wpa_supplicant *wpa_s)
4606325151a3SRui Paulo {
4607325151a3SRui Paulo 	struct wpas_dbus_priv *iface;
4608325151a3SRui Paulo 	DBusMessage *msg;
4609325151a3SRui Paulo 
4610325151a3SRui Paulo 	iface = wpa_s->global->dbus;
4611325151a3SRui Paulo 
4612325151a3SRui Paulo 	/* Do nothing if the control interface is not turned on */
461385732ac8SCy Schubert 	if (iface == NULL)
461485732ac8SCy Schubert 		return;
461585732ac8SCy Schubert 
461685732ac8SCy Schubert 	if (wpa_s->p2p_mgmt)
461785732ac8SCy Schubert 		wpa_s = wpa_s->parent;
461885732ac8SCy Schubert 
461985732ac8SCy Schubert 	if (!wpa_s->dbus_new_path)
4620325151a3SRui Paulo 		return;
4621325151a3SRui Paulo 
4622325151a3SRui Paulo 	msg = dbus_message_new_signal(wpa_s->dbus_new_path,
4623325151a3SRui Paulo 				      WPAS_DBUS_NEW_IFACE_P2PDEVICE,
4624325151a3SRui Paulo 				      "FindStopped");
4625325151a3SRui Paulo 	if (msg == NULL)
4626325151a3SRui Paulo 		return;
4627325151a3SRui Paulo 
4628325151a3SRui Paulo 	dbus_connection_send(iface->con, msg, NULL);
4629325151a3SRui Paulo 
4630325151a3SRui Paulo 	dbus_message_unref(msg);
4631325151a3SRui Paulo }
4632325151a3SRui Paulo 
4633325151a3SRui Paulo 
4634325151a3SRui Paulo /**
4635325151a3SRui Paulo  * wpas_dbus_signal_peer_groups_changed - Send peer group change property signal
4636325151a3SRui Paulo  * @wpa_s: %wpa_supplicant network interface data
4637325151a3SRui Paulo  * @dev_addr: P2P Device Address
4638325151a3SRui Paulo  *
4639325151a3SRui Paulo  * Notify listeners about peer Groups property changes.
4640325151a3SRui Paulo  */
46415b9c547cSRui Paulo void wpas_dbus_signal_peer_groups_changed(struct wpa_supplicant *wpa_s,
46425b9c547cSRui Paulo 					  const u8 *dev_addr)
46435b9c547cSRui Paulo {
46445b9c547cSRui Paulo 	char peer_obj_path[WPAS_DBUS_OBJECT_PATH_MAX];
46455b9c547cSRui Paulo 
46465b9c547cSRui Paulo 	if (wpa_s->p2p_mgmt)
46475b9c547cSRui Paulo 		wpa_s = wpa_s->parent;
46485b9c547cSRui Paulo 
4649325151a3SRui Paulo 	if (!wpa_s->dbus_new_path)
4650325151a3SRui Paulo 		return;
46515b9c547cSRui Paulo 	os_snprintf(peer_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
46525b9c547cSRui Paulo 		    "%s/" WPAS_DBUS_NEW_P2P_PEERS_PART "/" COMPACT_MACSTR,
46535b9c547cSRui Paulo 		    wpa_s->dbus_new_path, MAC2STR(dev_addr));
46545b9c547cSRui Paulo 
46555b9c547cSRui Paulo 	wpa_dbus_mark_property_changed(wpa_s->global->dbus, peer_obj_path,
46565b9c547cSRui Paulo 				       WPAS_DBUS_NEW_IFACE_P2P_PEER, "Groups");
46575b9c547cSRui Paulo }
46585b9c547cSRui Paulo 
46595b9c547cSRui Paulo 
4660d4f2939cSRui Paulo static const struct wpa_dbus_property_desc wpas_dbus_p2p_group_properties[] = {
4661d4f2939cSRui Paulo 	{ "Members", WPAS_DBUS_NEW_IFACE_P2P_GROUP, "ao",
4662d4f2939cSRui Paulo 	  wpas_dbus_getter_p2p_group_members,
4663780fb4a2SCy Schubert 	  NULL,
4664d4f2939cSRui Paulo 	  NULL
4665d4f2939cSRui Paulo 	},
4666d4f2939cSRui Paulo 	{ "Group", WPAS_DBUS_NEW_IFACE_P2P_GROUP, "o",
4667d4f2939cSRui Paulo 	  wpas_dbus_getter_p2p_group,
4668780fb4a2SCy Schubert 	  NULL,
4669d4f2939cSRui Paulo 	  NULL
4670d4f2939cSRui Paulo 	},
4671d4f2939cSRui Paulo 	{ "Role", WPAS_DBUS_NEW_IFACE_P2P_GROUP, "s",
4672d4f2939cSRui Paulo 	  wpas_dbus_getter_p2p_role,
4673780fb4a2SCy Schubert 	  NULL,
4674d4f2939cSRui Paulo 	  NULL
4675d4f2939cSRui Paulo 	},
4676d4f2939cSRui Paulo 	{ "SSID", WPAS_DBUS_NEW_IFACE_P2P_GROUP, "ay",
4677d4f2939cSRui Paulo 	  wpas_dbus_getter_p2p_group_ssid,
4678780fb4a2SCy Schubert 	  NULL,
4679d4f2939cSRui Paulo 	  NULL
4680d4f2939cSRui Paulo 	},
4681d4f2939cSRui Paulo 	{ "BSSID", WPAS_DBUS_NEW_IFACE_P2P_GROUP, "ay",
4682d4f2939cSRui Paulo 	  wpas_dbus_getter_p2p_group_bssid,
4683780fb4a2SCy Schubert 	  NULL,
4684d4f2939cSRui Paulo 	  NULL
4685d4f2939cSRui Paulo 	},
4686d4f2939cSRui Paulo 	{ "Frequency", WPAS_DBUS_NEW_IFACE_P2P_GROUP, "q",
4687d4f2939cSRui Paulo 	  wpas_dbus_getter_p2p_group_frequency,
4688780fb4a2SCy Schubert 	  NULL,
4689d4f2939cSRui Paulo 	  NULL
4690d4f2939cSRui Paulo 	},
4691d4f2939cSRui Paulo 	{ "Passphrase", WPAS_DBUS_NEW_IFACE_P2P_GROUP, "s",
4692d4f2939cSRui Paulo 	  wpas_dbus_getter_p2p_group_passphrase,
4693780fb4a2SCy Schubert 	  NULL,
4694d4f2939cSRui Paulo 	  NULL
4695d4f2939cSRui Paulo 	},
4696d4f2939cSRui Paulo 	{ "PSK", WPAS_DBUS_NEW_IFACE_P2P_GROUP, "ay",
4697d4f2939cSRui Paulo 	  wpas_dbus_getter_p2p_group_psk,
4698780fb4a2SCy Schubert 	  NULL,
4699d4f2939cSRui Paulo 	  NULL
4700d4f2939cSRui Paulo 	},
4701d4f2939cSRui Paulo 	{ "WPSVendorExtensions", WPAS_DBUS_NEW_IFACE_P2P_GROUP, "aay",
4702d4f2939cSRui Paulo 	  wpas_dbus_getter_p2p_group_vendor_ext,
4703780fb4a2SCy Schubert 	  wpas_dbus_setter_p2p_group_vendor_ext,
4704780fb4a2SCy Schubert 	  NULL
4705d4f2939cSRui Paulo 	},
4706780fb4a2SCy Schubert 	{ NULL, NULL, NULL, NULL, NULL, NULL }
4707d4f2939cSRui Paulo };
4708d4f2939cSRui Paulo 
4709d4f2939cSRui Paulo static const struct wpa_dbus_signal_desc wpas_dbus_p2p_group_signals[] = {
4710d4f2939cSRui Paulo 	{ "PeerJoined", WPAS_DBUS_NEW_IFACE_P2P_GROUP,
4711d4f2939cSRui Paulo 	  {
4712d4f2939cSRui Paulo 		  { "peer", "o", ARG_OUT },
4713d4f2939cSRui Paulo 		  END_ARGS
4714d4f2939cSRui Paulo 	  }
4715d4f2939cSRui Paulo 	},
4716d4f2939cSRui Paulo 	{ "PeerDisconnected", WPAS_DBUS_NEW_IFACE_P2P_GROUP,
4717d4f2939cSRui Paulo 	  {
4718d4f2939cSRui Paulo 		  { "peer", "o", ARG_OUT },
4719d4f2939cSRui Paulo 		  END_ARGS
4720d4f2939cSRui Paulo 	  }
4721d4f2939cSRui Paulo 	},
4722d4f2939cSRui Paulo 	{ NULL, NULL, { END_ARGS } }
4723d4f2939cSRui Paulo };
4724d4f2939cSRui Paulo 
4725d4f2939cSRui Paulo /**
4726d4f2939cSRui Paulo  * wpas_dbus_register_p2p_group - Register a p2p group object with dbus
4727d4f2939cSRui Paulo  * @wpa_s: wpa_supplicant interface structure
4728d4f2939cSRui Paulo  * @ssid: SSID struct
4729d4f2939cSRui Paulo  * Returns: 0 on success, -1 on failure
4730d4f2939cSRui Paulo  *
4731d4f2939cSRui Paulo  * Registers p2p group representing object with dbus
4732d4f2939cSRui Paulo  */
4733d4f2939cSRui Paulo void wpas_dbus_register_p2p_group(struct wpa_supplicant *wpa_s,
4734d4f2939cSRui Paulo 				  struct wpa_ssid *ssid)
4735d4f2939cSRui Paulo {
4736d4f2939cSRui Paulo 	struct wpas_dbus_priv *ctrl_iface;
4737d4f2939cSRui Paulo 	struct wpa_dbus_object_desc *obj_desc;
4738d4f2939cSRui Paulo 	char group_obj_path[WPAS_DBUS_OBJECT_PATH_MAX];
4739d4f2939cSRui Paulo 
4740d4f2939cSRui Paulo 	/* Do nothing if the control interface is not turned on */
4741d4f2939cSRui Paulo 	if (wpa_s == NULL || wpa_s->global == NULL)
4742d4f2939cSRui Paulo 		return;
4743d4f2939cSRui Paulo 
4744d4f2939cSRui Paulo 	ctrl_iface = wpa_s->global->dbus;
4745d4f2939cSRui Paulo 	if (ctrl_iface == NULL)
4746d4f2939cSRui Paulo 		return;
4747d4f2939cSRui Paulo 
4748d4f2939cSRui Paulo 	if (wpa_s->dbus_groupobj_path) {
4749d4f2939cSRui Paulo 		wpa_printf(MSG_INFO, "%s: Group object '%s' already exists",
4750d4f2939cSRui Paulo 			   __func__, wpa_s->dbus_groupobj_path);
4751d4f2939cSRui Paulo 		return;
4752d4f2939cSRui Paulo 	}
4753d4f2939cSRui Paulo 
4754d4f2939cSRui Paulo 	if (wpas_dbus_get_group_obj_path(wpa_s, ssid, group_obj_path) < 0)
4755d4f2939cSRui Paulo 		return;
4756d4f2939cSRui Paulo 
4757d4f2939cSRui Paulo 	wpa_s->dbus_groupobj_path = os_strdup(group_obj_path);
4758d4f2939cSRui Paulo 	if (wpa_s->dbus_groupobj_path == NULL)
4759d4f2939cSRui Paulo 		return;
4760d4f2939cSRui Paulo 
4761d4f2939cSRui Paulo 	wpa_printf(MSG_INFO, "dbus: Register group object '%s'",
4762d4f2939cSRui Paulo 		   group_obj_path);
4763d4f2939cSRui Paulo 	obj_desc = os_zalloc(sizeof(struct wpa_dbus_object_desc));
4764d4f2939cSRui Paulo 	if (!obj_desc) {
47655b9c547cSRui Paulo 		wpa_printf(MSG_ERROR,
47665b9c547cSRui Paulo 			   "Not enough memory to create object description");
4767d4f2939cSRui Paulo 		goto err;
4768d4f2939cSRui Paulo 	}
4769d4f2939cSRui Paulo 
4770d4f2939cSRui Paulo 	wpas_dbus_register(obj_desc, wpa_s, NULL, NULL,
4771d4f2939cSRui Paulo 			   wpas_dbus_p2p_group_properties,
4772d4f2939cSRui Paulo 			   wpas_dbus_p2p_group_signals);
4773d4f2939cSRui Paulo 
4774d4f2939cSRui Paulo 	if (wpa_dbus_register_object_per_iface(ctrl_iface, group_obj_path,
4775d4f2939cSRui Paulo 					       wpa_s->ifname, obj_desc))
4776d4f2939cSRui Paulo 		goto err;
4777d4f2939cSRui Paulo 
4778d4f2939cSRui Paulo 	return;
4779d4f2939cSRui Paulo 
4780d4f2939cSRui Paulo err:
4781d4f2939cSRui Paulo 	if (wpa_s->dbus_groupobj_path) {
4782d4f2939cSRui Paulo 		os_free(wpa_s->dbus_groupobj_path);
4783d4f2939cSRui Paulo 		wpa_s->dbus_groupobj_path = NULL;
4784d4f2939cSRui Paulo 	}
4785d4f2939cSRui Paulo 
4786d4f2939cSRui Paulo 	free_dbus_object_desc(obj_desc);
4787d4f2939cSRui Paulo }
4788d4f2939cSRui Paulo 
4789d4f2939cSRui Paulo /**
4790d4f2939cSRui Paulo  * wpas_dbus_unregister_p2p_group - Unregister a p2p group object from dbus
4791d4f2939cSRui Paulo  * @wpa_s: wpa_supplicant interface structure
4792d4f2939cSRui Paulo  * @ssid: network name of the p2p group started
4793d4f2939cSRui Paulo  */
4794d4f2939cSRui Paulo void wpas_dbus_unregister_p2p_group(struct wpa_supplicant *wpa_s,
4795d4f2939cSRui Paulo 				    const struct wpa_ssid *ssid)
4796d4f2939cSRui Paulo {
4797d4f2939cSRui Paulo 	struct wpas_dbus_priv *ctrl_iface;
4798d4f2939cSRui Paulo 
4799d4f2939cSRui Paulo 	/* Do nothing if the control interface is not turned on */
4800d4f2939cSRui Paulo 	if (wpa_s == NULL || wpa_s->global == NULL)
4801d4f2939cSRui Paulo 		return;
4802d4f2939cSRui Paulo 
48035b9c547cSRui Paulo 	if (wpa_s->p2p_mgmt)
48045b9c547cSRui Paulo 		wpa_s = wpa_s->parent;
48055b9c547cSRui Paulo 
4806d4f2939cSRui Paulo 	ctrl_iface = wpa_s->global->dbus;
4807d4f2939cSRui Paulo 	if (ctrl_iface == NULL)
4808d4f2939cSRui Paulo 		return;
4809d4f2939cSRui Paulo 
4810d4f2939cSRui Paulo 	if (!wpa_s->dbus_groupobj_path) {
4811d4f2939cSRui Paulo 		wpa_printf(MSG_DEBUG,
4812*c1d255d3SCy Schubert 			   "%s: Group object has already unregistered",
4813*c1d255d3SCy Schubert 			   __func__);
4814d4f2939cSRui Paulo 		return;
4815d4f2939cSRui Paulo 	}
4816d4f2939cSRui Paulo 
48175b9c547cSRui Paulo 	peer_groups_changed(wpa_s);
48185b9c547cSRui Paulo 
4819d4f2939cSRui Paulo 	wpa_printf(MSG_DEBUG, "dbus: Unregister group object '%s'",
4820d4f2939cSRui Paulo 		   wpa_s->dbus_groupobj_path);
4821d4f2939cSRui Paulo 
4822d4f2939cSRui Paulo 	wpa_dbus_unregister_object_per_iface(ctrl_iface,
4823d4f2939cSRui Paulo 					     wpa_s->dbus_groupobj_path);
4824d4f2939cSRui Paulo 
4825d4f2939cSRui Paulo 	os_free(wpa_s->dbus_groupobj_path);
4826d4f2939cSRui Paulo 	wpa_s->dbus_groupobj_path = NULL;
4827d4f2939cSRui Paulo }
4828d4f2939cSRui Paulo 
4829d4f2939cSRui Paulo static const struct wpa_dbus_property_desc
4830d4f2939cSRui Paulo 	wpas_dbus_persistent_group_properties[] = {
4831d4f2939cSRui Paulo 	{ "Properties", WPAS_DBUS_NEW_IFACE_PERSISTENT_GROUP, "a{sv}",
4832d4f2939cSRui Paulo 	  wpas_dbus_getter_persistent_group_properties,
4833780fb4a2SCy Schubert 	  wpas_dbus_setter_persistent_group_properties,
4834780fb4a2SCy Schubert 	  NULL
4835d4f2939cSRui Paulo 	},
4836780fb4a2SCy Schubert 	{ NULL, NULL, NULL, NULL, NULL, NULL }
4837d4f2939cSRui Paulo };
4838d4f2939cSRui Paulo 
4839d4f2939cSRui Paulo /* No signals intended for persistent group objects */
4840d4f2939cSRui Paulo 
4841d4f2939cSRui Paulo /**
4842d4f2939cSRui Paulo  * wpas_dbus_register_persistent_group - Register a configured(saved)
4843d4f2939cSRui Paulo  *	persistent group with dbus
4844d4f2939cSRui Paulo  * @wpa_s: wpa_supplicant interface structure
4845d4f2939cSRui Paulo  * @ssid: persistent group (still represented as a network within wpa)
4846d4f2939cSRui Paulo  *	  configuration data
4847d4f2939cSRui Paulo  * Returns: 0 on success, -1 on failure
4848d4f2939cSRui Paulo  *
4849d4f2939cSRui Paulo  * Registers a persistent group representing object with dbus.
4850d4f2939cSRui Paulo  */
4851d4f2939cSRui Paulo int wpas_dbus_register_persistent_group(struct wpa_supplicant *wpa_s,
4852d4f2939cSRui Paulo 					struct wpa_ssid *ssid)
4853d4f2939cSRui Paulo {
4854d4f2939cSRui Paulo 	struct wpas_dbus_priv *ctrl_iface;
4855d4f2939cSRui Paulo 	struct wpa_dbus_object_desc *obj_desc;
4856d4f2939cSRui Paulo 	struct network_handler_args *arg;
4857d4f2939cSRui Paulo 	char pgrp_obj_path[WPAS_DBUS_OBJECT_PATH_MAX];
4858d4f2939cSRui Paulo 
4859d4f2939cSRui Paulo 	/* Do nothing if the control interface is not turned on */
4860d4f2939cSRui Paulo 	if (wpa_s == NULL || wpa_s->global == NULL)
4861d4f2939cSRui Paulo 		return 0;
4862325151a3SRui Paulo 	wpa_s = wpa_s->parent->parent;
4863325151a3SRui Paulo 	if (!wpa_s->dbus_new_path)
4864325151a3SRui Paulo 		return 0;
4865d4f2939cSRui Paulo 
4866d4f2939cSRui Paulo 	/* Make sure ssid is a persistent group */
4867d4f2939cSRui Paulo 	if (ssid->disabled != 2 && !ssid->p2p_persistent_group)
4868d4f2939cSRui Paulo 		return -1; /* should we return w/o complaining? */
4869d4f2939cSRui Paulo 
48705b9c547cSRui Paulo 	if (wpa_s->p2p_mgmt)
48715b9c547cSRui Paulo 		wpa_s = wpa_s->parent;
48725b9c547cSRui Paulo 
4873d4f2939cSRui Paulo 	ctrl_iface = wpa_s->global->dbus;
4874d4f2939cSRui Paulo 	if (ctrl_iface == NULL)
4875d4f2939cSRui Paulo 		return 0;
4876d4f2939cSRui Paulo 
4877d4f2939cSRui Paulo 	/*
4878d4f2939cSRui Paulo 	 * Intentionally not coming up with different numbering scheme
4879d4f2939cSRui Paulo 	 * for persistent groups.
4880d4f2939cSRui Paulo 	 */
4881d4f2939cSRui Paulo 	os_snprintf(pgrp_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
4882d4f2939cSRui Paulo 		    "%s/" WPAS_DBUS_NEW_PERSISTENT_GROUPS_PART "/%u",
4883d4f2939cSRui Paulo 		    wpa_s->dbus_new_path, ssid->id);
4884d4f2939cSRui Paulo 
4885d4f2939cSRui Paulo 	wpa_printf(MSG_DEBUG, "dbus: Register persistent group object '%s'",
4886d4f2939cSRui Paulo 		   pgrp_obj_path);
4887d4f2939cSRui Paulo 	obj_desc = os_zalloc(sizeof(struct wpa_dbus_object_desc));
4888d4f2939cSRui Paulo 	if (!obj_desc) {
48895b9c547cSRui Paulo 		wpa_printf(MSG_ERROR,
48905b9c547cSRui Paulo 			   "dbus: Not enough memory to create object description");
4891d4f2939cSRui Paulo 		goto err;
4892d4f2939cSRui Paulo 	}
4893d4f2939cSRui Paulo 
4894d4f2939cSRui Paulo 	/*
4895d4f2939cSRui Paulo 	 * Reusing the same context structure as that for networks
4896d4f2939cSRui Paulo 	 * since these are represented using same data structure.
4897d4f2939cSRui Paulo 	 */
4898d4f2939cSRui Paulo 	/* allocate memory for handlers arguments */
4899d4f2939cSRui Paulo 	arg = os_zalloc(sizeof(struct network_handler_args));
4900d4f2939cSRui Paulo 	if (!arg) {
49015b9c547cSRui Paulo 		wpa_printf(MSG_ERROR,
49025b9c547cSRui Paulo 			   "dbus: Not enough memory to create arguments for method");
4903d4f2939cSRui Paulo 		goto err;
4904d4f2939cSRui Paulo 	}
4905d4f2939cSRui Paulo 
4906d4f2939cSRui Paulo 	arg->wpa_s = wpa_s;
4907d4f2939cSRui Paulo 	arg->ssid = ssid;
4908d4f2939cSRui Paulo 
4909d4f2939cSRui Paulo 	wpas_dbus_register(obj_desc, arg, wpa_dbus_free, NULL,
4910d4f2939cSRui Paulo 			   wpas_dbus_persistent_group_properties,
4911d4f2939cSRui Paulo 			   NULL);
4912d4f2939cSRui Paulo 
4913d4f2939cSRui Paulo 	if (wpa_dbus_register_object_per_iface(ctrl_iface, pgrp_obj_path,
4914d4f2939cSRui Paulo 					       wpa_s->ifname, obj_desc))
4915d4f2939cSRui Paulo 		goto err;
4916d4f2939cSRui Paulo 
4917d4f2939cSRui Paulo 	wpas_dbus_signal_persistent_group_added(wpa_s, ssid->id);
4918d4f2939cSRui Paulo 
4919d4f2939cSRui Paulo 	return 0;
4920d4f2939cSRui Paulo 
4921d4f2939cSRui Paulo err:
4922d4f2939cSRui Paulo 	free_dbus_object_desc(obj_desc);
4923d4f2939cSRui Paulo 	return -1;
4924d4f2939cSRui Paulo }
4925d4f2939cSRui Paulo 
4926d4f2939cSRui Paulo 
4927d4f2939cSRui Paulo /**
4928d4f2939cSRui Paulo  * wpas_dbus_unregister_persistent_group - Unregister a persistent_group
4929d4f2939cSRui Paulo  *	from dbus
4930d4f2939cSRui Paulo  * @wpa_s: wpa_supplicant interface structure
4931d4f2939cSRui Paulo  * @nid: network id
4932d4f2939cSRui Paulo  * Returns: 0 on success, -1 on failure
4933d4f2939cSRui Paulo  *
4934d4f2939cSRui Paulo  * Unregisters persistent group representing object from dbus
4935d4f2939cSRui Paulo  *
4936d4f2939cSRui Paulo  * NOTE: There is a slight issue with the semantics here. While the
4937d4f2939cSRui Paulo  * implementation simply means the persistent group is unloaded from memory,
4938d4f2939cSRui Paulo  * it should not get interpreted as the group is actually being erased/removed
4939d4f2939cSRui Paulo  * from persistent storage as well.
4940d4f2939cSRui Paulo  */
4941d4f2939cSRui Paulo int wpas_dbus_unregister_persistent_group(struct wpa_supplicant *wpa_s,
4942d4f2939cSRui Paulo 					  int nid)
4943d4f2939cSRui Paulo {
4944d4f2939cSRui Paulo 	struct wpas_dbus_priv *ctrl_iface;
4945d4f2939cSRui Paulo 	char pgrp_obj_path[WPAS_DBUS_OBJECT_PATH_MAX];
4946d4f2939cSRui Paulo 	int ret;
4947d4f2939cSRui Paulo 
4948d4f2939cSRui Paulo 	/* Do nothing if the control interface is not turned on */
4949325151a3SRui Paulo 	if (wpa_s == NULL || wpa_s->global == NULL)
4950d4f2939cSRui Paulo 		return 0;
49515b9c547cSRui Paulo 
4952325151a3SRui Paulo 	wpa_s = wpa_s->parent->parent;
49535b9c547cSRui Paulo 
4954d4f2939cSRui Paulo 	ctrl_iface = wpa_s->global->dbus;
4955325151a3SRui Paulo 	if (ctrl_iface == NULL || !wpa_s->dbus_new_path)
4956d4f2939cSRui Paulo 		return 0;
4957d4f2939cSRui Paulo 
4958d4f2939cSRui Paulo 	os_snprintf(pgrp_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
4959d4f2939cSRui Paulo 		    "%s/" WPAS_DBUS_NEW_PERSISTENT_GROUPS_PART "/%u",
4960d4f2939cSRui Paulo 		    wpa_s->dbus_new_path, nid);
4961d4f2939cSRui Paulo 
4962d4f2939cSRui Paulo 	wpa_printf(MSG_DEBUG, "dbus: Unregister persistent group object '%s'",
4963d4f2939cSRui Paulo 		   pgrp_obj_path);
4964d4f2939cSRui Paulo 	ret = wpa_dbus_unregister_object_per_iface(ctrl_iface, pgrp_obj_path);
4965d4f2939cSRui Paulo 
4966d4f2939cSRui Paulo 	if (!ret)
4967d4f2939cSRui Paulo 		wpas_dbus_signal_persistent_group_removed(wpa_s, nid);
4968d4f2939cSRui Paulo 
4969d4f2939cSRui Paulo 	return ret;
4970d4f2939cSRui Paulo }
4971d4f2939cSRui Paulo 
4972d4f2939cSRui Paulo #endif /* CONFIG_P2P */
4973