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