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>
7 * This software may be distributed under the terms of the BSD license.
8 * See README for more details.
14 #include "common/ieee802_11_defs.h"
16 #include "ap/sta_info.h"
17 #include "../config.h"
18 #include "../wpa_supplicant_i.h"
20 #include "../wpas_glue.h"
21 #include "dbus_new_helpers.h"
22 #include "dbus_dict_helpers.h"
24 #include "dbus_new_handlers.h"
25 #include "dbus_common_i.h"
26 #include "dbus_new_handlers_p2p.h"
28 #include "../p2p_supplicant.h"
30 #ifdef CONFIG_AP /* until needed by something else */
33 * NameOwnerChanged handling
35 * Some services we provide allow an application to register for
36 * a signal that it needs. While it can also unregister, we must
37 * be prepared for the case where the application simply crashes
38 * and thus doesn't clean up properly. The way to handle this in
39 * DBus is to register for the NameOwnerChanged signal which will
40 * signal an owner change to NULL if the peer closes the socket
41 * for whatever reason.
43 * Handle this signal via a filter function whenever necessary.
44 * The code below also handles refcounting in case in the future
45 * there will be multiple instances of this subscription scheme.
47 static const char wpas_dbus_noc_filter_str
[] =
48 "interface=org.freedesktop.DBus,member=NameOwnerChanged";
51 static DBusHandlerResult
noc_filter(DBusConnection
*conn
,
52 DBusMessage
*message
, void *data
)
54 struct wpas_dbus_priv
*priv
= data
;
56 if (dbus_message_get_type(message
) != DBUS_MESSAGE_TYPE_SIGNAL
)
57 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED
;
59 if (dbus_message_is_signal(message
, DBUS_INTERFACE_DBUS
,
60 "NameOwnerChanged")) {
62 const char *prev_owner
;
63 const char *new_owner
;
65 struct wpa_supplicant
*wpa_s
;
67 dbus_error_init(&derr
);
69 if (!dbus_message_get_args(message
, &derr
,
70 DBUS_TYPE_STRING
, &name
,
71 DBUS_TYPE_STRING
, &prev_owner
,
72 DBUS_TYPE_STRING
, &new_owner
,
74 /* Ignore this error */
75 dbus_error_free(&derr
);
76 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED
;
79 for (wpa_s
= priv
->global
->ifaces
; wpa_s
; wpa_s
= wpa_s
->next
) {
80 if (wpa_s
->preq_notify_peer
!= NULL
&&
81 os_strcmp(name
, wpa_s
->preq_notify_peer
) == 0 &&
82 (new_owner
== NULL
|| os_strlen(new_owner
) == 0)) {
83 /* probe request owner disconnected */
84 os_free(wpa_s
->preq_notify_peer
);
85 wpa_s
->preq_notify_peer
= NULL
;
86 wpas_dbus_unsubscribe_noc(priv
);
91 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED
;
95 void wpas_dbus_subscribe_noc(struct wpas_dbus_priv
*priv
)
97 priv
->dbus_noc_refcnt
++;
98 if (priv
->dbus_noc_refcnt
> 1)
101 if (!dbus_connection_add_filter(priv
->con
, noc_filter
, priv
, NULL
)) {
102 wpa_printf(MSG_ERROR
, "dbus: failed to add filter");
106 dbus_bus_add_match(priv
->con
, wpas_dbus_noc_filter_str
, NULL
);
110 void wpas_dbus_unsubscribe_noc(struct wpas_dbus_priv
*priv
)
112 priv
->dbus_noc_refcnt
--;
113 if (priv
->dbus_noc_refcnt
> 0)
116 dbus_bus_remove_match(priv
->con
, wpas_dbus_noc_filter_str
, NULL
);
117 dbus_connection_remove_filter(priv
->con
, noc_filter
, priv
);
120 #endif /* CONFIG_AP */
124 * wpas_dbus_signal_interface - Send a interface related event signal
125 * @wpa_s: %wpa_supplicant network interface data
126 * @sig_name: signal name - InterfaceAdded or InterfaceRemoved
127 * @properties: Whether to add second argument with object properties
129 * Notify listeners about event related with interface
131 static void wpas_dbus_signal_interface(struct wpa_supplicant
*wpa_s
,
132 const char *sig_name
,
133 dbus_bool_t properties
)
135 struct wpas_dbus_priv
*iface
;
137 DBusMessageIter iter
;
139 iface
= wpa_s
->global
->dbus
;
141 /* Do nothing if the control interface is not turned on */
142 if (iface
== NULL
|| !wpa_s
->dbus_new_path
)
145 msg
= dbus_message_new_signal(WPAS_DBUS_NEW_PATH
,
146 WPAS_DBUS_NEW_INTERFACE
, sig_name
);
150 dbus_message_iter_init_append(msg
, &iter
);
151 if (!dbus_message_iter_append_basic(&iter
, DBUS_TYPE_OBJECT_PATH
,
152 &wpa_s
->dbus_new_path
) ||
154 !wpa_dbus_get_object_properties(
155 iface
, wpa_s
->dbus_new_path
,
156 WPAS_DBUS_NEW_IFACE_INTERFACE
, &iter
)))
157 wpa_printf(MSG_ERROR
, "dbus: Failed to construct signal");
159 dbus_connection_send(iface
->con
, msg
, NULL
);
160 dbus_message_unref(msg
);
165 * wpas_dbus_signal_interface_added - Send a interface created signal
166 * @wpa_s: %wpa_supplicant network interface data
168 * Notify listeners about creating new interface
170 static void wpas_dbus_signal_interface_added(struct wpa_supplicant
*wpa_s
)
172 wpas_dbus_signal_interface(wpa_s
, "InterfaceAdded", TRUE
);
177 * wpas_dbus_signal_interface_removed - Send a interface removed signal
178 * @wpa_s: %wpa_supplicant network interface data
180 * Notify listeners about removing interface
182 static void wpas_dbus_signal_interface_removed(struct wpa_supplicant
*wpa_s
)
184 wpas_dbus_signal_interface(wpa_s
, "InterfaceRemoved", FALSE
);
190 * wpas_dbus_signal_scan_done - send scan done signal
191 * @wpa_s: %wpa_supplicant network interface data
192 * @success: indicates if scanning succeed or failed
194 * Notify listeners about finishing a scan
196 void wpas_dbus_signal_scan_done(struct wpa_supplicant
*wpa_s
, int success
)
198 struct wpas_dbus_priv
*iface
;
202 iface
= wpa_s
->global
->dbus
;
204 /* Do nothing if the control interface is not turned on */
205 if (iface
== NULL
|| !wpa_s
->dbus_new_path
)
208 msg
= dbus_message_new_signal(wpa_s
->dbus_new_path
,
209 WPAS_DBUS_NEW_IFACE_INTERFACE
,
214 succ
= success
? TRUE
: FALSE
;
215 if (dbus_message_append_args(msg
, DBUS_TYPE_BOOLEAN
, &succ
,
217 dbus_connection_send(iface
->con
, msg
, NULL
);
219 wpa_printf(MSG_ERROR
, "dbus: Failed to construct signal");
220 dbus_message_unref(msg
);
225 * wpas_dbus_signal_bss - Send a BSS related event signal
226 * @wpa_s: %wpa_supplicant network interface data
227 * @bss_obj_path: BSS object path
228 * @sig_name: signal name - BSSAdded or BSSRemoved
229 * @properties: Whether to add second argument with object properties
231 * Notify listeners about event related with BSS
233 static void wpas_dbus_signal_bss(struct wpa_supplicant
*wpa_s
,
234 const char *bss_obj_path
,
235 const char *sig_name
, dbus_bool_t properties
)
237 struct wpas_dbus_priv
*iface
;
239 DBusMessageIter iter
;
241 iface
= wpa_s
->global
->dbus
;
243 /* Do nothing if the control interface is not turned on */
244 if (iface
== NULL
|| !wpa_s
->dbus_new_path
)
247 msg
= dbus_message_new_signal(wpa_s
->dbus_new_path
,
248 WPAS_DBUS_NEW_IFACE_INTERFACE
,
253 dbus_message_iter_init_append(msg
, &iter
);
254 if (!dbus_message_iter_append_basic(&iter
, DBUS_TYPE_OBJECT_PATH
,
257 !wpa_dbus_get_object_properties(iface
, bss_obj_path
,
258 WPAS_DBUS_NEW_IFACE_BSS
,
260 wpa_printf(MSG_ERROR
, "dbus: Failed to construct signal");
262 dbus_connection_send(iface
->con
, msg
, NULL
);
263 dbus_message_unref(msg
);
268 * wpas_dbus_signal_bss_added - Send a BSS added signal
269 * @wpa_s: %wpa_supplicant network interface data
270 * @bss_obj_path: new BSS object path
272 * Notify listeners about adding new BSS
274 static void wpas_dbus_signal_bss_added(struct wpa_supplicant
*wpa_s
,
275 const char *bss_obj_path
)
277 wpas_dbus_signal_bss(wpa_s
, bss_obj_path
, "BSSAdded", TRUE
);
282 * wpas_dbus_signal_bss_removed - Send a BSS removed signal
283 * @wpa_s: %wpa_supplicant network interface data
284 * @bss_obj_path: BSS object path
286 * Notify listeners about removing BSS
288 static void wpas_dbus_signal_bss_removed(struct wpa_supplicant
*wpa_s
,
289 const char *bss_obj_path
)
291 wpas_dbus_signal_bss(wpa_s
, bss_obj_path
, "BSSRemoved", FALSE
);
296 * wpas_dbus_signal_blob - Send a blob related event signal
297 * @wpa_s: %wpa_supplicant network interface data
299 * @sig_name: signal name - BlobAdded or BlobRemoved
301 * Notify listeners about event related with blob
303 static void wpas_dbus_signal_blob(struct wpa_supplicant
*wpa_s
,
304 const char *name
, const char *sig_name
)
306 struct wpas_dbus_priv
*iface
;
309 iface
= wpa_s
->global
->dbus
;
311 /* Do nothing if the control interface is not turned on */
312 if (iface
== NULL
|| !wpa_s
->dbus_new_path
)
315 msg
= dbus_message_new_signal(wpa_s
->dbus_new_path
,
316 WPAS_DBUS_NEW_IFACE_INTERFACE
,
321 if (dbus_message_append_args(msg
, DBUS_TYPE_STRING
, &name
,
323 dbus_connection_send(iface
->con
, msg
, NULL
);
325 wpa_printf(MSG_ERROR
, "dbus: Failed to construct signal");
326 dbus_message_unref(msg
);
331 * wpas_dbus_signal_blob_added - Send a blob added signal
332 * @wpa_s: %wpa_supplicant network interface data
335 * Notify listeners about adding a new blob
337 void wpas_dbus_signal_blob_added(struct wpa_supplicant
*wpa_s
,
340 wpas_dbus_signal_blob(wpa_s
, name
, "BlobAdded");
345 * wpas_dbus_signal_blob_removed - Send a blob removed signal
346 * @wpa_s: %wpa_supplicant network interface data
349 * Notify listeners about removing blob
351 void wpas_dbus_signal_blob_removed(struct wpa_supplicant
*wpa_s
,
354 wpas_dbus_signal_blob(wpa_s
, name
, "BlobRemoved");
359 * wpas_dbus_signal_network - Send a network related event signal
360 * @wpa_s: %wpa_supplicant network interface data
361 * @id: new network id
362 * @sig_name: signal name - NetworkAdded, NetworkRemoved or NetworkSelected
363 * @properties: determines if add second argument with object properties
365 * Notify listeners about event related with configured network
367 static void wpas_dbus_signal_network(struct wpa_supplicant
*wpa_s
,
368 int id
, const char *sig_name
,
369 dbus_bool_t properties
)
371 struct wpas_dbus_priv
*iface
;
373 DBusMessageIter iter
;
374 char net_obj_path
[WPAS_DBUS_OBJECT_PATH_MAX
], *path
;
376 iface
= wpa_s
->global
->dbus
;
378 /* Do nothing if the control interface is not turned on */
379 if (iface
== NULL
|| !wpa_s
->dbus_new_path
)
382 os_snprintf(net_obj_path
, WPAS_DBUS_OBJECT_PATH_MAX
,
383 "%s/" WPAS_DBUS_NEW_NETWORKS_PART
"/%u",
384 wpa_s
->dbus_new_path
, id
);
386 msg
= dbus_message_new_signal(wpa_s
->dbus_new_path
,
387 WPAS_DBUS_NEW_IFACE_INTERFACE
,
392 dbus_message_iter_init_append(msg
, &iter
);
394 if (!dbus_message_iter_append_basic(&iter
, DBUS_TYPE_OBJECT_PATH
,
397 !wpa_dbus_get_object_properties(
398 iface
, net_obj_path
, WPAS_DBUS_NEW_IFACE_NETWORK
,
400 wpa_printf(MSG_ERROR
, "dbus: Failed to construct signal");
402 dbus_connection_send(iface
->con
, msg
, NULL
);
403 dbus_message_unref(msg
);
408 * wpas_dbus_signal_network_added - Send a network added signal
409 * @wpa_s: %wpa_supplicant network interface data
410 * @id: new network id
412 * Notify listeners about adding new network
414 static void wpas_dbus_signal_network_added(struct wpa_supplicant
*wpa_s
,
417 wpas_dbus_signal_network(wpa_s
, id
, "NetworkAdded", TRUE
);
422 * wpas_dbus_signal_network_removed - Send a network removed signal
423 * @wpa_s: %wpa_supplicant network interface data
426 * Notify listeners about removing a network
428 static void wpas_dbus_signal_network_removed(struct wpa_supplicant
*wpa_s
,
431 wpas_dbus_signal_network(wpa_s
, id
, "NetworkRemoved", FALSE
);
436 * wpas_dbus_signal_network_selected - Send a network selected signal
437 * @wpa_s: %wpa_supplicant network interface data
440 * Notify listeners about selecting a network
442 void wpas_dbus_signal_network_selected(struct wpa_supplicant
*wpa_s
, int id
)
444 wpas_dbus_signal_network(wpa_s
, id
, "NetworkSelected", FALSE
);
449 * wpas_dbus_signal_network_request - Indicate that additional information
450 * (EAP password, etc.) is required to complete the association to this SSID
451 * @wpa_s: %wpa_supplicant network interface data
452 * @rtype: The specific additional information required
453 * @default_text: Optional description of required information
455 * Request additional information or passwords to complete an association
458 void wpas_dbus_signal_network_request(struct wpa_supplicant
*wpa_s
,
459 struct wpa_ssid
*ssid
,
460 enum wpa_ctrl_req_type rtype
,
461 const char *default_txt
)
463 struct wpas_dbus_priv
*iface
;
465 DBusMessageIter iter
;
466 char net_obj_path
[WPAS_DBUS_OBJECT_PATH_MAX
];
467 const char *field
, *txt
= NULL
, *net_ptr
;
469 iface
= wpa_s
->global
->dbus
;
471 /* Do nothing if the control interface is not turned on */
472 if (iface
== NULL
|| !wpa_s
->dbus_new_path
)
475 field
= wpa_supplicant_ctrl_req_to_string(rtype
, default_txt
, &txt
);
479 msg
= dbus_message_new_signal(wpa_s
->dbus_new_path
,
480 WPAS_DBUS_NEW_IFACE_INTERFACE
,
485 os_snprintf(net_obj_path
, WPAS_DBUS_OBJECT_PATH_MAX
,
486 "%s/" WPAS_DBUS_NEW_NETWORKS_PART
"/%u",
487 wpa_s
->dbus_new_path
, ssid
->id
);
488 net_ptr
= &net_obj_path
[0];
490 dbus_message_iter_init_append(msg
, &iter
);
491 if (!dbus_message_iter_append_basic(&iter
, DBUS_TYPE_OBJECT_PATH
,
493 !dbus_message_iter_append_basic(&iter
, DBUS_TYPE_STRING
, &field
) ||
494 !dbus_message_iter_append_basic(&iter
, DBUS_TYPE_STRING
, &txt
))
495 wpa_printf(MSG_ERROR
, "dbus: Failed to construct signal");
497 dbus_connection_send(iface
->con
, msg
, NULL
);
498 dbus_message_unref(msg
);
503 * wpas_dbus_signal_network_enabled_changed - Signals Enabled property changes
504 * @wpa_s: %wpa_supplicant network interface data
505 * @ssid: configured network which Enabled property has changed
507 * Sends PropertyChanged signals containing new value of Enabled property
508 * for specified network
510 void wpas_dbus_signal_network_enabled_changed(struct wpa_supplicant
*wpa_s
,
511 struct wpa_ssid
*ssid
)
514 char path
[WPAS_DBUS_OBJECT_PATH_MAX
];
516 if (!wpa_s
->dbus_new_path
)
518 os_snprintf(path
, WPAS_DBUS_OBJECT_PATH_MAX
,
519 "%s/" WPAS_DBUS_NEW_NETWORKS_PART
"/%d",
520 wpa_s
->dbus_new_path
, ssid
->id
);
522 wpa_dbus_mark_property_changed(wpa_s
->global
->dbus
, path
,
523 WPAS_DBUS_NEW_IFACE_NETWORK
, "Enabled");
530 * wpas_dbus_signal_wps_event_pbc_overlap - Signals PBC overlap WPS event
531 * @wpa_s: %wpa_supplicant network interface data
533 * Sends Event dbus signal with name "pbc-overlap" and empty dict as arguments
535 void wpas_dbus_signal_wps_event_pbc_overlap(struct wpa_supplicant
*wpa_s
)
539 DBusMessageIter iter
, dict_iter
;
540 struct wpas_dbus_priv
*iface
;
541 char *key
= "pbc-overlap";
543 iface
= wpa_s
->global
->dbus
;
545 /* Do nothing if the control interface is not turned on */
546 if (iface
== NULL
|| !wpa_s
->dbus_new_path
)
549 msg
= dbus_message_new_signal(wpa_s
->dbus_new_path
,
550 WPAS_DBUS_NEW_IFACE_WPS
, "Event");
554 dbus_message_iter_init_append(msg
, &iter
);
556 if (!dbus_message_iter_append_basic(&iter
, DBUS_TYPE_STRING
, &key
) ||
557 !wpa_dbus_dict_open_write(&iter
, &dict_iter
) ||
558 !wpa_dbus_dict_close_write(&iter
, &dict_iter
))
559 wpa_printf(MSG_ERROR
, "dbus: Failed to construct signal");
561 dbus_connection_send(iface
->con
, msg
, NULL
);
563 dbus_message_unref(msg
);
568 * wpas_dbus_signal_wps_event_success - Signals Success WPS event
569 * @wpa_s: %wpa_supplicant network interface data
571 * Sends Event dbus signal with name "success" and empty dict as arguments
573 void wpas_dbus_signal_wps_event_success(struct wpa_supplicant
*wpa_s
)
577 DBusMessageIter iter
, dict_iter
;
578 struct wpas_dbus_priv
*iface
;
579 char *key
= "success";
581 iface
= wpa_s
->global
->dbus
;
583 /* Do nothing if the control interface is not turned on */
584 if (iface
== NULL
|| !wpa_s
->dbus_new_path
)
587 msg
= dbus_message_new_signal(wpa_s
->dbus_new_path
,
588 WPAS_DBUS_NEW_IFACE_WPS
, "Event");
592 dbus_message_iter_init_append(msg
, &iter
);
594 if (!dbus_message_iter_append_basic(&iter
, DBUS_TYPE_STRING
, &key
) ||
595 !wpa_dbus_dict_open_write(&iter
, &dict_iter
) ||
596 !wpa_dbus_dict_close_write(&iter
, &dict_iter
))
597 wpa_printf(MSG_ERROR
, "dbus: Failed to construct signal");
599 dbus_connection_send(iface
->con
, msg
, NULL
);
601 dbus_message_unref(msg
);
606 * wpas_dbus_signal_wps_event_fail - Signals Fail WPS event
607 * @wpa_s: %wpa_supplicant network interface data
608 * @fail: WPS failure information
610 * Sends Event dbus signal with name "fail" and dictionary containing
611 * "msg field with fail message number (int32) as arguments
613 void wpas_dbus_signal_wps_event_fail(struct wpa_supplicant
*wpa_s
,
614 struct wps_event_fail
*fail
)
618 DBusMessageIter iter
, dict_iter
;
619 struct wpas_dbus_priv
*iface
;
622 iface
= wpa_s
->global
->dbus
;
624 /* Do nothing if the control interface is not turned on */
625 if (iface
== NULL
|| !wpa_s
->dbus_new_path
)
628 msg
= dbus_message_new_signal(wpa_s
->dbus_new_path
,
629 WPAS_DBUS_NEW_IFACE_WPS
, "Event");
633 dbus_message_iter_init_append(msg
, &iter
);
635 if (!dbus_message_iter_append_basic(&iter
, DBUS_TYPE_STRING
, &key
) ||
636 !wpa_dbus_dict_open_write(&iter
, &dict_iter
) ||
637 !wpa_dbus_dict_append_int32(&dict_iter
, "msg", fail
->msg
) ||
638 !wpa_dbus_dict_append_int32(&dict_iter
, "config_error",
639 fail
->config_error
) ||
640 !wpa_dbus_dict_append_int32(&dict_iter
, "error_indication",
641 fail
->error_indication
) ||
642 !wpa_dbus_dict_close_write(&iter
, &dict_iter
))
643 wpa_printf(MSG_ERROR
, "dbus: Failed to construct signal");
645 dbus_connection_send(iface
->con
, msg
, NULL
);
647 dbus_message_unref(msg
);
652 * wpas_dbus_signal_wps_event_m2d - Signals M2D WPS event
653 * @wpa_s: %wpa_supplicant network interface data
654 * @m2d: M2D event data information
656 * Sends Event dbus signal with name "m2d" and dictionary containing
657 * fields of wps_event_m2d structure.
659 void wpas_dbus_signal_wps_event_m2d(struct wpa_supplicant
*wpa_s
,
660 struct wps_event_m2d
*m2d
)
664 DBusMessageIter iter
, dict_iter
;
665 struct wpas_dbus_priv
*iface
;
668 iface
= wpa_s
->global
->dbus
;
670 /* Do nothing if the control interface is not turned on */
671 if (iface
== NULL
|| !wpa_s
->dbus_new_path
)
674 msg
= dbus_message_new_signal(wpa_s
->dbus_new_path
,
675 WPAS_DBUS_NEW_IFACE_WPS
, "Event");
679 dbus_message_iter_init_append(msg
, &iter
);
681 if (!dbus_message_iter_append_basic(&iter
, DBUS_TYPE_STRING
, &key
) ||
682 !wpa_dbus_dict_open_write(&iter
, &dict_iter
) ||
683 !wpa_dbus_dict_append_uint16(&dict_iter
, "config_methods",
684 m2d
->config_methods
) ||
685 !wpa_dbus_dict_append_byte_array(&dict_iter
, "manufacturer",
686 (const char *) m2d
->manufacturer
,
687 m2d
->manufacturer_len
) ||
688 !wpa_dbus_dict_append_byte_array(&dict_iter
, "model_name",
689 (const char *) m2d
->model_name
,
690 m2d
->model_name_len
) ||
691 !wpa_dbus_dict_append_byte_array(&dict_iter
, "model_number",
692 (const char *) m2d
->model_number
,
693 m2d
->model_number_len
) ||
694 !wpa_dbus_dict_append_byte_array(&dict_iter
, "serial_number",
697 m2d
->serial_number_len
) ||
698 !wpa_dbus_dict_append_byte_array(&dict_iter
, "dev_name",
699 (const char *) m2d
->dev_name
,
700 m2d
->dev_name_len
) ||
701 !wpa_dbus_dict_append_byte_array(&dict_iter
, "primary_dev_type",
703 m2d
->primary_dev_type
, 8) ||
704 !wpa_dbus_dict_append_uint16(&dict_iter
, "config_error",
705 m2d
->config_error
) ||
706 !wpa_dbus_dict_append_uint16(&dict_iter
, "dev_password_id",
707 m2d
->dev_password_id
) ||
708 !wpa_dbus_dict_close_write(&iter
, &dict_iter
))
709 wpa_printf(MSG_ERROR
, "dbus: Failed to construct signal");
711 dbus_connection_send(iface
->con
, msg
, NULL
);
713 dbus_message_unref(msg
);
718 * wpas_dbus_signal_wps_cred - Signals new credentials
719 * @wpa_s: %wpa_supplicant network interface data
720 * @cred: WPS Credential information
722 * Sends signal with credentials in directory argument
724 void wpas_dbus_signal_wps_cred(struct wpa_supplicant
*wpa_s
,
725 const struct wps_credential
*cred
)
728 DBusMessageIter iter
, dict_iter
;
729 struct wpas_dbus_priv
*iface
;
730 char *auth_type
[5]; /* we have five possible authentication types */
732 char *encr_type
[3]; /* we have three possible encryption types */
735 iface
= wpa_s
->global
->dbus
;
737 /* Do nothing if the control interface is not turned on */
738 if (iface
== NULL
|| !wpa_s
->dbus_new_path
)
741 msg
= dbus_message_new_signal(wpa_s
->dbus_new_path
,
742 WPAS_DBUS_NEW_IFACE_WPS
,
747 dbus_message_iter_init_append(msg
, &iter
);
748 if (!wpa_dbus_dict_open_write(&iter
, &dict_iter
))
751 if (cred
->auth_type
& WPS_AUTH_OPEN
)
752 auth_type
[at_num
++] = "open";
753 if (cred
->auth_type
& WPS_AUTH_WPAPSK
)
754 auth_type
[at_num
++] = "wpa-psk";
755 if (cred
->auth_type
& WPS_AUTH_WPA
)
756 auth_type
[at_num
++] = "wpa-eap";
757 if (cred
->auth_type
& WPS_AUTH_WPA2
)
758 auth_type
[at_num
++] = "wpa2-eap";
759 if (cred
->auth_type
& WPS_AUTH_WPA2PSK
)
760 auth_type
[at_num
++] = "wpa2-psk";
762 if (cred
->encr_type
& WPS_ENCR_NONE
)
763 encr_type
[et_num
++] = "none";
764 if (cred
->encr_type
& WPS_ENCR_TKIP
)
765 encr_type
[et_num
++] = "tkip";
766 if (cred
->encr_type
& WPS_ENCR_AES
)
767 encr_type
[et_num
++] = "aes";
769 if ((wpa_s
->current_ssid
&&
770 !wpa_dbus_dict_append_byte_array(
772 (const char *) wpa_s
->current_ssid
->bssid
, ETH_ALEN
)) ||
773 !wpa_dbus_dict_append_byte_array(&dict_iter
, "SSID",
774 (const char *) cred
->ssid
,
776 !wpa_dbus_dict_append_string_array(&dict_iter
, "AuthType",
777 (const char **) auth_type
,
779 !wpa_dbus_dict_append_string_array(&dict_iter
, "EncrType",
780 (const char **) encr_type
,
782 !wpa_dbus_dict_append_byte_array(&dict_iter
, "Key",
783 (const char *) cred
->key
,
785 !wpa_dbus_dict_append_uint32(&dict_iter
, "KeyIndex",
787 !wpa_dbus_dict_close_write(&iter
, &dict_iter
))
790 dbus_connection_send(iface
->con
, msg
, NULL
);
793 dbus_message_unref(msg
);
796 #endif /* CONFIG_WPS */
801 void wpas_dbus_signal_mesh_group_started(struct wpa_supplicant
*wpa_s
,
802 struct wpa_ssid
*ssid
)
804 struct wpas_dbus_priv
*iface
;
806 DBusMessageIter iter
, dict_iter
;
808 iface
= wpa_s
->global
->dbus
;
810 /* Do nothing if the control interface is not turned on */
811 if (!iface
|| !wpa_s
->dbus_new_path
)
814 msg
= dbus_message_new_signal(wpa_s
->dbus_new_path
,
815 WPAS_DBUS_NEW_IFACE_MESH
,
820 dbus_message_iter_init_append(msg
, &iter
);
821 if (!wpa_dbus_dict_open_write(&iter
, &dict_iter
) ||
822 !wpa_dbus_dict_append_byte_array(&dict_iter
, "SSID",
823 (const char *) ssid
->ssid
,
825 !wpa_dbus_dict_close_write(&iter
, &dict_iter
))
826 wpa_printf(MSG_ERROR
, "dbus: Failed to construct signal");
828 dbus_connection_send(iface
->con
, msg
, NULL
);
829 dbus_message_unref(msg
);
833 void wpas_dbus_signal_mesh_group_removed(struct wpa_supplicant
*wpa_s
,
834 const u8
*meshid
, u8 meshid_len
,
837 struct wpas_dbus_priv
*iface
;
839 DBusMessageIter iter
, dict_iter
;
841 iface
= wpa_s
->global
->dbus
;
843 /* Do nothing if the control interface is not turned on */
844 if (!iface
|| !wpa_s
->dbus_new_path
)
847 msg
= dbus_message_new_signal(wpa_s
->dbus_new_path
,
848 WPAS_DBUS_NEW_IFACE_MESH
,
853 dbus_message_iter_init_append(msg
, &iter
);
854 if (!wpa_dbus_dict_open_write(&iter
, &dict_iter
) ||
855 !wpa_dbus_dict_append_byte_array(&dict_iter
, "SSID",
856 (const char *) meshid
,
858 !wpa_dbus_dict_append_int32(&dict_iter
, "DisconnectReason",
860 !wpa_dbus_dict_close_write(&iter
, &dict_iter
))
861 wpa_printf(MSG_ERROR
, "dbus: Failed to construct signal");
863 dbus_connection_send(iface
->con
, msg
, NULL
);
864 dbus_message_unref(msg
);
868 void wpas_dbus_signal_mesh_peer_connected(struct wpa_supplicant
*wpa_s
,
871 struct wpas_dbus_priv
*iface
;
873 DBusMessageIter iter
, dict_iter
;
875 iface
= wpa_s
->global
->dbus
;
877 /* Do nothing if the control interface is not turned on */
878 if (!iface
|| !wpa_s
->dbus_new_path
)
881 msg
= dbus_message_new_signal(wpa_s
->dbus_new_path
,
882 WPAS_DBUS_NEW_IFACE_MESH
,
883 "MeshPeerConnected");
887 dbus_message_iter_init_append(msg
, &iter
);
888 if (!wpa_dbus_dict_open_write(&iter
, &dict_iter
) ||
889 !wpa_dbus_dict_append_byte_array(&dict_iter
, "PeerAddress",
890 (const char *) peer_addr
,
892 !wpa_dbus_dict_close_write(&iter
, &dict_iter
))
893 wpa_printf(MSG_ERROR
, "dbus: Failed to construct signal");
895 dbus_connection_send(iface
->con
, msg
, NULL
);
896 dbus_message_unref(msg
);
900 void wpas_dbus_signal_mesh_peer_disconnected(struct wpa_supplicant
*wpa_s
,
901 const u8
*peer_addr
, int reason
)
903 struct wpas_dbus_priv
*iface
;
905 DBusMessageIter iter
, dict_iter
;
907 iface
= wpa_s
->global
->dbus
;
909 /* Do nothing if the control interface is not turned on */
910 if (!iface
|| !wpa_s
->dbus_new_path
)
913 msg
= dbus_message_new_signal(wpa_s
->dbus_new_path
,
914 WPAS_DBUS_NEW_IFACE_MESH
,
915 "MeshPeerDisconnected");
919 dbus_message_iter_init_append(msg
, &iter
);
920 if (!wpa_dbus_dict_open_write(&iter
, &dict_iter
) ||
921 !wpa_dbus_dict_append_byte_array(&dict_iter
, "PeerAddress",
922 (const char *) peer_addr
,
924 !wpa_dbus_dict_append_int32(&dict_iter
, "DisconnectReason",
926 !wpa_dbus_dict_close_write(&iter
, &dict_iter
))
927 wpa_printf(MSG_ERROR
, "dbus: Failed to construct signal");
929 dbus_connection_send(iface
->con
, msg
, NULL
);
930 dbus_message_unref(msg
);
933 #endif /* CONFIG_MESH */
936 void wpas_dbus_signal_certification(struct wpa_supplicant
*wpa_s
,
937 int depth
, const char *subject
,
938 const char *altsubject
[],
940 const char *cert_hash
,
941 const struct wpabuf
*cert
)
943 struct wpas_dbus_priv
*iface
;
945 DBusMessageIter iter
, dict_iter
;
947 iface
= wpa_s
->global
->dbus
;
949 /* Do nothing if the control interface is not turned on */
950 if (iface
== NULL
|| !wpa_s
->dbus_new_path
)
953 msg
= dbus_message_new_signal(wpa_s
->dbus_new_path
,
954 WPAS_DBUS_NEW_IFACE_INTERFACE
,
959 dbus_message_iter_init_append(msg
, &iter
);
960 if (!wpa_dbus_dict_open_write(&iter
, &dict_iter
) ||
961 !wpa_dbus_dict_append_uint32(&dict_iter
, "depth", depth
) ||
962 !wpa_dbus_dict_append_string(&dict_iter
, "subject", subject
) ||
963 (altsubject
&& num_altsubject
&&
964 !wpa_dbus_dict_append_string_array(&dict_iter
, "altsubject",
965 altsubject
, num_altsubject
)) ||
967 !wpa_dbus_dict_append_string(&dict_iter
, "cert_hash",
970 !wpa_dbus_dict_append_byte_array(&dict_iter
, "cert",
972 wpabuf_len(cert
))) ||
973 !wpa_dbus_dict_close_write(&iter
, &dict_iter
))
974 wpa_printf(MSG_ERROR
, "dbus: Failed to construct signal");
976 dbus_connection_send(iface
->con
, msg
, NULL
);
977 dbus_message_unref(msg
);
981 void wpas_dbus_signal_eap_status(struct wpa_supplicant
*wpa_s
,
982 const char *status
, const char *parameter
)
984 struct wpas_dbus_priv
*iface
;
986 DBusMessageIter iter
;
988 iface
= wpa_s
->global
->dbus
;
990 /* Do nothing if the control interface is not turned on */
991 if (iface
== NULL
|| !wpa_s
->dbus_new_path
)
994 msg
= dbus_message_new_signal(wpa_s
->dbus_new_path
,
995 WPAS_DBUS_NEW_IFACE_INTERFACE
,
1000 dbus_message_iter_init_append(msg
, &iter
);
1002 if (!dbus_message_iter_append_basic(&iter
, DBUS_TYPE_STRING
, &status
) ||
1003 !dbus_message_iter_append_basic(&iter
, DBUS_TYPE_STRING
,
1005 wpa_printf(MSG_ERROR
, "dbus: Failed to construct signal");
1007 dbus_connection_send(iface
->con
, msg
, NULL
);
1008 dbus_message_unref(msg
);
1013 * wpas_dbus_signal_sta - Send a station related event signal
1014 * @wpa_s: %wpa_supplicant network interface data
1015 * @sta: station mac address
1016 * @sig_name: signal name - StaAuthorized or StaDeauthorized
1018 * Notify listeners about event related with station
1020 static void wpas_dbus_signal_sta(struct wpa_supplicant
*wpa_s
,
1021 const u8
*sta
, const char *sig_name
)
1023 struct wpas_dbus_priv
*iface
;
1025 char sta_mac
[WPAS_DBUS_OBJECT_PATH_MAX
];
1028 os_snprintf(sta_mac
, WPAS_DBUS_OBJECT_PATH_MAX
, MACSTR
, MAC2STR(sta
));
1031 iface
= wpa_s
->global
->dbus
;
1033 /* Do nothing if the control interface is not turned on */
1034 if (iface
== NULL
|| !wpa_s
->dbus_new_path
)
1037 msg
= dbus_message_new_signal(wpa_s
->dbus_new_path
,
1038 WPAS_DBUS_NEW_IFACE_INTERFACE
, sig_name
);
1042 if (dbus_message_append_args(msg
, DBUS_TYPE_STRING
, &dev_mac
,
1044 dbus_connection_send(iface
->con
, msg
, NULL
);
1046 wpa_printf(MSG_ERROR
, "dbus: Failed to construct signal");
1047 dbus_message_unref(msg
);
1049 wpa_printf(MSG_DEBUG
, "dbus: Station MAC address '%s' '%s'",
1055 * wpas_dbus_signal_sta_authorized - Send a STA authorized signal
1056 * @wpa_s: %wpa_supplicant network interface data
1057 * @sta: station mac address
1059 * Notify listeners a new station has been authorized
1061 void wpas_dbus_signal_sta_authorized(struct wpa_supplicant
*wpa_s
,
1064 wpas_dbus_signal_sta(wpa_s
, sta
, "StaAuthorized");
1069 * wpas_dbus_signal_sta_deauthorized - Send a STA deauthorized signal
1070 * @wpa_s: %wpa_supplicant network interface data
1071 * @sta: station mac address
1073 * Notify listeners a station has been deauthorized
1075 void wpas_dbus_signal_sta_deauthorized(struct wpa_supplicant
*wpa_s
,
1078 wpas_dbus_signal_sta(wpa_s
, sta
, "StaDeauthorized");
1083 * wpas_dbus_signal_station - Send an event signal related to a station object
1084 * @wpa_s: %wpa_supplicant network interface data
1085 * @station_obj_path: Station object path
1086 * @sig_name: signal name - StationAdded or StationRemoved
1087 * @properties: Whether to add second argument with object properties
1089 * Notify listeners about event related with station.
1091 static void wpas_dbus_signal_station(struct wpa_supplicant
*wpa_s
,
1092 const char *station_obj_path
,
1093 const char *sig_name
,
1094 dbus_bool_t properties
)
1096 struct wpas_dbus_priv
*iface
;
1098 DBusMessageIter iter
;
1100 iface
= wpa_s
->global
->dbus
;
1102 /* Do nothing if the control interface is not turned on */
1103 if (!iface
|| !wpa_s
->dbus_new_path
)
1106 wpa_printf(MSG_DEBUG
, "dbus: STA signal %s", sig_name
);
1107 msg
= dbus_message_new_signal(wpa_s
->dbus_new_path
,
1108 WPAS_DBUS_NEW_IFACE_INTERFACE
, sig_name
);
1112 dbus_message_iter_init_append(msg
, &iter
);
1113 if (!dbus_message_iter_append_basic(&iter
, DBUS_TYPE_OBJECT_PATH
,
1114 &station_obj_path
) ||
1116 !wpa_dbus_get_object_properties(iface
, station_obj_path
,
1117 WPAS_DBUS_NEW_IFACE_STA
,
1119 wpa_printf(MSG_ERROR
, "dbus: Failed to construct signal");
1121 dbus_connection_send(iface
->con
, msg
, NULL
);
1122 dbus_message_unref(msg
);
1127 * wpas_dbus_signal_station_added - Send a Station added signal
1128 * @wpa_s: %wpa_supplicant network interface data
1129 * @station_obj_path: new Station object path
1131 * Notify listeners about adding new Station
1133 static void wpas_dbus_signal_station_added(struct wpa_supplicant
*wpa_s
,
1134 const char *station_obj_path
)
1136 wpas_dbus_signal_station(wpa_s
, station_obj_path
, "StationAdded", TRUE
);
1141 * wpas_dbus_signal_station_removed - Send a Station removed signal
1142 * @wpa_s: %wpa_supplicant network interface data
1143 * @station_obj_path: Station object path
1145 * Notify listeners about removing Station
1147 static void wpas_dbus_signal_station_removed(struct wpa_supplicant
*wpa_s
,
1148 const char *station_obj_path
)
1150 wpas_dbus_signal_station(wpa_s
, station_obj_path
, "StationRemoved",
1158 * wpas_dbus_signal_p2p_group_removed - Signals P2P group was removed
1159 * @wpa_s: %wpa_supplicant network interface data
1160 * @role: role of this device (client or GO)
1161 * Sends signal with i/f name and role as string arguments
1163 void wpas_dbus_signal_p2p_group_removed(struct wpa_supplicant
*wpa_s
,
1167 DBusMessageIter iter
, dict_iter
;
1168 struct wpas_dbus_priv
*iface
= wpa_s
->global
->dbus
;
1169 struct wpa_supplicant
*parent
;
1171 /* Do nothing if the control interface is not turned on */
1175 parent
= wpa_s
->parent
;
1176 if (parent
->p2p_mgmt
)
1177 parent
= parent
->parent
;
1179 if (!wpa_s
->dbus_groupobj_path
|| !wpa_s
->dbus_new_path
||
1180 !parent
->dbus_new_path
)
1183 msg
= dbus_message_new_signal(parent
->dbus_new_path
,
1184 WPAS_DBUS_NEW_IFACE_P2PDEVICE
,
1189 dbus_message_iter_init_append(msg
, &iter
);
1190 if (!wpa_dbus_dict_open_write(&iter
, &dict_iter
) ||
1191 !wpa_dbus_dict_append_object_path(&dict_iter
,
1193 wpa_s
->dbus_new_path
) ||
1194 !wpa_dbus_dict_append_string(&dict_iter
, "role", role
) ||
1195 !wpa_dbus_dict_append_object_path(&dict_iter
, "group_object",
1196 wpa_s
->dbus_groupobj_path
) ||
1197 !wpa_dbus_dict_close_write(&iter
, &dict_iter
))
1198 wpa_printf(MSG_ERROR
, "dbus: Failed to construct signal");
1200 dbus_connection_send(iface
->con
, msg
, NULL
);
1201 dbus_message_unref(msg
);
1206 * wpas_dbus_signal_p2p_provision_discovery - Signals various PD events
1208 * @dev_addr - who sent the request or responded to our request.
1209 * @request - Will be 1 if request, 0 for response.
1210 * @status - valid only in case of response
1211 * @config_methods - wps config methods
1212 * @generated_pin - pin to be displayed in case of WPS_CONFIG_DISPLAY method
1214 * Sends following provision discovery related events:
1215 * ProvisionDiscoveryRequestDisplayPin
1216 * ProvisionDiscoveryResponseDisplayPin
1217 * ProvisionDiscoveryRequestEnterPin
1218 * ProvisionDiscoveryResponseEnterPin
1219 * ProvisionDiscoveryPBCRequest
1220 * ProvisionDiscoveryPBCResponse
1223 * ProvisionDiscoveryFailure (timeout case)
1225 void wpas_dbus_signal_p2p_provision_discovery(struct wpa_supplicant
*wpa_s
,
1226 const u8
*dev_addr
, int request
,
1227 enum p2p_prov_disc_status status
,
1229 unsigned int generated_pin
)
1232 DBusMessageIter iter
;
1233 struct wpas_dbus_priv
*iface
;
1236 char peer_obj_path
[WPAS_DBUS_OBJECT_PATH_MAX
], *path
;
1238 char pin
[9], *p_pin
= NULL
;
1240 iface
= wpa_s
->global
->dbus
;
1242 /* Do nothing if the control interface is not turned on */
1246 if (wpa_s
->p2p_mgmt
)
1247 wpa_s
= wpa_s
->parent
;
1248 if (!wpa_s
->dbus_new_path
)
1251 if (request
|| !status
) {
1252 if (config_methods
& WPS_CONFIG_DISPLAY
)
1254 "ProvisionDiscoveryRequestDisplayPin" :
1255 "ProvisionDiscoveryResponseEnterPin";
1256 else if (config_methods
& WPS_CONFIG_KEYPAD
)
1258 "ProvisionDiscoveryRequestEnterPin" :
1259 "ProvisionDiscoveryResponseDisplayPin";
1260 else if (config_methods
& WPS_CONFIG_PUSHBUTTON
)
1261 _signal
= request
? "ProvisionDiscoveryPBCRequest" :
1262 "ProvisionDiscoveryPBCResponse";
1264 return; /* Unknown or un-supported method */
1266 /* Explicit check for failure response */
1267 _signal
= "ProvisionDiscoveryFailure";
1270 add_pin
= ((request
&& (config_methods
& WPS_CONFIG_DISPLAY
)) ||
1271 (!request
&& !status
&&
1272 (config_methods
& WPS_CONFIG_KEYPAD
)));
1275 os_snprintf(pin
, sizeof(pin
), "%08d", generated_pin
);
1279 msg
= dbus_message_new_signal(wpa_s
->dbus_new_path
,
1280 WPAS_DBUS_NEW_IFACE_P2PDEVICE
, _signal
);
1284 /* Check if this is a known peer */
1285 if (!p2p_peer_known(wpa_s
->global
->p2p
, dev_addr
))
1288 os_snprintf(peer_obj_path
, WPAS_DBUS_OBJECT_PATH_MAX
,
1289 "%s/" WPAS_DBUS_NEW_P2P_PEERS_PART
"/"
1291 wpa_s
->dbus_new_path
, MAC2STR(dev_addr
));
1293 path
= peer_obj_path
;
1295 dbus_message_iter_init_append(msg
, &iter
);
1297 if (!dbus_message_iter_append_basic(&iter
,
1298 DBUS_TYPE_OBJECT_PATH
,
1302 if (!request
&& status
)
1303 /* Attach status to ProvisionDiscoveryFailure */
1304 error_ret
= !dbus_message_iter_append_basic(&iter
,
1308 error_ret
= (add_pin
&&
1309 !dbus_message_iter_append_basic(&iter
,
1315 dbus_connection_send(iface
->con
, msg
, NULL
);
1317 wpa_printf(MSG_ERROR
, "dbus: Failed to construct signal");
1319 dbus_message_unref(msg
);
1324 * wpas_dbus_signal_p2p_go_neg_req - Signal P2P GO Negotiation Request RX
1325 * @wpa_s: %wpa_supplicant network interface data
1326 * @src: Source address of the message triggering this notification
1327 * @dev_passwd_id: WPS Device Password Id
1328 * @go_intent: Peer's GO Intent value
1330 * Sends signal to notify that a peer P2P Device is requesting group owner
1331 * negotiation with us.
1333 void wpas_dbus_signal_p2p_go_neg_req(struct wpa_supplicant
*wpa_s
,
1334 const u8
*src
, u16 dev_passwd_id
,
1338 DBusMessageIter iter
;
1339 struct wpas_dbus_priv
*iface
;
1340 char peer_obj_path
[WPAS_DBUS_OBJECT_PATH_MAX
], *path
;
1342 iface
= wpa_s
->global
->dbus
;
1344 /* Do nothing if the control interface is not turned on */
1348 if (wpa_s
->p2p_mgmt
)
1349 wpa_s
= wpa_s
->parent
;
1350 if (!wpa_s
->dbus_new_path
)
1353 os_snprintf(peer_obj_path
, WPAS_DBUS_OBJECT_PATH_MAX
,
1354 "%s/" WPAS_DBUS_NEW_P2P_PEERS_PART
"/" COMPACT_MACSTR
,
1355 wpa_s
->dbus_new_path
, MAC2STR(src
));
1356 path
= peer_obj_path
;
1358 msg
= dbus_message_new_signal(wpa_s
->dbus_new_path
,
1359 WPAS_DBUS_NEW_IFACE_P2PDEVICE
,
1360 "GONegotiationRequest");
1364 dbus_message_iter_init_append(msg
, &iter
);
1366 if (!dbus_message_iter_append_basic(&iter
, DBUS_TYPE_OBJECT_PATH
,
1368 !dbus_message_iter_append_basic(&iter
, DBUS_TYPE_UINT16
,
1370 !dbus_message_iter_append_basic(&iter
, DBUS_TYPE_BYTE
,
1372 wpa_printf(MSG_ERROR
, "dbus: Failed to construct signal");
1374 dbus_connection_send(iface
->con
, msg
, NULL
);
1376 dbus_message_unref(msg
);
1380 static int wpas_dbus_get_group_obj_path(struct wpa_supplicant
*wpa_s
,
1381 const struct wpa_ssid
*ssid
,
1382 char *group_obj_path
)
1386 if (!wpa_s
->dbus_new_path
||
1387 os_memcmp(ssid
->ssid
, P2P_WILDCARD_SSID
, P2P_WILDCARD_SSID_LEN
))
1390 os_memcpy(group_name
, ssid
->ssid
+ P2P_WILDCARD_SSID_LEN
, 2);
1391 group_name
[2] = '\0';
1393 os_snprintf(group_obj_path
, WPAS_DBUS_OBJECT_PATH_MAX
,
1394 "%s/" WPAS_DBUS_NEW_P2P_GROUPS_PART
"/%s",
1395 wpa_s
->dbus_new_path
, group_name
);
1401 struct group_changed_data
{
1402 struct wpa_supplicant
*wpa_s
;
1403 struct p2p_peer_info
*info
;
1407 static int match_group_where_peer_is_client(struct p2p_group
*group
,
1410 struct group_changed_data
*data
= user_data
;
1411 const struct p2p_group_config
*cfg
;
1412 struct wpa_supplicant
*wpa_s_go
;
1414 if (!p2p_group_is_client_connected(group
, data
->info
->p2p_device_addr
))
1417 cfg
= p2p_group_get_config(group
);
1419 wpa_s_go
= wpas_get_p2p_go_iface(data
->wpa_s
, cfg
->ssid
,
1421 if (wpa_s_go
!= NULL
&& wpa_s_go
== data
->wpa_s
) {
1422 wpas_dbus_signal_peer_groups_changed(
1423 data
->wpa_s
->p2pdev
, data
->info
->p2p_device_addr
);
1431 static void signal_peer_groups_changed(struct p2p_peer_info
*info
,
1434 struct group_changed_data
*data
= user_data
;
1435 struct wpa_supplicant
*wpa_s_go
;
1437 wpa_s_go
= wpas_get_p2p_client_iface(data
->wpa_s
,
1438 info
->p2p_device_addr
);
1439 if (wpa_s_go
!= NULL
&& wpa_s_go
== data
->wpa_s
) {
1440 wpas_dbus_signal_peer_groups_changed(data
->wpa_s
->p2pdev
,
1441 info
->p2p_device_addr
);
1446 p2p_loop_on_all_groups(data
->wpa_s
->global
->p2p
,
1447 match_group_where_peer_is_client
, data
);
1452 static void peer_groups_changed(struct wpa_supplicant
*wpa_s
)
1454 struct group_changed_data data
;
1456 os_memset(&data
, 0, sizeof(data
));
1459 p2p_loop_on_known_peers(wpa_s
->global
->p2p
,
1460 signal_peer_groups_changed
, &data
);
1465 * wpas_dbus_signal_p2p_group_started - Signals P2P group has
1466 * started. Emitted when a group is successfully started
1467 * irrespective of the role (client/GO) of the current device
1469 * @wpa_s: %wpa_supplicant network interface data
1470 * @client: this device is P2P client
1471 * @persistent: 0 - non persistent group, 1 - persistent group
1472 * @ip: When group role is client, it contains local IP address, netmask, and
1473 * GO's IP address, if assigned; otherwise, NULL
1475 void wpas_dbus_signal_p2p_group_started(struct wpa_supplicant
*wpa_s
,
1476 int client
, int persistent
,
1480 DBusMessageIter iter
, dict_iter
;
1481 struct wpas_dbus_priv
*iface
;
1482 struct wpa_supplicant
*parent
;
1484 parent
= wpa_s
->parent
;
1485 if (parent
->p2p_mgmt
)
1486 parent
= parent
->parent
;
1488 iface
= parent
->global
->dbus
;
1490 /* Do nothing if the control interface is not turned on */
1491 if (iface
== NULL
|| !parent
->dbus_new_path
|| !wpa_s
->dbus_new_path
)
1494 if (wpa_s
->dbus_groupobj_path
== NULL
)
1497 /* New interface has been created for this group */
1498 msg
= dbus_message_new_signal(parent
->dbus_new_path
,
1499 WPAS_DBUS_NEW_IFACE_P2PDEVICE
,
1504 dbus_message_iter_init_append(msg
, &iter
);
1506 * In case the device supports creating a separate interface the
1507 * DBus client will need to know the object path for the interface
1508 * object this group was created on, so include it here.
1510 if (!wpa_dbus_dict_open_write(&iter
, &dict_iter
) ||
1511 !wpa_dbus_dict_append_object_path(&dict_iter
,
1513 wpa_s
->dbus_new_path
) ||
1514 !wpa_dbus_dict_append_string(&dict_iter
, "role",
1515 client
? "client" : "GO") ||
1516 !wpa_dbus_dict_append_bool(&dict_iter
, "persistent", persistent
) ||
1517 !wpa_dbus_dict_append_object_path(&dict_iter
, "group_object",
1518 wpa_s
->dbus_groupobj_path
) ||
1520 (!wpa_dbus_dict_append_byte_array(&dict_iter
, "IpAddr",
1522 !wpa_dbus_dict_append_byte_array(&dict_iter
, "IpAddrMask",
1523 (char *) ip
+ 4, 4) ||
1524 !wpa_dbus_dict_append_byte_array(&dict_iter
, "IpAddrGo",
1525 (char *) ip
+ 8, 4))) ||
1526 !wpa_dbus_dict_close_write(&iter
, &dict_iter
)) {
1527 wpa_printf(MSG_ERROR
, "dbus: Failed to construct signal");
1529 dbus_connection_send(iface
->con
, msg
, NULL
);
1531 peer_groups_changed(wpa_s
);
1533 dbus_message_unref(msg
);
1538 * wpas_dbus_signal_p2p_go_neg_resp - Emit GONegotiation Success/Failure signal
1539 * @wpa_s: %wpa_supplicant network interface data
1540 * @res: Result of the GO Neg Request
1542 void wpas_dbus_signal_p2p_go_neg_resp(struct wpa_supplicant
*wpa_s
,
1543 struct p2p_go_neg_results
*res
)
1546 DBusMessageIter iter
, dict_iter
;
1547 DBusMessageIter iter_dict_entry
, iter_dict_val
, iter_dict_array
;
1548 struct wpas_dbus_priv
*iface
;
1549 char peer_obj_path
[WPAS_DBUS_OBJECT_PATH_MAX
], *path
;
1550 dbus_int32_t freqs
[P2P_MAX_CHANNELS
];
1551 dbus_int32_t
*f_array
= freqs
;
1554 iface
= wpa_s
->global
->dbus
;
1556 if (wpa_s
->p2p_mgmt
)
1557 wpa_s
= wpa_s
->parent
;
1559 os_memset(freqs
, 0, sizeof(freqs
));
1560 /* Do nothing if the control interface is not turned on */
1561 if (iface
== NULL
|| !wpa_s
->dbus_new_path
)
1564 os_snprintf(peer_obj_path
, WPAS_DBUS_OBJECT_PATH_MAX
,
1565 "%s/" WPAS_DBUS_NEW_P2P_PEERS_PART
"/" COMPACT_MACSTR
,
1566 wpa_s
->dbus_new_path
, MAC2STR(res
->peer_device_addr
));
1567 path
= peer_obj_path
;
1569 msg
= dbus_message_new_signal(wpa_s
->dbus_new_path
,
1570 WPAS_DBUS_NEW_IFACE_P2PDEVICE
,
1571 res
->status
? "GONegotiationFailure" :
1572 "GONegotiationSuccess");
1576 dbus_message_iter_init_append(msg
, &iter
);
1577 if (!wpa_dbus_dict_open_write(&iter
, &dict_iter
) ||
1578 !wpa_dbus_dict_append_object_path(&dict_iter
, "peer_object",
1580 !wpa_dbus_dict_append_int32(&dict_iter
, "status", res
->status
))
1585 int freq_list_num
= 0;
1587 if ((res
->role_go
&&
1588 !wpa_dbus_dict_append_string(&dict_iter
, "passphrase",
1589 res
->passphrase
)) ||
1590 !wpa_dbus_dict_append_string(&dict_iter
, "role_go",
1591 res
->role_go
? "GO" :
1593 !wpa_dbus_dict_append_int32(&dict_iter
, "frequency",
1595 !wpa_dbus_dict_append_byte_array(&dict_iter
, "ssid",
1596 (const char *) res
->ssid
,
1598 !wpa_dbus_dict_append_byte_array(&dict_iter
,
1601 res
->peer_device_addr
,
1603 !wpa_dbus_dict_append_byte_array(&dict_iter
,
1604 "peer_interface_addr",
1606 res
->peer_interface_addr
,
1608 !wpa_dbus_dict_append_string(&dict_iter
, "wps_method",
1609 p2p_wps_method_text(
1613 for (i
= 0; i
< P2P_MAX_CHANNELS
; i
++) {
1614 if (res
->freq_list
[i
]) {
1615 freqs
[i
] = res
->freq_list
[i
];
1620 if (!wpa_dbus_dict_begin_array(&dict_iter
,
1622 DBUS_TYPE_INT32_AS_STRING
,
1625 &iter_dict_array
) ||
1626 !dbus_message_iter_append_fixed_array(&iter_dict_array
,
1630 !wpa_dbus_dict_end_array(&dict_iter
,
1633 &iter_dict_array
) ||
1634 !wpa_dbus_dict_append_int32(&dict_iter
, "persistent_group",
1635 res
->persistent_group
) ||
1636 !wpa_dbus_dict_append_uint32(&dict_iter
,
1637 "peer_config_timeout",
1638 res
->peer_config_timeout
))
1642 if (!wpa_dbus_dict_close_write(&iter
, &dict_iter
))
1645 dbus_connection_send(iface
->con
, msg
, NULL
);
1647 dbus_message_unref(msg
);
1652 * wpas_dbus_signal_p2p_invitation_result - Emit InvitationResult signal
1653 * @wpa_s: %wpa_supplicant network interface data
1654 * @status: Status of invitation process
1655 * @bssid: Basic Service Set Identifier
1657 void wpas_dbus_signal_p2p_invitation_result(struct wpa_supplicant
*wpa_s
,
1658 int status
, const u8
*bssid
)
1661 DBusMessageIter iter
, dict_iter
;
1662 struct wpas_dbus_priv
*iface
;
1664 wpa_printf(MSG_DEBUG
, "%s", __func__
);
1666 iface
= wpa_s
->global
->dbus
;
1667 /* Do nothing if the control interface is not turned on */
1671 if (wpa_s
->p2p_mgmt
)
1672 wpa_s
= wpa_s
->parent
;
1673 if (!wpa_s
->dbus_new_path
)
1676 msg
= dbus_message_new_signal(wpa_s
->dbus_new_path
,
1677 WPAS_DBUS_NEW_IFACE_P2PDEVICE
,
1678 "InvitationResult");
1683 dbus_message_iter_init_append(msg
, &iter
);
1684 if (!wpa_dbus_dict_open_write(&iter
, &dict_iter
) ||
1685 !wpa_dbus_dict_append_int32(&dict_iter
, "status", status
) ||
1687 !wpa_dbus_dict_append_byte_array(&dict_iter
, "BSSID",
1688 (const char *) bssid
,
1690 !wpa_dbus_dict_close_write(&iter
, &dict_iter
))
1691 wpa_printf(MSG_ERROR
, "dbus: Failed to construct signal");
1693 dbus_connection_send(iface
->con
, msg
, NULL
);
1694 dbus_message_unref(msg
);
1700 * Method to emit a signal for a peer joining the group.
1701 * The signal will carry path to the group member object
1702 * constructed using p2p i/f addr used for connecting.
1704 * @wpa_s: %wpa_supplicant network interface data
1705 * @peer_addr: P2P Device Address of the peer joining the group
1707 void wpas_dbus_signal_p2p_peer_joined(struct wpa_supplicant
*wpa_s
,
1708 const u8
*peer_addr
)
1710 struct wpas_dbus_priv
*iface
;
1712 DBusMessageIter iter
;
1713 char peer_obj_path
[WPAS_DBUS_OBJECT_PATH_MAX
], *path
;
1714 struct wpa_supplicant
*parent
;
1716 iface
= wpa_s
->global
->dbus
;
1718 /* Do nothing if the control interface is not turned on */
1722 if (!wpa_s
->dbus_groupobj_path
)
1725 parent
= wpa_s
->parent
;
1726 if (parent
->p2p_mgmt
)
1727 parent
= parent
->parent
;
1728 if (!parent
->dbus_new_path
)
1731 os_snprintf(peer_obj_path
, WPAS_DBUS_OBJECT_PATH_MAX
,
1732 "%s/" WPAS_DBUS_NEW_P2P_PEERS_PART
"/"
1734 parent
->dbus_new_path
, MAC2STR(peer_addr
));
1736 msg
= dbus_message_new_signal(wpa_s
->dbus_groupobj_path
,
1737 WPAS_DBUS_NEW_IFACE_P2P_GROUP
,
1742 dbus_message_iter_init_append(msg
, &iter
);
1743 path
= peer_obj_path
;
1744 if (!dbus_message_iter_append_basic(&iter
, DBUS_TYPE_OBJECT_PATH
,
1746 wpa_printf(MSG_ERROR
, "dbus: Failed to construct signal");
1748 dbus_connection_send(iface
->con
, msg
, NULL
);
1749 wpas_dbus_signal_peer_groups_changed(parent
, peer_addr
);
1751 dbus_message_unref(msg
);
1757 * Method to emit a signal for a peer disconnecting the group.
1758 * The signal will carry path to the group member object
1759 * constructed using the P2P Device Address of the peer.
1761 * @wpa_s: %wpa_supplicant network interface data
1762 * @peer_addr: P2P Device Address of the peer joining the group
1764 void wpas_dbus_signal_p2p_peer_disconnected(struct wpa_supplicant
*wpa_s
,
1765 const u8
*peer_addr
)
1767 struct wpas_dbus_priv
*iface
;
1769 DBusMessageIter iter
;
1770 char peer_obj_path
[WPAS_DBUS_OBJECT_PATH_MAX
], *path
;
1771 struct wpa_supplicant
*parent
;
1773 iface
= wpa_s
->global
->dbus
;
1775 /* Do nothing if the control interface is not turned on */
1779 if (!wpa_s
->dbus_groupobj_path
)
1782 parent
= wpa_s
->parent
;
1783 if (parent
->p2p_mgmt
)
1784 parent
= parent
->parent
;
1785 if (!parent
->dbus_new_path
)
1788 os_snprintf(peer_obj_path
, WPAS_DBUS_OBJECT_PATH_MAX
,
1789 "%s/" WPAS_DBUS_NEW_P2P_PEERS_PART
"/"
1791 parent
->dbus_new_path
, MAC2STR(peer_addr
));
1793 msg
= dbus_message_new_signal(wpa_s
->dbus_groupobj_path
,
1794 WPAS_DBUS_NEW_IFACE_P2P_GROUP
,
1795 "PeerDisconnected");
1799 dbus_message_iter_init_append(msg
, &iter
);
1800 path
= peer_obj_path
;
1801 if (!dbus_message_iter_append_basic(&iter
, DBUS_TYPE_OBJECT_PATH
,
1803 wpa_printf(MSG_ERROR
,
1804 "dbus: Failed to construct PeerDisconnected signal");
1806 dbus_connection_send(iface
->con
, msg
, NULL
);
1807 wpas_dbus_signal_peer_groups_changed(parent
, peer_addr
);
1809 dbus_message_unref(msg
);
1815 * Method to emit a signal for a service discovery request.
1816 * The signal will carry station address, frequency, dialog token,
1817 * update indicator and it tlvs
1819 * @wpa_s: %wpa_supplicant network interface data
1820 * @sa: station addr (p2p i/f) of the peer
1821 * @dialog_token: service discovery request dialog token
1822 * @update_indic: service discovery request update indicator
1823 * @tlvs: service discovery request genrated byte array of tlvs
1824 * @tlvs_len: service discovery request tlvs length
1826 void wpas_dbus_signal_p2p_sd_request(struct wpa_supplicant
*wpa_s
,
1827 int freq
, const u8
*sa
, u8 dialog_token
,
1828 u16 update_indic
, const u8
*tlvs
,
1832 DBusMessageIter iter
, dict_iter
;
1833 struct wpas_dbus_priv
*iface
;
1834 char peer_obj_path
[WPAS_DBUS_OBJECT_PATH_MAX
], *path
;
1836 iface
= wpa_s
->global
->dbus
;
1838 /* Do nothing if the control interface is not turned on */
1842 if (wpa_s
->p2p_mgmt
)
1843 wpa_s
= wpa_s
->parent
;
1844 if (!wpa_s
->dbus_new_path
)
1847 /* Check if this is a known peer */
1848 if (!p2p_peer_known(wpa_s
->global
->p2p
, sa
))
1851 msg
= dbus_message_new_signal(wpa_s
->dbus_new_path
,
1852 WPAS_DBUS_NEW_IFACE_P2PDEVICE
,
1853 "ServiceDiscoveryRequest");
1857 os_snprintf(peer_obj_path
, WPAS_DBUS_OBJECT_PATH_MAX
,
1858 "%s/" WPAS_DBUS_NEW_P2P_PEERS_PART
"/"
1859 COMPACT_MACSTR
, wpa_s
->dbus_new_path
, MAC2STR(sa
));
1861 path
= peer_obj_path
;
1863 dbus_message_iter_init_append(msg
, &iter
);
1864 if (!wpa_dbus_dict_open_write(&iter
, &dict_iter
) ||
1865 !wpa_dbus_dict_append_object_path(&dict_iter
, "peer_object",
1867 !wpa_dbus_dict_append_int32(&dict_iter
, "frequency", freq
) ||
1868 !wpa_dbus_dict_append_int32(&dict_iter
, "dialog_token",
1870 !wpa_dbus_dict_append_uint16(&dict_iter
, "update_indicator",
1872 !wpa_dbus_dict_append_byte_array(&dict_iter
, "tlvs",
1873 (const char *) tlvs
,
1875 !wpa_dbus_dict_close_write(&iter
, &dict_iter
))
1876 wpa_printf(MSG_ERROR
, "dbus: Failed to construct signal");
1878 dbus_connection_send(iface
->con
, msg
, NULL
);
1879 dbus_message_unref(msg
);
1885 * Method to emit a signal for a service discovery response.
1886 * The signal will carry station address, update indicator and it
1889 * @wpa_s: %wpa_supplicant network interface data
1890 * @sa: station addr (p2p i/f) of the peer
1891 * @update_indic: service discovery request update indicator
1892 * @tlvs: service discovery request genrated byte array of tlvs
1893 * @tlvs_len: service discovery request tlvs length
1895 void wpas_dbus_signal_p2p_sd_response(struct wpa_supplicant
*wpa_s
,
1896 const u8
*sa
, u16 update_indic
,
1897 const u8
*tlvs
, size_t tlvs_len
)
1900 DBusMessageIter iter
, dict_iter
;
1901 struct wpas_dbus_priv
*iface
;
1902 char peer_obj_path
[WPAS_DBUS_OBJECT_PATH_MAX
], *path
;
1904 iface
= wpa_s
->global
->dbus
;
1906 /* Do nothing if the control interface is not turned on */
1910 if (wpa_s
->p2p_mgmt
)
1911 wpa_s
= wpa_s
->parent
;
1912 if (!wpa_s
->dbus_new_path
)
1915 /* Check if this is a known peer */
1916 if (!p2p_peer_known(wpa_s
->global
->p2p
, sa
))
1919 msg
= dbus_message_new_signal(wpa_s
->dbus_new_path
,
1920 WPAS_DBUS_NEW_IFACE_P2PDEVICE
,
1921 "ServiceDiscoveryResponse");
1925 os_snprintf(peer_obj_path
, WPAS_DBUS_OBJECT_PATH_MAX
,
1926 "%s/" WPAS_DBUS_NEW_P2P_PEERS_PART
"/"
1927 COMPACT_MACSTR
, wpa_s
->dbus_new_path
, MAC2STR(sa
));
1929 path
= peer_obj_path
;
1931 dbus_message_iter_init_append(msg
, &iter
);
1932 if (!wpa_dbus_dict_open_write(&iter
, &dict_iter
) ||
1933 !wpa_dbus_dict_append_object_path(&dict_iter
, "peer_object",
1935 !wpa_dbus_dict_append_uint16(&dict_iter
, "update_indicator",
1937 !wpa_dbus_dict_append_byte_array(&dict_iter
, "tlvs",
1938 (const char *) tlvs
,
1940 !wpa_dbus_dict_close_write(&iter
, &dict_iter
))
1941 wpa_printf(MSG_ERROR
, "dbus: Failed to construct signal");
1943 dbus_connection_send(iface
->con
, msg
, NULL
);
1944 dbus_message_unref(msg
);
1949 * wpas_dbus_signal_persistent_group - Send a persistent group related
1951 * @wpa_s: %wpa_supplicant network interface data
1952 * @id: new persistent group id
1953 * @sig_name: signal name - PersistentGroupAdded, PersistentGroupRemoved
1954 * @properties: determines if add second argument with object properties
1956 * Notify listeners about an event related to persistent groups.
1958 static void wpas_dbus_signal_persistent_group(struct wpa_supplicant
*wpa_s
,
1959 int id
, const char *sig_name
,
1960 dbus_bool_t properties
)
1962 struct wpas_dbus_priv
*iface
;
1964 DBusMessageIter iter
;
1965 char pgrp_obj_path
[WPAS_DBUS_OBJECT_PATH_MAX
], *path
;
1967 iface
= wpa_s
->global
->dbus
;
1969 /* Do nothing if the control interface is not turned on */
1973 if (wpa_s
->p2p_mgmt
)
1974 wpa_s
= wpa_s
->parent
;
1975 if (!wpa_s
->dbus_new_path
)
1978 os_snprintf(pgrp_obj_path
, WPAS_DBUS_OBJECT_PATH_MAX
,
1979 "%s/" WPAS_DBUS_NEW_PERSISTENT_GROUPS_PART
"/%u",
1980 wpa_s
->dbus_new_path
, id
);
1982 msg
= dbus_message_new_signal(wpa_s
->dbus_new_path
,
1983 WPAS_DBUS_NEW_IFACE_P2PDEVICE
,
1988 dbus_message_iter_init_append(msg
, &iter
);
1989 path
= pgrp_obj_path
;
1990 if (!dbus_message_iter_append_basic(&iter
, DBUS_TYPE_OBJECT_PATH
,
1993 !wpa_dbus_get_object_properties(
1994 iface
, pgrp_obj_path
,
1995 WPAS_DBUS_NEW_IFACE_PERSISTENT_GROUP
, &iter
)))
1996 wpa_printf(MSG_ERROR
, "dbus: Failed to construct signal");
1998 dbus_connection_send(iface
->con
, msg
, NULL
);
2000 dbus_message_unref(msg
);
2005 * wpas_dbus_signal_persistent_group_added - Send a persistent_group
2007 * @wpa_s: %wpa_supplicant network interface data
2008 * @id: new persistent group id
2010 * Notify listeners about addition of a new persistent group.
2012 static void wpas_dbus_signal_persistent_group_added(
2013 struct wpa_supplicant
*wpa_s
, int id
)
2015 wpas_dbus_signal_persistent_group(wpa_s
, id
, "PersistentGroupAdded",
2021 * wpas_dbus_signal_persistent_group_removed - Send a persistent_group
2023 * @wpa_s: %wpa_supplicant network interface data
2024 * @id: persistent group id
2026 * Notify listeners about removal of a persistent group.
2028 static void wpas_dbus_signal_persistent_group_removed(
2029 struct wpa_supplicant
*wpa_s
, int id
)
2031 wpas_dbus_signal_persistent_group(wpa_s
, id
, "PersistentGroupRemoved",
2037 * wpas_dbus_signal_p2p_wps_failed - Signals WpsFailed event
2038 * @wpa_s: %wpa_supplicant network interface data
2039 * @fail: WPS failure information
2041 * Sends Event dbus signal with name "fail" and dictionary containing
2042 * "msg" field with fail message number (int32) as arguments
2044 void wpas_dbus_signal_p2p_wps_failed(struct wpa_supplicant
*wpa_s
,
2045 struct wps_event_fail
*fail
)
2049 DBusMessageIter iter
, dict_iter
;
2050 struct wpas_dbus_priv
*iface
;
2053 iface
= wpa_s
->global
->dbus
;
2055 /* Do nothing if the control interface is not turned on */
2059 if (wpa_s
->p2p_mgmt
)
2060 wpa_s
= wpa_s
->parent
;
2062 if (!wpa_s
->dbus_new_path
)
2064 msg
= dbus_message_new_signal(wpa_s
->dbus_new_path
,
2065 WPAS_DBUS_NEW_IFACE_P2PDEVICE
,
2070 dbus_message_iter_init_append(msg
, &iter
);
2072 if (!dbus_message_iter_append_basic(&iter
, DBUS_TYPE_STRING
, &key
) ||
2073 !wpa_dbus_dict_open_write(&iter
, &dict_iter
) ||
2074 !wpa_dbus_dict_append_int32(&dict_iter
, "msg", fail
->msg
) ||
2075 !wpa_dbus_dict_append_int16(&dict_iter
, "config_error",
2076 fail
->config_error
) ||
2077 !wpa_dbus_dict_close_write(&iter
, &dict_iter
))
2078 wpa_printf(MSG_ERROR
, "dbus: Failed to construct signal");
2080 dbus_connection_send(iface
->con
, msg
, NULL
);
2082 dbus_message_unref(msg
);
2087 * wpas_dbus_signal_p2p_group_formation_failure - Signals GroupFormationFailure event
2088 * @wpa_s: %wpa_supplicant network interface data
2089 * @reason: indicates the reason code for group formation failure
2091 * Sends Event dbus signal and string reason code when available.
2093 void wpas_dbus_signal_p2p_group_formation_failure(struct wpa_supplicant
*wpa_s
,
2097 struct wpas_dbus_priv
*iface
;
2099 iface
= wpa_s
->global
->dbus
;
2101 /* Do nothing if the control interface is not turned on */
2105 if (wpa_s
->p2p_mgmt
)
2106 wpa_s
= wpa_s
->parent
;
2108 msg
= dbus_message_new_signal(wpa_s
->dbus_new_path
,
2109 WPAS_DBUS_NEW_IFACE_P2PDEVICE
,
2110 "GroupFormationFailure");
2114 if (dbus_message_append_args(msg
, DBUS_TYPE_STRING
, &reason
,
2116 dbus_connection_send(iface
->con
, msg
, NULL
);
2118 wpa_printf(MSG_ERROR
, "dbus: Failed to construct signal");
2120 dbus_message_unref(msg
);
2125 * wpas_dbus_signal_p2p_invitation_received - Emit InvitationReceived signal
2126 * @wpa_s: %wpa_supplicant network interface data
2127 * @sa: Source address of the Invitation Request
2128 * @dev_add: GO Device Address
2129 * @bssid: P2P Group BSSID or %NULL if not received
2130 * @id: Persistent group id or %0 if not persistent group
2131 * @op_freq: Operating frequency for the group
2134 void wpas_dbus_signal_p2p_invitation_received(struct wpa_supplicant
*wpa_s
,
2135 const u8
*sa
, const u8
*dev_addr
,
2136 const u8
*bssid
, int id
,
2140 DBusMessageIter iter
, dict_iter
;
2141 struct wpas_dbus_priv
*iface
;
2143 iface
= wpa_s
->global
->dbus
;
2145 /* Do nothing if the control interface is not turned on */
2149 if (wpa_s
->p2p_mgmt
)
2150 wpa_s
= wpa_s
->parent
;
2152 msg
= dbus_message_new_signal(wpa_s
->dbus_new_path
,
2153 WPAS_DBUS_NEW_IFACE_P2PDEVICE
,
2154 "InvitationReceived");
2158 dbus_message_iter_init_append(msg
, &iter
);
2159 if (!wpa_dbus_dict_open_write(&iter
, &dict_iter
) ||
2161 !wpa_dbus_dict_append_byte_array(&dict_iter
, "sa",
2162 (const char *) sa
, ETH_ALEN
)) ||
2164 !wpa_dbus_dict_append_byte_array(&dict_iter
, "go_dev_addr",
2165 (const char *) dev_addr
,
2168 !wpa_dbus_dict_append_byte_array(&dict_iter
, "bssid",
2169 (const char *) bssid
,
2172 !wpa_dbus_dict_append_int32(&dict_iter
, "persistent_id", id
)) ||
2173 !wpa_dbus_dict_append_int32(&dict_iter
, "op_freq", op_freq
) ||
2174 !wpa_dbus_dict_close_write(&iter
, &dict_iter
)) {
2175 dbus_message_unref(msg
);
2179 dbus_connection_send(iface
->con
, msg
, NULL
);
2180 dbus_message_unref(msg
);
2184 #endif /* CONFIG_P2P */
2188 * wpas_dbus_signal_prop_changed - Signals change of property
2189 * @wpa_s: %wpa_supplicant network interface data
2190 * @property: indicates which property has changed
2192 * Sends PropertyChanged signals with path, interface and arguments
2193 * depending on which property has changed.
2195 void wpas_dbus_signal_prop_changed(struct wpa_supplicant
*wpa_s
,
2196 enum wpas_dbus_prop property
)
2201 if (wpa_s
->dbus_new_path
== NULL
)
2202 return; /* Skip signal since D-Bus setup is not yet ready */
2206 case WPAS_DBUS_PROP_AP_SCAN
:
2209 case WPAS_DBUS_PROP_SCANNING
:
2212 case WPAS_DBUS_PROP_STATE
:
2215 case WPAS_DBUS_PROP_CURRENT_BSS
:
2216 prop
= "CurrentBSS";
2218 case WPAS_DBUS_PROP_CURRENT_NETWORK
:
2219 prop
= "CurrentNetwork";
2221 case WPAS_DBUS_PROP_BSSS
:
2224 case WPAS_DBUS_PROP_STATIONS
:
2227 case WPAS_DBUS_PROP_CURRENT_AUTH_MODE
:
2228 prop
= "CurrentAuthMode";
2230 case WPAS_DBUS_PROP_DISCONNECT_REASON
:
2231 prop
= "DisconnectReason";
2234 case WPAS_DBUS_PROP_AUTH_STATUS_CODE
:
2235 prop
= "AuthStatusCode";
2238 case WPAS_DBUS_PROP_ASSOC_STATUS_CODE
:
2239 prop
= "AssocStatusCode";
2242 case WPAS_DBUS_PROP_ROAM_TIME
:
2245 case WPAS_DBUS_PROP_ROAM_COMPLETE
:
2246 prop
= "RoamComplete";
2248 case WPAS_DBUS_PROP_SESSION_LENGTH
:
2249 prop
= "SessionLength";
2251 case WPAS_DBUS_PROP_BSS_TM_STATUS
:
2252 prop
= "BSSTMStatus";
2255 wpa_printf(MSG_ERROR
, "dbus: %s: Unknown Property value %d",
2256 __func__
, property
);
2260 wpa_dbus_mark_property_changed(wpa_s
->global
->dbus
,
2261 wpa_s
->dbus_new_path
,
2262 WPAS_DBUS_NEW_IFACE_INTERFACE
, prop
);
2264 wpa_dbus_flush_object_changed_properties(
2265 wpa_s
->global
->dbus
->con
, wpa_s
->dbus_new_path
);
2271 * wpas_dbus_bss_signal_prop_changed - Signals change of BSS property
2272 * @wpa_s: %wpa_supplicant network interface data
2273 * @property: indicates which property has changed
2274 * @id: unique BSS identifier
2276 * Sends PropertyChanged signals with path, interface, and arguments depending
2277 * on which property has changed.
2279 void wpas_dbus_bss_signal_prop_changed(struct wpa_supplicant
*wpa_s
,
2280 enum wpas_dbus_bss_prop property
,
2283 char path
[WPAS_DBUS_OBJECT_PATH_MAX
];
2286 if (!wpa_s
->dbus_new_path
)
2290 case WPAS_DBUS_BSS_PROP_SIGNAL
:
2293 case WPAS_DBUS_BSS_PROP_FREQ
:
2296 case WPAS_DBUS_BSS_PROP_MODE
:
2299 case WPAS_DBUS_BSS_PROP_PRIVACY
:
2302 case WPAS_DBUS_BSS_PROP_RATES
:
2305 case WPAS_DBUS_BSS_PROP_WPA
:
2308 case WPAS_DBUS_BSS_PROP_RSN
:
2311 case WPAS_DBUS_BSS_PROP_WPS
:
2314 case WPAS_DBUS_BSS_PROP_IES
:
2317 case WPAS_DBUS_BSS_PROP_AGE
:
2321 wpa_printf(MSG_ERROR
, "dbus: %s: Unknown Property value %d",
2322 __func__
, property
);
2326 os_snprintf(path
, WPAS_DBUS_OBJECT_PATH_MAX
,
2327 "%s/" WPAS_DBUS_NEW_BSSIDS_PART
"/%u",
2328 wpa_s
->dbus_new_path
, id
);
2330 wpa_dbus_mark_property_changed(wpa_s
->global
->dbus
, path
,
2331 WPAS_DBUS_NEW_IFACE_BSS
, prop
);
2336 * wpas_dbus_sta_signal_prop_changed - Signals change of STA property
2337 * @wpa_s: %wpa_supplicant network interface data
2338 * @property: indicates which property has changed
2339 * @address: unique BSS identifier
2341 * Sends PropertyChanged signals with path, interface, and arguments depending
2342 * on which property has changed.
2344 void wpas_dbus_sta_signal_prop_changed(struct wpa_supplicant
*wpa_s
,
2345 enum wpas_dbus_bss_prop property
,
2346 u8 address
[ETH_ALEN
])
2348 char path
[WPAS_DBUS_OBJECT_PATH_MAX
];
2352 case WPAS_DBUS_STA_PROP_ADDRESS
:
2356 wpa_printf(MSG_ERROR
, "dbus: %s: Unknown Property value %d",
2357 __func__
, property
);
2361 os_snprintf(path
, WPAS_DBUS_OBJECT_PATH_MAX
,
2362 "%s/" WPAS_DBUS_NEW_STAS_PART
"/" COMPACT_MACSTR
,
2363 wpa_s
->dbus_new_path
, MAC2STR(address
));
2365 wpa_dbus_mark_property_changed(wpa_s
->global
->dbus
, path
,
2366 WPAS_DBUS_NEW_IFACE_STA
, prop
);
2371 * wpas_dbus_signal_debug_level_changed - Signals change of debug param
2372 * @global: wpa_global structure
2374 * Sends PropertyChanged signals informing that debug level has changed.
2376 void wpas_dbus_signal_debug_level_changed(struct wpa_global
*global
)
2378 wpa_dbus_mark_property_changed(global
->dbus
, WPAS_DBUS_NEW_PATH
,
2379 WPAS_DBUS_NEW_INTERFACE
,
2385 * wpas_dbus_signal_debug_timestamp_changed - Signals change of debug param
2386 * @global: wpa_global structure
2388 * Sends PropertyChanged signals informing that debug timestamp has changed.
2390 void wpas_dbus_signal_debug_timestamp_changed(struct wpa_global
*global
)
2392 wpa_dbus_mark_property_changed(global
->dbus
, WPAS_DBUS_NEW_PATH
,
2393 WPAS_DBUS_NEW_INTERFACE
,
2399 * wpas_dbus_signal_debug_show_keys_changed - Signals change of debug param
2400 * @global: wpa_global structure
2402 * Sends PropertyChanged signals informing that debug show_keys has changed.
2404 void wpas_dbus_signal_debug_show_keys_changed(struct wpa_global
*global
)
2406 wpa_dbus_mark_property_changed(global
->dbus
, WPAS_DBUS_NEW_PATH
,
2407 WPAS_DBUS_NEW_INTERFACE
,
2412 static void wpas_dbus_register(struct wpa_dbus_object_desc
*obj_desc
,
2414 WPADBusArgumentFreeFunction priv_free
,
2415 const struct wpa_dbus_method_desc
*methods
,
2416 const struct wpa_dbus_property_desc
*properties
,
2417 const struct wpa_dbus_signal_desc
*signals
)
2421 obj_desc
->user_data
= priv
;
2422 obj_desc
->user_data_free_func
= priv_free
;
2423 obj_desc
->methods
= methods
;
2424 obj_desc
->properties
= properties
;
2425 obj_desc
->signals
= signals
;
2427 for (n
= 0; properties
&& properties
->dbus_property
; properties
++)
2430 obj_desc
->prop_changed_flags
= os_zalloc(n
);
2431 if (!obj_desc
->prop_changed_flags
)
2432 wpa_printf(MSG_DEBUG
, "dbus: %s: can't register handlers",
2437 static const struct wpa_dbus_method_desc wpas_dbus_global_methods
[] = {
2438 { "CreateInterface", WPAS_DBUS_NEW_INTERFACE
,
2439 (WPADBusMethodHandler
) wpas_dbus_handler_create_interface
,
2441 { "args", "a{sv}", ARG_IN
},
2442 { "path", "o", ARG_OUT
},
2446 { "RemoveInterface", WPAS_DBUS_NEW_INTERFACE
,
2447 (WPADBusMethodHandler
) wpas_dbus_handler_remove_interface
,
2449 { "path", "o", ARG_IN
},
2453 { "GetInterface", WPAS_DBUS_NEW_INTERFACE
,
2454 (WPADBusMethodHandler
) wpas_dbus_handler_get_interface
,
2456 { "ifname", "s", ARG_IN
},
2457 { "path", "o", ARG_OUT
},
2461 { "ExpectDisconnect", WPAS_DBUS_NEW_INTERFACE
,
2462 (WPADBusMethodHandler
) wpas_dbus_handler_expect_disconnect
,
2467 { NULL
, NULL
, NULL
, { END_ARGS
} }
2470 static const struct wpa_dbus_property_desc wpas_dbus_global_properties
[] = {
2471 { "DebugLevel", WPAS_DBUS_NEW_INTERFACE
, "s",
2472 wpas_dbus_getter_debug_level
,
2473 wpas_dbus_setter_debug_level
,
2476 { "DebugTimestamp", WPAS_DBUS_NEW_INTERFACE
, "b",
2477 wpas_dbus_getter_debug_timestamp
,
2478 wpas_dbus_setter_debug_timestamp
,
2481 { "DebugShowKeys", WPAS_DBUS_NEW_INTERFACE
, "b",
2482 wpas_dbus_getter_debug_show_keys
,
2483 wpas_dbus_setter_debug_show_keys
,
2486 { "Interfaces", WPAS_DBUS_NEW_INTERFACE
, "ao",
2487 wpas_dbus_getter_interfaces
,
2491 { "EapMethods", WPAS_DBUS_NEW_INTERFACE
, "as",
2492 wpas_dbus_getter_eap_methods
,
2496 { "Capabilities", WPAS_DBUS_NEW_INTERFACE
, "as",
2497 wpas_dbus_getter_global_capabilities
,
2501 #ifdef CONFIG_WIFI_DISPLAY
2502 { "WFDIEs", WPAS_DBUS_NEW_INTERFACE
, "ay",
2503 wpas_dbus_getter_global_wfd_ies
,
2504 wpas_dbus_setter_global_wfd_ies
,
2507 #endif /* CONFIG_WIFI_DISPLAY */
2508 { NULL
, NULL
, NULL
, NULL
, NULL
, NULL
}
2511 static const struct wpa_dbus_signal_desc wpas_dbus_global_signals
[] = {
2512 { "InterfaceAdded", WPAS_DBUS_NEW_INTERFACE
,
2514 { "path", "o", ARG_OUT
},
2515 { "properties", "a{sv}", ARG_OUT
},
2519 { "InterfaceRemoved", WPAS_DBUS_NEW_INTERFACE
,
2521 { "path", "o", ARG_OUT
},
2525 /* Deprecated: use org.freedesktop.DBus.Properties.PropertiesChanged */
2526 { "PropertiesChanged", WPAS_DBUS_NEW_INTERFACE
,
2528 { "properties", "a{sv}", ARG_OUT
},
2532 { NULL
, NULL
, { END_ARGS
} }
2536 static char * uscore_to_dbus(const char *uscore
)
2538 const char *p
= uscore
;
2540 dbus_bool_t last_was_uscore
= TRUE
;
2542 s
= str
= os_zalloc(os_strlen(uscore
) + 1);
2547 last_was_uscore
= TRUE
;
2549 *s
++ = last_was_uscore
? toupper(*p
) : *p
;
2550 last_was_uscore
= FALSE
;
2559 static int wpa_dbus_ctrl_iface_props_init(struct wpas_dbus_priv
*priv
);
2562 static void wpa_dbus_ctrl_iface_props_deinit(struct wpas_dbus_priv
*priv
)
2564 int idx
= priv
->globals_start
;
2566 /* Free all allocated property values */
2567 while (priv
->all_interface_properties
[idx
].dbus_property
)
2569 priv
->all_interface_properties
[idx
++].dbus_property
);
2570 os_free((char *) priv
->all_interface_properties
);
2575 * wpas_dbus_ctrl_iface_init - Initialize dbus control interface
2576 * @global: Pointer to global data from wpa_supplicant_init()
2577 * Returns: 0 on success or -1 on failure
2579 * Initialize the dbus control interface for wpa_supplicant and start
2580 * receiving commands from external programs over the bus.
2582 int wpas_dbus_ctrl_iface_init(struct wpas_dbus_priv
*priv
)
2584 struct wpa_dbus_object_desc
*obj_desc
;
2587 ret
= wpa_dbus_ctrl_iface_props_init(priv
);
2589 wpa_printf(MSG_ERROR
,
2590 "dbus: Not enough memory to init interface properties");
2594 obj_desc
= os_zalloc(sizeof(struct wpa_dbus_object_desc
));
2596 wpa_printf(MSG_ERROR
,
2597 "Not enough memory to create object description");
2601 wpas_dbus_register(obj_desc
, priv
->global
, NULL
,
2602 wpas_dbus_global_methods
,
2603 wpas_dbus_global_properties
,
2604 wpas_dbus_global_signals
);
2606 wpa_printf(MSG_DEBUG
, "dbus: Register D-Bus object '%s'",
2607 WPAS_DBUS_NEW_PATH
);
2608 ret
= wpa_dbus_ctrl_iface_init(priv
, WPAS_DBUS_NEW_PATH
,
2609 WPAS_DBUS_NEW_SERVICE
,
2612 free_dbus_object_desc(obj_desc
);
2616 priv
->dbus_new_initialized
= 1;
2620 wpa_dbus_ctrl_iface_props_deinit(priv
);
2626 * wpas_dbus_ctrl_iface_deinit - Deinitialize dbus ctrl interface for
2628 * @priv: Pointer to dbus private data from wpas_dbus_init()
2630 * Deinitialize the dbus control interface that was initialized with
2631 * wpas_dbus_ctrl_iface_init().
2633 void wpas_dbus_ctrl_iface_deinit(struct wpas_dbus_priv
*priv
)
2635 if (!priv
->dbus_new_initialized
)
2637 wpa_printf(MSG_DEBUG
, "dbus: Unregister D-Bus object '%s'",
2638 WPAS_DBUS_NEW_PATH
);
2639 dbus_connection_unregister_object_path(priv
->con
, WPAS_DBUS_NEW_PATH
);
2640 wpa_dbus_ctrl_iface_props_deinit(priv
);
2644 static void wpa_dbus_free(void *ptr
)
2650 static const struct wpa_dbus_property_desc wpas_dbus_network_properties
[] = {
2651 { "Properties", WPAS_DBUS_NEW_IFACE_NETWORK
, "a{sv}",
2652 wpas_dbus_getter_network_properties
,
2653 wpas_dbus_setter_network_properties
,
2656 { "Enabled", WPAS_DBUS_NEW_IFACE_NETWORK
, "b",
2657 wpas_dbus_getter_enabled
,
2658 wpas_dbus_setter_enabled
,
2661 { NULL
, NULL
, NULL
, NULL
, NULL
, NULL
}
2665 static const struct wpa_dbus_signal_desc wpas_dbus_network_signals
[] = {
2666 /* Deprecated: use org.freedesktop.DBus.Properties.PropertiesChanged */
2667 { "PropertiesChanged", WPAS_DBUS_NEW_IFACE_NETWORK
,
2669 { "properties", "a{sv}", ARG_OUT
},
2673 { NULL
, NULL
, { END_ARGS
} }
2678 * wpas_dbus_register_network - Register a configured network with dbus
2679 * @wpa_s: wpa_supplicant interface structure
2680 * @ssid: network configuration data
2681 * Returns: 0 on success, -1 on failure
2683 * Registers network representing object with dbus
2685 int wpas_dbus_register_network(struct wpa_supplicant
*wpa_s
,
2686 struct wpa_ssid
*ssid
)
2688 struct wpas_dbus_priv
*ctrl_iface
;
2689 struct wpa_dbus_object_desc
*obj_desc
;
2690 struct network_handler_args
*arg
;
2691 char net_obj_path
[WPAS_DBUS_OBJECT_PATH_MAX
];
2695 * If it is a persistent group register it as such.
2696 * This is to handle cases where an interface is being initialized
2697 * with a list of networks read from config.
2699 if (network_is_persistent_group(ssid
))
2700 return wpas_dbus_register_persistent_group(wpa_s
, ssid
);
2701 #endif /* CONFIG_P2P */
2703 /* Do nothing if the control interface is not turned on */
2704 if (wpa_s
== NULL
|| wpa_s
->global
== NULL
|| !wpa_s
->dbus_new_path
)
2706 ctrl_iface
= wpa_s
->global
->dbus
;
2707 if (ctrl_iface
== NULL
)
2710 os_snprintf(net_obj_path
, WPAS_DBUS_OBJECT_PATH_MAX
,
2711 "%s/" WPAS_DBUS_NEW_NETWORKS_PART
"/%u",
2712 wpa_s
->dbus_new_path
, ssid
->id
);
2714 wpa_printf(MSG_DEBUG
, "dbus: Register network object '%s'",
2716 obj_desc
= os_zalloc(sizeof(struct wpa_dbus_object_desc
));
2718 wpa_printf(MSG_ERROR
,
2719 "Not enough memory to create object description");
2723 /* allocate memory for handlers arguments */
2724 arg
= os_zalloc(sizeof(struct network_handler_args
));
2726 wpa_printf(MSG_ERROR
,
2727 "Not enough memory to create arguments for method");
2734 wpas_dbus_register(obj_desc
, arg
, wpa_dbus_free
, NULL
,
2735 wpas_dbus_network_properties
,
2736 wpas_dbus_network_signals
);
2738 if (wpa_dbus_register_object_per_iface(ctrl_iface
, net_obj_path
,
2739 wpa_s
->ifname
, obj_desc
))
2742 wpas_dbus_signal_network_added(wpa_s
, ssid
->id
);
2747 free_dbus_object_desc(obj_desc
);
2753 * wpas_dbus_unregister_network - Unregister a configured network from dbus
2754 * @wpa_s: wpa_supplicant interface structure
2756 * Returns: 0 on success, -1 on failure
2758 * Unregisters network representing object from dbus
2760 int wpas_dbus_unregister_network(struct wpa_supplicant
*wpa_s
, int nid
)
2762 struct wpas_dbus_priv
*ctrl_iface
;
2763 char net_obj_path
[WPAS_DBUS_OBJECT_PATH_MAX
];
2766 struct wpa_ssid
*ssid
;
2768 ssid
= wpa_config_get_network(wpa_s
->conf
, nid
);
2770 /* If it is a persistent group unregister it as such */
2771 if (ssid
&& network_is_persistent_group(ssid
))
2772 return wpas_dbus_unregister_persistent_group(wpa_s
, nid
);
2773 #endif /* CONFIG_P2P */
2775 /* Do nothing if the control interface is not turned on */
2776 if (wpa_s
->global
== NULL
|| wpa_s
->dbus_new_path
== NULL
)
2778 ctrl_iface
= wpa_s
->global
->dbus
;
2779 if (ctrl_iface
== NULL
)
2782 os_snprintf(net_obj_path
, WPAS_DBUS_OBJECT_PATH_MAX
,
2783 "%s/" WPAS_DBUS_NEW_NETWORKS_PART
"/%u",
2784 wpa_s
->dbus_new_path
, nid
);
2786 wpa_printf(MSG_DEBUG
, "dbus: Unregister network object '%s'",
2788 ret
= wpa_dbus_unregister_object_per_iface(ctrl_iface
, net_obj_path
);
2791 wpas_dbus_signal_network_removed(wpa_s
, nid
);
2797 static const struct wpa_dbus_property_desc wpas_dbus_bss_properties
[] = {
2798 { "SSID", WPAS_DBUS_NEW_IFACE_BSS
, "ay",
2799 wpas_dbus_getter_bss_ssid
,
2803 { "BSSID", WPAS_DBUS_NEW_IFACE_BSS
, "ay",
2804 wpas_dbus_getter_bss_bssid
,
2808 { "Privacy", WPAS_DBUS_NEW_IFACE_BSS
, "b",
2809 wpas_dbus_getter_bss_privacy
,
2813 { "Mode", WPAS_DBUS_NEW_IFACE_BSS
, "s",
2814 wpas_dbus_getter_bss_mode
,
2818 { "Signal", WPAS_DBUS_NEW_IFACE_BSS
, "n",
2819 wpas_dbus_getter_bss_signal
,
2823 { "Frequency", WPAS_DBUS_NEW_IFACE_BSS
, "q",
2824 wpas_dbus_getter_bss_frequency
,
2828 { "Rates", WPAS_DBUS_NEW_IFACE_BSS
, "au",
2829 wpas_dbus_getter_bss_rates
,
2833 { "WPA", WPAS_DBUS_NEW_IFACE_BSS
, "a{sv}",
2834 wpas_dbus_getter_bss_wpa
,
2838 { "RSN", WPAS_DBUS_NEW_IFACE_BSS
, "a{sv}",
2839 wpas_dbus_getter_bss_rsn
,
2843 { "WPS", WPAS_DBUS_NEW_IFACE_BSS
, "a{sv}",
2844 wpas_dbus_getter_bss_wps
,
2848 { "IEs", WPAS_DBUS_NEW_IFACE_BSS
, "ay",
2849 wpas_dbus_getter_bss_ies
,
2853 { "Age", WPAS_DBUS_NEW_IFACE_BSS
, "u",
2854 wpas_dbus_getter_bss_age
,
2859 "RoamTime", WPAS_DBUS_NEW_IFACE_INTERFACE
, "u",
2860 wpas_dbus_getter_roam_time
,
2865 "RoamComplete", WPAS_DBUS_NEW_IFACE_INTERFACE
, "b",
2866 wpas_dbus_getter_roam_complete
,
2871 "SessionLength", WPAS_DBUS_NEW_IFACE_INTERFACE
, "u",
2872 wpas_dbus_getter_session_length
,
2877 "BSSTMStatus", WPAS_DBUS_NEW_IFACE_INTERFACE
, "u",
2878 wpas_dbus_getter_bss_tm_status
,
2882 { NULL
, NULL
, NULL
, NULL
, NULL
, NULL
}
2886 static const struct wpa_dbus_signal_desc wpas_dbus_bss_signals
[] = {
2887 /* Deprecated: use org.freedesktop.DBus.Properties.PropertiesChanged */
2888 { "PropertiesChanged", WPAS_DBUS_NEW_IFACE_BSS
,
2890 { "properties", "a{sv}", ARG_OUT
},
2894 { NULL
, NULL
, { END_ARGS
} }
2899 * wpas_dbus_unregister_bss - Unregister a scanned BSS from dbus
2900 * @wpa_s: wpa_supplicant interface structure
2901 * @bssid: scanned network bssid
2902 * @id: unique BSS identifier
2903 * Returns: 0 on success, -1 on failure
2905 * Unregisters BSS representing object from dbus
2907 int wpas_dbus_unregister_bss(struct wpa_supplicant
*wpa_s
,
2908 u8 bssid
[ETH_ALEN
], unsigned int id
)
2910 struct wpas_dbus_priv
*ctrl_iface
;
2911 char bss_obj_path
[WPAS_DBUS_OBJECT_PATH_MAX
];
2913 /* Do nothing if the control interface is not turned on */
2914 if (wpa_s
== NULL
|| wpa_s
->global
== NULL
|| !wpa_s
->dbus_new_path
)
2916 ctrl_iface
= wpa_s
->global
->dbus
;
2917 if (ctrl_iface
== NULL
)
2920 os_snprintf(bss_obj_path
, WPAS_DBUS_OBJECT_PATH_MAX
,
2921 "%s/" WPAS_DBUS_NEW_BSSIDS_PART
"/%u",
2922 wpa_s
->dbus_new_path
, id
);
2924 wpa_printf(MSG_DEBUG
, "dbus: Unregister BSS object '%s'",
2926 if (wpa_dbus_unregister_object_per_iface(ctrl_iface
, bss_obj_path
)) {
2927 wpa_printf(MSG_ERROR
, "dbus: Cannot unregister BSS object %s",
2932 wpas_dbus_signal_bss_removed(wpa_s
, bss_obj_path
);
2933 wpas_dbus_signal_prop_changed(wpa_s
, WPAS_DBUS_PROP_BSSS
);
2940 * wpas_dbus_register_bss - Register a scanned BSS with dbus
2941 * @wpa_s: wpa_supplicant interface structure
2942 * @bssid: scanned network bssid
2943 * @id: unique BSS identifier
2944 * Returns: 0 on success, -1 on failure
2946 * Registers BSS representing object with dbus
2948 int wpas_dbus_register_bss(struct wpa_supplicant
*wpa_s
,
2949 u8 bssid
[ETH_ALEN
], unsigned int id
)
2951 struct wpas_dbus_priv
*ctrl_iface
;
2952 struct wpa_dbus_object_desc
*obj_desc
;
2953 char bss_obj_path
[WPAS_DBUS_OBJECT_PATH_MAX
];
2954 struct bss_handler_args
*arg
;
2956 /* Do nothing if the control interface is not turned on */
2957 if (wpa_s
== NULL
|| wpa_s
->global
== NULL
|| !wpa_s
->dbus_new_path
)
2959 ctrl_iface
= wpa_s
->global
->dbus
;
2960 if (ctrl_iface
== NULL
)
2963 os_snprintf(bss_obj_path
, WPAS_DBUS_OBJECT_PATH_MAX
,
2964 "%s/" WPAS_DBUS_NEW_BSSIDS_PART
"/%u",
2965 wpa_s
->dbus_new_path
, id
);
2967 obj_desc
= os_zalloc(sizeof(struct wpa_dbus_object_desc
));
2969 wpa_printf(MSG_ERROR
,
2970 "Not enough memory to create object description");
2974 arg
= os_zalloc(sizeof(struct bss_handler_args
));
2976 wpa_printf(MSG_ERROR
,
2977 "Not enough memory to create arguments for handler");
2983 wpas_dbus_register(obj_desc
, arg
, wpa_dbus_free
, NULL
,
2984 wpas_dbus_bss_properties
,
2985 wpas_dbus_bss_signals
);
2987 wpa_printf(MSG_DEBUG
, "dbus: Register BSS object '%s'",
2989 if (wpa_dbus_register_object_per_iface(ctrl_iface
, bss_obj_path
,
2990 wpa_s
->ifname
, obj_desc
)) {
2991 wpa_printf(MSG_ERROR
,
2992 "Cannot register BSSID dbus object %s.",
2997 wpas_dbus_signal_bss_added(wpa_s
, bss_obj_path
);
2998 wpas_dbus_signal_prop_changed(wpa_s
, WPAS_DBUS_PROP_BSSS
);
3003 free_dbus_object_desc(obj_desc
);
3008 static const struct wpa_dbus_property_desc wpas_dbus_sta_properties
[] = {
3009 { "Address", WPAS_DBUS_NEW_IFACE_STA
, "ay",
3010 wpas_dbus_getter_sta_address
,
3013 { "AID", WPAS_DBUS_NEW_IFACE_STA
, "q",
3014 wpas_dbus_getter_sta_aid
,
3017 { "Capabilities", WPAS_DBUS_NEW_IFACE_STA
, "q",
3018 wpas_dbus_getter_sta_caps
,
3021 { "RxPackets", WPAS_DBUS_NEW_IFACE_STA
, "t",
3022 wpas_dbus_getter_sta_rx_packets
,
3025 { "TxPackets", WPAS_DBUS_NEW_IFACE_STA
, "t",
3026 wpas_dbus_getter_sta_tx_packets
,
3029 { "RxBytes", WPAS_DBUS_NEW_IFACE_STA
, "t",
3030 wpas_dbus_getter_sta_rx_bytes
,
3033 { "TxBytes", WPAS_DBUS_NEW_IFACE_STA
, "t",
3034 wpas_dbus_getter_sta_tx_bytes
,
3037 { NULL
, NULL
, NULL
, NULL
, NULL
, NULL
}
3041 static const struct wpa_dbus_signal_desc wpas_dbus_sta_signals
[] = {
3042 /* Deprecated: use org.freedesktop.DBus.Properties.PropertiesChanged */
3043 { "PropertiesChanged", WPAS_DBUS_NEW_IFACE_STA
,
3045 { "properties", "a{sv}", ARG_OUT
},
3049 { NULL
, NULL
, { END_ARGS
} }
3054 * wpas_dbus_unregister_sta - Unregister a connected station from dbus
3055 * @wpa_s: wpa_supplicant interface structure
3056 * @sta: station MAC address
3057 * Returns: 0 on success, -1 on failure
3059 * Unregisters STA representing object from dbus.
3061 int wpas_dbus_unregister_sta(struct wpa_supplicant
*wpa_s
, const u8
*sta
)
3063 struct wpas_dbus_priv
*ctrl_iface
;
3064 char station_obj_path
[WPAS_DBUS_OBJECT_PATH_MAX
];
3066 /* Do nothing if the control interface is not turned on */
3067 if (!wpa_s
|| !wpa_s
->global
)
3069 ctrl_iface
= wpa_s
->global
->dbus
;
3073 os_snprintf(station_obj_path
, WPAS_DBUS_OBJECT_PATH_MAX
,
3074 "%s/" WPAS_DBUS_NEW_STAS_PART
"/" COMPACT_MACSTR
,
3075 wpa_s
->dbus_new_path
, MAC2STR(sta
));
3077 wpa_printf(MSG_DEBUG
, "dbus: Unregister STA object '%s'",
3079 if (wpa_dbus_unregister_object_per_iface(ctrl_iface
,
3080 station_obj_path
)) {
3081 wpa_printf(MSG_ERROR
, "dbus: Cannot unregister STA object %s",
3086 wpas_dbus_signal_station_removed(wpa_s
, station_obj_path
);
3087 wpas_dbus_signal_prop_changed(wpa_s
, WPAS_DBUS_PROP_STATIONS
);
3094 * wpas_dbus_register_sta - Register a connected station with dbus
3095 * @wpa_s: wpa_supplicant interface structure
3096 * @sta: station MAC address
3097 * Returns: 0 on success, -1 on failure
3099 * Registers STA representing object with dbus.
3101 int wpas_dbus_register_sta(struct wpa_supplicant
*wpa_s
, const u8
*sta
)
3103 struct wpas_dbus_priv
*ctrl_iface
;
3104 struct wpa_dbus_object_desc
*obj_desc
;
3105 char station_obj_path
[WPAS_DBUS_OBJECT_PATH_MAX
];
3106 struct sta_handler_args
*arg
;
3108 /* Do nothing if the control interface is not turned on */
3109 if (!wpa_s
|| !wpa_s
->global
)
3111 ctrl_iface
= wpa_s
->global
->dbus
;
3115 os_snprintf(station_obj_path
, WPAS_DBUS_OBJECT_PATH_MAX
,
3116 "%s/" WPAS_DBUS_NEW_STAS_PART
"/" COMPACT_MACSTR
,
3117 wpa_s
->dbus_new_path
, MAC2STR(sta
));
3119 obj_desc
= os_zalloc(sizeof(struct wpa_dbus_object_desc
));
3121 wpa_printf(MSG_ERROR
,
3122 "Not enough memory to create object description");
3126 arg
= os_zalloc(sizeof(struct sta_handler_args
));
3128 wpa_printf(MSG_ERROR
,
3129 "Not enough memory to create arguments for handler");
3135 wpas_dbus_register(obj_desc
, arg
, wpa_dbus_free
, NULL
,
3136 wpas_dbus_sta_properties
, wpas_dbus_sta_signals
);
3138 wpa_printf(MSG_DEBUG
, "dbus: Register STA object '%s'",
3140 if (wpa_dbus_register_object_per_iface(ctrl_iface
, station_obj_path
,
3141 wpa_s
->ifname
, obj_desc
)) {
3142 wpa_printf(MSG_ERROR
,
3143 "Cannot register STA dbus object %s",
3148 wpas_dbus_signal_station_added(wpa_s
, station_obj_path
);
3149 wpas_dbus_signal_prop_changed(wpa_s
, WPAS_DBUS_PROP_STATIONS
);
3154 free_dbus_object_desc(obj_desc
);
3159 static const struct wpa_dbus_method_desc wpas_dbus_interface_methods
[] = {
3160 { "Scan", WPAS_DBUS_NEW_IFACE_INTERFACE
,
3161 (WPADBusMethodHandler
) wpas_dbus_handler_scan
,
3163 { "args", "a{sv}", ARG_IN
},
3167 { "SignalPoll", WPAS_DBUS_NEW_IFACE_INTERFACE
,
3168 (WPADBusMethodHandler
) wpas_dbus_handler_signal_poll
,
3170 { "args", "a{sv}", ARG_OUT
},
3174 { "Disconnect", WPAS_DBUS_NEW_IFACE_INTERFACE
,
3175 (WPADBusMethodHandler
) wpas_dbus_handler_disconnect
,
3180 { "AddNetwork", WPAS_DBUS_NEW_IFACE_INTERFACE
,
3181 (WPADBusMethodHandler
) wpas_dbus_handler_add_network
,
3183 { "args", "a{sv}", ARG_IN
},
3184 { "path", "o", ARG_OUT
},
3188 { "Reassociate", WPAS_DBUS_NEW_IFACE_INTERFACE
,
3189 (WPADBusMethodHandler
) wpas_dbus_handler_reassociate
,
3194 { "Reattach", WPAS_DBUS_NEW_IFACE_INTERFACE
,
3195 (WPADBusMethodHandler
) wpas_dbus_handler_reattach
,
3200 { "Reconnect", WPAS_DBUS_NEW_IFACE_INTERFACE
,
3201 (WPADBusMethodHandler
) wpas_dbus_handler_reconnect
,
3206 { "RemoveNetwork", WPAS_DBUS_NEW_IFACE_INTERFACE
,
3207 (WPADBusMethodHandler
) wpas_dbus_handler_remove_network
,
3209 { "path", "o", ARG_IN
},
3213 { "RemoveAllNetworks", WPAS_DBUS_NEW_IFACE_INTERFACE
,
3214 (WPADBusMethodHandler
) wpas_dbus_handler_remove_all_networks
,
3219 { "SelectNetwork", WPAS_DBUS_NEW_IFACE_INTERFACE
,
3220 (WPADBusMethodHandler
) wpas_dbus_handler_select_network
,
3222 { "path", "o", ARG_IN
},
3226 { "NetworkReply", WPAS_DBUS_NEW_IFACE_INTERFACE
,
3227 (WPADBusMethodHandler
) wpas_dbus_handler_network_reply
,
3229 { "path", "o", ARG_IN
},
3230 { "field", "s", ARG_IN
},
3231 { "value", "s", ARG_IN
},
3235 #ifndef CONFIG_NO_CONFIG_BLOBS
3236 { "AddBlob", WPAS_DBUS_NEW_IFACE_INTERFACE
,
3237 (WPADBusMethodHandler
) wpas_dbus_handler_add_blob
,
3239 { "name", "s", ARG_IN
},
3240 { "data", "ay", ARG_IN
},
3244 { "GetBlob", WPAS_DBUS_NEW_IFACE_INTERFACE
,
3245 (WPADBusMethodHandler
) wpas_dbus_handler_get_blob
,
3247 { "name", "s", ARG_IN
},
3248 { "data", "ay", ARG_OUT
},
3252 { "RemoveBlob", WPAS_DBUS_NEW_IFACE_INTERFACE
,
3253 (WPADBusMethodHandler
) wpas_dbus_handler_remove_blob
,
3255 { "name", "s", ARG_IN
},
3259 #endif /* CONFIG_NO_CONFIG_BLOBS */
3260 { "SetPKCS11EngineAndModulePath", WPAS_DBUS_NEW_IFACE_INTERFACE
,
3261 (WPADBusMethodHandler
)
3262 wpas_dbus_handler_set_pkcs11_engine_and_module_path
,
3264 { "pkcs11_engine_path", "s", ARG_IN
},
3265 { "pkcs11_module_path", "s", ARG_IN
},
3270 { "Start", WPAS_DBUS_NEW_IFACE_WPS
,
3271 (WPADBusMethodHandler
) wpas_dbus_handler_wps_start
,
3273 { "args", "a{sv}", ARG_IN
},
3274 { "output", "a{sv}", ARG_OUT
},
3278 { "Cancel", WPAS_DBUS_NEW_IFACE_WPS
,
3279 (WPADBusMethodHandler
) wpas_dbus_handler_wps_cancel
,
3284 #endif /* CONFIG_WPS */
3286 { "Find", WPAS_DBUS_NEW_IFACE_P2PDEVICE
,
3287 (WPADBusMethodHandler
) wpas_dbus_handler_p2p_find
,
3289 { "args", "a{sv}", ARG_IN
},
3293 { "StopFind", WPAS_DBUS_NEW_IFACE_P2PDEVICE
,
3294 (WPADBusMethodHandler
) wpas_dbus_handler_p2p_stop_find
,
3299 { "Listen", WPAS_DBUS_NEW_IFACE_P2PDEVICE
,
3300 (WPADBusMethodHandler
) wpas_dbus_handler_p2p_listen
,
3302 { "timeout", "i", ARG_IN
},
3306 { "ExtendedListen", WPAS_DBUS_NEW_IFACE_P2PDEVICE
,
3307 (WPADBusMethodHandler
) wpas_dbus_handler_p2p_extendedlisten
,
3309 { "args", "a{sv}", ARG_IN
},
3313 { "PresenceRequest", WPAS_DBUS_NEW_IFACE_P2PDEVICE
,
3314 (WPADBusMethodHandler
) wpas_dbus_handler_p2p_presence_request
,
3316 { "args", "a{sv}", ARG_IN
},
3320 { "ProvisionDiscoveryRequest", WPAS_DBUS_NEW_IFACE_P2PDEVICE
,
3321 (WPADBusMethodHandler
) wpas_dbus_handler_p2p_prov_disc_req
,
3323 { "peer", "o", ARG_IN
},
3324 { "config_method", "s", ARG_IN
},
3328 { "Connect", WPAS_DBUS_NEW_IFACE_P2PDEVICE
,
3329 (WPADBusMethodHandler
) wpas_dbus_handler_p2p_connect
,
3331 { "args", "a{sv}", ARG_IN
},
3332 { "generated_pin", "s", ARG_OUT
},
3336 { "GroupAdd", WPAS_DBUS_NEW_IFACE_P2PDEVICE
,
3337 (WPADBusMethodHandler
) wpas_dbus_handler_p2p_group_add
,
3339 { "args", "a{sv}", ARG_IN
},
3343 { "Cancel", WPAS_DBUS_NEW_IFACE_P2PDEVICE
,
3344 (WPADBusMethodHandler
) wpas_dbus_handler_p2p_cancel
,
3349 { "Invite", WPAS_DBUS_NEW_IFACE_P2PDEVICE
,
3350 (WPADBusMethodHandler
) wpas_dbus_handler_p2p_invite
,
3352 { "args", "a{sv}", ARG_IN
},
3356 { "Disconnect", WPAS_DBUS_NEW_IFACE_P2PDEVICE
,
3357 (WPADBusMethodHandler
) wpas_dbus_handler_p2p_disconnect
,
3362 { "RejectPeer", WPAS_DBUS_NEW_IFACE_P2PDEVICE
,
3363 (WPADBusMethodHandler
) wpas_dbus_handler_p2p_rejectpeer
,
3365 { "peer", "o", ARG_IN
},
3369 { "RemoveClient", WPAS_DBUS_NEW_IFACE_P2PDEVICE
,
3370 (WPADBusMethodHandler
) wpas_dbus_handler_p2p_remove_client
,
3372 { "args", "a{sv}", ARG_IN
},
3376 { "Flush", WPAS_DBUS_NEW_IFACE_P2PDEVICE
,
3377 (WPADBusMethodHandler
) wpas_dbus_handler_p2p_flush
,
3382 { "AddService", WPAS_DBUS_NEW_IFACE_P2PDEVICE
,
3383 (WPADBusMethodHandler
) wpas_dbus_handler_p2p_add_service
,
3385 { "args", "a{sv}", ARG_IN
},
3389 { "DeleteService", WPAS_DBUS_NEW_IFACE_P2PDEVICE
,
3390 (WPADBusMethodHandler
) wpas_dbus_handler_p2p_delete_service
,
3392 { "args", "a{sv}", ARG_IN
},
3396 { "FlushService", WPAS_DBUS_NEW_IFACE_P2PDEVICE
,
3397 (WPADBusMethodHandler
) wpas_dbus_handler_p2p_flush_service
,
3402 { "ServiceDiscoveryRequest", WPAS_DBUS_NEW_IFACE_P2PDEVICE
,
3403 (WPADBusMethodHandler
) wpas_dbus_handler_p2p_service_sd_req
,
3405 { "args", "a{sv}", ARG_IN
},
3406 { "ref", "t", ARG_OUT
},
3410 { "ServiceDiscoveryResponse", WPAS_DBUS_NEW_IFACE_P2PDEVICE
,
3411 (WPADBusMethodHandler
) wpas_dbus_handler_p2p_service_sd_res
,
3413 { "args", "a{sv}", ARG_IN
},
3417 { "ServiceDiscoveryCancelRequest", WPAS_DBUS_NEW_IFACE_P2PDEVICE
,
3418 (WPADBusMethodHandler
) wpas_dbus_handler_p2p_service_sd_cancel_req
,
3420 { "args", "t", ARG_IN
},
3424 { "ServiceUpdate", WPAS_DBUS_NEW_IFACE_P2PDEVICE
,
3425 (WPADBusMethodHandler
) wpas_dbus_handler_p2p_service_update
,
3430 { "ServiceDiscoveryExternal", WPAS_DBUS_NEW_IFACE_P2PDEVICE
,
3431 (WPADBusMethodHandler
) wpas_dbus_handler_p2p_serv_disc_external
,
3433 { "arg", "i", ARG_IN
},
3437 { "AddPersistentGroup", WPAS_DBUS_NEW_IFACE_P2PDEVICE
,
3438 (WPADBusMethodHandler
) wpas_dbus_handler_add_persistent_group
,
3440 { "args", "a{sv}", ARG_IN
},
3441 { "path", "o", ARG_OUT
},
3445 { "RemovePersistentGroup", WPAS_DBUS_NEW_IFACE_P2PDEVICE
,
3446 (WPADBusMethodHandler
) wpas_dbus_handler_remove_persistent_group
,
3448 { "path", "o", ARG_IN
},
3452 { "RemoveAllPersistentGroups", WPAS_DBUS_NEW_IFACE_P2PDEVICE
,
3453 (WPADBusMethodHandler
)
3454 wpas_dbus_handler_remove_all_persistent_groups
,
3459 #endif /* CONFIG_P2P */
3460 { "FlushBSS", WPAS_DBUS_NEW_IFACE_INTERFACE
,
3461 (WPADBusMethodHandler
) wpas_dbus_handler_flush_bss
,
3463 { "age", "u", ARG_IN
},
3468 { "SubscribeProbeReq", WPAS_DBUS_NEW_IFACE_INTERFACE
,
3469 (WPADBusMethodHandler
) wpas_dbus_handler_subscribe_preq
,
3474 { "UnsubscribeProbeReq", WPAS_DBUS_NEW_IFACE_INTERFACE
,
3475 (WPADBusMethodHandler
) wpas_dbus_handler_unsubscribe_preq
,
3480 #endif /* CONFIG_AP */
3481 { "EAPLogoff", WPAS_DBUS_NEW_IFACE_INTERFACE
,
3482 (WPADBusMethodHandler
) wpas_dbus_handler_eap_logoff
,
3487 { "EAPLogon", WPAS_DBUS_NEW_IFACE_INTERFACE
,
3488 (WPADBusMethodHandler
) wpas_dbus_handler_eap_logon
,
3493 #ifdef CONFIG_AUTOSCAN
3494 { "AutoScan", WPAS_DBUS_NEW_IFACE_INTERFACE
,
3495 (WPADBusMethodHandler
) wpas_dbus_handler_autoscan
,
3497 { "arg", "s", ARG_IN
},
3501 #endif /* CONFIG_AUTOSCAN */
3503 { "TDLSDiscover", WPAS_DBUS_NEW_IFACE_INTERFACE
,
3504 (WPADBusMethodHandler
) wpas_dbus_handler_tdls_discover
,
3506 { "peer_address", "s", ARG_IN
},
3510 { "TDLSSetup", WPAS_DBUS_NEW_IFACE_INTERFACE
,
3511 (WPADBusMethodHandler
) wpas_dbus_handler_tdls_setup
,
3513 { "peer_address", "s", ARG_IN
},
3517 { "TDLSStatus", WPAS_DBUS_NEW_IFACE_INTERFACE
,
3518 (WPADBusMethodHandler
) wpas_dbus_handler_tdls_status
,
3520 { "peer_address", "s", ARG_IN
},
3521 { "status", "s", ARG_OUT
},
3525 { "TDLSTeardown", WPAS_DBUS_NEW_IFACE_INTERFACE
,
3526 (WPADBusMethodHandler
) wpas_dbus_handler_tdls_teardown
,
3528 { "peer_address", "s", ARG_IN
},
3532 { "TDLSChannelSwitch", WPAS_DBUS_NEW_IFACE_INTERFACE
,
3533 (WPADBusMethodHandler
) wpas_dbus_handler_tdls_channel_switch
,
3535 { "args", "a{sv}", ARG_IN
},
3539 { "TDLSCancelChannelSwitch", WPAS_DBUS_NEW_IFACE_INTERFACE
,
3540 (WPADBusMethodHandler
) wpas_dbus_handler_tdls_cancel_channel_switch
,
3542 { "peer_address", "s", ARG_IN
},
3546 #endif /* CONFIG_TDLS */
3547 { "VendorElemAdd", WPAS_DBUS_NEW_IFACE_INTERFACE
,
3548 (WPADBusMethodHandler
) wpas_dbus_handler_vendor_elem_add
,
3550 { "frame_id", "i", ARG_IN
},
3551 { "ielems", "ay", ARG_IN
},
3555 { "VendorElemGet", WPAS_DBUS_NEW_IFACE_INTERFACE
,
3556 (WPADBusMethodHandler
) wpas_dbus_handler_vendor_elem_get
,
3558 { "frame_id", "i", ARG_IN
},
3559 { "ielems", "ay", ARG_OUT
},
3563 { "VendorElemRem", WPAS_DBUS_NEW_IFACE_INTERFACE
,
3564 (WPADBusMethodHandler
) wpas_dbus_handler_vendor_elem_remove
,
3566 { "frame_id", "i", ARG_IN
},
3567 { "ielems", "ay", ARG_IN
},
3571 #ifndef CONFIG_NO_CONFIG_WRITE
3572 { "SaveConfig", WPAS_DBUS_NEW_IFACE_INTERFACE
,
3573 (WPADBusMethodHandler
) wpas_dbus_handler_save_config
,
3578 #endif /* CONFIG_NO_CONFIG_WRITE */
3579 { "AbortScan", WPAS_DBUS_NEW_IFACE_INTERFACE
,
3580 (WPADBusMethodHandler
) wpas_dbus_handler_abort_scan
,
3585 { NULL
, NULL
, NULL
, { END_ARGS
} }
3588 static const struct wpa_dbus_property_desc wpas_dbus_interface_properties
[] = {
3589 { "Capabilities", WPAS_DBUS_NEW_IFACE_INTERFACE
, "a{sv}",
3590 wpas_dbus_getter_capabilities
,
3594 { "State", WPAS_DBUS_NEW_IFACE_INTERFACE
, "s",
3595 wpas_dbus_getter_state
,
3599 { "Scanning", WPAS_DBUS_NEW_IFACE_INTERFACE
, "b",
3600 wpas_dbus_getter_scanning
,
3604 { "ApScan", WPAS_DBUS_NEW_IFACE_INTERFACE
, "u",
3605 wpas_dbus_getter_ap_scan
,
3606 wpas_dbus_setter_ap_scan
,
3609 { "BSSExpireAge", WPAS_DBUS_NEW_IFACE_INTERFACE
, "u",
3610 wpas_dbus_getter_bss_expire_age
,
3611 wpas_dbus_setter_bss_expire_age
,
3614 { "BSSExpireCount", WPAS_DBUS_NEW_IFACE_INTERFACE
, "u",
3615 wpas_dbus_getter_bss_expire_count
,
3616 wpas_dbus_setter_bss_expire_count
,
3619 { "Country", WPAS_DBUS_NEW_IFACE_INTERFACE
, "s",
3620 wpas_dbus_getter_country
,
3621 wpas_dbus_setter_country
,
3624 { "Ifname", WPAS_DBUS_NEW_IFACE_INTERFACE
, "s",
3625 wpas_dbus_getter_ifname
,
3629 { "Driver", WPAS_DBUS_NEW_IFACE_INTERFACE
, "s",
3630 wpas_dbus_getter_driver
,
3634 { "BridgeIfname", WPAS_DBUS_NEW_IFACE_INTERFACE
, "s",
3635 wpas_dbus_getter_bridge_ifname
,
3639 { "ConfigFile", WPAS_DBUS_NEW_IFACE_INTERFACE
, "s",
3640 wpas_dbus_getter_config_file
,
3644 { "CurrentBSS", WPAS_DBUS_NEW_IFACE_INTERFACE
, "o",
3645 wpas_dbus_getter_current_bss
,
3649 { "CurrentNetwork", WPAS_DBUS_NEW_IFACE_INTERFACE
, "o",
3650 wpas_dbus_getter_current_network
,
3654 { "CurrentAuthMode", WPAS_DBUS_NEW_IFACE_INTERFACE
, "s",
3655 wpas_dbus_getter_current_auth_mode
,
3659 { "Blobs", WPAS_DBUS_NEW_IFACE_INTERFACE
, "a{say}",
3660 wpas_dbus_getter_blobs
,
3664 { "BSSs", WPAS_DBUS_NEW_IFACE_INTERFACE
, "ao",
3665 wpas_dbus_getter_bsss
,
3669 { "Networks", WPAS_DBUS_NEW_IFACE_INTERFACE
, "ao",
3670 wpas_dbus_getter_networks
,
3674 { "FastReauth", WPAS_DBUS_NEW_IFACE_INTERFACE
, "b",
3675 wpas_dbus_getter_fast_reauth
,
3676 wpas_dbus_setter_fast_reauth
,
3679 { "ScanInterval", WPAS_DBUS_NEW_IFACE_INTERFACE
, "i",
3680 wpas_dbus_getter_scan_interval
,
3681 wpas_dbus_setter_scan_interval
,
3684 { "PKCS11EnginePath", WPAS_DBUS_NEW_IFACE_INTERFACE
, "s",
3685 wpas_dbus_getter_pkcs11_engine_path
,
3689 { "PKCS11ModulePath", WPAS_DBUS_NEW_IFACE_INTERFACE
, "s",
3690 wpas_dbus_getter_pkcs11_module_path
,
3695 { "ProcessCredentials", WPAS_DBUS_NEW_IFACE_WPS
, "b",
3696 wpas_dbus_getter_process_credentials
,
3697 wpas_dbus_setter_process_credentials
,
3700 { "ConfigMethods", WPAS_DBUS_NEW_IFACE_WPS
, "s",
3701 wpas_dbus_getter_config_methods
,
3702 wpas_dbus_setter_config_methods
,
3706 "DeviceName", WPAS_DBUS_NEW_IFACE_WPS
, "s",
3707 wpas_dbus_getter_wps_device_name
,
3708 wpas_dbus_setter_wps_device_name
,
3712 "Manufacturer", WPAS_DBUS_NEW_IFACE_WPS
, "s",
3713 wpas_dbus_getter_wps_manufacturer
,
3714 wpas_dbus_setter_wps_manufacturer
,
3718 "ModelName", WPAS_DBUS_NEW_IFACE_WPS
, "s",
3719 wpas_dbus_getter_wps_device_model_name
,
3720 wpas_dbus_setter_wps_device_model_name
,
3724 "ModelNumber", WPAS_DBUS_NEW_IFACE_WPS
, "s",
3725 wpas_dbus_getter_wps_device_model_number
,
3726 wpas_dbus_setter_wps_device_model_number
,
3730 "SerialNumber", WPAS_DBUS_NEW_IFACE_WPS
, "s",
3731 wpas_dbus_getter_wps_device_serial_number
,
3732 wpas_dbus_setter_wps_device_serial_number
,
3736 "DeviceType", WPAS_DBUS_NEW_IFACE_WPS
, "ay",
3737 wpas_dbus_getter_wps_device_device_type
,
3738 wpas_dbus_setter_wps_device_device_type
,
3741 #endif /* CONFIG_WPS */
3743 { "P2PDeviceConfig", WPAS_DBUS_NEW_IFACE_P2PDEVICE
, "a{sv}",
3744 wpas_dbus_getter_p2p_device_config
,
3745 wpas_dbus_setter_p2p_device_config
,
3748 { "Peers", WPAS_DBUS_NEW_IFACE_P2PDEVICE
, "ao",
3749 wpas_dbus_getter_p2p_peers
,
3753 { "Role", WPAS_DBUS_NEW_IFACE_P2PDEVICE
, "s",
3754 wpas_dbus_getter_p2p_role
,
3758 { "Group", WPAS_DBUS_NEW_IFACE_P2PDEVICE
, "o",
3759 wpas_dbus_getter_p2p_group
,
3763 { "PeerGO", WPAS_DBUS_NEW_IFACE_P2PDEVICE
, "o",
3764 wpas_dbus_getter_p2p_peergo
,
3768 { "PersistentGroups", WPAS_DBUS_NEW_IFACE_P2PDEVICE
, "ao",
3769 wpas_dbus_getter_persistent_groups
,
3773 #endif /* CONFIG_P2P */
3774 { "DisconnectReason", WPAS_DBUS_NEW_IFACE_INTERFACE
, "i",
3775 wpas_dbus_getter_disconnect_reason
,
3779 { "AuthStatusCode", WPAS_DBUS_NEW_IFACE_INTERFACE
, "i",
3780 wpas_dbus_getter_auth_status_code
,
3784 { "AssocStatusCode", WPAS_DBUS_NEW_IFACE_INTERFACE
, "i",
3785 wpas_dbus_getter_assoc_status_code
,
3790 { "MeshPeers", WPAS_DBUS_NEW_IFACE_MESH
, "aay",
3791 wpas_dbus_getter_mesh_peers
,
3795 { "MeshGroup", WPAS_DBUS_NEW_IFACE_MESH
, "ay",
3796 wpas_dbus_getter_mesh_group
,
3800 #endif /* CONFIG_MESH */
3801 { "Stations", WPAS_DBUS_NEW_IFACE_INTERFACE
, "ao",
3802 wpas_dbus_getter_stas
,
3806 { "MACAddressRandomizationMask", WPAS_DBUS_NEW_IFACE_INTERFACE
,
3808 wpas_dbus_getter_mac_address_randomization_mask
,
3809 wpas_dbus_setter_mac_address_randomization_mask
,
3812 { NULL
, NULL
, NULL
, NULL
, NULL
, NULL
}
3815 static const struct wpa_dbus_signal_desc wpas_dbus_interface_signals
[] = {
3816 { "ScanDone", WPAS_DBUS_NEW_IFACE_INTERFACE
,
3818 { "success", "b", ARG_OUT
},
3822 { "BSSAdded", WPAS_DBUS_NEW_IFACE_INTERFACE
,
3824 { "path", "o", ARG_OUT
},
3825 { "properties", "a{sv}", ARG_OUT
},
3829 { "BSSRemoved", WPAS_DBUS_NEW_IFACE_INTERFACE
,
3831 { "path", "o", ARG_OUT
},
3835 { "BlobAdded", WPAS_DBUS_NEW_IFACE_INTERFACE
,
3837 { "name", "s", ARG_OUT
},
3841 { "BlobRemoved", WPAS_DBUS_NEW_IFACE_INTERFACE
,
3843 { "name", "s", ARG_OUT
},
3847 { "NetworkAdded", WPAS_DBUS_NEW_IFACE_INTERFACE
,
3849 { "path", "o", ARG_OUT
},
3850 { "properties", "a{sv}", ARG_OUT
},
3854 { "NetworkRemoved", WPAS_DBUS_NEW_IFACE_INTERFACE
,
3856 { "path", "o", ARG_OUT
},
3860 { "NetworkSelected", WPAS_DBUS_NEW_IFACE_INTERFACE
,
3862 { "path", "o", ARG_OUT
},
3866 /* Deprecated: use org.freedesktop.DBus.Properties.PropertiesChanged */
3867 { "PropertiesChanged", WPAS_DBUS_NEW_IFACE_INTERFACE
,
3869 { "properties", "a{sv}", ARG_OUT
},
3874 { "Event", WPAS_DBUS_NEW_IFACE_WPS
,
3876 { "name", "s", ARG_OUT
},
3877 { "args", "a{sv}", ARG_OUT
},
3881 { "Credentials", WPAS_DBUS_NEW_IFACE_WPS
,
3883 { "credentials", "a{sv}", ARG_OUT
},
3887 /* Deprecated: use org.freedesktop.DBus.Properties.PropertiesChanged */
3888 { "PropertiesChanged", WPAS_DBUS_NEW_IFACE_WPS
,
3890 { "properties", "a{sv}", ARG_OUT
},
3894 #endif /* CONFIG_WPS */
3896 { "DeviceFound", WPAS_DBUS_NEW_IFACE_P2PDEVICE
,
3898 { "path", "o", ARG_OUT
},
3902 { "DeviceFoundProperties", WPAS_DBUS_NEW_IFACE_P2PDEVICE
,
3904 { "path", "o", ARG_OUT
},
3905 { "properties", "a{sv}", ARG_OUT
},
3909 { "DeviceLost", WPAS_DBUS_NEW_IFACE_P2PDEVICE
,
3911 { "path", "o", ARG_OUT
},
3915 { "FindStopped", WPAS_DBUS_NEW_IFACE_P2PDEVICE
,
3920 { "ProvisionDiscoveryRequestDisplayPin", WPAS_DBUS_NEW_IFACE_P2PDEVICE
,
3922 { "peer_object", "o", ARG_OUT
},
3923 { "pin", "s", ARG_OUT
},
3927 { "ProvisionDiscoveryResponseDisplayPin", WPAS_DBUS_NEW_IFACE_P2PDEVICE
,
3929 { "peer_object", "o", ARG_OUT
},
3930 { "pin", "s", ARG_OUT
},
3934 { "ProvisionDiscoveryRequestEnterPin", WPAS_DBUS_NEW_IFACE_P2PDEVICE
,
3936 { "peer_object", "o", ARG_OUT
},
3940 { "ProvisionDiscoveryResponseEnterPin", WPAS_DBUS_NEW_IFACE_P2PDEVICE
,
3942 { "peer_object", "o", ARG_OUT
},
3946 { "ProvisionDiscoveryPBCRequest", WPAS_DBUS_NEW_IFACE_P2PDEVICE
,
3948 { "peer_object", "o", ARG_OUT
},
3952 { "ProvisionDiscoveryPBCResponse", WPAS_DBUS_NEW_IFACE_P2PDEVICE
,
3954 { "peer_object", "o", ARG_OUT
},
3958 { "ProvisionDiscoveryFailure", WPAS_DBUS_NEW_IFACE_P2PDEVICE
,
3960 { "peer_object", "o", ARG_OUT
},
3961 { "status", "i", ARG_OUT
},
3965 { "GroupStarted", WPAS_DBUS_NEW_IFACE_P2PDEVICE
,
3967 { "properties", "a{sv}", ARG_OUT
},
3971 { "GroupFormationFailure", WPAS_DBUS_NEW_IFACE_P2PDEVICE
,
3973 { "reason", "s", ARG_OUT
},
3977 { "GONegotiationSuccess", WPAS_DBUS_NEW_IFACE_P2PDEVICE
,
3979 { "properties", "a{sv}", ARG_OUT
},
3983 { "GONegotiationFailure", WPAS_DBUS_NEW_IFACE_P2PDEVICE
,
3985 { "properties", "a{sv}", ARG_OUT
},
3989 { "GONegotiationRequest", WPAS_DBUS_NEW_IFACE_P2PDEVICE
,
3991 { "path", "o", ARG_OUT
},
3992 { "dev_passwd_id", "q", ARG_OUT
},
3993 { "device_go_intent", "y", ARG_OUT
},
3997 { "InvitationResult", WPAS_DBUS_NEW_IFACE_P2PDEVICE
,
3999 { "invite_result", "a{sv}", ARG_OUT
},
4003 { "GroupFinished", WPAS_DBUS_NEW_IFACE_P2PDEVICE
,
4005 { "properties", "a{sv}", ARG_OUT
},
4009 { "ServiceDiscoveryRequest", WPAS_DBUS_NEW_IFACE_P2PDEVICE
,
4011 { "sd_request", "a{sv}", ARG_OUT
},
4015 { "ServiceDiscoveryResponse", WPAS_DBUS_NEW_IFACE_P2PDEVICE
,
4017 { "sd_response", "a{sv}", ARG_OUT
},
4021 { "PersistentGroupAdded", WPAS_DBUS_NEW_IFACE_P2PDEVICE
,
4023 { "path", "o", ARG_OUT
},
4024 { "properties", "a{sv}", ARG_OUT
},
4028 { "PersistentGroupRemoved", WPAS_DBUS_NEW_IFACE_P2PDEVICE
,
4030 { "path", "o", ARG_OUT
},
4034 { "WpsFailed", WPAS_DBUS_NEW_IFACE_P2PDEVICE
,
4036 { "name", "s", ARG_OUT
},
4037 { "args", "a{sv}", ARG_OUT
},
4041 { "InvitationReceived", WPAS_DBUS_NEW_IFACE_P2PDEVICE
,
4043 { "properties", "a{sv}", ARG_OUT
},
4047 #endif /* CONFIG_P2P */
4049 { "ProbeRequest", WPAS_DBUS_NEW_IFACE_INTERFACE
,
4051 { "args", "a{sv}", ARG_OUT
},
4055 #endif /* CONFIG_AP */
4056 { "Certification", WPAS_DBUS_NEW_IFACE_INTERFACE
,
4058 { "certification", "a{sv}", ARG_OUT
},
4062 { "EAP", WPAS_DBUS_NEW_IFACE_INTERFACE
,
4064 { "status", "s", ARG_OUT
},
4065 { "parameter", "s", ARG_OUT
},
4069 { "StaAuthorized", WPAS_DBUS_NEW_IFACE_INTERFACE
,
4071 { "name", "s", ARG_OUT
},
4075 { "StaDeauthorized", WPAS_DBUS_NEW_IFACE_INTERFACE
,
4077 { "name", "s", ARG_OUT
},
4081 { "StationAdded", WPAS_DBUS_NEW_IFACE_INTERFACE
,
4083 { "path", "o", ARG_OUT
},
4084 { "properties", "a{sv}", ARG_OUT
},
4088 { "StationRemoved", WPAS_DBUS_NEW_IFACE_INTERFACE
,
4090 { "path", "o", ARG_OUT
},
4094 { "NetworkRequest", WPAS_DBUS_NEW_IFACE_INTERFACE
,
4096 { "path", "o", ARG_OUT
},
4097 { "field", "s", ARG_OUT
},
4098 { "text", "s", ARG_OUT
},
4103 { "MeshGroupStarted", WPAS_DBUS_NEW_IFACE_MESH
,
4105 { "args", "a{sv}", ARG_OUT
},
4109 { "MeshGroupRemoved", WPAS_DBUS_NEW_IFACE_MESH
,
4111 { "args", "a{sv}", ARG_OUT
},
4115 { "MeshPeerConnected", WPAS_DBUS_NEW_IFACE_MESH
,
4117 { "args", "a{sv}", ARG_OUT
},
4121 { "MeshPeerDisconnected", WPAS_DBUS_NEW_IFACE_MESH
,
4123 { "args", "a{sv}", ARG_OUT
},
4127 #endif /* CONFIG_MESH */
4128 { NULL
, NULL
, { END_ARGS
} }
4132 static int wpa_dbus_ctrl_iface_props_init(struct wpas_dbus_priv
*priv
)
4135 unsigned int i
, j
, count
, num_const
, num_globals
;
4136 const char *global_name
;
4137 static const char * const ignored_globals
[] = {
4138 "bss_expiration_age", "bss_expiration_scan_count",
4139 "ap_scan", "country", "fast_reauth",
4140 "pkcs11_engine_path", "pkcs11_module_path"
4143 /* wpas_dbus_interface_properties terminates with a NULL element */
4144 num_const
= ARRAY_SIZE(wpas_dbus_interface_properties
) - 1;
4146 num_globals
= wpa_config_get_num_global_field_names();
4147 priv
->globals_start
= num_const
;
4149 /* allocate enough for all properties + terminating NULL element */
4150 all_size
= (num_globals
+ num_const
+ 1) *
4151 sizeof(wpas_dbus_interface_properties
[0]);
4152 priv
->all_interface_properties
= os_zalloc(all_size
);
4153 if (!priv
->all_interface_properties
) {
4154 wpa_printf(MSG_ERROR
,
4155 "dbus: Not enough memory for interface properties");
4159 /* Copy constant interface properties to the start of the array */
4160 os_memcpy(priv
->all_interface_properties
,
4161 wpas_dbus_interface_properties
,
4162 sizeof(wpas_dbus_interface_properties
));
4164 /* Dynamically construct interface global properties */
4165 for (i
= 0, count
= num_const
; i
< num_globals
; i
++) {
4166 struct wpa_dbus_property_desc
*desc
;
4169 /* ignore globals that are actually just methods */
4170 global_name
= wpa_config_get_global_field_name(i
, &no_var
);
4173 /* Ignore fields already explicitly exposed */
4174 for (j
= 0; j
< ARRAY_SIZE(ignored_globals
); j
++) {
4175 if (os_strcmp(global_name
, ignored_globals
[j
]) == 0)
4178 if (j
< ARRAY_SIZE(ignored_globals
))
4181 desc
= &priv
->all_interface_properties
[count
++];
4182 desc
->dbus_property
= uscore_to_dbus(global_name
);
4183 if (!desc
->dbus_property
) {
4184 wpa_printf(MSG_ERROR
,
4185 "dbus: Not enough memory for D-Bus property name");
4188 desc
->dbus_interface
= WPAS_DBUS_NEW_IFACE_INTERFACE
;
4190 desc
->getter
= wpas_dbus_getter_iface_global
;
4191 desc
->setter
= wpas_dbus_setter_iface_global
;
4192 desc
->data
= global_name
;
4198 wpa_dbus_ctrl_iface_props_deinit(priv
);
4204 * wpas_dbus_register_interface - Register an interface with D-Bus
4205 * @wpa_s: wpa_supplicant interface structure
4206 * Returns: 0 on success, -1 on failure
4208 int wpas_dbus_register_interface(struct wpa_supplicant
*wpa_s
)
4210 struct wpa_dbus_object_desc
*obj_desc
= NULL
;
4211 struct wpas_dbus_priv
*ctrl_iface
= wpa_s
->global
->dbus
;
4214 /* Do nothing if the control interface is not turned on */
4215 if (ctrl_iface
== NULL
)
4218 /* Create and set the interface's object path */
4219 wpa_s
->dbus_new_path
= os_zalloc(WPAS_DBUS_OBJECT_PATH_MAX
);
4220 if (wpa_s
->dbus_new_path
== NULL
)
4222 next
= ctrl_iface
->next_objid
++;
4223 os_snprintf(wpa_s
->dbus_new_path
, WPAS_DBUS_OBJECT_PATH_MAX
,
4224 WPAS_DBUS_NEW_PATH_INTERFACES
"/%u",
4227 obj_desc
= os_zalloc(sizeof(struct wpa_dbus_object_desc
));
4229 wpa_printf(MSG_ERROR
,
4230 "Not enough memory to create object description");
4234 wpas_dbus_register(obj_desc
, wpa_s
, NULL
, wpas_dbus_interface_methods
,
4235 ctrl_iface
->all_interface_properties
,
4236 wpas_dbus_interface_signals
);
4238 wpa_printf(MSG_DEBUG
, "dbus: Register interface object '%s'",
4239 wpa_s
->dbus_new_path
);
4240 if (wpa_dbus_register_object_per_iface(ctrl_iface
,
4241 wpa_s
->dbus_new_path
,
4242 wpa_s
->ifname
, obj_desc
))
4245 wpas_dbus_signal_interface_added(wpa_s
);
4250 os_free(wpa_s
->dbus_new_path
);
4251 wpa_s
->dbus_new_path
= NULL
;
4252 free_dbus_object_desc(obj_desc
);
4258 * wpas_dbus_unregister_interface - Unregister the interface from D-Bus
4259 * @wpa_s: wpa_supplicant interface structure
4260 * Returns: 0 on success, -1 on failure
4262 int wpas_dbus_unregister_interface(struct wpa_supplicant
*wpa_s
)
4264 struct wpas_dbus_priv
*ctrl_iface
;
4266 /* Do nothing if the control interface is not turned on */
4267 if (wpa_s
== NULL
|| wpa_s
->global
== NULL
)
4269 ctrl_iface
= wpa_s
->global
->dbus
;
4270 if (ctrl_iface
== NULL
|| wpa_s
->dbus_new_path
== NULL
)
4273 wpa_printf(MSG_DEBUG
, "dbus: Unregister interface object '%s'",
4274 wpa_s
->dbus_new_path
);
4277 if (wpa_s
->preq_notify_peer
) {
4278 wpas_dbus_unsubscribe_noc(ctrl_iface
);
4279 os_free(wpa_s
->preq_notify_peer
);
4280 wpa_s
->preq_notify_peer
= NULL
;
4282 #endif /* CONFIG_AP */
4284 if (wpa_dbus_unregister_object_per_iface(ctrl_iface
,
4285 wpa_s
->dbus_new_path
))
4288 wpas_dbus_signal_interface_removed(wpa_s
);
4290 os_free(wpa_s
->dbus_new_path
);
4291 wpa_s
->dbus_new_path
= NULL
;
4298 static const struct wpa_dbus_property_desc wpas_dbus_p2p_peer_properties
[] = {
4299 { "DeviceName", WPAS_DBUS_NEW_IFACE_P2P_PEER
, "s",
4300 wpas_dbus_getter_p2p_peer_device_name
,
4304 { "Manufacturer", WPAS_DBUS_NEW_IFACE_P2P_PEER
, "s",
4305 wpas_dbus_getter_p2p_peer_manufacturer
,
4309 { "ModelName", WPAS_DBUS_NEW_IFACE_P2P_PEER
, "s",
4310 wpas_dbus_getter_p2p_peer_modelname
,
4314 { "ModelNumber", WPAS_DBUS_NEW_IFACE_P2P_PEER
, "s",
4315 wpas_dbus_getter_p2p_peer_modelnumber
,
4319 { "SerialNumber", WPAS_DBUS_NEW_IFACE_P2P_PEER
, "s",
4320 wpas_dbus_getter_p2p_peer_serialnumber
,
4324 { "PrimaryDeviceType", WPAS_DBUS_NEW_IFACE_P2P_PEER
, "ay",
4325 wpas_dbus_getter_p2p_peer_primary_device_type
,
4329 { "config_method", WPAS_DBUS_NEW_IFACE_P2P_PEER
, "q",
4330 wpas_dbus_getter_p2p_peer_config_method
,
4334 { "level", WPAS_DBUS_NEW_IFACE_P2P_PEER
, "i",
4335 wpas_dbus_getter_p2p_peer_level
,
4339 { "devicecapability", WPAS_DBUS_NEW_IFACE_P2P_PEER
, "y",
4340 wpas_dbus_getter_p2p_peer_device_capability
,
4344 { "groupcapability", WPAS_DBUS_NEW_IFACE_P2P_PEER
, "y",
4345 wpas_dbus_getter_p2p_peer_group_capability
,
4349 { "SecondaryDeviceTypes", WPAS_DBUS_NEW_IFACE_P2P_PEER
, "aay",
4350 wpas_dbus_getter_p2p_peer_secondary_device_types
,
4354 { "VendorExtension", WPAS_DBUS_NEW_IFACE_P2P_PEER
, "aay",
4355 wpas_dbus_getter_p2p_peer_vendor_extension
,
4359 { "IEs", WPAS_DBUS_NEW_IFACE_P2P_PEER
, "ay",
4360 wpas_dbus_getter_p2p_peer_ies
,
4364 { "DeviceAddress", WPAS_DBUS_NEW_IFACE_P2P_PEER
, "ay",
4365 wpas_dbus_getter_p2p_peer_device_address
,
4369 { "Groups", WPAS_DBUS_NEW_IFACE_P2P_PEER
, "ao",
4370 wpas_dbus_getter_p2p_peer_groups
,
4374 { "VSIE", WPAS_DBUS_NEW_IFACE_P2P_PEER
, "ay",
4375 wpas_dbus_getter_p2p_peer_vsie
,
4379 { NULL
, NULL
, NULL
, NULL
, NULL
, NULL
}
4382 static const struct wpa_dbus_signal_desc wpas_dbus_p2p_peer_signals
[] = {
4383 /* Deprecated: use org.freedesktop.DBus.Properties.PropertiesChanged */
4384 { "PropertiesChanged", WPAS_DBUS_NEW_IFACE_P2P_PEER
,
4386 { "properties", "a{sv}", ARG_OUT
},
4390 { NULL
, NULL
, { END_ARGS
} }
4394 * wpas_dbus_signal_peer - Send a peer related event signal
4395 * @wpa_s: %wpa_supplicant network interface data
4396 * @dev: peer device object
4397 * @interface: name of the interface emitting this signal.
4398 * In case of peer objects, it would be emitted by either
4399 * the "interface object" or by "peer objects"
4400 * @sig_name: signal name - DeviceFound
4401 * @properties: Whether to add a second argument with object properties
4403 * Notify listeners about event related with p2p peer device
4405 static void wpas_dbus_signal_peer(struct wpa_supplicant
*wpa_s
,
4406 const u8
*dev_addr
, const char *interface
,
4407 const char *sig_name
, dbus_bool_t properties
)
4409 struct wpas_dbus_priv
*iface
;
4411 DBusMessageIter iter
;
4412 char peer_obj_path
[WPAS_DBUS_OBJECT_PATH_MAX
], *path
;
4414 if (wpa_s
->p2p_mgmt
)
4415 wpa_s
= wpa_s
->parent
;
4417 iface
= wpa_s
->global
->dbus
;
4419 /* Do nothing if the control interface is not turned on */
4420 if (iface
== NULL
|| !wpa_s
->dbus_new_path
)
4423 os_snprintf(peer_obj_path
, WPAS_DBUS_OBJECT_PATH_MAX
,
4424 "%s/" WPAS_DBUS_NEW_P2P_PEERS_PART
"/" COMPACT_MACSTR
,
4425 wpa_s
->dbus_new_path
, MAC2STR(dev_addr
));
4427 msg
= dbus_message_new_signal(wpa_s
->dbus_new_path
, interface
,
4432 dbus_message_iter_init_append(msg
, &iter
);
4433 path
= peer_obj_path
;
4434 if (!dbus_message_iter_append_basic(&iter
, DBUS_TYPE_OBJECT_PATH
,
4436 (properties
&& !wpa_dbus_get_object_properties(
4437 iface
, peer_obj_path
, WPAS_DBUS_NEW_IFACE_P2P_PEER
,
4439 wpa_printf(MSG_ERROR
, "dbus: Failed to construct signal");
4441 dbus_connection_send(iface
->con
, msg
, NULL
);
4443 dbus_message_unref(msg
);
4448 * wpas_dbus_signal_peer_found - Send a peer found signal
4449 * @wpa_s: %wpa_supplicant network interface data
4450 * @dev_addr: Peer P2P Device Address
4452 * Notify listeners about find a p2p peer device found
4454 void wpas_dbus_signal_peer_device_found(struct wpa_supplicant
*wpa_s
,
4457 wpas_dbus_signal_peer(wpa_s
, dev_addr
,
4458 WPAS_DBUS_NEW_IFACE_P2PDEVICE
,
4459 "DeviceFound", FALSE
);
4461 wpas_dbus_signal_peer(wpa_s
, dev_addr
,
4462 WPAS_DBUS_NEW_IFACE_P2PDEVICE
,
4463 "DeviceFoundProperties", TRUE
);
4467 * wpas_dbus_signal_peer_lost - Send a peer lost signal
4468 * @wpa_s: %wpa_supplicant network interface data
4469 * @dev_addr: Peer P2P Device Address
4471 * Notify listeners about lost a p2p peer device
4473 void wpas_dbus_signal_peer_device_lost(struct wpa_supplicant
*wpa_s
,
4476 wpas_dbus_signal_peer(wpa_s
, dev_addr
,
4477 WPAS_DBUS_NEW_IFACE_P2PDEVICE
,
4478 "DeviceLost", FALSE
);
4482 * wpas_dbus_register_peer - Register a discovered peer object with dbus
4483 * @wpa_s: wpa_supplicant interface structure
4484 * @dev_addr: P2P Device Address of the peer
4485 * Returns: 0 on success, -1 on failure
4487 * Registers network representing object with dbus
4489 int wpas_dbus_register_peer(struct wpa_supplicant
*wpa_s
, const u8
*dev_addr
)
4491 struct wpas_dbus_priv
*ctrl_iface
;
4492 struct wpa_dbus_object_desc
*obj_desc
;
4493 struct peer_handler_args
*arg
;
4494 char peer_obj_path
[WPAS_DBUS_OBJECT_PATH_MAX
];
4496 /* Do nothing if the control interface is not turned on */
4497 if (wpa_s
== NULL
|| wpa_s
->global
== NULL
)
4500 ctrl_iface
= wpa_s
->global
->dbus
;
4501 if (ctrl_iface
== NULL
)
4504 wpa_s
= wpa_s
->parent
->parent
;
4505 if (!wpa_s
->dbus_new_path
)
4508 os_snprintf(peer_obj_path
, WPAS_DBUS_OBJECT_PATH_MAX
,
4509 "%s/" WPAS_DBUS_NEW_P2P_PEERS_PART
"/" COMPACT_MACSTR
,
4510 wpa_s
->dbus_new_path
, MAC2STR(dev_addr
));
4512 wpa_printf(MSG_INFO
, "dbus: Register peer object '%s'",
4514 obj_desc
= os_zalloc(sizeof(struct wpa_dbus_object_desc
));
4516 wpa_printf(MSG_ERROR
,
4517 "Not enough memory to create object description");
4521 /* allocate memory for handlers arguments */
4522 arg
= os_zalloc(sizeof(struct peer_handler_args
));
4524 wpa_printf(MSG_ERROR
,
4525 "Not enough memory to create arguments for method");
4530 os_memcpy(arg
->p2p_device_addr
, dev_addr
, ETH_ALEN
);
4532 wpas_dbus_register(obj_desc
, arg
, wpa_dbus_free
,
4534 wpas_dbus_p2p_peer_properties
,
4535 wpas_dbus_p2p_peer_signals
);
4537 if (wpa_dbus_register_object_per_iface(ctrl_iface
, peer_obj_path
,
4538 wpa_s
->ifname
, obj_desc
))
4544 free_dbus_object_desc(obj_desc
);
4549 * wpas_dbus_unregister_peer - Unregister a peer object with dbus
4550 * @wpa_s: wpa_supplicant interface structure
4551 * @dev_addr: p2p device addr
4552 * Returns: 0 on success, -1 on failure
4554 * Registers network representing object with dbus
4556 int wpas_dbus_unregister_peer(struct wpa_supplicant
*wpa_s
,
4559 struct wpas_dbus_priv
*ctrl_iface
;
4560 char peer_obj_path
[WPAS_DBUS_OBJECT_PATH_MAX
];
4563 /* Do nothing if the control interface is not turned on */
4564 if (wpa_s
== NULL
|| wpa_s
->global
== NULL
)
4567 wpa_s
= wpa_s
->parent
->parent
;
4568 if (!wpa_s
->dbus_new_path
)
4571 ctrl_iface
= wpa_s
->global
->dbus
;
4572 if (ctrl_iface
== NULL
)
4575 os_snprintf(peer_obj_path
, WPAS_DBUS_OBJECT_PATH_MAX
,
4576 "%s/" WPAS_DBUS_NEW_P2P_PEERS_PART
"/" COMPACT_MACSTR
,
4577 wpa_s
->dbus_new_path
, MAC2STR(dev_addr
));
4579 wpa_printf(MSG_INFO
, "dbus: Unregister peer object '%s'",
4581 ret
= wpa_dbus_unregister_object_per_iface(ctrl_iface
, peer_obj_path
);
4588 * wpas_dbus_signal_p2p_find_stopped - Send P2P Find stopped signal
4589 * @wpa_s: %wpa_supplicant network interface data
4591 * Notify listeners about P2P Find stopped
4593 void wpas_dbus_signal_p2p_find_stopped(struct wpa_supplicant
*wpa_s
)
4595 struct wpas_dbus_priv
*iface
;
4598 iface
= wpa_s
->global
->dbus
;
4600 /* Do nothing if the control interface is not turned on */
4604 if (wpa_s
->p2p_mgmt
)
4605 wpa_s
= wpa_s
->parent
;
4607 if (!wpa_s
->dbus_new_path
)
4610 msg
= dbus_message_new_signal(wpa_s
->dbus_new_path
,
4611 WPAS_DBUS_NEW_IFACE_P2PDEVICE
,
4616 dbus_connection_send(iface
->con
, msg
, NULL
);
4618 dbus_message_unref(msg
);
4623 * wpas_dbus_signal_peer_groups_changed - Send peer group change property signal
4624 * @wpa_s: %wpa_supplicant network interface data
4625 * @dev_addr: P2P Device Address
4627 * Notify listeners about peer Groups property changes.
4629 void wpas_dbus_signal_peer_groups_changed(struct wpa_supplicant
*wpa_s
,
4632 char peer_obj_path
[WPAS_DBUS_OBJECT_PATH_MAX
];
4634 if (wpa_s
->p2p_mgmt
)
4635 wpa_s
= wpa_s
->parent
;
4637 if (!wpa_s
->dbus_new_path
)
4639 os_snprintf(peer_obj_path
, WPAS_DBUS_OBJECT_PATH_MAX
,
4640 "%s/" WPAS_DBUS_NEW_P2P_PEERS_PART
"/" COMPACT_MACSTR
,
4641 wpa_s
->dbus_new_path
, MAC2STR(dev_addr
));
4643 wpa_dbus_mark_property_changed(wpa_s
->global
->dbus
, peer_obj_path
,
4644 WPAS_DBUS_NEW_IFACE_P2P_PEER
, "Groups");
4648 static const struct wpa_dbus_property_desc wpas_dbus_p2p_group_properties
[] = {
4649 { "Members", WPAS_DBUS_NEW_IFACE_P2P_GROUP
, "ao",
4650 wpas_dbus_getter_p2p_group_members
,
4654 { "Group", WPAS_DBUS_NEW_IFACE_P2P_GROUP
, "o",
4655 wpas_dbus_getter_p2p_group
,
4659 { "Role", WPAS_DBUS_NEW_IFACE_P2P_GROUP
, "s",
4660 wpas_dbus_getter_p2p_role
,
4664 { "SSID", WPAS_DBUS_NEW_IFACE_P2P_GROUP
, "ay",
4665 wpas_dbus_getter_p2p_group_ssid
,
4669 { "BSSID", WPAS_DBUS_NEW_IFACE_P2P_GROUP
, "ay",
4670 wpas_dbus_getter_p2p_group_bssid
,
4674 { "Frequency", WPAS_DBUS_NEW_IFACE_P2P_GROUP
, "q",
4675 wpas_dbus_getter_p2p_group_frequency
,
4679 { "Passphrase", WPAS_DBUS_NEW_IFACE_P2P_GROUP
, "s",
4680 wpas_dbus_getter_p2p_group_passphrase
,
4684 { "PSK", WPAS_DBUS_NEW_IFACE_P2P_GROUP
, "ay",
4685 wpas_dbus_getter_p2p_group_psk
,
4689 { "WPSVendorExtensions", WPAS_DBUS_NEW_IFACE_P2P_GROUP
, "aay",
4690 wpas_dbus_getter_p2p_group_vendor_ext
,
4691 wpas_dbus_setter_p2p_group_vendor_ext
,
4694 { NULL
, NULL
, NULL
, NULL
, NULL
, NULL
}
4697 static const struct wpa_dbus_signal_desc wpas_dbus_p2p_group_signals
[] = {
4698 { "PeerJoined", WPAS_DBUS_NEW_IFACE_P2P_GROUP
,
4700 { "peer", "o", ARG_OUT
},
4704 { "PeerDisconnected", WPAS_DBUS_NEW_IFACE_P2P_GROUP
,
4706 { "peer", "o", ARG_OUT
},
4710 { NULL
, NULL
, { END_ARGS
} }
4714 * wpas_dbus_register_p2p_group - Register a p2p group object with dbus
4715 * @wpa_s: wpa_supplicant interface structure
4716 * @ssid: SSID struct
4717 * Returns: 0 on success, -1 on failure
4719 * Registers p2p group representing object with dbus
4721 void wpas_dbus_register_p2p_group(struct wpa_supplicant
*wpa_s
,
4722 struct wpa_ssid
*ssid
)
4724 struct wpas_dbus_priv
*ctrl_iface
;
4725 struct wpa_dbus_object_desc
*obj_desc
;
4726 char group_obj_path
[WPAS_DBUS_OBJECT_PATH_MAX
];
4728 /* Do nothing if the control interface is not turned on */
4729 if (wpa_s
== NULL
|| wpa_s
->global
== NULL
)
4732 ctrl_iface
= wpa_s
->global
->dbus
;
4733 if (ctrl_iface
== NULL
)
4736 if (wpa_s
->dbus_groupobj_path
) {
4737 wpa_printf(MSG_INFO
, "%s: Group object '%s' already exists",
4738 __func__
, wpa_s
->dbus_groupobj_path
);
4742 if (wpas_dbus_get_group_obj_path(wpa_s
, ssid
, group_obj_path
) < 0)
4745 wpa_s
->dbus_groupobj_path
= os_strdup(group_obj_path
);
4746 if (wpa_s
->dbus_groupobj_path
== NULL
)
4749 wpa_printf(MSG_INFO
, "dbus: Register group object '%s'",
4751 obj_desc
= os_zalloc(sizeof(struct wpa_dbus_object_desc
));
4753 wpa_printf(MSG_ERROR
,
4754 "Not enough memory to create object description");
4758 wpas_dbus_register(obj_desc
, wpa_s
, NULL
, NULL
,
4759 wpas_dbus_p2p_group_properties
,
4760 wpas_dbus_p2p_group_signals
);
4762 if (wpa_dbus_register_object_per_iface(ctrl_iface
, group_obj_path
,
4763 wpa_s
->ifname
, obj_desc
))
4769 if (wpa_s
->dbus_groupobj_path
) {
4770 os_free(wpa_s
->dbus_groupobj_path
);
4771 wpa_s
->dbus_groupobj_path
= NULL
;
4774 free_dbus_object_desc(obj_desc
);
4778 * wpas_dbus_unregister_p2p_group - Unregister a p2p group object from dbus
4779 * @wpa_s: wpa_supplicant interface structure
4780 * @ssid: network name of the p2p group started
4782 void wpas_dbus_unregister_p2p_group(struct wpa_supplicant
*wpa_s
,
4783 const struct wpa_ssid
*ssid
)
4785 struct wpas_dbus_priv
*ctrl_iface
;
4787 /* Do nothing if the control interface is not turned on */
4788 if (wpa_s
== NULL
|| wpa_s
->global
== NULL
)
4791 if (wpa_s
->p2p_mgmt
)
4792 wpa_s
= wpa_s
->parent
;
4794 ctrl_iface
= wpa_s
->global
->dbus
;
4795 if (ctrl_iface
== NULL
)
4798 if (!wpa_s
->dbus_groupobj_path
) {
4799 wpa_printf(MSG_DEBUG
,
4800 "%s: Group object has already unregistered",
4805 peer_groups_changed(wpa_s
);
4807 wpa_printf(MSG_DEBUG
, "dbus: Unregister group object '%s'",
4808 wpa_s
->dbus_groupobj_path
);
4810 wpa_dbus_unregister_object_per_iface(ctrl_iface
,
4811 wpa_s
->dbus_groupobj_path
);
4813 os_free(wpa_s
->dbus_groupobj_path
);
4814 wpa_s
->dbus_groupobj_path
= NULL
;
4817 static const struct wpa_dbus_property_desc
4818 wpas_dbus_persistent_group_properties
[] = {
4819 { "Properties", WPAS_DBUS_NEW_IFACE_PERSISTENT_GROUP
, "a{sv}",
4820 wpas_dbus_getter_persistent_group_properties
,
4821 wpas_dbus_setter_persistent_group_properties
,
4824 { NULL
, NULL
, NULL
, NULL
, NULL
, NULL
}
4827 /* No signals intended for persistent group objects */
4830 * wpas_dbus_register_persistent_group - Register a configured(saved)
4831 * persistent group with dbus
4832 * @wpa_s: wpa_supplicant interface structure
4833 * @ssid: persistent group (still represented as a network within wpa)
4834 * configuration data
4835 * Returns: 0 on success, -1 on failure
4837 * Registers a persistent group representing object with dbus.
4839 int wpas_dbus_register_persistent_group(struct wpa_supplicant
*wpa_s
,
4840 struct wpa_ssid
*ssid
)
4842 struct wpas_dbus_priv
*ctrl_iface
;
4843 struct wpa_dbus_object_desc
*obj_desc
;
4844 struct network_handler_args
*arg
;
4845 char pgrp_obj_path
[WPAS_DBUS_OBJECT_PATH_MAX
];
4847 /* Do nothing if the control interface is not turned on */
4848 if (wpa_s
== NULL
|| wpa_s
->global
== NULL
)
4850 wpa_s
= wpa_s
->parent
->parent
;
4851 if (!wpa_s
->dbus_new_path
)
4854 /* Make sure ssid is a persistent group */
4855 if (ssid
->disabled
!= 2 && !ssid
->p2p_persistent_group
)
4856 return -1; /* should we return w/o complaining? */
4858 if (wpa_s
->p2p_mgmt
)
4859 wpa_s
= wpa_s
->parent
;
4861 ctrl_iface
= wpa_s
->global
->dbus
;
4862 if (ctrl_iface
== NULL
)
4866 * Intentionally not coming up with different numbering scheme
4867 * for persistent groups.
4869 os_snprintf(pgrp_obj_path
, WPAS_DBUS_OBJECT_PATH_MAX
,
4870 "%s/" WPAS_DBUS_NEW_PERSISTENT_GROUPS_PART
"/%u",
4871 wpa_s
->dbus_new_path
, ssid
->id
);
4873 wpa_printf(MSG_DEBUG
, "dbus: Register persistent group object '%s'",
4875 obj_desc
= os_zalloc(sizeof(struct wpa_dbus_object_desc
));
4877 wpa_printf(MSG_ERROR
,
4878 "dbus: Not enough memory to create object description");
4883 * Reusing the same context structure as that for networks
4884 * since these are represented using same data structure.
4886 /* allocate memory for handlers arguments */
4887 arg
= os_zalloc(sizeof(struct network_handler_args
));
4889 wpa_printf(MSG_ERROR
,
4890 "dbus: Not enough memory to create arguments for method");
4897 wpas_dbus_register(obj_desc
, arg
, wpa_dbus_free
, NULL
,
4898 wpas_dbus_persistent_group_properties
,
4901 if (wpa_dbus_register_object_per_iface(ctrl_iface
, pgrp_obj_path
,
4902 wpa_s
->ifname
, obj_desc
))
4905 wpas_dbus_signal_persistent_group_added(wpa_s
, ssid
->id
);
4910 free_dbus_object_desc(obj_desc
);
4916 * wpas_dbus_unregister_persistent_group - Unregister a persistent_group
4918 * @wpa_s: wpa_supplicant interface structure
4920 * Returns: 0 on success, -1 on failure
4922 * Unregisters persistent group representing object from dbus
4924 * NOTE: There is a slight issue with the semantics here. While the
4925 * implementation simply means the persistent group is unloaded from memory,
4926 * it should not get interpreted as the group is actually being erased/removed
4927 * from persistent storage as well.
4929 int wpas_dbus_unregister_persistent_group(struct wpa_supplicant
*wpa_s
,
4932 struct wpas_dbus_priv
*ctrl_iface
;
4933 char pgrp_obj_path
[WPAS_DBUS_OBJECT_PATH_MAX
];
4936 /* Do nothing if the control interface is not turned on */
4937 if (wpa_s
== NULL
|| wpa_s
->global
== NULL
)
4940 wpa_s
= wpa_s
->parent
->parent
;
4942 ctrl_iface
= wpa_s
->global
->dbus
;
4943 if (ctrl_iface
== NULL
|| !wpa_s
->dbus_new_path
)
4946 os_snprintf(pgrp_obj_path
, WPAS_DBUS_OBJECT_PATH_MAX
,
4947 "%s/" WPAS_DBUS_NEW_PERSISTENT_GROUPS_PART
"/%u",
4948 wpa_s
->dbus_new_path
, nid
);
4950 wpa_printf(MSG_DEBUG
, "dbus: Unregister persistent group object '%s'",
4952 ret
= wpa_dbus_unregister_object_per_iface(ctrl_iface
, pgrp_obj_path
);
4955 wpas_dbus_signal_persistent_group_removed(wpa_s
, nid
);
4960 #endif /* CONFIG_P2P */