Commit 4fe48b12 authored by Dan Williams's avatar Dan Williams

core: add connection provider interface

Allows better encapsulation of the functionality of the NMSettings
object that we want to expose to the device class.  They don't need
the whole object so to keep things simple and contained we'll just
give them a smaller interface to use.
parent 1b40d82b
......@@ -48,7 +48,9 @@ libsettings_la_SOURCES = \
nm-secret-agent.c \
nm-secret-agent.h \
nm-settings-utils.h \
nm-settings-utils.c
nm-settings-utils.c \
nm-connection-provider.h \
nm-connection-provider.c
libsettings_la_CPPFLAGS = \
$(DBUS_CFLAGS) \
......
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
/*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program 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 General Public License for more details:
*
* Copyright (C) 2012 Red Hat, Inc.
*/
#include "nm-connection-provider.h"
GSList *
nm_connection_provider_get_best_connections (NMConnectionProvider *self,
guint max_requested,
const char *ctype1,
const char *ctype2,
NMConnectionFilterFunc func,
gpointer func_data)
{
g_return_val_if_fail (NM_IS_CONNECTION_PROVIDER (self), NULL);
if (NM_CONNECTION_PROVIDER_GET_INTERFACE (self)->get_best_connections)
return NM_CONNECTION_PROVIDER_GET_INTERFACE (self)->get_best_connections (self, max_requested, ctype1, ctype2, func, func_data);
return NULL;
}
/*****************************************************************************/
static void
nm_connection_provider_init (gpointer g_iface)
{
}
GType
nm_connection_provider_get_type (void)
{
static GType cp_type = 0;
if (!G_UNLIKELY (cp_type)) {
const GTypeInfo cp_info = {
sizeof (NMConnectionProvider), /* class_size */
nm_connection_provider_init, /* base_init */
NULL, /* base_finalize */
NULL,
NULL, /* class_finalize */
NULL, /* class_data */
0,
0, /* n_preallocs */
NULL
};
cp_type = g_type_register_static (G_TYPE_INTERFACE, "NMConnectionProvider", &cp_info, 0);
g_type_interface_add_prerequisite (cp_type, G_TYPE_OBJECT);
}
return cp_type;
}
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
/*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program 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 General Public License for more details:
*
* Copyright (C) 2012 Red Hat, Inc.
*/
#ifndef NM_CONNECTION_PROVIDER_H
#define NM_CONNECTION_PROVIDER_H
#include <glib-object.h>
#include <nm-connection.h>
#define NM_TYPE_CONNECTION_PROVIDER (nm_connection_provider_get_type ())
#define NM_CONNECTION_PROVIDER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_CONNECTION_PROVIDER, NMConnectionProvider))
#define NM_IS_CONNECTION_PROVIDER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_CONNECTION_PROVIDER))
#define NM_CONNECTION_PROVIDER_GET_INTERFACE(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), NM_TYPE_CONNECTION_PROVIDER, NMConnectionProvider))
typedef struct _NMConnectionProvider NMConnectionProvider;
/**
* NMConnectionFilterFunc:
* @provider: The provider requesting the filtering
* @connection: the connection to be filtered
* @func_data: the caller-provided data pointer
*
* Returns: %TRUE to allow the connection, %FALSE to ignore it
*/
typedef gboolean (*NMConnectionFilterFunc) (NMConnectionProvider *provider,
NMConnection *connection,
gpointer func_data);
struct _NMConnectionProvider {
GTypeInterface g_iface;
/* Methods */
GSList * (*get_best_connections) (NMConnectionProvider *self,
guint max_requested,
const char *ctype1,
const char *ctype2,
NMConnectionFilterFunc func,
gpointer func_data);
};
GType nm_connection_provider_get_type (void);
/**
* nm_connection_provider_get_best_connections:
* @self: the #NMConnectionProvider
* @max_requested: if non-zero, the maximum number of connections to return
* @ctype1: an #NMSetting base type (eg NM_SETTING_WIRELESS_SETTING_NAME) to
* filter connections against
* @ctype2: a second #NMSetting base type (eg NM_SETTING_WIRELESS_SETTING_NAME)
* to filter connections against
* @func: caller-supplied function for filtering connections
* @func_data: caller-supplied data passed to @func
*
* Returns: a #GSList of #NMConnection objects in sorted order representing the
* "best" or highest-priority connections filtered by @ctype1 and/or @ctype2,
* and/or @func. Caller is responsible for freeing the returned #GSList, but
* the contained values do not need to be unreffed.
*/
GSList *nm_connection_provider_get_best_connections (NMConnectionProvider *self,
guint max_requested,
const char *ctype1,
const char *ctype2,
NMConnectionFilterFunc func,
gpointer func_data);
#endif /* NM_CONNECTION_PROVIDER_H */
......@@ -68,6 +68,7 @@
#include "plugins/keyfile/plugin.h"
#include "nm-agent-manager.h"
#include "nm-settings-utils.h"
#include "nm-connection-provider.h"
#define CONFIG_KEY_NO_AUTO_DEFAULT "no-auto-default"
......@@ -110,6 +111,12 @@ static void impl_settings_save_hostname (NMSettings *self,
static void unmanaged_specs_changed (NMSystemConfigInterface *config, gpointer user_data);
static void connection_provider_init (NMConnectionProvider *cp_class);
G_DEFINE_TYPE_EXTENDED (NMSettings, nm_settings, G_TYPE_OBJECT, 0,
G_IMPLEMENT_INTERFACE (NM_TYPE_CONNECTION_PROVIDER, connection_provider_init))
typedef struct {
NMDBusManager *dbus_mgr;
DBusGConnection *bus;
......@@ -127,8 +134,6 @@ typedef struct {
GSList *unmanaged_specs;
} NMSettingsPrivate;
G_DEFINE_TYPE (NMSettings, nm_settings, G_TYPE_OBJECT)
#define NM_SETTINGS_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_SETTINGS, NMSettingsPrivate))
enum {
......@@ -1621,6 +1626,82 @@ nm_settings_device_removed (NMSettings *self, NMDevice *device)
/***************************************************************/
static gint
best_connection_sort (gconstpointer a, gconstpointer b, gpointer user_data)
{
NMSettingsConnection *ac = (NMSettingsConnection *) a;
NMSettingsConnection *bc = (NMSettingsConnection *) b;
guint64 ats, bts;
if (!ac && bc)
return -1;
else if (ac && !bc)
return 1;
else if (!ac && !bc)
return 0;
g_assert (ac && bc);
/* In the future we may use connection priorities in addition to timestamps */
ats = nm_settings_connection_get_timestamp (ac);
bts = nm_settings_connection_get_timestamp (bc);
if (ats < bts)
return -1;
else if (ats > bts)
return 1;
return 0;
}
static GSList *
get_best_connections (NMConnectionProvider *provider,
guint max_requested,
const char *ctype1,
const char *ctype2,
NMConnectionFilterFunc func,
gpointer func_data)
{
NMSettings *self = NM_SETTINGS (provider);
NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self);
GSList *sorted = NULL;
GHashTableIter iter;
NMSettingsConnection *connection;
guint added = 0;
guint64 oldest = 0;
g_hash_table_iter_init (&iter, priv->connections);
while (g_hash_table_iter_next (&iter, NULL, (gpointer) &connection)) {
if (ctype1 && !nm_connection_is_type (NM_CONNECTION (connection), ctype1))
continue;
if (ctype2 && !nm_connection_is_type (NM_CONNECTION (connection), ctype2))
continue;
if (func && !func (provider, NM_CONNECTION (connection), func_data))
continue;
/* Don't bother with a connection that's older than the oldest one in the list */
if ( max_requested
&& added >= max_requested
&& nm_settings_connection_get_timestamp (connection) <= oldest)
continue;
/* List is sorted with oldest first */
sorted = g_slist_insert_sorted_with_data (sorted, connection, best_connection_sort, NULL);
added++;
if (max_requested && added > max_requested) {
/* Over the limit, remove the oldest one */
sorted = g_slist_delete_link (sorted, sorted);
added--;
}
oldest = nm_settings_connection_get_timestamp (NM_SETTINGS_CONNECTION (sorted->data));
}
return g_slist_reverse (sorted);
}
/***************************************************************/
NMSettings *
nm_settings_new (const char *config_file,
const char **plugins,
......@@ -1659,6 +1740,12 @@ nm_settings_new (const char *config_file,
return self;
}
static void
connection_provider_init (NMConnectionProvider *cp_class)
{
cp_class->get_best_connections = get_best_connections;
}
static void
nm_settings_init (NMSettings *self)
{
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment