diff options
author | Dylan Van Assche <me@dylanvanassche.be> | 2021-03-20 16:23:14 +0100 |
---|---|---|
committer | Aleksander Morgado <aleksander@aleksander.es> | 2021-05-26 13:14:52 +0000 |
commit | 8913bab1c5f085e3fcb5d7838617b7386ac35681 (patch) | |
tree | 6ef6b3cb2eb5d6ddbb9149ed4051bbf3c70ae1f7 | |
parent | 0a99cca2777d858250c9edeb6931a9edb1b75676 (diff) |
base-bearer: synchronize state when resuming
Refresh connection status on resume to confirm
that the connection bearers are still valid.
-rw-r--r-- | src/mm-base-bearer.c | 124 | ||||
-rw-r--r-- | src/mm-base-bearer.h | 24 | ||||
-rw-r--r-- | src/mm-iface-modem.c | 25 |
3 files changed, 173 insertions, 0 deletions
diff --git a/src/mm-base-bearer.c b/src/mm-base-bearer.c index 8b08884d..c26a5a1e 100644 --- a/src/mm-base-bearer.c +++ b/src/mm-base-bearer.c @@ -1486,6 +1486,130 @@ mm_base_bearer_report_connection_status_detailed (MMBaseBearer *self /*****************************************************************************/ +#if defined WITH_SYSTEMD_SUSPEND_RESUME + +typedef struct _SyncingContext SyncingContext; +static void interface_syncing_step (GTask *task); + +typedef enum { + SYNCING_STEP_FIRST, + SYNCING_STEP_REFRESH_CONNECTION, + SYNCING_STEP_LAST +} SyncingStep; + +struct _SyncingContext { + SyncingStep step; +}; + +gboolean +mm_base_bearer_sync_finish (MMBaseBearer *self, + GAsyncResult *res, + GError **error) +{ + return g_task_propagate_boolean (G_TASK (res), error); +} + +static gboolean +reload_connection_status_finish (MMBaseBearer *self, + GAsyncResult *res, + GError **error) +{ + return g_task_propagate_boolean (G_TASK (res), error); +} + +static void +reload_connection_status_ready (MMBaseBearer *self, + GAsyncResult *res, + GTask *task) +{ + SyncingContext *ctx; + g_autoptr(GError) error = NULL; + + ctx = g_task_get_task_data (task); + + reload_connection_status_finish (self, res, &error); + if (error) + mm_obj_warn (self, "reloading connection status failed: %s", error->message); + + /* Go on to the next step */ + ctx->step++; + interface_syncing_step (task); +} + +static void +interface_syncing_step (GTask *task) +{ + MMBaseBearer *self; + SyncingContext *ctx; + + /* Don't run new steps if we're cancelled */ + if (g_task_return_error_if_cancelled (task)) { + g_object_unref (task); + return; + } + + self = g_task_get_source_object (task); + ctx = g_task_get_task_data (task); + + switch (ctx->step) { + case SYNCING_STEP_FIRST: + ctx->step++; + /* fall through */ + + case SYNCING_STEP_REFRESH_CONNECTION: + /* + * AT+PPP based connections should not be synced. + * When a AT+PPP connection bearer is connected, the 'ignore_disconnection_reports' flag is set. + */ + if (!self->priv->ignore_disconnection_reports) { + if (!MM_BASE_BEARER_GET_CLASS (self)->reload_connection_status) + mm_obj_warn (self, "unable to reload connection status, method not implemented"); + else { + mm_obj_dbg (self, "refreshing connection status"); + MM_BASE_BEARER_GET_CLASS (self)->reload_connection_status (self, + (GAsyncReadyCallback) reload_connection_status_ready, + task); + return; + } + } + ctx->step++; + /* fall through */ + + case SYNCING_STEP_LAST: + /* We are done without errors! */ + g_task_return_boolean (task, TRUE); + g_object_unref (task); + return; + + default: + break; + } + + g_assert_not_reached (); +} + +void +mm_base_bearer_sync (MMBaseBearer *self, + GAsyncReadyCallback callback, + gpointer user_data) +{ + SyncingContext *ctx; + GTask *task; + + /* Create SyncingContext */ + ctx = g_new0 (SyncingContext, 1); + ctx->step = SYNCING_STEP_FIRST; + + /* Create sync steps task and execute it */ + task = g_task_new (self, NULL, callback, user_data); + g_task_set_task_data (task, ctx, (GDestroyNotify)g_free); + interface_syncing_step (task); +} + +#endif + +/*****************************************************************************/ + static gchar * log_object_build_id (MMLogObject *_self) { diff --git a/src/mm-base-bearer.h b/src/mm-base-bearer.h index 8c2bc175..499ec703 100644 --- a/src/mm-base-bearer.h +++ b/src/mm-base-bearer.h @@ -135,6 +135,18 @@ struct _MMBaseBearerClass { GAsyncResult *res, GError **error); +#if defined WITH_SYSTEMD_SUSPEND_RESUME + + /* Reload connection status */ + void (* reload_connection_status) (MMBaseBearer *bearer, + GAsyncReadyCallback callback, + gpointer user_data); + gboolean (* reload_connection_status_finish) (MMBaseBearer *bearer, + GAsyncResult *res, + GError **error); + +#endif + /* Reload statistics */ void (* reload_stats) (MMBaseBearer *bearer, GAsyncReadyCallback callback, @@ -185,4 +197,16 @@ void mm_base_bearer_report_connection_status_detailed (MMBaseBearer /* When unknown, just pass NULL */ #define mm_base_bearer_report_connection_status(self, status) mm_base_bearer_report_connection_status_detailed (self, status, NULL) +#if defined WITH_SYSTEMD_SUSPEND_RESUME + +/* Sync Broadband Bearer (async) */ +void mm_base_bearer_sync (MMBaseBearer *self, + GAsyncReadyCallback callback, + gpointer user_data); +gboolean mm_base_bearer_sync_finish (MMBaseBearer *self, + GAsyncResult *res, + GError **error); + +#endif + #endif /* MM_BASE_BEARER_H */ diff --git a/src/mm-iface-modem.c b/src/mm-iface-modem.c index b3604b8a..aff7a7a9 100644 --- a/src/mm-iface-modem.c +++ b/src/mm-iface-modem.c @@ -4219,6 +4219,7 @@ typedef enum { SYNCING_STEP_DETECT_SIM_SWAP, SYNCING_STEP_REFRESH_SIM_LOCK, SYNCING_STEP_REFRESH_SIGNAL_STRENGTH, + SYNCING_STEP_REFRESH_BEARERS, SYNCING_STEP_LAST } SyncingStep; @@ -4271,6 +4272,22 @@ sync_detect_sim_swap_ready (MMIfaceModem *self, } static void +reload_bearers (MMIfaceModem *self) +{ + g_autoptr(MMBearerList) list = NULL; + + g_object_get (self, + MM_IFACE_MODEM_BEARER_LIST, &list, + NULL); + + if (list) { + mm_bearer_list_foreach (list, + (MMBearerListForeachFunc)mm_base_bearer_sync, + NULL); + } +} + +static void interface_syncing_step (GTask *task) { MMIfaceModem *self; @@ -4316,6 +4333,14 @@ interface_syncing_step (GTask *task) ctx->step++; /* fall through */ + case SYNCING_STEP_REFRESH_BEARERS: + /* + * Refresh bearers. + */ + reload_bearers (self); + ctx->step++; + /* fall through */ + case SYNCING_STEP_LAST: /* We are done without errors! */ g_task_return_boolean (task, TRUE); |