temp/modemmanager: upgrade to 1.18rc1 aka 1.17.900 (MR 2453)

To test the release candidate in edge before MM stable release.

[ci:skip-build] already built successfully in CI
This commit is contained in:
Joel Selvaraj 2021-08-19 19:32:04 +05:30 committed by Clayton Craft
parent 82777179c1
commit 6de1f300af
No known key found for this signature in database
GPG key ID: 7A3461CA187CEA54
40 changed files with 9 additions and 3799 deletions

View file

@ -1,488 +0,0 @@
From d5f3a6d441f47836698b851d6049bf738d066ef6 Mon Sep 17 00:00:00 2001
From: Dylan Van Assche <me@dylanvanassche.be>
Date: Sat, 1 May 2021 15:50:47 +0200
Subject: [PATCH 01/39] base-manager: add quick suspend/resume base
Quick suspend/resume infrastructure for
synchronizing the interfaces when resuming.
---
src/main.c | 14 +++-
src/mm-base-manager.c | 48 ++++++++++++
src/mm-base-manager.h | 4 +
src/mm-base-modem.c | 155 +++++++++++++++++++++++++++++++++++++++
src/mm-base-modem.h | 23 ++++++
src/mm-broadband-modem.c | 81 ++++++++++++++++++++
src/mm-context.c | 11 +++
src/mm-context.h | 1 +
8 files changed, 336 insertions(+), 1 deletion(-)
diff --git a/src/main.c b/src/main.c
index 928078a3..4a036971 100644
--- a/src/main.c
+++ b/src/main.c
@@ -72,6 +72,13 @@ resuming_cb (MMSleepMonitor *sleep_monitor)
mm_base_manager_start (manager, FALSE);
}
+static void
+resuming_quick_cb (MMSleepMonitor *sleep_monitor)
+{
+ mm_dbg ("syncing modem state (quick resuming)");
+ mm_base_manager_sync (manager);
+}
+
#endif
static void
@@ -197,7 +204,12 @@ main (int argc, char *argv[])
if (mm_context_get_test_no_suspend_resume())
mm_dbg ("Suspend/resume support disabled at runtime");
- else {
+ else if (mm_context_get_test_quick_suspend_resume()) {
+ mm_dbg ("Quick suspend/resume hooks enabled");
+ sleep_monitor = mm_sleep_monitor_get ();
+ g_signal_connect (sleep_monitor, MM_SLEEP_MONITOR_RESUMING, G_CALLBACK (resuming_quick_cb), NULL);
+ } else {
+ mm_dbg ("Full suspend/resume hooks enabled");
sleep_monitor = mm_sleep_monitor_get ();
g_signal_connect (sleep_monitor, MM_SLEEP_MONITOR_SLEEPING, G_CALLBACK (sleeping_cb), NULL);
g_signal_connect (sleep_monitor, MM_SLEEP_MONITOR_RESUMING, G_CALLBACK (resuming_cb), NULL);
diff --git a/src/mm-base-manager.c b/src/mm-base-manager.c
index 130e5ad1..0c393f11 100644
--- a/src/mm-base-manager.c
+++ b/src/mm-base-manager.c
@@ -45,6 +45,7 @@
#include "mm-plugin.h"
#include "mm-filter.h"
#include "mm-log-object.h"
+#include "mm-base-modem.h"
static void initable_iface_init (GInitableIface *iface);
static void log_object_iface_init (MMLogObjectInterface *iface);
@@ -663,6 +664,53 @@ mm_base_manager_num_modems (MMBaseManager *self)
return n;
}
+/*****************************************************************************/
+/* Quick resume synchronization */
+
+#if defined WITH_SYSTEMD_SUSPEND_RESUME
+
+gboolean mm_base_modem_sync_finish (MMBaseModem *self,
+ GAsyncResult *res,
+ GError **error)
+{
+ return g_task_propagate_boolean (G_TASK (res), error);
+}
+
+static void
+mm_base_modem_sync_ready (MMBaseModem *self,
+ GAsyncResult *res,
+ gpointer user_data)
+{
+ g_autoptr(GError) error;
+
+ mm_base_modem_sync_finish (self, res, &error);
+ if (error) {
+ mm_obj_warn (self, "synchronization failed");
+ return;
+ }
+ mm_obj_info (self, "synchronization finished");
+}
+
+void
+mm_base_manager_sync (MMBaseManager *self)
+{
+ GHashTableIter iter;
+ gpointer key, value;
+
+ g_return_if_fail (self != NULL);
+ g_return_if_fail (MM_IS_BASE_MANAGER (self));
+
+ /* Refresh each device */
+ g_hash_table_iter_init (&iter, self->priv->devices);
+ while (g_hash_table_iter_next (&iter, &key, &value)) {
+ MMBaseModem *modem = mm_device_peek_modem (MM_DEVICE (value));
+ /* We just want to start the synchronization, we don't need the result */
+ mm_base_modem_sync (modem, (GAsyncReadyCallback)mm_base_modem_sync_ready, NULL);
+ }
+}
+
+#endif
+
/*****************************************************************************/
/* Set logging */
diff --git a/src/mm-base-manager.h b/src/mm-base-manager.h
index d70fa08f..be51d0c0 100644
--- a/src/mm-base-manager.h
+++ b/src/mm-base-manager.h
@@ -66,6 +66,10 @@ void mm_base_manager_start (MMBaseManager *manager,
void mm_base_manager_shutdown (MMBaseManager *manager,
gboolean disable);
+#if defined WITH_SYSTEMD_SUSPEND_RESUME
+void mm_base_manager_sync (MMBaseManager *manager);
+#endif
+
guint32 mm_base_manager_num_modems (MMBaseManager *manager);
#endif /* MM_BASE_MANAGER_H */
diff --git a/src/mm-base-modem.c b/src/mm-base-modem.c
index 926d0712..38f43f8c 100644
--- a/src/mm-base-modem.c
+++ b/src/mm-base-modem.c
@@ -369,6 +369,161 @@ mm_base_modem_grab_port (MMBaseModem *self,
return TRUE;
}
+/******************************************************************************/
+
+typedef struct {
+ gchar *name;
+ gulong link_port_grabbed_id;
+ guint timeout_id;
+} WaitLinkPortContext;
+
+static void
+wait_link_port_context_free (WaitLinkPortContext *ctx)
+{
+ g_assert (!ctx->link_port_grabbed_id);
+ g_assert (!ctx->timeout_id);
+ g_free (ctx->name);
+ g_slice_free (WaitLinkPortContext, ctx);
+}
+
+MMPort *
+mm_base_modem_wait_link_port_finish (MMBaseModem *self,
+ GAsyncResult *res,
+ GError **error)
+{
+ return g_task_propagate_pointer (G_TASK (res), error);
+}
+
+static gboolean
+wait_link_port_timeout_cb (GTask *task)
+{
+ WaitLinkPortContext *ctx;
+ MMBaseModem *self;
+
+ self = g_task_get_source_object (task);
+ ctx = g_task_get_task_data (task);
+
+ ctx->timeout_id = 0;
+ g_signal_handler_disconnect (self, ctx->link_port_grabbed_id);
+ ctx->link_port_grabbed_id = 0;
+
+ g_task_return_new_error (task, MM_CORE_ERROR, MM_CORE_ERROR_NOT_FOUND,
+ "Timed out waiting for link port 'net/%s'",
+ ctx->name);
+ g_object_unref (task);
+
+ return G_SOURCE_REMOVE;
+}
+
+static void
+wait_link_port_grabbed_cb (MMBaseModem *self,
+ MMPort *link_port,
+ GTask *task)
+{
+ WaitLinkPortContext *ctx;
+ MMPortSubsys link_port_subsystem;
+ const gchar *link_port_name;
+
+ ctx = g_task_get_task_data (task);
+
+ link_port_subsystem = mm_port_get_subsys (link_port);
+ link_port_name = mm_port_get_device (link_port);
+
+ if (link_port_subsystem != MM_PORT_SUBSYS_NET) {
+ mm_obj_warn (self, "unexpected link port subsystem grabbed: %s/%s",
+ mm_port_subsys_get_string (link_port_subsystem),
+ link_port_name);
+ return;
+ }
+
+ if (g_strcmp0 (link_port_name, ctx->name) != 0)
+ return;
+
+ /* we got it! */
+
+ g_source_remove (ctx->timeout_id);
+ ctx->timeout_id = 0;
+ g_signal_handler_disconnect (self, ctx->link_port_grabbed_id);
+ ctx->link_port_grabbed_id = 0;
+
+ g_task_return_pointer (task, g_object_ref (link_port), g_object_unref);
+ g_object_unref (task);
+}
+
+void
+mm_base_modem_wait_link_port (MMBaseModem *self,
+ const gchar *subsystem,
+ const gchar *name,
+ guint timeout_ms,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ WaitLinkPortContext *ctx;
+ GTask *task;
+ g_autofree gchar *key = NULL;
+ MMPort *port;
+
+ task = g_task_new (self, NULL, callback, user_data);
+
+ if (!g_str_equal (subsystem, "net")) {
+ g_task_return_new_error (task, MM_CORE_ERROR, MM_CORE_ERROR_UNSUPPORTED,
+ "Cannot wait for port '%s/%s', unexpected link port subsystem", subsystem, name);
+ g_object_unref (task);
+ return;
+ }
+
+ key = g_strdup_printf ("%s%s", subsystem, name);
+ port = g_hash_table_lookup (self->priv->link_ports, key);
+ if (port) {
+ mm_obj_dbg (self, "no need to wait for port '%s/%s': already grabbed", subsystem, name);
+ g_task_return_pointer (task, g_object_ref (port), g_object_unref);
+ g_object_unref (task);
+ return;
+ }
+
+ ctx = g_slice_new0 (WaitLinkPortContext);
+ ctx->name = g_strdup (name);
+ g_task_set_task_data (task, ctx, (GDestroyNotify)wait_link_port_context_free);
+
+ /* task ownership shared between timeout and signal handler */
+ ctx->timeout_id = g_timeout_add (timeout_ms,
+ (GSourceFunc) wait_link_port_timeout_cb,
+ task);
+ ctx->link_port_grabbed_id = g_signal_connect (self,
+ MM_BASE_MODEM_SIGNAL_LINK_PORT_GRABBED,
+ G_CALLBACK (wait_link_port_grabbed_cb),
+ task);
+
+ mm_obj_dbg (self, "waiting for port '%s/%s'...", subsystem, name);
+}
+
+/******************************************************************************/
+
+static void
+mm_base_modem_sync_ready (MMBaseModem *self,
+ GAsyncResult *res)
+{
+ g_autoptr (GError) error = NULL;
+
+ MM_BASE_MODEM_GET_CLASS (self)->sync_finish (self, res, &error);
+ if (error) {
+ mm_obj_warn (self, "synchronization failed");
+ }
+}
+
+void
+mm_base_modem_sync (MMBaseModem *self,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ g_assert (MM_BASE_MODEM_GET_CLASS (self)->sync != NULL);
+ g_assert (MM_BASE_MODEM_GET_CLASS (self)->sync_finish != NULL);
+
+ MM_BASE_MODEM_GET_CLASS (self)->sync (self,
+ (GAsyncReadyCallback) mm_base_modem_sync_ready,
+ NULL);
+}
+
gboolean
mm_base_modem_disable_finish (MMBaseModem *self,
GAsyncResult *res,
diff --git a/src/mm-base-modem.h b/src/mm-base-modem.h
index 24634814..75fd99f5 100644
--- a/src/mm-base-modem.h
+++ b/src/mm-base-modem.h
@@ -101,6 +101,22 @@ struct _MMBaseModemClass {
gboolean (*disable_finish) (MMBaseModem *self,
GAsyncResult *res,
GError **error);
+
+ /* Modem synchronization.
+ * When resuming in quick suspend/resume mode,
+ * this method triggers a synchronization of all modem interfaces */
+ void (* sync) (MMBaseModem *self,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+ gboolean (* sync_finish) (MMBaseModem *self,
+ GAsyncResult *res,
+ GError **error);
+
+ /* signals */
+ void (* link_port_grabbed) (MMBaseModem *self,
+ MMPort *link_port);
+ void (* link_port_released) (MMBaseModem *self,
+ MMPort *link_port);
};
GType mm_base_modem_get_type (void);
@@ -199,6 +215,13 @@ gboolean mm_base_modem_disable_finish (MMBaseModem *self,
GAsyncResult *res,
GError **error);
+void mm_base_modem_sync (MMBaseModem *self,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+gboolean mm_base_modem_sync_finish (MMBaseModem *self,
+ GAsyncResult *res,
+ GError **error);
+
void mm_base_modem_process_sim_event (MMBaseModem *self);
#endif /* MM_BASE_MODEM_H */
diff --git a/src/mm-broadband-modem.c b/src/mm-broadband-modem.c
index a25883ac..6e47757e 100644
--- a/src/mm-broadband-modem.c
+++ b/src/mm-broadband-modem.c
@@ -11337,6 +11337,82 @@ enable (MMBaseModem *self,
g_object_unref (task);
}
+/*****************************************************************************/
+
+#if defined WITH_SYSTEMD_SUSPEND_RESUME
+
+typedef enum {
+ SYNCING_STEP_FIRST,
+ SYNCING_STEP_LAST,
+} SyncingStep;
+
+typedef struct {
+ SyncingStep step;
+} SyncingContext;
+
+static gboolean
+synchronize_finish (MMBaseModem *self,
+ GAsyncResult *res,
+ GError **error)
+{
+ return g_task_propagate_boolean (G_TASK (res), error);
+}
+
+static void
+syncing_step (GTask *task)
+{
+ MMBroadbandModem *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_LAST:
+ mm_obj_info (self, "resume synchronization state (%d/%d): all done",
+ ctx->step, 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 ();
+}
+
+/* 'sync' as function name conflicts with a declared function in unistd.h */
+static void
+synchronize (MMBaseModem *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 (MM_BROADBAND_MODEM (self), NULL, callback, user_data);
+ g_task_set_task_data (task, ctx, (GDestroyNotify)g_free);
+ syncing_step (task);
+}
+
+#endif
/*****************************************************************************/
@@ -12683,6 +12759,11 @@ mm_broadband_modem_class_init (MMBroadbandModemClass *klass)
base_modem_class->disable = disable;
base_modem_class->disable_finish = disable_finish;
+#if defined WITH_SYSTEMD_SUSPEND_RESUME
+ base_modem_class->sync = synchronize;
+ base_modem_class->sync_finish = synchronize_finish;
+#endif
+
klass->setup_ports = setup_ports;
klass->initialization_started = initialization_started;
klass->initialization_started_finish = initialization_started_finish;
diff --git a/src/mm-context.c b/src/mm-context.c
index 6561127e..691ca82b 100644
--- a/src/mm-context.c
+++ b/src/mm-context.c
@@ -227,6 +227,7 @@ static gboolean test_no_udev;
#endif
#if defined WITH_SYSTEMD_SUSPEND_RESUME
static gboolean test_no_suspend_resume;
+static gboolean test_quick_suspend_resume;
#endif
static const GOptionEntry test_entries[] = {
@@ -258,6 +259,11 @@ static const GOptionEntry test_entries[] = {
"Disable suspend/resume support at runtime even if available",
NULL
},
+ {
+ "test-quick-suspend-resume", 0, 0, G_OPTION_ARG_NONE, &test_quick_suspend_resume,
+ "Enable quick suspend/resume support for modems which stay on during host suspension",
+ NULL
+ },
#endif
{ NULL }
};
@@ -308,6 +314,11 @@ mm_context_get_test_no_suspend_resume (void)
{
return test_no_suspend_resume;
}
+gboolean
+mm_context_get_test_quick_suspend_resume (void)
+{
+ return test_quick_suspend_resume;
+}
#endif
/*****************************************************************************/
diff --git a/src/mm-context.h b/src/mm-context.h
index 721fee88..276567fd 100644
--- a/src/mm-context.h
+++ b/src/mm-context.h
@@ -51,6 +51,7 @@ gboolean mm_context_get_test_no_udev (void);
#endif
#if defined WITH_SYSTEMD_SUSPEND_RESUME
gboolean mm_context_get_test_no_suspend_resume (void);
+gboolean mm_context_get_test_quick_suspend_resume (void);
#endif
#endif /* MM_CONTEXT_H */
--
2.31.1

View file

@ -1,33 +0,0 @@
From 4853aa702ed298ebceea2e9cd737d048380db38f Mon Sep 17 00:00:00 2001
From: Aleksander Morgado <aleksander@aleksander.es>
Date: Sun, 23 May 2021 12:16:55 +0200
Subject: [PATCH 02/39] base-manager: make sure g_autoptr() variables are
initialized to NULL
Otherwise, we may have memory issues if the variable isn't initialized
and the method exits.
---
src/mm-base-manager.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/mm-base-manager.c b/src/mm-base-manager.c
index 0c393f11..5880ffad 100644
--- a/src/mm-base-manager.c
+++ b/src/mm-base-manager.c
@@ -681,11 +681,11 @@ mm_base_modem_sync_ready (MMBaseModem *self,
GAsyncResult *res,
gpointer user_data)
{
- g_autoptr(GError) error;
+ g_autoptr(GError) error = NULL;
mm_base_modem_sync_finish (self, res, &error);
if (error) {
- mm_obj_warn (self, "synchronization failed");
+ mm_obj_warn (self, "synchronization failed: %s", error->message);
return;
}
mm_obj_info (self, "synchronization finished");
--
2.31.1

View file

@ -1,35 +0,0 @@
From dcea41cebabbcbd91597944fc3ff87c8d9aa5121 Mon Sep 17 00:00:00 2001
From: Aleksander Morgado <aleksander@aleksander.es>
Date: Sun, 23 May 2021 12:17:40 +0200
Subject: [PATCH 03/39] base-manager: don't assume a MMDevice always holds a
MMModem
There are cases, e.g. during modem object disposal, where this is not
true.
---
src/mm-base-manager.c | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/src/mm-base-manager.c b/src/mm-base-manager.c
index 5880ffad..c900eeaa 100644
--- a/src/mm-base-manager.c
+++ b/src/mm-base-manager.c
@@ -703,9 +703,13 @@ mm_base_manager_sync (MMBaseManager *self)
/* Refresh each device */
g_hash_table_iter_init (&iter, self->priv->devices);
while (g_hash_table_iter_next (&iter, &key, &value)) {
- MMBaseModem *modem = mm_device_peek_modem (MM_DEVICE (value));
+ MMBaseModem *modem;
+
+ modem = mm_device_peek_modem (MM_DEVICE (value));
+
/* We just want to start the synchronization, we don't need the result */
- mm_base_modem_sync (modem, (GAsyncReadyCallback)mm_base_modem_sync_ready, NULL);
+ if (modem)
+ mm_base_modem_sync (modem, (GAsyncReadyCallback)mm_base_modem_sync_ready, NULL);
}
}
--
2.31.1

View file

@ -1,39 +0,0 @@
From d02fad407c451e90fc6cbc0ad99aba86ff303816 Mon Sep 17 00:00:00 2001
From: Aleksander Morgado <aleksander@aleksander.es>
Date: Sun, 23 May 2021 12:18:42 +0200
Subject: [PATCH 04/39] base-manager: avoid using the `mm_` prefix for static
private methods
---
src/mm-base-manager.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/src/mm-base-manager.c b/src/mm-base-manager.c
index c900eeaa..5af959fb 100644
--- a/src/mm-base-manager.c
+++ b/src/mm-base-manager.c
@@ -677,9 +677,9 @@ gboolean mm_base_modem_sync_finish (MMBaseModem *self,
}
static void
-mm_base_modem_sync_ready (MMBaseModem *self,
- GAsyncResult *res,
- gpointer user_data)
+base_modem_sync_ready (MMBaseModem *self,
+ GAsyncResult *res,
+ gpointer user_data)
{
g_autoptr(GError) error = NULL;
@@ -709,7 +709,7 @@ mm_base_manager_sync (MMBaseManager *self)
/* We just want to start the synchronization, we don't need the result */
if (modem)
- mm_base_modem_sync (modem, (GAsyncReadyCallback)mm_base_modem_sync_ready, NULL);
+ mm_base_modem_sync (modem, (GAsyncReadyCallback)base_modem_sync_ready, NULL);
}
}
--
2.31.1

View file

@ -1,101 +0,0 @@
From 261684e74d4d00df63d7106162e2d0bb42e9652c Mon Sep 17 00:00:00 2001
From: Aleksander Morgado <aleksander@aleksander.es>
Date: Sun, 23 May 2021 12:19:06 +0200
Subject: [PATCH 05/39] base-modem: fix modem_sync() operation handling
The mm_base_modem_sync() method is an asynchronous method that
receives a callback and user data, and therefore we MUST always
complete the async method calling that callback. Set that up with a
GTask as usual.
Also, the mm_base_modem_sync_finish() method should be implemented
along with mm_base_modem_sync(), not in the source file of the
caller of the async method. The finish() always depends on how the
async method was implemented, in our case using a GTask.
---
src/mm-base-manager.c | 7 -------
src/mm-base-modem.c | 34 +++++++++++++++++++++++++---------
2 files changed, 25 insertions(+), 16 deletions(-)
diff --git a/src/mm-base-manager.c b/src/mm-base-manager.c
index 5af959fb..236405bb 100644
--- a/src/mm-base-manager.c
+++ b/src/mm-base-manager.c
@@ -669,13 +669,6 @@ mm_base_manager_num_modems (MMBaseManager *self)
#if defined WITH_SYSTEMD_SUSPEND_RESUME
-gboolean mm_base_modem_sync_finish (MMBaseModem *self,
- GAsyncResult *res,
- GError **error)
-{
- return g_task_propagate_boolean (G_TASK (res), error);
-}
-
static void
base_modem_sync_ready (MMBaseModem *self,
GAsyncResult *res,
diff --git a/src/mm-base-modem.c b/src/mm-base-modem.c
index 38f43f8c..923f159a 100644
--- a/src/mm-base-modem.c
+++ b/src/mm-base-modem.c
@@ -499,16 +499,26 @@ mm_base_modem_wait_link_port (MMBaseModem *self,
/******************************************************************************/
+gboolean
+mm_base_modem_sync_finish (MMBaseModem *self,
+ GAsyncResult *res,
+ GError **error)
+{
+ return g_task_propagate_boolean (G_TASK (res), error);
+}
+
static void
-mm_base_modem_sync_ready (MMBaseModem *self,
- GAsyncResult *res)
+sync_ready (MMBaseModem *self,
+ GAsyncResult *res,
+ GTask *task)
{
- g_autoptr (GError) error = NULL;
+ g_autoptr(GError) error = NULL;
- MM_BASE_MODEM_GET_CLASS (self)->sync_finish (self, res, &error);
- if (error) {
- mm_obj_warn (self, "synchronization failed");
- }
+ if (!MM_BASE_MODEM_GET_CLASS (self)->sync_finish (self, res, &error))
+ g_task_return_error (task, error);
+ else
+ g_task_return_boolean (task, TRUE);
+ g_object_unref (task);
}
void
@@ -516,14 +526,20 @@ mm_base_modem_sync (MMBaseModem *self,
GAsyncReadyCallback callback,
gpointer user_data)
{
+ GTask *task;
+
+ task = g_task_new (self, NULL, callback, user_data);
+
g_assert (MM_BASE_MODEM_GET_CLASS (self)->sync != NULL);
g_assert (MM_BASE_MODEM_GET_CLASS (self)->sync_finish != NULL);
MM_BASE_MODEM_GET_CLASS (self)->sync (self,
- (GAsyncReadyCallback) mm_base_modem_sync_ready,
- NULL);
+ (GAsyncReadyCallback) sync_ready,
+ task);
}
+/******************************************************************************/
+
gboolean
mm_base_modem_disable_finish (MMBaseModem *self,
GAsyncResult *res,
--
2.31.1

View file

@ -1,32 +0,0 @@
From 053d3f84f0fe4b13ec4586b180cea4aba8fc01ea Mon Sep 17 00:00:00 2001
From: Aleksander Morgado <aleksander@aleksander.es>
Date: Sun, 23 May 2021 12:23:59 +0200
Subject: [PATCH 06/39] base-modem: don't fail if sync() isn't implemented
---
src/mm-base-modem.c | 9 +++++++--
1 file changed, 7 insertions(+), 2 deletions(-)
diff --git a/src/mm-base-modem.c b/src/mm-base-modem.c
index 923f159a..28519ad4 100644
--- a/src/mm-base-modem.c
+++ b/src/mm-base-modem.c
@@ -530,8 +530,13 @@ mm_base_modem_sync (MMBaseModem *self,
task = g_task_new (self, NULL, callback, user_data);
- g_assert (MM_BASE_MODEM_GET_CLASS (self)->sync != NULL);
- g_assert (MM_BASE_MODEM_GET_CLASS (self)->sync_finish != NULL);
+ if (!MM_BASE_MODEM_GET_CLASS (self)->sync ||
+ !MM_BASE_MODEM_GET_CLASS (self)->sync_finish) {
+ g_task_return_new_error (task, MM_CORE_ERROR, MM_CORE_ERROR_UNSUPPORTED,
+ "Suspend/resume quick synchronization unsupported");
+ g_object_unref (task);
+ return;
+ }
MM_BASE_MODEM_GET_CLASS (self)->sync (self,
(GAsyncReadyCallback) sync_ready,
--
2.31.1

View file

@ -1,74 +0,0 @@
From 4cf023022a07011120e18239722626efbded9180 Mon Sep 17 00:00:00 2001
From: Aleksander Morgado <aleksander@aleksander.es>
Date: Wed, 26 May 2021 10:36:47 +0200
Subject: [PATCH 07/39] base-modem: make sync() available only if
suspend-resume enabled
---
src/mm-base-modem.c | 4 ++++
src/mm-base-modem.h | 6 ++++++
2 files changed, 10 insertions(+)
diff --git a/src/mm-base-modem.c b/src/mm-base-modem.c
index 28519ad4..580103ba 100644
--- a/src/mm-base-modem.c
+++ b/src/mm-base-modem.c
@@ -499,6 +499,8 @@ mm_base_modem_wait_link_port (MMBaseModem *self,
/******************************************************************************/
+#if defined WITH_SYSTEMD_SUSPEND_RESUME
+
gboolean
mm_base_modem_sync_finish (MMBaseModem *self,
GAsyncResult *res,
@@ -543,6 +545,8 @@ mm_base_modem_sync (MMBaseModem *self,
task);
}
+#endif /* WITH_SYSTEMD_SUSPEND_RESUME */
+
/******************************************************************************/
gboolean
diff --git a/src/mm-base-modem.h b/src/mm-base-modem.h
index 75fd99f5..d9538251 100644
--- a/src/mm-base-modem.h
+++ b/src/mm-base-modem.h
@@ -102,6 +102,7 @@ struct _MMBaseModemClass {
GAsyncResult *res,
GError **error);
+#if defined WITH_SYSTEMD_SUSPEND_RESUME
/* Modem synchronization.
* When resuming in quick suspend/resume mode,
* this method triggers a synchronization of all modem interfaces */
@@ -111,6 +112,7 @@ struct _MMBaseModemClass {
gboolean (* sync_finish) (MMBaseModem *self,
GAsyncResult *res,
GError **error);
+#endif
/* signals */
void (* link_port_grabbed) (MMBaseModem *self,
@@ -215,6 +217,8 @@ gboolean mm_base_modem_disable_finish (MMBaseModem *self,
GAsyncResult *res,
GError **error);
+#if defined WITH_SYSTEMD_SUSPEND_RESUME
+
void mm_base_modem_sync (MMBaseModem *self,
GAsyncReadyCallback callback,
gpointer user_data);
@@ -222,6 +226,8 @@ gboolean mm_base_modem_sync_finish (MMBaseModem *self,
GAsyncResult *res,
GError **error);
+#endif
+
void mm_base_modem_process_sim_event (MMBaseModem *self);
#endif /* MM_BASE_MODEM_H */
--
2.31.1

View file

@ -1,31 +0,0 @@
From d5ccd5fa9d1b6b5a0367bee7da347efd460f12ca Mon Sep 17 00:00:00 2001
From: Aleksander Morgado <aleksander@aleksander.es>
Date: Sun, 23 May 2021 12:28:02 +0200
Subject: [PATCH 08/39] broadband-modem: ignore cancellation during sync()
There is no input cancellable in the method, so the GTask will never
get cancelled from the outside.
---
src/mm-broadband-modem.c | 6 ------
1 file changed, 6 deletions(-)
diff --git a/src/mm-broadband-modem.c b/src/mm-broadband-modem.c
index 6e47757e..7d928aa8 100644
--- a/src/mm-broadband-modem.c
+++ b/src/mm-broadband-modem.c
@@ -11364,12 +11364,6 @@ syncing_step (GTask *task)
MMBroadbandModem *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);
--
2.31.1

View file

@ -1,53 +0,0 @@
From d59ca53e142dcbbc6afa3d1ace97ac367f96986f Mon Sep 17 00:00:00 2001
From: Aleksander Morgado <aleksander@aleksander.es>
Date: Sun, 23 May 2021 12:35:07 +0200
Subject: [PATCH 09/39] broadband-modem: skip synchronization after resume if
not needed
The synchronization after resume should only be needed on enabled
modems, as otherwise there is really no chance that the state of the
modem may have changed during suspend.
E.g. if a modem is failed because it doesn't have a SIM card, or if
the SIM-PIN is locked, or if the modem has never been enabled, there
is no point in attempting to synchronize the runtime state of the
modem.
---
src/mm-broadband-modem.c | 17 ++++++++++++++---
1 file changed, 14 insertions(+), 3 deletions(-)
diff --git a/src/mm-broadband-modem.c b/src/mm-broadband-modem.c
index 7d928aa8..db6eb8ce 100644
--- a/src/mm-broadband-modem.c
+++ b/src/mm-broadband-modem.c
@@ -11396,13 +11396,24 @@ synchronize (MMBaseModem *self,
SyncingContext *ctx;
GTask *task;
+ task = g_task_new (MM_BROADBAND_MODEM (self), NULL, callback, user_data);
+
+ /* Synchronization after resume is not needed on modems that have never
+ * been enabled.
+ */
+ if (MM_BROADBAND_MODEM (self)->priv->modem_state < MM_MODEM_STATE_ENABLED) {
+ g_task_return_new_error (task, MM_CORE_ERROR, MM_CORE_ERROR_WRONG_STATE,
+ "Synchronization after resume not needed in modem state '%s'",
+ mm_modem_state_get_string (MM_BROADBAND_MODEM (self)->priv->modem_state));
+ g_object_unref (task);
+ return;
+ }
+
/* Create SyncingContext */
ctx = g_new0 (SyncingContext, 1);
ctx->step = SYNCING_STEP_FIRST;
-
- /* Create sync steps task and execute it */
- task = g_task_new (MM_BROADBAND_MODEM (self), NULL, callback, user_data);
g_task_set_task_data (task, ctx, (GDestroyNotify)g_free);
+
syncing_step (task);
}
--
2.31.1

View file

@ -1,196 +0,0 @@
From 5b3585829a4752a4b53e725a22858aa759fac472 Mon Sep 17 00:00:00 2001
From: Dylan Van Assche <me@dylanvanassche.be>
Date: Sat, 1 May 2021 15:53:55 +0200
Subject: [PATCH 10/39] iface-modem-time: synchronize state when resuming
On resume, fetch the current network time as
the network time may be changed when suspended.
---
src/mm-broadband-modem.c | 30 ++++++++++++++
src/mm-iface-modem-time.c | 84 +++++++++++++++++++++++++++++++++++++++
src/mm-iface-modem-time.h | 12 ++++++
3 files changed, 126 insertions(+)
diff --git a/src/mm-broadband-modem.c b/src/mm-broadband-modem.c
index db6eb8ce..0e4f4740 100644
--- a/src/mm-broadband-modem.c
+++ b/src/mm-broadband-modem.c
@@ -11343,6 +11343,7 @@ enable (MMBaseModem *self,
typedef enum {
SYNCING_STEP_FIRST,
+ SYNCING_STEP_IFACE_TIME,
SYNCING_STEP_LAST,
} SyncingStep;
@@ -11350,6 +11351,8 @@ typedef struct {
SyncingStep step;
} SyncingContext;
+static void syncing_step (GTask *task);
+
static gboolean
synchronize_finish (MMBaseModem *self,
GAsyncResult *res,
@@ -11358,6 +11361,24 @@ synchronize_finish (MMBaseModem *self,
return g_task_propagate_boolean (G_TASK (res), error);
}
+static void
+iface_modem_time_sync_ready (MMIfaceModemTime *self,
+ GAsyncResult *res,
+ GTask *task)
+{
+ SyncingContext *ctx;
+ g_autoptr(GError) error = NULL;
+
+ ctx = g_task_get_task_data (task);
+
+ if (!mm_iface_modem_time_sync_finish (self, res, &error))
+ mm_obj_warn (self, "time interface synchronization failed: %s", error->message);
+
+ /* Go on to next step */
+ ctx->step++;
+ syncing_step (task);
+}
+
static void
syncing_step (GTask *task)
{
@@ -11372,6 +11393,15 @@ syncing_step (GTask *task)
ctx->step++;
/* fall through */
+ case SYNCING_STEP_IFACE_TIME:
+ /*
+ * Synchronize asynchronously the Time interface.
+ */
+ mm_obj_info (self, "resume synchronization state (%d/%d): time interface sync",
+ ctx->step, SYNCING_STEP_LAST);
+ mm_iface_modem_time_sync (MM_IFACE_MODEM_TIME (self), (GAsyncReadyCallback)iface_modem_time_sync_ready, task);
+ return;
+
case SYNCING_STEP_LAST:
mm_obj_info (self, "resume synchronization state (%d/%d): all done",
ctx->step, SYNCING_STEP_LAST);
diff --git a/src/mm-iface-modem-time.c b/src/mm-iface-modem-time.c
index 5770e7b7..e262b71d 100644
--- a/src/mm-iface-modem-time.c
+++ b/src/mm-iface-modem-time.c
@@ -728,6 +728,90 @@ mm_iface_modem_time_enable (MMIfaceModemTime *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_NETWORK_TIMEZONE,
+ SYNCING_STEP_LAST
+} SyncingStep;
+
+struct _SyncingContext {
+ SyncingStep step;
+};
+
+gboolean
+mm_iface_modem_time_sync_finish (MMIfaceModemTime *self,
+ GAsyncResult *res,
+ GError **error)
+{
+ return g_task_propagate_boolean (G_TASK (res), error);
+}
+
+static void
+interface_syncing_step (GTask *task)
+{
+ MMIfaceModemTime *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_NETWORK_TIMEZONE:
+ /* We start it and schedule it to run asynchronously */
+ start_network_timezone (self);
+ 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_iface_modem_time_sync (MMIfaceModemTime *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
+
+/*****************************************************************************/
+
typedef struct _InitializationContext InitializationContext;
static void interface_initialization_step (GTask *task);
diff --git a/src/mm-iface-modem-time.h b/src/mm-iface-modem-time.h
index ca0640d6..a3ac7074 100644
--- a/src/mm-iface-modem-time.h
+++ b/src/mm-iface-modem-time.h
@@ -125,6 +125,18 @@ gboolean mm_iface_modem_time_disable_finish (MMIfaceModemTime *self,
/* Shutdown Time interface */
void mm_iface_modem_time_shutdown (MMIfaceModemTime *self);
+#if defined WITH_SYSTEMD_SUSPEND_RESUME
+
+/* Sync Time interface (async) */
+void mm_iface_modem_time_sync (MMIfaceModemTime *self,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+gboolean mm_iface_modem_time_sync_finish (MMIfaceModemTime *self,
+ GAsyncResult *res,
+ GError **error);
+
+#endif
+
/* Bind properties for simple GetStatus() */
void mm_iface_modem_time_bind_simple_status (MMIfaceModemTime *self,
MMSimpleStatus *status);
--
2.31.1

View file

@ -1,36 +0,0 @@
From 3ab85a1487e67ce8faf833bafc4c5dad430af396 Mon Sep 17 00:00:00 2001
From: Aleksander Morgado <aleksander@aleksander.es>
Date: Sun, 23 May 2021 14:31:13 +0200
Subject: [PATCH 11/39] broadband-modem: skip time interface sync if no time
support
---
src/mm-broadband-modem.c | 12 ++++++++----
1 file changed, 8 insertions(+), 4 deletions(-)
diff --git a/src/mm-broadband-modem.c b/src/mm-broadband-modem.c
index 0e4f4740..91e023b8 100644
--- a/src/mm-broadband-modem.c
+++ b/src/mm-broadband-modem.c
@@ -11397,10 +11397,14 @@ syncing_step (GTask *task)
/*
* Synchronize asynchronously the Time interface.
*/
- mm_obj_info (self, "resume synchronization state (%d/%d): time interface sync",
- ctx->step, SYNCING_STEP_LAST);
- mm_iface_modem_time_sync (MM_IFACE_MODEM_TIME (self), (GAsyncReadyCallback)iface_modem_time_sync_ready, task);
- return;
+ if (self->priv->modem_time_dbus_skeleton) {
+ mm_obj_info (self, "resume synchronization state (%d/%d): time interface sync",
+ ctx->step, SYNCING_STEP_LAST);
+ mm_iface_modem_time_sync (MM_IFACE_MODEM_TIME (self), (GAsyncReadyCallback)iface_modem_time_sync_ready, task);
+ return;
+ }
+ ctx->step++;
+ /* fall through */
case SYNCING_STEP_LAST:
mm_obj_info (self, "resume synchronization state (%d/%d): all done",
--
2.31.1

View file

@ -1,31 +0,0 @@
From 35872aad3036c9c98cd3b1b6201c8057ac74ffc3 Mon Sep 17 00:00:00 2001
From: Aleksander Morgado <aleksander@aleksander.es>
Date: Sun, 23 May 2021 15:44:45 +0200
Subject: [PATCH 12/39] iface-modem-time: ignore cancellation during sync()
There is no input cancellable in the method, so the GTask will never
get cancelled from the outside.
---
src/mm-iface-modem-time.c | 6 ------
1 file changed, 6 deletions(-)
diff --git a/src/mm-iface-modem-time.c b/src/mm-iface-modem-time.c
index e262b71d..0d4f3764 100644
--- a/src/mm-iface-modem-time.c
+++ b/src/mm-iface-modem-time.c
@@ -757,12 +757,6 @@ interface_syncing_step (GTask *task)
MMIfaceModemTime *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);
--
2.31.1

View file

@ -1,283 +0,0 @@
From f5acb7ce85fec0c6cf1d284c125008b961f7a56e Mon Sep 17 00:00:00 2001
From: Dylan Van Assche <me@dylanvanassche.be>
Date: Sat, 13 Mar 2021 19:28:19 +0100
Subject: [PATCH 13/39] iface-modem-3gpp: synchronize state when resuming
On resume, refresh the EPS bearers and 3GPP registration
as the registration and bearers may expired during suspend.
---
src/mm-broadband-modem.c | 31 +++++++
src/mm-iface-modem-3gpp.c | 177 ++++++++++++++++++++++++++++++++++++++
src/mm-iface-modem-3gpp.h | 12 +++
3 files changed, 220 insertions(+)
diff --git a/src/mm-broadband-modem.c b/src/mm-broadband-modem.c
index 91e023b8..05d72875 100644
--- a/src/mm-broadband-modem.c
+++ b/src/mm-broadband-modem.c
@@ -11343,6 +11343,7 @@ enable (MMBaseModem *self,
typedef enum {
SYNCING_STEP_FIRST,
+ SYNCING_STEP_IFACE_3GPP,
SYNCING_STEP_IFACE_TIME,
SYNCING_STEP_LAST,
} SyncingStep;
@@ -11379,6 +11380,24 @@ iface_modem_time_sync_ready (MMIfaceModemTime *self,
syncing_step (task);
}
+static void
+iface_modem_3gpp_sync_ready (MMBroadbandModem *self,
+ GAsyncResult *res,
+ GTask *task)
+{
+ SyncingContext *ctx;
+ g_autoptr(GError) error = NULL;
+
+ ctx = g_task_get_task_data (task);
+
+ if (!mm_iface_modem_3gpp_sync_finish (MM_IFACE_MODEM_3GPP (self), res, &error))
+ mm_obj_warn (self, "3GPP interface synchronization failed: %s", error->message);
+
+ /* Go on to next step */
+ ctx->step++;
+ syncing_step (task);
+}
+
static void
syncing_step (GTask *task)
{
@@ -11393,6 +11412,18 @@ syncing_step (GTask *task)
ctx->step++;
/* fall through */
+ case SYNCING_STEP_IFACE_3GPP:
+ /*
+ * Start interface 3GPP synchronization.
+ * We hardly depend on the registration and bearer status,
+ * therefore we cannot continue with the other steps until
+ * this one is finished.
+ */
+ mm_obj_info (self, "resume synchronization state (%d/%d): 3GPP interface sync",
+ ctx->step, SYNCING_STEP_LAST);
+ mm_iface_modem_3gpp_sync (MM_IFACE_MODEM_3GPP (self), (GAsyncReadyCallback)iface_modem_3gpp_sync_ready, task);
+ return;
+
case SYNCING_STEP_IFACE_TIME:
/*
* Synchronize asynchronously the Time interface.
diff --git a/src/mm-iface-modem-3gpp.c b/src/mm-iface-modem-3gpp.c
index 93899355..c435da87 100644
--- a/src/mm-iface-modem-3gpp.c
+++ b/src/mm-iface-modem-3gpp.c
@@ -2341,6 +2341,183 @@ mm_iface_modem_3gpp_enable (MMIfaceModem3gpp *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_3GPP_REGISTRATION,
+ SYNCING_STEP_REFRESH_EPS_BEARER,
+ SYNCING_STEP_LAST
+} SyncingStep;
+
+struct _SyncingContext {
+ SyncingStep step;
+};
+
+gboolean
+mm_iface_modem_3gpp_sync_finish (MMIfaceModem3gpp *self,
+ GAsyncResult *res,
+ GError **error)
+{
+ return g_task_propagate_boolean (G_TASK (res), error);
+}
+
+static void
+sync_eps_bearer_ready (MMIfaceModem3gpp *self,
+ GAsyncResult *res,
+ GTask *task)
+{
+ MMBearerProperties *properties;
+ SyncingContext *ctx;
+ g_autoptr (GError) error = NULL;
+
+ mm_obj_dbg (self, "EPS bearer sync ready");
+ ctx = g_task_get_task_data (task);
+
+ properties = MM_IFACE_MODEM_3GPP_GET_INTERFACE (self)->load_initial_eps_bearer_finish (self, res, &error);
+ if (!properties) {
+ mm_obj_dbg (self, "couldn't refresh EPS bearer properties: %s", error->message);
+ } else {
+ mm_iface_modem_3gpp_update_initial_eps_bearer (self, properties);
+ g_object_unref (properties);
+ }
+
+ /* Go on to next step */
+ ctx->step++;
+ interface_syncing_step (task);
+}
+
+static void
+sync_eps_bearer (MMIfaceModem3gpp *self,
+ GAsyncReadyCallback callback,
+ GTask *task)
+{
+ SyncingContext *ctx;
+ gboolean eps_supported = FALSE;
+
+ g_object_get (self,
+ MM_IFACE_MODEM_3GPP_EPS_NETWORK_SUPPORTED, &eps_supported,
+ NULL);
+
+ /* Refresh EPS bearer if supported */
+ if (eps_supported &&
+ MM_IFACE_MODEM_3GPP_GET_INTERFACE (self)->load_initial_eps_bearer &&
+ MM_IFACE_MODEM_3GPP_GET_INTERFACE (self)->load_initial_eps_bearer_finish) {
+ MM_IFACE_MODEM_3GPP_GET_INTERFACE (self)->load_initial_eps_bearer (
+ self,
+ callback,
+ task);
+ return;
+ }
+
+ /* If EPS is unsupported, just go to the next step */
+ ctx = g_task_get_task_data (task);
+ ctx->step++;
+ interface_syncing_step (task);
+}
+
+static void
+sync_registration_ready (MMIfaceModem3gpp *self,
+ GAsyncResult *res,
+ GTask *task)
+{
+ SyncingContext *ctx;
+ g_autoptr (GError) error = NULL;
+
+ ctx = g_task_get_task_data (task);
+
+ mm_iface_modem_3gpp_run_registration_checks_finish (self, res, &error);
+ if (error) {
+ mm_obj_dbg (self, "Synchronizing 3GPP registration failed: %s", error->message);
+ g_error_free (error);
+ }
+
+ /* Go on to next step */
+ ctx->step++;
+ interface_syncing_step(task);
+}
+
+static void
+interface_syncing_step (GTask *task)
+{
+ MMIfaceModem3gpp *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_3GPP_REGISTRATION:
+ /*
+ * Refresh registration info to verify that the modem is still registered.
+ * Wait until registration checks are complete before going to the next step.
+ */
+ mm_iface_modem_3gpp_run_registration_checks (
+ self,
+ (GAsyncReadyCallback)sync_registration_ready,
+ task);
+ return;
+
+ case SYNCING_STEP_REFRESH_EPS_BEARER:
+ /*
+ * Refresh EPS bearer and wait until complete.
+ * We want to make sure that the modem is fully enabled again
+ * when we refresh the mobile data connection bearers.
+ */
+ sync_eps_bearer (
+ self,
+ (GAsyncReadyCallback)sync_eps_bearer_ready,
+ task);
+ return;
+
+ 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_iface_modem_3gpp_sync (MMIfaceModem3gpp *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
+
+/*****************************************************************************/
+
typedef struct _InitializationContext InitializationContext;
static void interface_initialization_step (GTask *task);
diff --git a/src/mm-iface-modem-3gpp.h b/src/mm-iface-modem-3gpp.h
index 258e5c10..027bef0f 100644
--- a/src/mm-iface-modem-3gpp.h
+++ b/src/mm-iface-modem-3gpp.h
@@ -265,6 +265,18 @@ gboolean mm_iface_modem_3gpp_disable_finish (MMIfaceModem3gpp *self,
GAsyncResult *res,
GError **error);
+#if defined WITH_SYSTEMD_SUSPEND_RESUME
+
+/* Sync 3GPP interface (async) */
+void mm_iface_modem_3gpp_sync (MMIfaceModem3gpp *self,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+gboolean mm_iface_modem_3gpp_sync_finish (MMIfaceModem3gpp *self,
+ GAsyncResult *res,
+ GError **error);
+
+#endif
+
/* Shutdown Modem 3GPP interface */
void mm_iface_modem_3gpp_shutdown (MMIfaceModem3gpp *self);
--
2.31.1

View file

@ -1,44 +0,0 @@
From fa6b6f69d4a2646e6695722372d9aa6b3d327151 Mon Sep 17 00:00:00 2001
From: Aleksander Morgado <aleksander@aleksander.es>
Date: Sun, 23 May 2021 14:14:27 +0200
Subject: [PATCH 14/39] iface-modem-3gpp: use g_autoptr() for the
MMBearerProperties during sync
---
src/mm-iface-modem-3gpp.c | 14 ++++++--------
1 file changed, 6 insertions(+), 8 deletions(-)
diff --git a/src/mm-iface-modem-3gpp.c b/src/mm-iface-modem-3gpp.c
index c435da87..c6db5e4f 100644
--- a/src/mm-iface-modem-3gpp.c
+++ b/src/mm-iface-modem-3gpp.c
@@ -2370,20 +2370,18 @@ sync_eps_bearer_ready (MMIfaceModem3gpp *self,
GAsyncResult *res,
GTask *task)
{
- MMBearerProperties *properties;
- SyncingContext *ctx;
- g_autoptr (GError) error = NULL;
+ SyncingContext *ctx;
+ g_autoptr(MMBearerProperties) properties = NULL;
+ g_autoptr(GError) error = NULL;
mm_obj_dbg (self, "EPS bearer sync ready");
ctx = g_task_get_task_data (task);
properties = MM_IFACE_MODEM_3GPP_GET_INTERFACE (self)->load_initial_eps_bearer_finish (self, res, &error);
- if (!properties) {
- mm_obj_dbg (self, "couldn't refresh EPS bearer properties: %s", error->message);
- } else {
+ if (!properties)
+ mm_obj_dbg (self, "couldn't refresh initial EPS bearer status: %s", error->message);
+ else
mm_iface_modem_3gpp_update_initial_eps_bearer (self, properties);
- g_object_unref (properties);
- }
/* Go on to next step */
ctx->step++;
--
2.31.1

View file

@ -1,31 +0,0 @@
From 4edb8e6c04347a0224d782f27ada1ad8d984fc91 Mon Sep 17 00:00:00 2001
From: Aleksander Morgado <aleksander@aleksander.es>
Date: Sun, 23 May 2021 14:15:30 +0200
Subject: [PATCH 15/39] iface-modem-3gpp: fix double GError free on
registration sync failure
---
src/mm-iface-modem-3gpp.c | 7 ++-----
1 file changed, 2 insertions(+), 5 deletions(-)
diff --git a/src/mm-iface-modem-3gpp.c b/src/mm-iface-modem-3gpp.c
index c6db5e4f..f0e9fe31 100644
--- a/src/mm-iface-modem-3gpp.c
+++ b/src/mm-iface-modem-3gpp.c
@@ -2427,11 +2427,8 @@ sync_registration_ready (MMIfaceModem3gpp *self,
ctx = g_task_get_task_data (task);
- mm_iface_modem_3gpp_run_registration_checks_finish (self, res, &error);
- if (error) {
- mm_obj_dbg (self, "Synchronizing 3GPP registration failed: %s", error->message);
- g_error_free (error);
- }
+ if (!mm_iface_modem_3gpp_run_registration_checks_finish (self, res, &error))
+ mm_obj_dbg (self, "couldn't synchronize 3GPP registration: %s", error->message);
/* Go on to next step */
ctx->step++;
--
2.31.1

View file

@ -1,25 +0,0 @@
From 346ca78aa710c0081af08838d5f31fc5a76065c2 Mon Sep 17 00:00:00 2001
From: Aleksander Morgado <aleksander@aleksander.es>
Date: Sun, 23 May 2021 14:17:57 +0200
Subject: [PATCH 16/39] iface-modem-3gpp: remove redundant log message
It doesn't give us any valuable information, so just remove it.
---
src/mm-iface-modem-3gpp.c | 1 -
1 file changed, 1 deletion(-)
diff --git a/src/mm-iface-modem-3gpp.c b/src/mm-iface-modem-3gpp.c
index f0e9fe31..cc39fa08 100644
--- a/src/mm-iface-modem-3gpp.c
+++ b/src/mm-iface-modem-3gpp.c
@@ -2374,7 +2374,6 @@ sync_eps_bearer_ready (MMIfaceModem3gpp *self,
g_autoptr(MMBearerProperties) properties = NULL;
g_autoptr(GError) error = NULL;
- mm_obj_dbg (self, "EPS bearer sync ready");
ctx = g_task_get_task_data (task);
properties = MM_IFACE_MODEM_3GPP_GET_INTERFACE (self)->load_initial_eps_bearer_finish (self, res, &error);
--
2.31.1

View file

@ -1,31 +0,0 @@
From 290de72a45dd44ae376299d239390ff477c93982 Mon Sep 17 00:00:00 2001
From: Aleksander Morgado <aleksander@aleksander.es>
Date: Sun, 23 May 2021 15:44:22 +0200
Subject: [PATCH 17/39] iface-modem-3gpp: ignore cancellation during sync()
There is no input cancellable in the method, so the GTask will never
get cancelled from the outside.
---
src/mm-iface-modem-3gpp.c | 6 ------
1 file changed, 6 deletions(-)
diff --git a/src/mm-iface-modem-3gpp.c b/src/mm-iface-modem-3gpp.c
index cc39fa08..660eec65 100644
--- a/src/mm-iface-modem-3gpp.c
+++ b/src/mm-iface-modem-3gpp.c
@@ -2440,12 +2440,6 @@ interface_syncing_step (GTask *task)
MMIfaceModem3gpp *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);
--
2.31.1

View file

@ -1,38 +0,0 @@
From beaefd7ce80732a90597561eb28d103c4249d471 Mon Sep 17 00:00:00 2001
From: Aleksander Morgado <aleksander@aleksander.es>
Date: Sun, 23 May 2021 14:26:12 +0200
Subject: [PATCH 18/39] broadband-modem: fix type in the ready() for
iface_modem_3gpp_sync()
When calling an async method ona given type, the convention is to use
the same type in the corresponding ready() method, so that we can use
it without additional casts on the finish().
---
src/mm-broadband-modem.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/mm-broadband-modem.c b/src/mm-broadband-modem.c
index 05d72875..908795cf 100644
--- a/src/mm-broadband-modem.c
+++ b/src/mm-broadband-modem.c
@@ -11381,7 +11381,7 @@ iface_modem_time_sync_ready (MMIfaceModemTime *self,
}
static void
-iface_modem_3gpp_sync_ready (MMBroadbandModem *self,
+iface_modem_3gpp_sync_ready (MMIfaceModem3gpp *self,
GAsyncResult *res,
GTask *task)
{
@@ -11390,7 +11390,7 @@ iface_modem_3gpp_sync_ready (MMBroadbandModem *self,
ctx = g_task_get_task_data (task);
- if (!mm_iface_modem_3gpp_sync_finish (MM_IFACE_MODEM_3GPP (self), res, &error))
+ if (!mm_iface_modem_3gpp_sync_finish (self, res, &error))
mm_obj_warn (self, "3GPP interface synchronization failed: %s", error->message);
/* Go on to next step */
--
2.31.1

View file

@ -1,36 +0,0 @@
From 1bfbb4a27fe5d88332dd1394c6b3aae4527661f6 Mon Sep 17 00:00:00 2001
From: Aleksander Morgado <aleksander@aleksander.es>
Date: Sun, 23 May 2021 14:32:20 +0200
Subject: [PATCH 19/39] broadband-modem: skip 3GPP interface sync if no 3GPP
support
---
src/mm-broadband-modem.c | 12 ++++++++----
1 file changed, 8 insertions(+), 4 deletions(-)
diff --git a/src/mm-broadband-modem.c b/src/mm-broadband-modem.c
index 908795cf..05a86af3 100644
--- a/src/mm-broadband-modem.c
+++ b/src/mm-broadband-modem.c
@@ -11419,10 +11419,14 @@ syncing_step (GTask *task)
* therefore we cannot continue with the other steps until
* this one is finished.
*/
- mm_obj_info (self, "resume synchronization state (%d/%d): 3GPP interface sync",
- ctx->step, SYNCING_STEP_LAST);
- mm_iface_modem_3gpp_sync (MM_IFACE_MODEM_3GPP (self), (GAsyncReadyCallback)iface_modem_3gpp_sync_ready, task);
- return;
+ if (self->priv->modem_3gpp_dbus_skeleton) {
+ mm_obj_info (self, "resume synchronization state (%d/%d): 3GPP interface sync",
+ ctx->step, SYNCING_STEP_LAST);
+ mm_iface_modem_3gpp_sync (MM_IFACE_MODEM_3GPP (self), (GAsyncReadyCallback)iface_modem_3gpp_sync_ready, task);
+ return;
+ }
+ ctx->step++;
+ /* fall through */
case SYNCING_STEP_IFACE_TIME:
/*
--
2.31.1

View file

@ -1,371 +0,0 @@
From 97cbdf4eb409afa4a7eca6d8dbadc65c39a008b1 Mon Sep 17 00:00:00 2001
From: Dylan Van Assche <me@dylanvanassche.be>
Date: Sun, 14 Mar 2021 09:53:49 +0100
Subject: [PATCH 20/39] iface-modem: synchronize state when resuming
Refresh signal strength and access technologies,
check for SIM swaps, and check if the SIM is locked.
The modem may have switched to a different
access technologies or have a different signal strength
when resuming. Moreover, the user may swap or remove
the SIM when suspended.
---
src/mm-broadband-modem.c | 44 ++++++++++
src/mm-iface-modem-3gpp.c | 2 +-
src/mm-iface-modem.c | 177 ++++++++++++++++++++++++++++++++++++--
src/mm-iface-modem.h | 23 ++++-
4 files changed, 238 insertions(+), 8 deletions(-)
diff --git a/src/mm-broadband-modem.c b/src/mm-broadband-modem.c
index 05a86af3..b99a38a6 100644
--- a/src/mm-broadband-modem.c
+++ b/src/mm-broadband-modem.c
@@ -11343,6 +11343,7 @@ enable (MMBaseModem *self,
typedef enum {
SYNCING_STEP_FIRST,
+ SYNCING_STEP_IFACE_MODEM,
SYNCING_STEP_IFACE_3GPP,
SYNCING_STEP_IFACE_TIME,
SYNCING_STEP_LAST,
@@ -11398,6 +11399,36 @@ iface_modem_3gpp_sync_ready (MMIfaceModem3gpp *self,
syncing_step (task);
}
+static void
+iface_modem_sync_ready (MMIfaceModem *self,
+ GAsyncResult *res,
+ GTask *task)
+{
+ SyncingContext *ctx;
+ MMModemLock lock;
+ g_autoptr (GError) error = NULL;
+
+ ctx = g_task_get_task_data (task);
+ lock = mm_iface_modem_get_unlock_required (self);
+
+ if (!mm_iface_modem_sync_finish (self, res, &error)) {
+ mm_obj_warn (self, "synchronizing Modem interface failed: %s", error->message);
+ }
+
+ /* SIM is locked, skip synchronization */
+ if (lock == MM_MODEM_LOCK_UNKNOWN || lock == MM_MODEM_LOCK_SIM_PIN || lock == MM_MODEM_LOCK_SIM_PUK) {
+ mm_obj_warn (self, "SIM is locked... Synchronization skipped");
+ ctx->step = SYNCING_STEP_LAST;
+ syncing_step (task);
+ }
+
+ /* Not locked, go on to next step */
+ mm_obj_dbg (self, "modem unlocked, continue synchronization");
+ ctx->step++;
+ syncing_step (task);
+ return;
+}
+
static void
syncing_step (GTask *task)
{
@@ -11412,6 +11443,19 @@ syncing_step (GTask *task)
ctx->step++;
/* fall through */
+ case SYNCING_STEP_IFACE_MODEM:
+ /*
+ * Start interface Modem synchronization.
+ * We want to make sure that the SIM is unlocked and not swapped before
+ * synchronizing other interfaces.
+ */
+ mm_obj_info (self, "resume synchronization state (%d/%d): Modem interface sync",
+ ctx->step, SYNCING_STEP_LAST);
+ mm_iface_modem_sync (MM_IFACE_MODEM (self),
+ (GAsyncReadyCallback)iface_modem_sync_ready,
+ task);
+ return;
+
case SYNCING_STEP_IFACE_3GPP:
/*
* Start interface 3GPP synchronization.
diff --git a/src/mm-iface-modem-3gpp.c b/src/mm-iface-modem-3gpp.c
index 660eec65..ea1ab7cb 100644
--- a/src/mm-iface-modem-3gpp.c
+++ b/src/mm-iface-modem-3gpp.c
@@ -314,7 +314,7 @@ run_registration_checks_ready (MMIfaceModem3gpp *self,
* from home to roaming or viceversa, both registered states, so there
* wouldn't be an explicit refresh triggered from the modem interface as
* the modem never got un-registered during the sequence. */
- mm_iface_modem_refresh_signal (MM_IFACE_MODEM (ctx->self));
+ mm_iface_modem_refresh_signal (MM_IFACE_MODEM (ctx->self), FALSE);
mm_obj_dbg (self, "currently registered in a 3GPP network");
g_task_return_boolean (task, TRUE);
g_object_unref (task);
diff --git a/src/mm-iface-modem.c b/src/mm-iface-modem.c
index 7a84a6d2..f208e92a 100644
--- a/src/mm-iface-modem.c
+++ b/src/mm-iface-modem.c
@@ -1587,12 +1587,28 @@ periodic_signal_check_cb (MMIfaceModem *self)
}
void
-mm_iface_modem_refresh_signal (MMIfaceModem *self)
+mm_iface_modem_refresh_signal (MMIfaceModem *self,
+ gboolean enforce)
{
SignalCheckContext *ctx;
- /* Don't refresh polling if we're not enabled */
ctx = get_signal_check_context (self);
+
+ /*
+ * If enforced, poll once explicitly to make sure the signal strength
+ * and access technologies are updated.
+ *
+ * Modems with signal indication support block periodic polling scheduling.
+ * With enforce == TRUE, the periodic polling logic can run once as
+ * it override once the periodic polling prohibition.
+ * When the polling is complete, the periodic polling scheduling
+ * is blocked again to avoid that modems with signal indication support
+ * are periodic polled for their signal status.
+ */
+ if (enforce)
+ ctx->enabled = TRUE;
+
+ /* Don't refresh polling if we're not enabled */
if (!ctx->enabled) {
mm_obj_dbg (self, "periodic signal check refresh ignored: checks not enabled");
return;
@@ -1671,7 +1687,7 @@ periodic_signal_check_enable (MMIfaceModem *self)
}
/* And refresh, which will trigger the first check at high frequency */
- mm_iface_modem_refresh_signal (self);
+ mm_iface_modem_refresh_signal (self, FALSE);
}
/*****************************************************************************/
@@ -2345,7 +2361,7 @@ set_current_capabilities_ready (MMIfaceModem *self,
g_dbus_method_invocation_take_error (ctx->invocation, error);
else {
/* Capabilities updated: explicitly refresh signal and access technology */
- mm_iface_modem_refresh_signal (self);
+ mm_iface_modem_refresh_signal (self, FALSE);
mm_gdbus_modem_complete_set_current_capabilities (ctx->skeleton, ctx->invocation);
}
@@ -2835,7 +2851,7 @@ handle_set_current_bands_ready (MMIfaceModem *self,
g_dbus_method_invocation_take_error (ctx->invocation, error);
else {
/* Bands updated: explicitly refresh signal and access technology */
- mm_iface_modem_refresh_signal (self);
+ mm_iface_modem_refresh_signal (self, FALSE);
mm_gdbus_modem_complete_set_current_bands (ctx->skeleton, ctx->invocation);
}
@@ -3222,7 +3238,7 @@ handle_set_current_modes_ready (MMIfaceModem *self,
g_dbus_method_invocation_take_error (ctx->invocation, error);
else {
/* Modes updated: explicitly refresh signal and access technology */
- mm_iface_modem_refresh_signal (self);
+ mm_iface_modem_refresh_signal (self, FALSE);
mm_gdbus_modem_complete_set_current_modes (ctx->skeleton, ctx->invocation);
}
@@ -4206,6 +4222,155 @@ mm_iface_modem_enable (MMIfaceModem *self,
interface_enabling_step (task);
}
+/*****************************************************************************/
+/* MODEM SYNCHRONIZATION */
+
+#if defined WITH_SYSTEMD_SUSPEND_RESUME
+
+typedef struct _SyncingContext SyncingContext;
+static void interface_syncing_step (GTask *task);
+
+typedef enum {
+ SYNCING_STEP_FIRST,
+ SYNCING_STEP_DETECT_SIM_SWAP,
+ SYNCING_STEP_REFRESH_SIM_LOCK,
+ SYNCING_STEP_REFRESH_SIGNAL_STRENGTH,
+ SYNCING_STEP_LAST
+} SyncingStep;
+
+struct _SyncingContext {
+ SyncingStep step;
+};
+
+gboolean
+mm_iface_modem_sync_finish (MMIfaceModem *self,
+ GAsyncResult *res,
+ GError **error)
+{
+ return g_task_propagate_boolean (G_TASK (res), error);
+}
+
+static void
+sync_sim_lock_ready (MMIfaceModem *self,
+ GAsyncResult *res,
+ GTask *task)
+{
+ SyncingContext *ctx;
+ g_autoptr (GError) error = NULL;
+
+ ctx = g_task_get_task_data (task);
+
+ if (!MM_IFACE_MODEM_GET_INTERFACE (self)->load_unlock_required_finish (self, res, &error))
+ mm_obj_warn (self, "checking sim lock status failed: %s", error->message);
+
+ /* Go on to next step */
+ ctx->step++;
+ interface_syncing_step (task);
+}
+
+static void
+sync_detect_sim_swap_ready (MMIfaceModem *self,
+ GAsyncResult *res,
+ GTask *task)
+{
+ SyncingContext *ctx;
+ g_autoptr (GError) error = NULL;
+
+ ctx = g_task_get_task_data (task);
+
+ if (!mm_iface_modem_check_for_sim_swap_finish (self, res, &error))
+ mm_obj_warn (self, "checking sim swap failed: %s", error->message);
+
+ /* Go on to next step */
+ ctx->step++;
+ interface_syncing_step (task);
+}
+
+static void
+interface_syncing_step (GTask *task)
+{
+ MMIfaceModem *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_DETECT_SIM_SWAP:
+ /*
+ * Detect possible SIM swaps.
+ * Checking lock status in all cases after possible SIM swaps are detected.
+ */
+ mm_iface_modem_check_for_sim_swap (
+ self,
+ 0,
+ NULL,
+ (GAsyncReadyCallback)sync_detect_sim_swap_ready,
+ task);
+ return;
+
+ case SYNCING_STEP_REFRESH_SIM_LOCK:
+ /*
+ * Refresh SIM lock status and wait until complete.
+ */
+ MM_IFACE_MODEM_GET_INTERFACE (self)->load_unlock_required (
+ self,
+ FALSE,
+ (GAsyncReadyCallback)sync_sim_lock_ready,
+ task);
+ return;
+
+ case SYNCING_STEP_REFRESH_SIGNAL_STRENGTH:
+ /*
+ * Start a signal strength and access technologies refresh sequence.
+ */
+ mm_iface_modem_refresh_signal (self, TRUE);
+ 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_iface_modem_sync (MMIfaceModem *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
+
/*****************************************************************************/
/* MODEM INITIALIZATION */
diff --git a/src/mm-iface-modem.h b/src/mm-iface-modem.h
index 66d43ac0..1cd4bdd1 100644
--- a/src/mm-iface-modem.h
+++ b/src/mm-iface-modem.h
@@ -460,6 +460,27 @@ gboolean mm_iface_modem_disable_finish (MMIfaceModem *self,
GAsyncResult *res,
GError **error);
+/* Shutdown Modem interface */
+void mm_iface_modem_shutdown (MMIfaceModem *self);
+
+/* Helper to return an error when the modem is in failed state and so it
+ * cannot process a given method invocation
+ */
+gboolean mm_iface_modem_abort_invocation_if_state_not_reached (MMIfaceModem *self,
+ GDBusMethodInvocation *invocation,
+ MMModemState minimum_required);
+#if defined WITH_SYSTEMD_SUSPEND_RESUME
+
+/* Sync Modem interface (async) */
+void mm_iface_modem_sync (MMIfaceModem *self,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+gboolean mm_iface_modem_sync_finish (MMIfaceModem *self,
+ GAsyncResult *res,
+ GError **error);
+
+#endif
+
/* Allow setting power state */
void mm_iface_modem_set_power_state (MMIfaceModem *self,
MMModemPowerState power_state,
@@ -526,7 +547,7 @@ void mm_iface_modem_update_signal_quality (MMIfaceModem *self,
guint signal_quality);
/* Allow requesting to refresh signal via polling */
-void mm_iface_modem_refresh_signal (MMIfaceModem *self);
+void mm_iface_modem_refresh_signal (MMIfaceModem *self, gboolean enforce);
/* Allow setting allowed modes */
void mm_iface_modem_set_current_modes (MMIfaceModem *self,
--
2.31.1

View file

@ -1,32 +0,0 @@
From 3ecb20084844dfccad6353abf38505d3c7635fd4 Mon Sep 17 00:00:00 2001
From: Aleksander Morgado <aleksander@aleksander.es>
Date: Sun, 23 May 2021 14:34:35 +0200
Subject: [PATCH 21/39] broadband-modem: fail synchronization if no modem
exported in DBus
---
src/mm-broadband-modem.c | 8 +++++++-
1 file changed, 7 insertions(+), 1 deletion(-)
diff --git a/src/mm-broadband-modem.c b/src/mm-broadband-modem.c
index b99a38a6..8c5f7acd 100644
--- a/src/mm-broadband-modem.c
+++ b/src/mm-broadband-modem.c
@@ -11449,7 +11449,13 @@ syncing_step (GTask *task)
* We want to make sure that the SIM is unlocked and not swapped before
* synchronizing other interfaces.
*/
- mm_obj_info (self, "resume synchronization state (%d/%d): Modem interface sync",
+ if (!self->priv->modem_dbus_skeleton) {
+ g_task_return_new_error (task, MM_CORE_ERROR, MM_CORE_ERROR_ABORTED,
+ "Synchronization aborted: no modem exposed in DBus");
+ g_object_unref (task);
+ return;
+ }
+ mm_obj_info (self, "resume synchronization state (%d/%d): modem interface sync",
ctx->step, SYNCING_STEP_LAST);
mm_iface_modem_sync (MM_IFACE_MODEM (self),
(GAsyncReadyCallback)iface_modem_sync_ready,
--
2.31.1

View file

@ -1,25 +0,0 @@
From 82327e5898d77d0583e7f28f9d004df6a19f70b1 Mon Sep 17 00:00:00 2001
From: Aleksander Morgado <aleksander@aleksander.es>
Date: Sun, 23 May 2021 14:44:09 +0200
Subject: [PATCH 22/39] broadband-modem: fix state machine logic when
synchronizing modem interface
---
src/mm-broadband-modem.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/src/mm-broadband-modem.c b/src/mm-broadband-modem.c
index 8c5f7acd..ac5fbb1c 100644
--- a/src/mm-broadband-modem.c
+++ b/src/mm-broadband-modem.c
@@ -11420,6 +11420,7 @@ iface_modem_sync_ready (MMIfaceModem *self,
mm_obj_warn (self, "SIM is locked... Synchronization skipped");
ctx->step = SYNCING_STEP_LAST;
syncing_step (task);
+ return;
}
/* Not locked, go on to next step */
--
2.31.1

View file

@ -1,63 +0,0 @@
From f466eda93a2a28421557ec9a7f1bf5d0aec7dd00 Mon Sep 17 00:00:00 2001
From: Aleksander Morgado <aleksander@aleksander.es>
Date: Sun, 23 May 2021 14:44:44 +0200
Subject: [PATCH 23/39] broadband-modem: abort sync if locked SIM card found
We made sure that the after resume synchronization was only started on
modems that had been enabled (and so unlocked). If we detect a locked
SIM card during the sync operation, it's either because the SIM card
was swapped, or because the modem was fully shutdown during the
suspension (and so the SIM requires SIM-PIN again).
Either way, we cannot sync the state cleanly at this point, we must
trigger a full modem reprobe in order to move back the modem state to
Locked.
---
src/mm-broadband-modem.c | 26 +++++++++++++++-----------
1 file changed, 15 insertions(+), 11 deletions(-)
diff --git a/src/mm-broadband-modem.c b/src/mm-broadband-modem.c
index ac5fbb1c..d9a6d6ac 100644
--- a/src/mm-broadband-modem.c
+++ b/src/mm-broadband-modem.c
@@ -11404,22 +11404,26 @@ iface_modem_sync_ready (MMIfaceModem *self,
GAsyncResult *res,
GTask *task)
{
- SyncingContext *ctx;
- MMModemLock lock;
- g_autoptr (GError) error = NULL;
+ SyncingContext *ctx;
+ MMModemLock lock;
+ g_autoptr(GError) error = NULL;
ctx = g_task_get_task_data (task);
- lock = mm_iface_modem_get_unlock_required (self);
- if (!mm_iface_modem_sync_finish (self, res, &error)) {
- mm_obj_warn (self, "synchronizing Modem interface failed: %s", error->message);
- }
+ if (!mm_iface_modem_sync_finish (self, res, &error))
+ mm_obj_warn (self, "modem interface synchronization failed: %s", error->message);
- /* SIM is locked, skip synchronization */
+ /* The synchronization logic only runs on modems that were enabled before
+ * the suspend/resume cycle, and therefore we should not get SIM-PIN locked
+ * at this point, unless the SIM was swapped. */
+ lock = mm_iface_modem_get_unlock_required (self);
if (lock == MM_MODEM_LOCK_UNKNOWN || lock == MM_MODEM_LOCK_SIM_PIN || lock == MM_MODEM_LOCK_SIM_PUK) {
- mm_obj_warn (self, "SIM is locked... Synchronization skipped");
- ctx->step = SYNCING_STEP_LAST;
- syncing_step (task);
+ /* Abort the sync() operation right away, and report a new SIM event that will
+ * disable the modem and trigger a full reprobe */
+ mm_obj_warn (self, "SIM is locked... synchronization aborted");
+ g_task_return_new_error (task, MM_CORE_ERROR, MM_CORE_ERROR_ABORTED,
+ "Locked SIM found during modem interface synchronization");
+ g_object_unref (task);
return;
}
--
2.31.1

View file

@ -1,129 +0,0 @@
From a414efa690d880b2037a084f33e05db4c2208123 Mon Sep 17 00:00:00 2001
From: Aleksander Morgado <aleksander@aleksander.es>
Date: Sun, 23 May 2021 15:40:36 +0200
Subject: [PATCH 24/39] iface-modem: remove the signal quality enforced refresh
during sync()
when mm_iface_modem_refresh_signal() is called, we'll restart the
signal quality refresh logic already, there is no need to request
an enforced start.
The enforced start was also modifying ctx->enabled unconditionally,
which is really not ok. This logic would be enabled only when we're
registered, and that logic is fine, no need to change that.
---
src/mm-iface-modem-3gpp.c | 2 +-
src/mm-iface-modem.c | 29 +++++++----------------------
src/mm-iface-modem.h | 2 +-
3 files changed, 9 insertions(+), 24 deletions(-)
diff --git a/src/mm-iface-modem-3gpp.c b/src/mm-iface-modem-3gpp.c
index ea1ab7cb..660eec65 100644
--- a/src/mm-iface-modem-3gpp.c
+++ b/src/mm-iface-modem-3gpp.c
@@ -314,7 +314,7 @@ run_registration_checks_ready (MMIfaceModem3gpp *self,
* from home to roaming or viceversa, both registered states, so there
* wouldn't be an explicit refresh triggered from the modem interface as
* the modem never got un-registered during the sequence. */
- mm_iface_modem_refresh_signal (MM_IFACE_MODEM (ctx->self), FALSE);
+ mm_iface_modem_refresh_signal (MM_IFACE_MODEM (ctx->self));
mm_obj_dbg (self, "currently registered in a 3GPP network");
g_task_return_boolean (task, TRUE);
g_object_unref (task);
diff --git a/src/mm-iface-modem.c b/src/mm-iface-modem.c
index f208e92a..85df77bd 100644
--- a/src/mm-iface-modem.c
+++ b/src/mm-iface-modem.c
@@ -1587,27 +1587,12 @@ periodic_signal_check_cb (MMIfaceModem *self)
}
void
-mm_iface_modem_refresh_signal (MMIfaceModem *self,
- gboolean enforce)
+mm_iface_modem_refresh_signal (MMIfaceModem *self)
{
SignalCheckContext *ctx;
ctx = get_signal_check_context (self);
- /*
- * If enforced, poll once explicitly to make sure the signal strength
- * and access technologies are updated.
- *
- * Modems with signal indication support block periodic polling scheduling.
- * With enforce == TRUE, the periodic polling logic can run once as
- * it override once the periodic polling prohibition.
- * When the polling is complete, the periodic polling scheduling
- * is blocked again to avoid that modems with signal indication support
- * are periodic polled for their signal status.
- */
- if (enforce)
- ctx->enabled = TRUE;
-
/* Don't refresh polling if we're not enabled */
if (!ctx->enabled) {
mm_obj_dbg (self, "periodic signal check refresh ignored: checks not enabled");
@@ -1687,7 +1672,7 @@ periodic_signal_check_enable (MMIfaceModem *self)
}
/* And refresh, which will trigger the first check at high frequency */
- mm_iface_modem_refresh_signal (self, FALSE);
+ mm_iface_modem_refresh_signal (self);
}
/*****************************************************************************/
@@ -2361,7 +2346,7 @@ set_current_capabilities_ready (MMIfaceModem *self,
g_dbus_method_invocation_take_error (ctx->invocation, error);
else {
/* Capabilities updated: explicitly refresh signal and access technology */
- mm_iface_modem_refresh_signal (self, FALSE);
+ mm_iface_modem_refresh_signal (self);
mm_gdbus_modem_complete_set_current_capabilities (ctx->skeleton, ctx->invocation);
}
@@ -2851,7 +2836,7 @@ handle_set_current_bands_ready (MMIfaceModem *self,
g_dbus_method_invocation_take_error (ctx->invocation, error);
else {
/* Bands updated: explicitly refresh signal and access technology */
- mm_iface_modem_refresh_signal (self, FALSE);
+ mm_iface_modem_refresh_signal (self);
mm_gdbus_modem_complete_set_current_bands (ctx->skeleton, ctx->invocation);
}
@@ -3238,7 +3223,7 @@ handle_set_current_modes_ready (MMIfaceModem *self,
g_dbus_method_invocation_take_error (ctx->invocation, error);
else {
/* Modes updated: explicitly refresh signal and access technology */
- mm_iface_modem_refresh_signal (self, FALSE);
+ mm_iface_modem_refresh_signal (self);
mm_gdbus_modem_complete_set_current_modes (ctx->skeleton, ctx->invocation);
}
@@ -4332,9 +4317,9 @@ interface_syncing_step (GTask *task)
case SYNCING_STEP_REFRESH_SIGNAL_STRENGTH:
/*
- * Start a signal strength and access technologies refresh sequence.
+ * Restart the signal strength and access technologies refresh sequence.
*/
- mm_iface_modem_refresh_signal (self, TRUE);
+ mm_iface_modem_refresh_signal (self);
ctx->step++;
/* fall through */
diff --git a/src/mm-iface-modem.h b/src/mm-iface-modem.h
index 1cd4bdd1..5ba2167c 100644
--- a/src/mm-iface-modem.h
+++ b/src/mm-iface-modem.h
@@ -547,7 +547,7 @@ void mm_iface_modem_update_signal_quality (MMIfaceModem *self,
guint signal_quality);
/* Allow requesting to refresh signal via polling */
-void mm_iface_modem_refresh_signal (MMIfaceModem *self, gboolean enforce);
+void mm_iface_modem_refresh_signal (MMIfaceModem *self);
/* Allow setting allowed modes */
void mm_iface_modem_set_current_modes (MMIfaceModem *self,
--
2.31.1

View file

@ -1,31 +0,0 @@
From fc25dae6d8f433244c1126908531b5961db5776d Mon Sep 17 00:00:00 2001
From: Aleksander Morgado <aleksander@aleksander.es>
Date: Sun, 23 May 2021 15:43:52 +0200
Subject: [PATCH 25/39] iface-modem: ignore cancellation during sync()
There is no input cancellable in the method, so the GTask will never
get cancelled from the outside.
---
src/mm-iface-modem.c | 6 ------
1 file changed, 6 deletions(-)
diff --git a/src/mm-iface-modem.c b/src/mm-iface-modem.c
index 85df77bd..b298eb89 100644
--- a/src/mm-iface-modem.c
+++ b/src/mm-iface-modem.c
@@ -4277,12 +4277,6 @@ interface_syncing_step (GTask *task)
MMIfaceModem *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);
--
2.31.1

View file

@ -1,241 +0,0 @@
From a293dcb53274119799d079152b894ce4f660776c Mon Sep 17 00:00:00 2001
From: Dylan Van Assche <me@dylanvanassche.be>
Date: Sat, 20 Mar 2021 16:23:14 +0100
Subject: [PATCH 26/39] base-bearer: synchronize state when resuming
Refresh connection status on resume to confirm
that the connection bearers are still valid.
---
src/mm-base-bearer.c | 124 +++++++++++++++++++++++++++++++++++++++++++
src/mm-base-bearer.h | 24 +++++++++
src/mm-iface-modem.c | 25 +++++++++
3 files changed, 173 insertions(+)
diff --git a/src/mm-base-bearer.c b/src/mm-base-bearer.c
index 7510fe19..1ce6e49c 100644
--- a/src/mm-base-bearer.c
+++ b/src/mm-base-bearer.c
@@ -1399,6 +1399,130 @@ mm_base_bearer_report_connection_status (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 1c1f96ea..a2a00166 100644
--- a/src/mm-base-bearer.h
+++ b/src/mm-base-bearer.h
@@ -123,6 +123,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,
@@ -169,4 +181,16 @@ void mm_base_bearer_disconnect_force (MMBaseBearer *self);
void mm_base_bearer_report_connection_status (MMBaseBearer *self,
MMBearerConnectionStatus status);
+#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 b298eb89..1fe1feff 100644
--- a/src/mm-iface-modem.c
+++ b/src/mm-iface-modem.c
@@ -4220,6 +4220,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,
interface_syncing_step (task);
}
+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)
{
@@ -4317,6 +4334,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);
--
2.31.1

View file

@ -1,54 +0,0 @@
From c13c2134b4ef913f71f91128298080b5b1cf316b Mon Sep 17 00:00:00 2001
From: Aleksander Morgado <aleksander@aleksander.es>
Date: Sun, 23 May 2021 20:58:40 +0200
Subject: [PATCH 27/39] base-bearer: improve comments of the
load/reload_connection_status() methods
---
src/mm-base-bearer.h | 22 +++++++++++++++++++---
1 file changed, 19 insertions(+), 3 deletions(-)
diff --git a/src/mm-base-bearer.h b/src/mm-base-bearer.h
index a2a00166..c5a4bda5 100644
--- a/src/mm-base-bearer.h
+++ b/src/mm-base-bearer.h
@@ -113,9 +113,15 @@ struct _MMBaseBearerClass {
GError **error);
/* Monitor connection status:
- * NOTE: only CONNECTED or DISCONNECTED should be reported here; this method
+ *
+ * Only CONNECTED or DISCONNECTED should be reported here; this method
* is used to poll for connection status once the connection has been
- * established */
+ * established.
+ *
+ * This method will return MM_CORE_ERROR_UNSUPPORTED if the polling
+ * is not required (i.e. if we can safely rely on async indications
+ * sent by the modem).
+ */
void (* load_connection_status) (MMBaseBearer *bearer,
GAsyncReadyCallback callback,
gpointer user_data);
@@ -125,7 +131,17 @@ struct _MMBaseBearerClass {
#if defined WITH_SYSTEMD_SUSPEND_RESUME
- /* Reload connection status */
+ /* Reload connection status:
+ *
+ * This method should return the exact connection status of the bearer, and
+ * the check must always be performed (if supported). This method should not
+ * return MM_CORE_ERROR_UNSUPPORTED as a way to skip the operation, as in
+ * this case the connection monitoring is required during the quick
+ * suspend/resume synchronization.
+ *
+ * It is up to each protocol/plugin whether providing the same method here
+ * and in load_connection_status() makes sense.
+ */
void (* reload_connection_status) (MMBaseBearer *bearer,
GAsyncReadyCallback callback,
gpointer user_data);
--
2.31.1

View file

@ -1,42 +0,0 @@
From ea6ecd7cf973022f0417e083bfe18aeaf9a94f84 Mon Sep 17 00:00:00 2001
From: Aleksander Morgado <aleksander@aleksander.es>
Date: Sun, 23 May 2021 15:51:51 +0200
Subject: [PATCH 28/39] base-bearer: fix connection reload completion
If we called the class reload_connection_status() method, we should
call the class reload_connection_status_finish() as well.
---
src/mm-base-bearer.c | 10 +---------
1 file changed, 1 insertion(+), 9 deletions(-)
diff --git a/src/mm-base-bearer.c b/src/mm-base-bearer.c
index 1ce6e49c..71f6684b 100644
--- a/src/mm-base-bearer.c
+++ b/src/mm-base-bearer.c
@@ -1422,14 +1422,6 @@ mm_base_bearer_sync_finish (MMBaseBearer *self,
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,
@@ -1440,7 +1432,7 @@ reload_connection_status_ready (MMBaseBearer *self,
ctx = g_task_get_task_data (task);
- reload_connection_status_finish (self, res, &error);
+ MM_BASE_BEARER_GET_CLASS (self)->reload_connection_status_finish (self, res, &error);
if (error)
mm_obj_warn (self, "reloading connection status failed: %s", error->message);
--
2.31.1

View file

@ -1,105 +0,0 @@
From d04b388e4dbc9c341fbd7176d1eef2b0dcba49ba Mon Sep 17 00:00:00 2001
From: Aleksander Morgado <aleksander@aleksander.es>
Date: Sun, 23 May 2021 21:17:42 +0200
Subject: [PATCH 29/39] base-bearer: propagate the new connection status after
reload
Just triggering a connection status reload won't change the actual
bearer object state.
We change the signature of the reload_connection_status_finish()
method so that it returns the actual reloaded bearer connection
status, and so both the load_ and reload_ methods can be implemented
with exactly the same method, something that was not possible before.
Once we get the new connection status reloaded, we apply it in the
bearer object only if it's DISCONNECTED (and it wasn't DISCONNECTED
before). This should cover the true real case we're interested in, and
nothing else (i.e. we won't overcomplicate the logic attempting to
handle disconnected->connected transitions detected in the sync()
operation).
---
src/mm-base-bearer.c | 29 +++++++++++++++++++++++------
src/mm-base-bearer.h | 6 +++---
2 files changed, 26 insertions(+), 9 deletions(-)
diff --git a/src/mm-base-bearer.c b/src/mm-base-bearer.c
index 71f6684b..69600c17 100644
--- a/src/mm-base-bearer.c
+++ b/src/mm-base-bearer.c
@@ -1411,7 +1411,8 @@ typedef enum {
} SyncingStep;
struct _SyncingContext {
- SyncingStep step;
+ SyncingStep step;
+ MMBearerStatus status;
};
gboolean
@@ -1427,14 +1428,29 @@ reload_connection_status_ready (MMBaseBearer *self,
GAsyncResult *res,
GTask *task)
{
- SyncingContext *ctx;
- g_autoptr(GError) error = NULL;
+ SyncingContext *ctx;
+ MMBearerConnectionStatus reloaded_status;
+ g_autoptr(GError) error = NULL;
ctx = g_task_get_task_data (task);
- MM_BASE_BEARER_GET_CLASS (self)->reload_connection_status_finish (self, res, &error);
- if (error)
+ /* The only update we're really interested in is the connected->disconnected
+ * one, because any other would be extremely strange and it's probably not
+ * worth trying to support those; e.g. a disconnected->connected change here
+ * would be impossible to be handled correctly. We'll also ignore intermediate
+ * states (connecting/disconnecting), as we can rely on the reports of the final
+ * state at some point soon.
+ *
+ * So, just handle DISCONNECTED at this point.
+ */
+ reloaded_status = MM_BASE_BEARER_GET_CLASS (self)->reload_connection_status_finish (self, res, &error);
+ if (reloaded_status == MM_BEARER_CONNECTION_STATUS_UNKNOWN)
mm_obj_warn (self, "reloading connection status failed: %s", error->message);
+ else if ((ctx->status == MM_BEARER_STATUS_CONNECTED) &&
+ (reloaded_status == MM_BEARER_CONNECTION_STATUS_DISCONNECTED)) {
+ mm_obj_dbg (self, "disconnection detected during status synchronization");
+ mm_base_bearer_report_connection_status (self, reloaded_status);
+ }
/* Go on to the next step */
ctx->step++;
@@ -1501,9 +1517,10 @@ mm_base_bearer_sync (MMBaseBearer *self,
SyncingContext *ctx;
GTask *task;
- /* Create SyncingContext */
+ /* Create SyncingContext and store the original bearer status */
ctx = g_new0 (SyncingContext, 1);
ctx->step = SYNCING_STEP_FIRST;
+ ctx->status = self->priv->status;
/* Create sync steps task and execute it */
task = g_task_new (self, NULL, callback, user_data);
diff --git a/src/mm-base-bearer.h b/src/mm-base-bearer.h
index c5a4bda5..16e4bae5 100644
--- a/src/mm-base-bearer.h
+++ b/src/mm-base-bearer.h
@@ -145,9 +145,9 @@ struct _MMBaseBearerClass {
void (* reload_connection_status) (MMBaseBearer *bearer,
GAsyncReadyCallback callback,
gpointer user_data);
- gboolean (* reload_connection_status_finish) (MMBaseBearer *bearer,
- GAsyncResult *res,
- GError **error);
+ MMBearerConnectionStatus (* reload_connection_status_finish) (MMBaseBearer *bearer,
+ GAsyncResult *res,
+ GError **error);
#endif
--
2.31.1

View file

@ -1,207 +0,0 @@
From 50be73286059a9694f0cc8cc8b42d73cb6e9cb1f Mon Sep 17 00:00:00 2001
From: Aleksander Morgado <aleksander@aleksander.es>
Date: Sun, 23 May 2021 21:40:20 +0200
Subject: [PATCH 30/39] iface-modem,bearer-list: sync all bearers one after the
other
Do not launch N checks for N bearers and ignore their result. Instead,
go one by one, and report errors one by one.
---
src/mm-bearer-list.c | 86 ++++++++++++++++++++++++++++++++++++++++++++
src/mm-bearer-list.h | 11 ++++++
src/mm-iface-modem.c | 49 +++++++++++++++++++------
3 files changed, 136 insertions(+), 10 deletions(-)
diff --git a/src/mm-bearer-list.c b/src/mm-bearer-list.c
index 65717132..1ce53e05 100644
--- a/src/mm-bearer-list.c
+++ b/src/mm-bearer-list.c
@@ -268,6 +268,92 @@ mm_bearer_list_disconnect_all_bearers (MMBearerList *self,
/*****************************************************************************/
+#if defined WITH_SYSTEMD_SUSPEND_RESUME
+
+typedef struct {
+ GList *pending;
+ MMBaseBearer *current;
+} SyncAllContext;
+
+static void
+sync_all_context_free (SyncAllContext *ctx)
+{
+ if (ctx->current)
+ g_object_unref (ctx->current);
+ g_list_free_full (ctx->pending, g_object_unref);
+ g_free (ctx);
+}
+
+gboolean
+mm_bearer_list_sync_all_bearers_finish (MMBearerList *self,
+ GAsyncResult *res,
+ GError **error)
+{
+ return g_task_propagate_boolean (G_TASK (res), error);
+}
+
+static void sync_next_bearer (GTask *task);
+
+static void
+sync_ready (MMBaseBearer *bearer,
+ GAsyncResult *res,
+ GTask *task)
+{
+ g_autoptr(GError) error = NULL;
+
+ if (!mm_base_bearer_sync_finish (bearer, res, &error))
+ mm_obj_warn (bearer, "failed synchronizing state: %s", error->message);
+
+ sync_next_bearer (task);
+}
+
+static void
+sync_next_bearer (GTask *task)
+{
+ SyncAllContext *ctx;
+
+ ctx = g_task_get_task_data (task);
+ if (ctx->current)
+ g_clear_object (&ctx->current);
+
+ /* No more bearers? all done! */
+ if (!ctx->pending) {
+ g_task_return_boolean (task, TRUE);
+ g_object_unref (task);
+ return;
+ }
+
+ ctx->current = MM_BASE_BEARER (ctx->pending->data);
+ ctx->pending = g_list_delete_link (ctx->pending, ctx->pending);
+
+ mm_base_bearer_sync (ctx->current, (GAsyncReadyCallback)sync_ready, task);
+}
+
+void
+mm_bearer_list_sync_all_bearers (MMBearerList *self,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ SyncAllContext *ctx;
+ GTask *task;
+
+ ctx = g_new0 (SyncAllContext, 1);
+
+ /* Get a copy of the list */
+ ctx->pending = g_list_copy_deep (self->priv->bearers,
+ (GCopyFunc)g_object_ref,
+ NULL);
+
+ task = g_task_new (self, NULL, callback, user_data);
+ g_task_set_task_data (task, ctx, (GDestroyNotify)sync_all_context_free);
+
+ sync_next_bearer (task);
+}
+
+#endif
+
+/*****************************************************************************/
+
MMBearerList *
mm_bearer_list_new (guint max_bearers,
guint max_active_bearers)
diff --git a/src/mm-bearer-list.h b/src/mm-bearer-list.h
index 0d220eee..04af79e9 100644
--- a/src/mm-bearer-list.h
+++ b/src/mm-bearer-list.h
@@ -85,4 +85,15 @@ gboolean mm_bearer_list_disconnect_all_bearers_finish (MMBearerList *self,
GAsyncResult *res,
GError **error);
+#if defined WITH_SYSTEMD_SUSPEND_RESUME
+
+void mm_bearer_list_sync_all_bearers (MMBearerList *self,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+gboolean mm_bearer_list_sync_all_bearers_finish (MMBearerList *self,
+ GAsyncResult *res,
+ GError **error);
+
+#endif
+
#endif /* MM_BEARER_LIST_H */
diff --git a/src/mm-iface-modem.c b/src/mm-iface-modem.c
index 1fe1feff..c3722c0a 100644
--- a/src/mm-iface-modem.c
+++ b/src/mm-iface-modem.c
@@ -4273,19 +4273,49 @@ sync_detect_sim_swap_ready (MMIfaceModem *self,
}
static void
-reload_bearers (MMIfaceModem *self)
+sync_all_bearers_ready (MMBearerList *bearer_list,
+ GAsyncResult *res,
+ GTask *task)
{
- g_autoptr(MMBearerList) list = NULL;
+ MMIfaceModem *self;
+ SyncingContext *ctx;
+ g_autoptr (GError) error = NULL;
+
+ self = g_task_get_source_object (task);
+ ctx = g_task_get_task_data (task);
+
+ if (!mm_bearer_list_sync_all_bearers_finish (bearer_list, res, &error))
+ mm_obj_warn (self, "synchronizing all bearer status failed: %s", error->message);
+
+ /* Go on to next step */
+ ctx->step++;
+ interface_syncing_step (task);
+}
+
+static void
+reload_bearers (GTask *task)
+{
+ MMIfaceModem *self;
+ SyncingContext *ctx;
+ g_autoptr(MMBearerList) bearer_list = NULL;
+
+ self = g_task_get_source_object (task);
+ ctx = g_task_get_task_data (task);
g_object_get (self,
- MM_IFACE_MODEM_BEARER_LIST, &list,
+ MM_IFACE_MODEM_BEARER_LIST, &bearer_list,
NULL);
- if (list) {
- mm_bearer_list_foreach (list,
- (MMBearerListForeachFunc)mm_base_bearer_sync,
- NULL);
+ if (!bearer_list) {
+ /* Go on to next step */
+ ctx->step++;
+ interface_syncing_step (task);
+ return;
}
+
+ mm_bearer_list_sync_all_bearers (bearer_list,
+ (GAsyncReadyCallback)sync_all_bearers_ready,
+ task);
}
static void
@@ -4338,9 +4368,8 @@ interface_syncing_step (GTask *task)
/*
* Refresh bearers.
*/
- reload_bearers (self);
- ctx->step++;
- /* fall through */
+ reload_bearers (task);
+ return;
case SYNCING_STEP_LAST:
/* We are done without errors! */
--
2.31.1

View file

@ -1,31 +0,0 @@
From 7c93327a711c3c5e0834acabd059ebd0fc70e379 Mon Sep 17 00:00:00 2001
From: Aleksander Morgado <aleksander@aleksander.es>
Date: Sun, 23 May 2021 21:46:34 +0200
Subject: [PATCH 31/39] base-bearer: ignore cancellation during sync()
There is no input cancellable in the method, so the GTask will never
get cancelled from the outside.
---
src/mm-base-bearer.c | 6 ------
1 file changed, 6 deletions(-)
diff --git a/src/mm-base-bearer.c b/src/mm-base-bearer.c
index 69600c17..801c3ec1 100644
--- a/src/mm-base-bearer.c
+++ b/src/mm-base-bearer.c
@@ -1463,12 +1463,6 @@ 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);
--
2.31.1

View file

@ -1,32 +0,0 @@
From 0576f8d28405df80c689f478363a2a041f9d5df3 Mon Sep 17 00:00:00 2001
From: Aleksander Morgado <aleksander@aleksander.es>
Date: Sun, 23 May 2021 22:11:08 +0200
Subject: [PATCH 32/39] broadband-bearer: reuse the same method for load and
reload
The load_() method is used for connection monitoring; while the
reload_() method is used to sync connection status after a
suspend/resume operation. The same method can be used for both things
in the case of AT+CGACT? based modems.
---
src/mm-broadband-bearer.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/src/mm-broadband-bearer.c b/src/mm-broadband-bearer.c
index 73869a0c..ff49903a 100644
--- a/src/mm-broadband-bearer.c
+++ b/src/mm-broadband-bearer.c
@@ -2333,6 +2333,10 @@ mm_broadband_bearer_class_init (MMBroadbandBearerClass *klass)
base_bearer_class->report_connection_status = report_connection_status;
base_bearer_class->load_connection_status = load_connection_status;
base_bearer_class->load_connection_status_finish = load_connection_status_finish;
+#if defined WITH_SYSTEMD_SUSPEND_RESUME
+ base_bearer_class->reload_connection_status = load_connection_status;
+ base_bearer_class->reload_connection_status_finish = load_connection_status_finish;
+#endif
klass->connect_3gpp = connect_3gpp;
klass->connect_3gpp_finish = detailed_connect_finish;
--
2.31.1

View file

@ -1,31 +0,0 @@
From 5fdf3f0f26579cc9a453401de09ca6ea0292e27c Mon Sep 17 00:00:00 2001
From: Aleksander Morgado <aleksander@aleksander.es>
Date: Sun, 23 May 2021 22:14:49 +0200
Subject: [PATCH 33/39] novatel-lte: reuse the same method for load and reload
The load_() method is used for connection monitoring; while the
reload_() method is used to sync connection status after a
suspend/resume operation. The same method can be used for both things
in the Novatel LTE plugin.
---
plugins/novatel/mm-broadband-bearer-novatel-lte.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/plugins/novatel/mm-broadband-bearer-novatel-lte.c b/plugins/novatel/mm-broadband-bearer-novatel-lte.c
index ec08f4d7..4419eb23 100644
--- a/plugins/novatel/mm-broadband-bearer-novatel-lte.c
+++ b/plugins/novatel/mm-broadband-bearer-novatel-lte.c
@@ -568,6 +568,10 @@ mm_broadband_bearer_novatel_lte_class_init (MMBroadbandBearerNovatelLteClass *kl
base_bearer_class->load_connection_status = load_connection_status;
base_bearer_class->load_connection_status_finish = load_connection_status_finish;
+#if defined WITH_SYSTEMD_SUSPEND_RESUME
+ base_bearer_class->reload_connection_status = load_connection_status;
+ base_bearer_class->reload_connection_status_finish = load_connection_status_finish;
+#endif
broadband_bearer_class->connect_3gpp = connect_3gpp;
broadband_bearer_class->connect_3gpp_finish = connect_3gpp_finish;
--
2.31.1

View file

@ -1,31 +0,0 @@
From 14ea67c111b6116071f00c235b23152b21ab2d04 Mon Sep 17 00:00:00 2001
From: Aleksander Morgado <aleksander@aleksander.es>
Date: Sun, 23 May 2021 22:17:25 +0200
Subject: [PATCH 34/39] sierra: reuse the same method for load and reload
The load_() method is used for connection monitoring; while the
reload_() method is used to sync connection status after a
suspend/resume operation. The same method can be used for both things
in the Sierra plugin.
---
plugins/sierra/mm-broadband-bearer-sierra.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/plugins/sierra/mm-broadband-bearer-sierra.c b/plugins/sierra/mm-broadband-bearer-sierra.c
index 2c2ef375..bf95a8eb 100644
--- a/plugins/sierra/mm-broadband-bearer-sierra.c
+++ b/plugins/sierra/mm-broadband-bearer-sierra.c
@@ -663,6 +663,10 @@ mm_broadband_bearer_sierra_class_init (MMBroadbandBearerSierraClass *klass)
base_bearer_class->load_connection_status = load_connection_status;
base_bearer_class->load_connection_status_finish = load_connection_status_finish;
+#if defined WITH_SYSTEMD_SUSPEND_RESUME
+ base_bearer_class->reload_connection_status = load_connection_status;
+ base_bearer_class->reload_connection_status_finish = load_connection_status_finish;
+#endif
broadband_bearer_class->dial_3gpp = dial_3gpp;
broadband_bearer_class->dial_3gpp_finish = dial_3gpp_finish;
--
2.31.1

View file

@ -1,31 +0,0 @@
From e56cb4ebb98fe814a2f88d47d92e480a14be4a72 Mon Sep 17 00:00:00 2001
From: Aleksander Morgado <aleksander@aleksander.es>
Date: Sun, 23 May 2021 22:19:40 +0200
Subject: [PATCH 35/39] cinterion: reuse the same method for load and reload
The load_() method is used for connection monitoring; while the
reload_() method is used to sync connection status after a
suspend/resume operation. The same method can be used for both things
in the Cinterion plugin.
---
plugins/cinterion/mm-broadband-bearer-cinterion.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/plugins/cinterion/mm-broadband-bearer-cinterion.c b/plugins/cinterion/mm-broadband-bearer-cinterion.c
index 464e75e9..861c7ccb 100644
--- a/plugins/cinterion/mm-broadband-bearer-cinterion.c
+++ b/plugins/cinterion/mm-broadband-bearer-cinterion.c
@@ -681,6 +681,10 @@ mm_broadband_bearer_cinterion_class_init (MMBroadbandBearerCinterionClass *klass
base_bearer_class->load_connection_status = load_connection_status;
base_bearer_class->load_connection_status_finish = load_connection_status_finish;
+#if defined WITH_SYSTEMD_SUSPEND_RESUME
+ base_bearer_class->reload_connection_status = load_connection_status;
+ base_bearer_class->reload_connection_status_finish = load_connection_status_finish;
+#endif
broadband_bearer_class->dial_3gpp = dial_3gpp;
broadband_bearer_class->dial_3gpp_finish = dial_3gpp_finish;
--
2.31.1

View file

@ -1,109 +0,0 @@
From 938e087defb53ca55ccc356f8094ce91f3f7da1a Mon Sep 17 00:00:00 2001
From: Aleksander Morgado <aleksander@aleksander.es>
Date: Sun, 23 May 2021 22:21:54 +0200
Subject: [PATCH 36/39] plugins: ignore reload_connection_status() where not
supported
Some of the AT-based connection methods don't have any way to query
connection status, or we don't have a proper implementation for those
yet. Ignore the reload operation in all those.
---
plugins/altair/mm-broadband-bearer-altair-lte.c | 4 ++++
plugins/huawei/mm-broadband-bearer-huawei.c | 4 ++++
plugins/icera/mm-broadband-bearer-icera.c | 4 ++++
plugins/iridium/mm-bearer-iridium.c | 4 ++++
plugins/mbm/mm-broadband-bearer-mbm.c | 4 ++++
plugins/option/mm-broadband-bearer-hso.c | 4 ++++
6 files changed, 24 insertions(+)
diff --git a/plugins/altair/mm-broadband-bearer-altair-lte.c b/plugins/altair/mm-broadband-bearer-altair-lte.c
index 1ce965a8..52403418 100644
--- a/plugins/altair/mm-broadband-bearer-altair-lte.c
+++ b/plugins/altair/mm-broadband-bearer-altair-lte.c
@@ -358,6 +358,10 @@ mm_broadband_bearer_altair_lte_class_init (MMBroadbandBearerAltairLteClass *klas
base_bearer_class->load_connection_status = NULL;
base_bearer_class->load_connection_status_finish = NULL;
+#if defined WITH_SYSTEMD_SUSPEND_RESUME
+ base_bearer_class->reload_connection_status = NULL;
+ base_bearer_class->reload_connection_status_finish = NULL;
+#endif
broadband_bearer_class->connect_3gpp = connect_3gpp;
broadband_bearer_class->connect_3gpp_finish = connect_3gpp_finish;
diff --git a/plugins/huawei/mm-broadband-bearer-huawei.c b/plugins/huawei/mm-broadband-bearer-huawei.c
index 4bf2bb59..5a098d1b 100644
--- a/plugins/huawei/mm-broadband-bearer-huawei.c
+++ b/plugins/huawei/mm-broadband-bearer-huawei.c
@@ -874,6 +874,10 @@ mm_broadband_bearer_huawei_class_init (MMBroadbandBearerHuaweiClass *klass)
base_bearer_class->report_connection_status = report_connection_status;
base_bearer_class->load_connection_status = NULL;
base_bearer_class->load_connection_status_finish = NULL;
+#if defined WITH_SYSTEMD_SUSPEND_RESUME
+ base_bearer_class->reload_connection_status = NULL;
+ base_bearer_class->reload_connection_status_finish = NULL;
+#endif
broadband_bearer_class->connect_3gpp = connect_3gpp;
broadband_bearer_class->connect_3gpp_finish = connect_3gpp_finish;
diff --git a/plugins/icera/mm-broadband-bearer-icera.c b/plugins/icera/mm-broadband-bearer-icera.c
index 1d6859c0..dcd477fa 100644
--- a/plugins/icera/mm-broadband-bearer-icera.c
+++ b/plugins/icera/mm-broadband-bearer-icera.c
@@ -1000,6 +1000,10 @@ mm_broadband_bearer_icera_class_init (MMBroadbandBearerIceraClass *klass)
base_bearer_class->report_connection_status = report_connection_status;
base_bearer_class->load_connection_status = NULL;
base_bearer_class->load_connection_status_finish = NULL;
+#if defined WITH_SYSTEMD_SUSPEND_RESUME
+ base_bearer_class->reload_connection_status = NULL;
+ base_bearer_class->reload_connection_status_finish = NULL;
+#endif
broadband_bearer_class->dial_3gpp = dial_3gpp;
broadband_bearer_class->dial_3gpp_finish = dial_3gpp_finish;
diff --git a/plugins/iridium/mm-bearer-iridium.c b/plugins/iridium/mm-bearer-iridium.c
index 12b60419..511954f1 100644
--- a/plugins/iridium/mm-bearer-iridium.c
+++ b/plugins/iridium/mm-bearer-iridium.c
@@ -252,4 +252,8 @@ mm_bearer_iridium_class_init (MMBearerIridiumClass *klass)
base_bearer_class->connect_finish = connect_finish;
base_bearer_class->load_connection_status = NULL;
base_bearer_class->load_connection_status_finish = NULL;
+#if defined WITH_SYSTEMD_SUSPEND_RESUME
+ base_bearer_class->reload_connection_status = NULL;
+ base_bearer_class->reload_connection_status_finish = NULL;
+#endif
}
diff --git a/plugins/mbm/mm-broadband-bearer-mbm.c b/plugins/mbm/mm-broadband-bearer-mbm.c
index 8de7a09f..0ba42aea 100644
--- a/plugins/mbm/mm-broadband-bearer-mbm.c
+++ b/plugins/mbm/mm-broadband-bearer-mbm.c
@@ -895,6 +895,10 @@ mm_broadband_bearer_mbm_class_init (MMBroadbandBearerMbmClass *klass)
base_bearer_class->report_connection_status = report_connection_status;
base_bearer_class->load_connection_status = NULL;
base_bearer_class->load_connection_status_finish = NULL;
+#if defined WITH_SYSTEMD_SUSPEND_RESUME
+ base_bearer_class->reload_connection_status = NULL;
+ base_bearer_class->reload_connection_status_finish = NULL;
+#endif
broadband_bearer_class->dial_3gpp = dial_3gpp;
broadband_bearer_class->dial_3gpp_finish = dial_3gpp_finish;
diff --git a/plugins/option/mm-broadband-bearer-hso.c b/plugins/option/mm-broadband-bearer-hso.c
index 908d32c6..3aa8de88 100644
--- a/plugins/option/mm-broadband-bearer-hso.c
+++ b/plugins/option/mm-broadband-bearer-hso.c
@@ -786,6 +786,10 @@ mm_broadband_bearer_hso_class_init (MMBroadbandBearerHsoClass *klass)
base_bearer_class->report_connection_status = report_connection_status;
base_bearer_class->load_connection_status = NULL;
base_bearer_class->load_connection_status_finish = NULL;
+#if defined WITH_SYSTEMD_SUSPEND_RESUME
+ base_bearer_class->reload_connection_status = NULL;
+ base_bearer_class->reload_connection_status_finish = NULL;
+#endif
broadband_bearer_class->dial_3gpp = dial_3gpp;
broadband_bearer_class->dial_3gpp_finish = dial_3gpp_finish;
--
2.31.1

View file

@ -1,153 +0,0 @@
From 1cf4e63d828669747424e740519a6e2da246be38 Mon Sep 17 00:00:00 2001
From: Aleksander Morgado <aleksander@aleksander.es>
Date: Sun, 23 May 2021 23:39:18 +0200
Subject: [PATCH 37/39] bearer-qmi: implement reload_connection_status() for
the sync operation
The original load_connection_status() method would return an
UNSUPPORTED error if connection monitoring wasn't required (which is
the default in most QMI modems).
The new reload_connection_status() method requires the check to always
be done unconditionally.
We take most of the original logic in the load_connection_status() for
the new reload_connection_status(), and we add the UNSUPPORTED error
logic exclusively in the new load_connection_status().
---
src/mm-bearer-qmi.c | 86 +++++++++++++++++++++++++++++++++++++--------
1 file changed, 71 insertions(+), 15 deletions(-)
diff --git a/src/mm-bearer-qmi.c b/src/mm-bearer-qmi.c
index 670fb804..967594bf 100644
--- a/src/mm-bearer-qmi.c
+++ b/src/mm-bearer-qmi.c
@@ -226,7 +226,7 @@ reload_stats (MMBaseBearer *self,
}
/*****************************************************************************/
-/* Connection status polling */
+/* Connection status check */
typedef enum {
CONNECTION_STATUS_CONTEXT_STEP_FIRST,
@@ -240,9 +240,9 @@ typedef struct {
} ConnectionStatusContext;
static MMBearerConnectionStatus
-load_connection_status_finish (MMBaseBearer *self,
- GAsyncResult *res,
- GError **error)
+reload_connection_status_finish (MMBaseBearer *self,
+ GAsyncResult *res,
+ GError **error)
{
gint val;
@@ -312,16 +312,6 @@ connection_status_context_step (GTask *task)
switch (ctx->step) {
case CONNECTION_STATUS_CONTEXT_STEP_FIRST:
- /* Connection status polling is an optional feature that must be
- * enabled explicitly via udev tags. If not set, out as unsupported */
- if (self->priv->data &&
- !mm_kernel_device_get_global_property_as_boolean (mm_port_peek_kernel_device (self->priv->data),
- "ID_MM_QMI_CONNECTION_STATUS_POLLING_ENABLE")) {
- g_task_return_new_error (task, MM_CORE_ERROR, MM_CORE_ERROR_UNSUPPORTED,
- "Connection status polling not required");
- g_object_unref (task);
- return;
- }
/* If no clients ready on start, assume disconnected */
if (!self->priv->client_ipv4 && !self->priv->client_ipv6) {
g_task_return_int (task, MM_BEARER_CONNECTION_STATUS_DISCONNECTED);
@@ -369,7 +359,7 @@ connection_status_context_step (GTask *task)
}
static void
-load_connection_status (MMBaseBearer *self,
+reload_connection_status (MMBaseBearer *self,
GAsyncReadyCallback callback,
gpointer user_data)
{
@@ -385,6 +375,68 @@ load_connection_status (MMBaseBearer *self,
connection_status_context_step (task);
}
+/*****************************************************************************/
+/* Connection status polling */
+
+static MMBearerConnectionStatus
+load_connection_status_finish (MMBaseBearer *self,
+ GAsyncResult *res,
+ GError **error)
+{
+ gint val;
+
+ val = g_task_propagate_int (G_TASK (res), error);
+ if (val < 0)
+ return MM_BEARER_CONNECTION_STATUS_UNKNOWN;
+
+ return (MMBearerConnectionStatus) val;
+}
+
+static void
+reload_connection_status_ready (MMBaseBearer *self,
+ GAsyncResult *res,
+ GTask *task)
+{
+ MMBearerConnectionStatus status;
+ GError *error = NULL;
+
+ status = reload_connection_status_finish (self, res, &error);
+ if (status == MM_BEARER_CONNECTION_STATUS_UNKNOWN)
+ g_task_return_error (task, error);
+ else
+ g_task_return_int (task, MM_BEARER_CONNECTION_STATUS_CONNECTED);
+ g_object_unref (task);
+}
+
+static void
+load_connection_status (MMBaseBearer *_self,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ MMBearerQmi *self = MM_BEARER_QMI (_self);
+ GTask *task;
+
+ task = g_task_new (self, NULL, callback, user_data);
+
+ /* Connection status polling is an optional feature that must be
+ * enabled explicitly via udev tags. If not set, out as unsupported.
+ * Note that when connected via a muxed link, the udev tag should be
+ * checked on the master interface (lower device) */
+ if ((self->priv->data &&
+ !mm_kernel_device_get_global_property_as_boolean (mm_port_peek_kernel_device (self->priv->data),
+ "ID_MM_QMI_CONNECTION_STATUS_POLLING_ENABLE")) ||
+ (self->priv->link &&
+ !mm_kernel_device_get_global_property_as_boolean (mm_kernel_device_peek_lower_device (mm_port_peek_kernel_device (self->priv->link)),
+ "ID_MM_QMI_CONNECTION_STATUS_POLLING_ENABLE"))) {
+ g_task_return_new_error (task, MM_CORE_ERROR, MM_CORE_ERROR_UNSUPPORTED,
+ "Connection status polling not required");
+ g_object_unref (task);
+ return;
+ }
+
+ reload_connection_status (_self, (GAsyncReadyCallback)reload_connection_status_ready, task);
+}
+
/*****************************************************************************/
/* Connect */
@@ -2235,4 +2287,8 @@ mm_bearer_qmi_class_init (MMBearerQmiClass *klass)
base_bearer_class->reload_stats_finish = reload_stats_finish;
base_bearer_class->load_connection_status = load_connection_status;
base_bearer_class->load_connection_status_finish = load_connection_status_finish;
+#if defined WITH_SYSTEMD_SUSPEND_RESUME
+ base_bearer_class->reload_connection_status = reload_connection_status;
+ base_bearer_class->reload_connection_status_finish = reload_connection_status_finish;
+#endif
}
--
2.31.1

View file

@ -1,148 +0,0 @@
From 0a1d5d800810bce1fc14c09be5f42eb5b90e7edb Mon Sep 17 00:00:00 2001
From: Aleksander Morgado <aleksander@aleksander.es>
Date: Mon, 24 May 2021 00:08:07 +0200
Subject: [PATCH 38/39] bearer-mbim: implement reload_connection_status()
Implement connection status reloading for MBIM based bearers.
Based on a patch by Dylan Van Assche <me@dylanvanassche.be>
---
src/mm-bearer-mbim.c | 115 +++++++++++++++++++++++++++++++++++++++++++
1 file changed, 115 insertions(+)
diff --git a/src/mm-bearer-mbim.c b/src/mm-bearer-mbim.c
index 55064b30..f0479ebb 100644
--- a/src/mm-bearer-mbim.c
+++ b/src/mm-bearer-mbim.c
@@ -1424,6 +1424,117 @@ report_connection_status (MMBaseBearer *self,
/*****************************************************************************/
+#if defined WITH_SYSTEMD_SUSPEND_RESUME
+
+static MMBearerConnectionStatus
+reload_connection_status_finish (MMBaseBearer *self,
+ GAsyncResult *res,
+ GError **error)
+{
+ gint val;
+
+ val = g_task_propagate_int (G_TASK (res), error);
+ if (val < 0)
+ return MM_BEARER_CONNECTION_STATUS_UNKNOWN;
+
+ return (MMBearerConnectionStatus) val;
+}
+
+static void
+reload_connection_status_ready (MbimDevice *device,
+ GAsyncResult *res,
+ GTask *task)
+{
+ MMBearerMbim *self;
+ guint32 session_id;
+ MbimActivationState activation_state;
+ MMBearerConnectionStatus bearer_connection_status = MM_BEARER_CONNECTION_STATUS_UNKNOWN;
+ g_autoptr(MbimMessage) response = NULL;
+ g_autoptr(GError) error = NULL;
+
+ self = g_task_get_source_object (task);
+
+ response = mbim_device_command_finish (device, res, &error);
+ if (!response ||
+ !mbim_message_response_get_result (response, MBIM_MESSAGE_TYPE_COMMAND_DONE, &error) ||
+ !mbim_message_connect_response_parse (
+ response,
+ &session_id,
+ &activation_state,
+ NULL, /* voice_call_state */
+ NULL, /* ip_type */
+ NULL, /* context_type */
+ NULL, /* nw_error */
+ &error)) {
+ g_prefix_error (&error, "Cannot load session ID '%u' status: ",
+ mm_bearer_mbim_get_session_id (MM_BEARER_MBIM (self)));
+ g_task_return_error (task, error);
+ g_object_unref (task);
+ return;
+ }
+
+ mm_obj_dbg (self, "session ID '%u': %s", session_id, mbim_activation_state_get_string (activation_state));
+
+ switch (activation_state) {
+ case MBIM_ACTIVATION_STATE_ACTIVATED:
+ case MBIM_ACTIVATION_STATE_ACTIVATING:
+ /* for the purposes of the sync operation, it's fine to map ACTIVATING
+ * to CONNECTED, as we're really going to ignore that state in the actual
+ * processing of the logic. */
+ bearer_connection_status = MM_BEARER_CONNECTION_STATUS_CONNECTED;
+ break;
+ case MBIM_ACTIVATION_STATE_DEACTIVATING:
+ bearer_connection_status = MM_BEARER_CONNECTION_STATUS_DISCONNECTING;
+ break;
+ case MBIM_ACTIVATION_STATE_DEACTIVATED:
+ bearer_connection_status = MM_BEARER_CONNECTION_STATUS_DISCONNECTED;
+ break;
+ case MBIM_ACTIVATION_STATE_UNKNOWN:
+ default:
+ break;
+ }
+
+ if (bearer_connection_status == MM_BEARER_CONNECTION_STATUS_UNKNOWN)
+ g_task_return_new_error (task, MM_CORE_ERROR, MM_CORE_ERROR_FAILED,
+ "Cannot load session ID '%u' status",
+ mm_bearer_mbim_get_session_id (MM_BEARER_MBIM (self)));
+ else
+ g_task_return_int (task, bearer_connection_status);
+ g_object_unref (task);
+}
+
+static void
+reload_connection_status (MMBaseBearer *self,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ MMPortMbim *mbim;
+ GTask *task = NULL;
+ g_autoptr(MbimMessage) message = NULL;
+
+ if (!peek_ports (self, &mbim, NULL, callback, user_data))
+ return;
+
+ task = g_task_new (self, NULL, callback, user_data);
+ message = mbim_message_connect_query_new (mm_bearer_mbim_get_session_id (MM_BEARER_MBIM (self)),
+ MBIM_ACTIVATION_STATE_UNKNOWN,
+ MBIM_VOICE_CALL_STATE_NONE,
+ MBIM_CONTEXT_IP_TYPE_DEFAULT,
+ mbim_uuid_from_context_type (MBIM_CONTEXT_TYPE_INTERNET),
+ 0,
+ NULL);
+ mbim_device_command (mm_port_mbim_peek_device (mbim),
+ message,
+ 10,
+ NULL,
+ (GAsyncReadyCallback)reload_connection_status_ready,
+ task);
+}
+
+#endif /* WITH_SYSTEMD_SUSPEND_RESUME */
+
+/*****************************************************************************/
+
MMBaseBearer *
mm_bearer_mbim_new (MMBroadbandModemMbim *modem,
MMBearerProperties *config,
@@ -1524,6 +1635,10 @@ mm_bearer_mbim_class_init (MMBearerMbimClass *klass)
base_bearer_class->reload_stats_finish = reload_stats_finish;
base_bearer_class->load_connection_status = NULL;
base_bearer_class->load_connection_status_finish = NULL;
+#if defined WITH_SYSTEMD_SUSPEND_RESUME
+ base_bearer_class->reload_connection_status = reload_connection_status;
+ base_bearer_class->reload_connection_status_finish = reload_connection_status_finish;
+#endif
properties[PROP_SESSION_ID] =
g_param_spec_uint (MM_BEARER_MBIM_SESSION_ID,
--
2.31.1

View file

@ -1,207 +0,0 @@
From f36e79292763a06b2548619858a54562149c9857 Mon Sep 17 00:00:00 2001
From: Dylan Van Assche <me@dylanvanassche.be>
Date: Thu, 27 May 2021 21:25:16 +0200
Subject: [PATCH 39/39] ModemManager: backport Quick Suspend/Resume patches to
MM 1.16.X
---
src/kerneldevice/mm-kernel-device.c | 18 ++++++++++++++++++
src/kerneldevice/mm-kernel-device.h | 4 ++++
src/mm-base-modem.c | 4 ++++
src/mm-base-modem.h | 23 +++++++++++++++++++++++
src/mm-bearer-mbim.c | 1 +
src/mm-bearer-mbim.h | 1 +
src/mm-bearer-qmi.c | 1 +
src/mm-bearer-qmi.h | 1 +
src/mm-iface-modem.h | 3 ---
9 files changed, 53 insertions(+), 3 deletions(-)
diff --git a/src/kerneldevice/mm-kernel-device.c b/src/kerneldevice/mm-kernel-device.c
index 464a3800..08d9d4a1 100644
--- a/src/kerneldevice/mm-kernel-device.c
+++ b/src/kerneldevice/mm-kernel-device.c
@@ -26,6 +26,16 @@ static void log_object_iface_init (MMLogObjectInterface *iface);
G_DEFINE_ABSTRACT_TYPE_WITH_CODE (MMKernelDevice, mm_kernel_device, G_TYPE_OBJECT,
G_IMPLEMENT_INTERFACE (MM_TYPE_LOG_OBJECT, log_object_iface_init))
+enum {
+ PROP_0,
+ PROP_LOWER_DEVICE,
+ PROP_LAST
+};
+
+struct _MMKernelDevicePrivate {
+ MMKernelDevice *lower_device;
+};
+
/*****************************************************************************/
@@ -125,6 +135,12 @@ mm_kernel_device_get_physdev_product (MMKernelDevice *self)
NULL);
}
+MMKernelDevice *
+mm_kernel_device_peek_lower_device (MMKernelDevice *self)
+{
+ return self->priv->lower_device;
+}
+
gint
mm_kernel_device_get_interface_class (MMKernelDevice *self)
{
@@ -347,6 +363,8 @@ log_object_build_id (MMLogObject *_self)
static void
mm_kernel_device_init (MMKernelDevice *self)
{
+ /* Initialize private data */
+ self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, MM_TYPE_KERNEL_DEVICE, MMKernelDevicePrivate);
}
static void
diff --git a/src/kerneldevice/mm-kernel-device.h b/src/kerneldevice/mm-kernel-device.h
index 45b270d5..678b3410 100644
--- a/src/kerneldevice/mm-kernel-device.h
+++ b/src/kerneldevice/mm-kernel-device.h
@@ -28,9 +28,11 @@
typedef struct _MMKernelDevice MMKernelDevice;
typedef struct _MMKernelDeviceClass MMKernelDeviceClass;
+typedef struct _MMKernelDevicePrivate MMKernelDevicePrivate;
struct _MMKernelDevice {
GObject parent;
+ MMKernelDevicePrivate *priv;
};
struct _MMKernelDeviceClass {
@@ -89,6 +91,8 @@ const gchar *mm_kernel_device_get_physdev_subsystem (MMKernelDevice *self);
const gchar *mm_kernel_device_get_physdev_manufacturer (MMKernelDevice *self);
const gchar *mm_kernel_device_get_physdev_product (MMKernelDevice *self);
+MMKernelDevice *mm_kernel_device_peek_lower_device (MMKernelDevice *self);
+
gboolean mm_kernel_device_cmp (MMKernelDevice *a, MMKernelDevice *b);
/* Standard properties are usually associated to single ports */
diff --git a/src/mm-base-modem.c b/src/mm-base-modem.c
index 580103ba..e54add87 100644
--- a/src/mm-base-modem.c
+++ b/src/mm-base-modem.c
@@ -115,6 +115,10 @@ struct _MMBaseModemPrivate {
/* MBIM ports */
GList *mbim;
#endif
+
+ /* Additional port links grabbed after having
+ * organized ports */
+ GHashTable *link_ports;
};
guint
diff --git a/src/mm-base-modem.h b/src/mm-base-modem.h
index d9538251..c52f0e18 100644
--- a/src/mm-base-modem.h
+++ b/src/mm-base-modem.h
@@ -63,6 +63,11 @@ typedef struct _MMBaseModemPrivate MMBaseModemPrivate;
#define MM_BASE_MODEM_VENDOR_ID "base-modem-vendor-id"
#define MM_BASE_MODEM_PRODUCT_ID "base-modem-product-id"
#define MM_BASE_MODEM_REPROBE "base-modem-reprobe"
+#define MM_BASE_MODEM_DATA_NET_SUPPORTED "base-modem-data-net-supported"
+#define MM_BASE_MODEM_DATA_TTY_SUPPORTED "base-modem-data-tty-supported"
+
+#define MM_BASE_MODEM_SIGNAL_LINK_PORT_GRABBED "base-modem-link-port-grabbed"
+#define MM_BASE_MODEM_SIGNAL_LINK_PORT_RELEASED "base-modem-link-port-released"
struct _MMBaseModem {
MmGdbusObjectSkeleton parent;
@@ -132,6 +137,24 @@ gboolean mm_base_modem_grab_port (MMBaseModem *self,
MMPortSerialAtFlag at_pflags,
GError **error);
+gboolean mm_base_modem_grab_link_port (MMBaseModem *self,
+ MMKernelDevice *kernel_device,
+ GError **error);
+gboolean mm_base_modem_release_link_port (MMBaseModem *self,
+ const gchar *subsystem,
+ const gchar *name,
+ GError **error);
+
+void mm_base_modem_wait_link_port (MMBaseModem *self,
+ const gchar *subsystem,
+ const gchar *name,
+ guint timeout_ms,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+MMPort *mm_base_modem_wait_link_port_finish (MMBaseModem *self,
+ GAsyncResult *res,
+ GError **error);
+
gboolean mm_base_modem_has_at_port (MMBaseModem *self);
gboolean mm_base_modem_organize_ports (MMBaseModem *self,
diff --git a/src/mm-bearer-mbim.c b/src/mm-bearer-mbim.c
index f0479ebb..99270474 100644
--- a/src/mm-bearer-mbim.c
+++ b/src/mm-bearer-mbim.c
@@ -47,6 +47,7 @@ struct _MMBearerMbimPrivate {
guint32 session_id;
MMPort *data;
+ MMPort *link;
};
/*****************************************************************************/
diff --git a/src/mm-bearer-mbim.h b/src/mm-bearer-mbim.h
index 0d97d8d9..48c1c846 100644
--- a/src/mm-bearer-mbim.h
+++ b/src/mm-bearer-mbim.h
@@ -24,6 +24,7 @@
#include "mm-base-bearer.h"
#include "mm-broadband-modem-mbim.h"
+#include "mm-kernel-device.h"
#define MM_TYPE_BEARER_MBIM (mm_bearer_mbim_get_type ())
#define MM_BEARER_MBIM(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), MM_TYPE_BEARER_MBIM, MMBearerMbim))
diff --git a/src/mm-bearer-qmi.c b/src/mm-bearer-qmi.c
index 967594bf..52e155d7 100644
--- a/src/mm-bearer-qmi.c
+++ b/src/mm-bearer-qmi.c
@@ -56,6 +56,7 @@ struct _MMBearerQmiPrivate {
guint event_report_ipv6_indication_id;
MMPort *data;
+ MMPort *link;
guint32 packet_data_handle_ipv4;
guint32 packet_data_handle_ipv6;
};
diff --git a/src/mm-bearer-qmi.h b/src/mm-bearer-qmi.h
index d75773f5..2a3c881c 100644
--- a/src/mm-bearer-qmi.h
+++ b/src/mm-bearer-qmi.h
@@ -26,6 +26,7 @@
#include "mm-base-bearer.h"
#include "mm-broadband-modem-qmi.h"
+#include "mm-kernel-device.h"
#define MM_TYPE_BEARER_QMI (mm_bearer_qmi_get_type ())
#define MM_BEARER_QMI(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), MM_TYPE_BEARER_QMI, MMBearerQmi))
diff --git a/src/mm-iface-modem.h b/src/mm-iface-modem.h
index 5ba2167c..110a839b 100644
--- a/src/mm-iface-modem.h
+++ b/src/mm-iface-modem.h
@@ -460,9 +460,6 @@ gboolean mm_iface_modem_disable_finish (MMIfaceModem *self,
GAsyncResult *res,
GError **error);
-/* Shutdown Modem interface */
-void mm_iface_modem_shutdown (MMIfaceModem *self);
-
/* Helper to return an error when the modem is in failed state and so it
* cannot process a given method invocation
*/
--
2.31.1

View file

@ -1,17 +1,16 @@
# Forked from Alpine to apply quick suspend/resume patches for the PinePhone EG25-G modem
# Forked from Alpine to package latest 1.18rc1 release candidate
pkgname=modemmanager
pkgver=9999_git20210528
_pkgver=1.16.6
pkgver=9999_git20210819
_pkgver=1.17.900
pkgrel=0
pkgdesc="ModemManager library"
url="http://www.freedesktop.org/wiki/Software/ModemManager"
arch="all !mips !mips64 !s390x" # polkit
arch="all !mips !mips64 !s390x !riscv64" # limited by polkit
license="GPL-2.0-or-later AND LGPL-2.1-or-later"
depends="dbus polkit"
depends_dev="libmm-glib"
makedepends="$depends_dev gobject-introspection-dev gtk-doc vala
libgudev-dev polkit-dev libmbim-dev libqmi-dev linux-headers libqrtr-glib-dev gettext-dev glib-dev"
makedepends="$makedepends automake autoconf autoconf-archive libtool"
libgudev-dev polkit-dev libmbim-dev libqmi-dev linux-headers"
checkdepends="glib-dev"
options="!check" # https://bugs.freedesktop.org/show_bug.cgi?id=101197
subpackages="
@ -22,50 +21,10 @@ subpackages="
$pkgname-openrc
$pkgname-bash-completion
"
# https://gitlab.freedesktop.org/mobile-broadband/ModemManager/-/merge_requests/511/commits
# patches are integrated in these patches already
source="https://www.freedesktop.org/software/ModemManager/ModemManager-$_pkgver.tar.xz
0001-base-manager-add-quick-suspend-resume-base.patch
0002-base-manager-make-sure-g_autoptr-variables-are-initi.patch
0003-base-manager-don-t-assume-a-MMDevice-always-holds-a-.patch
0004-base-manager-avoid-using-the-mm_-prefix-for-static-p.patch
0005-base-modem-fix-modem_sync-operation-handling.patch
0006-base-modem-don-t-fail-if-sync-isn-t-implemented.patch
0007-base-modem-make-sync-available-only-if-suspend-resum.patch
0008-broadband-modem-ignore-cancellation-during-sync.patch
0009-broadband-modem-skip-synchronization-after-resume-if.patch
0010-iface-modem-time-synchronize-state-when-resuming.patch
0011-broadband-modem-skip-time-interface-sync-if-no-time-.patch
0012-iface-modem-time-ignore-cancellation-during-sync.patch
0013-iface-modem-3gpp-synchronize-state-when-resuming.patch
0014-iface-modem-3gpp-use-g_autoptr-for-the-MMBearerPrope.patch
0015-iface-modem-3gpp-fix-double-GError-free-on-registrat.patch
0016-iface-modem-3gpp-remove-redundant-log-message.patch
0017-iface-modem-3gpp-ignore-cancellation-during-sync.patch
0018-broadband-modem-fix-type-in-the-ready-for-iface_mode.patch
0019-broadband-modem-skip-3GPP-interface-sync-if-no-3GPP-.patch
0020-iface-modem-synchronize-state-when-resuming.patch
0021-broadband-modem-fail-synchronization-if-no-modem-exp.patch
0022-broadband-modem-fix-state-machine-logic-when-synchro.patch
0023-broadband-modem-abort-sync-if-locked-SIM-card-found.patch
0024-iface-modem-remove-the-signal-quality-enforced-refre.patch
0025-iface-modem-ignore-cancellation-during-sync.patch
0026-base-bearer-synchronize-state-when-resuming.patch
0027-base-bearer-improve-comments-of-the-load-reload_conn.patch
0028-base-bearer-fix-connection-reload-completion.patch
0029-base-bearer-propagate-the-new-connection-status-afte.patch
0030-iface-modem-bearer-list-sync-all-bearers-one-after-t.patch
0031-base-bearer-ignore-cancellation-during-sync.patch
0032-broadband-bearer-reuse-the-same-method-for-load-and-.patch
0033-novatel-lte-reuse-the-same-method-for-load-and-reloa.patch
0034-sierra-reuse-the-same-method-for-load-and-reload.patch
0035-cinterion-reuse-the-same-method-for-load-and-reload.patch
0036-plugins-ignore-reload_connection_status-where-not-su.patch
0037-bearer-qmi-implement-reload_connection_status-for-th.patch
0038-bearer-mbim-implement-reload_connection_status.patch
0039-ModemManager-backport-Quick-Suspend-Resume-patches-t.patch
$pkgname.rules
$pkgname.initd"
$pkgname.initd
"
builddir="$srcdir"/ModemManager-$_pkgver
build() {
@ -121,46 +80,7 @@ check() {
}
sha512sums="
78a928007732baaa0eaed9d587913774d4fb79049d652474f39176190496012dc4c93fd0bd774ed6f86f845f3b9f345bcccf4c7b2438b83cf5846b2bcdcb39d5 ModemManager-1.16.6.tar.xz
c76ecd7f8fa679fcd011e7988f40cf1a6931a1c743a0440fc714f70967902f064a7738a15d3b90abf060e4617937beebaff1f454b44cf700c2c45362a489cc6d 0001-base-manager-add-quick-suspend-resume-base.patch
9a83651fd2a3c83fa79d5fc32794feb367f635a0dae0040b21f3999f1c3069b4bcea9e5003cffa0a95bd721201caea0fd678b62028ee22916618fda87a0804d3 0002-base-manager-make-sure-g_autoptr-variables-are-initi.patch
296d0484886644da22c29f8781a05eab52100c7c85b0d365e4e18d334127f1bf807b0fad10933a07f62dd7e0be0c15e592d85d95f6c36fd20ae74cb36fc4d57f 0003-base-manager-don-t-assume-a-MMDevice-always-holds-a-.patch
245e416a4cbd15c5505acf267e91d10fdb26629be5062bcc813b60da286c29bd5fa16e647e70f5afb8b2b6e7fbee8adb7e73d3cb363b848c9327d5650630134f 0004-base-manager-avoid-using-the-mm_-prefix-for-static-p.patch
c45fe7bdf34a444c05677d2cefe9ad80f61fe2b8f93262942b7032e014c40f8a12f1a6167f14fda8c4b45bb0ef7be2fd427e24c4d4eb73ffc017c506b85b362d 0005-base-modem-fix-modem_sync-operation-handling.patch
769398e5e575bf7dd62bbb53ddeda500614ea52412002b762dd6aae029ce95596b490c718624ac76bf4ce2fa888278f436125a27fc33de2ee6843dc2de05d7e4 0006-base-modem-don-t-fail-if-sync-isn-t-implemented.patch
cbaa137435b502594814f8b204372c23768d46a0492e04f0fc175a969764858b57f396cae20984a07c55f0b46c2dc63df4b8dee0c7c7185071d2dc5949c54fca 0007-base-modem-make-sync-available-only-if-suspend-resum.patch
8f9ac51997f404e6fca5ecc98b4bb9c62247c352344e3a83cf5955b992464fefe3b53dbae3ae3f0b6b3d7635ea1af2ad265b534bd3eb45bdd08a7a40f77d5822 0008-broadband-modem-ignore-cancellation-during-sync.patch
ee26e717e78d0665175397fe46ab06bf699b7ed9f61f43a24df63faa5c04aed91ac53e08044060eae416a5a91082f2e63a21c5682d56f18fdbe28072f39dad8e 0009-broadband-modem-skip-synchronization-after-resume-if.patch
022449ca8fc6277e7e15acb2f70703930e5f54cbd54794641b7329681137329909e1e46a2555a5ff6c7c06bfc5b57637a9fc7dd701019b6c7f0efdc210bb247b 0010-iface-modem-time-synchronize-state-when-resuming.patch
384f3cc68bb8fc99d66b2836aa223218aaa35b126aa58b31be4069d68854dda763964aed504808488e568275c9fce2d58a7ef430c29217a8f70bf90040f21bbe 0011-broadband-modem-skip-time-interface-sync-if-no-time-.patch
49ed4784ce74d4cc4118fba008820ac6b65ed283e44f2ae20f8f8b4b7d58cb3909ce38190b74712b948dbd0ef48e08a118c0de1630125e410aa26505ec8807a3 0012-iface-modem-time-ignore-cancellation-during-sync.patch
d0305030e0ce54d7b4990ab3eb54785881c03875d84e643640f1d3ef2e63fe11114a21dfeaa8808e4b879727263289c76bbdc50dd7ed859d7b9f65bdc8af781c 0013-iface-modem-3gpp-synchronize-state-when-resuming.patch
23564779a45f9be1f96568dd3f25e13d55480a45c6c66b4b8c733946937c985cf47c74db5ba3ee0752ed27f3bd1ecf1ca6f74c131954cd14565c74f27cfcc594 0014-iface-modem-3gpp-use-g_autoptr-for-the-MMBearerPrope.patch
3dc4b1625f16022d4532d19bc73ab1743bb09f05209e400618871d338f48c940567047cc602d3b83083aeeb13734cebce466f72181e5dc5124dead4944147680 0015-iface-modem-3gpp-fix-double-GError-free-on-registrat.patch
a9dae9d6fbc851ca022cba2226fc5225cd329c5d0cb537070d9fab7907317e47034fdde69bbeab880deb8fa80ca1fa10cf162599d6c4f33744f0a0953dc64e1c 0016-iface-modem-3gpp-remove-redundant-log-message.patch
58b4e987aef3ffd28845cb87e3d6055e5d2fe7c6796798c1c78cccb2073f3746c8d1949adaf0a098673b609f79a25d05153565cadfafd830e300131b498db2d8 0017-iface-modem-3gpp-ignore-cancellation-during-sync.patch
55d056132fa27a3765cb8bc3d516e1178b0f2d47e693f17e061d927d76c38e3e8830ccef2ee4a8ded810ac50d347bd4d7945be67630c564810b856ef8058c081 0018-broadband-modem-fix-type-in-the-ready-for-iface_mode.patch
b88cdcbe2474d875f45832ac9f24ba0dc1c492263792bfab2ee7a84dd23365a3811c185d47e3ca43710d7c3c976f950cae47455e97666ca809816b1705199255 0019-broadband-modem-skip-3GPP-interface-sync-if-no-3GPP-.patch
dd99f4788abe63e08ad20f3c1d0f55d88a059a974f491f3de26deb6bc2bbf117a72e169669693b27ada385d8012a6b66daae98ca135e12f30eff04b14a46f635 0020-iface-modem-synchronize-state-when-resuming.patch
dd8116a3a25422544b20d2639898f8d60e810c3075a4ed9972c1ba67f5918fa309b3df717e908891eb188d624ca494d53d0a2aa4fdca9037b353d531c80daeda 0021-broadband-modem-fail-synchronization-if-no-modem-exp.patch
3a21ff23bf9a9db604ad68171dda34cf833cafe96e9f57a3390de3f4d4d32f60f417de18d1f64a1dccd23d9a936975177101755cae8980cc93dbc035f1a7ded1 0022-broadband-modem-fix-state-machine-logic-when-synchro.patch
1aa82664e61cfc85c06849ee8a48ed20b268f5ed60106c0a21f1400726f001ffad35111ffd8593b8d9c08bf6a7b48cca93df5d06c11a88a249a5988204b581c3 0023-broadband-modem-abort-sync-if-locked-SIM-card-found.patch
f1c1691fbd94550170e23d08809c9d01fc644fa446dc0b482e741671fd0a31c96cb8ddd6ba6c03e29e996f6cb4c39c4a7f3d1ca614cb9435305269ead835d1f7 0024-iface-modem-remove-the-signal-quality-enforced-refre.patch
5387aa50d35f68db5577d2a8fd8862cfa40d56a9ffb8db22ed469011c765288b578979998ba1906c68e175fa9a1a2706678e9c13a9e11f500a773a06013c6fc7 0025-iface-modem-ignore-cancellation-during-sync.patch
ac46f072becac22ad5f88942e906b9e0bfa726e452a4b617d80c1d64fb224636218f22ab9dae4e13d875bcf59beec077bc1dc35ae29f9615e4034cf15f08d5f0 0026-base-bearer-synchronize-state-when-resuming.patch
9c52feb74c273e43eae3218b3ab221cc922536e4f73b5288b46ed59e7ae4be525d84fd510c27486a7735ccff826801d7d2f1a71b45a22a8919c563526495de53 0027-base-bearer-improve-comments-of-the-load-reload_conn.patch
f2891cf6ea1465bfcc4d4f902864e6fcb5c95ede724d9e55b90ab0d8f6d2b1512258d51345aa7653f30f46464ab1ca1996247ec194087e6c01788f6e606166c6 0028-base-bearer-fix-connection-reload-completion.patch
c4dfd858352f35f65397e38f2e5f9ca52899323bb9edc824b0c9397c02e2283add22c94468b4e784d14251b54ca96142c5b60c796130b836c3e4f9d6636d5aa9 0029-base-bearer-propagate-the-new-connection-status-afte.patch
4ab3bd5c6ae742dd0ed993fa540c8450e2458bc89679133e98dae802ead5e923408dca2e31ed63cf6892b443c44ef8d812f70f50fae5a77e8e511bbf535f7fb3 0030-iface-modem-bearer-list-sync-all-bearers-one-after-t.patch
cfcae1706d9fc0aca3f9d2fd60f05aa8c0985bc2bb94cae991900c97f0a7702cd3d9d0f6f4b39544855d8cbea7c4a29796f9abf6a8bf68506112cf0b0515a80e 0031-base-bearer-ignore-cancellation-during-sync.patch
84afa04a171064a916ff894854f79f48287a7f738fd7dbfaf00e825050fab30b4f8c56e690a021e3f370f0c332e73fb8696051bdc72fa5ba4d9ed204fc755085 0032-broadband-bearer-reuse-the-same-method-for-load-and-.patch
1b3c50476350ace754edd65a2748339edfee8ace5b56de3d38d3a6f1bdea9a0864becb03f948e8d1429b6f192b2e5c7d813731a24ac05f1dfb3b174f9725653a 0033-novatel-lte-reuse-the-same-method-for-load-and-reloa.patch
7a30cf38ff0f735794be282cc548f34a997d88d2d5acdcd077ffc398ff55a807180d5d309cfa6a254a8bb76ae7eb9d3b14fb972a3694dd454b99d635009ad1f3 0034-sierra-reuse-the-same-method-for-load-and-reload.patch
f4d8d23bb1c9c074db5c0036acae09b2a24587f7822119688f5bc017bcc1ea8570fc630d9b93267048b0f2295e6a8e669843b3d0c860ee6b2c43994e0c9685f4 0035-cinterion-reuse-the-same-method-for-load-and-reload.patch
689bebdd0a49adcfe1a35550f1424e376b70882ee97af9f622a636ab06ab13332a873320fab2dd52edd563e2ae8796a956e643b0a0aaa2093b65dc13aa90b397 0036-plugins-ignore-reload_connection_status-where-not-su.patch
bcee3ef714dd2117893176ccf402a21112d02c03e4dd062f6203e02a677ebe3add3141586b69cc2d76ef6a83b69cd53b55c7ede1649ab1ed8f400e45a358f9cb 0037-bearer-qmi-implement-reload_connection_status-for-th.patch
541baa9a07a2a5a6b6364412f95752a48a5ed398168a94ced1e2bef9f991b0c6cd6194060f39449d6fc4cfda8750cc2d974de6e30aef2ac806db4446a976e894 0038-bearer-mbim-implement-reload_connection_status.patch
4c411d8ae2aab3a0e84f9761db912500fdc01d5932722b34165d4b480af784fb63bd8268b4b66877c45d5778c28c7b6f4ed49434919dad2492b7e29a201b5a46 0039-ModemManager-backport-Quick-Suspend-Resume-patches-t.patch
0318f7c20a5090e32a2752ec05c33d447956f15cbccfe7773cbd39b81f42c02f18fbf1941c26ef766747d22c10787250c23b106fc4017ed4c4906c3c9810a0ff ModemManager-1.17.900.tar.xz
6fab86c27502b29be0c6610d835a3249a4a81993eb986cff2c3ea9393fadd3f693ba4bb0532ae0e50a83d359559511859dd05f7ea2f0cb52839f535a7e49f8a0 modemmanager.rules
9f74a2473b9cc7be42a467809639f5720ab251d13f29f8bbd4fd9a13edb80c10c5ee50fbe50819bfe67f231805b92f007c3e7403c46ab998dc843e1f9549659b modemmanager.initd
"