xref: /freebsd/contrib/wpa/wpa_supplicant/dbus/dbus_new.c (revision d4f2939c85ba45ef217ac26dbfc13f07e3c184e8)
1*d4f2939cSRui Paulo /*
2*d4f2939cSRui Paulo  * WPA Supplicant / dbus-based control interface
3*d4f2939cSRui Paulo  * Copyright (c) 2006, Dan Williams <dcbw@redhat.com> and Red Hat, Inc.
4*d4f2939cSRui Paulo  * Copyright (c) 2009-2010, Witold Sowa <witold.sowa@gmail.com>
5*d4f2939cSRui Paulo  * Copyright (c) 2009, Jouni Malinen <j@w1.fi>
6*d4f2939cSRui Paulo  *
7*d4f2939cSRui Paulo  * This software may be distributed under the terms of the BSD license.
8*d4f2939cSRui Paulo  * See README for more details.
9*d4f2939cSRui Paulo  */
10*d4f2939cSRui Paulo 
11*d4f2939cSRui Paulo #include "includes.h"
12*d4f2939cSRui Paulo 
13*d4f2939cSRui Paulo #include "common.h"
14*d4f2939cSRui Paulo #include "common/ieee802_11_defs.h"
15*d4f2939cSRui Paulo #include "wps/wps.h"
16*d4f2939cSRui Paulo #include "../config.h"
17*d4f2939cSRui Paulo #include "../wpa_supplicant_i.h"
18*d4f2939cSRui Paulo #include "../bss.h"
19*d4f2939cSRui Paulo #include "../wpas_glue.h"
20*d4f2939cSRui Paulo #include "dbus_new_helpers.h"
21*d4f2939cSRui Paulo #include "dbus_dict_helpers.h"
22*d4f2939cSRui Paulo #include "dbus_new.h"
23*d4f2939cSRui Paulo #include "dbus_new_handlers.h"
24*d4f2939cSRui Paulo #include "dbus_common_i.h"
25*d4f2939cSRui Paulo #include "dbus_new_handlers_p2p.h"
26*d4f2939cSRui Paulo #include "p2p/p2p.h"
27*d4f2939cSRui Paulo 
28*d4f2939cSRui Paulo #ifdef CONFIG_AP /* until needed by something else */
29*d4f2939cSRui Paulo 
30*d4f2939cSRui Paulo /*
31*d4f2939cSRui Paulo  * NameOwnerChanged handling
32*d4f2939cSRui Paulo  *
33*d4f2939cSRui Paulo  * Some services we provide allow an application to register for
34*d4f2939cSRui Paulo  * a signal that it needs. While it can also unregister, we must
35*d4f2939cSRui Paulo  * be prepared for the case where the application simply crashes
36*d4f2939cSRui Paulo  * and thus doesn't clean up properly. The way to handle this in
37*d4f2939cSRui Paulo  * DBus is to register for the NameOwnerChanged signal which will
38*d4f2939cSRui Paulo  * signal an owner change to NULL if the peer closes the socket
39*d4f2939cSRui Paulo  * for whatever reason.
40*d4f2939cSRui Paulo  *
41*d4f2939cSRui Paulo  * Handle this signal via a filter function whenever necessary.
42*d4f2939cSRui Paulo  * The code below also handles refcounting in case in the future
43*d4f2939cSRui Paulo  * there will be multiple instances of this subscription scheme.
44*d4f2939cSRui Paulo  */
45*d4f2939cSRui Paulo static const char wpas_dbus_noc_filter_str[] =
46*d4f2939cSRui Paulo 	"interface=org.freedesktop.DBus,member=NameOwnerChanged";
47*d4f2939cSRui Paulo 
48*d4f2939cSRui Paulo 
49*d4f2939cSRui Paulo static DBusHandlerResult noc_filter(DBusConnection *conn,
50*d4f2939cSRui Paulo 				    DBusMessage *message, void *data)
51*d4f2939cSRui Paulo {
52*d4f2939cSRui Paulo 	struct wpas_dbus_priv *priv = data;
53*d4f2939cSRui Paulo 
54*d4f2939cSRui Paulo 	if (dbus_message_get_type(message) != DBUS_MESSAGE_TYPE_SIGNAL)
55*d4f2939cSRui Paulo 		return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
56*d4f2939cSRui Paulo 
57*d4f2939cSRui Paulo 	if (dbus_message_is_signal(message, DBUS_INTERFACE_DBUS,
58*d4f2939cSRui Paulo 				   "NameOwnerChanged")) {
59*d4f2939cSRui Paulo 		const char *name;
60*d4f2939cSRui Paulo 		const char *prev_owner;
61*d4f2939cSRui Paulo 		const char *new_owner;
62*d4f2939cSRui Paulo 		DBusError derr;
63*d4f2939cSRui Paulo 		struct wpa_supplicant *wpa_s;
64*d4f2939cSRui Paulo 
65*d4f2939cSRui Paulo 		dbus_error_init(&derr);
66*d4f2939cSRui Paulo 
67*d4f2939cSRui Paulo 		if (!dbus_message_get_args(message, &derr,
68*d4f2939cSRui Paulo 					   DBUS_TYPE_STRING, &name,
69*d4f2939cSRui Paulo 					   DBUS_TYPE_STRING, &prev_owner,
70*d4f2939cSRui Paulo 					   DBUS_TYPE_STRING, &new_owner,
71*d4f2939cSRui Paulo 					   DBUS_TYPE_INVALID)) {
72*d4f2939cSRui Paulo 			/* Ignore this error */
73*d4f2939cSRui Paulo 			dbus_error_free(&derr);
74*d4f2939cSRui Paulo 			return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
75*d4f2939cSRui Paulo 		}
76*d4f2939cSRui Paulo 
77*d4f2939cSRui Paulo 		for (wpa_s = priv->global->ifaces; wpa_s; wpa_s = wpa_s->next)
78*d4f2939cSRui Paulo 		{
79*d4f2939cSRui Paulo 			if (wpa_s->preq_notify_peer != NULL &&
80*d4f2939cSRui Paulo 			    os_strcmp(name, wpa_s->preq_notify_peer) == 0 &&
81*d4f2939cSRui Paulo 			    (new_owner == NULL || os_strlen(new_owner) == 0)) {
82*d4f2939cSRui Paulo 				/* probe request owner disconnected */
83*d4f2939cSRui Paulo 				os_free(wpa_s->preq_notify_peer);
84*d4f2939cSRui Paulo 				wpa_s->preq_notify_peer = NULL;
85*d4f2939cSRui Paulo 				wpas_dbus_unsubscribe_noc(priv);
86*d4f2939cSRui Paulo 			}
87*d4f2939cSRui Paulo 		}
88*d4f2939cSRui Paulo 	}
89*d4f2939cSRui Paulo 
90*d4f2939cSRui Paulo 	return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
91*d4f2939cSRui Paulo }
92*d4f2939cSRui Paulo 
93*d4f2939cSRui Paulo 
94*d4f2939cSRui Paulo void wpas_dbus_subscribe_noc(struct wpas_dbus_priv *priv)
95*d4f2939cSRui Paulo {
96*d4f2939cSRui Paulo 	priv->dbus_noc_refcnt++;
97*d4f2939cSRui Paulo 	if (priv->dbus_noc_refcnt > 1)
98*d4f2939cSRui Paulo 		return;
99*d4f2939cSRui Paulo 
100*d4f2939cSRui Paulo 	if (!dbus_connection_add_filter(priv->con, noc_filter, priv, NULL)) {
101*d4f2939cSRui Paulo 		wpa_printf(MSG_ERROR, "dbus: failed to add filter");
102*d4f2939cSRui Paulo 		return;
103*d4f2939cSRui Paulo 	}
104*d4f2939cSRui Paulo 
105*d4f2939cSRui Paulo 	dbus_bus_add_match(priv->con, wpas_dbus_noc_filter_str, NULL);
106*d4f2939cSRui Paulo }
107*d4f2939cSRui Paulo 
108*d4f2939cSRui Paulo 
109*d4f2939cSRui Paulo void wpas_dbus_unsubscribe_noc(struct wpas_dbus_priv *priv)
110*d4f2939cSRui Paulo {
111*d4f2939cSRui Paulo 	priv->dbus_noc_refcnt--;
112*d4f2939cSRui Paulo 	if (priv->dbus_noc_refcnt > 0)
113*d4f2939cSRui Paulo 		return;
114*d4f2939cSRui Paulo 
115*d4f2939cSRui Paulo 	dbus_bus_remove_match(priv->con, wpas_dbus_noc_filter_str, NULL);
116*d4f2939cSRui Paulo 	dbus_connection_remove_filter(priv->con, noc_filter, priv);
117*d4f2939cSRui Paulo }
118*d4f2939cSRui Paulo 
119*d4f2939cSRui Paulo #endif /* CONFIG_AP */
120*d4f2939cSRui Paulo 
121*d4f2939cSRui Paulo 
122*d4f2939cSRui Paulo /**
123*d4f2939cSRui Paulo  * wpas_dbus_signal_interface - Send a interface related event signal
124*d4f2939cSRui Paulo  * @wpa_s: %wpa_supplicant network interface data
125*d4f2939cSRui Paulo  * @sig_name: signal name - InterfaceAdded or InterfaceRemoved
126*d4f2939cSRui Paulo  * @properties: Whether to add second argument with object properties
127*d4f2939cSRui Paulo  *
128*d4f2939cSRui Paulo  * Notify listeners about event related with interface
129*d4f2939cSRui Paulo  */
130*d4f2939cSRui Paulo static void wpas_dbus_signal_interface(struct wpa_supplicant *wpa_s,
131*d4f2939cSRui Paulo 				       const char *sig_name, int properties)
132*d4f2939cSRui Paulo {
133*d4f2939cSRui Paulo 	struct wpas_dbus_priv *iface;
134*d4f2939cSRui Paulo 	DBusMessage *msg;
135*d4f2939cSRui Paulo 	DBusMessageIter iter;
136*d4f2939cSRui Paulo 
137*d4f2939cSRui Paulo 	iface = wpa_s->global->dbus;
138*d4f2939cSRui Paulo 
139*d4f2939cSRui Paulo 	/* Do nothing if the control interface is not turned on */
140*d4f2939cSRui Paulo 	if (iface == NULL)
141*d4f2939cSRui Paulo 		return;
142*d4f2939cSRui Paulo 
143*d4f2939cSRui Paulo 	msg = dbus_message_new_signal(WPAS_DBUS_NEW_PATH,
144*d4f2939cSRui Paulo 				      WPAS_DBUS_NEW_INTERFACE, sig_name);
145*d4f2939cSRui Paulo 	if (msg == NULL)
146*d4f2939cSRui Paulo 		return;
147*d4f2939cSRui Paulo 
148*d4f2939cSRui Paulo 	dbus_message_iter_init_append(msg, &iter);
149*d4f2939cSRui Paulo 	if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_OBJECT_PATH,
150*d4f2939cSRui Paulo 					    &wpa_s->dbus_new_path))
151*d4f2939cSRui Paulo 		goto err;
152*d4f2939cSRui Paulo 
153*d4f2939cSRui Paulo 	if (properties) {
154*d4f2939cSRui Paulo 		if (!wpa_dbus_get_object_properties(
155*d4f2939cSRui Paulo 			    iface, wpa_s->dbus_new_path,
156*d4f2939cSRui Paulo 			    WPAS_DBUS_NEW_IFACE_INTERFACE, &iter))
157*d4f2939cSRui Paulo 			goto err;
158*d4f2939cSRui Paulo 	}
159*d4f2939cSRui Paulo 
160*d4f2939cSRui Paulo 	dbus_connection_send(iface->con, msg, NULL);
161*d4f2939cSRui Paulo 	dbus_message_unref(msg);
162*d4f2939cSRui Paulo 	return;
163*d4f2939cSRui Paulo 
164*d4f2939cSRui Paulo err:
165*d4f2939cSRui Paulo 	wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
166*d4f2939cSRui Paulo 	dbus_message_unref(msg);
167*d4f2939cSRui Paulo }
168*d4f2939cSRui Paulo 
169*d4f2939cSRui Paulo 
170*d4f2939cSRui Paulo /**
171*d4f2939cSRui Paulo  * wpas_dbus_signal_interface_added - Send a interface created signal
172*d4f2939cSRui Paulo  * @wpa_s: %wpa_supplicant network interface data
173*d4f2939cSRui Paulo  *
174*d4f2939cSRui Paulo  * Notify listeners about creating new interface
175*d4f2939cSRui Paulo  */
176*d4f2939cSRui Paulo static void wpas_dbus_signal_interface_added(struct wpa_supplicant *wpa_s)
177*d4f2939cSRui Paulo {
178*d4f2939cSRui Paulo 	wpas_dbus_signal_interface(wpa_s, "InterfaceAdded", TRUE);
179*d4f2939cSRui Paulo }
180*d4f2939cSRui Paulo 
181*d4f2939cSRui Paulo 
182*d4f2939cSRui Paulo /**
183*d4f2939cSRui Paulo  * wpas_dbus_signal_interface_removed - Send a interface removed signal
184*d4f2939cSRui Paulo  * @wpa_s: %wpa_supplicant network interface data
185*d4f2939cSRui Paulo  *
186*d4f2939cSRui Paulo  * Notify listeners about removing interface
187*d4f2939cSRui Paulo  */
188*d4f2939cSRui Paulo static void wpas_dbus_signal_interface_removed(struct wpa_supplicant *wpa_s)
189*d4f2939cSRui Paulo {
190*d4f2939cSRui Paulo 	wpas_dbus_signal_interface(wpa_s, "InterfaceRemoved", FALSE);
191*d4f2939cSRui Paulo 
192*d4f2939cSRui Paulo }
193*d4f2939cSRui Paulo 
194*d4f2939cSRui Paulo 
195*d4f2939cSRui Paulo /**
196*d4f2939cSRui Paulo  * wpas_dbus_signal_scan_done - send scan done signal
197*d4f2939cSRui Paulo  * @wpa_s: %wpa_supplicant network interface data
198*d4f2939cSRui Paulo  * @success: indicates if scanning succeed or failed
199*d4f2939cSRui Paulo  *
200*d4f2939cSRui Paulo  * Notify listeners about finishing a scan
201*d4f2939cSRui Paulo  */
202*d4f2939cSRui Paulo void wpas_dbus_signal_scan_done(struct wpa_supplicant *wpa_s, int success)
203*d4f2939cSRui Paulo {
204*d4f2939cSRui Paulo 	struct wpas_dbus_priv *iface;
205*d4f2939cSRui Paulo 	DBusMessage *msg;
206*d4f2939cSRui Paulo 	dbus_bool_t succ;
207*d4f2939cSRui Paulo 
208*d4f2939cSRui Paulo 	iface = wpa_s->global->dbus;
209*d4f2939cSRui Paulo 
210*d4f2939cSRui Paulo 	/* Do nothing if the control interface is not turned on */
211*d4f2939cSRui Paulo 	if (iface == NULL)
212*d4f2939cSRui Paulo 		return;
213*d4f2939cSRui Paulo 
214*d4f2939cSRui Paulo 	msg = dbus_message_new_signal(wpa_s->dbus_new_path,
215*d4f2939cSRui Paulo 				      WPAS_DBUS_NEW_IFACE_INTERFACE,
216*d4f2939cSRui Paulo 				      "ScanDone");
217*d4f2939cSRui Paulo 	if (msg == NULL)
218*d4f2939cSRui Paulo 		return;
219*d4f2939cSRui Paulo 
220*d4f2939cSRui Paulo 	succ = success ? TRUE : FALSE;
221*d4f2939cSRui Paulo 	if (dbus_message_append_args(msg, DBUS_TYPE_BOOLEAN, &succ,
222*d4f2939cSRui Paulo 				     DBUS_TYPE_INVALID))
223*d4f2939cSRui Paulo 		dbus_connection_send(iface->con, msg, NULL);
224*d4f2939cSRui Paulo 	else
225*d4f2939cSRui Paulo 		wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
226*d4f2939cSRui Paulo 	dbus_message_unref(msg);
227*d4f2939cSRui Paulo }
228*d4f2939cSRui Paulo 
229*d4f2939cSRui Paulo 
230*d4f2939cSRui Paulo /**
231*d4f2939cSRui Paulo  * wpas_dbus_signal_blob - Send a BSS related event signal
232*d4f2939cSRui Paulo  * @wpa_s: %wpa_supplicant network interface data
233*d4f2939cSRui Paulo  * @bss_obj_path: BSS object path
234*d4f2939cSRui Paulo  * @sig_name: signal name - BSSAdded or BSSRemoved
235*d4f2939cSRui Paulo  * @properties: Whether to add second argument with object properties
236*d4f2939cSRui Paulo  *
237*d4f2939cSRui Paulo  * Notify listeners about event related with BSS
238*d4f2939cSRui Paulo  */
239*d4f2939cSRui Paulo static void wpas_dbus_signal_bss(struct wpa_supplicant *wpa_s,
240*d4f2939cSRui Paulo 				 const char *bss_obj_path,
241*d4f2939cSRui Paulo 				 const char *sig_name, int properties)
242*d4f2939cSRui Paulo {
243*d4f2939cSRui Paulo 	struct wpas_dbus_priv *iface;
244*d4f2939cSRui Paulo 	DBusMessage *msg;
245*d4f2939cSRui Paulo 	DBusMessageIter iter;
246*d4f2939cSRui Paulo 
247*d4f2939cSRui Paulo 	iface = wpa_s->global->dbus;
248*d4f2939cSRui Paulo 
249*d4f2939cSRui Paulo 	/* Do nothing if the control interface is not turned on */
250*d4f2939cSRui Paulo 	if (iface == NULL)
251*d4f2939cSRui Paulo 		return;
252*d4f2939cSRui Paulo 
253*d4f2939cSRui Paulo 	msg = dbus_message_new_signal(wpa_s->dbus_new_path,
254*d4f2939cSRui Paulo 				      WPAS_DBUS_NEW_IFACE_INTERFACE,
255*d4f2939cSRui Paulo 				      sig_name);
256*d4f2939cSRui Paulo 	if (msg == NULL)
257*d4f2939cSRui Paulo 		return;
258*d4f2939cSRui Paulo 
259*d4f2939cSRui Paulo 	dbus_message_iter_init_append(msg, &iter);
260*d4f2939cSRui Paulo 	if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_OBJECT_PATH,
261*d4f2939cSRui Paulo 					    &bss_obj_path))
262*d4f2939cSRui Paulo 		goto err;
263*d4f2939cSRui Paulo 
264*d4f2939cSRui Paulo 	if (properties) {
265*d4f2939cSRui Paulo 		if (!wpa_dbus_get_object_properties(iface, bss_obj_path,
266*d4f2939cSRui Paulo 						    WPAS_DBUS_NEW_IFACE_BSS,
267*d4f2939cSRui Paulo 						    &iter))
268*d4f2939cSRui Paulo 			goto err;
269*d4f2939cSRui Paulo 	}
270*d4f2939cSRui Paulo 
271*d4f2939cSRui Paulo 	dbus_connection_send(iface->con, msg, NULL);
272*d4f2939cSRui Paulo 	dbus_message_unref(msg);
273*d4f2939cSRui Paulo 	return;
274*d4f2939cSRui Paulo 
275*d4f2939cSRui Paulo err:
276*d4f2939cSRui Paulo 	wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
277*d4f2939cSRui Paulo 	dbus_message_unref(msg);
278*d4f2939cSRui Paulo }
279*d4f2939cSRui Paulo 
280*d4f2939cSRui Paulo 
281*d4f2939cSRui Paulo /**
282*d4f2939cSRui Paulo  * wpas_dbus_signal_bss_added - Send a BSS added signal
283*d4f2939cSRui Paulo  * @wpa_s: %wpa_supplicant network interface data
284*d4f2939cSRui Paulo  * @bss_obj_path: new BSS object path
285*d4f2939cSRui Paulo  *
286*d4f2939cSRui Paulo  * Notify listeners about adding new BSS
287*d4f2939cSRui Paulo  */
288*d4f2939cSRui Paulo static void wpas_dbus_signal_bss_added(struct wpa_supplicant *wpa_s,
289*d4f2939cSRui Paulo 				       const char *bss_obj_path)
290*d4f2939cSRui Paulo {
291*d4f2939cSRui Paulo 	wpas_dbus_signal_bss(wpa_s, bss_obj_path, "BSSAdded", TRUE);
292*d4f2939cSRui Paulo }
293*d4f2939cSRui Paulo 
294*d4f2939cSRui Paulo 
295*d4f2939cSRui Paulo /**
296*d4f2939cSRui Paulo  * wpas_dbus_signal_bss_removed - Send a BSS removed signal
297*d4f2939cSRui Paulo  * @wpa_s: %wpa_supplicant network interface data
298*d4f2939cSRui Paulo  * @bss_obj_path: BSS object path
299*d4f2939cSRui Paulo  *
300*d4f2939cSRui Paulo  * Notify listeners about removing BSS
301*d4f2939cSRui Paulo  */
302*d4f2939cSRui Paulo static void wpas_dbus_signal_bss_removed(struct wpa_supplicant *wpa_s,
303*d4f2939cSRui Paulo 					 const char *bss_obj_path)
304*d4f2939cSRui Paulo {
305*d4f2939cSRui Paulo 	wpas_dbus_signal_bss(wpa_s, bss_obj_path, "BSSRemoved", FALSE);
306*d4f2939cSRui Paulo }
307*d4f2939cSRui Paulo 
308*d4f2939cSRui Paulo 
309*d4f2939cSRui Paulo /**
310*d4f2939cSRui Paulo  * wpas_dbus_signal_blob - Send a blob related event signal
311*d4f2939cSRui Paulo  * @wpa_s: %wpa_supplicant network interface data
312*d4f2939cSRui Paulo  * @name: blob name
313*d4f2939cSRui Paulo  * @sig_name: signal name - BlobAdded or BlobRemoved
314*d4f2939cSRui Paulo  *
315*d4f2939cSRui Paulo  * Notify listeners about event related with blob
316*d4f2939cSRui Paulo  */
317*d4f2939cSRui Paulo static void wpas_dbus_signal_blob(struct wpa_supplicant *wpa_s,
318*d4f2939cSRui Paulo 				  const char *name, const char *sig_name)
319*d4f2939cSRui Paulo {
320*d4f2939cSRui Paulo 	struct wpas_dbus_priv *iface;
321*d4f2939cSRui Paulo 	DBusMessage *msg;
322*d4f2939cSRui Paulo 
323*d4f2939cSRui Paulo 	iface = wpa_s->global->dbus;
324*d4f2939cSRui Paulo 
325*d4f2939cSRui Paulo 	/* Do nothing if the control interface is not turned on */
326*d4f2939cSRui Paulo 	if (iface == NULL)
327*d4f2939cSRui Paulo 		return;
328*d4f2939cSRui Paulo 
329*d4f2939cSRui Paulo 	msg = dbus_message_new_signal(wpa_s->dbus_new_path,
330*d4f2939cSRui Paulo 				      WPAS_DBUS_NEW_IFACE_INTERFACE,
331*d4f2939cSRui Paulo 				      sig_name);
332*d4f2939cSRui Paulo 	if (msg == NULL)
333*d4f2939cSRui Paulo 		return;
334*d4f2939cSRui Paulo 
335*d4f2939cSRui Paulo 	if (dbus_message_append_args(msg, DBUS_TYPE_STRING, &name,
336*d4f2939cSRui Paulo 				     DBUS_TYPE_INVALID))
337*d4f2939cSRui Paulo 		dbus_connection_send(iface->con, msg, NULL);
338*d4f2939cSRui Paulo 	else
339*d4f2939cSRui Paulo 		wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
340*d4f2939cSRui Paulo 	dbus_message_unref(msg);
341*d4f2939cSRui Paulo }
342*d4f2939cSRui Paulo 
343*d4f2939cSRui Paulo 
344*d4f2939cSRui Paulo /**
345*d4f2939cSRui Paulo  * wpas_dbus_signal_blob_added - Send a blob added signal
346*d4f2939cSRui Paulo  * @wpa_s: %wpa_supplicant network interface data
347*d4f2939cSRui Paulo  * @name: blob name
348*d4f2939cSRui Paulo  *
349*d4f2939cSRui Paulo  * Notify listeners about adding a new blob
350*d4f2939cSRui Paulo  */
351*d4f2939cSRui Paulo void wpas_dbus_signal_blob_added(struct wpa_supplicant *wpa_s,
352*d4f2939cSRui Paulo 				 const char *name)
353*d4f2939cSRui Paulo {
354*d4f2939cSRui Paulo 	wpas_dbus_signal_blob(wpa_s, name, "BlobAdded");
355*d4f2939cSRui Paulo }
356*d4f2939cSRui Paulo 
357*d4f2939cSRui Paulo 
358*d4f2939cSRui Paulo /**
359*d4f2939cSRui Paulo  * wpas_dbus_signal_blob_removed - Send a blob removed signal
360*d4f2939cSRui Paulo  * @wpa_s: %wpa_supplicant network interface data
361*d4f2939cSRui Paulo  * @name: blob name
362*d4f2939cSRui Paulo  *
363*d4f2939cSRui Paulo  * Notify listeners about removing blob
364*d4f2939cSRui Paulo  */
365*d4f2939cSRui Paulo void wpas_dbus_signal_blob_removed(struct wpa_supplicant *wpa_s,
366*d4f2939cSRui Paulo 				   const char *name)
367*d4f2939cSRui Paulo {
368*d4f2939cSRui Paulo 	wpas_dbus_signal_blob(wpa_s, name, "BlobRemoved");
369*d4f2939cSRui Paulo }
370*d4f2939cSRui Paulo 
371*d4f2939cSRui Paulo 
372*d4f2939cSRui Paulo /**
373*d4f2939cSRui Paulo  * wpas_dbus_signal_network - Send a network related event signal
374*d4f2939cSRui Paulo  * @wpa_s: %wpa_supplicant network interface data
375*d4f2939cSRui Paulo  * @id: new network id
376*d4f2939cSRui Paulo  * @sig_name: signal name - NetworkAdded, NetworkRemoved or NetworkSelected
377*d4f2939cSRui Paulo  * @properties: determines if add second argument with object properties
378*d4f2939cSRui Paulo  *
379*d4f2939cSRui Paulo  * Notify listeners about event related with configured network
380*d4f2939cSRui Paulo  */
381*d4f2939cSRui Paulo static void wpas_dbus_signal_network(struct wpa_supplicant *wpa_s,
382*d4f2939cSRui Paulo 				     int id, const char *sig_name,
383*d4f2939cSRui Paulo 				     int properties)
384*d4f2939cSRui Paulo {
385*d4f2939cSRui Paulo 	struct wpas_dbus_priv *iface;
386*d4f2939cSRui Paulo 	DBusMessage *msg;
387*d4f2939cSRui Paulo 	DBusMessageIter iter;
388*d4f2939cSRui Paulo 	char net_obj_path[WPAS_DBUS_OBJECT_PATH_MAX], *path;
389*d4f2939cSRui Paulo 
390*d4f2939cSRui Paulo 	iface = wpa_s->global->dbus;
391*d4f2939cSRui Paulo 
392*d4f2939cSRui Paulo 	/* Do nothing if the control interface is not turned on */
393*d4f2939cSRui Paulo 	if (iface == NULL)
394*d4f2939cSRui Paulo 		return;
395*d4f2939cSRui Paulo 
396*d4f2939cSRui Paulo 	os_snprintf(net_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
397*d4f2939cSRui Paulo 		    "%s/" WPAS_DBUS_NEW_NETWORKS_PART "/%u",
398*d4f2939cSRui Paulo 		    wpa_s->dbus_new_path, id);
399*d4f2939cSRui Paulo 
400*d4f2939cSRui Paulo 	msg = dbus_message_new_signal(wpa_s->dbus_new_path,
401*d4f2939cSRui Paulo 				      WPAS_DBUS_NEW_IFACE_INTERFACE,
402*d4f2939cSRui Paulo 				      sig_name);
403*d4f2939cSRui Paulo 	if (msg == NULL)
404*d4f2939cSRui Paulo 		return;
405*d4f2939cSRui Paulo 
406*d4f2939cSRui Paulo 	dbus_message_iter_init_append(msg, &iter);
407*d4f2939cSRui Paulo 	path = net_obj_path;
408*d4f2939cSRui Paulo 	if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_OBJECT_PATH,
409*d4f2939cSRui Paulo 					    &path))
410*d4f2939cSRui Paulo 		goto err;
411*d4f2939cSRui Paulo 
412*d4f2939cSRui Paulo 	if (properties) {
413*d4f2939cSRui Paulo 		if (!wpa_dbus_get_object_properties(
414*d4f2939cSRui Paulo 			    iface, net_obj_path, WPAS_DBUS_NEW_IFACE_NETWORK,
415*d4f2939cSRui Paulo 			    &iter))
416*d4f2939cSRui Paulo 			goto err;
417*d4f2939cSRui Paulo 	}
418*d4f2939cSRui Paulo 
419*d4f2939cSRui Paulo 	dbus_connection_send(iface->con, msg, NULL);
420*d4f2939cSRui Paulo 
421*d4f2939cSRui Paulo 	dbus_message_unref(msg);
422*d4f2939cSRui Paulo 	return;
423*d4f2939cSRui Paulo 
424*d4f2939cSRui Paulo err:
425*d4f2939cSRui Paulo 	wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
426*d4f2939cSRui Paulo 	dbus_message_unref(msg);
427*d4f2939cSRui Paulo }
428*d4f2939cSRui Paulo 
429*d4f2939cSRui Paulo 
430*d4f2939cSRui Paulo /**
431*d4f2939cSRui Paulo  * wpas_dbus_signal_network_added - Send a network added signal
432*d4f2939cSRui Paulo  * @wpa_s: %wpa_supplicant network interface data
433*d4f2939cSRui Paulo  * @id: new network id
434*d4f2939cSRui Paulo  *
435*d4f2939cSRui Paulo  * Notify listeners about adding new network
436*d4f2939cSRui Paulo  */
437*d4f2939cSRui Paulo static void wpas_dbus_signal_network_added(struct wpa_supplicant *wpa_s,
438*d4f2939cSRui Paulo 					   int id)
439*d4f2939cSRui Paulo {
440*d4f2939cSRui Paulo 	wpas_dbus_signal_network(wpa_s, id, "NetworkAdded", TRUE);
441*d4f2939cSRui Paulo }
442*d4f2939cSRui Paulo 
443*d4f2939cSRui Paulo 
444*d4f2939cSRui Paulo /**
445*d4f2939cSRui Paulo  * wpas_dbus_signal_network_removed - Send a network removed signal
446*d4f2939cSRui Paulo  * @wpa_s: %wpa_supplicant network interface data
447*d4f2939cSRui Paulo  * @id: network id
448*d4f2939cSRui Paulo  *
449*d4f2939cSRui Paulo  * Notify listeners about removing a network
450*d4f2939cSRui Paulo  */
451*d4f2939cSRui Paulo static void wpas_dbus_signal_network_removed(struct wpa_supplicant *wpa_s,
452*d4f2939cSRui Paulo 					     int id)
453*d4f2939cSRui Paulo {
454*d4f2939cSRui Paulo 	wpas_dbus_signal_network(wpa_s, id, "NetworkRemoved", FALSE);
455*d4f2939cSRui Paulo }
456*d4f2939cSRui Paulo 
457*d4f2939cSRui Paulo 
458*d4f2939cSRui Paulo /**
459*d4f2939cSRui Paulo  * wpas_dbus_signal_network_selected - Send a network selected signal
460*d4f2939cSRui Paulo  * @wpa_s: %wpa_supplicant network interface data
461*d4f2939cSRui Paulo  * @id: network id
462*d4f2939cSRui Paulo  *
463*d4f2939cSRui Paulo  * Notify listeners about selecting a network
464*d4f2939cSRui Paulo  */
465*d4f2939cSRui Paulo void wpas_dbus_signal_network_selected(struct wpa_supplicant *wpa_s, int id)
466*d4f2939cSRui Paulo {
467*d4f2939cSRui Paulo 	wpas_dbus_signal_network(wpa_s, id, "NetworkSelected", FALSE);
468*d4f2939cSRui Paulo }
469*d4f2939cSRui Paulo 
470*d4f2939cSRui Paulo 
471*d4f2939cSRui Paulo /**
472*d4f2939cSRui Paulo  * wpas_dbus_signal_network_request - Indicate that additional information
473*d4f2939cSRui Paulo  * (EAP password, etc.) is required to complete the association to this SSID
474*d4f2939cSRui Paulo  * @wpa_s: %wpa_supplicant network interface data
475*d4f2939cSRui Paulo  * @rtype: The specific additional information required
476*d4f2939cSRui Paulo  * @default_text: Optional description of required information
477*d4f2939cSRui Paulo  *
478*d4f2939cSRui Paulo  * Request additional information or passwords to complete an association
479*d4f2939cSRui Paulo  * request.
480*d4f2939cSRui Paulo  */
481*d4f2939cSRui Paulo void wpas_dbus_signal_network_request(struct wpa_supplicant *wpa_s,
482*d4f2939cSRui Paulo 				      struct wpa_ssid *ssid,
483*d4f2939cSRui Paulo 				      enum wpa_ctrl_req_type rtype,
484*d4f2939cSRui Paulo 				      const char *default_txt)
485*d4f2939cSRui Paulo {
486*d4f2939cSRui Paulo 	struct wpas_dbus_priv *iface;
487*d4f2939cSRui Paulo 	DBusMessage *msg;
488*d4f2939cSRui Paulo 	DBusMessageIter iter;
489*d4f2939cSRui Paulo 	char net_obj_path[WPAS_DBUS_OBJECT_PATH_MAX];
490*d4f2939cSRui Paulo 	const char *field, *txt = NULL, *net_ptr;
491*d4f2939cSRui Paulo 
492*d4f2939cSRui Paulo 	iface = wpa_s->global->dbus;
493*d4f2939cSRui Paulo 
494*d4f2939cSRui Paulo 	/* Do nothing if the control interface is not turned on */
495*d4f2939cSRui Paulo 	if (iface == NULL)
496*d4f2939cSRui Paulo 		return;
497*d4f2939cSRui Paulo 
498*d4f2939cSRui Paulo 	field = wpa_supplicant_ctrl_req_to_string(rtype, default_txt, &txt);
499*d4f2939cSRui Paulo 	if (field == NULL)
500*d4f2939cSRui Paulo 		return;
501*d4f2939cSRui Paulo 
502*d4f2939cSRui Paulo 	msg = dbus_message_new_signal(wpa_s->dbus_new_path,
503*d4f2939cSRui Paulo 				      WPAS_DBUS_NEW_IFACE_INTERFACE,
504*d4f2939cSRui Paulo 				      "NetworkRequest");
505*d4f2939cSRui Paulo 	if (msg == NULL)
506*d4f2939cSRui Paulo 		return;
507*d4f2939cSRui Paulo 
508*d4f2939cSRui Paulo 	os_snprintf(net_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
509*d4f2939cSRui Paulo 		    "%s/" WPAS_DBUS_NEW_NETWORKS_PART "/%u",
510*d4f2939cSRui Paulo 		    wpa_s->dbus_new_path, ssid->id);
511*d4f2939cSRui Paulo 	net_ptr = &net_obj_path[0];
512*d4f2939cSRui Paulo 
513*d4f2939cSRui Paulo 	dbus_message_iter_init_append(msg, &iter);
514*d4f2939cSRui Paulo 	if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_OBJECT_PATH,
515*d4f2939cSRui Paulo 					    &net_ptr))
516*d4f2939cSRui Paulo 		goto err;
517*d4f2939cSRui Paulo 	if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &field))
518*d4f2939cSRui Paulo 		goto err;
519*d4f2939cSRui Paulo 	if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &txt))
520*d4f2939cSRui Paulo 		goto err;
521*d4f2939cSRui Paulo 
522*d4f2939cSRui Paulo 	dbus_connection_send(iface->con, msg, NULL);
523*d4f2939cSRui Paulo 	dbus_message_unref(msg);
524*d4f2939cSRui Paulo 	return;
525*d4f2939cSRui Paulo 
526*d4f2939cSRui Paulo err:
527*d4f2939cSRui Paulo 	wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
528*d4f2939cSRui Paulo 	dbus_message_unref(msg);
529*d4f2939cSRui Paulo }
530*d4f2939cSRui Paulo 
531*d4f2939cSRui Paulo 
532*d4f2939cSRui Paulo /**
533*d4f2939cSRui Paulo  * wpas_dbus_signal_network_enabled_changed - Signals Enabled property changes
534*d4f2939cSRui Paulo  * @wpa_s: %wpa_supplicant network interface data
535*d4f2939cSRui Paulo  * @ssid: configured network which Enabled property has changed
536*d4f2939cSRui Paulo  *
537*d4f2939cSRui Paulo  * Sends PropertyChanged signals containing new value of Enabled property
538*d4f2939cSRui Paulo  * for specified network
539*d4f2939cSRui Paulo  */
540*d4f2939cSRui Paulo void wpas_dbus_signal_network_enabled_changed(struct wpa_supplicant *wpa_s,
541*d4f2939cSRui Paulo 					      struct wpa_ssid *ssid)
542*d4f2939cSRui Paulo {
543*d4f2939cSRui Paulo 
544*d4f2939cSRui Paulo 	char path[WPAS_DBUS_OBJECT_PATH_MAX];
545*d4f2939cSRui Paulo 	os_snprintf(path, WPAS_DBUS_OBJECT_PATH_MAX,
546*d4f2939cSRui Paulo 		    "%s/" WPAS_DBUS_NEW_NETWORKS_PART "/%d",
547*d4f2939cSRui Paulo 		    wpa_s->dbus_new_path, ssid->id);
548*d4f2939cSRui Paulo 
549*d4f2939cSRui Paulo 	wpa_dbus_mark_property_changed(wpa_s->global->dbus, path,
550*d4f2939cSRui Paulo 				       WPAS_DBUS_NEW_IFACE_NETWORK, "Enabled");
551*d4f2939cSRui Paulo }
552*d4f2939cSRui Paulo 
553*d4f2939cSRui Paulo 
554*d4f2939cSRui Paulo #ifdef CONFIG_WPS
555*d4f2939cSRui Paulo 
556*d4f2939cSRui Paulo /**
557*d4f2939cSRui Paulo  * wpas_dbus_signal_wps_event_success - Signals Success WPS event
558*d4f2939cSRui Paulo  * @wpa_s: %wpa_supplicant network interface data
559*d4f2939cSRui Paulo  *
560*d4f2939cSRui Paulo  * Sends Event dbus signal with name "success" and empty dict as arguments
561*d4f2939cSRui Paulo  */
562*d4f2939cSRui Paulo void wpas_dbus_signal_wps_event_success(struct wpa_supplicant *wpa_s)
563*d4f2939cSRui Paulo {
564*d4f2939cSRui Paulo 
565*d4f2939cSRui Paulo 	DBusMessage *msg;
566*d4f2939cSRui Paulo 	DBusMessageIter iter, dict_iter;
567*d4f2939cSRui Paulo 	struct wpas_dbus_priv *iface;
568*d4f2939cSRui Paulo 	char *key = "success";
569*d4f2939cSRui Paulo 
570*d4f2939cSRui Paulo 	iface = wpa_s->global->dbus;
571*d4f2939cSRui Paulo 
572*d4f2939cSRui Paulo 	/* Do nothing if the control interface is not turned on */
573*d4f2939cSRui Paulo 	if (iface == NULL)
574*d4f2939cSRui Paulo 		return;
575*d4f2939cSRui Paulo 
576*d4f2939cSRui Paulo 	msg = dbus_message_new_signal(wpa_s->dbus_new_path,
577*d4f2939cSRui Paulo 				      WPAS_DBUS_NEW_IFACE_WPS, "Event");
578*d4f2939cSRui Paulo 	if (msg == NULL)
579*d4f2939cSRui Paulo 		return;
580*d4f2939cSRui Paulo 
581*d4f2939cSRui Paulo 	dbus_message_iter_init_append(msg, &iter);
582*d4f2939cSRui Paulo 
583*d4f2939cSRui Paulo 	if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &key) ||
584*d4f2939cSRui Paulo 	    !wpa_dbus_dict_open_write(&iter, &dict_iter) ||
585*d4f2939cSRui Paulo 	    !wpa_dbus_dict_close_write(&iter, &dict_iter))
586*d4f2939cSRui Paulo 		wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
587*d4f2939cSRui Paulo 	else
588*d4f2939cSRui Paulo 		dbus_connection_send(iface->con, msg, NULL);
589*d4f2939cSRui Paulo 
590*d4f2939cSRui Paulo 	dbus_message_unref(msg);
591*d4f2939cSRui Paulo }
592*d4f2939cSRui Paulo 
593*d4f2939cSRui Paulo 
594*d4f2939cSRui Paulo /**
595*d4f2939cSRui Paulo  * wpas_dbus_signal_wps_event_fail - Signals Fail WPS event
596*d4f2939cSRui Paulo  * @wpa_s: %wpa_supplicant network interface data
597*d4f2939cSRui Paulo  *
598*d4f2939cSRui Paulo  * Sends Event dbus signal with name "fail" and dictionary containing
599*d4f2939cSRui Paulo  * "msg field with fail message number (int32) as arguments
600*d4f2939cSRui Paulo  */
601*d4f2939cSRui Paulo void wpas_dbus_signal_wps_event_fail(struct wpa_supplicant *wpa_s,
602*d4f2939cSRui Paulo 				     struct wps_event_fail *fail)
603*d4f2939cSRui Paulo {
604*d4f2939cSRui Paulo 
605*d4f2939cSRui Paulo 	DBusMessage *msg;
606*d4f2939cSRui Paulo 	DBusMessageIter iter, dict_iter;
607*d4f2939cSRui Paulo 	struct wpas_dbus_priv *iface;
608*d4f2939cSRui Paulo 	char *key = "fail";
609*d4f2939cSRui Paulo 
610*d4f2939cSRui Paulo 	iface = wpa_s->global->dbus;
611*d4f2939cSRui Paulo 
612*d4f2939cSRui Paulo 	/* Do nothing if the control interface is not turned on */
613*d4f2939cSRui Paulo 	if (iface == NULL)
614*d4f2939cSRui Paulo 		return;
615*d4f2939cSRui Paulo 
616*d4f2939cSRui Paulo 	msg = dbus_message_new_signal(wpa_s->dbus_new_path,
617*d4f2939cSRui Paulo 				      WPAS_DBUS_NEW_IFACE_WPS, "Event");
618*d4f2939cSRui Paulo 	if (msg == NULL)
619*d4f2939cSRui Paulo 		return;
620*d4f2939cSRui Paulo 
621*d4f2939cSRui Paulo 	dbus_message_iter_init_append(msg, &iter);
622*d4f2939cSRui Paulo 
623*d4f2939cSRui Paulo 	if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &key) ||
624*d4f2939cSRui Paulo 	    !wpa_dbus_dict_open_write(&iter, &dict_iter) ||
625*d4f2939cSRui Paulo 	    !wpa_dbus_dict_append_int32(&dict_iter, "msg", fail->msg) ||
626*d4f2939cSRui Paulo 	    !wpa_dbus_dict_close_write(&iter, &dict_iter))
627*d4f2939cSRui Paulo 		wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
628*d4f2939cSRui Paulo 	else
629*d4f2939cSRui Paulo 		dbus_connection_send(iface->con, msg, NULL);
630*d4f2939cSRui Paulo 
631*d4f2939cSRui Paulo 	dbus_message_unref(msg);
632*d4f2939cSRui Paulo }
633*d4f2939cSRui Paulo 
634*d4f2939cSRui Paulo 
635*d4f2939cSRui Paulo /**
636*d4f2939cSRui Paulo  * wpas_dbus_signal_wps_event_m2d - Signals M2D WPS event
637*d4f2939cSRui Paulo  * @wpa_s: %wpa_supplicant network interface data
638*d4f2939cSRui Paulo  *
639*d4f2939cSRui Paulo  * Sends Event dbus signal with name "m2d" and dictionary containing
640*d4f2939cSRui Paulo  * fields of wps_event_m2d structure.
641*d4f2939cSRui Paulo  */
642*d4f2939cSRui Paulo void wpas_dbus_signal_wps_event_m2d(struct wpa_supplicant *wpa_s,
643*d4f2939cSRui Paulo 				    struct wps_event_m2d *m2d)
644*d4f2939cSRui Paulo {
645*d4f2939cSRui Paulo 
646*d4f2939cSRui Paulo 	DBusMessage *msg;
647*d4f2939cSRui Paulo 	DBusMessageIter iter, dict_iter;
648*d4f2939cSRui Paulo 	struct wpas_dbus_priv *iface;
649*d4f2939cSRui Paulo 	char *key = "m2d";
650*d4f2939cSRui Paulo 
651*d4f2939cSRui Paulo 	iface = wpa_s->global->dbus;
652*d4f2939cSRui Paulo 
653*d4f2939cSRui Paulo 	/* Do nothing if the control interface is not turned on */
654*d4f2939cSRui Paulo 	if (iface == NULL)
655*d4f2939cSRui Paulo 		return;
656*d4f2939cSRui Paulo 
657*d4f2939cSRui Paulo 	msg = dbus_message_new_signal(wpa_s->dbus_new_path,
658*d4f2939cSRui Paulo 				      WPAS_DBUS_NEW_IFACE_WPS, "Event");
659*d4f2939cSRui Paulo 	if (msg == NULL)
660*d4f2939cSRui Paulo 		return;
661*d4f2939cSRui Paulo 
662*d4f2939cSRui Paulo 	dbus_message_iter_init_append(msg, &iter);
663*d4f2939cSRui Paulo 
664*d4f2939cSRui Paulo 	if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &key) ||
665*d4f2939cSRui Paulo 	    !wpa_dbus_dict_open_write(&iter, &dict_iter) ||
666*d4f2939cSRui Paulo 	    !wpa_dbus_dict_append_uint16(&dict_iter, "config_methods",
667*d4f2939cSRui Paulo 					 m2d->config_methods) ||
668*d4f2939cSRui Paulo 	    !wpa_dbus_dict_append_byte_array(&dict_iter, "manufacturer",
669*d4f2939cSRui Paulo 					     (const char *) m2d->manufacturer,
670*d4f2939cSRui Paulo 					     m2d->manufacturer_len) ||
671*d4f2939cSRui Paulo 	    !wpa_dbus_dict_append_byte_array(&dict_iter, "model_name",
672*d4f2939cSRui Paulo 					     (const char *) m2d->model_name,
673*d4f2939cSRui Paulo 					     m2d->model_name_len) ||
674*d4f2939cSRui Paulo 	    !wpa_dbus_dict_append_byte_array(&dict_iter, "model_number",
675*d4f2939cSRui Paulo 					     (const char *) m2d->model_number,
676*d4f2939cSRui Paulo 					     m2d->model_number_len) ||
677*d4f2939cSRui Paulo 	    !wpa_dbus_dict_append_byte_array(&dict_iter, "serial_number",
678*d4f2939cSRui Paulo 					     (const char *)
679*d4f2939cSRui Paulo 					     m2d->serial_number,
680*d4f2939cSRui Paulo 					     m2d->serial_number_len) ||
681*d4f2939cSRui Paulo 	    !wpa_dbus_dict_append_byte_array(&dict_iter, "dev_name",
682*d4f2939cSRui Paulo 					     (const char *) m2d->dev_name,
683*d4f2939cSRui Paulo 					     m2d->dev_name_len) ||
684*d4f2939cSRui Paulo 	    !wpa_dbus_dict_append_byte_array(&dict_iter, "primary_dev_type",
685*d4f2939cSRui Paulo 					     (const char *)
686*d4f2939cSRui Paulo 					     m2d->primary_dev_type, 8) ||
687*d4f2939cSRui Paulo 	    !wpa_dbus_dict_append_uint16(&dict_iter, "config_error",
688*d4f2939cSRui Paulo 					 m2d->config_error) ||
689*d4f2939cSRui Paulo 	    !wpa_dbus_dict_append_uint16(&dict_iter, "dev_password_id",
690*d4f2939cSRui Paulo 					 m2d->dev_password_id) ||
691*d4f2939cSRui Paulo 	    !wpa_dbus_dict_close_write(&iter, &dict_iter))
692*d4f2939cSRui Paulo 		wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
693*d4f2939cSRui Paulo 	else
694*d4f2939cSRui Paulo 		dbus_connection_send(iface->con, msg, NULL);
695*d4f2939cSRui Paulo 
696*d4f2939cSRui Paulo 	dbus_message_unref(msg);
697*d4f2939cSRui Paulo }
698*d4f2939cSRui Paulo 
699*d4f2939cSRui Paulo 
700*d4f2939cSRui Paulo /**
701*d4f2939cSRui Paulo  * wpas_dbus_signal_wps_cred - Signals new credentials
702*d4f2939cSRui Paulo  * @wpa_s: %wpa_supplicant network interface data
703*d4f2939cSRui Paulo  *
704*d4f2939cSRui Paulo  * Sends signal with credentials in directory argument
705*d4f2939cSRui Paulo  */
706*d4f2939cSRui Paulo void wpas_dbus_signal_wps_cred(struct wpa_supplicant *wpa_s,
707*d4f2939cSRui Paulo 			       const struct wps_credential *cred)
708*d4f2939cSRui Paulo {
709*d4f2939cSRui Paulo 	DBusMessage *msg;
710*d4f2939cSRui Paulo 	DBusMessageIter iter, dict_iter;
711*d4f2939cSRui Paulo 	struct wpas_dbus_priv *iface;
712*d4f2939cSRui Paulo 	char *auth_type[6]; /* we have six possible authorization types */
713*d4f2939cSRui Paulo 	int at_num = 0;
714*d4f2939cSRui Paulo 	char *encr_type[4]; /* we have four possible encryption types */
715*d4f2939cSRui Paulo 	int et_num = 0;
716*d4f2939cSRui Paulo 
717*d4f2939cSRui Paulo 	iface = wpa_s->global->dbus;
718*d4f2939cSRui Paulo 
719*d4f2939cSRui Paulo 	/* Do nothing if the control interface is not turned on */
720*d4f2939cSRui Paulo 	if (iface == NULL)
721*d4f2939cSRui Paulo 		return;
722*d4f2939cSRui Paulo 
723*d4f2939cSRui Paulo 	msg = dbus_message_new_signal(wpa_s->dbus_new_path,
724*d4f2939cSRui Paulo 				      WPAS_DBUS_NEW_IFACE_WPS,
725*d4f2939cSRui Paulo 				      "Credentials");
726*d4f2939cSRui Paulo 	if (msg == NULL)
727*d4f2939cSRui Paulo 		return;
728*d4f2939cSRui Paulo 
729*d4f2939cSRui Paulo 	dbus_message_iter_init_append(msg, &iter);
730*d4f2939cSRui Paulo 	if (!wpa_dbus_dict_open_write(&iter, &dict_iter))
731*d4f2939cSRui Paulo 		goto nomem;
732*d4f2939cSRui Paulo 
733*d4f2939cSRui Paulo 	if (cred->auth_type & WPS_AUTH_OPEN)
734*d4f2939cSRui Paulo 		auth_type[at_num++] = "open";
735*d4f2939cSRui Paulo 	if (cred->auth_type & WPS_AUTH_WPAPSK)
736*d4f2939cSRui Paulo 		auth_type[at_num++] = "wpa-psk";
737*d4f2939cSRui Paulo 	if (cred->auth_type & WPS_AUTH_SHARED)
738*d4f2939cSRui Paulo 		auth_type[at_num++] = "shared";
739*d4f2939cSRui Paulo 	if (cred->auth_type & WPS_AUTH_WPA)
740*d4f2939cSRui Paulo 		auth_type[at_num++] = "wpa-eap";
741*d4f2939cSRui Paulo 	if (cred->auth_type & WPS_AUTH_WPA2)
742*d4f2939cSRui Paulo 		auth_type[at_num++] = "wpa2-eap";
743*d4f2939cSRui Paulo 	if (cred->auth_type & WPS_AUTH_WPA2PSK)
744*d4f2939cSRui Paulo 		auth_type[at_num++] =
745*d4f2939cSRui Paulo 		"wpa2-psk";
746*d4f2939cSRui Paulo 
747*d4f2939cSRui Paulo 	if (cred->encr_type & WPS_ENCR_NONE)
748*d4f2939cSRui Paulo 		encr_type[et_num++] = "none";
749*d4f2939cSRui Paulo 	if (cred->encr_type & WPS_ENCR_WEP)
750*d4f2939cSRui Paulo 		encr_type[et_num++] = "wep";
751*d4f2939cSRui Paulo 	if (cred->encr_type & WPS_ENCR_TKIP)
752*d4f2939cSRui Paulo 		encr_type[et_num++] = "tkip";
753*d4f2939cSRui Paulo 	if (cred->encr_type & WPS_ENCR_AES)
754*d4f2939cSRui Paulo 		encr_type[et_num++] = "aes";
755*d4f2939cSRui Paulo 
756*d4f2939cSRui Paulo 	if (wpa_s->current_ssid) {
757*d4f2939cSRui Paulo 		if (!wpa_dbus_dict_append_byte_array(
758*d4f2939cSRui Paulo 			    &dict_iter, "BSSID",
759*d4f2939cSRui Paulo 			    (const char *) wpa_s->current_ssid->bssid,
760*d4f2939cSRui Paulo 			    ETH_ALEN))
761*d4f2939cSRui Paulo 			goto nomem;
762*d4f2939cSRui Paulo 	}
763*d4f2939cSRui Paulo 
764*d4f2939cSRui Paulo 	if (!wpa_dbus_dict_append_byte_array(&dict_iter, "SSID",
765*d4f2939cSRui Paulo 					     (const char *) cred->ssid,
766*d4f2939cSRui Paulo 					     cred->ssid_len) ||
767*d4f2939cSRui Paulo 	    !wpa_dbus_dict_append_string_array(&dict_iter, "AuthType",
768*d4f2939cSRui Paulo 					       (const char **) auth_type,
769*d4f2939cSRui Paulo 					       at_num) ||
770*d4f2939cSRui Paulo 	    !wpa_dbus_dict_append_string_array(&dict_iter, "EncrType",
771*d4f2939cSRui Paulo 					       (const char **) encr_type,
772*d4f2939cSRui Paulo 					       et_num) ||
773*d4f2939cSRui Paulo 	    !wpa_dbus_dict_append_byte_array(&dict_iter, "Key",
774*d4f2939cSRui Paulo 					     (const char *) cred->key,
775*d4f2939cSRui Paulo 					     cred->key_len) ||
776*d4f2939cSRui Paulo 	    !wpa_dbus_dict_append_uint32(&dict_iter, "KeyIndex",
777*d4f2939cSRui Paulo 					 cred->key_idx) ||
778*d4f2939cSRui Paulo 	    !wpa_dbus_dict_close_write(&iter, &dict_iter))
779*d4f2939cSRui Paulo 		goto nomem;
780*d4f2939cSRui Paulo 
781*d4f2939cSRui Paulo 	dbus_connection_send(iface->con, msg, NULL);
782*d4f2939cSRui Paulo 
783*d4f2939cSRui Paulo nomem:
784*d4f2939cSRui Paulo 	dbus_message_unref(msg);
785*d4f2939cSRui Paulo }
786*d4f2939cSRui Paulo 
787*d4f2939cSRui Paulo #endif /* CONFIG_WPS */
788*d4f2939cSRui Paulo 
789*d4f2939cSRui Paulo void wpas_dbus_signal_certification(struct wpa_supplicant *wpa_s,
790*d4f2939cSRui Paulo 				    int depth, const char *subject,
791*d4f2939cSRui Paulo 				    const char *cert_hash,
792*d4f2939cSRui Paulo 				    const struct wpabuf *cert)
793*d4f2939cSRui Paulo {
794*d4f2939cSRui Paulo 	struct wpas_dbus_priv *iface;
795*d4f2939cSRui Paulo 	DBusMessage *msg;
796*d4f2939cSRui Paulo 	DBusMessageIter iter, dict_iter;
797*d4f2939cSRui Paulo 
798*d4f2939cSRui Paulo 	iface = wpa_s->global->dbus;
799*d4f2939cSRui Paulo 
800*d4f2939cSRui Paulo 	/* Do nothing if the control interface is not turned on */
801*d4f2939cSRui Paulo 	if (iface == NULL)
802*d4f2939cSRui Paulo 		return;
803*d4f2939cSRui Paulo 
804*d4f2939cSRui Paulo 	msg = dbus_message_new_signal(wpa_s->dbus_new_path,
805*d4f2939cSRui Paulo 				      WPAS_DBUS_NEW_IFACE_INTERFACE,
806*d4f2939cSRui Paulo 				      "Certification");
807*d4f2939cSRui Paulo 	if (msg == NULL)
808*d4f2939cSRui Paulo 		return;
809*d4f2939cSRui Paulo 
810*d4f2939cSRui Paulo 	dbus_message_iter_init_append(msg, &iter);
811*d4f2939cSRui Paulo 	if (!wpa_dbus_dict_open_write(&iter, &dict_iter))
812*d4f2939cSRui Paulo 		goto nomem;
813*d4f2939cSRui Paulo 
814*d4f2939cSRui Paulo 	if (!wpa_dbus_dict_append_uint32(&dict_iter, "depth", depth) ||
815*d4f2939cSRui Paulo 	    !wpa_dbus_dict_append_string(&dict_iter, "subject", subject))
816*d4f2939cSRui Paulo 		goto nomem;
817*d4f2939cSRui Paulo 
818*d4f2939cSRui Paulo 	if (cert_hash &&
819*d4f2939cSRui Paulo 	    !wpa_dbus_dict_append_string(&dict_iter, "cert_hash", cert_hash))
820*d4f2939cSRui Paulo 		goto nomem;
821*d4f2939cSRui Paulo 
822*d4f2939cSRui Paulo 	if (cert &&
823*d4f2939cSRui Paulo 	    !wpa_dbus_dict_append_byte_array(&dict_iter, "cert",
824*d4f2939cSRui Paulo 					     wpabuf_head(cert),
825*d4f2939cSRui Paulo 					     wpabuf_len(cert)))
826*d4f2939cSRui Paulo 		goto nomem;
827*d4f2939cSRui Paulo 
828*d4f2939cSRui Paulo 	if (!wpa_dbus_dict_close_write(&iter, &dict_iter))
829*d4f2939cSRui Paulo 		goto nomem;
830*d4f2939cSRui Paulo 
831*d4f2939cSRui Paulo 	dbus_connection_send(iface->con, msg, NULL);
832*d4f2939cSRui Paulo 
833*d4f2939cSRui Paulo nomem:
834*d4f2939cSRui Paulo 	dbus_message_unref(msg);
835*d4f2939cSRui Paulo }
836*d4f2939cSRui Paulo 
837*d4f2939cSRui Paulo 
838*d4f2939cSRui Paulo void wpas_dbus_signal_eap_status(struct wpa_supplicant *wpa_s,
839*d4f2939cSRui Paulo 				 const char *status, const char *parameter)
840*d4f2939cSRui Paulo {
841*d4f2939cSRui Paulo 	struct wpas_dbus_priv *iface;
842*d4f2939cSRui Paulo 	DBusMessage *msg;
843*d4f2939cSRui Paulo 	DBusMessageIter iter;
844*d4f2939cSRui Paulo 
845*d4f2939cSRui Paulo 	iface = wpa_s->global->dbus;
846*d4f2939cSRui Paulo 
847*d4f2939cSRui Paulo 	/* Do nothing if the control interface is not turned on */
848*d4f2939cSRui Paulo 	if (iface == NULL)
849*d4f2939cSRui Paulo 		return;
850*d4f2939cSRui Paulo 
851*d4f2939cSRui Paulo 	msg = dbus_message_new_signal(wpa_s->dbus_new_path,
852*d4f2939cSRui Paulo 				      WPAS_DBUS_NEW_IFACE_INTERFACE,
853*d4f2939cSRui Paulo 				      "EAP");
854*d4f2939cSRui Paulo 	if (msg == NULL)
855*d4f2939cSRui Paulo 		return;
856*d4f2939cSRui Paulo 
857*d4f2939cSRui Paulo 	dbus_message_iter_init_append(msg, &iter);
858*d4f2939cSRui Paulo 
859*d4f2939cSRui Paulo 	if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &status)
860*d4f2939cSRui Paulo 	    ||
861*d4f2939cSRui Paulo 	    !dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING,
862*d4f2939cSRui Paulo 					    &parameter))
863*d4f2939cSRui Paulo 		goto nomem;
864*d4f2939cSRui Paulo 
865*d4f2939cSRui Paulo 	dbus_connection_send(iface->con, msg, NULL);
866*d4f2939cSRui Paulo 
867*d4f2939cSRui Paulo nomem:
868*d4f2939cSRui Paulo 	dbus_message_unref(msg);
869*d4f2939cSRui Paulo }
870*d4f2939cSRui Paulo 
871*d4f2939cSRui Paulo 
872*d4f2939cSRui Paulo #ifdef CONFIG_P2P
873*d4f2939cSRui Paulo 
874*d4f2939cSRui Paulo /**
875*d4f2939cSRui Paulo  * wpas_dbus_signal_p2p_group_removed - Signals P2P group was removed
876*d4f2939cSRui Paulo  * @wpa_s: %wpa_supplicant network interface data
877*d4f2939cSRui Paulo  * @role: role of this device (client or GO)
878*d4f2939cSRui Paulo  * Sends signal with i/f name and role as string arguments
879*d4f2939cSRui Paulo  */
880*d4f2939cSRui Paulo void wpas_dbus_signal_p2p_group_removed(struct wpa_supplicant *wpa_s,
881*d4f2939cSRui Paulo 					const char *role)
882*d4f2939cSRui Paulo {
883*d4f2939cSRui Paulo 
884*d4f2939cSRui Paulo 	DBusMessage *msg;
885*d4f2939cSRui Paulo 	DBusMessageIter iter;
886*d4f2939cSRui Paulo 	struct wpas_dbus_priv *iface = wpa_s->global->dbus;
887*d4f2939cSRui Paulo 	char *ifname = wpa_s->ifname;
888*d4f2939cSRui Paulo 
889*d4f2939cSRui Paulo 	/* Do nothing if the control interface is not turned on */
890*d4f2939cSRui Paulo 	if (iface == NULL)
891*d4f2939cSRui Paulo 		return;
892*d4f2939cSRui Paulo 
893*d4f2939cSRui Paulo 	msg = dbus_message_new_signal(wpa_s->dbus_new_path,
894*d4f2939cSRui Paulo 				      WPAS_DBUS_NEW_IFACE_P2PDEVICE,
895*d4f2939cSRui Paulo 				      "GroupFinished");
896*d4f2939cSRui Paulo 	if (msg == NULL)
897*d4f2939cSRui Paulo 		return;
898*d4f2939cSRui Paulo 
899*d4f2939cSRui Paulo 	dbus_message_iter_init_append(msg, &iter);
900*d4f2939cSRui Paulo 
901*d4f2939cSRui Paulo 	if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &ifname)) {
902*d4f2939cSRui Paulo 		wpa_printf(MSG_ERROR, "dbus: Failed to construct GroupFinished"
903*d4f2939cSRui Paulo 				      "signal -not enough memory for ifname ");
904*d4f2939cSRui Paulo 		goto err;
905*d4f2939cSRui Paulo 	}
906*d4f2939cSRui Paulo 
907*d4f2939cSRui Paulo 	if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &role))
908*d4f2939cSRui Paulo 		wpa_printf(MSG_ERROR, "dbus: Failed to construct GroupFinished"
909*d4f2939cSRui Paulo 				      "signal -not enough memory for role ");
910*d4f2939cSRui Paulo 	else
911*d4f2939cSRui Paulo 		dbus_connection_send(iface->con, msg, NULL);
912*d4f2939cSRui Paulo 
913*d4f2939cSRui Paulo err:
914*d4f2939cSRui Paulo 	dbus_message_unref(msg);
915*d4f2939cSRui Paulo }
916*d4f2939cSRui Paulo 
917*d4f2939cSRui Paulo 
918*d4f2939cSRui Paulo /**
919*d4f2939cSRui Paulo  * wpas_dbus_signal_p2p_provision_discovery - Signals various PD events
920*d4f2939cSRui Paulo  *
921*d4f2939cSRui Paulo  * @dev_addr - who sent the request or responded to our request.
922*d4f2939cSRui Paulo  * @request - Will be 1 if request, 0 for response.
923*d4f2939cSRui Paulo  * @status - valid only in case of response
924*d4f2939cSRui Paulo  * @config_methods - wps config methods
925*d4f2939cSRui Paulo  * @generated_pin - pin to be displayed in case of WPS_CONFIG_DISPLAY method
926*d4f2939cSRui Paulo  *
927*d4f2939cSRui Paulo  * Sends following provision discovery related events:
928*d4f2939cSRui Paulo  *	ProvisionDiscoveryRequestDisplayPin
929*d4f2939cSRui Paulo  *	ProvisionDiscoveryResponseDisplayPin
930*d4f2939cSRui Paulo  *	ProvisionDiscoveryRequestEnterPin
931*d4f2939cSRui Paulo  *	ProvisionDiscoveryResponseEnterPin
932*d4f2939cSRui Paulo  *	ProvisionDiscoveryPBCRequest
933*d4f2939cSRui Paulo  *	ProvisionDiscoveryPBCResponse
934*d4f2939cSRui Paulo  *
935*d4f2939cSRui Paulo  *	TODO::
936*d4f2939cSRui Paulo  *	ProvisionDiscoveryFailure (timeout case)
937*d4f2939cSRui Paulo  */
938*d4f2939cSRui Paulo void wpas_dbus_signal_p2p_provision_discovery(struct wpa_supplicant *wpa_s,
939*d4f2939cSRui Paulo 					      const u8 *dev_addr, int request,
940*d4f2939cSRui Paulo 					      enum p2p_prov_disc_status status,
941*d4f2939cSRui Paulo 					      u16 config_methods,
942*d4f2939cSRui Paulo 					      unsigned int generated_pin)
943*d4f2939cSRui Paulo {
944*d4f2939cSRui Paulo 	DBusMessage *msg;
945*d4f2939cSRui Paulo 	DBusMessageIter iter;
946*d4f2939cSRui Paulo 	struct wpas_dbus_priv *iface;
947*d4f2939cSRui Paulo 	char *_signal;
948*d4f2939cSRui Paulo 	int add_pin = 0;
949*d4f2939cSRui Paulo 	char peer_obj_path[WPAS_DBUS_OBJECT_PATH_MAX], *path;
950*d4f2939cSRui Paulo 	int error_ret = 1;
951*d4f2939cSRui Paulo 	char pin[9], *p_pin = NULL;
952*d4f2939cSRui Paulo 
953*d4f2939cSRui Paulo 	iface = wpa_s->global->dbus;
954*d4f2939cSRui Paulo 
955*d4f2939cSRui Paulo 	/* Do nothing if the control interface is not turned on */
956*d4f2939cSRui Paulo 	if (iface == NULL)
957*d4f2939cSRui Paulo 		return;
958*d4f2939cSRui Paulo 
959*d4f2939cSRui Paulo 	if (request || !status) {
960*d4f2939cSRui Paulo 		if (config_methods & WPS_CONFIG_DISPLAY)
961*d4f2939cSRui Paulo 			_signal = request ?
962*d4f2939cSRui Paulo 				 "ProvisionDiscoveryRequestDisplayPin" :
963*d4f2939cSRui Paulo 				 "ProvisionDiscoveryResponseEnterPin";
964*d4f2939cSRui Paulo 		else if (config_methods & WPS_CONFIG_KEYPAD)
965*d4f2939cSRui Paulo 			_signal = request ?
966*d4f2939cSRui Paulo 				 "ProvisionDiscoveryRequestEnterPin" :
967*d4f2939cSRui Paulo 				 "ProvisionDiscoveryResponseDisplayPin";
968*d4f2939cSRui Paulo 		else if (config_methods & WPS_CONFIG_PUSHBUTTON)
969*d4f2939cSRui Paulo 			_signal = request ? "ProvisionDiscoveryPBCRequest" :
970*d4f2939cSRui Paulo 				   "ProvisionDiscoveryPBCResponse";
971*d4f2939cSRui Paulo 		else
972*d4f2939cSRui Paulo 			return; /* Unknown or un-supported method */
973*d4f2939cSRui Paulo 	} else if (!request && status)
974*d4f2939cSRui Paulo 		/* Explicit check for failure response */
975*d4f2939cSRui Paulo 		_signal = "ProvisionDiscoveryFailure";
976*d4f2939cSRui Paulo 
977*d4f2939cSRui Paulo 	add_pin = ((request && (config_methods & WPS_CONFIG_DISPLAY)) ||
978*d4f2939cSRui Paulo 		   (!request && !status &&
979*d4f2939cSRui Paulo 			(config_methods & WPS_CONFIG_KEYPAD)));
980*d4f2939cSRui Paulo 
981*d4f2939cSRui Paulo 	if (add_pin) {
982*d4f2939cSRui Paulo 		os_snprintf(pin, sizeof(pin), "%08d", generated_pin);
983*d4f2939cSRui Paulo 		p_pin = pin;
984*d4f2939cSRui Paulo 	}
985*d4f2939cSRui Paulo 
986*d4f2939cSRui Paulo 	msg = dbus_message_new_signal(wpa_s->dbus_new_path,
987*d4f2939cSRui Paulo 				      WPAS_DBUS_NEW_IFACE_P2PDEVICE, _signal);
988*d4f2939cSRui Paulo 	if (msg == NULL)
989*d4f2939cSRui Paulo 		return;
990*d4f2939cSRui Paulo 
991*d4f2939cSRui Paulo 	/* Check if this is a known peer */
992*d4f2939cSRui Paulo 	if (!p2p_peer_known(wpa_s->global->p2p, dev_addr))
993*d4f2939cSRui Paulo 		goto error;
994*d4f2939cSRui Paulo 
995*d4f2939cSRui Paulo 	os_snprintf(peer_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
996*d4f2939cSRui Paulo 			"%s/" WPAS_DBUS_NEW_P2P_PEERS_PART "/"
997*d4f2939cSRui Paulo 			COMPACT_MACSTR,
998*d4f2939cSRui Paulo 			wpa_s->dbus_new_path, MAC2STR(dev_addr));
999*d4f2939cSRui Paulo 
1000*d4f2939cSRui Paulo 	path = peer_obj_path;
1001*d4f2939cSRui Paulo 
1002*d4f2939cSRui Paulo 	dbus_message_iter_init_append(msg, &iter);
1003*d4f2939cSRui Paulo 
1004*d4f2939cSRui Paulo 	if (!dbus_message_iter_append_basic(&iter,
1005*d4f2939cSRui Paulo 					    DBUS_TYPE_OBJECT_PATH,
1006*d4f2939cSRui Paulo 					    &path))
1007*d4f2939cSRui Paulo 			goto error;
1008*d4f2939cSRui Paulo 
1009*d4f2939cSRui Paulo 	if (!request && status)
1010*d4f2939cSRui Paulo 		/* Attach status to ProvisionDiscoveryFailure */
1011*d4f2939cSRui Paulo 		error_ret = !dbus_message_iter_append_basic(&iter,
1012*d4f2939cSRui Paulo 						    DBUS_TYPE_INT32,
1013*d4f2939cSRui Paulo 						    &status);
1014*d4f2939cSRui Paulo 	else
1015*d4f2939cSRui Paulo 		error_ret = (add_pin &&
1016*d4f2939cSRui Paulo 				 !dbus_message_iter_append_basic(&iter,
1017*d4f2939cSRui Paulo 							DBUS_TYPE_STRING,
1018*d4f2939cSRui Paulo 							&p_pin));
1019*d4f2939cSRui Paulo 
1020*d4f2939cSRui Paulo error:
1021*d4f2939cSRui Paulo 	if (!error_ret)
1022*d4f2939cSRui Paulo 		dbus_connection_send(iface->con, msg, NULL);
1023*d4f2939cSRui Paulo 	else
1024*d4f2939cSRui Paulo 		wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
1025*d4f2939cSRui Paulo 
1026*d4f2939cSRui Paulo 	dbus_message_unref(msg);
1027*d4f2939cSRui Paulo }
1028*d4f2939cSRui Paulo 
1029*d4f2939cSRui Paulo 
1030*d4f2939cSRui Paulo void wpas_dbus_signal_p2p_go_neg_req(struct wpa_supplicant *wpa_s,
1031*d4f2939cSRui Paulo 				     const u8 *src, u16 dev_passwd_id)
1032*d4f2939cSRui Paulo {
1033*d4f2939cSRui Paulo 	DBusMessage *msg;
1034*d4f2939cSRui Paulo 	DBusMessageIter iter;
1035*d4f2939cSRui Paulo 	struct wpas_dbus_priv *iface;
1036*d4f2939cSRui Paulo 	char peer_obj_path[WPAS_DBUS_OBJECT_PATH_MAX], *path;
1037*d4f2939cSRui Paulo 
1038*d4f2939cSRui Paulo 	iface = wpa_s->global->dbus;
1039*d4f2939cSRui Paulo 
1040*d4f2939cSRui Paulo 	/* Do nothing if the control interface is not turned on */
1041*d4f2939cSRui Paulo 	if (iface == NULL)
1042*d4f2939cSRui Paulo 		return;
1043*d4f2939cSRui Paulo 
1044*d4f2939cSRui Paulo 	os_snprintf(peer_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
1045*d4f2939cSRui Paulo 		    "%s/" WPAS_DBUS_NEW_P2P_PEERS_PART "/" COMPACT_MACSTR,
1046*d4f2939cSRui Paulo 		    wpa_s->dbus_new_path, MAC2STR(src));
1047*d4f2939cSRui Paulo 	path = peer_obj_path;
1048*d4f2939cSRui Paulo 
1049*d4f2939cSRui Paulo 	msg = dbus_message_new_signal(wpa_s->dbus_new_path,
1050*d4f2939cSRui Paulo 				      WPAS_DBUS_NEW_IFACE_P2PDEVICE,
1051*d4f2939cSRui Paulo 				      "GONegotiationRequest");
1052*d4f2939cSRui Paulo 	if (msg == NULL)
1053*d4f2939cSRui Paulo 		return;
1054*d4f2939cSRui Paulo 
1055*d4f2939cSRui Paulo 	dbus_message_iter_init_append(msg, &iter);
1056*d4f2939cSRui Paulo 
1057*d4f2939cSRui Paulo 	if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_OBJECT_PATH,
1058*d4f2939cSRui Paulo 					    &path) ||
1059*d4f2939cSRui Paulo 	    !dbus_message_iter_append_basic(&iter, DBUS_TYPE_UINT16,
1060*d4f2939cSRui Paulo 					    &dev_passwd_id))
1061*d4f2939cSRui Paulo 		wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
1062*d4f2939cSRui Paulo 	else
1063*d4f2939cSRui Paulo 		dbus_connection_send(iface->con, msg, NULL);
1064*d4f2939cSRui Paulo 
1065*d4f2939cSRui Paulo 	dbus_message_unref(msg);
1066*d4f2939cSRui Paulo }
1067*d4f2939cSRui Paulo 
1068*d4f2939cSRui Paulo 
1069*d4f2939cSRui Paulo static int wpas_dbus_get_group_obj_path(struct wpa_supplicant *wpa_s,
1070*d4f2939cSRui Paulo 					const struct wpa_ssid *ssid,
1071*d4f2939cSRui Paulo 					char *group_obj_path)
1072*d4f2939cSRui Paulo {
1073*d4f2939cSRui Paulo 	char group_name[3];
1074*d4f2939cSRui Paulo 
1075*d4f2939cSRui Paulo 	if (os_memcmp(ssid->ssid, P2P_WILDCARD_SSID, P2P_WILDCARD_SSID_LEN))
1076*d4f2939cSRui Paulo 		return -1;
1077*d4f2939cSRui Paulo 
1078*d4f2939cSRui Paulo 	os_memcpy(group_name, ssid->ssid + P2P_WILDCARD_SSID_LEN, 2);
1079*d4f2939cSRui Paulo 	group_name[2] = '\0';
1080*d4f2939cSRui Paulo 
1081*d4f2939cSRui Paulo 	os_snprintf(group_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
1082*d4f2939cSRui Paulo 		    "%s/" WPAS_DBUS_NEW_P2P_GROUPS_PART "/%s",
1083*d4f2939cSRui Paulo 		    wpa_s->dbus_new_path, group_name);
1084*d4f2939cSRui Paulo 
1085*d4f2939cSRui Paulo 	return 0;
1086*d4f2939cSRui Paulo }
1087*d4f2939cSRui Paulo 
1088*d4f2939cSRui Paulo 
1089*d4f2939cSRui Paulo /**
1090*d4f2939cSRui Paulo  * wpas_dbus_signal_p2p_group_started - Signals P2P group has
1091*d4f2939cSRui Paulo  * started. Emitted when a group is successfully started
1092*d4f2939cSRui Paulo  * irrespective of the role (client/GO) of the current device
1093*d4f2939cSRui Paulo  *
1094*d4f2939cSRui Paulo  * @wpa_s: %wpa_supplicant network interface data
1095*d4f2939cSRui Paulo  * @ssid: SSID object
1096*d4f2939cSRui Paulo  * @client: this device is P2P client
1097*d4f2939cSRui Paulo  * @network_id: network id of the group started, use instead of ssid->id
1098*d4f2939cSRui Paulo  *	to account for persistent groups
1099*d4f2939cSRui Paulo  */
1100*d4f2939cSRui Paulo void wpas_dbus_signal_p2p_group_started(struct wpa_supplicant *wpa_s,
1101*d4f2939cSRui Paulo 					const struct wpa_ssid *ssid,
1102*d4f2939cSRui Paulo 					int client, int network_id)
1103*d4f2939cSRui Paulo {
1104*d4f2939cSRui Paulo 	DBusMessage *msg;
1105*d4f2939cSRui Paulo 	DBusMessageIter iter, dict_iter;
1106*d4f2939cSRui Paulo 	struct wpas_dbus_priv *iface;
1107*d4f2939cSRui Paulo 	char group_obj_path[WPAS_DBUS_OBJECT_PATH_MAX];
1108*d4f2939cSRui Paulo 
1109*d4f2939cSRui Paulo 	iface = wpa_s->parent->global->dbus;
1110*d4f2939cSRui Paulo 
1111*d4f2939cSRui Paulo 	/* Do nothing if the control interface is not turned on */
1112*d4f2939cSRui Paulo 	if (iface == NULL)
1113*d4f2939cSRui Paulo 		return;
1114*d4f2939cSRui Paulo 
1115*d4f2939cSRui Paulo 	if (wpas_dbus_get_group_obj_path(wpa_s, ssid, group_obj_path) < 0)
1116*d4f2939cSRui Paulo 		return;
1117*d4f2939cSRui Paulo 
1118*d4f2939cSRui Paulo 	/* New interface has been created for this group */
1119*d4f2939cSRui Paulo 	msg = dbus_message_new_signal(wpa_s->parent->dbus_new_path,
1120*d4f2939cSRui Paulo 				      WPAS_DBUS_NEW_IFACE_P2PDEVICE,
1121*d4f2939cSRui Paulo 				      "GroupStarted");
1122*d4f2939cSRui Paulo 
1123*d4f2939cSRui Paulo 	if (msg == NULL)
1124*d4f2939cSRui Paulo 		return;
1125*d4f2939cSRui Paulo 
1126*d4f2939cSRui Paulo 	dbus_message_iter_init_append(msg, &iter);
1127*d4f2939cSRui Paulo 	if (!wpa_dbus_dict_open_write(&iter, &dict_iter))
1128*d4f2939cSRui Paulo 		goto nomem;
1129*d4f2939cSRui Paulo 
1130*d4f2939cSRui Paulo 	/*
1131*d4f2939cSRui Paulo 	 * In case the device supports creating a separate interface the
1132*d4f2939cSRui Paulo 	 * DBus client will need to know the object path for the interface
1133*d4f2939cSRui Paulo 	 * object this group was created on, so include it here.
1134*d4f2939cSRui Paulo 	 */
1135*d4f2939cSRui Paulo 	if (!wpa_dbus_dict_append_object_path(&dict_iter,
1136*d4f2939cSRui Paulo 					"interface_object",
1137*d4f2939cSRui Paulo 					wpa_s->dbus_new_path))
1138*d4f2939cSRui Paulo 		goto nomem;
1139*d4f2939cSRui Paulo 
1140*d4f2939cSRui Paulo 	if (!wpa_dbus_dict_append_string(&dict_iter, "role",
1141*d4f2939cSRui Paulo 					 client ? "client" : "GO"))
1142*d4f2939cSRui Paulo 		goto nomem;
1143*d4f2939cSRui Paulo 
1144*d4f2939cSRui Paulo 	if (!wpa_dbus_dict_append_object_path(&dict_iter, "group_object",
1145*d4f2939cSRui Paulo 					     group_obj_path) ||
1146*d4f2939cSRui Paulo 	   !wpa_dbus_dict_close_write(&iter, &dict_iter))
1147*d4f2939cSRui Paulo 		goto nomem;
1148*d4f2939cSRui Paulo 
1149*d4f2939cSRui Paulo 	dbus_connection_send(iface->con, msg, NULL);
1150*d4f2939cSRui Paulo 
1151*d4f2939cSRui Paulo nomem:
1152*d4f2939cSRui Paulo 	dbus_message_unref(msg);
1153*d4f2939cSRui Paulo }
1154*d4f2939cSRui Paulo 
1155*d4f2939cSRui Paulo 
1156*d4f2939cSRui Paulo /**
1157*d4f2939cSRui Paulo  *
1158*d4f2939cSRui Paulo  * Method to emit GONeogtiation Success or Failure signals based
1159*d4f2939cSRui Paulo  * on status.
1160*d4f2939cSRui Paulo  * @status: Status of the GO neg request. 0 for success, other for errors.
1161*d4f2939cSRui Paulo  */
1162*d4f2939cSRui Paulo void wpas_dbus_signal_p2p_go_neg_resp(struct wpa_supplicant *wpa_s,
1163*d4f2939cSRui Paulo 				      struct p2p_go_neg_results *res)
1164*d4f2939cSRui Paulo {
1165*d4f2939cSRui Paulo 	DBusMessage *msg;
1166*d4f2939cSRui Paulo 	DBusMessageIter iter, dict_iter;
1167*d4f2939cSRui Paulo 	DBusMessageIter iter_dict_entry, iter_dict_val, iter_dict_array;
1168*d4f2939cSRui Paulo 	struct wpas_dbus_priv *iface;
1169*d4f2939cSRui Paulo 	char peer_obj_path[WPAS_DBUS_OBJECT_PATH_MAX], *path;
1170*d4f2939cSRui Paulo 	dbus_int32_t freqs[P2P_MAX_CHANNELS];
1171*d4f2939cSRui Paulo 	dbus_int32_t *f_array = freqs;
1172*d4f2939cSRui Paulo 
1173*d4f2939cSRui Paulo 
1174*d4f2939cSRui Paulo 	iface = wpa_s->global->dbus;
1175*d4f2939cSRui Paulo 
1176*d4f2939cSRui Paulo 	os_memset(freqs, 0, sizeof(freqs));
1177*d4f2939cSRui Paulo 	/* Do nothing if the control interface is not turned on */
1178*d4f2939cSRui Paulo 	if (iface == NULL)
1179*d4f2939cSRui Paulo 		return;
1180*d4f2939cSRui Paulo 
1181*d4f2939cSRui Paulo 	os_snprintf(peer_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
1182*d4f2939cSRui Paulo 		    "%s/" WPAS_DBUS_NEW_P2P_PEERS_PART "/" COMPACT_MACSTR,
1183*d4f2939cSRui Paulo 		    wpa_s->dbus_new_path, MAC2STR(res->peer_device_addr));
1184*d4f2939cSRui Paulo 	path = peer_obj_path;
1185*d4f2939cSRui Paulo 
1186*d4f2939cSRui Paulo 	msg = dbus_message_new_signal(wpa_s->dbus_new_path,
1187*d4f2939cSRui Paulo 				      WPAS_DBUS_NEW_IFACE_P2PDEVICE,
1188*d4f2939cSRui Paulo 				      res->status ? "GONegotiationFailure" :
1189*d4f2939cSRui Paulo 						    "GONegotiationSuccess");
1190*d4f2939cSRui Paulo 	if (msg == NULL)
1191*d4f2939cSRui Paulo 		return;
1192*d4f2939cSRui Paulo 
1193*d4f2939cSRui Paulo 	dbus_message_iter_init_append(msg, &iter);
1194*d4f2939cSRui Paulo 	if (!wpa_dbus_dict_open_write(&iter, &dict_iter))
1195*d4f2939cSRui Paulo 		goto err;
1196*d4f2939cSRui Paulo 	if (!wpa_dbus_dict_append_object_path(&dict_iter, "peer_object",
1197*d4f2939cSRui Paulo 					      path) ||
1198*d4f2939cSRui Paulo 	    !wpa_dbus_dict_append_int32(&dict_iter, "status", res->status))
1199*d4f2939cSRui Paulo 		goto err;
1200*d4f2939cSRui Paulo 
1201*d4f2939cSRui Paulo 	if (!res->status) {
1202*d4f2939cSRui Paulo 		int i = 0;
1203*d4f2939cSRui Paulo 		int freq_list_num = 0;
1204*d4f2939cSRui Paulo 
1205*d4f2939cSRui Paulo 		if (res->role_go) {
1206*d4f2939cSRui Paulo 			if (!wpa_dbus_dict_append_byte_array(
1207*d4f2939cSRui Paulo 				    &dict_iter, "passphrase",
1208*d4f2939cSRui Paulo 				    (const char *) res->passphrase,
1209*d4f2939cSRui Paulo 				    sizeof(res->passphrase)))
1210*d4f2939cSRui Paulo 				goto err;
1211*d4f2939cSRui Paulo 		}
1212*d4f2939cSRui Paulo 
1213*d4f2939cSRui Paulo 		if (!wpa_dbus_dict_append_string(&dict_iter, "role_go",
1214*d4f2939cSRui Paulo 						 res->role_go ? "GO" :
1215*d4f2939cSRui Paulo 						 "client") ||
1216*d4f2939cSRui Paulo 		    !wpa_dbus_dict_append_int32(&dict_iter, "frequency",
1217*d4f2939cSRui Paulo 						res->freq) ||
1218*d4f2939cSRui Paulo 		    !wpa_dbus_dict_append_byte_array(&dict_iter, "ssid",
1219*d4f2939cSRui Paulo 						     (const char *) res->ssid,
1220*d4f2939cSRui Paulo 						     res->ssid_len) ||
1221*d4f2939cSRui Paulo 		    !wpa_dbus_dict_append_byte_array(&dict_iter,
1222*d4f2939cSRui Paulo 						     "peer_device_addr",
1223*d4f2939cSRui Paulo 						     (const char *)
1224*d4f2939cSRui Paulo 						     res->peer_device_addr,
1225*d4f2939cSRui Paulo 						     ETH_ALEN) ||
1226*d4f2939cSRui Paulo 		    !wpa_dbus_dict_append_byte_array(&dict_iter,
1227*d4f2939cSRui Paulo 						     "peer_interface_addr",
1228*d4f2939cSRui Paulo 						     (const char *)
1229*d4f2939cSRui Paulo 						     res->peer_interface_addr,
1230*d4f2939cSRui Paulo 						     ETH_ALEN) ||
1231*d4f2939cSRui Paulo 		    !wpa_dbus_dict_append_string(&dict_iter, "wps_method",
1232*d4f2939cSRui Paulo 						 p2p_wps_method_text(
1233*d4f2939cSRui Paulo 							 res->wps_method)))
1234*d4f2939cSRui Paulo 			goto err;
1235*d4f2939cSRui Paulo 
1236*d4f2939cSRui Paulo 		for (i = 0; i < P2P_MAX_CHANNELS; i++) {
1237*d4f2939cSRui Paulo 			if (res->freq_list[i]) {
1238*d4f2939cSRui Paulo 				freqs[i] = res->freq_list[i];
1239*d4f2939cSRui Paulo 				freq_list_num++;
1240*d4f2939cSRui Paulo 			}
1241*d4f2939cSRui Paulo 		}
1242*d4f2939cSRui Paulo 
1243*d4f2939cSRui Paulo 		if (!wpa_dbus_dict_begin_array(&dict_iter,
1244*d4f2939cSRui Paulo 					       "frequency_list",
1245*d4f2939cSRui Paulo 					       DBUS_TYPE_INT32_AS_STRING,
1246*d4f2939cSRui Paulo 					       &iter_dict_entry,
1247*d4f2939cSRui Paulo 					       &iter_dict_val,
1248*d4f2939cSRui Paulo 					       &iter_dict_array))
1249*d4f2939cSRui Paulo 			goto err;
1250*d4f2939cSRui Paulo 
1251*d4f2939cSRui Paulo 		if (!dbus_message_iter_append_fixed_array(&iter_dict_array,
1252*d4f2939cSRui Paulo 							  DBUS_TYPE_INT32,
1253*d4f2939cSRui Paulo 							  &f_array,
1254*d4f2939cSRui Paulo 							  freq_list_num))
1255*d4f2939cSRui Paulo 			goto err;
1256*d4f2939cSRui Paulo 
1257*d4f2939cSRui Paulo 		if (!wpa_dbus_dict_end_array(&dict_iter,
1258*d4f2939cSRui Paulo 					     &iter_dict_entry,
1259*d4f2939cSRui Paulo 					     &iter_dict_val,
1260*d4f2939cSRui Paulo 					     &iter_dict_array))
1261*d4f2939cSRui Paulo 			goto err;
1262*d4f2939cSRui Paulo 
1263*d4f2939cSRui Paulo 		if (!wpa_dbus_dict_append_int32(&dict_iter, "persistent_group",
1264*d4f2939cSRui Paulo 						res->persistent_group) ||
1265*d4f2939cSRui Paulo 		    !wpa_dbus_dict_append_uint32(&dict_iter,
1266*d4f2939cSRui Paulo 						 "peer_config_timeout",
1267*d4f2939cSRui Paulo 						 res->peer_config_timeout))
1268*d4f2939cSRui Paulo 			goto err;
1269*d4f2939cSRui Paulo 	}
1270*d4f2939cSRui Paulo 
1271*d4f2939cSRui Paulo 	if (!wpa_dbus_dict_close_write(&iter, &dict_iter))
1272*d4f2939cSRui Paulo 		goto err;
1273*d4f2939cSRui Paulo 
1274*d4f2939cSRui Paulo 	dbus_connection_send(iface->con, msg, NULL);
1275*d4f2939cSRui Paulo err:
1276*d4f2939cSRui Paulo 	dbus_message_unref(msg);
1277*d4f2939cSRui Paulo }
1278*d4f2939cSRui Paulo 
1279*d4f2939cSRui Paulo 
1280*d4f2939cSRui Paulo /**
1281*d4f2939cSRui Paulo  *
1282*d4f2939cSRui Paulo  * Method to emit Invitation Result signal based on status and
1283*d4f2939cSRui Paulo  * bssid
1284*d4f2939cSRui Paulo  * @status: Status of the Invite request. 0 for success, other
1285*d4f2939cSRui Paulo  * for errors
1286*d4f2939cSRui Paulo  * @bssid : Basic Service Set Identifier
1287*d4f2939cSRui Paulo  */
1288*d4f2939cSRui Paulo void wpas_dbus_signal_p2p_invitation_result(struct wpa_supplicant *wpa_s,
1289*d4f2939cSRui Paulo 					    int status, const u8 *bssid)
1290*d4f2939cSRui Paulo {
1291*d4f2939cSRui Paulo 	DBusMessage *msg;
1292*d4f2939cSRui Paulo 	DBusMessageIter iter, dict_iter;
1293*d4f2939cSRui Paulo 	struct wpas_dbus_priv *iface;
1294*d4f2939cSRui Paulo 
1295*d4f2939cSRui Paulo 	wpa_printf(MSG_INFO, "%s\n", __func__);
1296*d4f2939cSRui Paulo 
1297*d4f2939cSRui Paulo 	iface = wpa_s->global->dbus;
1298*d4f2939cSRui Paulo 	/* Do nothing if the control interface is not turned on */
1299*d4f2939cSRui Paulo 	if (iface == NULL)
1300*d4f2939cSRui Paulo 		return;
1301*d4f2939cSRui Paulo 
1302*d4f2939cSRui Paulo 	msg = dbus_message_new_signal(wpa_s->dbus_new_path,
1303*d4f2939cSRui Paulo 				      WPAS_DBUS_NEW_IFACE_P2PDEVICE,
1304*d4f2939cSRui Paulo 				      "InvitationResult");
1305*d4f2939cSRui Paulo 
1306*d4f2939cSRui Paulo 	if (msg == NULL)
1307*d4f2939cSRui Paulo 		return;
1308*d4f2939cSRui Paulo 
1309*d4f2939cSRui Paulo 	dbus_message_iter_init_append(msg, &iter);
1310*d4f2939cSRui Paulo 	if (!wpa_dbus_dict_open_write(&iter, &dict_iter))
1311*d4f2939cSRui Paulo 		goto nomem;
1312*d4f2939cSRui Paulo 
1313*d4f2939cSRui Paulo 	if (!wpa_dbus_dict_append_int32(&dict_iter, "status", status))
1314*d4f2939cSRui Paulo 		goto nomem;
1315*d4f2939cSRui Paulo 	if (bssid) {
1316*d4f2939cSRui Paulo 		if (!wpa_dbus_dict_append_byte_array(&dict_iter, "BSSID",
1317*d4f2939cSRui Paulo 						     (const char *) bssid,
1318*d4f2939cSRui Paulo 						     ETH_ALEN))
1319*d4f2939cSRui Paulo 			goto nomem;
1320*d4f2939cSRui Paulo 	}
1321*d4f2939cSRui Paulo 	if (!wpa_dbus_dict_close_write(&iter, &dict_iter))
1322*d4f2939cSRui Paulo 		goto nomem;
1323*d4f2939cSRui Paulo 
1324*d4f2939cSRui Paulo 	dbus_connection_send(iface->con, msg, NULL);
1325*d4f2939cSRui Paulo 
1326*d4f2939cSRui Paulo nomem:
1327*d4f2939cSRui Paulo 	dbus_message_unref(msg);
1328*d4f2939cSRui Paulo }
1329*d4f2939cSRui Paulo 
1330*d4f2939cSRui Paulo 
1331*d4f2939cSRui Paulo /**
1332*d4f2939cSRui Paulo  *
1333*d4f2939cSRui Paulo  * Method to emit a signal for a peer joining the group.
1334*d4f2939cSRui Paulo  * The signal will carry path to the group member object
1335*d4f2939cSRui Paulo  * constructed using p2p i/f addr used for connecting.
1336*d4f2939cSRui Paulo  *
1337*d4f2939cSRui Paulo  * @wpa_s: %wpa_supplicant network interface data
1338*d4f2939cSRui Paulo  * @member_addr: addr (p2p i/f) of the peer joining the group
1339*d4f2939cSRui Paulo  */
1340*d4f2939cSRui Paulo void wpas_dbus_signal_p2p_peer_joined(struct wpa_supplicant *wpa_s,
1341*d4f2939cSRui Paulo 				      const u8 *member)
1342*d4f2939cSRui Paulo {
1343*d4f2939cSRui Paulo 	struct wpas_dbus_priv *iface;
1344*d4f2939cSRui Paulo 	DBusMessage *msg;
1345*d4f2939cSRui Paulo 	DBusMessageIter iter;
1346*d4f2939cSRui Paulo 	char groupmember_obj_path[WPAS_DBUS_OBJECT_PATH_MAX], *path;
1347*d4f2939cSRui Paulo 
1348*d4f2939cSRui Paulo 	iface = wpa_s->global->dbus;
1349*d4f2939cSRui Paulo 
1350*d4f2939cSRui Paulo 	/* Do nothing if the control interface is not turned on */
1351*d4f2939cSRui Paulo 	if (iface == NULL)
1352*d4f2939cSRui Paulo 		return;
1353*d4f2939cSRui Paulo 
1354*d4f2939cSRui Paulo 	if (!wpa_s->dbus_groupobj_path)
1355*d4f2939cSRui Paulo 		return;
1356*d4f2939cSRui Paulo 
1357*d4f2939cSRui Paulo 	os_snprintf(groupmember_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
1358*d4f2939cSRui Paulo 			"%s/"  WPAS_DBUS_NEW_P2P_GROUPMEMBERS_PART "/"
1359*d4f2939cSRui Paulo 			COMPACT_MACSTR,
1360*d4f2939cSRui Paulo 			wpa_s->dbus_groupobj_path, MAC2STR(member));
1361*d4f2939cSRui Paulo 
1362*d4f2939cSRui Paulo 	msg = dbus_message_new_signal(wpa_s->dbus_groupobj_path,
1363*d4f2939cSRui Paulo 				      WPAS_DBUS_NEW_IFACE_P2P_GROUP,
1364*d4f2939cSRui Paulo 				      "PeerJoined");
1365*d4f2939cSRui Paulo 	if (msg == NULL)
1366*d4f2939cSRui Paulo 		return;
1367*d4f2939cSRui Paulo 
1368*d4f2939cSRui Paulo 	dbus_message_iter_init_append(msg, &iter);
1369*d4f2939cSRui Paulo 	path = groupmember_obj_path;
1370*d4f2939cSRui Paulo 	if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_OBJECT_PATH,
1371*d4f2939cSRui Paulo 					    &path))
1372*d4f2939cSRui Paulo 		goto err;
1373*d4f2939cSRui Paulo 
1374*d4f2939cSRui Paulo 	dbus_connection_send(iface->con, msg, NULL);
1375*d4f2939cSRui Paulo 
1376*d4f2939cSRui Paulo 	dbus_message_unref(msg);
1377*d4f2939cSRui Paulo 	return;
1378*d4f2939cSRui Paulo 
1379*d4f2939cSRui Paulo err:
1380*d4f2939cSRui Paulo 	wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
1381*d4f2939cSRui Paulo 	dbus_message_unref(msg);
1382*d4f2939cSRui Paulo }
1383*d4f2939cSRui Paulo 
1384*d4f2939cSRui Paulo 
1385*d4f2939cSRui Paulo /**
1386*d4f2939cSRui Paulo  *
1387*d4f2939cSRui Paulo  * Method to emit a signal for a peer disconnecting the group.
1388*d4f2939cSRui Paulo  * The signal will carry path to the group member object
1389*d4f2939cSRui Paulo  * constructed using p2p i/f addr used for connecting.
1390*d4f2939cSRui Paulo  *
1391*d4f2939cSRui Paulo  * @wpa_s: %wpa_supplicant network interface data
1392*d4f2939cSRui Paulo  * @member_addr: addr (p2p i/f) of the peer joining the group
1393*d4f2939cSRui Paulo  */
1394*d4f2939cSRui Paulo void wpas_dbus_signal_p2p_peer_disconnected(struct wpa_supplicant *wpa_s,
1395*d4f2939cSRui Paulo 				      const u8 *member)
1396*d4f2939cSRui Paulo {
1397*d4f2939cSRui Paulo 	struct wpas_dbus_priv *iface;
1398*d4f2939cSRui Paulo 	DBusMessage *msg;
1399*d4f2939cSRui Paulo 	DBusMessageIter iter;
1400*d4f2939cSRui Paulo 	char groupmember_obj_path[WPAS_DBUS_OBJECT_PATH_MAX], *path;
1401*d4f2939cSRui Paulo 
1402*d4f2939cSRui Paulo 	iface = wpa_s->global->dbus;
1403*d4f2939cSRui Paulo 
1404*d4f2939cSRui Paulo 	/* Do nothing if the control interface is not turned on */
1405*d4f2939cSRui Paulo 	if (iface == NULL)
1406*d4f2939cSRui Paulo 		return;
1407*d4f2939cSRui Paulo 
1408*d4f2939cSRui Paulo 	if (!wpa_s->dbus_groupobj_path)
1409*d4f2939cSRui Paulo 		return;
1410*d4f2939cSRui Paulo 
1411*d4f2939cSRui Paulo 	os_snprintf(groupmember_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
1412*d4f2939cSRui Paulo 			"%s/"  WPAS_DBUS_NEW_P2P_GROUPMEMBERS_PART "/"
1413*d4f2939cSRui Paulo 			COMPACT_MACSTR,
1414*d4f2939cSRui Paulo 			wpa_s->dbus_groupobj_path, MAC2STR(member));
1415*d4f2939cSRui Paulo 
1416*d4f2939cSRui Paulo 	msg = dbus_message_new_signal(wpa_s->dbus_groupobj_path,
1417*d4f2939cSRui Paulo 				      WPAS_DBUS_NEW_IFACE_P2P_GROUP,
1418*d4f2939cSRui Paulo 				      "PeerDisconnected");
1419*d4f2939cSRui Paulo 	if (msg == NULL)
1420*d4f2939cSRui Paulo 		return;
1421*d4f2939cSRui Paulo 
1422*d4f2939cSRui Paulo 	dbus_message_iter_init_append(msg, &iter);
1423*d4f2939cSRui Paulo 	path = groupmember_obj_path;
1424*d4f2939cSRui Paulo 	if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_OBJECT_PATH,
1425*d4f2939cSRui Paulo 					    &path))
1426*d4f2939cSRui Paulo 		goto err;
1427*d4f2939cSRui Paulo 
1428*d4f2939cSRui Paulo 	dbus_connection_send(iface->con, msg, NULL);
1429*d4f2939cSRui Paulo 
1430*d4f2939cSRui Paulo 	dbus_message_unref(msg);
1431*d4f2939cSRui Paulo 	return;
1432*d4f2939cSRui Paulo 
1433*d4f2939cSRui Paulo err:
1434*d4f2939cSRui Paulo 	wpa_printf(MSG_ERROR, "dbus: Failed to construct PeerDisconnected "
1435*d4f2939cSRui Paulo 			      "signal");
1436*d4f2939cSRui Paulo 	dbus_message_unref(msg);
1437*d4f2939cSRui Paulo }
1438*d4f2939cSRui Paulo 
1439*d4f2939cSRui Paulo 
1440*d4f2939cSRui Paulo /**
1441*d4f2939cSRui Paulo  *
1442*d4f2939cSRui Paulo  * Method to emit a signal for a service discovery request.
1443*d4f2939cSRui Paulo  * The signal will carry station address, frequency, dialog token,
1444*d4f2939cSRui Paulo  * update indicator and it tlvs
1445*d4f2939cSRui Paulo  *
1446*d4f2939cSRui Paulo  * @wpa_s: %wpa_supplicant network interface data
1447*d4f2939cSRui Paulo  * @sa: station addr (p2p i/f) of the peer
1448*d4f2939cSRui Paulo  * @dialog_token: service discovery request dialog token
1449*d4f2939cSRui Paulo  * @update_indic: service discovery request update indicator
1450*d4f2939cSRui Paulo  * @tlvs: service discovery request genrated byte array of tlvs
1451*d4f2939cSRui Paulo  * @tlvs_len: service discovery request tlvs length
1452*d4f2939cSRui Paulo  */
1453*d4f2939cSRui Paulo void wpas_dbus_signal_p2p_sd_request(struct wpa_supplicant *wpa_s,
1454*d4f2939cSRui Paulo 				     int freq, const u8 *sa, u8 dialog_token,
1455*d4f2939cSRui Paulo 				     u16 update_indic, const u8 *tlvs,
1456*d4f2939cSRui Paulo 				     size_t tlvs_len)
1457*d4f2939cSRui Paulo {
1458*d4f2939cSRui Paulo 	DBusMessage *msg;
1459*d4f2939cSRui Paulo 	DBusMessageIter iter, dict_iter;
1460*d4f2939cSRui Paulo 	struct wpas_dbus_priv *iface;
1461*d4f2939cSRui Paulo 	char peer_obj_path[WPAS_DBUS_OBJECT_PATH_MAX], *path;
1462*d4f2939cSRui Paulo 	iface = wpa_s->global->dbus;
1463*d4f2939cSRui Paulo 
1464*d4f2939cSRui Paulo 	/* Do nothing if the control interface is not turned on */
1465*d4f2939cSRui Paulo 	if (iface == NULL)
1466*d4f2939cSRui Paulo 		return;
1467*d4f2939cSRui Paulo 
1468*d4f2939cSRui Paulo 	msg = dbus_message_new_signal(wpa_s->dbus_new_path,
1469*d4f2939cSRui Paulo 				      WPAS_DBUS_NEW_IFACE_P2PDEVICE,
1470*d4f2939cSRui Paulo 				      "ServiceDiscoveryRequest");
1471*d4f2939cSRui Paulo 	if (msg == NULL)
1472*d4f2939cSRui Paulo 		return;
1473*d4f2939cSRui Paulo 
1474*d4f2939cSRui Paulo 	/* Check if this is a known peer */
1475*d4f2939cSRui Paulo 	if (!p2p_peer_known(wpa_s->global->p2p, sa))
1476*d4f2939cSRui Paulo 		goto error;
1477*d4f2939cSRui Paulo 
1478*d4f2939cSRui Paulo 	os_snprintf(peer_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
1479*d4f2939cSRui Paulo 		    "%s/" WPAS_DBUS_NEW_P2P_PEERS_PART "/"
1480*d4f2939cSRui Paulo 		    COMPACT_MACSTR, wpa_s->dbus_new_path, MAC2STR(sa));
1481*d4f2939cSRui Paulo 
1482*d4f2939cSRui Paulo 	path = peer_obj_path;
1483*d4f2939cSRui Paulo 
1484*d4f2939cSRui Paulo 	dbus_message_iter_init_append(msg, &iter);
1485*d4f2939cSRui Paulo 	if (!wpa_dbus_dict_open_write(&iter, &dict_iter))
1486*d4f2939cSRui Paulo 		goto error;
1487*d4f2939cSRui Paulo 
1488*d4f2939cSRui Paulo 
1489*d4f2939cSRui Paulo 	if (!wpa_dbus_dict_append_object_path(&dict_iter, "peer_object",
1490*d4f2939cSRui Paulo 					      path) ||
1491*d4f2939cSRui Paulo 	    !wpa_dbus_dict_append_int32(&dict_iter, "frequency", freq) ||
1492*d4f2939cSRui Paulo 	    !wpa_dbus_dict_append_int32(&dict_iter, "dialog_token",
1493*d4f2939cSRui Paulo 					dialog_token) ||
1494*d4f2939cSRui Paulo 	    !wpa_dbus_dict_append_uint16(&dict_iter, "update_indicator",
1495*d4f2939cSRui Paulo 					 update_indic) ||
1496*d4f2939cSRui Paulo 	    !wpa_dbus_dict_append_byte_array(&dict_iter, "tlvs",
1497*d4f2939cSRui Paulo 					     (const char *) tlvs,
1498*d4f2939cSRui Paulo 					     tlvs_len) ||
1499*d4f2939cSRui Paulo 	    !wpa_dbus_dict_close_write(&iter, &dict_iter))
1500*d4f2939cSRui Paulo 		goto error;
1501*d4f2939cSRui Paulo 
1502*d4f2939cSRui Paulo 	dbus_connection_send(iface->con, msg, NULL);
1503*d4f2939cSRui Paulo 	dbus_message_unref(msg);
1504*d4f2939cSRui Paulo 	return;
1505*d4f2939cSRui Paulo error:
1506*d4f2939cSRui Paulo 	wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
1507*d4f2939cSRui Paulo 	dbus_message_unref(msg);
1508*d4f2939cSRui Paulo }
1509*d4f2939cSRui Paulo 
1510*d4f2939cSRui Paulo 
1511*d4f2939cSRui Paulo /**
1512*d4f2939cSRui Paulo  *
1513*d4f2939cSRui Paulo  * Method to emit a signal for a service discovery response.
1514*d4f2939cSRui Paulo  * The signal will carry station address, update indicator and it
1515*d4f2939cSRui Paulo  * tlvs
1516*d4f2939cSRui Paulo  *
1517*d4f2939cSRui Paulo  * @wpa_s: %wpa_supplicant network interface data
1518*d4f2939cSRui Paulo  * @sa: station addr (p2p i/f) of the peer
1519*d4f2939cSRui Paulo  * @update_indic: service discovery request update indicator
1520*d4f2939cSRui Paulo  * @tlvs: service discovery request genrated byte array of tlvs
1521*d4f2939cSRui Paulo  * @tlvs_len: service discovery request tlvs length
1522*d4f2939cSRui Paulo  */
1523*d4f2939cSRui Paulo void wpas_dbus_signal_p2p_sd_response(struct wpa_supplicant *wpa_s,
1524*d4f2939cSRui Paulo 				      const u8 *sa, u16 update_indic,
1525*d4f2939cSRui Paulo 				      const u8 *tlvs, size_t tlvs_len)
1526*d4f2939cSRui Paulo {
1527*d4f2939cSRui Paulo 	DBusMessage *msg;
1528*d4f2939cSRui Paulo 	DBusMessageIter iter, dict_iter;
1529*d4f2939cSRui Paulo 	struct wpas_dbus_priv *iface;
1530*d4f2939cSRui Paulo 	char peer_obj_path[WPAS_DBUS_OBJECT_PATH_MAX], *path;
1531*d4f2939cSRui Paulo 	iface = wpa_s->global->dbus;
1532*d4f2939cSRui Paulo 
1533*d4f2939cSRui Paulo 	/* Do nothing if the control interface is not turned on */
1534*d4f2939cSRui Paulo 	if (iface == NULL)
1535*d4f2939cSRui Paulo 		return;
1536*d4f2939cSRui Paulo 
1537*d4f2939cSRui Paulo 	msg = dbus_message_new_signal(wpa_s->dbus_new_path,
1538*d4f2939cSRui Paulo 				      WPAS_DBUS_NEW_IFACE_P2PDEVICE,
1539*d4f2939cSRui Paulo 				"ServiceDiscoveryResponse");
1540*d4f2939cSRui Paulo 	if (msg == NULL)
1541*d4f2939cSRui Paulo 		return;
1542*d4f2939cSRui Paulo 
1543*d4f2939cSRui Paulo 	/* Check if this is a known peer */
1544*d4f2939cSRui Paulo 	if (!p2p_peer_known(wpa_s->global->p2p, sa))
1545*d4f2939cSRui Paulo 		goto error;
1546*d4f2939cSRui Paulo 
1547*d4f2939cSRui Paulo 	os_snprintf(peer_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
1548*d4f2939cSRui Paulo 		    "%s/" WPAS_DBUS_NEW_P2P_PEERS_PART "/"
1549*d4f2939cSRui Paulo 		    COMPACT_MACSTR, wpa_s->dbus_new_path, MAC2STR(sa));
1550*d4f2939cSRui Paulo 
1551*d4f2939cSRui Paulo 	path = peer_obj_path;
1552*d4f2939cSRui Paulo 
1553*d4f2939cSRui Paulo 	dbus_message_iter_init_append(msg, &iter);
1554*d4f2939cSRui Paulo 	if (!wpa_dbus_dict_open_write(&iter, &dict_iter))
1555*d4f2939cSRui Paulo 		goto error;
1556*d4f2939cSRui Paulo 
1557*d4f2939cSRui Paulo 	if (!wpa_dbus_dict_append_object_path(&dict_iter, "peer_object",
1558*d4f2939cSRui Paulo 					      path) ||
1559*d4f2939cSRui Paulo 	    !wpa_dbus_dict_append_uint16(&dict_iter, "update_indicator",
1560*d4f2939cSRui Paulo 					 update_indic) ||
1561*d4f2939cSRui Paulo 	    !wpa_dbus_dict_append_byte_array(&dict_iter, "tlvs",
1562*d4f2939cSRui Paulo 					     (const char *) tlvs,
1563*d4f2939cSRui Paulo 					     tlvs_len) ||
1564*d4f2939cSRui Paulo 	    !wpa_dbus_dict_close_write(&iter, &dict_iter))
1565*d4f2939cSRui Paulo 		goto error;
1566*d4f2939cSRui Paulo 
1567*d4f2939cSRui Paulo 
1568*d4f2939cSRui Paulo 	dbus_connection_send(iface->con, msg, NULL);
1569*d4f2939cSRui Paulo 	dbus_message_unref(msg);
1570*d4f2939cSRui Paulo 	return;
1571*d4f2939cSRui Paulo error:
1572*d4f2939cSRui Paulo 	wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
1573*d4f2939cSRui Paulo 	dbus_message_unref(msg);
1574*d4f2939cSRui Paulo }
1575*d4f2939cSRui Paulo 
1576*d4f2939cSRui Paulo /**
1577*d4f2939cSRui Paulo  * wpas_dbus_signal_persistent_group - Send a persistent group related
1578*d4f2939cSRui Paulo  *	event signal
1579*d4f2939cSRui Paulo  * @wpa_s: %wpa_supplicant network interface data
1580*d4f2939cSRui Paulo  * @id: new persistent group id
1581*d4f2939cSRui Paulo  * @sig_name: signal name - PersistentGroupAdded, PersistentGroupRemoved
1582*d4f2939cSRui Paulo  * @properties: determines if add second argument with object properties
1583*d4f2939cSRui Paulo  *
1584*d4f2939cSRui Paulo  * Notify listeners about an event related to persistent groups.
1585*d4f2939cSRui Paulo  */
1586*d4f2939cSRui Paulo static void wpas_dbus_signal_persistent_group(struct wpa_supplicant *wpa_s,
1587*d4f2939cSRui Paulo 					      int id, const char *sig_name,
1588*d4f2939cSRui Paulo 					      int properties)
1589*d4f2939cSRui Paulo {
1590*d4f2939cSRui Paulo 	struct wpas_dbus_priv *iface;
1591*d4f2939cSRui Paulo 	DBusMessage *msg;
1592*d4f2939cSRui Paulo 	DBusMessageIter iter;
1593*d4f2939cSRui Paulo 	char pgrp_obj_path[WPAS_DBUS_OBJECT_PATH_MAX], *path;
1594*d4f2939cSRui Paulo 
1595*d4f2939cSRui Paulo 	iface = wpa_s->global->dbus;
1596*d4f2939cSRui Paulo 
1597*d4f2939cSRui Paulo 	/* Do nothing if the control interface is not turned on */
1598*d4f2939cSRui Paulo 	if (iface == NULL)
1599*d4f2939cSRui Paulo 		return;
1600*d4f2939cSRui Paulo 
1601*d4f2939cSRui Paulo 	os_snprintf(pgrp_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
1602*d4f2939cSRui Paulo 		    "%s/" WPAS_DBUS_NEW_PERSISTENT_GROUPS_PART "/%u",
1603*d4f2939cSRui Paulo 		    wpa_s->dbus_new_path, id);
1604*d4f2939cSRui Paulo 
1605*d4f2939cSRui Paulo 	msg = dbus_message_new_signal(wpa_s->dbus_new_path,
1606*d4f2939cSRui Paulo 				      WPAS_DBUS_NEW_IFACE_P2PDEVICE,
1607*d4f2939cSRui Paulo 				      sig_name);
1608*d4f2939cSRui Paulo 	if (msg == NULL)
1609*d4f2939cSRui Paulo 		return;
1610*d4f2939cSRui Paulo 
1611*d4f2939cSRui Paulo 	dbus_message_iter_init_append(msg, &iter);
1612*d4f2939cSRui Paulo 	path = pgrp_obj_path;
1613*d4f2939cSRui Paulo 	if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_OBJECT_PATH,
1614*d4f2939cSRui Paulo 					    &path))
1615*d4f2939cSRui Paulo 		goto err;
1616*d4f2939cSRui Paulo 
1617*d4f2939cSRui Paulo 	if (properties) {
1618*d4f2939cSRui Paulo 		if (!wpa_dbus_get_object_properties(
1619*d4f2939cSRui Paulo 			    iface, pgrp_obj_path,
1620*d4f2939cSRui Paulo 			    WPAS_DBUS_NEW_IFACE_PERSISTENT_GROUP, &iter))
1621*d4f2939cSRui Paulo 			goto err;
1622*d4f2939cSRui Paulo 	}
1623*d4f2939cSRui Paulo 
1624*d4f2939cSRui Paulo 	dbus_connection_send(iface->con, msg, NULL);
1625*d4f2939cSRui Paulo 
1626*d4f2939cSRui Paulo 	dbus_message_unref(msg);
1627*d4f2939cSRui Paulo 	return;
1628*d4f2939cSRui Paulo 
1629*d4f2939cSRui Paulo err:
1630*d4f2939cSRui Paulo 	wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
1631*d4f2939cSRui Paulo 	dbus_message_unref(msg);
1632*d4f2939cSRui Paulo }
1633*d4f2939cSRui Paulo 
1634*d4f2939cSRui Paulo 
1635*d4f2939cSRui Paulo /**
1636*d4f2939cSRui Paulo  * wpas_dbus_signal_persistent_group_added - Send a persistent_group
1637*d4f2939cSRui Paulo  *	added signal
1638*d4f2939cSRui Paulo  * @wpa_s: %wpa_supplicant network interface data
1639*d4f2939cSRui Paulo  * @id: new persistent group id
1640*d4f2939cSRui Paulo  *
1641*d4f2939cSRui Paulo  * Notify listeners about addition of a new persistent group.
1642*d4f2939cSRui Paulo  */
1643*d4f2939cSRui Paulo static void wpas_dbus_signal_persistent_group_added(
1644*d4f2939cSRui Paulo 	struct wpa_supplicant *wpa_s, int id)
1645*d4f2939cSRui Paulo {
1646*d4f2939cSRui Paulo 	wpas_dbus_signal_persistent_group(wpa_s, id, "PersistentGroupAdded",
1647*d4f2939cSRui Paulo 					  TRUE);
1648*d4f2939cSRui Paulo }
1649*d4f2939cSRui Paulo 
1650*d4f2939cSRui Paulo 
1651*d4f2939cSRui Paulo /**
1652*d4f2939cSRui Paulo  * wpas_dbus_signal_persistent_group_removed - Send a persistent_group
1653*d4f2939cSRui Paulo  *	removed signal
1654*d4f2939cSRui Paulo  * @wpa_s: %wpa_supplicant network interface data
1655*d4f2939cSRui Paulo  * @id: persistent group id
1656*d4f2939cSRui Paulo  *
1657*d4f2939cSRui Paulo  * Notify listeners about removal of a persistent group.
1658*d4f2939cSRui Paulo  */
1659*d4f2939cSRui Paulo static void wpas_dbus_signal_persistent_group_removed(
1660*d4f2939cSRui Paulo 	struct wpa_supplicant *wpa_s, int id)
1661*d4f2939cSRui Paulo {
1662*d4f2939cSRui Paulo 	wpas_dbus_signal_persistent_group(wpa_s, id, "PersistentGroupRemoved",
1663*d4f2939cSRui Paulo 					  FALSE);
1664*d4f2939cSRui Paulo }
1665*d4f2939cSRui Paulo 
1666*d4f2939cSRui Paulo 
1667*d4f2939cSRui Paulo /**
1668*d4f2939cSRui Paulo  * wpas_dbus_signal_p2p_wps_failed - Signals WpsFailed event
1669*d4f2939cSRui Paulo  * @wpa_s: %wpa_supplicant network interface data
1670*d4f2939cSRui Paulo  *
1671*d4f2939cSRui Paulo  * Sends Event dbus signal with name "fail" and dictionary containing
1672*d4f2939cSRui Paulo  * "msg" field with fail message number (int32) as arguments
1673*d4f2939cSRui Paulo  */
1674*d4f2939cSRui Paulo void wpas_dbus_signal_p2p_wps_failed(struct wpa_supplicant *wpa_s,
1675*d4f2939cSRui Paulo 				     struct wps_event_fail *fail)
1676*d4f2939cSRui Paulo {
1677*d4f2939cSRui Paulo 
1678*d4f2939cSRui Paulo 	DBusMessage *msg;
1679*d4f2939cSRui Paulo 	DBusMessageIter iter, dict_iter;
1680*d4f2939cSRui Paulo 	struct wpas_dbus_priv *iface;
1681*d4f2939cSRui Paulo 	char *key = "fail";
1682*d4f2939cSRui Paulo 
1683*d4f2939cSRui Paulo 	iface = wpa_s->global->dbus;
1684*d4f2939cSRui Paulo 
1685*d4f2939cSRui Paulo 	/* Do nothing if the control interface is not turned on */
1686*d4f2939cSRui Paulo 	if (iface == NULL)
1687*d4f2939cSRui Paulo 		return;
1688*d4f2939cSRui Paulo 
1689*d4f2939cSRui Paulo 	msg = dbus_message_new_signal(wpa_s->dbus_new_path,
1690*d4f2939cSRui Paulo 				      WPAS_DBUS_NEW_IFACE_P2PDEVICE,
1691*d4f2939cSRui Paulo 				      "WpsFailed");
1692*d4f2939cSRui Paulo 	if (msg == NULL)
1693*d4f2939cSRui Paulo 		return;
1694*d4f2939cSRui Paulo 
1695*d4f2939cSRui Paulo 	dbus_message_iter_init_append(msg, &iter);
1696*d4f2939cSRui Paulo 
1697*d4f2939cSRui Paulo 	if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &key) ||
1698*d4f2939cSRui Paulo 	    !wpa_dbus_dict_open_write(&iter, &dict_iter) ||
1699*d4f2939cSRui Paulo 	    !wpa_dbus_dict_append_int32(&dict_iter, "msg", fail->msg) ||
1700*d4f2939cSRui Paulo 	    !wpa_dbus_dict_append_int16(&dict_iter, "config_error",
1701*d4f2939cSRui Paulo 					fail->config_error) ||
1702*d4f2939cSRui Paulo 	    !wpa_dbus_dict_close_write(&iter, &dict_iter))
1703*d4f2939cSRui Paulo 		wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
1704*d4f2939cSRui Paulo 	else
1705*d4f2939cSRui Paulo 		dbus_connection_send(iface->con, msg, NULL);
1706*d4f2939cSRui Paulo 
1707*d4f2939cSRui Paulo 	dbus_message_unref(msg);
1708*d4f2939cSRui Paulo }
1709*d4f2939cSRui Paulo 
1710*d4f2939cSRui Paulo #endif /*CONFIG_P2P*/
1711*d4f2939cSRui Paulo 
1712*d4f2939cSRui Paulo 
1713*d4f2939cSRui Paulo /**
1714*d4f2939cSRui Paulo  * wpas_dbus_signal_prop_changed - Signals change of property
1715*d4f2939cSRui Paulo  * @wpa_s: %wpa_supplicant network interface data
1716*d4f2939cSRui Paulo  * @property: indicates which property has changed
1717*d4f2939cSRui Paulo  *
1718*d4f2939cSRui Paulo  * Sends PropertyChanged signals with path, interface and arguments
1719*d4f2939cSRui Paulo  * depending on which property has changed.
1720*d4f2939cSRui Paulo  */
1721*d4f2939cSRui Paulo void wpas_dbus_signal_prop_changed(struct wpa_supplicant *wpa_s,
1722*d4f2939cSRui Paulo 				   enum wpas_dbus_prop property)
1723*d4f2939cSRui Paulo {
1724*d4f2939cSRui Paulo 	char *prop;
1725*d4f2939cSRui Paulo 	dbus_bool_t flush;
1726*d4f2939cSRui Paulo 
1727*d4f2939cSRui Paulo 	if (wpa_s->dbus_new_path == NULL)
1728*d4f2939cSRui Paulo 		return; /* Skip signal since D-Bus setup is not yet ready */
1729*d4f2939cSRui Paulo 
1730*d4f2939cSRui Paulo 	flush = FALSE;
1731*d4f2939cSRui Paulo 	switch (property) {
1732*d4f2939cSRui Paulo 	case WPAS_DBUS_PROP_AP_SCAN:
1733*d4f2939cSRui Paulo 		prop = "ApScan";
1734*d4f2939cSRui Paulo 		break;
1735*d4f2939cSRui Paulo 	case WPAS_DBUS_PROP_SCANNING:
1736*d4f2939cSRui Paulo 		prop = "Scanning";
1737*d4f2939cSRui Paulo 		break;
1738*d4f2939cSRui Paulo 	case WPAS_DBUS_PROP_STATE:
1739*d4f2939cSRui Paulo 		prop = "State";
1740*d4f2939cSRui Paulo 		break;
1741*d4f2939cSRui Paulo 	case WPAS_DBUS_PROP_CURRENT_BSS:
1742*d4f2939cSRui Paulo 		prop = "CurrentBSS";
1743*d4f2939cSRui Paulo 		break;
1744*d4f2939cSRui Paulo 	case WPAS_DBUS_PROP_CURRENT_NETWORK:
1745*d4f2939cSRui Paulo 		prop = "CurrentNetwork";
1746*d4f2939cSRui Paulo 		break;
1747*d4f2939cSRui Paulo 	case WPAS_DBUS_PROP_BSSS:
1748*d4f2939cSRui Paulo 		prop = "BSSs";
1749*d4f2939cSRui Paulo 		break;
1750*d4f2939cSRui Paulo 	case WPAS_DBUS_PROP_CURRENT_AUTH_MODE:
1751*d4f2939cSRui Paulo 		prop = "CurrentAuthMode";
1752*d4f2939cSRui Paulo 		break;
1753*d4f2939cSRui Paulo 	case WPAS_DBUS_PROP_DISCONNECT_REASON:
1754*d4f2939cSRui Paulo 		prop = "DisconnectReason";
1755*d4f2939cSRui Paulo 		flush = TRUE;
1756*d4f2939cSRui Paulo 		break;
1757*d4f2939cSRui Paulo 	default:
1758*d4f2939cSRui Paulo 		wpa_printf(MSG_ERROR, "dbus: %s: Unknown Property value %d",
1759*d4f2939cSRui Paulo 			   __func__, property);
1760*d4f2939cSRui Paulo 		return;
1761*d4f2939cSRui Paulo 	}
1762*d4f2939cSRui Paulo 
1763*d4f2939cSRui Paulo 	wpa_dbus_mark_property_changed(wpa_s->global->dbus,
1764*d4f2939cSRui Paulo 				       wpa_s->dbus_new_path,
1765*d4f2939cSRui Paulo 				       WPAS_DBUS_NEW_IFACE_INTERFACE, prop);
1766*d4f2939cSRui Paulo 	if (flush) {
1767*d4f2939cSRui Paulo 		wpa_dbus_flush_object_changed_properties(
1768*d4f2939cSRui Paulo 			wpa_s->global->dbus->con, wpa_s->dbus_new_path);
1769*d4f2939cSRui Paulo 	}
1770*d4f2939cSRui Paulo }
1771*d4f2939cSRui Paulo 
1772*d4f2939cSRui Paulo 
1773*d4f2939cSRui Paulo /**
1774*d4f2939cSRui Paulo  * wpas_dbus_bss_signal_prop_changed - Signals change of BSS property
1775*d4f2939cSRui Paulo  * @wpa_s: %wpa_supplicant network interface data
1776*d4f2939cSRui Paulo  * @property: indicates which property has changed
1777*d4f2939cSRui Paulo  * @id: unique BSS identifier
1778*d4f2939cSRui Paulo  *
1779*d4f2939cSRui Paulo  * Sends PropertyChanged signals with path, interface, and arguments depending
1780*d4f2939cSRui Paulo  * on which property has changed.
1781*d4f2939cSRui Paulo  */
1782*d4f2939cSRui Paulo void wpas_dbus_bss_signal_prop_changed(struct wpa_supplicant *wpa_s,
1783*d4f2939cSRui Paulo 				       enum wpas_dbus_bss_prop property,
1784*d4f2939cSRui Paulo 				       unsigned int id)
1785*d4f2939cSRui Paulo {
1786*d4f2939cSRui Paulo 	char path[WPAS_DBUS_OBJECT_PATH_MAX];
1787*d4f2939cSRui Paulo 	char *prop;
1788*d4f2939cSRui Paulo 
1789*d4f2939cSRui Paulo 	switch (property) {
1790*d4f2939cSRui Paulo 	case WPAS_DBUS_BSS_PROP_SIGNAL:
1791*d4f2939cSRui Paulo 		prop = "Signal";
1792*d4f2939cSRui Paulo 		break;
1793*d4f2939cSRui Paulo 	case WPAS_DBUS_BSS_PROP_FREQ:
1794*d4f2939cSRui Paulo 		prop = "Frequency";
1795*d4f2939cSRui Paulo 		break;
1796*d4f2939cSRui Paulo 	case WPAS_DBUS_BSS_PROP_MODE:
1797*d4f2939cSRui Paulo 		prop = "Mode";
1798*d4f2939cSRui Paulo 		break;
1799*d4f2939cSRui Paulo 	case WPAS_DBUS_BSS_PROP_PRIVACY:
1800*d4f2939cSRui Paulo 		prop = "Privacy";
1801*d4f2939cSRui Paulo 		break;
1802*d4f2939cSRui Paulo 	case WPAS_DBUS_BSS_PROP_RATES:
1803*d4f2939cSRui Paulo 		prop = "Rates";
1804*d4f2939cSRui Paulo 		break;
1805*d4f2939cSRui Paulo 	case WPAS_DBUS_BSS_PROP_WPA:
1806*d4f2939cSRui Paulo 		prop = "WPA";
1807*d4f2939cSRui Paulo 		break;
1808*d4f2939cSRui Paulo 	case WPAS_DBUS_BSS_PROP_RSN:
1809*d4f2939cSRui Paulo 		prop = "RSN";
1810*d4f2939cSRui Paulo 		break;
1811*d4f2939cSRui Paulo 	case WPAS_DBUS_BSS_PROP_IES:
1812*d4f2939cSRui Paulo 		prop = "IEs";
1813*d4f2939cSRui Paulo 		break;
1814*d4f2939cSRui Paulo 	default:
1815*d4f2939cSRui Paulo 		wpa_printf(MSG_ERROR, "dbus: %s: Unknown Property value %d",
1816*d4f2939cSRui Paulo 			   __func__, property);
1817*d4f2939cSRui Paulo 		return;
1818*d4f2939cSRui Paulo 	}
1819*d4f2939cSRui Paulo 
1820*d4f2939cSRui Paulo 	os_snprintf(path, WPAS_DBUS_OBJECT_PATH_MAX,
1821*d4f2939cSRui Paulo 		    "%s/" WPAS_DBUS_NEW_BSSIDS_PART "/%u",
1822*d4f2939cSRui Paulo 		    wpa_s->dbus_new_path, id);
1823*d4f2939cSRui Paulo 
1824*d4f2939cSRui Paulo 	wpa_dbus_mark_property_changed(wpa_s->global->dbus, path,
1825*d4f2939cSRui Paulo 				       WPAS_DBUS_NEW_IFACE_BSS, prop);
1826*d4f2939cSRui Paulo }
1827*d4f2939cSRui Paulo 
1828*d4f2939cSRui Paulo 
1829*d4f2939cSRui Paulo /**
1830*d4f2939cSRui Paulo  * wpas_dbus_signal_debug_level_changed - Signals change of debug param
1831*d4f2939cSRui Paulo  * @global: wpa_global structure
1832*d4f2939cSRui Paulo  *
1833*d4f2939cSRui Paulo  * Sends PropertyChanged signals informing that debug level has changed.
1834*d4f2939cSRui Paulo  */
1835*d4f2939cSRui Paulo void wpas_dbus_signal_debug_level_changed(struct wpa_global *global)
1836*d4f2939cSRui Paulo {
1837*d4f2939cSRui Paulo 	wpa_dbus_mark_property_changed(global->dbus, WPAS_DBUS_NEW_PATH,
1838*d4f2939cSRui Paulo 				       WPAS_DBUS_NEW_INTERFACE,
1839*d4f2939cSRui Paulo 				       "DebugLevel");
1840*d4f2939cSRui Paulo }
1841*d4f2939cSRui Paulo 
1842*d4f2939cSRui Paulo 
1843*d4f2939cSRui Paulo /**
1844*d4f2939cSRui Paulo  * wpas_dbus_signal_debug_timestamp_changed - Signals change of debug param
1845*d4f2939cSRui Paulo  * @global: wpa_global structure
1846*d4f2939cSRui Paulo  *
1847*d4f2939cSRui Paulo  * Sends PropertyChanged signals informing that debug timestamp has changed.
1848*d4f2939cSRui Paulo  */
1849*d4f2939cSRui Paulo void wpas_dbus_signal_debug_timestamp_changed(struct wpa_global *global)
1850*d4f2939cSRui Paulo {
1851*d4f2939cSRui Paulo 	wpa_dbus_mark_property_changed(global->dbus, WPAS_DBUS_NEW_PATH,
1852*d4f2939cSRui Paulo 				       WPAS_DBUS_NEW_INTERFACE,
1853*d4f2939cSRui Paulo 				       "DebugTimestamp");
1854*d4f2939cSRui Paulo }
1855*d4f2939cSRui Paulo 
1856*d4f2939cSRui Paulo 
1857*d4f2939cSRui Paulo /**
1858*d4f2939cSRui Paulo  * wpas_dbus_signal_debug_show_keys_changed - Signals change of debug param
1859*d4f2939cSRui Paulo  * @global: wpa_global structure
1860*d4f2939cSRui Paulo  *
1861*d4f2939cSRui Paulo  * Sends PropertyChanged signals informing that debug show_keys has changed.
1862*d4f2939cSRui Paulo  */
1863*d4f2939cSRui Paulo void wpas_dbus_signal_debug_show_keys_changed(struct wpa_global *global)
1864*d4f2939cSRui Paulo {
1865*d4f2939cSRui Paulo 	wpa_dbus_mark_property_changed(global->dbus, WPAS_DBUS_NEW_PATH,
1866*d4f2939cSRui Paulo 				       WPAS_DBUS_NEW_INTERFACE,
1867*d4f2939cSRui Paulo 				       "DebugShowKeys");
1868*d4f2939cSRui Paulo }
1869*d4f2939cSRui Paulo 
1870*d4f2939cSRui Paulo 
1871*d4f2939cSRui Paulo static void wpas_dbus_register(struct wpa_dbus_object_desc *obj_desc,
1872*d4f2939cSRui Paulo 			       void *priv,
1873*d4f2939cSRui Paulo 			       WPADBusArgumentFreeFunction priv_free,
1874*d4f2939cSRui Paulo 			       const struct wpa_dbus_method_desc *methods,
1875*d4f2939cSRui Paulo 			       const struct wpa_dbus_property_desc *properties,
1876*d4f2939cSRui Paulo 			       const struct wpa_dbus_signal_desc *signals)
1877*d4f2939cSRui Paulo {
1878*d4f2939cSRui Paulo 	int n;
1879*d4f2939cSRui Paulo 
1880*d4f2939cSRui Paulo 	obj_desc->user_data = priv;
1881*d4f2939cSRui Paulo 	obj_desc->user_data_free_func = priv_free;
1882*d4f2939cSRui Paulo 	obj_desc->methods = methods;
1883*d4f2939cSRui Paulo 	obj_desc->properties = properties;
1884*d4f2939cSRui Paulo 	obj_desc->signals = signals;
1885*d4f2939cSRui Paulo 
1886*d4f2939cSRui Paulo 	for (n = 0; properties && properties->dbus_property; properties++)
1887*d4f2939cSRui Paulo 		n++;
1888*d4f2939cSRui Paulo 
1889*d4f2939cSRui Paulo 	obj_desc->prop_changed_flags = os_zalloc(n);
1890*d4f2939cSRui Paulo 	if (!obj_desc->prop_changed_flags)
1891*d4f2939cSRui Paulo 		wpa_printf(MSG_DEBUG, "dbus: %s: can't register handlers",
1892*d4f2939cSRui Paulo 			   __func__);
1893*d4f2939cSRui Paulo }
1894*d4f2939cSRui Paulo 
1895*d4f2939cSRui Paulo 
1896*d4f2939cSRui Paulo static const struct wpa_dbus_method_desc wpas_dbus_global_methods[] = {
1897*d4f2939cSRui Paulo 	{ "CreateInterface", WPAS_DBUS_NEW_INTERFACE,
1898*d4f2939cSRui Paulo 	  (WPADBusMethodHandler) &wpas_dbus_handler_create_interface,
1899*d4f2939cSRui Paulo 	  {
1900*d4f2939cSRui Paulo 		  { "args", "a{sv}", ARG_IN },
1901*d4f2939cSRui Paulo 		  { "path", "o", ARG_OUT },
1902*d4f2939cSRui Paulo 		  END_ARGS
1903*d4f2939cSRui Paulo 	  }
1904*d4f2939cSRui Paulo 	},
1905*d4f2939cSRui Paulo 	{ "RemoveInterface", WPAS_DBUS_NEW_INTERFACE,
1906*d4f2939cSRui Paulo 	  (WPADBusMethodHandler) &wpas_dbus_handler_remove_interface,
1907*d4f2939cSRui Paulo 	  {
1908*d4f2939cSRui Paulo 		  { "path", "o", ARG_IN },
1909*d4f2939cSRui Paulo 		  END_ARGS
1910*d4f2939cSRui Paulo 	  }
1911*d4f2939cSRui Paulo 	},
1912*d4f2939cSRui Paulo 	{ "GetInterface", WPAS_DBUS_NEW_INTERFACE,
1913*d4f2939cSRui Paulo 	  (WPADBusMethodHandler) &wpas_dbus_handler_get_interface,
1914*d4f2939cSRui Paulo 	  {
1915*d4f2939cSRui Paulo 		  { "ifname", "s", ARG_IN },
1916*d4f2939cSRui Paulo 		  { "path", "o", ARG_OUT },
1917*d4f2939cSRui Paulo 		  END_ARGS
1918*d4f2939cSRui Paulo 	  }
1919*d4f2939cSRui Paulo 	},
1920*d4f2939cSRui Paulo #ifdef CONFIG_AUTOSCAN
1921*d4f2939cSRui Paulo 	{ "AutoScan", WPAS_DBUS_NEW_IFACE_INTERFACE,
1922*d4f2939cSRui Paulo 	  (WPADBusMethodHandler) &wpas_dbus_handler_autoscan,
1923*d4f2939cSRui Paulo 	  {
1924*d4f2939cSRui Paulo 		  { "arg", "s", ARG_IN },
1925*d4f2939cSRui Paulo 		  END_ARGS
1926*d4f2939cSRui Paulo 	  }
1927*d4f2939cSRui Paulo 	},
1928*d4f2939cSRui Paulo #endif /* CONFIG_AUTOSCAN */
1929*d4f2939cSRui Paulo 	{ NULL, NULL, NULL, { END_ARGS } }
1930*d4f2939cSRui Paulo };
1931*d4f2939cSRui Paulo 
1932*d4f2939cSRui Paulo static const struct wpa_dbus_property_desc wpas_dbus_global_properties[] = {
1933*d4f2939cSRui Paulo 	{ "DebugLevel", WPAS_DBUS_NEW_INTERFACE, "s",
1934*d4f2939cSRui Paulo 	  wpas_dbus_getter_debug_level,
1935*d4f2939cSRui Paulo 	  wpas_dbus_setter_debug_level
1936*d4f2939cSRui Paulo 	},
1937*d4f2939cSRui Paulo 	{ "DebugTimestamp", WPAS_DBUS_NEW_INTERFACE, "b",
1938*d4f2939cSRui Paulo 	  wpas_dbus_getter_debug_timestamp,
1939*d4f2939cSRui Paulo 	  wpas_dbus_setter_debug_timestamp
1940*d4f2939cSRui Paulo 	},
1941*d4f2939cSRui Paulo 	{ "DebugShowKeys", WPAS_DBUS_NEW_INTERFACE, "b",
1942*d4f2939cSRui Paulo 	  wpas_dbus_getter_debug_show_keys,
1943*d4f2939cSRui Paulo 	  wpas_dbus_setter_debug_show_keys
1944*d4f2939cSRui Paulo 	},
1945*d4f2939cSRui Paulo 	{ "Interfaces", WPAS_DBUS_NEW_INTERFACE, "ao",
1946*d4f2939cSRui Paulo 	  wpas_dbus_getter_interfaces,
1947*d4f2939cSRui Paulo 	  NULL
1948*d4f2939cSRui Paulo 	},
1949*d4f2939cSRui Paulo 	{ "EapMethods", WPAS_DBUS_NEW_INTERFACE, "as",
1950*d4f2939cSRui Paulo 	  wpas_dbus_getter_eap_methods,
1951*d4f2939cSRui Paulo 	  NULL
1952*d4f2939cSRui Paulo 	},
1953*d4f2939cSRui Paulo 	{ "Capabilities", WPAS_DBUS_NEW_INTERFACE, "as",
1954*d4f2939cSRui Paulo 	  wpas_dbus_getter_global_capabilities,
1955*d4f2939cSRui Paulo 	  NULL
1956*d4f2939cSRui Paulo 	},
1957*d4f2939cSRui Paulo 	{ NULL, NULL, NULL, NULL, NULL }
1958*d4f2939cSRui Paulo };
1959*d4f2939cSRui Paulo 
1960*d4f2939cSRui Paulo static const struct wpa_dbus_signal_desc wpas_dbus_global_signals[] = {
1961*d4f2939cSRui Paulo 	{ "InterfaceAdded", WPAS_DBUS_NEW_INTERFACE,
1962*d4f2939cSRui Paulo 	  {
1963*d4f2939cSRui Paulo 		  { "path", "o", ARG_OUT },
1964*d4f2939cSRui Paulo 		  { "properties", "a{sv}", ARG_OUT },
1965*d4f2939cSRui Paulo 		  END_ARGS
1966*d4f2939cSRui Paulo 	  }
1967*d4f2939cSRui Paulo 	},
1968*d4f2939cSRui Paulo 	{ "InterfaceRemoved", WPAS_DBUS_NEW_INTERFACE,
1969*d4f2939cSRui Paulo 	  {
1970*d4f2939cSRui Paulo 		  { "path", "o", ARG_OUT },
1971*d4f2939cSRui Paulo 		  END_ARGS
1972*d4f2939cSRui Paulo 	  }
1973*d4f2939cSRui Paulo 	},
1974*d4f2939cSRui Paulo 	{ "NetworkRequest", WPAS_DBUS_NEW_IFACE_INTERFACE,
1975*d4f2939cSRui Paulo 	  {
1976*d4f2939cSRui Paulo 		  { "path", "o", ARG_OUT },
1977*d4f2939cSRui Paulo 		  { "field", "s", ARG_OUT },
1978*d4f2939cSRui Paulo 		  { "text", "s", ARG_OUT },
1979*d4f2939cSRui Paulo 		  END_ARGS
1980*d4f2939cSRui Paulo 	  }
1981*d4f2939cSRui Paulo 	},
1982*d4f2939cSRui Paulo 	/* Deprecated: use org.freedesktop.DBus.Properties.PropertiesChanged */
1983*d4f2939cSRui Paulo 	{ "PropertiesChanged", WPAS_DBUS_NEW_INTERFACE,
1984*d4f2939cSRui Paulo 	  {
1985*d4f2939cSRui Paulo 		  { "properties", "a{sv}", ARG_OUT },
1986*d4f2939cSRui Paulo 		  END_ARGS
1987*d4f2939cSRui Paulo 	  }
1988*d4f2939cSRui Paulo 	},
1989*d4f2939cSRui Paulo 	{ NULL, NULL, { END_ARGS } }
1990*d4f2939cSRui Paulo };
1991*d4f2939cSRui Paulo 
1992*d4f2939cSRui Paulo 
1993*d4f2939cSRui Paulo /**
1994*d4f2939cSRui Paulo  * wpas_dbus_ctrl_iface_init - Initialize dbus control interface
1995*d4f2939cSRui Paulo  * @global: Pointer to global data from wpa_supplicant_init()
1996*d4f2939cSRui Paulo  * Returns: 0 on success or -1 on failure
1997*d4f2939cSRui Paulo  *
1998*d4f2939cSRui Paulo  * Initialize the dbus control interface for wpa_supplicantand and start
1999*d4f2939cSRui Paulo  * receiving commands from external programs over the bus.
2000*d4f2939cSRui Paulo  */
2001*d4f2939cSRui Paulo int wpas_dbus_ctrl_iface_init(struct wpas_dbus_priv *priv)
2002*d4f2939cSRui Paulo {
2003*d4f2939cSRui Paulo 	struct wpa_dbus_object_desc *obj_desc;
2004*d4f2939cSRui Paulo 	int ret;
2005*d4f2939cSRui Paulo 
2006*d4f2939cSRui Paulo 	obj_desc = os_zalloc(sizeof(struct wpa_dbus_object_desc));
2007*d4f2939cSRui Paulo 	if (!obj_desc) {
2008*d4f2939cSRui Paulo 		wpa_printf(MSG_ERROR, "Not enough memory "
2009*d4f2939cSRui Paulo 			   "to create object description");
2010*d4f2939cSRui Paulo 		return -1;
2011*d4f2939cSRui Paulo 	}
2012*d4f2939cSRui Paulo 
2013*d4f2939cSRui Paulo 	wpas_dbus_register(obj_desc, priv->global, NULL,
2014*d4f2939cSRui Paulo 			   wpas_dbus_global_methods,
2015*d4f2939cSRui Paulo 			   wpas_dbus_global_properties,
2016*d4f2939cSRui Paulo 			   wpas_dbus_global_signals);
2017*d4f2939cSRui Paulo 
2018*d4f2939cSRui Paulo 	wpa_printf(MSG_DEBUG, "dbus: Register D-Bus object '%s'",
2019*d4f2939cSRui Paulo 		   WPAS_DBUS_NEW_PATH);
2020*d4f2939cSRui Paulo 	ret = wpa_dbus_ctrl_iface_init(priv, WPAS_DBUS_NEW_PATH,
2021*d4f2939cSRui Paulo 				       WPAS_DBUS_NEW_SERVICE,
2022*d4f2939cSRui Paulo 				       obj_desc);
2023*d4f2939cSRui Paulo 	if (ret < 0)
2024*d4f2939cSRui Paulo 		free_dbus_object_desc(obj_desc);
2025*d4f2939cSRui Paulo 	else
2026*d4f2939cSRui Paulo 		priv->dbus_new_initialized = 1;
2027*d4f2939cSRui Paulo 
2028*d4f2939cSRui Paulo 	return ret;
2029*d4f2939cSRui Paulo }
2030*d4f2939cSRui Paulo 
2031*d4f2939cSRui Paulo 
2032*d4f2939cSRui Paulo /**
2033*d4f2939cSRui Paulo  * wpas_dbus_ctrl_iface_deinit - Deinitialize dbus ctrl interface for
2034*d4f2939cSRui Paulo  * wpa_supplicant
2035*d4f2939cSRui Paulo  * @iface: Pointer to dbus private data from wpas_dbus_init()
2036*d4f2939cSRui Paulo  *
2037*d4f2939cSRui Paulo  * Deinitialize the dbus control interface that was initialized with
2038*d4f2939cSRui Paulo  * wpas_dbus_ctrl_iface_init().
2039*d4f2939cSRui Paulo  */
2040*d4f2939cSRui Paulo void wpas_dbus_ctrl_iface_deinit(struct wpas_dbus_priv *iface)
2041*d4f2939cSRui Paulo {
2042*d4f2939cSRui Paulo 	if (!iface->dbus_new_initialized)
2043*d4f2939cSRui Paulo 		return;
2044*d4f2939cSRui Paulo 	wpa_printf(MSG_DEBUG, "dbus: Unregister D-Bus object '%s'",
2045*d4f2939cSRui Paulo 		   WPAS_DBUS_NEW_PATH);
2046*d4f2939cSRui Paulo 	dbus_connection_unregister_object_path(iface->con,
2047*d4f2939cSRui Paulo 					       WPAS_DBUS_NEW_PATH);
2048*d4f2939cSRui Paulo }
2049*d4f2939cSRui Paulo 
2050*d4f2939cSRui Paulo 
2051*d4f2939cSRui Paulo static void wpa_dbus_free(void *ptr)
2052*d4f2939cSRui Paulo {
2053*d4f2939cSRui Paulo 	os_free(ptr);
2054*d4f2939cSRui Paulo }
2055*d4f2939cSRui Paulo 
2056*d4f2939cSRui Paulo 
2057*d4f2939cSRui Paulo static const struct wpa_dbus_property_desc wpas_dbus_network_properties[] = {
2058*d4f2939cSRui Paulo 	{ "Properties", WPAS_DBUS_NEW_IFACE_NETWORK, "a{sv}",
2059*d4f2939cSRui Paulo 	  wpas_dbus_getter_network_properties,
2060*d4f2939cSRui Paulo 	  wpas_dbus_setter_network_properties
2061*d4f2939cSRui Paulo 	},
2062*d4f2939cSRui Paulo 	{ "Enabled", WPAS_DBUS_NEW_IFACE_NETWORK, "b",
2063*d4f2939cSRui Paulo 	  wpas_dbus_getter_enabled,
2064*d4f2939cSRui Paulo 	  wpas_dbus_setter_enabled
2065*d4f2939cSRui Paulo 	},
2066*d4f2939cSRui Paulo 	{ NULL, NULL, NULL, NULL, NULL }
2067*d4f2939cSRui Paulo };
2068*d4f2939cSRui Paulo 
2069*d4f2939cSRui Paulo 
2070*d4f2939cSRui Paulo static const struct wpa_dbus_signal_desc wpas_dbus_network_signals[] = {
2071*d4f2939cSRui Paulo 	/* Deprecated: use org.freedesktop.DBus.Properties.PropertiesChanged */
2072*d4f2939cSRui Paulo 	{ "PropertiesChanged", WPAS_DBUS_NEW_IFACE_NETWORK,
2073*d4f2939cSRui Paulo 	  {
2074*d4f2939cSRui Paulo 		  { "properties", "a{sv}", ARG_OUT },
2075*d4f2939cSRui Paulo 		  END_ARGS
2076*d4f2939cSRui Paulo 	  }
2077*d4f2939cSRui Paulo 	},
2078*d4f2939cSRui Paulo 	{ NULL, NULL, { END_ARGS } }
2079*d4f2939cSRui Paulo };
2080*d4f2939cSRui Paulo 
2081*d4f2939cSRui Paulo 
2082*d4f2939cSRui Paulo /**
2083*d4f2939cSRui Paulo  * wpas_dbus_register_network - Register a configured network with dbus
2084*d4f2939cSRui Paulo  * @wpa_s: wpa_supplicant interface structure
2085*d4f2939cSRui Paulo  * @ssid: network configuration data
2086*d4f2939cSRui Paulo  * Returns: 0 on success, -1 on failure
2087*d4f2939cSRui Paulo  *
2088*d4f2939cSRui Paulo  * Registers network representing object with dbus
2089*d4f2939cSRui Paulo  */
2090*d4f2939cSRui Paulo int wpas_dbus_register_network(struct wpa_supplicant *wpa_s,
2091*d4f2939cSRui Paulo 			       struct wpa_ssid *ssid)
2092*d4f2939cSRui Paulo {
2093*d4f2939cSRui Paulo 	struct wpas_dbus_priv *ctrl_iface;
2094*d4f2939cSRui Paulo 	struct wpa_dbus_object_desc *obj_desc;
2095*d4f2939cSRui Paulo 	struct network_handler_args *arg;
2096*d4f2939cSRui Paulo 	char net_obj_path[WPAS_DBUS_OBJECT_PATH_MAX];
2097*d4f2939cSRui Paulo 
2098*d4f2939cSRui Paulo #ifdef CONFIG_P2P
2099*d4f2939cSRui Paulo 	/*
2100*d4f2939cSRui Paulo 	 * If it is a persistent group register it as such.
2101*d4f2939cSRui Paulo 	 * This is to handle cases where an interface is being initialized
2102*d4f2939cSRui Paulo 	 * with a list of networks read from config.
2103*d4f2939cSRui Paulo 	 */
2104*d4f2939cSRui Paulo 	if (network_is_persistent_group(ssid))
2105*d4f2939cSRui Paulo 		return wpas_dbus_register_persistent_group(wpa_s, ssid);
2106*d4f2939cSRui Paulo #endif /* CONFIG_P2P */
2107*d4f2939cSRui Paulo 
2108*d4f2939cSRui Paulo 	/* Do nothing if the control interface is not turned on */
2109*d4f2939cSRui Paulo 	if (wpa_s == NULL || wpa_s->global == NULL)
2110*d4f2939cSRui Paulo 		return 0;
2111*d4f2939cSRui Paulo 	ctrl_iface = wpa_s->global->dbus;
2112*d4f2939cSRui Paulo 	if (ctrl_iface == NULL)
2113*d4f2939cSRui Paulo 		return 0;
2114*d4f2939cSRui Paulo 
2115*d4f2939cSRui Paulo 	os_snprintf(net_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
2116*d4f2939cSRui Paulo 		    "%s/" WPAS_DBUS_NEW_NETWORKS_PART "/%u",
2117*d4f2939cSRui Paulo 		    wpa_s->dbus_new_path, ssid->id);
2118*d4f2939cSRui Paulo 
2119*d4f2939cSRui Paulo 	wpa_printf(MSG_DEBUG, "dbus: Register network object '%s'",
2120*d4f2939cSRui Paulo 		   net_obj_path);
2121*d4f2939cSRui Paulo 	obj_desc = os_zalloc(sizeof(struct wpa_dbus_object_desc));
2122*d4f2939cSRui Paulo 	if (!obj_desc) {
2123*d4f2939cSRui Paulo 		wpa_printf(MSG_ERROR, "Not enough memory "
2124*d4f2939cSRui Paulo 			   "to create object description");
2125*d4f2939cSRui Paulo 		goto err;
2126*d4f2939cSRui Paulo 	}
2127*d4f2939cSRui Paulo 
2128*d4f2939cSRui Paulo 	/* allocate memory for handlers arguments */
2129*d4f2939cSRui Paulo 	arg = os_zalloc(sizeof(struct network_handler_args));
2130*d4f2939cSRui Paulo 	if (!arg) {
2131*d4f2939cSRui Paulo 		wpa_printf(MSG_ERROR, "Not enough memory "
2132*d4f2939cSRui Paulo 			   "to create arguments for method");
2133*d4f2939cSRui Paulo 		goto err;
2134*d4f2939cSRui Paulo 	}
2135*d4f2939cSRui Paulo 
2136*d4f2939cSRui Paulo 	arg->wpa_s = wpa_s;
2137*d4f2939cSRui Paulo 	arg->ssid = ssid;
2138*d4f2939cSRui Paulo 
2139*d4f2939cSRui Paulo 	wpas_dbus_register(obj_desc, arg, wpa_dbus_free, NULL,
2140*d4f2939cSRui Paulo 			   wpas_dbus_network_properties,
2141*d4f2939cSRui Paulo 			   wpas_dbus_network_signals);
2142*d4f2939cSRui Paulo 
2143*d4f2939cSRui Paulo 	if (wpa_dbus_register_object_per_iface(ctrl_iface, net_obj_path,
2144*d4f2939cSRui Paulo 					       wpa_s->ifname, obj_desc))
2145*d4f2939cSRui Paulo 		goto err;
2146*d4f2939cSRui Paulo 
2147*d4f2939cSRui Paulo 	wpas_dbus_signal_network_added(wpa_s, ssid->id);
2148*d4f2939cSRui Paulo 
2149*d4f2939cSRui Paulo 	return 0;
2150*d4f2939cSRui Paulo 
2151*d4f2939cSRui Paulo err:
2152*d4f2939cSRui Paulo 	free_dbus_object_desc(obj_desc);
2153*d4f2939cSRui Paulo 	return -1;
2154*d4f2939cSRui Paulo }
2155*d4f2939cSRui Paulo 
2156*d4f2939cSRui Paulo 
2157*d4f2939cSRui Paulo /**
2158*d4f2939cSRui Paulo  * wpas_dbus_unregister_network - Unregister a configured network from dbus
2159*d4f2939cSRui Paulo  * @wpa_s: wpa_supplicant interface structure
2160*d4f2939cSRui Paulo  * @nid: network id
2161*d4f2939cSRui Paulo  * Returns: 0 on success, -1 on failure
2162*d4f2939cSRui Paulo  *
2163*d4f2939cSRui Paulo  * Unregisters network representing object from dbus
2164*d4f2939cSRui Paulo  */
2165*d4f2939cSRui Paulo int wpas_dbus_unregister_network(struct wpa_supplicant *wpa_s, int nid)
2166*d4f2939cSRui Paulo {
2167*d4f2939cSRui Paulo 	struct wpas_dbus_priv *ctrl_iface;
2168*d4f2939cSRui Paulo 	char net_obj_path[WPAS_DBUS_OBJECT_PATH_MAX];
2169*d4f2939cSRui Paulo 	int ret;
2170*d4f2939cSRui Paulo #ifdef CONFIG_P2P
2171*d4f2939cSRui Paulo 	struct wpa_ssid *ssid;
2172*d4f2939cSRui Paulo 
2173*d4f2939cSRui Paulo 	ssid = wpa_config_get_network(wpa_s->conf, nid);
2174*d4f2939cSRui Paulo 
2175*d4f2939cSRui Paulo 	/* If it is a persistent group unregister it as such */
2176*d4f2939cSRui Paulo 	if (ssid && network_is_persistent_group(ssid))
2177*d4f2939cSRui Paulo 		return wpas_dbus_unregister_persistent_group(wpa_s, nid);
2178*d4f2939cSRui Paulo #endif /* CONFIG_P2P */
2179*d4f2939cSRui Paulo 
2180*d4f2939cSRui Paulo 	/* Do nothing if the control interface is not turned on */
2181*d4f2939cSRui Paulo 	if (wpa_s->global == NULL || wpa_s->dbus_new_path == NULL)
2182*d4f2939cSRui Paulo 		return 0;
2183*d4f2939cSRui Paulo 	ctrl_iface = wpa_s->global->dbus;
2184*d4f2939cSRui Paulo 	if (ctrl_iface == NULL)
2185*d4f2939cSRui Paulo 		return 0;
2186*d4f2939cSRui Paulo 
2187*d4f2939cSRui Paulo 	os_snprintf(net_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
2188*d4f2939cSRui Paulo 		    "%s/" WPAS_DBUS_NEW_NETWORKS_PART "/%u",
2189*d4f2939cSRui Paulo 		    wpa_s->dbus_new_path, nid);
2190*d4f2939cSRui Paulo 
2191*d4f2939cSRui Paulo 	wpa_printf(MSG_DEBUG, "dbus: Unregister network object '%s'",
2192*d4f2939cSRui Paulo 		   net_obj_path);
2193*d4f2939cSRui Paulo 	ret = wpa_dbus_unregister_object_per_iface(ctrl_iface, net_obj_path);
2194*d4f2939cSRui Paulo 
2195*d4f2939cSRui Paulo 	if (!ret)
2196*d4f2939cSRui Paulo 		wpas_dbus_signal_network_removed(wpa_s, nid);
2197*d4f2939cSRui Paulo 
2198*d4f2939cSRui Paulo 	return ret;
2199*d4f2939cSRui Paulo }
2200*d4f2939cSRui Paulo 
2201*d4f2939cSRui Paulo 
2202*d4f2939cSRui Paulo static const struct wpa_dbus_property_desc wpas_dbus_bss_properties[] = {
2203*d4f2939cSRui Paulo 	{ "SSID", WPAS_DBUS_NEW_IFACE_BSS, "ay",
2204*d4f2939cSRui Paulo 	  wpas_dbus_getter_bss_ssid,
2205*d4f2939cSRui Paulo 	  NULL
2206*d4f2939cSRui Paulo 	},
2207*d4f2939cSRui Paulo 	{ "BSSID", WPAS_DBUS_NEW_IFACE_BSS, "ay",
2208*d4f2939cSRui Paulo 	  wpas_dbus_getter_bss_bssid,
2209*d4f2939cSRui Paulo 	  NULL
2210*d4f2939cSRui Paulo 	},
2211*d4f2939cSRui Paulo 	{ "Privacy", WPAS_DBUS_NEW_IFACE_BSS, "b",
2212*d4f2939cSRui Paulo 	  wpas_dbus_getter_bss_privacy,
2213*d4f2939cSRui Paulo 	  NULL
2214*d4f2939cSRui Paulo 	},
2215*d4f2939cSRui Paulo 	{ "Mode", WPAS_DBUS_NEW_IFACE_BSS, "s",
2216*d4f2939cSRui Paulo 	  wpas_dbus_getter_bss_mode,
2217*d4f2939cSRui Paulo 	  NULL
2218*d4f2939cSRui Paulo 	},
2219*d4f2939cSRui Paulo 	{ "Signal", WPAS_DBUS_NEW_IFACE_BSS, "n",
2220*d4f2939cSRui Paulo 	  wpas_dbus_getter_bss_signal,
2221*d4f2939cSRui Paulo 	  NULL
2222*d4f2939cSRui Paulo 	},
2223*d4f2939cSRui Paulo 	{ "Frequency", WPAS_DBUS_NEW_IFACE_BSS, "q",
2224*d4f2939cSRui Paulo 	  wpas_dbus_getter_bss_frequency,
2225*d4f2939cSRui Paulo 	  NULL
2226*d4f2939cSRui Paulo 	},
2227*d4f2939cSRui Paulo 	{ "Rates", WPAS_DBUS_NEW_IFACE_BSS, "au",
2228*d4f2939cSRui Paulo 	  wpas_dbus_getter_bss_rates,
2229*d4f2939cSRui Paulo 	  NULL
2230*d4f2939cSRui Paulo 	},
2231*d4f2939cSRui Paulo 	{ "WPA", WPAS_DBUS_NEW_IFACE_BSS, "a{sv}",
2232*d4f2939cSRui Paulo 	  wpas_dbus_getter_bss_wpa,
2233*d4f2939cSRui Paulo 	  NULL
2234*d4f2939cSRui Paulo 	},
2235*d4f2939cSRui Paulo 	{ "RSN", WPAS_DBUS_NEW_IFACE_BSS, "a{sv}",
2236*d4f2939cSRui Paulo 	  wpas_dbus_getter_bss_rsn,
2237*d4f2939cSRui Paulo 	  NULL
2238*d4f2939cSRui Paulo 	},
2239*d4f2939cSRui Paulo 	{ "WPS", WPAS_DBUS_NEW_IFACE_BSS, "a{sv}",
2240*d4f2939cSRui Paulo 	  wpas_dbus_getter_bss_wps,
2241*d4f2939cSRui Paulo 	  NULL
2242*d4f2939cSRui Paulo 	},
2243*d4f2939cSRui Paulo 	{ "IEs", WPAS_DBUS_NEW_IFACE_BSS, "ay",
2244*d4f2939cSRui Paulo 	  wpas_dbus_getter_bss_ies,
2245*d4f2939cSRui Paulo 	  NULL
2246*d4f2939cSRui Paulo 	},
2247*d4f2939cSRui Paulo 	{ NULL, NULL, NULL, NULL, NULL }
2248*d4f2939cSRui Paulo };
2249*d4f2939cSRui Paulo 
2250*d4f2939cSRui Paulo 
2251*d4f2939cSRui Paulo static const struct wpa_dbus_signal_desc wpas_dbus_bss_signals[] = {
2252*d4f2939cSRui Paulo 	/* Deprecated: use org.freedesktop.DBus.Properties.PropertiesChanged */
2253*d4f2939cSRui Paulo 	{ "PropertiesChanged", WPAS_DBUS_NEW_IFACE_BSS,
2254*d4f2939cSRui Paulo 	  {
2255*d4f2939cSRui Paulo 		  { "properties", "a{sv}", ARG_OUT },
2256*d4f2939cSRui Paulo 		  END_ARGS
2257*d4f2939cSRui Paulo 	  }
2258*d4f2939cSRui Paulo 	},
2259*d4f2939cSRui Paulo 	{ NULL, NULL, { END_ARGS } }
2260*d4f2939cSRui Paulo };
2261*d4f2939cSRui Paulo 
2262*d4f2939cSRui Paulo 
2263*d4f2939cSRui Paulo /**
2264*d4f2939cSRui Paulo  * wpas_dbus_unregister_bss - Unregister a scanned BSS from dbus
2265*d4f2939cSRui Paulo  * @wpa_s: wpa_supplicant interface structure
2266*d4f2939cSRui Paulo  * @bssid: scanned network bssid
2267*d4f2939cSRui Paulo  * @id: unique BSS identifier
2268*d4f2939cSRui Paulo  * Returns: 0 on success, -1 on failure
2269*d4f2939cSRui Paulo  *
2270*d4f2939cSRui Paulo  * Unregisters BSS representing object from dbus
2271*d4f2939cSRui Paulo  */
2272*d4f2939cSRui Paulo int wpas_dbus_unregister_bss(struct wpa_supplicant *wpa_s,
2273*d4f2939cSRui Paulo 			     u8 bssid[ETH_ALEN], unsigned int id)
2274*d4f2939cSRui Paulo {
2275*d4f2939cSRui Paulo 	struct wpas_dbus_priv *ctrl_iface;
2276*d4f2939cSRui Paulo 	char bss_obj_path[WPAS_DBUS_OBJECT_PATH_MAX];
2277*d4f2939cSRui Paulo 
2278*d4f2939cSRui Paulo 	/* Do nothing if the control interface is not turned on */
2279*d4f2939cSRui Paulo 	if (wpa_s == NULL || wpa_s->global == NULL)
2280*d4f2939cSRui Paulo 		return 0;
2281*d4f2939cSRui Paulo 	ctrl_iface = wpa_s->global->dbus;
2282*d4f2939cSRui Paulo 	if (ctrl_iface == NULL)
2283*d4f2939cSRui Paulo 		return 0;
2284*d4f2939cSRui Paulo 
2285*d4f2939cSRui Paulo 	os_snprintf(bss_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
2286*d4f2939cSRui Paulo 		    "%s/" WPAS_DBUS_NEW_BSSIDS_PART "/%u",
2287*d4f2939cSRui Paulo 		    wpa_s->dbus_new_path, id);
2288*d4f2939cSRui Paulo 
2289*d4f2939cSRui Paulo 	wpa_printf(MSG_DEBUG, "dbus: Unregister BSS object '%s'",
2290*d4f2939cSRui Paulo 		   bss_obj_path);
2291*d4f2939cSRui Paulo 	if (wpa_dbus_unregister_object_per_iface(ctrl_iface, bss_obj_path)) {
2292*d4f2939cSRui Paulo 		wpa_printf(MSG_ERROR, "dbus: Cannot unregister BSS object %s",
2293*d4f2939cSRui Paulo 			   bss_obj_path);
2294*d4f2939cSRui Paulo 		return -1;
2295*d4f2939cSRui Paulo 	}
2296*d4f2939cSRui Paulo 
2297*d4f2939cSRui Paulo 	wpas_dbus_signal_bss_removed(wpa_s, bss_obj_path);
2298*d4f2939cSRui Paulo 	wpas_dbus_signal_prop_changed(wpa_s, WPAS_DBUS_PROP_BSSS);
2299*d4f2939cSRui Paulo 
2300*d4f2939cSRui Paulo 	return 0;
2301*d4f2939cSRui Paulo }
2302*d4f2939cSRui Paulo 
2303*d4f2939cSRui Paulo 
2304*d4f2939cSRui Paulo /**
2305*d4f2939cSRui Paulo  * wpas_dbus_register_bss - Register a scanned BSS with dbus
2306*d4f2939cSRui Paulo  * @wpa_s: wpa_supplicant interface structure
2307*d4f2939cSRui Paulo  * @bssid: scanned network bssid
2308*d4f2939cSRui Paulo  * @id: unique BSS identifier
2309*d4f2939cSRui Paulo  * Returns: 0 on success, -1 on failure
2310*d4f2939cSRui Paulo  *
2311*d4f2939cSRui Paulo  * Registers BSS representing object with dbus
2312*d4f2939cSRui Paulo  */
2313*d4f2939cSRui Paulo int wpas_dbus_register_bss(struct wpa_supplicant *wpa_s,
2314*d4f2939cSRui Paulo 			   u8 bssid[ETH_ALEN], unsigned int id)
2315*d4f2939cSRui Paulo {
2316*d4f2939cSRui Paulo 	struct wpas_dbus_priv *ctrl_iface;
2317*d4f2939cSRui Paulo 	struct wpa_dbus_object_desc *obj_desc;
2318*d4f2939cSRui Paulo 	char bss_obj_path[WPAS_DBUS_OBJECT_PATH_MAX];
2319*d4f2939cSRui Paulo 	struct bss_handler_args *arg;
2320*d4f2939cSRui Paulo 
2321*d4f2939cSRui Paulo 	/* Do nothing if the control interface is not turned on */
2322*d4f2939cSRui Paulo 	if (wpa_s == NULL || wpa_s->global == NULL)
2323*d4f2939cSRui Paulo 		return 0;
2324*d4f2939cSRui Paulo 	ctrl_iface = wpa_s->global->dbus;
2325*d4f2939cSRui Paulo 	if (ctrl_iface == NULL)
2326*d4f2939cSRui Paulo 		return 0;
2327*d4f2939cSRui Paulo 
2328*d4f2939cSRui Paulo 	os_snprintf(bss_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
2329*d4f2939cSRui Paulo 		    "%s/" WPAS_DBUS_NEW_BSSIDS_PART "/%u",
2330*d4f2939cSRui Paulo 		    wpa_s->dbus_new_path, id);
2331*d4f2939cSRui Paulo 
2332*d4f2939cSRui Paulo 	obj_desc = os_zalloc(sizeof(struct wpa_dbus_object_desc));
2333*d4f2939cSRui Paulo 	if (!obj_desc) {
2334*d4f2939cSRui Paulo 		wpa_printf(MSG_ERROR, "Not enough memory "
2335*d4f2939cSRui Paulo 			   "to create object description");
2336*d4f2939cSRui Paulo 		goto err;
2337*d4f2939cSRui Paulo 	}
2338*d4f2939cSRui Paulo 
2339*d4f2939cSRui Paulo 	arg = os_zalloc(sizeof(struct bss_handler_args));
2340*d4f2939cSRui Paulo 	if (!arg) {
2341*d4f2939cSRui Paulo 		wpa_printf(MSG_ERROR, "Not enough memory "
2342*d4f2939cSRui Paulo 			   "to create arguments for handler");
2343*d4f2939cSRui Paulo 		goto err;
2344*d4f2939cSRui Paulo 	}
2345*d4f2939cSRui Paulo 	arg->wpa_s = wpa_s;
2346*d4f2939cSRui Paulo 	arg->id = id;
2347*d4f2939cSRui Paulo 
2348*d4f2939cSRui Paulo 	wpas_dbus_register(obj_desc, arg, wpa_dbus_free, NULL,
2349*d4f2939cSRui Paulo 			   wpas_dbus_bss_properties,
2350*d4f2939cSRui Paulo 			   wpas_dbus_bss_signals);
2351*d4f2939cSRui Paulo 
2352*d4f2939cSRui Paulo 	wpa_printf(MSG_DEBUG, "dbus: Register BSS object '%s'",
2353*d4f2939cSRui Paulo 		   bss_obj_path);
2354*d4f2939cSRui Paulo 	if (wpa_dbus_register_object_per_iface(ctrl_iface, bss_obj_path,
2355*d4f2939cSRui Paulo 					       wpa_s->ifname, obj_desc)) {
2356*d4f2939cSRui Paulo 		wpa_printf(MSG_ERROR,
2357*d4f2939cSRui Paulo 			   "Cannot register BSSID dbus object %s.",
2358*d4f2939cSRui Paulo 			   bss_obj_path);
2359*d4f2939cSRui Paulo 		goto err;
2360*d4f2939cSRui Paulo 	}
2361*d4f2939cSRui Paulo 
2362*d4f2939cSRui Paulo 	wpas_dbus_signal_bss_added(wpa_s, bss_obj_path);
2363*d4f2939cSRui Paulo 	wpas_dbus_signal_prop_changed(wpa_s, WPAS_DBUS_PROP_BSSS);
2364*d4f2939cSRui Paulo 
2365*d4f2939cSRui Paulo 	return 0;
2366*d4f2939cSRui Paulo 
2367*d4f2939cSRui Paulo err:
2368*d4f2939cSRui Paulo 	free_dbus_object_desc(obj_desc);
2369*d4f2939cSRui Paulo 	return -1;
2370*d4f2939cSRui Paulo }
2371*d4f2939cSRui Paulo 
2372*d4f2939cSRui Paulo 
2373*d4f2939cSRui Paulo static const struct wpa_dbus_method_desc wpas_dbus_interface_methods[] = {
2374*d4f2939cSRui Paulo 	{ "Scan", WPAS_DBUS_NEW_IFACE_INTERFACE,
2375*d4f2939cSRui Paulo 	  (WPADBusMethodHandler) &wpas_dbus_handler_scan,
2376*d4f2939cSRui Paulo 	  {
2377*d4f2939cSRui Paulo 		  { "args", "a{sv}", ARG_IN },
2378*d4f2939cSRui Paulo 		  END_ARGS
2379*d4f2939cSRui Paulo 	  }
2380*d4f2939cSRui Paulo 	},
2381*d4f2939cSRui Paulo 	{ "Disconnect", WPAS_DBUS_NEW_IFACE_INTERFACE,
2382*d4f2939cSRui Paulo 	  (WPADBusMethodHandler) &wpas_dbus_handler_disconnect,
2383*d4f2939cSRui Paulo 	  {
2384*d4f2939cSRui Paulo 		  END_ARGS
2385*d4f2939cSRui Paulo 	  }
2386*d4f2939cSRui Paulo 	},
2387*d4f2939cSRui Paulo 	{ "AddNetwork", WPAS_DBUS_NEW_IFACE_INTERFACE,
2388*d4f2939cSRui Paulo 	  (WPADBusMethodHandler) &wpas_dbus_handler_add_network,
2389*d4f2939cSRui Paulo 	  {
2390*d4f2939cSRui Paulo 		  { "args", "a{sv}", ARG_IN },
2391*d4f2939cSRui Paulo 		  { "path", "o", ARG_OUT },
2392*d4f2939cSRui Paulo 		  END_ARGS
2393*d4f2939cSRui Paulo 	  }
2394*d4f2939cSRui Paulo 	},
2395*d4f2939cSRui Paulo 	{ "Reassociate", WPAS_DBUS_NEW_IFACE_INTERFACE,
2396*d4f2939cSRui Paulo 	  (WPADBusMethodHandler) &wpas_dbus_handler_reassociate,
2397*d4f2939cSRui Paulo 	  {
2398*d4f2939cSRui Paulo 		  END_ARGS
2399*d4f2939cSRui Paulo 	  }
2400*d4f2939cSRui Paulo 	},
2401*d4f2939cSRui Paulo 	{ "RemoveNetwork", WPAS_DBUS_NEW_IFACE_INTERFACE,
2402*d4f2939cSRui Paulo 	  (WPADBusMethodHandler) &wpas_dbus_handler_remove_network,
2403*d4f2939cSRui Paulo 	  {
2404*d4f2939cSRui Paulo 		  { "path", "o", ARG_IN },
2405*d4f2939cSRui Paulo 		  END_ARGS
2406*d4f2939cSRui Paulo 	  }
2407*d4f2939cSRui Paulo 	},
2408*d4f2939cSRui Paulo 	{ "RemoveAllNetworks", WPAS_DBUS_NEW_IFACE_INTERFACE,
2409*d4f2939cSRui Paulo 	  (WPADBusMethodHandler) &wpas_dbus_handler_remove_all_networks,
2410*d4f2939cSRui Paulo 	  {
2411*d4f2939cSRui Paulo 		  END_ARGS
2412*d4f2939cSRui Paulo 	  }
2413*d4f2939cSRui Paulo 	},
2414*d4f2939cSRui Paulo 	{ "SelectNetwork", WPAS_DBUS_NEW_IFACE_INTERFACE,
2415*d4f2939cSRui Paulo 	  (WPADBusMethodHandler) &wpas_dbus_handler_select_network,
2416*d4f2939cSRui Paulo 	  {
2417*d4f2939cSRui Paulo 		  { "path", "o", ARG_IN },
2418*d4f2939cSRui Paulo 		  END_ARGS
2419*d4f2939cSRui Paulo 	  }
2420*d4f2939cSRui Paulo 	},
2421*d4f2939cSRui Paulo 	{ "NetworkReply", WPAS_DBUS_NEW_IFACE_INTERFACE,
2422*d4f2939cSRui Paulo 	  (WPADBusMethodHandler) &wpas_dbus_handler_network_reply,
2423*d4f2939cSRui Paulo 	  {
2424*d4f2939cSRui Paulo 		  { "path", "o", ARG_IN },
2425*d4f2939cSRui Paulo 		  { "field", "s", ARG_IN },
2426*d4f2939cSRui Paulo 		  { "value", "s", ARG_IN },
2427*d4f2939cSRui Paulo 		  END_ARGS
2428*d4f2939cSRui Paulo 	  }
2429*d4f2939cSRui Paulo 	},
2430*d4f2939cSRui Paulo 	{ "AddBlob", WPAS_DBUS_NEW_IFACE_INTERFACE,
2431*d4f2939cSRui Paulo 	  (WPADBusMethodHandler) &wpas_dbus_handler_add_blob,
2432*d4f2939cSRui Paulo 	  {
2433*d4f2939cSRui Paulo 		  { "name", "s", ARG_IN },
2434*d4f2939cSRui Paulo 		  { "data", "ay", ARG_IN },
2435*d4f2939cSRui Paulo 		  END_ARGS
2436*d4f2939cSRui Paulo 	  }
2437*d4f2939cSRui Paulo 	},
2438*d4f2939cSRui Paulo 	{ "GetBlob", WPAS_DBUS_NEW_IFACE_INTERFACE,
2439*d4f2939cSRui Paulo 	  (WPADBusMethodHandler) &wpas_dbus_handler_get_blob,
2440*d4f2939cSRui Paulo 	  {
2441*d4f2939cSRui Paulo 		  { "name", "s", ARG_IN },
2442*d4f2939cSRui Paulo 		  { "data", "ay", ARG_OUT },
2443*d4f2939cSRui Paulo 		  END_ARGS
2444*d4f2939cSRui Paulo 	  }
2445*d4f2939cSRui Paulo 	},
2446*d4f2939cSRui Paulo 	{ "RemoveBlob", WPAS_DBUS_NEW_IFACE_INTERFACE,
2447*d4f2939cSRui Paulo 	  (WPADBusMethodHandler) &wpas_dbus_handler_remove_blob,
2448*d4f2939cSRui Paulo 	  {
2449*d4f2939cSRui Paulo 		  { "name", "s", ARG_IN },
2450*d4f2939cSRui Paulo 		  END_ARGS
2451*d4f2939cSRui Paulo 	  }
2452*d4f2939cSRui Paulo 	},
2453*d4f2939cSRui Paulo #ifdef CONFIG_WPS
2454*d4f2939cSRui Paulo 	{ "Start", WPAS_DBUS_NEW_IFACE_WPS,
2455*d4f2939cSRui Paulo 	  (WPADBusMethodHandler) &wpas_dbus_handler_wps_start,
2456*d4f2939cSRui Paulo 	  {
2457*d4f2939cSRui Paulo 		  { "args", "a{sv}", ARG_IN },
2458*d4f2939cSRui Paulo 		  { "output", "a{sv}", ARG_OUT },
2459*d4f2939cSRui Paulo 		  END_ARGS
2460*d4f2939cSRui Paulo 	  }
2461*d4f2939cSRui Paulo 	},
2462*d4f2939cSRui Paulo #endif /* CONFIG_WPS */
2463*d4f2939cSRui Paulo #ifdef CONFIG_P2P
2464*d4f2939cSRui Paulo 	{ "Find", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
2465*d4f2939cSRui Paulo 	  (WPADBusMethodHandler)wpas_dbus_handler_p2p_find,
2466*d4f2939cSRui Paulo 	  {
2467*d4f2939cSRui Paulo 		  { "args", "a{sv}", ARG_IN },
2468*d4f2939cSRui Paulo 		  END_ARGS
2469*d4f2939cSRui Paulo 	  }
2470*d4f2939cSRui Paulo 	},
2471*d4f2939cSRui Paulo 	{ "StopFind", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
2472*d4f2939cSRui Paulo 	  (WPADBusMethodHandler)wpas_dbus_handler_p2p_stop_find,
2473*d4f2939cSRui Paulo 	  {
2474*d4f2939cSRui Paulo 		  END_ARGS
2475*d4f2939cSRui Paulo 	  }
2476*d4f2939cSRui Paulo 	},
2477*d4f2939cSRui Paulo 	{ "Listen", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
2478*d4f2939cSRui Paulo 	  (WPADBusMethodHandler)wpas_dbus_handler_p2p_listen,
2479*d4f2939cSRui Paulo 	  {
2480*d4f2939cSRui Paulo 		  { "timeout", "i", ARG_IN },
2481*d4f2939cSRui Paulo 		  END_ARGS
2482*d4f2939cSRui Paulo 	  }
2483*d4f2939cSRui Paulo 	},
2484*d4f2939cSRui Paulo 	{ "ExtendedListen", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
2485*d4f2939cSRui Paulo 	  (WPADBusMethodHandler)wpas_dbus_handler_p2p_extendedlisten,
2486*d4f2939cSRui Paulo 	  {
2487*d4f2939cSRui Paulo 		  { "args", "a{sv}", ARG_IN },
2488*d4f2939cSRui Paulo 		  END_ARGS
2489*d4f2939cSRui Paulo 	  }
2490*d4f2939cSRui Paulo 	},
2491*d4f2939cSRui Paulo 	{ "PresenceRequest", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
2492*d4f2939cSRui Paulo 	  (WPADBusMethodHandler)wpas_dbus_handler_p2p_presence_request,
2493*d4f2939cSRui Paulo 	  {
2494*d4f2939cSRui Paulo 		  { "args", "a{sv}", ARG_IN },
2495*d4f2939cSRui Paulo 		  END_ARGS
2496*d4f2939cSRui Paulo 	  }
2497*d4f2939cSRui Paulo 	},
2498*d4f2939cSRui Paulo 	{ "ProvisionDiscoveryRequest", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
2499*d4f2939cSRui Paulo 	  (WPADBusMethodHandler)wpas_dbus_handler_p2p_prov_disc_req,
2500*d4f2939cSRui Paulo 	  {
2501*d4f2939cSRui Paulo 		  { "peer", "o", ARG_IN },
2502*d4f2939cSRui Paulo 		  { "config_method", "s", ARG_IN },
2503*d4f2939cSRui Paulo 		  END_ARGS
2504*d4f2939cSRui Paulo 	  }
2505*d4f2939cSRui Paulo 	},
2506*d4f2939cSRui Paulo 	{ "Connect", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
2507*d4f2939cSRui Paulo 	  (WPADBusMethodHandler)wpas_dbus_handler_p2p_connect,
2508*d4f2939cSRui Paulo 	  {
2509*d4f2939cSRui Paulo 		  { "args", "a{sv}", ARG_IN },
2510*d4f2939cSRui Paulo 		  { "generated_pin", "s", ARG_OUT },
2511*d4f2939cSRui Paulo 		  END_ARGS
2512*d4f2939cSRui Paulo 	  }
2513*d4f2939cSRui Paulo 	},
2514*d4f2939cSRui Paulo 	{ "GroupAdd", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
2515*d4f2939cSRui Paulo 	  (WPADBusMethodHandler)wpas_dbus_handler_p2p_group_add,
2516*d4f2939cSRui Paulo 	  {
2517*d4f2939cSRui Paulo 		  { "args", "a{sv}", ARG_IN },
2518*d4f2939cSRui Paulo 		  END_ARGS
2519*d4f2939cSRui Paulo 	  }
2520*d4f2939cSRui Paulo 	},
2521*d4f2939cSRui Paulo 	{ "Invite", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
2522*d4f2939cSRui Paulo 	  (WPADBusMethodHandler)wpas_dbus_handler_p2p_invite,
2523*d4f2939cSRui Paulo 	  {
2524*d4f2939cSRui Paulo 		  { "args", "a{sv}", ARG_IN },
2525*d4f2939cSRui Paulo 		  END_ARGS
2526*d4f2939cSRui Paulo 	  }
2527*d4f2939cSRui Paulo 	},
2528*d4f2939cSRui Paulo 	{ "Disconnect", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
2529*d4f2939cSRui Paulo 	  (WPADBusMethodHandler)wpas_dbus_handler_p2p_disconnect,
2530*d4f2939cSRui Paulo 	  {
2531*d4f2939cSRui Paulo 		  END_ARGS
2532*d4f2939cSRui Paulo 	  }
2533*d4f2939cSRui Paulo 	},
2534*d4f2939cSRui Paulo 	{ "RejectPeer", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
2535*d4f2939cSRui Paulo 	  (WPADBusMethodHandler)wpas_dbus_handler_p2p_rejectpeer,
2536*d4f2939cSRui Paulo 	  {
2537*d4f2939cSRui Paulo 		  { "peer", "o", ARG_IN },
2538*d4f2939cSRui Paulo 		  END_ARGS
2539*d4f2939cSRui Paulo 	  }
2540*d4f2939cSRui Paulo 	},
2541*d4f2939cSRui Paulo 	{ "Flush", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
2542*d4f2939cSRui Paulo 	  (WPADBusMethodHandler)wpas_dbus_handler_p2p_flush,
2543*d4f2939cSRui Paulo 	  {
2544*d4f2939cSRui Paulo 		  END_ARGS
2545*d4f2939cSRui Paulo 	  }
2546*d4f2939cSRui Paulo 	},
2547*d4f2939cSRui Paulo 	{ "AddService", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
2548*d4f2939cSRui Paulo 	  (WPADBusMethodHandler)wpas_dbus_handler_p2p_add_service,
2549*d4f2939cSRui Paulo 	  {
2550*d4f2939cSRui Paulo 		  { "args", "a{sv}", ARG_IN },
2551*d4f2939cSRui Paulo 		  END_ARGS
2552*d4f2939cSRui Paulo 	  }
2553*d4f2939cSRui Paulo 	},
2554*d4f2939cSRui Paulo 	{ "DeleteService", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
2555*d4f2939cSRui Paulo 	  (WPADBusMethodHandler)wpas_dbus_handler_p2p_delete_service,
2556*d4f2939cSRui Paulo 	  {
2557*d4f2939cSRui Paulo 		  { "args", "a{sv}", ARG_IN },
2558*d4f2939cSRui Paulo 		  END_ARGS
2559*d4f2939cSRui Paulo 	  }
2560*d4f2939cSRui Paulo 	},
2561*d4f2939cSRui Paulo 	{ "FlushService", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
2562*d4f2939cSRui Paulo 	  (WPADBusMethodHandler)wpas_dbus_handler_p2p_flush_service,
2563*d4f2939cSRui Paulo 	  {
2564*d4f2939cSRui Paulo 		  END_ARGS
2565*d4f2939cSRui Paulo 	  }
2566*d4f2939cSRui Paulo 	},
2567*d4f2939cSRui Paulo 	{ "ServiceDiscoveryRequest", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
2568*d4f2939cSRui Paulo 	  (WPADBusMethodHandler)wpas_dbus_handler_p2p_service_sd_req,
2569*d4f2939cSRui Paulo 	  {
2570*d4f2939cSRui Paulo 		  { "args", "a{sv}", ARG_IN },
2571*d4f2939cSRui Paulo 		  END_ARGS
2572*d4f2939cSRui Paulo 	  }
2573*d4f2939cSRui Paulo 	},
2574*d4f2939cSRui Paulo 	{ "ServiceDiscoveryResponse", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
2575*d4f2939cSRui Paulo 	  (WPADBusMethodHandler)wpas_dbus_handler_p2p_service_sd_res,
2576*d4f2939cSRui Paulo 	  {
2577*d4f2939cSRui Paulo 		  { "args", "a{sv}", ARG_IN },
2578*d4f2939cSRui Paulo 		  END_ARGS
2579*d4f2939cSRui Paulo 	  }
2580*d4f2939cSRui Paulo 	},
2581*d4f2939cSRui Paulo 	{ "ServiceDiscoveryCancelRequest", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
2582*d4f2939cSRui Paulo 	  (WPADBusMethodHandler)wpas_dbus_handler_p2p_service_sd_cancel_req,
2583*d4f2939cSRui Paulo 	  {
2584*d4f2939cSRui Paulo 		  { "args", "t", ARG_IN },
2585*d4f2939cSRui Paulo 		  END_ARGS
2586*d4f2939cSRui Paulo 	  }
2587*d4f2939cSRui Paulo 	},
2588*d4f2939cSRui Paulo 	{ "ServiceUpdate", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
2589*d4f2939cSRui Paulo 	  (WPADBusMethodHandler)wpas_dbus_handler_p2p_service_update,
2590*d4f2939cSRui Paulo 	  {
2591*d4f2939cSRui Paulo 		  END_ARGS
2592*d4f2939cSRui Paulo 	  }
2593*d4f2939cSRui Paulo 	},
2594*d4f2939cSRui Paulo 	{ "ServiceDiscoveryExternal", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
2595*d4f2939cSRui Paulo 	  (WPADBusMethodHandler)wpas_dbus_handler_p2p_serv_disc_external,
2596*d4f2939cSRui Paulo 	  {
2597*d4f2939cSRui Paulo 		  { "arg", "i", ARG_IN },
2598*d4f2939cSRui Paulo 		  END_ARGS
2599*d4f2939cSRui Paulo 	  }
2600*d4f2939cSRui Paulo 	},
2601*d4f2939cSRui Paulo 	{ "ServiceDiscoveryExternal", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
2602*d4f2939cSRui Paulo 	  (WPADBusMethodHandler)wpas_dbus_handler_p2p_serv_disc_external,
2603*d4f2939cSRui Paulo 	  {
2604*d4f2939cSRui Paulo 		  { "arg", "i", ARG_IN },
2605*d4f2939cSRui Paulo 		  END_ARGS
2606*d4f2939cSRui Paulo 	  }
2607*d4f2939cSRui Paulo 	},
2608*d4f2939cSRui Paulo 	{ "AddPersistentGroup", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
2609*d4f2939cSRui Paulo 	  (WPADBusMethodHandler) wpas_dbus_handler_add_persistent_group,
2610*d4f2939cSRui Paulo 	  {
2611*d4f2939cSRui Paulo 		  { "args", "a{sv}", ARG_IN },
2612*d4f2939cSRui Paulo 		  { "path", "o", ARG_OUT },
2613*d4f2939cSRui Paulo 		  END_ARGS
2614*d4f2939cSRui Paulo 	  }
2615*d4f2939cSRui Paulo 	},
2616*d4f2939cSRui Paulo 	{ "RemovePersistentGroup", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
2617*d4f2939cSRui Paulo 	  (WPADBusMethodHandler) wpas_dbus_handler_remove_persistent_group,
2618*d4f2939cSRui Paulo 	  {
2619*d4f2939cSRui Paulo 		  { "path", "o", ARG_IN },
2620*d4f2939cSRui Paulo 		  END_ARGS
2621*d4f2939cSRui Paulo 	  }
2622*d4f2939cSRui Paulo 	},
2623*d4f2939cSRui Paulo 	{ "RemoveAllPersistentGroups", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
2624*d4f2939cSRui Paulo 	  (WPADBusMethodHandler)
2625*d4f2939cSRui Paulo 	  wpas_dbus_handler_remove_all_persistent_groups,
2626*d4f2939cSRui Paulo 	  {
2627*d4f2939cSRui Paulo 		  END_ARGS
2628*d4f2939cSRui Paulo 	  }
2629*d4f2939cSRui Paulo 	},
2630*d4f2939cSRui Paulo #endif /* CONFIG_P2P */
2631*d4f2939cSRui Paulo 	{ "FlushBSS", WPAS_DBUS_NEW_IFACE_INTERFACE,
2632*d4f2939cSRui Paulo 	  (WPADBusMethodHandler) &wpas_dbus_handler_flush_bss,
2633*d4f2939cSRui Paulo 	  {
2634*d4f2939cSRui Paulo 		  { "age", "u", ARG_IN },
2635*d4f2939cSRui Paulo 		  END_ARGS
2636*d4f2939cSRui Paulo 	  }
2637*d4f2939cSRui Paulo 	},
2638*d4f2939cSRui Paulo #ifdef CONFIG_AP
2639*d4f2939cSRui Paulo 	{ "SubscribeProbeReq", WPAS_DBUS_NEW_IFACE_INTERFACE,
2640*d4f2939cSRui Paulo 	  (WPADBusMethodHandler) wpas_dbus_handler_subscribe_preq,
2641*d4f2939cSRui Paulo 	  {
2642*d4f2939cSRui Paulo 		  END_ARGS
2643*d4f2939cSRui Paulo 	  }
2644*d4f2939cSRui Paulo 	},
2645*d4f2939cSRui Paulo 	{ "UnsubscribeProbeReq", WPAS_DBUS_NEW_IFACE_INTERFACE,
2646*d4f2939cSRui Paulo 	  (WPADBusMethodHandler) wpas_dbus_handler_unsubscribe_preq,
2647*d4f2939cSRui Paulo 	  {
2648*d4f2939cSRui Paulo 		  END_ARGS
2649*d4f2939cSRui Paulo 	  }
2650*d4f2939cSRui Paulo 	},
2651*d4f2939cSRui Paulo #endif /* CONFIG_AP */
2652*d4f2939cSRui Paulo 	{ NULL, NULL, NULL, { END_ARGS } }
2653*d4f2939cSRui Paulo };
2654*d4f2939cSRui Paulo 
2655*d4f2939cSRui Paulo static const struct wpa_dbus_property_desc wpas_dbus_interface_properties[] = {
2656*d4f2939cSRui Paulo 	{ "Capabilities", WPAS_DBUS_NEW_IFACE_INTERFACE, "a{sv}",
2657*d4f2939cSRui Paulo 	  wpas_dbus_getter_capabilities,
2658*d4f2939cSRui Paulo 	  NULL
2659*d4f2939cSRui Paulo 	},
2660*d4f2939cSRui Paulo 	{ "State", WPAS_DBUS_NEW_IFACE_INTERFACE, "s",
2661*d4f2939cSRui Paulo 	  wpas_dbus_getter_state,
2662*d4f2939cSRui Paulo 	  NULL
2663*d4f2939cSRui Paulo 	},
2664*d4f2939cSRui Paulo 	{ "Scanning", WPAS_DBUS_NEW_IFACE_INTERFACE, "b",
2665*d4f2939cSRui Paulo 	  wpas_dbus_getter_scanning,
2666*d4f2939cSRui Paulo 	  NULL
2667*d4f2939cSRui Paulo 	},
2668*d4f2939cSRui Paulo 	{ "ApScan", WPAS_DBUS_NEW_IFACE_INTERFACE, "u",
2669*d4f2939cSRui Paulo 	  wpas_dbus_getter_ap_scan,
2670*d4f2939cSRui Paulo 	  wpas_dbus_setter_ap_scan
2671*d4f2939cSRui Paulo 	},
2672*d4f2939cSRui Paulo 	{ "BSSExpireAge", WPAS_DBUS_NEW_IFACE_INTERFACE, "u",
2673*d4f2939cSRui Paulo 	  wpas_dbus_getter_bss_expire_age,
2674*d4f2939cSRui Paulo 	  wpas_dbus_setter_bss_expire_age
2675*d4f2939cSRui Paulo 	},
2676*d4f2939cSRui Paulo 	{ "BSSExpireCount", WPAS_DBUS_NEW_IFACE_INTERFACE, "u",
2677*d4f2939cSRui Paulo 	  wpas_dbus_getter_bss_expire_count,
2678*d4f2939cSRui Paulo 	  wpas_dbus_setter_bss_expire_count
2679*d4f2939cSRui Paulo 	},
2680*d4f2939cSRui Paulo 	{ "Country", WPAS_DBUS_NEW_IFACE_INTERFACE, "s",
2681*d4f2939cSRui Paulo 	  wpas_dbus_getter_country,
2682*d4f2939cSRui Paulo 	  wpas_dbus_setter_country
2683*d4f2939cSRui Paulo 	},
2684*d4f2939cSRui Paulo 	{ "Ifname", WPAS_DBUS_NEW_IFACE_INTERFACE, "s",
2685*d4f2939cSRui Paulo 	  wpas_dbus_getter_ifname,
2686*d4f2939cSRui Paulo 	  NULL
2687*d4f2939cSRui Paulo 	},
2688*d4f2939cSRui Paulo 	{ "Driver", WPAS_DBUS_NEW_IFACE_INTERFACE, "s",
2689*d4f2939cSRui Paulo 	  wpas_dbus_getter_driver,
2690*d4f2939cSRui Paulo 	  NULL
2691*d4f2939cSRui Paulo 	},
2692*d4f2939cSRui Paulo 	{ "BridgeIfname", WPAS_DBUS_NEW_IFACE_INTERFACE, "s",
2693*d4f2939cSRui Paulo 	  wpas_dbus_getter_bridge_ifname,
2694*d4f2939cSRui Paulo 	  NULL
2695*d4f2939cSRui Paulo 	},
2696*d4f2939cSRui Paulo 	{ "CurrentBSS", WPAS_DBUS_NEW_IFACE_INTERFACE, "o",
2697*d4f2939cSRui Paulo 	  wpas_dbus_getter_current_bss,
2698*d4f2939cSRui Paulo 	  NULL
2699*d4f2939cSRui Paulo 	},
2700*d4f2939cSRui Paulo 	{ "CurrentNetwork", WPAS_DBUS_NEW_IFACE_INTERFACE, "o",
2701*d4f2939cSRui Paulo 	  wpas_dbus_getter_current_network,
2702*d4f2939cSRui Paulo 	  NULL
2703*d4f2939cSRui Paulo 	},
2704*d4f2939cSRui Paulo 	{ "CurrentAuthMode", WPAS_DBUS_NEW_IFACE_INTERFACE, "s",
2705*d4f2939cSRui Paulo 	  wpas_dbus_getter_current_auth_mode,
2706*d4f2939cSRui Paulo 	  NULL
2707*d4f2939cSRui Paulo 	},
2708*d4f2939cSRui Paulo 	{ "Blobs", WPAS_DBUS_NEW_IFACE_INTERFACE, "a{say}",
2709*d4f2939cSRui Paulo 	  wpas_dbus_getter_blobs,
2710*d4f2939cSRui Paulo 	  NULL
2711*d4f2939cSRui Paulo 	},
2712*d4f2939cSRui Paulo 	{ "BSSs", WPAS_DBUS_NEW_IFACE_INTERFACE, "ao",
2713*d4f2939cSRui Paulo 	  wpas_dbus_getter_bsss,
2714*d4f2939cSRui Paulo 	  NULL
2715*d4f2939cSRui Paulo 	},
2716*d4f2939cSRui Paulo 	{ "Networks", WPAS_DBUS_NEW_IFACE_INTERFACE, "ao",
2717*d4f2939cSRui Paulo 	  wpas_dbus_getter_networks,
2718*d4f2939cSRui Paulo 	  NULL
2719*d4f2939cSRui Paulo 	},
2720*d4f2939cSRui Paulo 	{ "FastReauth", WPAS_DBUS_NEW_IFACE_INTERFACE, "b",
2721*d4f2939cSRui Paulo 	  wpas_dbus_getter_fast_reauth,
2722*d4f2939cSRui Paulo 	  wpas_dbus_setter_fast_reauth
2723*d4f2939cSRui Paulo 	},
2724*d4f2939cSRui Paulo 	{ "ScanInterval", WPAS_DBUS_NEW_IFACE_INTERFACE, "i",
2725*d4f2939cSRui Paulo 	  wpas_dbus_getter_scan_interval,
2726*d4f2939cSRui Paulo 	  wpas_dbus_setter_scan_interval
2727*d4f2939cSRui Paulo 	},
2728*d4f2939cSRui Paulo #ifdef CONFIG_WPS
2729*d4f2939cSRui Paulo 	{ "ProcessCredentials", WPAS_DBUS_NEW_IFACE_WPS, "b",
2730*d4f2939cSRui Paulo 	  wpas_dbus_getter_process_credentials,
2731*d4f2939cSRui Paulo 	  wpas_dbus_setter_process_credentials
2732*d4f2939cSRui Paulo 	},
2733*d4f2939cSRui Paulo #endif /* CONFIG_WPS */
2734*d4f2939cSRui Paulo #ifdef CONFIG_P2P
2735*d4f2939cSRui Paulo 	{ "P2PDeviceConfig", WPAS_DBUS_NEW_IFACE_P2PDEVICE, "a{sv}",
2736*d4f2939cSRui Paulo 	  wpas_dbus_getter_p2p_device_config,
2737*d4f2939cSRui Paulo 	  wpas_dbus_setter_p2p_device_config
2738*d4f2939cSRui Paulo 	},
2739*d4f2939cSRui Paulo 	{ "Peers", WPAS_DBUS_NEW_IFACE_P2PDEVICE, "ao",
2740*d4f2939cSRui Paulo 	  wpas_dbus_getter_p2p_peers,
2741*d4f2939cSRui Paulo 	  NULL
2742*d4f2939cSRui Paulo 	},
2743*d4f2939cSRui Paulo 	{ "Role", WPAS_DBUS_NEW_IFACE_P2PDEVICE, "s",
2744*d4f2939cSRui Paulo 	  wpas_dbus_getter_p2p_role,
2745*d4f2939cSRui Paulo 	  NULL
2746*d4f2939cSRui Paulo 	},
2747*d4f2939cSRui Paulo 	{ "Group", WPAS_DBUS_NEW_IFACE_P2PDEVICE, "o",
2748*d4f2939cSRui Paulo 	  wpas_dbus_getter_p2p_group,
2749*d4f2939cSRui Paulo 	  NULL
2750*d4f2939cSRui Paulo 	},
2751*d4f2939cSRui Paulo 	{ "PeerGO", WPAS_DBUS_NEW_IFACE_P2PDEVICE, "o",
2752*d4f2939cSRui Paulo 	  wpas_dbus_getter_p2p_peergo,
2753*d4f2939cSRui Paulo 	  NULL
2754*d4f2939cSRui Paulo 	},
2755*d4f2939cSRui Paulo 	{ "PersistentGroups", WPAS_DBUS_NEW_IFACE_P2PDEVICE, "ao",
2756*d4f2939cSRui Paulo 	  wpas_dbus_getter_persistent_groups,
2757*d4f2939cSRui Paulo 	  NULL
2758*d4f2939cSRui Paulo 	},
2759*d4f2939cSRui Paulo #endif /* CONFIG_P2P */
2760*d4f2939cSRui Paulo 	{ "DisconnectReason", WPAS_DBUS_NEW_IFACE_INTERFACE, "i",
2761*d4f2939cSRui Paulo 	  wpas_dbus_getter_disconnect_reason,
2762*d4f2939cSRui Paulo 	  NULL
2763*d4f2939cSRui Paulo 	},
2764*d4f2939cSRui Paulo 	{ NULL, NULL, NULL, NULL, NULL }
2765*d4f2939cSRui Paulo };
2766*d4f2939cSRui Paulo 
2767*d4f2939cSRui Paulo static const struct wpa_dbus_signal_desc wpas_dbus_interface_signals[] = {
2768*d4f2939cSRui Paulo 	{ "ScanDone", WPAS_DBUS_NEW_IFACE_INTERFACE,
2769*d4f2939cSRui Paulo 	  {
2770*d4f2939cSRui Paulo 		  { "success", "b", ARG_OUT },
2771*d4f2939cSRui Paulo 		  END_ARGS
2772*d4f2939cSRui Paulo 	  }
2773*d4f2939cSRui Paulo 	},
2774*d4f2939cSRui Paulo 	{ "BSSAdded", WPAS_DBUS_NEW_IFACE_INTERFACE,
2775*d4f2939cSRui Paulo 	  {
2776*d4f2939cSRui Paulo 		  { "path", "o", ARG_OUT },
2777*d4f2939cSRui Paulo 		  { "properties", "a{sv}", ARG_OUT },
2778*d4f2939cSRui Paulo 		  END_ARGS
2779*d4f2939cSRui Paulo 	  }
2780*d4f2939cSRui Paulo 	},
2781*d4f2939cSRui Paulo 	{ "BSSRemoved", WPAS_DBUS_NEW_IFACE_INTERFACE,
2782*d4f2939cSRui Paulo 	  {
2783*d4f2939cSRui Paulo 		  { "path", "o", ARG_OUT },
2784*d4f2939cSRui Paulo 		  END_ARGS
2785*d4f2939cSRui Paulo 	  }
2786*d4f2939cSRui Paulo 	},
2787*d4f2939cSRui Paulo 	{ "BlobAdded", WPAS_DBUS_NEW_IFACE_INTERFACE,
2788*d4f2939cSRui Paulo 	  {
2789*d4f2939cSRui Paulo 		  { "name", "s", ARG_OUT },
2790*d4f2939cSRui Paulo 		  END_ARGS
2791*d4f2939cSRui Paulo 	  }
2792*d4f2939cSRui Paulo 	},
2793*d4f2939cSRui Paulo 	{ "BlobRemoved", WPAS_DBUS_NEW_IFACE_INTERFACE,
2794*d4f2939cSRui Paulo 	  {
2795*d4f2939cSRui Paulo 		  { "name", "s", ARG_OUT },
2796*d4f2939cSRui Paulo 		  END_ARGS
2797*d4f2939cSRui Paulo 	  }
2798*d4f2939cSRui Paulo 	},
2799*d4f2939cSRui Paulo 	{ "NetworkAdded", WPAS_DBUS_NEW_IFACE_INTERFACE,
2800*d4f2939cSRui Paulo 	  {
2801*d4f2939cSRui Paulo 		  { "path", "o", ARG_OUT },
2802*d4f2939cSRui Paulo 		  { "properties", "a{sv}", ARG_OUT },
2803*d4f2939cSRui Paulo 		  END_ARGS
2804*d4f2939cSRui Paulo 	  }
2805*d4f2939cSRui Paulo 	},
2806*d4f2939cSRui Paulo 	{ "NetworkRemoved", WPAS_DBUS_NEW_IFACE_INTERFACE,
2807*d4f2939cSRui Paulo 	  {
2808*d4f2939cSRui Paulo 		  { "path", "o", ARG_OUT },
2809*d4f2939cSRui Paulo 		  END_ARGS
2810*d4f2939cSRui Paulo 	  }
2811*d4f2939cSRui Paulo 	},
2812*d4f2939cSRui Paulo 	{ "NetworkSelected", WPAS_DBUS_NEW_IFACE_INTERFACE,
2813*d4f2939cSRui Paulo 	  {
2814*d4f2939cSRui Paulo 		  { "path", "o", ARG_OUT },
2815*d4f2939cSRui Paulo 		  END_ARGS
2816*d4f2939cSRui Paulo 	  }
2817*d4f2939cSRui Paulo 	},
2818*d4f2939cSRui Paulo 	/* Deprecated: use org.freedesktop.DBus.Properties.PropertiesChanged */
2819*d4f2939cSRui Paulo 	{ "PropertiesChanged", WPAS_DBUS_NEW_IFACE_INTERFACE,
2820*d4f2939cSRui Paulo 	  {
2821*d4f2939cSRui Paulo 		  { "properties", "a{sv}", ARG_OUT },
2822*d4f2939cSRui Paulo 		  END_ARGS
2823*d4f2939cSRui Paulo 	  }
2824*d4f2939cSRui Paulo 	},
2825*d4f2939cSRui Paulo #ifdef CONFIG_WPS
2826*d4f2939cSRui Paulo 	{ "Event", WPAS_DBUS_NEW_IFACE_WPS,
2827*d4f2939cSRui Paulo 	  {
2828*d4f2939cSRui Paulo 		  { "name", "s", ARG_OUT },
2829*d4f2939cSRui Paulo 		  { "args", "a{sv}", ARG_OUT },
2830*d4f2939cSRui Paulo 		  END_ARGS
2831*d4f2939cSRui Paulo 	  }
2832*d4f2939cSRui Paulo 	},
2833*d4f2939cSRui Paulo 	{ "Credentials", WPAS_DBUS_NEW_IFACE_WPS,
2834*d4f2939cSRui Paulo 	  {
2835*d4f2939cSRui Paulo 		  { "credentials", "a{sv}", ARG_OUT },
2836*d4f2939cSRui Paulo 		  END_ARGS
2837*d4f2939cSRui Paulo 	  }
2838*d4f2939cSRui Paulo 	},
2839*d4f2939cSRui Paulo 	/* Deprecated: use org.freedesktop.DBus.Properties.PropertiesChanged */
2840*d4f2939cSRui Paulo 	{ "PropertiesChanged", WPAS_DBUS_NEW_IFACE_WPS,
2841*d4f2939cSRui Paulo 	  {
2842*d4f2939cSRui Paulo 		  { "properties", "a{sv}", ARG_OUT },
2843*d4f2939cSRui Paulo 		  END_ARGS
2844*d4f2939cSRui Paulo 	  }
2845*d4f2939cSRui Paulo 	},
2846*d4f2939cSRui Paulo #endif /* CONFIG_WPS */
2847*d4f2939cSRui Paulo #ifdef CONFIG_P2P
2848*d4f2939cSRui Paulo 	{ "P2PStateChanged", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
2849*d4f2939cSRui Paulo 	  {
2850*d4f2939cSRui Paulo 		  { "states", "a{ss}", ARG_OUT },
2851*d4f2939cSRui Paulo 		  END_ARGS
2852*d4f2939cSRui Paulo 	  }
2853*d4f2939cSRui Paulo 	},
2854*d4f2939cSRui Paulo 	{ "DeviceFound", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
2855*d4f2939cSRui Paulo 	  {
2856*d4f2939cSRui Paulo 		  { "path", "o", ARG_OUT },
2857*d4f2939cSRui Paulo 		  { "properties", "a{sv}", ARG_OUT },
2858*d4f2939cSRui Paulo 		  END_ARGS
2859*d4f2939cSRui Paulo 	  }
2860*d4f2939cSRui Paulo 	},
2861*d4f2939cSRui Paulo 	{ "DeviceLost", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
2862*d4f2939cSRui Paulo 	  {
2863*d4f2939cSRui Paulo 		  { "path", "o", ARG_OUT },
2864*d4f2939cSRui Paulo 		  END_ARGS
2865*d4f2939cSRui Paulo 	  }
2866*d4f2939cSRui Paulo 	},
2867*d4f2939cSRui Paulo 	{ "ProvisionDiscoveryRequestDisplayPin", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
2868*d4f2939cSRui Paulo 	  {
2869*d4f2939cSRui Paulo 		  { "peer_object", "o", ARG_OUT },
2870*d4f2939cSRui Paulo 		  { "pin", "s", ARG_OUT },
2871*d4f2939cSRui Paulo 		  END_ARGS
2872*d4f2939cSRui Paulo 	  }
2873*d4f2939cSRui Paulo 	},
2874*d4f2939cSRui Paulo 	{ "ProvisionDiscoveryResponseDisplayPin", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
2875*d4f2939cSRui Paulo 	  {
2876*d4f2939cSRui Paulo 		  { "peer_object", "o", ARG_OUT },
2877*d4f2939cSRui Paulo 		  { "pin", "s", ARG_OUT },
2878*d4f2939cSRui Paulo 		  END_ARGS
2879*d4f2939cSRui Paulo 	  }
2880*d4f2939cSRui Paulo 	},
2881*d4f2939cSRui Paulo 	{ "ProvisionDiscoveryRequestEnterPin", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
2882*d4f2939cSRui Paulo 	  {
2883*d4f2939cSRui Paulo 		  { "peer_object", "o", ARG_OUT },
2884*d4f2939cSRui Paulo 		  END_ARGS
2885*d4f2939cSRui Paulo 	  }
2886*d4f2939cSRui Paulo 	},
2887*d4f2939cSRui Paulo 	{ "ProvisionDiscoveryResponseEnterPin", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
2888*d4f2939cSRui Paulo 	  {
2889*d4f2939cSRui Paulo 		  { "peer_object", "o", ARG_OUT },
2890*d4f2939cSRui Paulo 		  END_ARGS
2891*d4f2939cSRui Paulo 	  }
2892*d4f2939cSRui Paulo 	},
2893*d4f2939cSRui Paulo 	{ "ProvisionDiscoveryPBCRequest", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
2894*d4f2939cSRui Paulo 	  {
2895*d4f2939cSRui Paulo 		  { "peer_object", "o", ARG_OUT },
2896*d4f2939cSRui Paulo 		  END_ARGS
2897*d4f2939cSRui Paulo 	  }
2898*d4f2939cSRui Paulo 	},
2899*d4f2939cSRui Paulo 	{ "ProvisionDiscoveryPBCResponse", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
2900*d4f2939cSRui Paulo 	  {
2901*d4f2939cSRui Paulo 		  { "peer_object", "o", ARG_OUT },
2902*d4f2939cSRui Paulo 		  END_ARGS
2903*d4f2939cSRui Paulo 	  }
2904*d4f2939cSRui Paulo 	},
2905*d4f2939cSRui Paulo 	{ "ProvisionDiscoveryFailure", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
2906*d4f2939cSRui Paulo 	  {
2907*d4f2939cSRui Paulo 		  { "peer_object", "o", ARG_OUT },
2908*d4f2939cSRui Paulo 		  { "status", "i", ARG_OUT },
2909*d4f2939cSRui Paulo 		  END_ARGS
2910*d4f2939cSRui Paulo 	  }
2911*d4f2939cSRui Paulo 	},
2912*d4f2939cSRui Paulo 	{ "GroupStarted", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
2913*d4f2939cSRui Paulo 	  {
2914*d4f2939cSRui Paulo 		  { "properties", "a{sv}", ARG_OUT },
2915*d4f2939cSRui Paulo 		  END_ARGS
2916*d4f2939cSRui Paulo 	  }
2917*d4f2939cSRui Paulo 	},
2918*d4f2939cSRui Paulo 	{ "GONegotiationSuccess", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
2919*d4f2939cSRui Paulo 	  {
2920*d4f2939cSRui Paulo 		  END_ARGS
2921*d4f2939cSRui Paulo 	  }
2922*d4f2939cSRui Paulo 	},
2923*d4f2939cSRui Paulo 	{ "GONegotiationFailure", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
2924*d4f2939cSRui Paulo 	  {
2925*d4f2939cSRui Paulo 		  { "status", "i", ARG_OUT },
2926*d4f2939cSRui Paulo 		  END_ARGS
2927*d4f2939cSRui Paulo 	  }
2928*d4f2939cSRui Paulo 	},
2929*d4f2939cSRui Paulo 	{ "GONegotiationRequest", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
2930*d4f2939cSRui Paulo 	  {
2931*d4f2939cSRui Paulo 		  { "path", "o", ARG_OUT },
2932*d4f2939cSRui Paulo 		  { "dev_passwd_id", "i", ARG_OUT },
2933*d4f2939cSRui Paulo 		  END_ARGS
2934*d4f2939cSRui Paulo 	  }
2935*d4f2939cSRui Paulo 	},
2936*d4f2939cSRui Paulo 	{ "InvitationResult", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
2937*d4f2939cSRui Paulo 	  {
2938*d4f2939cSRui Paulo 		  { "invite_result", "a{sv}", ARG_OUT },
2939*d4f2939cSRui Paulo 		  END_ARGS
2940*d4f2939cSRui Paulo 	  }
2941*d4f2939cSRui Paulo 	},
2942*d4f2939cSRui Paulo 	{ "GroupFinished", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
2943*d4f2939cSRui Paulo 	  {
2944*d4f2939cSRui Paulo 		  { "ifname", "s", ARG_OUT },
2945*d4f2939cSRui Paulo 		  { "role", "s", ARG_OUT },
2946*d4f2939cSRui Paulo 		  END_ARGS
2947*d4f2939cSRui Paulo 	  }
2948*d4f2939cSRui Paulo 	},
2949*d4f2939cSRui Paulo 	{ "ServiceDiscoveryRequest", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
2950*d4f2939cSRui Paulo 	  {
2951*d4f2939cSRui Paulo 		  { "sd_request", "a{sv}", ARG_OUT },
2952*d4f2939cSRui Paulo 		  END_ARGS
2953*d4f2939cSRui Paulo 	  }
2954*d4f2939cSRui Paulo 	},
2955*d4f2939cSRui Paulo 	{ "ServiceDiscoveryResponse", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
2956*d4f2939cSRui Paulo 	  {
2957*d4f2939cSRui Paulo 		  { "sd_response", "a{sv}", ARG_OUT },
2958*d4f2939cSRui Paulo 		  END_ARGS
2959*d4f2939cSRui Paulo 	  }
2960*d4f2939cSRui Paulo 	},
2961*d4f2939cSRui Paulo 	{ "PersistentGroupAdded", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
2962*d4f2939cSRui Paulo 	  {
2963*d4f2939cSRui Paulo 		  { "path", "o", ARG_OUT },
2964*d4f2939cSRui Paulo 		  { "properties", "a{sv}", ARG_OUT },
2965*d4f2939cSRui Paulo 		  END_ARGS
2966*d4f2939cSRui Paulo 	  }
2967*d4f2939cSRui Paulo 	},
2968*d4f2939cSRui Paulo 	{ "PersistentGroupRemoved", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
2969*d4f2939cSRui Paulo 	  {
2970*d4f2939cSRui Paulo 		  { "path", "o", ARG_OUT },
2971*d4f2939cSRui Paulo 		  END_ARGS
2972*d4f2939cSRui Paulo 	  }
2973*d4f2939cSRui Paulo 	},
2974*d4f2939cSRui Paulo 	{ "WpsFailed", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
2975*d4f2939cSRui Paulo 	  {
2976*d4f2939cSRui Paulo 		  { "name", "s", ARG_OUT },
2977*d4f2939cSRui Paulo 		  { "args", "a{sv}", ARG_OUT },
2978*d4f2939cSRui Paulo 		  END_ARGS
2979*d4f2939cSRui Paulo 	  }
2980*d4f2939cSRui Paulo 	},
2981*d4f2939cSRui Paulo #endif /* CONFIG_P2P */
2982*d4f2939cSRui Paulo #ifdef CONFIG_AP
2983*d4f2939cSRui Paulo 	{ "ProbeRequest", WPAS_DBUS_NEW_IFACE_INTERFACE,
2984*d4f2939cSRui Paulo 	  {
2985*d4f2939cSRui Paulo 		  { "args", "a{sv}", ARG_OUT },
2986*d4f2939cSRui Paulo 		  END_ARGS
2987*d4f2939cSRui Paulo 	  }
2988*d4f2939cSRui Paulo 	},
2989*d4f2939cSRui Paulo #endif /* CONFIG_AP */
2990*d4f2939cSRui Paulo 	{ "Certification", WPAS_DBUS_NEW_IFACE_INTERFACE,
2991*d4f2939cSRui Paulo 	  {
2992*d4f2939cSRui Paulo 		  { "certification", "a{sv}", ARG_OUT },
2993*d4f2939cSRui Paulo 		  END_ARGS
2994*d4f2939cSRui Paulo 	  }
2995*d4f2939cSRui Paulo 	},
2996*d4f2939cSRui Paulo 	{ "EAP", WPAS_DBUS_NEW_IFACE_INTERFACE,
2997*d4f2939cSRui Paulo 	  {
2998*d4f2939cSRui Paulo 		  { "status", "s", ARG_OUT },
2999*d4f2939cSRui Paulo 		  { "parameter", "s", ARG_OUT },
3000*d4f2939cSRui Paulo 		  END_ARGS
3001*d4f2939cSRui Paulo 	  }
3002*d4f2939cSRui Paulo 	},
3003*d4f2939cSRui Paulo 	{ NULL, NULL, { END_ARGS } }
3004*d4f2939cSRui Paulo };
3005*d4f2939cSRui Paulo 
3006*d4f2939cSRui Paulo 
3007*d4f2939cSRui Paulo int wpas_dbus_register_interface(struct wpa_supplicant *wpa_s)
3008*d4f2939cSRui Paulo {
3009*d4f2939cSRui Paulo 
3010*d4f2939cSRui Paulo 	struct wpa_dbus_object_desc *obj_desc = NULL;
3011*d4f2939cSRui Paulo 	struct wpas_dbus_priv *ctrl_iface = wpa_s->global->dbus;
3012*d4f2939cSRui Paulo 	int next;
3013*d4f2939cSRui Paulo 
3014*d4f2939cSRui Paulo 	/* Do nothing if the control interface is not turned on */
3015*d4f2939cSRui Paulo 	if (ctrl_iface == NULL)
3016*d4f2939cSRui Paulo 		return 0;
3017*d4f2939cSRui Paulo 
3018*d4f2939cSRui Paulo 	/* Create and set the interface's object path */
3019*d4f2939cSRui Paulo 	wpa_s->dbus_new_path = os_zalloc(WPAS_DBUS_OBJECT_PATH_MAX);
3020*d4f2939cSRui Paulo 	if (wpa_s->dbus_new_path == NULL)
3021*d4f2939cSRui Paulo 		return -1;
3022*d4f2939cSRui Paulo 	next = ctrl_iface->next_objid++;
3023*d4f2939cSRui Paulo 	os_snprintf(wpa_s->dbus_new_path, WPAS_DBUS_OBJECT_PATH_MAX,
3024*d4f2939cSRui Paulo 		    WPAS_DBUS_NEW_PATH_INTERFACES "/%u",
3025*d4f2939cSRui Paulo 		    next);
3026*d4f2939cSRui Paulo 
3027*d4f2939cSRui Paulo 	obj_desc = os_zalloc(sizeof(struct wpa_dbus_object_desc));
3028*d4f2939cSRui Paulo 	if (!obj_desc) {
3029*d4f2939cSRui Paulo 		wpa_printf(MSG_ERROR, "Not enough memory "
3030*d4f2939cSRui Paulo 			   "to create object description");
3031*d4f2939cSRui Paulo 		goto err;
3032*d4f2939cSRui Paulo 	}
3033*d4f2939cSRui Paulo 
3034*d4f2939cSRui Paulo 	wpas_dbus_register(obj_desc, wpa_s, NULL, wpas_dbus_interface_methods,
3035*d4f2939cSRui Paulo 			   wpas_dbus_interface_properties,
3036*d4f2939cSRui Paulo 			   wpas_dbus_interface_signals);
3037*d4f2939cSRui Paulo 
3038*d4f2939cSRui Paulo 	wpa_printf(MSG_DEBUG, "dbus: Register interface object '%s'",
3039*d4f2939cSRui Paulo 		   wpa_s->dbus_new_path);
3040*d4f2939cSRui Paulo 	if (wpa_dbus_register_object_per_iface(ctrl_iface,
3041*d4f2939cSRui Paulo 					       wpa_s->dbus_new_path,
3042*d4f2939cSRui Paulo 					       wpa_s->ifname, obj_desc))
3043*d4f2939cSRui Paulo 		goto err;
3044*d4f2939cSRui Paulo 
3045*d4f2939cSRui Paulo 	wpas_dbus_signal_interface_added(wpa_s);
3046*d4f2939cSRui Paulo 
3047*d4f2939cSRui Paulo 	return 0;
3048*d4f2939cSRui Paulo 
3049*d4f2939cSRui Paulo err:
3050*d4f2939cSRui Paulo 	os_free(wpa_s->dbus_new_path);
3051*d4f2939cSRui Paulo 	wpa_s->dbus_new_path = NULL;
3052*d4f2939cSRui Paulo 	free_dbus_object_desc(obj_desc);
3053*d4f2939cSRui Paulo 	return -1;
3054*d4f2939cSRui Paulo }
3055*d4f2939cSRui Paulo 
3056*d4f2939cSRui Paulo 
3057*d4f2939cSRui Paulo int wpas_dbus_unregister_interface(struct wpa_supplicant *wpa_s)
3058*d4f2939cSRui Paulo {
3059*d4f2939cSRui Paulo 	struct wpas_dbus_priv *ctrl_iface;
3060*d4f2939cSRui Paulo 
3061*d4f2939cSRui Paulo 	/* Do nothing if the control interface is not turned on */
3062*d4f2939cSRui Paulo 	if (wpa_s == NULL || wpa_s->global == NULL)
3063*d4f2939cSRui Paulo 		return 0;
3064*d4f2939cSRui Paulo 	ctrl_iface = wpa_s->global->dbus;
3065*d4f2939cSRui Paulo 	if (ctrl_iface == NULL)
3066*d4f2939cSRui Paulo 		return 0;
3067*d4f2939cSRui Paulo 
3068*d4f2939cSRui Paulo 	wpa_printf(MSG_DEBUG, "dbus: Unregister interface object '%s'",
3069*d4f2939cSRui Paulo 		   wpa_s->dbus_new_path);
3070*d4f2939cSRui Paulo 
3071*d4f2939cSRui Paulo #ifdef CONFIG_AP
3072*d4f2939cSRui Paulo 	if (wpa_s->preq_notify_peer) {
3073*d4f2939cSRui Paulo 		wpas_dbus_unsubscribe_noc(ctrl_iface);
3074*d4f2939cSRui Paulo 		os_free(wpa_s->preq_notify_peer);
3075*d4f2939cSRui Paulo 		wpa_s->preq_notify_peer = NULL;
3076*d4f2939cSRui Paulo 	}
3077*d4f2939cSRui Paulo #endif /* CONFIG_AP */
3078*d4f2939cSRui Paulo 
3079*d4f2939cSRui Paulo 	if (wpa_dbus_unregister_object_per_iface(ctrl_iface,
3080*d4f2939cSRui Paulo 						 wpa_s->dbus_new_path))
3081*d4f2939cSRui Paulo 		return -1;
3082*d4f2939cSRui Paulo 
3083*d4f2939cSRui Paulo 	wpas_dbus_signal_interface_removed(wpa_s);
3084*d4f2939cSRui Paulo 
3085*d4f2939cSRui Paulo 	os_free(wpa_s->dbus_new_path);
3086*d4f2939cSRui Paulo 	wpa_s->dbus_new_path = NULL;
3087*d4f2939cSRui Paulo 
3088*d4f2939cSRui Paulo 	return 0;
3089*d4f2939cSRui Paulo }
3090*d4f2939cSRui Paulo 
3091*d4f2939cSRui Paulo #ifdef CONFIG_P2P
3092*d4f2939cSRui Paulo 
3093*d4f2939cSRui Paulo static const struct wpa_dbus_property_desc wpas_dbus_p2p_peer_properties[] = {
3094*d4f2939cSRui Paulo 	{ "DeviceName", WPAS_DBUS_NEW_IFACE_P2P_PEER, "s",
3095*d4f2939cSRui Paulo 	  wpas_dbus_getter_p2p_peer_device_name,
3096*d4f2939cSRui Paulo 	  NULL
3097*d4f2939cSRui Paulo 	},
3098*d4f2939cSRui Paulo 	{ "PrimaryDeviceType", WPAS_DBUS_NEW_IFACE_P2P_PEER, "ay",
3099*d4f2939cSRui Paulo 	  wpas_dbus_getter_p2p_peer_primary_device_type,
3100*d4f2939cSRui Paulo 	  NULL
3101*d4f2939cSRui Paulo 	},
3102*d4f2939cSRui Paulo 	{ "config_method", WPAS_DBUS_NEW_IFACE_P2P_PEER, "q",
3103*d4f2939cSRui Paulo 	  wpas_dbus_getter_p2p_peer_config_method,
3104*d4f2939cSRui Paulo 	  NULL
3105*d4f2939cSRui Paulo 	},
3106*d4f2939cSRui Paulo 	{ "level", WPAS_DBUS_NEW_IFACE_P2P_PEER, "i",
3107*d4f2939cSRui Paulo 	  wpas_dbus_getter_p2p_peer_level,
3108*d4f2939cSRui Paulo 	  NULL
3109*d4f2939cSRui Paulo 	},
3110*d4f2939cSRui Paulo 	{ "devicecapability", WPAS_DBUS_NEW_IFACE_P2P_PEER, "y",
3111*d4f2939cSRui Paulo 	  wpas_dbus_getter_p2p_peer_device_capability,
3112*d4f2939cSRui Paulo 	  NULL
3113*d4f2939cSRui Paulo 	},
3114*d4f2939cSRui Paulo 	{ "groupcapability", WPAS_DBUS_NEW_IFACE_P2P_PEER, "y",
3115*d4f2939cSRui Paulo 	  wpas_dbus_getter_p2p_peer_group_capability,
3116*d4f2939cSRui Paulo 	  NULL
3117*d4f2939cSRui Paulo 	},
3118*d4f2939cSRui Paulo 	{ "SecondaryDeviceTypes", WPAS_DBUS_NEW_IFACE_P2P_PEER, "aay",
3119*d4f2939cSRui Paulo 	  wpas_dbus_getter_p2p_peer_secondary_device_types,
3120*d4f2939cSRui Paulo 	  NULL
3121*d4f2939cSRui Paulo 	},
3122*d4f2939cSRui Paulo 	{ "VendorExtension", WPAS_DBUS_NEW_IFACE_P2P_PEER, "aay",
3123*d4f2939cSRui Paulo 	  wpas_dbus_getter_p2p_peer_vendor_extension,
3124*d4f2939cSRui Paulo 	  NULL
3125*d4f2939cSRui Paulo 	},
3126*d4f2939cSRui Paulo 	{ "IEs", WPAS_DBUS_NEW_IFACE_P2P_PEER, "ay",
3127*d4f2939cSRui Paulo 	  wpas_dbus_getter_p2p_peer_ies,
3128*d4f2939cSRui Paulo 	  NULL
3129*d4f2939cSRui Paulo 	},
3130*d4f2939cSRui Paulo 	{ NULL, NULL, NULL, NULL, NULL }
3131*d4f2939cSRui Paulo };
3132*d4f2939cSRui Paulo 
3133*d4f2939cSRui Paulo static const struct wpa_dbus_signal_desc wpas_dbus_p2p_peer_signals[] = {
3134*d4f2939cSRui Paulo 
3135*d4f2939cSRui Paulo 	{ NULL, NULL, { END_ARGS } }
3136*d4f2939cSRui Paulo };
3137*d4f2939cSRui Paulo 
3138*d4f2939cSRui Paulo /**
3139*d4f2939cSRui Paulo  * wpas_dbus_signal_peer - Send a peer related event signal
3140*d4f2939cSRui Paulo  * @wpa_s: %wpa_supplicant network interface data
3141*d4f2939cSRui Paulo  * @dev: peer device object
3142*d4f2939cSRui Paulo  * @interface: name of the interface emitting this signal.
3143*d4f2939cSRui Paulo  *	In case of peer objects, it would be emitted by either
3144*d4f2939cSRui Paulo  *	the "interface object" or by "peer objects"
3145*d4f2939cSRui Paulo  * @sig_name: signal name - DeviceFound
3146*d4f2939cSRui Paulo  *
3147*d4f2939cSRui Paulo  * Notify listeners about event related with newly found p2p peer device
3148*d4f2939cSRui Paulo  */
3149*d4f2939cSRui Paulo static void wpas_dbus_signal_peer(struct wpa_supplicant *wpa_s,
3150*d4f2939cSRui Paulo 				  const u8 *dev_addr, const char *interface,
3151*d4f2939cSRui Paulo 				  const char *sig_name)
3152*d4f2939cSRui Paulo {
3153*d4f2939cSRui Paulo 	struct wpas_dbus_priv *iface;
3154*d4f2939cSRui Paulo 	DBusMessage *msg;
3155*d4f2939cSRui Paulo 	DBusMessageIter iter;
3156*d4f2939cSRui Paulo 	char peer_obj_path[WPAS_DBUS_OBJECT_PATH_MAX], *path;
3157*d4f2939cSRui Paulo 
3158*d4f2939cSRui Paulo 	iface = wpa_s->global->dbus;
3159*d4f2939cSRui Paulo 
3160*d4f2939cSRui Paulo 	/* Do nothing if the control interface is not turned on */
3161*d4f2939cSRui Paulo 	if (iface == NULL)
3162*d4f2939cSRui Paulo 		return;
3163*d4f2939cSRui Paulo 
3164*d4f2939cSRui Paulo 	os_snprintf(peer_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
3165*d4f2939cSRui Paulo 		    "%s/" WPAS_DBUS_NEW_P2P_PEERS_PART "/" COMPACT_MACSTR,
3166*d4f2939cSRui Paulo 		    wpa_s->dbus_new_path, MAC2STR(dev_addr));
3167*d4f2939cSRui Paulo 
3168*d4f2939cSRui Paulo 	msg = dbus_message_new_signal(wpa_s->dbus_new_path, interface,
3169*d4f2939cSRui Paulo 				      sig_name);
3170*d4f2939cSRui Paulo 	if (msg == NULL)
3171*d4f2939cSRui Paulo 		return;
3172*d4f2939cSRui Paulo 
3173*d4f2939cSRui Paulo 	dbus_message_iter_init_append(msg, &iter);
3174*d4f2939cSRui Paulo 	path = peer_obj_path;
3175*d4f2939cSRui Paulo 	if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_OBJECT_PATH,
3176*d4f2939cSRui Paulo 					    &path))
3177*d4f2939cSRui Paulo 		goto err;
3178*d4f2939cSRui Paulo 
3179*d4f2939cSRui Paulo 	dbus_connection_send(iface->con, msg, NULL);
3180*d4f2939cSRui Paulo 
3181*d4f2939cSRui Paulo 	dbus_message_unref(msg);
3182*d4f2939cSRui Paulo 	return;
3183*d4f2939cSRui Paulo 
3184*d4f2939cSRui Paulo err:
3185*d4f2939cSRui Paulo 	wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
3186*d4f2939cSRui Paulo 	dbus_message_unref(msg);
3187*d4f2939cSRui Paulo }
3188*d4f2939cSRui Paulo 
3189*d4f2939cSRui Paulo 
3190*d4f2939cSRui Paulo /**
3191*d4f2939cSRui Paulo  * wpas_dbus_signal_peer_found - Send a peer found signal
3192*d4f2939cSRui Paulo  * @wpa_s: %wpa_supplicant network interface data
3193*d4f2939cSRui Paulo  * @dev: peer device object
3194*d4f2939cSRui Paulo  *
3195*d4f2939cSRui Paulo  * Notify listeners about find a p2p peer device found
3196*d4f2939cSRui Paulo  */
3197*d4f2939cSRui Paulo void wpas_dbus_signal_peer_device_found(struct wpa_supplicant *wpa_s,
3198*d4f2939cSRui Paulo 					const u8 *dev_addr)
3199*d4f2939cSRui Paulo {
3200*d4f2939cSRui Paulo 	wpas_dbus_signal_peer(wpa_s, dev_addr,
3201*d4f2939cSRui Paulo 			      WPAS_DBUS_NEW_IFACE_P2PDEVICE,
3202*d4f2939cSRui Paulo 			      "DeviceFound");
3203*d4f2939cSRui Paulo }
3204*d4f2939cSRui Paulo 
3205*d4f2939cSRui Paulo /**
3206*d4f2939cSRui Paulo  * wpas_dbus_signal_peer_lost - Send a peer lost signal
3207*d4f2939cSRui Paulo  * @wpa_s: %wpa_supplicant network interface data
3208*d4f2939cSRui Paulo  * @dev: peer device object
3209*d4f2939cSRui Paulo  *
3210*d4f2939cSRui Paulo  * Notify listeners about lost a p2p peer device
3211*d4f2939cSRui Paulo  */
3212*d4f2939cSRui Paulo void wpas_dbus_signal_peer_device_lost(struct wpa_supplicant *wpa_s,
3213*d4f2939cSRui Paulo 				       const u8 *dev_addr)
3214*d4f2939cSRui Paulo {
3215*d4f2939cSRui Paulo 	wpas_dbus_signal_peer(wpa_s, dev_addr,
3216*d4f2939cSRui Paulo 			      WPAS_DBUS_NEW_IFACE_P2PDEVICE,
3217*d4f2939cSRui Paulo 			      "DeviceLost");
3218*d4f2939cSRui Paulo }
3219*d4f2939cSRui Paulo 
3220*d4f2939cSRui Paulo /**
3221*d4f2939cSRui Paulo  * wpas_dbus_register_peer - Register a discovered peer object with dbus
3222*d4f2939cSRui Paulo  * @wpa_s: wpa_supplicant interface structure
3223*d4f2939cSRui Paulo  * @ssid: network configuration data
3224*d4f2939cSRui Paulo  * Returns: 0 on success, -1 on failure
3225*d4f2939cSRui Paulo  *
3226*d4f2939cSRui Paulo  * Registers network representing object with dbus
3227*d4f2939cSRui Paulo  */
3228*d4f2939cSRui Paulo int wpas_dbus_register_peer(struct wpa_supplicant *wpa_s, const u8 *dev_addr)
3229*d4f2939cSRui Paulo {
3230*d4f2939cSRui Paulo 	struct wpas_dbus_priv *ctrl_iface;
3231*d4f2939cSRui Paulo 	struct wpa_dbus_object_desc *obj_desc;
3232*d4f2939cSRui Paulo 	struct peer_handler_args *arg;
3233*d4f2939cSRui Paulo 	char peer_obj_path[WPAS_DBUS_OBJECT_PATH_MAX];
3234*d4f2939cSRui Paulo 
3235*d4f2939cSRui Paulo 	/* Do nothing if the control interface is not turned on */
3236*d4f2939cSRui Paulo 	if (wpa_s == NULL || wpa_s->global == NULL)
3237*d4f2939cSRui Paulo 		return 0;
3238*d4f2939cSRui Paulo 
3239*d4f2939cSRui Paulo 	ctrl_iface = wpa_s->global->dbus;
3240*d4f2939cSRui Paulo 	if (ctrl_iface == NULL)
3241*d4f2939cSRui Paulo 		return 0;
3242*d4f2939cSRui Paulo 
3243*d4f2939cSRui Paulo 	os_snprintf(peer_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
3244*d4f2939cSRui Paulo 		    "%s/" WPAS_DBUS_NEW_P2P_PEERS_PART "/" COMPACT_MACSTR,
3245*d4f2939cSRui Paulo 		    wpa_s->dbus_new_path, MAC2STR(dev_addr));
3246*d4f2939cSRui Paulo 
3247*d4f2939cSRui Paulo 	wpa_printf(MSG_INFO, "dbus: Register peer object '%s'",
3248*d4f2939cSRui Paulo 		   peer_obj_path);
3249*d4f2939cSRui Paulo 	obj_desc = os_zalloc(sizeof(struct wpa_dbus_object_desc));
3250*d4f2939cSRui Paulo 	if (!obj_desc) {
3251*d4f2939cSRui Paulo 		wpa_printf(MSG_ERROR, "Not enough memory "
3252*d4f2939cSRui Paulo 			   "to create object description");
3253*d4f2939cSRui Paulo 		goto err;
3254*d4f2939cSRui Paulo 	}
3255*d4f2939cSRui Paulo 
3256*d4f2939cSRui Paulo 	/* allocate memory for handlers arguments */
3257*d4f2939cSRui Paulo 	arg = os_zalloc(sizeof(struct peer_handler_args));
3258*d4f2939cSRui Paulo 	if (!arg) {
3259*d4f2939cSRui Paulo 		wpa_printf(MSG_ERROR, "Not enough memory "
3260*d4f2939cSRui Paulo 			   "to create arguments for method");
3261*d4f2939cSRui Paulo 		goto err;
3262*d4f2939cSRui Paulo 	}
3263*d4f2939cSRui Paulo 
3264*d4f2939cSRui Paulo 	arg->wpa_s = wpa_s;
3265*d4f2939cSRui Paulo 	os_memcpy(arg->p2p_device_addr, dev_addr, ETH_ALEN);
3266*d4f2939cSRui Paulo 
3267*d4f2939cSRui Paulo 	wpas_dbus_register(obj_desc, arg, wpa_dbus_free,
3268*d4f2939cSRui Paulo 			   NULL,
3269*d4f2939cSRui Paulo 			   wpas_dbus_p2p_peer_properties,
3270*d4f2939cSRui Paulo 			   wpas_dbus_p2p_peer_signals);
3271*d4f2939cSRui Paulo 
3272*d4f2939cSRui Paulo 	if (wpa_dbus_register_object_per_iface(ctrl_iface, peer_obj_path,
3273*d4f2939cSRui Paulo 					       wpa_s->ifname, obj_desc))
3274*d4f2939cSRui Paulo 		goto err;
3275*d4f2939cSRui Paulo 
3276*d4f2939cSRui Paulo 	return 0;
3277*d4f2939cSRui Paulo 
3278*d4f2939cSRui Paulo err:
3279*d4f2939cSRui Paulo 	free_dbus_object_desc(obj_desc);
3280*d4f2939cSRui Paulo 	return -1;
3281*d4f2939cSRui Paulo }
3282*d4f2939cSRui Paulo 
3283*d4f2939cSRui Paulo /**
3284*d4f2939cSRui Paulo  * wpas_dbus_unregister_peer - Unregister a peer object with dbus
3285*d4f2939cSRui Paulo  * @wpa_s: wpa_supplicant interface structure
3286*d4f2939cSRui Paulo  * @dev_addr: p2p device addr
3287*d4f2939cSRui Paulo  * Returns: 0 on success, -1 on failure
3288*d4f2939cSRui Paulo  *
3289*d4f2939cSRui Paulo  * Registers network representing object with dbus
3290*d4f2939cSRui Paulo  */
3291*d4f2939cSRui Paulo int wpas_dbus_unregister_peer(struct wpa_supplicant *wpa_s,
3292*d4f2939cSRui Paulo 				  const u8 *dev_addr)
3293*d4f2939cSRui Paulo {
3294*d4f2939cSRui Paulo 	struct wpas_dbus_priv *ctrl_iface;
3295*d4f2939cSRui Paulo 	char peer_obj_path[WPAS_DBUS_OBJECT_PATH_MAX];
3296*d4f2939cSRui Paulo 	int ret;
3297*d4f2939cSRui Paulo 
3298*d4f2939cSRui Paulo 	/* Do nothing if the control interface is not turned on */
3299*d4f2939cSRui Paulo 	if (wpa_s == NULL || wpa_s->global == NULL ||
3300*d4f2939cSRui Paulo 	    wpa_s->dbus_new_path == NULL)
3301*d4f2939cSRui Paulo 		return 0;
3302*d4f2939cSRui Paulo 	ctrl_iface = wpa_s->global->dbus;
3303*d4f2939cSRui Paulo 	if (ctrl_iface == NULL)
3304*d4f2939cSRui Paulo 		return 0;
3305*d4f2939cSRui Paulo 
3306*d4f2939cSRui Paulo 	os_snprintf(peer_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
3307*d4f2939cSRui Paulo 		    "%s/" WPAS_DBUS_NEW_P2P_PEERS_PART "/" COMPACT_MACSTR,
3308*d4f2939cSRui Paulo 		    wpa_s->dbus_new_path, MAC2STR(dev_addr));
3309*d4f2939cSRui Paulo 
3310*d4f2939cSRui Paulo 	wpa_printf(MSG_INFO, "dbus: Unregister peer object '%s'",
3311*d4f2939cSRui Paulo 		   peer_obj_path);
3312*d4f2939cSRui Paulo 	ret = wpa_dbus_unregister_object_per_iface(ctrl_iface, peer_obj_path);
3313*d4f2939cSRui Paulo 
3314*d4f2939cSRui Paulo 	return ret;
3315*d4f2939cSRui Paulo }
3316*d4f2939cSRui Paulo 
3317*d4f2939cSRui Paulo 
3318*d4f2939cSRui Paulo static const struct wpa_dbus_property_desc wpas_dbus_p2p_group_properties[] = {
3319*d4f2939cSRui Paulo 	{ "Members", WPAS_DBUS_NEW_IFACE_P2P_GROUP, "ao",
3320*d4f2939cSRui Paulo 	  wpas_dbus_getter_p2p_group_members,
3321*d4f2939cSRui Paulo 	  NULL
3322*d4f2939cSRui Paulo 	},
3323*d4f2939cSRui Paulo 	{ "Group", WPAS_DBUS_NEW_IFACE_P2P_GROUP, "o",
3324*d4f2939cSRui Paulo 	  wpas_dbus_getter_p2p_group,
3325*d4f2939cSRui Paulo 	  NULL
3326*d4f2939cSRui Paulo 	},
3327*d4f2939cSRui Paulo 	{ "Role", WPAS_DBUS_NEW_IFACE_P2P_GROUP, "s",
3328*d4f2939cSRui Paulo 	  wpas_dbus_getter_p2p_role,
3329*d4f2939cSRui Paulo 	  NULL
3330*d4f2939cSRui Paulo 	},
3331*d4f2939cSRui Paulo 	{ "SSID", WPAS_DBUS_NEW_IFACE_P2P_GROUP, "ay",
3332*d4f2939cSRui Paulo 	  wpas_dbus_getter_p2p_group_ssid,
3333*d4f2939cSRui Paulo 	  NULL
3334*d4f2939cSRui Paulo 	},
3335*d4f2939cSRui Paulo 	{ "BSSID", WPAS_DBUS_NEW_IFACE_P2P_GROUP, "ay",
3336*d4f2939cSRui Paulo 	  wpas_dbus_getter_p2p_group_bssid,
3337*d4f2939cSRui Paulo 	  NULL
3338*d4f2939cSRui Paulo 	},
3339*d4f2939cSRui Paulo 	{ "Frequency", WPAS_DBUS_NEW_IFACE_P2P_GROUP, "q",
3340*d4f2939cSRui Paulo 	  wpas_dbus_getter_p2p_group_frequency,
3341*d4f2939cSRui Paulo 	  NULL
3342*d4f2939cSRui Paulo 	},
3343*d4f2939cSRui Paulo 	{ "Passphrase", WPAS_DBUS_NEW_IFACE_P2P_GROUP, "s",
3344*d4f2939cSRui Paulo 	  wpas_dbus_getter_p2p_group_passphrase,
3345*d4f2939cSRui Paulo 	  NULL
3346*d4f2939cSRui Paulo 	},
3347*d4f2939cSRui Paulo 	{ "PSK", WPAS_DBUS_NEW_IFACE_P2P_GROUP, "ay",
3348*d4f2939cSRui Paulo 	  wpas_dbus_getter_p2p_group_psk,
3349*d4f2939cSRui Paulo 	  NULL
3350*d4f2939cSRui Paulo 	},
3351*d4f2939cSRui Paulo 	{ "WPSVendorExtensions", WPAS_DBUS_NEW_IFACE_P2P_GROUP, "aay",
3352*d4f2939cSRui Paulo 	  wpas_dbus_getter_p2p_group_vendor_ext,
3353*d4f2939cSRui Paulo 	  wpas_dbus_setter_p2p_group_vendor_ext
3354*d4f2939cSRui Paulo 	},
3355*d4f2939cSRui Paulo 	{ NULL, NULL, NULL, NULL, NULL }
3356*d4f2939cSRui Paulo };
3357*d4f2939cSRui Paulo 
3358*d4f2939cSRui Paulo static const struct wpa_dbus_signal_desc wpas_dbus_p2p_group_signals[] = {
3359*d4f2939cSRui Paulo 	{ "PeerJoined", WPAS_DBUS_NEW_IFACE_P2P_GROUP,
3360*d4f2939cSRui Paulo 	  {
3361*d4f2939cSRui Paulo 		  { "peer", "o", ARG_OUT },
3362*d4f2939cSRui Paulo 		  END_ARGS
3363*d4f2939cSRui Paulo 	  }
3364*d4f2939cSRui Paulo 	},
3365*d4f2939cSRui Paulo 	{ "PeerDisconnected", WPAS_DBUS_NEW_IFACE_P2P_GROUP,
3366*d4f2939cSRui Paulo 	  {
3367*d4f2939cSRui Paulo 		  { "peer", "o", ARG_OUT },
3368*d4f2939cSRui Paulo 		  END_ARGS
3369*d4f2939cSRui Paulo 	  }
3370*d4f2939cSRui Paulo 	},
3371*d4f2939cSRui Paulo 	{ NULL, NULL, { END_ARGS } }
3372*d4f2939cSRui Paulo };
3373*d4f2939cSRui Paulo 
3374*d4f2939cSRui Paulo /**
3375*d4f2939cSRui Paulo  * wpas_dbus_register_p2p_group - Register a p2p group object with dbus
3376*d4f2939cSRui Paulo  * @wpa_s: wpa_supplicant interface structure
3377*d4f2939cSRui Paulo  * @ssid: SSID struct
3378*d4f2939cSRui Paulo  * Returns: 0 on success, -1 on failure
3379*d4f2939cSRui Paulo  *
3380*d4f2939cSRui Paulo  * Registers p2p group representing object with dbus
3381*d4f2939cSRui Paulo  */
3382*d4f2939cSRui Paulo void wpas_dbus_register_p2p_group(struct wpa_supplicant *wpa_s,
3383*d4f2939cSRui Paulo 				  struct wpa_ssid *ssid)
3384*d4f2939cSRui Paulo {
3385*d4f2939cSRui Paulo 	struct wpas_dbus_priv *ctrl_iface;
3386*d4f2939cSRui Paulo 	struct wpa_dbus_object_desc *obj_desc;
3387*d4f2939cSRui Paulo 	char group_obj_path[WPAS_DBUS_OBJECT_PATH_MAX];
3388*d4f2939cSRui Paulo 
3389*d4f2939cSRui Paulo 	/* Do nothing if the control interface is not turned on */
3390*d4f2939cSRui Paulo 	if (wpa_s == NULL || wpa_s->global == NULL)
3391*d4f2939cSRui Paulo 		return;
3392*d4f2939cSRui Paulo 
3393*d4f2939cSRui Paulo 	ctrl_iface = wpa_s->global->dbus;
3394*d4f2939cSRui Paulo 	if (ctrl_iface == NULL)
3395*d4f2939cSRui Paulo 		return;
3396*d4f2939cSRui Paulo 
3397*d4f2939cSRui Paulo 	if (wpa_s->dbus_groupobj_path) {
3398*d4f2939cSRui Paulo 		wpa_printf(MSG_INFO, "%s: Group object '%s' already exists",
3399*d4f2939cSRui Paulo 			   __func__, wpa_s->dbus_groupobj_path);
3400*d4f2939cSRui Paulo 		return;
3401*d4f2939cSRui Paulo 	}
3402*d4f2939cSRui Paulo 
3403*d4f2939cSRui Paulo 	if (wpas_dbus_get_group_obj_path(wpa_s, ssid, group_obj_path) < 0)
3404*d4f2939cSRui Paulo 		return;
3405*d4f2939cSRui Paulo 
3406*d4f2939cSRui Paulo 	wpa_s->dbus_groupobj_path = os_strdup(group_obj_path);
3407*d4f2939cSRui Paulo 	if (wpa_s->dbus_groupobj_path == NULL)
3408*d4f2939cSRui Paulo 		return;
3409*d4f2939cSRui Paulo 
3410*d4f2939cSRui Paulo 	wpa_printf(MSG_INFO, "dbus: Register group object '%s'",
3411*d4f2939cSRui Paulo 		   group_obj_path);
3412*d4f2939cSRui Paulo 	obj_desc = os_zalloc(sizeof(struct wpa_dbus_object_desc));
3413*d4f2939cSRui Paulo 	if (!obj_desc) {
3414*d4f2939cSRui Paulo 		wpa_printf(MSG_ERROR, "Not enough memory "
3415*d4f2939cSRui Paulo 			   "to create object description");
3416*d4f2939cSRui Paulo 		goto err;
3417*d4f2939cSRui Paulo 	}
3418*d4f2939cSRui Paulo 
3419*d4f2939cSRui Paulo 	wpas_dbus_register(obj_desc, wpa_s, NULL, NULL,
3420*d4f2939cSRui Paulo 			   wpas_dbus_p2p_group_properties,
3421*d4f2939cSRui Paulo 			   wpas_dbus_p2p_group_signals);
3422*d4f2939cSRui Paulo 
3423*d4f2939cSRui Paulo 	if (wpa_dbus_register_object_per_iface(ctrl_iface, group_obj_path,
3424*d4f2939cSRui Paulo 					       wpa_s->ifname, obj_desc))
3425*d4f2939cSRui Paulo 		goto err;
3426*d4f2939cSRui Paulo 
3427*d4f2939cSRui Paulo 	return;
3428*d4f2939cSRui Paulo 
3429*d4f2939cSRui Paulo err:
3430*d4f2939cSRui Paulo 	if (wpa_s->dbus_groupobj_path) {
3431*d4f2939cSRui Paulo 		os_free(wpa_s->dbus_groupobj_path);
3432*d4f2939cSRui Paulo 		wpa_s->dbus_groupobj_path = NULL;
3433*d4f2939cSRui Paulo 	}
3434*d4f2939cSRui Paulo 
3435*d4f2939cSRui Paulo 	free_dbus_object_desc(obj_desc);
3436*d4f2939cSRui Paulo }
3437*d4f2939cSRui Paulo 
3438*d4f2939cSRui Paulo /**
3439*d4f2939cSRui Paulo  * wpas_dbus_unregister_p2p_group - Unregister a p2p group object from dbus
3440*d4f2939cSRui Paulo  * @wpa_s: wpa_supplicant interface structure
3441*d4f2939cSRui Paulo  * @ssid: network name of the p2p group started
3442*d4f2939cSRui Paulo  */
3443*d4f2939cSRui Paulo void wpas_dbus_unregister_p2p_group(struct wpa_supplicant *wpa_s,
3444*d4f2939cSRui Paulo 				    const struct wpa_ssid *ssid)
3445*d4f2939cSRui Paulo {
3446*d4f2939cSRui Paulo 	struct wpas_dbus_priv *ctrl_iface;
3447*d4f2939cSRui Paulo 
3448*d4f2939cSRui Paulo 	/* Do nothing if the control interface is not turned on */
3449*d4f2939cSRui Paulo 	if (wpa_s == NULL || wpa_s->global == NULL)
3450*d4f2939cSRui Paulo 		return;
3451*d4f2939cSRui Paulo 
3452*d4f2939cSRui Paulo 	ctrl_iface = wpa_s->global->dbus;
3453*d4f2939cSRui Paulo 	if (ctrl_iface == NULL)
3454*d4f2939cSRui Paulo 		return;
3455*d4f2939cSRui Paulo 
3456*d4f2939cSRui Paulo 	if (!wpa_s->dbus_groupobj_path) {
3457*d4f2939cSRui Paulo 		wpa_printf(MSG_DEBUG,
3458*d4f2939cSRui Paulo 			   "%s: Group object '%s' already unregistered",
3459*d4f2939cSRui Paulo 			   __func__, wpa_s->dbus_groupobj_path);
3460*d4f2939cSRui Paulo 		return;
3461*d4f2939cSRui Paulo 	}
3462*d4f2939cSRui Paulo 
3463*d4f2939cSRui Paulo 	wpa_printf(MSG_DEBUG, "dbus: Unregister group object '%s'",
3464*d4f2939cSRui Paulo 		   wpa_s->dbus_groupobj_path);
3465*d4f2939cSRui Paulo 
3466*d4f2939cSRui Paulo 	wpa_dbus_unregister_object_per_iface(ctrl_iface,
3467*d4f2939cSRui Paulo 					     wpa_s->dbus_groupobj_path);
3468*d4f2939cSRui Paulo 
3469*d4f2939cSRui Paulo 	os_free(wpa_s->dbus_groupobj_path);
3470*d4f2939cSRui Paulo 	wpa_s->dbus_groupobj_path = NULL;
3471*d4f2939cSRui Paulo }
3472*d4f2939cSRui Paulo 
3473*d4f2939cSRui Paulo static const struct wpa_dbus_property_desc
3474*d4f2939cSRui Paulo wpas_dbus_p2p_groupmember_properties[] = {
3475*d4f2939cSRui Paulo 	{ NULL, NULL, NULL, NULL, NULL }
3476*d4f2939cSRui Paulo };
3477*d4f2939cSRui Paulo 
3478*d4f2939cSRui Paulo /**
3479*d4f2939cSRui Paulo  * wpas_dbus_register_p2p_groupmember - Register a p2p groupmember
3480*d4f2939cSRui Paulo  * object with dbus
3481*d4f2939cSRui Paulo  * @wpa_s: wpa_supplicant interface structure
3482*d4f2939cSRui Paulo  * @p2p_if_addr: i/f addr of the device joining this group
3483*d4f2939cSRui Paulo  *
3484*d4f2939cSRui Paulo  * Registers p2p groupmember representing object with dbus
3485*d4f2939cSRui Paulo  */
3486*d4f2939cSRui Paulo void wpas_dbus_register_p2p_groupmember(struct wpa_supplicant *wpa_s,
3487*d4f2939cSRui Paulo 					const u8 *p2p_if_addr)
3488*d4f2939cSRui Paulo {
3489*d4f2939cSRui Paulo 	struct wpas_dbus_priv *ctrl_iface;
3490*d4f2939cSRui Paulo 	struct wpa_dbus_object_desc *obj_desc = NULL;
3491*d4f2939cSRui Paulo 	struct groupmember_handler_args *arg;
3492*d4f2939cSRui Paulo 	char groupmember_obj_path[WPAS_DBUS_OBJECT_PATH_MAX];
3493*d4f2939cSRui Paulo 
3494*d4f2939cSRui Paulo 	/* Do nothing if the control interface is not turned on */
3495*d4f2939cSRui Paulo 	if (wpa_s == NULL || wpa_s->global == NULL)
3496*d4f2939cSRui Paulo 		return;
3497*d4f2939cSRui Paulo 
3498*d4f2939cSRui Paulo 	ctrl_iface = wpa_s->global->dbus;
3499*d4f2939cSRui Paulo 	if (ctrl_iface == NULL)
3500*d4f2939cSRui Paulo 		return;
3501*d4f2939cSRui Paulo 
3502*d4f2939cSRui Paulo 	if (!wpa_s->dbus_groupobj_path)
3503*d4f2939cSRui Paulo 		return;
3504*d4f2939cSRui Paulo 
3505*d4f2939cSRui Paulo 	os_snprintf(groupmember_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
3506*d4f2939cSRui Paulo 		"%s/" WPAS_DBUS_NEW_P2P_GROUPMEMBERS_PART "/" COMPACT_MACSTR,
3507*d4f2939cSRui Paulo 		wpa_s->dbus_groupobj_path, MAC2STR(p2p_if_addr));
3508*d4f2939cSRui Paulo 
3509*d4f2939cSRui Paulo 	obj_desc = os_zalloc(sizeof(struct wpa_dbus_object_desc));
3510*d4f2939cSRui Paulo 	if (!obj_desc) {
3511*d4f2939cSRui Paulo 		wpa_printf(MSG_ERROR, "Not enough memory "
3512*d4f2939cSRui Paulo 			   "to create object description");
3513*d4f2939cSRui Paulo 		goto err;
3514*d4f2939cSRui Paulo 	}
3515*d4f2939cSRui Paulo 
3516*d4f2939cSRui Paulo 	/* allocate memory for handlers arguments */
3517*d4f2939cSRui Paulo 	arg = os_zalloc(sizeof(struct groupmember_handler_args));
3518*d4f2939cSRui Paulo 	if (!arg) {
3519*d4f2939cSRui Paulo 		wpa_printf(MSG_ERROR, "Not enough memory "
3520*d4f2939cSRui Paulo 			   "to create arguments for method");
3521*d4f2939cSRui Paulo 		goto err;
3522*d4f2939cSRui Paulo 	}
3523*d4f2939cSRui Paulo 
3524*d4f2939cSRui Paulo 	arg->wpa_s = wpa_s;
3525*d4f2939cSRui Paulo 	os_memcpy(arg->member_addr, p2p_if_addr, ETH_ALEN);
3526*d4f2939cSRui Paulo 
3527*d4f2939cSRui Paulo 	wpas_dbus_register(obj_desc, arg, wpa_dbus_free, NULL,
3528*d4f2939cSRui Paulo 			   wpas_dbus_p2p_groupmember_properties, NULL);
3529*d4f2939cSRui Paulo 
3530*d4f2939cSRui Paulo 	if (wpa_dbus_register_object_per_iface(ctrl_iface, groupmember_obj_path,
3531*d4f2939cSRui Paulo 					       wpa_s->ifname, obj_desc))
3532*d4f2939cSRui Paulo 		goto err;
3533*d4f2939cSRui Paulo 
3534*d4f2939cSRui Paulo 	wpa_printf(MSG_INFO,
3535*d4f2939cSRui Paulo 		   "dbus: Registered group member object '%s' successfully",
3536*d4f2939cSRui Paulo 		   groupmember_obj_path);
3537*d4f2939cSRui Paulo 	return;
3538*d4f2939cSRui Paulo 
3539*d4f2939cSRui Paulo err:
3540*d4f2939cSRui Paulo 	free_dbus_object_desc(obj_desc);
3541*d4f2939cSRui Paulo }
3542*d4f2939cSRui Paulo 
3543*d4f2939cSRui Paulo /**
3544*d4f2939cSRui Paulo  * wpas_dbus_unregister_p2p_groupmember - Unregister a p2p groupmember
3545*d4f2939cSRui Paulo  * object with dbus
3546*d4f2939cSRui Paulo  * @wpa_s: wpa_supplicant interface structure
3547*d4f2939cSRui Paulo  * @p2p_if_addr: i/f addr of the device joining this group
3548*d4f2939cSRui Paulo  *
3549*d4f2939cSRui Paulo  * Unregisters p2p groupmember representing object with dbus
3550*d4f2939cSRui Paulo  */
3551*d4f2939cSRui Paulo void wpas_dbus_unregister_p2p_groupmember(struct wpa_supplicant *wpa_s,
3552*d4f2939cSRui Paulo 					  const u8 *p2p_if_addr)
3553*d4f2939cSRui Paulo {
3554*d4f2939cSRui Paulo 	struct wpas_dbus_priv *ctrl_iface;
3555*d4f2939cSRui Paulo 	char groupmember_obj_path[WPAS_DBUS_OBJECT_PATH_MAX];
3556*d4f2939cSRui Paulo 
3557*d4f2939cSRui Paulo 	/* Do nothing if the control interface is not turned on */
3558*d4f2939cSRui Paulo 	if (wpa_s == NULL || wpa_s->global == NULL)
3559*d4f2939cSRui Paulo 		return;
3560*d4f2939cSRui Paulo 
3561*d4f2939cSRui Paulo 	ctrl_iface = wpa_s->global->dbus;
3562*d4f2939cSRui Paulo 	if (ctrl_iface == NULL)
3563*d4f2939cSRui Paulo 		return;
3564*d4f2939cSRui Paulo 
3565*d4f2939cSRui Paulo 	if (!wpa_s->dbus_groupobj_path)
3566*d4f2939cSRui Paulo 		return;
3567*d4f2939cSRui Paulo 
3568*d4f2939cSRui Paulo 	os_snprintf(groupmember_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
3569*d4f2939cSRui Paulo 		"%s/" WPAS_DBUS_NEW_P2P_GROUPMEMBERS_PART "/" COMPACT_MACSTR,
3570*d4f2939cSRui Paulo 		wpa_s->dbus_groupobj_path, MAC2STR(p2p_if_addr));
3571*d4f2939cSRui Paulo 
3572*d4f2939cSRui Paulo 	wpa_dbus_unregister_object_per_iface(ctrl_iface, groupmember_obj_path);
3573*d4f2939cSRui Paulo }
3574*d4f2939cSRui Paulo 
3575*d4f2939cSRui Paulo 
3576*d4f2939cSRui Paulo static const struct wpa_dbus_property_desc
3577*d4f2939cSRui Paulo 	wpas_dbus_persistent_group_properties[] = {
3578*d4f2939cSRui Paulo 	{ "Properties", WPAS_DBUS_NEW_IFACE_PERSISTENT_GROUP, "a{sv}",
3579*d4f2939cSRui Paulo 	  wpas_dbus_getter_persistent_group_properties,
3580*d4f2939cSRui Paulo 	  wpas_dbus_setter_persistent_group_properties
3581*d4f2939cSRui Paulo 	},
3582*d4f2939cSRui Paulo 	{ NULL, NULL, NULL, NULL, NULL }
3583*d4f2939cSRui Paulo };
3584*d4f2939cSRui Paulo 
3585*d4f2939cSRui Paulo /* No signals intended for persistent group objects */
3586*d4f2939cSRui Paulo 
3587*d4f2939cSRui Paulo /**
3588*d4f2939cSRui Paulo  * wpas_dbus_register_persistent_group - Register a configured(saved)
3589*d4f2939cSRui Paulo  *	persistent group with dbus
3590*d4f2939cSRui Paulo  * @wpa_s: wpa_supplicant interface structure
3591*d4f2939cSRui Paulo  * @ssid: persistent group (still represented as a network within wpa)
3592*d4f2939cSRui Paulo  *	  configuration data
3593*d4f2939cSRui Paulo  * Returns: 0 on success, -1 on failure
3594*d4f2939cSRui Paulo  *
3595*d4f2939cSRui Paulo  * Registers a persistent group representing object with dbus.
3596*d4f2939cSRui Paulo  */
3597*d4f2939cSRui Paulo int wpas_dbus_register_persistent_group(struct wpa_supplicant *wpa_s,
3598*d4f2939cSRui Paulo 					struct wpa_ssid *ssid)
3599*d4f2939cSRui Paulo {
3600*d4f2939cSRui Paulo 	struct wpas_dbus_priv *ctrl_iface;
3601*d4f2939cSRui Paulo 	struct wpa_dbus_object_desc *obj_desc;
3602*d4f2939cSRui Paulo 	struct network_handler_args *arg;
3603*d4f2939cSRui Paulo 	char pgrp_obj_path[WPAS_DBUS_OBJECT_PATH_MAX];
3604*d4f2939cSRui Paulo 
3605*d4f2939cSRui Paulo 	/* Do nothing if the control interface is not turned on */
3606*d4f2939cSRui Paulo 	if (wpa_s == NULL || wpa_s->global == NULL)
3607*d4f2939cSRui Paulo 		return 0;
3608*d4f2939cSRui Paulo 
3609*d4f2939cSRui Paulo 	/* Make sure ssid is a persistent group */
3610*d4f2939cSRui Paulo 	if (ssid->disabled != 2 && !ssid->p2p_persistent_group)
3611*d4f2939cSRui Paulo 		return -1; /* should we return w/o complaining? */
3612*d4f2939cSRui Paulo 
3613*d4f2939cSRui Paulo 	ctrl_iface = wpa_s->global->dbus;
3614*d4f2939cSRui Paulo 	if (ctrl_iface == NULL)
3615*d4f2939cSRui Paulo 		return 0;
3616*d4f2939cSRui Paulo 
3617*d4f2939cSRui Paulo 	/*
3618*d4f2939cSRui Paulo 	 * Intentionally not coming up with different numbering scheme
3619*d4f2939cSRui Paulo 	 * for persistent groups.
3620*d4f2939cSRui Paulo 	 */
3621*d4f2939cSRui Paulo 	os_snprintf(pgrp_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
3622*d4f2939cSRui Paulo 		    "%s/" WPAS_DBUS_NEW_PERSISTENT_GROUPS_PART "/%u",
3623*d4f2939cSRui Paulo 		    wpa_s->dbus_new_path, ssid->id);
3624*d4f2939cSRui Paulo 
3625*d4f2939cSRui Paulo 	wpa_printf(MSG_DEBUG, "dbus: Register persistent group object '%s'",
3626*d4f2939cSRui Paulo 		   pgrp_obj_path);
3627*d4f2939cSRui Paulo 	obj_desc = os_zalloc(sizeof(struct wpa_dbus_object_desc));
3628*d4f2939cSRui Paulo 	if (!obj_desc) {
3629*d4f2939cSRui Paulo 		wpa_printf(MSG_ERROR, "dbus: Not enough memory to create "
3630*d4f2939cSRui Paulo 			   "object description");
3631*d4f2939cSRui Paulo 		goto err;
3632*d4f2939cSRui Paulo 	}
3633*d4f2939cSRui Paulo 
3634*d4f2939cSRui Paulo 	/*
3635*d4f2939cSRui Paulo 	 * Reusing the same context structure as that for networks
3636*d4f2939cSRui Paulo 	 * since these are represented using same data structure.
3637*d4f2939cSRui Paulo 	 */
3638*d4f2939cSRui Paulo 	/* allocate memory for handlers arguments */
3639*d4f2939cSRui Paulo 	arg = os_zalloc(sizeof(struct network_handler_args));
3640*d4f2939cSRui Paulo 	if (!arg) {
3641*d4f2939cSRui Paulo 		wpa_printf(MSG_ERROR, "dbus: Not enough memory to create "
3642*d4f2939cSRui Paulo 			   "arguments for method");
3643*d4f2939cSRui Paulo 		goto err;
3644*d4f2939cSRui Paulo 	}
3645*d4f2939cSRui Paulo 
3646*d4f2939cSRui Paulo 	arg->wpa_s = wpa_s;
3647*d4f2939cSRui Paulo 	arg->ssid = ssid;
3648*d4f2939cSRui Paulo 
3649*d4f2939cSRui Paulo 	wpas_dbus_register(obj_desc, arg, wpa_dbus_free, NULL,
3650*d4f2939cSRui Paulo 			   wpas_dbus_persistent_group_properties,
3651*d4f2939cSRui Paulo 			   NULL);
3652*d4f2939cSRui Paulo 
3653*d4f2939cSRui Paulo 	if (wpa_dbus_register_object_per_iface(ctrl_iface, pgrp_obj_path,
3654*d4f2939cSRui Paulo 					       wpa_s->ifname, obj_desc))
3655*d4f2939cSRui Paulo 		goto err;
3656*d4f2939cSRui Paulo 
3657*d4f2939cSRui Paulo 	wpas_dbus_signal_persistent_group_added(wpa_s, ssid->id);
3658*d4f2939cSRui Paulo 
3659*d4f2939cSRui Paulo 	return 0;
3660*d4f2939cSRui Paulo 
3661*d4f2939cSRui Paulo err:
3662*d4f2939cSRui Paulo 	free_dbus_object_desc(obj_desc);
3663*d4f2939cSRui Paulo 	return -1;
3664*d4f2939cSRui Paulo }
3665*d4f2939cSRui Paulo 
3666*d4f2939cSRui Paulo 
3667*d4f2939cSRui Paulo /**
3668*d4f2939cSRui Paulo  * wpas_dbus_unregister_persistent_group - Unregister a persistent_group
3669*d4f2939cSRui Paulo  *	from dbus
3670*d4f2939cSRui Paulo  * @wpa_s: wpa_supplicant interface structure
3671*d4f2939cSRui Paulo  * @nid: network id
3672*d4f2939cSRui Paulo  * Returns: 0 on success, -1 on failure
3673*d4f2939cSRui Paulo  *
3674*d4f2939cSRui Paulo  * Unregisters persistent group representing object from dbus
3675*d4f2939cSRui Paulo  *
3676*d4f2939cSRui Paulo  * NOTE: There is a slight issue with the semantics here. While the
3677*d4f2939cSRui Paulo  * implementation simply means the persistent group is unloaded from memory,
3678*d4f2939cSRui Paulo  * it should not get interpreted as the group is actually being erased/removed
3679*d4f2939cSRui Paulo  * from persistent storage as well.
3680*d4f2939cSRui Paulo  */
3681*d4f2939cSRui Paulo int wpas_dbus_unregister_persistent_group(struct wpa_supplicant *wpa_s,
3682*d4f2939cSRui Paulo 					  int nid)
3683*d4f2939cSRui Paulo {
3684*d4f2939cSRui Paulo 	struct wpas_dbus_priv *ctrl_iface;
3685*d4f2939cSRui Paulo 	char pgrp_obj_path[WPAS_DBUS_OBJECT_PATH_MAX];
3686*d4f2939cSRui Paulo 	int ret;
3687*d4f2939cSRui Paulo 
3688*d4f2939cSRui Paulo 	/* Do nothing if the control interface is not turned on */
3689*d4f2939cSRui Paulo 	if (wpa_s == NULL || wpa_s->global == NULL ||
3690*d4f2939cSRui Paulo 	    wpa_s->dbus_new_path == NULL)
3691*d4f2939cSRui Paulo 		return 0;
3692*d4f2939cSRui Paulo 	ctrl_iface = wpa_s->global->dbus;
3693*d4f2939cSRui Paulo 	if (ctrl_iface == NULL)
3694*d4f2939cSRui Paulo 		return 0;
3695*d4f2939cSRui Paulo 
3696*d4f2939cSRui Paulo 	os_snprintf(pgrp_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
3697*d4f2939cSRui Paulo 		    "%s/" WPAS_DBUS_NEW_PERSISTENT_GROUPS_PART "/%u",
3698*d4f2939cSRui Paulo 		    wpa_s->dbus_new_path, nid);
3699*d4f2939cSRui Paulo 
3700*d4f2939cSRui Paulo 	wpa_printf(MSG_DEBUG, "dbus: Unregister persistent group object '%s'",
3701*d4f2939cSRui Paulo 		   pgrp_obj_path);
3702*d4f2939cSRui Paulo 	ret = wpa_dbus_unregister_object_per_iface(ctrl_iface, pgrp_obj_path);
3703*d4f2939cSRui Paulo 
3704*d4f2939cSRui Paulo 	if (!ret)
3705*d4f2939cSRui Paulo 		wpas_dbus_signal_persistent_group_removed(wpa_s, nid);
3706*d4f2939cSRui Paulo 
3707*d4f2939cSRui Paulo 	return ret;
3708*d4f2939cSRui Paulo }
3709*d4f2939cSRui Paulo 
3710*d4f2939cSRui Paulo #endif /* CONFIG_P2P */
3711