aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAleksander Morgado <aleksandermj@chromium.org>2024-05-07 11:24:11 +0000
committerAleksander Morgado <aleksandermj@chromium.org>2024-05-29 08:02:40 +0000
commitfa169bda9fb8b0ec26ea28502ef406b655de6ef0 (patch)
tree17eed86f827d45d76cfa8fd2c4ee6712e5c6aca1 /src
parentc5b9effdc7b8d7dd505c223e742a4e1f25c3fde3 (diff)
iface-modem-3gpp: power down before updating initial EPS bearer settings
Before the operation to update the current initial EPS bearer settings, we will now unconditionally put the modem in low power mode. so that when the next network registration happens we are sure the new settings are in place. This approach was previously applied already to all QMI-based modems as well as to all Fibocom modems. The approach applies now to all modems of all vendors and in all control protocols.
Diffstat (limited to 'src')
-rw-r--r--src/mm-iface-modem-3gpp.c224
1 files changed, 166 insertions, 58 deletions
diff --git a/src/mm-iface-modem-3gpp.c b/src/mm-iface-modem-3gpp.c
index 2adb63f3..77599a8b 100644
--- a/src/mm-iface-modem-3gpp.c
+++ b/src/mm-iface-modem-3gpp.c
@@ -1208,17 +1208,30 @@ handle_set_eps_ue_mode_operation (MmGdbusModem3gpp *skeleton,
/*****************************************************************************/
+typedef enum {
+ HANDLE_SET_INITIAL_EPS_BEARER_SETTINGS_STEP_FIRST,
+ HANDLE_SET_INITIAL_EPS_BEARER_SETTINGS_STEP_POWER_DOWN,
+ HANDLE_SET_INITIAL_EPS_BEARER_SETTINGS_STEP_UPDATE,
+ HANDLE_SET_INITIAL_EPS_BEARER_SETTINGS_STEP_PREVIOUS_POWER,
+ HANDLE_SET_INITIAL_EPS_BEARER_SETTINGS_STEP_RELOAD,
+ HANDLE_SET_INITIAL_EPS_BEARER_SETTINGS_STEP_LAST,
+} HandleSetInitialEpsBearerSettingsStep;
+
typedef struct {
- MmGdbusModem3gpp *skeleton;
- GDBusMethodInvocation *invocation;
- MMIfaceModem3gpp *self;
- GVariant *dictionary;
- MMBearerProperties *config;
+ HandleSetInitialEpsBearerSettingsStep step;
+ MmGdbusModem3gpp *skeleton;
+ GDBusMethodInvocation *invocation;
+ MMIfaceModem3gpp *self;
+ GVariant *dictionary;
+ MMBearerProperties *config;
+ MMModemPowerState previous_power_state;
+ GError *saved_error;
} HandleSetInitialEpsBearerSettingsContext;
static void
handle_set_initial_eps_bearer_settings_context_free (HandleSetInitialEpsBearerSettingsContext *ctx)
{
+ g_assert (!ctx->saved_error);
g_clear_object (&ctx->config);
g_variant_unref (ctx->dictionary);
g_object_unref (ctx->skeleton);
@@ -1227,72 +1240,171 @@ handle_set_initial_eps_bearer_settings_context_free (HandleSetInitialEpsBearerSe
g_slice_free (HandleSetInitialEpsBearerSettingsContext, ctx);
}
+static void handle_set_initial_eps_bearer_settings_step (HandleSetInitialEpsBearerSettingsContext *ctx);
+
static void
-after_set_load_initial_eps_bearer_settings_ready (MMIfaceModem3gpp *self,
- GAsyncResult *res,
- HandleSetInitialEpsBearerSettingsContext *ctx)
+handle_set_initial_eps_bearer_settings_reload_ready (MMIfaceModem3gpp *self,
+ GAsyncResult *res,
+ HandleSetInitialEpsBearerSettingsContext *ctx)
{
- GError *error = NULL;
- g_autoptr(MMBearerProperties) new_config = NULL;
- g_autoptr(GVariant) dictionary = NULL;
+ g_autoptr(MMBearerProperties) new_config = NULL;
+ g_autoptr(GVariant) dictionary = NULL;
- new_config = MM_IFACE_MODEM_3GPP_GET_IFACE (self)->load_initial_eps_bearer_settings_finish (self, res, &error);
- if (error) {
- mm_obj_warn (self, "failed reloading initial EPS bearer settings after update: %s", error->message);
- mm_dbus_method_invocation_take_error (ctx->invocation, error);
- handle_set_initial_eps_bearer_settings_context_free (ctx);
- return;
- }
+ g_assert (!ctx->saved_error);
- if (!mm_bearer_properties_cmp (new_config, ctx->config, MM_BEARER_PROPERTIES_CMP_FLAGS_EPS)) {
+ new_config = MM_IFACE_MODEM_3GPP_GET_IFACE (self)->load_initial_eps_bearer_settings_finish (self, res, &ctx->saved_error);
+ if (ctx->saved_error)
+ mm_obj_warn (self, "failed reloading initial EPS bearer settings after update: %s", ctx->saved_error->message);
+ else if (!mm_bearer_properties_cmp (new_config, ctx->config, MM_BEARER_PROPERTIES_CMP_FLAGS_EPS)) {
mm_obj_warn (self, "requested and reloaded initial EPS bearer settings don't match");
mm_obj_info (self, "reloaded initial EPS bearer settings:");
mm_log_bearer_properties (self, MM_LOG_LEVEL_INFO, " ", new_config);
- mm_dbus_method_invocation_return_error_literal (ctx->invocation, MM_CORE_ERROR, MM_CORE_ERROR_FAILED,
- "Initial EPS bearer settings were not updated");
- handle_set_initial_eps_bearer_settings_context_free (ctx);
- return;
+ ctx->saved_error = g_error_new_literal (MM_CORE_ERROR, MM_CORE_ERROR_FAILED,
+ "Initial EPS bearer settings were not updated");
+ } else {
+ dictionary = mm_bearer_properties_get_dictionary (new_config);
+ mm_gdbus_modem3gpp_set_initial_eps_bearer_settings (ctx->skeleton, dictionary);
}
- dictionary = mm_bearer_properties_get_dictionary (new_config);
- mm_gdbus_modem3gpp_set_initial_eps_bearer_settings (ctx->skeleton, dictionary);
- mm_gdbus_modem3gpp_complete_set_initial_eps_bearer_settings (ctx->skeleton, ctx->invocation);
- handle_set_initial_eps_bearer_settings_context_free (ctx);
+ ctx->step++;
+ handle_set_initial_eps_bearer_settings_step (ctx);
}
static void
-set_initial_eps_bearer_settings_ready (MMIfaceModem3gpp *self,
- GAsyncResult *res,
- HandleSetInitialEpsBearerSettingsContext *ctx)
+handle_set_initial_eps_bearer_settings_previous_power_ready (MMIfaceModem *self,
+ GAsyncResult *res,
+ HandleSetInitialEpsBearerSettingsContext *ctx)
{
- GError *error = NULL;
+ g_autoptr(GError) error = NULL;
- if (!MM_IFACE_MODEM_3GPP_GET_IFACE (self)->set_initial_eps_bearer_settings_finish (self, res, &error)) {
- mm_obj_warn (self, "failed setting initial EPS bearer settings: %s", error->message);
+ if (!mm_iface_modem_set_power_state_finish (self, res, NULL, &error)) {
+ mm_obj_warn (self, "failed to restore power state after updating initial EPS bearer settings: %s", error->message);
+ if (!ctx->saved_error)
+ ctx->saved_error = g_steal_pointer (&error);
+ } else {
+ mm_obj_dbg (self, "modem power state updated: %s -> %s",
+ mm_modem_power_state_get_string (MM_MODEM_POWER_STATE_LOW),
+ mm_modem_power_state_get_string (ctx->previous_power_state));
+ }
+
+ /* Jump to last if there is any error */
+ if (ctx->saved_error)
+ ctx->step = HANDLE_SET_INITIAL_EPS_BEARER_SETTINGS_STEP_LAST;
+ else
+ ctx->step++;
+ handle_set_initial_eps_bearer_settings_step (ctx);
+}
+
+static void
+handle_set_initial_eps_bearer_settings_update_ready (MMIfaceModem3gpp *self,
+ GAsyncResult *res,
+ HandleSetInitialEpsBearerSettingsContext *ctx)
+{
+ if (!MM_IFACE_MODEM_3GPP_GET_IFACE (self)->set_initial_eps_bearer_settings_finish (self, res, &ctx->saved_error)) {
+ mm_obj_warn (self, "failed setting initial EPS bearer settings: %s", ctx->saved_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;
+ /* we continue the steps in order to power up after the failure if needed */
+ } else {
+ /* delay processing profile manager updates on success */
+ mm_iface_modem_3gpp_profile_manager_update_ignore_stop_delayed (MM_IFACE_MODEM_3GPP_PROFILE_MANAGER (self));
+ mm_obj_info (self, "initial EPS bearer settings updated");
}
- 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));
+ ctx->step++;
+ handle_set_initial_eps_bearer_settings_step (ctx);
+}
- if (MM_IFACE_MODEM_3GPP_GET_IFACE (self)->load_initial_eps_bearer_settings &&
- MM_IFACE_MODEM_3GPP_GET_IFACE (self)->load_initial_eps_bearer_settings_finish) {
- MM_IFACE_MODEM_3GPP_GET_IFACE (self)->load_initial_eps_bearer_settings (
- self,
- (GAsyncReadyCallback)after_set_load_initial_eps_bearer_settings_ready,
- ctx);
- return;
+static void
+handle_set_initial_eps_bearer_settings_power_down_ready (MMIfaceModem *self,
+ GAsyncResult *res,
+ HandleSetInitialEpsBearerSettingsContext *ctx)
+{
+ if (!mm_iface_modem_set_power_state_finish (self, res, &ctx->previous_power_state, &ctx->saved_error)) {
+ /* Jump to last if there is any error */
+ mm_obj_warn (self, "failed to power down modem before updating initial EPS bearer settings: %s", ctx->saved_error->message);
+ ctx->step = HANDLE_SET_INITIAL_EPS_BEARER_SETTINGS_STEP_LAST;
+ } else {
+ mm_obj_dbg (self, "modem power state updated: %s -> %s",
+ mm_modem_power_state_get_string (ctx->previous_power_state),
+ mm_modem_power_state_get_string (MM_MODEM_POWER_STATE_LOW));
+ ctx->step++;
}
- /* Assume we're ok */
- mm_gdbus_modem3gpp_complete_set_initial_eps_bearer_settings (ctx->skeleton, ctx->invocation);
- handle_set_initial_eps_bearer_settings_context_free (ctx);
+ handle_set_initial_eps_bearer_settings_step (ctx);
+}
+
+static void
+handle_set_initial_eps_bearer_settings_step (HandleSetInitialEpsBearerSettingsContext *ctx)
+{
+ switch (ctx->step) {
+ case HANDLE_SET_INITIAL_EPS_BEARER_SETTINGS_STEP_FIRST:
+ ctx->step++;
+ /* fall through */
+
+ case HANDLE_SET_INITIAL_EPS_BEARER_SETTINGS_STEP_POWER_DOWN:
+ mm_obj_msg (ctx->self, "set initial EPS bearer settings state (%d/%d): power down",
+ ctx->step, HANDLE_SET_INITIAL_EPS_BEARER_SETTINGS_STEP_LAST);
+ mm_iface_modem_set_power_state (
+ MM_IFACE_MODEM (ctx->self),
+ MM_MODEM_POWER_STATE_LOW,
+ (GAsyncReadyCallback)handle_set_initial_eps_bearer_settings_power_down_ready,
+ ctx);
+ return;
+
+ case HANDLE_SET_INITIAL_EPS_BEARER_SETTINGS_STEP_UPDATE:
+ mm_obj_msg (ctx->self, "set initial EPS bearer settings state (%d/%d): update",
+ ctx->step, HANDLE_SET_INITIAL_EPS_BEARER_SETTINGS_STEP_LAST);
+ mm_iface_modem_3gpp_profile_manager_update_ignore_start (MM_IFACE_MODEM_3GPP_PROFILE_MANAGER (ctx->self));
+ MM_IFACE_MODEM_3GPP_GET_IFACE (ctx->self)->set_initial_eps_bearer_settings (
+ ctx->self,
+ ctx->config,
+ (GAsyncReadyCallback)handle_set_initial_eps_bearer_settings_update_ready,
+ ctx);
+ return;
+
+ case HANDLE_SET_INITIAL_EPS_BEARER_SETTINGS_STEP_PREVIOUS_POWER:
+ mm_obj_msg (ctx->self, "set initial EPS bearer settings state (%d/%d): recover previous power state",
+ ctx->step, HANDLE_SET_INITIAL_EPS_BEARER_SETTINGS_STEP_LAST);
+ mm_iface_modem_set_power_state (
+ MM_IFACE_MODEM (ctx->self),
+ ctx->previous_power_state,
+ (GAsyncReadyCallback)handle_set_initial_eps_bearer_settings_previous_power_ready,
+ ctx);
+ return;
+
+ case HANDLE_SET_INITIAL_EPS_BEARER_SETTINGS_STEP_RELOAD:
+ mm_obj_msg (ctx->self, "set initial EPS bearer settings state (%d/%d): reload",
+ ctx->step, HANDLE_SET_INITIAL_EPS_BEARER_SETTINGS_STEP_LAST);
+ if (MM_IFACE_MODEM_3GPP_GET_IFACE (ctx->self)->load_initial_eps_bearer_settings &&
+ MM_IFACE_MODEM_3GPP_GET_IFACE (ctx->self)->load_initial_eps_bearer_settings_finish) {
+ MM_IFACE_MODEM_3GPP_GET_IFACE (ctx->self)->load_initial_eps_bearer_settings (
+ ctx->self,
+ (GAsyncReadyCallback)handle_set_initial_eps_bearer_settings_reload_ready,
+ ctx);
+ return;
+ }
+ /* Otherwise, assume we're ok */
+
+ ctx->step++;
+ /* fall through */
+
+ case HANDLE_SET_INITIAL_EPS_BEARER_SETTINGS_STEP_LAST:
+ if (ctx->saved_error) {
+ mm_obj_msg (ctx->self, "set initial EPS bearer settings state (%d/%d): failed",
+ ctx->step, HANDLE_SET_INITIAL_EPS_BEARER_SETTINGS_STEP_LAST);
+ mm_dbus_method_invocation_take_error (ctx->invocation, g_steal_pointer (&ctx->saved_error));
+ } else {
+ mm_obj_msg (ctx->self, "set initial EPS bearer settings state (%d/%d): all done",
+ ctx->step, HANDLE_SET_INITIAL_EPS_BEARER_SETTINGS_STEP_LAST);
+ mm_gdbus_modem3gpp_complete_set_initial_eps_bearer_settings (ctx->skeleton, ctx->invocation);
+ }
+ handle_set_initial_eps_bearer_settings_context_free (ctx);
+ return;
+
+ default:
+ g_assert_not_reached ();
+ }
}
static void
@@ -1343,14 +1455,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_IFACE (self)->set_initial_eps_bearer_settings (
- MM_IFACE_MODEM_3GPP (self),
- ctx->config,
- (GAsyncReadyCallback)set_initial_eps_bearer_settings_ready,
- ctx);
+ /* Launch procedure */
+ ctx->step = HANDLE_SET_INITIAL_EPS_BEARER_SETTINGS_STEP_FIRST;
+ handle_set_initial_eps_bearer_settings_step (ctx);
}
static gboolean
@@ -1366,6 +1473,7 @@ handle_set_initial_eps_bearer_settings (MmGdbusModem3gpp *skeleton,
ctx->invocation = g_object_ref (invocation);
ctx->self = g_object_ref (self);
ctx->dictionary = g_variant_ref (dictionary);
+ ctx->previous_power_state = MM_MODEM_POWER_STATE_UNKNOWN;
mm_base_modem_authorize (MM_BASE_MODEM (self),
invocation,