summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Haller <thaller@redhat.com>2022-11-14 08:09:51 +0100
committerThomas Haller <thaller@redhat.com>2022-11-14 08:09:51 +0100
commit02f7fb2cdd77a8479594bc3b0c17c8c685747199 (patch)
tree652e9c272ef2fa683d81f239454e2c90d70cbd78
parent8dc4b4701be87eeb9abf7f61de075d728a401b77 (diff)
parent8942789bb6a2bbe47c653d9bdeba998596b9274b (diff)
downloadNetworkManager-02f7fb2cdd77a8479594bc3b0c17c8c685747199.tar.gz
dbus: merge branch 'th/dbus-utils-cleanup'
https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/merge_requests/1454
-rw-r--r--Makefile.am1
-rw-r--r--po/POTFILES.in2
-rw-r--r--src/core/devices/wwan/nm-modem-ofono.c61
-rw-r--r--src/core/nm-dispatcher.c3
-rw-r--r--src/core/nm-sleep-monitor.c31
-rw-r--r--src/core/supplicant/nm-supplicant-interface.c2
-rw-r--r--src/core/supplicant/nm-supplicant-manager.c4
-rw-r--r--src/libnm-core-impl/meson.build1
-rw-r--r--src/libnm-core-impl/nm-dbus-utils.c259
-rw-r--r--src/libnm-core-intern/nm-core-internal.h25
-rw-r--r--src/libnm-glib-aux/nm-dbus-aux.c205
-rw-r--r--src/libnm-glib-aux/nm-dbus-aux.h36
12 files changed, 290 insertions, 340 deletions
diff --git a/Makefile.am b/Makefile.am
index d75aefae86..7142073cad 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -1370,7 +1370,6 @@ src_libnm_core_impl_lib_c_settings_real = \
src_libnm_core_impl_lib_c_real = \
$(src_libnm_core_impl_lib_c_settings_real) \
src/libnm-core-impl/nm-connection.c \
- src/libnm-core-impl/nm-dbus-utils.c \
src/libnm-core-impl/nm-errors.c \
src/libnm-core-impl/nm-keyfile-utils.c \
src/libnm-core-impl/nm-keyfile.c \
diff --git a/po/POTFILES.in b/po/POTFILES.in
index 82895456b0..a1a5730075 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -72,7 +72,6 @@ src/libnm-client-impl/nm-vpn-service-plugin.c
src/libnm-core-aux-extern/nm-libnm-core-aux.c
src/libnm-core-aux-intern/nm-libnm-core-utils.c
src/libnm-core-impl/nm-connection.c
-src/libnm-core-impl/nm-dbus-utils.c
src/libnm-core-impl/nm-keyfile-utils.c
src/libnm-core-impl/nm-keyfile.c
src/libnm-core-impl/nm-setting-6lowpan.c
@@ -132,6 +131,7 @@ src/libnm-crypto/nm-crypto-gnutls.c
src/libnm-crypto/nm-crypto-nss.c
src/libnm-crypto/nm-crypto-null.c
src/libnm-crypto/nm-crypto.c
+src/libnm-glib-aux/nm-dbus-aux.c
src/libnm-glib-aux/nm-shared-utils.c
src/libnm-log-core/nm-logging.c
src/libnmc-base/nm-client-utils.c
diff --git a/src/core/devices/wwan/nm-modem-ofono.c b/src/core/devices/wwan/nm-modem-ofono.c
index 10e6d145b7..b374562189 100644
--- a/src/core/devices/wwan/nm-modem-ofono.c
+++ b/src/core/devices/wwan/nm-modem-ofono.c
@@ -7,6 +7,7 @@
#include "nm-modem-ofono.h"
+#include "libnm-glib-aux/nm-dbus-aux.h"
#include "libnm-core-intern/nm-core-internal.h"
#include "libnm-glib-aux/nm-uuid.h"
#include "devices/nm-device-private.h"
@@ -453,11 +454,11 @@ _sim_proxy_new_cb(GObject *source, GAsyncResult *result, gpointer user_data)
priv->sim_proxy = proxy;
/* Watch for custom ofono PropertyChanged signals */
- _nm_dbus_signal_connect(priv->sim_proxy,
- "PropertyChanged",
- G_VARIANT_TYPE("(sv)"),
- G_CALLBACK(sim_property_changed),
- self);
+ _nm_dbus_proxy_signal_connect(priv->sim_proxy,
+ "PropertyChanged",
+ G_VARIANT_TYPE("(sv)"),
+ G_CALLBACK(sim_property_changed),
+ self);
g_dbus_proxy_call(priv->sim_proxy,
"GetProperties",
@@ -833,11 +834,11 @@ _context_proxy_new_cb(GObject *source, GAsyncResult *result, gpointer user_data)
_LOGD("recieved proxy for %s", g_dbus_proxy_get_object_path(proxy));
octx->proxy = proxy;
- _nm_dbus_signal_connect(proxy,
- "PropertyChanged",
- G_VARIANT_TYPE("(sv)"),
- G_CALLBACK(context_property_changed),
- octx);
+ _nm_dbus_proxy_signal_connect(proxy,
+ "PropertyChanged",
+ G_VARIANT_TYPE("(sv)"),
+ G_CALLBACK(context_property_changed),
+ octx);
uuid = _generate_uuid(priv->imsi, g_dbus_proxy_get_object_path(proxy));
g_hash_table_insert(priv->contexts, uuid, octx);
@@ -972,23 +973,23 @@ _connman_proxy_new_cb(GObject *source, GAsyncResult *result, gpointer user_data)
priv->connman_proxy = proxy;
- _nm_dbus_signal_connect(priv->connman_proxy,
- "PropertyChanged",
- G_VARIANT_TYPE("(sv)"),
- G_CALLBACK(connman_property_changed),
- self);
+ _nm_dbus_proxy_signal_connect(priv->connman_proxy,
+ "PropertyChanged",
+ G_VARIANT_TYPE("(sv)"),
+ G_CALLBACK(connman_property_changed),
+ self);
- _nm_dbus_signal_connect(priv->connman_proxy,
- "ContextAdded",
- G_VARIANT_TYPE("(oa{sv})"),
- G_CALLBACK(connman_context_added),
- self);
+ _nm_dbus_proxy_signal_connect(priv->connman_proxy,
+ "ContextAdded",
+ G_VARIANT_TYPE("(oa{sv})"),
+ G_CALLBACK(connman_context_added),
+ self);
- _nm_dbus_signal_connect(priv->connman_proxy,
- "ContextRemoved",
- G_VARIANT_TYPE("(o)"),
- G_CALLBACK(connman_context_removed),
- self);
+ _nm_dbus_proxy_signal_connect(priv->connman_proxy,
+ "ContextRemoved",
+ G_VARIANT_TYPE("(o)"),
+ G_CALLBACK(connman_context_removed),
+ self);
g_dbus_proxy_call(priv->connman_proxy,
"GetProperties",
@@ -1575,11 +1576,11 @@ modem_proxy_new_cb(GObject *source, GAsyncResult *result, gpointer user_data)
priv->modem_proxy = proxy;
- _nm_dbus_signal_connect(priv->modem_proxy,
- "PropertyChanged",
- G_VARIANT_TYPE("(sv)"),
- G_CALLBACK(modem_property_changed),
- self);
+ _nm_dbus_proxy_signal_connect(priv->modem_proxy,
+ "PropertyChanged",
+ G_VARIANT_TYPE("(sv)"),
+ G_CALLBACK(modem_property_changed),
+ self);
g_dbus_proxy_call(priv->modem_proxy,
"GetProperties",
diff --git a/src/core/nm-dispatcher.c b/src/core/nm-dispatcher.c
index 1617dc3667..ab361faa7b 100644
--- a/src/core/nm-dispatcher.c
+++ b/src/core/nm-dispatcher.c
@@ -8,6 +8,7 @@
#include "nm-dispatcher.h"
+#include "libnm-glib-aux/nm-dbus-aux.h"
#include "libnm-core-aux-extern/nm-dispatcher-api.h"
#include "NetworkManagerUtils.h"
#include "nm-utils.h"
@@ -428,7 +429,7 @@ dispatcher_done_cb(GObject *source, GAsyncResult *result, gpointer user_data)
if (!ret) {
NMLogLevel log_level = LOGL_DEBUG;
- if (_nm_dbus_error_has_name(error, "org.freedesktop.systemd1.LoadFailed")) {
+ if (nm_dbus_error_is(error, "org.freedesktop.systemd1.LoadFailed")) {
g_dbus_error_strip_remote_error(error);
log_level = LOGL_WARN;
}
diff --git a/src/core/nm-sleep-monitor.c b/src/core/nm-sleep-monitor.c
index a7ea496de9..66ea2f6c71 100644
--- a/src/core/nm-sleep-monitor.c
+++ b/src/core/nm-sleep-monitor.c
@@ -11,6 +11,7 @@
#include <sys/stat.h>
#include <gio/gunixfdlist.h>
+#include "libnm-glib-aux/nm-dbus-aux.h"
#include "libnm-core-intern/nm-core-internal.h"
#include "NetworkManagerUtils.h"
@@ -294,24 +295,24 @@ on_proxy_acquired(GObject *object, GAsyncResult *res, NMSleepMonitor *self)
g_clear_object(&self->cancellable);
#if USE_UPOWER
- self->sig_id_1 = _nm_dbus_signal_connect(self->proxy,
- "Sleeping",
- NULL,
- G_CALLBACK(upower_sleeping_cb),
- self);
- self->sig_id_2 = _nm_dbus_signal_connect(self->proxy,
- "Resuming",
- NULL,
- G_CALLBACK(upower_resuming_cb),
- self);
+ self->sig_id_1 = _nm_dbus_proxy_signal_connect(self->proxy,
+ "Sleeping",
+ NULL,
+ G_CALLBACK(upower_sleeping_cb),
+ self);
+ self->sig_id_2 = _nm_dbus_proxy_signal_connect(self->proxy,
+ "Resuming",
+ NULL,
+ G_CALLBACK(upower_resuming_cb),
+ self);
#else
self->sig_id_1 =
g_signal_connect(self->proxy, "notify::g-name-owner", G_CALLBACK(name_owner_cb), self);
- self->sig_id_2 = _nm_dbus_signal_connect(self->proxy,
- "PrepareForSleep",
- G_VARIANT_TYPE("(b)"),
- G_CALLBACK(prepare_for_sleep_cb),
- self);
+ self->sig_id_2 = _nm_dbus_proxy_signal_connect(self->proxy,
+ "PrepareForSleep",
+ G_VARIANT_TYPE("(b)"),
+ G_CALLBACK(prepare_for_sleep_cb),
+ self);
{
gs_free char *owner = NULL;
diff --git a/src/core/supplicant/nm-supplicant-interface.c b/src/core/supplicant/nm-supplicant-interface.c
index 5b5d86229c..18525724f4 100644
--- a/src/core/supplicant/nm-supplicant-interface.c
+++ b/src/core/supplicant/nm-supplicant-interface.c
@@ -2647,7 +2647,7 @@ scan_request_cb(GObject *source, GAsyncResult *result, gpointer user_data)
_LOGD("request-scan: request cancelled");
else {
if (error) {
- if (_nm_dbus_error_has_name(error, "fi.w1.wpa_supplicant1.Interface.ScanError"))
+ if (nm_dbus_error_is(error, "fi.w1.wpa_supplicant1.Interface.ScanError"))
_LOGD("request-scan: could not get scan request result: %s", error->message);
else {
g_dbus_error_strip_remote_error(error);
diff --git a/src/core/supplicant/nm-supplicant-manager.c b/src/core/supplicant/nm-supplicant-manager.c
index 2ec7db237a..f6927500dd 100644
--- a/src/core/supplicant/nm-supplicant-manager.c
+++ b/src/core/supplicant/nm-supplicant-manager.c
@@ -450,7 +450,7 @@ _create_iface_dbus_call_get_interface_cb(GObject *source, GAsyncResult *result,
char ifname[NMP_IFNAMSIZ];
if (handle->create_iface_try_count < CREATE_IFACE_TRY_COUNT_MAX
- && _nm_dbus_error_has_name(error, NM_WPAS_ERROR_UNKNOWN_IFACE)
+ && nm_dbus_error_is(error, NM_WPAS_ERROR_UNKNOWN_IFACE)
&& nm_platform_if_indextoname(NM_PLATFORM_GET, handle->ifindex, ifname)) {
/* Before, supplicant told us the interface existed. Was there a race?
* Try again. */
@@ -500,7 +500,7 @@ _create_iface_dbus_call_create_interface_cb(GObject *source,
nm_assert(handle->self);
TRUE;
})
- && _nm_dbus_error_has_name(error, NM_WPAS_ERROR_EXISTS_ERROR)
+ && nm_dbus_error_is(error, NM_WPAS_ERROR_EXISTS_ERROR)
&& nm_platform_if_indextoname(NM_PLATFORM_GET, handle->ifindex, ifname)) {
self = handle->self;
_LOGT("create-iface[" NM_HASH_OBFUSCATE_PTR_FMT
diff --git a/src/libnm-core-impl/meson.build b/src/libnm-core-impl/meson.build
index 2de3ff0849..25d4c6b859 100644
--- a/src/libnm-core-impl/meson.build
+++ b/src/libnm-core-impl/meson.build
@@ -60,7 +60,6 @@ libnm_core_settings_sources = files(
libnm_core_impl_sources = files(
'nm-connection.c',
- 'nm-dbus-utils.c',
'nm-errors.c',
'nm-keyfile-utils.c',
'nm-keyfile.c',
diff --git a/src/libnm-core-impl/nm-dbus-utils.c b/src/libnm-core-impl/nm-dbus-utils.c
deleted file mode 100644
index c9443ff944..0000000000
--- a/src/libnm-core-impl/nm-dbus-utils.c
+++ /dev/null
@@ -1,259 +0,0 @@
-/* SPDX-License-Identifier: LGPL-2.1-or-later */
-/*
- * Copyright (C) 2015 Red Hat, Inc.
- */
-
-#include "libnm-core-impl/nm-default-libnm-core.h"
-
-#include "libnm-core-intern/nm-core-internal.h"
-
-typedef struct {
- char *signal_name;
- const GVariantType *signature;
-} NMDBusSignalData;
-
-static void
-dbus_signal_data_free(gpointer data, GClosure *closure)
-{
- NMDBusSignalData *sd = data;
-
- g_free(sd->signal_name);
- g_slice_free(NMDBusSignalData, sd);
-}
-
-static void
-dbus_signal_meta_marshal(GClosure *closure,
- GValue *return_value,
- guint n_param_values,
- const GValue *param_values,
- gpointer invocation_hint,
- gpointer marshal_data)
-{
- NMDBusSignalData *sd = marshal_data;
- const char *signal_name;
- GVariant *parameters, *param;
- GValue *closure_params;
- gsize n_params, i;
-
- g_return_if_fail(n_param_values == 4);
-
- signal_name = g_value_get_string(&param_values[2]);
- parameters = g_value_get_variant(&param_values[3]);
-
- if (strcmp(signal_name, sd->signal_name) != 0)
- return;
-
- if (sd->signature) {
- if (!g_variant_is_of_type(parameters, sd->signature)) {
- g_warning("%p: got signal '%s' but parameters were of type '%s', not '%s'",
- g_value_get_object(&param_values[0]),
- signal_name,
- g_variant_get_type_string(parameters),
- g_variant_type_peek_string(sd->signature));
- return;
- }
-
- n_params = g_variant_n_children(parameters) + 1;
- } else
- n_params = 1;
-
- closure_params = g_new0(GValue, n_params);
- g_value_init(&closure_params[0], G_TYPE_OBJECT);
- g_value_copy(&param_values[0], &closure_params[0]);
-
- for (i = 1; i < n_params; i++) {
- param = g_variant_get_child_value(parameters, i - 1);
- if (g_variant_is_of_type(param, G_VARIANT_TYPE("ay"))
- || g_variant_is_of_type(param, G_VARIANT_TYPE("aay"))) {
- /* g_dbus_gvariant_to_gvalue() thinks 'ay' means "non-UTF-8 NUL-terminated string" */
- g_value_init(&closure_params[i], G_TYPE_VARIANT);
- g_value_set_variant(&closure_params[i], param);
- } else
- g_dbus_gvariant_to_gvalue(param, &closure_params[i]);
- g_variant_unref(param);
- }
-
- g_cclosure_marshal_generic(closure, NULL, n_params, closure_params, invocation_hint, NULL);
-
- for (i = 0; i < n_params; i++)
- g_value_unset(&closure_params[i]);
- g_free(closure_params);
-}
-
-/**
- * _nm_dbus_signal_connect_data:
- * @proxy: a #GDBusProxy
- * @signal_name: the D-Bus signal to connect to
- * @signature: (allow-none): the signal's type signature (must be a tuple)
- * @c_handler: the signal handler function
- * @data: (allow-none): data to pass to @c_handler
- * @destroy_data: (allow-none): closure destroy notify for @data
- * @connect_flags: connection flags
- *
- * Connects to the D-Bus signal @signal_name on @proxy. @c_handler must be a
- * void function whose first argument is a #GDBusProxy, followed by arguments
- * for each element of @signature, ending with a #gpointer argument for @data.
- *
- * The argument types in @c_handler correspond to the types output by
- * g_dbus_gvariant_to_gvalue(), except for 'ay' and 'aay'. In particular:
- * - both 16-bit and 32-bit integers are passed as #int/#guint
- * - 'as' values are passed as #GStrv (char **)
- * - all other array, tuple, and dict types are passed as #GVariant
- *
- * If @signature is %NULL, then the signal's parameters will be ignored, and
- * @c_handler should take only the #GDBusProxy and #gpointer arguments.
- *
- * Returns: the signal handler ID, which can be used with
- * g_signal_handler_remove(). Beware that because of the way the signal is
- * connected, you will not be able to remove it with
- * g_signal_handlers_disconnect_by_func(), although
- * g_signal_handlers_disconnect_by_data() will work correctly.
- */
-gulong
-_nm_dbus_signal_connect_data(GDBusProxy *proxy,
- const char *signal_name,
- const GVariantType *signature,
- GCallback c_handler,
- gpointer data,
- GClosureNotify destroy_data,
- GConnectFlags connect_flags)
-{
- NMDBusSignalData *sd;
- GClosure *closure;
- gboolean swapped = !!(connect_flags & G_CONNECT_SWAPPED);
- gboolean after = !!(connect_flags & G_CONNECT_AFTER);
-
- g_return_val_if_fail(G_IS_DBUS_PROXY(proxy), 0);
- g_return_val_if_fail(signal_name != NULL, 0);
- g_return_val_if_fail(signature == NULL || g_variant_type_is_tuple(signature), 0);
- g_return_val_if_fail(c_handler != NULL, 0);
-
- sd = g_slice_new(NMDBusSignalData);
- sd->signal_name = g_strdup(signal_name);
- sd->signature = signature;
-
- closure = (swapped ? g_cclosure_new_swap : g_cclosure_new)(c_handler, data, destroy_data);
- g_closure_set_marshal(closure, g_cclosure_marshal_generic);
- g_closure_set_meta_marshal(closure, sd, dbus_signal_meta_marshal);
- g_closure_add_finalize_notifier(closure, sd, dbus_signal_data_free);
-
- return g_signal_connect_closure(proxy, "g-signal", closure, after);
-}
-
-/**
- * _nm_dbus_signal_connect:
- * @proxy: a #GDBusProxy
- * @signal_name: the D-Bus signal to connect to
- * @signature: the signal's type signature (must be a tuple)
- * @c_handler: the signal handler function
- * @data: (allow-none): data to pass to @c_handler
- *
- * Simplified version of _nm_dbus_signal_connect_data() with fewer arguments.
- *
- * Returns: the signal handler ID, as with _nm_signal_connect_data().
- */
-
-/**
- * _nm_dbus_typecheck_response:
- * @response: the #GVariant response to check.
- * @reply_type: the expected reply type. It may be %NULL to perform no
- * checking.
- * @error: (allow-none): the error in case the @reply_type does not match.
- *
- * Returns: %TRUE, if @response is of the expected @reply_type.
- */
-gboolean
-_nm_dbus_typecheck_response(GVariant *response, const GVariantType *reply_type, GError **error)
-{
- g_return_val_if_fail(response, FALSE);
-
- if (!reply_type)
- return TRUE;
- if (g_variant_is_of_type(response, reply_type))
- return TRUE;
-
- /* This is the same error code that g_dbus_connection_call() returns if
- * @reply_type doesn't match.
- */
- g_set_error(error,
- G_IO_ERROR,
- G_IO_ERROR_INVALID_ARGUMENT,
- _("Method returned type '%s', but expected '%s'"),
- g_variant_get_type_string(response),
- g_variant_type_peek_string(reply_type));
- return FALSE;
-}
-
-/**
- * _nm_dbus_proxy_call_finish:
- * @proxy: A #GDBusProxy.
- * @res: A #GAsyncResult obtained from the #GAsyncReadyCallback passed to
- * g_dbus_proxy_call().
- * @reply_type: (allow-none): the expected type of the reply, or %NULL
- * @error: Return location for error or %NULL.
- *
- * Finishes an operation started with g_dbus_proxy_call(), as with
- * g_dbus_proxy_call_finish(), except thatif @reply_type is non-%NULL, then it
- * will also check that the response matches that type signature, and return
- * an error if not.
- *
- * Returns: %NULL if @error is set. Otherwise, a #GVariant tuple with
- * return values. Free with g_variant_unref().
- */
-GVariant *
-_nm_dbus_proxy_call_finish(GDBusProxy *proxy,
- GAsyncResult *res,
- const GVariantType *reply_type,
- GError **error)
-{
- GVariant *variant;
-
- variant = g_dbus_proxy_call_finish(proxy, res, error);
- if (variant && !_nm_dbus_typecheck_response(variant, reply_type, error))
- nm_clear_pointer(&variant, g_variant_unref);
- return variant;
-}
-
-GVariant *
-_nm_dbus_connection_call_finish(GDBusConnection *dbus_connection,
- GAsyncResult *result,
- const GVariantType *reply_type,
- GError **error)
-{
- GVariant *variant;
-
- variant = g_dbus_connection_call_finish(dbus_connection, result, error);
- if (variant && !_nm_dbus_typecheck_response(variant, reply_type, error))
- nm_clear_pointer(&variant, g_variant_unref);
- return variant;
-}
-
-/**
- * _nm_dbus_error_has_name:
- * @error: (allow-none): a #GError, or %NULL
- * @dbus_error_name: a D-Bus error name
- *
- * Checks if @error is set and corresponds to the D-Bus error @dbus_error_name.
- *
- * This should only be used for "foreign" D-Bus errors (eg, errors
- * from BlueZ or wpa_supplicant). All NetworkManager D-Bus errors
- * should be properly mapped by gdbus to one of the domains/codes in
- * nm-errors.h.
- *
- * Returns: %TRUE or %FALSE
- */
-gboolean
-_nm_dbus_error_has_name(GError *error, const char *dbus_error_name)
-{
- gboolean has_name = FALSE;
-
- if (error && g_dbus_error_is_remote_error(error)) {
- char *error_name;
-
- error_name = g_dbus_error_get_remote_error(error);
- has_name = !g_strcmp0(error_name, dbus_error_name);
- g_free(error_name);
- }
-
- return has_name;
-}
diff --git a/src/libnm-core-intern/nm-core-internal.h b/src/libnm-core-intern/nm-core-internal.h
index 21c994f033..df9a6d047b 100644
--- a/src/libnm-core-intern/nm-core-internal.h
+++ b/src/libnm-core-intern/nm-core-internal.h
@@ -367,31 +367,6 @@ void _nm_dbus_errors_init(void);
extern gboolean _nm_utils_is_manager_process;
-gboolean
-_nm_dbus_typecheck_response(GVariant *response, const GVariantType *reply_type, GError **error);
-
-gulong _nm_dbus_signal_connect_data(GDBusProxy *proxy,
- const char *signal_name,
- const GVariantType *signature,
- GCallback c_handler,
- gpointer data,
- GClosureNotify destroy_data,
- GConnectFlags connect_flags);
-#define _nm_dbus_signal_connect(proxy, name, signature, handler, data) \
- _nm_dbus_signal_connect_data(proxy, name, signature, handler, data, NULL, (GConnectFlags) 0)
-
-GVariant *_nm_dbus_proxy_call_finish(GDBusProxy *proxy,
- GAsyncResult *res,
- const GVariantType *reply_type,
- GError **error);
-
-GVariant *_nm_dbus_connection_call_finish(GDBusConnection *dbus_connection,
- GAsyncResult *result,
- const GVariantType *reply_type,
- GError **error);
-
-gboolean _nm_dbus_error_has_name(GError *error, const char *dbus_error_name);
-
/*****************************************************************************/
char *_nm_utils_ssid_to_utf8(GBytes *ssid);
diff --git a/src/libnm-glib-aux/nm-dbus-aux.c b/src/libnm-glib-aux/nm-dbus-aux.c
index c6597aea5a..3925da55bc 100644
--- a/src/libnm-glib-aux/nm-dbus-aux.c
+++ b/src/libnm-glib-aux/nm-dbus-aux.c
@@ -1,6 +1,6 @@
/* SPDX-License-Identifier: LGPL-2.1-or-later */
/*
- * Copyright (C) 2019 Red Hat, Inc.
+ * Copyright (C) 2015,2019 Red Hat, Inc.
*/
#include "libnm-glib-aux/nm-default-glib-i18n-lib.h"
@@ -414,6 +414,12 @@ _nm_dbus_error_is(GError *error, ...)
gs_free char *dbus_error = NULL;
const char *name;
va_list ap;
+ gboolean found = FALSE;
+
+ /* This should only be used for "foreign" D-Bus errors (eg, errors
+ * from BlueZ or wpa_supplicant). All NetworkManager D-Bus errors
+ * should be properly mapped by gdbus to one of the domains/codes in
+ * nm-errors.h. */
dbus_error = g_dbus_error_get_remote_error(error);
if (!dbus_error)
@@ -422,13 +428,13 @@ _nm_dbus_error_is(GError *error, ...)
va_start(ap, error);
while ((name = va_arg(ap, const char *))) {
if (nm_streq(dbus_error, name)) {
- va_end(ap);
- return TRUE;
+ found = TRUE;
+ break;
}
}
va_end(ap);
- return FALSE;
+ return found;
}
/*****************************************************************************/
@@ -517,3 +523,194 @@ nm_dbus_connection_call_blocking(NMDBusConnectionCallBlockingData *data, GError
return g_steal_pointer(&result);
}
+
+/*****************************************************************************/
+
+typedef struct {
+ char *signal_name;
+ const GVariantType *signature;
+} NMDBusSignalData;
+
+static void
+dbus_signal_data_free(gpointer data, GClosure *closure)
+{
+ NMDBusSignalData *sd = data;
+
+ g_free(sd->signal_name);
+ g_slice_free(NMDBusSignalData, sd);
+}
+
+static void
+dbus_signal_meta_marshal(GClosure *closure,
+ GValue *return_value,
+ guint n_param_values,
+ const GValue *param_values,
+ gpointer invocation_hint,
+ gpointer marshal_data)
+{
+ NMDBusSignalData *sd = marshal_data;
+ const char *signal_name;
+ GVariant *parameters;
+ gs_free GValue *closure_params_free = NULL;
+ GValue *closure_params;
+ gsize n_params;
+ gsize i;
+
+ g_return_if_fail(n_param_values == 4);
+
+ signal_name = g_value_get_string(&param_values[2]);
+ parameters = g_value_get_variant(&param_values[3]);
+
+ if (!nm_streq(signal_name, sd->signal_name))
+ return;
+
+ if (sd->signature) {
+ if (!g_variant_is_of_type(parameters, sd->signature)) {
+ g_warning("%p: got signal '%s' but parameters were of type '%s', not '%s'",
+ g_value_get_object(&param_values[0]),
+ signal_name,
+ g_variant_get_type_string(parameters),
+ g_variant_type_peek_string(sd->signature));
+ return;
+ }
+
+ n_params = g_variant_n_children(parameters) + 1;
+ } else
+ n_params = 1;
+
+ closure_params = nm_malloc0_maybe_a(240, sizeof(GValue) * n_params, &closure_params_free);
+ g_value_init(&closure_params[0], G_TYPE_OBJECT);
+ g_value_copy(&param_values[0], &closure_params[0]);
+
+ for (i = 1; i < n_params; i++) {
+ gs_unref_variant GVariant *param = NULL;
+
+ param = g_variant_get_child_value(parameters, i - 1);
+ if (g_variant_is_of_type(param, G_VARIANT_TYPE("ay"))
+ || g_variant_is_of_type(param, G_VARIANT_TYPE("aay"))) {
+ /* g_dbus_gvariant_to_gvalue() thinks 'ay' means "non-UTF-8 NUL-terminated string" */
+ g_value_init(&closure_params[i], G_TYPE_VARIANT);
+ g_value_set_variant(&closure_params[i], param);
+ } else
+ g_dbus_gvariant_to_gvalue(param, &closure_params[i]);
+ }
+
+ g_cclosure_marshal_generic(closure, NULL, n_params, closure_params, invocation_hint, NULL);
+
+ for (i = 0; i < n_params; i++)
+ g_value_unset(&closure_params[i]);
+}
+
+/**
+ * _nm_dbus_proxy_signal_connect_data:
+ * @proxy: a #GDBusProxy
+ * @signal_name: the D-Bus signal to connect to
+ * @signature: (allow-none): the signal's type signature (must be a tuple)
+ * @c_handler: the signal handler function
+ * @data: (allow-none): data to pass to @c_handler
+ * @destroy_data: (allow-none): closure destroy notify for @data
+ * @connect_flags: connection flags
+ *
+ * Connects to the D-Bus signal @signal_name on @proxy. @c_handler must be a
+ * void function whose first argument is a #GDBusProxy, followed by arguments
+ * for each element of @signature, ending with a #gpointer argument for @data.
+ *
+ * The argument types in @c_handler correspond to the types output by
+ * g_dbus_gvariant_to_gvalue(), except for 'ay' and 'aay'. In particular:
+ * - both 16-bit and 32-bit integers are passed as #int/#guint
+ * - 'as' values are passed as #GStrv (char **)
+ * - all other array, tuple, and dict types are passed as #GVariant
+ *
+ * If @signature is %NULL, then the signal's parameters will be ignored, and
+ * @c_handler should take only the #GDBusProxy and #gpointer arguments.
+ *
+ * Returns: the signal handler ID, which can be used with
+ * g_signal_handler_remove(). Beware that because of the way the signal is
+ * connected, you will not be able to remove it with
+ * g_signal_handlers_disconnect_by_func(), although
+ * g_signal_handlers_disconnect_by_data() will work correctly.
+ */
+gulong
+_nm_dbus_proxy_signal_connect_data(GDBusProxy *proxy,
+ const char *signal_name,
+ const GVariantType *signature,
+ GCallback c_handler,
+ gpointer data,
+ GClosureNotify destroy_data,
+ GConnectFlags connect_flags)
+{
+ NMDBusSignalData *sd;
+ GClosure *closure;
+ gboolean swapped = !!(connect_flags & G_CONNECT_SWAPPED);
+ gboolean after = !!(connect_flags & G_CONNECT_AFTER);
+
+ g_return_val_if_fail(G_IS_DBUS_PROXY(proxy), 0);
+ g_return_val_if_fail(signal_name != NULL, 0);
+ g_return_val_if_fail(signature == NULL || g_variant_type_is_tuple(signature), 0);
+ g_return_val_if_fail(c_handler != NULL, 0);
+
+ sd = g_slice_new(NMDBusSignalData);
+ sd->signal_name = g_strdup(signal_name);
+ sd->signature = signature;
+
+ closure = (swapped ? g_cclosure_new_swap : g_cclosure_new)(c_handler, data, destroy_data);
+ g_closure_set_marshal(closure, g_cclosure_marshal_generic);
+ g_closure_set_meta_marshal(closure, sd, dbus_signal_meta_marshal);
+ g_closure_add_finalize_notifier(closure, sd, dbus_signal_data_free);
+
+ return g_signal_connect_closure(proxy, "g-signal", closure, after);
+}
+
+/*****************************************************************************/
+
+static gboolean
+_nm_dbus_typecheck_response(GVariant *response, const GVariantType *reply_type, GError **error)
+{
+ g_return_val_if_fail(response, FALSE);
+
+ if (!reply_type)
+ return TRUE;
+ if (g_variant_is_of_type(response, reply_type))
+ return TRUE;
+
+ /* This is the same error code that g_dbus_connection_call() returns if
+ * @reply_type doesn't match.
+ */
+ g_set_error(error,
+ G_IO_ERROR,
+ G_IO_ERROR_INVALID_ARGUMENT,
+ _("Method returned type '%s', but expected '%s'"),
+ g_variant_get_type_string(response),
+ g_variant_type_peek_string(reply_type));
+ return FALSE;
+}
+
+/**
+ * _nm_dbus_proxy_call_finish:
+ * @proxy: A #GDBusProxy.
+ * @res: A #GAsyncResult obtained from the #GAsyncReadyCallback passed to
+ * g_dbus_proxy_call().
+ * @reply_type: (allow-none): the expected type of the reply, or %NULL
+ * @error: Return location for error or %NULL.
+ *
+ * Finishes an operation started with g_dbus_proxy_call(), as with
+ * g_dbus_proxy_call_finish(), except thatif @reply_type is non-%NULL, then it
+ * will also check that the response matches that type signature, and return
+ * an error if not.
+ *
+ * Returns: %NULL if @error is set. Otherwise, a #GVariant tuple with
+ * return values. Free with g_variant_unref().
+ */
+GVariant *
+_nm_dbus_proxy_call_finish(GDBusProxy *proxy,
+ GAsyncResult *res,
+ const GVariantType *reply_type,
+ GError **error)
+{
+ GVariant *variant;
+
+ variant = g_dbus_proxy_call_finish(proxy, res, error);
+ if (variant && !_nm_dbus_typecheck_response(variant, reply_type, error))
+ nm_clear_pointer(&variant, g_variant_unref);
+ return variant;
+}
diff --git a/src/libnm-glib-aux/nm-dbus-aux.h b/src/libnm-glib-aux/nm-dbus-aux.h
index b7cb0b8da4..5db79c08f7 100644
--- a/src/libnm-glib-aux/nm-dbus-aux.h
+++ b/src/libnm-glib-aux/nm-dbus-aux.h
@@ -274,4 +274,40 @@ nm_g_variant_tuple_get_u(GVariant *v, guint32 *out_u)
return FALSE;
}
+/*****************************************************************************/
+
+gulong _nm_dbus_proxy_signal_connect_data(GDBusProxy *proxy,
+ const char *signal_name,
+ const GVariantType *signature,
+ GCallback c_handler,
+ gpointer data,
+ GClosureNotify destroy_data,
+ GConnectFlags connect_flags);
+
+/**
+ * _nm_dbus_proxy_signal_connect:
+ * @proxy: a #GDBusProxy
+ * @signal_name: the D-Bus signal to connect to
+ * @signature: the signal's type signature (must be a tuple)
+ * @c_handler: the signal handler function
+ * @data: (allow-none): data to pass to @c_handler
+ *
+ * Simplified version of _nm_dbus_proxy_signal_connect_data() with fewer arguments.
+ *
+ * Returns: the signal handler ID, as with _nm_signal_connect_data().
+ */
+#define _nm_dbus_proxy_signal_connect(proxy, name, signature, handler, data) \
+ _nm_dbus_proxy_signal_connect_data(proxy, \
+ name, \
+ signature, \
+ handler, \
+ data, \
+ NULL, \
+ (GConnectFlags) 0)
+
+GVariant *_nm_dbus_proxy_call_finish(GDBusProxy *proxy,
+ GAsyncResult *res,
+ const GVariantType *reply_type,
+ GError **error);
+
#endif /* __NM_DBUS_AUX_H__ */