summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/devices/nm-device-wifi.c28
-rw-r--r--src/devices/nm-device.c33
-rw-r--r--src/devices/nm-device.h12
-rw-r--r--src/nm-manager.c6
4 files changed, 68 insertions, 11 deletions
diff --git a/src/devices/nm-device-wifi.c b/src/devices/nm-device-wifi.c
index 06ac602a2a..363b83ab54 100644
--- a/src/devices/nm-device-wifi.c
+++ b/src/devices/nm-device-wifi.c
@@ -1050,9 +1050,10 @@ check_connection_compatible (NMDevice *device,
static gboolean
-check_connection_available (NMDevice *device,
- NMConnection *connection,
- const char *specific_object)
+_internal_check_connection_available (NMDevice *device,
+ NMConnection *connection,
+ const char *specific_object,
+ gboolean ignore_ap_list)
{
NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (device);
NMSettingWireless *s_wifi;
@@ -1077,7 +1078,7 @@ check_connection_available (NMDevice *device,
return TRUE;
/* Hidden SSIDs obviously don't always appear in the scan list either */
- if (nm_setting_wireless_get_hidden (s_wifi))
+ if (nm_setting_wireless_get_hidden (s_wifi) || ignore_ap_list)
return TRUE;
/* check if its visible */
@@ -1089,6 +1090,24 @@ check_connection_available (NMDevice *device,
return FALSE;
}
+static gboolean
+check_connection_available (NMDevice *device,
+ NMConnection *connection,
+ const char *specific_object)
+{
+ return _internal_check_connection_available (device, connection, specific_object, FALSE);
+}
+
+/* FIXME: remove this function when we require the 'hidden' property to be
+ * set before a hidden connection can be activated.
+ */
+static gboolean
+check_connection_available_wifi_hidden (NMDevice *device,
+ NMConnection *connection)
+{
+ return _internal_check_connection_available (device, connection, NULL, TRUE);
+}
+
/*
* List of manufacturer default SSIDs that are often unchanged by users.
*
@@ -3629,6 +3648,7 @@ nm_device_wifi_class_init (NMDeviceWifiClass *klass)
parent_class->is_available = is_available;
parent_class->check_connection_compatible = check_connection_compatible;
parent_class->check_connection_available = check_connection_available;
+ parent_class->check_connection_available_wifi_hidden = check_connection_available_wifi_hidden;
parent_class->complete_connection = complete_connection;
parent_class->set_enabled = set_enabled;
diff --git a/src/devices/nm-device.c b/src/devices/nm-device.c
index 699b9785c7..fb37c968d6 100644
--- a/src/devices/nm-device.c
+++ b/src/devices/nm-device.c
@@ -1643,7 +1643,7 @@ can_auto_connect (NMDevice *device,
if (!nm_setting_connection_get_autoconnect (s_con))
return FALSE;
- return nm_device_connection_is_available (device, connection);
+ return nm_device_connection_is_available (device, connection, FALSE);
}
static gboolean
@@ -7046,10 +7046,26 @@ nm_device_get_autoconnect (NMDevice *device)
return NM_DEVICE_GET_PRIVATE (device)->autoconnect;
}
+/**
+ * nm_device_connection_is_available():
+ * @device: the #NMDevice
+ * @connection: the #NMConnection to check for availability
+ * @allow_device_override: set to %TRUE to let the device do specific checks
+ *
+ * Check if @connection is available to be activated on @device. Normally this
+ * only checks if the connection is in @device's AvailableConnections property.
+ * If @allow_device_override is %TRUE then the device is asked to do specific
+ * checks that may bypass the AvailableConnections property.
+ *
+ * Returns: %TRUE if @connection can be activated on @device
+ */
gboolean
-nm_device_connection_is_available (NMDevice *device, NMConnection *connection)
+nm_device_connection_is_available (NMDevice *device,
+ NMConnection *connection,
+ gboolean allow_device_override)
{
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (device);
+ gboolean available = FALSE;
if (priv->default_unmanaged && (priv->state == NM_DEVICE_STATE_UNMANAGED)) {
/* default-unmanaged devices in UNMANAGED state have no available connections
@@ -7060,7 +7076,18 @@ nm_device_connection_is_available (NMDevice *device, NMConnection *connection)
return TRUE;
}
- return !!g_hash_table_lookup (priv->available_connections, connection);
+ available = !!g_hash_table_lookup (priv->available_connections, connection);
+ if (!available && allow_device_override) {
+ /* FIXME: hack for hidden WiFi becuase clients didn't consistently
+ * set the 'hidden' property to indicate hidden SSID networks. If
+ * activating but the network isn't available let the device recheck
+ * availability.
+ */
+ if (NM_DEVICE_GET_CLASS (device)->check_connection_available_wifi_hidden)
+ available = NM_DEVICE_GET_CLASS (device)->check_connection_available_wifi_hidden (device, connection);
+ }
+
+ return available;
}
static void
diff --git a/src/devices/nm-device.h b/src/devices/nm-device.h
index 297bbe9cfc..47d7856f34 100644
--- a/src/devices/nm-device.h
+++ b/src/devices/nm-device.h
@@ -153,6 +153,14 @@ typedef struct {
NMConnection *connection,
const char *specific_object);
+ /* Same as check_connection_available() but called if the connection
+ * is not present in the activating-connections array during activation,
+ * to give the device a chance to allow/deny the activation. This is a
+ * hack only meant for hidden WiFi networks.
+ */
+ gboolean (* check_connection_available_wifi_hidden) (NMDevice *self,
+ NMConnection *connection);
+
gboolean (* complete_connection) (NMDevice *self,
NMConnection *connection,
const char *specific_object,
@@ -331,7 +339,9 @@ const char *nm_device_get_physical_port_id (NMDevice *device);
guint32 nm_device_get_mtu (NMDevice *device);
-gboolean nm_device_connection_is_available (NMDevice *device, NMConnection *connection);
+gboolean nm_device_connection_is_available (NMDevice *device,
+ NMConnection *connection,
+ gboolean allow_device_override);
gboolean nm_device_notify_component_added (NMDevice *device, GObject *component);
diff --git a/src/nm-manager.c b/src/nm-manager.c
index 26e65d84fe..1466a429f0 100644
--- a/src/nm-manager.c
+++ b/src/nm-manager.c
@@ -2501,7 +2501,7 @@ ensure_master_active_connection (NMManager *self,
if (!is_compatible_with_slave (candidate, connection))
continue;
- if (nm_device_connection_is_available (master_device, candidate)) {
+ if (nm_device_connection_is_available (master_device, candidate, TRUE)) {
master_ac = nm_manager_activate_connection (self,
candidate,
NULL,
@@ -2542,7 +2542,7 @@ ensure_master_active_connection (NMManager *self,
continue;
}
- if (!nm_device_connection_is_available (candidate, master_connection))
+ if (!nm_device_connection_is_available (candidate, master_connection, TRUE))
continue;
found_device = TRUE;
@@ -2658,7 +2658,7 @@ _internal_activate_device (NMManager *self, NMActiveConnection *active, GError *
}
/* Final connection must be available on device */
- if (!nm_device_connection_is_available (device, connection)) {
+ if (!nm_device_connection_is_available (device, connection, TRUE)) {
g_set_error (error, NM_MANAGER_ERROR, NM_MANAGER_ERROR_UNKNOWN_CONNECTION,
"Connection '%s' is not available on the device %s at this time.",
nm_connection_get_id (connection), nm_device_get_iface (device));