Commit 94078a13 authored by Dan Winship's avatar Dan Winship

core: port NMDhcp4Config/NMDhcp6Config to GVariant

In the gdbus port, the :options properties will be GVariant-valued
(and thus immutable), so having APIs that let you repeatedly modify
them would make things complicated. Since we actually only ever set
all the options at once, just change the APIs to do that, rather than
setting the options one-by-one.

Since nm-dispatcher already works in terms of GVariant, it makes
things simpler there if NMDhcp[46]Config can return its options as a
GVariant. And since we'll need it to be a GVariant internally later
anyway, just port everything to GVariant now, and convert it to a
GHashTable for dbus-glib only in get_property().
parent c1dd3b6e
......@@ -3417,22 +3417,6 @@ dhcp4_fail (NMDevice *self, gboolean timeout)
g_warn_if_reached ();
}
static void
dhcp4_update_config (NMDevice *self, NMDhcp4Config *config, GHashTable *options)
{
GHashTableIter iter;
const char *key, *value;
/* Update the DHCP4 config object with new DHCP options */
nm_dhcp4_config_reset (config);
g_hash_table_iter_init (&iter, options);
while (g_hash_table_iter_next (&iter, (gpointer) &key, (gpointer) &value))
nm_dhcp4_config_add_option (config, key, value);
g_object_notify (G_OBJECT (self), NM_DEVICE_DHCP4_CONFIG);
}
static void
dhcp4_state_changed (NMDhcpClient *client,
NMDhcpState state,
......@@ -3458,7 +3442,8 @@ dhcp4_state_changed (NMDhcpClient *client,
break;
}
dhcp4_update_config (self, priv->dhcp4_config, options);
nm_dhcp4_config_set_options (priv->dhcp4_config, options);
g_object_notify (G_OBJECT (self), NM_DEVICE_DHCP4_CONFIG);
if (priv->ip4_state == IP_CONF)
nm_device_activate_schedule_ip4_config_result (self, ip4_config);
......@@ -4073,22 +4058,6 @@ dhcp6_timeout (NMDevice *self, NMDhcpClient *client)
}
}
static void
dhcp6_update_config (NMDevice *self, NMDhcp6Config *config, GHashTable *options)
{
GHashTableIter iter;
const char *key, *value;
/* Update the DHCP6 config object with new DHCP options */
nm_dhcp6_config_reset (config);
g_hash_table_iter_init (&iter, options);
while (g_hash_table_iter_next (&iter, (gpointer) &key, (gpointer) &value))
nm_dhcp6_config_add_option (config, key, value);
g_object_notify (G_OBJECT (self), NM_DEVICE_DHCP6_CONFIG);
}
static void
dhcp6_state_changed (NMDhcpClient *client,
NMDhcpState state,
......@@ -4109,7 +4078,8 @@ dhcp6_state_changed (NMDhcpClient *client,
g_clear_object (&priv->dhcp6_ip6_config);
if (ip6_config) {
priv->dhcp6_ip6_config = g_object_ref (ip6_config);
dhcp6_update_config (self, priv->dhcp6_config, options);
nm_dhcp6_config_set_options (priv->dhcp6_config, options);
g_object_notify (G_OBJECT (self), NM_DEVICE_DHCP6_CONFIG);
}
if (priv->ip6_state == IP_CONF) {
......
......@@ -34,7 +34,7 @@ G_DEFINE_TYPE (NMDhcp4Config, nm_dhcp4_config, NM_TYPE_EXPORTED_OBJECT)
#define NM_DHCP4_CONFIG_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_DHCP4_CONFIG, NMDhcp4ConfigPrivate))
typedef struct {
GHashTable *options;
GVariant *options;
} NMDhcp4ConfigPrivate;
......@@ -53,68 +53,50 @@ nm_dhcp4_config_new (void)
}
void
nm_dhcp4_config_add_option (NMDhcp4Config *self,
const char *key,
const char *option)
nm_dhcp4_config_set_options (NMDhcp4Config *self,
GHashTable *options)
{
GValue *svalue;
NMDhcp4ConfigPrivate *priv = NM_DHCP4_CONFIG_GET_PRIVATE (self);
GHashTableIter iter;
const char *key, *value;
GVariantBuilder builder;
g_return_if_fail (NM_IS_DHCP4_CONFIG (self));
g_return_if_fail (key != NULL);
g_return_if_fail (option != NULL);
g_return_if_fail (options != NULL);
svalue = g_slice_new0 (GValue);
g_value_init (svalue, G_TYPE_STRING);
g_value_set_string (svalue, option);
g_hash_table_insert (NM_DHCP4_CONFIG_GET_PRIVATE (self)->options, g_strdup (key), svalue);
g_object_notify (G_OBJECT (self), NM_DHCP4_CONFIG_OPTIONS);
}
g_variant_unref (priv->options);
void
nm_dhcp4_config_reset (NMDhcp4Config *self)
{
g_return_if_fail (NM_IS_DHCP4_CONFIG (self));
g_variant_builder_init (&builder, G_VARIANT_TYPE ("a{sv}"));
g_hash_table_iter_init (&iter, options);
while (g_hash_table_iter_next (&iter, (gpointer) &key, (gpointer) &value))
g_variant_builder_add (&builder, "{sv}", key, g_variant_new_string (value));
g_hash_table_remove_all (NM_DHCP4_CONFIG_GET_PRIVATE (self)->options);
priv->options = g_variant_builder_end (&builder);
g_variant_ref_sink (priv->options);
g_object_notify (G_OBJECT (self), NM_DHCP4_CONFIG_OPTIONS);
}
const char *
nm_dhcp4_config_get_option (NMDhcp4Config *self, const char *key)
{
GValue *value;
NMDhcp4ConfigPrivate *priv = NM_DHCP4_CONFIG_GET_PRIVATE (self);
const char *value;
g_return_val_if_fail (NM_IS_DHCP4_CONFIG (self), NULL);
g_return_val_if_fail (key != NULL, NULL);
value = g_hash_table_lookup (NM_DHCP4_CONFIG_GET_PRIVATE (self)->options, key);
return value ? g_value_get_string (value) : NULL;
if (g_variant_lookup (priv->options, key, "&s", &value))
return value;
else
return NULL;
}
/* Caller owns the list, but not the values in the list */
GSList *
nm_dhcp4_config_list_options (NMDhcp4Config *self)
GVariant *
nm_dhcp4_config_get_options (NMDhcp4Config *self)
{
GHashTableIter iter;
const char *option = NULL;
GSList *list = NULL;
g_return_val_if_fail (NM_IS_DHCP4_CONFIG (self), NULL);
g_hash_table_iter_init (&iter, NM_DHCP4_CONFIG_GET_PRIVATE (self)->options);
while (g_hash_table_iter_next (&iter, (gpointer) &option, NULL))
list = g_slist_prepend (list, (gpointer) option);
return list;
}
static void
nm_gvalue_destroy (gpointer data)
{
GValue *value = (GValue *) data;
g_value_unset (value);
g_slice_free (GValue, value);
return g_variant_ref (NM_DHCP4_CONFIG_GET_PRIVATE (self)->options);
}
static void
......@@ -124,7 +106,8 @@ nm_dhcp4_config_init (NMDhcp4Config *self)
nm_exported_object_export (NM_EXPORTED_OBJECT (self));
priv->options = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, nm_gvalue_destroy);
priv->options = g_variant_new_array (G_VARIANT_TYPE ("{sv}"), NULL, 0);
g_variant_ref_sink (priv->options);
}
static void
......@@ -132,7 +115,7 @@ finalize (GObject *object)
{
NMDhcp4ConfigPrivate *priv = NM_DHCP4_CONFIG_GET_PRIVATE (object);
g_hash_table_destroy (priv->options);
g_variant_unref (priv->options);
G_OBJECT_CLASS (nm_dhcp4_config_parent_class)->finalize (object);
}
......@@ -145,7 +128,11 @@ get_property (GObject *object, guint prop_id,
switch (prop_id) {
case PROP_OPTIONS:
g_value_set_boxed (value, priv->options);
/* dbus_g_value_parse_g_variant() will call g_value_init(), but
* @value is already inited.
*/
g_value_unset (value);
dbus_g_value_parse_g_variant (priv->options, value);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
......
......@@ -45,14 +45,11 @@ GType nm_dhcp4_config_get_type (void);
NMDhcp4Config *nm_dhcp4_config_new (void);
void nm_dhcp4_config_add_option (NMDhcp4Config *config,
const char *key,
const char *option);
void nm_dhcp4_config_reset (NMDhcp4Config *config);
void nm_dhcp4_config_set_options (NMDhcp4Config *config,
GHashTable *options);
const char *nm_dhcp4_config_get_option (NMDhcp4Config *config, const char *option);
GSList *nm_dhcp4_config_list_options (NMDhcp4Config *config);
GVariant *nm_dhcp4_config_get_options (NMDhcp4Config *config);
#endif /* __NETWORKMANAGER_DHCP4_CONFIG_H__ */
......@@ -34,7 +34,7 @@ G_DEFINE_TYPE (NMDhcp6Config, nm_dhcp6_config, NM_TYPE_EXPORTED_OBJECT)
#define NM_DHCP6_CONFIG_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_DHCP6_CONFIG, NMDhcp6ConfigPrivate))
typedef struct {
GHashTable *options;
GVariant *options;
} NMDhcp6ConfigPrivate;
......@@ -53,68 +53,50 @@ nm_dhcp6_config_new (void)
}
void
nm_dhcp6_config_add_option (NMDhcp6Config *self,
const char *key,
const char *option)
nm_dhcp6_config_set_options (NMDhcp6Config *self,
GHashTable *options)
{
GValue *svalue;
NMDhcp6ConfigPrivate *priv = NM_DHCP6_CONFIG_GET_PRIVATE (self);
GHashTableIter iter;
const char *key, *value;
GVariantBuilder builder;
g_return_if_fail (NM_IS_DHCP6_CONFIG (self));
g_return_if_fail (key != NULL);
g_return_if_fail (option != NULL);
g_return_if_fail (options != NULL);
svalue = g_slice_new0 (GValue);
g_value_init (svalue, G_TYPE_STRING);
g_value_set_string (svalue, option);
g_hash_table_insert (NM_DHCP6_CONFIG_GET_PRIVATE (self)->options, g_strdup (key), svalue);
g_object_notify (G_OBJECT (self), NM_DHCP6_CONFIG_OPTIONS);
}
g_variant_unref (priv->options);
void
nm_dhcp6_config_reset (NMDhcp6Config *self)
{
g_return_if_fail (NM_IS_DHCP6_CONFIG (self));
g_variant_builder_init (&builder, G_VARIANT_TYPE ("a{sv}"));
g_hash_table_iter_init (&iter, options);
while (g_hash_table_iter_next (&iter, (gpointer) &key, (gpointer) &value))
g_variant_builder_add (&builder, "{sv}", key, g_variant_new_string (value));
g_hash_table_remove_all (NM_DHCP6_CONFIG_GET_PRIVATE (self)->options);
priv->options = g_variant_builder_end (&builder);
g_variant_ref_sink (priv->options);
g_object_notify (G_OBJECT (self), NM_DHCP6_CONFIG_OPTIONS);
}
const char *
nm_dhcp6_config_get_option (NMDhcp6Config *self, const char *key)
{
GValue *value;
NMDhcp6ConfigPrivate *priv = NM_DHCP6_CONFIG_GET_PRIVATE (self);
const char *value;
g_return_val_if_fail (NM_IS_DHCP6_CONFIG (self), NULL);
g_return_val_if_fail (key != NULL, NULL);
value = g_hash_table_lookup (NM_DHCP6_CONFIG_GET_PRIVATE (self)->options, key);
return value ? g_value_get_string (value) : NULL;
if (g_variant_lookup (priv->options, key, "&s", &value))
return value;
else
return NULL;
}
/* Caller owns the list, but not the values in the list */
GSList *
nm_dhcp6_config_list_options (NMDhcp6Config *self)
GVariant *
nm_dhcp6_config_get_options (NMDhcp6Config *self)
{
GHashTableIter iter;
const char *option = NULL;
GSList *list = NULL;
g_return_val_if_fail (NM_IS_DHCP6_CONFIG (self), NULL);
g_hash_table_iter_init (&iter, NM_DHCP6_CONFIG_GET_PRIVATE (self)->options);
while (g_hash_table_iter_next (&iter, (gpointer) &option, NULL))
list = g_slist_prepend (list, (gpointer) option);
return list;
}
static void
nm_gvalue_destroy (gpointer data)
{
GValue *value = (GValue *) data;
g_value_unset (value);
g_slice_free (GValue, value);
return g_variant_ref (NM_DHCP6_CONFIG_GET_PRIVATE (self)->options);
}
static void
......@@ -124,7 +106,8 @@ nm_dhcp6_config_init (NMDhcp6Config *self)
nm_exported_object_export (NM_EXPORTED_OBJECT (self));
priv->options = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, nm_gvalue_destroy);
priv->options = g_variant_new_array (G_VARIANT_TYPE ("{sv}"), NULL, 0);
g_variant_ref_sink (priv->options);
}
static void
......@@ -132,7 +115,7 @@ finalize (GObject *object)
{
NMDhcp6ConfigPrivate *priv = NM_DHCP6_CONFIG_GET_PRIVATE (object);
g_hash_table_destroy (priv->options);
g_variant_unref (priv->options);
G_OBJECT_CLASS (nm_dhcp6_config_parent_class)->finalize (object);
}
......@@ -145,7 +128,11 @@ get_property (GObject *object, guint prop_id,
switch (prop_id) {
case PROP_OPTIONS:
g_value_set_boxed (value, priv->options);
/* dbus_g_value_parse_g_variant() will call g_value_init(), but
* @value is already inited.
*/
g_value_unset (value);
dbus_g_value_parse_g_variant (priv->options, value);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
......
......@@ -45,14 +45,11 @@ GType nm_dhcp6_config_get_type (void);
NMDhcp6Config *nm_dhcp6_config_new (void);
void nm_dhcp6_config_add_option (NMDhcp6Config *config,
const char *key,
const char *option);
void nm_dhcp6_config_reset (NMDhcp6Config *config);
void nm_dhcp6_config_set_options (NMDhcp6Config *config,
GHashTable *options);
const char *nm_dhcp6_config_get_option (NMDhcp6Config *config, const char *option);
GSList *nm_dhcp6_config_list_options (NMDhcp6Config *self);
GVariant *nm_dhcp6_config_get_options (NMDhcp6Config *self);
#endif /* __NETWORKMANAGER_DHCP6_CONFIG_H__ */
......@@ -220,45 +220,13 @@ dump_ip6_to_props (NMIP6Config *ip6, GVariantBuilder *builder)
g_variant_builder_end (&int_builder));
}
static void
dump_dhcp4_to_props (NMDhcp4Config *config, GVariantBuilder *builder)
{
GSList *options, *iter;
options = nm_dhcp4_config_list_options (config);
for (iter = options; iter; iter = g_slist_next (iter)) {
const char *option = (const char *) iter->data;
const char *val;
val = nm_dhcp4_config_get_option (config, option);
g_variant_builder_add (builder, "{sv}", option, g_variant_new_string (val));
}
g_slist_free (options);
}
static void
dump_dhcp6_to_props (NMDhcp6Config *config, GVariantBuilder *builder)
{
GSList *options, *iter;
options = nm_dhcp6_config_list_options (config);
for (iter = options; iter; iter = g_slist_next (iter)) {
const char *option = (const char *) iter->data;
const char *val;
val = nm_dhcp6_config_get_option (config, option);
g_variant_builder_add (builder, "{sv}", option, g_variant_new_string (val));
}
g_slist_free (options);
}
static void
fill_device_props (NMDevice *device,
GVariantBuilder *dev_builder,
GVariantBuilder *ip4_builder,
GVariantBuilder *ip6_builder,
GVariantBuilder *dhcp4_builder,
GVariantBuilder *dhcp6_builder)
GVariant **dhcp4_props,
GVariant **dhcp6_props)
{
NMIP4Config *ip4_config;
NMIP6Config *ip6_config;
......@@ -287,11 +255,11 @@ fill_device_props (NMDevice *device,
dhcp4_config = nm_device_get_dhcp4_config (device);
if (dhcp4_config)
dump_dhcp4_to_props (dhcp4_config, dhcp4_builder);
*dhcp4_props = nm_dhcp4_config_get_options (dhcp4_config);
dhcp6_config = nm_device_get_dhcp6_config (device);
if (dhcp6_config)
dump_dhcp6_to_props (dhcp6_config, dhcp6_builder);
*dhcp6_props = nm_dhcp6_config_get_options (dhcp6_config);
}
static void
......@@ -485,8 +453,8 @@ _dispatcher_call (DispatcherAction action,
GVariantBuilder device_props;
GVariantBuilder device_ip4_props;
GVariantBuilder device_ip6_props;
GVariantBuilder device_dhcp4_props;
GVariantBuilder device_dhcp6_props;
GVariant *device_dhcp4_props = NULL;
GVariant *device_dhcp6_props = NULL;
GVariantBuilder vpn_ip4_props;
GVariantBuilder vpn_ip6_props;
DispatchInfo *info = NULL;
......@@ -572,8 +540,6 @@ _dispatcher_call (DispatcherAction action,
g_variant_builder_init (&device_props, G_VARIANT_TYPE_VARDICT);
g_variant_builder_init (&device_ip4_props, G_VARIANT_TYPE_VARDICT);
g_variant_builder_init (&device_ip6_props, G_VARIANT_TYPE_VARDICT);
g_variant_builder_init (&device_dhcp4_props, G_VARIANT_TYPE_VARDICT);
g_variant_builder_init (&device_dhcp6_props, G_VARIANT_TYPE_VARDICT);
g_variant_builder_init (&vpn_ip4_props, G_VARIANT_TYPE_VARDICT);
g_variant_builder_init (&vpn_ip6_props, G_VARIANT_TYPE_VARDICT);
......@@ -593,21 +559,26 @@ _dispatcher_call (DispatcherAction action,
}
}
if (!device_dhcp4_props)
device_dhcp4_props = g_variant_ref_sink (g_variant_new_array (G_VARIANT_TYPE ("{sv}"), NULL, 0));
if (!device_dhcp6_props)
device_dhcp6_props = g_variant_ref_sink (g_variant_new_array (G_VARIANT_TYPE ("{sv}"), NULL, 0));
/* Send the action to the dispatcher */
if (blocking) {
GVariant *ret;
GVariantIter *results;
ret = _nm_dbus_proxy_call_sync (dispatcher_proxy, "Action",
g_variant_new ("(s@a{sa{sv}}a{sv}a{sv}a{sv}a{sv}a{sv}a{sv}sa{sv}a{sv}b)",
g_variant_new ("(s@a{sa{sv}}a{sv}a{sv}a{sv}a{sv}@a{sv}@a{sv}sa{sv}a{sv}b)",
action_to_string (action),
connection_dict,
&connection_props,
&device_props,
&device_ip4_props,
&device_ip6_props,
&device_dhcp4_props,
&device_dhcp6_props,
device_dhcp4_props,
device_dhcp6_props,
vpn_iface ? vpn_iface : "",
&vpn_ip4_props,
&vpn_ip6_props,
......@@ -634,15 +605,15 @@ _dispatcher_call (DispatcherAction action,
info->callback = callback;
info->user_data = user_data;
g_dbus_proxy_call (dispatcher_proxy, "Action",
g_variant_new ("(s@a{sa{sv}}a{sv}a{sv}a{sv}a{sv}a{sv}a{sv}sa{sv}a{sv}b)",
g_variant_new ("(s@a{sa{sv}}a{sv}a{sv}a{sv}a{sv}@a{sv}@a{sv}sa{sv}a{sv}b)",
action_to_string (action),
connection_dict,
&connection_props,
&device_props,
&device_ip4_props,
&device_ip6_props,
&device_dhcp4_props,
&device_dhcp6_props,
device_dhcp4_props,
device_dhcp6_props,
vpn_iface ? vpn_iface : "",
&vpn_ip4_props,
&vpn_ip6_props,
......@@ -652,6 +623,9 @@ _dispatcher_call (DispatcherAction action,
success = TRUE;
}
g_variant_unref (device_dhcp4_props);
g_variant_unref (device_dhcp6_props);
done:
if (success && info) {
/* Track the request in case of cancelation */
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment