diff options
author | Thomas Haller <thaller@redhat.com> | 2019-08-11 11:04:44 +0200 |
---|---|---|
committer | Thomas Haller <thaller@redhat.com> | 2019-09-22 16:05:50 +0200 |
commit | d048050c2d4545cc6914e23548424a5b0519d2b9 (patch) | |
tree | 9418dbf3739f5725671def76e5dd50d5d7c7e7bf | |
parent | c73b5c1be0c683f234ce7e4b2cdcefa1882e6262 (diff) | |
download | NetworkManager-d048050c2d4545cc6914e23548424a5b0519d2b9.tar.gz |
shared: add more nm_dbus_connection_call_*() and nm_dbus_connection_signal_subscribe_*() helpers
-rw-r--r-- | shared/nm-glib-aux/nm-dbus-aux.c | 192 | ||||
-rw-r--r-- | shared/nm-glib-aux/nm-dbus-aux.h | 100 |
2 files changed, 287 insertions, 5 deletions
diff --git a/shared/nm-glib-aux/nm-dbus-aux.c b/shared/nm-glib-aux/nm-dbus-aux.c index 4b8c629e2c..51db326a75 100644 --- a/shared/nm-glib-aux/nm-dbus-aux.c +++ b/shared/nm-glib-aux/nm-dbus-aux.c @@ -53,3 +53,195 @@ nm_dbus_connection_call_get_name_owner (GDBusConnection *dbus_connection, _nm_dbus_connection_call_get_name_owner_cb, nm_utils_user_data_pack (user_data, callback)); } + +/*****************************************************************************/ + +static void +_nm_dbus_connection_call_get_all_cb (GObject *source, + GAsyncResult *res, + gpointer user_data) +{ + gs_unref_variant GVariant *ret = NULL; + gs_free_error GError *error = NULL; + gpointer orig_user_data; + NMDBusConnectionCallDefaultCb callback; + + nm_utils_user_data_unpack (user_data, &orig_user_data, &callback); + + ret = g_dbus_connection_call_finish (G_DBUS_CONNECTION (source), res, &error); + + nm_assert ((!!ret) != (!!error)); + + callback (ret, error, orig_user_data); +} + +void +nm_dbus_connection_call_get_all (GDBusConnection *dbus_connection, + const char *bus_name, + const char *object_path, + const char *interface_name, + int timeout_msec, + GCancellable *cancellable, + NMDBusConnectionCallDefaultCb callback, + gpointer user_data) +{ + nm_assert (callback); + + g_dbus_connection_call (dbus_connection, + bus_name, + object_path, + DBUS_INTERFACE_PROPERTIES, + "GetAll", + g_variant_new ("(s)", interface_name), + G_VARIANT_TYPE ("(a{sv})"), + G_DBUS_CALL_FLAGS_NONE, + timeout_msec, + cancellable, + _nm_dbus_connection_call_get_all_cb, + nm_utils_user_data_pack (user_data, callback)); +} + +/*****************************************************************************/ + +typedef struct { + NMDBusConnectionSignalObjectMangerCb callback; + gpointer user_data; + GDestroyNotify user_data_free_func; +} SubscribeObjectManagerData; + +static void +_subscribe_object_manager_cb (GDBusConnection *connection, + const char *sender_name, + const char *arg_object_path, + const char *interface_name, + const char *signal_name, + GVariant *parameters, + gpointer user_data) +{ + const SubscribeObjectManagerData *d = user_data; + + nm_assert (nm_streq0 (interface_name, DBUS_INTERFACE_OBJECT_MANAGER)); + + if (nm_streq (signal_name, "InterfacesAdded")) { + gs_unref_variant GVariant *interfaces_and_properties = NULL; + const char *object_path; + + if (!g_variant_is_of_type (parameters, G_VARIANT_TYPE ("(oa{sa{sv}})"))) + return; + + g_variant_get (parameters, + "(&o@a{sa{sv}})", + &object_path, + &interfaces_and_properties); + + d->callback (object_path, interfaces_and_properties, NULL, d->user_data); + return; + } + + if (nm_streq (signal_name, "InterfacesRemoved")) { + gs_free const char **interfaces = NULL; + const char *object_path; + + if (!g_variant_is_of_type (parameters, G_VARIANT_TYPE ("(oas)"))) + return; + + g_variant_get (parameters, + "(&o^a&s)", + &object_path, + &interfaces); + + d->callback (object_path, NULL, interfaces, d->user_data); + return; + } +} + +static void +_subscribe_object_manager_data_free (gpointer ptr) +{ + SubscribeObjectManagerData *d = ptr; + + if (d->user_data_free_func) + d->user_data_free_func (d->user_data); + nm_g_slice_free (d); +} + +guint +nm_dbus_connection_signal_subscribe_object_manager (GDBusConnection *dbus_connection, + const char *service_name, + const char *object_path, + NMDBusConnectionSignalObjectMangerCb callback, + gpointer user_data, + GDestroyNotify user_data_free_func) +{ + SubscribeObjectManagerData *d; + + g_return_val_if_fail (callback, 0); + + d = g_slice_new (SubscribeObjectManagerData); + *d = (SubscribeObjectManagerData) { + .callback = callback, + .user_data = user_data, + .user_data_free_func = user_data_free_func, + }; + + return nm_dbus_connection_signal_subscribe_object_manager_plain (dbus_connection, + service_name, + object_path, + NULL, + _subscribe_object_manager_cb, + d, + _subscribe_object_manager_data_free); +} + +/*****************************************************************************/ + +static void +_nm_dbus_connection_call_get_managed_objects_cb (GObject *source, + GAsyncResult *res, + gpointer user_data) +{ + gs_unref_variant GVariant *ret = NULL; + gs_unref_variant GVariant *arg = NULL; + gs_free_error GError *error = NULL; + gpointer orig_user_data; + NMDBusConnectionCallDefaultCb callback; + + nm_utils_user_data_unpack (user_data, &orig_user_data, &callback); + + ret = g_dbus_connection_call_finish (G_DBUS_CONNECTION (source), res, &error); + + nm_assert ((!!ret) != (!!error)); + + if (ret) { + nm_assert (g_variant_is_of_type (ret, G_VARIANT_TYPE ("(a{oa{sa{sv}}})"))); + arg = g_variant_get_child_value (ret, 0); + } + + callback (arg, error, orig_user_data); +} + +void +nm_dbus_connection_call_get_managed_objects (GDBusConnection *dbus_connection, + const char *bus_name, + const char *object_path, + GDBusCallFlags flags, + int timeout_msec, + GCancellable *cancellable, + NMDBusConnectionCallDefaultCb callback, + gpointer user_data) +{ + nm_assert (callback); + + g_dbus_connection_call (dbus_connection, + bus_name, + object_path, + DBUS_INTERFACE_OBJECT_MANAGER, + "GetManagedObjects", + NULL, + G_VARIANT_TYPE ("(a{oa{sa{sv}}})"), + flags, + timeout_msec, + cancellable, + _nm_dbus_connection_call_get_managed_objects_cb, + nm_utils_user_data_pack (user_data, callback)); +} diff --git a/shared/nm-glib-aux/nm-dbus-aux.h b/shared/nm-glib-aux/nm-dbus-aux.h index 6200da023e..d5e3bf4780 100644 --- a/shared/nm-glib-aux/nm-dbus-aux.h +++ b/shared/nm-glib-aux/nm-dbus-aux.h @@ -28,6 +28,12 @@ nm_clear_g_dbus_connection_signal (GDBusConnection *dbus_connection, /*****************************************************************************/ +typedef void (*NMDBusConnectionCallDefaultCb) (GVariant *result, + GError *error, + gpointer user_data); + +/*****************************************************************************/ + static inline void nm_dbus_connection_call_start_service_by_name (GDBusConnection *dbus_connection, const char *name, @@ -77,11 +83,95 @@ typedef void (*NMDBusConnectionCallGetNameOwnerCb) (const char *name_owner, gpointer user_data); void nm_dbus_connection_call_get_name_owner (GDBusConnection *dbus_connection, - const char *service_name, - int timeout_msec, - GCancellable *cancellable, - NMDBusConnectionCallGetNameOwnerCb callback, - gpointer user_data); + const char *service_name, + int timeout_msec, + GCancellable *cancellable, + NMDBusConnectionCallGetNameOwnerCb callback, + gpointer user_data); + +static inline guint +nm_dbus_connection_signal_subscribe_properties_changed (GDBusConnection *dbus_connection, + const char *bus_name, + const char *object_path, + const char *interface_name, + GDBusSignalCallback callback, + gpointer user_data, + GDestroyNotify user_data_free_func) + +{ + nm_assert (bus_name); + + /* it seems that using a non-unique name causes problems that we get signals + * also from unrelated senders. Usually, you are anyway monitoring the name-owner, + * so you should have the unique name at hand. + * + * If not, investigate this, ensure that it works, and lift this restriction. */ + nm_assert (g_dbus_is_unique_name (bus_name)); + + return g_dbus_connection_signal_subscribe (dbus_connection, + bus_name, + DBUS_INTERFACE_PROPERTIES, + "PropertiesChanged", + object_path, + interface_name, + G_DBUS_SIGNAL_FLAGS_NONE, + callback, + user_data, + user_data_free_func); +} + +void nm_dbus_connection_call_get_all (GDBusConnection *dbus_connection, + const char *bus_name, + const char *object_path, + const char *interface_name, + int timeout_msec, + GCancellable *cancellable, + NMDBusConnectionCallDefaultCb callback, + gpointer user_data); + +/*****************************************************************************/ + +static inline guint +nm_dbus_connection_signal_subscribe_object_manager_plain (GDBusConnection *dbus_connection, + const char *service_name, + const char *object_path, + const char *signal_name, + GDBusSignalCallback callback, + gpointer user_data, + GDestroyNotify user_data_free_func) +{ + return g_dbus_connection_signal_subscribe (dbus_connection, + service_name, + DBUS_INTERFACE_OBJECT_MANAGER, + signal_name, + object_path, + NULL, + G_DBUS_SIGNAL_FLAGS_NONE, + callback, + user_data, + user_data_free_func); +} + +typedef void (*NMDBusConnectionSignalObjectMangerCb) (const char *object_path, + GVariant *added_interfaces_and_properties, + const char *const*removed_interfaces, + gpointer user_data); + +guint nm_dbus_connection_signal_subscribe_object_manager (GDBusConnection *dbus_connection, + const char *service_name, + const char *object_path, + NMDBusConnectionSignalObjectMangerCb callback, + gpointer user_data, + GDestroyNotify user_data_free_func); + +void nm_dbus_connection_call_get_managed_objects (GDBusConnection *dbus_connection, + const char *bus_name, + const char *object_path, + GDBusCallFlags flags, + int timeout_msec, + GCancellable *cancellable, + NMDBusConnectionCallDefaultCb callback, + gpointer user_data); /*****************************************************************************/ |