dbus: clean up new D-Bus interface getters and setters

A number of fixes/improvements here:

1) Remove casting of getter/setter function types which allows
us to change the prototypes in the future and not have hard-to-find
runtime segfaults

2) Instead of having the getters create a fake reply message which
then gets its arguments copied into the real reply message, and is
then disposed, just pass message iters around and have them add
their arguments to the message itself

3) For setters, just pass in the message iter positioned at the
start of the argument list, instead of each setter having to skip
over the standard interface+property name

4) Convert error handling to use DBusError and return the error
back down through the call stacks to the function that will
actually send the error back to the caller, instead of having a
fake DBusMessage of type DBUS_MESSAGE_TYPE_ERROR that then
needs to have the error extracted from it.

But most of all, this fixes various segfaults (like rh #725517
and #678625) which were caused by some functions deep down in the
getter callpaths wanting a source DBusMessage* when the getters were
used for two things: signals (which don't have a source DBusMessage)
and methods (which will have a source DBusMessage that's being
replied to).  This duality made the code fragile when handling
errors like invalid IEs over the air.

Signed-off-by: Dan Williams <dcbw@redhat.com>
This commit is contained in:
Dan Williams 2011-07-29 21:25:39 +03:00 committed by Jouni Malinen
parent e783c9b0e5
commit 6aeeb6fa21
11 changed files with 1373 additions and 1370 deletions

View file

@ -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 A valid DBusMessageIter pointing to the start of the dict
* @param iter_dict (out) A DBusMessageIter to be passed to * @param iter_dict (out) A DBusMessageIter to be passed to
* wpa_dbus_dict_read_next_entry() * wpa_dbus_dict_read_next_entry()
* @error on failure a descriptive error
* @return TRUE on success, FALSE on failure * @return TRUE on success, FALSE on failure
* *
*/ */
dbus_bool_t wpa_dbus_dict_open_read(DBusMessageIter *iter, 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; return FALSE;
}
if (dbus_message_iter_get_arg_type(iter) != DBUS_TYPE_ARRAY || 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; return FALSE;
}
dbus_message_iter_recurse(iter, iter_dict); dbus_message_iter_recurse(iter, iter_dict);
return TRUE; return TRUE;

View file

@ -156,7 +156,8 @@ struct wpa_dbus_dict_entry {
}; };
dbus_bool_t wpa_dbus_dict_open_read(DBusMessageIter *iter, 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, dbus_bool_t wpa_dbus_dict_get_entry(DBusMessageIter *iter_dict,
struct wpa_dbus_dict_entry *entry); struct wpa_dbus_dict_entry *entry);

View file

@ -45,7 +45,7 @@ static void wpas_dbus_signal_interface(struct wpa_supplicant *wpa_s,
{ {
struct wpas_dbus_priv *iface; struct wpas_dbus_priv *iface;
DBusMessage *msg; DBusMessage *msg;
DBusMessageIter iter, iter_dict; DBusMessageIter iter;
iface = wpa_s->global->dbus; iface = wpa_s->global->dbus;
@ -64,14 +64,9 @@ static void wpas_dbus_signal_interface(struct wpa_supplicant *wpa_s,
goto err; goto err;
if (properties) { if (properties) {
if (!wpa_dbus_dict_open_write(&iter, &iter_dict)) if (!wpa_dbus_get_object_properties(
goto err; iface, wpa_s->dbus_new_path,
WPAS_DBUS_NEW_IFACE_INTERFACE, &iter))
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))
goto err; goto err;
} }
@ -160,7 +155,7 @@ static void wpas_dbus_signal_bss(struct wpa_supplicant *wpa_s,
{ {
struct wpas_dbus_priv *iface; struct wpas_dbus_priv *iface;
DBusMessage *msg; DBusMessage *msg;
DBusMessageIter iter, iter_dict; DBusMessageIter iter;
iface = wpa_s->global->dbus; iface = wpa_s->global->dbus;
@ -180,14 +175,9 @@ static void wpas_dbus_signal_bss(struct wpa_supplicant *wpa_s,
goto err; goto err;
if (properties) { if (properties) {
if (!wpa_dbus_dict_open_write(&iter, &iter_dict)) if (!wpa_dbus_get_object_properties(iface, bss_obj_path,
goto err;
wpa_dbus_get_object_properties(iface, bss_obj_path,
WPAS_DBUS_NEW_IFACE_BSS, WPAS_DBUS_NEW_IFACE_BSS,
&iter_dict); &iter))
if (!wpa_dbus_dict_close_write(&iter, &iter_dict))
goto err; goto err;
} }
@ -307,7 +297,7 @@ static void wpas_dbus_signal_network(struct wpa_supplicant *wpa_s,
{ {
struct wpas_dbus_priv *iface; struct wpas_dbus_priv *iface;
DBusMessage *msg; DBusMessage *msg;
DBusMessageIter iter, iter_dict; DBusMessageIter iter;
char net_obj_path[WPAS_DBUS_OBJECT_PATH_MAX], *path; char net_obj_path[WPAS_DBUS_OBJECT_PATH_MAX], *path;
iface = wpa_s->global->dbus; iface = wpa_s->global->dbus;
@ -333,14 +323,9 @@ static void wpas_dbus_signal_network(struct wpa_supplicant *wpa_s,
goto err; goto err;
if (properties) { if (properties) {
if (!wpa_dbus_dict_open_write(&iter, &iter_dict)) if (!wpa_dbus_get_object_properties(
goto err; iface, net_obj_path, WPAS_DBUS_NEW_IFACE_NETWORK,
&iter))
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))
goto err; goto err;
} }
@ -1345,7 +1330,7 @@ static void wpas_dbus_signal_persistent_group(struct wpa_supplicant *wpa_s,
{ {
struct wpas_dbus_priv *iface; struct wpas_dbus_priv *iface;
DBusMessage *msg; DBusMessage *msg;
DBusMessageIter iter, iter_dict; DBusMessageIter iter;
char pgrp_obj_path[WPAS_DBUS_OBJECT_PATH_MAX], *path; char pgrp_obj_path[WPAS_DBUS_OBJECT_PATH_MAX], *path;
iface = wpa_s->global->dbus; iface = wpa_s->global->dbus;
@ -1371,15 +1356,9 @@ static void wpas_dbus_signal_persistent_group(struct wpa_supplicant *wpa_s,
goto err; goto err;
if (properties) { if (properties) {
if (!wpa_dbus_dict_open_write(&iter, &iter_dict)) if (!wpa_dbus_get_object_properties(
goto err;
wpa_dbus_get_object_properties(
iface, pgrp_obj_path, iface, pgrp_obj_path,
WPAS_DBUS_NEW_IFACE_PERSISTENT_GROUP, WPAS_DBUS_NEW_IFACE_PERSISTENT_GROUP, &iter))
&iter_dict);
if (!wpa_dbus_dict_close_write(&iter, &iter_dict))
goto err; goto err;
} }
@ -1491,34 +1470,31 @@ void wpas_dbus_signal_prop_changed(struct wpa_supplicant *wpa_s,
switch (property) { switch (property) {
case WPAS_DBUS_PROP_AP_SCAN: case WPAS_DBUS_PROP_AP_SCAN:
getter = (WPADBusPropertyAccessor) wpas_dbus_getter_ap_scan; getter = wpas_dbus_getter_ap_scan;
prop = "ApScan"; prop = "ApScan";
break; break;
case WPAS_DBUS_PROP_SCANNING: case WPAS_DBUS_PROP_SCANNING:
getter = (WPADBusPropertyAccessor) wpas_dbus_getter_scanning; getter = wpas_dbus_getter_scanning;
prop = "Scanning"; prop = "Scanning";
break; break;
case WPAS_DBUS_PROP_STATE: case WPAS_DBUS_PROP_STATE:
getter = (WPADBusPropertyAccessor) wpas_dbus_getter_state; getter = wpas_dbus_getter_state;
prop = "State"; prop = "State";
break; break;
case WPAS_DBUS_PROP_CURRENT_BSS: case WPAS_DBUS_PROP_CURRENT_BSS:
getter = (WPADBusPropertyAccessor) getter = wpas_dbus_getter_current_bss;
wpas_dbus_getter_current_bss;
prop = "CurrentBSS"; prop = "CurrentBSS";
break; break;
case WPAS_DBUS_PROP_CURRENT_NETWORK: case WPAS_DBUS_PROP_CURRENT_NETWORK:
getter = (WPADBusPropertyAccessor) getter = wpas_dbus_getter_current_network;
wpas_dbus_getter_current_network;
prop = "CurrentNetwork"; prop = "CurrentNetwork";
break; break;
case WPAS_DBUS_PROP_BSSS: case WPAS_DBUS_PROP_BSSS:
getter = (WPADBusPropertyAccessor) wpas_dbus_getter_bsss; getter = wpas_dbus_getter_bsss;
prop = "BSSs"; prop = "BSSs";
break; break;
case WPAS_DBUS_PROP_CURRENT_AUTH_MODE: case WPAS_DBUS_PROP_CURRENT_AUTH_MODE:
getter = (WPADBusPropertyAccessor) getter = wpas_dbus_getter_current_auth_mode;
wpas_dbus_getter_current_auth_mode;
prop = "CurrentAuthMode"; prop = "CurrentAuthMode";
break; break;
default: default:
@ -1685,27 +1661,27 @@ static const struct wpa_dbus_method_desc wpas_dbus_global_methods[] = {
static const struct wpa_dbus_property_desc wpas_dbus_global_properties[] = { static const struct wpa_dbus_property_desc wpas_dbus_global_properties[] = {
{ "DebugLevel", WPAS_DBUS_NEW_INTERFACE, "s", { "DebugLevel", WPAS_DBUS_NEW_INTERFACE, "s",
(WPADBusPropertyAccessor) wpas_dbus_getter_debug_level, wpas_dbus_getter_debug_level,
(WPADBusPropertyAccessor) wpas_dbus_setter_debug_level, wpas_dbus_setter_debug_level,
RW RW
}, },
{ "DebugTimestamp", WPAS_DBUS_NEW_INTERFACE, "b", { "DebugTimestamp", WPAS_DBUS_NEW_INTERFACE, "b",
(WPADBusPropertyAccessor) wpas_dbus_getter_debug_timestamp, wpas_dbus_getter_debug_timestamp,
(WPADBusPropertyAccessor) wpas_dbus_setter_debug_timestamp, wpas_dbus_setter_debug_timestamp,
RW RW
}, },
{ "DebugShowKeys", WPAS_DBUS_NEW_INTERFACE, "b", { "DebugShowKeys", WPAS_DBUS_NEW_INTERFACE, "b",
(WPADBusPropertyAccessor) wpas_dbus_getter_debug_show_keys, wpas_dbus_getter_debug_show_keys,
(WPADBusPropertyAccessor) wpas_dbus_setter_debug_show_keys, wpas_dbus_setter_debug_show_keys,
RW RW
}, },
{ "Interfaces", WPAS_DBUS_NEW_INTERFACE, "ao", { "Interfaces", WPAS_DBUS_NEW_INTERFACE, "ao",
(WPADBusPropertyAccessor) &wpas_dbus_getter_interfaces, wpas_dbus_getter_interfaces,
NULL, NULL,
R R
}, },
{ "EapMethods", WPAS_DBUS_NEW_INTERFACE, "as", { "EapMethods", WPAS_DBUS_NEW_INTERFACE, "as",
(WPADBusPropertyAccessor) wpas_dbus_getter_eap_methods, wpas_dbus_getter_eap_methods,
NULL, NULL,
R R
}, },
@ -1802,13 +1778,13 @@ static void wpa_dbus_free(void *ptr)
static const struct wpa_dbus_property_desc wpas_dbus_network_properties[] = { static const struct wpa_dbus_property_desc wpas_dbus_network_properties[] = {
{ "Properties", WPAS_DBUS_NEW_IFACE_NETWORK, "a{sv}", { "Properties", WPAS_DBUS_NEW_IFACE_NETWORK, "a{sv}",
(WPADBusPropertyAccessor) wpas_dbus_getter_network_properties, wpas_dbus_getter_network_properties,
(WPADBusPropertyAccessor) wpas_dbus_setter_network_properties, wpas_dbus_setter_network_properties,
RW RW
}, },
{ "Enabled", WPAS_DBUS_NEW_IFACE_NETWORK, "b", { "Enabled", WPAS_DBUS_NEW_IFACE_NETWORK, "b",
(WPADBusPropertyAccessor) wpas_dbus_getter_enabled, wpas_dbus_getter_enabled,
(WPADBusPropertyAccessor) wpas_dbus_setter_enabled, wpas_dbus_setter_enabled,
RW RW
}, },
{ NULL, NULL, NULL, NULL, NULL, 0 } { NULL, NULL, NULL, NULL, NULL, 0 }
@ -1949,52 +1925,52 @@ int wpas_dbus_unregister_network(struct wpa_supplicant *wpa_s, int nid)
static const struct wpa_dbus_property_desc wpas_dbus_bss_properties[] = { static const struct wpa_dbus_property_desc wpas_dbus_bss_properties[] = {
{ "SSID", WPAS_DBUS_NEW_IFACE_BSS, "ay", { "SSID", WPAS_DBUS_NEW_IFACE_BSS, "ay",
(WPADBusPropertyAccessor) wpas_dbus_getter_bss_ssid, wpas_dbus_getter_bss_ssid,
NULL, NULL,
R R
}, },
{ "BSSID", WPAS_DBUS_NEW_IFACE_BSS, "ay", { "BSSID", WPAS_DBUS_NEW_IFACE_BSS, "ay",
(WPADBusPropertyAccessor) wpas_dbus_getter_bss_bssid, wpas_dbus_getter_bss_bssid,
NULL, NULL,
R R
}, },
{ "Privacy", WPAS_DBUS_NEW_IFACE_BSS, "b", { "Privacy", WPAS_DBUS_NEW_IFACE_BSS, "b",
(WPADBusPropertyAccessor) wpas_dbus_getter_bss_privacy, wpas_dbus_getter_bss_privacy,
NULL, NULL,
R R
}, },
{ "Mode", WPAS_DBUS_NEW_IFACE_BSS, "s", { "Mode", WPAS_DBUS_NEW_IFACE_BSS, "s",
(WPADBusPropertyAccessor) wpas_dbus_getter_bss_mode, wpas_dbus_getter_bss_mode,
NULL, NULL,
R R
}, },
{ "Signal", WPAS_DBUS_NEW_IFACE_BSS, "n", { "Signal", WPAS_DBUS_NEW_IFACE_BSS, "n",
(WPADBusPropertyAccessor) wpas_dbus_getter_bss_signal, wpas_dbus_getter_bss_signal,
NULL, NULL,
R R
}, },
{ "Frequency", WPAS_DBUS_NEW_IFACE_BSS, "q", { "Frequency", WPAS_DBUS_NEW_IFACE_BSS, "q",
(WPADBusPropertyAccessor) wpas_dbus_getter_bss_frequency, wpas_dbus_getter_bss_frequency,
NULL, NULL,
R R
}, },
{ "Rates", WPAS_DBUS_NEW_IFACE_BSS, "au", { "Rates", WPAS_DBUS_NEW_IFACE_BSS, "au",
(WPADBusPropertyAccessor) wpas_dbus_getter_bss_rates, wpas_dbus_getter_bss_rates,
NULL, NULL,
R R
}, },
{ "WPA", WPAS_DBUS_NEW_IFACE_BSS, "a{sv}", { "WPA", WPAS_DBUS_NEW_IFACE_BSS, "a{sv}",
(WPADBusPropertyAccessor) wpas_dbus_getter_bss_wpa, wpas_dbus_getter_bss_wpa,
NULL, NULL,
R R
}, },
{ "RSN", WPAS_DBUS_NEW_IFACE_BSS, "a{sv}", { "RSN", WPAS_DBUS_NEW_IFACE_BSS, "a{sv}",
(WPADBusPropertyAccessor) wpas_dbus_getter_bss_rsn, wpas_dbus_getter_bss_rsn,
NULL, NULL,
R R
}, },
{ "IEs", WPAS_DBUS_NEW_IFACE_BSS, "ay", { "IEs", WPAS_DBUS_NEW_IFACE_BSS, "ay",
(WPADBusPropertyAccessor) wpas_dbus_getter_bss_ies, wpas_dbus_getter_bss_ies,
NULL, NULL,
R R
}, },
@ -2378,104 +2354,104 @@ static const struct wpa_dbus_method_desc wpas_dbus_interface_methods[] = {
static const struct wpa_dbus_property_desc wpas_dbus_interface_properties[] = { static const struct wpa_dbus_property_desc wpas_dbus_interface_properties[] = {
{ "Capabilities", WPAS_DBUS_NEW_IFACE_INTERFACE, "a{sv}", { "Capabilities", WPAS_DBUS_NEW_IFACE_INTERFACE, "a{sv}",
(WPADBusPropertyAccessor) wpas_dbus_getter_capabilities, wpas_dbus_getter_capabilities,
NULL, R NULL, R
}, },
{ "State", WPAS_DBUS_NEW_IFACE_INTERFACE, "s", { "State", WPAS_DBUS_NEW_IFACE_INTERFACE, "s",
(WPADBusPropertyAccessor) wpas_dbus_getter_state, wpas_dbus_getter_state,
NULL, R NULL, R
}, },
{ "Scanning", WPAS_DBUS_NEW_IFACE_INTERFACE, "b", { "Scanning", WPAS_DBUS_NEW_IFACE_INTERFACE, "b",
(WPADBusPropertyAccessor) wpas_dbus_getter_scanning, wpas_dbus_getter_scanning,
NULL, R NULL, R
}, },
{ "ApScan", WPAS_DBUS_NEW_IFACE_INTERFACE, "u", { "ApScan", WPAS_DBUS_NEW_IFACE_INTERFACE, "u",
(WPADBusPropertyAccessor) wpas_dbus_getter_ap_scan, wpas_dbus_getter_ap_scan,
(WPADBusPropertyAccessor) wpas_dbus_setter_ap_scan, wpas_dbus_setter_ap_scan,
RW RW
}, },
{ "BSSExpireAge", WPAS_DBUS_NEW_IFACE_INTERFACE, "u", { "BSSExpireAge", WPAS_DBUS_NEW_IFACE_INTERFACE, "u",
(WPADBusPropertyAccessor) wpas_dbus_getter_bss_expire_age, wpas_dbus_getter_bss_expire_age,
(WPADBusPropertyAccessor) wpas_dbus_setter_bss_expire_age, wpas_dbus_setter_bss_expire_age,
RW RW
}, },
{ "BSSExpireCount", WPAS_DBUS_NEW_IFACE_INTERFACE, "u", { "BSSExpireCount", WPAS_DBUS_NEW_IFACE_INTERFACE, "u",
(WPADBusPropertyAccessor) wpas_dbus_getter_bss_expire_count, wpas_dbus_getter_bss_expire_count,
(WPADBusPropertyAccessor) wpas_dbus_setter_bss_expire_count, wpas_dbus_setter_bss_expire_count,
RW RW
}, },
{ "Country", WPAS_DBUS_NEW_IFACE_INTERFACE, "s", { "Country", WPAS_DBUS_NEW_IFACE_INTERFACE, "s",
(WPADBusPropertyAccessor) wpas_dbus_getter_country, wpas_dbus_getter_country,
(WPADBusPropertyAccessor) wpas_dbus_setter_country, wpas_dbus_setter_country,
RW RW
}, },
{ "Ifname", WPAS_DBUS_NEW_IFACE_INTERFACE, "s", { "Ifname", WPAS_DBUS_NEW_IFACE_INTERFACE, "s",
(WPADBusPropertyAccessor) wpas_dbus_getter_ifname, wpas_dbus_getter_ifname,
NULL, R NULL, R
}, },
{ "Driver", WPAS_DBUS_NEW_IFACE_INTERFACE, "s", { "Driver", WPAS_DBUS_NEW_IFACE_INTERFACE, "s",
(WPADBusPropertyAccessor) wpas_dbus_getter_driver, wpas_dbus_getter_driver,
NULL, R NULL, R
}, },
{ "BridgeIfname", WPAS_DBUS_NEW_IFACE_INTERFACE, "s", { "BridgeIfname", WPAS_DBUS_NEW_IFACE_INTERFACE, "s",
(WPADBusPropertyAccessor) wpas_dbus_getter_bridge_ifname, wpas_dbus_getter_bridge_ifname,
NULL, R NULL, R
}, },
{ "CurrentBSS", WPAS_DBUS_NEW_IFACE_INTERFACE, "o", { "CurrentBSS", WPAS_DBUS_NEW_IFACE_INTERFACE, "o",
(WPADBusPropertyAccessor) wpas_dbus_getter_current_bss, wpas_dbus_getter_current_bss,
NULL, R NULL, R
}, },
{ "CurrentNetwork", WPAS_DBUS_NEW_IFACE_INTERFACE, "o", { "CurrentNetwork", WPAS_DBUS_NEW_IFACE_INTERFACE, "o",
(WPADBusPropertyAccessor) wpas_dbus_getter_current_network, wpas_dbus_getter_current_network,
NULL, R NULL, R
}, },
{ "CurrentAuthMode", WPAS_DBUS_NEW_IFACE_INTERFACE, "s", { "CurrentAuthMode", WPAS_DBUS_NEW_IFACE_INTERFACE, "s",
(WPADBusPropertyAccessor) wpas_dbus_getter_current_auth_mode, wpas_dbus_getter_current_auth_mode,
NULL, R NULL, R
}, },
{ "Blobs", WPAS_DBUS_NEW_IFACE_INTERFACE, "a{say}", { "Blobs", WPAS_DBUS_NEW_IFACE_INTERFACE, "a{say}",
(WPADBusPropertyAccessor) wpas_dbus_getter_blobs, wpas_dbus_getter_blobs,
NULL, R NULL, R
}, },
{ "BSSs", WPAS_DBUS_NEW_IFACE_INTERFACE, "ao", { "BSSs", WPAS_DBUS_NEW_IFACE_INTERFACE, "ao",
(WPADBusPropertyAccessor) wpas_dbus_getter_bsss, wpas_dbus_getter_bsss,
NULL, R NULL, R
}, },
{ "Networks", WPAS_DBUS_NEW_IFACE_INTERFACE, "ao", { "Networks", WPAS_DBUS_NEW_IFACE_INTERFACE, "ao",
(WPADBusPropertyAccessor) wpas_dbus_getter_networks, wpas_dbus_getter_networks,
NULL, R NULL, R
}, },
#ifdef CONFIG_WPS #ifdef CONFIG_WPS
{ "ProcessCredentials", WPAS_DBUS_NEW_IFACE_WPS, "b", { "ProcessCredentials", WPAS_DBUS_NEW_IFACE_WPS, "b",
(WPADBusPropertyAccessor) wpas_dbus_getter_process_credentials, wpas_dbus_getter_process_credentials,
(WPADBusPropertyAccessor) wpas_dbus_setter_process_credentials, wpas_dbus_setter_process_credentials,
RW RW
}, },
#endif /* CONFIG_WPS */ #endif /* CONFIG_WPS */
#ifdef CONFIG_P2P #ifdef CONFIG_P2P
{ "P2PDeviceProperties", WPAS_DBUS_NEW_IFACE_P2PDEVICE, "a{sv}", { "P2PDeviceProperties", WPAS_DBUS_NEW_IFACE_P2PDEVICE, "a{sv}",
(WPADBusPropertyAccessor) wpas_dbus_getter_p2p_device_properties, wpas_dbus_getter_p2p_device_properties,
(WPADBusPropertyAccessor) wpas_dbus_setter_p2p_device_properties, wpas_dbus_setter_p2p_device_properties,
RW RW
}, },
{ "Peers", WPAS_DBUS_NEW_IFACE_P2PDEVICE, "ao", { "Peers", WPAS_DBUS_NEW_IFACE_P2PDEVICE, "ao",
(WPADBusPropertyAccessor) wpas_dbus_getter_p2p_peers, wpas_dbus_getter_p2p_peers,
NULL, R NULL, R
}, },
{ "Role", WPAS_DBUS_NEW_IFACE_P2PDEVICE, "s", { "Role", WPAS_DBUS_NEW_IFACE_P2PDEVICE, "s",
(WPADBusPropertyAccessor) wpas_dbus_getter_p2p_role, wpas_dbus_getter_p2p_role,
NULL, R NULL, R
}, },
{ "Group", WPAS_DBUS_NEW_IFACE_P2PDEVICE, "o", { "Group", WPAS_DBUS_NEW_IFACE_P2PDEVICE, "o",
(WPADBusPropertyAccessor) wpas_dbus_getter_p2p_group, wpas_dbus_getter_p2p_group,
NULL, R NULL, R
}, },
{ "PeerGO", WPAS_DBUS_NEW_IFACE_P2PDEVICE, "o", { "PeerGO", WPAS_DBUS_NEW_IFACE_P2PDEVICE, "o",
(WPADBusPropertyAccessor) wpas_dbus_getter_p2p_peergo, wpas_dbus_getter_p2p_peergo,
NULL, R NULL, R
}, },
{ "PersistentGroups", WPAS_DBUS_NEW_IFACE_P2PDEVICE, "ao", { "PersistentGroups", WPAS_DBUS_NEW_IFACE_P2PDEVICE, "ao",
(WPADBusPropertyAccessor) wpas_dbus_getter_persistent_groups, wpas_dbus_getter_persistent_groups,
NULL, R NULL, R
}, },
#endif /* CONFIG_P2P */ #endif /* CONFIG_P2P */
@ -2784,11 +2760,11 @@ int wpas_dbus_unregister_interface(struct wpa_supplicant *wpa_s)
static const struct wpa_dbus_property_desc wpas_dbus_p2p_peer_properties[] = { static const struct wpa_dbus_property_desc wpas_dbus_p2p_peer_properties[] = {
{ "Properties", WPAS_DBUS_NEW_IFACE_P2P_PEER, "a{sv}", { "Properties", WPAS_DBUS_NEW_IFACE_P2P_PEER, "a{sv}",
(WPADBusPropertyAccessor) wpas_dbus_getter_p2p_peer_properties, wpas_dbus_getter_p2p_peer_properties,
NULL, R NULL, R
}, },
{ "IEs", WPAS_DBUS_NEW_IFACE_P2P_PEER, "ay", { "IEs", WPAS_DBUS_NEW_IFACE_P2P_PEER, "ay",
(WPADBusPropertyAccessor) wpas_dbus_getter_p2p_peer_ies, wpas_dbus_getter_p2p_peer_ies,
NULL, R NULL, R
}, },
{ NULL, NULL, NULL, NULL, NULL, 0 } { NULL, NULL, NULL, NULL, NULL, 0 }
@ -2981,13 +2957,13 @@ int wpas_dbus_unregister_peer(struct wpa_supplicant *wpa_s,
static const struct wpa_dbus_property_desc wpas_dbus_p2p_group_properties[] = { static const struct wpa_dbus_property_desc wpas_dbus_p2p_group_properties[] = {
{ "Members", WPAS_DBUS_NEW_IFACE_P2P_GROUP, "ao", { "Members", WPAS_DBUS_NEW_IFACE_P2P_GROUP, "ao",
(WPADBusPropertyAccessor) wpas_dbus_getter_p2p_group_members, wpas_dbus_getter_p2p_group_members,
NULL, R NULL, R
}, },
{ "Properties", { "Properties",
WPAS_DBUS_NEW_IFACE_P2P_GROUP, "a{sv}", WPAS_DBUS_NEW_IFACE_P2P_GROUP, "a{sv}",
(WPADBusPropertyAccessor) wpas_dbus_getter_p2p_group_properties, wpas_dbus_getter_p2p_group_properties,
(WPADBusPropertyAccessor) wpas_dbus_setter_p2p_group_properties, wpas_dbus_setter_p2p_group_properties,
RW RW
}, },
{ NULL, NULL, NULL, NULL, NULL, 0 } { NULL, NULL, NULL, NULL, NULL, 0 }
@ -3111,7 +3087,7 @@ void wpas_dbus_unregister_p2p_group(struct wpa_supplicant *wpa_s,
static const struct wpa_dbus_property_desc static const struct wpa_dbus_property_desc
wpas_dbus_p2p_groupmember_properties[] = { wpas_dbus_p2p_groupmember_properties[] = {
{ "Properties", WPAS_DBUS_NEW_IFACE_P2P_GROUPMEMBER, "a{sv}", { "Properties", WPAS_DBUS_NEW_IFACE_P2P_GROUPMEMBER, "a{sv}",
(WPADBusPropertyAccessor) wpas_dbus_getter_p2p_group_properties, wpas_dbus_getter_p2p_group_properties,
NULL, R NULL, R
}, },
{ NULL, NULL, NULL, NULL, NULL, 0 } { NULL, NULL, NULL, NULL, NULL, 0 }
@ -3218,9 +3194,7 @@ void wpas_dbus_unregister_p2p_groupmember(struct wpa_supplicant *wpa_s,
static const struct wpa_dbus_property_desc static const struct wpa_dbus_property_desc
wpas_dbus_persistent_group_properties[] = { wpas_dbus_persistent_group_properties[] = {
{ "Properties", WPAS_DBUS_NEW_IFACE_PERSISTENT_GROUP, "a{sv}", { "Properties", WPAS_DBUS_NEW_IFACE_PERSISTENT_GROUP, "a{sv}",
(WPADBusPropertyAccessor)
wpas_dbus_getter_persistent_group_properties, wpas_dbus_getter_persistent_group_properties,
(WPADBusPropertyAccessor)
wpas_dbus_setter_persistent_group_properties, wpas_dbus_setter_persistent_group_properties,
RW RW
}, },

File diff suppressed because it is too large Load diff

View file

@ -26,17 +26,20 @@ struct bss_handler_args {
unsigned int id; unsigned int id;
}; };
DBusMessage * wpas_dbus_simple_property_getter(DBusMessage *message, dbus_bool_t wpas_dbus_simple_property_getter(DBusMessageIter *iter,
const int type, const int type,
const void *val); const void *val,
DBusError *error);
DBusMessage * wpas_dbus_simple_property_setter(DBusMessage *message, dbus_bool_t wpas_dbus_simple_property_setter(DBusMessageIter *iter,
DBusError *error,
const int type, void *val); const int type, void *val);
DBusMessage * wpas_dbus_simple_array_property_getter(DBusMessage *message, dbus_bool_t wpas_dbus_simple_array_property_getter(DBusMessageIter *iter,
const int type, const int type,
const void *array, const void *array,
size_t array_len); size_t array_len,
DBusError *error);
DBusMessage * wpas_dbus_handler_create_interface(DBusMessage *message, DBusMessage * wpas_dbus_handler_create_interface(DBusMessage *message,
struct wpa_global *global); struct wpa_global *global);
@ -47,29 +50,35 @@ DBusMessage * wpas_dbus_handler_remove_interface(DBusMessage *message,
DBusMessage * wpas_dbus_handler_get_interface(DBusMessage *message, DBusMessage * wpas_dbus_handler_get_interface(DBusMessage *message,
struct wpa_global *global); struct wpa_global *global);
DBusMessage * wpas_dbus_getter_debug_level(DBusMessage *message, dbus_bool_t wpas_dbus_getter_debug_level(DBusMessageIter *iter,
struct wpa_global *global); DBusError *error,
void *user_data);
DBusMessage * wpas_dbus_getter_debug_timestamp(DBusMessage *message, dbus_bool_t wpas_dbus_getter_debug_timestamp(DBusMessageIter *iter,
struct wpa_global *global); DBusError *error,
void *user_data);
DBusMessage * wpas_dbus_getter_debug_show_keys(DBusMessage *message, dbus_bool_t wpas_dbus_getter_debug_show_keys(DBusMessageIter *iter,
struct wpa_global *global); DBusError *error,
void *user_data);
DBusMessage * wpas_dbus_setter_debug_level(DBusMessage *message, dbus_bool_t wpas_dbus_setter_debug_level(DBusMessageIter *iter,
struct wpa_global *global); DBusError *error, void *user_data);
DBusMessage * wpas_dbus_setter_debug_timestamp(DBusMessage *message, dbus_bool_t wpas_dbus_setter_debug_timestamp(DBusMessageIter *iter,
struct wpa_global *global); DBusError *error,
void *user_data);
DBusMessage * wpas_dbus_setter_debug_show_keys(DBusMessage *message, dbus_bool_t wpas_dbus_setter_debug_show_keys(DBusMessageIter *iter,
struct wpa_global *global); DBusError *error,
void *user_data);
DBusMessage * wpas_dbus_getter_interfaces(DBusMessage *message, dbus_bool_t wpas_dbus_getter_interfaces(DBusMessageIter *iter,
struct wpa_global *global); DBusError *error,
void *user_data);
DBusMessage * wpas_dbus_getter_eap_methods(DBusMessage *message, dbus_bool_t wpas_dbus_getter_eap_methods(DBusMessageIter *iter,
void *nothing); DBusError *error, void *user_data);
DBusMessage * wpas_dbus_handler_scan(DBusMessage *message, DBusMessage * wpas_dbus_handler_scan(DBusMessage *message,
struct wpa_supplicant *wpa_s); struct wpa_supplicant *wpa_s);
@ -77,10 +86,10 @@ DBusMessage * wpas_dbus_handler_scan(DBusMessage *message,
DBusMessage * wpas_dbus_handler_disconnect(DBusMessage *message, DBusMessage * wpas_dbus_handler_disconnect(DBusMessage *message,
struct wpa_supplicant *wpa_s); struct wpa_supplicant *wpa_s);
DBusMessage * set_network_properties(DBusMessage *message, dbus_bool_t set_network_properties(struct wpa_supplicant *wpa_s,
struct wpa_supplicant *wpa_s,
struct wpa_ssid *ssid, struct wpa_ssid *ssid,
DBusMessageIter *iter); DBusMessageIter *iter,
DBusError *error);
DBusMessage * wpas_dbus_handler_add_network(DBusMessage *message, DBusMessage * wpas_dbus_handler_add_network(DBusMessage *message,
struct wpa_supplicant *wpa_s); struct wpa_supplicant *wpa_s);
@ -106,119 +115,126 @@ DBusMessage * wpas_dbus_handler_remove_blob(DBusMessage *message,
DBusMessage * wpas_dbus_handler_flush_bss(DBusMessage *message, DBusMessage * wpas_dbus_handler_flush_bss(DBusMessage *message,
struct wpa_supplicant *wpa_s); struct wpa_supplicant *wpa_s);
DBusMessage * wpas_dbus_getter_capabilities(DBusMessage *message, dbus_bool_t wpas_dbus_getter_capabilities(DBusMessageIter *iter,
struct wpa_supplicant *wpa_s); DBusError *error, void *user_data);
DBusMessage * wpas_dbus_getter_state(DBusMessage *message, dbus_bool_t wpas_dbus_getter_state(DBusMessageIter *iter, DBusError *error,
struct wpa_supplicant *wpa_s); void *user_data);
DBusMessage * wpas_dbus_getter_scanning(DBusMessage *message, dbus_bool_t wpas_dbus_getter_scanning(DBusMessageIter *iter, DBusError *error,
struct wpa_supplicant *wpa_s); void *user_data);
DBusMessage * wpas_dbus_getter_ap_scan(DBusMessage *message, dbus_bool_t wpas_dbus_getter_ap_scan(DBusMessageIter *iter, DBusError *error,
struct wpa_supplicant *wpa_s); void *user_data);
DBusMessage * wpas_dbus_setter_ap_scan(DBusMessage *message, dbus_bool_t wpas_dbus_setter_ap_scan(DBusMessageIter *iter, DBusError *error,
struct wpa_supplicant *wpa_s); void *user_data);
DBusMessage * wpas_dbus_getter_bss_expire_age(DBusMessage *message, dbus_bool_t wpas_dbus_getter_bss_expire_age(DBusMessageIter *iter,
struct wpa_supplicant *wpa_s); DBusError *error, void *user_data);
DBusMessage * wpas_dbus_setter_bss_expire_age(DBusMessage *message, dbus_bool_t wpas_dbus_setter_bss_expire_age(DBusMessageIter *iter,
struct wpa_supplicant *wpa_s); DBusError *error,
void *user_data);
DBusMessage * wpas_dbus_getter_bss_expire_count(DBusMessage *message, dbus_bool_t wpas_dbus_getter_bss_expire_count(DBusMessageIter *iter,
struct wpa_supplicant *wpa_s); DBusError *error,
void *user_data);
DBusMessage * wpas_dbus_setter_bss_expire_count(DBusMessage *message, dbus_bool_t wpas_dbus_setter_bss_expire_count(DBusMessageIter *iter,
struct wpa_supplicant *wpa_s); DBusError *error,
void *user_data);
DBusMessage * wpas_dbus_getter_country(DBusMessage *message, dbus_bool_t wpas_dbus_getter_country(DBusMessageIter *iter, DBusError *error,
struct wpa_supplicant *wpa_s); void *user_data);
DBusMessage * wpas_dbus_setter_country(DBusMessage *message, dbus_bool_t wpas_dbus_setter_country(DBusMessageIter *iter, DBusError *error,
struct wpa_supplicant *wpa_s); void *user_data);
DBusMessage * wpas_dbus_getter_ifname(DBusMessage *message, dbus_bool_t wpas_dbus_getter_ifname(DBusMessageIter *iter, DBusError *error,
struct wpa_supplicant *wpa_s); void *user_data);
DBusMessage * wpas_dbus_getter_driver(DBusMessage *message, dbus_bool_t wpas_dbus_getter_driver(DBusMessageIter *iter, DBusError *error,
struct wpa_supplicant *wpa_s); void *user_data);
DBusMessage * wpas_dbus_getter_bridge_ifname(DBusMessage *message, dbus_bool_t wpas_dbus_getter_bridge_ifname(DBusMessageIter *iter,
struct wpa_supplicant *wpa_s); DBusError *error,
void *user_data);
DBusMessage * wpas_dbus_getter_current_bss(DBusMessage *message, dbus_bool_t wpas_dbus_getter_current_bss(DBusMessageIter *iter,
struct wpa_supplicant *wpa_s); DBusError *error,
void *user_data);
DBusMessage * wpas_dbus_getter_current_network(DBusMessage *message, dbus_bool_t wpas_dbus_getter_current_network(DBusMessageIter *iter,
struct wpa_supplicant *wpa_s); DBusError *error,
void *user_data);
DBusMessage * wpas_dbus_getter_current_auth_mode(DBusMessage *message, dbus_bool_t wpas_dbus_getter_current_auth_mode(DBusMessageIter *iter,
struct wpa_supplicant *wpa_s); DBusError *error,
void *user_data);
DBusMessage * wpas_dbus_getter_bsss(DBusMessage *message, dbus_bool_t wpas_dbus_getter_bsss(DBusMessageIter *iter, DBusError *error,
struct wpa_supplicant *wpa_s); void *user_data);
DBusMessage * wpas_dbus_getter_networks(DBusMessage *message, dbus_bool_t wpas_dbus_getter_networks(DBusMessageIter *iter, DBusError *error,
struct wpa_supplicant *wpa_s); void *user_data);
DBusMessage * wpas_dbus_getter_blobs(DBusMessage *message, dbus_bool_t wpas_dbus_getter_blobs(DBusMessageIter *iter, DBusError *error,
struct wpa_supplicant *bss); void *user_data);
DBusMessage * wpas_dbus_getter_bss_bssid(DBusMessage *message, dbus_bool_t wpas_dbus_getter_bss_bssid(DBusMessageIter *iter, DBusError *error,
struct bss_handler_args *bss); void *user_data);
DBusMessage * wpas_dbus_getter_bss_ssid(DBusMessage *message, dbus_bool_t wpas_dbus_getter_bss_ssid(DBusMessageIter *iter, DBusError *error,
struct bss_handler_args *bss); void *user_data);
DBusMessage * wpas_dbus_getter_bss_privacy(DBusMessage *message, dbus_bool_t wpas_dbus_getter_bss_privacy(DBusMessageIter *iter,
struct bss_handler_args *bss); DBusError *error, void *user_data);
DBusMessage * wpas_dbus_getter_bss_mode(DBusMessage *message, dbus_bool_t wpas_dbus_getter_bss_mode(DBusMessageIter *iter, DBusError *error,
struct bss_handler_args *bss); void *user_data);
DBusMessage * wpas_dbus_getter_bss_signal(DBusMessage *message, dbus_bool_t wpas_dbus_getter_bss_signal(DBusMessageIter *iter,
struct bss_handler_args *bss); DBusError *error, void *user_data);
DBusMessage * wpas_dbus_getter_bss_frequency(DBusMessage *message, dbus_bool_t wpas_dbus_getter_bss_frequency(DBusMessageIter *iter,
struct bss_handler_args *bss); DBusError *error, void *user_data);
DBusMessage * wpas_dbus_getter_bss_rates(DBusMessage *message, dbus_bool_t wpas_dbus_getter_bss_rates(DBusMessageIter *iter,
struct bss_handler_args *bss); DBusError *error, void *user_data);
DBusMessage * wpas_dbus_getter_bss_wpa(DBusMessage *message, dbus_bool_t wpas_dbus_getter_bss_wpa(DBusMessageIter *iter, DBusError *error,
struct bss_handler_args *bss); void *user_data);
DBusMessage * wpas_dbus_getter_bss_rsn(DBusMessage *message, dbus_bool_t wpas_dbus_getter_bss_rsn(DBusMessageIter *iter, DBusError *error,
struct bss_handler_args *bss); void *user_data);
DBusMessage * wpas_dbus_getter_bss_ies(DBusMessage *message, dbus_bool_t wpas_dbus_getter_bss_ies(DBusMessageIter *iter, DBusError *error,
struct bss_handler_args *bss); void *user_data);
DBusMessage * wpas_dbus_getter_enabled(DBusMessage *message, dbus_bool_t wpas_dbus_getter_enabled(DBusMessageIter *iter, DBusError *error,
struct network_handler_args *net); void *user_data);
DBusMessage * wpas_dbus_setter_enabled(DBusMessage *message, dbus_bool_t wpas_dbus_setter_enabled(DBusMessageIter *iter, DBusError *error,
struct network_handler_args *net); void *user_data);
DBusMessage * wpas_dbus_getter_network_properties( dbus_bool_t wpas_dbus_getter_network_properties(DBusMessageIter *iter,
DBusMessage *message, struct network_handler_args *net); DBusError *error,
void *user_data);
DBusMessage * wpas_dbus_setter_network_properties( dbus_bool_t wpas_dbus_setter_network_properties(DBusMessageIter *iter,
DBusMessage *message, struct network_handler_args *net); DBusError *error,
void *user_data);
DBusMessage * wpas_dbus_handler_wps_start(DBusMessage *message, DBusMessage * wpas_dbus_handler_wps_start(DBusMessage *message,
struct wpa_supplicant *wpa_s); struct wpa_supplicant *wpa_s);
DBusMessage * wpas_dbus_getter_process_credentials( dbus_bool_t wpas_dbus_getter_process_credentials(DBusMessageIter *iter,
DBusMessage *message, struct wpa_supplicant *wpa_s); DBusError *error, void *user_data);
DBusMessage * wpas_dbus_setter_process_credentials( dbus_bool_t wpas_dbus_setter_process_credentials(DBusMessageIter *iter,
DBusMessage *message, struct wpa_supplicant *wpa_s); DBusError *error,
void *user_data);
DBusMessage * wpas_dbus_getter_credentials(DBusMessage *message,
struct wpa_supplicant *wpa_s);
DBusMessage * wpas_dbus_error_invalid_args(DBusMessage *message, DBusMessage * wpas_dbus_error_invalid_args(DBusMessage *message,
const char *arg); const char *arg);

View file

@ -86,7 +86,7 @@ DBusMessage * wpas_dbus_handler_p2p_find(DBusMessage *message,
dbus_message_iter_init(message, &iter); dbus_message_iter_init(message, &iter);
entry.key = NULL; entry.key = NULL;
if (!wpa_dbus_dict_open_read(&iter, &iter_dict)) if (!wpa_dbus_dict_open_read(&iter, &iter_dict, NULL))
goto error; goto error;
while (wpa_dbus_dict_has_dict_entry(&iter_dict)) { while (wpa_dbus_dict_has_dict_entry(&iter_dict)) {
@ -192,7 +192,7 @@ DBusMessage * wpas_dbus_handler_p2p_extendedlisten(
dbus_message_iter_init(message, &iter); dbus_message_iter_init(message, &iter);
entry.key = NULL; entry.key = NULL;
if (!wpa_dbus_dict_open_read(&iter, &iter_dict)) if (!wpa_dbus_dict_open_read(&iter, &iter_dict, NULL))
goto error; goto error;
while (wpa_dbus_dict_has_dict_entry(&iter_dict)) { while (wpa_dbus_dict_has_dict_entry(&iter_dict)) {
@ -234,7 +234,7 @@ DBusMessage * wpas_dbus_handler_p2p_presence_request(
dbus_message_iter_init(message, &iter); dbus_message_iter_init(message, &iter);
entry.key = NULL; entry.key = NULL;
if (!wpa_dbus_dict_open_read(&iter, &iter_dict)) if (!wpa_dbus_dict_open_read(&iter, &iter_dict, NULL))
goto error; goto error;
while (wpa_dbus_dict_has_dict_entry(&iter_dict)) { while (wpa_dbus_dict_has_dict_entry(&iter_dict)) {
@ -288,7 +288,7 @@ DBusMessage * wpas_dbus_handler_p2p_group_add(DBusMessage *message,
dbus_message_iter_init(message, &iter); 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; goto inv_args;
while (wpa_dbus_dict_has_dict_entry(&iter_dict)) { while (wpa_dbus_dict_has_dict_entry(&iter_dict)) {
@ -406,7 +406,7 @@ DBusMessage * wpas_dbus_handler_p2p_connect(DBusMessage *message,
dbus_message_iter_init(message, &iter); 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; goto inv_args;
while (wpa_dbus_dict_has_dict_entry(&iter_dict)) { while (wpa_dbus_dict_has_dict_entry(&iter_dict)) {
@ -536,7 +536,7 @@ DBusMessage * wpas_dbus_handler_p2p_invite(DBusMessage *message,
dbus_message_iter_init(message, &iter); 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; goto err;
while (wpa_dbus_dict_has_dict_entry(&iter_dict)) { while (wpa_dbus_dict_has_dict_entry(&iter_dict)) {
@ -661,11 +661,12 @@ DBusMessage * wpas_dbus_handler_p2p_prov_disc_req(DBusMessage *message,
* P2P Device property accessor methods. * P2P Device property accessor methods.
*/ */
DBusMessage * wpas_dbus_getter_p2p_device_properties( dbus_bool_t wpas_dbus_getter_p2p_device_properties(DBusMessageIter *iter,
DBusMessage *message, struct wpa_supplicant *wpa_s) DBusError *error,
void *user_data)
{ {
DBusMessage *reply = NULL; struct wpa_supplicant *wpa_s = user_data;
DBusMessageIter iter, variant_iter, dict_iter; DBusMessageIter variant_iter, dict_iter;
DBusMessageIter iter_secdev_dict_entry, iter_secdev_dict_val, DBusMessageIter iter_secdev_dict_entry, iter_secdev_dict_val,
iter_secdev_dict_array; iter_secdev_dict_array;
const char *dev_name; const char *dev_name;
@ -673,17 +674,7 @@ DBusMessage * wpas_dbus_getter_p2p_device_properties(
int i; int i;
const struct wpabuf *vendor_ext[P2P_MAX_WPS_VENDOR_EXT]; const struct wpabuf *vendor_ext[P2P_MAX_WPS_VENDOR_EXT];
if (message == NULL) if (!dbus_message_iter_open_container(iter, DBUS_TYPE_VARIANT,
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,
"a{sv}", &variant_iter) || "a{sv}", &variant_iter) ||
!wpa_dbus_dict_open_write(&variant_iter, &dict_iter)) !wpa_dbus_dict_open_write(&variant_iter, &dict_iter))
goto err_no_mem; goto err_no_mem;
@ -791,44 +782,42 @@ DBusMessage * wpas_dbus_getter_p2p_device_properties(
goto err_no_mem; goto err_no_mem;
if (!wpa_dbus_dict_close_write(&variant_iter, &dict_iter) || 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; goto err_no_mem;
return reply; return TRUE;
err_no_mem: err_no_mem:
dbus_message_unref(reply); dbus_set_error_const(error, DBUS_ERROR_NO_MEMORY, "no memory");
return dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY, NULL); return FALSE;
} }
DBusMessage * wpas_dbus_setter_p2p_device_properties( dbus_bool_t wpas_dbus_setter_p2p_device_properties(DBusMessageIter *iter,
DBusMessage *message, struct wpa_supplicant *wpa_s) DBusError *error,
void *user_data)
{ {
DBusMessage *reply = NULL; struct wpa_supplicant *wpa_s = user_data;
DBusMessageIter iter, variant_iter; DBusMessageIter variant_iter, iter_dict;
struct wpa_dbus_dict_entry entry = {.type = DBUS_TYPE_STRING }; struct wpa_dbus_dict_entry entry = {.type = DBUS_TYPE_STRING };
DBusMessageIter iter_dict;
unsigned int i; unsigned int i;
dbus_message_iter_init(message, &iter); dbus_message_iter_recurse(iter, &variant_iter);
if (!wpa_dbus_dict_open_read(&variant_iter, &iter_dict, error))
dbus_message_iter_next(&iter); return FALSE;
dbus_message_iter_next(&iter);
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);
while (wpa_dbus_dict_has_dict_entry(&iter_dict)) { while (wpa_dbus_dict_has_dict_entry(&iter_dict)) {
if (!wpa_dbus_dict_get_entry(&iter_dict, &entry)) if (!wpa_dbus_dict_get_entry(&iter_dict, &entry)) {
return wpas_dbus_error_invalid_args(message, NULL); dbus_set_error_const(error, DBUS_ERROR_INVALID_ARGS,
"invalid message format");
return FALSE;
}
if (os_strcmp(entry.key, "DeviceName") == 0) { if (os_strcmp(entry.key, "DeviceName") == 0) {
char *devname; char *devname;
if (entry.type != DBUS_TYPE_STRING) if (entry.type != DBUS_TYPE_STRING)
goto error_clear; goto error;
devname = os_strdup(entry.str_value); devname = os_strdup(entry.str_value);
if (devname == NULL) if (devname == NULL)
@ -843,7 +832,7 @@ DBusMessage * wpas_dbus_setter_p2p_device_properties(
if (entry.type != DBUS_TYPE_ARRAY || if (entry.type != DBUS_TYPE_ARRAY ||
entry.array_type != DBUS_TYPE_BYTE || entry.array_type != DBUS_TYPE_BYTE ||
entry.array_len != WPS_DEV_TYPE_LEN) entry.array_len != WPS_DEV_TYPE_LEN)
goto error_clear; goto error;
os_memcpy(wpa_s->conf->device_type, os_memcpy(wpa_s->conf->device_type,
entry.bytearray_value, entry.bytearray_value,
@ -871,7 +860,7 @@ DBusMessage * wpas_dbus_setter_p2p_device_properties(
if ((entry.type != DBUS_TYPE_ARRAY) || if ((entry.type != DBUS_TYPE_ARRAY) ||
(entry.array_type != WPAS_DBUS_TYPE_BINARRAY) || (entry.array_type != WPAS_DBUS_TYPE_BINARRAY) ||
(entry.array_len > P2P_MAX_WPS_VENDOR_EXT)) (entry.array_len > P2P_MAX_WPS_VENDOR_EXT))
goto error_clear; goto error;
wpa_s->conf->changed_parameters |= wpa_s->conf->changed_parameters |=
CFG_CHANGED_VENDOR_EXTENSION; CFG_CHANGED_VENDOR_EXTENSION;
@ -916,7 +905,7 @@ DBusMessage * wpas_dbus_setter_p2p_device_properties(
char *postfix; char *postfix;
if (entry.type != DBUS_TYPE_STRING) if (entry.type != DBUS_TYPE_STRING)
goto error_clear; goto error;
postfix = os_strdup(entry.str_value); postfix = os_strdup(entry.str_value);
if (!postfix) if (!postfix)
@ -939,7 +928,7 @@ DBusMessage * wpas_dbus_setter_p2p_device_properties(
entry.type == DBUS_TYPE_UINT32) entry.type == DBUS_TYPE_UINT32)
wpa_s->conf->disassoc_low_ack = entry.uint32_value; wpa_s->conf->disassoc_low_ack = entry.uint32_value;
else else
goto error_clear; goto error;
wpa_dbus_dict_entry_clear(&entry); wpa_dbus_dict_entry_clear(&entry);
} }
@ -949,30 +938,31 @@ DBusMessage * wpas_dbus_setter_p2p_device_properties(
wpa_supplicant_update_config(wpa_s); wpa_supplicant_update_config(wpa_s);
} }
return reply; return TRUE;
error_clear:
wpa_dbus_dict_entry_clear(&entry);
error: 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); wpa_dbus_dict_entry_clear(&entry);
return FALSE;
return reply;
err_no_mem_clear: err_no_mem_clear:
dbus_set_error_const(error, DBUS_ERROR_NO_MEMORY, "no memory");
wpa_dbus_dict_entry_clear(&entry); 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, dbus_bool_t wpas_dbus_getter_p2p_peers(DBusMessageIter *iter, DBusError *error,
struct wpa_supplicant *wpa_s) void *user_data)
{ {
DBusMessage *reply = NULL; struct wpa_supplicant *wpa_s = user_data;
struct p2p_data *p2p = wpa_s->global->p2p; struct p2p_data *p2p = wpa_s->global->p2p;
int next = 0, i = 0; int next = 0, i = 0;
int num = 0, out_of_mem = 0; int num = 0, out_of_mem = 0;
const u8 *addr; const u8 *addr;
const struct p2p_peer_info *peer_info = NULL; const struct p2p_peer_info *peer_info = NULL;
dbus_bool_t success = FALSE;
struct dl_list peer_objpath_list; struct dl_list peer_objpath_list;
struct peer_objpath_node { struct peer_objpath_node {
@ -1022,9 +1012,10 @@ DBusMessage * wpas_dbus_getter_p2p_peers(DBusMessage *message,
struct peer_objpath_node, list) struct peer_objpath_node, list)
peer_obj_paths[i++] = node->path; peer_obj_paths[i++] = node->path;
reply = wpas_dbus_simple_array_property_getter(message, success = wpas_dbus_simple_array_property_getter(iter,
DBUS_TYPE_OBJECT_PATH, DBUS_TYPE_OBJECT_PATH,
peer_obj_paths, num); peer_obj_paths, num,
error);
error: error:
if (peer_obj_paths) if (peer_obj_paths)
@ -1036,10 +1027,9 @@ error:
os_free(node); os_free(node);
} }
if (out_of_mem) if (out_of_mem)
reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY, dbus_set_error_const(error, DBUS_ERROR_NO_MEMORY, "no memory");
NULL);
return reply; return success;
} }
@ -1072,9 +1062,10 @@ static enum wpas_p2p_role wpas_get_p2p_role(struct wpa_supplicant *wpa_s)
} }
DBusMessage * wpas_dbus_getter_p2p_role(DBusMessage *message, dbus_bool_t wpas_dbus_getter_p2p_role(DBusMessageIter *iter, DBusError *error,
struct wpa_supplicant *wpa_s) void *user_data)
{ {
struct wpa_supplicant *wpa_s = user_data;
char *str; char *str;
switch (wpas_get_p2p_role(wpa_s)) { switch (wpas_get_p2p_role(wpa_s)) {
@ -1088,37 +1079,40 @@ DBusMessage * wpas_dbus_getter_p2p_role(DBusMessage *message,
str = "device"; str = "device";
} }
return wpas_dbus_simple_property_getter(message, DBUS_TYPE_STRING, return wpas_dbus_simple_property_getter(iter, DBUS_TYPE_STRING, &str,
&str); error);
} }
DBusMessage * wpas_dbus_getter_p2p_group(DBusMessage *message, dbus_bool_t wpas_dbus_getter_p2p_group(DBusMessageIter *iter, DBusError *error,
struct wpa_supplicant *wpa_s) void *user_data)
{ {
struct wpa_supplicant *wpa_s = user_data;
if (wpa_s->dbus_groupobj_path == NULL) if (wpa_s->dbus_groupobj_path == NULL)
return NULL; return FALSE;
return wpas_dbus_simple_property_getter(message, return wpas_dbus_simple_property_getter(iter, DBUS_TYPE_OBJECT_PATH,
DBUS_TYPE_OBJECT_PATH, &wpa_s->dbus_groupobj_path,
&wpa_s->dbus_groupobj_path); error);
} }
DBusMessage * wpas_dbus_getter_p2p_peergo(DBusMessage *message, dbus_bool_t wpas_dbus_getter_p2p_peergo(DBusMessageIter *iter,
struct wpa_supplicant *wpa_s) DBusError *error, void *user_data)
{ {
struct wpa_supplicant *wpa_s = user_data;
char go_peer_obj_path[WPAS_DBUS_OBJECT_PATH_MAX], *path; char go_peer_obj_path[WPAS_DBUS_OBJECT_PATH_MAX], *path;
if (wpas_get_p2p_role(wpa_s) != WPAS_P2P_ROLE_CLIENT) 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, os_snprintf(go_peer_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
"%s/" WPAS_DBUS_NEW_P2P_PEERS_PART "/" COMPACT_MACSTR, "%s/" WPAS_DBUS_NEW_P2P_PEERS_PART "/" COMPACT_MACSTR,
wpa_s->dbus_new_path, MAC2STR(wpa_s->go_dev_addr)); wpa_s->dbus_new_path, MAC2STR(wpa_s->go_dev_addr));
path = go_peer_obj_path; path = go_peer_obj_path;
return wpas_dbus_simple_property_getter(message, return wpas_dbus_simple_property_getter(iter, DBUS_TYPE_OBJECT_PATH,
DBUS_TYPE_OBJECT_PATH, &path); &path, error);
} }
@ -1126,11 +1120,11 @@ DBusMessage * wpas_dbus_getter_p2p_peergo(DBusMessage *message,
* Peer object properties accessor methods * Peer object properties accessor methods
*/ */
DBusMessage * wpas_dbus_getter_p2p_peer_properties( dbus_bool_t wpas_dbus_getter_p2p_peer_properties(DBusMessageIter *iter,
DBusMessage *message, struct peer_handler_args *peer_args) DBusError *error, void *user_data)
{ {
DBusMessage *reply = NULL; struct peer_handler_args *peer_args = user_data;
DBusMessageIter iter, variant_iter, dict_iter; DBusMessageIter variant_iter, dict_iter;
const struct p2p_peer_info *info = NULL; const struct p2p_peer_info *info = NULL;
char devtype[WPS_DEV_TYPE_BUFSIZE]; char devtype[WPS_DEV_TYPE_BUFSIZE];
const struct wpabuf *vendor_extension[P2P_MAX_WPS_VENDOR_EXT]; const struct wpabuf *vendor_extension[P2P_MAX_WPS_VENDOR_EXT];
@ -1139,19 +1133,12 @@ DBusMessage * wpas_dbus_getter_p2p_peer_properties(
/* get the peer info */ /* get the peer info */
info = p2p_get_peer_found(peer_args->wpa_s->global->p2p, info = p2p_get_peer_found(peer_args->wpa_s->global->p2p,
peer_args->p2p_device_addr, 0); peer_args->p2p_device_addr, 0);
if (info == NULL) if (info == NULL) {
return NULL; dbus_set_error(error, DBUS_ERROR_FAILED, "failed to find peer");
return FALSE;
}
if (message == NULL) if (!dbus_message_iter_open_container(iter, DBUS_TYPE_VARIANT,
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,
"a{sv}", &variant_iter) || "a{sv}", &variant_iter) ||
!wpa_dbus_dict_open_write(&variant_iter, &dict_iter)) !wpa_dbus_dict_open_write(&variant_iter, &dict_iter))
goto err_no_mem; goto err_no_mem;
@ -1241,45 +1228,53 @@ DBusMessage * wpas_dbus_getter_p2p_peer_properties(
goto err_no_mem; goto err_no_mem;
if (!wpa_dbus_dict_close_write(&variant_iter, &dict_iter) || 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; goto err_no_mem;
return reply; return TRUE;
err_no_mem: err_no_mem:
dbus_message_unref(reply); dbus_set_error_const(error, DBUS_ERROR_NO_MEMORY, "no memory");
return dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY, NULL); return FALSE;
} }
DBusMessage * wpas_dbus_getter_p2p_peer_ies( dbus_bool_t wpas_dbus_getter_p2p_peer_ies(DBusMessageIter *iter,
DBusMessage *message, struct peer_handler_args *peer_args) 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 * wpas_dbus_getter_persistent_groups - Get array of peristent group objects
* @message: Pointer to incoming dbus message * @iter: Pointer to incoming dbus message iter
* @wpa_s: wpa_supplicant structure for a network interface * @error: Location to store error on failure
* Returns: a dbus message containing an array of all persistent group * @user_data: Function specific data
* dbus object paths. * Returns: TRUE on success, FALSE on failure
* *
* Getter for "Networks" property. * Getter for "PersistentGroups" property.
*/ */
DBusMessage * wpas_dbus_getter_persistent_groups(DBusMessage *message, dbus_bool_t wpas_dbus_getter_persistent_groups(DBusMessageIter *iter,
struct wpa_supplicant *wpa_s) DBusError *error,
void *user_data)
{ {
DBusMessage *reply = NULL; struct wpa_supplicant *wpa_s = user_data;
struct wpa_ssid *ssid; struct wpa_ssid *ssid;
char **paths; char **paths;
unsigned int i = 0, num = 0; unsigned int i = 0, num = 0;
dbus_bool_t success = FALSE;
if (wpa_s->conf == NULL) { if (wpa_s->conf == NULL) {
wpa_printf(MSG_ERROR, "dbus: %s: " wpa_printf(MSG_ERROR, "dbus: %s: "
"An error occurred getting persistent groups list", "An error occurred getting persistent groups list",
__func__); __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) for (ssid = wpa_s->conf->ssid; ssid; ssid = ssid->next)
@ -1288,8 +1283,8 @@ DBusMessage * wpas_dbus_getter_persistent_groups(DBusMessage *message,
paths = os_zalloc(num * sizeof(char *)); paths = os_zalloc(num * sizeof(char *));
if (!paths) { if (!paths) {
return dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY, dbus_set_error_const(error, DBUS_ERROR_NO_MEMORY, "no memory");
NULL); return FALSE;
} }
/* Loop through configured networks and append object path of each */ /* Loop through configured networks and append object path of each */
@ -1298,9 +1293,8 @@ DBusMessage * wpas_dbus_getter_persistent_groups(DBusMessage *message,
continue; continue;
paths[i] = os_zalloc(WPAS_DBUS_OBJECT_PATH_MAX); paths[i] = os_zalloc(WPAS_DBUS_OBJECT_PATH_MAX);
if (paths[i] == NULL) { if (paths[i] == NULL) {
reply = dbus_message_new_error(message, dbus_set_error_const(error, DBUS_ERROR_NO_MEMORY,
DBUS_ERROR_NO_MEMORY, "no memory");
NULL);
goto out; goto out;
} }
/* Construct the object path for this network. */ /* Construct the object path for this network. */
@ -1309,74 +1303,65 @@ DBusMessage * wpas_dbus_getter_persistent_groups(DBusMessage *message,
wpa_s->dbus_new_path, ssid->id); wpa_s->dbus_new_path, ssid->id);
} }
reply = wpas_dbus_simple_array_property_getter(message, success = wpas_dbus_simple_array_property_getter(iter,
DBUS_TYPE_OBJECT_PATH, DBUS_TYPE_OBJECT_PATH,
paths, num); paths, num, error);
out: out:
while (i) while (i)
os_free(paths[--i]); os_free(paths[--i]);
os_free(paths); os_free(paths);
return reply; return success;
} }
/** /**
* wpas_dbus_getter_persistent_group_properties - Get options for a persistent * wpas_dbus_getter_persistent_group_properties - Get options for a persistent
* group * group
* @message: Pointer to incoming dbus message * @iter: Pointer to incoming dbus message iter
* @net: wpa_supplicant structure for a network interface and * @error: Location to store error on failure
* wpa_ssid structure for a configured persistent group (internally network) * @user_data: Function specific data
* Returns: DBus message with network properties or DBus error on failure * Returns: TRUE on success, FALSE on failure
* *
* Getter for "Properties" property of a persistent group. * Getter for "Properties" property of a persistent group.
*/ */
DBusMessage * wpas_dbus_getter_persistent_group_properties( dbus_bool_t wpas_dbus_getter_persistent_group_properties(DBusMessageIter *iter,
DBusMessage *message, struct network_handler_args *net) DBusError *error,
void *user_data)
{ {
/* struct network_handler_args *net = user_data;
* Leveraging the fact that persistent group object is still
/* Leveraging the fact that persistent group object is still
* represented in same manner as network within. * 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 * wpas_dbus_setter_persistent_group_properties - Get options for a persistent
* group * group
* @message: Pointer to incoming dbus message * @iter: Pointer to incoming dbus message iter
* @net: wpa_supplicant structure for a network interface and * @error: Location to store error on failure
* wpa_ssid structure for a configured persistent group (internally network) * @user_data: Function specific data
* Returns: DBus message with network properties or DBus error on failure * Returns: TRUE on success, FALSE on failure
* *
* Setter for "Properties" property of a persistent group. * Setter for "Properties" property of a persistent group.
*/ */
DBusMessage * wpas_dbus_setter_persistent_group_properties( dbus_bool_t wpas_dbus_setter_persistent_group_properties(DBusMessageIter *iter,
DBusMessage *message, struct network_handler_args *net) DBusError *error,
void *user_data)
{ {
struct network_handler_args *net = user_data;
struct wpa_ssid *ssid = net->ssid; struct wpa_ssid *ssid = net->ssid;
DBusMessage *reply = NULL; DBusMessageIter variant_iter;
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);
/* /*
* Leveraging the fact that persistent group object is still * Leveraging the fact that persistent group object is still
* represented in same manner as network within. * represented in same manner as network within.
*/ */
reply = set_network_properties(message, net->wpa_s, ssid, dbus_message_iter_recurse(iter, &variant_iter);
&variant_iter); return set_network_properties(net->wpa_s, ssid, &variant_iter, error);
if (reply)
wpa_printf(MSG_DEBUG, "dbus control interface couldn't set "
"persistent group properties");
return reply;
} }
@ -1398,6 +1383,7 @@ DBusMessage * wpas_dbus_handler_add_persistent_group(
DBusMessageIter iter; DBusMessageIter iter;
struct wpa_ssid *ssid = NULL; struct wpa_ssid *ssid = NULL;
char path_buf[WPAS_DBUS_OBJECT_PATH_MAX], *path = path_buf; char path_buf[WPAS_DBUS_OBJECT_PATH_MAX], *path = path_buf;
DBusError error;
dbus_message_iter_init(message, &iter); dbus_message_iter_init(message, &iter);
@ -1419,11 +1405,16 @@ DBusMessage * wpas_dbus_handler_add_persistent_group(
wpa_config_set_network_defaults(ssid); wpa_config_set_network_defaults(ssid);
reply = set_network_properties(message, wpa_s, ssid, &iter); dbus_error_init(&error);
if (reply) { if (!set_network_properties(wpa_s, ssid, &iter, &error)) {
wpa_printf(MSG_DEBUG, "dbus: %s: " wpa_printf(MSG_DEBUG, "dbus: %s: "
"Control interface could not set persistent group " "Control interface could not set persistent group "
"properties", __func__); "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; goto err;
} }
@ -1569,27 +1560,29 @@ DBusMessage * wpas_dbus_handler_remove_all_persistent_groups(
* Group object properties accessor methods * Group object properties accessor methods
*/ */
DBusMessage * wpas_dbus_getter_p2p_group_members(DBusMessage *message, dbus_bool_t wpas_dbus_getter_p2p_group_members(DBusMessageIter *iter,
struct wpa_supplicant *wpa_s) DBusError *error,
void *user_data)
{ {
DBusMessage *reply = NULL; struct wpa_supplicant *wpa_s = user_data;
struct wpa_ssid *ssid; struct wpa_ssid *ssid;
unsigned int num_members; unsigned int num_members;
char **paths; char **paths;
unsigned int i; unsigned int i;
void *next = NULL; void *next = NULL;
const u8 *addr; const u8 *addr;
dbus_bool_t success = FALSE;
/* Ensure we are a GO */ /* Ensure we are a GO */
if (wpa_s->wpa_state != WPA_COMPLETED) if (wpa_s->wpa_state != WPA_COMPLETED)
return NULL; return FALSE;
ssid = wpa_s->conf->ssid; ssid = wpa_s->conf->ssid;
/* At present WPAS P2P_GO mode only applicable for p2p_go */ /* At present WPAS P2P_GO mode only applicable for p2p_go */
if (ssid->mode != WPAS_MODE_P2P_GO && if (ssid->mode != WPAS_MODE_P2P_GO &&
ssid->mode != WPAS_MODE_AP && ssid->mode != WPAS_MODE_AP &&
ssid->mode != WPAS_MODE_P2P_GROUP_FORMATION) ssid->mode != WPAS_MODE_P2P_GROUP_FORMATION)
return NULL; return FALSE;
num_members = p2p_get_group_num_members(wpa_s->p2p_group); num_members = p2p_get_group_num_members(wpa_s->p2p_group);
@ -1609,53 +1602,45 @@ DBusMessage * wpas_dbus_getter_p2p_group_members(DBusMessage *message,
i++; i++;
} }
reply = wpas_dbus_simple_array_property_getter(message, success = wpas_dbus_simple_array_property_getter(iter,
DBUS_TYPE_OBJECT_PATH, DBUS_TYPE_OBJECT_PATH,
paths, num_members); paths, num_members,
error);
for (i = 0; i < num_members; i++) for (i = 0; i < num_members; i++)
os_free(paths[i]); os_free(paths[i]);
os_free(paths); os_free(paths);
return reply; return success;
out_of_memory: out_of_memory:
reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY, NULL); dbus_set_error_const(error, DBUS_ERROR_NO_MEMORY, "no memory");
if (paths) { if (paths) {
for (i = 0; i < num_members; i++) for (i = 0; i < num_members; i++)
os_free(paths[i]); os_free(paths[i]);
os_free(paths); os_free(paths);
} }
return reply; return FALSE;
} }
DBusMessage * wpas_dbus_getter_p2p_group_properties( dbus_bool_t wpas_dbus_getter_p2p_group_properties(DBusMessageIter *iter,
DBusMessage *message, struct wpa_supplicant *wpa_s) DBusError *error,
void *user_data)
{ {
DBusMessage *reply = NULL; struct wpa_supplicant *wpa_s = user_data;
DBusMessageIter iter, variant_iter, dict_iter; DBusMessageIter variant_iter, dict_iter;
struct hostapd_data *hapd = wpa_s->ap_iface->bss[0]; struct hostapd_data *hapd = wpa_s->ap_iface->bss[0];
const struct wpabuf *vendor_ext[MAX_WPS_VENDOR_EXTENSIONS]; const struct wpabuf *vendor_ext[MAX_WPS_VENDOR_EXTENSIONS];
int num_vendor_ext = 0; int num_vendor_ext = 0;
int i; int i;
if (!hapd) { if (!hapd) {
reply = dbus_message_new_error(message, DBUS_ERROR_FAILED, dbus_set_error_const(error, DBUS_ERROR_FAILED,
NULL); "internal error");
return reply; return FALSE;
} }
if (message == NULL) if (!dbus_message_iter_open_container(iter, DBUS_TYPE_VARIANT,
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,
"a{sv}", &variant_iter) || "a{sv}", &variant_iter) ||
!wpa_dbus_dict_open_write(&variant_iter, &dict_iter)) !wpa_dbus_dict_open_write(&variant_iter, &dict_iter))
goto err_no_mem; goto err_no_mem;
@ -1673,44 +1658,42 @@ DBusMessage * wpas_dbus_getter_p2p_group_properties(
goto err_no_mem; goto err_no_mem;
if (!wpa_dbus_dict_close_write(&variant_iter, &dict_iter) || 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; goto err_no_mem;
return reply; return TRUE;
err_no_mem: err_no_mem:
dbus_message_unref(reply); dbus_set_error_const(error, DBUS_ERROR_NO_MEMORY, "no memory");
return dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY, NULL); return FALSE;
} }
DBusMessage * wpas_dbus_setter_p2p_group_properties( dbus_bool_t wpas_dbus_setter_p2p_group_properties(DBusMessageIter *iter,
DBusMessage *message, struct wpa_supplicant *wpa_s) DBusError *error,
void *user_data)
{ {
DBusMessage *reply = NULL; struct wpa_supplicant *wpa_s = user_data;
DBusMessageIter iter, variant_iter; DBusMessageIter variant_iter, iter_dict;
struct wpa_dbus_dict_entry entry = { .type = DBUS_TYPE_STRING }; struct wpa_dbus_dict_entry entry = { .type = DBUS_TYPE_STRING };
DBusMessageIter iter_dict;
unsigned int i; unsigned int i;
struct hostapd_data *hapd = wpa_s->ap_iface->bss[0]; struct hostapd_data *hapd = wpa_s->ap_iface->bss[0];
if (!hapd) if (!hapd) {
goto error; dbus_set_error_const(error, DBUS_ERROR_FAILED,
"internal error");
return FALSE;
}
dbus_message_iter_init(message, &iter); dbus_message_iter_recurse(iter, &variant_iter);
if (!wpa_dbus_dict_open_read(&variant_iter, &iter_dict, error))
dbus_message_iter_next(&iter); return FALSE;
dbus_message_iter_next(&iter);
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);
while (wpa_dbus_dict_has_dict_entry(&iter_dict)) { while (wpa_dbus_dict_has_dict_entry(&iter_dict)) {
if (!wpa_dbus_dict_get_entry(&iter_dict, &entry)) { if (!wpa_dbus_dict_get_entry(&iter_dict, &entry)) {
reply = wpas_dbus_error_invalid_args(message, NULL); dbus_set_error_const(error, DBUS_ERROR_INVALID_ARGS,
break; "invalid message format");
return FALSE;
} }
if (os_strcmp(entry.key, "WPSVendorExtensions") == 0) { if (os_strcmp(entry.key, "WPSVendorExtensions") == 0) {
@ -1735,13 +1718,13 @@ DBusMessage * wpas_dbus_setter_p2p_group_properties(
wpa_dbus_dict_entry_clear(&entry); wpa_dbus_dict_entry_clear(&entry);
} }
return reply; return TRUE;
error: error:
reply = wpas_dbus_error_invalid_args(message, entry.key);
wpa_dbus_dict_entry_clear(&entry); wpa_dbus_dict_entry_clear(&entry);
dbus_set_error_const(error, DBUS_ERROR_INVALID_ARGS,
return reply; "invalid message format");
return FALSE;
} }
@ -1761,7 +1744,7 @@ DBusMessage * wpas_dbus_handler_p2p_add_service(DBusMessage *message,
dbus_message_iter_init(message, &iter); 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; goto error;
if (wpa_dbus_dict_has_dict_entry(&iter_dict)) { if (wpa_dbus_dict_has_dict_entry(&iter_dict)) {
@ -1858,7 +1841,7 @@ DBusMessage * wpas_dbus_handler_p2p_delete_service(
dbus_message_iter_init(message, &iter); 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; goto error;
if (wpa_dbus_dict_has_dict_entry(&iter_dict)) { if (wpa_dbus_dict_has_dict_entry(&iter_dict)) {
@ -1960,7 +1943,7 @@ DBusMessage * wpas_dbus_handler_p2p_service_sd_req(
dbus_message_iter_init(message, &iter); 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; goto error;
while (wpa_dbus_dict_has_dict_entry(&iter_dict)) { while (wpa_dbus_dict_has_dict_entry(&iter_dict)) {
@ -2049,7 +2032,7 @@ DBusMessage * wpas_dbus_handler_p2p_service_sd_res(
dbus_message_iter_init(message, &iter); 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; goto error;
while (wpa_dbus_dict_has_dict_entry(&iter_dict)) { while (wpa_dbus_dict_has_dict_entry(&iter_dict)) {

View file

@ -94,61 +94,69 @@ DBusMessage *wpas_dbus_handler_p2p_serv_disc_external(
/* /*
* P2P Device property accessor methods. * P2P Device property accessor methods.
*/ */
DBusMessage *wpas_dbus_setter_p2p_device_properties(DBusMessage *message, dbus_bool_t wpas_dbus_setter_p2p_device_properties(DBusMessageIter *iter,
struct wpa_supplicant *wpa_s); DBusError *error,
void *user_data);
DBusMessage *wpas_dbus_getter_p2p_device_properties(DBusMessage *message, dbus_bool_t wpas_dbus_getter_p2p_device_properties(DBusMessageIter *iter,
struct wpa_supplicant *wpa_s); DBusError *error,
void *user_data);
DBusMessage *wpas_dbus_getter_p2p_peers(DBusMessage *message, dbus_bool_t wpas_dbus_getter_p2p_peers(DBusMessageIter *iter, DBusError *error,
struct wpa_supplicant *wpa_s); void *user_data);
DBusMessage *wpas_dbus_getter_p2p_role(DBusMessage *message, dbus_bool_t wpas_dbus_getter_p2p_role(DBusMessageIter *iter, DBusError *error,
struct wpa_supplicant *wpa_s); void *user_data);
DBusMessage *wpas_dbus_getter_p2p_group(DBusMessage *message, dbus_bool_t wpas_dbus_getter_p2p_group(DBusMessageIter *iter, DBusError *error,
struct wpa_supplicant *wpa_s); void *user_data);
DBusMessage *wpas_dbus_getter_p2p_peergo(DBusMessage *message, dbus_bool_t wpas_dbus_getter_p2p_peergo(DBusMessageIter *iter,
struct wpa_supplicant *wpa_s); DBusError *error,
void *user_data);
/* /*
* P2P Peer properties. * P2P Peer properties.
*/ */
DBusMessage *wpas_dbus_getter_p2p_peer_properties( dbus_bool_t wpas_dbus_getter_p2p_peer_properties(DBusMessageIter *iter,
DBusMessage *message, DBusError *error,
struct peer_handler_args *peer); void *user_data);
DBusMessage *wpas_dbus_getter_p2p_peer_ies( dbus_bool_t wpas_dbus_getter_p2p_peer_ies(DBusMessageIter *iter,
DBusMessage *message, DBusError *error,
struct peer_handler_args *peer); void *user_data);
/* /*
* P2P Group properties * P2P Group properties
*/ */
DBusMessage *wpas_dbus_getter_p2p_group_members( dbus_bool_t wpas_dbus_getter_p2p_group_members(DBusMessageIter *iter,
DBusMessage *message, DBusError *error,
struct wpa_supplicant *wpa_s); void *user_data);
DBusMessage *wpas_dbus_getter_p2p_group_properties( dbus_bool_t wpas_dbus_getter_p2p_group_properties(DBusMessageIter *iter,
DBusMessage *message, DBusError *error,
struct wpa_supplicant *wpa_s); void *user_data);
DBusMessage *wpas_dbus_setter_p2p_group_properties( dbus_bool_t wpas_dbus_setter_p2p_group_properties(DBusMessageIter *iter,
DBusMessage *message, DBusError *error,
struct wpa_supplicant *wpa_s); void *user_data);
/* /*
* P2P Persistent Groups and properties * P2P Persistent Groups and properties
*/ */
DBusMessage * wpas_dbus_getter_persistent_groups(DBusMessage *message, dbus_bool_t wpas_dbus_getter_persistent_groups(DBusMessageIter *iter,
struct wpa_supplicant *wpa_s); DBusError *error,
DBusMessage * wpas_dbus_getter_persistent_group_properties( void *user_data);
DBusMessage *message, struct network_handler_args *net);
DBusMessage * wpas_dbus_setter_persistent_group_properties( dbus_bool_t wpas_dbus_getter_persistent_group_properties(DBusMessageIter *iter,
DBusMessage *message, struct network_handler_args *net); 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 * wpas_dbus_handler_add_persistent_group(
DBusMessage *message, struct wpa_supplicant *wpa_s); DBusMessage *message, struct wpa_supplicant *wpa_s);

View file

@ -284,40 +284,43 @@ DBusMessage * wpas_dbus_handler_wps_start(DBusMessage *message,
* wpas_dbus_getter_process_credentials - Check if credentials are processed * wpas_dbus_getter_process_credentials - Check if credentials are processed
* @message: Pointer to incoming dbus message * @message: Pointer to incoming dbus message
* @wpa_s: %wpa_supplicant data structure * @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 * Getter for "ProcessCredentials" property. Returns returned boolean will be
* true if wps_cred_processing configuration field is not equal to 1 or false * true if wps_cred_processing configuration field is not equal to 1 or false
* if otherwise. * if otherwise.
*/ */
DBusMessage * wpas_dbus_getter_process_credentials( dbus_bool_t wpas_dbus_getter_process_credentials(DBusMessageIter *iter,
DBusMessage *message, struct wpa_supplicant *wpa_s) DBusError *error,
void *user_data)
{ {
struct wpa_supplicant *wpa_s = user_data;
dbus_bool_t process = (wpa_s->conf->wps_cred_processing != 1); dbus_bool_t process = (wpa_s->conf->wps_cred_processing != 1);
return wpas_dbus_simple_property_getter(message, DBUS_TYPE_BOOLEAN, return wpas_dbus_simple_property_getter(iter, DBUS_TYPE_BOOLEAN,
&process); &process, error);
} }
/** /**
* wpas_dbus_setter_process_credentials - Set credentials_processed conf param * wpas_dbus_setter_process_credentials - Set credentials_processed conf param
* @message: Pointer to incoming dbus message * @iter: Pointer to incoming dbus message iter
* @wpa_s: %wpa_supplicant data structure * @error: Location to store error on failure
* Returns: NULL on success or DBus error on failure * @user_data: Function specific data
* Returns: TRUE on success, FALSE on failure
* *
* Setter for "ProcessCredentials" property. Sets credentials_processed on 2 * Setter for "ProcessCredentials" property. Sets credentials_processed on 2
* if boolean argument is true or on 1 if otherwise. * if boolean argument is true or on 1 if otherwise.
*/ */
DBusMessage * wpas_dbus_setter_process_credentials( dbus_bool_t wpas_dbus_setter_process_credentials(DBusMessageIter *iter,
DBusMessage *message, struct wpa_supplicant *wpa_s) DBusError *error,
void *user_data)
{ {
DBusMessage *reply = NULL; struct wpa_supplicant *wpa_s = user_data;
dbus_bool_t process_credentials, old_pc; dbus_bool_t process_credentials, old_pc;
reply = wpas_dbus_simple_property_setter(message, DBUS_TYPE_BOOLEAN, if (!wpas_dbus_simple_property_setter(iter, error, DBUS_TYPE_BOOLEAN,
&process_credentials); &process_credentials))
if (reply) return FALSE;
return reply;
old_pc = (wpa_s->conf->wps_cred_processing != 1); old_pc = (wpa_s->conf->wps_cred_processing != 1);
wpa_s->conf->wps_cred_processing = (process_credentials ? 2 : 1); wpa_s->conf->wps_cred_processing = (process_credentials ? 2 : 1);
@ -328,5 +331,5 @@ DBusMessage * wpas_dbus_setter_process_credentials(
WPAS_DBUS_NEW_IFACE_WPS, WPAS_DBUS_NEW_IFACE_WPS,
"ProcessCredentials"); "ProcessCredentials");
return NULL; return TRUE;
} }

View file

@ -21,112 +21,50 @@
#include "dbus_common_i.h" #include "dbus_common_i.h"
#include "dbus_new.h" #include "dbus_new.h"
#include "dbus_new_helpers.h" #include "dbus_new_helpers.h"
#include "dbus_dict_helpers.h"
/** static dbus_bool_t fill_dict_with_properties(
* recursive_iter_copy - Reads arguments from one iterator and DBusMessageIter *dict_iter,
* writes to another recursively const struct wpa_dbus_property_desc *props,
* @from: iterator to read from const char *interface, void *user_data, DBusError *error)
* @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)
{ {
DBusMessageIter entry_iter;
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;
const struct wpa_dbus_property_desc *dsc; const struct wpa_dbus_property_desc *dsc;
for (dsc = props; dsc && dsc->dbus_property; dsc++) { for (dsc = props; dsc && dsc->dbus_property; dsc++) {
if (!os_strncmp(dsc->dbus_interface, interface, /* Only return properties for the requested D-Bus interface */
WPAS_DBUS_INTERFACE_MAX) && if (os_strncmp(dsc->dbus_interface, interface,
dsc->access != W && dsc->getter) { WPAS_DBUS_INTERFACE_MAX) != 0)
reply = dsc->getter(NULL, user_data);
if (!reply)
continue; continue;
if (dbus_message_get_type(reply) == /* Handle access permissions or missing getter */
DBUS_MESSAGE_TYPE_ERROR) { if (dsc->getter == NULL || dsc->access == W)
dbus_message_unref(reply);
continue; continue;
}
dbus_message_iter_init(reply, &ret_iter); if (!dbus_message_iter_open_container(dict_iter,
dbus_message_iter_open_container(dict_iter,
DBUS_TYPE_DICT_ENTRY, DBUS_TYPE_DICT_ENTRY,
NULL, &entry_iter); NULL, &entry_iter)) {
dbus_message_iter_append_basic( dbus_set_error_const(error, DBUS_ERROR_NO_MEMORY,
&entry_iter, DBUS_TYPE_STRING, "no memory");
&dsc->dbus_property); return FALSE;
recursive_iter_copy(&ret_iter, &entry_iter);
dbus_message_iter_close_container(dict_iter,
&entry_iter);
dbus_message_unref(reply);
counter++;
} }
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;
} }
return counter; /* 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);
}
return TRUE;
} }
@ -142,37 +80,44 @@ static unsigned int fill_dict_with_properties(
* specified as argument. Returned message contains one dict argument * specified as argument. Returned message contains one dict argument
* with properties names as keys and theirs values as values. * with properties names as keys and theirs values as values.
*/ */
static DBusMessage * get_all_properties( static DBusMessage * get_all_properties(DBusMessage *message, char *interface,
DBusMessage *message, char *interface,
struct wpa_dbus_object_desc *obj_dsc) struct wpa_dbus_object_desc *obj_dsc)
{ {
/* Create and initialize the return message */ DBusMessage *reply;
DBusMessage *reply = dbus_message_new_method_return(message);
DBusMessageIter iter, dict_iter; DBusMessageIter iter, dict_iter;
int props_num; DBusError error;
dbus_message_iter_init_append(reply, &iter); reply = dbus_message_new_method_return(message);
if (reply == NULL) {
dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, wpa_printf(MSG_ERROR, "%s: out of memory creating dbus reply",
DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING __func__);
DBUS_TYPE_STRING_AS_STRING return NULL;
DBUS_TYPE_VARIANT_AS_STRING
DBUS_DICT_ENTRY_END_CHAR_AS_STRING,
&dict_iter);
props_num = fill_dict_with_properties(&dict_iter, obj_dsc->properties,
interface, obj_dsc->user_data);
dbus_message_iter_close_container(&iter, &dict_iter);
if (props_num == 0) {
dbus_message_unref(reply);
reply = dbus_message_new_error(message,
DBUS_ERROR_INVALID_ARGS,
"No readable properties in "
"this interface");
} }
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;
}
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 = 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; return reply;
} }
@ -219,15 +164,33 @@ static DBusMessage * properties_get(DBusMessage *message,
const struct wpa_dbus_property_desc *dsc, const struct wpa_dbus_property_desc *dsc,
void *user_data) 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, return dbus_message_new_error(message, DBUS_ERROR_INVALID_ARGS,
NULL); NULL);
}
if (dsc->access != W && dsc->getter) if (dsc->access == W || dsc->getter == NULL) {
return dsc->getter(message, user_data);
return dbus_message_new_error(message, DBUS_ERROR_INVALID_ARGS, return dbus_message_new_error(message, DBUS_ERROR_INVALID_ARGS,
"Property is write-only"); "Property is write-only");
}
reply = dbus_message_new_method_return(message);
dbus_message_iter_init_append(reply, &iter);
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, const struct wpa_dbus_property_desc *dsc,
void *user_data) 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, return dbus_message_new_error(message, DBUS_ERROR_INVALID_ARGS,
NULL); NULL);
}
if (dsc->access != R && dsc->setter) if (dsc->access == R || dsc->setter == NULL) {
return dsc->setter(message, user_data);
return dbus_message_new_error(message, DBUS_ERROR_INVALID_ARGS, return dbus_message_new_error(message, DBUS_ERROR_INVALID_ARGS,
"Property is read-only"); "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);
/* 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 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, static dbus_bool_t put_changed_properties(
const char *interface, const struct wpa_dbus_object_desc *obj_dsc, const char *interface,
DBusMessageIter *dict_iter) DBusMessageIter *dict_iter)
{ {
DBusMessage *getter_reply; DBusMessageIter entry_iter;
DBusMessageIter prop_iter, entry_iter;
const struct wpa_dbus_property_desc *dsc; const struct wpa_dbus_property_desc *dsc;
int i; int i;
DBusError error;
for (dsc = obj_dsc->properties, i = 0; dsc && dsc->dbus_property; for (dsc = obj_dsc->properties, i = 0; dsc && dsc->dbus_property;
dsc++, i++) { dsc++, i++) {
@ -640,37 +626,37 @@ static void put_changed_properties(const struct wpa_dbus_object_desc *obj_dsc,
continue; continue;
obj_dsc->prop_changed_flags[i] = 0; obj_dsc->prop_changed_flags[i] = 0;
getter_reply = dsc->getter(NULL, obj_dsc->user_data); if (!dbus_message_iter_open_container(dict_iter,
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 (!dbus_message_iter_init(getter_reply, &prop_iter) ||
!dbus_message_iter_open_container(dict_iter,
DBUS_TYPE_DICT_ENTRY, DBUS_TYPE_DICT_ENTRY,
NULL, &entry_iter) || NULL, &entry_iter))
!dbus_message_iter_append_basic(&entry_iter, return FALSE;
if (!dbus_message_iter_append_basic(&entry_iter,
DBUS_TYPE_STRING, DBUS_TYPE_STRING,
&dsc->dbus_property)) &dsc->dbus_property))
goto err; return FALSE;
recursive_iter_copy(&prop_iter, &entry_iter); dbus_error_init(&error);
if (!dsc->getter(&entry_iter, &error, obj_dsc->user_data)) {
if (!dbus_message_iter_close_container(dict_iter, &entry_iter)) if (dbus_error_is_set (&error)) {
goto err; wpa_printf(MSG_ERROR, "dbus: %s: Cannot get "
"new value of property %s: (%s) %s",
dbus_message_unref(getter_reply); __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;
} }
return; if (!dbus_message_iter_close_container(dict_iter, &entry_iter))
return FALSE;
}
err: return TRUE;
wpa_printf(MSG_ERROR, "dbus: %s: Cannot construct signal", __func__);
} }
@ -691,7 +677,8 @@ static void send_prop_changed_signal(
"{sv}", &dict_iter)) "{sv}", &dict_iter))
goto err; goto err;
put_changed_properties(obj_dsc, interface, &dict_iter); if (!put_changed_properties(obj_dsc, interface, &dict_iter))
goto err;
if (!dbus_message_iter_close_container(&signal_iter, &dict_iter)) if (!dbus_message_iter_close_container(&signal_iter, &dict_iter))
goto err; goto err;
@ -860,29 +847,49 @@ void wpa_dbus_mark_property_changed(struct wpas_dbus_priv *iface,
* @iface: dbus priv struct * @iface: dbus priv struct
* @path: path to DBus object which properties will be obtained * @path: path to DBus object which properties will be obtained
* @interface: interface name 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 * Iterates over all properties registered with object and execute getters
* of those, which are readable and which interface matches interface * of those, which are readable and which interface matches interface
* specified as argument. Obtained properties values are stored in * specified as argument. Obtained properties values are stored in
* dict_iter dictionary. * dict_iter dictionary.
*/ */
void wpa_dbus_get_object_properties(struct wpas_dbus_priv *iface, dbus_bool_t wpa_dbus_get_object_properties(struct wpas_dbus_priv *iface,
const char *path, const char *interface, const char *path,
DBusMessageIter *dict_iter) const char *interface,
DBusMessageIter *iter)
{ {
struct wpa_dbus_object_desc *obj_desc = NULL; struct wpa_dbus_object_desc *obj_desc = NULL;
DBusMessageIter dict_iter;
DBusError error;
dbus_connection_get_object_path_data(iface->con, path, dbus_connection_get_object_path_data(iface->con, path,
(void **) &obj_desc); (void **) &obj_desc);
if (!obj_desc) { if (!obj_desc) {
wpa_printf(MSG_ERROR, "dbus: wpa_dbus_get_object_properties: " wpa_printf(MSG_ERROR, "dbus: %s: could not obtain object's "
"could not obtain object's private data: %s", path); "private data: %s", __func__, path);
return; return FALSE;
} }
fill_dict_with_properties(dict_iter, obj_desc->properties, if (!wpa_dbus_dict_open_write(iter, &dict_iter)) {
interface, obj_desc->user_data); 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;
}
return wpa_dbus_dict_close_write(iter, &dict_iter);
} }
/** /**
@ -955,3 +962,32 @@ char *wpas_dbus_new_decompose_object_path(const char *path,
return obj_path_only; 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;
}

View file

@ -22,8 +22,9 @@ typedef DBusMessage * (* WPADBusMethodHandler)(DBusMessage *message,
void *user_data); void *user_data);
typedef void (* WPADBusArgumentFreeFunction)(void *handler_arg); typedef void (* WPADBusArgumentFreeFunction)(void *handler_arg);
typedef DBusMessage * (* WPADBusPropertyAccessor)(DBusMessage *message, typedef dbus_bool_t (* WPADBusPropertyAccessor)(DBusMessageIter *iter,
const void *user_data); DBusError *error,
void *user_data);
struct wpa_dbus_object_desc { struct wpa_dbus_object_desc {
DBusConnection *connection; DBusConnection *connection;
@ -128,9 +129,10 @@ int wpa_dbus_unregister_object_per_iface(
struct wpas_dbus_priv *ctrl_iface, struct wpas_dbus_priv *ctrl_iface,
const char *path); const char *path);
void wpa_dbus_get_object_properties(struct wpas_dbus_priv *iface, dbus_bool_t wpa_dbus_get_object_properties(struct wpas_dbus_priv *iface,
const char *path, const char *interface, const char *path,
DBusMessageIter *dict_iter); const char *interface,
DBusMessageIter *iter);
void wpa_dbus_flush_all_changed_properties(DBusConnection *con); void wpa_dbus_flush_all_changed_properties(DBusConnection *con);
@ -150,4 +152,9 @@ char *wpas_dbus_new_decompose_object_path(const char *path,
char **network, char **network,
char **bssid); 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 */ #endif /* WPA_DBUS_CTRL_H */

View file

@ -116,7 +116,7 @@ DBusMessage * wpas_dbus_global_add_interface(DBusMessage *message,
DBusMessageIter iter_dict; DBusMessageIter iter_dict;
struct wpa_dbus_dict_entry entry; 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; goto error;
while (wpa_dbus_dict_has_dict_entry(&iter_dict)) { while (wpa_dbus_dict_has_dict_entry(&iter_dict)) {
if (!wpa_dbus_dict_get_entry(&iter_dict, &entry)) if (!wpa_dbus_dict_get_entry(&iter_dict, &entry))
@ -922,7 +922,7 @@ DBusMessage * wpas_dbus_iface_set_network(DBusMessage *message,
dbus_message_iter_init(message, &iter); 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); reply = wpas_dbus_new_invalid_opts_error(message, NULL);
goto out; goto out;
} }
@ -1202,7 +1202,7 @@ DBusMessage * wpas_dbus_iface_set_smartcard_modules(
if (!dbus_message_iter_init(message, &iter)) if (!dbus_message_iter_init(message, &iter))
goto error; goto error;
if (!wpa_dbus_dict_open_read(&iter, &iter_dict)) if (!wpa_dbus_dict_open_read(&iter, &iter_dict, NULL))
goto error; goto error;
while (wpa_dbus_dict_has_dict_entry(&iter_dict)) { 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); 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); return wpas_dbus_new_invalid_opts_error(message, NULL);
while (wpa_dbus_dict_has_dict_entry(&iter_dict)) { while (wpa_dbus_dict_has_dict_entry(&iter_dict)) {