[PATCH v5 2/2] huawei: delay processing of network-initiated disconnection

Prathmesh Prabhu Chromium pprabhu at chromium.org
Fri Sep 20 11:19:51 PDT 2013


Thanks Aleksander,

Verified that the final patch here on top of

[PATCH v4 1/2] bearer: consolidate unsolicited connection status reports

work correctly w.r.t. Huawei MU736, i.e., connect/disconnect/network
initiated disconnect operations all work correctly.


On Fri, Sep 20, 2013 at 10:29 AM, Aleksander Morgado
<aleksander at lanedo.com>wrote:

> Originally developed by:
>   Prathmesh Prabhu <pprabhu at chromium.org>
>   Ben Chan <benchan at chromium.org>
>
> Huawei MU736 prematurely fires a ^NDISSTAT unsolicited message upon a
> network-initiated disconnection. The modem can go into a bad state if a
> reconnect attempt happens before the disconnection completes. This patch
> works
> around the issue by delaying the reporting of the disconnection.
> ---
>  plugins/huawei/mm-broadband-bearer-huawei.c | 56
> ++++++++++++++++++++++++++++-
>  plugins/huawei/mm-broadband-modem-huawei.c  |  7 ++--
>  src/mm-bearer.h                             |  1 +
>  3 files changed, 61 insertions(+), 3 deletions(-)
>
> diff --git a/plugins/huawei/mm-broadband-bearer-huawei.c
> b/plugins/huawei/mm-broadband-bearer-huawei.c
> index 2d8f0cd..deb91ca 100644
> --- a/plugins/huawei/mm-broadband-bearer-huawei.c
> +++ b/plugins/huawei/mm-broadband-bearer-huawei.c
> @@ -37,6 +37,8 @@ G_DEFINE_TYPE (MMBroadbandBearerHuawei,
> mm_broadband_bearer_huawei, MM_TYPE_BROA
>  struct _MMBroadbandBearerHuaweiPrivate {
>      gpointer connect_pending;
>      gpointer disconnect_pending;
> +    /* Tag for the post task for network-initiated disconnect */
> +    guint network_disconnect_pending_id;
>  };
>
>
>  /*****************************************************************************/
> @@ -232,6 +234,11 @@ connect_3gpp_context_step (Connect3gppContext *ctx)
>          return;
>      }
>
> +    /* Network-initiated disconnect should not be outstanding at this
> point,
> +     * because it interferes with the connect attempt.
> +     */
> +    g_assert (ctx->self->priv->network_disconnect_pending_id == 0);
> +
>      switch (ctx->step) {
>      case CONNECT_3GPP_CONTEXT_STEP_FIRST: {
>          MMBearerIpFamily ip_family;
> @@ -598,6 +605,11 @@ disconnect_3gpp_context_step (Disconnect3gppContext
> *ctx)
>          return;
>
>      case DISCONNECT_3GPP_CONTEXT_STEP_LAST:
> +        if (ctx->self->priv->network_disconnect_pending_id != 0) {
> +            g_source_remove
> (ctx->self->priv->network_disconnect_pending_id);
> +            ctx->self->priv->network_disconnect_pending_id = 0;
> +        }
> +
>          /* Clear context */
>          ctx->self->priv->disconnect_pending = NULL;
>          /* Set data port as result */
> @@ -640,6 +652,18 @@ disconnect_3gpp (MMBroadbandBearer *self,
>
>
>  /*****************************************************************************/
>
> +static gboolean
> +network_disconnect_3gpp_delayed (MMBroadbandBearerHuawei *self)
> +{
> +    mm_dbg ("Disconnect bearer '%s' on network request.",
> +            mm_bearer_get_path (MM_BEARER (self)));
> +
> +    self->priv->network_disconnect_pending_id = 0;
> +    mm_bearer_report_connection_status (MM_BEARER (self),
> +
>  MM_BEARER_CONNECTION_STATUS_DISCONNECTED);
> +    return FALSE;
> +}
> +
>  static void
>  report_connection_status (MMBearer *bearer,
>                            MMBearerConnectionStatus status)
> @@ -647,6 +671,7 @@ report_connection_status (MMBearer *bearer,
>      MMBroadbandBearerHuawei *self = MM_BROADBAND_BEARER_HUAWEI (bearer);
>
>      g_assert (status == MM_BEARER_CONNECTION_STATUS_CONNECTED ||
> +              status == MM_BEARER_CONNECTION_STATUS_DISCONNECTING ||
>                status == MM_BEARER_CONNECTION_STATUS_DISCONNECTED);
>
>      /* When a pending connection / disconnection attempt is in progress,
> we use
> @@ -664,7 +689,22 @@ report_connection_status (MMBearer *bearer,
>
>      /* We already use ^NDISSTATQRY? to poll the connection status, so only
>       * handle network-initiated disconnection here. */
> -    mm_dbg ("Disconnect bearer '%s'", mm_bearer_get_path (MM_BEARER
> (self)));
> +    if (status == MM_BEARER_CONNECTION_STATUS_DISCONNECTING) {
> +        /* MM_BEARER_CONNECTION_STATUS_DISCONNECTING is used to indicate
> that the
> +         * reporting of disconnection should be delayed. See
> MMBroadbandModemHuawei's
> +         * bearer_report_connection_status for details. */
> +        if (self->priv->network_disconnect_pending_id == 0) {
> +            mm_dbg ("Delay network-initiated disconnection of bearer
> '%s'",
> +                    mm_bearer_get_path (MM_BEARER (self)));
> +            self->priv->network_disconnect_pending_id =
> (g_timeout_add_seconds (
> +                                                             4,
> +
> (GSourceFunc) network_disconnect_3gpp_delayed,
> +                                                             self));
> +        }
> +        return;
> +    }
> +
> +    /* Report disconnected right away */
>      MM_BEARER_CLASS
> (mm_broadband_bearer_huawei_parent_class)->report_connection_status (
>          bearer,
>          MM_BEARER_CONNECTION_STATUS_DISCONNECTED);
> @@ -692,6 +732,19 @@ mm_broadband_bearer_huawei_new_finish (GAsyncResult
> *res,
>      return MM_BEARER (bearer);
>  }
>
> +static void
> +dispose (GObject *object)
> +{
> +    MMBroadbandBearerHuawei *self = MM_BROADBAND_BEARER_HUAWEI (object);
> +
> +    if (self->priv->network_disconnect_pending_id != 0) {
> +        g_source_remove (self->priv->network_disconnect_pending_id);
> +        self->priv->network_disconnect_pending_id = 0;
> +    }
> +
> +    G_OBJECT_CLASS (mm_broadband_bearer_huawei_parent_class)->dispose
> (object);
> +}
> +
>  void
>  mm_broadband_bearer_huawei_new (MMBroadbandModemHuawei *modem,
>                                  MMBearerProperties *config,
> @@ -728,6 +781,7 @@ mm_broadband_bearer_huawei_class_init
> (MMBroadbandBearerHuaweiClass *klass)
>
>      g_type_class_add_private (object_class, sizeof
> (MMBroadbandBearerHuaweiPrivate));
>
> +    object_class->dispose = dispose;
>      bearer_class->report_connection_status = report_connection_status;
>      broadband_bearer_class->connect_3gpp = connect_3gpp;
>      broadband_bearer_class->connect_3gpp_finish = connect_3gpp_finish;
> diff --git a/plugins/huawei/mm-broadband-modem-huawei.c
> b/plugins/huawei/mm-broadband-modem-huawei.c
> index f93f5a1..4f231df 100644
> --- a/plugins/huawei/mm-broadband-modem-huawei.c
> +++ b/plugins/huawei/mm-broadband-modem-huawei.c
> @@ -1525,11 +1525,14 @@ bearer_report_connection_status (MMBearer *bearer,
>  {
>      if (ndisstat_result->ipv4_available) {
>          /* TODO: MMBroadbandBearerHuawei does not currently support IPv6.
> -         * When it does, we should check the IP family associated with
> each bearer. */
> +         * When it does, we should check the IP family associated with
> each bearer.
> +         *
> +         * Also, send DISCONNECTING so that we give some time before
> actually
> +         * disconnecting the connection */
>          mm_bearer_report_connection_status (bearer,
>
>  ndisstat_result->ipv4_connected ?
>
>  MM_BEARER_CONNECTION_STATUS_CONNECTED :
> -
>  MM_BEARER_CONNECTION_STATUS_DISCONNECTED);
> +
>  MM_BEARER_CONNECTION_STATUS_DISCONNECTING);
>      }
>  }
>
> diff --git a/src/mm-bearer.h b/src/mm-bearer.h
> index dc217c5..c1bcaee 100644
> --- a/src/mm-bearer.h
> +++ b/src/mm-bearer.h
> @@ -70,6 +70,7 @@ typedef enum { /*< underscore_name=mm_bearer_status >*/
>  typedef enum { /*< underscore_name=mm_bearer_connection_status >*/
>      MM_BEARER_CONNECTION_STATUS_UNKNOWN,
>      MM_BEARER_CONNECTION_STATUS_DISCONNECTED,
> +    MM_BEARER_CONNECTION_STATUS_DISCONNECTING,
>      MM_BEARER_CONNECTION_STATUS_CONNECTED,
>      MM_BEARER_CONNECTION_STATUS_CONNECTION_FAILED,
>  } MMBearerConnectionStatus;
> --
> 1.8.3.1
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.freedesktop.org/archives/modemmanager-devel/attachments/20130920/ed0613e8/attachment-0001.html>


More information about the ModemManager-devel mailing list