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