aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
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,