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));