summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile.am2
-rw-r--r--libnm/meson.build1
-rw-r--r--libnm/nm-client.c12
-rw-r--r--libnm/nm-client.h3
-rw-r--r--libnm/nm-dbus-client.c237
-rw-r--r--libnm/nm-dbus-client.h37
6 files changed, 292 insertions, 0 deletions
diff --git a/Makefile.am b/Makefile.am
index 95238324a4..523caf00e9 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -1232,6 +1232,7 @@ libnm_lib_h_pub_mkenums = \
libnm/nm-enum-types.h
libnm_lib_h_priv = \
libnm/nm-libnm-utils.h \
+ libnm/nm-dbus-client.h \
libnm/nm-dbus-helpers.h \
libnm/nm-device-private.h \
libnm/nm-dhcp4-config.h \
@@ -1248,6 +1249,7 @@ libnm_lib_c_real = \
libnm/nm-active-connection.c \
libnm/nm-checkpoint.c \
libnm/nm-client.c \
+ libnm/nm-dbus-client.c \
libnm/nm-dbus-helpers.c \
libnm/nm-device-6lowpan.c \
libnm/nm-device-adsl.c \
diff --git a/libnm/meson.build b/libnm/meson.build
index 0d7fb3acf2..d9398b57e4 100644
--- a/libnm/meson.build
+++ b/libnm/meson.build
@@ -77,6 +77,7 @@ libnm_sources = files(
'nm-active-connection.c',
'nm-checkpoint.c',
'nm-client.c',
+ 'nm-dbus-client.c',
'nm-dbus-helpers.c',
'nm-device-6lowpan.c',
'nm-device-adsl.c',
diff --git a/libnm/nm-client.c b/libnm/nm-client.c
index 1e81221537..2c09698986 100644
--- a/libnm/nm-client.c
+++ b/libnm/nm-client.c
@@ -20,6 +20,7 @@
#include "nm-active-connection.h"
#include "nm-vpn-connection.h"
#include "nm-remote-connection.h"
+#include "nm-dbus-client.h"
#include "nm-dbus-helpers.h"
#include "nm-wimax-nsp.h"
#include "nm-object-private.h"
@@ -96,6 +97,7 @@ typedef struct {
typedef struct {
NMManager *manager;
+ NMDBusClient *dbus_client;
NMRemoteSettings *settings;
NMDnsManager *dns_manager;
GDBusObjectManager *object_manager;
@@ -168,9 +170,17 @@ NM_CACHED_QUARK_FCN ("nm-client-error-quark", nm_client_error_quark)
/*****************************************************************************/
+static const NMDBusClientCallbackTable dbus_client_callback_table = {
+};
+
static void
nm_client_init (NMClient *client)
{
+ NMClientPrivate *priv = NM_CLIENT_GET_PRIVATE (client);
+
+ priv->dbus_client = nm_dbus_client_new (g_bus_get_sync (_nm_dbus_bus_type (), NULL, NULL),
+ &dbus_client_callback_table,
+ client);
}
static gboolean
@@ -3408,6 +3418,8 @@ dispose (GObject *object)
nm_clear_g_cancellable (&priv->new_object_manager_cancellable);
+ nm_clear_pointer (&priv->dbus_client, nm_dbus_client_free);
+
if (priv->manager) {
g_signal_handlers_disconnect_by_data (priv->manager, object);
g_clear_object (&priv->manager);
diff --git a/libnm/nm-client.h b/libnm/nm-client.h
index 44b71ee094..da66e9fe5c 100644
--- a/libnm/nm-client.h
+++ b/libnm/nm-client.h
@@ -221,9 +221,11 @@ typedef struct {
GType nm_client_get_type (void);
+_NM_LIBNM_SYNC
NMClient *nm_client_new (GCancellable *cancellable,
GError **error);
+_NM_LIBNM_ASYNC
void nm_client_new_async (GCancellable *cancellable,
GAsyncReadyCallback callback,
gpointer user_data);
@@ -291,6 +293,7 @@ NMClientPermissionResult nm_client_get_permission_result (NMClient *client,
NMConnectivityState nm_client_get_connectivity (NMClient *client);
+_NM_LIBNM_SYNC
NMConnectivityState nm_client_check_connectivity (NMClient *client,
GCancellable *cancellable,
GError **error);
diff --git a/libnm/nm-dbus-client.c b/libnm/nm-dbus-client.c
new file mode 100644
index 0000000000..109dc357fc
--- /dev/null
+++ b/libnm/nm-dbus-client.c
@@ -0,0 +1,237 @@
+/*
+ * 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 2019 Red Hat, Inc.
+ */
+
+#include "nm-default.h"
+
+#include "nm-dbus-client.h"
+
+#include "c-list/src/c-list.h"
+#include "nm-glib-aux/nm-dbus-aux.h"
+#include "nm-glib-aux/nm-ref-string.h"
+#include "nm-dbus-interface.h"
+
+/*****************************************************************************/
+
+typedef void (*EventHandleFcn) (NMDBusClient *self,
+ gpointer user_data);
+
+typedef struct {
+ CList event_lst;
+ EventHandleFcn handle_fcn;
+ gpointer user_data;
+} EventData;
+
+struct _NMDBusClient {
+
+ const NMDBusClientCallbackTable *callback_table;
+ gpointer callback_user_data;
+
+ GMutex event_lock;
+
+ CList event_lst_head;
+
+ GMainContext *caller_context;
+ GMainContext *intern_context;
+
+ GDBusConnection *dbus_connection;
+
+ GCancellable *i_name_owner_get_cancellable;
+
+ char *i_name_owner;
+
+ guint name_owner_changed_id;
+};
+
+/*****************************************************************************/
+
+#define _LOGT(...) do { } while (0)
+
+static gboolean
+NM_IS_DBUS_CLIENT (NMDBusClient *self)
+{
+ nm_assert (!self || G_IS_DBUS_CONNECTION (self->dbus_connection));
+
+ return !!self;
+}
+
+/*****************************************************************************/
+
+static void
+_event_queue (NMDBusClient *self,
+ EventHandleFcn handle_fcn,
+ gpointer user_data)
+{
+ EventData *e;
+
+ e = g_slice_new (EventData);
+ e->handle_fcn = handle_fcn;
+ e->user_data = user_data;
+
+ g_mutex_lock (&self->event_lock);
+ c_list_link_tail (&self->event_lst_head, &e->event_lst);
+ g_mutex_unlock (&self->event_lock);
+}
+
+static gboolean
+_event_dequeue_and_handle (NMDBusClient *self)
+{
+ EventData *e;
+
+ g_mutex_lock (&self->event_lock);
+ e = c_list_first_entry (&self->event_lst_head, EventData, event_lst);
+ if (e)
+ c_list_unlink (&e->event_lst);
+ g_mutex_unlock (&self->event_lock);
+
+ if (!e)
+ return FALSE;
+
+ e->handle_fcn (self, e->user_data);
+ nm_g_slice_free (e);
+ return TRUE;
+}
+
+/*****************************************************************************/
+
+static void
+i_name_owner_changed (NMDBusClient *self,
+ const char *name_owner,
+ gboolean from_get_callback)
+{
+ if (G_UNLIKELY (self->i_name_owner_get_cancellable))
+ g_clear_object (&self->i_name_owner_get_cancellable);
+ else {
+ if (nm_streq0 (self->i_name_owner, name_owner))
+ return;
+ }
+
+ g_free (self->i_name_owner);
+ self->i_name_owner = g_strdup (name_owner);
+
+ if (!self->i_name_owner)
+ _LOGT ("D-Bus name for %s has no owner", NM_DBUS_SERVICE);
+ else
+ _LOGT ("D-Bus name for %s has owner %s", NM_DBUS_SERVICE, i_name_owner);
+
+ //XXX: initialize parts.
+
+ //XXX: notify caller about name owner changed.
+}
+
+static void
+i_name_owner_changed_cb (GDBusConnection *connection,
+ const char *sender_name,
+ const char *object_path,
+ const char *interface_name,
+ const char *signal_name,
+ GVariant *parameters,
+ gpointer user_data)
+{
+ const char *new_owner;
+
+ if (g_variant_is_of_type (parameters, G_VARIANT_TYPE ("(sss)"))) {
+ g_variant_get (parameters,
+ "(&s&s&s)",
+ NULL,
+ NULL,
+ &new_owner);
+ i_name_owner_changed (user_data, nm_str_not_empty (new_owner), FALSE);
+ }
+}
+
+static void
+i_name_owner_get_cb (const char *name_owner,
+ GError *error,
+ gpointer user_data)
+{
+ if ( name_owner
+ || !g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
+ i_name_owner_changed (user_data, name_owner, TRUE);
+}
+
+/*****************************************************************************/
+
+NMDBusClient *
+nm_dbus_client_new (GDBusConnection *dbus_connection,
+ const NMDBusClientCallbackTable *callback_table,
+ gpointer callback_user_data)
+{
+ NMDBusClient *self;
+
+ g_return_val_if_fail (G_IS_DBUS_CONNECTION (dbus_connection), NULL);
+ g_return_val_if_fail (callback_table, NULL);
+
+ self = g_slice_new (NMDBusClient);
+
+ *self = (NMDBusClient) {
+ .callback_table = callback_table,
+ .callback_user_data = callback_user_data,
+ .dbus_connection = g_object_ref (dbus_connection),
+ .caller_context = g_main_context_ref_thread_default (),
+ .intern_context = g_main_context_new (),
+ .event_lst_head = C_LIST_INIT (self->event_lst_head),
+ };
+
+ g_mutex_init (&self->event_lock);
+
+ g_main_context_push_thread_default (self->intern_context);
+
+ self->name_owner_changed_id = nm_dbus_connection_signal_subscribe_name_owner_changed (self->dbus_connection,
+ NM_DBUS_SERVICE,
+ i_name_owner_changed_cb,
+ self,
+ NULL);
+
+ self->i_name_owner_get_cancellable = g_cancellable_new ();
+ nm_dbus_connection_call_get_name_owner (self->dbus_connection,
+ NM_DBUS_SERVICE,
+ -1,
+ self->i_name_owner_get_cancellable,
+ i_name_owner_get_cb,
+ self);
+
+ g_main_context_pop_thread_default (self->intern_context);
+
+ return self;
+}
+
+void
+nm_dbus_client_free (NMDBusClient *self)
+{
+ g_return_if_fail (NM_IS_DBUS_CLIENT (self));
+
+ //XXX: handle pending events in event_lst_head
+ nm_assert (c_list_is_empty (&self->event_lst_head));
+
+ nm_clear_g_cancellable (&self->i_name_owner_get_cancellable);
+
+ nm_clear_g_dbus_connection_signal (self->dbus_connection,
+ &self->name_owner_changed_id);
+
+ g_object_unref (self->dbus_connection);
+
+ g_main_context_unref (self->caller_context);
+
+ //XXX: ensure there are no pending jobs (or we handle them correctly).
+ g_main_context_unref (self->intern_context);
+
+ g_mutex_clear (&self->event_lock);
+
+ nm_g_slice_free (self);
+}
diff --git a/libnm/nm-dbus-client.h b/libnm/nm-dbus-client.h
new file mode 100644
index 0000000000..542744f68c
--- /dev/null
+++ b/libnm/nm-dbus-client.h
@@ -0,0 +1,37 @@
+/*
+ * 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 2019 Red Hat, Inc.
+ */
+
+#ifndef __NM_DBUS_CLIENT_H__
+#define __NM_DBUS_CLIENT_H__
+
+typedef struct _NMDBusClient NMDBusClient;
+
+typedef struct {
+ void (*name_owner_changed) (NMDBusClient *self,
+ const char *new_owner,
+ gpointer user_data);
+} NMDBusClientCallbackTable;
+
+NMDBusClient *nm_dbus_client_new (GDBusConnection *dbus_connection,
+ const NMDBusClientCallbackTable *callback_table,
+ gpointer callback_user_data);
+
+void nm_dbus_client_free (NMDBusClient *self);
+
+#endif /* __NM_DBUS_CLIENT_H__ */