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 program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
11 * Alternatively, this software may be distributed under the terms of BSD
14 * See README and COPYING for more details.
20 #include "common/ieee802_11_defs.h"
22 #include "../config.h"
23 #include "../wpa_supplicant_i.h"
25 #include "../wpas_glue.h"
26 #include "dbus_new_helpers.h"
27 #include "dbus_dict_helpers.h"
29 #include "dbus_new_handlers.h"
30 #include "dbus_common_i.h"
31 #include "dbus_new_handlers_p2p.h"
34 #ifdef CONFIG_AP /* until needed by something else */
37 * NameOwnerChanged handling
39 * Some services we provide allow an application to register for
40 * a signal that it needs. While it can also unregister, we must
41 * be prepared for the case where the application simply crashes
42 * and thus doesn't clean up properly. The way to handle this in
43 * DBus is to register for the NameOwnerChanged signal which will
44 * signal an owner change to NULL if the peer closes the socket
45 * for whatever reason.
47 * Handle this signal via a filter function whenever necessary.
48 * The code below also handles refcounting in case in the future
49 * there will be multiple instances of this subscription scheme.
51 static const char wpas_dbus_noc_filter_str
[] =
52 "interface=org.freedesktop.DBus,member=NameOwnerChanged";
55 static DBusHandlerResult
noc_filter(DBusConnection
*conn
,
56 DBusMessage
*message
, void *data
)
58 struct wpas_dbus_priv
*priv
= data
;
60 if (dbus_message_get_type(message
) != DBUS_MESSAGE_TYPE_SIGNAL
)
61 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED
;
63 if (dbus_message_is_signal(message
, DBUS_INTERFACE_DBUS
,
64 "NameOwnerChanged")) {
66 const char *prev_owner
;
67 const char *new_owner
;
69 struct wpa_supplicant
*wpa_s
;
71 dbus_error_init(&derr
);
73 if (!dbus_message_get_args(message
, &derr
,
74 DBUS_TYPE_STRING
, &name
,
75 DBUS_TYPE_STRING
, &prev_owner
,
76 DBUS_TYPE_STRING
, &new_owner
,
78 /* Ignore this error */
79 dbus_error_free(&derr
);
80 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED
;
83 for (wpa_s
= priv
->global
->ifaces
; wpa_s
; wpa_s
= wpa_s
->next
)
85 if (wpa_s
->preq_notify_peer
!= NULL
&&
86 os_strcmp(name
, wpa_s
->preq_notify_peer
) == 0 &&
87 (new_owner
== NULL
|| os_strlen(new_owner
) == 0)) {
88 /* probe request owner disconnected */
89 os_free(wpa_s
->preq_notify_peer
);
90 wpa_s
->preq_notify_peer
= NULL
;
91 wpas_dbus_unsubscribe_noc(priv
);
96 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED
;
100 void wpas_dbus_subscribe_noc(struct wpas_dbus_priv
*priv
)
102 priv
->dbus_noc_refcnt
++;
103 if (priv
->dbus_noc_refcnt
> 1)
106 if (!dbus_connection_add_filter(priv
->con
, noc_filter
, priv
, NULL
)) {
107 wpa_printf(MSG_ERROR
, "dbus: failed to add filter");
111 dbus_bus_add_match(priv
->con
, wpas_dbus_noc_filter_str
, NULL
);
115 void wpas_dbus_unsubscribe_noc(struct wpas_dbus_priv
*priv
)
117 priv
->dbus_noc_refcnt
--;
118 if (priv
->dbus_noc_refcnt
> 0)
121 dbus_bus_remove_match(priv
->con
, wpas_dbus_noc_filter_str
, NULL
);
122 dbus_connection_remove_filter(priv
->con
, noc_filter
, priv
);
125 #endif /* CONFIG_AP */
129 * wpas_dbus_signal_interface - Send a interface related event signal
130 * @wpa_s: %wpa_supplicant network interface data
131 * @sig_name: signal name - InterfaceAdded or InterfaceRemoved
132 * @properties: Whether to add second argument with object properties
134 * Notify listeners about event related with interface
136 static void wpas_dbus_signal_interface(struct wpa_supplicant
*wpa_s
,
137 const char *sig_name
, int properties
)
139 struct wpas_dbus_priv
*iface
;
141 DBusMessageIter iter
;
143 iface
= wpa_s
->global
->dbus
;
145 /* Do nothing if the control interface is not turned on */
149 msg
= dbus_message_new_signal(WPAS_DBUS_NEW_PATH
,
150 WPAS_DBUS_NEW_INTERFACE
, sig_name
);
154 dbus_message_iter_init_append(msg
, &iter
);
155 if (!dbus_message_iter_append_basic(&iter
, DBUS_TYPE_OBJECT_PATH
,
156 &wpa_s
->dbus_new_path
))
160 if (!wpa_dbus_get_object_properties(
161 iface
, wpa_s
->dbus_new_path
,
162 WPAS_DBUS_NEW_IFACE_INTERFACE
, &iter
))
166 dbus_connection_send(iface
->con
, msg
, NULL
);
167 dbus_message_unref(msg
);
171 wpa_printf(MSG_ERROR
, "dbus: Failed to construct signal");
172 dbus_message_unref(msg
);
177 * wpas_dbus_signal_interface_added - Send a interface created signal
178 * @wpa_s: %wpa_supplicant network interface data
180 * Notify listeners about creating new interface
182 static void wpas_dbus_signal_interface_added(struct wpa_supplicant
*wpa_s
)
184 wpas_dbus_signal_interface(wpa_s
, "InterfaceAdded", TRUE
);
189 * wpas_dbus_signal_interface_removed - Send a interface removed signal
190 * @wpa_s: %wpa_supplicant network interface data
192 * Notify listeners about removing interface
194 static void wpas_dbus_signal_interface_removed(struct wpa_supplicant
*wpa_s
)
196 wpas_dbus_signal_interface(wpa_s
, "InterfaceRemoved", FALSE
);
202 * wpas_dbus_signal_scan_done - send scan done signal
203 * @wpa_s: %wpa_supplicant network interface data
204 * @success: indicates if scanning succeed or failed
206 * Notify listeners about finishing a scan
208 void wpas_dbus_signal_scan_done(struct wpa_supplicant
*wpa_s
, int success
)
210 struct wpas_dbus_priv
*iface
;
214 iface
= wpa_s
->global
->dbus
;
216 /* Do nothing if the control interface is not turned on */
220 msg
= dbus_message_new_signal(wpa_s
->dbus_new_path
,
221 WPAS_DBUS_NEW_IFACE_INTERFACE
,
226 succ
= success
? TRUE
: FALSE
;
227 if (dbus_message_append_args(msg
, DBUS_TYPE_BOOLEAN
, &succ
,
229 dbus_connection_send(iface
->con
, msg
, NULL
);
231 wpa_printf(MSG_ERROR
, "dbus: Failed to construct signal");
232 dbus_message_unref(msg
);
237 * wpas_dbus_signal_blob - Send a BSS related event signal
238 * @wpa_s: %wpa_supplicant network interface data
239 * @bss_obj_path: BSS object path
240 * @sig_name: signal name - BSSAdded or BSSRemoved
241 * @properties: Whether to add second argument with object properties
243 * Notify listeners about event related with BSS
245 static void wpas_dbus_signal_bss(struct wpa_supplicant
*wpa_s
,
246 const char *bss_obj_path
,
247 const char *sig_name
, int properties
)
249 struct wpas_dbus_priv
*iface
;
251 DBusMessageIter iter
;
253 iface
= wpa_s
->global
->dbus
;
255 /* Do nothing if the control interface is not turned on */
259 msg
= dbus_message_new_signal(wpa_s
->dbus_new_path
,
260 WPAS_DBUS_NEW_IFACE_INTERFACE
,
265 dbus_message_iter_init_append(msg
, &iter
);
266 if (!dbus_message_iter_append_basic(&iter
, DBUS_TYPE_OBJECT_PATH
,
271 if (!wpa_dbus_get_object_properties(iface
, bss_obj_path
,
272 WPAS_DBUS_NEW_IFACE_BSS
,
277 dbus_connection_send(iface
->con
, msg
, NULL
);
278 dbus_message_unref(msg
);
282 wpa_printf(MSG_ERROR
, "dbus: Failed to construct signal");
283 dbus_message_unref(msg
);
288 * wpas_dbus_signal_bss_added - Send a BSS added signal
289 * @wpa_s: %wpa_supplicant network interface data
290 * @bss_obj_path: new BSS object path
292 * Notify listeners about adding new BSS
294 static void wpas_dbus_signal_bss_added(struct wpa_supplicant
*wpa_s
,
295 const char *bss_obj_path
)
297 wpas_dbus_signal_bss(wpa_s
, bss_obj_path
, "BSSAdded", TRUE
);
302 * wpas_dbus_signal_bss_removed - Send a BSS removed signal
303 * @wpa_s: %wpa_supplicant network interface data
304 * @bss_obj_path: BSS object path
306 * Notify listeners about removing BSS
308 static void wpas_dbus_signal_bss_removed(struct wpa_supplicant
*wpa_s
,
309 const char *bss_obj_path
)
311 wpas_dbus_signal_bss(wpa_s
, bss_obj_path
, "BSSRemoved", FALSE
);
316 * wpas_dbus_signal_blob - Send a blob related event signal
317 * @wpa_s: %wpa_supplicant network interface data
319 * @sig_name: signal name - BlobAdded or BlobRemoved
321 * Notify listeners about event related with blob
323 static void wpas_dbus_signal_blob(struct wpa_supplicant
*wpa_s
,
324 const char *name
, const char *sig_name
)
326 struct wpas_dbus_priv
*iface
;
329 iface
= wpa_s
->global
->dbus
;
331 /* Do nothing if the control interface is not turned on */
335 msg
= dbus_message_new_signal(wpa_s
->dbus_new_path
,
336 WPAS_DBUS_NEW_IFACE_INTERFACE
,
341 if (dbus_message_append_args(msg
, DBUS_TYPE_STRING
, &name
,
343 dbus_connection_send(iface
->con
, msg
, NULL
);
345 wpa_printf(MSG_ERROR
, "dbus: Failed to construct signal");
346 dbus_message_unref(msg
);
351 * wpas_dbus_signal_blob_added - Send a blob added signal
352 * @wpa_s: %wpa_supplicant network interface data
355 * Notify listeners about adding a new blob
357 void wpas_dbus_signal_blob_added(struct wpa_supplicant
*wpa_s
,
360 wpas_dbus_signal_blob(wpa_s
, name
, "BlobAdded");
365 * wpas_dbus_signal_blob_removed - Send a blob removed signal
366 * @wpa_s: %wpa_supplicant network interface data
369 * Notify listeners about removing blob
371 void wpas_dbus_signal_blob_removed(struct wpa_supplicant
*wpa_s
,
374 wpas_dbus_signal_blob(wpa_s
, name
, "BlobRemoved");
379 * wpas_dbus_signal_network - Send a network related event signal
380 * @wpa_s: %wpa_supplicant network interface data
381 * @id: new network id
382 * @sig_name: signal name - NetworkAdded, NetworkRemoved or NetworkSelected
383 * @properties: determines if add second argument with object properties
385 * Notify listeners about event related with configured network
387 static void wpas_dbus_signal_network(struct wpa_supplicant
*wpa_s
,
388 int id
, const char *sig_name
,
391 struct wpas_dbus_priv
*iface
;
393 DBusMessageIter iter
;
394 char net_obj_path
[WPAS_DBUS_OBJECT_PATH_MAX
], *path
;
396 iface
= wpa_s
->global
->dbus
;
398 /* Do nothing if the control interface is not turned on */
402 os_snprintf(net_obj_path
, WPAS_DBUS_OBJECT_PATH_MAX
,
403 "%s/" WPAS_DBUS_NEW_NETWORKS_PART
"/%u",
404 wpa_s
->dbus_new_path
, id
);
406 msg
= dbus_message_new_signal(wpa_s
->dbus_new_path
,
407 WPAS_DBUS_NEW_IFACE_INTERFACE
,
412 dbus_message_iter_init_append(msg
, &iter
);
414 if (!dbus_message_iter_append_basic(&iter
, DBUS_TYPE_OBJECT_PATH
,
419 if (!wpa_dbus_get_object_properties(
420 iface
, net_obj_path
, WPAS_DBUS_NEW_IFACE_NETWORK
,
425 dbus_connection_send(iface
->con
, msg
, NULL
);
427 dbus_message_unref(msg
);
431 wpa_printf(MSG_ERROR
, "dbus: Failed to construct signal");
432 dbus_message_unref(msg
);
437 * wpas_dbus_signal_network_added - Send a network added signal
438 * @wpa_s: %wpa_supplicant network interface data
439 * @id: new network id
441 * Notify listeners about adding new network
443 static void wpas_dbus_signal_network_added(struct wpa_supplicant
*wpa_s
,
446 wpas_dbus_signal_network(wpa_s
, id
, "NetworkAdded", TRUE
);
451 * wpas_dbus_signal_network_removed - Send a network removed signal
452 * @wpa_s: %wpa_supplicant network interface data
455 * Notify listeners about removing a network
457 static void wpas_dbus_signal_network_removed(struct wpa_supplicant
*wpa_s
,
460 wpas_dbus_signal_network(wpa_s
, id
, "NetworkRemoved", FALSE
);
465 * wpas_dbus_signal_network_selected - Send a network selected signal
466 * @wpa_s: %wpa_supplicant network interface data
469 * Notify listeners about selecting a network
471 void wpas_dbus_signal_network_selected(struct wpa_supplicant
*wpa_s
, int id
)
473 wpas_dbus_signal_network(wpa_s
, id
, "NetworkSelected", FALSE
);
478 * wpas_dbus_signal_network_request - Indicate that additional information
479 * (EAP password, etc.) is required to complete the association to this SSID
480 * @wpa_s: %wpa_supplicant network interface data
481 * @rtype: The specific additional information required
482 * @default_text: Optional description of required information
484 * Request additional information or passwords to complete an association
487 void wpas_dbus_signal_network_request(struct wpa_supplicant
*wpa_s
,
488 struct wpa_ssid
*ssid
,
489 enum wpa_ctrl_req_type rtype
,
490 const char *default_txt
)
492 struct wpas_dbus_priv
*iface
;
494 DBusMessageIter iter
;
495 char net_obj_path
[WPAS_DBUS_OBJECT_PATH_MAX
];
496 const char *field
, *txt
= NULL
, *net_ptr
;
498 iface
= wpa_s
->global
->dbus
;
500 /* Do nothing if the control interface is not turned on */
504 field
= wpa_supplicant_ctrl_req_to_string(rtype
, default_txt
, &txt
);
508 msg
= dbus_message_new_signal(wpa_s
->dbus_new_path
,
509 WPAS_DBUS_NEW_IFACE_INTERFACE
,
514 os_snprintf(net_obj_path
, WPAS_DBUS_OBJECT_PATH_MAX
,
515 "%s/" WPAS_DBUS_NEW_NETWORKS_PART
"/%u",
516 wpa_s
->dbus_new_path
, ssid
->id
);
517 net_ptr
= &net_obj_path
[0];
519 dbus_message_iter_init_append(msg
, &iter
);
520 if (!dbus_message_iter_append_basic(&iter
, DBUS_TYPE_OBJECT_PATH
,
523 if (!dbus_message_iter_append_basic(&iter
, DBUS_TYPE_STRING
, &field
))
525 if (!dbus_message_iter_append_basic(&iter
, DBUS_TYPE_STRING
, &txt
))
528 dbus_connection_send(iface
->con
, msg
, NULL
);
529 dbus_message_unref(msg
);
533 wpa_printf(MSG_ERROR
, "dbus: Failed to construct signal");
534 dbus_message_unref(msg
);
539 * wpas_dbus_signal_network_enabled_changed - Signals Enabled property changes
540 * @wpa_s: %wpa_supplicant network interface data
541 * @ssid: configured network which Enabled property has changed
543 * Sends PropertyChanged signals containing new value of Enabled property
544 * for specified network
546 void wpas_dbus_signal_network_enabled_changed(struct wpa_supplicant
*wpa_s
,
547 struct wpa_ssid
*ssid
)
550 char path
[WPAS_DBUS_OBJECT_PATH_MAX
];
551 os_snprintf(path
, WPAS_DBUS_OBJECT_PATH_MAX
,
552 "%s/" WPAS_DBUS_NEW_NETWORKS_PART
"/%d",
553 wpa_s
->dbus_new_path
, ssid
->id
);
555 wpa_dbus_mark_property_changed(wpa_s
->global
->dbus
, path
,
556 WPAS_DBUS_NEW_IFACE_NETWORK
, "Enabled");
563 * wpas_dbus_signal_wps_event_success - Signals Success WPS event
564 * @wpa_s: %wpa_supplicant network interface data
566 * Sends Event dbus signal with name "success" and empty dict as arguments
568 void wpas_dbus_signal_wps_event_success(struct wpa_supplicant
*wpa_s
)
572 DBusMessageIter iter
, dict_iter
;
573 struct wpas_dbus_priv
*iface
;
574 char *key
= "success";
576 iface
= wpa_s
->global
->dbus
;
578 /* Do nothing if the control interface is not turned on */
582 msg
= dbus_message_new_signal(wpa_s
->dbus_new_path
,
583 WPAS_DBUS_NEW_IFACE_WPS
, "Event");
587 dbus_message_iter_init_append(msg
, &iter
);
589 if (!dbus_message_iter_append_basic(&iter
, DBUS_TYPE_STRING
, &key
) ||
590 !wpa_dbus_dict_open_write(&iter
, &dict_iter
) ||
591 !wpa_dbus_dict_close_write(&iter
, &dict_iter
))
592 wpa_printf(MSG_ERROR
, "dbus: Failed to construct signal");
594 dbus_connection_send(iface
->con
, msg
, NULL
);
596 dbus_message_unref(msg
);
601 * wpas_dbus_signal_wps_event_fail - Signals Fail WPS event
602 * @wpa_s: %wpa_supplicant network interface data
604 * Sends Event dbus signal with name "fail" and dictionary containing
605 * "msg field with fail message number (int32) as arguments
607 void wpas_dbus_signal_wps_event_fail(struct wpa_supplicant
*wpa_s
,
608 struct wps_event_fail
*fail
)
612 DBusMessageIter iter
, dict_iter
;
613 struct wpas_dbus_priv
*iface
;
616 iface
= wpa_s
->global
->dbus
;
618 /* Do nothing if the control interface is not turned on */
622 msg
= dbus_message_new_signal(wpa_s
->dbus_new_path
,
623 WPAS_DBUS_NEW_IFACE_WPS
, "Event");
627 dbus_message_iter_init_append(msg
, &iter
);
629 if (!dbus_message_iter_append_basic(&iter
, DBUS_TYPE_STRING
, &key
) ||
630 !wpa_dbus_dict_open_write(&iter
, &dict_iter
) ||
631 !wpa_dbus_dict_append_int32(&dict_iter
, "msg", fail
->msg
) ||
632 !wpa_dbus_dict_close_write(&iter
, &dict_iter
))
633 wpa_printf(MSG_ERROR
, "dbus: Failed to construct signal");
635 dbus_connection_send(iface
->con
, msg
, NULL
);
637 dbus_message_unref(msg
);
642 * wpas_dbus_signal_wps_event_m2d - Signals M2D WPS event
643 * @wpa_s: %wpa_supplicant network interface data
645 * Sends Event dbus signal with name "m2d" and dictionary containing
646 * fields of wps_event_m2d structure.
648 void wpas_dbus_signal_wps_event_m2d(struct wpa_supplicant
*wpa_s
,
649 struct wps_event_m2d
*m2d
)
653 DBusMessageIter iter
, dict_iter
;
654 struct wpas_dbus_priv
*iface
;
657 iface
= wpa_s
->global
->dbus
;
659 /* Do nothing if the control interface is not turned on */
663 msg
= dbus_message_new_signal(wpa_s
->dbus_new_path
,
664 WPAS_DBUS_NEW_IFACE_WPS
, "Event");
668 dbus_message_iter_init_append(msg
, &iter
);
670 if (!dbus_message_iter_append_basic(&iter
, DBUS_TYPE_STRING
, &key
) ||
671 !wpa_dbus_dict_open_write(&iter
, &dict_iter
) ||
672 !wpa_dbus_dict_append_uint16(&dict_iter
, "config_methods",
673 m2d
->config_methods
) ||
674 !wpa_dbus_dict_append_byte_array(&dict_iter
, "manufacturer",
675 (const char *) m2d
->manufacturer
,
676 m2d
->manufacturer_len
) ||
677 !wpa_dbus_dict_append_byte_array(&dict_iter
, "model_name",
678 (const char *) m2d
->model_name
,
679 m2d
->model_name_len
) ||
680 !wpa_dbus_dict_append_byte_array(&dict_iter
, "model_number",
681 (const char *) m2d
->model_number
,
682 m2d
->model_number_len
) ||
683 !wpa_dbus_dict_append_byte_array(&dict_iter
, "serial_number",
686 m2d
->serial_number_len
) ||
687 !wpa_dbus_dict_append_byte_array(&dict_iter
, "dev_name",
688 (const char *) m2d
->dev_name
,
689 m2d
->dev_name_len
) ||
690 !wpa_dbus_dict_append_byte_array(&dict_iter
, "primary_dev_type",
692 m2d
->primary_dev_type
, 8) ||
693 !wpa_dbus_dict_append_uint16(&dict_iter
, "config_error",
694 m2d
->config_error
) ||
695 !wpa_dbus_dict_append_uint16(&dict_iter
, "dev_password_id",
696 m2d
->dev_password_id
) ||
697 !wpa_dbus_dict_close_write(&iter
, &dict_iter
))
698 wpa_printf(MSG_ERROR
, "dbus: Failed to construct signal");
700 dbus_connection_send(iface
->con
, msg
, NULL
);
702 dbus_message_unref(msg
);
707 * wpas_dbus_signal_wps_cred - Signals new credentials
708 * @wpa_s: %wpa_supplicant network interface data
710 * Sends signal with credentials in directory argument
712 void wpas_dbus_signal_wps_cred(struct wpa_supplicant
*wpa_s
,
713 const struct wps_credential
*cred
)
716 DBusMessageIter iter
, dict_iter
;
717 struct wpas_dbus_priv
*iface
;
718 char *auth_type
[6]; /* we have six possible authorization types */
720 char *encr_type
[4]; /* we have four possible encryption types */
723 iface
= wpa_s
->global
->dbus
;
725 /* Do nothing if the control interface is not turned on */
729 msg
= dbus_message_new_signal(wpa_s
->dbus_new_path
,
730 WPAS_DBUS_NEW_IFACE_WPS
,
735 dbus_message_iter_init_append(msg
, &iter
);
736 if (!wpa_dbus_dict_open_write(&iter
, &dict_iter
))
739 if (cred
->auth_type
& WPS_AUTH_OPEN
)
740 auth_type
[at_num
++] = "open";
741 if (cred
->auth_type
& WPS_AUTH_WPAPSK
)
742 auth_type
[at_num
++] = "wpa-psk";
743 if (cred
->auth_type
& WPS_AUTH_SHARED
)
744 auth_type
[at_num
++] = "shared";
745 if (cred
->auth_type
& WPS_AUTH_WPA
)
746 auth_type
[at_num
++] = "wpa-eap";
747 if (cred
->auth_type
& WPS_AUTH_WPA2
)
748 auth_type
[at_num
++] = "wpa2-eap";
749 if (cred
->auth_type
& WPS_AUTH_WPA2PSK
)
750 auth_type
[at_num
++] =
753 if (cred
->encr_type
& WPS_ENCR_NONE
)
754 encr_type
[et_num
++] = "none";
755 if (cred
->encr_type
& WPS_ENCR_WEP
)
756 encr_type
[et_num
++] = "wep";
757 if (cred
->encr_type
& WPS_ENCR_TKIP
)
758 encr_type
[et_num
++] = "tkip";
759 if (cred
->encr_type
& WPS_ENCR_AES
)
760 encr_type
[et_num
++] = "aes";
762 if (wpa_s
->current_ssid
) {
763 if (!wpa_dbus_dict_append_byte_array(
765 (const char *) wpa_s
->current_ssid
->bssid
,
770 if (!wpa_dbus_dict_append_byte_array(&dict_iter
, "SSID",
771 (const char *) cred
->ssid
,
773 !wpa_dbus_dict_append_string_array(&dict_iter
, "AuthType",
774 (const char **) auth_type
,
776 !wpa_dbus_dict_append_string_array(&dict_iter
, "EncrType",
777 (const char **) encr_type
,
779 !wpa_dbus_dict_append_byte_array(&dict_iter
, "Key",
780 (const char *) cred
->key
,
782 !wpa_dbus_dict_append_uint32(&dict_iter
, "KeyIndex",
784 !wpa_dbus_dict_close_write(&iter
, &dict_iter
))
787 dbus_connection_send(iface
->con
, msg
, NULL
);
790 dbus_message_unref(msg
);
793 #endif /* CONFIG_WPS */
795 void wpas_dbus_signal_certification(struct wpa_supplicant
*wpa_s
,
796 int depth
, const char *subject
,
797 const char *cert_hash
,
798 const struct wpabuf
*cert
)
800 struct wpas_dbus_priv
*iface
;
802 DBusMessageIter iter
, dict_iter
;
804 iface
= wpa_s
->global
->dbus
;
806 /* Do nothing if the control interface is not turned on */
810 msg
= dbus_message_new_signal(wpa_s
->dbus_new_path
,
811 WPAS_DBUS_NEW_IFACE_INTERFACE
,
816 dbus_message_iter_init_append(msg
, &iter
);
817 if (!wpa_dbus_dict_open_write(&iter
, &dict_iter
))
820 if (!wpa_dbus_dict_append_uint32(&dict_iter
, "depth", depth
) ||
821 !wpa_dbus_dict_append_string(&dict_iter
, "subject", subject
))
825 !wpa_dbus_dict_append_string(&dict_iter
, "cert_hash", cert_hash
))
829 !wpa_dbus_dict_append_byte_array(&dict_iter
, "cert",
834 if (!wpa_dbus_dict_close_write(&iter
, &dict_iter
))
837 dbus_connection_send(iface
->con
, msg
, NULL
);
840 dbus_message_unref(msg
);
846 * wpas_dbus_signal_p2p_group_removed - Signals P2P group was removed
847 * @wpa_s: %wpa_supplicant network interface data
848 * @role: role of this device (client or GO)
849 * Sends signal with i/f name and role as string arguments
851 void wpas_dbus_signal_p2p_group_removed(struct wpa_supplicant
*wpa_s
,
856 DBusMessageIter iter
;
857 struct wpas_dbus_priv
*iface
= wpa_s
->global
->dbus
;
858 char *ifname
= wpa_s
->ifname
;
860 /* Do nothing if the control interface is not turned on */
864 msg
= dbus_message_new_signal(wpa_s
->dbus_new_path
,
865 WPAS_DBUS_NEW_IFACE_P2PDEVICE
,
870 dbus_message_iter_init_append(msg
, &iter
);
872 if (!dbus_message_iter_append_basic(&iter
, DBUS_TYPE_STRING
, &ifname
)) {
873 wpa_printf(MSG_ERROR
, "dbus: Failed to construct GroupFinished"
874 "signal -not enough memory for ifname ");
878 if (!dbus_message_iter_append_basic(&iter
, DBUS_TYPE_STRING
, &role
))
879 wpa_printf(MSG_ERROR
, "dbus: Failed to construct GroupFinished"
880 "signal -not enough memory for role ");
882 dbus_connection_send(iface
->con
, msg
, NULL
);
885 dbus_message_unref(msg
);
890 * wpas_dbus_signal_p2p_provision_discovery - Signals various PD events
892 * @dev_addr - who sent the request or responded to our request.
893 * @request - Will be 1 if request, 0 for response.
894 * @status - valid only in case of response
895 * @config_methods - wps config methods
896 * @generated_pin - pin to be displayed in case of WPS_CONFIG_DISPLAY method
898 * Sends following provision discovery related events:
899 * ProvisionDiscoveryRequestDisplayPin
900 * ProvisionDiscoveryResponseDisplayPin
901 * ProvisionDiscoveryRequestEnterPin
902 * ProvisionDiscoveryResponseEnterPin
903 * ProvisionDiscoveryPBCRequest
904 * ProvisionDiscoveryPBCResponse
907 * ProvisionDiscoveryFailure (timeout case)
909 void wpas_dbus_signal_p2p_provision_discovery(struct wpa_supplicant
*wpa_s
,
910 const u8
*dev_addr
, int request
,
911 enum p2p_prov_disc_status status
,
913 unsigned int generated_pin
)
916 DBusMessageIter iter
;
917 struct wpas_dbus_priv
*iface
;
920 char peer_obj_path
[WPAS_DBUS_OBJECT_PATH_MAX
], *path
;
922 char pin
[9], *p_pin
= NULL
;
924 iface
= wpa_s
->global
->dbus
;
926 /* Do nothing if the control interface is not turned on */
930 if (request
|| !status
) {
931 if (config_methods
& WPS_CONFIG_DISPLAY
)
933 "ProvisionDiscoveryRequestDisplayPin" :
934 "ProvisionDiscoveryResponseEnterPin";
935 else if (config_methods
& WPS_CONFIG_KEYPAD
)
937 "ProvisionDiscoveryRequestEnterPin" :
938 "ProvisionDiscoveryResponseDisplayPin";
939 else if (config_methods
& WPS_CONFIG_PUSHBUTTON
)
940 _signal
= request
? "ProvisionDiscoveryPBCRequest" :
941 "ProvisionDiscoveryPBCResponse";
943 return; /* Unknown or un-supported method */
944 } else if (!request
&& status
)
945 /* Explicit check for failure response */
946 _signal
= "ProvisionDiscoveryFailure";
948 add_pin
= ((request
&& (config_methods
& WPS_CONFIG_DISPLAY
)) ||
949 (!request
&& !status
&&
950 (config_methods
& WPS_CONFIG_KEYPAD
)));
953 os_snprintf(pin
, sizeof(pin
), "%08d", generated_pin
);
957 msg
= dbus_message_new_signal(wpa_s
->dbus_new_path
,
958 WPAS_DBUS_NEW_IFACE_P2PDEVICE
, _signal
);
962 /* Check if this is a known peer */
963 if (!p2p_peer_known(wpa_s
->global
->p2p
, dev_addr
))
966 os_snprintf(peer_obj_path
, WPAS_DBUS_OBJECT_PATH_MAX
,
967 "%s/" WPAS_DBUS_NEW_P2P_PEERS_PART
"/"
969 wpa_s
->dbus_new_path
, MAC2STR(dev_addr
));
971 path
= peer_obj_path
;
973 dbus_message_iter_init_append(msg
, &iter
);
975 if (!dbus_message_iter_append_basic(&iter
,
976 DBUS_TYPE_OBJECT_PATH
,
980 if (!request
&& status
)
981 /* Attach status to ProvisionDiscoveryFailure */
982 error_ret
= !dbus_message_iter_append_basic(&iter
,
986 error_ret
= (add_pin
&&
987 !dbus_message_iter_append_basic(&iter
,
993 dbus_connection_send(iface
->con
, msg
, NULL
);
995 wpa_printf(MSG_ERROR
, "dbus: Failed to construct signal");
997 dbus_message_unref(msg
);
1001 void wpas_dbus_signal_p2p_go_neg_req(struct wpa_supplicant
*wpa_s
,
1002 const u8
*src
, u16 dev_passwd_id
)
1005 DBusMessageIter iter
;
1006 struct wpas_dbus_priv
*iface
;
1007 char peer_obj_path
[WPAS_DBUS_OBJECT_PATH_MAX
], *path
;
1009 iface
= wpa_s
->global
->dbus
;
1011 /* Do nothing if the control interface is not turned on */
1015 os_snprintf(peer_obj_path
, WPAS_DBUS_OBJECT_PATH_MAX
,
1016 "%s/" WPAS_DBUS_NEW_P2P_PEERS_PART
"/" COMPACT_MACSTR
,
1017 wpa_s
->dbus_new_path
, MAC2STR(src
));
1018 path
= peer_obj_path
;
1020 msg
= dbus_message_new_signal(wpa_s
->dbus_new_path
,
1021 WPAS_DBUS_NEW_IFACE_P2PDEVICE
,
1022 "GONegotiationRequest");
1026 dbus_message_iter_init_append(msg
, &iter
);
1028 if (!dbus_message_iter_append_basic(&iter
, DBUS_TYPE_OBJECT_PATH
,
1030 !dbus_message_iter_append_basic(&iter
, DBUS_TYPE_UINT16
,
1032 wpa_printf(MSG_ERROR
, "dbus: Failed to construct signal");
1034 dbus_connection_send(iface
->con
, msg
, NULL
);
1036 dbus_message_unref(msg
);
1040 static int wpas_dbus_get_group_obj_path(struct wpa_supplicant
*wpa_s
,
1041 const struct wpa_ssid
*ssid
,
1042 char *group_obj_path
)
1046 if (os_memcmp(ssid
->ssid
, P2P_WILDCARD_SSID
, P2P_WILDCARD_SSID_LEN
))
1049 os_memcpy(group_name
, ssid
->ssid
+ P2P_WILDCARD_SSID_LEN
, 2);
1050 group_name
[2] = '\0';
1052 os_snprintf(group_obj_path
, WPAS_DBUS_OBJECT_PATH_MAX
,
1053 "%s/" WPAS_DBUS_NEW_P2P_GROUPS_PART
"/%s",
1054 wpa_s
->dbus_new_path
, group_name
);
1061 * wpas_dbus_signal_p2p_group_started - Signals P2P group has
1062 * started. Emitted when a group is successfully started
1063 * irrespective of the role (client/GO) of the current device
1065 * @wpa_s: %wpa_supplicant network interface data
1066 * @ssid: SSID object
1067 * @client: this device is P2P client
1068 * @network_id: network id of the group started, use instead of ssid->id
1069 * to account for persistent groups
1071 void wpas_dbus_signal_p2p_group_started(struct wpa_supplicant
*wpa_s
,
1072 const struct wpa_ssid
*ssid
,
1073 int client
, int network_id
)
1076 DBusMessageIter iter
, dict_iter
;
1077 struct wpas_dbus_priv
*iface
;
1078 char net_obj_path
[WPAS_DBUS_OBJECT_PATH_MAX
];
1079 char group_obj_path
[WPAS_DBUS_OBJECT_PATH_MAX
];
1081 iface
= wpa_s
->parent
->global
->dbus
;
1083 /* Do nothing if the control interface is not turned on */
1087 if (wpas_dbus_get_group_obj_path(wpa_s
, ssid
, group_obj_path
) < 0)
1090 /* New interface has been created for this group */
1091 msg
= dbus_message_new_signal(wpa_s
->parent
->dbus_new_path
,
1092 WPAS_DBUS_NEW_IFACE_P2PDEVICE
,
1098 dbus_message_iter_init_append(msg
, &iter
);
1099 if (!wpa_dbus_dict_open_write(&iter
, &dict_iter
))
1103 * In case the device supports creating a separate interface the
1104 * DBus client will need to know the object path for the interface
1105 * object this group was created on, so include it here.
1107 if (!wpa_dbus_dict_append_object_path(&dict_iter
,
1109 wpa_s
->dbus_new_path
))
1112 if (!wpa_dbus_dict_append_string(&dict_iter
, "role",
1113 client
? "client" : "GO"))
1116 os_snprintf(net_obj_path
, WPAS_DBUS_OBJECT_PATH_MAX
,
1117 "%s/" WPAS_DBUS_NEW_NETWORKS_PART
"/%u",
1118 wpa_s
->parent
->dbus_new_path
, network_id
);
1120 if (!wpa_dbus_dict_append_object_path(&dict_iter
, "group_object",
1122 !wpa_dbus_dict_append_object_path(&dict_iter
, "network_object",
1124 !wpa_dbus_dict_close_write(&iter
, &dict_iter
))
1127 dbus_connection_send(iface
->con
, msg
, NULL
);
1130 dbus_message_unref(msg
);
1136 * Method to emit GONeogtiation Success or Failure signals based
1138 * @status: Status of the GO neg request. 0 for success, other for errors.
1140 void wpas_dbus_signal_p2p_go_neg_resp(struct wpa_supplicant
*wpa_s
,
1141 struct p2p_go_neg_results
*res
)
1144 DBusMessageIter iter
, dict_iter
;
1145 DBusMessageIter iter_dict_entry
, iter_dict_val
, iter_dict_array
;
1146 struct wpas_dbus_priv
*iface
;
1147 char peer_obj_path
[WPAS_DBUS_OBJECT_PATH_MAX
], *path
;
1148 dbus_int32_t freqs
[P2P_MAX_CHANNELS
];
1149 dbus_int32_t
*f_array
= freqs
;
1152 iface
= wpa_s
->global
->dbus
;
1154 os_memset(freqs
, 0, sizeof(freqs
));
1155 /* Do nothing if the control interface is not turned on */
1159 os_snprintf(peer_obj_path
, WPAS_DBUS_OBJECT_PATH_MAX
,
1160 "%s/" WPAS_DBUS_NEW_P2P_PEERS_PART
"/" COMPACT_MACSTR
,
1161 wpa_s
->dbus_new_path
, MAC2STR(res
->peer_device_addr
));
1162 path
= peer_obj_path
;
1164 msg
= dbus_message_new_signal(wpa_s
->dbus_new_path
,
1165 WPAS_DBUS_NEW_IFACE_P2PDEVICE
,
1166 res
->status
? "GONegotiationFailure" :
1167 "GONegotiationSuccess");
1171 dbus_message_iter_init_append(msg
, &iter
);
1172 if (!wpa_dbus_dict_open_write(&iter
, &dict_iter
))
1174 if (!wpa_dbus_dict_append_object_path(&dict_iter
, "peer_object",
1176 !wpa_dbus_dict_append_int32(&dict_iter
, "status", res
->status
))
1181 int freq_list_num
= 0;
1184 if (!wpa_dbus_dict_append_byte_array(
1185 &dict_iter
, "passphrase",
1186 (const char *) res
->passphrase
,
1187 sizeof(res
->passphrase
)))
1191 if (!wpa_dbus_dict_append_string(&dict_iter
, "role_go",
1192 res
->role_go
? "GO" :
1194 !wpa_dbus_dict_append_int32(&dict_iter
, "frequency",
1196 !wpa_dbus_dict_append_byte_array(&dict_iter
, "ssid",
1197 (const char *) res
->ssid
,
1199 !wpa_dbus_dict_append_byte_array(&dict_iter
,
1202 res
->peer_device_addr
,
1204 !wpa_dbus_dict_append_byte_array(&dict_iter
,
1205 "peer_interface_addr",
1207 res
->peer_interface_addr
,
1209 !wpa_dbus_dict_append_string(&dict_iter
, "wps_method",
1210 p2p_wps_method_text(
1214 for (i
= 0; i
< P2P_MAX_CHANNELS
; i
++) {
1215 if (res
->freq_list
[i
]) {
1216 freqs
[i
] = res
->freq_list
[i
];
1221 if (!wpa_dbus_dict_begin_array(&dict_iter
,
1223 DBUS_TYPE_INT32_AS_STRING
,
1229 if (!dbus_message_iter_append_fixed_array(&iter_dict_array
,
1235 if (!wpa_dbus_dict_end_array(&dict_iter
,
1241 if (!wpa_dbus_dict_append_int32(&dict_iter
, "persistent_group",
1242 res
->persistent_group
) ||
1243 !wpa_dbus_dict_append_uint32(&dict_iter
,
1244 "peer_config_timeout",
1245 res
->peer_config_timeout
))
1249 if (!wpa_dbus_dict_close_write(&iter
, &dict_iter
))
1252 dbus_connection_send(iface
->con
, msg
, NULL
);
1254 dbus_message_unref(msg
);
1260 * Method to emit Invitation Result signal based on status and
1262 * @status: Status of the Invite request. 0 for success, other
1264 * @bssid : Basic Service Set Identifier
1266 void wpas_dbus_signal_p2p_invitation_result(struct wpa_supplicant
*wpa_s
,
1267 int status
, const u8
*bssid
)
1270 DBusMessageIter iter
, dict_iter
;
1271 struct wpas_dbus_priv
*iface
;
1273 wpa_printf(MSG_INFO
, "%s\n", __func__
);
1275 iface
= wpa_s
->global
->dbus
;
1276 /* Do nothing if the control interface is not turned on */
1280 msg
= dbus_message_new_signal(wpa_s
->dbus_new_path
,
1281 WPAS_DBUS_NEW_IFACE_P2PDEVICE
,
1282 "InvitationResult");
1287 dbus_message_iter_init_append(msg
, &iter
);
1288 if (!wpa_dbus_dict_open_write(&iter
, &dict_iter
))
1291 if (!wpa_dbus_dict_append_int32(&dict_iter
, "status", status
))
1294 if (!wpa_dbus_dict_append_byte_array(&dict_iter
, "BSSID",
1295 (const char *) bssid
,
1299 if (!wpa_dbus_dict_close_write(&iter
, &dict_iter
))
1302 dbus_connection_send(iface
->con
, msg
, NULL
);
1305 dbus_message_unref(msg
);
1311 * Method to emit a signal for a peer joining the group.
1312 * The signal will carry path to the group member object
1313 * constructed using p2p i/f addr used for connecting.
1315 * @wpa_s: %wpa_supplicant network interface data
1316 * @member_addr: addr (p2p i/f) of the peer joining the group
1318 void wpas_dbus_signal_p2p_peer_joined(struct wpa_supplicant
*wpa_s
,
1321 struct wpas_dbus_priv
*iface
;
1323 DBusMessageIter iter
;
1324 char groupmember_obj_path
[WPAS_DBUS_OBJECT_PATH_MAX
], *path
;
1326 iface
= wpa_s
->global
->dbus
;
1328 /* Do nothing if the control interface is not turned on */
1332 if (!wpa_s
->dbus_groupobj_path
)
1335 os_snprintf(groupmember_obj_path
, WPAS_DBUS_OBJECT_PATH_MAX
,
1336 "%s/" WPAS_DBUS_NEW_P2P_GROUPMEMBERS_PART
"/"
1338 wpa_s
->dbus_groupobj_path
, MAC2STR(member
));
1340 msg
= dbus_message_new_signal(wpa_s
->dbus_groupobj_path
,
1341 WPAS_DBUS_NEW_IFACE_P2P_GROUP
,
1346 dbus_message_iter_init_append(msg
, &iter
);
1347 path
= groupmember_obj_path
;
1348 if (!dbus_message_iter_append_basic(&iter
, DBUS_TYPE_OBJECT_PATH
,
1352 dbus_connection_send(iface
->con
, msg
, NULL
);
1354 dbus_message_unref(msg
);
1358 wpa_printf(MSG_ERROR
, "dbus: Failed to construct signal");
1359 dbus_message_unref(msg
);
1365 * Method to emit a signal for a peer disconnecting the group.
1366 * The signal will carry path to the group member object
1367 * constructed using p2p i/f addr used for connecting.
1369 * @wpa_s: %wpa_supplicant network interface data
1370 * @member_addr: addr (p2p i/f) of the peer joining the group
1372 void wpas_dbus_signal_p2p_peer_disconnected(struct wpa_supplicant
*wpa_s
,
1375 struct wpas_dbus_priv
*iface
;
1377 DBusMessageIter iter
;
1378 char groupmember_obj_path
[WPAS_DBUS_OBJECT_PATH_MAX
], *path
;
1380 iface
= wpa_s
->global
->dbus
;
1382 /* Do nothing if the control interface is not turned on */
1386 if (!wpa_s
->dbus_groupobj_path
)
1389 os_snprintf(groupmember_obj_path
, WPAS_DBUS_OBJECT_PATH_MAX
,
1390 "%s/" WPAS_DBUS_NEW_P2P_GROUPMEMBERS_PART
"/"
1392 wpa_s
->dbus_groupobj_path
, MAC2STR(member
));
1394 msg
= dbus_message_new_signal(wpa_s
->dbus_groupobj_path
,
1395 WPAS_DBUS_NEW_IFACE_P2P_GROUP
,
1396 "PeerDisconnected");
1400 dbus_message_iter_init_append(msg
, &iter
);
1401 path
= groupmember_obj_path
;
1402 if (!dbus_message_iter_append_basic(&iter
, DBUS_TYPE_OBJECT_PATH
,
1406 dbus_connection_send(iface
->con
, msg
, NULL
);
1408 dbus_message_unref(msg
);
1412 wpa_printf(MSG_ERROR
, "dbus: Failed to construct PeerDisconnected "
1414 dbus_message_unref(msg
);
1420 * Method to emit a signal for a service discovery request.
1421 * The signal will carry station address, frequency, dialog token,
1422 * update indicator and it tlvs
1424 * @wpa_s: %wpa_supplicant network interface data
1425 * @sa: station addr (p2p i/f) of the peer
1426 * @dialog_token: service discovery request dialog token
1427 * @update_indic: service discovery request update indicator
1428 * @tlvs: service discovery request genrated byte array of tlvs
1429 * @tlvs_len: service discovery request tlvs length
1431 void wpas_dbus_signal_p2p_sd_request(struct wpa_supplicant
*wpa_s
,
1432 int freq
, const u8
*sa
, u8 dialog_token
,
1433 u16 update_indic
, const u8
*tlvs
,
1437 DBusMessageIter iter
, dict_iter
;
1438 struct wpas_dbus_priv
*iface
;
1439 char peer_obj_path
[WPAS_DBUS_OBJECT_PATH_MAX
], *path
;
1440 iface
= wpa_s
->global
->dbus
;
1442 /* Do nothing if the control interface is not turned on */
1446 msg
= dbus_message_new_signal(wpa_s
->dbus_new_path
,
1447 WPAS_DBUS_NEW_IFACE_P2PDEVICE
,
1448 "ServiceDiscoveryRequest");
1452 /* Check if this is a known peer */
1453 if (!p2p_peer_known(wpa_s
->global
->p2p
, sa
))
1456 os_snprintf(peer_obj_path
, WPAS_DBUS_OBJECT_PATH_MAX
,
1457 "%s/" WPAS_DBUS_NEW_P2P_PEERS_PART
"/"
1458 COMPACT_MACSTR
, wpa_s
->dbus_new_path
, MAC2STR(sa
));
1460 path
= peer_obj_path
;
1462 dbus_message_iter_init_append(msg
, &iter
);
1463 if (!wpa_dbus_dict_open_write(&iter
, &dict_iter
))
1467 if (!wpa_dbus_dict_append_object_path(&dict_iter
, "peer_object",
1469 !wpa_dbus_dict_append_int32(&dict_iter
, "frequency", freq
) ||
1470 !wpa_dbus_dict_append_int32(&dict_iter
, "dialog_token",
1472 !wpa_dbus_dict_append_uint16(&dict_iter
, "update_indicator",
1474 !wpa_dbus_dict_append_byte_array(&dict_iter
, "tlvs",
1475 (const char *) tlvs
,
1477 !wpa_dbus_dict_close_write(&iter
, &dict_iter
))
1480 dbus_connection_send(iface
->con
, msg
, NULL
);
1481 dbus_message_unref(msg
);
1484 wpa_printf(MSG_ERROR
, "dbus: Failed to construct signal");
1485 dbus_message_unref(msg
);
1491 * Method to emit a signal for a service discovery response.
1492 * The signal will carry station address, update indicator and it
1495 * @wpa_s: %wpa_supplicant network interface data
1496 * @sa: station addr (p2p i/f) of the peer
1497 * @update_indic: service discovery request update indicator
1498 * @tlvs: service discovery request genrated byte array of tlvs
1499 * @tlvs_len: service discovery request tlvs length
1501 void wpas_dbus_signal_p2p_sd_response(struct wpa_supplicant
*wpa_s
,
1502 const u8
*sa
, u16 update_indic
,
1503 const u8
*tlvs
, size_t tlvs_len
)
1506 DBusMessageIter iter
, dict_iter
;
1507 struct wpas_dbus_priv
*iface
;
1508 char peer_obj_path
[WPAS_DBUS_OBJECT_PATH_MAX
], *path
;
1509 iface
= wpa_s
->global
->dbus
;
1511 /* Do nothing if the control interface is not turned on */
1515 msg
= dbus_message_new_signal(wpa_s
->dbus_new_path
,
1516 WPAS_DBUS_NEW_IFACE_P2PDEVICE
,
1517 "ServiceDiscoveryResponse");
1521 /* Check if this is a known peer */
1522 if (!p2p_peer_known(wpa_s
->global
->p2p
, sa
))
1525 os_snprintf(peer_obj_path
, WPAS_DBUS_OBJECT_PATH_MAX
,
1526 "%s/" WPAS_DBUS_NEW_P2P_PEERS_PART
"/"
1527 COMPACT_MACSTR
, wpa_s
->dbus_new_path
, MAC2STR(sa
));
1529 path
= peer_obj_path
;
1531 dbus_message_iter_init_append(msg
, &iter
);
1532 if (!wpa_dbus_dict_open_write(&iter
, &dict_iter
))
1535 if (!wpa_dbus_dict_append_object_path(&dict_iter
, "peer_object",
1537 !wpa_dbus_dict_append_uint16(&dict_iter
, "update_indicator",
1539 !wpa_dbus_dict_append_byte_array(&dict_iter
, "tlvs",
1540 (const char *) tlvs
,
1542 !wpa_dbus_dict_close_write(&iter
, &dict_iter
))
1546 dbus_connection_send(iface
->con
, msg
, NULL
);
1547 dbus_message_unref(msg
);
1550 wpa_printf(MSG_ERROR
, "dbus: Failed to construct signal");
1551 dbus_message_unref(msg
);
1555 * wpas_dbus_signal_persistent_group - Send a persistent group related
1557 * @wpa_s: %wpa_supplicant network interface data
1558 * @id: new persistent group id
1559 * @sig_name: signal name - PersistentGroupAdded, PersistentGroupRemoved
1560 * @properties: determines if add second argument with object properties
1562 * Notify listeners about an event related to persistent groups.
1564 static void wpas_dbus_signal_persistent_group(struct wpa_supplicant
*wpa_s
,
1565 int id
, const char *sig_name
,
1568 struct wpas_dbus_priv
*iface
;
1570 DBusMessageIter iter
;
1571 char pgrp_obj_path
[WPAS_DBUS_OBJECT_PATH_MAX
], *path
;
1573 iface
= wpa_s
->global
->dbus
;
1575 /* Do nothing if the control interface is not turned on */
1579 os_snprintf(pgrp_obj_path
, WPAS_DBUS_OBJECT_PATH_MAX
,
1580 "%s/" WPAS_DBUS_NEW_PERSISTENT_GROUPS_PART
"/%u",
1581 wpa_s
->dbus_new_path
, id
);
1583 msg
= dbus_message_new_signal(wpa_s
->dbus_new_path
,
1584 WPAS_DBUS_NEW_IFACE_P2PDEVICE
,
1589 dbus_message_iter_init_append(msg
, &iter
);
1590 path
= pgrp_obj_path
;
1591 if (!dbus_message_iter_append_basic(&iter
, DBUS_TYPE_OBJECT_PATH
,
1596 if (!wpa_dbus_get_object_properties(
1597 iface
, pgrp_obj_path
,
1598 WPAS_DBUS_NEW_IFACE_PERSISTENT_GROUP
, &iter
))
1602 dbus_connection_send(iface
->con
, msg
, NULL
);
1604 dbus_message_unref(msg
);
1608 wpa_printf(MSG_ERROR
, "dbus: Failed to construct signal");
1609 dbus_message_unref(msg
);
1614 * wpas_dbus_signal_persistent_group_added - Send a persistent_group
1616 * @wpa_s: %wpa_supplicant network interface data
1617 * @id: new persistent group id
1619 * Notify listeners about addition of a new persistent group.
1621 static void wpas_dbus_signal_persistent_group_added(
1622 struct wpa_supplicant
*wpa_s
, int id
)
1624 wpas_dbus_signal_persistent_group(wpa_s
, id
, "PersistentGroupAdded",
1630 * wpas_dbus_signal_persistent_group_removed - Send a persistent_group
1632 * @wpa_s: %wpa_supplicant network interface data
1633 * @id: persistent group id
1635 * Notify listeners about removal of a persistent group.
1637 static void wpas_dbus_signal_persistent_group_removed(
1638 struct wpa_supplicant
*wpa_s
, int id
)
1640 wpas_dbus_signal_persistent_group(wpa_s
, id
, "PersistentGroupRemoved",
1646 * wpas_dbus_signal_p2p_wps_failed - Signals WpsFailed event
1647 * @wpa_s: %wpa_supplicant network interface data
1649 * Sends Event dbus signal with name "fail" and dictionary containing
1650 * "msg" field with fail message number (int32) as arguments
1652 void wpas_dbus_signal_p2p_wps_failed(struct wpa_supplicant
*wpa_s
,
1653 struct wps_event_fail
*fail
)
1657 DBusMessageIter iter
, dict_iter
;
1658 struct wpas_dbus_priv
*iface
;
1661 iface
= wpa_s
->global
->dbus
;
1663 /* Do nothing if the control interface is not turned on */
1667 msg
= dbus_message_new_signal(wpa_s
->dbus_new_path
,
1668 WPAS_DBUS_NEW_IFACE_P2PDEVICE
,
1673 dbus_message_iter_init_append(msg
, &iter
);
1675 if (!dbus_message_iter_append_basic(&iter
, DBUS_TYPE_STRING
, &key
) ||
1676 !wpa_dbus_dict_open_write(&iter
, &dict_iter
) ||
1677 !wpa_dbus_dict_append_int32(&dict_iter
, "msg", fail
->msg
) ||
1678 !wpa_dbus_dict_append_int16(&dict_iter
, "config_error",
1679 fail
->config_error
) ||
1680 !wpa_dbus_dict_close_write(&iter
, &dict_iter
))
1681 wpa_printf(MSG_ERROR
, "dbus: Failed to construct signal");
1683 dbus_connection_send(iface
->con
, msg
, NULL
);
1685 dbus_message_unref(msg
);
1688 #endif /*CONFIG_P2P*/
1692 * wpas_dbus_signal_prop_changed - Signals change of property
1693 * @wpa_s: %wpa_supplicant network interface data
1694 * @property: indicates which property has changed
1696 * Sends PropertyChanged signals with path, interface and arguments
1697 * depending on which property has changed.
1699 void wpas_dbus_signal_prop_changed(struct wpa_supplicant
*wpa_s
,
1700 enum wpas_dbus_prop property
)
1704 if (wpa_s
->dbus_new_path
== NULL
)
1705 return; /* Skip signal since D-Bus setup is not yet ready */
1708 case WPAS_DBUS_PROP_AP_SCAN
:
1711 case WPAS_DBUS_PROP_SCANNING
:
1714 case WPAS_DBUS_PROP_STATE
:
1717 case WPAS_DBUS_PROP_CURRENT_BSS
:
1718 prop
= "CurrentBSS";
1720 case WPAS_DBUS_PROP_CURRENT_NETWORK
:
1721 prop
= "CurrentNetwork";
1723 case WPAS_DBUS_PROP_BSSS
:
1726 case WPAS_DBUS_PROP_CURRENT_AUTH_MODE
:
1727 prop
= "CurrentAuthMode";
1730 wpa_printf(MSG_ERROR
, "dbus: %s: Unknown Property value %d",
1731 __func__
, property
);
1735 wpa_dbus_mark_property_changed(wpa_s
->global
->dbus
,
1736 wpa_s
->dbus_new_path
,
1737 WPAS_DBUS_NEW_IFACE_INTERFACE
, prop
);
1742 * wpas_dbus_bss_signal_prop_changed - Signals change of BSS property
1743 * @wpa_s: %wpa_supplicant network interface data
1744 * @property: indicates which property has changed
1745 * @id: unique BSS identifier
1747 * Sends PropertyChanged signals with path, interface, and arguments depending
1748 * on which property has changed.
1750 void wpas_dbus_bss_signal_prop_changed(struct wpa_supplicant
*wpa_s
,
1751 enum wpas_dbus_bss_prop property
,
1754 char path
[WPAS_DBUS_OBJECT_PATH_MAX
];
1758 case WPAS_DBUS_BSS_PROP_SIGNAL
:
1761 case WPAS_DBUS_BSS_PROP_FREQ
:
1764 case WPAS_DBUS_BSS_PROP_MODE
:
1767 case WPAS_DBUS_BSS_PROP_PRIVACY
:
1770 case WPAS_DBUS_BSS_PROP_RATES
:
1773 case WPAS_DBUS_BSS_PROP_WPA
:
1776 case WPAS_DBUS_BSS_PROP_RSN
:
1779 case WPAS_DBUS_BSS_PROP_IES
:
1783 wpa_printf(MSG_ERROR
, "dbus: %s: Unknown Property value %d",
1784 __func__
, property
);
1788 os_snprintf(path
, WPAS_DBUS_OBJECT_PATH_MAX
,
1789 "%s/" WPAS_DBUS_NEW_BSSIDS_PART
"/%u",
1790 wpa_s
->dbus_new_path
, id
);
1792 wpa_dbus_mark_property_changed(wpa_s
->global
->dbus
, path
,
1793 WPAS_DBUS_NEW_IFACE_BSS
, prop
);
1798 * wpas_dbus_signal_debug_level_changed - Signals change of debug param
1799 * @global: wpa_global structure
1801 * Sends PropertyChanged signals informing that debug level has changed.
1803 void wpas_dbus_signal_debug_level_changed(struct wpa_global
*global
)
1805 wpa_dbus_mark_property_changed(global
->dbus
, WPAS_DBUS_NEW_PATH
,
1806 WPAS_DBUS_NEW_INTERFACE
,
1812 * wpas_dbus_signal_debug_timestamp_changed - Signals change of debug param
1813 * @global: wpa_global structure
1815 * Sends PropertyChanged signals informing that debug timestamp has changed.
1817 void wpas_dbus_signal_debug_timestamp_changed(struct wpa_global
*global
)
1819 wpa_dbus_mark_property_changed(global
->dbus
, WPAS_DBUS_NEW_PATH
,
1820 WPAS_DBUS_NEW_INTERFACE
,
1826 * wpas_dbus_signal_debug_show_keys_changed - Signals change of debug param
1827 * @global: wpa_global structure
1829 * Sends PropertyChanged signals informing that debug show_keys has changed.
1831 void wpas_dbus_signal_debug_show_keys_changed(struct wpa_global
*global
)
1833 wpa_dbus_mark_property_changed(global
->dbus
, WPAS_DBUS_NEW_PATH
,
1834 WPAS_DBUS_NEW_INTERFACE
,
1839 static void wpas_dbus_register(struct wpa_dbus_object_desc
*obj_desc
,
1841 WPADBusArgumentFreeFunction priv_free
,
1842 const struct wpa_dbus_method_desc
*methods
,
1843 const struct wpa_dbus_property_desc
*properties
,
1844 const struct wpa_dbus_signal_desc
*signals
)
1848 obj_desc
->user_data
= priv
;
1849 obj_desc
->user_data_free_func
= priv_free
;
1850 obj_desc
->methods
= methods
;
1851 obj_desc
->properties
= properties
;
1852 obj_desc
->signals
= signals
;
1854 for (n
= 0; properties
&& properties
->dbus_property
; properties
++)
1857 obj_desc
->prop_changed_flags
= os_zalloc(n
);
1858 if (!obj_desc
->prop_changed_flags
)
1859 wpa_printf(MSG_DEBUG
, "dbus: %s: can't register handlers",
1864 static const struct wpa_dbus_method_desc wpas_dbus_global_methods
[] = {
1865 { "CreateInterface", WPAS_DBUS_NEW_INTERFACE
,
1866 (WPADBusMethodHandler
) &wpas_dbus_handler_create_interface
,
1868 { "args", "a{sv}", ARG_IN
},
1869 { "path", "o", ARG_OUT
},
1873 { "RemoveInterface", WPAS_DBUS_NEW_INTERFACE
,
1874 (WPADBusMethodHandler
) &wpas_dbus_handler_remove_interface
,
1876 { "path", "o", ARG_IN
},
1880 { "GetInterface", WPAS_DBUS_NEW_INTERFACE
,
1881 (WPADBusMethodHandler
) &wpas_dbus_handler_get_interface
,
1883 { "ifname", "s", ARG_IN
},
1884 { "path", "o", ARG_OUT
},
1888 { NULL
, NULL
, NULL
, { END_ARGS
} }
1891 static const struct wpa_dbus_property_desc wpas_dbus_global_properties
[] = {
1892 { "DebugLevel", WPAS_DBUS_NEW_INTERFACE
, "s",
1893 wpas_dbus_getter_debug_level
,
1894 wpas_dbus_setter_debug_level
1896 { "DebugTimestamp", WPAS_DBUS_NEW_INTERFACE
, "b",
1897 wpas_dbus_getter_debug_timestamp
,
1898 wpas_dbus_setter_debug_timestamp
1900 { "DebugShowKeys", WPAS_DBUS_NEW_INTERFACE
, "b",
1901 wpas_dbus_getter_debug_show_keys
,
1902 wpas_dbus_setter_debug_show_keys
1904 { "Interfaces", WPAS_DBUS_NEW_INTERFACE
, "ao",
1905 wpas_dbus_getter_interfaces
,
1908 { "EapMethods", WPAS_DBUS_NEW_INTERFACE
, "as",
1909 wpas_dbus_getter_eap_methods
,
1912 { NULL
, NULL
, NULL
, NULL
, NULL
}
1915 static const struct wpa_dbus_signal_desc wpas_dbus_global_signals
[] = {
1916 { "InterfaceAdded", WPAS_DBUS_NEW_INTERFACE
,
1918 { "path", "o", ARG_OUT
},
1919 { "properties", "a{sv}", ARG_OUT
},
1923 { "InterfaceRemoved", WPAS_DBUS_NEW_INTERFACE
,
1925 { "path", "o", ARG_OUT
},
1929 { "NetworkRequest", WPAS_DBUS_NEW_IFACE_INTERFACE
,
1931 { "path", "o", ARG_OUT
},
1932 { "field", "s", ARG_OUT
},
1933 { "text", "s", ARG_OUT
},
1937 /* Deprecated: use org.freedesktop.DBus.Properties.PropertiesChanged */
1938 { "PropertiesChanged", WPAS_DBUS_NEW_INTERFACE
,
1940 { "properties", "a{sv}", ARG_OUT
},
1944 { NULL
, NULL
, { END_ARGS
} }
1949 * wpas_dbus_ctrl_iface_init - Initialize dbus control interface
1950 * @global: Pointer to global data from wpa_supplicant_init()
1951 * Returns: 0 on success or -1 on failure
1953 * Initialize the dbus control interface for wpa_supplicantand and start
1954 * receiving commands from external programs over the bus.
1956 int wpas_dbus_ctrl_iface_init(struct wpas_dbus_priv
*priv
)
1958 struct wpa_dbus_object_desc
*obj_desc
;
1961 obj_desc
= os_zalloc(sizeof(struct wpa_dbus_object_desc
));
1963 wpa_printf(MSG_ERROR
, "Not enough memory "
1964 "to create object description");
1968 wpas_dbus_register(obj_desc
, priv
->global
, NULL
,
1969 wpas_dbus_global_methods
,
1970 wpas_dbus_global_properties
,
1971 wpas_dbus_global_signals
);
1973 wpa_printf(MSG_DEBUG
, "dbus: Register D-Bus object '%s'",
1974 WPAS_DBUS_NEW_PATH
);
1975 ret
= wpa_dbus_ctrl_iface_init(priv
, WPAS_DBUS_NEW_PATH
,
1976 WPAS_DBUS_NEW_SERVICE
,
1979 free_dbus_object_desc(obj_desc
);
1981 priv
->dbus_new_initialized
= 1;
1988 * wpas_dbus_ctrl_iface_deinit - Deinitialize dbus ctrl interface for
1990 * @iface: Pointer to dbus private data from wpas_dbus_init()
1992 * Deinitialize the dbus control interface that was initialized with
1993 * wpas_dbus_ctrl_iface_init().
1995 void wpas_dbus_ctrl_iface_deinit(struct wpas_dbus_priv
*iface
)
1997 if (!iface
->dbus_new_initialized
)
1999 wpa_printf(MSG_DEBUG
, "dbus: Unregister D-Bus object '%s'",
2000 WPAS_DBUS_NEW_PATH
);
2001 dbus_connection_unregister_object_path(iface
->con
,
2002 WPAS_DBUS_NEW_PATH
);
2006 static void wpa_dbus_free(void *ptr
)
2012 static const struct wpa_dbus_property_desc wpas_dbus_network_properties
[] = {
2013 { "Properties", WPAS_DBUS_NEW_IFACE_NETWORK
, "a{sv}",
2014 wpas_dbus_getter_network_properties
,
2015 wpas_dbus_setter_network_properties
2017 { "Enabled", WPAS_DBUS_NEW_IFACE_NETWORK
, "b",
2018 wpas_dbus_getter_enabled
,
2019 wpas_dbus_setter_enabled
2021 { NULL
, NULL
, NULL
, NULL
, NULL
}
2025 static const struct wpa_dbus_signal_desc wpas_dbus_network_signals
[] = {
2026 /* Deprecated: use org.freedesktop.DBus.Properties.PropertiesChanged */
2027 { "PropertiesChanged", WPAS_DBUS_NEW_IFACE_NETWORK
,
2029 { "properties", "a{sv}", ARG_OUT
},
2033 { NULL
, NULL
, { END_ARGS
} }
2038 * wpas_dbus_register_network - Register a configured network with dbus
2039 * @wpa_s: wpa_supplicant interface structure
2040 * @ssid: network configuration data
2041 * Returns: 0 on success, -1 on failure
2043 * Registers network representing object with dbus
2045 int wpas_dbus_register_network(struct wpa_supplicant
*wpa_s
,
2046 struct wpa_ssid
*ssid
)
2048 struct wpas_dbus_priv
*ctrl_iface
;
2049 struct wpa_dbus_object_desc
*obj_desc
;
2050 struct network_handler_args
*arg
;
2051 char net_obj_path
[WPAS_DBUS_OBJECT_PATH_MAX
];
2055 * If it is a persistent group register it as such.
2056 * This is to handle cases where an interface is being initialized
2057 * with a list of networks read from config.
2059 if (network_is_persistent_group(ssid
))
2060 return wpas_dbus_register_persistent_group(wpa_s
, ssid
);
2061 #endif /* CONFIG_P2P */
2063 /* Do nothing if the control interface is not turned on */
2064 if (wpa_s
== NULL
|| wpa_s
->global
== NULL
)
2066 ctrl_iface
= wpa_s
->global
->dbus
;
2067 if (ctrl_iface
== NULL
)
2070 os_snprintf(net_obj_path
, WPAS_DBUS_OBJECT_PATH_MAX
,
2071 "%s/" WPAS_DBUS_NEW_NETWORKS_PART
"/%u",
2072 wpa_s
->dbus_new_path
, ssid
->id
);
2074 wpa_printf(MSG_DEBUG
, "dbus: Register network object '%s'",
2076 obj_desc
= os_zalloc(sizeof(struct wpa_dbus_object_desc
));
2078 wpa_printf(MSG_ERROR
, "Not enough memory "
2079 "to create object description");
2083 /* allocate memory for handlers arguments */
2084 arg
= os_zalloc(sizeof(struct network_handler_args
));
2086 wpa_printf(MSG_ERROR
, "Not enough memory "
2087 "to create arguments for method");
2094 wpas_dbus_register(obj_desc
, arg
, wpa_dbus_free
, NULL
,
2095 wpas_dbus_network_properties
,
2096 wpas_dbus_network_signals
);
2098 if (wpa_dbus_register_object_per_iface(ctrl_iface
, net_obj_path
,
2099 wpa_s
->ifname
, obj_desc
))
2102 wpas_dbus_signal_network_added(wpa_s
, ssid
->id
);
2107 free_dbus_object_desc(obj_desc
);
2113 * wpas_dbus_unregister_network - Unregister a configured network from dbus
2114 * @wpa_s: wpa_supplicant interface structure
2116 * Returns: 0 on success, -1 on failure
2118 * Unregisters network representing object from dbus
2120 int wpas_dbus_unregister_network(struct wpa_supplicant
*wpa_s
, int nid
)
2122 struct wpas_dbus_priv
*ctrl_iface
;
2123 char net_obj_path
[WPAS_DBUS_OBJECT_PATH_MAX
];
2126 struct wpa_ssid
*ssid
;
2128 ssid
= wpa_config_get_network(wpa_s
->conf
, nid
);
2130 /* If it is a persistent group unregister it as such */
2131 if (ssid
&& network_is_persistent_group(ssid
))
2132 return wpas_dbus_unregister_persistent_group(wpa_s
, nid
);
2133 #endif /* CONFIG_P2P */
2135 /* Do nothing if the control interface is not turned on */
2136 if (wpa_s
->global
== NULL
|| wpa_s
->dbus_new_path
== NULL
)
2138 ctrl_iface
= wpa_s
->global
->dbus
;
2139 if (ctrl_iface
== NULL
)
2142 os_snprintf(net_obj_path
, WPAS_DBUS_OBJECT_PATH_MAX
,
2143 "%s/" WPAS_DBUS_NEW_NETWORKS_PART
"/%u",
2144 wpa_s
->dbus_new_path
, nid
);
2146 wpa_printf(MSG_DEBUG
, "dbus: Unregister network object '%s'",
2148 ret
= wpa_dbus_unregister_object_per_iface(ctrl_iface
, net_obj_path
);
2151 wpas_dbus_signal_network_removed(wpa_s
, nid
);
2157 static const struct wpa_dbus_property_desc wpas_dbus_bss_properties
[] = {
2158 { "SSID", WPAS_DBUS_NEW_IFACE_BSS
, "ay",
2159 wpas_dbus_getter_bss_ssid
,
2162 { "BSSID", WPAS_DBUS_NEW_IFACE_BSS
, "ay",
2163 wpas_dbus_getter_bss_bssid
,
2166 { "Privacy", WPAS_DBUS_NEW_IFACE_BSS
, "b",
2167 wpas_dbus_getter_bss_privacy
,
2170 { "Mode", WPAS_DBUS_NEW_IFACE_BSS
, "s",
2171 wpas_dbus_getter_bss_mode
,
2174 { "Signal", WPAS_DBUS_NEW_IFACE_BSS
, "n",
2175 wpas_dbus_getter_bss_signal
,
2178 { "Frequency", WPAS_DBUS_NEW_IFACE_BSS
, "q",
2179 wpas_dbus_getter_bss_frequency
,
2182 { "Rates", WPAS_DBUS_NEW_IFACE_BSS
, "au",
2183 wpas_dbus_getter_bss_rates
,
2186 { "WPA", WPAS_DBUS_NEW_IFACE_BSS
, "a{sv}",
2187 wpas_dbus_getter_bss_wpa
,
2190 { "RSN", WPAS_DBUS_NEW_IFACE_BSS
, "a{sv}",
2191 wpas_dbus_getter_bss_rsn
,
2194 { "IEs", WPAS_DBUS_NEW_IFACE_BSS
, "ay",
2195 wpas_dbus_getter_bss_ies
,
2198 { NULL
, NULL
, NULL
, NULL
, NULL
}
2202 static const struct wpa_dbus_signal_desc wpas_dbus_bss_signals
[] = {
2203 /* Deprecated: use org.freedesktop.DBus.Properties.PropertiesChanged */
2204 { "PropertiesChanged", WPAS_DBUS_NEW_IFACE_BSS
,
2206 { "properties", "a{sv}", ARG_OUT
},
2210 { NULL
, NULL
, { END_ARGS
} }
2215 * wpas_dbus_unregister_bss - Unregister a scanned BSS from dbus
2216 * @wpa_s: wpa_supplicant interface structure
2217 * @bssid: scanned network bssid
2218 * @id: unique BSS identifier
2219 * Returns: 0 on success, -1 on failure
2221 * Unregisters BSS representing object from dbus
2223 int wpas_dbus_unregister_bss(struct wpa_supplicant
*wpa_s
,
2224 u8 bssid
[ETH_ALEN
], unsigned int id
)
2226 struct wpas_dbus_priv
*ctrl_iface
;
2227 char bss_obj_path
[WPAS_DBUS_OBJECT_PATH_MAX
];
2229 /* Do nothing if the control interface is not turned on */
2230 if (wpa_s
== NULL
|| wpa_s
->global
== NULL
)
2232 ctrl_iface
= wpa_s
->global
->dbus
;
2233 if (ctrl_iface
== NULL
)
2236 os_snprintf(bss_obj_path
, WPAS_DBUS_OBJECT_PATH_MAX
,
2237 "%s/" WPAS_DBUS_NEW_BSSIDS_PART
"/%u",
2238 wpa_s
->dbus_new_path
, id
);
2240 wpa_printf(MSG_DEBUG
, "dbus: Unregister BSS object '%s'",
2242 if (wpa_dbus_unregister_object_per_iface(ctrl_iface
, bss_obj_path
)) {
2243 wpa_printf(MSG_ERROR
, "dbus: Cannot unregister BSS object %s",
2248 wpas_dbus_signal_bss_removed(wpa_s
, bss_obj_path
);
2249 wpas_dbus_signal_prop_changed(wpa_s
, WPAS_DBUS_PROP_BSSS
);
2256 * wpas_dbus_register_bss - Register a scanned BSS with dbus
2257 * @wpa_s: wpa_supplicant interface structure
2258 * @bssid: scanned network bssid
2259 * @id: unique BSS identifier
2260 * Returns: 0 on success, -1 on failure
2262 * Registers BSS representing object with dbus
2264 int wpas_dbus_register_bss(struct wpa_supplicant
*wpa_s
,
2265 u8 bssid
[ETH_ALEN
], unsigned int id
)
2267 struct wpas_dbus_priv
*ctrl_iface
;
2268 struct wpa_dbus_object_desc
*obj_desc
;
2269 char bss_obj_path
[WPAS_DBUS_OBJECT_PATH_MAX
];
2270 struct bss_handler_args
*arg
;
2272 /* Do nothing if the control interface is not turned on */
2273 if (wpa_s
== NULL
|| wpa_s
->global
== NULL
)
2275 ctrl_iface
= wpa_s
->global
->dbus
;
2276 if (ctrl_iface
== NULL
)
2279 os_snprintf(bss_obj_path
, WPAS_DBUS_OBJECT_PATH_MAX
,
2280 "%s/" WPAS_DBUS_NEW_BSSIDS_PART
"/%u",
2281 wpa_s
->dbus_new_path
, id
);
2283 obj_desc
= os_zalloc(sizeof(struct wpa_dbus_object_desc
));
2285 wpa_printf(MSG_ERROR
, "Not enough memory "
2286 "to create object description");
2290 arg
= os_zalloc(sizeof(struct bss_handler_args
));
2292 wpa_printf(MSG_ERROR
, "Not enough memory "
2293 "to create arguments for handler");
2299 wpas_dbus_register(obj_desc
, arg
, wpa_dbus_free
, NULL
,
2300 wpas_dbus_bss_properties
,
2301 wpas_dbus_bss_signals
);
2303 wpa_printf(MSG_DEBUG
, "dbus: Register BSS object '%s'",
2305 if (wpa_dbus_register_object_per_iface(ctrl_iface
, bss_obj_path
,
2306 wpa_s
->ifname
, obj_desc
)) {
2307 wpa_printf(MSG_ERROR
,
2308 "Cannot register BSSID dbus object %s.",
2313 wpas_dbus_signal_bss_added(wpa_s
, bss_obj_path
);
2314 wpas_dbus_signal_prop_changed(wpa_s
, WPAS_DBUS_PROP_BSSS
);
2319 free_dbus_object_desc(obj_desc
);
2324 static const struct wpa_dbus_method_desc wpas_dbus_interface_methods
[] = {
2325 { "Scan", WPAS_DBUS_NEW_IFACE_INTERFACE
,
2326 (WPADBusMethodHandler
) &wpas_dbus_handler_scan
,
2328 { "args", "a{sv}", ARG_IN
},
2332 { "Disconnect", WPAS_DBUS_NEW_IFACE_INTERFACE
,
2333 (WPADBusMethodHandler
) &wpas_dbus_handler_disconnect
,
2338 { "AddNetwork", WPAS_DBUS_NEW_IFACE_INTERFACE
,
2339 (WPADBusMethodHandler
) &wpas_dbus_handler_add_network
,
2341 { "args", "a{sv}", ARG_IN
},
2342 { "path", "o", ARG_OUT
},
2346 { "RemoveNetwork", WPAS_DBUS_NEW_IFACE_INTERFACE
,
2347 (WPADBusMethodHandler
) &wpas_dbus_handler_remove_network
,
2349 { "path", "o", ARG_IN
},
2353 { "RemoveAllNetworks", WPAS_DBUS_NEW_IFACE_INTERFACE
,
2354 (WPADBusMethodHandler
) &wpas_dbus_handler_remove_all_networks
,
2359 { "SelectNetwork", WPAS_DBUS_NEW_IFACE_INTERFACE
,
2360 (WPADBusMethodHandler
) &wpas_dbus_handler_select_network
,
2362 { "path", "o", ARG_IN
},
2366 { "NetworkReply", WPAS_DBUS_NEW_IFACE_INTERFACE
,
2367 (WPADBusMethodHandler
) &wpas_dbus_handler_network_reply
,
2369 { "path", "o", ARG_IN
},
2370 { "field", "s", ARG_IN
},
2371 { "value", "s", ARG_IN
},
2375 { "AddBlob", WPAS_DBUS_NEW_IFACE_INTERFACE
,
2376 (WPADBusMethodHandler
) &wpas_dbus_handler_add_blob
,
2378 { "name", "s", ARG_IN
},
2379 { "data", "ay", ARG_IN
},
2383 { "GetBlob", WPAS_DBUS_NEW_IFACE_INTERFACE
,
2384 (WPADBusMethodHandler
) &wpas_dbus_handler_get_blob
,
2386 { "name", "s", ARG_IN
},
2387 { "data", "ay", ARG_OUT
},
2391 { "RemoveBlob", WPAS_DBUS_NEW_IFACE_INTERFACE
,
2392 (WPADBusMethodHandler
) &wpas_dbus_handler_remove_blob
,
2394 { "name", "s", ARG_IN
},
2399 { "Start", WPAS_DBUS_NEW_IFACE_WPS
,
2400 (WPADBusMethodHandler
) &wpas_dbus_handler_wps_start
,
2402 { "args", "a{sv}", ARG_IN
},
2403 { "output", "a{sv}", ARG_OUT
},
2407 #endif /* CONFIG_WPS */
2409 { "Find", WPAS_DBUS_NEW_IFACE_P2PDEVICE
,
2410 (WPADBusMethodHandler
)wpas_dbus_handler_p2p_find
,
2412 { "args", "a{sv}", ARG_IN
},
2416 { "StopFind", WPAS_DBUS_NEW_IFACE_P2PDEVICE
,
2417 (WPADBusMethodHandler
)wpas_dbus_handler_p2p_stop_find
,
2422 { "Listen", WPAS_DBUS_NEW_IFACE_P2PDEVICE
,
2423 (WPADBusMethodHandler
)wpas_dbus_handler_p2p_listen
,
2425 { "timeout", "i", ARG_IN
},
2429 { "ExtendedListen", WPAS_DBUS_NEW_IFACE_P2PDEVICE
,
2430 (WPADBusMethodHandler
)wpas_dbus_handler_p2p_extendedlisten
,
2432 { "args", "a{sv}", ARG_IN
},
2436 { "PresenceRequest", WPAS_DBUS_NEW_IFACE_P2PDEVICE
,
2437 (WPADBusMethodHandler
)wpas_dbus_handler_p2p_presence_request
,
2439 { "args", "a{sv}", ARG_IN
},
2443 { "ProvisionDiscoveryRequest", WPAS_DBUS_NEW_IFACE_P2PDEVICE
,
2444 (WPADBusMethodHandler
)wpas_dbus_handler_p2p_prov_disc_req
,
2446 { "peer", "o", ARG_IN
},
2447 { "config_method", "s", ARG_IN
},
2451 { "Connect", WPAS_DBUS_NEW_IFACE_P2PDEVICE
,
2452 (WPADBusMethodHandler
)wpas_dbus_handler_p2p_connect
,
2454 { "args", "a{sv}", ARG_IN
},
2455 { "generated_pin", "s", ARG_OUT
},
2459 { "GroupAdd", WPAS_DBUS_NEW_IFACE_P2PDEVICE
,
2460 (WPADBusMethodHandler
)wpas_dbus_handler_p2p_group_add
,
2462 { "args", "a{sv}", ARG_IN
},
2466 { "Invite", WPAS_DBUS_NEW_IFACE_P2PDEVICE
,
2467 (WPADBusMethodHandler
)wpas_dbus_handler_p2p_invite
,
2469 { "args", "a{sv}", ARG_IN
},
2473 { "Disconnect", WPAS_DBUS_NEW_IFACE_P2PDEVICE
,
2474 (WPADBusMethodHandler
)wpas_dbus_handler_p2p_disconnect
,
2479 { "RejectPeer", WPAS_DBUS_NEW_IFACE_P2PDEVICE
,
2480 (WPADBusMethodHandler
)wpas_dbus_handler_p2p_rejectpeer
,
2482 { "peer", "o", ARG_IN
},
2486 { "Flush", WPAS_DBUS_NEW_IFACE_P2PDEVICE
,
2487 (WPADBusMethodHandler
)wpas_dbus_handler_p2p_flush
,
2492 { "AddService", WPAS_DBUS_NEW_IFACE_P2PDEVICE
,
2493 (WPADBusMethodHandler
)wpas_dbus_handler_p2p_add_service
,
2495 { "args", "a{sv}", ARG_IN
},
2499 { "DeleteService", WPAS_DBUS_NEW_IFACE_P2PDEVICE
,
2500 (WPADBusMethodHandler
)wpas_dbus_handler_p2p_delete_service
,
2502 { "args", "a{sv}", ARG_IN
},
2506 { "FlushService", WPAS_DBUS_NEW_IFACE_P2PDEVICE
,
2507 (WPADBusMethodHandler
)wpas_dbus_handler_p2p_flush_service
,
2512 { "ServiceDiscoveryRequest", WPAS_DBUS_NEW_IFACE_P2PDEVICE
,
2513 (WPADBusMethodHandler
)wpas_dbus_handler_p2p_service_sd_req
,
2515 { "args", "a{sv}", ARG_IN
},
2519 { "ServiceDiscoveryResponse", WPAS_DBUS_NEW_IFACE_P2PDEVICE
,
2520 (WPADBusMethodHandler
)wpas_dbus_handler_p2p_service_sd_res
,
2522 { "args", "a{sv}", ARG_IN
},
2526 { "ServiceDiscoveryCancelRequest", WPAS_DBUS_NEW_IFACE_P2PDEVICE
,
2527 (WPADBusMethodHandler
)wpas_dbus_handler_p2p_service_sd_cancel_req
,
2529 { "args", "t", ARG_IN
},
2533 { "ServiceUpdate", WPAS_DBUS_NEW_IFACE_P2PDEVICE
,
2534 (WPADBusMethodHandler
)wpas_dbus_handler_p2p_service_update
,
2539 { "ServiceDiscoveryExternal", WPAS_DBUS_NEW_IFACE_P2PDEVICE
,
2540 (WPADBusMethodHandler
)wpas_dbus_handler_p2p_serv_disc_external
,
2542 { "arg", "i", ARG_IN
},
2546 { "ServiceDiscoveryExternal", WPAS_DBUS_NEW_IFACE_P2PDEVICE
,
2547 (WPADBusMethodHandler
)wpas_dbus_handler_p2p_serv_disc_external
,
2549 { "arg", "i", ARG_IN
},
2553 { "AddPersistentGroup", WPAS_DBUS_NEW_IFACE_P2PDEVICE
,
2554 (WPADBusMethodHandler
) wpas_dbus_handler_add_persistent_group
,
2556 { "args", "a{sv}", ARG_IN
},
2557 { "path", "o", ARG_OUT
},
2561 { "RemovePersistentGroup", WPAS_DBUS_NEW_IFACE_P2PDEVICE
,
2562 (WPADBusMethodHandler
) wpas_dbus_handler_remove_persistent_group
,
2564 { "path", "o", ARG_IN
},
2568 { "RemoveAllPersistentGroups", WPAS_DBUS_NEW_IFACE_P2PDEVICE
,
2569 (WPADBusMethodHandler
)
2570 wpas_dbus_handler_remove_all_persistent_groups
,
2575 #endif /* CONFIG_P2P */
2576 { "FlushBSS", WPAS_DBUS_NEW_IFACE_INTERFACE
,
2577 (WPADBusMethodHandler
) &wpas_dbus_handler_flush_bss
,
2579 { "age", "u", ARG_IN
},
2584 { "SubscribeProbeReq", WPAS_DBUS_NEW_IFACE_INTERFACE
,
2585 (WPADBusMethodHandler
) wpas_dbus_handler_subscribe_preq
,
2590 { "UnsubscribeProbeReq", WPAS_DBUS_NEW_IFACE_INTERFACE
,
2591 (WPADBusMethodHandler
) wpas_dbus_handler_unsubscribe_preq
,
2596 #endif /* CONFIG_AP */
2597 { NULL
, NULL
, NULL
, { END_ARGS
} }
2600 static const struct wpa_dbus_property_desc wpas_dbus_interface_properties
[] = {
2601 { "Capabilities", WPAS_DBUS_NEW_IFACE_INTERFACE
, "a{sv}",
2602 wpas_dbus_getter_capabilities
,
2605 { "State", WPAS_DBUS_NEW_IFACE_INTERFACE
, "s",
2606 wpas_dbus_getter_state
,
2609 { "Scanning", WPAS_DBUS_NEW_IFACE_INTERFACE
, "b",
2610 wpas_dbus_getter_scanning
,
2613 { "ApScan", WPAS_DBUS_NEW_IFACE_INTERFACE
, "u",
2614 wpas_dbus_getter_ap_scan
,
2615 wpas_dbus_setter_ap_scan
2617 { "BSSExpireAge", WPAS_DBUS_NEW_IFACE_INTERFACE
, "u",
2618 wpas_dbus_getter_bss_expire_age
,
2619 wpas_dbus_setter_bss_expire_age
2621 { "BSSExpireCount", WPAS_DBUS_NEW_IFACE_INTERFACE
, "u",
2622 wpas_dbus_getter_bss_expire_count
,
2623 wpas_dbus_setter_bss_expire_count
2625 { "Country", WPAS_DBUS_NEW_IFACE_INTERFACE
, "s",
2626 wpas_dbus_getter_country
,
2627 wpas_dbus_setter_country
2629 { "Ifname", WPAS_DBUS_NEW_IFACE_INTERFACE
, "s",
2630 wpas_dbus_getter_ifname
,
2633 { "Driver", WPAS_DBUS_NEW_IFACE_INTERFACE
, "s",
2634 wpas_dbus_getter_driver
,
2637 { "BridgeIfname", WPAS_DBUS_NEW_IFACE_INTERFACE
, "s",
2638 wpas_dbus_getter_bridge_ifname
,
2641 { "CurrentBSS", WPAS_DBUS_NEW_IFACE_INTERFACE
, "o",
2642 wpas_dbus_getter_current_bss
,
2645 { "CurrentNetwork", WPAS_DBUS_NEW_IFACE_INTERFACE
, "o",
2646 wpas_dbus_getter_current_network
,
2649 { "CurrentAuthMode", WPAS_DBUS_NEW_IFACE_INTERFACE
, "s",
2650 wpas_dbus_getter_current_auth_mode
,
2653 { "Blobs", WPAS_DBUS_NEW_IFACE_INTERFACE
, "a{say}",
2654 wpas_dbus_getter_blobs
,
2657 { "BSSs", WPAS_DBUS_NEW_IFACE_INTERFACE
, "ao",
2658 wpas_dbus_getter_bsss
,
2661 { "Networks", WPAS_DBUS_NEW_IFACE_INTERFACE
, "ao",
2662 wpas_dbus_getter_networks
,
2665 { "FastReauth", WPAS_DBUS_NEW_IFACE_INTERFACE
, "b",
2666 wpas_dbus_getter_fast_reauth
,
2667 wpas_dbus_setter_fast_reauth
2669 { "ScanInterval", WPAS_DBUS_NEW_IFACE_INTERFACE
, "i",
2670 wpas_dbus_getter_scan_interval
,
2671 wpas_dbus_setter_scan_interval
2674 { "ProcessCredentials", WPAS_DBUS_NEW_IFACE_WPS
, "b",
2675 wpas_dbus_getter_process_credentials
,
2676 wpas_dbus_setter_process_credentials
2678 #endif /* CONFIG_WPS */
2680 { "P2PDeviceConfig", WPAS_DBUS_NEW_IFACE_P2PDEVICE
, "a{sv}",
2681 wpas_dbus_getter_p2p_device_config
,
2682 wpas_dbus_setter_p2p_device_config
2684 { "Peers", WPAS_DBUS_NEW_IFACE_P2PDEVICE
, "ao",
2685 wpas_dbus_getter_p2p_peers
,
2688 { "Role", WPAS_DBUS_NEW_IFACE_P2PDEVICE
, "s",
2689 wpas_dbus_getter_p2p_role
,
2692 { "Group", WPAS_DBUS_NEW_IFACE_P2PDEVICE
, "o",
2693 wpas_dbus_getter_p2p_group
,
2696 { "PeerGO", WPAS_DBUS_NEW_IFACE_P2PDEVICE
, "o",
2697 wpas_dbus_getter_p2p_peergo
,
2700 { "PersistentGroups", WPAS_DBUS_NEW_IFACE_P2PDEVICE
, "ao",
2701 wpas_dbus_getter_persistent_groups
,
2704 #endif /* CONFIG_P2P */
2705 { NULL
, NULL
, NULL
, NULL
, NULL
}
2708 static const struct wpa_dbus_signal_desc wpas_dbus_interface_signals
[] = {
2709 { "ScanDone", WPAS_DBUS_NEW_IFACE_INTERFACE
,
2711 { "success", "b", ARG_OUT
},
2715 { "BSSAdded", WPAS_DBUS_NEW_IFACE_INTERFACE
,
2717 { "path", "o", ARG_OUT
},
2718 { "properties", "a{sv}", ARG_OUT
},
2722 { "BSSRemoved", WPAS_DBUS_NEW_IFACE_INTERFACE
,
2724 { "path", "o", ARG_OUT
},
2728 { "BlobAdded", WPAS_DBUS_NEW_IFACE_INTERFACE
,
2730 { "name", "s", ARG_OUT
},
2734 { "BlobRemoved", WPAS_DBUS_NEW_IFACE_INTERFACE
,
2736 { "name", "s", ARG_OUT
},
2740 { "NetworkAdded", WPAS_DBUS_NEW_IFACE_INTERFACE
,
2742 { "path", "o", ARG_OUT
},
2743 { "properties", "a{sv}", ARG_OUT
},
2747 { "NetworkRemoved", WPAS_DBUS_NEW_IFACE_INTERFACE
,
2749 { "path", "o", ARG_OUT
},
2753 { "NetworkSelected", WPAS_DBUS_NEW_IFACE_INTERFACE
,
2755 { "path", "o", ARG_OUT
},
2759 /* Deprecated: use org.freedesktop.DBus.Properties.PropertiesChanged */
2760 { "PropertiesChanged", WPAS_DBUS_NEW_IFACE_INTERFACE
,
2762 { "properties", "a{sv}", ARG_OUT
},
2767 { "Event", WPAS_DBUS_NEW_IFACE_WPS
,
2769 { "name", "s", ARG_OUT
},
2770 { "args", "a{sv}", ARG_OUT
},
2774 { "Credentials", WPAS_DBUS_NEW_IFACE_WPS
,
2776 { "credentials", "a{sv}", ARG_OUT
},
2780 /* Deprecated: use org.freedesktop.DBus.Properties.PropertiesChanged */
2781 { "PropertiesChanged", WPAS_DBUS_NEW_IFACE_WPS
,
2783 { "properties", "a{sv}", ARG_OUT
},
2787 #endif /* CONFIG_WPS */
2789 { "P2PStateChanged", WPAS_DBUS_NEW_IFACE_P2PDEVICE
,
2791 { "states", "a{ss}", ARG_OUT
},
2795 { "DeviceFound", WPAS_DBUS_NEW_IFACE_P2PDEVICE
,
2797 { "path", "o", ARG_OUT
},
2798 { "properties", "a{sv}", ARG_OUT
},
2802 { "DeviceLost", WPAS_DBUS_NEW_IFACE_P2PDEVICE
,
2804 { "path", "o", ARG_OUT
},
2808 { "ProvisionDiscoveryRequestDisplayPin", WPAS_DBUS_NEW_IFACE_P2PDEVICE
,
2810 { "peer_object", "o", ARG_OUT
},
2811 { "pin", "s", ARG_OUT
},
2815 { "ProvisionDiscoveryResponseDisplayPin", WPAS_DBUS_NEW_IFACE_P2PDEVICE
,
2817 { "peer_object", "o", ARG_OUT
},
2818 { "pin", "s", ARG_OUT
},
2822 { "ProvisionDiscoveryRequestEnterPin", WPAS_DBUS_NEW_IFACE_P2PDEVICE
,
2824 { "peer_object", "o", ARG_OUT
},
2828 { "ProvisionDiscoveryResponseEnterPin", WPAS_DBUS_NEW_IFACE_P2PDEVICE
,
2830 { "peer_object", "o", ARG_OUT
},
2834 { "ProvisionDiscoveryPBCRequest", WPAS_DBUS_NEW_IFACE_P2PDEVICE
,
2836 { "peer_object", "o", ARG_OUT
},
2840 { "ProvisionDiscoveryPBCResponse", WPAS_DBUS_NEW_IFACE_P2PDEVICE
,
2842 { "peer_object", "o", ARG_OUT
},
2846 { "ProvisionDiscoveryFailure", WPAS_DBUS_NEW_IFACE_P2PDEVICE
,
2848 { "peer_object", "o", ARG_OUT
},
2849 { "status", "i", ARG_OUT
},
2853 { "GroupStarted", WPAS_DBUS_NEW_IFACE_P2PDEVICE
,
2855 { "properties", "a{sv}", ARG_OUT
},
2859 { "GONegotiationSuccess", WPAS_DBUS_NEW_IFACE_P2PDEVICE
,
2864 { "GONegotiationFailure", WPAS_DBUS_NEW_IFACE_P2PDEVICE
,
2866 { "status", "i", ARG_OUT
},
2870 { "GONegotiationRequest", WPAS_DBUS_NEW_IFACE_P2PDEVICE
,
2872 { "path", "o", ARG_OUT
},
2873 { "dev_passwd_id", "i", ARG_OUT
},
2877 { "InvitationResult", WPAS_DBUS_NEW_IFACE_P2PDEVICE
,
2879 { "invite_result", "a{sv}", ARG_OUT
},
2883 { "GroupFinished", WPAS_DBUS_NEW_IFACE_P2PDEVICE
,
2885 { "ifname", "s", ARG_OUT
},
2886 { "role", "s", ARG_OUT
},
2890 { "ServiceDiscoveryRequest", WPAS_DBUS_NEW_IFACE_P2PDEVICE
,
2892 { "sd_request", "a{sv}", ARG_OUT
},
2896 { "ServiceDiscoveryResponse", WPAS_DBUS_NEW_IFACE_P2PDEVICE
,
2898 { "sd_response", "a{sv}", ARG_OUT
},
2902 { "PersistentGroupAdded", WPAS_DBUS_NEW_IFACE_P2PDEVICE
,
2904 { "path", "o", ARG_OUT
},
2905 { "properties", "a{sv}", ARG_OUT
},
2909 { "PersistentGroupRemoved", WPAS_DBUS_NEW_IFACE_P2PDEVICE
,
2911 { "path", "o", ARG_OUT
},
2915 { "WpsFailed", WPAS_DBUS_NEW_IFACE_P2PDEVICE
,
2917 { "name", "s", ARG_OUT
},
2918 { "args", "a{sv}", ARG_OUT
},
2922 #endif /* CONFIG_P2P */
2924 { "ProbeRequest", WPAS_DBUS_NEW_IFACE_INTERFACE
,
2926 { "args", "a{sv}", ARG_OUT
},
2930 #endif /* CONFIG_AP */
2931 { "Certification", WPAS_DBUS_NEW_IFACE_INTERFACE
,
2933 { "certification", "a{sv}", ARG_OUT
},
2937 { NULL
, NULL
, { END_ARGS
} }
2941 int wpas_dbus_register_interface(struct wpa_supplicant
*wpa_s
)
2944 struct wpa_dbus_object_desc
*obj_desc
= NULL
;
2945 struct wpas_dbus_priv
*ctrl_iface
= wpa_s
->global
->dbus
;
2948 /* Do nothing if the control interface is not turned on */
2949 if (ctrl_iface
== NULL
)
2952 /* Create and set the interface's object path */
2953 wpa_s
->dbus_new_path
= os_zalloc(WPAS_DBUS_OBJECT_PATH_MAX
);
2954 if (wpa_s
->dbus_new_path
== NULL
)
2956 next
= ctrl_iface
->next_objid
++;
2957 os_snprintf(wpa_s
->dbus_new_path
, WPAS_DBUS_OBJECT_PATH_MAX
,
2958 WPAS_DBUS_NEW_PATH_INTERFACES
"/%u",
2961 obj_desc
= os_zalloc(sizeof(struct wpa_dbus_object_desc
));
2963 wpa_printf(MSG_ERROR
, "Not enough memory "
2964 "to create object description");
2968 wpas_dbus_register(obj_desc
, wpa_s
, NULL
, wpas_dbus_interface_methods
,
2969 wpas_dbus_interface_properties
,
2970 wpas_dbus_interface_signals
);
2972 wpa_printf(MSG_DEBUG
, "dbus: Register interface object '%s'",
2973 wpa_s
->dbus_new_path
);
2974 if (wpa_dbus_register_object_per_iface(ctrl_iface
,
2975 wpa_s
->dbus_new_path
,
2976 wpa_s
->ifname
, obj_desc
))
2979 wpas_dbus_signal_interface_added(wpa_s
);
2984 os_free(wpa_s
->dbus_new_path
);
2985 wpa_s
->dbus_new_path
= NULL
;
2986 free_dbus_object_desc(obj_desc
);
2991 int wpas_dbus_unregister_interface(struct wpa_supplicant
*wpa_s
)
2993 struct wpas_dbus_priv
*ctrl_iface
;
2995 /* Do nothing if the control interface is not turned on */
2996 if (wpa_s
== NULL
|| wpa_s
->global
== NULL
)
2998 ctrl_iface
= wpa_s
->global
->dbus
;
2999 if (ctrl_iface
== NULL
)
3002 wpa_printf(MSG_DEBUG
, "dbus: Unregister interface object '%s'",
3003 wpa_s
->dbus_new_path
);
3006 if (wpa_s
->preq_notify_peer
) {
3007 wpas_dbus_unsubscribe_noc(ctrl_iface
);
3008 os_free(wpa_s
->preq_notify_peer
);
3009 wpa_s
->preq_notify_peer
= NULL
;
3011 #endif /* CONFIG_AP */
3013 if (wpa_dbus_unregister_object_per_iface(ctrl_iface
,
3014 wpa_s
->dbus_new_path
))
3017 wpas_dbus_signal_interface_removed(wpa_s
);
3019 os_free(wpa_s
->dbus_new_path
);
3020 wpa_s
->dbus_new_path
= NULL
;
3027 static const struct wpa_dbus_property_desc wpas_dbus_p2p_peer_properties
[] = {
3028 { "DeviceName", WPAS_DBUS_NEW_IFACE_P2P_PEER
, "s",
3029 wpas_dbus_getter_p2p_peer_device_name
,
3032 { "PrimaryDeviceType", WPAS_DBUS_NEW_IFACE_P2P_PEER
, "ay",
3033 wpas_dbus_getter_p2p_peer_primary_device_type
,
3036 { "config_method", WPAS_DBUS_NEW_IFACE_P2P_PEER
, "q",
3037 wpas_dbus_getter_p2p_peer_config_method
,
3040 { "level", WPAS_DBUS_NEW_IFACE_P2P_PEER
, "i",
3041 wpas_dbus_getter_p2p_peer_level
,
3044 { "devicecapability", WPAS_DBUS_NEW_IFACE_P2P_PEER
, "y",
3045 wpas_dbus_getter_p2p_peer_device_capability
,
3048 { "groupcapability", WPAS_DBUS_NEW_IFACE_P2P_PEER
, "y",
3049 wpas_dbus_getter_p2p_peer_group_capability
,
3052 { "SecondaryDeviceTypes", WPAS_DBUS_NEW_IFACE_P2P_PEER
, "aay",
3053 wpas_dbus_getter_p2p_peer_secondary_device_types
,
3056 { "VendorExtension", WPAS_DBUS_NEW_IFACE_P2P_PEER
, "aay",
3057 wpas_dbus_getter_p2p_peer_vendor_extension
,
3060 { "IEs", WPAS_DBUS_NEW_IFACE_P2P_PEER
, "ay",
3061 wpas_dbus_getter_p2p_peer_ies
,
3064 { NULL
, NULL
, NULL
, NULL
, NULL
}
3067 static const struct wpa_dbus_signal_desc wpas_dbus_p2p_peer_signals
[] = {
3069 { NULL
, NULL
, { END_ARGS
} }
3073 * wpas_dbus_signal_peer - Send a peer related event signal
3074 * @wpa_s: %wpa_supplicant network interface data
3075 * @dev: peer device object
3076 * @interface: name of the interface emitting this signal.
3077 * In case of peer objects, it would be emitted by either
3078 * the "interface object" or by "peer objects"
3079 * @sig_name: signal name - DeviceFound
3081 * Notify listeners about event related with newly found p2p peer device
3083 static void wpas_dbus_signal_peer(struct wpa_supplicant
*wpa_s
,
3084 const u8
*dev_addr
, const char *interface
,
3085 const char *sig_name
)
3087 struct wpas_dbus_priv
*iface
;
3089 DBusMessageIter iter
;
3090 char peer_obj_path
[WPAS_DBUS_OBJECT_PATH_MAX
], *path
;
3092 iface
= wpa_s
->global
->dbus
;
3094 /* Do nothing if the control interface is not turned on */
3098 os_snprintf(peer_obj_path
, WPAS_DBUS_OBJECT_PATH_MAX
,
3099 "%s/" WPAS_DBUS_NEW_P2P_PEERS_PART
"/" COMPACT_MACSTR
,
3100 wpa_s
->dbus_new_path
, MAC2STR(dev_addr
));
3102 msg
= dbus_message_new_signal(wpa_s
->dbus_new_path
, interface
,
3107 dbus_message_iter_init_append(msg
, &iter
);
3108 path
= peer_obj_path
;
3109 if (!dbus_message_iter_append_basic(&iter
, DBUS_TYPE_OBJECT_PATH
,
3113 dbus_connection_send(iface
->con
, msg
, NULL
);
3115 dbus_message_unref(msg
);
3119 wpa_printf(MSG_ERROR
, "dbus: Failed to construct signal");
3120 dbus_message_unref(msg
);
3125 * wpas_dbus_signal_peer_found - Send a peer found signal
3126 * @wpa_s: %wpa_supplicant network interface data
3127 * @dev: peer device object
3129 * Notify listeners about find a p2p peer device found
3131 void wpas_dbus_signal_peer_device_found(struct wpa_supplicant
*wpa_s
,
3134 wpas_dbus_signal_peer(wpa_s
, dev_addr
,
3135 WPAS_DBUS_NEW_IFACE_P2PDEVICE
,
3140 * wpas_dbus_signal_peer_lost - Send a peer lost signal
3141 * @wpa_s: %wpa_supplicant network interface data
3142 * @dev: peer device object
3144 * Notify listeners about lost a p2p peer device
3146 void wpas_dbus_signal_peer_device_lost(struct wpa_supplicant
*wpa_s
,
3149 wpas_dbus_signal_peer(wpa_s
, dev_addr
,
3150 WPAS_DBUS_NEW_IFACE_P2PDEVICE
,
3155 * wpas_dbus_register_peer - Register a discovered peer object with dbus
3156 * @wpa_s: wpa_supplicant interface structure
3157 * @ssid: network configuration data
3158 * Returns: 0 on success, -1 on failure
3160 * Registers network representing object with dbus
3162 int wpas_dbus_register_peer(struct wpa_supplicant
*wpa_s
, const u8
*dev_addr
)
3164 struct wpas_dbus_priv
*ctrl_iface
;
3165 struct wpa_dbus_object_desc
*obj_desc
;
3166 struct peer_handler_args
*arg
;
3167 char peer_obj_path
[WPAS_DBUS_OBJECT_PATH_MAX
];
3169 /* Do nothing if the control interface is not turned on */
3170 if (wpa_s
== NULL
|| wpa_s
->global
== NULL
)
3173 ctrl_iface
= wpa_s
->global
->dbus
;
3174 if (ctrl_iface
== NULL
)
3177 os_snprintf(peer_obj_path
, WPAS_DBUS_OBJECT_PATH_MAX
,
3178 "%s/" WPAS_DBUS_NEW_P2P_PEERS_PART
"/" COMPACT_MACSTR
,
3179 wpa_s
->dbus_new_path
, MAC2STR(dev_addr
));
3181 wpa_printf(MSG_INFO
, "dbus: Register peer object '%s'",
3183 obj_desc
= os_zalloc(sizeof(struct wpa_dbus_object_desc
));
3185 wpa_printf(MSG_ERROR
, "Not enough memory "
3186 "to create object description");
3190 /* allocate memory for handlers arguments */
3191 arg
= os_zalloc(sizeof(struct peer_handler_args
));
3193 wpa_printf(MSG_ERROR
, "Not enough memory "
3194 "to create arguments for method");
3199 os_memcpy(arg
->p2p_device_addr
, dev_addr
, ETH_ALEN
);
3201 wpas_dbus_register(obj_desc
, arg
, wpa_dbus_free
,
3203 wpas_dbus_p2p_peer_properties
,
3204 wpas_dbus_p2p_peer_signals
);
3206 if (wpa_dbus_register_object_per_iface(ctrl_iface
, peer_obj_path
,
3207 wpa_s
->ifname
, obj_desc
))
3213 free_dbus_object_desc(obj_desc
);
3218 * wpas_dbus_unregister_peer - Unregister a peer object with dbus
3219 * @wpa_s: wpa_supplicant interface structure
3220 * @dev_addr: p2p device addr
3221 * Returns: 0 on success, -1 on failure
3223 * Registers network representing object with dbus
3225 int wpas_dbus_unregister_peer(struct wpa_supplicant
*wpa_s
,
3228 struct wpas_dbus_priv
*ctrl_iface
;
3229 char peer_obj_path
[WPAS_DBUS_OBJECT_PATH_MAX
];
3232 /* Do nothing if the control interface is not turned on */
3233 if (wpa_s
== NULL
|| wpa_s
->global
== NULL
||
3234 wpa_s
->dbus_new_path
== NULL
)
3236 ctrl_iface
= wpa_s
->global
->dbus
;
3237 if (ctrl_iface
== NULL
)
3240 os_snprintf(peer_obj_path
, WPAS_DBUS_OBJECT_PATH_MAX
,
3241 "%s/" WPAS_DBUS_NEW_P2P_PEERS_PART
"/" COMPACT_MACSTR
,
3242 wpa_s
->dbus_new_path
, MAC2STR(dev_addr
));
3244 wpa_printf(MSG_INFO
, "dbus: Unregister peer object '%s'",
3246 ret
= wpa_dbus_unregister_object_per_iface(ctrl_iface
, peer_obj_path
);
3252 static const struct wpa_dbus_property_desc wpas_dbus_p2p_group_properties
[] = {
3253 { "Members", WPAS_DBUS_NEW_IFACE_P2P_GROUP
, "ao",
3254 wpas_dbus_getter_p2p_group_members
,
3257 { "Group", WPAS_DBUS_NEW_IFACE_P2P_GROUP
, "o",
3258 wpas_dbus_getter_p2p_group
,
3261 { "Role", WPAS_DBUS_NEW_IFACE_P2P_GROUP
, "s",
3262 wpas_dbus_getter_p2p_role
,
3265 { "SSID", WPAS_DBUS_NEW_IFACE_P2P_GROUP
, "ay",
3266 wpas_dbus_getter_p2p_group_ssid
,
3269 { "BSSID", WPAS_DBUS_NEW_IFACE_P2P_GROUP
, "ay",
3270 wpas_dbus_getter_p2p_group_bssid
,
3273 { "Frequency", WPAS_DBUS_NEW_IFACE_P2P_GROUP
, "q",
3274 wpas_dbus_getter_p2p_group_frequency
,
3277 { "Passphrase", WPAS_DBUS_NEW_IFACE_P2P_GROUP
, "s",
3278 wpas_dbus_getter_p2p_group_passphrase
,
3281 { "PSK", WPAS_DBUS_NEW_IFACE_P2P_GROUP
, "ay",
3282 wpas_dbus_getter_p2p_group_psk
,
3285 { "WPSVendorExtensions", WPAS_DBUS_NEW_IFACE_P2P_GROUP
, "aay",
3286 wpas_dbus_getter_p2p_group_vendor_ext
,
3287 wpas_dbus_setter_p2p_group_vendor_ext
3289 { NULL
, NULL
, NULL
, NULL
, NULL
}
3292 static const struct wpa_dbus_signal_desc wpas_dbus_p2p_group_signals
[] = {
3293 { "PeerJoined", WPAS_DBUS_NEW_IFACE_P2P_GROUP
,
3295 { "peer", "o", ARG_OUT
},
3299 { "PeerDisconnected", WPAS_DBUS_NEW_IFACE_P2P_GROUP
,
3301 { "peer", "o", ARG_OUT
},
3305 { NULL
, NULL
, { END_ARGS
} }
3309 * wpas_dbus_register_p2p_group - Register a p2p group object with dbus
3310 * @wpa_s: wpa_supplicant interface structure
3311 * @ssid: SSID struct
3312 * Returns: 0 on success, -1 on failure
3314 * Registers p2p group representing object with dbus
3316 void wpas_dbus_register_p2p_group(struct wpa_supplicant
*wpa_s
,
3317 struct wpa_ssid
*ssid
)
3319 struct wpas_dbus_priv
*ctrl_iface
;
3320 struct wpa_dbus_object_desc
*obj_desc
;
3321 char group_obj_path
[WPAS_DBUS_OBJECT_PATH_MAX
];
3323 /* Do nothing if the control interface is not turned on */
3324 if (wpa_s
== NULL
|| wpa_s
->global
== NULL
)
3327 ctrl_iface
= wpa_s
->global
->dbus
;
3328 if (ctrl_iface
== NULL
)
3331 if (wpa_s
->dbus_groupobj_path
) {
3332 wpa_printf(MSG_INFO
, "%s: Group object '%s' already exists",
3333 __func__
, wpa_s
->dbus_groupobj_path
);
3337 if (wpas_dbus_get_group_obj_path(wpa_s
, ssid
, group_obj_path
) < 0)
3340 wpa_s
->dbus_groupobj_path
= os_strdup(group_obj_path
);
3341 if (wpa_s
->dbus_groupobj_path
== NULL
)
3344 wpa_printf(MSG_INFO
, "dbus: Register group object '%s'",
3346 obj_desc
= os_zalloc(sizeof(struct wpa_dbus_object_desc
));
3348 wpa_printf(MSG_ERROR
, "Not enough memory "
3349 "to create object description");
3353 wpas_dbus_register(obj_desc
, wpa_s
, NULL
, NULL
,
3354 wpas_dbus_p2p_group_properties
,
3355 wpas_dbus_p2p_group_signals
);
3357 if (wpa_dbus_register_object_per_iface(ctrl_iface
, group_obj_path
,
3358 wpa_s
->ifname
, obj_desc
))
3364 if (wpa_s
->dbus_groupobj_path
) {
3365 os_free(wpa_s
->dbus_groupobj_path
);
3366 wpa_s
->dbus_groupobj_path
= NULL
;
3369 free_dbus_object_desc(obj_desc
);
3373 * wpas_dbus_unregister_p2p_group - Unregister a p2p group object from dbus
3374 * @wpa_s: wpa_supplicant interface structure
3375 * @ssid: network name of the p2p group started
3377 void wpas_dbus_unregister_p2p_group(struct wpa_supplicant
*wpa_s
,
3378 const struct wpa_ssid
*ssid
)
3380 struct wpas_dbus_priv
*ctrl_iface
;
3382 /* Do nothing if the control interface is not turned on */
3383 if (wpa_s
== NULL
|| wpa_s
->global
== NULL
)
3386 ctrl_iface
= wpa_s
->global
->dbus
;
3387 if (ctrl_iface
== NULL
)
3390 if (!wpa_s
->dbus_groupobj_path
) {
3391 wpa_printf(MSG_DEBUG
,
3392 "%s: Group object '%s' already unregistered",
3393 __func__
, wpa_s
->dbus_groupobj_path
);
3397 wpa_printf(MSG_DEBUG
, "dbus: Unregister group object '%s'",
3398 wpa_s
->dbus_groupobj_path
);
3400 wpa_dbus_unregister_object_per_iface(ctrl_iface
,
3401 wpa_s
->dbus_groupobj_path
);
3403 os_free(wpa_s
->dbus_groupobj_path
);
3404 wpa_s
->dbus_groupobj_path
= NULL
;
3407 static const struct wpa_dbus_property_desc
3408 wpas_dbus_p2p_groupmember_properties
[] = {
3409 { NULL
, NULL
, NULL
, NULL
, NULL
}
3413 * wpas_dbus_register_p2p_groupmember - Register a p2p groupmember
3415 * @wpa_s: wpa_supplicant interface structure
3416 * @p2p_if_addr: i/f addr of the device joining this group
3418 * Registers p2p groupmember representing object with dbus
3420 void wpas_dbus_register_p2p_groupmember(struct wpa_supplicant
*wpa_s
,
3421 const u8
*p2p_if_addr
)
3423 struct wpas_dbus_priv
*ctrl_iface
;
3424 struct wpa_dbus_object_desc
*obj_desc
= NULL
;
3425 struct groupmember_handler_args
*arg
;
3426 char groupmember_obj_path
[WPAS_DBUS_OBJECT_PATH_MAX
];
3428 /* Do nothing if the control interface is not turned on */
3429 if (wpa_s
== NULL
|| wpa_s
->global
== NULL
)
3432 ctrl_iface
= wpa_s
->global
->dbus
;
3433 if (ctrl_iface
== NULL
)
3436 if (!wpa_s
->dbus_groupobj_path
)
3439 os_snprintf(groupmember_obj_path
, WPAS_DBUS_OBJECT_PATH_MAX
,
3440 "%s/" WPAS_DBUS_NEW_P2P_GROUPMEMBERS_PART
"/" COMPACT_MACSTR
,
3441 wpa_s
->dbus_groupobj_path
, MAC2STR(p2p_if_addr
));
3443 obj_desc
= os_zalloc(sizeof(struct wpa_dbus_object_desc
));
3445 wpa_printf(MSG_ERROR
, "Not enough memory "
3446 "to create object description");
3450 /* allocate memory for handlers arguments */
3451 arg
= os_zalloc(sizeof(struct groupmember_handler_args
));
3453 wpa_printf(MSG_ERROR
, "Not enough memory "
3454 "to create arguments for method");
3459 os_memcpy(arg
->member_addr
, p2p_if_addr
, ETH_ALEN
);
3461 wpas_dbus_register(obj_desc
, arg
, wpa_dbus_free
, NULL
,
3462 wpas_dbus_p2p_groupmember_properties
, NULL
);
3464 if (wpa_dbus_register_object_per_iface(ctrl_iface
, groupmember_obj_path
,
3465 wpa_s
->ifname
, obj_desc
))
3468 wpa_printf(MSG_INFO
,
3469 "dbus: Registered group member object '%s' successfully",
3470 groupmember_obj_path
);
3474 free_dbus_object_desc(obj_desc
);
3478 * wpas_dbus_unregister_p2p_groupmember - Unregister a p2p groupmember
3480 * @wpa_s: wpa_supplicant interface structure
3481 * @p2p_if_addr: i/f addr of the device joining this group
3483 * Unregisters p2p groupmember representing object with dbus
3485 void wpas_dbus_unregister_p2p_groupmember(struct wpa_supplicant
*wpa_s
,
3486 const u8
*p2p_if_addr
)
3488 struct wpas_dbus_priv
*ctrl_iface
;
3489 char groupmember_obj_path
[WPAS_DBUS_OBJECT_PATH_MAX
];
3491 /* Do nothing if the control interface is not turned on */
3492 if (wpa_s
== NULL
|| wpa_s
->global
== NULL
)
3495 ctrl_iface
= wpa_s
->global
->dbus
;
3496 if (ctrl_iface
== NULL
)
3499 if (!wpa_s
->dbus_groupobj_path
)
3502 os_snprintf(groupmember_obj_path
, WPAS_DBUS_OBJECT_PATH_MAX
,
3503 "%s/" WPAS_DBUS_NEW_P2P_GROUPMEMBERS_PART
"/" COMPACT_MACSTR
,
3504 wpa_s
->dbus_groupobj_path
, MAC2STR(p2p_if_addr
));
3506 wpa_dbus_unregister_object_per_iface(ctrl_iface
, groupmember_obj_path
);
3510 static const struct wpa_dbus_property_desc
3511 wpas_dbus_persistent_group_properties
[] = {
3512 { "Properties", WPAS_DBUS_NEW_IFACE_PERSISTENT_GROUP
, "a{sv}",
3513 wpas_dbus_getter_persistent_group_properties
,
3514 wpas_dbus_setter_persistent_group_properties
3516 { NULL
, NULL
, NULL
, NULL
, NULL
}
3519 /* No signals intended for persistent group objects */
3522 * wpas_dbus_register_persistent_group - Register a configured(saved)
3523 * persistent group with dbus
3524 * @wpa_s: wpa_supplicant interface structure
3525 * @ssid: persistent group (still represented as a network within wpa)
3526 * configuration data
3527 * Returns: 0 on success, -1 on failure
3529 * Registers a persistent group representing object with dbus.
3531 int wpas_dbus_register_persistent_group(struct wpa_supplicant
*wpa_s
,
3532 struct wpa_ssid
*ssid
)
3534 struct wpas_dbus_priv
*ctrl_iface
;
3535 struct wpa_dbus_object_desc
*obj_desc
;
3536 struct network_handler_args
*arg
;
3537 char pgrp_obj_path
[WPAS_DBUS_OBJECT_PATH_MAX
];
3539 /* Do nothing if the control interface is not turned on */
3540 if (wpa_s
== NULL
|| wpa_s
->global
== NULL
)
3543 /* Make sure ssid is a persistent group */
3544 if (ssid
->disabled
!= 2 && !ssid
->p2p_persistent_group
)
3545 return -1; /* should we return w/o complaining? */
3547 ctrl_iface
= wpa_s
->global
->dbus
;
3548 if (ctrl_iface
== NULL
)
3552 * Intentionally not coming up with different numbering scheme
3553 * for persistent groups.
3555 os_snprintf(pgrp_obj_path
, WPAS_DBUS_OBJECT_PATH_MAX
,
3556 "%s/" WPAS_DBUS_NEW_PERSISTENT_GROUPS_PART
"/%u",
3557 wpa_s
->dbus_new_path
, ssid
->id
);
3559 wpa_printf(MSG_DEBUG
, "dbus: Register persistent group object '%s'",
3561 obj_desc
= os_zalloc(sizeof(struct wpa_dbus_object_desc
));
3563 wpa_printf(MSG_ERROR
, "dbus: Not enough memory to create "
3564 "object description");
3569 * Reusing the same context structure as that for networks
3570 * since these are represented using same data structure.
3572 /* allocate memory for handlers arguments */
3573 arg
= os_zalloc(sizeof(struct network_handler_args
));
3575 wpa_printf(MSG_ERROR
, "dbus: Not enough memory to create "
3576 "arguments for method");
3583 wpas_dbus_register(obj_desc
, arg
, wpa_dbus_free
, NULL
,
3584 wpas_dbus_persistent_group_properties
,
3587 if (wpa_dbus_register_object_per_iface(ctrl_iface
, pgrp_obj_path
,
3588 wpa_s
->ifname
, obj_desc
))
3591 wpas_dbus_signal_persistent_group_added(wpa_s
, ssid
->id
);
3596 free_dbus_object_desc(obj_desc
);
3602 * wpas_dbus_unregister_persistent_group - Unregister a persistent_group
3604 * @wpa_s: wpa_supplicant interface structure
3606 * Returns: 0 on success, -1 on failure
3608 * Unregisters persistent group representing object from dbus
3610 * NOTE: There is a slight issue with the semantics here. While the
3611 * implementation simply means the persistent group is unloaded from memory,
3612 * it should not get interpreted as the group is actually being erased/removed
3613 * from persistent storage as well.
3615 int wpas_dbus_unregister_persistent_group(struct wpa_supplicant
*wpa_s
,
3618 struct wpas_dbus_priv
*ctrl_iface
;
3619 char pgrp_obj_path
[WPAS_DBUS_OBJECT_PATH_MAX
];
3622 /* Do nothing if the control interface is not turned on */
3623 if (wpa_s
== NULL
|| wpa_s
->global
== NULL
||
3624 wpa_s
->dbus_new_path
== NULL
)
3626 ctrl_iface
= wpa_s
->global
->dbus
;
3627 if (ctrl_iface
== NULL
)
3630 os_snprintf(pgrp_obj_path
, WPAS_DBUS_OBJECT_PATH_MAX
,
3631 "%s/" WPAS_DBUS_NEW_PERSISTENT_GROUPS_PART
"/%u",
3632 wpa_s
->dbus_new_path
, nid
);
3634 wpa_printf(MSG_DEBUG
, "dbus: Unregister persistent group object '%s'",
3636 ret
= wpa_dbus_unregister_object_per_iface(ctrl_iface
, pgrp_obj_path
);
3639 wpas_dbus_signal_persistent_group_removed(wpa_s
, nid
);
3644 #endif /* CONFIG_P2P */