aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/mm-broadband-modem-mbim.c193
1 files changed, 139 insertions, 54 deletions
diff --git a/src/mm-broadband-modem-mbim.c b/src/mm-broadband-modem-mbim.c
index 926495e6..2aab75f5 100644
--- a/src/mm-broadband-modem-mbim.c
+++ b/src/mm-broadband-modem-mbim.c
@@ -141,6 +141,7 @@ struct _MMBroadbandModemMbimPrivate {
gchar *requested_operator_id;
MbimDataClass requested_data_class; /* 0 for defaults/auto */
GTask *pending_allowed_modes_action;
+ gulong enabling_signal_id;
/* USSD helpers */
GTask *pending_ussd_action;
@@ -3787,7 +3788,7 @@ modem_3gpp_set_nr5g_registration_settings (MMIfaceModem3gpp *_self,
}
/*****************************************************************************/
-/* Common unsolicited events setup and cleanup */
+/* Signal state updates */
static void
basic_connect_notification_signal_state (MMBroadbandModemMbim *self,
@@ -3851,17 +3852,8 @@ basic_connect_notification_signal_state (MMBroadbandModemMbim *self,
mm_iface_modem_signal_update (MM_IFACE_MODEM_SIGNAL (self), cdma, evdo, gsm, umts, lte, nr5g);
}
-static void
-update_access_technologies (MMBroadbandModemMbim *self)
-{
- MMModemAccessTechnology act;
-
- act = mm_modem_access_technology_from_mbim_data_class (self->priv->highest_available_data_class);
- if (act == MM_MODEM_ACCESS_TECHNOLOGY_UNKNOWN)
- act = mm_modem_access_technology_from_mbim_data_class (self->priv->available_data_classes);
-
- mm_iface_modem_3gpp_update_access_technologies (MM_IFACE_MODEM_3GPP (self), act);
-}
+/*****************************************************************************/
+/* ATDS location update */
static void
atds_location_query_ready (MbimDevice *device,
@@ -3888,8 +3880,83 @@ atds_location_query_ready (MbimDevice *device,
}
static void
+update_atds_location (MMBroadbandModemMbim *self)
+{
+ g_autoptr(MbimMessage) message = NULL;
+ MMPortMbim *port;
+ MbimDevice *device;
+
+ port = mm_broadband_modem_mbim_peek_port_mbim (self);
+ if (!port)
+ return;
+ device = mm_port_mbim_peek_device (port);
+ if (!device)
+ return;
+
+ message = mbim_message_atds_location_query_new (NULL);
+ mbim_device_command (device,
+ message,
+ 10,
+ NULL,
+ (GAsyncReadyCallback)atds_location_query_ready,
+ g_object_ref (self));
+}
+
+/*****************************************************************************/
+/* Access technology updates */
+
+static void
+update_access_technologies (MMBroadbandModemMbim *self)
+{
+ MMModemAccessTechnology act;
+
+ act = mm_modem_access_technology_from_mbim_data_class (self->priv->highest_available_data_class);
+ if (act == MM_MODEM_ACCESS_TECHNOLOGY_UNKNOWN)
+ act = mm_modem_access_technology_from_mbim_data_class (self->priv->available_data_classes);
+
+ mm_iface_modem_3gpp_update_access_technologies (MM_IFACE_MODEM_3GPP (self), act);
+}
+
+/*****************************************************************************/
+/* Registration info updates */
+
+static void update_registration_info (MMBroadbandModemMbim *self,
+ gboolean scheduled,
+ MbimRegisterState state,
+ MbimDataClass available_data_classes,
+ gchar *operator_id_take,
+ gchar *operator_name_take);
+
+static void
+enabling_state_changed (MMBroadbandModemMbim *self)
+{
+ MMModemState state;
+
+ g_object_get (self, MM_IFACE_MODEM_STATE, &state, NULL);
+
+ /* if we've reached a enabled state, we can trigger the update */
+ if (state > MM_MODEM_STATE_ENABLING) {
+ mm_obj_dbg (self, "triggering 3GPP registration info update");
+ update_registration_info (self,
+ TRUE,
+ self->priv->reg_state,
+ self->priv->available_data_classes,
+ g_strdup (self->priv->current_operator_id),
+ g_strdup (self->priv->current_operator_name));
+ }
+ /* if something bad happened during enabling, we can ignore any pending
+ * registration info update */
+ else if (state < MM_MODEM_STATE_ENABLING)
+ mm_obj_dbg (self, "discarding pending 3GPP registration info update");
+
+ /* this signal is expected to be fired just once */
+ g_signal_handler_disconnect (self, self->priv->enabling_signal_id);
+ self->priv->enabling_signal_id = 0;
+}
+
+static void
update_registration_info (MMBroadbandModemMbim *self,
- MbimDevice *device,
+ gboolean scheduled,
MbimRegisterState state,
MbimDataClass available_data_classes,
gchar *operator_id_take,
@@ -3902,6 +3969,14 @@ update_registration_info (MMBroadbandModemMbim *self,
MMModem3gppRegistrationState reg_state_5gs;
gboolean operator_updated = FALSE;
gboolean reg_state_updated = FALSE;
+ MMModemState modem_state;
+ gboolean schedule_update_in_enabled = FALSE;
+
+ /* If we're enabling, we will not attempt to update anything yet, we will
+ * instead store the info and schedule the updates for when we're enabled */
+ g_object_get (self, MM_IFACE_MODEM_STATE, &modem_state, NULL);
+ if (modem_state == MM_MODEM_STATE_ENABLING)
+ schedule_update_in_enabled = TRUE;
if (self->priv->reg_state != state)
reg_state_updated = TRUE;
@@ -3937,54 +4012,59 @@ update_registration_info (MMBroadbandModemMbim *self,
g_free (operator_name_take);
}
- reg_state_cs = MM_MODEM_3GPP_REGISTRATION_STATE_IDLE;
- reg_state_ps = MM_MODEM_3GPP_REGISTRATION_STATE_IDLE;
- reg_state_eps = MM_MODEM_3GPP_REGISTRATION_STATE_IDLE;
- reg_state_5gs = MM_MODEM_3GPP_REGISTRATION_STATE_IDLE;
+ /* If we can update domain registration states right now, do it */
+ if (!schedule_update_in_enabled) {
+ reg_state_cs = MM_MODEM_3GPP_REGISTRATION_STATE_IDLE;
+ reg_state_ps = MM_MODEM_3GPP_REGISTRATION_STATE_IDLE;
+ reg_state_eps = MM_MODEM_3GPP_REGISTRATION_STATE_IDLE;
+ reg_state_5gs = MM_MODEM_3GPP_REGISTRATION_STATE_IDLE;
- if (available_data_classes & (MBIM_DATA_CLASS_GPRS | MBIM_DATA_CLASS_EDGE |
- MBIM_DATA_CLASS_UMTS | MBIM_DATA_CLASS_HSDPA | MBIM_DATA_CLASS_HSUPA)) {
- reg_state_cs = reg_state;
- if (self->priv->packet_service_state == MBIM_PACKET_SERVICE_STATE_ATTACHED)
- reg_state_ps = reg_state;
- }
+ if (available_data_classes & (MBIM_DATA_CLASS_GPRS | MBIM_DATA_CLASS_EDGE |
+ MBIM_DATA_CLASS_UMTS | MBIM_DATA_CLASS_HSDPA | MBIM_DATA_CLASS_HSUPA)) {
+ reg_state_cs = reg_state;
+ if (self->priv->packet_service_state == MBIM_PACKET_SERVICE_STATE_ATTACHED)
+ reg_state_ps = reg_state;
+ }
- if (available_data_classes & (MBIM_DATA_CLASS_LTE))
- reg_state_eps = reg_state;
+ if (available_data_classes & (MBIM_DATA_CLASS_LTE))
+ reg_state_eps = reg_state;
- if (available_data_classes & (MBIM_DATA_CLASS_5G_NSA | MBIM_DATA_CLASS_5G_SA))
- reg_state_5gs = reg_state;
+ 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);
- 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);
- 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_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);
+ 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);
+ 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);
- self->priv->available_data_classes = available_data_classes;
- update_access_technologies (self);
+ /* request to reload operator info explicitly, so that the new
+ * operator name and code is propagated to the DBus interface */
+ if (operator_updated || scheduled)
+ mm_iface_modem_3gpp_reload_current_registration_info (MM_IFACE_MODEM_3GPP (self), NULL, NULL);
+ }
- /* request to reload operator info explicitly, so that the new
- * operator name and code is propagated to the DBus interface */
- if (operator_updated)
- mm_iface_modem_3gpp_reload_current_registration_info (MM_IFACE_MODEM_3GPP (self), NULL, NULL);
+ self->priv->available_data_classes = available_data_classes;
+ /* If we can update access technologies right now, do it */
+ if (!schedule_update_in_enabled)
+ update_access_technologies (self);
/* request to reload location info */
- if (reg_state_updated && self->priv->is_atds_location_supported) {
+ if (!schedule_update_in_enabled && self->priv->is_atds_location_supported && (reg_state_updated || scheduled)) {
if (self->priv->reg_state < MBIM_REGISTER_STATE_HOME) {
mm_iface_modem_3gpp_update_location (MM_IFACE_MODEM_3GPP (self), 0, 0, 0);
- } else {
- g_autoptr(MbimMessage) message = NULL;
-
- message = mbim_message_atds_location_query_new (NULL);
- mbim_device_command (device,
- message,
- 10,
- NULL,
- (GAsyncReadyCallback)atds_location_query_ready,
- g_object_ref (self));
- }
+
+ } else
+ update_atds_location (self);
+ }
+
+ if (schedule_update_in_enabled && !self->priv->enabling_signal_id) {
+ mm_obj_dbg (self, "Scheduled registration info update once the modem is enabled");
+ self->priv->enabling_signal_id = g_signal_connect (self,
+ "notify::" MM_IFACE_MODEM_STATE,
+ G_CALLBACK (enabling_state_changed),
+ NULL);
}
}
@@ -4038,7 +4118,7 @@ basic_connect_notification_register_state (MMBroadbandModemMbim *self,
}
update_registration_info (self,
- device,
+ FALSE,
register_state,
available_data_classes,
provider_id,
@@ -4312,7 +4392,7 @@ basic_connect_notification_packet_service (MMBroadbandModemMbim *self,
if (self->priv->packet_service_state != packet_service_state) {
self->priv->packet_service_state = packet_service_state;
update_registration_info (self,
- device,
+ FALSE,
self->priv->reg_state,
self->priv->available_data_classes,
g_strdup (self->priv->current_operator_id),
@@ -5400,7 +5480,7 @@ register_state_query_ready (MbimDevice *device,
}
update_registration_info (self,
- device,
+ FALSE,
register_state,
available_data_classes,
provider_id,
@@ -8494,6 +8574,11 @@ dispose (GObject *object)
MMBroadbandModemMbim *self = MM_BROADBAND_MODEM_MBIM (object);
MMPortMbim *mbim;
+ if (self->priv->enabling_signal_id && g_signal_handler_is_connected (self, self->priv->enabling_signal_id)) {
+ g_signal_handler_disconnect (self, self->priv->enabling_signal_id);
+ self->priv->enabling_signal_id = 0;
+ }
+
/* If any port cleanup is needed, it must be done during dispose(), as
* the modem object will be affected by an explciit g_object_run_dispose()
* that will remove all port references right away */