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 "../config.h"
17 #include "../wpa_supplicant_i.h"
19 #include "../wpas_glue.h"
20 #include "dbus_new_helpers.h"
21 #include "dbus_dict_helpers.h"
23 #include "dbus_new_handlers.h"
24 #include "dbus_common_i.h"
25 #include "dbus_new_handlers_p2p.h"
27 #include "../p2p_supplicant.h"
29 #ifdef CONFIG_AP /* until needed by something else */
32 * NameOwnerChanged handling
34 * Some services we provide allow an application to register for
35 * a signal that it needs. While it can also unregister, we must
36 * be prepared for the case where the application simply crashes
37 * and thus doesn't clean up properly. The way to handle this in
38 * DBus is to register for the NameOwnerChanged signal which will
39 * signal an owner change to NULL if the peer closes the socket
40 * for whatever reason.
42 * Handle this signal via a filter function whenever necessary.
43 * The code below also handles refcounting in case in the future
44 * there will be multiple instances of this subscription scheme.
46 static const char wpas_dbus_noc_filter_str
[] =
47 "interface=org.freedesktop.DBus,member=NameOwnerChanged";
50 static DBusHandlerResult
noc_filter(DBusConnection
*conn
,
51 DBusMessage
*message
, void *data
)
53 struct wpas_dbus_priv
*priv
= data
;
55 if (dbus_message_get_type(message
) != DBUS_MESSAGE_TYPE_SIGNAL
)
56 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED
;
58 if (dbus_message_is_signal(message
, DBUS_INTERFACE_DBUS
,
59 "NameOwnerChanged")) {
61 const char *prev_owner
;
62 const char *new_owner
;
64 struct wpa_supplicant
*wpa_s
;
66 dbus_error_init(&derr
);
68 if (!dbus_message_get_args(message
, &derr
,
69 DBUS_TYPE_STRING
, &name
,
70 DBUS_TYPE_STRING
, &prev_owner
,
71 DBUS_TYPE_STRING
, &new_owner
,
73 /* Ignore this error */
74 dbus_error_free(&derr
);
75 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED
;
78 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
, int properties
)
134 struct wpas_dbus_priv
*iface
;
136 DBusMessageIter iter
;
138 iface
= wpa_s
->global
->dbus
;
140 /* Do nothing if the control interface is not turned on */
144 msg
= dbus_message_new_signal(WPAS_DBUS_NEW_PATH
,
145 WPAS_DBUS_NEW_INTERFACE
, sig_name
);
149 dbus_message_iter_init_append(msg
, &iter
);
150 if (!dbus_message_iter_append_basic(&iter
, DBUS_TYPE_OBJECT_PATH
,
151 &wpa_s
->dbus_new_path
))
155 if (!wpa_dbus_get_object_properties(
156 iface
, wpa_s
->dbus_new_path
,
157 WPAS_DBUS_NEW_IFACE_INTERFACE
, &iter
))
161 dbus_connection_send(iface
->con
, msg
, NULL
);
162 dbus_message_unref(msg
);
166 wpa_printf(MSG_ERROR
, "dbus: Failed to construct signal");
167 dbus_message_unref(msg
);
172 * wpas_dbus_signal_interface_added - Send a interface created signal
173 * @wpa_s: %wpa_supplicant network interface data
175 * Notify listeners about creating new interface
177 static void wpas_dbus_signal_interface_added(struct wpa_supplicant
*wpa_s
)
179 wpas_dbus_signal_interface(wpa_s
, "InterfaceAdded", TRUE
);
184 * wpas_dbus_signal_interface_removed - Send a interface removed signal
185 * @wpa_s: %wpa_supplicant network interface data
187 * Notify listeners about removing interface
189 static void wpas_dbus_signal_interface_removed(struct wpa_supplicant
*wpa_s
)
191 wpas_dbus_signal_interface(wpa_s
, "InterfaceRemoved", FALSE
);
197 * wpas_dbus_signal_scan_done - send scan done signal
198 * @wpa_s: %wpa_supplicant network interface data
199 * @success: indicates if scanning succeed or failed
201 * Notify listeners about finishing a scan
203 void wpas_dbus_signal_scan_done(struct wpa_supplicant
*wpa_s
, int success
)
205 struct wpas_dbus_priv
*iface
;
209 iface
= wpa_s
->global
->dbus
;
211 /* Do nothing if the control interface is not turned on */
215 msg
= dbus_message_new_signal(wpa_s
->dbus_new_path
,
216 WPAS_DBUS_NEW_IFACE_INTERFACE
,
221 succ
= success
? TRUE
: FALSE
;
222 if (dbus_message_append_args(msg
, DBUS_TYPE_BOOLEAN
, &succ
,
224 dbus_connection_send(iface
->con
, msg
, NULL
);
226 wpa_printf(MSG_ERROR
, "dbus: Failed to construct signal");
227 dbus_message_unref(msg
);
232 * wpas_dbus_signal_blob - Send a BSS related event signal
233 * @wpa_s: %wpa_supplicant network interface data
234 * @bss_obj_path: BSS object path
235 * @sig_name: signal name - BSSAdded or BSSRemoved
236 * @properties: Whether to add second argument with object properties
238 * Notify listeners about event related with BSS
240 static void wpas_dbus_signal_bss(struct wpa_supplicant
*wpa_s
,
241 const char *bss_obj_path
,
242 const char *sig_name
, int properties
)
244 struct wpas_dbus_priv
*iface
;
246 DBusMessageIter iter
;
248 iface
= wpa_s
->global
->dbus
;
250 /* Do nothing if the control interface is not turned on */
254 msg
= dbus_message_new_signal(wpa_s
->dbus_new_path
,
255 WPAS_DBUS_NEW_IFACE_INTERFACE
,
260 dbus_message_iter_init_append(msg
, &iter
);
261 if (!dbus_message_iter_append_basic(&iter
, DBUS_TYPE_OBJECT_PATH
,
266 if (!wpa_dbus_get_object_properties(iface
, bss_obj_path
,
267 WPAS_DBUS_NEW_IFACE_BSS
,
272 dbus_connection_send(iface
->con
, msg
, NULL
);
273 dbus_message_unref(msg
);
277 wpa_printf(MSG_ERROR
, "dbus: Failed to construct signal");
278 dbus_message_unref(msg
);
283 * wpas_dbus_signal_bss_added - Send a BSS added signal
284 * @wpa_s: %wpa_supplicant network interface data
285 * @bss_obj_path: new BSS object path
287 * Notify listeners about adding new BSS
289 static void wpas_dbus_signal_bss_added(struct wpa_supplicant
*wpa_s
,
290 const char *bss_obj_path
)
292 wpas_dbus_signal_bss(wpa_s
, bss_obj_path
, "BSSAdded", TRUE
);
297 * wpas_dbus_signal_bss_removed - Send a BSS removed signal
298 * @wpa_s: %wpa_supplicant network interface data
299 * @bss_obj_path: BSS object path
301 * Notify listeners about removing BSS
303 static void wpas_dbus_signal_bss_removed(struct wpa_supplicant
*wpa_s
,
304 const char *bss_obj_path
)
306 wpas_dbus_signal_bss(wpa_s
, bss_obj_path
, "BSSRemoved", FALSE
);
311 * wpas_dbus_signal_blob - Send a blob related event signal
312 * @wpa_s: %wpa_supplicant network interface data
314 * @sig_name: signal name - BlobAdded or BlobRemoved
316 * Notify listeners about event related with blob
318 static void wpas_dbus_signal_blob(struct wpa_supplicant
*wpa_s
,
319 const char *name
, const char *sig_name
)
321 struct wpas_dbus_priv
*iface
;
324 iface
= wpa_s
->global
->dbus
;
326 /* Do nothing if the control interface is not turned on */
330 msg
= dbus_message_new_signal(wpa_s
->dbus_new_path
,
331 WPAS_DBUS_NEW_IFACE_INTERFACE
,
336 if (dbus_message_append_args(msg
, DBUS_TYPE_STRING
, &name
,
338 dbus_connection_send(iface
->con
, msg
, NULL
);
340 wpa_printf(MSG_ERROR
, "dbus: Failed to construct signal");
341 dbus_message_unref(msg
);
346 * wpas_dbus_signal_blob_added - Send a blob added signal
347 * @wpa_s: %wpa_supplicant network interface data
350 * Notify listeners about adding a new blob
352 void wpas_dbus_signal_blob_added(struct wpa_supplicant
*wpa_s
,
355 wpas_dbus_signal_blob(wpa_s
, name
, "BlobAdded");
360 * wpas_dbus_signal_blob_removed - Send a blob removed signal
361 * @wpa_s: %wpa_supplicant network interface data
364 * Notify listeners about removing blob
366 void wpas_dbus_signal_blob_removed(struct wpa_supplicant
*wpa_s
,
369 wpas_dbus_signal_blob(wpa_s
, name
, "BlobRemoved");
374 * wpas_dbus_signal_network - Send a network related event signal
375 * @wpa_s: %wpa_supplicant network interface data
376 * @id: new network id
377 * @sig_name: signal name - NetworkAdded, NetworkRemoved or NetworkSelected
378 * @properties: determines if add second argument with object properties
380 * Notify listeners about event related with configured network
382 static void wpas_dbus_signal_network(struct wpa_supplicant
*wpa_s
,
383 int id
, const char *sig_name
,
386 struct wpas_dbus_priv
*iface
;
388 DBusMessageIter iter
;
389 char net_obj_path
[WPAS_DBUS_OBJECT_PATH_MAX
], *path
;
391 iface
= wpa_s
->global
->dbus
;
393 /* Do nothing if the control interface is not turned on */
397 os_snprintf(net_obj_path
, WPAS_DBUS_OBJECT_PATH_MAX
,
398 "%s/" WPAS_DBUS_NEW_NETWORKS_PART
"/%u",
399 wpa_s
->dbus_new_path
, id
);
401 msg
= dbus_message_new_signal(wpa_s
->dbus_new_path
,
402 WPAS_DBUS_NEW_IFACE_INTERFACE
,
407 dbus_message_iter_init_append(msg
, &iter
);
409 if (!dbus_message_iter_append_basic(&iter
, DBUS_TYPE_OBJECT_PATH
,
414 if (!wpa_dbus_get_object_properties(
415 iface
, net_obj_path
, WPAS_DBUS_NEW_IFACE_NETWORK
,
420 dbus_connection_send(iface
->con
, msg
, NULL
);
422 dbus_message_unref(msg
);
426 wpa_printf(MSG_ERROR
, "dbus: Failed to construct signal");
427 dbus_message_unref(msg
);
432 * wpas_dbus_signal_network_added - Send a network added signal
433 * @wpa_s: %wpa_supplicant network interface data
434 * @id: new network id
436 * Notify listeners about adding new network
438 static void wpas_dbus_signal_network_added(struct wpa_supplicant
*wpa_s
,
441 wpas_dbus_signal_network(wpa_s
, id
, "NetworkAdded", TRUE
);
446 * wpas_dbus_signal_network_removed - Send a network removed signal
447 * @wpa_s: %wpa_supplicant network interface data
450 * Notify listeners about removing a network
452 static void wpas_dbus_signal_network_removed(struct wpa_supplicant
*wpa_s
,
455 wpas_dbus_signal_network(wpa_s
, id
, "NetworkRemoved", FALSE
);
460 * wpas_dbus_signal_network_selected - Send a network selected signal
461 * @wpa_s: %wpa_supplicant network interface data
464 * Notify listeners about selecting a network
466 void wpas_dbus_signal_network_selected(struct wpa_supplicant
*wpa_s
, int id
)
468 wpas_dbus_signal_network(wpa_s
, id
, "NetworkSelected", FALSE
);
473 * wpas_dbus_signal_network_request - Indicate that additional information
474 * (EAP password, etc.) is required to complete the association to this SSID
475 * @wpa_s: %wpa_supplicant network interface data
476 * @rtype: The specific additional information required
477 * @default_text: Optional description of required information
479 * Request additional information or passwords to complete an association
482 void wpas_dbus_signal_network_request(struct wpa_supplicant
*wpa_s
,
483 struct wpa_ssid
*ssid
,
484 enum wpa_ctrl_req_type rtype
,
485 const char *default_txt
)
487 struct wpas_dbus_priv
*iface
;
489 DBusMessageIter iter
;
490 char net_obj_path
[WPAS_DBUS_OBJECT_PATH_MAX
];
491 const char *field
, *txt
= NULL
, *net_ptr
;
493 iface
= wpa_s
->global
->dbus
;
495 /* Do nothing if the control interface is not turned on */
499 field
= wpa_supplicant_ctrl_req_to_string(rtype
, default_txt
, &txt
);
503 msg
= dbus_message_new_signal(wpa_s
->dbus_new_path
,
504 WPAS_DBUS_NEW_IFACE_INTERFACE
,
509 os_snprintf(net_obj_path
, WPAS_DBUS_OBJECT_PATH_MAX
,
510 "%s/" WPAS_DBUS_NEW_NETWORKS_PART
"/%u",
511 wpa_s
->dbus_new_path
, ssid
->id
);
512 net_ptr
= &net_obj_path
[0];
514 dbus_message_iter_init_append(msg
, &iter
);
515 if (!dbus_message_iter_append_basic(&iter
, DBUS_TYPE_OBJECT_PATH
,
518 if (!dbus_message_iter_append_basic(&iter
, DBUS_TYPE_STRING
, &field
))
520 if (!dbus_message_iter_append_basic(&iter
, DBUS_TYPE_STRING
, &txt
))
523 dbus_connection_send(iface
->con
, msg
, NULL
);
524 dbus_message_unref(msg
);
528 wpa_printf(MSG_ERROR
, "dbus: Failed to construct signal");
529 dbus_message_unref(msg
);
534 * wpas_dbus_signal_network_enabled_changed - Signals Enabled property changes
535 * @wpa_s: %wpa_supplicant network interface data
536 * @ssid: configured network which Enabled property has changed
538 * Sends PropertyChanged signals containing new value of Enabled property
539 * for specified network
541 void wpas_dbus_signal_network_enabled_changed(struct wpa_supplicant
*wpa_s
,
542 struct wpa_ssid
*ssid
)
545 char path
[WPAS_DBUS_OBJECT_PATH_MAX
];
546 os_snprintf(path
, WPAS_DBUS_OBJECT_PATH_MAX
,
547 "%s/" WPAS_DBUS_NEW_NETWORKS_PART
"/%d",
548 wpa_s
->dbus_new_path
, ssid
->id
);
550 wpa_dbus_mark_property_changed(wpa_s
->global
->dbus
, path
,
551 WPAS_DBUS_NEW_IFACE_NETWORK
, "Enabled");
558 * wpas_dbus_signal_wps_event_success - Signals Success WPS event
559 * @wpa_s: %wpa_supplicant network interface data
561 * Sends Event dbus signal with name "success" and empty dict as arguments
563 void wpas_dbus_signal_wps_event_success(struct wpa_supplicant
*wpa_s
)
567 DBusMessageIter iter
, dict_iter
;
568 struct wpas_dbus_priv
*iface
;
569 char *key
= "success";
571 iface
= wpa_s
->global
->dbus
;
573 /* Do nothing if the control interface is not turned on */
577 msg
= dbus_message_new_signal(wpa_s
->dbus_new_path
,
578 WPAS_DBUS_NEW_IFACE_WPS
, "Event");
582 dbus_message_iter_init_append(msg
, &iter
);
584 if (!dbus_message_iter_append_basic(&iter
, DBUS_TYPE_STRING
, &key
) ||
585 !wpa_dbus_dict_open_write(&iter
, &dict_iter
) ||
586 !wpa_dbus_dict_close_write(&iter
, &dict_iter
))
587 wpa_printf(MSG_ERROR
, "dbus: Failed to construct signal");
589 dbus_connection_send(iface
->con
, msg
, NULL
);
591 dbus_message_unref(msg
);
596 * wpas_dbus_signal_wps_event_fail - Signals Fail WPS event
597 * @wpa_s: %wpa_supplicant network interface data
599 * Sends Event dbus signal with name "fail" and dictionary containing
600 * "msg field with fail message number (int32) as arguments
602 void wpas_dbus_signal_wps_event_fail(struct wpa_supplicant
*wpa_s
,
603 struct wps_event_fail
*fail
)
607 DBusMessageIter iter
, dict_iter
;
608 struct wpas_dbus_priv
*iface
;
611 iface
= wpa_s
->global
->dbus
;
613 /* Do nothing if the control interface is not turned on */
617 msg
= dbus_message_new_signal(wpa_s
->dbus_new_path
,
618 WPAS_DBUS_NEW_IFACE_WPS
, "Event");
622 dbus_message_iter_init_append(msg
, &iter
);
624 if (!dbus_message_iter_append_basic(&iter
, DBUS_TYPE_STRING
, &key
) ||
625 !wpa_dbus_dict_open_write(&iter
, &dict_iter
) ||
626 !wpa_dbus_dict_append_int32(&dict_iter
, "msg", fail
->msg
) ||
627 !wpa_dbus_dict_close_write(&iter
, &dict_iter
))
628 wpa_printf(MSG_ERROR
, "dbus: Failed to construct signal");
630 dbus_connection_send(iface
->con
, msg
, NULL
);
632 dbus_message_unref(msg
);
637 * wpas_dbus_signal_wps_event_m2d - Signals M2D WPS event
638 * @wpa_s: %wpa_supplicant network interface data
640 * Sends Event dbus signal with name "m2d" and dictionary containing
641 * fields of wps_event_m2d structure.
643 void wpas_dbus_signal_wps_event_m2d(struct wpa_supplicant
*wpa_s
,
644 struct wps_event_m2d
*m2d
)
648 DBusMessageIter iter
, dict_iter
;
649 struct wpas_dbus_priv
*iface
;
652 iface
= wpa_s
->global
->dbus
;
654 /* Do nothing if the control interface is not turned on */
658 msg
= dbus_message_new_signal(wpa_s
->dbus_new_path
,
659 WPAS_DBUS_NEW_IFACE_WPS
, "Event");
663 dbus_message_iter_init_append(msg
, &iter
);
665 if (!dbus_message_iter_append_basic(&iter
, DBUS_TYPE_STRING
, &key
) ||
666 !wpa_dbus_dict_open_write(&iter
, &dict_iter
) ||
667 !wpa_dbus_dict_append_uint16(&dict_iter
, "config_methods",
668 m2d
->config_methods
) ||
669 !wpa_dbus_dict_append_byte_array(&dict_iter
, "manufacturer",
670 (const char *) m2d
->manufacturer
,
671 m2d
->manufacturer_len
) ||
672 !wpa_dbus_dict_append_byte_array(&dict_iter
, "model_name",
673 (const char *) m2d
->model_name
,
674 m2d
->model_name_len
) ||
675 !wpa_dbus_dict_append_byte_array(&dict_iter
, "model_number",
676 (const char *) m2d
->model_number
,
677 m2d
->model_number_len
) ||
678 !wpa_dbus_dict_append_byte_array(&dict_iter
, "serial_number",
681 m2d
->serial_number_len
) ||
682 !wpa_dbus_dict_append_byte_array(&dict_iter
, "dev_name",
683 (const char *) m2d
->dev_name
,
684 m2d
->dev_name_len
) ||
685 !wpa_dbus_dict_append_byte_array(&dict_iter
, "primary_dev_type",
687 m2d
->primary_dev_type
, 8) ||
688 !wpa_dbus_dict_append_uint16(&dict_iter
, "config_error",
689 m2d
->config_error
) ||
690 !wpa_dbus_dict_append_uint16(&dict_iter
, "dev_password_id",
691 m2d
->dev_password_id
) ||
692 !wpa_dbus_dict_close_write(&iter
, &dict_iter
))
693 wpa_printf(MSG_ERROR
, "dbus: Failed to construct signal");
695 dbus_connection_send(iface
->con
, msg
, NULL
);
697 dbus_message_unref(msg
);
702 * wpas_dbus_signal_wps_cred - Signals new credentials
703 * @wpa_s: %wpa_supplicant network interface data
705 * Sends signal with credentials in directory argument
707 void wpas_dbus_signal_wps_cred(struct wpa_supplicant
*wpa_s
,
708 const struct wps_credential
*cred
)
711 DBusMessageIter iter
, dict_iter
;
712 struct wpas_dbus_priv
*iface
;
713 char *auth_type
[5]; /* we have five possible authentication types */
715 char *encr_type
[3]; /* we have three possible encryption types */
718 iface
= wpa_s
->global
->dbus
;
720 /* Do nothing if the control interface is not turned on */
724 msg
= dbus_message_new_signal(wpa_s
->dbus_new_path
,
725 WPAS_DBUS_NEW_IFACE_WPS
,
730 dbus_message_iter_init_append(msg
, &iter
);
731 if (!wpa_dbus_dict_open_write(&iter
, &dict_iter
))
734 if (cred
->auth_type
& WPS_AUTH_OPEN
)
735 auth_type
[at_num
++] = "open";
736 if (cred
->auth_type
& WPS_AUTH_WPAPSK
)
737 auth_type
[at_num
++] = "wpa-psk";
738 if (cred
->auth_type
& WPS_AUTH_WPA
)
739 auth_type
[at_num
++] = "wpa-eap";
740 if (cred
->auth_type
& WPS_AUTH_WPA2
)
741 auth_type
[at_num
++] = "wpa2-eap";
742 if (cred
->auth_type
& WPS_AUTH_WPA2PSK
)
743 auth_type
[at_num
++] = "wpa2-psk";
745 if (cred
->encr_type
& WPS_ENCR_NONE
)
746 encr_type
[et_num
++] = "none";
747 if (cred
->encr_type
& WPS_ENCR_TKIP
)
748 encr_type
[et_num
++] = "tkip";
749 if (cred
->encr_type
& WPS_ENCR_AES
)
750 encr_type
[et_num
++] = "aes";
752 if (wpa_s
->current_ssid
) {
753 if (!wpa_dbus_dict_append_byte_array(
755 (const char *) wpa_s
->current_ssid
->bssid
,
760 if (!wpa_dbus_dict_append_byte_array(&dict_iter
, "SSID",
761 (const char *) cred
->ssid
,
763 !wpa_dbus_dict_append_string_array(&dict_iter
, "AuthType",
764 (const char **) auth_type
,
766 !wpa_dbus_dict_append_string_array(&dict_iter
, "EncrType",
767 (const char **) encr_type
,
769 !wpa_dbus_dict_append_byte_array(&dict_iter
, "Key",
770 (const char *) cred
->key
,
772 !wpa_dbus_dict_append_uint32(&dict_iter
, "KeyIndex",
774 !wpa_dbus_dict_close_write(&iter
, &dict_iter
))
777 dbus_connection_send(iface
->con
, msg
, NULL
);
780 dbus_message_unref(msg
);
783 #endif /* CONFIG_WPS */
785 void wpas_dbus_signal_certification(struct wpa_supplicant
*wpa_s
,
786 int depth
, const char *subject
,
787 const char *cert_hash
,
788 const struct wpabuf
*cert
)
790 struct wpas_dbus_priv
*iface
;
792 DBusMessageIter iter
, dict_iter
;
794 iface
= wpa_s
->global
->dbus
;
796 /* Do nothing if the control interface is not turned on */
800 msg
= dbus_message_new_signal(wpa_s
->dbus_new_path
,
801 WPAS_DBUS_NEW_IFACE_INTERFACE
,
806 dbus_message_iter_init_append(msg
, &iter
);
807 if (!wpa_dbus_dict_open_write(&iter
, &dict_iter
))
810 if (!wpa_dbus_dict_append_uint32(&dict_iter
, "depth", depth
) ||
811 !wpa_dbus_dict_append_string(&dict_iter
, "subject", subject
))
815 !wpa_dbus_dict_append_string(&dict_iter
, "cert_hash", cert_hash
))
819 !wpa_dbus_dict_append_byte_array(&dict_iter
, "cert",
824 if (!wpa_dbus_dict_close_write(&iter
, &dict_iter
))
827 dbus_connection_send(iface
->con
, msg
, NULL
);
830 dbus_message_unref(msg
);
834 void wpas_dbus_signal_eap_status(struct wpa_supplicant
*wpa_s
,
835 const char *status
, const char *parameter
)
837 struct wpas_dbus_priv
*iface
;
839 DBusMessageIter iter
;
841 iface
= wpa_s
->global
->dbus
;
843 /* Do nothing if the control interface is not turned on */
847 msg
= dbus_message_new_signal(wpa_s
->dbus_new_path
,
848 WPAS_DBUS_NEW_IFACE_INTERFACE
,
853 dbus_message_iter_init_append(msg
, &iter
);
855 if (!dbus_message_iter_append_basic(&iter
, DBUS_TYPE_STRING
, &status
)
857 !dbus_message_iter_append_basic(&iter
, DBUS_TYPE_STRING
,
861 dbus_connection_send(iface
->con
, msg
, NULL
);
864 dbus_message_unref(msg
);
869 * wpas_dbus_signal_sta - Send a station related event signal
870 * @wpa_s: %wpa_supplicant network interface data
871 * @sta: station mac address
872 * @sig_name: signal name - StaAuthorized or StaDeauthorized
874 * Notify listeners about event related with station
876 static void wpas_dbus_signal_sta(struct wpa_supplicant
*wpa_s
,
877 const u8
*sta
, const char *sig_name
)
879 struct wpas_dbus_priv
*iface
;
881 char sta_mac
[WPAS_DBUS_OBJECT_PATH_MAX
];
884 os_snprintf(sta_mac
, WPAS_DBUS_OBJECT_PATH_MAX
, MACSTR
, MAC2STR(sta
));
887 iface
= wpa_s
->global
->dbus
;
889 /* Do nothing if the control interface is not turned on */
893 msg
= dbus_message_new_signal(wpa_s
->dbus_new_path
,
894 WPAS_DBUS_NEW_IFACE_INTERFACE
, sig_name
);
898 if (dbus_message_append_args(msg
, DBUS_TYPE_STRING
, &dev_mac
,
900 dbus_connection_send(iface
->con
, msg
, NULL
);
902 wpa_printf(MSG_ERROR
, "dbus: Failed to construct signal");
903 dbus_message_unref(msg
);
905 wpa_printf(MSG_DEBUG
, "dbus: Station MAC address '%s' '%s'",
911 * wpas_dbus_signal_sta_authorized - Send a STA authorized signal
912 * @wpa_s: %wpa_supplicant network interface data
913 * @sta: station mac address
915 * Notify listeners a new station has been authorized
917 void wpas_dbus_signal_sta_authorized(struct wpa_supplicant
*wpa_s
,
920 wpas_dbus_signal_sta(wpa_s
, sta
, "StaAuthorized");
925 * wpas_dbus_signal_sta_deauthorized - Send a STA deauthorized signal
926 * @wpa_s: %wpa_supplicant network interface data
927 * @sta: station mac address
929 * Notify listeners a station has been deauthorized
931 void wpas_dbus_signal_sta_deauthorized(struct wpa_supplicant
*wpa_s
,
934 wpas_dbus_signal_sta(wpa_s
, sta
, "StaDeauthorized");
941 * wpas_dbus_signal_p2p_group_removed - Signals P2P group was removed
942 * @wpa_s: %wpa_supplicant network interface data
943 * @role: role of this device (client or GO)
944 * Sends signal with i/f name and role as string arguments
946 void wpas_dbus_signal_p2p_group_removed(struct wpa_supplicant
*wpa_s
,
951 DBusMessageIter iter
, dict_iter
;
952 struct wpas_dbus_priv
*iface
= wpa_s
->global
->dbus
;
953 struct wpa_supplicant
*parent
;
955 /* Do nothing if the control interface is not turned on */
959 parent
= wpa_s
->parent
;
960 if (parent
->p2p_mgmt
)
961 parent
= parent
->parent
;
963 if (!wpa_s
->dbus_groupobj_path
)
966 msg
= dbus_message_new_signal(parent
->dbus_new_path
,
967 WPAS_DBUS_NEW_IFACE_P2PDEVICE
,
972 dbus_message_iter_init_append(msg
, &iter
);
973 if (!wpa_dbus_dict_open_write(&iter
, &dict_iter
))
976 if (!wpa_dbus_dict_append_object_path(&dict_iter
,
978 wpa_s
->dbus_new_path
))
981 if (!wpa_dbus_dict_append_string(&dict_iter
, "role", role
))
984 if (!wpa_dbus_dict_append_object_path(&dict_iter
, "group_object",
985 wpa_s
->dbus_groupobj_path
) ||
986 !wpa_dbus_dict_close_write(&iter
, &dict_iter
))
990 dbus_connection_send(iface
->con
, msg
, NULL
);
994 wpa_printf(MSG_ERROR
,
995 "dbus: Failed to construct GroupFinished");
997 dbus_message_unref(msg
);
1002 * wpas_dbus_signal_p2p_provision_discovery - Signals various PD events
1004 * @dev_addr - who sent the request or responded to our request.
1005 * @request - Will be 1 if request, 0 for response.
1006 * @status - valid only in case of response
1007 * @config_methods - wps config methods
1008 * @generated_pin - pin to be displayed in case of WPS_CONFIG_DISPLAY method
1010 * Sends following provision discovery related events:
1011 * ProvisionDiscoveryRequestDisplayPin
1012 * ProvisionDiscoveryResponseDisplayPin
1013 * ProvisionDiscoveryRequestEnterPin
1014 * ProvisionDiscoveryResponseEnterPin
1015 * ProvisionDiscoveryPBCRequest
1016 * ProvisionDiscoveryPBCResponse
1019 * ProvisionDiscoveryFailure (timeout case)
1021 void wpas_dbus_signal_p2p_provision_discovery(struct wpa_supplicant
*wpa_s
,
1022 const u8
*dev_addr
, int request
,
1023 enum p2p_prov_disc_status status
,
1025 unsigned int generated_pin
)
1028 DBusMessageIter iter
;
1029 struct wpas_dbus_priv
*iface
;
1032 char peer_obj_path
[WPAS_DBUS_OBJECT_PATH_MAX
], *path
;
1034 char pin
[9], *p_pin
= NULL
;
1036 iface
= wpa_s
->global
->dbus
;
1038 /* Do nothing if the control interface is not turned on */
1042 if (wpa_s
->p2p_mgmt
)
1043 wpa_s
= wpa_s
->parent
;
1045 if (request
|| !status
) {
1046 if (config_methods
& WPS_CONFIG_DISPLAY
)
1048 "ProvisionDiscoveryRequestDisplayPin" :
1049 "ProvisionDiscoveryResponseEnterPin";
1050 else if (config_methods
& WPS_CONFIG_KEYPAD
)
1052 "ProvisionDiscoveryRequestEnterPin" :
1053 "ProvisionDiscoveryResponseDisplayPin";
1054 else if (config_methods
& WPS_CONFIG_PUSHBUTTON
)
1055 _signal
= request
? "ProvisionDiscoveryPBCRequest" :
1056 "ProvisionDiscoveryPBCResponse";
1058 return; /* Unknown or un-supported method */
1059 } else if (!request
&& status
)
1060 /* Explicit check for failure response */
1061 _signal
= "ProvisionDiscoveryFailure";
1063 add_pin
= ((request
&& (config_methods
& WPS_CONFIG_DISPLAY
)) ||
1064 (!request
&& !status
&&
1065 (config_methods
& WPS_CONFIG_KEYPAD
)));
1068 os_snprintf(pin
, sizeof(pin
), "%08d", generated_pin
);
1072 msg
= dbus_message_new_signal(wpa_s
->dbus_new_path
,
1073 WPAS_DBUS_NEW_IFACE_P2PDEVICE
, _signal
);
1077 /* Check if this is a known peer */
1078 if (!p2p_peer_known(wpa_s
->global
->p2p
, dev_addr
))
1081 os_snprintf(peer_obj_path
, WPAS_DBUS_OBJECT_PATH_MAX
,
1082 "%s/" WPAS_DBUS_NEW_P2P_PEERS_PART
"/"
1084 wpa_s
->dbus_new_path
, MAC2STR(dev_addr
));
1086 path
= peer_obj_path
;
1088 dbus_message_iter_init_append(msg
, &iter
);
1090 if (!dbus_message_iter_append_basic(&iter
,
1091 DBUS_TYPE_OBJECT_PATH
,
1095 if (!request
&& status
)
1096 /* Attach status to ProvisionDiscoveryFailure */
1097 error_ret
= !dbus_message_iter_append_basic(&iter
,
1101 error_ret
= (add_pin
&&
1102 !dbus_message_iter_append_basic(&iter
,
1108 dbus_connection_send(iface
->con
, msg
, NULL
);
1110 wpa_printf(MSG_ERROR
, "dbus: Failed to construct signal");
1112 dbus_message_unref(msg
);
1116 void wpas_dbus_signal_p2p_go_neg_req(struct wpa_supplicant
*wpa_s
,
1117 const u8
*src
, u16 dev_passwd_id
)
1120 DBusMessageIter iter
;
1121 struct wpas_dbus_priv
*iface
;
1122 char peer_obj_path
[WPAS_DBUS_OBJECT_PATH_MAX
], *path
;
1124 iface
= wpa_s
->global
->dbus
;
1126 /* Do nothing if the control interface is not turned on */
1130 if (wpa_s
->p2p_mgmt
)
1131 wpa_s
= wpa_s
->parent
;
1133 os_snprintf(peer_obj_path
, WPAS_DBUS_OBJECT_PATH_MAX
,
1134 "%s/" WPAS_DBUS_NEW_P2P_PEERS_PART
"/" COMPACT_MACSTR
,
1135 wpa_s
->dbus_new_path
, MAC2STR(src
));
1136 path
= peer_obj_path
;
1138 msg
= dbus_message_new_signal(wpa_s
->dbus_new_path
,
1139 WPAS_DBUS_NEW_IFACE_P2PDEVICE
,
1140 "GONegotiationRequest");
1144 dbus_message_iter_init_append(msg
, &iter
);
1146 if (!dbus_message_iter_append_basic(&iter
, DBUS_TYPE_OBJECT_PATH
,
1148 !dbus_message_iter_append_basic(&iter
, DBUS_TYPE_UINT16
,
1150 wpa_printf(MSG_ERROR
, "dbus: Failed to construct signal");
1152 dbus_connection_send(iface
->con
, msg
, NULL
);
1154 dbus_message_unref(msg
);
1158 static int wpas_dbus_get_group_obj_path(struct wpa_supplicant
*wpa_s
,
1159 const struct wpa_ssid
*ssid
,
1160 char *group_obj_path
)
1164 if (os_memcmp(ssid
->ssid
, P2P_WILDCARD_SSID
, P2P_WILDCARD_SSID_LEN
))
1167 os_memcpy(group_name
, ssid
->ssid
+ P2P_WILDCARD_SSID_LEN
, 2);
1168 group_name
[2] = '\0';
1170 os_snprintf(group_obj_path
, WPAS_DBUS_OBJECT_PATH_MAX
,
1171 "%s/" WPAS_DBUS_NEW_P2P_GROUPS_PART
"/%s",
1172 wpa_s
->dbus_new_path
, group_name
);
1178 struct group_changed_data
{
1179 struct wpa_supplicant
*wpa_s
;
1180 struct p2p_peer_info
*info
;
1184 static int match_group_where_peer_is_client(struct p2p_group
*group
,
1187 struct group_changed_data
*data
= user_data
;
1188 const struct p2p_group_config
*cfg
;
1189 struct wpa_supplicant
*wpa_s_go
;
1191 if (!p2p_group_is_client_connected(group
, data
->info
->p2p_device_addr
))
1194 cfg
= p2p_group_get_config(group
);
1196 wpa_s_go
= wpas_get_p2p_go_iface(data
->wpa_s
, cfg
->ssid
,
1198 if (wpa_s_go
!= NULL
&& wpa_s_go
== data
->wpa_s
) {
1199 wpas_dbus_signal_peer_groups_changed(
1200 data
->wpa_s
->parent
, data
->info
->p2p_device_addr
);
1208 static void signal_peer_groups_changed(struct p2p_peer_info
*info
,
1211 struct group_changed_data
*data
= user_data
;
1212 struct wpa_supplicant
*wpa_s_go
;
1214 wpa_s_go
= wpas_get_p2p_client_iface(data
->wpa_s
,
1215 info
->p2p_device_addr
);
1216 if (wpa_s_go
!= NULL
&& wpa_s_go
== data
->wpa_s
) {
1217 wpas_dbus_signal_peer_groups_changed(data
->wpa_s
->parent
,
1218 info
->p2p_device_addr
);
1223 p2p_loop_on_all_groups(data
->wpa_s
->global
->p2p
,
1224 match_group_where_peer_is_client
, data
);
1229 static void peer_groups_changed(struct wpa_supplicant
*wpa_s
)
1231 struct group_changed_data data
;
1233 os_memset(&data
, 0, sizeof(data
));
1236 p2p_loop_on_known_peers(wpa_s
->global
->p2p
,
1237 signal_peer_groups_changed
, &data
);
1242 * wpas_dbus_signal_p2p_group_started - Signals P2P group has
1243 * started. Emitted when a group is successfully started
1244 * irrespective of the role (client/GO) of the current device
1246 * @wpa_s: %wpa_supplicant network interface data
1247 * @ssid: SSID object
1248 * @client: this device is P2P client
1249 * @network_id: network id of the group started, use instead of ssid->id
1250 * to account for persistent groups
1252 void wpas_dbus_signal_p2p_group_started(struct wpa_supplicant
*wpa_s
,
1253 const struct wpa_ssid
*ssid
,
1254 int client
, int network_id
)
1257 DBusMessageIter iter
, dict_iter
;
1258 struct wpas_dbus_priv
*iface
;
1259 struct wpa_supplicant
*parent
;
1261 parent
= wpa_s
->parent
;
1262 if (parent
->p2p_mgmt
)
1263 parent
= parent
->parent
;
1265 iface
= parent
->global
->dbus
;
1267 /* Do nothing if the control interface is not turned on */
1271 if (wpa_s
->dbus_groupobj_path
== NULL
)
1274 /* New interface has been created for this group */
1275 msg
= dbus_message_new_signal(parent
->dbus_new_path
,
1276 WPAS_DBUS_NEW_IFACE_P2PDEVICE
,
1281 dbus_message_iter_init_append(msg
, &iter
);
1282 if (!wpa_dbus_dict_open_write(&iter
, &dict_iter
))
1286 * In case the device supports creating a separate interface the
1287 * DBus client will need to know the object path for the interface
1288 * object this group was created on, so include it here.
1290 if (!wpa_dbus_dict_append_object_path(&dict_iter
,
1292 wpa_s
->dbus_new_path
))
1295 if (!wpa_dbus_dict_append_string(&dict_iter
, "role",
1296 client
? "client" : "GO"))
1299 if (!wpa_dbus_dict_append_object_path(&dict_iter
, "group_object",
1300 wpa_s
->dbus_groupobj_path
) ||
1301 !wpa_dbus_dict_close_write(&iter
, &dict_iter
))
1304 dbus_connection_send(iface
->con
, msg
, NULL
);
1307 peer_groups_changed(wpa_s
);
1310 dbus_message_unref(msg
);
1316 * Method to emit GONegotiation Success or Failure signals based
1318 * @status: Status of the GO neg request. 0 for success, other for errors.
1320 void wpas_dbus_signal_p2p_go_neg_resp(struct wpa_supplicant
*wpa_s
,
1321 struct p2p_go_neg_results
*res
)
1324 DBusMessageIter iter
, dict_iter
;
1325 DBusMessageIter iter_dict_entry
, iter_dict_val
, iter_dict_array
;
1326 struct wpas_dbus_priv
*iface
;
1327 char peer_obj_path
[WPAS_DBUS_OBJECT_PATH_MAX
], *path
;
1328 dbus_int32_t freqs
[P2P_MAX_CHANNELS
];
1329 dbus_int32_t
*f_array
= freqs
;
1332 iface
= wpa_s
->global
->dbus
;
1334 if (wpa_s
->p2p_mgmt
)
1335 wpa_s
= wpa_s
->parent
;
1337 os_memset(freqs
, 0, sizeof(freqs
));
1338 /* Do nothing if the control interface is not turned on */
1342 os_snprintf(peer_obj_path
, WPAS_DBUS_OBJECT_PATH_MAX
,
1343 "%s/" WPAS_DBUS_NEW_P2P_PEERS_PART
"/" COMPACT_MACSTR
,
1344 wpa_s
->dbus_new_path
, MAC2STR(res
->peer_device_addr
));
1345 path
= peer_obj_path
;
1347 msg
= dbus_message_new_signal(wpa_s
->dbus_new_path
,
1348 WPAS_DBUS_NEW_IFACE_P2PDEVICE
,
1349 res
->status
? "GONegotiationFailure" :
1350 "GONegotiationSuccess");
1354 dbus_message_iter_init_append(msg
, &iter
);
1355 if (!wpa_dbus_dict_open_write(&iter
, &dict_iter
))
1357 if (!wpa_dbus_dict_append_object_path(&dict_iter
, "peer_object",
1359 !wpa_dbus_dict_append_int32(&dict_iter
, "status", res
->status
))
1364 int freq_list_num
= 0;
1367 !wpa_dbus_dict_append_string(&dict_iter
, "passphrase",
1371 if (!wpa_dbus_dict_append_string(&dict_iter
, "role_go",
1372 res
->role_go
? "GO" :
1374 !wpa_dbus_dict_append_int32(&dict_iter
, "frequency",
1376 !wpa_dbus_dict_append_byte_array(&dict_iter
, "ssid",
1377 (const char *) res
->ssid
,
1379 !wpa_dbus_dict_append_byte_array(&dict_iter
,
1382 res
->peer_device_addr
,
1384 !wpa_dbus_dict_append_byte_array(&dict_iter
,
1385 "peer_interface_addr",
1387 res
->peer_interface_addr
,
1389 !wpa_dbus_dict_append_string(&dict_iter
, "wps_method",
1390 p2p_wps_method_text(
1394 for (i
= 0; i
< P2P_MAX_CHANNELS
; i
++) {
1395 if (res
->freq_list
[i
]) {
1396 freqs
[i
] = res
->freq_list
[i
];
1401 if (!wpa_dbus_dict_begin_array(&dict_iter
,
1403 DBUS_TYPE_INT32_AS_STRING
,
1409 if (!dbus_message_iter_append_fixed_array(&iter_dict_array
,
1415 if (!wpa_dbus_dict_end_array(&dict_iter
,
1421 if (!wpa_dbus_dict_append_int32(&dict_iter
, "persistent_group",
1422 res
->persistent_group
) ||
1423 !wpa_dbus_dict_append_uint32(&dict_iter
,
1424 "peer_config_timeout",
1425 res
->peer_config_timeout
))
1429 if (!wpa_dbus_dict_close_write(&iter
, &dict_iter
))
1432 dbus_connection_send(iface
->con
, msg
, NULL
);
1434 dbus_message_unref(msg
);
1440 * Method to emit Invitation Result signal based on status and
1442 * @status: Status of the Invite request. 0 for success, other
1444 * @bssid : Basic Service Set Identifier
1446 void wpas_dbus_signal_p2p_invitation_result(struct wpa_supplicant
*wpa_s
,
1447 int status
, const u8
*bssid
)
1450 DBusMessageIter iter
, dict_iter
;
1451 struct wpas_dbus_priv
*iface
;
1453 wpa_printf(MSG_DEBUG
, "%s", __func__
);
1455 iface
= wpa_s
->global
->dbus
;
1456 /* Do nothing if the control interface is not turned on */
1460 if (wpa_s
->p2p_mgmt
)
1461 wpa_s
= wpa_s
->parent
;
1463 msg
= dbus_message_new_signal(wpa_s
->dbus_new_path
,
1464 WPAS_DBUS_NEW_IFACE_P2PDEVICE
,
1465 "InvitationResult");
1470 dbus_message_iter_init_append(msg
, &iter
);
1471 if (!wpa_dbus_dict_open_write(&iter
, &dict_iter
))
1474 if (!wpa_dbus_dict_append_int32(&dict_iter
, "status", status
))
1477 if (!wpa_dbus_dict_append_byte_array(&dict_iter
, "BSSID",
1478 (const char *) bssid
,
1482 if (!wpa_dbus_dict_close_write(&iter
, &dict_iter
))
1485 dbus_connection_send(iface
->con
, msg
, NULL
);
1488 dbus_message_unref(msg
);
1494 * Method to emit a signal for a peer joining the group.
1495 * The signal will carry path to the group member object
1496 * constructed using p2p i/f addr used for connecting.
1498 * @wpa_s: %wpa_supplicant network interface data
1499 * @peer_addr: P2P Device Address of the peer joining the group
1501 void wpas_dbus_signal_p2p_peer_joined(struct wpa_supplicant
*wpa_s
,
1502 const u8
*peer_addr
)
1504 struct wpas_dbus_priv
*iface
;
1506 DBusMessageIter iter
;
1507 char peer_obj_path
[WPAS_DBUS_OBJECT_PATH_MAX
], *path
;
1508 struct wpa_supplicant
*parent
;
1510 iface
= wpa_s
->global
->dbus
;
1512 /* Do nothing if the control interface is not turned on */
1516 if (!wpa_s
->dbus_groupobj_path
)
1519 parent
= wpa_s
->parent
;
1520 if (parent
->p2p_mgmt
)
1521 parent
= parent
->parent
;
1523 os_snprintf(peer_obj_path
, WPAS_DBUS_OBJECT_PATH_MAX
,
1524 "%s/" WPAS_DBUS_NEW_P2P_PEERS_PART
"/"
1526 parent
->dbus_new_path
, MAC2STR(peer_addr
));
1528 msg
= dbus_message_new_signal(wpa_s
->dbus_groupobj_path
,
1529 WPAS_DBUS_NEW_IFACE_P2P_GROUP
,
1534 dbus_message_iter_init_append(msg
, &iter
);
1535 path
= peer_obj_path
;
1536 if (!dbus_message_iter_append_basic(&iter
, DBUS_TYPE_OBJECT_PATH
,
1540 dbus_connection_send(iface
->con
, msg
, NULL
);
1541 dbus_message_unref(msg
);
1543 wpas_dbus_signal_peer_groups_changed(parent
, peer_addr
);
1548 wpa_printf(MSG_ERROR
, "dbus: Failed to construct signal");
1549 dbus_message_unref(msg
);
1555 * Method to emit a signal for a peer disconnecting the group.
1556 * The signal will carry path to the group member object
1557 * constructed using the P2P Device Address of the peer.
1559 * @wpa_s: %wpa_supplicant network interface data
1560 * @peer_addr: P2P Device Address of the peer joining the group
1562 void wpas_dbus_signal_p2p_peer_disconnected(struct wpa_supplicant
*wpa_s
,
1563 const u8
*peer_addr
)
1565 struct wpas_dbus_priv
*iface
;
1567 DBusMessageIter iter
;
1568 char peer_obj_path
[WPAS_DBUS_OBJECT_PATH_MAX
], *path
;
1569 struct wpa_supplicant
*parent
;
1571 iface
= wpa_s
->global
->dbus
;
1573 /* Do nothing if the control interface is not turned on */
1577 if (!wpa_s
->dbus_groupobj_path
)
1580 parent
= wpa_s
->parent
;
1581 if (parent
->p2p_mgmt
)
1582 parent
= parent
->parent
;
1584 os_snprintf(peer_obj_path
, WPAS_DBUS_OBJECT_PATH_MAX
,
1585 "%s/" WPAS_DBUS_NEW_P2P_PEERS_PART
"/"
1587 parent
->dbus_new_path
, MAC2STR(peer_addr
));
1589 msg
= dbus_message_new_signal(wpa_s
->dbus_groupobj_path
,
1590 WPAS_DBUS_NEW_IFACE_P2P_GROUP
,
1591 "PeerDisconnected");
1595 dbus_message_iter_init_append(msg
, &iter
);
1596 path
= peer_obj_path
;
1597 if (!dbus_message_iter_append_basic(&iter
, DBUS_TYPE_OBJECT_PATH
,
1601 dbus_connection_send(iface
->con
, msg
, NULL
);
1602 dbus_message_unref(msg
);
1604 wpas_dbus_signal_peer_groups_changed(parent
, peer_addr
);
1609 wpa_printf(MSG_ERROR
, "dbus: Failed to construct PeerDisconnected "
1611 dbus_message_unref(msg
);
1617 * Method to emit a signal for a service discovery request.
1618 * The signal will carry station address, frequency, dialog token,
1619 * update indicator and it tlvs
1621 * @wpa_s: %wpa_supplicant network interface data
1622 * @sa: station addr (p2p i/f) of the peer
1623 * @dialog_token: service discovery request dialog token
1624 * @update_indic: service discovery request update indicator
1625 * @tlvs: service discovery request genrated byte array of tlvs
1626 * @tlvs_len: service discovery request tlvs length
1628 void wpas_dbus_signal_p2p_sd_request(struct wpa_supplicant
*wpa_s
,
1629 int freq
, const u8
*sa
, u8 dialog_token
,
1630 u16 update_indic
, const u8
*tlvs
,
1634 DBusMessageIter iter
, dict_iter
;
1635 struct wpas_dbus_priv
*iface
;
1636 char peer_obj_path
[WPAS_DBUS_OBJECT_PATH_MAX
], *path
;
1637 iface
= wpa_s
->global
->dbus
;
1639 /* Do nothing if the control interface is not turned on */
1643 if (wpa_s
->p2p_mgmt
)
1644 wpa_s
= wpa_s
->parent
;
1646 msg
= dbus_message_new_signal(wpa_s
->dbus_new_path
,
1647 WPAS_DBUS_NEW_IFACE_P2PDEVICE
,
1648 "ServiceDiscoveryRequest");
1652 /* Check if this is a known peer */
1653 if (!p2p_peer_known(wpa_s
->global
->p2p
, sa
))
1656 os_snprintf(peer_obj_path
, WPAS_DBUS_OBJECT_PATH_MAX
,
1657 "%s/" WPAS_DBUS_NEW_P2P_PEERS_PART
"/"
1658 COMPACT_MACSTR
, wpa_s
->dbus_new_path
, MAC2STR(sa
));
1660 path
= peer_obj_path
;
1662 dbus_message_iter_init_append(msg
, &iter
);
1663 if (!wpa_dbus_dict_open_write(&iter
, &dict_iter
))
1667 if (!wpa_dbus_dict_append_object_path(&dict_iter
, "peer_object",
1669 !wpa_dbus_dict_append_int32(&dict_iter
, "frequency", freq
) ||
1670 !wpa_dbus_dict_append_int32(&dict_iter
, "dialog_token",
1672 !wpa_dbus_dict_append_uint16(&dict_iter
, "update_indicator",
1674 !wpa_dbus_dict_append_byte_array(&dict_iter
, "tlvs",
1675 (const char *) tlvs
,
1677 !wpa_dbus_dict_close_write(&iter
, &dict_iter
))
1680 dbus_connection_send(iface
->con
, msg
, NULL
);
1681 dbus_message_unref(msg
);
1684 wpa_printf(MSG_ERROR
, "dbus: Failed to construct signal");
1685 dbus_message_unref(msg
);
1691 * Method to emit a signal for a service discovery response.
1692 * The signal will carry station address, update indicator and it
1695 * @wpa_s: %wpa_supplicant network interface data
1696 * @sa: station addr (p2p i/f) of the peer
1697 * @update_indic: service discovery request update indicator
1698 * @tlvs: service discovery request genrated byte array of tlvs
1699 * @tlvs_len: service discovery request tlvs length
1701 void wpas_dbus_signal_p2p_sd_response(struct wpa_supplicant
*wpa_s
,
1702 const u8
*sa
, u16 update_indic
,
1703 const u8
*tlvs
, size_t tlvs_len
)
1706 DBusMessageIter iter
, dict_iter
;
1707 struct wpas_dbus_priv
*iface
;
1708 char peer_obj_path
[WPAS_DBUS_OBJECT_PATH_MAX
], *path
;
1709 iface
= wpa_s
->global
->dbus
;
1711 /* Do nothing if the control interface is not turned on */
1715 if (wpa_s
->p2p_mgmt
)
1716 wpa_s
= wpa_s
->parent
;
1718 msg
= dbus_message_new_signal(wpa_s
->dbus_new_path
,
1719 WPAS_DBUS_NEW_IFACE_P2PDEVICE
,
1720 "ServiceDiscoveryResponse");
1724 /* Check if this is a known peer */
1725 if (!p2p_peer_known(wpa_s
->global
->p2p
, sa
))
1728 os_snprintf(peer_obj_path
, WPAS_DBUS_OBJECT_PATH_MAX
,
1729 "%s/" WPAS_DBUS_NEW_P2P_PEERS_PART
"/"
1730 COMPACT_MACSTR
, wpa_s
->dbus_new_path
, MAC2STR(sa
));
1732 path
= peer_obj_path
;
1734 dbus_message_iter_init_append(msg
, &iter
);
1735 if (!wpa_dbus_dict_open_write(&iter
, &dict_iter
))
1738 if (!wpa_dbus_dict_append_object_path(&dict_iter
, "peer_object",
1740 !wpa_dbus_dict_append_uint16(&dict_iter
, "update_indicator",
1742 !wpa_dbus_dict_append_byte_array(&dict_iter
, "tlvs",
1743 (const char *) tlvs
,
1745 !wpa_dbus_dict_close_write(&iter
, &dict_iter
))
1749 dbus_connection_send(iface
->con
, msg
, NULL
);
1750 dbus_message_unref(msg
);
1753 wpa_printf(MSG_ERROR
, "dbus: Failed to construct signal");
1754 dbus_message_unref(msg
);
1758 * wpas_dbus_signal_persistent_group - Send a persistent group related
1760 * @wpa_s: %wpa_supplicant network interface data
1761 * @id: new persistent group id
1762 * @sig_name: signal name - PersistentGroupAdded, PersistentGroupRemoved
1763 * @properties: determines if add second argument with object properties
1765 * Notify listeners about an event related to persistent groups.
1767 static void wpas_dbus_signal_persistent_group(struct wpa_supplicant
*wpa_s
,
1768 int id
, const char *sig_name
,
1771 struct wpas_dbus_priv
*iface
;
1773 DBusMessageIter iter
;
1774 char pgrp_obj_path
[WPAS_DBUS_OBJECT_PATH_MAX
], *path
;
1776 iface
= wpa_s
->global
->dbus
;
1778 /* Do nothing if the control interface is not turned on */
1782 if (wpa_s
->p2p_mgmt
)
1783 wpa_s
= wpa_s
->parent
;
1785 os_snprintf(pgrp_obj_path
, WPAS_DBUS_OBJECT_PATH_MAX
,
1786 "%s/" WPAS_DBUS_NEW_PERSISTENT_GROUPS_PART
"/%u",
1787 wpa_s
->dbus_new_path
, id
);
1789 msg
= dbus_message_new_signal(wpa_s
->dbus_new_path
,
1790 WPAS_DBUS_NEW_IFACE_P2PDEVICE
,
1795 dbus_message_iter_init_append(msg
, &iter
);
1796 path
= pgrp_obj_path
;
1797 if (!dbus_message_iter_append_basic(&iter
, DBUS_TYPE_OBJECT_PATH
,
1802 if (!wpa_dbus_get_object_properties(
1803 iface
, pgrp_obj_path
,
1804 WPAS_DBUS_NEW_IFACE_PERSISTENT_GROUP
, &iter
))
1808 dbus_connection_send(iface
->con
, msg
, NULL
);
1810 dbus_message_unref(msg
);
1814 wpa_printf(MSG_ERROR
, "dbus: Failed to construct signal");
1815 dbus_message_unref(msg
);
1820 * wpas_dbus_signal_persistent_group_added - Send a persistent_group
1822 * @wpa_s: %wpa_supplicant network interface data
1823 * @id: new persistent group id
1825 * Notify listeners about addition of a new persistent group.
1827 static void wpas_dbus_signal_persistent_group_added(
1828 struct wpa_supplicant
*wpa_s
, int id
)
1830 wpas_dbus_signal_persistent_group(wpa_s
, id
, "PersistentGroupAdded",
1836 * wpas_dbus_signal_persistent_group_removed - Send a persistent_group
1838 * @wpa_s: %wpa_supplicant network interface data
1839 * @id: persistent group id
1841 * Notify listeners about removal of a persistent group.
1843 static void wpas_dbus_signal_persistent_group_removed(
1844 struct wpa_supplicant
*wpa_s
, int id
)
1846 wpas_dbus_signal_persistent_group(wpa_s
, id
, "PersistentGroupRemoved",
1852 * wpas_dbus_signal_p2p_wps_failed - Signals WpsFailed event
1853 * @wpa_s: %wpa_supplicant network interface data
1855 * Sends Event dbus signal with name "fail" and dictionary containing
1856 * "msg" field with fail message number (int32) as arguments
1858 void wpas_dbus_signal_p2p_wps_failed(struct wpa_supplicant
*wpa_s
,
1859 struct wps_event_fail
*fail
)
1863 DBusMessageIter iter
, dict_iter
;
1864 struct wpas_dbus_priv
*iface
;
1867 iface
= wpa_s
->global
->dbus
;
1869 /* Do nothing if the control interface is not turned on */
1873 if (wpa_s
->p2p_mgmt
)
1874 wpa_s
= wpa_s
->parent
;
1876 msg
= dbus_message_new_signal(wpa_s
->dbus_new_path
,
1877 WPAS_DBUS_NEW_IFACE_P2PDEVICE
,
1882 dbus_message_iter_init_append(msg
, &iter
);
1884 if (!dbus_message_iter_append_basic(&iter
, DBUS_TYPE_STRING
, &key
) ||
1885 !wpa_dbus_dict_open_write(&iter
, &dict_iter
) ||
1886 !wpa_dbus_dict_append_int32(&dict_iter
, "msg", fail
->msg
) ||
1887 !wpa_dbus_dict_append_int16(&dict_iter
, "config_error",
1888 fail
->config_error
) ||
1889 !wpa_dbus_dict_close_write(&iter
, &dict_iter
))
1890 wpa_printf(MSG_ERROR
, "dbus: Failed to construct signal");
1892 dbus_connection_send(iface
->con
, msg
, NULL
);
1894 dbus_message_unref(msg
);
1897 #endif /*CONFIG_P2P*/
1901 * wpas_dbus_signal_prop_changed - Signals change of property
1902 * @wpa_s: %wpa_supplicant network interface data
1903 * @property: indicates which property has changed
1905 * Sends PropertyChanged signals with path, interface and arguments
1906 * depending on which property has changed.
1908 void wpas_dbus_signal_prop_changed(struct wpa_supplicant
*wpa_s
,
1909 enum wpas_dbus_prop property
)
1914 if (wpa_s
->dbus_new_path
== NULL
)
1915 return; /* Skip signal since D-Bus setup is not yet ready */
1919 case WPAS_DBUS_PROP_AP_SCAN
:
1922 case WPAS_DBUS_PROP_SCANNING
:
1925 case WPAS_DBUS_PROP_STATE
:
1928 case WPAS_DBUS_PROP_CURRENT_BSS
:
1929 prop
= "CurrentBSS";
1931 case WPAS_DBUS_PROP_CURRENT_NETWORK
:
1932 prop
= "CurrentNetwork";
1934 case WPAS_DBUS_PROP_BSSS
:
1937 case WPAS_DBUS_PROP_CURRENT_AUTH_MODE
:
1938 prop
= "CurrentAuthMode";
1940 case WPAS_DBUS_PROP_DISCONNECT_REASON
:
1941 prop
= "DisconnectReason";
1945 wpa_printf(MSG_ERROR
, "dbus: %s: Unknown Property value %d",
1946 __func__
, property
);
1950 wpa_dbus_mark_property_changed(wpa_s
->global
->dbus
,
1951 wpa_s
->dbus_new_path
,
1952 WPAS_DBUS_NEW_IFACE_INTERFACE
, prop
);
1954 wpa_dbus_flush_object_changed_properties(
1955 wpa_s
->global
->dbus
->con
, wpa_s
->dbus_new_path
);
1961 * wpas_dbus_bss_signal_prop_changed - Signals change of BSS property
1962 * @wpa_s: %wpa_supplicant network interface data
1963 * @property: indicates which property has changed
1964 * @id: unique BSS identifier
1966 * Sends PropertyChanged signals with path, interface, and arguments depending
1967 * on which property has changed.
1969 void wpas_dbus_bss_signal_prop_changed(struct wpa_supplicant
*wpa_s
,
1970 enum wpas_dbus_bss_prop property
,
1973 char path
[WPAS_DBUS_OBJECT_PATH_MAX
];
1977 case WPAS_DBUS_BSS_PROP_SIGNAL
:
1980 case WPAS_DBUS_BSS_PROP_FREQ
:
1983 case WPAS_DBUS_BSS_PROP_MODE
:
1986 case WPAS_DBUS_BSS_PROP_PRIVACY
:
1989 case WPAS_DBUS_BSS_PROP_RATES
:
1992 case WPAS_DBUS_BSS_PROP_WPA
:
1995 case WPAS_DBUS_BSS_PROP_RSN
:
1998 case WPAS_DBUS_BSS_PROP_WPS
:
2001 case WPAS_DBUS_BSS_PROP_IES
:
2004 case WPAS_DBUS_BSS_PROP_AGE
:
2008 wpa_printf(MSG_ERROR
, "dbus: %s: Unknown Property value %d",
2009 __func__
, property
);
2013 os_snprintf(path
, WPAS_DBUS_OBJECT_PATH_MAX
,
2014 "%s/" WPAS_DBUS_NEW_BSSIDS_PART
"/%u",
2015 wpa_s
->dbus_new_path
, id
);
2017 wpa_dbus_mark_property_changed(wpa_s
->global
->dbus
, path
,
2018 WPAS_DBUS_NEW_IFACE_BSS
, prop
);
2023 * wpas_dbus_signal_debug_level_changed - Signals change of debug param
2024 * @global: wpa_global structure
2026 * Sends PropertyChanged signals informing that debug level has changed.
2028 void wpas_dbus_signal_debug_level_changed(struct wpa_global
*global
)
2030 wpa_dbus_mark_property_changed(global
->dbus
, WPAS_DBUS_NEW_PATH
,
2031 WPAS_DBUS_NEW_INTERFACE
,
2037 * wpas_dbus_signal_debug_timestamp_changed - Signals change of debug param
2038 * @global: wpa_global structure
2040 * Sends PropertyChanged signals informing that debug timestamp has changed.
2042 void wpas_dbus_signal_debug_timestamp_changed(struct wpa_global
*global
)
2044 wpa_dbus_mark_property_changed(global
->dbus
, WPAS_DBUS_NEW_PATH
,
2045 WPAS_DBUS_NEW_INTERFACE
,
2051 * wpas_dbus_signal_debug_show_keys_changed - Signals change of debug param
2052 * @global: wpa_global structure
2054 * Sends PropertyChanged signals informing that debug show_keys has changed.
2056 void wpas_dbus_signal_debug_show_keys_changed(struct wpa_global
*global
)
2058 wpa_dbus_mark_property_changed(global
->dbus
, WPAS_DBUS_NEW_PATH
,
2059 WPAS_DBUS_NEW_INTERFACE
,
2064 static void wpas_dbus_register(struct wpa_dbus_object_desc
*obj_desc
,
2066 WPADBusArgumentFreeFunction priv_free
,
2067 const struct wpa_dbus_method_desc
*methods
,
2068 const struct wpa_dbus_property_desc
*properties
,
2069 const struct wpa_dbus_signal_desc
*signals
)
2073 obj_desc
->user_data
= priv
;
2074 obj_desc
->user_data_free_func
= priv_free
;
2075 obj_desc
->methods
= methods
;
2076 obj_desc
->properties
= properties
;
2077 obj_desc
->signals
= signals
;
2079 for (n
= 0; properties
&& properties
->dbus_property
; properties
++)
2082 obj_desc
->prop_changed_flags
= os_zalloc(n
);
2083 if (!obj_desc
->prop_changed_flags
)
2084 wpa_printf(MSG_DEBUG
, "dbus: %s: can't register handlers",
2089 static const struct wpa_dbus_method_desc wpas_dbus_global_methods
[] = {
2090 { "CreateInterface", WPAS_DBUS_NEW_INTERFACE
,
2091 (WPADBusMethodHandler
) &wpas_dbus_handler_create_interface
,
2093 { "args", "a{sv}", ARG_IN
},
2094 { "path", "o", ARG_OUT
},
2098 { "RemoveInterface", WPAS_DBUS_NEW_INTERFACE
,
2099 (WPADBusMethodHandler
) &wpas_dbus_handler_remove_interface
,
2101 { "path", "o", ARG_IN
},
2105 { "GetInterface", WPAS_DBUS_NEW_INTERFACE
,
2106 (WPADBusMethodHandler
) &wpas_dbus_handler_get_interface
,
2108 { "ifname", "s", ARG_IN
},
2109 { "path", "o", ARG_OUT
},
2113 { NULL
, NULL
, NULL
, { END_ARGS
} }
2116 static const struct wpa_dbus_property_desc wpas_dbus_global_properties
[] = {
2117 { "DebugLevel", WPAS_DBUS_NEW_INTERFACE
, "s",
2118 wpas_dbus_getter_debug_level
,
2119 wpas_dbus_setter_debug_level
2121 { "DebugTimestamp", WPAS_DBUS_NEW_INTERFACE
, "b",
2122 wpas_dbus_getter_debug_timestamp
,
2123 wpas_dbus_setter_debug_timestamp
2125 { "DebugShowKeys", WPAS_DBUS_NEW_INTERFACE
, "b",
2126 wpas_dbus_getter_debug_show_keys
,
2127 wpas_dbus_setter_debug_show_keys
2129 { "Interfaces", WPAS_DBUS_NEW_INTERFACE
, "ao",
2130 wpas_dbus_getter_interfaces
,
2133 { "EapMethods", WPAS_DBUS_NEW_INTERFACE
, "as",
2134 wpas_dbus_getter_eap_methods
,
2137 { "Capabilities", WPAS_DBUS_NEW_INTERFACE
, "as",
2138 wpas_dbus_getter_global_capabilities
,
2141 #ifdef CONFIG_WIFI_DISPLAY
2142 { "WFDIEs", WPAS_DBUS_NEW_INTERFACE
, "ay",
2143 wpas_dbus_getter_global_wfd_ies
,
2144 wpas_dbus_setter_global_wfd_ies
2146 #endif /* CONFIG_WIFI_DISPLAY */
2147 { NULL
, NULL
, NULL
, NULL
, NULL
}
2150 static const struct wpa_dbus_signal_desc wpas_dbus_global_signals
[] = {
2151 { "InterfaceAdded", WPAS_DBUS_NEW_INTERFACE
,
2153 { "path", "o", ARG_OUT
},
2154 { "properties", "a{sv}", ARG_OUT
},
2158 { "InterfaceRemoved", WPAS_DBUS_NEW_INTERFACE
,
2160 { "path", "o", ARG_OUT
},
2164 { "NetworkRequest", WPAS_DBUS_NEW_IFACE_INTERFACE
,
2166 { "path", "o", ARG_OUT
},
2167 { "field", "s", ARG_OUT
},
2168 { "text", "s", ARG_OUT
},
2172 /* Deprecated: use org.freedesktop.DBus.Properties.PropertiesChanged */
2173 { "PropertiesChanged", WPAS_DBUS_NEW_INTERFACE
,
2175 { "properties", "a{sv}", ARG_OUT
},
2179 { NULL
, NULL
, { END_ARGS
} }
2184 * wpas_dbus_ctrl_iface_init - Initialize dbus control interface
2185 * @global: Pointer to global data from wpa_supplicant_init()
2186 * Returns: 0 on success or -1 on failure
2188 * Initialize the dbus control interface for wpa_supplicantand and start
2189 * receiving commands from external programs over the bus.
2191 int wpas_dbus_ctrl_iface_init(struct wpas_dbus_priv
*priv
)
2193 struct wpa_dbus_object_desc
*obj_desc
;
2196 obj_desc
= os_zalloc(sizeof(struct wpa_dbus_object_desc
));
2198 wpa_printf(MSG_ERROR
, "Not enough memory "
2199 "to create object description");
2203 wpas_dbus_register(obj_desc
, priv
->global
, NULL
,
2204 wpas_dbus_global_methods
,
2205 wpas_dbus_global_properties
,
2206 wpas_dbus_global_signals
);
2208 wpa_printf(MSG_DEBUG
, "dbus: Register D-Bus object '%s'",
2209 WPAS_DBUS_NEW_PATH
);
2210 ret
= wpa_dbus_ctrl_iface_init(priv
, WPAS_DBUS_NEW_PATH
,
2211 WPAS_DBUS_NEW_SERVICE
,
2214 free_dbus_object_desc(obj_desc
);
2216 priv
->dbus_new_initialized
= 1;
2223 * wpas_dbus_ctrl_iface_deinit - Deinitialize dbus ctrl interface for
2225 * @iface: Pointer to dbus private data from wpas_dbus_init()
2227 * Deinitialize the dbus control interface that was initialized with
2228 * wpas_dbus_ctrl_iface_init().
2230 void wpas_dbus_ctrl_iface_deinit(struct wpas_dbus_priv
*iface
)
2232 if (!iface
->dbus_new_initialized
)
2234 wpa_printf(MSG_DEBUG
, "dbus: Unregister D-Bus object '%s'",
2235 WPAS_DBUS_NEW_PATH
);
2236 dbus_connection_unregister_object_path(iface
->con
,
2237 WPAS_DBUS_NEW_PATH
);
2241 static void wpa_dbus_free(void *ptr
)
2247 static const struct wpa_dbus_property_desc wpas_dbus_network_properties
[] = {
2248 { "Properties", WPAS_DBUS_NEW_IFACE_NETWORK
, "a{sv}",
2249 wpas_dbus_getter_network_properties
,
2250 wpas_dbus_setter_network_properties
2252 { "Enabled", WPAS_DBUS_NEW_IFACE_NETWORK
, "b",
2253 wpas_dbus_getter_enabled
,
2254 wpas_dbus_setter_enabled
2256 { NULL
, NULL
, NULL
, NULL
, NULL
}
2260 static const struct wpa_dbus_signal_desc wpas_dbus_network_signals
[] = {
2261 /* Deprecated: use org.freedesktop.DBus.Properties.PropertiesChanged */
2262 { "PropertiesChanged", WPAS_DBUS_NEW_IFACE_NETWORK
,
2264 { "properties", "a{sv}", ARG_OUT
},
2268 { NULL
, NULL
, { END_ARGS
} }
2273 * wpas_dbus_register_network - Register a configured network with dbus
2274 * @wpa_s: wpa_supplicant interface structure
2275 * @ssid: network configuration data
2276 * Returns: 0 on success, -1 on failure
2278 * Registers network representing object with dbus
2280 int wpas_dbus_register_network(struct wpa_supplicant
*wpa_s
,
2281 struct wpa_ssid
*ssid
)
2283 struct wpas_dbus_priv
*ctrl_iface
;
2284 struct wpa_dbus_object_desc
*obj_desc
;
2285 struct network_handler_args
*arg
;
2286 char net_obj_path
[WPAS_DBUS_OBJECT_PATH_MAX
];
2290 * If it is a persistent group register it as such.
2291 * This is to handle cases where an interface is being initialized
2292 * with a list of networks read from config.
2294 if (network_is_persistent_group(ssid
))
2295 return wpas_dbus_register_persistent_group(wpa_s
, ssid
);
2296 #endif /* CONFIG_P2P */
2298 /* Do nothing if the control interface is not turned on */
2299 if (wpa_s
== NULL
|| wpa_s
->global
== NULL
)
2301 ctrl_iface
= wpa_s
->global
->dbus
;
2302 if (ctrl_iface
== NULL
)
2305 os_snprintf(net_obj_path
, WPAS_DBUS_OBJECT_PATH_MAX
,
2306 "%s/" WPAS_DBUS_NEW_NETWORKS_PART
"/%u",
2307 wpa_s
->dbus_new_path
, ssid
->id
);
2309 wpa_printf(MSG_DEBUG
, "dbus: Register network object '%s'",
2311 obj_desc
= os_zalloc(sizeof(struct wpa_dbus_object_desc
));
2313 wpa_printf(MSG_ERROR
, "Not enough memory "
2314 "to create object description");
2318 /* allocate memory for handlers arguments */
2319 arg
= os_zalloc(sizeof(struct network_handler_args
));
2321 wpa_printf(MSG_ERROR
, "Not enough memory "
2322 "to create arguments for method");
2329 wpas_dbus_register(obj_desc
, arg
, wpa_dbus_free
, NULL
,
2330 wpas_dbus_network_properties
,
2331 wpas_dbus_network_signals
);
2333 if (wpa_dbus_register_object_per_iface(ctrl_iface
, net_obj_path
,
2334 wpa_s
->ifname
, obj_desc
))
2337 wpas_dbus_signal_network_added(wpa_s
, ssid
->id
);
2342 free_dbus_object_desc(obj_desc
);
2348 * wpas_dbus_unregister_network - Unregister a configured network from dbus
2349 * @wpa_s: wpa_supplicant interface structure
2351 * Returns: 0 on success, -1 on failure
2353 * Unregisters network representing object from dbus
2355 int wpas_dbus_unregister_network(struct wpa_supplicant
*wpa_s
, int nid
)
2357 struct wpas_dbus_priv
*ctrl_iface
;
2358 char net_obj_path
[WPAS_DBUS_OBJECT_PATH_MAX
];
2361 struct wpa_ssid
*ssid
;
2363 ssid
= wpa_config_get_network(wpa_s
->conf
, nid
);
2365 /* If it is a persistent group unregister it as such */
2366 if (ssid
&& network_is_persistent_group(ssid
))
2367 return wpas_dbus_unregister_persistent_group(wpa_s
, nid
);
2368 #endif /* CONFIG_P2P */
2370 /* Do nothing if the control interface is not turned on */
2371 if (wpa_s
->global
== NULL
|| wpa_s
->dbus_new_path
== NULL
)
2373 ctrl_iface
= wpa_s
->global
->dbus
;
2374 if (ctrl_iface
== NULL
)
2377 os_snprintf(net_obj_path
, WPAS_DBUS_OBJECT_PATH_MAX
,
2378 "%s/" WPAS_DBUS_NEW_NETWORKS_PART
"/%u",
2379 wpa_s
->dbus_new_path
, nid
);
2381 wpa_printf(MSG_DEBUG
, "dbus: Unregister network object '%s'",
2383 ret
= wpa_dbus_unregister_object_per_iface(ctrl_iface
, net_obj_path
);
2386 wpas_dbus_signal_network_removed(wpa_s
, nid
);
2392 static const struct wpa_dbus_property_desc wpas_dbus_bss_properties
[] = {
2393 { "SSID", WPAS_DBUS_NEW_IFACE_BSS
, "ay",
2394 wpas_dbus_getter_bss_ssid
,
2397 { "BSSID", WPAS_DBUS_NEW_IFACE_BSS
, "ay",
2398 wpas_dbus_getter_bss_bssid
,
2401 { "Privacy", WPAS_DBUS_NEW_IFACE_BSS
, "b",
2402 wpas_dbus_getter_bss_privacy
,
2405 { "Mode", WPAS_DBUS_NEW_IFACE_BSS
, "s",
2406 wpas_dbus_getter_bss_mode
,
2409 { "Signal", WPAS_DBUS_NEW_IFACE_BSS
, "n",
2410 wpas_dbus_getter_bss_signal
,
2413 { "Frequency", WPAS_DBUS_NEW_IFACE_BSS
, "q",
2414 wpas_dbus_getter_bss_frequency
,
2417 { "Rates", WPAS_DBUS_NEW_IFACE_BSS
, "au",
2418 wpas_dbus_getter_bss_rates
,
2421 { "WPA", WPAS_DBUS_NEW_IFACE_BSS
, "a{sv}",
2422 wpas_dbus_getter_bss_wpa
,
2425 { "RSN", WPAS_DBUS_NEW_IFACE_BSS
, "a{sv}",
2426 wpas_dbus_getter_bss_rsn
,
2429 { "WPS", WPAS_DBUS_NEW_IFACE_BSS
, "a{sv}",
2430 wpas_dbus_getter_bss_wps
,
2433 { "IEs", WPAS_DBUS_NEW_IFACE_BSS
, "ay",
2434 wpas_dbus_getter_bss_ies
,
2437 { "Age", WPAS_DBUS_NEW_IFACE_BSS
, "u",
2438 wpas_dbus_getter_bss_age
,
2441 { NULL
, NULL
, NULL
, NULL
, NULL
}
2445 static const struct wpa_dbus_signal_desc wpas_dbus_bss_signals
[] = {
2446 /* Deprecated: use org.freedesktop.DBus.Properties.PropertiesChanged */
2447 { "PropertiesChanged", WPAS_DBUS_NEW_IFACE_BSS
,
2449 { "properties", "a{sv}", ARG_OUT
},
2453 { NULL
, NULL
, { END_ARGS
} }
2458 * wpas_dbus_unregister_bss - Unregister a scanned BSS from dbus
2459 * @wpa_s: wpa_supplicant interface structure
2460 * @bssid: scanned network bssid
2461 * @id: unique BSS identifier
2462 * Returns: 0 on success, -1 on failure
2464 * Unregisters BSS representing object from dbus
2466 int wpas_dbus_unregister_bss(struct wpa_supplicant
*wpa_s
,
2467 u8 bssid
[ETH_ALEN
], unsigned int id
)
2469 struct wpas_dbus_priv
*ctrl_iface
;
2470 char bss_obj_path
[WPAS_DBUS_OBJECT_PATH_MAX
];
2472 /* Do nothing if the control interface is not turned on */
2473 if (wpa_s
== NULL
|| wpa_s
->global
== NULL
)
2475 ctrl_iface
= wpa_s
->global
->dbus
;
2476 if (ctrl_iface
== NULL
)
2479 os_snprintf(bss_obj_path
, WPAS_DBUS_OBJECT_PATH_MAX
,
2480 "%s/" WPAS_DBUS_NEW_BSSIDS_PART
"/%u",
2481 wpa_s
->dbus_new_path
, id
);
2483 wpa_printf(MSG_DEBUG
, "dbus: Unregister BSS object '%s'",
2485 if (wpa_dbus_unregister_object_per_iface(ctrl_iface
, bss_obj_path
)) {
2486 wpa_printf(MSG_ERROR
, "dbus: Cannot unregister BSS object %s",
2491 wpas_dbus_signal_bss_removed(wpa_s
, bss_obj_path
);
2492 wpas_dbus_signal_prop_changed(wpa_s
, WPAS_DBUS_PROP_BSSS
);
2499 * wpas_dbus_register_bss - Register a scanned BSS with dbus
2500 * @wpa_s: wpa_supplicant interface structure
2501 * @bssid: scanned network bssid
2502 * @id: unique BSS identifier
2503 * Returns: 0 on success, -1 on failure
2505 * Registers BSS representing object with dbus
2507 int wpas_dbus_register_bss(struct wpa_supplicant
*wpa_s
,
2508 u8 bssid
[ETH_ALEN
], unsigned int id
)
2510 struct wpas_dbus_priv
*ctrl_iface
;
2511 struct wpa_dbus_object_desc
*obj_desc
;
2512 char bss_obj_path
[WPAS_DBUS_OBJECT_PATH_MAX
];
2513 struct bss_handler_args
*arg
;
2515 /* Do nothing if the control interface is not turned on */
2516 if (wpa_s
== NULL
|| wpa_s
->global
== NULL
)
2518 ctrl_iface
= wpa_s
->global
->dbus
;
2519 if (ctrl_iface
== NULL
)
2522 os_snprintf(bss_obj_path
, WPAS_DBUS_OBJECT_PATH_MAX
,
2523 "%s/" WPAS_DBUS_NEW_BSSIDS_PART
"/%u",
2524 wpa_s
->dbus_new_path
, id
);
2526 obj_desc
= os_zalloc(sizeof(struct wpa_dbus_object_desc
));
2528 wpa_printf(MSG_ERROR
, "Not enough memory "
2529 "to create object description");
2533 arg
= os_zalloc(sizeof(struct bss_handler_args
));
2535 wpa_printf(MSG_ERROR
, "Not enough memory "
2536 "to create arguments for handler");
2542 wpas_dbus_register(obj_desc
, arg
, wpa_dbus_free
, NULL
,
2543 wpas_dbus_bss_properties
,
2544 wpas_dbus_bss_signals
);
2546 wpa_printf(MSG_DEBUG
, "dbus: Register BSS object '%s'",
2548 if (wpa_dbus_register_object_per_iface(ctrl_iface
, bss_obj_path
,
2549 wpa_s
->ifname
, obj_desc
)) {
2550 wpa_printf(MSG_ERROR
,
2551 "Cannot register BSSID dbus object %s.",
2556 wpas_dbus_signal_bss_added(wpa_s
, bss_obj_path
);
2557 wpas_dbus_signal_prop_changed(wpa_s
, WPAS_DBUS_PROP_BSSS
);
2562 free_dbus_object_desc(obj_desc
);
2567 static const struct wpa_dbus_method_desc wpas_dbus_interface_methods
[] = {
2568 { "Scan", WPAS_DBUS_NEW_IFACE_INTERFACE
,
2569 (WPADBusMethodHandler
) &wpas_dbus_handler_scan
,
2571 { "args", "a{sv}", ARG_IN
},
2575 { "SignalPoll", WPAS_DBUS_NEW_IFACE_INTERFACE
,
2576 (WPADBusMethodHandler
) &wpas_dbus_handler_signal_poll
,
2578 { "args", "a{sv}", ARG_OUT
},
2582 { "Disconnect", WPAS_DBUS_NEW_IFACE_INTERFACE
,
2583 (WPADBusMethodHandler
) &wpas_dbus_handler_disconnect
,
2588 { "AddNetwork", WPAS_DBUS_NEW_IFACE_INTERFACE
,
2589 (WPADBusMethodHandler
) &wpas_dbus_handler_add_network
,
2591 { "args", "a{sv}", ARG_IN
},
2592 { "path", "o", ARG_OUT
},
2596 { "Reassociate", WPAS_DBUS_NEW_IFACE_INTERFACE
,
2597 (WPADBusMethodHandler
) &wpas_dbus_handler_reassociate
,
2602 { "Reattach", WPAS_DBUS_NEW_IFACE_INTERFACE
,
2603 (WPADBusMethodHandler
) &wpas_dbus_handler_reattach
,
2608 { "RemoveNetwork", WPAS_DBUS_NEW_IFACE_INTERFACE
,
2609 (WPADBusMethodHandler
) &wpas_dbus_handler_remove_network
,
2611 { "path", "o", ARG_IN
},
2615 { "RemoveAllNetworks", WPAS_DBUS_NEW_IFACE_INTERFACE
,
2616 (WPADBusMethodHandler
) &wpas_dbus_handler_remove_all_networks
,
2621 { "SelectNetwork", WPAS_DBUS_NEW_IFACE_INTERFACE
,
2622 (WPADBusMethodHandler
) &wpas_dbus_handler_select_network
,
2624 { "path", "o", ARG_IN
},
2628 { "NetworkReply", WPAS_DBUS_NEW_IFACE_INTERFACE
,
2629 (WPADBusMethodHandler
) &wpas_dbus_handler_network_reply
,
2631 { "path", "o", ARG_IN
},
2632 { "field", "s", ARG_IN
},
2633 { "value", "s", ARG_IN
},
2637 #ifndef CONFIG_NO_CONFIG_BLOBS
2638 { "AddBlob", WPAS_DBUS_NEW_IFACE_INTERFACE
,
2639 (WPADBusMethodHandler
) &wpas_dbus_handler_add_blob
,
2641 { "name", "s", ARG_IN
},
2642 { "data", "ay", ARG_IN
},
2646 { "GetBlob", WPAS_DBUS_NEW_IFACE_INTERFACE
,
2647 (WPADBusMethodHandler
) &wpas_dbus_handler_get_blob
,
2649 { "name", "s", ARG_IN
},
2650 { "data", "ay", ARG_OUT
},
2654 { "RemoveBlob", WPAS_DBUS_NEW_IFACE_INTERFACE
,
2655 (WPADBusMethodHandler
) &wpas_dbus_handler_remove_blob
,
2657 { "name", "s", ARG_IN
},
2661 #endif /* CONFIG_NO_CONFIG_BLOBS */
2662 { "SetPKCS11EngineAndModulePath", WPAS_DBUS_NEW_IFACE_INTERFACE
,
2663 (WPADBusMethodHandler
)
2664 &wpas_dbus_handler_set_pkcs11_engine_and_module_path
,
2666 { "pkcs11_engine_path", "s", ARG_IN
},
2667 { "pkcs11_module_path", "s", ARG_IN
},
2672 { "Start", WPAS_DBUS_NEW_IFACE_WPS
,
2673 (WPADBusMethodHandler
) &wpas_dbus_handler_wps_start
,
2675 { "args", "a{sv}", ARG_IN
},
2676 { "output", "a{sv}", ARG_OUT
},
2680 #endif /* CONFIG_WPS */
2682 { "Find", WPAS_DBUS_NEW_IFACE_P2PDEVICE
,
2683 (WPADBusMethodHandler
)wpas_dbus_handler_p2p_find
,
2685 { "args", "a{sv}", ARG_IN
},
2689 { "StopFind", WPAS_DBUS_NEW_IFACE_P2PDEVICE
,
2690 (WPADBusMethodHandler
)wpas_dbus_handler_p2p_stop_find
,
2695 { "Listen", WPAS_DBUS_NEW_IFACE_P2PDEVICE
,
2696 (WPADBusMethodHandler
)wpas_dbus_handler_p2p_listen
,
2698 { "timeout", "i", ARG_IN
},
2702 { "ExtendedListen", WPAS_DBUS_NEW_IFACE_P2PDEVICE
,
2703 (WPADBusMethodHandler
)wpas_dbus_handler_p2p_extendedlisten
,
2705 { "args", "a{sv}", ARG_IN
},
2709 { "PresenceRequest", WPAS_DBUS_NEW_IFACE_P2PDEVICE
,
2710 (WPADBusMethodHandler
)wpas_dbus_handler_p2p_presence_request
,
2712 { "args", "a{sv}", ARG_IN
},
2716 { "ProvisionDiscoveryRequest", WPAS_DBUS_NEW_IFACE_P2PDEVICE
,
2717 (WPADBusMethodHandler
)wpas_dbus_handler_p2p_prov_disc_req
,
2719 { "peer", "o", ARG_IN
},
2720 { "config_method", "s", ARG_IN
},
2724 { "Connect", WPAS_DBUS_NEW_IFACE_P2PDEVICE
,
2725 (WPADBusMethodHandler
)wpas_dbus_handler_p2p_connect
,
2727 { "args", "a{sv}", ARG_IN
},
2728 { "generated_pin", "s", ARG_OUT
},
2732 { "GroupAdd", WPAS_DBUS_NEW_IFACE_P2PDEVICE
,
2733 (WPADBusMethodHandler
)wpas_dbus_handler_p2p_group_add
,
2735 { "args", "a{sv}", ARG_IN
},
2739 { "Invite", WPAS_DBUS_NEW_IFACE_P2PDEVICE
,
2740 (WPADBusMethodHandler
)wpas_dbus_handler_p2p_invite
,
2742 { "args", "a{sv}", ARG_IN
},
2746 { "Disconnect", WPAS_DBUS_NEW_IFACE_P2PDEVICE
,
2747 (WPADBusMethodHandler
)wpas_dbus_handler_p2p_disconnect
,
2752 { "RejectPeer", WPAS_DBUS_NEW_IFACE_P2PDEVICE
,
2753 (WPADBusMethodHandler
)wpas_dbus_handler_p2p_rejectpeer
,
2755 { "peer", "o", ARG_IN
},
2759 { "Flush", WPAS_DBUS_NEW_IFACE_P2PDEVICE
,
2760 (WPADBusMethodHandler
)wpas_dbus_handler_p2p_flush
,
2765 { "AddService", WPAS_DBUS_NEW_IFACE_P2PDEVICE
,
2766 (WPADBusMethodHandler
)wpas_dbus_handler_p2p_add_service
,
2768 { "args", "a{sv}", ARG_IN
},
2772 { "DeleteService", WPAS_DBUS_NEW_IFACE_P2PDEVICE
,
2773 (WPADBusMethodHandler
)wpas_dbus_handler_p2p_delete_service
,
2775 { "args", "a{sv}", ARG_IN
},
2779 { "FlushService", WPAS_DBUS_NEW_IFACE_P2PDEVICE
,
2780 (WPADBusMethodHandler
)wpas_dbus_handler_p2p_flush_service
,
2785 { "ServiceDiscoveryRequest", WPAS_DBUS_NEW_IFACE_P2PDEVICE
,
2786 (WPADBusMethodHandler
)wpas_dbus_handler_p2p_service_sd_req
,
2788 { "args", "a{sv}", ARG_IN
},
2789 { "ref", "t", ARG_OUT
},
2793 { "ServiceDiscoveryResponse", WPAS_DBUS_NEW_IFACE_P2PDEVICE
,
2794 (WPADBusMethodHandler
)wpas_dbus_handler_p2p_service_sd_res
,
2796 { "args", "a{sv}", ARG_IN
},
2800 { "ServiceDiscoveryCancelRequest", WPAS_DBUS_NEW_IFACE_P2PDEVICE
,
2801 (WPADBusMethodHandler
)wpas_dbus_handler_p2p_service_sd_cancel_req
,
2803 { "args", "t", ARG_IN
},
2807 { "ServiceUpdate", WPAS_DBUS_NEW_IFACE_P2PDEVICE
,
2808 (WPADBusMethodHandler
)wpas_dbus_handler_p2p_service_update
,
2813 { "ServiceDiscoveryExternal", WPAS_DBUS_NEW_IFACE_P2PDEVICE
,
2814 (WPADBusMethodHandler
)wpas_dbus_handler_p2p_serv_disc_external
,
2816 { "arg", "i", ARG_IN
},
2820 { "AddPersistentGroup", WPAS_DBUS_NEW_IFACE_P2PDEVICE
,
2821 (WPADBusMethodHandler
) wpas_dbus_handler_add_persistent_group
,
2823 { "args", "a{sv}", ARG_IN
},
2824 { "path", "o", ARG_OUT
},
2828 { "RemovePersistentGroup", WPAS_DBUS_NEW_IFACE_P2PDEVICE
,
2829 (WPADBusMethodHandler
) wpas_dbus_handler_remove_persistent_group
,
2831 { "path", "o", ARG_IN
},
2835 { "RemoveAllPersistentGroups", WPAS_DBUS_NEW_IFACE_P2PDEVICE
,
2836 (WPADBusMethodHandler
)
2837 wpas_dbus_handler_remove_all_persistent_groups
,
2842 #endif /* CONFIG_P2P */
2843 { "FlushBSS", WPAS_DBUS_NEW_IFACE_INTERFACE
,
2844 (WPADBusMethodHandler
) &wpas_dbus_handler_flush_bss
,
2846 { "age", "u", ARG_IN
},
2851 { "SubscribeProbeReq", WPAS_DBUS_NEW_IFACE_INTERFACE
,
2852 (WPADBusMethodHandler
) wpas_dbus_handler_subscribe_preq
,
2857 { "UnsubscribeProbeReq", WPAS_DBUS_NEW_IFACE_INTERFACE
,
2858 (WPADBusMethodHandler
) wpas_dbus_handler_unsubscribe_preq
,
2863 #endif /* CONFIG_AP */
2864 { "EAPLogoff", WPAS_DBUS_NEW_IFACE_INTERFACE
,
2865 (WPADBusMethodHandler
) &wpas_dbus_handler_eap_logoff
,
2870 { "EAPLogon", WPAS_DBUS_NEW_IFACE_INTERFACE
,
2871 (WPADBusMethodHandler
) &wpas_dbus_handler_eap_logon
,
2876 #ifdef CONFIG_AUTOSCAN
2877 { "AutoScan", WPAS_DBUS_NEW_IFACE_INTERFACE
,
2878 (WPADBusMethodHandler
) &wpas_dbus_handler_autoscan
,
2880 { "arg", "s", ARG_IN
},
2884 #endif /* CONFIG_AUTOSCAN */
2886 { "TDLSDiscover", WPAS_DBUS_NEW_IFACE_INTERFACE
,
2887 (WPADBusMethodHandler
) wpas_dbus_handler_tdls_discover
,
2889 { "peer_address", "s", ARG_IN
},
2893 { "TDLSSetup", WPAS_DBUS_NEW_IFACE_INTERFACE
,
2894 (WPADBusMethodHandler
) wpas_dbus_handler_tdls_setup
,
2896 { "peer_address", "s", ARG_IN
},
2900 { "TDLSStatus", WPAS_DBUS_NEW_IFACE_INTERFACE
,
2901 (WPADBusMethodHandler
) wpas_dbus_handler_tdls_status
,
2903 { "peer_address", "s", ARG_IN
},
2904 { "status", "s", ARG_OUT
},
2908 { "TDLSTeardown", WPAS_DBUS_NEW_IFACE_INTERFACE
,
2909 (WPADBusMethodHandler
) wpas_dbus_handler_tdls_teardown
,
2911 { "peer_address", "s", ARG_IN
},
2915 #endif /* CONFIG_TDLS */
2916 { NULL
, NULL
, NULL
, { END_ARGS
} }
2919 static const struct wpa_dbus_property_desc wpas_dbus_interface_properties
[] = {
2920 { "Capabilities", WPAS_DBUS_NEW_IFACE_INTERFACE
, "a{sv}",
2921 wpas_dbus_getter_capabilities
,
2924 { "State", WPAS_DBUS_NEW_IFACE_INTERFACE
, "s",
2925 wpas_dbus_getter_state
,
2928 { "Scanning", WPAS_DBUS_NEW_IFACE_INTERFACE
, "b",
2929 wpas_dbus_getter_scanning
,
2932 { "ApScan", WPAS_DBUS_NEW_IFACE_INTERFACE
, "u",
2933 wpas_dbus_getter_ap_scan
,
2934 wpas_dbus_setter_ap_scan
2936 { "BSSExpireAge", WPAS_DBUS_NEW_IFACE_INTERFACE
, "u",
2937 wpas_dbus_getter_bss_expire_age
,
2938 wpas_dbus_setter_bss_expire_age
2940 { "BSSExpireCount", WPAS_DBUS_NEW_IFACE_INTERFACE
, "u",
2941 wpas_dbus_getter_bss_expire_count
,
2942 wpas_dbus_setter_bss_expire_count
2944 { "Country", WPAS_DBUS_NEW_IFACE_INTERFACE
, "s",
2945 wpas_dbus_getter_country
,
2946 wpas_dbus_setter_country
2948 { "Ifname", WPAS_DBUS_NEW_IFACE_INTERFACE
, "s",
2949 wpas_dbus_getter_ifname
,
2952 { "Driver", WPAS_DBUS_NEW_IFACE_INTERFACE
, "s",
2953 wpas_dbus_getter_driver
,
2956 { "BridgeIfname", WPAS_DBUS_NEW_IFACE_INTERFACE
, "s",
2957 wpas_dbus_getter_bridge_ifname
,
2960 { "CurrentBSS", WPAS_DBUS_NEW_IFACE_INTERFACE
, "o",
2961 wpas_dbus_getter_current_bss
,
2964 { "CurrentNetwork", WPAS_DBUS_NEW_IFACE_INTERFACE
, "o",
2965 wpas_dbus_getter_current_network
,
2968 { "CurrentAuthMode", WPAS_DBUS_NEW_IFACE_INTERFACE
, "s",
2969 wpas_dbus_getter_current_auth_mode
,
2972 { "Blobs", WPAS_DBUS_NEW_IFACE_INTERFACE
, "a{say}",
2973 wpas_dbus_getter_blobs
,
2976 { "BSSs", WPAS_DBUS_NEW_IFACE_INTERFACE
, "ao",
2977 wpas_dbus_getter_bsss
,
2980 { "Networks", WPAS_DBUS_NEW_IFACE_INTERFACE
, "ao",
2981 wpas_dbus_getter_networks
,
2984 { "FastReauth", WPAS_DBUS_NEW_IFACE_INTERFACE
, "b",
2985 wpas_dbus_getter_fast_reauth
,
2986 wpas_dbus_setter_fast_reauth
2988 { "ScanInterval", WPAS_DBUS_NEW_IFACE_INTERFACE
, "i",
2989 wpas_dbus_getter_scan_interval
,
2990 wpas_dbus_setter_scan_interval
2992 { "PKCS11EnginePath", WPAS_DBUS_NEW_IFACE_INTERFACE
, "s",
2993 wpas_dbus_getter_pkcs11_engine_path
,
2996 { "PKCS11ModulePath", WPAS_DBUS_NEW_IFACE_INTERFACE
, "s",
2997 wpas_dbus_getter_pkcs11_module_path
,
3001 { "ProcessCredentials", WPAS_DBUS_NEW_IFACE_WPS
, "b",
3002 wpas_dbus_getter_process_credentials
,
3003 wpas_dbus_setter_process_credentials
3005 { "ConfigMethods", WPAS_DBUS_NEW_IFACE_WPS
, "s",
3006 wpas_dbus_getter_config_methods
,
3007 wpas_dbus_setter_config_methods
3009 #endif /* CONFIG_WPS */
3011 { "P2PDeviceConfig", WPAS_DBUS_NEW_IFACE_P2PDEVICE
, "a{sv}",
3012 wpas_dbus_getter_p2p_device_config
,
3013 wpas_dbus_setter_p2p_device_config
3015 { "Peers", WPAS_DBUS_NEW_IFACE_P2PDEVICE
, "ao",
3016 wpas_dbus_getter_p2p_peers
,
3019 { "Role", WPAS_DBUS_NEW_IFACE_P2PDEVICE
, "s",
3020 wpas_dbus_getter_p2p_role
,
3023 { "Group", WPAS_DBUS_NEW_IFACE_P2PDEVICE
, "o",
3024 wpas_dbus_getter_p2p_group
,
3027 { "PeerGO", WPAS_DBUS_NEW_IFACE_P2PDEVICE
, "o",
3028 wpas_dbus_getter_p2p_peergo
,
3031 { "PersistentGroups", WPAS_DBUS_NEW_IFACE_P2PDEVICE
, "ao",
3032 wpas_dbus_getter_persistent_groups
,
3035 #endif /* CONFIG_P2P */
3036 { "DisconnectReason", WPAS_DBUS_NEW_IFACE_INTERFACE
, "i",
3037 wpas_dbus_getter_disconnect_reason
,
3040 { NULL
, NULL
, NULL
, NULL
, NULL
}
3043 static const struct wpa_dbus_signal_desc wpas_dbus_interface_signals
[] = {
3044 { "ScanDone", WPAS_DBUS_NEW_IFACE_INTERFACE
,
3046 { "success", "b", ARG_OUT
},
3050 { "BSSAdded", WPAS_DBUS_NEW_IFACE_INTERFACE
,
3052 { "path", "o", ARG_OUT
},
3053 { "properties", "a{sv}", ARG_OUT
},
3057 { "BSSRemoved", WPAS_DBUS_NEW_IFACE_INTERFACE
,
3059 { "path", "o", ARG_OUT
},
3063 { "BlobAdded", WPAS_DBUS_NEW_IFACE_INTERFACE
,
3065 { "name", "s", ARG_OUT
},
3069 { "BlobRemoved", WPAS_DBUS_NEW_IFACE_INTERFACE
,
3071 { "name", "s", ARG_OUT
},
3075 { "NetworkAdded", WPAS_DBUS_NEW_IFACE_INTERFACE
,
3077 { "path", "o", ARG_OUT
},
3078 { "properties", "a{sv}", ARG_OUT
},
3082 { "NetworkRemoved", WPAS_DBUS_NEW_IFACE_INTERFACE
,
3084 { "path", "o", ARG_OUT
},
3088 { "NetworkSelected", WPAS_DBUS_NEW_IFACE_INTERFACE
,
3090 { "path", "o", ARG_OUT
},
3094 /* Deprecated: use org.freedesktop.DBus.Properties.PropertiesChanged */
3095 { "PropertiesChanged", WPAS_DBUS_NEW_IFACE_INTERFACE
,
3097 { "properties", "a{sv}", ARG_OUT
},
3102 { "Event", WPAS_DBUS_NEW_IFACE_WPS
,
3104 { "name", "s", ARG_OUT
},
3105 { "args", "a{sv}", ARG_OUT
},
3109 { "Credentials", WPAS_DBUS_NEW_IFACE_WPS
,
3111 { "credentials", "a{sv}", ARG_OUT
},
3115 /* Deprecated: use org.freedesktop.DBus.Properties.PropertiesChanged */
3116 { "PropertiesChanged", WPAS_DBUS_NEW_IFACE_WPS
,
3118 { "properties", "a{sv}", ARG_OUT
},
3122 #endif /* CONFIG_WPS */
3124 { "P2PStateChanged", WPAS_DBUS_NEW_IFACE_P2PDEVICE
,
3126 { "states", "a{ss}", ARG_OUT
},
3130 { "DeviceFound", WPAS_DBUS_NEW_IFACE_P2PDEVICE
,
3132 { "path", "o", ARG_OUT
},
3136 { "DeviceLost", WPAS_DBUS_NEW_IFACE_P2PDEVICE
,
3138 { "path", "o", ARG_OUT
},
3142 { "ProvisionDiscoveryRequestDisplayPin", WPAS_DBUS_NEW_IFACE_P2PDEVICE
,
3144 { "peer_object", "o", ARG_OUT
},
3145 { "pin", "s", ARG_OUT
},
3149 { "ProvisionDiscoveryResponseDisplayPin", WPAS_DBUS_NEW_IFACE_P2PDEVICE
,
3151 { "peer_object", "o", ARG_OUT
},
3152 { "pin", "s", ARG_OUT
},
3156 { "ProvisionDiscoveryRequestEnterPin", WPAS_DBUS_NEW_IFACE_P2PDEVICE
,
3158 { "peer_object", "o", ARG_OUT
},
3162 { "ProvisionDiscoveryResponseEnterPin", WPAS_DBUS_NEW_IFACE_P2PDEVICE
,
3164 { "peer_object", "o", ARG_OUT
},
3168 { "ProvisionDiscoveryPBCRequest", WPAS_DBUS_NEW_IFACE_P2PDEVICE
,
3170 { "peer_object", "o", ARG_OUT
},
3174 { "ProvisionDiscoveryPBCResponse", WPAS_DBUS_NEW_IFACE_P2PDEVICE
,
3176 { "peer_object", "o", ARG_OUT
},
3180 { "ProvisionDiscoveryFailure", WPAS_DBUS_NEW_IFACE_P2PDEVICE
,
3182 { "peer_object", "o", ARG_OUT
},
3183 { "status", "i", ARG_OUT
},
3187 { "GroupStarted", WPAS_DBUS_NEW_IFACE_P2PDEVICE
,
3189 { "properties", "a{sv}", ARG_OUT
},
3193 { "GONegotiationSuccess", WPAS_DBUS_NEW_IFACE_P2PDEVICE
,
3195 { "properties", "a{sv}", ARG_OUT
},
3199 { "GONegotiationFailure", WPAS_DBUS_NEW_IFACE_P2PDEVICE
,
3201 { "properties", "a{sv}", ARG_OUT
},
3205 { "GONegotiationRequest", WPAS_DBUS_NEW_IFACE_P2PDEVICE
,
3207 { "path", "o", ARG_OUT
},
3208 { "dev_passwd_id", "i", ARG_OUT
},
3212 { "InvitationResult", WPAS_DBUS_NEW_IFACE_P2PDEVICE
,
3214 { "invite_result", "a{sv}", ARG_OUT
},
3218 { "GroupFinished", WPAS_DBUS_NEW_IFACE_P2PDEVICE
,
3220 { "properties", "a{sv}", ARG_OUT
},
3224 { "ServiceDiscoveryRequest", WPAS_DBUS_NEW_IFACE_P2PDEVICE
,
3226 { "sd_request", "a{sv}", ARG_OUT
},
3230 { "ServiceDiscoveryResponse", WPAS_DBUS_NEW_IFACE_P2PDEVICE
,
3232 { "sd_response", "a{sv}", ARG_OUT
},
3236 { "PersistentGroupAdded", WPAS_DBUS_NEW_IFACE_P2PDEVICE
,
3238 { "path", "o", ARG_OUT
},
3239 { "properties", "a{sv}", ARG_OUT
},
3243 { "PersistentGroupRemoved", WPAS_DBUS_NEW_IFACE_P2PDEVICE
,
3245 { "path", "o", ARG_OUT
},
3249 { "WpsFailed", WPAS_DBUS_NEW_IFACE_P2PDEVICE
,
3251 { "name", "s", ARG_OUT
},
3252 { "args", "a{sv}", ARG_OUT
},
3256 #endif /* CONFIG_P2P */
3258 { "ProbeRequest", WPAS_DBUS_NEW_IFACE_INTERFACE
,
3260 { "args", "a{sv}", ARG_OUT
},
3264 #endif /* CONFIG_AP */
3265 { "Certification", WPAS_DBUS_NEW_IFACE_INTERFACE
,
3267 { "certification", "a{sv}", ARG_OUT
},
3271 { "EAP", WPAS_DBUS_NEW_IFACE_INTERFACE
,
3273 { "status", "s", ARG_OUT
},
3274 { "parameter", "s", ARG_OUT
},
3278 { "StaAuthorized", WPAS_DBUS_NEW_IFACE_INTERFACE
,
3280 { "name", "s", ARG_OUT
},
3284 { "StaDeauthorized", WPAS_DBUS_NEW_IFACE_INTERFACE
,
3286 { "name", "s", ARG_OUT
},
3290 { NULL
, NULL
, { END_ARGS
} }
3294 int wpas_dbus_register_interface(struct wpa_supplicant
*wpa_s
)
3297 struct wpa_dbus_object_desc
*obj_desc
= NULL
;
3298 struct wpas_dbus_priv
*ctrl_iface
= wpa_s
->global
->dbus
;
3301 /* Do nothing if the control interface is not turned on */
3302 if (ctrl_iface
== NULL
)
3305 /* Create and set the interface's object path */
3306 wpa_s
->dbus_new_path
= os_zalloc(WPAS_DBUS_OBJECT_PATH_MAX
);
3307 if (wpa_s
->dbus_new_path
== NULL
)
3309 next
= ctrl_iface
->next_objid
++;
3310 os_snprintf(wpa_s
->dbus_new_path
, WPAS_DBUS_OBJECT_PATH_MAX
,
3311 WPAS_DBUS_NEW_PATH_INTERFACES
"/%u",
3314 obj_desc
= os_zalloc(sizeof(struct wpa_dbus_object_desc
));
3316 wpa_printf(MSG_ERROR
, "Not enough memory "
3317 "to create object description");
3321 wpas_dbus_register(obj_desc
, wpa_s
, NULL
, wpas_dbus_interface_methods
,
3322 wpas_dbus_interface_properties
,
3323 wpas_dbus_interface_signals
);
3325 wpa_printf(MSG_DEBUG
, "dbus: Register interface object '%s'",
3326 wpa_s
->dbus_new_path
);
3327 if (wpa_dbus_register_object_per_iface(ctrl_iface
,
3328 wpa_s
->dbus_new_path
,
3329 wpa_s
->ifname
, obj_desc
))
3332 wpas_dbus_signal_interface_added(wpa_s
);
3337 os_free(wpa_s
->dbus_new_path
);
3338 wpa_s
->dbus_new_path
= NULL
;
3339 free_dbus_object_desc(obj_desc
);
3344 int wpas_dbus_unregister_interface(struct wpa_supplicant
*wpa_s
)
3346 struct wpas_dbus_priv
*ctrl_iface
;
3348 /* Do nothing if the control interface is not turned on */
3349 if (wpa_s
== NULL
|| wpa_s
->global
== NULL
)
3351 ctrl_iface
= wpa_s
->global
->dbus
;
3352 if (ctrl_iface
== NULL
)
3355 wpa_printf(MSG_DEBUG
, "dbus: Unregister interface object '%s'",
3356 wpa_s
->dbus_new_path
);
3359 if (wpa_s
->preq_notify_peer
) {
3360 wpas_dbus_unsubscribe_noc(ctrl_iface
);
3361 os_free(wpa_s
->preq_notify_peer
);
3362 wpa_s
->preq_notify_peer
= NULL
;
3364 #endif /* CONFIG_AP */
3366 if (wpa_dbus_unregister_object_per_iface(ctrl_iface
,
3367 wpa_s
->dbus_new_path
))
3370 wpas_dbus_signal_interface_removed(wpa_s
);
3372 os_free(wpa_s
->dbus_new_path
);
3373 wpa_s
->dbus_new_path
= NULL
;
3380 static const struct wpa_dbus_property_desc wpas_dbus_p2p_peer_properties
[] = {
3381 { "DeviceName", WPAS_DBUS_NEW_IFACE_P2P_PEER
, "s",
3382 wpas_dbus_getter_p2p_peer_device_name
,
3385 { "PrimaryDeviceType", WPAS_DBUS_NEW_IFACE_P2P_PEER
, "ay",
3386 wpas_dbus_getter_p2p_peer_primary_device_type
,
3389 { "config_method", WPAS_DBUS_NEW_IFACE_P2P_PEER
, "q",
3390 wpas_dbus_getter_p2p_peer_config_method
,
3393 { "level", WPAS_DBUS_NEW_IFACE_P2P_PEER
, "i",
3394 wpas_dbus_getter_p2p_peer_level
,
3397 { "devicecapability", WPAS_DBUS_NEW_IFACE_P2P_PEER
, "y",
3398 wpas_dbus_getter_p2p_peer_device_capability
,
3401 { "groupcapability", WPAS_DBUS_NEW_IFACE_P2P_PEER
, "y",
3402 wpas_dbus_getter_p2p_peer_group_capability
,
3405 { "SecondaryDeviceTypes", WPAS_DBUS_NEW_IFACE_P2P_PEER
, "aay",
3406 wpas_dbus_getter_p2p_peer_secondary_device_types
,
3409 { "VendorExtension", WPAS_DBUS_NEW_IFACE_P2P_PEER
, "aay",
3410 wpas_dbus_getter_p2p_peer_vendor_extension
,
3413 { "IEs", WPAS_DBUS_NEW_IFACE_P2P_PEER
, "ay",
3414 wpas_dbus_getter_p2p_peer_ies
,
3417 { "DeviceAddress", WPAS_DBUS_NEW_IFACE_P2P_PEER
, "ay",
3418 wpas_dbus_getter_p2p_peer_device_address
,
3421 { "Groups", WPAS_DBUS_NEW_IFACE_P2P_PEER
, "ao",
3422 wpas_dbus_getter_p2p_peer_groups
,
3425 { NULL
, NULL
, NULL
, NULL
, NULL
}
3428 static const struct wpa_dbus_signal_desc wpas_dbus_p2p_peer_signals
[] = {
3429 /* Deprecated: use org.freedesktop.DBus.Properties.PropertiesChanged */
3430 { "PropertiesChanged", WPAS_DBUS_NEW_IFACE_P2P_PEER
,
3432 { "properties", "a{sv}", ARG_OUT
},
3436 { NULL
, NULL
, { END_ARGS
} }
3440 * wpas_dbus_signal_peer - Send a peer related event signal
3441 * @wpa_s: %wpa_supplicant network interface data
3442 * @dev: peer device object
3443 * @interface: name of the interface emitting this signal.
3444 * In case of peer objects, it would be emitted by either
3445 * the "interface object" or by "peer objects"
3446 * @sig_name: signal name - DeviceFound
3448 * Notify listeners about event related with newly found p2p peer device
3450 static void wpas_dbus_signal_peer(struct wpa_supplicant
*wpa_s
,
3451 const u8
*dev_addr
, const char *interface
,
3452 const char *sig_name
)
3454 struct wpas_dbus_priv
*iface
;
3456 DBusMessageIter iter
;
3457 char peer_obj_path
[WPAS_DBUS_OBJECT_PATH_MAX
], *path
;
3459 if (wpa_s
->p2p_mgmt
)
3460 wpa_s
= wpa_s
->parent
;
3462 iface
= wpa_s
->global
->dbus
;
3464 /* Do nothing if the control interface is not turned on */
3468 os_snprintf(peer_obj_path
, WPAS_DBUS_OBJECT_PATH_MAX
,
3469 "%s/" WPAS_DBUS_NEW_P2P_PEERS_PART
"/" COMPACT_MACSTR
,
3470 wpa_s
->dbus_new_path
, MAC2STR(dev_addr
));
3472 msg
= dbus_message_new_signal(wpa_s
->dbus_new_path
, interface
,
3477 dbus_message_iter_init_append(msg
, &iter
);
3478 path
= peer_obj_path
;
3479 if (!dbus_message_iter_append_basic(&iter
, DBUS_TYPE_OBJECT_PATH
,
3483 dbus_connection_send(iface
->con
, msg
, NULL
);
3485 dbus_message_unref(msg
);
3489 wpa_printf(MSG_ERROR
, "dbus: Failed to construct signal");
3490 dbus_message_unref(msg
);
3495 * wpas_dbus_signal_peer_found - Send a peer found signal
3496 * @wpa_s: %wpa_supplicant network interface data
3497 * @dev: peer device object
3499 * Notify listeners about find a p2p peer device found
3501 void wpas_dbus_signal_peer_device_found(struct wpa_supplicant
*wpa_s
,
3504 wpas_dbus_signal_peer(wpa_s
, dev_addr
,
3505 WPAS_DBUS_NEW_IFACE_P2PDEVICE
,
3510 * wpas_dbus_signal_peer_lost - Send a peer lost signal
3511 * @wpa_s: %wpa_supplicant network interface data
3512 * @dev: peer device object
3514 * Notify listeners about lost a p2p peer device
3516 void wpas_dbus_signal_peer_device_lost(struct wpa_supplicant
*wpa_s
,
3519 wpas_dbus_signal_peer(wpa_s
, dev_addr
,
3520 WPAS_DBUS_NEW_IFACE_P2PDEVICE
,
3525 * wpas_dbus_register_peer - Register a discovered peer object with dbus
3526 * @wpa_s: wpa_supplicant interface structure
3527 * @ssid: network configuration data
3528 * Returns: 0 on success, -1 on failure
3530 * Registers network representing object with dbus
3532 int wpas_dbus_register_peer(struct wpa_supplicant
*wpa_s
, const u8
*dev_addr
)
3534 struct wpas_dbus_priv
*ctrl_iface
;
3535 struct wpa_dbus_object_desc
*obj_desc
;
3536 struct peer_handler_args
*arg
;
3537 char peer_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 ctrl_iface
= wpa_s
->global
->dbus
;
3544 if (ctrl_iface
== NULL
)
3547 if (wpa_s
->p2p_mgmt
)
3548 wpa_s
= wpa_s
->parent
;
3550 os_snprintf(peer_obj_path
, WPAS_DBUS_OBJECT_PATH_MAX
,
3551 "%s/" WPAS_DBUS_NEW_P2P_PEERS_PART
"/" COMPACT_MACSTR
,
3552 wpa_s
->dbus_new_path
, MAC2STR(dev_addr
));
3554 wpa_printf(MSG_INFO
, "dbus: Register peer object '%s'",
3556 obj_desc
= os_zalloc(sizeof(struct wpa_dbus_object_desc
));
3558 wpa_printf(MSG_ERROR
, "Not enough memory "
3559 "to create object description");
3563 /* allocate memory for handlers arguments */
3564 arg
= os_zalloc(sizeof(struct peer_handler_args
));
3566 wpa_printf(MSG_ERROR
, "Not enough memory "
3567 "to create arguments for method");
3572 os_memcpy(arg
->p2p_device_addr
, dev_addr
, ETH_ALEN
);
3574 wpas_dbus_register(obj_desc
, arg
, wpa_dbus_free
,
3576 wpas_dbus_p2p_peer_properties
,
3577 wpas_dbus_p2p_peer_signals
);
3579 if (wpa_dbus_register_object_per_iface(ctrl_iface
, peer_obj_path
,
3580 wpa_s
->ifname
, obj_desc
))
3586 free_dbus_object_desc(obj_desc
);
3591 * wpas_dbus_unregister_peer - Unregister a peer object with dbus
3592 * @wpa_s: wpa_supplicant interface structure
3593 * @dev_addr: p2p device addr
3594 * Returns: 0 on success, -1 on failure
3596 * Registers network representing object with dbus
3598 int wpas_dbus_unregister_peer(struct wpa_supplicant
*wpa_s
,
3601 struct wpas_dbus_priv
*ctrl_iface
;
3602 char peer_obj_path
[WPAS_DBUS_OBJECT_PATH_MAX
];
3605 /* Do nothing if the control interface is not turned on */
3606 if (wpa_s
== NULL
|| wpa_s
->global
== NULL
||
3607 wpa_s
->dbus_new_path
== NULL
)
3610 if (wpa_s
->p2p_mgmt
)
3611 wpa_s
= wpa_s
->parent
;
3613 ctrl_iface
= wpa_s
->global
->dbus
;
3614 if (ctrl_iface
== NULL
)
3617 os_snprintf(peer_obj_path
, WPAS_DBUS_OBJECT_PATH_MAX
,
3618 "%s/" WPAS_DBUS_NEW_P2P_PEERS_PART
"/" COMPACT_MACSTR
,
3619 wpa_s
->dbus_new_path
, MAC2STR(dev_addr
));
3621 wpa_printf(MSG_INFO
, "dbus: Unregister peer object '%s'",
3623 ret
= wpa_dbus_unregister_object_per_iface(ctrl_iface
, peer_obj_path
);
3629 void wpas_dbus_signal_peer_groups_changed(struct wpa_supplicant
*wpa_s
,
3632 char peer_obj_path
[WPAS_DBUS_OBJECT_PATH_MAX
];
3634 if (wpa_s
->p2p_mgmt
)
3635 wpa_s
= wpa_s
->parent
;
3637 os_snprintf(peer_obj_path
, WPAS_DBUS_OBJECT_PATH_MAX
,
3638 "%s/" WPAS_DBUS_NEW_P2P_PEERS_PART
"/" COMPACT_MACSTR
,
3639 wpa_s
->dbus_new_path
, MAC2STR(dev_addr
));
3641 wpa_dbus_mark_property_changed(wpa_s
->global
->dbus
, peer_obj_path
,
3642 WPAS_DBUS_NEW_IFACE_P2P_PEER
, "Groups");
3646 static const struct wpa_dbus_property_desc wpas_dbus_p2p_group_properties
[] = {
3647 { "Members", WPAS_DBUS_NEW_IFACE_P2P_GROUP
, "ao",
3648 wpas_dbus_getter_p2p_group_members
,
3651 { "Group", WPAS_DBUS_NEW_IFACE_P2P_GROUP
, "o",
3652 wpas_dbus_getter_p2p_group
,
3655 { "Role", WPAS_DBUS_NEW_IFACE_P2P_GROUP
, "s",
3656 wpas_dbus_getter_p2p_role
,
3659 { "SSID", WPAS_DBUS_NEW_IFACE_P2P_GROUP
, "ay",
3660 wpas_dbus_getter_p2p_group_ssid
,
3663 { "BSSID", WPAS_DBUS_NEW_IFACE_P2P_GROUP
, "ay",
3664 wpas_dbus_getter_p2p_group_bssid
,
3667 { "Frequency", WPAS_DBUS_NEW_IFACE_P2P_GROUP
, "q",
3668 wpas_dbus_getter_p2p_group_frequency
,
3671 { "Passphrase", WPAS_DBUS_NEW_IFACE_P2P_GROUP
, "s",
3672 wpas_dbus_getter_p2p_group_passphrase
,
3675 { "PSK", WPAS_DBUS_NEW_IFACE_P2P_GROUP
, "ay",
3676 wpas_dbus_getter_p2p_group_psk
,
3679 { "WPSVendorExtensions", WPAS_DBUS_NEW_IFACE_P2P_GROUP
, "aay",
3680 wpas_dbus_getter_p2p_group_vendor_ext
,
3681 wpas_dbus_setter_p2p_group_vendor_ext
3683 { NULL
, NULL
, NULL
, NULL
, NULL
}
3686 static const struct wpa_dbus_signal_desc wpas_dbus_p2p_group_signals
[] = {
3687 { "PeerJoined", WPAS_DBUS_NEW_IFACE_P2P_GROUP
,
3689 { "peer", "o", ARG_OUT
},
3693 { "PeerDisconnected", WPAS_DBUS_NEW_IFACE_P2P_GROUP
,
3695 { "peer", "o", ARG_OUT
},
3699 { NULL
, NULL
, { END_ARGS
} }
3703 * wpas_dbus_register_p2p_group - Register a p2p group object with dbus
3704 * @wpa_s: wpa_supplicant interface structure
3705 * @ssid: SSID struct
3706 * Returns: 0 on success, -1 on failure
3708 * Registers p2p group representing object with dbus
3710 void wpas_dbus_register_p2p_group(struct wpa_supplicant
*wpa_s
,
3711 struct wpa_ssid
*ssid
)
3713 struct wpas_dbus_priv
*ctrl_iface
;
3714 struct wpa_dbus_object_desc
*obj_desc
;
3715 char group_obj_path
[WPAS_DBUS_OBJECT_PATH_MAX
];
3717 /* Do nothing if the control interface is not turned on */
3718 if (wpa_s
== NULL
|| wpa_s
->global
== NULL
)
3721 ctrl_iface
= wpa_s
->global
->dbus
;
3722 if (ctrl_iface
== NULL
)
3725 if (wpa_s
->dbus_groupobj_path
) {
3726 wpa_printf(MSG_INFO
, "%s: Group object '%s' already exists",
3727 __func__
, wpa_s
->dbus_groupobj_path
);
3731 if (wpas_dbus_get_group_obj_path(wpa_s
, ssid
, group_obj_path
) < 0)
3734 wpa_s
->dbus_groupobj_path
= os_strdup(group_obj_path
);
3735 if (wpa_s
->dbus_groupobj_path
== NULL
)
3738 wpa_printf(MSG_INFO
, "dbus: Register group object '%s'",
3740 obj_desc
= os_zalloc(sizeof(struct wpa_dbus_object_desc
));
3742 wpa_printf(MSG_ERROR
, "Not enough memory "
3743 "to create object description");
3747 wpas_dbus_register(obj_desc
, wpa_s
, NULL
, NULL
,
3748 wpas_dbus_p2p_group_properties
,
3749 wpas_dbus_p2p_group_signals
);
3751 if (wpa_dbus_register_object_per_iface(ctrl_iface
, group_obj_path
,
3752 wpa_s
->ifname
, obj_desc
))
3758 if (wpa_s
->dbus_groupobj_path
) {
3759 os_free(wpa_s
->dbus_groupobj_path
);
3760 wpa_s
->dbus_groupobj_path
= NULL
;
3763 free_dbus_object_desc(obj_desc
);
3767 * wpas_dbus_unregister_p2p_group - Unregister a p2p group object from dbus
3768 * @wpa_s: wpa_supplicant interface structure
3769 * @ssid: network name of the p2p group started
3771 void wpas_dbus_unregister_p2p_group(struct wpa_supplicant
*wpa_s
,
3772 const struct wpa_ssid
*ssid
)
3774 struct wpas_dbus_priv
*ctrl_iface
;
3776 /* Do nothing if the control interface is not turned on */
3777 if (wpa_s
== NULL
|| wpa_s
->global
== NULL
)
3780 if (wpa_s
->p2p_mgmt
)
3781 wpa_s
= wpa_s
->parent
;
3783 ctrl_iface
= wpa_s
->global
->dbus
;
3784 if (ctrl_iface
== NULL
)
3787 if (!wpa_s
->dbus_groupobj_path
) {
3788 wpa_printf(MSG_DEBUG
,
3789 "%s: Group object '%s' already unregistered",
3790 __func__
, wpa_s
->dbus_groupobj_path
);
3794 peer_groups_changed(wpa_s
);
3796 wpa_printf(MSG_DEBUG
, "dbus: Unregister group object '%s'",
3797 wpa_s
->dbus_groupobj_path
);
3799 wpa_dbus_unregister_object_per_iface(ctrl_iface
,
3800 wpa_s
->dbus_groupobj_path
);
3802 os_free(wpa_s
->dbus_groupobj_path
);
3803 wpa_s
->dbus_groupobj_path
= NULL
;
3806 static const struct wpa_dbus_property_desc
3807 wpas_dbus_persistent_group_properties
[] = {
3808 { "Properties", WPAS_DBUS_NEW_IFACE_PERSISTENT_GROUP
, "a{sv}",
3809 wpas_dbus_getter_persistent_group_properties
,
3810 wpas_dbus_setter_persistent_group_properties
3812 { NULL
, NULL
, NULL
, NULL
, NULL
}
3815 /* No signals intended for persistent group objects */
3818 * wpas_dbus_register_persistent_group - Register a configured(saved)
3819 * persistent group with dbus
3820 * @wpa_s: wpa_supplicant interface structure
3821 * @ssid: persistent group (still represented as a network within wpa)
3822 * configuration data
3823 * Returns: 0 on success, -1 on failure
3825 * Registers a persistent group representing object with dbus.
3827 int wpas_dbus_register_persistent_group(struct wpa_supplicant
*wpa_s
,
3828 struct wpa_ssid
*ssid
)
3830 struct wpas_dbus_priv
*ctrl_iface
;
3831 struct wpa_dbus_object_desc
*obj_desc
;
3832 struct network_handler_args
*arg
;
3833 char pgrp_obj_path
[WPAS_DBUS_OBJECT_PATH_MAX
];
3835 /* Do nothing if the control interface is not turned on */
3836 if (wpa_s
== NULL
|| wpa_s
->global
== NULL
)
3839 /* Make sure ssid is a persistent group */
3840 if (ssid
->disabled
!= 2 && !ssid
->p2p_persistent_group
)
3841 return -1; /* should we return w/o complaining? */
3843 if (wpa_s
->p2p_mgmt
)
3844 wpa_s
= wpa_s
->parent
;
3846 ctrl_iface
= wpa_s
->global
->dbus
;
3847 if (ctrl_iface
== NULL
)
3851 * Intentionally not coming up with different numbering scheme
3852 * for persistent groups.
3854 os_snprintf(pgrp_obj_path
, WPAS_DBUS_OBJECT_PATH_MAX
,
3855 "%s/" WPAS_DBUS_NEW_PERSISTENT_GROUPS_PART
"/%u",
3856 wpa_s
->dbus_new_path
, ssid
->id
);
3858 wpa_printf(MSG_DEBUG
, "dbus: Register persistent group object '%s'",
3860 obj_desc
= os_zalloc(sizeof(struct wpa_dbus_object_desc
));
3862 wpa_printf(MSG_ERROR
, "dbus: Not enough memory to create "
3863 "object description");
3868 * Reusing the same context structure as that for networks
3869 * since these are represented using same data structure.
3871 /* allocate memory for handlers arguments */
3872 arg
= os_zalloc(sizeof(struct network_handler_args
));
3874 wpa_printf(MSG_ERROR
, "dbus: Not enough memory to create "
3875 "arguments for method");
3882 wpas_dbus_register(obj_desc
, arg
, wpa_dbus_free
, NULL
,
3883 wpas_dbus_persistent_group_properties
,
3886 if (wpa_dbus_register_object_per_iface(ctrl_iface
, pgrp_obj_path
,
3887 wpa_s
->ifname
, obj_desc
))
3890 wpas_dbus_signal_persistent_group_added(wpa_s
, ssid
->id
);
3895 free_dbus_object_desc(obj_desc
);
3901 * wpas_dbus_unregister_persistent_group - Unregister a persistent_group
3903 * @wpa_s: wpa_supplicant interface structure
3905 * Returns: 0 on success, -1 on failure
3907 * Unregisters persistent group representing object from dbus
3909 * NOTE: There is a slight issue with the semantics here. While the
3910 * implementation simply means the persistent group is unloaded from memory,
3911 * it should not get interpreted as the group is actually being erased/removed
3912 * from persistent storage as well.
3914 int wpas_dbus_unregister_persistent_group(struct wpa_supplicant
*wpa_s
,
3917 struct wpas_dbus_priv
*ctrl_iface
;
3918 char pgrp_obj_path
[WPAS_DBUS_OBJECT_PATH_MAX
];
3921 /* Do nothing if the control interface is not turned on */
3922 if (wpa_s
== NULL
|| wpa_s
->global
== NULL
||
3923 wpa_s
->dbus_new_path
== NULL
)
3926 if (wpa_s
->p2p_mgmt
)
3927 wpa_s
= wpa_s
->parent
;
3929 ctrl_iface
= wpa_s
->global
->dbus
;
3930 if (ctrl_iface
== NULL
)
3933 os_snprintf(pgrp_obj_path
, WPAS_DBUS_OBJECT_PATH_MAX
,
3934 "%s/" WPAS_DBUS_NEW_PERSISTENT_GROUPS_PART
"/%u",
3935 wpa_s
->dbus_new_path
, nid
);
3937 wpa_printf(MSG_DEBUG
, "dbus: Unregister persistent group object '%s'",
3939 ret
= wpa_dbus_unregister_object_per_iface(ctrl_iface
, pgrp_obj_path
);
3942 wpas_dbus_signal_persistent_group_removed(wpa_s
, nid
);
3947 #endif /* CONFIG_P2P */