diff options
-rw-r--r-- | src/devices/nm-device-wifi.c | 28 | ||||
-rw-r--r-- | src/devices/nm-device.c | 33 | ||||
-rw-r--r-- | src/devices/nm-device.h | 12 | ||||
-rw-r--r-- | src/nm-manager.c | 6 |
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)); |