iface-modem-3gpp: allow applying domain registration updates altogether

When processing QMI and MBIM messages to report domain registration
updates, we should do that altogether so that we don't report bogus
transitions to idle if the registration state switches from one domain
to another.

Fixes https://gitlab.freedesktop.org/mobile-broadband/ModemManager/-/issues/629
This commit is contained in:
Aleksander Morgado
2022-09-16 10:07:25 +00:00
committed by Aleksander Morgado
parent 453e8bc7d1
commit 1fa67b3842
5 changed files with 90 additions and 54 deletions

View File

@@ -4484,12 +4484,13 @@ update_registration_info (MMBroadbandModemMbim *self,
if (available_data_classes & (MBIM_DATA_CLASS_5G_NSA | MBIM_DATA_CLASS_5G_SA))
reg_state_5gs = reg_state;
mm_iface_modem_3gpp_update_cs_registration_state (MM_IFACE_MODEM_3GPP (self), reg_state_cs);
mm_iface_modem_3gpp_update_ps_registration_state (MM_IFACE_MODEM_3GPP (self), reg_state_ps);
mm_iface_modem_3gpp_update_cs_registration_state (MM_IFACE_MODEM_3GPP (self), reg_state_cs, TRUE);
mm_iface_modem_3gpp_update_ps_registration_state (MM_IFACE_MODEM_3GPP (self), reg_state_ps, TRUE);
if (mm_iface_modem_is_3gpp_lte (MM_IFACE_MODEM (self)))
mm_iface_modem_3gpp_update_eps_registration_state (MM_IFACE_MODEM_3GPP (self), reg_state_eps);
mm_iface_modem_3gpp_update_eps_registration_state (MM_IFACE_MODEM_3GPP (self), reg_state_eps, TRUE);
if (mm_iface_modem_is_3gpp_5gnr (MM_IFACE_MODEM (self)))
mm_iface_modem_3gpp_update_5gs_registration_state (MM_IFACE_MODEM_3GPP (self), reg_state_5gs);
mm_iface_modem_3gpp_update_5gs_registration_state (MM_IFACE_MODEM_3GPP (self), reg_state_5gs, TRUE);
mm_iface_modem_3gpp_apply_deferred_registration_state (MM_IFACE_MODEM_3GPP (self));
/* request to reload operator info explicitly, so that the new
* operator name and code is propagated to the DBus interface */

View File

@@ -3143,12 +3143,13 @@ common_process_serving_system_3gpp (MMBroadbandModemQmi *self,
else
reg_state_3gpp = MM_MODEM_3GPP_REGISTRATION_STATE_UNKNOWN;
mm_iface_modem_3gpp_update_cs_registration_state (MM_IFACE_MODEM_3GPP (self), reg_state_3gpp);
mm_iface_modem_3gpp_update_ps_registration_state (MM_IFACE_MODEM_3GPP (self), reg_state_3gpp);
mm_iface_modem_3gpp_update_cs_registration_state (MM_IFACE_MODEM_3GPP (self), reg_state_3gpp, TRUE);
mm_iface_modem_3gpp_update_ps_registration_state (MM_IFACE_MODEM_3GPP (self), reg_state_3gpp, TRUE);
if (mm_iface_modem_is_3gpp_lte (MM_IFACE_MODEM (self)))
mm_iface_modem_3gpp_update_eps_registration_state (MM_IFACE_MODEM_3GPP (self), reg_state_3gpp);
mm_iface_modem_3gpp_update_eps_registration_state (MM_IFACE_MODEM_3GPP (self), reg_state_3gpp, TRUE);
if (mm_iface_modem_is_3gpp_5gnr (MM_IFACE_MODEM (self)))
mm_iface_modem_3gpp_update_5gs_registration_state (MM_IFACE_MODEM_3GPP (self), reg_state_3gpp);
mm_iface_modem_3gpp_update_5gs_registration_state (MM_IFACE_MODEM_3GPP (self), reg_state_3gpp, TRUE);
mm_iface_modem_3gpp_apply_deferred_registration_state (MM_IFACE_MODEM_3GPP (self));
mm_iface_modem_3gpp_update_access_technologies (MM_IFACE_MODEM_3GPP (self), MM_MODEM_ACCESS_TECHNOLOGY_UNKNOWN);
mm_iface_modem_3gpp_update_location (MM_IFACE_MODEM_3GPP (self), 0, 0, 0);
@@ -3251,17 +3252,20 @@ common_process_serving_system_3gpp (MMBroadbandModemQmi *self,
* state as unknown, so that the "PS" one takes precedence when building
* the consolidated registration state (otherwise we may be using some old cached
* "EPS" state wrongly). */
mm_iface_modem_3gpp_update_cs_registration_state (MM_IFACE_MODEM_3GPP (self), mm_cs_registration_state);
mm_iface_modem_3gpp_update_ps_registration_state (MM_IFACE_MODEM_3GPP (self), mm_ps_registration_state);
mm_iface_modem_3gpp_update_cs_registration_state (MM_IFACE_MODEM_3GPP (self), mm_cs_registration_state, TRUE);
mm_iface_modem_3gpp_update_ps_registration_state (MM_IFACE_MODEM_3GPP (self), mm_ps_registration_state, TRUE);
if (mm_iface_modem_is_3gpp_lte (MM_IFACE_MODEM (self)))
mm_iface_modem_3gpp_update_eps_registration_state (MM_IFACE_MODEM_3GPP (self),
(mm_access_technologies & MM_MODEM_ACCESS_TECHNOLOGY_LTE) ?
mm_ps_registration_state : MM_MODEM_3GPP_REGISTRATION_STATE_UNKNOWN);
((mm_access_technologies & MM_MODEM_ACCESS_TECHNOLOGY_LTE) ?
mm_ps_registration_state : MM_MODEM_3GPP_REGISTRATION_STATE_UNKNOWN),
TRUE);
/* Same thing for "5GS" state */
if (mm_iface_modem_is_3gpp_5gnr (MM_IFACE_MODEM (self)))
mm_iface_modem_3gpp_update_5gs_registration_state (MM_IFACE_MODEM_3GPP (self),
(mm_access_technologies & MM_MODEM_ACCESS_TECHNOLOGY_5GNR) ?
mm_ps_registration_state : MM_MODEM_3GPP_REGISTRATION_STATE_UNKNOWN);
((mm_access_technologies & MM_MODEM_ACCESS_TECHNOLOGY_5GNR) ?
mm_ps_registration_state : MM_MODEM_3GPP_REGISTRATION_STATE_UNKNOWN),
TRUE);
mm_iface_modem_3gpp_apply_deferred_registration_state (MM_IFACE_MODEM_3GPP (self));
mm_iface_modem_3gpp_update_access_technologies (MM_IFACE_MODEM_3GPP (self), mm_access_technologies);
/* Get 3GPP location LAC/TAC and CI */
@@ -3881,9 +3885,10 @@ consolidated_update_ps_registration_state (MMBroadbandModemQmi *self,
g_assert_not_reached ();
}
mm_iface_modem_3gpp_update_ps_registration_state (MM_IFACE_MODEM_3GPP (self), state_ps);
mm_iface_modem_3gpp_update_eps_registration_state (MM_IFACE_MODEM_3GPP (self), is_eps ? state_ps : MM_MODEM_3GPP_REGISTRATION_STATE_UNKNOWN);
mm_iface_modem_3gpp_update_5gs_registration_state (MM_IFACE_MODEM_3GPP (self), is_5gs ? state_ps : MM_MODEM_3GPP_REGISTRATION_STATE_UNKNOWN);
mm_iface_modem_3gpp_update_ps_registration_state (MM_IFACE_MODEM_3GPP (self), state_ps, TRUE);
mm_iface_modem_3gpp_update_eps_registration_state (MM_IFACE_MODEM_3GPP (self), is_eps ? state_ps : MM_MODEM_3GPP_REGISTRATION_STATE_UNKNOWN, TRUE);
mm_iface_modem_3gpp_update_5gs_registration_state (MM_IFACE_MODEM_3GPP (self), is_5gs ? state_ps : MM_MODEM_3GPP_REGISTRATION_STATE_UNKNOWN, TRUE);
mm_iface_modem_3gpp_apply_deferred_registration_state (MM_IFACE_MODEM_3GPP (self));
}
static void
@@ -3952,9 +3957,9 @@ common_process_system_info_3gpp (MMBroadbandModemQmi *self,
self->priv->current_operator_id = operator_id;
}
/* Report new registration states */
mm_iface_modem_3gpp_update_cs_registration_state (MM_IFACE_MODEM_3GPP (self), cs_registration_state);
/* Report new registration states.
* Note: consolidated_update_ps_registration_state() calls apply_deferred_registration_state() always */
mm_iface_modem_3gpp_update_cs_registration_state (MM_IFACE_MODEM_3GPP (self), cs_registration_state, TRUE);
/* Store PS system reg state and update PS/EPS/5GS states accordingly */
self->priv->system_info_ps_registration_state = ps_registration_state;
consolidated_update_ps_registration_state (self, has_lte_info, has_nr5g_info);

