aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAleksander Morgado <aleksander@lanedo.com>2012-07-20 12:24:13 +0200
committerAleksander Morgado <aleksander@lanedo.com>2012-08-06 20:07:26 +0200
commit63a45f808260f3138b595bf9b250d2a212cb83d4 (patch)
treeaa2a7ab7920490ec3ced9a27890ef82ea15e4a90
parentd065dd572b3abb5e76467abe1140bf2010fe6fbb (diff)
hso: avoid trying to use an already freed context
In the connection sequence, we keep the context in the private info of the Bearer object, so that we can complete and free it when we receive OWANCALL unsolicited messages. Now, the reply of the OWANCALL itself may get processed as an unsolicited message, so effectively we're processing and finishing the connection/disconnection context *before* we process the reply of the AT command. This patch ensures that we do not try to re-use the connection context after it has been processed by the unsolicited messages handler.
-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[] = {