2 * WPA Supplicant / dbus-based control interface
3 * Copyright (c) 2006, Dan Williams <dcbw@redhat.com> and Red Hat, Inc.
4 * Copyright (c) 2009, 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.
21 #include "../config.h"
22 #include "../wpa_supplicant_i.h"
24 #include "dbus_new_helpers.h"
25 #include "dbus_dict_helpers.h"
27 #include "dbus_new_handlers.h"
28 #include "dbus_common.h"
29 #include "dbus_common_i.h"
32 * wpas_dbus_set_path - Assign a dbus path to an interface
33 * @wpa_s: wpa_supplicant interface structure
34 * @path: dbus path to set on the interface
35 * Returns: 0 on success, -1 on error
37 static int wpas_dbus_set_path(struct wpa_supplicant *wpa_s,
40 u32 len = os_strlen(path);
41 if (len >= WPAS_DBUS_OBJECT_PATH_MAX)
43 if (wpa_s->dbus_new_path)
45 wpa_s->dbus_new_path = os_strdup(path);
51 * wpas_dbus_signal_interface - Send a interface related event signal
52 * @wpa_s: %wpa_supplicant network interface data
53 * @sig_name: signal name - InterfaceAdded or InterfaceRemoved
54 * @properties: determines if add second argument with object properties
56 * Notify listeners about event related with interface
58 static void wpas_dbus_signal_interface(struct wpa_supplicant *wpa_s,
59 const char *sig_name, int properties)
61 struct wpas_dbus_priv *iface;
63 DBusMessageIter iter, iter_dict;
66 iface = wpa_s->global->dbus;
68 /* Do nothing if the control interface is not turned on */
72 path = wpas_dbus_get_path(wpa_s);
74 wpa_printf(MSG_ERROR, "wpas_dbus_signal_interface[dbus]: "
75 "Interface doesn't have a dbus path. "
76 "Can't send signal.");
79 _signal = dbus_message_new_signal(WPAS_DBUS_NEW_PATH,
80 WPAS_DBUS_NEW_INTERFACE, sig_name);
81 if (_signal == NULL) {
82 wpa_printf(MSG_ERROR, "wpas_dbus_signal_interface[dbus]: "
83 "enough memory to send scan results signal.");
87 dbus_message_iter_init_append(_signal, &iter);
89 if(!dbus_message_iter_append_basic(&iter, DBUS_TYPE_OBJECT_PATH,
94 if (!wpa_dbus_dict_open_write(&iter, &iter_dict))
97 wpa_dbus_get_object_properties(iface, path,
98 WPAS_DBUS_NEW_IFACE_INTERFACE,
101 if (!wpa_dbus_dict_close_write(&iter, &iter_dict))
105 dbus_connection_send(iface->con, _signal, NULL);
107 dbus_message_unref(_signal);
111 wpa_printf(MSG_ERROR, "wpas_dbus_signal_interface[dbus]: "
112 "not enough memory to construct signal.");
113 dbus_message_unref(_signal);
118 * wpas_dbus_signal_interface_added - Send a interface created signal
119 * @wpa_s: %wpa_supplicant network interface data
121 * Notify listeners about creating new interface
123 static void wpas_dbus_signal_interface_added(struct wpa_supplicant *wpa_s)
125 wpas_dbus_signal_interface(wpa_s, "InterfaceAdded", TRUE);
130 * wpas_dbus_signal_interface_removed - Send a interface removed signal
131 * @wpa_s: %wpa_supplicant network interface data
133 * Notify listeners about removing interface
135 static void wpas_dbus_signal_interface_removed(struct wpa_supplicant *wpa_s)
137 wpas_dbus_signal_interface(wpa_s, "InterfaceRemoved", FALSE);
143 * wpas_dbus_signal_scan_done - send scan done signal
144 * @wpa_s: %wpa_supplicant network interface data
145 * @success: indicates if scanning succeed or failed
147 * Notify listeners about finishing a scan
149 static void wpas_dbus_signal_scan_done(struct wpa_supplicant *wpa_s,
152 struct wpas_dbus_priv *iface;
153 DBusMessage *_signal;
157 iface = wpa_s->global->dbus;
159 /* Do nothing if the control interface is not turned on */
163 path = wpas_dbus_get_path(wpa_s);
165 wpa_printf(MSG_ERROR, "wpas_dbus_signal_scan_done[dbus]: "
166 "Interface doesn't have a dbus path. "
167 "Can't send signal.");
170 _signal = dbus_message_new_signal(path, WPAS_DBUS_NEW_IFACE_INTERFACE,
172 if (_signal == NULL) {
173 wpa_printf(MSG_ERROR, "wpas_dbus_signal_scan_done[dbus]: "
174 "enough memory to send signal.");
178 succ = success ? TRUE : FALSE;
179 if (dbus_message_append_args(_signal, DBUS_TYPE_BOOLEAN, &succ,
180 DBUS_TYPE_INVALID)) {
181 dbus_connection_send(iface->con, _signal, NULL);
183 wpa_printf(MSG_ERROR, "wpas_dbus_signal_scan_done[dbus]: "
184 "not enough memory to construct signal.");
186 dbus_message_unref(_signal);
191 * wpas_dbus_signal_blob - Send a BSS related event signal
192 * @wpa_s: %wpa_supplicant network interface data
193 * @bss_obj_path: BSS object path
194 * @sig_name: signal name - BSSAdded or BSSRemoved
195 * @properties: determines if add second argument with object properties
197 * Notify listeners about event related with BSS
199 static void wpas_dbus_signal_bss(struct wpa_supplicant *wpa_s,
200 const char *bss_obj_path,
201 const char *sig_name, int properties)
203 struct wpas_dbus_priv *iface;
204 DBusMessage *_signal;
205 DBusMessageIter iter, iter_dict;
208 iface = wpa_s->global->dbus;
210 /* Do nothing if the control interface is not turned on */
214 path = wpas_dbus_get_path(wpa_s);
216 wpa_printf(MSG_ERROR, "wpas_dbus_signal_bss[dbus]: "
217 "Interface doesn't have a dbus path. "
218 "Can't send signal.");
221 _signal = dbus_message_new_signal(path, WPAS_DBUS_NEW_IFACE_INTERFACE,
223 if (_signal == NULL) {
224 wpa_printf(MSG_ERROR, "wpas_dbus_signal_bss[dbus]: "
225 "enough memory to send signal.");
229 dbus_message_iter_init_append(_signal, &iter);
231 if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_OBJECT_PATH,
236 if (!wpa_dbus_dict_open_write(&iter, &iter_dict))
239 wpa_dbus_get_object_properties(iface, bss_obj_path,
240 WPAS_DBUS_NEW_IFACE_BSSID,
243 if (!wpa_dbus_dict_close_write(&iter, &iter_dict))
247 dbus_connection_send(iface->con, _signal, NULL);
249 dbus_message_unref(_signal);
253 wpa_printf(MSG_ERROR, "wpas_dbus_signal_bss[dbus]: "
254 "not enough memory to construct signal.");
255 dbus_message_unref(_signal);
260 * wpas_dbus_signal_bss_added - Send a BSS added signal
261 * @wpa_s: %wpa_supplicant network interface data
262 * @bss_obj_path: new BSS object path
264 * Notify listeners about adding new BSS
266 static void wpas_dbus_signal_bss_added(struct wpa_supplicant *wpa_s,
267 const char *bss_obj_path)
269 wpas_dbus_signal_bss(wpa_s, bss_obj_path, "BSSAdded", TRUE);
274 * wpas_dbus_signal_bss_removed - Send a BSS removed signal
275 * @wpa_s: %wpa_supplicant network interface data
276 * @bss_obj_path: BSS object path
278 * Notify listeners about removing BSS
280 static void wpas_dbus_signal_bss_removed(struct wpa_supplicant *wpa_s,
281 const char *bss_obj_path)
283 wpas_dbus_signal_bss(wpa_s, bss_obj_path, "BSSRemoved", FALSE);
288 * wpas_dbus_signal_blob - Send a blob related event signal
289 * @wpa_s: %wpa_supplicant network interface data
291 * @sig_name: signal name - BlobAdded or BlobRemoved
293 * Notify listeners about event related with blob
295 static void wpas_dbus_signal_blob(struct wpa_supplicant *wpa_s,
296 const char *name, const char *sig_name)
298 struct wpas_dbus_priv *iface;
299 DBusMessage *_signal;
302 iface = wpa_s->global->dbus;
304 /* Do nothing if the control interface is not turned on */
308 path = wpas_dbus_get_path(wpa_s);
310 wpa_printf(MSG_ERROR, "wpas_dbus_signal_blob[dbus]: "
311 "Interface doesn't have a dbus path. "
312 "Can't send signal.");
315 _signal = dbus_message_new_signal(path, WPAS_DBUS_NEW_IFACE_INTERFACE,
317 if (_signal == NULL) {
318 wpa_printf(MSG_ERROR, "wpas_dbus_signal_blob[dbus]: "
319 "enough memory to send signal.");
323 if (dbus_message_append_args(_signal, DBUS_TYPE_STRING, &name,
324 DBUS_TYPE_INVALID)) {
325 dbus_connection_send(iface->con, _signal, NULL);
327 wpa_printf(MSG_ERROR, "wpas_dbus_signal_blob[dbus]: "
328 "not enough memory to construct signal.");
330 dbus_message_unref(_signal);
335 * wpas_dbus_signal_blob_added - Send a blob added signal
336 * @wpa_s: %wpa_supplicant network interface data
339 * Notify listeners about adding a new blob
341 static void wpas_dbus_signal_blob_added(struct wpa_supplicant *wpa_s,
344 wpas_dbus_signal_blob(wpa_s, name, "BlobAdded");
349 * wpas_dbus_signal_blob_removed - Send a blob removed signal
350 * @wpa_s: %wpa_supplicant network interface data
353 * Notify listeners about removing blob
355 static void wpas_dbus_signal_blob_removed(struct wpa_supplicant *wpa_s,
358 wpas_dbus_signal_blob(wpa_s, name, "BlobRemoved");
363 * wpas_dbus_signal_network - Send a network related event signal
364 * @wpa_s: %wpa_supplicant network interface data
365 * @id: new network id
366 * @sig_name: signal name - NetworkAdded, NetworkRemoved or NetworkSelected
367 * @properties: determines if add second argument with object properties
369 * Notify listeners about event related with configured network
371 static void wpas_dbus_signal_network(struct wpa_supplicant *wpa_s,
372 int id, const char *sig_name,
375 struct wpas_dbus_priv *iface;
376 DBusMessage *_signal;
377 DBusMessageIter iter, iter_dict;
381 iface = wpa_s->global->dbus;
383 /* Do nothing if the control interface is not turned on */
387 path = wpas_dbus_get_path(wpa_s);
389 wpa_printf(MSG_ERROR, "wpas_dbus_signal_network[dbus]: "
390 "Interface doesn't have a dbus path. "
391 "Can't send signal.");
395 net_obj_path = os_zalloc(WPAS_DBUS_OBJECT_PATH_MAX);
396 if (net_obj_path == NULL)
398 os_snprintf(net_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
399 "%s/" WPAS_DBUS_NEW_NETWORKS_PART "/%u", path, id);
401 _signal = dbus_message_new_signal(path, WPAS_DBUS_NEW_IFACE_INTERFACE,
403 if (_signal == NULL) {
404 wpa_printf(MSG_ERROR, "wpas_dbus_signal_network[dbus]: "
405 "enough memory to send signal.");
406 os_free(net_obj_path);
410 dbus_message_iter_init_append(_signal, &iter);
412 if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_OBJECT_PATH,
417 if (!wpa_dbus_dict_open_write(&iter, &iter_dict))
420 wpa_dbus_get_object_properties(iface, net_obj_path,
421 WPAS_DBUS_NEW_IFACE_NETWORK,
424 if (!wpa_dbus_dict_close_write(&iter, &iter_dict))
428 dbus_connection_send(iface->con, _signal, NULL);
430 os_free(net_obj_path);
431 dbus_message_unref(_signal);
435 wpa_printf(MSG_ERROR, "wpas_dbus_signal_network[dbus]: "
436 "not enough memory to construct signal.");
437 os_free(net_obj_path);
438 dbus_message_unref(_signal);
443 * wpas_dbus_signal_network_added - Send a network added signal
444 * @wpa_s: %wpa_supplicant network interface data
445 * @id: new network id
447 * Notify listeners about adding new network
449 static void wpas_dbus_signal_network_added(struct wpa_supplicant *wpa_s,
452 wpas_dbus_signal_network(wpa_s, id, "NetworkAdded", TRUE);
457 * wpas_dbus_signal_network_removed - Send a network removed signal
458 * @wpa_s: %wpa_supplicant network interface data
461 * Notify listeners about removing a network
463 static void wpas_dbus_signal_network_removed(struct wpa_supplicant *wpa_s,
466 wpas_dbus_signal_network(wpa_s, id, "NetworkRemoved", FALSE);
471 * wpas_dbus_signal_network_selected - Send a network selected signal
472 * @wpa_s: %wpa_supplicant network interface data
475 * Notify listeners about selecting a network
477 static void wpas_dbus_signal_network_selected(struct wpa_supplicant *wpa_s,
480 wpas_dbus_signal_network(wpa_s, id, "NetworkSelected", FALSE);
485 * wpas_dbus_signal_state_changed - Send a state changed signal
486 * @wpa_s: %wpa_supplicant network interface data
487 * @new_state: new state wpa_supplicant is entering
488 * @old_state: old state wpa_supplicant is leaving
490 * Notify listeners that wpa_supplicant has changed state
492 static void wpas_dbus_signal_state_changed(struct wpa_supplicant *wpa_s,
493 enum wpa_states new_state,
494 enum wpa_states old_state)
496 struct wpas_dbus_priv *iface;
497 DBusMessage *_signal = NULL;
499 char *new_state_str, *old_state_str;
502 /* Do nothing if the control interface is not turned on */
503 if (wpa_s->global == NULL)
505 iface = wpa_s->global->dbus;
509 /* Only send signal if state really changed */
510 if (new_state == old_state)
513 path = wpas_dbus_get_path(wpa_s);
515 perror("wpas_dbus_signal_state_changed[dbus]: "
516 "interface didn't have a dbus path");
517 wpa_printf(MSG_ERROR,
518 "wpas_dbus_signal_state_changed[dbus]: "
519 "interface didn't have a dbus path; can't send "
523 _signal = dbus_message_new_signal(path, WPAS_DBUS_NEW_IFACE_INTERFACE,
525 if (_signal == NULL) {
526 perror("wpas_dbus_signal_state_changed[dbus]: "
527 "couldn't create dbus signal; likely out of memory");
528 wpa_printf(MSG_ERROR,
529 "wpas_dbus_signal_state_changed[dbus]: "
530 "couldn't create dbus signal; likely out of "
535 new_state_str = os_strdup(wpa_supplicant_state_txt(new_state));
536 old_state_str = os_strdup(wpa_supplicant_state_txt(old_state));
537 if (new_state_str == NULL || old_state_str == NULL) {
538 perror("wpas_dbus_signal_state_changed[dbus]: "
539 "couldn't convert state strings");
540 wpa_printf(MSG_ERROR,
541 "wpas_dbus_signal_state_changed[dbus]: "
542 "couldn't convert state strings.");
546 /* make state string lowercase to fit new DBus API convention */
549 *tmp = tolower(*tmp);
554 *tmp = tolower(*tmp);
558 if (!dbus_message_append_args(_signal,
559 DBUS_TYPE_STRING, &new_state_str,
560 DBUS_TYPE_STRING, &old_state_str,
561 DBUS_TYPE_INVALID)) {
562 perror("wpas_dbus_signal_state_changed[dbus]: "
563 "not enough memory to construct state change signal.");
564 wpa_printf(MSG_ERROR,
565 "wpas_dbus_signal_state_changed[dbus]: "
566 "not enough memory to construct state change "
571 dbus_connection_send(iface->con, _signal, NULL);
574 dbus_message_unref(_signal);
575 os_free(new_state_str);
576 os_free(old_state_str);
581 * wpas_dbus_signal_network_enabled_changed - Signals Enabled property changes
582 * @wpa_s: %wpa_supplicant network interface data
583 * @ssid: configured network which Enabled property has changed
585 * Sends PropertyChanged signals containing new value of Enabled property
586 * for specified network
588 static void wpas_dbus_signal_network_enabled_changed(
589 struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid)
592 struct network_handler_args args = {wpa_s, ssid};
594 char path[WPAS_DBUS_OBJECT_PATH_MAX];
595 os_snprintf(path, WPAS_DBUS_OBJECT_PATH_MAX,
596 "%s/" WPAS_DBUS_NEW_NETWORKS_PART "/%d",
597 wpas_dbus_get_path(wpa_s), ssid->id);
599 wpa_dbus_signal_property_changed(wpa_s->global->dbus,
600 (WPADBusPropertyAccessor)
601 wpas_dbus_getter_enabled, &args,
602 path, WPAS_DBUS_NEW_IFACE_NETWORK,
610 * wpas_dbus_signal_wps_event_success - Signals Success WPS event
611 * @wpa_s: %wpa_supplicant network interface data
613 * Sends Event dbus signal with name "success" and empty dict as arguments
615 static void wpas_dbus_signal_wps_event_success(struct wpa_supplicant *wpa_s)
618 DBusMessage *_signal = NULL;
619 DBusMessageIter iter, dict_iter;
620 struct wpas_dbus_priv *iface;
621 char *key = "success";
624 iface = wpa_s->global->dbus;
626 /* Do nothing if the control interface is not turned on */
630 path = wpas_dbus_get_path(wpa_s);
632 wpa_printf(MSG_ERROR, "wpas_dbus_signal_wps_event_success"
633 "[dbus]: interface has no dbus path set");
637 _signal = dbus_message_new_signal(path, WPAS_DBUS_NEW_IFACE_WPS,
640 wpa_printf(MSG_ERROR, "wpas_dbus_signal_wps_event_success"
641 "[dbus]: out of memory when creating a signal");
645 dbus_message_iter_init_append(_signal, &iter);
647 if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &key) ||
648 !wpa_dbus_dict_open_write(&iter, &dict_iter) ||
649 !wpa_dbus_dict_close_write(&iter, &dict_iter)) {
650 wpa_printf(MSG_ERROR, "wpas_dbus_signal_wps_event_success"
651 "[dbus]: out of memory");
655 dbus_connection_send(iface->con, _signal, NULL);
657 dbus_message_unref(_signal);
662 * wpas_dbus_signal_wps_event_fail - Signals Fail WPS event
663 * @wpa_s: %wpa_supplicant network interface data
665 * Sends Event dbus signal with name "fail" and dictionary containing
666 * "msg field with fail message number (int32) as arguments
668 static void wpas_dbus_signal_wps_event_fail(struct wpa_supplicant *wpa_s,
669 struct wps_event_fail *fail)
672 DBusMessage *_signal = NULL;
673 DBusMessageIter iter, dict_iter;
674 struct wpas_dbus_priv *iface;
678 iface = wpa_s->global->dbus;
680 /* Do nothing if the control interface is not turned on */
684 path = wpas_dbus_get_path(wpa_s);
686 wpa_printf(MSG_ERROR, "wpas_dbus_signal_wps_event_fail[dbus]: "
687 "interface has no dbus path set");
691 _signal = dbus_message_new_signal(path, WPAS_DBUS_NEW_IFACE_WPS,
694 wpa_printf(MSG_ERROR, "wpas_dbus_signal_wps_event_fail[dbus]: "
695 "out of memory when creating a signal");
699 dbus_message_iter_init_append(_signal, &iter);
701 if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &key) ||
702 !wpa_dbus_dict_open_write(&iter, &dict_iter) ||
703 !wpa_dbus_dict_append_int32(&dict_iter, "msg", fail->msg) ||
704 !wpa_dbus_dict_close_write(&iter, &dict_iter)) {
705 wpa_printf(MSG_ERROR, "wpas_dbus_signal_wps_event_fail[dbus]: "
710 dbus_connection_send(iface->con, _signal, NULL);
712 dbus_message_unref(_signal);
717 * wpas_dbus_signal_wps_event_m2d - Signals M2D WPS event
718 * @wpa_s: %wpa_supplicant network interface data
720 * Sends Event dbus signal with name "m2d" and dictionary containing
721 * fields of wps_event_m2d structure.
723 static void wpas_dbus_signal_wps_event_m2d(struct wpa_supplicant *wpa_s,
724 struct wps_event_m2d *m2d)
727 DBusMessage *_signal = NULL;
728 DBusMessageIter iter, dict_iter;
729 struct wpas_dbus_priv *iface;
733 iface = wpa_s->global->dbus;
735 /* Do nothing if the control interface is not turned on */
739 path = wpas_dbus_get_path(wpa_s);
741 wpa_printf(MSG_ERROR, "wpas_dbus_signal_wps_event_m2d[dbus]: "
742 "interface has no dbus path set");
746 _signal = dbus_message_new_signal(path, WPAS_DBUS_NEW_IFACE_WPS,
749 wpa_printf(MSG_ERROR, "wpas_dbus_signal_wps_event_m2d[dbus]: "
750 "out of memory when creating a signal");
754 dbus_message_iter_init_append(_signal, &iter);
756 if (!(dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &key) &&
757 wpa_dbus_dict_open_write(&iter, &dict_iter) &&
758 wpa_dbus_dict_append_uint16(&dict_iter, "config_methods",
759 m2d->config_methods) &&
760 wpa_dbus_dict_append_byte_array(&dict_iter, "manufacturer",
761 (const char *) m2d->manufacturer,
762 m2d->manufacturer_len) &&
763 wpa_dbus_dict_append_byte_array(&dict_iter, "model_name",
764 (const char *) m2d->model_name,
765 m2d->model_name_len) &&
766 wpa_dbus_dict_append_byte_array(&dict_iter, "model_number",
767 (const char *) m2d->model_number,
768 m2d->model_number_len) &&
769 wpa_dbus_dict_append_byte_array(&dict_iter, "serial_number",
772 m2d->serial_number_len) &&
773 wpa_dbus_dict_append_byte_array(&dict_iter, "dev_name",
774 (const char *) m2d->dev_name,
775 m2d->dev_name_len) &&
776 wpa_dbus_dict_append_byte_array(&dict_iter, "primary_dev_type",
778 m2d->primary_dev_type, 8) &&
779 wpa_dbus_dict_append_uint16(&dict_iter, "config_error",
780 m2d->config_error) &&
781 wpa_dbus_dict_append_uint16(&dict_iter, "dev_password_id",
782 m2d->dev_password_id) &&
783 wpa_dbus_dict_close_write(&iter, &dict_iter))) {
784 wpa_printf(MSG_ERROR, "wpas_dbus_signal_wps_event_m2d[dbus]: "
789 dbus_connection_send(iface->con, _signal, NULL);
791 dbus_message_unref(_signal);
796 * wpas_dbus_signal_wps_cred - Signals new credentials
797 * @wpa_s: %wpa_supplicant network interface data
799 * Sends signal with credentials in directory argument
801 static void wpas_dbus_signal_wps_cred(struct wpa_supplicant *wpa_s,
802 const struct wps_credential *cred)
804 DBusMessage *_signal = NULL;
805 DBusMessageIter iter, dict_iter;
806 struct wpas_dbus_priv *iface;
808 char *auth_type[6]; /* we have six possible authorization types */
810 char *encr_type[4]; /* we have four possible encryption types */
813 iface = wpa_s->global->dbus;
815 /* Do nothing if the control interface is not turned on */
819 path = wpas_dbus_get_path(wpa_s);
821 wpa_printf(MSG_ERROR, "wpas_dbus_signal_wps_cred[dbus]: "
822 "interface has no dbus path set");
826 _signal = dbus_message_new_signal(path, WPAS_DBUS_NEW_IFACE_WPS,
829 wpa_printf(MSG_ERROR, "wpas_dbus_signal_wps_cred[dbus]: "
830 "out of memory when creating a signal");
834 dbus_message_iter_init_append(_signal, &iter);
836 if (!wpa_dbus_dict_open_write(&iter, &dict_iter)) {
837 perror("wpas_dbus_signal_wps_cred[dbus]: out of memory "
838 "when opening a dictionary");
842 if (cred->auth_type & WPS_AUTH_OPEN)
843 auth_type[at_num++] = "open";
844 if (cred->auth_type & WPS_AUTH_WPAPSK)
845 auth_type[at_num++] = "wpa-psk";
846 if (cred->auth_type & WPS_AUTH_SHARED)
847 auth_type[at_num++] = "shared";
848 if (cred->auth_type & WPS_AUTH_WPA)
849 auth_type[at_num++] = "wpa-eap";
850 if (cred->auth_type & WPS_AUTH_WPA2)
851 auth_type[at_num++] = "wpa2-eap";
852 if (cred->auth_type & WPS_AUTH_WPA2PSK)
853 auth_type[at_num++] =
856 if (cred->encr_type & WPS_ENCR_NONE)
857 encr_type[et_num++] = "none";
858 if (cred->encr_type & WPS_ENCR_WEP)
859 encr_type[et_num++] = "wep";
860 if (cred->encr_type & WPS_ENCR_TKIP)
861 encr_type[et_num++] = "tkip";
862 if (cred->encr_type & WPS_ENCR_AES)
863 encr_type[et_num++] = "aes";
865 if (wpa_s->current_ssid) {
866 if (!wpa_dbus_dict_append_byte_array(
868 (const char *) wpa_s->current_ssid->bssid,
870 perror("wpas_dbus_signal_wps_cred[dbus]: out of "
871 "memory when appending bssid to dictionary");
876 if (!(wpa_dbus_dict_append_byte_array(&dict_iter, "SSID",
877 (const char *) cred->ssid,
879 wpa_dbus_dict_append_string_array(&dict_iter, "AuthType",
880 (const char **) auth_type,
882 wpa_dbus_dict_append_string_array(&dict_iter, "EncrType",
883 (const char **) encr_type,
885 wpa_dbus_dict_append_byte_array(&dict_iter, "Key",
886 (const char *) cred->key,
888 wpa_dbus_dict_append_uint32(&dict_iter, "KeyIndex",
890 perror("wpas_dbus_signal_wps_cred[dbus]: out of memory "
891 "when appending to dictionary");
895 if (!wpa_dbus_dict_close_write(&iter, &dict_iter)) {
896 perror("wpas_dbus_signal_wps_cred[dbus]: out of memory "
897 "when closing a dictionary");
901 dbus_connection_send(iface->con, _signal, NULL);
904 dbus_message_unref(_signal);
907 #endif /* CONFIG_WPS */
911 * wpas_dbus_signal_prop_changed - Signals change of property
912 * @wpa_s: %wpa_supplicant network interface data
913 * @property: indicates which property has changed
915 * Sends ProertyChanged signals with path, interface and arguments
916 * depending on which property has changed.
918 static void wpas_dbus_signal_prop_changed(struct wpa_supplicant *wpa_s,
919 enum wpas_dbus_prop property)
921 WPADBusPropertyAccessor getter;
927 case WPAS_DBUS_PROP_AP_SCAN:
928 getter = (WPADBusPropertyAccessor) wpas_dbus_getter_ap_scan;
930 iface = WPAS_DBUS_NEW_IFACE_INTERFACE;
933 case WPAS_DBUS_PROP_SCANNING:
934 getter = (WPADBusPropertyAccessor) wpas_dbus_getter_scanning;
936 iface = WPAS_DBUS_NEW_IFACE_INTERFACE;
939 case WPAS_DBUS_PROP_CURRENT_BSS:
940 getter = (WPADBusPropertyAccessor)
941 wpas_dbus_getter_current_bss;
943 iface = WPAS_DBUS_NEW_IFACE_INTERFACE;
946 case WPAS_DBUS_PROP_CURRENT_NETWORK:
947 getter = (WPADBusPropertyAccessor)
948 wpas_dbus_getter_current_network;
950 iface = WPAS_DBUS_NEW_IFACE_INTERFACE;
951 prop = "CurrentNetwork";
954 wpa_printf(MSG_ERROR, "wpas_dbus_signal_prop_changed[dbus]: "
955 "Unknown Property enum value %d", property);
959 wpa_dbus_signal_property_changed(wpa_s->global->dbus,
961 wpas_dbus_get_path(wpa_s), iface,
967 * wpas_dbus_signal_debug_level_changed - Signals change of debug param
968 * @global: wpa_global structure
970 * Sends ProertyChanged signals informing that debug level has changed.
972 static void wpas_dbus_signal_debug_level_changed(struct wpa_global *global)
974 wpa_dbus_signal_property_changed(global->dbus,
975 (WPADBusPropertyAccessor)
976 wpas_dbus_getter_debug_level,
977 global, WPAS_DBUS_NEW_PATH,
978 WPAS_DBUS_NEW_INTERFACE,
984 * wpas_dbus_signal_debug_timestamp_changed - Signals change of debug param
985 * @global: wpa_global structure
987 * Sends ProertyChanged signals informing that debug timestamp has changed.
989 static void wpas_dbus_signal_debug_timestamp_changed(struct wpa_global *global)
991 wpa_dbus_signal_property_changed(global->dbus,
992 (WPADBusPropertyAccessor)
993 wpas_dbus_getter_debug_timestamp,
994 global, WPAS_DBUS_NEW_PATH,
995 WPAS_DBUS_NEW_INTERFACE,
1001 * wpas_dbus_signal_debug_show_keys_changed - Signals change of debug param
1002 * @global: wpa_global structure
1004 * Sends ProertyChanged signals informing that debug show_keys has changed.
1006 static void wpas_dbus_signal_debug_show_keys_changed(struct wpa_global *global)
1008 wpa_dbus_signal_property_changed(global->dbus,
1009 (WPADBusPropertyAccessor)
1010 wpas_dbus_getter_debug_show_keys,
1011 global, WPAS_DBUS_NEW_PATH,
1012 WPAS_DBUS_NEW_INTERFACE,
1017 struct wpas_dbus_method {
1020 WPADBusMethodHandler handler;
1021 struct wpa_dbus_argument args[3];
1024 struct wpas_dbus_property {
1028 WPADBusPropertyAccessor getter;
1029 WPADBusPropertyAccessor setter;
1030 enum dbus_prop_access _access;
1033 struct wpas_dbus_signal {
1036 struct wpa_dbus_argument args[3];
1040 static void wpas_dbus_register(struct wpa_dbus_object_desc *obj_desc,
1042 WPADBusArgumentFreeFunction priv_free,
1043 const struct wpas_dbus_method *methods,
1044 const struct wpas_dbus_property *properties,
1045 const struct wpas_dbus_signal *signals)
1049 obj_desc->user_data = priv;
1050 obj_desc->user_data_free_func = priv_free;
1052 for (i = 0; methods && methods[i].name; i++) {
1053 wpa_dbus_method_register(obj_desc, methods[i].iface,
1054 methods[i].name, methods[i].handler,
1058 for (i = 0; properties && properties[i].name; i++) {
1059 wpa_dbus_property_register(obj_desc, properties[i].iface,
1062 properties[i].getter,
1063 properties[i].setter,
1064 properties[i]._access);
1067 for (i = 0; signals && signals[i].name; i++) {
1068 wpa_dbus_signal_register(obj_desc, signals[i].iface,
1069 signals[i].name, signals[i].args);
1074 static const struct wpas_dbus_method wpas_dbus_global_methods[] = {
1075 { "CreateInterface", WPAS_DBUS_NEW_INTERFACE,
1076 (WPADBusMethodHandler) &wpas_dbus_handler_create_interface,
1078 { "args", "a{sv}", ARG_IN },
1079 { "path", "o", ARG_OUT },
1083 { "RemoveInterface", WPAS_DBUS_NEW_INTERFACE,
1084 (WPADBusMethodHandler) &wpas_dbus_handler_remove_interface,
1086 { "path", "o", ARG_IN },
1090 { "GetInterface", WPAS_DBUS_NEW_INTERFACE,
1091 (WPADBusMethodHandler) &wpas_dbus_handler_get_interface,
1093 { "ifname", "s", ARG_IN },
1094 { "path", "o", ARG_OUT },
1098 { NULL, NULL, NULL, { END_ARGS } }
1101 static const struct wpas_dbus_property wpas_dbus_global_properties[] = {
1102 { "DebugLevel", WPAS_DBUS_NEW_INTERFACE, "y",
1103 (WPADBusPropertyAccessor) wpas_dbus_getter_debug_level,
1104 (WPADBusPropertyAccessor) wpas_dbus_setter_debug_level,
1107 { "DebugTimestamp", WPAS_DBUS_NEW_INTERFACE, "b",
1108 (WPADBusPropertyAccessor) wpas_dbus_getter_debug_timestamp,
1109 (WPADBusPropertyAccessor) wpas_dbus_setter_debug_timestamp,
1112 { "DebugShowKeys", WPAS_DBUS_NEW_INTERFACE, "b",
1113 (WPADBusPropertyAccessor) wpas_dbus_getter_debug_show_keys,
1114 (WPADBusPropertyAccessor) wpas_dbus_setter_debug_show_keys,
1117 { "Interfaces", WPAS_DBUS_NEW_INTERFACE, "ao",
1118 (WPADBusPropertyAccessor) &wpas_dbus_getter_interfaces,
1122 { "EapMethods", WPAS_DBUS_NEW_INTERFACE, "as",
1123 (WPADBusPropertyAccessor) wpas_dbus_getter_eap_methods,
1127 { NULL, NULL, NULL, NULL, NULL, 0 }
1130 static const struct wpas_dbus_signal wpas_dbus_global_signals[] = {
1131 { "InterfaceAdded", WPAS_DBUS_NEW_INTERFACE,
1133 { "path", "o", ARG_OUT },
1134 { "properties", "a{sv}", ARG_OUT },
1138 { "InterfaceRemoved", WPAS_DBUS_NEW_INTERFACE,
1140 { "path", "o", ARG_OUT },
1144 { "PropertiesChanged", WPAS_DBUS_NEW_INTERFACE,
1146 { "properties", "a{sv}", ARG_OUT },
1150 { NULL, NULL, { END_ARGS } }
1155 * wpas_dbus_ctrl_iface_init - Initialize dbus control interface
1156 * @global: Pointer to global data from wpa_supplicant_init()
1157 * Returns: 0 on success or -1 on failure
1159 * Initialize the dbus control interface for wpa_supplicantand and start
1160 * receiving commands from external programs over the bus.
1162 int wpas_dbus_ctrl_iface_init(struct wpas_dbus_priv *priv)
1164 struct wpa_dbus_object_desc *obj_desc;
1167 obj_desc = os_zalloc(sizeof(struct wpa_dbus_object_desc));
1169 wpa_printf(MSG_ERROR, "Not enough memory "
1170 "to create object description");
1174 wpas_dbus_register(obj_desc, priv->global, NULL,
1175 wpas_dbus_global_methods,
1176 wpas_dbus_global_properties,
1177 wpas_dbus_global_signals);
1179 wpa_printf(MSG_DEBUG, "dbus: Register D-Bus object '%s'",
1180 WPAS_DBUS_NEW_PATH);
1181 ret = wpa_dbus_ctrl_iface_init(priv, WPAS_DBUS_NEW_PATH,
1182 WPAS_DBUS_NEW_SERVICE,
1185 free_dbus_object_desc(obj_desc);
1187 priv->dbus_new_initialized = 1;
1194 * wpas_dbus_ctrl_iface_deinit - Deinitialize dbus ctrl interface for
1196 * @iface: Pointer to dbus private data from wpas_dbus_init()
1198 * Deinitialize the dbus control interface that was initialized with
1199 * wpas_dbus_ctrl_iface_init().
1201 void wpas_dbus_ctrl_iface_deinit(struct wpas_dbus_priv *iface)
1203 if (!iface->dbus_new_initialized)
1205 wpa_printf(MSG_DEBUG, "dbus: Unregister D-Bus object '%s'",
1206 WPAS_DBUS_NEW_PATH);
1207 dbus_connection_unregister_object_path(iface->con,
1208 WPAS_DBUS_NEW_PATH);
1212 static void wpa_dbus_free(void *ptr)
1218 static const struct wpas_dbus_property wpas_dbus_network_properties[] = {
1219 { "Properties", WPAS_DBUS_NEW_IFACE_NETWORK, "a{sv}",
1220 (WPADBusPropertyAccessor) wpas_dbus_getter_network_properties,
1221 (WPADBusPropertyAccessor) wpas_dbus_setter_network_properties,
1224 { "Enabled", WPAS_DBUS_NEW_IFACE_NETWORK, "b",
1225 (WPADBusPropertyAccessor) wpas_dbus_getter_enabled,
1226 (WPADBusPropertyAccessor) wpas_dbus_setter_enabled,
1229 { NULL, NULL, NULL, NULL, NULL, 0 }
1233 static const struct wpas_dbus_signal wpas_dbus_network_signals[] = {
1234 { "PropertiesChanged", WPAS_DBUS_NEW_IFACE_NETWORK,
1236 { "properties", "a{sv}", ARG_OUT },
1240 { NULL, NULL, { END_ARGS } }
1245 * wpas_dbus_register_network - Register a configured network with dbus
1246 * @wpa_s: wpa_supplicant interface structure
1247 * @ssid: network configuration data
1248 * Returns: 0 on success, -1 on failure
1250 * Registers network representing object with dbus
1252 static int wpas_dbus_register_network(struct wpa_supplicant *wpa_s,
1253 struct wpa_ssid *ssid)
1255 struct wpas_dbus_priv *ctrl_iface;
1256 struct wpa_dbus_object_desc *obj_desc;
1258 struct network_handler_args *arg = NULL;
1262 /* Do nothing if the control interface is not turned on */
1263 if (wpa_s == NULL || wpa_s->global == NULL)
1265 ctrl_iface = wpa_s->global->dbus;
1266 if (ctrl_iface == NULL)
1269 net_obj_path = os_zalloc(WPAS_DBUS_OBJECT_PATH_MAX);
1270 if (net_obj_path == NULL)
1272 os_snprintf(net_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
1273 "%s/" WPAS_DBUS_NEW_NETWORKS_PART "/%u",
1274 wpas_dbus_get_path(wpa_s), ssid->id);
1276 wpa_printf(MSG_DEBUG, "dbus: Register network object '%s'",
1278 obj_desc = os_zalloc(sizeof(struct wpa_dbus_object_desc));
1280 wpa_printf(MSG_ERROR, "Not enough memory "
1281 "to create object description");
1285 /* allocate memory for handlers arguments */
1286 arg = os_zalloc(sizeof(struct network_handler_args));
1288 wpa_printf(MSG_ERROR, "Not enough memory "
1289 "to create arguments for method");
1296 wpas_dbus_register(obj_desc, arg, wpa_dbus_free, NULL,
1297 wpas_dbus_network_properties,
1298 wpas_dbus_network_signals);
1300 if (wpa_dbus_register_object_per_iface(ctrl_iface, net_obj_path,
1301 wpa_s->ifname, obj_desc))
1304 wpas_dbus_signal_network_added(wpa_s, ssid->id);
1306 os_free(net_obj_path);
1310 os_free(net_obj_path);
1318 * wpas_dbus_unregister_network - Unregister a configured network from dbus
1319 * @wpa_s: wpa_supplicant interface structure
1321 * Returns: 0 on success, -1 on failure
1323 * Unregisters network representing object from dbus
1325 static int wpas_dbus_unregister_network(struct wpa_supplicant *wpa_s, int nid)
1327 struct wpas_dbus_priv *ctrl_iface;
1331 /* Do nothing if the control interface is not turned on */
1332 if (wpa_s == NULL || wpa_s->global == NULL)
1334 ctrl_iface = wpa_s->global->dbus;
1335 if (ctrl_iface == NULL)
1338 net_obj_path = os_zalloc(WPAS_DBUS_OBJECT_PATH_MAX);
1339 if (net_obj_path == NULL)
1341 os_snprintf(net_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
1342 "%s/" WPAS_DBUS_NEW_NETWORKS_PART "/%u",
1343 wpas_dbus_get_path(wpa_s), nid);
1345 wpa_printf(MSG_DEBUG, "dbus: Unregister network object '%s'",
1347 ret = wpa_dbus_unregister_object_per_iface(ctrl_iface, net_obj_path);
1350 wpas_dbus_signal_network_removed(wpa_s, nid);
1352 os_free(net_obj_path);
1357 static const struct wpas_dbus_property wpas_dbus_bss_properties[] = {
1358 { "SSID", WPAS_DBUS_NEW_IFACE_BSSID, "ay",
1359 (WPADBusPropertyAccessor) wpas_dbus_getter_bss_ssid,
1363 { "BSSID", WPAS_DBUS_NEW_IFACE_BSSID, "ay",
1364 (WPADBusPropertyAccessor) wpas_dbus_getter_bss_bssid,
1368 { "Privacy", WPAS_DBUS_NEW_IFACE_BSSID, "b",
1369 (WPADBusPropertyAccessor) wpas_dbus_getter_bss_privacy,
1373 { "Mode", WPAS_DBUS_NEW_IFACE_BSSID, "s",
1374 (WPADBusPropertyAccessor) wpas_dbus_getter_bss_mode,
1378 { "Signal", WPAS_DBUS_NEW_IFACE_BSSID, "n",
1379 (WPADBusPropertyAccessor) wpas_dbus_getter_bss_signal,
1383 { "Frequency", WPAS_DBUS_NEW_IFACE_BSSID, "q",
1384 (WPADBusPropertyAccessor) wpas_dbus_getter_bss_frequency,
1388 { "MaxRate", WPAS_DBUS_NEW_IFACE_BSSID, "q",
1389 (WPADBusPropertyAccessor) wpas_dbus_getter_bss_max_rate,
1393 { "WPAIE", WPAS_DBUS_NEW_IFACE_BSSID, "ay",
1394 (WPADBusPropertyAccessor) wpas_dbus_getter_bss_wpaie,
1398 { "RSNIE", WPAS_DBUS_NEW_IFACE_BSSID, "ay",
1399 (WPADBusPropertyAccessor) wpas_dbus_getter_bss_rsnie,
1403 { "WPSIE", WPAS_DBUS_NEW_IFACE_BSSID, "ay",
1404 (WPADBusPropertyAccessor) wpas_dbus_getter_bss_wpsie,
1408 { NULL, NULL, NULL, NULL, NULL, 0 }
1412 static const struct wpas_dbus_signal wpas_dbus_bss_signals[] = {
1413 { "PropertiesChanged", WPAS_DBUS_NEW_IFACE_BSSID,
1415 { "properties", "a{sv}", ARG_OUT },
1419 { NULL, NULL, { END_ARGS } }
1424 * wpas_dbus_unregister_bss - Unregister a scanned BSS from dbus
1425 * @wpa_s: wpa_supplicant interface structure
1426 * @bssid: scanned network bssid
1427 * @id: unique BSS identifier
1428 * Returns: 0 on success, -1 on failure
1430 * Unregisters BSS representing object from dbus
1432 static int wpas_dbus_unregister_bss(struct wpa_supplicant *wpa_s,
1433 u8 bssid[ETH_ALEN], unsigned int id)
1435 struct wpas_dbus_priv *ctrl_iface;
1438 /* Do nothing if the control interface is not turned on */
1439 if (wpa_s == NULL || wpa_s->global == NULL)
1441 ctrl_iface = wpa_s->global->dbus;
1442 if (ctrl_iface == NULL)
1445 bss_obj_path = os_zalloc(WPAS_DBUS_OBJECT_PATH_MAX);
1446 if (bss_obj_path == NULL)
1449 os_snprintf(bss_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
1450 "%s/" WPAS_DBUS_NEW_BSSIDS_PART "/%u",
1451 wpas_dbus_get_path(wpa_s), id);
1453 wpa_printf(MSG_DEBUG, "dbus: Unregister BSS object '%s'",
1455 if (wpa_dbus_unregister_object_per_iface(ctrl_iface, bss_obj_path)) {
1456 wpa_printf(MSG_ERROR,
1457 "Cannot unregister BSSID dbus object %s.",
1459 os_free(bss_obj_path);
1463 wpas_dbus_signal_bss_removed(wpa_s, bss_obj_path);
1465 os_free(bss_obj_path);
1471 * wpas_dbus_register_bss - Register a scanned BSS with dbus
1472 * @wpa_s: wpa_supplicant interface structure
1473 * @bssid: scanned network bssid
1474 * @id: unique BSS identifier
1475 * Returns: 0 on success, -1 on failure
1477 * Registers BSS representing object with dbus
1479 static int wpas_dbus_register_bss(struct wpa_supplicant *wpa_s,
1480 u8 bssid[ETH_ALEN], unsigned int id)
1482 struct wpas_dbus_priv *ctrl_iface;
1483 struct wpa_dbus_object_desc *obj_desc;
1486 struct bss_handler_args *arg = NULL;
1488 /* Do nothing if the control interface is not turned on */
1489 if (wpa_s == NULL || wpa_s->global == NULL)
1491 ctrl_iface = wpa_s->global->dbus;
1492 if (ctrl_iface == NULL)
1495 bss_obj_path = os_zalloc(WPAS_DBUS_OBJECT_PATH_MAX);
1496 if (bss_obj_path == NULL)
1499 os_snprintf(bss_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
1500 "%s/" WPAS_DBUS_NEW_BSSIDS_PART "/%u",
1501 wpas_dbus_get_path(wpa_s), id);
1503 obj_desc = os_zalloc(sizeof(struct wpa_dbus_object_desc));
1505 wpa_printf(MSG_ERROR, "Not enough memory "
1506 "to create object description");
1510 arg = os_zalloc(sizeof(struct bss_handler_args));
1512 wpa_printf(MSG_ERROR, "Not enough memory "
1513 "to create arguments for handler");
1519 wpas_dbus_register(obj_desc, arg, wpa_dbus_free, NULL,
1520 wpas_dbus_bss_properties,
1521 wpas_dbus_bss_signals);
1523 wpa_printf(MSG_DEBUG, "dbus: Register BSS object '%s'",
1525 if (wpa_dbus_register_object_per_iface(ctrl_iface, bss_obj_path,
1526 wpa_s->ifname, obj_desc)) {
1527 wpa_printf(MSG_ERROR,
1528 "Cannot register BSSID dbus object %s.",
1533 wpas_dbus_signal_bss_added(wpa_s, bss_obj_path);
1535 os_free(bss_obj_path);
1539 os_free(bss_obj_path);
1546 static const struct wpas_dbus_method wpas_dbus_interface_methods[] = {
1547 { "Scan", WPAS_DBUS_NEW_IFACE_INTERFACE,
1548 (WPADBusMethodHandler) &wpas_dbus_handler_scan,
1550 { "args", "a{sv}", ARG_IN },
1554 { "Disconnect", WPAS_DBUS_NEW_IFACE_INTERFACE,
1555 (WPADBusMethodHandler) &wpas_dbus_handler_disconnect,
1560 { "AddNetwork", WPAS_DBUS_NEW_IFACE_INTERFACE,
1561 (WPADBusMethodHandler) &wpas_dbus_handler_add_network,
1563 { "args", "a{sv}", ARG_IN },
1564 { "path", "o", ARG_OUT },
1568 { "RemoveNetwork", WPAS_DBUS_NEW_IFACE_INTERFACE,
1569 (WPADBusMethodHandler) &wpas_dbus_handler_remove_network,
1571 { "path", "o", ARG_IN },
1575 { "SelectNetwork", WPAS_DBUS_NEW_IFACE_INTERFACE,
1576 (WPADBusMethodHandler) &wpas_dbus_handler_select_network,
1578 { "path", "o", ARG_IN },
1582 { "AddBlob", WPAS_DBUS_NEW_IFACE_INTERFACE,
1583 (WPADBusMethodHandler) &wpas_dbus_handler_add_blob,
1585 { "name", "s", ARG_IN },
1586 { "data", "ay", ARG_IN },
1590 { "GetBlob", WPAS_DBUS_NEW_IFACE_INTERFACE,
1591 (WPADBusMethodHandler) &wpas_dbus_handler_get_blob,
1593 { "name", "s", ARG_IN },
1594 { "data", "ay", ARG_OUT },
1598 { "RemoveBlob", WPAS_DBUS_NEW_IFACE_INTERFACE,
1599 (WPADBusMethodHandler) &wpas_dbus_handler_remove_blob,
1601 { "name", "s", ARG_IN },
1606 { "Start", WPAS_DBUS_NEW_IFACE_WPS,
1607 (WPADBusMethodHandler) &wpas_dbus_handler_wps_start,
1609 { "args", "a{sv}", ARG_IN },
1610 { "output", "a{sv}", ARG_OUT },
1614 #endif /* CONFIG_WPS */
1615 { NULL, NULL, NULL, { END_ARGS } }
1618 static const struct wpas_dbus_property wpas_dbus_interface_properties[] = {
1619 { "Capabilities", WPAS_DBUS_NEW_IFACE_INTERFACE, "a{sv}",
1620 (WPADBusPropertyAccessor) wpas_dbus_getter_capabilities,
1623 { "State", WPAS_DBUS_NEW_IFACE_INTERFACE, "s",
1624 (WPADBusPropertyAccessor) wpas_dbus_getter_state,
1627 { "Scanning", WPAS_DBUS_NEW_IFACE_INTERFACE, "b",
1628 (WPADBusPropertyAccessor) wpas_dbus_getter_scanning,
1631 { "ApScan", WPAS_DBUS_NEW_IFACE_INTERFACE, "u",
1632 (WPADBusPropertyAccessor) wpas_dbus_getter_ap_scan,
1633 (WPADBusPropertyAccessor) wpas_dbus_setter_ap_scan,
1636 { "Ifname", WPAS_DBUS_NEW_IFACE_INTERFACE, "s",
1637 (WPADBusPropertyAccessor) wpas_dbus_getter_ifname,
1640 { "Driver", WPAS_DBUS_NEW_IFACE_INTERFACE, "s",
1641 (WPADBusPropertyAccessor) wpas_dbus_getter_driver,
1644 { "BridgeIfname", WPAS_DBUS_NEW_IFACE_INTERFACE, "s",
1645 (WPADBusPropertyAccessor) wpas_dbus_getter_bridge_ifname,
1648 { "CurrentBSS", WPAS_DBUS_NEW_IFACE_INTERFACE, "o",
1649 (WPADBusPropertyAccessor) wpas_dbus_getter_current_bss,
1652 { "CurrentNetwork", WPAS_DBUS_NEW_IFACE_INTERFACE, "o",
1653 (WPADBusPropertyAccessor) wpas_dbus_getter_current_network,
1656 { "Blobs", WPAS_DBUS_NEW_IFACE_INTERFACE, "a{say}",
1657 (WPADBusPropertyAccessor) wpas_dbus_getter_blobs,
1660 { "BSSs", WPAS_DBUS_NEW_IFACE_INTERFACE, "ao",
1661 (WPADBusPropertyAccessor) wpas_dbus_getter_bsss,
1664 { "Networks", WPAS_DBUS_NEW_IFACE_INTERFACE, "ao",
1665 (WPADBusPropertyAccessor) wpas_dbus_getter_networks,
1669 { "ProcessCredentials", WPAS_DBUS_NEW_IFACE_WPS, "b",
1670 (WPADBusPropertyAccessor) wpas_dbus_getter_process_credentials,
1671 (WPADBusPropertyAccessor) wpas_dbus_setter_process_credentials,
1674 #endif /* CONFIG_WPS */
1675 { NULL, NULL, NULL, NULL, NULL, 0 }
1678 static const struct wpas_dbus_signal wpas_dbus_interface_signals[] = {
1679 { "ScanDone", WPAS_DBUS_NEW_IFACE_INTERFACE,
1681 { "success", "b", ARG_OUT },
1685 { "StateChanged", WPAS_DBUS_NEW_IFACE_INTERFACE,
1687 { "newState", "s", ARG_OUT },
1688 { "oldState", "s", ARG_OUT },
1692 { "BSSAdded", WPAS_DBUS_NEW_IFACE_INTERFACE,
1694 { "path", "o", ARG_OUT },
1695 { "properties", "a{sv}", ARG_OUT },
1699 { "BSSRemoved", WPAS_DBUS_NEW_IFACE_INTERFACE,
1701 { "path", "o", ARG_OUT },
1705 { "BlobAdded", WPAS_DBUS_NEW_IFACE_INTERFACE,
1707 { "name", "s", ARG_OUT },
1711 { "BlobRemoved", WPAS_DBUS_NEW_IFACE_INTERFACE,
1713 { "name", "s", ARG_OUT },
1717 { "NetworkAdded", WPAS_DBUS_NEW_IFACE_INTERFACE,
1719 { "path", "o", ARG_OUT },
1720 { "properties", "a{sv}", ARG_OUT },
1724 { "NetworkRemoved", WPAS_DBUS_NEW_IFACE_INTERFACE,
1726 { "path", "o", ARG_OUT },
1730 { "NetworkSelected", WPAS_DBUS_NEW_IFACE_INTERFACE,
1732 { "path", "o", ARG_OUT },
1736 { "PropertiesChanged", WPAS_DBUS_NEW_IFACE_INTERFACE,
1738 { "properties", "a{sv}", ARG_OUT },
1743 { "Event", WPAS_DBUS_NEW_IFACE_WPS,
1745 { "name", "s", ARG_OUT },
1746 { "args", "a{sv}", ARG_OUT },
1750 { "Credentials", WPAS_DBUS_NEW_IFACE_WPS,
1752 { "credentials", "a{sv}", ARG_OUT },
1756 { "PropertiesChanged", WPAS_DBUS_NEW_IFACE_WPS,
1758 { "properties", "a{sv}", ARG_OUT },
1762 #endif /* CONFIG_WPS */
1763 { NULL, NULL, { END_ARGS } }
1767 static int wpas_dbus_register_interface(struct wpa_supplicant *wpa_s)
1770 struct wpa_dbus_object_desc *obj_desc = NULL;
1772 struct wpas_dbus_priv *ctrl_iface = wpa_s->global->dbus;
1775 /* Do nothing if the control interface is not turned on */
1776 if (ctrl_iface == NULL)
1779 /* Create and set the interface's object path */
1780 path = os_zalloc(WPAS_DBUS_OBJECT_PATH_MAX);
1783 next = ctrl_iface->next_objid++;
1784 os_snprintf(path, WPAS_DBUS_OBJECT_PATH_MAX,
1785 WPAS_DBUS_NEW_PATH_INTERFACES "/%u",
1787 if (wpas_dbus_set_path(wpa_s, path)) {
1788 wpa_printf(MSG_DEBUG,
1789 "Failed to set dbus path for interface %s",
1794 obj_desc = os_zalloc(sizeof(struct wpa_dbus_object_desc));
1796 wpa_printf(MSG_ERROR, "Not enough memory "
1797 "to create object description");
1801 wpas_dbus_register(obj_desc, wpa_s, NULL, wpas_dbus_interface_methods,
1802 wpas_dbus_interface_properties,
1803 wpas_dbus_interface_signals);
1805 wpa_printf(MSG_DEBUG, "dbus: Register interface object '%s'", path);
1806 if (wpa_dbus_register_object_per_iface(ctrl_iface, path, wpa_s->ifname,
1810 wpas_dbus_signal_interface_added(wpa_s);
1822 static int wpas_dbus_unregister_interface(struct wpa_supplicant *wpa_s)
1824 struct wpas_dbus_priv *ctrl_iface;
1826 /* Do nothing if the control interface is not turned on */
1827 if (wpa_s == NULL || wpa_s->global == NULL)
1829 ctrl_iface = wpa_s->global->dbus;
1830 if (ctrl_iface == NULL)
1833 wpa_printf(MSG_DEBUG, "dbus: Unregister interface object '%s'",
1834 wpas_dbus_get_path(wpa_s));
1835 if (wpa_dbus_unregister_object_per_iface(ctrl_iface,
1836 wpas_dbus_get_path(wpa_s)))
1839 wpas_dbus_signal_interface_removed(wpa_s);
1841 os_free(wpa_s->dbus_new_path);
1842 wpa_s->dbus_new_path = NULL;
1848 static struct wpas_dbus_callbacks callbacks =
1850 .signal_interface_added = wpas_dbus_signal_interface_added,
1851 .signal_interface_removed = wpas_dbus_signal_interface_removed,
1853 .register_interface = wpas_dbus_register_interface,
1854 .unregister_interface = wpas_dbus_unregister_interface,
1856 .signal_scan_done = wpas_dbus_signal_scan_done,
1858 .signal_blob_added = wpas_dbus_signal_blob_added,
1859 .signal_blob_removed = wpas_dbus_signal_blob_removed,
1861 .signal_network_selected = wpas_dbus_signal_network_selected,
1863 .signal_state_changed = wpas_dbus_signal_state_changed,
1864 .register_network = wpas_dbus_register_network,
1865 .unregister_network = wpas_dbus_unregister_network,
1867 .signal_network_enabled_changed =
1868 wpas_dbus_signal_network_enabled_changed,
1870 .register_bss = wpas_dbus_register_bss,
1871 .unregister_bss = wpas_dbus_unregister_bss,
1873 .signal_prop_changed = wpas_dbus_signal_prop_changed,
1875 .signal_debug_level_changed = wpas_dbus_signal_debug_level_changed,
1876 .signal_debug_timestamp_changed =
1877 wpas_dbus_signal_debug_timestamp_changed,
1878 .signal_debug_show_keys_changed =
1879 wpas_dbus_signal_debug_show_keys_changed,
1882 .signal_wps_event_success = wpas_dbus_signal_wps_event_success,
1883 .signal_wps_event_fail = wpas_dbus_signal_wps_event_fail,
1884 .signal_wps_event_m2d = wpas_dbus_signal_wps_event_m2d,
1885 .signal_wps_credentials = wpas_dbus_signal_wps_cred,
1886 #endif /* CONFIG_WPS */
1890 struct wpas_dbus_callbacks * wpas_dbus_get_callbacks(void)
1897 * wpas_dbus_get_path - Get an interface's dbus path
1898 * @wpa_s: %wpa_supplicant interface structure
1899 * Returns: Interface's dbus object path, or %NULL on error
1901 const char * wpas_dbus_get_path(struct wpa_supplicant *wpa_s)
1903 return wpa_s->dbus_new_path;