summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAleksander Morgado <aleksander@aleksander.es>2019-12-21 09:45:08 +0100
committerAleksander Morgado <aleksander@aleksander.es>2019-12-21 15:14:58 +0100
commit160821383eedccf7e7e2ae1a3cfeb028df7b15ae (patch)
tree1bad7096f93a2826436ed8a1fff74be97d0f7ff7
parent7d3adeca4d9feee55e74831a086e88ae49886efd (diff)
iface-modem-simple: clear ongoing connect cancellable on early errors
If the Simple.Connect() operation fails before the bearer connection process starts (e.g. during the previous SIM-PIN checks or explicit registration attempt), the ongoing connect cancellable is not being properly cleared, and this would prevent additional new connection attempts unless an explicit Simple.Disconnect() is called. $ sudo mmcli -m 1 --simple-connect="operator-id=21403,apn=internet" error: couldn't connect the modem: 'GDBus.Error:org.freedesktop.ModemManager1.Error.MobileEquipment.NetworkTimeout: Network timeout' $ sudo mmcli -m 1 --simple-connect="operator-id=21403,apn=internet" error: couldn't connect the modem: 'GDBus.Error:org.freedesktop.ModemManager1.Error.Core.InProgress: Connection request forbidden: operation already in progress' $ sudo mmcli -m 1 --simple-connect="operator-id=21403,apn=internet" error: couldn't connect the modem: 'GDBus.Error:org.freedesktop.ModemManager1.Error.Core.InProgress: Connection request forbidden: operation already in progress' Fix this, by making sure the ongoing connect cancellable is always cleared when completing the DBus method invocation that created it. Fixes https://gitlab.freedesktop.org/mobile-broadband/ModemManager/issues/169 (cherry picked from commit 7a398214f9a4d85399d082634d08b2f47a8b7778)
-rw-r--r--src/mm-iface-modem-simple.c31
1 files changed, 20 insertions, 11 deletions
diff --git a/src/mm-iface-modem-simple.c b/src/mm-iface-modem-simple.c
index 1e29c3ce..50c31a00 100644
--- a/src/mm-iface-modem-simple.c
+++ b/src/mm-iface-modem-simple.c
@@ -238,9 +238,28 @@ typedef struct {
} ConnectionContext;
static void
-connection_context_free (ConnectionContext *ctx)
+cleanup_cancellation (ConnectionContext *ctx)
{
+ Private *priv;
+
+ /* The ongoing connect cancellable and the one in the connection context
+ * must be the same, as they're set together, so if the one in the
+ * context doesn't exist, do nothing. */
+ if (!ctx->cancellable)
+ return;
+
+ /* If the ongoing connect cancellable is cancelled via the Simple.Disconnect
+ * method, it won't exist in the private struct, so don't assume they
+ * both exist. */
+ priv = get_private (ctx->self);
+ g_clear_object (&priv->ongoing_connect);
g_clear_object (&ctx->cancellable);
+}
+
+static void
+connection_context_free (ConnectionContext *ctx)
+{
+ cleanup_cancellation (ctx);
g_clear_object (&ctx->properties);
g_clear_object (&ctx->bearer);
g_variant_unref (ctx->dictionary);
@@ -487,16 +506,6 @@ completed_if_cancelled (ConnectionContext *ctx)
return TRUE;
}
-static void
-cleanup_cancellation (ConnectionContext *ctx)
-{
- Private *priv;
-
- priv = get_private (ctx->self);
- g_clear_object (&priv->ongoing_connect);
- g_clear_object (&ctx->cancellable);
-}
-
static gboolean
setup_cancellation (ConnectionContext *ctx,
GError **error)