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
This commit is contained in:
+20
-11
@@ -237,10 +237,29 @@ typedef struct {
|
||||
GCancellable *cancellable;
|
||||
} ConnectionContext;
|
||||
|
||||
static void
|
||||
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)
|
||||
{
|
||||
g_clear_object (&ctx->cancellable);
|
||||
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)
|
||||
|
||||
Reference in New Issue
Block a user