From 04d50e2db7a4bae2b21112faadf5f23176663d1d Mon Sep 17 00:00:00 2001 From: Aleksander Morgado Date: Fri, 31 Aug 2012 10:01:11 +0200 Subject: [PATCH] icera: retry configuring PDP context if it fails. This is the port to git master of the following commit: commit fb3187847b9c62d5205962c3c707ac1f44eaddcc Author: Eric Shienbrood Date: Thu Aug 11 16:58:34 2011 -0400 icera: retry configuring PDP context if it fails. If a connect operation is attempted immediately after a disconnect, it sometimes fails with CME error 583 - "a profile (CID) is currently active". Apparently, even though the preceding operation (%IPDPACT) to deactivate the PDP context returned an OK response, the context is not really completely available until a fraction of a second later. This causes the %IPDPCFG operation that is part of the subsequent connect attempt to fail with error 583. This change retries the %IPDPCFG after a one second delay. BUG=chrome-os-partner:4936 TEST=This can be tested from the UI, but I found it easier to produce the timing needed to trigger the bug by running mm-disconnect and mm-connect from a shell. Start out with the modem in the connected state. In the shell, run sudo /usr/local/lib/flimflam/test/mm-disconnect; sudo /usr/local/lib/flimflam/test/mm-connect --number='*99#' --apn=wap.cingular modem-manager should emit the log line "Invalid error code: 583". Prior to this change, the connect operation would fail. Now it should succeed. Change-Id: I6ae0e6a9f5405b54b0b465fe91d9542529f365c2 Reviewed-on: http://gerrit.chromium.org/gerrit/5781 Tested-by: Eric Shienbrood Reviewed-by: Nathan J. Williams --- plugins/icera/mm-broadband-bearer-icera.c | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/plugins/icera/mm-broadband-bearer-icera.c b/plugins/icera/mm-broadband-bearer-icera.c index 8a277f0f..64c9b276 100644 --- a/plugins/icera/mm-broadband-bearer-icera.c +++ b/plugins/icera/mm-broadband-bearer-icera.c @@ -459,6 +459,7 @@ typedef struct { guint cid; GCancellable *cancellable; GSimpleAsyncResult *result; + guint authentication_retries; } Dial3gppContext; static Dial3gppContext * @@ -792,6 +793,15 @@ deactivate_ready (MMBaseModem *modem, g_free (command); } +static void authenticate (Dial3gppContext *ctx); + +static gboolean +retry_authentication_cb (Dial3gppContext *ctx) +{ + authenticate (ctx); + return FALSE; +} + static void authenticate_ready (MMBaseModem *modem, GAsyncResult *res, @@ -805,7 +815,16 @@ authenticate_ready (MMBaseModem *modem, return; if (!mm_base_modem_at_command_full_finish (modem, res, &error)) { - /* TODO(njw): retry up to 3 times with a 1-second delay */ + /* Retry configuring the context. It sometimes fails with a 583 + * error ["a profile (CID) is currently active"] if a connect + * is attempted too soon after a disconnect. */ + if (++ctx->authentication_retries < 3) { + mm_dbg ("Authentication failed: '%s'; retrying...", error->message); + g_error_free (error); + g_timeout_add_seconds (1, (GSourceFunc)retry_authentication_cb, ctx); + return; + } + /* Return an error */ g_simple_async_result_take_error (ctx->result, error); dial_3gpp_context_complete_and_free (ctx);