core: also check specific object when determining available connections

This commit is contained in:
Dan Williams 2013-09-03 15:34:56 -05:00
parent 8a173e1d7a
commit f4befaab00
5 changed files with 89 additions and 9 deletions

View file

@ -221,7 +221,9 @@ check_connection_compatible (NMDevice *device,
}
static gboolean
check_connection_available (NMDevice *device, NMConnection *connection)
check_connection_available (NMDevice *device,
NMConnection *connection,
const char *specific_object)
{
NMDeviceBtPrivate *priv = NM_DEVICE_BT_GET_PRIVATE (device);
guint32 bt_type;

View file

@ -1021,13 +1021,22 @@ check_connection_compatible (NMDevice *device,
static gboolean
check_connection_available (NMDevice *device, NMConnection *connection)
check_connection_available (NMDevice *device,
NMConnection *connection,
const char *specific_object)
{
NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (device);
NMSettingWireless *s_wifi;
const char *mode;
GSList *ap_iter = NULL;
if (specific_object) {
NMAccessPoint *ap;
ap = get_ap_by_path (NM_DEVICE_WIFI (device), specific_object);
return ap ? nm_ap_check_compatible (ap, connection) : FALSE;
}
s_wifi = nm_connection_get_setting_wireless (connection);
/* Ad-Hoc and AP connections are always available because they may be

View file

@ -320,7 +320,9 @@ static gboolean nm_device_set_ip6_config (NMDevice *dev,
static gboolean nm_device_activate_ip6_config_commit (gpointer user_data);
static gboolean check_connection_available (NMDevice *device, NMConnection *connection);
static gboolean check_connection_available (NMDevice *device,
NMConnection *connection,
const char *specific_object);
static gboolean spec_match_list (NMDevice *device, const GSList *specs);
@ -6613,7 +6615,7 @@ _try_add_available_connection (NMDevice *self, NMConnection *connection)
if (nm_device_check_connection_compatible (self, connection, NULL)) {
/* Let subclasses implement additional checks on the connection */
if ( NM_DEVICE_GET_CLASS (self)->check_connection_available
&& NM_DEVICE_GET_CLASS (self)->check_connection_available (self, connection)) {
&& NM_DEVICE_GET_CLASS (self)->check_connection_available (self, connection, NULL)) {
g_hash_table_insert (NM_DEVICE_GET_PRIVATE (self)->available_connections,
g_object_ref (connection),
@ -6631,7 +6633,9 @@ _del_available_connection (NMDevice *device, NMConnection *connection)
}
static gboolean
check_connection_available (NMDevice *device, NMConnection *connection)
check_connection_available (NMDevice *device,
NMConnection *connection,
const char *specific_object)
{
/* Default is to assume the connection is available unless a subclass
* overrides this with more specific checks.
@ -6658,6 +6662,42 @@ nm_device_recheck_available_connections (NMDevice *device)
_signal_available_connections_changed (device);
}
/**
* nm_device_get_available_connections:
* @device: the #NMDevice
* @specific_object: a specific object path if any
*
* Returns a list of connections available to activate on the device, taking
* into account any device-specific details given by @specific_object (like
* WiFi access point path).
*
* Returns: caller-owned #GPtrArray of #NMConnections
*/
GPtrArray *
nm_device_get_available_connections (NMDevice *device, const char *specific_object)
{
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (device);
GHashTableIter iter;
guint num_available;
NMConnection *connection = NULL;
GPtrArray *array = NULL;
num_available = g_hash_table_size (priv->available_connections);
if (num_available > 0) {
array = g_ptr_array_sized_new (num_available);
g_hash_table_iter_init (&iter, priv->available_connections);
while (g_hash_table_iter_next (&iter, (gpointer) &connection, NULL)) {
/* If a specific object is given, only include connections that are
* compatible with it.
*/
if ( !specific_object
|| NM_DEVICE_GET_CLASS (device)->check_connection_available (device, connection, specific_object))
g_ptr_array_add (array, connection);
}
}
return array;
}
static void
cp_connection_added (NMConnectionProvider *cp, NMConnection *connection, gpointer user_data)
{

View file

@ -140,11 +140,13 @@ typedef struct {
GError **error);
/* Checks whether the connection is likely available to be activated,
* including any live network information like scan lists. Returns
* TRUE if the connection is available; FALSE if not.
* including any live network information like scan lists. The connection
* is checked against the object defined by @specific_object, if given.
* Returns TRUE if the connection is available; FALSE if not.
*/
gboolean (* check_connection_available) (NMDevice *self,
NMConnection *connection);
NMConnection *connection,
const char *specific_object);
gboolean (* complete_connection) (NMDevice *self,
NMConnection *connection,
@ -337,6 +339,9 @@ void nm_device_add_pending_action (NMDevice *device, const char *action);
void nm_device_remove_pending_action (NMDevice *device, const char *action);
gboolean nm_device_has_pending_action (NMDevice *device);
GPtrArray *nm_device_get_available_connections (NMDevice *device,
const char *specific_object);
G_END_DECLS
/* For testing only */

View file

@ -261,6 +261,22 @@ get_nsp_by_name (NMDeviceWimax *self, const char *name)
return NULL;
}
static NMWimaxNsp *
get_nsp_by_path (NMDeviceWimax *self, const char *path)
{
NMDeviceWimaxPrivate *priv = NM_DEVICE_WIMAX_GET_PRIVATE (self);
GSList *iter;
for (iter = priv->nsp_list; iter; iter = iter->next) {
NMWimaxNsp *nsp = NM_WIMAX_NSP (iter->data);
if (!g_strcmp0 (nm_wimax_nsp_get_dbus_path (nsp), path))
return nsp;
}
return NULL;
}
static gboolean
update_availability (NMDeviceWimax *self, gboolean old_available)
{
@ -375,10 +391,18 @@ check_connection_compatible (NMDevice *device,
}
static gboolean
check_connection_available (NMDevice *device, NMConnection *connection)
check_connection_available (NMDevice *device,
NMConnection *connection,
const char *specific_object)
{
NMDeviceWimaxPrivate *priv = NM_DEVICE_WIMAX_GET_PRIVATE (device);
const GSList *ns_iter = NULL;
NMWimaxNsp *nsp;
if (specific_object) {
nsp = get_nsp_by_path (NM_DEVICE_WIMAX (device), specific_object);
return nsp ? nm_wimax_nsp_check_compatible (nsp, connection) : FALSE;
}
/* Ensure the connection applies to an NSP in the scan list */
for (ns_iter = priv->nsp_list; ns_iter; ns_iter = ns_iter->next) {