diff --git a/.gitignore b/.gitignore index c4790edc87..b58f499316 100644 --- a/.gitignore +++ b/.gitignore @@ -133,6 +133,8 @@ valgrind-*.log /initscript/*/[Nn]etwork[Mm]anager /introspection/all.xml +/introspection/nmdbus-*.c +/introspection/nmdbus-*.h /libgsystem/ diff --git a/Makefile.am b/Makefile.am index 1f1311b8fc..18bb6c68c0 100644 --- a/Makefile.am +++ b/Makefile.am @@ -3,11 +3,11 @@ include $(GLIB_MAKEFILE) SUBDIRS = \ . \ include \ + introspection \ libnm-core \ libnm \ libnm-util \ libnm-glib \ - introspection \ src \ callouts \ clients \ diff --git a/callouts/Makefile.am b/callouts/Makefile.am index d305554cc0..1c5f39566d 100644 --- a/callouts/Makefile.am +++ b/callouts/Makefile.am @@ -49,8 +49,7 @@ nm_dispatcher_LDADD = \ libnmdbus-dispatcher.la \ $(GLIB_LIBS) -# We have to build the gdbus generated code separately, without -# -DGLIB_VERSION_MAX_ALLOWED, due to a bug in GLib 2.38 +# See note about gdbus-codegen in introspection/Makefile.am noinst_LTLIBRARIES += libnmdbus-dispatcher.la diff --git a/callouts/nm-dispatcher-utils.c b/callouts/nm-dispatcher-utils.c index 9a16880a57..66b6a07fd8 100644 --- a/callouts/nm-dispatcher-utils.c +++ b/callouts/nm-dispatcher-utils.c @@ -406,7 +406,7 @@ nm_dispatcher_utils_construct_envp (const char *action, } /* UUID and ID */ - con_setting = g_variant_lookup_value (connection_dict, NM_SETTING_CONNECTION_SETTING_NAME, G_VARIANT_TYPE ("a{sv}")); + con_setting = g_variant_lookup_value (connection_dict, NM_SETTING_CONNECTION_SETTING_NAME, NM_VARIANT_TYPE_SETTING); if (!con_setting) { g_warning ("Failed to read connection setting"); return NULL; diff --git a/callouts/tests/test-dispatcher-envp.c b/callouts/tests/test-dispatcher-envp.c index b51c1c16a5..c2f1b41df7 100644 --- a/callouts/tests/test-dispatcher-envp.c +++ b/callouts/tests/test-dispatcher-envp.c @@ -30,25 +30,9 @@ #include "nm-dispatcher-utils.h" #include "nm-dispatcher-api.h" #include "nm-utils.h" -#include "nm-dbus-glib-types.h" /*******************************************/ -static GVariant * -connection_hash_to_dict (GHashTable *hash) -{ - GValue val = { 0, }; - GVariant *dict; - - g_value_init (&val, DBUS_TYPE_G_MAP_OF_MAP_OF_VARIANT); - g_value_set_boxed (&val, hash); - dict = dbus_g_value_build_g_variant (&val); - g_value_unset (&val); - - g_variant_ref_sink (dict); - return dict; -} - static gboolean parse_main (GKeyFile *kf, GVariant **out_con_dict, @@ -62,7 +46,6 @@ parse_main (GKeyFile *kf, NMConnection *connection; NMSettingConnection *s_con; GVariantBuilder props; - GHashTable *con_hash; *out_expected_iface = g_key_file_get_string (kf, "main", "expected-iface", error); if (*out_expected_iface == NULL) @@ -93,10 +76,8 @@ parse_main (GKeyFile *kf, g_free (id); nm_connection_add_setting (connection, NM_SETTING (s_con)); - con_hash = nm_connection_to_dbus (connection, NM_CONNECTION_SERIALIZE_ALL); + *out_con_dict = nm_connection_to_dbus (connection, NM_CONNECTION_SERIALIZE_ALL); g_object_unref (connection); - *out_con_dict = connection_hash_to_dict (con_hash); - g_hash_table_unref (con_hash); g_variant_builder_init (&props, G_VARIANT_TYPE ("a{sv}")); g_variant_builder_add (&props, "{sv}", diff --git a/clients/Makefile.am b/clients/Makefile.am index 1d622773d8..dea8f9e331 100644 --- a/clients/Makefile.am +++ b/clients/Makefile.am @@ -5,7 +5,6 @@ AM_CPPFLAGS = \ -I${top_builddir}/libnm-core \ -I${top_srcdir}/libnm \ -I${top_builddir}/libnm \ - $(DBUS_CFLAGS) \ $(GLIB_CFLAGS) \ -DNM_VERSION_MAX_ALLOWED=NM_VERSION_NEXT_STABLE \ -DNMLOCALEDIR=\"$(datadir)/locale\" @@ -19,5 +18,4 @@ nm_online_CPPFLAGS = \ nm_online_LDADD = \ $(top_builddir)/libnm/libnm.la \ - $(DBUS_LIBS) \ $(GLIB_LIBS) diff --git a/clients/cli/Makefile.am b/clients/cli/Makefile.am index 1ad761c8ef..7fa67948ec 100644 --- a/clients/cli/Makefile.am +++ b/clients/cli/Makefile.am @@ -9,7 +9,6 @@ AM_CPPFLAGS = \ -I${top_builddir}/libnm-core \ -I${top_srcdir}/libnm \ -I${top_builddir}/libnm \ - $(DBUS_CFLAGS) \ $(GLIB_CFLAGS) \ -DG_LOG_DOMAIN=\""nmcli"\" \ -DNM_VERSION_MAX_ALLOWED=NM_VERSION_NEXT_STABLE \ @@ -32,7 +31,6 @@ nmcli_SOURCES = \ utils.h nmcli_LDADD = \ - $(DBUS_LIBS) \ $(GLIB_LIBS) \ $(READLINE_LIBS) \ $(top_builddir)/libnm/libnm.la diff --git a/clients/cli/connections.c b/clients/cli/connections.c index 89ff12b7fd..bd425ecfd6 100644 --- a/clients/cli/connections.c +++ b/clients/cli/connections.c @@ -5343,19 +5343,19 @@ gen_cmd_print0 (const char *text, int state) char *ret = NULL; if (!state) { - GHashTable *settings; - GHashTableIter iter; + GVariant *settings; + GVariantIter iter; const char *setting_name; int i = 0; settings = nm_connection_to_dbus (nmc_tab_completion.connection, NM_CONNECTION_SERIALIZE_NO_SECRETS); - words = g_new (char *, g_hash_table_size (settings) + 2); - g_hash_table_iter_init (&iter, settings); - while (g_hash_table_iter_next (&iter, (gpointer) &setting_name, NULL)) + words = g_new (char *, g_variant_n_children (settings) + 2); + g_variant_iter_init (&iter, settings); + while (g_variant_iter_next (&iter, "{&s@a{sv}}", &setting_name, NULL)) words [i++] = g_strdup (setting_name); words[i++] = g_strdup ("all"); words[i] = NULL; - g_hash_table_unref (settings); + g_variant_unref (settings); } if (words) { diff --git a/clients/cli/network-manager.c b/clients/cli/network-manager.c index a963a04bfc..4a885dbfd1 100644 --- a/clients/cli/network-manager.c +++ b/clients/cli/network-manager.c @@ -677,7 +677,7 @@ do_general (NmCli *nmc, int argc, char **argv) nmc->get_client (nmc); /* create NMClient */ nm_client_set_logging (nmc->client, level, domains, &error); if (error) { - if (g_error_matches (error, DBUS_GERROR, DBUS_GERROR_ACCESS_DENIED)) + if (g_error_matches (error, G_DBUS_ERROR, G_DBUS_ERROR_AUTH_FAILED)) g_string_printf (nmc->return_text, _("Error: access denied to set logging; %s"), error->message); else g_string_printf (nmc->return_text, _("Error: %s"), error->message); diff --git a/clients/tui/Makefile.am b/clients/tui/Makefile.am index 147f5064f3..fb5ad8fcf0 100644 --- a/clients/tui/Makefile.am +++ b/clients/tui/Makefile.am @@ -12,7 +12,6 @@ AM_CPPFLAGS= \ -I$(srcdir)/newt \ $(GLIB_CFLAGS) \ $(NEWT_CFLAGS) \ - $(DBUS_CFLAGS) \ $(GUDEV_CFLAGS) \ -DG_LOG_DOMAIN=\""nmtui"\" \ -DNM_VERSION_MAX_ALLOWED=NM_VERSION_NEXT_STABLE \ @@ -121,7 +120,6 @@ nmtui_LDADD = \ $(top_builddir)/libnm/libnm.la \ $(builddir)/newt/libnmt-newt.a \ $(GUDEV_LIBS) \ - $(DBUS_LIBS) \ $(NEWT_LIBS) \ $(GLIB_LIBS) \ $(NULL) diff --git a/clients/tui/nmt-editor.c b/clients/tui/nmt-editor.c index ab364f4b3f..0f35f48f04 100644 --- a/clients/tui/nmt-editor.c +++ b/clients/tui/nmt-editor.c @@ -162,31 +162,21 @@ save_connection_and_exit (NmtNewtButton *button, static void got_secrets (NMRemoteConnection *connection, - GHashTable *secrets, + GVariant *secrets, GError *error, gpointer op) { - GHashTable *copy = NULL, *setting; - GHashTableIter iter; - const char *name; - - if (secrets) { - /* 'secrets' is owned by the caller so we must copy it */ - copy = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, (GDestroyNotify) g_hash_table_destroy); - g_hash_table_iter_init (&iter, secrets); - while (g_hash_table_iter_next (&iter, (gpointer) &name, (gpointer) &setting)) - g_hash_table_insert (copy, g_strdup (name), nm_utils_gvalue_hash_dup (setting)); - } - - nmt_sync_op_complete_pointer (op, copy, error); + if (secrets) + g_variant_ref (secrets); + nmt_sync_op_complete_pointer (op, secrets, error); } static NMConnection * build_edit_connection (NMConnection *orig_connection) { NMConnection *edit_connection; - GHashTable *settings, *secrets; - GHashTableIter iter; + GVariant *settings, *secrets; + GVariantIter iter; const char *setting_name; NmtSyncOp op; @@ -196,8 +186,8 @@ build_edit_connection (NMConnection *orig_connection) return edit_connection; settings = nm_connection_to_dbus (orig_connection, NM_CONNECTION_SERIALIZE_NO_SECRETS); - g_hash_table_iter_init (&iter, settings); - while (g_hash_table_iter_next (&iter, (gpointer) &setting_name, NULL)) { + g_variant_iter_init (&iter, settings); + while (g_variant_iter_next (&iter, "{&s@a{sv}}", &setting_name, NULL)) { nmt_sync_op_init (&op); nm_remote_connection_get_secrets (NM_REMOTE_CONNECTION (orig_connection), setting_name, got_secrets, &op); @@ -205,10 +195,10 @@ build_edit_connection (NMConnection *orig_connection) secrets = nmt_sync_op_wait_pointer (&op, NULL); if (secrets) { (void) nm_connection_update_secrets (edit_connection, setting_name, secrets, NULL); - g_hash_table_unref (secrets); + g_variant_unref (secrets); } } - g_hash_table_unref (settings); + g_variant_unref (settings); return edit_connection; } diff --git a/clients/tui/nmt-secret-agent.c b/clients/tui/nmt-secret-agent.c index 7550ce64f6..b2c7ad890c 100644 --- a/clients/tui/nmt-secret-agent.c +++ b/clients/tui/nmt-secret-agent.c @@ -482,14 +482,6 @@ nmt_secret_agent_get_secrets (NMSecretAgent *agent, request_secrets_from_ui (request); } -static void -gvalue_destroy_notify (gpointer data) -{ - GValue *value = data; - g_value_unset (value); - g_slice_free (GValue, value); -} - /** * nmt_secret_agent_response: * @self: the #NmtSecretAgent @@ -511,8 +503,7 @@ nmt_secret_agent_response (NmtSecretAgent *self, { NmtSecretAgentPrivate *priv; NmtSecretAgentRequest *request; - GHashTable *hash = NULL, *setting_hash; - GValue *value; + GVariant *dict = NULL; GError *error = NULL; int i; @@ -523,32 +514,41 @@ nmt_secret_agent_response (NmtSecretAgent *self, g_return_if_fail (request != NULL); if (secrets) { - hash = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, (GDestroyNotify) g_hash_table_unref); + GVariantBuilder conn_builder, *setting_builder; + GHashTable *settings; + GHashTableIter iter; + const char *name; + + settings = g_hash_table_new (g_str_hash, g_str_equal); for (i = 0; i < secrets->len; i++) { NmtSecretAgentSecretReal *secret = secrets->pdata[i]; - setting_hash = g_hash_table_lookup (hash, nm_setting_get_name (secret->setting)); - if (!setting_hash) { - setting_hash = g_hash_table_new_full (g_str_hash, g_str_equal, - g_free, gvalue_destroy_notify); - g_hash_table_insert (hash, (char *)nm_setting_get_name (secret->setting), - setting_hash); + setting_builder = g_hash_table_lookup (settings, nm_setting_get_name (secret->setting)); + if (!setting_builder) { + setting_builder = g_variant_builder_new (NM_VARIANT_TYPE_SETTING); + g_hash_table_insert (settings, (char *) nm_setting_get_name (secret->setting), + setting_builder); } - value = g_slice_new0 (GValue); - g_value_init (value, G_TYPE_STRING); - g_value_set_string (value, secret->base.value); - - g_hash_table_insert (setting_hash, g_strdup (secret->property), value); + g_variant_builder_add (setting_builder, "{sv}", + secret->property, + g_variant_new_string (secret->base.value)); } + + g_variant_builder_init (&conn_builder, NM_VARIANT_TYPE_CONNECTION); + g_hash_table_iter_init (&iter, settings); + while (g_hash_table_iter_next (&iter, (gpointer *) &name, (gpointer *) &setting_builder)) + g_variant_builder_add (&conn_builder, "{sa{sv}}", name, setting_builder); + dict = g_variant_builder_end (&conn_builder); + g_hash_table_destroy (settings); } else { error = g_error_new (NM_SECRET_AGENT_ERROR, NM_SECRET_AGENT_ERROR_USER_CANCELED, "User cancelled"); } - request->callback (NM_SECRET_AGENT (self), request->connection, hash, error, request->callback_data); + request->callback (NM_SECRET_AGENT (self), request->connection, dict, error, request->callback_data); - g_clear_pointer (&hash, g_hash_table_unref); + g_clear_pointer (&dict, g_variant_unref); g_clear_error (&error); g_hash_table_remove (priv->requests, request_id); } diff --git a/configure.ac b/configure.ac index a2efb30659..e24ce732f9 100644 --- a/configure.ac +++ b/configure.ac @@ -890,7 +890,6 @@ libnm-core/nm-version.h libnm-core/Makefile libnm-core/tests/Makefile libnm/libnm.pc -libnm/libnm-vpn.pc libnm/Makefile libnm/tests/Makefile libnm-util/libnm-util.pc diff --git a/docs/libnm/Makefile.am b/docs/libnm/Makefile.am index c99e242512..5556aadb97 100644 --- a/docs/libnm/Makefile.am +++ b/docs/libnm/Makefile.am @@ -38,11 +38,9 @@ IGNORE_HFILES= \ nm-object-private.h \ nm-param-spec-dbus.h \ nm-remote-connection-private.h \ - nm-secret-agent-glue.h \ nm-setting-private.h \ nm-types-private.h \ - nm-utils-private.h \ - nm-vpn-plugin-glue.h + nm-utils-private.h # Images to copy into HTML directory. HTML_IMAGES = libnm.png @@ -62,12 +60,10 @@ GTKDOC_CFLAGS = \ -I$(top_srcdir)/libnm \ -I$(top_builddir)/libnm \ -DNM_VERSION_MAX_ALLOWED=NM_VERSION_NEXT_STABLE \ - $(GLIB_CFLAGS) \ - $(DBUS_CFLAGS) + $(GLIB_CFLAGS) GTKDOC_LIBS = \ $(top_builddir)/libnm/libnm.la \ - $(top_builddir)/libnm/libnm-vpn.la \ $(GLIB_LIBS) diff --git a/examples/C/glib/Makefile.am b/examples/C/glib/Makefile.am index c3e9be0660..d8e5d2853e 100644 --- a/examples/C/glib/Makefile.am +++ b/examples/C/glib/Makefile.am @@ -4,7 +4,6 @@ AM_CPPFLAGS = \ -I${top_builddir}/libnm-core \ -I${top_srcdir}/libnm \ -I${top_builddir}/libnm \ - $(DBUS_CFLAGS) \ $(GLIB_CFLAGS) noinst_PROGRAMS = \ @@ -25,7 +24,6 @@ add_connection_gdbus_LDADD = \ add_connection_libnm_SOURCES = add-connection-libnm.c add_connection_libnm_LDADD = \ $(top_builddir)/libnm/libnm.la \ - $(DBUS_LIBS) \ $(GLIB_LIBS) get_active_connections_gdbus_SOURCES = get-active-connections-gdbus.c @@ -35,7 +33,6 @@ get_active_connections_gdbus_LDADD = \ get_ap_info_libnm_SOURCES = get-ap-info-libnm.c get_ap_info_libnm_LDADD = \ $(top_builddir)/libnm/libnm.la \ - $(DBUS_LIBS) \ $(GLIB_LIBS) list_connections_gdbus_SOURCES = list-connections-gdbus.c @@ -45,7 +42,6 @@ list_connections_gdbus_LDADD = \ list_connections_libnm_SOURCES = list-connections-libnm.c list_connections_libnm_LDADD = \ $(top_builddir)/libnm/libnm.la \ - $(DBUS_LIBS) \ $(GLIB_LIBS) monitor_nm_running_gdbus_SOURCES = monitor-nm-running-gdbus.c diff --git a/include/nm-test-utils.h b/include/nm-test-utils.h index 6fe2470ade..f519bd90de 100644 --- a/include/nm-test-utils.h +++ b/include/nm-test-utils.h @@ -1000,4 +1000,92 @@ nmtst_assert_hwaddr_equals (gconstpointer hwaddr1, gssize hwaddr1_len, const cha nmtst_assert_hwaddr_equals (hwaddr1, hwaddr1_len, expected, G_STRLOC) #endif +#ifdef __NM_CONNECTION_H__ + +typedef enum { + NMTST_VARIANT_EDITOR_CONNECTION, + NMTST_VARIANT_EDITOR_SETTING, + NMTST_VARIANT_EDITOR_PROPERTY +} NmtstVariantEditorPhase; + +#define NMTST_VARIANT_EDITOR(__connection_variant, __code) \ + G_STMT_START { \ + GVariantIter __connection_iter, *__setting_iter; \ + GVariantBuilder __connection_builder, __setting_builder; \ + const char *__cur_setting_name, *__cur_property_name; \ + GVariant *__property_val; \ + NmtstVariantEditorPhase __phase; \ + \ + g_variant_builder_init (&__connection_builder, NM_VARIANT_TYPE_CONNECTION); \ + g_variant_iter_init (&__connection_iter, __connection_variant); \ + \ + __phase = NMTST_VARIANT_EDITOR_CONNECTION; \ + __code; \ + while (g_variant_iter_next (&__connection_iter, "{&sa{sv}}", &__cur_setting_name, &__setting_iter)) { \ + g_variant_builder_init (&__setting_builder, NM_VARIANT_TYPE_SETTING); \ + __phase = NMTST_VARIANT_EDITOR_SETTING; \ + __code; \ + \ + while (g_variant_iter_next (__setting_iter, "{&sv}", &__cur_property_name, &__property_val)) { \ + __phase = NMTST_VARIANT_EDITOR_PROPERTY; \ + __code; \ + \ + if (__cur_property_name) { \ + g_variant_builder_add (&__setting_builder, "{sv}", \ + __cur_property_name, \ + __property_val); \ + } else \ + g_variant_unref (__property_val); \ + } \ + \ + if (__cur_setting_name) \ + g_variant_builder_add (&__connection_builder, "{sa{sv}}", __cur_setting_name, &__setting_builder); \ + g_variant_iter_free (__setting_iter); \ + } \ + \ + g_variant_unref (__connection_variant); \ + \ + __connection_variant = g_variant_builder_end (&__connection_builder); \ + } G_STMT_END; +#endif + +#define NMTST_VARIANT_ADD_SETTING(__setting_name, __setting_variant) \ + G_STMT_START { \ + if (__phase == NMTST_VARIANT_EDITOR_CONNECTION) \ + g_variant_builder_add (&__connection_builder, "{s@a{sv}}", __setting_name, __setting_variant); \ + } G_STMT_END + +#define NMTST_VARIANT_DROP_SETTING(__setting_name) \ + G_STMT_START { \ + if (__phase == NMTST_VARIANT_EDITOR_SETTING) { \ + if (!strcmp (__cur_setting_name, __setting_name)) \ + __cur_setting_name = NULL; \ + } \ + } G_STMT_END + +#define NMTST_VARIANT_ADD_PROPERTY(__setting_name, __property_name, __format_string, __value) \ + G_STMT_START { \ + if (__phase == NMTST_VARIANT_EDITOR_SETTING) { \ + if (!strcmp (__cur_setting_name, __setting_name)) { \ + g_variant_builder_add (&__setting_builder, "{sv}", __property_name, \ + g_variant_new (__format_string, __value)); \ + } \ + } \ + } G_STMT_END + +#define NMTST_VARIANT_DROP_PROPERTY(__setting_name, __property_name) \ + G_STMT_START { \ + if (__phase == NMTST_VARIANT_EDITOR_PROPERTY) { \ + if ( !strcmp (__cur_setting_name, __setting_name) \ + && !strcmp (__cur_property_name, __property_name)) \ + __cur_property_name = NULL; \ + } \ + } G_STMT_END + +#define NMTST_VARIANT_CHANGE_PROPERTY(__setting_name, __property_name, __format_string, __value) \ + G_STMT_START { \ + NMTST_VARIANT_DROP_PROPERTY (__setting_name, __property_name); \ + NMTST_VARIANT_ADD_PROPERTY (__setting_name, __property_name, __format_string, __value); \ + } G_STMT_END + #endif /* __NM_TEST_UTILS_H__ */ diff --git a/introspection/Makefile.am b/introspection/Makefile.am index 4d742dfac4..3cf0873396 100644 --- a/introspection/Makefile.am +++ b/introspection/Makefile.am @@ -1,3 +1,91 @@ +noinst_LTLIBRARIES = \ + libnmdbus.la + +# gdbus-codegen 2.38 will emit code that requires glib 2.38, which +# will then cause availability warnings if we define +# GLIB_VERSION_MAX_ALLOWED=GLIB_VERSION_2_32. +# +# This is fixed in GLib 2.40 (it emits code that takes +# GLIB_VERSION_MAX_ALLOWED into account), so this workaround can go +# away when we depend on that. +AM_CPPFLAGS = $(filter-out -DGLIB_VERSION_MAX_ALLOWED%,$(GLIB_CFLAGS)) + +nodist_libnmdbus_la_SOURCES = \ + nmdbus-access-point.c \ + nmdbus-access-point.h \ + nmdbus-active-connection.c \ + nmdbus-active-connection.h \ + nmdbus-agent-manager.c \ + nmdbus-agent-manager.h \ + nmdbus-device-bond.c \ + nmdbus-device-bond.h \ + nmdbus-device-bridge.c \ + nmdbus-device-bridge.h \ + nmdbus-device-bt.c \ + nmdbus-device-bt.h \ + nmdbus-device-ethernet.c \ + nmdbus-device-ethernet.h \ + nmdbus-device.c \ + nmdbus-device.h \ + nmdbus-device-generic.c \ + nmdbus-device-generic.h \ + nmdbus-device-gre.c \ + nmdbus-device-gre.h \ + nmdbus-device-infiniband.c \ + nmdbus-device-infiniband.h \ + nmdbus-device-macvlan.c \ + nmdbus-device-macvlan.h \ + nmdbus-device-tun.c \ + nmdbus-device-tun.h \ + nmdbus-device-veth.c \ + nmdbus-device-veth.h \ + nmdbus-device-vlan.c \ + nmdbus-device-vlan.h \ + nmdbus-device-vxlan.c \ + nmdbus-device-vxlan.h \ + nmdbus-device-wifi.c \ + nmdbus-device-wifi.h \ + nmdbus-device-wimax.c \ + nmdbus-device-wimax.h \ + nmdbus-dhcp4-config.c \ + nmdbus-dhcp4-config.h \ + nmdbus-dhcp6-config.c \ + nmdbus-dhcp6-config.h \ + nmdbus-ip4-config.c \ + nmdbus-ip4-config.h \ + nmdbus-ip6-config.c \ + nmdbus-ip6-config.h \ + nmdbus-manager.c \ + nmdbus-manager.h \ + nmdbus-ppp-manager.c \ + nmdbus-ppp-manager.h \ + nmdbus-secret-agent.c \ + nmdbus-secret-agent.h \ + nmdbus-settings-connection.c \ + nmdbus-settings-connection.h \ + nmdbus-settings.c \ + nmdbus-settings.h \ + nmdbus-vpn-connection.c \ + nmdbus-vpn-connection.h \ + nmdbus-vpn-plugin.c \ + nmdbus-vpn-plugin.h + +define _make_nmdbus_rule +$(1): $(patsubst nmdbus-%.c,nm-%.xml,$(1)) + $$(AM_V_GEN) gdbus-codegen \ + --generate-c-code $$(basename $$@) \ + --c-namespace NMDBus \ + --interface-prefix org.freedesktop.NetworkManager \ + $$< + +$(basename $(1)).h: $(1) + @true +endef + +$(foreach f,$(filter %.c,$(nodist_libnmdbus_la_SOURCES)),$(eval $(call _make_nmdbus_rule,$f))) + +CLEANFILES = $(nodist_libnmdbus_la_SOURCES) + EXTRA_DIST = \ all.xml.in \ generic-types.xml \ diff --git a/introspection/nm-device-ethernet.xml b/introspection/nm-device-ethernet.xml index 000caf752f..2554bda17f 100644 --- a/introspection/nm-device-ethernet.xml +++ b/introspection/nm-device-ethernet.xml @@ -2,6 +2,7 @@ + diff --git a/introspection/nm-device-wifi.xml b/introspection/nm-device-wifi.xml index 65c7b71dce..2476fd7dd9 100644 --- a/introspection/nm-device-wifi.xml +++ b/introspection/nm-device-wifi.xml @@ -2,6 +2,8 @@ + + diff --git a/introspection/nm-manager.xml b/introspection/nm-manager.xml index 6af2be3032..78021f73da 100644 --- a/introspection/nm-manager.xml +++ b/introspection/nm-manager.xml @@ -2,6 +2,8 @@ + + Get the list of network devices. diff --git a/introspection/nm-ppp-manager.xml b/introspection/nm-ppp-manager.xml index 2867daf979..5ea1e8b16b 100644 --- a/introspection/nm-ppp-manager.xml +++ b/introspection/nm-ppp-manager.xml @@ -2,6 +2,8 @@ + + diff --git a/introspection/nm-vpn-connection.xml b/introspection/nm-vpn-connection.xml index 65b9178543..03bbbe980f 100644 --- a/introspection/nm-vpn-connection.xml +++ b/introspection/nm-vpn-connection.xml @@ -2,6 +2,8 @@ + + Represents an active connection to a Virtual Private Network. diff --git a/introspection/nm-vpn-plugin.xml b/introspection/nm-vpn-plugin.xml index a72fa93c2c..adb6a08526 100644 --- a/introspection/nm-vpn-plugin.xml +++ b/introspection/nm-vpn-plugin.xml @@ -2,6 +2,8 @@ + + This interface is provided by plugins providing VPN services to the NetworkManager daemon. diff --git a/libnm-core/Makefile.am b/libnm-core/Makefile.am index 53805e27e2..785db1d7df 100644 --- a/libnm-core/Makefile.am +++ b/libnm-core/Makefile.am @@ -7,8 +7,7 @@ AM_CPPFLAGS = \ -DG_LOG_DOMAIN=\""libnm"\" \ -DNETWORKMANAGER_COMPILATION \ -DNM_VERSION_MAX_ALLOWED=NM_VERSION_NEXT_STABLE \ - $(GLIB_CFLAGS) \ - $(DBUS_CFLAGS) + $(GLIB_CFLAGS) noinst_LTLIBRARIES = libnm-core.la @@ -30,7 +29,6 @@ GLIB_MKENUMS_C_FLAGS = --identifier-prefix NM libnm_core_la_LIBADD = \ $(GLIB_LIBS) \ - $(DBUS_LIBS) \ $(UUID_LIBS) if WITH_GNUTLS diff --git a/libnm-core/Makefile.libnm-core b/libnm-core/Makefile.libnm-core index c68a720f7e..22566e0638 100644 --- a/libnm-core/Makefile.libnm-core +++ b/libnm-core/Makefile.libnm-core @@ -81,6 +81,5 @@ libnm_core_sources = \ $(core)/nm-setting-wireless.c \ $(core)/nm-setting.c \ $(core)/nm-simple-connection.c \ - $(core)/nm-utils.c \ - $(core)/nm-value-transforms.c + $(core)/nm-utils.c diff --git a/libnm-core/nm-connection.c b/libnm-core/nm-connection.c index 8dc18632d3..142fee4cd0 100644 --- a/libnm-core/nm-connection.c +++ b/libnm-core/nm-connection.c @@ -22,11 +22,9 @@ #include #include -#include #include #include "nm-connection.h" -#include "nm-utils-internal.h" -#include "nm-dbus-glib-types.h" +#include "nm-utils.h" #include "nm-setting-private.h" #include "nm-setting-8021x.h" @@ -243,35 +241,40 @@ nm_connection_get_setting_by_name (NMConnection *connection, const char *name) } static gboolean -validate_permissions_type (GHashTable *hash, GError **error) +validate_permissions_type (GVariant *variant, GError **error) { - GHashTable *s_con; - GValue *permissions; + GVariant *s_con; + GVariant *permissions; + gboolean valid = TRUE; /* Ensure the connection::permissions item (if present) is the correct * type, otherwise the g_object_set() will throw a warning and ignore the * error, leaving us with no permissions. */ - s_con = g_hash_table_lookup (hash, NM_SETTING_CONNECTION_SETTING_NAME); - if (s_con) { - permissions = g_hash_table_lookup (s_con, NM_SETTING_CONNECTION_PERMISSIONS); - if (permissions) { - if (!G_VALUE_HOLDS (permissions, G_TYPE_STRV)) { - g_set_error_literal (error, - NM_SETTING_ERROR, - NM_SETTING_ERROR_PROPERTY_TYPE_MISMATCH, - "Wrong permissions property type; should be an array of strings."); - return FALSE; - } + s_con = g_variant_lookup_value (variant, NM_SETTING_CONNECTION_SETTING_NAME, NM_VARIANT_TYPE_SETTING); + if (!s_con) + return TRUE; + + permissions = g_variant_lookup_value (s_con, NM_SETTING_CONNECTION_PERMISSIONS, NULL); + if (permissions) { + if (!g_variant_is_of_type (permissions, G_VARIANT_TYPE_STRING_ARRAY)) { + g_set_error_literal (error, + NM_SETTING_ERROR, + NM_SETTING_ERROR_PROPERTY_TYPE_MISMATCH, + "Wrong permissions property type; should be a list of strings."); + valid = FALSE; } + g_variant_unref (permissions); } - return TRUE; + + g_variant_unref (s_con); + return valid; } /** * nm_connection_replace_settings: * @connection: a #NMConnection - * @new_settings: (element-type utf8 GLib.HashTable): a #GHashTable of settings + * @new_settings: a #GVariant of type %NM_VARIANT_TYPE_CONNECTION, with the new settings * @error: location to store error, or %NULL * * Replaces @connection's settings with @new_settings (which must be @@ -283,18 +286,18 @@ validate_permissions_type (GHashTable *hash, GError **error) **/ gboolean nm_connection_replace_settings (NMConnection *connection, - GHashTable *new_settings, + GVariant *new_settings, GError **error) { NMConnectionPrivate *priv; - GHashTableIter iter; + GVariantIter iter; const char *setting_name; - GHashTable *setting_hash; + GVariant *setting_dict; GSList *settings = NULL, *s; gboolean changed; g_return_val_if_fail (NM_IS_CONNECTION (connection), FALSE); - g_return_val_if_fail (new_settings != NULL, FALSE); + g_return_val_if_fail (g_variant_is_of_type (new_settings, NM_VARIANT_TYPE_CONNECTION), FALSE); g_return_val_if_fail (error == NULL || *error == NULL, FALSE); priv = NM_CONNECTION_GET_PRIVATE (connection); @@ -302,8 +305,8 @@ nm_connection_replace_settings (NMConnection *connection, if (!validate_permissions_type (new_settings, error)) return FALSE; - g_hash_table_iter_init (&iter, new_settings); - while (g_hash_table_iter_next (&iter, (gpointer) &setting_name, (gpointer) &setting_hash)) { + g_variant_iter_init (&iter, new_settings); + while (g_variant_iter_next (&iter, "{&s@a{sv}}", &setting_name, &setting_dict)) { NMSetting *setting; GType type; @@ -313,15 +316,19 @@ nm_connection_replace_settings (NMConnection *connection, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_INVALID_SETTING, "unknown setting name '%s'", setting_name); + g_variant_unref (setting_dict); g_slist_free_full (settings, g_object_unref); return FALSE; } - setting = _nm_setting_new_from_dbus (type, setting_hash, new_settings, error); + setting = _nm_setting_new_from_dbus (type, setting_dict, new_settings, error); + g_variant_unref (setting_dict); + if (!setting) { g_slist_free_full (settings, g_object_unref); return FALSE; } + settings = g_slist_prepend (settings, setting); } @@ -928,16 +935,16 @@ nm_connection_normalize (NMConnection *connection, * nm_connection_update_secrets: * @connection: the #NMConnection * @setting_name: the setting object name to which the secrets apply - * @secrets: (element-type utf8 GObject.Value): a #GHashTable mapping - * string:#GValue of setting property names and secrets of the given @setting_name + * @secrets: a #GVariant of secrets, of type %NM_VARIANT_TYPE_CONNECTION + * or %NM_VARIANT_TYPE_SETTING * @error: location to store error, or %NULL * - * Update the specified setting's secrets, given a hash table of secrets + * Update the specified setting's secrets, given a dictionary of secrets * intended for that setting (deserialized from D-Bus for example). Will also - * extract the given setting's secrets hash if given a hash of hashes, as would - * be returned from nm_connection_to_dbus(). If @setting_name is %NULL, expects - * a fully serialized #NMConnection as returned by nm_connection_to_dbus() and - * will update all secrets from all settings contained in @secrets. + * extract the given setting's secrets hash if given a connection dictionary. + * If @setting_name is %NULL, expects a fully serialized #NMConnection as + * returned by nm_connection_to_dbus() and will update all secrets from all + * settings contained in @secrets. * * Returns: %TRUE if the secrets were successfully updated, %FALSE if the update * failed (tried to update secrets for a setting that doesn't exist, etc) @@ -945,38 +952,28 @@ nm_connection_normalize (NMConnection *connection, gboolean nm_connection_update_secrets (NMConnection *connection, const char *setting_name, - GHashTable *secrets, + GVariant *secrets, GError **error) { NMSetting *setting; gboolean success = TRUE, updated = FALSE; - GHashTable *setting_hash = NULL; - GHashTableIter iter; + GVariant *setting_dict = NULL; + GVariantIter iter; const char *key; - gboolean hashed_connection = FALSE; + gboolean full_connection; int success_detail; g_return_val_if_fail (NM_IS_CONNECTION (connection), FALSE); - g_return_val_if_fail (secrets != NULL, FALSE); + g_return_val_if_fail ( g_variant_is_of_type (secrets, NM_VARIANT_TYPE_SETTING) + || g_variant_is_of_type (secrets, NM_VARIANT_TYPE_CONNECTION), FALSE); if (error) g_return_val_if_fail (*error == NULL, FALSE); /* Empty @secrets means success */ - if (g_hash_table_size (secrets) == 0) + if (g_variant_n_children (secrets) == 0) return TRUE; - /* For backwards compatibility, this function accepts either a hashed - * connection (GHashTable of GHashTables of GValues) or a single hashed - * setting (GHashTable of GValues). - */ - g_hash_table_iter_init (&iter, secrets); - while (g_hash_table_iter_next (&iter, (gpointer) &key, NULL)) { - if (nm_setting_lookup_type (key) != G_TYPE_INVALID) { - /* @secrets looks like a hashed connection */ - hashed_connection = TRUE; - break; - } - } + full_connection = g_variant_is_of_type (secrets, NM_VARIANT_TYPE_CONNECTION); if (setting_name) { /* Update just one setting's secrets */ @@ -989,10 +986,10 @@ nm_connection_update_secrets (NMConnection *connection, return FALSE; } - if (hashed_connection) { - setting_hash = g_hash_table_lookup (secrets, setting_name); - if (!setting_hash) { - /* The hashed connection that didn't contain any secrets for + if (full_connection) { + setting_dict = g_variant_lookup_value (secrets, setting_name, NM_VARIANT_TYPE_SETTING); + if (!setting_dict) { + /* The connection dictionary didn't contain any secrets for * @setting_name; just return success. */ return TRUE; @@ -1001,16 +998,18 @@ nm_connection_update_secrets (NMConnection *connection, g_signal_handlers_block_by_func (setting, (GCallback) setting_changed_cb, connection); success_detail = _nm_setting_update_secrets (setting, - setting_hash ? setting_hash : secrets, + setting_dict ? setting_dict : secrets, error); g_signal_handlers_unblock_by_func (setting, (GCallback) setting_changed_cb, connection); + g_clear_pointer (&setting_dict, g_variant_unref); + if (success_detail == NM_SETTING_UPDATE_SECRET_ERROR) return FALSE; if (success_detail == NM_SETTING_UPDATE_SECRET_SUCCESS_MODIFIED) updated = TRUE; } else { - if (!hashed_connection) { + if (!full_connection) { g_set_error_literal (error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_SETTING_NOT_FOUND, @@ -1019,8 +1018,8 @@ nm_connection_update_secrets (NMConnection *connection, } /* check first, whether all the settings exist... */ - g_hash_table_iter_init (&iter, secrets); - while (g_hash_table_iter_next (&iter, (gpointer) &key, NULL)) { + g_variant_iter_init (&iter, secrets); + while (g_variant_iter_next (&iter, "{&s@a{sv}}", &key, NULL)) { setting = nm_connection_get_setting_by_name (connection, key); if (!setting) { g_set_error_literal (error, @@ -1031,16 +1030,18 @@ nm_connection_update_secrets (NMConnection *connection, } } - /* Update each setting with any secrets from the hashed connection */ - g_hash_table_iter_init (&iter, secrets); - while (g_hash_table_iter_next (&iter, (gpointer) &key, (gpointer) &setting_hash)) { + /* Update each setting with any secrets from the connection dictionary */ + g_variant_iter_init (&iter, secrets); + while (g_variant_iter_next (&iter, "{&s@a{sv}}", &key, &setting_dict)) { /* Update the secrets for this setting */ setting = nm_connection_get_setting_by_name (connection, key); g_signal_handlers_block_by_func (setting, (GCallback) setting_changed_cb, connection); - success_detail = _nm_setting_update_secrets (setting, setting_hash, error); + success_detail = _nm_setting_update_secrets (setting, setting_dict, error); g_signal_handlers_unblock_by_func (setting, (GCallback) setting_changed_cb, connection); + g_variant_unref (setting_dict); + if (success_detail == NM_SETTING_UPDATE_SECRET_ERROR) { success = FALSE; break; @@ -1184,46 +1185,43 @@ nm_connection_clear_secrets_with_flags (NMConnection *connection, * @connection: the #NMConnection * @flags: serialization flags, e.g. %NM_CONNECTION_SERIALIZE_ALL * - * Converts the #NMConnection into a #GHashTable describing the connection, - * suitable for marshalling over D-Bus or otherwise serializing. The hash table - * mapping is string:#GHashTable with each element in the returned hash - * representing a #NMSetting object. The keys are setting object names, and the - * values are #GHashTables mapping string:GValue, each of which represents the - * properties of the #NMSetting object. + * Converts the #NMConnection into a #GVariant of type + * %NM_VARIANT_TYPE_CONNECTION describing the connection, suitable for + * marshalling over D-Bus or otherwise serializing. * - * Returns: (transfer full) (element-type utf8 GLib.HashTable): a new - * #GHashTable describing the connection, its settings, and each setting's - * properties. The caller owns the hash table and must unref the hash table - * with g_hash_table_unref() when it is no longer needed. + * Returns: (transfer none): a new floating #GVariant describing the connection, + * its settings, and each setting's properties. **/ -GHashTable * -nm_connection_to_dbus (NMConnection *connection, NMConnectionSerializationFlags flags) +GVariant * +nm_connection_to_dbus (NMConnection *connection, + NMConnectionSerializationFlags flags) { NMConnectionPrivate *priv; + GVariantBuilder builder; GHashTableIter iter; gpointer key, data; - GHashTable *ret, *setting_hash; + GVariant *setting_dict, *ret; g_return_val_if_fail (NM_IS_CONNECTION (connection), NULL); - - ret = g_hash_table_new_full (g_str_hash, g_str_equal, - g_free, (GDestroyNotify) g_hash_table_destroy); - priv = NM_CONNECTION_GET_PRIVATE (connection); + g_variant_builder_init (&builder, NM_VARIANT_TYPE_CONNECTION); + /* Add each setting's hash to the main hash */ g_hash_table_iter_init (&iter, priv->settings); while (g_hash_table_iter_next (&iter, &key, &data)) { NMSetting *setting = NM_SETTING (data); - setting_hash = _nm_setting_to_dbus (setting, connection, flags); - if (setting_hash) - g_hash_table_insert (ret, g_strdup (nm_setting_get_name (setting)), setting_hash); + setting_dict = _nm_setting_to_dbus (setting, connection, flags); + if (setting_dict) + g_variant_builder_add (&builder, "{s@a{sv}}", nm_setting_get_name (setting), setting_dict); } + ret = g_variant_builder_end (&builder); + /* Don't send empty hashes */ - if (g_hash_table_size (ret) < 1) { - g_hash_table_destroy (ret); + if (g_variant_n_children (ret) == 0) { + g_variant_unref (ret); ret = NULL; } diff --git a/libnm-core/nm-connection.h b/libnm-core/nm-connection.h index 3987f61b41..de1cd528a4 100644 --- a/libnm-core/nm-connection.h +++ b/libnm-core/nm-connection.h @@ -140,6 +140,25 @@ NMSetting *nm_connection_get_setting (NMConnection *connection, NMSetting *nm_connection_get_setting_by_name (NMConnection *connection, const char *name); +/** + * NM_VARIANT_TYPE_CONNECTION: + * + * #GVariantType for a dictionary mapping from setting names to + * %NM_VARIANT_TYPE_SETTING variants. This is used to represent an + * #NMConnection, and is the type taken by nm_simple_connection_new_from_dbus() + * and returned from nm_connection_to_dbus(). + */ +#define NM_VARIANT_TYPE_CONNECTION (G_VARIANT_TYPE ("a{sa{sv}}")) + +/** + * NM_VARIANT_TYPE_SETTING: + * + * #GVariantType for a dictionary mapping from property names to values. This is + * an alias for %G_VARIANT_TYPE_VARDICT, and is the type of each element of + * an %NM_VARIANT_TYPE_CONNECTION dictionary. + */ +#define NM_VARIANT_TYPE_SETTING G_VARIANT_TYPE_VARDICT + /** * NMConnectionSerializationFlags: * @NM_CONNECTION_SERIALIZE_ALL: serialize all properties (including secrets) @@ -155,11 +174,11 @@ typedef enum { /*< flags >*/ NM_CONNECTION_SERIALIZE_ONLY_SECRETS = 0x00000002, } NMConnectionSerializationFlags; -GHashTable *nm_connection_to_dbus (NMConnection *connection, +GVariant *nm_connection_to_dbus (NMConnection *connection, NMConnectionSerializationFlags flags); gboolean nm_connection_replace_settings (NMConnection *connection, - GHashTable *new_settings, + GVariant *new_settings, GError **error); void nm_connection_replace_settings_from_connection (NMConnection *connection, @@ -193,7 +212,7 @@ void nm_connection_clear_secrets_with_flags (NMConnection *connection, gboolean nm_connection_update_secrets (NMConnection *connection, const char *setting_name, - GHashTable *secrets, + GVariant *secrets, GError **error); void nm_connection_set_path (NMConnection *connection, diff --git a/libnm-core/nm-property-compare.c b/libnm-core/nm-property-compare.c index 4f6fae8bb8..d3ff94de3d 100644 --- a/libnm-core/nm-property-compare.c +++ b/libnm-core/nm-property-compare.c @@ -26,479 +26,68 @@ #include #include #include -#include - -#include "nm-dbus-glib-types.h" - -static gboolean -type_is_fixed_size (GType type, gsize *tsize) -{ - switch (type) { - case G_TYPE_CHAR: - if (tsize) *tsize = sizeof (char); - return TRUE; - case G_TYPE_UCHAR: - if (tsize) *tsize = sizeof (guchar); - return TRUE; - case G_TYPE_BOOLEAN: - if (tsize) *tsize = sizeof (gboolean); - return TRUE; - case G_TYPE_LONG: - if (tsize) *tsize = sizeof (glong); - return TRUE; - case G_TYPE_ULONG: - if (tsize) *tsize = sizeof (gulong); - return TRUE; - case G_TYPE_INT: - if (tsize) *tsize = sizeof (gint); - return TRUE; - case G_TYPE_UINT: - if (tsize) *tsize = sizeof (guint); - return TRUE; - case G_TYPE_INT64: - if (tsize) *tsize = sizeof (gint64); - return TRUE; - case G_TYPE_UINT64: - if (tsize) *tsize = sizeof (guint64); - return TRUE; - case G_TYPE_FLOAT: - if (tsize) *tsize = sizeof (gfloat); - return TRUE; - case G_TYPE_DOUBLE: - if (tsize) *tsize = sizeof (gdouble); - return TRUE; - default: - return FALSE; - } -} - -#define FLOAT_FACTOR 0.00000001 +#include static gint -nm_property_compare_fixed (const GValue *value1, const GValue *value2) +_nm_property_compare_collection (GVariant *value1, GVariant *value2) { - int ret = 0; + GVariant *child1, *child2; + int i, len1, len2; + int ret; - switch (G_VALUE_TYPE (value1)) { - case G_TYPE_CHAR: { - gchar val1 = g_value_get_schar (value1); - gchar val2 = g_value_get_schar (value2); - if (val1 != val2) - ret = val1 < val2 ? -1 : val1 > val2; - break; - } - case G_TYPE_UCHAR: { - guchar val1 = g_value_get_uchar (value1); - guchar val2 = g_value_get_uchar (value2); - if (val1 != val2) - ret = val1 < val2 ? -1 : val1 > val2; - break; - } - case G_TYPE_BOOLEAN: { - gboolean val1 = g_value_get_boolean (value1); - gboolean val2 = g_value_get_boolean (value2); - if (val1 != val2) - ret = val1 < val2 ? -1 : val1 > val2; - break; - } - case G_TYPE_LONG: { - glong val1 = g_value_get_long (value1); - glong val2 = g_value_get_long (value2); - if (val1 != val2) - ret = val1 < val2 ? -1 : val1 > val2; - break; - } - case G_TYPE_ULONG: { - gulong val1 = g_value_get_ulong (value1); - gulong val2 = g_value_get_ulong (value2); - if (val1 != val2) - ret = val1 < val2 ? -1 : val1 > val2; - break; - } - case G_TYPE_INT: { - gint val1 = g_value_get_int (value1); - gint val2 = g_value_get_int (value2); - if (val1 != val2) - ret = val1 < val2 ? -1 : val1 > val2; - break; - } - case G_TYPE_UINT: { - guint val1 = g_value_get_uint (value1); - guint val2 = g_value_get_uint (value2); - if (val1 != val2) - ret = val1 < val2 ? -1 : val1 > val2; - break; - } - case G_TYPE_INT64: { - gint64 val1 = g_value_get_int64 (value1); - gint64 val2 = g_value_get_int64 (value2); - if (val1 != val2) - ret = val1 < val2 ? -1 : val1 > val2; - break; - } - case G_TYPE_UINT64: { - guint64 val1 = g_value_get_uint64 (value1); - guint64 val2 = g_value_get_uint64 (value2); - if (val1 != val2) - ret = val1 < val2 ? -1 : val1 > val2; - break; - } - case G_TYPE_FLOAT: { - gfloat val1 = g_value_get_float (value1); - gfloat val2 = g_value_get_float (value2); - /* Can't use == or != here due to inexactness of FP */ - if (fabsf (val1 - val2) > FLOAT_FACTOR) - ret = val1 < val2 ? -1 : val1 > val2; - break; - } - case G_TYPE_DOUBLE: { - gdouble val1 = g_value_get_double (value1); - gdouble val2 = g_value_get_double (value2); - if (fabs (val1 - val2) > FLOAT_FACTOR) - ret = val1 < val2 ? -1 : val1 > val2; - break; - } - default: - g_warning ("Unhandled fixed size type '%s'", G_VALUE_TYPE_NAME (value1)); - } - - return ret; -} - -static gint -nm_property_compare_string (const GValue *value1, const GValue *value2) -{ - const char *str1 = g_value_get_string (value1); - const char *str2 = g_value_get_string (value2); - - if (str1 == str2) - return 0; - - if (!str1) - return 1; - if (!str2) - return -1; - - return strcmp (str1, str2); -} - -static gint -nm_property_compare_strv (const GValue *value1, const GValue *value2) -{ - char **strv1; - char **strv2; - gint ret; - guint i = 0; - - strv1 = (char **) g_value_get_boxed (value1); - strv2 = (char **) g_value_get_boxed (value2); - - while (strv1[i] && strv2[i]) { - ret = strcmp (strv1[i], strv2[i]); - if (ret) - return ret; - i++; - } - - if (strv1[i] == NULL && strv2[i] == NULL) - return 0; - - if (strv1[i]) - return 1; - - return -1; -} - -static void -_gvalue_destroy (gpointer data) -{ - GValue *value = (GValue *) data; - - g_value_unset (value); - g_slice_free (GValue, value); -} - -static GValue * -_gvalue_dup (const GValue *value) -{ - GValue *dup; - - dup = g_slice_new0 (GValue); - g_value_init (dup, G_VALUE_TYPE (value)); - g_value_copy (value, dup); - - return dup; -} - -static void -iterate_collection (const GValue *value, gpointer user_data) -{ - GSList **list = (GSList **) user_data; - - *list = g_slist_prepend (*list, _gvalue_dup (value)); -} - -static gint -nm_property_compare_collection (const GValue *value1, const GValue *value2) -{ - gint ret; - guint len1; - guint len2; - GType value_type = dbus_g_type_get_collection_specialization (G_VALUE_TYPE (value1)); - gsize element_size = 0; - - if (type_is_fixed_size (value_type, &element_size)) { - gpointer data1 = NULL; - gpointer data2 = NULL; - - dbus_g_type_collection_get_fixed ((GValue *) value1, &data1, &len1); - dbus_g_type_collection_get_fixed ((GValue *) value2, &data2, &len2); - - if (len1 != len2) - ret = len1 < len2 ? -1 : len1 > len2; - else - ret = memcmp (data1, data2, len1 * element_size); - } else { - GSList *list1 = NULL; - GSList *list2 = NULL; - - dbus_g_type_collection_value_iterate (value1, iterate_collection, &list1); - len1 = g_slist_length (list1); - dbus_g_type_collection_value_iterate (value2, iterate_collection, &list2); - len2 = g_slist_length (list2); - - if (len1 != len2) - ret = len1 < len2 ? -1 : len1 > len2; - else { - GSList *iter1; - GSList *iter2; - - for (iter1 = list1, iter2 = list2, ret = 0; - ret == 0 && iter1 && iter2; - iter1 = iter1->next, iter2 = iter2->next) - ret = nm_property_compare ((GValue *) iter1->data, (GValue *) iter2->data); - } - - g_slist_free_full (list1, _gvalue_destroy); - g_slist_free_full (list2, _gvalue_destroy); - } - - return ret; -} - -static void -iterate_map (const GValue *key_val, - const GValue *value_val, - gpointer user_data) -{ - GHashTable **hash = (GHashTable **) user_data; - - g_hash_table_insert (*hash, g_value_dup_string (key_val), _gvalue_dup (value_val)); -} - -typedef struct { - GHashTable *hash2; - gint ret; -} CompareMapInfo; - -static void -compare_one_map_item (gpointer key, gpointer val, gpointer user_data) -{ - CompareMapInfo *info = (CompareMapInfo *) user_data; - GValue *value2; - - if (info->ret) - return; - - value2 = (GValue *) g_hash_table_lookup (info->hash2, key); - if (value2) - info->ret = nm_property_compare ((GValue *) val, value2); - else - info->ret = 1; -} - -static gint -nm_property_compare_map (const GValue *value1, const GValue *value2) -{ - GHashTable *hash1 = NULL; - GHashTable *hash2 = NULL; - guint len1; - guint len2; - gint ret = 0; - - if (dbus_g_type_get_map_key_specialization (G_VALUE_TYPE (value1)) != G_TYPE_STRING) { - g_warning ("Can not compare maps with '%s' for keys", - g_type_name (dbus_g_type_get_map_key_specialization (G_VALUE_TYPE (value1)))); - return 0; - } - - hash1 = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, _gvalue_destroy); - dbus_g_type_map_value_iterate (value1, iterate_map, &hash1); - len1 = g_hash_table_size (hash1); - - hash2 = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, _gvalue_destroy); - dbus_g_type_map_value_iterate (value2, iterate_map, &hash2); - len2 = g_hash_table_size (hash2); + len1 = g_variant_n_children (value1); + len2 = g_variant_n_children (value2); if (len1 != len2) - ret = len1 < len2 ? -1 : len1 > len2; - else { - CompareMapInfo info; + return len1 < len2 ? -1 : len1 > len2; - info.ret = 0; - info.hash2 = hash2; - g_hash_table_foreach (hash1, compare_one_map_item, &info); - ret = info.ret; + for (i = 0; i < len1; i++) { + child1 = g_variant_get_child_value (value1, i); + child2 = g_variant_get_child_value (value2, i); + + ret = nm_property_compare (child1, child2); + g_variant_unref (child1); + g_variant_unref (child2); + + if (ret) + return ret; } - g_hash_table_destroy (hash1); - g_hash_table_destroy (hash2); - - return ret; + return 0; } static gint -_gvalue_ip6_address_compare (const GValue *value1, const GValue *value2) +_nm_property_compare_strdict (GVariant *value1, GVariant *value2) { - GValueArray *values1, *values2; - GValue *tmp_val; - GByteArray *addr1, *addr2; - guint32 prefix1, prefix2; - GByteArray *gw1, *gw2; - gint ret = 0; - int i; + GVariantIter iter; + int len1, len2; + const char *key, *val1, *val2; + int ret; - /* IP6 addresses are GValueArrays (see nm-dbus-glib-types.h) */ - values1 = g_value_get_boxed (value1); - values2 = g_value_get_boxed (value2); + len1 = g_variant_n_children (value1); + len2 = g_variant_n_children (value2); - /* Since they are NM IPv6 address structures, we expect both - * to contain two elements as specified in nm-dbus-glib-types.h. - */ - g_return_val_if_fail (values1->n_values == 3, 0); - g_return_val_if_fail (values2->n_values == 3, 0); + if (len1 != len2) + return len1 < len2 ? -1 : len1 > len2; - /* First struct IPv6 address */ - tmp_val = g_value_array_get_nth (values1, 0); - addr1 = g_value_get_boxed (tmp_val); - /* First struct IPv6 prefix */ - tmp_val = g_value_array_get_nth (values1, 1); - prefix1 = g_value_get_uint (tmp_val); - /* First struct IPv6 gateway */ - tmp_val = g_value_array_get_nth (values1, 2); - gw1 = g_value_get_boxed (tmp_val); + g_variant_iter_init (&iter, value1); + while (g_variant_iter_next (&iter, "{&s&s}", &key, &val1)) { + if (!g_variant_lookup (value2, key, "&s", &val2)) + return -1; - /* Second struct IPv6 address */ - tmp_val = g_value_array_get_nth (values2, 0); - addr2 = g_value_get_boxed (tmp_val); - /* Second struct IPv6 prefix */ - tmp_val = g_value_array_get_nth (values2, 1); - prefix2 = g_value_get_uint (tmp_val); - /* Second struct IPv6 gateway */ - tmp_val = g_value_array_get_nth (values2, 2); - gw2 = g_value_get_boxed (tmp_val); - - /* Compare IPv6 addresses */ - if (prefix1 != prefix2) - return prefix1 < prefix2 ? -1 : prefix1 > prefix2; - - if (!IN6_ARE_ADDR_EQUAL ((struct in6_addr *)addr1->data, (struct in6_addr *)addr2->data)) { - for (i = 0; ret == 0 && i < addr1->len; i++) - ret = addr1->data[i] < addr2->data[i] ? -1 : addr1->data[i] > addr2->data[i]; + ret = strcmp (val1, val2); + if (ret) + return ret; } - if (!IN6_ARE_ADDR_EQUAL ((struct in6_addr *) gw1->data, (struct in6_addr *) gw2->data)) { - for (i = 0; ret == 0 && i < gw1->len; i++) - ret = gw1->data[i] < gw2->data[i] ? -1 : gw1->data[i] > gw2->data[i]; - } - - return ret; -} - -static gint -_gvalue_ip6_route_compare (const GValue *value1, const GValue *value2) -{ - GValueArray *values1, *values2; - GValue *tmp_val; - GByteArray *dest1, *dest2; - GByteArray *next_hop1, *next_hop2; - guint32 prefix1, prefix2; - guint32 metric1, metric2; - gint ret = 0; - int i; - - /* IP6 routes are GValueArrays (see nm-dbus-glib-types.h) */ - values1 = g_value_get_boxed (value1); - values2 = g_value_get_boxed (value2); - - /* Since they are NM IPv6 route structures, we expect both - * to contain 4 elements as specified in nm-dbus-glib-types.h. - */ - g_return_val_if_fail (values1->n_values == 4, 0); - g_return_val_if_fail (values2->n_values == 4, 0); - - /* First struct IPv6 route */ - tmp_val = g_value_array_get_nth (values1, 0); - dest1 = g_value_get_boxed (tmp_val); - tmp_val = g_value_array_get_nth (values1, 1); - prefix1 = g_value_get_uint (tmp_val); - tmp_val = g_value_array_get_nth (values1, 2); - next_hop1 = g_value_get_boxed (tmp_val); - tmp_val = g_value_array_get_nth (values1, 3); - metric1 = g_value_get_uint (tmp_val); - - /* Second struct IPv6 route */ - tmp_val = g_value_array_get_nth (values2, 0); - dest2 = g_value_get_boxed (tmp_val); - tmp_val = g_value_array_get_nth (values2, 1); - prefix2 = g_value_get_uint (tmp_val); - tmp_val = g_value_array_get_nth (values2, 2); - next_hop2 = g_value_get_boxed (tmp_val); - tmp_val = g_value_array_get_nth (values2, 3); - metric2 = g_value_get_uint (tmp_val); - - /* Compare the routes */ - if (prefix1 != prefix2) - return prefix1 < prefix2 ? -1 : prefix1 > prefix2; - - if (!IN6_ARE_ADDR_EQUAL ((struct in6_addr *)dest1->data, (struct in6_addr *)dest2->data)) { - for (i = 0; ret == 0 && i < dest1->len; i++) - ret = dest1->data[i] < dest2->data[i] ? -1 : dest1->data[i] > dest2->data[i]; - } - - if (!IN6_ARE_ADDR_EQUAL ((struct in6_addr *)next_hop1->data, (struct in6_addr *)next_hop2->data)) { - for (i = 0; ret == 0 && i < next_hop1->len; i++) - ret = next_hop1->data[i] < next_hop2->data[i] ? -1 : next_hop1->data[i] > next_hop2->data[i]; - } - - if (metric1 != metric2) - ret = metric1 < metric2 ? -1 : metric1 > metric2; - - return ret; -} - -static gint -nm_property_compare_struct (const GValue *value1, const GValue *value2) -{ - /* value1 and value2 must contain the same type since - * nm_property_compare() enforced that already. - */ - - if (G_VALUE_HOLDS (value1, DBUS_TYPE_G_IP6_ADDRESS)) { - return _gvalue_ip6_address_compare (value1, value2); - } else if (G_VALUE_HOLDS (value1, DBUS_TYPE_G_IP6_ROUTE)) { - return _gvalue_ip6_route_compare (value1, value2); - } else { - g_warning ("Don't know how to compare structures"); - return (value1 == value2); - } + return 0; } int -nm_property_compare (const GValue *value1, const GValue *value2) +nm_property_compare (GVariant *value1, GVariant *value2) { - GType type1; - GType type2; + const GVariantType *type1; + const GVariantType *type2; gint ret; if (value1 == value2) @@ -508,42 +97,22 @@ nm_property_compare (const GValue *value1, const GValue *value2) if (!value2) return -1; - type1 = G_VALUE_TYPE (value1); - type2 = G_VALUE_TYPE (value2); + type1 = g_variant_get_type (value1); + type2 = g_variant_get_type (value2); - if (type1 != type2) + if (!g_variant_type_equal (type1, type2)) return type1 < type2 ? -1 : type1 > type2; - if (type_is_fixed_size (type1, NULL)) - ret = nm_property_compare_fixed (value1, value2); - else if (type1 == G_TYPE_STRING) - ret = nm_property_compare_string (value1, value2); - else if (G_VALUE_HOLDS_BOXED (value1)) { - gpointer p1 = g_value_get_boxed (value1); - gpointer p2 = g_value_get_boxed (value2); - - if (p1 == p2) - ret = 0; /* Exactly the same values */ - else if (!p1) - ret = 1; /* The comparision functions below don't handle NULLs */ - else if (!p2) - ret = -1; /* The comparision functions below don't handle NULLs */ - else if (type1 == G_TYPE_STRV) - ret = nm_property_compare_strv (value1, value2); - else if (dbus_g_type_is_collection (type1)) - ret = nm_property_compare_collection (value1, value2); - else if (dbus_g_type_is_map (type1)) - ret = nm_property_compare_map (value1, value2); - else if (dbus_g_type_is_struct (type1)) - ret = nm_property_compare_struct (value1, value2); - else if (type1 == G_TYPE_VALUE) - ret = nm_property_compare ((GValue *) g_value_get_boxed (value1), (GValue *) g_value_get_boxed (value2)); - else { - g_warning ("Don't know how to compare boxed types '%s'", g_type_name (type1)); - ret = value1 == value2; - } - } else { - g_warning ("Don't know how to compare types '%s'", g_type_name (type1)); + if (g_variant_type_is_basic (type1)) + ret = g_variant_compare (value1, value2); + else if (g_variant_is_of_type (value1, G_VARIANT_TYPE ("a{ss}"))) + ret = _nm_property_compare_strdict (value1, value2); + else if (g_variant_type_is_array (type1)) + ret = _nm_property_compare_collection (value1, value2); + else if (g_variant_type_is_tuple (type1)) + ret = _nm_property_compare_collection (value1, value2); + else { + g_warning ("Don't know how to compare variant type '%s'", (const char *) type1); ret = value1 == value2; } diff --git a/libnm-core/nm-property-compare.h b/libnm-core/nm-property-compare.h index 72fc76baf7..33016787ff 100644 --- a/libnm-core/nm-property-compare.h +++ b/libnm-core/nm-property-compare.h @@ -23,8 +23,8 @@ #ifndef __NM_PROPERTY_COMPARE_H__ #define __NM_PROPERTY_COMPARE_H__ -#include +#include -int nm_property_compare (const GValue *value1, const GValue *value2); +int nm_property_compare (GVariant *value1, GVariant *value2); #endif /* __NM_PROPERTY_COMPARE_H__ */ diff --git a/libnm-core/nm-setting-8021x.c b/libnm-core/nm-setting-8021x.c index 0a63b74043..1d40f8f148 100644 --- a/libnm-core/nm-setting-8021x.c +++ b/libnm-core/nm-setting-8021x.c @@ -21,12 +21,10 @@ */ #include -#include #include #include "nm-setting-8021x.h" #include "nm-utils.h" -#include "nm-dbus-glib-types.h" #include "crypto.h" #include "nm-utils-private.h" #include "nm-setting-private.h" @@ -3188,7 +3186,7 @@ nm_setting_802_1x_class_init (NMSetting8021xClass *setting_class) G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); _nm_setting_class_transform_property (parent_class, NM_SETTING_802_1X_CA_CERT, - DBUS_TYPE_G_UCHAR_ARRAY, + G_VARIANT_TYPE_BYTESTRING, _nm_utils_bytes_to_dbus, _nm_utils_bytes_from_dbus); @@ -3257,7 +3255,7 @@ nm_setting_802_1x_class_init (NMSetting8021xClass *setting_class) G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); _nm_setting_class_transform_property (parent_class, NM_SETTING_802_1X_CLIENT_CERT, - DBUS_TYPE_G_UCHAR_ARRAY, + G_VARIANT_TYPE_BYTESTRING, _nm_utils_bytes_to_dbus, _nm_utils_bytes_from_dbus); @@ -3370,7 +3368,7 @@ nm_setting_802_1x_class_init (NMSetting8021xClass *setting_class) G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); _nm_setting_class_transform_property (parent_class, NM_SETTING_802_1X_PHASE2_CA_CERT, - DBUS_TYPE_G_UCHAR_ARRAY, + G_VARIANT_TYPE_BYTESTRING, _nm_utils_bytes_to_dbus, _nm_utils_bytes_from_dbus); @@ -3444,7 +3442,7 @@ nm_setting_802_1x_class_init (NMSetting8021xClass *setting_class) G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); _nm_setting_class_transform_property (parent_class, NM_SETTING_802_1X_PHASE2_CLIENT_CERT, - DBUS_TYPE_G_UCHAR_ARRAY, + G_VARIANT_TYPE_BYTESTRING, _nm_utils_bytes_to_dbus, _nm_utils_bytes_from_dbus); @@ -3493,7 +3491,7 @@ nm_setting_802_1x_class_init (NMSetting8021xClass *setting_class) NM_SETTING_PARAM_SECRET | G_PARAM_STATIC_STRINGS)); _nm_setting_class_transform_property (parent_class, NM_SETTING_802_1X_PASSWORD_RAW, - DBUS_TYPE_G_UCHAR_ARRAY, + G_VARIANT_TYPE_BYTESTRING, _nm_utils_bytes_to_dbus, _nm_utils_bytes_from_dbus); @@ -3548,7 +3546,7 @@ nm_setting_802_1x_class_init (NMSetting8021xClass *setting_class) G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); _nm_setting_class_transform_property (parent_class, NM_SETTING_802_1X_PRIVATE_KEY, - DBUS_TYPE_G_UCHAR_ARRAY, + G_VARIANT_TYPE_BYTESTRING, _nm_utils_bytes_to_dbus, _nm_utils_bytes_from_dbus); @@ -3617,7 +3615,7 @@ nm_setting_802_1x_class_init (NMSetting8021xClass *setting_class) G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); _nm_setting_class_transform_property (parent_class, NM_SETTING_802_1X_PHASE2_PRIVATE_KEY, - DBUS_TYPE_G_UCHAR_ARRAY, + G_VARIANT_TYPE_BYTESTRING, _nm_utils_bytes_to_dbus, _nm_utils_bytes_from_dbus); diff --git a/libnm-core/nm-setting-bluetooth.c b/libnm-core/nm-setting-bluetooth.c index 44e71e06da..8791744a04 100644 --- a/libnm-core/nm-setting-bluetooth.c +++ b/libnm-core/nm-setting-bluetooth.c @@ -24,7 +24,6 @@ #include #include -#include "nm-dbus-glib-types.h" #include "nm-setting-bluetooth.h" #include "nm-setting-cdma.h" #include "nm-setting-gsm.h" @@ -276,7 +275,7 @@ nm_setting_bluetooth_class_init (NMSettingBluetoothClass *setting_class) NM_SETTING_PARAM_INFERRABLE | G_PARAM_STATIC_STRINGS)); _nm_setting_class_transform_property (parent_class, NM_SETTING_BLUETOOTH_BDADDR, - DBUS_TYPE_G_UCHAR_ARRAY, + G_VARIANT_TYPE_BYTESTRING, _nm_utils_hwaddr_to_dbus, _nm_utils_hwaddr_from_dbus); diff --git a/libnm-core/nm-setting-bond.c b/libnm-core/nm-setting-bond.c index 22ef5dd213..c7eb9b2db5 100644 --- a/libnm-core/nm-setting-bond.c +++ b/libnm-core/nm-setting-bond.c @@ -24,13 +24,11 @@ #include #include #include -#include #include #include "nm-setting-bond.h" #include "nm-utils.h" #include "nm-utils-private.h" -#include "nm-dbus-glib-types.h" #include "nm-setting-private.h" /** @@ -734,11 +732,12 @@ nm_setting_bond_class_init (NMSettingBondClass *setting_class) NM_SETTING_PARAM_INFERRABLE | G_PARAM_STATIC_STRINGS)); _nm_setting_class_transform_property (parent_class, NM_SETTING_BOND_OPTIONS, - DBUS_TYPE_G_MAP_OF_STRING, + G_VARIANT_TYPE ("a{ss}"), _nm_utils_strdict_to_dbus, _nm_utils_strdict_from_dbus); - _nm_setting_class_add_dbus_only_property (parent_class, "interface-name", G_TYPE_STRING, + _nm_setting_class_add_dbus_only_property (parent_class, "interface-name", + G_VARIANT_TYPE_STRING, _nm_setting_get_deprecated_virtual_interface_name, NULL); } diff --git a/libnm-core/nm-setting-bridge-port.c b/libnm-core/nm-setting-bridge-port.c index b4826f3f56..ffd21638c8 100644 --- a/libnm-core/nm-setting-bridge-port.c +++ b/libnm-core/nm-setting-bridge-port.c @@ -22,7 +22,6 @@ #include #include #include -#include #include #include "nm-setting-bridge-port.h" diff --git a/libnm-core/nm-setting-bridge.c b/libnm-core/nm-setting-bridge.c index 49bca2e813..720f5cb278 100644 --- a/libnm-core/nm-setting-bridge.c +++ b/libnm-core/nm-setting-bridge.c @@ -22,7 +22,6 @@ #include #include #include -#include #include #include "nm-setting-bridge.h" @@ -388,7 +387,7 @@ nm_setting_bridge_class_init (NMSettingBridgeClass *setting_class) NM_SETTING_PARAM_INFERRABLE | G_PARAM_STATIC_STRINGS)); _nm_setting_class_transform_property (parent_class, NM_SETTING_BRIDGE_MAC_ADDRESS, - DBUS_TYPE_G_UCHAR_ARRAY, + G_VARIANT_TYPE_BYTESTRING, _nm_utils_hwaddr_to_dbus, _nm_utils_hwaddr_from_dbus); @@ -478,7 +477,8 @@ nm_setting_bridge_class_init (NMSettingBridgeClass *setting_class) NM_SETTING_PARAM_INFERRABLE | G_PARAM_STATIC_STRINGS)); - _nm_setting_class_add_dbus_only_property (parent_class, "interface-name", G_TYPE_STRING, + _nm_setting_class_add_dbus_only_property (parent_class, "interface-name", + G_VARIANT_TYPE_STRING, _nm_setting_get_deprecated_virtual_interface_name, NULL); } diff --git a/libnm-core/nm-setting-connection.c b/libnm-core/nm-setting-connection.c index 200b9a7cd7..e6b537122a 100644 --- a/libnm-core/nm-setting-connection.c +++ b/libnm-core/nm-setting-connection.c @@ -949,35 +949,34 @@ verify (NMSetting *setting, GSList *all_settings, GError **error) } static const char * -find_virtual_interface_name (GHashTable *connection_hash) +find_virtual_interface_name (GVariant *connection_dict) { - GHashTable *setting_hash; - GValue *value; + GVariant *setting_dict; + const char *interface_name; - setting_hash = g_hash_table_lookup (connection_hash, NM_SETTING_BOND_SETTING_NAME); - if (!setting_hash) - setting_hash = g_hash_table_lookup (connection_hash, NM_SETTING_BRIDGE_SETTING_NAME); - if (!setting_hash) - setting_hash = g_hash_table_lookup (connection_hash, NM_SETTING_TEAM_SETTING_NAME); - if (!setting_hash) - setting_hash = g_hash_table_lookup (connection_hash, NM_SETTING_VLAN_SETTING_NAME); + setting_dict = g_variant_lookup_value (connection_dict, NM_SETTING_BOND_SETTING_NAME, NM_VARIANT_TYPE_SETTING); + if (!setting_dict) + setting_dict = g_variant_lookup_value (connection_dict, NM_SETTING_BRIDGE_SETTING_NAME, NM_VARIANT_TYPE_SETTING); + if (!setting_dict) + setting_dict = g_variant_lookup_value (connection_dict, NM_SETTING_TEAM_SETTING_NAME, NM_VARIANT_TYPE_SETTING); + if (!setting_dict) + setting_dict = g_variant_lookup_value (connection_dict, NM_SETTING_VLAN_SETTING_NAME, NM_VARIANT_TYPE_SETTING); - if (!setting_hash) + if (!setting_dict) return NULL; /* All of the deprecated virtual interface name properties were named "interface-name". */ - value = g_hash_table_lookup (setting_hash, "interface-name"); - if (!value || !G_VALUE_HOLDS_STRING (value)) + if (!g_variant_lookup (setting_dict, "interface-name", "&s", &interface_name)) return NULL; - return g_value_get_string (value); + return interface_name; } static void nm_setting_connection_set_interface_name (NMSetting *setting, - GHashTable *connection_hash, + GVariant *connection_dict, const char *property, - const GValue *value) + GVariant *value) { const char *interface_name; @@ -985,9 +984,9 @@ nm_setting_connection_set_interface_name (NMSetting *setting, * we need to make verification fail, even if that virtual name would be * overridden by a valid connection.interface-name. */ - interface_name = find_virtual_interface_name (connection_hash); + interface_name = find_virtual_interface_name (connection_dict); if (!interface_name || nm_utils_iface_valid_name (interface_name)) - interface_name = g_value_get_string (value); + interface_name = g_variant_get_string (value, NULL); g_object_set (G_OBJECT (setting), NM_SETTING_CONNECTION_INTERFACE_NAME, interface_name, @@ -996,12 +995,12 @@ nm_setting_connection_set_interface_name (NMSetting *setting, static void nm_setting_connection_no_interface_name (NMSetting *setting, - GHashTable *connection_hash, + GVariant *connection_dict, const char *property) { const char *virtual_interface_name; - virtual_interface_name = find_virtual_interface_name (connection_hash); + virtual_interface_name = find_virtual_interface_name (connection_dict); g_object_set (G_OBJECT (setting), NM_SETTING_CONNECTION_INTERFACE_NAME, virtual_interface_name, NULL); @@ -1271,7 +1270,7 @@ nm_setting_connection_class_init (NMSettingConnectionClass *setting_class) NM_SETTING_PARAM_INFERRABLE | G_PARAM_STATIC_STRINGS)); _nm_setting_class_override_property (parent_class, NM_SETTING_CONNECTION_INTERFACE_NAME, - G_TYPE_STRING, + G_VARIANT_TYPE_STRING, NULL, nm_setting_connection_set_interface_name, nm_setting_connection_no_interface_name); diff --git a/libnm-core/nm-setting-dcb.c b/libnm-core/nm-setting-dcb.c index 67955b5809..8943db6b8f 100644 --- a/libnm-core/nm-setting-dcb.c +++ b/libnm-core/nm-setting-dcb.c @@ -20,13 +20,11 @@ */ #include -#include #include #include "nm-setting-dcb.h" #include "nm-utils.h" #include "nm-utils-private.h" -#include "nm-dbus-glib-types.h" #include "nm-setting-private.h" /** @@ -777,23 +775,23 @@ set_gvalue_from_array (GValue *v, uint *a, size_t len) #define SET_GVALUE_FROM_ARRAY(v, a) set_gvalue_from_array (v, a, G_N_ELEMENTS (a)) -static void -_nm_setting_dcb_uint_array_to_dbus (const GValue *prop_value, - GValue *dbus_value) +static GVariant * +_nm_setting_dcb_uint_array_to_dbus (const GValue *prop_value) { GArray *src = g_value_get_boxed (prop_value); - set_gvalue_from_array (dbus_value, (guint *) src->data, src->len); + return g_variant_new_fixed_array (G_VARIANT_TYPE_UINT32, src->data, src->len, sizeof (guint32)); } static void -_nm_setting_dcb_uint_array_from_dbus (const GValue *dbus_value, +_nm_setting_dcb_uint_array_from_dbus (GVariant *dbus_value, GValue *prop_value) { - GArray *src = g_value_get_boxed (dbus_value); - - set_gvalue_from_array (prop_value, (guint *) src->data, src->len); + gconstpointer array; + gsize length; + array = g_variant_get_fixed_array (dbus_value, &length, sizeof (guint32)); + set_gvalue_from_array (prop_value, (guint *) array, length); } static void @@ -1058,7 +1056,7 @@ nm_setting_dcb_class_init (NMSettingDcbClass *setting_class) G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); _nm_setting_class_transform_property (parent_class, NM_SETTING_DCB_PRIORITY_FLOW_CONTROL, - DBUS_TYPE_G_UINT_ARRAY, + G_VARIANT_TYPE ("au"), _nm_setting_dcb_uint_array_to_dbus, _nm_setting_dcb_uint_array_from_dbus); @@ -1092,7 +1090,7 @@ nm_setting_dcb_class_init (NMSettingDcbClass *setting_class) G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); _nm_setting_class_transform_property (parent_class, NM_SETTING_DCB_PRIORITY_GROUP_ID, - DBUS_TYPE_G_UINT_ARRAY, + G_VARIANT_TYPE ("au"), _nm_setting_dcb_uint_array_to_dbus, _nm_setting_dcb_uint_array_from_dbus); @@ -1113,7 +1111,7 @@ nm_setting_dcb_class_init (NMSettingDcbClass *setting_class) G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); _nm_setting_class_transform_property (parent_class, NM_SETTING_DCB_PRIORITY_GROUP_BANDWIDTH, - DBUS_TYPE_G_UINT_ARRAY, + G_VARIANT_TYPE ("au"), _nm_setting_dcb_uint_array_to_dbus, _nm_setting_dcb_uint_array_from_dbus); @@ -1135,7 +1133,7 @@ nm_setting_dcb_class_init (NMSettingDcbClass *setting_class) G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); _nm_setting_class_transform_property (parent_class, NM_SETTING_DCB_PRIORITY_BANDWIDTH, - DBUS_TYPE_G_UINT_ARRAY, + G_VARIANT_TYPE ("au"), _nm_setting_dcb_uint_array_to_dbus, _nm_setting_dcb_uint_array_from_dbus); @@ -1155,7 +1153,7 @@ nm_setting_dcb_class_init (NMSettingDcbClass *setting_class) G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); _nm_setting_class_transform_property (parent_class, NM_SETTING_DCB_PRIORITY_STRICT_BANDWIDTH, - DBUS_TYPE_G_UINT_ARRAY, + G_VARIANT_TYPE ("au"), _nm_setting_dcb_uint_array_to_dbus, _nm_setting_dcb_uint_array_from_dbus); @@ -1175,7 +1173,7 @@ nm_setting_dcb_class_init (NMSettingDcbClass *setting_class) G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); _nm_setting_class_transform_property (parent_class, NM_SETTING_DCB_PRIORITY_TRAFFIC_CLASS, - DBUS_TYPE_G_UINT_ARRAY, + G_VARIANT_TYPE ("au"), _nm_setting_dcb_uint_array_to_dbus, _nm_setting_dcb_uint_array_from_dbus); } diff --git a/libnm-core/nm-setting-gsm.c b/libnm-core/nm-setting-gsm.c index 70f0501e8d..3d497f7540 100644 --- a/libnm-core/nm-setting-gsm.c +++ b/libnm-core/nm-setting-gsm.c @@ -625,9 +625,9 @@ nm_setting_gsm_class_init (NMSettingGsmClass *setting_class) /* Ignore incoming deprecated properties */ _nm_setting_class_add_dbus_only_property (parent_class, "allowed-bands", - G_TYPE_UINT, + G_VARIANT_TYPE_UINT32, NULL, NULL); _nm_setting_class_add_dbus_only_property (parent_class, "network-type", - G_TYPE_INT, + G_VARIANT_TYPE_INT32, NULL, NULL); } diff --git a/libnm-core/nm-setting-infiniband.c b/libnm-core/nm-setting-infiniband.c index a5bbf92664..6c8d31e23c 100644 --- a/libnm-core/nm-setting-infiniband.c +++ b/libnm-core/nm-setting-infiniband.c @@ -20,7 +20,6 @@ */ #include -#include #include #include "nm-setting-infiniband.h" @@ -419,7 +418,7 @@ nm_setting_infiniband_class_init (NMSettingInfinibandClass *setting_class) NM_SETTING_PARAM_INFERRABLE | G_PARAM_STATIC_STRINGS)); _nm_setting_class_transform_property (parent_class, NM_SETTING_INFINIBAND_MAC_ADDRESS, - DBUS_TYPE_G_UCHAR_ARRAY, + G_VARIANT_TYPE_BYTESTRING, _nm_utils_hwaddr_to_dbus, _nm_utils_hwaddr_from_dbus); diff --git a/libnm-core/nm-setting-ip4-config.c b/libnm-core/nm-setting-ip4-config.c index ef31832dc2..ba31bcedb6 100644 --- a/libnm-core/nm-setting-ip4-config.c +++ b/libnm-core/nm-setting-ip4-config.c @@ -21,12 +21,10 @@ */ #include -#include #include #include "nm-setting-ip4-config.h" #include "nm-utils.h" -#include "nm-dbus-glib-types.h" #include "nm-glib-compat.h" #include "nm-setting-private.h" #include "nm-core-internal.h" @@ -1095,6 +1093,45 @@ finalize (GObject *object) G_OBJECT_CLASS (nm_setting_ip4_config_parent_class)->finalize (object); } +static GVariant * +ip4_dns_to_dbus (const GValue *prop_value) +{ + return nm_utils_ip4_dns_to_variant (g_value_get_boxed (prop_value)); +} + +static void +ip4_dns_from_dbus (GVariant *dbus_value, + GValue *prop_value) +{ + g_value_take_boxed (prop_value, nm_utils_ip4_dns_from_variant (dbus_value)); +} + +static GVariant * +ip4_addresses_to_dbus (const GValue *prop_value) +{ + return nm_utils_ip4_addresses_to_variant (g_value_get_boxed (prop_value)); +} + +static void +ip4_addresses_from_dbus (GVariant *dbus_value, + GValue *prop_value) +{ + g_value_take_boxed (prop_value, nm_utils_ip4_addresses_from_variant (dbus_value)); +} + +static GVariant * +ip4_routes_to_dbus (const GValue *prop_value) +{ + return nm_utils_ip4_routes_to_variant (g_value_get_boxed (prop_value)); +} + +static void +ip4_routes_from_dbus (GVariant *dbus_value, + GValue *prop_value) +{ + g_value_take_boxed (prop_value, nm_utils_ip4_routes_from_variant (dbus_value)); +} + static void set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) @@ -1275,9 +1312,9 @@ nm_setting_ip4_config_class_init (NMSettingIP4ConfigClass *setting_class) G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); _nm_setting_class_transform_property (parent_class, NM_SETTING_IP4_CONFIG_DNS, - DBUS_TYPE_G_UINT_ARRAY, - _nm_utils_ip4_dns_to_dbus, - _nm_utils_ip4_dns_from_dbus); + G_VARIANT_TYPE ("au"), + ip4_dns_to_dbus, + ip4_dns_from_dbus); /** * NMSettingIP4Config:dns-search: @@ -1314,9 +1351,9 @@ nm_setting_ip4_config_class_init (NMSettingIP4ConfigClass *setting_class) NM_SETTING_PARAM_INFERRABLE | G_PARAM_STATIC_STRINGS)); _nm_setting_class_transform_property (parent_class, NM_SETTING_IP4_CONFIG_ADDRESSES, - DBUS_TYPE_G_ARRAY_OF_ARRAY_OF_UINT, - _nm_utils_ip4_addresses_to_dbus, - _nm_utils_ip4_addresses_from_dbus); + G_VARIANT_TYPE ("aau"), + ip4_addresses_to_dbus, + ip4_addresses_from_dbus); /** * NMSettingIP4Config:address-labels: @@ -1349,9 +1386,9 @@ nm_setting_ip4_config_class_init (NMSettingIP4ConfigClass *setting_class) NM_SETTING_PARAM_INFERRABLE | G_PARAM_STATIC_STRINGS)); _nm_setting_class_transform_property (parent_class, NM_SETTING_IP4_CONFIG_ROUTES, - DBUS_TYPE_G_ARRAY_OF_ARRAY_OF_UINT, - _nm_utils_ip4_routes_to_dbus, - _nm_utils_ip4_routes_from_dbus); + G_VARIANT_TYPE ("aau"), + ip4_routes_to_dbus, + ip4_routes_from_dbus); /** * NMSettingIP4Config:ignore-auto-routes: diff --git a/libnm-core/nm-setting-ip6-config.c b/libnm-core/nm-setting-ip6-config.c index 6c085404d0..81e04dbf37 100644 --- a/libnm-core/nm-setting-ip6-config.c +++ b/libnm-core/nm-setting-ip6-config.c @@ -20,13 +20,11 @@ */ #include -#include #include #include "nm-setting-ip6-config.h" #include "nm-utils.h" #include "nm-utils-private.h" -#include "nm-dbus-glib-types.h" #include "nm-glib-compat.h" #include "nm-setting-private.h" @@ -923,6 +921,45 @@ finalize (GObject *object) G_OBJECT_CLASS (nm_setting_ip6_config_parent_class)->finalize (object); } +static GVariant * +ip6_dns_to_dbus (const GValue *prop_value) +{ + return nm_utils_ip6_dns_to_variant (g_value_get_boxed (prop_value)); +} + +static void +ip6_dns_from_dbus (GVariant *dbus_value, + GValue *prop_value) +{ + g_value_take_boxed (prop_value, nm_utils_ip6_dns_from_variant (dbus_value)); +} + +static GVariant * +ip6_addresses_to_dbus (const GValue *prop_value) +{ + return nm_utils_ip6_addresses_to_variant (g_value_get_boxed (prop_value)); +} + +static void +ip6_addresses_from_dbus (GVariant *dbus_value, + GValue *prop_value) +{ + g_value_take_boxed (prop_value, nm_utils_ip6_addresses_from_variant (dbus_value)); +} + +static GVariant * +ip6_routes_to_dbus (const GValue *prop_value) +{ + return nm_utils_ip6_routes_to_variant (g_value_get_boxed (prop_value)); +} + +static void +ip6_routes_from_dbus (GVariant *dbus_value, + GValue *prop_value) +{ + g_value_take_boxed (prop_value, nm_utils_ip6_routes_from_variant (dbus_value)); +} + static void set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) @@ -1090,9 +1127,9 @@ nm_setting_ip6_config_class_init (NMSettingIP6ConfigClass *setting_class) G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); _nm_setting_class_transform_property (parent_class, NM_SETTING_IP6_CONFIG_DNS, - DBUS_TYPE_G_ARRAY_OF_ARRAY_OF_UCHAR, - _nm_utils_ip6_dns_to_dbus, - _nm_utils_ip6_dns_from_dbus); + G_VARIANT_TYPE ("aay"), + ip6_dns_to_dbus, + ip6_dns_from_dbus); /** * NMSettingIP6Config:dns-search: @@ -1128,9 +1165,9 @@ nm_setting_ip6_config_class_init (NMSettingIP6ConfigClass *setting_class) NM_SETTING_PARAM_INFERRABLE | G_PARAM_STATIC_STRINGS)); _nm_setting_class_transform_property (parent_class, NM_SETTING_IP6_CONFIG_ADDRESSES, - DBUS_TYPE_G_ARRAY_OF_IP6_ADDRESS, - _nm_utils_ip6_addresses_to_dbus, - _nm_utils_ip6_addresses_from_dbus); + G_VARIANT_TYPE ("a(ayuay)"), + ip6_addresses_to_dbus, + ip6_addresses_from_dbus); /** * NMSettingIP6Config:routes: @@ -1149,9 +1186,9 @@ nm_setting_ip6_config_class_init (NMSettingIP6ConfigClass *setting_class) NM_SETTING_PARAM_INFERRABLE | G_PARAM_STATIC_STRINGS)); _nm_setting_class_transform_property (parent_class, NM_SETTING_IP6_CONFIG_ROUTES, - DBUS_TYPE_G_ARRAY_OF_IP6_ROUTE, - _nm_utils_ip6_routes_to_dbus, - _nm_utils_ip6_routes_from_dbus); + G_VARIANT_TYPE ("a(ayuayu)"), + ip6_routes_to_dbus, + ip6_routes_from_dbus); /** * NMSettingIP6Config:ignore-auto-routes: diff --git a/libnm-core/nm-setting-olpc-mesh.c b/libnm-core/nm-setting-olpc-mesh.c index 378aa044da..2d5967c6d2 100644 --- a/libnm-core/nm-setting-olpc-mesh.c +++ b/libnm-core/nm-setting-olpc-mesh.c @@ -21,13 +21,11 @@ */ #include -#include #include #include "nm-setting-olpc-mesh.h" #include "nm-dbus-interface.h" #include "nm-utils.h" -#include "nm-dbus-glib-types.h" #include "nm-utils-private.h" #include "nm-setting-private.h" @@ -239,7 +237,7 @@ nm_setting_olpc_mesh_class_init (NMSettingOlpcMeshClass *setting_class) NM_SETTING_PARAM_INFERRABLE | G_PARAM_STATIC_STRINGS)); _nm_setting_class_transform_property (parent_class, NM_SETTING_OLPC_MESH_SSID, - DBUS_TYPE_G_UCHAR_ARRAY, + G_VARIANT_TYPE_BYTESTRING, _nm_utils_bytes_to_dbus, _nm_utils_bytes_from_dbus); @@ -271,7 +269,7 @@ nm_setting_olpc_mesh_class_init (NMSettingOlpcMeshClass *setting_class) G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); _nm_setting_class_transform_property (parent_class, NM_SETTING_OLPC_MESH_DHCP_ANYCAST_ADDRESS, - DBUS_TYPE_G_UCHAR_ARRAY, + G_VARIANT_TYPE_BYTESTRING, _nm_utils_hwaddr_to_dbus, _nm_utils_hwaddr_from_dbus); } diff --git a/libnm-core/nm-setting-private.h b/libnm-core/nm-setting-private.h index e7c141a05d..f277992481 100644 --- a/libnm-core/nm-setting-private.h +++ b/libnm-core/nm-setting-private.h @@ -66,7 +66,7 @@ typedef enum NMSettingUpdateSecretResult { } NMSettingUpdateSecretResult; NMSettingUpdateSecretResult _nm_setting_update_secrets (NMSetting *setting, - GHashTable *secrets, + GVariant *secrets, GError **error); gboolean _nm_setting_clear_secrets (NMSetting *setting); gboolean _nm_setting_clear_secrets_with_flags (NMSetting *setting, @@ -104,10 +104,9 @@ NMSetting * _nm_setting_find_in_list_required (GSList *all_settings, NMSettingVerifyResult _nm_setting_verify_required_virtual_interface_name (GSList *all_settings, GError **error); -gboolean _nm_setting_get_deprecated_virtual_interface_name (NMSetting *setting, - NMConnection *connection, - const char *property, - GValue *value); +GVariant *_nm_setting_get_deprecated_virtual_interface_name (NMSetting *setting, + NMConnection *connection, + const char *property); NMSettingVerifyResult _nm_setting_verify (NMSetting *setting, GSList *all_settings, @@ -117,47 +116,46 @@ NMSetting *_nm_setting_find_in_list_base_type (GSList *all_settings); gboolean _nm_setting_slave_type_is_valid (const char *slave_type, const char **out_port_type); const char * _nm_setting_slave_type_detect_from_settings (GSList *all_settings, NMSetting **out_s_port); -GHashTable *_nm_setting_to_dbus (NMSetting *setting, +GVariant *_nm_setting_to_dbus (NMSetting *setting, NMConnection *connection, NMConnectionSerializationFlags flags); NMSetting *_nm_setting_new_from_dbus (GType setting_type, - GHashTable *setting_hash, - GHashTable *connection_hash, + GVariant *setting_dict, + GVariant *connection_dict, GError **error); -typedef gboolean (*NMSettingPropertyGetFunc) (NMSetting *setting, - NMConnection *connection, - const char *property, - GValue *value); -typedef void (*NMSettingPropertySetFunc) (NMSetting *setting, - GHashTable *connection_hash, - const char *property, - const GValue *value); -typedef void (*NMSettingPropertyNotSetFunc) (NMSetting *setting, - GHashTable *connection_hash, - const char *property); +typedef GVariant * (*NMSettingPropertyGetFunc) (NMSetting *setting, + NMConnection *connection, + const char *property); +typedef void (*NMSettingPropertySetFunc) (NMSetting *setting, + GVariant *connection_dict, + const char *property, + GVariant *value); +typedef void (*NMSettingPropertyNotSetFunc) (NMSetting *setting, + GVariant *connection_dict, + const char *property); void _nm_setting_class_add_dbus_only_property (NMSettingClass *setting_class, const char *property_name, - GType dbus_type, + const GVariantType *dbus_type, NMSettingPropertyGetFunc get_func, NMSettingPropertySetFunc set_func); void _nm_setting_class_override_property (NMSettingClass *setting_class, const char *property_name, - GType dbus_type, + const GVariantType *dbus_type, NMSettingPropertyGetFunc get_func, NMSettingPropertySetFunc set_func, NMSettingPropertyNotSetFunc not_set_func); -typedef void (*NMSettingPropertyTransformFunc) (const GValue *from, - GValue *to); +typedef GVariant * (*NMSettingPropertyTransformToFunc) (const GValue *from); +typedef void (*NMSettingPropertyTransformFromFunc) (GVariant *from, GValue *to); void _nm_setting_class_transform_property (NMSettingClass *setting_class, const char *property_name, - GType dbus_type, - NMSettingPropertyTransformFunc to_dbus, - NMSettingPropertyTransformFunc from_dbus); + const GVariantType *dbus_type, + NMSettingPropertyTransformToFunc to_dbus, + NMSettingPropertyTransformFromFunc from_dbus); #endif /* NM_SETTING_PRIVATE_H */ diff --git a/libnm-core/nm-setting-team-port.c b/libnm-core/nm-setting-team-port.c index cbed8de48f..1e04d68c69 100644 --- a/libnm-core/nm-setting-team-port.c +++ b/libnm-core/nm-setting-team-port.c @@ -21,7 +21,6 @@ #include #include #include -#include #include #include "nm-setting-team-port.h" diff --git a/libnm-core/nm-setting-team.c b/libnm-core/nm-setting-team.c index 8fb94c3992..cb41e6f0a5 100644 --- a/libnm-core/nm-setting-team.c +++ b/libnm-core/nm-setting-team.c @@ -20,13 +20,11 @@ #include #include -#include #include #include "nm-setting-team.h" #include "nm-utils.h" #include "nm-utils-private.h" -#include "nm-dbus-glib-types.h" #include "nm-setting-private.h" /** @@ -183,7 +181,8 @@ nm_setting_team_class_init (NMSettingTeamClass *setting_class) NM_SETTING_PARAM_INFERRABLE | G_PARAM_STATIC_STRINGS)); - _nm_setting_class_add_dbus_only_property (parent_class, "interface-name", G_TYPE_STRING, + _nm_setting_class_add_dbus_only_property (parent_class, "interface-name", + G_VARIANT_TYPE_STRING, _nm_setting_get_deprecated_virtual_interface_name, NULL); } diff --git a/libnm-core/nm-setting-vlan.c b/libnm-core/nm-setting-vlan.c index 55262264b2..e043518615 100644 --- a/libnm-core/nm-setting-vlan.c +++ b/libnm-core/nm-setting-vlan.c @@ -777,7 +777,8 @@ nm_setting_vlan_class_init (NMSettingVlanClass *setting_class) NM_SETTING_PARAM_INFERRABLE | G_PARAM_STATIC_STRINGS)); - _nm_setting_class_add_dbus_only_property (parent_class, "interface-name", G_TYPE_STRING, + _nm_setting_class_add_dbus_only_property (parent_class, "interface-name", + G_VARIANT_TYPE_STRING, _nm_setting_get_deprecated_virtual_interface_name, NULL); } diff --git a/libnm-core/nm-setting-vpn.c b/libnm-core/nm-setting-vpn.c index 30a4893d31..6ce4145029 100644 --- a/libnm-core/nm-setting-vpn.c +++ b/libnm-core/nm-setting-vpn.c @@ -22,13 +22,11 @@ #include #include #include -#include #include #include "nm-setting-vpn.h" #include "nm-utils.h" #include "nm-utils-private.h" -#include "nm-dbus-glib-types.h" #include "nm-setting-private.h" /** @@ -448,20 +446,20 @@ update_secret_string (NMSetting *setting, } static NMSettingUpdateSecretResult -update_secret_hash (NMSetting *setting, - GHashTable *secrets, +update_secret_dict (NMSetting *setting, + GVariant *secrets, GError **error) { NMSettingVpnPrivate *priv = NM_SETTING_VPN_GET_PRIVATE (setting); - GHashTableIter iter; + GVariantIter iter; const char *name, *value; NMSettingUpdateSecretResult result = NM_SETTING_UPDATE_SECRET_SUCCESS_UNCHANGED; g_return_val_if_fail (secrets != NULL, NM_SETTING_UPDATE_SECRET_ERROR); /* Make sure the items are valid */ - g_hash_table_iter_init (&iter, secrets); - while (g_hash_table_iter_next (&iter, (gpointer *) &name, (gpointer *) &value)) { + g_variant_iter_init (&iter, secrets); + while (g_variant_iter_next (&iter, "{&s&s}", &name, &value)) { if (!name || !strlen (name)) { g_set_error_literal (error, NM_SETTING_ERROR, NM_SETTING_ERROR_PROPERTY_TYPE_MISMATCH, @@ -478,8 +476,8 @@ update_secret_hash (NMSetting *setting, } /* Now add the items to the settings' secrets list */ - g_hash_table_iter_init (&iter, secrets); - while (g_hash_table_iter_next (&iter, (gpointer *) &name, (gpointer *) &value)) { + g_variant_iter_init (&iter, secrets); + while (g_variant_iter_next (&iter, "{&s&s}", &name, &value)) { if (value == NULL) { g_warn_if_fail (value != NULL); continue; @@ -500,26 +498,26 @@ update_secret_hash (NMSetting *setting, } static int -update_one_secret (NMSetting *setting, const char *key, GValue *value, GError **error) +update_one_secret (NMSetting *setting, const char *key, GVariant *value, GError **error) { NMSettingUpdateSecretResult success = NM_SETTING_UPDATE_SECRET_ERROR; g_return_val_if_fail (key != NULL, NM_SETTING_UPDATE_SECRET_ERROR); g_return_val_if_fail (value != NULL, NM_SETTING_UPDATE_SECRET_ERROR); - if (G_VALUE_HOLDS_STRING (value)) { + if (g_variant_is_of_type (value, G_VARIANT_TYPE_STRING)) { /* Passing the string properties individually isn't correct, and won't * produce the correct result, but for some reason that's how it used * to be done. So even though it's not correct, keep the code around * for compatibility's sake. */ - success = update_secret_string (setting, key, g_value_get_string (value), error); - } else if (G_VALUE_HOLDS (value, DBUS_TYPE_G_MAP_OF_STRING)) { + success = update_secret_string (setting, key, g_variant_get_string (value, NULL), error); + } else if (g_variant_is_of_type (value, G_VARIANT_TYPE ("a{ss}"))) { if (strcmp (key, NM_SETTING_VPN_SECRETS) != 0) { g_set_error (error, NM_SETTING_ERROR, NM_SETTING_ERROR_PROPERTY_NOT_SECRET, "Property %s not a secret property", key); } else - success = update_secret_hash (setting, g_value_get_boxed (value), error); + success = update_secret_dict (setting, value, error); } else g_set_error_literal (error, NM_SETTING_ERROR, NM_SETTING_ERROR_PROPERTY_TYPE_MISMATCH, key); @@ -837,7 +835,7 @@ nm_setting_vpn_class_init (NMSettingVpnClass *setting_class) G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); _nm_setting_class_transform_property (parent_class, NM_SETTING_VPN_DATA, - DBUS_TYPE_G_MAP_OF_STRING, + G_VARIANT_TYPE ("a{ss}"), _nm_utils_strdict_to_dbus, _nm_utils_strdict_from_dbus); @@ -857,7 +855,7 @@ nm_setting_vpn_class_init (NMSettingVpnClass *setting_class) NM_SETTING_PARAM_SECRET | G_PARAM_STATIC_STRINGS)); _nm_setting_class_transform_property (parent_class, NM_SETTING_VPN_SECRETS, - DBUS_TYPE_G_MAP_OF_STRING, + G_VARIANT_TYPE ("a{ss}"), _nm_utils_strdict_to_dbus, _nm_utils_strdict_from_dbus); } diff --git a/libnm-core/nm-setting-wimax.c b/libnm-core/nm-setting-wimax.c index 467e1f617c..bcb2458d4d 100644 --- a/libnm-core/nm-setting-wimax.c +++ b/libnm-core/nm-setting-wimax.c @@ -22,7 +22,6 @@ #include #include -#include #include #include "nm-setting-wimax.h" @@ -255,7 +254,7 @@ nm_setting_wimax_class_init (NMSettingWimaxClass *setting_class) G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); _nm_setting_class_transform_property (parent_class, NM_SETTING_WIMAX_MAC_ADDRESS, - DBUS_TYPE_G_UCHAR_ARRAY, + G_VARIANT_TYPE_BYTESTRING, _nm_utils_hwaddr_to_dbus, _nm_utils_hwaddr_from_dbus); } diff --git a/libnm-core/nm-setting-wired.c b/libnm-core/nm-setting-wired.c index f641e8a813..4338ab047e 100644 --- a/libnm-core/nm-setting-wired.c +++ b/libnm-core/nm-setting-wired.c @@ -22,13 +22,11 @@ #include #include -#include #include #include "nm-setting-wired.h" #include "nm-utils.h" #include "nm-utils-private.h" -#include "nm-dbus-glib-types.h" #include "nm-setting-private.h" /** @@ -895,7 +893,7 @@ nm_setting_wired_class_init (NMSettingWiredClass *setting_class) NM_SETTING_PARAM_INFERRABLE | G_PARAM_STATIC_STRINGS)); _nm_setting_class_transform_property (parent_class, NM_SETTING_WIRED_MAC_ADDRESS, - DBUS_TYPE_G_UCHAR_ARRAY, + G_VARIANT_TYPE_BYTESTRING, _nm_utils_hwaddr_to_dbus, _nm_utils_hwaddr_from_dbus); @@ -913,7 +911,7 @@ nm_setting_wired_class_init (NMSettingWiredClass *setting_class) NM_SETTING_PARAM_INFERRABLE | G_PARAM_STATIC_STRINGS)); _nm_setting_class_transform_property (parent_class, NM_SETTING_WIRED_CLONED_MAC_ADDRESS, - DBUS_TYPE_G_UCHAR_ARRAY, + G_VARIANT_TYPE_BYTESTRING, _nm_utils_hwaddr_to_dbus, _nm_utils_hwaddr_from_dbus); @@ -999,7 +997,7 @@ nm_setting_wired_class_init (NMSettingWiredClass *setting_class) NM_SETTING_PARAM_INFERRABLE | G_PARAM_STATIC_STRINGS)); _nm_setting_class_transform_property (parent_class, NM_SETTING_WIRED_S390_OPTIONS, - DBUS_TYPE_G_MAP_OF_STRING, + G_VARIANT_TYPE ("a{ss}"), _nm_utils_strdict_to_dbus, _nm_utils_strdict_from_dbus); } diff --git a/libnm-core/nm-setting-wireless.c b/libnm-core/nm-setting-wireless.c index 600e54c0eb..17e7c3f3b5 100644 --- a/libnm-core/nm-setting-wireless.c +++ b/libnm-core/nm-setting-wireless.c @@ -22,13 +22,11 @@ #include #include -#include #include #include "nm-setting-wireless.h" #include "nm-dbus-interface.h" #include "nm-utils.h" -#include "nm-dbus-glib-types.h" #include "nm-utils-private.h" #include "nm-setting-private.h" @@ -820,17 +818,15 @@ verify (NMSetting *setting, GSList *all_settings, GError **error) return TRUE; } -static gboolean +static GVariant * nm_setting_wireless_get_security (NMSetting *setting, NMConnection *connection, - const char *property_name, - GValue *value) + const char *property_name) { - if (nm_connection_get_setting_wireless_security (connection)) { - g_value_set_string (value, NM_SETTING_WIRELESS_SECURITY_SETTING_NAME); - return TRUE; - } else - return FALSE; + if (nm_connection_get_setting_wireless_security (connection)) + return g_variant_new_string (NM_SETTING_WIRELESS_SECURITY_SETTING_NAME); + else + return NULL; } static void @@ -998,7 +994,7 @@ nm_setting_wireless_class_init (NMSettingWirelessClass *setting_class) G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); _nm_setting_class_transform_property (parent_class, NM_SETTING_WIRELESS_SSID, - DBUS_TYPE_G_UCHAR_ARRAY, + G_VARIANT_TYPE_BYTESTRING, _nm_utils_bytes_to_dbus, _nm_utils_bytes_from_dbus); @@ -1063,7 +1059,7 @@ nm_setting_wireless_class_init (NMSettingWirelessClass *setting_class) G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); _nm_setting_class_transform_property (parent_class, NM_SETTING_WIRELESS_BSSID, - DBUS_TYPE_G_UCHAR_ARRAY, + G_VARIANT_TYPE_BYTESTRING, _nm_utils_hwaddr_to_dbus, _nm_utils_hwaddr_from_dbus); @@ -1114,7 +1110,7 @@ nm_setting_wireless_class_init (NMSettingWirelessClass *setting_class) G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); _nm_setting_class_transform_property (parent_class, NM_SETTING_WIRELESS_MAC_ADDRESS, - DBUS_TYPE_G_UCHAR_ARRAY, + G_VARIANT_TYPE_BYTESTRING, _nm_utils_hwaddr_to_dbus, _nm_utils_hwaddr_from_dbus); @@ -1131,7 +1127,7 @@ nm_setting_wireless_class_init (NMSettingWirelessClass *setting_class) G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); _nm_setting_class_transform_property (parent_class, NM_SETTING_WIRELESS_CLONED_MAC_ADDRESS, - DBUS_TYPE_G_UCHAR_ARRAY, + G_VARIANT_TYPE_BYTESTRING, _nm_utils_hwaddr_to_dbus, _nm_utils_hwaddr_from_dbus); @@ -1200,6 +1196,7 @@ nm_setting_wireless_class_init (NMSettingWirelessClass *setting_class) G_PARAM_STATIC_STRINGS)); /* Compatibility for deprecated property */ - _nm_setting_class_add_dbus_only_property (parent_class, "security", G_TYPE_STRING, + _nm_setting_class_add_dbus_only_property (parent_class, "security", + G_VARIANT_TYPE_STRING, nm_setting_wireless_get_security, NULL); } diff --git a/libnm-core/nm-setting.c b/libnm-core/nm-setting.c index 04eee75117..197b80c14f 100644 --- a/libnm-core/nm-setting.c +++ b/libnm-core/nm-setting.c @@ -22,6 +22,7 @@ #include #include +#include #include "nm-setting.h" #include "nm-setting-private.h" @@ -104,7 +105,6 @@ _ensure_registered (void) #if !GLIB_CHECK_VERSION (2, 35, 0) g_type_init (); #endif - _nm_value_transforms_register (); registered_settings = g_hash_table_new (g_str_hash, g_str_equal); registered_settings_by_type = g_hash_table_new (_nm_gtype_hash, _nm_gtype_equal); } @@ -376,14 +376,14 @@ _nm_setting_slave_type_detect_from_settings (GSList *all_settings, NMSetting **o typedef struct { const char *name; GParamSpec *param_spec; - GType dbus_type; + const GVariantType *dbus_type; NMSettingPropertyGetFunc get_func; NMSettingPropertySetFunc set_func; NMSettingPropertyNotSetFunc not_set_func; - NMSettingPropertyTransformFunc to_dbus; - NMSettingPropertyTransformFunc from_dbus; + NMSettingPropertyTransformToFunc to_dbus; + NMSettingPropertyTransformFromFunc from_dbus; } NMSettingProperty; static GQuark setting_property_overrides_quark; @@ -411,12 +411,12 @@ static void add_property_override (NMSettingClass *setting_class, const char *property_name, GParamSpec *param_spec, - GType dbus_type, + const GVariantType *dbus_type, NMSettingPropertyGetFunc get_func, NMSettingPropertySetFunc set_func, NMSettingPropertyNotSetFunc not_set_func, - NMSettingPropertyTransformFunc to_dbus, - NMSettingPropertyTransformFunc from_dbus) + NMSettingPropertyTransformToFunc to_dbus, + NMSettingPropertyTransformFromFunc from_dbus) { GType setting_type = G_TYPE_FROM_CLASS (setting_class); GArray *overrides; @@ -448,7 +448,7 @@ add_property_override (NMSettingClass *setting_class, * _nm_setting_class_add_dbus_only_property: * @setting_class: the setting class * @property_name: the name of the property to override - * @dbus_type: the type of the property + * @dbus_type: the type of the property (in its D-Bus representation) * @get_func: (allow-none): function to call to get the value of the property * @set_func: (allow-none): function to call to set the value of the property * @@ -457,9 +457,9 @@ add_property_override (NMSettingClass *setting_class, * a #GObject property. * * When serializing a setting to D-Bus, @get_func will be called to get the - * property's value. If it returns %TRUE, the value will be added to the hash, - * and if %FALSE, it will not. (If @get_func is %NULL, the property will always - * be omitted in the serialization.) + * property's value. (If it returns %NULL, no value will be added to the + * serialization. If @get_func is %NULL, the property will always be omitted in + * the serialization.) * * When deserializing a D-Bus representation into a setting, if @property_name * is present, then @set_func will be called to set (and/or verify) it. If it @@ -471,7 +471,7 @@ add_property_override (NMSettingClass *setting_class, void _nm_setting_class_add_dbus_only_property (NMSettingClass *setting_class, const char *property_name, - GType dbus_type, + const GVariantType *dbus_type, NMSettingPropertyGetFunc get_func, NMSettingPropertySetFunc set_func) { @@ -520,7 +520,7 @@ _nm_setting_class_add_dbus_only_property (NMSettingClass *setting_class, void _nm_setting_class_override_property (NMSettingClass *setting_class, const char *property_name, - GType dbus_type, + const GVariantType *dbus_type, NMSettingPropertyGetFunc get_func, NMSettingPropertySetFunc set_func, NMSettingPropertyNotSetFunc not_set_func) @@ -555,9 +555,9 @@ _nm_setting_class_override_property (NMSettingClass *setting_class, void _nm_setting_class_transform_property (NMSettingClass *setting_class, const char *property, - GType dbus_type, - NMSettingPropertyTransformFunc to_dbus, - NMSettingPropertyTransformFunc from_dbus) + const GVariantType *dbus_type, + NMSettingPropertyTransformToFunc to_dbus, + NMSettingPropertyTransformFromFunc from_dbus) { GParamSpec *param_spec; @@ -643,33 +643,90 @@ nm_setting_class_find_property (NMSettingClass *setting_class, const char *prope /*************************************************************/ -static void -destroy_gvalue (gpointer data) +static const GVariantType * +variant_type_for_gtype (GType type) { - GValue *value = (GValue *) data; - - if (G_IS_VALUE (value)) - g_value_unset (value); - g_slice_free (GValue, value); + if (type == G_TYPE_BOOLEAN) + return G_VARIANT_TYPE_BOOLEAN; + else if (type == G_TYPE_UCHAR) + return G_VARIANT_TYPE_BYTE; + else if (type == G_TYPE_INT) + return G_VARIANT_TYPE_INT32; + else if (type == G_TYPE_UINT) + return G_VARIANT_TYPE_UINT32; + else if (type == G_TYPE_INT64) + return G_VARIANT_TYPE_INT64; + else if (type == G_TYPE_UINT64) + return G_VARIANT_TYPE_UINT64; + else if (type == G_TYPE_STRING) + return G_VARIANT_TYPE_STRING; + else if (type == G_TYPE_DOUBLE) + return G_VARIANT_TYPE_DOUBLE; + else if (type == G_TYPE_STRV) + return G_VARIANT_TYPE_STRING_ARRAY; + else + g_assert_not_reached (); } +static GVariant * +get_property_for_dbus (NMSetting *setting, + const NMSettingProperty *property, + gboolean ignore_default) +{ + GValue prop_value = { 0, }; + GVariant *dbus_value; + + g_return_val_if_fail (property->param_spec != NULL, NULL); + + g_value_init (&prop_value, property->param_spec->value_type); + g_object_get_property (G_OBJECT (setting), property->param_spec->name, &prop_value); + + if (ignore_default && g_param_value_defaults (property->param_spec, &prop_value)) { + g_value_unset (&prop_value); + return NULL; + } + + if (property->to_dbus) + dbus_value = property->to_dbus (&prop_value); + else if (property->dbus_type) + dbus_value = g_dbus_gvalue_to_gvariant (&prop_value, property->dbus_type); + else + dbus_value = g_dbus_gvalue_to_gvariant (&prop_value, variant_type_for_gtype (prop_value.g_type)); + g_value_unset (&prop_value); + + return dbus_value; +} + +static void +set_property_from_dbus (const NMSettingProperty *property, GVariant *src_value, GValue *dst_value) +{ + g_return_val_if_fail (property->param_spec != NULL, NULL); + + if (property->from_dbus) + property->from_dbus (src_value, dst_value); + else + g_dbus_gvariant_to_gvalue (src_value, dst_value); +} + + /** * _nm_setting_to_dbus: * @setting: the #NMSetting * @connection: the #NMConnection containing @setting * @flags: hash flags, e.g. %NM_CONNECTION_SERIALIZE_ALL * - * Converts the #NMSetting into a #GHashTable mapping each setting property - * name to a GValue describing that property, suitable for marshalling over - * D-Bus or serializing. The mapping is string to GValue. + * Converts the #NMSetting into a #GVariant of type #NM_VARIANT_TYPE_SETTING + * mapping each setting property name to a value describing that property, + * suitable for marshalling over D-Bus or serializing. * - * Returns: (transfer full) (element-type utf8 GObject.Value): a new #GHashTable - * describing the setting's properties + * Returns: (transfer none): a new floating #GVariant describing the setting's + * properties **/ -GHashTable * +GVariant * _nm_setting_to_dbus (NMSetting *setting, NMConnection *connection, NMConnectionSerializationFlags flags) { - GHashTable *hash; + GVariantBuilder builder; + GVariant *dbus_value; const NMSettingProperty *properties; guint n_properties, i; @@ -677,14 +734,11 @@ _nm_setting_to_dbus (NMSetting *setting, NMConnection *connection, NMConnectionS properties = nm_setting_class_get_properties (NM_SETTING_GET_CLASS (setting), &n_properties); - hash = g_hash_table_new_full (g_str_hash, g_str_equal, - (GDestroyNotify) g_free, destroy_gvalue); + g_variant_builder_init (&builder, NM_VARIANT_TYPE_SETTING); for (i = 0; i < n_properties; i++) { const NMSettingProperty *property = &properties[i]; GParamSpec *prop_spec = property->param_spec; - GValue *value; - gboolean set; if (!prop_spec && !property->get_func) { /* Override property with no get_func, so we skip it. */ @@ -702,73 +756,65 @@ _nm_setting_to_dbus (NMSetting *setting, NMConnection *connection, NMConnectionS && !(prop_spec && (prop_spec->flags & NM_SETTING_PARAM_SECRET))) continue; - value = g_slice_new0 (GValue); - if (property->get_func) { - g_value_init (value, property->dbus_type); - set = property->get_func (setting, connection, property->name, value); - } else if (prop_spec) { - g_value_init (value, prop_spec->value_type); - g_object_get_property (G_OBJECT (setting), prop_spec->name, value); - - /* Don't serialize values with default values */ - set = !g_param_value_defaults (prop_spec, value); - - /* Convert the property value if necessary */ - if (set && property->to_dbus) { - GValue *dbus_value = g_slice_new0 (GValue); - - g_value_init (dbus_value, property->dbus_type); - property->to_dbus (value, dbus_value); - destroy_gvalue (value); - value = dbus_value; - } - } else - g_assert_not_reached (); - - if (set) - g_hash_table_insert (hash, g_strdup (property->name), value); + if (property->get_func) + dbus_value = property->get_func (setting, connection, property->name); + else if (prop_spec) + dbus_value = get_property_for_dbus (setting, property, TRUE); else - destroy_gvalue (value); + g_assert_not_reached (); + if (dbus_value) { + /* Allow dbus_value to be either floating or not. */ + g_variant_take_ref (dbus_value); + + g_variant_builder_add (&builder, "{sv}", property->name, dbus_value); + g_variant_unref (dbus_value); + } } - return hash; + return g_variant_builder_end (&builder); } /** * _nm_setting_new_from_dbus: * @setting_type: the #NMSetting type which the hash contains properties for - * @setting_hash: (element-type utf8 GObject.Value): the #GHashTable containing a - * string to #GValue mapping of properties that apply to the setting - * @connection_hash: (element-type utf8 GObject.Value): the #GHashTable containing a - * string to #GHashTable mapping of properties for the whole connection + * @setting_dict: the #GVariant containing an %NM_VARIANT_TYPE_SETTING dictionary + * mapping property names to values + * @connection_dict: the #GVariant containing an %NM_VARIANT_TYPE_CONNECTION + * dictionary mapping setting names to dictionaries. * @error: location to store error, or %NULL * * Creates a new #NMSetting object and populates that object with the properties - * contained in the hash table, using each hash key as the property to set, - * and each hash value as the value to set that property to. Setting properties - * are strongly typed, thus the GValue type of the hash value must be correct. - * See the documentation on each #NMSetting object subclass for the correct - * property names and value types. + * contained in @setting_dict, using each key as the property to set, and each + * value as the value to set that property to. Setting properties are strongly + * typed, thus the #GVariantType of the dict value must be correct. See the + * documentation on each #NMSetting object subclass for the correct property + * names and value types. * * Returns: a new #NMSetting object populated with the properties from the * hash table, or %NULL if @setting_hash could not be deserialized. **/ NMSetting * _nm_setting_new_from_dbus (GType setting_type, - GHashTable *setting_hash, - GHashTable *connection_hash, + GVariant *setting_dict, + GVariant *connection_dict, GError **error) { - NMSetting *setting; NMSettingClass *class; - GHashTableIter iter; + NMSetting *setting; + GVariantIter iter; const char *prop_name; const NMSettingProperty *properties; guint n_properties; guint i; g_return_val_if_fail (G_TYPE_IS_INSTANTIATABLE (setting_type), NULL); - g_return_val_if_fail (setting_hash != NULL, NULL); + g_return_val_if_fail (g_variant_is_of_type (setting_dict, NM_VARIANT_TYPE_SETTING), NULL); + + /* connection_dict is not technically optional, but some tests in test-general + * don't bother with it in cases where they know it's not needed. + */ + if (connection_dict) + g_return_val_if_fail (g_variant_is_of_type (connection_dict, NM_VARIANT_TYPE_CONNECTION), NULL); /* g_type_class_ref() ensures the setting class is created if it hasn't * already been used. @@ -776,8 +822,8 @@ _nm_setting_new_from_dbus (GType setting_type, class = g_type_class_ref (setting_type); /* Check for invalid properties first. */ - g_hash_table_iter_init (&iter, setting_hash); - while (g_hash_table_iter_next (&iter, (gpointer) &prop_name, NULL)) { + g_variant_iter_init (&iter, setting_dict); + while (g_variant_iter_next (&iter, "{&sv}", &prop_name, NULL)) { if (!nm_setting_class_find_property (class, prop_name)) { /* Oh, we're so nice and only warn, maybe it should be a fatal error? */ g_warning ("Ignoring invalid property '%s'", prop_name); @@ -791,31 +837,30 @@ _nm_setting_new_from_dbus (GType setting_type, properties = nm_setting_class_get_properties (class, &n_properties); for (i = 0; i < n_properties; i++) { const NMSettingProperty *property = &properties[i]; - GValue *value = g_hash_table_lookup (setting_hash, property->name); + GVariant *value = g_variant_lookup_value (setting_dict, property->name, NULL); if (value && property->set_func) { property->set_func (setting, - connection_hash, + connection_dict, property->name, value); } else if (!value && property->not_set_func) { property->not_set_func (setting, - connection_hash, + connection_dict, property->name); } else if (value && property->param_spec) { + GValue object_value = { 0, }; + if (!(property->param_spec->flags & G_PARAM_WRITABLE)) continue; - if (property->from_dbus) { - GValue object_value = G_VALUE_INIT; - - g_value_init (&object_value, property->param_spec->value_type); - property->from_dbus (value, &object_value); - g_object_set_property (G_OBJECT (setting), property->param_spec->name, &object_value); - g_value_unset (&object_value); - } else - g_object_set_property (G_OBJECT (setting), property->param_spec->name, value); + g_value_init (&object_value, property->param_spec->value_type); + set_property_from_dbus (property, value, &object_value); + g_object_set_property (G_OBJECT (setting), property->param_spec->name, &object_value); } + + if (value) + g_variant_unref (value); } g_type_class_unref (class); @@ -945,8 +990,7 @@ compare_property (NMSetting *setting, NMSettingCompareFlags flags) { const NMSettingProperty *property; - GValue value1 = G_VALUE_INIT; - GValue value2 = G_VALUE_INIT; + GVariant *value1, *value2; int cmp; /* Handle compare flags */ @@ -976,29 +1020,13 @@ compare_property (NMSetting *setting, property = nm_setting_class_find_property (NM_SETTING_GET_CLASS (setting), prop_spec->name); g_return_val_if_fail (property != NULL, FALSE); - g_value_init (&value1, prop_spec->value_type); - g_object_get_property (G_OBJECT (setting), prop_spec->name, &value1); + value1 = get_property_for_dbus (setting, property, FALSE); + value2 = get_property_for_dbus (other, property, FALSE); - g_value_init (&value2, prop_spec->value_type); - g_object_get_property (G_OBJECT (other), prop_spec->name, &value2); + cmp = nm_property_compare (value1, value2); - if (property->to_dbus) { - GValue dbus_value1 = G_VALUE_INIT, dbus_value2 = G_VALUE_INIT; - - g_value_init (&dbus_value1, property->dbus_type); - property->to_dbus (&value1, &dbus_value1); - g_value_init (&dbus_value2, property->dbus_type); - property->to_dbus (&value2, &dbus_value2); - - cmp = nm_property_compare (&dbus_value1, &dbus_value2); - - g_value_unset (&dbus_value1); - g_value_unset (&dbus_value2); - } else - cmp = nm_property_compare (&value1, &value2); - - g_value_unset (&value1); - g_value_unset (&value2); + g_variant_unref (value1); + g_variant_unref (value2); return cmp == 0; } @@ -1389,10 +1417,11 @@ nm_setting_need_secrets (NMSetting *setting) } static int -update_one_secret (NMSetting *setting, const char *key, GValue *value, GError **error) +update_one_secret (NMSetting *setting, const char *key, GVariant *value, GError **error) { const NMSettingProperty *property; GParamSpec *prop_spec; + GValue prop_value = { 0, }; property = nm_setting_class_find_property (NM_SETTING_GET_CLASS (setting), key); if (!property) { @@ -1408,65 +1437,65 @@ update_one_secret (NMSetting *setting, const char *key, GValue *value, GError ** if (!prop_spec || !(prop_spec->flags & NM_SETTING_PARAM_SECRET)) return NM_SETTING_UPDATE_SECRET_SUCCESS_UNCHANGED; - if (g_value_type_compatible (G_VALUE_TYPE (value), G_PARAM_SPEC_VALUE_TYPE (prop_spec))) { - if (G_VALUE_HOLDS_STRING (value) && G_IS_PARAM_SPEC_STRING (prop_spec)) { - /* String is expected to be a common case. Handle it specially and check whether - * the value is already set. Otherwise, we just reset the property and - * assume the value got modified. */ - char *v; + if ( g_variant_is_of_type (value, G_VARIANT_TYPE_STRING) + && G_IS_PARAM_SPEC_STRING (prop_spec)) { + /* String is expected to be a common case. Handle it specially and check + * whether the value is already set. Otherwise, we just reset the + * property and assume the value got modified. + */ + char *v; - g_object_get (G_OBJECT (setting), prop_spec->name, &v, NULL); - if (g_strcmp0 (v, g_value_get_string (value)) == 0) { - g_free (v); - return NM_SETTING_UPDATE_SECRET_SUCCESS_UNCHANGED; - } + g_object_get (G_OBJECT (setting), prop_spec->name, &v, NULL); + if (g_strcmp0 (v, g_variant_get_string (value, NULL)) == 0) { g_free (v); + return NM_SETTING_UPDATE_SECRET_SUCCESS_UNCHANGED; } - g_object_set_property (G_OBJECT (setting), prop_spec->name, value); - return NM_SETTING_UPDATE_SECRET_SUCCESS_MODIFIED; + g_free (v); } - g_set_error (error, - NM_SETTING_ERROR, - NM_SETTING_ERROR_PROPERTY_TYPE_MISMATCH, - "%s", key); - return NM_SETTING_UPDATE_SECRET_ERROR; + + g_value_init (&prop_value, prop_spec->value_type); + set_property_from_dbus (property, value, &prop_value); + g_object_set_property (G_OBJECT (setting), prop_spec->name, &prop_value); + g_value_unset (&prop_value); + + return NM_SETTING_UPDATE_SECRET_SUCCESS_MODIFIED; } /** * _nm_setting_update_secrets: * @setting: the #NMSetting - * @secrets: (element-type utf8 GObject.Value): a #GHashTable mapping - * string to #GValue of setting property names and secrets + * @secrets: a #GVariant of type #NM_VARIANT_TYPE_SETTING, mapping property + * names to secrets. * @error: location to store error, or %NULL * - * Update the setting's secrets, given a hash table of secrets intended for that + * Update the setting's secrets, given a dictionary of secrets intended for that * setting (deserialized from D-Bus for example). * * Returns: an #NMSettingUpdateSecretResult - * update one or more of the secrets. **/ NMSettingUpdateSecretResult -_nm_setting_update_secrets (NMSetting *setting, GHashTable *secrets, GError **error) +_nm_setting_update_secrets (NMSetting *setting, GVariant *secrets, GError **error) { - GHashTableIter iter; - gpointer key, data; + GVariantIter iter; + const char *secret_key; + GVariant *secret_value; GError *tmp_error = NULL; NMSettingUpdateSecretResult result = NM_SETTING_UPDATE_SECRET_SUCCESS_UNCHANGED; g_return_val_if_fail (NM_IS_SETTING (setting), NM_SETTING_UPDATE_SECRET_ERROR); - g_return_val_if_fail (secrets != NULL, NM_SETTING_UPDATE_SECRET_ERROR); + g_return_val_if_fail (g_variant_is_of_type (secrets, NM_VARIANT_TYPE_SETTING), NM_SETTING_UPDATE_SECRET_ERROR); if (error) g_return_val_if_fail (*error == NULL, NM_SETTING_UPDATE_SECRET_ERROR); - g_hash_table_iter_init (&iter, secrets); - while (g_hash_table_iter_next (&iter, &key, &data)) { + g_variant_iter_init (&iter, secrets); + while (g_variant_iter_next (&iter, "{&sv}", &secret_key, &secret_value)) { int success; - const char *secret_key = (const char *) key; - GValue *secret_value = (GValue *) data; success = NM_SETTING_GET_CLASS (setting)->update_one_secret (setting, secret_key, secret_value, &tmp_error); g_assert (!((success == NM_SETTING_UPDATE_SECRET_ERROR) ^ (!!tmp_error))); + g_variant_unref (secret_value); + if (success == NM_SETTING_UPDATE_SECRET_ERROR) { g_propagate_error (error, tmp_error); return NM_SETTING_UPDATE_SECRET_ERROR; @@ -1707,22 +1736,20 @@ _nm_setting_verify_required_virtual_interface_name (GSList *all_settings, return NM_SETTING_VERIFY_SUCCESS; } -gboolean +GVariant * _nm_setting_get_deprecated_virtual_interface_name (NMSetting *setting, NMConnection *connection, - const char *property, - GValue *value) + const char *property) { NMSettingConnection *s_con; s_con = nm_connection_get_setting_connection (connection); - g_return_val_if_fail (s_con != NULL, FALSE); + g_return_val_if_fail (s_con != NULL, NULL); - if (nm_setting_connection_get_interface_name (s_con)) { - g_value_set_string (value, nm_setting_connection_get_interface_name (s_con)); - return TRUE; - } else - return FALSE; + if (nm_setting_connection_get_interface_name (s_con)) + return g_variant_new_string (nm_setting_connection_get_interface_name (s_con)); + else + return NULL; } /*****************************************************************************/ diff --git a/libnm-core/nm-setting.h b/libnm-core/nm-setting.h index c2fef09f1b..80fc7bb6a6 100644 --- a/libnm-core/nm-setting.h +++ b/libnm-core/nm-setting.h @@ -179,7 +179,7 @@ typedef struct { int (*update_one_secret) (NMSetting *setting, const char *key, - GValue *value, + GVariant *value, GError **error); gboolean (*get_secret_flags) (NMSetting *setting, diff --git a/libnm-core/nm-simple-connection.c b/libnm-core/nm-simple-connection.c index 3c05cccf46..03e5a92d81 100644 --- a/libnm-core/nm-simple-connection.c +++ b/libnm-core/nm-simple-connection.c @@ -50,8 +50,7 @@ nm_simple_connection_new (void) /** * nm_simple_connection_new_from_dbus: - * @hash: (element-type utf8 GLib.HashTable): the #GHashTable describing - * the connection + * @dict: a #GVariant of type %NM_VARIANT_TYPE_CONNECTION describing the connection * @error: on unsuccessful return, an error * * Creates a new #NMSimpleConnection from a hash table describing the @@ -63,14 +62,15 @@ nm_simple_connection_new (void) * connection failed to validate **/ NMConnection * -nm_simple_connection_new_from_dbus (GHashTable *hash, GError **error) +nm_simple_connection_new_from_dbus (GVariant *dict, GError **error) { NMConnection *connection; - g_return_val_if_fail (hash != NULL, NULL); + g_return_val_if_fail (dict != NULL, NULL); + g_return_val_if_fail (g_variant_is_of_type (dict, NM_VARIANT_TYPE_CONNECTION), NULL); connection = nm_simple_connection_new (); - if ( !nm_connection_replace_settings (connection, hash, error) + if ( !nm_connection_replace_settings (connection, dict, error) || !nm_connection_verify (connection, error)) g_clear_object (&connection); return connection; diff --git a/libnm-core/nm-simple-connection.h b/libnm-core/nm-simple-connection.h index b535ed9db9..aea04e3a67 100644 --- a/libnm-core/nm-simple-connection.h +++ b/libnm-core/nm-simple-connection.h @@ -51,7 +51,7 @@ GType nm_simple_connection_get_type (void); NMConnection *nm_simple_connection_new (void); -NMConnection *nm_simple_connection_new_from_dbus (GHashTable *hash, +NMConnection *nm_simple_connection_new_from_dbus (GVariant *dict, GError **error); NMConnection *nm_simple_connection_new_clone (NMConnection *connection); diff --git a/libnm-core/nm-utils-private.h b/libnm-core/nm-utils-private.h index be9619dbf6..bf8687d373 100644 --- a/libnm-core/nm-utils-private.h +++ b/libnm-core/nm-utils-private.h @@ -29,50 +29,38 @@ gboolean _nm_utils_string_in_list (const char *str, gboolean _nm_utils_string_slist_validate (GSList *list, const char **valid_values); -gboolean _nm_utils_gvalue_array_validate (GValueArray *elements, - guint n_expected, ...); +/* D-Bus transform funcs */ -void _nm_value_transforms_register (void); - -void _nm_utils_hwaddr_to_dbus (const GValue *prop_value, - GValue *dbus_value); -void _nm_utils_hwaddr_from_dbus (const GValue *dbus_value, +GVariant * _nm_utils_hwaddr_to_dbus (const GValue *prop_value); +void _nm_utils_hwaddr_from_dbus (GVariant *dbus_value, GValue *prop_value); -void _nm_utils_strdict_to_dbus (const GValue *prop_value, - GValue *dbus_value); -void _nm_utils_strdict_from_dbus (const GValue *dbus_value, +GVariant * _nm_utils_strdict_to_dbus (const GValue *prop_value); +void _nm_utils_strdict_from_dbus (GVariant *dbus_value, GValue *prop_value); -void _nm_utils_bytes_to_dbus (const GValue *prop_value, - GValue *dbus_value); -void _nm_utils_bytes_from_dbus (const GValue *dbus_value, +GVariant * _nm_utils_bytes_to_dbus (const GValue *prop_value); +void _nm_utils_bytes_from_dbus (GVariant *dbus_value, GValue *prop_value); -void _nm_utils_ip4_dns_to_dbus (const GValue *prop_value, - GValue *dbus_value); -void _nm_utils_ip4_dns_from_dbus (const GValue *dbus_value, +GVariant * _nm_utils_ip4_dns_to_dbus (const GValue *prop_value); +void _nm_utils_ip4_dns_from_dbus (GVariant *dbus_value, GValue *prop_value); -void _nm_utils_ip4_addresses_to_dbus (const GValue *prop_value, - GValue *dbus_value); -void _nm_utils_ip4_addresses_from_dbus (const GValue *dbus_value, +GVariant * _nm_utils_ip4_addresses_to_dbus (const GValue *prop_value); +void _nm_utils_ip4_addresses_from_dbus (GVariant *dbus_value, GValue *prop_value); -void _nm_utils_ip4_routes_to_dbus (const GValue *prop_value, - GValue *dbus_value); -void _nm_utils_ip4_routes_from_dbus (const GValue *dbus_value, +GVariant * _nm_utils_ip4_routes_to_dbus (const GValue *prop_value); +void _nm_utils_ip4_routes_from_dbus (GVariant *dbus_value, GValue *prop_value); -void _nm_utils_ip6_dns_to_dbus (const GValue *prop_value, - GValue *dbus_value); -void _nm_utils_ip6_dns_from_dbus (const GValue *dbus_value, +GVariant * _nm_utils_ip6_dns_to_dbus (const GValue *prop_value); +void _nm_utils_ip6_dns_from_dbus (GVariant *dbus_value, GValue *prop_value); -void _nm_utils_ip6_addresses_to_dbus (const GValue *prop_value, - GValue *dbus_value); -void _nm_utils_ip6_addresses_from_dbus (const GValue *dbus_value, +GVariant * _nm_utils_ip6_addresses_to_dbus (const GValue *prop_value); +void _nm_utils_ip6_addresses_from_dbus (GVariant *dbus_value, GValue *prop_value); -void _nm_utils_ip6_routes_to_dbus (const GValue *prop_value, - GValue *dbus_value); -void _nm_utils_ip6_routes_from_dbus (const GValue *dbus_value, +GVariant * _nm_utils_ip6_routes_to_dbus (const GValue *prop_value); +void _nm_utils_ip6_routes_from_dbus (GVariant *dbus_value, GValue *prop_value); GSList * _nm_utils_strv_to_slist (char **strv); diff --git a/libnm-core/nm-utils.c b/libnm-core/nm-utils.c index 2a0497c342..617b0b4df8 100644 --- a/libnm-core/nm-utils.c +++ b/libnm-core/nm-utils.c @@ -30,7 +30,6 @@ #include "nm-utils.h" #include "nm-utils-private.h" #include "nm-glib-compat.h" -#include "nm-dbus-glib-types.h" #include "nm-setting-private.h" #include "crypto.h" @@ -234,8 +233,6 @@ nm_utils_init (GError **error) if (!crypto_init (error)) return FALSE; - - _nm_value_transforms_register (); } return TRUE; } @@ -441,54 +438,6 @@ nm_utils_same_ssid (const guint8 *ssid1, gsize len1, return memcmp (ssid1, ssid2, len1) == 0 ? TRUE : FALSE; } -static void -value_destroy (gpointer data) -{ - GValue *value = (GValue *) data; - - g_value_unset (value); - g_slice_free (GValue, value); -} - -static void -value_dup (gpointer key, gpointer val, gpointer user_data) -{ - GHashTable *table = (GHashTable *) user_data; - GValue *value = (GValue *) val; - GValue *dup_value; - - dup_value = g_slice_new0 (GValue); - g_value_init (dup_value, G_VALUE_TYPE (val)); - g_value_copy (value, dup_value); - - g_hash_table_insert (table, g_strdup ((char *) key), dup_value); -} - -/** - * nm_utils_gvalue_hash_dup: - * @hash: a #GHashTable mapping string:GValue - * - * Utility function to duplicate a hash table of #GValues. - * - * Returns: (transfer container) (element-type utf8 GObject.Value): a newly allocated duplicated #GHashTable, caller must free the - * returned hash with g_hash_table_unref() or g_hash_table_destroy() - **/ -GHashTable * -nm_utils_gvalue_hash_dup (GHashTable *hash) -{ - GHashTable *table; - - g_return_val_if_fail (hash != NULL, NULL); - - table = g_hash_table_new_full (g_str_hash, g_str_equal, - (GDestroyNotify) g_free, - value_destroy); - - g_hash_table_foreach (hash, value_dup, table); - - return table; -} - gboolean _nm_utils_string_in_list (const char *str, const char **valid_strings) { @@ -514,30 +463,6 @@ _nm_utils_string_slist_validate (GSList *list, const char **valid_values) return TRUE; } -gboolean -_nm_utils_gvalue_array_validate (GValueArray *elements, guint n_expected, ...) -{ - va_list args; - GValue *tmp; - int i; - gboolean valid = FALSE; - - if (n_expected != elements->n_values) - return FALSE; - - va_start (args, n_expected); - for (i = 0; i < n_expected; i++) { - tmp = g_value_array_get_nth (elements, i); - if (G_VALUE_TYPE (tmp) != va_arg (args, GType)) - goto done; - } - valid = TRUE; - -done: - va_end (args); - return valid; -} - /** * _nm_utils_hash_values_to_slist: * @hash: a #GHashTable @@ -566,18 +491,39 @@ _nm_utils_hash_values_to_slist (GHashTable *hash) return list; } -void -_nm_utils_strdict_to_dbus (const GValue *prop_value, - GValue *dbus_value) +GVariant * +_nm_utils_strdict_to_dbus (const GValue *prop_value) { - g_value_set_boxed (dbus_value, g_value_get_boxed (prop_value)); + GHashTable *hash; + GHashTableIter iter; + gpointer key, value; + GVariantBuilder builder; + + g_variant_builder_init (&builder, G_VARIANT_TYPE ("a{ss}")); + hash = g_value_get_boxed (prop_value); + if (hash) { + g_hash_table_iter_init (&iter, hash); + while (g_hash_table_iter_next (&iter, &key, &value)) + g_variant_builder_add (&builder, "{ss}", key, value); + } + + return g_variant_builder_end (&builder); } void -_nm_utils_strdict_from_dbus (const GValue *dbus_value, +_nm_utils_strdict_from_dbus (GVariant *dbus_value, GValue *prop_value) { - g_value_set_boxed (prop_value, g_value_get_boxed (dbus_value)); + GVariantIter iter; + const char *key, *value; + GHashTable *hash; + + hash = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free); + g_variant_iter_init (&iter, dbus_value); + while (g_variant_iter_next (&iter, "{&s&s}", &key, &value)) + g_hash_table_insert (hash, g_strdup (key), g_strdup (value)); + + g_value_take_boxed (prop_value, hash); } GHashTable * @@ -652,32 +598,37 @@ _nm_utils_copy_object_array (const GPtrArray *array) return _nm_utils_copy_array (array, g_object_ref, g_object_unref); } -void -_nm_utils_bytes_to_dbus (const GValue *prop_value, - GValue *dbus_value) +GVariant * +_nm_utils_bytes_to_dbus (const GValue *prop_value) { GBytes *bytes = g_value_get_boxed (prop_value); - GByteArray *ba = NULL; if (bytes) { - ba = g_byte_array_new (); - g_byte_array_append (ba, - g_bytes_get_data (bytes, NULL), - g_bytes_get_size (bytes)); + return g_variant_new_fixed_array (G_VARIANT_TYPE_BYTE, + g_bytes_get_data (bytes, NULL), + g_bytes_get_size (bytes), + 1); + } else { + return g_variant_new_fixed_array (G_VARIANT_TYPE_BYTE, + NULL, 0, + 1); } - - g_value_take_boxed (dbus_value, ba); } void -_nm_utils_bytes_from_dbus (const GValue *dbus_value, +_nm_utils_bytes_from_dbus (GVariant *dbus_value, GValue *prop_value) { - GByteArray *ba = g_value_dup_boxed (dbus_value); - GBytes *bytes = NULL; + GBytes *bytes; - if (ba) - bytes = g_byte_array_free_to_bytes (ba); + if (g_variant_n_children (dbus_value)) { + gconstpointer data; + gsize length; + + data = g_variant_get_fixed_array (dbus_value, &length, 1); + bytes = g_bytes_new (data, length); + } else + bytes = NULL; g_value_take_boxed (prop_value, bytes); } @@ -1078,359 +1029,6 @@ nm_utils_wpa_psk_valid (const char *psk) return TRUE; } -void -_nm_utils_ip4_dns_to_dbus (const GValue *prop_value, - GValue *dbus_value) -{ - char **dns; - int i; - GArray *array; - - dns = g_value_get_boxed (prop_value); - array = g_array_new (FALSE, FALSE, sizeof (guint32)); - - if (dns) { - for (i = 0; dns[i]; i++) { - guint32 ip = 0; - - inet_pton (AF_INET, dns[i], &ip); - g_array_append_val (array, ip); - } - } - - g_value_take_boxed (dbus_value, array); -} - -void -_nm_utils_ip4_dns_from_dbus (const GValue *dbus_value, - GValue *prop_value) -{ - GArray *array; - GPtrArray *dns; - int i; - - array = g_value_get_boxed (dbus_value); - dns = g_ptr_array_new (); - - if (array) { - for (i = 0; i < array->len; i++) { - guint32 ip = g_array_index (array, guint32, i); - const char *str; - - str = nm_utils_inet4_ntop (ip, NULL); - g_ptr_array_add (dns, g_strdup (str)); - } - } - - g_ptr_array_add (dns, NULL); - g_value_take_boxed (prop_value, g_ptr_array_free (dns, FALSE)); -} - -void -_nm_utils_ip4_addresses_to_dbus (const GValue *prop_value, - GValue *dbus_value) -{ - GPtrArray *addresses, *dbus_addresses; - int i; - - addresses = g_value_get_boxed (prop_value); - dbus_addresses = g_ptr_array_new (); - - if (addresses) { - for (i = 0; i < addresses->len; i++) { - NMIP4Address *addr = addresses->pdata[i]; - GArray *array; - guint32 tmp; - - array = g_array_sized_new (FALSE, TRUE, sizeof (guint32), 3); - - tmp = nm_ip4_address_get_address (addr); - g_array_append_val (array, tmp); - - tmp = nm_ip4_address_get_prefix (addr); - g_array_append_val (array, tmp); - - tmp = nm_ip4_address_get_gateway (addr); - g_array_append_val (array, tmp); - - g_ptr_array_add (dbus_addresses, array); - } - } - - g_value_take_boxed (dbus_value, dbus_addresses); -} - -void -_nm_utils_ip4_addresses_from_dbus (const GValue *dbus_value, - GValue *prop_value) -{ - GPtrArray *dbus_addresses; - GPtrArray *addresses; - int i; - - dbus_addresses = g_value_get_boxed (dbus_value); - addresses = g_ptr_array_new_with_free_func ((GDestroyNotify) nm_ip4_address_unref); - - if (dbus_addresses) { - for (i = 0; i < dbus_addresses->len; i++) { - GArray *array = dbus_addresses->pdata[i]; - NMIP4Address *addr; - - if (array->len < 3) { - g_warning ("Ignoring invalid IP4 address"); - continue; - } - - addr = nm_ip4_address_new (); - nm_ip4_address_set_address (addr, g_array_index (array, guint32, 0)); - nm_ip4_address_set_prefix (addr, g_array_index (array, guint32, 1)); - nm_ip4_address_set_gateway (addr, g_array_index (array, guint32, 2)); - - g_ptr_array_add (addresses, addr); - } - } - - g_value_take_boxed (prop_value, addresses); -} - -void -_nm_utils_ip4_routes_to_dbus (const GValue *prop_value, - GValue *dbus_value) -{ - GPtrArray *routes, *dbus_routes; - int i; - - routes = g_value_get_boxed (prop_value); - dbus_routes = g_ptr_array_new (); - - if (routes) { - for (i = 0; i < routes->len; i++) { - NMIP4Route *route = routes->pdata[i]; - GArray *array; - guint32 tmp; - - array = g_array_sized_new (FALSE, TRUE, sizeof (guint32), 4); - - tmp = nm_ip4_route_get_dest (route); - g_array_append_val (array, tmp); - - tmp = nm_ip4_route_get_prefix (route); - g_array_append_val (array, tmp); - - tmp = nm_ip4_route_get_next_hop (route); - g_array_append_val (array, tmp); - - tmp = nm_ip4_route_get_metric (route); - g_array_append_val (array, tmp); - - g_ptr_array_add (dbus_routes, array); - } - } - - g_value_take_boxed (dbus_value, dbus_routes); -} - -void -_nm_utils_ip4_routes_from_dbus (const GValue *dbus_value, - GValue *prop_value) -{ - GPtrArray *dbus_routes, *routes; - int i; - - dbus_routes = g_value_get_boxed (dbus_value); - routes = g_ptr_array_new_with_free_func ((GDestroyNotify) nm_ip4_route_unref); - - if (dbus_routes) { - for (i = 0; i < dbus_routes->len; i++) { - GArray *array = dbus_routes->pdata[i]; - NMIP4Route *route; - - if (array->len < 4) { - g_warning ("Ignoring invalid IP4 route"); - continue; - } - - route = nm_ip4_route_new (); - nm_ip4_route_set_dest (route, g_array_index (array, guint32, 0)); - nm_ip4_route_set_prefix (route, g_array_index (array, guint32, 1)); - nm_ip4_route_set_next_hop (route, g_array_index (array, guint32, 2)); - nm_ip4_route_set_metric (route, g_array_index (array, guint32, 3)); - - g_ptr_array_add (routes, route); - } - } - - g_value_take_boxed (prop_value, routes); -} - -/** - * nm_utils_ip4_addresses_from_gvalue: - * @value: #GValue containing a #GPtrArray of #GArrays of #guint32s - * - * Utility function to convert a #GPtrArray of #GArrays of #guint32s representing - * a list of NetworkManager IPv4 addresses (which is a tuple of address, gateway, - * and prefix) into a #GSList of #NMIP4Address objects. The specific format of - * this serialization is not guaranteed to be stable and the #GArray may be - * extended in the future. - * - * Returns: (transfer full) (element-type NMIP4Address): a newly allocated #GSList of #NMIP4Address objects - **/ -GSList * -nm_utils_ip4_addresses_from_gvalue (const GValue *value) -{ - GPtrArray *addresses; - int i; - GSList *list = NULL; - - addresses = (GPtrArray *) g_value_get_boxed (value); - for (i = 0; addresses && (i < addresses->len); i++) { - GArray *array = (GArray *) g_ptr_array_index (addresses, i); - NMIP4Address *addr; - - if (array->len < 3) { - g_warning ("Ignoring invalid IP4 address"); - continue; - } - - addr = nm_ip4_address_new (); - nm_ip4_address_set_address (addr, g_array_index (array, guint32, 0)); - nm_ip4_address_set_prefix (addr, g_array_index (array, guint32, 1)); - nm_ip4_address_set_gateway (addr, g_array_index (array, guint32, 2)); - list = g_slist_prepend (list, addr); - } - - return g_slist_reverse (list); -} - -/** - * nm_utils_ip4_addresses_to_gvalue: - * @list: (element-type NMIP4Address): a list of #NMIP4Address objects - * @value: a pointer to a #GValue into which to place the converted addresses, - * which should be unset by the caller (when no longer needed) with - * g_value_unset(). - * - * Utility function to convert a #GSList of #NMIP4Address objects into a - * #GPtrArray of #GArrays of #guint32s representing a list of NetworkManager IPv4 - * addresses (which is a tuple of address, gateway, and prefix). The specific - * format of this serialization is not guaranteed to be stable and may be - * extended in the future. - **/ -void -nm_utils_ip4_addresses_to_gvalue (GSList *list, GValue *value) -{ - GPtrArray *addresses; - GSList *iter; - - addresses = g_ptr_array_new (); - - for (iter = list; iter; iter = iter->next) { - NMIP4Address *addr = (NMIP4Address *) iter->data; - GArray *array; - guint32 tmp; - - array = g_array_sized_new (FALSE, TRUE, sizeof (guint32), 3); - - tmp = nm_ip4_address_get_address (addr); - g_array_append_val (array, tmp); - - tmp = nm_ip4_address_get_prefix (addr); - g_array_append_val (array, tmp); - - tmp = nm_ip4_address_get_gateway (addr); - g_array_append_val (array, tmp); - - g_ptr_array_add (addresses, array); - } - - g_value_take_boxed (value, addresses); -} - -/** - * nm_utils_ip4_routes_from_gvalue: - * @value: #GValue containing a #GPtrArray of #GArrays of #guint32s - * - * Utility function to convert a #GPtrArray of #GArrays of #guint32s representing - * a list of NetworkManager IPv4 routes (which is a tuple of route, next hop, - * prefix, and metric) into a #GSList of #NMIP4Route objects. The specific - * format of this serialization is not guaranteed to be stable and may be - * extended in the future. - * - * Returns: (transfer full) (element-type NMIP4Route): a newly allocated #GSList of #NMIP4Route objects - **/ -GSList * -nm_utils_ip4_routes_from_gvalue (const GValue *value) -{ - GPtrArray *routes; - int i; - GSList *list = NULL; - - routes = (GPtrArray *) g_value_get_boxed (value); - for (i = 0; routes && (i < routes->len); i++) { - GArray *array = (GArray *) g_ptr_array_index (routes, i); - NMIP4Route *route; - - if (array->len < 4) { - g_warning ("Ignoring invalid IP4 route"); - continue; - } - - route = nm_ip4_route_new (); - nm_ip4_route_set_dest (route, g_array_index (array, guint32, 0)); - nm_ip4_route_set_prefix (route, g_array_index (array, guint32, 1)); - nm_ip4_route_set_next_hop (route, g_array_index (array, guint32, 2)); - nm_ip4_route_set_metric (route, g_array_index (array, guint32, 3)); - list = g_slist_prepend (list, route); - } - - return g_slist_reverse (list); -} - -/** - * nm_utils_ip4_routes_to_gvalue: - * @list: (element-type NMIP4Route): a list of #NMIP4Route objects - * @value: a pointer to a #GValue into which to place the converted routes, - * which should be unset by the caller (when no longer needed) with - * g_value_unset(). - * - * Utility function to convert a #GSList of #NMIP4Route objects into a - * #GPtrArray of #GArrays of #guint32s representing a list of NetworkManager IPv4 - * routes (which is a tuple of route, next hop, prefix, and metric). The - * specific format of this serialization is not guaranteed to be stable and may - * be extended in the future. - **/ -void -nm_utils_ip4_routes_to_gvalue (GSList *list, GValue *value) -{ - GPtrArray *routes; - GSList *iter; - - routes = g_ptr_array_new (); - - for (iter = list; iter; iter = iter->next) { - NMIP4Route *route = (NMIP4Route *) iter->data; - GArray *array; - guint32 tmp; - - array = g_array_sized_new (FALSE, TRUE, sizeof (guint32), 3); - - tmp = nm_ip4_route_get_dest (route); - g_array_append_val (array, tmp); - - tmp = nm_ip4_route_get_prefix (route); - g_array_append_val (array, tmp); - - tmp = nm_ip4_route_get_next_hop (route); - g_array_append_val (array, tmp); - - tmp = nm_ip4_route_get_metric (route); - g_array_append_val (array, tmp); - - g_ptr_array_add (routes, array); - } - - g_value_take_boxed (value, routes); -} - /** * nm_utils_ip4_dns_to_variant: * @dns: (type utf8): an array of IP address strings @@ -1728,620 +1326,6 @@ nm_utils_ip4_get_default_prefix (guint32 ip) return 24; /* Class C - 255.255.255.0 */ } -void -_nm_utils_ip6_dns_to_dbus (const GValue *prop_value, - GValue *dbus_value) -{ - char **dns; - GPtrArray *dbus_dns; - int i; - - dns = g_value_get_boxed (prop_value); - dbus_dns = g_ptr_array_new (); - - if (dns) { - for (i = 0; dns[i]; i++) { - GByteArray *bytearray; - - bytearray = g_byte_array_new (); - g_byte_array_set_size (bytearray, 16); - inet_pton (AF_INET6, dns[i], bytearray->data); - g_ptr_array_add (dbus_dns, bytearray); - } - } - - g_value_take_boxed (dbus_value, dbus_dns); -} - -void -_nm_utils_ip6_dns_from_dbus (const GValue *dbus_value, - GValue *prop_value) -{ - GPtrArray *dbus_dns, *dns; - int i; - - dbus_dns = g_value_get_boxed (dbus_value); - dns = g_ptr_array_new (); - - if (dbus_dns) { - for (i = 0; i < dbus_dns->len; i++) { - GByteArray *bytearray = dbus_dns->pdata[i]; - const char *str; - - if (bytearray->len != 16) { - g_warning ("%s: ignoring invalid IP6 address of length %d", - __func__, bytearray->len); - continue; - } - - str = nm_utils_inet6_ntop ((struct in6_addr *) bytearray->data, NULL); - g_ptr_array_add (dns, g_strdup (str)); - } - } - - g_ptr_array_add (dns, NULL); - g_value_take_boxed (prop_value, g_ptr_array_free (dns, FALSE)); -} - -void -_nm_utils_ip6_addresses_to_dbus (const GValue *prop_value, - GValue *dbus_value) -{ - GPtrArray *addresses, *dbus_addresses; - int i; - - addresses = g_value_get_boxed (prop_value); - dbus_addresses = g_ptr_array_new (); - - if (addresses) { - for (i = 0; i < addresses->len; i++) { - NMIP6Address *addr = addresses->pdata[i]; - GValueArray *array; - GValue element = G_VALUE_INIT; - GByteArray *ba; - - array = g_value_array_new (3); - - /* IP address */ - g_value_init (&element, DBUS_TYPE_G_UCHAR_ARRAY); - ba = g_byte_array_new (); - g_byte_array_append (ba, (guint8 *) nm_ip6_address_get_address (addr), 16); - g_value_take_boxed (&element, ba); - g_value_array_append (array, &element); - g_value_unset (&element); - - /* Prefix */ - g_value_init (&element, G_TYPE_UINT); - g_value_set_uint (&element, nm_ip6_address_get_prefix (addr)); - g_value_array_append (array, &element); - g_value_unset (&element); - - /* Gateway */ - g_value_init (&element, DBUS_TYPE_G_UCHAR_ARRAY); - ba = g_byte_array_new (); - g_byte_array_append (ba, (guint8 *) nm_ip6_address_get_gateway (addr), 16); - g_value_take_boxed (&element, ba); - g_value_array_append (array, &element); - g_value_unset (&element); - - g_ptr_array_add (dbus_addresses, array); - } - } - - g_value_take_boxed (dbus_value, dbus_addresses); -} - -void -_nm_utils_ip6_addresses_from_dbus (const GValue *dbus_value, - GValue *prop_value) -{ - GPtrArray *addresses, *dbus_addresses; - int i; - - dbus_addresses = g_value_get_boxed (dbus_value); - addresses = g_ptr_array_new_with_free_func ((GDestroyNotify) nm_ip6_address_unref); - - if (dbus_addresses) { - for (i = 0; i < dbus_addresses->len; i++) { - GValueArray *elements = dbus_addresses->pdata[i]; - GValue *tmp; - GByteArray *ba_addr; - GByteArray *ba_gw = NULL; - NMIP6Address *addr; - guint32 prefix; - - if (elements->n_values < 2 || elements->n_values > 3) { - g_warning ("%s: ignoring invalid IP6 address structure", __func__); - continue; - } - - /* Third element (gateway) is optional */ - if ( !_nm_utils_gvalue_array_validate (elements, 2, DBUS_TYPE_G_UCHAR_ARRAY, G_TYPE_UINT) - && !_nm_utils_gvalue_array_validate (elements, 3, DBUS_TYPE_G_UCHAR_ARRAY, G_TYPE_UINT, DBUS_TYPE_G_UCHAR_ARRAY)) { - g_warning ("%s: ignoring invalid IP6 address structure", __func__); - continue; - } - - tmp = g_value_array_get_nth (elements, 0); - ba_addr = g_value_get_boxed (tmp); - if (ba_addr->len != 16) { - g_warning ("%s: ignoring invalid IP6 address of length %d", - __func__, ba_addr->len); - continue; - } - - tmp = g_value_array_get_nth (elements, 1); - prefix = g_value_get_uint (tmp); - if (prefix > 128) { - g_warning ("%s: ignoring invalid IP6 prefix %d", - __func__, prefix); - continue; - } - - if (elements->n_values == 3) { - tmp = g_value_array_get_nth (elements, 2); - ba_gw = g_value_get_boxed (tmp); - if (ba_gw->len != 16) { - g_warning ("%s: ignoring invalid IP6 gateway address of length %d", - __func__, ba_gw->len); - continue; - } - } - - addr = nm_ip6_address_new (); - nm_ip6_address_set_prefix (addr, prefix); - nm_ip6_address_set_address (addr, (const struct in6_addr *) ba_addr->data); - if (ba_gw) - nm_ip6_address_set_gateway (addr, (const struct in6_addr *) ba_gw->data); - - g_ptr_array_add (addresses, addr); - } - } - - g_value_take_boxed (prop_value, addresses); -} - -void -_nm_utils_ip6_routes_to_dbus (const GValue *prop_value, - GValue *dbus_value) -{ - GPtrArray *routes, *dbus_routes; - int i; - - routes = g_value_get_boxed (prop_value); - dbus_routes = g_ptr_array_new (); - - if (routes) { - for (i = 0; i < routes->len; i++) { - NMIP6Route *route = routes->pdata[i]; - GValueArray *array; - const struct in6_addr *addr; - GByteArray *ba; - GValue element = G_VALUE_INIT; - - array = g_value_array_new (4); - - g_value_init (&element, DBUS_TYPE_G_UCHAR_ARRAY); - addr = nm_ip6_route_get_dest (route); - ba = g_byte_array_new (); - g_byte_array_append (ba, (guchar *)addr, sizeof (*addr)); - g_value_take_boxed (&element, ba); - g_value_array_append (array, &element); - g_value_unset (&element); - - g_value_init (&element, G_TYPE_UINT); - g_value_set_uint (&element, nm_ip6_route_get_prefix (route)); - g_value_array_append (array, &element); - g_value_unset (&element); - - g_value_init (&element, DBUS_TYPE_G_UCHAR_ARRAY); - addr = nm_ip6_route_get_next_hop (route); - ba = g_byte_array_new (); - g_byte_array_append (ba, (guchar *)addr, sizeof (*addr)); - g_value_take_boxed (&element, ba); - g_value_array_append (array, &element); - g_value_unset (&element); - - g_value_init (&element, G_TYPE_UINT); - g_value_set_uint (&element, nm_ip6_route_get_metric (route)); - g_value_array_append (array, &element); - g_value_unset (&element); - - g_ptr_array_add (dbus_routes, array); - } - } - - g_value_take_boxed (dbus_value, dbus_routes); -} - -void -_nm_utils_ip6_routes_from_dbus (const GValue *dbus_value, - GValue *prop_value) -{ - GPtrArray *routes, *dbus_routes; - int i; - - dbus_routes = g_value_get_boxed (dbus_value); - routes = g_ptr_array_new_with_free_func ((GDestroyNotify) nm_ip6_route_unref); - - if (dbus_routes) { - for (i = 0; i < dbus_routes->len; i++) { - GValueArray *route_values = dbus_routes->pdata[i]; - GByteArray *dest, *next_hop; - guint prefix, metric; - NMIP6Route *route; - - if (!_nm_utils_gvalue_array_validate (route_values, 4, - DBUS_TYPE_G_UCHAR_ARRAY, - G_TYPE_UINT, - DBUS_TYPE_G_UCHAR_ARRAY, - G_TYPE_UINT)) { - g_warning ("Ignoring invalid IP6 route"); - continue; - } - - dest = g_value_get_boxed (g_value_array_get_nth (route_values, 0)); - if (dest->len != 16) { - g_warning ("%s: ignoring invalid IP6 dest address of length %d", - __func__, dest->len); - continue; - } - - prefix = g_value_get_uint (g_value_array_get_nth (route_values, 1)); - - next_hop = g_value_get_boxed (g_value_array_get_nth (route_values, 2)); - if (next_hop->len != 16) { - g_warning ("%s: ignoring invalid IP6 next_hop address of length %d", - __func__, next_hop->len); - continue; - } - - metric = g_value_get_uint (g_value_array_get_nth (route_values, 3)); - - route = nm_ip6_route_new (); - nm_ip6_route_set_dest (route, (struct in6_addr *)dest->data); - nm_ip6_route_set_prefix (route, prefix); - nm_ip6_route_set_next_hop (route, (struct in6_addr *)next_hop->data); - nm_ip6_route_set_metric (route, metric); - - g_ptr_array_add (routes, route); - } - } - - g_value_take_boxed (prop_value, routes); -} - -/** - * nm_utils_ip6_addresses_from_gvalue: - * @value: gvalue containing a GPtrArray of GValueArrays of (GArray of guchars) and #guint32 - * - * Utility function to convert a #GPtrArray of #GValueArrays of (#GArray of guchars) and #guint32 - * representing a list of NetworkManager IPv6 addresses (which is a tuple of address, - * prefix, and gateway), into a #GSList of #NMIP6Address objects. The specific format of - * this serialization is not guaranteed to be stable and the #GValueArray may be - * extended in the future. - * - * Returns: (transfer full) (element-type NMIP6Address): a newly allocated #GSList of #NMIP6Address objects - **/ -GSList * -nm_utils_ip6_addresses_from_gvalue (const GValue *value) -{ - GPtrArray *addresses; - int i; - GSList *list = NULL; - - addresses = (GPtrArray *) g_value_get_boxed (value); - - for (i = 0; addresses && (i < addresses->len); i++) { - GValueArray *elements = (GValueArray *) g_ptr_array_index (addresses, i); - GValue *tmp; - GByteArray *ba_addr; - GByteArray *ba_gw = NULL; - NMIP6Address *addr; - guint32 prefix; - - if (elements->n_values < 2 || elements->n_values > 3) { - g_warning ("%s: ignoring invalid IP6 address structure", __func__); - continue; - } - - /* Third element (gateway) is optional */ - if ( !_nm_utils_gvalue_array_validate (elements, 2, DBUS_TYPE_G_UCHAR_ARRAY, G_TYPE_UINT) - && !_nm_utils_gvalue_array_validate (elements, 3, DBUS_TYPE_G_UCHAR_ARRAY, G_TYPE_UINT, DBUS_TYPE_G_UCHAR_ARRAY)) { - g_warning ("%s: ignoring invalid IP6 address structure", __func__); - continue; - } - - tmp = g_value_array_get_nth (elements, 0); - ba_addr = g_value_get_boxed (tmp); - if (ba_addr->len != 16) { - g_warning ("%s: ignoring invalid IP6 address of length %d", - __func__, ba_addr->len); - continue; - } - - tmp = g_value_array_get_nth (elements, 1); - prefix = g_value_get_uint (tmp); - if (prefix > 128) { - g_warning ("%s: ignoring invalid IP6 prefix %d", - __func__, prefix); - continue; - } - - if (elements->n_values == 3) { - tmp = g_value_array_get_nth (elements, 2); - ba_gw = g_value_get_boxed (tmp); - if (ba_gw->len != 16) { - g_warning ("%s: ignoring invalid IP6 gateway address of length %d", - __func__, ba_gw->len); - continue; - } - } - - addr = nm_ip6_address_new (); - nm_ip6_address_set_prefix (addr, prefix); - nm_ip6_address_set_address (addr, (const struct in6_addr *) ba_addr->data); - if (ba_gw) - nm_ip6_address_set_gateway (addr, (const struct in6_addr *) ba_gw->data); - - list = g_slist_prepend (list, addr); - } - - return g_slist_reverse (list); -} - -/** - * nm_utils_ip6_addresses_to_gvalue: - * @list: (element-type NMIP6Address): a list of #NMIP6Address objects - * @value: a pointer to a #GValue into which to place the converted addresses, - * which should be unset by the caller (when no longer needed) with - * g_value_unset(). - * - * Utility function to convert a #GSList of #NMIP6Address objects into a - * #GPtrArray of #GValueArrays representing a list of NetworkManager IPv6 addresses - * (which is a tuple of address, prefix, and gateway). The specific format of - * this serialization is not guaranteed to be stable and may be extended in the - * future. - **/ -void -nm_utils_ip6_addresses_to_gvalue (GSList *list, GValue *value) -{ - GPtrArray *addresses; - GSList *iter; - - addresses = g_ptr_array_new (); - - for (iter = list; iter; iter = iter->next) { - NMIP6Address *addr = (NMIP6Address *) iter->data; - GValueArray *array; - GValue element = G_VALUE_INIT; - GByteArray *ba; - - array = g_value_array_new (3); - - /* IP address */ - g_value_init (&element, DBUS_TYPE_G_UCHAR_ARRAY); - ba = g_byte_array_new (); - g_byte_array_append (ba, (guint8 *) nm_ip6_address_get_address (addr), 16); - g_value_take_boxed (&element, ba); - g_value_array_append (array, &element); - g_value_unset (&element); - - /* Prefix */ - g_value_init (&element, G_TYPE_UINT); - g_value_set_uint (&element, nm_ip6_address_get_prefix (addr)); - g_value_array_append (array, &element); - g_value_unset (&element); - - /* Gateway */ - g_value_init (&element, DBUS_TYPE_G_UCHAR_ARRAY); - ba = g_byte_array_new (); - g_byte_array_append (ba, (guint8 *) nm_ip6_address_get_gateway (addr), 16); - g_value_take_boxed (&element, ba); - g_value_array_append (array, &element); - g_value_unset (&element); - - g_ptr_array_add (addresses, array); - } - - g_value_take_boxed (value, addresses); -} - -/** - * nm_utils_ip6_routes_from_gvalue: - * @value: #GValue containing a #GPtrArray of #GValueArrays of (#GArray of #guchars), #guint32, - * (#GArray of #guchars), and #guint32 - * - * Utility function #GPtrArray of #GValueArrays of (#GArray of #guchars), #guint32, - * (#GArray of #guchars), and #guint32 representing a list of NetworkManager IPv6 - * routes (which is a tuple of destination, prefix, next hop, and metric) - * into a #GSList of #NMIP6Route objects. The specific format of this serialization - * is not guaranteed to be stable and may be extended in the future. - * - * Returns: (transfer full) (element-type NMIP6Route): a newly allocated #GSList of #NMIP6Route objects - **/ -GSList * -nm_utils_ip6_routes_from_gvalue (const GValue *value) -{ - GPtrArray *routes; - int i; - GSList *list = NULL; - - routes = (GPtrArray *) g_value_get_boxed (value); - for (i = 0; routes && (i < routes->len); i++) { - GValueArray *route_values = (GValueArray *) g_ptr_array_index (routes, i); - GByteArray *dest, *next_hop; - guint prefix, metric; - NMIP6Route *route; - - if (!_nm_utils_gvalue_array_validate (route_values, 4, - DBUS_TYPE_G_UCHAR_ARRAY, - G_TYPE_UINT, - DBUS_TYPE_G_UCHAR_ARRAY, - G_TYPE_UINT)) { - g_warning ("Ignoring invalid IP6 route"); - continue; - } - - dest = g_value_get_boxed (g_value_array_get_nth (route_values, 0)); - if (dest->len != 16) { - g_warning ("%s: ignoring invalid IP6 dest address of length %d", - __func__, dest->len); - continue; - } - - prefix = g_value_get_uint (g_value_array_get_nth (route_values, 1)); - - next_hop = g_value_get_boxed (g_value_array_get_nth (route_values, 2)); - if (next_hop->len != 16) { - g_warning ("%s: ignoring invalid IP6 next_hop address of length %d", - __func__, next_hop->len); - continue; - } - - metric = g_value_get_uint (g_value_array_get_nth (route_values, 3)); - - route = nm_ip6_route_new (); - nm_ip6_route_set_dest (route, (struct in6_addr *)dest->data); - nm_ip6_route_set_prefix (route, prefix); - nm_ip6_route_set_next_hop (route, (struct in6_addr *)next_hop->data); - nm_ip6_route_set_metric (route, metric); - list = g_slist_prepend (list, route); - } - - return g_slist_reverse (list); -} - -/** - * nm_utils_ip6_routes_to_gvalue: - * @list: (element-type NMIP6Route): a list of #NMIP6Route objects - * @value: a pointer to a #GValue into which to place the converted routes, - * which should be unset by the caller (when no longer needed) with - * g_value_unset(). - * - * Utility function to convert a #GSList of #NMIP6Route objects into a #GPtrArray of - * #GValueArrays of (#GArray of #guchars), #guint32, (#GArray of #guchars), and #guint32 - * representing a list of NetworkManager IPv6 routes (which is a tuple of destination, - * prefix, next hop, and metric). The specific format of this serialization is not - * guaranteed to be stable and may be extended in the future. - **/ -void -nm_utils_ip6_routes_to_gvalue (GSList *list, GValue *value) -{ - GPtrArray *routes; - GSList *iter; - - routes = g_ptr_array_new (); - - for (iter = list; iter; iter = iter->next) { - NMIP6Route *route = (NMIP6Route *) iter->data; - GValueArray *array; - const struct in6_addr *addr; - GByteArray *ba; - GValue element = G_VALUE_INIT; - - array = g_value_array_new (4); - - g_value_init (&element, DBUS_TYPE_G_UCHAR_ARRAY); - addr = nm_ip6_route_get_dest (route); - ba = g_byte_array_new (); - g_byte_array_append (ba, (guchar *)addr, sizeof (*addr)); - g_value_take_boxed (&element, ba); - g_value_array_append (array, &element); - g_value_unset (&element); - - g_value_init (&element, G_TYPE_UINT); - g_value_set_uint (&element, nm_ip6_route_get_prefix (route)); - g_value_array_append (array, &element); - g_value_unset (&element); - - g_value_init (&element, DBUS_TYPE_G_UCHAR_ARRAY); - addr = nm_ip6_route_get_next_hop (route); - ba = g_byte_array_new (); - g_byte_array_append (ba, (guchar *)addr, sizeof (*addr)); - g_value_take_boxed (&element, ba); - g_value_array_append (array, &element); - g_value_unset (&element); - - g_value_init (&element, G_TYPE_UINT); - g_value_set_uint (&element, nm_ip6_route_get_metric (route)); - g_value_array_append (array, &element); - g_value_unset (&element); - - g_ptr_array_add (routes, array); - } - - g_value_take_boxed (value, routes); -} - -/** - * nm_utils_ip6_dns_from_gvalue: (skip) - * @value: a #GValue - * - * Converts a #GValue containing a #GPtrArray of IP6 DNS, represented as - * #GByteArrays into a #GSList of IP address strings. - * - * Returns: a #GSList of IP6 addresses. - */ -GSList * -nm_utils_ip6_dns_from_gvalue (const GValue *value) -{ - GPtrArray *dns; - int i; - GSList *list = NULL; - - dns = (GPtrArray *) g_value_get_boxed (value); - for (i = 0; dns && (i < dns->len); i++) { - GByteArray *bytearray = (GByteArray *) g_ptr_array_index (dns, i); - const char *str; - - if (bytearray->len != 16) { - g_warning ("%s: ignoring invalid IP6 address of length %d", - __func__, bytearray->len); - continue; - } - - str = nm_utils_inet6_ntop ((struct in6_addr *) bytearray->data, NULL); - list = g_slist_prepend (list, g_strdup (str)); - } - - return g_slist_reverse (list); -} - -/** - * nm_utils_ip6_dns_to_gvalue: (skip) - * @list: a list of #NMIP6Route objects - * @value: a pointer to a #GValue into which to place the converted DNS server - * addresses, which should be unset by the caller (when no longer needed) with - * g_value_unset(). - * - * Utility function to convert a #GSList of struct - * in6_addr structs into a #GPtrArray of #GByteArrays - * representing each server's IPv6 addresses in network byte order. - * The specific format of this serialization is not guaranteed to be - * stable and may be extended in the future. - */ -void -nm_utils_ip6_dns_to_gvalue (GSList *list, GValue *value) -{ - GPtrArray *dns; - GSList *iter; - - dns = g_ptr_array_new (); - - for (iter = list; iter; iter = iter->next) { - const char *str = iter->data; - GByteArray *bytearray; - - bytearray = g_byte_array_new (); - g_byte_array_set_size (bytearray, 16); - inet_pton (AF_INET6, str, bytearray->data); - g_ptr_array_add (dns, bytearray); - } - - g_value_take_boxed (value, dns); -} - /** * nm_utils_ip6_dns_to_variant: * @dns: (type utf8): an array of IP address strings @@ -3395,25 +2379,33 @@ nm_utils_hwaddr_matches (gconstpointer hwaddr1, return !memcmp (hwaddr1, hwaddr2, hwaddr1_len); } -void -_nm_utils_hwaddr_to_dbus (const GValue *prop_value, - GValue *dbus_value) +GVariant * +_nm_utils_hwaddr_to_dbus (const GValue *prop_value) { const char *str = g_value_get_string (prop_value); - GByteArray *array; + guint8 buf[NM_UTILS_HWADDR_LEN_MAX]; + int len; - array = str ? nm_utils_hwaddr_atoba (str, hwaddr_binary_len (str)) : NULL; - g_value_take_boxed (dbus_value, array); + if (str) { + len = hwaddr_binary_len (str); + g_return_val_if_fail (len <= NM_UTILS_HWADDR_LEN_MAX, NULL); + if (!nm_utils_hwaddr_aton (str, buf, len)) + len = 0; + } else + len = 0; + + return g_variant_new_fixed_array (G_VARIANT_TYPE_BYTE, buf, len, 1); } void -_nm_utils_hwaddr_from_dbus (const GValue *dbus_value, +_nm_utils_hwaddr_from_dbus (GVariant *dbus_value, GValue *prop_value) { - GByteArray *array = g_value_get_boxed (dbus_value); + gsize length = 0; + const guint8 *array = g_variant_get_fixed_array (dbus_value, &length, 1); char *str; - str = array ? nm_utils_hwaddr_ntoa (array->data, array->len) : NULL; + str = length ? nm_utils_hwaddr_ntoa (array, length) : NULL; g_value_take_string (prop_value, str); } diff --git a/libnm-core/nm-utils.h b/libnm-core/nm-utils.h index 5c11112357..3bb4b9ff49 100644 --- a/libnm-core/nm-utils.h +++ b/libnm-core/nm-utils.h @@ -49,8 +49,6 @@ gboolean nm_utils_same_ssid (const guint8 *ssid1, gsize len1, gboolean ignore_trailing_null); char * nm_utils_ssid_to_utf8 (const guint8 *ssid, gsize len); -GHashTable *nm_utils_gvalue_hash_dup (GHashTable *hash); - /** * NMUtilsSecurityType: * @NMU_SEC_INVALID: unknown or invalid security, placeholder and not used @@ -95,12 +93,6 @@ gboolean nm_utils_ap_mode_security_valid (NMUtilsSecurityType type, gboolean nm_utils_wep_key_valid (const char *key, NMWepKeyType wep_type); gboolean nm_utils_wpa_psk_valid (const char *psk); -GSList *nm_utils_ip4_addresses_from_gvalue (const GValue *value); -void nm_utils_ip4_addresses_to_gvalue (GSList *list, GValue *value); - -GSList *nm_utils_ip4_routes_from_gvalue (const GValue *value); -void nm_utils_ip4_routes_to_gvalue (GSList *list, GValue *value); - GVariant *nm_utils_ip4_dns_to_variant (char **dns); char **nm_utils_ip4_dns_from_variant (GVariant *value); GVariant *nm_utils_ip4_addresses_to_variant (GPtrArray *addresses); @@ -112,15 +104,6 @@ guint32 nm_utils_ip4_netmask_to_prefix (guint32 netmask); guint32 nm_utils_ip4_prefix_to_netmask (guint32 prefix); guint32 nm_utils_ip4_get_default_prefix (guint32 ip); -GSList *nm_utils_ip6_addresses_from_gvalue (const GValue *value); -void nm_utils_ip6_addresses_to_gvalue (GSList *list, GValue *value); - -GSList *nm_utils_ip6_routes_from_gvalue (const GValue *value); -void nm_utils_ip6_routes_to_gvalue (GSList *list, GValue *value); - -GSList *nm_utils_ip6_dns_from_gvalue (const GValue *value); -void nm_utils_ip6_dns_to_gvalue (GSList *list, GValue *value); - GVariant *nm_utils_ip6_dns_to_variant (char **dns); char **nm_utils_ip6_dns_from_variant (GVariant *value); GVariant *nm_utils_ip6_addresses_to_variant (GPtrArray *addresses); diff --git a/libnm-core/nm-value-transforms.c b/libnm-core/nm-value-transforms.c deleted file mode 100644 index 77d2609741..0000000000 --- a/libnm-core/nm-value-transforms.c +++ /dev/null @@ -1,112 +0,0 @@ -/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ - -/* - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301 USA. - * - * Copyright 2005 - 2014 Red Hat, Inc. - */ - -#include "config.h" - -#include - -#include "nm-utils.h" -#include "nm-utils-private.h" -#include "nm-dbus-glib-types.h" -#include "nm-glib-compat.h" - -static void -_nm_utils_convert_op_to_string (const GValue *src_value, GValue *dest_value) -{ - g_return_if_fail (g_type_is_a (G_VALUE_TYPE (src_value), DBUS_TYPE_G_OBJECT_PATH)); - - g_value_set_string (dest_value, (const char *) g_value_get_boxed (src_value)); -} - -static void -_string_array_to_string (const GPtrArray *strings, GValue *dest_value) -{ - GString *printable; - guint i; - - printable = g_string_new (NULL); - for (i = 0; strings && i < strings->len; i++) { - if (i > 0) - g_string_append_c (printable, ','); - g_string_append (printable, strings->pdata[i]); - } - - g_value_take_string (dest_value, g_string_free (printable, FALSE)); -} - -static void -_nm_utils_convert_op_array_to_string (const GValue *src_value, GValue *dest_value) -{ - const GPtrArray *strings; - - g_return_if_fail (g_type_is_a (G_VALUE_TYPE (src_value), DBUS_TYPE_G_ARRAY_OF_OBJECT_PATH)); - - strings = (const GPtrArray *) g_value_get_boxed (src_value); - _string_array_to_string (strings, dest_value); -} - -static void -convert_one_gvalue_hash_entry (gpointer key, gpointer value, gpointer user_data) -{ - GString *printable = (GString *) user_data; - char *value_as_string; - - value_as_string = g_strdup_value_contents ((GValue *) value); - g_string_append_printf (printable, " { '%s': %s },", (const char *) key, value_as_string); - g_free (value_as_string); -} - -static void -_nm_utils_convert_gvalue_hash_to_string (const GValue *src_value, GValue *dest_value) -{ - GHashTable *hash; - GString *printable; - - g_return_if_fail (g_type_is_a (G_VALUE_TYPE (src_value), DBUS_TYPE_G_MAP_OF_VARIANT)); - - hash = (GHashTable *) g_value_get_boxed (src_value); - - printable = g_string_new ("["); - g_hash_table_foreach (hash, convert_one_gvalue_hash_entry, printable); - g_string_append (printable, " ]"); - - g_value_take_string (dest_value, printable->str); - g_string_free (printable, FALSE); -} - -void -_nm_value_transforms_register (void) -{ - static gboolean registered = FALSE; - - if (G_UNLIKELY (!registered)) { - g_value_register_transform_func (DBUS_TYPE_G_OBJECT_PATH, - G_TYPE_STRING, - _nm_utils_convert_op_to_string); - g_value_register_transform_func (DBUS_TYPE_G_ARRAY_OF_OBJECT_PATH, - G_TYPE_STRING, - _nm_utils_convert_op_array_to_string); - g_value_register_transform_func (DBUS_TYPE_G_MAP_OF_VARIANT, - G_TYPE_STRING, - _nm_utils_convert_gvalue_hash_to_string); - registered = TRUE; - } -} diff --git a/libnm-core/tests/Makefile.am b/libnm-core/tests/Makefile.am index 9966688689..eea0fc198e 100644 --- a/libnm-core/tests/Makefile.am +++ b/libnm-core/tests/Makefile.am @@ -9,7 +9,6 @@ AM_CPPFLAGS = \ -DNETWORKMANAGER_COMPILATION \ -DNM_VERSION_MAX_ALLOWED=NM_VERSION_NEXT_STABLE \ $(GLIB_CFLAGS) \ - $(DBUS_CFLAGS) \ -DTEST_CERT_DIR=\"$(certsdir)\" noinst_PROGRAMS = \ @@ -23,8 +22,7 @@ noinst_PROGRAMS = \ LDADD = \ $(top_builddir)/libnm-core/libnm-core.la \ - $(GLIB_LIBS) \ - $(DBUS_LIBS) + $(GLIB_LIBS) TESTS = $(noinst_PROGRAMS) diff --git a/libnm-core/tests/test-compare.c b/libnm-core/tests/test-compare.c index 5091403f02..e6ab047d64 100644 --- a/libnm-core/tests/test-compare.c +++ b/libnm-core/tests/test-compare.c @@ -21,9 +21,7 @@ #include #include -#include -#include "nm-dbus-glib-types.h" #include "nm-glib-compat.h" #include "nm-property-compare.h" @@ -33,256 +31,152 @@ static void compare_ints (void) { - GValue value1 = G_VALUE_INIT; - GValue value2 = G_VALUE_INIT; + GVariant *value1, *value2; - g_value_init (&value1, G_TYPE_INT); - g_value_init (&value2, G_TYPE_INT); + value1 = g_variant_new_int32 (5); + value2 = g_variant_new_int32 (5); + g_assert (nm_property_compare (value1, value2) == 0); - g_value_set_int (&value1, 5); - g_value_set_int (&value2, 5); - g_assert (nm_property_compare (&value1, &value2) == 0); + g_variant_unref (value2); + value2 = g_variant_new_int32 (10); + g_assert (nm_property_compare (value1, value2) < 0); - g_value_set_int (&value2, 10); - g_assert (nm_property_compare (&value1, &value2) < 0); + g_variant_unref (value2); + value2 = g_variant_new_int32 (-1); + g_assert (nm_property_compare (value1, value2) > 0); - g_value_set_int (&value2, 1); - g_assert (nm_property_compare (&value1, &value2) > 0); + g_variant_unref (value1); + g_variant_unref (value2); } static void compare_strings (void) { - GValue value1 = G_VALUE_INIT; - GValue value2 = G_VALUE_INIT; + GVariant *value1, *value2; const char *str1 = "hello"; const char *str2 = "world"; - g_value_init (&value1, G_TYPE_STRING); - g_value_init (&value2, G_TYPE_STRING); + value1 = g_variant_new_string (str1); + value2 = g_variant_new_string (str1); + g_assert (nm_property_compare (value1, value2) == 0); - g_value_set_string (&value1, str1); - g_value_set_string (&value2, str1); - g_assert (nm_property_compare (&value1, &value2) == 0); + g_variant_unref (value2); + value2 = g_variant_new_string (str2); + g_assert (nm_property_compare (value1, value2) < 0); - g_value_set_string (&value2, str2); - g_assert (nm_property_compare (&value1, &value2) < 0); + g_assert (nm_property_compare (value2, value1) > 0); - g_assert (nm_property_compare (&value2, &value1) > 0); + g_variant_unref (value1); + g_variant_unref (value2); } static void compare_strv (void) { - GValue value1 = G_VALUE_INIT; - GValue value2 = G_VALUE_INIT; - char *strv1[] = { "foo", "bar", "baz", NULL }; - char *strv2[] = { "foo", "bar", "bar", NULL }; - char *strv3[] = { "foo", "bar", NULL }; - char *strv4[] = { "foo", "bar", "baz", "bam", NULL }; + GVariant *value1, *value2; + const char * const strv1[] = { "foo", "bar", "baz", NULL }; + const char * const strv2[] = { "foo", "bar", "bar", NULL }; + const char * const strv3[] = { "foo", "bar", NULL }; + const char * const strv4[] = { "foo", "bar", "baz", "bam", NULL }; - g_value_init (&value1, G_TYPE_STRV); - g_value_init (&value2, G_TYPE_STRV); + value1 = g_variant_new_strv (strv1, -1); + value2 = g_variant_new_strv (strv1, -1); + g_assert (nm_property_compare (value1, value2) == 0); - g_value_set_boxed (&value1, strv1); - g_value_set_boxed (&value2, strv1); - g_assert (nm_property_compare (&value1, &value2) == 0); + g_variant_unref (value2); + value2 = g_variant_new_strv (strv2, -1); + g_assert (nm_property_compare (value1, value2) != 0); - g_value_set_boxed (&value2, strv2); - g_assert (nm_property_compare (&value1, &value2) != 0); + g_variant_unref (value2); + value2 = g_variant_new_strv (strv3, -1); + g_assert (nm_property_compare (value1, value2) != 0); - g_value_set_boxed (&value2, strv3); - g_assert (nm_property_compare (&value1, &value2) != 0); + g_variant_unref (value2); + value2 = g_variant_new_strv (strv4, -1); + g_assert (nm_property_compare (value1, value2) != 0); - g_value_set_boxed (&value2, strv4); - g_assert (nm_property_compare (&value1, &value2) != 0); + g_variant_unref (value1); + g_variant_unref (value2); } static void -compare_garrays (void) +compare_arrays (void) { - GArray *array1; - GArray *array2; - GValue value1 = G_VALUE_INIT; - GValue value2 = G_VALUE_INIT; - int i; + GVariant *value1, *value2; + guint32 array[] = { 0, 1, 2, 3, 4 }; - g_value_init (&value1, DBUS_TYPE_G_UINT_ARRAY); - array1 = g_array_new (FALSE, FALSE, sizeof (guint32)); + value1 = g_variant_new_fixed_array (G_VARIANT_TYPE_UINT32, + array, G_N_ELEMENTS (array), + sizeof (guint32)); + value2 = g_variant_new_fixed_array (G_VARIANT_TYPE_UINT32, + array, G_N_ELEMENTS (array), + sizeof (guint32)); - g_value_init (&value2, DBUS_TYPE_G_UINT_ARRAY); - array2 = g_array_new (FALSE, FALSE, sizeof (guint32)); + g_assert (nm_property_compare (value1, value2) == 0); - for (i = 0; i < 5; i++) { - g_array_append_val (array1, i); - g_array_append_val (array2, i); - } + g_variant_unref (value2); + value2 = g_variant_new_fixed_array (G_VARIANT_TYPE_UINT32, + array + 1, G_N_ELEMENTS (array) - 1, + sizeof (guint32)); + g_assert (nm_property_compare (value1, value2) != 0); - g_value_set_boxed (&value1, array1); - g_value_set_boxed (&value2, array2); - g_assert (nm_property_compare (&value1, &value2) == 0); + array[0] = 7; + g_variant_unref (value2); + value2 = g_variant_new_fixed_array (G_VARIANT_TYPE_UINT32, + array, G_N_ELEMENTS (array), + sizeof (guint32)); + g_assert (nm_property_compare (value1, value2) != 0); - g_array_remove_index (array2, 0); - g_value_set_boxed (&value2, array2); - g_assert (nm_property_compare (&value1, &value2) != 0); - - i = 7; - g_array_prepend_val (array2, i); - g_value_set_boxed (&value2, array2); - g_assert (nm_property_compare (&value1, &value2) != 0); -} - -static void -compare_ptrarrays (void) -{ - GPtrArray *array1; - GPtrArray *array2; - GValue value1 = G_VALUE_INIT; - GValue value2 = G_VALUE_INIT; - - g_value_init (&value1, dbus_g_type_get_collection ("GPtrArray", G_TYPE_STRING)); - array1 = g_ptr_array_new (); - - g_value_init (&value2, dbus_g_type_get_collection ("GPtrArray", G_TYPE_STRING)); - array2 = g_ptr_array_new (); - - g_ptr_array_add (array1, "hello"); - g_ptr_array_add (array1, "world"); - g_value_set_boxed (&value1, array1); - - g_ptr_array_add (array2, "hello"); - g_ptr_array_add (array2, "world"); - g_value_set_boxed (&value2, array2); - - g_assert (nm_property_compare (&value1, &value2) == 0); - - g_ptr_array_add (array2, "boo"); - g_value_set_boxed (&value2, array2); - g_assert (nm_property_compare (&value1, &value2) != 0); - - g_ptr_array_add (array1, "booz"); - g_value_set_boxed (&value1, array1); - g_assert (nm_property_compare (&value1, &value2) != 0); + g_variant_unref (value1); + g_variant_unref (value2); } static void compare_str_hash (void) { - GHashTable *hash1; - GHashTable *hash2; - GValue value1 = G_VALUE_INIT; - GValue value2 = G_VALUE_INIT; + GVariant *value1, *value2; + GVariantBuilder builder; - g_value_init (&value1, dbus_g_type_get_map ("GHashTable", G_TYPE_STRING, G_TYPE_STRING)); - g_value_init (&value2, dbus_g_type_get_map ("GHashTable", G_TYPE_STRING, G_TYPE_STRING)); + g_variant_builder_init (&builder, G_VARIANT_TYPE ("a{ss}")); + g_variant_builder_add (&builder, "{ss}", "key1", "hello"); + g_variant_builder_add (&builder, "{ss}", "key2", "world"); + g_variant_builder_add (&builder, "{ss}", "key3", "!"); + value1 = g_variant_builder_end (&builder); - hash1 = g_hash_table_new (g_str_hash, g_str_equal); - hash2 = g_hash_table_new (g_str_hash, g_str_equal); + g_variant_builder_init (&builder, G_VARIANT_TYPE ("a{ss}")); + g_variant_builder_add (&builder, "{ss}", "key3", "!"); + g_variant_builder_add (&builder, "{ss}", "key2", "world"); + g_variant_builder_add (&builder, "{ss}", "key1", "hello"); + value2 = g_variant_builder_end (&builder); - g_hash_table_insert (hash1, "key1", "hello"); - g_hash_table_insert (hash1, "key2", "world"); - g_hash_table_insert (hash1, "key3", "!"); + g_assert (nm_property_compare (value1, value2) == 0); - g_hash_table_insert (hash2, "key3", "!"); - g_hash_table_insert (hash2, "key2", "world"); - g_hash_table_insert (hash2, "key1", "hello"); + g_variant_unref (value2); + g_variant_builder_init (&builder, G_VARIANT_TYPE ("a{ss}")); + g_variant_builder_add (&builder, "{ss}", "key1", "hello"); + g_variant_builder_add (&builder, "{ss}", "key3", "!"); + value2 = g_variant_builder_end (&builder); - g_value_set_boxed (&value1, hash1); - g_value_set_boxed (&value2, hash2); - g_assert (nm_property_compare (&value1, &value2) == 0); + g_assert (nm_property_compare (value1, value2) != 0); + g_assert (nm_property_compare (value2, value1) != 0); - g_hash_table_remove (hash2, "key2"); - g_value_set_boxed (&value2, hash2); - g_assert (nm_property_compare (&value1, &value2) != 0); + g_variant_unref (value2); + g_variant_builder_init (&builder, G_VARIANT_TYPE ("a{ss}")); + g_variant_builder_add (&builder, "{ss}", "key1", "hello"); + g_variant_builder_add (&builder, "{ss}", "key2", "moon"); + g_variant_builder_add (&builder, "{ss}", "key3", "!"); + value2 = g_variant_builder_end (&builder); - g_hash_table_insert (hash2, "key2", "moon"); - g_value_set_boxed (&value2, hash2); - g_assert (nm_property_compare (&value1, &value2) != 0); -} + g_assert (nm_property_compare (value1, value2) != 0); -static GValue * -str_to_gvalue (const char *str) -{ - GValue *value; - - value = g_slice_new0 (GValue); - g_value_init (value, G_TYPE_STRING); - g_value_set_string (value, str); - - return value; -} - -static GValue * -uint_to_gvalue (guint i) -{ - GValue *value; - - value = g_slice_new0 (GValue); - g_value_init (value, G_TYPE_UINT); - g_value_set_uint (value, i); - - return value; -} - -static GValue * -double_to_gvalue (double d) -{ - GValue *value; - - value = g_slice_new0 (GValue); - g_value_init (value, G_TYPE_DOUBLE); - g_value_set_double (value, d); - - return value; -} - -static void -compare_gvalue_hash (void) -{ - GHashTable *hash1; - GHashTable *hash2; - GValue value1 = G_VALUE_INIT; - GValue value2 = G_VALUE_INIT; - - g_value_init (&value1, dbus_g_type_get_map ("GHashTable", G_TYPE_STRING, G_TYPE_VALUE)); - g_value_init (&value2, dbus_g_type_get_map ("GHashTable", G_TYPE_STRING, G_TYPE_VALUE)); - - hash1 = g_hash_table_new (g_str_hash, g_str_equal); - hash2 = g_hash_table_new (g_str_hash, g_str_equal); - - g_hash_table_insert (hash1, "key1", str_to_gvalue ("hello")); - g_hash_table_insert (hash1, "key2", uint_to_gvalue (5)); - g_hash_table_insert (hash1, "key3", double_to_gvalue (123.456)); - - g_hash_table_insert (hash2, "key3", double_to_gvalue (123.456)); - g_hash_table_insert (hash2, "key2", uint_to_gvalue (5)); - g_hash_table_insert (hash2, "key1", str_to_gvalue ("hello")); - - g_value_set_boxed (&value1, hash1); - g_value_set_boxed (&value2, hash2); - g_assert (nm_property_compare (&value1, &value2) == 0); - - g_hash_table_remove (hash2, "key2"); - g_value_set_boxed (&value2, hash2); - g_assert (nm_property_compare (&value1, &value2) != 0); - - g_hash_table_insert (hash2, "key2", str_to_gvalue ("moon")); - g_value_set_boxed (&value2, hash2); - g_assert (nm_property_compare (&value1, &value2) != 0); + g_variant_unref (value1); + g_variant_unref (value2); } static void compare_ip6_addresses (void) { - GValueArray *array1; - GValueArray *array2; - GValueArray *array3; - GByteArray *ba1; - GByteArray *ba2; - GByteArray *ba3; - GValue element = G_VALUE_INIT; - GValue value1 = G_VALUE_INIT; - GValue value2 = G_VALUE_INIT; + GVariant *value1, *value2; struct in6_addr addr1; struct in6_addr addr2; struct in6_addr addr3; @@ -294,86 +188,44 @@ compare_ip6_addresses (void) inet_pton (AF_INET6, "ffff:2:3:4:5:6:7:8", &addr2); inet_pton (AF_INET6, "::", &addr3); - /* address 1 */ - array1 = g_value_array_new (2); + value1 = g_variant_new ("(@ayu@ay)", + g_variant_new_fixed_array (G_VARIANT_TYPE_BYTE, + (guint8 *) addr1.s6_addr, 16, 1), + prefix1, + g_variant_new_fixed_array (G_VARIANT_TYPE_BYTE, + (guint8 *) addr3.s6_addr, 16, 1)); - ba1 = g_byte_array_new (); - g_value_init (&element, DBUS_TYPE_G_UCHAR_ARRAY); - g_byte_array_append (ba1, (guint8 *) addr1.s6_addr, 16); - g_value_take_boxed (&element, ba1); - g_value_array_append (array1, &element); - g_value_unset (&element); + value2 = g_variant_new ("(@ayu@ay)", + g_variant_new_fixed_array (G_VARIANT_TYPE_BYTE, + (guint8 *) addr1.s6_addr, 16, 1), + prefix1, + g_variant_new_fixed_array (G_VARIANT_TYPE_BYTE, + (guint8 *) addr3.s6_addr, 16, 1)); - g_value_init (&element, G_TYPE_UINT); - g_value_set_uint (&element, prefix1); - g_value_array_append (array1, &element); - g_value_unset (&element); + g_assert (nm_property_compare (value1, value2) == 0); - ba1 = g_byte_array_new (); - g_value_init (&element, DBUS_TYPE_G_UCHAR_ARRAY); - g_byte_array_append (ba1, (guint8 *) addr3.s6_addr, 16); - g_value_take_boxed (&element, ba1); - g_value_array_append (array1, &element); - g_value_unset (&element); + g_variant_unref (value2); + value2 = g_variant_new ("(@ayu@ay)", + g_variant_new_fixed_array (G_VARIANT_TYPE_BYTE, + (guint8 *) addr2.s6_addr, 16, 1), + prefix2, + g_variant_new_fixed_array (G_VARIANT_TYPE_BYTE, + (guint8 *) addr3.s6_addr, 16, 1)); - /* address 2 */ - array2 = g_value_array_new (2); + g_assert (nm_property_compare (value1, value2) != 0); - ba2 = g_byte_array_new (); - g_value_init (&element, DBUS_TYPE_G_UCHAR_ARRAY); - g_byte_array_append (ba2, (guint8 *) addr2.s6_addr, 16); - g_value_take_boxed (&element, ba2); - g_value_array_append (array2, &element); - g_value_unset (&element); + g_variant_unref (value2); + value2 = g_variant_new ("(@ayu@ay)", + g_variant_new_fixed_array (G_VARIANT_TYPE_BYTE, + (guint8 *) addr3.s6_addr, 16, 1), + prefix3, + g_variant_new_fixed_array (G_VARIANT_TYPE_BYTE, + (guint8 *) addr3.s6_addr, 16, 1)); - g_value_init (&element, G_TYPE_UINT); - g_value_set_uint (&element, prefix2); - g_value_array_append (array2, &element); - g_value_unset (&element); + g_assert (nm_property_compare (value1, value2) != 0); - ba2 = g_byte_array_new (); - g_value_init (&element, DBUS_TYPE_G_UCHAR_ARRAY); - g_byte_array_append (ba2, (guint8 *) addr3.s6_addr, 16); - g_value_take_boxed (&element, ba2); - g_value_array_append (array2, &element); - g_value_unset (&element); - - /* address 3 */ - array3 = g_value_array_new (2); - - ba3 = g_byte_array_new (); - g_value_init (&element, DBUS_TYPE_G_UCHAR_ARRAY); - g_byte_array_append (ba3, (guint8 *) addr3.s6_addr, 16); - g_value_take_boxed (&element, ba3); - g_value_array_append (array3, &element); - g_value_unset (&element); - - g_value_init (&element, G_TYPE_UINT); - g_value_set_uint (&element, prefix3); - g_value_array_append (array3, &element); - g_value_unset (&element); - - ba3 = g_byte_array_new (); - g_value_init (&element, DBUS_TYPE_G_UCHAR_ARRAY); - g_byte_array_append (ba3, (guint8 *) addr3.s6_addr, 16); - g_value_take_boxed (&element, ba3); - g_value_array_append (array3, &element); - g_value_unset (&element); - - g_value_init (&value1, DBUS_TYPE_G_IP6_ADDRESS); - g_value_init (&value2, DBUS_TYPE_G_IP6_ADDRESS); - - g_value_set_boxed (&value1, array1); - g_value_set_boxed (&value2, array1); - g_assert (nm_property_compare (&value1, &value2) == 0); - - g_value_set_boxed (&value1, array1); - g_value_set_boxed (&value2, array2); - g_assert (nm_property_compare (&value1, &value2) != 0); - - g_value_set_boxed (&value1, array1); - g_value_set_boxed (&value2, array3); - g_assert (nm_property_compare (&value1, &value2) != 0); + g_variant_unref (value1); + g_variant_unref (value2); } NMTST_DEFINE (); @@ -386,10 +238,8 @@ main (int argc, char *argv[]) g_test_add_func ("/libnm/compare/ints", compare_ints); g_test_add_func ("/libnm/compare/strings", compare_strings); g_test_add_func ("/libnm/compare/strv", compare_strv); - g_test_add_func ("/libnm/compare/garrays", compare_garrays); - g_test_add_func ("/libnm/compare/ptrarrays", compare_ptrarrays); + g_test_add_func ("/libnm/compare/arrays", compare_arrays); g_test_add_func ("/libnm/compare/str_hash", compare_str_hash); - g_test_add_func ("/libnm/compare/gvalue_hash", compare_gvalue_hash); g_test_add_func ("/libnm/compare/ip6_addresses", compare_ip6_addresses); return g_test_run (); diff --git a/libnm-core/tests/test-general.c b/libnm-core/tests/test-general.c index a46a3cf905..af1a6fb549 100644 --- a/libnm-core/tests/test-general.c +++ b/libnm-core/tests/test-general.c @@ -20,7 +20,6 @@ */ #include -#include #include #include @@ -40,7 +39,6 @@ #include "nm-setting-bond.h" #include "nm-utils.h" #include "nm-core-internal.h" -#include "nm-dbus-glib-types.h" #include "nm-test-utils.h" @@ -181,8 +179,8 @@ test_setting_vpn_update_secrets (void) { NMConnection *connection; NMSettingVpn *s_vpn; - GHashTable *settings, *vpn, *secrets; - GValue val = G_VALUE_INIT; + GVariantBuilder settings_builder, vpn_builder, secrets_builder; + GVariant *settings; gboolean success; GError *error = NULL; const char *tmp; @@ -202,18 +200,20 @@ test_setting_vpn_update_secrets (void) "error creating vpn setting"); nm_connection_add_setting (connection, NM_SETTING (s_vpn)); - settings = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, (GDestroyNotify) g_hash_table_destroy); - vpn = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, (GDestroyNotify) g_value_unset); - g_hash_table_insert (settings, NM_SETTING_VPN_SETTING_NAME, vpn); + g_variant_builder_init (&settings_builder, NM_VARIANT_TYPE_CONNECTION); + g_variant_builder_init (&vpn_builder, NM_VARIANT_TYPE_SETTING); + g_variant_builder_init (&secrets_builder, G_VARIANT_TYPE ("a{ss}")); - secrets = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, NULL); - g_value_init (&val, DBUS_TYPE_G_MAP_OF_STRING); - g_value_take_boxed (&val, secrets); - g_hash_table_insert (vpn, NM_SETTING_VPN_SECRETS, &val); + g_variant_builder_add (&secrets_builder, "{ss}", key1, val1); + g_variant_builder_add (&secrets_builder, "{ss}", key2, val2); - /* Add some secrets */ - g_hash_table_insert (secrets, (char *) key1, (char *) val1); - g_hash_table_insert (secrets, (char *) key2, (char *) val2); + g_variant_builder_add (&vpn_builder, "{sv}", + NM_SETTING_VPN_SECRETS, + g_variant_builder_end (&secrets_builder)); + g_variant_builder_add (&settings_builder, "{sa{sv}}", + NM_SETTING_VPN_SETTING_NAME, + &vpn_builder); + settings = g_variant_builder_end (&settings_builder); success = nm_connection_update_secrets (connection, NM_SETTING_VPN_SETTING_NAME, settings, &error); ASSERT (success == TRUE, @@ -232,7 +232,7 @@ test_setting_vpn_update_secrets (void) ASSERT (strcmp (tmp, val2) == 0, "vpn-update-secrets", "unexpected key #2 value"); - g_hash_table_destroy (settings); + g_variant_unref (settings); g_object_unref (connection); } @@ -581,27 +581,42 @@ make_test_wsec_setting (const char *detail) return s_wsec; } +#define ASSERT_CONTAINS(vardict, key, test_name, msg) \ + { \ + GVariant *value; \ + value = g_variant_lookup_value (vardict, key, NULL); \ + ASSERT (value != NULL, test_name, msg); \ + g_variant_unref (value); \ + } + +#define ASSERT_NOT_CONTAINS(vardict, key, test_name, msg) \ + { \ + GVariant *value; \ + value = g_variant_lookup_value (vardict, key, NULL); \ + ASSERT (value == NULL, test_name, msg); \ + } + static void test_setting_to_dbus_all (void) { NMSettingWirelessSecurity *s_wsec; - GHashTable *hash; + GVariant *dict; s_wsec = make_test_wsec_setting ("setting-to-dbus-all"); - hash = _nm_setting_to_dbus (NM_SETTING (s_wsec), NULL, NM_CONNECTION_SERIALIZE_ALL); + dict = _nm_setting_to_dbus (NM_SETTING (s_wsec), NULL, NM_CONNECTION_SERIALIZE_ALL); /* Make sure all keys are there */ - ASSERT (g_hash_table_lookup (hash, NM_SETTING_WIRELESS_SECURITY_KEY_MGMT), + ASSERT_CONTAINS (dict, NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, "setting-to-dbus-all", "unexpectedly missing " NM_SETTING_WIRELESS_SECURITY_KEY_MGMT); - ASSERT (g_hash_table_lookup (hash, NM_SETTING_WIRELESS_SECURITY_LEAP_USERNAME), + ASSERT_CONTAINS (dict, NM_SETTING_WIRELESS_SECURITY_LEAP_USERNAME, "setting-to-dbus-all", "unexpectedly missing " NM_SETTING_WIRELESS_SECURITY_LEAP_USERNAME); - ASSERT (g_hash_table_lookup (hash, NM_SETTING_WIRELESS_SECURITY_PSK), + ASSERT_CONTAINS (dict, NM_SETTING_WIRELESS_SECURITY_PSK, "setting-to-dbus-all", "unexpectedly missing " NM_SETTING_WIRELESS_SECURITY_PSK); - ASSERT (g_hash_table_lookup (hash, NM_SETTING_WIRELESS_SECURITY_WEP_KEY0), + ASSERT_CONTAINS (dict, NM_SETTING_WIRELESS_SECURITY_WEP_KEY0, "setting-to-dbus-all", "unexpectedly missing " NM_SETTING_WIRELESS_SECURITY_WEP_KEY0); - g_hash_table_destroy (hash); + g_variant_unref (dict); g_object_unref (s_wsec); } @@ -609,25 +624,25 @@ static void test_setting_to_dbus_no_secrets (void) { NMSettingWirelessSecurity *s_wsec; - GHashTable *hash; + GVariant *dict; s_wsec = make_test_wsec_setting ("setting-to-dbus-no-secrets"); - hash = _nm_setting_to_dbus (NM_SETTING (s_wsec), NULL, NM_CONNECTION_SERIALIZE_NO_SECRETS); + dict = _nm_setting_to_dbus (NM_SETTING (s_wsec), NULL, NM_CONNECTION_SERIALIZE_NO_SECRETS); /* Make sure non-secret keys are there */ - ASSERT (g_hash_table_lookup (hash, NM_SETTING_WIRELESS_SECURITY_KEY_MGMT), - "setting-to-dbus-no-secrets", "unexpectedly missing " NM_SETTING_WIRELESS_SECURITY_KEY_MGMT); - ASSERT (g_hash_table_lookup (hash, NM_SETTING_WIRELESS_SECURITY_LEAP_USERNAME), - "setting-to-dbus-no-secrets", "unexpectedly missing " NM_SETTING_WIRELESS_SECURITY_LEAP_USERNAME); + ASSERT_CONTAINS (dict, NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, + "setting-to-dbus-no-secrets", "unexpectedly missing " NM_SETTING_WIRELESS_SECURITY_KEY_MGMT); + ASSERT_CONTAINS (dict, NM_SETTING_WIRELESS_SECURITY_LEAP_USERNAME, + "setting-to-dbus-no-secrets", "unexpectedly missing " NM_SETTING_WIRELESS_SECURITY_LEAP_USERNAME); /* Make sure secrets are not there */ - ASSERT (g_hash_table_lookup (hash, NM_SETTING_WIRELESS_SECURITY_PSK) == NULL, - "setting-to-dbus-no-secrets", "unexpectedly present " NM_SETTING_WIRELESS_SECURITY_PSK); - ASSERT (g_hash_table_lookup (hash, NM_SETTING_WIRELESS_SECURITY_WEP_KEY0) == NULL, - "setting-to-dbus-no-secrets", "unexpectedly present " NM_SETTING_WIRELESS_SECURITY_WEP_KEY0); + ASSERT_NOT_CONTAINS (dict, NM_SETTING_WIRELESS_SECURITY_PSK, + "setting-to-dbus-no-secrets", "unexpectedly present " NM_SETTING_WIRELESS_SECURITY_PSK); + ASSERT_NOT_CONTAINS (dict, NM_SETTING_WIRELESS_SECURITY_WEP_KEY0, + "setting-to-dbus-no-secrets", "unexpectedly present " NM_SETTING_WIRELESS_SECURITY_WEP_KEY0); - g_hash_table_destroy (hash); + g_variant_unref (dict); g_object_unref (s_wsec); } @@ -635,25 +650,25 @@ static void test_setting_to_dbus_only_secrets (void) { NMSettingWirelessSecurity *s_wsec; - GHashTable *hash; + GVariant *dict; s_wsec = make_test_wsec_setting ("setting-to-dbus-only-secrets"); - hash = _nm_setting_to_dbus (NM_SETTING (s_wsec), NULL, NM_CONNECTION_SERIALIZE_ONLY_SECRETS); + dict = _nm_setting_to_dbus (NM_SETTING (s_wsec), NULL, NM_CONNECTION_SERIALIZE_ONLY_SECRETS); - /* Make sure non-secret keys are there */ - ASSERT (g_hash_table_lookup (hash, NM_SETTING_WIRELESS_SECURITY_KEY_MGMT) == NULL, - "setting-to-dbus-only-secrets", "unexpectedly present " NM_SETTING_WIRELESS_SECURITY_KEY_MGMT); - ASSERT (g_hash_table_lookup (hash, NM_SETTING_WIRELESS_SECURITY_LEAP_USERNAME) == NULL, - "setting-to-dbus-only-secrets", "unexpectedly present " NM_SETTING_WIRELESS_SECURITY_LEAP_USERNAME); + /* Make sure non-secret keys are not there */ + ASSERT_NOT_CONTAINS (dict, NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, + "setting-to-dbus-only-secrets", "unexpectedly present " NM_SETTING_WIRELESS_SECURITY_KEY_MGMT); + ASSERT_NOT_CONTAINS (dict, NM_SETTING_WIRELESS_SECURITY_LEAP_USERNAME, + "setting-to-dbus-only-secrets", "unexpectedly present " NM_SETTING_WIRELESS_SECURITY_LEAP_USERNAME); - /* Make sure secrets are not there */ - ASSERT (g_hash_table_lookup (hash, NM_SETTING_WIRELESS_SECURITY_PSK), - "setting-to-dbus-only-secrets", "unexpectedly missing " NM_SETTING_WIRELESS_SECURITY_PSK); - ASSERT (g_hash_table_lookup (hash, NM_SETTING_WIRELESS_SECURITY_WEP_KEY0), - "setting-to-dbus-only-secrets", "unexpectedly missing " NM_SETTING_WIRELESS_SECURITY_WEP_KEY0); + /* Make sure secrets are there */ + ASSERT_CONTAINS (dict, NM_SETTING_WIRELESS_SECURITY_PSK, + "setting-to-dbus-only-secrets", "unexpectedly missing " NM_SETTING_WIRELESS_SECURITY_PSK); + ASSERT_CONTAINS (dict, NM_SETTING_WIRELESS_SECURITY_WEP_KEY0, + "setting-to-dbus-only-secrets", "unexpectedly missing " NM_SETTING_WIRELESS_SECURITY_WEP_KEY0); - g_hash_table_destroy (hash); + g_variant_unref (dict); g_object_unref (s_wsec); } @@ -661,11 +676,11 @@ static void test_setting_to_dbus_transform (void) { NMSetting *s_wired; - GHashTable *hash; - GValue *val; + GVariant *dict, *val; const char *test_mac_address = "11:22:33:44:55:66"; - GByteArray *dbus_mac_address; - GByteArray *cmp_mac_address; + const guint8 *dbus_mac_address; + guint8 cmp_mac_address[ETH_ALEN]; + gsize len; s_wired = nm_setting_wired_new (); g_object_set (s_wired, @@ -674,22 +689,20 @@ test_setting_to_dbus_transform (void) g_assert_cmpstr (nm_setting_wired_get_mac_address (NM_SETTING_WIRED (s_wired)), ==, test_mac_address); - hash = _nm_setting_to_dbus (s_wired, NULL, NM_CONNECTION_SERIALIZE_ALL); - g_assert (hash != NULL); + dict = _nm_setting_to_dbus (s_wired, NULL, NM_CONNECTION_SERIALIZE_ALL); + g_assert (dict != NULL); - val = g_hash_table_lookup (hash, NM_SETTING_WIRED_MAC_ADDRESS); + val = g_variant_lookup_value (dict, NM_SETTING_WIRED_MAC_ADDRESS, G_VARIANT_TYPE_BYTESTRING); g_assert (val != NULL); - g_assert (G_VALUE_HOLDS (val, DBUS_TYPE_G_UCHAR_ARRAY)); - dbus_mac_address = g_value_get_boxed (val); + dbus_mac_address = g_variant_get_fixed_array (val, &len, 1); + g_assert_cmpint (len, ==, ETH_ALEN); - cmp_mac_address = nm_utils_hwaddr_atoba (test_mac_address, ETH_ALEN); + nm_utils_hwaddr_aton (test_mac_address, cmp_mac_address, ETH_ALEN); + g_assert (memcmp (dbus_mac_address, cmp_mac_address, ETH_ALEN) == 0); - g_assert_cmpint (dbus_mac_address->len, ==, cmp_mac_address->len); - g_assert (memcmp (dbus_mac_address->data, cmp_mac_address->data, ETH_ALEN) == 0); - - g_byte_array_unref (cmp_mac_address); - g_hash_table_unref (hash); + g_variant_unref (val); + g_variant_unref (dict); g_object_unref (s_wired); } @@ -698,21 +711,21 @@ test_connection_to_dbus_setting_name (void) { NMConnection *connection; NMSettingWirelessSecurity *s_wsec; - GHashTable *hash; + GVariant *dict; connection = nm_simple_connection_new (); s_wsec = make_test_wsec_setting ("connection-to-dbus-setting-name"); nm_connection_add_setting (connection, NM_SETTING (s_wsec)); - hash = nm_connection_to_dbus (connection, NM_CONNECTION_SERIALIZE_ALL); + dict = nm_connection_to_dbus (connection, NM_CONNECTION_SERIALIZE_ALL); - /* Make sure the keys of the first level hash are setting names, not + /* Make sure the keys of the first level dict are setting names, not * the GType name of the setting objects. */ - ASSERT (g_hash_table_lookup (hash, NM_SETTING_WIRELESS_SECURITY_SETTING_NAME) != NULL, - "connection-to-dbus-setting-name", "unexpectedly missing " NM_SETTING_WIRELESS_SECURITY_SETTING_NAME); + ASSERT_CONTAINS (dict, NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, + "connection-to-dbus-setting-name", "unexpectedly missing " NM_SETTING_WIRELESS_SECURITY_SETTING_NAME); - g_hash_table_destroy (hash); + g_variant_unref (dict); g_object_unref (connection); } @@ -723,8 +736,7 @@ test_connection_to_dbus_deprecated_props (void) NMSetting *s_wireless; GBytes *ssid; NMSettingWirelessSecurity *s_wsec; - GHashTable *hash, *wireless_hash; - GValue *sec_val; + GVariant *dict, *wireless_dict, *sec_val; connection = nmtst_create_minimal_connection ("test-connection-to-dbus-deprecated-props", NULL, @@ -739,33 +751,36 @@ test_connection_to_dbus_deprecated_props (void) g_bytes_unref (ssid); nm_connection_add_setting (connection, s_wireless); - /* Hash should not have an 802-11-wireless.security property */ - hash = nm_connection_to_dbus (connection, NM_CONNECTION_SERIALIZE_ALL); - g_assert (hash != NULL); + /* Serialization should not have an 802-11-wireless.security property */ + dict = nm_connection_to_dbus (connection, NM_CONNECTION_SERIALIZE_ALL); + g_assert (dict != NULL); - wireless_hash = g_hash_table_lookup (hash, NM_SETTING_WIRELESS_SETTING_NAME); - g_assert (wireless_hash != NULL); + wireless_dict = g_variant_lookup_value (dict, NM_SETTING_WIRELESS_SETTING_NAME, NM_VARIANT_TYPE_SETTING); + g_assert (wireless_dict != NULL); - sec_val = g_hash_table_lookup (wireless_hash, "security"); + sec_val = g_variant_lookup_value (wireless_dict, "security", NULL); g_assert (sec_val == NULL); - g_hash_table_destroy (hash); + g_variant_unref (wireless_dict); + g_variant_unref (dict); /* Now add an NMSettingWirelessSecurity and try again */ s_wsec = make_test_wsec_setting ("test-connection-to-dbus-deprecated-props"); nm_connection_add_setting (connection, NM_SETTING (s_wsec)); - hash = nm_connection_to_dbus (connection, NM_CONNECTION_SERIALIZE_ALL); - g_assert (hash != NULL); + dict = nm_connection_to_dbus (connection, NM_CONNECTION_SERIALIZE_ALL); + g_assert (dict != NULL); - wireless_hash = g_hash_table_lookup (hash, NM_SETTING_WIRELESS_SETTING_NAME); - g_assert (wireless_hash != NULL); + wireless_dict = g_variant_lookup_value (dict, NM_SETTING_WIRELESS_SETTING_NAME, NM_VARIANT_TYPE_SETTING); + g_assert (wireless_dict != NULL); - sec_val = g_hash_table_lookup (wireless_hash, "security"); - g_assert (G_VALUE_HOLDS_STRING (sec_val)); - g_assert_cmpstr (g_value_get_string (sec_val), ==, NM_SETTING_WIRELESS_SECURITY_SETTING_NAME); + sec_val = g_variant_lookup_value (wireless_dict, "security", NULL); + g_assert (g_variant_is_of_type (sec_val, G_VARIANT_TYPE_STRING)); + g_assert_cmpstr (g_variant_get_string (sec_val, NULL), ==, NM_SETTING_WIRELESS_SECURITY_SETTING_NAME); - g_hash_table_destroy (hash); + g_variant_unref (sec_val); + g_variant_unref (wireless_dict); + g_variant_unref (dict); g_object_unref (connection); } @@ -773,14 +788,14 @@ static void test_setting_new_from_dbus (void) { NMSettingWirelessSecurity *s_wsec; - GHashTable *hash; + GVariant *dict; - s_wsec = make_test_wsec_setting ("setting-to-dbus-all"); - hash = _nm_setting_to_dbus (NM_SETTING (s_wsec), NULL, NM_CONNECTION_SERIALIZE_ALL); + s_wsec = make_test_wsec_setting ("setting-new-from-dbus"); + dict = _nm_setting_to_dbus (NM_SETTING (s_wsec), NULL, NM_CONNECTION_SERIALIZE_ALL); g_object_unref (s_wsec); - s_wsec = (NMSettingWirelessSecurity *) _nm_setting_new_from_dbus (NM_TYPE_SETTING_WIRELESS_SECURITY, hash, NULL, NULL); - g_hash_table_destroy (hash); + s_wsec = (NMSettingWirelessSecurity *) _nm_setting_new_from_dbus (NM_TYPE_SETTING_WIRELESS_SECURITY, dict, NULL, NULL); + g_variant_unref (dict); g_assert (s_wsec); g_assert_cmpstr (nm_setting_wireless_security_get_key_mgmt (s_wsec), ==, "wpa-psk"); @@ -793,25 +808,27 @@ static void test_setting_new_from_dbus_transform (void) { NMSetting *s_wired; - GHashTable *hash; - GValue val = { 0, }; + GVariant *dict; + GVariantBuilder builder; const char *test_mac_address = "11:22:33:44:55:66"; - GByteArray *dbus_mac_address; + guint8 dbus_mac_address[ETH_ALEN]; GError *error = NULL; - hash = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, (GDestroyNotify) g_value_unset); + nm_utils_hwaddr_aton (test_mac_address, dbus_mac_address, ETH_ALEN); - dbus_mac_address = nm_utils_hwaddr_atoba (test_mac_address, ETH_ALEN); - g_value_init (&val, DBUS_TYPE_G_UCHAR_ARRAY); - g_value_take_boxed (&val, dbus_mac_address); - g_hash_table_insert (hash, NM_SETTING_WIRED_MAC_ADDRESS, &val); + g_variant_builder_init (&builder, NM_VARIANT_TYPE_SETTING); + g_variant_builder_add (&builder, "{sv}", + NM_SETTING_WIRED_MAC_ADDRESS, + g_variant_new_fixed_array (G_VARIANT_TYPE_BYTE, + dbus_mac_address, ETH_ALEN, 1)); + dict = g_variant_builder_end (&builder); - s_wired = _nm_setting_new_from_dbus (NM_TYPE_SETTING_WIRED, hash, NULL, &error); + s_wired = _nm_setting_new_from_dbus (NM_TYPE_SETTING_WIRED, dict, NULL, &error); g_assert_no_error (error); g_assert_cmpstr (nm_setting_wired_get_mac_address (NM_SETTING_WIRED (s_wired)), ==, test_mac_address); - g_hash_table_unref (hash); + g_variant_unref (dict); g_object_unref (s_wired); } @@ -852,73 +869,61 @@ new_test_connection (void) return connection; } -static GValue * -string_to_gvalue (const char *str) -{ - GValue *val; - - val = g_slice_new0 (GValue); - g_value_init (val, G_TYPE_STRING); - g_value_set_string (val, str); - return val; -} - -static void -destroy_gvalue (gpointer data) -{ - g_value_unset ((GValue *) data); - g_slice_free (GValue, data); -} - -static GHashTable * -new_connection_hash (char **out_uuid, +static GVariant * +new_connection_dict (char **out_uuid, const char **out_expected_id, const char **out_expected_ip6_method) { - GHashTable *hash; - GHashTable *setting; + GVariantBuilder conn_builder, setting_builder; - hash = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, (GDestroyNotify) g_hash_table_destroy); + g_variant_builder_init (&conn_builder, NM_VARIANT_TYPE_CONNECTION); *out_uuid = nm_utils_uuid_generate (); *out_expected_id = "My happy connection"; *out_expected_ip6_method = NM_SETTING_IP6_CONFIG_METHOD_LINK_LOCAL; /* Connection setting */ - setting = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, destroy_gvalue); - g_hash_table_insert (setting, - g_strdup (NM_SETTING_NAME), - string_to_gvalue (NM_SETTING_CONNECTION_SETTING_NAME)); - g_hash_table_insert (setting, - g_strdup (NM_SETTING_CONNECTION_ID), - string_to_gvalue (*out_expected_id)); - g_hash_table_insert (setting, - g_strdup (NM_SETTING_CONNECTION_UUID), - string_to_gvalue (*out_uuid)); - g_hash_table_insert (setting, - g_strdup (NM_SETTING_CONNECTION_TYPE), - string_to_gvalue (NM_SETTING_WIRED_SETTING_NAME)); - g_hash_table_insert (hash, g_strdup (NM_SETTING_CONNECTION_SETTING_NAME), setting); + g_variant_builder_init (&setting_builder, NM_VARIANT_TYPE_SETTING); + g_variant_builder_add (&setting_builder, "{sv}", + NM_SETTING_NAME, + g_variant_new_string (NM_SETTING_CONNECTION_SETTING_NAME)); + g_variant_builder_add (&setting_builder, "{sv}", + NM_SETTING_CONNECTION_ID, + g_variant_new_string (*out_expected_id)); + g_variant_builder_add (&setting_builder, "{sv}", + NM_SETTING_CONNECTION_UUID, + g_variant_new_string (*out_uuid)); + g_variant_builder_add (&setting_builder, "{sv}", + NM_SETTING_CONNECTION_TYPE, + g_variant_new_string (NM_SETTING_WIRED_SETTING_NAME)); + + g_variant_builder_add (&conn_builder, "{sa{sv}}", + NM_SETTING_CONNECTION_SETTING_NAME, + &setting_builder); /* Wired setting */ - setting = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, destroy_gvalue); - g_hash_table_insert (hash, g_strdup (NM_SETTING_WIRED_SETTING_NAME), setting); + g_variant_builder_init (&setting_builder, NM_VARIANT_TYPE_SETTING); + g_variant_builder_add (&conn_builder, "{sa{sv}}", + NM_SETTING_WIRED_SETTING_NAME, + &setting_builder); /* IP6 */ - setting = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, destroy_gvalue); - g_hash_table_insert (setting, - g_strdup (NM_SETTING_IP6_CONFIG_METHOD), - string_to_gvalue (*out_expected_ip6_method)); - g_hash_table_insert (hash, g_strdup (NM_SETTING_IP6_CONFIG_SETTING_NAME), setting); + g_variant_builder_init (&setting_builder, NM_VARIANT_TYPE_SETTING); + g_variant_builder_add (&setting_builder, "{sv}", + NM_SETTING_IP6_CONFIG_METHOD, + g_variant_new_string (*out_expected_ip6_method)); + g_variant_builder_add (&conn_builder, "{sa{sv}}", + NM_SETTING_IP6_CONFIG_SETTING_NAME, + &setting_builder); - return hash; + return g_variant_builder_end (&conn_builder); } static void test_connection_replace_settings () { NMConnection *connection; - GHashTable *new_settings; + GVariant *new_settings; GError *error = NULL; gboolean success; NMSettingConnection *s_con; @@ -928,7 +933,7 @@ test_connection_replace_settings () connection = new_test_connection (); - new_settings = new_connection_hash (&uuid, &expected_id, &expected_method); + new_settings = new_connection_dict (&uuid, &expected_id, &expected_method); g_assert (new_settings); /* Replace settings and test */ @@ -949,7 +954,7 @@ test_connection_replace_settings () g_assert_cmpstr (nm_setting_ip6_config_get_method (s_ip6), ==, expected_method); g_free (uuid); - g_hash_table_destroy (new_settings); + g_variant_unref (new_settings); g_object_unref (connection); } @@ -1014,7 +1019,8 @@ static void test_connection_replace_settings_bad (void) { NMConnection *connection, *new_connection; - GHashTable *new_settings, *setting_hash; + GVariant *new_settings; + GVariantBuilder builder, setting_builder; GError *error = NULL; gboolean success; NMSettingConnection *s_con; @@ -1047,10 +1053,15 @@ test_connection_replace_settings_bad (void) g_assert_cmpstr (nm_connection_get_id (connection), ==, "bad-connection"); g_assert (!nm_connection_verify (connection, NULL)); g_object_unref (connection); + g_variant_unref (new_settings); - /* But given an invalid hash, it should fail */ - setting_hash = g_hash_table_new (g_str_hash, g_str_equal); - g_hash_table_insert (new_settings, g_strdup ("ip-over-avian-carrier"), setting_hash); + /* But given an invalid dict, it should fail */ + g_variant_builder_init (&builder, NM_VARIANT_TYPE_CONNECTION); + g_variant_builder_init (&setting_builder, NM_VARIANT_TYPE_SETTING); + g_variant_builder_add (&builder, "{sa{sv}}", + "ip-over-avian-carrier", + &setting_builder); + new_settings = g_variant_builder_end (&builder); connection = new_test_connection (); success = nm_connection_replace_settings (connection, new_settings, &error); @@ -1060,7 +1071,7 @@ test_connection_replace_settings_bad (void) g_assert (nm_connection_verify (connection, NULL)); g_object_unref (connection); - g_hash_table_unref (new_settings); + g_variant_unref (new_settings); g_object_unref (new_connection); } @@ -1068,14 +1079,14 @@ static void test_connection_new_from_dbus () { NMConnection *connection; - GHashTable *new_settings; + GVariant *new_settings; GError *error = NULL; NMSettingConnection *s_con; NMSettingIP6Config *s_ip6; char *uuid = NULL; const char *expected_id = NULL, *expected_method = NULL; - new_settings = new_connection_hash (&uuid, &expected_id, &expected_method); + new_settings = new_connection_dict (&uuid, &expected_id, &expected_method); g_assert (new_settings); /* Replace settings and test */ @@ -1096,7 +1107,7 @@ test_connection_new_from_dbus () g_assert_cmpstr (nm_setting_ip6_config_get_method (s_ip6), ==, expected_method); g_free (uuid); - g_hash_table_destroy (new_settings); + g_variant_unref (new_settings); g_object_unref (connection); } @@ -2633,15 +2644,14 @@ test_setting_old_uuid (void) /* * Test normalization of interface-name - **/ + */ static void test_connection_normalize_virtual_iface_name (void) { NMConnection *con = NULL; NMSettingConnection *s_con; NMSettingVlan *s_vlan; - GHashTable *connection_hash, *setting_hash; - GValue *value; + GVariant *connection_dict, *setting_dict, *var; GError *error = NULL; const char *IFACE_NAME = "iface"; const char *IFACE_VIRT = "iface-X"; @@ -2671,27 +2681,41 @@ test_connection_normalize_virtual_iface_name (void) g_assert_cmpstr (nm_connection_get_interface_name (con), ==, IFACE_NAME); - connection_hash = nm_connection_to_dbus (con, NM_CONNECTION_SERIALIZE_ALL); + connection_dict = nm_connection_to_dbus (con, NM_CONNECTION_SERIALIZE_ALL); g_object_unref (con); /* Serialized form should include vlan.interface-name as well. */ - setting_hash = g_hash_table_lookup (connection_hash, NM_SETTING_VLAN_SETTING_NAME); - g_assert (setting_hash != NULL); - value = g_hash_table_lookup (setting_hash, "interface-name"); - g_assert (value != NULL); - g_assert (G_VALUE_HOLDS_STRING (value)); - g_assert_cmpstr (g_value_get_string (value), ==, IFACE_NAME); + setting_dict = g_variant_lookup_value (connection_dict, NM_SETTING_VLAN_SETTING_NAME, NM_VARIANT_TYPE_SETTING); + g_assert (setting_dict != NULL); + var = g_variant_lookup_value (setting_dict, "interface-name", NULL); + g_assert (var != NULL); + g_assert (g_variant_is_of_type (var, G_VARIANT_TYPE_STRING)); + g_assert_cmpstr (g_variant_get_string (var, NULL), ==, IFACE_NAME); + + g_variant_unref (setting_dict); + g_variant_unref (var); /* If vlan.interface-name is invalid, deserialization will fail. */ - g_value_set_string (value, ":::this-is-not-a-valid-interface-name:::"); - con = nm_simple_connection_new_from_dbus (connection_hash, &error); + NMTST_VARIANT_EDITOR (connection_dict, + NMTST_VARIANT_CHANGE_PROPERTY (NM_SETTING_VLAN_SETTING_NAME, + "interface-name", + "s", + ":::this-is-not-a-valid-interface-name:::"); + ); + + con = nm_simple_connection_new_from_dbus (connection_dict, &error); g_assert_error (error, NM_SETTING_CONNECTION_ERROR, NM_SETTING_CONNECTION_ERROR_INVALID_PROPERTY); g_clear_error (&error); /* If vlan.interface-name is valid, but doesn't match, it will be ignored. */ - g_value_set_string (value, IFACE_VIRT); + NMTST_VARIANT_EDITOR (connection_dict, + NMTST_VARIANT_CHANGE_PROPERTY (NM_SETTING_VLAN_SETTING_NAME, + "interface-name", + "s", + IFACE_VIRT); + ); - con = nm_simple_connection_new_from_dbus (connection_hash, &error); + con = nm_simple_connection_new_from_dbus (connection_dict, &error); g_assert_no_error (error); g_assert_cmpstr (nm_connection_get_interface_name (con), ==, IFACE_NAME); @@ -2702,11 +2726,12 @@ test_connection_normalize_virtual_iface_name (void) /* But removing connection.interface-name should result in vlan.connection-name * being "promoted". */ - setting_hash = g_hash_table_lookup (connection_hash, NM_SETTING_CONNECTION_SETTING_NAME); - g_assert (setting_hash != NULL); - g_hash_table_remove (setting_hash, NM_SETTING_CONNECTION_INTERFACE_NAME); + NMTST_VARIANT_EDITOR (connection_dict, + NMTST_VARIANT_DROP_PROPERTY (NM_SETTING_CONNECTION_SETTING_NAME, + NM_SETTING_CONNECTION_INTERFACE_NAME); + ); - con = nm_simple_connection_new_from_dbus (connection_hash, &error); + con = nm_simple_connection_new_from_dbus (connection_dict, &error); g_assert_no_error (error); g_assert_cmpstr (nm_connection_get_interface_name (con), ==, IFACE_VIRT); @@ -2714,7 +2739,7 @@ test_connection_normalize_virtual_iface_name (void) g_assert_cmpstr (nm_setting_connection_get_interface_name (s_con), ==, IFACE_VIRT); g_object_unref (con); - g_hash_table_unref (connection_hash); + g_variant_unref (connection_dict); } static void diff --git a/libnm-core/tests/test-secrets.c b/libnm-core/tests/test-secrets.c index 22aa460ebc..738441ad47 100644 --- a/libnm-core/tests/test-secrets.c +++ b/libnm-core/tests/test-secrets.c @@ -22,8 +22,6 @@ #include #include -#include - #include "nm-setting-connection.h" #include "nm-setting-wired.h" #include "nm-setting-8021x.h" @@ -35,6 +33,7 @@ #include "nm-setting-ppp.h" #include "nm-setting-pppoe.h" #include "nm-setting-vpn.h" +#include "nm-utils.h" #include "nm-test-utils.h" @@ -441,34 +440,20 @@ wifi_connection_new (void) return connection; } -static void -value_destroy (gpointer data) +static GVariant * +build_wep_secrets (const char *wepkey) { - GValue *value = (GValue *) data; + GVariantBuilder builder; - g_value_unset (value); - g_slice_free (GValue, value); -} + g_variant_builder_init (&builder, G_VARIANT_TYPE ("a{sv}")); + g_variant_builder_add (&builder, "{sv}", + NM_SETTING_WIRELESS_SECURITY_WEP_KEY0, + g_variant_new_string (wepkey)); + g_variant_builder_add (&builder, "{sv}", + NM_SETTING_WIRELESS_SECURITY_WEP_KEY_TYPE, + g_variant_new_uint32 (NM_WEP_KEY_TYPE_KEY)); -static GValue * -string_to_gvalue (const char *str) -{ - GValue *val = g_slice_new0 (GValue); - - g_value_init (val, G_TYPE_STRING); - g_value_set_string (val, str); - return val; -} - -static GValue * -uint_to_gvalue (guint32 i) -{ - GValue *val; - - val = g_slice_new0 (GValue); - g_value_init (val, G_TYPE_UINT); - g_value_set_uint (val, i); - return val; + return g_variant_builder_end (&builder); } static void @@ -476,7 +461,7 @@ test_update_secrets_wifi_single_setting (void) { NMConnection *connection; NMSettingWirelessSecurity *s_wsec; - GHashTable *secrets; + GVariant *secrets; GError *error = NULL; gboolean success; const char *wepkey = "11111111111111111111111111"; @@ -486,11 +471,7 @@ test_update_secrets_wifi_single_setting (void) connection = wifi_connection_new (); - /* Build up the secrets hash */ - secrets = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, value_destroy); - g_hash_table_insert (secrets, NM_SETTING_WIRELESS_SECURITY_WEP_KEY0, string_to_gvalue (wepkey)); - g_hash_table_insert (secrets, NM_SETTING_WIRELESS_SECURITY_WEP_KEY_TYPE, uint_to_gvalue (NM_WEP_KEY_TYPE_KEY)); - + secrets = build_wep_secrets (wepkey); success = nm_connection_update_secrets (connection, NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, secrets, @@ -498,6 +479,8 @@ test_update_secrets_wifi_single_setting (void) g_assert_no_error (error); g_assert (success); + g_variant_unref (secrets); + /* Make sure the secret is now in the connection */ s_wsec = nm_connection_get_setting_wireless_security (connection); g_assert (s_wsec); @@ -512,7 +495,8 @@ test_update_secrets_wifi_full_hash (void) { NMConnection *connection; NMSettingWirelessSecurity *s_wsec; - GHashTable *secrets, *all; + GVariantBuilder builder; + GVariant *all; GError *error = NULL; gboolean success; const char *wepkey = "11111111111111111111111111"; @@ -524,12 +508,11 @@ test_update_secrets_wifi_full_hash (void) connection = wifi_connection_new (); - /* Build up the secrets hash */ - all = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, (GDestroyNotify) g_hash_table_destroy); - secrets = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, value_destroy); - g_hash_table_insert (secrets, NM_SETTING_WIRELESS_SECURITY_WEP_KEY0, string_to_gvalue (wepkey)); - g_hash_table_insert (secrets, NM_SETTING_WIRELESS_SECURITY_WEP_KEY_TYPE, uint_to_gvalue (NM_WEP_KEY_TYPE_KEY)); - g_hash_table_insert (all, NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, secrets); + g_variant_builder_init (&builder, NM_VARIANT_TYPE_CONNECTION); + g_variant_builder_add (&builder, "{s@a{sv}}", + NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, + build_wep_secrets (wepkey)); + all = g_variant_builder_end (&builder); success = nm_connection_update_secrets (connection, NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, @@ -538,6 +521,8 @@ test_update_secrets_wifi_full_hash (void) g_assert_no_error (error); g_assert (success); + g_variant_unref (all); + /* Make sure the secret is now in the connection */ s_wsec = nm_connection_get_setting_wireless_security (connection); g_assert (s_wsec); @@ -551,7 +536,7 @@ static void test_update_secrets_wifi_bad_setting_name (void) { NMConnection *connection; - GHashTable *secrets; + GVariant *secrets; GError *error = NULL; gboolean success; const char *wepkey = "11111111111111111111111111"; @@ -562,10 +547,7 @@ test_update_secrets_wifi_bad_setting_name (void) connection = wifi_connection_new (); - /* Build up the secrets hash */ - secrets = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, value_destroy); - g_hash_table_insert (secrets, NM_SETTING_WIRELESS_SECURITY_WEP_KEY0, string_to_gvalue (wepkey)); - g_hash_table_insert (secrets, NM_SETTING_WIRELESS_SECURITY_WEP_KEY_TYPE, uint_to_gvalue (NM_WEP_KEY_TYPE_KEY)); + secrets = build_wep_secrets (wepkey); success = nm_connection_update_secrets (connection, "asdfasdfasdfasf", @@ -574,6 +556,8 @@ test_update_secrets_wifi_bad_setting_name (void) g_assert_error (error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_SETTING_NOT_FOUND); g_assert (success == FALSE); + g_variant_unref (secrets); + g_object_unref (connection); } @@ -582,7 +566,7 @@ test_update_secrets_whole_connection (void) { NMConnection *connection; NMSettingWirelessSecurity *s_wsec; - GHashTable *secrets, *wsec_hash; + GVariant *secrets; GError *error = NULL; gboolean success; const char *wepkey = "11111111111111111111111111"; @@ -593,16 +577,21 @@ test_update_secrets_whole_connection (void) connection = wifi_connection_new (); - /* Build up the secrets hash */ + /* Build up the secrets dictionary */ secrets = nm_connection_to_dbus (connection, NM_CONNECTION_SERIALIZE_ALL); - wsec_hash = g_hash_table_lookup (secrets, NM_SETTING_WIRELESS_SECURITY_SETTING_NAME); - g_assert (wsec_hash); - g_hash_table_insert (wsec_hash, NM_SETTING_WIRELESS_SECURITY_WEP_KEY0, string_to_gvalue (wepkey)); + NMTST_VARIANT_EDITOR (secrets, + NMTST_VARIANT_ADD_PROPERTY (NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, + NM_SETTING_WIRELESS_SECURITY_WEP_KEY0, + "s", + wepkey); + ); success = nm_connection_update_secrets (connection, NULL, secrets, &error); g_assert_no_error (error); g_assert (success == TRUE); + g_variant_unref (secrets); + s_wsec = nm_connection_get_setting_wireless_security (connection); g_assert (s_wsec); g_assert_cmpstr (nm_setting_wireless_security_get_wep_key (s_wsec, 0), ==, wepkey); @@ -614,17 +603,18 @@ static void test_update_secrets_whole_connection_empty_hash (void) { NMConnection *connection; - GHashTable *secrets; + GVariant *secrets; GError *error = NULL; gboolean success; /* Test that updating secrets with an empty hash returns success */ connection = wifi_connection_new (); - secrets = g_hash_table_new (g_str_hash, g_str_equal); + secrets = g_variant_new_array (G_VARIANT_TYPE ("{sv}"), NULL, 0); success = nm_connection_update_secrets (connection, NULL, secrets, &error); g_assert_no_error (error); g_assert (success == TRUE); + g_variant_unref (secrets); g_object_unref (connection); } @@ -632,7 +622,11 @@ static void test_update_secrets_whole_connection_bad_setting (void) { NMConnection *connection; - GHashTable *secrets, *wsec_hash; + NMSettingWirelessSecurity *s_wsec; + GVariant *secrets, *copy, *setting_hash; + const char *setting_name; + GVariantBuilder conn_builder; + GVariantIter conn_iter; GError *error = NULL; gboolean success; const char *wepkey = "11111111111111111111111111"; @@ -642,25 +636,36 @@ test_update_secrets_whole_connection_bad_setting (void) */ connection = wifi_connection_new (); + s_wsec = nm_connection_get_setting_wireless_security (connection); + g_assert (s_wsec != NULL); + g_object_set (G_OBJECT (s_wsec), + NM_SETTING_WIRELESS_SECURITY_WEP_KEY0, wepkey, + NULL); /* Build up the secrets hash */ secrets = nm_connection_to_dbus (connection, NM_CONNECTION_SERIALIZE_ALL); - wsec_hash = g_hash_table_lookup (secrets, NM_SETTING_WIRELESS_SECURITY_SETTING_NAME); - g_assert (wsec_hash); - g_hash_table_insert (wsec_hash, NM_SETTING_WIRELESS_SECURITY_WEP_KEY0, string_to_gvalue (wepkey)); - /* Steal the wsec setting hash so it's not deallocated, and stuff it back - * in with a different name so we ensure libnm is returning the right - * error when it finds an entry in the connection hash that doesn't match - * any setting in the connection. + /* Copy the dict, renaming the wireless-security setting in the process + * (so we ensure libnm is returning the right error when it finds an entry + * in the connection hash that doesn't match any setting in the connection). */ - g_hash_table_steal (secrets, NM_SETTING_WIRELESS_SECURITY_SETTING_NAME); - g_hash_table_insert (secrets, "asdfasdfasdfasdf", wsec_hash); + g_variant_builder_init (&conn_builder, NM_VARIANT_TYPE_CONNECTION); + g_variant_iter_init (&conn_iter, secrets); + while (g_variant_iter_next (&conn_iter, "{&s@a{sv}}", &setting_name, &setting_hash)) { + if (strcmp (setting_name, NM_SETTING_WIRELESS_SECURITY_SETTING_NAME) == 0) + setting_name = "asdfasdfasdfasdf"; - success = nm_connection_update_secrets (connection, NULL, secrets, &error); + g_variant_builder_add (&conn_builder, "{s@a{sv}}", setting_name, setting_hash); + g_variant_unref (setting_hash); + } + copy = g_variant_builder_end (&conn_builder); + g_variant_unref (secrets); + + success = nm_connection_update_secrets (connection, NULL, copy, &error); g_assert_error (error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_SETTING_NOT_FOUND); g_assert (success == FALSE); + g_variant_unref (copy); g_object_unref (connection); } @@ -668,7 +673,7 @@ static void test_update_secrets_whole_connection_empty_base_setting (void) { NMConnection *connection; - GHashTable *secrets; + GVariant *secrets, *setting; GError *error = NULL; gboolean success; @@ -678,8 +683,11 @@ test_update_secrets_whole_connection_empty_base_setting (void) connection = wifi_connection_new (); secrets = nm_connection_to_dbus (connection, NM_CONNECTION_SERIALIZE_ONLY_SECRETS); - g_assert_cmpint (g_hash_table_size (secrets), ==, 3); - g_assert (g_hash_table_lookup (secrets, NM_SETTING_WIRELESS_SETTING_NAME)); + g_assert_cmpint (g_variant_n_children (secrets), ==, 3); + + setting = g_variant_lookup_value (secrets, NM_SETTING_WIRELESS_SETTING_NAME, NULL); + g_assert (setting != NULL); + g_variant_unref (setting); success = nm_connection_update_secrets (connection, NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, @@ -688,7 +696,7 @@ test_update_secrets_whole_connection_empty_base_setting (void) g_assert_no_error (error); g_assert (success); - g_hash_table_destroy (secrets); + g_variant_unref (secrets); g_object_unref (connection); } @@ -696,7 +704,7 @@ static void test_update_secrets_null_setting_name_with_setting_hash (void) { NMConnection *connection; - GHashTable *secrets; + GVariant *secrets; GError *error = NULL; gboolean success; const char *wepkey = "11111111111111111111111111"; @@ -705,15 +713,13 @@ test_update_secrets_null_setting_name_with_setting_hash (void) connection = wifi_connection_new (); - secrets = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, value_destroy); - g_hash_table_insert (secrets, NM_SETTING_WIRELESS_SECURITY_WEP_KEY0, string_to_gvalue (wepkey)); - g_hash_table_insert (secrets, NM_SETTING_WIRELESS_SECURITY_WEP_KEY_TYPE, uint_to_gvalue (NM_WEP_KEY_TYPE_KEY)); + secrets = build_wep_secrets (wepkey); success = nm_connection_update_secrets (connection, NULL, secrets, &error); g_assert_error (error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_SETTING_NOT_FOUND); g_assert (!success); - g_hash_table_destroy (secrets); + g_variant_unref (secrets); g_object_unref (connection); } diff --git a/libnm/Makefile.am b/libnm/Makefile.am index e703f376bc..b15db447d7 100644 --- a/libnm/Makefile.am +++ b/libnm/Makefile.am @@ -4,13 +4,17 @@ SUBDIRS = . tests AM_CPPFLAGS = \ -I$(top_srcdir)/include \ + -I$(top_builddir)/introspection \ -I$(top_srcdir)/libnm-core \ -I$(top_builddir)/libnm-core \ -I$(top_srcdir)/libnm \ -I$(top_builddir)/libnm \ -DG_LOG_DOMAIN=\""libnm"\" \ -DNETWORKMANAGER_COMPILATION \ - -DNM_VERSION_MAX_ALLOWED=NM_VERSION_NEXT_STABLE + -DNM_VERSION_MAX_ALLOWED=NM_VERSION_NEXT_STABLE \ + $(GLIB_CFLAGS) \ + $(GUDEV_CFLAGS) \ + -DNMRUNDIR=\"$(nmrundir)\" include $(top_srcdir)/libnm-core/Makefile.libnm-core @@ -18,12 +22,6 @@ include $(top_srcdir)/libnm-core/Makefile.libnm-core lib_LTLIBRARIES = libnm.la -libnm_la_CFLAGS = \ - $(GLIB_CFLAGS) \ - $(DBUS_CFLAGS) \ - $(GUDEV_CFLAGS) \ - -DNMRUNDIR=\"$(nmrundir)\" - libnmincludedir = $(includedir)/libnm libnminclude_HEADERS = \ @@ -55,10 +53,13 @@ libnminclude_HEADERS = \ nm-remote-settings.h \ nm-secret-agent.h \ nm-vpn-connection.h \ + nm-vpn-plugin.h \ + nm-vpn-plugin-ui-interface.h \ + nm-vpn-plugin-utils.h \ nm-wimax-nsp.h libnm_la_private_headers = \ - nm-dbus-helpers-private.h \ + nm-dbus-helpers.h \ nm-device-private.h \ nm-object-cache.h \ nm-object-private.h \ @@ -94,28 +95,24 @@ libnm_la_csources = \ nm-remote-settings.c \ nm-secret-agent.c \ nm-vpn-connection.c \ + nm-vpn-plugin.c \ + nm-vpn-plugin-ui-interface.c \ + nm-vpn-plugin-utils.c \ nm-wimax-nsp.c libnm_la_SOURCES = \ $(libnm_la_csources) \ $(libnm_la_private_headers) -nm-secret-agent-glue.h: $(top_srcdir)/introspection/nm-secret-agent.xml - $(AM_V_GEN) dbus-binding-tool --prefix=nm_secret_agent --mode=glib-server --output=$@ $< - GLIB_GENERATED = nm-enum-types.h nm-enum-types.c nm_enum_types_sources = $(libnminclude_HEADERS) GLIB_MKENUMS_H_FLAGS = --identifier-prefix NM --fhead '\#include \n' GLIB_MKENUMS_C_FLAGS = --identifier-prefix NM -BUILT_SOURCES = \ - nm-vpn-plugin-glue.h \ - nm-secret-agent-glue.h - libnm_la_LIBADD = \ $(top_builddir)/libnm-core/libnm-core.la \ + $(top_builddir)/introspection/libnmdbus.la \ $(GLIB_LIBS) \ - $(DBUS_LIBS) \ $(UUID_LIBS) \ $(GUDEV_LIBS) @@ -124,45 +121,16 @@ SYMBOL_VIS_FILE=$(srcdir)/libnm.ver libnm_la_LDFLAGS = -Wl,--version-script=$(SYMBOL_VIS_FILE) \ -version-info "0:0:0" - -# libnm-vpn - -lib_LTLIBRARIES += libnm-vpn.la - -libnmvpndir = $(includedir)/libnm - -libnmvpn_HEADERS = \ - nm-vpn-plugin.h \ - nm-vpn-plugin-ui-interface.h \ - nm-vpn-plugin-utils.h \ - nm-vpn-enum-types.h - -libnm_vpn_la_SOURCES = \ - nm-vpn-plugin.c \ - nm-vpn-plugin-ui-interface.c \ - nm-vpn-plugin-utils.c \ - nm-vpn-enum-types.c - -nm-vpn-plugin-glue.h: $(top_srcdir)/introspection/nm-vpn-plugin.xml - $(AM_V_GEN) dbus-binding-tool --prefix=nm_vpn_plugin --mode=glib-server --output=$@ $< - -GLIB_GENERATED += nm-vpn-enum-types.h nm-vpn-enum-types.c -nm_vpn_enum_types_sources = $(libnmvpn_HEADERS) -libnm_vpn_la_CFLAGS = $(GLIB_CFLAGS) $(DBUS_CFLAGS) -libnm_vpn_la_LIBADD = $(GLIB_LIBS) $(DBUS_LIBS) -libnm_vpn_la_LDFLAGS = -Wl,--version-script=$(srcdir)/libnm-vpn.ver \ - -version-info "0:0:0" - ### -BUILT_SOURCES += $(GLIB_GENERATED) +BUILT_SOURCES = $(GLIB_GENERATED) pkgconfigdir = $(libdir)/pkgconfig -pkgconfig_DATA = libnm.pc libnm-vpn.pc +pkgconfig_DATA = libnm.pc -DISTCLEANFILES = libnm.pc libnm-vpn.pc +DISTCLEANFILES = libnm.pc -EXTRA_DIST = libnm.pc.in libnm-vpn.pc.in libnm.ver libnm-vpn.ver +EXTRA_DIST = libnm.pc.in libnm.ver CLEANFILES = $(BUILT_SOURCES) @@ -182,8 +150,8 @@ introspection_sources = \ $(libnm_la_csources) NM-1.0.gir: libnm.la -NM_1_0_gir_INCLUDES = Gio-2.0 DBusGLib-1.0 -NM_1_0_gir_PACKAGES = gio-2.0 dbus-glib-1 gudev-1.0 +NM_1_0_gir_INCLUDES = Gio-2.0 +NM_1_0_gir_PACKAGES = gio-2.0 gudev-1.0 NM_1_0_gir_EXPORT_PACKAGES = libnm NM_1_0_gir_CFLAGS = $(AM_CPPFLAGS) NM_1_0_gir_LIBS = libnm.la diff --git a/libnm/libnm-vpn.pc.in b/libnm/libnm-vpn.pc.in deleted file mode 100644 index ef847d5d34..0000000000 --- a/libnm/libnm-vpn.pc.in +++ /dev/null @@ -1,13 +0,0 @@ -prefix=@prefix@ -exec_prefix=@exec_prefix@ -libdir=@libdir@ -includedir=@includedir@ - -Name: libnm-vpn -Description: Convenience library for NetworkManager VPN plugins -Version: @VERSION@ -Requires: libnm >= @VERSION@ gio-2.0 dbus-glib-1 -Cflags: -I${includedir}/libnm -Libs: -L${libdir} -lnm-vpn - - diff --git a/libnm/libnm-vpn.ver b/libnm/libnm-vpn.ver deleted file mode 100644 index f782d12bb6..0000000000 --- a/libnm/libnm-vpn.ver +++ /dev/null @@ -1,31 +0,0 @@ -{ -global: - nm_vpn_plugin_disconnect; - nm_vpn_plugin_error_get_type; - nm_vpn_plugin_error_quark; - nm_vpn_plugin_failure; - nm_vpn_plugin_get_connection; - nm_vpn_plugin_get_state; - nm_vpn_plugin_get_type; - nm_vpn_plugin_secrets_required; - nm_vpn_plugin_set_ip4_config; - nm_vpn_plugin_set_login_banner; - nm_vpn_plugin_set_state; - nm_vpn_plugin_ui_capability_get_type; - nm_vpn_plugin_ui_interface_delete_connection; - nm_vpn_plugin_ui_interface_export; - nm_vpn_plugin_ui_interface_get_capabilities; - nm_vpn_plugin_ui_interface_get_suggested_name; - nm_vpn_plugin_ui_interface_get_type; - nm_vpn_plugin_ui_interface_import; - nm_vpn_plugin_ui_interface_prop_get_type; - nm_vpn_plugin_ui_interface_ui_factory; - nm_vpn_plugin_ui_widget_interface_get_type; - nm_vpn_plugin_ui_widget_interface_get_widget; - nm_vpn_plugin_ui_widget_interface_save_secrets; - nm_vpn_plugin_ui_widget_interface_update_connection; - nm_vpn_plugin_utils_get_secret_flags; - nm_vpn_plugin_utils_read_vpn_details; -local: - *; -}; diff --git a/libnm/libnm.ver b/libnm/libnm.ver index d48731c474..c9329cc51a 100644 --- a/libnm/libnm.ver +++ b/libnm/libnm.ver @@ -866,7 +866,6 @@ global: nm_utils_deinit; nm_utils_escape_ssid; nm_utils_file_is_pkcs12; - nm_utils_gvalue_hash_dup; nm_utils_hex2byte; nm_utils_hexstr2bin; nm_utils_hwaddr_atoba; @@ -879,30 +878,20 @@ global: nm_utils_inet4_ntop; nm_utils_inet6_ntop; nm_utils_init; - nm_utils_ip4_addresses_from_gvalue; nm_utils_ip4_addresses_from_variant; - nm_utils_ip4_addresses_to_gvalue; nm_utils_ip4_addresses_to_variant; nm_utils_ip4_dns_from_variant; nm_utils_ip4_dns_to_variant; nm_utils_ip4_get_default_prefix; nm_utils_ip4_netmask_to_prefix; nm_utils_ip4_prefix_to_netmask; - nm_utils_ip4_routes_from_gvalue; nm_utils_ip4_routes_from_variant; - nm_utils_ip4_routes_to_gvalue; nm_utils_ip4_routes_to_variant; - nm_utils_ip6_addresses_from_gvalue; nm_utils_ip6_addresses_from_variant; - nm_utils_ip6_addresses_to_gvalue; nm_utils_ip6_addresses_to_variant; - nm_utils_ip6_dns_from_gvalue; nm_utils_ip6_dns_from_variant; - nm_utils_ip6_dns_to_gvalue; nm_utils_ip6_dns_to_variant; - nm_utils_ip6_routes_from_gvalue; nm_utils_ip6_routes_from_variant; - nm_utils_ip6_routes_to_gvalue; nm_utils_ip6_routes_to_variant; nm_utils_is_empty_ssid; nm_utils_is_uuid; @@ -927,7 +916,31 @@ global: nm_vpn_connection_get_vpn_state; nm_vpn_connection_state_get_type; nm_vpn_connection_state_reason_get_type; + nm_vpn_plugin_disconnect; + nm_vpn_plugin_error_get_type; + nm_vpn_plugin_error_quark; + nm_vpn_plugin_failure; nm_vpn_plugin_failure_get_type; + nm_vpn_plugin_get_connection; + nm_vpn_plugin_get_state; + nm_vpn_plugin_get_type; + nm_vpn_plugin_secrets_required; + nm_vpn_plugin_set_ip4_config; + nm_vpn_plugin_set_login_banner; + nm_vpn_plugin_set_state; + nm_vpn_plugin_ui_capability_get_type; + nm_vpn_plugin_ui_interface_export; + nm_vpn_plugin_ui_interface_get_capabilities; + nm_vpn_plugin_ui_interface_get_suggested_name; + nm_vpn_plugin_ui_interface_get_type; + nm_vpn_plugin_ui_interface_import; + nm_vpn_plugin_ui_interface_prop_get_type; + nm_vpn_plugin_ui_interface_ui_factory; + nm_vpn_plugin_ui_widget_interface_get_type; + nm_vpn_plugin_ui_widget_interface_get_widget; + nm_vpn_plugin_ui_widget_interface_update_connection; + nm_vpn_plugin_utils_get_secret_flags; + nm_vpn_plugin_utils_read_vpn_details; nm_vpn_service_state_get_type; nm_wep_key_type_get_type; nm_wimax_nsp_connection_valid; diff --git a/libnm/nm-access-point.c b/libnm/nm-access-point.c index d0695f9197..fc36c0faa8 100644 --- a/libnm/nm-access-point.c +++ b/libnm/nm-access-point.c @@ -39,8 +39,6 @@ G_DEFINE_TYPE (NMAccessPoint, nm_access_point, NM_TYPE_OBJECT) #define NM_ACCESS_POINT_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_ACCESS_POINT, NMAccessPointPrivate)) typedef struct { - DBusGProxy *proxy; - NM80211ApFlags flags; NM80211ApSecurityFlags wpa_flags; NM80211ApSecurityFlags rsn_flags; @@ -361,16 +359,6 @@ nm_access_point_init (NMAccessPoint *ap) { } -static void -dispose (GObject *object) -{ - NMAccessPointPrivate *priv = NM_ACCESS_POINT_GET_PRIVATE (object); - - g_clear_object (&priv->proxy); - - G_OBJECT_CLASS (nm_access_point_parent_class)->dispose (object); -} - static void finalize (GObject *object) { @@ -449,9 +437,8 @@ init_dbus (NMObject *object) NM_OBJECT_CLASS (nm_access_point_parent_class)->init_dbus (object); - priv->proxy = _nm_object_new_proxy (object, NULL, NM_DBUS_INTERFACE_ACCESS_POINT); _nm_object_register_properties (object, - priv->proxy, + NM_DBUS_INTERFACE_ACCESS_POINT, property_info); } @@ -464,9 +451,10 @@ nm_access_point_class_init (NMAccessPointClass *ap_class) g_type_class_add_private (ap_class, sizeof (NMAccessPointPrivate)); + _nm_object_class_add_interface (nm_object_class, NM_DBUS_INTERFACE_ACCESS_POINT); + /* virtual methods */ object_class->get_property = get_property; - object_class->dispose = dispose; object_class->finalize = finalize; nm_object_class->init_dbus = init_dbus; diff --git a/libnm/nm-active-connection.c b/libnm/nm-active-connection.c index 7088e496a4..e2fcbb0a0a 100644 --- a/libnm/nm-active-connection.c +++ b/libnm/nm-active-connection.c @@ -30,26 +30,20 @@ #include "nm-connection.h" #include "nm-vpn-connection.h" #include "nm-glib-compat.h" -#include "nm-dbus-helpers-private.h" +#include "nm-dbus-helpers.h" -static GType _nm_active_connection_type_for_path (DBusGConnection *connection, - const char *path); -static void _nm_active_connection_type_for_path_async (DBusGConnection *connection, - const char *path, - NMObjectTypeCallbackFunc callback, - gpointer user_data); +static GType _nm_active_connection_decide_type (GVariant *value); G_DEFINE_TYPE_WITH_CODE (NMActiveConnection, nm_active_connection, NM_TYPE_OBJECT, _nm_object_register_type_func (g_define_type_id, - _nm_active_connection_type_for_path, - _nm_active_connection_type_for_path_async); + _nm_active_connection_decide_type, + NM_DBUS_INTERFACE_ACTIVE_CONNECTION, + "Vpn"); ) #define NM_ACTIVE_CONNECTION_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_ACTIVE_CONNECTION, NMActiveConnectionPrivate)) typedef struct { - DBusGProxy *proxy; - char *connection; char *id; char *uuid; @@ -89,97 +83,13 @@ enum { }; static GType -_nm_active_connection_type_for_path (DBusGConnection *connection, - const char *path) +_nm_active_connection_decide_type (GVariant *value) { - DBusGProxy *proxy; - GError *error = NULL; - GValue value = G_VALUE_INIT; - GType type; - - proxy = _nm_dbus_new_proxy_for_connection (connection, path, "org.freedesktop.DBus.Properties"); - if (!proxy) { - g_warning ("%s: couldn't create D-Bus object proxy.", __func__); - return G_TYPE_INVALID; - } - - /* Have to create an NMVpnConnection if it's a VPN connection, otherwise - * a plain NMActiveConnection. - */ - if (dbus_g_proxy_call (proxy, - "Get", &error, - G_TYPE_STRING, NM_DBUS_INTERFACE_ACTIVE_CONNECTION, - G_TYPE_STRING, "Vpn", - G_TYPE_INVALID, - G_TYPE_VALUE, &value, G_TYPE_INVALID)) { - if (g_value_get_boolean (&value)) - type = NM_TYPE_VPN_CONNECTION; - else - type = NM_TYPE_ACTIVE_CONNECTION; - } else { - g_warning ("Error in getting active connection 'Vpn' property: (%d) %s", - error->code, error->message); - g_error_free (error); - type = G_TYPE_INVALID; - } - - g_object_unref (proxy); - return type; -} - -typedef struct { - DBusGConnection *connection; - NMObjectTypeCallbackFunc callback; - gpointer user_data; -} NMActiveConnectionAsyncData; - -static void -async_got_type (DBusGProxy *proxy, DBusGProxyCall *call, gpointer user_data) -{ - NMActiveConnectionAsyncData *async_data = user_data; - GValue value = G_VALUE_INIT; - const char *path = dbus_g_proxy_get_path (proxy); - GError *error = NULL; - GType type; - - if (dbus_g_proxy_end_call (proxy, call, &error, - G_TYPE_VALUE, &value, - G_TYPE_INVALID)) { - if (g_value_get_boolean (&value)) - type = NM_TYPE_VPN_CONNECTION; - else - type = NM_TYPE_ACTIVE_CONNECTION; - } else { - g_warning ("%s: could not read properties for %s: %s", __func__, path, error->message); - type = G_TYPE_INVALID; - } - - async_data->callback (type, async_data->user_data); - - g_object_unref (proxy); - g_slice_free (NMActiveConnectionAsyncData, async_data); -} - -static void -_nm_active_connection_type_for_path_async (DBusGConnection *connection, - const char *path, - NMObjectTypeCallbackFunc callback, - gpointer user_data) -{ - NMActiveConnectionAsyncData *async_data; - DBusGProxy *proxy; - - async_data = g_slice_new (NMActiveConnectionAsyncData); - async_data->connection = connection; - async_data->callback = callback; - async_data->user_data = user_data; - - proxy = _nm_dbus_new_proxy_for_connection (connection, path, "org.freedesktop.DBus.Properties"); - dbus_g_proxy_begin_call (proxy, "Get", - async_got_type, async_data, NULL, - G_TYPE_STRING, NM_DBUS_INTERFACE_ACTIVE_CONNECTION, - G_TYPE_STRING, "Vpn", - G_TYPE_INVALID); + /* @value is the value of the o.fd.NM.ActiveConnection property "VPN" */ + if (g_variant_get_boolean (value)) + return NM_TYPE_VPN_CONNECTION; + else + return NM_TYPE_ACTIVE_CONNECTION; } /** @@ -461,8 +371,6 @@ dispose (GObject *object) g_clear_object (&priv->ip6_config); g_clear_object (&priv->dhcp6_config); - g_clear_object (&priv->proxy); - G_OBJECT_CLASS (nm_active_connection_parent_class)->dispose (object); } @@ -567,9 +475,8 @@ init_dbus (NMObject *object) NM_OBJECT_CLASS (nm_active_connection_parent_class)->init_dbus (object); - priv->proxy = _nm_object_new_proxy (object, NULL, NM_DBUS_INTERFACE_ACTIVE_CONNECTION); _nm_object_register_properties (object, - priv->proxy, + NM_DBUS_INTERFACE_ACTIVE_CONNECTION, property_info); } @@ -582,6 +489,8 @@ nm_active_connection_class_init (NMActiveConnectionClass *ap_class) g_type_class_add_private (ap_class, sizeof (NMActiveConnectionPrivate)); + _nm_object_class_add_interface (nm_object_class, NM_DBUS_INTERFACE_ACTIVE_CONNECTION); + /* virtual methods */ object_class->get_property = get_property; object_class->dispose = dispose; diff --git a/libnm/nm-client.c b/libnm/nm-client.c index 70c9c813ab..54eacab12f 100644 --- a/libnm/nm-client.c +++ b/libnm/nm-client.c @@ -19,7 +19,6 @@ * Copyright 2007 - 2013 Red Hat, Inc. */ -#include #include #include @@ -32,8 +31,10 @@ #include "nm-active-connection.h" #include "nm-vpn-connection.h" #include "nm-object-cache.h" -#include "nm-dbus-glib-types.h" #include "nm-glib-compat.h" +#include "nm-dbus-helpers.h" + +#include "nmdbus-manager.h" void _nm_device_wifi_set_wireless_enabled (NMDeviceWifi *device, gboolean enabled); @@ -50,7 +51,7 @@ G_DEFINE_TYPE_WITH_CODE (NMClient, nm_client, NM_TYPE_OBJECT, #define NM_CLIENT_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_CLIENT, NMClientPrivate)) typedef struct { - DBusGProxy *client_proxy; + NMDBusManager *manager_proxy; char *version; NMState state; gboolean startup; @@ -60,7 +61,7 @@ typedef struct { NMActiveConnection *primary_connection; NMActiveConnection *activating_connection; - DBusGProxyCall *perm_call; + GCancellable *perm_call_cancellable; GHashTable *permissions; /* Activations waiting for their NMActiveConnection @@ -166,7 +167,7 @@ wireless_enabled_cb (GObject *object, GParamSpec *pspec, gpointer user_data) poke_wireless_devices_with_rf_status (NM_CLIENT (object)); } -static void client_recheck_permissions (DBusGProxy *proxy, gpointer user_data); +static void client_recheck_permissions (NMDBusManager *proxy, gpointer user_data); static void active_connections_changed_cb (GObject *object, GParamSpec *pspec, gpointer user_data); static void object_creation_failed_cb (GObject *object, GError *error, char *failed_path); @@ -195,18 +196,14 @@ init_dbus (NMObject *object) NM_OBJECT_CLASS (nm_client_parent_class)->init_dbus (object); - priv->client_proxy = _nm_object_new_proxy (object, NULL, NM_DBUS_INTERFACE); + priv->manager_proxy = NMDBUS_MANAGER (_nm_object_get_proxy (object, NM_DBUS_INTERFACE)); _nm_object_register_properties (object, - priv->client_proxy, + NM_DBUS_INTERFACE, property_info); /* Permissions */ - dbus_g_proxy_add_signal (priv->client_proxy, "CheckPermissions", G_TYPE_INVALID); - dbus_g_proxy_connect_signal (priv->client_proxy, - "CheckPermissions", - G_CALLBACK (client_recheck_permissions), - object, - NULL); + g_signal_connect (priv->manager_proxy, "check-permissions", + G_CALLBACK (client_recheck_permissions), object); } #define NM_AUTH_PERMISSION_ENABLE_DISABLE_NETWORK "org.freedesktop.NetworkManager.enable-disable-network" @@ -263,7 +260,7 @@ nm_permission_result_to_client (const char *nm) } static void -update_permissions (NMClient *self, GHashTable *permissions) +update_permissions (NMClient *self, GVariant *permissions) { NMClientPrivate *priv = NM_CLIENT_GET_PRIVATE (self); GHashTableIter iter; @@ -277,11 +274,14 @@ update_permissions (NMClient *self, GHashTable *permissions) g_hash_table_remove_all (priv->permissions); if (permissions) { + GVariantIter viter; + const char *pkey, *pvalue; + /* Process new permissions */ - g_hash_table_iter_init (&iter, permissions); - while (g_hash_table_iter_next (&iter, &key, &value)) { - perm = nm_permission_to_client ((const char *) key); - perm_result = nm_permission_result_to_client ((const char *) value); + g_variant_iter_init (&viter, permissions); + while (g_variant_iter_next (&viter, "{&s&s}", &pkey, &pvalue)) { + perm = nm_permission_to_client (pkey); + perm_result = nm_permission_result_to_client (pvalue); if (perm) { g_hash_table_insert (priv->permissions, GUINT_TO_POINTER (perm), @@ -318,48 +318,68 @@ update_permissions (NMClient *self, GHashTable *permissions) static gboolean get_permissions_sync (NMClient *self, GError **error) { - gboolean success; - GHashTable *permissions = NULL; + NMClientPrivate *priv = NM_CLIENT_GET_PRIVATE (self); + GVariant *permissions; - success = dbus_g_proxy_call_with_timeout (NM_CLIENT_GET_PRIVATE (self)->client_proxy, - "GetPermissions", 3000, error, - G_TYPE_INVALID, - DBUS_TYPE_G_MAP_OF_STRING, &permissions, G_TYPE_INVALID); - update_permissions (self, success ? permissions : NULL); - if (permissions) - g_hash_table_destroy (permissions); - - return success; + if (nmdbus_manager_call_get_permissions_sync (priv->manager_proxy, + &permissions, + NULL, error)) { + update_permissions (self, permissions); + g_variant_unref (permissions); + return TRUE; + } else { + update_permissions (self, NULL); + return FALSE; + } } static void -get_permissions_reply (DBusGProxy *proxy, - DBusGProxyCall *call, +get_permissions_reply (GObject *object, + GAsyncResult *result, gpointer user_data) { - NMClient *self = NM_CLIENT (user_data); - GHashTable *permissions; + NMClient *self; + NMClientPrivate *priv; + GVariant *permissions = NULL; GError *error = NULL; - dbus_g_proxy_end_call (proxy, call, &error, - DBUS_TYPE_G_MAP_OF_STRING, &permissions, - G_TYPE_INVALID); - NM_CLIENT_GET_PRIVATE (self)->perm_call = NULL; - update_permissions (NM_CLIENT (user_data), error ? NULL : permissions); + /* WARNING: this may be called after the client is disposed, so we can't + * look at self/priv until after we've determined that that isn't the case. + */ + + nmdbus_manager_call_get_permissions_finish (NMDBUS_MANAGER (object), + &permissions, + result, &error); + if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) { + /* @self has been disposed. */ + g_error_free (error); + return; + } + + self = user_data; + priv = NM_CLIENT_GET_PRIVATE (self); + + update_permissions (self, permissions); + + g_clear_pointer (&permissions, g_variant_unref); g_clear_error (&error); + g_clear_object (&priv->perm_call_cancellable); } static void -client_recheck_permissions (DBusGProxy *proxy, gpointer user_data) +client_recheck_permissions (NMDBusManager *proxy, gpointer user_data) { NMClient *self = NM_CLIENT (user_data); NMClientPrivate *priv = NM_CLIENT_GET_PRIVATE (self); - if (!priv->perm_call) { - priv->perm_call = dbus_g_proxy_begin_call (NM_CLIENT_GET_PRIVATE (self)->client_proxy, "GetPermissions", - get_permissions_reply, self, NULL, - G_TYPE_INVALID); - } + if (priv->perm_call_cancellable) + return; + + priv->perm_call_cancellable = g_cancellable_new (); + nmdbus_manager_call_get_permissions (priv->manager_proxy, + priv->perm_call_cancellable, + get_permissions_reply, + self); } /** @@ -549,24 +569,21 @@ recheck_pending_activations (NMClient *self, const char *failed_path, GError *er } static void -activate_cb (DBusGProxy *proxy, - DBusGProxyCall *call, +activate_cb (GObject *object, + GAsyncResult *result, gpointer user_data) { ActivateInfo *info = user_data; - char *path; GError *error = NULL; - dbus_g_proxy_end_call (proxy, call, &error, - DBUS_TYPE_G_OBJECT_PATH, &path, - G_TYPE_INVALID); - if (error) { + if (nmdbus_manager_call_activate_connection_finish (NMDBUS_MANAGER (object), + &info->active_path, + result, &error)) { + recheck_pending_activations (info->client, NULL, NULL); + } else { activate_info_complete (info, NULL, error); activate_info_free (info); g_clear_error (&error); - } else { - info->active_path = path; - recheck_pending_activations (info->client, NULL, NULL); } } @@ -643,35 +660,31 @@ nm_client_activate_connection (NMClient *client, return; } - dbus_g_proxy_begin_call (priv->client_proxy, "ActivateConnection", - activate_cb, info, NULL, - DBUS_TYPE_G_OBJECT_PATH, connection ? nm_connection_get_path (connection) : "/", - DBUS_TYPE_G_OBJECT_PATH, device ? nm_object_get_path (NM_OBJECT (device)) : "/", - DBUS_TYPE_G_OBJECT_PATH, specific_object ? specific_object : "/", - G_TYPE_INVALID); + nmdbus_manager_call_activate_connection (priv->manager_proxy, + connection ? nm_connection_get_path (connection) : "/", + device ? nm_object_get_path (NM_OBJECT (device)) : "/", + specific_object ? specific_object : "/", + NULL, + activate_cb, info); } static void -add_activate_cb (DBusGProxy *proxy, - DBusGProxyCall *call, +add_activate_cb (GObject *object, + GAsyncResult *result, gpointer user_data) { ActivateInfo *info = user_data; - char *connection_path; - char *active_path; GError *error = NULL; - dbus_g_proxy_end_call (proxy, call, &error, - DBUS_TYPE_G_OBJECT_PATH, &connection_path, - DBUS_TYPE_G_OBJECT_PATH, &active_path, - G_TYPE_INVALID); - if (error) { + if (nmdbus_manager_call_add_and_activate_connection_finish (NMDBUS_MANAGER (object), + &info->new_connection_path, + &info->active_path, + result, &error)) { + recheck_pending_activations (info->client, NULL, NULL); + } else { activate_info_complete (info, NULL, error); activate_info_free (info); - } else { - info->new_connection_path = connection_path; - info->active_path = active_path; - recheck_pending_activations (info->client, NULL, NULL); + g_clear_error (&error); } } @@ -707,7 +720,7 @@ nm_client_add_and_activate_connection (NMClient *client, { NMClientPrivate *priv; ActivateInfo *info; - GHashTable *hash = NULL; + GVariant *dict = NULL; g_return_if_fail (NM_IS_CLIENT (client)); g_return_if_fail (NM_IS_DEVICE (device)); @@ -718,24 +731,22 @@ nm_client_add_and_activate_connection (NMClient *client, info->client = client; if (partial) - hash = nm_connection_to_dbus (partial, NM_CONNECTION_SERIALIZE_ALL); - if (!hash) - hash = g_hash_table_new (g_str_hash, g_str_equal); + dict = nm_connection_to_dbus (partial, NM_CONNECTION_SERIALIZE_ALL); + if (!dict) + dict = g_variant_new_array (G_VARIANT_TYPE ("{sa{sv}}"), NULL, 0); priv = NM_CLIENT_GET_PRIVATE (client); priv->pending_activations = g_slist_prepend (priv->pending_activations, info); if (nm_client_get_nm_running (client)) { - dbus_g_proxy_begin_call (priv->client_proxy, "AddAndActivateConnection", - add_activate_cb, info, NULL, - DBUS_TYPE_G_MAP_OF_MAP_OF_VARIANT, hash, - DBUS_TYPE_G_OBJECT_PATH, nm_object_get_path (NM_OBJECT (device)), - DBUS_TYPE_G_OBJECT_PATH, specific_object ? specific_object : "/", - G_TYPE_INVALID); + nmdbus_manager_call_add_and_activate_connection (priv->manager_proxy, + dict, + nm_object_get_path (NM_OBJECT (device)), + specific_object ? specific_object : "/", + NULL, + add_activate_cb, info); } else info->idle_id = g_idle_add (activate_nm_not_running, info); - - g_hash_table_unref (hash); } static void @@ -773,10 +784,9 @@ nm_client_deactivate_connection (NMClient *client, NMActiveConnection *active) return; path = nm_object_get_path (NM_OBJECT (active)); - if (!dbus_g_proxy_call (priv->client_proxy, "DeactivateConnection", &error, - DBUS_TYPE_G_OBJECT_PATH, path, - G_TYPE_INVALID, - G_TYPE_INVALID)) { + if (!nmdbus_manager_call_deactivate_connection_sync (priv->manager_proxy, + path, + NULL, &error)) { g_warning ("Could not deactivate connection '%s': %s", path, error->message); g_error_free (error); } @@ -832,20 +842,15 @@ nm_client_wireless_get_enabled (NMClient *client) void nm_client_wireless_set_enabled (NMClient *client, gboolean enabled) { - GValue value = G_VALUE_INIT; - g_return_if_fail (NM_IS_CLIENT (client)); if (!nm_client_get_nm_running (client)) return; - g_value_init (&value, G_TYPE_BOOLEAN); - g_value_set_boolean (&value, enabled); - _nm_object_set_property (NM_OBJECT (client), NM_DBUS_INTERFACE, "WirelessEnabled", - &value); + "b", enabled); } /** @@ -890,20 +895,15 @@ nm_client_wwan_get_enabled (NMClient *client) void nm_client_wwan_set_enabled (NMClient *client, gboolean enabled) { - GValue value = G_VALUE_INIT; - g_return_if_fail (NM_IS_CLIENT (client)); if (!nm_client_get_nm_running (client)) return; - g_value_init (&value, G_TYPE_BOOLEAN); - g_value_set_boolean (&value, enabled); - _nm_object_set_property (NM_OBJECT (client), NM_DBUS_INTERFACE, "WwanEnabled", - &value); + "b", enabled); } /** @@ -948,20 +948,15 @@ nm_client_wimax_get_enabled (NMClient *client) void nm_client_wimax_set_enabled (NMClient *client, gboolean enabled) { - GValue value = G_VALUE_INIT; - g_return_if_fail (NM_IS_CLIENT (client)); if (!nm_client_get_nm_running (client)) return; - g_value_init (&value, G_TYPE_BOOLEAN); - g_value_set_boolean (&value, enabled); - _nm_object_set_property (NM_OBJECT (client), NM_DBUS_INTERFACE, "WimaxEnabled", - &value); + "b", enabled); } /** @@ -1067,10 +1062,9 @@ nm_client_networking_set_enabled (NMClient *client, gboolean enable) if (!nm_client_get_nm_running (client)) return; - if (!dbus_g_proxy_call (NM_CLIENT_GET_PRIVATE (client)->client_proxy, "Enable", &err, - G_TYPE_BOOLEAN, enable, - G_TYPE_INVALID, - G_TYPE_INVALID)) { + if (!nmdbus_manager_call_enable_sync (NM_CLIENT_GET_PRIVATE (client)->manager_proxy, + enable, + NULL, &err)) { g_warning ("Error enabling/disabling networking: %s", err->message); g_error_free (err); } @@ -1148,11 +1142,9 @@ nm_client_get_logging (NMClient *client, char **level, char **domains, GError ** if (!level && !domains) return TRUE; - return dbus_g_proxy_call (priv->client_proxy, "GetLogging", error, - G_TYPE_INVALID, - G_TYPE_STRING, level, - G_TYPE_STRING, domains, - G_TYPE_INVALID); + return nmdbus_manager_call_get_logging_sync (priv->manager_proxy, + level, domains, + NULL, error); } /** @@ -1187,11 +1179,9 @@ nm_client_set_logging (NMClient *client, const char *level, const char *domains, if (!level && !domains) return TRUE; - return dbus_g_proxy_call (priv->client_proxy, "SetLogging", error, - G_TYPE_STRING, level ? level : "", - G_TYPE_STRING, domains ? domains : "", - G_TYPE_INVALID, - G_TYPE_INVALID); + return nmdbus_manager_call_set_logging_sync (priv->manager_proxy, + level, domains, + NULL, error); } /** @@ -1343,7 +1333,7 @@ nm_running_changed_cb (GObject *object, } else { _nm_object_suppress_property_updates (NM_OBJECT (client), FALSE); _nm_object_reload_properties_async (NM_OBJECT (client), updated_properties, client); - client_recheck_permissions (priv->client_proxy, client); + client_recheck_permissions (priv->manager_proxy, client); } } @@ -1387,77 +1377,39 @@ nm_client_check_connectivity (NMClient *client, GError **error) { NMClientPrivate *priv; - NMConnectivityState connectivity; + guint32 connectivity; g_return_val_if_fail (NM_IS_CLIENT (client), NM_CONNECTIVITY_UNKNOWN); priv = NM_CLIENT_GET_PRIVATE (client); - if (!dbus_g_proxy_call (priv->client_proxy, "CheckConnectivity", error, - G_TYPE_INVALID, - G_TYPE_UINT, &connectivity, - G_TYPE_INVALID)) - connectivity = NM_CONNECTIVITY_UNKNOWN; - - return connectivity; -} - -typedef struct { - NMClient *client; - DBusGProxyCall *call; - GCancellable *cancellable; - guint cancelled_id; - NMConnectivityState connectivity; -} CheckConnectivityData; - -static void -check_connectivity_data_free (CheckConnectivityData *ccd) -{ - if (ccd->cancellable) { - if (ccd->cancelled_id) - g_signal_handler_disconnect (ccd->cancellable, ccd->cancelled_id); - g_object_unref (ccd->cancellable); - } - - g_slice_free (CheckConnectivityData, ccd); + if (nmdbus_manager_call_check_connectivity_sync (priv->manager_proxy, + &connectivity, + cancellable, error)) + return connectivity; + else + return NM_CONNECTIVITY_UNKNOWN; } static void -check_connectivity_cb (DBusGProxy *proxy, - DBusGProxyCall *call, +check_connectivity_cb (GObject *object, + GAsyncResult *result, gpointer user_data) { GSimpleAsyncResult *simple = user_data; - CheckConnectivityData *ccd = g_simple_async_result_get_op_res_gpointer (simple); + guint32 connectivity; GError *error = NULL; - if (ccd->cancellable) { - g_signal_handler_disconnect (ccd->cancellable, ccd->cancelled_id); - ccd->cancelled_id = 0; - } - - if (!dbus_g_proxy_end_call (proxy, call, &error, - G_TYPE_UINT, &ccd->connectivity, - G_TYPE_INVALID)) + if (nmdbus_manager_call_check_connectivity_finish (NMDBUS_MANAGER (object), + &connectivity, + result, &error)) + g_simple_async_result_set_op_res_gssize (simple, connectivity); + else g_simple_async_result_take_error (simple, error); g_simple_async_result_complete (simple); g_object_unref (simple); } -static void -check_connectivity_cancelled_cb (GCancellable *cancellable, - gpointer user_data) -{ - GSimpleAsyncResult *simple = user_data; - CheckConnectivityData *ccd = g_simple_async_result_get_op_res_gpointer (simple); - - g_signal_handler_disconnect (cancellable, ccd->cancelled_id); - ccd->cancelled_id = 0; - - dbus_g_proxy_cancel_call (NM_CLIENT_GET_PRIVATE (ccd->client)->client_proxy, ccd->call); - g_simple_async_result_complete_in_idle (simple); -} - /** * nm_client_check_connectivity_async: * @client: an #NMClient @@ -1478,29 +1430,15 @@ nm_client_check_connectivity_async (NMClient *client, { NMClientPrivate *priv; GSimpleAsyncResult *simple; - CheckConnectivityData *ccd; g_return_if_fail (NM_IS_CLIENT (client)); priv = NM_CLIENT_GET_PRIVATE (client); - ccd = g_slice_new (CheckConnectivityData); - ccd->client = client; - simple = g_simple_async_result_new (G_OBJECT (client), callback, user_data, nm_client_check_connectivity_async); - g_simple_async_result_set_op_res_gpointer (simple, ccd, (GDestroyNotify) check_connectivity_data_free); - - if (cancellable) { - ccd->cancellable = g_object_ref (cancellable); - ccd->cancelled_id = g_signal_connect (cancellable, "cancelled", - G_CALLBACK (check_connectivity_cancelled_cb), - simple); - g_simple_async_result_set_check_cancellable (simple, cancellable); - } - - ccd->call = dbus_g_proxy_begin_call (priv->client_proxy, "CheckConnectivity", - check_connectivity_cb, simple, NULL, - G_TYPE_INVALID); + nmdbus_manager_call_check_connectivity (priv->manager_proxy, + cancellable, + check_connectivity_cb, simple); } /** @@ -1520,17 +1458,14 @@ nm_client_check_connectivity_finish (NMClient *client, GError **error) { GSimpleAsyncResult *simple; - CheckConnectivityData *ccd; g_return_val_if_fail (g_simple_async_result_is_valid (result, G_OBJECT (client), nm_client_check_connectivity_async), NM_CONNECTIVITY_UNKNOWN); simple = G_SIMPLE_ASYNC_RESULT (result); - ccd = g_simple_async_result_get_op_res_gpointer (simple); if (g_simple_async_result_propagate_error (simple, error)) return NM_CONNECTIVITY_UNKNOWN; - - return ccd->connectivity; + return (NMConnectivityState) g_simple_async_result_get_op_res_gssize (simple); } /****************************************************************/ @@ -1725,6 +1660,7 @@ init_sync (GInitable *initable, GCancellable *cancellable, GError **error) typedef struct { NMClient *client; + GCancellable *cancellable; GSimpleAsyncResult *result; } NMClientInitData; @@ -1733,22 +1669,23 @@ init_async_complete (NMClientInitData *init_data) { g_simple_async_result_complete (init_data->result); g_object_unref (init_data->result); + g_clear_object (&init_data->cancellable); g_slice_free (NMClientInitData, init_data); } static void -init_async_got_permissions (DBusGProxy *proxy, DBusGProxyCall *call, gpointer user_data) +init_async_got_permissions (GObject *object, GAsyncResult *result, gpointer user_data) { NMClientInitData *init_data = user_data; - GHashTable *permissions; - GError *error = NULL; + GVariant *permissions; - dbus_g_proxy_end_call (proxy, call, &error, - DBUS_TYPE_G_MAP_OF_STRING, &permissions, - G_TYPE_INVALID); - update_permissions (init_data->client, error ? NULL : permissions); - if (error) - g_simple_async_result_take_error (init_data->result, error); + if (nmdbus_manager_call_get_permissions_finish (NMDBUS_MANAGER (object), + &permissions, + result, NULL)) { + update_permissions (init_data->client, permissions); + g_variant_unref (permissions); + } else + update_permissions (init_data->client, NULL); init_async_complete (init_data); } @@ -1771,9 +1708,9 @@ init_async_parent_inited (GObject *source, GAsyncResult *result, gpointer user_d return; } - dbus_g_proxy_begin_call (priv->client_proxy, "GetPermissions", - init_async_got_permissions, init_data, NULL, - G_TYPE_INVALID); + nmdbus_manager_call_get_permissions (priv->manager_proxy, + init_data->cancellable, + init_async_got_permissions, init_data); } static void @@ -1792,6 +1729,7 @@ init_async (GAsyncInitable *initable, int io_priority, init_data = g_slice_new0 (NMClientInitData); init_data->client = NM_CLIENT (initable); + init_data->cancellable = cancellable ? g_object_ref (cancellable) : NULL; init_data->result = g_simple_async_result_new (G_OBJECT (initable), callback, user_data, init_async); g_simple_async_result_set_op_res_gboolean (init_data->result, TRUE); @@ -1817,13 +1755,11 @@ dispose (GObject *object) NMClient *client = NM_CLIENT (object); NMClientPrivate *priv = NM_CLIENT_GET_PRIVATE (object); - if (priv->perm_call) { - dbus_g_proxy_cancel_call (priv->client_proxy, priv->perm_call); - priv->perm_call = NULL; + if (priv->perm_call_cancellable) { + g_cancellable_cancel (priv->perm_call_cancellable); + g_clear_object (&priv->perm_call_cancellable); } - g_clear_object (&priv->client_proxy); - free_devices (client, TRUE); free_active_connections (client, TRUE); g_clear_object (&priv->primary_connection); @@ -1962,6 +1898,9 @@ nm_client_class_init (NMClientClass *client_class) g_type_class_add_private (client_class, sizeof (NMClientPrivate)); + _nm_object_class_add_interface (nm_object_class, NM_DBUS_INTERFACE); + _nm_dbus_register_proxy_type (NM_DBUS_INTERFACE, NMDBUS_TYPE_MANAGER_PROXY); + /* virtual methods */ object_class->constructor = constructor; object_class->constructed = constructed; diff --git a/libnm/nm-dbus-helpers-private.h b/libnm/nm-dbus-helpers-private.h deleted file mode 100644 index 10e8ecd81e..0000000000 --- a/libnm/nm-dbus-helpers-private.h +++ /dev/null @@ -1,36 +0,0 @@ -/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ -/* - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301 USA. - * - * Copyright 2013 Red Hat, Inc. - */ - -#ifndef __NM_DBUS_HELPERS_PRIVATE_H__ -#define __NM_DBUS_HELPERS_PRIVATE_H__ - -#include -#include -#include - -DBusGConnection *_nm_dbus_new_connection (GError **error); - -gboolean _nm_dbus_is_connection_private (DBusGConnection *connection); - -DBusGProxy * _nm_dbus_new_proxy_for_connection (DBusGConnection *connection, - const char *path, - const char *interface); - -#endif /* __NM_DBUS_HELPERS_PRIVATE_H__ */ diff --git a/libnm/nm-dbus-helpers.c b/libnm/nm-dbus-helpers.c index 464facef8b..0d8e0f2be6 100644 --- a/libnm/nm-dbus-helpers.c +++ b/libnm/nm-dbus-helpers.c @@ -21,80 +21,325 @@ #include #include #include -#include -#include -#include "nm-dbus-helpers-private.h" +#include "nm-dbus-helpers.h" #include "nm-dbus-interface.h" -static dbus_int32_t priv_slot = -1; -static DBusBusType nm_bus = DBUS_BUS_SYSTEM; +#define NM_DBUS_PRIVATE_CONNECTION_TAG "libnm-private-connection" +static GBusType nm_bus = G_BUS_TYPE_SYSTEM; -static void -_ensure_nm_dbus_helpers_inited (void) +GBusType +_nm_dbus_bus_type (void) { static gsize init_value = 0; if (g_once_init_enter (&init_value)) { - dbus_connection_allocate_data_slot (&priv_slot); - g_assert (priv_slot != -1); - if (g_getenv ("LIBNM_USE_SESSION_BUS")) - nm_bus = DBUS_BUS_SESSION; + nm_bus = G_BUS_TYPE_SESSION; g_once_init_leave (&init_value, 1); } + + return nm_bus; } -DBusGConnection * -_nm_dbus_new_connection (GError **error) +GDBusConnection * +_nm_dbus_new_connection (GCancellable *cancellable, GError **error) { - DBusGConnection *connection = NULL; + GDBusConnection *connection = NULL; - _ensure_nm_dbus_helpers_inited (); - -#if HAVE_DBUS_GLIB_100 /* If running as root try the private bus first */ - if (0 == geteuid () && nm_bus == DBUS_BUS_SYSTEM) { - connection = dbus_g_connection_open ("unix:path=" NMRUNDIR "/private", error); - if (connection) { - DBusConnection *dbus_connection = dbus_g_connection_get_connection (connection); + if (0 == geteuid ()) { + GError *local = NULL; + connection = g_dbus_connection_new_for_address_sync ("unix:path=" NMRUNDIR "/private", + G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_CLIENT, + NULL, cancellable, &local); + if (connection) { /* Mark this connection as private */ - dbus_connection_set_data (dbus_connection, priv_slot, GUINT_TO_POINTER (TRUE), NULL); - dbus_connection_set_exit_on_disconnect (dbus_connection, FALSE); + g_object_set_data (G_OBJECT (connection), + NM_DBUS_PRIVATE_CONNECTION_TAG, + GUINT_TO_POINTER (TRUE)); return connection; } - /* Fall back to a bus if for some reason private socket isn't available */ - g_clear_error (error); + + if (g_error_matches (local, G_IO_ERROR, G_IO_ERROR_CANCELLED)) { + g_propagate_error (error, local); + return NULL; + } + g_error_free (local); } -#endif - if (connection == NULL) - connection = dbus_g_bus_get (nm_bus, error); + return g_bus_get_sync (_nm_dbus_bus_type (), cancellable, error); +} - return connection; +static void +new_connection_async_got_system (GObject *source, GAsyncResult *result, gpointer user_data) +{ + GSimpleAsyncResult *simple = user_data; + GDBusConnection *connection; + GError *error = NULL; + + connection = g_bus_get_finish (result, &error); + if (connection) + g_simple_async_result_set_op_res_gpointer (simple, connection, g_object_unref); + else + g_simple_async_result_take_error (simple, error); + + g_simple_async_result_complete (simple); + g_object_unref (simple); +} + +static void +new_connection_async_got_private (GObject *source, GAsyncResult *result, gpointer user_data) +{ + GSimpleAsyncResult *simple = user_data; + GDBusConnection *connection; + GError *error = NULL; + + connection = g_dbus_connection_new_for_address_finish (result, &error); + if (connection) { + g_simple_async_result_set_op_res_gpointer (simple, connection, g_object_unref); + g_simple_async_result_complete (simple); + g_object_unref (simple); + return; + } + + if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) { + g_simple_async_result_take_error (simple, error); + g_simple_async_result_complete (simple); + g_object_unref (simple); + return; + } + + g_clear_error (&error); + g_bus_get (_nm_dbus_bus_type (), + g_object_get_data (G_OBJECT (simple), "cancellable"), + new_connection_async_got_system, simple); +} + +void +_nm_dbus_new_connection_async (GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + GSimpleAsyncResult *simple; + + simple = g_simple_async_result_new (NULL, callback, user_data, _nm_dbus_new_connection_async); + + /* If running as root try the private bus first */ + if (0 == geteuid ()) { + g_object_set_data_full (G_OBJECT (simple), "cancellable", + g_object_ref (cancellable), g_object_unref); + g_dbus_connection_new_for_address ("unix:path=" NMRUNDIR "/private", + G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_CLIENT, + NULL, + cancellable, + new_connection_async_got_private, simple); + } else { + g_bus_get (_nm_dbus_bus_type (), + cancellable, + new_connection_async_got_system, simple); + } +} + +GDBusConnection * +_nm_dbus_new_connection_finish (GAsyncResult *result, + GError **error) +{ + GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (result); + + if (g_simple_async_result_propagate_error (simple, error)) + return NULL; + + return g_object_ref (g_simple_async_result_get_op_res_gpointer (simple)); } gboolean -_nm_dbus_is_connection_private (DBusGConnection *connection) +_nm_dbus_is_connection_private (GDBusConnection *connection) { - if (priv_slot == -1) - return FALSE; - return !!dbus_connection_get_data (dbus_g_connection_get_connection (connection), priv_slot); + return !!g_object_get_data (G_OBJECT (connection), NM_DBUS_PRIVATE_CONNECTION_TAG); } -DBusGProxy * -_nm_dbus_new_proxy_for_connection (DBusGConnection *connection, +static GHashTable *proxy_types; + +#undef _nm_dbus_register_proxy_type +void +_nm_dbus_register_proxy_type (const char *interface, + GType proxy_type) +{ + if (!proxy_types) + proxy_types = g_hash_table_new (g_str_hash, g_str_equal); + + g_assert (g_hash_table_lookup (proxy_types, interface) == NULL); + g_hash_table_insert (proxy_types, (char *) interface, GSIZE_TO_POINTER (proxy_type)); +} + +/* We don't (currently) use GDBus's property-handling code */ +#define NM_DBUS_PROXY_FLAGS (G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES | \ + G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START) + +GDBusProxy * +_nm_dbus_new_proxy_for_connection (GDBusConnection *connection, const char *path, - const char *interface) + const char *interface, + GCancellable *cancellable, + GError **error) { - /* Private connections can't use dbus_g_proxy_new_for_name() or - * dbus_g_proxy_new_for_name_owner() because peer-to-peer connections don't - * have either a bus daemon or name owners, both of which those functions - * require. - */ - if (_nm_dbus_is_connection_private (connection)) - return dbus_g_proxy_new_for_peer (connection, path, interface); + GType proxy_type; + const char *name; - return dbus_g_proxy_new_for_name (connection, NM_DBUS_SERVICE, path, interface); + proxy_type = GPOINTER_TO_SIZE (g_hash_table_lookup (proxy_types, interface)); + if (!proxy_type) + proxy_type = G_TYPE_DBUS_PROXY; + + if (_nm_dbus_is_connection_private (connection)) + name = NULL; + else + name = NM_DBUS_SERVICE; + + return g_initable_new (proxy_type, cancellable, error, + "g-connection", connection, + "g-flags", NM_DBUS_PROXY_FLAGS, + "g-name", name, + "g-object-path", path, + "g-interface-name", interface, + NULL); +} + +void +_nm_dbus_new_proxy_for_connection_async (GDBusConnection *connection, + const char *path, + const char *interface, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + GType proxy_type; + const char *name; + + proxy_type = GPOINTER_TO_SIZE (g_hash_table_lookup (proxy_types, interface)); + if (!proxy_type) + proxy_type = G_TYPE_DBUS_PROXY; + + if (_nm_dbus_is_connection_private (connection)) + name = NULL; + else + name = NM_DBUS_SERVICE; + + g_async_initable_new_async (proxy_type, G_PRIORITY_DEFAULT, + cancellable, callback, user_data, + "g-connection", connection, + "g-flags", NM_DBUS_PROXY_FLAGS, + "g-name", name, + "g-object-path", path, + "g-interface-name", interface, + NULL); +} + +GDBusProxy * +_nm_dbus_new_proxy_for_connection_finish (GAsyncResult *result, + GError **error) +{ + GObject *source, *proxy; + + source = g_async_result_get_source_object (result); + proxy = g_async_initable_new_finish (G_ASYNC_INITABLE (source), result, error); + g_object_unref (source); + + return G_DBUS_PROXY (proxy); +} + +void +_nm_dbus_register_error_domain (GQuark domain, + const char *interface, + GType enum_type) +{ + GEnumClass *enum_class; + GEnumValue *e; + char *error_name; + int i; + + enum_class = g_type_class_ref (enum_type); + for (i = 0; i < enum_class->n_values; i++) { + e = &enum_class->values[i]; + error_name = g_strdup_printf ("%s.%s", interface, e->value_nick); + g_dbus_error_register_error (domain, e->value, error_name); + g_free (error_name); + } + + g_type_class_unref (enum_class); +} + +/* Binds the properties on a generated server-side GDBus object to the + * corresponding properties on the public object. + */ +void +_nm_dbus_bind_properties (gpointer object, gpointer skeleton) +{ + GParamSpec **properties; + guint n_properties; + int i; + + properties = g_object_class_list_properties (G_OBJECT_GET_CLASS (skeleton), &n_properties); + for (i = 0; i < n_properties; i++) { + if (g_str_has_prefix (properties[i]->name, "g-")) + continue; + + g_object_bind_property (object, properties[i]->name, + skeleton, properties[i]->name, + G_BINDING_BIDIRECTIONAL | G_BINDING_SYNC_CREATE); + } +} + +static char * +signal_name_from_method_name (const char *method_name) +{ + GString *signal_name; + const char *p; + + signal_name = g_string_new ("handle"); + for (p = method_name; *p; p++) { + if (g_ascii_isupper (*p)) + g_string_append_c (signal_name, '-'); + g_string_append_c (signal_name, g_ascii_tolower (*p)); + } + + return g_string_free (signal_name, FALSE); +} + +static void +_nm_dbus_method_meta_marshal (GClosure *closure, GValue *return_value, + guint n_param_values, const GValue *param_values, + gpointer invocation_hint, gpointer marshal_data) +{ + closure->marshal (closure, return_value, n_param_values, + param_values, invocation_hint, + ((GCClosure *)closure)->callback); + + g_value_set_boolean (return_value, TRUE); +} + +/* Takes (method_name, handler_func) pairs and connects the handlers to the + * signals on skeleton, with object as the user_data, but swapped so it comes + * first in the argument list, and handling the return value automatically. + */ +void +_nm_dbus_bind_methods (gpointer object, gpointer skeleton, ...) +{ + va_list ap; + const char *method_name; + char *signal_name; + GCallback handler; + GClosure *closure; + + va_start (ap, skeleton); + while ( (method_name = va_arg (ap, const char *)) + && (handler = va_arg (ap, GCallback))) { + signal_name = signal_name_from_method_name (method_name); + closure = g_cclosure_new_swap (handler, object, NULL); + g_closure_set_meta_marshal (closure, NULL, _nm_dbus_method_meta_marshal); + g_signal_connect_closure (skeleton, signal_name, closure, FALSE); + g_free (signal_name); + } + va_end (ap); } diff --git a/libnm/nm-dbus-helpers.h b/libnm/nm-dbus-helpers.h new file mode 100644 index 0000000000..9b0456b2bb --- /dev/null +++ b/libnm/nm-dbus-helpers.h @@ -0,0 +1,82 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA. + * + * Copyright 2013 Red Hat, Inc. + */ + +#ifndef __NM_DBUS_HELPERS_PRIVATE_H__ +#define __NM_DBUS_HELPERS_PRIVATE_H__ + +#include + +/* Copied from dbus/dbus-shared.h */ +#define DBUS_SERVICE_DBUS "org.freedesktop.DBus" +#define DBUS_PATH_DBUS "/org/freedesktop/DBus" +#define DBUS_PATH_LOCAL "/org/freedesktop/DBus/Local" + +#define DBUS_INTERFACE_DBUS "org.freedesktop.DBus" +#define DBUS_INTERFACE_INTROSPECTABLE "org.freedesktop.DBus.Introspectable" +#define DBUS_INTERFACE_PROPERTIES "org.freedesktop.DBus.Properties" +#define DBUS_INTERFACE_PEER "org.freedesktop.DBus.Peer" + + +GBusType _nm_dbus_bus_type (void); + +GDBusConnection *_nm_dbus_new_connection (GCancellable *cancellable, + GError **error); + +void _nm_dbus_new_connection_async (GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); +GDBusConnection *_nm_dbus_new_connection_finish (GAsyncResult *result, + GError **error); + +gboolean _nm_dbus_is_connection_private (GDBusConnection *connection); + +void _nm_dbus_register_proxy_type (const char *interface, + GType proxy_type); +/* Guarantee that @interface is a static string */ +#define _nm_dbus_register_proxy_type(interface, proxy_type) \ + _nm_dbus_register_proxy_type (interface "", proxy_type) \ + +GDBusProxy *_nm_dbus_new_proxy_for_connection (GDBusConnection *connection, + const char *path, + const char *interface, + GCancellable *cancellable, + GError **error); + +void _nm_dbus_new_proxy_for_connection_async (GDBusConnection *connection, + const char *path, + const char *interface, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); +GDBusProxy *_nm_dbus_new_proxy_for_connection_finish (GAsyncResult *result, + GError **error); + +void _nm_dbus_register_error_domain (GQuark domain, + const char *interface, + GType enum_type); + +void _nm_dbus_bind_properties (gpointer object, + gpointer skeleton); + +void _nm_dbus_bind_methods (gpointer object, + gpointer skeleton, + ...) G_GNUC_NULL_TERMINATED; + +#endif /* __NM_DBUS_HELPERS_PRIVATE_H__ */ diff --git a/libnm/nm-device-adsl.c b/libnm/nm-device-adsl.c index 3d99020a2e..49d6595e42 100644 --- a/libnm/nm-device-adsl.c +++ b/libnm/nm-device-adsl.c @@ -32,11 +32,8 @@ G_DEFINE_TYPE (NMDeviceAdsl, nm_device_adsl, NM_TYPE_DEVICE) #define NM_DEVICE_ADSL_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_DEVICE_ADSL, NMDeviceAdslPrivate)) typedef struct { - DBusGProxy *proxy; - gboolean carrier; - gboolean disposed; } NMDeviceAdslPrivate; enum { @@ -130,35 +127,11 @@ init_dbus (NMObject *object) NM_OBJECT_CLASS (nm_device_adsl_parent_class)->init_dbus (object); - priv->proxy = _nm_object_new_proxy (object, NULL, NM_DBUS_INTERFACE_DEVICE_ADSL); _nm_object_register_properties (object, - priv->proxy, + NM_DBUS_INTERFACE_DEVICE_ADSL, property_info); } -static void -dispose (GObject *object) -{ - NMDeviceAdslPrivate *priv = NM_DEVICE_ADSL_GET_PRIVATE (object); - - if (priv->disposed) { - G_OBJECT_CLASS (nm_device_adsl_parent_class)->dispose (object); - return; - } - - priv->disposed = TRUE; - - g_object_unref (priv->proxy); - - G_OBJECT_CLASS (nm_device_adsl_parent_class)->dispose (object); -} - -static void -finalize (GObject *object) -{ - G_OBJECT_CLASS (nm_device_adsl_parent_class)->finalize (object); -} - static void get_property (GObject *object, guint prop_id, @@ -186,9 +159,9 @@ nm_device_adsl_class_init (NMDeviceAdslClass *adsl_class) g_type_class_add_private (object_class, sizeof (NMDeviceAdslPrivate)); + _nm_object_class_add_interface (nm_object_class, NM_DBUS_INTERFACE_DEVICE_ADSL); + /* virtual methods */ - object_class->dispose = dispose; - object_class->finalize = finalize; object_class->get_property = get_property; nm_object_class->init_dbus = init_dbus; diff --git a/libnm/nm-device-bond.c b/libnm/nm-device-bond.c index e378c9cc31..b22d8b30fb 100644 --- a/libnm/nm-device-bond.c +++ b/libnm/nm-device-bond.c @@ -37,8 +37,6 @@ G_DEFINE_TYPE (NMDeviceBond, nm_device_bond, NM_TYPE_DEVICE) #define NM_DEVICE_BOND_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_DEVICE_BOND, NMDeviceBondPrivate)) typedef struct { - DBusGProxy *proxy; - char *hw_address; gboolean carrier; GPtrArray *slaves; @@ -191,9 +189,8 @@ init_dbus (NMObject *object) NM_OBJECT_CLASS (nm_device_bond_parent_class)->init_dbus (object); - priv->proxy = _nm_object_new_proxy (object, NULL, NM_DBUS_INTERFACE_DEVICE_BOND); _nm_object_register_properties (object, - priv->proxy, + NM_DBUS_INTERFACE_DEVICE_BOND, property_info); } @@ -202,8 +199,6 @@ dispose (GObject *object) { NMDeviceBondPrivate *priv = NM_DEVICE_BOND_GET_PRIVATE (object); - g_clear_object (&priv->proxy); - g_clear_pointer (&priv->slaves, g_ptr_array_unref); G_OBJECT_CLASS (nm_device_bond_parent_class)->dispose (object); @@ -252,6 +247,8 @@ nm_device_bond_class_init (NMDeviceBondClass *bond_class) g_type_class_add_private (bond_class, sizeof (NMDeviceBondPrivate)); + _nm_object_class_add_interface (nm_object_class, NM_DBUS_INTERFACE_DEVICE_BOND); + /* virtual methods */ object_class->dispose = dispose; object_class->finalize = finalize; diff --git a/libnm/nm-device-bridge.c b/libnm/nm-device-bridge.c index cb9cb2ad46..b4ee25b811 100644 --- a/libnm/nm-device-bridge.c +++ b/libnm/nm-device-bridge.c @@ -37,8 +37,6 @@ G_DEFINE_TYPE (NMDeviceBridge, nm_device_bridge, NM_TYPE_DEVICE) #define NM_DEVICE_BRIDGE_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_DEVICE_BRIDGE, NMDeviceBridgePrivate)) typedef struct { - DBusGProxy *proxy; - char *hw_address; gboolean carrier; GPtrArray *slaves; @@ -191,9 +189,8 @@ init_dbus (NMObject *object) NM_OBJECT_CLASS (nm_device_bridge_parent_class)->init_dbus (object); - priv->proxy = _nm_object_new_proxy (object, NULL, NM_DBUS_INTERFACE_DEVICE_BRIDGE); _nm_object_register_properties (object, - priv->proxy, + NM_DBUS_INTERFACE_DEVICE_BRIDGE, property_info); } @@ -202,8 +199,6 @@ dispose (GObject *object) { NMDeviceBridgePrivate *priv = NM_DEVICE_BRIDGE_GET_PRIVATE (object); - g_clear_object (&priv->proxy); - g_clear_pointer (&priv->slaves, g_ptr_array_unref); G_OBJECT_CLASS (nm_device_bridge_parent_class)->dispose (object); @@ -252,6 +247,8 @@ nm_device_bridge_class_init (NMDeviceBridgeClass *bridge_class) g_type_class_add_private (bridge_class, sizeof (NMDeviceBridgePrivate)); + _nm_object_class_add_interface (nm_object_class, NM_DBUS_INTERFACE_DEVICE_BRIDGE); + /* virtual methods */ object_class->dispose = dispose; object_class->finalize = finalize; diff --git a/libnm/nm-device-bt.c b/libnm/nm-device-bt.c index 925442e524..b5cefe817f 100644 --- a/libnm/nm-device-bt.c +++ b/libnm/nm-device-bt.c @@ -37,8 +37,6 @@ G_DEFINE_TYPE (NMDeviceBt, nm_device_bt, NM_TYPE_DEVICE) #define NM_DEVICE_BT_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_DEVICE_BT, NMDeviceBtPrivate)) typedef struct { - DBusGProxy *proxy; - char *hw_address; char *name; guint32 bt_capabilities; @@ -227,22 +225,11 @@ init_dbus (NMObject *object) NM_OBJECT_CLASS (nm_device_bt_parent_class)->init_dbus (object); - priv->proxy = _nm_object_new_proxy (object, NULL, NM_DBUS_INTERFACE_DEVICE_BLUETOOTH); _nm_object_register_properties (object, - priv->proxy, + NM_DBUS_INTERFACE_DEVICE_BLUETOOTH, property_info); } -static void -dispose (GObject *object) -{ - NMDeviceBtPrivate *priv = NM_DEVICE_BT_GET_PRIVATE (object); - - g_clear_object (&priv->proxy); - - G_OBJECT_CLASS (nm_device_bt_parent_class)->dispose (object); -} - static void finalize (GObject *object) { @@ -287,8 +274,9 @@ nm_device_bt_class_init (NMDeviceBtClass *bt_class) g_type_class_add_private (bt_class, sizeof (NMDeviceBtPrivate)); + _nm_object_class_add_interface (nm_object_class, NM_DBUS_INTERFACE_DEVICE_BLUETOOTH); + /* virtual methods */ - object_class->dispose = dispose; object_class->finalize = finalize; object_class->get_property = get_property; diff --git a/libnm/nm-device-ethernet.c b/libnm/nm-device-ethernet.c index 118cda17d6..e26a58ee21 100644 --- a/libnm/nm-device-ethernet.c +++ b/libnm/nm-device-ethernet.c @@ -38,8 +38,6 @@ G_DEFINE_TYPE (NMDeviceEthernet, nm_device_ethernet, NM_TYPE_DEVICE) #define NM_DEVICE_ETHERNET_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_DEVICE_ETHERNET, NMDeviceEthernetPrivate)) typedef struct { - DBusGProxy *proxy; - char *hw_address; char *perm_hw_address; guint32 speed; @@ -226,22 +224,11 @@ init_dbus (NMObject *object) NM_OBJECT_CLASS (nm_device_ethernet_parent_class)->init_dbus (object); - priv->proxy = _nm_object_new_proxy (object, NULL, NM_DBUS_INTERFACE_DEVICE_WIRED); _nm_object_register_properties (object, - priv->proxy, + NM_DBUS_INTERFACE_DEVICE_WIRED, property_info); } -static void -dispose (GObject *object) -{ - NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE (object); - - g_clear_object (&priv->proxy); - - G_OBJECT_CLASS (nm_device_ethernet_parent_class)->dispose (object); -} - static void finalize (GObject *object) { @@ -289,8 +276,9 @@ nm_device_ethernet_class_init (NMDeviceEthernetClass *eth_class) g_type_class_add_private (eth_class, sizeof (NMDeviceEthernetPrivate)); + _nm_object_class_add_interface (nm_object_class, NM_DBUS_INTERFACE_DEVICE_WIRED); + /* virtual methods */ - object_class->dispose = dispose; object_class->finalize = finalize; object_class->get_property = get_property; diff --git a/libnm/nm-device-generic.c b/libnm/nm-device-generic.c index 29cae7cd37..5d11fcde0a 100644 --- a/libnm/nm-device-generic.c +++ b/libnm/nm-device-generic.c @@ -32,8 +32,6 @@ G_DEFINE_TYPE (NMDeviceGeneric, nm_device_generic, NM_TYPE_DEVICE) #define NM_DEVICE_GENERIC_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_DEVICE_GENERIC, NMDeviceGenericPrivate)) typedef struct { - DBusGProxy *proxy; - char *hw_address; char *type_description; } NMDeviceGenericPrivate; @@ -148,22 +146,11 @@ init_dbus (NMObject *object) NM_OBJECT_CLASS (nm_device_generic_parent_class)->init_dbus (object); - priv->proxy = _nm_object_new_proxy (object, NULL, NM_DBUS_INTERFACE_DEVICE_GENERIC); _nm_object_register_properties (object, - priv->proxy, + NM_DBUS_INTERFACE_DEVICE_GENERIC, property_info); } -static void -dispose (GObject *object) -{ - NMDeviceGenericPrivate *priv = NM_DEVICE_GENERIC_GET_PRIVATE (object); - - g_clear_object (&priv->proxy); - - G_OBJECT_CLASS (nm_device_generic_parent_class)->dispose (object); -} - static void finalize (GObject *object) { @@ -205,7 +192,8 @@ nm_device_generic_class_init (NMDeviceGenericClass *klass) g_type_class_add_private (klass, sizeof (NMDeviceGenericPrivate)); - object_class->dispose = dispose; + _nm_object_class_add_interface (nm_object_class, NM_DBUS_INTERFACE_DEVICE_GENERIC); + object_class->finalize = finalize; object_class->get_property = get_property; diff --git a/libnm/nm-device-infiniband.c b/libnm/nm-device-infiniband.c index 478c6e8c18..10ee1140d4 100644 --- a/libnm/nm-device-infiniband.c +++ b/libnm/nm-device-infiniband.c @@ -36,8 +36,6 @@ G_DEFINE_TYPE (NMDeviceInfiniband, nm_device_infiniband, NM_TYPE_DEVICE) #define NM_DEVICE_INFINIBAND_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_DEVICE_INFINIBAND, NMDeviceInfinibandPrivate)) typedef struct { - DBusGProxy *proxy; - char *hw_address; gboolean carrier; } NMDeviceInfinibandPrivate; @@ -175,22 +173,11 @@ init_dbus (NMObject *object) NM_OBJECT_CLASS (nm_device_infiniband_parent_class)->init_dbus (object); - priv->proxy = _nm_object_new_proxy (object, NULL, NM_DBUS_INTERFACE_DEVICE_INFINIBAND); _nm_object_register_properties (object, - priv->proxy, + NM_DBUS_INTERFACE_DEVICE_INFINIBAND, property_info); } -static void -dispose (GObject *object) -{ - NMDeviceInfinibandPrivate *priv = NM_DEVICE_INFINIBAND_GET_PRIVATE (object); - - g_clear_object (&priv->proxy); - - G_OBJECT_CLASS (nm_device_infiniband_parent_class)->dispose (object); -} - static void finalize (GObject *object) { @@ -231,8 +218,9 @@ nm_device_infiniband_class_init (NMDeviceInfinibandClass *ib_class) g_type_class_add_private (ib_class, sizeof (NMDeviceInfinibandPrivate)); + _nm_object_class_add_interface (nm_object_class, NM_DBUS_INTERFACE_DEVICE_INFINIBAND); + /* virtual methods */ - object_class->dispose = dispose; object_class->finalize = finalize; object_class->get_property = get_property; diff --git a/libnm/nm-device-modem.c b/libnm/nm-device-modem.c index 511f084bba..4983864cb4 100644 --- a/libnm/nm-device-modem.c +++ b/libnm/nm-device-modem.c @@ -37,8 +37,6 @@ G_DEFINE_TYPE (NMDeviceModem, nm_device_modem, NM_TYPE_DEVICE) #define NM_DEVICE_MODEM_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_DEVICE_MODEM, NMDeviceModemPrivate)) typedef struct { - DBusGProxy *proxy; - NMDeviceModemCapabilities caps; NMDeviceModemCapabilities current_caps; } NMDeviceModemPrivate; @@ -195,9 +193,8 @@ init_dbus (NMObject *object) NM_OBJECT_CLASS (nm_device_modem_parent_class)->init_dbus (object); - priv->proxy = _nm_object_new_proxy (object, NULL, NM_DBUS_INTERFACE_DEVICE_MODEM); _nm_object_register_properties (object, - priv->proxy, + NM_DBUS_INTERFACE_DEVICE_MODEM, property_info); } @@ -222,16 +219,6 @@ get_property (GObject *object, } } -static void -dispose (GObject *object) -{ - NMDeviceModemPrivate *priv = NM_DEVICE_MODEM_GET_PRIVATE (object); - - g_clear_object (&priv->proxy); - - G_OBJECT_CLASS (nm_device_modem_parent_class)->dispose (object); -} - static void nm_device_modem_class_init (NMDeviceModemClass *modem_class) { @@ -241,9 +228,10 @@ nm_device_modem_class_init (NMDeviceModemClass *modem_class) g_type_class_add_private (modem_class, sizeof (NMDeviceModemPrivate)); + _nm_object_class_add_interface (nm_object_class, NM_DBUS_INTERFACE_DEVICE_MODEM); + /* virtual methods */ object_class->get_property = get_property; - object_class->dispose = dispose; nm_object_class->init_dbus = init_dbus; diff --git a/libnm/nm-device-olpc-mesh.c b/libnm/nm-device-olpc-mesh.c index b8c2c25cca..ba139a2d43 100644 --- a/libnm/nm-device-olpc-mesh.c +++ b/libnm/nm-device-olpc-mesh.c @@ -36,8 +36,6 @@ G_DEFINE_TYPE (NMDeviceOlpcMesh, nm_device_olpc_mesh, NM_TYPE_DEVICE) #define NM_DEVICE_OLPC_MESH_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_DEVICE_OLPC_MESH, NMDeviceOlpcMeshPrivate)) typedef struct { - DBusGProxy *proxy; - char *hw_address; NMDeviceWifi *companion; guint32 active_channel; @@ -178,9 +176,8 @@ init_dbus (NMObject *object) NM_OBJECT_CLASS (nm_device_olpc_mesh_parent_class)->init_dbus (object); - priv->proxy = _nm_object_new_proxy (object, NULL, NM_DBUS_INTERFACE_DEVICE_OLPC_MESH); _nm_object_register_properties (object, - priv->proxy, + NM_DBUS_INTERFACE_DEVICE_OLPC_MESH, property_info); } @@ -190,7 +187,6 @@ dispose (GObject *object) NMDeviceOlpcMeshPrivate *priv = NM_DEVICE_OLPC_MESH_GET_PRIVATE (object); g_clear_object (&priv->companion); - g_clear_object (&priv->proxy); G_OBJECT_CLASS (nm_device_olpc_mesh_parent_class)->dispose (object); } @@ -238,6 +234,8 @@ nm_device_olpc_mesh_class_init (NMDeviceOlpcMeshClass *olpc_mesh_class) g_type_class_add_private (olpc_mesh_class, sizeof (NMDeviceOlpcMeshPrivate)); + _nm_object_class_add_interface (nm_object_class, NM_DBUS_INTERFACE_DEVICE_OLPC_MESH); + /* virtual methods */ object_class->dispose = dispose; object_class->finalize = finalize; diff --git a/libnm/nm-device-team.c b/libnm/nm-device-team.c index 27deda8a5a..06db4cf84a 100644 --- a/libnm/nm-device-team.c +++ b/libnm/nm-device-team.c @@ -37,8 +37,6 @@ G_DEFINE_TYPE (NMDeviceTeam, nm_device_team, NM_TYPE_DEVICE) #define NM_DEVICE_TEAM_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_DEVICE_TEAM, NMDeviceTeamPrivate)) typedef struct { - DBusGProxy *proxy; - char *hw_address; gboolean carrier; GPtrArray *slaves; @@ -191,9 +189,8 @@ init_dbus (NMObject *object) NM_OBJECT_CLASS (nm_device_team_parent_class)->init_dbus (object); - priv->proxy = _nm_object_new_proxy (object, NULL, NM_DBUS_INTERFACE_DEVICE_TEAM); _nm_object_register_properties (object, - priv->proxy, + NM_DBUS_INTERFACE_DEVICE_TEAM, property_info); } @@ -202,8 +199,6 @@ dispose (GObject *object) { NMDeviceTeamPrivate *priv = NM_DEVICE_TEAM_GET_PRIVATE (object); - g_clear_object (&priv->proxy); - g_clear_pointer (&priv->slaves, g_ptr_array_unref); G_OBJECT_CLASS (nm_device_team_parent_class)->dispose (object); @@ -252,6 +247,8 @@ nm_device_team_class_init (NMDeviceTeamClass *team_class) g_type_class_add_private (team_class, sizeof (NMDeviceTeamPrivate)); + _nm_object_class_add_interface (nm_object_class, NM_DBUS_INTERFACE_DEVICE_TEAM); + /* virtual methods */ object_class->dispose = dispose; object_class->finalize = finalize; diff --git a/libnm/nm-device-vlan.c b/libnm/nm-device-vlan.c index b0deb1b089..9cb9d9fde1 100644 --- a/libnm/nm-device-vlan.c +++ b/libnm/nm-device-vlan.c @@ -36,8 +36,6 @@ G_DEFINE_TYPE (NMDeviceVlan, nm_device_vlan, NM_TYPE_DEVICE) #define NM_DEVICE_VLAN_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_DEVICE_VLAN, NMDeviceVlanPrivate)) typedef struct { - DBusGProxy *proxy; - char *hw_address; gboolean carrier; guint vlan_id; @@ -205,22 +203,11 @@ init_dbus (NMObject *object) NM_OBJECT_CLASS (nm_device_vlan_parent_class)->init_dbus (object); - priv->proxy = _nm_object_new_proxy (object, NULL, NM_DBUS_INTERFACE_DEVICE_VLAN); _nm_object_register_properties (object, - priv->proxy, + NM_DBUS_INTERFACE_DEVICE_VLAN, property_info); } -static void -dispose (GObject *object) -{ - NMDeviceVlanPrivate *priv = NM_DEVICE_VLAN_GET_PRIVATE (object); - - g_clear_object (&priv->proxy); - - G_OBJECT_CLASS (nm_device_vlan_parent_class)->dispose (object); -} - static void finalize (GObject *object) { @@ -264,8 +251,9 @@ nm_device_vlan_class_init (NMDeviceVlanClass *vlan_class) g_type_class_add_private (vlan_class, sizeof (NMDeviceVlanPrivate)); + _nm_object_class_add_interface (nm_object_class, NM_DBUS_INTERFACE_DEVICE_VLAN); + /* virtual methods */ - object_class->dispose = dispose; object_class->finalize = finalize; object_class->get_property = get_property; diff --git a/libnm/nm-device-wifi.c b/libnm/nm-device-wifi.c index 7252672f2d..677eeebdf9 100644 --- a/libnm/nm-device-wifi.c +++ b/libnm/nm-device-wifi.c @@ -33,8 +33,10 @@ #include "nm-device-private.h" #include "nm-object-private.h" #include "nm-object-cache.h" -#include "nm-dbus-glib-types.h" #include "nm-core-internal.h" +#include "nm-dbus-helpers.h" + +#include "nmdbus-device-wifi.h" G_DEFINE_TYPE (NMDeviceWifi, nm_device_wifi, NM_TYPE_DEVICE) @@ -45,12 +47,13 @@ static void state_changed_cb (NMDevice *device, GParamSpec *pspec, gpointer user typedef struct { NMDeviceWifi *device; + GCancellable *cancellable; NMDeviceWifiRequestScanFn callback; gpointer user_data; } RequestScanInfo; typedef struct { - DBusGProxy *proxy; + NMDBusDeviceWifi *proxy; char *hw_address; char *perm_hw_address; @@ -60,7 +63,6 @@ typedef struct { NMDeviceWifiCapabilities wireless_caps; GPtrArray *aps; - DBusGProxyCall *scan_call; RequestScanInfo *scan_info; } NMDeviceWifiPrivate; @@ -286,24 +288,27 @@ nm_device_wifi_get_access_point_by_path (NMDeviceWifi *device, } static void -request_scan_cb (DBusGProxy *proxy, - DBusGProxyCall *call, +request_scan_cb (GObject *source, + GAsyncResult *result, gpointer user_data) { RequestScanInfo *info = user_data; - NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (info->device); - GError *error = NULL; - dbus_g_proxy_end_call (proxy, call, &error, G_TYPE_INVALID); + if (info->callback) { + NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (info->device); + GError *error = NULL; + + nmdbus_device_wifi_call_request_scan_finish (NMDBUS_DEVICE_WIFI (source), + result, &error); - if (info->callback) info->callback (info->device, error, info->user_data); - g_clear_error (&error); - g_slice_free (RequestScanInfo, info); + g_clear_error (&error); + priv->scan_info = NULL; + } - priv->scan_call = NULL; - priv->scan_info = NULL; + g_clear_object (&info->cancellable); + g_slice_free (RequestScanInfo, info); } /** @@ -322,29 +327,25 @@ nm_device_wifi_request_scan_simple (NMDeviceWifi *device, gpointer user_data) { RequestScanInfo *info; - GHashTable *options; NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (device); g_return_if_fail (NM_IS_DEVICE_WIFI (device)); /* If a scan is in progress, just return */ - if (priv->scan_call) + if (priv->scan_info) return; - options = g_hash_table_new (g_str_hash, g_str_equal); - info = g_slice_new0 (RequestScanInfo); info->device = device; + info->cancellable = g_cancellable_new (); info->callback = callback; info->user_data = user_data; priv->scan_info = info; - priv->scan_call = dbus_g_proxy_begin_call (NM_DEVICE_WIFI_GET_PRIVATE (device)->proxy, "RequestScan", - request_scan_cb, info, NULL, - DBUS_TYPE_G_MAP_OF_VARIANT, options, - G_TYPE_INVALID); - - g_hash_table_unref (options); + nmdbus_device_wifi_call_request_scan (NM_DEVICE_WIFI_GET_PRIVATE (device)->proxy, + g_variant_new_array (G_VARIANT_TYPE_VARDICT, NULL, 0), + info->cancellable, + request_scan_cb, info); } static void @@ -594,9 +595,9 @@ init_dbus (NMObject *object) NM_OBJECT_CLASS (nm_device_wifi_parent_class)->init_dbus (object); - priv->proxy = _nm_object_new_proxy (object, NULL, NM_DBUS_INTERFACE_DEVICE_WIRELESS); + priv->proxy = NMDBUS_DEVICE_WIFI (_nm_object_get_proxy (object, NM_DBUS_INTERFACE_DEVICE_WIRELESS)); _nm_object_register_properties (object, - priv->proxy, + NM_DBUS_INTERFACE_DEVICE_WIRELESS, property_info); } @@ -621,24 +622,26 @@ dispose (GObject *object) NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (object); GError *error = NULL; - if (priv->scan_call) { - g_set_error_literal (&error, NM_DEVICE_WIFI_ERROR, NM_DEVICE_WIFI_ERROR_UNKNOWN, - "Wi-Fi device was destroyed"); - if (priv->scan_info) { - if (priv->scan_info->callback) - priv->scan_info->callback (NULL, error, priv->scan_info->user_data); - g_slice_free (RequestScanInfo, priv->scan_info); - priv->scan_info = NULL; - } - g_clear_error (&error); + if (priv->scan_info) { + RequestScanInfo *scan_info; - dbus_g_proxy_cancel_call (priv->proxy, priv->scan_call); - priv->scan_call = NULL; + scan_info = priv->scan_info; + priv->scan_info = NULL; + + if (scan_info->callback) { + g_set_error_literal (&error, NM_DEVICE_WIFI_ERROR, NM_DEVICE_WIFI_ERROR_UNKNOWN, + "Wi-Fi device was destroyed"); + scan_info->callback (NULL, error, scan_info->user_data); + scan_info->callback = NULL; + g_clear_error (&error); + } + + g_cancellable_cancel (scan_info->cancellable); + /* request_scan_cb() will free scan_info */ } if (priv->aps) clean_up_aps (NM_DEVICE_WIFI (object), TRUE); - g_clear_object (&priv->proxy); G_OBJECT_CLASS (nm_device_wifi_parent_class)->dispose (object); } @@ -663,6 +666,10 @@ nm_device_wifi_class_init (NMDeviceWifiClass *wifi_class) g_type_class_add_private (wifi_class, sizeof (NMDeviceWifiPrivate)); + _nm_object_class_add_interface (nm_object_class, NM_DBUS_INTERFACE_DEVICE_WIRELESS); + _nm_dbus_register_proxy_type (NM_DBUS_INTERFACE_DEVICE_WIRELESS, + NMDBUS_TYPE_DEVICE_WIFI_PROXY); + /* virtual methods */ object_class->get_property = get_property; object_class->dispose = dispose; diff --git a/libnm/nm-device-wimax.c b/libnm/nm-device-wimax.c index fc5793acb2..ec16279191 100644 --- a/libnm/nm-device-wimax.c +++ b/libnm/nm-device-wimax.c @@ -31,7 +31,6 @@ #include "nm-device-wimax.h" #include "nm-object-private.h" #include "nm-object-cache.h" -#include "nm-dbus-glib-types.h" #include "nm-core-internal.h" #include "nm-device-private.h" @@ -43,8 +42,6 @@ void _nm_device_wimax_set_wireless_enabled (NMDeviceWimax *wimax, gboolean enabl static void state_changed_cb (NMDevice *device, GParamSpec *pspec, gpointer user_data); typedef struct { - DBusGProxy *proxy; - char *hw_address; NMWimaxNsp *active_nsp; GPtrArray *nsps; @@ -495,9 +492,8 @@ init_dbus (NMObject *object) NM_OBJECT_CLASS (nm_device_wimax_parent_class)->init_dbus (object); - priv->proxy = _nm_object_new_proxy (object, NULL, NM_DBUS_INTERFACE_DEVICE_WIMAX); _nm_object_register_properties (object, - priv->proxy, + NM_DBUS_INTERFACE_DEVICE_WIMAX, property_info); } @@ -530,7 +526,6 @@ dispose (GObject *object) if (priv->nsps) clean_up_nsps (NM_DEVICE_WIMAX (object)); - g_clear_object (&priv->proxy); G_OBJECT_CLASS (nm_device_wimax_parent_class)->dispose (object); } @@ -544,6 +539,8 @@ nm_device_wimax_class_init (NMDeviceWimaxClass *wimax_class) g_type_class_add_private (wimax_class, sizeof (NMDeviceWimaxPrivate)); + _nm_object_class_add_interface (nm_object_class, NM_DBUS_INTERFACE_DEVICE_WIMAX); + /* virtual methods */ object_class->get_property = get_property; object_class->dispose = dispose; diff --git a/libnm/nm-device.c b/libnm/nm-device.c index 1eff7386d6..187a298b5c 100644 --- a/libnm/nm-device.c +++ b/libnm/nm-device.c @@ -44,28 +44,26 @@ #include "nm-object-cache.h" #include "nm-remote-connection.h" #include "nm-core-internal.h" -#include "nm-dbus-glib-types.h" #include "nm-glib-compat.h" #include "nm-utils.h" -#include "nm-dbus-helpers-private.h" +#include "nm-dbus-helpers.h" -static GType _nm_device_type_for_path (DBusGConnection *connection, - const char *path); -static void _nm_device_type_for_path_async (DBusGConnection *connection, - const char *path, - NMObjectTypeCallbackFunc callback, - gpointer user_data); +#include "nmdbus-device.h" + +static GType _nm_device_decide_type (GVariant *value); gboolean connection_compatible (NMDevice *device, NMConnection *connection, GError **error); G_DEFINE_TYPE_WITH_CODE (NMDevice, nm_device, NM_TYPE_OBJECT, - _nm_object_register_type_func (g_define_type_id, _nm_device_type_for_path, - _nm_device_type_for_path_async); + _nm_object_register_type_func (g_define_type_id, + _nm_device_decide_type, + NM_DBUS_INTERFACE_DEVICE, + "DeviceType"); ) #define NM_DEVICE_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_DEVICE, NMDevicePrivate)) typedef struct { - DBusGProxy *proxy; + NMDBusDevice *proxy; char *iface; char *ip_iface; @@ -162,29 +160,21 @@ nm_device_init (NMDevice *device) priv->reason = NM_DEVICE_STATE_REASON_NONE; } -#define DBUS_G_TYPE_UINT_STRUCT (dbus_g_type_get_struct ("GValueArray", G_TYPE_UINT, G_TYPE_UINT, G_TYPE_INVALID)) - static gboolean -demarshal_state_reason (NMObject *object, GParamSpec *pspec, GValue *value, gpointer field) +demarshal_state_reason (NMObject *object, GParamSpec *pspec, GVariant *value, gpointer field) { guint32 *reason_field = field; - if (!G_VALUE_HOLDS (value, DBUS_G_TYPE_UINT_STRUCT)) - return FALSE; - - dbus_g_type_struct_get (value, - 1, reason_field, - G_MAXUINT); - + g_variant_get (value, "(uu)", NULL, reason_field); _nm_object_queue_notify (object, NM_DEVICE_STATE_REASON); return TRUE; } static void -device_state_changed (DBusGProxy *proxy, - NMDeviceState new_state, - NMDeviceState old_state, - NMDeviceStateReason reason, +device_state_changed (NMDBusDevice *proxy, + guint new_state, + guint old_state, + guint reason, gpointer user_data); static void @@ -222,26 +212,13 @@ init_dbus (NMObject *object) NM_OBJECT_CLASS (nm_device_parent_class)->init_dbus (object); - priv->proxy = _nm_object_new_proxy (object, NULL, NM_DBUS_INTERFACE_DEVICE); + priv->proxy = NMDBUS_DEVICE (_nm_object_get_proxy (object, NM_DBUS_INTERFACE_DEVICE)); _nm_object_register_properties (object, - priv->proxy, + NM_DBUS_INTERFACE_DEVICE, property_info); - dbus_g_object_register_marshaller (g_cclosure_marshal_generic, - G_TYPE_NONE, - G_TYPE_UINT, G_TYPE_UINT, G_TYPE_UINT, - G_TYPE_INVALID); - - dbus_g_proxy_add_signal (priv->proxy, - "StateChanged", - G_TYPE_UINT, G_TYPE_UINT, G_TYPE_UINT, - G_TYPE_INVALID); - - dbus_g_proxy_connect_signal (priv->proxy, "StateChanged", - G_CALLBACK (device_state_changed), - NM_DEVICE (object), - NULL); - + g_signal_connect (priv->proxy, "state-changed", + G_CALLBACK (device_state_changed), object); } typedef struct { @@ -284,33 +261,33 @@ device_state_change_reloaded (GObject *object, } static void -device_state_changed (DBusGProxy *proxy, - NMDeviceState new_state, - NMDeviceState old_state, - NMDeviceStateReason reason, +device_state_changed (NMDBusDevice *proxy, + guint new_state, + guint old_state, + guint reason, gpointer user_data) { NMDevice *self = NM_DEVICE (user_data); NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); + StateChangeData *data; - if (old_state != new_state) { - StateChangeData *data; + if (old_state == new_state) + return; - /* Our object-valued properties (eg, ip4_config) will still - * have their old values at this point, because NMObject is - * in the process of asynchronously reading the new values. - * Wait for that to finish before emitting the signal. - */ - priv->last_seen_state = new_state; + /* Our object-valued properties (eg, ip4_config) will still + * have their old values at this point, because NMObject is + * in the process of asynchronously reading the new values. + * Wait for that to finish before emitting the signal. + */ + priv->last_seen_state = new_state; - data = g_slice_new (StateChangeData); - data->old_state = old_state; - data->new_state = new_state; - data->reason = reason; - _nm_object_reload_properties_async (NM_OBJECT (user_data), - device_state_change_reloaded, - data); - } + data = g_slice_new (StateChangeData); + data->old_state = old_state; + data->new_state = new_state; + data->reason = reason; + _nm_object_reload_properties_async (NM_OBJECT (user_data), + device_state_change_reloaded, + data); } static GType @@ -367,7 +344,6 @@ dispose (GObject *object) { NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (object); - g_clear_object (&priv->proxy); g_clear_object (&priv->ip4_config); g_clear_object (&priv->dhcp4_config); g_clear_object (&priv->ip6_config); @@ -521,6 +497,9 @@ nm_device_class_init (NMDeviceClass *device_class) g_type_class_add_private (device_class, sizeof (NMDevicePrivate)); + _nm_object_class_add_interface (nm_object_class, NM_DBUS_INTERFACE_DEVICE); + _nm_dbus_register_proxy_type (NM_DBUS_INTERFACE_DEVICE, NMDBUS_TYPE_DEVICE_PROXY); + /* virtual methods */ object_class->constructed = constructed; object_class->get_property = get_property; @@ -864,90 +843,9 @@ _nm_device_set_device_type (NMDevice *device, NMDeviceType dtype) } static GType -_nm_device_type_for_path (DBusGConnection *connection, - const char *path) +_nm_device_decide_type (GVariant *value) { - DBusGProxy *proxy; - GError *err = NULL; - GValue value = G_VALUE_INIT; - NMDeviceType nm_dtype; - - proxy = _nm_dbus_new_proxy_for_connection (connection, path, "org.freedesktop.DBus.Properties"); - if (!proxy) { - g_warning ("%s: couldn't create D-Bus object proxy.", __func__); - return G_TYPE_INVALID; - } - - if (!dbus_g_proxy_call (proxy, - "Get", &err, - G_TYPE_STRING, NM_DBUS_INTERFACE_DEVICE, - G_TYPE_STRING, "DeviceType", - G_TYPE_INVALID, - G_TYPE_VALUE, &value, G_TYPE_INVALID)) { - g_warning ("Error in get_property: %s\n", err->message); - g_error_free (err); - g_object_unref (proxy); - return G_TYPE_INVALID; - } - g_object_unref (proxy); - - nm_dtype = g_value_get_uint (&value); - return _nm_device_gtype_from_dtype (nm_dtype); -} - -typedef struct { - DBusGConnection *connection; - NMObjectTypeCallbackFunc callback; - gpointer user_data; -} NMDeviceAsyncData; - -static void -async_got_type (DBusGProxy *proxy, DBusGProxyCall *call, gpointer user_data) -{ - NMDeviceAsyncData *async_data = user_data; - GValue value = G_VALUE_INIT; - const char *path = dbus_g_proxy_get_path (proxy); - GError *error = NULL; - GType type; - - if (dbus_g_proxy_end_call (proxy, call, &error, - G_TYPE_VALUE, &value, - G_TYPE_INVALID)) { - NMDeviceType dtype; - - dtype = g_value_get_uint (&value); - type = _nm_device_gtype_from_dtype (dtype); - } else { - g_warning ("%s: could not read properties for %s: %s", __func__, path, error->message); - g_error_free (error); - type = G_TYPE_INVALID; - } - - async_data->callback (type, async_data->user_data); - g_object_unref (proxy); - g_slice_free (NMDeviceAsyncData, async_data); -} - -static void -_nm_device_type_for_path_async (DBusGConnection *connection, - const char *path, - NMObjectTypeCallbackFunc callback, - gpointer user_data) -{ - NMDeviceAsyncData *async_data; - DBusGProxy *proxy; - - async_data = g_slice_new (NMDeviceAsyncData); - async_data->connection = connection; - async_data->callback = callback; - async_data->user_data = user_data; - - proxy = _nm_dbus_new_proxy_for_connection (connection, path, "org.freedesktop.DBus.Properties"); - dbus_g_proxy_begin_call (proxy, "Get", - async_got_type, async_data, NULL, - G_TYPE_STRING, NM_DBUS_INTERFACE_DEVICE, - G_TYPE_STRING, "DeviceType", - G_TYPE_INVALID); + return _nm_device_gtype_from_dtype (g_variant_get_uint32 (value)); } /** @@ -1183,20 +1081,14 @@ nm_device_get_autoconnect (NMDevice *device) void nm_device_set_autoconnect (NMDevice *device, gboolean autoconnect) { - GValue value = G_VALUE_INIT; - g_return_if_fail (NM_IS_DEVICE (device)); - g_value_init (&value, G_TYPE_BOOLEAN); - g_value_set_boolean (&value, autoconnect); - - NM_DEVICE_GET_PRIVATE (device)->autoconnect = autoconnect; _nm_object_set_property (NM_OBJECT (device), NM_DBUS_INTERFACE_DEVICE, "Autoconnect", - &value); + "b", autoconnect); } /** @@ -2004,28 +1896,24 @@ typedef struct { NMDevice *device; NMDeviceCallbackFn fn; gpointer user_data; - const char *method; } DeviceCallbackInfo; static void -device_operation_cb (DBusGProxy *proxy, - DBusGProxyCall *call, - gpointer user_data) +device_disconnect_cb (GObject *proxy, + GAsyncResult *result, + gpointer user_data) { DeviceCallbackInfo *info = user_data; GError *error = NULL; - dbus_g_proxy_end_call (proxy, call, &error, - G_TYPE_INVALID); + nmdbus_device_call_disconnect_finish (NMDBUS_DEVICE (proxy), result, &error); if (info->fn) info->fn (info->device, error, info->user_data); else if (error) { - g_warning ("%s: device %s %s failed: (%d) %s", + g_warning ("%s: device %s disconnect failed: %s", __func__, nm_object_get_path (NM_OBJECT (info->device)), - info->method, - error ? error->code : -1, - error && error->message ? error->message : "(unknown)"); + error->message); } g_clear_error (&error); @@ -2056,12 +1944,34 @@ nm_device_disconnect (NMDevice *device, info = g_slice_new (DeviceCallbackInfo); info->fn = callback; info->user_data = user_data; - info->method = "Disconnect"; info->device = g_object_ref (device); - dbus_g_proxy_begin_call (NM_DEVICE_GET_PRIVATE (device)->proxy, "Disconnect", - device_operation_cb, info, NULL, - G_TYPE_INVALID); + nmdbus_device_call_disconnect (NM_DEVICE_GET_PRIVATE (device)->proxy, + NULL, + device_disconnect_cb, info); +} + +static void +device_delete_cb (GObject *proxy, + GAsyncResult *result, + gpointer user_data) +{ + DeviceCallbackInfo *info = user_data; + GError *error = NULL; + + nmdbus_device_call_delete_finish (NMDBUS_DEVICE (proxy), result, &error); + if (info->fn) + info->fn (info->device, error, info->user_data); + else if (error) { + g_warning ("%s: device %s delete failed: %s", + __func__, + nm_object_get_path (NM_OBJECT (info->device)), + error->message); + } + g_clear_error (&error); + + g_object_unref (info->device); + g_slice_free (DeviceCallbackInfo, info); } /** @@ -2085,12 +1995,11 @@ nm_device_delete (NMDevice *device, info = g_slice_new (DeviceCallbackInfo); info->fn = callback; info->user_data = user_data; - info->method = "Delete"; info->device = g_object_ref (device); - dbus_g_proxy_begin_call (NM_DEVICE_GET_PRIVATE (device)->proxy, "Delete", - device_operation_cb, info, NULL, - G_TYPE_INVALID); + nmdbus_device_call_delete (NM_DEVICE_GET_PRIVATE (device)->proxy, + NULL, + device_delete_cb, info); } /** diff --git a/libnm/nm-dhcp4-config.c b/libnm/nm-dhcp4-config.c index 0782b23736..e012491dfa 100644 --- a/libnm/nm-dhcp4-config.c +++ b/libnm/nm-dhcp4-config.c @@ -31,8 +31,6 @@ G_DEFINE_TYPE (NMDhcp4Config, nm_dhcp4_config, NM_TYPE_OBJECT) #define NM_DHCP4_CONFIG_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_DHCP4_CONFIG, NMDhcp4ConfigPrivate)) typedef struct { - DBusGProxy *proxy; - GHashTable *options; } NMDhcp4ConfigPrivate; @@ -52,21 +50,19 @@ nm_dhcp4_config_init (NMDhcp4Config *config) } static gboolean -demarshal_dhcp4_options (NMObject *object, GParamSpec *pspec, GValue *value, gpointer field) +demarshal_dhcp4_options (NMObject *object, GParamSpec *pspec, GVariant *value, gpointer field) { NMDhcp4ConfigPrivate *priv = NM_DHCP4_CONFIG_GET_PRIVATE (object); - GHashTable *new_options; - GHashTableIter iter; + GVariantIter iter; const char *key; - GValue *opt; + GVariant *opt; g_hash_table_remove_all (priv->options); - new_options = g_value_get_boxed (value); - if (new_options) { - g_hash_table_iter_init (&iter, new_options); - while (g_hash_table_iter_next (&iter, (gpointer) &key, (gpointer) &opt)) - g_hash_table_insert (priv->options, g_strdup (key), g_value_dup_string (opt)); + g_variant_iter_init (&iter, value); + while (g_variant_iter_next (&iter, "{&sv}", &key, &opt)) { + g_hash_table_insert (priv->options, g_strdup (key), g_variant_dup_string (opt, NULL)); + g_variant_unref (opt); } _nm_object_queue_notify (object, NM_DHCP4_CONFIG_OPTIONS); @@ -84,9 +80,8 @@ init_dbus (NMObject *object) NM_OBJECT_CLASS (nm_dhcp4_config_parent_class)->init_dbus (object); - priv->proxy = _nm_object_new_proxy (object, NULL, NM_DBUS_INTERFACE_DHCP4_CONFIG); _nm_object_register_properties (object, - priv->proxy, + NM_DBUS_INTERFACE_DHCP4_CONFIG, property_info); } @@ -98,8 +93,6 @@ finalize (GObject *object) if (priv->options) g_hash_table_destroy (priv->options); - g_object_unref (priv->proxy); - G_OBJECT_CLASS (nm_dhcp4_config_parent_class)->finalize (object); } @@ -129,6 +122,8 @@ nm_dhcp4_config_class_init (NMDhcp4ConfigClass *config_class) g_type_class_add_private (config_class, sizeof (NMDhcp4ConfigPrivate)); + _nm_object_class_add_interface (nm_object_class, NM_DBUS_INTERFACE_DHCP4_CONFIG); + /* virtual methods */ object_class->get_property = get_property; object_class->finalize = finalize; diff --git a/libnm/nm-dhcp6-config.c b/libnm/nm-dhcp6-config.c index ffabb809e0..2dfdb59f27 100644 --- a/libnm/nm-dhcp6-config.c +++ b/libnm/nm-dhcp6-config.c @@ -31,8 +31,6 @@ G_DEFINE_TYPE (NMDhcp6Config, nm_dhcp6_config, NM_TYPE_OBJECT) #define NM_DHCP6_CONFIG_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_DHCP6_CONFIG, NMDhcp6ConfigPrivate)) typedef struct { - DBusGProxy *proxy; - GHashTable *options; } NMDhcp6ConfigPrivate; @@ -52,21 +50,19 @@ nm_dhcp6_config_init (NMDhcp6Config *config) } static gboolean -demarshal_dhcp6_options (NMObject *object, GParamSpec *pspec, GValue *value, gpointer field) +demarshal_dhcp6_options (NMObject *object, GParamSpec *pspec, GVariant *value, gpointer field) { NMDhcp6ConfigPrivate *priv = NM_DHCP6_CONFIG_GET_PRIVATE (object); - GHashTable *new_options; - GHashTableIter iter; + GVariantIter iter; const char *key; - GValue *opt; + GVariant *opt; g_hash_table_remove_all (priv->options); - new_options = g_value_get_boxed (value); - if (new_options) { - g_hash_table_iter_init (&iter, new_options); - while (g_hash_table_iter_next (&iter, (gpointer) &key, (gpointer) &opt)) - g_hash_table_insert (priv->options, g_strdup (key), g_value_dup_string (opt)); + g_variant_iter_init (&iter, value); + while (g_variant_iter_next (&iter, "{&sv}", &key, &opt)) { + g_hash_table_insert (priv->options, g_strdup (key), g_variant_dup_string (opt, NULL)); + g_variant_unref (opt); } _nm_object_queue_notify (object, NM_DHCP6_CONFIG_OPTIONS); @@ -84,9 +80,8 @@ init_dbus (NMObject *object) NM_OBJECT_CLASS (nm_dhcp6_config_parent_class)->init_dbus (object); - priv->proxy = _nm_object_new_proxy (object, NULL, NM_DBUS_INTERFACE_DHCP6_CONFIG); _nm_object_register_properties (object, - priv->proxy, + NM_DBUS_INTERFACE_DHCP6_CONFIG, property_info); } @@ -98,8 +93,6 @@ finalize (GObject *object) if (priv->options) g_hash_table_destroy (priv->options); - g_object_unref (priv->proxy); - G_OBJECT_CLASS (nm_dhcp6_config_parent_class)->finalize (object); } @@ -129,6 +122,8 @@ nm_dhcp6_config_class_init (NMDhcp6ConfigClass *config_class) g_type_class_add_private (config_class, sizeof (NMDhcp6ConfigPrivate)); + _nm_object_class_add_interface (nm_object_class, NM_DBUS_INTERFACE_DHCP6_CONFIG); + /* virtual methods */ object_class->get_property = get_property; object_class->finalize = finalize; diff --git a/libnm/nm-ip4-config.c b/libnm/nm-ip4-config.c index 77937c4699..ac3e5b36e9 100644 --- a/libnm/nm-ip4-config.c +++ b/libnm/nm-ip4-config.c @@ -33,11 +33,9 @@ G_DEFINE_TYPE (NMIP4Config, nm_ip4_config, NM_TYPE_OBJECT) #define NM_IP4_CONFIG_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_IP4_CONFIG, NMIP4ConfigPrivate)) typedef struct { - DBusGProxy *proxy; - char *gateway; - GSList *addresses; - GSList *routes; + GPtrArray *addresses; + GPtrArray *routes; char **nameservers; char **domains; char **searches; @@ -62,6 +60,8 @@ nm_ip4_config_init (NMIP4Config *config) { NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE (config); + priv->addresses = g_ptr_array_new (); + priv->routes = g_ptr_array_new (); priv->nameservers = g_new0 (char *, 1); priv->domains = g_new0 (char *, 1); priv->searches = g_new0 (char *, 1); @@ -69,58 +69,39 @@ nm_ip4_config_init (NMIP4Config *config) } static gboolean -demarshal_ip4_address_array (NMObject *object, GParamSpec *pspec, GValue *value, gpointer field) +demarshal_ip4_address_array (NMObject *object, GParamSpec *pspec, GVariant *value, gpointer field) { NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE (object); - g_slist_free_full (priv->addresses, (GDestroyNotify) nm_ip4_address_unref); - priv->addresses = NULL; - - priv->addresses = nm_utils_ip4_addresses_from_gvalue (value); + g_ptr_array_unref (priv->addresses); + priv->addresses = nm_utils_ip4_addresses_from_variant (value); _nm_object_queue_notify (object, NM_IP4_CONFIG_ADDRESSES); return TRUE; } static gboolean -demarshal_ip4_array (NMObject *object, GParamSpec *pspec, GValue *value, gpointer field) +demarshal_ip4_array (NMObject *object, GParamSpec *pspec, GVariant *value, gpointer field) { - GArray *ip_array; char ***obj_field; - int i; - - if (!G_VALUE_HOLDS (value, DBUS_TYPE_G_UINT_ARRAY)) - return FALSE; - - ip_array = g_value_get_boxed (value); obj_field = field; if (*obj_field) g_strfreev (*obj_field); - *obj_field = g_new (char *, ip_array->len + 1); - for (i = 0; i < ip_array->len; i++) { - guint32 ip = g_array_index (ip_array, guint32, i); - const char *str; - - str = nm_utils_inet4_ntop (ip, NULL); - (*obj_field)[i] = g_strdup (str); - } - (*obj_field)[i] = NULL; + *obj_field = nm_utils_ip4_dns_from_variant (value); _nm_object_queue_notify (object, pspec->name); return TRUE; } static gboolean -demarshal_ip4_routes_array (NMObject *object, GParamSpec *pspec, GValue *value, gpointer field) +demarshal_ip4_routes_array (NMObject *object, GParamSpec *pspec, GVariant *value, gpointer field) { NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE (object); - g_slist_free_full (priv->routes, (GDestroyNotify) nm_ip4_route_unref); - priv->routes = NULL; - - priv->routes = nm_utils_ip4_routes_from_gvalue (value); + g_ptr_array_unref (priv->routes); + priv->routes = nm_utils_ip4_routes_from_variant (value); _nm_object_queue_notify (object, NM_IP4_CONFIG_ROUTES); return TRUE; @@ -143,9 +124,8 @@ init_dbus (NMObject *object) NM_OBJECT_CLASS (nm_ip4_config_parent_class)->init_dbus (object); - priv->proxy = _nm_object_new_proxy (object, NULL, NM_DBUS_INTERFACE_IP4_CONFIG); _nm_object_register_properties (object, - priv->proxy, + NM_DBUS_INTERFACE_IP4_CONFIG, property_info); } @@ -156,16 +136,14 @@ finalize (GObject *object) g_free (priv->gateway); - g_slist_free_full (priv->addresses, (GDestroyNotify) nm_ip4_address_unref); - g_slist_free_full (priv->routes, (GDestroyNotify) nm_ip4_route_unref); + g_ptr_array_unref (priv->addresses); + g_ptr_array_unref (priv->routes); g_strfreev (priv->nameservers); g_strfreev (priv->domains); g_strfreev (priv->searches); g_strfreev (priv->wins); - g_object_unref (priv->proxy); - G_OBJECT_CLASS (nm_ip4_config_parent_class)->finalize (object); } @@ -176,21 +154,20 @@ get_property (GObject *object, GParamSpec *pspec) { NMIP4Config *self = NM_IP4_CONFIG (object); - NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE (self); switch (prop_id) { case PROP_GATEWAY: g_value_set_string (value, nm_ip4_config_get_gateway (self)); break; case PROP_ADDRESSES: - g_value_take_boxed (value, _nm_utils_copy_slist_to_array (priv->addresses, - (NMUtilsCopyFunc) nm_ip4_address_dup, - (GDestroyNotify) nm_ip4_address_unref)); + g_value_take_boxed (value, _nm_utils_copy_array (nm_ip4_config_get_addresses (self), + (NMUtilsCopyFunc) nm_ip4_address_dup, + (GDestroyNotify) nm_ip4_address_unref)); break; case PROP_ROUTES: - g_value_take_boxed (value, _nm_utils_copy_slist_to_array (priv->routes, - (NMUtilsCopyFunc) nm_ip4_route_dup, - (GDestroyNotify) nm_ip4_route_unref)); + g_value_take_boxed (value, _nm_utils_copy_array (nm_ip4_config_get_routes (self), + (NMUtilsCopyFunc) nm_ip4_route_dup, + (GDestroyNotify) nm_ip4_route_unref)); break; case PROP_NAMESERVERS: g_value_set_boxed (value, (char **) nm_ip4_config_get_nameservers (self)); @@ -218,6 +195,8 @@ nm_ip4_config_class_init (NMIP4ConfigClass *config_class) g_type_class_add_private (config_class, sizeof (NMIP4ConfigPrivate)); + _nm_object_class_add_interface (nm_object_class, NM_DBUS_INTERFACE_IP4_CONFIG); + /* virtual methods */ object_class->get_property = get_property; object_class->finalize = finalize; @@ -333,10 +312,11 @@ nm_ip4_config_get_gateway (NMIP4Config *config) * * Gets the IP4 addresses (containing the address, prefix, and gateway). * - * Returns: (element-type NMIP4Address) (transfer none): the #GSList containing #NMIP4Addresses. - * This is the internal copy used by the configuration and must not be modified. + * Returns: (element-type NMIP4Address) (transfer none): the #GPtrArray + * containing #NMIP4Addresses. This is the internal copy used by the + * configuration and must not be modified. **/ -const GSList * +GPtrArray * nm_ip4_config_get_addresses (NMIP4Config *config) { g_return_val_if_fail (NM_IS_IP4_CONFIG (config), NULL); @@ -418,11 +398,11 @@ nm_ip4_config_get_wins_servers (NMIP4Config *config) * * Gets the routes. * - * Returns: (element-type NMIP4Route) (transfer none): the #GSList containing - * #NMIP4Routes. This is the internal copy used by the configuration, - * and must not be modified. + * Returns: (element-type NMIP4Route) (transfer none): the #GPtrArray containing + * #NMIP4Routes. This is the internal copy used by the configuration, and must + * not be modified. **/ -const GSList * +GPtrArray * nm_ip4_config_get_routes (NMIP4Config *config) { g_return_val_if_fail (NM_IS_IP4_CONFIG (config), NULL); diff --git a/libnm/nm-ip4-config.h b/libnm/nm-ip4-config.h index c07ea7cc06..ce65fd8cbd 100644 --- a/libnm/nm-ip4-config.h +++ b/libnm/nm-ip4-config.h @@ -61,8 +61,8 @@ typedef struct { GType nm_ip4_config_get_type (void); const char * nm_ip4_config_get_gateway (NMIP4Config *config); -const GSList * nm_ip4_config_get_addresses (NMIP4Config *config); -const GSList * nm_ip4_config_get_routes (NMIP4Config *config); +GPtrArray * nm_ip4_config_get_addresses (NMIP4Config *config); +GPtrArray * nm_ip4_config_get_routes (NMIP4Config *config); const char * const *nm_ip4_config_get_nameservers (NMIP4Config *config); const char * const *nm_ip4_config_get_domains (NMIP4Config *config); const char * const *nm_ip4_config_get_searches (NMIP4Config *config); diff --git a/libnm/nm-ip6-config.c b/libnm/nm-ip6-config.c index 58cd42153b..8b48c15992 100644 --- a/libnm/nm-ip6-config.c +++ b/libnm/nm-ip6-config.c @@ -26,7 +26,6 @@ #include "nm-dbus-interface.h" #include "nm-object-private.h" #include "nm-utils.h" -#include "nm-dbus-glib-types.h" #include "nm-core-internal.h" G_DEFINE_TYPE (NMIP6Config, nm_ip6_config, NM_TYPE_OBJECT) @@ -34,11 +33,9 @@ G_DEFINE_TYPE (NMIP6Config, nm_ip6_config, NM_TYPE_OBJECT) #define NM_IP6_CONFIG_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_IP6_CONFIG, NMIP6ConfigPrivate)) typedef struct { - DBusGProxy *proxy; - char *gateway; - GSList *addresses; - GSList *routes; + GPtrArray *addresses; + GPtrArray *routes; char **nameservers; char **domains; char **searches; @@ -57,58 +54,39 @@ enum { }; static gboolean -demarshal_ip6_address_array (NMObject *object, GParamSpec *pspec, GValue *value, gpointer field) +demarshal_ip6_address_array (NMObject *object, GParamSpec *pspec, GVariant *value, gpointer field) { NMIP6ConfigPrivate *priv = NM_IP6_CONFIG_GET_PRIVATE (object); - g_slist_free_full (priv->addresses, (GDestroyNotify) nm_ip6_address_unref); - priv->addresses = NULL; - - priv->addresses = nm_utils_ip6_addresses_from_gvalue (value); + g_ptr_array_unref (priv->addresses); + priv->addresses = nm_utils_ip6_addresses_from_variant (value); _nm_object_queue_notify (object, NM_IP6_CONFIG_ADDRESSES); return TRUE; } static gboolean -demarshal_ip6_nameserver_array (NMObject *object, GParamSpec *pspec, GValue *value, gpointer field) +demarshal_ip6_nameserver_array (NMObject *object, GParamSpec *pspec, GVariant *value, gpointer field) { - GPtrArray *ip_array; char ***obj_field; - int i; - - if (!G_VALUE_HOLDS (value, DBUS_TYPE_G_ARRAY_OF_ARRAY_OF_UCHAR)) - return FALSE; - - ip_array = g_value_get_boxed (value); obj_field = field; if (*obj_field) g_strfreev (*obj_field); - *obj_field = g_new (char *, ip_array ? ip_array->len + 1 : 1); - for (i = 0; ip_array && i < ip_array->len; i++) { - GByteArray *ip = g_ptr_array_index (ip_array, i); - const char *str; - - str = nm_utils_inet6_ntop ((struct in6_addr *) ip->data, NULL); - (*obj_field)[i] = g_strdup (str); - } - (*obj_field)[i] = NULL; + *obj_field = nm_utils_ip6_dns_from_variant (value); _nm_object_queue_notify (object, pspec->name); return TRUE; } static gboolean -demarshal_ip6_routes_array (NMObject *object, GParamSpec *pspec, GValue *value, gpointer field) +demarshal_ip6_routes_array (NMObject *object, GParamSpec *pspec, GVariant *value, gpointer field) { NMIP6ConfigPrivate *priv = NM_IP6_CONFIG_GET_PRIVATE (object); - g_slist_free_full (priv->routes, (GDestroyNotify) nm_ip6_route_unref); - priv->routes = NULL; - - priv->routes = nm_utils_ip6_routes_from_gvalue (value); + g_ptr_array_unref (priv->routes); + priv->routes = nm_utils_ip6_routes_from_variant (value); _nm_object_queue_notify (object, NM_IP6_CONFIG_ROUTES); return TRUE; @@ -130,9 +108,8 @@ init_dbus (NMObject *object) NM_OBJECT_CLASS (nm_ip6_config_parent_class)->init_dbus (object); - priv->proxy = _nm_object_new_proxy (object, NULL, NM_DBUS_INTERFACE_IP6_CONFIG); _nm_object_register_properties (object, - priv->proxy, + NM_DBUS_INTERFACE_IP6_CONFIG, property_info); } @@ -158,11 +135,11 @@ nm_ip6_config_get_gateway (NMIP6Config *config) * * Gets the IP6 addresses (containing the address, prefix, and gateway). * - * Returns: (element-type NMIP6Address) (transfer none): the #GSList containing - * #NMIP6Addresses. This is the internal copy used by the configuration - * and must not be modified. + * Returns: (element-type NMIP6Address) (transfer none): the #GPtrArray + * containing #NMIP6Addresses. This is the internal copy used by the + * configuration and must not be modified. **/ -const GSList * +GPtrArray * nm_ip6_config_get_addresses (NMIP6Config *config) { g_return_val_if_fail (NM_IS_IP6_CONFIG (config), NULL); @@ -226,11 +203,11 @@ nm_ip6_config_get_searches (NMIP6Config *config) * * Gets the routes. * - * Returns: (element-type NMIP6Route): (transfer none): the #GSList containing - * #NMIP6Routes. This is the internal copy used by the configuration, - * and must not be modified. + * Returns: (element-type NMIP6Route) (transfer none): the #GPtrArray containing + * #NMIP6Routes. This is the internal copy used by the configuration, and must + * not be modified. **/ -const GSList * +GPtrArray * nm_ip6_config_get_routes (NMIP6Config *config) { g_return_val_if_fail (NM_IS_IP6_CONFIG (config), NULL); @@ -245,15 +222,13 @@ finalize (GObject *object) g_free (priv->gateway); - g_slist_free_full (priv->addresses, (GDestroyNotify) nm_ip6_address_unref); - g_slist_free_full (priv->routes, (GDestroyNotify) nm_ip6_route_unref); + g_ptr_array_unref (priv->addresses); + g_ptr_array_unref (priv->routes); g_strfreev (priv->nameservers); g_strfreev (priv->domains); g_strfreev (priv->searches); - g_object_unref (priv->proxy); - G_OBJECT_CLASS (nm_ip6_config_parent_class)->finalize (object); } @@ -264,21 +239,20 @@ get_property (GObject *object, GParamSpec *pspec) { NMIP6Config *self = NM_IP6_CONFIG (object); - NMIP6ConfigPrivate *priv = NM_IP6_CONFIG_GET_PRIVATE (self); switch (prop_id) { case PROP_GATEWAY: g_value_set_string (value, nm_ip6_config_get_gateway (self)); break; case PROP_ADDRESSES: - g_value_take_boxed (value, _nm_utils_copy_slist_to_array (priv->addresses, - (NMUtilsCopyFunc) nm_ip6_address_dup, - (GDestroyNotify) nm_ip6_address_unref)); + g_value_take_boxed (value, _nm_utils_copy_array (nm_ip6_config_get_addresses (self), + (NMUtilsCopyFunc) nm_ip6_address_dup, + (GDestroyNotify) nm_ip6_address_unref)); break; case PROP_ROUTES: - g_value_take_boxed (value, _nm_utils_copy_slist_to_array (priv->routes, - (NMUtilsCopyFunc) nm_ip6_route_dup, - (GDestroyNotify) nm_ip6_route_unref)); + g_value_take_boxed (value, _nm_utils_copy_array (nm_ip6_config_get_routes (self), + (NMUtilsCopyFunc) nm_ip6_route_dup, + (GDestroyNotify) nm_ip6_route_unref)); break; case PROP_NAMESERVERS: g_value_set_boxed (value, (char **) nm_ip6_config_get_nameservers (self)); @@ -300,6 +274,8 @@ nm_ip6_config_init (NMIP6Config *config) { NMIP6ConfigPrivate *priv = NM_IP6_CONFIG_GET_PRIVATE (config); + priv->addresses = g_ptr_array_new (); + priv->routes = g_ptr_array_new (); priv->nameservers = g_new0 (char *, 1); priv->domains = g_new0 (char *, 1); priv->searches = g_new0 (char *, 1); @@ -313,6 +289,8 @@ nm_ip6_config_class_init (NMIP6ConfigClass *config_class) g_type_class_add_private (config_class, sizeof (NMIP6ConfigPrivate)); + _nm_object_class_add_interface (nm_object_class, NM_DBUS_INTERFACE_IP6_CONFIG); + /* virtual methods */ object_class->get_property = get_property; object_class->finalize = finalize; diff --git a/libnm/nm-ip6-config.h b/libnm/nm-ip6-config.h index 52320005fd..385bfdf73e 100644 --- a/libnm/nm-ip6-config.h +++ b/libnm/nm-ip6-config.h @@ -60,8 +60,8 @@ typedef struct { GType nm_ip6_config_get_type (void); const char * nm_ip6_config_get_gateway (NMIP6Config *config); -const GSList * nm_ip6_config_get_addresses (NMIP6Config *config); -const GSList * nm_ip6_config_get_routes (NMIP6Config *config); +GPtrArray * nm_ip6_config_get_addresses (NMIP6Config *config); +GPtrArray * nm_ip6_config_get_routes (NMIP6Config *config); const char * const * nm_ip6_config_get_nameservers (NMIP6Config *config); const char * const * nm_ip6_config_get_domains (NMIP6Config *config); const char * const * nm_ip6_config_get_searches (NMIP6Config *config); diff --git a/libnm/nm-object-private.h b/libnm/nm-object-private.h index 111dc96b11..82e38f4d21 100644 --- a/libnm/nm-object-private.h +++ b/libnm/nm-object-private.h @@ -24,9 +24,9 @@ #include #include "nm-object.h" -typedef gboolean (*PropertyMarshalFunc) (NMObject *, GParamSpec *, GValue *, gpointer); +typedef gboolean (*PropertyMarshalFunc) (NMObject *, GParamSpec *, GVariant *, gpointer); -typedef GObject * (*NMObjectCreatorFunc) (DBusGConnection *, const char *); +typedef GObject * (*NMObjectCreatorFunc) (GDBusConnection *, const char *); typedef struct { const char *name; @@ -36,12 +36,8 @@ typedef struct { const char *signal_prefix; } NMPropertiesInfo; -DBusGProxy *_nm_object_new_proxy (NMObject *self, - const char *path, - const char *interface); - void _nm_object_register_properties (NMObject *object, - DBusGProxy *proxy, + const char *interface, const NMPropertiesInfo *info); gboolean _nm_object_reload_properties (NMObject *object, GError **error); @@ -66,17 +62,23 @@ void _nm_object_reload_property (NMObject *object, void _nm_object_set_property (NMObject *object, const char *interface, const char *prop_name, - GValue *value); + const char *format_string, + ...); /* object demarshalling support */ -typedef GType (*NMObjectTypeFunc) (DBusGConnection *, const char *); -typedef void (*NMObjectTypeCallbackFunc) (GType, gpointer); -typedef void (*NMObjectTypeAsyncFunc) (DBusGConnection *, const char *, NMObjectTypeCallbackFunc, gpointer); +typedef GType (*NMObjectDecideTypeFunc) (GVariant *); -void _nm_object_register_type_func (GType base_type, NMObjectTypeFunc type_func, - NMObjectTypeAsyncFunc type_async_func); +void _nm_object_register_type_func (GType base_type, + NMObjectDecideTypeFunc type_func, + const char *interface, + const char *property); #define NM_OBJECT_NM_RUNNING "nm-running-internal" gboolean _nm_object_get_nm_running (NMObject *self); +void _nm_object_class_add_interface (NMObjectClass *object_class, + const char *interface); +GDBusProxy *_nm_object_get_proxy (NMObject *object, + const char *interface); + #endif /* __NM_OBJECT_PRIVATE_H__ */ diff --git a/libnm/nm-object.c b/libnm/nm-object.c index 6f52321925..eef6128573 100644 --- a/libnm/nm-object.c +++ b/libnm/nm-object.c @@ -29,9 +29,8 @@ #include "nm-object.h" #include "nm-object-cache.h" #include "nm-object-private.h" -#include "nm-dbus-glib-types.h" #include "nm-glib-compat.h" -#include "nm-dbus-helpers-private.h" +#include "nm-dbus-helpers.h" static gboolean debug = FALSE; #define dbgmsg(f,...) if (G_UNLIKELY (debug)) { g_message (f, ## __VA_ARGS__ ); } @@ -39,11 +38,23 @@ static gboolean debug = FALSE; static void nm_object_initable_iface_init (GInitableIface *iface); static void nm_object_async_initable_iface_init (GAsyncInitableIface *iface); -static GHashTable *type_funcs, *type_async_funcs; +typedef struct { + NMObjectDecideTypeFunc type_func; + char *interface; + char *property; +} NMObjectTypeFuncData; + +static GHashTable *type_funcs; + +typedef struct { + GSList *interfaces; +} NMObjectClassPrivate; + +#define NM_OBJECT_CLASS_GET_PRIVATE(k) (G_TYPE_CLASS_GET_PRIVATE ((k), NM_TYPE_OBJECT, NMObjectClassPrivate)) G_DEFINE_ABSTRACT_TYPE_WITH_CODE (NMObject, nm_object, G_TYPE_OBJECT, type_funcs = g_hash_table_new (NULL, NULL); - type_async_funcs = g_hash_table_new (NULL, NULL); + g_type_add_class_private (g_define_type_id, sizeof (NMObjectClassPrivate)); G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE, nm_object_initable_iface_init); G_IMPLEMENT_INTERFACE (G_TYPE_ASYNC_INITABLE, nm_object_async_initable_iface_init); ) @@ -60,13 +71,13 @@ typedef struct { static void reload_complete (NMObject *object); typedef struct { - DBusGConnection *connection; - DBusGProxy *bus_proxy; + GDBusConnection *connection; + gboolean private_connection; gboolean nm_running; char *path; - DBusGProxy *properties_proxy; - GSList *property_interfaces; + GHashTable *proxies; + GDBusProxy *properties_proxy; GSList *property_tables; NMObject *parent; gboolean suppress_property_updates; @@ -113,20 +124,15 @@ nm_object_error_quark (void) } static void -proxy_name_owner_changed (DBusGProxy *proxy, - const char *name, - const char *old_owner, - const char *new_owner, - gpointer user_data) +on_name_owner_changed (GObject *proxy, + GParamSpec *pspec, + gpointer user_data) { NMObject *self = NM_OBJECT (user_data); NMObjectPrivate *priv = NM_OBJECT_GET_PRIVATE (self); gboolean now_running; - if (g_strcmp0 (name, NM_DBUS_SERVICE) != 0) - return; - - now_running = (new_owner && new_owner[0]); + now_running = (g_dbus_proxy_get_name_owner (priv->properties_proxy) != NULL); if (now_running != priv->nm_running) { priv->nm_running = now_running; g_object_notify (G_OBJECT (self), NM_OBJECT_NM_RUNNING); @@ -136,22 +142,9 @@ proxy_name_owner_changed (DBusGProxy *proxy, static void nm_object_init (NMObject *object) { -} + NMObjectPrivate *priv = NM_OBJECT_GET_PRIVATE (object); -static gboolean -init_common (NMObject *self, GError **error) -{ - NMObjectPrivate *priv = NM_OBJECT_GET_PRIVATE (self); - - if (!priv->path) { - g_set_error_literal (error, NM_OBJECT_ERROR, NM_OBJECT_ERROR_OBJECT_CREATION_FAILURE, - _("Caller did not specify D-Bus path for object")); - return FALSE; - } - - NM_OBJECT_GET_CLASS (self)->init_dbus (self); - - return TRUE; + priv->proxies = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, g_object_unref); } static void @@ -159,24 +152,12 @@ init_dbus (NMObject *object) { NMObjectPrivate *priv = NM_OBJECT_GET_PRIVATE (object); - priv->properties_proxy = _nm_object_new_proxy (object, NULL, "org.freedesktop.DBus.Properties"); - if (_nm_dbus_is_connection_private (priv->connection)) priv->nm_running = TRUE; else { - priv->bus_proxy = dbus_g_proxy_new_for_name (priv->connection, - DBUS_SERVICE_DBUS, - DBUS_PATH_DBUS, - DBUS_INTERFACE_DBUS); - g_assert (priv->bus_proxy); - - dbus_g_proxy_add_signal (priv->bus_proxy, "NameOwnerChanged", - G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, - G_TYPE_INVALID); - dbus_g_proxy_connect_signal (priv->bus_proxy, - "NameOwnerChanged", - G_CALLBACK (proxy_name_owner_changed), - object, NULL); + priv->nm_running = (g_dbus_proxy_get_name_owner (priv->properties_proxy) != NULL); + g_signal_connect (priv->properties_proxy, "notify::g-name-owner", + G_CALLBACK (on_name_owner_changed), object); } } @@ -185,72 +166,137 @@ init_sync (GInitable *initable, GCancellable *cancellable, GError **error) { NMObject *self = NM_OBJECT (initable); NMObjectPrivate *priv = NM_OBJECT_GET_PRIVATE (self); + NMObjectClassPrivate *cpriv = NM_OBJECT_CLASS_GET_PRIVATE (NM_OBJECT_GET_CLASS (self)); + GSList *iter; - priv->connection = _nm_dbus_new_connection (error); + if (!priv->path) { + g_set_error_literal (error, NM_OBJECT_ERROR, NM_OBJECT_ERROR_OBJECT_CREATION_FAILURE, + _("Caller did not specify D-Bus path for object")); + return FALSE; + } + + priv->connection = _nm_dbus_new_connection (cancellable, error); if (!priv->connection) return FALSE; - if (!init_common (self, error)) + + /* Create proxies */ + for (iter = cpriv->interfaces; iter; iter = iter->next) { + const char *interface = iter->data; + GDBusProxy *proxy; + + proxy = _nm_dbus_new_proxy_for_connection (priv->connection, priv->path, interface, + cancellable, error); + if (!proxy) + return FALSE; + g_hash_table_insert (priv->proxies, (char *) interface, proxy); + } + + priv->properties_proxy = _nm_dbus_new_proxy_for_connection (priv->connection, + priv->path, + DBUS_INTERFACE_PROPERTIES, + cancellable, error); + if (!priv->properties_proxy) return FALSE; - if (priv->bus_proxy) { - if (!dbus_g_proxy_call (priv->bus_proxy, - "NameHasOwner", error, - G_TYPE_STRING, NM_DBUS_SERVICE, - G_TYPE_INVALID, - G_TYPE_BOOLEAN, &priv->nm_running, - G_TYPE_INVALID)) - return FALSE; - } + NM_OBJECT_GET_CLASS (self)->init_dbus (self); return _nm_object_reload_properties (self, error); } -/* Takes ownership of @error */ +typedef struct { + NMObject *object; + GSimpleAsyncResult *simple; + GCancellable *cancellable; + int proxies_pending; + GError *error; +} NMObjectInitData; + static void -init_async_complete (GSimpleAsyncResult *simple, GError *error) +init_async_complete (NMObjectInitData *init_data) { - if (error) - g_simple_async_result_take_error (simple, error); + if (init_data->error) + g_simple_async_result_take_error (init_data->simple, init_data->error); else - g_simple_async_result_set_op_res_gboolean (simple, TRUE); - g_simple_async_result_complete (simple); - g_object_unref (simple); + g_simple_async_result_set_op_res_gboolean (init_data->simple, TRUE); + g_simple_async_result_complete (init_data->simple); + g_object_unref (init_data->simple); + g_clear_object (&init_data->cancellable); + g_slice_free (NMObjectInitData, init_data); } static void init_async_got_properties (GObject *object, GAsyncResult *result, gpointer user_data) { - GSimpleAsyncResult *simple = user_data; - GError *error = NULL; + NMObjectInitData *init_data = user_data; - if (!_nm_object_reload_properties_finish (NM_OBJECT (object), result, &error)) - g_assert (error); - init_async_complete (simple, error); + _nm_object_reload_properties_finish (NM_OBJECT (object), result, &init_data->error); + init_async_complete (init_data); } static void -init_async_got_nm_running (DBusGProxy *proxy, DBusGProxyCall *call, - gpointer user_data) +init_async_got_proxy (GObject *object, GAsyncResult *result, gpointer user_data) { - GSimpleAsyncResult *simple = user_data; - NMObject *self; - NMObjectPrivate *priv; - GError *error = NULL; + NMObjectInitData *init_data = user_data; + NMObject *self = init_data->object; + NMObjectPrivate *priv = NM_OBJECT_GET_PRIVATE (self); + GDBusProxy *proxy; - self = NM_OBJECT (g_async_result_get_source_object (G_ASYNC_RESULT (simple))); - priv = NM_OBJECT_GET_PRIVATE (self); + if (!init_data->error) { + proxy = _nm_dbus_new_proxy_for_connection_finish (result, &init_data->error); + if (proxy) { + const char *interface = g_dbus_proxy_get_interface_name (proxy); - if (!dbus_g_proxy_end_call (proxy, call, &error, - G_TYPE_BOOLEAN, &priv->nm_running, - G_TYPE_INVALID)) { - init_async_complete (simple, error); - } else if (!priv->nm_running) - init_async_complete (simple, NULL); - else - _nm_object_reload_properties_async (self, init_async_got_properties, simple); + if (!strcmp (interface, DBUS_INTERFACE_PROPERTIES)) + priv->properties_proxy = proxy; + else + g_hash_table_insert (priv->proxies, (char *) interface, proxy); + } + } - /* g_async_result_get_source_object() adds a ref */ - g_object_unref (self); + init_data->proxies_pending--; + if (init_data->proxies_pending) + return; + + if (init_data->error) { + init_async_complete (init_data); + return; + } + + NM_OBJECT_GET_CLASS (self)->init_dbus (self); + + _nm_object_reload_properties_async (init_data->object, init_async_got_properties, init_data); +} + +static void +init_async_got_bus (GObject *object, GAsyncResult *result, gpointer user_data) +{ + NMObjectInitData *init_data = user_data; + NMObjectPrivate *priv = NM_OBJECT_GET_PRIVATE (init_data->object); + NMObjectClassPrivate *cpriv = NM_OBJECT_CLASS_GET_PRIVATE (NM_OBJECT_GET_CLASS (init_data->object)); + GSList *iter; + + priv->connection = _nm_dbus_new_connection_finish (result, &init_data->error); + if (!priv->connection) { + init_async_complete (init_data); + return; + } + + for (iter = cpriv->interfaces; iter; iter = iter->next) { + const char *interface = iter->data; + + _nm_dbus_new_proxy_for_connection_async (priv->connection, + priv->path, interface, + init_data->cancellable, + init_async_got_proxy, init_data); + init_data->proxies_pending++; + } + + _nm_dbus_new_proxy_for_connection_async (priv->connection, + priv->path, + DBUS_INTERFACE_PROPERTIES, + init_data->cancellable, + init_async_got_proxy, init_data); + init_data->proxies_pending++; } static void @@ -260,34 +306,24 @@ init_async (GAsyncInitable *initable, int io_priority, { NMObject *self = NM_OBJECT (initable); NMObjectPrivate *priv = NM_OBJECT_GET_PRIVATE (self); - GSimpleAsyncResult *simple; - GError *error = NULL; + NMObjectInitData *init_data; - simple = g_simple_async_result_new (G_OBJECT (initable), callback, user_data, init_async); - - priv->connection = _nm_dbus_new_connection (&error); - if (!priv->connection) { - g_simple_async_result_take_error (simple, error); - g_simple_async_result_complete_in_idle (simple); - g_object_unref (simple); - return; - } - if (!init_common (self, &error)) { - g_simple_async_result_take_error (simple, error); - g_simple_async_result_complete_in_idle (simple); - g_object_unref (simple); + if (!priv->path) { + g_simple_async_report_error_in_idle (G_OBJECT (initable), + callback, user_data, + NM_OBJECT_ERROR, + NM_OBJECT_ERROR_OBJECT_CREATION_FAILURE, + "%s", + _("Caller did not specify D-Bus path for object")); return; } - if (priv->bus_proxy) { - /* Check if NM is running */ - dbus_g_proxy_begin_call (priv->bus_proxy, "NameHasOwner", - init_async_got_nm_running, - simple, NULL, - G_TYPE_STRING, NM_DBUS_SERVICE, - G_TYPE_INVALID); - } else - _nm_object_reload_properties_async (self, init_async_got_properties, simple); + init_data = g_slice_new0 (NMObjectInitData); + init_data->object = self; + init_data->simple = g_simple_async_result_new (G_OBJECT (initable), callback, user_data, init_async); + init_data->cancellable = cancellable ? g_object_ref (cancellable) : NULL; + + _nm_dbus_new_connection_async (cancellable, init_async_got_bus, init_data); } static gboolean @@ -314,16 +350,10 @@ dispose (GObject *object) g_slist_free_full (priv->notify_props, g_free); priv->notify_props = NULL; - g_slist_free_full (priv->property_interfaces, g_free); - priv->property_interfaces = NULL; - + g_clear_pointer (&priv->proxies, g_hash_table_unref); g_clear_object (&priv->properties_proxy); - g_clear_object (&priv->bus_proxy); - if (priv->connection) { - dbus_g_connection_unref (priv->connection); - priv->connection = NULL; - } + g_clear_object (&priv->connection); G_OBJECT_CLASS (nm_object_parent_class)->dispose (object); } @@ -453,6 +483,28 @@ nm_object_async_initable_iface_init (GAsyncInitableIface *iface) iface->init_finish = init_finish; } +/** + * _nm_object_class_add_interface: + * @object_class: an #NMObjectClass + * @interface: a D-Bus interface name + * + * Registers that @object_class implements @interface. A proxy for that + * interface will automatically be created at construction time, and can + * be retrieved with _nm_object_get_proxy(). + */ +void +_nm_object_class_add_interface (NMObjectClass *object_class, + const char *interface) +{ + NMObjectClassPrivate *cpriv; + + g_return_if_fail (NM_IS_OBJECT_CLASS (object_class)); + + cpriv = NM_OBJECT_CLASS_GET_PRIVATE (object_class); + + cpriv->interfaces = g_slist_prepend (cpriv->interfaces, g_strdup (interface)); +} + /** * nm_object_get_path: * @object: a #NMObject @@ -470,6 +522,28 @@ nm_object_get_path (NMObject *object) return NM_OBJECT_GET_PRIVATE (object)->path; } +/** + * _nm_object_get_proxy: + * @object: an #NMObject + * @interface: a D-Bus interface implemented by @object + * + * Gets the D-Bus proxy for @interface on @object. + * + * Returns: (transfer none): a D-Bus proxy + */ +GDBusProxy * +_nm_object_get_proxy (NMObject *object, + const char *interface) +{ + GDBusProxy *proxy; + + g_return_val_if_fail (NM_IS_OBJECT (object), NULL); + + proxy = g_hash_table_lookup (NM_OBJECT_GET_PRIVATE (object)->proxies, interface); + g_return_val_if_fail (proxy != NULL, NULL); + return proxy; +} + static gboolean deferred_notify_cb (gpointer data) { @@ -524,27 +598,68 @@ _nm_object_queue_notify (NMObject *object, const char *property) } void -_nm_object_register_type_func (GType base_type, NMObjectTypeFunc type_func, - NMObjectTypeAsyncFunc type_async_func) +_nm_object_register_type_func (GType base_type, + NMObjectDecideTypeFunc type_func, + const char *interface, + const char *property) { + NMObjectTypeFuncData *type_data; + + g_return_if_fail (type_func != NULL); + g_return_if_fail (interface != NULL); + g_return_if_fail (property != NULL); + + type_data = g_slice_new (NMObjectTypeFuncData); + type_data->type_func = type_func; + type_data->interface = g_strdup (interface); + type_data->property = g_strdup (property); + g_hash_table_insert (type_funcs, GSIZE_TO_POINTER (base_type), - type_func); - g_hash_table_insert (type_async_funcs, - GSIZE_TO_POINTER (base_type), - type_async_func); + type_data); } static GObject * -_nm_object_create (GType type, DBusGConnection *connection, const char *path) +_nm_object_create (GType type, GDBusConnection *connection, const char *path) { - NMObjectTypeFunc type_func; + NMObjectTypeFuncData *type_data; GObject *object; GError *error = NULL; - type_func = g_hash_table_lookup (type_funcs, GSIZE_TO_POINTER (type)); - if (type_func) - type = type_func (connection, path); + type_data = g_hash_table_lookup (type_funcs, GSIZE_TO_POINTER (type)); + if (type_data) { + GDBusProxy *proxy; + GVariant *ret, *value; + + proxy = _nm_dbus_new_proxy_for_connection (connection, path, + DBUS_INTERFACE_PROPERTIES, + NULL, &error); + if (!proxy) { + g_warning ("Could not create proxy for %s: %s.", path, error->message); + g_error_free (error); + return G_TYPE_INVALID; + } + + ret = g_dbus_proxy_call_sync (proxy, + "Get", + g_variant_new ("(ss)", + type_data->interface, + type_data->property), + G_DBUS_CALL_FLAGS_NONE, -1, + NULL, &error); + g_object_unref (proxy); + if (!ret) { + g_warning ("Could not fetch property '%s' of interface '%s' on %s: %s\n", + type_data->property, type_data->interface, path, error->message); + g_error_free (error); + return G_TYPE_INVALID; + } + + g_variant_get (ret, "(v)", &value); + type = type_data->type_func (value); + g_variant_unref (value); + g_variant_unref (ret); + } if (type == G_TYPE_INVALID) { dbgmsg ("Could not create object for %s: unknown object type", path); @@ -576,6 +691,7 @@ typedef struct { char *path; NMObjectCreateCallbackFunc callback; gpointer user_data; + NMObjectTypeFuncData *type_data; } NMObjectTypeAsyncData; static void @@ -588,7 +704,7 @@ create_async_complete (GObject *object, NMObjectTypeAsyncData *async_data) } static void -async_inited (GObject *object, GAsyncResult *result, gpointer user_data) +create_async_inited (GObject *object, GAsyncResult *result, gpointer user_data) { NMObjectTypeAsyncData *async_data = user_data; GError *error = NULL; @@ -619,9 +735,8 @@ async_inited (GObject *object, GAsyncResult *result, gpointer user_data) } static void -async_got_type (GType type, gpointer user_data) +create_async_got_type (NMObjectTypeAsyncData *async_data, GType type) { - NMObjectTypeAsyncData *async_data = user_data; GObject *object; if (type == G_TYPE_INVALID) { @@ -634,15 +749,64 @@ async_got_type (GType type, gpointer user_data) NM_OBJECT_PATH, async_data->path, NULL); g_async_initable_init_async (G_ASYNC_INITABLE (object), G_PRIORITY_DEFAULT, - NULL, async_inited, async_data); + NULL, create_async_inited, async_data); } static void -_nm_object_create_async (GType type, DBusGConnection *connection, const char *path, +create_async_got_property (GObject *proxy, GAsyncResult *result, gpointer user_data) +{ + NMObjectTypeAsyncData *async_data = user_data; + NMObjectTypeFuncData *type_data = async_data->type_data; + GVariant *ret, *value; + GError *error = NULL; + GType type; + + ret = g_dbus_proxy_call_finish (G_DBUS_PROXY (proxy), result, &error); + if (ret) { + g_variant_get (ret, "(v)", &value); + type = type_data->type_func (value); + g_variant_unref (value); + g_variant_unref (ret); + } else { + g_warning ("Could not fetch property '%s' of interface '%s' on %s: %s\n", + type_data->property, type_data->interface, async_data->path, + error->message); + g_clear_error (&error); + type = G_TYPE_INVALID; + } + + create_async_got_type (async_data, type); +} + +static void +create_async_got_proxy (GObject *object, GAsyncResult *result, gpointer user_data) +{ + NMObjectTypeAsyncData *async_data = user_data; + GDBusProxy *proxy; + GError *error = NULL; + + proxy = _nm_dbus_new_proxy_for_connection_finish (result, &error); + if (!proxy) { + g_warning ("Could not create proxy for %s: %s.", async_data->path, error->message); + g_error_free (error); + create_async_complete (NULL, async_data); + return; + } + + g_dbus_proxy_call (proxy, + "Get", + g_variant_new ("(ss)", + async_data->type_data->interface, + async_data->type_data->property), + G_DBUS_CALL_FLAGS_NONE, -1, + NULL, + create_async_got_property, async_data); +} + +static void +_nm_object_create_async (GType type, GDBusConnection *connection, const char *path, NMObjectCreateCallbackFunc callback, gpointer user_data) { - NMObjectTypeAsyncFunc type_async_func; - NMObjectTypeFunc type_func; NMObjectTypeAsyncData *async_data; async_data = g_slice_new (NMObjectTypeAsyncData); @@ -650,17 +814,16 @@ _nm_object_create_async (GType type, DBusGConnection *connection, const char *pa async_data->callback = callback; async_data->user_data = user_data; - type_async_func = g_hash_table_lookup (type_async_funcs, GSIZE_TO_POINTER (type)); - if (type_async_func) { - type_async_func (connection, path, async_got_type, async_data); + async_data->type_data = g_hash_table_lookup (type_funcs, GSIZE_TO_POINTER (type)); + if (async_data->type_data) { + _nm_dbus_new_proxy_for_connection_async (connection, path, + DBUS_INTERFACE_PROPERTIES, + NULL, + create_async_got_proxy, async_data); return; } - type_func = g_hash_table_lookup (type_funcs, GSIZE_TO_POINTER (type)); - if (type_func) - type = type_func (connection, path); - - async_got_type (type, async_data); + create_async_got_type (async_data, type); } /* Stolen from dbus-glib */ @@ -863,7 +1026,7 @@ object_created (GObject *obj, const char *path, gpointer user_data) } static gboolean -handle_object_property (NMObject *self, const char *property_name, GValue *value, +handle_object_property (NMObject *self, const char *property_name, GVariant *value, PropertyInfo *pi, gboolean synchronously) { NMObjectPrivate *priv = NM_OBJECT_GET_PRIVATE (self); @@ -882,7 +1045,7 @@ handle_object_property (NMObject *self, const char *property_name, GValue *value if (priv->reload_results) priv->reload_remaining++; - path = g_value_get_boxed (value); + path = g_variant_get_string (value, NULL); if (!strcmp (path, "/")) { object_created (NULL, path, odata); @@ -906,37 +1069,37 @@ handle_object_property (NMObject *self, const char *property_name, GValue *value } static gboolean -handle_object_array_property (NMObject *self, const char *property_name, GValue *value, +handle_object_array_property (NMObject *self, const char *property_name, GVariant *value, PropertyInfo *pi, gboolean synchronously) { NMObjectPrivate *priv = NM_OBJECT_GET_PRIVATE (self); GObject *obj; - GPtrArray *paths; + GVariantIter iter; + gsize npaths; GPtrArray **array = pi->field; const char *path; ObjectCreatedData *odata; - int i; - paths = g_value_get_boxed (value); + npaths = g_variant_n_children (value); odata = g_slice_new (ObjectCreatedData); odata->self = g_object_ref (self); odata->pi = pi; - odata->objects = g_new0 (GObject *, paths->len); - odata->length = odata->remaining = paths->len; + odata->objects = g_new0 (GObject *, npaths); + odata->length = odata->remaining = npaths; odata->array = TRUE; odata->property_name = property_name; if (priv->reload_results) priv->reload_remaining++; - if (paths->len == 0) { + if (npaths == 0) { object_property_complete (odata); return TRUE; } - for (i = 0; i < paths->len; i++) { - path = paths->pdata[i]; + g_variant_iter_init (&iter, value); + while (g_variant_iter_next (&iter, "&o", &path)) { if (!strcmp (path, "/")) { /* FIXME: can't happen? */ continue; @@ -959,11 +1122,12 @@ handle_object_array_property (NMObject *self, const char *property_name, GValue return TRUE; } - return *array && ((*array)->len == paths->len); + return *array && ((*array)->len == npaths); } static void -handle_property_changed (NMObject *self, const char *dbus_name, GValue *value, gboolean synchronously) +handle_property_changed (NMObject *self, const char *dbus_name, + GVariant *value, gboolean synchronously) { NMObjectPrivate *priv = NM_OBJECT_GET_PRIVATE (self); char *prop_name; @@ -1004,7 +1168,7 @@ handle_property_changed (NMObject *self, const char *dbus_name, GValue *value, g if (G_UNLIKELY (debug)) { char *s; - s = g_strdup_value_contents (value); + s = g_variant_print (value, FALSE); dbgmsg ("PC: (%p) %s::%s => '%s' (%s%s%s)", self, G_OBJECT_TYPE_NAME (self), prop_name, @@ -1016,9 +1180,9 @@ handle_property_changed (NMObject *self, const char *dbus_name, GValue *value, g } if (pi->object_type) { - if (G_VALUE_HOLDS (value, DBUS_TYPE_G_OBJECT_PATH)) + if (g_variant_is_of_type (value, G_VARIANT_TYPE_OBJECT_PATH)) success = handle_object_property (self, pspec->name, value, pi, synchronously); - else if (G_VALUE_HOLDS (value, DBUS_TYPE_G_ARRAY_OF_OBJECT_PATH)) + else if (g_variant_is_of_type (value, G_VARIANT_TYPE ("ao"))) success = handle_object_array_property (self, pspec->name, value, pi, synchronously); else { g_warn_if_reached (); @@ -1039,39 +1203,43 @@ out: } static void -process_properties_changed (NMObject *self, GHashTable *properties, gboolean synchronously) +process_properties_changed (NMObject *self, GVariant *properties, gboolean synchronously) { NMObjectPrivate *priv = NM_OBJECT_GET_PRIVATE (self); - GHashTableIter iter; - gpointer name, value; + GVariantIter iter; + const char *name; + GVariant *value; if (priv->suppress_property_updates) return; - g_hash_table_iter_init (&iter, properties); - while (g_hash_table_iter_next (&iter, &name, &value)) { - if (value) - handle_property_changed (self, name, value, synchronously); - else { - dbgmsg ("%s:%d %s(): object %s property '%s' value is unexpectedly NULL", - __FILE__, __LINE__, __func__, G_OBJECT_TYPE_NAME (self), (const char *) name); - } - } + g_variant_iter_init (&iter, properties); + while (g_variant_iter_next (&iter, "{sv}", &name, &value)) + handle_property_changed (self, name, value, synchronously); } static void -properties_changed_proxy (DBusGProxy *proxy, - GHashTable *properties, - gpointer user_data) +property_proxy_signal (GDBusProxy *proxy, + const char *sender_name, + const char *signal_name, + GVariant *parameters, + gpointer user_data) { + GVariant *properties; + + if (strcmp (signal_name, "PropertiesChanged") != 0) + return; + + g_variant_get (parameters, "(@a{sv})", &properties); process_properties_changed (NM_OBJECT (user_data), properties, FALSE); + g_variant_unref (properties); } -#define HANDLE_TYPE(ucase, lcase, getter) \ - } else if (pspec->value_type == G_TYPE_##ucase) { \ - if (G_VALUE_HOLDS_##ucase (value)) { \ - g##lcase *param = (g##lcase *) field; \ - *param = g_value_get_##getter (value); \ +#define HANDLE_TYPE(gtype, vtype, ctype, getter) \ + } else if (pspec->value_type == gtype) { \ + if (g_variant_is_of_type (value, vtype)) { \ + ctype *param = (ctype *) field; \ + *param = getter (value); \ } else { \ success = FALSE; \ goto done; \ @@ -1080,20 +1248,20 @@ properties_changed_proxy (DBusGProxy *proxy, static gboolean demarshal_generic (NMObject *object, GParamSpec *pspec, - GValue *value, + GVariant *value, gpointer field) { gboolean success = TRUE; if (pspec->value_type == G_TYPE_STRING) { - if (G_VALUE_HOLDS_STRING (value)) { + if (g_variant_is_of_type (value, G_VARIANT_TYPE_STRING)) { char **param = (char **) field; g_free (*param); - *param = g_value_dup_string (value); - } else if (G_VALUE_HOLDS (value, DBUS_TYPE_G_OBJECT_PATH)) { + *param = g_variant_dup_string (value, NULL); + } else if (g_variant_is_of_type (value, G_VARIANT_TYPE_OBJECT_PATH)) { char **param = (char **) field; g_free (*param); - *param = g_strdup (g_value_get_boxed (value)); + *param = g_variant_dup_string (value, NULL); /* Handle "NULL" object paths */ if (g_strcmp0 (*param, "/") == 0) { g_free (*param); @@ -1107,24 +1275,28 @@ demarshal_generic (NMObject *object, char ***param = (char ***)field; if (*param) g_strfreev (*param); - *param = g_value_dup_boxed (value); + *param = g_variant_dup_strv (value, NULL); } else if (pspec->value_type == G_TYPE_BYTES) { GBytes **param = (GBytes **)field; - GByteArray *val; + gconstpointer val; + gsize length; + if (*param) g_bytes_unref (*param); - val = g_value_get_boxed (value); - *param = g_bytes_new (val->data, val->len); - HANDLE_TYPE(BOOLEAN, boolean, boolean) - HANDLE_TYPE(CHAR, char, schar) - HANDLE_TYPE(UCHAR, uchar, uchar) - HANDLE_TYPE(DOUBLE, double, double) - HANDLE_TYPE(INT, int, int) - HANDLE_TYPE(UINT, uint, uint) - HANDLE_TYPE(INT64, int, int) - HANDLE_TYPE(UINT64, uint, uint) - HANDLE_TYPE(LONG, long, long) - HANDLE_TYPE(ULONG, ulong, ulong) + val = g_variant_get_fixed_array (value, &length, 1); + if (length) + *param = g_bytes_new (val, length); + else + *param = NULL; + HANDLE_TYPE (G_TYPE_BOOLEAN, G_VARIANT_TYPE_BOOLEAN, gboolean, g_variant_get_boolean) + HANDLE_TYPE (G_TYPE_UCHAR, G_VARIANT_TYPE_BYTE, guchar, g_variant_get_byte) + HANDLE_TYPE (G_TYPE_DOUBLE, G_VARIANT_TYPE_DOUBLE, gdouble, g_variant_get_double) + HANDLE_TYPE (G_TYPE_INT, G_VARIANT_TYPE_INT32, gint, g_variant_get_int32) + HANDLE_TYPE (G_TYPE_UINT, G_VARIANT_TYPE_UINT32, guint, g_variant_get_uint32) + HANDLE_TYPE (G_TYPE_INT64, G_VARIANT_TYPE_INT64, gint, g_variant_get_int64) + HANDLE_TYPE (G_TYPE_UINT64, G_VARIANT_TYPE_UINT64, guint, g_variant_get_uint64) + HANDLE_TYPE (G_TYPE_LONG, G_VARIANT_TYPE_INT64, glong, g_variant_get_int64) + HANDLE_TYPE (G_TYPE_ULONG, G_VARIANT_TYPE_UINT64, gulong, g_variant_get_uint64) } else { dbgmsg ("%s: %s/%s unhandled type %s.", __func__, @@ -1147,17 +1319,18 @@ done: void _nm_object_register_properties (NMObject *object, - DBusGProxy *proxy, + const char *interface, const NMPropertiesInfo *info) { NMObjectPrivate *priv = NM_OBJECT_GET_PRIVATE (object); + GDBusProxy *proxy; static gsize dval = 0; const char *debugstr; NMPropertiesInfo *tmp; GHashTable *instance; g_return_if_fail (NM_IS_OBJECT (object)); - g_return_if_fail (proxy != NULL); + g_return_if_fail (interface != NULL); g_return_if_fail (info != NULL); if (g_once_init_enter (&dval)) { @@ -1167,15 +1340,11 @@ _nm_object_register_properties (NMObject *object, g_once_init_leave (&dval, 1); } - priv->property_interfaces = g_slist_prepend (priv->property_interfaces, - g_strdup (dbus_g_proxy_get_interface (proxy))); + proxy = _nm_object_get_proxy (object, interface); + g_return_if_fail (proxy != NULL); - dbus_g_proxy_add_signal (proxy, "PropertiesChanged", DBUS_TYPE_G_MAP_OF_VARIANT, G_TYPE_INVALID); - dbus_g_proxy_connect_signal (proxy, - "PropertiesChanged", - G_CALLBACK (properties_changed_proxy), - object, - NULL); + g_signal_connect (proxy, "g-signal", + G_CALLBACK (property_proxy_signal), object); instance = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free); priv->property_tables = g_slist_prepend (priv->property_tables, instance); @@ -1201,22 +1370,28 @@ gboolean _nm_object_reload_properties (NMObject *object, GError **error) { NMObjectPrivate *priv = NM_OBJECT_GET_PRIVATE (object); - GHashTable *props = NULL; - GSList *p; + GVariant *ret, *props; + GHashTableIter iter; + const char *interface; + GDBusProxy *proxy; - if (!priv->property_interfaces || !priv->nm_running) + if (!g_hash_table_size (priv->proxies) || !priv->nm_running) return TRUE; - for (p = priv->property_interfaces; p; p = p->next) { - if (!dbus_g_proxy_call (priv->properties_proxy, "GetAll", error, - G_TYPE_STRING, p->data, - G_TYPE_INVALID, - DBUS_TYPE_G_MAP_OF_VARIANT, &props, - G_TYPE_INVALID)) + g_hash_table_iter_init (&iter, priv->proxies); + while (g_hash_table_iter_next (&iter, (gpointer *) &interface, (gpointer *) &proxy)) { + ret = g_dbus_proxy_call_sync (priv->properties_proxy, + "GetAll", + g_variant_new ("(s)", interface), + G_DBUS_CALL_FLAGS_NONE, -1, + NULL, error); + if (!ret) return FALSE; + g_variant_get (ret, "(@a{sv})", &props); process_properties_changed (object, props, TRUE); - g_hash_table_destroy (props); + g_variant_unref (props); + g_variant_unref (ret); } return TRUE; @@ -1236,7 +1411,7 @@ _nm_object_reload_property (NMObject *object, const char *interface, const char *prop_name) { - GValue value = G_VALUE_INIT; + GVariant *ret, *value; GError *err = NULL; g_return_if_fail (NM_IS_OBJECT (object)); @@ -1246,13 +1421,12 @@ _nm_object_reload_property (NMObject *object, if (!NM_OBJECT_GET_PRIVATE (object)->nm_running) return; - if (!dbus_g_proxy_call_with_timeout (NM_OBJECT_GET_PRIVATE (object)->properties_proxy, - "Get", 15000, &err, - G_TYPE_STRING, interface, - G_TYPE_STRING, prop_name, - G_TYPE_INVALID, - G_TYPE_VALUE, &value, - G_TYPE_INVALID)) { + ret = g_dbus_proxy_call_sync (NM_OBJECT_GET_PRIVATE (object)->properties_proxy, + "Get", + g_variant_new ("(ss)", interface, prop_name), + G_DBUS_CALL_FLAGS_NONE, 15000, + NULL, &err); + if (!ret) { dbgmsg ("%s: Error getting '%s' for %s: (%d) %s\n", __func__, prop_name, @@ -1263,35 +1437,43 @@ _nm_object_reload_property (NMObject *object, return; } - handle_property_changed (object, prop_name, &value, TRUE); - g_value_unset (&value); + g_variant_get (ret, "(v)", &value); + handle_property_changed (object, prop_name, value, TRUE); + g_variant_unref (value); + g_variant_unref (ret); } void _nm_object_set_property (NMObject *object, const char *interface, const char *prop_name, - GValue *value) + const char *format_string, + ...) { + GVariant *val, *ret; + va_list ap; + g_return_if_fail (NM_IS_OBJECT (object)); g_return_if_fail (interface != NULL); g_return_if_fail (prop_name != NULL); - g_return_if_fail (G_IS_VALUE (value)); + g_return_if_fail (format_string != NULL); if (!NM_OBJECT_GET_PRIVATE (object)->nm_running) return; - if (!dbus_g_proxy_call_with_timeout (NM_OBJECT_GET_PRIVATE (object)->properties_proxy, - "Set", 2000, NULL, - G_TYPE_STRING, interface, - G_TYPE_STRING, prop_name, - G_TYPE_VALUE, value, - G_TYPE_INVALID)) { + va_start (ap, format_string); + val = g_variant_new_va (format_string, NULL, &ap); + va_end (ap); + g_return_if_fail (val != NULL); - /* Ignore errors. dbus_g_proxy_call_with_timeout() is called instead of - * dbus_g_proxy_call_no_reply() to give NM chance to authenticate the caller. - */ - } + ret = g_dbus_proxy_call_sync (NM_OBJECT_GET_PRIVATE (object)->properties_proxy, + "Set", + g_variant_new ("(ssv)", interface, prop_name, val), + G_DBUS_CALL_FLAGS_NONE, 2000, + NULL, NULL); + /* Ignore errors. */ + if (ret) + g_variant_unref (ret); } static void @@ -1323,19 +1505,21 @@ reload_complete (NMObject *object) } static void -reload_got_properties (DBusGProxy *proxy, DBusGProxyCall *call, +reload_got_properties (GObject *proxy, + GAsyncResult *result, gpointer user_data) { NMObject *object = user_data; NMObjectPrivate *priv = NM_OBJECT_GET_PRIVATE (object); - GHashTable *props = NULL; + GVariant *ret, *props; GError *error = NULL; - if (dbus_g_proxy_end_call (proxy, call, &error, - DBUS_TYPE_G_MAP_OF_VARIANT, &props, - G_TYPE_INVALID)) { + ret = g_dbus_proxy_call_finish (G_DBUS_PROXY (proxy), result, &error); + if (ret) { + g_variant_get (ret, "(@a{sv})", &props); process_properties_changed (object, props, FALSE); - g_hash_table_destroy (props); + g_variant_unref (props); + g_variant_unref (ret); } else { if (priv->reload_error) g_error_free (error); @@ -1352,12 +1536,14 @@ _nm_object_reload_properties_async (NMObject *object, GAsyncReadyCallback callba { NMObjectPrivate *priv = NM_OBJECT_GET_PRIVATE (object); GSimpleAsyncResult *simple; - GSList *p; + GHashTableIter iter; + const char *interface; + GDBusProxy *proxy; simple = g_simple_async_result_new (G_OBJECT (object), callback, user_data, _nm_object_reload_properties_async); - if (!priv->property_interfaces) { + if (!g_hash_table_size (priv->proxies) || !priv->nm_running) { g_simple_async_result_complete_in_idle (simple); g_object_unref (simple); return; @@ -1372,12 +1558,15 @@ _nm_object_reload_properties_async (NMObject *object, GAsyncReadyCallback callba if (priv->reload_results->next) return; - for (p = priv->property_interfaces; p; p = p->next) { + g_hash_table_iter_init (&iter, priv->proxies); + while (g_hash_table_iter_next (&iter, (gpointer *) &interface, (gpointer *) &proxy)) { priv->reload_remaining++; - dbus_g_proxy_begin_call (priv->properties_proxy, "GetAll", - reload_got_properties, object, NULL, - G_TYPE_STRING, p->data, - G_TYPE_INVALID); + g_dbus_proxy_call (priv->properties_proxy, + "GetAll", + g_variant_new ("(s)", interface), + G_DBUS_CALL_FLAGS_NONE, -1, + NULL, + reload_got_properties, object); } } @@ -1396,14 +1585,6 @@ _nm_object_reload_properties_finish (NMObject *object, GAsyncResult *result, GEr return g_simple_async_result_get_op_res_gboolean (simple); } -DBusGProxy * -_nm_object_new_proxy (NMObject *self, const char *path, const char *interface) -{ - NMObjectPrivate *priv = NM_OBJECT_GET_PRIVATE (self); - - return _nm_dbus_new_proxy_for_connection (priv->connection, path ? path : priv->path, interface); -} - gboolean _nm_object_get_nm_running (NMObject *self) { diff --git a/libnm/nm-object.h b/libnm/nm-object.h index c492e67125..1ad83a915c 100644 --- a/libnm/nm-object.h +++ b/libnm/nm-object.h @@ -26,9 +26,7 @@ #error "Only can be included directly." #endif -#include -#include -#include +#include #include diff --git a/libnm/nm-remote-connection.c b/libnm/nm-remote-connection.c index e16322b837..9c581928f9 100644 --- a/libnm/nm-remote-connection.c +++ b/libnm/nm-remote-connection.c @@ -29,9 +29,10 @@ #include "nm-remote-connection.h" #include "nm-remote-connection-private.h" #include "nm-object-private.h" -#include "nm-dbus-glib-types.h" #include "nm-glib-compat.h" -#include "nm-dbus-helpers-private.h" +#include "nm-dbus-helpers.h" + +#include "nmdbus-settings-connection.h" static void nm_remote_connection_connection_iface_init (NMConnectionInterface *iface); static void nm_remote_connection_initable_iface_init (GInitableIface *iface); @@ -54,21 +55,18 @@ enum { }; typedef struct RemoteCall RemoteCall; -typedef void (*RemoteCallFetchResultCb) (RemoteCall *call, DBusGProxyCall *proxy_call, GError *error); +typedef void (*RemoteCallFetchResultCb) (RemoteCall *call, GAsyncResult *result); struct RemoteCall { NMRemoteConnection *self; - DBusGProxyCall *call; RemoteCallFetchResultCb fetch_result_cb; GFunc callback; gpointer user_data; }; typedef struct { - DBusGProxy *proxy; - gboolean proxy_is_destroyed; - GSList *calls; + NMDBusSettingsConnection *proxy; gboolean unsaved; @@ -97,35 +95,16 @@ nm_remote_connection_error_quark (void) /****************************************************************/ static void -remote_call_dbus_cb (DBusGProxy *proxy, DBusGProxyCall *proxy_call, gpointer user_data) +remote_call_dbus_cb (GObject *proxy, GAsyncResult *result, gpointer user_data) { RemoteCall *call = user_data; - NMRemoteConnectionPrivate *priv = NM_REMOTE_CONNECTION_GET_PRIVATE (call->self); - GError *error = NULL; - g_assert ( (!proxy && !proxy_call && priv->proxy_is_destroyed) || - ( proxy && proxy_call && !priv->proxy_is_destroyed && proxy == priv->proxy) ); + call->fetch_result_cb (call, result); - if (priv->proxy_is_destroyed) { - error = g_error_new_literal (NM_REMOTE_CONNECTION_ERROR, - NM_REMOTE_CONNECTION_ERROR_DISCONNECTED, - _("Disconnected by D-Bus")); - } - call->fetch_result_cb (call, proxy_call, error); - g_clear_error (&error); - - priv->calls = g_slist_remove (priv->calls, call); g_object_unref (call->self); g_free (call); } -static gboolean -remote_call_cleanup_cb (void *user_data) -{ - remote_call_dbus_cb (NULL, NULL, user_data); - return G_SOURCE_REMOVE; -} - static RemoteCall * remote_call_new (NMRemoteConnection *self, RemoteCallFetchResultCb fetch_result_cb, @@ -133,65 +112,31 @@ remote_call_new (NMRemoteConnection *self, gpointer user_data) { RemoteCall *call; - NMRemoteConnectionPrivate *priv = NM_REMOTE_CONNECTION_GET_PRIVATE (self); g_assert (fetch_result_cb); - if (priv->proxy_is_destroyed && !callback) - return NULL; - call = g_malloc0 (sizeof (RemoteCall)); call->self = g_object_ref (self); call->fetch_result_cb = fetch_result_cb; call->user_data = user_data; call->callback = callback; - if (priv->proxy_is_destroyed) { - g_idle_add (remote_call_cleanup_cb, call); - return NULL; - } - priv->calls = g_slist_prepend (priv->calls, call); return call; } -static void -proxy_set_destroyed (NMRemoteConnection *self) -{ - NMRemoteConnectionPrivate *priv = NM_REMOTE_CONNECTION_GET_PRIVATE (self); - - if (priv->proxy_is_destroyed) { - g_assert (!priv->calls); - return; - } - - priv->proxy_is_destroyed = TRUE; - - priv->calls = g_slist_reverse (priv->calls); - while (priv->calls) - remote_call_dbus_cb (NULL, NULL, priv->calls->data); -} - -static void -proxy_destroy_cb (DBusGProxy* proxy, gpointer user_data) { - proxy_set_destroyed (user_data); -} - /****************************************************************/ static void -result_cb (RemoteCall *call, DBusGProxyCall *proxy_call, GError *error) +update_result_cb (RemoteCall *call, GAsyncResult *result) { + NMRemoteConnectionPrivate *priv = NM_REMOTE_CONNECTION_GET_PRIVATE (call->self); NMRemoteConnectionResultFunc func = (NMRemoteConnectionResultFunc) call->callback; - GError *local_error = NULL; + GError *error = NULL; - if (!error) { - dbus_g_proxy_end_call (NM_REMOTE_CONNECTION_GET_PRIVATE (call->self)->proxy, - proxy_call, &local_error, G_TYPE_INVALID); - error = local_error; - } + nmdbus_settings_connection_call_update_finish (priv->proxy, result, &error); if (func) (*func) (call->self, error, call->user_data); - g_clear_error (&local_error); + g_clear_error (&error); } /** @@ -211,23 +156,34 @@ nm_remote_connection_commit_changes (NMRemoteConnection *self, { NMRemoteConnectionPrivate *priv; RemoteCall *call; - GHashTable *settings; + GVariant *settings; g_return_if_fail (NM_IS_REMOTE_CONNECTION (self)); priv = NM_REMOTE_CONNECTION_GET_PRIVATE (self); - call = remote_call_new (self, result_cb, (GFunc) callback, user_data); + call = remote_call_new (self, update_result_cb, (GFunc) callback, user_data); if (!call) return; settings = nm_connection_to_dbus (NM_CONNECTION (self), NM_CONNECTION_SERIALIZE_ALL); - call->call = dbus_g_proxy_begin_call (priv->proxy, "Update", - remote_call_dbus_cb, call, NULL, - DBUS_TYPE_G_MAP_OF_MAP_OF_VARIANT, settings, - G_TYPE_INVALID); - g_assert (call->call); - g_hash_table_destroy (settings); + nmdbus_settings_connection_call_update (priv->proxy, + settings, + NULL, + remote_call_dbus_cb, call); +} + +static void +update_unsaved_result_cb (RemoteCall *call, GAsyncResult *result) +{ + NMRemoteConnectionPrivate *priv = NM_REMOTE_CONNECTION_GET_PRIVATE (call->self); + NMRemoteConnectionResultFunc func = (NMRemoteConnectionResultFunc) call->callback; + GError *error = NULL; + + nmdbus_settings_connection_call_update_unsaved_finish (priv->proxy, result, &error); + if (func) + (*func) (call->self, error, call->user_data); + g_clear_error (&error); } /** @@ -248,24 +204,35 @@ nm_remote_connection_commit_changes_unsaved (NMRemoteConnection *connection, gpointer user_data) { NMRemoteConnectionPrivate *priv; - GHashTable *settings = NULL; + GVariant *settings; RemoteCall *call; g_return_if_fail (NM_IS_REMOTE_CONNECTION (connection)); priv = NM_REMOTE_CONNECTION_GET_PRIVATE (connection); - call = remote_call_new (connection, result_cb, (GFunc) callback, user_data); + call = remote_call_new (connection, update_unsaved_result_cb, (GFunc) callback, user_data); if (!call) return; settings = nm_connection_to_dbus (NM_CONNECTION (connection), NM_CONNECTION_SERIALIZE_ALL); - call->call = dbus_g_proxy_begin_call (priv->proxy, "UpdateUnsaved", - remote_call_dbus_cb, call, NULL, - DBUS_TYPE_G_MAP_OF_MAP_OF_VARIANT, settings, - G_TYPE_INVALID); - g_assert (call->call); - g_hash_table_destroy (settings); + nmdbus_settings_connection_call_update_unsaved (priv->proxy, + settings, + NULL, + remote_call_dbus_cb, call); +} + +static void +save_result_cb (RemoteCall *call, GAsyncResult *result) +{ + NMRemoteConnectionPrivate *priv = NM_REMOTE_CONNECTION_GET_PRIVATE (call->self); + NMRemoteConnectionResultFunc func = (NMRemoteConnectionResultFunc) call->callback; + GError *error = NULL; + + nmdbus_settings_connection_call_save_finish (priv->proxy, result, &error); + if (func) + (*func) (call->self, error, call->user_data); + g_clear_error (&error); } /** @@ -290,12 +257,26 @@ nm_remote_connection_save (NMRemoteConnection *connection, priv = NM_REMOTE_CONNECTION_GET_PRIVATE (connection); - call = remote_call_new (connection, result_cb, (GFunc) callback, user_data); + call = remote_call_new (connection, save_result_cb, (GFunc) callback, user_data); if (!call) return; - call->call = dbus_g_proxy_begin_call (priv->proxy, "Save", remote_call_dbus_cb, call, NULL, G_TYPE_INVALID); - g_assert (call->call); + nmdbus_settings_connection_call_save (priv->proxy, + NULL, + remote_call_dbus_cb, call); +} + +static void +delete_result_cb (RemoteCall *call, GAsyncResult *result) +{ + NMRemoteConnectionPrivate *priv = NM_REMOTE_CONNECTION_GET_PRIVATE (call->self); + NMRemoteConnectionResultFunc func = (NMRemoteConnectionResultFunc) call->callback; + GError *error = NULL; + + nmdbus_settings_connection_call_delete_finish (priv->proxy, result, &error); + if (func) + (*func) (call->self, error, call->user_data); + g_clear_error (&error); } /** @@ -318,35 +299,31 @@ nm_remote_connection_delete (NMRemoteConnection *self, priv = NM_REMOTE_CONNECTION_GET_PRIVATE (self); - call = remote_call_new (self, result_cb, (GFunc) callback, user_data); + call = remote_call_new (self, delete_result_cb, (GFunc) callback, user_data); if (!call) return; - call->call = dbus_g_proxy_begin_call (priv->proxy, "Delete", - remote_call_dbus_cb, call, NULL, - G_TYPE_INVALID); - g_assert (call->call); + nmdbus_settings_connection_call_delete (priv->proxy, + NULL, + remote_call_dbus_cb, call); } static void -get_secrets_cb (RemoteCall *call, DBusGProxyCall *proxy_call, GError *error) +get_secrets_cb (RemoteCall *call, GAsyncResult *result) { + NMRemoteConnectionPrivate *priv = NM_REMOTE_CONNECTION_GET_PRIVATE (call->self); NMRemoteConnectionGetSecretsFunc func = (NMRemoteConnectionGetSecretsFunc) call->callback; - GHashTable *secrets = NULL; - GError *local_error = NULL; + GVariant *secrets = NULL; + GError *error = NULL; - if (!error) { - dbus_g_proxy_end_call (NM_REMOTE_CONNECTION_GET_PRIVATE (call->self)->proxy, - proxy_call, &local_error, - DBUS_TYPE_G_MAP_OF_MAP_OF_VARIANT, &secrets, - G_TYPE_INVALID); - error = local_error; - } + if (!nmdbus_settings_connection_call_get_secrets_finish (priv->proxy, &secrets, + result, &error)) + secrets = NULL; if (func) (*func) (call->self, error ? NULL : secrets, error, call->user_data); - g_clear_error (&local_error); + g_clear_error (&error); if (secrets) - g_hash_table_destroy (secrets); + g_variant_unref (secrets); } @@ -378,11 +355,10 @@ nm_remote_connection_get_secrets (NMRemoteConnection *self, if (!call) return; - call->call = dbus_g_proxy_begin_call (priv->proxy, "GetSecrets", - remote_call_dbus_cb, call, NULL, - G_TYPE_STRING, setting_name, - G_TYPE_INVALID); - g_assert (call->call); + nmdbus_settings_connection_call_get_secrets (priv->proxy, + setting_name, + NULL, + remote_call_dbus_cb, call); } /** @@ -428,7 +404,7 @@ nm_remote_connection_get_visible (NMRemoteConnection *connection) /****************************************************************/ static void -replace_settings (NMRemoteConnection *self, GHashTable *new_settings) +replace_settings (NMRemoteConnection *self, GVariant *new_settings) { GError *error = NULL; @@ -443,29 +419,24 @@ replace_settings (NMRemoteConnection *self, GHashTable *new_settings) } static void -updated_get_settings_cb (DBusGProxy *proxy, - DBusGProxyCall *call, +updated_get_settings_cb (GObject *proxy, + GAsyncResult *result, gpointer user_data) { NMRemoteConnection *self = user_data; NMRemoteConnectionPrivate *priv = NM_REMOTE_CONNECTION_GET_PRIVATE (self); - GHashTable *new_settings; - GError *error = NULL; + GVariant *new_settings; gboolean visible; - dbus_g_proxy_end_call (proxy, call, &error, - DBUS_TYPE_G_MAP_OF_MAP_OF_VARIANT, &new_settings, - G_TYPE_INVALID); - if (error) { - g_error_free (error); - + if (!nmdbus_settings_connection_call_get_settings_finish (priv->proxy, &new_settings, + result, NULL)) { /* Connection is no longer visible to this user. */ nm_connection_clear_settings (NM_CONNECTION (self)); visible = FALSE; } else { replace_settings (self, new_settings); - g_hash_table_destroy (new_settings); + g_variant_unref (new_settings); visible = TRUE; } @@ -477,17 +448,15 @@ updated_get_settings_cb (DBusGProxy *proxy, } static void -updated_cb (DBusGProxy *proxy, gpointer user_data) +updated_cb (NMDBusSettingsConnection *proxy, gpointer user_data) { NMRemoteConnection *self = NM_REMOTE_CONNECTION (user_data); NMRemoteConnectionPrivate *priv = NM_REMOTE_CONNECTION_GET_PRIVATE (self); /* The connection got updated; request the replacement settings */ - if (!priv->proxy_is_destroyed) { - dbus_g_proxy_begin_call (priv->proxy, "GetSettings", - updated_get_settings_cb, self, NULL, - G_TYPE_INVALID); - } + nmdbus_settings_connection_call_get_settings (priv->proxy, + NULL, + updated_get_settings_cb, self); } /****************************************************************/ @@ -503,18 +472,15 @@ init_dbus (NMObject *object) NM_OBJECT_CLASS (nm_remote_connection_parent_class)->init_dbus (object); - priv->proxy = _nm_object_new_proxy (object, NULL, NM_DBUS_INTERFACE_SETTINGS_CONNECTION); + priv->proxy = NMDBUS_SETTINGS_CONNECTION (_nm_object_get_proxy (object, NM_DBUS_INTERFACE_SETTINGS_CONNECTION)); g_assert (priv->proxy); - dbus_g_proxy_set_default_timeout (priv->proxy, G_MAXINT); _nm_object_register_properties (object, - priv->proxy, + NM_DBUS_INTERFACE_SETTINGS_CONNECTION, property_info); - dbus_g_proxy_add_signal (priv->proxy, "Updated", G_TYPE_INVALID); - dbus_g_proxy_connect_signal (priv->proxy, "Updated", G_CALLBACK (updated_cb), object, NULL); - - g_signal_connect (priv->proxy, "destroy", G_CALLBACK (proxy_destroy_cb), object); + g_signal_connect (priv->proxy, "updated", + G_CALLBACK (updated_cb), object); } static gboolean @@ -522,25 +488,26 @@ init_sync (GInitable *initable, GCancellable *cancellable, GError **error) { NMRemoteConnection *self = NM_REMOTE_CONNECTION (initable); NMRemoteConnectionPrivate *priv = NM_REMOTE_CONNECTION_GET_PRIVATE (initable); - GHashTable *hash; + GVariant *settings; if (!nm_remote_connection_parent_initable_iface->init (initable, cancellable, error)) return FALSE; - if (!dbus_g_proxy_call (priv->proxy, "GetSettings", error, - G_TYPE_INVALID, - DBUS_TYPE_G_MAP_OF_MAP_OF_VARIANT, &hash, - G_TYPE_INVALID)) + if (!nmdbus_settings_connection_call_get_settings_sync (priv->proxy, + &settings, + cancellable, error)) return FALSE; + priv->visible = TRUE; - replace_settings (self, hash); - g_hash_table_destroy (hash); + replace_settings (self, settings); + g_variant_unref (settings); return TRUE; } typedef struct { NMRemoteConnection *connection; + GCancellable *cancellable; GSimpleAsyncResult *result; } NMRemoteConnectionInitData; @@ -554,30 +521,29 @@ init_async_complete (NMRemoteConnectionInitData *init_data, GError *error) g_simple_async_result_complete (init_data->result); g_object_unref (init_data->result); + g_clear_object (&init_data->cancellable); g_slice_free (NMRemoteConnectionInitData, init_data); } static void -init_get_settings_cb (DBusGProxy *proxy, - DBusGProxyCall *call, +init_get_settings_cb (GObject *proxy, + GAsyncResult *result, gpointer user_data) { NMRemoteConnectionInitData *init_data = user_data; NMRemoteConnectionPrivate *priv = NM_REMOTE_CONNECTION_GET_PRIVATE (init_data->connection); - GHashTable *settings; + GVariant *settings; GError *error = NULL; - dbus_g_proxy_end_call (proxy, call, &error, - DBUS_TYPE_G_MAP_OF_MAP_OF_VARIANT, &settings, - G_TYPE_INVALID); - if (error) { + if (!nmdbus_settings_connection_call_get_settings_finish (priv->proxy, &settings, + result, &error)) { init_async_complete (init_data, error); return; } priv->visible = TRUE; replace_settings (init_data->connection, settings); - g_hash_table_destroy (settings); + g_variant_unref (settings); init_async_complete (init_data, NULL); } @@ -594,9 +560,9 @@ init_async_parent_inited (GObject *source, GAsyncResult *result, gpointer user_d return; } - dbus_g_proxy_begin_call (priv->proxy, "GetSettings", - init_get_settings_cb, init_data, NULL, - G_TYPE_INVALID); + nmdbus_settings_connection_call_get_settings (priv->proxy, + init_data->cancellable, + init_get_settings_cb, init_data); } static void @@ -608,6 +574,7 @@ init_async (GAsyncInitable *initable, int io_priority, init_data = g_slice_new0 (NMRemoteConnectionInitData); init_data->connection = NM_REMOTE_CONNECTION (initable); + init_data->cancellable = cancellable ? g_object_ref (cancellable) : NULL; init_data->result = g_simple_async_result_new (G_OBJECT (initable), callback, user_data, init_async); @@ -655,22 +622,6 @@ constructed (GObject *object) nm_object_get_path (NM_OBJECT (object))); } -static void -dispose (GObject *object) -{ - NMRemoteConnection *self = NM_REMOTE_CONNECTION (object); - NMRemoteConnectionPrivate *priv = NM_REMOTE_CONNECTION_GET_PRIVATE (self); - - proxy_set_destroyed (self); - - if (priv->proxy) { - g_signal_handlers_disconnect_by_func (priv->proxy, proxy_destroy_cb, object); - g_clear_object (&priv->proxy); - } - - G_OBJECT_CLASS (nm_remote_connection_parent_class)->dispose (object); -} - static void nm_remote_connection_class_init (NMRemoteConnectionClass *remote_class) { @@ -679,10 +630,13 @@ nm_remote_connection_class_init (NMRemoteConnectionClass *remote_class) g_type_class_add_private (object_class, sizeof (NMRemoteConnectionPrivate)); + _nm_object_class_add_interface (nm_object_class, NM_DBUS_INTERFACE_SETTINGS_CONNECTION); + _nm_dbus_register_proxy_type (NM_DBUS_INTERFACE_SETTINGS_CONNECTION, + NMDBUS_TYPE_SETTINGS_CONNECTION_PROXY); + /* virtual methods */ object_class->constructed = constructed; object_class->get_property = get_property; - object_class->dispose = dispose; nm_object_class->init_dbus = init_dbus; diff --git a/libnm/nm-remote-connection.h b/libnm/nm-remote-connection.h index d5668298a7..fc5b87d8a0 100644 --- a/libnm/nm-remote-connection.h +++ b/libnm/nm-remote-connection.h @@ -89,9 +89,8 @@ typedef NMRemoteConnectionResultFunc NMRemoteConnectionDeleteFunc; /** * NMRemoteConnectionGetSecretsFunc: * @connection: the connection for which secrets were requested - * @secrets: (element-type utf8 GLib.HashTable): on success, a hash table of - * hash tables, with each inner hash mapping a setting property to a #GValue - * containing that property's value + * @secrets: on success, a #GVariant of type %NM_VARIANT_TYPE_CONNECTION + * containing secrets. * @error: on failure, a descriptive error * @user_data: user data passed to nm_remote_connection_get_secrets() * @@ -99,7 +98,7 @@ typedef NMRemoteConnectionResultFunc NMRemoteConnectionDeleteFunc; * secrets via nm_remote_connection_get_secrets(). */ typedef void (*NMRemoteConnectionGetSecretsFunc) (NMRemoteConnection *connection, - GHashTable *secrets, + GVariant *secrets, GError *error, gpointer user_data); diff --git a/libnm/nm-remote-settings.c b/libnm/nm-remote-settings.c index 8c570f2062..8c9eb0940f 100644 --- a/libnm/nm-remote-settings.c +++ b/libnm/nm-remote-settings.c @@ -23,15 +23,16 @@ #include #include -#include "nm-dbus-glib-types.h" #include "nm-remote-settings.h" #include "nm-remote-connection-private.h" #include "nm-object-private.h" -#include "nm-dbus-helpers-private.h" +#include "nm-dbus-helpers.h" #include "nm-glib-compat.h" #include "nm-object-private.h" #include "nm-core-internal.h" +#include "nmdbus-settings.h" + /** * SECTION:nm-remote-settings * @Short_description: A helper for NetworkManager's settings API @@ -124,7 +125,7 @@ G_DEFINE_TYPE (NMRemoteSettings, nm_remote_settings, NM_TYPE_OBJECT) #define NM_REMOTE_SETTINGS_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_REMOTE_SETTINGS, NMRemoteSettingsPrivate)) typedef struct { - DBusGProxy *proxy; + NMDBusSettings *proxy; GPtrArray *all_connections; GPtrArray *visible_connections; @@ -424,19 +425,19 @@ nm_remote_settings_list_connections (NMRemoteSettings *settings) } static void -add_connection_done (DBusGProxy *proxy, DBusGProxyCall *call, gpointer user_data) +add_connection_done (GObject *proxy, GAsyncResult *result, gpointer user_data) { AddConnectionInfo *info = user_data; GError *error = NULL; - char *path = NULL; - if (dbus_g_proxy_end_call (proxy, call, &error, DBUS_TYPE_G_OBJECT_PATH, &path, G_TYPE_INVALID)) { - info->path = path; + if (nmdbus_settings_call_add_connection_finish (NMDBUS_SETTINGS (proxy), + &info->path, + result, &error)) { /* Wait until this connection is fully initialized before calling the callback */ - } else + } else { add_connection_info_complete (info->self, info, NULL, error); - - g_clear_error (&error); + g_clear_error (&error); + } } /** @@ -467,7 +468,7 @@ nm_remote_settings_add_connection (NMRemoteSettings *settings, { NMRemoteSettingsPrivate *priv; AddConnectionInfo *info; - GHashTable *new_settings; + GVariant *new_settings; g_return_val_if_fail (NM_IS_REMOTE_SETTINGS (settings), FALSE); g_return_val_if_fail (NM_IS_CONNECTION (connection), FALSE); @@ -484,13 +485,10 @@ nm_remote_settings_add_connection (NMRemoteSettings *settings, info->callback_data = user_data; new_settings = nm_connection_to_dbus (connection, NM_CONNECTION_SERIALIZE_ALL); - dbus_g_proxy_begin_call (priv->proxy, "AddConnection", - add_connection_done, - info, - NULL, - DBUS_TYPE_G_MAP_OF_MAP_OF_VARIANT, new_settings, - G_TYPE_INVALID); - g_hash_table_destroy (new_settings); + nmdbus_settings_call_add_connection (priv->proxy, + new_settings, + NULL, + add_connection_done, info); priv->add_list = g_slist_append (priv->add_list, info); @@ -520,7 +518,7 @@ nm_remote_settings_add_connection_unsaved (NMRemoteSettings *settings, { NMRemoteSettingsPrivate *priv; AddConnectionInfo *info; - GHashTable *new_settings; + GVariant *new_settings; g_return_val_if_fail (NM_IS_REMOTE_SETTINGS (settings), FALSE); g_return_val_if_fail (NM_IS_CONNECTION (connection), FALSE); @@ -537,13 +535,10 @@ nm_remote_settings_add_connection_unsaved (NMRemoteSettings *settings, info->callback_data = user_data; new_settings = nm_connection_to_dbus (connection, NM_CONNECTION_SERIALIZE_ALL); - dbus_g_proxy_begin_call (priv->proxy, "AddConnectionUnsaved", - add_connection_done, - info, - NULL, - DBUS_TYPE_G_MAP_OF_MAP_OF_VARIANT, new_settings, - G_TYPE_INVALID); - g_hash_table_destroy (new_settings); + nmdbus_settings_call_add_connection_unsaved (priv->proxy, + new_settings, + NULL, + add_connection_done, info); priv->add_list = g_slist_append (priv->add_list, info); @@ -580,8 +575,7 @@ nm_remote_settings_load_connections (NMRemoteSettings *settings, GError **error) { NMRemoteSettingsPrivate *priv; - char **my_failures = NULL; - gboolean ret; + gboolean success; g_return_val_if_fail (NM_IS_REMOTE_SETTINGS (settings), FALSE); g_return_val_if_fail (filenames != NULL, FALSE); @@ -595,22 +589,14 @@ nm_remote_settings_load_connections (NMRemoteSettings *settings, return FALSE; } - if (!dbus_g_proxy_call (priv->proxy, "LoadConnections", error, - G_TYPE_STRV, filenames, - G_TYPE_INVALID, - G_TYPE_BOOLEAN, &ret, - G_TYPE_STRV, &my_failures, - G_TYPE_INVALID)) - ret = FALSE; + if (!nmdbus_settings_call_load_connections_sync (priv->proxy, + (const char * const *) filenames, + &success, + failures, + NULL, error)) + success = FALSE; - if (failures) { - if (my_failures && !*my_failures) - g_clear_pointer (&my_failures, g_free); - *failures = my_failures; - } else - g_strfreev (my_failures); - - return ret; + return success; } /** @@ -642,11 +628,10 @@ nm_remote_settings_reload_connections (NMRemoteSettings *settings, return FALSE; } - if (!dbus_g_proxy_call (priv->proxy, "ReloadConnections", error, - G_TYPE_INVALID, - G_TYPE_BOOLEAN, &success, - G_TYPE_INVALID)) - return FALSE; + if (!nmdbus_settings_call_reload_connections_sync (priv->proxy, &success, + NULL, error)) + success = FALSE; + return success; } @@ -657,14 +642,14 @@ typedef struct { } SaveHostnameInfo; static void -save_hostname_cb (DBusGProxy *proxy, - DBusGProxyCall *call, +save_hostname_cb (GObject *proxy, + GAsyncResult *result, gpointer user_data) { SaveHostnameInfo *info = user_data; GError *error = NULL; - dbus_g_proxy_end_call (proxy, call, &error, G_TYPE_INVALID); + nmdbus_settings_call_save_hostname_finish (NMDBUS_SETTINGS (proxy), result, &error); if (info->callback != NULL) info->callback (info->settings, error, info->callback_data); g_clear_error (&error); @@ -707,12 +692,10 @@ nm_remote_settings_save_hostname (NMRemoteSettings *settings, info->callback = callback; info->callback_data = user_data; - dbus_g_proxy_begin_call (priv->proxy, "SaveHostname", - save_hostname_cb, - info, - g_free, - G_TYPE_STRING, hostname ? hostname : "", - G_TYPE_INVALID); + nmdbus_settings_call_save_hostname (priv->proxy, + hostname ? hostname : "", + NULL, + save_hostname_cb, info); return TRUE; } @@ -860,11 +843,9 @@ init_dbus (NMObject *object) NM_OBJECT_CLASS (nm_remote_settings_parent_class)->init_dbus (object); - priv->proxy = _nm_object_new_proxy (object, - NM_DBUS_PATH_SETTINGS, - NM_DBUS_INTERFACE_SETTINGS); + priv->proxy = NMDBUS_SETTINGS (_nm_object_get_proxy (object, NM_DBUS_INTERFACE_SETTINGS)); _nm_object_register_properties (object, - priv->proxy, + NM_DBUS_INTERFACE_SETTINGS, property_info); g_signal_connect (object, "notify::" NM_OBJECT_NM_RUNNING, @@ -919,7 +900,6 @@ dispose (GObject *object) g_clear_pointer (&priv->visible_connections, g_ptr_array_unref); g_clear_pointer (&priv->hostname, g_free); - g_clear_object (&priv->proxy); G_OBJECT_CLASS (nm_remote_settings_parent_class)->dispose (object); } @@ -957,6 +937,9 @@ nm_remote_settings_class_init (NMRemoteSettingsClass *class) g_type_class_add_private (class, sizeof (NMRemoteSettingsPrivate)); + _nm_object_class_add_interface (nm_object_class, NM_DBUS_INTERFACE_SETTINGS); + _nm_dbus_register_proxy_type (NM_DBUS_INTERFACE_SETTINGS, NMDBUS_TYPE_SETTINGS_PROXY); + /* Virtual methods */ object_class->constructor = constructor; object_class->get_property = get_property; diff --git a/libnm/nm-secret-agent.c b/libnm/nm-secret-agent.c index 40915e54f8..7c782d1d94 100644 --- a/libnm/nm-secret-agent.c +++ b/libnm/nm-secret-agent.c @@ -20,39 +20,16 @@ #include #include -#include #include "nm-glib-compat.h" #include "nm-dbus-interface.h" #include "nm-secret-agent.h" #include "nm-enum-types.h" -#include "nm-dbus-helpers-private.h" +#include "nm-dbus-helpers.h" #include "nm-simple-connection.h" -static void impl_secret_agent_get_secrets (NMSecretAgent *self, - GHashTable *connection_hash, - const char *connection_path, - const char *setting_name, - const char **hints, - guint32 flags, - DBusGMethodInvocation *context); - -static void impl_secret_agent_cancel_get_secrets (NMSecretAgent *self, - const char *connection_path, - const char *setting_name, - DBusGMethodInvocation *context); - -static void impl_secret_agent_save_secrets (NMSecretAgent *self, - GHashTable *connection_hash, - const char *connection_path, - DBusGMethodInvocation *context); - -static void impl_secret_agent_delete_secrets (NMSecretAgent *self, - GHashTable *connection_hash, - const char *connection_path, - DBusGMethodInvocation *context); - -#include "nm-secret-agent-glue.h" +#include "nmdbus-secret-agent.h" +#include "nmdbus-agent-manager.h" static void nm_secret_agent_initable_iface_init (GInitableIface *iface); static void nm_secret_agent_async_initable_iface_init (GAsyncInitableIface *iface); @@ -68,17 +45,15 @@ typedef struct { gboolean registering; NMSecretAgentCapabilities capabilities; - DBusGConnection *bus; + GDBusConnection *bus; gboolean private_bus; gboolean session_bus; - DBusGProxy *dbus_proxy; - DBusGProxy *manager_proxy; + NMDBusAgentManager *manager_proxy; + NMDBusSecretAgent *dbus_secret_agent; /* GetSecretsInfo structs of in-flight GetSecrets requests */ GSList *pending_gets; - char *nm_owner; - char *identifier; gboolean auto_register; gboolean suppress_auto; @@ -108,36 +83,13 @@ nm_secret_agent_error_quark (void) /*************************************************************/ -static const char * -get_nm_owner (NMSecretAgent *self) -{ - NMSecretAgentPrivate *priv = NM_SECRET_AGENT_GET_PRIVATE (self); - GError *error = NULL; - char *owner; - - if (!priv->nm_owner) { - if (!dbus_g_proxy_call_with_timeout (priv->dbus_proxy, - "GetNameOwner", 2000, &error, - G_TYPE_STRING, NM_DBUS_SERVICE, - G_TYPE_INVALID, - G_TYPE_STRING, &owner, - G_TYPE_INVALID)) - return NULL; - - priv->nm_owner = g_strdup (owner); - g_free (owner); - } - - return priv->nm_owner; -} - static void _internal_unregister (NMSecretAgent *self) { NMSecretAgentPrivate *priv = NM_SECRET_AGENT_GET_PRIVATE (self); if (priv->registered) { - dbus_g_connection_unregister_g_object (priv->bus, G_OBJECT (self)); + g_dbus_interface_skeleton_unexport (G_DBUS_INTERFACE_SKELETON (priv->dbus_secret_agent)); priv->registered = FALSE; priv->registering = FALSE; g_object_notify (G_OBJECT (self), NM_SECRET_AGENT_REGISTERED); @@ -147,7 +99,7 @@ _internal_unregister (NMSecretAgent *self) typedef struct { char *path; char *setting_name; - DBusGMethodInvocation *context; + GDBusMethodInvocation *context; } GetSecretsInfo; static void @@ -177,61 +129,44 @@ should_auto_register (NMSecretAgent *self) } static void -name_owner_changed (DBusGProxy *proxy, - const char *name, - const char *old_owner, - const char *new_owner, +name_owner_changed (GObject *proxy, + GParamSpec *pspec, gpointer user_data) { NMSecretAgent *self = NM_SECRET_AGENT (user_data); NMSecretAgentPrivate *priv = NM_SECRET_AGENT_GET_PRIVATE (self); - gboolean old_owner_good = (old_owner && strlen (old_owner)); - gboolean new_owner_good = (new_owner && strlen (new_owner)); GSList *iter; - if (strcmp (name, NM_DBUS_SERVICE) == 0) { - g_free (priv->nm_owner); - priv->nm_owner = g_strdup (new_owner); + if (g_dbus_proxy_get_name_owner (G_DBUS_PROXY (proxy)) != NULL) { + if (should_auto_register (self)) + nm_secret_agent_register_async (self, NULL, NULL, NULL); + } else { + /* Cancel any pending secrets requests */ + for (iter = priv->pending_gets; iter; iter = g_slist_next (iter)) { + GetSecretsInfo *info = iter->data; - if (!old_owner_good && new_owner_good) { - /* NM appeared */ - if (should_auto_register (self)) - nm_secret_agent_register_async (self, NULL, NULL, NULL); - } else if (old_owner_good && !new_owner_good) { - /* Cancel any pending secrets requests */ - for (iter = priv->pending_gets; iter; iter = g_slist_next (iter)) { - GetSecretsInfo *info = iter->data; - - NM_SECRET_AGENT_GET_CLASS (self)->cancel_get_secrets (self, - info->path, - info->setting_name); - } - g_slist_free (priv->pending_gets); - priv->pending_gets = NULL; - - /* NM disappeared */ - _internal_unregister (self); - } else if (old_owner_good && new_owner_good && strcmp (old_owner, new_owner)) { - /* Hmm, NM magically restarted */ - _internal_unregister (self); - if (should_auto_register (self)) - nm_secret_agent_register_async (self, NULL, NULL, NULL); + NM_SECRET_AGENT_GET_CLASS (self)->cancel_get_secrets (self, + info->path, + info->setting_name); } + g_slist_free (priv->pending_gets); + priv->pending_gets = NULL; + + _internal_unregister (self); } } static gboolean verify_sender (NMSecretAgent *self, - DBusGMethodInvocation *context, + GDBusMethodInvocation *context, GError **error) { NMSecretAgentPrivate *priv = NM_SECRET_AGENT_GET_PRIVATE (self); - DBusConnection *bus; - char *sender; const char *nm_owner; - DBusError dbus_error; - uid_t sender_uid = G_MAXUINT; - gboolean allowed = FALSE; + const char *sender; + guint32 sender_uid; + GVariant *ret; + GError *local = NULL; g_return_val_if_fail (context != NULL, FALSE); @@ -243,7 +178,7 @@ verify_sender (NMSecretAgent *self, /* Verify that the sender is the same as NetworkManager's bus name owner. */ - nm_owner = get_nm_owner (self); + nm_owner = g_dbus_proxy_get_name_owner (G_DBUS_PROXY (priv->manager_proxy)); if (!nm_owner) { g_set_error_literal (error, NM_SECRET_AGENT_ERROR, @@ -252,16 +187,7 @@ verify_sender (NMSecretAgent *self, return FALSE; } - bus = dbus_g_connection_get_connection (priv->bus); - if (!bus) { - g_set_error_literal (error, - NM_SECRET_AGENT_ERROR, - NM_SECRET_AGENT_ERROR_NOT_AUTHORIZED, - "Failed to get DBus connection."); - return FALSE; - } - - sender = dbus_g_method_get_sender (context); + sender = g_dbus_method_invocation_get_sender (context); if (!sender) { g_set_error_literal (error, NM_SECRET_AGENT_ERROR, @@ -276,28 +202,41 @@ verify_sender (NMSecretAgent *self, NM_SECRET_AGENT_ERROR, NM_SECRET_AGENT_ERROR_NOT_AUTHORIZED, "Request sender does not match NetworkManager bus name owner."); - goto out; + return FALSE; } /* If we're connected to the session bus, then this must be a test program, * so skip the UID check. */ - if (priv->session_bus) { - allowed = TRUE; - goto out; - } + if (priv->session_bus) + return TRUE; - dbus_error_init (&dbus_error); - sender_uid = dbus_bus_get_unix_user (bus, sender, &dbus_error); - if (dbus_error_is_set (&dbus_error)) { + /* Check the UID of the sender */ + ret = g_dbus_connection_call_sync (priv->bus, + DBUS_SERVICE_DBUS, + DBUS_PATH_DBUS, + DBUS_INTERFACE_DBUS, + "GetConnectionUnixUser", + g_variant_new ("(s)", sender), + G_VARIANT_TYPE ("(u)"), + G_DBUS_CALL_FLAGS_NONE, -1, + NULL, &local); + if (!ret) { + char *remote_error = g_dbus_error_get_remote_error (local); + + g_dbus_error_strip_remote_error (local); g_set_error (error, NM_SECRET_AGENT_ERROR, NM_SECRET_AGENT_ERROR_NOT_AUTHORIZED, - "Failed to get request unix user: (%s) %s.", - dbus_error.name, dbus_error.message); - dbus_error_free (&dbus_error); - goto out; + "Failed to request unix user: (%s) %s.", + remote_error ? remote_error : "", + local->message); + g_free (remote_error); + g_error_free (local); + return FALSE; } + g_variant_get (ret, "(u)", &sender_uid); + g_variant_unref (ret); /* We only accept requests from NM, which always runs as root */ if (0 != sender_uid) { @@ -305,20 +244,16 @@ verify_sender (NMSecretAgent *self, NM_SECRET_AGENT_ERROR, NM_SECRET_AGENT_ERROR_NOT_AUTHORIZED, "Request sender is not root."); - goto out; + return FALSE; } - allowed = TRUE; - -out: - g_free (sender); - return allowed; + return TRUE; } static gboolean verify_request (NMSecretAgent *self, - DBusGMethodInvocation *context, - GHashTable *connection_hash, + GDBusMethodInvocation *context, + GVariant *connection_dict, const char *connection_path, NMConnection **out_connection, GError **error) @@ -330,10 +265,10 @@ verify_request (NMSecretAgent *self, return FALSE; /* No connection? If the sender verified, then we allow the request */ - if (connection_hash == NULL) + if (connection_dict == NULL) return TRUE; - /* If we have a connection hash, we require a path too */ + /* If we have a connection dictionary, we require a path too */ if (connection_path == NULL) { g_set_error_literal (error, NM_SECRET_AGENT_ERROR, @@ -344,7 +279,7 @@ verify_request (NMSecretAgent *self, /* Make sure the given connection is valid */ g_assert (out_connection); - connection = nm_simple_connection_new_from_dbus (connection_hash, &local); + connection = nm_simple_connection_new_from_dbus (connection_dict, &local); if (connection) { nm_connection_set_path (connection, connection_path); *out_connection = connection; @@ -364,16 +299,18 @@ verify_request (NMSecretAgent *self, static void get_secrets_cb (NMSecretAgent *self, NMConnection *connection, - GHashTable *secrets, + GVariant *secrets, GError *error, gpointer user_data) { GetSecretsInfo *info = user_data; if (error) - dbus_g_method_return_error (info->context, error); - else - dbus_g_method_return (info->context, secrets); + g_dbus_method_invocation_return_gerror (info->context, error); + else { + g_dbus_method_invocation_return_value (info->context, + g_variant_new ("(@a{sa{sv}})", secrets)); + } /* Remove the request from internal tracking */ get_secrets_info_finalize (self, info); @@ -381,12 +318,13 @@ get_secrets_cb (NMSecretAgent *self, static void impl_secret_agent_get_secrets (NMSecretAgent *self, - GHashTable *connection_hash, + GDBusMethodInvocation *context, + GVariant *connection_dict, const char *connection_path, const char *setting_name, - const char **hints, - guint32 flags, - DBusGMethodInvocation *context) + const char * const *hints, + guint flags, + gpointer user_data) { NMSecretAgentPrivate *priv = NM_SECRET_AGENT_GET_PRIVATE (self); GError *error = NULL; @@ -394,9 +332,8 @@ impl_secret_agent_get_secrets (NMSecretAgent *self, GetSecretsInfo *info; /* Make sure the request comes from NetworkManager and is valid */ - if (!verify_request (self, context, connection_hash, connection_path, &connection, &error)) { - dbus_g_method_return_error (context, error); - g_clear_error (&error); + if (!verify_request (self, context, connection_dict, connection_path, &connection, &error)) { + g_dbus_method_invocation_take_error (context, error); return; } @@ -410,7 +347,7 @@ impl_secret_agent_get_secrets (NMSecretAgent *self, connection, connection_path, setting_name, - hints, + (const char **) hints, flags, get_secrets_cb, info); @@ -434,9 +371,10 @@ find_get_secrets_info (GSList *list, const char *path, const char *setting_name) static void impl_secret_agent_cancel_get_secrets (NMSecretAgent *self, + GDBusMethodInvocation *context, const char *connection_path, const char *setting_name, - DBusGMethodInvocation *context) + gpointer user_data) { NMSecretAgentPrivate *priv = NM_SECRET_AGENT_GET_PRIVATE (self); GError *error = NULL; @@ -444,19 +382,16 @@ impl_secret_agent_cancel_get_secrets (NMSecretAgent *self, /* Make sure the request comes from NetworkManager and is valid */ if (!verify_request (self, context, NULL, NULL, NULL, &error)) { - dbus_g_method_return_error (context, error); - g_clear_error (&error); + g_dbus_method_invocation_take_error (context, error); return; } info = find_get_secrets_info (priv->pending_gets, connection_path, setting_name); if (!info) { - g_set_error_literal (&error, - NM_SECRET_AGENT_ERROR, - NM_SECRET_AGENT_ERROR_INTERNAL_ERROR, - "No secrets request in progress for this connection."); - dbus_g_method_return_error (context, error); - g_clear_error (&error); + g_dbus_method_invocation_return_error (context, + NM_SECRET_AGENT_ERROR, + NM_SECRET_AGENT_ERROR_INTERNAL_ERROR, + "No secrets request in progress for this connection."); return; } @@ -464,7 +399,7 @@ impl_secret_agent_cancel_get_secrets (NMSecretAgent *self, NM_SECRET_AGENT_GET_CLASS (self)->cancel_get_secrets (self, info->path, info->setting_name); - dbus_g_method_return (context); + g_dbus_method_invocation_return_value (context, NULL); } static void @@ -473,27 +408,27 @@ save_secrets_cb (NMSecretAgent *self, GError *error, gpointer user_data) { - DBusGMethodInvocation *context = user_data; + GDBusMethodInvocation *context = user_data; if (error) - dbus_g_method_return_error (context, error); + g_dbus_method_invocation_return_gerror (context, error); else - dbus_g_method_return (context); + g_dbus_method_invocation_return_value (context, NULL); } static void impl_secret_agent_save_secrets (NMSecretAgent *self, - GHashTable *connection_hash, + GDBusMethodInvocation *context, + GVariant *connection_dict, const char *connection_path, - DBusGMethodInvocation *context) + gpointer user_data) { GError *error = NULL; NMConnection *connection = NULL; /* Make sure the request comes from NetworkManager and is valid */ - if (!verify_request (self, context, connection_hash, connection_path, &connection, &error)) { - dbus_g_method_return_error (context, error); - g_clear_error (&error); + if (!verify_request (self, context, connection_dict, connection_path, &connection, &error)) { + g_dbus_method_invocation_take_error (context, error); return; } @@ -511,27 +446,27 @@ delete_secrets_cb (NMSecretAgent *self, GError *error, gpointer user_data) { - DBusGMethodInvocation *context = user_data; + GDBusMethodInvocation *context = user_data; if (error) - dbus_g_method_return_error (context, error); + g_dbus_method_invocation_return_gerror (context, error); else - dbus_g_method_return (context); + g_dbus_method_invocation_return_value (context, NULL); } static void impl_secret_agent_delete_secrets (NMSecretAgent *self, - GHashTable *connection_hash, + GDBusMethodInvocation *context, + GVariant *connection_dict, const char *connection_path, - DBusGMethodInvocation *context) + gpointer user_data) { GError *error = NULL; NMConnection *connection = NULL; /* Make sure the request comes from NetworkManager and is valid */ - if (!verify_request (self, context, connection_hash, connection_path, &connection, &error)) { - dbus_g_method_return_error (context, error); - g_clear_error (&error); + if (!verify_request (self, context, connection_dict, connection_path, &connection, &error)) { + g_dbus_method_invocation_take_error (context, error); return; } @@ -550,7 +485,9 @@ check_nm_running (NMSecretAgent *self, GError **error) { NMSecretAgentPrivate *priv = NM_SECRET_AGENT_GET_PRIVATE (self); - if (priv->nm_owner || priv->private_bus) + if (priv->private_bus) + return TRUE; + if (g_dbus_proxy_get_name_owner (G_DBUS_PROXY (priv->manager_proxy))) return TRUE; g_set_error (error, NM_SECRET_AGENT_ERROR, NM_SECRET_AGENT_ERROR_INTERNAL_ERROR, @@ -604,29 +541,25 @@ nm_secret_agent_register (NMSecretAgent *self, priv->suppress_auto = FALSE; /* Export our secret agent interface before registering with the manager */ - dbus_g_connection_register_g_object (priv->bus, - NM_DBUS_PATH_SECRET_AGENT, - G_OBJECT (self)); + if (!g_dbus_interface_skeleton_export (G_DBUS_INTERFACE_SKELETON (priv->dbus_secret_agent), + priv->bus, + NM_DBUS_PATH_SECRET_AGENT, + error)) + return FALSE; priv->registering = TRUE; - if (dbus_g_proxy_call_with_timeout (priv->manager_proxy, - "RegisterWithCapabilities", - 5000, NULL, - G_TYPE_STRING, priv->identifier, - G_TYPE_UINT, priv->capabilities, - G_TYPE_INVALID, - G_TYPE_INVALID)) + if (nmdbus_agent_manager_call_register_with_capabilities_sync (priv->manager_proxy, + priv->identifier, + priv->capabilities, + cancellable, NULL)) goto success; /* Might be an old NetworkManager that doesn't support capabilities; * fall back to old Register() method instead. */ - if (dbus_g_proxy_call_with_timeout (priv->manager_proxy, - "Register", - 5000, error, - G_TYPE_STRING, priv->identifier, - G_TYPE_INVALID, - G_TYPE_INVALID)) + if (nmdbus_agent_manager_call_register_sync (priv->manager_proxy, + priv->identifier, + cancellable, NULL)) goto success; /* Failure */ @@ -666,24 +599,27 @@ reg_result (NMSecretAgent *self, GSimpleAsyncResult *simple, GError *error) } static void -reg_request_cb (DBusGProxy *proxy, - DBusGProxyCall *call, +reg_request_cb (GObject *proxy, + GAsyncResult *result, gpointer user_data) { GSimpleAsyncResult *simple = user_data; NMSecretAgent *self; + NMSecretAgentPrivate *priv; GError *error = NULL; self = NM_SECRET_AGENT (g_async_result_get_source_object (G_ASYNC_RESULT (simple))); g_object_unref (self); /* drop extra ref added by get_source_object() */ + priv = NM_SECRET_AGENT_GET_PRIVATE (self); - dbus_g_proxy_end_call (proxy, call, &error, G_TYPE_INVALID); + nmdbus_agent_manager_call_register_finish (NMDBUS_AGENT_MANAGER (proxy), result, &error); reg_result (self, simple, error); + g_clear_error (&error); } static void -reg_with_caps_cb (DBusGProxy *proxy, - DBusGProxyCall *call, +reg_with_caps_cb (GObject *proxy, + GAsyncResult *result, gpointer user_data) { GSimpleAsyncResult *simple = user_data; @@ -694,7 +630,7 @@ reg_with_caps_cb (DBusGProxy *proxy, g_object_unref (self); /* drop extra ref added by get_source_object() */ priv = NM_SECRET_AGENT_GET_PRIVATE (self); - if (dbus_g_proxy_end_call (proxy, call, NULL, G_TYPE_INVALID)) { + if (nmdbus_agent_manager_call_register_with_capabilities_finish (NMDBUS_AGENT_MANAGER (proxy), result, NULL)) { reg_result (self, simple, NULL); return; } @@ -702,14 +638,9 @@ reg_with_caps_cb (DBusGProxy *proxy, /* Might be an old NetworkManager that doesn't support capabilities; * fall back to old Register() method instead. */ - dbus_g_proxy_begin_call_with_timeout (priv->manager_proxy, - "Register", - reg_request_cb, - self, - NULL, - 5000, - G_TYPE_STRING, priv->identifier, - G_TYPE_INVALID); + nmdbus_agent_manager_call_register (priv->manager_proxy, + priv->identifier, + NULL, reg_request_cb, simple); } /** @@ -762,23 +693,25 @@ nm_secret_agent_register_async (NMSecretAgent *self, return; } - priv->suppress_auto = FALSE; - /* Export our secret agent interface before registering with the manager */ - dbus_g_connection_register_g_object (priv->bus, - NM_DBUS_PATH_SECRET_AGENT, - G_OBJECT (self)); + if (!g_dbus_interface_skeleton_export (G_DBUS_INTERFACE_SKELETON (priv->dbus_secret_agent), + priv->bus, + NM_DBUS_PATH_SECRET_AGENT, + &error)) { + g_simple_async_result_take_error (simple, error); + g_simple_async_result_complete_in_idle (simple); + g_object_unref (simple); + return; + } + priv->suppress_auto = FALSE; priv->registering = TRUE; - dbus_g_proxy_begin_call_with_timeout (priv->manager_proxy, - "RegisterWithCapabilities", - reg_with_caps_cb, - simple, - NULL, - 5000, - G_TYPE_STRING, priv->identifier, - G_TYPE_UINT, priv->capabilities, - G_TYPE_INVALID); + + nmdbus_agent_manager_call_register_with_capabilities (priv->manager_proxy, + priv->identifier, + priv->capabilities, + NULL, + reg_with_caps_cb, simple); } /** @@ -835,25 +768,16 @@ nm_secret_agent_unregister (NMSecretAgent *self, g_return_val_if_fail (priv->bus != NULL, FALSE); g_return_val_if_fail (priv->manager_proxy != NULL, FALSE); - if (!check_nm_running (self, error)) - return FALSE; - priv->suppress_auto = TRUE; - success = dbus_g_proxy_call_with_timeout (priv->manager_proxy, - "Unregister", - 5000, error, - G_TYPE_INVALID, - G_TYPE_INVALID); + success = nmdbus_agent_manager_call_unregister_sync (priv->manager_proxy, cancellable, error); _internal_unregister (self); return success; } static void -unregister_cb (DBusGProxy *proxy, - DBusGProxyCall *call, - gpointer user_data) +unregister_cb (GObject *proxy, GAsyncResult *result, gpointer user_data) { GSimpleAsyncResult *simple = user_data; NMSecretAgent *self; @@ -864,7 +788,8 @@ unregister_cb (DBusGProxy *proxy, _internal_unregister (self); - if (dbus_g_proxy_end_call (proxy, call, &error, G_TYPE_INVALID)) + if (nmdbus_agent_manager_call_unregister_finish (NMDBUS_AGENT_MANAGER (proxy), + result, &error)) g_simple_async_result_set_op_res_gboolean (simple, TRUE); else g_simple_async_result_take_error (simple, error); @@ -917,13 +842,8 @@ nm_secret_agent_unregister_async (NMSecretAgent *self, priv->suppress_auto = TRUE; - dbus_g_proxy_begin_call_with_timeout (priv->manager_proxy, - "Unregister", - unregister_cb, - simple, - NULL, - 5000, - G_TYPE_INVALID); + nmdbus_agent_manager_call_unregister (priv->manager_proxy, cancellable, + unregister_cb, simple); } /** @@ -1099,57 +1019,31 @@ validate_identifier (const char *identifier) static void nm_secret_agent_init (NMSecretAgent *self) { + NMSecretAgentPrivate *priv = NM_SECRET_AGENT_GET_PRIVATE (self); + + priv->dbus_secret_agent = nmdbus_secret_agent_skeleton_new (); + _nm_dbus_bind_properties (self, priv->dbus_secret_agent); + _nm_dbus_bind_methods (self, priv->dbus_secret_agent, + "GetSecrets", impl_secret_agent_get_secrets, + "CancelGetSecrets", impl_secret_agent_cancel_get_secrets, + "DeleteSecrets", impl_secret_agent_delete_secrets, + "SaveSecrets", impl_secret_agent_save_secrets, + NULL); } -static gboolean -init_common (NMSecretAgent *self, GError **error) +static void +init_common (NMSecretAgent *self) { NMSecretAgentPrivate *priv = NM_SECRET_AGENT_GET_PRIVATE (self); - DBusGConnection *session_bus; - priv->bus = _nm_dbus_new_connection (error); - if (!priv->bus) - return FALSE; priv->private_bus = _nm_dbus_is_connection_private (priv->bus); - session_bus = dbus_g_bus_get (DBUS_BUS_SESSION, NULL); - if (priv->bus == session_bus) - priv->session_bus = TRUE; - if (session_bus) - dbus_g_connection_unref (session_bus); - if (priv->private_bus == FALSE) { - priv->dbus_proxy = dbus_g_proxy_new_for_name (priv->bus, - DBUS_SERVICE_DBUS, - DBUS_PATH_DBUS, - DBUS_INTERFACE_DBUS); - g_assert (priv->dbus_proxy); + priv->session_bus = _nm_dbus_bus_type () == G_BUS_TYPE_SESSION; - dbus_g_object_register_marshaller (g_cclosure_marshal_generic, - G_TYPE_NONE, - G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, - G_TYPE_INVALID); - dbus_g_proxy_add_signal (priv->dbus_proxy, "NameOwnerChanged", - G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, - G_TYPE_INVALID); - dbus_g_proxy_connect_signal (priv->dbus_proxy, - "NameOwnerChanged", - G_CALLBACK (name_owner_changed), - self, NULL); - - get_nm_owner (self); + g_signal_connect (priv->manager_proxy, "notify::g-name-owner", + G_CALLBACK (name_owner_changed), self); } - - priv->manager_proxy = _nm_dbus_new_proxy_for_connection (priv->bus, - NM_DBUS_PATH_AGENT_MANAGER, - NM_DBUS_INTERFACE_AGENT_MANAGER); - if (!priv->manager_proxy) { - g_set_error_literal (error, NM_SECRET_AGENT_ERROR, NM_SECRET_AGENT_ERROR_INTERNAL_ERROR, - "Couldn't create NM agent manager proxy."); - return FALSE; - } - - return TRUE; } static gboolean @@ -1157,30 +1051,102 @@ init_sync (GInitable *initable, GCancellable *cancellable, GError **error) { NMSecretAgent *self = NM_SECRET_AGENT (initable); NMSecretAgentPrivate *priv = NM_SECRET_AGENT_GET_PRIVATE (self); + GDBusProxy *proxy; - if (!init_common (self, error)) + priv->bus = _nm_dbus_new_connection (cancellable, error); + if (!priv->bus) return FALSE; + proxy = _nm_dbus_new_proxy_for_connection (priv->bus, + NM_DBUS_PATH_AGENT_MANAGER, + NM_DBUS_INTERFACE_AGENT_MANAGER, + cancellable, error); + if (!proxy) + return FALSE; + priv->manager_proxy = NMDBUS_AGENT_MANAGER (proxy); + + init_common (self); + if (priv->auto_register) return nm_secret_agent_register (self, cancellable, error); else return TRUE; } +typedef struct { + NMSecretAgent *self; + GCancellable *cancellable; + GSimpleAsyncResult *simple; +} NMSecretAgentInitData; + static void -init_async_registered (GObject *initable, GAsyncResult *result, gpointer user_data) +init_async_complete (NMSecretAgentInitData *init_data, GError *error) { - NMSecretAgent *self = NM_SECRET_AGENT (initable); - GSimpleAsyncResult *simple = user_data; + if (!error) + g_simple_async_result_set_op_res_gboolean (init_data->simple, TRUE); + else + g_simple_async_result_take_error (init_data->simple, error); + + g_simple_async_result_complete_in_idle (init_data->simple); + + g_object_unref (init_data->simple); + g_clear_object (&init_data->cancellable); + g_slice_free (NMSecretAgentInitData, init_data); +} + +static void +init_async_registered (GObject *object, GAsyncResult *result, gpointer user_data) +{ + NMSecretAgent *self = NM_SECRET_AGENT (object); + NMSecretAgentInitData *init_data = user_data; GError *error = NULL; - if (nm_secret_agent_register_finish (self, result, &error)) - g_simple_async_result_set_op_res_gboolean (simple, TRUE); - else - g_simple_async_result_take_error (simple, error); + nm_secret_agent_register_finish (self, result, &error); + init_async_complete (init_data, error); +} - g_simple_async_result_complete_in_idle (simple); - g_object_unref (simple); +static void +init_async_got_proxy (GObject *object, GAsyncResult *result, gpointer user_data) +{ + NMSecretAgentInitData *init_data = user_data; + NMSecretAgentPrivate *priv = NM_SECRET_AGENT_GET_PRIVATE (init_data->self); + GDBusProxy *proxy; + GError *error = NULL; + + proxy = _nm_dbus_new_proxy_for_connection_finish (result, &error); + if (!proxy) { + init_async_complete (init_data, error); + return; + } + priv->manager_proxy = NMDBUS_AGENT_MANAGER (proxy); + + init_common (init_data->self); + + if (priv->auto_register) { + nm_secret_agent_register_async (init_data->self, init_data->cancellable, + init_async_registered, init_data); + } else + init_async_complete (init_data, NULL); +} + +static void +init_async_got_bus (GObject *initable, GAsyncResult *result, gpointer user_data) +{ + NMSecretAgentInitData *init_data = user_data; + NMSecretAgentPrivate *priv = NM_SECRET_AGENT_GET_PRIVATE (init_data->self); + GError *error = NULL; + + priv->bus = _nm_dbus_new_connection_finish (result, &error); + if (!priv->bus) { + init_async_complete (init_data, error); + return; + } + + _nm_dbus_new_proxy_for_connection_async (priv->bus, + NM_DBUS_PATH_AGENT_MANAGER, + NM_DBUS_INTERFACE_AGENT_MANAGER, + init_data->cancellable, + init_async_got_proxy, init_data); } static void @@ -1189,26 +1155,16 @@ init_async (GAsyncInitable *initable, int io_priority, gpointer user_data) { NMSecretAgent *self = NM_SECRET_AGENT (initable); - NMSecretAgentPrivate *priv = NM_SECRET_AGENT_GET_PRIVATE (self); - GSimpleAsyncResult *simple; - GError *error = NULL; + NMSecretAgentInitData *init_data; - simple = g_simple_async_result_new (G_OBJECT (initable), callback, user_data, init_async); + init_data = g_slice_new (NMSecretAgentInitData); + init_data->self = self; + init_data->cancellable = cancellable ? g_object_ref (cancellable) : NULL; - if (!init_common (self, &error)) { - g_simple_async_result_take_error (simple, error); - g_simple_async_result_complete_in_idle (simple); - g_object_unref (simple); - return; - } + init_data->simple = g_simple_async_result_new (G_OBJECT (initable), callback, + user_data, init_async); - if (priv->auto_register) - nm_secret_agent_register_async (self, cancellable, init_async_registered, simple); - else { - g_simple_async_result_set_op_res_gboolean (simple, TRUE); - g_simple_async_result_complete_in_idle (simple); - g_object_unref (simple); - } + _nm_dbus_new_connection_async (cancellable, init_async_got_bus, init_data); } static gboolean @@ -1288,21 +1244,17 @@ dispose (GObject *object) if (priv->registered) nm_secret_agent_unregister_async (self, NULL, NULL, NULL); - g_free (priv->identifier); - priv->identifier = NULL; - g_free (priv->nm_owner); - priv->nm_owner = NULL; + g_clear_pointer (&priv->identifier, g_free); while (priv->pending_gets) get_secrets_info_finalize (self, priv->pending_gets->data); - g_clear_object (&priv->dbus_proxy); - g_clear_object (&priv->manager_proxy); + g_signal_handlers_disconnect_matched (priv->dbus_secret_agent, G_SIGNAL_MATCH_DATA, + 0, 0, NULL, NULL, self); + g_object_unref (priv->dbus_secret_agent); - if (priv->bus) { - dbus_g_connection_unref (priv->bus); - priv->bus = NULL; - } + g_clear_object (&priv->manager_proxy); + g_clear_object (&priv->bus); G_OBJECT_CLASS (nm_secret_agent_parent_class)->dispose (object); } @@ -1393,12 +1345,12 @@ nm_secret_agent_class_init (NMSecretAgentClass *class) G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS)); - dbus_g_object_type_install_info (G_TYPE_FROM_CLASS (class), - &dbus_glib_nm_secret_agent_object_info); + _nm_dbus_register_proxy_type (NM_DBUS_INTERFACE_AGENT_MANAGER, + NMDBUS_TYPE_AGENT_MANAGER_PROXY); - dbus_g_error_domain_register (NM_SECRET_AGENT_ERROR, - NM_DBUS_INTERFACE_SECRET_AGENT, - NM_TYPE_SECRET_AGENT_ERROR); + _nm_dbus_register_error_domain (NM_SECRET_AGENT_ERROR, + NM_DBUS_INTERFACE_SECRET_AGENT, + NM_TYPE_SECRET_AGENT_ERROR); } static void diff --git a/libnm/nm-secret-agent.h b/libnm/nm-secret-agent.h index 4b88d55be7..90fcc7d7e1 100644 --- a/libnm/nm-secret-agent.h +++ b/libnm/nm-secret-agent.h @@ -83,13 +83,12 @@ typedef struct { * note that this object will be unrefed after the callback has returned, use * g_object_ref()/g_object_unref() if you want to use this object after the callback * has returned - * @secrets: (element-type utf8 GLib.HashTable): the #GHashTable containing - * the requested secrets in the same format as an #NMConnection hash (as - * created by nm_connection_to_dbus() for example). Each key in @secrets + * @secrets: the #GVariant of type %NM_VARIANT_TYPE_CONNECTION containing the requested + * secrets (as created by nm_connection_to_dbus() for example). Each key in @secrets * should be the name of a #NMSetting object (like "802-11-wireless-security") - * and each value should be a #GHashTable. The sub-hashes map string:#GValue - * where the string is the setting property name (like "psk") and the value - * is the secret + * and each value should be an %NM_VARIANT_TYPE_SETTING variant. The sub-dicts + * map string:value, where the string is the setting property name (like "psk") + * and the value is the secret * @error: if the secrets request failed, give a descriptive error here * @user_data: caller-specific data to be passed to the function * @@ -98,14 +97,14 @@ typedef struct { * return them, or to return an error, this function should be called with * those secrets or the error. * - * To easily create the hash table to return the Wi-Fi PSK, you could do + * To easily create the dictionary to return the Wi-Fi PSK, you could do * something like this: * - * Creating a secrets hash + * Creating a secrets dictionary * * NMConnection *secrets; * NMSettingWirelessSecurity *s_wsec; - * GHashTable *secrets_hash; + * GVariant *secrets_dict; * * secrets = nm_connection_new (); * s_wsec = (NMSettingWirelessSecurity *) nm_setting_wireless_security_new (); @@ -113,18 +112,18 @@ typedef struct { * NM_SETTING_WIRELESS_SECURITY_PSK, "my really cool PSK", * NULL); * nm_connection_add_setting (secrets, NM_SETTING (s_wsec)); - * secrets_hash = nm_connection_to_dbus (secrets, NM_CONNECTION_SERIALIZE_ALL); + * secrets_dict = nm_connection_to_dbus (secrets, NM_CONNECTION_SERIALIZE_ALL); * - * (call the NMSecretAgentGetSecretsFunc with secrets_hash) + * (call the NMSecretAgentGetSecretsFunc with secrets_dict) * * g_object_unref (secrets); - * g_hash_table_unref (secrets_hash); + * g_variant_unref (secrets_dict); * * */ typedef void (*NMSecretAgentGetSecretsFunc) (NMSecretAgent *agent, NMConnection *connection, - GHashTable *secrets, + GVariant *secrets, GError *error, gpointer user_data); diff --git a/libnm/nm-vpn-connection.c b/libnm/nm-vpn-connection.c index fc3d8c81c1..cea9397631 100644 --- a/libnm/nm-vpn-connection.c +++ b/libnm/nm-vpn-connection.c @@ -25,13 +25,15 @@ #include "nm-utils.h" #include "nm-object-private.h" #include "nm-active-connection.h" +#include "nm-dbus-helpers.h" + +#include "nmdbus-vpn-connection.h" G_DEFINE_TYPE (NMVpnConnection, nm_vpn_connection, NM_TYPE_ACTIVE_CONNECTION) #define NM_VPN_CONNECTION_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_VPN_CONNECTION, NMVpnConnectionPrivate)) typedef struct { - DBusGProxy *proxy; char *banner; NMVpnConnectionState vpn_state; } NMVpnConnectionPrivate; @@ -94,9 +96,9 @@ nm_vpn_connection_get_vpn_state (NMVpnConnection *vpn) } static void -vpn_state_changed_proxy (DBusGProxy *proxy, - NMVpnConnectionState vpn_state, - NMVpnConnectionStateReason reason, +vpn_state_changed_proxy (NMDBusVpnConnection *proxy, + guint vpn_state, + guint reason, gpointer user_data) { NMVpnConnection *connection = NM_VPN_CONNECTION (user_data); @@ -128,24 +130,17 @@ init_dbus (NMObject *object) { NM_VPN_CONNECTION_VPN_STATE, &priv->vpn_state }, { NULL }, }; + GDBusProxy *proxy; NM_OBJECT_CLASS (nm_vpn_connection_parent_class)->init_dbus (object); - priv->proxy = _nm_object_new_proxy (object, NULL, NM_DBUS_INTERFACE_VPN_CONNECTION); _nm_object_register_properties (object, - priv->proxy, + NM_DBUS_INTERFACE_VPN_CONNECTION, property_info); - dbus_g_object_register_marshaller (g_cclosure_marshal_generic, - G_TYPE_NONE, - G_TYPE_UINT, G_TYPE_UINT, - G_TYPE_INVALID); - dbus_g_proxy_add_signal (priv->proxy, "VpnStateChanged", G_TYPE_UINT, G_TYPE_UINT, G_TYPE_INVALID); - dbus_g_proxy_connect_signal (priv->proxy, - "VpnStateChanged", - G_CALLBACK (vpn_state_changed_proxy), - object, - NULL); + proxy = _nm_object_get_proxy (object, NM_DBUS_INTERFACE_VPN_CONNECTION); + g_signal_connect (proxy, "vpn-state-changed", + G_CALLBACK (vpn_state_changed_proxy), object); } static void @@ -154,7 +149,6 @@ finalize (GObject *object) NMVpnConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE (object); g_free (priv->banner); - g_object_unref (priv->proxy); G_OBJECT_CLASS (nm_vpn_connection_parent_class)->finalize (object); } @@ -188,6 +182,10 @@ nm_vpn_connection_class_init (NMVpnConnectionClass *connection_class) g_type_class_add_private (connection_class, sizeof (NMVpnConnectionPrivate)); + _nm_object_class_add_interface (nm_object_class, NM_DBUS_INTERFACE_VPN_CONNECTION); + _nm_dbus_register_proxy_type (NM_DBUS_INTERFACE_VPN_CONNECTION, + NMDBUS_TYPE_VPN_CONNECTION_PROXY); + /* virtual methods */ object_class->get_property = get_property; object_class->finalize = finalize; diff --git a/libnm/nm-vpn-plugin-ui-interface.c b/libnm/nm-vpn-plugin-ui-interface.c index 9350b13eff..af00cfd1da 100644 --- a/libnm/nm-vpn-plugin-ui-interface.c +++ b/libnm/nm-vpn-plugin-ui-interface.c @@ -98,6 +98,11 @@ nm_vpn_plugin_ui_interface_get_type (void) } +/** + * nm_vpn_plugin_ui_interface_ui_factory: + * + * Returns: (transfer full): + */ NMVpnPluginUiWidgetInterface * nm_vpn_plugin_ui_interface_ui_factory (NMVpnPluginUiInterface *iface, NMConnection *connection, @@ -116,6 +121,11 @@ nm_vpn_plugin_ui_interface_get_capabilities (NMVpnPluginUiInterface *iface) return NM_VPN_PLUGIN_UI_INTERFACE_GET_INTERFACE (iface)->get_capabilities (iface); } +/** + * nm_vpn_plugin_ui_interface_import: + * + * Returns: (transfer full): + */ NMConnection * nm_vpn_plugin_ui_interface_import (NMVpnPluginUiInterface *iface, const char *path, @@ -207,6 +217,11 @@ nm_vpn_plugin_ui_widget_interface_get_type (void) return vpn_plugin_ui_widget_interface_type; } +/** + * nm_vpn_plugin_ui_widget_interface_get_widget: + * + * Returns: (transfer none): + */ GObject * nm_vpn_plugin_ui_widget_interface_get_widget (NMVpnPluginUiWidgetInterface *iface) { diff --git a/libnm/nm-vpn-plugin-ui-interface.h b/libnm/nm-vpn-plugin-ui-interface.h index 1219360294..4aab74482e 100644 --- a/libnm/nm-vpn-plugin-ui-interface.h +++ b/libnm/nm-vpn-plugin-ui-interface.h @@ -38,8 +38,10 @@ typedef struct _NMVpnPluginUiWidgetInterface NMVpnPluginUiWidgetInterface; /* Plugin's factory function that returns a GObject that implements * NMVpnPluginUiInterface. */ +#ifndef __GI_SCANNER__ typedef NMVpnPluginUiInterface * (*NMVpnPluginUiFactory) (GError **error); NMVpnPluginUiInterface *nm_vpn_plugin_ui_factory (GError **error); +#endif /**************************************************/ diff --git a/libnm/nm-vpn-plugin-utils.c b/libnm/nm-vpn-plugin-utils.c index bfa939a15f..6ff2f57cac 100644 --- a/libnm/nm-vpn-plugin-utils.c +++ b/libnm/nm-vpn-plugin-utils.c @@ -26,7 +26,6 @@ #include "nm-vpn-plugin-utils.h" #include "nm-vpn-plugin.h" #include "nm-core-internal.h" -#include "nm-dbus-glib-types.h" #define DATA_KEY_TAG "DATA_KEY=" #define DATA_VAL_TAG "DATA_VAL=" diff --git a/libnm/nm-vpn-plugin.c b/libnm/nm-vpn-plugin.c index c47f61a5c8..ba5ecdc1f9 100644 --- a/libnm/nm-vpn-plugin.c +++ b/libnm/nm-vpn-plugin.c @@ -26,48 +26,12 @@ #include "nm-glib-compat.h" #include "nm-vpn-plugin.h" -#include "nm-vpn-enum-types.h" +#include "nm-enum-types.h" #include "nm-utils.h" -#include "nm-dbus-glib-types.h" +#include "nm-connection.h" +#include "nm-dbus-helpers.h" -static gboolean impl_vpn_plugin_connect (NMVpnPlugin *plugin, - GHashTable *connection, - GError **error); - -static gboolean impl_vpn_plugin_connect_interactive (NMVpnPlugin *plugin, - GHashTable *connection, - GHashTable *details, - GError **error); - -static gboolean impl_vpn_plugin_need_secrets (NMVpnPlugin *plugin, - GHashTable *connection, - char **service_name, - GError **err); - -static gboolean impl_vpn_plugin_new_secrets (NMVpnPlugin *plugin, - GHashTable *connection, - GError **err); - -static gboolean impl_vpn_plugin_disconnect (NMVpnPlugin *plugin, - GError **err); - -static gboolean impl_vpn_plugin_set_config (NMVpnPlugin *plugin, - GHashTable *config, - GError **err); - -static gboolean impl_vpn_plugin_set_ip4_config (NMVpnPlugin *plugin, - GHashTable *config, - GError **err); - -static gboolean impl_vpn_plugin_set_ip6_config (NMVpnPlugin *plugin, - GHashTable *config, - GError **err); - -static gboolean impl_vpn_plugin_set_failure (NMVpnPlugin *plugin, - char *reason, - GError **err); - -#include "nm-vpn-plugin-glue.h" +#include "nmdbus-vpn-plugin.h" #define NM_VPN_PLUGIN_QUIT_TIMER 20 @@ -81,7 +45,8 @@ typedef struct { NMVpnServiceState state; /* DBUS-y stuff */ - DBusGConnection *connection; + GDBusConnection *connection; + NMDBusVpnPlugin *dbus_vpn_plugin; char *dbus_service_name; /* Temporary stuff */ @@ -95,7 +60,7 @@ typedef struct { gboolean has_ip6, got_ip6; /* Config stuff copied from config to ip4config */ - GValue banner, tundev, gateway, mtu; + char *banner, *tundev, *gateway, *mtu; } NMVpnPluginPrivate; #define NM_VPN_PLUGIN_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_VPN_PLUGIN, NMVpnPluginPrivate)) @@ -140,27 +105,31 @@ nm_vpn_plugin_error_quark (void) static void nm_vpn_plugin_set_connection (NMVpnPlugin *plugin, - DBusGConnection *connection) + GDBusConnection *connection) { NMVpnPluginPrivate *priv = NM_VPN_PLUGIN_GET_PRIVATE (plugin); - if (priv->connection) - dbus_g_connection_unref (priv->connection); + g_clear_object (&priv->connection); - priv->connection = connection; + priv->connection = g_object_ref (connection); } -DBusGConnection * +/** + * nm_vpn_plugin_get_connection: + * + * Returns: (transfer full): + */ +GDBusConnection * nm_vpn_plugin_get_connection (NMVpnPlugin *plugin) { - DBusGConnection *connection; + GDBusConnection *connection; g_return_val_if_fail (NM_IS_VPN_PLUGIN (plugin), NULL); connection = NM_VPN_PLUGIN_GET_PRIVATE (plugin)->connection; if (connection) - dbus_g_connection_ref (connection); + g_object_ref (connection); return connection; } @@ -301,60 +270,46 @@ schedule_fail_stop (NMVpnPlugin *plugin) priv->fail_stop_id = g_idle_add (fail_stop, plugin); } -static void -_g_value_set (GValue *dst, GValue *src) -{ - if (src) { - GType type = G_VALUE_TYPE (src); - - if (G_IS_VALUE (dst)) - g_value_unset (dst); - g_value_init (dst, type); - g_value_copy (src, dst); - } else if (G_IS_VALUE (dst)) - g_value_unset (dst); -} - void nm_vpn_plugin_set_config (NMVpnPlugin *plugin, - GHashTable *config) + GVariant *config) { NMVpnPluginPrivate *priv = NM_VPN_PLUGIN_GET_PRIVATE (plugin); - GValue *val; g_return_if_fail (NM_IS_VPN_PLUGIN (plugin)); g_return_if_fail (config != NULL); priv->got_config = TRUE; - val = g_hash_table_lookup (config, NM_VPN_PLUGIN_CONFIG_HAS_IP4); - if (val && g_value_get_boolean (val)) - priv->has_ip4 = TRUE; - val = g_hash_table_lookup (config, NM_VPN_PLUGIN_CONFIG_HAS_IP6); - if (val && g_value_get_boolean (val)) - priv->has_ip6 = TRUE; + g_variant_lookup (config, NM_VPN_PLUGIN_CONFIG_HAS_IP4, "b", &priv->has_ip4); + g_variant_lookup (config, NM_VPN_PLUGIN_CONFIG_HAS_IP6, "b", &priv->has_ip6); g_warn_if_fail (priv->has_ip4 || priv->has_ip6); /* Record the items that need to also be inserted into the * ip4config, for compatibility with older daemons. */ - _g_value_set (&priv->banner, g_hash_table_lookup (config, NM_VPN_PLUGIN_CONFIG_BANNER)); - _g_value_set (&priv->tundev, g_hash_table_lookup (config, NM_VPN_PLUGIN_CONFIG_TUNDEV)); - _g_value_set (&priv->gateway, g_hash_table_lookup (config, NM_VPN_PLUGIN_CONFIG_EXT_GATEWAY)); - _g_value_set (&priv->mtu, g_hash_table_lookup (config, NM_VPN_PLUGIN_CONFIG_MTU)); + g_clear_pointer (&priv->banner, g_free); + g_variant_lookup (config, NM_VPN_PLUGIN_CONFIG_BANNER, "&s", &priv->banner); + g_clear_pointer (&priv->tundev, g_free); + g_variant_lookup (config, NM_VPN_PLUGIN_CONFIG_TUNDEV, "&s", &priv->tundev); + g_clear_pointer (&priv->gateway, g_free); + g_variant_lookup (config, NM_VPN_PLUGIN_CONFIG_EXT_GATEWAY, "&s", &priv->gateway); + g_clear_pointer (&priv->mtu, g_free); + g_variant_lookup (config, NM_VPN_PLUGIN_CONFIG_MTU, "&s", &priv->mtu); g_signal_emit (plugin, signals[CONFIG], 0, config); } void nm_vpn_plugin_set_ip4_config (NMVpnPlugin *plugin, - GHashTable *ip4_config) + GVariant *ip4_config) { NMVpnPluginPrivate *priv = NM_VPN_PLUGIN_GET_PRIVATE (plugin); - GHashTable *combined_config; - GHashTableIter iter; - gpointer key, value; + GVariant *combined_config; + GVariantBuilder builder; + GVariantIter iter; + const char *key, *value; g_return_if_fail (NM_IS_VPN_PLUGIN (plugin)); g_return_if_fail (ip4_config != NULL); @@ -374,22 +329,24 @@ nm_vpn_plugin_set_ip4_config (NMVpnPlugin *plugin, * being emitted. So just copy all of that data into the ip4 * config too. */ - combined_config = g_hash_table_new (g_str_hash, g_str_equal); - g_hash_table_iter_init (&iter, ip4_config); - while (g_hash_table_iter_next (&iter, &key, &value)) - g_hash_table_insert (combined_config, key, value); + g_variant_builder_init (&builder, G_VARIANT_TYPE ("a{ss}")); + g_variant_iter_init (&iter, ip4_config); + while (g_variant_iter_next (&iter, "{&s&s}", &key, &value)) + g_variant_builder_add (&builder, "{ss}", key, value); - if (G_VALUE_TYPE (&priv->banner) != G_TYPE_INVALID) - g_hash_table_insert (combined_config, NM_VPN_PLUGIN_IP4_CONFIG_BANNER, &priv->banner); - if (G_VALUE_TYPE (&priv->tundev) != G_TYPE_INVALID) - g_hash_table_insert (combined_config, NM_VPN_PLUGIN_IP4_CONFIG_TUNDEV, &priv->tundev); - if (G_VALUE_TYPE (&priv->gateway) != G_TYPE_INVALID) - g_hash_table_insert (combined_config, NM_VPN_PLUGIN_IP4_CONFIG_EXT_GATEWAY, &priv->gateway); - if (G_VALUE_TYPE (&priv->mtu) != G_TYPE_INVALID) - g_hash_table_insert (combined_config, NM_VPN_PLUGIN_IP4_CONFIG_MTU, &priv->mtu); + if (priv->banner) + g_variant_builder_add (&builder, "{ss}", NM_VPN_PLUGIN_IP4_CONFIG_BANNER, &priv->banner); + if (priv->tundev) + g_variant_builder_add (&builder, "{ss}", NM_VPN_PLUGIN_IP4_CONFIG_TUNDEV, &priv->tundev); + if (priv->gateway) + g_variant_builder_add (&builder, "{ss}", NM_VPN_PLUGIN_IP4_CONFIG_EXT_GATEWAY, &priv->gateway); + if (priv->mtu) + g_variant_builder_add (&builder, "{ss}", NM_VPN_PLUGIN_IP4_CONFIG_MTU, &priv->mtu); + combined_config = g_variant_builder_end (&builder); + g_variant_ref_sink (combined_config); g_signal_emit (plugin, signals[IP4_CONFIG], 0, combined_config); - g_hash_table_destroy (combined_config); + g_variant_unref (combined_config); if ( priv->has_ip4 == priv->got_ip4 && priv->has_ip6 == priv->got_ip6) @@ -398,7 +355,7 @@ nm_vpn_plugin_set_ip4_config (NMVpnPlugin *plugin, void nm_vpn_plugin_set_ip6_config (NMVpnPlugin *plugin, - GHashTable *ip6_config) + GVariant *ip6_config) { NMVpnPluginPrivate *priv = NM_VPN_PLUGIN_GET_PRIVATE (plugin); @@ -431,55 +388,63 @@ connect_timer_start (NMVpnPlugin *plugin) connect_timer_removed); } -static gboolean +static void _connect_generic (NMVpnPlugin *plugin, - GHashTable *properties, - GHashTable *details, - GError **error) + GDBusMethodInvocation *context, + GVariant *properties, + GVariant *details) { NMVpnPluginPrivate *priv = NM_VPN_PLUGIN_GET_PRIVATE (plugin); NMVpnPluginClass *vpn_class = NM_VPN_PLUGIN_GET_CLASS (plugin); NMConnection *connection; gboolean success = FALSE; - GError *local = NULL; + GError *error = NULL; if (priv->state != NM_VPN_SERVICE_STATE_STOPPED && priv->state != NM_VPN_SERVICE_STATE_INIT) { - g_set_error (error, NM_VPN_PLUGIN_ERROR, NM_VPN_PLUGIN_ERROR_WRONG_STATE, - "Could not start connection: wrong plugin state %d", - priv->state); - return FALSE; + g_dbus_method_invocation_return_error (context, + NM_VPN_PLUGIN_ERROR, + NM_VPN_PLUGIN_ERROR_WRONG_STATE, + "Could not start connection: wrong plugin state %d", + priv->state); + return; } - connection = nm_simple_connection_new_from_dbus (properties, &local); + connection = nm_simple_connection_new_from_dbus (properties, &error); if (!connection) { - g_set_error (error, NM_VPN_PLUGIN_ERROR, NM_VPN_PLUGIN_ERROR_BAD_ARGUMENTS, - "Invalid connection: (%d) %s", - local->code, local->message); - g_clear_error (&local); - return FALSE; + g_dbus_method_invocation_return_error (context, + NM_VPN_PLUGIN_ERROR, + NM_VPN_PLUGIN_ERROR_BAD_ARGUMENTS, + "Invalid connection: (%d) %s", + error->code, error->message); + g_clear_error (&error); } - priv->interactive = FALSE; if (details && !vpn_class->connect_interactive) { - g_set_error_literal (error, NM_VPN_PLUGIN_ERROR, NM_VPN_PLUGIN_ERROR_INTERACTIVE_NOT_SUPPORTED, - "Plugin does not implement ConnectInteractive()"); - return FALSE; + g_dbus_method_invocation_return_error (context, + NM_VPN_PLUGIN_ERROR, + NM_VPN_PLUGIN_ERROR_INTERACTIVE_NOT_SUPPORTED, + "Plugin does not implement ConnectInteractive()"); + return; } nm_vpn_plugin_set_state (plugin, NM_VPN_SERVICE_STATE_STARTING); if (details) { priv->interactive = TRUE; - success = vpn_class->connect_interactive (plugin, connection, details, error); + success = vpn_class->connect_interactive (plugin, connection, details, &error); } else - success = vpn_class->connect (plugin, connection, error); + success = vpn_class->connect (plugin, connection, &error); if (success) { + g_dbus_method_invocation_return_value (context, NULL); + /* Add a timer to make sure we do not wait indefinitely for the successful connect. */ connect_timer_start (plugin); } else { + g_dbus_method_invocation_take_error (context, error); + /* Stop the plugin from an idle handler so that the Connect * method return gets sent before the STOP StateChanged signal. */ @@ -487,120 +452,125 @@ _connect_generic (NMVpnPlugin *plugin, } g_object_unref (connection); - return success; } -static gboolean +static void impl_vpn_plugin_connect (NMVpnPlugin *plugin, - GHashTable *connection, - GError **error) + GDBusMethodInvocation *context, + GVariant *connection, + gpointer user_data) { - return _connect_generic (plugin, connection, NULL, error); + _connect_generic (plugin, context, connection, NULL); } -static gboolean +static void impl_vpn_plugin_connect_interactive (NMVpnPlugin *plugin, - GHashTable *connection, - GHashTable *details, - GError **error) + GDBusMethodInvocation *context, + GVariant *connection, + GVariant *details, + gpointer user_data) { - return _connect_generic (plugin, connection, details, error); + _connect_generic (plugin, context, connection, details); } /***************************************************************/ -static gboolean +static void impl_vpn_plugin_need_secrets (NMVpnPlugin *plugin, - GHashTable *properties, - char **setting_name, - GError **err) + GDBusMethodInvocation *context, + GVariant *properties, + gpointer user_data) { - gboolean ret = FALSE; NMConnection *connection; - char *sn = NULL; - GError *ns_err = NULL; - gboolean needed = FALSE; - GError *cnfh_err = NULL; + char *setting_name; + gboolean needed; + GError *error = NULL; - g_return_val_if_fail (NM_IS_VPN_PLUGIN (plugin), FALSE); - g_return_val_if_fail (properties != NULL, FALSE); - - connection = nm_simple_connection_new_from_dbus (properties, &cnfh_err); + connection = nm_simple_connection_new_from_dbus (properties, &error); if (!connection) { - g_set_error (err, - NM_VPN_PLUGIN_ERROR, - NM_VPN_PLUGIN_ERROR_CONNECTION_INVALID, - "The connection was invalid: '%s' / '%s' invalid: %d.", - g_type_name (nm_setting_lookup_type_by_quark (cnfh_err->domain)), - cnfh_err->message, cnfh_err->code); - g_error_free (cnfh_err); - return FALSE; + g_dbus_method_invocation_return_error (context, + NM_VPN_PLUGIN_ERROR, + NM_VPN_PLUGIN_ERROR_CONNECTION_INVALID, + "The connection was invalid: '%s' / '%s' invalid: %d.", + g_type_name (nm_setting_lookup_type_by_quark (error->domain)), + error->message, error->code); + g_error_free (error); + return; } if (!NM_VPN_PLUGIN_GET_CLASS (plugin)->need_secrets) { - *setting_name = ""; - ret = TRUE; - goto out; + g_dbus_method_invocation_return_value (context, + g_variant_new ("(s)", "")); + return; } - needed = NM_VPN_PLUGIN_GET_CLASS (plugin)->need_secrets (plugin, connection, &sn, &ns_err); - if (ns_err) { - *err = g_error_copy (ns_err); - g_error_free (ns_err); - goto out; + needed = NM_VPN_PLUGIN_GET_CLASS (plugin)->need_secrets (plugin, connection, &setting_name, &error); + if (error) { + g_dbus_method_invocation_take_error (context, error); + return; } - ret = TRUE; if (needed) { - g_assert (sn); - *setting_name = g_strdup (sn); + g_assert (setting_name); + g_dbus_method_invocation_return_value (context, + g_variant_new ("(s)", setting_name)); + g_free (setting_name); } else { /* No secrets required */ - *setting_name = g_strdup (""); + g_dbus_method_invocation_return_value (context, + g_variant_new ("(s)", "")); } - -out: - return ret; } -static gboolean +static void impl_vpn_plugin_new_secrets (NMVpnPlugin *plugin, - GHashTable *properties, - GError **error) + GDBusMethodInvocation *context, + GVariant *properties, + gpointer user_data) { NMVpnPluginPrivate *priv = NM_VPN_PLUGIN_GET_PRIVATE (plugin); NMConnection *connection; - GError *local = NULL; + GError *error = NULL; gboolean success; if (priv->state != NM_VPN_SERVICE_STATE_STARTING) { - g_set_error (error, NM_VPN_PLUGIN_ERROR, NM_VPN_PLUGIN_ERROR_WRONG_STATE, - "Could not accept new secrets: wrong plugin state %d", - priv->state); - return FALSE; + g_dbus_method_invocation_return_error (context, + NM_VPN_PLUGIN_ERROR, + NM_VPN_PLUGIN_ERROR_WRONG_STATE, + "Could not accept new secrets: wrong plugin state %d", + priv->state); + return; } - connection = nm_simple_connection_new_from_dbus (properties, &local); + connection = nm_simple_connection_new_from_dbus (properties, &error); if (!connection) { - g_set_error (error, NM_VPN_PLUGIN_ERROR, NM_VPN_PLUGIN_ERROR_BAD_ARGUMENTS, - "Invalid connection: (%d) %s", - local->code, local->message); - g_clear_error (&local); - return FALSE; + g_dbus_method_invocation_return_error (context, + NM_VPN_PLUGIN_ERROR, + NM_VPN_PLUGIN_ERROR_BAD_ARGUMENTS, + "Invalid connection: (%d) %s", + error->code, error->message); + g_clear_error (&error); + return; } if (!NM_VPN_PLUGIN_GET_CLASS (plugin)->new_secrets) { - g_set_error_literal (error, NM_VPN_PLUGIN_ERROR, NM_VPN_PLUGIN_ERROR_INTERACTIVE_NOT_SUPPORTED, - "Could not accept new secrets: plugin cannot process interactive secrets"); + g_dbus_method_invocation_return_error (context, + NM_VPN_PLUGIN_ERROR, + NM_VPN_PLUGIN_ERROR_INTERACTIVE_NOT_SUPPORTED, + "Could not accept new secrets: plugin cannot process interactive secrets"); g_object_unref (connection); - return FALSE; + return; } - success = NM_VPN_PLUGIN_GET_CLASS (plugin)->new_secrets (plugin, connection, error); + success = NM_VPN_PLUGIN_GET_CLASS (plugin)->new_secrets (plugin, connection, &error); if (success) { + g_dbus_method_invocation_return_value (context, NULL); + /* Add a timer to make sure we do not wait indefinitely for the successful connect. */ connect_timer_start (plugin); } else { + g_dbus_method_invocation_take_error (context, error); + /* Stop the plugin from and idle handler so that the NewSecrets * method return gets sent before the STOP StateChanged signal. */ @@ -608,7 +578,6 @@ impl_vpn_plugin_new_secrets (NMVpnPlugin *plugin, } g_object_unref (connection); - return success; } /** @@ -649,51 +618,57 @@ nm_vpn_plugin_secrets_required (NMVpnPlugin *plugin, /***************************************************************/ -static gboolean +static void impl_vpn_plugin_disconnect (NMVpnPlugin *plugin, - GError **err) + GDBusMethodInvocation *context, + gpointer user_data) { - return nm_vpn_plugin_disconnect (plugin, err); + GError *error = NULL; + + if (nm_vpn_plugin_disconnect (plugin, &error)) + g_dbus_method_invocation_return_value (context, NULL); + else + g_dbus_method_invocation_take_error (context, error); } -static gboolean +static void impl_vpn_plugin_set_config (NMVpnPlugin *plugin, - GHashTable *config, - GError **err) + GDBusMethodInvocation *context, + GVariant *config, + gpointer user_data) { nm_vpn_plugin_set_config (plugin, config); - - return TRUE; + g_dbus_method_invocation_return_value (context, NULL); } -static gboolean +static void impl_vpn_plugin_set_ip4_config (NMVpnPlugin *plugin, - GHashTable *config, - GError **err) + GDBusMethodInvocation *context, + GVariant *config, + gpointer user_data) { nm_vpn_plugin_set_ip4_config (plugin, config); - - return TRUE; + g_dbus_method_invocation_return_value (context, NULL); } -static gboolean +static void impl_vpn_plugin_set_ip6_config (NMVpnPlugin *plugin, - GHashTable *config, - GError **err) + GDBusMethodInvocation *context, + GVariant *config, + gpointer user_data) { nm_vpn_plugin_set_ip6_config (plugin, config); - - return TRUE; + g_dbus_method_invocation_return_value (context, NULL); } -static gboolean +static void impl_vpn_plugin_set_failure (NMVpnPlugin *plugin, + GDBusMethodInvocation *context, char *reason, - GError **err) + gpointer user_data) { nm_vpn_plugin_failure (plugin, NM_VPN_PLUGIN_FAILURE_BAD_IP_CONFIG); - - return TRUE; + g_dbus_method_invocation_return_value (context, NULL); } /*********************************************************************/ @@ -739,11 +714,12 @@ nm_vpn_plugin_init (NMVpnPlugin *plugin) static gboolean init_sync (GInitable *initable, GCancellable *cancellable, GError **error) { - NMVpnPluginPrivate *priv = NM_VPN_PLUGIN_GET_PRIVATE (initable); - NMVpnPlugin *plugin; - DBusGConnection *connection; - DBusGProxy *proxy; - guint request_name_result; + NMVpnPlugin *plugin = NM_VPN_PLUGIN (initable); + NMVpnPluginPrivate *priv = NM_VPN_PLUGIN_GET_PRIVATE (plugin); + GDBusConnection *connection = NULL; + GDBusProxy *proxy; + GVariant *ret; + gboolean success = FALSE; if (!priv->dbus_service_name) { g_set_error_literal (error, NM_VPN_PLUGIN_ERROR, NM_VPN_PLUGIN_ERROR_BAD_ARGUMENTS, @@ -751,36 +727,60 @@ init_sync (GInitable *initable, GCancellable *cancellable, GError **error) return FALSE; } - connection = dbus_g_bus_get (DBUS_BUS_SYSTEM, error); + connection = g_bus_get_sync (G_BUS_TYPE_SYSTEM, NULL, error); if (!connection) return FALSE; - proxy = dbus_g_proxy_new_for_name (connection, - "org.freedesktop.DBus", - "/org/freedesktop/DBus", - "org.freedesktop.DBus"); + proxy = g_dbus_proxy_new_sync (connection, + G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES | + G_DBUS_PROXY_FLAGS_DO_NOT_CONNECT_SIGNALS, + NULL, + DBUS_SERVICE_DBUS, + DBUS_PATH_DBUS, + DBUS_INTERFACE_DBUS, + cancellable, error); + if (!proxy) + goto out; - if (!dbus_g_proxy_call (proxy, "RequestName", error, - G_TYPE_STRING, priv->dbus_service_name, - G_TYPE_UINT, 0, - G_TYPE_INVALID, - G_TYPE_UINT, &request_name_result, - G_TYPE_INVALID)) { - g_object_unref (proxy); - return FALSE; - } + ret = g_dbus_proxy_call_sync (proxy, + "RequestName", + g_variant_new ("(s)", priv->dbus_service_name), + G_DBUS_CALL_FLAGS_NONE, 0, + cancellable, error); g_object_unref (proxy); + if (!ret) + goto out; + g_variant_unref (ret); - dbus_g_connection_register_g_object (connection, - NM_VPN_DBUS_PLUGIN_PATH, - G_OBJECT (initable)); + priv->dbus_vpn_plugin = nmdbus_vpn_plugin_skeleton_new (); + if (!g_dbus_interface_skeleton_export (G_DBUS_INTERFACE_SKELETON (priv->dbus_vpn_plugin), + connection, + NM_VPN_DBUS_PLUGIN_PATH, + error)) + goto out; - plugin = NM_VPN_PLUGIN (initable); + _nm_dbus_bind_properties (plugin, priv->dbus_vpn_plugin); + _nm_dbus_bind_methods (plugin, priv->dbus_vpn_plugin, + "Connect", impl_vpn_plugin_connect, + "ConnectInteractive", impl_vpn_plugin_connect_interactive, + "NeedSecrets", impl_vpn_plugin_need_secrets, + "NewSecrets", impl_vpn_plugin_new_secrets, + "Disconnect", impl_vpn_plugin_disconnect, + "SetConfig", impl_vpn_plugin_set_config, + "SetIp4Config", impl_vpn_plugin_set_ip4_config, + "SetIp6Config", impl_vpn_plugin_set_ip6_config, + "SetFailure", impl_vpn_plugin_set_failure, + NULL); nm_vpn_plugin_set_connection (plugin, connection); nm_vpn_plugin_set_state (plugin, NM_VPN_SERVICE_STATE_INIT); - return TRUE; + success = TRUE; + + out: + g_clear_object (&connection); + + return success; } static void @@ -859,14 +859,10 @@ finalize (GObject *object) nm_vpn_plugin_set_connection (plugin, NULL); g_free (priv->dbus_service_name); - if (G_IS_VALUE (&priv->banner)) - g_value_unset (&priv->banner); - if (G_IS_VALUE (&priv->tundev)) - g_value_unset (&priv->tundev); - if (G_IS_VALUE (&priv->gateway)) - g_value_unset (&priv->gateway); - if (G_IS_VALUE (&priv->mtu)) - g_value_unset (&priv->mtu); + g_clear_pointer (&priv->banner, g_free); + g_clear_pointer (&priv->tundev, g_free); + g_clear_pointer (&priv->gateway, g_free); + g_clear_pointer (&priv->mtu, g_free); G_OBJECT_CLASS (nm_vpn_plugin_parent_class)->finalize (object); } @@ -923,9 +919,6 @@ nm_vpn_plugin_class_init (NMVpnPluginClass *plugin_class) g_type_class_add_private (object_class, sizeof (NMVpnPluginPrivate)); - dbus_g_object_type_install_info (G_TYPE_FROM_CLASS (plugin_class), - &dbus_glib_nm_vpn_plugin_object_info); - /* virtual methods */ object_class->set_property = set_property; object_class->get_property = get_property; @@ -970,7 +963,7 @@ nm_vpn_plugin_class_init (NMVpnPluginClass *plugin_class) G_SIGNAL_RUN_FIRST, G_STRUCT_OFFSET (NMVpnPluginClass, state_changed), NULL, NULL, - g_cclosure_marshal_VOID__UINT, + NULL, G_TYPE_NONE, 1, G_TYPE_UINT); @@ -988,9 +981,9 @@ nm_vpn_plugin_class_init (NMVpnPluginClass *plugin_class) G_SIGNAL_RUN_FIRST, G_STRUCT_OFFSET (NMVpnPluginClass, config), NULL, NULL, - g_cclosure_marshal_VOID__BOXED, + NULL, G_TYPE_NONE, 1, - DBUS_TYPE_G_MAP_OF_VARIANT); + G_TYPE_VARIANT); signals[IP4_CONFIG] = g_signal_new ("ip4-config", @@ -998,9 +991,9 @@ nm_vpn_plugin_class_init (NMVpnPluginClass *plugin_class) G_SIGNAL_RUN_FIRST, G_STRUCT_OFFSET (NMVpnPluginClass, ip4_config), NULL, NULL, - g_cclosure_marshal_VOID__BOXED, + NULL, G_TYPE_NONE, 1, - DBUS_TYPE_G_MAP_OF_VARIANT); + G_TYPE_VARIANT); signals[IP6_CONFIG] = g_signal_new ("ip6-config", @@ -1008,9 +1001,9 @@ nm_vpn_plugin_class_init (NMVpnPluginClass *plugin_class) G_SIGNAL_RUN_FIRST, G_STRUCT_OFFSET (NMVpnPluginClass, ip6_config), NULL, NULL, - g_cclosure_marshal_VOID__BOXED, + NULL, G_TYPE_NONE, 1, - DBUS_TYPE_G_MAP_OF_VARIANT); + G_TYPE_VARIANT); signals[LOGIN_BANNER] = g_signal_new ("login-banner", @@ -1018,7 +1011,7 @@ nm_vpn_plugin_class_init (NMVpnPluginClass *plugin_class) G_SIGNAL_RUN_FIRST, G_STRUCT_OFFSET (NMVpnPluginClass, login_banner), NULL, NULL, - g_cclosure_marshal_VOID__STRING, + NULL, G_TYPE_NONE, 1, G_TYPE_STRING); @@ -1028,7 +1021,7 @@ nm_vpn_plugin_class_init (NMVpnPluginClass *plugin_class) G_SIGNAL_RUN_FIRST, G_STRUCT_OFFSET (NMVpnPluginClass, failure), NULL, NULL, - g_cclosure_marshal_VOID__UINT, + NULL, G_TYPE_NONE, 1, G_TYPE_UINT); @@ -1038,13 +1031,13 @@ nm_vpn_plugin_class_init (NMVpnPluginClass *plugin_class) G_SIGNAL_RUN_FIRST, G_STRUCT_OFFSET (NMVpnPluginClass, quit), NULL, NULL, - g_cclosure_marshal_VOID__VOID, + NULL, G_TYPE_NONE, 0, G_TYPE_NONE); - dbus_g_error_domain_register (NM_VPN_PLUGIN_ERROR, - NM_DBUS_VPN_ERROR_PREFIX, - NM_TYPE_VPN_PLUGIN_ERROR); + _nm_dbus_register_error_domain (NM_VPN_PLUGIN_ERROR, + NM_DBUS_VPN_ERROR_PREFIX, + NM_TYPE_VPN_PLUGIN_ERROR); setup_unix_signal_handler (); } diff --git a/libnm/nm-vpn-plugin.h b/libnm/nm-vpn-plugin.h index 5f20abff64..a81a5c7abe 100644 --- a/libnm/nm-vpn-plugin.h +++ b/libnm/nm-vpn-plugin.h @@ -26,9 +26,7 @@ #error "Only can be included directly." #endif -#include -#include -#include +#include #include #include @@ -98,7 +96,7 @@ typedef struct { NMVpnServiceState state); void (*ip4_config) (NMVpnPlugin *plugin, - GHashTable *ip4_config); + GVariant *ip4_config); void (*login_banner) (NMVpnPlugin *plugin, const char *banner); @@ -109,10 +107,10 @@ typedef struct { void (*quit) (NMVpnPlugin *plugin); void (*config) (NMVpnPlugin *plugin, - GHashTable *config); + GVariant *config); void (*ip6_config) (NMVpnPlugin *plugin, - GHashTable *config); + GVariant *config); /* virtual methods */ gboolean (*connect) (NMVpnPlugin *plugin, @@ -133,7 +131,7 @@ typedef struct { gboolean (*connect_interactive) (NMVpnPlugin *plugin, NMConnection *connection, - GHashTable *details, + GVariant *details, GError **error); /*< private >*/ @@ -142,9 +140,8 @@ typedef struct { GType nm_vpn_plugin_get_type (void); GQuark nm_vpn_plugin_error_quark (void); -GType nm_vpn_plugin_error_get_type (void); -DBusGConnection *nm_vpn_plugin_get_connection (NMVpnPlugin *plugin); +GDBusConnection *nm_vpn_plugin_get_connection (NMVpnPlugin *plugin); NMVpnServiceState nm_vpn_plugin_get_state (NMVpnPlugin *plugin); void nm_vpn_plugin_set_state (NMVpnPlugin *plugin, NMVpnServiceState state); @@ -160,13 +157,13 @@ void nm_vpn_plugin_failure (NMVpnPlugin *plugin, NMVpnPluginFailure reason); void nm_vpn_plugin_set_config (NMVpnPlugin *plugin, - GHashTable *config); + GVariant *config); void nm_vpn_plugin_set_ip4_config (NMVpnPlugin *plugin, - GHashTable *ip4_config); + GVariant *ip4_config); void nm_vpn_plugin_set_ip6_config (NMVpnPlugin *plugin, - GHashTable *ip6_config); + GVariant *ip6_config); gboolean nm_vpn_plugin_disconnect (NMVpnPlugin *plugin, GError **err); diff --git a/libnm/nm-wimax-nsp.c b/libnm/nm-wimax-nsp.c index e4617ad677..57170893be 100644 --- a/libnm/nm-wimax-nsp.c +++ b/libnm/nm-wimax-nsp.c @@ -36,8 +36,6 @@ G_DEFINE_TYPE (NMWimaxNsp, nm_wimax_nsp, NM_TYPE_OBJECT) #define NM_WIMAX_NSP_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_WIMAX_NSP, NMWimaxNspPrivate)) typedef struct { - DBusGProxy *proxy; - char *name; guint32 signal_quality; NMWimaxNspNetworkType network_type; @@ -182,16 +180,6 @@ nm_wimax_nsp_init (NMWimaxNsp *nsp) { } -static void -dispose (GObject *object) -{ - NMWimaxNspPrivate *priv = NM_WIMAX_NSP_GET_PRIVATE (object); - - g_clear_object (&priv->proxy); - - G_OBJECT_CLASS (nm_wimax_nsp_parent_class)->dispose (object); -} - static void finalize (GObject *object) { @@ -239,9 +227,8 @@ init_dbus (NMObject *object) NM_OBJECT_CLASS (nm_wimax_nsp_parent_class)->init_dbus (object); - priv->proxy = _nm_object_new_proxy (object, NULL, NM_DBUS_INTERFACE_WIMAX_NSP); _nm_object_register_properties (object, - priv->proxy, + NM_DBUS_INTERFACE_WIMAX_NSP, property_info); } @@ -253,9 +240,10 @@ nm_wimax_nsp_class_init (NMWimaxNspClass *nsp_class) g_type_class_add_private (nsp_class, sizeof (NMWimaxNspPrivate)); + _nm_object_class_add_interface (nm_object_class, NM_DBUS_INTERFACE_WIMAX_NSP); + /* virtual methods */ object_class->get_property = get_property; - object_class->dispose = dispose; object_class->finalize = finalize; nm_object_class->init_dbus = init_dbus; diff --git a/libnm/tests/Makefile.am b/libnm/tests/Makefile.am index cbf2da9629..38449fad07 100644 --- a/libnm/tests/Makefile.am +++ b/libnm/tests/Makefile.am @@ -9,13 +9,11 @@ AM_CPPFLAGS = \ -DNETWORKMANAGER_COMPILATION \ -DNM_VERSION_MAX_ALLOWED=NM_VERSION_NEXT_STABLE \ -DTEST_NM_SERVICE=\"$(abs_top_srcdir)/tools/test-networkmanager-service.py\" \ - $(GLIB_CFLAGS) \ - $(DBUS_CFLAGS) + $(GLIB_CFLAGS) LDADD = \ $(top_builddir)/libnm/libnm.la \ - $(GLIB_LIBS) \ - $(DBUS_LIBS) + $(GLIB_LIBS) noinst_PROGRAMS = $(TESTS) diff --git a/libnm/tests/common.c b/libnm/tests/common.c index 818b13ee59..109ab04322 100644 --- a/libnm/tests/common.c +++ b/libnm/tests/common.c @@ -32,9 +32,9 @@ name_exists (GDBusConnection *c, const char *name) gboolean exists = FALSE; reply = g_dbus_connection_call_sync (c, - DBUS_SERVICE_DBUS, - DBUS_PATH_DBUS, - DBUS_INTERFACE_DBUS, + "org.freedesktop.DBus", + "/org/freedesktop/DBus", + "org.freedesktop.DBus", "GetNameOwner", g_variant_new ("(s)", name), NULL, diff --git a/libnm/tests/test-nm-client.c b/libnm/tests/test-nm-client.c index 269f0fdae6..92de6f87cb 100644 --- a/libnm/tests/test-nm-client.c +++ b/libnm/tests/test-nm-client.c @@ -18,9 +18,6 @@ * */ -#include -#include -#include #include #include #include diff --git a/libnm/tests/test-remote-settings-client.c b/libnm/tests/test-remote-settings-client.c index f8ea5b42a3..7543d2cf6e 100644 --- a/libnm/tests/test-remote-settings-client.c +++ b/libnm/tests/test-remote-settings-client.c @@ -18,9 +18,6 @@ * */ -#include -#include -#include #include #include #include @@ -34,7 +31,7 @@ static NMTestServiceInfo *sinfo; static NMRemoteSettings *settings = NULL; -DBusGConnection *bus = NULL; +GDBusConnection *bus = NULL; NMRemoteConnection *remote = NULL; /*******************************************************************/ @@ -88,16 +85,16 @@ test_add_connection (void) /*******************************************************************/ static void -set_visible_cb (DBusGProxy *proxy, - DBusGProxyCall *call, +set_visible_cb (GObject *proxy, + GAsyncResult *result, gpointer user_data) { GError *error = NULL; - gboolean success; + GVariant *ret; - success = dbus_g_proxy_end_call (proxy, call, &error, G_TYPE_INVALID); + ret = g_dbus_proxy_call_finish (G_DBUS_PROXY (proxy), result, &error); g_assert_no_error (error); - g_assert (success == TRUE); + g_variant_unref (ret); } static void @@ -129,7 +126,7 @@ test_make_invisible (void) { time_t start, now; GSList *list, *iter; - DBusGProxy *proxy; + GDBusProxy *proxy; gboolean visible_changed = FALSE, connection_removed = FALSE; gboolean has_settings = FALSE; char *path; @@ -141,15 +138,23 @@ test_make_invisible (void) g_signal_connect (settings, "connection-removed", G_CALLBACK (connection_removed_cb), &connection_removed); path = g_strdup (nm_connection_get_path (NM_CONNECTION (remote))); - proxy = dbus_g_proxy_new_for_name (bus, - NM_DBUS_SERVICE, - path, - NM_DBUS_INTERFACE_SETTINGS_CONNECTION); + proxy = g_dbus_proxy_new_sync (bus, + G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES, + NULL, + NM_DBUS_SERVICE, + path, + NM_DBUS_INTERFACE_SETTINGS_CONNECTION, + NULL, + NULL); g_assert (proxy != NULL); /* Bypass the NMRemoteSettings object so we can test it independently */ - dbus_g_proxy_begin_call (proxy, "SetVisible", set_visible_cb, NULL, NULL, - G_TYPE_BOOLEAN, FALSE, G_TYPE_INVALID); + g_dbus_proxy_call (proxy, + "SetVisible", + g_variant_new ("(b)", FALSE), + G_DBUS_CALL_FLAGS_NONE, -1, + NULL, + set_visible_cb, NULL); /* Wait for the connection to be removed */ start = time (NULL); @@ -198,7 +203,7 @@ test_make_visible (void) { time_t start, now; GSList *list, *iter; - DBusGProxy *proxy; + GDBusProxy *proxy; gboolean found = FALSE; char *path; NMRemoteConnection *new = NULL; @@ -210,16 +215,23 @@ test_make_visible (void) G_CALLBACK (vis_new_connection_cb), &new); path = g_strdup (nm_connection_get_path (NM_CONNECTION (remote))); - proxy = dbus_g_proxy_new_for_name (bus, - NM_DBUS_SERVICE, - path, - NM_DBUS_INTERFACE_SETTINGS_CONNECTION); + proxy = g_dbus_proxy_new_sync (bus, + G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES, + NULL, + NM_DBUS_SERVICE, + path, + NM_DBUS_INTERFACE_SETTINGS_CONNECTION, + NULL, + NULL); g_assert (proxy != NULL); /* Bypass the NMRemoteSettings object so we can test it independently */ - dbus_g_proxy_begin_call (proxy, "SetVisible", set_visible_cb, NULL, NULL, - G_TYPE_BOOLEAN, TRUE, G_TYPE_INVALID); - + g_dbus_proxy_call (proxy, + "SetVisible", + g_variant_new ("(b)", TRUE), + G_DBUS_CALL_FLAGS_NONE, -1, + NULL, + set_visible_cb, NULL); /* Wait for the settings service to announce the connection again */ start = time (NULL); @@ -255,16 +267,16 @@ test_make_visible (void) /*******************************************************************/ static void -deleted_cb (DBusGProxy *proxy, - DBusGProxyCall *call, +deleted_cb (GObject *proxy, + GAsyncResult *result, gpointer user_data) { GError *error = NULL; - gboolean success; + GVariant *ret; - success = dbus_g_proxy_end_call (proxy, call, &error, G_TYPE_INVALID); + ret = g_dbus_proxy_call_finish (G_DBUS_PROXY (proxy), result, &error); g_assert_no_error (error); - g_assert (success == TRUE); + g_variant_unref (ret); } static void @@ -280,7 +292,7 @@ test_remove_connection (void) NMRemoteConnection *connection; time_t start, now; GSList *list, *iter; - DBusGProxy *proxy; + GDBusProxy *proxy; gboolean done = FALSE; char *path; @@ -294,14 +306,23 @@ test_remove_connection (void) path = g_strdup (nm_connection_get_path (NM_CONNECTION (connection))); g_signal_connect (settings, "connection-removed", G_CALLBACK (removed_cb), &done); - proxy = dbus_g_proxy_new_for_name (bus, - NM_DBUS_SERVICE, - path, - NM_DBUS_INTERFACE_SETTINGS_CONNECTION); + proxy = g_dbus_proxy_new_sync (bus, + G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES, + NULL, + NM_DBUS_SERVICE, + path, + NM_DBUS_INTERFACE_SETTINGS_CONNECTION, + NULL, + NULL); g_assert (proxy != NULL); /* Bypass the NMRemoteSettings object so we can test it independently */ - dbus_g_proxy_begin_call (proxy, "Delete", deleted_cb, NULL, NULL, G_TYPE_INVALID); + g_dbus_proxy_call (proxy, + "Delete", + NULL, + G_DBUS_CALL_FLAGS_NONE, -1, + NULL, + deleted_cb, NULL); start = time (NULL); do { @@ -481,7 +502,7 @@ main (int argc, char **argv) g_test_init (&argc, &argv, NULL); - bus = dbus_g_bus_get (DBUS_BUS_SESSION, &error); + bus = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, &error); g_assert_no_error (error); sinfo = nm_test_service_init (); @@ -504,7 +525,7 @@ main (int argc, char **argv) nm_test_service_cleanup (sinfo); g_object_unref (settings); - dbus_g_connection_unref (bus); + g_object_unref (bus); return ret; } diff --git a/libnm/tests/test-secret-agent.c b/libnm/tests/test-secret-agent.c index bd540124c6..27b844d1d4 100644 --- a/libnm/tests/test-secret-agent.c +++ b/libnm/tests/test-secret-agent.c @@ -61,8 +61,8 @@ test_secret_agent_get_secrets (NMSecretAgent *agent, gpointer callback_data) { NMSettingWirelessSecurity *s_wsec; - GHashTable *hash = NULL, *setting_hash; - GValue value = G_VALUE_INIT; + GVariant *secrets = NULL; + GVariantBuilder secrets_builder, setting_builder; char *secret = NULL; GError *error = NULL; @@ -92,20 +92,21 @@ test_secret_agent_get_secrets (NMSecretAgent *agent, goto done; } - hash = g_hash_table_new_full (g_str_hash, g_str_equal, - NULL, (GDestroyNotify) g_hash_table_unref); - setting_hash = g_hash_table_new (g_str_hash, g_str_equal); - g_hash_table_insert (hash, (char *) setting_name, setting_hash); + g_variant_builder_init (&setting_builder, NM_VARIANT_TYPE_SETTING); + g_variant_builder_add (&setting_builder, "{sv}", + NM_SETTING_WIRELESS_SECURITY_PSK, + g_variant_new_string (secret)); - g_value_init (&value, G_TYPE_STRING); - g_value_set_string (&value, secret); - - g_hash_table_insert (setting_hash, NM_SETTING_WIRELESS_SECURITY_PSK, &value); + g_variant_builder_init (&secrets_builder, NM_VARIANT_TYPE_CONNECTION); + g_variant_builder_add (&secrets_builder, "{sa{sv}}", + setting_name, + &setting_builder); + secrets = g_variant_ref_sink (g_variant_builder_end (&secrets_builder)); done: - callback (agent, connection, hash, error, callback_data); + callback (agent, connection, secrets, error, callback_data); g_clear_error (&error); - g_clear_pointer (&hash, g_hash_table_unref); + g_clear_pointer (&secrets, g_variant_unref); g_free (secret); } @@ -386,6 +387,7 @@ connection_activated_none_cb (NMClient *c, TestSecretAgentData *sadata = user_data; g_assert (error != NULL); + g_dbus_error_strip_remote_error (error); g_assert_cmpstr (error->message, ==, "No secret agent available"); g_main_loop_quit (sadata->loop); @@ -430,6 +432,7 @@ connection_activated_no_secrets_cb (NMClient *c, TestSecretAgentData *sadata = user_data; g_assert (error != NULL); + g_dbus_error_strip_remote_error (error); g_assert_cmpstr (error->message, ==, "No secrets provided"); g_main_loop_quit (sadata->loop); @@ -464,6 +467,7 @@ connection_activated_cancel_cb (NMClient *c, TestSecretAgentData *sadata = user_data; g_assert (error != NULL); + g_dbus_error_strip_remote_error (error); g_assert_cmpstr (error->message, ==, "User canceled"); g_main_loop_quit (sadata->loop); @@ -518,6 +522,7 @@ connection_activated_good_cb (NMClient *c, * other tests won't get to). */ g_assert (error != NULL); + g_dbus_error_strip_remote_error (error); g_assert_cmpstr (error->message, ==, "Not yet implemented"); g_main_loop_quit (sadata->loop); diff --git a/src/NetworkManagerUtils.c b/src/NetworkManagerUtils.c index b665984fe0..63648e3322 100644 --- a/src/NetworkManagerUtils.c +++ b/src/NetworkManagerUtils.c @@ -46,6 +46,7 @@ #include "nm-setting-wireless-security.h" #include "nm-manager-auth.h" #include "nm-posix-signals.h" +#include "nm-dbus-glib-types.h" /* * Some toolchains (E.G. uClibc 0.9.33 and earlier) don't export @@ -1840,3 +1841,147 @@ nm_utils_ipv6_interface_identfier_get_from_addr (NMUtilsIPv6IfaceId *iid, memcpy (iid, addr->s6_addr + 8, 8); } +/** + * nm_utils_connection_hash_to_dict: + * @hash: a hashed #NMConnection + * + * Returns: a (floating) #GVariant equivalent to @hash. + */ +GVariant * +nm_utils_connection_hash_to_dict (GHashTable *hash) +{ + GValue val = { 0, }; + GVariant *variant; + + if (!hash) + return NULL; + + g_value_init (&val, DBUS_TYPE_G_MAP_OF_MAP_OF_VARIANT); + g_value_set_boxed (&val, hash); + variant = dbus_g_value_build_g_variant (&val); + g_value_unset (&val); + + return variant; +} + +/** + * nm_utils_connection_dict_to_hash: + * @dict: a #GVariant-serialized #NMConnection + * + * Returns: a #GHashTable equivalent to @dict. + */ +GHashTable * +nm_utils_connection_dict_to_hash (GVariant *dict) +{ + GValue val = { 0, }; + + if (!dict) + return NULL; + + dbus_g_value_parse_g_variant (dict, &val); + return g_value_get_boxed (&val); +} + +GSList * +nm_utils_ip4_routes_from_gvalue (const GValue *value) +{ + GPtrArray *routes; + int i; + GSList *list = NULL; + + routes = (GPtrArray *) g_value_get_boxed (value); + for (i = 0; routes && (i < routes->len); i++) { + GArray *array = (GArray *) g_ptr_array_index (routes, i); + NMIP4Route *route; + + if (array->len < 4) { + g_warning ("Ignoring invalid IP4 route"); + continue; + } + + route = nm_ip4_route_new (); + nm_ip4_route_set_dest (route, g_array_index (array, guint32, 0)); + nm_ip4_route_set_prefix (route, g_array_index (array, guint32, 1)); + nm_ip4_route_set_next_hop (route, g_array_index (array, guint32, 2)); + nm_ip4_route_set_metric (route, g_array_index (array, guint32, 3)); + list = g_slist_prepend (list, route); + } + + return g_slist_reverse (list); +} + +static gboolean +_nm_utils_gvalue_array_validate (GValueArray *elements, guint n_expected, ...) +{ + va_list args; + GValue *tmp; + int i; + gboolean valid = FALSE; + + if (n_expected != elements->n_values) + return FALSE; + + va_start (args, n_expected); + for (i = 0; i < n_expected; i++) { + tmp = g_value_array_get_nth (elements, i); + if (G_VALUE_TYPE (tmp) != va_arg (args, GType)) + goto done; + } + valid = TRUE; + +done: + va_end (args); + return valid; +} + +GSList * +nm_utils_ip6_routes_from_gvalue (const GValue *value) +{ + GPtrArray *routes; + int i; + GSList *list = NULL; + + routes = (GPtrArray *) g_value_get_boxed (value); + for (i = 0; routes && (i < routes->len); i++) { + GValueArray *route_values = (GValueArray *) g_ptr_array_index (routes, i); + GByteArray *dest, *next_hop; + guint prefix, metric; + NMIP6Route *route; + + if (!_nm_utils_gvalue_array_validate (route_values, 4, + DBUS_TYPE_G_UCHAR_ARRAY, + G_TYPE_UINT, + DBUS_TYPE_G_UCHAR_ARRAY, + G_TYPE_UINT)) { + g_warning ("Ignoring invalid IP6 route"); + continue; + } + + dest = g_value_get_boxed (g_value_array_get_nth (route_values, 0)); + if (dest->len != 16) { + g_warning ("%s: ignoring invalid IP6 dest address of length %d", + __func__, dest->len); + continue; + } + + prefix = g_value_get_uint (g_value_array_get_nth (route_values, 1)); + + next_hop = g_value_get_boxed (g_value_array_get_nth (route_values, 2)); + if (next_hop->len != 16) { + g_warning ("%s: ignoring invalid IP6 next_hop address of length %d", + __func__, next_hop->len); + continue; + } + + metric = g_value_get_uint (g_value_array_get_nth (route_values, 3)); + + route = nm_ip6_route_new (); + nm_ip6_route_set_dest (route, (struct in6_addr *)dest->data); + nm_ip6_route_set_prefix (route, prefix); + nm_ip6_route_set_next_hop (route, (struct in6_addr *)next_hop->data); + nm_ip6_route_set_metric (route, metric); + list = g_slist_prepend (list, route); + } + + return g_slist_reverse (list); +} diff --git a/src/NetworkManagerUtils.h b/src/NetworkManagerUtils.h index 9a31053326..0996276a6e 100644 --- a/src/NetworkManagerUtils.h +++ b/src/NetworkManagerUtils.h @@ -167,4 +167,10 @@ void nm_utils_ipv6_addr_set_interface_identfier (struct in6_addr *addr, void nm_utils_ipv6_interface_identfier_get_from_addr (NMUtilsIPv6IfaceId *iid, const struct in6_addr *addr); +GVariant *nm_utils_connection_hash_to_dict (GHashTable *hash); +GHashTable *nm_utils_connection_dict_to_hash (GVariant *dict); + +GSList *nm_utils_ip4_routes_from_gvalue (const GValue *value); +GSList *nm_utils_ip6_routes_from_gvalue (const GValue *value); + #endif /* __NETWORKMANAGER_UTILS_H__ */ diff --git a/src/nm-dispatcher.c b/src/nm-dispatcher.c index 752b1baf04..e77cca6f5d 100644 --- a/src/nm-dispatcher.c +++ b/src/nm-dispatcher.c @@ -471,7 +471,11 @@ _dispatcher_call (DispatcherAction action, } if (connection) { - connection_hash = nm_connection_to_dbus (connection, NM_CONNECTION_SERIALIZE_NO_SECRETS); + GVariant *connection_dict; + + connection_dict = nm_connection_to_dbus (connection, NM_CONNECTION_SERIALIZE_NO_SECRETS); + connection_hash = nm_utils_connection_dict_to_hash (connection_dict); + g_variant_unref (connection_dict); connection_props = value_hash_create (); value_hash_add_object_path (connection_props, diff --git a/src/nm-manager.c b/src/nm-manager.c index 09a994c63f..e08e595877 100644 --- a/src/nm-manager.c +++ b/src/nm-manager.c @@ -3296,8 +3296,12 @@ impl_manager_add_and_activate_connection (NMManager *self, * validate_activation_request()). */ connection = nm_simple_connection_new (); - if (settings && g_hash_table_size (settings)) - nm_connection_replace_settings (connection, settings, NULL); + if (settings && g_hash_table_size (settings)) { + GVariant *settings_dict = nm_utils_connection_hash_to_dict (settings); + + nm_connection_replace_settings (connection, settings_dict, NULL); + g_variant_unref (settings_dict); + } subject = validate_activation_request (self, context, diff --git a/src/settings/nm-agent-manager.c b/src/settings/nm-agent-manager.c index a2c0c6bb5f..333cbb261e 100644 --- a/src/settings/nm-agent-manager.c +++ b/src/settings/nm-agent-manager.c @@ -40,6 +40,7 @@ #include "nm-dbus-manager.h" #include "nm-session-monitor.h" #include "nm-simple-connection.h" +#include "NetworkManagerUtils.h" G_DEFINE_TYPE (NMAgentManager, nm_agent_manager, G_TYPE_OBJECT) @@ -910,8 +911,13 @@ get_agent_request_secrets (ConnectionRequest *req, gboolean include_system_secre tmp = nm_simple_connection_new_clone (req->connection); nm_connection_clear_secrets (tmp); if (include_system_secrets) { - if (req->existing_secrets) - (void) nm_connection_update_secrets (tmp, req->setting_name, req->existing_secrets, NULL); + if (req->existing_secrets) { + GVariant *secrets_dict; + + secrets_dict = nm_utils_connection_hash_to_dict (req->existing_secrets); + (void) nm_connection_update_secrets (tmp, req->setting_name, secrets_dict, NULL); + g_variant_unref (secrets_dict); + } } else { /* Update secret flags in the temporary connection to indicate that * the system secrets we're not sending to the agent aren't required, @@ -1085,6 +1091,7 @@ get_start (gpointer user_data) NMConnection *tmp; GError *error = NULL; gboolean new_secrets = (req->flags & NM_SECRET_AGENT_GET_SECRETS_FLAG_REQUEST_NEW); + GVariant *secrets_dict; /* The connection already had secrets; check if any more are required. * If no more are required, we're done. If secrets are still needed, @@ -1094,7 +1101,8 @@ get_start (gpointer user_data) tmp = nm_simple_connection_new_clone (req->connection); g_assert (tmp); - if (!nm_connection_update_secrets (tmp, req->setting_name, req->existing_secrets, &error)) { + secrets_dict = nm_utils_connection_hash_to_dict (req->existing_secrets); + if (!nm_connection_update_secrets (tmp, req->setting_name, secrets_dict, &error)) { req_complete_error (parent, error); g_clear_error (&error); } else { @@ -1114,6 +1122,7 @@ get_start (gpointer user_data) request_next_agent (parent); } } + g_variant_unref (secrets_dict); g_object_unref (tmp); } else { /* Couldn't get secrets from system settings, so now we ask the diff --git a/src/settings/nm-secret-agent.c b/src/settings/nm-secret-agent.c index 97728f804c..a1c6954ee2 100644 --- a/src/settings/nm-secret-agent.c +++ b/src/settings/nm-secret-agent.c @@ -35,6 +35,7 @@ #include "nm-logging.h" #include "nm-auth-subject.h" #include "nm-simple-connection.h" +#include "NetworkManagerUtils.h" G_DEFINE_TYPE (NMSecretAgent, nm_secret_agent, G_TYPE_OBJECT) @@ -283,6 +284,7 @@ nm_secret_agent_get_secrets (NMSecretAgent *self, gpointer callback_data) { NMSecretAgentPrivate *priv; + GVariant *dict; GHashTable *hash; Request *r; @@ -293,7 +295,9 @@ nm_secret_agent_get_secrets (NMSecretAgent *self, priv = NM_SECRET_AGENT_GET_PRIVATE (self); g_return_val_if_fail (priv->proxy != NULL, NULL); - hash = nm_connection_to_dbus (connection, NM_CONNECTION_SERIALIZE_ALL); + dict = nm_connection_to_dbus (connection, NM_CONNECTION_SERIALIZE_ALL); + hash = nm_utils_connection_dict_to_hash (dict); + g_variant_unref (dict); /* Mask off the private ONLY_SYSTEM flag if present */ flags &= ~NM_SECRET_AGENT_GET_SECRETS_FLAG_ONLY_SYSTEM; @@ -385,11 +389,14 @@ agent_new_save_delete (NMSecretAgent *self, gpointer callback_data) { NMSecretAgentPrivate *priv = NM_SECRET_AGENT_GET_PRIVATE (self); + GVariant *dict; GHashTable *hash; Request *r; const char *cpath = nm_connection_get_path (connection); - hash = nm_connection_to_dbus (connection, flags); + dict = nm_connection_to_dbus (connection, flags); + hash = nm_utils_connection_dict_to_hash (dict); + g_variant_unref (dict); r = request_new (self, cpath, NULL, callback, callback_data); r->call = dbus_g_proxy_begin_call_with_timeout (priv->proxy, diff --git a/src/settings/nm-settings-connection.c b/src/settings/nm-settings-connection.c index 513e6efc13..db382adb82 100644 --- a/src/settings/nm-settings-connection.c +++ b/src/settings/nm-settings-connection.c @@ -29,7 +29,6 @@ #include #include #include -#include "nm-core-internal.h" #include "nm-settings-connection.h" #include "nm-session-monitor.h" @@ -440,7 +439,6 @@ nm_settings_connection_replace_settings (NMSettingsConnection *self, GError **error) { NMSettingsConnectionPrivate *priv; - GHashTable *hash = NULL; gboolean success = FALSE; g_return_val_if_fail (NM_IS_SETTINGS_CONNECTION (self), FALSE); @@ -476,10 +474,12 @@ nm_settings_connection_replace_settings (NMSettingsConnection *self, * in the replacement connection data if it was eg reread from disk. */ if (priv->agent_secrets) { - hash = nm_connection_to_dbus (priv->agent_secrets, NM_CONNECTION_SERIALIZE_ONLY_SECRETS); - if (hash) { - (void) nm_connection_update_secrets (NM_CONNECTION (self), NULL, hash, NULL); - g_hash_table_destroy (hash); + GVariant *dict; + + dict = nm_connection_to_dbus (priv->agent_secrets, NM_CONNECTION_SERIALIZE_ONLY_SECRETS); + if (dict) { + (void) nm_connection_update_secrets (NM_CONNECTION (self), NULL, dict, NULL); + g_variant_unref (dict); } } @@ -725,7 +725,7 @@ agent_secrets_done_cb (NMAgentManager *manager, NMSettingsConnectionSecretsFunc callback = other_data2; gpointer callback_data = other_data3; GError *local = NULL; - GHashTable *hash; + GVariant *dict; gboolean agent_had_system = FALSE; if (error) { @@ -808,14 +808,17 @@ agent_secrets_done_cb (NMAgentManager *manager, /* Update the connection with our existing secrets from backing storage */ nm_connection_clear_secrets (NM_CONNECTION (self)); - hash = nm_connection_to_dbus (priv->system_secrets, NM_CONNECTION_SERIALIZE_ONLY_SECRETS); - if (!hash || nm_connection_update_secrets (NM_CONNECTION (self), setting_name, hash, &local)) { + dict = nm_connection_to_dbus (priv->system_secrets, NM_CONNECTION_SERIALIZE_ONLY_SECRETS); + if (!dict || nm_connection_update_secrets (NM_CONNECTION (self), setting_name, dict, &local)) { + GVariant *secrets_dict; + /* Update the connection with the agent's secrets; by this point if any * system-owned secrets exist in 'secrets' the agent that provided them * will have been authenticated, so those secrets can replace the existing * system secrets. */ - if (nm_connection_update_secrets (NM_CONNECTION (self), setting_name, secrets, &local)) { + secrets_dict = nm_utils_connection_hash_to_dict (secrets); + if (nm_connection_update_secrets (NM_CONNECTION (self), setting_name, secrets_dict, &local)) { /* Now that all secrets are updated, copy and cache new secrets, * then save them to backing storage. */ @@ -848,6 +851,7 @@ agent_secrets_done_cb (NMAgentManager *manager, local ? local->code : -1, (local && local->message) ? local->message : "(unknown)"); } + g_variant_unref (secrets_dict); } else { nm_log_dbg (LOGD_SETTINGS, "(%s/%s:%u) failed to update with existing secrets: (%d) %s", nm_connection_get_uuid (NM_CONNECTION (self)), @@ -859,8 +863,8 @@ agent_secrets_done_cb (NMAgentManager *manager, callback (self, call_id, agent_username, setting_name, local, callback_data); g_clear_error (&local); - if (hash) - g_hash_table_destroy (hash); + if (dict) + g_variant_unref (dict); } /** @@ -890,7 +894,8 @@ nm_settings_connection_get_secrets (NMSettingsConnection *self, GError **error) { NMSettingsConnectionPrivate *priv = NM_SETTINGS_CONNECTION_GET_PRIVATE (self); - GHashTable *existing_secrets; + GVariant *existing_secrets; + GHashTable *existing_secrets_hash; guint32 call_id = 0; char *joined_hints = NULL; @@ -913,10 +918,11 @@ nm_settings_connection_get_secrets (NMSettingsConnection *self, } existing_secrets = nm_connection_to_dbus (priv->system_secrets, NM_CONNECTION_SERIALIZE_ONLY_SECRETS); + existing_secrets_hash = nm_utils_connection_dict_to_hash (existing_secrets); call_id = nm_agent_manager_get_secrets (priv->agent_mgr, NM_CONNECTION (self), subject, - existing_secrets, + existing_secrets_hash, setting_name, flags, hints, @@ -924,8 +930,10 @@ nm_settings_connection_get_secrets (NMSettingsConnection *self, self, callback, callback_data); + if (existing_secrets_hash) + g_hash_table_unref (existing_secrets_hash); if (existing_secrets) - g_hash_table_unref (existing_secrets); + g_variant_unref (existing_secrets); if (nm_logging_enabled (LOGL_DEBUG, LOGD_SETTINGS)) { if (hints) @@ -1130,7 +1138,8 @@ get_settings_auth_cb (NMSettingsConnection *self, if (error) dbus_g_method_return_error (context, error); else { - GHashTable *settings; + GVariant *settings; + GHashTable *settings_hash; NMConnection *dupl_con; NMSettingConnection *s_con; NMSettingWireless *s_wifi; @@ -1168,8 +1177,10 @@ get_settings_auth_cb (NMSettingsConnection *self, */ settings = nm_connection_to_dbus (NM_CONNECTION (dupl_con), NM_CONNECTION_SERIALIZE_NO_SECRETS); g_assert (settings); - dbus_g_method_return (context, settings); - g_hash_table_destroy (settings); + settings_hash = nm_utils_connection_dict_to_hash (settings); + dbus_g_method_return (context, settings_hash); + g_hash_table_destroy (settings_hash); + g_variant_unref (settings); g_object_unref (dupl_con); } } @@ -1328,7 +1339,10 @@ impl_settings_connection_update_helper (NMSettingsConnection *self, /* Check if the settings are valid first */ if (new_settings) { - tmp = nm_simple_connection_new_from_dbus (new_settings, &error); + GVariant *new_settings_dict = nm_utils_connection_hash_to_dict (new_settings); + + tmp = nm_simple_connection_new_from_dbus (new_settings_dict, &error); + g_variant_unref (new_settings_dict); if (!tmp) { g_assert (error); goto error; @@ -1483,6 +1497,7 @@ dbus_get_agent_secrets_cb (NMSettingsConnection *self, { NMSettingsConnectionPrivate *priv = NM_SETTINGS_CONNECTION_GET_PRIVATE (self); DBusGMethodInvocation *context = user_data; + GVariant *dict; GHashTable *hash; priv->reqs = g_slist_remove (priv->reqs, GUINT_TO_POINTER (call_id)); @@ -1495,11 +1510,15 @@ dbus_get_agent_secrets_cb (NMSettingsConnection *self, * secrets from backing storage and those returned from the agent * by the time we get here. */ - hash = nm_connection_to_dbus (NM_CONNECTION (self), NM_CONNECTION_SERIALIZE_ONLY_SECRETS); - if (!hash) + dict = nm_connection_to_dbus (NM_CONNECTION (self), NM_CONNECTION_SERIALIZE_ONLY_SECRETS); + if (dict) + hash = nm_utils_connection_dict_to_hash (dict); + else hash = g_hash_table_new (NULL, NULL); dbus_g_method_return (context, hash); g_hash_table_destroy (hash); + if (dict) + g_variant_unref (dict); } } diff --git a/src/settings/nm-settings.c b/src/settings/nm-settings.c index 0ad85e614f..a4339ed492 100644 --- a/src/settings/nm-settings.c +++ b/src/settings/nm-settings.c @@ -1221,9 +1221,12 @@ impl_settings_add_connection_helper (NMSettings *self, DBusGMethodInvocation *context) { NMConnection *connection; + GVariant *dict; GError *error = NULL; - connection = nm_simple_connection_new_from_dbus (settings, &error); + dict = nm_utils_connection_hash_to_dict (settings); + connection = nm_simple_connection_new_from_dbus (dict, &error); + g_variant_unref (dict); if (connection) { nm_settings_add_connection_dbus (self, connection, diff --git a/src/vpn-manager/nm-vpn-connection.c b/src/vpn-manager/nm-vpn-connection.c index d11a1fe60a..50539d3604 100644 --- a/src/vpn-manager/nm-vpn-connection.c +++ b/src/vpn-manager/nm-vpn-connection.c @@ -1457,6 +1457,7 @@ _hash_with_username (NMConnection *connection, const char *username) NMConnection *dup; NMSettingVpn *s_vpn; GHashTable *hash; + GVariant *dict; const char *existing; /* Shortcut if we weren't given a username or if there already was one in @@ -1465,16 +1466,23 @@ _hash_with_username (NMConnection *connection, const char *username) s_vpn = nm_connection_get_setting_vpn (connection); g_assert (s_vpn); existing = nm_setting_vpn_get_user_name (s_vpn); - if (username == NULL || existing) - return nm_connection_to_dbus (connection, NM_CONNECTION_SERIALIZE_ALL); + if (username == NULL || existing) { + dict = nm_connection_to_dbus (connection, NM_CONNECTION_SERIALIZE_ALL); + hash = nm_utils_connection_dict_to_hash (dict); + g_variant_unref (dict); + return hash; + } dup = nm_simple_connection_new_clone (connection); g_assert (dup); s_vpn = nm_connection_get_setting_vpn (dup); g_assert (s_vpn); g_object_set (s_vpn, NM_SETTING_VPN_USER_NAME, username, NULL); - hash = nm_connection_to_dbus (dup, NM_CONNECTION_SERIALIZE_ALL); + dict = nm_connection_to_dbus (dup, NM_CONNECTION_SERIALIZE_ALL); g_object_unref (dup); + + hash = nm_utils_connection_dict_to_hash (dict); + g_variant_unref (dict); return hash; } diff --git a/tools/test-networkmanager-service.py b/tools/test-networkmanager-service.py index 7716dca9ac..defc320937 100755 --- a/tools/test-networkmanager-service.py +++ b/tools/test-networkmanager-service.py @@ -843,6 +843,7 @@ class Settings(dbus.service.Object): self.props = {} self.props['Hostname'] = "foobar.baz" self.props['CanModify'] = True + self.props['Connections'] = dbus.Array([], 'o') def auto_remove_next_connection(self): self.remove_next_connection = True; @@ -859,8 +860,9 @@ class Settings(dbus.service.Object): path = "/org/freedesktop/NetworkManager/Settings/Connection/{0}".format(self.counter) self.counter = self.counter + 1 self.connections[path] = Connection(self.bus, path, settings, self.delete_connection) + self.props['Connections'] = dbus.Array(self.connections.keys(), 'o') self.NewConnection(path) - self.PropertiesChanged({ 'connections': dbus.Array(self.connections.keys(), 'o') }) + self.PropertiesChanged({ 'connections': self.props['Connections'] }) if self.remove_next_connection: self.remove_next_connection = False @@ -870,7 +872,8 @@ class Settings(dbus.service.Object): def delete_connection(self, connection): del self.connections[connection.path] - self.PropertiesChanged({ 'connections': dbus.Array(self.connections.keys(), 'o') }) + self.props['Connections'] = dbus.Array(self.connections.keys(), 'o') + self.PropertiesChanged({ 'connections': self.props['Connections'] }) @dbus.service.method(dbus_interface=dbus.PROPERTIES_IFACE, in_signature='s', out_signature='a{sv}') def GetAll(self, iface):