summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Haller <thaller@redhat.com>2019-08-11 11:04:44 +0200
committerThomas Haller <thaller@redhat.com>2019-09-22 16:05:50 +0200
commitd048050c2d4545cc6914e23548424a5b0519d2b9 (patch)
tree9418dbf3739f5725671def76e5dd50d5d7c7e7bf
parentc73b5c1be0c683f234ce7e4b2cdcefa1882e6262 (diff)
downloadNetworkManager-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.c192
-rw-r--r--shared/nm-glib-aux/nm-dbus-aux.h100
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);
/*****************************************************************************/