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 */
1060 /* Explicit check for failure response */
1061 _signal = "ProvisionDiscoveryFailure";
1064 add_pin = ((request && (config_methods & WPS_CONFIG_DISPLAY)) ||
1065 (!request && !status &&
1066 (config_methods & WPS_CONFIG_KEYPAD)));
1069 os_snprintf(pin, sizeof(pin), "%08d", generated_pin);
1073 msg = dbus_message_new_signal(wpa_s->dbus_new_path,
1074 WPAS_DBUS_NEW_IFACE_P2PDEVICE, _signal);
1078 /* Check if this is a known peer */
1079 if (!p2p_peer_known(wpa_s->global->p2p, dev_addr))
1082 os_snprintf(peer_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
1083 "%s/" WPAS_DBUS_NEW_P2P_PEERS_PART "/"
1085 wpa_s->dbus_new_path, MAC2STR(dev_addr));
1087 path = peer_obj_path;
1089 dbus_message_iter_init_append(msg, &iter);
1091 if (!dbus_message_iter_append_basic(&iter,
1092 DBUS_TYPE_OBJECT_PATH,
1096 if (!request && status)
1097 /* Attach status to ProvisionDiscoveryFailure */
1098 error_ret = !dbus_message_iter_append_basic(&iter,
1102 error_ret = (add_pin &&
1103 !dbus_message_iter_append_basic(&iter,
1109 dbus_connection_send(iface->con, msg, NULL);
1111 wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
1113 dbus_message_unref(msg);
1117 void wpas_dbus_signal_p2p_go_neg_req(struct wpa_supplicant *wpa_s,
1118 const u8 *src, u16 dev_passwd_id)
1121 DBusMessageIter iter;
1122 struct wpas_dbus_priv *iface;
1123 char peer_obj_path[WPAS_DBUS_OBJECT_PATH_MAX], *path;
1125 iface = wpa_s->global->dbus;
1127 /* Do nothing if the control interface is not turned on */
1131 if (wpa_s->p2p_mgmt)
1132 wpa_s = wpa_s->parent;
1134 os_snprintf(peer_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
1135 "%s/" WPAS_DBUS_NEW_P2P_PEERS_PART "/" COMPACT_MACSTR,
1136 wpa_s->dbus_new_path, MAC2STR(src));
1137 path = peer_obj_path;
1139 msg = dbus_message_new_signal(wpa_s->dbus_new_path,
1140 WPAS_DBUS_NEW_IFACE_P2PDEVICE,
1141 "GONegotiationRequest");
1145 dbus_message_iter_init_append(msg, &iter);
1147 if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_OBJECT_PATH,
1149 !dbus_message_iter_append_basic(&iter, DBUS_TYPE_UINT16,
1151 wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
1153 dbus_connection_send(iface->con, msg, NULL);
1155 dbus_message_unref(msg);
1159 static int wpas_dbus_get_group_obj_path(struct wpa_supplicant *wpa_s,
1160 const struct wpa_ssid *ssid,
1161 char *group_obj_path)
1165 if (os_memcmp(ssid->ssid, P2P_WILDCARD_SSID, P2P_WILDCARD_SSID_LEN))
1168 os_memcpy(group_name, ssid->ssid + P2P_WILDCARD_SSID_LEN, 2);
1169 group_name[2] = '\0';
1171 os_snprintf(group_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
1172 "%s/" WPAS_DBUS_NEW_P2P_GROUPS_PART "/%s",
1173 wpa_s->dbus_new_path, group_name);
1179 struct group_changed_data {
1180 struct wpa_supplicant *wpa_s;
1181 struct p2p_peer_info *info;
1185 static int match_group_where_peer_is_client(struct p2p_group *group,
1188 struct group_changed_data *data = user_data;
1189 const struct p2p_group_config *cfg;
1190 struct wpa_supplicant *wpa_s_go;
1192 if (!p2p_group_is_client_connected(group, data->info->p2p_device_addr))
1195 cfg = p2p_group_get_config(group);
1197 wpa_s_go = wpas_get_p2p_go_iface(data->wpa_s, cfg->ssid,
1199 if (wpa_s_go != NULL && wpa_s_go == data->wpa_s) {
1200 wpas_dbus_signal_peer_groups_changed(
1201 data->wpa_s->parent, data->info->p2p_device_addr);
1209 static void signal_peer_groups_changed(struct p2p_peer_info *info,
1212 struct group_changed_data *data = user_data;
1213 struct wpa_supplicant *wpa_s_go;
1215 wpa_s_go = wpas_get_p2p_client_iface(data->wpa_s,
1216 info->p2p_device_addr);
1217 if (wpa_s_go != NULL && wpa_s_go == data->wpa_s) {
1218 wpas_dbus_signal_peer_groups_changed(data->wpa_s->parent,
1219 info->p2p_device_addr);
1224 p2p_loop_on_all_groups(data->wpa_s->global->p2p,
1225 match_group_where_peer_is_client, data);
1230 static void peer_groups_changed(struct wpa_supplicant *wpa_s)
1232 struct group_changed_data data;
1234 os_memset(&data, 0, sizeof(data));
1237 p2p_loop_on_known_peers(wpa_s->global->p2p,
1238 signal_peer_groups_changed, &data);
1243 * wpas_dbus_signal_p2p_group_started - Signals P2P group has
1244 * started. Emitted when a group is successfully started
1245 * irrespective of the role (client/GO) of the current device
1247 * @wpa_s: %wpa_supplicant network interface data
1248 * @ssid: SSID object
1249 * @client: this device is P2P client
1250 * @network_id: network id of the group started, use instead of ssid->id
1251 * to account for persistent groups
1253 void wpas_dbus_signal_p2p_group_started(struct wpa_supplicant *wpa_s,
1254 const struct wpa_ssid *ssid,
1255 int client, int network_id)
1258 DBusMessageIter iter, dict_iter;
1259 struct wpas_dbus_priv *iface;
1260 struct wpa_supplicant *parent;
1262 parent = wpa_s->parent;
1263 if (parent->p2p_mgmt)
1264 parent = parent->parent;
1266 iface = parent->global->dbus;
1268 /* Do nothing if the control interface is not turned on */
1272 if (wpa_s->dbus_groupobj_path == NULL)
1275 /* New interface has been created for this group */
1276 msg = dbus_message_new_signal(parent->dbus_new_path,
1277 WPAS_DBUS_NEW_IFACE_P2PDEVICE,
1282 dbus_message_iter_init_append(msg, &iter);
1283 if (!wpa_dbus_dict_open_write(&iter, &dict_iter))
1287 * In case the device supports creating a separate interface the
1288 * DBus client will need to know the object path for the interface
1289 * object this group was created on, so include it here.
1291 if (!wpa_dbus_dict_append_object_path(&dict_iter,
1293 wpa_s->dbus_new_path))
1296 if (!wpa_dbus_dict_append_string(&dict_iter, "role",
1297 client ? "client" : "GO"))
1300 if (!wpa_dbus_dict_append_object_path(&dict_iter, "group_object",
1301 wpa_s->dbus_groupobj_path) ||
1302 !wpa_dbus_dict_close_write(&iter, &dict_iter))
1305 dbus_connection_send(iface->con, msg, NULL);
1308 peer_groups_changed(wpa_s);
1311 dbus_message_unref(msg);
1317 * Method to emit GONegotiation Success or Failure signals based
1319 * @status: Status of the GO neg request. 0 for success, other for errors.
1321 void wpas_dbus_signal_p2p_go_neg_resp(struct wpa_supplicant *wpa_s,
1322 struct p2p_go_neg_results *res)
1325 DBusMessageIter iter, dict_iter;
1326 DBusMessageIter iter_dict_entry, iter_dict_val, iter_dict_array;
1327 struct wpas_dbus_priv *iface;
1328 char peer_obj_path[WPAS_DBUS_OBJECT_PATH_MAX], *path;
1329 dbus_int32_t freqs[P2P_MAX_CHANNELS];
1330 dbus_int32_t *f_array = freqs;
1333 iface = wpa_s->global->dbus;
1335 if (wpa_s->p2p_mgmt)
1336 wpa_s = wpa_s->parent;
1338 os_memset(freqs, 0, sizeof(freqs));
1339 /* Do nothing if the control interface is not turned on */
1343 os_snprintf(peer_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
1344 "%s/" WPAS_DBUS_NEW_P2P_PEERS_PART "/" COMPACT_MACSTR,
1345 wpa_s->dbus_new_path, MAC2STR(res->peer_device_addr));
1346 path = peer_obj_path;
1348 msg = dbus_message_new_signal(wpa_s->dbus_new_path,
1349 WPAS_DBUS_NEW_IFACE_P2PDEVICE,
1350 res->status ? "GONegotiationFailure" :
1351 "GONegotiationSuccess");
1355 dbus_message_iter_init_append(msg, &iter);
1356 if (!wpa_dbus_dict_open_write(&iter, &dict_iter))
1358 if (!wpa_dbus_dict_append_object_path(&dict_iter, "peer_object",
1360 !wpa_dbus_dict_append_int32(&dict_iter, "status", res->status))
1365 int freq_list_num = 0;
1368 !wpa_dbus_dict_append_string(&dict_iter, "passphrase",
1372 if (!wpa_dbus_dict_append_string(&dict_iter, "role_go",
1373 res->role_go ? "GO" :
1375 !wpa_dbus_dict_append_int32(&dict_iter, "frequency",
1377 !wpa_dbus_dict_append_byte_array(&dict_iter, "ssid",
1378 (const char *) res->ssid,
1380 !wpa_dbus_dict_append_byte_array(&dict_iter,
1383 res->peer_device_addr,
1385 !wpa_dbus_dict_append_byte_array(&dict_iter,
1386 "peer_interface_addr",
1388 res->peer_interface_addr,
1390 !wpa_dbus_dict_append_string(&dict_iter, "wps_method",
1391 p2p_wps_method_text(
1395 for (i = 0; i < P2P_MAX_CHANNELS; i++) {
1396 if (res->freq_list[i]) {
1397 freqs[i] = res->freq_list[i];
1402 if (!wpa_dbus_dict_begin_array(&dict_iter,
1404 DBUS_TYPE_INT32_AS_STRING,
1410 if (!dbus_message_iter_append_fixed_array(&iter_dict_array,
1416 if (!wpa_dbus_dict_end_array(&dict_iter,
1422 if (!wpa_dbus_dict_append_int32(&dict_iter, "persistent_group",
1423 res->persistent_group) ||
1424 !wpa_dbus_dict_append_uint32(&dict_iter,
1425 "peer_config_timeout",
1426 res->peer_config_timeout))
1430 if (!wpa_dbus_dict_close_write(&iter, &dict_iter))
1433 dbus_connection_send(iface->con, msg, NULL);
1435 dbus_message_unref(msg);
1441 * Method to emit Invitation Result signal based on status and
1443 * @status: Status of the Invite request. 0 for success, other
1445 * @bssid : Basic Service Set Identifier
1447 void wpas_dbus_signal_p2p_invitation_result(struct wpa_supplicant *wpa_s,
1448 int status, const u8 *bssid)
1451 DBusMessageIter iter, dict_iter;
1452 struct wpas_dbus_priv *iface;
1454 wpa_printf(MSG_DEBUG, "%s", __func__);
1456 iface = wpa_s->global->dbus;
1457 /* Do nothing if the control interface is not turned on */
1461 if (wpa_s->p2p_mgmt)
1462 wpa_s = wpa_s->parent;
1464 msg = dbus_message_new_signal(wpa_s->dbus_new_path,
1465 WPAS_DBUS_NEW_IFACE_P2PDEVICE,
1466 "InvitationResult");
1471 dbus_message_iter_init_append(msg, &iter);
1472 if (!wpa_dbus_dict_open_write(&iter, &dict_iter))
1475 if (!wpa_dbus_dict_append_int32(&dict_iter, "status", status))
1478 if (!wpa_dbus_dict_append_byte_array(&dict_iter, "BSSID",
1479 (const char *) bssid,
1483 if (!wpa_dbus_dict_close_write(&iter, &dict_iter))
1486 dbus_connection_send(iface->con, msg, NULL);
1489 dbus_message_unref(msg);
1495 * Method to emit a signal for a peer joining the group.
1496 * The signal will carry path to the group member object
1497 * constructed using p2p i/f addr used for connecting.
1499 * @wpa_s: %wpa_supplicant network interface data
1500 * @peer_addr: P2P Device Address of the peer joining the group
1502 void wpas_dbus_signal_p2p_peer_joined(struct wpa_supplicant *wpa_s,
1503 const u8 *peer_addr)
1505 struct wpas_dbus_priv *iface;
1507 DBusMessageIter iter;
1508 char peer_obj_path[WPAS_DBUS_OBJECT_PATH_MAX], *path;
1509 struct wpa_supplicant *parent;
1511 iface = wpa_s->global->dbus;
1513 /* Do nothing if the control interface is not turned on */
1517 if (!wpa_s->dbus_groupobj_path)
1520 parent = wpa_s->parent;
1521 if (parent->p2p_mgmt)
1522 parent = parent->parent;
1524 os_snprintf(peer_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
1525 "%s/" WPAS_DBUS_NEW_P2P_PEERS_PART "/"
1527 parent->dbus_new_path, MAC2STR(peer_addr));
1529 msg = dbus_message_new_signal(wpa_s->dbus_groupobj_path,
1530 WPAS_DBUS_NEW_IFACE_P2P_GROUP,
1535 dbus_message_iter_init_append(msg, &iter);
1536 path = peer_obj_path;
1537 if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_OBJECT_PATH,
1541 dbus_connection_send(iface->con, msg, NULL);
1542 dbus_message_unref(msg);
1544 wpas_dbus_signal_peer_groups_changed(parent, peer_addr);
1549 wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
1550 dbus_message_unref(msg);
1556 * Method to emit a signal for a peer disconnecting the group.
1557 * The signal will carry path to the group member object
1558 * constructed using the P2P Device Address of the peer.
1560 * @wpa_s: %wpa_supplicant network interface data
1561 * @peer_addr: P2P Device Address of the peer joining the group
1563 void wpas_dbus_signal_p2p_peer_disconnected(struct wpa_supplicant *wpa_s,
1564 const u8 *peer_addr)
1566 struct wpas_dbus_priv *iface;
1568 DBusMessageIter iter;
1569 char peer_obj_path[WPAS_DBUS_OBJECT_PATH_MAX], *path;
1570 struct wpa_supplicant *parent;
1572 iface = wpa_s->global->dbus;
1574 /* Do nothing if the control interface is not turned on */
1578 if (!wpa_s->dbus_groupobj_path)
1581 parent = wpa_s->parent;
1582 if (parent->p2p_mgmt)
1583 parent = parent->parent;
1585 os_snprintf(peer_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
1586 "%s/" WPAS_DBUS_NEW_P2P_PEERS_PART "/"
1588 parent->dbus_new_path, MAC2STR(peer_addr));
1590 msg = dbus_message_new_signal(wpa_s->dbus_groupobj_path,
1591 WPAS_DBUS_NEW_IFACE_P2P_GROUP,
1592 "PeerDisconnected");
1596 dbus_message_iter_init_append(msg, &iter);
1597 path = peer_obj_path;
1598 if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_OBJECT_PATH,
1602 dbus_connection_send(iface->con, msg, NULL);
1603 dbus_message_unref(msg);
1605 wpas_dbus_signal_peer_groups_changed(parent, peer_addr);
1610 wpa_printf(MSG_ERROR, "dbus: Failed to construct PeerDisconnected "
1612 dbus_message_unref(msg);
1618 * Method to emit a signal for a service discovery request.
1619 * The signal will carry station address, frequency, dialog token,
1620 * update indicator and it tlvs
1622 * @wpa_s: %wpa_supplicant network interface data
1623 * @sa: station addr (p2p i/f) of the peer
1624 * @dialog_token: service discovery request dialog token
1625 * @update_indic: service discovery request update indicator
1626 * @tlvs: service discovery request genrated byte array of tlvs
1627 * @tlvs_len: service discovery request tlvs length
1629 void wpas_dbus_signal_p2p_sd_request(struct wpa_supplicant *wpa_s,
1630 int freq, const u8 *sa, u8 dialog_token,
1631 u16 update_indic, const u8 *tlvs,
1635 DBusMessageIter iter, dict_iter;
1636 struct wpas_dbus_priv *iface;
1637 char peer_obj_path[WPAS_DBUS_OBJECT_PATH_MAX], *path;
1638 iface = wpa_s->global->dbus;
1640 /* Do nothing if the control interface is not turned on */
1644 if (wpa_s->p2p_mgmt)
1645 wpa_s = wpa_s->parent;
1647 msg = dbus_message_new_signal(wpa_s->dbus_new_path,
1648 WPAS_DBUS_NEW_IFACE_P2PDEVICE,
1649 "ServiceDiscoveryRequest");
1653 /* Check if this is a known peer */
1654 if (!p2p_peer_known(wpa_s->global->p2p, sa))
1657 os_snprintf(peer_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
1658 "%s/" WPAS_DBUS_NEW_P2P_PEERS_PART "/"
1659 COMPACT_MACSTR, wpa_s->dbus_new_path, MAC2STR(sa));
1661 path = peer_obj_path;
1663 dbus_message_iter_init_append(msg, &iter);
1664 if (!wpa_dbus_dict_open_write(&iter, &dict_iter))
1668 if (!wpa_dbus_dict_append_object_path(&dict_iter, "peer_object",
1670 !wpa_dbus_dict_append_int32(&dict_iter, "frequency", freq) ||
1671 !wpa_dbus_dict_append_int32(&dict_iter, "dialog_token",
1673 !wpa_dbus_dict_append_uint16(&dict_iter, "update_indicator",
1675 !wpa_dbus_dict_append_byte_array(&dict_iter, "tlvs",
1676 (const char *) tlvs,
1678 !wpa_dbus_dict_close_write(&iter, &dict_iter))
1681 dbus_connection_send(iface->con, msg, NULL);
1682 dbus_message_unref(msg);
1685 wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
1686 dbus_message_unref(msg);
1692 * Method to emit a signal for a service discovery response.
1693 * The signal will carry station address, update indicator and it
1696 * @wpa_s: %wpa_supplicant network interface data
1697 * @sa: station addr (p2p i/f) of the peer
1698 * @update_indic: service discovery request update indicator
1699 * @tlvs: service discovery request genrated byte array of tlvs
1700 * @tlvs_len: service discovery request tlvs length
1702 void wpas_dbus_signal_p2p_sd_response(struct wpa_supplicant *wpa_s,
1703 const u8 *sa, u16 update_indic,
1704 const u8 *tlvs, size_t tlvs_len)
1707 DBusMessageIter iter, dict_iter;
1708 struct wpas_dbus_priv *iface;
1709 char peer_obj_path[WPAS_DBUS_OBJECT_PATH_MAX], *path;
1710 iface = wpa_s->global->dbus;
1712 /* Do nothing if the control interface is not turned on */
1716 if (wpa_s->p2p_mgmt)
1717 wpa_s = wpa_s->parent;
1719 msg = dbus_message_new_signal(wpa_s->dbus_new_path,
1720 WPAS_DBUS_NEW_IFACE_P2PDEVICE,
1721 "ServiceDiscoveryResponse");
1725 /* Check if this is a known peer */
1726 if (!p2p_peer_known(wpa_s->global->p2p, sa))
1729 os_snprintf(peer_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
1730 "%s/" WPAS_DBUS_NEW_P2P_PEERS_PART "/"
1731 COMPACT_MACSTR, wpa_s->dbus_new_path, MAC2STR(sa));
1733 path = peer_obj_path;
1735 dbus_message_iter_init_append(msg, &iter);
1736 if (!wpa_dbus_dict_open_write(&iter, &dict_iter))
1739 if (!wpa_dbus_dict_append_object_path(&dict_iter, "peer_object",
1741 !wpa_dbus_dict_append_uint16(&dict_iter, "update_indicator",
1743 !wpa_dbus_dict_append_byte_array(&dict_iter, "tlvs",
1744 (const char *) tlvs,
1746 !wpa_dbus_dict_close_write(&iter, &dict_iter))
1750 dbus_connection_send(iface->con, msg, NULL);
1751 dbus_message_unref(msg);
1754 wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
1755 dbus_message_unref(msg);
1759 * wpas_dbus_signal_persistent_group - Send a persistent group related
1761 * @wpa_s: %wpa_supplicant network interface data
1762 * @id: new persistent group id
1763 * @sig_name: signal name - PersistentGroupAdded, PersistentGroupRemoved
1764 * @properties: determines if add second argument with object properties
1766 * Notify listeners about an event related to persistent groups.
1768 static void wpas_dbus_signal_persistent_group(struct wpa_supplicant *wpa_s,
1769 int id, const char *sig_name,
1772 struct wpas_dbus_priv *iface;
1774 DBusMessageIter iter;
1775 char pgrp_obj_path[WPAS_DBUS_OBJECT_PATH_MAX], *path;
1777 iface = wpa_s->global->dbus;
1779 /* Do nothing if the control interface is not turned on */
1783 if (wpa_s->p2p_mgmt)
1784 wpa_s = wpa_s->parent;
1786 os_snprintf(pgrp_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
1787 "%s/" WPAS_DBUS_NEW_PERSISTENT_GROUPS_PART "/%u",
1788 wpa_s->dbus_new_path, id);
1790 msg = dbus_message_new_signal(wpa_s->dbus_new_path,
1791 WPAS_DBUS_NEW_IFACE_P2PDEVICE,
1796 dbus_message_iter_init_append(msg, &iter);
1797 path = pgrp_obj_path;
1798 if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_OBJECT_PATH,
1803 if (!wpa_dbus_get_object_properties(
1804 iface, pgrp_obj_path,
1805 WPAS_DBUS_NEW_IFACE_PERSISTENT_GROUP, &iter))
1809 dbus_connection_send(iface->con, msg, NULL);
1811 dbus_message_unref(msg);
1815 wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
1816 dbus_message_unref(msg);
1821 * wpas_dbus_signal_persistent_group_added - Send a persistent_group
1823 * @wpa_s: %wpa_supplicant network interface data
1824 * @id: new persistent group id
1826 * Notify listeners about addition of a new persistent group.
1828 static void wpas_dbus_signal_persistent_group_added(
1829 struct wpa_supplicant *wpa_s, int id)
1831 wpas_dbus_signal_persistent_group(wpa_s, id, "PersistentGroupAdded",
1837 * wpas_dbus_signal_persistent_group_removed - Send a persistent_group
1839 * @wpa_s: %wpa_supplicant network interface data
1840 * @id: persistent group id
1842 * Notify listeners about removal of a persistent group.
1844 static void wpas_dbus_signal_persistent_group_removed(
1845 struct wpa_supplicant *wpa_s, int id)
1847 wpas_dbus_signal_persistent_group(wpa_s, id, "PersistentGroupRemoved",
1853 * wpas_dbus_signal_p2p_wps_failed - Signals WpsFailed event
1854 * @wpa_s: %wpa_supplicant network interface data
1856 * Sends Event dbus signal with name "fail" and dictionary containing
1857 * "msg" field with fail message number (int32) as arguments
1859 void wpas_dbus_signal_p2p_wps_failed(struct wpa_supplicant *wpa_s,
1860 struct wps_event_fail *fail)
1864 DBusMessageIter iter, dict_iter;
1865 struct wpas_dbus_priv *iface;
1868 iface = wpa_s->global->dbus;
1870 /* Do nothing if the control interface is not turned on */
1874 if (wpa_s->p2p_mgmt)
1875 wpa_s = wpa_s->parent;
1877 msg = dbus_message_new_signal(wpa_s->dbus_new_path,
1878 WPAS_DBUS_NEW_IFACE_P2PDEVICE,
1883 dbus_message_iter_init_append(msg, &iter);
1885 if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &key) ||
1886 !wpa_dbus_dict_open_write(&iter, &dict_iter) ||
1887 !wpa_dbus_dict_append_int32(&dict_iter, "msg", fail->msg) ||
1888 !wpa_dbus_dict_append_int16(&dict_iter, "config_error",
1889 fail->config_error) ||
1890 !wpa_dbus_dict_close_write(&iter, &dict_iter))
1891 wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
1893 dbus_connection_send(iface->con, msg, NULL);
1895 dbus_message_unref(msg);
1898 #endif /*CONFIG_P2P*/
1902 * wpas_dbus_signal_prop_changed - Signals change of property
1903 * @wpa_s: %wpa_supplicant network interface data
1904 * @property: indicates which property has changed
1906 * Sends PropertyChanged signals with path, interface and arguments
1907 * depending on which property has changed.
1909 void wpas_dbus_signal_prop_changed(struct wpa_supplicant *wpa_s,
1910 enum wpas_dbus_prop property)
1915 if (wpa_s->dbus_new_path == NULL)
1916 return; /* Skip signal since D-Bus setup is not yet ready */
1920 case WPAS_DBUS_PROP_AP_SCAN:
1923 case WPAS_DBUS_PROP_SCANNING:
1926 case WPAS_DBUS_PROP_STATE:
1929 case WPAS_DBUS_PROP_CURRENT_BSS:
1930 prop = "CurrentBSS";
1932 case WPAS_DBUS_PROP_CURRENT_NETWORK:
1933 prop = "CurrentNetwork";
1935 case WPAS_DBUS_PROP_BSSS:
1938 case WPAS_DBUS_PROP_CURRENT_AUTH_MODE:
1939 prop = "CurrentAuthMode";
1941 case WPAS_DBUS_PROP_DISCONNECT_REASON:
1942 prop = "DisconnectReason";
1946 wpa_printf(MSG_ERROR, "dbus: %s: Unknown Property value %d",
1947 __func__, property);
1951 wpa_dbus_mark_property_changed(wpa_s->global->dbus,
1952 wpa_s->dbus_new_path,
1953 WPAS_DBUS_NEW_IFACE_INTERFACE, prop);
1955 wpa_dbus_flush_object_changed_properties(
1956 wpa_s->global->dbus->con, wpa_s->dbus_new_path);
1962 * wpas_dbus_bss_signal_prop_changed - Signals change of BSS property
1963 * @wpa_s: %wpa_supplicant network interface data
1964 * @property: indicates which property has changed
1965 * @id: unique BSS identifier
1967 * Sends PropertyChanged signals with path, interface, and arguments depending
1968 * on which property has changed.
1970 void wpas_dbus_bss_signal_prop_changed(struct wpa_supplicant *wpa_s,
1971 enum wpas_dbus_bss_prop property,
1974 char path[WPAS_DBUS_OBJECT_PATH_MAX];
1978 case WPAS_DBUS_BSS_PROP_SIGNAL:
1981 case WPAS_DBUS_BSS_PROP_FREQ:
1984 case WPAS_DBUS_BSS_PROP_MODE:
1987 case WPAS_DBUS_BSS_PROP_PRIVACY:
1990 case WPAS_DBUS_BSS_PROP_RATES:
1993 case WPAS_DBUS_BSS_PROP_WPA:
1996 case WPAS_DBUS_BSS_PROP_RSN:
1999 case WPAS_DBUS_BSS_PROP_WPS:
2002 case WPAS_DBUS_BSS_PROP_IES:
2005 case WPAS_DBUS_BSS_PROP_AGE:
2009 wpa_printf(MSG_ERROR, "dbus: %s: Unknown Property value %d",
2010 __func__, property);
2014 os_snprintf(path, WPAS_DBUS_OBJECT_PATH_MAX,
2015 "%s/" WPAS_DBUS_NEW_BSSIDS_PART "/%u",
2016 wpa_s->dbus_new_path, id);
2018 wpa_dbus_mark_property_changed(wpa_s->global->dbus, path,
2019 WPAS_DBUS_NEW_IFACE_BSS, prop);
2024 * wpas_dbus_signal_debug_level_changed - Signals change of debug param
2025 * @global: wpa_global structure
2027 * Sends PropertyChanged signals informing that debug level has changed.
2029 void wpas_dbus_signal_debug_level_changed(struct wpa_global *global)
2031 wpa_dbus_mark_property_changed(global->dbus, WPAS_DBUS_NEW_PATH,
2032 WPAS_DBUS_NEW_INTERFACE,
2038 * wpas_dbus_signal_debug_timestamp_changed - Signals change of debug param
2039 * @global: wpa_global structure
2041 * Sends PropertyChanged signals informing that debug timestamp has changed.
2043 void wpas_dbus_signal_debug_timestamp_changed(struct wpa_global *global)
2045 wpa_dbus_mark_property_changed(global->dbus, WPAS_DBUS_NEW_PATH,
2046 WPAS_DBUS_NEW_INTERFACE,
2052 * wpas_dbus_signal_debug_show_keys_changed - Signals change of debug param
2053 * @global: wpa_global structure
2055 * Sends PropertyChanged signals informing that debug show_keys has changed.
2057 void wpas_dbus_signal_debug_show_keys_changed(struct wpa_global *global)
2059 wpa_dbus_mark_property_changed(global->dbus, WPAS_DBUS_NEW_PATH,
2060 WPAS_DBUS_NEW_INTERFACE,
2065 static void wpas_dbus_register(struct wpa_dbus_object_desc *obj_desc,
2067 WPADBusArgumentFreeFunction priv_free,
2068 const struct wpa_dbus_method_desc *methods,
2069 const struct wpa_dbus_property_desc *properties,
2070 const struct wpa_dbus_signal_desc *signals)
2074 obj_desc->user_data = priv;
2075 obj_desc->user_data_free_func = priv_free;
2076 obj_desc->methods = methods;
2077 obj_desc->properties = properties;
2078 obj_desc->signals = signals;
2080 for (n = 0; properties && properties->dbus_property; properties++)
2083 obj_desc->prop_changed_flags = os_zalloc(n);
2084 if (!obj_desc->prop_changed_flags)
2085 wpa_printf(MSG_DEBUG, "dbus: %s: can't register handlers",
2090 static const struct wpa_dbus_method_desc wpas_dbus_global_methods[] = {
2091 { "CreateInterface", WPAS_DBUS_NEW_INTERFACE,
2092 (WPADBusMethodHandler) &wpas_dbus_handler_create_interface,
2094 { "args", "a{sv}", ARG_IN },
2095 { "path", "o", ARG_OUT },
2099 { "RemoveInterface", WPAS_DBUS_NEW_INTERFACE,
2100 (WPADBusMethodHandler) &wpas_dbus_handler_remove_interface,
2102 { "path", "o", ARG_IN },
2106 { "GetInterface", WPAS_DBUS_NEW_INTERFACE,
2107 (WPADBusMethodHandler) &wpas_dbus_handler_get_interface,
2109 { "ifname", "s", ARG_IN },
2110 { "path", "o", ARG_OUT },
2114 { NULL, NULL, NULL, { END_ARGS } }
2117 static const struct wpa_dbus_property_desc wpas_dbus_global_properties[] = {
2118 { "DebugLevel", WPAS_DBUS_NEW_INTERFACE, "s",
2119 wpas_dbus_getter_debug_level,
2120 wpas_dbus_setter_debug_level
2122 { "DebugTimestamp", WPAS_DBUS_NEW_INTERFACE, "b",
2123 wpas_dbus_getter_debug_timestamp,
2124 wpas_dbus_setter_debug_timestamp
2126 { "DebugShowKeys", WPAS_DBUS_NEW_INTERFACE, "b",
2127 wpas_dbus_getter_debug_show_keys,
2128 wpas_dbus_setter_debug_show_keys
2130 { "Interfaces", WPAS_DBUS_NEW_INTERFACE, "ao",
2131 wpas_dbus_getter_interfaces,
2134 { "EapMethods", WPAS_DBUS_NEW_INTERFACE, "as",
2135 wpas_dbus_getter_eap_methods,
2138 { "Capabilities", WPAS_DBUS_NEW_INTERFACE, "as",
2139 wpas_dbus_getter_global_capabilities,
2142 #ifdef CONFIG_WIFI_DISPLAY
2143 { "WFDIEs", WPAS_DBUS_NEW_INTERFACE, "ay",
2144 wpas_dbus_getter_global_wfd_ies,
2145 wpas_dbus_setter_global_wfd_ies
2147 #endif /* CONFIG_WIFI_DISPLAY */
2148 { NULL, NULL, NULL, NULL, NULL }
2151 static const struct wpa_dbus_signal_desc wpas_dbus_global_signals[] = {
2152 { "InterfaceAdded", WPAS_DBUS_NEW_INTERFACE,
2154 { "path", "o", ARG_OUT },
2155 { "properties", "a{sv}", ARG_OUT },
2159 { "InterfaceRemoved", WPAS_DBUS_NEW_INTERFACE,
2161 { "path", "o", ARG_OUT },
2165 { "NetworkRequest", WPAS_DBUS_NEW_IFACE_INTERFACE,
2167 { "path", "o", ARG_OUT },
2168 { "field", "s", ARG_OUT },
2169 { "text", "s", ARG_OUT },
2173 /* Deprecated: use org.freedesktop.DBus.Properties.PropertiesChanged */
2174 { "PropertiesChanged", WPAS_DBUS_NEW_INTERFACE,
2176 { "properties", "a{sv}", ARG_OUT },
2180 { NULL, NULL, { END_ARGS } }
2185 * wpas_dbus_ctrl_iface_init - Initialize dbus control interface
2186 * @global: Pointer to global data from wpa_supplicant_init()
2187 * Returns: 0 on success or -1 on failure
2189 * Initialize the dbus control interface for wpa_supplicantand and start
2190 * receiving commands from external programs over the bus.
2192 int wpas_dbus_ctrl_iface_init(struct wpas_dbus_priv *priv)
2194 struct wpa_dbus_object_desc *obj_desc;
2197 obj_desc = os_zalloc(sizeof(struct wpa_dbus_object_desc));
2199 wpa_printf(MSG_ERROR, "Not enough memory "
2200 "to create object description");
2204 wpas_dbus_register(obj_desc, priv->global, NULL,
2205 wpas_dbus_global_methods,
2206 wpas_dbus_global_properties,
2207 wpas_dbus_global_signals);
2209 wpa_printf(MSG_DEBUG, "dbus: Register D-Bus object '%s'",
2210 WPAS_DBUS_NEW_PATH);
2211 ret = wpa_dbus_ctrl_iface_init(priv, WPAS_DBUS_NEW_PATH,
2212 WPAS_DBUS_NEW_SERVICE,
2215 free_dbus_object_desc(obj_desc);
2217 priv->dbus_new_initialized = 1;
2224 * wpas_dbus_ctrl_iface_deinit - Deinitialize dbus ctrl interface for
2226 * @iface: Pointer to dbus private data from wpas_dbus_init()
2228 * Deinitialize the dbus control interface that was initialized with
2229 * wpas_dbus_ctrl_iface_init().
2231 void wpas_dbus_ctrl_iface_deinit(struct wpas_dbus_priv *iface)
2233 if (!iface->dbus_new_initialized)
2235 wpa_printf(MSG_DEBUG, "dbus: Unregister D-Bus object '%s'",
2236 WPAS_DBUS_NEW_PATH);
2237 dbus_connection_unregister_object_path(iface->con,
2238 WPAS_DBUS_NEW_PATH);
2242 static void wpa_dbus_free(void *ptr)
2248 static const struct wpa_dbus_property_desc wpas_dbus_network_properties[] = {
2249 { "Properties", WPAS_DBUS_NEW_IFACE_NETWORK, "a{sv}",
2250 wpas_dbus_getter_network_properties,
2251 wpas_dbus_setter_network_properties
2253 { "Enabled", WPAS_DBUS_NEW_IFACE_NETWORK, "b",
2254 wpas_dbus_getter_enabled,
2255 wpas_dbus_setter_enabled
2257 { NULL, NULL, NULL, NULL, NULL }
2261 static const struct wpa_dbus_signal_desc wpas_dbus_network_signals[] = {
2262 /* Deprecated: use org.freedesktop.DBus.Properties.PropertiesChanged */
2263 { "PropertiesChanged", WPAS_DBUS_NEW_IFACE_NETWORK,
2265 { "properties", "a{sv}", ARG_OUT },
2269 { NULL, NULL, { END_ARGS } }
2274 * wpas_dbus_register_network - Register a configured network with dbus
2275 * @wpa_s: wpa_supplicant interface structure
2276 * @ssid: network configuration data
2277 * Returns: 0 on success, -1 on failure
2279 * Registers network representing object with dbus
2281 int wpas_dbus_register_network(struct wpa_supplicant *wpa_s,
2282 struct wpa_ssid *ssid)
2284 struct wpas_dbus_priv *ctrl_iface;
2285 struct wpa_dbus_object_desc *obj_desc;
2286 struct network_handler_args *arg;
2287 char net_obj_path[WPAS_DBUS_OBJECT_PATH_MAX];
2291 * If it is a persistent group register it as such.
2292 * This is to handle cases where an interface is being initialized
2293 * with a list of networks read from config.
2295 if (network_is_persistent_group(ssid))
2296 return wpas_dbus_register_persistent_group(wpa_s, ssid);
2297 #endif /* CONFIG_P2P */
2299 /* Do nothing if the control interface is not turned on */
2300 if (wpa_s == NULL || wpa_s->global == NULL)
2302 ctrl_iface = wpa_s->global->dbus;
2303 if (ctrl_iface == NULL)
2306 os_snprintf(net_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
2307 "%s/" WPAS_DBUS_NEW_NETWORKS_PART "/%u",
2308 wpa_s->dbus_new_path, ssid->id);
2310 wpa_printf(MSG_DEBUG, "dbus: Register network object '%s'",
2312 obj_desc = os_zalloc(sizeof(struct wpa_dbus_object_desc));
2314 wpa_printf(MSG_ERROR, "Not enough memory "
2315 "to create object description");
2319 /* allocate memory for handlers arguments */
2320 arg = os_zalloc(sizeof(struct network_handler_args));
2322 wpa_printf(MSG_ERROR, "Not enough memory "
2323 "to create arguments for method");
2330 wpas_dbus_register(obj_desc, arg, wpa_dbus_free, NULL,
2331 wpas_dbus_network_properties,
2332 wpas_dbus_network_signals);
2334 if (wpa_dbus_register_object_per_iface(ctrl_iface, net_obj_path,
2335 wpa_s->ifname, obj_desc))
2338 wpas_dbus_signal_network_added(wpa_s, ssid->id);
2343 free_dbus_object_desc(obj_desc);
2349 * wpas_dbus_unregister_network - Unregister a configured network from dbus
2350 * @wpa_s: wpa_supplicant interface structure
2352 * Returns: 0 on success, -1 on failure
2354 * Unregisters network representing object from dbus
2356 int wpas_dbus_unregister_network(struct wpa_supplicant *wpa_s, int nid)
2358 struct wpas_dbus_priv *ctrl_iface;
2359 char net_obj_path[WPAS_DBUS_OBJECT_PATH_MAX];
2362 struct wpa_ssid *ssid;
2364 ssid = wpa_config_get_network(wpa_s->conf, nid);
2366 /* If it is a persistent group unregister it as such */
2367 if (ssid && network_is_persistent_group(ssid))
2368 return wpas_dbus_unregister_persistent_group(wpa_s, nid);
2369 #endif /* CONFIG_P2P */
2371 /* Do nothing if the control interface is not turned on */
2372 if (wpa_s->global == NULL || wpa_s->dbus_new_path == NULL)
2374 ctrl_iface = wpa_s->global->dbus;
2375 if (ctrl_iface == NULL)
2378 os_snprintf(net_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
2379 "%s/" WPAS_DBUS_NEW_NETWORKS_PART "/%u",
2380 wpa_s->dbus_new_path, nid);
2382 wpa_printf(MSG_DEBUG, "dbus: Unregister network object '%s'",
2384 ret = wpa_dbus_unregister_object_per_iface(ctrl_iface, net_obj_path);
2387 wpas_dbus_signal_network_removed(wpa_s, nid);
2393 static const struct wpa_dbus_property_desc wpas_dbus_bss_properties[] = {
2394 { "SSID", WPAS_DBUS_NEW_IFACE_BSS, "ay",
2395 wpas_dbus_getter_bss_ssid,
2398 { "BSSID", WPAS_DBUS_NEW_IFACE_BSS, "ay",
2399 wpas_dbus_getter_bss_bssid,
2402 { "Privacy", WPAS_DBUS_NEW_IFACE_BSS, "b",
2403 wpas_dbus_getter_bss_privacy,
2406 { "Mode", WPAS_DBUS_NEW_IFACE_BSS, "s",
2407 wpas_dbus_getter_bss_mode,
2410 { "Signal", WPAS_DBUS_NEW_IFACE_BSS, "n",
2411 wpas_dbus_getter_bss_signal,
2414 { "Frequency", WPAS_DBUS_NEW_IFACE_BSS, "q",
2415 wpas_dbus_getter_bss_frequency,
2418 { "Rates", WPAS_DBUS_NEW_IFACE_BSS, "au",
2419 wpas_dbus_getter_bss_rates,
2422 { "WPA", WPAS_DBUS_NEW_IFACE_BSS, "a{sv}",
2423 wpas_dbus_getter_bss_wpa,
2426 { "RSN", WPAS_DBUS_NEW_IFACE_BSS, "a{sv}",
2427 wpas_dbus_getter_bss_rsn,
2430 { "WPS", WPAS_DBUS_NEW_IFACE_BSS, "a{sv}",
2431 wpas_dbus_getter_bss_wps,
2434 { "IEs", WPAS_DBUS_NEW_IFACE_BSS, "ay",
2435 wpas_dbus_getter_bss_ies,
2438 { "Age", WPAS_DBUS_NEW_IFACE_BSS, "u",
2439 wpas_dbus_getter_bss_age,
2442 { NULL, NULL, NULL, NULL, NULL }
2446 static const struct wpa_dbus_signal_desc wpas_dbus_bss_signals[] = {
2447 /* Deprecated: use org.freedesktop.DBus.Properties.PropertiesChanged */
2448 { "PropertiesChanged", WPAS_DBUS_NEW_IFACE_BSS,
2450 { "properties", "a{sv}", ARG_OUT },
2454 { NULL, NULL, { END_ARGS } }
2459 * wpas_dbus_unregister_bss - Unregister a scanned BSS from dbus
2460 * @wpa_s: wpa_supplicant interface structure
2461 * @bssid: scanned network bssid
2462 * @id: unique BSS identifier
2463 * Returns: 0 on success, -1 on failure
2465 * Unregisters BSS representing object from dbus
2467 int wpas_dbus_unregister_bss(struct wpa_supplicant *wpa_s,
2468 u8 bssid[ETH_ALEN], unsigned int id)
2470 struct wpas_dbus_priv *ctrl_iface;
2471 char bss_obj_path[WPAS_DBUS_OBJECT_PATH_MAX];
2473 /* Do nothing if the control interface is not turned on */
2474 if (wpa_s == NULL || wpa_s->global == NULL)
2476 ctrl_iface = wpa_s->global->dbus;
2477 if (ctrl_iface == NULL)
2480 os_snprintf(bss_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
2481 "%s/" WPAS_DBUS_NEW_BSSIDS_PART "/%u",
2482 wpa_s->dbus_new_path, id);
2484 wpa_printf(MSG_DEBUG, "dbus: Unregister BSS object '%s'",
2486 if (wpa_dbus_unregister_object_per_iface(ctrl_iface, bss_obj_path)) {
2487 wpa_printf(MSG_ERROR, "dbus: Cannot unregister BSS object %s",
2492 wpas_dbus_signal_bss_removed(wpa_s, bss_obj_path);
2493 wpas_dbus_signal_prop_changed(wpa_s, WPAS_DBUS_PROP_BSSS);
2500 * wpas_dbus_register_bss - Register a scanned BSS with dbus
2501 * @wpa_s: wpa_supplicant interface structure
2502 * @bssid: scanned network bssid
2503 * @id: unique BSS identifier
2504 * Returns: 0 on success, -1 on failure
2506 * Registers BSS representing object with dbus
2508 int wpas_dbus_register_bss(struct wpa_supplicant *wpa_s,
2509 u8 bssid[ETH_ALEN], unsigned int id)
2511 struct wpas_dbus_priv *ctrl_iface;
2512 struct wpa_dbus_object_desc *obj_desc;
2513 char bss_obj_path[WPAS_DBUS_OBJECT_PATH_MAX];
2514 struct bss_handler_args *arg;
2516 /* Do nothing if the control interface is not turned on */
2517 if (wpa_s == NULL || wpa_s->global == NULL)
2519 ctrl_iface = wpa_s->global->dbus;
2520 if (ctrl_iface == NULL)
2523 os_snprintf(bss_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
2524 "%s/" WPAS_DBUS_NEW_BSSIDS_PART "/%u",
2525 wpa_s->dbus_new_path, id);
2527 obj_desc = os_zalloc(sizeof(struct wpa_dbus_object_desc));
2529 wpa_printf(MSG_ERROR, "Not enough memory "
2530 "to create object description");
2534 arg = os_zalloc(sizeof(struct bss_handler_args));
2536 wpa_printf(MSG_ERROR, "Not enough memory "
2537 "to create arguments for handler");
2543 wpas_dbus_register(obj_desc, arg, wpa_dbus_free, NULL,
2544 wpas_dbus_bss_properties,
2545 wpas_dbus_bss_signals);
2547 wpa_printf(MSG_DEBUG, "dbus: Register BSS object '%s'",
2549 if (wpa_dbus_register_object_per_iface(ctrl_iface, bss_obj_path,
2550 wpa_s->ifname, obj_desc)) {
2551 wpa_printf(MSG_ERROR,
2552 "Cannot register BSSID dbus object %s.",
2557 wpas_dbus_signal_bss_added(wpa_s, bss_obj_path);
2558 wpas_dbus_signal_prop_changed(wpa_s, WPAS_DBUS_PROP_BSSS);
2563 free_dbus_object_desc(obj_desc);
2568 static const struct wpa_dbus_method_desc wpas_dbus_interface_methods[] = {
2569 { "Scan", WPAS_DBUS_NEW_IFACE_INTERFACE,
2570 (WPADBusMethodHandler) &wpas_dbus_handler_scan,
2572 { "args", "a{sv}", ARG_IN },
2576 { "SignalPoll", WPAS_DBUS_NEW_IFACE_INTERFACE,
2577 (WPADBusMethodHandler) &wpas_dbus_handler_signal_poll,
2579 { "args", "a{sv}", ARG_OUT },
2583 { "Disconnect", WPAS_DBUS_NEW_IFACE_INTERFACE,
2584 (WPADBusMethodHandler) &wpas_dbus_handler_disconnect,
2589 { "AddNetwork", WPAS_DBUS_NEW_IFACE_INTERFACE,
2590 (WPADBusMethodHandler) &wpas_dbus_handler_add_network,
2592 { "args", "a{sv}", ARG_IN },
2593 { "path", "o", ARG_OUT },
2597 { "Reassociate", WPAS_DBUS_NEW_IFACE_INTERFACE,
2598 (WPADBusMethodHandler) &wpas_dbus_handler_reassociate,
2603 { "Reattach", WPAS_DBUS_NEW_IFACE_INTERFACE,
2604 (WPADBusMethodHandler) &wpas_dbus_handler_reattach,
2609 { "RemoveNetwork", WPAS_DBUS_NEW_IFACE_INTERFACE,
2610 (WPADBusMethodHandler) &wpas_dbus_handler_remove_network,
2612 { "path", "o", ARG_IN },
2616 { "RemoveAllNetworks", WPAS_DBUS_NEW_IFACE_INTERFACE,
2617 (WPADBusMethodHandler) &wpas_dbus_handler_remove_all_networks,
2622 { "SelectNetwork", WPAS_DBUS_NEW_IFACE_INTERFACE,
2623 (WPADBusMethodHandler) &wpas_dbus_handler_select_network,
2625 { "path", "o", ARG_IN },
2629 { "NetworkReply", WPAS_DBUS_NEW_IFACE_INTERFACE,
2630 (WPADBusMethodHandler) &wpas_dbus_handler_network_reply,
2632 { "path", "o", ARG_IN },
2633 { "field", "s", ARG_IN },
2634 { "value", "s", ARG_IN },
2638 #ifndef CONFIG_NO_CONFIG_BLOBS
2639 { "AddBlob", WPAS_DBUS_NEW_IFACE_INTERFACE,
2640 (WPADBusMethodHandler) &wpas_dbus_handler_add_blob,
2642 { "name", "s", ARG_IN },
2643 { "data", "ay", ARG_IN },
2647 { "GetBlob", WPAS_DBUS_NEW_IFACE_INTERFACE,
2648 (WPADBusMethodHandler) &wpas_dbus_handler_get_blob,
2650 { "name", "s", ARG_IN },
2651 { "data", "ay", ARG_OUT },
2655 { "RemoveBlob", WPAS_DBUS_NEW_IFACE_INTERFACE,
2656 (WPADBusMethodHandler) &wpas_dbus_handler_remove_blob,
2658 { "name", "s", ARG_IN },
2662 #endif /* CONFIG_NO_CONFIG_BLOBS */
2663 { "SetPKCS11EngineAndModulePath", WPAS_DBUS_NEW_IFACE_INTERFACE,
2664 (WPADBusMethodHandler)
2665 &wpas_dbus_handler_set_pkcs11_engine_and_module_path,
2667 { "pkcs11_engine_path", "s", ARG_IN },
2668 { "pkcs11_module_path", "s", ARG_IN },
2673 { "Start", WPAS_DBUS_NEW_IFACE_WPS,
2674 (WPADBusMethodHandler) &wpas_dbus_handler_wps_start,
2676 { "args", "a{sv}", ARG_IN },
2677 { "output", "a{sv}", ARG_OUT },
2681 #endif /* CONFIG_WPS */
2683 { "Find", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
2684 (WPADBusMethodHandler)wpas_dbus_handler_p2p_find,
2686 { "args", "a{sv}", ARG_IN },
2690 { "StopFind", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
2691 (WPADBusMethodHandler)wpas_dbus_handler_p2p_stop_find,
2696 { "Listen", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
2697 (WPADBusMethodHandler)wpas_dbus_handler_p2p_listen,
2699 { "timeout", "i", ARG_IN },
2703 { "ExtendedListen", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
2704 (WPADBusMethodHandler)wpas_dbus_handler_p2p_extendedlisten,
2706 { "args", "a{sv}", ARG_IN },
2710 { "PresenceRequest", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
2711 (WPADBusMethodHandler)wpas_dbus_handler_p2p_presence_request,
2713 { "args", "a{sv}", ARG_IN },
2717 { "ProvisionDiscoveryRequest", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
2718 (WPADBusMethodHandler)wpas_dbus_handler_p2p_prov_disc_req,
2720 { "peer", "o", ARG_IN },
2721 { "config_method", "s", ARG_IN },
2725 { "Connect", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
2726 (WPADBusMethodHandler)wpas_dbus_handler_p2p_connect,
2728 { "args", "a{sv}", ARG_IN },
2729 { "generated_pin", "s", ARG_OUT },
2733 { "GroupAdd", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
2734 (WPADBusMethodHandler)wpas_dbus_handler_p2p_group_add,
2736 { "args", "a{sv}", ARG_IN },
2740 { "Invite", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
2741 (WPADBusMethodHandler)wpas_dbus_handler_p2p_invite,
2743 { "args", "a{sv}", ARG_IN },
2747 { "Disconnect", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
2748 (WPADBusMethodHandler)wpas_dbus_handler_p2p_disconnect,
2753 { "RejectPeer", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
2754 (WPADBusMethodHandler)wpas_dbus_handler_p2p_rejectpeer,
2756 { "peer", "o", ARG_IN },
2760 { "Flush", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
2761 (WPADBusMethodHandler)wpas_dbus_handler_p2p_flush,
2766 { "AddService", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
2767 (WPADBusMethodHandler)wpas_dbus_handler_p2p_add_service,
2769 { "args", "a{sv}", ARG_IN },
2773 { "DeleteService", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
2774 (WPADBusMethodHandler)wpas_dbus_handler_p2p_delete_service,
2776 { "args", "a{sv}", ARG_IN },
2780 { "FlushService", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
2781 (WPADBusMethodHandler)wpas_dbus_handler_p2p_flush_service,
2786 { "ServiceDiscoveryRequest", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
2787 (WPADBusMethodHandler)wpas_dbus_handler_p2p_service_sd_req,
2789 { "args", "a{sv}", ARG_IN },
2790 { "ref", "t", ARG_OUT },
2794 { "ServiceDiscoveryResponse", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
2795 (WPADBusMethodHandler)wpas_dbus_handler_p2p_service_sd_res,
2797 { "args", "a{sv}", ARG_IN },
2801 { "ServiceDiscoveryCancelRequest", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
2802 (WPADBusMethodHandler)wpas_dbus_handler_p2p_service_sd_cancel_req,
2804 { "args", "t", ARG_IN },
2808 { "ServiceUpdate", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
2809 (WPADBusMethodHandler)wpas_dbus_handler_p2p_service_update,
2814 { "ServiceDiscoveryExternal", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
2815 (WPADBusMethodHandler)wpas_dbus_handler_p2p_serv_disc_external,
2817 { "arg", "i", ARG_IN },
2821 { "AddPersistentGroup", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
2822 (WPADBusMethodHandler) wpas_dbus_handler_add_persistent_group,
2824 { "args", "a{sv}", ARG_IN },
2825 { "path", "o", ARG_OUT },
2829 { "RemovePersistentGroup", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
2830 (WPADBusMethodHandler) wpas_dbus_handler_remove_persistent_group,
2832 { "path", "o", ARG_IN },
2836 { "RemoveAllPersistentGroups", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
2837 (WPADBusMethodHandler)
2838 wpas_dbus_handler_remove_all_persistent_groups,
2843 #endif /* CONFIG_P2P */
2844 { "FlushBSS", WPAS_DBUS_NEW_IFACE_INTERFACE,
2845 (WPADBusMethodHandler) &wpas_dbus_handler_flush_bss,
2847 { "age", "u", ARG_IN },
2852 { "SubscribeProbeReq", WPAS_DBUS_NEW_IFACE_INTERFACE,
2853 (WPADBusMethodHandler) wpas_dbus_handler_subscribe_preq,
2858 { "UnsubscribeProbeReq", WPAS_DBUS_NEW_IFACE_INTERFACE,
2859 (WPADBusMethodHandler) wpas_dbus_handler_unsubscribe_preq,
2864 #endif /* CONFIG_AP */
2865 { "EAPLogoff", WPAS_DBUS_NEW_IFACE_INTERFACE,
2866 (WPADBusMethodHandler) &wpas_dbus_handler_eap_logoff,
2871 { "EAPLogon", WPAS_DBUS_NEW_IFACE_INTERFACE,
2872 (WPADBusMethodHandler) &wpas_dbus_handler_eap_logon,
2877 #ifdef CONFIG_AUTOSCAN
2878 { "AutoScan", WPAS_DBUS_NEW_IFACE_INTERFACE,
2879 (WPADBusMethodHandler) &wpas_dbus_handler_autoscan,
2881 { "arg", "s", ARG_IN },
2885 #endif /* CONFIG_AUTOSCAN */
2887 { "TDLSDiscover", WPAS_DBUS_NEW_IFACE_INTERFACE,
2888 (WPADBusMethodHandler) wpas_dbus_handler_tdls_discover,
2890 { "peer_address", "s", ARG_IN },
2894 { "TDLSSetup", WPAS_DBUS_NEW_IFACE_INTERFACE,
2895 (WPADBusMethodHandler) wpas_dbus_handler_tdls_setup,
2897 { "peer_address", "s", ARG_IN },
2901 { "TDLSStatus", WPAS_DBUS_NEW_IFACE_INTERFACE,
2902 (WPADBusMethodHandler) wpas_dbus_handler_tdls_status,
2904 { "peer_address", "s", ARG_IN },
2905 { "status", "s", ARG_OUT },
2909 { "TDLSTeardown", WPAS_DBUS_NEW_IFACE_INTERFACE,
2910 (WPADBusMethodHandler) wpas_dbus_handler_tdls_teardown,
2912 { "peer_address", "s", ARG_IN },
2916 #endif /* CONFIG_TDLS */
2917 { NULL, NULL, NULL, { END_ARGS } }
2920 static const struct wpa_dbus_property_desc wpas_dbus_interface_properties[] = {
2921 { "Capabilities", WPAS_DBUS_NEW_IFACE_INTERFACE, "a{sv}",
2922 wpas_dbus_getter_capabilities,
2925 { "State", WPAS_DBUS_NEW_IFACE_INTERFACE, "s",
2926 wpas_dbus_getter_state,
2929 { "Scanning", WPAS_DBUS_NEW_IFACE_INTERFACE, "b",
2930 wpas_dbus_getter_scanning,
2933 { "ApScan", WPAS_DBUS_NEW_IFACE_INTERFACE, "u",
2934 wpas_dbus_getter_ap_scan,
2935 wpas_dbus_setter_ap_scan
2937 { "BSSExpireAge", WPAS_DBUS_NEW_IFACE_INTERFACE, "u",
2938 wpas_dbus_getter_bss_expire_age,
2939 wpas_dbus_setter_bss_expire_age
2941 { "BSSExpireCount", WPAS_DBUS_NEW_IFACE_INTERFACE, "u",
2942 wpas_dbus_getter_bss_expire_count,
2943 wpas_dbus_setter_bss_expire_count
2945 { "Country", WPAS_DBUS_NEW_IFACE_INTERFACE, "s",
2946 wpas_dbus_getter_country,
2947 wpas_dbus_setter_country
2949 { "Ifname", WPAS_DBUS_NEW_IFACE_INTERFACE, "s",
2950 wpas_dbus_getter_ifname,
2953 { "Driver", WPAS_DBUS_NEW_IFACE_INTERFACE, "s",
2954 wpas_dbus_getter_driver,
2957 { "BridgeIfname", WPAS_DBUS_NEW_IFACE_INTERFACE, "s",
2958 wpas_dbus_getter_bridge_ifname,
2961 { "CurrentBSS", WPAS_DBUS_NEW_IFACE_INTERFACE, "o",
2962 wpas_dbus_getter_current_bss,
2965 { "CurrentNetwork", WPAS_DBUS_NEW_IFACE_INTERFACE, "o",
2966 wpas_dbus_getter_current_network,
2969 { "CurrentAuthMode", WPAS_DBUS_NEW_IFACE_INTERFACE, "s",
2970 wpas_dbus_getter_current_auth_mode,
2973 { "Blobs", WPAS_DBUS_NEW_IFACE_INTERFACE, "a{say}",
2974 wpas_dbus_getter_blobs,
2977 { "BSSs", WPAS_DBUS_NEW_IFACE_INTERFACE, "ao",
2978 wpas_dbus_getter_bsss,
2981 { "Networks", WPAS_DBUS_NEW_IFACE_INTERFACE, "ao",
2982 wpas_dbus_getter_networks,
2985 { "FastReauth", WPAS_DBUS_NEW_IFACE_INTERFACE, "b",
2986 wpas_dbus_getter_fast_reauth,
2987 wpas_dbus_setter_fast_reauth
2989 { "ScanInterval", WPAS_DBUS_NEW_IFACE_INTERFACE, "i",
2990 wpas_dbus_getter_scan_interval,
2991 wpas_dbus_setter_scan_interval
2993 { "PKCS11EnginePath", WPAS_DBUS_NEW_IFACE_INTERFACE, "s",
2994 wpas_dbus_getter_pkcs11_engine_path,
2997 { "PKCS11ModulePath", WPAS_DBUS_NEW_IFACE_INTERFACE, "s",
2998 wpas_dbus_getter_pkcs11_module_path,
3002 { "ProcessCredentials", WPAS_DBUS_NEW_IFACE_WPS, "b",
3003 wpas_dbus_getter_process_credentials,
3004 wpas_dbus_setter_process_credentials
3006 { "ConfigMethods", WPAS_DBUS_NEW_IFACE_WPS, "s",
3007 wpas_dbus_getter_config_methods,
3008 wpas_dbus_setter_config_methods
3010 #endif /* CONFIG_WPS */
3012 { "P2PDeviceConfig", WPAS_DBUS_NEW_IFACE_P2PDEVICE, "a{sv}",
3013 wpas_dbus_getter_p2p_device_config,
3014 wpas_dbus_setter_p2p_device_config
3016 { "Peers", WPAS_DBUS_NEW_IFACE_P2PDEVICE, "ao",
3017 wpas_dbus_getter_p2p_peers,
3020 { "Role", WPAS_DBUS_NEW_IFACE_P2PDEVICE, "s",
3021 wpas_dbus_getter_p2p_role,
3024 { "Group", WPAS_DBUS_NEW_IFACE_P2PDEVICE, "o",
3025 wpas_dbus_getter_p2p_group,
3028 { "PeerGO", WPAS_DBUS_NEW_IFACE_P2PDEVICE, "o",
3029 wpas_dbus_getter_p2p_peergo,
3032 { "PersistentGroups", WPAS_DBUS_NEW_IFACE_P2PDEVICE, "ao",
3033 wpas_dbus_getter_persistent_groups,
3036 #endif /* CONFIG_P2P */
3037 { "DisconnectReason", WPAS_DBUS_NEW_IFACE_INTERFACE, "i",
3038 wpas_dbus_getter_disconnect_reason,
3041 { NULL, NULL, NULL, NULL, NULL }
3044 static const struct wpa_dbus_signal_desc wpas_dbus_interface_signals[] = {
3045 { "ScanDone", WPAS_DBUS_NEW_IFACE_INTERFACE,
3047 { "success", "b", ARG_OUT },
3051 { "BSSAdded", WPAS_DBUS_NEW_IFACE_INTERFACE,
3053 { "path", "o", ARG_OUT },
3054 { "properties", "a{sv}", ARG_OUT },
3058 { "BSSRemoved", WPAS_DBUS_NEW_IFACE_INTERFACE,
3060 { "path", "o", ARG_OUT },
3064 { "BlobAdded", WPAS_DBUS_NEW_IFACE_INTERFACE,
3066 { "name", "s", ARG_OUT },
3070 { "BlobRemoved", WPAS_DBUS_NEW_IFACE_INTERFACE,
3072 { "name", "s", ARG_OUT },
3076 { "NetworkAdded", WPAS_DBUS_NEW_IFACE_INTERFACE,
3078 { "path", "o", ARG_OUT },
3079 { "properties", "a{sv}", ARG_OUT },
3083 { "NetworkRemoved", WPAS_DBUS_NEW_IFACE_INTERFACE,
3085 { "path", "o", ARG_OUT },
3089 { "NetworkSelected", WPAS_DBUS_NEW_IFACE_INTERFACE,
3091 { "path", "o", ARG_OUT },
3095 /* Deprecated: use org.freedesktop.DBus.Properties.PropertiesChanged */
3096 { "PropertiesChanged", WPAS_DBUS_NEW_IFACE_INTERFACE,
3098 { "properties", "a{sv}", ARG_OUT },
3103 { "Event", WPAS_DBUS_NEW_IFACE_WPS,
3105 { "name", "s", ARG_OUT },
3106 { "args", "a{sv}", ARG_OUT },
3110 { "Credentials", WPAS_DBUS_NEW_IFACE_WPS,
3112 { "credentials", "a{sv}", ARG_OUT },
3116 /* Deprecated: use org.freedesktop.DBus.Properties.PropertiesChanged */
3117 { "PropertiesChanged", WPAS_DBUS_NEW_IFACE_WPS,
3119 { "properties", "a{sv}", ARG_OUT },
3123 #endif /* CONFIG_WPS */
3125 { "P2PStateChanged", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
3127 { "states", "a{ss}", ARG_OUT },
3131 { "DeviceFound", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
3133 { "path", "o", ARG_OUT },
3137 { "DeviceLost", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
3139 { "path", "o", ARG_OUT },
3143 { "ProvisionDiscoveryRequestDisplayPin", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
3145 { "peer_object", "o", ARG_OUT },
3146 { "pin", "s", ARG_OUT },
3150 { "ProvisionDiscoveryResponseDisplayPin", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
3152 { "peer_object", "o", ARG_OUT },
3153 { "pin", "s", ARG_OUT },
3157 { "ProvisionDiscoveryRequestEnterPin", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
3159 { "peer_object", "o", ARG_OUT },
3163 { "ProvisionDiscoveryResponseEnterPin", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
3165 { "peer_object", "o", ARG_OUT },
3169 { "ProvisionDiscoveryPBCRequest", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
3171 { "peer_object", "o", ARG_OUT },
3175 { "ProvisionDiscoveryPBCResponse", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
3177 { "peer_object", "o", ARG_OUT },
3181 { "ProvisionDiscoveryFailure", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
3183 { "peer_object", "o", ARG_OUT },
3184 { "status", "i", ARG_OUT },
3188 { "GroupStarted", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
3190 { "properties", "a{sv}", ARG_OUT },
3194 { "GONegotiationSuccess", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
3196 { "properties", "a{sv}", ARG_OUT },
3200 { "GONegotiationFailure", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
3202 { "properties", "a{sv}", ARG_OUT },
3206 { "GONegotiationRequest", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
3208 { "path", "o", ARG_OUT },
3209 { "dev_passwd_id", "i", ARG_OUT },
3213 { "InvitationResult", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
3215 { "invite_result", "a{sv}", ARG_OUT },
3219 { "GroupFinished", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
3221 { "properties", "a{sv}", ARG_OUT },
3225 { "ServiceDiscoveryRequest", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
3227 { "sd_request", "a{sv}", ARG_OUT },
3231 { "ServiceDiscoveryResponse", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
3233 { "sd_response", "a{sv}", ARG_OUT },
3237 { "PersistentGroupAdded", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
3239 { "path", "o", ARG_OUT },
3240 { "properties", "a{sv}", ARG_OUT },
3244 { "PersistentGroupRemoved", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
3246 { "path", "o", ARG_OUT },
3250 { "WpsFailed", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
3252 { "name", "s", ARG_OUT },
3253 { "args", "a{sv}", ARG_OUT },
3257 #endif /* CONFIG_P2P */
3259 { "ProbeRequest", WPAS_DBUS_NEW_IFACE_INTERFACE,
3261 { "args", "a{sv}", ARG_OUT },
3265 #endif /* CONFIG_AP */
3266 { "Certification", WPAS_DBUS_NEW_IFACE_INTERFACE,
3268 { "certification", "a{sv}", ARG_OUT },
3272 { "EAP", WPAS_DBUS_NEW_IFACE_INTERFACE,
3274 { "status", "s", ARG_OUT },
3275 { "parameter", "s", ARG_OUT },
3279 { "StaAuthorized", WPAS_DBUS_NEW_IFACE_INTERFACE,
3281 { "name", "s", ARG_OUT },
3285 { "StaDeauthorized", WPAS_DBUS_NEW_IFACE_INTERFACE,
3287 { "name", "s", ARG_OUT },
3291 { NULL, NULL, { END_ARGS } }
3295 int wpas_dbus_register_interface(struct wpa_supplicant *wpa_s)
3298 struct wpa_dbus_object_desc *obj_desc = NULL;
3299 struct wpas_dbus_priv *ctrl_iface = wpa_s->global->dbus;
3302 /* Do nothing if the control interface is not turned on */
3303 if (ctrl_iface == NULL)
3306 /* Create and set the interface's object path */
3307 wpa_s->dbus_new_path = os_zalloc(WPAS_DBUS_OBJECT_PATH_MAX);
3308 if (wpa_s->dbus_new_path == NULL)
3310 next = ctrl_iface->next_objid++;
3311 os_snprintf(wpa_s->dbus_new_path, WPAS_DBUS_OBJECT_PATH_MAX,
3312 WPAS_DBUS_NEW_PATH_INTERFACES "/%u",
3315 obj_desc = os_zalloc(sizeof(struct wpa_dbus_object_desc));
3317 wpa_printf(MSG_ERROR, "Not enough memory "
3318 "to create object description");
3322 wpas_dbus_register(obj_desc, wpa_s, NULL, wpas_dbus_interface_methods,
3323 wpas_dbus_interface_properties,
3324 wpas_dbus_interface_signals);
3326 wpa_printf(MSG_DEBUG, "dbus: Register interface object '%s'",
3327 wpa_s->dbus_new_path);
3328 if (wpa_dbus_register_object_per_iface(ctrl_iface,
3329 wpa_s->dbus_new_path,
3330 wpa_s->ifname, obj_desc))
3333 wpas_dbus_signal_interface_added(wpa_s);
3338 os_free(wpa_s->dbus_new_path);
3339 wpa_s->dbus_new_path = NULL;
3340 free_dbus_object_desc(obj_desc);
3345 int wpas_dbus_unregister_interface(struct wpa_supplicant *wpa_s)
3347 struct wpas_dbus_priv *ctrl_iface;
3349 /* Do nothing if the control interface is not turned on */
3350 if (wpa_s == NULL || wpa_s->global == NULL)
3352 ctrl_iface = wpa_s->global->dbus;
3353 if (ctrl_iface == NULL)
3356 wpa_printf(MSG_DEBUG, "dbus: Unregister interface object '%s'",
3357 wpa_s->dbus_new_path);
3360 if (wpa_s->preq_notify_peer) {
3361 wpas_dbus_unsubscribe_noc(ctrl_iface);
3362 os_free(wpa_s->preq_notify_peer);
3363 wpa_s->preq_notify_peer = NULL;
3365 #endif /* CONFIG_AP */
3367 if (wpa_dbus_unregister_object_per_iface(ctrl_iface,
3368 wpa_s->dbus_new_path))
3371 wpas_dbus_signal_interface_removed(wpa_s);
3373 os_free(wpa_s->dbus_new_path);
3374 wpa_s->dbus_new_path = NULL;
3381 static const struct wpa_dbus_property_desc wpas_dbus_p2p_peer_properties[] = {
3382 { "DeviceName", WPAS_DBUS_NEW_IFACE_P2P_PEER, "s",
3383 wpas_dbus_getter_p2p_peer_device_name,
3386 { "PrimaryDeviceType", WPAS_DBUS_NEW_IFACE_P2P_PEER, "ay",
3387 wpas_dbus_getter_p2p_peer_primary_device_type,
3390 { "config_method", WPAS_DBUS_NEW_IFACE_P2P_PEER, "q",
3391 wpas_dbus_getter_p2p_peer_config_method,
3394 { "level", WPAS_DBUS_NEW_IFACE_P2P_PEER, "i",
3395 wpas_dbus_getter_p2p_peer_level,
3398 { "devicecapability", WPAS_DBUS_NEW_IFACE_P2P_PEER, "y",
3399 wpas_dbus_getter_p2p_peer_device_capability,
3402 { "groupcapability", WPAS_DBUS_NEW_IFACE_P2P_PEER, "y",
3403 wpas_dbus_getter_p2p_peer_group_capability,
3406 { "SecondaryDeviceTypes", WPAS_DBUS_NEW_IFACE_P2P_PEER, "aay",
3407 wpas_dbus_getter_p2p_peer_secondary_device_types,
3410 { "VendorExtension", WPAS_DBUS_NEW_IFACE_P2P_PEER, "aay",
3411 wpas_dbus_getter_p2p_peer_vendor_extension,
3414 { "IEs", WPAS_DBUS_NEW_IFACE_P2P_PEER, "ay",
3415 wpas_dbus_getter_p2p_peer_ies,
3418 { "DeviceAddress", WPAS_DBUS_NEW_IFACE_P2P_PEER, "ay",
3419 wpas_dbus_getter_p2p_peer_device_address,
3422 { "Groups", WPAS_DBUS_NEW_IFACE_P2P_PEER, "ao",
3423 wpas_dbus_getter_p2p_peer_groups,
3426 { NULL, NULL, NULL, NULL, NULL }
3429 static const struct wpa_dbus_signal_desc wpas_dbus_p2p_peer_signals[] = {
3430 /* Deprecated: use org.freedesktop.DBus.Properties.PropertiesChanged */
3431 { "PropertiesChanged", WPAS_DBUS_NEW_IFACE_P2P_PEER,
3433 { "properties", "a{sv}", ARG_OUT },
3437 { NULL, NULL, { END_ARGS } }
3441 * wpas_dbus_signal_peer - Send a peer related event signal
3442 * @wpa_s: %wpa_supplicant network interface data
3443 * @dev: peer device object
3444 * @interface: name of the interface emitting this signal.
3445 * In case of peer objects, it would be emitted by either
3446 * the "interface object" or by "peer objects"
3447 * @sig_name: signal name - DeviceFound
3449 * Notify listeners about event related with newly found p2p peer device
3451 static void wpas_dbus_signal_peer(struct wpa_supplicant *wpa_s,
3452 const u8 *dev_addr, const char *interface,
3453 const char *sig_name)
3455 struct wpas_dbus_priv *iface;
3457 DBusMessageIter iter;
3458 char peer_obj_path[WPAS_DBUS_OBJECT_PATH_MAX], *path;
3460 if (wpa_s->p2p_mgmt)
3461 wpa_s = wpa_s->parent;
3463 iface = wpa_s->global->dbus;
3465 /* Do nothing if the control interface is not turned on */
3469 os_snprintf(peer_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
3470 "%s/" WPAS_DBUS_NEW_P2P_PEERS_PART "/" COMPACT_MACSTR,
3471 wpa_s->dbus_new_path, MAC2STR(dev_addr));
3473 msg = dbus_message_new_signal(wpa_s->dbus_new_path, interface,
3478 dbus_message_iter_init_append(msg, &iter);
3479 path = peer_obj_path;
3480 if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_OBJECT_PATH,
3484 dbus_connection_send(iface->con, msg, NULL);
3486 dbus_message_unref(msg);
3490 wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
3491 dbus_message_unref(msg);
3496 * wpas_dbus_signal_peer_found - Send a peer found signal
3497 * @wpa_s: %wpa_supplicant network interface data
3498 * @dev: peer device object
3500 * Notify listeners about find a p2p peer device found
3502 void wpas_dbus_signal_peer_device_found(struct wpa_supplicant *wpa_s,
3505 wpas_dbus_signal_peer(wpa_s, dev_addr,
3506 WPAS_DBUS_NEW_IFACE_P2PDEVICE,
3511 * wpas_dbus_signal_peer_lost - Send a peer lost signal
3512 * @wpa_s: %wpa_supplicant network interface data
3513 * @dev: peer device object
3515 * Notify listeners about lost a p2p peer device
3517 void wpas_dbus_signal_peer_device_lost(struct wpa_supplicant *wpa_s,
3520 wpas_dbus_signal_peer(wpa_s, dev_addr,
3521 WPAS_DBUS_NEW_IFACE_P2PDEVICE,
3526 * wpas_dbus_register_peer - Register a discovered peer object with dbus
3527 * @wpa_s: wpa_supplicant interface structure
3528 * @ssid: network configuration data
3529 * Returns: 0 on success, -1 on failure
3531 * Registers network representing object with dbus
3533 int wpas_dbus_register_peer(struct wpa_supplicant *wpa_s, const u8 *dev_addr)
3535 struct wpas_dbus_priv *ctrl_iface;
3536 struct wpa_dbus_object_desc *obj_desc;
3537 struct peer_handler_args *arg;
3538 char peer_obj_path[WPAS_DBUS_OBJECT_PATH_MAX];
3540 /* Do nothing if the control interface is not turned on */
3541 if (wpa_s == NULL || wpa_s->global == NULL)
3544 ctrl_iface = wpa_s->global->dbus;
3545 if (ctrl_iface == NULL)
3548 if (wpa_s->p2p_mgmt)
3549 wpa_s = wpa_s->parent;
3551 os_snprintf(peer_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
3552 "%s/" WPAS_DBUS_NEW_P2P_PEERS_PART "/" COMPACT_MACSTR,
3553 wpa_s->dbus_new_path, MAC2STR(dev_addr));
3555 wpa_printf(MSG_INFO, "dbus: Register peer object '%s'",
3557 obj_desc = os_zalloc(sizeof(struct wpa_dbus_object_desc));
3559 wpa_printf(MSG_ERROR, "Not enough memory "
3560 "to create object description");
3564 /* allocate memory for handlers arguments */
3565 arg = os_zalloc(sizeof(struct peer_handler_args));
3567 wpa_printf(MSG_ERROR, "Not enough memory "
3568 "to create arguments for method");
3573 os_memcpy(arg->p2p_device_addr, dev_addr, ETH_ALEN);
3575 wpas_dbus_register(obj_desc, arg, wpa_dbus_free,
3577 wpas_dbus_p2p_peer_properties,
3578 wpas_dbus_p2p_peer_signals);
3580 if (wpa_dbus_register_object_per_iface(ctrl_iface, peer_obj_path,
3581 wpa_s->ifname, obj_desc))
3587 free_dbus_object_desc(obj_desc);
3592 * wpas_dbus_unregister_peer - Unregister a peer object with dbus
3593 * @wpa_s: wpa_supplicant interface structure
3594 * @dev_addr: p2p device addr
3595 * Returns: 0 on success, -1 on failure
3597 * Registers network representing object with dbus
3599 int wpas_dbus_unregister_peer(struct wpa_supplicant *wpa_s,
3602 struct wpas_dbus_priv *ctrl_iface;
3603 char peer_obj_path[WPAS_DBUS_OBJECT_PATH_MAX];
3606 /* Do nothing if the control interface is not turned on */
3607 if (wpa_s == NULL || wpa_s->global == NULL ||
3608 wpa_s->dbus_new_path == NULL)
3611 if (wpa_s->p2p_mgmt)
3612 wpa_s = wpa_s->parent;
3614 ctrl_iface = wpa_s->global->dbus;
3615 if (ctrl_iface == NULL)
3618 os_snprintf(peer_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
3619 "%s/" WPAS_DBUS_NEW_P2P_PEERS_PART "/" COMPACT_MACSTR,
3620 wpa_s->dbus_new_path, MAC2STR(dev_addr));
3622 wpa_printf(MSG_INFO, "dbus: Unregister peer object '%s'",
3624 ret = wpa_dbus_unregister_object_per_iface(ctrl_iface, peer_obj_path);
3630 void wpas_dbus_signal_peer_groups_changed(struct wpa_supplicant *wpa_s,
3633 char peer_obj_path[WPAS_DBUS_OBJECT_PATH_MAX];
3635 if (wpa_s->p2p_mgmt)
3636 wpa_s = wpa_s->parent;
3638 os_snprintf(peer_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
3639 "%s/" WPAS_DBUS_NEW_P2P_PEERS_PART "/" COMPACT_MACSTR,
3640 wpa_s->dbus_new_path, MAC2STR(dev_addr));
3642 wpa_dbus_mark_property_changed(wpa_s->global->dbus, peer_obj_path,
3643 WPAS_DBUS_NEW_IFACE_P2P_PEER, "Groups");
3647 static const struct wpa_dbus_property_desc wpas_dbus_p2p_group_properties[] = {
3648 { "Members", WPAS_DBUS_NEW_IFACE_P2P_GROUP, "ao",
3649 wpas_dbus_getter_p2p_group_members,
3652 { "Group", WPAS_DBUS_NEW_IFACE_P2P_GROUP, "o",
3653 wpas_dbus_getter_p2p_group,
3656 { "Role", WPAS_DBUS_NEW_IFACE_P2P_GROUP, "s",
3657 wpas_dbus_getter_p2p_role,
3660 { "SSID", WPAS_DBUS_NEW_IFACE_P2P_GROUP, "ay",
3661 wpas_dbus_getter_p2p_group_ssid,
3664 { "BSSID", WPAS_DBUS_NEW_IFACE_P2P_GROUP, "ay",
3665 wpas_dbus_getter_p2p_group_bssid,
3668 { "Frequency", WPAS_DBUS_NEW_IFACE_P2P_GROUP, "q",
3669 wpas_dbus_getter_p2p_group_frequency,
3672 { "Passphrase", WPAS_DBUS_NEW_IFACE_P2P_GROUP, "s",
3673 wpas_dbus_getter_p2p_group_passphrase,
3676 { "PSK", WPAS_DBUS_NEW_IFACE_P2P_GROUP, "ay",
3677 wpas_dbus_getter_p2p_group_psk,
3680 { "WPSVendorExtensions", WPAS_DBUS_NEW_IFACE_P2P_GROUP, "aay",
3681 wpas_dbus_getter_p2p_group_vendor_ext,
3682 wpas_dbus_setter_p2p_group_vendor_ext
3684 { NULL, NULL, NULL, NULL, NULL }
3687 static const struct wpa_dbus_signal_desc wpas_dbus_p2p_group_signals[] = {
3688 { "PeerJoined", WPAS_DBUS_NEW_IFACE_P2P_GROUP,
3690 { "peer", "o", ARG_OUT },
3694 { "PeerDisconnected", WPAS_DBUS_NEW_IFACE_P2P_GROUP,
3696 { "peer", "o", ARG_OUT },
3700 { NULL, NULL, { END_ARGS } }
3704 * wpas_dbus_register_p2p_group - Register a p2p group object with dbus
3705 * @wpa_s: wpa_supplicant interface structure
3706 * @ssid: SSID struct
3707 * Returns: 0 on success, -1 on failure
3709 * Registers p2p group representing object with dbus
3711 void wpas_dbus_register_p2p_group(struct wpa_supplicant *wpa_s,
3712 struct wpa_ssid *ssid)
3714 struct wpas_dbus_priv *ctrl_iface;
3715 struct wpa_dbus_object_desc *obj_desc;
3716 char group_obj_path[WPAS_DBUS_OBJECT_PATH_MAX];
3718 /* Do nothing if the control interface is not turned on */
3719 if (wpa_s == NULL || wpa_s->global == NULL)
3722 ctrl_iface = wpa_s->global->dbus;
3723 if (ctrl_iface == NULL)
3726 if (wpa_s->dbus_groupobj_path) {
3727 wpa_printf(MSG_INFO, "%s: Group object '%s' already exists",
3728 __func__, wpa_s->dbus_groupobj_path);
3732 if (wpas_dbus_get_group_obj_path(wpa_s, ssid, group_obj_path) < 0)
3735 wpa_s->dbus_groupobj_path = os_strdup(group_obj_path);
3736 if (wpa_s->dbus_groupobj_path == NULL)
3739 wpa_printf(MSG_INFO, "dbus: Register group object '%s'",
3741 obj_desc = os_zalloc(sizeof(struct wpa_dbus_object_desc));
3743 wpa_printf(MSG_ERROR, "Not enough memory "
3744 "to create object description");
3748 wpas_dbus_register(obj_desc, wpa_s, NULL, NULL,
3749 wpas_dbus_p2p_group_properties,
3750 wpas_dbus_p2p_group_signals);
3752 if (wpa_dbus_register_object_per_iface(ctrl_iface, group_obj_path,
3753 wpa_s->ifname, obj_desc))
3759 if (wpa_s->dbus_groupobj_path) {
3760 os_free(wpa_s->dbus_groupobj_path);
3761 wpa_s->dbus_groupobj_path = NULL;
3764 free_dbus_object_desc(obj_desc);
3768 * wpas_dbus_unregister_p2p_group - Unregister a p2p group object from dbus
3769 * @wpa_s: wpa_supplicant interface structure
3770 * @ssid: network name of the p2p group started
3772 void wpas_dbus_unregister_p2p_group(struct wpa_supplicant *wpa_s,
3773 const struct wpa_ssid *ssid)
3775 struct wpas_dbus_priv *ctrl_iface;
3777 /* Do nothing if the control interface is not turned on */
3778 if (wpa_s == NULL || wpa_s->global == NULL)
3781 if (wpa_s->p2p_mgmt)
3782 wpa_s = wpa_s->parent;
3784 ctrl_iface = wpa_s->global->dbus;
3785 if (ctrl_iface == NULL)
3788 if (!wpa_s->dbus_groupobj_path) {
3789 wpa_printf(MSG_DEBUG,
3790 "%s: Group object '%s' already unregistered",
3791 __func__, wpa_s->dbus_groupobj_path);
3795 peer_groups_changed(wpa_s);
3797 wpa_printf(MSG_DEBUG, "dbus: Unregister group object '%s'",
3798 wpa_s->dbus_groupobj_path);
3800 wpa_dbus_unregister_object_per_iface(ctrl_iface,
3801 wpa_s->dbus_groupobj_path);
3803 os_free(wpa_s->dbus_groupobj_path);
3804 wpa_s->dbus_groupobj_path = NULL;
3807 static const struct wpa_dbus_property_desc
3808 wpas_dbus_persistent_group_properties[] = {
3809 { "Properties", WPAS_DBUS_NEW_IFACE_PERSISTENT_GROUP, "a{sv}",
3810 wpas_dbus_getter_persistent_group_properties,
3811 wpas_dbus_setter_persistent_group_properties
3813 { NULL, NULL, NULL, NULL, NULL }
3816 /* No signals intended for persistent group objects */
3819 * wpas_dbus_register_persistent_group - Register a configured(saved)
3820 * persistent group with dbus
3821 * @wpa_s: wpa_supplicant interface structure
3822 * @ssid: persistent group (still represented as a network within wpa)
3823 * configuration data
3824 * Returns: 0 on success, -1 on failure
3826 * Registers a persistent group representing object with dbus.
3828 int wpas_dbus_register_persistent_group(struct wpa_supplicant *wpa_s,
3829 struct wpa_ssid *ssid)
3831 struct wpas_dbus_priv *ctrl_iface;
3832 struct wpa_dbus_object_desc *obj_desc;
3833 struct network_handler_args *arg;
3834 char pgrp_obj_path[WPAS_DBUS_OBJECT_PATH_MAX];
3836 /* Do nothing if the control interface is not turned on */
3837 if (wpa_s == NULL || wpa_s->global == NULL)
3840 /* Make sure ssid is a persistent group */
3841 if (ssid->disabled != 2 && !ssid->p2p_persistent_group)
3842 return -1; /* should we return w/o complaining? */
3844 if (wpa_s->p2p_mgmt)
3845 wpa_s = wpa_s->parent;
3847 ctrl_iface = wpa_s->global->dbus;
3848 if (ctrl_iface == NULL)
3852 * Intentionally not coming up with different numbering scheme
3853 * for persistent groups.
3855 os_snprintf(pgrp_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
3856 "%s/" WPAS_DBUS_NEW_PERSISTENT_GROUPS_PART "/%u",
3857 wpa_s->dbus_new_path, ssid->id);
3859 wpa_printf(MSG_DEBUG, "dbus: Register persistent group object '%s'",
3861 obj_desc = os_zalloc(sizeof(struct wpa_dbus_object_desc));
3863 wpa_printf(MSG_ERROR, "dbus: Not enough memory to create "
3864 "object description");
3869 * Reusing the same context structure as that for networks
3870 * since these are represented using same data structure.
3872 /* allocate memory for handlers arguments */
3873 arg = os_zalloc(sizeof(struct network_handler_args));
3875 wpa_printf(MSG_ERROR, "dbus: Not enough memory to create "
3876 "arguments for method");
3883 wpas_dbus_register(obj_desc, arg, wpa_dbus_free, NULL,
3884 wpas_dbus_persistent_group_properties,
3887 if (wpa_dbus_register_object_per_iface(ctrl_iface, pgrp_obj_path,
3888 wpa_s->ifname, obj_desc))
3891 wpas_dbus_signal_persistent_group_added(wpa_s, ssid->id);
3896 free_dbus_object_desc(obj_desc);
3902 * wpas_dbus_unregister_persistent_group - Unregister a persistent_group
3904 * @wpa_s: wpa_supplicant interface structure
3906 * Returns: 0 on success, -1 on failure
3908 * Unregisters persistent group representing object from dbus
3910 * NOTE: There is a slight issue with the semantics here. While the
3911 * implementation simply means the persistent group is unloaded from memory,
3912 * it should not get interpreted as the group is actually being erased/removed
3913 * from persistent storage as well.
3915 int wpas_dbus_unregister_persistent_group(struct wpa_supplicant *wpa_s,
3918 struct wpas_dbus_priv *ctrl_iface;
3919 char pgrp_obj_path[WPAS_DBUS_OBJECT_PATH_MAX];
3922 /* Do nothing if the control interface is not turned on */
3923 if (wpa_s == NULL || wpa_s->global == NULL ||
3924 wpa_s->dbus_new_path == NULL)
3927 if (wpa_s->p2p_mgmt)
3928 wpa_s = wpa_s->parent;
3930 ctrl_iface = wpa_s->global->dbus;
3931 if (ctrl_iface == NULL)
3934 os_snprintf(pgrp_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
3935 "%s/" WPAS_DBUS_NEW_PERSISTENT_GROUPS_PART "/%u",
3936 wpa_s->dbus_new_path, nid);
3938 wpa_printf(MSG_DEBUG, "dbus: Unregister persistent group object '%s'",
3940 ret = wpa_dbus_unregister_object_per_iface(ctrl_iface, pgrp_obj_path);
3943 wpas_dbus_signal_persistent_group_removed(wpa_s, nid);
3948 #endif /* CONFIG_P2P */