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 224 : static DBusHandlerResult noc_filter(DBusConnection *conn,
51 : DBusMessage *message, void *data)
52 : {
53 224 : struct wpas_dbus_priv *priv = data;
54 :
55 224 : if (dbus_message_get_type(message) != DBUS_MESSAGE_TYPE_SIGNAL)
56 223 : 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 2 : void wpas_dbus_subscribe_noc(struct wpas_dbus_priv *priv)
95 : {
96 2 : priv->dbus_noc_refcnt++;
97 2 : if (priv->dbus_noc_refcnt > 1)
98 0 : return;
99 :
100 2 : 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 2 : dbus_bus_add_match(priv->con, wpas_dbus_noc_filter_str, NULL);
106 : }
107 :
108 :
109 2 : void wpas_dbus_unsubscribe_noc(struct wpas_dbus_priv *priv)
110 : {
111 2 : priv->dbus_noc_refcnt--;
112 2 : if (priv->dbus_noc_refcnt > 0)
113 2 : return;
114 :
115 2 : dbus_bus_remove_match(priv->con, wpas_dbus_noc_filter_str, NULL);
116 2 : 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 326 : 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 326 : iface = wpa_s->global->dbus;
138 :
139 : /* Do nothing if the control interface is not turned on */
140 326 : if (iface == NULL || !wpa_s->dbus_new_path)
141 0 : return;
142 :
143 326 : msg = dbus_message_new_signal(WPAS_DBUS_NEW_PATH,
144 : WPAS_DBUS_NEW_INTERFACE, sig_name);
145 326 : if (msg == NULL)
146 0 : return;
147 :
148 326 : dbus_message_iter_init_append(msg, &iter);
149 326 : if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_OBJECT_PATH,
150 652 : &wpa_s->dbus_new_path) ||
151 163 : (properties &&
152 163 : !wpa_dbus_get_object_properties(
153 163 : 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 323 : dbus_connection_send(iface->con, msg, NULL);
158 326 : 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 163 : static void wpas_dbus_signal_interface_added(struct wpa_supplicant *wpa_s)
169 : {
170 163 : wpas_dbus_signal_interface(wpa_s, "InterfaceAdded", TRUE);
171 163 : }
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 163 : static void wpas_dbus_signal_interface_removed(struct wpa_supplicant *wpa_s)
181 : {
182 163 : wpas_dbus_signal_interface(wpa_s, "InterfaceRemoved", FALSE);
183 :
184 163 : }
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 4373 : 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 4373 : iface = wpa_s->global->dbus;
201 :
202 : /* Do nothing if the control interface is not turned on */
203 4373 : if (iface == NULL || !wpa_s->dbus_new_path)
204 3912 : return;
205 :
206 2417 : msg = dbus_message_new_signal(wpa_s->dbus_new_path,
207 : WPAS_DBUS_NEW_IFACE_INTERFACE,
208 : "ScanDone");
209 2417 : if (msg == NULL)
210 0 : return;
211 :
212 2417 : succ = success ? TRUE : FALSE;
213 2417 : if (dbus_message_append_args(msg, DBUS_TYPE_BOOLEAN, &succ,
214 : DBUS_TYPE_INVALID))
215 2417 : dbus_connection_send(iface->con, msg, NULL);
216 : else
217 0 : wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
218 2417 : 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 3590 : 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 3590 : iface = wpa_s->global->dbus;
240 :
241 : /* Do nothing if the control interface is not turned on */
242 3590 : if (iface == NULL || !wpa_s->dbus_new_path)
243 0 : return;
244 :
245 3590 : msg = dbus_message_new_signal(wpa_s->dbus_new_path,
246 : WPAS_DBUS_NEW_IFACE_INTERFACE,
247 : sig_name);
248 3590 : if (msg == NULL)
249 0 : return;
250 :
251 3590 : dbus_message_iter_init_append(msg, &iter);
252 3590 : if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_OBJECT_PATH,
253 3590 : &bss_obj_path) ||
254 1795 : (properties &&
255 1795 : !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 3590 : dbus_connection_send(iface->con, msg, NULL);
261 3590 : 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 1795 : static void wpas_dbus_signal_bss_added(struct wpa_supplicant *wpa_s,
273 : const char *bss_obj_path)
274 : {
275 1795 : wpas_dbus_signal_bss(wpa_s, bss_obj_path, "BSSAdded", TRUE);
276 1795 : }
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 1795 : static void wpas_dbus_signal_bss_removed(struct wpa_supplicant *wpa_s,
287 : const char *bss_obj_path)
288 : {
289 1795 : wpas_dbus_signal_bss(wpa_s, bss_obj_path, "BSSRemoved", FALSE);
290 1795 : }
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 11757 : 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 11757 : iface = wpa_s->global->dbus;
375 :
376 : /* Do nothing if the control interface is not turned on */
377 11757 : if (iface == NULL || !wpa_s->dbus_new_path)
378 1856 : return;
379 :
380 10829 : 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 10829 : msg = dbus_message_new_signal(wpa_s->dbus_new_path,
385 : WPAS_DBUS_NEW_IFACE_INTERFACE,
386 : sig_name);
387 10829 : if (msg == NULL)
388 0 : return;
389 :
390 10829 : dbus_message_iter_init_append(msg, &iter);
391 10829 : path = net_obj_path;
392 10829 : if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_OBJECT_PATH,
393 10829 : &path) ||
394 4050 : (properties &&
395 4050 : !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 10829 : dbus_connection_send(iface->con, msg, NULL);
401 10829 : 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 4050 : static void wpas_dbus_signal_network_added(struct wpa_supplicant *wpa_s,
413 : int id)
414 : {
415 4050 : wpas_dbus_signal_network(wpa_s, id, "NetworkAdded", TRUE);
416 4050 : }
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 4052 : static void wpas_dbus_signal_network_removed(struct wpa_supplicant *wpa_s,
427 : int id)
428 : {
429 4052 : wpas_dbus_signal_network(wpa_s, id, "NetworkRemoved", FALSE);
430 4052 : }
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 3655 : void wpas_dbus_signal_network_selected(struct wpa_supplicant *wpa_s, int id)
441 : {
442 3655 : wpas_dbus_signal_network(wpa_s, id, "NetworkSelected", FALSE);
443 3655 : }
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 89 : 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 89 : const char *field, *txt = NULL, *net_ptr;
466 :
467 89 : iface = wpa_s->global->dbus;
468 :
469 : /* Do nothing if the control interface is not turned on */
470 89 : if (iface == NULL || !wpa_s->dbus_new_path)
471 2 : return;
472 :
473 88 : field = wpa_supplicant_ctrl_req_to_string(rtype, default_txt, &txt);
474 88 : if (field == NULL)
475 0 : return;
476 :
477 88 : msg = dbus_message_new_signal(wpa_s->dbus_new_path,
478 : WPAS_DBUS_NEW_IFACE_INTERFACE,
479 : "NetworkRequest");
480 88 : if (msg == NULL)
481 0 : return;
482 :
483 88 : 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 88 : net_ptr = &net_obj_path[0];
487 :
488 88 : dbus_message_iter_init_append(msg, &iter);
489 88 : if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_OBJECT_PATH,
490 88 : &net_ptr) ||
491 176 : !dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &field) ||
492 88 : !dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &txt))
493 0 : wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
494 : else
495 88 : dbus_connection_send(iface->con, msg, NULL);
496 88 : 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 3599 : 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 3599 : if (!wpa_s->dbus_new_path)
515 4475 : return;
516 2723 : 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 2723 : 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 329 : 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 329 : char *key = "success";
578 :
579 329 : iface = wpa_s->global->dbus;
580 :
581 : /* Do nothing if the control interface is not turned on */
582 329 : if (iface == NULL || !wpa_s->dbus_new_path)
583 408 : return;
584 :
585 125 : msg = dbus_message_new_signal(wpa_s->dbus_new_path,
586 : WPAS_DBUS_NEW_IFACE_WPS, "Event");
587 125 : if (msg == NULL)
588 0 : return;
589 :
590 125 : dbus_message_iter_init_append(msg, &iter);
591 :
592 250 : if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &key) ||
593 250 : !wpa_dbus_dict_open_write(&iter, &dict_iter) ||
594 125 : !wpa_dbus_dict_close_write(&iter, &dict_iter))
595 0 : wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
596 : else
597 125 : dbus_connection_send(iface->con, msg, NULL);
598 :
599 125 : 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 95 : 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 95 : char *key = "fail";
619 :
620 95 : iface = wpa_s->global->dbus;
621 :
622 : /* Do nothing if the control interface is not turned on */
623 95 : if (iface == NULL || !wpa_s->dbus_new_path)
624 36 : 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 30 : 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 30 : char *key = "m2d";
665 :
666 30 : iface = wpa_s->global->dbus;
667 :
668 : /* Do nothing if the control interface is not turned on */
669 30 : if (iface == NULL || !wpa_s->dbus_new_path)
670 44 : return;
671 :
672 8 : msg = dbus_message_new_signal(wpa_s->dbus_new_path,
673 : WPAS_DBUS_NEW_IFACE_WPS, "Event");
674 8 : if (msg == NULL)
675 0 : return;
676 :
677 8 : dbus_message_iter_init_append(msg, &iter);
678 :
679 16 : if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &key) ||
680 16 : !wpa_dbus_dict_open_write(&iter, &dict_iter) ||
681 8 : !wpa_dbus_dict_append_uint16(&dict_iter, "config_methods",
682 16 : m2d->config_methods) ||
683 16 : !wpa_dbus_dict_append_byte_array(&dict_iter, "manufacturer",
684 8 : (const char *) m2d->manufacturer,
685 16 : m2d->manufacturer_len) ||
686 16 : !wpa_dbus_dict_append_byte_array(&dict_iter, "model_name",
687 8 : (const char *) m2d->model_name,
688 16 : m2d->model_name_len) ||
689 16 : !wpa_dbus_dict_append_byte_array(&dict_iter, "model_number",
690 8 : (const char *) m2d->model_number,
691 16 : m2d->model_number_len) ||
692 16 : !wpa_dbus_dict_append_byte_array(&dict_iter, "serial_number",
693 : (const char *)
694 8 : m2d->serial_number,
695 16 : m2d->serial_number_len) ||
696 16 : !wpa_dbus_dict_append_byte_array(&dict_iter, "dev_name",
697 8 : (const char *) m2d->dev_name,
698 16 : m2d->dev_name_len) ||
699 8 : !wpa_dbus_dict_append_byte_array(&dict_iter, "primary_dev_type",
700 : (const char *)
701 16 : m2d->primary_dev_type, 8) ||
702 8 : !wpa_dbus_dict_append_uint16(&dict_iter, "config_error",
703 16 : m2d->config_error) ||
704 8 : !wpa_dbus_dict_append_uint16(&dict_iter, "dev_password_id",
705 16 : m2d->dev_password_id) ||
706 8 : !wpa_dbus_dict_close_write(&iter, &dict_iter))
707 0 : wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
708 : else
709 8 : dbus_connection_send(iface->con, msg, NULL);
710 :
711 8 : 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 941 : 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 941 : iface = wpa_s->global->dbus;
808 :
809 : /* Do nothing if the control interface is not turned on */
810 941 : if (iface == NULL || !wpa_s->dbus_new_path)
811 146 : return;
812 :
813 868 : msg = dbus_message_new_signal(wpa_s->dbus_new_path,
814 : WPAS_DBUS_NEW_IFACE_INTERFACE,
815 : "Certification");
816 868 : if (msg == NULL)
817 0 : return;
818 :
819 868 : dbus_message_iter_init_append(msg, &iter);
820 1736 : if (!wpa_dbus_dict_open_write(&iter, &dict_iter) ||
821 1736 : !wpa_dbus_dict_append_uint32(&dict_iter, "depth", depth) ||
822 1736 : !wpa_dbus_dict_append_string(&dict_iter, "subject", subject) ||
823 1276 : (altsubject && num_altsubject &&
824 408 : !wpa_dbus_dict_append_string_array(&dict_iter, "altsubject",
825 868 : altsubject, num_altsubject)) ||
826 868 : (cert_hash &&
827 868 : !wpa_dbus_dict_append_string(&dict_iter, "cert_hash",
828 868 : cert_hash)) ||
829 868 : (cert &&
830 1736 : !wpa_dbus_dict_append_byte_array(&dict_iter, "cert",
831 868 : wpabuf_head(cert),
832 1736 : wpabuf_len(cert))) ||
833 868 : !wpa_dbus_dict_close_write(&iter, &dict_iter))
834 0 : wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
835 : else
836 868 : dbus_connection_send(iface->con, msg, NULL);
837 868 : dbus_message_unref(msg);
838 : }
839 :
840 :
841 8693 : 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 8693 : iface = wpa_s->global->dbus;
849 :
850 : /* Do nothing if the control interface is not turned on */
851 8693 : if (iface == NULL || !wpa_s->dbus_new_path)
852 3222 : return;
853 :
854 7082 : msg = dbus_message_new_signal(wpa_s->dbus_new_path,
855 : WPAS_DBUS_NEW_IFACE_INTERFACE,
856 : "EAP");
857 7082 : if (msg == NULL)
858 0 : return;
859 :
860 7082 : dbus_message_iter_init_append(msg, &iter);
861 :
862 14164 : if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &status) ||
863 7082 : !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 7082 : dbus_connection_send(iface->con, msg, NULL);
868 7082 : 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 627 : 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 627 : os_snprintf(sta_mac, WPAS_DBUS_OBJECT_PATH_MAX, MACSTR, MAC2STR(sta));
889 627 : dev_mac = sta_mac;
890 :
891 627 : iface = wpa_s->global->dbus;
892 :
893 : /* Do nothing if the control interface is not turned on */
894 627 : if (iface == NULL || !wpa_s->dbus_new_path)
895 338 : return;
896 :
897 458 : msg = dbus_message_new_signal(wpa_s->dbus_new_path,
898 : WPAS_DBUS_NEW_IFACE_INTERFACE, sig_name);
899 458 : if (msg == NULL)
900 0 : return;
901 :
902 458 : if (dbus_message_append_args(msg, DBUS_TYPE_STRING, &dev_mac,
903 : DBUS_TYPE_INVALID))
904 458 : dbus_connection_send(iface->con, msg, NULL);
905 : else
906 0 : wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
907 458 : dbus_message_unref(msg);
908 :
909 458 : 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 314 : void wpas_dbus_signal_sta_authorized(struct wpa_supplicant *wpa_s,
922 : const u8 *sta)
923 : {
924 314 : wpas_dbus_signal_sta(wpa_s, sta, "StaAuthorized");
925 314 : }
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 313 : void wpas_dbus_signal_sta_deauthorized(struct wpa_supplicant *wpa_s,
936 : const u8 *sta)
937 : {
938 313 : wpas_dbus_signal_sta(wpa_s, sta, "StaDeauthorized");
939 313 : }
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 686 : 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 686 : 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 686 : if (iface == NULL)
960 639 : return;
961 :
962 370 : parent = wpa_s->parent;
963 370 : if (parent->p2p_mgmt)
964 0 : parent = parent->parent;
965 :
966 733 : if (!wpa_s->dbus_groupobj_path || !wpa_s->dbus_new_path ||
967 363 : !parent->dbus_new_path)
968 7 : return;
969 :
970 363 : msg = dbus_message_new_signal(parent->dbus_new_path,
971 : WPAS_DBUS_NEW_IFACE_P2PDEVICE,
972 : "GroupFinished");
973 363 : if (msg == NULL)
974 0 : return;
975 :
976 363 : dbus_message_iter_init_append(msg, &iter);
977 726 : if (!wpa_dbus_dict_open_write(&iter, &dict_iter) ||
978 363 : !wpa_dbus_dict_append_object_path(&dict_iter,
979 : "interface_object",
980 726 : wpa_s->dbus_new_path) ||
981 726 : !wpa_dbus_dict_append_string(&dict_iter, "role", role) ||
982 363 : !wpa_dbus_dict_append_object_path(&dict_iter, "group_object",
983 726 : wpa_s->dbus_groupobj_path) ||
984 363 : !wpa_dbus_dict_close_write(&iter, &dict_iter))
985 0 : wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
986 : else
987 363 : dbus_connection_send(iface->con, msg, NULL);
988 363 : 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 140 : 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 140 : int add_pin = 0;
1023 : char peer_obj_path[WPAS_DBUS_OBJECT_PATH_MAX], *path;
1024 140 : int error_ret = 1;
1025 140 : char pin[9], *p_pin = NULL;
1026 :
1027 140 : iface = wpa_s->global->dbus;
1028 :
1029 : /* Do nothing if the control interface is not turned on */
1030 140 : if (iface == NULL)
1031 103 : return;
1032 :
1033 89 : if (wpa_s->p2p_mgmt)
1034 0 : wpa_s = wpa_s->parent;
1035 89 : if (!wpa_s->dbus_new_path)
1036 0 : return;
1037 :
1038 89 : if (request || !status) {
1039 173 : if (config_methods & WPS_CONFIG_DISPLAY)
1040 77 : _signal = request ?
1041 77 : "ProvisionDiscoveryRequestDisplayPin" :
1042 : "ProvisionDiscoveryResponseEnterPin";
1043 10 : else if (config_methods & WPS_CONFIG_KEYPAD)
1044 3 : _signal = request ?
1045 3 : "ProvisionDiscoveryRequestEnterPin" :
1046 : "ProvisionDiscoveryResponseDisplayPin";
1047 7 : else if (config_methods & WPS_CONFIG_PUSHBUTTON)
1048 6 : _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 161 : add_pin = ((request && (config_methods & WPS_CONFIG_DISPLAY)) ||
1058 18 : (!request && !status &&
1059 8 : (config_methods & WPS_CONFIG_KEYPAD)));
1060 :
1061 88 : if (add_pin) {
1062 73 : os_snprintf(pin, sizeof(pin), "%08d", generated_pin);
1063 73 : p_pin = pin;
1064 : }
1065 :
1066 88 : msg = dbus_message_new_signal(wpa_s->dbus_new_path,
1067 : WPAS_DBUS_NEW_IFACE_P2PDEVICE, _signal);
1068 88 : if (msg == NULL)
1069 0 : return;
1070 :
1071 : /* Check if this is a known peer */
1072 88 : if (!p2p_peer_known(wpa_s->global->p2p, dev_addr))
1073 0 : goto error;
1074 :
1075 528 : os_snprintf(peer_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
1076 : "%s/" WPAS_DBUS_NEW_P2P_PEERS_PART "/"
1077 : COMPACT_MACSTR,
1078 528 : wpa_s->dbus_new_path, MAC2STR(dev_addr));
1079 :
1080 88 : path = peer_obj_path;
1081 :
1082 88 : dbus_message_iter_init_append(msg, &iter);
1083 :
1084 88 : if (!dbus_message_iter_append_basic(&iter,
1085 : DBUS_TYPE_OBJECT_PATH,
1086 : &path))
1087 0 : goto error;
1088 :
1089 88 : 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 159 : error_ret = (add_pin &&
1096 73 : !dbus_message_iter_append_basic(&iter,
1097 : DBUS_TYPE_STRING,
1098 : &p_pin));
1099 :
1100 : error:
1101 88 : if (!error_ret)
1102 88 : dbus_connection_send(iface->con, msg, NULL);
1103 : else
1104 0 : wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
1105 :
1106 88 : 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 41 : 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 41 : iface = wpa_s->global->dbus;
1130 :
1131 : /* Do nothing if the control interface is not turned on */
1132 41 : if (iface == NULL)
1133 54 : 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 363 : 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 726 : if (!wpa_s->dbus_new_path ||
1174 363 : os_memcmp(ssid->ssid, P2P_WILDCARD_SSID, P2P_WILDCARD_SSID_LEN))
1175 0 : return -1;
1176 :
1177 363 : os_memcpy(group_name, ssid->ssid + P2P_WILDCARD_SSID_LEN, 2);
1178 363 : group_name[2] = '\0';
1179 :
1180 363 : 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 363 : 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 224 : static int match_group_where_peer_is_client(struct p2p_group *group,
1195 : void *user_data)
1196 : {
1197 224 : struct group_changed_data *data = user_data;
1198 : const struct p2p_group_config *cfg;
1199 : struct wpa_supplicant *wpa_s_go;
1200 :
1201 224 : if (!p2p_group_is_client_connected(group, data->info->p2p_device_addr))
1202 43 : return 1;
1203 :
1204 181 : cfg = p2p_group_get_config(group);
1205 :
1206 181 : wpa_s_go = wpas_get_p2p_go_iface(data->wpa_s, cfg->ssid,
1207 : cfg->ssid_len);
1208 181 : if (wpa_s_go != NULL && wpa_s_go == data->wpa_s) {
1209 181 : wpas_dbus_signal_peer_groups_changed(
1210 181 : data->wpa_s->p2pdev, data->info->p2p_device_addr);
1211 181 : return 0;
1212 : }
1213 :
1214 0 : return 1;
1215 : }
1216 :
1217 :
1218 350 : static void signal_peer_groups_changed(struct p2p_peer_info *info,
1219 : void *user_data)
1220 : {
1221 350 : struct group_changed_data *data = user_data;
1222 : struct wpa_supplicant *wpa_s_go;
1223 :
1224 350 : wpa_s_go = wpas_get_p2p_client_iface(data->wpa_s,
1225 350 : info->p2p_device_addr);
1226 350 : if (wpa_s_go != NULL && wpa_s_go == data->wpa_s) {
1227 120 : wpas_dbus_signal_peer_groups_changed(data->wpa_s->p2pdev,
1228 120 : info->p2p_device_addr);
1229 470 : return;
1230 : }
1231 :
1232 230 : data->info = info;
1233 230 : p2p_loop_on_all_groups(data->wpa_s->global->p2p,
1234 : match_group_where_peer_is_client, data);
1235 230 : data->info = NULL;
1236 : }
1237 :
1238 :
1239 423 : static void peer_groups_changed(struct wpa_supplicant *wpa_s)
1240 : {
1241 : struct group_changed_data data;
1242 :
1243 423 : os_memset(&data, 0, sizeof(data));
1244 423 : data.wpa_s = wpa_s;
1245 :
1246 423 : p2p_loop_on_known_peers(wpa_s->global->p2p,
1247 : signal_peer_groups_changed, &data);
1248 423 : }
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 : * @client: this device is P2P client
1258 : * @persistent: 0 - non persistent group, 1 - persistent group
1259 : */
1260 667 : void wpas_dbus_signal_p2p_group_started(struct wpa_supplicant *wpa_s,
1261 : int client, int persistent)
1262 : {
1263 : DBusMessage *msg;
1264 : DBusMessageIter iter, dict_iter;
1265 : struct wpas_dbus_priv *iface;
1266 : struct wpa_supplicant *parent;
1267 :
1268 667 : parent = wpa_s->parent;
1269 667 : if (parent->p2p_mgmt)
1270 18 : parent = parent->parent;
1271 :
1272 667 : iface = parent->global->dbus;
1273 :
1274 : /* Do nothing if the control interface is not turned on */
1275 667 : if (iface == NULL || !parent->dbus_new_path || !wpa_s->dbus_new_path)
1276 608 : return;
1277 :
1278 363 : if (wpa_s->dbus_groupobj_path == NULL)
1279 0 : return;
1280 :
1281 : /* New interface has been created for this group */
1282 363 : msg = dbus_message_new_signal(parent->dbus_new_path,
1283 : WPAS_DBUS_NEW_IFACE_P2PDEVICE,
1284 : "GroupStarted");
1285 363 : if (msg == NULL)
1286 0 : return;
1287 :
1288 363 : dbus_message_iter_init_append(msg, &iter);
1289 : /*
1290 : * In case the device supports creating a separate interface the
1291 : * DBus client will need to know the object path for the interface
1292 : * object this group was created on, so include it here.
1293 : */
1294 726 : if (!wpa_dbus_dict_open_write(&iter, &dict_iter) ||
1295 363 : !wpa_dbus_dict_append_object_path(&dict_iter,
1296 : "interface_object",
1297 726 : wpa_s->dbus_new_path) ||
1298 363 : !wpa_dbus_dict_append_string(&dict_iter, "role",
1299 363 : client ? "client" : "GO") ||
1300 726 : !wpa_dbus_dict_append_bool(&dict_iter, "persistent", persistent) ||
1301 363 : !wpa_dbus_dict_append_object_path(&dict_iter, "group_object",
1302 726 : wpa_s->dbus_groupobj_path) ||
1303 363 : !wpa_dbus_dict_close_write(&iter, &dict_iter)) {
1304 0 : wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
1305 : } else {
1306 363 : dbus_connection_send(iface->con, msg, NULL);
1307 363 : if (client)
1308 60 : peer_groups_changed(wpa_s);
1309 : }
1310 363 : dbus_message_unref(msg);
1311 : }
1312 :
1313 :
1314 : /**
1315 : * wpas_dbus_signal_p2p_go_neg_resp - Emit GONegotiation Success/Failure signal
1316 : * @wpa_s: %wpa_supplicant network interface data
1317 : * @res: Result of the GO Neg Request
1318 : */
1319 312 : void wpas_dbus_signal_p2p_go_neg_resp(struct wpa_supplicant *wpa_s,
1320 : struct p2p_go_neg_results *res)
1321 : {
1322 : DBusMessage *msg;
1323 : DBusMessageIter iter, dict_iter;
1324 : DBusMessageIter iter_dict_entry, iter_dict_val, iter_dict_array;
1325 : struct wpas_dbus_priv *iface;
1326 : char peer_obj_path[WPAS_DBUS_OBJECT_PATH_MAX], *path;
1327 : dbus_int32_t freqs[P2P_MAX_CHANNELS];
1328 312 : dbus_int32_t *f_array = freqs;
1329 :
1330 :
1331 312 : iface = wpa_s->global->dbus;
1332 :
1333 312 : if (wpa_s->p2p_mgmt)
1334 18 : wpa_s = wpa_s->parent;
1335 :
1336 312 : os_memset(freqs, 0, sizeof(freqs));
1337 : /* Do nothing if the control interface is not turned on */
1338 312 : if (iface == NULL || !wpa_s->dbus_new_path)
1339 332 : return;
1340 :
1341 876 : os_snprintf(peer_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
1342 : "%s/" WPAS_DBUS_NEW_P2P_PEERS_PART "/" COMPACT_MACSTR,
1343 876 : wpa_s->dbus_new_path, MAC2STR(res->peer_device_addr));
1344 146 : path = peer_obj_path;
1345 :
1346 146 : msg = dbus_message_new_signal(wpa_s->dbus_new_path,
1347 : WPAS_DBUS_NEW_IFACE_P2PDEVICE,
1348 146 : res->status ? "GONegotiationFailure" :
1349 : "GONegotiationSuccess");
1350 146 : if (msg == NULL)
1351 0 : return;
1352 :
1353 146 : dbus_message_iter_init_append(msg, &iter);
1354 292 : if (!wpa_dbus_dict_open_write(&iter, &dict_iter) ||
1355 146 : !wpa_dbus_dict_append_object_path(&dict_iter, "peer_object",
1356 146 : path) ||
1357 146 : !wpa_dbus_dict_append_int32(&dict_iter, "status", res->status))
1358 : goto err;
1359 :
1360 146 : if (!res->status) {
1361 139 : int i = 0;
1362 139 : int freq_list_num = 0;
1363 :
1364 235 : if ((res->role_go &&
1365 96 : !wpa_dbus_dict_append_string(&dict_iter, "passphrase",
1366 235 : res->passphrase)) ||
1367 139 : !wpa_dbus_dict_append_string(&dict_iter, "role_go",
1368 139 : res->role_go ? "GO" :
1369 139 : "client") ||
1370 139 : !wpa_dbus_dict_append_int32(&dict_iter, "frequency",
1371 139 : res->freq) ||
1372 278 : !wpa_dbus_dict_append_byte_array(&dict_iter, "ssid",
1373 139 : (const char *) res->ssid,
1374 278 : res->ssid_len) ||
1375 139 : !wpa_dbus_dict_append_byte_array(&dict_iter,
1376 : "peer_device_addr",
1377 : (const char *)
1378 139 : res->peer_device_addr,
1379 139 : ETH_ALEN) ||
1380 139 : !wpa_dbus_dict_append_byte_array(&dict_iter,
1381 : "peer_interface_addr",
1382 : (const char *)
1383 139 : res->peer_interface_addr,
1384 139 : ETH_ALEN) ||
1385 139 : !wpa_dbus_dict_append_string(&dict_iter, "wps_method",
1386 : p2p_wps_method_text(
1387 : res->wps_method)))
1388 : goto err;
1389 :
1390 7089 : for (i = 0; i < P2P_MAX_CHANNELS; i++) {
1391 6950 : if (res->freq_list[i]) {
1392 1285 : freqs[i] = res->freq_list[i];
1393 1285 : freq_list_num++;
1394 : }
1395 : }
1396 :
1397 139 : if (!wpa_dbus_dict_begin_array(&dict_iter,
1398 : "frequency_list",
1399 : DBUS_TYPE_INT32_AS_STRING,
1400 : &iter_dict_entry,
1401 : &iter_dict_val,
1402 139 : &iter_dict_array) ||
1403 139 : !dbus_message_iter_append_fixed_array(&iter_dict_array,
1404 : DBUS_TYPE_INT32,
1405 : &f_array,
1406 139 : freq_list_num) ||
1407 139 : !wpa_dbus_dict_end_array(&dict_iter,
1408 : &iter_dict_entry,
1409 : &iter_dict_val,
1410 139 : &iter_dict_array) ||
1411 139 : !wpa_dbus_dict_append_int32(&dict_iter, "persistent_group",
1412 139 : res->persistent_group) ||
1413 139 : !wpa_dbus_dict_append_uint32(&dict_iter,
1414 : "peer_config_timeout",
1415 : res->peer_config_timeout))
1416 : goto err;
1417 : }
1418 :
1419 146 : if (!wpa_dbus_dict_close_write(&iter, &dict_iter))
1420 0 : goto err;
1421 :
1422 146 : dbus_connection_send(iface->con, msg, NULL);
1423 : err:
1424 146 : dbus_message_unref(msg);
1425 : }
1426 :
1427 :
1428 : /**
1429 : * wpas_dbus_signal_p2p_invitation_result - Emit InvitationResult signal
1430 : * @wpa_s: %wpa_supplicant network interface data
1431 : * @status: Status of invitation process
1432 : * @bssid: Basic Service Set Identifier
1433 : */
1434 64 : void wpas_dbus_signal_p2p_invitation_result(struct wpa_supplicant *wpa_s,
1435 : int status, const u8 *bssid)
1436 : {
1437 : DBusMessage *msg;
1438 : DBusMessageIter iter, dict_iter;
1439 : struct wpas_dbus_priv *iface;
1440 :
1441 64 : wpa_printf(MSG_DEBUG, "%s", __func__);
1442 :
1443 64 : iface = wpa_s->global->dbus;
1444 : /* Do nothing if the control interface is not turned on */
1445 64 : if (iface == NULL)
1446 54 : return;
1447 :
1448 37 : if (wpa_s->p2p_mgmt)
1449 0 : wpa_s = wpa_s->parent;
1450 37 : if (!wpa_s->dbus_new_path)
1451 0 : return;
1452 :
1453 37 : msg = dbus_message_new_signal(wpa_s->dbus_new_path,
1454 : WPAS_DBUS_NEW_IFACE_P2PDEVICE,
1455 : "InvitationResult");
1456 :
1457 37 : if (msg == NULL)
1458 0 : return;
1459 :
1460 37 : dbus_message_iter_init_append(msg, &iter);
1461 74 : if (!wpa_dbus_dict_open_write(&iter, &dict_iter) ||
1462 74 : !wpa_dbus_dict_append_int32(&dict_iter, "status", status) ||
1463 2 : (bssid &&
1464 2 : !wpa_dbus_dict_append_byte_array(&dict_iter, "BSSID",
1465 : (const char *) bssid,
1466 37 : ETH_ALEN)) ||
1467 37 : !wpa_dbus_dict_close_write(&iter, &dict_iter))
1468 0 : wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
1469 : else
1470 37 : dbus_connection_send(iface->con, msg, NULL);
1471 37 : dbus_message_unref(msg);
1472 : }
1473 :
1474 :
1475 : /**
1476 : *
1477 : * Method to emit a signal for a peer joining the group.
1478 : * The signal will carry path to the group member object
1479 : * constructed using p2p i/f addr used for connecting.
1480 : *
1481 : * @wpa_s: %wpa_supplicant network interface data
1482 : * @peer_addr: P2P Device Address of the peer joining the group
1483 : */
1484 277 : void wpas_dbus_signal_p2p_peer_joined(struct wpa_supplicant *wpa_s,
1485 : const u8 *peer_addr)
1486 : {
1487 : struct wpas_dbus_priv *iface;
1488 : DBusMessage *msg;
1489 : DBusMessageIter iter;
1490 : char peer_obj_path[WPAS_DBUS_OBJECT_PATH_MAX], *path;
1491 : struct wpa_supplicant *parent;
1492 :
1493 277 : iface = wpa_s->global->dbus;
1494 :
1495 : /* Do nothing if the control interface is not turned on */
1496 277 : if (iface == NULL)
1497 150 : return;
1498 :
1499 202 : if (!wpa_s->dbus_groupobj_path)
1500 0 : return;
1501 :
1502 202 : parent = wpa_s->parent;
1503 202 : if (parent->p2p_mgmt)
1504 0 : parent = parent->parent;
1505 202 : if (!parent->dbus_new_path)
1506 0 : return;
1507 :
1508 1212 : os_snprintf(peer_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
1509 : "%s/" WPAS_DBUS_NEW_P2P_PEERS_PART "/"
1510 : COMPACT_MACSTR,
1511 1212 : parent->dbus_new_path, MAC2STR(peer_addr));
1512 :
1513 202 : msg = dbus_message_new_signal(wpa_s->dbus_groupobj_path,
1514 : WPAS_DBUS_NEW_IFACE_P2P_GROUP,
1515 : "PeerJoined");
1516 202 : if (msg == NULL)
1517 0 : return;
1518 :
1519 202 : dbus_message_iter_init_append(msg, &iter);
1520 202 : path = peer_obj_path;
1521 202 : if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_OBJECT_PATH,
1522 : &path)) {
1523 0 : wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
1524 : } else {
1525 202 : dbus_connection_send(iface->con, msg, NULL);
1526 202 : wpas_dbus_signal_peer_groups_changed(parent, peer_addr);
1527 : }
1528 202 : dbus_message_unref(msg);
1529 : }
1530 :
1531 :
1532 : /**
1533 : *
1534 : * Method to emit a signal for a peer disconnecting the group.
1535 : * The signal will carry path to the group member object
1536 : * constructed using the P2P Device Address of the peer.
1537 : *
1538 : * @wpa_s: %wpa_supplicant network interface data
1539 : * @peer_addr: P2P Device Address of the peer joining the group
1540 : */
1541 277 : void wpas_dbus_signal_p2p_peer_disconnected(struct wpa_supplicant *wpa_s,
1542 : const u8 *peer_addr)
1543 : {
1544 : struct wpas_dbus_priv *iface;
1545 : DBusMessage *msg;
1546 : DBusMessageIter iter;
1547 : char peer_obj_path[WPAS_DBUS_OBJECT_PATH_MAX], *path;
1548 : struct wpa_supplicant *parent;
1549 :
1550 277 : iface = wpa_s->global->dbus;
1551 :
1552 : /* Do nothing if the control interface is not turned on */
1553 277 : if (iface == NULL)
1554 323 : return;
1555 :
1556 202 : if (!wpa_s->dbus_groupobj_path)
1557 173 : return;
1558 :
1559 29 : parent = wpa_s->parent;
1560 29 : if (parent->p2p_mgmt)
1561 0 : parent = parent->parent;
1562 29 : if (!parent->dbus_new_path)
1563 0 : return;
1564 :
1565 174 : os_snprintf(peer_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
1566 : "%s/" WPAS_DBUS_NEW_P2P_PEERS_PART "/"
1567 : COMPACT_MACSTR,
1568 174 : parent->dbus_new_path, MAC2STR(peer_addr));
1569 :
1570 29 : msg = dbus_message_new_signal(wpa_s->dbus_groupobj_path,
1571 : WPAS_DBUS_NEW_IFACE_P2P_GROUP,
1572 : "PeerDisconnected");
1573 29 : if (msg == NULL)
1574 0 : return;
1575 :
1576 29 : dbus_message_iter_init_append(msg, &iter);
1577 29 : path = peer_obj_path;
1578 29 : if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_OBJECT_PATH,
1579 : &path)) {
1580 0 : wpa_printf(MSG_ERROR,
1581 : "dbus: Failed to construct PeerDisconnected signal");
1582 : } else {
1583 29 : dbus_connection_send(iface->con, msg, NULL);
1584 29 : wpas_dbus_signal_peer_groups_changed(parent, peer_addr);
1585 : }
1586 29 : dbus_message_unref(msg);
1587 : }
1588 :
1589 :
1590 : /**
1591 : *
1592 : * Method to emit a signal for a service discovery request.
1593 : * The signal will carry station address, frequency, dialog token,
1594 : * update indicator and it tlvs
1595 : *
1596 : * @wpa_s: %wpa_supplicant network interface data
1597 : * @sa: station addr (p2p i/f) of the peer
1598 : * @dialog_token: service discovery request dialog token
1599 : * @update_indic: service discovery request update indicator
1600 : * @tlvs: service discovery request genrated byte array of tlvs
1601 : * @tlvs_len: service discovery request tlvs length
1602 : */
1603 85 : void wpas_dbus_signal_p2p_sd_request(struct wpa_supplicant *wpa_s,
1604 : int freq, const u8 *sa, u8 dialog_token,
1605 : u16 update_indic, const u8 *tlvs,
1606 : size_t tlvs_len)
1607 : {
1608 : DBusMessage *msg;
1609 : DBusMessageIter iter, dict_iter;
1610 : struct wpas_dbus_priv *iface;
1611 : char peer_obj_path[WPAS_DBUS_OBJECT_PATH_MAX], *path;
1612 :
1613 85 : iface = wpa_s->global->dbus;
1614 :
1615 : /* Do nothing if the control interface is not turned on */
1616 85 : if (iface == NULL)
1617 21 : return;
1618 :
1619 75 : if (wpa_s->p2p_mgmt)
1620 0 : wpa_s = wpa_s->parent;
1621 75 : if (!wpa_s->dbus_new_path)
1622 0 : return;
1623 :
1624 : /* Check if this is a known peer */
1625 75 : if (!p2p_peer_known(wpa_s->global->p2p, sa))
1626 1 : return;
1627 :
1628 74 : msg = dbus_message_new_signal(wpa_s->dbus_new_path,
1629 : WPAS_DBUS_NEW_IFACE_P2PDEVICE,
1630 : "ServiceDiscoveryRequest");
1631 74 : if (msg == NULL)
1632 0 : return;
1633 :
1634 444 : os_snprintf(peer_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
1635 : "%s/" WPAS_DBUS_NEW_P2P_PEERS_PART "/"
1636 444 : COMPACT_MACSTR, wpa_s->dbus_new_path, MAC2STR(sa));
1637 :
1638 74 : path = peer_obj_path;
1639 :
1640 74 : dbus_message_iter_init_append(msg, &iter);
1641 148 : if (!wpa_dbus_dict_open_write(&iter, &dict_iter) ||
1642 74 : !wpa_dbus_dict_append_object_path(&dict_iter, "peer_object",
1643 74 : path) ||
1644 148 : !wpa_dbus_dict_append_int32(&dict_iter, "frequency", freq) ||
1645 74 : !wpa_dbus_dict_append_int32(&dict_iter, "dialog_token",
1646 74 : dialog_token) ||
1647 74 : !wpa_dbus_dict_append_uint16(&dict_iter, "update_indicator",
1648 74 : update_indic) ||
1649 74 : !wpa_dbus_dict_append_byte_array(&dict_iter, "tlvs",
1650 : (const char *) tlvs,
1651 74 : tlvs_len) ||
1652 74 : !wpa_dbus_dict_close_write(&iter, &dict_iter))
1653 0 : wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
1654 : else
1655 74 : dbus_connection_send(iface->con, msg, NULL);
1656 74 : dbus_message_unref(msg);
1657 : }
1658 :
1659 :
1660 : /**
1661 : *
1662 : * Method to emit a signal for a service discovery response.
1663 : * The signal will carry station address, update indicator and it
1664 : * tlvs
1665 : *
1666 : * @wpa_s: %wpa_supplicant network interface data
1667 : * @sa: station addr (p2p i/f) of the peer
1668 : * @update_indic: service discovery request update indicator
1669 : * @tlvs: service discovery request genrated byte array of tlvs
1670 : * @tlvs_len: service discovery request tlvs length
1671 : */
1672 84 : void wpas_dbus_signal_p2p_sd_response(struct wpa_supplicant *wpa_s,
1673 : const u8 *sa, u16 update_indic,
1674 : const u8 *tlvs, size_t tlvs_len)
1675 : {
1676 : DBusMessage *msg;
1677 : DBusMessageIter iter, dict_iter;
1678 : struct wpas_dbus_priv *iface;
1679 : char peer_obj_path[WPAS_DBUS_OBJECT_PATH_MAX], *path;
1680 :
1681 84 : iface = wpa_s->global->dbus;
1682 :
1683 : /* Do nothing if the control interface is not turned on */
1684 84 : if (iface == NULL)
1685 162 : return;
1686 :
1687 3 : if (wpa_s->p2p_mgmt)
1688 0 : wpa_s = wpa_s->parent;
1689 3 : if (!wpa_s->dbus_new_path)
1690 0 : return;
1691 :
1692 : /* Check if this is a known peer */
1693 3 : if (!p2p_peer_known(wpa_s->global->p2p, sa))
1694 0 : return;
1695 :
1696 3 : msg = dbus_message_new_signal(wpa_s->dbus_new_path,
1697 : WPAS_DBUS_NEW_IFACE_P2PDEVICE,
1698 : "ServiceDiscoveryResponse");
1699 3 : if (msg == NULL)
1700 0 : return;
1701 :
1702 18 : os_snprintf(peer_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
1703 : "%s/" WPAS_DBUS_NEW_P2P_PEERS_PART "/"
1704 18 : COMPACT_MACSTR, wpa_s->dbus_new_path, MAC2STR(sa));
1705 :
1706 3 : path = peer_obj_path;
1707 :
1708 3 : dbus_message_iter_init_append(msg, &iter);
1709 6 : if (!wpa_dbus_dict_open_write(&iter, &dict_iter) ||
1710 3 : !wpa_dbus_dict_append_object_path(&dict_iter, "peer_object",
1711 3 : path) ||
1712 3 : !wpa_dbus_dict_append_uint16(&dict_iter, "update_indicator",
1713 3 : update_indic) ||
1714 3 : !wpa_dbus_dict_append_byte_array(&dict_iter, "tlvs",
1715 : (const char *) tlvs,
1716 3 : tlvs_len) ||
1717 3 : !wpa_dbus_dict_close_write(&iter, &dict_iter))
1718 0 : wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
1719 : else
1720 3 : dbus_connection_send(iface->con, msg, NULL);
1721 3 : dbus_message_unref(msg);
1722 : }
1723 :
1724 :
1725 : /**
1726 : * wpas_dbus_signal_persistent_group - Send a persistent group related
1727 : * event signal
1728 : * @wpa_s: %wpa_supplicant network interface data
1729 : * @id: new persistent group id
1730 : * @sig_name: signal name - PersistentGroupAdded, PersistentGroupRemoved
1731 : * @properties: determines if add second argument with object properties
1732 : *
1733 : * Notify listeners about an event related to persistent groups.
1734 : */
1735 156 : static void wpas_dbus_signal_persistent_group(struct wpa_supplicant *wpa_s,
1736 : int id, const char *sig_name,
1737 : int properties)
1738 : {
1739 : struct wpas_dbus_priv *iface;
1740 : DBusMessage *msg;
1741 : DBusMessageIter iter;
1742 : char pgrp_obj_path[WPAS_DBUS_OBJECT_PATH_MAX], *path;
1743 :
1744 156 : iface = wpa_s->global->dbus;
1745 :
1746 : /* Do nothing if the control interface is not turned on */
1747 156 : if (iface == NULL)
1748 0 : return;
1749 :
1750 156 : if (wpa_s->p2p_mgmt)
1751 0 : wpa_s = wpa_s->parent;
1752 156 : if (!wpa_s->dbus_new_path)
1753 0 : return;
1754 :
1755 156 : os_snprintf(pgrp_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
1756 : "%s/" WPAS_DBUS_NEW_PERSISTENT_GROUPS_PART "/%u",
1757 : wpa_s->dbus_new_path, id);
1758 :
1759 156 : msg = dbus_message_new_signal(wpa_s->dbus_new_path,
1760 : WPAS_DBUS_NEW_IFACE_P2PDEVICE,
1761 : sig_name);
1762 156 : if (msg == NULL)
1763 0 : return;
1764 :
1765 156 : dbus_message_iter_init_append(msg, &iter);
1766 156 : path = pgrp_obj_path;
1767 156 : if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_OBJECT_PATH,
1768 156 : &path) ||
1769 77 : (properties &&
1770 77 : !wpa_dbus_get_object_properties(
1771 : iface, pgrp_obj_path,
1772 : WPAS_DBUS_NEW_IFACE_PERSISTENT_GROUP, &iter)))
1773 0 : wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
1774 : else
1775 156 : dbus_connection_send(iface->con, msg, NULL);
1776 :
1777 156 : dbus_message_unref(msg);
1778 : }
1779 :
1780 :
1781 : /**
1782 : * wpas_dbus_signal_persistent_group_added - Send a persistent_group
1783 : * added signal
1784 : * @wpa_s: %wpa_supplicant network interface data
1785 : * @id: new persistent group id
1786 : *
1787 : * Notify listeners about addition of a new persistent group.
1788 : */
1789 77 : static void wpas_dbus_signal_persistent_group_added(
1790 : struct wpa_supplicant *wpa_s, int id)
1791 : {
1792 77 : wpas_dbus_signal_persistent_group(wpa_s, id, "PersistentGroupAdded",
1793 : TRUE);
1794 77 : }
1795 :
1796 :
1797 : /**
1798 : * wpas_dbus_signal_persistent_group_removed - Send a persistent_group
1799 : * removed signal
1800 : * @wpa_s: %wpa_supplicant network interface data
1801 : * @id: persistent group id
1802 : *
1803 : * Notify listeners about removal of a persistent group.
1804 : */
1805 79 : static void wpas_dbus_signal_persistent_group_removed(
1806 : struct wpa_supplicant *wpa_s, int id)
1807 : {
1808 79 : wpas_dbus_signal_persistent_group(wpa_s, id, "PersistentGroupRemoved",
1809 : FALSE);
1810 79 : }
1811 :
1812 :
1813 : /**
1814 : * wpas_dbus_signal_p2p_wps_failed - Signals WpsFailed event
1815 : * @wpa_s: %wpa_supplicant network interface data
1816 : * @fail: WPS failure information
1817 : *
1818 : * Sends Event dbus signal with name "fail" and dictionary containing
1819 : * "msg" field with fail message number (int32) as arguments
1820 : */
1821 7 : void wpas_dbus_signal_p2p_wps_failed(struct wpa_supplicant *wpa_s,
1822 : struct wps_event_fail *fail)
1823 : {
1824 :
1825 : DBusMessage *msg;
1826 : DBusMessageIter iter, dict_iter;
1827 : struct wpas_dbus_priv *iface;
1828 7 : char *key = "fail";
1829 :
1830 7 : iface = wpa_s->global->dbus;
1831 :
1832 : /* Do nothing if the control interface is not turned on */
1833 7 : if (iface == NULL)
1834 8 : return;
1835 :
1836 3 : if (wpa_s->p2p_mgmt)
1837 0 : wpa_s = wpa_s->parent;
1838 :
1839 3 : if (!wpa_s->dbus_new_path)
1840 0 : return;
1841 3 : msg = dbus_message_new_signal(wpa_s->dbus_new_path,
1842 : WPAS_DBUS_NEW_IFACE_P2PDEVICE,
1843 : "WpsFailed");
1844 3 : if (msg == NULL)
1845 0 : return;
1846 :
1847 3 : dbus_message_iter_init_append(msg, &iter);
1848 :
1849 6 : if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &key) ||
1850 6 : !wpa_dbus_dict_open_write(&iter, &dict_iter) ||
1851 6 : !wpa_dbus_dict_append_int32(&dict_iter, "msg", fail->msg) ||
1852 3 : !wpa_dbus_dict_append_int16(&dict_iter, "config_error",
1853 6 : fail->config_error) ||
1854 3 : !wpa_dbus_dict_close_write(&iter, &dict_iter))
1855 0 : wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
1856 : else
1857 3 : dbus_connection_send(iface->con, msg, NULL);
1858 :
1859 3 : dbus_message_unref(msg);
1860 : }
1861 :
1862 :
1863 : /**
1864 : * wpas_dbus_signal_p2p_group_formation_failure - Signals GroupFormationFailure event
1865 : * @wpa_s: %wpa_supplicant network interface data
1866 : * @reason: indicates the reason code for group formation failure
1867 : *
1868 : * Sends Event dbus signal and string reason code when available.
1869 : */
1870 30 : void wpas_dbus_signal_p2p_group_formation_failure(struct wpa_supplicant *wpa_s,
1871 : const char *reason)
1872 : {
1873 : DBusMessage *msg;
1874 : struct wpas_dbus_priv *iface;
1875 :
1876 30 : iface = wpa_s->global->dbus;
1877 :
1878 : /* Do nothing if the control interface is not turned on */
1879 30 : if (iface == NULL)
1880 17 : return;
1881 :
1882 13 : msg = dbus_message_new_signal(wpa_s->dbus_new_path,
1883 : WPAS_DBUS_NEW_IFACE_P2PDEVICE,
1884 : "GroupFormationFailure");
1885 13 : if (msg == NULL)
1886 0 : return;
1887 :
1888 13 : if (dbus_message_append_args(msg, DBUS_TYPE_STRING, &reason,
1889 : DBUS_TYPE_INVALID))
1890 13 : dbus_connection_send(iface->con, msg, NULL);
1891 : else
1892 0 : wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
1893 :
1894 13 : dbus_message_unref(msg);
1895 : }
1896 :
1897 :
1898 : /**
1899 : * wpas_dbus_signal_p2p_invitation_received - Emit InvitationReceived signal
1900 : * @wpa_s: %wpa_supplicant network interface data
1901 : * @sa: Source address of the Invitation Request
1902 : * @dev_add: GO Device Address
1903 : * @bssid: P2P Group BSSID or %NULL if not received
1904 : * @id: Persistent group id or %0 if not persistent group
1905 : * @op_freq: Operating frequency for the group
1906 : */
1907 :
1908 19 : void wpas_dbus_signal_p2p_invitation_received(struct wpa_supplicant *wpa_s,
1909 : const u8 *sa, const u8 *dev_addr,
1910 : const u8 *bssid, int id,
1911 : int op_freq)
1912 : {
1913 : DBusMessage *msg;
1914 : DBusMessageIter iter, dict_iter;
1915 : struct wpas_dbus_priv *iface;
1916 :
1917 19 : iface = wpa_s->global->dbus;
1918 :
1919 : /* Do nothing if the control interface is not turned on */
1920 19 : if (iface == NULL)
1921 14 : return;
1922 :
1923 12 : msg = dbus_message_new_signal(wpa_s->dbus_new_path,
1924 : WPAS_DBUS_NEW_IFACE_P2PDEVICE,
1925 : "InvitationReceived");
1926 12 : if (msg == NULL)
1927 0 : return;
1928 :
1929 12 : dbus_message_iter_init_append(msg, &iter);
1930 12 : if (!wpa_dbus_dict_open_write(&iter, &dict_iter) ||
1931 12 : (sa &&
1932 12 : !wpa_dbus_dict_append_byte_array(&dict_iter, "sa",
1933 12 : (const char *) sa, ETH_ALEN)) ||
1934 12 : (dev_addr &&
1935 12 : !wpa_dbus_dict_append_byte_array(&dict_iter, "go_dev_addr",
1936 : (const char *) dev_addr,
1937 12 : ETH_ALEN)) ||
1938 9 : (bssid &&
1939 9 : !wpa_dbus_dict_append_byte_array(&dict_iter, "bssid",
1940 : (const char *) bssid,
1941 12 : ETH_ALEN)) ||
1942 2 : (id &&
1943 14 : !wpa_dbus_dict_append_int32(&dict_iter, "persistent_id", id)) ||
1944 24 : !wpa_dbus_dict_append_int32(&dict_iter, "op_freq", op_freq) ||
1945 12 : !wpa_dbus_dict_close_write(&iter, &dict_iter)) {
1946 0 : dbus_message_unref(msg);
1947 0 : return;
1948 : }
1949 :
1950 12 : dbus_connection_send(iface->con, msg, NULL);
1951 12 : dbus_message_unref(msg);
1952 : }
1953 :
1954 :
1955 : #endif /* CONFIG_P2P */
1956 :
1957 :
1958 : /**
1959 : * wpas_dbus_signal_prop_changed - Signals change of property
1960 : * @wpa_s: %wpa_supplicant network interface data
1961 : * @property: indicates which property has changed
1962 : *
1963 : * Sends PropertyChanged signals with path, interface and arguments
1964 : * depending on which property has changed.
1965 : */
1966 72126 : void wpas_dbus_signal_prop_changed(struct wpa_supplicant *wpa_s,
1967 : enum wpas_dbus_prop property)
1968 : {
1969 : char *prop;
1970 : dbus_bool_t flush;
1971 :
1972 72126 : if (wpa_s->dbus_new_path == NULL)
1973 22967 : return; /* Skip signal since D-Bus setup is not yet ready */
1974 :
1975 49159 : flush = FALSE;
1976 49159 : switch (property) {
1977 : case WPAS_DBUS_PROP_AP_SCAN:
1978 12 : prop = "ApScan";
1979 12 : break;
1980 : case WPAS_DBUS_PROP_SCANNING:
1981 5292 : prop = "Scanning";
1982 5292 : break;
1983 : case WPAS_DBUS_PROP_STATE:
1984 23783 : prop = "State";
1985 23783 : break;
1986 : case WPAS_DBUS_PROP_CURRENT_BSS:
1987 7055 : prop = "CurrentBSS";
1988 7055 : break;
1989 : case WPAS_DBUS_PROP_CURRENT_NETWORK:
1990 1008 : prop = "CurrentNetwork";
1991 1008 : break;
1992 : case WPAS_DBUS_PROP_BSSS:
1993 3590 : prop = "BSSs";
1994 3590 : break;
1995 : case WPAS_DBUS_PROP_CURRENT_AUTH_MODE:
1996 5124 : prop = "CurrentAuthMode";
1997 5124 : break;
1998 : case WPAS_DBUS_PROP_DISCONNECT_REASON:
1999 3257 : prop = "DisconnectReason";
2000 3257 : flush = TRUE;
2001 3257 : break;
2002 : case WPAS_DBUS_PROP_ASSOC_STATUS_CODE:
2003 38 : prop = "AssocStatusCode";
2004 38 : flush = TRUE;
2005 38 : break;
2006 : default:
2007 0 : wpa_printf(MSG_ERROR, "dbus: %s: Unknown Property value %d",
2008 : __func__, property);
2009 0 : return;
2010 : }
2011 :
2012 49159 : wpa_dbus_mark_property_changed(wpa_s->global->dbus,
2013 49159 : wpa_s->dbus_new_path,
2014 : WPAS_DBUS_NEW_IFACE_INTERFACE, prop);
2015 49159 : if (flush) {
2016 3295 : wpa_dbus_flush_object_changed_properties(
2017 3295 : wpa_s->global->dbus->con, wpa_s->dbus_new_path);
2018 : }
2019 : }
2020 :
2021 :
2022 : /**
2023 : * wpas_dbus_bss_signal_prop_changed - Signals change of BSS property
2024 : * @wpa_s: %wpa_supplicant network interface data
2025 : * @property: indicates which property has changed
2026 : * @id: unique BSS identifier
2027 : *
2028 : * Sends PropertyChanged signals with path, interface, and arguments depending
2029 : * on which property has changed.
2030 : */
2031 2225 : void wpas_dbus_bss_signal_prop_changed(struct wpa_supplicant *wpa_s,
2032 : enum wpas_dbus_bss_prop property,
2033 : unsigned int id)
2034 : {
2035 : char path[WPAS_DBUS_OBJECT_PATH_MAX];
2036 : char *prop;
2037 :
2038 2225 : if (!wpa_s->dbus_new_path)
2039 1820 : return;
2040 :
2041 1315 : switch (property) {
2042 : case WPAS_DBUS_BSS_PROP_SIGNAL:
2043 0 : prop = "Signal";
2044 0 : break;
2045 : case WPAS_DBUS_BSS_PROP_FREQ:
2046 2 : prop = "Frequency";
2047 2 : break;
2048 : case WPAS_DBUS_BSS_PROP_MODE:
2049 0 : prop = "Mode";
2050 0 : break;
2051 : case WPAS_DBUS_BSS_PROP_PRIVACY:
2052 9 : prop = "Privacy";
2053 9 : break;
2054 : case WPAS_DBUS_BSS_PROP_RATES:
2055 0 : prop = "Rates";
2056 0 : break;
2057 : case WPAS_DBUS_BSS_PROP_WPA:
2058 7 : prop = "WPA";
2059 7 : break;
2060 : case WPAS_DBUS_BSS_PROP_RSN:
2061 8 : prop = "RSN";
2062 8 : break;
2063 : case WPAS_DBUS_BSS_PROP_WPS:
2064 37 : prop = "WPS";
2065 37 : break;
2066 : case WPAS_DBUS_BSS_PROP_IES:
2067 50 : prop = "IEs";
2068 50 : break;
2069 : case WPAS_DBUS_BSS_PROP_AGE:
2070 1202 : prop = "Age";
2071 1202 : break;
2072 : default:
2073 0 : wpa_printf(MSG_ERROR, "dbus: %s: Unknown Property value %d",
2074 : __func__, property);
2075 0 : return;
2076 : }
2077 :
2078 1315 : os_snprintf(path, WPAS_DBUS_OBJECT_PATH_MAX,
2079 : "%s/" WPAS_DBUS_NEW_BSSIDS_PART "/%u",
2080 : wpa_s->dbus_new_path, id);
2081 :
2082 1315 : wpa_dbus_mark_property_changed(wpa_s->global->dbus, path,
2083 : WPAS_DBUS_NEW_IFACE_BSS, prop);
2084 : }
2085 :
2086 :
2087 : /**
2088 : * wpas_dbus_signal_debug_level_changed - Signals change of debug param
2089 : * @global: wpa_global structure
2090 : *
2091 : * Sends PropertyChanged signals informing that debug level has changed.
2092 : */
2093 2 : void wpas_dbus_signal_debug_level_changed(struct wpa_global *global)
2094 : {
2095 2 : wpa_dbus_mark_property_changed(global->dbus, WPAS_DBUS_NEW_PATH,
2096 : WPAS_DBUS_NEW_INTERFACE,
2097 : "DebugLevel");
2098 2 : }
2099 :
2100 :
2101 : /**
2102 : * wpas_dbus_signal_debug_timestamp_changed - Signals change of debug param
2103 : * @global: wpa_global structure
2104 : *
2105 : * Sends PropertyChanged signals informing that debug timestamp has changed.
2106 : */
2107 2 : void wpas_dbus_signal_debug_timestamp_changed(struct wpa_global *global)
2108 : {
2109 2 : wpa_dbus_mark_property_changed(global->dbus, WPAS_DBUS_NEW_PATH,
2110 : WPAS_DBUS_NEW_INTERFACE,
2111 : "DebugTimestamp");
2112 2 : }
2113 :
2114 :
2115 : /**
2116 : * wpas_dbus_signal_debug_show_keys_changed - Signals change of debug param
2117 : * @global: wpa_global structure
2118 : *
2119 : * Sends PropertyChanged signals informing that debug show_keys has changed.
2120 : */
2121 2 : void wpas_dbus_signal_debug_show_keys_changed(struct wpa_global *global)
2122 : {
2123 2 : wpa_dbus_mark_property_changed(global->dbus, WPAS_DBUS_NEW_PATH,
2124 : WPAS_DBUS_NEW_INTERFACE,
2125 : "DebugShowKeys");
2126 2 : }
2127 :
2128 :
2129 6741 : static void wpas_dbus_register(struct wpa_dbus_object_desc *obj_desc,
2130 : void *priv,
2131 : WPADBusArgumentFreeFunction priv_free,
2132 : const struct wpa_dbus_method_desc *methods,
2133 : const struct wpa_dbus_property_desc *properties,
2134 : const struct wpa_dbus_signal_desc *signals)
2135 : {
2136 : int n;
2137 :
2138 6741 : obj_desc->user_data = priv;
2139 6741 : obj_desc->user_data_free_func = priv_free;
2140 6741 : obj_desc->methods = methods;
2141 6741 : obj_desc->properties = properties;
2142 6741 : obj_desc->signals = signals;
2143 :
2144 66403 : for (n = 0; properties && properties->dbus_property; properties++)
2145 59662 : n++;
2146 :
2147 6741 : obj_desc->prop_changed_flags = os_zalloc(n);
2148 6741 : if (!obj_desc->prop_changed_flags)
2149 1 : wpa_printf(MSG_DEBUG, "dbus: %s: can't register handlers",
2150 : __func__);
2151 6741 : }
2152 :
2153 :
2154 : static const struct wpa_dbus_method_desc wpas_dbus_global_methods[] = {
2155 : { "CreateInterface", WPAS_DBUS_NEW_INTERFACE,
2156 : (WPADBusMethodHandler) wpas_dbus_handler_create_interface,
2157 : {
2158 : { "args", "a{sv}", ARG_IN },
2159 : { "path", "o", ARG_OUT },
2160 : END_ARGS
2161 : }
2162 : },
2163 : { "RemoveInterface", WPAS_DBUS_NEW_INTERFACE,
2164 : (WPADBusMethodHandler) wpas_dbus_handler_remove_interface,
2165 : {
2166 : { "path", "o", ARG_IN },
2167 : END_ARGS
2168 : }
2169 : },
2170 : { "GetInterface", WPAS_DBUS_NEW_INTERFACE,
2171 : (WPADBusMethodHandler) wpas_dbus_handler_get_interface,
2172 : {
2173 : { "ifname", "s", ARG_IN },
2174 : { "path", "o", ARG_OUT },
2175 : END_ARGS
2176 : }
2177 : },
2178 : { "ExpectDisconnect", WPAS_DBUS_NEW_INTERFACE,
2179 : (WPADBusMethodHandler) wpas_dbus_handler_expect_disconnect,
2180 : {
2181 : END_ARGS
2182 : }
2183 : },
2184 : { NULL, NULL, NULL, { END_ARGS } }
2185 : };
2186 :
2187 : static const struct wpa_dbus_property_desc wpas_dbus_global_properties[] = {
2188 : { "DebugLevel", WPAS_DBUS_NEW_INTERFACE, "s",
2189 : wpas_dbus_getter_debug_level,
2190 : wpas_dbus_setter_debug_level,
2191 : NULL
2192 : },
2193 : { "DebugTimestamp", WPAS_DBUS_NEW_INTERFACE, "b",
2194 : wpas_dbus_getter_debug_timestamp,
2195 : wpas_dbus_setter_debug_timestamp,
2196 : NULL
2197 : },
2198 : { "DebugShowKeys", WPAS_DBUS_NEW_INTERFACE, "b",
2199 : wpas_dbus_getter_debug_show_keys,
2200 : wpas_dbus_setter_debug_show_keys,
2201 : NULL
2202 : },
2203 : { "Interfaces", WPAS_DBUS_NEW_INTERFACE, "ao",
2204 : wpas_dbus_getter_interfaces,
2205 : NULL,
2206 : NULL
2207 : },
2208 : { "EapMethods", WPAS_DBUS_NEW_INTERFACE, "as",
2209 : wpas_dbus_getter_eap_methods,
2210 : NULL,
2211 : NULL
2212 : },
2213 : { "Capabilities", WPAS_DBUS_NEW_INTERFACE, "as",
2214 : wpas_dbus_getter_global_capabilities,
2215 : NULL,
2216 : NULL
2217 : },
2218 : #ifdef CONFIG_WIFI_DISPLAY
2219 : { "WFDIEs", WPAS_DBUS_NEW_INTERFACE, "ay",
2220 : wpas_dbus_getter_global_wfd_ies,
2221 : wpas_dbus_setter_global_wfd_ies,
2222 : NULL
2223 : },
2224 : #endif /* CONFIG_WIFI_DISPLAY */
2225 : { NULL, NULL, NULL, NULL, NULL, NULL }
2226 : };
2227 :
2228 : static const struct wpa_dbus_signal_desc wpas_dbus_global_signals[] = {
2229 : { "InterfaceAdded", WPAS_DBUS_NEW_INTERFACE,
2230 : {
2231 : { "path", "o", ARG_OUT },
2232 : { "properties", "a{sv}", ARG_OUT },
2233 : END_ARGS
2234 : }
2235 : },
2236 : { "InterfaceRemoved", WPAS_DBUS_NEW_INTERFACE,
2237 : {
2238 : { "path", "o", ARG_OUT },
2239 : END_ARGS
2240 : }
2241 : },
2242 : /* Deprecated: use org.freedesktop.DBus.Properties.PropertiesChanged */
2243 : { "PropertiesChanged", WPAS_DBUS_NEW_INTERFACE,
2244 : {
2245 : { "properties", "a{sv}", ARG_OUT },
2246 : END_ARGS
2247 : }
2248 : },
2249 : { NULL, NULL, { END_ARGS } }
2250 : };
2251 :
2252 :
2253 636 : static char * uscore_to_dbus(const char *uscore)
2254 : {
2255 636 : const char *p = uscore;
2256 : char *str, *s;
2257 636 : dbus_bool_t last_was_uscore = TRUE;
2258 :
2259 636 : s = str = os_zalloc(os_strlen(uscore) + 1);
2260 636 : if (!str)
2261 0 : return NULL;
2262 10374 : while (p && *p) {
2263 9102 : if (*p == '_') {
2264 1014 : last_was_uscore = TRUE;
2265 : } else {
2266 8088 : *s++ = last_was_uscore ? toupper(*p) : *p;
2267 8088 : last_was_uscore = FALSE;
2268 : }
2269 9102 : p++;
2270 : }
2271 :
2272 636 : return str;
2273 : }
2274 :
2275 :
2276 : static int wpa_dbus_ctrl_iface_props_init(struct wpas_dbus_priv *priv);
2277 :
2278 :
2279 6 : static void wpa_dbus_ctrl_iface_props_deinit(struct wpas_dbus_priv *priv)
2280 : {
2281 6 : int idx = priv->globals_start;
2282 :
2283 : /* Free all allocated property values */
2284 648 : while (priv->all_interface_properties[idx].dbus_property)
2285 636 : os_free((char *)
2286 636 : priv->all_interface_properties[idx++].dbus_property);
2287 6 : os_free((char *) priv->all_interface_properties);
2288 6 : }
2289 :
2290 :
2291 : /**
2292 : * wpas_dbus_ctrl_iface_init - Initialize dbus control interface
2293 : * @global: Pointer to global data from wpa_supplicant_init()
2294 : * Returns: 0 on success or -1 on failure
2295 : *
2296 : * Initialize the dbus control interface for wpa_supplicant and start
2297 : * receiving commands from external programs over the bus.
2298 : */
2299 6 : int wpas_dbus_ctrl_iface_init(struct wpas_dbus_priv *priv)
2300 : {
2301 : struct wpa_dbus_object_desc *obj_desc;
2302 : int ret;
2303 :
2304 6 : ret = wpa_dbus_ctrl_iface_props_init(priv);
2305 6 : if (ret < 0) {
2306 0 : wpa_printf(MSG_ERROR,
2307 : "dbus: Not enough memory to init interface properties");
2308 0 : return -1;
2309 : }
2310 :
2311 6 : obj_desc = os_zalloc(sizeof(struct wpa_dbus_object_desc));
2312 6 : if (!obj_desc) {
2313 0 : wpa_printf(MSG_ERROR,
2314 : "Not enough memory to create object description");
2315 0 : goto error;
2316 : }
2317 :
2318 6 : wpas_dbus_register(obj_desc, priv->global, NULL,
2319 : wpas_dbus_global_methods,
2320 : wpas_dbus_global_properties,
2321 : wpas_dbus_global_signals);
2322 :
2323 6 : wpa_printf(MSG_DEBUG, "dbus: Register D-Bus object '%s'",
2324 : WPAS_DBUS_NEW_PATH);
2325 6 : ret = wpa_dbus_ctrl_iface_init(priv, WPAS_DBUS_NEW_PATH,
2326 : WPAS_DBUS_NEW_SERVICE,
2327 : obj_desc);
2328 6 : if (ret < 0) {
2329 0 : free_dbus_object_desc(obj_desc);
2330 0 : goto error;
2331 : }
2332 :
2333 6 : priv->dbus_new_initialized = 1;
2334 6 : return 0;
2335 :
2336 : error:
2337 0 : wpa_dbus_ctrl_iface_props_deinit(priv);
2338 0 : return -1;
2339 : }
2340 :
2341 :
2342 : /**
2343 : * wpas_dbus_ctrl_iface_deinit - Deinitialize dbus ctrl interface for
2344 : * wpa_supplicant
2345 : * @priv: Pointer to dbus private data from wpas_dbus_init()
2346 : *
2347 : * Deinitialize the dbus control interface that was initialized with
2348 : * wpas_dbus_ctrl_iface_init().
2349 : */
2350 6 : void wpas_dbus_ctrl_iface_deinit(struct wpas_dbus_priv *priv)
2351 : {
2352 6 : if (!priv->dbus_new_initialized)
2353 6 : return;
2354 6 : wpa_printf(MSG_DEBUG, "dbus: Unregister D-Bus object '%s'",
2355 : WPAS_DBUS_NEW_PATH);
2356 6 : dbus_connection_unregister_object_path(priv->con, WPAS_DBUS_NEW_PATH);
2357 6 : wpa_dbus_ctrl_iface_props_deinit(priv);
2358 : }
2359 :
2360 :
2361 6209 : static void wpa_dbus_free(void *ptr)
2362 : {
2363 6209 : os_free(ptr);
2364 6209 : }
2365 :
2366 :
2367 : static const struct wpa_dbus_property_desc wpas_dbus_network_properties[] = {
2368 : { "Properties", WPAS_DBUS_NEW_IFACE_NETWORK, "a{sv}",
2369 : wpas_dbus_getter_network_properties,
2370 : wpas_dbus_setter_network_properties,
2371 : NULL
2372 : },
2373 : { "Enabled", WPAS_DBUS_NEW_IFACE_NETWORK, "b",
2374 : wpas_dbus_getter_enabled,
2375 : wpas_dbus_setter_enabled,
2376 : NULL
2377 : },
2378 : { NULL, NULL, NULL, NULL, NULL, NULL }
2379 : };
2380 :
2381 :
2382 : static const struct wpa_dbus_signal_desc wpas_dbus_network_signals[] = {
2383 : /* Deprecated: use org.freedesktop.DBus.Properties.PropertiesChanged */
2384 : { "PropertiesChanged", WPAS_DBUS_NEW_IFACE_NETWORK,
2385 : {
2386 : { "properties", "a{sv}", ARG_OUT },
2387 : END_ARGS
2388 : }
2389 : },
2390 : { NULL, NULL, { END_ARGS } }
2391 : };
2392 :
2393 :
2394 : /**
2395 : * wpas_dbus_register_network - Register a configured network with dbus
2396 : * @wpa_s: wpa_supplicant interface structure
2397 : * @ssid: network configuration data
2398 : * Returns: 0 on success, -1 on failure
2399 : *
2400 : * Registers network representing object with dbus
2401 : */
2402 5048 : int wpas_dbus_register_network(struct wpa_supplicant *wpa_s,
2403 : struct wpa_ssid *ssid)
2404 : {
2405 : struct wpas_dbus_priv *ctrl_iface;
2406 : struct wpa_dbus_object_desc *obj_desc;
2407 : struct network_handler_args *arg;
2408 : char net_obj_path[WPAS_DBUS_OBJECT_PATH_MAX];
2409 :
2410 : #ifdef CONFIG_P2P
2411 : /*
2412 : * If it is a persistent group register it as such.
2413 : * This is to handle cases where an interface is being initialized
2414 : * with a list of networks read from config.
2415 : */
2416 5048 : if (network_is_persistent_group(ssid))
2417 0 : return wpas_dbus_register_persistent_group(wpa_s, ssid);
2418 : #endif /* CONFIG_P2P */
2419 :
2420 : /* Do nothing if the control interface is not turned on */
2421 5048 : if (wpa_s == NULL || wpa_s->global == NULL || !wpa_s->dbus_new_path)
2422 996 : return 0;
2423 4052 : ctrl_iface = wpa_s->global->dbus;
2424 4052 : if (ctrl_iface == NULL)
2425 0 : return 0;
2426 :
2427 4052 : os_snprintf(net_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
2428 : "%s/" WPAS_DBUS_NEW_NETWORKS_PART "/%u",
2429 : wpa_s->dbus_new_path, ssid->id);
2430 :
2431 4052 : wpa_printf(MSG_DEBUG, "dbus: Register network object '%s'",
2432 : net_obj_path);
2433 4052 : obj_desc = os_zalloc(sizeof(struct wpa_dbus_object_desc));
2434 4052 : if (!obj_desc) {
2435 1 : wpa_printf(MSG_ERROR,
2436 : "Not enough memory to create object description");
2437 1 : goto err;
2438 : }
2439 :
2440 : /* allocate memory for handlers arguments */
2441 4051 : arg = os_zalloc(sizeof(struct network_handler_args));
2442 4051 : if (!arg) {
2443 1 : wpa_printf(MSG_ERROR,
2444 : "Not enough memory to create arguments for method");
2445 1 : goto err;
2446 : }
2447 :
2448 4050 : arg->wpa_s = wpa_s;
2449 4050 : arg->ssid = ssid;
2450 :
2451 4050 : wpas_dbus_register(obj_desc, arg, wpa_dbus_free, NULL,
2452 : wpas_dbus_network_properties,
2453 : wpas_dbus_network_signals);
2454 :
2455 4050 : if (wpa_dbus_register_object_per_iface(ctrl_iface, net_obj_path,
2456 4050 : wpa_s->ifname, obj_desc))
2457 0 : goto err;
2458 :
2459 4050 : wpas_dbus_signal_network_added(wpa_s, ssid->id);
2460 :
2461 4050 : return 0;
2462 :
2463 : err:
2464 2 : free_dbus_object_desc(obj_desc);
2465 2 : return -1;
2466 : }
2467 :
2468 :
2469 : /**
2470 : * wpas_dbus_unregister_network - Unregister a configured network from dbus
2471 : * @wpa_s: wpa_supplicant interface structure
2472 : * @nid: network id
2473 : * Returns: 0 on success, -1 on failure
2474 : *
2475 : * Unregisters network representing object from dbus
2476 : */
2477 5048 : int wpas_dbus_unregister_network(struct wpa_supplicant *wpa_s, int nid)
2478 : {
2479 : struct wpas_dbus_priv *ctrl_iface;
2480 : char net_obj_path[WPAS_DBUS_OBJECT_PATH_MAX];
2481 : int ret;
2482 : #ifdef CONFIG_P2P
2483 : struct wpa_ssid *ssid;
2484 :
2485 5048 : ssid = wpa_config_get_network(wpa_s->conf, nid);
2486 :
2487 : /* If it is a persistent group unregister it as such */
2488 5048 : if (ssid && network_is_persistent_group(ssid))
2489 2 : return wpas_dbus_unregister_persistent_group(wpa_s, nid);
2490 : #endif /* CONFIG_P2P */
2491 :
2492 : /* Do nothing if the control interface is not turned on */
2493 5046 : if (wpa_s->global == NULL || wpa_s->dbus_new_path == NULL)
2494 994 : return 0;
2495 4052 : ctrl_iface = wpa_s->global->dbus;
2496 4052 : if (ctrl_iface == NULL)
2497 0 : return 0;
2498 :
2499 4052 : os_snprintf(net_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
2500 : "%s/" WPAS_DBUS_NEW_NETWORKS_PART "/%u",
2501 : wpa_s->dbus_new_path, nid);
2502 :
2503 4052 : wpa_printf(MSG_DEBUG, "dbus: Unregister network object '%s'",
2504 : net_obj_path);
2505 4052 : ret = wpa_dbus_unregister_object_per_iface(ctrl_iface, net_obj_path);
2506 :
2507 4052 : if (!ret)
2508 4052 : wpas_dbus_signal_network_removed(wpa_s, nid);
2509 :
2510 4052 : return ret;
2511 : }
2512 :
2513 :
2514 : static const struct wpa_dbus_property_desc wpas_dbus_bss_properties[] = {
2515 : { "SSID", WPAS_DBUS_NEW_IFACE_BSS, "ay",
2516 : wpas_dbus_getter_bss_ssid,
2517 : NULL,
2518 : NULL
2519 : },
2520 : { "BSSID", WPAS_DBUS_NEW_IFACE_BSS, "ay",
2521 : wpas_dbus_getter_bss_bssid,
2522 : NULL,
2523 : NULL
2524 : },
2525 : { "Privacy", WPAS_DBUS_NEW_IFACE_BSS, "b",
2526 : wpas_dbus_getter_bss_privacy,
2527 : NULL,
2528 : NULL
2529 : },
2530 : { "Mode", WPAS_DBUS_NEW_IFACE_BSS, "s",
2531 : wpas_dbus_getter_bss_mode,
2532 : NULL,
2533 : NULL
2534 : },
2535 : { "Signal", WPAS_DBUS_NEW_IFACE_BSS, "n",
2536 : wpas_dbus_getter_bss_signal,
2537 : NULL,
2538 : NULL
2539 : },
2540 : { "Frequency", WPAS_DBUS_NEW_IFACE_BSS, "q",
2541 : wpas_dbus_getter_bss_frequency,
2542 : NULL,
2543 : NULL
2544 : },
2545 : { "Rates", WPAS_DBUS_NEW_IFACE_BSS, "au",
2546 : wpas_dbus_getter_bss_rates,
2547 : NULL,
2548 : NULL
2549 : },
2550 : { "WPA", WPAS_DBUS_NEW_IFACE_BSS, "a{sv}",
2551 : wpas_dbus_getter_bss_wpa,
2552 : NULL,
2553 : NULL
2554 : },
2555 : { "RSN", WPAS_DBUS_NEW_IFACE_BSS, "a{sv}",
2556 : wpas_dbus_getter_bss_rsn,
2557 : NULL,
2558 : NULL
2559 : },
2560 : { "WPS", WPAS_DBUS_NEW_IFACE_BSS, "a{sv}",
2561 : wpas_dbus_getter_bss_wps,
2562 : NULL,
2563 : NULL
2564 : },
2565 : { "IEs", WPAS_DBUS_NEW_IFACE_BSS, "ay",
2566 : wpas_dbus_getter_bss_ies,
2567 : NULL,
2568 : NULL
2569 : },
2570 : { "Age", WPAS_DBUS_NEW_IFACE_BSS, "u",
2571 : wpas_dbus_getter_bss_age,
2572 : NULL,
2573 : NULL
2574 : },
2575 : { NULL, NULL, NULL, NULL, NULL, NULL }
2576 : };
2577 :
2578 :
2579 : static const struct wpa_dbus_signal_desc wpas_dbus_bss_signals[] = {
2580 : /* Deprecated: use org.freedesktop.DBus.Properties.PropertiesChanged */
2581 : { "PropertiesChanged", WPAS_DBUS_NEW_IFACE_BSS,
2582 : {
2583 : { "properties", "a{sv}", ARG_OUT },
2584 : END_ARGS
2585 : }
2586 : },
2587 : { NULL, NULL, { END_ARGS } }
2588 : };
2589 :
2590 :
2591 : /**
2592 : * wpas_dbus_unregister_bss - Unregister a scanned BSS from dbus
2593 : * @wpa_s: wpa_supplicant interface structure
2594 : * @bssid: scanned network bssid
2595 : * @id: unique BSS identifier
2596 : * Returns: 0 on success, -1 on failure
2597 : *
2598 : * Unregisters BSS representing object from dbus
2599 : */
2600 3743 : int wpas_dbus_unregister_bss(struct wpa_supplicant *wpa_s,
2601 : u8 bssid[ETH_ALEN], unsigned int id)
2602 : {
2603 : struct wpas_dbus_priv *ctrl_iface;
2604 : char bss_obj_path[WPAS_DBUS_OBJECT_PATH_MAX];
2605 :
2606 : /* Do nothing if the control interface is not turned on */
2607 3743 : if (wpa_s == NULL || wpa_s->global == NULL || !wpa_s->dbus_new_path)
2608 1948 : return 0;
2609 1795 : ctrl_iface = wpa_s->global->dbus;
2610 1795 : if (ctrl_iface == NULL)
2611 0 : return 0;
2612 :
2613 1795 : os_snprintf(bss_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
2614 : "%s/" WPAS_DBUS_NEW_BSSIDS_PART "/%u",
2615 : wpa_s->dbus_new_path, id);
2616 :
2617 1795 : wpa_printf(MSG_DEBUG, "dbus: Unregister BSS object '%s'",
2618 : bss_obj_path);
2619 1795 : if (wpa_dbus_unregister_object_per_iface(ctrl_iface, bss_obj_path)) {
2620 0 : wpa_printf(MSG_ERROR, "dbus: Cannot unregister BSS object %s",
2621 : bss_obj_path);
2622 0 : return -1;
2623 : }
2624 :
2625 1795 : wpas_dbus_signal_bss_removed(wpa_s, bss_obj_path);
2626 1795 : wpas_dbus_signal_prop_changed(wpa_s, WPAS_DBUS_PROP_BSSS);
2627 :
2628 1795 : return 0;
2629 : }
2630 :
2631 :
2632 : /**
2633 : * wpas_dbus_register_bss - Register a scanned BSS with dbus
2634 : * @wpa_s: wpa_supplicant interface structure
2635 : * @bssid: scanned network bssid
2636 : * @id: unique BSS identifier
2637 : * Returns: 0 on success, -1 on failure
2638 : *
2639 : * Registers BSS representing object with dbus
2640 : */
2641 3743 : int wpas_dbus_register_bss(struct wpa_supplicant *wpa_s,
2642 : u8 bssid[ETH_ALEN], unsigned int id)
2643 : {
2644 : struct wpas_dbus_priv *ctrl_iface;
2645 : struct wpa_dbus_object_desc *obj_desc;
2646 : char bss_obj_path[WPAS_DBUS_OBJECT_PATH_MAX];
2647 : struct bss_handler_args *arg;
2648 :
2649 : /* Do nothing if the control interface is not turned on */
2650 3743 : if (wpa_s == NULL || wpa_s->global == NULL || !wpa_s->dbus_new_path)
2651 1948 : return 0;
2652 1795 : ctrl_iface = wpa_s->global->dbus;
2653 1795 : if (ctrl_iface == NULL)
2654 0 : return 0;
2655 :
2656 1795 : os_snprintf(bss_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
2657 : "%s/" WPAS_DBUS_NEW_BSSIDS_PART "/%u",
2658 : wpa_s->dbus_new_path, id);
2659 :
2660 1795 : obj_desc = os_zalloc(sizeof(struct wpa_dbus_object_desc));
2661 1795 : if (!obj_desc) {
2662 0 : wpa_printf(MSG_ERROR,
2663 : "Not enough memory to create object description");
2664 0 : goto err;
2665 : }
2666 :
2667 1795 : arg = os_zalloc(sizeof(struct bss_handler_args));
2668 1795 : if (!arg) {
2669 0 : wpa_printf(MSG_ERROR,
2670 : "Not enough memory to create arguments for handler");
2671 0 : goto err;
2672 : }
2673 1795 : arg->wpa_s = wpa_s;
2674 1795 : arg->id = id;
2675 :
2676 1795 : wpas_dbus_register(obj_desc, arg, wpa_dbus_free, NULL,
2677 : wpas_dbus_bss_properties,
2678 : wpas_dbus_bss_signals);
2679 :
2680 1795 : wpa_printf(MSG_DEBUG, "dbus: Register BSS object '%s'",
2681 : bss_obj_path);
2682 1795 : if (wpa_dbus_register_object_per_iface(ctrl_iface, bss_obj_path,
2683 1795 : wpa_s->ifname, obj_desc)) {
2684 0 : wpa_printf(MSG_ERROR,
2685 : "Cannot register BSSID dbus object %s.",
2686 : bss_obj_path);
2687 0 : goto err;
2688 : }
2689 :
2690 1795 : wpas_dbus_signal_bss_added(wpa_s, bss_obj_path);
2691 1795 : wpas_dbus_signal_prop_changed(wpa_s, WPAS_DBUS_PROP_BSSS);
2692 :
2693 1795 : return 0;
2694 :
2695 : err:
2696 0 : free_dbus_object_desc(obj_desc);
2697 0 : return -1;
2698 : }
2699 :
2700 :
2701 : static const struct wpa_dbus_method_desc wpas_dbus_interface_methods[] = {
2702 : { "Scan", WPAS_DBUS_NEW_IFACE_INTERFACE,
2703 : (WPADBusMethodHandler) wpas_dbus_handler_scan,
2704 : {
2705 : { "args", "a{sv}", ARG_IN },
2706 : END_ARGS
2707 : }
2708 : },
2709 : { "SignalPoll", WPAS_DBUS_NEW_IFACE_INTERFACE,
2710 : (WPADBusMethodHandler) wpas_dbus_handler_signal_poll,
2711 : {
2712 : { "args", "a{sv}", ARG_OUT },
2713 : END_ARGS
2714 : }
2715 : },
2716 : { "Disconnect", WPAS_DBUS_NEW_IFACE_INTERFACE,
2717 : (WPADBusMethodHandler) wpas_dbus_handler_disconnect,
2718 : {
2719 : END_ARGS
2720 : }
2721 : },
2722 : { "AddNetwork", WPAS_DBUS_NEW_IFACE_INTERFACE,
2723 : (WPADBusMethodHandler) wpas_dbus_handler_add_network,
2724 : {
2725 : { "args", "a{sv}", ARG_IN },
2726 : { "path", "o", ARG_OUT },
2727 : END_ARGS
2728 : }
2729 : },
2730 : { "Reassociate", WPAS_DBUS_NEW_IFACE_INTERFACE,
2731 : (WPADBusMethodHandler) wpas_dbus_handler_reassociate,
2732 : {
2733 : END_ARGS
2734 : }
2735 : },
2736 : { "Reattach", WPAS_DBUS_NEW_IFACE_INTERFACE,
2737 : (WPADBusMethodHandler) wpas_dbus_handler_reattach,
2738 : {
2739 : END_ARGS
2740 : }
2741 : },
2742 : { "Reconnect", WPAS_DBUS_NEW_IFACE_INTERFACE,
2743 : (WPADBusMethodHandler) wpas_dbus_handler_reconnect,
2744 : {
2745 : END_ARGS
2746 : }
2747 : },
2748 : { "RemoveNetwork", WPAS_DBUS_NEW_IFACE_INTERFACE,
2749 : (WPADBusMethodHandler) wpas_dbus_handler_remove_network,
2750 : {
2751 : { "path", "o", ARG_IN },
2752 : END_ARGS
2753 : }
2754 : },
2755 : { "RemoveAllNetworks", WPAS_DBUS_NEW_IFACE_INTERFACE,
2756 : (WPADBusMethodHandler) wpas_dbus_handler_remove_all_networks,
2757 : {
2758 : END_ARGS
2759 : }
2760 : },
2761 : { "SelectNetwork", WPAS_DBUS_NEW_IFACE_INTERFACE,
2762 : (WPADBusMethodHandler) wpas_dbus_handler_select_network,
2763 : {
2764 : { "path", "o", ARG_IN },
2765 : END_ARGS
2766 : }
2767 : },
2768 : { "NetworkReply", WPAS_DBUS_NEW_IFACE_INTERFACE,
2769 : (WPADBusMethodHandler) wpas_dbus_handler_network_reply,
2770 : {
2771 : { "path", "o", ARG_IN },
2772 : { "field", "s", ARG_IN },
2773 : { "value", "s", ARG_IN },
2774 : END_ARGS
2775 : }
2776 : },
2777 : #ifndef CONFIG_NO_CONFIG_BLOBS
2778 : { "AddBlob", WPAS_DBUS_NEW_IFACE_INTERFACE,
2779 : (WPADBusMethodHandler) wpas_dbus_handler_add_blob,
2780 : {
2781 : { "name", "s", ARG_IN },
2782 : { "data", "ay", ARG_IN },
2783 : END_ARGS
2784 : }
2785 : },
2786 : { "GetBlob", WPAS_DBUS_NEW_IFACE_INTERFACE,
2787 : (WPADBusMethodHandler) wpas_dbus_handler_get_blob,
2788 : {
2789 : { "name", "s", ARG_IN },
2790 : { "data", "ay", ARG_OUT },
2791 : END_ARGS
2792 : }
2793 : },
2794 : { "RemoveBlob", WPAS_DBUS_NEW_IFACE_INTERFACE,
2795 : (WPADBusMethodHandler) wpas_dbus_handler_remove_blob,
2796 : {
2797 : { "name", "s", ARG_IN },
2798 : END_ARGS
2799 : }
2800 : },
2801 : #endif /* CONFIG_NO_CONFIG_BLOBS */
2802 : { "SetPKCS11EngineAndModulePath", WPAS_DBUS_NEW_IFACE_INTERFACE,
2803 : (WPADBusMethodHandler)
2804 : wpas_dbus_handler_set_pkcs11_engine_and_module_path,
2805 : {
2806 : { "pkcs11_engine_path", "s", ARG_IN },
2807 : { "pkcs11_module_path", "s", ARG_IN },
2808 : END_ARGS
2809 : }
2810 : },
2811 : #ifdef CONFIG_WPS
2812 : { "Start", WPAS_DBUS_NEW_IFACE_WPS,
2813 : (WPADBusMethodHandler) wpas_dbus_handler_wps_start,
2814 : {
2815 : { "args", "a{sv}", ARG_IN },
2816 : { "output", "a{sv}", ARG_OUT },
2817 : END_ARGS
2818 : }
2819 : },
2820 : { "Cancel", WPAS_DBUS_NEW_IFACE_WPS,
2821 : (WPADBusMethodHandler) wpas_dbus_handler_wps_cancel,
2822 : {
2823 : END_ARGS
2824 : }
2825 : },
2826 : #endif /* CONFIG_WPS */
2827 : #ifdef CONFIG_P2P
2828 : { "Find", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
2829 : (WPADBusMethodHandler) wpas_dbus_handler_p2p_find,
2830 : {
2831 : { "args", "a{sv}", ARG_IN },
2832 : END_ARGS
2833 : }
2834 : },
2835 : { "StopFind", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
2836 : (WPADBusMethodHandler) wpas_dbus_handler_p2p_stop_find,
2837 : {
2838 : END_ARGS
2839 : }
2840 : },
2841 : { "Listen", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
2842 : (WPADBusMethodHandler) wpas_dbus_handler_p2p_listen,
2843 : {
2844 : { "timeout", "i", ARG_IN },
2845 : END_ARGS
2846 : }
2847 : },
2848 : { "ExtendedListen", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
2849 : (WPADBusMethodHandler) wpas_dbus_handler_p2p_extendedlisten,
2850 : {
2851 : { "args", "a{sv}", ARG_IN },
2852 : END_ARGS
2853 : }
2854 : },
2855 : { "PresenceRequest", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
2856 : (WPADBusMethodHandler) wpas_dbus_handler_p2p_presence_request,
2857 : {
2858 : { "args", "a{sv}", ARG_IN },
2859 : END_ARGS
2860 : }
2861 : },
2862 : { "ProvisionDiscoveryRequest", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
2863 : (WPADBusMethodHandler) wpas_dbus_handler_p2p_prov_disc_req,
2864 : {
2865 : { "peer", "o", ARG_IN },
2866 : { "config_method", "s", ARG_IN },
2867 : END_ARGS
2868 : }
2869 : },
2870 : { "Connect", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
2871 : (WPADBusMethodHandler) wpas_dbus_handler_p2p_connect,
2872 : {
2873 : { "args", "a{sv}", ARG_IN },
2874 : { "generated_pin", "s", ARG_OUT },
2875 : END_ARGS
2876 : }
2877 : },
2878 : { "GroupAdd", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
2879 : (WPADBusMethodHandler) wpas_dbus_handler_p2p_group_add,
2880 : {
2881 : { "args", "a{sv}", ARG_IN },
2882 : END_ARGS
2883 : }
2884 : },
2885 : { "Cancel", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
2886 : (WPADBusMethodHandler) wpas_dbus_handler_p2p_cancel,
2887 : {
2888 : END_ARGS
2889 : }
2890 : },
2891 : { "Invite", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
2892 : (WPADBusMethodHandler) wpas_dbus_handler_p2p_invite,
2893 : {
2894 : { "args", "a{sv}", ARG_IN },
2895 : END_ARGS
2896 : }
2897 : },
2898 : { "Disconnect", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
2899 : (WPADBusMethodHandler) wpas_dbus_handler_p2p_disconnect,
2900 : {
2901 : END_ARGS
2902 : }
2903 : },
2904 : { "RejectPeer", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
2905 : (WPADBusMethodHandler) wpas_dbus_handler_p2p_rejectpeer,
2906 : {
2907 : { "peer", "o", ARG_IN },
2908 : END_ARGS
2909 : }
2910 : },
2911 : { "RemoveClient", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
2912 : (WPADBusMethodHandler) wpas_dbus_handler_p2p_remove_client,
2913 : {
2914 : { "args", "a{sv}", ARG_IN },
2915 : END_ARGS
2916 : }
2917 : },
2918 : { "Flush", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
2919 : (WPADBusMethodHandler) wpas_dbus_handler_p2p_flush,
2920 : {
2921 : END_ARGS
2922 : }
2923 : },
2924 : { "AddService", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
2925 : (WPADBusMethodHandler) wpas_dbus_handler_p2p_add_service,
2926 : {
2927 : { "args", "a{sv}", ARG_IN },
2928 : END_ARGS
2929 : }
2930 : },
2931 : { "DeleteService", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
2932 : (WPADBusMethodHandler) wpas_dbus_handler_p2p_delete_service,
2933 : {
2934 : { "args", "a{sv}", ARG_IN },
2935 : END_ARGS
2936 : }
2937 : },
2938 : { "FlushService", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
2939 : (WPADBusMethodHandler) wpas_dbus_handler_p2p_flush_service,
2940 : {
2941 : END_ARGS
2942 : }
2943 : },
2944 : { "ServiceDiscoveryRequest", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
2945 : (WPADBusMethodHandler) wpas_dbus_handler_p2p_service_sd_req,
2946 : {
2947 : { "args", "a{sv}", ARG_IN },
2948 : { "ref", "t", ARG_OUT },
2949 : END_ARGS
2950 : }
2951 : },
2952 : { "ServiceDiscoveryResponse", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
2953 : (WPADBusMethodHandler) wpas_dbus_handler_p2p_service_sd_res,
2954 : {
2955 : { "args", "a{sv}", ARG_IN },
2956 : END_ARGS
2957 : }
2958 : },
2959 : { "ServiceDiscoveryCancelRequest", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
2960 : (WPADBusMethodHandler) wpas_dbus_handler_p2p_service_sd_cancel_req,
2961 : {
2962 : { "args", "t", ARG_IN },
2963 : END_ARGS
2964 : }
2965 : },
2966 : { "ServiceUpdate", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
2967 : (WPADBusMethodHandler) wpas_dbus_handler_p2p_service_update,
2968 : {
2969 : END_ARGS
2970 : }
2971 : },
2972 : { "ServiceDiscoveryExternal", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
2973 : (WPADBusMethodHandler) wpas_dbus_handler_p2p_serv_disc_external,
2974 : {
2975 : { "arg", "i", ARG_IN },
2976 : END_ARGS
2977 : }
2978 : },
2979 : { "AddPersistentGroup", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
2980 : (WPADBusMethodHandler) wpas_dbus_handler_add_persistent_group,
2981 : {
2982 : { "args", "a{sv}", ARG_IN },
2983 : { "path", "o", ARG_OUT },
2984 : END_ARGS
2985 : }
2986 : },
2987 : { "RemovePersistentGroup", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
2988 : (WPADBusMethodHandler) wpas_dbus_handler_remove_persistent_group,
2989 : {
2990 : { "path", "o", ARG_IN },
2991 : END_ARGS
2992 : }
2993 : },
2994 : { "RemoveAllPersistentGroups", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
2995 : (WPADBusMethodHandler)
2996 : wpas_dbus_handler_remove_all_persistent_groups,
2997 : {
2998 : END_ARGS
2999 : }
3000 : },
3001 : #endif /* CONFIG_P2P */
3002 : { "FlushBSS", WPAS_DBUS_NEW_IFACE_INTERFACE,
3003 : (WPADBusMethodHandler) wpas_dbus_handler_flush_bss,
3004 : {
3005 : { "age", "u", ARG_IN },
3006 : END_ARGS
3007 : }
3008 : },
3009 : #ifdef CONFIG_AP
3010 : { "SubscribeProbeReq", WPAS_DBUS_NEW_IFACE_INTERFACE,
3011 : (WPADBusMethodHandler) wpas_dbus_handler_subscribe_preq,
3012 : {
3013 : END_ARGS
3014 : }
3015 : },
3016 : { "UnsubscribeProbeReq", WPAS_DBUS_NEW_IFACE_INTERFACE,
3017 : (WPADBusMethodHandler) wpas_dbus_handler_unsubscribe_preq,
3018 : {
3019 : END_ARGS
3020 : }
3021 : },
3022 : #endif /* CONFIG_AP */
3023 : { "EAPLogoff", WPAS_DBUS_NEW_IFACE_INTERFACE,
3024 : (WPADBusMethodHandler) wpas_dbus_handler_eap_logoff,
3025 : {
3026 : END_ARGS
3027 : }
3028 : },
3029 : { "EAPLogon", WPAS_DBUS_NEW_IFACE_INTERFACE,
3030 : (WPADBusMethodHandler) wpas_dbus_handler_eap_logon,
3031 : {
3032 : END_ARGS
3033 : }
3034 : },
3035 : #ifdef CONFIG_AUTOSCAN
3036 : { "AutoScan", WPAS_DBUS_NEW_IFACE_INTERFACE,
3037 : (WPADBusMethodHandler) wpas_dbus_handler_autoscan,
3038 : {
3039 : { "arg", "s", ARG_IN },
3040 : END_ARGS
3041 : }
3042 : },
3043 : #endif /* CONFIG_AUTOSCAN */
3044 : #ifdef CONFIG_TDLS
3045 : { "TDLSDiscover", WPAS_DBUS_NEW_IFACE_INTERFACE,
3046 : (WPADBusMethodHandler) wpas_dbus_handler_tdls_discover,
3047 : {
3048 : { "peer_address", "s", ARG_IN },
3049 : END_ARGS
3050 : }
3051 : },
3052 : { "TDLSSetup", WPAS_DBUS_NEW_IFACE_INTERFACE,
3053 : (WPADBusMethodHandler) wpas_dbus_handler_tdls_setup,
3054 : {
3055 : { "peer_address", "s", ARG_IN },
3056 : END_ARGS
3057 : }
3058 : },
3059 : { "TDLSStatus", WPAS_DBUS_NEW_IFACE_INTERFACE,
3060 : (WPADBusMethodHandler) wpas_dbus_handler_tdls_status,
3061 : {
3062 : { "peer_address", "s", ARG_IN },
3063 : { "status", "s", ARG_OUT },
3064 : END_ARGS
3065 : }
3066 : },
3067 : { "TDLSTeardown", WPAS_DBUS_NEW_IFACE_INTERFACE,
3068 : (WPADBusMethodHandler) wpas_dbus_handler_tdls_teardown,
3069 : {
3070 : { "peer_address", "s", ARG_IN },
3071 : END_ARGS
3072 : }
3073 : },
3074 : #endif /* CONFIG_TDLS */
3075 : { "VendorElemAdd", WPAS_DBUS_NEW_IFACE_INTERFACE,
3076 : (WPADBusMethodHandler) wpas_dbus_handler_vendor_elem_add,
3077 : {
3078 : { "frame_id", "i", ARG_IN },
3079 : { "ielems", "ay", ARG_IN },
3080 : END_ARGS
3081 : }
3082 : },
3083 : { "VendorElemGet", WPAS_DBUS_NEW_IFACE_INTERFACE,
3084 : (WPADBusMethodHandler) wpas_dbus_handler_vendor_elem_get,
3085 : {
3086 : { "frame_id", "i", ARG_IN },
3087 : { "ielems", "ay", ARG_OUT },
3088 : END_ARGS
3089 : }
3090 : },
3091 : { "VendorElemRem", WPAS_DBUS_NEW_IFACE_INTERFACE,
3092 : (WPADBusMethodHandler) wpas_dbus_handler_vendor_elem_remove,
3093 : {
3094 : { "frame_id", "i", ARG_IN },
3095 : { "ielems", "ay", ARG_IN },
3096 : END_ARGS
3097 : }
3098 : },
3099 : #ifndef CONFIG_NO_CONFIG_WRITE
3100 : { "SaveConfig", WPAS_DBUS_NEW_IFACE_INTERFACE,
3101 : (WPADBusMethodHandler) wpas_dbus_handler_save_config,
3102 : {
3103 : END_ARGS
3104 : }
3105 : },
3106 : #endif /* CONFIG_NO_CONFIG_WRITE */
3107 : { NULL, NULL, NULL, { END_ARGS } }
3108 : };
3109 :
3110 : static const struct wpa_dbus_property_desc wpas_dbus_interface_properties[] = {
3111 : { "Capabilities", WPAS_DBUS_NEW_IFACE_INTERFACE, "a{sv}",
3112 : wpas_dbus_getter_capabilities,
3113 : NULL,
3114 : NULL
3115 : },
3116 : { "State", WPAS_DBUS_NEW_IFACE_INTERFACE, "s",
3117 : wpas_dbus_getter_state,
3118 : NULL,
3119 : NULL
3120 : },
3121 : { "Scanning", WPAS_DBUS_NEW_IFACE_INTERFACE, "b",
3122 : wpas_dbus_getter_scanning,
3123 : NULL,
3124 : NULL
3125 : },
3126 : { "ApScan", WPAS_DBUS_NEW_IFACE_INTERFACE, "u",
3127 : wpas_dbus_getter_ap_scan,
3128 : wpas_dbus_setter_ap_scan,
3129 : NULL
3130 : },
3131 : { "BSSExpireAge", WPAS_DBUS_NEW_IFACE_INTERFACE, "u",
3132 : wpas_dbus_getter_bss_expire_age,
3133 : wpas_dbus_setter_bss_expire_age,
3134 : NULL
3135 : },
3136 : { "BSSExpireCount", WPAS_DBUS_NEW_IFACE_INTERFACE, "u",
3137 : wpas_dbus_getter_bss_expire_count,
3138 : wpas_dbus_setter_bss_expire_count,
3139 : NULL
3140 : },
3141 : { "Country", WPAS_DBUS_NEW_IFACE_INTERFACE, "s",
3142 : wpas_dbus_getter_country,
3143 : wpas_dbus_setter_country,
3144 : NULL
3145 : },
3146 : { "Ifname", WPAS_DBUS_NEW_IFACE_INTERFACE, "s",
3147 : wpas_dbus_getter_ifname,
3148 : NULL,
3149 : NULL
3150 : },
3151 : { "Driver", WPAS_DBUS_NEW_IFACE_INTERFACE, "s",
3152 : wpas_dbus_getter_driver,
3153 : NULL,
3154 : NULL
3155 : },
3156 : { "BridgeIfname", WPAS_DBUS_NEW_IFACE_INTERFACE, "s",
3157 : wpas_dbus_getter_bridge_ifname,
3158 : NULL,
3159 : NULL
3160 : },
3161 : { "ConfigFile", WPAS_DBUS_NEW_IFACE_INTERFACE, "s",
3162 : wpas_dbus_getter_config_file,
3163 : NULL,
3164 : NULL
3165 : },
3166 : { "CurrentBSS", WPAS_DBUS_NEW_IFACE_INTERFACE, "o",
3167 : wpas_dbus_getter_current_bss,
3168 : NULL,
3169 : NULL
3170 : },
3171 : { "CurrentNetwork", WPAS_DBUS_NEW_IFACE_INTERFACE, "o",
3172 : wpas_dbus_getter_current_network,
3173 : NULL,
3174 : NULL
3175 : },
3176 : { "CurrentAuthMode", WPAS_DBUS_NEW_IFACE_INTERFACE, "s",
3177 : wpas_dbus_getter_current_auth_mode,
3178 : NULL,
3179 : NULL
3180 : },
3181 : { "Blobs", WPAS_DBUS_NEW_IFACE_INTERFACE, "a{say}",
3182 : wpas_dbus_getter_blobs,
3183 : NULL,
3184 : NULL
3185 : },
3186 : { "BSSs", WPAS_DBUS_NEW_IFACE_INTERFACE, "ao",
3187 : wpas_dbus_getter_bsss,
3188 : NULL,
3189 : NULL
3190 : },
3191 : { "Networks", WPAS_DBUS_NEW_IFACE_INTERFACE, "ao",
3192 : wpas_dbus_getter_networks,
3193 : NULL,
3194 : NULL
3195 : },
3196 : { "FastReauth", WPAS_DBUS_NEW_IFACE_INTERFACE, "b",
3197 : wpas_dbus_getter_fast_reauth,
3198 : wpas_dbus_setter_fast_reauth,
3199 : NULL
3200 : },
3201 : { "ScanInterval", WPAS_DBUS_NEW_IFACE_INTERFACE, "i",
3202 : wpas_dbus_getter_scan_interval,
3203 : wpas_dbus_setter_scan_interval,
3204 : NULL
3205 : },
3206 : { "PKCS11EnginePath", WPAS_DBUS_NEW_IFACE_INTERFACE, "s",
3207 : wpas_dbus_getter_pkcs11_engine_path,
3208 : NULL,
3209 : NULL
3210 : },
3211 : { "PKCS11ModulePath", WPAS_DBUS_NEW_IFACE_INTERFACE, "s",
3212 : wpas_dbus_getter_pkcs11_module_path,
3213 : NULL,
3214 : NULL
3215 : },
3216 : #ifdef CONFIG_WPS
3217 : { "ProcessCredentials", WPAS_DBUS_NEW_IFACE_WPS, "b",
3218 : wpas_dbus_getter_process_credentials,
3219 : wpas_dbus_setter_process_credentials,
3220 : NULL
3221 : },
3222 : { "ConfigMethods", WPAS_DBUS_NEW_IFACE_WPS, "s",
3223 : wpas_dbus_getter_config_methods,
3224 : wpas_dbus_setter_config_methods,
3225 : NULL
3226 : },
3227 : #endif /* CONFIG_WPS */
3228 : #ifdef CONFIG_P2P
3229 : { "P2PDeviceConfig", WPAS_DBUS_NEW_IFACE_P2PDEVICE, "a{sv}",
3230 : wpas_dbus_getter_p2p_device_config,
3231 : wpas_dbus_setter_p2p_device_config,
3232 : NULL
3233 : },
3234 : { "Peers", WPAS_DBUS_NEW_IFACE_P2PDEVICE, "ao",
3235 : wpas_dbus_getter_p2p_peers,
3236 : NULL,
3237 : NULL
3238 : },
3239 : { "Role", WPAS_DBUS_NEW_IFACE_P2PDEVICE, "s",
3240 : wpas_dbus_getter_p2p_role,
3241 : NULL,
3242 : NULL
3243 : },
3244 : { "Group", WPAS_DBUS_NEW_IFACE_P2PDEVICE, "o",
3245 : wpas_dbus_getter_p2p_group,
3246 : NULL,
3247 : NULL
3248 : },
3249 : { "PeerGO", WPAS_DBUS_NEW_IFACE_P2PDEVICE, "o",
3250 : wpas_dbus_getter_p2p_peergo,
3251 : NULL,
3252 : NULL
3253 : },
3254 : { "PersistentGroups", WPAS_DBUS_NEW_IFACE_P2PDEVICE, "ao",
3255 : wpas_dbus_getter_persistent_groups,
3256 : NULL,
3257 : NULL
3258 : },
3259 : #endif /* CONFIG_P2P */
3260 : { "DisconnectReason", WPAS_DBUS_NEW_IFACE_INTERFACE, "i",
3261 : wpas_dbus_getter_disconnect_reason,
3262 : NULL,
3263 : NULL
3264 : },
3265 : { "AssocStatusCode", WPAS_DBUS_NEW_IFACE_INTERFACE, "i",
3266 : wpas_dbus_getter_assoc_status_code,
3267 : NULL,
3268 : NULL
3269 : },
3270 : { NULL, NULL, NULL, NULL, NULL, NULL }
3271 : };
3272 :
3273 : static const struct wpa_dbus_signal_desc wpas_dbus_interface_signals[] = {
3274 : { "ScanDone", WPAS_DBUS_NEW_IFACE_INTERFACE,
3275 : {
3276 : { "success", "b", ARG_OUT },
3277 : END_ARGS
3278 : }
3279 : },
3280 : { "BSSAdded", WPAS_DBUS_NEW_IFACE_INTERFACE,
3281 : {
3282 : { "path", "o", ARG_OUT },
3283 : { "properties", "a{sv}", ARG_OUT },
3284 : END_ARGS
3285 : }
3286 : },
3287 : { "BSSRemoved", WPAS_DBUS_NEW_IFACE_INTERFACE,
3288 : {
3289 : { "path", "o", ARG_OUT },
3290 : END_ARGS
3291 : }
3292 : },
3293 : { "BlobAdded", WPAS_DBUS_NEW_IFACE_INTERFACE,
3294 : {
3295 : { "name", "s", ARG_OUT },
3296 : END_ARGS
3297 : }
3298 : },
3299 : { "BlobRemoved", WPAS_DBUS_NEW_IFACE_INTERFACE,
3300 : {
3301 : { "name", "s", ARG_OUT },
3302 : END_ARGS
3303 : }
3304 : },
3305 : { "NetworkAdded", WPAS_DBUS_NEW_IFACE_INTERFACE,
3306 : {
3307 : { "path", "o", ARG_OUT },
3308 : { "properties", "a{sv}", ARG_OUT },
3309 : END_ARGS
3310 : }
3311 : },
3312 : { "NetworkRemoved", WPAS_DBUS_NEW_IFACE_INTERFACE,
3313 : {
3314 : { "path", "o", ARG_OUT },
3315 : END_ARGS
3316 : }
3317 : },
3318 : { "NetworkSelected", WPAS_DBUS_NEW_IFACE_INTERFACE,
3319 : {
3320 : { "path", "o", ARG_OUT },
3321 : END_ARGS
3322 : }
3323 : },
3324 : /* Deprecated: use org.freedesktop.DBus.Properties.PropertiesChanged */
3325 : { "PropertiesChanged", WPAS_DBUS_NEW_IFACE_INTERFACE,
3326 : {
3327 : { "properties", "a{sv}", ARG_OUT },
3328 : END_ARGS
3329 : }
3330 : },
3331 : #ifdef CONFIG_WPS
3332 : { "Event", WPAS_DBUS_NEW_IFACE_WPS,
3333 : {
3334 : { "name", "s", ARG_OUT },
3335 : { "args", "a{sv}", ARG_OUT },
3336 : END_ARGS
3337 : }
3338 : },
3339 : { "Credentials", WPAS_DBUS_NEW_IFACE_WPS,
3340 : {
3341 : { "credentials", "a{sv}", ARG_OUT },
3342 : END_ARGS
3343 : }
3344 : },
3345 : /* Deprecated: use org.freedesktop.DBus.Properties.PropertiesChanged */
3346 : { "PropertiesChanged", WPAS_DBUS_NEW_IFACE_WPS,
3347 : {
3348 : { "properties", "a{sv}", ARG_OUT },
3349 : END_ARGS
3350 : }
3351 : },
3352 : #endif /* CONFIG_WPS */
3353 : #ifdef CONFIG_P2P
3354 : { "DeviceFound", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
3355 : {
3356 : { "path", "o", ARG_OUT },
3357 : END_ARGS
3358 : }
3359 : },
3360 : { "DeviceFoundProperties", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
3361 : {
3362 : { "path", "o", ARG_OUT },
3363 : { "properties", "a{sv}", ARG_OUT },
3364 : END_ARGS
3365 : }
3366 : },
3367 : { "DeviceLost", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
3368 : {
3369 : { "path", "o", ARG_OUT },
3370 : END_ARGS
3371 : }
3372 : },
3373 : { "FindStopped", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
3374 : {
3375 : END_ARGS
3376 : }
3377 : },
3378 : { "ProvisionDiscoveryRequestDisplayPin", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
3379 : {
3380 : { "peer_object", "o", ARG_OUT },
3381 : { "pin", "s", ARG_OUT },
3382 : END_ARGS
3383 : }
3384 : },
3385 : { "ProvisionDiscoveryResponseDisplayPin", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
3386 : {
3387 : { "peer_object", "o", ARG_OUT },
3388 : { "pin", "s", ARG_OUT },
3389 : END_ARGS
3390 : }
3391 : },
3392 : { "ProvisionDiscoveryRequestEnterPin", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
3393 : {
3394 : { "peer_object", "o", ARG_OUT },
3395 : END_ARGS
3396 : }
3397 : },
3398 : { "ProvisionDiscoveryResponseEnterPin", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
3399 : {
3400 : { "peer_object", "o", ARG_OUT },
3401 : END_ARGS
3402 : }
3403 : },
3404 : { "ProvisionDiscoveryPBCRequest", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
3405 : {
3406 : { "peer_object", "o", ARG_OUT },
3407 : END_ARGS
3408 : }
3409 : },
3410 : { "ProvisionDiscoveryPBCResponse", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
3411 : {
3412 : { "peer_object", "o", ARG_OUT },
3413 : END_ARGS
3414 : }
3415 : },
3416 : { "ProvisionDiscoveryFailure", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
3417 : {
3418 : { "peer_object", "o", ARG_OUT },
3419 : { "status", "i", ARG_OUT },
3420 : END_ARGS
3421 : }
3422 : },
3423 : { "GroupStarted", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
3424 : {
3425 : { "properties", "a{sv}", ARG_OUT },
3426 : END_ARGS
3427 : }
3428 : },
3429 : { "GroupFormationFailure", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
3430 : {
3431 : { "reason", "s", ARG_OUT },
3432 : END_ARGS
3433 : }
3434 : },
3435 : { "GONegotiationSuccess", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
3436 : {
3437 : { "properties", "a{sv}", ARG_OUT },
3438 : END_ARGS
3439 : }
3440 : },
3441 : { "GONegotiationFailure", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
3442 : {
3443 : { "properties", "a{sv}", ARG_OUT },
3444 : END_ARGS
3445 : }
3446 : },
3447 : { "GONegotiationRequest", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
3448 : {
3449 : { "path", "o", ARG_OUT },
3450 : { "dev_passwd_id", "q", ARG_OUT },
3451 : { "device_go_intent", "y", ARG_OUT },
3452 : END_ARGS
3453 : }
3454 : },
3455 : { "InvitationResult", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
3456 : {
3457 : { "invite_result", "a{sv}", ARG_OUT },
3458 : END_ARGS
3459 : }
3460 : },
3461 : { "GroupFinished", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
3462 : {
3463 : { "properties", "a{sv}", ARG_OUT },
3464 : END_ARGS
3465 : }
3466 : },
3467 : { "ServiceDiscoveryRequest", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
3468 : {
3469 : { "sd_request", "a{sv}", ARG_OUT },
3470 : END_ARGS
3471 : }
3472 : },
3473 : { "ServiceDiscoveryResponse", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
3474 : {
3475 : { "sd_response", "a{sv}", ARG_OUT },
3476 : END_ARGS
3477 : }
3478 : },
3479 : { "PersistentGroupAdded", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
3480 : {
3481 : { "path", "o", ARG_OUT },
3482 : { "properties", "a{sv}", ARG_OUT },
3483 : END_ARGS
3484 : }
3485 : },
3486 : { "PersistentGroupRemoved", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
3487 : {
3488 : { "path", "o", ARG_OUT },
3489 : END_ARGS
3490 : }
3491 : },
3492 : { "WpsFailed", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
3493 : {
3494 : { "name", "s", ARG_OUT },
3495 : { "args", "a{sv}", ARG_OUT },
3496 : END_ARGS
3497 : }
3498 : },
3499 : { "InvitationReceived", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
3500 : {
3501 : { "properties", "a{sv}", ARG_OUT },
3502 : END_ARGS
3503 : }
3504 : },
3505 : #endif /* CONFIG_P2P */
3506 : #ifdef CONFIG_AP
3507 : { "ProbeRequest", WPAS_DBUS_NEW_IFACE_INTERFACE,
3508 : {
3509 : { "args", "a{sv}", ARG_OUT },
3510 : END_ARGS
3511 : }
3512 : },
3513 : #endif /* CONFIG_AP */
3514 : { "Certification", WPAS_DBUS_NEW_IFACE_INTERFACE,
3515 : {
3516 : { "certification", "a{sv}", ARG_OUT },
3517 : END_ARGS
3518 : }
3519 : },
3520 : { "EAP", WPAS_DBUS_NEW_IFACE_INTERFACE,
3521 : {
3522 : { "status", "s", ARG_OUT },
3523 : { "parameter", "s", ARG_OUT },
3524 : END_ARGS
3525 : }
3526 : },
3527 : { "StaAuthorized", WPAS_DBUS_NEW_IFACE_INTERFACE,
3528 : {
3529 : { "name", "s", ARG_OUT },
3530 : END_ARGS
3531 : }
3532 : },
3533 : { "StaDeauthorized", WPAS_DBUS_NEW_IFACE_INTERFACE,
3534 : {
3535 : { "name", "s", ARG_OUT },
3536 : END_ARGS
3537 : }
3538 : },
3539 : { "NetworkRequest", WPAS_DBUS_NEW_IFACE_INTERFACE,
3540 : {
3541 : { "path", "o", ARG_OUT },
3542 : { "field", "s", ARG_OUT },
3543 : { "text", "s", ARG_OUT },
3544 : END_ARGS
3545 : }
3546 : },
3547 : { NULL, NULL, { END_ARGS } }
3548 : };
3549 :
3550 :
3551 6 : static int wpa_dbus_ctrl_iface_props_init(struct wpas_dbus_priv *priv)
3552 : {
3553 : size_t all_size;
3554 : unsigned int i, j, count, num_const, num_globals;
3555 : const char *global_name;
3556 : static const char * const ignored_globals[] = {
3557 : "bss_expiration_age", "bss_expiration_scan_count",
3558 : "ap_scan", "country", "fast_reauth",
3559 : "pkcs11_engine_path", "pkcs11_module_path"
3560 : };
3561 :
3562 : /* wpas_dbus_interface_properties terminates with a NULL element */
3563 6 : num_const = ARRAY_SIZE(wpas_dbus_interface_properties) - 1;
3564 :
3565 6 : num_globals = wpa_config_get_num_global_field_names();
3566 6 : priv->globals_start = num_const;
3567 :
3568 : /* allocate enough for all properties + terminating NULL element */
3569 6 : all_size = (num_globals + num_const + 1) *
3570 : sizeof(wpas_dbus_interface_properties[0]);
3571 6 : priv->all_interface_properties = os_zalloc(all_size);
3572 6 : if (!priv->all_interface_properties) {
3573 0 : wpa_printf(MSG_ERROR,
3574 : "dbus: Not enough memory for interface properties");
3575 0 : return -1;
3576 : }
3577 :
3578 : /* Copy constant interface properties to the start of the array */
3579 6 : os_memcpy(priv->all_interface_properties,
3580 : wpas_dbus_interface_properties,
3581 : sizeof(wpas_dbus_interface_properties));
3582 :
3583 : /* Dynamically construct interface global properties */
3584 696 : for (i = 0, count = num_const; i < num_globals; i++) {
3585 : struct wpa_dbus_property_desc *desc;
3586 690 : int no_var = 0;
3587 :
3588 : /* ignore globals that are actually just methods */
3589 690 : global_name = wpa_config_get_global_field_name(i, &no_var);
3590 690 : if (no_var)
3591 66 : continue;
3592 : /* Ignore fields already explicitly exposed */
3593 5256 : for (j = 0; j < ARRAY_SIZE(ignored_globals); j++) {
3594 4620 : if (os_strcmp(global_name, ignored_globals[j]) == 0)
3595 42 : break;
3596 : }
3597 678 : if (j < ARRAY_SIZE(ignored_globals))
3598 42 : continue;
3599 :
3600 636 : desc = &priv->all_interface_properties[count++];
3601 636 : desc->dbus_property = uscore_to_dbus(global_name);
3602 636 : if (!desc->dbus_property) {
3603 0 : wpa_printf(MSG_ERROR,
3604 : "dbus: Not enough memory for D-Bus property name");
3605 0 : goto error;
3606 : }
3607 636 : desc->dbus_interface = WPAS_DBUS_NEW_IFACE_INTERFACE;
3608 636 : desc->type = "s";
3609 636 : desc->getter = wpas_dbus_getter_iface_global;
3610 636 : desc->setter = wpas_dbus_setter_iface_global;
3611 636 : desc->data = global_name;
3612 : }
3613 :
3614 6 : return 0;
3615 :
3616 : error:
3617 0 : wpa_dbus_ctrl_iface_props_deinit(priv);
3618 0 : return -1;
3619 : }
3620 :
3621 :
3622 : /**
3623 : * wpas_dbus_register_interface - Register an interface with D-Bus
3624 : * @wpa_s: wpa_supplicant interface structure
3625 : * Returns: 0 on success, -1 on failure
3626 : */
3627 667 : int wpas_dbus_register_interface(struct wpa_supplicant *wpa_s)
3628 : {
3629 667 : struct wpa_dbus_object_desc *obj_desc = NULL;
3630 667 : struct wpas_dbus_priv *ctrl_iface = wpa_s->global->dbus;
3631 : int next;
3632 :
3633 : /* Do nothing if the control interface is not turned on */
3634 667 : if (ctrl_iface == NULL)
3635 502 : return 0;
3636 :
3637 : /* Create and set the interface's object path */
3638 165 : wpa_s->dbus_new_path = os_zalloc(WPAS_DBUS_OBJECT_PATH_MAX);
3639 165 : if (wpa_s->dbus_new_path == NULL)
3640 1 : return -1;
3641 164 : next = ctrl_iface->next_objid++;
3642 164 : os_snprintf(wpa_s->dbus_new_path, WPAS_DBUS_OBJECT_PATH_MAX,
3643 : WPAS_DBUS_NEW_PATH_INTERFACES "/%u",
3644 : next);
3645 :
3646 164 : obj_desc = os_zalloc(sizeof(struct wpa_dbus_object_desc));
3647 164 : if (!obj_desc) {
3648 1 : wpa_printf(MSG_ERROR,
3649 : "Not enough memory to create object description");
3650 1 : goto err;
3651 : }
3652 :
3653 163 : wpas_dbus_register(obj_desc, wpa_s, NULL, wpas_dbus_interface_methods,
3654 163 : ctrl_iface->all_interface_properties,
3655 : wpas_dbus_interface_signals);
3656 :
3657 163 : wpa_printf(MSG_DEBUG, "dbus: Register interface object '%s'",
3658 : wpa_s->dbus_new_path);
3659 163 : if (wpa_dbus_register_object_per_iface(ctrl_iface,
3660 163 : wpa_s->dbus_new_path,
3661 163 : wpa_s->ifname, obj_desc))
3662 0 : goto err;
3663 :
3664 163 : wpas_dbus_signal_interface_added(wpa_s);
3665 :
3666 163 : return 0;
3667 :
3668 : err:
3669 1 : os_free(wpa_s->dbus_new_path);
3670 1 : wpa_s->dbus_new_path = NULL;
3671 1 : free_dbus_object_desc(obj_desc);
3672 1 : return -1;
3673 : }
3674 :
3675 :
3676 : /**
3677 : * wpas_dbus_unregister_interface - Unregister the interface from D-Bus
3678 : * @wpa_s: wpa_supplicant interface structure
3679 : * Returns: 0 on success, -1 on failure
3680 : */
3681 668 : int wpas_dbus_unregister_interface(struct wpa_supplicant *wpa_s)
3682 : {
3683 : struct wpas_dbus_priv *ctrl_iface;
3684 :
3685 : /* Do nothing if the control interface is not turned on */
3686 668 : if (wpa_s == NULL || wpa_s->global == NULL)
3687 0 : return 0;
3688 668 : ctrl_iface = wpa_s->global->dbus;
3689 668 : if (ctrl_iface == NULL || wpa_s->dbus_new_path == NULL)
3690 505 : return 0;
3691 :
3692 163 : wpa_printf(MSG_DEBUG, "dbus: Unregister interface object '%s'",
3693 : wpa_s->dbus_new_path);
3694 :
3695 : #ifdef CONFIG_AP
3696 163 : if (wpa_s->preq_notify_peer) {
3697 0 : wpas_dbus_unsubscribe_noc(ctrl_iface);
3698 0 : os_free(wpa_s->preq_notify_peer);
3699 0 : wpa_s->preq_notify_peer = NULL;
3700 : }
3701 : #endif /* CONFIG_AP */
3702 :
3703 163 : if (wpa_dbus_unregister_object_per_iface(ctrl_iface,
3704 163 : wpa_s->dbus_new_path))
3705 0 : return -1;
3706 :
3707 163 : wpas_dbus_signal_interface_removed(wpa_s);
3708 :
3709 163 : os_free(wpa_s->dbus_new_path);
3710 163 : wpa_s->dbus_new_path = NULL;
3711 :
3712 163 : return 0;
3713 : }
3714 :
3715 : #ifdef CONFIG_P2P
3716 :
3717 : static const struct wpa_dbus_property_desc wpas_dbus_p2p_peer_properties[] = {
3718 : { "DeviceName", WPAS_DBUS_NEW_IFACE_P2P_PEER, "s",
3719 : wpas_dbus_getter_p2p_peer_device_name,
3720 : NULL,
3721 : NULL
3722 : },
3723 : { "Manufacturer", WPAS_DBUS_NEW_IFACE_P2P_PEER, "s",
3724 : wpas_dbus_getter_p2p_peer_manufacturer,
3725 : NULL,
3726 : NULL
3727 : },
3728 : { "ModelName", WPAS_DBUS_NEW_IFACE_P2P_PEER, "s",
3729 : wpas_dbus_getter_p2p_peer_modelname,
3730 : NULL,
3731 : NULL
3732 : },
3733 : { "ModelNumber", WPAS_DBUS_NEW_IFACE_P2P_PEER, "s",
3734 : wpas_dbus_getter_p2p_peer_modelnumber,
3735 : NULL,
3736 : NULL
3737 : },
3738 : { "SerialNumber", WPAS_DBUS_NEW_IFACE_P2P_PEER, "s",
3739 : wpas_dbus_getter_p2p_peer_serialnumber,
3740 : NULL,
3741 : NULL
3742 : },
3743 : { "PrimaryDeviceType", WPAS_DBUS_NEW_IFACE_P2P_PEER, "ay",
3744 : wpas_dbus_getter_p2p_peer_primary_device_type,
3745 : NULL,
3746 : NULL
3747 : },
3748 : { "config_method", WPAS_DBUS_NEW_IFACE_P2P_PEER, "q",
3749 : wpas_dbus_getter_p2p_peer_config_method,
3750 : NULL,
3751 : NULL
3752 : },
3753 : { "level", WPAS_DBUS_NEW_IFACE_P2P_PEER, "i",
3754 : wpas_dbus_getter_p2p_peer_level,
3755 : NULL,
3756 : NULL
3757 : },
3758 : { "devicecapability", WPAS_DBUS_NEW_IFACE_P2P_PEER, "y",
3759 : wpas_dbus_getter_p2p_peer_device_capability,
3760 : NULL,
3761 : NULL
3762 : },
3763 : { "groupcapability", WPAS_DBUS_NEW_IFACE_P2P_PEER, "y",
3764 : wpas_dbus_getter_p2p_peer_group_capability,
3765 : NULL,
3766 : NULL
3767 : },
3768 : { "SecondaryDeviceTypes", WPAS_DBUS_NEW_IFACE_P2P_PEER, "aay",
3769 : wpas_dbus_getter_p2p_peer_secondary_device_types,
3770 : NULL,
3771 : NULL
3772 : },
3773 : { "VendorExtension", WPAS_DBUS_NEW_IFACE_P2P_PEER, "aay",
3774 : wpas_dbus_getter_p2p_peer_vendor_extension,
3775 : NULL,
3776 : NULL
3777 : },
3778 : { "IEs", WPAS_DBUS_NEW_IFACE_P2P_PEER, "ay",
3779 : wpas_dbus_getter_p2p_peer_ies,
3780 : NULL,
3781 : NULL
3782 : },
3783 : { "DeviceAddress", WPAS_DBUS_NEW_IFACE_P2P_PEER, "ay",
3784 : wpas_dbus_getter_p2p_peer_device_address,
3785 : NULL,
3786 : NULL
3787 : },
3788 : { "Groups", WPAS_DBUS_NEW_IFACE_P2P_PEER, "ao",
3789 : wpas_dbus_getter_p2p_peer_groups,
3790 : NULL,
3791 : NULL
3792 : },
3793 : { NULL, NULL, NULL, NULL, NULL, NULL }
3794 : };
3795 :
3796 : static const struct wpa_dbus_signal_desc wpas_dbus_p2p_peer_signals[] = {
3797 : /* Deprecated: use org.freedesktop.DBus.Properties.PropertiesChanged */
3798 : { "PropertiesChanged", WPAS_DBUS_NEW_IFACE_P2P_PEER,
3799 : {
3800 : { "properties", "a{sv}", ARG_OUT },
3801 : END_ARGS
3802 : }
3803 : },
3804 : { NULL, NULL, { END_ARGS } }
3805 : };
3806 :
3807 : /**
3808 : * wpas_dbus_signal_peer - Send a peer related event signal
3809 : * @wpa_s: %wpa_supplicant network interface data
3810 : * @dev: peer device object
3811 : * @interface: name of the interface emitting this signal.
3812 : * In case of peer objects, it would be emitted by either
3813 : * the "interface object" or by "peer objects"
3814 : * @sig_name: signal name - DeviceFound
3815 : * @properties: Whether to add a second argument with object properties
3816 : *
3817 : * Notify listeners about event related with p2p peer device
3818 : */
3819 2146 : static void wpas_dbus_signal_peer(struct wpa_supplicant *wpa_s,
3820 : const u8 *dev_addr, const char *interface,
3821 : const char *sig_name, int properties)
3822 : {
3823 : struct wpas_dbus_priv *iface;
3824 : DBusMessage *msg;
3825 : DBusMessageIter iter;
3826 : char peer_obj_path[WPAS_DBUS_OBJECT_PATH_MAX], *path;
3827 :
3828 2146 : if (wpa_s->p2p_mgmt)
3829 78 : wpa_s = wpa_s->parent;
3830 :
3831 2146 : iface = wpa_s->global->dbus;
3832 :
3833 : /* Do nothing if the control interface is not turned on */
3834 2146 : if (iface == NULL || !wpa_s->dbus_new_path)
3835 2546 : return;
3836 :
3837 5238 : os_snprintf(peer_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
3838 : "%s/" WPAS_DBUS_NEW_P2P_PEERS_PART "/" COMPACT_MACSTR,
3839 5238 : wpa_s->dbus_new_path, MAC2STR(dev_addr));
3840 :
3841 873 : msg = dbus_message_new_signal(wpa_s->dbus_new_path, interface,
3842 : sig_name);
3843 873 : if (msg == NULL)
3844 0 : return;
3845 :
3846 873 : dbus_message_iter_init_append(msg, &iter);
3847 873 : path = peer_obj_path;
3848 873 : if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_OBJECT_PATH,
3849 873 : &path) ||
3850 293 : (properties && !wpa_dbus_get_object_properties(
3851 : iface, peer_obj_path, WPAS_DBUS_NEW_IFACE_P2P_PEER,
3852 : &iter)))
3853 0 : wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
3854 : else
3855 873 : dbus_connection_send(iface->con, msg, NULL);
3856 :
3857 873 : dbus_message_unref(msg);
3858 : }
3859 :
3860 :
3861 : /**
3862 : * wpas_dbus_signal_peer_found - Send a peer found signal
3863 : * @wpa_s: %wpa_supplicant network interface data
3864 : * @dev_addr: Peer P2P Device Address
3865 : *
3866 : * Notify listeners about find a p2p peer device found
3867 : */
3868 725 : void wpas_dbus_signal_peer_device_found(struct wpa_supplicant *wpa_s,
3869 : const u8 *dev_addr)
3870 : {
3871 725 : wpas_dbus_signal_peer(wpa_s, dev_addr,
3872 : WPAS_DBUS_NEW_IFACE_P2PDEVICE,
3873 : "DeviceFound", FALSE);
3874 :
3875 725 : wpas_dbus_signal_peer(wpa_s, dev_addr,
3876 : WPAS_DBUS_NEW_IFACE_P2PDEVICE,
3877 : "DeviceFoundProperties", TRUE);
3878 725 : }
3879 :
3880 : /**
3881 : * wpas_dbus_signal_peer_lost - Send a peer lost signal
3882 : * @wpa_s: %wpa_supplicant network interface data
3883 : * @dev_addr: Peer P2P Device Address
3884 : *
3885 : * Notify listeners about lost a p2p peer device
3886 : */
3887 696 : void wpas_dbus_signal_peer_device_lost(struct wpa_supplicant *wpa_s,
3888 : const u8 *dev_addr)
3889 : {
3890 696 : wpas_dbus_signal_peer(wpa_s, dev_addr,
3891 : WPAS_DBUS_NEW_IFACE_P2PDEVICE,
3892 : "DeviceLost", FALSE);
3893 696 : }
3894 :
3895 : /**
3896 : * wpas_dbus_register_peer - Register a discovered peer object with dbus
3897 : * @wpa_s: wpa_supplicant interface structure
3898 : * @dev_addr: P2P Device Address of the peer
3899 : * Returns: 0 on success, -1 on failure
3900 : *
3901 : * Registers network representing object with dbus
3902 : */
3903 696 : int wpas_dbus_register_peer(struct wpa_supplicant *wpa_s, const u8 *dev_addr)
3904 : {
3905 : struct wpas_dbus_priv *ctrl_iface;
3906 : struct wpa_dbus_object_desc *obj_desc;
3907 : struct peer_handler_args *arg;
3908 : char peer_obj_path[WPAS_DBUS_OBJECT_PATH_MAX];
3909 :
3910 : /* Do nothing if the control interface is not turned on */
3911 696 : if (wpa_s == NULL || wpa_s->global == NULL)
3912 0 : return 0;
3913 :
3914 696 : ctrl_iface = wpa_s->global->dbus;
3915 696 : if (ctrl_iface == NULL)
3916 409 : return 0;
3917 :
3918 287 : wpa_s = wpa_s->parent->parent;
3919 287 : if (!wpa_s->dbus_new_path)
3920 0 : return 0;
3921 :
3922 1722 : os_snprintf(peer_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
3923 : "%s/" WPAS_DBUS_NEW_P2P_PEERS_PART "/" COMPACT_MACSTR,
3924 1722 : wpa_s->dbus_new_path, MAC2STR(dev_addr));
3925 :
3926 287 : wpa_printf(MSG_INFO, "dbus: Register peer object '%s'",
3927 : peer_obj_path);
3928 287 : obj_desc = os_zalloc(sizeof(struct wpa_dbus_object_desc));
3929 287 : if (!obj_desc) {
3930 0 : wpa_printf(MSG_ERROR,
3931 : "Not enough memory to create object description");
3932 0 : goto err;
3933 : }
3934 :
3935 : /* allocate memory for handlers arguments */
3936 287 : arg = os_zalloc(sizeof(struct peer_handler_args));
3937 287 : if (!arg) {
3938 0 : wpa_printf(MSG_ERROR,
3939 : "Not enough memory to create arguments for method");
3940 0 : goto err;
3941 : }
3942 :
3943 287 : arg->wpa_s = wpa_s;
3944 287 : os_memcpy(arg->p2p_device_addr, dev_addr, ETH_ALEN);
3945 :
3946 287 : wpas_dbus_register(obj_desc, arg, wpa_dbus_free,
3947 : NULL,
3948 : wpas_dbus_p2p_peer_properties,
3949 : wpas_dbus_p2p_peer_signals);
3950 :
3951 287 : if (wpa_dbus_register_object_per_iface(ctrl_iface, peer_obj_path,
3952 287 : wpa_s->ifname, obj_desc))
3953 0 : goto err;
3954 :
3955 287 : return 0;
3956 :
3957 : err:
3958 0 : free_dbus_object_desc(obj_desc);
3959 0 : return -1;
3960 : }
3961 :
3962 : /**
3963 : * wpas_dbus_unregister_peer - Unregister a peer object with dbus
3964 : * @wpa_s: wpa_supplicant interface structure
3965 : * @dev_addr: p2p device addr
3966 : * Returns: 0 on success, -1 on failure
3967 : *
3968 : * Registers network representing object with dbus
3969 : */
3970 696 : int wpas_dbus_unregister_peer(struct wpa_supplicant *wpa_s,
3971 : const u8 *dev_addr)
3972 : {
3973 : struct wpas_dbus_priv *ctrl_iface;
3974 : char peer_obj_path[WPAS_DBUS_OBJECT_PATH_MAX];
3975 : int ret;
3976 :
3977 : /* Do nothing if the control interface is not turned on */
3978 696 : if (wpa_s == NULL || wpa_s->global == NULL)
3979 0 : return 0;
3980 :
3981 696 : wpa_s = wpa_s->parent->parent;
3982 696 : if (!wpa_s->dbus_new_path)
3983 409 : return 0;
3984 :
3985 287 : ctrl_iface = wpa_s->global->dbus;
3986 287 : if (ctrl_iface == NULL)
3987 0 : return 0;
3988 :
3989 1722 : os_snprintf(peer_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
3990 : "%s/" WPAS_DBUS_NEW_P2P_PEERS_PART "/" COMPACT_MACSTR,
3991 1722 : wpa_s->dbus_new_path, MAC2STR(dev_addr));
3992 :
3993 287 : wpa_printf(MSG_INFO, "dbus: Unregister peer object '%s'",
3994 : peer_obj_path);
3995 287 : ret = wpa_dbus_unregister_object_per_iface(ctrl_iface, peer_obj_path);
3996 :
3997 287 : return ret;
3998 : }
3999 :
4000 :
4001 : /**
4002 : * wpas_dbus_signal_p2p_find_stopped - Send P2P Find stopped signal
4003 : * @wpa_s: %wpa_supplicant network interface data
4004 : *
4005 : * Notify listeners about P2P Find stopped
4006 : */
4007 476 : void wpas_dbus_signal_p2p_find_stopped(struct wpa_supplicant *wpa_s)
4008 : {
4009 : struct wpas_dbus_priv *iface;
4010 : DBusMessage *msg;
4011 :
4012 476 : iface = wpa_s->global->dbus;
4013 :
4014 : /* Do nothing if the control interface is not turned on */
4015 476 : if (iface == NULL || !wpa_s->dbus_new_path)
4016 315 : return;
4017 :
4018 161 : msg = dbus_message_new_signal(wpa_s->dbus_new_path,
4019 : WPAS_DBUS_NEW_IFACE_P2PDEVICE,
4020 : "FindStopped");
4021 161 : if (msg == NULL)
4022 0 : return;
4023 :
4024 161 : dbus_connection_send(iface->con, msg, NULL);
4025 :
4026 161 : dbus_message_unref(msg);
4027 : }
4028 :
4029 :
4030 : /**
4031 : * wpas_dbus_signal_peer_groups_changed - Send peer group change property signal
4032 : * @wpa_s: %wpa_supplicant network interface data
4033 : * @dev_addr: P2P Device Address
4034 : *
4035 : * Notify listeners about peer Groups property changes.
4036 : */
4037 532 : void wpas_dbus_signal_peer_groups_changed(struct wpa_supplicant *wpa_s,
4038 : const u8 *dev_addr)
4039 : {
4040 : char peer_obj_path[WPAS_DBUS_OBJECT_PATH_MAX];
4041 :
4042 532 : if (wpa_s->p2p_mgmt)
4043 0 : wpa_s = wpa_s->parent;
4044 :
4045 532 : if (!wpa_s->dbus_new_path)
4046 532 : return;
4047 3192 : os_snprintf(peer_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
4048 : "%s/" WPAS_DBUS_NEW_P2P_PEERS_PART "/" COMPACT_MACSTR,
4049 3192 : wpa_s->dbus_new_path, MAC2STR(dev_addr));
4050 :
4051 532 : wpa_dbus_mark_property_changed(wpa_s->global->dbus, peer_obj_path,
4052 : WPAS_DBUS_NEW_IFACE_P2P_PEER, "Groups");
4053 : }
4054 :
4055 :
4056 : static const struct wpa_dbus_property_desc wpas_dbus_p2p_group_properties[] = {
4057 : { "Members", WPAS_DBUS_NEW_IFACE_P2P_GROUP, "ao",
4058 : wpas_dbus_getter_p2p_group_members,
4059 : NULL,
4060 : NULL
4061 : },
4062 : { "Group", WPAS_DBUS_NEW_IFACE_P2P_GROUP, "o",
4063 : wpas_dbus_getter_p2p_group,
4064 : NULL,
4065 : NULL
4066 : },
4067 : { "Role", WPAS_DBUS_NEW_IFACE_P2P_GROUP, "s",
4068 : wpas_dbus_getter_p2p_role,
4069 : NULL,
4070 : NULL
4071 : },
4072 : { "SSID", WPAS_DBUS_NEW_IFACE_P2P_GROUP, "ay",
4073 : wpas_dbus_getter_p2p_group_ssid,
4074 : NULL,
4075 : NULL
4076 : },
4077 : { "BSSID", WPAS_DBUS_NEW_IFACE_P2P_GROUP, "ay",
4078 : wpas_dbus_getter_p2p_group_bssid,
4079 : NULL,
4080 : NULL
4081 : },
4082 : { "Frequency", WPAS_DBUS_NEW_IFACE_P2P_GROUP, "q",
4083 : wpas_dbus_getter_p2p_group_frequency,
4084 : NULL,
4085 : NULL
4086 : },
4087 : { "Passphrase", WPAS_DBUS_NEW_IFACE_P2P_GROUP, "s",
4088 : wpas_dbus_getter_p2p_group_passphrase,
4089 : NULL,
4090 : NULL
4091 : },
4092 : { "PSK", WPAS_DBUS_NEW_IFACE_P2P_GROUP, "ay",
4093 : wpas_dbus_getter_p2p_group_psk,
4094 : NULL,
4095 : NULL
4096 : },
4097 : { "WPSVendorExtensions", WPAS_DBUS_NEW_IFACE_P2P_GROUP, "aay",
4098 : wpas_dbus_getter_p2p_group_vendor_ext,
4099 : wpas_dbus_setter_p2p_group_vendor_ext,
4100 : NULL
4101 : },
4102 : { NULL, NULL, NULL, NULL, NULL, NULL }
4103 : };
4104 :
4105 : static const struct wpa_dbus_signal_desc wpas_dbus_p2p_group_signals[] = {
4106 : { "PeerJoined", WPAS_DBUS_NEW_IFACE_P2P_GROUP,
4107 : {
4108 : { "peer", "o", ARG_OUT },
4109 : END_ARGS
4110 : }
4111 : },
4112 : { "PeerDisconnected", WPAS_DBUS_NEW_IFACE_P2P_GROUP,
4113 : {
4114 : { "peer", "o", ARG_OUT },
4115 : END_ARGS
4116 : }
4117 : },
4118 : { NULL, NULL, { END_ARGS } }
4119 : };
4120 :
4121 : /**
4122 : * wpas_dbus_register_p2p_group - Register a p2p group object with dbus
4123 : * @wpa_s: wpa_supplicant interface structure
4124 : * @ssid: SSID struct
4125 : * Returns: 0 on success, -1 on failure
4126 : *
4127 : * Registers p2p group representing object with dbus
4128 : */
4129 667 : void wpas_dbus_register_p2p_group(struct wpa_supplicant *wpa_s,
4130 : struct wpa_ssid *ssid)
4131 : {
4132 : struct wpas_dbus_priv *ctrl_iface;
4133 : struct wpa_dbus_object_desc *obj_desc;
4134 : char group_obj_path[WPAS_DBUS_OBJECT_PATH_MAX];
4135 :
4136 : /* Do nothing if the control interface is not turned on */
4137 667 : if (wpa_s == NULL || wpa_s->global == NULL)
4138 667 : return;
4139 :
4140 667 : ctrl_iface = wpa_s->global->dbus;
4141 667 : if (ctrl_iface == NULL)
4142 304 : return;
4143 :
4144 363 : if (wpa_s->dbus_groupobj_path) {
4145 0 : wpa_printf(MSG_INFO, "%s: Group object '%s' already exists",
4146 : __func__, wpa_s->dbus_groupobj_path);
4147 0 : return;
4148 : }
4149 :
4150 363 : if (wpas_dbus_get_group_obj_path(wpa_s, ssid, group_obj_path) < 0)
4151 0 : return;
4152 :
4153 363 : wpa_s->dbus_groupobj_path = os_strdup(group_obj_path);
4154 363 : if (wpa_s->dbus_groupobj_path == NULL)
4155 0 : return;
4156 :
4157 363 : wpa_printf(MSG_INFO, "dbus: Register group object '%s'",
4158 : group_obj_path);
4159 363 : obj_desc = os_zalloc(sizeof(struct wpa_dbus_object_desc));
4160 363 : if (!obj_desc) {
4161 0 : wpa_printf(MSG_ERROR,
4162 : "Not enough memory to create object description");
4163 0 : goto err;
4164 : }
4165 :
4166 363 : wpas_dbus_register(obj_desc, wpa_s, NULL, NULL,
4167 : wpas_dbus_p2p_group_properties,
4168 : wpas_dbus_p2p_group_signals);
4169 :
4170 363 : if (wpa_dbus_register_object_per_iface(ctrl_iface, group_obj_path,
4171 363 : wpa_s->ifname, obj_desc))
4172 0 : goto err;
4173 :
4174 363 : return;
4175 :
4176 : err:
4177 0 : if (wpa_s->dbus_groupobj_path) {
4178 0 : os_free(wpa_s->dbus_groupobj_path);
4179 0 : wpa_s->dbus_groupobj_path = NULL;
4180 : }
4181 :
4182 0 : free_dbus_object_desc(obj_desc);
4183 : }
4184 :
4185 : /**
4186 : * wpas_dbus_unregister_p2p_group - Unregister a p2p group object from dbus
4187 : * @wpa_s: wpa_supplicant interface structure
4188 : * @ssid: network name of the p2p group started
4189 : */
4190 686 : void wpas_dbus_unregister_p2p_group(struct wpa_supplicant *wpa_s,
4191 : const struct wpa_ssid *ssid)
4192 : {
4193 : struct wpas_dbus_priv *ctrl_iface;
4194 :
4195 : /* Do nothing if the control interface is not turned on */
4196 686 : if (wpa_s == NULL || wpa_s->global == NULL)
4197 0 : return;
4198 :
4199 686 : if (wpa_s->p2p_mgmt)
4200 0 : wpa_s = wpa_s->parent;
4201 :
4202 686 : ctrl_iface = wpa_s->global->dbus;
4203 686 : if (ctrl_iface == NULL)
4204 316 : return;
4205 :
4206 370 : if (!wpa_s->dbus_groupobj_path) {
4207 7 : wpa_printf(MSG_DEBUG,
4208 : "%s: Group object '%s' already unregistered",
4209 : __func__, wpa_s->dbus_groupobj_path);
4210 7 : return;
4211 : }
4212 :
4213 363 : peer_groups_changed(wpa_s);
4214 :
4215 363 : wpa_printf(MSG_DEBUG, "dbus: Unregister group object '%s'",
4216 : wpa_s->dbus_groupobj_path);
4217 :
4218 363 : wpa_dbus_unregister_object_per_iface(ctrl_iface,
4219 363 : wpa_s->dbus_groupobj_path);
4220 :
4221 363 : os_free(wpa_s->dbus_groupobj_path);
4222 363 : wpa_s->dbus_groupobj_path = NULL;
4223 : }
4224 :
4225 : static const struct wpa_dbus_property_desc
4226 : wpas_dbus_persistent_group_properties[] = {
4227 : { "Properties", WPAS_DBUS_NEW_IFACE_PERSISTENT_GROUP, "a{sv}",
4228 : wpas_dbus_getter_persistent_group_properties,
4229 : wpas_dbus_setter_persistent_group_properties,
4230 : NULL
4231 : },
4232 : { NULL, NULL, NULL, NULL, NULL, NULL }
4233 : };
4234 :
4235 : /* No signals intended for persistent group objects */
4236 :
4237 : /**
4238 : * wpas_dbus_register_persistent_group - Register a configured(saved)
4239 : * persistent group with dbus
4240 : * @wpa_s: wpa_supplicant interface structure
4241 : * @ssid: persistent group (still represented as a network within wpa)
4242 : * configuration data
4243 : * Returns: 0 on success, -1 on failure
4244 : *
4245 : * Registers a persistent group representing object with dbus.
4246 : */
4247 159 : int wpas_dbus_register_persistent_group(struct wpa_supplicant *wpa_s,
4248 : struct wpa_ssid *ssid)
4249 : {
4250 : struct wpas_dbus_priv *ctrl_iface;
4251 : struct wpa_dbus_object_desc *obj_desc;
4252 : struct network_handler_args *arg;
4253 : char pgrp_obj_path[WPAS_DBUS_OBJECT_PATH_MAX];
4254 :
4255 : /* Do nothing if the control interface is not turned on */
4256 159 : if (wpa_s == NULL || wpa_s->global == NULL)
4257 0 : return 0;
4258 159 : wpa_s = wpa_s->parent->parent;
4259 159 : if (!wpa_s->dbus_new_path)
4260 82 : return 0;
4261 :
4262 : /* Make sure ssid is a persistent group */
4263 77 : if (ssid->disabled != 2 && !ssid->p2p_persistent_group)
4264 0 : return -1; /* should we return w/o complaining? */
4265 :
4266 77 : if (wpa_s->p2p_mgmt)
4267 0 : wpa_s = wpa_s->parent;
4268 :
4269 77 : ctrl_iface = wpa_s->global->dbus;
4270 77 : if (ctrl_iface == NULL)
4271 0 : return 0;
4272 :
4273 : /*
4274 : * Intentionally not coming up with different numbering scheme
4275 : * for persistent groups.
4276 : */
4277 77 : os_snprintf(pgrp_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
4278 : "%s/" WPAS_DBUS_NEW_PERSISTENT_GROUPS_PART "/%u",
4279 : wpa_s->dbus_new_path, ssid->id);
4280 :
4281 77 : wpa_printf(MSG_DEBUG, "dbus: Register persistent group object '%s'",
4282 : pgrp_obj_path);
4283 77 : obj_desc = os_zalloc(sizeof(struct wpa_dbus_object_desc));
4284 77 : if (!obj_desc) {
4285 0 : wpa_printf(MSG_ERROR,
4286 : "dbus: Not enough memory to create object description");
4287 0 : goto err;
4288 : }
4289 :
4290 : /*
4291 : * Reusing the same context structure as that for networks
4292 : * since these are represented using same data structure.
4293 : */
4294 : /* allocate memory for handlers arguments */
4295 77 : arg = os_zalloc(sizeof(struct network_handler_args));
4296 77 : if (!arg) {
4297 0 : wpa_printf(MSG_ERROR,
4298 : "dbus: Not enough memory to create arguments for method");
4299 0 : goto err;
4300 : }
4301 :
4302 77 : arg->wpa_s = wpa_s;
4303 77 : arg->ssid = ssid;
4304 :
4305 77 : wpas_dbus_register(obj_desc, arg, wpa_dbus_free, NULL,
4306 : wpas_dbus_persistent_group_properties,
4307 : NULL);
4308 :
4309 77 : if (wpa_dbus_register_object_per_iface(ctrl_iface, pgrp_obj_path,
4310 77 : wpa_s->ifname, obj_desc))
4311 0 : goto err;
4312 :
4313 77 : wpas_dbus_signal_persistent_group_added(wpa_s, ssid->id);
4314 :
4315 77 : return 0;
4316 :
4317 : err:
4318 0 : free_dbus_object_desc(obj_desc);
4319 0 : return -1;
4320 : }
4321 :
4322 :
4323 : /**
4324 : * wpas_dbus_unregister_persistent_group - Unregister a persistent_group
4325 : * from dbus
4326 : * @wpa_s: wpa_supplicant interface structure
4327 : * @nid: network id
4328 : * Returns: 0 on success, -1 on failure
4329 : *
4330 : * Unregisters persistent group representing object from dbus
4331 : *
4332 : * NOTE: There is a slight issue with the semantics here. While the
4333 : * implementation simply means the persistent group is unloaded from memory,
4334 : * it should not get interpreted as the group is actually being erased/removed
4335 : * from persistent storage as well.
4336 : */
4337 161 : int wpas_dbus_unregister_persistent_group(struct wpa_supplicant *wpa_s,
4338 : int nid)
4339 : {
4340 : struct wpas_dbus_priv *ctrl_iface;
4341 : char pgrp_obj_path[WPAS_DBUS_OBJECT_PATH_MAX];
4342 : int ret;
4343 :
4344 : /* Do nothing if the control interface is not turned on */
4345 161 : if (wpa_s == NULL || wpa_s->global == NULL)
4346 0 : return 0;
4347 :
4348 161 : wpa_s = wpa_s->parent->parent;
4349 :
4350 161 : ctrl_iface = wpa_s->global->dbus;
4351 161 : if (ctrl_iface == NULL || !wpa_s->dbus_new_path)
4352 82 : return 0;
4353 :
4354 79 : os_snprintf(pgrp_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
4355 : "%s/" WPAS_DBUS_NEW_PERSISTENT_GROUPS_PART "/%u",
4356 : wpa_s->dbus_new_path, nid);
4357 :
4358 79 : wpa_printf(MSG_DEBUG, "dbus: Unregister persistent group object '%s'",
4359 : pgrp_obj_path);
4360 79 : ret = wpa_dbus_unregister_object_per_iface(ctrl_iface, pgrp_obj_path);
4361 :
4362 79 : if (!ret)
4363 79 : wpas_dbus_signal_persistent_group_removed(wpa_s, nid);
4364 :
4365 79 : return ret;
4366 : }
4367 :
4368 : #endif /* CONFIG_P2P */
|