diff --git a/include/NetworkManager.h b/include/NetworkManager.h
index e0df39be4c..3fee1af00d 100644
--- a/include/NetworkManager.h
+++ b/include/NetworkManager.h
@@ -558,6 +558,9 @@ typedef enum {
/* Modem now ready and available */
NM_DEVICE_STATE_REASON_MODEM_AVAILABLE = 58,
+ /* SIM PIN was incorrect */
+ NM_DEVICE_STATE_REASON_SIM_PIN_INCORRECT = 59,
+
/* Unused */
NM_DEVICE_STATE_REASON_LAST = 0xFFFF
} NMDeviceStateReason;
diff --git a/introspection/nm-device.xml b/introspection/nm-device.xml
index 34afcfc2a8..f459bce4f5 100644
--- a/introspection/nm-device.xml
+++ b/introspection/nm-device.xml
@@ -622,6 +622,11 @@
Modem now ready and available.
+
+
+ The SIM PIN was incorrect.
+
+
diff --git a/src/devices/bluetooth/nm-device-bt.c b/src/devices/bluetooth/nm-device-bt.c
index 35c44763c4..f9dedebd80 100644
--- a/src/devices/bluetooth/nm-device-bt.c
+++ b/src/devices/bluetooth/nm-device-bt.c
@@ -487,8 +487,19 @@ modem_prepare_result (NMModem *modem,
nm_device_state_changed (device, NM_DEVICE_STATE_FAILED, stage2_reason);
break;
}
- } else
+ } else {
+ if (reason == NM_DEVICE_STATE_REASON_SIM_PIN_INCORRECT) {
+ /* If the connect failed because the SIM PIN was wrong don't allow
+ * the device to be auto-activated anymore, which would risk locking
+ * the SIM if the incorrect PIN continues to be used.
+ */
+ g_object_set (G_OBJECT (device), NM_DEVICE_AUTOCONNECT, FALSE, NULL);
+ nm_log_info (LOGD_MB, "(%s): disabling autoconnect due to failed SIM PIN",
+ nm_device_get_iface (device));
+ }
+
nm_device_state_changed (device, NM_DEVICE_STATE_FAILED, reason);
+ }
}
static void
diff --git a/src/devices/nm-device.c b/src/devices/nm-device.c
index cd1de57f55..df2a1408cb 100644
--- a/src/devices/nm-device.c
+++ b/src/devices/nm-device.c
@@ -6577,6 +6577,8 @@ reason_to_string (NMDeviceStateReason reason)
return "modem-failed";
case NM_DEVICE_STATE_REASON_MODEM_AVAILABLE:
return "modem-available";
+ case NM_DEVICE_STATE_REASON_SIM_PIN_INCORRECT:
+ return "sim-pin-incorrect";
default:
break;
}
diff --git a/src/devices/wwan/nm-device-modem.c b/src/devices/wwan/nm-device-modem.c
index 7bf2560c93..b686967ab5 100644
--- a/src/devices/wwan/nm-device-modem.c
+++ b/src/devices/wwan/nm-device-modem.c
@@ -29,6 +29,7 @@
#include "nm-rfkill-manager.h"
#include "nm-logging.h"
#include "nm-dbus-manager.h"
+#include "nm-settings-connection.h"
#if WITH_MODEM_MANAGER_1
#include "nm-modem-broadband.h"
@@ -98,8 +99,19 @@ modem_prepare_result (NMModem *modem,
if (success)
nm_device_activate_schedule_stage2_device_config (device);
- else
+ else {
+ if (reason == NM_DEVICE_STATE_REASON_SIM_PIN_INCORRECT) {
+ /* If the connect failed because the SIM PIN was wrong don't allow
+ * the device to be auto-activated anymore, which would risk locking
+ * the SIM if the incorrect PIN continues to be used.
+ */
+ g_object_set (G_OBJECT (device), NM_DEVICE_AUTOCONNECT, FALSE, NULL);
+ nm_log_info (LOGD_MB, "(%s): disabling autoconnect due to failed SIM PIN",
+ nm_device_get_iface (device));
+ }
+
nm_device_state_changed (device, NM_DEVICE_STATE_FAILED, reason);
+ }
}
static void
@@ -255,6 +267,7 @@ device_state_changed (NMDevice *device,
NMDeviceStateReason reason)
{
NMDeviceModemPrivate *priv = NM_DEVICE_MODEM_GET_PRIVATE (device);
+ NMConnection *connection = nm_device_get_connection (device);
g_assert (priv->modem);
@@ -267,6 +280,26 @@ device_state_changed (NMDevice *device,
}
nm_modem_device_state_changed (priv->modem, new_state, old_state, reason);
+
+ switch (reason) {
+ case NM_DEVICE_STATE_REASON_GSM_REGISTRATION_DENIED:
+ case NM_DEVICE_STATE_REASON_GSM_REGISTRATION_NOT_SEARCHING:
+ case NM_DEVICE_STATE_REASON_GSM_SIM_NOT_INSERTED:
+ case NM_DEVICE_STATE_REASON_GSM_SIM_PIN_REQUIRED:
+ case NM_DEVICE_STATE_REASON_GSM_SIM_PUK_REQUIRED:
+ case NM_DEVICE_STATE_REASON_GSM_SIM_WRONG:
+ case NM_DEVICE_STATE_REASON_SIM_PIN_INCORRECT:
+ case NM_DEVICE_STATE_REASON_MODEM_INIT_FAILED:
+ case NM_DEVICE_STATE_REASON_GSM_APN_FAILED:
+ /* Block autoconnect of the just-failed connection for situations
+ * where a retry attempt would just fail again.
+ */
+ if (connection)
+ nm_settings_connection_set_autoconnect_blocked_reason (NM_SETTINGS_CONNECTION (connection), reason);
+ break;
+ default:
+ break;
+ }
}
static guint
diff --git a/src/devices/wwan/nm-modem-broadband.c b/src/devices/wwan/nm-modem-broadband.c
index 83bf4a2657..d0daaa30dd 100644
--- a/src/devices/wwan/nm-modem-broadband.c
+++ b/src/devices/wwan/nm-modem-broadband.c
@@ -90,6 +90,8 @@ translate_mm_error (GError *error)
reason = NM_DEVICE_STATE_REASON_GSM_SIM_PUK_REQUIRED;
else if (g_error_matches (error, MM_MOBILE_EQUIPMENT_ERROR, MM_MOBILE_EQUIPMENT_ERROR_SIM_WRONG))
reason = NM_DEVICE_STATE_REASON_GSM_SIM_WRONG;
+ else if (g_error_matches (error, MM_MOBILE_EQUIPMENT_ERROR, MM_MOBILE_EQUIPMENT_ERROR_INCORRECT_PASSWORD))
+ reason = NM_DEVICE_STATE_REASON_SIM_PIN_INCORRECT;
else {
/* unable to map the ModemManager error to a NM_DEVICE_STATE_REASON */
nm_log_dbg (LOGD_MB, "unmapped error detected: '%s'", error->message);
diff --git a/src/devices/wwan/nm-modem-old-types.h b/src/devices/wwan/nm-modem-old-types.h
index 976605db2b..84065a6841 100644
--- a/src/devices/wwan/nm-modem-old-types.h
+++ b/src/devices/wwan/nm-modem-old-types.h
@@ -50,6 +50,7 @@
#define MM_OLD_MODEM_ERROR_SIM_PIN MM_OLD_MODEM_ERROR ".SimPinRequired"
#define MM_OLD_MODEM_ERROR_SIM_PUK MM_OLD_MODEM_ERROR ".SimPukRequired"
#define MM_OLD_MODEM_ERROR_SIM_WRONG MM_OLD_MODEM_ERROR ".SimWrong"
+#define MM_OLD_MODEM_ERROR_WRONG_PASSWORD MM_OLD_MODEM_ERROR ".IncorrectPassword"
typedef enum {
MM_OLD_MODEM_STATE_UNKNOWN = 0,
diff --git a/src/devices/wwan/nm-modem-old.c b/src/devices/wwan/nm-modem-old.c
index 708d318357..917c37fe6c 100644
--- a/src/devices/wwan/nm-modem-old.c
+++ b/src/devices/wwan/nm-modem-old.c
@@ -124,6 +124,8 @@ translate_mm_error (GError *error)
reason = NM_DEVICE_STATE_REASON_GSM_SIM_PUK_REQUIRED;
else if (dbus_g_error_has_name (error, MM_OLD_MODEM_ERROR_SIM_WRONG))
reason = NM_DEVICE_STATE_REASON_GSM_SIM_WRONG;
+ else if (dbus_g_error_has_name (error, MM_OLD_MODEM_ERROR_WRONG_PASSWORD))
+ reason = NM_DEVICE_STATE_REASON_SIM_PIN_INCORRECT;
else {
/* unable to map the ModemManager error to a NM_DEVICE_STATE_REASON */
nm_log_dbg (LOGD_MB, "unmapped dbus error detected: '%s'", dbus_g_error_get_name (error));