summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDan Williams <dcbw@redhat.com>2013-05-31 15:22:07 -0500
committerDan Williams <dcbw@redhat.com>2014-05-06 14:15:50 -0500
commitbb1fece6e6bdae53bc8383d300fa866150032ebc (patch)
tree35c881f4485c5e9603f6888a236b8997f7301056
parent5d8197a80bef620d0ce364e9b7b1fd2b85265982 (diff)
downloadNetworkManager-bb1fece6e6bdae53bc8383d300fa866150032ebc.tar.gz
wwan: make device available whenever it's not rfkilled
Since the ModemManager enabled/disabled state is a user-changable one, and since NM can enable the modem when starting a connection, allow modems to be available for activation whenever they are not in airplane mode. This makes WWAN autoconnect=true connections actually autoconnect. If the first connection fails during ModemManager setup for fatal reasons (missing SIM, bad PIN, not registered), autoconnect will be blocked for that connection until activation is manually requested and succeeds.
-rw-r--r--src/devices/wwan/nm-device-modem.c63
1 files changed, 48 insertions, 15 deletions
diff --git a/src/devices/wwan/nm-device-modem.c b/src/devices/wwan/nm-device-modem.c
index 5cadbf1014..68619fde3f 100644
--- a/src/devices/wwan/nm-device-modem.c
+++ b/src/devices/wwan/nm-device-modem.c
@@ -44,6 +44,7 @@ typedef struct {
NMModem *modem;
NMDeviceModemCapabilities caps;
NMDeviceModemCapabilities current_caps;
+ gboolean rf_enabled;
} NMDeviceModemPrivate;
enum {
@@ -53,8 +54,6 @@ enum {
PROP_CURRENT_CAPABILITIES,
};
-static void set_enabled (NMDevice *device, gboolean enabled);
-
/*****************************************************************************/
static void
@@ -168,8 +167,24 @@ data_port_changed_cb (NMModem *modem, GParamSpec *pspec, gpointer user_data)
static void
modem_enabled_cb (NMModem *modem, GParamSpec *pspec, gpointer user_data)
{
- set_enabled (NM_DEVICE (user_data), nm_modem_get_mm_enabled (modem));
- nm_device_emit_recheck_auto_activate (NM_DEVICE (user_data));
+ NMDevice *device = NM_DEVICE (user_data);
+ NMDeviceModemPrivate *priv = NM_DEVICE_MODEM_GET_PRIVATE (device);
+ NMDeviceState state;
+
+ /* Called when the ModemManager modem enabled state is changed externally
+ * to NetworkManager (eg something using MM's D-Bus API directly).
+ */
+
+ if (priv->rf_enabled && nm_modem_get_mm_enabled (modem) == FALSE) {
+ state = nm_device_get_state (device);
+ if (nm_device_is_activating (device) || state == NM_DEVICE_STATE_ACTIVATED) {
+ /* user-initiated action, hence DISCONNECTED not FAILED */
+ nm_device_state_changed (device,
+ NM_DEVICE_STATE_DISCONNECTED,
+ NM_DEVICE_STATE_REASON_USER_REQUESTED);
+ }
+ }
+ nm_device_emit_recheck_auto_activate (device);
}
static void
@@ -321,7 +336,9 @@ act_stage3_ip6_config_start (NMDevice *device,
static gboolean
get_enabled (NMDevice *device)
{
- return nm_modem_get_mm_enabled (NM_DEVICE_MODEM_GET_PRIVATE (device)->modem);
+ NMDeviceModemPrivate *priv = NM_DEVICE_MODEM_GET_PRIVATE (device);
+
+ return priv->rf_enabled && nm_modem_get_mm_enabled (priv->modem);
}
static void
@@ -329,21 +346,36 @@ set_enabled (NMDevice *device, gboolean enabled)
{
NMDeviceModem *self = NM_DEVICE_MODEM (device);
NMDeviceModemPrivate *priv = NM_DEVICE_MODEM_GET_PRIVATE (self);
- NMDeviceState state;
+
+ /* Called only by the Manager in response to rfkill switch changes or
+ * global user WWAN enable/disable preference changes.
+ */
+ priv->rf_enabled = enabled;
if (priv->modem) {
+ /* Sync the ModemManager modem enabled/disabled with rfkill/user preference */
nm_modem_set_mm_enabled (priv->modem, enabled);
+ }
- if (enabled == FALSE) {
- state = nm_device_get_state (device);
- if (nm_device_is_activating (device) || state == NM_DEVICE_STATE_ACTIVATED) {
- /* user-initiated action, hence DISCONNECTED not FAILED */
- nm_device_state_changed (device,
- NM_DEVICE_STATE_DISCONNECTED,
- NM_DEVICE_STATE_REASON_USER_REQUESTED);
- }
- }
+ if (enabled == FALSE) {
+ nm_device_state_changed (device,
+ NM_DEVICE_STATE_UNAVAILABLE,
+ NM_DEVICE_STATE_REASON_NONE);
+ }
+}
+
+static gboolean
+is_available (NMDevice *dev)
+{
+ NMDeviceModemPrivate *priv = NM_DEVICE_MODEM_GET_PRIVATE (dev);
+
+ /* The device is available whenever it's not rfkilled */
+ if (!priv->rf_enabled) {
+ nm_log_dbg (LOGD_MB, "(%s): not available because WWAN airplane mode is on",
+ nm_device_get_iface (dev));
}
+
+ return priv->rf_enabled;
}
/*****************************************************************************/
@@ -492,6 +524,7 @@ nm_device_modem_class_init (NMDeviceModemClass *mclass)
device_class->get_enabled = get_enabled;
device_class->set_enabled = set_enabled;
device_class->owns_iface = owns_iface;
+ device_class->is_available = is_available;
device_class->state_changed = device_state_changed;