diff options
Diffstat (limited to 'libnm/nm-manager.c')
| -rw-r--r-- | libnm/nm-manager.c | 113 |
1 files changed, 94 insertions, 19 deletions
diff --git a/libnm/nm-manager.c b/libnm/nm-manager.c index d3df7337..e664b710 100644 --- a/libnm/nm-manager.c +++ b/libnm/nm-manager.c @@ -34,6 +34,7 @@ #include "nm-active-connection.h" #include "nm-vpn-connection.h" #include "nm-dbus-helpers.h" +#include "nm-utils/c-list.h" #include "introspection/org.freedesktop.NetworkManager.h" @@ -71,7 +72,7 @@ typedef struct { /* Activations waiting for their NMActiveConnection * to appear and then their callback to be called. */ - GSList *pending_activations; + CList pending_activations; gboolean networking_enabled; gboolean wireless_enabled; @@ -82,6 +83,9 @@ typedef struct { gboolean wimax_enabled; gboolean wimax_hw_enabled; + + gboolean connectivity_check_available; + gboolean connectivity_check_enabled; } NMManagerPrivate; enum { @@ -98,6 +102,8 @@ enum { PROP_WIMAX_HARDWARE_ENABLED, PROP_ACTIVE_CONNECTIONS, PROP_CONNECTIVITY, + PROP_CONNECTIVITY_CHECK_AVAILABLE, + PROP_CONNECTIVITY_CHECK_ENABLED, PROP_PRIMARY_CONNECTION, PROP_ACTIVATING_CONNECTION, PROP_DEVICES, @@ -128,6 +134,8 @@ nm_manager_init (NMManager *manager) { NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (manager); + c_list_init (&priv->pending_activations); + priv->state = NM_STATE_UNKNOWN; priv->connectivity = NM_CONNECTIVITY_UNKNOWN; @@ -176,6 +184,8 @@ init_dbus (NMObject *object) { NM_MANAGER_WIMAX_HARDWARE_ENABLED, &priv->wimax_hw_enabled }, { NM_MANAGER_ACTIVE_CONNECTIONS, &priv->active_connections, NULL, NM_TYPE_ACTIVE_CONNECTION, "active-connection" }, { NM_MANAGER_CONNECTIVITY, &priv->connectivity }, + { NM_MANAGER_CONNECTIVITY_CHECK_AVAILABLE, &priv->connectivity_check_available }, + { NM_MANAGER_CONNECTIVITY_CHECK_ENABLED, &priv->connectivity_check_enabled }, { NM_MANAGER_PRIMARY_CONNECTION, &priv->primary_connection, NULL, NM_TYPE_ACTIVE_CONNECTION }, { NM_MANAGER_ACTIVATING_CONNECTION, &priv->activating_connection, NULL, NM_TYPE_ACTIVE_CONNECTION }, { NM_MANAGER_DEVICES, &priv->devices, NULL, NM_TYPE_DEVICE, "device" }, @@ -192,8 +202,8 @@ init_dbus (NMObject *object) property_info); /* Permissions */ - g_signal_connect (priv->proxy, "check-permissions", - G_CALLBACK (manager_recheck_permissions), object); + g_signal_connect_object (priv->proxy, "check-permissions", + G_CALLBACK (manager_recheck_permissions), object, 0); } static NMClientPermission @@ -229,6 +239,8 @@ nm_permission_to_client (const char *nm) return NM_CLIENT_PERMISSION_CHECKPOINT_ROLLBACK; else if (!strcmp (nm, NM_AUTH_PERMISSION_ENABLE_DISABLE_STATISTICS)) return NM_CLIENT_PERMISSION_ENABLE_DISABLE_STATISTICS; + else if (!strcmp (nm, NM_AUTH_PERMISSION_ENABLE_DISABLE_CONNECTIVITY_CHECK)) + return NM_CLIENT_PERMISSION_ENABLE_DISABLE_CONNECTIVITY_CHECK; return NM_CLIENT_PERMISSION_NONE; } @@ -499,6 +511,31 @@ nm_manager_wimax_hardware_get_enabled (NMManager *manager) } gboolean +nm_manager_connectivity_check_get_available (NMManager *manager) +{ + g_return_val_if_fail (NM_IS_MANAGER (manager), FALSE); + + return NM_MANAGER_GET_PRIVATE (manager)->connectivity_check_available; +} + +gboolean +nm_manager_connectivity_check_get_enabled (NMManager *manager) +{ + return NM_MANAGER_GET_PRIVATE (manager)->connectivity_check_enabled; +} + +void +nm_manager_connectivity_check_set_enabled (NMManager *manager, gboolean enabled) +{ + g_return_if_fail (NM_IS_MANAGER (manager)); + + _nm_object_set_property (NM_OBJECT (manager), + NM_DBUS_INTERFACE, + "ConnectivityCheckEnabled", + "b", enabled); +} + +gboolean nm_manager_get_logging (NMManager *manager, char **level, char **domains, GError **error) { gboolean ret; @@ -576,8 +613,13 @@ nm_manager_check_connectivity (NMManager *manager, if (nmdbus_manager_call_check_connectivity_sync (priv->proxy, &connectivity, - cancellable, error)) + cancellable, error)) { + if (connectivity != priv->connectivity) { + priv->connectivity = connectivity; + g_object_notify (G_OBJECT (manager), NM_MANAGER_CONNECTIVITY); + } return connectivity; + } else { if (error && *error) g_dbus_error_strip_remote_error (*error); @@ -593,12 +635,21 @@ check_connectivity_cb (GObject *object, GSimpleAsyncResult *simple = user_data; guint32 connectivity; GError *error = NULL; + NMManager *manager; + NMManagerPrivate *priv; if (nmdbus_manager_call_check_connectivity_finish (NMDBUS_MANAGER (object), &connectivity, - result, &error)) + result, &error)) { g_simple_async_result_set_op_res_gssize (simple, connectivity); - else { + + manager = NM_MANAGER (g_async_result_get_source_object (G_ASYNC_RESULT (simple))); + priv = NM_MANAGER_GET_PRIVATE (manager); + if (connectivity != priv->connectivity) { + priv->connectivity = connectivity; + g_object_notify (G_OBJECT (manager), NM_MANAGER_CONNECTIVITY); + } + } else { g_dbus_error_strip_remote_error (error); g_simple_async_result_take_error (simple, error); } @@ -735,6 +786,7 @@ nm_manager_get_activating_connection (NMManager *manager) } typedef struct { + CList lst; NMManager *manager; GSimpleAsyncResult *simple; GCancellable *cancellable; @@ -748,15 +800,13 @@ activate_info_complete (ActivateInfo *info, NMActiveConnection *active, GError *error) { - NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (info->manager); - if (active) g_simple_async_result_set_op_res_gpointer (info->simple, g_object_ref (active), g_object_unref); else g_simple_async_result_set_from_error (info->simple, error); g_simple_async_result_complete (info->simple); - priv->pending_activations = g_slist_remove (priv->pending_activations, info); + c_list_unlink (&info->lst); g_free (info->active_path); g_free (info->new_connection_path); @@ -790,7 +840,7 @@ static void recheck_pending_activations (NMManager *self) { NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self); - GSList *iter, *next; + CList *iter, *safe; NMActiveConnection *candidate; const GPtrArray *devices; NMDevice *device; @@ -804,12 +854,10 @@ recheck_pending_activations (NMManager *self) * device have both updated their properties to point to each other, and * call the pending connection's callback. */ - for (iter = priv->pending_activations; iter; iter = next) { - ActivateInfo *info = iter->data; + c_list_for_each_safe (iter, safe, &priv->pending_activations) { + ActivateInfo *info = c_list_entry (iter, ActivateInfo, lst); gs_unref_object GDBusObject *dbus_obj = NULL; - next = g_slist_next (iter); - if (!info->active_path) continue; @@ -901,14 +949,15 @@ nm_manager_activate_connection_async (NMManager *manager, if (connection) g_return_if_fail (NM_IS_CONNECTION (connection)); + priv = NM_MANAGER_GET_PRIVATE (manager); + info = g_slice_new0 (ActivateInfo); info->manager = manager; info->simple = g_simple_async_result_new (G_OBJECT (manager), callback, user_data, nm_manager_activate_connection_async); info->cancellable = cancellable ? g_object_ref (cancellable) : NULL; - priv = NM_MANAGER_GET_PRIVATE (manager); - priv->pending_activations = g_slist_prepend (priv->pending_activations, info); + c_list_link_tail (&priv->pending_activations, &info->lst); nmdbus_manager_call_activate_connection (priv->proxy, connection ? nm_connection_get_path (connection) : "/", @@ -977,14 +1026,15 @@ nm_manager_add_and_activate_connection_async (NMManager *manager, if (partial) g_return_if_fail (NM_IS_CONNECTION (partial)); + priv = NM_MANAGER_GET_PRIVATE (manager); + info = g_slice_new0 (ActivateInfo); info->manager = manager; info->simple = g_simple_async_result_new (G_OBJECT (manager), callback, user_data, nm_manager_add_and_activate_connection_async); info->cancellable = cancellable ? g_object_ref (cancellable) : NULL; - priv = NM_MANAGER_GET_PRIVATE (manager); - priv->pending_activations = g_slist_prepend (priv->pending_activations, info); + c_list_link_tail (&priv->pending_activations, &info->lst); if (partial) dict = nm_connection_to_dbus (partial, NM_CONNECTION_SERIALIZE_ALL); @@ -1294,7 +1344,7 @@ dispose (GObject *object) /* Each activation should hold a ref on @manager, so if we're being disposed, * there shouldn't be any pending. */ - g_warn_if_fail (priv->pending_activations == NULL); + g_warn_if_fail (c_list_is_empty (&priv->pending_activations)); g_hash_table_destroy (priv->permissions); priv->permissions = NULL; @@ -1348,6 +1398,13 @@ set_property (GObject *object, guint prop_id, /* Let the property value flip when we get the change signal from NM */ } break; + case PROP_CONNECTIVITY_CHECK_ENABLED: + b = g_value_get_boolean (value); + if (priv->connectivity_check_enabled != b) { + nm_manager_connectivity_check_set_enabled (NM_MANAGER (object), b); + /* Let the property value flip when we get the change signal from NM */ + } + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -1400,6 +1457,12 @@ get_property (GObject *object, case PROP_CONNECTIVITY: g_value_set_enum (value, priv->connectivity); break; + case PROP_CONNECTIVITY_CHECK_AVAILABLE: + g_value_set_boolean (value, priv->connectivity_check_available); + break; + case PROP_CONNECTIVITY_CHECK_ENABLED: + g_value_set_boolean (value, priv->connectivity_check_enabled); + break; case PROP_PRIMARY_CONNECTION: g_value_set_object (value, priv->primary_connection); break; @@ -1520,6 +1583,18 @@ nm_manager_class_init (NMManagerClass *manager_class) G_PARAM_READABLE | G_PARAM_STATIC_STRINGS)); g_object_class_install_property + (object_class, PROP_CONNECTIVITY_CHECK_AVAILABLE, + g_param_spec_boolean (NM_MANAGER_CONNECTIVITY_CHECK_AVAILABLE, "", "", + FALSE, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); + g_object_class_install_property + (object_class, PROP_CONNECTIVITY_CHECK_ENABLED, + g_param_spec_boolean (NM_MANAGER_CONNECTIVITY_CHECK_ENABLED, "", "", + FALSE, + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); + g_object_class_install_property (object_class, PROP_PRIMARY_CONNECTION, g_param_spec_object (NM_MANAGER_PRIMARY_CONNECTION, "", "", NM_TYPE_ACTIVE_CONNECTION, |