2 * WPA Supplicant / dbus-based control interface
3 * Copyright (c) 2006, Dan Williams <dcbw@redhat.com> and Red Hat, Inc.
4 * Copyright (c) 2009-2010, Witold Sowa <witold.sowa@gmail.com>
5 * Copyright (c) 2009, Jouni Malinen <j@w1.fi>
7 * This software may be distributed under the terms of the BSD license.
8 * See README for more details.
14 #include "common/ieee802_11_defs.h"
16 #include "../config.h"
17 #include "../wpa_supplicant_i.h"
19 #include "../wpas_glue.h"
20 #include "dbus_new_helpers.h"
21 #include "dbus_dict_helpers.h"
23 #include "dbus_new_handlers.h"
24 #include "dbus_common_i.h"
25 #include "dbus_new_handlers_p2p.h"
27 #include "../p2p_supplicant.h"
29 #ifdef CONFIG_AP /* until needed by something else */
32 * NameOwnerChanged handling
34 * Some services we provide allow an application to register for
35 * a signal that it needs. While it can also unregister, we must
36 * be prepared for the case where the application simply crashes
37 * and thus doesn't clean up properly. The way to handle this in
38 * DBus is to register for the NameOwnerChanged signal which will
39 * signal an owner change to NULL if the peer closes the socket
40 * for whatever reason.
42 * Handle this signal via a filter function whenever necessary.
43 * The code below also handles refcounting in case in the future
44 * there will be multiple instances of this subscription scheme.
46 static const char wpas_dbus_noc_filter_str[] =
47 "interface=org.freedesktop.DBus,member=NameOwnerChanged";
50 static DBusHandlerResult noc_filter(DBusConnection *conn,
51 DBusMessage *message, void *data)
53 struct wpas_dbus_priv *priv = data;
55 if (dbus_message_get_type(message) != DBUS_MESSAGE_TYPE_SIGNAL)
56 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
58 if (dbus_message_is_signal(message, DBUS_INTERFACE_DBUS,
59 "NameOwnerChanged")) {
61 const char *prev_owner;
62 const char *new_owner;
64 struct wpa_supplicant *wpa_s;
66 dbus_error_init(&derr);
68 if (!dbus_message_get_args(message, &derr,
69 DBUS_TYPE_STRING, &name,
70 DBUS_TYPE_STRING, &prev_owner,
71 DBUS_TYPE_STRING, &new_owner,
73 /* Ignore this error */
74 dbus_error_free(&derr);
75 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
78 for (wpa_s = priv->global->ifaces; wpa_s; wpa_s = wpa_s->next)
80 if (wpa_s->preq_notify_peer != NULL &&
81 os_strcmp(name, wpa_s->preq_notify_peer) == 0 &&
82 (new_owner == NULL || os_strlen(new_owner) == 0)) {
83 /* probe request owner disconnected */
84 os_free(wpa_s->preq_notify_peer);
85 wpa_s->preq_notify_peer = NULL;
86 wpas_dbus_unsubscribe_noc(priv);
91 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
95 void wpas_dbus_subscribe_noc(struct wpas_dbus_priv *priv)
97 priv->dbus_noc_refcnt++;
98 if (priv->dbus_noc_refcnt > 1)
101 if (!dbus_connection_add_filter(priv->con, noc_filter, priv, NULL)) {
102 wpa_printf(MSG_ERROR, "dbus: failed to add filter");
106 dbus_bus_add_match(priv->con, wpas_dbus_noc_filter_str, NULL);
110 void wpas_dbus_unsubscribe_noc(struct wpas_dbus_priv *priv)
112 priv->dbus_noc_refcnt--;
113 if (priv->dbus_noc_refcnt > 0)
116 dbus_bus_remove_match(priv->con, wpas_dbus_noc_filter_str, NULL);
117 dbus_connection_remove_filter(priv->con, noc_filter, priv);
120 #endif /* CONFIG_AP */
124 * wpas_dbus_signal_interface - Send a interface related event signal
125 * @wpa_s: %wpa_supplicant network interface data
126 * @sig_name: signal name - InterfaceAdded or InterfaceRemoved
127 * @properties: Whether to add second argument with object properties
129 * Notify listeners about event related with interface
131 static void wpas_dbus_signal_interface(struct wpa_supplicant *wpa_s,
132 const char *sig_name, int properties)
134 struct wpas_dbus_priv *iface;
136 DBusMessageIter iter;
138 iface = wpa_s->global->dbus;
140 /* Do nothing if the control interface is not turned on */
144 msg = dbus_message_new_signal(WPAS_DBUS_NEW_PATH,
145 WPAS_DBUS_NEW_INTERFACE, sig_name);
149 dbus_message_iter_init_append(msg, &iter);
150 if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_OBJECT_PATH,
151 &wpa_s->dbus_new_path))
155 if (!wpa_dbus_get_object_properties(
156 iface, wpa_s->dbus_new_path,
157 WPAS_DBUS_NEW_IFACE_INTERFACE, &iter))
161 dbus_connection_send(iface->con, msg, NULL);
162 dbus_message_unref(msg);
166 wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
167 dbus_message_unref(msg);
172 * wpas_dbus_signal_interface_added - Send a interface created signal
173 * @wpa_s: %wpa_supplicant network interface data
175 * Notify listeners about creating new interface
177 static void wpas_dbus_signal_interface_added(struct wpa_supplicant *wpa_s)
179 wpas_dbus_signal_interface(wpa_s, "InterfaceAdded", TRUE);
184 * wpas_dbus_signal_interface_removed - Send a interface removed signal
185 * @wpa_s: %wpa_supplicant network interface data
187 * Notify listeners about removing interface
189 static void wpas_dbus_signal_interface_removed(struct wpa_supplicant *wpa_s)
191 wpas_dbus_signal_interface(wpa_s, "InterfaceRemoved", FALSE);
197 * wpas_dbus_signal_scan_done - send scan done signal
198 * @wpa_s: %wpa_supplicant network interface data
199 * @success: indicates if scanning succeed or failed
201 * Notify listeners about finishing a scan
203 void wpas_dbus_signal_scan_done(struct wpa_supplicant *wpa_s, int success)
205 struct wpas_dbus_priv *iface;
209 iface = wpa_s->global->dbus;
211 /* Do nothing if the control interface is not turned on */
215 msg = dbus_message_new_signal(wpa_s->dbus_new_path,
216 WPAS_DBUS_NEW_IFACE_INTERFACE,
221 succ = success ? TRUE : FALSE;
222 if (dbus_message_append_args(msg, DBUS_TYPE_BOOLEAN, &succ,
224 dbus_connection_send(iface->con, msg, NULL);
226 wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
227 dbus_message_unref(msg);
232 * wpas_dbus_signal_blob - Send a BSS related event signal
233 * @wpa_s: %wpa_supplicant network interface data
234 * @bss_obj_path: BSS object path
235 * @sig_name: signal name - BSSAdded or BSSRemoved
236 * @properties: Whether to add second argument with object properties
238 * Notify listeners about event related with BSS
240 static void wpas_dbus_signal_bss(struct wpa_supplicant *wpa_s,
241 const char *bss_obj_path,
242 const char *sig_name, int properties)
244 struct wpas_dbus_priv *iface;
246 DBusMessageIter iter;
248 iface = wpa_s->global->dbus;
250 /* Do nothing if the control interface is not turned on */
254 msg = dbus_message_new_signal(wpa_s->dbus_new_path,
255 WPAS_DBUS_NEW_IFACE_INTERFACE,
260 dbus_message_iter_init_append(msg, &iter);
261 if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_OBJECT_PATH,
266 if (!wpa_dbus_get_object_properties(iface, bss_obj_path,
267 WPAS_DBUS_NEW_IFACE_BSS,
272 dbus_connection_send(iface->con, msg, NULL);
273 dbus_message_unref(msg);
277 wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
278 dbus_message_unref(msg);
283 * wpas_dbus_signal_bss_added - Send a BSS added signal
284 * @wpa_s: %wpa_supplicant network interface data
285 * @bss_obj_path: new BSS object path
287 * Notify listeners about adding new BSS
289 static void wpas_dbus_signal_bss_added(struct wpa_supplicant *wpa_s,
290 const char *bss_obj_path)
292 wpas_dbus_signal_bss(wpa_s, bss_obj_path, "BSSAdded", TRUE);
297 * wpas_dbus_signal_bss_removed - Send a BSS removed signal
298 * @wpa_s: %wpa_supplicant network interface data
299 * @bss_obj_path: BSS object path
301 * Notify listeners about removing BSS
303 static void wpas_dbus_signal_bss_removed(struct wpa_supplicant *wpa_s,
304 const char *bss_obj_path)
306 wpas_dbus_signal_bss(wpa_s, bss_obj_path, "BSSRemoved", FALSE);
311 * wpas_dbus_signal_blob - Send a blob related event signal
312 * @wpa_s: %wpa_supplicant network interface data
314 * @sig_name: signal name - BlobAdded or BlobRemoved
316 * Notify listeners about event related with blob
318 static void wpas_dbus_signal_blob(struct wpa_supplicant *wpa_s,
319 const char *name, const char *sig_name)
321 struct wpas_dbus_priv *iface;
324 iface = wpa_s->global->dbus;
326 /* Do nothing if the control interface is not turned on */
330 msg = dbus_message_new_signal(wpa_s->dbus_new_path,
331 WPAS_DBUS_NEW_IFACE_INTERFACE,
336 if (dbus_message_append_args(msg, DBUS_TYPE_STRING, &name,
338 dbus_connection_send(iface->con, msg, NULL);
340 wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
341 dbus_message_unref(msg);
346 * wpas_dbus_signal_blob_added - Send a blob added signal
347 * @wpa_s: %wpa_supplicant network interface data
350 * Notify listeners about adding a new blob
352 void wpas_dbus_signal_blob_added(struct wpa_supplicant *wpa_s,
355 wpas_dbus_signal_blob(wpa_s, name, "BlobAdded");
360 * wpas_dbus_signal_blob_removed - Send a blob removed signal
361 * @wpa_s: %wpa_supplicant network interface data
364 * Notify listeners about removing blob
366 void wpas_dbus_signal_blob_removed(struct wpa_supplicant *wpa_s,
369 wpas_dbus_signal_blob(wpa_s, name, "BlobRemoved");
374 * wpas_dbus_signal_network - Send a network related event signal
375 * @wpa_s: %wpa_supplicant network interface data
376 * @id: new network id
377 * @sig_name: signal name - NetworkAdded, NetworkRemoved or NetworkSelected
378 * @properties: determines if add second argument with object properties
380 * Notify listeners about event related with configured network
382 static void wpas_dbus_signal_network(struct wpa_supplicant *wpa_s,
383 int id, const char *sig_name,
386 struct wpas_dbus_priv *iface;
388 DBusMessageIter iter;
389 char net_obj_path[WPAS_DBUS_OBJECT_PATH_MAX], *path;
391 iface = wpa_s->global->dbus;
393 /* Do nothing if the control interface is not turned on */
397 os_snprintf(net_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
398 "%s/" WPAS_DBUS_NEW_NETWORKS_PART "/%u",
399 wpa_s->dbus_new_path, id);
401 msg = dbus_message_new_signal(wpa_s->dbus_new_path,
402 WPAS_DBUS_NEW_IFACE_INTERFACE,
407 dbus_message_iter_init_append(msg, &iter);
409 if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_OBJECT_PATH,
414 if (!wpa_dbus_get_object_properties(
415 iface, net_obj_path, WPAS_DBUS_NEW_IFACE_NETWORK,
420 dbus_connection_send(iface->con, msg, NULL);
422 dbus_message_unref(msg);
426 wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
427 dbus_message_unref(msg);
432 * wpas_dbus_signal_network_added - Send a network added signal
433 * @wpa_s: %wpa_supplicant network interface data
434 * @id: new network id
436 * Notify listeners about adding new network
438 static void wpas_dbus_signal_network_added(struct wpa_supplicant *wpa_s,
441 wpas_dbus_signal_network(wpa_s, id, "NetworkAdded", TRUE);
446 * wpas_dbus_signal_network_removed - Send a network removed signal
447 * @wpa_s: %wpa_supplicant network interface data
450 * Notify listeners about removing a network
452 static void wpas_dbus_signal_network_removed(struct wpa_supplicant *wpa_s,
455 wpas_dbus_signal_network(wpa_s, id, "NetworkRemoved", FALSE);
460 * wpas_dbus_signal_network_selected - Send a network selected signal
461 * @wpa_s: %wpa_supplicant network interface data
464 * Notify listeners about selecting a network
466 void wpas_dbus_signal_network_selected(struct wpa_supplicant *wpa_s, int id)
468 wpas_dbus_signal_network(wpa_s, id, "NetworkSelected", FALSE);
473 * wpas_dbus_signal_network_request - Indicate that additional information
474 * (EAP password, etc.) is required to complete the association to this SSID
475 * @wpa_s: %wpa_supplicant network interface data
476 * @rtype: The specific additional information required
477 * @default_text: Optional description of required information
479 * Request additional information or passwords to complete an association
482 void wpas_dbus_signal_network_request(struct wpa_supplicant *wpa_s,
483 struct wpa_ssid *ssid,
484 enum wpa_ctrl_req_type rtype,
485 const char *default_txt)
487 struct wpas_dbus_priv *iface;
489 DBusMessageIter iter;
490 char net_obj_path[WPAS_DBUS_OBJECT_PATH_MAX];
491 const char *field, *txt = NULL, *net_ptr;
493 iface = wpa_s->global->dbus;
495 /* Do nothing if the control interface is not turned on */
499 field = wpa_supplicant_ctrl_req_to_string(rtype, default_txt, &txt);
503 msg = dbus_message_new_signal(wpa_s->dbus_new_path,
504 WPAS_DBUS_NEW_IFACE_INTERFACE,
509 os_snprintf(net_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
510 "%s/" WPAS_DBUS_NEW_NETWORKS_PART "/%u",
511 wpa_s->dbus_new_path, ssid->id);
512 net_ptr = &net_obj_path[0];
514 dbus_message_iter_init_append(msg, &iter);
515 if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_OBJECT_PATH,
518 if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &field))
520 if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &txt))
523 dbus_connection_send(iface->con, msg, NULL);
524 dbus_message_unref(msg);
528 wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
529 dbus_message_unref(msg);
534 * wpas_dbus_signal_network_enabled_changed - Signals Enabled property changes
535 * @wpa_s: %wpa_supplicant network interface data
536 * @ssid: configured network which Enabled property has changed
538 * Sends PropertyChanged signals containing new value of Enabled property
539 * for specified network
541 void wpas_dbus_signal_network_enabled_changed(struct wpa_supplicant *wpa_s,
542 struct wpa_ssid *ssid)
545 char path[WPAS_DBUS_OBJECT_PATH_MAX];
546 os_snprintf(path, WPAS_DBUS_OBJECT_PATH_MAX,
547 "%s/" WPAS_DBUS_NEW_NETWORKS_PART "/%d",
548 wpa_s->dbus_new_path, ssid->id);
550 wpa_dbus_mark_property_changed(wpa_s->global->dbus, path,
551 WPAS_DBUS_NEW_IFACE_NETWORK, "Enabled");
558 * wpas_dbus_signal_wps_event_success - Signals Success WPS event
559 * @wpa_s: %wpa_supplicant network interface data
561 * Sends Event dbus signal with name "success" and empty dict as arguments
563 void wpas_dbus_signal_wps_event_success(struct wpa_supplicant *wpa_s)
567 DBusMessageIter iter, dict_iter;
568 struct wpas_dbus_priv *iface;
569 char *key = "success";
571 iface = wpa_s->global->dbus;
573 /* Do nothing if the control interface is not turned on */
577 msg = dbus_message_new_signal(wpa_s->dbus_new_path,
578 WPAS_DBUS_NEW_IFACE_WPS, "Event");
582 dbus_message_iter_init_append(msg, &iter);
584 if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &key) ||
585 !wpa_dbus_dict_open_write(&iter, &dict_iter) ||
586 !wpa_dbus_dict_close_write(&iter, &dict_iter))
587 wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
589 dbus_connection_send(iface->con, msg, NULL);
591 dbus_message_unref(msg);
596 * wpas_dbus_signal_wps_event_fail - Signals Fail WPS event
597 * @wpa_s: %wpa_supplicant network interface data
599 * Sends Event dbus signal with name "fail" and dictionary containing
600 * "msg field with fail message number (int32) as arguments
602 void wpas_dbus_signal_wps_event_fail(struct wpa_supplicant *wpa_s,
603 struct wps_event_fail *fail)
607 DBusMessageIter iter, dict_iter;
608 struct wpas_dbus_priv *iface;
611 iface = wpa_s->global->dbus;
613 /* Do nothing if the control interface is not turned on */
617 msg = dbus_message_new_signal(wpa_s->dbus_new_path,
618 WPAS_DBUS_NEW_IFACE_WPS, "Event");
622 dbus_message_iter_init_append(msg, &iter);
624 if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &key) ||
625 !wpa_dbus_dict_open_write(&iter, &dict_iter) ||
626 !wpa_dbus_dict_append_int32(&dict_iter, "msg", fail->msg) ||
627 !wpa_dbus_dict_close_write(&iter, &dict_iter))
628 wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
630 dbus_connection_send(iface->con, msg, NULL);
632 dbus_message_unref(msg);
637 * wpas_dbus_signal_wps_event_m2d - Signals M2D WPS event
638 * @wpa_s: %wpa_supplicant network interface data
640 * Sends Event dbus signal with name "m2d" and dictionary containing
641 * fields of wps_event_m2d structure.
643 void wpas_dbus_signal_wps_event_m2d(struct wpa_supplicant *wpa_s,
644 struct wps_event_m2d *m2d)
648 DBusMessageIter iter, dict_iter;
649 struct wpas_dbus_priv *iface;
652 iface = wpa_s->global->dbus;
654 /* Do nothing if the control interface is not turned on */
658 msg = dbus_message_new_signal(wpa_s->dbus_new_path,
659 WPAS_DBUS_NEW_IFACE_WPS, "Event");
663 dbus_message_iter_init_append(msg, &iter);
665 if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &key) ||
666 !wpa_dbus_dict_open_write(&iter, &dict_iter) ||
667 !wpa_dbus_dict_append_uint16(&dict_iter, "config_methods",
668 m2d->config_methods) ||
669 !wpa_dbus_dict_append_byte_array(&dict_iter, "manufacturer",
670 (const char *) m2d->manufacturer,
671 m2d->manufacturer_len) ||
672 !wpa_dbus_dict_append_byte_array(&dict_iter, "model_name",
673 (const char *) m2d->model_name,
674 m2d->model_name_len) ||
675 !wpa_dbus_dict_append_byte_array(&dict_iter, "model_number",
676 (const char *) m2d->model_number,
677 m2d->model_number_len) ||
678 !wpa_dbus_dict_append_byte_array(&dict_iter, "serial_number",
681 m2d->serial_number_len) ||
682 !wpa_dbus_dict_append_byte_array(&dict_iter, "dev_name",
683 (const char *) m2d->dev_name,
684 m2d->dev_name_len) ||
685 !wpa_dbus_dict_append_byte_array(&dict_iter, "primary_dev_type",
687 m2d->primary_dev_type, 8) ||
688 !wpa_dbus_dict_append_uint16(&dict_iter, "config_error",
689 m2d->config_error) ||
690 !wpa_dbus_dict_append_uint16(&dict_iter, "dev_password_id",
691 m2d->dev_password_id) ||
692 !wpa_dbus_dict_close_write(&iter, &dict_iter))
693 wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
695 dbus_connection_send(iface->con, msg, NULL);
697 dbus_message_unref(msg);
702 * wpas_dbus_signal_wps_cred - Signals new credentials
703 * @wpa_s: %wpa_supplicant network interface data
705 * Sends signal with credentials in directory argument
707 void wpas_dbus_signal_wps_cred(struct wpa_supplicant *wpa_s,
708 const struct wps_credential *cred)
711 DBusMessageIter iter, dict_iter;
712 struct wpas_dbus_priv *iface;
713 char *auth_type[5]; /* we have five possible authentication types */
715 char *encr_type[3]; /* we have three possible encryption types */
718 iface = wpa_s->global->dbus;
720 /* Do nothing if the control interface is not turned on */
724 msg = dbus_message_new_signal(wpa_s->dbus_new_path,
725 WPAS_DBUS_NEW_IFACE_WPS,
730 dbus_message_iter_init_append(msg, &iter);
731 if (!wpa_dbus_dict_open_write(&iter, &dict_iter))
734 if (cred->auth_type & WPS_AUTH_OPEN)
735 auth_type[at_num++] = "open";
736 if (cred->auth_type & WPS_AUTH_WPAPSK)
737 auth_type[at_num++] = "wpa-psk";
738 if (cred->auth_type & WPS_AUTH_WPA)
739 auth_type[at_num++] = "wpa-eap";
740 if (cred->auth_type & WPS_AUTH_WPA2)
741 auth_type[at_num++] = "wpa2-eap";
742 if (cred->auth_type & WPS_AUTH_WPA2PSK)
743 auth_type[at_num++] = "wpa2-psk";
745 if (cred->encr_type & WPS_ENCR_NONE)
746 encr_type[et_num++] = "none";
747 if (cred->encr_type & WPS_ENCR_TKIP)
748 encr_type[et_num++] = "tkip";
749 if (cred->encr_type & WPS_ENCR_AES)
750 encr_type[et_num++] = "aes";
752 if (wpa_s->current_ssid) {
753 if (!wpa_dbus_dict_append_byte_array(
755 (const char *) wpa_s->current_ssid->bssid,
760 if (!wpa_dbus_dict_append_byte_array(&dict_iter, "SSID",
761 (const char *) cred->ssid,
763 !wpa_dbus_dict_append_string_array(&dict_iter, "AuthType",
764 (const char **) auth_type,
766 !wpa_dbus_dict_append_string_array(&dict_iter, "EncrType",
767 (const char **) encr_type,
769 !wpa_dbus_dict_append_byte_array(&dict_iter, "Key",
770 (const char *) cred->key,
772 !wpa_dbus_dict_append_uint32(&dict_iter, "KeyIndex",
774 !wpa_dbus_dict_close_write(&iter, &dict_iter))
777 dbus_connection_send(iface->con, msg, NULL);
780 dbus_message_unref(msg);
783 #endif /* CONFIG_WPS */
785 void wpas_dbus_signal_certification(struct wpa_supplicant *wpa_s,
786 int depth, const char *subject,
787 const char *cert_hash,
788 const struct wpabuf *cert)
790 struct wpas_dbus_priv *iface;
792 DBusMessageIter iter, dict_iter;
794 iface = wpa_s->global->dbus;
796 /* Do nothing if the control interface is not turned on */
800 msg = dbus_message_new_signal(wpa_s->dbus_new_path,
801 WPAS_DBUS_NEW_IFACE_INTERFACE,
806 dbus_message_iter_init_append(msg, &iter);
807 if (!wpa_dbus_dict_open_write(&iter, &dict_iter))
810 if (!wpa_dbus_dict_append_uint32(&dict_iter, "depth", depth) ||
811 !wpa_dbus_dict_append_string(&dict_iter, "subject", subject))
815 !wpa_dbus_dict_append_string(&dict_iter, "cert_hash", cert_hash))
819 !wpa_dbus_dict_append_byte_array(&dict_iter, "cert",
824 if (!wpa_dbus_dict_close_write(&iter, &dict_iter))
827 dbus_connection_send(iface->con, msg, NULL);
830 dbus_message_unref(msg);
834 void wpas_dbus_signal_eap_status(struct wpa_supplicant *wpa_s,
835 const char *status, const char *parameter)
837 struct wpas_dbus_priv *iface;
839 DBusMessageIter iter;
841 iface = wpa_s->global->dbus;
843 /* Do nothing if the control interface is not turned on */
847 msg = dbus_message_new_signal(wpa_s->dbus_new_path,
848 WPAS_DBUS_NEW_IFACE_INTERFACE,
853 dbus_message_iter_init_append(msg, &iter);
855 if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &status)
857 !dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING,
861 dbus_connection_send(iface->con, msg, NULL);
864 dbus_message_unref(msg);
869 * wpas_dbus_signal_sta - Send a station related event signal
870 * @wpa_s: %wpa_supplicant network interface data
871 * @sta: station mac address
872 * @sig_name: signal name - StaAuthorized or StaDeauthorized
874 * Notify listeners about event related with station
876 static void wpas_dbus_signal_sta(struct wpa_supplicant *wpa_s,
877 const u8 *sta, const char *sig_name)
879 struct wpas_dbus_priv *iface;
881 char sta_mac[WPAS_DBUS_OBJECT_PATH_MAX];
884 os_snprintf(sta_mac, WPAS_DBUS_OBJECT_PATH_MAX, MACSTR, MAC2STR(sta));
887 iface = wpa_s->global->dbus;
889 /* Do nothing if the control interface is not turned on */
893 msg = dbus_message_new_signal(wpa_s->dbus_new_path,
894 WPAS_DBUS_NEW_IFACE_INTERFACE, sig_name);
898 if (dbus_message_append_args(msg, DBUS_TYPE_STRING, &dev_mac,
900 dbus_connection_send(iface->con, msg, NULL);
902 wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
903 dbus_message_unref(msg);
905 wpa_printf(MSG_DEBUG, "dbus: Station MAC address '%s' '%s'",
911 * wpas_dbus_signal_sta_authorized - Send a STA authorized signal
912 * @wpa_s: %wpa_supplicant network interface data
913 * @sta: station mac address
915 * Notify listeners a new station has been authorized
917 void wpas_dbus_signal_sta_authorized(struct wpa_supplicant *wpa_s,
920 wpas_dbus_signal_sta(wpa_s, sta, "StaAuthorized");
925 * wpas_dbus_signal_sta_deauthorized - Send a STA deauthorized signal
926 * @wpa_s: %wpa_supplicant network interface data
927 * @sta: station mac address
929 * Notify listeners a station has been deauthorized
931 void wpas_dbus_signal_sta_deauthorized(struct wpa_supplicant *wpa_s,
934 wpas_dbus_signal_sta(wpa_s, sta, "StaDeauthorized");
941 * wpas_dbus_signal_p2p_group_removed - Signals P2P group was removed
942 * @wpa_s: %wpa_supplicant network interface data
943 * @role: role of this device (client or GO)
944 * Sends signal with i/f name and role as string arguments
946 void wpas_dbus_signal_p2p_group_removed(struct wpa_supplicant *wpa_s,
951 DBusMessageIter iter, dict_iter;
952 struct wpas_dbus_priv *iface = wpa_s->global->dbus;
954 /* Do nothing if the control interface is not turned on */
958 if (!wpa_s->dbus_groupobj_path)
961 msg = dbus_message_new_signal(wpa_s->parent->dbus_new_path,
962 WPAS_DBUS_NEW_IFACE_P2PDEVICE,
967 dbus_message_iter_init_append(msg, &iter);
968 if (!wpa_dbus_dict_open_write(&iter, &dict_iter))
971 if (!wpa_dbus_dict_append_object_path(&dict_iter,
973 wpa_s->dbus_new_path))
976 if (!wpa_dbus_dict_append_string(&dict_iter, "role", role))
979 if (!wpa_dbus_dict_append_object_path(&dict_iter, "group_object",
980 wpa_s->dbus_groupobj_path) ||
981 !wpa_dbus_dict_close_write(&iter, &dict_iter))
985 dbus_connection_send(iface->con, msg, NULL);
989 wpa_printf(MSG_ERROR,
990 "dbus: Failed to construct GroupFinished");
992 dbus_message_unref(msg);
997 * wpas_dbus_signal_p2p_provision_discovery - Signals various PD events
999 * @dev_addr - who sent the request or responded to our request.
1000 * @request - Will be 1 if request, 0 for response.
1001 * @status - valid only in case of response
1002 * @config_methods - wps config methods
1003 * @generated_pin - pin to be displayed in case of WPS_CONFIG_DISPLAY method
1005 * Sends following provision discovery related events:
1006 * ProvisionDiscoveryRequestDisplayPin
1007 * ProvisionDiscoveryResponseDisplayPin
1008 * ProvisionDiscoveryRequestEnterPin
1009 * ProvisionDiscoveryResponseEnterPin
1010 * ProvisionDiscoveryPBCRequest
1011 * ProvisionDiscoveryPBCResponse
1014 * ProvisionDiscoveryFailure (timeout case)
1016 void wpas_dbus_signal_p2p_provision_discovery(struct wpa_supplicant *wpa_s,
1017 const u8 *dev_addr, int request,
1018 enum p2p_prov_disc_status status,
1020 unsigned int generated_pin)
1023 DBusMessageIter iter;
1024 struct wpas_dbus_priv *iface;
1027 char peer_obj_path[WPAS_DBUS_OBJECT_PATH_MAX], *path;
1029 char pin[9], *p_pin = NULL;
1031 iface = wpa_s->global->dbus;
1033 /* Do nothing if the control interface is not turned on */
1037 if (request || !status) {
1038 if (config_methods & WPS_CONFIG_DISPLAY)
1040 "ProvisionDiscoveryRequestDisplayPin" :
1041 "ProvisionDiscoveryResponseEnterPin";
1042 else if (config_methods & WPS_CONFIG_KEYPAD)
1044 "ProvisionDiscoveryRequestEnterPin" :
1045 "ProvisionDiscoveryResponseDisplayPin";
1046 else if (config_methods & WPS_CONFIG_PUSHBUTTON)
1047 _signal = request ? "ProvisionDiscoveryPBCRequest" :
1048 "ProvisionDiscoveryPBCResponse";
1050 return; /* Unknown or un-supported method */
1051 } else if (!request && status)
1052 /* Explicit check for failure response */
1053 _signal = "ProvisionDiscoveryFailure";
1055 add_pin = ((request && (config_methods & WPS_CONFIG_DISPLAY)) ||
1056 (!request && !status &&
1057 (config_methods & WPS_CONFIG_KEYPAD)));
1060 os_snprintf(pin, sizeof(pin), "%08d", generated_pin);
1064 msg = dbus_message_new_signal(wpa_s->dbus_new_path,
1065 WPAS_DBUS_NEW_IFACE_P2PDEVICE, _signal);
1069 /* Check if this is a known peer */
1070 if (!p2p_peer_known(wpa_s->global->p2p, dev_addr))
1073 os_snprintf(peer_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
1074 "%s/" WPAS_DBUS_NEW_P2P_PEERS_PART "/"
1076 wpa_s->dbus_new_path, MAC2STR(dev_addr));
1078 path = peer_obj_path;
1080 dbus_message_iter_init_append(msg, &iter);
1082 if (!dbus_message_iter_append_basic(&iter,
1083 DBUS_TYPE_OBJECT_PATH,
1087 if (!request && status)
1088 /* Attach status to ProvisionDiscoveryFailure */
1089 error_ret = !dbus_message_iter_append_basic(&iter,
1093 error_ret = (add_pin &&
1094 !dbus_message_iter_append_basic(&iter,
1100 dbus_connection_send(iface->con, msg, NULL);
1102 wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
1104 dbus_message_unref(msg);
1108 void wpas_dbus_signal_p2p_go_neg_req(struct wpa_supplicant *wpa_s,
1109 const u8 *src, u16 dev_passwd_id)
1112 DBusMessageIter iter;
1113 struct wpas_dbus_priv *iface;
1114 char peer_obj_path[WPAS_DBUS_OBJECT_PATH_MAX], *path;
1116 iface = wpa_s->global->dbus;
1118 /* Do nothing if the control interface is not turned on */
1122 os_snprintf(peer_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
1123 "%s/" WPAS_DBUS_NEW_P2P_PEERS_PART "/" COMPACT_MACSTR,
1124 wpa_s->dbus_new_path, MAC2STR(src));
1125 path = peer_obj_path;
1127 msg = dbus_message_new_signal(wpa_s->dbus_new_path,
1128 WPAS_DBUS_NEW_IFACE_P2PDEVICE,
1129 "GONegotiationRequest");
1133 dbus_message_iter_init_append(msg, &iter);
1135 if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_OBJECT_PATH,
1137 !dbus_message_iter_append_basic(&iter, DBUS_TYPE_UINT16,
1139 wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
1141 dbus_connection_send(iface->con, msg, NULL);
1143 dbus_message_unref(msg);
1147 static int wpas_dbus_get_group_obj_path(struct wpa_supplicant *wpa_s,
1148 const struct wpa_ssid *ssid,
1149 char *group_obj_path)
1153 if (os_memcmp(ssid->ssid, P2P_WILDCARD_SSID, P2P_WILDCARD_SSID_LEN))
1156 os_memcpy(group_name, ssid->ssid + P2P_WILDCARD_SSID_LEN, 2);
1157 group_name[2] = '\0';
1159 os_snprintf(group_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
1160 "%s/" WPAS_DBUS_NEW_P2P_GROUPS_PART "/%s",
1161 wpa_s->dbus_new_path, group_name);
1167 struct group_changed_data {
1168 struct wpa_supplicant *wpa_s;
1169 struct p2p_peer_info *info;
1173 static int match_group_where_peer_is_client(struct p2p_group *group,
1176 struct group_changed_data *data = user_data;
1177 const struct p2p_group_config *cfg;
1178 struct wpa_supplicant *wpa_s_go;
1180 if (!p2p_group_is_client_connected(group, data->info->p2p_device_addr))
1183 cfg = p2p_group_get_config(group);
1185 wpa_s_go = wpas_get_p2p_go_iface(data->wpa_s, cfg->ssid,
1187 if (wpa_s_go != NULL && wpa_s_go == data->wpa_s) {
1188 wpas_dbus_signal_peer_groups_changed(
1189 data->wpa_s->parent, data->info->p2p_device_addr);
1197 static void signal_peer_groups_changed(struct p2p_peer_info *info,
1200 struct group_changed_data *data = user_data;
1201 struct wpa_supplicant *wpa_s_go;
1203 wpa_s_go = wpas_get_p2p_client_iface(data->wpa_s,
1204 info->p2p_device_addr);
1205 if (wpa_s_go != NULL && wpa_s_go == data->wpa_s) {
1206 wpas_dbus_signal_peer_groups_changed(data->wpa_s->parent,
1207 info->p2p_device_addr);
1212 p2p_loop_on_all_groups(data->wpa_s->global->p2p,
1213 match_group_where_peer_is_client, data);
1218 static void peer_groups_changed(struct wpa_supplicant *wpa_s)
1220 struct group_changed_data data;
1222 os_memset(&data, 0, sizeof(data));
1225 p2p_loop_on_known_peers(wpa_s->global->p2p,
1226 signal_peer_groups_changed, &data);
1231 * wpas_dbus_signal_p2p_group_started - Signals P2P group has
1232 * started. Emitted when a group is successfully started
1233 * irrespective of the role (client/GO) of the current device
1235 * @wpa_s: %wpa_supplicant network interface data
1236 * @ssid: SSID object
1237 * @client: this device is P2P client
1238 * @network_id: network id of the group started, use instead of ssid->id
1239 * to account for persistent groups
1241 void wpas_dbus_signal_p2p_group_started(struct wpa_supplicant *wpa_s,
1242 const struct wpa_ssid *ssid,
1243 int client, int network_id)
1246 DBusMessageIter iter, dict_iter;
1247 struct wpas_dbus_priv *iface;
1249 iface = wpa_s->parent->global->dbus;
1251 /* Do nothing if the control interface is not turned on */
1255 if (wpa_s->dbus_groupobj_path == NULL)
1258 /* New interface has been created for this group */
1259 msg = dbus_message_new_signal(wpa_s->parent->dbus_new_path,
1260 WPAS_DBUS_NEW_IFACE_P2PDEVICE,
1265 dbus_message_iter_init_append(msg, &iter);
1266 if (!wpa_dbus_dict_open_write(&iter, &dict_iter))
1270 * In case the device supports creating a separate interface the
1271 * DBus client will need to know the object path for the interface
1272 * object this group was created on, so include it here.
1274 if (!wpa_dbus_dict_append_object_path(&dict_iter,
1276 wpa_s->dbus_new_path))
1279 if (!wpa_dbus_dict_append_string(&dict_iter, "role",
1280 client ? "client" : "GO"))
1283 if (!wpa_dbus_dict_append_object_path(&dict_iter, "group_object",
1284 wpa_s->dbus_groupobj_path) ||
1285 !wpa_dbus_dict_close_write(&iter, &dict_iter))
1288 dbus_connection_send(iface->con, msg, NULL);
1291 peer_groups_changed(wpa_s);
1294 dbus_message_unref(msg);
1300 * Method to emit GONegotiation Success or Failure signals based
1302 * @status: Status of the GO neg request. 0 for success, other for errors.
1304 void wpas_dbus_signal_p2p_go_neg_resp(struct wpa_supplicant *wpa_s,
1305 struct p2p_go_neg_results *res)
1308 DBusMessageIter iter, dict_iter;
1309 DBusMessageIter iter_dict_entry, iter_dict_val, iter_dict_array;
1310 struct wpas_dbus_priv *iface;
1311 char peer_obj_path[WPAS_DBUS_OBJECT_PATH_MAX], *path;
1312 dbus_int32_t freqs[P2P_MAX_CHANNELS];
1313 dbus_int32_t *f_array = freqs;
1316 iface = wpa_s->global->dbus;
1318 os_memset(freqs, 0, sizeof(freqs));
1319 /* Do nothing if the control interface is not turned on */
1323 os_snprintf(peer_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
1324 "%s/" WPAS_DBUS_NEW_P2P_PEERS_PART "/" COMPACT_MACSTR,
1325 wpa_s->dbus_new_path, MAC2STR(res->peer_device_addr));
1326 path = peer_obj_path;
1328 msg = dbus_message_new_signal(wpa_s->dbus_new_path,
1329 WPAS_DBUS_NEW_IFACE_P2PDEVICE,
1330 res->status ? "GONegotiationFailure" :
1331 "GONegotiationSuccess");
1335 dbus_message_iter_init_append(msg, &iter);
1336 if (!wpa_dbus_dict_open_write(&iter, &dict_iter))
1338 if (!wpa_dbus_dict_append_object_path(&dict_iter, "peer_object",
1340 !wpa_dbus_dict_append_int32(&dict_iter, "status", res->status))
1345 int freq_list_num = 0;
1348 if (!wpa_dbus_dict_append_byte_array(
1349 &dict_iter, "passphrase",
1350 (const char *) res->passphrase,
1351 sizeof(res->passphrase)))
1355 if (!wpa_dbus_dict_append_string(&dict_iter, "role_go",
1356 res->role_go ? "GO" :
1358 !wpa_dbus_dict_append_int32(&dict_iter, "frequency",
1360 !wpa_dbus_dict_append_byte_array(&dict_iter, "ssid",
1361 (const char *) res->ssid,
1363 !wpa_dbus_dict_append_byte_array(&dict_iter,
1366 res->peer_device_addr,
1368 !wpa_dbus_dict_append_byte_array(&dict_iter,
1369 "peer_interface_addr",
1371 res->peer_interface_addr,
1373 !wpa_dbus_dict_append_string(&dict_iter, "wps_method",
1374 p2p_wps_method_text(
1378 for (i = 0; i < P2P_MAX_CHANNELS; i++) {
1379 if (res->freq_list[i]) {
1380 freqs[i] = res->freq_list[i];
1385 if (!wpa_dbus_dict_begin_array(&dict_iter,
1387 DBUS_TYPE_INT32_AS_STRING,
1393 if (!dbus_message_iter_append_fixed_array(&iter_dict_array,
1399 if (!wpa_dbus_dict_end_array(&dict_iter,
1405 if (!wpa_dbus_dict_append_int32(&dict_iter, "persistent_group",
1406 res->persistent_group) ||
1407 !wpa_dbus_dict_append_uint32(&dict_iter,
1408 "peer_config_timeout",
1409 res->peer_config_timeout))
1413 if (!wpa_dbus_dict_close_write(&iter, &dict_iter))
1416 dbus_connection_send(iface->con, msg, NULL);
1418 dbus_message_unref(msg);
1424 * Method to emit Invitation Result signal based on status and
1426 * @status: Status of the Invite request. 0 for success, other
1428 * @bssid : Basic Service Set Identifier
1430 void wpas_dbus_signal_p2p_invitation_result(struct wpa_supplicant *wpa_s,
1431 int status, const u8 *bssid)
1434 DBusMessageIter iter, dict_iter;
1435 struct wpas_dbus_priv *iface;
1437 wpa_printf(MSG_DEBUG, "%s", __func__);
1439 iface = wpa_s->global->dbus;
1440 /* Do nothing if the control interface is not turned on */
1444 msg = dbus_message_new_signal(wpa_s->dbus_new_path,
1445 WPAS_DBUS_NEW_IFACE_P2PDEVICE,
1446 "InvitationResult");
1451 dbus_message_iter_init_append(msg, &iter);
1452 if (!wpa_dbus_dict_open_write(&iter, &dict_iter))
1455 if (!wpa_dbus_dict_append_int32(&dict_iter, "status", status))
1458 if (!wpa_dbus_dict_append_byte_array(&dict_iter, "BSSID",
1459 (const char *) bssid,
1463 if (!wpa_dbus_dict_close_write(&iter, &dict_iter))
1466 dbus_connection_send(iface->con, msg, NULL);
1469 dbus_message_unref(msg);
1475 * Method to emit a signal for a peer joining the group.
1476 * The signal will carry path to the group member object
1477 * constructed using p2p i/f addr used for connecting.
1479 * @wpa_s: %wpa_supplicant network interface data
1480 * @peer_addr: P2P Device Address of the peer joining the group
1482 void wpas_dbus_signal_p2p_peer_joined(struct wpa_supplicant *wpa_s,
1483 const u8 *peer_addr)
1485 struct wpas_dbus_priv *iface;
1487 DBusMessageIter iter;
1488 char peer_obj_path[WPAS_DBUS_OBJECT_PATH_MAX], *path;
1490 iface = wpa_s->global->dbus;
1492 /* Do nothing if the control interface is not turned on */
1496 if (!wpa_s->dbus_groupobj_path)
1499 os_snprintf(peer_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
1500 "%s/" WPAS_DBUS_NEW_P2P_PEERS_PART "/"
1502 wpa_s->parent->dbus_new_path, MAC2STR(peer_addr));
1504 msg = dbus_message_new_signal(wpa_s->dbus_groupobj_path,
1505 WPAS_DBUS_NEW_IFACE_P2P_GROUP,
1510 dbus_message_iter_init_append(msg, &iter);
1511 path = peer_obj_path;
1512 if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_OBJECT_PATH,
1516 dbus_connection_send(iface->con, msg, NULL);
1517 dbus_message_unref(msg);
1519 wpas_dbus_signal_peer_groups_changed(wpa_s->parent, peer_addr);
1524 wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
1525 dbus_message_unref(msg);
1531 * Method to emit a signal for a peer disconnecting the group.
1532 * The signal will carry path to the group member object
1533 * constructed using the P2P Device Address of the peer.
1535 * @wpa_s: %wpa_supplicant network interface data
1536 * @peer_addr: P2P Device Address of the peer joining the group
1538 void wpas_dbus_signal_p2p_peer_disconnected(struct wpa_supplicant *wpa_s,
1539 const u8 *peer_addr)
1541 struct wpas_dbus_priv *iface;
1543 DBusMessageIter iter;
1544 char peer_obj_path[WPAS_DBUS_OBJECT_PATH_MAX], *path;
1546 iface = wpa_s->global->dbus;
1548 /* Do nothing if the control interface is not turned on */
1552 if (!wpa_s->dbus_groupobj_path)
1555 os_snprintf(peer_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
1556 "%s/" WPAS_DBUS_NEW_P2P_PEERS_PART "/"
1558 wpa_s->dbus_groupobj_path, MAC2STR(peer_addr));
1560 msg = dbus_message_new_signal(wpa_s->dbus_groupobj_path,
1561 WPAS_DBUS_NEW_IFACE_P2P_GROUP,
1562 "PeerDisconnected");
1566 dbus_message_iter_init_append(msg, &iter);
1567 path = peer_obj_path;
1568 if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_OBJECT_PATH,
1572 dbus_connection_send(iface->con, msg, NULL);
1573 dbus_message_unref(msg);
1575 wpas_dbus_signal_peer_groups_changed(wpa_s->parent, peer_addr);
1580 wpa_printf(MSG_ERROR, "dbus: Failed to construct PeerDisconnected "
1582 dbus_message_unref(msg);
1588 * Method to emit a signal for a service discovery request.
1589 * The signal will carry station address, frequency, dialog token,
1590 * update indicator and it tlvs
1592 * @wpa_s: %wpa_supplicant network interface data
1593 * @sa: station addr (p2p i/f) of the peer
1594 * @dialog_token: service discovery request dialog token
1595 * @update_indic: service discovery request update indicator
1596 * @tlvs: service discovery request genrated byte array of tlvs
1597 * @tlvs_len: service discovery request tlvs length
1599 void wpas_dbus_signal_p2p_sd_request(struct wpa_supplicant *wpa_s,
1600 int freq, const u8 *sa, u8 dialog_token,
1601 u16 update_indic, const u8 *tlvs,
1605 DBusMessageIter iter, dict_iter;
1606 struct wpas_dbus_priv *iface;
1607 char peer_obj_path[WPAS_DBUS_OBJECT_PATH_MAX], *path;
1608 iface = wpa_s->global->dbus;
1610 /* Do nothing if the control interface is not turned on */
1614 msg = dbus_message_new_signal(wpa_s->dbus_new_path,
1615 WPAS_DBUS_NEW_IFACE_P2PDEVICE,
1616 "ServiceDiscoveryRequest");
1620 /* Check if this is a known peer */
1621 if (!p2p_peer_known(wpa_s->global->p2p, sa))
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))
1635 if (!wpa_dbus_dict_append_object_path(&dict_iter, "peer_object",
1637 !wpa_dbus_dict_append_int32(&dict_iter, "frequency", freq) ||
1638 !wpa_dbus_dict_append_int32(&dict_iter, "dialog_token",
1640 !wpa_dbus_dict_append_uint16(&dict_iter, "update_indicator",
1642 !wpa_dbus_dict_append_byte_array(&dict_iter, "tlvs",
1643 (const char *) tlvs,
1645 !wpa_dbus_dict_close_write(&iter, &dict_iter))
1648 dbus_connection_send(iface->con, msg, NULL);
1649 dbus_message_unref(msg);
1652 wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
1653 dbus_message_unref(msg);
1659 * Method to emit a signal for a service discovery response.
1660 * The signal will carry station address, update indicator and it
1663 * @wpa_s: %wpa_supplicant network interface data
1664 * @sa: station addr (p2p i/f) of the peer
1665 * @update_indic: service discovery request update indicator
1666 * @tlvs: service discovery request genrated byte array of tlvs
1667 * @tlvs_len: service discovery request tlvs length
1669 void wpas_dbus_signal_p2p_sd_response(struct wpa_supplicant *wpa_s,
1670 const u8 *sa, u16 update_indic,
1671 const u8 *tlvs, size_t tlvs_len)
1674 DBusMessageIter iter, dict_iter;
1675 struct wpas_dbus_priv *iface;
1676 char peer_obj_path[WPAS_DBUS_OBJECT_PATH_MAX], *path;
1677 iface = wpa_s->global->dbus;
1679 /* Do nothing if the control interface is not turned on */
1683 msg = dbus_message_new_signal(wpa_s->dbus_new_path,
1684 WPAS_DBUS_NEW_IFACE_P2PDEVICE,
1685 "ServiceDiscoveryResponse");
1689 /* Check if this is a known peer */
1690 if (!p2p_peer_known(wpa_s->global->p2p, sa))
1693 os_snprintf(peer_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
1694 "%s/" WPAS_DBUS_NEW_P2P_PEERS_PART "/"
1695 COMPACT_MACSTR, wpa_s->dbus_new_path, MAC2STR(sa));
1697 path = peer_obj_path;
1699 dbus_message_iter_init_append(msg, &iter);
1700 if (!wpa_dbus_dict_open_write(&iter, &dict_iter))
1703 if (!wpa_dbus_dict_append_object_path(&dict_iter, "peer_object",
1705 !wpa_dbus_dict_append_uint16(&dict_iter, "update_indicator",
1707 !wpa_dbus_dict_append_byte_array(&dict_iter, "tlvs",
1708 (const char *) tlvs,
1710 !wpa_dbus_dict_close_write(&iter, &dict_iter))
1714 dbus_connection_send(iface->con, msg, NULL);
1715 dbus_message_unref(msg);
1718 wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
1719 dbus_message_unref(msg);
1723 * wpas_dbus_signal_persistent_group - Send a persistent group related
1725 * @wpa_s: %wpa_supplicant network interface data
1726 * @id: new persistent group id
1727 * @sig_name: signal name - PersistentGroupAdded, PersistentGroupRemoved
1728 * @properties: determines if add second argument with object properties
1730 * Notify listeners about an event related to persistent groups.
1732 static void wpas_dbus_signal_persistent_group(struct wpa_supplicant *wpa_s,
1733 int id, const char *sig_name,
1736 struct wpas_dbus_priv *iface;
1738 DBusMessageIter iter;
1739 char pgrp_obj_path[WPAS_DBUS_OBJECT_PATH_MAX], *path;
1741 iface = wpa_s->global->dbus;
1743 /* Do nothing if the control interface is not turned on */
1747 os_snprintf(pgrp_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
1748 "%s/" WPAS_DBUS_NEW_PERSISTENT_GROUPS_PART "/%u",
1749 wpa_s->dbus_new_path, id);
1751 msg = dbus_message_new_signal(wpa_s->dbus_new_path,
1752 WPAS_DBUS_NEW_IFACE_P2PDEVICE,
1757 dbus_message_iter_init_append(msg, &iter);
1758 path = pgrp_obj_path;
1759 if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_OBJECT_PATH,
1764 if (!wpa_dbus_get_object_properties(
1765 iface, pgrp_obj_path,
1766 WPAS_DBUS_NEW_IFACE_PERSISTENT_GROUP, &iter))
1770 dbus_connection_send(iface->con, msg, NULL);
1772 dbus_message_unref(msg);
1776 wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
1777 dbus_message_unref(msg);
1782 * wpas_dbus_signal_persistent_group_added - Send a persistent_group
1784 * @wpa_s: %wpa_supplicant network interface data
1785 * @id: new persistent group id
1787 * Notify listeners about addition of a new persistent group.
1789 static void wpas_dbus_signal_persistent_group_added(
1790 struct wpa_supplicant *wpa_s, int id)
1792 wpas_dbus_signal_persistent_group(wpa_s, id, "PersistentGroupAdded",
1798 * wpas_dbus_signal_persistent_group_removed - Send a persistent_group
1800 * @wpa_s: %wpa_supplicant network interface data
1801 * @id: persistent group id
1803 * Notify listeners about removal of a persistent group.
1805 static void wpas_dbus_signal_persistent_group_removed(
1806 struct wpa_supplicant *wpa_s, int id)
1808 wpas_dbus_signal_persistent_group(wpa_s, id, "PersistentGroupRemoved",
1814 * wpas_dbus_signal_p2p_wps_failed - Signals WpsFailed event
1815 * @wpa_s: %wpa_supplicant network interface data
1817 * Sends Event dbus signal with name "fail" and dictionary containing
1818 * "msg" field with fail message number (int32) as arguments
1820 void wpas_dbus_signal_p2p_wps_failed(struct wpa_supplicant *wpa_s,
1821 struct wps_event_fail *fail)
1825 DBusMessageIter iter, dict_iter;
1826 struct wpas_dbus_priv *iface;
1829 iface = wpa_s->global->dbus;
1831 /* Do nothing if the control interface is not turned on */
1835 msg = dbus_message_new_signal(wpa_s->dbus_new_path,
1836 WPAS_DBUS_NEW_IFACE_P2PDEVICE,
1841 dbus_message_iter_init_append(msg, &iter);
1843 if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &key) ||
1844 !wpa_dbus_dict_open_write(&iter, &dict_iter) ||
1845 !wpa_dbus_dict_append_int32(&dict_iter, "msg", fail->msg) ||
1846 !wpa_dbus_dict_append_int16(&dict_iter, "config_error",
1847 fail->config_error) ||
1848 !wpa_dbus_dict_close_write(&iter, &dict_iter))
1849 wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
1851 dbus_connection_send(iface->con, msg, NULL);
1853 dbus_message_unref(msg);
1856 #endif /*CONFIG_P2P*/
1860 * wpas_dbus_signal_prop_changed - Signals change of property
1861 * @wpa_s: %wpa_supplicant network interface data
1862 * @property: indicates which property has changed
1864 * Sends PropertyChanged signals with path, interface and arguments
1865 * depending on which property has changed.
1867 void wpas_dbus_signal_prop_changed(struct wpa_supplicant *wpa_s,
1868 enum wpas_dbus_prop property)
1873 if (wpa_s->dbus_new_path == NULL)
1874 return; /* Skip signal since D-Bus setup is not yet ready */
1878 case WPAS_DBUS_PROP_AP_SCAN:
1881 case WPAS_DBUS_PROP_SCANNING:
1884 case WPAS_DBUS_PROP_STATE:
1887 case WPAS_DBUS_PROP_CURRENT_BSS:
1888 prop = "CurrentBSS";
1890 case WPAS_DBUS_PROP_CURRENT_NETWORK:
1891 prop = "CurrentNetwork";
1893 case WPAS_DBUS_PROP_BSSS:
1896 case WPAS_DBUS_PROP_CURRENT_AUTH_MODE:
1897 prop = "CurrentAuthMode";
1899 case WPAS_DBUS_PROP_DISCONNECT_REASON:
1900 prop = "DisconnectReason";
1904 wpa_printf(MSG_ERROR, "dbus: %s: Unknown Property value %d",
1905 __func__, property);
1909 wpa_dbus_mark_property_changed(wpa_s->global->dbus,
1910 wpa_s->dbus_new_path,
1911 WPAS_DBUS_NEW_IFACE_INTERFACE, prop);
1913 wpa_dbus_flush_object_changed_properties(
1914 wpa_s->global->dbus->con, wpa_s->dbus_new_path);
1920 * wpas_dbus_bss_signal_prop_changed - Signals change of BSS property
1921 * @wpa_s: %wpa_supplicant network interface data
1922 * @property: indicates which property has changed
1923 * @id: unique BSS identifier
1925 * Sends PropertyChanged signals with path, interface, and arguments depending
1926 * on which property has changed.
1928 void wpas_dbus_bss_signal_prop_changed(struct wpa_supplicant *wpa_s,
1929 enum wpas_dbus_bss_prop property,
1932 char path[WPAS_DBUS_OBJECT_PATH_MAX];
1936 case WPAS_DBUS_BSS_PROP_SIGNAL:
1939 case WPAS_DBUS_BSS_PROP_FREQ:
1942 case WPAS_DBUS_BSS_PROP_MODE:
1945 case WPAS_DBUS_BSS_PROP_PRIVACY:
1948 case WPAS_DBUS_BSS_PROP_RATES:
1951 case WPAS_DBUS_BSS_PROP_WPA:
1954 case WPAS_DBUS_BSS_PROP_RSN:
1957 case WPAS_DBUS_BSS_PROP_WPS:
1960 case WPAS_DBUS_BSS_PROP_IES:
1963 case WPAS_DBUS_BSS_PROP_AGE:
1967 wpa_printf(MSG_ERROR, "dbus: %s: Unknown Property value %d",
1968 __func__, property);
1972 os_snprintf(path, WPAS_DBUS_OBJECT_PATH_MAX,
1973 "%s/" WPAS_DBUS_NEW_BSSIDS_PART "/%u",
1974 wpa_s->dbus_new_path, id);
1976 wpa_dbus_mark_property_changed(wpa_s->global->dbus, path,
1977 WPAS_DBUS_NEW_IFACE_BSS, prop);
1982 * wpas_dbus_signal_debug_level_changed - Signals change of debug param
1983 * @global: wpa_global structure
1985 * Sends PropertyChanged signals informing that debug level has changed.
1987 void wpas_dbus_signal_debug_level_changed(struct wpa_global *global)
1989 wpa_dbus_mark_property_changed(global->dbus, WPAS_DBUS_NEW_PATH,
1990 WPAS_DBUS_NEW_INTERFACE,
1996 * wpas_dbus_signal_debug_timestamp_changed - Signals change of debug param
1997 * @global: wpa_global structure
1999 * Sends PropertyChanged signals informing that debug timestamp has changed.
2001 void wpas_dbus_signal_debug_timestamp_changed(struct wpa_global *global)
2003 wpa_dbus_mark_property_changed(global->dbus, WPAS_DBUS_NEW_PATH,
2004 WPAS_DBUS_NEW_INTERFACE,
2010 * wpas_dbus_signal_debug_show_keys_changed - Signals change of debug param
2011 * @global: wpa_global structure
2013 * Sends PropertyChanged signals informing that debug show_keys has changed.
2015 void wpas_dbus_signal_debug_show_keys_changed(struct wpa_global *global)
2017 wpa_dbus_mark_property_changed(global->dbus, WPAS_DBUS_NEW_PATH,
2018 WPAS_DBUS_NEW_INTERFACE,
2023 static void wpas_dbus_register(struct wpa_dbus_object_desc *obj_desc,
2025 WPADBusArgumentFreeFunction priv_free,
2026 const struct wpa_dbus_method_desc *methods,
2027 const struct wpa_dbus_property_desc *properties,
2028 const struct wpa_dbus_signal_desc *signals)
2032 obj_desc->user_data = priv;
2033 obj_desc->user_data_free_func = priv_free;
2034 obj_desc->methods = methods;
2035 obj_desc->properties = properties;
2036 obj_desc->signals = signals;
2038 for (n = 0; properties && properties->dbus_property; properties++)
2041 obj_desc->prop_changed_flags = os_zalloc(n);
2042 if (!obj_desc->prop_changed_flags)
2043 wpa_printf(MSG_DEBUG, "dbus: %s: can't register handlers",
2048 static const struct wpa_dbus_method_desc wpas_dbus_global_methods[] = {
2049 { "CreateInterface", WPAS_DBUS_NEW_INTERFACE,
2050 (WPADBusMethodHandler) &wpas_dbus_handler_create_interface,
2052 { "args", "a{sv}", ARG_IN },
2053 { "path", "o", ARG_OUT },
2057 { "RemoveInterface", WPAS_DBUS_NEW_INTERFACE,
2058 (WPADBusMethodHandler) &wpas_dbus_handler_remove_interface,
2060 { "path", "o", ARG_IN },
2064 { "GetInterface", WPAS_DBUS_NEW_INTERFACE,
2065 (WPADBusMethodHandler) &wpas_dbus_handler_get_interface,
2067 { "ifname", "s", ARG_IN },
2068 { "path", "o", ARG_OUT },
2072 { NULL, NULL, NULL, { END_ARGS } }
2075 static const struct wpa_dbus_property_desc wpas_dbus_global_properties[] = {
2076 { "DebugLevel", WPAS_DBUS_NEW_INTERFACE, "s",
2077 wpas_dbus_getter_debug_level,
2078 wpas_dbus_setter_debug_level
2080 { "DebugTimestamp", WPAS_DBUS_NEW_INTERFACE, "b",
2081 wpas_dbus_getter_debug_timestamp,
2082 wpas_dbus_setter_debug_timestamp
2084 { "DebugShowKeys", WPAS_DBUS_NEW_INTERFACE, "b",
2085 wpas_dbus_getter_debug_show_keys,
2086 wpas_dbus_setter_debug_show_keys
2088 { "Interfaces", WPAS_DBUS_NEW_INTERFACE, "ao",
2089 wpas_dbus_getter_interfaces,
2092 { "EapMethods", WPAS_DBUS_NEW_INTERFACE, "as",
2093 wpas_dbus_getter_eap_methods,
2096 { "Capabilities", WPAS_DBUS_NEW_INTERFACE, "as",
2097 wpas_dbus_getter_global_capabilities,
2100 #ifdef CONFIG_WIFI_DISPLAY
2101 { "WFDIEs", WPAS_DBUS_NEW_INTERFACE, "ay",
2102 wpas_dbus_getter_global_wfd_ies,
2103 wpas_dbus_setter_global_wfd_ies
2105 #endif /* CONFIG_WIFI_DISPLAY */
2106 { NULL, NULL, NULL, NULL, NULL }
2109 static const struct wpa_dbus_signal_desc wpas_dbus_global_signals[] = {
2110 { "InterfaceAdded", WPAS_DBUS_NEW_INTERFACE,
2112 { "path", "o", ARG_OUT },
2113 { "properties", "a{sv}", ARG_OUT },
2117 { "InterfaceRemoved", WPAS_DBUS_NEW_INTERFACE,
2119 { "path", "o", ARG_OUT },
2123 { "NetworkRequest", WPAS_DBUS_NEW_IFACE_INTERFACE,
2125 { "path", "o", ARG_OUT },
2126 { "field", "s", ARG_OUT },
2127 { "text", "s", ARG_OUT },
2131 /* Deprecated: use org.freedesktop.DBus.Properties.PropertiesChanged */
2132 { "PropertiesChanged", WPAS_DBUS_NEW_INTERFACE,
2134 { "properties", "a{sv}", ARG_OUT },
2138 { NULL, NULL, { END_ARGS } }
2143 * wpas_dbus_ctrl_iface_init - Initialize dbus control interface
2144 * @global: Pointer to global data from wpa_supplicant_init()
2145 * Returns: 0 on success or -1 on failure
2147 * Initialize the dbus control interface for wpa_supplicantand and start
2148 * receiving commands from external programs over the bus.
2150 int wpas_dbus_ctrl_iface_init(struct wpas_dbus_priv *priv)
2152 struct wpa_dbus_object_desc *obj_desc;
2155 obj_desc = os_zalloc(sizeof(struct wpa_dbus_object_desc));
2157 wpa_printf(MSG_ERROR, "Not enough memory "
2158 "to create object description");
2162 wpas_dbus_register(obj_desc, priv->global, NULL,
2163 wpas_dbus_global_methods,
2164 wpas_dbus_global_properties,
2165 wpas_dbus_global_signals);
2167 wpa_printf(MSG_DEBUG, "dbus: Register D-Bus object '%s'",
2168 WPAS_DBUS_NEW_PATH);
2169 ret = wpa_dbus_ctrl_iface_init(priv, WPAS_DBUS_NEW_PATH,
2170 WPAS_DBUS_NEW_SERVICE,
2173 free_dbus_object_desc(obj_desc);
2175 priv->dbus_new_initialized = 1;
2182 * wpas_dbus_ctrl_iface_deinit - Deinitialize dbus ctrl interface for
2184 * @iface: Pointer to dbus private data from wpas_dbus_init()
2186 * Deinitialize the dbus control interface that was initialized with
2187 * wpas_dbus_ctrl_iface_init().
2189 void wpas_dbus_ctrl_iface_deinit(struct wpas_dbus_priv *iface)
2191 if (!iface->dbus_new_initialized)
2193 wpa_printf(MSG_DEBUG, "dbus: Unregister D-Bus object '%s'",
2194 WPAS_DBUS_NEW_PATH);
2195 dbus_connection_unregister_object_path(iface->con,
2196 WPAS_DBUS_NEW_PATH);
2200 static void wpa_dbus_free(void *ptr)
2206 static const struct wpa_dbus_property_desc wpas_dbus_network_properties[] = {
2207 { "Properties", WPAS_DBUS_NEW_IFACE_NETWORK, "a{sv}",
2208 wpas_dbus_getter_network_properties,
2209 wpas_dbus_setter_network_properties
2211 { "Enabled", WPAS_DBUS_NEW_IFACE_NETWORK, "b",
2212 wpas_dbus_getter_enabled,
2213 wpas_dbus_setter_enabled
2215 { NULL, NULL, NULL, NULL, NULL }
2219 static const struct wpa_dbus_signal_desc wpas_dbus_network_signals[] = {
2220 /* Deprecated: use org.freedesktop.DBus.Properties.PropertiesChanged */
2221 { "PropertiesChanged", WPAS_DBUS_NEW_IFACE_NETWORK,
2223 { "properties", "a{sv}", ARG_OUT },
2227 { NULL, NULL, { END_ARGS } }
2232 * wpas_dbus_register_network - Register a configured network with dbus
2233 * @wpa_s: wpa_supplicant interface structure
2234 * @ssid: network configuration data
2235 * Returns: 0 on success, -1 on failure
2237 * Registers network representing object with dbus
2239 int wpas_dbus_register_network(struct wpa_supplicant *wpa_s,
2240 struct wpa_ssid *ssid)
2242 struct wpas_dbus_priv *ctrl_iface;
2243 struct wpa_dbus_object_desc *obj_desc;
2244 struct network_handler_args *arg;
2245 char net_obj_path[WPAS_DBUS_OBJECT_PATH_MAX];
2249 * If it is a persistent group register it as such.
2250 * This is to handle cases where an interface is being initialized
2251 * with a list of networks read from config.
2253 if (network_is_persistent_group(ssid))
2254 return wpas_dbus_register_persistent_group(wpa_s, ssid);
2255 #endif /* CONFIG_P2P */
2257 /* Do nothing if the control interface is not turned on */
2258 if (wpa_s == NULL || wpa_s->global == NULL)
2260 ctrl_iface = wpa_s->global->dbus;
2261 if (ctrl_iface == NULL)
2264 os_snprintf(net_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
2265 "%s/" WPAS_DBUS_NEW_NETWORKS_PART "/%u",
2266 wpa_s->dbus_new_path, ssid->id);
2268 wpa_printf(MSG_DEBUG, "dbus: Register network object '%s'",
2270 obj_desc = os_zalloc(sizeof(struct wpa_dbus_object_desc));
2272 wpa_printf(MSG_ERROR, "Not enough memory "
2273 "to create object description");
2277 /* allocate memory for handlers arguments */
2278 arg = os_zalloc(sizeof(struct network_handler_args));
2280 wpa_printf(MSG_ERROR, "Not enough memory "
2281 "to create arguments for method");
2288 wpas_dbus_register(obj_desc, arg, wpa_dbus_free, NULL,
2289 wpas_dbus_network_properties,
2290 wpas_dbus_network_signals);
2292 if (wpa_dbus_register_object_per_iface(ctrl_iface, net_obj_path,
2293 wpa_s->ifname, obj_desc))
2296 wpas_dbus_signal_network_added(wpa_s, ssid->id);
2301 free_dbus_object_desc(obj_desc);
2307 * wpas_dbus_unregister_network - Unregister a configured network from dbus
2308 * @wpa_s: wpa_supplicant interface structure
2310 * Returns: 0 on success, -1 on failure
2312 * Unregisters network representing object from dbus
2314 int wpas_dbus_unregister_network(struct wpa_supplicant *wpa_s, int nid)
2316 struct wpas_dbus_priv *ctrl_iface;
2317 char net_obj_path[WPAS_DBUS_OBJECT_PATH_MAX];
2320 struct wpa_ssid *ssid;
2322 ssid = wpa_config_get_network(wpa_s->conf, nid);
2324 /* If it is a persistent group unregister it as such */
2325 if (ssid && network_is_persistent_group(ssid))
2326 return wpas_dbus_unregister_persistent_group(wpa_s, nid);
2327 #endif /* CONFIG_P2P */
2329 /* Do nothing if the control interface is not turned on */
2330 if (wpa_s->global == NULL || wpa_s->dbus_new_path == NULL)
2332 ctrl_iface = wpa_s->global->dbus;
2333 if (ctrl_iface == NULL)
2336 os_snprintf(net_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
2337 "%s/" WPAS_DBUS_NEW_NETWORKS_PART "/%u",
2338 wpa_s->dbus_new_path, nid);
2340 wpa_printf(MSG_DEBUG, "dbus: Unregister network object '%s'",
2342 ret = wpa_dbus_unregister_object_per_iface(ctrl_iface, net_obj_path);
2345 wpas_dbus_signal_network_removed(wpa_s, nid);
2351 static const struct wpa_dbus_property_desc wpas_dbus_bss_properties[] = {
2352 { "SSID", WPAS_DBUS_NEW_IFACE_BSS, "ay",
2353 wpas_dbus_getter_bss_ssid,
2356 { "BSSID", WPAS_DBUS_NEW_IFACE_BSS, "ay",
2357 wpas_dbus_getter_bss_bssid,
2360 { "Privacy", WPAS_DBUS_NEW_IFACE_BSS, "b",
2361 wpas_dbus_getter_bss_privacy,
2364 { "Mode", WPAS_DBUS_NEW_IFACE_BSS, "s",
2365 wpas_dbus_getter_bss_mode,
2368 { "Signal", WPAS_DBUS_NEW_IFACE_BSS, "n",
2369 wpas_dbus_getter_bss_signal,
2372 { "Frequency", WPAS_DBUS_NEW_IFACE_BSS, "q",
2373 wpas_dbus_getter_bss_frequency,
2376 { "Rates", WPAS_DBUS_NEW_IFACE_BSS, "au",
2377 wpas_dbus_getter_bss_rates,
2380 { "WPA", WPAS_DBUS_NEW_IFACE_BSS, "a{sv}",
2381 wpas_dbus_getter_bss_wpa,
2384 { "RSN", WPAS_DBUS_NEW_IFACE_BSS, "a{sv}",
2385 wpas_dbus_getter_bss_rsn,
2388 { "WPS", WPAS_DBUS_NEW_IFACE_BSS, "a{sv}",
2389 wpas_dbus_getter_bss_wps,
2392 { "IEs", WPAS_DBUS_NEW_IFACE_BSS, "ay",
2393 wpas_dbus_getter_bss_ies,
2396 { "Age", WPAS_DBUS_NEW_IFACE_BSS, "u",
2397 wpas_dbus_getter_bss_age,
2400 { NULL, NULL, NULL, NULL, NULL }
2404 static const struct wpa_dbus_signal_desc wpas_dbus_bss_signals[] = {
2405 /* Deprecated: use org.freedesktop.DBus.Properties.PropertiesChanged */
2406 { "PropertiesChanged", WPAS_DBUS_NEW_IFACE_BSS,
2408 { "properties", "a{sv}", ARG_OUT },
2412 { NULL, NULL, { END_ARGS } }
2417 * wpas_dbus_unregister_bss - Unregister a scanned BSS from dbus
2418 * @wpa_s: wpa_supplicant interface structure
2419 * @bssid: scanned network bssid
2420 * @id: unique BSS identifier
2421 * Returns: 0 on success, -1 on failure
2423 * Unregisters BSS representing object from dbus
2425 int wpas_dbus_unregister_bss(struct wpa_supplicant *wpa_s,
2426 u8 bssid[ETH_ALEN], unsigned int id)
2428 struct wpas_dbus_priv *ctrl_iface;
2429 char bss_obj_path[WPAS_DBUS_OBJECT_PATH_MAX];
2431 /* Do nothing if the control interface is not turned on */
2432 if (wpa_s == NULL || wpa_s->global == NULL)
2434 ctrl_iface = wpa_s->global->dbus;
2435 if (ctrl_iface == NULL)
2438 os_snprintf(bss_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
2439 "%s/" WPAS_DBUS_NEW_BSSIDS_PART "/%u",
2440 wpa_s->dbus_new_path, id);
2442 wpa_printf(MSG_DEBUG, "dbus: Unregister BSS object '%s'",
2444 if (wpa_dbus_unregister_object_per_iface(ctrl_iface, bss_obj_path)) {
2445 wpa_printf(MSG_ERROR, "dbus: Cannot unregister BSS object %s",
2450 wpas_dbus_signal_bss_removed(wpa_s, bss_obj_path);
2451 wpas_dbus_signal_prop_changed(wpa_s, WPAS_DBUS_PROP_BSSS);
2458 * wpas_dbus_register_bss - Register a scanned BSS with dbus
2459 * @wpa_s: wpa_supplicant interface structure
2460 * @bssid: scanned network bssid
2461 * @id: unique BSS identifier
2462 * Returns: 0 on success, -1 on failure
2464 * Registers BSS representing object with dbus
2466 int wpas_dbus_register_bss(struct wpa_supplicant *wpa_s,
2467 u8 bssid[ETH_ALEN], unsigned int id)
2469 struct wpas_dbus_priv *ctrl_iface;
2470 struct wpa_dbus_object_desc *obj_desc;
2471 char bss_obj_path[WPAS_DBUS_OBJECT_PATH_MAX];
2472 struct bss_handler_args *arg;
2474 /* Do nothing if the control interface is not turned on */
2475 if (wpa_s == NULL || wpa_s->global == NULL)
2477 ctrl_iface = wpa_s->global->dbus;
2478 if (ctrl_iface == NULL)
2481 os_snprintf(bss_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
2482 "%s/" WPAS_DBUS_NEW_BSSIDS_PART "/%u",
2483 wpa_s->dbus_new_path, id);
2485 obj_desc = os_zalloc(sizeof(struct wpa_dbus_object_desc));
2487 wpa_printf(MSG_ERROR, "Not enough memory "
2488 "to create object description");
2492 arg = os_zalloc(sizeof(struct bss_handler_args));
2494 wpa_printf(MSG_ERROR, "Not enough memory "
2495 "to create arguments for handler");
2501 wpas_dbus_register(obj_desc, arg, wpa_dbus_free, NULL,
2502 wpas_dbus_bss_properties,
2503 wpas_dbus_bss_signals);
2505 wpa_printf(MSG_DEBUG, "dbus: Register BSS object '%s'",
2507 if (wpa_dbus_register_object_per_iface(ctrl_iface, bss_obj_path,
2508 wpa_s->ifname, obj_desc)) {
2509 wpa_printf(MSG_ERROR,
2510 "Cannot register BSSID dbus object %s.",
2515 wpas_dbus_signal_bss_added(wpa_s, bss_obj_path);
2516 wpas_dbus_signal_prop_changed(wpa_s, WPAS_DBUS_PROP_BSSS);
2521 free_dbus_object_desc(obj_desc);
2526 static const struct wpa_dbus_method_desc wpas_dbus_interface_methods[] = {
2527 { "Scan", WPAS_DBUS_NEW_IFACE_INTERFACE,
2528 (WPADBusMethodHandler) &wpas_dbus_handler_scan,
2530 { "args", "a{sv}", ARG_IN },
2534 { "SignalPoll", WPAS_DBUS_NEW_IFACE_INTERFACE,
2535 (WPADBusMethodHandler) &wpas_dbus_handler_signal_poll,
2537 { "args", "a{sv}", ARG_OUT },
2541 { "Disconnect", WPAS_DBUS_NEW_IFACE_INTERFACE,
2542 (WPADBusMethodHandler) &wpas_dbus_handler_disconnect,
2547 { "AddNetwork", WPAS_DBUS_NEW_IFACE_INTERFACE,
2548 (WPADBusMethodHandler) &wpas_dbus_handler_add_network,
2550 { "args", "a{sv}", ARG_IN },
2551 { "path", "o", ARG_OUT },
2555 { "Reassociate", WPAS_DBUS_NEW_IFACE_INTERFACE,
2556 (WPADBusMethodHandler) &wpas_dbus_handler_reassociate,
2561 { "Reattach", WPAS_DBUS_NEW_IFACE_INTERFACE,
2562 (WPADBusMethodHandler) &wpas_dbus_handler_reattach,
2567 { "RemoveNetwork", WPAS_DBUS_NEW_IFACE_INTERFACE,
2568 (WPADBusMethodHandler) &wpas_dbus_handler_remove_network,
2570 { "path", "o", ARG_IN },
2574 { "RemoveAllNetworks", WPAS_DBUS_NEW_IFACE_INTERFACE,
2575 (WPADBusMethodHandler) &wpas_dbus_handler_remove_all_networks,
2580 { "SelectNetwork", WPAS_DBUS_NEW_IFACE_INTERFACE,
2581 (WPADBusMethodHandler) &wpas_dbus_handler_select_network,
2583 { "path", "o", ARG_IN },
2587 { "NetworkReply", WPAS_DBUS_NEW_IFACE_INTERFACE,
2588 (WPADBusMethodHandler) &wpas_dbus_handler_network_reply,
2590 { "path", "o", ARG_IN },
2591 { "field", "s", ARG_IN },
2592 { "value", "s", ARG_IN },
2596 #ifndef CONFIG_NO_CONFIG_BLOBS
2597 { "AddBlob", WPAS_DBUS_NEW_IFACE_INTERFACE,
2598 (WPADBusMethodHandler) &wpas_dbus_handler_add_blob,
2600 { "name", "s", ARG_IN },
2601 { "data", "ay", ARG_IN },
2605 { "GetBlob", WPAS_DBUS_NEW_IFACE_INTERFACE,
2606 (WPADBusMethodHandler) &wpas_dbus_handler_get_blob,
2608 { "name", "s", ARG_IN },
2609 { "data", "ay", ARG_OUT },
2613 { "RemoveBlob", WPAS_DBUS_NEW_IFACE_INTERFACE,
2614 (WPADBusMethodHandler) &wpas_dbus_handler_remove_blob,
2616 { "name", "s", ARG_IN },
2620 #endif /* CONFIG_NO_CONFIG_BLOBS */
2621 { "SetPKCS11EngineAndModulePath", WPAS_DBUS_NEW_IFACE_INTERFACE,
2622 (WPADBusMethodHandler)
2623 &wpas_dbus_handler_set_pkcs11_engine_and_module_path,
2625 { "pkcs11_engine_path", "s", ARG_IN },
2626 { "pkcs11_module_path", "s", ARG_IN },
2631 { "Start", WPAS_DBUS_NEW_IFACE_WPS,
2632 (WPADBusMethodHandler) &wpas_dbus_handler_wps_start,
2634 { "args", "a{sv}", ARG_IN },
2635 { "output", "a{sv}", ARG_OUT },
2639 #endif /* CONFIG_WPS */
2641 { "Find", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
2642 (WPADBusMethodHandler)wpas_dbus_handler_p2p_find,
2644 { "args", "a{sv}", ARG_IN },
2648 { "StopFind", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
2649 (WPADBusMethodHandler)wpas_dbus_handler_p2p_stop_find,
2654 { "Listen", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
2655 (WPADBusMethodHandler)wpas_dbus_handler_p2p_listen,
2657 { "timeout", "i", ARG_IN },
2661 { "ExtendedListen", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
2662 (WPADBusMethodHandler)wpas_dbus_handler_p2p_extendedlisten,
2664 { "args", "a{sv}", ARG_IN },
2668 { "PresenceRequest", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
2669 (WPADBusMethodHandler)wpas_dbus_handler_p2p_presence_request,
2671 { "args", "a{sv}", ARG_IN },
2675 { "ProvisionDiscoveryRequest", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
2676 (WPADBusMethodHandler)wpas_dbus_handler_p2p_prov_disc_req,
2678 { "peer", "o", ARG_IN },
2679 { "config_method", "s", ARG_IN },
2683 { "Connect", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
2684 (WPADBusMethodHandler)wpas_dbus_handler_p2p_connect,
2686 { "args", "a{sv}", ARG_IN },
2687 { "generated_pin", "s", ARG_OUT },
2691 { "GroupAdd", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
2692 (WPADBusMethodHandler)wpas_dbus_handler_p2p_group_add,
2694 { "args", "a{sv}", ARG_IN },
2698 { "Invite", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
2699 (WPADBusMethodHandler)wpas_dbus_handler_p2p_invite,
2701 { "args", "a{sv}", ARG_IN },
2705 { "Disconnect", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
2706 (WPADBusMethodHandler)wpas_dbus_handler_p2p_disconnect,
2711 { "RejectPeer", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
2712 (WPADBusMethodHandler)wpas_dbus_handler_p2p_rejectpeer,
2714 { "peer", "o", ARG_IN },
2718 { "Flush", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
2719 (WPADBusMethodHandler)wpas_dbus_handler_p2p_flush,
2724 { "AddService", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
2725 (WPADBusMethodHandler)wpas_dbus_handler_p2p_add_service,
2727 { "args", "a{sv}", ARG_IN },
2731 { "DeleteService", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
2732 (WPADBusMethodHandler)wpas_dbus_handler_p2p_delete_service,
2734 { "args", "a{sv}", ARG_IN },
2738 { "FlushService", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
2739 (WPADBusMethodHandler)wpas_dbus_handler_p2p_flush_service,
2744 { "ServiceDiscoveryRequest", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
2745 (WPADBusMethodHandler)wpas_dbus_handler_p2p_service_sd_req,
2747 { "args", "a{sv}", ARG_IN },
2748 { "ref", "t", ARG_OUT },
2752 { "ServiceDiscoveryResponse", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
2753 (WPADBusMethodHandler)wpas_dbus_handler_p2p_service_sd_res,
2755 { "args", "a{sv}", ARG_IN },
2759 { "ServiceDiscoveryCancelRequest", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
2760 (WPADBusMethodHandler)wpas_dbus_handler_p2p_service_sd_cancel_req,
2762 { "args", "t", ARG_IN },
2766 { "ServiceUpdate", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
2767 (WPADBusMethodHandler)wpas_dbus_handler_p2p_service_update,
2772 { "ServiceDiscoveryExternal", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
2773 (WPADBusMethodHandler)wpas_dbus_handler_p2p_serv_disc_external,
2775 { "arg", "i", ARG_IN },
2779 { "AddPersistentGroup", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
2780 (WPADBusMethodHandler) wpas_dbus_handler_add_persistent_group,
2782 { "args", "a{sv}", ARG_IN },
2783 { "path", "o", ARG_OUT },
2787 { "RemovePersistentGroup", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
2788 (WPADBusMethodHandler) wpas_dbus_handler_remove_persistent_group,
2790 { "path", "o", ARG_IN },
2794 { "RemoveAllPersistentGroups", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
2795 (WPADBusMethodHandler)
2796 wpas_dbus_handler_remove_all_persistent_groups,
2801 #endif /* CONFIG_P2P */
2802 { "FlushBSS", WPAS_DBUS_NEW_IFACE_INTERFACE,
2803 (WPADBusMethodHandler) &wpas_dbus_handler_flush_bss,
2805 { "age", "u", ARG_IN },
2810 { "SubscribeProbeReq", WPAS_DBUS_NEW_IFACE_INTERFACE,
2811 (WPADBusMethodHandler) wpas_dbus_handler_subscribe_preq,
2816 { "UnsubscribeProbeReq", WPAS_DBUS_NEW_IFACE_INTERFACE,
2817 (WPADBusMethodHandler) wpas_dbus_handler_unsubscribe_preq,
2822 #endif /* CONFIG_AP */
2823 { "EAPLogoff", WPAS_DBUS_NEW_IFACE_INTERFACE,
2824 (WPADBusMethodHandler) &wpas_dbus_handler_eap_logoff,
2829 { "EAPLogon", WPAS_DBUS_NEW_IFACE_INTERFACE,
2830 (WPADBusMethodHandler) &wpas_dbus_handler_eap_logon,
2835 #ifdef CONFIG_AUTOSCAN
2836 { "AutoScan", WPAS_DBUS_NEW_IFACE_INTERFACE,
2837 (WPADBusMethodHandler) &wpas_dbus_handler_autoscan,
2839 { "arg", "s", ARG_IN },
2843 #endif /* CONFIG_AUTOSCAN */
2845 { "TDLSDiscover", WPAS_DBUS_NEW_IFACE_INTERFACE,
2846 (WPADBusMethodHandler) wpas_dbus_handler_tdls_discover,
2848 { "peer_address", "s", ARG_IN },
2852 { "TDLSSetup", WPAS_DBUS_NEW_IFACE_INTERFACE,
2853 (WPADBusMethodHandler) wpas_dbus_handler_tdls_setup,
2855 { "peer_address", "s", ARG_IN },
2859 { "TDLSStatus", WPAS_DBUS_NEW_IFACE_INTERFACE,
2860 (WPADBusMethodHandler) wpas_dbus_handler_tdls_status,
2862 { "peer_address", "s", ARG_IN },
2863 { "status", "s", ARG_OUT },
2867 { "TDLSTeardown", WPAS_DBUS_NEW_IFACE_INTERFACE,
2868 (WPADBusMethodHandler) wpas_dbus_handler_tdls_teardown,
2870 { "peer_address", "s", ARG_IN },
2874 #endif /* CONFIG_TDLS */
2875 { NULL, NULL, NULL, { END_ARGS } }
2878 static const struct wpa_dbus_property_desc wpas_dbus_interface_properties[] = {
2879 { "Capabilities", WPAS_DBUS_NEW_IFACE_INTERFACE, "a{sv}",
2880 wpas_dbus_getter_capabilities,
2883 { "State", WPAS_DBUS_NEW_IFACE_INTERFACE, "s",
2884 wpas_dbus_getter_state,
2887 { "Scanning", WPAS_DBUS_NEW_IFACE_INTERFACE, "b",
2888 wpas_dbus_getter_scanning,
2891 { "ApScan", WPAS_DBUS_NEW_IFACE_INTERFACE, "u",
2892 wpas_dbus_getter_ap_scan,
2893 wpas_dbus_setter_ap_scan
2895 { "BSSExpireAge", WPAS_DBUS_NEW_IFACE_INTERFACE, "u",
2896 wpas_dbus_getter_bss_expire_age,
2897 wpas_dbus_setter_bss_expire_age
2899 { "BSSExpireCount", WPAS_DBUS_NEW_IFACE_INTERFACE, "u",
2900 wpas_dbus_getter_bss_expire_count,
2901 wpas_dbus_setter_bss_expire_count
2903 { "Country", WPAS_DBUS_NEW_IFACE_INTERFACE, "s",
2904 wpas_dbus_getter_country,
2905 wpas_dbus_setter_country
2907 { "Ifname", WPAS_DBUS_NEW_IFACE_INTERFACE, "s",
2908 wpas_dbus_getter_ifname,
2911 { "Driver", WPAS_DBUS_NEW_IFACE_INTERFACE, "s",
2912 wpas_dbus_getter_driver,
2915 { "BridgeIfname", WPAS_DBUS_NEW_IFACE_INTERFACE, "s",
2916 wpas_dbus_getter_bridge_ifname,
2919 { "CurrentBSS", WPAS_DBUS_NEW_IFACE_INTERFACE, "o",
2920 wpas_dbus_getter_current_bss,
2923 { "CurrentNetwork", WPAS_DBUS_NEW_IFACE_INTERFACE, "o",
2924 wpas_dbus_getter_current_network,
2927 { "CurrentAuthMode", WPAS_DBUS_NEW_IFACE_INTERFACE, "s",
2928 wpas_dbus_getter_current_auth_mode,
2931 { "Blobs", WPAS_DBUS_NEW_IFACE_INTERFACE, "a{say}",
2932 wpas_dbus_getter_blobs,
2935 { "BSSs", WPAS_DBUS_NEW_IFACE_INTERFACE, "ao",
2936 wpas_dbus_getter_bsss,
2939 { "Networks", WPAS_DBUS_NEW_IFACE_INTERFACE, "ao",
2940 wpas_dbus_getter_networks,
2943 { "FastReauth", WPAS_DBUS_NEW_IFACE_INTERFACE, "b",
2944 wpas_dbus_getter_fast_reauth,
2945 wpas_dbus_setter_fast_reauth
2947 { "ScanInterval", WPAS_DBUS_NEW_IFACE_INTERFACE, "i",
2948 wpas_dbus_getter_scan_interval,
2949 wpas_dbus_setter_scan_interval
2951 { "PKCS11EnginePath", WPAS_DBUS_NEW_IFACE_INTERFACE, "s",
2952 wpas_dbus_getter_pkcs11_engine_path,
2955 { "PKCS11ModulePath", WPAS_DBUS_NEW_IFACE_INTERFACE, "s",
2956 wpas_dbus_getter_pkcs11_module_path,
2960 { "ProcessCredentials", WPAS_DBUS_NEW_IFACE_WPS, "b",
2961 wpas_dbus_getter_process_credentials,
2962 wpas_dbus_setter_process_credentials
2964 #endif /* CONFIG_WPS */
2966 { "P2PDeviceConfig", WPAS_DBUS_NEW_IFACE_P2PDEVICE, "a{sv}",
2967 wpas_dbus_getter_p2p_device_config,
2968 wpas_dbus_setter_p2p_device_config
2970 { "Peers", WPAS_DBUS_NEW_IFACE_P2PDEVICE, "ao",
2971 wpas_dbus_getter_p2p_peers,
2974 { "Role", WPAS_DBUS_NEW_IFACE_P2PDEVICE, "s",
2975 wpas_dbus_getter_p2p_role,
2978 { "Group", WPAS_DBUS_NEW_IFACE_P2PDEVICE, "o",
2979 wpas_dbus_getter_p2p_group,
2982 { "PeerGO", WPAS_DBUS_NEW_IFACE_P2PDEVICE, "o",
2983 wpas_dbus_getter_p2p_peergo,
2986 { "PersistentGroups", WPAS_DBUS_NEW_IFACE_P2PDEVICE, "ao",
2987 wpas_dbus_getter_persistent_groups,
2990 #endif /* CONFIG_P2P */
2991 { "DisconnectReason", WPAS_DBUS_NEW_IFACE_INTERFACE, "i",
2992 wpas_dbus_getter_disconnect_reason,
2995 { NULL, NULL, NULL, NULL, NULL }
2998 static const struct wpa_dbus_signal_desc wpas_dbus_interface_signals[] = {
2999 { "ScanDone", WPAS_DBUS_NEW_IFACE_INTERFACE,
3001 { "success", "b", ARG_OUT },
3005 { "BSSAdded", WPAS_DBUS_NEW_IFACE_INTERFACE,
3007 { "path", "o", ARG_OUT },
3008 { "properties", "a{sv}", ARG_OUT },
3012 { "BSSRemoved", WPAS_DBUS_NEW_IFACE_INTERFACE,
3014 { "path", "o", ARG_OUT },
3018 { "BlobAdded", WPAS_DBUS_NEW_IFACE_INTERFACE,
3020 { "name", "s", ARG_OUT },
3024 { "BlobRemoved", WPAS_DBUS_NEW_IFACE_INTERFACE,
3026 { "name", "s", ARG_OUT },
3030 { "NetworkAdded", WPAS_DBUS_NEW_IFACE_INTERFACE,
3032 { "path", "o", ARG_OUT },
3033 { "properties", "a{sv}", ARG_OUT },
3037 { "NetworkRemoved", WPAS_DBUS_NEW_IFACE_INTERFACE,
3039 { "path", "o", ARG_OUT },
3043 { "NetworkSelected", WPAS_DBUS_NEW_IFACE_INTERFACE,
3045 { "path", "o", ARG_OUT },
3049 /* Deprecated: use org.freedesktop.DBus.Properties.PropertiesChanged */
3050 { "PropertiesChanged", WPAS_DBUS_NEW_IFACE_INTERFACE,
3052 { "properties", "a{sv}", ARG_OUT },
3057 { "Event", WPAS_DBUS_NEW_IFACE_WPS,
3059 { "name", "s", ARG_OUT },
3060 { "args", "a{sv}", ARG_OUT },
3064 { "Credentials", WPAS_DBUS_NEW_IFACE_WPS,
3066 { "credentials", "a{sv}", ARG_OUT },
3070 /* Deprecated: use org.freedesktop.DBus.Properties.PropertiesChanged */
3071 { "PropertiesChanged", WPAS_DBUS_NEW_IFACE_WPS,
3073 { "properties", "a{sv}", ARG_OUT },
3077 #endif /* CONFIG_WPS */
3079 { "P2PStateChanged", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
3081 { "states", "a{ss}", ARG_OUT },
3085 { "DeviceFound", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
3087 { "path", "o", ARG_OUT },
3091 { "DeviceLost", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
3093 { "path", "o", ARG_OUT },
3097 { "ProvisionDiscoveryRequestDisplayPin", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
3099 { "peer_object", "o", ARG_OUT },
3100 { "pin", "s", ARG_OUT },
3104 { "ProvisionDiscoveryResponseDisplayPin", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
3106 { "peer_object", "o", ARG_OUT },
3107 { "pin", "s", ARG_OUT },
3111 { "ProvisionDiscoveryRequestEnterPin", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
3113 { "peer_object", "o", ARG_OUT },
3117 { "ProvisionDiscoveryResponseEnterPin", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
3119 { "peer_object", "o", ARG_OUT },
3123 { "ProvisionDiscoveryPBCRequest", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
3125 { "peer_object", "o", ARG_OUT },
3129 { "ProvisionDiscoveryPBCResponse", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
3131 { "peer_object", "o", ARG_OUT },
3135 { "ProvisionDiscoveryFailure", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
3137 { "peer_object", "o", ARG_OUT },
3138 { "status", "i", ARG_OUT },
3142 { "GroupStarted", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
3144 { "properties", "a{sv}", ARG_OUT },
3148 { "GONegotiationSuccess", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
3150 { "properties", "a{sv}", ARG_OUT },
3154 { "GONegotiationFailure", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
3156 { "properties", "a{sv}", ARG_OUT },
3160 { "GONegotiationRequest", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
3162 { "path", "o", ARG_OUT },
3163 { "dev_passwd_id", "i", ARG_OUT },
3167 { "InvitationResult", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
3169 { "invite_result", "a{sv}", ARG_OUT },
3173 { "GroupFinished", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
3175 { "properties", "a{sv}", ARG_OUT },
3179 { "ServiceDiscoveryRequest", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
3181 { "sd_request", "a{sv}", ARG_OUT },
3185 { "ServiceDiscoveryResponse", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
3187 { "sd_response", "a{sv}", ARG_OUT },
3191 { "PersistentGroupAdded", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
3193 { "path", "o", ARG_OUT },
3194 { "properties", "a{sv}", ARG_OUT },
3198 { "PersistentGroupRemoved", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
3200 { "path", "o", ARG_OUT },
3204 { "WpsFailed", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
3206 { "name", "s", ARG_OUT },
3207 { "args", "a{sv}", ARG_OUT },
3211 #endif /* CONFIG_P2P */
3213 { "ProbeRequest", WPAS_DBUS_NEW_IFACE_INTERFACE,
3215 { "args", "a{sv}", ARG_OUT },
3219 #endif /* CONFIG_AP */
3220 { "Certification", WPAS_DBUS_NEW_IFACE_INTERFACE,
3222 { "certification", "a{sv}", ARG_OUT },
3226 { "EAP", WPAS_DBUS_NEW_IFACE_INTERFACE,
3228 { "status", "s", ARG_OUT },
3229 { "parameter", "s", ARG_OUT },
3233 { "StaAuthorized", WPAS_DBUS_NEW_IFACE_INTERFACE,
3235 { "name", "s", ARG_OUT },
3239 { "StaDeauthorized", WPAS_DBUS_NEW_IFACE_INTERFACE,
3241 { "name", "s", ARG_OUT },
3245 { NULL, NULL, { END_ARGS } }
3249 int wpas_dbus_register_interface(struct wpa_supplicant *wpa_s)
3252 struct wpa_dbus_object_desc *obj_desc = NULL;
3253 struct wpas_dbus_priv *ctrl_iface = wpa_s->global->dbus;
3256 /* Do nothing if the control interface is not turned on */
3257 if (ctrl_iface == NULL)
3260 /* Create and set the interface's object path */
3261 wpa_s->dbus_new_path = os_zalloc(WPAS_DBUS_OBJECT_PATH_MAX);
3262 if (wpa_s->dbus_new_path == NULL)
3264 next = ctrl_iface->next_objid++;
3265 os_snprintf(wpa_s->dbus_new_path, WPAS_DBUS_OBJECT_PATH_MAX,
3266 WPAS_DBUS_NEW_PATH_INTERFACES "/%u",
3269 obj_desc = os_zalloc(sizeof(struct wpa_dbus_object_desc));
3271 wpa_printf(MSG_ERROR, "Not enough memory "
3272 "to create object description");
3276 wpas_dbus_register(obj_desc, wpa_s, NULL, wpas_dbus_interface_methods,
3277 wpas_dbus_interface_properties,
3278 wpas_dbus_interface_signals);
3280 wpa_printf(MSG_DEBUG, "dbus: Register interface object '%s'",
3281 wpa_s->dbus_new_path);
3282 if (wpa_dbus_register_object_per_iface(ctrl_iface,
3283 wpa_s->dbus_new_path,
3284 wpa_s->ifname, obj_desc))
3287 wpas_dbus_signal_interface_added(wpa_s);
3292 os_free(wpa_s->dbus_new_path);
3293 wpa_s->dbus_new_path = NULL;
3294 free_dbus_object_desc(obj_desc);
3299 int wpas_dbus_unregister_interface(struct wpa_supplicant *wpa_s)
3301 struct wpas_dbus_priv *ctrl_iface;
3303 /* Do nothing if the control interface is not turned on */
3304 if (wpa_s == NULL || wpa_s->global == NULL)
3306 ctrl_iface = wpa_s->global->dbus;
3307 if (ctrl_iface == NULL)
3310 wpa_printf(MSG_DEBUG, "dbus: Unregister interface object '%s'",
3311 wpa_s->dbus_new_path);
3314 if (wpa_s->preq_notify_peer) {
3315 wpas_dbus_unsubscribe_noc(ctrl_iface);
3316 os_free(wpa_s->preq_notify_peer);
3317 wpa_s->preq_notify_peer = NULL;
3319 #endif /* CONFIG_AP */
3321 if (wpa_dbus_unregister_object_per_iface(ctrl_iface,
3322 wpa_s->dbus_new_path))
3325 wpas_dbus_signal_interface_removed(wpa_s);
3327 os_free(wpa_s->dbus_new_path);
3328 wpa_s->dbus_new_path = NULL;
3335 static const struct wpa_dbus_property_desc wpas_dbus_p2p_peer_properties[] = {
3336 { "DeviceName", WPAS_DBUS_NEW_IFACE_P2P_PEER, "s",
3337 wpas_dbus_getter_p2p_peer_device_name,
3340 { "PrimaryDeviceType", WPAS_DBUS_NEW_IFACE_P2P_PEER, "ay",
3341 wpas_dbus_getter_p2p_peer_primary_device_type,
3344 { "config_method", WPAS_DBUS_NEW_IFACE_P2P_PEER, "q",
3345 wpas_dbus_getter_p2p_peer_config_method,
3348 { "level", WPAS_DBUS_NEW_IFACE_P2P_PEER, "i",
3349 wpas_dbus_getter_p2p_peer_level,
3352 { "devicecapability", WPAS_DBUS_NEW_IFACE_P2P_PEER, "y",
3353 wpas_dbus_getter_p2p_peer_device_capability,
3356 { "groupcapability", WPAS_DBUS_NEW_IFACE_P2P_PEER, "y",
3357 wpas_dbus_getter_p2p_peer_group_capability,
3360 { "SecondaryDeviceTypes", WPAS_DBUS_NEW_IFACE_P2P_PEER, "aay",
3361 wpas_dbus_getter_p2p_peer_secondary_device_types,
3364 { "VendorExtension", WPAS_DBUS_NEW_IFACE_P2P_PEER, "aay",
3365 wpas_dbus_getter_p2p_peer_vendor_extension,
3368 { "IEs", WPAS_DBUS_NEW_IFACE_P2P_PEER, "ay",
3369 wpas_dbus_getter_p2p_peer_ies,
3372 { "DeviceAddress", WPAS_DBUS_NEW_IFACE_P2P_PEER, "ay",
3373 wpas_dbus_getter_p2p_peer_device_address,
3376 { "Groups", WPAS_DBUS_NEW_IFACE_P2P_PEER, "ao",
3377 wpas_dbus_getter_p2p_peer_groups,
3380 { NULL, NULL, NULL, NULL, NULL }
3383 static const struct wpa_dbus_signal_desc wpas_dbus_p2p_peer_signals[] = {
3384 /* Deprecated: use org.freedesktop.DBus.Properties.PropertiesChanged */
3385 { "PropertiesChanged", WPAS_DBUS_NEW_IFACE_P2P_PEER,
3387 { "properties", "a{sv}", ARG_OUT },
3391 { NULL, NULL, { END_ARGS } }
3395 * wpas_dbus_signal_peer - Send a peer related event signal
3396 * @wpa_s: %wpa_supplicant network interface data
3397 * @dev: peer device object
3398 * @interface: name of the interface emitting this signal.
3399 * In case of peer objects, it would be emitted by either
3400 * the "interface object" or by "peer objects"
3401 * @sig_name: signal name - DeviceFound
3403 * Notify listeners about event related with newly found p2p peer device
3405 static void wpas_dbus_signal_peer(struct wpa_supplicant *wpa_s,
3406 const u8 *dev_addr, const char *interface,
3407 const char *sig_name)
3409 struct wpas_dbus_priv *iface;
3411 DBusMessageIter iter;
3412 char peer_obj_path[WPAS_DBUS_OBJECT_PATH_MAX], *path;
3414 iface = wpa_s->global->dbus;
3416 /* Do nothing if the control interface is not turned on */
3420 os_snprintf(peer_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
3421 "%s/" WPAS_DBUS_NEW_P2P_PEERS_PART "/" COMPACT_MACSTR,
3422 wpa_s->dbus_new_path, MAC2STR(dev_addr));
3424 msg = dbus_message_new_signal(wpa_s->dbus_new_path, interface,
3429 dbus_message_iter_init_append(msg, &iter);
3430 path = peer_obj_path;
3431 if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_OBJECT_PATH,
3435 dbus_connection_send(iface->con, msg, NULL);
3437 dbus_message_unref(msg);
3441 wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
3442 dbus_message_unref(msg);
3447 * wpas_dbus_signal_peer_found - Send a peer found signal
3448 * @wpa_s: %wpa_supplicant network interface data
3449 * @dev: peer device object
3451 * Notify listeners about find a p2p peer device found
3453 void wpas_dbus_signal_peer_device_found(struct wpa_supplicant *wpa_s,
3456 wpas_dbus_signal_peer(wpa_s, dev_addr,
3457 WPAS_DBUS_NEW_IFACE_P2PDEVICE,
3462 * wpas_dbus_signal_peer_lost - Send a peer lost signal
3463 * @wpa_s: %wpa_supplicant network interface data
3464 * @dev: peer device object
3466 * Notify listeners about lost a p2p peer device
3468 void wpas_dbus_signal_peer_device_lost(struct wpa_supplicant *wpa_s,
3471 wpas_dbus_signal_peer(wpa_s, dev_addr,
3472 WPAS_DBUS_NEW_IFACE_P2PDEVICE,
3477 * wpas_dbus_register_peer - Register a discovered peer object with dbus
3478 * @wpa_s: wpa_supplicant interface structure
3479 * @ssid: network configuration data
3480 * Returns: 0 on success, -1 on failure
3482 * Registers network representing object with dbus
3484 int wpas_dbus_register_peer(struct wpa_supplicant *wpa_s, const u8 *dev_addr)
3486 struct wpas_dbus_priv *ctrl_iface;
3487 struct wpa_dbus_object_desc *obj_desc;
3488 struct peer_handler_args *arg;
3489 char peer_obj_path[WPAS_DBUS_OBJECT_PATH_MAX];
3491 /* Do nothing if the control interface is not turned on */
3492 if (wpa_s == NULL || wpa_s->global == NULL)
3495 ctrl_iface = wpa_s->global->dbus;
3496 if (ctrl_iface == NULL)
3499 os_snprintf(peer_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
3500 "%s/" WPAS_DBUS_NEW_P2P_PEERS_PART "/" COMPACT_MACSTR,
3501 wpa_s->dbus_new_path, MAC2STR(dev_addr));
3503 wpa_printf(MSG_INFO, "dbus: Register peer object '%s'",
3505 obj_desc = os_zalloc(sizeof(struct wpa_dbus_object_desc));
3507 wpa_printf(MSG_ERROR, "Not enough memory "
3508 "to create object description");
3512 /* allocate memory for handlers arguments */
3513 arg = os_zalloc(sizeof(struct peer_handler_args));
3515 wpa_printf(MSG_ERROR, "Not enough memory "
3516 "to create arguments for method");
3521 os_memcpy(arg->p2p_device_addr, dev_addr, ETH_ALEN);
3523 wpas_dbus_register(obj_desc, arg, wpa_dbus_free,
3525 wpas_dbus_p2p_peer_properties,
3526 wpas_dbus_p2p_peer_signals);
3528 if (wpa_dbus_register_object_per_iface(ctrl_iface, peer_obj_path,
3529 wpa_s->ifname, obj_desc))
3535 free_dbus_object_desc(obj_desc);
3540 * wpas_dbus_unregister_peer - Unregister a peer object with dbus
3541 * @wpa_s: wpa_supplicant interface structure
3542 * @dev_addr: p2p device addr
3543 * Returns: 0 on success, -1 on failure
3545 * Registers network representing object with dbus
3547 int wpas_dbus_unregister_peer(struct wpa_supplicant *wpa_s,
3550 struct wpas_dbus_priv *ctrl_iface;
3551 char peer_obj_path[WPAS_DBUS_OBJECT_PATH_MAX];
3554 /* Do nothing if the control interface is not turned on */
3555 if (wpa_s == NULL || wpa_s->global == NULL ||
3556 wpa_s->dbus_new_path == NULL)
3558 ctrl_iface = wpa_s->global->dbus;
3559 if (ctrl_iface == NULL)
3562 os_snprintf(peer_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
3563 "%s/" WPAS_DBUS_NEW_P2P_PEERS_PART "/" COMPACT_MACSTR,
3564 wpa_s->dbus_new_path, MAC2STR(dev_addr));
3566 wpa_printf(MSG_INFO, "dbus: Unregister peer object '%s'",
3568 ret = wpa_dbus_unregister_object_per_iface(ctrl_iface, peer_obj_path);
3574 void wpas_dbus_signal_peer_groups_changed(struct wpa_supplicant *wpa_s,
3577 char peer_obj_path[WPAS_DBUS_OBJECT_PATH_MAX];
3579 os_snprintf(peer_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
3580 "%s/" WPAS_DBUS_NEW_P2P_PEERS_PART "/" COMPACT_MACSTR,
3581 wpa_s->dbus_new_path, MAC2STR(dev_addr));
3583 wpa_dbus_mark_property_changed(wpa_s->global->dbus, peer_obj_path,
3584 WPAS_DBUS_NEW_IFACE_P2P_PEER, "Groups");
3588 static const struct wpa_dbus_property_desc wpas_dbus_p2p_group_properties[] = {
3589 { "Members", WPAS_DBUS_NEW_IFACE_P2P_GROUP, "ao",
3590 wpas_dbus_getter_p2p_group_members,
3593 { "Group", WPAS_DBUS_NEW_IFACE_P2P_GROUP, "o",
3594 wpas_dbus_getter_p2p_group,
3597 { "Role", WPAS_DBUS_NEW_IFACE_P2P_GROUP, "s",
3598 wpas_dbus_getter_p2p_role,
3601 { "SSID", WPAS_DBUS_NEW_IFACE_P2P_GROUP, "ay",
3602 wpas_dbus_getter_p2p_group_ssid,
3605 { "BSSID", WPAS_DBUS_NEW_IFACE_P2P_GROUP, "ay",
3606 wpas_dbus_getter_p2p_group_bssid,
3609 { "Frequency", WPAS_DBUS_NEW_IFACE_P2P_GROUP, "q",
3610 wpas_dbus_getter_p2p_group_frequency,
3613 { "Passphrase", WPAS_DBUS_NEW_IFACE_P2P_GROUP, "s",
3614 wpas_dbus_getter_p2p_group_passphrase,
3617 { "PSK", WPAS_DBUS_NEW_IFACE_P2P_GROUP, "ay",
3618 wpas_dbus_getter_p2p_group_psk,
3621 { "WPSVendorExtensions", WPAS_DBUS_NEW_IFACE_P2P_GROUP, "aay",
3622 wpas_dbus_getter_p2p_group_vendor_ext,
3623 wpas_dbus_setter_p2p_group_vendor_ext
3625 { NULL, NULL, NULL, NULL, NULL }
3628 static const struct wpa_dbus_signal_desc wpas_dbus_p2p_group_signals[] = {
3629 { "PeerJoined", WPAS_DBUS_NEW_IFACE_P2P_GROUP,
3631 { "peer", "o", ARG_OUT },
3635 { "PeerDisconnected", WPAS_DBUS_NEW_IFACE_P2P_GROUP,
3637 { "peer", "o", ARG_OUT },
3641 { NULL, NULL, { END_ARGS } }
3645 * wpas_dbus_register_p2p_group - Register a p2p group object with dbus
3646 * @wpa_s: wpa_supplicant interface structure
3647 * @ssid: SSID struct
3648 * Returns: 0 on success, -1 on failure
3650 * Registers p2p group representing object with dbus
3652 void wpas_dbus_register_p2p_group(struct wpa_supplicant *wpa_s,
3653 struct wpa_ssid *ssid)
3655 struct wpas_dbus_priv *ctrl_iface;
3656 struct wpa_dbus_object_desc *obj_desc;
3657 char group_obj_path[WPAS_DBUS_OBJECT_PATH_MAX];
3659 /* Do nothing if the control interface is not turned on */
3660 if (wpa_s == NULL || wpa_s->global == NULL)
3663 ctrl_iface = wpa_s->global->dbus;
3664 if (ctrl_iface == NULL)
3667 if (wpa_s->dbus_groupobj_path) {
3668 wpa_printf(MSG_INFO, "%s: Group object '%s' already exists",
3669 __func__, wpa_s->dbus_groupobj_path);
3673 if (wpas_dbus_get_group_obj_path(wpa_s, ssid, group_obj_path) < 0)
3676 wpa_s->dbus_groupobj_path = os_strdup(group_obj_path);
3677 if (wpa_s->dbus_groupobj_path == NULL)
3680 wpa_printf(MSG_INFO, "dbus: Register group object '%s'",
3682 obj_desc = os_zalloc(sizeof(struct wpa_dbus_object_desc));
3684 wpa_printf(MSG_ERROR, "Not enough memory "
3685 "to create object description");
3689 wpas_dbus_register(obj_desc, wpa_s, NULL, NULL,
3690 wpas_dbus_p2p_group_properties,
3691 wpas_dbus_p2p_group_signals);
3693 if (wpa_dbus_register_object_per_iface(ctrl_iface, group_obj_path,
3694 wpa_s->ifname, obj_desc))
3700 if (wpa_s->dbus_groupobj_path) {
3701 os_free(wpa_s->dbus_groupobj_path);
3702 wpa_s->dbus_groupobj_path = NULL;
3705 free_dbus_object_desc(obj_desc);
3709 * wpas_dbus_unregister_p2p_group - Unregister a p2p group object from dbus
3710 * @wpa_s: wpa_supplicant interface structure
3711 * @ssid: network name of the p2p group started
3713 void wpas_dbus_unregister_p2p_group(struct wpa_supplicant *wpa_s,
3714 const struct wpa_ssid *ssid)
3716 struct wpas_dbus_priv *ctrl_iface;
3718 /* Do nothing if the control interface is not turned on */
3719 if (wpa_s == NULL || wpa_s->global == NULL)
3722 ctrl_iface = wpa_s->global->dbus;
3723 if (ctrl_iface == NULL)
3726 if (!wpa_s->dbus_groupobj_path) {
3727 wpa_printf(MSG_DEBUG,
3728 "%s: Group object '%s' already unregistered",
3729 __func__, wpa_s->dbus_groupobj_path);
3733 peer_groups_changed(wpa_s);
3735 wpa_printf(MSG_DEBUG, "dbus: Unregister group object '%s'",
3736 wpa_s->dbus_groupobj_path);
3738 wpa_dbus_unregister_object_per_iface(ctrl_iface,
3739 wpa_s->dbus_groupobj_path);
3741 os_free(wpa_s->dbus_groupobj_path);
3742 wpa_s->dbus_groupobj_path = NULL;
3745 static const struct wpa_dbus_property_desc
3746 wpas_dbus_persistent_group_properties[] = {
3747 { "Properties", WPAS_DBUS_NEW_IFACE_PERSISTENT_GROUP, "a{sv}",
3748 wpas_dbus_getter_persistent_group_properties,
3749 wpas_dbus_setter_persistent_group_properties
3751 { NULL, NULL, NULL, NULL, NULL }
3754 /* No signals intended for persistent group objects */
3757 * wpas_dbus_register_persistent_group - Register a configured(saved)
3758 * persistent group with dbus
3759 * @wpa_s: wpa_supplicant interface structure
3760 * @ssid: persistent group (still represented as a network within wpa)
3761 * configuration data
3762 * Returns: 0 on success, -1 on failure
3764 * Registers a persistent group representing object with dbus.
3766 int wpas_dbus_register_persistent_group(struct wpa_supplicant *wpa_s,
3767 struct wpa_ssid *ssid)
3769 struct wpas_dbus_priv *ctrl_iface;
3770 struct wpa_dbus_object_desc *obj_desc;
3771 struct network_handler_args *arg;
3772 char pgrp_obj_path[WPAS_DBUS_OBJECT_PATH_MAX];
3774 /* Do nothing if the control interface is not turned on */
3775 if (wpa_s == NULL || wpa_s->global == NULL)
3778 /* Make sure ssid is a persistent group */
3779 if (ssid->disabled != 2 && !ssid->p2p_persistent_group)
3780 return -1; /* should we return w/o complaining? */
3782 ctrl_iface = wpa_s->global->dbus;
3783 if (ctrl_iface == NULL)
3787 * Intentionally not coming up with different numbering scheme
3788 * for persistent groups.
3790 os_snprintf(pgrp_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
3791 "%s/" WPAS_DBUS_NEW_PERSISTENT_GROUPS_PART "/%u",
3792 wpa_s->dbus_new_path, ssid->id);
3794 wpa_printf(MSG_DEBUG, "dbus: Register persistent group object '%s'",
3796 obj_desc = os_zalloc(sizeof(struct wpa_dbus_object_desc));
3798 wpa_printf(MSG_ERROR, "dbus: Not enough memory to create "
3799 "object description");
3804 * Reusing the same context structure as that for networks
3805 * since these are represented using same data structure.
3807 /* allocate memory for handlers arguments */
3808 arg = os_zalloc(sizeof(struct network_handler_args));
3810 wpa_printf(MSG_ERROR, "dbus: Not enough memory to create "
3811 "arguments for method");
3818 wpas_dbus_register(obj_desc, arg, wpa_dbus_free, NULL,
3819 wpas_dbus_persistent_group_properties,
3822 if (wpa_dbus_register_object_per_iface(ctrl_iface, pgrp_obj_path,
3823 wpa_s->ifname, obj_desc))
3826 wpas_dbus_signal_persistent_group_added(wpa_s, ssid->id);
3831 free_dbus_object_desc(obj_desc);
3837 * wpas_dbus_unregister_persistent_group - Unregister a persistent_group
3839 * @wpa_s: wpa_supplicant interface structure
3841 * Returns: 0 on success, -1 on failure
3843 * Unregisters persistent group representing object from dbus
3845 * NOTE: There is a slight issue with the semantics here. While the
3846 * implementation simply means the persistent group is unloaded from memory,
3847 * it should not get interpreted as the group is actually being erased/removed
3848 * from persistent storage as well.
3850 int wpas_dbus_unregister_persistent_group(struct wpa_supplicant *wpa_s,
3853 struct wpas_dbus_priv *ctrl_iface;
3854 char pgrp_obj_path[WPAS_DBUS_OBJECT_PATH_MAX];
3857 /* Do nothing if the control interface is not turned on */
3858 if (wpa_s == NULL || wpa_s->global == NULL ||
3859 wpa_s->dbus_new_path == NULL)
3861 ctrl_iface = wpa_s->global->dbus;
3862 if (ctrl_iface == NULL)
3865 os_snprintf(pgrp_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
3866 "%s/" WPAS_DBUS_NEW_PERSISTENT_GROUPS_PART "/%u",
3867 wpa_s->dbus_new_path, nid);
3869 wpa_printf(MSG_DEBUG, "dbus: Unregister persistent group object '%s'",
3871 ret = wpa_dbus_unregister_object_per_iface(ctrl_iface, pgrp_obj_path);
3874 wpas_dbus_signal_persistent_group_removed(wpa_s, nid);
3879 #endif /* CONFIG_P2P */