[PATCH 2/2] dbus: expose interface globals via D-Bus properties
Dan Williams
dcbw
Wed Oct 7 15:16:58 PDT 2015
All interface globals are now exposed as D-Bus properties of type
string, and parsed via the normal interface global parsing functions.
Signed-off-by: Dan Williams <dcbw at redhat.com>
---
wpa_supplicant/config.c | 16 ++++++
wpa_supplicant/config.h | 3 ++
wpa_supplicant/dbus/dbus_new.c | 85 ++++++++++++++++++++++++++++++-
wpa_supplicant/dbus/dbus_new_handlers.c | 72 ++++++++++++++++++++++++++
wpa_supplicant/dbus/dbus_new_handlers.h | 2 +
wpa_supplicant/dbus/dbus_new_helpers.h | 2 +
wpa_supplicant/dbus/dbus_new_introspect.c | 2 +-
7 files changed, 179 insertions(+), 3 deletions(-)
diff --git a/wpa_supplicant/config.c b/wpa_supplicant/config.c
index b1adab7..5d085a3 100644
--- a/wpa_supplicant/config.c
+++ b/wpa_supplicant/config.c
@@ -4304,6 +4304,22 @@ int wpa_config_get_value(const char *name, struct wpa_config *config,
}
+int wpa_config_get_num_global_field_names(void)
+{
+ return NUM_GLOBAL_FIELDS;
+}
+
+const char * wpa_config_get_global_field_name(int i, int *no_var)
+{
+ if (i < 0 || i >= NUM_GLOBAL_FIELDS)
+ return NULL;
+
+ if (no_var && !global_fields[i].param1)
+ *no_var = 1;
+ return global_fields[i].name;
+}
+
+
int wpa_config_process_global(struct wpa_config *config, char *pos, int line)
{
size_t i;
diff --git a/wpa_supplicant/config.h b/wpa_supplicant/config.h
index 68d64fa..cca602e 100644
--- a/wpa_supplicant/config.h
+++ b/wpa_supplicant/config.h
@@ -1310,6 +1310,9 @@ void wpa_config_debug_dump_networks(struct wpa_config *config);
/* Prototypes for common functions from config.c */
int wpa_config_process_global(struct wpa_config *config, char *pos, int line);
+int wpa_config_get_num_global_field_names(void);
+
+const char * wpa_config_get_global_field_name(int i, int *no_var);
/* Prototypes for backend specific functions from the selected config_*.c */
diff --git a/wpa_supplicant/dbus/dbus_new.c b/wpa_supplicant/dbus/dbus_new.c
index 7d99ea3..7c8f7dc 100644
--- a/wpa_supplicant/dbus/dbus_new.c
+++ b/wpa_supplicant/dbus/dbus_new.c
@@ -2999,6 +2999,8 @@ static const struct wpa_dbus_method_desc wpas_dbus_interface_methods[] = {
{ NULL, NULL, NULL, { END_ARGS } }
};
+static struct wpa_dbus_property_desc *wpas_dbus_all_interface_properties = NULL;
+
static const struct wpa_dbus_property_desc wpas_dbus_interface_properties[] = {
{ "Capabilities", WPAS_DBUS_NEW_IFACE_INTERFACE, "a{sv}",
wpas_dbus_getter_capabilities,
@@ -3398,6 +3400,28 @@ static const struct wpa_dbus_signal_desc wpas_dbus_interface_signals[] = {
};
+static char *
+uscore_to_dbus (const char *uscore)
+{
+ const char *p = uscore;
+ char *str, *s;
+ dbus_bool_t last_was_uscore = TRUE;
+
+ s = str = os_zalloc(strlen (uscore) + 1);
+ while (p && *p) {
+ if (*p == '_')
+ last_was_uscore = TRUE;
+ else {
+ *s++ = last_was_uscore ? toupper (*p) : *p;
+ last_was_uscore = FALSE;
+ }
+ ++p;
+ }
+
+ return str;
+}
+
+
/**
* wpas_dbus_register_interface - Register an interface with D-Bus
* @wpa_s: wpa_supplicant interface structure
@@ -3405,7 +3429,6 @@ static const struct wpa_dbus_signal_desc wpas_dbus_interface_signals[] = {
*/
int wpas_dbus_register_interface(struct wpa_supplicant *wpa_s)
{
-
struct wpa_dbus_object_desc *obj_desc = NULL;
struct wpas_dbus_priv *ctrl_iface = wpa_s->global->dbus;
int next;
@@ -3430,8 +3453,66 @@ int wpas_dbus_register_interface(struct wpa_supplicant *wpa_s)
goto err;
}
+ if (wpas_dbus_all_interface_properties == NULL) {
+ size_t all_size;
+ int i, j, count, num_const, num_globals;
+ const char *global_name;
+ static const char *ignored_globals[] = {
+ "bss_expiration_age", "bss_expiration_scan_count",
+ "ap_scan", "country", "fast_reauth",
+ "pkcs11_engine_path", "pkcs11_module_path"
+ };
+
+ /* wpas_dbus_interface_properties terminates with a NULL element */
+ num_const = ARRAY_SIZE(wpas_dbus_interface_properties) - 1;
+
+ num_globals = wpa_config_get_num_global_field_names();
+
+ /* allocate enough for all properties + terminating NULL element */
+ all_size = (num_globals + num_const + 1) *
+ sizeof (wpas_dbus_interface_properties[0]);
+ wpas_dbus_all_interface_properties = os_zalloc(all_size);
+ if (!wpas_dbus_all_interface_properties) {
+ wpa_printf(MSG_ERROR,
+ "Not enough memory for interface properties");
+ goto err;
+ }
+ os_memcpy(wpas_dbus_all_interface_properties,
+ wpas_dbus_interface_properties,
+ sizeof(wpas_dbus_interface_properties));
+
+ for (i = 0, count = num_const; i < num_globals; i++) {
+ int no_var = 0;
+
+ /* ignore globals that are actually just methods */
+ global_name = wpa_config_get_global_field_name(i, &no_var);
+ if (no_var)
+ continue;
+ /* Ignore fields already exposed explicitly */
+ for (j = 0; j < ARRAY_SIZE(ignored_globals); j++) {
+ if (os_strcmp(global_name, ignored_globals[j]) == 0)
+ break;
+ }
+ if (j < ARRAY_SIZE(ignored_globals))
+ continue;
+
+ wpas_dbus_all_interface_properties[count].dbus_property =
+ uscore_to_dbus(global_name);
+ wpas_dbus_all_interface_properties[count].dbus_interface =
+ WPAS_DBUS_NEW_IFACE_INTERFACE;
+ wpas_dbus_all_interface_properties[count].type = "s";
+ wpas_dbus_all_interface_properties[count].getter =
+ wpas_dbus_getter_iface_global;
+ wpas_dbus_all_interface_properties[count].setter =
+ wpas_dbus_setter_iface_global;
+ wpas_dbus_all_interface_properties[count].data =
+ global_name;
+ count++;
+ }
+ }
+
wpas_dbus_register(obj_desc, wpa_s, NULL, wpas_dbus_interface_methods,
- wpas_dbus_interface_properties,
+ wpas_dbus_all_interface_properties,
wpas_dbus_interface_signals);
wpa_printf(MSG_DEBUG, "dbus: Register interface object '%s'",
diff --git a/wpa_supplicant/dbus/dbus_new_handlers.c b/wpa_supplicant/dbus/dbus_new_handlers.c
index ac75a5b..dc2bc43 100644
--- a/wpa_supplicant/dbus/dbus_new_handlers.c
+++ b/wpa_supplicant/dbus/dbus_new_handlers.c
@@ -3480,6 +3480,78 @@ dbus_bool_t wpas_dbus_getter_blobs(const struct wpa_dbus_property_desc *property
}
+dbus_bool_t wpas_dbus_getter_iface_global(const struct wpa_dbus_property_desc *property_desc,
+ DBusMessageIter *iter,
+ DBusError *error, void *user_data)
+{
+ struct wpa_supplicant *wpa_s = user_data;
+ int ret;
+ char buf[250];
+ char *p = buf;
+
+ if (!property_desc->data) {
+ dbus_set_error(error, DBUS_ERROR_INVALID_ARGS,
+ "Unhandled interface property %s",
+ property_desc->dbus_property);
+ return FALSE;
+ }
+
+ ret = wpa_config_get_value(property_desc->data, wpa_s->conf, buf,
+ sizeof (buf));
+ if (ret < 0)
+ *p = '\0';
+
+ return wpas_dbus_simple_property_getter(iter, DBUS_TYPE_STRING, &p,
+ error);
+}
+
+
+dbus_bool_t wpas_dbus_setter_iface_global(const struct wpa_dbus_property_desc *property_desc,
+ DBusMessageIter *iter,
+ DBusError *error, void *user_data)
+{
+ struct wpa_supplicant *wpa_s = user_data;
+ const char *new_value = NULL;
+ char buf[250];
+ size_t combined_len;
+ int ret;
+
+ if (!wpas_dbus_simple_property_setter(iter, error, DBUS_TYPE_STRING,
+ &new_value))
+ return FALSE;
+
+ combined_len = strlen (property_desc->data) + strlen (new_value) + 3;
+ if (combined_len >= sizeof (buf)) {
+ dbus_set_error(error, DBUS_ERROR_INVALID_ARGS,
+ "Interface property %s value too large",
+ property_desc->dbus_property);
+ return FALSE;
+ }
+
+ if (!new_value[0])
+ new_value = "NULL";
+
+ ret = os_snprintf(buf, combined_len, "%s=%s", property_desc->data,
+ new_value);
+ if (os_snprintf_error(combined_len, ret)) {
+ dbus_set_error(error, WPAS_DBUS_ERROR_UNKNOWN_ERROR,
+ "Failed to construct new interface property %s",
+ property_desc->dbus_property);
+ return FALSE;
+ }
+
+ if (wpa_config_process_global(wpa_s->conf, buf, -1)) {
+ dbus_set_error(error, DBUS_ERROR_INVALID_ARGS,
+ "Failed to set interface property %s",
+ property_desc->dbus_property);
+ return FALSE;
+ }
+
+ wpa_supplicant_update_config(wpa_s);
+ return TRUE;
+}
+
+
static struct wpa_bss * get_bss_helper(struct bss_handler_args *args,
DBusError *error, const char *func_name)
{
diff --git a/wpa_supplicant/dbus/dbus_new_handlers.h b/wpa_supplicant/dbus/dbus_new_handlers.h
index 8af99e0..5f2054d 100644
--- a/wpa_supplicant/dbus/dbus_new_handlers.h
+++ b/wpa_supplicant/dbus/dbus_new_handlers.h
@@ -61,6 +61,8 @@ DECLARE_ACCESSOR(wpas_dbus_setter_debug_show_keys)
DECLARE_ACCESSOR(wpas_dbus_getter_interfaces)
DECLARE_ACCESSOR(wpas_dbus_getter_eap_methods)
DECLARE_ACCESSOR(wpas_dbus_getter_global_capabilities)
+DECLARE_ACCESSOR(wpas_dbus_getter_iface_global)
+DECLARE_ACCESSOR(wpas_dbus_setter_iface_global)
DBusMessage * wpas_dbus_handler_scan(DBusMessage *message,
struct wpa_supplicant *wpa_s);
diff --git a/wpa_supplicant/dbus/dbus_new_helpers.h b/wpa_supplicant/dbus/dbus_new_helpers.h
index 44ace3b..c3ae080 100644
--- a/wpa_supplicant/dbus/dbus_new_helpers.h
+++ b/wpa_supplicant/dbus/dbus_new_helpers.h
@@ -94,6 +94,8 @@ struct wpa_dbus_property_desc {
WPADBusPropertyAccessor getter;
/* property setter function */
WPADBusPropertyAccessor setter;
+ /* other data */
+ const char *data;
};
diff --git a/wpa_supplicant/dbus/dbus_new_introspect.c b/wpa_supplicant/dbus/dbus_new_introspect.c
index fba57e6..fac352a 100644
--- a/wpa_supplicant/dbus/dbus_new_introspect.c
+++ b/wpa_supplicant/dbus/dbus_new_introspect.c
@@ -38,7 +38,7 @@ static struct interfaces * add_interface(struct dl_list *list,
if (!iface)
return NULL;
iface->dbus_interface = os_strdup(dbus_interface);
- iface->xml = wpabuf_alloc(6000);
+ iface->xml = wpabuf_alloc(10000);
if (iface->dbus_interface == NULL || iface->xml == NULL) {
os_free(iface->dbus_interface);
wpabuf_free(iface->xml);
--
2.1.0
More information about the Hostap
mailing list