[PATCH] huawei: Retry connect/disconnect attempt upon NDISSTATQRY failures.

Dan Williams dcbw at redhat.com
Wed Aug 28 11:22:30 PDT 2013


On Wed, 2013-08-28 at 10:33 -0700, Prathmesh Prabhu wrote:
> Hi,
> 
> Please consider the following patch.

Thanks!

A couple issues first though...  best to use 'git format-patch' to
generate the patch, which means we can more easily apply it.  Next,
since most mail clients line-wrap by default, you need to set your mail
client to "preformatted" when pasting the patch into the email, or put
the patch as an attachment to the message.  Ben might be able to help
you with these issues if you've got any questions.

Dan

> 
> Thanks,
> 
> 
> Prathmesh
> 
> 
> This is a workaround for a bug in the modem firmware that causes the NDISSTATQRY
> 
> response to be an error response intermittently. With this patch, the connect /
> disconnect attempt ignores a few of these error responses. Note that the overall
> time-out for the connect/disconnect is not affected by this change.
> 
> 
> diff --git a/plugins/huawei/mm-broadband-bearer-huawei.c
> b/plugins/huawei/mm-broadband-bearer-huawei.c
> index 2e1b0b0..75d3566 100644
> --- a/plugins/huawei/mm-broadband-bearer-huawei.c
> +++ b/plugins/huawei/mm-broadband-bearer-huawei.c
> @@ -57,6 +57,7 @@ typedef struct {
>      GSimpleAsyncResult *result;
>      Connect3gppContextStep step;
>      guint check_count;
> +    guint failed_ndisstatqry_count;
>  } Connect3gppContext;
> 
>  static void
> @@ -130,20 +131,15 @@ connect_ndisstatqry_check_ready (MMBaseModem *modem,
>                                                 &ipv6_available,
>                                                 &ipv6_connected,
>                                                 &error)) {
> -        mm_dbg ("Modem doesn't properly support ^NDISSTATQRY command: %s",
> error->message);
> +        ctx->failed_ndisstatqry_count++;
> +        mm_dbg ("Unexpected response to ^NDISSTATQRY command: %s (Attempts
> so far: %d)",
> +                error->message, ctx->failed_ndisstatqry_count);
>          g_error_free (error);
> -
> -        ctx->self->priv->connect_pending = NULL;
> -        g_simple_async_result_set_error (ctx->result,
> -                                         MM_MOBILE_EQUIPMENT_ERROR,
> -
> MM_MOBILE_EQUIPMENT_ERROR_NOT_SUPPORTED,
> -                                         "Connection attempt not
> supported");
> -        connect_3gpp_context_complete_and_free (ctx);
> -        return;
> +        response = NULL;  /* Set to NULL to skip steps below. */
>      }
> 
>      /* Connected in IPv4? */
> -    if (ipv4_available && ipv4_connected) {
> +    if (response && ipv4_available && ipv4_connected) {
>          /* Success! */
>          ctx->step++;
>          connect_3gpp_context_step (ctx);
> @@ -315,6 +311,17 @@ connect_3gpp_context_step (Connect3gppContext *ctx)
>              connect_3gpp_context_complete_and_free (ctx);
>              return;
>          }
> +        /* Give up if too many unexpected responses to NIDSSTATQRY are
> encountered. */
> +        if (ctx->failed_ndisstatqry_count > 3) {
> +            /* Clear context */
> +            ctx->self->priv->connect_pending = NULL;
> +            g_simple_async_result_set_error (ctx->result,
> +                                             MM_MOBILE_EQUIPMENT_ERROR,
> +
> MM_MOBILE_EQUIPMENT_ERROR_NOT_SUPPORTED,
> +                                             "Connection attempt not
> supported.");
> +            connect_3gpp_context_complete_and_free (ctx);
> +            return;
> +        }
> 
>          /* Check if connected */
>          ctx->check_count++;
> @@ -413,6 +420,7 @@ typedef struct {
>      GSimpleAsyncResult *result;
>      Disconnect3gppContextStep step;
>      guint check_count;
> +    guint failed_ndisstatqry_count;
>  } Disconnect3gppContext;
> 
>  static void
> @@ -480,20 +488,15 @@ disconnect_ndisstatqry_check_ready (MMBaseModem
> *modem,
>                                                 &ipv6_available,
>                                                 &ipv6_connected,
>                                                 &error)) {
> -        mm_dbg ("Modem doesn't properly support ^NDISSTATQRY command: %s",
> error->message);
> +        ctx->failed_ndisstatqry_count++;
> +        mm_dbg ("Unexpected response to ^NDISSTATQRY command: %s (Attempts
> so far: %d)",
> +                error->message, ctx->failed_ndisstatqry_count);
>          g_error_free (error);
> -
> -        ctx->self->priv->disconnect_pending = NULL;
> -        g_simple_async_result_set_error (ctx->result,
> -                                         MM_MOBILE_EQUIPMENT_ERROR,
> -
> MM_MOBILE_EQUIPMENT_ERROR_NOT_SUPPORTED,
> -                                         "Disconnection attempt not
> supported");
> -        disconnect_3gpp_context_complete_and_free (ctx);
> -        return;
> +        response = NULL;  /* Set to NULL to skip steps below. */
>      }
> 
>      /* Disconnected IPv4? */
> -    if (ipv4_available && !ipv4_connected) {
> +    if (response && ipv4_available && !ipv4_connected) {
>          /* Success! */
>          ctx->step++;
>          disconnect_3gpp_context_step (ctx);
> @@ -568,6 +571,17 @@ disconnect_3gpp_context_step (Disconnect3gppContext
> *ctx)
>              disconnect_3gpp_context_complete_and_free (ctx);
>              return;
>          }
> +        /* Give up if too many unexpected responses to NIDSSTATQRY are
> encountered. */
> +        if (ctx->failed_ndisstatqry_count > 3) {
> +            /* Clear context */
> +            ctx->self->priv->disconnect_pending = NULL;
> +            g_simple_async_result_set_error (ctx->result,
> +                                             MM_MOBILE_EQUIPMENT_ERROR,
> +
> MM_MOBILE_EQUIPMENT_ERROR_NOT_SUPPORTED,
> +                                             "Disconnection attempt not
> supported.");
> +            disconnect_3gpp_context_complete_and_free (ctx);
> +            return;
> +        }
> 
>          /* Check if disconnected */
>          ctx->check_count++;




More information about the ModemManager-devel mailing list