diff options
author | Aleksander Morgado <aleksandermj@chromium.org> | 2023-03-30 10:52:53 +0000 |
---|---|---|
committer | Aleksander Morgado <aleksandermj@chromium.org> | 2023-05-03 12:12:18 +0000 |
commit | 45406e78e2c7ad7515f6b173d0759af6d89266a8 (patch) | |
tree | 7a8ef69beed763181c3fb4c4f91821f472f6ff86 | |
parent | bf2843ad77732f5fbe1ee04e7ad5415a60bf5eeb (diff) | |
download | ModemManager-45406e78e2c7ad7515f6b173d0759af6d89266a8.tar.gz |
iface-modem-3gpp: don't guess packet service state if modem can report it
In certain protocols like QMI or MBIM we may be able to report an
exact packet service state, so there is no need to guess it, as the
guess may not always be right.
The logic will track automatically whether modem-reported packet
service states are available, and use them if so. Otherwise, it'll try
to guess as we were doing before (e.g. if registered in EPS, packet
service is considered attached).
-rw-r--r-- | src/mm-iface-modem-3gpp.c | 86 | ||||
-rw-r--r-- | src/mm-iface-modem-3gpp.h | 3 |
2 files changed, 78 insertions, 11 deletions
diff --git a/src/mm-iface-modem-3gpp.c b/src/mm-iface-modem-3gpp.c index 6c3393189..2c479818c 100644 --- a/src/mm-iface-modem-3gpp.c +++ b/src/mm-iface-modem-3gpp.c @@ -73,6 +73,8 @@ typedef struct { /* Registration checks */ guint check_timeout_source; gboolean check_running; + /* Packet service state */ + gboolean packet_service_state_update_supported; } Private; static void @@ -298,6 +300,7 @@ get_consolidated_packet_service_state (MMIfaceModem3gpp *self) Private *priv; priv = get_private (self); + g_assert (!priv->packet_service_state_update_supported); /* If registered in any of PS, EPS or 5GS, then packet service domain is * implicitly attached. */ @@ -2063,6 +2066,9 @@ mm_iface_modem_3gpp_update_location (MMIfaceModem3gpp *self, /*****************************************************************************/ +static void update_packet_service_state (MMIfaceModem3gpp *self, + MMModem3gppPacketServiceState new_state); + static void update_registration_reload_current_registration_info_ready (MMIfaceModem3gpp *self, GAsyncResult *res, @@ -2075,6 +2081,10 @@ update_registration_reload_current_registration_info_ready (MMIfaceModem3gpp *se new_state = GPOINTER_TO_UINT (user_data); + /* Update packet service state if we don't support external updates */ + if (!priv->packet_service_state_update_supported) + update_packet_service_state (self, get_consolidated_packet_service_state (self)); + mm_obj_msg (self, "3GPP registration state changed (registering -> %s)", mm_modem_3gpp_registration_state_get_string (new_state)); mm_obj_info (self, "consolidated registration state: cs '%s', ps '%s', eps '%s', 5gs '%s' --> '%s'", @@ -2087,8 +2097,7 @@ update_registration_reload_current_registration_info_ready (MMIfaceModem3gpp *se /* The properties in the interface are bound to the properties * in the skeleton, so just updating here is enough */ g_object_set (self, - MM_IFACE_MODEM_3GPP_REGISTRATION_STATE, new_state, - MM_IFACE_MODEM_3GPP_PACKET_SERVICE_STATE, get_consolidated_packet_service_state (self), + MM_IFACE_MODEM_3GPP_REGISTRATION_STATE, new_state, NULL); mm_iface_modem_update_subsystem_state (MM_IFACE_MODEM (self), @@ -2107,11 +2116,15 @@ update_non_registered_state (MMIfaceModem3gpp *self, /* Not registered neither in home nor roaming network */ mm_iface_modem_3gpp_clear_current_operator (self); + /* No packet service if we're not registered. This change is done + * also when the device itself supports reporting the packet service + * state updates. */ + update_packet_service_state (self, MM_MODEM_3GPP_PACKET_SERVICE_STATE_DETACHED); + /* The property in the interface is bound to the property * in the skeleton, so just updating here is enough */ g_object_set (self, - MM_IFACE_MODEM_3GPP_REGISTRATION_STATE, new_state, - MM_IFACE_MODEM_3GPP_PACKET_SERVICE_STATE, MM_MODEM_3GPP_PACKET_SERVICE_STATE_DETACHED, + MM_IFACE_MODEM_3GPP_REGISTRATION_STATE, new_state, NULL); mm_iface_modem_update_subsystem_state ( @@ -2127,20 +2140,32 @@ static void update_registration_state (MMIfaceModem3gpp *self, MMModem3gppRegistrationState new_state) { - Private *priv; - MMModem3gppRegistrationState old_state = MM_MODEM_3GPP_REGISTRATION_STATE_UNKNOWN; - MMModem3gppPacketServiceState old_packet_service_state = MM_MODEM_3GPP_PACKET_SERVICE_STATE_UNKNOWN; + Private *priv; + MMModem3gppRegistrationState old_state = MM_MODEM_3GPP_REGISTRATION_STATE_UNKNOWN; priv = get_private (self); g_object_get (self, - MM_IFACE_MODEM_3GPP_REGISTRATION_STATE, &old_state, - MM_IFACE_MODEM_3GPP_PACKET_SERVICE_STATE, &old_packet_service_state, + MM_IFACE_MODEM_3GPP_REGISTRATION_STATE, &old_state, NULL); /* Only set new state if different */ - if (new_state == old_state && old_packet_service_state == get_consolidated_packet_service_state (self)) - return; + if (new_state == old_state) { + MMModem3gppPacketServiceState old_packet_service_state = MM_MODEM_3GPP_PACKET_SERVICE_STATE_UNKNOWN; + + /* If packet service updates are expected, we can ignore the packet service state as that + * info won't be used to build a consolidated packet service state */ + if (priv->packet_service_state_update_supported) + return; + + /* If packet service updates are not expected, also check whether there are changes + * in the consolidate packet service state */ + g_object_get (self, + MM_IFACE_MODEM_3GPP_PACKET_SERVICE_STATE, &old_packet_service_state, + NULL); + if (old_packet_service_state == get_consolidated_packet_service_state (self)) + return; + } if (mm_modem_3gpp_registration_state_is_registered (new_state)) { MMModemState modem_state; @@ -2220,6 +2245,45 @@ mm_iface_modem_3gpp_apply_deferred_registration_state (MMIfaceModem3gpp *self) } /*****************************************************************************/ +/* Packet service state as reported by the device */ + +static void +update_packet_service_state (MMIfaceModem3gpp *self, + MMModem3gppPacketServiceState new_state) +{ + MMModem3gppPacketServiceState old_state = MM_MODEM_3GPP_PACKET_SERVICE_STATE_UNKNOWN; + + g_object_get (self, + MM_IFACE_MODEM_3GPP_PACKET_SERVICE_STATE, &old_state, + NULL); + + /* Only set new state if different */ + if (old_state == new_state) + return; + + mm_obj_msg (self, "3GPP packet service state changed (%s -> %s)", + mm_modem_3gpp_packet_service_state_get_string (old_state), + mm_modem_3gpp_packet_service_state_get_string (new_state)); + + /* The properties in the interface are bound to the properties + * in the skeleton, so just updating here is enough */ + g_object_set (self, + MM_IFACE_MODEM_3GPP_PACKET_SERVICE_STATE, new_state, + NULL); +} + +void +mm_iface_modem_3gpp_update_packet_service_state (MMIfaceModem3gpp *self, + MMModem3gppPacketServiceState new_state) +{ + Private *priv; + + priv = get_private (self); + priv->packet_service_state_update_supported = TRUE; + update_packet_service_state (self, new_state); +} + +/*****************************************************************************/ /* Periodic registration checks */ #define REGISTRATION_CHECK_TIMEOUT_SEC 30 diff --git a/src/mm-iface-modem-3gpp.h b/src/mm-iface-modem-3gpp.h index 3925a583a..5054570f4 100644 --- a/src/mm-iface-modem-3gpp.h +++ b/src/mm-iface-modem-3gpp.h @@ -342,6 +342,9 @@ void mm_iface_modem_3gpp_update_5gs_registration_state (MMIfaceModem3gpp gboolean deferred); void mm_iface_modem_3gpp_apply_deferred_registration_state (MMIfaceModem3gpp *self); +void mm_iface_modem_3gpp_update_packet_service_state (MMIfaceModem3gpp *self, + MMModem3gppPacketServiceState state); + void mm_iface_modem_3gpp_update_subscription_state (MMIfaceModem3gpp *self, MMModem3gppSubscriptionState state); void mm_iface_modem_3gpp_update_access_technologies (MMIfaceModem3gpp *self, |