From 1445b5b2966db464ca1a2f164a49cebaacf9e68c Mon Sep 17 00:00:00 2001 From: Aleksander Morgado Date: Tue, 11 Dec 2018 15:50:41 +0100 Subject: [PATCH] wwan: rework when settings/device are blocked for autoconnection The reasons to block autoconnection at settings level are not the same as the ones to block autoconnection at device level. E.g. if the SIM-PIN is wrong, you may want to block autoconnection both at settings level (as the PIN configured in settings is wrong) and at device level (so that no other setting is tried automatically). For some other reasons, you may want to block autoconnection only at setting level (e.g. wrong APN). And for some other reasons you may want to block autoconnection at device level only (e.g. SIM missing), so that the autoconnection blocking is removed when the device goes away. This is especially important with SIM hotplug events processed by ModemManager, as a device without SIM will be removed from MM when a new SIM is inserted, so that a completely new object is exposed in MM with the newly detected SIM. https://github.com/NetworkManager/NetworkManager/pull/259 (cherry picked from commit 90e9695af541d0e13c5327466f1414b35a04c73d) --- src/devices/nm-device.c | 2 +- src/devices/nm-device.h | 2 ++ src/devices/wwan/nm-device-modem.c | 38 +++++++++++++++++++++++++----- src/nm-policy.c | 11 ++++----- 4 files changed, 39 insertions(+), 14 deletions(-) diff --git a/src/devices/nm-device.c b/src/devices/nm-device.c index 9ea665c8cb..186f184554 100644 --- a/src/devices/nm-device.c +++ b/src/devices/nm-device.c @@ -385,7 +385,7 @@ typedef struct _NMDevicePrivate { bool v4_route_table_initialized:1; bool v6_route_table_initialized:1; - NMDeviceAutoconnectBlockedFlags autoconnect_blocked_flags:4; + NMDeviceAutoconnectBlockedFlags autoconnect_blocked_flags:5; bool is_enslaved:1; bool master_ready_handled:1; diff --git a/src/devices/nm-device.h b/src/devices/nm-device.h index 8f376b20b4..3c703564bc 100644 --- a/src/devices/nm-device.h +++ b/src/devices/nm-device.h @@ -722,6 +722,8 @@ typedef enum { NM_DEVICE_AUTOCONNECT_BLOCKED_WRONG_PIN = (1LL << 1), NM_DEVICE_AUTOCONNECT_BLOCKED_MANUAL_DISCONNECT = (1LL << 2), + NM_DEVICE_AUTOCONNECT_BLOCKED_SIM_MISSING = (1LL << 3), + NM_DEVICE_AUTOCONNECT_BLOCKED_INIT_FAILED = (1LL << 4), _NM_DEVICE_AUTOCONNECT_BLOCKED_LAST, diff --git a/src/devices/wwan/nm-device-modem.c b/src/devices/wwan/nm-device-modem.c index 4119d5987a..8ff931aa5e 100644 --- a/src/devices/wwan/nm-device-modem.c +++ b/src/devices/wwan/nm-device-modem.c @@ -125,14 +125,40 @@ modem_prepare_result (NMModem *modem, if (success) nm_device_activate_schedule_stage2_device_config (device); else { - if (nm_device_state_reason_check (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. - */ + /* There are several reasons to block autoconnection at device level: + * + * - Wrong SIM-PIN: The device won't autoconnect because it doesn't make sense + * to retry the connection with the same PIN. This error also makes autoconnection + * blocked at settings level, so not even a modem unplug and replug will allow + * autoconnection again. It is somewhat redundant to block autoconnection at + * both device and setting level really. + * + * - SIM wrong or not inserted: If the modem is reporting a SIM not inserted error, + * we can block autoconnection at device level, so that if the same device is + * unplugged and replugged with a SIM (or if a SIM hotplug event happens in MM, + * recreating the device completely), we can try the autoconnection again. + * + * - Modem initialization failed: For some reason unknown to NM, the modem wasn't + * initialized correctly, which leads to an unusable device. A device unplug and + * replug may solve the issue, so make it a device-level autoconnection blocking + * reason. + */ + switch (nm_device_state_reason_check (reason)) { + case NM_DEVICE_STATE_REASON_GSM_SIM_PIN_REQUIRED: + case NM_DEVICE_STATE_REASON_GSM_SIM_PUK_REQUIRED: + case NM_DEVICE_STATE_REASON_SIM_PIN_INCORRECT: nm_device_autoconnect_blocked_set (device, NM_DEVICE_AUTOCONNECT_BLOCKED_WRONG_PIN); + break; + case NM_DEVICE_STATE_REASON_GSM_SIM_NOT_INSERTED: + case NM_DEVICE_STATE_REASON_GSM_SIM_WRONG: + nm_device_autoconnect_blocked_set (device, NM_DEVICE_AUTOCONNECT_BLOCKED_SIM_MISSING); + break; + case NM_DEVICE_STATE_REASON_MODEM_INIT_FAILED: + nm_device_autoconnect_blocked_set (device, NM_DEVICE_AUTOCONNECT_BLOCKED_INIT_FAILED); + break; + default: + break; } - nm_device_state_changed (device, NM_DEVICE_STATE_FAILED, reason); } } diff --git a/src/nm-policy.c b/src/nm-policy.c index 7f8c665c30..a59601053f 100644 --- a/src/nm-policy.c +++ b/src/nm-policy.c @@ -1751,17 +1751,14 @@ device_state_changed (NMDevice *device, NMSettingConnection *s_con = NULL; switch (nm_device_state_reason_check (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. + /* Block autoconnection at settings level if there is any settings-specific + * error reported by the modem (e.g. wrong SIM-PIN or wrong APN). Do not block + * autoconnection at settings level for errors in the device domain (e.g. + * a missing SIM or wrong modem initialization). */ if (sett_conn) { nm_settings_connection_autoconnect_blocked_reason_set (sett_conn,