From 1f69aa52ea2e0a73ac502565df8c666ee49cab6a Mon Sep 17 00:00:00 2001 From: Dmitry Shmidt Date: Tue, 24 Jan 2012 16:10:04 -0800 Subject: Update to new version 0.8.16 from BRCM Sync with main tree commit b8349523e460493fa0b4de36c689595109e45e91 Author: Neeraj Kumar Garg Date: Tue Dec 27 23:21:45 2011 +0200 P2P: Reject p2p_group_add if forced frequency is not acceptable Change-Id: Icb4541a371b05c270e80440d7a7fdea7f33ff61e Signed-off-by: Dmitry Shmidt --- wpa_supplicant/dbus/dbus_dict_helpers.c | 24 +- wpa_supplicant/dbus/dbus_dict_helpers.h | 3 +- wpa_supplicant/dbus/dbus_new.c | 490 ++++--- wpa_supplicant/dbus/dbus_new.h | 18 +- wpa_supplicant/dbus/dbus_new_handlers.c | 1485 ++++++++++---------- wpa_supplicant/dbus/dbus_new_handlers.h | 227 +-- wpa_supplicant/dbus/dbus_new_handlers_p2p.c | 888 ++++++------ wpa_supplicant/dbus/dbus_new_handlers_p2p.h | 74 +- wpa_supplicant/dbus/dbus_new_handlers_wps.c | 107 +- wpa_supplicant/dbus/dbus_new_helpers.c | 440 +++--- wpa_supplicant/dbus/dbus_new_helpers.h | 25 +- wpa_supplicant/dbus/dbus_new_introspect.c | 7 +- wpa_supplicant/dbus/dbus_old.c | 1 - wpa_supplicant/dbus/dbus_old_handlers.c | 10 +- .../dbus/fi.epitest.hostap.WPASupplicant.service | 4 - wpa_supplicant/dbus/fi.w1.wpa_supplicant1.service | 4 - 16 files changed, 2100 insertions(+), 1707 deletions(-) delete mode 100644 wpa_supplicant/dbus/fi.epitest.hostap.WPASupplicant.service delete mode 100644 wpa_supplicant/dbus/fi.w1.wpa_supplicant1.service (limited to 'wpa_supplicant/dbus') diff --git a/wpa_supplicant/dbus/dbus_dict_helpers.c b/wpa_supplicant/dbus/dbus_dict_helpers.c index 788f736..5f9e64a 100644 --- a/wpa_supplicant/dbus/dbus_dict_helpers.c +++ b/wpa_supplicant/dbus/dbus_dict_helpers.c @@ -705,18 +705,26 @@ dbus_bool_t wpa_dbus_dict_append_wpabuf_array(DBusMessageIter *iter_dict, * @param iter A valid DBusMessageIter pointing to the start of the dict * @param iter_dict (out) A DBusMessageIter to be passed to * wpa_dbus_dict_read_next_entry() + * @error on failure a descriptive error * @return TRUE on success, FALSE on failure * */ dbus_bool_t wpa_dbus_dict_open_read(DBusMessageIter *iter, - DBusMessageIter *iter_dict) + DBusMessageIter *iter_dict, + DBusError *error) { - if (!iter || !iter_dict) + if (!iter || !iter_dict) { + dbus_set_error_const(error, DBUS_ERROR_FAILED, + "[internal] missing message iterators"); return FALSE; + } if (dbus_message_iter_get_arg_type(iter) != DBUS_TYPE_ARRAY || - dbus_message_iter_get_element_type(iter) != DBUS_TYPE_DICT_ENTRY) + dbus_message_iter_get_element_type(iter) != DBUS_TYPE_DICT_ENTRY) { + dbus_set_error_const(error, DBUS_ERROR_INVALID_ARGS, + "unexpected message argument types"); return FALSE; + } dbus_message_iter_recurse(iter, iter_dict); return TRUE; @@ -1087,13 +1095,13 @@ void wpa_dbus_dict_entry_clear(struct wpa_dbus_dict_entry *entry) os_free(entry->strarray_value[i]); os_free(entry->strarray_value); break; + case WPAS_DBUS_TYPE_BINARRAY: + for (i = 0; i < entry->array_len; i++) + wpabuf_free(entry->binarray_value[i]); + os_free(entry->binarray_value); + break; } break; - case WPAS_DBUS_TYPE_BINARRAY: - for (i = 0; i < entry->array_len; i++) - wpabuf_free(entry->binarray_value[i]); - os_free(entry->binarray_value); - break; } memset(entry, 0, sizeof(struct wpa_dbus_dict_entry)); diff --git a/wpa_supplicant/dbus/dbus_dict_helpers.h b/wpa_supplicant/dbus/dbus_dict_helpers.h index 9e90c50..2f6eb45 100644 --- a/wpa_supplicant/dbus/dbus_dict_helpers.h +++ b/wpa_supplicant/dbus/dbus_dict_helpers.h @@ -156,7 +156,8 @@ struct wpa_dbus_dict_entry { }; dbus_bool_t wpa_dbus_dict_open_read(DBusMessageIter *iter, - DBusMessageIter *iter_dict); + DBusMessageIter *iter_dict, + DBusError *error); dbus_bool_t wpa_dbus_dict_get_entry(DBusMessageIter *iter_dict, struct wpa_dbus_dict_entry *entry); diff --git a/wpa_supplicant/dbus/dbus_new.c b/wpa_supplicant/dbus/dbus_new.c index 533cb32..2bf9be8 100644 --- a/wpa_supplicant/dbus/dbus_new.c +++ b/wpa_supplicant/dbus/dbus_new.c @@ -22,11 +22,11 @@ #include "../config.h" #include "../wpa_supplicant_i.h" #include "../bss.h" +#include "../wpas_glue.h" #include "dbus_new_helpers.h" #include "dbus_dict_helpers.h" #include "dbus_new.h" #include "dbus_new_handlers.h" -#include "dbus_common.h" #include "dbus_common_i.h" #include "dbus_new_handlers_p2p.h" #include "p2p/p2p.h" @@ -45,7 +45,7 @@ static void wpas_dbus_signal_interface(struct wpa_supplicant *wpa_s, { struct wpas_dbus_priv *iface; DBusMessage *msg; - DBusMessageIter iter, iter_dict; + DBusMessageIter iter; iface = wpa_s->global->dbus; @@ -64,14 +64,9 @@ static void wpas_dbus_signal_interface(struct wpa_supplicant *wpa_s, goto err; if (properties) { - if (!wpa_dbus_dict_open_write(&iter, &iter_dict)) - goto err; - - wpa_dbus_get_object_properties(iface, wpa_s->dbus_new_path, - WPAS_DBUS_NEW_IFACE_INTERFACE, - &iter_dict); - - if (!wpa_dbus_dict_close_write(&iter, &iter_dict)) + if (!wpa_dbus_get_object_properties( + iface, wpa_s->dbus_new_path, + WPAS_DBUS_NEW_IFACE_INTERFACE, &iter)) goto err; } @@ -160,7 +155,7 @@ static void wpas_dbus_signal_bss(struct wpa_supplicant *wpa_s, { struct wpas_dbus_priv *iface; DBusMessage *msg; - DBusMessageIter iter, iter_dict; + DBusMessageIter iter; iface = wpa_s->global->dbus; @@ -180,14 +175,9 @@ static void wpas_dbus_signal_bss(struct wpa_supplicant *wpa_s, goto err; if (properties) { - if (!wpa_dbus_dict_open_write(&iter, &iter_dict)) - goto err; - - wpa_dbus_get_object_properties(iface, bss_obj_path, - WPAS_DBUS_NEW_IFACE_BSS, - &iter_dict); - - if (!wpa_dbus_dict_close_write(&iter, &iter_dict)) + if (!wpa_dbus_get_object_properties(iface, bss_obj_path, + WPAS_DBUS_NEW_IFACE_BSS, + &iter)) goto err; } @@ -307,7 +297,7 @@ static void wpas_dbus_signal_network(struct wpa_supplicant *wpa_s, { struct wpas_dbus_priv *iface; DBusMessage *msg; - DBusMessageIter iter, iter_dict; + DBusMessageIter iter; char net_obj_path[WPAS_DBUS_OBJECT_PATH_MAX], *path; iface = wpa_s->global->dbus; @@ -333,14 +323,9 @@ static void wpas_dbus_signal_network(struct wpa_supplicant *wpa_s, goto err; if (properties) { - if (!wpa_dbus_dict_open_write(&iter, &iter_dict)) - goto err; - - wpa_dbus_get_object_properties(iface, net_obj_path, - WPAS_DBUS_NEW_IFACE_NETWORK, - &iter_dict); - - if (!wpa_dbus_dict_close_write(&iter, &iter_dict)) + if (!wpa_dbus_get_object_properties( + iface, net_obj_path, WPAS_DBUS_NEW_IFACE_NETWORK, + &iter)) goto err; } @@ -397,6 +382,67 @@ void wpas_dbus_signal_network_selected(struct wpa_supplicant *wpa_s, int id) /** + * wpas_dbus_signal_network_request - Indicate that additional information + * (EAP password, etc.) is required to complete the association to this SSID + * @wpa_s: %wpa_supplicant network interface data + * @rtype: The specific additional information required + * @default_text: Optional description of required information + * + * Request additional information or passwords to complete an association + * request. + */ +void wpas_dbus_signal_network_request(struct wpa_supplicant *wpa_s, + struct wpa_ssid *ssid, + enum wpa_ctrl_req_type rtype, + const char *default_txt) +{ + struct wpas_dbus_priv *iface; + DBusMessage *msg; + DBusMessageIter iter; + char net_obj_path[WPAS_DBUS_OBJECT_PATH_MAX]; + const char *field, *txt = NULL, *net_ptr; + + iface = wpa_s->global->dbus; + + /* Do nothing if the control interface is not turned on */ + if (iface == NULL) + return; + + field = wpa_supplicant_ctrl_req_to_string(rtype, default_txt, &txt); + if (field == NULL) + return; + + msg = dbus_message_new_signal(wpa_s->dbus_new_path, + WPAS_DBUS_NEW_IFACE_INTERFACE, + "NetworkRequest"); + if (msg == NULL) + return; + + os_snprintf(net_obj_path, WPAS_DBUS_OBJECT_PATH_MAX, + "%s/" WPAS_DBUS_NEW_NETWORKS_PART "/%u", + wpa_s->dbus_new_path, ssid->id); + net_ptr = &net_obj_path[0]; + + dbus_message_iter_init_append(msg, &iter); + if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_OBJECT_PATH, + &net_ptr)) + goto err; + if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &field)) + goto err; + if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &txt)) + goto err; + + dbus_connection_send(iface->con, msg, NULL); + dbus_message_unref(msg); + return; + +err: + wpa_printf(MSG_ERROR, "dbus: Failed to construct signal"); + dbus_message_unref(msg); +} + + +/** * wpas_dbus_signal_network_enabled_changed - Signals Enabled property changes * @wpa_s: %wpa_supplicant network interface data * @ssid: configured network which Enabled property has changed @@ -821,7 +867,7 @@ void wpas_dbus_signal_p2p_provision_discovery(struct wpa_supplicant *wpa_s, return; /* Check if this is a known peer */ - if (p2p_get_peer_info(wpa_s->global->p2p, dev_addr, 0, NULL, 0) < 0) + if (!p2p_peer_known(wpa_s->global->p2p, dev_addr)) goto error; os_snprintf(peer_obj_path, WPAS_DBUS_OBJECT_PATH_MAX, @@ -920,7 +966,7 @@ static int wpas_dbus_get_group_obj_path(struct wpa_supplicant *wpa_s, /** * wpas_dbus_signal_p2p_group_started - Signals P2P group has - * started.Emitted when a group is succesfully started + * started. Emitted when a group is successfully started * irrespective of the role (client/GO) of the current device * * @wpa_s: %wpa_supplicant network interface data @@ -998,35 +1044,118 @@ nomem: * on status. * @status: Status of the GO neg request. 0 for success, other for errors. */ -void wpas_dbus_signal_p2p_go_neg_resp(struct wpa_supplicant *wpa_s, int status) +void wpas_dbus_signal_p2p_go_neg_resp(struct wpa_supplicant *wpa_s, + struct p2p_go_neg_results *res) { DBusMessage *msg; - DBusMessageIter iter; + DBusMessageIter iter, dict_iter; + DBusMessageIter iter_dict_entry, iter_dict_val, iter_dict_array; struct wpas_dbus_priv *iface; + char peer_obj_path[WPAS_DBUS_OBJECT_PATH_MAX], *path; + dbus_int32_t freqs[P2P_MAX_CHANNELS]; + dbus_int32_t *f_array = freqs; + iface = wpa_s->global->dbus; + os_memset(freqs, 0, sizeof(freqs)); /* Do nothing if the control interface is not turned on */ if (iface == NULL) return; + os_snprintf(peer_obj_path, WPAS_DBUS_OBJECT_PATH_MAX, + "%s/" WPAS_DBUS_NEW_P2P_PEERS_PART "/" COMPACT_MACSTR, + wpa_s->dbus_new_path, MAC2STR(res->peer_device_addr)); + path = peer_obj_path; + msg = dbus_message_new_signal(wpa_s->dbus_new_path, WPAS_DBUS_NEW_IFACE_P2PDEVICE, - status ? "GONegotiationFailure" : - "GONegotiationSuccess"); + res->status ? "GONegotiationFailure" : + "GONegotiationSuccess"); if (msg == NULL) return; - if (status) { - dbus_message_iter_init_append(msg, &iter); - if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_INT32, - &status)) { - wpa_printf(MSG_ERROR, - "dbus: Failed to construct signal"); + dbus_message_iter_init_append(msg, &iter); + if (!wpa_dbus_dict_open_write(&iter, &dict_iter)) + goto err; + if (!wpa_dbus_dict_append_object_path(&dict_iter, "peer_object", + path) || + !wpa_dbus_dict_append_int32(&dict_iter, "status", res->status)) + goto err; + + if (!res->status) { + int i = 0; + int freq_list_num = 0; + + if (res->role_go) { + if (!wpa_dbus_dict_append_byte_array( + &dict_iter, "passphrase", + (const char *) res->passphrase, + sizeof(res->passphrase))) + goto err; + } + + if (!wpa_dbus_dict_append_string(&dict_iter, "role_go", + res->role_go ? "GO" : + "client") || + !wpa_dbus_dict_append_int32(&dict_iter, "frequency", + res->freq) || + !wpa_dbus_dict_append_byte_array(&dict_iter, "ssid", + (const char *) res->ssid, + res->ssid_len) || + !wpa_dbus_dict_append_byte_array(&dict_iter, + "peer_device_addr", + (const char *) + res->peer_device_addr, + ETH_ALEN) || + !wpa_dbus_dict_append_byte_array(&dict_iter, + "peer_interface_addr", + (const char *) + res->peer_interface_addr, + ETH_ALEN) || + !wpa_dbus_dict_append_string(&dict_iter, "wps_method", + p2p_wps_method_text( + res->wps_method))) goto err; + + for (i = 0; i < P2P_MAX_CHANNELS; i++) { + if (res->freq_list[i]) { + freqs[i] = res->freq_list[i]; + freq_list_num++; + } } + + if (!wpa_dbus_dict_begin_array(&dict_iter, + "frequency_list", + DBUS_TYPE_INT32_AS_STRING, + &iter_dict_entry, + &iter_dict_val, + &iter_dict_array)) + goto err; + + if (!dbus_message_iter_append_fixed_array(&iter_dict_array, + DBUS_TYPE_INT32, + &f_array, + freq_list_num)) + goto err; + + if (!wpa_dbus_dict_end_array(&dict_iter, + &iter_dict_entry, + &iter_dict_val, + &iter_dict_array)) + goto err; + + if (!wpa_dbus_dict_append_int32(&dict_iter, "persistent_group", + res->persistent_group) || + !wpa_dbus_dict_append_uint32(&dict_iter, + "peer_config_timeout", + res->peer_config_timeout)) + goto err; } + if (!wpa_dbus_dict_close_write(&iter, &dict_iter)) + goto err; + dbus_connection_send(iface->con, msg, NULL); err: dbus_message_unref(msg); @@ -1228,7 +1357,7 @@ void wpas_dbus_signal_p2p_sd_request(struct wpa_supplicant *wpa_s, return; /* Check if this is a known peer */ - if (p2p_get_peer_info(wpa_s->global->p2p, sa, 0, NULL, 0) < 0) + if (!p2p_peer_known(wpa_s->global->p2p, sa)) goto error; os_snprintf(peer_obj_path, WPAS_DBUS_OBJECT_PATH_MAX, @@ -1297,7 +1426,7 @@ void wpas_dbus_signal_p2p_sd_response(struct wpa_supplicant *wpa_s, return; /* Check if this is a known peer */ - if (p2p_get_peer_info(wpa_s->global->p2p, sa, 0, NULL, 0) < 0) + if (!p2p_peer_known(wpa_s->global->p2p, sa)) goto error; os_snprintf(peer_obj_path, WPAS_DBUS_OBJECT_PATH_MAX, @@ -1345,7 +1474,7 @@ static void wpas_dbus_signal_persistent_group(struct wpa_supplicant *wpa_s, { struct wpas_dbus_priv *iface; DBusMessage *msg; - DBusMessageIter iter, iter_dict; + DBusMessageIter iter; char pgrp_obj_path[WPAS_DBUS_OBJECT_PATH_MAX], *path; iface = wpa_s->global->dbus; @@ -1371,15 +1500,9 @@ static void wpas_dbus_signal_persistent_group(struct wpa_supplicant *wpa_s, goto err; if (properties) { - if (!wpa_dbus_dict_open_write(&iter, &iter_dict)) - goto err; - - wpa_dbus_get_object_properties( - iface, pgrp_obj_path, - WPAS_DBUS_NEW_IFACE_PERSISTENT_GROUP, - &iter_dict); - - if (!wpa_dbus_dict_close_write(&iter, &iter_dict)) + if (!wpa_dbus_get_object_properties( + iface, pgrp_obj_path, + WPAS_DBUS_NEW_IFACE_PERSISTENT_GROUP, &iter)) goto err; } @@ -1483,7 +1606,6 @@ void wpas_dbus_signal_p2p_wps_failed(struct wpa_supplicant *wpa_s, void wpas_dbus_signal_prop_changed(struct wpa_supplicant *wpa_s, enum wpas_dbus_prop property) { - WPADBusPropertyAccessor getter; char *prop; if (wpa_s->dbus_new_path == NULL) @@ -1491,34 +1613,24 @@ void wpas_dbus_signal_prop_changed(struct wpa_supplicant *wpa_s, switch (property) { case WPAS_DBUS_PROP_AP_SCAN: - getter = (WPADBusPropertyAccessor) wpas_dbus_getter_ap_scan; prop = "ApScan"; break; case WPAS_DBUS_PROP_SCANNING: - getter = (WPADBusPropertyAccessor) wpas_dbus_getter_scanning; prop = "Scanning"; break; case WPAS_DBUS_PROP_STATE: - getter = (WPADBusPropertyAccessor) wpas_dbus_getter_state; prop = "State"; break; case WPAS_DBUS_PROP_CURRENT_BSS: - getter = (WPADBusPropertyAccessor) - wpas_dbus_getter_current_bss; prop = "CurrentBSS"; break; case WPAS_DBUS_PROP_CURRENT_NETWORK: - getter = (WPADBusPropertyAccessor) - wpas_dbus_getter_current_network; prop = "CurrentNetwork"; break; case WPAS_DBUS_PROP_BSSS: - getter = (WPADBusPropertyAccessor) wpas_dbus_getter_bsss; prop = "BSSs"; break; case WPAS_DBUS_PROP_CURRENT_AUTH_MODE: - getter = (WPADBusPropertyAccessor) - wpas_dbus_getter_current_auth_mode; prop = "CurrentAuthMode"; break; default: @@ -1685,31 +1797,26 @@ static const struct wpa_dbus_method_desc wpas_dbus_global_methods[] = { static const struct wpa_dbus_property_desc wpas_dbus_global_properties[] = { { "DebugLevel", WPAS_DBUS_NEW_INTERFACE, "s", - (WPADBusPropertyAccessor) wpas_dbus_getter_debug_level, - (WPADBusPropertyAccessor) wpas_dbus_setter_debug_level, - RW + wpas_dbus_getter_debug_level, + wpas_dbus_setter_debug_level }, { "DebugTimestamp", WPAS_DBUS_NEW_INTERFACE, "b", - (WPADBusPropertyAccessor) wpas_dbus_getter_debug_timestamp, - (WPADBusPropertyAccessor) wpas_dbus_setter_debug_timestamp, - RW + wpas_dbus_getter_debug_timestamp, + wpas_dbus_setter_debug_timestamp }, { "DebugShowKeys", WPAS_DBUS_NEW_INTERFACE, "b", - (WPADBusPropertyAccessor) wpas_dbus_getter_debug_show_keys, - (WPADBusPropertyAccessor) wpas_dbus_setter_debug_show_keys, - RW + wpas_dbus_getter_debug_show_keys, + wpas_dbus_setter_debug_show_keys }, { "Interfaces", WPAS_DBUS_NEW_INTERFACE, "ao", - (WPADBusPropertyAccessor) &wpas_dbus_getter_interfaces, - NULL, - R + wpas_dbus_getter_interfaces, + NULL }, { "EapMethods", WPAS_DBUS_NEW_INTERFACE, "as", - (WPADBusPropertyAccessor) wpas_dbus_getter_eap_methods, - NULL, - R + wpas_dbus_getter_eap_methods, + NULL }, - { NULL, NULL, NULL, NULL, NULL, 0 } + { NULL, NULL, NULL, NULL, NULL } }; static const struct wpa_dbus_signal_desc wpas_dbus_global_signals[] = { @@ -1726,6 +1833,15 @@ static const struct wpa_dbus_signal_desc wpas_dbus_global_signals[] = { END_ARGS } }, + { "NetworkRequest", WPAS_DBUS_NEW_IFACE_INTERFACE, + { + { "path", "o", ARG_OUT }, + { "field", "s", ARG_OUT }, + { "text", "s", ARG_OUT }, + END_ARGS + } + }, + /* Deprecated: use org.freedesktop.DBus.Properties.PropertiesChanged */ { "PropertiesChanged", WPAS_DBUS_NEW_INTERFACE, { { "properties", "a{sv}", ARG_OUT }, @@ -1802,20 +1918,19 @@ static void wpa_dbus_free(void *ptr) static const struct wpa_dbus_property_desc wpas_dbus_network_properties[] = { { "Properties", WPAS_DBUS_NEW_IFACE_NETWORK, "a{sv}", - (WPADBusPropertyAccessor) wpas_dbus_getter_network_properties, - (WPADBusPropertyAccessor) wpas_dbus_setter_network_properties, - RW + wpas_dbus_getter_network_properties, + wpas_dbus_setter_network_properties }, { "Enabled", WPAS_DBUS_NEW_IFACE_NETWORK, "b", - (WPADBusPropertyAccessor) wpas_dbus_getter_enabled, - (WPADBusPropertyAccessor) wpas_dbus_setter_enabled, - RW + wpas_dbus_getter_enabled, + wpas_dbus_setter_enabled }, - { NULL, NULL, NULL, NULL, NULL, 0 } + { NULL, NULL, NULL, NULL, NULL } }; static const struct wpa_dbus_signal_desc wpas_dbus_network_signals[] = { + /* Deprecated: use org.freedesktop.DBus.Properties.PropertiesChanged */ { "PropertiesChanged", WPAS_DBUS_NEW_IFACE_NETWORK, { { "properties", "a{sv}", ARG_OUT }, @@ -1925,8 +2040,7 @@ int wpas_dbus_unregister_network(struct wpa_supplicant *wpa_s, int nid) #endif /* CONFIG_P2P */ /* Do nothing if the control interface is not turned on */ - if (wpa_s == NULL || wpa_s->global == NULL || - wpa_s->dbus_new_path == NULL) + if (wpa_s->global == NULL || wpa_s->dbus_new_path == NULL) return 0; ctrl_iface = wpa_s->global->dbus; if (ctrl_iface == NULL) @@ -1949,60 +2063,51 @@ int wpas_dbus_unregister_network(struct wpa_supplicant *wpa_s, int nid) static const struct wpa_dbus_property_desc wpas_dbus_bss_properties[] = { { "SSID", WPAS_DBUS_NEW_IFACE_BSS, "ay", - (WPADBusPropertyAccessor) wpas_dbus_getter_bss_ssid, - NULL, - R + wpas_dbus_getter_bss_ssid, + NULL }, { "BSSID", WPAS_DBUS_NEW_IFACE_BSS, "ay", - (WPADBusPropertyAccessor) wpas_dbus_getter_bss_bssid, - NULL, - R + wpas_dbus_getter_bss_bssid, + NULL }, { "Privacy", WPAS_DBUS_NEW_IFACE_BSS, "b", - (WPADBusPropertyAccessor) wpas_dbus_getter_bss_privacy, - NULL, - R + wpas_dbus_getter_bss_privacy, + NULL }, { "Mode", WPAS_DBUS_NEW_IFACE_BSS, "s", - (WPADBusPropertyAccessor) wpas_dbus_getter_bss_mode, - NULL, - R + wpas_dbus_getter_bss_mode, + NULL }, { "Signal", WPAS_DBUS_NEW_IFACE_BSS, "n", - (WPADBusPropertyAccessor) wpas_dbus_getter_bss_signal, - NULL, - R + wpas_dbus_getter_bss_signal, + NULL }, { "Frequency", WPAS_DBUS_NEW_IFACE_BSS, "q", - (WPADBusPropertyAccessor) wpas_dbus_getter_bss_frequency, - NULL, - R + wpas_dbus_getter_bss_frequency, + NULL }, { "Rates", WPAS_DBUS_NEW_IFACE_BSS, "au", - (WPADBusPropertyAccessor) wpas_dbus_getter_bss_rates, - NULL, - R + wpas_dbus_getter_bss_rates, + NULL }, { "WPA", WPAS_DBUS_NEW_IFACE_BSS, "a{sv}", - (WPADBusPropertyAccessor) wpas_dbus_getter_bss_wpa, - NULL, - R + wpas_dbus_getter_bss_wpa, + NULL }, { "RSN", WPAS_DBUS_NEW_IFACE_BSS, "a{sv}", - (WPADBusPropertyAccessor) wpas_dbus_getter_bss_rsn, - NULL, - R + wpas_dbus_getter_bss_rsn, + NULL }, { "IEs", WPAS_DBUS_NEW_IFACE_BSS, "ay", - (WPADBusPropertyAccessor) wpas_dbus_getter_bss_ies, - NULL, - R + wpas_dbus_getter_bss_ies, + NULL }, - { NULL, NULL, NULL, NULL, NULL, 0 } + { NULL, NULL, NULL, NULL, NULL } }; static const struct wpa_dbus_signal_desc wpas_dbus_bss_signals[] = { + /* Deprecated: use org.freedesktop.DBus.Properties.PropertiesChanged */ { "PropertiesChanged", WPAS_DBUS_NEW_IFACE_BSS, { { "properties", "a{sv}", ARG_OUT }, @@ -2165,6 +2270,15 @@ static const struct wpa_dbus_method_desc wpas_dbus_interface_methods[] = { END_ARGS } }, + { "NetworkReply", WPAS_DBUS_NEW_IFACE_INTERFACE, + (WPADBusMethodHandler) &wpas_dbus_handler_network_reply, + { + { "path", "o", ARG_IN }, + { "field", "s", ARG_IN }, + { "value", "s", ARG_IN }, + END_ARGS + } + }, { "AddBlob", WPAS_DBUS_NEW_IFACE_INTERFACE, (WPADBusMethodHandler) &wpas_dbus_handler_add_blob, { @@ -2245,7 +2359,7 @@ static const struct wpa_dbus_method_desc wpas_dbus_interface_methods[] = { (WPADBusMethodHandler)wpas_dbus_handler_p2p_connect, { { "args", "a{sv}", ARG_IN }, - { "generated_pin", "i", ARG_OUT }, + { "generated_pin", "s", ARG_OUT }, END_ARGS } }, @@ -2378,108 +2492,102 @@ static const struct wpa_dbus_method_desc wpas_dbus_interface_methods[] = { static const struct wpa_dbus_property_desc wpas_dbus_interface_properties[] = { { "Capabilities", WPAS_DBUS_NEW_IFACE_INTERFACE, "a{sv}", - (WPADBusPropertyAccessor) wpas_dbus_getter_capabilities, - NULL, R + wpas_dbus_getter_capabilities, + NULL }, { "State", WPAS_DBUS_NEW_IFACE_INTERFACE, "s", - (WPADBusPropertyAccessor) wpas_dbus_getter_state, - NULL, R + wpas_dbus_getter_state, + NULL }, { "Scanning", WPAS_DBUS_NEW_IFACE_INTERFACE, "b", - (WPADBusPropertyAccessor) wpas_dbus_getter_scanning, - NULL, R + wpas_dbus_getter_scanning, + NULL }, { "ApScan", WPAS_DBUS_NEW_IFACE_INTERFACE, "u", - (WPADBusPropertyAccessor) wpas_dbus_getter_ap_scan, - (WPADBusPropertyAccessor) wpas_dbus_setter_ap_scan, - RW + wpas_dbus_getter_ap_scan, + wpas_dbus_setter_ap_scan }, { "BSSExpireAge", WPAS_DBUS_NEW_IFACE_INTERFACE, "u", - (WPADBusPropertyAccessor) wpas_dbus_getter_bss_expire_age, - (WPADBusPropertyAccessor) wpas_dbus_setter_bss_expire_age, - RW + wpas_dbus_getter_bss_expire_age, + wpas_dbus_setter_bss_expire_age }, { "BSSExpireCount", WPAS_DBUS_NEW_IFACE_INTERFACE, "u", - (WPADBusPropertyAccessor) wpas_dbus_getter_bss_expire_count, - (WPADBusPropertyAccessor) wpas_dbus_setter_bss_expire_count, - RW + wpas_dbus_getter_bss_expire_count, + wpas_dbus_setter_bss_expire_count }, { "Country", WPAS_DBUS_NEW_IFACE_INTERFACE, "s", - (WPADBusPropertyAccessor) wpas_dbus_getter_country, - (WPADBusPropertyAccessor) wpas_dbus_setter_country, - RW + wpas_dbus_getter_country, + wpas_dbus_setter_country }, { "Ifname", WPAS_DBUS_NEW_IFACE_INTERFACE, "s", - (WPADBusPropertyAccessor) wpas_dbus_getter_ifname, - NULL, R + wpas_dbus_getter_ifname, + NULL }, { "Driver", WPAS_DBUS_NEW_IFACE_INTERFACE, "s", - (WPADBusPropertyAccessor) wpas_dbus_getter_driver, - NULL, R + wpas_dbus_getter_driver, + NULL }, { "BridgeIfname", WPAS_DBUS_NEW_IFACE_INTERFACE, "s", - (WPADBusPropertyAccessor) wpas_dbus_getter_bridge_ifname, - NULL, R + wpas_dbus_getter_bridge_ifname, + NULL }, { "CurrentBSS", WPAS_DBUS_NEW_IFACE_INTERFACE, "o", - (WPADBusPropertyAccessor) wpas_dbus_getter_current_bss, - NULL, R + wpas_dbus_getter_current_bss, + NULL }, { "CurrentNetwork", WPAS_DBUS_NEW_IFACE_INTERFACE, "o", - (WPADBusPropertyAccessor) wpas_dbus_getter_current_network, - NULL, R + wpas_dbus_getter_current_network, + NULL }, { "CurrentAuthMode", WPAS_DBUS_NEW_IFACE_INTERFACE, "s", - (WPADBusPropertyAccessor) wpas_dbus_getter_current_auth_mode, - NULL, R + wpas_dbus_getter_current_auth_mode, + NULL }, { "Blobs", WPAS_DBUS_NEW_IFACE_INTERFACE, "a{say}", - (WPADBusPropertyAccessor) wpas_dbus_getter_blobs, - NULL, R + wpas_dbus_getter_blobs, + NULL }, { "BSSs", WPAS_DBUS_NEW_IFACE_INTERFACE, "ao", - (WPADBusPropertyAccessor) wpas_dbus_getter_bsss, - NULL, R + wpas_dbus_getter_bsss, + NULL }, { "Networks", WPAS_DBUS_NEW_IFACE_INTERFACE, "ao", - (WPADBusPropertyAccessor) wpas_dbus_getter_networks, - NULL, R + wpas_dbus_getter_networks, + NULL }, #ifdef CONFIG_WPS { "ProcessCredentials", WPAS_DBUS_NEW_IFACE_WPS, "b", - (WPADBusPropertyAccessor) wpas_dbus_getter_process_credentials, - (WPADBusPropertyAccessor) wpas_dbus_setter_process_credentials, - RW + wpas_dbus_getter_process_credentials, + wpas_dbus_setter_process_credentials }, #endif /* CONFIG_WPS */ #ifdef CONFIG_P2P { "P2PDeviceProperties", WPAS_DBUS_NEW_IFACE_P2PDEVICE, "a{sv}", - (WPADBusPropertyAccessor) wpas_dbus_getter_p2p_device_properties, - (WPADBusPropertyAccessor) wpas_dbus_setter_p2p_device_properties, - RW + wpas_dbus_getter_p2p_device_properties, + wpas_dbus_setter_p2p_device_properties }, { "Peers", WPAS_DBUS_NEW_IFACE_P2PDEVICE, "ao", - (WPADBusPropertyAccessor) wpas_dbus_getter_p2p_peers, - NULL, R + wpas_dbus_getter_p2p_peers, + NULL }, { "Role", WPAS_DBUS_NEW_IFACE_P2PDEVICE, "s", - (WPADBusPropertyAccessor) wpas_dbus_getter_p2p_role, - NULL, R + wpas_dbus_getter_p2p_role, + NULL }, { "Group", WPAS_DBUS_NEW_IFACE_P2PDEVICE, "o", - (WPADBusPropertyAccessor) wpas_dbus_getter_p2p_group, - NULL, R + wpas_dbus_getter_p2p_group, + NULL }, { "PeerGO", WPAS_DBUS_NEW_IFACE_P2PDEVICE, "o", - (WPADBusPropertyAccessor) wpas_dbus_getter_p2p_peergo, - NULL, R + wpas_dbus_getter_p2p_peergo, + NULL }, { "PersistentGroups", WPAS_DBUS_NEW_IFACE_P2PDEVICE, "ao", - (WPADBusPropertyAccessor) wpas_dbus_getter_persistent_groups, - NULL, R + wpas_dbus_getter_persistent_groups, + NULL }, #endif /* CONFIG_P2P */ - { NULL, NULL, NULL, NULL, NULL, 0 } + { NULL, NULL, NULL, NULL, NULL } }; static const struct wpa_dbus_signal_desc wpas_dbus_interface_signals[] = { @@ -2533,6 +2641,7 @@ static const struct wpa_dbus_signal_desc wpas_dbus_interface_signals[] = { END_ARGS } }, + /* Deprecated: use org.freedesktop.DBus.Properties.PropertiesChanged */ { "PropertiesChanged", WPAS_DBUS_NEW_IFACE_INTERFACE, { { "properties", "a{sv}", ARG_OUT }, @@ -2553,6 +2662,7 @@ static const struct wpa_dbus_signal_desc wpas_dbus_interface_signals[] = { END_ARGS } }, + /* Deprecated: use org.freedesktop.DBus.Properties.PropertiesChanged */ { "PropertiesChanged", WPAS_DBUS_NEW_IFACE_WPS, { { "properties", "a{sv}", ARG_OUT }, @@ -2784,14 +2894,14 @@ int wpas_dbus_unregister_interface(struct wpa_supplicant *wpa_s) static const struct wpa_dbus_property_desc wpas_dbus_p2p_peer_properties[] = { { "Properties", WPAS_DBUS_NEW_IFACE_P2P_PEER, "a{sv}", - (WPADBusPropertyAccessor) wpas_dbus_getter_p2p_peer_properties, - NULL, R + wpas_dbus_getter_p2p_peer_properties, + NULL }, { "IEs", WPAS_DBUS_NEW_IFACE_P2P_PEER, "ay", - (WPADBusPropertyAccessor) wpas_dbus_getter_p2p_peer_ies, - NULL, R + wpas_dbus_getter_p2p_peer_ies, + NULL }, - { NULL, NULL, NULL, NULL, NULL, 0 } + { NULL, NULL, NULL, NULL, NULL } }; static const struct wpa_dbus_signal_desc wpas_dbus_p2p_peer_signals[] = { @@ -2981,16 +3091,15 @@ int wpas_dbus_unregister_peer(struct wpa_supplicant *wpa_s, static const struct wpa_dbus_property_desc wpas_dbus_p2p_group_properties[] = { { "Members", WPAS_DBUS_NEW_IFACE_P2P_GROUP, "ao", - (WPADBusPropertyAccessor) wpas_dbus_getter_p2p_group_members, - NULL, R + wpas_dbus_getter_p2p_group_members, + NULL }, { "Properties", WPAS_DBUS_NEW_IFACE_P2P_GROUP, "a{sv}", - (WPADBusPropertyAccessor) wpas_dbus_getter_p2p_group_properties, - (WPADBusPropertyAccessor) wpas_dbus_setter_p2p_group_properties, - RW + wpas_dbus_getter_p2p_group_properties, + wpas_dbus_setter_p2p_group_properties }, - { NULL, NULL, NULL, NULL, NULL, 0 } + { NULL, NULL, NULL, NULL, NULL } }; static const struct wpa_dbus_signal_desc wpas_dbus_p2p_group_signals[] = { @@ -3111,10 +3220,10 @@ void wpas_dbus_unregister_p2p_group(struct wpa_supplicant *wpa_s, static const struct wpa_dbus_property_desc wpas_dbus_p2p_groupmember_properties[] = { { "Properties", WPAS_DBUS_NEW_IFACE_P2P_GROUPMEMBER, "a{sv}", - (WPADBusPropertyAccessor) wpas_dbus_getter_p2p_group_properties, - NULL, R + wpas_dbus_getter_p2p_group_properties, + NULL }, - { NULL, NULL, NULL, NULL, NULL, 0 } + { NULL, NULL, NULL, NULL, NULL } }; /** @@ -3218,13 +3327,10 @@ void wpas_dbus_unregister_p2p_groupmember(struct wpa_supplicant *wpa_s, static const struct wpa_dbus_property_desc wpas_dbus_persistent_group_properties[] = { { "Properties", WPAS_DBUS_NEW_IFACE_PERSISTENT_GROUP, "a{sv}", - (WPADBusPropertyAccessor) wpas_dbus_getter_persistent_group_properties, - (WPADBusPropertyAccessor) - wpas_dbus_setter_persistent_group_properties, - RW + wpas_dbus_setter_persistent_group_properties }, - { NULL, NULL, NULL, NULL, NULL, 0 } + { NULL, NULL, NULL, NULL, NULL } }; /* No signals intended for persistent group objects */ diff --git a/wpa_supplicant/dbus/dbus_new.h b/wpa_supplicant/dbus/dbus_new.h index 080000c..93ce722 100644 --- a/wpa_supplicant/dbus/dbus_new.h +++ b/wpa_supplicant/dbus/dbus_new.h @@ -16,6 +16,7 @@ #ifndef CTRL_IFACE_DBUS_NEW_H #define CTRL_IFACE_DBUS_NEW_H +#include "common/defs.h" #include "p2p/p2p.h" struct wpa_global; @@ -24,7 +25,6 @@ struct wpa_ssid; struct wps_event_m2d; struct wps_event_fail; struct wps_credential; -enum wpa_states; enum wpas_dbus_prop { WPAS_DBUS_PROP_AP_SCAN, @@ -131,6 +131,10 @@ void wpas_dbus_bss_signal_prop_changed(struct wpa_supplicant *wpa_s, void wpas_dbus_signal_network_enabled_changed(struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid); void wpas_dbus_signal_network_selected(struct wpa_supplicant *wpa_s, int id); +void wpas_dbus_signal_network_request(struct wpa_supplicant *wpa_s, + struct wpa_ssid *ssid, + enum wpa_ctrl_req_type rtype, + const char *default_text); void wpas_dbus_signal_scan_done(struct wpa_supplicant *wpa_s, int success); void wpas_dbus_signal_wps_cred(struct wpa_supplicant *wpa_s, const struct wps_credential *cred); @@ -175,7 +179,8 @@ void wpas_dbus_signal_p2p_group_started(struct wpa_supplicant *wpa_s, int client, int network_id); void wpas_dbus_register_p2p_group(struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid); -void wpas_dbus_signal_p2p_go_neg_resp(struct wpa_supplicant *wpa_s, int status); +void wpas_dbus_signal_p2p_go_neg_resp(struct wpa_supplicant *wpa_s, + struct p2p_go_neg_results *res); void wpas_dbus_unregister_p2p_group(struct wpa_supplicant *wpa_s, const struct wpa_ssid *ssid); int wpas_dbus_register_persistent_group(struct wpa_supplicant *wpa_s, @@ -241,6 +246,12 @@ static inline void wpas_dbus_signal_network_selected( { } +static inline void wpas_dbus_signal_network_request( + struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid, + enum wpa_ctrl_req_type rtype, const char *default_txt) +{ +} + static inline void wpas_dbus_signal_scan_done(struct wpa_supplicant *wpa_s, int success) { @@ -375,7 +386,8 @@ static inline int wpas_dbus_unregister_persistent_group( } static inline void -wpas_dbus_signal_p2p_go_neg_resp(struct wpa_supplicant *wpa_s, int status) +wpas_dbus_signal_p2p_go_neg_resp(struct wpa_supplicant *wpa_s, + struct p2p_go_neg_results *res) { } diff --git a/wpa_supplicant/dbus/dbus_new_handlers.c b/wpa_supplicant/dbus/dbus_new_handlers.c index ee8757a..e3526d4 100644 --- a/wpa_supplicant/dbus/dbus_new_handlers.c +++ b/wpa_supplicant/dbus/dbus_new_handlers.c @@ -25,9 +25,9 @@ #include "../wpa_supplicant_i.h" #include "../driver_i.h" #include "../notify.h" -#include "../wpas_glue.h" #include "../bss.h" #include "../scan.h" +#include "../ctrl_iface.h" #include "dbus_new_helpers.h" #include "dbus_new.h" #include "dbus_new_handlers.h" @@ -163,36 +163,35 @@ static struct wpa_supplicant * get_iface_by_dbus_path( /** * set_network_properties - Set properties of a configured network - * @message: Pointer to incoming dbus message * @wpa_s: wpa_supplicant structure for a network interface * @ssid: wpa_ssid structure for a configured network * @iter: DBus message iterator containing dictionary of network * properties to set. - * Returns: NULL when succeed or DBus error on failure + * @error: On failure, an error describing the failure + * Returns: TRUE if the request succeeds, FALSE if it failed * * Sets network configuration with parameters given id DBus dictionary */ -DBusMessage * set_network_properties(DBusMessage *message, - struct wpa_supplicant *wpa_s, - struct wpa_ssid *ssid, - DBusMessageIter *iter) +dbus_bool_t set_network_properties(struct wpa_supplicant *wpa_s, + struct wpa_ssid *ssid, + DBusMessageIter *iter, + DBusError *error) { - struct wpa_dbus_dict_entry entry = { .type = DBUS_TYPE_STRING }; - DBusMessage *reply = NULL; DBusMessageIter iter_dict; + char *value = NULL; - if (!wpa_dbus_dict_open_read(iter, &iter_dict)) - return wpas_dbus_error_invalid_args(message, NULL); + if (!wpa_dbus_dict_open_read(iter, &iter_dict, error)) + return FALSE; while (wpa_dbus_dict_has_dict_entry(&iter_dict)) { - char *value = NULL; size_t size = 50; int ret; - if (!wpa_dbus_dict_get_entry(&iter_dict, &entry)) { - reply = wpas_dbus_error_invalid_args(message, NULL); - break; - } + + if (!wpa_dbus_dict_get_entry(&iter_dict, &entry)) + goto error; + + value = NULL; if (entry.type == DBUS_TYPE_ARRAY && entry.array_type == DBUS_TYPE_BYTE) { if (entry.array_len <= 0) @@ -261,71 +260,59 @@ DBusMessage * set_network_properties(DBusMessage *message, os_free(value); wpa_dbus_dict_entry_clear(&entry); - continue; - - error: - os_free(value); - reply = wpas_dbus_error_invalid_args(message, entry.key); - wpa_dbus_dict_entry_clear(&entry); - break; } - return reply; + return TRUE; + +error: + os_free(value); + wpa_dbus_dict_entry_clear(&entry); + dbus_set_error_const(error, DBUS_ERROR_INVALID_ARGS, + "invalid message format"); + return FALSE; } /** * wpas_dbus_simple_property_getter - Get basic type property - * @message: Pointer to incoming dbus message + * @iter: Message iter to use when appending arguments * @type: DBus type of property (must be basic type) * @val: pointer to place holding property value - * Returns: The DBus message containing response for Properties.Get call - * or DBus error message if error occurred. + * @error: On failure an error describing the failure + * Returns: TRUE if the request was successful, FALSE if it failed * * Generic getter for basic type properties. Type is required to be basic. */ -DBusMessage * wpas_dbus_simple_property_getter(DBusMessage *message, - const int type, const void *val) +dbus_bool_t wpas_dbus_simple_property_getter(DBusMessageIter *iter, + const int type, + const void *val, + DBusError *error) { - DBusMessage *reply = NULL; - DBusMessageIter iter, variant_iter; + DBusMessageIter variant_iter; if (!dbus_type_is_basic(type)) { - wpa_printf(MSG_ERROR, "dbus: wpas_dbus_simple_property_getter:" - " given type is not basic"); - return wpas_dbus_error_unknown_error(message, NULL); + dbus_set_error(error, DBUS_ERROR_FAILED, + "%s: given type is not basic", __func__); + return FALSE; } - if (message == NULL) - reply = dbus_message_new(DBUS_MESSAGE_TYPE_SIGNAL); - else - reply = dbus_message_new_method_return(message); - - if (reply != NULL) { - dbus_message_iter_init_append(reply, &iter); - if (!dbus_message_iter_open_container( - &iter, DBUS_TYPE_VARIANT, - wpa_dbus_type_as_string(type), &variant_iter) || - !dbus_message_iter_append_basic(&variant_iter, type, - val) || - !dbus_message_iter_close_container(&iter, &variant_iter)) { - wpa_printf(MSG_ERROR, "dbus: " - "wpas_dbus_simple_property_getter: out of " - "memory to put property value into " - "message"); - dbus_message_unref(reply); - reply = dbus_message_new_error(message, - DBUS_ERROR_NO_MEMORY, - NULL); - } - } else { - wpa_printf(MSG_ERROR, "dbus: wpas_dbus_simple_property_getter:" - " out of memory to return property value"); - reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY, - NULL); - } + if (!dbus_message_iter_open_container(iter, DBUS_TYPE_VARIANT, + wpa_dbus_type_as_string(type), + &variant_iter)) + goto error; - return reply; + if (!dbus_message_iter_append_basic(&variant_iter, type, val)) + goto error; + + if (!dbus_message_iter_close_container(iter, &variant_iter)) + goto error; + + return TRUE; + +error: + dbus_set_error(error, DBUS_ERROR_FAILED, + "%s: error constructing reply", __func__); + return FALSE; } @@ -334,102 +321,79 @@ DBusMessage * wpas_dbus_simple_property_getter(DBusMessage *message, * @message: Pointer to incoming dbus message * @type: DBus type of property (must be basic type) * @val: pointer to place where value being set will be stored - * Returns: NULL or DBus error message if error occurred. + * Returns: TRUE if the request was successful, FALSE if it failed * * Generic setter for basic type properties. Type is required to be basic. */ -DBusMessage * wpas_dbus_simple_property_setter(DBusMessage *message, - const int type, void *val) +dbus_bool_t wpas_dbus_simple_property_setter(DBusMessageIter *iter, + DBusError *error, + const int type, void *val) { - DBusMessageIter iter, variant_iter; + DBusMessageIter variant_iter; if (!dbus_type_is_basic(type)) { - wpa_printf(MSG_ERROR, "dbus: wpas_dbus_simple_property_setter:" - " given type is not basic"); - return wpas_dbus_error_unknown_error(message, NULL); + dbus_set_error(error, DBUS_ERROR_FAILED, + "%s: given type is not basic", __func__); + return FALSE; } - if (!dbus_message_iter_init(message, &iter)) { - wpa_printf(MSG_ERROR, "dbus: wpas_dbus_simple_property_setter:" - " out of memory to return scanning state"); - return dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY, - NULL); - } - - /* omit first and second argument and get value from third */ - dbus_message_iter_next(&iter); - dbus_message_iter_next(&iter); - dbus_message_iter_recurse(&iter, &variant_iter); - + /* Look at the new value */ + dbus_message_iter_recurse(iter, &variant_iter); if (dbus_message_iter_get_arg_type(&variant_iter) != type) { - wpa_printf(MSG_DEBUG, "dbus: wpas_dbus_simple_property_setter:" - " wrong property type"); - return wpas_dbus_error_invalid_args(message, - "wrong property type"); + dbus_set_error_const(error, DBUS_ERROR_FAILED, + "wrong property type"); + return FALSE; } dbus_message_iter_get_basic(&variant_iter, val); - return NULL; + return TRUE; } /** * wpas_dbus_simple_array_property_getter - Get array type property - * @message: Pointer to incoming dbus message + * @iter: Pointer to incoming dbus message iterator * @type: DBus type of property array elements (must be basic type) * @array: pointer to array of elements to put into response message * @array_len: length of above array - * Returns: The DBus message containing response for Properties.Get call - * or DBus error message if error occurred. + * @error: a pointer to an error to fill on failure + * Returns: TRUE if the request succeeded, FALSE if it failed * * Generic getter for array type properties. Array elements type is * required to be basic. */ -DBusMessage * wpas_dbus_simple_array_property_getter(DBusMessage *message, - const int type, - const void *array, - size_t array_len) +dbus_bool_t wpas_dbus_simple_array_property_getter(DBusMessageIter *iter, + const int type, + const void *array, + size_t array_len, + DBusError *error) { - DBusMessage *reply = NULL; - DBusMessageIter iter, variant_iter, array_iter; + DBusMessageIter variant_iter, array_iter; char type_str[] = "a?"; /* ? will be replaced with subtype letter; */ const char *sub_type_str; size_t element_size, i; if (!dbus_type_is_basic(type)) { - wpa_printf(MSG_ERROR, "dbus: " - "wpas_dbus_simple_array_property_getter: given " - "type is not basic"); - return wpas_dbus_error_unknown_error(message, NULL); + dbus_set_error(error, DBUS_ERROR_FAILED, + "%s: given type is not basic", __func__); + return FALSE; } sub_type_str = wpa_dbus_type_as_string(type); type_str[1] = sub_type_str[0]; - if (message == NULL) - reply = dbus_message_new(DBUS_MESSAGE_TYPE_SIGNAL); - else - reply = dbus_message_new_method_return(message); - if (reply == NULL) { - wpa_printf(MSG_ERROR, "dbus: " - "wpas_dbus_simple_array_property_getter: out of " - "memory to create return message"); - return dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY, - NULL); + if (!dbus_message_iter_open_container(iter, DBUS_TYPE_VARIANT, + type_str, &variant_iter)) { + dbus_set_error(error, DBUS_ERROR_FAILED, + "%s: failed to construct message 1", __func__); + return FALSE; } - dbus_message_iter_init_append(reply, &iter); - - if (!dbus_message_iter_open_container(&iter, DBUS_TYPE_VARIANT, - type_str, &variant_iter) || - !dbus_message_iter_open_container(&variant_iter, DBUS_TYPE_ARRAY, + if (!dbus_message_iter_open_container(&variant_iter, DBUS_TYPE_ARRAY, sub_type_str, &array_iter)) { - wpa_printf(MSG_ERROR, "dbus: " - "wpas_dbus_simple_array_property_getter: out of " - "memory to open container"); - dbus_message_unref(reply); - return dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY, - NULL); + dbus_set_error(error, DBUS_ERROR_FAILED, + "%s: failed to construct message 2", __func__); + return FALSE; } switch(type) { @@ -457,11 +421,9 @@ DBusMessage * wpas_dbus_simple_array_property_getter(DBusMessage *message, element_size = sizeof(char *); break; default: - wpa_printf(MSG_ERROR, "dbus: " - "wpas_dbus_simple_array_property_getter: " - "fatal: unknown element type"); - element_size = 1; - break; + dbus_set_error(error, DBUS_ERROR_FAILED, + "%s: unknown element type %d", __func__, type); + return FALSE; } for (i = 0; i < array_len; i++) { @@ -469,17 +431,19 @@ DBusMessage * wpas_dbus_simple_array_property_getter(DBusMessage *message, array + i * element_size); } - if (!dbus_message_iter_close_container(&variant_iter, &array_iter) || - !dbus_message_iter_close_container(&iter, &variant_iter)) { - wpa_printf(MSG_ERROR, "dbus: " - "wpas_dbus_simple_array_property_getter: out of " - "memory to close container"); - dbus_message_unref(reply); - return dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY, - NULL); + if (!dbus_message_iter_close_container(&variant_iter, &array_iter)) { + dbus_set_error(error, DBUS_ERROR_FAILED, + "%s: failed to construct message 3", __func__); + return FALSE; } - return reply; + if (!dbus_message_iter_close_container(iter, &variant_iter)) { + dbus_set_error(error, DBUS_ERROR_FAILED, + "%s: failed to construct message 4", __func__); + return FALSE; + } + + return TRUE; } @@ -508,7 +472,7 @@ DBusMessage * wpas_dbus_handler_create_interface(DBusMessage *message, dbus_message_iter_init(message, &iter); - if (!wpa_dbus_dict_open_read(&iter, &iter_dict)) + if (!wpa_dbus_dict_open_read(&iter, &iter_dict, NULL)) goto error; while (wpa_dbus_dict_has_dict_entry(&iter_dict)) { if (!wpa_dbus_dict_get_entry(&iter_dict, &entry)) @@ -612,7 +576,7 @@ DBusMessage * wpas_dbus_handler_remove_interface(DBusMessage *message, wpa_s = get_iface_by_dbus_path(global, path); if (wpa_s == NULL) reply = wpas_dbus_error_iface_unknown(message); - else if (wpa_supplicant_remove_iface(global, wpa_s, 0)) { + else if (wpa_supplicant_remove_iface(global, wpa_s)) { reply = wpas_dbus_error_unknown_error( message, "wpa_supplicant couldn't remove this " "interface."); @@ -664,79 +628,86 @@ DBusMessage * wpas_dbus_handler_get_interface(DBusMessage *message, /** * wpas_dbus_getter_debug_level - Get debug level - * @message: Pointer to incoming dbus message - * @global: %wpa_supplicant global data structure - * Returns: DBus message with value of debug level + * @iter: Pointer to incoming dbus message iter + * @error: Location to store error on failure + * @user_data: Function specific data + * Returns: TRUE on success, FALSE on failure * * Getter for "DebugLevel" property. */ -DBusMessage * wpas_dbus_getter_debug_level(DBusMessage *message, - struct wpa_global *global) +dbus_bool_t wpas_dbus_getter_debug_level(DBusMessageIter *iter, + DBusError *error, + void *user_data) { const char *str; int idx = wpa_debug_level; + if (idx < 0) idx = 0; if (idx > 5) idx = 5; str = debug_strings[idx]; - return wpas_dbus_simple_property_getter(message, DBUS_TYPE_STRING, - &str); + return wpas_dbus_simple_property_getter(iter, DBUS_TYPE_STRING, + &str, error); } /** * wpas_dbus_getter_debug_timestamp - Get debug timestamp - * @message: Pointer to incoming dbus message - * @global: %wpa_supplicant global data structure - * Returns: DBus message with value of debug timestamp + * @iter: Pointer to incoming dbus message iter + * @error: Location to store error on failure + * @user_data: Function specific data + * Returns: TRUE on success, FALSE on failure * * Getter for "DebugTimestamp" property. */ -DBusMessage * wpas_dbus_getter_debug_timestamp(DBusMessage *message, - struct wpa_global *global) +dbus_bool_t wpas_dbus_getter_debug_timestamp(DBusMessageIter *iter, + DBusError *error, + void *user_data) { - return wpas_dbus_simple_property_getter(message, DBUS_TYPE_BOOLEAN, - &wpa_debug_timestamp); + return wpas_dbus_simple_property_getter(iter, DBUS_TYPE_BOOLEAN, + &wpa_debug_timestamp, error); } /** * wpas_dbus_getter_debug_show_keys - Get debug show keys - * @message: Pointer to incoming dbus message - * @global: %wpa_supplicant global data structure - * Returns: DBus message with value of debug show_keys + * @iter: Pointer to incoming dbus message iter + * @error: Location to store error on failure + * @user_data: Function specific data + * Returns: TRUE on success, FALSE on failure * * Getter for "DebugShowKeys" property. */ -DBusMessage * wpas_dbus_getter_debug_show_keys(DBusMessage *message, - struct wpa_global *global) +dbus_bool_t wpas_dbus_getter_debug_show_keys(DBusMessageIter *iter, + DBusError *error, + void *user_data) { - return wpas_dbus_simple_property_getter(message, DBUS_TYPE_BOOLEAN, - &wpa_debug_show_keys); + return wpas_dbus_simple_property_getter(iter, DBUS_TYPE_BOOLEAN, + &wpa_debug_show_keys, error); } /** * wpas_dbus_setter_debug_level - Set debug level - * @message: Pointer to incoming dbus message - * @global: %wpa_supplicant global data structure - * Returns: %NULL or DBus error message + * @iter: Pointer to incoming dbus message iter + * @error: Location to store error on failure + * @user_data: Function specific data + * Returns: TRUE on success, FALSE on failure * * Setter for "DebugLevel" property. */ -DBusMessage * wpas_dbus_setter_debug_level(DBusMessage *message, - struct wpa_global *global) +dbus_bool_t wpas_dbus_setter_debug_level(DBusMessageIter *iter, + DBusError *error, void *user_data) { - DBusMessage *reply; + struct wpa_global *global = user_data; const char *str = NULL; int i, val = -1; - reply = wpas_dbus_simple_property_setter(message, DBUS_TYPE_STRING, - &str); - if (reply) - return reply; + if (!wpas_dbus_simple_property_setter(iter, error, DBUS_TYPE_STRING, + &str)) + return FALSE; for (i = 0; debug_strings[i]; i++) if (os_strcmp(debug_strings[i], str) == 0) { @@ -747,137 +718,142 @@ DBusMessage * wpas_dbus_setter_debug_level(DBusMessage *message, if (val < 0 || wpa_supplicant_set_debug_params(global, val, wpa_debug_timestamp, wpa_debug_show_keys)) { - return wpas_dbus_error_invalid_args( - message, "Wrong debug level value"); + dbus_set_error_const(error, DBUS_ERROR_FAILED, "wrong debug " + "level value"); + return FALSE; } - return NULL; + return TRUE; } /** * wpas_dbus_setter_debug_timestamp - Set debug timestamp - * @message: Pointer to incoming dbus message - * @global: %wpa_supplicant global data structure - * Returns: %NULL or DBus error message + * @iter: Pointer to incoming dbus message iter + * @error: Location to store error on failure + * @user_data: Function specific data + * Returns: TRUE on success, FALSE on failure * * Setter for "DebugTimestamp" property. */ -DBusMessage * wpas_dbus_setter_debug_timestamp(DBusMessage *message, - struct wpa_global *global) +dbus_bool_t wpas_dbus_setter_debug_timestamp(DBusMessageIter *iter, + DBusError *error, + void *user_data) { - DBusMessage *reply; + struct wpa_global *global = user_data; dbus_bool_t val; - reply = wpas_dbus_simple_property_setter(message, DBUS_TYPE_BOOLEAN, - &val); - if (reply) - return reply; + if (!wpas_dbus_simple_property_setter(iter, error, DBUS_TYPE_BOOLEAN, + &val)) + return FALSE; wpa_supplicant_set_debug_params(global, wpa_debug_level, val ? 1 : 0, wpa_debug_show_keys); - - return NULL; + return TRUE; } /** * wpas_dbus_setter_debug_show_keys - Set debug show keys - * @message: Pointer to incoming dbus message - * @global: %wpa_supplicant global data structure - * Returns: %NULL or DBus error message + * @iter: Pointer to incoming dbus message iter + * @error: Location to store error on failure + * @user_data: Function specific data + * Returns: TRUE on success, FALSE on failure * * Setter for "DebugShowKeys" property. */ -DBusMessage * wpas_dbus_setter_debug_show_keys(DBusMessage *message, - struct wpa_global *global) +dbus_bool_t wpas_dbus_setter_debug_show_keys(DBusMessageIter *iter, + DBusError *error, + void *user_data) { - DBusMessage *reply; + struct wpa_global *global = user_data; dbus_bool_t val; - reply = wpas_dbus_simple_property_setter(message, DBUS_TYPE_BOOLEAN, - &val); - if (reply) - return reply; + if (!wpas_dbus_simple_property_setter(iter, error, DBUS_TYPE_BOOLEAN, + &val)) + return FALSE; wpa_supplicant_set_debug_params(global, wpa_debug_level, wpa_debug_timestamp, val ? 1 : 0); - - return NULL; + return TRUE; } /** * wpas_dbus_getter_interfaces - Request registered interfaces list - * @message: Pointer to incoming dbus message - * @global: %wpa_supplicant global data structure - * Returns: The object paths array containing registered interfaces - * objects paths or DBus error on failure + * @iter: Pointer to incoming dbus message iter + * @error: Location to store error on failure + * @user_data: Function specific data + * Returns: TRUE on success, FALSE on failure * * Getter for "Interfaces" property. Handles requests * by dbus clients to return list of registered interfaces objects * paths */ -DBusMessage * wpas_dbus_getter_interfaces(DBusMessage *message, - struct wpa_global *global) +dbus_bool_t wpas_dbus_getter_interfaces(DBusMessageIter *iter, + DBusError *error, + void *user_data) { - DBusMessage *reply = NULL; + struct wpa_global *global = user_data; struct wpa_supplicant *wpa_s; const char **paths; unsigned int i = 0, num = 0; + dbus_bool_t success; for (wpa_s = global->ifaces; wpa_s; wpa_s = wpa_s->next) num++; paths = os_zalloc(num * sizeof(char*)); if (!paths) { - return dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY, - NULL); + dbus_set_error_const(error, DBUS_ERROR_NO_MEMORY, "no memory"); + return FALSE; } for (wpa_s = global->ifaces; wpa_s; wpa_s = wpa_s->next) paths[i++] = wpa_s->dbus_new_path; - reply = wpas_dbus_simple_array_property_getter(message, - DBUS_TYPE_OBJECT_PATH, - paths, num); + success = wpas_dbus_simple_array_property_getter(iter, + DBUS_TYPE_OBJECT_PATH, + paths, num, error); os_free(paths); - return reply; + return success; } /** * wpas_dbus_getter_eap_methods - Request supported EAP methods list - * @message: Pointer to incoming dbus message - * @nothing: not used argument. may be NULL or anything else - * Returns: The object paths array containing supported EAP methods - * represented by strings or DBus error on failure + * @iter: Pointer to incoming dbus message iter + * @error: Location to store error on failure + * @user_data: Function specific data + * Returns: TRUE on success, FALSE on failure * * Getter for "EapMethods" property. Handles requests * by dbus clients to return list of strings with supported EAP methods */ -DBusMessage * wpas_dbus_getter_eap_methods(DBusMessage *message, void *nothing) +dbus_bool_t wpas_dbus_getter_eap_methods(DBusMessageIter *iter, + DBusError *error, void *user_data) { - DBusMessage *reply = NULL; char **eap_methods; size_t num_items = 0; + dbus_bool_t success; eap_methods = eap_get_names_as_string_array(&num_items); if (!eap_methods) { - return dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY, - NULL); + dbus_set_error_const(error, DBUS_ERROR_NO_MEMORY, "no memory"); + return FALSE; } - reply = wpas_dbus_simple_array_property_getter(message, - DBUS_TYPE_STRING, - eap_methods, num_items); + success = wpas_dbus_simple_array_property_getter(iter, + DBUS_TYPE_STRING, + eap_methods, + num_items, error); while (num_items) os_free(eap_methods[--num_items]); os_free(eap_methods); - return reply; + return success; } @@ -1288,6 +1264,7 @@ DBusMessage * wpas_dbus_handler_add_network(DBusMessage *message, DBusMessageIter iter; struct wpa_ssid *ssid = NULL; char path_buf[WPAS_DBUS_OBJECT_PATH_MAX], *path = path_buf; + DBusError error; dbus_message_iter_init(message, &iter); @@ -1305,11 +1282,15 @@ DBusMessage * wpas_dbus_handler_add_network(DBusMessage *message, ssid->disabled = 1; wpa_config_set_network_defaults(ssid); - reply = set_network_properties(message, wpa_s, ssid, &iter); - if (reply) { + dbus_error_init(&error); + if (!set_network_properties(wpa_s, ssid, &iter, &error)) { wpa_printf(MSG_DEBUG, "wpas_dbus_handler_add_network[dbus]:" "control interface couldn't set network " "properties"); + reply = wpas_dbus_reply_new_from_error(message, &error, + DBUS_ERROR_INVALID_ARGS, + "Failed to add network"); + dbus_error_free(&error); goto err; } @@ -1493,6 +1474,70 @@ out: /** + * wpas_dbus_handler_network_reply - Reply to a NetworkRequest signal + * @message: Pointer to incoming dbus message + * @wpa_s: wpa_supplicant structure for a network interface + * Returns: NULL on success or dbus error on failure + * + * Handler function for "NetworkReply" method call of network interface. + */ +DBusMessage * wpas_dbus_handler_network_reply(DBusMessage *message, + struct wpa_supplicant *wpa_s) +{ +#ifdef IEEE8021X_EAPOL + DBusMessage *reply = NULL; + const char *op, *field, *value; + char *iface = NULL, *net_id = NULL; + int id; + struct wpa_ssid *ssid; + + if (!dbus_message_get_args(message, NULL, + DBUS_TYPE_OBJECT_PATH, &op, + DBUS_TYPE_STRING, &field, + DBUS_TYPE_STRING, &value, + DBUS_TYPE_INVALID)) + return wpas_dbus_error_invalid_args(message, NULL); + + /* Extract the network ID and ensure the network */ + /* is actually a child of this interface */ + iface = wpas_dbus_new_decompose_object_path(op, 0, &net_id, NULL); + if (iface == NULL || os_strcmp(iface, wpa_s->dbus_new_path) != 0) { + reply = wpas_dbus_error_invalid_args(message, op); + goto out; + } + + id = strtoul(net_id, NULL, 10); + if (errno == EINVAL) { + reply = wpas_dbus_error_invalid_args(message, net_id); + goto out; + } + + ssid = wpa_config_get_network(wpa_s->conf, id); + if (ssid == NULL) { + reply = wpas_dbus_error_network_unknown(message); + goto out; + } + + if (wpa_supplicant_ctrl_iface_ctrl_rsp_handle(wpa_s, ssid, + field, value) < 0) + reply = wpas_dbus_error_invalid_args(message, field); + else { + /* Tell EAP to retry immediately */ + eapol_sm_notify_ctrl_response(wpa_s->eapol); + } + +out: + os_free(iface); + os_free(net_id); + return reply; +#else /* IEEE8021X_EAPOL */ + wpa_printf(MSG_DEBUG, "CTRL_IFACE: 802.1X not included"); + return wpas_dbus_error_unknown_error(message, "802.1X not included"); +#endif /* IEEE8021X_EAPOL */ +} + + +/** * wpas_dbus_handler_add_blob - Store named binary blob (ie, for certificates) * @message: Pointer to incoming dbus message * @wpa_s: %wpa_supplicant data structure @@ -1683,32 +1728,24 @@ DBusMessage * wpas_dbus_handler_flush_bss(DBusMessage *message, /** * wpas_dbus_getter_capabilities - Return interface capabilities - * @message: Pointer to incoming dbus message - * @wpa_s: wpa_supplicant structure for a network interface - * Returns: A dbus message containing a dict of strings + * @iter: Pointer to incoming dbus message iter + * @error: Location to store error on failure + * @user_data: Function specific data + * Returns: TRUE on success, FALSE on failure * * Getter for "Capabilities" property of an interface. */ -DBusMessage * wpas_dbus_getter_capabilities(DBusMessage *message, - struct wpa_supplicant *wpa_s) +dbus_bool_t wpas_dbus_getter_capabilities(DBusMessageIter *iter, + DBusError *error, void *user_data) { - DBusMessage *reply = NULL; + struct wpa_supplicant *wpa_s = user_data; struct wpa_driver_capa capa; int res; - DBusMessageIter iter, iter_dict; - DBusMessageIter iter_dict_entry, iter_dict_val, iter_array, + DBusMessageIter iter_dict, iter_dict_entry, iter_dict_val, iter_array, variant_iter; const char *scans[] = { "active", "passive", "ssid" }; - if (message == NULL) - reply = dbus_message_new(DBUS_MESSAGE_TYPE_SIGNAL); - else - reply = dbus_message_new_method_return(message); - if (!reply) - goto nomem; - - dbus_message_iter_init_append(reply, &iter); - if (!dbus_message_iter_open_container(&iter, DBUS_TYPE_VARIANT, + if (!dbus_message_iter_open_container(iter, DBUS_TYPE_VARIANT, "a{sv}", &variant_iter)) goto nomem; @@ -2004,36 +2041,43 @@ DBusMessage * wpas_dbus_getter_capabilities(DBusMessage *message, goto nomem; /***** Modes end */ + if (res >= 0) { + dbus_int32_t max_scan_ssid = capa.max_scan_ssids; + + if (!wpa_dbus_dict_append_int32(&iter_dict, "MaxScanSSID", + max_scan_ssid)) + goto nomem; + } + if (!wpa_dbus_dict_close_write(&variant_iter, &iter_dict)) goto nomem; - if (!dbus_message_iter_close_container(&iter, &variant_iter)) + if (!dbus_message_iter_close_container(iter, &variant_iter)) goto nomem; - return reply; + return TRUE; nomem: - if (reply) - dbus_message_unref(reply); - - return dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY, NULL); + dbus_set_error_const(error, DBUS_ERROR_NO_MEMORY, "no memory"); + return FALSE; } /** * wpas_dbus_getter_state - Get interface state - * @message: Pointer to incoming dbus message - * @wpa_s: wpa_supplicant structure for a network interface - * Returns: A dbus message containing a STRING representing the current - * interface state + * @iter: Pointer to incoming dbus message iter + * @error: Location to store error on failure + * @user_data: Function specific data + * Returns: TRUE on success, FALSE on failure * * Getter for "State" property. */ -DBusMessage * wpas_dbus_getter_state(DBusMessage *message, - struct wpa_supplicant *wpa_s) +dbus_bool_t wpas_dbus_getter_state(DBusMessageIter *iter, DBusError *error, + void *user_data) { - DBusMessage *reply = NULL; + struct wpa_supplicant *wpa_s = user_data; const char *str_state; char *state_ls, *tmp; + dbus_bool_t success = FALSE; str_state = wpa_supplicant_state_txt(wpa_s->wpa_state); @@ -2041,183 +2085,204 @@ DBusMessage * wpas_dbus_getter_state(DBusMessage *message, */ state_ls = tmp = os_strdup(str_state); if (!tmp) { - return dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY, - NULL); + dbus_set_error_const(error, DBUS_ERROR_NO_MEMORY, "no memory"); + return FALSE; } while (*tmp) { *tmp = tolower(*tmp); tmp++; } - reply = wpas_dbus_simple_property_getter(message, DBUS_TYPE_STRING, - &state_ls); + success = wpas_dbus_simple_property_getter(iter, DBUS_TYPE_STRING, + &state_ls, error); os_free(state_ls); - return reply; + return success; } /** * wpas_dbus_new_iface_get_scanning - Get interface scanning state - * @message: Pointer to incoming dbus message - * @wpa_s: wpa_supplicant structure for a network interface - * Returns: A dbus message containing whether the interface is scanning + * @iter: Pointer to incoming dbus message iter + * @error: Location to store error on failure + * @user_data: Function specific data + * Returns: TRUE on success, FALSE on failure * * Getter for "scanning" property. */ -DBusMessage * wpas_dbus_getter_scanning(DBusMessage *message, - struct wpa_supplicant *wpa_s) +dbus_bool_t wpas_dbus_getter_scanning(DBusMessageIter *iter, DBusError *error, + void *user_data) { + struct wpa_supplicant *wpa_s = user_data; dbus_bool_t scanning = wpa_s->scanning ? TRUE : FALSE; - return wpas_dbus_simple_property_getter(message, DBUS_TYPE_BOOLEAN, - &scanning); + + return wpas_dbus_simple_property_getter(iter, DBUS_TYPE_BOOLEAN, + &scanning, error); } /** * wpas_dbus_getter_ap_scan - Control roaming mode - * @message: Pointer to incoming dbus message - * @wpa_s: wpa_supplicant structure for a network interface - * Returns: A message containong value of ap_scan variable + * @iter: Pointer to incoming dbus message iter + * @error: Location to store error on failure + * @user_data: Function specific data + * Returns: TRUE on success, FALSE on failure * * Getter function for "ApScan" property. */ -DBusMessage * wpas_dbus_getter_ap_scan(DBusMessage *message, - struct wpa_supplicant *wpa_s) +dbus_bool_t wpas_dbus_getter_ap_scan(DBusMessageIter *iter, DBusError *error, + void *user_data) { + struct wpa_supplicant *wpa_s = user_data; dbus_uint32_t ap_scan = wpa_s->conf->ap_scan; - return wpas_dbus_simple_property_getter(message, DBUS_TYPE_UINT32, - &ap_scan); + + return wpas_dbus_simple_property_getter(iter, DBUS_TYPE_UINT32, + &ap_scan, error); } /** * wpas_dbus_setter_ap_scan - Control roaming mode - * @message: Pointer to incoming dbus message - * @wpa_s: wpa_supplicant structure for a network interface - * Returns: NULL + * @iter: Pointer to incoming dbus message iter + * @error: Location to store error on failure + * @user_data: Function specific data + * Returns: TRUE on success, FALSE on failure * * Setter function for "ApScan" property. */ -DBusMessage * wpas_dbus_setter_ap_scan(DBusMessage *message, - struct wpa_supplicant *wpa_s) +dbus_bool_t wpas_dbus_setter_ap_scan(DBusMessageIter *iter, DBusError *error, + void *user_data) { - DBusMessage *reply = NULL; + struct wpa_supplicant *wpa_s = user_data; dbus_uint32_t ap_scan; - reply = wpas_dbus_simple_property_setter(message, DBUS_TYPE_UINT32, - &ap_scan); - if (reply) - return reply; + if (!wpas_dbus_simple_property_setter(iter, error, DBUS_TYPE_UINT32, + &ap_scan)) + return FALSE; if (wpa_supplicant_set_ap_scan(wpa_s, ap_scan)) { - return wpas_dbus_error_invalid_args( - message, "ap_scan must equal 0, 1 or 2"); + dbus_set_error_const(error, DBUS_ERROR_FAILED, + "ap_scan must be 0, 1, or 2"); + return FALSE; } - return NULL; + return TRUE; } /** * wpas_dbus_getter_bss_expire_age - Get BSS entry expiration age - * @message: Pointer to incoming dbus message - * @wpa_s: wpa_supplicant structure for a network interface - * Returns: A message containing value of bss_expiration_age variable + * @iter: Pointer to incoming dbus message iter + * @error: Location to store error on failure + * @user_data: Function specific data + * Returns: TRUE on success, FALSE on failure * * Getter function for "BSSExpireAge" property. */ -DBusMessage * wpas_dbus_getter_bss_expire_age(DBusMessage *message, - struct wpa_supplicant *wpa_s) +dbus_bool_t wpas_dbus_getter_bss_expire_age(DBusMessageIter *iter, + DBusError *error, + void *user_data) { + struct wpa_supplicant *wpa_s = user_data; dbus_uint32_t expire_age = wpa_s->conf->bss_expiration_age; - return wpas_dbus_simple_property_getter(message, DBUS_TYPE_UINT32, - &expire_age); + + return wpas_dbus_simple_property_getter(iter, DBUS_TYPE_UINT32, + &expire_age, error); } /** * wpas_dbus_setter_bss_expire_age - Control BSS entry expiration age - * @message: Pointer to incoming dbus message - * @wpa_s: wpa_supplicant structure for a network interface - * Returns: NULL + * @iter: Pointer to incoming dbus message iter + * @error: Location to store error on failure + * @user_data: Function specific data + * Returns: TRUE on success, FALSE on failure * * Setter function for "BSSExpireAge" property. */ -DBusMessage * wpas_dbus_setter_bss_expire_age(DBusMessage *message, - struct wpa_supplicant *wpa_s) +dbus_bool_t wpas_dbus_setter_bss_expire_age(DBusMessageIter *iter, + DBusError *error, + void *user_data) { - DBusMessage *reply = NULL; + struct wpa_supplicant *wpa_s = user_data; dbus_uint32_t expire_age; - reply = wpas_dbus_simple_property_setter(message, DBUS_TYPE_UINT32, - &expire_age); - if (reply) - return reply; + if (!wpas_dbus_simple_property_setter(iter, error, DBUS_TYPE_UINT32, + &expire_age)) + return FALSE; if (wpa_supplicant_set_bss_expiration_age(wpa_s, expire_age)) { - return wpas_dbus_error_invalid_args( - message, "BSSExpireAge must be >=10"); + dbus_set_error_const(error, DBUS_ERROR_FAILED, + "BSSExpireAge must be >= 10"); + return FALSE; } - return NULL; + return TRUE; } /** * wpas_dbus_getter_bss_expire_count - Get BSS entry expiration scan count - * @message: Pointer to incoming dbus message - * @wpa_s: wpa_supplicant structure for a network interface - * Returns: A message containing value of bss_expire_count variable + * @iter: Pointer to incoming dbus message iter + * @error: Location to store error on failure + * @user_data: Function specific data + * Returns: TRUE on success, FALSE on failure * * Getter function for "BSSExpireCount" property. */ -DBusMessage * wpas_dbus_getter_bss_expire_count(DBusMessage *message, - struct wpa_supplicant *wpa_s) +dbus_bool_t wpas_dbus_getter_bss_expire_count(DBusMessageIter *iter, + DBusError *error, + void *user_data) { + struct wpa_supplicant *wpa_s = user_data; dbus_uint32_t expire_count = wpa_s->conf->bss_expiration_age; - return wpas_dbus_simple_property_getter(message, DBUS_TYPE_UINT32, - &expire_count); + + return wpas_dbus_simple_property_getter(iter, DBUS_TYPE_UINT32, + &expire_count, error); } /** * wpas_dbus_setter_bss_expire_count - Control BSS entry expiration scan count - * @message: Pointer to incoming dbus message - * @wpa_s: wpa_supplicant structure for a network interface - * Returns: NULL + * @iter: Pointer to incoming dbus message iter + * @error: Location to store error on failure + * @user_data: Function specific data + * Returns: TRUE on success, FALSE on failure * * Setter function for "BSSExpireCount" property. */ -DBusMessage * wpas_dbus_setter_bss_expire_count(DBusMessage *message, - struct wpa_supplicant *wpa_s) +dbus_bool_t wpas_dbus_setter_bss_expire_count(DBusMessageIter *iter, + DBusError *error, + void *user_data) { - DBusMessage *reply = NULL; + struct wpa_supplicant *wpa_s = user_data; dbus_uint32_t expire_count; - reply = wpas_dbus_simple_property_setter(message, DBUS_TYPE_UINT32, - &expire_count); - if (reply) - return reply; + if (!wpas_dbus_simple_property_setter(iter, error, DBUS_TYPE_UINT32, + &expire_count)) + return FALSE; if (wpa_supplicant_set_bss_expiration_count(wpa_s, expire_count)) { - return wpas_dbus_error_invalid_args( - message, "BSSExpireCount must be >0"); + dbus_set_error_const(error, DBUS_ERROR_FAILED, + "BSSExpireCount must be > 0"); + return FALSE; } - return NULL; + return TRUE; } /** * wpas_dbus_getter_country - Control country code - * @message: Pointer to incoming dbus message - * @wpa_s: wpa_supplicant structure for a network interface - * Returns: A message containong value of country variable + * @iter: Pointer to incoming dbus message iter + * @error: Location to store error on failure + * @user_data: Function specific data + * Returns: TRUE on success, FALSE on failure * * Getter function for "Country" property. */ -DBusMessage * wpas_dbus_getter_country(DBusMessage *message, - struct wpa_supplicant *wpa_s) +dbus_bool_t wpas_dbus_getter_country(DBusMessageIter *iter, DBusError *error, + void *user_data) { + struct wpa_supplicant *wpa_s = user_data; char country[3]; char *str = country; @@ -2225,103 +2290,112 @@ DBusMessage * wpas_dbus_getter_country(DBusMessage *message, country[1] = wpa_s->conf->country[1]; country[2] = '\0'; - return wpas_dbus_simple_property_getter(message, DBUS_TYPE_STRING, - &str); + return wpas_dbus_simple_property_getter(iter, DBUS_TYPE_STRING, + &str, error); } /** * wpas_dbus_setter_country - Control country code - * @message: Pointer to incoming dbus message - * @wpa_s: wpa_supplicant structure for a network interface - * Returns: NULL + * @iter: Pointer to incoming dbus message iter + * @error: Location to store error on failure + * @user_data: Function specific data + * Returns: TRUE on success, FALSE on failure * * Setter function for "Country" property. */ -DBusMessage * wpas_dbus_setter_country(DBusMessage *message, - struct wpa_supplicant *wpa_s) +dbus_bool_t wpas_dbus_setter_country(DBusMessageIter *iter, DBusError *error, + void *user_data) { - DBusMessage *reply = NULL; + struct wpa_supplicant *wpa_s = user_data; const char *country; - reply = wpas_dbus_simple_property_setter(message, DBUS_TYPE_STRING, - &country); - if (reply) - return reply; + if (!wpas_dbus_simple_property_setter(iter, error, DBUS_TYPE_STRING, + &country)) + return FALSE; - if (!country[0] || !country[1]) - return wpas_dbus_error_invalid_args(message, - "invalid country code"); + if (!country[0] || !country[1]) { + dbus_set_error_const(error, DBUS_ERROR_FAILED, + "invalid country code"); + return FALSE; + } if (wpa_s->drv_priv != NULL && wpa_drv_set_country(wpa_s, country)) { wpa_printf(MSG_DEBUG, "Failed to set country"); - return wpas_dbus_error_invalid_args( - message, "failed to set country code"); + dbus_set_error_const(error, DBUS_ERROR_FAILED, + "failed to set country code"); + return FALSE; } wpa_s->conf->country[0] = country[0]; wpa_s->conf->country[1] = country[1]; - return NULL; + return TRUE; } /** * wpas_dbus_getter_ifname - Get interface name - * @message: Pointer to incoming dbus message - * @wpa_s: wpa_supplicant structure for a network interface - * Returns: A dbus message containing a name of network interface - * associated with with wpa_s + * @iter: Pointer to incoming dbus message iter + * @error: Location to store error on failure + * @user_data: Function specific data + * Returns: TRUE on success, FALSE on failure * * Getter for "Ifname" property. */ -DBusMessage * wpas_dbus_getter_ifname(DBusMessage *message, - struct wpa_supplicant *wpa_s) +dbus_bool_t wpas_dbus_getter_ifname(DBusMessageIter *iter, DBusError *error, + void *user_data) { + struct wpa_supplicant *wpa_s = user_data; const char *ifname = wpa_s->ifname; - return wpas_dbus_simple_property_getter(message, DBUS_TYPE_STRING, - &ifname); + + return wpas_dbus_simple_property_getter(iter, DBUS_TYPE_STRING, + &ifname, error); } /** * wpas_dbus_getter_driver - Get interface name - * @message: Pointer to incoming dbus message - * @wpa_s: wpa_supplicant structure for a network interface - * Returns: A dbus message containing a name of network interface - * driver associated with with wpa_s + * @iter: Pointer to incoming dbus message iter + * @error: Location to store error on failure + * @user_data: Function specific data + * Returns: TRUE on success, FALSE on failure * * Getter for "Driver" property. */ -DBusMessage * wpas_dbus_getter_driver(DBusMessage *message, - struct wpa_supplicant *wpa_s) +dbus_bool_t wpas_dbus_getter_driver(DBusMessageIter *iter, DBusError *error, + void *user_data) { + struct wpa_supplicant *wpa_s = user_data; const char *driver; if (wpa_s->driver == NULL || wpa_s->driver->name == NULL) { wpa_printf(MSG_DEBUG, "wpas_dbus_getter_driver[dbus]: " "wpa_s has no driver set"); - return wpas_dbus_error_unknown_error(message, NULL); + dbus_set_error(error, DBUS_ERROR_FAILED, "%s: no driver set", + __func__); + return FALSE; } driver = wpa_s->driver->name; - return wpas_dbus_simple_property_getter(message, DBUS_TYPE_STRING, - &driver); + return wpas_dbus_simple_property_getter(iter, DBUS_TYPE_STRING, + &driver, error); } /** * wpas_dbus_getter_current_bss - Get current bss object path - * @message: Pointer to incoming dbus message - * @wpa_s: wpa_supplicant structure for a network interface - * Returns: A dbus message containing a DBus object path to - * current BSS + * @iter: Pointer to incoming dbus message iter + * @error: Location to store error on failure + * @user_data: Function specific data + * Returns: TRUE on success, FALSE on failure * * Getter for "CurrentBSS" property. */ -DBusMessage * wpas_dbus_getter_current_bss(DBusMessage *message, - struct wpa_supplicant *wpa_s) +dbus_bool_t wpas_dbus_getter_current_bss(DBusMessageIter *iter, + DBusError *error, + void *user_data) { - DBusMessage *reply; + struct wpa_supplicant *wpa_s = user_data; char path_buf[WPAS_DBUS_OBJECT_PATH_MAX], *bss_obj_path = path_buf; if (wpa_s->current_bss) @@ -2331,27 +2405,25 @@ DBusMessage * wpas_dbus_getter_current_bss(DBusMessage *message, else os_snprintf(bss_obj_path, WPAS_DBUS_OBJECT_PATH_MAX, "/"); - reply = wpas_dbus_simple_property_getter(message, - DBUS_TYPE_OBJECT_PATH, - &bss_obj_path); - - return reply; + return wpas_dbus_simple_property_getter(iter, DBUS_TYPE_OBJECT_PATH, + &bss_obj_path, error); } /** * wpas_dbus_getter_current_network - Get current network object path - * @message: Pointer to incoming dbus message - * @wpa_s: wpa_supplicant structure for a network interface - * Returns: A dbus message containing a DBus object path to - * current network + * @iter: Pointer to incoming dbus message iter + * @error: Location to store error on failure + * @user_data: Function specific data + * Returns: TRUE on success, FALSE on failure * * Getter for "CurrentNetwork" property. */ -DBusMessage * wpas_dbus_getter_current_network(DBusMessage *message, - struct wpa_supplicant *wpa_s) +dbus_bool_t wpas_dbus_getter_current_network(DBusMessageIter *iter, + DBusError *error, + void *user_data) { - DBusMessage *reply; + struct wpa_supplicant *wpa_s = user_data; char path_buf[WPAS_DBUS_OBJECT_PATH_MAX], *net_obj_path = path_buf; if (wpa_s->current_ssid) @@ -2361,27 +2433,25 @@ DBusMessage * wpas_dbus_getter_current_network(DBusMessage *message, else os_snprintf(net_obj_path, WPAS_DBUS_OBJECT_PATH_MAX, "/"); - reply = wpas_dbus_simple_property_getter(message, - DBUS_TYPE_OBJECT_PATH, - &net_obj_path); - - return reply; + return wpas_dbus_simple_property_getter(iter, DBUS_TYPE_OBJECT_PATH, + &net_obj_path, error); } /** * wpas_dbus_getter_current_auth_mode - Get current authentication type - * @message: Pointer to incoming dbus message - * @wpa_s: wpa_supplicant structure for a network interface - * Returns: A dbus message containing a string indicating the current - * authentication type. + * @iter: Pointer to incoming dbus message iter + * @error: Location to store error on failure + * @user_data: Function specific data + * Returns: TRUE on success, FALSE on failure * * Getter for "CurrentAuthMode" property. */ -DBusMessage * wpas_dbus_getter_current_auth_mode(DBusMessage *message, - struct wpa_supplicant *wpa_s) +dbus_bool_t wpas_dbus_getter_current_auth_mode(DBusMessageIter *iter, + DBusError *error, + void *user_data) { - DBusMessage *reply; + struct wpa_supplicant *wpa_s = user_data; const char *eap_mode; const char *auth_mode; char eap_mode_buf[WPAS_DBUS_AUTH_MODE_MAX]; @@ -2400,70 +2470,61 @@ DBusMessage * wpas_dbus_getter_current_auth_mode(DBusMessage *message, wpa_s->current_ssid->proto); } - reply = wpas_dbus_simple_property_getter(message, - DBUS_TYPE_STRING, - &auth_mode); - - return reply; + return wpas_dbus_simple_property_getter(iter, DBUS_TYPE_STRING, + &auth_mode, error); } /** * wpas_dbus_getter_bridge_ifname - Get interface name - * @message: Pointer to incoming dbus message - * @wpa_s: wpa_supplicant structure for a network interface - * Returns: A dbus message containing a name of bridge network - * interface associated with with wpa_s + * @iter: Pointer to incoming dbus message iter + * @error: Location to store error on failure + * @user_data: Function specific data + * Returns: TRUE on success, FALSE on failure * * Getter for "BridgeIfname" property. */ -DBusMessage * wpas_dbus_getter_bridge_ifname(DBusMessage *message, - struct wpa_supplicant *wpa_s) +dbus_bool_t wpas_dbus_getter_bridge_ifname(DBusMessageIter *iter, + DBusError *error, + void *user_data) { - const char *bridge_ifname = NULL; - - bridge_ifname = wpa_s->bridge_ifname; - if (bridge_ifname == NULL) { - wpa_printf(MSG_ERROR, "wpas_dbus_getter_bridge_ifname[dbus]: " - "wpa_s has no bridge interface name set"); - return wpas_dbus_error_unknown_error(message, NULL); - } - - return wpas_dbus_simple_property_getter(message, DBUS_TYPE_STRING, - &bridge_ifname); + struct wpa_supplicant *wpa_s = user_data; + const char *bridge_ifname = wpa_s->bridge_ifname; + return wpas_dbus_simple_property_getter(iter, DBUS_TYPE_STRING, + &bridge_ifname, error); } /** * wpas_dbus_getter_bsss - Get array of BSSs objects - * @message: Pointer to incoming dbus message - * @wpa_s: wpa_supplicant structure for a network interface - * Returns: a dbus message containing an array of all known BSS objects - * dbus paths + * @iter: Pointer to incoming dbus message iter + * @error: Location to store error on failure + * @user_data: Function specific data + * Returns: TRUE on success, FALSE on failure * * Getter for "BSSs" property. */ -DBusMessage * wpas_dbus_getter_bsss(DBusMessage *message, - struct wpa_supplicant *wpa_s) +dbus_bool_t wpas_dbus_getter_bsss(DBusMessageIter *iter, DBusError *error, + void *user_data) { - DBusMessage *reply = NULL; + struct wpa_supplicant *wpa_s = user_data; struct wpa_bss *bss; char **paths; unsigned int i = 0; + dbus_bool_t success = FALSE; paths = os_zalloc(wpa_s->num_bss * sizeof(char *)); if (!paths) { - return dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY, - NULL); + dbus_set_error_const(error, DBUS_ERROR_NO_MEMORY, "no memory"); + return FALSE; } /* Loop through scan results and append each result's object path */ dl_list_for_each(bss, &wpa_s->bss_id, struct wpa_bss, list_id) { paths[i] = os_zalloc(WPAS_DBUS_OBJECT_PATH_MAX); if (paths[i] == NULL) { - reply = dbus_message_new_error(message, - DBUS_ERROR_NO_MEMORY, - NULL); + dbus_set_error_const(error, DBUS_ERROR_NO_MEMORY, + "no memory"); goto out; } /* Construct the object path for this BSS. */ @@ -2472,39 +2533,43 @@ DBusMessage * wpas_dbus_getter_bsss(DBusMessage *message, wpa_s->dbus_new_path, bss->id); } - reply = wpas_dbus_simple_array_property_getter(message, - DBUS_TYPE_OBJECT_PATH, - paths, wpa_s->num_bss); + success = wpas_dbus_simple_array_property_getter(iter, + DBUS_TYPE_OBJECT_PATH, + paths, wpa_s->num_bss, + error); out: while (i) os_free(paths[--i]); os_free(paths); - return reply; + return success; } /** * wpas_dbus_getter_networks - Get array of networks objects - * @message: Pointer to incoming dbus message - * @wpa_s: wpa_supplicant structure for a network interface - * Returns: a dbus message containing an array of all configured - * networks dbus object paths. + * @iter: Pointer to incoming dbus message iter + * @error: Location to store error on failure + * @user_data: Function specific data + * Returns: TRUE on success, FALSE on failure * * Getter for "Networks" property. */ -DBusMessage * wpas_dbus_getter_networks(DBusMessage *message, - struct wpa_supplicant *wpa_s) +dbus_bool_t wpas_dbus_getter_networks(DBusMessageIter *iter, DBusError *error, + void *user_data) { - DBusMessage *reply = NULL; + struct wpa_supplicant *wpa_s = user_data; struct wpa_ssid *ssid; char **paths; unsigned int i = 0, num = 0; + dbus_bool_t success = FALSE; if (wpa_s->conf == NULL) { - wpa_printf(MSG_ERROR, "wpas_dbus_getter_networks[dbus]: " - "An error occurred getting networks list."); - return wpas_dbus_error_unknown_error(message, NULL); + wpa_printf(MSG_ERROR, "%s[dbus]: An error occurred getting " + "networks list.", __func__); + dbus_set_error(error, DBUS_ERROR_FAILED, "%s: an error " + "occurred getting the networks list", __func__); + return FALSE; } for (ssid = wpa_s->conf->ssid; ssid; ssid = ssid->next) @@ -2513,8 +2578,8 @@ DBusMessage * wpas_dbus_getter_networks(DBusMessage *message, paths = os_zalloc(num * sizeof(char *)); if (!paths) { - return dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY, - NULL); + dbus_set_error(error, DBUS_ERROR_NO_MEMORY, "no memory"); + return FALSE; } /* Loop through configured networks and append object path of each */ @@ -2523,9 +2588,7 @@ DBusMessage * wpas_dbus_getter_networks(DBusMessage *message, continue; paths[i] = os_zalloc(WPAS_DBUS_OBJECT_PATH_MAX); if (paths[i] == NULL) { - reply = dbus_message_new_error(message, - DBUS_ERROR_NO_MEMORY, - NULL); + dbus_set_error(error, DBUS_ERROR_NO_MEMORY, "no memory"); goto out; } @@ -2535,50 +2598,40 @@ DBusMessage * wpas_dbus_getter_networks(DBusMessage *message, wpa_s->dbus_new_path, ssid->id); } - reply = wpas_dbus_simple_array_property_getter(message, - DBUS_TYPE_OBJECT_PATH, - paths, num); + success = wpas_dbus_simple_array_property_getter(iter, + DBUS_TYPE_OBJECT_PATH, + paths, num, error); out: while (i) os_free(paths[--i]); os_free(paths); - return reply; + return success; } /** * wpas_dbus_getter_blobs - Get all blobs defined for this interface - * @message: Pointer to incoming dbus message - * @wpa_s: wpa_supplicant structure for a network interface - * Returns: a dbus message containing a dictionary of pairs (blob_name, blob) + * @iter: Pointer to incoming dbus message iter + * @error: Location to store error on failure + * @user_data: Function specific data + * Returns: TRUE on success, FALSE on failure * * Getter for "Blobs" property. */ -DBusMessage * wpas_dbus_getter_blobs(DBusMessage *message, - struct wpa_supplicant *wpa_s) +dbus_bool_t wpas_dbus_getter_blobs(DBusMessageIter *iter, DBusError *error, + void *user_data) { - DBusMessage *reply = NULL; - DBusMessageIter iter, variant_iter, dict_iter, entry_iter, array_iter; + struct wpa_supplicant *wpa_s = user_data; + DBusMessageIter variant_iter, dict_iter, entry_iter, array_iter; struct wpa_config_blob *blob; - if (message == NULL) - reply = dbus_message_new(DBUS_MESSAGE_TYPE_SIGNAL); - else - reply = dbus_message_new_method_return(message); - if (!reply) - return dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY, - NULL); - - dbus_message_iter_init_append(reply, &iter); - - if (!dbus_message_iter_open_container(&iter, DBUS_TYPE_VARIANT, + if (!dbus_message_iter_open_container(iter, DBUS_TYPE_VARIANT, "a{say}", &variant_iter) || !dbus_message_iter_open_container(&variant_iter, DBUS_TYPE_ARRAY, "{say}", &dict_iter)) { - dbus_message_unref(reply); - return dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY, - NULL); + dbus_set_error_const(error, DBUS_ERROR_NO_MEMORY, "no memory"); + return FALSE; } blob = wpa_s->conf->blobs; @@ -2601,176 +2654,192 @@ DBusMessage * wpas_dbus_getter_blobs(DBusMessage *message, &array_iter) || !dbus_message_iter_close_container(&dict_iter, &entry_iter)) { - dbus_message_unref(reply); - return dbus_message_new_error(message, - DBUS_ERROR_NO_MEMORY, - NULL); + dbus_set_error_const(error, DBUS_ERROR_NO_MEMORY, + "no memory"); + return FALSE; } blob = blob->next; } if (!dbus_message_iter_close_container(&variant_iter, &dict_iter) || - !dbus_message_iter_close_container(&iter, &variant_iter)) { - dbus_message_unref(reply); - return dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY, - NULL); + !dbus_message_iter_close_container(iter, &variant_iter)) { + dbus_set_error_const(error, DBUS_ERROR_NO_MEMORY, "no memory"); + return FALSE; } - return reply; + return TRUE; +} + + +static struct wpa_bss * get_bss_helper(struct bss_handler_args *args, + DBusError *error, const char *func_name) +{ + struct wpa_bss *res = wpa_bss_get_id(args->wpa_s, args->id); + + if (!res) { + wpa_printf(MSG_ERROR, "%s[dbus]: no bss with id %d found", + func_name, args->id); + dbus_set_error(error, DBUS_ERROR_FAILED, + "%s: BSS %d not found", + func_name, args->id); + } + + return res; } /** * wpas_dbus_getter_bss_bssid - Return the BSSID of a BSS - * @message: Pointer to incoming dbus message - * @bss: a pair of interface describing structure and bss's id - * Returns: a dbus message containing the bssid for the requested bss + * @iter: Pointer to incoming dbus message iter + * @error: Location to store error on failure + * @user_data: Function specific data + * Returns: TRUE on success, FALSE on failure * * Getter for "BSSID" property. */ -DBusMessage * wpas_dbus_getter_bss_bssid(DBusMessage *message, - struct bss_handler_args *bss) +dbus_bool_t wpas_dbus_getter_bss_bssid(DBusMessageIter *iter, DBusError *error, + void *user_data) { - struct wpa_bss *res = wpa_bss_get_id(bss->wpa_s, bss->id); + struct bss_handler_args *args = user_data; + struct wpa_bss *res; - if (!res) { - wpa_printf(MSG_ERROR, "wpas_dbus_getter_bss_bssid[dbus]: no " - "bss with id %d found", bss->id); - return NULL; - } + res = get_bss_helper(args, error, __func__); + if (!res) + return FALSE; - return wpas_dbus_simple_array_property_getter(message, DBUS_TYPE_BYTE, - res->bssid, ETH_ALEN); + return wpas_dbus_simple_array_property_getter(iter, DBUS_TYPE_BYTE, + res->bssid, ETH_ALEN, + error); } /** * wpas_dbus_getter_bss_ssid - Return the SSID of a BSS - * @message: Pointer to incoming dbus message - * @bss: a pair of interface describing structure and bss's id - * Returns: a dbus message containing the ssid for the requested bss + * @iter: Pointer to incoming dbus message iter + * @error: Location to store error on failure + * @user_data: Function specific data + * Returns: TRUE on success, FALSE on failure * * Getter for "SSID" property. */ -DBusMessage * wpas_dbus_getter_bss_ssid(DBusMessage *message, - struct bss_handler_args *bss) +dbus_bool_t wpas_dbus_getter_bss_ssid(DBusMessageIter *iter, DBusError *error, + void *user_data) { - struct wpa_bss *res = wpa_bss_get_id(bss->wpa_s, bss->id); + struct bss_handler_args *args = user_data; + struct wpa_bss *res; - if (!res) { - wpa_printf(MSG_ERROR, "wpas_dbus_getter_bss_ssid[dbus]: no " - "bss with id %d found", bss->id); - return NULL; - } + res = get_bss_helper(args, error, __func__); + if (!res) + return FALSE; - return wpas_dbus_simple_array_property_getter(message, DBUS_TYPE_BYTE, - res->ssid, - res->ssid_len); + return wpas_dbus_simple_array_property_getter(iter, DBUS_TYPE_BYTE, + res->ssid, res->ssid_len, + error); } /** * wpas_dbus_getter_bss_privacy - Return the privacy flag of a BSS - * @message: Pointer to incoming dbus message - * @bss: a pair of interface describing structure and bss's id - * Returns: a dbus message containing the privacy flag value of requested bss + * @iter: Pointer to incoming dbus message iter + * @error: Location to store error on failure + * @user_data: Function specific data + * Returns: TRUE on success, FALSE on failure * * Getter for "Privacy" property. */ -DBusMessage * wpas_dbus_getter_bss_privacy(DBusMessage *message, - struct bss_handler_args *bss) +dbus_bool_t wpas_dbus_getter_bss_privacy(DBusMessageIter *iter, + DBusError *error, void *user_data) { - struct wpa_bss *res = wpa_bss_get_id(bss->wpa_s, bss->id); + struct bss_handler_args *args = user_data; + struct wpa_bss *res; dbus_bool_t privacy; - if (!res) { - wpa_printf(MSG_ERROR, "wpas_dbus_getter_bss_privacy[dbus]: no " - "bss with id %d found", bss->id); - return NULL; - } + res = get_bss_helper(args, error, __func__); + if (!res) + return FALSE; privacy = (res->caps & IEEE80211_CAP_PRIVACY) ? TRUE : FALSE; - return wpas_dbus_simple_property_getter(message, DBUS_TYPE_BOOLEAN, - &privacy); + return wpas_dbus_simple_property_getter(iter, DBUS_TYPE_BOOLEAN, + &privacy, error); } /** * wpas_dbus_getter_bss_mode - Return the mode of a BSS - * @message: Pointer to incoming dbus message - * @bss: a pair of interface describing structure and bss's id - * Returns: a dbus message containing the mode of requested bss + * @iter: Pointer to incoming dbus message iter + * @error: Location to store error on failure + * @user_data: Function specific data + * Returns: TRUE on success, FALSE on failure * * Getter for "Mode" property. */ -DBusMessage * wpas_dbus_getter_bss_mode(DBusMessage *message, - struct bss_handler_args *bss) +dbus_bool_t wpas_dbus_getter_bss_mode(DBusMessageIter *iter, DBusError *error, + void *user_data) { - struct wpa_bss *res = wpa_bss_get_id(bss->wpa_s, bss->id); + struct bss_handler_args *args = user_data; + struct wpa_bss *res; const char *mode; - if (!res) { - wpa_printf(MSG_ERROR, "wpas_dbus_getter_bss_mode[dbus]: no " - "bss with id %d found", bss->id); - return NULL; - } + res = get_bss_helper(args, error, __func__); + if (!res) + return FALSE; if (res->caps & IEEE80211_CAP_IBSS) mode = "ad-hoc"; else mode = "infrastructure"; - return wpas_dbus_simple_property_getter(message, DBUS_TYPE_STRING, - &mode); + return wpas_dbus_simple_property_getter(iter, DBUS_TYPE_STRING, + &mode, error); } /** * wpas_dbus_getter_bss_level - Return the signal strength of a BSS - * @message: Pointer to incoming dbus message - * @bss: a pair of interface describing structure and bss's id - * Returns: a dbus message containing the signal strength of requested bss + * @iter: Pointer to incoming dbus message iter + * @error: Location to store error on failure + * @user_data: Function specific data + * Returns: TRUE on success, FALSE on failure * * Getter for "Level" property. */ -DBusMessage * wpas_dbus_getter_bss_signal(DBusMessage *message, - struct bss_handler_args *bss) +dbus_bool_t wpas_dbus_getter_bss_signal(DBusMessageIter *iter, + DBusError *error, void *user_data) { - struct wpa_bss *res = wpa_bss_get_id(bss->wpa_s, bss->id); + struct bss_handler_args *args = user_data; + struct wpa_bss *res; - if (!res) { - wpa_printf(MSG_ERROR, "wpas_dbus_getter_bss_signal[dbus]: no " - "bss with id %d found", bss->id); - return NULL; - } + res = get_bss_helper(args, error, __func__); + if (!res) + return FALSE; - return wpas_dbus_simple_property_getter(message, DBUS_TYPE_INT16, - &res->level); + return wpas_dbus_simple_property_getter(iter, DBUS_TYPE_INT16, + &res->level, error); } /** * wpas_dbus_getter_bss_frequency - Return the frequency of a BSS - * @message: Pointer to incoming dbus message - * @bss: a pair of interface describing structure and bss's id - * Returns: a dbus message containing the frequency of requested bss + * @iter: Pointer to incoming dbus message iter + * @error: Location to store error on failure + * @user_data: Function specific data + * Returns: TRUE on success, FALSE on failure * * Getter for "Frequency" property. */ -DBusMessage * wpas_dbus_getter_bss_frequency(DBusMessage *message, - struct bss_handler_args *bss) +dbus_bool_t wpas_dbus_getter_bss_frequency(DBusMessageIter *iter, + DBusError *error, void *user_data) { - struct wpa_bss *res = wpa_bss_get_id(bss->wpa_s, bss->id); + struct bss_handler_args *args = user_data; + struct wpa_bss *res; - if (!res) { - wpa_printf(MSG_ERROR, "wpas_dbus_getter_bss_frequency[dbus]: " - "no bss with id %d found", bss->id); - return NULL; - } + res = get_bss_helper(args, error, __func__); + if (!res) + return FALSE; - return wpas_dbus_simple_property_getter(message, DBUS_TYPE_UINT16, - &res->freq); + return wpas_dbus_simple_property_getter(iter, DBUS_TYPE_UINT16, + &res->freq, error); } @@ -2782,72 +2851,64 @@ static int cmp_u8s_desc(const void *a, const void *b) /** * wpas_dbus_getter_bss_rates - Return available bit rates of a BSS - * @message: Pointer to incoming dbus message - * @bss: a pair of interface describing structure and bss's id - * Returns: a dbus message containing sorted array of bit rates + * @iter: Pointer to incoming dbus message iter + * @error: Location to store error on failure + * @user_data: Function specific data + * Returns: TRUE on success, FALSE on failure * * Getter for "Rates" property. */ -DBusMessage * wpas_dbus_getter_bss_rates(DBusMessage *message, - struct bss_handler_args *bss) +dbus_bool_t wpas_dbus_getter_bss_rates(DBusMessageIter *iter, + DBusError *error, void *user_data) { - DBusMessage *reply; - struct wpa_bss *res = wpa_bss_get_id(bss->wpa_s, bss->id); + struct bss_handler_args *args = user_data; + struct wpa_bss *res; u8 *ie_rates = NULL; u32 *real_rates; int rates_num, i; + dbus_bool_t success = FALSE; - if (!res) { - wpa_printf(MSG_ERROR, "wpas_dbus_getter_bss_rates[dbus]: " - "no bss with id %d found", bss->id); - return NULL; - } + res = get_bss_helper(args, error, __func__); + if (!res) + return FALSE; rates_num = wpa_bss_get_bit_rates(res, &ie_rates); if (rates_num < 0) - return NULL; + return FALSE; qsort(ie_rates, rates_num, 1, cmp_u8s_desc); real_rates = os_malloc(sizeof(u32) * rates_num); if (!real_rates) { os_free(ie_rates); - return dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY, - NULL); + dbus_set_error_const(error, DBUS_ERROR_NO_MEMORY, "no memory"); + return FALSE; } for (i = 0; i < rates_num; i++) real_rates[i] = ie_rates[i] * 500000; - reply = wpas_dbus_simple_array_property_getter(message, - DBUS_TYPE_UINT32, - real_rates, rates_num); + success = wpas_dbus_simple_array_property_getter(iter, DBUS_TYPE_UINT32, + real_rates, rates_num, + error); os_free(ie_rates); os_free(real_rates); - return reply; + return success; } -static DBusMessage * wpas_dbus_get_bss_security_prop( - DBusMessage *message, struct wpa_ie_data *ie_data) +static dbus_bool_t wpas_dbus_get_bss_security_prop(DBusMessageIter *iter, + struct wpa_ie_data *ie_data, + DBusError *error) { - DBusMessage *reply; - DBusMessageIter iter, iter_dict, variant_iter; + DBusMessageIter iter_dict, variant_iter; const char *group; const char *pairwise[2]; /* max 2 pairwise ciphers is supported */ const char *key_mgmt[7]; /* max 7 key managements may be supported */ int n; - if (message == NULL) - reply = dbus_message_new(DBUS_MESSAGE_TYPE_SIGNAL); - else - reply = dbus_message_new_method_return(message); - if (!reply) - goto nomem; - - dbus_message_iter_init_append(reply, &iter); - if (!dbus_message_iter_open_container(&iter, DBUS_TYPE_VARIANT, + if (!dbus_message_iter_open_container(iter, DBUS_TYPE_VARIANT, "a{sv}", &variant_iter)) goto nomem; @@ -2928,152 +2989,152 @@ static DBusMessage * wpas_dbus_get_bss_security_prop( if (!wpa_dbus_dict_close_write(&variant_iter, &iter_dict)) goto nomem; - if (!dbus_message_iter_close_container(&iter, &variant_iter)) + if (!dbus_message_iter_close_container(iter, &variant_iter)) goto nomem; - return reply; + return TRUE; nomem: - if (reply) - dbus_message_unref(reply); - - return dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY, NULL); + dbus_set_error_const(error, DBUS_ERROR_NO_MEMORY, "no memory"); + return FALSE; } /** * wpas_dbus_getter_bss_wpa - Return the WPA options of a BSS - * @message: Pointer to incoming dbus message - * @bss: a pair of interface describing structure and bss's id - * Returns: a dbus message containing the WPA options of requested bss + * @iter: Pointer to incoming dbus message iter + * @error: Location to store error on failure + * @user_data: Function specific data + * Returns: TRUE on success, FALSE on failure * * Getter for "WPA" property. */ -DBusMessage * wpas_dbus_getter_bss_wpa(DBusMessage *message, - struct bss_handler_args *bss) +dbus_bool_t wpas_dbus_getter_bss_wpa(DBusMessageIter *iter, DBusError *error, + void *user_data) { - struct wpa_bss *res = wpa_bss_get_id(bss->wpa_s, bss->id); + struct bss_handler_args *args = user_data; + struct wpa_bss *res; struct wpa_ie_data wpa_data; const u8 *ie; - if (!res) { - wpa_printf(MSG_ERROR, "wpas_dbus_getter_bss_wpa[dbus]: no " - "bss with id %d found", bss->id); - return NULL; - } + res = get_bss_helper(args, error, __func__); + if (!res) + return FALSE; os_memset(&wpa_data, 0, sizeof(wpa_data)); ie = wpa_bss_get_vendor_ie(res, WPA_IE_VENDOR_TYPE); if (ie) { - if (wpa_parse_wpa_ie(ie, 2 + ie[1], &wpa_data) < 0) - return wpas_dbus_error_unknown_error(message, - "invalid WPA IE"); + if (wpa_parse_wpa_ie(ie, 2 + ie[1], &wpa_data) < 0) { + dbus_set_error_const(error, DBUS_ERROR_FAILED, + "failed to parse WPA IE"); + return FALSE; + } } - return wpas_dbus_get_bss_security_prop(message, &wpa_data); + return wpas_dbus_get_bss_security_prop(iter, &wpa_data, error); } /** * wpas_dbus_getter_bss_rsn - Return the RSN options of a BSS - * @message: Pointer to incoming dbus message - * @bss: a pair of interface describing structure and bss's id - * Returns: a dbus message containing the RSN options of requested bss + * @iter: Pointer to incoming dbus message iter + * @error: Location to store error on failure + * @user_data: Function specific data + * Returns: TRUE on success, FALSE on failure * * Getter for "RSN" property. */ -DBusMessage * wpas_dbus_getter_bss_rsn(DBusMessage *message, - struct bss_handler_args *bss) +dbus_bool_t wpas_dbus_getter_bss_rsn(DBusMessageIter *iter, DBusError *error, + void *user_data) { - struct wpa_bss *res = wpa_bss_get_id(bss->wpa_s, bss->id); + struct bss_handler_args *args = user_data; + struct wpa_bss *res; struct wpa_ie_data wpa_data; const u8 *ie; - if (!res) { - wpa_printf(MSG_ERROR, "wpas_dbus_getter_bss_rsn[dbus]: no " - "bss with id %d found", bss->id); - return NULL; - } + res = get_bss_helper(args, error, __func__); + if (!res) + return FALSE; os_memset(&wpa_data, 0, sizeof(wpa_data)); ie = wpa_bss_get_ie(res, WLAN_EID_RSN); if (ie) { - if (wpa_parse_wpa_ie(ie, 2 + ie[1], &wpa_data) < 0) - return wpas_dbus_error_unknown_error(message, - "invalid RSN IE"); + if (wpa_parse_wpa_ie(ie, 2 + ie[1], &wpa_data) < 0) { + dbus_set_error_const(error, DBUS_ERROR_FAILED, + "failed to parse RSN IE"); + return FALSE; + } } - return wpas_dbus_get_bss_security_prop(message, &wpa_data); + return wpas_dbus_get_bss_security_prop(iter, &wpa_data, error); } /** * wpas_dbus_getter_bss_ies - Return all IEs of a BSS - * @message: Pointer to incoming dbus message - * @bss: a pair of interface describing structure and bss's id - * Returns: a dbus message containing IEs byte array + * @iter: Pointer to incoming dbus message iter + * @error: Location to store error on failure + * @user_data: Function specific data + * Returns: TRUE on success, FALSE on failure * * Getter for "IEs" property. */ -DBusMessage * wpas_dbus_getter_bss_ies(DBusMessage *message, - struct bss_handler_args *bss) +dbus_bool_t wpas_dbus_getter_bss_ies(DBusMessageIter *iter, DBusError *error, + void *user_data) { - struct wpa_bss *res = wpa_bss_get_id(bss->wpa_s, bss->id); + struct bss_handler_args *args = user_data; + struct wpa_bss *res; - if (!res) { - wpa_printf(MSG_ERROR, "wpas_dbus_getter_bss_ies[dbus]: no " - "bss with id %d found", bss->id); - return NULL; - } + res = get_bss_helper(args, error, __func__); + if (!res) + return FALSE; - return wpas_dbus_simple_array_property_getter(message, DBUS_TYPE_BYTE, - res + 1, res->ie_len); + return wpas_dbus_simple_array_property_getter(iter, DBUS_TYPE_BYTE, + res + 1, res->ie_len, + error); } /** * wpas_dbus_getter_enabled - Check whether network is enabled or disabled - * @message: Pointer to incoming dbus message - * @wpas_dbus_setter_enabled: wpa_supplicant structure for a network interface - * and wpa_ssid structure for a configured network - * Returns: DBus message with boolean indicating state of configured network - * or DBus error on failure + * @iter: Pointer to incoming dbus message iter + * @error: Location to store error on failure + * @user_data: Function specific data + * Returns: TRUE on success, FALSE on failure * * Getter for "enabled" property of a configured network. */ -DBusMessage * wpas_dbus_getter_enabled(DBusMessage *message, - struct network_handler_args *net) +dbus_bool_t wpas_dbus_getter_enabled(DBusMessageIter *iter, DBusError *error, + void *user_data) { + struct network_handler_args *net = user_data; dbus_bool_t enabled = net->ssid->disabled ? FALSE : TRUE; - return wpas_dbus_simple_property_getter(message, DBUS_TYPE_BOOLEAN, - &enabled); + + return wpas_dbus_simple_property_getter(iter, DBUS_TYPE_BOOLEAN, + &enabled, error); } /** * wpas_dbus_setter_enabled - Mark a configured network as enabled or disabled - * @message: Pointer to incoming dbus message - * @wpas_dbus_setter_enabled: wpa_supplicant structure for a network interface - * and wpa_ssid structure for a configured network - * Returns: NULL indicating success or DBus error on failure + * @iter: Pointer to incoming dbus message iter + * @error: Location to store error on failure + * @user_data: Function specific data + * Returns: TRUE on success, FALSE on failure * * Setter for "Enabled" property of a configured network. */ -DBusMessage * wpas_dbus_setter_enabled(DBusMessage *message, - struct network_handler_args *net) +dbus_bool_t wpas_dbus_setter_enabled(DBusMessageIter *iter, DBusError *error, + void *user_data) { - DBusMessage *reply = NULL; - + struct network_handler_args *net = user_data; struct wpa_supplicant *wpa_s; struct wpa_ssid *ssid; - dbus_bool_t enable; - reply = wpas_dbus_simple_property_setter(message, DBUS_TYPE_BOOLEAN, - &enable); - - if (reply) - return reply; + if (!wpas_dbus_simple_property_setter(iter, error, DBUS_TYPE_BOOLEAN, + &enable)) + return FALSE; wpa_s = net->wpa_s; ssid = net->ssid; @@ -3083,48 +3144,38 @@ DBusMessage * wpas_dbus_setter_enabled(DBusMessage *message, else wpa_supplicant_disable_network(wpa_s, ssid); - return NULL; + return TRUE; } /** * wpas_dbus_getter_network_properties - Get options for a configured network - * @message: Pointer to incoming dbus message - * @net: wpa_supplicant structure for a network interface and - * wpa_ssid structure for a configured network - * Returns: DBus message with network properties or DBus error on failure + * @iter: Pointer to incoming dbus message iter + * @error: Location to store error on failure + * @user_data: Function specific data + * Returns: TRUE on success, FALSE on failure * * Getter for "Properties" property of a configured network. */ -DBusMessage * wpas_dbus_getter_network_properties( - DBusMessage *message, struct network_handler_args *net) +dbus_bool_t wpas_dbus_getter_network_properties(DBusMessageIter *iter, + DBusError *error, + void *user_data) { - DBusMessage *reply = NULL; - DBusMessageIter iter, variant_iter, dict_iter; + struct network_handler_args *net = user_data; + DBusMessageIter variant_iter, dict_iter; char **iterator; char **props = wpa_config_get_all(net->ssid, 1); - if (!props) - return dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY, - NULL); + dbus_bool_t success = FALSE; - if (message == NULL) - reply = dbus_message_new(DBUS_MESSAGE_TYPE_SIGNAL); - else - reply = dbus_message_new_method_return(message); - if (!reply) { - reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY, - NULL); - goto out; + if (!props) { + dbus_set_error_const(error, DBUS_ERROR_NO_MEMORY, "no memory"); + return FALSE; } - dbus_message_iter_init_append(reply, &iter); - - if (!dbus_message_iter_open_container(&iter, DBUS_TYPE_VARIANT, - "a{sv}", &variant_iter) || + if (!dbus_message_iter_open_container(iter, DBUS_TYPE_VARIANT, "a{sv}", + &variant_iter) || !wpa_dbus_dict_open_write(&variant_iter, &dict_iter)) { - dbus_message_unref(reply); - reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY, - NULL); + dbus_set_error_const(error, DBUS_ERROR_NO_MEMORY, "no memory"); goto out; } @@ -3132,10 +3183,8 @@ DBusMessage * wpas_dbus_getter_network_properties( while (*iterator) { if (!wpa_dbus_dict_append_string(&dict_iter, *iterator, *(iterator + 1))) { - dbus_message_unref(reply); - reply = dbus_message_new_error(message, - DBUS_ERROR_NO_MEMORY, - NULL); + dbus_set_error_const(error, DBUS_ERROR_NO_MEMORY, + "no memory"); goto out; } iterator += 2; @@ -3143,13 +3192,13 @@ DBusMessage * wpas_dbus_getter_network_properties( if (!wpa_dbus_dict_close_write(&variant_iter, &dict_iter) || - !dbus_message_iter_close_container(&iter, &variant_iter)) { - dbus_message_unref(reply); - reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY, - NULL); + !dbus_message_iter_close_container(iter, &variant_iter)) { + dbus_set_error_const(error, DBUS_ERROR_NO_MEMORY, "no memory"); goto out; } + success = TRUE; + out: iterator = props; while (*iterator) { @@ -3157,39 +3206,27 @@ out: iterator++; } os_free(props); - return reply; + return success; } /** * wpas_dbus_setter_network_properties - Set options for a configured network - * @message: Pointer to incoming dbus message - * @net: wpa_supplicant structure for a network interface and - * wpa_ssid structure for a configured network - * Returns: NULL indicating success or DBus error on failure + * @iter: Pointer to incoming dbus message iter + * @error: Location to store error on failure + * @user_data: Function specific data + * Returns: TRUE on success, FALSE on failure * * Setter for "Properties" property of a configured network. */ -DBusMessage * wpas_dbus_setter_network_properties( - DBusMessage *message, struct network_handler_args *net) +dbus_bool_t wpas_dbus_setter_network_properties(DBusMessageIter *iter, + DBusError *error, + void *user_data) { + struct network_handler_args *net = user_data; struct wpa_ssid *ssid = net->ssid; + DBusMessageIter variant_iter; - DBusMessage *reply = NULL; - DBusMessageIter iter, variant_iter; - - dbus_message_iter_init(message, &iter); - - dbus_message_iter_next(&iter); - dbus_message_iter_next(&iter); - - dbus_message_iter_recurse(&iter, &variant_iter); - - reply = set_network_properties(message, net->wpa_s, ssid, - &variant_iter); - if (reply) - wpa_printf(MSG_DEBUG, "dbus control interface couldn't set " - "network properties"); - - return reply; + dbus_message_iter_recurse(iter, &variant_iter); + return set_network_properties(net->wpa_s, ssid, &variant_iter, error); } diff --git a/wpa_supplicant/dbus/dbus_new_handlers.h b/wpa_supplicant/dbus/dbus_new_handlers.h index 978ee4c..ac3af1f 100644 --- a/wpa_supplicant/dbus/dbus_new_handlers.h +++ b/wpa_supplicant/dbus/dbus_new_handlers.h @@ -26,17 +26,20 @@ struct bss_handler_args { unsigned int id; }; -DBusMessage * wpas_dbus_simple_property_getter(DBusMessage *message, - const int type, - const void *val); +dbus_bool_t wpas_dbus_simple_property_getter(DBusMessageIter *iter, + const int type, + const void *val, + DBusError *error); -DBusMessage * wpas_dbus_simple_property_setter(DBusMessage *message, - const int type, void *val); +dbus_bool_t wpas_dbus_simple_property_setter(DBusMessageIter *iter, + DBusError *error, + const int type, void *val); -DBusMessage * wpas_dbus_simple_array_property_getter(DBusMessage *message, - const int type, - const void *array, - size_t array_len); +dbus_bool_t wpas_dbus_simple_array_property_getter(DBusMessageIter *iter, + const int type, + const void *array, + size_t array_len, + DBusError *error); DBusMessage * wpas_dbus_handler_create_interface(DBusMessage *message, struct wpa_global *global); @@ -47,29 +50,35 @@ DBusMessage * wpas_dbus_handler_remove_interface(DBusMessage *message, DBusMessage * wpas_dbus_handler_get_interface(DBusMessage *message, struct wpa_global *global); -DBusMessage * wpas_dbus_getter_debug_level(DBusMessage *message, - struct wpa_global *global); +dbus_bool_t wpas_dbus_getter_debug_level(DBusMessageIter *iter, + DBusError *error, + void *user_data); -DBusMessage * wpas_dbus_getter_debug_timestamp(DBusMessage *message, - struct wpa_global *global); +dbus_bool_t wpas_dbus_getter_debug_timestamp(DBusMessageIter *iter, + DBusError *error, + void *user_data); -DBusMessage * wpas_dbus_getter_debug_show_keys(DBusMessage *message, - struct wpa_global *global); +dbus_bool_t wpas_dbus_getter_debug_show_keys(DBusMessageIter *iter, + DBusError *error, + void *user_data); -DBusMessage * wpas_dbus_setter_debug_level(DBusMessage *message, - struct wpa_global *global); +dbus_bool_t wpas_dbus_setter_debug_level(DBusMessageIter *iter, + DBusError *error, void *user_data); -DBusMessage * wpas_dbus_setter_debug_timestamp(DBusMessage *message, - struct wpa_global *global); +dbus_bool_t wpas_dbus_setter_debug_timestamp(DBusMessageIter *iter, + DBusError *error, + void *user_data); -DBusMessage * wpas_dbus_setter_debug_show_keys(DBusMessage *message, - struct wpa_global *global); +dbus_bool_t wpas_dbus_setter_debug_show_keys(DBusMessageIter *iter, + DBusError *error, + void *user_data); -DBusMessage * wpas_dbus_getter_interfaces(DBusMessage *message, - struct wpa_global *global); +dbus_bool_t wpas_dbus_getter_interfaces(DBusMessageIter *iter, + DBusError *error, + void *user_data); -DBusMessage * wpas_dbus_getter_eap_methods(DBusMessage *message, - void *nothing); +dbus_bool_t wpas_dbus_getter_eap_methods(DBusMessageIter *iter, + DBusError *error, void *user_data); DBusMessage * wpas_dbus_handler_scan(DBusMessage *message, struct wpa_supplicant *wpa_s); @@ -77,10 +86,10 @@ DBusMessage * wpas_dbus_handler_scan(DBusMessage *message, DBusMessage * wpas_dbus_handler_disconnect(DBusMessage *message, struct wpa_supplicant *wpa_s); -DBusMessage * set_network_properties(DBusMessage *message, - struct wpa_supplicant *wpa_s, - struct wpa_ssid *ssid, - DBusMessageIter *iter); +dbus_bool_t set_network_properties(struct wpa_supplicant *wpa_s, + struct wpa_ssid *ssid, + DBusMessageIter *iter, + DBusError *error); DBusMessage * wpas_dbus_handler_add_network(DBusMessage *message, struct wpa_supplicant *wpa_s); @@ -94,6 +103,9 @@ DBusMessage * wpas_dbus_handler_remove_all_networks( DBusMessage * wpas_dbus_handler_select_network(DBusMessage *message, struct wpa_supplicant *wpa_s); +DBusMessage * wpas_dbus_handler_network_reply(DBusMessage *message, + struct wpa_supplicant *wpa_s); + DBusMessage * wpas_dbus_handler_add_blob(DBusMessage *message, struct wpa_supplicant *wpa_s); @@ -106,119 +118,126 @@ DBusMessage * wpas_dbus_handler_remove_blob(DBusMessage *message, DBusMessage * wpas_dbus_handler_flush_bss(DBusMessage *message, struct wpa_supplicant *wpa_s); -DBusMessage * wpas_dbus_getter_capabilities(DBusMessage *message, - struct wpa_supplicant *wpa_s); +dbus_bool_t wpas_dbus_getter_capabilities(DBusMessageIter *iter, + DBusError *error, void *user_data); -DBusMessage * wpas_dbus_getter_state(DBusMessage *message, - struct wpa_supplicant *wpa_s); +dbus_bool_t wpas_dbus_getter_state(DBusMessageIter *iter, DBusError *error, + void *user_data); -DBusMessage * wpas_dbus_getter_scanning(DBusMessage *message, - struct wpa_supplicant *wpa_s); +dbus_bool_t wpas_dbus_getter_scanning(DBusMessageIter *iter, DBusError *error, + void *user_data); -DBusMessage * wpas_dbus_getter_ap_scan(DBusMessage *message, - struct wpa_supplicant *wpa_s); +dbus_bool_t wpas_dbus_getter_ap_scan(DBusMessageIter *iter, DBusError *error, + void *user_data); -DBusMessage * wpas_dbus_setter_ap_scan(DBusMessage *message, - struct wpa_supplicant *wpa_s); +dbus_bool_t wpas_dbus_setter_ap_scan(DBusMessageIter *iter, DBusError *error, + void *user_data); -DBusMessage * wpas_dbus_getter_bss_expire_age(DBusMessage *message, - struct wpa_supplicant *wpa_s); +dbus_bool_t wpas_dbus_getter_bss_expire_age(DBusMessageIter *iter, + DBusError *error, void *user_data); -DBusMessage * wpas_dbus_setter_bss_expire_age(DBusMessage *message, - struct wpa_supplicant *wpa_s); +dbus_bool_t wpas_dbus_setter_bss_expire_age(DBusMessageIter *iter, + DBusError *error, + void *user_data); -DBusMessage * wpas_dbus_getter_bss_expire_count(DBusMessage *message, - struct wpa_supplicant *wpa_s); +dbus_bool_t wpas_dbus_getter_bss_expire_count(DBusMessageIter *iter, + DBusError *error, + void *user_data); -DBusMessage * wpas_dbus_setter_bss_expire_count(DBusMessage *message, - struct wpa_supplicant *wpa_s); +dbus_bool_t wpas_dbus_setter_bss_expire_count(DBusMessageIter *iter, + DBusError *error, + void *user_data); -DBusMessage * wpas_dbus_getter_country(DBusMessage *message, - struct wpa_supplicant *wpa_s); +dbus_bool_t wpas_dbus_getter_country(DBusMessageIter *iter, DBusError *error, + void *user_data); -DBusMessage * wpas_dbus_setter_country(DBusMessage *message, - struct wpa_supplicant *wpa_s); +dbus_bool_t wpas_dbus_setter_country(DBusMessageIter *iter, DBusError *error, + void *user_data); -DBusMessage * wpas_dbus_getter_ifname(DBusMessage *message, - struct wpa_supplicant *wpa_s); +dbus_bool_t wpas_dbus_getter_ifname(DBusMessageIter *iter, DBusError *error, + void *user_data); -DBusMessage * wpas_dbus_getter_driver(DBusMessage *message, - struct wpa_supplicant *wpa_s); +dbus_bool_t wpas_dbus_getter_driver(DBusMessageIter *iter, DBusError *error, + void *user_data); -DBusMessage * wpas_dbus_getter_bridge_ifname(DBusMessage *message, - struct wpa_supplicant *wpa_s); +dbus_bool_t wpas_dbus_getter_bridge_ifname(DBusMessageIter *iter, + DBusError *error, + void *user_data); -DBusMessage * wpas_dbus_getter_current_bss(DBusMessage *message, - struct wpa_supplicant *wpa_s); +dbus_bool_t wpas_dbus_getter_current_bss(DBusMessageIter *iter, + DBusError *error, + void *user_data); -DBusMessage * wpas_dbus_getter_current_network(DBusMessage *message, - struct wpa_supplicant *wpa_s); +dbus_bool_t wpas_dbus_getter_current_network(DBusMessageIter *iter, + DBusError *error, + void *user_data); -DBusMessage * wpas_dbus_getter_current_auth_mode(DBusMessage *message, - struct wpa_supplicant *wpa_s); +dbus_bool_t wpas_dbus_getter_current_auth_mode(DBusMessageIter *iter, + DBusError *error, + void *user_data); -DBusMessage * wpas_dbus_getter_bsss(DBusMessage *message, - struct wpa_supplicant *wpa_s); +dbus_bool_t wpas_dbus_getter_bsss(DBusMessageIter *iter, DBusError *error, + void *user_data); -DBusMessage * wpas_dbus_getter_networks(DBusMessage *message, - struct wpa_supplicant *wpa_s); +dbus_bool_t wpas_dbus_getter_networks(DBusMessageIter *iter, DBusError *error, + void *user_data); -DBusMessage * wpas_dbus_getter_blobs(DBusMessage *message, - struct wpa_supplicant *bss); +dbus_bool_t wpas_dbus_getter_blobs(DBusMessageIter *iter, DBusError *error, + void *user_data); -DBusMessage * wpas_dbus_getter_bss_bssid(DBusMessage *message, - struct bss_handler_args *bss); +dbus_bool_t wpas_dbus_getter_bss_bssid(DBusMessageIter *iter, DBusError *error, + void *user_data); -DBusMessage * wpas_dbus_getter_bss_ssid(DBusMessage *message, - struct bss_handler_args *bss); +dbus_bool_t wpas_dbus_getter_bss_ssid(DBusMessageIter *iter, DBusError *error, + void *user_data); -DBusMessage * wpas_dbus_getter_bss_privacy(DBusMessage *message, - struct bss_handler_args *bss); +dbus_bool_t wpas_dbus_getter_bss_privacy(DBusMessageIter *iter, + DBusError *error, void *user_data); -DBusMessage * wpas_dbus_getter_bss_mode(DBusMessage *message, - struct bss_handler_args *bss); +dbus_bool_t wpas_dbus_getter_bss_mode(DBusMessageIter *iter, DBusError *error, + void *user_data); -DBusMessage * wpas_dbus_getter_bss_signal(DBusMessage *message, - struct bss_handler_args *bss); +dbus_bool_t wpas_dbus_getter_bss_signal(DBusMessageIter *iter, + DBusError *error, void *user_data); -DBusMessage * wpas_dbus_getter_bss_frequency(DBusMessage *message, - struct bss_handler_args *bss); +dbus_bool_t wpas_dbus_getter_bss_frequency(DBusMessageIter *iter, + DBusError *error, void *user_data); -DBusMessage * wpas_dbus_getter_bss_rates(DBusMessage *message, - struct bss_handler_args *bss); +dbus_bool_t wpas_dbus_getter_bss_rates(DBusMessageIter *iter, + DBusError *error, void *user_data); -DBusMessage * wpas_dbus_getter_bss_wpa(DBusMessage *message, - struct bss_handler_args *bss); +dbus_bool_t wpas_dbus_getter_bss_wpa(DBusMessageIter *iter, DBusError *error, + void *user_data); -DBusMessage * wpas_dbus_getter_bss_rsn(DBusMessage *message, - struct bss_handler_args *bss); +dbus_bool_t wpas_dbus_getter_bss_rsn(DBusMessageIter *iter, DBusError *error, + void *user_data); -DBusMessage * wpas_dbus_getter_bss_ies(DBusMessage *message, - struct bss_handler_args *bss); +dbus_bool_t wpas_dbus_getter_bss_ies(DBusMessageIter *iter, DBusError *error, + void *user_data); -DBusMessage * wpas_dbus_getter_enabled(DBusMessage *message, - struct network_handler_args *net); +dbus_bool_t wpas_dbus_getter_enabled(DBusMessageIter *iter, DBusError *error, + void *user_data); -DBusMessage * wpas_dbus_setter_enabled(DBusMessage *message, - struct network_handler_args *net); +dbus_bool_t wpas_dbus_setter_enabled(DBusMessageIter *iter, DBusError *error, + void *user_data); -DBusMessage * wpas_dbus_getter_network_properties( - DBusMessage *message, struct network_handler_args *net); +dbus_bool_t wpas_dbus_getter_network_properties(DBusMessageIter *iter, + DBusError *error, + void *user_data); -DBusMessage * wpas_dbus_setter_network_properties( - DBusMessage *message, struct network_handler_args *net); +dbus_bool_t wpas_dbus_setter_network_properties(DBusMessageIter *iter, + DBusError *error, + void *user_data); DBusMessage * wpas_dbus_handler_wps_start(DBusMessage *message, struct wpa_supplicant *wpa_s); -DBusMessage * wpas_dbus_getter_process_credentials( - DBusMessage *message, struct wpa_supplicant *wpa_s); - -DBusMessage * wpas_dbus_setter_process_credentials( - DBusMessage *message, struct wpa_supplicant *wpa_s); +dbus_bool_t wpas_dbus_getter_process_credentials(DBusMessageIter *iter, + DBusError *error, void *user_data); -DBusMessage * wpas_dbus_getter_credentials(DBusMessage *message, - struct wpa_supplicant *wpa_s); +dbus_bool_t wpas_dbus_setter_process_credentials(DBusMessageIter *iter, + DBusError *error, + void *user_data); DBusMessage * wpas_dbus_error_invalid_args(DBusMessage *message, const char *arg); diff --git a/wpa_supplicant/dbus/dbus_new_handlers_p2p.c b/wpa_supplicant/dbus/dbus_new_handlers_p2p.c index 55482b4..671d0e5 100644 --- a/wpa_supplicant/dbus/dbus_new_handlers_p2p.c +++ b/wpa_supplicant/dbus/dbus_new_handlers_p2p.c @@ -70,23 +70,23 @@ static DBusMessage * wpas_dbus_error_persistent_group_unknown( } -DBusMessage *wpas_dbus_handler_p2p_find(DBusMessage * message, - struct wpa_supplicant * wpa_s) +DBusMessage * wpas_dbus_handler_p2p_find(DBusMessage *message, + struct wpa_supplicant *wpa_s) { struct wpa_dbus_dict_entry entry; DBusMessage *reply = NULL; DBusMessageIter iter; DBusMessageIter iter_dict; unsigned int timeout = 0; - unsigned int searchonly = 0; enum p2p_discovery_type type = P2P_FIND_ONLY_SOCIAL; int num_req_dev_types = 0; unsigned int i; u8 *req_dev_types = NULL; dbus_message_iter_init(message, &iter); + entry.key = NULL; - if (!wpa_dbus_dict_open_read(&iter, &iter_dict)) + if (!wpa_dbus_dict_open_read(&iter, &iter_dict, NULL)) goto error; while (wpa_dbus_dict_has_dict_entry(&iter_dict)) { @@ -96,14 +96,12 @@ DBusMessage *wpas_dbus_handler_p2p_find(DBusMessage * message, if (!os_strcmp(entry.key, "Timeout") && (entry.type == DBUS_TYPE_INT32)) { timeout = entry.uint32_value; - } else if (!os_strcmp(entry.key, "SearchOnly") && - (entry.type == DBUS_TYPE_BOOLEAN)) { - searchonly = (entry.bool_value == TRUE) ? 1 : 0; } else if (os_strcmp(entry.key, "RequestedDeviceTypes") == 0) { if ((entry.type != DBUS_TYPE_ARRAY) || (entry.array_type != WPAS_DBUS_TYPE_BINARRAY)) goto error_clear; + os_free(req_dev_types); req_dev_types = os_malloc(WPS_DEV_TYPE_LEN * entry.array_len); if (!req_dev_types) @@ -117,33 +115,45 @@ DBusMessage *wpas_dbus_handler_p2p_find(DBusMessage * message, wpabuf_head(entry.binarray_value[i]), WPS_DEV_TYPE_LEN); } - num_req_dev_types = entry.array_len; + } else if (!os_strcmp(entry.key, "DiscoveryType") && + (entry.type == DBUS_TYPE_STRING)) { + if (!os_strcmp(entry.str_value, "start_with_full")) + type = P2P_FIND_START_WITH_FULL; + else if (!os_strcmp(entry.str_value, "social")) + type = P2P_FIND_ONLY_SOCIAL; + else if (!os_strcmp(entry.str_value, "progressive")) + type = P2P_FIND_PROGRESSIVE; + else + goto error_clear; } else goto error_clear; wpa_dbus_dict_entry_clear(&entry); } wpas_p2p_find(wpa_s, timeout, type, num_req_dev_types, req_dev_types); + os_free(req_dev_types); return reply; error_clear: - os_free(req_dev_types); wpa_dbus_dict_entry_clear(&entry); error: + os_free(req_dev_types); reply = wpas_dbus_error_invalid_args(message, entry.key); return reply; } -DBusMessage *wpas_dbus_handler_p2p_stop_find(DBusMessage * message, - struct wpa_supplicant * wpa_s) + +DBusMessage * wpas_dbus_handler_p2p_stop_find(DBusMessage *message, + struct wpa_supplicant *wpa_s) { wpas_p2p_stop_find(wpa_s); return NULL; } -DBusMessage *wpas_dbus_handler_p2p_rejectpeer(DBusMessage * message, - struct wpa_supplicant * wpa_s) + +DBusMessage * wpas_dbus_handler_p2p_rejectpeer(DBusMessage *message, + struct wpa_supplicant *wpa_s) { DBusMessageIter iter; char *peer_object_path = NULL; @@ -162,8 +172,9 @@ DBusMessage *wpas_dbus_handler_p2p_rejectpeer(DBusMessage * message, return NULL; } -DBusMessage *wpas_dbus_handler_p2p_listen(DBusMessage * message, - struct wpa_supplicant * wpa_s) + +DBusMessage * wpas_dbus_handler_p2p_listen(DBusMessage *message, + struct wpa_supplicant *wpa_s) { dbus_int32_t timeout = 0; @@ -179,8 +190,9 @@ DBusMessage *wpas_dbus_handler_p2p_listen(DBusMessage * message, return NULL; } -DBusMessage *wpas_dbus_handler_p2p_extendedlisten(DBusMessage * message, - struct wpa_supplicant * wpa_s) + +DBusMessage * wpas_dbus_handler_p2p_extendedlisten( + DBusMessage *message, struct wpa_supplicant *wpa_s) { unsigned int period = 0, interval = 0; struct wpa_dbus_dict_entry entry; @@ -188,18 +200,19 @@ DBusMessage *wpas_dbus_handler_p2p_extendedlisten(DBusMessage * message, DBusMessageIter iter_dict; dbus_message_iter_init(message, &iter); + entry.key = NULL; - if (!wpa_dbus_dict_open_read(&iter, &iter_dict)) + if (!wpa_dbus_dict_open_read(&iter, &iter_dict, NULL)) goto error; while (wpa_dbus_dict_has_dict_entry(&iter_dict)) { if (!wpa_dbus_dict_get_entry(&iter_dict, &entry)) goto error; - if (!strcmp(entry.key, "period") && + if (!os_strcmp(entry.key, "period") && (entry.type == DBUS_TYPE_INT32)) period = entry.uint32_value; - else if (!strcmp(entry.key, "interval") && + else if (!os_strcmp(entry.key, "interval") && (entry.type == DBUS_TYPE_INT32)) interval = entry.uint32_value; else @@ -208,8 +221,8 @@ DBusMessage *wpas_dbus_handler_p2p_extendedlisten(DBusMessage * message, } if (wpas_p2p_ext_listen(wpa_s, period, interval)) - return wpas_dbus_error_unknown_error(message, - "failed to initiate a p2p_ext_listen."); + return wpas_dbus_error_unknown_error( + message, "failed to initiate a p2p_ext_listen."); return NULL; @@ -219,9 +232,9 @@ error: return wpas_dbus_error_invalid_args(message, entry.key); } -DBusMessage *wpas_dbus_handler_p2p_presence_request(DBusMessage * message, - struct wpa_supplicant * - wpa_s) + +DBusMessage * wpas_dbus_handler_p2p_presence_request( + DBusMessage *message, struct wpa_supplicant *wpa_s) { unsigned int dur1 = 0, int1 = 0, dur2 = 0, int2 = 0; struct wpa_dbus_dict_entry entry; @@ -229,24 +242,25 @@ DBusMessage *wpas_dbus_handler_p2p_presence_request(DBusMessage * message, DBusMessageIter iter_dict; dbus_message_iter_init(message, &iter); + entry.key = NULL; - if (!wpa_dbus_dict_open_read(&iter, &iter_dict)) + if (!wpa_dbus_dict_open_read(&iter, &iter_dict, NULL)) goto error; while (wpa_dbus_dict_has_dict_entry(&iter_dict)) { if (!wpa_dbus_dict_get_entry(&iter_dict, &entry)) goto error; - if (!strcmp(entry.key, "duration1") && + if (!os_strcmp(entry.key, "duration1") && (entry.type == DBUS_TYPE_INT32)) dur1 = entry.uint32_value; - else if (!strcmp(entry.key, "interval1") && + else if (!os_strcmp(entry.key, "interval1") && entry.type == DBUS_TYPE_INT32) int1 = entry.uint32_value; - else if (!strcmp(entry.key, "duration2") && + else if (!os_strcmp(entry.key, "duration2") && entry.type == DBUS_TYPE_INT32) dur2 = entry.uint32_value; - else if (!strcmp(entry.key, "interval2") && + else if (!os_strcmp(entry.key, "interval2") && entry.type == DBUS_TYPE_INT32) int2 = entry.uint32_value; else @@ -266,8 +280,9 @@ error: return wpas_dbus_error_invalid_args(message, entry.key); } -DBusMessage *wpas_dbus_handler_p2p_group_add(DBusMessage * message, - struct wpa_supplicant * wpa_s) + +DBusMessage * wpas_dbus_handler_p2p_group_add(DBusMessage *message, + struct wpa_supplicant *wpa_s) { DBusMessageIter iter_dict; DBusMessage *reply = NULL; @@ -283,22 +298,22 @@ DBusMessage *wpas_dbus_handler_p2p_group_add(DBusMessage * message, dbus_message_iter_init(message, &iter); - if (!wpa_dbus_dict_open_read(&iter, &iter_dict)) + if (!wpa_dbus_dict_open_read(&iter, &iter_dict, NULL)) goto inv_args; while (wpa_dbus_dict_has_dict_entry(&iter_dict)) { if (!wpa_dbus_dict_get_entry(&iter_dict, &entry)) goto inv_args; - if (!strcmp(entry.key, "persistent") && + if (!os_strcmp(entry.key, "persistent") && (entry.type == DBUS_TYPE_BOOLEAN)) { persistent_group = (entry.bool_value == TRUE) ? 1 : 0; - } else if (!strcmp(entry.key, "frequency") && + } else if (!os_strcmp(entry.key, "frequency") && (entry.type == DBUS_TYPE_INT32)) { freq = entry.int32_value; if (freq <= 0) goto inv_args_clear; - } else if (!strcmp(entry.key, "persistent_group_object") && + } else if (!os_strcmp(entry.key, "persistent_group_object") && entry.type == DBUS_TYPE_OBJECT_PATH) pg_object_path = os_strdup(entry.str_value); else @@ -330,14 +345,15 @@ DBusMessage *wpas_dbus_handler_p2p_group_add(DBusMessage * message, goto out; } - /* Get the SSID structure form the persistant group id */ + /* Get the SSID structure from the persistent group id */ ssid = wpa_config_get_network(wpa_s->conf, group_id); if (ssid == NULL || ssid->disabled != 2) goto inv_args; if (wpas_p2p_group_add_persistent(wpa_s, ssid, 0, freq)) { - reply = wpas_dbus_error_unknown_error(message, - "Failed to reinvoke a persistent group"); + reply = wpas_dbus_error_unknown_error( + message, + "Failed to reinvoke a persistent group"); goto out; } } else if (wpas_p2p_group_add(wpa_s, persistent_group, freq)) @@ -355,8 +371,9 @@ inv_args: goto out; } -DBusMessage *wpas_dbus_handler_p2p_disconnect(DBusMessage *message, - struct wpa_supplicant *wpa_s) + +DBusMessage * wpas_dbus_handler_p2p_disconnect(DBusMessage *message, + struct wpa_supplicant *wpa_s) { if (wpas_p2p_disconnect(wpa_s)) return wpas_dbus_error_unknown_error(message, @@ -365,9 +382,36 @@ DBusMessage *wpas_dbus_handler_p2p_disconnect(DBusMessage *message, return NULL; } -DBusMessage *wpas_dbus_handler_p2p_flush(DBusMessage * message, - struct wpa_supplicant * wpa_s) + +static dbus_bool_t wpa_dbus_p2p_check_enabled(struct wpa_supplicant *wpa_s, + DBusMessage *message, + DBusMessage **out_reply, + DBusError *error) { + /* Return an error message or an error if P2P isn't available */ + if (wpa_s->global->p2p_disabled || wpa_s->global->p2p == NULL) { + if (out_reply) { + *out_reply = dbus_message_new_error( + message, DBUS_ERROR_FAILED, + "P2P is not available for this interface"); + } + dbus_set_error_const(error, DBUS_ERROR_FAILED, + "P2P is not available for this " + "interface"); + return FALSE; + } + return TRUE; +} + + +DBusMessage * wpas_dbus_handler_p2p_flush(DBusMessage *message, + struct wpa_supplicant *wpa_s) +{ + DBusMessage *reply = NULL; + + if (!wpa_dbus_p2p_check_enabled(wpa_s, message, &reply, NULL)) + return reply; + os_memset(wpa_s->p2p_auth_invite, 0, ETH_ALEN); wpa_s->force_long_sd = 0; p2p_flush(wpa_s->global->p2p); @@ -375,8 +419,9 @@ DBusMessage *wpas_dbus_handler_p2p_flush(DBusMessage * message, return NULL; } -DBusMessage *wpas_dbus_handler_p2p_connect(DBusMessage * message, - struct wpa_supplicant * wpa_s) + +DBusMessage * wpas_dbus_handler_p2p_connect(DBusMessage *message, + struct wpa_supplicant *wpa_s) { DBusMessageIter iter_dict; DBusMessage *reply = NULL; @@ -395,52 +440,53 @@ DBusMessage *wpas_dbus_handler_p2p_connect(DBusMessage * message, char *err_msg = NULL; char *iface = NULL; + if (!wpa_dbus_p2p_check_enabled(wpa_s, message, &reply, NULL)) + return reply; + dbus_message_iter_init(message, &iter); - if (!wpa_dbus_dict_open_read(&iter, &iter_dict)) + if (!wpa_dbus_dict_open_read(&iter, &iter_dict, NULL)) goto inv_args; while (wpa_dbus_dict_has_dict_entry(&iter_dict)) { if (!wpa_dbus_dict_get_entry(&iter_dict, &entry)) goto inv_args; - if (!strcmp(entry.key, "peer") && + if (!os_strcmp(entry.key, "peer") && (entry.type == DBUS_TYPE_OBJECT_PATH)) { peer_object_path = os_strdup(entry.str_value); - } else if (!strcmp(entry.key, "persistent") && + } else if (!os_strcmp(entry.key, "persistent") && (entry.type == DBUS_TYPE_BOOLEAN)) { persistent_group = (entry.bool_value == TRUE) ? 1 : 0; - } else if (!strcmp(entry.key, "join") && + } else if (!os_strcmp(entry.key, "join") && (entry.type == DBUS_TYPE_BOOLEAN)) { join = (entry.bool_value == TRUE) ? 1 : 0; - } else if (!strcmp(entry.key, "authorize_only") && + } else if (!os_strcmp(entry.key, "authorize_only") && (entry.type == DBUS_TYPE_BOOLEAN)) { authorize_only = (entry.bool_value == TRUE) ? 1 : 0; - } else if (!strcmp(entry.key, "frequency") && + } else if (!os_strcmp(entry.key, "frequency") && (entry.type == DBUS_TYPE_INT32)) { freq = entry.int32_value; if (freq <= 0) goto inv_args_clear; - } else if (!strcmp(entry.key, "go_intent") && + } else if (!os_strcmp(entry.key, "go_intent") && (entry.type == DBUS_TYPE_INT32)) { go_intent = entry.int32_value; if ((go_intent < 0) || (go_intent > 15)) goto inv_args_clear; - } else if (!strcmp(entry.key, "wps_method") && + } else if (!os_strcmp(entry.key, "wps_method") && (entry.type == DBUS_TYPE_STRING)) { - if (!strcmp(entry.str_value, "pbc")) + if (!os_strcmp(entry.str_value, "pbc")) wps_method = WPS_PBC; - else if (!strcmp(entry.str_value, "pin")) + else if (!os_strcmp(entry.str_value, "pin")) wps_method = WPS_PIN_DISPLAY; - else if (!strcmp(entry.str_value, "label")) - wps_method = WPS_PIN_LABEL; - else if (!strcmp(entry.str_value, "display")) + else if (!os_strcmp(entry.str_value, "display")) wps_method = WPS_PIN_DISPLAY; - else if (!strcmp(entry.str_value, "keypad")) + else if (!os_strcmp(entry.str_value, "keypad")) wps_method = WPS_PIN_KEYPAD; else goto inv_args_clear; - } else if (!strcmp(entry.key, "pin") && + } else if (!os_strcmp(entry.key, "pin") && (entry.type == DBUS_TYPE_STRING)) { pin = os_strdup(entry.str_value); } else @@ -451,16 +497,13 @@ DBusMessage *wpas_dbus_handler_p2p_connect(DBusMessage * message, if (!peer_object_path || (wps_method == WPS_NOT_READY) || (parse_peer_object_path(peer_object_path, addr) < 0) || - (p2p_get_peer_info(wpa_s->global->p2p, addr, 0, NULL, 0) < 0)) { - reply = wpas_dbus_error_invalid_args(message, NULL); + !p2p_peer_known(wpa_s->global->p2p, addr)) goto inv_args; - } /* * Validate the wps_method specified and the pin value. */ - if ((!pin || !pin[0]) && - ((wps_method == WPS_PIN_LABEL) || (wps_method == WPS_PIN_KEYPAD))) + if ((!pin || !pin[0]) && (wps_method == WPS_PIN_KEYPAD)) goto inv_args; new_pin = wpas_p2p_connect(wpa_s, addr, pin, wps_method, @@ -468,31 +511,34 @@ DBusMessage *wpas_dbus_handler_p2p_connect(DBusMessage * message, go_intent, freq); if (new_pin >= 0) { + char npin[9]; + char *generated_pin; + os_snprintf(npin, sizeof(npin), "%08d", new_pin); + generated_pin = npin; reply = dbus_message_new_method_return(message); - dbus_message_append_args(reply, DBUS_TYPE_INT32, - &new_pin, DBUS_TYPE_INVALID); + dbus_message_append_args(reply, DBUS_TYPE_STRING, + &generated_pin, DBUS_TYPE_INVALID); } else { switch (new_pin) { case -2: - err_msg = "connect failed due to" - " channel unavailability."; + err_msg = "connect failed due to channel " + "unavailability."; iface = WPAS_DBUS_ERROR_CONNECT_CHANNEL_UNAVAILABLE; break; case -3: - err_msg = "connect failed due to" - " unsupported channel."; + err_msg = "connect failed due to unsupported channel."; iface = WPAS_DBUS_ERROR_CONNECT_CHANNEL_UNSUPPORTED; break; default: - err_msg = "connect failed due to" - " unspecified error."; + err_msg = "connect failed due to unspecified error."; iface = WPAS_DBUS_ERROR_CONNECT_UNSPECIFIED_ERROR; break; } + /* - * TODO:: + * TODO: * Do we need specialized errors corresponding to above * error conditions as against just returning a different * error message? @@ -511,8 +557,9 @@ inv_args: goto out; } -DBusMessage *wpas_dbus_handler_p2p_invite(DBusMessage * message, - struct wpa_supplicant *wpa_s) + +DBusMessage * wpas_dbus_handler_p2p_invite(DBusMessage *message, + struct wpa_supplicant *wpa_s) { DBusMessageIter iter_dict; DBusMessage *reply = NULL; @@ -527,20 +574,23 @@ DBusMessage *wpas_dbus_handler_p2p_invite(DBusMessage * message, int persistent = 0; struct wpa_ssid *ssid; + if (!wpa_dbus_p2p_check_enabled(wpa_s, message, &reply, NULL)) + return reply; + dbus_message_iter_init(message, &iter); - if (!wpa_dbus_dict_open_read(&iter, &iter_dict)) + if (!wpa_dbus_dict_open_read(&iter, &iter_dict, NULL)) goto err; while (wpa_dbus_dict_has_dict_entry(&iter_dict)) { if (!wpa_dbus_dict_get_entry(&iter_dict, &entry)) goto err; - if (!strcmp(entry.key, "peer") && + if (!os_strcmp(entry.key, "peer") && (entry.type == DBUS_TYPE_OBJECT_PATH)) { peer_object_path = os_strdup(entry.str_value); wpa_dbus_dict_entry_clear(&entry); - } else if (!strcmp(entry.key, "persistent_group_object") && + } else if (!os_strcmp(entry.key, "persistent_group_object") && (entry.type == DBUS_TYPE_OBJECT_PATH)) { pg_object_path = os_strdup(entry.str_value); persistent = 1; @@ -553,43 +603,41 @@ DBusMessage *wpas_dbus_handler_p2p_invite(DBusMessage * message, if (!peer_object_path || (parse_peer_object_path(peer_object_path, peer_addr) < 0) || - (p2p_get_peer_info(wpa_s->global->p2p, - peer_addr, 0, NULL, 0) < 0)) { + !p2p_peer_known(wpa_s->global->p2p, peer_addr)) { goto err; } if (persistent) { /* * A group ID is defined meaning we want to re-invoke a - * persisatnt group + * persistent group */ iface = wpas_dbus_new_decompose_object_path(pg_object_path, 1, &net_id_str, NULL); if (iface == NULL || os_strcmp(iface, wpa_s->dbus_new_path) != 0) { - reply = - wpas_dbus_error_invalid_args(message, - pg_object_path); + reply = wpas_dbus_error_invalid_args(message, + pg_object_path); goto out; } group_id = strtoul(net_id_str, NULL, 10); if (errno == EINVAL) { reply = wpas_dbus_error_invalid_args( - message, pg_object_path); + message, pg_object_path); goto out; } - /* Get the SSID structure form the persistant group id */ + /* Get the SSID structure from the persistent group id */ ssid = wpa_config_get_network(wpa_s->conf, group_id); if (ssid == NULL || ssid->disabled != 2) goto err; if (wpas_p2p_invite(wpa_s, peer_addr, ssid, NULL) < 0) { reply = wpas_dbus_error_unknown_error( - message, - "Failed to reinvoke a persistent group"); + message, + "Failed to reinvoke a persistent group"); goto out; } } else { @@ -597,10 +645,9 @@ DBusMessage *wpas_dbus_handler_p2p_invite(DBusMessage * message, * No group ID means propose to a peer to join my active group */ if (wpas_p2p_invite_group(wpa_s, wpa_s->ifname, - peer_addr, NULL)) { + peer_addr, NULL)) { reply = wpas_dbus_error_unknown_error( - message, - "Failed to join to an active group"); + message, "Failed to join to an active group"); goto out; } } @@ -615,8 +662,9 @@ err: goto out; } -DBusMessage *wpas_dbus_handler_p2p_prov_disc_req(DBusMessage * message, - struct wpa_supplicant *wpa_s) + +DBusMessage * wpas_dbus_handler_p2p_prov_disc_req(DBusMessage *message, + struct wpa_supplicant *wpa_s) { DBusMessageIter iter; char *peer_object_path = NULL; @@ -643,23 +691,24 @@ DBusMessage *wpas_dbus_handler_p2p_prov_disc_req(DBusMessage * message, os_strcmp(config_method, "pushbutton")) return wpas_dbus_error_invalid_args(message, NULL); - if (wpas_p2p_prov_disc(wpa_s, peer_addr, config_method) < 0) + if (wpas_p2p_prov_disc(wpa_s, peer_addr, config_method, 0) < 0) return wpas_dbus_error_unknown_error(message, "Failed to send provision discovery request"); return NULL; } + /* * P2P Device property accessor methods. */ -DBusMessage *wpas_dbus_getter_p2p_device_properties(DBusMessage * message, - struct wpa_supplicant * - wpa_s) +dbus_bool_t wpas_dbus_getter_p2p_device_properties(DBusMessageIter *iter, + DBusError *error, + void *user_data) { - DBusMessage *reply = NULL; - DBusMessageIter iter, variant_iter, dict_iter; + struct wpa_supplicant *wpa_s = user_data; + DBusMessageIter variant_iter, dict_iter; DBusMessageIter iter_secdev_dict_entry, iter_secdev_dict_val, iter_secdev_dict_array; const char *dev_name; @@ -667,17 +716,10 @@ DBusMessage *wpas_dbus_getter_p2p_device_properties(DBusMessage * message, int i; const struct wpabuf *vendor_ext[P2P_MAX_WPS_VENDOR_EXT]; - if (message == NULL) - reply = dbus_message_new(DBUS_MESSAGE_TYPE_SIGNAL); - else - reply = dbus_message_new_method_return(message); + if (!wpa_dbus_p2p_check_enabled(wpa_s, NULL, NULL, error)) + return FALSE; - if (!reply) - goto err_no_mem; - - dbus_message_iter_init_append(reply, &iter); - - if (!dbus_message_iter_open_container(&iter, DBUS_TYPE_VARIANT, + if (!dbus_message_iter_open_container(iter, DBUS_TYPE_VARIANT, "a{sv}", &variant_iter) || !wpa_dbus_dict_open_write(&variant_iter, &dict_iter)) goto err_no_mem; @@ -738,7 +780,7 @@ DBusMessage *wpas_dbus_getter_p2p_device_properties(DBusMessage * message, wpa_s->conf->p2p_go_intent)) goto err_no_mem; - /* Persistant Reconnect */ + /* Persistent Reconnect */ if (!wpa_dbus_dict_append_bool(&dict_iter, "PersistantReconnect", wpa_s->conf->persistent_reconnect)) goto err_no_mem; @@ -785,44 +827,45 @@ DBusMessage *wpas_dbus_getter_p2p_device_properties(DBusMessage * message, goto err_no_mem; if (!wpa_dbus_dict_close_write(&variant_iter, &dict_iter) || - !dbus_message_iter_close_container(&iter, &variant_iter)) + !dbus_message_iter_close_container(iter, &variant_iter)) goto err_no_mem; - return reply; + return TRUE; + err_no_mem: - dbus_message_unref(reply); - return dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY, NULL); + dbus_set_error_const(error, DBUS_ERROR_NO_MEMORY, "no memory"); + return FALSE; } -DBusMessage *wpas_dbus_setter_p2p_device_properties(DBusMessage * message, - struct wpa_supplicant * - wpa_s) + +dbus_bool_t wpas_dbus_setter_p2p_device_properties(DBusMessageIter *iter, + DBusError *error, + void *user_data) { - DBusMessage *reply = NULL; - DBusMessageIter iter, variant_iter; + struct wpa_supplicant *wpa_s = user_data; + DBusMessageIter variant_iter, iter_dict; struct wpa_dbus_dict_entry entry = {.type = DBUS_TYPE_STRING }; - DBusMessageIter iter_dict; unsigned int i; - dbus_message_iter_init(message, &iter); - - dbus_message_iter_next(&iter); - dbus_message_iter_next(&iter); + if (!wpa_dbus_p2p_check_enabled(wpa_s, NULL, NULL, error)) + return FALSE; - dbus_message_iter_recurse(&iter, &variant_iter); - - if (!wpa_dbus_dict_open_read(&variant_iter, &iter_dict)) - return wpas_dbus_error_invalid_args(message, NULL); + dbus_message_iter_recurse(iter, &variant_iter); + if (!wpa_dbus_dict_open_read(&variant_iter, &iter_dict, error)) + return FALSE; while (wpa_dbus_dict_has_dict_entry(&iter_dict)) { - if (!wpa_dbus_dict_get_entry(&iter_dict, &entry)) - return wpas_dbus_error_invalid_args(message, NULL); + if (!wpa_dbus_dict_get_entry(&iter_dict, &entry)) { + dbus_set_error_const(error, DBUS_ERROR_INVALID_ARGS, + "invalid message format"); + return FALSE; + } if (os_strcmp(entry.key, "DeviceName") == 0) { char *devname; if (entry.type != DBUS_TYPE_STRING) - goto error_clear; + goto error; devname = os_strdup(entry.str_value); if (devname == NULL) @@ -832,12 +875,12 @@ DBusMessage *wpas_dbus_setter_p2p_device_properties(DBusMessage * message, wpa_s->conf->device_name = devname; wpa_s->conf->changed_parameters |= - CFG_CHANGED_DEVICE_NAME; + CFG_CHANGED_DEVICE_NAME; } else if (os_strcmp(entry.key, "PrimaryDeviceType") == 0) { if (entry.type != DBUS_TYPE_ARRAY || entry.array_type != DBUS_TYPE_BYTE || entry.array_len != WPS_DEV_TYPE_LEN) - goto error_clear; + goto error; os_memcpy(wpa_s->conf->device_type, entry.bytearray_value, @@ -851,7 +894,8 @@ DBusMessage *wpas_dbus_setter_p2p_device_properties(DBusMessage * message, goto error; for (i = 0; i < entry.array_len; i++) - if (wpabuf_len(entry.binarray_value[i]) != WPS_DEV_TYPE_LEN) + if (wpabuf_len(entry.binarray_value[i]) != + WPS_DEV_TYPE_LEN) goto err_no_mem_clear; for (i = 0; i < entry.array_len; i++) os_memcpy(wpa_s->conf->sec_device_type[i], @@ -864,10 +908,10 @@ DBusMessage *wpas_dbus_setter_p2p_device_properties(DBusMessage * message, if ((entry.type != DBUS_TYPE_ARRAY) || (entry.array_type != WPAS_DBUS_TYPE_BINARRAY) || (entry.array_len > P2P_MAX_WPS_VENDOR_EXT)) - goto error_clear; + goto error; wpa_s->conf->changed_parameters |= - CFG_CHANGED_VENDOR_EXTENSION; + CFG_CHANGED_VENDOR_EXTENSION; for (i = 0; i < P2P_MAX_WPS_VENDOR_EXT; i++) { wpabuf_free(wpa_s->conf->wps_vendor_ext[i]); @@ -882,11 +926,9 @@ DBusMessage *wpas_dbus_setter_p2p_device_properties(DBusMessage * message, (entry.type == DBUS_TYPE_UINT32) && (entry.uint32_value <= 15)) wpa_s->conf->p2p_go_intent = entry.uint32_value; - else if ((os_strcmp(entry.key, "PersistantReconnect") == 0) && (entry.type == DBUS_TYPE_BOOLEAN)) wpa_s->conf->persistent_reconnect = entry.bool_value; - else if ((os_strcmp(entry.key, "ListenRegClass") == 0) && (entry.type == DBUS_TYPE_UINT32)) { wpa_s->conf->p2p_listen_reg_class = entry.uint32_value; @@ -911,7 +953,7 @@ DBusMessage *wpas_dbus_setter_p2p_device_properties(DBusMessage * message, char *postfix; if (entry.type != DBUS_TYPE_STRING) - goto error_clear; + goto error; postfix = os_strdup(entry.str_value); if (!postfix) @@ -926,7 +968,7 @@ DBusMessage *wpas_dbus_setter_p2p_device_properties(DBusMessage * message, (entry.type == DBUS_TYPE_BOOLEAN)) { wpa_s->conf->p2p_intra_bss = entry.bool_value; wpa_s->conf->changed_parameters |= - CFG_CHANGED_P2P_INTRA_BSS; + CFG_CHANGED_P2P_INTRA_BSS; } else if ((os_strcmp(entry.key, "GroupIdle") == 0) && (entry.type == DBUS_TYPE_UINT32)) wpa_s->conf->p2p_group_idle = entry.uint32_value; @@ -934,7 +976,7 @@ DBusMessage *wpas_dbus_setter_p2p_device_properties(DBusMessage * message, entry.type == DBUS_TYPE_UINT32) wpa_s->conf->disassoc_low_ack = entry.uint32_value; else - goto error_clear; + goto error; wpa_dbus_dict_entry_clear(&entry); } @@ -944,29 +986,31 @@ DBusMessage *wpas_dbus_setter_p2p_device_properties(DBusMessage * message, wpa_supplicant_update_config(wpa_s); } - return reply; + return TRUE; - error_clear: - wpa_dbus_dict_entry_clear(&entry); error: - reply = wpas_dbus_error_invalid_args(message, entry.key); + dbus_set_error_const(error, DBUS_ERROR_INVALID_ARGS, + "invalid message format"); wpa_dbus_dict_entry_clear(&entry); + return FALSE; - return reply; err_no_mem_clear: + dbus_set_error_const(error, DBUS_ERROR_NO_MEMORY, "no memory"); wpa_dbus_dict_entry_clear(&entry); - return dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY, NULL); + return FALSE; } -DBusMessage *wpas_dbus_getter_p2p_peers(DBusMessage * message, - struct wpa_supplicant * wpa_s) + +dbus_bool_t wpas_dbus_getter_p2p_peers(DBusMessageIter *iter, DBusError *error, + void *user_data) { - DBusMessage *reply = NULL; + struct wpa_supplicant *wpa_s = user_data; struct p2p_data *p2p = wpa_s->global->p2p; int next = 0, i = 0; int num = 0, out_of_mem = 0; const u8 *addr; const struct p2p_peer_info *peer_info = NULL; + dbus_bool_t success = FALSE; struct dl_list peer_objpath_list; struct peer_objpath_node { @@ -976,6 +1020,9 @@ DBusMessage *wpas_dbus_getter_p2p_peers(DBusMessage * message, char **peer_obj_paths = NULL; + if (!wpa_dbus_p2p_check_enabled(wpa_s, NULL, NULL, error)) + return FALSE; + dl_list_init(&peer_objpath_list); /* Get the first peer info */ @@ -1016,9 +1063,10 @@ DBusMessage *wpas_dbus_getter_p2p_peers(DBusMessage * message, struct peer_objpath_node, list) peer_obj_paths[i++] = node->path; - reply = wpas_dbus_simple_array_property_getter(message, - DBUS_TYPE_OBJECT_PATH, - peer_obj_paths, num); + success = wpas_dbus_simple_array_property_getter(iter, + DBUS_TYPE_OBJECT_PATH, + peer_obj_paths, num, + error); error: if (peer_obj_paths) @@ -1030,12 +1078,12 @@ error: os_free(node); } if (out_of_mem) - reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY, - NULL); + dbus_set_error_const(error, DBUS_ERROR_NO_MEMORY, "no memory"); - return reply; + return success; } + enum wpas_p2p_role { WPAS_P2P_ROLE_DEVICE, WPAS_P2P_ROLE_GO, @@ -1064,9 +1112,11 @@ static enum wpas_p2p_role wpas_get_p2p_role(struct wpa_supplicant *wpa_s) } } -DBusMessage *wpas_dbus_getter_p2p_role(DBusMessage * message, - struct wpa_supplicant * wpa_s) + +dbus_bool_t wpas_dbus_getter_p2p_role(DBusMessageIter *iter, DBusError *error, + void *user_data) { + struct wpa_supplicant *wpa_s = user_data; char *str; switch (wpas_get_p2p_role(wpa_s)) { @@ -1080,83 +1130,85 @@ DBusMessage *wpas_dbus_getter_p2p_role(DBusMessage * message, str = "device"; } - return wpas_dbus_simple_property_getter(message, DBUS_TYPE_STRING, - &str); + return wpas_dbus_simple_property_getter(iter, DBUS_TYPE_STRING, &str, + error); } -DBusMessage *wpas_dbus_getter_p2p_group(DBusMessage * message, - struct wpa_supplicant * wpa_s) + +dbus_bool_t wpas_dbus_getter_p2p_group(DBusMessageIter *iter, DBusError *error, + void *user_data) { + struct wpa_supplicant *wpa_s = user_data; + if (wpa_s->dbus_groupobj_path == NULL) - return NULL; + return FALSE; - return wpas_dbus_simple_property_getter(message, - DBUS_TYPE_OBJECT_PATH, - &wpa_s->dbus_groupobj_path); + return wpas_dbus_simple_property_getter(iter, DBUS_TYPE_OBJECT_PATH, + &wpa_s->dbus_groupobj_path, + error); } -DBusMessage *wpas_dbus_getter_p2p_peergo(DBusMessage * message, - struct wpa_supplicant * wpa_s) + +dbus_bool_t wpas_dbus_getter_p2p_peergo(DBusMessageIter *iter, + DBusError *error, void *user_data) { + struct wpa_supplicant *wpa_s = user_data; char go_peer_obj_path[WPAS_DBUS_OBJECT_PATH_MAX], *path; if (wpas_get_p2p_role(wpa_s) != WPAS_P2P_ROLE_CLIENT) - return NULL; + return FALSE; os_snprintf(go_peer_obj_path, WPAS_DBUS_OBJECT_PATH_MAX, "%s/" WPAS_DBUS_NEW_P2P_PEERS_PART "/" COMPACT_MACSTR, wpa_s->dbus_new_path, MAC2STR(wpa_s->go_dev_addr)); path = go_peer_obj_path; - return wpas_dbus_simple_property_getter(message, - DBUS_TYPE_OBJECT_PATH, &path); + return wpas_dbus_simple_property_getter(iter, DBUS_TYPE_OBJECT_PATH, + &path, error); } + /* * Peer object properties accessor methods */ -DBusMessage *wpas_dbus_getter_p2p_peer_properties(DBusMessage * message, - struct peer_handler_args * - peer_args) +dbus_bool_t wpas_dbus_getter_p2p_peer_properties(DBusMessageIter *iter, + DBusError *error, void *user_data) { - DBusMessage *reply = NULL; - DBusMessageIter iter, variant_iter, dict_iter; + struct peer_handler_args *peer_args = user_data; + DBusMessageIter variant_iter, dict_iter; const struct p2p_peer_info *info = NULL; - char devtype[WPS_DEV_TYPE_BUFSIZE]; + const struct wpabuf *vendor_extension[P2P_MAX_WPS_VENDOR_EXT]; + int i, num; + + if (!wpa_dbus_p2p_check_enabled(peer_args->wpa_s, NULL, NULL, error)) + return FALSE; /* get the peer info */ info = p2p_get_peer_found(peer_args->wpa_s->global->p2p, peer_args->p2p_device_addr, 0); - if (info == NULL) - return NULL; - - if (message == NULL) - reply = dbus_message_new(DBUS_MESSAGE_TYPE_SIGNAL); - else - reply = dbus_message_new_method_return(message); - - if (!reply) - goto err_no_mem; + if (info == NULL) { + dbus_set_error(error, DBUS_ERROR_FAILED, "failed to find peer"); + return FALSE; + } - dbus_message_iter_init_append(reply, &iter); - if (!dbus_message_iter_open_container(&iter, DBUS_TYPE_VARIANT, + if (!dbus_message_iter_open_container(iter, DBUS_TYPE_VARIANT, "a{sv}", &variant_iter) || !wpa_dbus_dict_open_write(&variant_iter, &dict_iter)) goto err_no_mem; /* Fill out the dictionary */ - wps_dev_type_bin2str(info->pri_dev_type, devtype, sizeof(devtype)); if (!wpa_dbus_dict_append_string(&dict_iter, "DeviceName", info->device_name)) goto err_no_mem; - if (!wpa_dbus_dict_append_string(&dict_iter, "PrimaryDeviceType", - devtype)) + if (!wpa_dbus_dict_append_byte_array(&dict_iter, "PrimaryDeviceType", + (char *)info->pri_dev_type, + WPS_DEV_TYPE_LEN)) goto err_no_mem; if (!wpa_dbus_dict_append_uint16(&dict_iter, "config_method", info->config_methods)) goto err_no_mem; if (!wpa_dbus_dict_append_int32(&dict_iter, "level", - info->level)) + info->level)) goto err_no_mem; if (!wpa_dbus_dict_append_byte(&dict_iter, "devicecapability", info->dev_capab)) @@ -1166,115 +1218,97 @@ DBusMessage *wpas_dbus_getter_p2p_peer_properties(DBusMessage * message, goto err_no_mem; if (info->wps_sec_dev_type_list_len) { - char *sec_dev_types[MAX_SEC_DEVICE_TYPES]; - u8 *sec_dev_type_list = NULL; - char secdevtype[WPS_DEV_TYPE_BUFSIZE]; - int num_sec_dev_types = 0; - int i; - - sec_dev_type_list = os_zalloc(info->wps_sec_dev_type_list_len); - - if (sec_dev_type_list == NULL) - goto err_no_mem; - - os_memcpy(sec_dev_type_list, info->wps_sec_dev_type_list, - info->wps_sec_dev_type_list_len); - - for (i = 0; i < MAX_SEC_DEVICE_TYPES && - i < (int) (info->wps_sec_dev_type_list_len / - WPS_DEV_TYPE_LEN); - i++) { - sec_dev_types[i] = os_zalloc(sizeof(secdevtype)); - - if (!sec_dev_types[i] || - wps_dev_type_bin2str( - &sec_dev_type_list[i * - WPS_DEV_TYPE_LEN], - sec_dev_types[i], - sizeof(secdevtype)) == NULL) { - while (--i >= 0) - os_free(sec_dev_types[i]); - os_free(sec_dev_type_list); - goto err_no_mem; - } - - num_sec_dev_types++; - } - - os_free(sec_dev_type_list); + const u8 *sec_dev_type_list = info->wps_sec_dev_type_list; + int num_sec_dev_types = + info->wps_sec_dev_type_list_len / WPS_DEV_TYPE_LEN; + DBusMessageIter iter_secdev_dict_entry, iter_secdev_dict_val, + iter_secdev_dict_array; if (num_sec_dev_types) { - if (!wpa_dbus_dict_append_string_array(&dict_iter, + if (!wpa_dbus_dict_begin_array(&dict_iter, "SecondaryDeviceTypes", - (const char **)sec_dev_types, - num_sec_dev_types)) { - for (i = 0; i < num_sec_dev_types; i++) - os_free(sec_dev_types[i]); + DBUS_TYPE_ARRAY_AS_STRING + DBUS_TYPE_BYTE_AS_STRING, + &iter_secdev_dict_entry, + &iter_secdev_dict_val, + &iter_secdev_dict_array)) goto err_no_mem; + for (i = 0; i < num_sec_dev_types; i++) { + wpa_dbus_dict_bin_array_add_element( + &iter_secdev_dict_array, + sec_dev_type_list, + WPS_DEV_TYPE_LEN); + sec_dev_type_list += WPS_DEV_TYPE_LEN; } - for (i = 0; i < num_sec_dev_types; i++) - os_free(sec_dev_types[i]); + if (!wpa_dbus_dict_end_array(&dict_iter, + &iter_secdev_dict_entry, + &iter_secdev_dict_val, + &iter_secdev_dict_array)) + goto err_no_mem; } } - { - /* Add WPS vendor extensions attribute */ - const struct wpabuf *vendor_extension[P2P_MAX_WPS_VENDOR_EXT]; - int i, num = 0; - - for (i = 0; i < P2P_MAX_WPS_VENDOR_EXT; i++) { - if (info->wps_vendor_ext[i] == NULL) - continue; - vendor_extension[num] = info->wps_vendor_ext[i]; - num++; - } - - if (!wpa_dbus_dict_append_wpabuf_array( - &dict_iter, "VendorExtension", - vendor_extension, num)) - goto err_no_mem; + /* Add WPS vendor extensions attribute */ + for (i = 0, num = 0; i < P2P_MAX_WPS_VENDOR_EXT; i++) { + if (info->wps_vendor_ext[i] == NULL) + continue; + vendor_extension[num] = info->wps_vendor_ext[i]; + num++; } + if (!wpa_dbus_dict_append_wpabuf_array(&dict_iter, "VendorExtension", + vendor_extension, num)) + goto err_no_mem; + if (!wpa_dbus_dict_close_write(&variant_iter, &dict_iter) || - !dbus_message_iter_close_container(&iter, &variant_iter)) + !dbus_message_iter_close_container(iter, &variant_iter)) goto err_no_mem; - return reply; + return TRUE; + err_no_mem: - dbus_message_unref(reply); - return dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY, NULL); + dbus_set_error_const(error, DBUS_ERROR_NO_MEMORY, "no memory"); + return FALSE; } -DBusMessage *wpas_dbus_getter_p2p_peer_ies(DBusMessage * message, - struct peer_handler_args * peer_args) + +dbus_bool_t wpas_dbus_getter_p2p_peer_ies(DBusMessageIter *iter, + DBusError *error, void *user_data) { - return NULL; + /* struct peer_handler_args *peer_args = user_data; */ + + dbus_set_error_const(error, DBUS_ERROR_FAILED, "not implemented"); + return FALSE; } /** - * wpas_dbus_getter_persistent_groups - Get array of peristent group objects - * @message: Pointer to incoming dbus message - * @wpa_s: wpa_supplicant structure for a network interface - * Returns: a dbus message containing an array of all persistent group - * dbus object paths. + * wpas_dbus_getter_persistent_groups - Get array of persistent group objects + * @iter: Pointer to incoming dbus message iter + * @error: Location to store error on failure + * @user_data: Function specific data + * Returns: TRUE on success, FALSE on failure * - * Getter for "Networks" property. + * Getter for "PersistentGroups" property. */ -DBusMessage * wpas_dbus_getter_persistent_groups(DBusMessage *message, - struct wpa_supplicant *wpa_s) +dbus_bool_t wpas_dbus_getter_persistent_groups(DBusMessageIter *iter, + DBusError *error, + void *user_data) { - DBusMessage *reply = NULL; + struct wpa_supplicant *wpa_s = user_data; struct wpa_ssid *ssid; char **paths; unsigned int i = 0, num = 0; + dbus_bool_t success = FALSE; if (wpa_s->conf == NULL) { wpa_printf(MSG_ERROR, "dbus: %s: " "An error occurred getting persistent groups list", __func__); - return wpas_dbus_error_unknown_error(message, NULL); + dbus_set_error_const(error, DBUS_ERROR_FAILED, "an error " + "occurred getting persistent groups list"); + return FALSE; } for (ssid = wpa_s->conf->ssid; ssid; ssid = ssid->next) @@ -1283,8 +1317,8 @@ DBusMessage * wpas_dbus_getter_persistent_groups(DBusMessage *message, paths = os_zalloc(num * sizeof(char *)); if (!paths) { - return dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY, - NULL); + dbus_set_error_const(error, DBUS_ERROR_NO_MEMORY, "no memory"); + return FALSE; } /* Loop through configured networks and append object path of each */ @@ -1293,9 +1327,8 @@ DBusMessage * wpas_dbus_getter_persistent_groups(DBusMessage *message, continue; paths[i] = os_zalloc(WPAS_DBUS_OBJECT_PATH_MAX); if (paths[i] == NULL) { - reply = dbus_message_new_error(message, - DBUS_ERROR_NO_MEMORY, - NULL); + dbus_set_error_const(error, DBUS_ERROR_NO_MEMORY, + "no memory"); goto out; } /* Construct the object path for this network. */ @@ -1304,74 +1337,65 @@ DBusMessage * wpas_dbus_getter_persistent_groups(DBusMessage *message, wpa_s->dbus_new_path, ssid->id); } - reply = wpas_dbus_simple_array_property_getter(message, - DBUS_TYPE_OBJECT_PATH, - paths, num); + success = wpas_dbus_simple_array_property_getter(iter, + DBUS_TYPE_OBJECT_PATH, + paths, num, error); out: while (i) os_free(paths[--i]); os_free(paths); - return reply; + return success; } /** * wpas_dbus_getter_persistent_group_properties - Get options for a persistent * group - * @message: Pointer to incoming dbus message - * @net: wpa_supplicant structure for a network interface and - * wpa_ssid structure for a configured persistent group (internally network) - * Returns: DBus message with network properties or DBus error on failure + * @iter: Pointer to incoming dbus message iter + * @error: Location to store error on failure + * @user_data: Function specific data + * Returns: TRUE on success, FALSE on failure * * Getter for "Properties" property of a persistent group. */ -DBusMessage * wpas_dbus_getter_persistent_group_properties( - DBusMessage *message, struct network_handler_args *net) +dbus_bool_t wpas_dbus_getter_persistent_group_properties(DBusMessageIter *iter, + DBusError *error, + void *user_data) { - /* - * Leveraging the fact that persistent group object is still + struct network_handler_args *net = user_data; + + /* Leveraging the fact that persistent group object is still * represented in same manner as network within. */ - return wpas_dbus_getter_network_properties(message, net); + return wpas_dbus_getter_network_properties(iter, error, net); } /** * wpas_dbus_setter_persistent_group_properties - Get options for a persistent * group - * @message: Pointer to incoming dbus message - * @net: wpa_supplicant structure for a network interface and - * wpa_ssid structure for a configured persistent group (internally network) - * Returns: DBus message with network properties or DBus error on failure + * @iter: Pointer to incoming dbus message iter + * @error: Location to store error on failure + * @user_data: Function specific data + * Returns: TRUE on success, FALSE on failure * * Setter for "Properties" property of a persistent group. */ -DBusMessage * wpas_dbus_setter_persistent_group_properties( - DBusMessage *message, struct network_handler_args *net) +dbus_bool_t wpas_dbus_setter_persistent_group_properties(DBusMessageIter *iter, + DBusError *error, + void *user_data) { + struct network_handler_args *net = user_data; struct wpa_ssid *ssid = net->ssid; - DBusMessage *reply = NULL; - DBusMessageIter iter, variant_iter; - - dbus_message_iter_init(message, &iter); - - dbus_message_iter_next(&iter); - dbus_message_iter_next(&iter); - - dbus_message_iter_recurse(&iter, &variant_iter); + DBusMessageIter variant_iter; /* * Leveraging the fact that persistent group object is still * represented in same manner as network within. */ - reply = set_network_properties(message, net->wpa_s, ssid, - &variant_iter); - if (reply) - wpa_printf(MSG_DEBUG, "dbus control interface couldn't set " - "persistent group properties"); - - return reply; + dbus_message_iter_recurse(iter, &variant_iter); + return set_network_properties(net->wpa_s, ssid, &variant_iter, error); } @@ -1393,6 +1417,7 @@ DBusMessage * wpas_dbus_handler_add_persistent_group( DBusMessageIter iter; struct wpa_ssid *ssid = NULL; char path_buf[WPAS_DBUS_OBJECT_PATH_MAX], *path = path_buf; + DBusError error; dbus_message_iter_init(message, &iter); @@ -1414,11 +1439,16 @@ DBusMessage * wpas_dbus_handler_add_persistent_group( wpa_config_set_network_defaults(ssid); - reply = set_network_properties(message, wpa_s, ssid, &iter); - if (reply) { + dbus_error_init(&error); + if (!set_network_properties(wpa_s, ssid, &iter, &error)) { wpa_printf(MSG_DEBUG, "dbus: %s: " "Control interface could not set persistent group " "properties", __func__); + reply = wpas_dbus_reply_new_from_error(message, &error, + DBUS_ERROR_INVALID_ARGS, + "Failed to set network " + "properties"); + dbus_error_free(&error); goto err; } @@ -1564,27 +1594,29 @@ DBusMessage * wpas_dbus_handler_remove_all_persistent_groups( * Group object properties accessor methods */ -DBusMessage *wpas_dbus_getter_p2p_group_members(DBusMessage * message, - struct wpa_supplicant * wpa_s) +dbus_bool_t wpas_dbus_getter_p2p_group_members(DBusMessageIter *iter, + DBusError *error, + void *user_data) { - DBusMessage *reply = NULL; + struct wpa_supplicant *wpa_s = user_data; struct wpa_ssid *ssid; unsigned int num_members; char **paths; unsigned int i; void *next = NULL; const u8 *addr; + dbus_bool_t success = FALSE; /* Ensure we are a GO */ if (wpa_s->wpa_state != WPA_COMPLETED) - goto out; + return FALSE; ssid = wpa_s->conf->ssid; /* At present WPAS P2P_GO mode only applicable for p2p_go */ if (ssid->mode != WPAS_MODE_P2P_GO && ssid->mode != WPAS_MODE_AP && ssid->mode != WPAS_MODE_P2P_GROUP_FORMATION) - goto out; + return FALSE; num_members = p2p_get_group_num_members(wpa_s->p2p_group); @@ -1604,50 +1636,45 @@ DBusMessage *wpas_dbus_getter_p2p_group_members(DBusMessage * message, i++; } - reply = wpas_dbus_simple_array_property_getter(message, - DBUS_TYPE_OBJECT_PATH, - paths, num_members); + success = wpas_dbus_simple_array_property_getter(iter, + DBUS_TYPE_OBJECT_PATH, + paths, num_members, + error); -out_free: for (i = 0; i < num_members; i++) os_free(paths[i]); os_free(paths); -out: - return reply; + return success; + out_of_memory: - reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY, NULL); - goto out_free; + dbus_set_error_const(error, DBUS_ERROR_NO_MEMORY, "no memory"); + if (paths) { + for (i = 0; i < num_members; i++) + os_free(paths[i]); + os_free(paths); + } + return FALSE; } -DBusMessage *wpas_dbus_getter_p2p_group_properties( - DBusMessage *message, - struct wpa_supplicant *wpa_s) +dbus_bool_t wpas_dbus_getter_p2p_group_properties(DBusMessageIter *iter, + DBusError *error, + void *user_data) { - DBusMessage *reply = NULL; - DBusMessageIter iter, variant_iter, dict_iter; + struct wpa_supplicant *wpa_s = user_data; + DBusMessageIter variant_iter, dict_iter; struct hostapd_data *hapd = wpa_s->ap_iface->bss[0]; const struct wpabuf *vendor_ext[MAX_WPS_VENDOR_EXTENSIONS]; int num_vendor_ext = 0; int i; if (!hapd) { - reply = dbus_message_new_error(message, DBUS_ERROR_FAILED, - NULL); - return reply; + dbus_set_error_const(error, DBUS_ERROR_FAILED, + "internal error"); + return FALSE; } - if (message == NULL) - reply = dbus_message_new(DBUS_MESSAGE_TYPE_SIGNAL); - else - reply = dbus_message_new_method_return(message); - - if (!reply) - goto err_no_mem; - - dbus_message_iter_init_append(reply, &iter); - - if (!dbus_message_iter_open_container(&iter, DBUS_TYPE_VARIANT, + if (!dbus_message_iter_open_container(iter, DBUS_TYPE_VARIANT, "a{sv}", &variant_iter) || !wpa_dbus_dict_open_write(&variant_iter, &dict_iter)) goto err_no_mem; @@ -1665,45 +1692,42 @@ DBusMessage *wpas_dbus_getter_p2p_group_properties( goto err_no_mem; if (!wpa_dbus_dict_close_write(&variant_iter, &dict_iter) || - !dbus_message_iter_close_container(&iter, &variant_iter)) + !dbus_message_iter_close_container(iter, &variant_iter)) goto err_no_mem; - return reply; + return TRUE; err_no_mem: - dbus_message_unref(reply); - return dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY, NULL); + dbus_set_error_const(error, DBUS_ERROR_NO_MEMORY, "no memory"); + return FALSE; } -DBusMessage *wpas_dbus_setter_p2p_group_properties( - DBusMessage *message, - struct wpa_supplicant *wpa_s) + +dbus_bool_t wpas_dbus_setter_p2p_group_properties(DBusMessageIter *iter, + DBusError *error, + void *user_data) { - DBusMessage *reply = NULL; - DBusMessageIter iter, variant_iter; - struct wpa_dbus_dict_entry entry = {.type = DBUS_TYPE_STRING }; - DBusMessageIter iter_dict; + struct wpa_supplicant *wpa_s = user_data; + DBusMessageIter variant_iter, iter_dict; + struct wpa_dbus_dict_entry entry = { .type = DBUS_TYPE_STRING }; unsigned int i; - struct hostapd_data *hapd = wpa_s->ap_iface->bss[0]; - if (!hapd) - goto error; - - dbus_message_iter_init(message, &iter); - - dbus_message_iter_next(&iter); - dbus_message_iter_next(&iter); - - dbus_message_iter_recurse(&iter, &variant_iter); + if (!hapd) { + dbus_set_error_const(error, DBUS_ERROR_FAILED, + "internal error"); + return FALSE; + } - if (!wpa_dbus_dict_open_read(&variant_iter, &iter_dict)) - return wpas_dbus_error_invalid_args(message, NULL); + dbus_message_iter_recurse(iter, &variant_iter); + if (!wpa_dbus_dict_open_read(&variant_iter, &iter_dict, error)) + return FALSE; while (wpa_dbus_dict_has_dict_entry(&iter_dict)) { if (!wpa_dbus_dict_get_entry(&iter_dict, &entry)) { - reply = wpas_dbus_error_invalid_args(message, NULL); - break; + dbus_set_error_const(error, DBUS_ERROR_INVALID_ARGS, + "invalid message format"); + return FALSE; } if (os_strcmp(entry.key, "WPSVendorExtensions") == 0) { @@ -1728,17 +1752,18 @@ DBusMessage *wpas_dbus_setter_p2p_group_properties( wpa_dbus_dict_entry_clear(&entry); } - return reply; + return TRUE; error: - reply = wpas_dbus_error_invalid_args(message, entry.key); wpa_dbus_dict_entry_clear(&entry); - - return reply; + dbus_set_error_const(error, DBUS_ERROR_INVALID_ARGS, + "invalid message format"); + return FALSE; } -DBusMessage *wpas_dbus_handler_p2p_add_service(DBusMessage * message, - struct wpa_supplicant * wpa_s) + +DBusMessage * wpas_dbus_handler_p2p_add_service(DBusMessage *message, + struct wpa_supplicant *wpa_s) { DBusMessageIter iter_dict; DBusMessage *reply = NULL; @@ -1753,18 +1778,18 @@ DBusMessage *wpas_dbus_handler_p2p_add_service(DBusMessage * message, dbus_message_iter_init(message, &iter); - if (!wpa_dbus_dict_open_read(&iter, &iter_dict)) + if (!wpa_dbus_dict_open_read(&iter, &iter_dict, NULL)) goto error; if (wpa_dbus_dict_has_dict_entry(&iter_dict)) { if (!wpa_dbus_dict_get_entry(&iter_dict, &entry)) goto error; - if (!strcmp(entry.key, "service_type") && + if (!os_strcmp(entry.key, "service_type") && (entry.type == DBUS_TYPE_STRING)) { - if (!strcmp(entry.str_value, "upnp")) + if (!os_strcmp(entry.str_value, "upnp")) upnp = 1; - else if (!strcmp(entry.str_value, "bonjour")) + else if (!os_strcmp(entry.str_value, "bonjour")) bonjour = 1; else goto error_clear; @@ -1777,10 +1802,10 @@ DBusMessage *wpas_dbus_handler_p2p_add_service(DBusMessage * message, if (!wpa_dbus_dict_get_entry(&iter_dict, &entry)) goto error; - if (!strcmp(entry.key, "version") && + if (!os_strcmp(entry.key, "version") && entry.type == DBUS_TYPE_INT32) version = entry.uint32_value; - else if (!strcmp(entry.key, "service") && + else if (!os_strcmp(entry.key, "service") && entry.type == DBUS_TYPE_STRING) service = os_strdup(entry.str_value); wpa_dbus_dict_entry_clear(&entry); @@ -1797,13 +1822,14 @@ DBusMessage *wpas_dbus_handler_p2p_add_service(DBusMessage * message, if (!wpa_dbus_dict_get_entry(&iter_dict, &entry)) goto error; - if (!strcmp(entry.key, "query")) { + if (!os_strcmp(entry.key, "query")) { if ((entry.type != DBUS_TYPE_ARRAY) || (entry.array_type != DBUS_TYPE_BYTE)) goto error_clear; - query = wpabuf_alloc_copy(entry.bytearray_value, - entry.array_len); - } else if (!strcmp(entry.key, "response")) { + query = wpabuf_alloc_copy( + entry.bytearray_value, + entry.array_len); + } else if (!os_strcmp(entry.key, "response")) { if ((entry.type != DBUS_TYPE_ARRAY) || (entry.array_type != DBUS_TYPE_BYTE)) goto error_clear; @@ -1832,8 +1858,9 @@ error: return wpas_dbus_error_invalid_args(message, NULL); } -DBusMessage *wpas_dbus_handler_p2p_delete_service(DBusMessage * message, - struct wpa_supplicant * wpa_s) + +DBusMessage * wpas_dbus_handler_p2p_delete_service( + DBusMessage *message, struct wpa_supplicant *wpa_s) { DBusMessageIter iter_dict; DBusMessage *reply = NULL; @@ -1848,18 +1875,18 @@ DBusMessage *wpas_dbus_handler_p2p_delete_service(DBusMessage * message, dbus_message_iter_init(message, &iter); - if (!wpa_dbus_dict_open_read(&iter, &iter_dict)) + if (!wpa_dbus_dict_open_read(&iter, &iter_dict, NULL)) goto error; if (wpa_dbus_dict_has_dict_entry(&iter_dict)) { if (!wpa_dbus_dict_get_entry(&iter_dict, &entry)) goto error; - if (!strcmp(entry.key, "service_type") && + if (!os_strcmp(entry.key, "service_type") && (entry.type == DBUS_TYPE_STRING)) { - if (!strcmp(entry.str_value, "upnp")) + if (!os_strcmp(entry.str_value, "upnp")) upnp = 1; - else if (!strcmp(entry.str_value, "bonjour")) + else if (!os_strcmp(entry.str_value, "bonjour")) bonjour = 1; else goto error_clear; @@ -1870,10 +1897,10 @@ DBusMessage *wpas_dbus_handler_p2p_delete_service(DBusMessage * message, while (wpa_dbus_dict_has_dict_entry(&iter_dict)) { if (!wpa_dbus_dict_get_entry(&iter_dict, &entry)) goto error; - if (!strcmp(entry.key, "version") && + if (!os_strcmp(entry.key, "version") && entry.type == DBUS_TYPE_INT32) version = entry.uint32_value; - else if (!strcmp(entry.key, "service") && + else if (!os_strcmp(entry.key, "service") && entry.type == DBUS_TYPE_STRING) service = os_strdup(entry.str_value); else @@ -1894,12 +1921,13 @@ DBusMessage *wpas_dbus_handler_p2p_delete_service(DBusMessage * message, if (!wpa_dbus_dict_get_entry(&iter_dict, &entry)) goto error; - if (!strcmp(entry.key, "query")) { + if (!os_strcmp(entry.key, "query")) { if ((entry.type != DBUS_TYPE_ARRAY) || (entry.array_type != DBUS_TYPE_BYTE)) goto error_clear; - query = wpabuf_alloc_copy(entry.bytearray_value, - entry.array_len); + query = wpabuf_alloc_copy( + entry.bytearray_value, + entry.array_len); } else goto error_clear; @@ -1923,15 +1951,17 @@ error: return wpas_dbus_error_invalid_args(message, NULL); } -DBusMessage *wpas_dbus_handler_p2p_flush_service(DBusMessage * message, - struct wpa_supplicant * wpa_s) + +DBusMessage * wpas_dbus_handler_p2p_flush_service(DBusMessage *message, + struct wpa_supplicant *wpa_s) { wpas_p2p_service_flush(wpa_s); return NULL; } -DBusMessage *wpas_dbus_handler_p2p_service_sd_req(DBusMessage * message, - struct wpa_supplicant * wpa_s) + +DBusMessage * wpas_dbus_handler_p2p_service_sd_req( + DBusMessage *message, struct wpa_supplicant *wpa_s) { DBusMessageIter iter_dict; DBusMessage *reply = NULL; @@ -1947,28 +1977,28 @@ DBusMessage *wpas_dbus_handler_p2p_service_sd_req(DBusMessage * message, dbus_message_iter_init(message, &iter); - if (!wpa_dbus_dict_open_read(&iter, &iter_dict)) + if (!wpa_dbus_dict_open_read(&iter, &iter_dict, NULL)) goto error; while (wpa_dbus_dict_has_dict_entry(&iter_dict)) { if (!wpa_dbus_dict_get_entry(&iter_dict, &entry)) goto error; - if (!strcmp(entry.key, "peer_object") && + if (!os_strcmp(entry.key, "peer_object") && entry.type == DBUS_TYPE_OBJECT_PATH) { peer_object_path = os_strdup(entry.str_value); - } else if (!strcmp(entry.key, "service_type") && + } else if (!os_strcmp(entry.key, "service_type") && entry.type == DBUS_TYPE_STRING) { - if (!strcmp(entry.str_value, "upnp")) + if (!os_strcmp(entry.str_value, "upnp")) upnp = 1; else goto error_clear; - } else if (!strcmp(entry.key, "version") && + } else if (!os_strcmp(entry.key, "version") && entry.type == DBUS_TYPE_INT32) { version = entry.uint32_value; - } else if (!strcmp(entry.key, "service") && + } else if (!os_strcmp(entry.key, "service") && entry.type == DBUS_TYPE_STRING) { service = os_strdup(entry.str_value); - } else if (!strcmp(entry.key, "tlv")) { + } else if (!os_strcmp(entry.key, "tlv")) { if (entry.type != DBUS_TYPE_ARRAY || entry.array_type != DBUS_TYPE_BYTE) goto error_clear; @@ -1982,19 +2012,18 @@ DBusMessage *wpas_dbus_handler_p2p_service_sd_req(DBusMessage * message, if (!peer_object_path || (parse_peer_object_path(peer_object_path, addr) < 0) || - (p2p_get_peer_info(wpa_s->global->p2p, addr, 0, NULL, 0) < 0)) + !p2p_peer_known(wpa_s->global->p2p, addr)) goto error; if (upnp == 1) { if (version <= 0 || service == NULL) goto error; - ref = (unsigned long)wpas_p2p_sd_request_upnp(wpa_s, addr, - version, service); + ref = wpas_p2p_sd_request_upnp(wpa_s, addr, version, service); } else { if (tlv == NULL) goto error; - ref = (unsigned long)wpas_p2p_sd_request(wpa_s, addr, tlv); + ref = wpas_p2p_sd_request(wpa_s, addr, tlv); wpabuf_free(tlv); } @@ -2003,8 +2032,8 @@ DBusMessage *wpas_dbus_handler_p2p_service_sd_req(DBusMessage * message, dbus_message_append_args(reply, DBUS_TYPE_UINT64, &ref, DBUS_TYPE_INVALID); } else { - reply = wpas_dbus_error_unknown_error(message, - "Unable to send SD request"); + reply = wpas_dbus_error_unknown_error( + message, "Unable to send SD request"); } out: os_free(service); @@ -2019,7 +2048,8 @@ error: goto out; } -DBusMessage *wpas_dbus_handler_p2p_service_sd_res( + +DBusMessage * wpas_dbus_handler_p2p_service_sd_res( DBusMessage *message, struct wpa_supplicant *wpa_s) { DBusMessageIter iter_dict; @@ -2034,23 +2064,23 @@ DBusMessage *wpas_dbus_handler_p2p_service_sd_res( dbus_message_iter_init(message, &iter); - if (!wpa_dbus_dict_open_read(&iter, &iter_dict)) + if (!wpa_dbus_dict_open_read(&iter, &iter_dict, NULL)) goto error; while (wpa_dbus_dict_has_dict_entry(&iter_dict)) { if (!wpa_dbus_dict_get_entry(&iter_dict, &entry)) goto error; - if (!strcmp(entry.key, "peer_object") && + if (!os_strcmp(entry.key, "peer_object") && entry.type == DBUS_TYPE_OBJECT_PATH) { peer_object_path = os_strdup(entry.str_value); - } else if (!strcmp(entry.key, "frequency") && + } else if (!os_strcmp(entry.key, "frequency") && entry.type == DBUS_TYPE_INT32) { freq = entry.uint32_value; - } else if (!strcmp(entry.key, "dialog_token") && + } else if (!os_strcmp(entry.key, "dialog_token") && entry.type == DBUS_TYPE_UINT32) { dlg_tok = entry.uint32_value; - } else if (!strcmp(entry.key, "tlvs")) { + } else if (!os_strcmp(entry.key, "tlvs")) { if (entry.type != DBUS_TYPE_ARRAY || entry.array_type != DBUS_TYPE_BYTE) goto error_clear; @@ -2063,7 +2093,7 @@ DBusMessage *wpas_dbus_handler_p2p_service_sd_res( } if (!peer_object_path || (parse_peer_object_path(peer_object_path, addr) < 0) || - (p2p_get_peer_info(wpa_s->global->p2p, addr, 0, NULL, 0) < 0)) + !p2p_peer_known(wpa_s->global->p2p, addr)) goto error; if (tlv == NULL) @@ -2081,8 +2111,9 @@ error: goto out; } -DBusMessage *wpas_dbus_handler_p2p_service_sd_cancel_req(DBusMessage * message, struct wpa_supplicant - *wpa_s) + +DBusMessage * wpas_dbus_handler_p2p_service_sd_cancel_req( + DBusMessage *message, struct wpa_supplicant *wpa_s) { DBusMessageIter iter; u64 req = 0; @@ -2093,7 +2124,7 @@ DBusMessage *wpas_dbus_handler_p2p_service_sd_cancel_req(DBusMessage * message, if (req == 0) goto error; - if (!wpas_p2p_sd_cancel_request(wpa_s, (void *)(unsigned long)req)) + if (!wpas_p2p_sd_cancel_request(wpa_s, req)) goto error; return NULL; @@ -2101,16 +2132,17 @@ error: return wpas_dbus_error_invalid_args(message, NULL); } -DBusMessage *wpas_dbus_handler_p2p_service_update(DBusMessage * message, - struct wpa_supplicant * wpa_s) + +DBusMessage * wpas_dbus_handler_p2p_service_update( + DBusMessage *message, struct wpa_supplicant *wpa_s) { wpas_p2p_sd_service_update(wpa_s); return NULL; } -DBusMessage *wpas_dbus_handler_p2p_serv_disc_external(DBusMessage * message, - struct wpa_supplicant * - wpa_s) + +DBusMessage * wpas_dbus_handler_p2p_serv_disc_external( + DBusMessage *message, struct wpa_supplicant *wpa_s) { DBusMessageIter iter; int ext = 0; diff --git a/wpa_supplicant/dbus/dbus_new_handlers_p2p.h b/wpa_supplicant/dbus/dbus_new_handlers_p2p.h index ed9a345..206e904 100644 --- a/wpa_supplicant/dbus/dbus_new_handlers_p2p.h +++ b/wpa_supplicant/dbus/dbus_new_handlers_p2p.h @@ -94,61 +94,69 @@ DBusMessage *wpas_dbus_handler_p2p_serv_disc_external( /* * P2P Device property accessor methods. */ -DBusMessage *wpas_dbus_setter_p2p_device_properties(DBusMessage *message, - struct wpa_supplicant *wpa_s); +dbus_bool_t wpas_dbus_setter_p2p_device_properties(DBusMessageIter *iter, + DBusError *error, + void *user_data); -DBusMessage *wpas_dbus_getter_p2p_device_properties(DBusMessage *message, - struct wpa_supplicant *wpa_s); +dbus_bool_t wpas_dbus_getter_p2p_device_properties(DBusMessageIter *iter, + DBusError *error, + void *user_data); -DBusMessage *wpas_dbus_getter_p2p_peers(DBusMessage *message, - struct wpa_supplicant *wpa_s); +dbus_bool_t wpas_dbus_getter_p2p_peers(DBusMessageIter *iter, DBusError *error, + void *user_data); -DBusMessage *wpas_dbus_getter_p2p_role(DBusMessage *message, - struct wpa_supplicant *wpa_s); +dbus_bool_t wpas_dbus_getter_p2p_role(DBusMessageIter *iter, DBusError *error, + void *user_data); -DBusMessage *wpas_dbus_getter_p2p_group(DBusMessage *message, - struct wpa_supplicant *wpa_s); +dbus_bool_t wpas_dbus_getter_p2p_group(DBusMessageIter *iter, DBusError *error, + void *user_data); -DBusMessage *wpas_dbus_getter_p2p_peergo(DBusMessage *message, - struct wpa_supplicant *wpa_s); +dbus_bool_t wpas_dbus_getter_p2p_peergo(DBusMessageIter *iter, + DBusError *error, + void *user_data); /* * P2P Peer properties. */ -DBusMessage *wpas_dbus_getter_p2p_peer_properties( - DBusMessage *message, - struct peer_handler_args *peer); +dbus_bool_t wpas_dbus_getter_p2p_peer_properties(DBusMessageIter *iter, + DBusError *error, + void *user_data); -DBusMessage *wpas_dbus_getter_p2p_peer_ies( - DBusMessage *message, - struct peer_handler_args *peer); +dbus_bool_t wpas_dbus_getter_p2p_peer_ies(DBusMessageIter *iter, + DBusError *error, + void *user_data); /* * P2P Group properties */ -DBusMessage *wpas_dbus_getter_p2p_group_members( - DBusMessage *message, - struct wpa_supplicant *wpa_s); +dbus_bool_t wpas_dbus_getter_p2p_group_members(DBusMessageIter *iter, + DBusError *error, + void *user_data); -DBusMessage *wpas_dbus_getter_p2p_group_properties( - DBusMessage *message, - struct wpa_supplicant *wpa_s); +dbus_bool_t wpas_dbus_getter_p2p_group_properties(DBusMessageIter *iter, + DBusError *error, + void *user_data); -DBusMessage *wpas_dbus_setter_p2p_group_properties( - DBusMessage *message, - struct wpa_supplicant *wpa_s); +dbus_bool_t wpas_dbus_setter_p2p_group_properties(DBusMessageIter *iter, + DBusError *error, + void *user_data); /* * P2P Persistent Groups and properties */ -DBusMessage * wpas_dbus_getter_persistent_groups(DBusMessage *message, - struct wpa_supplicant *wpa_s); -DBusMessage * wpas_dbus_getter_persistent_group_properties( - DBusMessage *message, struct network_handler_args *net); -DBusMessage * wpas_dbus_setter_persistent_group_properties( - DBusMessage *message, struct network_handler_args *net); +dbus_bool_t wpas_dbus_getter_persistent_groups(DBusMessageIter *iter, + DBusError *error, + void *user_data); + +dbus_bool_t wpas_dbus_getter_persistent_group_properties(DBusMessageIter *iter, + DBusError *error, void *user_data); + +dbus_bool_t wpas_dbus_setter_persistent_group_properties(DBusMessageIter *iter, + DBusError *error, + void *user_data); + DBusMessage * wpas_dbus_handler_add_persistent_group( DBusMessage *message, struct wpa_supplicant *wpa_s); diff --git a/wpa_supplicant/dbus/dbus_new_handlers_wps.c b/wpa_supplicant/dbus/dbus_new_handlers_wps.c index c118d73..a72cfb3 100644 --- a/wpa_supplicant/dbus/dbus_new_handlers_wps.c +++ b/wpa_supplicant/dbus/dbus_new_handlers_wps.c @@ -19,6 +19,8 @@ #include "../config.h" #include "../wpa_supplicant_i.h" #include "../wps_supplicant.h" +#include "../driver_i.h" +#include "../ap.h" #include "dbus_new_helpers.h" #include "dbus_new.h" #include "dbus_new_handlers.h" @@ -30,6 +32,7 @@ struct wps_start_params { int type; /* 0 - not set, 1 - pin, 2 - pbc */ u8 *bssid; char *pin; + u8 *p2p_dev_addr; }; @@ -148,6 +151,41 @@ static int wpas_dbus_handler_wps_pin(DBusMessage *message, } +#ifdef CONFIG_P2P +static int wpas_dbus_handler_wps_p2p_dev_addr(DBusMessage *message, + DBusMessageIter *entry_iter, + struct wps_start_params *params, + DBusMessage **reply) +{ + DBusMessageIter variant_iter, array_iter; + int len; + + dbus_message_iter_recurse(entry_iter, &variant_iter); + if (dbus_message_iter_get_arg_type(&variant_iter) != DBUS_TYPE_ARRAY || + dbus_message_iter_get_element_type(&variant_iter) != + DBUS_TYPE_BYTE) { + wpa_printf(MSG_DEBUG, "dbus: WPS.Start - Wrong " + "P2PDeviceAddress type, byte array required"); + *reply = wpas_dbus_error_invalid_args( + message, "P2PDeviceAddress must be a byte array"); + return -1; + } + dbus_message_iter_recurse(&variant_iter, &array_iter); + dbus_message_iter_get_fixed_array(&array_iter, ¶ms->p2p_dev_addr, + &len); + if (len != ETH_ALEN) { + wpa_printf(MSG_DEBUG, "dbus: WPS.Start - Wrong " + "P2PDeviceAddress length %d", len); + *reply = wpas_dbus_error_invalid_args(message, + "P2PDeviceAddress " + "has wrong length"); + return -1; + } + return 0; +} +#endif /* CONFIG_P2P */ + + static int wpas_dbus_handler_wps_start_entry(DBusMessage *message, char *key, DBusMessageIter *entry_iter, struct wps_start_params *params, @@ -165,6 +203,11 @@ static int wpas_dbus_handler_wps_start_entry(DBusMessage *message, char *key, else if (os_strcmp(key, "Pin") == 0) return wpas_dbus_handler_wps_pin(message, entry_iter, params, reply); +#ifdef CONFIG_P2P + else if (os_strcmp(key, "P2PDeviceAddress") == 0) + return wpas_dbus_handler_wps_p2p_dev_addr(message, entry_iter, + params, reply); +#endif /* CONFIG_P2P */ wpa_printf(MSG_DEBUG, "dbus: WPS.Start - unknown key %s", key); *reply = wpas_dbus_error_invalid_args(message, key); @@ -231,12 +274,31 @@ DBusMessage * wpas_dbus_handler_wps_start(DBusMessage *message, ret = wpas_wps_start_reg(wpa_s, params.bssid, params.pin, NULL); else if (params.type == 1) { - ret = wpas_wps_start_pin(wpa_s, params.bssid, params.pin, 0, - DEV_PW_DEFAULT); - if (ret > 0) - os_snprintf(npin, sizeof(npin), "%08d", ret); - } else +#ifdef CONFIG_AP + if (wpa_s->ap_iface) + ret = wpa_supplicant_ap_wps_pin(wpa_s, + params.bssid, + params.pin, + npin, sizeof(npin)); + else +#endif /* CONFIG_AP */ + { + ret = wpas_wps_start_pin(wpa_s, params.bssid, + params.pin, 0, + DEV_PW_DEFAULT); + if (ret > 0) + os_snprintf(npin, sizeof(npin), "%08d", ret); + } + } else { +#ifdef CONFIG_AP + if (wpa_s->ap_iface) + ret = wpa_supplicant_ap_wps_pbc(wpa_s, + params.bssid, + params.p2p_dev_addr); + else +#endif /* CONFIG_AP */ ret = wpas_wps_start_pbc(wpa_s, params.bssid, 0); + } if (ret < 0) { wpa_printf(MSG_DEBUG, "dbus: WPS.Start wpas_wps_failed in " @@ -284,40 +346,43 @@ DBusMessage * wpas_dbus_handler_wps_start(DBusMessage *message, * wpas_dbus_getter_process_credentials - Check if credentials are processed * @message: Pointer to incoming dbus message * @wpa_s: %wpa_supplicant data structure - * Returns: DBus message with a boolean on success or DBus error on failure + * Returns: TRUE on success, FALSE on failure * * Getter for "ProcessCredentials" property. Returns returned boolean will be * true if wps_cred_processing configuration field is not equal to 1 or false * if otherwise. */ -DBusMessage * wpas_dbus_getter_process_credentials( - DBusMessage *message, struct wpa_supplicant *wpa_s) +dbus_bool_t wpas_dbus_getter_process_credentials(DBusMessageIter *iter, + DBusError *error, + void *user_data) { + struct wpa_supplicant *wpa_s = user_data; dbus_bool_t process = (wpa_s->conf->wps_cred_processing != 1); - return wpas_dbus_simple_property_getter(message, DBUS_TYPE_BOOLEAN, - &process); + return wpas_dbus_simple_property_getter(iter, DBUS_TYPE_BOOLEAN, + &process, error); } /** * wpas_dbus_setter_process_credentials - Set credentials_processed conf param - * @message: Pointer to incoming dbus message - * @wpa_s: %wpa_supplicant data structure - * Returns: NULL on success or DBus error on failure + * @iter: Pointer to incoming dbus message iter + * @error: Location to store error on failure + * @user_data: Function specific data + * Returns: TRUE on success, FALSE on failure * * Setter for "ProcessCredentials" property. Sets credentials_processed on 2 * if boolean argument is true or on 1 if otherwise. */ -DBusMessage * wpas_dbus_setter_process_credentials( - DBusMessage *message, struct wpa_supplicant *wpa_s) +dbus_bool_t wpas_dbus_setter_process_credentials(DBusMessageIter *iter, + DBusError *error, + void *user_data) { - DBusMessage *reply = NULL; + struct wpa_supplicant *wpa_s = user_data; dbus_bool_t process_credentials, old_pc; - reply = wpas_dbus_simple_property_setter(message, DBUS_TYPE_BOOLEAN, - &process_credentials); - if (reply) - return reply; + if (!wpas_dbus_simple_property_setter(iter, error, DBUS_TYPE_BOOLEAN, + &process_credentials)) + return FALSE; old_pc = (wpa_s->conf->wps_cred_processing != 1); wpa_s->conf->wps_cred_processing = (process_credentials ? 2 : 1); @@ -328,5 +393,5 @@ DBusMessage * wpas_dbus_setter_process_credentials( WPAS_DBUS_NEW_IFACE_WPS, "ProcessCredentials"); - return NULL; + return TRUE; } diff --git a/wpa_supplicant/dbus/dbus_new_helpers.c b/wpa_supplicant/dbus/dbus_new_helpers.c index 78611d4..e254365 100644 --- a/wpa_supplicant/dbus/dbus_new_helpers.c +++ b/wpa_supplicant/dbus/dbus_new_helpers.c @@ -21,112 +21,50 @@ #include "dbus_common_i.h" #include "dbus_new.h" #include "dbus_new_helpers.h" +#include "dbus_dict_helpers.h" -/** - * recursive_iter_copy - Reads arguments from one iterator and - * writes to another recursively - * @from: iterator to read from - * @to: iterator to write to - * - * Copies one iterator's elements to another. If any element in - * iterator is of container type, its content is copied recursively - */ -static void recursive_iter_copy(DBusMessageIter *from, DBusMessageIter *to) +static dbus_bool_t fill_dict_with_properties( + DBusMessageIter *dict_iter, + const struct wpa_dbus_property_desc *props, + const char *interface, void *user_data, DBusError *error) { - - char *subtype = NULL; - int type; - - /* iterate over iterator to copy */ - while ((type = dbus_message_iter_get_arg_type(from)) != - DBUS_TYPE_INVALID) { - - /* simply copy basic type entries */ - if (dbus_type_is_basic(type)) { - if (dbus_type_is_fixed(type)) { - /* - * According to DBus documentation all - * fixed-length types are guaranteed to fit - * 8 bytes - */ - dbus_uint64_t v; - dbus_message_iter_get_basic(from, &v); - dbus_message_iter_append_basic(to, type, &v); - } else { - char *v; - dbus_message_iter_get_basic(from, &v); - dbus_message_iter_append_basic(to, type, &v); - } - } else { - /* recursively copy container type entries */ - DBusMessageIter write_subiter, read_subiter; - - dbus_message_iter_recurse(from, &read_subiter); - - if (type == DBUS_TYPE_VARIANT || - type == DBUS_TYPE_ARRAY) { - subtype = dbus_message_iter_get_signature( - &read_subiter); - } - - dbus_message_iter_open_container(to, type, subtype, - &write_subiter); - - recursive_iter_copy(&read_subiter, &write_subiter); - - dbus_message_iter_close_container(to, &write_subiter); - if (subtype) - dbus_free(subtype); - } - - dbus_message_iter_next(from); - } -} - - -static unsigned int fill_dict_with_properties( - DBusMessageIter *dict_iter, const struct wpa_dbus_property_desc *props, - const char *interface, const void *user_data) -{ - DBusMessage *reply; - DBusMessageIter entry_iter, ret_iter; - unsigned int counter = 0; + DBusMessageIter entry_iter; const struct wpa_dbus_property_desc *dsc; for (dsc = props; dsc && dsc->dbus_property; dsc++) { - if (!os_strncmp(dsc->dbus_interface, interface, - WPAS_DBUS_INTERFACE_MAX) && - dsc->access != W && dsc->getter) { - reply = dsc->getter(NULL, user_data); - if (!reply) - continue; - - if (dbus_message_get_type(reply) == - DBUS_MESSAGE_TYPE_ERROR) { - dbus_message_unref(reply); - continue; - } + /* Only return properties for the requested D-Bus interface */ + if (os_strncmp(dsc->dbus_interface, interface, + WPAS_DBUS_INTERFACE_MAX) != 0) + continue; - dbus_message_iter_init(reply, &ret_iter); + /* Skip write-only properties */ + if (dsc->getter == NULL) + continue; - dbus_message_iter_open_container(dict_iter, - DBUS_TYPE_DICT_ENTRY, - NULL, &entry_iter); - dbus_message_iter_append_basic( - &entry_iter, DBUS_TYPE_STRING, - &dsc->dbus_property); + if (!dbus_message_iter_open_container(dict_iter, + DBUS_TYPE_DICT_ENTRY, + NULL, &entry_iter)) { + dbus_set_error_const(error, DBUS_ERROR_NO_MEMORY, + "no memory"); + return FALSE; + } + if (!dbus_message_iter_append_basic(&entry_iter, + DBUS_TYPE_STRING, + &dsc->dbus_property)) { + dbus_set_error_const(error, DBUS_ERROR_NO_MEMORY, + "no memory"); + return FALSE; + } - recursive_iter_copy(&ret_iter, &entry_iter); + /* An error getting a property fails the request entirely */ + if (!dsc->getter(&entry_iter, error, user_data)) + return FALSE; - dbus_message_iter_close_container(dict_iter, - &entry_iter); - dbus_message_unref(reply); - counter++; - } + dbus_message_iter_close_container(dict_iter, &entry_iter); } - return counter; + return TRUE; } @@ -142,37 +80,44 @@ static unsigned int fill_dict_with_properties( * specified as argument. Returned message contains one dict argument * with properties names as keys and theirs values as values. */ -static DBusMessage * get_all_properties( - DBusMessage *message, char *interface, - struct wpa_dbus_object_desc *obj_dsc) +static DBusMessage * get_all_properties(DBusMessage *message, char *interface, + struct wpa_dbus_object_desc *obj_dsc) { - /* Create and initialize the return message */ - DBusMessage *reply = dbus_message_new_method_return(message); + DBusMessage *reply; DBusMessageIter iter, dict_iter; - int props_num; - - dbus_message_iter_init_append(reply, &iter); - - dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, - DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING - DBUS_TYPE_STRING_AS_STRING - DBUS_TYPE_VARIANT_AS_STRING - DBUS_DICT_ENTRY_END_CHAR_AS_STRING, - &dict_iter); + DBusError error; - props_num = fill_dict_with_properties(&dict_iter, obj_dsc->properties, - interface, obj_dsc->user_data); + reply = dbus_message_new_method_return(message); + if (reply == NULL) { + wpa_printf(MSG_ERROR, "%s: out of memory creating dbus reply", + __func__); + return NULL; + } - dbus_message_iter_close_container(&iter, &dict_iter); + dbus_message_iter_init_append(reply, &iter); + if (!wpa_dbus_dict_open_write(&iter, &dict_iter)) { + wpa_printf(MSG_ERROR, "%s: out of memory creating reply", + __func__); + dbus_message_unref(reply); + reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY, + "out of memory"); + return reply; + } - if (props_num == 0) { + dbus_error_init(&error); + if (!fill_dict_with_properties(&dict_iter, obj_dsc->properties, + interface, obj_dsc->user_data, &error)) + { dbus_message_unref(reply); - reply = dbus_message_new_error(message, - DBUS_ERROR_INVALID_ARGS, - "No readable properties in " - "this interface"); + reply = wpas_dbus_reply_new_from_error(message, &error, + DBUS_ERROR_INVALID_ARGS, + "No readable properties" + " in this interface"); + dbus_error_free(&error); + return reply; } + wpa_dbus_dict_close_write(&iter, &dict_iter); return reply; } @@ -219,15 +164,33 @@ static DBusMessage * properties_get(DBusMessage *message, const struct wpa_dbus_property_desc *dsc, void *user_data) { - if (os_strcmp(dbus_message_get_signature(message), "ss")) + DBusMessage *reply; + DBusMessageIter iter; + DBusError error; + + if (os_strcmp(dbus_message_get_signature(message), "ss")) { return dbus_message_new_error(message, DBUS_ERROR_INVALID_ARGS, NULL); + } - if (dsc->access != W && dsc->getter) - return dsc->getter(message, user_data); + if (dsc->getter == NULL) { + return dbus_message_new_error(message, DBUS_ERROR_INVALID_ARGS, + "Property is write-only"); + } + + reply = dbus_message_new_method_return(message); + dbus_message_iter_init_append(reply, &iter); - return dbus_message_new_error(message, DBUS_ERROR_INVALID_ARGS, - "Property is write-only"); + dbus_error_init(&error); + if (dsc->getter(&iter, &error, user_data) == FALSE) { + dbus_message_unref(reply); + reply = wpas_dbus_reply_new_from_error( + message, &error, DBUS_ERROR_FAILED, + "Failed to read property"); + dbus_error_free(&error); + } + + return reply; } @@ -235,15 +198,38 @@ static DBusMessage * properties_set(DBusMessage *message, const struct wpa_dbus_property_desc *dsc, void *user_data) { - if (os_strcmp(dbus_message_get_signature(message), "ssv")) + DBusMessage *reply; + DBusMessageIter iter; + DBusError error; + + if (os_strcmp(dbus_message_get_signature(message), "ssv")) { return dbus_message_new_error(message, DBUS_ERROR_INVALID_ARGS, NULL); + } + + if (dsc->setter == NULL) { + return dbus_message_new_error(message, DBUS_ERROR_INVALID_ARGS, + "Property is read-only"); + } + + dbus_message_iter_init(message, &iter); + /* Skip the interface name and the property name */ + dbus_message_iter_next(&iter); + dbus_message_iter_next(&iter); - if (dsc->access != R && dsc->setter) - return dsc->setter(message, user_data); + /* Iter will now point to the property's new value */ + dbus_error_init(&error); + if (dsc->setter(&iter, &error, user_data) == TRUE) { + /* Success */ + reply = dbus_message_new_method_return(message); + } else { + reply = wpas_dbus_reply_new_from_error( + message, &error, DBUS_ERROR_FAILED, + "Failed to set property"); + dbus_error_free(&error); + } - return dbus_message_new_error(message, DBUS_ERROR_INVALID_ARGS, - "Property is read-only"); + return reply; } @@ -622,14 +608,14 @@ int wpa_dbus_unregister_object_per_iface( } -static void put_changed_properties(const struct wpa_dbus_object_desc *obj_dsc, - const char *interface, - DBusMessageIter *dict_iter) +static dbus_bool_t put_changed_properties( + const struct wpa_dbus_object_desc *obj_dsc, const char *interface, + DBusMessageIter *dict_iter, int clear_changed) { - DBusMessage *getter_reply; - DBusMessageIter prop_iter, entry_iter; + DBusMessageIter entry_iter; const struct wpa_dbus_property_desc *dsc; int i; + DBusError error; for (dsc = obj_dsc->properties, i = 0; dsc && dsc->dbus_property; dsc++, i++) { @@ -638,43 +624,94 @@ static void put_changed_properties(const struct wpa_dbus_object_desc *obj_dsc, continue; if (os_strcmp(dsc->dbus_interface, interface) != 0) continue; - obj_dsc->prop_changed_flags[i] = 0; - - getter_reply = dsc->getter(NULL, obj_dsc->user_data); - if (!getter_reply || - dbus_message_get_type(getter_reply) == - DBUS_MESSAGE_TYPE_ERROR) { - wpa_printf(MSG_ERROR, "dbus: %s: Cannot get new value " - "of property %s", __func__, - dsc->dbus_property); - continue; - } + if (clear_changed) + obj_dsc->prop_changed_flags[i] = 0; - if (!dbus_message_iter_init(getter_reply, &prop_iter) || - !dbus_message_iter_open_container(dict_iter, + if (!dbus_message_iter_open_container(dict_iter, DBUS_TYPE_DICT_ENTRY, - NULL, &entry_iter) || - !dbus_message_iter_append_basic(&entry_iter, + NULL, &entry_iter)) + return FALSE; + + if (!dbus_message_iter_append_basic(&entry_iter, DBUS_TYPE_STRING, &dsc->dbus_property)) - goto err; - - recursive_iter_copy(&prop_iter, &entry_iter); + return FALSE; + + dbus_error_init(&error); + if (!dsc->getter(&entry_iter, &error, obj_dsc->user_data)) { + if (dbus_error_is_set (&error)) { + wpa_printf(MSG_ERROR, "dbus: %s: Cannot get " + "new value of property %s: (%s) %s", + __func__, dsc->dbus_property, + error.name, error.message); + } else { + wpa_printf(MSG_ERROR, "dbus: %s: Cannot get " + "new value of property %s", + __func__, dsc->dbus_property); + } + dbus_error_free(&error); + return FALSE; + } if (!dbus_message_iter_close_container(dict_iter, &entry_iter)) - goto err; - - dbus_message_unref(getter_reply); + return FALSE; } + return TRUE; +} + + +static void do_send_prop_changed_signal( + DBusConnection *con, const char *path, const char *interface, + const struct wpa_dbus_object_desc *obj_dsc) +{ + DBusMessage *msg; + DBusMessageIter signal_iter, dict_iter; + + msg = dbus_message_new_signal(path, DBUS_INTERFACE_PROPERTIES, + "PropertiesChanged"); + if (msg == NULL) + return; + + dbus_message_iter_init_append(msg, &signal_iter); + + if (!dbus_message_iter_append_basic(&signal_iter, DBUS_TYPE_STRING, + &interface)) + goto err; + + /* Changed properties dict */ + if (!dbus_message_iter_open_container(&signal_iter, DBUS_TYPE_ARRAY, + "{sv}", &dict_iter)) + goto err; + + if (!put_changed_properties(obj_dsc, interface, &dict_iter, 0)) + goto err; + + if (!dbus_message_iter_close_container(&signal_iter, &dict_iter)) + goto err; + + /* Invalidated properties array (empty) */ + if (!dbus_message_iter_open_container(&signal_iter, DBUS_TYPE_ARRAY, + "s", &dict_iter)) + goto err; + + if (!dbus_message_iter_close_container(&signal_iter, &dict_iter)) + goto err; + + dbus_connection_send(con, msg, NULL); + +out: + dbus_message_unref(msg); return; err: - wpa_printf(MSG_ERROR, "dbus: %s: Cannot construct signal", __func__); + wpa_printf(MSG_DEBUG, "dbus: %s: Failed to construct signal", + __func__); + goto out; } -static void send_prop_changed_signal( +static void do_send_deprecated_prop_changed_signal( DBusConnection *con, const char *path, const char *interface, const struct wpa_dbus_object_desc *obj_dsc) { @@ -691,7 +728,8 @@ static void send_prop_changed_signal( "{sv}", &dict_iter)) goto err; - put_changed_properties(obj_dsc, interface, &dict_iter); + if (!put_changed_properties(obj_dsc, interface, &dict_iter, 1)) + goto err; if (!dbus_message_iter_close_container(&signal_iter, &dict_iter)) goto err; @@ -709,6 +747,29 @@ err: } +static void send_prop_changed_signal( + DBusConnection *con, const char *path, const char *interface, + const struct wpa_dbus_object_desc *obj_dsc) +{ + /* + * First, send property change notification on the standardized + * org.freedesktop.DBus.Properties interface. This call will not + * clear the property change bits, so that they are preserved for + * the call that follows. + */ + do_send_prop_changed_signal(con, path, interface, obj_dsc); + + /* + * Now send PropertiesChanged on our own interface for backwards + * compatibility. This is deprecated and will be removed in a future + * release. + */ + do_send_deprecated_prop_changed_signal(con, path, interface, obj_dsc); + + /* Property change bits have now been cleared. */ +} + + static void flush_object_timeout_handler(void *eloop_ctx, void *timeout_ctx) { DBusConnection *con = eloop_ctx; @@ -860,29 +921,49 @@ void wpa_dbus_mark_property_changed(struct wpas_dbus_priv *iface, * @iface: dbus priv struct * @path: path to DBus object which properties will be obtained * @interface: interface name which properties will be obtained - * @dict_iter: correct, open DBus dictionary iterator. + * @iter: DBus message iter at which to append property dictionary. * * Iterates over all properties registered with object and execute getters * of those, which are readable and which interface matches interface * specified as argument. Obtained properties values are stored in * dict_iter dictionary. */ -void wpa_dbus_get_object_properties(struct wpas_dbus_priv *iface, - const char *path, const char *interface, - DBusMessageIter *dict_iter) +dbus_bool_t wpa_dbus_get_object_properties(struct wpas_dbus_priv *iface, + const char *path, + const char *interface, + DBusMessageIter *iter) { struct wpa_dbus_object_desc *obj_desc = NULL; + DBusMessageIter dict_iter; + DBusError error; dbus_connection_get_object_path_data(iface->con, path, (void **) &obj_desc); if (!obj_desc) { - wpa_printf(MSG_ERROR, "dbus: wpa_dbus_get_object_properties: " - "could not obtain object's private data: %s", path); - return; + wpa_printf(MSG_ERROR, "dbus: %s: could not obtain object's " + "private data: %s", __func__, path); + return FALSE; + } + + if (!wpa_dbus_dict_open_write(iter, &dict_iter)) { + wpa_printf(MSG_ERROR, "dbus: %s: failed to open message dict", + __func__); + return FALSE; + } + + dbus_error_init(&error); + if (!fill_dict_with_properties(&dict_iter, obj_desc->properties, + interface, obj_desc->user_data, + &error)) { + wpa_printf(MSG_ERROR, "dbus: %s: failed to get object" + " properties: (%s) %s", __func__, + dbus_error_is_set(&error) ? error.name : "none", + dbus_error_is_set(&error) ? error.message : "none"); + dbus_error_free(&error); + return FALSE; } - fill_dict_with_properties(dict_iter, obj_desc->properties, - interface, obj_desc->user_data); + return wpa_dbus_dict_close_write(iter, &dict_iter); } /** @@ -955,3 +1036,32 @@ char *wpas_dbus_new_decompose_object_path(const char *path, return obj_path_only; } + + +/** + * wpas_dbus_reply_new_from_error - Create a new D-Bus error message from a + * dbus error structure + * @message: The original request message for which the error is a reply + * @error: The error containing a name and a descriptive error cause + * @fallback_name: A generic error name if @error was not set + * @fallback_string: A generic error string if @error was not set + * Returns: A new D-Bus error message + * + * Given a DBusMessage structure, creates a new D-Bus error message using + * the error name and string contained in that structure. + */ +DBusMessage * wpas_dbus_reply_new_from_error(DBusMessage *message, + DBusError *error, + const char *fallback_name, + const char *fallback_string) +{ + if (error && error->name && error->message) { + return dbus_message_new_error(message, error->name, + error->message); + } + if (fallback_name && fallback_string) { + return dbus_message_new_error(message, fallback_name, + fallback_string); + } + return NULL; +} diff --git a/wpa_supplicant/dbus/dbus_new_helpers.h b/wpa_supplicant/dbus/dbus_new_helpers.h index fd21c22..d6e7b48 100644 --- a/wpa_supplicant/dbus/dbus_new_helpers.h +++ b/wpa_supplicant/dbus/dbus_new_helpers.h @@ -22,8 +22,9 @@ typedef DBusMessage * (* WPADBusMethodHandler)(DBusMessage *message, void *user_data); typedef void (* WPADBusArgumentFreeFunction)(void *handler_arg); -typedef DBusMessage * (* WPADBusPropertyAccessor)(DBusMessage *message, - const void *user_data); +typedef dbus_bool_t (* WPADBusPropertyAccessor)(DBusMessageIter *iter, + DBusError *error, + void *user_data); struct wpa_dbus_object_desc { DBusConnection *connection; @@ -44,8 +45,6 @@ struct wpa_dbus_object_desc { WPADBusArgumentFreeFunction user_data_free_func; }; -enum dbus_prop_access { R, W, RW }; - enum dbus_arg_direction { ARG_IN, ARG_OUT }; struct wpa_dbus_argument { @@ -67,7 +66,7 @@ struct wpa_dbus_method_desc { /* method handling function */ WPADBusMethodHandler method_handler; /* array of arguments */ - struct wpa_dbus_argument args[3]; + struct wpa_dbus_argument args[4]; }; /** @@ -79,7 +78,7 @@ struct wpa_dbus_signal_desc { /* signal interface */ const char *dbus_interface; /* array of arguments */ - struct wpa_dbus_argument args[3]; + struct wpa_dbus_argument args[4]; }; /** @@ -96,8 +95,6 @@ struct wpa_dbus_property_desc { WPADBusPropertyAccessor getter; /* property setter function */ WPADBusPropertyAccessor setter; - /* property access permissions */ - enum dbus_prop_access access; }; @@ -128,9 +125,10 @@ int wpa_dbus_unregister_object_per_iface( struct wpas_dbus_priv *ctrl_iface, const char *path); -void wpa_dbus_get_object_properties(struct wpas_dbus_priv *iface, - const char *path, const char *interface, - DBusMessageIter *dict_iter); +dbus_bool_t wpa_dbus_get_object_properties(struct wpas_dbus_priv *iface, + const char *path, + const char *interface, + DBusMessageIter *iter); void wpa_dbus_flush_all_changed_properties(DBusConnection *con); @@ -150,4 +148,9 @@ char *wpas_dbus_new_decompose_object_path(const char *path, char **network, char **bssid); +DBusMessage *wpas_dbus_reply_new_from_error(DBusMessage *message, + DBusError *error, + const char *fallback_name, + const char *fallback_string); + #endif /* WPA_DBUS_CTRL_H */ diff --git a/wpa_supplicant/dbus/dbus_new_introspect.c b/wpa_supplicant/dbus/dbus_new_introspect.c index fd433df..fb29f20 100644 --- a/wpa_supplicant/dbus/dbus_new_introspect.c +++ b/wpa_supplicant/dbus/dbus_new_introspect.c @@ -89,10 +89,11 @@ static void add_entry(struct wpabuf *xml, const char *type, const char *name, static void add_property(struct wpabuf *xml, const struct wpa_dbus_property_desc *dsc) { - wpabuf_printf(xml, "", + wpabuf_printf(xml, "", dsc->dbus_property, dsc->type, - (dsc->access == R ? "read" : - (dsc->access == W ? "write" : "readwrite"))); + dsc->getter ? "read" : "", + dsc->setter ? "write" : ""); } diff --git a/wpa_supplicant/dbus/dbus_old.c b/wpa_supplicant/dbus/dbus_old.c index d255e14..71ab61e 100644 --- a/wpa_supplicant/dbus/dbus_old.c +++ b/wpa_supplicant/dbus/dbus_old.c @@ -23,7 +23,6 @@ #include "../bss.h" #include "dbus_old.h" #include "dbus_old_handlers.h" -#include "dbus_common.h" #include "dbus_common_i.h" diff --git a/wpa_supplicant/dbus/dbus_old_handlers.c b/wpa_supplicant/dbus/dbus_old_handlers.c index 39fe241..a7eabf3 100644 --- a/wpa_supplicant/dbus/dbus_old_handlers.c +++ b/wpa_supplicant/dbus/dbus_old_handlers.c @@ -116,7 +116,7 @@ DBusMessage * wpas_dbus_global_add_interface(DBusMessage *message, DBusMessageIter iter_dict; struct wpa_dbus_dict_entry entry; - if (!wpa_dbus_dict_open_read(&iter, &iter_dict)) + if (!wpa_dbus_dict_open_read(&iter, &iter_dict, NULL)) goto error; while (wpa_dbus_dict_has_dict_entry(&iter_dict)) { if (!wpa_dbus_dict_get_entry(&iter_dict, &entry)) @@ -229,7 +229,7 @@ DBusMessage * wpas_dbus_global_remove_interface(DBusMessage *message, goto out; } - if (!wpa_supplicant_remove_iface(global, wpa_s, 0)) { + if (!wpa_supplicant_remove_iface(global, wpa_s)) { reply = wpas_dbus_new_success_reply(message); } else { reply = dbus_message_new_error(message, @@ -922,7 +922,7 @@ DBusMessage * wpas_dbus_iface_set_network(DBusMessage *message, dbus_message_iter_init(message, &iter); - if (!wpa_dbus_dict_open_read(&iter, &iter_dict)) { + if (!wpa_dbus_dict_open_read(&iter, &iter_dict, NULL)) { reply = wpas_dbus_new_invalid_opts_error(message, NULL); goto out; } @@ -1202,7 +1202,7 @@ DBusMessage * wpas_dbus_iface_set_smartcard_modules( if (!dbus_message_iter_init(message, &iter)) goto error; - if (!wpa_dbus_dict_open_read(&iter, &iter_dict)) + if (!wpa_dbus_dict_open_read(&iter, &iter_dict, NULL)) goto error; while (wpa_dbus_dict_has_dict_entry(&iter_dict)) { @@ -1324,7 +1324,7 @@ DBusMessage * wpas_dbus_iface_set_blobs(DBusMessage *message, dbus_message_iter_init(message, &iter); - if (!wpa_dbus_dict_open_read(&iter, &iter_dict)) + if (!wpa_dbus_dict_open_read(&iter, &iter_dict, NULL)) return wpas_dbus_new_invalid_opts_error(message, NULL); while (wpa_dbus_dict_has_dict_entry(&iter_dict)) { diff --git a/wpa_supplicant/dbus/fi.epitest.hostap.WPASupplicant.service b/wpa_supplicant/dbus/fi.epitest.hostap.WPASupplicant.service deleted file mode 100644 index a9ce1ec..0000000 --- a/wpa_supplicant/dbus/fi.epitest.hostap.WPASupplicant.service +++ /dev/null @@ -1,4 +0,0 @@ -[D-BUS Service] -Name=fi.epitest.hostap.WPASupplicant -Exec=/sbin/wpa_supplicant -u -User=root diff --git a/wpa_supplicant/dbus/fi.w1.wpa_supplicant1.service b/wpa_supplicant/dbus/fi.w1.wpa_supplicant1.service deleted file mode 100644 index df78471..0000000 --- a/wpa_supplicant/dbus/fi.w1.wpa_supplicant1.service +++ /dev/null @@ -1,4 +0,0 @@ -[D-BUS Service] -Name=fi.w1.wpa_supplicant1 -Exec=/sbin/wpa_supplicant -u -User=root -- cgit v1.1