[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