View File

@@ -4827,21 +4827,21 @@ registration_state_changed (MMPortSerialAt *port,
* - CEREG/C5GREG always reports TAC
*/
if (cgreg)
mm_iface_modem_3gpp_update_ps_registration_state (MM_IFACE_MODEM_3GPP (self), state);
mm_iface_modem_3gpp_update_ps_registration_state (MM_IFACE_MODEM_3GPP (self), state, FALSE);
else if (cereg) {
tac = lac;
lac = 0;
mm_iface_modem_3gpp_update_eps_registration_state (MM_IFACE_MODEM_3GPP (self), state);
mm_iface_modem_3gpp_update_eps_registration_state (MM_IFACE_MODEM_3GPP (self), state, FALSE);
} else if (c5greg) {
tac = lac;
lac = 0;
mm_iface_modem_3gpp_update_5gs_registration_state (MM_IFACE_MODEM_3GPP (self), state);
mm_iface_modem_3gpp_update_5gs_registration_state (MM_IFACE_MODEM_3GPP (self), state, FALSE);
} else {
if (act == MM_MODEM_ACCESS_TECHNOLOGY_LTE) {
tac = lac;
lac = 0;
}
mm_iface_modem_3gpp_update_cs_registration_state (MM_IFACE_MODEM_3GPP (self), state);
mm_iface_modem_3gpp_update_cs_registration_state (MM_IFACE_MODEM_3GPP (self), state, FALSE);
}
/* Only update access technologies from CREG/CGREG response if the modem
@@ -5248,7 +5248,7 @@ registration_status_check_ready (MMBroadbandModem *self,
mm_obj_dbg (self, "got PS registration state when checking EPS registration state");
else if (ctx->running_5gs)
mm_obj_dbg (self, "got PS registration state when checking 5GS registration state");
mm_iface_modem_3gpp_update_ps_registration_state (MM_IFACE_MODEM_3GPP (self), state);
mm_iface_modem_3gpp_update_ps_registration_state (MM_IFACE_MODEM_3GPP (self), state, FALSE);
} else if (cereg) {
tac = lac;
lac = 0;
@@ -5258,7 +5258,7 @@ registration_status_check_ready (MMBroadbandModem *self,
mm_obj_dbg (self, "got EPS registration state when checking PS registration state");
else if (ctx->running_5gs)
mm_obj_dbg (self, "got EPS registration state when checking 5GS registration state");
mm_iface_modem_3gpp_update_eps_registration_state (MM_IFACE_MODEM_3GPP (self), state);
mm_iface_modem_3gpp_update_eps_registration_state (MM_IFACE_MODEM_3GPP (self), state, FALSE);
} else if (c5greg) {
tac = lac;
lac = 0;
@@ -5268,7 +5268,7 @@ registration_status_check_ready (MMBroadbandModem *self,
mm_obj_dbg (self, "got 5GS registration state when checking PS registration state");
else if (ctx->running_eps)
mm_obj_dbg (self, "got 5GS registration state when checking EPS registration state");
mm_iface_modem_3gpp_update_5gs_registration_state (MM_IFACE_MODEM_3GPP (self), state);
mm_iface_modem_3gpp_update_5gs_registration_state (MM_IFACE_MODEM_3GPP (self), state, FALSE);
} else {
if (act == MM_MODEM_ACCESS_TECHNOLOGY_LTE) {
tac = lac;
@@ -5280,7 +5280,7 @@ registration_status_check_ready (MMBroadbandModem *self,
mm_obj_dbg (self, "got CS registration state when checking EPS registration state");
else if (ctx->running_5gs)
mm_obj_dbg (self, "got CS registration state when checking 5GS registration state");
mm_iface_modem_3gpp_update_cs_registration_state (MM_IFACE_MODEM_3GPP (self), state);
mm_iface_modem_3gpp_update_cs_registration_state (MM_IFACE_MODEM_3GPP (self), state, FALSE);
}
mm_iface_modem_3gpp_update_access_technologies (MM_IFACE_MODEM_3GPP (self), act);

View File

@@ -424,12 +424,14 @@ register_in_network_context_complete_failed (GTask *task,
ctx = g_task_get_task_data (task);
mm_iface_modem_3gpp_update_cs_registration_state (ctx->self, MM_MODEM_3GPP_REGISTRATION_STATE_IDLE);
mm_iface_modem_3gpp_update_ps_registration_state (ctx->self, MM_MODEM_3GPP_REGISTRATION_STATE_IDLE);
mm_iface_modem_3gpp_update_eps_registration_state (ctx->self, MM_MODEM_3GPP_REGISTRATION_STATE_IDLE);
mm_iface_modem_3gpp_update_5gs_registration_state (ctx->self, MM_MODEM_3GPP_REGISTRATION_STATE_IDLE);
mm_iface_modem_3gpp_update_access_technologies (ctx->self, MM_MODEM_ACCESS_TECHNOLOGY_UNKNOWN);
mm_iface_modem_3gpp_update_location (ctx->self, 0, 0, 0);
mm_iface_modem_3gpp_update_cs_registration_state (ctx->self, MM_MODEM_3GPP_REGISTRATION_STATE_IDLE, TRUE);
mm_iface_modem_3gpp_update_ps_registration_state (ctx->self, MM_MODEM_3GPP_REGISTRATION_STATE_IDLE, TRUE);
mm_iface_modem_3gpp_update_eps_registration_state (ctx->self, MM_MODEM_3GPP_REGISTRATION_STATE_IDLE, TRUE);
mm_iface_modem_3gpp_update_5gs_registration_state (ctx->self, MM_MODEM_3GPP_REGISTRATION_STATE_IDLE, TRUE);
mm_iface_modem_3gpp_apply_deferred_registration_state (ctx->self);
mm_iface_modem_3gpp_update_access_technologies (ctx->self, MM_MODEM_ACCESS_TECHNOLOGY_UNKNOWN);
mm_iface_modem_3gpp_update_location (ctx->self, 0, 0, 0);
g_task_return_error (task, error);
g_object_unref (task);
@@ -2072,8 +2074,7 @@ update_non_registered_state (MMIfaceModem3gpp *self,
static void
update_registration_state (MMIfaceModem3gpp *self,
MMModem3gppRegistrationState new_state,
gboolean deferrable)
MMModem3gppRegistrationState new_state)
{
Private *priv;
MMModem3gppRegistrationState old_state = MM_MODEM_3GPP_REGISTRATION_STATE_UNKNOWN;
@@ -2140,7 +2141,8 @@ update_registration_state (MMIfaceModem3gpp *self,
void
mm_iface_modem_3gpp_update_cs_registration_state (MMIfaceModem3gpp *self,
MMModem3gppRegistrationState state)
MMModem3gppRegistrationState state,
gboolean deferred)
{
Private *priv;
gboolean supported = FALSE;
@@ -2154,12 +2156,15 @@ mm_iface_modem_3gpp_update_cs_registration_state (MMIfaceModem3gpp *
priv = get_private (self);
priv->state_cs = state;
update_registration_state (self, get_consolidated_reg_state (self), TRUE);
if (!deferred)
mm_iface_modem_3gpp_apply_deferred_registration_state (self);
}
void
mm_iface_modem_3gpp_update_ps_registration_state (MMIfaceModem3gpp *self,
MMModem3gppRegistrationState state)
MMModem3gppRegistrationState state,
gboolean deferred)
{
Private *priv;
gboolean supported = FALSE;
@@ -2173,12 +2178,15 @@ mm_iface_modem_3gpp_update_ps_registration_state (MMIfaceModem3gpp *
priv = get_private (self);
priv->state_ps = state;
update_registration_state (self, get_consolidated_reg_state (self), TRUE);
if (!deferred)
mm_iface_modem_3gpp_apply_deferred_registration_state (self);
}
void
mm_iface_modem_3gpp_update_eps_registration_state (MMIfaceModem3gpp *self,
MMModem3gppRegistrationState state)
MMModem3gppRegistrationState state,
gboolean deferred)
{
Private *priv;
gboolean supported = FALSE;
@@ -2192,12 +2200,15 @@ mm_iface_modem_3gpp_update_eps_registration_state (MMIfaceModem3gpp
priv = get_private (self);
priv->state_eps = state;
update_registration_state (self, get_consolidated_reg_state (self), TRUE);
if (!deferred)
mm_iface_modem_3gpp_apply_deferred_registration_state (self);
}
void
mm_iface_modem_3gpp_update_5gs_registration_state (MMIfaceModem3gpp *self,
MMModem3gppRegistrationState state)
MMModem3gppRegistrationState state,
gboolean deferred)
{
Private *priv;
gboolean supported = FALSE;
@@ -2211,7 +2222,15 @@ mm_iface_modem_3gpp_update_5gs_registration_state (MMIfaceModem3gpp
priv = get_private (self);
priv->state_5gs = state;
update_registration_state (self, get_consolidated_reg_state (self), TRUE);
if (!deferred)
mm_iface_modem_3gpp_apply_deferred_registration_state (self);
}
void
mm_iface_modem_3gpp_apply_deferred_registration_state (MMIfaceModem3gpp *self)
{
update_registration_state (self, get_consolidated_reg_state (self));
}
/*****************************************************************************/
@@ -2556,7 +2575,7 @@ interface_disabling_step (GTask *task)
/* fall through */
case DISABLING_STEP_REGISTRATION_STATE:
update_registration_state (self, MM_MODEM_3GPP_REGISTRATION_STATE_UNKNOWN, FALSE);
update_registration_state (self, MM_MODEM_3GPP_REGISTRATION_STATE_UNKNOWN);
mm_iface_modem_3gpp_update_access_technologies (self, MM_MODEM_ACCESS_TECHNOLOGY_UNKNOWN);
mm_iface_modem_3gpp_update_location (self, 0, 0, 0);
ctx->step++;

View File

@@ -321,16 +321,27 @@ void mm_iface_modem_3gpp_shutdown (MMIfaceModem3gpp *self);
/* Objects implementing this interface can report new registration info,
* access technologies and location.
*
* This may happen when handling unsolicited registration messages, or when
* the interface asks to run registration state checks. */
void mm_iface_modem_3gpp_update_cs_registration_state (MMIfaceModem3gpp *self,
MMModem3gppRegistrationState state);
void mm_iface_modem_3gpp_update_ps_registration_state (MMIfaceModem3gpp *self,
MMModem3gppRegistrationState state);
void mm_iface_modem_3gpp_update_eps_registration_state (MMIfaceModem3gpp *self,
MMModem3gppRegistrationState state);
void mm_iface_modem_3gpp_update_5gs_registration_state (MMIfaceModem3gpp *self,
MMModem3gppRegistrationState state);
* the interface asks to run registration state checks.
*
* The registration updates may be "deferred" so that they are applied all at
* the same time.
*/
void mm_iface_modem_3gpp_update_cs_registration_state (MMIfaceModem3gpp *self,
MMModem3gppRegistrationState state,
gboolean deferred);
void mm_iface_modem_3gpp_update_ps_registration_state (MMIfaceModem3gpp *self,
MMModem3gppRegistrationState state,
gboolean deferred);
void mm_iface_modem_3gpp_update_eps_registration_state (MMIfaceModem3gpp *self,
MMModem3gppRegistrationState state,
gboolean deferred);
void mm_iface_modem_3gpp_update_5gs_registration_state (MMIfaceModem3gpp *self,
MMModem3gppRegistrationState state,
gboolean deferred);
void mm_iface_modem_3gpp_apply_deferred_registration_state (MMIfaceModem3gpp *self);
void mm_iface_modem_3gpp_update_subscription_state (MMIfaceModem3gpp *self,
MMModem3gppSubscriptionState state);
void mm_iface_modem_3gpp_update_access_technologies (MMIfaceModem3gpp *self,