From: Marcel Holtmann <marcel@holtmann.org>
To: ofono@ofono.org
Subject: Re: [PATCH v2] atmodem: fix crash during context deactivation
Date: Wed, 26 May 2010 10:35:52 +0200 [thread overview]
Message-ID: <1274862952.27220.147.camel@localhost.localdomain> (raw)
In-Reply-To: <20100525145641.11296.52980.stgit@potku.valot.fi>
[-- Attachment #1: Type: text/plain, Size: 4406 bytes --]
Hi Kalle,
> Ofono either crashed or busy looped with my Huawei E1552 3G modem when I
> tried to deactivate GPRS context. The reason was that gcd->chat was
> unreferenced already in setup_ppp() but the chat was still accessed
> later in at_gprs_deactivate_primary().
>
> To fix the problem, change the logic instead to suspend chat session
> for PPP and resume when PPP has disconnected. Now it doesn't crash
> anymore.
>
> Also remove the CGACT=0 command during deactivation, it's enough to shutdown
> ppp.
>
> Deactivation still doesn't work properly with Huawei E1552, and most
> probably with other Huawei modems, because the modem hangs up the chat
> line after PPP deactivation. This needs to be fixed separately. The
> workaround is to reboot the modem, for example physically unplug and plug
> it in again.
> ---
>
> drivers/atmodem/gprs-context.c | 56 +++++++++++++---------------------------
> 1 files changed, 18 insertions(+), 38 deletions(-)
>
> diff --git a/drivers/atmodem/gprs-context.c b/drivers/atmodem/gprs-context.c
> index ba5f0c0..794db8a 100644
> --- a/drivers/atmodem/gprs-context.c
> +++ b/drivers/atmodem/gprs-context.c
> @@ -65,22 +65,6 @@ struct gprs_context_data {
> void *cb_data; /* Callback data */
> };
>
> -static void at_cgact_down_cb(gboolean ok, GAtResult *result, gpointer user_data)
> -{
> - struct cb_data *cbd = user_data;
> - ofono_gprs_context_cb_t cb = cbd->cb;
> - struct ofono_gprs_context *gc = cbd->user;
> - struct gprs_context_data *gcd = ofono_gprs_context_get_data(gc);
> - struct ofono_error error;
> -
> - if (ok)
> - gcd->active_context = 0;
> -
> - decode_at_error(&error, g_at_result_final_response(result));
> -
> - cb(&error, cbd->data);
> -}
> -
> static void ppp_connect(const char *interface, const char *ip,
> const char *dns1, const char *dns2,
> gpointer user_data)
> @@ -104,13 +88,19 @@ static void ppp_disconnect(GAtPPPDisconnectReason reason, gpointer user_data)
> struct ofono_gprs_context *gc = user_data;
> struct gprs_context_data *gcd = ofono_gprs_context_get_data(gc);
>
> + DBG("");
> +
> + g_at_chat_resume(gcd->chat);
> +
> if (gcd->state == STATE_ENABLING) {
> CALLBACK_WITH_FAILURE(gcd->up_cb, NULL, FALSE, NULL,
> NULL, NULL, NULL, gcd->cb_data);
> - return;
> + } else if (gcd->state == STATE_DISABLING) {
> + CALLBACK_WITH_SUCCESS(gcd->down_cb, gcd->cb_data);
> + } else {
> + ofono_gprs_context_deactivated(gc, gcd->active_context);
> }
the easier to read coding style here is noew clearly a switch statement.
> - ofono_gprs_context_deactivated(gc, gcd->active_context);
> gcd->active_context = 0;
> gcd->state = STATE_IDLE;
> }
> @@ -118,13 +108,14 @@ static void ppp_disconnect(GAtPPPDisconnectReason reason, gpointer user_data)
> static gboolean setup_ppp(struct ofono_gprs_context *gc)
> {
> struct gprs_context_data *gcd = ofono_gprs_context_get_data(gc);
> - GIOChannel *channel;
> + GAtIO *io;
> +
> + io = g_at_chat_get_io(gcd->chat);
>
> - channel = g_at_chat_get_channel(gcd->chat);
> - g_at_chat_unref(gcd->chat);
> + g_at_chat_suspend(gcd->chat);
>
> /* open ppp */
> - gcd->ppp = g_at_ppp_new(channel);
> + gcd->ppp = g_at_ppp_new_from_io(io);
>
> if (gcd->ppp == NULL)
> return FALSE;
> @@ -227,25 +218,14 @@ static void at_gprs_deactivate_primary(struct ofono_gprs_context *gc,
> ofono_gprs_context_cb_t cb, void *data)
> {
> struct gprs_context_data *gcd = ofono_gprs_context_get_data(gc);
> - struct cb_data *cbd = cb_data_new(cb, data);
> - char buf[64];
> -
> - if (!cbd)
> - goto error;
> -
> - cbd->user = gc;
>
> - snprintf(buf, sizeof(buf), "AT+CGACT=0,%u", id);
> + DBG("");
>
> - if (g_at_chat_send(gcd->chat, buf, none_prefix,
> - at_cgact_down_cb, cbd, g_free) > 0)
> - return;
> -
> -error:
> - if (cbd)
> - g_free(cbd);
> + gcd->state = STATE_DISABLING;
> + gcd->down_cb = cb;
> + gcd->cb_data = data;
>
> - CALLBACK_WITH_FAILURE(cb, data);
> + g_at_ppp_shutdown(gcd->ppp);
> }
>
> static int at_gprs_context_probe(struct ofono_gprs_context *gc,
The rest looks fine to me. However maybe splitting this into one patch
that removes the CGACT and another that adds suspend/resume calls seems
a bit cleaner to me.
Regards
Marcel
next prev parent reply other threads:[~2010-05-26 8:35 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
2010-05-25 14:56 [PATCH v2] atmodem: fix crash during context deactivation Kalle Valo
2010-05-26 7:05 ` Kalle Valo
2010-05-26 8:35 ` Marcel Holtmann [this message]
2010-05-26 15:06 ` Kalle Valo
2010-05-26 15:04 ` Zhang, Zhenhua
2010-05-26 15:33 ` Kalle Valo
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1274862952.27220.147.camel@localhost.localdomain \
--to=marcel@holtmann.org \
--cc=ofono@ofono.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox