From f9fd8667d131bb6334e9eaa07a49bce567cb43d9 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Wed, 3 Oct 2007 14:48:25 +0000 Subject: [PATCH] 2007-10-03 Dan Williams Add a GetActiveConnections() method on the Manager object. * src/nm-manager.c src/nm-manager.h introspection/nm-manager.xml - (connection_get_settings_cb): keep connection type around too - (impl_manager_get_active_connections, add_one_connection_element): implement; returns all active connections and what devices they apply to * libnm-glib/nm-client.c libnm-glib/nm-client.h introspection/nm-manager-client.xml - (nm_client_get_devices): GPtrArray elements are allocated and owned by the caller; free here to avoid memory leak - (nm_client_get_active_connections): implement; return the list of active connections - (nm_client_free_active_connection_element): implement; free an element of the GSList returned by nm_client_get_active_connections() git-svn-id: http://svn-archive.gnome.org/svn/NetworkManager/trunk@2927 4912f4e0-d625-0410-9fb7-b9a5a253dbdc --- ChangeLog | 22 ++++++ introspection/nm-manager-client.xml | 12 ++++ introspection/nm-manager.xml | 12 ++++ libnm-glib/nm-client.c | 103 +++++++++++++++++++++++++- libnm-glib/nm-client.h | 18 +++-- src/nm-manager.c | 108 ++++++++++++++++++++++++++++ src/nm-manager.h | 1 + 7 files changed, 271 insertions(+), 5 deletions(-) diff --git a/ChangeLog b/ChangeLog index d221f95fa9..a25a646f53 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,25 @@ +2007-10-03 Dan Williams + + Add a GetActiveConnections() method on the Manager object. + + * src/nm-manager.c + src/nm-manager.h + introspection/nm-manager.xml + - (connection_get_settings_cb): keep connection type around too + - (impl_manager_get_active_connections, add_one_connection_element): + implement; returns all active connections and what devices they + apply to + + * libnm-glib/nm-client.c + libnm-glib/nm-client.h + introspection/nm-manager-client.xml + - (nm_client_get_devices): GPtrArray elements are allocated and owned + by the caller; free here to avoid memory leak + - (nm_client_get_active_connections): implement; return the list of + active connections + - (nm_client_free_active_connection_element): implement; free an element + of the GSList returned by nm_client_get_active_connections() + 2007-10-03 Dan Williams * src/nm-device-802-11-wireless.c diff --git a/introspection/nm-manager-client.xml b/introspection/nm-manager-client.xml index 66e76e82d8..99cfd7eccb 100644 --- a/introspection/nm-manager-client.xml +++ b/introspection/nm-manager-client.xml @@ -23,6 +23,18 @@ + + + + + + diff --git a/introspection/nm-manager.xml b/introspection/nm-manager.xml index 5020343eac..24c48164ad 100644 --- a/introspection/nm-manager.xml +++ b/introspection/nm-manager.xml @@ -23,6 +23,18 @@ + + + + + + diff --git a/libnm-glib/nm-client.c b/libnm-glib/nm-client.c index 73c896f567..d6ad65e8ed 100644 --- a/libnm-glib/nm-client.c +++ b/libnm-glib/nm-client.c @@ -359,10 +359,12 @@ nm_client_get_devices (NMClient *client) for (i = 0; i < array->len; i++) { NMDevice *device; + char *path = g_ptr_array_index (array, i); - device = get_device (client, (const char *) g_ptr_array_index (array, i), TRUE); + device = get_device (client, (const char *) path, TRUE); if (device) list = g_slist_append (list, device); + g_free (path); } g_ptr_array_free (array, TRUE); @@ -444,6 +446,105 @@ nm_client_activate_device (NMClient *client, info); } + +GSList * +nm_client_get_active_connections (NMClient *client) +{ + NMClientPrivate *priv; + GSList *connections = NULL; + GPtrArray *array = NULL; + GError *err; + int i, j; + static GType type = 0, ao_type = 0; + + g_return_val_if_fail (NM_IS_CLIENT (client), NULL); + + priv = NM_CLIENT_GET_PRIVATE (client); + if (!org_freedesktop_NetworkManager_get_active_connections (priv->client_proxy, &array, &err)) { + g_warning ("Error in get_active_connections: %s", err->message); + g_error_free (err); + return NULL; + } + + /* dbus signature "sooao" */ + if (G_UNLIKELY (ao_type) == 0) + ao_type = dbus_g_type_get_collection ("GPtrArray", DBUS_TYPE_G_OBJECT_PATH); + if (G_UNLIKELY (type) == 0) { + type = dbus_g_type_get_struct ("GValueArray", + G_TYPE_STRING, + DBUS_TYPE_G_OBJECT_PATH, + DBUS_TYPE_G_OBJECT_PATH, + ao_type, + G_TYPE_INVALID); + } + + for (i = 0; i < array->len; i++) { + NMClientActiveConnection *ac_elt; + GValue val = {0, }; + GPtrArray *devices = NULL; + + ac_elt = g_slice_new0 (NMClientActiveConnection); + if (!ac_elt) { + g_warning ("Error in get_active_connections: not enough memory."); + continue; + } + + g_value_init (&val, type); + g_value_take_boxed (&val, g_ptr_array_index (array, i)); + dbus_g_type_struct_get (&val, + 0, &(ac_elt->service_name), + 1, &(ac_elt->connection_path), + 2, &(ac_elt->specific_object), + 3, &devices, + G_MAXUINT); + g_value_unset (&val); + + if (devices == NULL || (devices->len == 0)) { + g_warning ("Error in get_active_connections: no devices returned."); + nm_client_free_active_connection_element (ac_elt); + continue; + } + + if (!strcmp (ac_elt->specific_object, "/")) { + g_free (ac_elt->specific_object); + ac_elt->specific_object = NULL; + } + + for (j = 0; j < devices->len; j++) { + NMDevice *device; + char *path = g_ptr_array_index (devices, j); + + device = get_device (client, (const char *) path, TRUE); + ac_elt->devices = g_slist_append (ac_elt->devices, g_object_ref (device)); + g_free (path); + } + g_ptr_array_free (devices, TRUE); + + connections = g_slist_append (connections, ac_elt); + } + + g_ptr_array_free (array, TRUE); + return connections; +} + +void +nm_client_free_active_connection_element (NMClientActiveConnection *elt) +{ + GSList *iter; + + g_return_if_fail (elt != NULL); + + g_free (elt->service_name); + g_free (elt->connection_path); + g_free (elt->specific_object); + + g_slist_foreach (elt->devices, (GFunc) g_object_unref, NULL); + g_slist_free (elt->devices); + + g_slice_free (NMClientActiveConnection, elt); +} + + gboolean nm_client_wireless_get_enabled (NMClient *client) { diff --git a/libnm-glib/nm-client.h b/libnm-glib/nm-client.h index bb410ff21a..9b4e5fc7a3 100644 --- a/libnm-glib/nm-client.h +++ b/libnm-glib/nm-client.h @@ -38,10 +38,20 @@ GType nm_client_get_type (void); NMClient *nm_client_new (void); -gboolean nm_client_manager_is_running (NMClient *client); -GSList *nm_client_get_devices (NMClient *client); -NMDevice *nm_client_get_device_by_path (NMClient *client, - const char *object_path); +gboolean nm_client_manager_is_running (NMClient *client); +GSList *nm_client_get_devices (NMClient *client); +NMDevice *nm_client_get_device_by_path (NMClient *client, + const char *object_path); + +typedef struct NMClientActiveConnection { + char *service_name; + char *connection_path; + char *specific_object; + GSList *devices; /* list of NMDevice objects */ +} NMClientActiveConnection; + +GSList * nm_client_get_active_connections (NMClient *client); +void nm_client_free_active_connection_element (NMClientActiveConnection *elt); typedef void (*NMClientActivateDeviceFn) (gpointer user_data, GError *error); diff --git a/src/nm-manager.c b/src/nm-manager.c index 1653422db8..ed0725ceff 100644 --- a/src/nm-manager.c +++ b/src/nm-manager.c @@ -18,6 +18,10 @@ static void impl_manager_activate_device (NMManager *manager, char *specific_object_path, DBusGMethodInvocation *context); +static gboolean impl_manager_get_active_connections (NMManager *manager, + GPtrArray **connections, + GError **err); + static gboolean impl_manager_sleep (NMManager *manager, gboolean sleep, GError **err); /* Legacy 0.6 compatibility interface */ @@ -386,6 +390,10 @@ connection_get_settings_cb (DBusGProxy *proxy, g_assert_not_reached (); } + g_object_set_data (G_OBJECT (connection), + NM_MANAGER_CONNECTION_TYPE_TAG, + GUINT_TO_POINTER (connection_type)); + g_signal_emit (manager, signals[CONNECTION_ADDED], 0, connection, connection_type); } else { // FIXME: merge settings? or just replace? @@ -986,6 +994,106 @@ impl_manager_activate_device (NMManager *manager, } } +static GValueArray * +add_one_connection_element (NMManager *manager, + NMDevice *device) +{ + GValueArray *elt; + static GType type = 0, ao_type = 0; + GValue entry = {0, }; + GPtrArray *dev_array = NULL; + NMActRequest *req; + const char *service_name; + NMConnection *connection; + const char *specific_object; + gpointer type_ptr; + + req = nm_device_get_act_request (device); + g_assert (req); + + connection = nm_act_request_get_connection (req); + type_ptr = g_object_get_data (G_OBJECT (connection), NM_MANAGER_CONNECTION_TYPE_TAG); + g_return_val_if_fail (type_ptr != NULL, NULL); + + switch ((NMConnectionType) GPOINTER_TO_UINT (type_ptr)) { + case NM_CONNECTION_TYPE_USER: + service_name = NM_DBUS_SERVICE_USER_SETTINGS; + break; + case NM_CONNECTION_TYPE_SYSTEM: + service_name = NM_DBUS_SERVICE_SYSTEM_SETTINGS; + break; + default: + g_assert_not_reached (); + break; + } + + specific_object = nm_act_request_get_specific_object (req); + + /* dbus signature "sooao" */ + if (G_UNLIKELY (ao_type) == 0) + ao_type = dbus_g_type_get_collection ("GPtrArray", DBUS_TYPE_G_OBJECT_PATH); + if (G_UNLIKELY (type) == 0) { + type = dbus_g_type_get_struct ("GValueArray", + G_TYPE_STRING, + DBUS_TYPE_G_OBJECT_PATH, + DBUS_TYPE_G_OBJECT_PATH, + ao_type, + G_TYPE_INVALID); + } + + dev_array = g_ptr_array_sized_new (1); + if (!dev_array) + return NULL; + g_ptr_array_add (dev_array, g_strdup (nm_device_get_dbus_path (device))); + + g_value_init (&entry, type); + g_value_take_boxed (&entry, dbus_g_type_specialized_construct (type)); + dbus_g_type_struct_set (&entry, + 0, service_name, + 1, nm_manager_get_connection_dbus_path (manager, connection), + 2, specific_object ? specific_object : "/", + 3, dev_array, + G_MAXUINT); + return g_value_get_boxed (&entry); +} + +static gboolean +impl_manager_get_active_connections (NMManager *manager, + GPtrArray **connections, + GError **err) +{ + NMManagerPrivate *priv; + GType type, aoao_type, ao_type; + DBusGTypeSpecializedAppendContext ctx; + GValue val = {0, }; + GSList *iter; + + g_return_val_if_fail (NM_IS_MANAGER (manager), FALSE); + + priv = NM_MANAGER_GET_PRIVATE (manager); + + // GPtrArray of GValueArrays of (gchar * and GPtrArray of gchar *) + *connections = g_ptr_array_sized_new (1); + + // FIXME: this assumes one active device per connection + for (iter = priv->devices; iter; iter = g_slist_next (iter)) { + NMDevice *dev = NM_DEVICE (iter->data); + GValueArray *item; + + if ( (nm_device_get_state (dev) != NM_DEVICE_STATE_ACTIVATED) + && !nm_device_is_activating (dev)) + continue; + + item = add_one_connection_element (manager, dev); + if (!item) + continue; + + g_ptr_array_add (*connections, item); + } + + return TRUE; +} + gboolean nm_manager_wireless_enabled (NMManager *manager) { diff --git a/src/nm-manager.h b/src/nm-manager.h index b7275eca7e..8ff1d199ea 100644 --- a/src/nm-manager.h +++ b/src/nm-manager.h @@ -18,6 +18,7 @@ #define NM_MANAGER_WIRELESS_ENABLED "wireless-enabled" #define NM_MANAGER_CONNECTION_PROXY_TAG "dbus-proxy" +#define NM_MANAGER_CONNECTION_TYPE_TAG "service-type" typedef enum { NM_CONNECTION_TYPE_UNKNOWN = 0,