summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAleksander Morgado <aleksandermj@chromium.org>2023-03-30 10:52:53 +0000
committerAleksander Morgado <aleksandermj@chromium.org>2023-05-03 12:12:18 +0000
commit45406e78e2c7ad7515f6b173d0759af6d89266a8 (patch)
tree7a8ef69beed763181c3fb4c4f91821f472f6ff86
parentbf2843ad77732f5fbe1ee04e7ad5415a60bf5eeb (diff)
downloadModemManager-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.c86
-rw-r--r--src/mm-iface-modem-3gpp.h3
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,