diff --git a/src/mm-base-bearer.c b/src/mm-base-bearer.c index 3f39ffb6..de2bd5f5 100644 --- a/src/mm-base-bearer.c +++ b/src/mm-base-bearer.c @@ -31,6 +31,7 @@ #include "mm-daemon-enums-types.h" #include "mm-iface-modem.h" #include "mm-iface-modem-3gpp.h" +#include "mm-iface-modem-3gpp-profile-manager.h" #include "mm-iface-modem-cdma.h" #include "mm-base-bearer.h" #include "mm-base-modem-at.h" @@ -974,10 +975,17 @@ connect_ready (MMBaseBearer *self, mm_obj_warn (self, "connection attempt #%u failed: %s", mm_bearer_stats_get_attempts (self->priv->stats), error->message); + /* process profile manager updates right away on error */ + if (mm_iface_modem_is_3gpp (MM_IFACE_MODEM (self->priv->modem))) + mm_iface_modem_3gpp_profile_manager_update_ignore_stop (MM_IFACE_MODEM_3GPP_PROFILE_MANAGER (self->priv->modem)); connect_failed (self, task, error); return; } + /* delay processing profile manager updates on success */ + if (mm_iface_modem_is_3gpp (MM_IFACE_MODEM (self->priv->modem))) + mm_iface_modem_3gpp_profile_manager_update_ignore_stop_delayed (MM_IFACE_MODEM_3GPP_PROFILE_MANAGER (self->priv->modem)); + /* Handle cancellations detected after successful connection */ if (connect_check_cancel (self, task)) return; @@ -1093,6 +1101,10 @@ mm_base_bearer_connect (MMBaseBearer *self, /* Clear previous connection error, if any */ bearer_update_connection_error (self, NULL); + /* The connect request may imply a profile update internally, so ignore it */ + if (mm_iface_modem_is_3gpp (MM_IFACE_MODEM (self->priv->modem))) + mm_iface_modem_3gpp_profile_manager_update_ignore_start (MM_IFACE_MODEM_3GPP_PROFILE_MANAGER (self->priv->modem)); + /* Connecting! */ mm_obj_dbg (self, "connecting..."); self->priv->connect_cancellable = g_cancellable_new (); diff --git a/src/mm-iface-modem-3gpp-profile-manager.c b/src/mm-iface-modem-3gpp-profile-manager.c index b5f9a2bc..d4478dec 100644 --- a/src/mm-iface-modem-3gpp-profile-manager.c +++ b/src/mm-iface-modem-3gpp-profile-manager.c @@ -42,6 +42,8 @@ static GQuark supported_quark; static GQuark private_quark; typedef struct { + /* reported updates should be ignored */ + gint update_ignored; /* throttle updated signal */ guint updated_timeout_source; } Private; @@ -82,6 +84,68 @@ mm_iface_modem_3gpp_profile_manager_bind_simple_status (MMIfaceModem3gppProfileM /*****************************************************************************/ +void +mm_iface_modem_3gpp_profile_manager_update_ignore_start (MMIfaceModem3gppProfileManager *self) +{ + Private *priv; + + if (!GPOINTER_TO_UINT (g_object_get_qdata (G_OBJECT (self), supported_quark))) { + mm_obj_dbg (self, "skipping profile manager update ignore start: unsupported"); + return; + } + + priv = get_private (self); + g_assert_cmpint (priv->update_ignored, >=, 0); + priv->update_ignored++; + mm_obj_dbg (self, "ignoring profile manager updates during our own operations (%d ongoing)", priv->update_ignored); +} + +void +mm_iface_modem_3gpp_profile_manager_update_ignore_stop (MMIfaceModem3gppProfileManager *self) +{ + Private *priv; + + if (!GPOINTER_TO_UINT (g_object_get_qdata (G_OBJECT (self), supported_quark))) { + mm_obj_dbg (self, "skipping profile manager update ignore stop: unsupported"); + return; + } + + priv = get_private (self); + g_assert_cmpint (priv->update_ignored, >, 0); + priv->update_ignored--; + if (priv->update_ignored > 0) + mm_obj_dbg (self, "still ignoring profile manager updates during our own operations (%d ongoing)", priv->update_ignored); + else + mm_obj_dbg (self, "no longer ignoring profile manager updates during our own operations"); +} + +/* Wait some ms before actually enabling back the update requests */ +#define DELAYED_UPDATE_IGNORE_STOP_TIMEOUT_MS 100 + +static gboolean +update_ignore_stop_delayed_cb (MMIfaceModem3gppProfileManager *self) /* full ref */ +{ + mm_iface_modem_3gpp_profile_manager_update_ignore_stop (self); + g_object_unref (self); + return G_SOURCE_REMOVE; +} + +void +mm_iface_modem_3gpp_profile_manager_update_ignore_stop_delayed (MMIfaceModem3gppProfileManager *self) +{ + if (!GPOINTER_TO_UINT (g_object_get_qdata (G_OBJECT (self), supported_quark))) { + mm_obj_dbg (self, "skipping profile manager update ignore stop delayed: unsupported"); + return; + } + + mm_obj_dbg (self, "delayed request to stop ignoring profile manager updates"); + g_timeout_add (DELAYED_UPDATE_IGNORE_STOP_TIMEOUT_MS, + (GSourceFunc) update_ignore_stop_delayed_cb, + g_object_ref (self)); +} + +/*****************************************************************************/ + /* Throttle the amount of "Updated" signals we emit, e.g. so that if we receive * multiple modem indications in a very short time span, we don't emit one signal * for each of them. */ @@ -116,6 +180,17 @@ mm_iface_modem_3gpp_profile_manager_updated (MMIfaceModem3gppProfileManager *sel Private *priv; priv = get_private (self); + + if (!GPOINTER_TO_UINT (g_object_get_qdata (G_OBJECT (self), supported_quark))) { + mm_obj_info (self, "skipping profile manager updated signal: unsupported"); + return; + } + + if (priv->update_ignored > 0) { + mm_obj_info (self, "skipping profile manager updated signal: ignored"); + return; + } + if (priv->updated_timeout_source) { mm_obj_info (self, "skipping profile manager updated signal: one already scheduled"); return; @@ -1105,6 +1180,8 @@ set_profile_ready (MMIfaceModem3gppProfileManager *self, profile_stored = mm_iface_modem_3gpp_profile_manager_set_profile_finish (self, res, &error); if (!profile_stored) { mm_obj_warn (self, "failed setting 3GPP profile: %s", error->message); + /* process profile manager updates right away on error */ + mm_iface_modem_3gpp_profile_manager_update_ignore_stop (self); mm_dbus_method_invocation_take_error (ctx->invocation, error); handle_set_context_free (ctx); return; @@ -1113,6 +1190,9 @@ set_profile_ready (MMIfaceModem3gppProfileManager *self, mm_obj_info (self, "3GPP profile set:"); mm_log_3gpp_profile (self, MM_LOG_LEVEL_INFO, " ", profile_stored); + /* delay processing profile manager updates on success */ + mm_iface_modem_3gpp_profile_manager_update_ignore_stop_delayed (self); + profile_dictionary = mm_3gpp_profile_get_dictionary (profile_stored); mm_gdbus_modem3gpp_profile_manager_complete_set (ctx->skeleton, ctx->invocation, profile_dictionary); handle_set_context_free (ctx); @@ -1159,6 +1239,9 @@ handle_set_auth_ready (MMBaseModem *self, index_field = mm_gdbus_modem3gpp_profile_manager_get_index_field (ctx->skeleton); + /* Start ignoring our own indications */ + mm_iface_modem_3gpp_profile_manager_update_ignore_start (MM_IFACE_MODEM_3GPP_PROFILE_MANAGER (self)); + /* Don't call the class callback directly, use the common helper method * that is also used by other internal operations. */ mm_iface_modem_3gpp_profile_manager_set_profile ( @@ -1220,9 +1303,13 @@ delete_profile_ready (MMIfaceModem3gppProfileManager *self, if (!MM_IFACE_MODEM_3GPP_PROFILE_MANAGER_GET_INTERFACE (self)->delete_profile_finish (self, res, &error)) { mm_obj_warn (self, "failed deleting 3GPP profile: %s", error->message); + /* process profile manager updates right away on error */ + mm_iface_modem_3gpp_profile_manager_update_ignore_stop (self); mm_dbus_method_invocation_take_error (ctx->invocation, error); } else { mm_obj_info (self, "3GPP profile deleted"); + /* delay processing profile manager updates on success */ + mm_iface_modem_3gpp_profile_manager_update_ignore_stop_delayed (self); mm_gdbus_modem3gpp_profile_manager_complete_delete (ctx->skeleton, ctx->invocation); } handle_delete_context_free (ctx); @@ -1307,6 +1394,9 @@ handle_delete_auth_ready (MMBaseModem *self, mm_obj_info (self, "processing user request to delete 3GPP profile..."); mm_log_3gpp_profile (self, MM_LOG_LEVEL_INFO, " ", profile); + /* Start ignoring our own indications */ + mm_iface_modem_3gpp_profile_manager_update_ignore_start (MM_IFACE_MODEM_3GPP_PROFILE_MANAGER (self)); + MM_IFACE_MODEM_3GPP_PROFILE_MANAGER_GET_INTERFACE (self)->delete_profile ( MM_IFACE_MODEM_3GPP_PROFILE_MANAGER (self), profile, diff --git a/src/mm-iface-modem-3gpp-profile-manager.h b/src/mm-iface-modem-3gpp-profile-manager.h index e9724087..e127697d 100644 --- a/src/mm-iface-modem-3gpp-profile-manager.h +++ b/src/mm-iface-modem-3gpp-profile-manager.h @@ -222,6 +222,12 @@ void mm_iface_modem_3gpp_profile_manager_shutdown (MMIfaceModem3gppProfileManage void mm_iface_modem_3gpp_profile_manager_bind_simple_status (MMIfaceModem3gppProfileManager *self, MMSimpleStatus *status); +/* Helpers to request ignorig Updated signal emission requests sent by implementations during + * our own operations */ +void mm_iface_modem_3gpp_profile_manager_update_ignore_start (MMIfaceModem3gppProfileManager *self); +void mm_iface_modem_3gpp_profile_manager_update_ignore_stop (MMIfaceModem3gppProfileManager *self); +void mm_iface_modem_3gpp_profile_manager_update_ignore_stop_delayed (MMIfaceModem3gppProfileManager *self); + /* Helper to emit the Updated signal by implementations */ void mm_iface_modem_3gpp_profile_manager_updated (MMIfaceModem3gppProfileManager *self); @@ -250,5 +256,4 @@ MM3gppProfile *mm_iface_modem_3gpp_profile_manager_set_profile_finish (MMIface GAsyncResult *res, GError **error); - #endif /* MM_IFACE_MODEM_3GPP_PROFILE_MANAGER_H */ diff --git a/src/mm-iface-modem-3gpp.c b/src/mm-iface-modem-3gpp.c index 61ebf175..a7426937 100644 --- a/src/mm-iface-modem-3gpp.c +++ b/src/mm-iface-modem-3gpp.c @@ -24,6 +24,7 @@ #include "mm-iface-modem.h" #include "mm-iface-modem-location.h" #include "mm-iface-modem-3gpp.h" +#include "mm-iface-modem-3gpp-profile-manager.h" #include "mm-base-modem.h" #include "mm-modem-helpers.h" #include "mm-error-helpers.h" @@ -1267,6 +1268,8 @@ set_initial_eps_bearer_settings_ready (MMIfaceModem3gpp if (!MM_IFACE_MODEM_3GPP_GET_INTERFACE (self)->set_initial_eps_bearer_settings_finish (self, res, &error)) { mm_obj_warn (self, "failed setting initial EPS bearer settings: %s", error->message); + /* process profile manager updates right away on error */ + mm_iface_modem_3gpp_profile_manager_update_ignore_stop (MM_IFACE_MODEM_3GPP_PROFILE_MANAGER (self)); mm_dbus_method_invocation_take_error (ctx->invocation, error); handle_set_initial_eps_bearer_settings_context_free (ctx); return; @@ -1274,6 +1277,9 @@ set_initial_eps_bearer_settings_ready (MMIfaceModem3gpp mm_obj_info (self, "initial EPS bearer settings updated"); + /* delay processing profile manager updates on success */ + mm_iface_modem_3gpp_profile_manager_update_ignore_stop_delayed (MM_IFACE_MODEM_3GPP_PROFILE_MANAGER (self)); + if (MM_IFACE_MODEM_3GPP_GET_INTERFACE (self)->load_initial_eps_bearer_settings && MM_IFACE_MODEM_3GPP_GET_INTERFACE (self)->load_initial_eps_bearer_settings_finish) { MM_IFACE_MODEM_3GPP_GET_INTERFACE (self)->load_initial_eps_bearer_settings ( @@ -1336,6 +1342,9 @@ set_initial_eps_bearer_settings_auth_ready (MMBaseModem return; } + /* Start ignoring our own indications */ + mm_iface_modem_3gpp_profile_manager_update_ignore_start (MM_IFACE_MODEM_3GPP_PROFILE_MANAGER (self)); + MM_IFACE_MODEM_3GPP_GET_INTERFACE (self)->set_initial_eps_bearer_settings ( MM_IFACE_MODEM_3GPP (self), ctx->config,