core: merge branch 'more-gdbus-bgo746901'
https://bugzilla.gnome.org/show_bug.cgi?id=746901
This commit is contained in:
@@ -58,6 +58,7 @@ libnm_core_sources = \
|
||||
$(core_build)/nm-core-enum-types.c \
|
||||
$(core)/crypto.c \
|
||||
$(core)/nm-connection.c \
|
||||
$(core)/nm-dbus-utils.c \
|
||||
$(core)/nm-errors.c \
|
||||
$(core)/nm-keyfile-reader.c \
|
||||
$(core)/nm-keyfile-utils.c \
|
||||
|
@@ -33,6 +33,8 @@
|
||||
* and some test programs.
|
||||
**/
|
||||
|
||||
#include <gio/gio.h>
|
||||
|
||||
#include "nm-connection.h"
|
||||
#include "nm-core-enum-types.h"
|
||||
#include "nm-dbus-interface.h"
|
||||
@@ -139,4 +141,30 @@ GByteArray *nm_utils_rsa_key_encrypt (const guint8 *data,
|
||||
|
||||
gint64 _nm_utils_ascii_str_to_int64 (const char *str, guint base, gint64 min, gint64 max, gint64 fallback);
|
||||
|
||||
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_proxy_call_sync (GDBusProxy *proxy,
|
||||
const gchar *method_name,
|
||||
GVariant *parameters,
|
||||
const GVariantType *reply_type,
|
||||
GDBusCallFlags flags,
|
||||
gint timeout_msec,
|
||||
GCancellable *cancellable,
|
||||
GError **error);
|
||||
|
||||
gboolean _nm_dbus_error_has_name (GError *error,
|
||||
const char *dbus_error_name);
|
||||
#endif
|
||||
|
290
libnm-core/nm-dbus-utils.c
Normal file
290
libnm-core/nm-dbus-utils.c
Normal file
@@ -0,0 +1,290 @@
|
||||
/* -*- 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 2015 Red Hat, Inc.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <gio/gio.h>
|
||||
#include <glib/gi18n-lib.h>
|
||||
|
||||
#include "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 (¶m_values[2]);
|
||||
parameters = g_value_get_variant (¶m_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 (¶m_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 (¶m_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 #gint/#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().
|
||||
*/
|
||||
|
||||
|
||||
static void
|
||||
typecheck_response (GVariant **response,
|
||||
const GVariantType *reply_type,
|
||||
GError **error)
|
||||
{
|
||||
if (*response && reply_type && !g_variant_is_of_type (*response, reply_type)) {
|
||||
/* 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));
|
||||
g_clear_pointer (response, g_variant_unref);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* _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 *ret;
|
||||
|
||||
ret = g_dbus_proxy_call_finish (proxy, res, error);
|
||||
typecheck_response (&ret, reply_type, error);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* _nm_dbus_proxy_call_sync:
|
||||
* @proxy: A #GDBusProxy.
|
||||
* @method_name: Name of method to invoke.
|
||||
* @parameters: (allow-none): A #GVariant tuple with parameters for the signal
|
||||
* or %NULL if not passing parameters.
|
||||
* @reply_type: (allow-none): the expected type of the reply, or %NULL
|
||||
* @flags: Flags from the #GDBusCallFlags enumeration.
|
||||
* @timeout_msec: The timeout in milliseconds (with %G_MAXINT meaning
|
||||
* "infinite") or -1 to use the proxy default timeout.
|
||||
* @cancellable: (allow-none): A #GCancellable or %NULL.
|
||||
* @error: Return location for error or %NULL.
|
||||
*
|
||||
* Synchronously invokes the @method_name method on @proxy, as with
|
||||
* g_dbus_proxy_call_sync(), except that if @reply_type is non-%NULL, then the
|
||||
* reply to the call will be checked against it, and an error returned if it
|
||||
* does not match.
|
||||
*
|
||||
* Returns: %NULL if @error is set. Otherwise a #GVariant tuple with
|
||||
* return values. Free with g_variant_unref().
|
||||
*/
|
||||
GVariant *
|
||||
_nm_dbus_proxy_call_sync (GDBusProxy *proxy,
|
||||
const gchar *method_name,
|
||||
GVariant *parameters,
|
||||
const GVariantType *reply_type,
|
||||
GDBusCallFlags flags,
|
||||
gint timeout_msec,
|
||||
GCancellable *cancellable,
|
||||
GError **error)
|
||||
{
|
||||
GVariant *ret;
|
||||
|
||||
ret = g_dbus_proxy_call_sync (proxy, method_name, parameters,
|
||||
flags, timeout_msec,
|
||||
cancellable, error);
|
||||
typecheck_response (&ret, reply_type, error);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* _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.
|
||||
*
|
||||
* 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;
|
||||
}
|
@@ -34,6 +34,7 @@
|
||||
#include "nm-glib-compat.h"
|
||||
#include "nm-dbus-helpers.h"
|
||||
#include "nm-client.h"
|
||||
#include "nm-core-internal.h"
|
||||
|
||||
static gboolean debug = FALSE;
|
||||
#define dbgmsg(f,...) if (G_UNLIKELY (debug)) { g_message (f, ## __VA_ARGS__ ); }
|
||||
@@ -511,7 +512,8 @@ create_async_got_property (GObject *proxy, GAsyncResult *result, gpointer user_d
|
||||
GError *error = NULL;
|
||||
GType type;
|
||||
|
||||
ret = g_dbus_proxy_call_finish (G_DBUS_PROXY (proxy), result, &error);
|
||||
ret = _nm_dbus_proxy_call_finish (G_DBUS_PROXY (proxy), result,
|
||||
G_VARIANT_TYPE ("(v)"), &error);
|
||||
if (ret) {
|
||||
g_variant_get (ret, "(v)", &value);
|
||||
type = type_data->type_func (value);
|
||||
@@ -519,8 +521,8 @@ create_async_got_property (GObject *proxy, GAsyncResult *result, gpointer user_d
|
||||
g_variant_unref (ret);
|
||||
} else {
|
||||
dbgmsg ("Could not fetch property '%s' of interface '%s' on %s: %s\n",
|
||||
type_data->property, type_data->interface, async_data->path,
|
||||
error->message);
|
||||
type_data->property, type_data->interface, async_data->path,
|
||||
error->message);
|
||||
g_clear_error (&error);
|
||||
type = G_TYPE_INVALID;
|
||||
}
|
||||
@@ -961,20 +963,11 @@ process_properties_changed (NMObject *self, GVariant *properties, gboolean synch
|
||||
}
|
||||
|
||||
static void
|
||||
property_proxy_signal (GDBusProxy *proxy,
|
||||
const char *sender_name,
|
||||
const char *signal_name,
|
||||
GVariant *parameters,
|
||||
gpointer user_data)
|
||||
properties_changed (GDBusProxy *proxy,
|
||||
GVariant *properties,
|
||||
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(vtype, ctype, getter) \
|
||||
@@ -1117,8 +1110,8 @@ _nm_object_register_properties (NMObject *object,
|
||||
proxy = _nm_object_get_proxy (object, interface);
|
||||
g_return_if_fail (proxy != NULL);
|
||||
|
||||
g_signal_connect (proxy, "g-signal",
|
||||
G_CALLBACK (property_proxy_signal), object);
|
||||
_nm_dbus_signal_connect (proxy, "PropertiesChanged", G_VARIANT_TYPE ("(a{sv})"),
|
||||
G_CALLBACK (properties_changed), 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);
|
||||
@@ -1156,11 +1149,12 @@ _nm_object_reload_properties (NMObject *object, GError **error)
|
||||
|
||||
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);
|
||||
ret = _nm_dbus_proxy_call_sync (priv->properties_proxy,
|
||||
"GetAll",
|
||||
g_variant_new ("(s)", interface),
|
||||
G_VARIANT_TYPE ("(a{sv})"),
|
||||
G_DBUS_CALL_FLAGS_NONE, -1,
|
||||
NULL, error);
|
||||
if (!ret) {
|
||||
if (error && *error)
|
||||
g_dbus_error_strip_remote_error (*error);
|
||||
@@ -1203,11 +1197,12 @@ _nm_object_reload_property (NMObject *object,
|
||||
if (!NM_OBJECT_GET_PRIVATE (object)->nm_running)
|
||||
return;
|
||||
|
||||
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);
|
||||
ret = _nm_dbus_proxy_call_sync (NM_OBJECT_GET_PRIVATE (object)->properties_proxy,
|
||||
"Get",
|
||||
g_variant_new ("(ss)", interface, prop_name),
|
||||
G_VARIANT_TYPE ("(v)"),
|
||||
G_DBUS_CALL_FLAGS_NONE, 15000,
|
||||
NULL, &err);
|
||||
if (!ret) {
|
||||
dbgmsg ("%s: Error getting '%s' for %s: (%d) %s\n",
|
||||
__func__,
|
||||
@@ -1305,7 +1300,9 @@ reload_got_properties (GObject *proxy,
|
||||
GVariant *ret, *props;
|
||||
GError *error = NULL;
|
||||
|
||||
ret = g_dbus_proxy_call_finish (G_DBUS_PROXY (proxy), result, &error);
|
||||
ret = _nm_dbus_proxy_call_finish (G_DBUS_PROXY (proxy), result,
|
||||
G_VARIANT_TYPE ("(a{sv})"),
|
||||
&error);
|
||||
if (ret) {
|
||||
g_variant_get (ret, "(@a{sv})", &props);
|
||||
process_properties_changed (object, props, FALSE);
|
||||
|
@@ -1153,101 +1153,6 @@ nm_utils_get_shared_wifi_permission (NMConnection *connection)
|
||||
|
||||
/*********************************/
|
||||
|
||||
static void
|
||||
nm_gvalue_destroy (gpointer data)
|
||||
{
|
||||
GValue *value = (GValue *) data;
|
||||
|
||||
g_value_unset (value);
|
||||
g_slice_free (GValue, value);
|
||||
}
|
||||
|
||||
GHashTable *
|
||||
value_hash_create (void)
|
||||
{
|
||||
return g_hash_table_new_full (g_str_hash, g_str_equal, g_free, nm_gvalue_destroy);
|
||||
}
|
||||
|
||||
void
|
||||
value_hash_add (GHashTable *hash,
|
||||
const char *key,
|
||||
GValue *value)
|
||||
{
|
||||
g_hash_table_insert (hash, g_strdup (key), value);
|
||||
}
|
||||
|
||||
void
|
||||
value_hash_add_str (GHashTable *hash,
|
||||
const char *key,
|
||||
const char *str)
|
||||
{
|
||||
GValue *value;
|
||||
|
||||
value = g_slice_new0 (GValue);
|
||||
g_value_init (value, G_TYPE_STRING);
|
||||
g_value_set_string (value, str);
|
||||
|
||||
value_hash_add (hash, key, value);
|
||||
}
|
||||
|
||||
void
|
||||
value_hash_add_object_path (GHashTable *hash,
|
||||
const char *key,
|
||||
const char *op)
|
||||
{
|
||||
GValue *value;
|
||||
|
||||
value = g_slice_new0 (GValue);
|
||||
g_value_init (value, DBUS_TYPE_G_OBJECT_PATH);
|
||||
g_value_set_boxed (value, op);
|
||||
|
||||
value_hash_add (hash, key, value);
|
||||
}
|
||||
|
||||
void
|
||||
value_hash_add_uint (GHashTable *hash,
|
||||
const char *key,
|
||||
guint32 val)
|
||||
{
|
||||
GValue *value;
|
||||
|
||||
value = g_slice_new0 (GValue);
|
||||
g_value_init (value, G_TYPE_UINT);
|
||||
g_value_set_uint (value, val);
|
||||
|
||||
value_hash_add (hash, key, value);
|
||||
}
|
||||
|
||||
void
|
||||
value_hash_add_bool (GHashTable *hash,
|
||||
const char *key,
|
||||
gboolean val)
|
||||
{
|
||||
GValue *value;
|
||||
|
||||
value = g_slice_new0 (GValue);
|
||||
g_value_init (value, G_TYPE_BOOLEAN);
|
||||
g_value_set_boolean (value, val);
|
||||
|
||||
value_hash_add (hash, key, value);
|
||||
}
|
||||
|
||||
void
|
||||
value_hash_add_object_property (GHashTable *hash,
|
||||
const char *key,
|
||||
GObject *object,
|
||||
const char *prop,
|
||||
GType val_type)
|
||||
{
|
||||
GValue *value;
|
||||
|
||||
value = g_slice_new0 (GValue);
|
||||
g_value_init (value, val_type);
|
||||
g_object_get_property (object, prop, value);
|
||||
value_hash_add (hash, key, value);
|
||||
}
|
||||
|
||||
|
||||
static char *
|
||||
get_new_connection_name (const GSList *existing,
|
||||
const char *preferred,
|
||||
|
@@ -109,33 +109,6 @@ GSList *nm_match_spec_split (const char *value);
|
||||
|
||||
const char *nm_utils_get_shared_wifi_permission (NMConnection *connection);
|
||||
|
||||
GHashTable *value_hash_create (void);
|
||||
void value_hash_add (GHashTable *hash,
|
||||
const char *key,
|
||||
GValue *value);
|
||||
|
||||
void value_hash_add_str (GHashTable *hash,
|
||||
const char *key,
|
||||
const char *str);
|
||||
|
||||
void value_hash_add_object_path (GHashTable *hash,
|
||||
const char *key,
|
||||
const char *op);
|
||||
|
||||
void value_hash_add_uint (GHashTable *hash,
|
||||
const char *key,
|
||||
guint32 val);
|
||||
|
||||
void value_hash_add_bool (GHashTable *hash,
|
||||
const char *key,
|
||||
gboolean val);
|
||||
|
||||
void value_hash_add_object_property (GHashTable *hash,
|
||||
const char *key,
|
||||
GObject *object,
|
||||
const char *prop,
|
||||
GType val_type);
|
||||
|
||||
const char *nm_utils_get_ip_config_method (NMConnection *connection,
|
||||
GType ip_setting_type);
|
||||
|
||||
|
@@ -864,21 +864,14 @@ properties_changed (GDBusProxy *proxy,
|
||||
|
||||
static void
|
||||
bluez4_property_changed (GDBusProxy *proxy,
|
||||
const char *sender,
|
||||
const char *signal_name,
|
||||
GVariant *parameters,
|
||||
gpointer user_data)
|
||||
const char *property,
|
||||
GVariant *v,
|
||||
gpointer user_data)
|
||||
{
|
||||
NMBluezDevice *self = NM_BLUEZ_DEVICE (user_data);
|
||||
|
||||
if (g_strcmp0 (signal_name, "PropertyChanged") == 0) {
|
||||
const char *property = NULL;
|
||||
GVariant *v = NULL;
|
||||
|
||||
g_variant_get (parameters, "(&sv)", &property, &v);
|
||||
_take_one_variant_property (self, property, v);
|
||||
check_emit_usable (self);
|
||||
}
|
||||
_take_one_variant_property (self, property, v);
|
||||
check_emit_usable (self);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -888,27 +881,21 @@ get_properties_cb_4 (GObject *source_object, GAsyncResult *res, gpointer user_da
|
||||
NMBluezDevicePrivate *priv = NM_BLUEZ_DEVICE_GET_PRIVATE (self);
|
||||
GError *err = NULL;
|
||||
GVariant *v_properties, *v_dict;
|
||||
GVariantType *v_type;
|
||||
|
||||
v_properties = g_dbus_proxy_call_finish (priv->proxy, res, &err);
|
||||
v_properties = _nm_dbus_proxy_call_finish (priv->proxy, res,
|
||||
G_VARIANT_TYPE ("(a{sv})"),
|
||||
&err);
|
||||
if (!v_properties) {
|
||||
nm_log_warn (LOGD_BT, "bluez[%s] error getting device properties: %s",
|
||||
priv->path, err && err->message ? err->message : "(unknown)");
|
||||
priv->path, err->message);
|
||||
g_error_free (err);
|
||||
g_signal_emit (self, signals[INITIALIZED], 0, FALSE);
|
||||
goto END;
|
||||
}
|
||||
|
||||
v_type = g_variant_type_new ("(a{sv})");
|
||||
if (g_variant_is_of_type (v_properties, v_type)) {
|
||||
v_dict = g_variant_get_child_value (v_properties, 0);
|
||||
_set_properties (self, v_dict);
|
||||
g_variant_unref (v_dict);
|
||||
} else {
|
||||
nm_log_warn (LOGD_BT, "bluez[%s] GetProperties returns unexpected result of type %s", priv->path, g_variant_get_type_string (v_properties));
|
||||
}
|
||||
g_variant_type_free (v_type);
|
||||
|
||||
v_dict = g_variant_get_child_value (v_properties, 0);
|
||||
_set_properties (self, v_dict);
|
||||
g_variant_unref (v_dict);
|
||||
g_variant_unref (v_properties);
|
||||
|
||||
/* Check if any connections match this device */
|
||||
@@ -917,7 +904,6 @@ get_properties_cb_4 (GObject *source_object, GAsyncResult *res, gpointer user_da
|
||||
priv->initialized = TRUE;
|
||||
g_signal_emit (self, signals[INITIALIZED], 0, TRUE);
|
||||
|
||||
|
||||
check_emit_usable (self);
|
||||
|
||||
END:
|
||||
@@ -985,8 +971,8 @@ on_proxy_acquired (GObject *object, GAsyncResult *res, NMBluezDevice *self)
|
||||
G_CALLBACK (properties_changed), self);
|
||||
if (priv->bluez_version == 4) {
|
||||
/* Watch for custom Bluez4 PropertyChanged signals */
|
||||
g_signal_connect (priv->proxy, "g-signal",
|
||||
G_CALLBACK (bluez4_property_changed), self);
|
||||
_nm_dbus_signal_connect (priv->proxy, "PropertyChanged", G_VARIANT_TYPE ("(sv)"),
|
||||
G_CALLBACK (bluez4_property_changed), self);
|
||||
}
|
||||
|
||||
query_properties (self);
|
||||
|
@@ -35,8 +35,7 @@
|
||||
#include "nm-bluez-common.h"
|
||||
#include "nm-connection-provider.h"
|
||||
#include "nm-device-bt.h"
|
||||
|
||||
#include "nm-dbus-manager.h"
|
||||
#include "nm-core-internal.h"
|
||||
|
||||
typedef struct {
|
||||
int bluez_version;
|
||||
@@ -276,8 +275,8 @@ check_bluez_and_try_setup_do_introspect (GObject *source_object,
|
||||
|
||||
g_clear_object (&priv->async_cancellable);
|
||||
|
||||
result = g_dbus_proxy_call_finish (priv->introspect_proxy, res, &error);
|
||||
|
||||
result = _nm_dbus_proxy_call_finish (priv->introspect_proxy, res,
|
||||
G_VARIANT_TYPE ("(s)"), &error);
|
||||
if (!result) {
|
||||
char *reason2 = g_strdup_printf ("introspect failed with %s", error->message);
|
||||
check_bluez_and_try_setup_final_step (self, 0, reason2);
|
||||
|
@@ -24,13 +24,11 @@
|
||||
#include <string.h>
|
||||
|
||||
#include "nm-dbus-interface.h"
|
||||
#include "nm-dbus-manager.h"
|
||||
#include "nm-bluez4-adapter.h"
|
||||
#include "nm-bluez-device.h"
|
||||
#include "nm-bluez-common.h"
|
||||
#include "nm-dbus-glib-types.h"
|
||||
#include "nm-logging.h"
|
||||
|
||||
#include "nm-core-internal.h"
|
||||
|
||||
G_DEFINE_TYPE (NMBluez4Adapter, nm_bluez4_adapter, G_TYPE_OBJECT)
|
||||
|
||||
@@ -38,7 +36,7 @@ G_DEFINE_TYPE (NMBluez4Adapter, nm_bluez4_adapter, G_TYPE_OBJECT)
|
||||
|
||||
typedef struct {
|
||||
char *path;
|
||||
DBusGProxy *proxy;
|
||||
GDBusProxy *proxy;
|
||||
gboolean initialized;
|
||||
|
||||
char *address;
|
||||
@@ -158,7 +156,7 @@ device_do_remove (NMBluez4Adapter *self, NMBluezDevice *device)
|
||||
}
|
||||
|
||||
static void
|
||||
device_created (DBusGProxy *proxy, const char *path, gpointer user_data)
|
||||
device_created (GDBusProxy *proxy, const char *path, gpointer user_data)
|
||||
{
|
||||
NMBluez4Adapter *self = NM_BLUEZ4_ADAPTER (user_data);
|
||||
NMBluez4AdapterPrivate *priv = NM_BLUEZ4_ADAPTER_GET_PRIVATE (self);
|
||||
@@ -173,7 +171,7 @@ device_created (DBusGProxy *proxy, const char *path, gpointer user_data)
|
||||
}
|
||||
|
||||
static void
|
||||
device_removed (DBusGProxy *proxy, const char *path, gpointer user_data)
|
||||
device_removed (GDBusProxy *proxy, const char *path, gpointer user_data)
|
||||
{
|
||||
NMBluez4Adapter *self = NM_BLUEZ4_ADAPTER (user_data);
|
||||
NMBluez4AdapterPrivate *priv = NM_BLUEZ4_ADAPTER_GET_PRIVATE (self);
|
||||
@@ -186,37 +184,35 @@ device_removed (DBusGProxy *proxy, const char *path, gpointer user_data)
|
||||
device_do_remove (self, device);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
get_properties_cb (DBusGProxy *proxy, DBusGProxyCall *call, gpointer user_data)
|
||||
get_properties_cb (GObject *proxy, GAsyncResult *result, gpointer user_data)
|
||||
{
|
||||
NMBluez4Adapter *self = NM_BLUEZ4_ADAPTER (user_data);
|
||||
NMBluez4AdapterPrivate *priv = NM_BLUEZ4_ADAPTER_GET_PRIVATE (self);
|
||||
GHashTable *properties = NULL;
|
||||
GError *err = NULL;
|
||||
GValue *value;
|
||||
GPtrArray *devices;
|
||||
GVariant *ret, *properties;
|
||||
char **devices;
|
||||
int i;
|
||||
|
||||
if (!dbus_g_proxy_end_call (proxy, call, &err,
|
||||
DBUS_TYPE_G_MAP_OF_VARIANT, &properties,
|
||||
G_TYPE_INVALID)) {
|
||||
nm_log_warn (LOGD_BT, "bluez error getting adapter properties: %s",
|
||||
err && err->message ? err->message : "(unknown)");
|
||||
ret = _nm_dbus_proxy_call_finish (G_DBUS_PROXY (proxy), result,
|
||||
G_VARIANT_TYPE ("(a{sv})"), &err);
|
||||
if (!ret) {
|
||||
nm_log_warn (LOGD_BT, "bluez error getting adapter properties: %s", err->message);
|
||||
g_error_free (err);
|
||||
goto done;
|
||||
}
|
||||
|
||||
value = g_hash_table_lookup (properties, "Address");
|
||||
priv->address = value ? g_value_dup_string (value) : NULL;
|
||||
properties = g_variant_get_child_value (ret, 0);
|
||||
|
||||
value = g_hash_table_lookup (properties, "Devices");
|
||||
devices = value ? g_value_get_boxed (value) : NULL;
|
||||
g_variant_lookup (properties, "Address", "s", &priv->address);
|
||||
if (g_variant_lookup (properties, "Devices", "^ao", &devices)) {
|
||||
for (i = 0; devices[i]; i++)
|
||||
device_created (priv->proxy, devices[i], self);
|
||||
g_strfreev (devices);
|
||||
}
|
||||
|
||||
for (i = 0; devices && i < devices->len; i++)
|
||||
device_created (priv->proxy, g_ptr_array_index (devices, i), self);
|
||||
|
||||
g_hash_table_unref (properties);
|
||||
g_variant_unref (properties);
|
||||
g_variant_unref (ret);
|
||||
|
||||
priv->initialized = TRUE;
|
||||
|
||||
@@ -228,16 +224,12 @@ static void
|
||||
query_properties (NMBluez4Adapter *self)
|
||||
{
|
||||
NMBluez4AdapterPrivate *priv = NM_BLUEZ4_ADAPTER_GET_PRIVATE (self);
|
||||
DBusGProxyCall *call;
|
||||
|
||||
call = dbus_g_proxy_begin_call (priv->proxy, "GetProperties",
|
||||
get_properties_cb,
|
||||
self,
|
||||
NULL, G_TYPE_INVALID);
|
||||
if (!call) {
|
||||
nm_log_warn (LOGD_BT, "failed to request Bluetooth adapter properties for %s.",
|
||||
priv->path);
|
||||
}
|
||||
g_dbus_proxy_call (priv->proxy, "GetProperties",
|
||||
NULL,
|
||||
G_DBUS_CALL_FLAGS_NONE, -1,
|
||||
NULL,
|
||||
get_properties_cb, self);
|
||||
}
|
||||
|
||||
/***********************************************************/
|
||||
@@ -247,34 +239,25 @@ nm_bluez4_adapter_new (const char *path, NMConnectionProvider *provider)
|
||||
{
|
||||
NMBluez4Adapter *self;
|
||||
NMBluez4AdapterPrivate *priv;
|
||||
DBusGConnection *connection;
|
||||
|
||||
self = (NMBluez4Adapter *) g_object_new (NM_TYPE_BLUEZ4_ADAPTER,
|
||||
NM_BLUEZ4_ADAPTER_PATH, path,
|
||||
NULL);
|
||||
if (!self)
|
||||
return NULL;
|
||||
|
||||
priv = NM_BLUEZ4_ADAPTER_GET_PRIVATE (self);
|
||||
|
||||
priv->provider = provider;
|
||||
|
||||
connection = nm_dbus_manager_get_connection (nm_dbus_manager_get ());
|
||||
|
||||
priv->proxy = dbus_g_proxy_new_for_name (connection,
|
||||
BLUEZ_SERVICE,
|
||||
priv->path,
|
||||
BLUEZ4_ADAPTER_INTERFACE);
|
||||
|
||||
dbus_g_proxy_add_signal (priv->proxy, "DeviceCreated",
|
||||
DBUS_TYPE_G_OBJECT_PATH, G_TYPE_INVALID);
|
||||
dbus_g_proxy_connect_signal (priv->proxy, "DeviceCreated",
|
||||
G_CALLBACK (device_created), self, NULL);
|
||||
|
||||
dbus_g_proxy_add_signal (priv->proxy, "DeviceRemoved",
|
||||
DBUS_TYPE_G_OBJECT_PATH, G_TYPE_INVALID);
|
||||
dbus_g_proxy_connect_signal (priv->proxy, "DeviceRemoved",
|
||||
G_CALLBACK (device_removed), self, NULL);
|
||||
priv->proxy = g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SYSTEM,
|
||||
G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES,
|
||||
NULL,
|
||||
BLUEZ_SERVICE,
|
||||
priv->path,
|
||||
BLUEZ4_ADAPTER_INTERFACE,
|
||||
NULL, NULL);
|
||||
_nm_dbus_signal_connect (priv->proxy, "DeviceCreated", G_VARIANT_TYPE ("(o)"),
|
||||
G_CALLBACK (device_created), self);
|
||||
_nm_dbus_signal_connect (priv->proxy, "DeviceRemoved", G_VARIANT_TYPE ("(o)"),
|
||||
G_CALLBACK (device_removed), self);
|
||||
|
||||
query_properties (self);
|
||||
return self;
|
||||
|
@@ -24,24 +24,20 @@
|
||||
#include <signal.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <dbus/dbus-glib.h>
|
||||
|
||||
#include "nm-logging.h"
|
||||
#include "nm-dbus-glib-types.h"
|
||||
#include "nm-bluez-manager.h"
|
||||
#include "nm-bluez4-manager.h"
|
||||
#include "nm-bluez4-adapter.h"
|
||||
#include "nm-dbus-manager.h"
|
||||
#include "nm-bluez-common.h"
|
||||
|
||||
#include "nm-core-internal.h"
|
||||
|
||||
typedef struct {
|
||||
NMDBusManager *dbus_mgr;
|
||||
gulong name_owner_changed_id;
|
||||
|
||||
NMConnectionProvider *provider;
|
||||
|
||||
DBusGProxy *proxy;
|
||||
GDBusProxy *proxy;
|
||||
|
||||
NMBluez4Adapter *adapter;
|
||||
} NMBluez4ManagerPrivate;
|
||||
@@ -120,7 +116,7 @@ adapter_initialized (NMBluez4Adapter *adapter, gboolean success, gpointer user_d
|
||||
}
|
||||
|
||||
static void
|
||||
adapter_removed (DBusGProxy *proxy, const char *path, NMBluez4Manager *self)
|
||||
adapter_removed (GDBusProxy *proxy, const char *path, NMBluez4Manager *self)
|
||||
{
|
||||
NMBluez4ManagerPrivate *priv = NM_BLUEZ4_MANAGER_GET_PRIVATE (self);
|
||||
|
||||
@@ -140,7 +136,7 @@ adapter_removed (DBusGProxy *proxy, const char *path, NMBluez4Manager *self)
|
||||
}
|
||||
|
||||
static void
|
||||
default_adapter_changed (DBusGProxy *proxy, const char *path, NMBluez4Manager *self)
|
||||
default_adapter_changed (GDBusProxy *proxy, const char *path, NMBluez4Manager *self)
|
||||
{
|
||||
NMBluez4ManagerPrivate *priv = NM_BLUEZ4_MANAGER_GET_PRIVATE (self);
|
||||
const char *cur_path = NULL;
|
||||
@@ -166,130 +162,65 @@ default_adapter_changed (DBusGProxy *proxy, const char *path, NMBluez4Manager *s
|
||||
}
|
||||
|
||||
static void
|
||||
default_adapter_cb (DBusGProxy *proxy, DBusGProxyCall *call, gpointer user_data)
|
||||
default_adapter_cb (GObject *proxy, GAsyncResult *result, gpointer user_data)
|
||||
{
|
||||
NMBluez4Manager *self = NM_BLUEZ4_MANAGER (user_data);
|
||||
NMBluez4ManagerPrivate *priv = NM_BLUEZ4_MANAGER_GET_PRIVATE (self);
|
||||
const char *default_adapter = NULL;
|
||||
GVariant *ret;
|
||||
GError *err = NULL;
|
||||
|
||||
if (!dbus_g_proxy_end_call (proxy, call, &err,
|
||||
DBUS_TYPE_G_OBJECT_PATH, &default_adapter,
|
||||
G_TYPE_INVALID)) {
|
||||
ret = _nm_dbus_proxy_call_finish (G_DBUS_PROXY (proxy), result,
|
||||
G_VARIANT_TYPE ("(o)"), &err);
|
||||
if (ret) {
|
||||
const char *default_adapter;
|
||||
|
||||
g_variant_get (ret, "(&o)", &default_adapter);
|
||||
default_adapter_changed (priv->proxy, default_adapter, self);
|
||||
g_variant_unref (ret);
|
||||
} else {
|
||||
/* Ignore "No such adapter" errors; just means bluetooth isn't active */
|
||||
if ( !dbus_g_error_has_name (err, "org.bluez.Error.NoSuchAdapter")
|
||||
&& !dbus_g_error_has_name (err, "org.freedesktop.systemd1.LoadFailed")
|
||||
&& !g_error_matches (err, DBUS_GERROR, DBUS_GERROR_SERVICE_UNKNOWN)) {
|
||||
if ( !_nm_dbus_error_has_name (err, "org.bluez.Error.NoSuchAdapter")
|
||||
&& !_nm_dbus_error_has_name (err, "org.freedesktop.systemd1.LoadFailed")
|
||||
&& !g_error_matches (err, G_DBUS_ERROR, G_DBUS_ERROR_SERVICE_UNKNOWN)) {
|
||||
g_dbus_error_strip_remote_error (err);
|
||||
nm_log_warn (LOGD_BT, "bluez error getting default adapter: %s",
|
||||
err && err->message ? err->message : "(unknown)");
|
||||
err->message);
|
||||
}
|
||||
g_error_free (err);
|
||||
return;
|
||||
}
|
||||
|
||||
default_adapter_changed (priv->proxy, default_adapter, self);
|
||||
}
|
||||
|
||||
static void
|
||||
query_default_adapter (NMBluez4Manager *self)
|
||||
{
|
||||
NMBluez4ManagerPrivate *priv = NM_BLUEZ4_MANAGER_GET_PRIVATE (self);
|
||||
DBusGProxyCall *call;
|
||||
|
||||
call = dbus_g_proxy_begin_call (priv->proxy, "DefaultAdapter",
|
||||
default_adapter_cb,
|
||||
self,
|
||||
NULL, G_TYPE_INVALID);
|
||||
if (!call)
|
||||
nm_log_warn (LOGD_BT, "failed to request default Bluetooth adapter.");
|
||||
g_dbus_proxy_call (priv->proxy, "DefaultAdapter",
|
||||
NULL,
|
||||
G_DBUS_CALL_FLAGS_NONE, -1,
|
||||
NULL,
|
||||
default_adapter_cb, self);
|
||||
}
|
||||
|
||||
static void
|
||||
bluez_connect (NMBluez4Manager *self)
|
||||
{
|
||||
NMBluez4ManagerPrivate *priv = NM_BLUEZ4_MANAGER_GET_PRIVATE (self);
|
||||
DBusGConnection *connection;
|
||||
|
||||
g_return_if_fail (priv->proxy == NULL);
|
||||
|
||||
connection = nm_dbus_manager_get_connection (priv->dbus_mgr);
|
||||
if (!connection)
|
||||
return;
|
||||
|
||||
priv->proxy = dbus_g_proxy_new_for_name (connection,
|
||||
BLUEZ_SERVICE,
|
||||
BLUEZ_MANAGER_PATH,
|
||||
BLUEZ4_MANAGER_INTERFACE);
|
||||
|
||||
dbus_g_proxy_add_signal (priv->proxy, "AdapterRemoved",
|
||||
DBUS_TYPE_G_OBJECT_PATH, G_TYPE_INVALID);
|
||||
dbus_g_proxy_connect_signal (priv->proxy, "AdapterRemoved",
|
||||
G_CALLBACK (adapter_removed), self, NULL);
|
||||
|
||||
dbus_g_proxy_add_signal (priv->proxy, "DefaultAdapterChanged",
|
||||
DBUS_TYPE_G_OBJECT_PATH, G_TYPE_INVALID);
|
||||
dbus_g_proxy_connect_signal (priv->proxy, "DefaultAdapterChanged",
|
||||
G_CALLBACK (default_adapter_changed), self, NULL);
|
||||
|
||||
query_default_adapter (self);
|
||||
}
|
||||
|
||||
static void
|
||||
name_owner_changed_cb (NMDBusManager *dbus_mgr,
|
||||
const char *name,
|
||||
const char *old_owner,
|
||||
const char *new_owner,
|
||||
name_owner_changed_cb (GObject *object,
|
||||
GParamSpec *pspec,
|
||||
gpointer user_data)
|
||||
{
|
||||
NMBluez4Manager *self = NM_BLUEZ4_MANAGER (user_data);
|
||||
NMBluez4ManagerPrivate *priv = NM_BLUEZ4_MANAGER_GET_PRIVATE (self);
|
||||
gboolean old_owner_good = (old_owner && strlen (old_owner));
|
||||
gboolean new_owner_good = (new_owner && strlen (new_owner));
|
||||
char *owner;
|
||||
|
||||
/* Can't handle the signal if its not from the Bluez */
|
||||
if (strcmp (BLUEZ_SERVICE, name))
|
||||
return;
|
||||
|
||||
if (!old_owner_good && new_owner_good)
|
||||
owner = g_dbus_proxy_get_name_owner (priv->proxy);
|
||||
if (owner) {
|
||||
query_default_adapter (self);
|
||||
else if (old_owner_good && !new_owner_good) {
|
||||
g_free (owner);
|
||||
} else {
|
||||
/* Throwing away the adapter removes all devices too */
|
||||
if (priv->adapter) {
|
||||
g_object_unref (priv->adapter);
|
||||
priv->adapter = NULL;
|
||||
}
|
||||
g_clear_object (&priv->adapter);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
bluez_cleanup (NMBluez4Manager *self, gboolean do_signal)
|
||||
{
|
||||
NMBluez4ManagerPrivate *priv = NM_BLUEZ4_MANAGER_GET_PRIVATE (self);
|
||||
|
||||
if (priv->proxy) {
|
||||
g_object_unref (priv->proxy);
|
||||
priv->proxy = NULL;
|
||||
}
|
||||
|
||||
if (priv->adapter) {
|
||||
g_object_unref (priv->adapter);
|
||||
priv->adapter = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
dbus_connection_changed_cb (NMDBusManager *dbus_mgr,
|
||||
DBusGConnection *connection,
|
||||
gpointer user_data)
|
||||
{
|
||||
NMBluez4Manager *self = NM_BLUEZ4_MANAGER (user_data);
|
||||
|
||||
if (!connection)
|
||||
bluez_cleanup (self, TRUE);
|
||||
else
|
||||
bluez_connect (self);
|
||||
}
|
||||
|
||||
/****************************************************************/
|
||||
|
||||
NMBluez4Manager *
|
||||
@@ -307,20 +238,21 @@ nm_bluez4_manager_init (NMBluez4Manager *self)
|
||||
{
|
||||
NMBluez4ManagerPrivate *priv = NM_BLUEZ4_MANAGER_GET_PRIVATE (self);
|
||||
|
||||
priv->dbus_mgr = nm_dbus_manager_get ();
|
||||
g_assert (priv->dbus_mgr);
|
||||
priv->proxy = g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SYSTEM,
|
||||
G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES,
|
||||
NULL,
|
||||
BLUEZ_SERVICE,
|
||||
BLUEZ_MANAGER_PATH,
|
||||
BLUEZ4_MANAGER_INTERFACE,
|
||||
NULL, NULL);
|
||||
_nm_dbus_signal_connect (priv->proxy, "AdapterRemoved", G_VARIANT_TYPE ("(o)"),
|
||||
G_CALLBACK (adapter_removed), self);
|
||||
_nm_dbus_signal_connect (priv->proxy, "DefaultAdapterChanged", G_VARIANT_TYPE ("(o)"),
|
||||
G_CALLBACK (default_adapter_changed), self);
|
||||
g_signal_connect (priv->proxy, "notify::g-name-owner",
|
||||
G_CALLBACK (name_owner_changed_cb), self);
|
||||
|
||||
g_signal_connect (priv->dbus_mgr,
|
||||
NM_DBUS_MANAGER_NAME_OWNER_CHANGED,
|
||||
G_CALLBACK (name_owner_changed_cb),
|
||||
self);
|
||||
|
||||
g_signal_connect (priv->dbus_mgr,
|
||||
NM_DBUS_MANAGER_DBUS_CONNECTION_CHANGED,
|
||||
G_CALLBACK (dbus_connection_changed_cb),
|
||||
self);
|
||||
|
||||
bluez_connect (self);
|
||||
query_default_adapter (self);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -329,13 +261,8 @@ dispose (GObject *object)
|
||||
NMBluez4Manager *self = NM_BLUEZ4_MANAGER (object);
|
||||
NMBluez4ManagerPrivate *priv = NM_BLUEZ4_MANAGER_GET_PRIVATE (self);
|
||||
|
||||
bluez_cleanup (self, FALSE);
|
||||
|
||||
if (priv->dbus_mgr) {
|
||||
g_signal_handlers_disconnect_by_func (priv->dbus_mgr, name_owner_changed_cb, self);
|
||||
g_signal_handlers_disconnect_by_func (priv->dbus_mgr, dbus_connection_changed_cb, self);
|
||||
priv->dbus_mgr = NULL;
|
||||
}
|
||||
g_clear_object (&priv->proxy);
|
||||
g_clear_object (&priv->adapter);
|
||||
|
||||
G_OBJECT_CLASS (nm_bluez4_manager_parent_class)->dispose (object);
|
||||
}
|
||||
|
@@ -34,6 +34,7 @@
|
||||
#include "nm-bluez-common.h"
|
||||
|
||||
#include "nm-dbus-manager.h"
|
||||
#include "nm-core-internal.h"
|
||||
|
||||
typedef struct {
|
||||
NMDBusManager *dbus_mgr;
|
||||
@@ -170,39 +171,23 @@ device_removed (GDBusProxy *proxy, const gchar *path, NMBluez5Manager *self)
|
||||
}
|
||||
|
||||
static void
|
||||
object_manager_g_signal (GDBusProxy *proxy,
|
||||
gchar *sender_name,
|
||||
gchar *signal_name,
|
||||
GVariant *parameters,
|
||||
NMBluez5Manager *self)
|
||||
object_manager_interfaces_added (GDBusProxy *proxy,
|
||||
const char *path,
|
||||
GVariant *dict,
|
||||
NMBluez5Manager *self)
|
||||
{
|
||||
GVariant *variant;
|
||||
const gchar *path;
|
||||
if (g_variant_lookup (dict, BLUEZ5_DEVICE_INTERFACE, "a{sv}", NULL))
|
||||
device_added (proxy, path, self);
|
||||
}
|
||||
|
||||
if (!strcmp (signal_name, "InterfacesRemoved")) {
|
||||
const gchar **ifaces;
|
||||
gsize i, length;
|
||||
|
||||
g_variant_get (parameters, "(&o*)", &path, &variant);
|
||||
|
||||
ifaces = g_variant_get_strv (variant, &length);
|
||||
|
||||
for (i = 0; i < length; i++) {
|
||||
if (!strcmp (ifaces[i], BLUEZ5_DEVICE_INTERFACE)) {
|
||||
device_removed (proxy, path, self);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
g_free (ifaces);
|
||||
|
||||
} else if (!strcmp (signal_name, "InterfacesAdded")) {
|
||||
g_variant_get (parameters, "(&o*)", &path, &variant);
|
||||
|
||||
if (g_variant_lookup_value (variant, BLUEZ5_DEVICE_INTERFACE,
|
||||
G_VARIANT_TYPE_DICTIONARY))
|
||||
device_added (proxy, path, self);
|
||||
}
|
||||
static void
|
||||
object_manager_interfaces_removed (GDBusProxy *proxy,
|
||||
const char *path,
|
||||
const char **ifaces,
|
||||
NMBluez5Manager *self)
|
||||
{
|
||||
if (_nm_utils_string_in_list (BLUEZ5_DEVICE_INTERFACE, ifaces))
|
||||
device_removed (proxy, path, self);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -215,8 +200,9 @@ get_managed_objects_cb (GDBusProxy *proxy,
|
||||
GError *error = NULL;
|
||||
const char *path;
|
||||
|
||||
variant = g_dbus_proxy_call_finish (proxy, res, &error);
|
||||
|
||||
variant = _nm_dbus_proxy_call_finish (proxy, res,
|
||||
G_VARIANT_TYPE ("(a{oa{sa{sv}}})"),
|
||||
&error);
|
||||
if (!variant) {
|
||||
if (g_error_matches (error, G_DBUS_ERROR, G_DBUS_ERROR_UNKNOWN_METHOD))
|
||||
nm_log_warn (LOGD_BT, "Couldn't get managed objects: not running Bluez5?");
|
||||
@@ -264,8 +250,10 @@ on_proxy_acquired (GObject *object,
|
||||
(GAsyncReadyCallback) get_managed_objects_cb,
|
||||
self);
|
||||
|
||||
g_signal_connect (priv->proxy, "g-signal",
|
||||
G_CALLBACK (object_manager_g_signal), self);
|
||||
_nm_dbus_signal_connect (priv->proxy, "InterfacesAdded", G_VARIANT_TYPE ("(oa{sa{sv}})"),
|
||||
G_CALLBACK (object_manager_interfaces_added), self);
|
||||
_nm_dbus_signal_connect (priv->proxy, "InterfacesRemoved", G_VARIANT_TYPE ("(oas)"),
|
||||
G_CALLBACK (object_manager_interfaces_removed), self);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@@ -24,6 +24,7 @@
|
||||
|
||||
#include "nm-logging.h"
|
||||
#include "nm-errors.h"
|
||||
#include "nm-core-internal.h"
|
||||
|
||||
#define POLKIT_SERVICE "org.freedesktop.PolicyKit1"
|
||||
#define POLKIT_OBJECT_PATH "/org/freedesktop/PolicyKit1/Authority"
|
||||
@@ -176,7 +177,7 @@ check_authorization_cb (GDBusProxy *proxy,
|
||||
GVariant *value;
|
||||
GError *error = NULL;
|
||||
|
||||
value = g_dbus_proxy_call_finish (proxy, res, &error);
|
||||
value = _nm_dbus_proxy_call_finish (proxy, res, G_VARIANT_TYPE ("((bba{ss}))"), &error);
|
||||
if (value == NULL) {
|
||||
if (data->cancellation_id != NULL &&
|
||||
(!g_dbus_error_is_remote_error (error) &&
|
||||
@@ -200,18 +201,15 @@ check_authorization_cb (GDBusProxy *proxy,
|
||||
error->message);
|
||||
g_error_free (error);
|
||||
} else {
|
||||
GVariant *result_value;
|
||||
CheckAuthorizationResult *result;
|
||||
|
||||
result = g_new0 (CheckAuthorizationResult, 1);
|
||||
|
||||
result_value = g_variant_get_child_value (value, 0);
|
||||
g_variant_get (result_value,
|
||||
"(bb@a{ss})",
|
||||
g_variant_get (value,
|
||||
"((bb@a{ss}))",
|
||||
&result->is_authorized,
|
||||
&result->is_challenge,
|
||||
NULL);
|
||||
g_variant_unref (result_value);
|
||||
g_variant_unref (value);
|
||||
|
||||
_LOGD ("call[%u]: CheckAuthorization succeeded: (is_authorized=%d, is_challenge=%d)", data->call_id, result->is_authorized, result->is_challenge);
|
||||
@@ -394,21 +392,16 @@ _dbus_on_name_owner_notify_cb (GObject *object,
|
||||
}
|
||||
|
||||
static void
|
||||
_dbus_on_g_signal_cb (GDBusProxy *proxy,
|
||||
const gchar *sender_name,
|
||||
const gchar *signal_name,
|
||||
GVariant *parameters,
|
||||
gpointer user_data)
|
||||
_dbus_on_changed_signal_cb (GDBusProxy *proxy,
|
||||
gpointer user_data)
|
||||
{
|
||||
NMAuthManager *self = user_data;
|
||||
NMAuthManagerPrivate *priv = NM_AUTH_MANAGER_GET_PRIVATE (self);
|
||||
|
||||
g_return_if_fail (priv->proxy == proxy);
|
||||
|
||||
_LOGD ("dbus signal: \"%s\"", signal_name ? signal_name : "(null)");
|
||||
|
||||
if (g_strcmp0 (signal_name, "Changed") == 0)
|
||||
_emit_changed_signal (self);
|
||||
_LOGD ("dbus signal: \"Changed\"");
|
||||
_emit_changed_signal (self);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -463,10 +456,9 @@ _dbus_new_proxy_cb (GObject *source_object,
|
||||
"notify::g-name-owner",
|
||||
G_CALLBACK (_dbus_on_name_owner_notify_cb),
|
||||
self);
|
||||
g_signal_connect (priv->proxy,
|
||||
"g-signal",
|
||||
G_CALLBACK (_dbus_on_g_signal_cb),
|
||||
self);
|
||||
_nm_dbus_signal_connect (priv->proxy, "Changed", NULL,
|
||||
G_CALLBACK (_dbus_on_changed_signal_cb),
|
||||
self);
|
||||
|
||||
_log_name_owner (self, NULL);
|
||||
|
||||
@@ -604,8 +596,7 @@ dispose (GObject *object)
|
||||
}
|
||||
|
||||
if (priv->proxy) {
|
||||
g_signal_handlers_disconnect_by_func (priv->proxy, _dbus_on_name_owner_notify_cb, self);
|
||||
g_signal_handlers_disconnect_by_func (priv->proxy, _dbus_on_g_signal_cb, self);
|
||||
g_signal_handlers_disconnect_by_data (priv->proxy, self);
|
||||
g_clear_object (&priv->proxy);
|
||||
}
|
||||
#endif
|
||||
|
@@ -35,12 +35,17 @@
|
||||
#include "nm-device.h"
|
||||
#include "nm-dhcp4-config.h"
|
||||
#include "nm-dhcp6-config.h"
|
||||
#include "nm-ip4-config.h"
|
||||
#include "nm-ip6-config.h"
|
||||
#include "nm-dbus-glib-types.h"
|
||||
#include "nm-glib-compat.h"
|
||||
#include "nm-settings-connection.h"
|
||||
#include "nm-platform.h"
|
||||
#include "nm-core-internal.h"
|
||||
|
||||
#define CALL_TIMEOUT (1000 * 60 * 10) /* 10 minutes for all scripts */
|
||||
|
||||
static GDBusProxy *dispatcher_proxy;
|
||||
static GHashTable *requests = NULL;
|
||||
|
||||
typedef struct {
|
||||
@@ -80,24 +85,145 @@ _get_monitor_by_action (DispatcherAction action)
|
||||
}
|
||||
|
||||
static void
|
||||
dump_object_to_props (GObject *object, GHashTable *hash)
|
||||
dump_ip4_to_props (NMIP4Config *ip4, GVariantBuilder *builder)
|
||||
{
|
||||
GParamSpec **pspecs;
|
||||
guint len = 0, i;
|
||||
GVariantBuilder int_builder;
|
||||
guint n, i;
|
||||
const NMPlatformIP4Address *addr;
|
||||
const NMPlatformIP4Route *route;
|
||||
guint32 array[4];
|
||||
|
||||
pspecs = g_object_class_list_properties (G_OBJECT_GET_CLASS (object), &len);
|
||||
for (i = 0; i < len; i++) {
|
||||
value_hash_add_object_property (hash,
|
||||
pspecs[i]->name,
|
||||
object,
|
||||
pspecs[i]->name,
|
||||
pspecs[i]->value_type);
|
||||
/* Addresses */
|
||||
g_variant_builder_init (&int_builder, G_VARIANT_TYPE ("aau"));
|
||||
n = nm_ip4_config_get_num_addresses (ip4);
|
||||
for (i = 0; i < n; i++) {
|
||||
addr = nm_ip4_config_get_address (ip4, i);
|
||||
array[0] = addr->address;
|
||||
array[1] = addr->plen;
|
||||
array[2] = (i == 0) ? nm_ip4_config_get_gateway (ip4) : 0;
|
||||
g_variant_builder_add (&int_builder, "@au",
|
||||
g_variant_new_fixed_array (G_VARIANT_TYPE_UINT32,
|
||||
array, 3, sizeof (guint32)));
|
||||
}
|
||||
g_free (pspecs);
|
||||
g_variant_builder_add (builder, "{sv}",
|
||||
"addresses",
|
||||
g_variant_builder_end (&int_builder));
|
||||
|
||||
/* DNS servers */
|
||||
g_variant_builder_init (&int_builder, G_VARIANT_TYPE ("au"));
|
||||
n = nm_ip4_config_get_num_nameservers (ip4);
|
||||
for (i = 0; i < n; i++)
|
||||
g_variant_builder_add (&int_builder, "u", nm_ip4_config_get_nameserver (ip4, i));
|
||||
g_variant_builder_add (builder, "{sv}",
|
||||
"nameservers",
|
||||
g_variant_builder_end (&int_builder));
|
||||
|
||||
/* Search domains */
|
||||
g_variant_builder_init (&int_builder, G_VARIANT_TYPE ("as"));
|
||||
n = nm_ip4_config_get_num_domains (ip4);
|
||||
for (i = 0; i < n; i++)
|
||||
g_variant_builder_add (&int_builder, "s", nm_ip4_config_get_domain (ip4, i));
|
||||
g_variant_builder_add (builder, "{sv}",
|
||||
"domains",
|
||||
g_variant_builder_end (&int_builder));
|
||||
|
||||
/* WINS servers */
|
||||
g_variant_builder_init (&int_builder, G_VARIANT_TYPE ("au"));
|
||||
n = nm_ip4_config_get_num_wins (ip4);
|
||||
for (i = 0; i < n; i++)
|
||||
g_variant_builder_add (&int_builder, "u", nm_ip4_config_get_wins (ip4, i));
|
||||
g_variant_builder_add (builder, "{sv}",
|
||||
"wins-servers",
|
||||
g_variant_builder_end (&int_builder));
|
||||
|
||||
/* Static routes */
|
||||
g_variant_builder_init (&int_builder, G_VARIANT_TYPE ("aau"));
|
||||
n = nm_ip4_config_get_num_routes (ip4);
|
||||
for (i = 0; i < n; i++) {
|
||||
route = nm_ip4_config_get_route (ip4, i);
|
||||
array[0] = route->network;
|
||||
array[1] = route->plen;
|
||||
array[2] = route->gateway;
|
||||
array[3] = route->metric;
|
||||
g_variant_builder_add (&int_builder, "@au",
|
||||
g_variant_new_fixed_array (G_VARIANT_TYPE_UINT32,
|
||||
array, 4, sizeof (guint32)));
|
||||
}
|
||||
g_variant_builder_add (builder, "{sv}",
|
||||
"routes",
|
||||
g_variant_builder_end (&int_builder));
|
||||
}
|
||||
|
||||
static void
|
||||
dump_dhcp4_to_props (NMDhcp4Config *config, GHashTable *hash)
|
||||
dump_ip6_to_props (NMIP6Config *ip6, GVariantBuilder *builder)
|
||||
{
|
||||
GVariantBuilder int_builder;
|
||||
guint n, i;
|
||||
const NMPlatformIP6Address *addr;
|
||||
const struct in6_addr *gw_bytes;
|
||||
const NMPlatformIP6Route *route;
|
||||
GVariant *ip, *gw;
|
||||
|
||||
/* Addresses */
|
||||
g_variant_builder_init (&int_builder, G_VARIANT_TYPE ("a(ayuay)"));
|
||||
n = nm_ip6_config_get_num_addresses (ip6);
|
||||
for (i = 0; i < n; i++) {
|
||||
addr = nm_ip6_config_get_address (ip6, i);
|
||||
gw_bytes = nm_ip6_config_get_gateway (ip6);
|
||||
ip = g_variant_new_fixed_array (G_VARIANT_TYPE_BYTE,
|
||||
&addr->address,
|
||||
sizeof (struct in6_addr), 1);
|
||||
gw = g_variant_new_fixed_array (G_VARIANT_TYPE_BYTE,
|
||||
(i == 0 && gw_bytes) ? gw_bytes : &in6addr_any,
|
||||
sizeof (struct in6_addr), 1);
|
||||
g_variant_builder_add (&int_builder, "(@ayu@ay)", ip, addr->plen, gw);
|
||||
}
|
||||
g_variant_builder_add (builder, "{sv}",
|
||||
"addresses",
|
||||
g_variant_builder_end (&int_builder));
|
||||
|
||||
/* DNS servers */
|
||||
g_variant_builder_init (&int_builder, G_VARIANT_TYPE ("aay"));
|
||||
n = nm_ip6_config_get_num_nameservers (ip6);
|
||||
for (i = 0; i < n; i++) {
|
||||
ip = g_variant_new_fixed_array (G_VARIANT_TYPE_BYTE,
|
||||
nm_ip6_config_get_nameserver (ip6, i),
|
||||
sizeof (struct in6_addr), 1);
|
||||
g_variant_builder_add (&int_builder, "@ay", ip);
|
||||
}
|
||||
g_variant_builder_add (builder, "{sv}",
|
||||
"nameservers",
|
||||
g_variant_builder_end (&int_builder));
|
||||
|
||||
/* Search domains */
|
||||
g_variant_builder_init (&int_builder, G_VARIANT_TYPE ("as"));
|
||||
n = nm_ip6_config_get_num_domains (ip6);
|
||||
for (i = 0; i < n; i++)
|
||||
g_variant_builder_add (&int_builder, "s", nm_ip6_config_get_domain (ip6, i));
|
||||
g_variant_builder_add (builder, "{sv}",
|
||||
"domains",
|
||||
g_variant_builder_end (&int_builder));
|
||||
|
||||
/* Static routes */
|
||||
g_variant_builder_init (&int_builder, G_VARIANT_TYPE ("a(ayuayu)"));
|
||||
n = nm_ip6_config_get_num_routes (ip6);
|
||||
for (i = 0; i < n; i++) {
|
||||
route = nm_ip6_config_get_route (ip6, i);
|
||||
ip = g_variant_new_fixed_array (G_VARIANT_TYPE_BYTE,
|
||||
&route->network,
|
||||
sizeof (struct in6_addr), 1);
|
||||
gw = g_variant_new_fixed_array (G_VARIANT_TYPE_BYTE,
|
||||
&route->gateway,
|
||||
sizeof (struct in6_addr), 1);
|
||||
g_variant_builder_add (&int_builder, "(@ayu@ayu)", ip, route->plen, gw, route->metric);
|
||||
}
|
||||
g_variant_builder_add (builder, "{sv}",
|
||||
"routes",
|
||||
g_variant_builder_end (&int_builder));
|
||||
}
|
||||
|
||||
static void
|
||||
dump_dhcp4_to_props (NMDhcp4Config *config, GVariantBuilder *builder)
|
||||
{
|
||||
GSList *options, *iter;
|
||||
|
||||
@@ -107,13 +233,13 @@ dump_dhcp4_to_props (NMDhcp4Config *config, GHashTable *hash)
|
||||
const char *val;
|
||||
|
||||
val = nm_dhcp4_config_get_option (config, option);
|
||||
value_hash_add_str (hash, option, val);
|
||||
g_variant_builder_add (builder, "{sv}", option, g_variant_new_string (val));
|
||||
}
|
||||
g_slist_free (options);
|
||||
}
|
||||
|
||||
static void
|
||||
dump_dhcp6_to_props (NMDhcp6Config *config, GHashTable *hash)
|
||||
dump_dhcp6_to_props (NMDhcp6Config *config, GVariantBuilder *builder)
|
||||
{
|
||||
GSList *options, *iter;
|
||||
|
||||
@@ -123,18 +249,18 @@ dump_dhcp6_to_props (NMDhcp6Config *config, GHashTable *hash)
|
||||
const char *val;
|
||||
|
||||
val = nm_dhcp6_config_get_option (config, option);
|
||||
value_hash_add_str (hash, option, val);
|
||||
g_variant_builder_add (builder, "{sv}", option, g_variant_new_string (val));
|
||||
}
|
||||
g_slist_free (options);
|
||||
}
|
||||
|
||||
static void
|
||||
fill_device_props (NMDevice *device,
|
||||
GHashTable *dev_hash,
|
||||
GHashTable *ip4_hash,
|
||||
GHashTable *ip6_hash,
|
||||
GHashTable *dhcp4_hash,
|
||||
GHashTable *dhcp6_hash)
|
||||
GVariantBuilder *dev_builder,
|
||||
GVariantBuilder *ip4_builder,
|
||||
GVariantBuilder *ip6_builder,
|
||||
GVariantBuilder *dhcp4_builder,
|
||||
GVariantBuilder *dhcp6_builder)
|
||||
{
|
||||
NMIP4Config *ip4_config;
|
||||
NMIP6Config *ip6_config;
|
||||
@@ -142,39 +268,44 @@ fill_device_props (NMDevice *device,
|
||||
NMDhcp6Config *dhcp6_config;
|
||||
|
||||
/* If the action is for a VPN, send the VPN's IP interface instead of the device's */
|
||||
value_hash_add_str (dev_hash, NMD_DEVICE_PROPS_IP_INTERFACE, nm_device_get_ip_iface (device));
|
||||
value_hash_add_str (dev_hash, NMD_DEVICE_PROPS_INTERFACE, nm_device_get_iface (device));
|
||||
value_hash_add_uint (dev_hash, NMD_DEVICE_PROPS_TYPE, nm_device_get_device_type (device));
|
||||
value_hash_add_uint (dev_hash, NMD_DEVICE_PROPS_STATE, nm_device_get_state (device));
|
||||
value_hash_add_object_path (dev_hash, NMD_DEVICE_PROPS_PATH, nm_device_get_path (device));
|
||||
g_variant_builder_add (dev_builder, "{sv}", NMD_DEVICE_PROPS_IP_INTERFACE,
|
||||
g_variant_new_string (nm_device_get_ip_iface (device)));
|
||||
g_variant_builder_add (dev_builder, "{sv}", NMD_DEVICE_PROPS_INTERFACE,
|
||||
g_variant_new_string (nm_device_get_iface (device)));
|
||||
g_variant_builder_add (dev_builder, "{sv}", NMD_DEVICE_PROPS_TYPE,
|
||||
g_variant_new_uint32 (nm_device_get_device_type (device)));
|
||||
g_variant_builder_add (dev_builder, "{sv}", NMD_DEVICE_PROPS_STATE,
|
||||
g_variant_new_uint32 (nm_device_get_state (device)));
|
||||
g_variant_builder_add (dev_builder, "{sv}", NMD_DEVICE_PROPS_PATH,
|
||||
g_variant_new_object_path (nm_device_get_path (device)));
|
||||
|
||||
ip4_config = nm_device_get_ip4_config (device);
|
||||
if (ip4_config)
|
||||
dump_object_to_props (G_OBJECT (ip4_config), ip4_hash);
|
||||
dump_ip4_to_props (ip4_config, ip4_builder);
|
||||
|
||||
ip6_config = nm_device_get_ip6_config (device);
|
||||
if (ip6_config)
|
||||
dump_object_to_props (G_OBJECT (ip6_config), ip6_hash);
|
||||
dump_ip6_to_props (ip6_config, ip6_builder);
|
||||
|
||||
dhcp4_config = nm_device_get_dhcp4_config (device);
|
||||
if (dhcp4_config)
|
||||
dump_dhcp4_to_props (dhcp4_config, dhcp4_hash);
|
||||
dump_dhcp4_to_props (dhcp4_config, dhcp4_builder);
|
||||
|
||||
dhcp6_config = nm_device_get_dhcp6_config (device);
|
||||
if (dhcp6_config)
|
||||
dump_dhcp6_to_props (dhcp6_config, dhcp6_hash);
|
||||
dump_dhcp6_to_props (dhcp6_config, dhcp6_builder);
|
||||
}
|
||||
|
||||
static void
|
||||
fill_vpn_props (NMIP4Config *ip4_config,
|
||||
NMIP6Config *ip6_config,
|
||||
GHashTable *ip4_hash,
|
||||
GHashTable *ip6_hash)
|
||||
GVariantBuilder *ip4_builder,
|
||||
GVariantBuilder *ip6_builder)
|
||||
{
|
||||
if (ip4_config)
|
||||
dump_object_to_props (G_OBJECT (ip4_config), ip4_hash);
|
||||
dump_ip4_to_props (ip4_config, ip4_builder);
|
||||
if (ip6_config)
|
||||
dump_object_to_props (G_OBJECT (ip6_config), ip6_hash);
|
||||
dump_ip6_to_props (ip6_config, ip6_builder);
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
@@ -228,51 +359,25 @@ dispatch_result_to_string (DispatchResult result)
|
||||
g_assert_not_reached ();
|
||||
}
|
||||
|
||||
static gboolean
|
||||
validate_element (guint request_id, GValue *val, GType expected_type, guint idx, guint eltnum)
|
||||
{
|
||||
if (G_VALUE_TYPE (val) != expected_type) {
|
||||
nm_log_dbg (LOGD_DISPATCH, "(%u) result %d element %d invalid type %s",
|
||||
request_id, idx, eltnum, G_VALUE_TYPE_NAME (val));
|
||||
return FALSE;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
dispatcher_results_process (guint request_id, DispatcherAction action, GPtrArray *results)
|
||||
dispatcher_results_process (guint request_id, DispatcherAction action, GVariantIter *results)
|
||||
{
|
||||
guint i;
|
||||
const char *script, *err;
|
||||
guint32 result;
|
||||
const Monitor *monitor = _get_monitor_by_action (action);
|
||||
|
||||
g_return_if_fail (results != NULL);
|
||||
|
||||
if (results->len == 0) {
|
||||
if (g_variant_iter_n_children (results) == 0) {
|
||||
nm_log_dbg (LOGD_DISPATCH, "(%u) succeeded but no scripts invoked",
|
||||
request_id);
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 0; i < results->len; i++) {
|
||||
GValueArray *item = g_ptr_array_index (results, i);
|
||||
GValue *tmp;
|
||||
const char *script, *err;
|
||||
DispatchResult result;
|
||||
while (g_variant_iter_next (results, "(&su&s)", &script, &result, &err)) {
|
||||
const char *script_validation_msg = "";
|
||||
|
||||
if (item->n_values != 3) {
|
||||
nm_log_dbg (LOGD_DISPATCH, "(%u) unexpected number of items in "
|
||||
"dispatcher result (got %d, expected 3)",
|
||||
request_id, item->n_values);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Script */
|
||||
tmp = g_value_array_get_nth (item, 0);
|
||||
if (!validate_element (request_id, tmp, G_TYPE_STRING, i, 0))
|
||||
continue;
|
||||
script = g_value_get_string (tmp);
|
||||
if (!script) {
|
||||
if (!*script) {
|
||||
script_validation_msg = " (path is NULL)";
|
||||
script = "(unknown)";
|
||||
} else if (!strncmp (script, monitor->dir, monitor->dir_len) /* check: prefixed by script directory */
|
||||
@@ -284,20 +389,6 @@ dispatcher_results_process (guint request_id, DispatcherAction action, GPtrArray
|
||||
} else
|
||||
script_validation_msg = " (unexpected path)";
|
||||
|
||||
|
||||
/* Result */
|
||||
tmp = g_value_array_get_nth (item, 1);
|
||||
if (!validate_element (request_id, tmp, G_TYPE_UINT, i, 1))
|
||||
continue;
|
||||
result = g_value_get_uint (tmp);
|
||||
|
||||
/* Error */
|
||||
tmp = g_value_array_get_nth (item, 2);
|
||||
if (!validate_element (request_id, tmp, G_TYPE_STRING, i, 2))
|
||||
continue;
|
||||
err = g_value_get_string (tmp);
|
||||
|
||||
|
||||
if (result == DISPATCH_RESULT_SUCCESS) {
|
||||
nm_log_dbg (LOGD_DISPATCH, "(%u) %s succeeded%s",
|
||||
request_id,
|
||||
@@ -307,52 +398,43 @@ dispatcher_results_process (guint request_id, DispatcherAction action, GPtrArray
|
||||
request_id,
|
||||
script,
|
||||
dispatch_result_to_string (result),
|
||||
err ? err : "", script_validation_msg);
|
||||
err, script_validation_msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
free_results (GPtrArray *results)
|
||||
{
|
||||
g_return_if_fail (results != NULL);
|
||||
g_ptr_array_foreach (results, (GFunc) g_value_array_free, NULL);
|
||||
g_ptr_array_free (results, TRUE);
|
||||
}
|
||||
|
||||
static void
|
||||
dispatcher_done_cb (DBusGProxy *proxy, DBusGProxyCall *call, gpointer user_data)
|
||||
dispatcher_done_cb (GObject *proxy, GAsyncResult *result, gpointer user_data)
|
||||
{
|
||||
DispatchInfo *info = user_data;
|
||||
GVariant *ret;
|
||||
GVariantIter *results;
|
||||
GError *error = NULL;
|
||||
GPtrArray *results = NULL;
|
||||
|
||||
if (dbus_g_proxy_end_call (proxy, call, &error,
|
||||
DISPATCHER_TYPE_RESULT_ARRAY, &results,
|
||||
G_TYPE_INVALID)) {
|
||||
ret = _nm_dbus_proxy_call_finish (G_DBUS_PROXY (proxy), result,
|
||||
G_VARIANT_TYPE ("(a(sus))"),
|
||||
&error);
|
||||
if (ret) {
|
||||
g_variant_get (ret, "(a(sus))", &results);
|
||||
dispatcher_results_process (info->request_id, info->action, results);
|
||||
free_results (results);
|
||||
g_variant_iter_free (results);
|
||||
g_variant_unref (ret);
|
||||
} else {
|
||||
g_assert (error);
|
||||
|
||||
if (!g_error_matches (error, DBUS_GERROR, DBUS_GERROR_REMOTE_EXCEPTION)) {
|
||||
nm_log_warn (LOGD_DISPATCH, "(%u) failed to call dispatcher scripts: (%s:%d) %s",
|
||||
info->request_id, g_quark_to_string (error->domain),
|
||||
error->code, error->message);
|
||||
} else if (!dbus_g_error_has_name (error, "org.freedesktop.systemd1.LoadFailed")) {
|
||||
nm_log_warn (LOGD_DISPATCH, "(%u) failed to call dispatcher scripts: (%s) %s",
|
||||
info->request_id, dbus_g_error_get_name (error), error->message);
|
||||
if (_nm_dbus_error_has_name (error, "org.freedesktop.systemd1.LoadFailed")) {
|
||||
g_dbus_error_strip_remote_error (error);
|
||||
nm_log_warn (LOGD_DISPATCH, "(%u) failed to call dispatcher scripts: %s",
|
||||
info->request_id, error->message);
|
||||
} else {
|
||||
nm_log_dbg (LOGD_DISPATCH, "(%u) failed to call dispatcher scripts: (%s) %s",
|
||||
info->request_id, dbus_g_error_get_name (error), error->message);
|
||||
nm_log_dbg (LOGD_DISPATCH, "(%u) failed to call dispatcher scripts: %s",
|
||||
info->request_id, error->message);
|
||||
}
|
||||
g_clear_error (&error);
|
||||
}
|
||||
|
||||
if (info->callback)
|
||||
info->callback (info->request_id, info->user_data);
|
||||
|
||||
g_clear_error (&error);
|
||||
g_object_unref (proxy);
|
||||
dispatcher_info_cleanup (info);
|
||||
}
|
||||
|
||||
static const char *action_table[] = {
|
||||
@@ -400,23 +482,24 @@ _dispatcher_call (DispatcherAction action,
|
||||
gpointer user_data,
|
||||
guint *out_call_id)
|
||||
{
|
||||
DBusGProxy *proxy;
|
||||
DBusGConnection *g_connection;
|
||||
GHashTable *connection_hash;
|
||||
GHashTable *connection_props;
|
||||
GHashTable *device_props;
|
||||
GHashTable *device_ip4_props;
|
||||
GHashTable *device_ip6_props;
|
||||
GHashTable *device_dhcp4_props;
|
||||
GHashTable *device_dhcp6_props;
|
||||
GHashTable *vpn_ip4_props;
|
||||
GHashTable *vpn_ip6_props;
|
||||
GVariant *connection_dict;
|
||||
GVariantBuilder connection_props;
|
||||
GVariantBuilder device_props;
|
||||
GVariantBuilder device_ip4_props;
|
||||
GVariantBuilder device_ip6_props;
|
||||
GVariantBuilder device_dhcp4_props;
|
||||
GVariantBuilder device_dhcp6_props;
|
||||
GVariantBuilder vpn_ip4_props;
|
||||
GVariantBuilder vpn_ip6_props;
|
||||
DispatchInfo *info = NULL;
|
||||
gboolean success = FALSE;
|
||||
GError *error = NULL;
|
||||
static guint request_counter = 0;
|
||||
guint reqid = ++request_counter;
|
||||
|
||||
if (!dispatcher_proxy)
|
||||
return FALSE;
|
||||
|
||||
/* Wrapping protection */
|
||||
if (G_UNLIKELY (!reqid))
|
||||
reqid = ++request_counter;
|
||||
@@ -463,92 +546,87 @@ _dispatcher_call (DispatcherAction action,
|
||||
goto done;
|
||||
}
|
||||
|
||||
g_connection = nm_dbus_manager_get_connection (nm_dbus_manager_get ());
|
||||
proxy = dbus_g_proxy_new_for_name (g_connection,
|
||||
NM_DISPATCHER_DBUS_SERVICE,
|
||||
NM_DISPATCHER_DBUS_PATH,
|
||||
NM_DISPATCHER_DBUS_INTERFACE);
|
||||
if (!proxy) {
|
||||
nm_log_err (LOGD_DISPATCH, "(%u) could not get dispatcher proxy!", reqid);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (connection) {
|
||||
GVariant *connection_dict;
|
||||
const char *filename;
|
||||
|
||||
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,
|
||||
NMD_CONNECTION_PROPS_PATH,
|
||||
nm_connection_get_path (connection));
|
||||
g_variant_builder_init (&connection_props, G_VARIANT_TYPE_VARDICT);
|
||||
g_variant_builder_add (&connection_props, "{sv}",
|
||||
NMD_CONNECTION_PROPS_PATH,
|
||||
g_variant_new_object_path (nm_connection_get_path (connection)));
|
||||
filename = nm_settings_connection_get_filename (NM_SETTINGS_CONNECTION (connection));
|
||||
if (filename) {
|
||||
value_hash_add_str (connection_props,
|
||||
NMD_CONNECTION_PROPS_FILENAME,
|
||||
filename);
|
||||
g_variant_builder_add (&connection_props, "{sv}",
|
||||
NMD_CONNECTION_PROPS_FILENAME,
|
||||
g_variant_new_string (filename));
|
||||
}
|
||||
if (nm_settings_connection_get_nm_generated_assumed (NM_SETTINGS_CONNECTION (connection))) {
|
||||
value_hash_add_bool (connection_props,
|
||||
NMD_CONNECTION_PROPS_EXTERNAL,
|
||||
TRUE);
|
||||
g_variant_builder_add (&connection_props, "{sv}",
|
||||
NMD_CONNECTION_PROPS_EXTERNAL,
|
||||
g_variant_new_boolean (TRUE));
|
||||
}
|
||||
} else {
|
||||
connection_hash = value_hash_create ();
|
||||
connection_props = value_hash_create ();
|
||||
connection_dict = g_variant_new_array (G_VARIANT_TYPE ("{sv}"), NULL, 0);
|
||||
g_variant_builder_init (&connection_props, G_VARIANT_TYPE_VARDICT);
|
||||
}
|
||||
|
||||
device_props = value_hash_create ();
|
||||
device_ip4_props = value_hash_create ();
|
||||
device_ip6_props = value_hash_create ();
|
||||
device_dhcp4_props = value_hash_create ();
|
||||
device_dhcp6_props = value_hash_create ();
|
||||
vpn_ip4_props = value_hash_create ();
|
||||
vpn_ip6_props = value_hash_create ();
|
||||
g_variant_builder_init (&device_props, G_VARIANT_TYPE_VARDICT);
|
||||
g_variant_builder_init (&device_ip4_props, G_VARIANT_TYPE_VARDICT);
|
||||
g_variant_builder_init (&device_ip6_props, G_VARIANT_TYPE_VARDICT);
|
||||
g_variant_builder_init (&device_dhcp4_props, G_VARIANT_TYPE_VARDICT);
|
||||
g_variant_builder_init (&device_dhcp6_props, G_VARIANT_TYPE_VARDICT);
|
||||
g_variant_builder_init (&vpn_ip4_props, G_VARIANT_TYPE_VARDICT);
|
||||
g_variant_builder_init (&vpn_ip6_props, G_VARIANT_TYPE_VARDICT);
|
||||
|
||||
/* hostname actions only send the hostname */
|
||||
if (action != DISPATCHER_ACTION_HOSTNAME) {
|
||||
fill_device_props (device,
|
||||
device_props,
|
||||
device_ip4_props,
|
||||
device_ip6_props,
|
||||
device_dhcp4_props,
|
||||
device_dhcp6_props);
|
||||
if (vpn_ip4_config || vpn_ip6_config)
|
||||
fill_vpn_props (vpn_ip4_config, vpn_ip6_config, vpn_ip4_props, vpn_ip6_props);
|
||||
&device_props,
|
||||
&device_ip4_props,
|
||||
&device_ip6_props,
|
||||
&device_dhcp4_props,
|
||||
&device_dhcp6_props);
|
||||
if (vpn_ip4_config || vpn_ip6_config) {
|
||||
fill_vpn_props (vpn_ip4_config,
|
||||
vpn_ip6_config,
|
||||
&vpn_ip4_props,
|
||||
&vpn_ip6_props);
|
||||
}
|
||||
}
|
||||
|
||||
/* Send the action to the dispatcher */
|
||||
if (blocking) {
|
||||
GPtrArray *results = NULL;
|
||||
GVariant *ret;
|
||||
GVariantIter *results;
|
||||
|
||||
success = dbus_g_proxy_call_with_timeout (proxy, "Action",
|
||||
CALL_TIMEOUT,
|
||||
&error,
|
||||
G_TYPE_STRING, action_to_string (action),
|
||||
DBUS_TYPE_G_MAP_OF_MAP_OF_VARIANT, connection_hash,
|
||||
DBUS_TYPE_G_MAP_OF_VARIANT, connection_props,
|
||||
DBUS_TYPE_G_MAP_OF_VARIANT, device_props,
|
||||
DBUS_TYPE_G_MAP_OF_VARIANT, device_ip4_props,
|
||||
DBUS_TYPE_G_MAP_OF_VARIANT, device_ip6_props,
|
||||
DBUS_TYPE_G_MAP_OF_VARIANT, device_dhcp4_props,
|
||||
DBUS_TYPE_G_MAP_OF_VARIANT, device_dhcp6_props,
|
||||
G_TYPE_STRING, vpn_iface ? vpn_iface : "",
|
||||
DBUS_TYPE_G_MAP_OF_VARIANT, vpn_ip4_props,
|
||||
DBUS_TYPE_G_MAP_OF_VARIANT, vpn_ip6_props,
|
||||
G_TYPE_BOOLEAN, nm_logging_enabled (LOGL_DEBUG, LOGD_DISPATCH),
|
||||
G_TYPE_INVALID,
|
||||
DISPATCHER_TYPE_RESULT_ARRAY, &results,
|
||||
G_TYPE_INVALID);
|
||||
if (success) {
|
||||
ret = _nm_dbus_proxy_call_sync (dispatcher_proxy, "Action",
|
||||
g_variant_new ("(s@a{sa{sv}}a{sv}a{sv}a{sv}a{sv}a{sv}a{sv}sa{sv}a{sv}b)",
|
||||
action_to_string (action),
|
||||
connection_dict,
|
||||
&connection_props,
|
||||
&device_props,
|
||||
&device_ip4_props,
|
||||
&device_ip6_props,
|
||||
&device_dhcp4_props,
|
||||
&device_dhcp6_props,
|
||||
vpn_iface ? vpn_iface : "",
|
||||
&vpn_ip4_props,
|
||||
&vpn_ip6_props,
|
||||
nm_logging_enabled (LOGL_DEBUG, LOGD_DISPATCH)),
|
||||
G_VARIANT_TYPE ("(a(sus))"),
|
||||
G_DBUS_CALL_FLAGS_NONE, CALL_TIMEOUT,
|
||||
NULL, &error);
|
||||
if (ret) {
|
||||
g_variant_get (ret, "(a(sus))", &results);
|
||||
dispatcher_results_process (reqid, action, results);
|
||||
free_results (results);
|
||||
g_variant_iter_free (results);
|
||||
g_variant_unref (ret);
|
||||
success = TRUE;
|
||||
} else {
|
||||
nm_log_warn (LOGD_DISPATCH, "(%u) failed: (%d) %s", reqid, error->code, error->message);
|
||||
g_error_free (error);
|
||||
nm_log_warn (LOGD_DISPATCH, "(%u) failed: %s", reqid, error->message);
|
||||
g_clear_error (&error);
|
||||
success = FALSE;
|
||||
}
|
||||
} else {
|
||||
info = g_malloc0 (sizeof (*info));
|
||||
@@ -556,37 +634,25 @@ _dispatcher_call (DispatcherAction action,
|
||||
info->request_id = reqid;
|
||||
info->callback = callback;
|
||||
info->user_data = user_data;
|
||||
dbus_g_proxy_begin_call_with_timeout (proxy, "Action",
|
||||
dispatcher_done_cb,
|
||||
info,
|
||||
(GDestroyNotify) dispatcher_info_cleanup,
|
||||
CALL_TIMEOUT,
|
||||
G_TYPE_STRING, action_to_string (action),
|
||||
DBUS_TYPE_G_MAP_OF_MAP_OF_VARIANT, connection_hash,
|
||||
DBUS_TYPE_G_MAP_OF_VARIANT, connection_props,
|
||||
DBUS_TYPE_G_MAP_OF_VARIANT, device_props,
|
||||
DBUS_TYPE_G_MAP_OF_VARIANT, device_ip4_props,
|
||||
DBUS_TYPE_G_MAP_OF_VARIANT, device_ip6_props,
|
||||
DBUS_TYPE_G_MAP_OF_VARIANT, device_dhcp4_props,
|
||||
DBUS_TYPE_G_MAP_OF_VARIANT, device_dhcp6_props,
|
||||
G_TYPE_STRING, vpn_iface ? vpn_iface : "",
|
||||
DBUS_TYPE_G_MAP_OF_VARIANT, vpn_ip4_props,
|
||||
DBUS_TYPE_G_MAP_OF_VARIANT, vpn_ip6_props,
|
||||
G_TYPE_BOOLEAN, nm_logging_enabled (LOGL_DEBUG, LOGD_DISPATCH),
|
||||
G_TYPE_INVALID);
|
||||
g_dbus_proxy_call (dispatcher_proxy, "Action",
|
||||
g_variant_new ("(s@a{sa{sv}}a{sv}a{sv}a{sv}a{sv}a{sv}a{sv}sa{sv}a{sv}b)",
|
||||
action_to_string (action),
|
||||
connection_dict,
|
||||
&connection_props,
|
||||
&device_props,
|
||||
&device_ip4_props,
|
||||
&device_ip6_props,
|
||||
&device_dhcp4_props,
|
||||
&device_dhcp6_props,
|
||||
vpn_iface ? vpn_iface : "",
|
||||
&vpn_ip4_props,
|
||||
&vpn_ip6_props,
|
||||
nm_logging_enabled (LOGL_DEBUG, LOGD_DISPATCH)),
|
||||
G_DBUS_CALL_FLAGS_NONE, CALL_TIMEOUT,
|
||||
NULL, dispatcher_done_cb, info);
|
||||
success = TRUE;
|
||||
}
|
||||
|
||||
g_hash_table_destroy (connection_hash);
|
||||
g_hash_table_destroy (connection_props);
|
||||
g_hash_table_destroy (device_props);
|
||||
g_hash_table_destroy (device_ip4_props);
|
||||
g_hash_table_destroy (device_ip6_props);
|
||||
g_hash_table_destroy (device_dhcp4_props);
|
||||
g_hash_table_destroy (device_dhcp6_props);
|
||||
g_hash_table_destroy (vpn_ip4_props);
|
||||
g_hash_table_destroy (vpn_ip6_props);
|
||||
|
||||
done:
|
||||
if (success && info) {
|
||||
/* Track the request in case of cancelation */
|
||||
@@ -777,6 +843,7 @@ nm_dispatcher_init (void)
|
||||
{
|
||||
GFile *file;
|
||||
guint i;
|
||||
GError *error = NULL;
|
||||
|
||||
for (i = 0; i < G_N_ELEMENTS (monitors); i++) {
|
||||
file = g_file_new_for_path (monitors[i].dir);
|
||||
@@ -787,5 +854,18 @@ nm_dispatcher_init (void)
|
||||
}
|
||||
g_object_unref (file);
|
||||
}
|
||||
|
||||
dispatcher_proxy = g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SYSTEM,
|
||||
G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES |
|
||||
G_DBUS_PROXY_FLAGS_DO_NOT_CONNECT_SIGNALS,
|
||||
NULL,
|
||||
NM_DISPATCHER_DBUS_SERVICE,
|
||||
NM_DISPATCHER_DBUS_PATH,
|
||||
NM_DISPATCHER_DBUS_INTERFACE,
|
||||
NULL, &error);
|
||||
if (!dispatcher_proxy) {
|
||||
nm_log_err (LOGD_DISPATCH, "could not get dispatcher proxy! %s", error->message);
|
||||
g_clear_error (&error);
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -23,11 +23,10 @@
|
||||
#include <string.h>
|
||||
#include <glib.h>
|
||||
#include <gio/gio.h>
|
||||
#include <dbus/dbus.h>
|
||||
|
||||
#include "nm-firewall-manager.h"
|
||||
#include "nm-dbus-manager.h"
|
||||
#include "nm-logging.h"
|
||||
#include "gsystem-local-alloc.h"
|
||||
|
||||
#define NM_FIREWALL_MANAGER_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), \
|
||||
NM_TYPE_FIREWALL_MANAGER, \
|
||||
@@ -43,9 +42,7 @@ enum {
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
NMDBusManager * dbus_mgr;
|
||||
guint name_owner_id;
|
||||
DBusGProxy * proxy;
|
||||
GDBusProxy * proxy;
|
||||
gboolean running;
|
||||
|
||||
GSList *pending_calls;
|
||||
@@ -70,36 +67,50 @@ typedef struct {
|
||||
FwAddToZoneFunc callback;
|
||||
gpointer user_data;
|
||||
guint id;
|
||||
gboolean completed;
|
||||
|
||||
guint idle_id;
|
||||
DBusGProxyCall *dbus_call;
|
||||
GCancellable *cancellable;
|
||||
} CBInfo;
|
||||
|
||||
static void
|
||||
_cb_info_free (CBInfo *info)
|
||||
_cb_info_complete_and_free (CBInfo *info,
|
||||
const char *tag,
|
||||
const char *debug_error_match,
|
||||
GError *error)
|
||||
{
|
||||
NMFirewallManagerPrivate *priv;
|
||||
gs_free_error GError *local = NULL;
|
||||
|
||||
g_return_if_fail (info != NULL);
|
||||
g_return_if_fail (tag != NULL);
|
||||
|
||||
if (!info->completed) {
|
||||
nm_log_dbg (LOGD_FIREWALL, "(%s) firewall zone call cancelled [%u]", info->iface, info->id);
|
||||
if (info->callback) {
|
||||
GError *error;
|
||||
|
||||
error = g_error_new_literal (G_IO_ERROR, G_IO_ERROR_CANCELLED,
|
||||
"Operation was cancelled");
|
||||
info->callback (error, info->user_data);
|
||||
g_error_free (error);
|
||||
}
|
||||
/* A cancelled idle call won't set the error; catch that here */
|
||||
if (!error && g_cancellable_is_cancelled (info->cancellable)) {
|
||||
error = local = g_error_new_literal (G_IO_ERROR, G_IO_ERROR_CANCELLED,
|
||||
"Operation was cancelled");
|
||||
}
|
||||
|
||||
if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) {
|
||||
nm_log_dbg (LOGD_FIREWALL, "(%s) firewall zone %s call cancelled [%u]",
|
||||
info->iface, tag, info->id);
|
||||
} else if (error) {
|
||||
g_dbus_error_strip_remote_error (error);
|
||||
if (!g_strcmp0 (error->message, debug_error_match)) {
|
||||
nm_log_dbg (LOGD_FIREWALL, "(%s) firewall zone %s failed [%u]: %s",
|
||||
info->iface, tag, info->id, error->message);
|
||||
} else {
|
||||
nm_log_warn (LOGD_FIREWALL, "(%s) firewall zone %s failed [%u]: %s",
|
||||
info->iface, tag, info->id, error->message);
|
||||
}
|
||||
} else {
|
||||
nm_log_dbg (LOGD_FIREWALL, "(%s) firewall zone %s succeeded [%u]",
|
||||
info->iface, tag, info->id);
|
||||
}
|
||||
|
||||
if (info->callback)
|
||||
info->callback (error, info->user_data);
|
||||
|
||||
g_free (info->iface);
|
||||
|
||||
priv = NM_FIREWALL_MANAGER_GET_PRIVATE (info->self);
|
||||
priv->pending_calls = g_slist_remove (priv->pending_calls, info);
|
||||
g_object_unref (info->self);
|
||||
|
||||
g_object_unref (info->cancellable);
|
||||
g_slice_free (CBInfo, info);
|
||||
}
|
||||
|
||||
@@ -107,16 +118,14 @@ static CBInfo *
|
||||
_cb_info_create (NMFirewallManager *self, const char *iface, FwAddToZoneFunc callback, gpointer user_data)
|
||||
{
|
||||
NMFirewallManagerPrivate *priv = NM_FIREWALL_MANAGER_GET_PRIVATE (self);
|
||||
static guint id;
|
||||
static guint id = 1;
|
||||
CBInfo *info;
|
||||
|
||||
info = g_slice_new0 (CBInfo);
|
||||
if (++id == 0)
|
||||
++id;
|
||||
info->self = g_object_ref (self);
|
||||
info->id = id;
|
||||
info->id = id++;
|
||||
info->iface = g_strdup (iface);
|
||||
info->completed = FALSE;
|
||||
info->cancellable = g_cancellable_new ();
|
||||
info->callback = callback;
|
||||
info->user_data = user_data;
|
||||
|
||||
@@ -129,50 +138,20 @@ add_or_change_idle_cb (gpointer user_data)
|
||||
{
|
||||
CBInfo *info = user_data;
|
||||
|
||||
if (info->idle_id == 0) {
|
||||
/* operation was cancelled. _cb_info_free will invoke callback. */
|
||||
} else {
|
||||
nm_log_dbg (LOGD_FIREWALL, "(%s) firewall zone call pretends success [%u]",
|
||||
info->iface, info->id);
|
||||
if (info->callback)
|
||||
info->callback (NULL, info->user_data);
|
||||
info->completed = TRUE;
|
||||
info->idle_id = 0;
|
||||
}
|
||||
|
||||
_cb_info_free (info);
|
||||
info->idle_id = 0;
|
||||
_cb_info_complete_and_free (info, "idle call", NULL, NULL);
|
||||
return G_SOURCE_REMOVE;
|
||||
}
|
||||
|
||||
static void
|
||||
add_or_change_cb (DBusGProxy *proxy, DBusGProxyCall *call_id, gpointer user_data)
|
||||
add_or_change_cb (GObject *proxy, GAsyncResult *result, gpointer user_data)
|
||||
{
|
||||
CBInfo *info = user_data;
|
||||
GError *error = NULL;
|
||||
char *zone = NULL;
|
||||
gs_free_error GError *error = NULL;
|
||||
gs_unref_variant GVariant *ret = NULL;
|
||||
|
||||
if (!dbus_g_proxy_end_call (proxy, call_id, &error,
|
||||
G_TYPE_STRING, &zone,
|
||||
G_TYPE_INVALID)) {
|
||||
g_assert (error);
|
||||
if (g_strcmp0 (error->message, "ZONE_ALREADY_SET") != 0) {
|
||||
nm_log_warn (LOGD_FIREWALL, "(%s) firewall zone add/change failed [%u]: (%d) %s",
|
||||
info->iface, info->id, error->code, error->message);
|
||||
} else {
|
||||
nm_log_dbg (LOGD_FIREWALL, "(%s) firewall zone add/change failed [%u]: (%d) %s",
|
||||
info->iface, info->id, error->code, error->message);
|
||||
}
|
||||
} else {
|
||||
nm_log_dbg (LOGD_FIREWALL, "(%s) firewall zone add/change succeeded [%u]",
|
||||
info->iface, info->id);
|
||||
}
|
||||
|
||||
if (info->callback)
|
||||
info->callback (error, info->user_data);
|
||||
|
||||
info->completed = TRUE;
|
||||
g_free (zone);
|
||||
g_clear_error (&error);
|
||||
ret = g_dbus_proxy_call_finish (G_DBUS_PROXY (proxy), result, &error);
|
||||
_cb_info_complete_and_free (info, "add/change", "ZONE_ALREADY_SET", error);
|
||||
}
|
||||
|
||||
NMFirewallPendingCall
|
||||
@@ -203,45 +182,24 @@ nm_firewall_manager_add_or_change_zone (NMFirewallManager *self,
|
||||
|
||||
nm_log_dbg (LOGD_FIREWALL, "(%s) firewall zone %s -> %s%s%s [%u]", iface, add ? "add" : "change",
|
||||
zone?"\"":"", zone ? zone : "default", zone?"\"":"", info->id);
|
||||
info->dbus_call = dbus_g_proxy_begin_call_with_timeout (priv->proxy,
|
||||
add ? "addInterface" : "changeZone",
|
||||
add_or_change_cb,
|
||||
info,
|
||||
(GDestroyNotify) _cb_info_free,
|
||||
10000, /* timeout */
|
||||
G_TYPE_STRING, zone ? zone : "",
|
||||
G_TYPE_STRING, iface,
|
||||
G_TYPE_INVALID);
|
||||
return PENDING_CALL_FROM_INFO (info);
|
||||
g_dbus_proxy_call (priv->proxy,
|
||||
add ? "addInterface" : "changeZone",
|
||||
g_variant_new ("(ss)", zone ? zone : "", iface),
|
||||
G_DBUS_CALL_FLAGS_NONE, 10000,
|
||||
info->cancellable,
|
||||
add_or_change_cb, info);
|
||||
return (NMFirewallPendingCall) info;
|
||||
}
|
||||
|
||||
static void
|
||||
remove_cb (DBusGProxy *proxy, DBusGProxyCall *call_id, gpointer user_data)
|
||||
remove_cb (GObject *proxy, GAsyncResult *result, gpointer user_data)
|
||||
{
|
||||
CBInfo *info = user_data;
|
||||
GError *error = NULL;
|
||||
char * zone = NULL;
|
||||
gs_free_error GError *error = NULL;
|
||||
gs_unref_variant GVariant *ret = NULL;
|
||||
|
||||
if (!dbus_g_proxy_end_call (proxy, call_id, &error,
|
||||
G_TYPE_STRING, &zone,
|
||||
G_TYPE_INVALID)) {
|
||||
g_assert (error);
|
||||
/* ignore UNKNOWN_INTERFACE errors */
|
||||
if (error->message && !strstr (error->message, "UNKNOWN_INTERFACE")) {
|
||||
nm_log_warn (LOGD_FIREWALL, "(%s) firewall zone remove failed [%u]: (%d) %s",
|
||||
info->iface, info->id, error->code, error->message);
|
||||
} else {
|
||||
nm_log_dbg (LOGD_FIREWALL, "(%s) firewall zone remove failed [%u]: (%d) %s",
|
||||
info->iface, info->id, error->code, error->message);
|
||||
}
|
||||
} else {
|
||||
nm_log_dbg (LOGD_FIREWALL, "(%s) firewall zone remove succeeded [%u]",
|
||||
info->iface, info->id);
|
||||
}
|
||||
|
||||
info->completed = TRUE;
|
||||
g_free (zone);
|
||||
g_clear_error (&error);
|
||||
ret = g_dbus_proxy_call_finish (G_DBUS_PROXY (proxy), result, &error);
|
||||
_cb_info_complete_and_free (info, "remove", "UNKNOWN_INTERFACE", error);
|
||||
}
|
||||
|
||||
NMFirewallPendingCall
|
||||
@@ -261,42 +219,25 @@ nm_firewall_manager_remove_from_zone (NMFirewallManager *self,
|
||||
|
||||
nm_log_dbg (LOGD_FIREWALL, "(%s) firewall zone remove -> %s%s%s [%u]", iface,
|
||||
zone?"\"":"", zone ? zone : "*", zone?"\"":"", info->id);
|
||||
info->dbus_call = dbus_g_proxy_begin_call_with_timeout (priv->proxy,
|
||||
"removeInterface",
|
||||
remove_cb,
|
||||
info,
|
||||
(GDestroyNotify) _cb_info_free,
|
||||
10000, /* timeout */
|
||||
G_TYPE_STRING, zone ? zone : "",
|
||||
G_TYPE_STRING, iface,
|
||||
G_TYPE_INVALID);
|
||||
return PENDING_CALL_FROM_INFO (info);
|
||||
g_dbus_proxy_call (priv->proxy,
|
||||
"removeInterface",
|
||||
g_variant_new ("(ss)", zone ? zone : "", iface),
|
||||
G_DBUS_CALL_FLAGS_NONE, 10000,
|
||||
info->cancellable,
|
||||
remove_cb, info);
|
||||
return (NMFirewallPendingCall) info;
|
||||
}
|
||||
|
||||
void nm_firewall_manager_cancel_call (NMFirewallManager *self, NMFirewallPendingCall call)
|
||||
void
|
||||
nm_firewall_manager_cancel_call (NMFirewallManager *self, NMFirewallPendingCall call)
|
||||
{
|
||||
NMFirewallManagerPrivate *priv = NM_FIREWALL_MANAGER_GET_PRIVATE (self);
|
||||
GSList *pending;
|
||||
CBInfo *info;
|
||||
CBInfo *info = (CBInfo *) call;
|
||||
|
||||
g_return_if_fail (NM_IS_FIREWALL_MANAGER (self));
|
||||
|
||||
if (call == PENDING_CALL_DUMMY)
|
||||
return;
|
||||
|
||||
pending = g_slist_find (priv->pending_calls, call);
|
||||
|
||||
if (!pending)
|
||||
return;
|
||||
priv->pending_calls = g_slist_remove_link (priv->pending_calls, pending);
|
||||
|
||||
info = (CBInfo *) call;
|
||||
if (info->idle_id)
|
||||
info->idle_id = 0;
|
||||
else {
|
||||
dbus_g_proxy_cancel_call (NM_FIREWALL_MANAGER_GET_PRIVATE (self)->proxy,
|
||||
info->dbus_call);
|
||||
}
|
||||
info->callback = NULL;
|
||||
info->idle_id = 0;
|
||||
g_cancellable_cancel (info->cancellable);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -311,25 +252,19 @@ set_running (NMFirewallManager *self, gboolean now_running)
|
||||
}
|
||||
|
||||
static void
|
||||
name_owner_changed (NMDBusManager *dbus_mgr,
|
||||
const char *name,
|
||||
const char *old_owner,
|
||||
const char *new_owner,
|
||||
gpointer user_data)
|
||||
name_owner_changed (GObject *object,
|
||||
GParamSpec *pspec,
|
||||
gpointer user_data)
|
||||
{
|
||||
NMFirewallManager *self = NM_FIREWALL_MANAGER (user_data);
|
||||
gboolean old_owner_good = (old_owner && strlen (old_owner));
|
||||
gboolean new_owner_good = (new_owner && strlen (new_owner));
|
||||
gs_free char *owner = NULL;
|
||||
|
||||
/* We only care about the firewall here */
|
||||
if (strcmp (FIREWALL_DBUS_SERVICE, name) != 0)
|
||||
return;
|
||||
|
||||
if (!old_owner_good && new_owner_good) {
|
||||
owner = g_dbus_proxy_get_name_owner (G_DBUS_PROXY (object));
|
||||
if (owner) {
|
||||
nm_log_dbg (LOGD_FIREWALL, "firewall started");
|
||||
set_running (self, TRUE);
|
||||
g_signal_emit (self, signals[STARTED], 0);
|
||||
} else if (old_owner_good && !new_owner_good) {
|
||||
} else {
|
||||
nm_log_dbg (LOGD_FIREWALL, "firewall stopped");
|
||||
set_running (self, FALSE);
|
||||
}
|
||||
@@ -343,21 +278,23 @@ static void
|
||||
nm_firewall_manager_init (NMFirewallManager * self)
|
||||
{
|
||||
NMFirewallManagerPrivate *priv = NM_FIREWALL_MANAGER_GET_PRIVATE (self);
|
||||
DBusGConnection *bus;
|
||||
gs_free char *owner = NULL;
|
||||
|
||||
priv->dbus_mgr = g_object_ref (nm_dbus_manager_get ());
|
||||
priv->name_owner_id = g_signal_connect (priv->dbus_mgr,
|
||||
NM_DBUS_MANAGER_NAME_OWNER_CHANGED,
|
||||
G_CALLBACK (name_owner_changed),
|
||||
self);
|
||||
priv->running = nm_dbus_manager_name_has_owner (priv->dbus_mgr, FIREWALL_DBUS_SERVICE);
|
||||
priv->proxy = g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SYSTEM,
|
||||
G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES |
|
||||
G_DBUS_PROXY_FLAGS_DO_NOT_CONNECT_SIGNALS,
|
||||
NULL,
|
||||
FIREWALL_DBUS_SERVICE,
|
||||
FIREWALL_DBUS_PATH,
|
||||
FIREWALL_DBUS_INTERFACE_ZONE,
|
||||
NULL, NULL);
|
||||
|
||||
g_signal_connect (priv->proxy, "notify::g-name-owner",
|
||||
G_CALLBACK (name_owner_changed), self);
|
||||
owner = g_dbus_proxy_get_name_owner (priv->proxy);
|
||||
priv->running = (owner != NULL);
|
||||
nm_log_dbg (LOGD_FIREWALL, "firewall %s running", priv->running ? "is" : "is not" );
|
||||
|
||||
bus = nm_dbus_manager_get_connection (priv->dbus_mgr);
|
||||
priv->proxy = dbus_g_proxy_new_for_name (bus,
|
||||
FIREWALL_DBUS_SERVICE,
|
||||
FIREWALL_DBUS_PATH,
|
||||
FIREWALL_DBUS_INTERFACE_ZONE);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -386,12 +323,6 @@ dispose (GObject *object)
|
||||
|
||||
g_assert (priv->pending_calls == NULL);
|
||||
|
||||
if (priv->dbus_mgr) {
|
||||
g_signal_handler_disconnect (priv->dbus_mgr, priv->name_owner_id);
|
||||
priv->name_owner_id = 0;
|
||||
g_clear_object (&priv->dbus_mgr);
|
||||
}
|
||||
|
||||
g_clear_object (&priv->proxy);
|
||||
|
||||
/* Chain up to the parent class */
|
||||
|
@@ -190,7 +190,7 @@ typedef struct {
|
||||
|
||||
NMVpnManager *vpn_manager;
|
||||
|
||||
DBusGProxy *aipd_proxy;
|
||||
GDBusProxy *aipd_proxy;
|
||||
NMSleepMonitor *sleep_monitor;
|
||||
|
||||
GSList *auth_chains;
|
||||
@@ -801,7 +801,7 @@ device_removed_cb (NMDevice *device, gpointer user_data)
|
||||
}
|
||||
|
||||
static void
|
||||
aipd_handle_event (DBusGProxy *proxy,
|
||||
aipd_handle_event (GDBusProxy *proxy,
|
||||
const char *event,
|
||||
const char *iface,
|
||||
const char *address,
|
||||
@@ -812,11 +812,6 @@ aipd_handle_event (DBusGProxy *proxy,
|
||||
GSList *iter;
|
||||
gboolean handled = FALSE;
|
||||
|
||||
if (!event || !iface) {
|
||||
nm_log_warn (LOGD_AUTOIP4, "incomplete message received from avahi-autoipd");
|
||||
return;
|
||||
}
|
||||
|
||||
if ( (strcmp (event, "BIND") != 0)
|
||||
&& (strcmp (event, "CONFLICT") != 0)
|
||||
&& (strcmp (event, "UNBIND") != 0)
|
||||
@@ -3865,14 +3860,14 @@ impl_manager_sleep (NMManager *self,
|
||||
}
|
||||
|
||||
static void
|
||||
sleeping_cb (DBusGProxy *proxy, gpointer user_data)
|
||||
sleeping_cb (NMSleepMonitor *monitor, gpointer user_data)
|
||||
{
|
||||
nm_log_dbg (LOGD_SUSPEND, "Received sleeping signal");
|
||||
_internal_sleep (NM_MANAGER (user_data), TRUE);
|
||||
}
|
||||
|
||||
static void
|
||||
resuming_cb (DBusGProxy *proxy, gpointer user_data)
|
||||
resuming_cb (NMSleepMonitor *monitor, gpointer user_data)
|
||||
{
|
||||
nm_log_dbg (LOGD_SUSPEND, "Received resuming signal");
|
||||
_internal_sleep (NM_MANAGER (user_data), FALSE);
|
||||
@@ -4870,9 +4865,9 @@ static void
|
||||
nm_manager_init (NMManager *manager)
|
||||
{
|
||||
NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (manager);
|
||||
DBusGConnection *g_connection;
|
||||
guint i;
|
||||
GFile *file;
|
||||
GError *error = NULL;
|
||||
|
||||
/* Initialize rfkill structures and states */
|
||||
memset (priv->radio_states, 0, sizeof (priv->radio_states));
|
||||
@@ -4913,30 +4908,22 @@ nm_manager_init (NMManager *manager)
|
||||
|
||||
priv->vpn_manager = g_object_ref (nm_vpn_manager_get ());
|
||||
|
||||
g_connection = nm_dbus_manager_get_connection (priv->dbus_mgr);
|
||||
|
||||
/* avahi-autoipd stuff */
|
||||
priv->aipd_proxy = dbus_g_proxy_new_for_name (g_connection,
|
||||
NM_AUTOIP_DBUS_SERVICE,
|
||||
"/",
|
||||
NM_AUTOIP_DBUS_IFACE);
|
||||
priv->aipd_proxy = g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SYSTEM,
|
||||
G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES,
|
||||
NULL,
|
||||
NM_AUTOIP_DBUS_SERVICE,
|
||||
"/",
|
||||
NM_AUTOIP_DBUS_IFACE,
|
||||
NULL, &error);
|
||||
if (priv->aipd_proxy) {
|
||||
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->aipd_proxy,
|
||||
"Event",
|
||||
G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING,
|
||||
G_TYPE_INVALID);
|
||||
|
||||
dbus_g_proxy_connect_signal (priv->aipd_proxy, "Event",
|
||||
G_CALLBACK (aipd_handle_event),
|
||||
manager,
|
||||
NULL);
|
||||
} else
|
||||
nm_log_warn (LOGD_AUTOIP4, "could not initialize avahi-autoipd D-Bus proxy");
|
||||
_nm_dbus_signal_connect (priv->aipd_proxy, "Event", G_VARIANT_TYPE ("(sss)"),
|
||||
G_CALLBACK (aipd_handle_event), manager);
|
||||
} else {
|
||||
nm_log_warn (LOGD_AUTOIP4, "could not initialize avahi-autoipd D-Bus proxy: %s",
|
||||
error->message);
|
||||
g_clear_error (&error);
|
||||
}
|
||||
|
||||
/* sleep/wake handling */
|
||||
priv->sleep_monitor = g_object_ref (nm_sleep_monitor_get ());
|
||||
|
@@ -28,6 +28,7 @@
|
||||
|
||||
#include "nm-logging.h"
|
||||
#include "nm-dbus-manager.h"
|
||||
#include "nm-core-internal.h"
|
||||
|
||||
#include "nm-sleep-monitor.h"
|
||||
|
||||
@@ -123,19 +124,12 @@ take_inhibitor (NMSleepMonitor *self)
|
||||
}
|
||||
|
||||
static void
|
||||
signal_cb (GDBusProxy *proxy,
|
||||
const gchar *sendername,
|
||||
const gchar *signalname,
|
||||
GVariant *args,
|
||||
gpointer data)
|
||||
prepare_for_sleep_cb (GDBusProxy *proxy,
|
||||
gboolean is_about_to_suspend,
|
||||
gpointer data)
|
||||
{
|
||||
NMSleepMonitor *self = data;
|
||||
gboolean is_about_to_suspend;
|
||||
|
||||
if (strcmp (signalname, "PrepareForSleep") != 0)
|
||||
return;
|
||||
|
||||
g_variant_get (args, "(b)", &is_about_to_suspend);
|
||||
nm_log_dbg (LOGD_SUSPEND, "Received PrepareForSleep signal: %d", is_about_to_suspend);
|
||||
|
||||
if (is_about_to_suspend) {
|
||||
@@ -182,7 +176,8 @@ on_proxy_acquired (GObject *object,
|
||||
}
|
||||
|
||||
g_signal_connect (self->sd_proxy, "notify::g-name-owner", G_CALLBACK (name_owner_cb), self);
|
||||
g_signal_connect (self->sd_proxy, "g-signal", G_CALLBACK (signal_cb), self);
|
||||
_nm_dbus_signal_connect (self->sd_proxy, "PrepareForSleep", G_VARIANT_TYPE ("(b)"),
|
||||
G_CALLBACK (prepare_for_sleep_cb), self);
|
||||
|
||||
owner = g_dbus_proxy_get_name_owner (self->sd_proxy);
|
||||
if (owner)
|
||||
|
@@ -22,33 +22,32 @@
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <sys/stat.h>
|
||||
#include <dbus/dbus-glib.h>
|
||||
#include <gio/gio.h>
|
||||
#include "nm-logging.h"
|
||||
#include "nm-dbus-manager.h"
|
||||
#include "nm-core-internal.h"
|
||||
|
||||
#include "nm-sleep-monitor.h"
|
||||
|
||||
#define UPOWER_DBUS_SERVICE "org.freedesktop.UPower"
|
||||
|
||||
struct _NMSleepMonitor {
|
||||
GObject parent_instance;
|
||||
GObject parent_instance;
|
||||
|
||||
DBusGProxy *upower_proxy;
|
||||
GDBusProxy *upower_proxy;
|
||||
};
|
||||
|
||||
struct _NMSleepMonitorClass {
|
||||
GObjectClass parent_class;
|
||||
GObjectClass parent_class;
|
||||
|
||||
void (*sleeping) (NMSleepMonitor *monitor);
|
||||
void (*resuming) (NMSleepMonitor *monitor);
|
||||
void (*sleeping) (NMSleepMonitor *monitor);
|
||||
void (*resuming) (NMSleepMonitor *monitor);
|
||||
};
|
||||
|
||||
|
||||
enum {
|
||||
SLEEPING,
|
||||
RESUMING,
|
||||
LAST_SIGNAL,
|
||||
SLEEPING,
|
||||
RESUMING,
|
||||
LAST_SIGNAL,
|
||||
};
|
||||
static guint signals[LAST_SIGNAL] = {0};
|
||||
|
||||
@@ -57,80 +56,78 @@ G_DEFINE_TYPE (NMSleepMonitor, nm_sleep_monitor, G_TYPE_OBJECT);
|
||||
/********************************************************************/
|
||||
|
||||
static void
|
||||
upower_sleeping_cb (DBusGProxy *proxy, gpointer user_data)
|
||||
upower_sleeping_cb (GDBusProxy *proxy, gpointer user_data)
|
||||
{
|
||||
nm_log_dbg (LOGD_SUSPEND, "Received UPower sleeping signal");
|
||||
g_signal_emit (user_data, signals[SLEEPING], 0);
|
||||
nm_log_dbg (LOGD_SUSPEND, "Received UPower sleeping signal");
|
||||
g_signal_emit (user_data, signals[SLEEPING], 0);
|
||||
}
|
||||
|
||||
static void
|
||||
upower_resuming_cb (DBusGProxy *proxy, gpointer user_data)
|
||||
upower_resuming_cb (GDBusProxy *proxy, gpointer user_data)
|
||||
{
|
||||
nm_log_dbg (LOGD_SUSPEND, "Received UPower resuming signal");
|
||||
g_signal_emit (user_data, signals[RESUMING], 0);
|
||||
nm_log_dbg (LOGD_SUSPEND, "Received UPower resuming signal");
|
||||
g_signal_emit (user_data, signals[RESUMING], 0);
|
||||
}
|
||||
|
||||
static void
|
||||
nm_sleep_monitor_init (NMSleepMonitor *self)
|
||||
{
|
||||
DBusGConnection *bus;
|
||||
GError *error = NULL;
|
||||
|
||||
bus = nm_dbus_manager_get_connection (nm_dbus_manager_get ());
|
||||
self->upower_proxy = dbus_g_proxy_new_for_name (bus,
|
||||
UPOWER_DBUS_SERVICE,
|
||||
"/org/freedesktop/UPower",
|
||||
"org.freedesktop.UPower");
|
||||
if (self->upower_proxy) {
|
||||
dbus_g_proxy_add_signal (self->upower_proxy, "Sleeping", G_TYPE_INVALID);
|
||||
dbus_g_proxy_connect_signal (self->upower_proxy, "Sleeping",
|
||||
G_CALLBACK (upower_sleeping_cb),
|
||||
self, NULL);
|
||||
|
||||
dbus_g_proxy_add_signal (self->upower_proxy, "Resuming", G_TYPE_INVALID);
|
||||
dbus_g_proxy_connect_signal (self->upower_proxy, "Resuming",
|
||||
G_CALLBACK (upower_resuming_cb),
|
||||
self, NULL);
|
||||
} else
|
||||
nm_log_warn (LOGD_SUSPEND, "could not initialize UPower D-Bus proxy");
|
||||
self->upower_proxy = g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SYSTEM,
|
||||
G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START |
|
||||
G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES,
|
||||
NULL,
|
||||
UPOWER_DBUS_SERVICE,
|
||||
"/org/freedesktop/UPower",
|
||||
"org.freedesktop.UPower",
|
||||
NULL, &error);
|
||||
if (self->upower_proxy) {
|
||||
_nm_dbus_signal_connect (self->upower_proxy, "Sleeping", NULL,
|
||||
G_CALLBACK (upower_sleeping_cb), self);
|
||||
_nm_dbus_signal_connect (self->upower_proxy, "Resuming", NULL,
|
||||
G_CALLBACK (upower_resuming_cb), self);
|
||||
} else {
|
||||
nm_log_warn (LOGD_SUSPEND, "could not initialize UPower D-Bus proxy: %s", error->message);
|
||||
g_error_free (error);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
finalize (GObject *object)
|
||||
{
|
||||
NMSleepMonitor *self = NM_SLEEP_MONITOR (object);
|
||||
NMSleepMonitor *self = NM_SLEEP_MONITOR (object);
|
||||
|
||||
if (self->upower_proxy)
|
||||
g_object_unref (self->upower_proxy);
|
||||
g_clear_object (&self->upower_proxy);
|
||||
|
||||
if (G_OBJECT_CLASS (nm_sleep_monitor_parent_class)->finalize != NULL)
|
||||
G_OBJECT_CLASS (nm_sleep_monitor_parent_class)->finalize (object);
|
||||
G_OBJECT_CLASS (nm_sleep_monitor_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
nm_sleep_monitor_class_init (NMSleepMonitorClass *klass)
|
||||
{
|
||||
GObjectClass *gobject_class;
|
||||
GObjectClass *gobject_class;
|
||||
|
||||
gobject_class = G_OBJECT_CLASS (klass);
|
||||
gobject_class = G_OBJECT_CLASS (klass);
|
||||
|
||||
gobject_class->finalize = finalize;
|
||||
gobject_class->finalize = finalize;
|
||||
|
||||
signals[SLEEPING] = g_signal_new (NM_SLEEP_MONITOR_SLEEPING,
|
||||
NM_TYPE_SLEEP_MONITOR,
|
||||
G_SIGNAL_RUN_LAST,
|
||||
G_STRUCT_OFFSET (NMSleepMonitorClass, sleeping),
|
||||
NULL, /* accumulator */
|
||||
NULL, /* accumulator data */
|
||||
g_cclosure_marshal_VOID__VOID,
|
||||
G_TYPE_NONE, 0);
|
||||
signals[RESUMING] = g_signal_new (NM_SLEEP_MONITOR_RESUMING,
|
||||
NM_TYPE_SLEEP_MONITOR,
|
||||
G_SIGNAL_RUN_LAST,
|
||||
G_STRUCT_OFFSET (NMSleepMonitorClass, resuming),
|
||||
NULL, /* accumulator */
|
||||
NULL, /* accumulator data */
|
||||
g_cclosure_marshal_VOID__VOID,
|
||||
G_TYPE_NONE, 0);
|
||||
signals[SLEEPING] = g_signal_new (NM_SLEEP_MONITOR_SLEEPING,
|
||||
NM_TYPE_SLEEP_MONITOR,
|
||||
G_SIGNAL_RUN_LAST,
|
||||
G_STRUCT_OFFSET (NMSleepMonitorClass, sleeping),
|
||||
NULL, /* accumulator */
|
||||
NULL, /* accumulator data */
|
||||
g_cclosure_marshal_VOID__VOID,
|
||||
G_TYPE_NONE, 0);
|
||||
signals[RESUMING] = g_signal_new (NM_SLEEP_MONITOR_RESUMING,
|
||||
NM_TYPE_SLEEP_MONITOR,
|
||||
G_SIGNAL_RUN_LAST,
|
||||
G_STRUCT_OFFSET (NMSleepMonitorClass, resuming),
|
||||
NULL, /* accumulator */
|
||||
NULL, /* accumulator data */
|
||||
g_cclosure_marshal_VOID__VOID,
|
||||
G_TYPE_NONE, 0);
|
||||
}
|
||||
|
||||
NM_DEFINE_SINGLETON_GETTER (NMSleepMonitor, nm_sleep_monitor_get, NM_TYPE_SLEEP_MONITOR);
|
||||
|
@@ -404,19 +404,6 @@ nm_supplicant_interface_credentials_reply (NMSupplicantInterface *self,
|
||||
return !!reply;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
_dbus_error_has_name (GError *error, const char *dbus_error_name)
|
||||
{
|
||||
gs_free char *error_name = NULL;
|
||||
gboolean is_error = FALSE;
|
||||
|
||||
if (error && g_dbus_error_is_remote_error (error)) {
|
||||
error_name = g_dbus_error_get_remote_error (error);
|
||||
is_error = !g_strcmp0 (error_name, dbus_error_name);
|
||||
}
|
||||
return is_error;
|
||||
}
|
||||
|
||||
static void
|
||||
iface_check_netreply_cb (GDBusProxy *proxy, GAsyncResult *result, gpointer user_data)
|
||||
{
|
||||
@@ -439,7 +426,7 @@ iface_check_netreply_cb (GDBusProxy *proxy, GAsyncResult *result, gpointer user_
|
||||
self = NM_SUPPLICANT_INTERFACE (user_data);
|
||||
priv = NM_SUPPLICANT_INTERFACE_GET_PRIVATE (self);
|
||||
|
||||
if (variant || _dbus_error_has_name (error, "fi.w1.wpa_supplicant1.InvalidArgs"))
|
||||
if (variant || _nm_dbus_error_has_name (error, "fi.w1.wpa_supplicant1.InvalidArgs"))
|
||||
priv->has_credreq = TRUE;
|
||||
|
||||
nm_log_dbg (LOGD_SUPPLICANT, "Supplicant %s network credentials requests",
|
||||
@@ -477,14 +464,16 @@ iface_check_ap_mode_cb (GDBusProxy *proxy, GAsyncResult *result, gpointer user_d
|
||||
const char *data;
|
||||
|
||||
/* The ProbeRequest method only exists if AP mode has been enabled */
|
||||
variant = g_dbus_proxy_call_finish (proxy, result, &error);
|
||||
variant = _nm_dbus_proxy_call_finish (proxy, result,
|
||||
G_VARIANT_TYPE ("(s)"),
|
||||
&error);
|
||||
if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
|
||||
return;
|
||||
|
||||
self = NM_SUPPLICANT_INTERFACE (user_data);
|
||||
priv = NM_SUPPLICANT_INTERFACE_GET_PRIVATE (self);
|
||||
|
||||
if (variant && g_variant_is_of_type (variant, G_VARIANT_TYPE ("(s)"))) {
|
||||
if (variant) {
|
||||
g_variant_get (variant, "(&s)", &data);
|
||||
if (strstr (data, "ProbeRequest"))
|
||||
priv->ap_support = AP_SUPPORT_YES;
|
||||
@@ -493,41 +482,59 @@ iface_check_ap_mode_cb (GDBusProxy *proxy, GAsyncResult *result, gpointer user_d
|
||||
iface_check_ready (self);
|
||||
}
|
||||
|
||||
#define MATCH_SIGNAL(s, n, v, t) (!strcmp (s, n) && g_variant_is_of_type (v, t))
|
||||
|
||||
static void
|
||||
signal_cb (GDBusProxy *proxy,
|
||||
const gchar *sender,
|
||||
const gchar *signal,
|
||||
GVariant *args,
|
||||
gpointer user_data)
|
||||
wpas_iface_scan_done (GDBusProxy *proxy,
|
||||
gboolean success,
|
||||
gpointer user_data)
|
||||
{
|
||||
NMSupplicantInterface *self = NM_SUPPLICANT_INTERFACE (user_data);
|
||||
NMSupplicantInterfacePrivate *priv = NM_SUPPLICANT_INTERFACE_GET_PRIVATE (self);
|
||||
const char *path, *field, *message;
|
||||
gboolean success;
|
||||
|
||||
if (MATCH_SIGNAL (signal, "ScanDone", args, G_VARIANT_TYPE ("(b)"))) {
|
||||
/* Cache last scan completed time */
|
||||
/* Cache last scan completed time */
|
||||
priv->last_scan = nm_utils_get_monotonic_timestamp_s ();
|
||||
|
||||
g_signal_emit (self, signals[SCAN_DONE], 0, success);
|
||||
}
|
||||
|
||||
static void
|
||||
wpas_iface_bss_added (GDBusProxy *proxy,
|
||||
const char *path,
|
||||
GVariant *props,
|
||||
gpointer user_data)
|
||||
{
|
||||
NMSupplicantInterface *self = NM_SUPPLICANT_INTERFACE (user_data);
|
||||
NMSupplicantInterfacePrivate *priv = NM_SUPPLICANT_INTERFACE_GET_PRIVATE (self);
|
||||
|
||||
if (priv->scanning)
|
||||
priv->last_scan = nm_utils_get_monotonic_timestamp_s ();
|
||||
|
||||
g_variant_get (args, "(b)", &success);
|
||||
g_signal_emit (self, signals[SCAN_DONE], 0, success);
|
||||
} else if (MATCH_SIGNAL (signal, "BSSAdded", args, G_VARIANT_TYPE ("(oa{sv})"))) {
|
||||
if (priv->scanning)
|
||||
priv->last_scan = nm_utils_get_monotonic_timestamp_s ();
|
||||
handle_new_bss (self, path);
|
||||
}
|
||||
|
||||
g_variant_get (args, "(&oa{sv})", &path, NULL);
|
||||
handle_new_bss (self, path);
|
||||
} else if (MATCH_SIGNAL (signal, "BSSRemoved", args, G_VARIANT_TYPE ("(o)"))) {
|
||||
g_variant_get (args, "(&o)", &path);
|
||||
g_signal_emit (self, signals[BSS_REMOVED], 0, path);
|
||||
g_hash_table_remove (priv->bss_proxies, path);
|
||||
} else if (MATCH_SIGNAL (signal, "NetworkRequest", args, G_VARIANT_TYPE ("(oss)"))) {
|
||||
g_variant_get (args, "(&o&s&s)", &path, &field, &message);
|
||||
if (priv->has_credreq && priv->net_path && !g_strcmp0 (path, priv->net_path))
|
||||
g_signal_emit (self, signals[CREDENTIALS_REQUEST], 0, field, message);
|
||||
}
|
||||
static void
|
||||
wpas_iface_bss_removed (GDBusProxy *proxy,
|
||||
const char *path,
|
||||
gpointer user_data)
|
||||
{
|
||||
NMSupplicantInterface *self = NM_SUPPLICANT_INTERFACE (user_data);
|
||||
NMSupplicantInterfacePrivate *priv = NM_SUPPLICANT_INTERFACE_GET_PRIVATE (self);
|
||||
|
||||
g_signal_emit (self, signals[BSS_REMOVED], 0, path);
|
||||
g_hash_table_remove (priv->bss_proxies, path);
|
||||
}
|
||||
|
||||
static void
|
||||
wpas_iface_network_request (GDBusProxy *proxy,
|
||||
const char *path,
|
||||
const char *field,
|
||||
const char *message,
|
||||
gpointer user_data)
|
||||
{
|
||||
NMSupplicantInterface *self = NM_SUPPLICANT_INTERFACE (user_data);
|
||||
NMSupplicantInterfacePrivate *priv = NM_SUPPLICANT_INTERFACE_GET_PRIVATE (self);
|
||||
|
||||
if (priv->has_credreq && priv->net_path && !g_strcmp0 (path, priv->net_path))
|
||||
g_signal_emit (self, signals[CREDENTIALS_REQUEST], 0, field, message);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -602,7 +609,14 @@ on_iface_proxy_acquired (GDBusProxy *proxy, GAsyncResult *result, gpointer user_
|
||||
self = NM_SUPPLICANT_INTERFACE (user_data);
|
||||
priv = NM_SUPPLICANT_INTERFACE_GET_PRIVATE (self);
|
||||
|
||||
g_signal_connect (priv->iface_proxy, "g-signal", G_CALLBACK (signal_cb), self);
|
||||
_nm_dbus_signal_connect (priv->iface_proxy, "ScanDone", G_VARIANT_TYPE ("(b)"),
|
||||
G_CALLBACK (wpas_iface_scan_done), self);
|
||||
_nm_dbus_signal_connect (priv->iface_proxy, "BSSAdded", G_VARIANT_TYPE ("(oa{sv})"),
|
||||
G_CALLBACK (wpas_iface_bss_added), self);
|
||||
_nm_dbus_signal_connect (priv->iface_proxy, "BSSRemoved", G_VARIANT_TYPE ("(o)"),
|
||||
G_CALLBACK (wpas_iface_bss_removed), self);
|
||||
_nm_dbus_signal_connect (priv->iface_proxy, "NetworkRequest", G_VARIANT_TYPE ("(oss)"),
|
||||
G_CALLBACK (wpas_iface_network_request), self);
|
||||
|
||||
/* Check whether NetworkReply and AP mode are supported */
|
||||
priv->ready_count = 1;
|
||||
@@ -666,19 +680,20 @@ interface_get_cb (GDBusProxy *proxy, GAsyncResult *result, gpointer user_data)
|
||||
NMSupplicantInterfacePrivate *priv;
|
||||
gs_unref_variant GVariant *variant = NULL;
|
||||
gs_free_error GError *error = NULL;
|
||||
char *path;
|
||||
const char *path;
|
||||
|
||||
variant = g_dbus_proxy_call_finish (proxy, result, &error);
|
||||
variant = _nm_dbus_proxy_call_finish (proxy, result,
|
||||
G_VARIANT_TYPE ("(o)"),
|
||||
&error);
|
||||
if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
|
||||
return;
|
||||
|
||||
self = NM_SUPPLICANT_INTERFACE (user_data);
|
||||
priv = NM_SUPPLICANT_INTERFACE_GET_PRIVATE (self);
|
||||
|
||||
if (variant && g_variant_is_of_type (variant, G_VARIANT_TYPE ("(o)"))) {
|
||||
g_variant_get (variant, "(o)", &path);
|
||||
if (variant) {
|
||||
g_variant_get (variant, "(&o)", &path);
|
||||
interface_add_done (self, path);
|
||||
g_free (path);
|
||||
} else {
|
||||
nm_log_err (LOGD_SUPPLICANT, "(%s): error getting interface: %s", priv->dev, error->message);
|
||||
set_state (self, NM_SUPPLICANT_INTERFACE_STATE_DOWN);
|
||||
@@ -692,20 +707,21 @@ interface_add_cb (GDBusProxy *proxy, GAsyncResult *result, gpointer user_data)
|
||||
NMSupplicantInterfacePrivate *priv;
|
||||
gs_free_error GError *error = NULL;
|
||||
gs_unref_variant GVariant *variant = NULL;
|
||||
char *path;
|
||||
const char *path;
|
||||
|
||||
variant = g_dbus_proxy_call_finish (proxy, result, &error);
|
||||
variant = _nm_dbus_proxy_call_finish (proxy, result,
|
||||
G_VARIANT_TYPE ("(o)"),
|
||||
&error);
|
||||
if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
|
||||
return;
|
||||
|
||||
self = NM_SUPPLICANT_INTERFACE (user_data);
|
||||
priv = NM_SUPPLICANT_INTERFACE_GET_PRIVATE (self);
|
||||
|
||||
if (variant && g_variant_is_of_type (variant, G_VARIANT_TYPE ("(o)"))) {
|
||||
g_variant_get (variant, "(o)", &path);
|
||||
if (variant) {
|
||||
g_variant_get (variant, "(&o)", &path);
|
||||
interface_add_done (self, path);
|
||||
g_free (path);
|
||||
} else if (_dbus_error_has_name (error, WPAS_ERROR_EXISTS_ERROR)) {
|
||||
} else if (_nm_dbus_error_has_name (error, WPAS_ERROR_EXISTS_ERROR)) {
|
||||
/* Interface already added, just get its object path */
|
||||
g_dbus_proxy_call (priv->wpas_proxy,
|
||||
"GetInterface",
|
||||
@@ -963,19 +979,15 @@ add_network_cb (GDBusProxy *proxy, GAsyncResult *result, gpointer user_data)
|
||||
const char *blob_name;
|
||||
GByteArray *blob_data;
|
||||
|
||||
reply = g_dbus_proxy_call_finish (proxy, result, &error);
|
||||
reply = _nm_dbus_proxy_call_finish (proxy, result,
|
||||
G_VARIANT_TYPE ("(o)"),
|
||||
&error);
|
||||
if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
|
||||
return;
|
||||
|
||||
self = NM_SUPPLICANT_INTERFACE (user_data);
|
||||
priv = NM_SUPPLICANT_INTERFACE_GET_PRIVATE (self);
|
||||
|
||||
if (reply && !g_variant_is_of_type (reply, G_VARIANT_TYPE ("(o)"))) {
|
||||
error = g_error_new (NM_MANAGER_ERROR, NM_MANAGER_ERROR_FAILED,
|
||||
"Unexpected AddNetwork reply type %s",
|
||||
g_variant_get_type_string (reply));
|
||||
}
|
||||
|
||||
g_free (priv->net_path);
|
||||
priv->net_path = NULL;
|
||||
|
||||
@@ -986,7 +998,6 @@ add_network_cb (GDBusProxy *proxy, GAsyncResult *result, gpointer user_data)
|
||||
}
|
||||
|
||||
g_variant_get (reply, "(o)", &priv->net_path);
|
||||
g_assert (priv->net_path);
|
||||
|
||||
/* Send blobs first; otherwise jump to selecting the network */
|
||||
blobs = nm_supplicant_config_get_blobs (priv->cfg);
|
||||
|
@@ -1580,44 +1580,74 @@ really_activate (NMVpnConnection *self, const char *username)
|
||||
_set_vpn_state (self, STATE_CONNECT, NM_VPN_CONNECTION_STATE_REASON_NONE, FALSE);
|
||||
}
|
||||
|
||||
#define MATCH_SIGNAL(s, n, v, t) (!strcmp (s, n) && g_variant_is_of_type (v, t))
|
||||
static void
|
||||
failure_cb (GDBusProxy *proxy,
|
||||
guint32 reason,
|
||||
gpointer user_data)
|
||||
{
|
||||
NMVpnConnection *self = NM_VPN_CONNECTION (user_data);
|
||||
|
||||
plugin_failed (self, reason);
|
||||
}
|
||||
|
||||
static void
|
||||
signal_cb (GDBusProxy *proxy,
|
||||
const gchar *sender,
|
||||
const gchar *signal,
|
||||
GVariant *args,
|
||||
gpointer user_data)
|
||||
state_changed_cb (GDBusProxy *proxy,
|
||||
guint32 new_service_state,
|
||||
gpointer user_data)
|
||||
{
|
||||
NMVpnConnection *self = NM_VPN_CONNECTION (user_data);
|
||||
|
||||
plugin_state_changed (self, new_service_state);
|
||||
}
|
||||
|
||||
static void
|
||||
secrets_required_cb (GDBusProxy *proxy,
|
||||
const char *message,
|
||||
const char **secrets,
|
||||
gpointer user_data)
|
||||
{
|
||||
NMVpnConnection *self = NM_VPN_CONNECTION (user_data);
|
||||
|
||||
plugin_interactive_secrets_required (self, message, secrets);
|
||||
}
|
||||
|
||||
static void
|
||||
config_cb (GDBusProxy *proxy,
|
||||
GVariant *dict,
|
||||
gpointer user_data)
|
||||
{
|
||||
NMVpnConnection *self = NM_VPN_CONNECTION (user_data);
|
||||
NMVpnConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE (self);
|
||||
const char *message, **secrets;
|
||||
gs_unref_variant GVariant *dict = NULL;
|
||||
guint u32;
|
||||
|
||||
if (MATCH_SIGNAL (signal, "Failure", args, G_VARIANT_TYPE ("(u)"))) {
|
||||
g_variant_get (args, "(u)", &u32);
|
||||
plugin_failed (self, u32);
|
||||
} else if (MATCH_SIGNAL (signal, "StateChanged", args, G_VARIANT_TYPE ("(u)"))) {
|
||||
g_variant_get (args, "(u)", &u32);
|
||||
plugin_state_changed (self, u32);
|
||||
} else if (MATCH_SIGNAL (signal, "SecretsRequired", args, G_VARIANT_TYPE ("(sas)"))) {
|
||||
g_variant_get (args, "(&s^a&s)", &message, &secrets);
|
||||
plugin_interactive_secrets_required (self, message, secrets);
|
||||
g_free (secrets);
|
||||
} else if (priv->vpn_state >= STATE_NEED_AUTH) {
|
||||
/* Only list to these signals during and after connection */
|
||||
if (MATCH_SIGNAL (signal, "Config", args, G_VARIANT_TYPE ("(a{sv})"))) {
|
||||
g_variant_get (args, "(@a{sv})", &dict);
|
||||
nm_vpn_connection_config_get (self, dict);
|
||||
} else if (MATCH_SIGNAL (signal, "Ip4Config", args, G_VARIANT_TYPE ("(a{sv})"))) {
|
||||
g_variant_get (args, "(@a{sv})", &dict);
|
||||
nm_vpn_connection_ip4_config_get (self, dict);
|
||||
} else if (MATCH_SIGNAL (signal, "Ip6Config", args, G_VARIANT_TYPE ("(a{sv})"))) {
|
||||
g_variant_get (args, "(@a{sv})", &dict);
|
||||
nm_vpn_connection_ip6_config_get (self, dict);
|
||||
}
|
||||
}
|
||||
/* Only list to this signals during and after connection */
|
||||
if (priv->vpn_state >= STATE_NEED_AUTH)
|
||||
nm_vpn_connection_config_get (self, dict);
|
||||
}
|
||||
|
||||
static void
|
||||
ip4_config_cb (GDBusProxy *proxy,
|
||||
GVariant *dict,
|
||||
gpointer user_data)
|
||||
{
|
||||
NMVpnConnection *self = NM_VPN_CONNECTION (user_data);
|
||||
NMVpnConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE (self);
|
||||
|
||||
/* Only list to this signals during and after connection */
|
||||
if (priv->vpn_state >= STATE_NEED_AUTH)
|
||||
nm_vpn_connection_ip4_config_get (self, dict);
|
||||
}
|
||||
|
||||
static void
|
||||
ip6_config_cb (GDBusProxy *proxy,
|
||||
GVariant *dict,
|
||||
gpointer user_data)
|
||||
{
|
||||
NMVpnConnection *self = NM_VPN_CONNECTION (user_data);
|
||||
NMVpnConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE (self);
|
||||
|
||||
/* Only list to this signals during and after connection */
|
||||
if (priv->vpn_state >= STATE_NEED_AUTH)
|
||||
nm_vpn_connection_ip6_config_get (self, dict);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -1648,7 +1678,18 @@ on_proxy_acquired (GObject *object, GAsyncResult *result, gpointer user_data)
|
||||
}
|
||||
|
||||
priv->proxy = proxy;
|
||||
g_signal_connect (priv->proxy, "g-signal", G_CALLBACK (signal_cb), self);
|
||||
_nm_dbus_signal_connect (priv->proxy, "Failure", G_VARIANT_TYPE ("(u)"),
|
||||
G_CALLBACK (failure_cb), self);
|
||||
_nm_dbus_signal_connect (priv->proxy, "StateChanged", G_VARIANT_TYPE ("(u)"),
|
||||
G_CALLBACK (state_changed_cb), self);
|
||||
_nm_dbus_signal_connect (priv->proxy, "SecretsRequired", G_VARIANT_TYPE ("(sas)"),
|
||||
G_CALLBACK (secrets_required_cb), self);
|
||||
_nm_dbus_signal_connect (priv->proxy, "Config", G_VARIANT_TYPE ("(a{sv})"),
|
||||
G_CALLBACK (config_cb), self);
|
||||
_nm_dbus_signal_connect (priv->proxy, "Ip4Config", G_VARIANT_TYPE ("(a{sv})"),
|
||||
G_CALLBACK (ip4_config_cb), self);
|
||||
_nm_dbus_signal_connect (priv->proxy, "Ip6Config", G_VARIANT_TYPE ("(a{sv})"),
|
||||
G_CALLBACK (ip6_config_cb), self);
|
||||
|
||||
_set_vpn_state (self, STATE_NEED_AUTH, NM_VPN_CONNECTION_STATE_REASON_NONE, FALSE);
|
||||
|
||||
@@ -1810,7 +1851,7 @@ plugin_need_secrets_cb (GDBusProxy *proxy, GAsyncResult *result, gpointer user_d
|
||||
gs_free_error GError *error = NULL;
|
||||
const char *setting_name;
|
||||
|
||||
reply = g_dbus_proxy_call_finish (proxy, result, &error);
|
||||
reply = _nm_dbus_proxy_call_finish (proxy, result, G_VARIANT_TYPE ("(s)"), &error);
|
||||
if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
|
||||
return;
|
||||
|
||||
|
Reference in New Issue
Block a user