aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--plugins/option/mm-broadband-bearer-hso.c48
1 files changed, 33 insertions, 15 deletions
diff --git a/plugins/option/mm-broadband-bearer-hso.c b/plugins/option/mm-broadband-bearer-hso.c
index 561c11fc..0d163024 100644
--- a/plugins/option/mm-broadband-bearer-hso.c
+++ b/plugins/option/mm-broadband-bearer-hso.c
@@ -332,7 +332,7 @@ mm_broadband_bearer_hso_report_connection_status (MMBroadbandBearerHso *self,
self->priv->connect_pending_id = 0;
}
- if (self->priv->connect_cancellable_id) {
+ if (ctx && self->priv->connect_cancellable_id) {
g_cancellable_disconnect (ctx->cancellable,
self->priv->connect_cancellable_id);
self->priv->connect_cancellable_id = 0;
@@ -456,10 +456,24 @@ connect_cancelled_cb (GCancellable *cancellable,
static void
activate_ready (MMBaseModem *modem,
GAsyncResult *res,
- Dial3gppContext *ctx)
+ MMBroadbandBearerHso *self)
{
+ Dial3gppContext *ctx;
GError *error = NULL;
+ /* Try to recover the connection context. If none found, it means the
+ * context was already completed and we have nothing else to do. */
+ ctx = self->priv->connect_pending;
+
+ if (!ctx) {
+ mm_dbg ("Connection context was finished already by an unsolicited message");
+
+ /* Run _finish() to finalize the async call, even if we don't care
+ * the result */
+ mm_base_modem_at_command_full_finish (modem, res, NULL);
+ return;
+ }
+
/* From now on, if we get cancelled, we'll need to run the connection
* reset ourselves just in case */
@@ -471,13 +485,13 @@ activate_ready (MMBaseModem *modem,
/* We will now setup a timeout so that we don't wait forever to get the
* connection on */
- ctx->self->priv->connect_pending_id = g_timeout_add_seconds (30,
- (GSourceFunc)connect_timed_out_cb,
- ctx->self);
- ctx->self->priv->connect_cancellable_id = g_cancellable_connect (ctx->cancellable,
- G_CALLBACK (connect_cancelled_cb),
- ctx->self,
- NULL);
+ self->priv->connect_pending_id = g_timeout_add_seconds (30,
+ (GSourceFunc)connect_timed_out_cb,
+ self);
+ self->priv->connect_cancellable_id = g_cancellable_connect (ctx->cancellable,
+ G_CALLBACK (connect_cancelled_cb),
+ self,
+ NULL);
}
static void authenticate (Dial3gppContext *ctx);
@@ -503,6 +517,15 @@ authenticate_ready (MMBaseModem *modem,
/* Store which auth command worked, for next attempts */
ctx->self->priv->auth_idx = ctx->auth_idx;
+ /* The unsolicited response to AT_OWANCALL may come before the OK does.
+ * We will keep the connection context in the bearer private data so
+ * that it is accessible from the unsolicited message handler. Note
+ * also that we do NOT pass the ctx to the GAsyncReadyCallback, as it
+ * may not be valid any more when the callback is called (it may be
+ * already completed in the unsolicited handling) */
+ g_assert (ctx->self->priv->connect_pending == NULL);
+ ctx->self->priv->connect_pending = ctx;
+
/* Success, activate the PDP context and start the data session */
command = g_strdup_printf ("AT_OWANCALL=%d,1,1",
ctx->cid);
@@ -513,13 +536,8 @@ authenticate_ready (MMBaseModem *modem,
FALSE,
NULL, /* cancellable */
(GAsyncReadyCallback)activate_ready,
- ctx);
+ ctx->self); /* we pass the bearer object! */
g_free (command);
-
- /* We will now keep the context in the bearer's private.
- * Reports of modem being connected will arrive via unsolicited messages. */
- g_assert (ctx->self->priv->connect_pending == NULL);
- ctx->self->priv->connect_pending = ctx;
}
const gchar *auth_commands[] = {