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) ||
153 !wpa_dbus_get_object_properties(
154 iface, wpa_s->dbus_new_path,
155 WPAS_DBUS_NEW_IFACE_INTERFACE, &iter)))
156 wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
158 dbus_connection_send(iface->con, msg, NULL);
159 dbus_message_unref(msg);
164 * wpas_dbus_signal_interface_added - Send a interface created signal
165 * @wpa_s: %wpa_supplicant network interface data
167 * Notify listeners about creating new interface
169 static void wpas_dbus_signal_interface_added(struct wpa_supplicant *wpa_s)
171 wpas_dbus_signal_interface(wpa_s, "InterfaceAdded", TRUE);
176 * wpas_dbus_signal_interface_removed - Send a interface removed signal
177 * @wpa_s: %wpa_supplicant network interface data
179 * Notify listeners about removing interface
181 static void wpas_dbus_signal_interface_removed(struct wpa_supplicant *wpa_s)
183 wpas_dbus_signal_interface(wpa_s, "InterfaceRemoved", FALSE);
189 * wpas_dbus_signal_scan_done - send scan done signal
190 * @wpa_s: %wpa_supplicant network interface data
191 * @success: indicates if scanning succeed or failed
193 * Notify listeners about finishing a scan
195 void wpas_dbus_signal_scan_done(struct wpa_supplicant *wpa_s, int success)
197 struct wpas_dbus_priv *iface;
201 iface = wpa_s->global->dbus;
203 /* Do nothing if the control interface is not turned on */
207 msg = dbus_message_new_signal(wpa_s->dbus_new_path,
208 WPAS_DBUS_NEW_IFACE_INTERFACE,
213 succ = success ? TRUE : FALSE;
214 if (dbus_message_append_args(msg, DBUS_TYPE_BOOLEAN, &succ,
216 dbus_connection_send(iface->con, msg, NULL);
218 wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
219 dbus_message_unref(msg);
224 * wpas_dbus_signal_bss - Send a BSS related event signal
225 * @wpa_s: %wpa_supplicant network interface data
226 * @bss_obj_path: BSS object path
227 * @sig_name: signal name - BSSAdded or BSSRemoved
228 * @properties: Whether to add second argument with object properties
230 * Notify listeners about event related with BSS
232 static void wpas_dbus_signal_bss(struct wpa_supplicant *wpa_s,
233 const char *bss_obj_path,
234 const char *sig_name, int properties)
236 struct wpas_dbus_priv *iface;
238 DBusMessageIter iter;
240 iface = wpa_s->global->dbus;
242 /* Do nothing if the control interface is not turned on */
246 msg = dbus_message_new_signal(wpa_s->dbus_new_path,
247 WPAS_DBUS_NEW_IFACE_INTERFACE,
252 dbus_message_iter_init_append(msg, &iter);
253 if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_OBJECT_PATH,
256 !wpa_dbus_get_object_properties(iface, bss_obj_path,
257 WPAS_DBUS_NEW_IFACE_BSS,
259 wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
261 dbus_connection_send(iface->con, msg, NULL);
262 dbus_message_unref(msg);
267 * wpas_dbus_signal_bss_added - Send a BSS added signal
268 * @wpa_s: %wpa_supplicant network interface data
269 * @bss_obj_path: new BSS object path
271 * Notify listeners about adding new BSS
273 static void wpas_dbus_signal_bss_added(struct wpa_supplicant *wpa_s,
274 const char *bss_obj_path)
276 wpas_dbus_signal_bss(wpa_s, bss_obj_path, "BSSAdded", TRUE);
281 * wpas_dbus_signal_bss_removed - Send a BSS removed signal
282 * @wpa_s: %wpa_supplicant network interface data
283 * @bss_obj_path: BSS object path
285 * Notify listeners about removing BSS
287 static void wpas_dbus_signal_bss_removed(struct wpa_supplicant *wpa_s,
288 const char *bss_obj_path)
290 wpas_dbus_signal_bss(wpa_s, bss_obj_path, "BSSRemoved", FALSE);
295 * wpas_dbus_signal_blob - Send a blob related event signal
296 * @wpa_s: %wpa_supplicant network interface data
298 * @sig_name: signal name - BlobAdded or BlobRemoved
300 * Notify listeners about event related with blob
302 static void wpas_dbus_signal_blob(struct wpa_supplicant *wpa_s,
303 const char *name, const char *sig_name)
305 struct wpas_dbus_priv *iface;
308 iface = wpa_s->global->dbus;
310 /* Do nothing if the control interface is not turned on */
314 msg = dbus_message_new_signal(wpa_s->dbus_new_path,
315 WPAS_DBUS_NEW_IFACE_INTERFACE,
320 if (dbus_message_append_args(msg, DBUS_TYPE_STRING, &name,
322 dbus_connection_send(iface->con, msg, NULL);
324 wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
325 dbus_message_unref(msg);
330 * wpas_dbus_signal_blob_added - Send a blob added signal
331 * @wpa_s: %wpa_supplicant network interface data
334 * Notify listeners about adding a new blob
336 void wpas_dbus_signal_blob_added(struct wpa_supplicant *wpa_s,
339 wpas_dbus_signal_blob(wpa_s, name, "BlobAdded");
344 * wpas_dbus_signal_blob_removed - Send a blob removed signal
345 * @wpa_s: %wpa_supplicant network interface data
348 * Notify listeners about removing blob
350 void wpas_dbus_signal_blob_removed(struct wpa_supplicant *wpa_s,
353 wpas_dbus_signal_blob(wpa_s, name, "BlobRemoved");
358 * wpas_dbus_signal_network - Send a network related event signal
359 * @wpa_s: %wpa_supplicant network interface data
360 * @id: new network id
361 * @sig_name: signal name - NetworkAdded, NetworkRemoved or NetworkSelected
362 * @properties: determines if add second argument with object properties
364 * Notify listeners about event related with configured network
366 static void wpas_dbus_signal_network(struct wpa_supplicant *wpa_s,
367 int id, const char *sig_name,
370 struct wpas_dbus_priv *iface;
372 DBusMessageIter iter;
373 char net_obj_path[WPAS_DBUS_OBJECT_PATH_MAX], *path;
375 iface = wpa_s->global->dbus;
377 /* Do nothing if the control interface is not turned on */
381 os_snprintf(net_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
382 "%s/" WPAS_DBUS_NEW_NETWORKS_PART "/%u",
383 wpa_s->dbus_new_path, id);
385 msg = dbus_message_new_signal(wpa_s->dbus_new_path,
386 WPAS_DBUS_NEW_IFACE_INTERFACE,
391 dbus_message_iter_init_append(msg, &iter);
393 if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_OBJECT_PATH,
396 !wpa_dbus_get_object_properties(
397 iface, net_obj_path, WPAS_DBUS_NEW_IFACE_NETWORK,
399 wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
401 dbus_connection_send(iface->con, msg, NULL);
402 dbus_message_unref(msg);
407 * wpas_dbus_signal_network_added - Send a network added signal
408 * @wpa_s: %wpa_supplicant network interface data
409 * @id: new network id
411 * Notify listeners about adding new network
413 static void wpas_dbus_signal_network_added(struct wpa_supplicant *wpa_s,
416 wpas_dbus_signal_network(wpa_s, id, "NetworkAdded", TRUE);
421 * wpas_dbus_signal_network_removed - Send a network removed signal
422 * @wpa_s: %wpa_supplicant network interface data
425 * Notify listeners about removing a network
427 static void wpas_dbus_signal_network_removed(struct wpa_supplicant *wpa_s,
430 wpas_dbus_signal_network(wpa_s, id, "NetworkRemoved", FALSE);
435 * wpas_dbus_signal_network_selected - Send a network selected signal
436 * @wpa_s: %wpa_supplicant network interface data
439 * Notify listeners about selecting a network
441 void wpas_dbus_signal_network_selected(struct wpa_supplicant *wpa_s, int id)
443 wpas_dbus_signal_network(wpa_s, id, "NetworkSelected", FALSE);
448 * wpas_dbus_signal_network_request - Indicate that additional information
449 * (EAP password, etc.) is required to complete the association to this SSID
450 * @wpa_s: %wpa_supplicant network interface data
451 * @rtype: The specific additional information required
452 * @default_text: Optional description of required information
454 * Request additional information or passwords to complete an association
457 void wpas_dbus_signal_network_request(struct wpa_supplicant *wpa_s,
458 struct wpa_ssid *ssid,
459 enum wpa_ctrl_req_type rtype,
460 const char *default_txt)
462 struct wpas_dbus_priv *iface;
464 DBusMessageIter iter;
465 char net_obj_path[WPAS_DBUS_OBJECT_PATH_MAX];
466 const char *field, *txt = NULL, *net_ptr;
468 iface = wpa_s->global->dbus;
470 /* Do nothing if the control interface is not turned on */
474 field = wpa_supplicant_ctrl_req_to_string(rtype, default_txt, &txt);
478 msg = dbus_message_new_signal(wpa_s->dbus_new_path,
479 WPAS_DBUS_NEW_IFACE_INTERFACE,
484 os_snprintf(net_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
485 "%s/" WPAS_DBUS_NEW_NETWORKS_PART "/%u",
486 wpa_s->dbus_new_path, ssid->id);
487 net_ptr = &net_obj_path[0];
489 dbus_message_iter_init_append(msg, &iter);
490 if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_OBJECT_PATH,
492 !dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &field) ||
493 !dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &txt))
494 wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
496 dbus_connection_send(iface->con, msg, NULL);
497 dbus_message_unref(msg);
502 * wpas_dbus_signal_network_enabled_changed - Signals Enabled property changes
503 * @wpa_s: %wpa_supplicant network interface data
504 * @ssid: configured network which Enabled property has changed
506 * Sends PropertyChanged signals containing new value of Enabled property
507 * for specified network
509 void wpas_dbus_signal_network_enabled_changed(struct wpa_supplicant *wpa_s,
510 struct wpa_ssid *ssid)
513 char path[WPAS_DBUS_OBJECT_PATH_MAX];
514 os_snprintf(path, WPAS_DBUS_OBJECT_PATH_MAX,
515 "%s/" WPAS_DBUS_NEW_NETWORKS_PART "/%d",
516 wpa_s->dbus_new_path, ssid->id);
518 wpa_dbus_mark_property_changed(wpa_s->global->dbus, path,
519 WPAS_DBUS_NEW_IFACE_NETWORK, "Enabled");
526 * wpas_dbus_signal_wps_event_success - Signals Success WPS event
527 * @wpa_s: %wpa_supplicant network interface data
529 * Sends Event dbus signal with name "success" and empty dict as arguments
531 void wpas_dbus_signal_wps_event_success(struct wpa_supplicant *wpa_s)
535 DBusMessageIter iter, dict_iter;
536 struct wpas_dbus_priv *iface;
537 char *key = "success";
539 iface = wpa_s->global->dbus;
541 /* Do nothing if the control interface is not turned on */
545 msg = dbus_message_new_signal(wpa_s->dbus_new_path,
546 WPAS_DBUS_NEW_IFACE_WPS, "Event");
550 dbus_message_iter_init_append(msg, &iter);
552 if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &key) ||
553 !wpa_dbus_dict_open_write(&iter, &dict_iter) ||
554 !wpa_dbus_dict_close_write(&iter, &dict_iter))
555 wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
557 dbus_connection_send(iface->con, msg, NULL);
559 dbus_message_unref(msg);
564 * wpas_dbus_signal_wps_event_fail - Signals Fail WPS event
565 * @wpa_s: %wpa_supplicant network interface data
567 * Sends Event dbus signal with name "fail" and dictionary containing
568 * "msg field with fail message number (int32) as arguments
570 void wpas_dbus_signal_wps_event_fail(struct wpa_supplicant *wpa_s,
571 struct wps_event_fail *fail)
575 DBusMessageIter iter, dict_iter;
576 struct wpas_dbus_priv *iface;
579 iface = wpa_s->global->dbus;
581 /* Do nothing if the control interface is not turned on */
585 msg = dbus_message_new_signal(wpa_s->dbus_new_path,
586 WPAS_DBUS_NEW_IFACE_WPS, "Event");
590 dbus_message_iter_init_append(msg, &iter);
592 if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &key) ||
593 !wpa_dbus_dict_open_write(&iter, &dict_iter) ||
594 !wpa_dbus_dict_append_int32(&dict_iter, "msg", fail->msg) ||
595 !wpa_dbus_dict_close_write(&iter, &dict_iter))
596 wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
598 dbus_connection_send(iface->con, msg, NULL);
600 dbus_message_unref(msg);
605 * wpas_dbus_signal_wps_event_m2d - Signals M2D WPS event
606 * @wpa_s: %wpa_supplicant network interface data
608 * Sends Event dbus signal with name "m2d" and dictionary containing
609 * fields of wps_event_m2d structure.
611 void wpas_dbus_signal_wps_event_m2d(struct wpa_supplicant *wpa_s,
612 struct wps_event_m2d *m2d)
616 DBusMessageIter iter, dict_iter;
617 struct wpas_dbus_priv *iface;
620 iface = wpa_s->global->dbus;
622 /* Do nothing if the control interface is not turned on */
626 msg = dbus_message_new_signal(wpa_s->dbus_new_path,
627 WPAS_DBUS_NEW_IFACE_WPS, "Event");
631 dbus_message_iter_init_append(msg, &iter);
633 if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &key) ||
634 !wpa_dbus_dict_open_write(&iter, &dict_iter) ||
635 !wpa_dbus_dict_append_uint16(&dict_iter, "config_methods",
636 m2d->config_methods) ||
637 !wpa_dbus_dict_append_byte_array(&dict_iter, "manufacturer",
638 (const char *) m2d->manufacturer,
639 m2d->manufacturer_len) ||
640 !wpa_dbus_dict_append_byte_array(&dict_iter, "model_name",
641 (const char *) m2d->model_name,
642 m2d->model_name_len) ||
643 !wpa_dbus_dict_append_byte_array(&dict_iter, "model_number",
644 (const char *) m2d->model_number,
645 m2d->model_number_len) ||
646 !wpa_dbus_dict_append_byte_array(&dict_iter, "serial_number",
649 m2d->serial_number_len) ||
650 !wpa_dbus_dict_append_byte_array(&dict_iter, "dev_name",
651 (const char *) m2d->dev_name,
652 m2d->dev_name_len) ||
653 !wpa_dbus_dict_append_byte_array(&dict_iter, "primary_dev_type",
655 m2d->primary_dev_type, 8) ||
656 !wpa_dbus_dict_append_uint16(&dict_iter, "config_error",
657 m2d->config_error) ||
658 !wpa_dbus_dict_append_uint16(&dict_iter, "dev_password_id",
659 m2d->dev_password_id) ||
660 !wpa_dbus_dict_close_write(&iter, &dict_iter))
661 wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
663 dbus_connection_send(iface->con, msg, NULL);
665 dbus_message_unref(msg);
670 * wpas_dbus_signal_wps_cred - Signals new credentials
671 * @wpa_s: %wpa_supplicant network interface data
673 * Sends signal with credentials in directory argument
675 void wpas_dbus_signal_wps_cred(struct wpa_supplicant *wpa_s,
676 const struct wps_credential *cred)
679 DBusMessageIter iter, dict_iter;
680 struct wpas_dbus_priv *iface;
681 char *auth_type[5]; /* we have five possible authentication types */
683 char *encr_type[3]; /* we have three possible encryption types */
686 iface = wpa_s->global->dbus;
688 /* Do nothing if the control interface is not turned on */
692 msg = dbus_message_new_signal(wpa_s->dbus_new_path,
693 WPAS_DBUS_NEW_IFACE_WPS,
698 dbus_message_iter_init_append(msg, &iter);
699 if (!wpa_dbus_dict_open_write(&iter, &dict_iter))
702 if (cred->auth_type & WPS_AUTH_OPEN)
703 auth_type[at_num++] = "open";
704 if (cred->auth_type & WPS_AUTH_WPAPSK)
705 auth_type[at_num++] = "wpa-psk";
706 if (cred->auth_type & WPS_AUTH_WPA)
707 auth_type[at_num++] = "wpa-eap";
708 if (cred->auth_type & WPS_AUTH_WPA2)
709 auth_type[at_num++] = "wpa2-eap";
710 if (cred->auth_type & WPS_AUTH_WPA2PSK)
711 auth_type[at_num++] = "wpa2-psk";
713 if (cred->encr_type & WPS_ENCR_NONE)
714 encr_type[et_num++] = "none";
715 if (cred->encr_type & WPS_ENCR_TKIP)
716 encr_type[et_num++] = "tkip";
717 if (cred->encr_type & WPS_ENCR_AES)
718 encr_type[et_num++] = "aes";
720 if ((wpa_s->current_ssid &&
721 !wpa_dbus_dict_append_byte_array(
723 (const char *) wpa_s->current_ssid->bssid, ETH_ALEN)) ||
724 !wpa_dbus_dict_append_byte_array(&dict_iter, "SSID",
725 (const char *) cred->ssid,
727 !wpa_dbus_dict_append_string_array(&dict_iter, "AuthType",
728 (const char **) auth_type,
730 !wpa_dbus_dict_append_string_array(&dict_iter, "EncrType",
731 (const char **) encr_type,
733 !wpa_dbus_dict_append_byte_array(&dict_iter, "Key",
734 (const char *) cred->key,
736 !wpa_dbus_dict_append_uint32(&dict_iter, "KeyIndex",
738 !wpa_dbus_dict_close_write(&iter, &dict_iter))
741 dbus_connection_send(iface->con, msg, NULL);
744 dbus_message_unref(msg);
747 #endif /* CONFIG_WPS */
749 void wpas_dbus_signal_certification(struct wpa_supplicant *wpa_s,
750 int depth, const char *subject,
751 const char *cert_hash,
752 const struct wpabuf *cert)
754 struct wpas_dbus_priv *iface;
756 DBusMessageIter iter, dict_iter;
758 iface = wpa_s->global->dbus;
760 /* Do nothing if the control interface is not turned on */
764 msg = dbus_message_new_signal(wpa_s->dbus_new_path,
765 WPAS_DBUS_NEW_IFACE_INTERFACE,
770 dbus_message_iter_init_append(msg, &iter);
771 if (!wpa_dbus_dict_open_write(&iter, &dict_iter) ||
772 !wpa_dbus_dict_append_uint32(&dict_iter, "depth", depth) ||
773 !wpa_dbus_dict_append_string(&dict_iter, "subject", subject) ||
775 !wpa_dbus_dict_append_string(&dict_iter, "cert_hash",
778 !wpa_dbus_dict_append_byte_array(&dict_iter, "cert",
780 wpabuf_len(cert))) ||
781 !wpa_dbus_dict_close_write(&iter, &dict_iter))
782 wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
784 dbus_connection_send(iface->con, msg, NULL);
785 dbus_message_unref(msg);
789 void wpas_dbus_signal_eap_status(struct wpa_supplicant *wpa_s,
790 const char *status, const char *parameter)
792 struct wpas_dbus_priv *iface;
794 DBusMessageIter iter;
796 iface = wpa_s->global->dbus;
798 /* Do nothing if the control interface is not turned on */
802 msg = dbus_message_new_signal(wpa_s->dbus_new_path,
803 WPAS_DBUS_NEW_IFACE_INTERFACE,
808 dbus_message_iter_init_append(msg, &iter);
810 if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &status) ||
811 !dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING,
813 wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
815 dbus_connection_send(iface->con, msg, NULL);
816 dbus_message_unref(msg);
821 * wpas_dbus_signal_sta - Send a station related event signal
822 * @wpa_s: %wpa_supplicant network interface data
823 * @sta: station mac address
824 * @sig_name: signal name - StaAuthorized or StaDeauthorized
826 * Notify listeners about event related with station
828 static void wpas_dbus_signal_sta(struct wpa_supplicant *wpa_s,
829 const u8 *sta, const char *sig_name)
831 struct wpas_dbus_priv *iface;
833 char sta_mac[WPAS_DBUS_OBJECT_PATH_MAX];
836 os_snprintf(sta_mac, WPAS_DBUS_OBJECT_PATH_MAX, MACSTR, MAC2STR(sta));
839 iface = wpa_s->global->dbus;
841 /* Do nothing if the control interface is not turned on */
845 msg = dbus_message_new_signal(wpa_s->dbus_new_path,
846 WPAS_DBUS_NEW_IFACE_INTERFACE, sig_name);
850 if (dbus_message_append_args(msg, DBUS_TYPE_STRING, &dev_mac,
852 dbus_connection_send(iface->con, msg, NULL);
854 wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
855 dbus_message_unref(msg);
857 wpa_printf(MSG_DEBUG, "dbus: Station MAC address '%s' '%s'",
863 * wpas_dbus_signal_sta_authorized - Send a STA authorized signal
864 * @wpa_s: %wpa_supplicant network interface data
865 * @sta: station mac address
867 * Notify listeners a new station has been authorized
869 void wpas_dbus_signal_sta_authorized(struct wpa_supplicant *wpa_s,
872 wpas_dbus_signal_sta(wpa_s, sta, "StaAuthorized");
877 * wpas_dbus_signal_sta_deauthorized - Send a STA deauthorized signal
878 * @wpa_s: %wpa_supplicant network interface data
879 * @sta: station mac address
881 * Notify listeners a station has been deauthorized
883 void wpas_dbus_signal_sta_deauthorized(struct wpa_supplicant *wpa_s,
886 wpas_dbus_signal_sta(wpa_s, sta, "StaDeauthorized");
893 * wpas_dbus_signal_p2p_group_removed - Signals P2P group was removed
894 * @wpa_s: %wpa_supplicant network interface data
895 * @role: role of this device (client or GO)
896 * Sends signal with i/f name and role as string arguments
898 void wpas_dbus_signal_p2p_group_removed(struct wpa_supplicant *wpa_s,
902 DBusMessageIter iter, dict_iter;
903 struct wpas_dbus_priv *iface = wpa_s->global->dbus;
904 struct wpa_supplicant *parent;
906 /* Do nothing if the control interface is not turned on */
910 parent = wpa_s->parent;
911 if (parent->p2p_mgmt)
912 parent = parent->parent;
914 if (!wpa_s->dbus_groupobj_path)
917 msg = dbus_message_new_signal(parent->dbus_new_path,
918 WPAS_DBUS_NEW_IFACE_P2PDEVICE,
923 dbus_message_iter_init_append(msg, &iter);
924 if (!wpa_dbus_dict_open_write(&iter, &dict_iter) ||
925 !wpa_dbus_dict_append_object_path(&dict_iter,
927 wpa_s->dbus_new_path) ||
928 !wpa_dbus_dict_append_string(&dict_iter, "role", role) ||
929 !wpa_dbus_dict_append_object_path(&dict_iter, "group_object",
930 wpa_s->dbus_groupobj_path) ||
931 !wpa_dbus_dict_close_write(&iter, &dict_iter))
932 wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
934 dbus_connection_send(iface->con, msg, NULL);
935 dbus_message_unref(msg);
940 * wpas_dbus_signal_p2p_provision_discovery - Signals various PD events
942 * @dev_addr - who sent the request or responded to our request.
943 * @request - Will be 1 if request, 0 for response.
944 * @status - valid only in case of response
945 * @config_methods - wps config methods
946 * @generated_pin - pin to be displayed in case of WPS_CONFIG_DISPLAY method
948 * Sends following provision discovery related events:
949 * ProvisionDiscoveryRequestDisplayPin
950 * ProvisionDiscoveryResponseDisplayPin
951 * ProvisionDiscoveryRequestEnterPin
952 * ProvisionDiscoveryResponseEnterPin
953 * ProvisionDiscoveryPBCRequest
954 * ProvisionDiscoveryPBCResponse
957 * ProvisionDiscoveryFailure (timeout case)
959 void wpas_dbus_signal_p2p_provision_discovery(struct wpa_supplicant *wpa_s,
960 const u8 *dev_addr, int request,
961 enum p2p_prov_disc_status status,
963 unsigned int generated_pin)
966 DBusMessageIter iter;
967 struct wpas_dbus_priv *iface;
970 char peer_obj_path[WPAS_DBUS_OBJECT_PATH_MAX], *path;
972 char pin[9], *p_pin = NULL;
974 iface = wpa_s->global->dbus;
976 /* Do nothing if the control interface is not turned on */
981 wpa_s = wpa_s->parent;
983 if (request || !status) {
984 if (config_methods & WPS_CONFIG_DISPLAY)
986 "ProvisionDiscoveryRequestDisplayPin" :
987 "ProvisionDiscoveryResponseEnterPin";
988 else if (config_methods & WPS_CONFIG_KEYPAD)
990 "ProvisionDiscoveryRequestEnterPin" :
991 "ProvisionDiscoveryResponseDisplayPin";
992 else if (config_methods & WPS_CONFIG_PUSHBUTTON)
993 _signal = request ? "ProvisionDiscoveryPBCRequest" :
994 "ProvisionDiscoveryPBCResponse";
996 return; /* Unknown or un-supported method */
998 /* Explicit check for failure response */
999 _signal = "ProvisionDiscoveryFailure";
1002 add_pin = ((request && (config_methods & WPS_CONFIG_DISPLAY)) ||
1003 (!request && !status &&
1004 (config_methods & WPS_CONFIG_KEYPAD)));
1007 os_snprintf(pin, sizeof(pin), "%08d", generated_pin);
1011 msg = dbus_message_new_signal(wpa_s->dbus_new_path,
1012 WPAS_DBUS_NEW_IFACE_P2PDEVICE, _signal);
1016 /* Check if this is a known peer */
1017 if (!p2p_peer_known(wpa_s->global->p2p, dev_addr))
1020 os_snprintf(peer_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
1021 "%s/" WPAS_DBUS_NEW_P2P_PEERS_PART "/"
1023 wpa_s->dbus_new_path, MAC2STR(dev_addr));
1025 path = peer_obj_path;
1027 dbus_message_iter_init_append(msg, &iter);
1029 if (!dbus_message_iter_append_basic(&iter,
1030 DBUS_TYPE_OBJECT_PATH,
1034 if (!request && status)
1035 /* Attach status to ProvisionDiscoveryFailure */
1036 error_ret = !dbus_message_iter_append_basic(&iter,
1040 error_ret = (add_pin &&
1041 !dbus_message_iter_append_basic(&iter,
1047 dbus_connection_send(iface->con, msg, NULL);
1049 wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
1051 dbus_message_unref(msg);
1055 void wpas_dbus_signal_p2p_go_neg_req(struct wpa_supplicant *wpa_s,
1056 const u8 *src, u16 dev_passwd_id)
1059 DBusMessageIter iter;
1060 struct wpas_dbus_priv *iface;
1061 char peer_obj_path[WPAS_DBUS_OBJECT_PATH_MAX], *path;
1063 iface = wpa_s->global->dbus;
1065 /* Do nothing if the control interface is not turned on */
1069 if (wpa_s->p2p_mgmt)
1070 wpa_s = wpa_s->parent;
1072 os_snprintf(peer_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
1073 "%s/" WPAS_DBUS_NEW_P2P_PEERS_PART "/" COMPACT_MACSTR,
1074 wpa_s->dbus_new_path, MAC2STR(src));
1075 path = peer_obj_path;
1077 msg = dbus_message_new_signal(wpa_s->dbus_new_path,
1078 WPAS_DBUS_NEW_IFACE_P2PDEVICE,
1079 "GONegotiationRequest");
1083 dbus_message_iter_init_append(msg, &iter);
1085 if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_OBJECT_PATH,
1087 !dbus_message_iter_append_basic(&iter, DBUS_TYPE_UINT16,
1089 wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
1091 dbus_connection_send(iface->con, msg, NULL);
1093 dbus_message_unref(msg);
1097 static int wpas_dbus_get_group_obj_path(struct wpa_supplicant *wpa_s,
1098 const struct wpa_ssid *ssid,
1099 char *group_obj_path)
1103 if (os_memcmp(ssid->ssid, P2P_WILDCARD_SSID, P2P_WILDCARD_SSID_LEN))
1106 os_memcpy(group_name, ssid->ssid + P2P_WILDCARD_SSID_LEN, 2);
1107 group_name[2] = '\0';
1109 os_snprintf(group_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
1110 "%s/" WPAS_DBUS_NEW_P2P_GROUPS_PART "/%s",
1111 wpa_s->dbus_new_path, group_name);
1117 struct group_changed_data {
1118 struct wpa_supplicant *wpa_s;
1119 struct p2p_peer_info *info;
1123 static int match_group_where_peer_is_client(struct p2p_group *group,
1126 struct group_changed_data *data = user_data;
1127 const struct p2p_group_config *cfg;
1128 struct wpa_supplicant *wpa_s_go;
1130 if (!p2p_group_is_client_connected(group, data->info->p2p_device_addr))
1133 cfg = p2p_group_get_config(group);
1135 wpa_s_go = wpas_get_p2p_go_iface(data->wpa_s, cfg->ssid,
1137 if (wpa_s_go != NULL && wpa_s_go == data->wpa_s) {
1138 wpas_dbus_signal_peer_groups_changed(
1139 data->wpa_s->parent, data->info->p2p_device_addr);
1147 static void signal_peer_groups_changed(struct p2p_peer_info *info,
1150 struct group_changed_data *data = user_data;
1151 struct wpa_supplicant *wpa_s_go;
1153 wpa_s_go = wpas_get_p2p_client_iface(data->wpa_s,
1154 info->p2p_device_addr);
1155 if (wpa_s_go != NULL && wpa_s_go == data->wpa_s) {
1156 wpas_dbus_signal_peer_groups_changed(data->wpa_s->parent,
1157 info->p2p_device_addr);
1162 p2p_loop_on_all_groups(data->wpa_s->global->p2p,
1163 match_group_where_peer_is_client, data);
1168 static void peer_groups_changed(struct wpa_supplicant *wpa_s)
1170 struct group_changed_data data;
1172 os_memset(&data, 0, sizeof(data));
1175 p2p_loop_on_known_peers(wpa_s->global->p2p,
1176 signal_peer_groups_changed, &data);
1181 * wpas_dbus_signal_p2p_group_started - Signals P2P group has
1182 * started. Emitted when a group is successfully started
1183 * irrespective of the role (client/GO) of the current device
1185 * @wpa_s: %wpa_supplicant network interface data
1186 * @ssid: SSID object
1187 * @client: this device is P2P client
1188 * @network_id: network id of the group started, use instead of ssid->id
1189 * to account for persistent groups
1191 void wpas_dbus_signal_p2p_group_started(struct wpa_supplicant *wpa_s,
1192 const struct wpa_ssid *ssid,
1193 int client, int network_id)
1196 DBusMessageIter iter, dict_iter;
1197 struct wpas_dbus_priv *iface;
1198 struct wpa_supplicant *parent;
1200 parent = wpa_s->parent;
1201 if (parent->p2p_mgmt)
1202 parent = parent->parent;
1204 iface = parent->global->dbus;
1206 /* Do nothing if the control interface is not turned on */
1210 if (wpa_s->dbus_groupobj_path == NULL)
1213 /* New interface has been created for this group */
1214 msg = dbus_message_new_signal(parent->dbus_new_path,
1215 WPAS_DBUS_NEW_IFACE_P2PDEVICE,
1220 dbus_message_iter_init_append(msg, &iter);
1222 * In case the device supports creating a separate interface the
1223 * DBus client will need to know the object path for the interface
1224 * object this group was created on, so include it here.
1226 if (!wpa_dbus_dict_open_write(&iter, &dict_iter) ||
1227 !wpa_dbus_dict_append_object_path(&dict_iter,
1229 wpa_s->dbus_new_path) ||
1230 !wpa_dbus_dict_append_string(&dict_iter, "role",
1231 client ? "client" : "GO") ||
1232 !wpa_dbus_dict_append_object_path(&dict_iter, "group_object",
1233 wpa_s->dbus_groupobj_path) ||
1234 !wpa_dbus_dict_close_write(&iter, &dict_iter)) {
1235 wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
1237 dbus_connection_send(iface->con, msg, NULL);
1239 peer_groups_changed(wpa_s);
1241 dbus_message_unref(msg);
1247 * Method to emit GONegotiation Success or Failure signals based
1249 * @status: Status of the GO neg request. 0 for success, other for errors.
1251 void wpas_dbus_signal_p2p_go_neg_resp(struct wpa_supplicant *wpa_s,
1252 struct p2p_go_neg_results *res)
1255 DBusMessageIter iter, dict_iter;
1256 DBusMessageIter iter_dict_entry, iter_dict_val, iter_dict_array;
1257 struct wpas_dbus_priv *iface;
1258 char peer_obj_path[WPAS_DBUS_OBJECT_PATH_MAX], *path;
1259 dbus_int32_t freqs[P2P_MAX_CHANNELS];
1260 dbus_int32_t *f_array = freqs;
1263 iface = wpa_s->global->dbus;
1265 if (wpa_s->p2p_mgmt)
1266 wpa_s = wpa_s->parent;
1268 os_memset(freqs, 0, sizeof(freqs));
1269 /* Do nothing if the control interface is not turned on */
1273 os_snprintf(peer_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
1274 "%s/" WPAS_DBUS_NEW_P2P_PEERS_PART "/" COMPACT_MACSTR,
1275 wpa_s->dbus_new_path, MAC2STR(res->peer_device_addr));
1276 path = peer_obj_path;
1278 msg = dbus_message_new_signal(wpa_s->dbus_new_path,
1279 WPAS_DBUS_NEW_IFACE_P2PDEVICE,
1280 res->status ? "GONegotiationFailure" :
1281 "GONegotiationSuccess");
1285 dbus_message_iter_init_append(msg, &iter);
1286 if (!wpa_dbus_dict_open_write(&iter, &dict_iter) ||
1287 !wpa_dbus_dict_append_object_path(&dict_iter, "peer_object",
1289 !wpa_dbus_dict_append_int32(&dict_iter, "status", res->status))
1294 int freq_list_num = 0;
1296 if ((res->role_go &&
1297 !wpa_dbus_dict_append_string(&dict_iter, "passphrase",
1298 res->passphrase)) ||
1299 !wpa_dbus_dict_append_string(&dict_iter, "role_go",
1300 res->role_go ? "GO" :
1302 !wpa_dbus_dict_append_int32(&dict_iter, "frequency",
1304 !wpa_dbus_dict_append_byte_array(&dict_iter, "ssid",
1305 (const char *) res->ssid,
1307 !wpa_dbus_dict_append_byte_array(&dict_iter,
1310 res->peer_device_addr,
1312 !wpa_dbus_dict_append_byte_array(&dict_iter,
1313 "peer_interface_addr",
1315 res->peer_interface_addr,
1317 !wpa_dbus_dict_append_string(&dict_iter, "wps_method",
1318 p2p_wps_method_text(
1322 for (i = 0; i < P2P_MAX_CHANNELS; i++) {
1323 if (res->freq_list[i]) {
1324 freqs[i] = res->freq_list[i];
1329 if (!wpa_dbus_dict_begin_array(&dict_iter,
1331 DBUS_TYPE_INT32_AS_STRING,
1334 &iter_dict_array) ||
1335 !dbus_message_iter_append_fixed_array(&iter_dict_array,
1339 !wpa_dbus_dict_end_array(&dict_iter,
1342 &iter_dict_array) ||
1343 !wpa_dbus_dict_append_int32(&dict_iter, "persistent_group",
1344 res->persistent_group) ||
1345 !wpa_dbus_dict_append_uint32(&dict_iter,
1346 "peer_config_timeout",
1347 res->peer_config_timeout))
1351 if (!wpa_dbus_dict_close_write(&iter, &dict_iter))
1354 dbus_connection_send(iface->con, msg, NULL);
1356 dbus_message_unref(msg);
1362 * Method to emit Invitation Result signal based on status and
1364 * @status: Status of the Invite request. 0 for success, other
1366 * @bssid : Basic Service Set Identifier
1368 void wpas_dbus_signal_p2p_invitation_result(struct wpa_supplicant *wpa_s,
1369 int status, const u8 *bssid)
1372 DBusMessageIter iter, dict_iter;
1373 struct wpas_dbus_priv *iface;
1375 wpa_printf(MSG_DEBUG, "%s", __func__);
1377 iface = wpa_s->global->dbus;
1378 /* Do nothing if the control interface is not turned on */
1382 if (wpa_s->p2p_mgmt)
1383 wpa_s = wpa_s->parent;
1385 msg = dbus_message_new_signal(wpa_s->dbus_new_path,
1386 WPAS_DBUS_NEW_IFACE_P2PDEVICE,
1387 "InvitationResult");
1392 dbus_message_iter_init_append(msg, &iter);
1393 if (!wpa_dbus_dict_open_write(&iter, &dict_iter) ||
1394 !wpa_dbus_dict_append_int32(&dict_iter, "status", status) ||
1396 !wpa_dbus_dict_append_byte_array(&dict_iter, "BSSID",
1397 (const char *) bssid,
1399 !wpa_dbus_dict_close_write(&iter, &dict_iter))
1400 wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
1402 dbus_connection_send(iface->con, msg, NULL);
1403 dbus_message_unref(msg);
1409 * Method to emit a signal for a peer joining the group.
1410 * The signal will carry path to the group member object
1411 * constructed using p2p i/f addr used for connecting.
1413 * @wpa_s: %wpa_supplicant network interface data
1414 * @peer_addr: P2P Device Address of the peer joining the group
1416 void wpas_dbus_signal_p2p_peer_joined(struct wpa_supplicant *wpa_s,
1417 const u8 *peer_addr)
1419 struct wpas_dbus_priv *iface;
1421 DBusMessageIter iter;
1422 char peer_obj_path[WPAS_DBUS_OBJECT_PATH_MAX], *path;
1423 struct wpa_supplicant *parent;
1425 iface = wpa_s->global->dbus;
1427 /* Do nothing if the control interface is not turned on */
1431 if (!wpa_s->dbus_groupobj_path)
1434 parent = wpa_s->parent;
1435 if (parent->p2p_mgmt)
1436 parent = parent->parent;
1438 os_snprintf(peer_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
1439 "%s/" WPAS_DBUS_NEW_P2P_PEERS_PART "/"
1441 parent->dbus_new_path, MAC2STR(peer_addr));
1443 msg = dbus_message_new_signal(wpa_s->dbus_groupobj_path,
1444 WPAS_DBUS_NEW_IFACE_P2P_GROUP,
1449 dbus_message_iter_init_append(msg, &iter);
1450 path = peer_obj_path;
1451 if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_OBJECT_PATH,
1453 wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
1455 dbus_connection_send(iface->con, msg, NULL);
1456 wpas_dbus_signal_peer_groups_changed(parent, peer_addr);
1458 dbus_message_unref(msg);
1464 * Method to emit a signal for a peer disconnecting the group.
1465 * The signal will carry path to the group member object
1466 * constructed using the P2P Device Address of the peer.
1468 * @wpa_s: %wpa_supplicant network interface data
1469 * @peer_addr: P2P Device Address of the peer joining the group
1471 void wpas_dbus_signal_p2p_peer_disconnected(struct wpa_supplicant *wpa_s,
1472 const u8 *peer_addr)
1474 struct wpas_dbus_priv *iface;
1476 DBusMessageIter iter;
1477 char peer_obj_path[WPAS_DBUS_OBJECT_PATH_MAX], *path;
1478 struct wpa_supplicant *parent;
1480 iface = wpa_s->global->dbus;
1482 /* Do nothing if the control interface is not turned on */
1486 if (!wpa_s->dbus_groupobj_path)
1489 parent = wpa_s->parent;
1490 if (parent->p2p_mgmt)
1491 parent = parent->parent;
1493 os_snprintf(peer_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
1494 "%s/" WPAS_DBUS_NEW_P2P_PEERS_PART "/"
1496 parent->dbus_new_path, MAC2STR(peer_addr));
1498 msg = dbus_message_new_signal(wpa_s->dbus_groupobj_path,
1499 WPAS_DBUS_NEW_IFACE_P2P_GROUP,
1500 "PeerDisconnected");
1504 dbus_message_iter_init_append(msg, &iter);
1505 path = peer_obj_path;
1506 if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_OBJECT_PATH,
1508 wpa_printf(MSG_ERROR,
1509 "dbus: Failed to construct PeerDisconnected signal");
1511 dbus_connection_send(iface->con, msg, NULL);
1512 wpas_dbus_signal_peer_groups_changed(parent, peer_addr);
1514 dbus_message_unref(msg);
1520 * Method to emit a signal for a service discovery request.
1521 * The signal will carry station address, frequency, dialog token,
1522 * update indicator and it tlvs
1524 * @wpa_s: %wpa_supplicant network interface data
1525 * @sa: station addr (p2p i/f) of the peer
1526 * @dialog_token: service discovery request dialog token
1527 * @update_indic: service discovery request update indicator
1528 * @tlvs: service discovery request genrated byte array of tlvs
1529 * @tlvs_len: service discovery request tlvs length
1531 void wpas_dbus_signal_p2p_sd_request(struct wpa_supplicant *wpa_s,
1532 int freq, const u8 *sa, u8 dialog_token,
1533 u16 update_indic, const u8 *tlvs,
1537 DBusMessageIter iter, dict_iter;
1538 struct wpas_dbus_priv *iface;
1539 char peer_obj_path[WPAS_DBUS_OBJECT_PATH_MAX], *path;
1540 iface = wpa_s->global->dbus;
1542 /* Do nothing if the control interface is not turned on */
1546 if (wpa_s->p2p_mgmt)
1547 wpa_s = wpa_s->parent;
1549 /* Check if this is a known peer */
1550 if (!p2p_peer_known(wpa_s->global->p2p, sa))
1553 msg = dbus_message_new_signal(wpa_s->dbus_new_path,
1554 WPAS_DBUS_NEW_IFACE_P2PDEVICE,
1555 "ServiceDiscoveryRequest");
1559 os_snprintf(peer_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
1560 "%s/" WPAS_DBUS_NEW_P2P_PEERS_PART "/"
1561 COMPACT_MACSTR, wpa_s->dbus_new_path, MAC2STR(sa));
1563 path = peer_obj_path;
1565 dbus_message_iter_init_append(msg, &iter);
1566 if (!wpa_dbus_dict_open_write(&iter, &dict_iter) ||
1567 !wpa_dbus_dict_append_object_path(&dict_iter, "peer_object",
1569 !wpa_dbus_dict_append_int32(&dict_iter, "frequency", freq) ||
1570 !wpa_dbus_dict_append_int32(&dict_iter, "dialog_token",
1572 !wpa_dbus_dict_append_uint16(&dict_iter, "update_indicator",
1574 !wpa_dbus_dict_append_byte_array(&dict_iter, "tlvs",
1575 (const char *) tlvs,
1577 !wpa_dbus_dict_close_write(&iter, &dict_iter))
1578 wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
1580 dbus_connection_send(iface->con, msg, NULL);
1581 dbus_message_unref(msg);
1587 * Method to emit a signal for a service discovery response.
1588 * The signal will carry station address, update indicator and it
1591 * @wpa_s: %wpa_supplicant network interface data
1592 * @sa: station addr (p2p i/f) of the peer
1593 * @update_indic: service discovery request update indicator
1594 * @tlvs: service discovery request genrated byte array of tlvs
1595 * @tlvs_len: service discovery request tlvs length
1597 void wpas_dbus_signal_p2p_sd_response(struct wpa_supplicant *wpa_s,
1598 const u8 *sa, u16 update_indic,
1599 const u8 *tlvs, size_t tlvs_len)
1602 DBusMessageIter iter, dict_iter;
1603 struct wpas_dbus_priv *iface;
1604 char peer_obj_path[WPAS_DBUS_OBJECT_PATH_MAX], *path;
1605 iface = wpa_s->global->dbus;
1607 /* Do nothing if the control interface is not turned on */
1611 if (wpa_s->p2p_mgmt)
1612 wpa_s = wpa_s->parent;
1614 /* Check if this is a known peer */
1615 if (!p2p_peer_known(wpa_s->global->p2p, sa))
1618 msg = dbus_message_new_signal(wpa_s->dbus_new_path,
1619 WPAS_DBUS_NEW_IFACE_P2PDEVICE,
1620 "ServiceDiscoveryResponse");
1624 os_snprintf(peer_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
1625 "%s/" WPAS_DBUS_NEW_P2P_PEERS_PART "/"
1626 COMPACT_MACSTR, wpa_s->dbus_new_path, MAC2STR(sa));
1628 path = peer_obj_path;
1630 dbus_message_iter_init_append(msg, &iter);
1631 if (!wpa_dbus_dict_open_write(&iter, &dict_iter) ||
1632 !wpa_dbus_dict_append_object_path(&dict_iter, "peer_object",
1634 !wpa_dbus_dict_append_uint16(&dict_iter, "update_indicator",
1636 !wpa_dbus_dict_append_byte_array(&dict_iter, "tlvs",
1637 (const char *) tlvs,
1639 !wpa_dbus_dict_close_write(&iter, &dict_iter))
1640 wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
1642 dbus_connection_send(iface->con, msg, NULL);
1643 dbus_message_unref(msg);
1648 * wpas_dbus_signal_persistent_group - Send a persistent group related
1650 * @wpa_s: %wpa_supplicant network interface data
1651 * @id: new persistent group id
1652 * @sig_name: signal name - PersistentGroupAdded, PersistentGroupRemoved
1653 * @properties: determines if add second argument with object properties
1655 * Notify listeners about an event related to persistent groups.
1657 static void wpas_dbus_signal_persistent_group(struct wpa_supplicant *wpa_s,
1658 int id, const char *sig_name,
1661 struct wpas_dbus_priv *iface;
1663 DBusMessageIter iter;
1664 char pgrp_obj_path[WPAS_DBUS_OBJECT_PATH_MAX], *path;
1666 iface = wpa_s->global->dbus;
1668 /* Do nothing if the control interface is not turned on */
1672 if (wpa_s->p2p_mgmt)
1673 wpa_s = wpa_s->parent;
1675 os_snprintf(pgrp_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
1676 "%s/" WPAS_DBUS_NEW_PERSISTENT_GROUPS_PART "/%u",
1677 wpa_s->dbus_new_path, id);
1679 msg = dbus_message_new_signal(wpa_s->dbus_new_path,
1680 WPAS_DBUS_NEW_IFACE_P2PDEVICE,
1685 dbus_message_iter_init_append(msg, &iter);
1686 path = pgrp_obj_path;
1687 if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_OBJECT_PATH,
1690 !wpa_dbus_get_object_properties(
1691 iface, pgrp_obj_path,
1692 WPAS_DBUS_NEW_IFACE_PERSISTENT_GROUP, &iter)))
1693 wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
1695 dbus_connection_send(iface->con, msg, NULL);
1697 dbus_message_unref(msg);
1702 * wpas_dbus_signal_persistent_group_added - Send a persistent_group
1704 * @wpa_s: %wpa_supplicant network interface data
1705 * @id: new persistent group id
1707 * Notify listeners about addition of a new persistent group.
1709 static void wpas_dbus_signal_persistent_group_added(
1710 struct wpa_supplicant *wpa_s, int id)
1712 wpas_dbus_signal_persistent_group(wpa_s, id, "PersistentGroupAdded",
1718 * wpas_dbus_signal_persistent_group_removed - Send a persistent_group
1720 * @wpa_s: %wpa_supplicant network interface data
1721 * @id: persistent group id
1723 * Notify listeners about removal of a persistent group.
1725 static void wpas_dbus_signal_persistent_group_removed(
1726 struct wpa_supplicant *wpa_s, int id)
1728 wpas_dbus_signal_persistent_group(wpa_s, id, "PersistentGroupRemoved",
1734 * wpas_dbus_signal_p2p_wps_failed - Signals WpsFailed event
1735 * @wpa_s: %wpa_supplicant network interface data
1737 * Sends Event dbus signal with name "fail" and dictionary containing
1738 * "msg" field with fail message number (int32) as arguments
1740 void wpas_dbus_signal_p2p_wps_failed(struct wpa_supplicant *wpa_s,
1741 struct wps_event_fail *fail)
1745 DBusMessageIter iter, dict_iter;
1746 struct wpas_dbus_priv *iface;
1749 iface = wpa_s->global->dbus;
1751 /* Do nothing if the control interface is not turned on */
1755 if (wpa_s->p2p_mgmt)
1756 wpa_s = wpa_s->parent;
1758 msg = dbus_message_new_signal(wpa_s->dbus_new_path,
1759 WPAS_DBUS_NEW_IFACE_P2PDEVICE,
1764 dbus_message_iter_init_append(msg, &iter);
1766 if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &key) ||
1767 !wpa_dbus_dict_open_write(&iter, &dict_iter) ||
1768 !wpa_dbus_dict_append_int32(&dict_iter, "msg", fail->msg) ||
1769 !wpa_dbus_dict_append_int16(&dict_iter, "config_error",
1770 fail->config_error) ||
1771 !wpa_dbus_dict_close_write(&iter, &dict_iter))
1772 wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
1774 dbus_connection_send(iface->con, msg, NULL);
1776 dbus_message_unref(msg);
1779 #endif /* CONFIG_P2P */
1783 * wpas_dbus_signal_prop_changed - Signals change of property
1784 * @wpa_s: %wpa_supplicant network interface data
1785 * @property: indicates which property has changed
1787 * Sends PropertyChanged signals with path, interface and arguments
1788 * depending on which property has changed.
1790 void wpas_dbus_signal_prop_changed(struct wpa_supplicant *wpa_s,
1791 enum wpas_dbus_prop property)
1796 if (wpa_s->dbus_new_path == NULL)
1797 return; /* Skip signal since D-Bus setup is not yet ready */
1801 case WPAS_DBUS_PROP_AP_SCAN:
1804 case WPAS_DBUS_PROP_SCANNING:
1807 case WPAS_DBUS_PROP_STATE:
1810 case WPAS_DBUS_PROP_CURRENT_BSS:
1811 prop = "CurrentBSS";
1813 case WPAS_DBUS_PROP_CURRENT_NETWORK:
1814 prop = "CurrentNetwork";
1816 case WPAS_DBUS_PROP_BSSS:
1819 case WPAS_DBUS_PROP_CURRENT_AUTH_MODE:
1820 prop = "CurrentAuthMode";
1822 case WPAS_DBUS_PROP_DISCONNECT_REASON:
1823 prop = "DisconnectReason";
1827 wpa_printf(MSG_ERROR, "dbus: %s: Unknown Property value %d",
1828 __func__, property);
1832 wpa_dbus_mark_property_changed(wpa_s->global->dbus,
1833 wpa_s->dbus_new_path,
1834 WPAS_DBUS_NEW_IFACE_INTERFACE, prop);
1836 wpa_dbus_flush_object_changed_properties(
1837 wpa_s->global->dbus->con, wpa_s->dbus_new_path);
1843 * wpas_dbus_bss_signal_prop_changed - Signals change of BSS property
1844 * @wpa_s: %wpa_supplicant network interface data
1845 * @property: indicates which property has changed
1846 * @id: unique BSS identifier
1848 * Sends PropertyChanged signals with path, interface, and arguments depending
1849 * on which property has changed.
1851 void wpas_dbus_bss_signal_prop_changed(struct wpa_supplicant *wpa_s,
1852 enum wpas_dbus_bss_prop property,
1855 char path[WPAS_DBUS_OBJECT_PATH_MAX];
1859 case WPAS_DBUS_BSS_PROP_SIGNAL:
1862 case WPAS_DBUS_BSS_PROP_FREQ:
1865 case WPAS_DBUS_BSS_PROP_MODE:
1868 case WPAS_DBUS_BSS_PROP_PRIVACY:
1871 case WPAS_DBUS_BSS_PROP_RATES:
1874 case WPAS_DBUS_BSS_PROP_WPA:
1877 case WPAS_DBUS_BSS_PROP_RSN:
1880 case WPAS_DBUS_BSS_PROP_WPS:
1883 case WPAS_DBUS_BSS_PROP_IES:
1886 case WPAS_DBUS_BSS_PROP_AGE:
1890 wpa_printf(MSG_ERROR, "dbus: %s: Unknown Property value %d",
1891 __func__, property);
1895 os_snprintf(path, WPAS_DBUS_OBJECT_PATH_MAX,
1896 "%s/" WPAS_DBUS_NEW_BSSIDS_PART "/%u",
1897 wpa_s->dbus_new_path, id);
1899 wpa_dbus_mark_property_changed(wpa_s->global->dbus, path,
1900 WPAS_DBUS_NEW_IFACE_BSS, prop);
1905 * wpas_dbus_signal_debug_level_changed - Signals change of debug param
1906 * @global: wpa_global structure
1908 * Sends PropertyChanged signals informing that debug level has changed.
1910 void wpas_dbus_signal_debug_level_changed(struct wpa_global *global)
1912 wpa_dbus_mark_property_changed(global->dbus, WPAS_DBUS_NEW_PATH,
1913 WPAS_DBUS_NEW_INTERFACE,
1919 * wpas_dbus_signal_debug_timestamp_changed - Signals change of debug param
1920 * @global: wpa_global structure
1922 * Sends PropertyChanged signals informing that debug timestamp has changed.
1924 void wpas_dbus_signal_debug_timestamp_changed(struct wpa_global *global)
1926 wpa_dbus_mark_property_changed(global->dbus, WPAS_DBUS_NEW_PATH,
1927 WPAS_DBUS_NEW_INTERFACE,
1933 * wpas_dbus_signal_debug_show_keys_changed - Signals change of debug param
1934 * @global: wpa_global structure
1936 * Sends PropertyChanged signals informing that debug show_keys has changed.
1938 void wpas_dbus_signal_debug_show_keys_changed(struct wpa_global *global)
1940 wpa_dbus_mark_property_changed(global->dbus, WPAS_DBUS_NEW_PATH,
1941 WPAS_DBUS_NEW_INTERFACE,
1946 static void wpas_dbus_register(struct wpa_dbus_object_desc *obj_desc,
1948 WPADBusArgumentFreeFunction priv_free,
1949 const struct wpa_dbus_method_desc *methods,
1950 const struct wpa_dbus_property_desc *properties,
1951 const struct wpa_dbus_signal_desc *signals)
1955 obj_desc->user_data = priv;
1956 obj_desc->user_data_free_func = priv_free;
1957 obj_desc->methods = methods;
1958 obj_desc->properties = properties;
1959 obj_desc->signals = signals;
1961 for (n = 0; properties && properties->dbus_property; properties++)
1964 obj_desc->prop_changed_flags = os_zalloc(n);
1965 if (!obj_desc->prop_changed_flags)
1966 wpa_printf(MSG_DEBUG, "dbus: %s: can't register handlers",
1971 static const struct wpa_dbus_method_desc wpas_dbus_global_methods[] = {
1972 { "CreateInterface", WPAS_DBUS_NEW_INTERFACE,
1973 (WPADBusMethodHandler) &wpas_dbus_handler_create_interface,
1975 { "args", "a{sv}", ARG_IN },
1976 { "path", "o", ARG_OUT },
1980 { "RemoveInterface", WPAS_DBUS_NEW_INTERFACE,
1981 (WPADBusMethodHandler) &wpas_dbus_handler_remove_interface,
1983 { "path", "o", ARG_IN },
1987 { "GetInterface", WPAS_DBUS_NEW_INTERFACE,
1988 (WPADBusMethodHandler) &wpas_dbus_handler_get_interface,
1990 { "ifname", "s", ARG_IN },
1991 { "path", "o", ARG_OUT },
1995 { NULL, NULL, NULL, { END_ARGS } }
1998 static const struct wpa_dbus_property_desc wpas_dbus_global_properties[] = {
1999 { "DebugLevel", WPAS_DBUS_NEW_INTERFACE, "s",
2000 wpas_dbus_getter_debug_level,
2001 wpas_dbus_setter_debug_level
2003 { "DebugTimestamp", WPAS_DBUS_NEW_INTERFACE, "b",
2004 wpas_dbus_getter_debug_timestamp,
2005 wpas_dbus_setter_debug_timestamp
2007 { "DebugShowKeys", WPAS_DBUS_NEW_INTERFACE, "b",
2008 wpas_dbus_getter_debug_show_keys,
2009 wpas_dbus_setter_debug_show_keys
2011 { "Interfaces", WPAS_DBUS_NEW_INTERFACE, "ao",
2012 wpas_dbus_getter_interfaces,
2015 { "EapMethods", WPAS_DBUS_NEW_INTERFACE, "as",
2016 wpas_dbus_getter_eap_methods,
2019 { "Capabilities", WPAS_DBUS_NEW_INTERFACE, "as",
2020 wpas_dbus_getter_global_capabilities,
2023 #ifdef CONFIG_WIFI_DISPLAY
2024 { "WFDIEs", WPAS_DBUS_NEW_INTERFACE, "ay",
2025 wpas_dbus_getter_global_wfd_ies,
2026 wpas_dbus_setter_global_wfd_ies
2028 #endif /* CONFIG_WIFI_DISPLAY */
2029 { NULL, NULL, NULL, NULL, NULL }
2032 static const struct wpa_dbus_signal_desc wpas_dbus_global_signals[] = {
2033 { "InterfaceAdded", WPAS_DBUS_NEW_INTERFACE,
2035 { "path", "o", ARG_OUT },
2036 { "properties", "a{sv}", ARG_OUT },
2040 { "InterfaceRemoved", WPAS_DBUS_NEW_INTERFACE,
2042 { "path", "o", ARG_OUT },
2046 { "NetworkRequest", WPAS_DBUS_NEW_IFACE_INTERFACE,
2048 { "path", "o", ARG_OUT },
2049 { "field", "s", ARG_OUT },
2050 { "text", "s", ARG_OUT },
2054 /* Deprecated: use org.freedesktop.DBus.Properties.PropertiesChanged */
2055 { "PropertiesChanged", WPAS_DBUS_NEW_INTERFACE,
2057 { "properties", "a{sv}", ARG_OUT },
2061 { NULL, NULL, { END_ARGS } }
2066 * wpas_dbus_ctrl_iface_init - Initialize dbus control interface
2067 * @global: Pointer to global data from wpa_supplicant_init()
2068 * Returns: 0 on success or -1 on failure
2070 * Initialize the dbus control interface for wpa_supplicantand and start
2071 * receiving commands from external programs over the bus.
2073 int wpas_dbus_ctrl_iface_init(struct wpas_dbus_priv *priv)
2075 struct wpa_dbus_object_desc *obj_desc;
2078 obj_desc = os_zalloc(sizeof(struct wpa_dbus_object_desc));
2080 wpa_printf(MSG_ERROR, "Not enough memory "
2081 "to create object description");
2085 wpas_dbus_register(obj_desc, priv->global, NULL,
2086 wpas_dbus_global_methods,
2087 wpas_dbus_global_properties,
2088 wpas_dbus_global_signals);
2090 wpa_printf(MSG_DEBUG, "dbus: Register D-Bus object '%s'",
2091 WPAS_DBUS_NEW_PATH);
2092 ret = wpa_dbus_ctrl_iface_init(priv, WPAS_DBUS_NEW_PATH,
2093 WPAS_DBUS_NEW_SERVICE,
2096 free_dbus_object_desc(obj_desc);
2098 priv->dbus_new_initialized = 1;
2105 * wpas_dbus_ctrl_iface_deinit - Deinitialize dbus ctrl interface for
2107 * @iface: Pointer to dbus private data from wpas_dbus_init()
2109 * Deinitialize the dbus control interface that was initialized with
2110 * wpas_dbus_ctrl_iface_init().
2112 void wpas_dbus_ctrl_iface_deinit(struct wpas_dbus_priv *iface)
2114 if (!iface->dbus_new_initialized)
2116 wpa_printf(MSG_DEBUG, "dbus: Unregister D-Bus object '%s'",
2117 WPAS_DBUS_NEW_PATH);
2118 dbus_connection_unregister_object_path(iface->con,
2119 WPAS_DBUS_NEW_PATH);
2123 static void wpa_dbus_free(void *ptr)
2129 static const struct wpa_dbus_property_desc wpas_dbus_network_properties[] = {
2130 { "Properties", WPAS_DBUS_NEW_IFACE_NETWORK, "a{sv}",
2131 wpas_dbus_getter_network_properties,
2132 wpas_dbus_setter_network_properties
2134 { "Enabled", WPAS_DBUS_NEW_IFACE_NETWORK, "b",
2135 wpas_dbus_getter_enabled,
2136 wpas_dbus_setter_enabled
2138 { NULL, NULL, NULL, NULL, NULL }
2142 static const struct wpa_dbus_signal_desc wpas_dbus_network_signals[] = {
2143 /* Deprecated: use org.freedesktop.DBus.Properties.PropertiesChanged */
2144 { "PropertiesChanged", WPAS_DBUS_NEW_IFACE_NETWORK,
2146 { "properties", "a{sv}", ARG_OUT },
2150 { NULL, NULL, { END_ARGS } }
2155 * wpas_dbus_register_network - Register a configured network with dbus
2156 * @wpa_s: wpa_supplicant interface structure
2157 * @ssid: network configuration data
2158 * Returns: 0 on success, -1 on failure
2160 * Registers network representing object with dbus
2162 int wpas_dbus_register_network(struct wpa_supplicant *wpa_s,
2163 struct wpa_ssid *ssid)
2165 struct wpas_dbus_priv *ctrl_iface;
2166 struct wpa_dbus_object_desc *obj_desc;
2167 struct network_handler_args *arg;
2168 char net_obj_path[WPAS_DBUS_OBJECT_PATH_MAX];
2172 * If it is a persistent group register it as such.
2173 * This is to handle cases where an interface is being initialized
2174 * with a list of networks read from config.
2176 if (network_is_persistent_group(ssid))
2177 return wpas_dbus_register_persistent_group(wpa_s, ssid);
2178 #endif /* CONFIG_P2P */
2180 /* Do nothing if the control interface is not turned on */
2181 if (wpa_s == NULL || wpa_s->global == NULL)
2183 ctrl_iface = wpa_s->global->dbus;
2184 if (ctrl_iface == NULL)
2187 os_snprintf(net_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
2188 "%s/" WPAS_DBUS_NEW_NETWORKS_PART "/%u",
2189 wpa_s->dbus_new_path, ssid->id);
2191 wpa_printf(MSG_DEBUG, "dbus: Register network object '%s'",
2193 obj_desc = os_zalloc(sizeof(struct wpa_dbus_object_desc));
2195 wpa_printf(MSG_ERROR, "Not enough memory "
2196 "to create object description");
2200 /* allocate memory for handlers arguments */
2201 arg = os_zalloc(sizeof(struct network_handler_args));
2203 wpa_printf(MSG_ERROR, "Not enough memory "
2204 "to create arguments for method");
2211 wpas_dbus_register(obj_desc, arg, wpa_dbus_free, NULL,
2212 wpas_dbus_network_properties,
2213 wpas_dbus_network_signals);
2215 if (wpa_dbus_register_object_per_iface(ctrl_iface, net_obj_path,
2216 wpa_s->ifname, obj_desc))
2219 wpas_dbus_signal_network_added(wpa_s, ssid->id);
2224 free_dbus_object_desc(obj_desc);
2230 * wpas_dbus_unregister_network - Unregister a configured network from dbus
2231 * @wpa_s: wpa_supplicant interface structure
2233 * Returns: 0 on success, -1 on failure
2235 * Unregisters network representing object from dbus
2237 int wpas_dbus_unregister_network(struct wpa_supplicant *wpa_s, int nid)
2239 struct wpas_dbus_priv *ctrl_iface;
2240 char net_obj_path[WPAS_DBUS_OBJECT_PATH_MAX];
2243 struct wpa_ssid *ssid;
2245 ssid = wpa_config_get_network(wpa_s->conf, nid);
2247 /* If it is a persistent group unregister it as such */
2248 if (ssid && network_is_persistent_group(ssid))
2249 return wpas_dbus_unregister_persistent_group(wpa_s, nid);
2250 #endif /* CONFIG_P2P */
2252 /* Do nothing if the control interface is not turned on */
2253 if (wpa_s->global == NULL || wpa_s->dbus_new_path == NULL)
2255 ctrl_iface = wpa_s->global->dbus;
2256 if (ctrl_iface == NULL)
2259 os_snprintf(net_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
2260 "%s/" WPAS_DBUS_NEW_NETWORKS_PART "/%u",
2261 wpa_s->dbus_new_path, nid);
2263 wpa_printf(MSG_DEBUG, "dbus: Unregister network object '%s'",
2265 ret = wpa_dbus_unregister_object_per_iface(ctrl_iface, net_obj_path);
2268 wpas_dbus_signal_network_removed(wpa_s, nid);
2274 static const struct wpa_dbus_property_desc wpas_dbus_bss_properties[] = {
2275 { "SSID", WPAS_DBUS_NEW_IFACE_BSS, "ay",
2276 wpas_dbus_getter_bss_ssid,
2279 { "BSSID", WPAS_DBUS_NEW_IFACE_BSS, "ay",
2280 wpas_dbus_getter_bss_bssid,
2283 { "Privacy", WPAS_DBUS_NEW_IFACE_BSS, "b",
2284 wpas_dbus_getter_bss_privacy,
2287 { "Mode", WPAS_DBUS_NEW_IFACE_BSS, "s",
2288 wpas_dbus_getter_bss_mode,
2291 { "Signal", WPAS_DBUS_NEW_IFACE_BSS, "n",
2292 wpas_dbus_getter_bss_signal,
2295 { "Frequency", WPAS_DBUS_NEW_IFACE_BSS, "q",
2296 wpas_dbus_getter_bss_frequency,
2299 { "Rates", WPAS_DBUS_NEW_IFACE_BSS, "au",
2300 wpas_dbus_getter_bss_rates,
2303 { "WPA", WPAS_DBUS_NEW_IFACE_BSS, "a{sv}",
2304 wpas_dbus_getter_bss_wpa,
2307 { "RSN", WPAS_DBUS_NEW_IFACE_BSS, "a{sv}",
2308 wpas_dbus_getter_bss_rsn,
2311 { "WPS", WPAS_DBUS_NEW_IFACE_BSS, "a{sv}",
2312 wpas_dbus_getter_bss_wps,
2315 { "IEs", WPAS_DBUS_NEW_IFACE_BSS, "ay",
2316 wpas_dbus_getter_bss_ies,
2319 { "Age", WPAS_DBUS_NEW_IFACE_BSS, "u",
2320 wpas_dbus_getter_bss_age,
2323 { NULL, NULL, NULL, NULL, NULL }
2327 static const struct wpa_dbus_signal_desc wpas_dbus_bss_signals[] = {
2328 /* Deprecated: use org.freedesktop.DBus.Properties.PropertiesChanged */
2329 { "PropertiesChanged", WPAS_DBUS_NEW_IFACE_BSS,
2331 { "properties", "a{sv}", ARG_OUT },
2335 { NULL, NULL, { END_ARGS } }
2340 * wpas_dbus_unregister_bss - Unregister a scanned BSS from dbus
2341 * @wpa_s: wpa_supplicant interface structure
2342 * @bssid: scanned network bssid
2343 * @id: unique BSS identifier
2344 * Returns: 0 on success, -1 on failure
2346 * Unregisters BSS representing object from dbus
2348 int wpas_dbus_unregister_bss(struct wpa_supplicant *wpa_s,
2349 u8 bssid[ETH_ALEN], unsigned int id)
2351 struct wpas_dbus_priv *ctrl_iface;
2352 char bss_obj_path[WPAS_DBUS_OBJECT_PATH_MAX];
2354 /* Do nothing if the control interface is not turned on */
2355 if (wpa_s == NULL || wpa_s->global == NULL)
2357 ctrl_iface = wpa_s->global->dbus;
2358 if (ctrl_iface == NULL)
2361 os_snprintf(bss_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
2362 "%s/" WPAS_DBUS_NEW_BSSIDS_PART "/%u",
2363 wpa_s->dbus_new_path, id);
2365 wpa_printf(MSG_DEBUG, "dbus: Unregister BSS object '%s'",
2367 if (wpa_dbus_unregister_object_per_iface(ctrl_iface, bss_obj_path)) {
2368 wpa_printf(MSG_ERROR, "dbus: Cannot unregister BSS object %s",
2373 wpas_dbus_signal_bss_removed(wpa_s, bss_obj_path);
2374 wpas_dbus_signal_prop_changed(wpa_s, WPAS_DBUS_PROP_BSSS);
2381 * wpas_dbus_register_bss - Register a scanned BSS with dbus
2382 * @wpa_s: wpa_supplicant interface structure
2383 * @bssid: scanned network bssid
2384 * @id: unique BSS identifier
2385 * Returns: 0 on success, -1 on failure
2387 * Registers BSS representing object with dbus
2389 int wpas_dbus_register_bss(struct wpa_supplicant *wpa_s,
2390 u8 bssid[ETH_ALEN], unsigned int id)
2392 struct wpas_dbus_priv *ctrl_iface;
2393 struct wpa_dbus_object_desc *obj_desc;
2394 char bss_obj_path[WPAS_DBUS_OBJECT_PATH_MAX];
2395 struct bss_handler_args *arg;
2397 /* Do nothing if the control interface is not turned on */
2398 if (wpa_s == NULL || wpa_s->global == NULL)
2400 ctrl_iface = wpa_s->global->dbus;
2401 if (ctrl_iface == NULL)
2404 os_snprintf(bss_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
2405 "%s/" WPAS_DBUS_NEW_BSSIDS_PART "/%u",
2406 wpa_s->dbus_new_path, id);
2408 obj_desc = os_zalloc(sizeof(struct wpa_dbus_object_desc));
2410 wpa_printf(MSG_ERROR, "Not enough memory "
2411 "to create object description");
2415 arg = os_zalloc(sizeof(struct bss_handler_args));
2417 wpa_printf(MSG_ERROR, "Not enough memory "
2418 "to create arguments for handler");
2424 wpas_dbus_register(obj_desc, arg, wpa_dbus_free, NULL,
2425 wpas_dbus_bss_properties,
2426 wpas_dbus_bss_signals);
2428 wpa_printf(MSG_DEBUG, "dbus: Register BSS object '%s'",
2430 if (wpa_dbus_register_object_per_iface(ctrl_iface, bss_obj_path,
2431 wpa_s->ifname, obj_desc)) {
2432 wpa_printf(MSG_ERROR,
2433 "Cannot register BSSID dbus object %s.",
2438 wpas_dbus_signal_bss_added(wpa_s, bss_obj_path);
2439 wpas_dbus_signal_prop_changed(wpa_s, WPAS_DBUS_PROP_BSSS);
2444 free_dbus_object_desc(obj_desc);
2449 static const struct wpa_dbus_method_desc wpas_dbus_interface_methods[] = {
2450 { "Scan", WPAS_DBUS_NEW_IFACE_INTERFACE,
2451 (WPADBusMethodHandler) &wpas_dbus_handler_scan,
2453 { "args", "a{sv}", ARG_IN },
2457 { "SignalPoll", WPAS_DBUS_NEW_IFACE_INTERFACE,
2458 (WPADBusMethodHandler) &wpas_dbus_handler_signal_poll,
2460 { "args", "a{sv}", ARG_OUT },
2464 { "Disconnect", WPAS_DBUS_NEW_IFACE_INTERFACE,
2465 (WPADBusMethodHandler) &wpas_dbus_handler_disconnect,
2470 { "AddNetwork", WPAS_DBUS_NEW_IFACE_INTERFACE,
2471 (WPADBusMethodHandler) &wpas_dbus_handler_add_network,
2473 { "args", "a{sv}", ARG_IN },
2474 { "path", "o", ARG_OUT },
2478 { "Reassociate", WPAS_DBUS_NEW_IFACE_INTERFACE,
2479 (WPADBusMethodHandler) &wpas_dbus_handler_reassociate,
2484 { "Reattach", WPAS_DBUS_NEW_IFACE_INTERFACE,
2485 (WPADBusMethodHandler) &wpas_dbus_handler_reattach,
2490 { "RemoveNetwork", WPAS_DBUS_NEW_IFACE_INTERFACE,
2491 (WPADBusMethodHandler) &wpas_dbus_handler_remove_network,
2493 { "path", "o", ARG_IN },
2497 { "RemoveAllNetworks", WPAS_DBUS_NEW_IFACE_INTERFACE,
2498 (WPADBusMethodHandler) &wpas_dbus_handler_remove_all_networks,
2503 { "SelectNetwork", WPAS_DBUS_NEW_IFACE_INTERFACE,
2504 (WPADBusMethodHandler) &wpas_dbus_handler_select_network,
2506 { "path", "o", ARG_IN },
2510 { "NetworkReply", WPAS_DBUS_NEW_IFACE_INTERFACE,
2511 (WPADBusMethodHandler) &wpas_dbus_handler_network_reply,
2513 { "path", "o", ARG_IN },
2514 { "field", "s", ARG_IN },
2515 { "value", "s", ARG_IN },
2519 #ifndef CONFIG_NO_CONFIG_BLOBS
2520 { "AddBlob", WPAS_DBUS_NEW_IFACE_INTERFACE,
2521 (WPADBusMethodHandler) &wpas_dbus_handler_add_blob,
2523 { "name", "s", ARG_IN },
2524 { "data", "ay", ARG_IN },
2528 { "GetBlob", WPAS_DBUS_NEW_IFACE_INTERFACE,
2529 (WPADBusMethodHandler) &wpas_dbus_handler_get_blob,
2531 { "name", "s", ARG_IN },
2532 { "data", "ay", ARG_OUT },
2536 { "RemoveBlob", WPAS_DBUS_NEW_IFACE_INTERFACE,
2537 (WPADBusMethodHandler) &wpas_dbus_handler_remove_blob,
2539 { "name", "s", ARG_IN },
2543 #endif /* CONFIG_NO_CONFIG_BLOBS */
2544 { "SetPKCS11EngineAndModulePath", WPAS_DBUS_NEW_IFACE_INTERFACE,
2545 (WPADBusMethodHandler)
2546 &wpas_dbus_handler_set_pkcs11_engine_and_module_path,
2548 { "pkcs11_engine_path", "s", ARG_IN },
2549 { "pkcs11_module_path", "s", ARG_IN },
2554 { "Start", WPAS_DBUS_NEW_IFACE_WPS,
2555 (WPADBusMethodHandler) &wpas_dbus_handler_wps_start,
2557 { "args", "a{sv}", ARG_IN },
2558 { "output", "a{sv}", ARG_OUT },
2562 #endif /* CONFIG_WPS */
2564 { "Find", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
2565 (WPADBusMethodHandler)wpas_dbus_handler_p2p_find,
2567 { "args", "a{sv}", ARG_IN },
2571 { "StopFind", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
2572 (WPADBusMethodHandler)wpas_dbus_handler_p2p_stop_find,
2577 { "Listen", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
2578 (WPADBusMethodHandler)wpas_dbus_handler_p2p_listen,
2580 { "timeout", "i", ARG_IN },
2584 { "ExtendedListen", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
2585 (WPADBusMethodHandler)wpas_dbus_handler_p2p_extendedlisten,
2587 { "args", "a{sv}", ARG_IN },
2591 { "PresenceRequest", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
2592 (WPADBusMethodHandler)wpas_dbus_handler_p2p_presence_request,
2594 { "args", "a{sv}", ARG_IN },
2598 { "ProvisionDiscoveryRequest", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
2599 (WPADBusMethodHandler)wpas_dbus_handler_p2p_prov_disc_req,
2601 { "peer", "o", ARG_IN },
2602 { "config_method", "s", ARG_IN },
2606 { "Connect", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
2607 (WPADBusMethodHandler)wpas_dbus_handler_p2p_connect,
2609 { "args", "a{sv}", ARG_IN },
2610 { "generated_pin", "s", ARG_OUT },
2614 { "GroupAdd", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
2615 (WPADBusMethodHandler)wpas_dbus_handler_p2p_group_add,
2617 { "args", "a{sv}", ARG_IN },
2621 { "Invite", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
2622 (WPADBusMethodHandler)wpas_dbus_handler_p2p_invite,
2624 { "args", "a{sv}", ARG_IN },
2628 { "Disconnect", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
2629 (WPADBusMethodHandler)wpas_dbus_handler_p2p_disconnect,
2634 { "RejectPeer", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
2635 (WPADBusMethodHandler)wpas_dbus_handler_p2p_rejectpeer,
2637 { "peer", "o", ARG_IN },
2641 { "Flush", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
2642 (WPADBusMethodHandler)wpas_dbus_handler_p2p_flush,
2647 { "AddService", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
2648 (WPADBusMethodHandler)wpas_dbus_handler_p2p_add_service,
2650 { "args", "a{sv}", ARG_IN },
2654 { "DeleteService", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
2655 (WPADBusMethodHandler)wpas_dbus_handler_p2p_delete_service,
2657 { "args", "a{sv}", ARG_IN },
2661 { "FlushService", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
2662 (WPADBusMethodHandler)wpas_dbus_handler_p2p_flush_service,
2667 { "ServiceDiscoveryRequest", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
2668 (WPADBusMethodHandler)wpas_dbus_handler_p2p_service_sd_req,
2670 { "args", "a{sv}", ARG_IN },
2671 { "ref", "t", ARG_OUT },
2675 { "ServiceDiscoveryResponse", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
2676 (WPADBusMethodHandler)wpas_dbus_handler_p2p_service_sd_res,
2678 { "args", "a{sv}", ARG_IN },
2682 { "ServiceDiscoveryCancelRequest", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
2683 (WPADBusMethodHandler)wpas_dbus_handler_p2p_service_sd_cancel_req,
2685 { "args", "t", ARG_IN },
2689 { "ServiceUpdate", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
2690 (WPADBusMethodHandler)wpas_dbus_handler_p2p_service_update,
2695 { "ServiceDiscoveryExternal", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
2696 (WPADBusMethodHandler)wpas_dbus_handler_p2p_serv_disc_external,
2698 { "arg", "i", ARG_IN },
2702 { "AddPersistentGroup", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
2703 (WPADBusMethodHandler) wpas_dbus_handler_add_persistent_group,
2705 { "args", "a{sv}", ARG_IN },
2706 { "path", "o", ARG_OUT },
2710 { "RemovePersistentGroup", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
2711 (WPADBusMethodHandler) wpas_dbus_handler_remove_persistent_group,
2713 { "path", "o", ARG_IN },
2717 { "RemoveAllPersistentGroups", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
2718 (WPADBusMethodHandler)
2719 wpas_dbus_handler_remove_all_persistent_groups,
2724 #endif /* CONFIG_P2P */
2725 { "FlushBSS", WPAS_DBUS_NEW_IFACE_INTERFACE,
2726 (WPADBusMethodHandler) &wpas_dbus_handler_flush_bss,
2728 { "age", "u", ARG_IN },
2733 { "SubscribeProbeReq", WPAS_DBUS_NEW_IFACE_INTERFACE,
2734 (WPADBusMethodHandler) wpas_dbus_handler_subscribe_preq,
2739 { "UnsubscribeProbeReq", WPAS_DBUS_NEW_IFACE_INTERFACE,
2740 (WPADBusMethodHandler) wpas_dbus_handler_unsubscribe_preq,
2745 #endif /* CONFIG_AP */
2746 { "EAPLogoff", WPAS_DBUS_NEW_IFACE_INTERFACE,
2747 (WPADBusMethodHandler) &wpas_dbus_handler_eap_logoff,
2752 { "EAPLogon", WPAS_DBUS_NEW_IFACE_INTERFACE,
2753 (WPADBusMethodHandler) &wpas_dbus_handler_eap_logon,
2758 #ifdef CONFIG_AUTOSCAN
2759 { "AutoScan", WPAS_DBUS_NEW_IFACE_INTERFACE,
2760 (WPADBusMethodHandler) &wpas_dbus_handler_autoscan,
2762 { "arg", "s", ARG_IN },
2766 #endif /* CONFIG_AUTOSCAN */
2768 { "TDLSDiscover", WPAS_DBUS_NEW_IFACE_INTERFACE,
2769 (WPADBusMethodHandler) wpas_dbus_handler_tdls_discover,
2771 { "peer_address", "s", ARG_IN },
2775 { "TDLSSetup", WPAS_DBUS_NEW_IFACE_INTERFACE,
2776 (WPADBusMethodHandler) wpas_dbus_handler_tdls_setup,
2778 { "peer_address", "s", ARG_IN },
2782 { "TDLSStatus", WPAS_DBUS_NEW_IFACE_INTERFACE,
2783 (WPADBusMethodHandler) wpas_dbus_handler_tdls_status,
2785 { "peer_address", "s", ARG_IN },
2786 { "status", "s", ARG_OUT },
2790 { "TDLSTeardown", WPAS_DBUS_NEW_IFACE_INTERFACE,
2791 (WPADBusMethodHandler) wpas_dbus_handler_tdls_teardown,
2793 { "peer_address", "s", ARG_IN },
2797 #endif /* CONFIG_TDLS */
2798 { NULL, NULL, NULL, { END_ARGS } }
2801 static const struct wpa_dbus_property_desc wpas_dbus_interface_properties[] = {
2802 { "Capabilities", WPAS_DBUS_NEW_IFACE_INTERFACE, "a{sv}",
2803 wpas_dbus_getter_capabilities,
2806 { "State", WPAS_DBUS_NEW_IFACE_INTERFACE, "s",
2807 wpas_dbus_getter_state,
2810 { "Scanning", WPAS_DBUS_NEW_IFACE_INTERFACE, "b",
2811 wpas_dbus_getter_scanning,
2814 { "ApScan", WPAS_DBUS_NEW_IFACE_INTERFACE, "u",
2815 wpas_dbus_getter_ap_scan,
2816 wpas_dbus_setter_ap_scan
2818 { "BSSExpireAge", WPAS_DBUS_NEW_IFACE_INTERFACE, "u",
2819 wpas_dbus_getter_bss_expire_age,
2820 wpas_dbus_setter_bss_expire_age
2822 { "BSSExpireCount", WPAS_DBUS_NEW_IFACE_INTERFACE, "u",
2823 wpas_dbus_getter_bss_expire_count,
2824 wpas_dbus_setter_bss_expire_count
2826 { "Country", WPAS_DBUS_NEW_IFACE_INTERFACE, "s",
2827 wpas_dbus_getter_country,
2828 wpas_dbus_setter_country
2830 { "Ifname", WPAS_DBUS_NEW_IFACE_INTERFACE, "s",
2831 wpas_dbus_getter_ifname,
2834 { "Driver", WPAS_DBUS_NEW_IFACE_INTERFACE, "s",
2835 wpas_dbus_getter_driver,
2838 { "BridgeIfname", WPAS_DBUS_NEW_IFACE_INTERFACE, "s",
2839 wpas_dbus_getter_bridge_ifname,
2842 { "CurrentBSS", WPAS_DBUS_NEW_IFACE_INTERFACE, "o",
2843 wpas_dbus_getter_current_bss,
2846 { "CurrentNetwork", WPAS_DBUS_NEW_IFACE_INTERFACE, "o",
2847 wpas_dbus_getter_current_network,
2850 { "CurrentAuthMode", WPAS_DBUS_NEW_IFACE_INTERFACE, "s",
2851 wpas_dbus_getter_current_auth_mode,
2854 { "Blobs", WPAS_DBUS_NEW_IFACE_INTERFACE, "a{say}",
2855 wpas_dbus_getter_blobs,
2858 { "BSSs", WPAS_DBUS_NEW_IFACE_INTERFACE, "ao",
2859 wpas_dbus_getter_bsss,
2862 { "Networks", WPAS_DBUS_NEW_IFACE_INTERFACE, "ao",
2863 wpas_dbus_getter_networks,
2866 { "FastReauth", WPAS_DBUS_NEW_IFACE_INTERFACE, "b",
2867 wpas_dbus_getter_fast_reauth,
2868 wpas_dbus_setter_fast_reauth
2870 { "ScanInterval", WPAS_DBUS_NEW_IFACE_INTERFACE, "i",
2871 wpas_dbus_getter_scan_interval,
2872 wpas_dbus_setter_scan_interval
2874 { "PKCS11EnginePath", WPAS_DBUS_NEW_IFACE_INTERFACE, "s",
2875 wpas_dbus_getter_pkcs11_engine_path,
2878 { "PKCS11ModulePath", WPAS_DBUS_NEW_IFACE_INTERFACE, "s",
2879 wpas_dbus_getter_pkcs11_module_path,
2883 { "ProcessCredentials", WPAS_DBUS_NEW_IFACE_WPS, "b",
2884 wpas_dbus_getter_process_credentials,
2885 wpas_dbus_setter_process_credentials
2887 { "ConfigMethods", WPAS_DBUS_NEW_IFACE_WPS, "s",
2888 wpas_dbus_getter_config_methods,
2889 wpas_dbus_setter_config_methods
2891 #endif /* CONFIG_WPS */
2893 { "P2PDeviceConfig", WPAS_DBUS_NEW_IFACE_P2PDEVICE, "a{sv}",
2894 wpas_dbus_getter_p2p_device_config,
2895 wpas_dbus_setter_p2p_device_config
2897 { "Peers", WPAS_DBUS_NEW_IFACE_P2PDEVICE, "ao",
2898 wpas_dbus_getter_p2p_peers,
2901 { "Role", WPAS_DBUS_NEW_IFACE_P2PDEVICE, "s",
2902 wpas_dbus_getter_p2p_role,
2905 { "Group", WPAS_DBUS_NEW_IFACE_P2PDEVICE, "o",
2906 wpas_dbus_getter_p2p_group,
2909 { "PeerGO", WPAS_DBUS_NEW_IFACE_P2PDEVICE, "o",
2910 wpas_dbus_getter_p2p_peergo,
2913 { "PersistentGroups", WPAS_DBUS_NEW_IFACE_P2PDEVICE, "ao",
2914 wpas_dbus_getter_persistent_groups,
2917 #endif /* CONFIG_P2P */
2918 { "DisconnectReason", WPAS_DBUS_NEW_IFACE_INTERFACE, "i",
2919 wpas_dbus_getter_disconnect_reason,
2922 { NULL, NULL, NULL, NULL, NULL }
2925 static const struct wpa_dbus_signal_desc wpas_dbus_interface_signals[] = {
2926 { "ScanDone", WPAS_DBUS_NEW_IFACE_INTERFACE,
2928 { "success", "b", ARG_OUT },
2932 { "BSSAdded", WPAS_DBUS_NEW_IFACE_INTERFACE,
2934 { "path", "o", ARG_OUT },
2935 { "properties", "a{sv}", ARG_OUT },
2939 { "BSSRemoved", WPAS_DBUS_NEW_IFACE_INTERFACE,
2941 { "path", "o", ARG_OUT },
2945 { "BlobAdded", WPAS_DBUS_NEW_IFACE_INTERFACE,
2947 { "name", "s", ARG_OUT },
2951 { "BlobRemoved", WPAS_DBUS_NEW_IFACE_INTERFACE,
2953 { "name", "s", ARG_OUT },
2957 { "NetworkAdded", WPAS_DBUS_NEW_IFACE_INTERFACE,
2959 { "path", "o", ARG_OUT },
2960 { "properties", "a{sv}", ARG_OUT },
2964 { "NetworkRemoved", WPAS_DBUS_NEW_IFACE_INTERFACE,
2966 { "path", "o", ARG_OUT },
2970 { "NetworkSelected", WPAS_DBUS_NEW_IFACE_INTERFACE,
2972 { "path", "o", ARG_OUT },
2976 /* Deprecated: use org.freedesktop.DBus.Properties.PropertiesChanged */
2977 { "PropertiesChanged", WPAS_DBUS_NEW_IFACE_INTERFACE,
2979 { "properties", "a{sv}", ARG_OUT },
2984 { "Event", WPAS_DBUS_NEW_IFACE_WPS,
2986 { "name", "s", ARG_OUT },
2987 { "args", "a{sv}", ARG_OUT },
2991 { "Credentials", WPAS_DBUS_NEW_IFACE_WPS,
2993 { "credentials", "a{sv}", ARG_OUT },
2997 /* Deprecated: use org.freedesktop.DBus.Properties.PropertiesChanged */
2998 { "PropertiesChanged", WPAS_DBUS_NEW_IFACE_WPS,
3000 { "properties", "a{sv}", ARG_OUT },
3004 #endif /* CONFIG_WPS */
3006 { "P2PStateChanged", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
3008 { "states", "a{ss}", ARG_OUT },
3012 { "DeviceFound", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
3014 { "path", "o", ARG_OUT },
3018 { "DeviceLost", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
3020 { "path", "o", ARG_OUT },
3024 { "ProvisionDiscoveryRequestDisplayPin", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
3026 { "peer_object", "o", ARG_OUT },
3027 { "pin", "s", ARG_OUT },
3031 { "ProvisionDiscoveryResponseDisplayPin", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
3033 { "peer_object", "o", ARG_OUT },
3034 { "pin", "s", ARG_OUT },
3038 { "ProvisionDiscoveryRequestEnterPin", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
3040 { "peer_object", "o", ARG_OUT },
3044 { "ProvisionDiscoveryResponseEnterPin", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
3046 { "peer_object", "o", ARG_OUT },
3050 { "ProvisionDiscoveryPBCRequest", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
3052 { "peer_object", "o", ARG_OUT },
3056 { "ProvisionDiscoveryPBCResponse", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
3058 { "peer_object", "o", ARG_OUT },
3062 { "ProvisionDiscoveryFailure", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
3064 { "peer_object", "o", ARG_OUT },
3065 { "status", "i", ARG_OUT },
3069 { "GroupStarted", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
3071 { "properties", "a{sv}", ARG_OUT },
3075 { "GONegotiationSuccess", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
3077 { "properties", "a{sv}", ARG_OUT },
3081 { "GONegotiationFailure", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
3083 { "properties", "a{sv}", ARG_OUT },
3087 { "GONegotiationRequest", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
3089 { "path", "o", ARG_OUT },
3090 { "dev_passwd_id", "i", ARG_OUT },
3094 { "InvitationResult", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
3096 { "invite_result", "a{sv}", ARG_OUT },
3100 { "GroupFinished", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
3102 { "properties", "a{sv}", ARG_OUT },
3106 { "ServiceDiscoveryRequest", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
3108 { "sd_request", "a{sv}", ARG_OUT },
3112 { "ServiceDiscoveryResponse", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
3114 { "sd_response", "a{sv}", ARG_OUT },
3118 { "PersistentGroupAdded", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
3120 { "path", "o", ARG_OUT },
3121 { "properties", "a{sv}", ARG_OUT },
3125 { "PersistentGroupRemoved", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
3127 { "path", "o", ARG_OUT },
3131 { "WpsFailed", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
3133 { "name", "s", ARG_OUT },
3134 { "args", "a{sv}", ARG_OUT },
3138 #endif /* CONFIG_P2P */
3140 { "ProbeRequest", WPAS_DBUS_NEW_IFACE_INTERFACE,
3142 { "args", "a{sv}", ARG_OUT },
3146 #endif /* CONFIG_AP */
3147 { "Certification", WPAS_DBUS_NEW_IFACE_INTERFACE,
3149 { "certification", "a{sv}", ARG_OUT },
3153 { "EAP", WPAS_DBUS_NEW_IFACE_INTERFACE,
3155 { "status", "s", ARG_OUT },
3156 { "parameter", "s", ARG_OUT },
3160 { "StaAuthorized", WPAS_DBUS_NEW_IFACE_INTERFACE,
3162 { "name", "s", ARG_OUT },
3166 { "StaDeauthorized", WPAS_DBUS_NEW_IFACE_INTERFACE,
3168 { "name", "s", ARG_OUT },
3172 { NULL, NULL, { END_ARGS } }
3176 int wpas_dbus_register_interface(struct wpa_supplicant *wpa_s)
3179 struct wpa_dbus_object_desc *obj_desc = NULL;
3180 struct wpas_dbus_priv *ctrl_iface = wpa_s->global->dbus;
3183 /* Do nothing if the control interface is not turned on */
3184 if (ctrl_iface == NULL)
3187 /* Create and set the interface's object path */
3188 wpa_s->dbus_new_path = os_zalloc(WPAS_DBUS_OBJECT_PATH_MAX);
3189 if (wpa_s->dbus_new_path == NULL)
3191 next = ctrl_iface->next_objid++;
3192 os_snprintf(wpa_s->dbus_new_path, WPAS_DBUS_OBJECT_PATH_MAX,
3193 WPAS_DBUS_NEW_PATH_INTERFACES "/%u",
3196 obj_desc = os_zalloc(sizeof(struct wpa_dbus_object_desc));
3198 wpa_printf(MSG_ERROR, "Not enough memory "
3199 "to create object description");
3203 wpas_dbus_register(obj_desc, wpa_s, NULL, wpas_dbus_interface_methods,
3204 wpas_dbus_interface_properties,
3205 wpas_dbus_interface_signals);
3207 wpa_printf(MSG_DEBUG, "dbus: Register interface object '%s'",
3208 wpa_s->dbus_new_path);
3209 if (wpa_dbus_register_object_per_iface(ctrl_iface,
3210 wpa_s->dbus_new_path,
3211 wpa_s->ifname, obj_desc))
3214 wpas_dbus_signal_interface_added(wpa_s);
3219 os_free(wpa_s->dbus_new_path);
3220 wpa_s->dbus_new_path = NULL;
3221 free_dbus_object_desc(obj_desc);
3226 int wpas_dbus_unregister_interface(struct wpa_supplicant *wpa_s)
3228 struct wpas_dbus_priv *ctrl_iface;
3230 /* Do nothing if the control interface is not turned on */
3231 if (wpa_s == NULL || wpa_s->global == NULL)
3233 ctrl_iface = wpa_s->global->dbus;
3234 if (ctrl_iface == NULL)
3237 wpa_printf(MSG_DEBUG, "dbus: Unregister interface object '%s'",
3238 wpa_s->dbus_new_path);
3241 if (wpa_s->preq_notify_peer) {
3242 wpas_dbus_unsubscribe_noc(ctrl_iface);
3243 os_free(wpa_s->preq_notify_peer);
3244 wpa_s->preq_notify_peer = NULL;
3246 #endif /* CONFIG_AP */
3248 if (wpa_dbus_unregister_object_per_iface(ctrl_iface,
3249 wpa_s->dbus_new_path))
3252 wpas_dbus_signal_interface_removed(wpa_s);
3254 os_free(wpa_s->dbus_new_path);
3255 wpa_s->dbus_new_path = NULL;
3262 static const struct wpa_dbus_property_desc wpas_dbus_p2p_peer_properties[] = {
3263 { "DeviceName", WPAS_DBUS_NEW_IFACE_P2P_PEER, "s",
3264 wpas_dbus_getter_p2p_peer_device_name,
3267 { "PrimaryDeviceType", WPAS_DBUS_NEW_IFACE_P2P_PEER, "ay",
3268 wpas_dbus_getter_p2p_peer_primary_device_type,
3271 { "config_method", WPAS_DBUS_NEW_IFACE_P2P_PEER, "q",
3272 wpas_dbus_getter_p2p_peer_config_method,
3275 { "level", WPAS_DBUS_NEW_IFACE_P2P_PEER, "i",
3276 wpas_dbus_getter_p2p_peer_level,
3279 { "devicecapability", WPAS_DBUS_NEW_IFACE_P2P_PEER, "y",
3280 wpas_dbus_getter_p2p_peer_device_capability,
3283 { "groupcapability", WPAS_DBUS_NEW_IFACE_P2P_PEER, "y",
3284 wpas_dbus_getter_p2p_peer_group_capability,
3287 { "SecondaryDeviceTypes", WPAS_DBUS_NEW_IFACE_P2P_PEER, "aay",
3288 wpas_dbus_getter_p2p_peer_secondary_device_types,
3291 { "VendorExtension", WPAS_DBUS_NEW_IFACE_P2P_PEER, "aay",
3292 wpas_dbus_getter_p2p_peer_vendor_extension,
3295 { "IEs", WPAS_DBUS_NEW_IFACE_P2P_PEER, "ay",
3296 wpas_dbus_getter_p2p_peer_ies,
3299 { "DeviceAddress", WPAS_DBUS_NEW_IFACE_P2P_PEER, "ay",
3300 wpas_dbus_getter_p2p_peer_device_address,
3303 { "Groups", WPAS_DBUS_NEW_IFACE_P2P_PEER, "ao",
3304 wpas_dbus_getter_p2p_peer_groups,
3307 { NULL, NULL, NULL, NULL, NULL }
3310 static const struct wpa_dbus_signal_desc wpas_dbus_p2p_peer_signals[] = {
3311 /* Deprecated: use org.freedesktop.DBus.Properties.PropertiesChanged */
3312 { "PropertiesChanged", WPAS_DBUS_NEW_IFACE_P2P_PEER,
3314 { "properties", "a{sv}", ARG_OUT },
3318 { NULL, NULL, { END_ARGS } }
3322 * wpas_dbus_signal_peer - Send a peer related event signal
3323 * @wpa_s: %wpa_supplicant network interface data
3324 * @dev: peer device object
3325 * @interface: name of the interface emitting this signal.
3326 * In case of peer objects, it would be emitted by either
3327 * the "interface object" or by "peer objects"
3328 * @sig_name: signal name - DeviceFound
3330 * Notify listeners about event related with newly found p2p peer device
3332 static void wpas_dbus_signal_peer(struct wpa_supplicant *wpa_s,
3333 const u8 *dev_addr, const char *interface,
3334 const char *sig_name)
3336 struct wpas_dbus_priv *iface;
3338 DBusMessageIter iter;
3339 char peer_obj_path[WPAS_DBUS_OBJECT_PATH_MAX], *path;
3341 if (wpa_s->p2p_mgmt)
3342 wpa_s = wpa_s->parent;
3344 iface = wpa_s->global->dbus;
3346 /* Do nothing if the control interface is not turned on */
3350 os_snprintf(peer_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
3351 "%s/" WPAS_DBUS_NEW_P2P_PEERS_PART "/" COMPACT_MACSTR,
3352 wpa_s->dbus_new_path, MAC2STR(dev_addr));
3354 msg = dbus_message_new_signal(wpa_s->dbus_new_path, interface,
3359 dbus_message_iter_init_append(msg, &iter);
3360 path = peer_obj_path;
3361 if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_OBJECT_PATH,
3363 wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
3365 dbus_connection_send(iface->con, msg, NULL);
3367 dbus_message_unref(msg);
3372 * wpas_dbus_signal_peer_found - Send a peer found signal
3373 * @wpa_s: %wpa_supplicant network interface data
3374 * @dev: peer device object
3376 * Notify listeners about find a p2p peer device found
3378 void wpas_dbus_signal_peer_device_found(struct wpa_supplicant *wpa_s,
3381 wpas_dbus_signal_peer(wpa_s, dev_addr,
3382 WPAS_DBUS_NEW_IFACE_P2PDEVICE,
3387 * wpas_dbus_signal_peer_lost - Send a peer lost signal
3388 * @wpa_s: %wpa_supplicant network interface data
3389 * @dev: peer device object
3391 * Notify listeners about lost a p2p peer device
3393 void wpas_dbus_signal_peer_device_lost(struct wpa_supplicant *wpa_s,
3396 wpas_dbus_signal_peer(wpa_s, dev_addr,
3397 WPAS_DBUS_NEW_IFACE_P2PDEVICE,
3402 * wpas_dbus_register_peer - Register a discovered peer object with dbus
3403 * @wpa_s: wpa_supplicant interface structure
3404 * @ssid: network configuration data
3405 * Returns: 0 on success, -1 on failure
3407 * Registers network representing object with dbus
3409 int wpas_dbus_register_peer(struct wpa_supplicant *wpa_s, const u8 *dev_addr)
3411 struct wpas_dbus_priv *ctrl_iface;
3412 struct wpa_dbus_object_desc *obj_desc;
3413 struct peer_handler_args *arg;
3414 char peer_obj_path[WPAS_DBUS_OBJECT_PATH_MAX];
3416 /* Do nothing if the control interface is not turned on */
3417 if (wpa_s == NULL || wpa_s->global == NULL)
3420 ctrl_iface = wpa_s->global->dbus;
3421 if (ctrl_iface == NULL)
3424 if (wpa_s->p2p_mgmt)
3425 wpa_s = wpa_s->parent;
3427 os_snprintf(peer_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
3428 "%s/" WPAS_DBUS_NEW_P2P_PEERS_PART "/" COMPACT_MACSTR,
3429 wpa_s->dbus_new_path, MAC2STR(dev_addr));
3431 wpa_printf(MSG_INFO, "dbus: Register peer object '%s'",
3433 obj_desc = os_zalloc(sizeof(struct wpa_dbus_object_desc));
3435 wpa_printf(MSG_ERROR, "Not enough memory "
3436 "to create object description");
3440 /* allocate memory for handlers arguments */
3441 arg = os_zalloc(sizeof(struct peer_handler_args));
3443 wpa_printf(MSG_ERROR, "Not enough memory "
3444 "to create arguments for method");
3449 os_memcpy(arg->p2p_device_addr, dev_addr, ETH_ALEN);
3451 wpas_dbus_register(obj_desc, arg, wpa_dbus_free,
3453 wpas_dbus_p2p_peer_properties,
3454 wpas_dbus_p2p_peer_signals);
3456 if (wpa_dbus_register_object_per_iface(ctrl_iface, peer_obj_path,
3457 wpa_s->ifname, obj_desc))
3463 free_dbus_object_desc(obj_desc);
3468 * wpas_dbus_unregister_peer - Unregister a peer object with dbus
3469 * @wpa_s: wpa_supplicant interface structure
3470 * @dev_addr: p2p device addr
3471 * Returns: 0 on success, -1 on failure
3473 * Registers network representing object with dbus
3475 int wpas_dbus_unregister_peer(struct wpa_supplicant *wpa_s,
3478 struct wpas_dbus_priv *ctrl_iface;
3479 char peer_obj_path[WPAS_DBUS_OBJECT_PATH_MAX];
3482 /* Do nothing if the control interface is not turned on */
3483 if (wpa_s == NULL || wpa_s->global == NULL ||
3484 wpa_s->dbus_new_path == NULL)
3487 if (wpa_s->p2p_mgmt)
3488 wpa_s = wpa_s->parent;
3490 ctrl_iface = wpa_s->global->dbus;
3491 if (ctrl_iface == NULL)
3494 os_snprintf(peer_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
3495 "%s/" WPAS_DBUS_NEW_P2P_PEERS_PART "/" COMPACT_MACSTR,
3496 wpa_s->dbus_new_path, MAC2STR(dev_addr));
3498 wpa_printf(MSG_INFO, "dbus: Unregister peer object '%s'",
3500 ret = wpa_dbus_unregister_object_per_iface(ctrl_iface, peer_obj_path);
3506 void wpas_dbus_signal_peer_groups_changed(struct wpa_supplicant *wpa_s,
3509 char peer_obj_path[WPAS_DBUS_OBJECT_PATH_MAX];
3511 if (wpa_s->p2p_mgmt)
3512 wpa_s = wpa_s->parent;
3514 os_snprintf(peer_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
3515 "%s/" WPAS_DBUS_NEW_P2P_PEERS_PART "/" COMPACT_MACSTR,
3516 wpa_s->dbus_new_path, MAC2STR(dev_addr));
3518 wpa_dbus_mark_property_changed(wpa_s->global->dbus, peer_obj_path,
3519 WPAS_DBUS_NEW_IFACE_P2P_PEER, "Groups");
3523 static const struct wpa_dbus_property_desc wpas_dbus_p2p_group_properties[] = {
3524 { "Members", WPAS_DBUS_NEW_IFACE_P2P_GROUP, "ao",
3525 wpas_dbus_getter_p2p_group_members,
3528 { "Group", WPAS_DBUS_NEW_IFACE_P2P_GROUP, "o",
3529 wpas_dbus_getter_p2p_group,
3532 { "Role", WPAS_DBUS_NEW_IFACE_P2P_GROUP, "s",
3533 wpas_dbus_getter_p2p_role,
3536 { "SSID", WPAS_DBUS_NEW_IFACE_P2P_GROUP, "ay",
3537 wpas_dbus_getter_p2p_group_ssid,
3540 { "BSSID", WPAS_DBUS_NEW_IFACE_P2P_GROUP, "ay",
3541 wpas_dbus_getter_p2p_group_bssid,
3544 { "Frequency", WPAS_DBUS_NEW_IFACE_P2P_GROUP, "q",
3545 wpas_dbus_getter_p2p_group_frequency,
3548 { "Passphrase", WPAS_DBUS_NEW_IFACE_P2P_GROUP, "s",
3549 wpas_dbus_getter_p2p_group_passphrase,
3552 { "PSK", WPAS_DBUS_NEW_IFACE_P2P_GROUP, "ay",
3553 wpas_dbus_getter_p2p_group_psk,
3556 { "WPSVendorExtensions", WPAS_DBUS_NEW_IFACE_P2P_GROUP, "aay",
3557 wpas_dbus_getter_p2p_group_vendor_ext,
3558 wpas_dbus_setter_p2p_group_vendor_ext
3560 { NULL, NULL, NULL, NULL, NULL }
3563 static const struct wpa_dbus_signal_desc wpas_dbus_p2p_group_signals[] = {
3564 { "PeerJoined", WPAS_DBUS_NEW_IFACE_P2P_GROUP,
3566 { "peer", "o", ARG_OUT },
3570 { "PeerDisconnected", WPAS_DBUS_NEW_IFACE_P2P_GROUP,
3572 { "peer", "o", ARG_OUT },
3576 { NULL, NULL, { END_ARGS } }
3580 * wpas_dbus_register_p2p_group - Register a p2p group object with dbus
3581 * @wpa_s: wpa_supplicant interface structure
3582 * @ssid: SSID struct
3583 * Returns: 0 on success, -1 on failure
3585 * Registers p2p group representing object with dbus
3587 void wpas_dbus_register_p2p_group(struct wpa_supplicant *wpa_s,
3588 struct wpa_ssid *ssid)
3590 struct wpas_dbus_priv *ctrl_iface;
3591 struct wpa_dbus_object_desc *obj_desc;
3592 char group_obj_path[WPAS_DBUS_OBJECT_PATH_MAX];
3594 /* Do nothing if the control interface is not turned on */
3595 if (wpa_s == NULL || wpa_s->global == NULL)
3598 ctrl_iface = wpa_s->global->dbus;
3599 if (ctrl_iface == NULL)
3602 if (wpa_s->dbus_groupobj_path) {
3603 wpa_printf(MSG_INFO, "%s: Group object '%s' already exists",
3604 __func__, wpa_s->dbus_groupobj_path);
3608 if (wpas_dbus_get_group_obj_path(wpa_s, ssid, group_obj_path) < 0)
3611 wpa_s->dbus_groupobj_path = os_strdup(group_obj_path);
3612 if (wpa_s->dbus_groupobj_path == NULL)
3615 wpa_printf(MSG_INFO, "dbus: Register group object '%s'",
3617 obj_desc = os_zalloc(sizeof(struct wpa_dbus_object_desc));
3619 wpa_printf(MSG_ERROR, "Not enough memory "
3620 "to create object description");
3624 wpas_dbus_register(obj_desc, wpa_s, NULL, NULL,
3625 wpas_dbus_p2p_group_properties,
3626 wpas_dbus_p2p_group_signals);
3628 if (wpa_dbus_register_object_per_iface(ctrl_iface, group_obj_path,
3629 wpa_s->ifname, obj_desc))
3635 if (wpa_s->dbus_groupobj_path) {
3636 os_free(wpa_s->dbus_groupobj_path);
3637 wpa_s->dbus_groupobj_path = NULL;
3640 free_dbus_object_desc(obj_desc);
3644 * wpas_dbus_unregister_p2p_group - Unregister a p2p group object from dbus
3645 * @wpa_s: wpa_supplicant interface structure
3646 * @ssid: network name of the p2p group started
3648 void wpas_dbus_unregister_p2p_group(struct wpa_supplicant *wpa_s,
3649 const struct wpa_ssid *ssid)
3651 struct wpas_dbus_priv *ctrl_iface;
3653 /* Do nothing if the control interface is not turned on */
3654 if (wpa_s == NULL || wpa_s->global == NULL)
3657 if (wpa_s->p2p_mgmt)
3658 wpa_s = wpa_s->parent;
3660 ctrl_iface = wpa_s->global->dbus;
3661 if (ctrl_iface == NULL)
3664 if (!wpa_s->dbus_groupobj_path) {
3665 wpa_printf(MSG_DEBUG,
3666 "%s: Group object '%s' already unregistered",
3667 __func__, wpa_s->dbus_groupobj_path);
3671 peer_groups_changed(wpa_s);
3673 wpa_printf(MSG_DEBUG, "dbus: Unregister group object '%s'",
3674 wpa_s->dbus_groupobj_path);
3676 wpa_dbus_unregister_object_per_iface(ctrl_iface,
3677 wpa_s->dbus_groupobj_path);
3679 os_free(wpa_s->dbus_groupobj_path);
3680 wpa_s->dbus_groupobj_path = NULL;
3683 static const struct wpa_dbus_property_desc
3684 wpas_dbus_persistent_group_properties[] = {
3685 { "Properties", WPAS_DBUS_NEW_IFACE_PERSISTENT_GROUP, "a{sv}",
3686 wpas_dbus_getter_persistent_group_properties,
3687 wpas_dbus_setter_persistent_group_properties
3689 { NULL, NULL, NULL, NULL, NULL }
3692 /* No signals intended for persistent group objects */
3695 * wpas_dbus_register_persistent_group - Register a configured(saved)
3696 * persistent group with dbus
3697 * @wpa_s: wpa_supplicant interface structure
3698 * @ssid: persistent group (still represented as a network within wpa)
3699 * configuration data
3700 * Returns: 0 on success, -1 on failure
3702 * Registers a persistent group representing object with dbus.
3704 int wpas_dbus_register_persistent_group(struct wpa_supplicant *wpa_s,
3705 struct wpa_ssid *ssid)
3707 struct wpas_dbus_priv *ctrl_iface;
3708 struct wpa_dbus_object_desc *obj_desc;
3709 struct network_handler_args *arg;
3710 char pgrp_obj_path[WPAS_DBUS_OBJECT_PATH_MAX];
3712 /* Do nothing if the control interface is not turned on */
3713 if (wpa_s == NULL || wpa_s->global == NULL)
3716 /* Make sure ssid is a persistent group */
3717 if (ssid->disabled != 2 && !ssid->p2p_persistent_group)
3718 return -1; /* should we return w/o complaining? */
3720 if (wpa_s->p2p_mgmt)
3721 wpa_s = wpa_s->parent;
3723 ctrl_iface = wpa_s->global->dbus;
3724 if (ctrl_iface == NULL)
3728 * Intentionally not coming up with different numbering scheme
3729 * for persistent groups.
3731 os_snprintf(pgrp_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
3732 "%s/" WPAS_DBUS_NEW_PERSISTENT_GROUPS_PART "/%u",
3733 wpa_s->dbus_new_path, ssid->id);
3735 wpa_printf(MSG_DEBUG, "dbus: Register persistent group object '%s'",
3737 obj_desc = os_zalloc(sizeof(struct wpa_dbus_object_desc));
3739 wpa_printf(MSG_ERROR, "dbus: Not enough memory to create "
3740 "object description");
3745 * Reusing the same context structure as that for networks
3746 * since these are represented using same data structure.
3748 /* allocate memory for handlers arguments */
3749 arg = os_zalloc(sizeof(struct network_handler_args));
3751 wpa_printf(MSG_ERROR, "dbus: Not enough memory to create "
3752 "arguments for method");
3759 wpas_dbus_register(obj_desc, arg, wpa_dbus_free, NULL,
3760 wpas_dbus_persistent_group_properties,
3763 if (wpa_dbus_register_object_per_iface(ctrl_iface, pgrp_obj_path,
3764 wpa_s->ifname, obj_desc))
3767 wpas_dbus_signal_persistent_group_added(wpa_s, ssid->id);
3772 free_dbus_object_desc(obj_desc);
3778 * wpas_dbus_unregister_persistent_group - Unregister a persistent_group
3780 * @wpa_s: wpa_supplicant interface structure
3782 * Returns: 0 on success, -1 on failure
3784 * Unregisters persistent group representing object from dbus
3786 * NOTE: There is a slight issue with the semantics here. While the
3787 * implementation simply means the persistent group is unloaded from memory,
3788 * it should not get interpreted as the group is actually being erased/removed
3789 * from persistent storage as well.
3791 int wpas_dbus_unregister_persistent_group(struct wpa_supplicant *wpa_s,
3794 struct wpas_dbus_priv *ctrl_iface;
3795 char pgrp_obj_path[WPAS_DBUS_OBJECT_PATH_MAX];
3798 /* Do nothing if the control interface is not turned on */
3799 if (wpa_s == NULL || wpa_s->global == NULL ||
3800 wpa_s->dbus_new_path == NULL)
3803 if (wpa_s->p2p_mgmt)
3804 wpa_s = wpa_s->parent;
3806 ctrl_iface = wpa_s->global->dbus;
3807 if (ctrl_iface == NULL)
3810 os_snprintf(pgrp_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
3811 "%s/" WPAS_DBUS_NEW_PERSISTENT_GROUPS_PART "/%u",
3812 wpa_s->dbus_new_path, nid);
3814 wpa_printf(MSG_DEBUG, "dbus: Unregister persistent group object '%s'",
3816 ret = wpa_dbus_unregister_object_per_iface(ctrl_iface, pgrp_obj_path);
3819 wpas_dbus_signal_persistent_group_removed(wpa_s, nid);
3824 #endif /* CONFIG_P2P */