core: merge branch 'th/queue_act_request_no_carrier_rh1079353'

https://bugzilla.redhat.com/show_bug.cgi?id=1079353
This commit is contained in:
Thomas Haller 2015-02-24 11:50:38 +01:00
commit 1f5b9ffc3d
11 changed files with 263 additions and 157 deletions

View file

@ -187,6 +187,7 @@ check_connection_compatible (NMDevice *device, NMConnection *connection)
static gboolean
check_connection_available (NMDevice *device,
NMConnection *connection,
NMDeviceCheckConAvailableFlags flags,
const char *specific_object)
{
NMDeviceBtPrivate *priv = NM_DEVICE_BT_GET_PRIVATE (device);
@ -929,7 +930,7 @@ bluez_device_removed (NMBluezDevice *bdev, gpointer user_data)
/*****************************************************************************/
static gboolean
is_available (NMDevice *dev)
is_available (NMDevice *dev, NMDeviceCheckDevAvailableFlags flags)
{
NMDeviceBt *self = NM_DEVICE_BT (dev);
NMDeviceBtPrivate *priv = NM_DEVICE_BT_GET_PRIVATE (self);
@ -957,7 +958,7 @@ handle_availability_change (NMDeviceBt *self,
return;
}
available = nm_device_is_available (device);
available = nm_device_is_available (device, NM_DEVICE_CHECK_DEV_AVAILABLE_NONE);
if (available == old_available)
return;
@ -987,7 +988,7 @@ set_mm_running (NMDeviceBt *self, gboolean running)
_LOGD (LOGD_BT, "ModemManager now %s",
running ? "available" : "unavailable");
old_available = nm_device_is_available (NM_DEVICE (self));
old_available = nm_device_is_available (NM_DEVICE (self), NM_DEVICE_CHECK_DEV_AVAILABLE_NONE);
priv->mm_running = running;
handle_availability_change (self, old_available, NM_DEVICE_STATE_REASON_MODEM_MANAGER_UNAVAILABLE);

View file

@ -68,7 +68,7 @@ get_generic_capabilities (NMDevice *dev)
}
static gboolean
is_available (NMDevice *dev)
is_available (NMDevice *dev, NMDeviceCheckDevAvailableFlags flags)
{
if (NM_DEVICE_GET_CLASS (dev)->is_up)
return NM_DEVICE_GET_CLASS (dev)->is_up (dev);
@ -78,6 +78,7 @@ is_available (NMDevice *dev)
static gboolean
check_connection_available (NMDevice *device,
NMConnection *connection,
NMDeviceCheckConAvailableFlags flags,
const char *specific_object)
{
/* Connections are always available because the carrier state is determined

View file

@ -66,7 +66,7 @@ get_generic_capabilities (NMDevice *dev)
}
static gboolean
is_available (NMDevice *dev)
is_available (NMDevice *dev, NMDeviceCheckDevAvailableFlags flags)
{
if (NM_DEVICE_GET_CLASS (dev)->is_up)
return NM_DEVICE_GET_CLASS (dev)->is_up (dev);
@ -76,6 +76,7 @@ is_available (NMDevice *dev)
static gboolean
check_connection_available (NMDevice *device,
NMConnection *connection,
NMDeviceCheckConAvailableFlags flags,
const char *specific_object)
{
/* Connections are always available because the carrier state is determined

View file

@ -210,6 +210,7 @@ typedef struct {
guint32 ip4_address;
NMActRequest * queued_act_request;
gboolean queued_act_request_is_waiting_for_carrier;
NMActRequest * act_request;
guint act_source_id;
gpointer act_source_func;
@ -338,6 +339,8 @@ static gboolean addrconf6_start_with_link_ready (NMDevice *self);
static gboolean dhcp6_start_with_link_ready (NMDevice *self, NMConnection *connection);
static NMActStageReturn linklocal6_start (NMDevice *self);
static void _carrier_wait_check_queued_act_request (NMDevice *self);
static gboolean nm_device_get_default_unmanaged (NMDevice *self);
static void _set_state_full (NMDevice *self,
@ -1138,6 +1141,7 @@ nm_device_set_carrier (NMDevice *self, gboolean carrier)
g_source_remove (priv->carrier_wait_id);
priv->carrier_wait_id = 0;
nm_device_remove_pending_action (self, "carrier wait", TRUE);
_carrier_wait_check_queued_act_request (self);
}
} else if (state <= NM_DEVICE_STATE_DISCONNECTED) {
_LOGI (LOGD_DEVICE, "link disconnected");
@ -1734,16 +1738,24 @@ nm_device_removed (NMDevice *self)
static gboolean
is_available (NMDevice *self)
is_available (NMDevice *self, NMDeviceCheckDevAvailableFlags flags)
{
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
return priv->carrier || priv->ignore_carrier;
if (priv->carrier || priv->ignore_carrier)
return TRUE;
if (NM_FLAGS_HAS (flags, NM_DEVICE_CHECK_DEV_AVAILABLE_IGNORE_CARRIER))
return TRUE;
return FALSE;
}
/**
* nm_device_is_available:
* @self: the #NMDevice
* @flags: additional flags to influence the check. Flags have the
* meaning to increase the availability of a device.
*
* Checks if @self would currently be capable of activating a
* connection. In particular, it checks that the device is ready (eg,
@ -1759,14 +1771,14 @@ is_available (NMDevice *self)
* Returns: %TRUE or %FALSE
*/
gboolean
nm_device_is_available (NMDevice *self)
nm_device_is_available (NMDevice *self, NMDeviceCheckDevAvailableFlags flags)
{
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
if (priv->firmware_missing)
return FALSE;
return NM_DEVICE_GET_CLASS (self)->is_available (self);
return NM_DEVICE_GET_CLASS (self)->is_available (self, flags);
}
gboolean
@ -1890,7 +1902,7 @@ can_auto_connect (NMDevice *self,
if (!nm_setting_connection_get_autoconnect (s_con))
return FALSE;
return nm_device_connection_is_available (self, connection, FALSE);
return nm_device_check_connection_available (self, connection, NM_DEVICE_CHECK_CON_AVAILABLE_NONE, NULL);
}
/**
@ -5622,6 +5634,15 @@ disconnect_cb (NMDevice *self,
}
}
static void
_clear_queued_act_request (NMDevicePrivate *priv)
{
if (priv->queued_act_request) {
nm_active_connection_set_state ((NMActiveConnection *) priv->queued_act_request, NM_ACTIVE_CONNECTION_STATE_DEACTIVATED);
g_clear_object (&priv->queued_act_request);
}
}
static void
impl_device_disconnect (NMDevice *self, DBusGMethodInvocation *context)
{
@ -5724,26 +5745,97 @@ _device_activate (NMDevice *self, NMActRequest *req)
nm_device_activate_schedule_stage1_device_prepare (self);
}
static void
_carrier_wait_check_queued_act_request (NMDevice *self)
{
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
NMActRequest *queued_req;
if ( !priv->queued_act_request
|| !priv->queued_act_request_is_waiting_for_carrier)
return;
priv->queued_act_request_is_waiting_for_carrier = FALSE;
if (!priv->carrier) {
_LOGD (LOGD_DEVICE, "Cancel queued activation request as we have no carrier after timeout");
g_clear_object (&priv->queued_act_request);
} else {
_LOGD (LOGD_DEVICE, "Activate queued activation request as we now have carrier");
queued_req = priv->queued_act_request;
priv->queued_act_request = NULL;
_device_activate (self, queued_req);
g_object_unref (queued_req);
}
}
static gboolean
_carrier_wait_check_act_request_must_queue (NMDevice *self, NMActRequest *req)
{
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
NMConnection *connection;
/* If we have carrier or if we are not waiting for it, the activation
* request is not blocked waiting for carrier. */
if (priv->carrier)
return FALSE;
if (priv->carrier_wait_id == 0)
return FALSE;
connection = nm_act_request_get_connection (req);
if (!nm_device_check_connection_available (self, connection, NM_DEVICE_CHECK_CON_AVAILABLE_ALL, NULL)) {
/* We passed all @flags we have, and no @specific_object.
* This equals maximal availability, if a connection is not available
* in this case, it is not waiting for carrier.
*
* Actually, why are we even trying to activate it? Strange, but whatever
* the reason, don't wait for carrier.
*/
return FALSE;
}
if (nm_device_check_connection_available (self, connection, NM_DEVICE_CHECK_CON_AVAILABLE_ALL & ~_NM_DEVICE_CHECK_CON_AVAILABLE_FOR_USER_REQUEST_WAITING_CARRIER, NULL)) {
/* The connection was available with flags ALL, and it is still available
* if we pretend not to wait for carrier. That means that the
* connection is available now, and does not wait for carrier.
*
* Since the flags increase the availability of a connection, when checking
* ALL&~WAITING_CARRIER, it means that we certainly would wait for carrier. */
return FALSE;
}
/* The activation request must wait for carrier. */
return TRUE;
}
void
nm_device_queue_activation (NMDevice *self, NMActRequest *req)
{
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
gboolean must_queue;
if (!priv->act_request) {
must_queue = _carrier_wait_check_act_request_must_queue (self, req);
if (!priv->act_request && !must_queue) {
/* Just activate immediately */
_device_activate (self, req);
return;
}
/* supercede any already-queued request */
g_clear_object (&priv->queued_act_request);
_clear_queued_act_request (priv);
priv->queued_act_request = g_object_ref (req);
priv->queued_act_request_is_waiting_for_carrier = must_queue;
/* Deactivate existing activation request first */
_LOGI (LOGD_DEVICE, "disconnecting for new activation request.");
nm_device_state_changed (self,
NM_DEVICE_STATE_DEACTIVATING,
NM_DEVICE_STATE_REASON_NONE);
_LOGD (LOGD_DEVICE, "queue activation request waiting for %s", must_queue ? "carrier" : "currently active connection to disconnect");
if (priv->act_request) {
/* Deactivate existing activation request first */
_LOGI (LOGD_DEVICE, "disconnecting for new activation request.");
nm_device_state_changed (self,
NM_DEVICE_STATE_DEACTIVATING,
NM_DEVICE_STATE_REASON_NONE);
}
}
/*
@ -6285,6 +6377,9 @@ carrier_wait_timeout (gpointer user_data)
NM_DEVICE_GET_PRIVATE (self)->carrier_wait_id = 0;
nm_device_remove_pending_action (self, "carrier wait", TRUE);
_carrier_wait_check_queued_act_request (self);
return G_SOURCE_REMOVE;
}
@ -6349,12 +6444,11 @@ nm_device_bring_up (NMDevice *self, gboolean block, gboolean *no_firmware)
* a timeout is reached.
*/
if (device_has_capability (self, NM_DEVICE_CAP_CARRIER_DETECT)) {
if (priv->carrier_wait_id) {
if (priv->carrier_wait_id)
g_source_remove (priv->carrier_wait_id);
nm_device_remove_pending_action (self, "carrier wait", TRUE);
}
else
nm_device_add_pending_action (self, "carrier wait", TRUE);
priv->carrier_wait_id = g_timeout_add_seconds (5, carrier_wait_timeout, self);
nm_device_add_pending_action (self, "carrier wait", TRUE);
}
/* Can only get HW address of some devices when they are up */
@ -6880,48 +6974,45 @@ nm_device_set_dhcp_anycast_address (NMDevice *self, const char *addr)
}
/**
* nm_device_connection_is_available():
* nm_device_check_connection_available():
* @self: the #NMDevice
* @connection: the #NMConnection to check for availability
* @allow_device_override: set to %TRUE to let the device do specific checks
* @flags: flags to affect the decision making of whether a connection
* is available. Adding a flag can only make a connection more available,
* not less.
* @specific_object: a device type dependent argument to further
* filter the result. Passing a non %NULL specific object can only reduce
* the availability of a connection.
*
* Check if @connection is available to be activated on @self. Normally this
* only checks if the connection is in @self's AvailableConnections property.
* If @allow_device_override is %TRUE then the device is asked to do specific
* checks that may bypass the AvailableConnections property.
* Check if @connection is available to be activated on @self.
*
* Returns: %TRUE if @connection can be activated on @self
*/
gboolean
nm_device_connection_is_available (NMDevice *self,
NMConnection *connection,
gboolean allow_device_override)
nm_device_check_connection_available (NMDevice *self,
NMConnection *connection,
NMDeviceCheckConAvailableFlags flags,
const char *specific_object)
{
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
gboolean available = FALSE;
NMDeviceState state;
if (nm_device_get_default_unmanaged (self) && (priv->state == NM_DEVICE_STATE_UNMANAGED)) {
/* default-unmanaged devices in UNMANAGED state have no available connections
* so we must manually check whether the connection is available here.
*/
if ( nm_device_check_connection_compatible (self, connection)
&& NM_DEVICE_GET_CLASS (self)->check_connection_available (self, connection, NULL))
return TRUE;
}
state = nm_device_get_state (self);
if (state < NM_DEVICE_STATE_UNMANAGED)
return FALSE;
if ( state < NM_DEVICE_STATE_UNAVAILABLE
&& nm_device_get_unmanaged_flag (self, NM_UNMANAGED_ALL & ~NM_UNMANAGED_DEFAULT))
return FALSE;
if ( state < NM_DEVICE_STATE_DISCONNECTED
&& ( ( !NM_FLAGS_HAS (flags, _NM_DEVICE_CHECK_CON_AVAILABLE_FOR_USER_REQUEST_WAITING_CARRIER)
&& !nm_device_is_available (self, NM_DEVICE_CHECK_DEV_AVAILABLE_NONE))
|| ( NM_FLAGS_HAS (flags, _NM_DEVICE_CHECK_CON_AVAILABLE_FOR_USER_REQUEST_WAITING_CARRIER)
&& !nm_device_is_available (self, NM_DEVICE_CHECK_DEV_AVAILABLE_IGNORE_CARRIER))))
return FALSE;
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_check_connection_compatible (self, connection)
&& NM_DEVICE_GET_CLASS (self)->check_connection_available_wifi_hidden)
available = NM_DEVICE_GET_CLASS (self)->check_connection_available_wifi_hidden (self, connection);
}
if (!nm_device_check_connection_compatible (self, connection))
return FALSE;
return available;
return NM_DEVICE_GET_CLASS (self)->check_connection_available (self, connection, flags, specific_object);
}
static void
@ -6941,17 +7032,10 @@ _clear_available_connections (NMDevice *self, gboolean do_signal)
static gboolean
_try_add_available_connection (NMDevice *self, NMConnection *connection)
{
if ( nm_device_get_state (self) < NM_DEVICE_STATE_DISCONNECTED
&& !nm_device_get_default_unmanaged (self))
return FALSE;
if (nm_device_check_connection_compatible (self, connection)) {
if (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),
GUINT_TO_POINTER (1));
return TRUE;
}
if (nm_device_check_connection_available (self, connection, NM_DEVICE_CHECK_CON_AVAILABLE_NONE, NULL)) {
g_hash_table_add (NM_DEVICE_GET_PRIVATE (self)->available_connections,
g_object_ref (connection));
return TRUE;
}
return FALSE;
}
@ -6965,15 +7049,28 @@ _del_available_connection (NMDevice *self, NMConnection *connection)
static gboolean
check_connection_available (NMDevice *self,
NMConnection *connection,
NMDeviceCheckConAvailableFlags flags,
const char *specific_object)
{
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self);
/* Connections which require a network connection are not available when
* the device has no carrier, even with ignore-carrer=TRUE.
*/
if (NM_DEVICE_GET_PRIVATE (self)->carrier == FALSE)
return connection_requires_carrier (connection) ? FALSE : TRUE;
if ( priv->carrier
|| !connection_requires_carrier (connection))
return TRUE;
return TRUE;
if ( NM_FLAGS_HAS (flags, _NM_DEVICE_CHECK_CON_AVAILABLE_FOR_USER_REQUEST_WAITING_CARRIER)
&& priv->carrier_wait_id != 0) {
/* The device has no carrier though the connection requires it.
*
* If we are still waiting for carrier, the connection is available
* for an explicit user-request. */
return TRUE;
}
return FALSE;
}
void
@ -7025,8 +7122,8 @@ nm_device_get_available_connections (NMDevice *self, const char *specific_object
/* If a specific object is given, only include connections that are
* compatible with it.
*/
if ( !specific_object
|| NM_DEVICE_GET_CLASS (self)->check_connection_available (self, connection, specific_object))
if ( !specific_object /* << Optimization: we know that the connection is available without @specific_object. */
|| nm_device_check_connection_available (self, connection, NM_DEVICE_CHECK_CON_AVAILABLE_NONE, specific_object))
g_ptr_array_add (array, connection);
}
}
@ -7635,7 +7732,7 @@ _set_state_full (NMDevice *self,
if (state <= NM_DEVICE_STATE_UNAVAILABLE) {
_clear_available_connections (self, TRUE);
g_clear_object (&priv->queued_act_request);
_clear_queued_act_request (priv);
}
/* Update the available connections list when a device first becomes available */
@ -7731,7 +7828,7 @@ _set_state_full (NMDevice *self,
* we can't change states again from the state handler for a variety of
* reasons.
*/
if (nm_device_is_available (self)) {
if (nm_device_is_available (self, NM_DEVICE_CHECK_DEV_AVAILABLE_NONE)) {
_LOGD (LOGD_DEVICE, "device is available, will transition to DISCONNECTED");
nm_device_queue_state (self, NM_DEVICE_STATE_DISCONNECTED, NM_DEVICE_STATE_REASON_NONE);
} else {
@ -7762,7 +7859,8 @@ _set_state_full (NMDevice *self,
}
break;
case NM_DEVICE_STATE_DISCONNECTED:
if (priv->queued_act_request) {
if ( priv->queued_act_request
&& !priv->queued_act_request_is_waiting_for_carrier) {
NMActRequest *queued_req;
queued_req = priv->queued_act_request;
@ -8352,7 +8450,7 @@ dispose (GObject *object)
priv->carrier_wait_id = 0;
}
g_clear_object (&priv->queued_act_request);
_clear_queued_act_request (priv);
platform = nm_platform_get ();
g_signal_handlers_disconnect_by_func (platform, G_CALLBACK (device_ip_changed), self);

View file

@ -86,10 +86,37 @@ G_BEGIN_DECLS
typedef enum NMActStageReturn NMActStageReturn;
/* These flags affect whether a connection is considered available on a device
* (check_connection_available()). The flags should have the meaning of relaxing
* a condition, so that adding a flag might make a connection available that would
* not be available otherwise. Adding a flag should never make a connection
* not available if it would be available otherwise. */
typedef enum {
NM_DEVICE_CHECK_CON_AVAILABLE_NONE = 0,
_NM_DEVICE_CHECK_CON_AVAILABLE_FOR_USER_REQUEST_WAITING_CARRIER = (1L << 0),
_NM_DEVICE_CHECK_CON_AVAILABLE_FOR_USER_REQUEST_IGNORE_AP = (1L << 1),
NM_DEVICE_CHECK_CON_AVAILABLE_FOR_USER_REQUEST = _NM_DEVICE_CHECK_CON_AVAILABLE_FOR_USER_REQUEST_WAITING_CARRIER
| _NM_DEVICE_CHECK_CON_AVAILABLE_FOR_USER_REQUEST_IGNORE_AP,
__NM_DEVICE_CHECK_CON_AVAILABLE_ALL,
NM_DEVICE_CHECK_CON_AVAILABLE_ALL = (((__NM_DEVICE_CHECK_CON_AVAILABLE_ALL - 1) << 1) - 1),
} NMDeviceCheckConAvailableFlags;
struct _NMDevice {
GObject parent;
};
/* The flags have an relaxing meaning, that means, specifying more flags, can make
* a device appear more available. It can never make a device less available. */
typedef enum {
NM_DEVICE_CHECK_DEV_AVAILABLE_NONE = 0,
NM_DEVICE_CHECK_DEV_AVAILABLE_IGNORE_CARRIER = (1L << 0),
__NM_DEVICE_CHECK_DEV_AVAILABLE_ALL,
NM_DEVICE_CHECK_DEV_AVAILABLE_ALL = (((__NM_DEVICE_CHECK_DEV_AVAILABLE_ALL - 1) << 1) - 1),
} NMDeviceCheckDevAvailableFlags;
typedef struct {
GObjectClass parent;
@ -117,7 +144,7 @@ typedef struct {
guint32 (* get_generic_capabilities) (NMDevice *self);
gboolean (* is_available) (NMDevice *self);
gboolean (* is_available) (NMDevice *self, NMDeviceCheckDevAvailableFlags flags);
gboolean (* get_enabled) (NMDevice *self);
@ -137,19 +164,18 @@ typedef struct {
* 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.
*
* The passed @flags affect whether a connection is considered
* available or not. Adding more flags, means the connection is
* *more* available.
*
* Specifying @specific_object can only reduce the availability of a connection.
*/
gboolean (* check_connection_available) (NMDevice *self,
NMConnection *connection,
NMDeviceCheckConAvailableFlags flags,
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,
@ -268,7 +294,7 @@ NMConnection * nm_device_get_connection (NMDevice *dev);
void nm_device_removed (NMDevice *dev);
gboolean nm_device_is_available (NMDevice *dev);
gboolean nm_device_is_available (NMDevice *dev, NMDeviceCheckDevAvailableFlags flags);
gboolean nm_device_has_carrier (NMDevice *dev);
NMConnection * nm_device_generate_connection (NMDevice *self, NMDevice *master);
@ -327,7 +353,8 @@ typedef enum {
/* Boundary value */
__NM_UNMANAGED_LAST,
NM_UNMANAGED_LAST = __NM_UNMANAGED_LAST - 1,
NM_UNMANAGED_LAST = __NM_UNMANAGED_LAST - 1,
NM_UNMANAGED_ALL = ((NM_UNMANAGED_LAST << 1) - 1),
} NMUnmanagedFlags;
gboolean nm_device_get_managed (NMDevice *device);
@ -371,9 +398,10 @@ gboolean nm_device_has_pending_action (NMDevice *device);
GPtrArray *nm_device_get_available_connections (NMDevice *device,
const char *specific_object);
gboolean nm_device_connection_is_available (NMDevice *device,
NMConnection *connection,
gboolean allow_device_override);
gboolean nm_device_check_connection_available (NMDevice *device,
NMConnection *connection,
NMDeviceCheckConAvailableFlags flags,
const char *specific_object);
gboolean nm_device_notify_component_added (NMDevice *device, GObject *component);

View file

@ -74,7 +74,7 @@ get_generic_capabilities (NMDevice *device)
}
static gboolean
is_available (NMDevice *device)
is_available (NMDevice *device, NMDeviceCheckDevAvailableFlags flags)
{
if (NM_DEVICE_GET_CLASS (device)->is_up)
return NM_DEVICE_GET_CLASS (device)->is_up (device);
@ -84,6 +84,7 @@ is_available (NMDevice *device)
static gboolean
check_connection_available (NMDevice *device,
NMConnection *connection,
NMDeviceCheckConAvailableFlags flags,
const char *specific_object)
{
/* Connections are always available because the carrier state is determined

View file

@ -235,7 +235,7 @@ act_stage2_config (NMDevice *device, NMDeviceStateReason *reason)
}
static gboolean
is_available (NMDevice *device)
is_available (NMDevice *device, NMDeviceCheckDevAvailableFlags flags)
{
NMDeviceOlpcMesh *self = NM_DEVICE_OLPC_MESH (device);

View file

@ -864,10 +864,10 @@ check_connection_compatible (NMDevice *device, NMConnection *connection)
static gboolean
_internal_check_connection_available (NMDevice *device,
NMConnection *connection,
const char *specific_object,
gboolean ignore_ap_list)
check_connection_available (NMDevice *device,
NMConnection *connection,
NMDeviceCheckConAvailableFlags flags,
const char *specific_object)
{
NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (device);
NMSettingWireless *s_wifi;
@ -877,6 +877,9 @@ _internal_check_connection_available (NMDevice *device,
s_wifi = nm_connection_get_setting_wireless (connection);
g_return_val_if_fail (s_wifi, FALSE);
/* a connection that is available for a certain @specific_object, MUST
* also be available in general (without @specific_object). */
if (specific_object) {
NMAccessPoint *ap;
@ -892,8 +895,15 @@ _internal_check_connection_available (NMDevice *device,
|| g_strcmp0 (mode, NM_SETTING_WIRELESS_MODE_AP) == 0)
return TRUE;
/* Hidden SSIDs obviously don't always appear in the scan list either */
if (nm_setting_wireless_get_hidden (s_wifi) || ignore_ap_list)
/* Hidden SSIDs obviously don't always appear in the scan list either.
*
* For an explict user-activation-request, a connection is considered
* available because for hidden Wi-Fi, 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_setting_wireless_get_hidden (s_wifi) || NM_FLAGS_HAS (flags, _NM_DEVICE_CHECK_CON_AVAILABLE_FOR_USER_REQUEST_IGNORE_AP))
return TRUE;
/* check if its visible */
@ -905,24 +915,6 @@ _internal_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.
*
@ -1144,28 +1136,22 @@ complete_connection (NMDevice *device,
}
static gboolean
is_available (NMDevice *device)
is_available (NMDevice *device, NMDeviceCheckDevAvailableFlags flags)
{
NMDeviceWifi *self = NM_DEVICE_WIFI (device);
NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (self);
guint32 state;
if (!priv->enabled) {
_LOGD (LOGD_WIFI, "not available because not enabled");
if (!priv->enabled)
return FALSE;
}
if (!priv->sup_iface) {
_LOGD (LOGD_WIFI, "not available because supplicant not running");
if (!priv->sup_iface)
return FALSE;
}
state = nm_supplicant_interface_get_state (priv->sup_iface);
if ( state < NM_SUPPLICANT_INTERFACE_STATE_READY
|| state > NM_SUPPLICANT_INTERFACE_STATE_COMPLETED) {
_LOGD (LOGD_WIFI, "not available because supplicant interface not ready");
|| state > NM_SUPPLICANT_INTERFACE_STATE_COMPLETED)
return FALSE;
}
return TRUE;
}
@ -2170,7 +2156,7 @@ supplicant_iface_state_cb (NMSupplicantInterface *iface,
/* If the interface can now be activated because the supplicant is now
* available, transition to DISCONNECTED.
*/
if ((devstate == NM_DEVICE_STATE_UNAVAILABLE) && nm_device_is_available (device)) {
if ((devstate == NM_DEVICE_STATE_UNAVAILABLE) && nm_device_is_available (device, NM_DEVICE_CHECK_DEV_AVAILABLE_NONE)) {
nm_device_state_changed (device,
NM_DEVICE_STATE_DISCONNECTED,
NM_DEVICE_STATE_REASON_SUPPLICANT_AVAILABLE);
@ -3341,7 +3327,6 @@ 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;

View file

@ -239,7 +239,7 @@ update_availability (NMDeviceWimax *self, gboolean old_available)
NMDeviceState state;
gboolean new_available, changed = FALSE;
new_available = nm_device_is_available (device);
new_available = nm_device_is_available (device, NM_DEVICE_CHECK_DEV_AVAILABLE_NONE);
if (new_available == old_available)
return FALSE;
@ -281,7 +281,7 @@ set_enabled (NMDevice *device, gboolean enabled)
if (priv->enabled == enabled)
return;
old_available = nm_device_is_available (NM_DEVICE (device));
old_available = nm_device_is_available (NM_DEVICE (device), NM_DEVICE_CHECK_DEV_AVAILABLE_NONE);
priv->enabled = enabled;
nm_log_dbg (LOGD_WIMAX, "(%s): radio now %s",
@ -334,12 +334,16 @@ check_connection_compatible (NMDevice *device, NMConnection *connection)
static gboolean
check_connection_available (NMDevice *device,
NMConnection *connection,
NMDeviceCheckConAvailableFlags flags,
const char *specific_object)
{
NMDeviceWimaxPrivate *priv = NM_DEVICE_WIMAX_GET_PRIVATE (device);
const GSList *ns_iter = NULL;
NMWimaxNsp *nsp;
/* a connection that is available for a certain @specific_object, MUST
* also be available in general (without @specific_object). */
if (specific_object) {
nsp = get_nsp_by_path (NM_DEVICE_WIMAX (device), specific_object);
return nsp ? nm_wimax_nsp_check_compatible (nsp, connection) : FALSE;
@ -484,30 +488,21 @@ can_auto_connect (NMDevice *device,
}
static gboolean
is_available (NMDevice *device)
is_available (NMDevice *device, NMDeviceCheckDevAvailableFlags flags)
{
NMDeviceWimaxPrivate *priv = NM_DEVICE_WIMAX_GET_PRIVATE (device);
const char *iface = nm_device_get_iface (device);
if (!priv->enabled) {
nm_log_dbg (LOGD_WIMAX, "(%s): not available because not enabled", iface);
if (!priv->enabled)
return FALSE;
}
if (!priv->wimaxd_enabled) {
nm_log_dbg (LOGD_WIMAX, "(%s): not available because not enabled in wimaxd", iface);
if (!priv->wimaxd_enabled)
return FALSE;
}
if (!nm_wimax_util_sdk_is_initialized ()) {
nm_log_dbg (LOGD_WIMAX, "(%s): not available because WiMAX SDK not initialized", iface);
if (!nm_wimax_util_sdk_is_initialized ())
return FALSE;
}
if (!priv->sdk) {
nm_log_dbg (LOGD_WIMAX, "(%s): not available because not known to WiMAX SDK", iface);
if (!priv->sdk)
return FALSE;
}
return iwmxsdk_status_get (priv->sdk) >= WIMAX_API_DEVICE_STATUS_Ready;
}
@ -712,7 +707,7 @@ wmx_state_change_cb (struct wmxsdk *wmxsdk,
return;
state = nm_device_get_state (NM_DEVICE (self));
old_available = nm_device_is_available (NM_DEVICE (self));
old_available = nm_device_is_available (NM_DEVICE (self), NM_DEVICE_CHECK_DEV_AVAILABLE_NONE);
priv->status = new_status;
if (priv->current_nsp)
@ -1153,7 +1148,7 @@ static gboolean
sdk_action_defer_cb (gpointer user_data)
{
NMDeviceWimax *self = NM_DEVICE_WIMAX (user_data);
gboolean old_available = nm_device_is_available (NM_DEVICE (self));
gboolean old_available = nm_device_is_available (NM_DEVICE (self), NM_DEVICE_CHECK_DEV_AVAILABLE_NONE);
NM_DEVICE_WIMAX_GET_PRIVATE (self)->sdk_action_defer_id = 0;
update_availability (self, old_available);

View file

@ -300,14 +300,14 @@ modem_state_cb (NMModem *modem,
nm_device_recheck_available_connections (device);
}
if ((dev_state >= NM_DEVICE_STATE_DISCONNECTED) && !nm_device_is_available (device)) {
if ((dev_state >= NM_DEVICE_STATE_DISCONNECTED) && !nm_device_is_available (device, NM_DEVICE_CHECK_DEV_AVAILABLE_NONE)) {
nm_device_state_changed (device,
NM_DEVICE_STATE_UNAVAILABLE,
NM_DEVICE_STATE_REASON_MODEM_FAILED);
return;
}
if ((dev_state == NM_DEVICE_STATE_UNAVAILABLE) && nm_device_is_available (device)) {
if ((dev_state == NM_DEVICE_STATE_UNAVAILABLE) && nm_device_is_available (device, NM_DEVICE_CHECK_DEV_AVAILABLE_NONE)) {
nm_device_state_changed (device,
NM_DEVICE_STATE_DISCONNECTED,
NM_DEVICE_STATE_REASON_MODEM_AVAILABLE);
@ -394,6 +394,7 @@ check_connection_compatible (NMDevice *device, NMConnection *connection)
static gboolean
check_connection_available (NMDevice *device,
NMConnection *connection,
NMDeviceCheckConAvailableFlags flags,
const char *specific_object)
{
NMDeviceModem *self = NM_DEVICE_MODEM (device);
@ -583,24 +584,19 @@ set_enabled (NMDevice *device, gboolean enabled)
}
static gboolean
is_available (NMDevice *device)
is_available (NMDevice *device, NMDeviceCheckDevAvailableFlags flags)
{
NMDeviceModem *self = NM_DEVICE_MODEM (device);
NMDeviceModemPrivate *priv = NM_DEVICE_MODEM_GET_PRIVATE (device);
NMDeviceModemPrivate *priv = NM_DEVICE_MODEM_GET_PRIVATE (self);
NMModemState modem_state;
if (!priv->rf_enabled) {
_LOGD (LOGD_MB, "not available because WWAN airplane mode is on");
if (!priv->rf_enabled)
return FALSE;
}
g_assert (priv->modem);
modem_state = nm_modem_get_state (priv->modem);
if (modem_state <= NM_MODEM_STATE_INITIALIZING) {
_LOGD (LOGD_MB, "not available because modem is not ready (%s)",
nm_modem_state_to_string (modem_state));
if (modem_state <= NM_MODEM_STATE_INITIALIZING)
return FALSE;
}
return TRUE;
}

View file

@ -2538,7 +2538,7 @@ ensure_master_active_connection (NMManager *self,
if (!is_compatible_with_slave (candidate, connection))
continue;
if (nm_device_connection_is_available (master_device, candidate, TRUE)) {
if (nm_device_check_connection_available (master_device, candidate, NM_DEVICE_CHECK_CON_AVAILABLE_FOR_USER_REQUEST, NULL)) {
master_ac = nm_manager_activate_connection (self,
candidate,
NULL,
@ -2579,7 +2579,7 @@ ensure_master_active_connection (NMManager *self,
continue;
}
if (!nm_device_connection_is_available (candidate, master_connection, TRUE))
if (!nm_device_check_connection_available (candidate, master_connection, NM_DEVICE_CHECK_CON_AVAILABLE_FOR_USER_REQUEST, NULL))
continue;
found_device = TRUE;
@ -2696,7 +2696,7 @@ _internal_activate_device (NMManager *self, NMActiveConnection *active, GError *
* in the UNAVAILABLE state here. To ensure it can be activated
* immediately, we transition it to DISCONNECTED.
*/
if ( nm_device_is_available (device)
if ( nm_device_is_available (device, NM_DEVICE_CHECK_DEV_AVAILABLE_NONE)
&& (nm_device_get_state (device) == NM_DEVICE_STATE_UNAVAILABLE)) {
nm_device_state_changed (device,
NM_DEVICE_STATE_DISCONNECTED,
@ -2729,7 +2729,7 @@ _internal_activate_device (NMManager *self, NMActiveConnection *active, GError *
}
/* Final connection must be available on device */
if (!nm_device_connection_is_available (device, connection, TRUE)) {
if (!nm_device_check_connection_available (device, connection, NM_DEVICE_CHECK_CON_AVAILABLE_FOR_USER_REQUEST, NULL)) {
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));