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