aboutsummaryrefslogtreecommitdiff
path: root/src/mm-iface-modem-3gpp.c
diff options
context:
space:
mode:
authorAleksander Morgado <aleksander@aleksander.es>2020-03-23 07:58:23 +0100
committerAleksander Morgado <aleksander@aleksander.es>2020-04-09 12:38:50 +0000
commit05301f23a1f3fdacb3a024b38d48d0129305daf0 (patch)
tree1ba125cf24e63ec41b9d8007a39f18bad2e63c4d /src/mm-iface-modem-3gpp.c
parent9144a9fa344856c484e3354eafc41c11e4a0c4a2 (diff)
iface-modem-3gpp: new 5GS network support
Diffstat (limited to 'src/mm-iface-modem-3gpp.c')
-rw-r--r--src/mm-iface-modem-3gpp.c158
1 files changed, 101 insertions, 57 deletions
diff --git a/src/mm-iface-modem-3gpp.c b/src/mm-iface-modem-3gpp.c
index cbd989f6..f3779c95 100644
--- a/src/mm-iface-modem-3gpp.c
+++ b/src/mm-iface-modem-3gpp.c
@@ -38,9 +38,10 @@ static GQuark private_quark;
typedef struct {
/* Registration state */
- MMModem3gppRegistrationState cs;
- MMModem3gppRegistrationState ps;
- MMModem3gppRegistrationState eps;
+ MMModem3gppRegistrationState state_cs;
+ MMModem3gppRegistrationState state_ps;
+ MMModem3gppRegistrationState state_eps;
+ MMModem3gppRegistrationState state_5gs;
gboolean manual_registration;
gchar *manual_registration_operator_id;
GCancellable *pending_registration_cancellable;
@@ -74,9 +75,10 @@ get_private (MMIfaceModem3gpp *self)
priv = g_object_get_qdata (G_OBJECT (self), private_quark);
if (!priv) {
priv = g_slice_new0 (Private);
- priv->cs = MM_MODEM_3GPP_REGISTRATION_STATE_UNKNOWN;
- priv->ps = MM_MODEM_3GPP_REGISTRATION_STATE_UNKNOWN;
- priv->eps = MM_MODEM_3GPP_REGISTRATION_STATE_UNKNOWN;
+ priv->state_cs = MM_MODEM_3GPP_REGISTRATION_STATE_UNKNOWN;
+ priv->state_ps = MM_MODEM_3GPP_REGISTRATION_STATE_UNKNOWN;
+ priv->state_eps = MM_MODEM_3GPP_REGISTRATION_STATE_UNKNOWN;
+ priv->state_5gs = MM_MODEM_3GPP_REGISTRATION_STATE_UNKNOWN;
g_object_set_qdata_full (G_OBJECT (self), private_quark, priv, (GDestroyNotify)private_free);
}
@@ -140,50 +142,59 @@ get_consolidated_reg_state (MMIfaceModem3gpp *self)
* So here we prefer the +CREG response, but if we never got a successful
* +CREG response, we'll take +CGREG instead.
*/
- if (priv->cs == MM_MODEM_3GPP_REGISTRATION_STATE_HOME ||
- priv->cs == MM_MODEM_3GPP_REGISTRATION_STATE_ROAMING) {
- consolidated = priv->cs;
+ if (priv->state_cs == MM_MODEM_3GPP_REGISTRATION_STATE_HOME ||
+ priv->state_cs == MM_MODEM_3GPP_REGISTRATION_STATE_ROAMING) {
+ consolidated = priv->state_cs;
goto out;
}
- if (priv->ps == MM_MODEM_3GPP_REGISTRATION_STATE_HOME ||
- priv->ps == MM_MODEM_3GPP_REGISTRATION_STATE_ROAMING) {
- consolidated = priv->ps;
+ if (priv->state_ps == MM_MODEM_3GPP_REGISTRATION_STATE_HOME ||
+ priv->state_ps == MM_MODEM_3GPP_REGISTRATION_STATE_ROAMING) {
+ consolidated = priv->state_ps;
goto out;
}
- if (priv->eps == MM_MODEM_3GPP_REGISTRATION_STATE_HOME ||
- priv->eps == MM_MODEM_3GPP_REGISTRATION_STATE_ROAMING) {
- consolidated = priv->eps;
+ if (priv->state_eps == MM_MODEM_3GPP_REGISTRATION_STATE_HOME ||
+ priv->state_eps == MM_MODEM_3GPP_REGISTRATION_STATE_ROAMING) {
+ consolidated = priv->state_eps;
+ goto out;
+ }
+ if (priv->state_5gs == MM_MODEM_3GPP_REGISTRATION_STATE_HOME ||
+ priv->state_5gs == MM_MODEM_3GPP_REGISTRATION_STATE_ROAMING) {
+ consolidated = priv->state_5gs;
goto out;
}
/* Searching? */
- if (priv->cs == MM_MODEM_3GPP_REGISTRATION_STATE_SEARCHING ||
- priv->ps == MM_MODEM_3GPP_REGISTRATION_STATE_SEARCHING ||
- priv->eps == MM_MODEM_3GPP_REGISTRATION_STATE_SEARCHING) {
+ if (priv->state_cs == MM_MODEM_3GPP_REGISTRATION_STATE_SEARCHING ||
+ priv->state_ps == MM_MODEM_3GPP_REGISTRATION_STATE_SEARCHING ||
+ priv->state_eps == MM_MODEM_3GPP_REGISTRATION_STATE_SEARCHING ||
+ priv->state_5gs == MM_MODEM_3GPP_REGISTRATION_STATE_SEARCHING) {
consolidated = MM_MODEM_3GPP_REGISTRATION_STATE_SEARCHING;
goto out;
}
/* If at least one state is DENIED and the others are UNKNOWN or IDLE, use DENIED */
- if ((priv->cs == MM_MODEM_3GPP_REGISTRATION_STATE_DENIED ||
- priv->ps == MM_MODEM_3GPP_REGISTRATION_STATE_DENIED ||
- priv->eps == MM_MODEM_3GPP_REGISTRATION_STATE_DENIED) &&
- REG_STATE_IS_UNKNOWN_IDLE_DENIED (priv->cs) &&
- REG_STATE_IS_UNKNOWN_IDLE_DENIED (priv->ps) &&
- REG_STATE_IS_UNKNOWN_IDLE_DENIED (priv->eps)) {
+ if ((priv->state_cs == MM_MODEM_3GPP_REGISTRATION_STATE_DENIED ||
+ priv->state_ps == MM_MODEM_3GPP_REGISTRATION_STATE_DENIED ||
+ priv->state_eps == MM_MODEM_3GPP_REGISTRATION_STATE_DENIED ||
+ priv->state_5gs == MM_MODEM_3GPP_REGISTRATION_STATE_DENIED) &&
+ REG_STATE_IS_UNKNOWN_IDLE_DENIED (priv->state_cs) &&
+ REG_STATE_IS_UNKNOWN_IDLE_DENIED (priv->state_ps) &&
+ REG_STATE_IS_UNKNOWN_IDLE_DENIED (priv->state_eps) &&
+ REG_STATE_IS_UNKNOWN_IDLE_DENIED (priv->state_5gs)) {
consolidated = MM_MODEM_3GPP_REGISTRATION_STATE_DENIED;
goto out;
}
/* Emergency services? */
- if (priv->cs == MM_MODEM_3GPP_REGISTRATION_STATE_EMERGENCY_ONLY ||
- priv->ps == MM_MODEM_3GPP_REGISTRATION_STATE_EMERGENCY_ONLY ||
- priv->eps == MM_MODEM_3GPP_REGISTRATION_STATE_EMERGENCY_ONLY) {
+ if (priv->state_cs == MM_MODEM_3GPP_REGISTRATION_STATE_EMERGENCY_ONLY ||
+ priv->state_ps == MM_MODEM_3GPP_REGISTRATION_STATE_EMERGENCY_ONLY ||
+ priv->state_eps == MM_MODEM_3GPP_REGISTRATION_STATE_EMERGENCY_ONLY ||
+ priv->state_5gs == MM_MODEM_3GPP_REGISTRATION_STATE_EMERGENCY_ONLY) {
consolidated = MM_MODEM_3GPP_REGISTRATION_STATE_EMERGENCY_ONLY;
goto out;
}
- /* Support for additional registration states reported when on LTE.
+ /* Support for additional registration states reported when on LTE/5GNR.
*
* For example, we may see the modem registered in LTE (EPS==HOME), and we
* may get "SMS only" reported for CS.
@@ -195,29 +206,31 @@ get_consolidated_reg_state (MMIfaceModem3gpp *self)
* We also warn in that case, because ideally we should always report the
* LTE registration state first, not this one.
*/
- if (priv->cs == MM_MODEM_3GPP_REGISTRATION_STATE_HOME_SMS_ONLY ||
- priv->cs == MM_MODEM_3GPP_REGISTRATION_STATE_ROAMING_SMS_ONLY ||
- priv->cs == MM_MODEM_3GPP_REGISTRATION_STATE_HOME_CSFB_NOT_PREFERRED ||
- priv->cs == MM_MODEM_3GPP_REGISTRATION_STATE_ROAMING_CSFB_NOT_PREFERRED) {
+ if (priv->state_cs == MM_MODEM_3GPP_REGISTRATION_STATE_HOME_SMS_ONLY ||
+ priv->state_cs == MM_MODEM_3GPP_REGISTRATION_STATE_ROAMING_SMS_ONLY ||
+ priv->state_cs == MM_MODEM_3GPP_REGISTRATION_STATE_HOME_CSFB_NOT_PREFERRED ||
+ priv->state_cs == MM_MODEM_3GPP_REGISTRATION_STATE_ROAMING_CSFB_NOT_PREFERRED) {
mm_obj_warn (self, "3GPP CSFB registration state is consolidated: %s",
- mm_modem_3gpp_registration_state_get_string (priv->cs));
- consolidated = priv->cs;
+ mm_modem_3gpp_registration_state_get_string (priv->state_cs));
+ consolidated = priv->state_cs;
goto out;
}
/* Idle? */
- if (priv->cs == MM_MODEM_3GPP_REGISTRATION_STATE_IDLE ||
- priv->ps == MM_MODEM_3GPP_REGISTRATION_STATE_IDLE ||
- priv->eps == MM_MODEM_3GPP_REGISTRATION_STATE_IDLE) {
+ if (priv->state_cs == MM_MODEM_3GPP_REGISTRATION_STATE_IDLE ||
+ priv->state_ps == MM_MODEM_3GPP_REGISTRATION_STATE_IDLE ||
+ priv->state_eps == MM_MODEM_3GPP_REGISTRATION_STATE_IDLE ||
+ priv->state_5gs == MM_MODEM_3GPP_REGISTRATION_STATE_IDLE) {
consolidated = MM_MODEM_3GPP_REGISTRATION_STATE_IDLE;
goto out;
}
out:
- mm_obj_dbg (self, "building consolidated registration state: cs '%s', ps '%s', eps '%s' --> '%s'",
- mm_modem_3gpp_registration_state_get_string (priv->cs),
- mm_modem_3gpp_registration_state_get_string (priv->ps),
- mm_modem_3gpp_registration_state_get_string (priv->eps),
+ mm_obj_dbg (self, "building consolidated registration state: cs '%s', ps '%s', eps '%s', 5gs '%s' --> '%s'",
+ mm_modem_3gpp_registration_state_get_string (priv->state_cs),
+ mm_modem_3gpp_registration_state_get_string (priv->state_ps),
+ mm_modem_3gpp_registration_state_get_string (priv->state_eps),
+ mm_modem_3gpp_registration_state_get_string (priv->state_5gs),
mm_modem_3gpp_registration_state_get_string (consolidated));
return consolidated;
@@ -1141,27 +1154,31 @@ mm_iface_modem_3gpp_run_registration_checks (MMIfaceModem3gpp *self,
GAsyncReadyCallback callback,
gpointer user_data)
{
- gboolean cs_supported = FALSE;
- gboolean ps_supported = FALSE;
- gboolean eps_supported = FALSE;
+ gboolean is_cs_supported = FALSE;
+ gboolean is_ps_supported = FALSE;
+ gboolean is_eps_supported = FALSE;
+ gboolean is_5gs_supported = FALSE;
g_assert (MM_IFACE_MODEM_3GPP_GET_INTERFACE (self)->run_registration_checks != NULL);
g_object_get (self,
- MM_IFACE_MODEM_3GPP_CS_NETWORK_SUPPORTED, &cs_supported,
- MM_IFACE_MODEM_3GPP_PS_NETWORK_SUPPORTED, &ps_supported,
- MM_IFACE_MODEM_3GPP_EPS_NETWORK_SUPPORTED, &eps_supported,
+ MM_IFACE_MODEM_3GPP_CS_NETWORK_SUPPORTED, &is_cs_supported,
+ MM_IFACE_MODEM_3GPP_PS_NETWORK_SUPPORTED, &is_ps_supported,
+ MM_IFACE_MODEM_3GPP_EPS_NETWORK_SUPPORTED, &is_eps_supported,
+ MM_IFACE_MODEM_3GPP_5GS_NETWORK_SUPPORTED, &is_5gs_supported,
NULL);
- mm_obj_dbg (self, "running registration checks (CS: '%s', PS: '%s', EPS: '%s')",
- cs_supported ? "yes" : "no",
- ps_supported ? "yes" : "no",
- eps_supported ? "yes" : "no");
+ mm_obj_dbg (self, "running registration checks (CS: '%s', PS: '%s', EPS: '%s', 5GS: '%s')",
+ is_cs_supported ? "yes" : "no",
+ is_ps_supported ? "yes" : "no",
+ is_eps_supported ? "yes" : "no",
+ is_5gs_supported ? "yes" : "no");
MM_IFACE_MODEM_3GPP_GET_INTERFACE (self)->run_registration_checks (self,
- cs_supported,
- ps_supported,
- eps_supported,
+ is_cs_supported,
+ is_ps_supported,
+ is_eps_supported,
+ is_5gs_supported,
callback,
user_data);
}
@@ -1531,7 +1548,7 @@ mm_iface_modem_3gpp_update_cs_registration_state (MMIfaceModem3gpp *
return;
priv = get_private (self);
- priv->cs = state;
+ priv->state_cs = state;
update_registration_state (self, get_consolidated_reg_state (self), TRUE);
}
@@ -1550,7 +1567,7 @@ mm_iface_modem_3gpp_update_ps_registration_state (MMIfaceModem3gpp *
return;
priv = get_private (self);
- priv->ps = state;
+ priv->state_ps = state;
update_registration_state (self, get_consolidated_reg_state (self), TRUE);
}
@@ -1569,7 +1586,26 @@ mm_iface_modem_3gpp_update_eps_registration_state (MMIfaceModem3gpp
return;
priv = get_private (self);
- priv->eps = state;
+ priv->state_eps = state;
+ update_registration_state (self, get_consolidated_reg_state (self), TRUE);
+}
+
+void
+mm_iface_modem_3gpp_update_5gs_registration_state (MMIfaceModem3gpp *self,
+ MMModem3gppRegistrationState state)
+{
+ Private *priv;
+ gboolean supported = FALSE;
+
+ g_object_get (self,
+ MM_IFACE_MODEM_3GPP_5GS_NETWORK_SUPPORTED, &supported,
+ NULL);
+
+ if (!supported)
+ return;
+
+ priv = get_private (self);
+ priv->state_5gs = state;
update_registration_state (self, get_consolidated_reg_state (self), TRUE);
}
@@ -2629,6 +2665,14 @@ iface_modem_3gpp_init (gpointer g_iface)
g_object_interface_install_property
(g_iface,
+ g_param_spec_boolean (MM_IFACE_MODEM_3GPP_5GS_NETWORK_SUPPORTED,
+ "5GS network supported",
+ "Whether the modem works in the 5GS network",
+ FALSE,
+ G_PARAM_READWRITE));
+
+ g_object_interface_install_property
+ (g_iface,
g_param_spec_flags (MM_IFACE_MODEM_3GPP_IGNORED_FACILITY_LOCKS,
"Ignored locks",
"Ignored facility locks",