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

Prathmesh Prabhu Chromium pprabhu at chromium.org
Fri Sep 20 11:56:25 PDT 2013


@Aleksander: Soungs good, wrt your responses to Ben's concerns. The only
place where report_disconnect_status and report_connect_status are called
already guards against ctx being NULL.

I verified basic functionality of the icera plugin.

Thanks,
Prathmesh


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

> Originally developed by:
>   Ben Chan <benchan at chromium.org>
>
> This patch replaces mm_bearer_report_disconnection() with a more generic
> mm_bearer_report_connection_status(), which allows reporting any
> connection status of a bearer. This further allows getting rid of those
> custom report_connection_status functions in plugic specific bearer
> subclasses.
>
> Note that while plugin-specific implementations can receive multiple
> 'MMBearerConnectionStatus' values, the generic implementation is only
> allowed
> to receive DISCONNECTED. Plugins need to make sure that they process all
> the
> other status values, and only report DISCONNECTED to the parent when
> required.
>
> MBM:
>   The MBM bearer implementation of report_connection_status() expects
> either
>   CONNECTED or DISCONNECTED. If any of these is received and there is an
> ongoing
>   connection attempt, the corresponding operation will be completed. If
> there is
>   no connection attempt, we will just handle the DISCONNECTED state,
> calling the
>   parent method to notify that the modem got network-disconnected.
>
> Icera:
>   The Icera bearer implementation of report_connection_status() expects
> either
>   CONNECTED, CONNECT FAILED or DISCONNECTED. If any of these is received
> and
>   there is an ongoing connection or disconnection attempt, the
> corresponding
>   operation will be completed. If there is no connection or disconnection
>   attempt, we will just handle the CONNECT FAILED and DISCONNECTED states,
>   calling the parent method (always with DISCONNECTED) to notify that the
> modem
>   got network-disconnected.
>
> Option/HSO:
>   The Option/HSO bearer implementation of report_connection_status()
> expects
>   either CONNECTED, CONNECTION FAILED or DISCONNECTED. If any of these is
>   received and there is an ongoing connection or disconnection attempt, the
>   corresponding operation will be completed. If there is no connection or
>   disconnection attempt, we will just handle the CONNECTION FAILED and
>   DISCONNECTED states, calling the parent method (always with
> DISCONNECTED) to
>   notify that the modem got network-disconnected.
>
> Huawei:
>   The Huawei bearer implementation of report_connection_status() expects
> either
>   CONNECTED or DISCONNECTED. These messages are not used to process pending
>   connection or disconnection attempts; so if they are received while one
> of
>   these is on-going, it will just be ignored. CONNECTED reports are also
>   ignored, so we will just handle the DISCONNECTED state, calling the
> parent
>   method to notify that the modem got network-disconnected.
>
> Altair-LTE:
>   The Altair-LTE bearers will only report DISCONNECTED on
> network-disconnected
>   cases. There is no custom report_connection_status().
>
> Novatel-LTE:
>   The Novatel-LTE bearers will only report DISCONNECTED on
> network-disconnected
>   cases. There is no custom report_connection_status().
> ---
>  plugins/altair/mm-broadband-modem-altair-lte.c    |   3 +-
>  plugins/huawei/mm-broadband-bearer-huawei.c       |  30 +++--
>  plugins/huawei/mm-broadband-bearer-huawei.h       |   3 -
>  plugins/huawei/mm-broadband-modem-huawei.c        |   6 +-
>  plugins/icera/mm-broadband-bearer-icera.c         | 154
> ++++++++++------------
>  plugins/icera/mm-broadband-bearer-icera.h         |  10 --
>  plugins/icera/mm-broadband-modem-icera.c          |  15 +--
>  plugins/mbm/mm-broadband-bearer-mbm.c             |  63 +++++----
>  plugins/mbm/mm-broadband-bearer-mbm.h             |   9 --
>  plugins/mbm/mm-broadband-modem-mbm.c              |  13 +-
>  plugins/novatel/mm-broadband-bearer-novatel-lte.c |   2 +-
>  plugins/option/mm-broadband-bearer-hso.c          | 107 +++++++--------
>  plugins/option/mm-broadband-bearer-hso.h          |  10 --
>  plugins/option/mm-broadband-modem-hso.c           |  15 +--
>  src/mm-bearer-qmi.c                               |  14 +-
>  src/mm-bearer.c                                   |  16 ++-
>  src/mm-bearer.h                                   |  15 ++-
>  src/mm-broadband-bearer.c                         |  16 ++-
>  18 files changed, 243 insertions(+), 258 deletions(-)
>
> diff --git a/plugins/altair/mm-broadband-modem-altair-lte.c
> b/plugins/altair/mm-broadband-modem-altair-lte.c
> index 4fceff8..3303cbb 100644
> --- a/plugins/altair/mm-broadband-modem-altair-lte.c
> +++ b/plugins/altair/mm-broadband-modem-altair-lte.c
> @@ -518,7 +518,8 @@ static void
>  bearer_list_report_disconnect_status_foreach (MMBearer *bearer,
>                                                gpointer *user_data)
>  {
> -    mm_bearer_report_disconnection (bearer);
> +    mm_bearer_report_connection_status (bearer,
> +
>  MM_BEARER_CONNECTION_STATUS_DISCONNECTED);
>  }
>
>  static void
> diff --git a/plugins/huawei/mm-broadband-bearer-huawei.c
> b/plugins/huawei/mm-broadband-bearer-huawei.c
> index 233102f..2d8f0cd 100644
> --- a/plugins/huawei/mm-broadband-bearer-huawei.c
> +++ b/plugins/huawei/mm-broadband-bearer-huawei.c
> @@ -30,6 +30,7 @@
>  #include "mm-log.h"
>  #include "mm-modem-helpers.h"
>  #include "mm-modem-helpers-huawei.h"
> +#include "mm-daemon-enums-types.h"
>
>  G_DEFINE_TYPE (MMBroadbandBearerHuawei, mm_broadband_bearer_huawei,
> MM_TYPE_BROADBAND_BEARER)
>
> @@ -639,22 +640,34 @@ disconnect_3gpp (MMBroadbandBearer *self,
>
>
>  /*****************************************************************************/
>
> -void
> -mm_broadband_bearer_huawei_report_connection_status
> (MMBroadbandBearerHuawei *self,
> -                                                     gboolean connected)
> +static void
> +report_connection_status (MMBearer *bearer,
> +                          MMBearerConnectionStatus status)
>  {
> +    MMBroadbandBearerHuawei *self = MM_BROADBAND_BEARER_HUAWEI (bearer);
> +
> +    g_assert (status == MM_BEARER_CONNECTION_STATUS_CONNECTED ||
> +              status == MM_BEARER_CONNECTION_STATUS_DISCONNECTED);
> +
>      /* When a pending connection / disconnection attempt is in progress,
> we use
>       * ^NDISSTATQRY? to check the connection status and thus temporarily
> ignore
>       * ^NDISSTAT unsolicited messages */
>      if (self->priv->connect_pending || self->priv->disconnect_pending)
>          return;
>
> +    mm_dbg ("Received spontaneous ^NDISSTAT (%s)",
> +            mm_bearer_connection_status_get_string (status));
> +
> +    /* Ignore 'CONNECTED' */
> +    if (status == MM_BEARER_CONNECTION_STATUS_CONNECTED)
> +        return;
> +
>      /* We already use ^NDISSTATQRY? to poll the connection status, so only
>       * handle network-initiated disconnection here. */
> -    if (!connected) {
> -        mm_dbg ("Disconnect bearer '%s'", mm_bearer_get_path (MM_BEARER
> (self)));
> -        mm_bearer_report_disconnection (MM_BEARER (self));
> -    }
> +    mm_dbg ("Disconnect bearer '%s'", mm_bearer_get_path (MM_BEARER
> (self)));
> +    MM_BEARER_CLASS
> (mm_broadband_bearer_huawei_parent_class)->report_connection_status (
> +        bearer,
> +        MM_BEARER_CONNECTION_STATUS_DISCONNECTED);
>  }
>
>
>  /*****************************************************************************/
> @@ -710,11 +723,12 @@ static void
>  mm_broadband_bearer_huawei_class_init (MMBroadbandBearerHuaweiClass
> *klass)
>  {
>      GObjectClass *object_class = G_OBJECT_CLASS (klass);
> -
> +    MMBearerClass *bearer_class = MM_BEARER_CLASS (klass);
>      MMBroadbandBearerClass *broadband_bearer_class =
> MM_BROADBAND_BEARER_CLASS (klass);
>
>      g_type_class_add_private (object_class, sizeof
> (MMBroadbandBearerHuaweiPrivate));
>
> +    bearer_class->report_connection_status = report_connection_status;
>      broadband_bearer_class->connect_3gpp = connect_3gpp;
>      broadband_bearer_class->connect_3gpp_finish = connect_3gpp_finish;
>      broadband_bearer_class->disconnect_3gpp = disconnect_3gpp;
> diff --git a/plugins/huawei/mm-broadband-bearer-huawei.h
> b/plugins/huawei/mm-broadband-bearer-huawei.h
> index 3eb0efd..4c87d9c 100644
> --- a/plugins/huawei/mm-broadband-bearer-huawei.h
> +++ b/plugins/huawei/mm-broadband-bearer-huawei.h
> @@ -56,7 +56,4 @@ void      mm_broadband_bearer_huawei_new
>  (MMBroadbandModemHuawei *modem,
>  MMBearer *mm_broadband_bearer_huawei_new_finish (GAsyncResult *res,
>                                                   GError **error);
>
> -void mm_broadband_bearer_huawei_report_connection_status
> (MMBroadbandBearerHuawei *self,
> -                                                          gboolean
> connected);
> -
>  #endif /* MM_BROADBAND_BEARER_HUAWEI_H */
> diff --git a/plugins/huawei/mm-broadband-modem-huawei.c
> b/plugins/huawei/mm-broadband-modem-huawei.c
> index 66ec62d..f93f5a1 100644
> --- a/plugins/huawei/mm-broadband-modem-huawei.c
> +++ b/plugins/huawei/mm-broadband-modem-huawei.c
> @@ -1526,8 +1526,10 @@ 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. */
> -        mm_broadband_bearer_huawei_report_connection_status
> (MM_BROADBAND_BEARER_HUAWEI (bearer),
> -
> ndisstat_result->ipv4_connected);
> +        mm_bearer_report_connection_status (bearer,
> +
>  ndisstat_result->ipv4_connected ?
> +
>  MM_BEARER_CONNECTION_STATUS_CONNECTED :
> +
>  MM_BEARER_CONNECTION_STATUS_DISCONNECTED);
>      }
>  }
>
> diff --git a/plugins/icera/mm-broadband-bearer-icera.c
> b/plugins/icera/mm-broadband-bearer-icera.c
> index b7ea8df..48a2a79 100644
> --- a/plugins/icera/mm-broadband-bearer-icera.c
> +++ b/plugins/icera/mm-broadband-bearer-icera.c
> @@ -32,6 +32,7 @@
>  #include "mm-log.h"
>  #include "mm-modem-helpers.h"
>  #include "mm-error-helpers.h"
> +#include "mm-daemon-enums-types.h"
>
>  G_DEFINE_TYPE (MMBroadbandBearerIcera, mm_broadband_bearer_icera,
> MM_TYPE_BROADBAND_BEARER);
>
> @@ -360,13 +361,14 @@ disconnect_3gpp_timed_out_cb (MMBroadbandBearerIcera
> *self)
>
>  static void
>  report_disconnect_status (MMBroadbandBearerIcera *self,
> -                          MMBroadbandBearerIceraConnectionStatus status)
> +                          MMBearerConnectionStatus status)
>  {
>      Disconnect3gppContext *ctx;
>
>      /* Recover context */
>      ctx = self->priv->disconnect_pending;
>      self->priv->disconnect_pending = NULL;
> +    g_assert (ctx != NULL);
>
>      /* Cleanup timeout, if any */
>      if (self->priv->disconnect_pending_id) {
> @@ -374,42 +376,26 @@ report_disconnect_status (MMBroadbandBearerIcera
> *self,
>          self->priv->disconnect_pending_id = 0;
>      }
>
> -    switch (status) {
> -    case MM_BROADBAND_BEARER_ICERA_CONNECTION_STATUS_UNKNOWN:
> -        g_warn_if_reached ();
> -        break;
> -
> -    case MM_BROADBAND_BEARER_ICERA_CONNECTION_STATUS_CONNECTED:
> -        if (!ctx)
> -            break;
> -
> +    /* Received 'CONNECTED' during a disconnection attempt? */
> +    if (status == MM_BEARER_CONNECTION_STATUS_CONNECTED) {
>          g_simple_async_result_set_error (ctx->result,
>                                           MM_CORE_ERROR,
>                                           MM_CORE_ERROR_FAILED,
>                                           "Disconnection failed");
>          disconnect_3gpp_context_complete_and_free (ctx);
>          return;
> +    }
>
> -    case MM_BROADBAND_BEARER_ICERA_CONNECTION_STATUS_CONNECTION_FAILED:
> -        if (!ctx)
> -            break;
> -
> -        /* Well, this actually means disconnection, right? */
> -        g_simple_async_result_set_op_res_gboolean (ctx->result, TRUE);
> -        disconnect_3gpp_context_complete_and_free (ctx);
> -        return;
> -
> -    case MM_BROADBAND_BEARER_ICERA_CONNECTION_STATUS_DISCONNECTED:
> -        if (!ctx) {
> -            mm_dbg ("Received spontaneous %%IPDPACT disconnect");
> -            mm_bearer_report_disconnection (MM_BEARER (self));
> -            break;
> -        }
> -
> +    /* Received 'DISCONNECTED' during a disconnection attempt? */
> +    if (status == MM_BEARER_CONNECTION_STATUS_DISCONNECTED ||
> +        status == MM_BEARER_CONNECTION_STATUS_CONNECTION_FAILED) {
>          g_simple_async_result_set_op_res_gboolean (ctx->result, TRUE);
>          disconnect_3gpp_context_complete_and_free (ctx);
>          return;
>      }
> +
> +    /* No other status is expected by this implementation */
> +    g_assert_not_reached ();
>  }
>
>  static void
> @@ -658,9 +644,8 @@ forced_close_cb (MMSerialPort *port,
>                   MMBroadbandBearerIcera *self)
>  {
>      /* Just treat the forced close event as any other unsolicited message
> */
> -    mm_broadband_bearer_icera_report_connection_status (
> -        self,
> -        MM_BROADBAND_BEARER_ICERA_CONNECTION_STATUS_CONNECTION_FAILED);
> +    mm_bearer_report_connection_status (MM_BEARER (self),
> +
>  MM_BEARER_CONNECTION_STATUS_CONNECTION_FAILED);
>  }
>
>  static void
> @@ -699,13 +684,18 @@ ier_query_ready (MMBaseModem *modem,
>
>  static void
>  report_connect_status (MMBroadbandBearerIcera *self,
> -                       MMBroadbandBearerIceraConnectionStatus status)
> +                       MMBearerConnectionStatus status)
>  {
>      Dial3gppContext *ctx;
>
> +    g_assert (status == MM_BEARER_CONNECTION_STATUS_CONNECTED ||
> +              status == MM_BEARER_CONNECTION_STATUS_CONNECTION_FAILED ||
> +              status == MM_BEARER_CONNECTION_STATUS_DISCONNECTED);
> +
>      /* Recover context and remove it from the private info */
>      ctx = self->priv->connect_pending;
>      self->priv->connect_pending = NULL;
> +    g_assert (ctx != NULL);
>
>      /* Cleanup cancellable, timeout and port closed watch, if any */
>      if (self->priv->connect_pending_id) {
> @@ -713,29 +703,19 @@ report_connect_status (MMBroadbandBearerIcera *self,
>          self->priv->connect_pending_id = 0;
>      }
>
> -    if (ctx && self->priv->connect_cancellable_id) {
> +    if (self->priv->connect_cancellable_id) {
>          g_cancellable_disconnect (ctx->cancellable,
>                                    self->priv->connect_cancellable_id);
>          self->priv->connect_cancellable_id = 0;
>      }
>
> -    if (ctx && self->priv->connect_port_closed_id) {
> +    if (self->priv->connect_port_closed_id) {
>          g_signal_handler_disconnect (ctx->primary,
> self->priv->connect_port_closed_id);
>          self->priv->connect_port_closed_id = 0;
>      }
>
> -    switch (status) {
> -    case MM_BROADBAND_BEARER_ICERA_CONNECTION_STATUS_UNKNOWN:
> -        break;
> -
> -    case MM_BROADBAND_BEARER_ICERA_CONNECTION_STATUS_CONNECTED:
> -        if (!ctx)
> -            /* We may get this if the timeout for the connection attempt
> is
> -             * reached before the unsolicited response. We should probably
> -             * keep the CID around to request explicit disconnection in
> this
> -             * case. */
> -            break;
> -
> +    /* Received 'CONNECTED' during a connection attempt? */
> +    if (status == MM_BEARER_CONNECTION_STATUS_CONNECTED) {
>          /* If we wanted to get cancelled before, do it now */
>          if (ctx->saved_error) {
>              /* Keep error */
> @@ -751,20 +731,19 @@ report_connect_status (MMBroadbandBearerIcera *self,
>
> (GDestroyNotify)g_object_unref);
>          dial_3gpp_context_complete_and_free (ctx);
>          return;
> +    }
>
> -    case MM_BROADBAND_BEARER_ICERA_CONNECTION_STATUS_CONNECTION_FAILED:
> -        if (!ctx)
> -            break;
> -
> -        /* If we wanted to get cancelled before and now we couldn't
> connect,
> -         * use the cancelled error and return */
> -        if (ctx->saved_error) {
> -            g_simple_async_result_take_error (ctx->result,
> ctx->saved_error);
> -            ctx->saved_error = NULL;
> -            dial_3gpp_context_complete_and_free (ctx);
> -            return;
> -        }
> +    /* If we wanted to get cancelled before and now we couldn't connect,
> +     * use the cancelled error and return */
> +    if (ctx->saved_error) {
> +        g_simple_async_result_take_error (ctx->result, ctx->saved_error);
> +        ctx->saved_error = NULL;
> +        dial_3gpp_context_complete_and_free (ctx);
> +        return;
> +    }
>
> +    /* Received CONNECTION_FAILED during a connection attempt? */
> +    if (status == MM_BEARER_CONNECTION_STATUS_CONNECTION_FAILED) {
>          /* Try to gather additional info about the connection failure */
>          mm_base_modem_at_command_full (
>              ctx->modem,
> @@ -777,32 +756,14 @@ report_connect_status (MMBroadbandBearerIcera *self,
>              (GAsyncReadyCallback)ier_query_ready,
>              ctx);
>          return;
> -
> -    case MM_BROADBAND_BEARER_ICERA_CONNECTION_STATUS_DISCONNECTED:
> -        if (ctx) {
> -            /* If we wanted to get cancelled before and now we couldn't
> connect,
> -             * use the cancelled error and return */
> -            if (ctx->saved_error) {
> -                g_simple_async_result_take_error (ctx->result,
> ctx->saved_error);
> -                ctx->saved_error = NULL;
> -                dial_3gpp_context_complete_and_free (ctx);
> -                return;
> -            }
> -
> -            g_simple_async_result_set_error (ctx->result,
> -                                             MM_CORE_ERROR,
> -                                             MM_CORE_ERROR_FAILED,
> -                                             "Call setup failed");
> -            dial_3gpp_context_complete_and_free (ctx);
> -            return;
> -        }
> -
> -        /* Just ensure we mark ourselves as being disconnected... */
> -        mm_bearer_report_disconnection (MM_BEARER (self));
> -        return;
>      }
>
> -    g_warn_if_reached ();
> +    /* Otherwise, received 'DISCONNECTED' during a connection attempt? */
> +    g_simple_async_result_set_error (ctx->result,
> +                                     MM_CORE_ERROR,
> +                                     MM_CORE_ERROR_FAILED,
> +                                     "Call setup failed");
> +    dial_3gpp_context_complete_and_free (ctx);
>  }
>
>  static void
> @@ -1060,15 +1021,36 @@ dial_3gpp (MMBroadbandBearer *self,
>
>
>  /*****************************************************************************/
>
> -void
> -mm_broadband_bearer_icera_report_connection_status
> (MMBroadbandBearerIcera *self,
> -
>  MMBroadbandBearerIceraConnectionStatus status)
> +static void
> +report_connection_status (MMBearer *bearer,
> +                          MMBearerConnectionStatus status)
>  {
> -    if (self->priv->connect_pending)
> +    MMBroadbandBearerIcera *self = MM_BROADBAND_BEARER_ICERA (bearer);
> +
> +    /* Process pending connection attempt */
> +    if (self->priv->connect_pending) {
>          report_connect_status (self, status);
> +        return;
> +    }
>
> -    if (self->priv->disconnect_pending)
> +    /* Process pending disconnection attempt */
> +    if (self->priv->disconnect_pending) {
>          report_disconnect_status (self, status);
> +        return;
> +    }
> +
> +    mm_dbg ("Received spontaneous %%IPDPACT (%s)",
> +            mm_bearer_connection_status_get_string (status));
> +
> +    /* Received a random 'DISCONNECTED'...*/
> +    if (status == MM_BEARER_CONNECTION_STATUS_DISCONNECTED ||
> +        status == MM_BEARER_CONNECTION_STATUS_CONNECTION_FAILED) {
> +        /* If no connection/disconnection attempt on-going, make sure we
> mark ourselves as
> +         * disconnected. Make sure we only pass 'DISCONNECTED' to the
> parent */
> +        MM_BEARER_CLASS
> (mm_broadband_bearer_icera_parent_class)->report_connection_status (
> +            bearer,
> +            MM_BEARER_CONNECTION_STATUS_DISCONNECTED);
> +    }
>  }
>
>
>  /*****************************************************************************/
> @@ -1165,12 +1147,14 @@ static void
>  mm_broadband_bearer_icera_class_init (MMBroadbandBearerIceraClass *klass)
>  {
>      GObjectClass *object_class = G_OBJECT_CLASS (klass);
> +    MMBearerClass *bearer_class = MM_BEARER_CLASS (klass);
>      MMBroadbandBearerClass *broadband_bearer_class =
> MM_BROADBAND_BEARER_CLASS (klass);
>
>      g_type_class_add_private (object_class, sizeof
> (MMBroadbandBearerIceraPrivate));
>
>      object_class->get_property = get_property;
>      object_class->set_property = set_property;
> +    bearer_class->report_connection_status = report_connection_status;
>      broadband_bearer_class->dial_3gpp = dial_3gpp;
>      broadband_bearer_class->dial_3gpp_finish = dial_3gpp_finish;
>      broadband_bearer_class->get_ip_config_3gpp = get_ip_config_3gpp;
> diff --git a/plugins/icera/mm-broadband-bearer-icera.h
> b/plugins/icera/mm-broadband-bearer-icera.h
> index 4edd189..f513659 100644
> --- a/plugins/icera/mm-broadband-bearer-icera.h
> +++ b/plugins/icera/mm-broadband-bearer-icera.h
> @@ -36,13 +36,6 @@
>
>  #define MM_BROADBAND_BEARER_ICERA_DEFAULT_IP_METHOD
> "broadband-bearer-icera-default-ip-method"
>
> -typedef enum {
> -    MM_BROADBAND_BEARER_ICERA_CONNECTION_STATUS_UNKNOWN,
> -    MM_BROADBAND_BEARER_ICERA_CONNECTION_STATUS_CONNECTED,
> -    MM_BROADBAND_BEARER_ICERA_CONNECTION_STATUS_CONNECTION_FAILED,
> -    MM_BROADBAND_BEARER_ICERA_CONNECTION_STATUS_DISCONNECTED
> -} MMBroadbandBearerIceraConnectionStatus;
> -
>  typedef struct _MMBroadbandBearerIcera MMBroadbandBearerIcera;
>  typedef struct _MMBroadbandBearerIceraClass MMBroadbandBearerIceraClass;
>  typedef struct _MMBroadbandBearerIceraPrivate
> MMBroadbandBearerIceraPrivate;
> @@ -68,7 +61,4 @@ void      mm_broadband_bearer_icera_new
>  (MMBroadbandModem *modem,
>  MMBearer *mm_broadband_bearer_icera_new_finish (GAsyncResult *res,
>                                                  GError **error);
>
> -void mm_broadband_bearer_icera_report_connection_status
> (MMBroadbandBearerIcera *self,
> -
> MMBroadbandBearerIceraConnectionStatus status);
> -
>  #endif /* MM_BROADBAND_BEARER_ICERA_H */
> diff --git a/plugins/icera/mm-broadband-modem-icera.c
> b/plugins/icera/mm-broadband-modem-icera.c
> index b84cd12..bf3d18b 100644
> --- a/plugins/icera/mm-broadband-modem-icera.c
> +++ b/plugins/icera/mm-broadband-modem-icera.c
> @@ -397,7 +397,7 @@ modem_set_current_modes (MMIfaceModem *self,
>
>  typedef struct {
>      guint cid;
> -    MMBroadbandBearerIceraConnectionStatus status;
> +    MMBearerConnectionStatus status;
>  } BearerListReportStatusForeachContext;
>
>  static void
> @@ -410,8 +410,7 @@ bearer_list_report_status_foreach (MMBearer *bearer,
>      if (!MM_IS_BROADBAND_BEARER_ICERA (bearer))
>          return;
>
> -    mm_broadband_bearer_icera_report_connection_status
> (MM_BROADBAND_BEARER_ICERA (bearer),
> -                                                        ctx->status);
> +    mm_bearer_report_connection_status (bearer, ctx->status);
>  }
>
>  static void
> @@ -431,20 +430,20 @@ ipdpact_received (MMAtSerialPort *port,
>
>      /* Setup context */
>      ctx.cid = cid;
> -    ctx.status = MM_BROADBAND_BEARER_ICERA_CONNECTION_STATUS_UNKNOWN;
> +    ctx.status = MM_BEARER_CONNECTION_STATUS_UNKNOWN;
>
>      switch (status) {
>      case 0:
> -        ctx.status =
> MM_BROADBAND_BEARER_ICERA_CONNECTION_STATUS_DISCONNECTED;
> +        ctx.status = MM_BEARER_CONNECTION_STATUS_DISCONNECTED;
>          break;
>      case 1:
> -        ctx.status =
> MM_BROADBAND_BEARER_ICERA_CONNECTION_STATUS_CONNECTED;
> +        ctx.status = MM_BEARER_CONNECTION_STATUS_CONNECTED;
>          break;
>      case 2:
>          /* activating */
>          break;
>      case 3:
> -        ctx.status =
> MM_BROADBAND_BEARER_ICERA_CONNECTION_STATUS_CONNECTION_FAILED;
> +        ctx.status = MM_BEARER_CONNECTION_STATUS_CONNECTION_FAILED;
>          break;
>      default:
>          mm_warn ("Unknown Icera connect status %d", status);
> @@ -452,7 +451,7 @@ ipdpact_received (MMAtSerialPort *port,
>      }
>
>      /* If unknown status, don't try to report anything */
> -    if (ctx.status == MM_BROADBAND_BEARER_ICERA_CONNECTION_STATUS_UNKNOWN)
> +    if (ctx.status == MM_BEARER_CONNECTION_STATUS_UNKNOWN)
>          return;
>
>      /* If empty bearer list, nothing else to do */
> diff --git a/plugins/mbm/mm-broadband-bearer-mbm.c
> b/plugins/mbm/mm-broadband-bearer-mbm.c
> index e4f9983..c7495ce 100644
> --- a/plugins/mbm/mm-broadband-bearer-mbm.c
> +++ b/plugins/mbm/mm-broadband-bearer-mbm.c
> @@ -39,6 +39,7 @@
>  #include "mm-broadband-bearer-mbm.h"
>  #include "mm-log.h"
>  #include "mm-modem-helpers.h"
> +#include "mm-daemon-enums-types.h"
>
>  G_DEFINE_TYPE (MMBroadbandBearerMbm, mm_broadband_bearer_mbm,
> MM_TYPE_BROADBAND_BEARER);
>
> @@ -114,55 +115,63 @@ dial_3gpp_finish (MMBroadbandBearer *self,
>      return MM_PORT (g_object_ref
> (g_simple_async_result_get_op_res_gpointer (G_SIMPLE_ASYNC_RESULT (res))));
>  }
>
> -void
> -mm_broadband_bearer_mbm_report_connection_status (MMBroadbandBearerMbm
> *self,
> -
>  MMBroadbandBearerMbmConnectionStatus status)
> +static void
> +report_connection_status (MMBearer *bearer,
> +                          MMBearerConnectionStatus status)
>  {
> +    MMBroadbandBearerMbm *self = MM_BROADBAND_BEARER_MBM (bearer);
>      Dial3gppContext *ctx;
>
> +    g_assert (status == MM_BEARER_CONNECTION_STATUS_CONNECTED ||
> +              status == MM_BEARER_CONNECTION_STATUS_DISCONNECTED);
> +
>      /* Recover context (if any) and remove both cancellation and timeout
> (if any)*/
>      ctx = self->priv->connect_pending;
>      self->priv->connect_pending = NULL;
>
> +    /* Connection status reported but no connection attempt? */
> +    if (!ctx) {
> +        g_assert (self->priv->connect_pending_id == 0);
> +
> +        mm_dbg ("Received spontaneous *E2NAP (%s)",
> +                mm_bearer_connection_status_get_string (status));
> +
> +        if (status == MM_BEARER_CONNECTION_STATUS_DISCONNECTED) {
> +            /* If no connection attempt on-going, make sure we mark
> ourselves as
> +             * disconnected */
> +            MM_BEARER_CLASS
> (mm_broadband_bearer_mbm_parent_class)->report_connection_status (
> +                bearer,
> +                status);
> +        }
> +        return;
> +    }
> +
>      if (self->priv->connect_pending_id) {
>          g_source_remove (self->priv->connect_pending_id);
>          self->priv->connect_pending_id = 0;
>      }
>
> -    if (ctx && self->priv->connect_cancellable_id) {
> +    if (self->priv->connect_cancellable_id) {
>          g_cancellable_disconnect (ctx->cancellable,
>                                    self->priv->connect_cancellable_id);
>          self->priv->connect_cancellable_id = 0;
>      }
>
> -    switch (status) {
> -    case MM_BROADBAND_BEARER_MBM_CONNECTION_STATUS_UNKNOWN:
> -        g_warn_if_reached ();
> -        break;
> -
> -    case MM_BROADBAND_BEARER_MBM_CONNECTION_STATUS_CONNECTED:
> -        if (!ctx)
> -            break;
> -
> +    /* Reporting connected */
> +    if (status == MM_BEARER_CONNECTION_STATUS_CONNECTED) {
>          g_simple_async_result_set_op_res_gpointer (ctx->result,
>                                                     g_object_ref
> (ctx->data),
>
> (GDestroyNotify)g_object_unref);
>          dial_3gpp_context_complete_and_free (ctx);
>          return;
> -
> -    case MM_BROADBAND_BEARER_MBM_CONNECTION_STATUS_DISCONNECTED:
> -        if (ctx) {
> -            g_simple_async_result_set_error (ctx->result,
> -                                             MM_CORE_ERROR,
> -                                             MM_CORE_ERROR_FAILED,
> -                                             "Call setup failed");
> -            dial_3gpp_context_complete_and_free (ctx);
> -        } else {
> -            /* Just ensure we mark ourselves as being disconnected... */
> -            mm_bearer_report_disconnection (MM_BEARER (self));
> -        }
> -        break;
>      }
> +
> +    /* Reporting disconnected */
> +    g_simple_async_result_set_error (ctx->result,
> +                                     MM_CORE_ERROR,
> +                                     MM_CORE_ERROR_FAILED,
> +                                     "Call setup failed");
> +    dial_3gpp_context_complete_and_free (ctx);
>  }
>
>  static void
> @@ -591,10 +600,12 @@ mm_broadband_bearer_mbm_class_init
> (MMBroadbandBearerMbmClass *klass)
>  {
>      GObjectClass *object_class = G_OBJECT_CLASS (klass);
>
> +    MMBearerClass *bearer_class = MM_BEARER_CLASS (klass);
>      MMBroadbandBearerClass *broadband_bearer_class =
> MM_BROADBAND_BEARER_CLASS (klass);
>
>      g_type_class_add_private (object_class, sizeof
> (MMBroadbandBearerMbmPrivate));
>
> +    bearer_class->report_connection_status = report_connection_status;
>      broadband_bearer_class->dial_3gpp = dial_3gpp;
>      broadband_bearer_class->dial_3gpp_finish = dial_3gpp_finish;
>      broadband_bearer_class->disconnect_3gpp = disconnect_3gpp;
> diff --git a/plugins/mbm/mm-broadband-bearer-mbm.h
> b/plugins/mbm/mm-broadband-bearer-mbm.h
> index dcbeeec..a49cce1 100644
> --- a/plugins/mbm/mm-broadband-bearer-mbm.h
> +++ b/plugins/mbm/mm-broadband-bearer-mbm.h
> @@ -41,12 +41,6 @@
>  #define MM_IS_BROADBAND_BEARER_MBM_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE
> ((klass),  MM_TYPE_BROADBAND_BEARER_MBM))
>  #define MM_BROADBAND_BEARER_MBM_GET_CLASS(obj)
>  (G_TYPE_INSTANCE_GET_CLASS ((obj),  MM_TYPE_BROADBAND_BEARER_MBM,
> MMBroadbandBearerMbmClass))
>
> -typedef enum {
> -    MM_BROADBAND_BEARER_MBM_CONNECTION_STATUS_UNKNOWN,
> -    MM_BROADBAND_BEARER_MBM_CONNECTION_STATUS_CONNECTED,
> -    MM_BROADBAND_BEARER_MBM_CONNECTION_STATUS_DISCONNECTED
> -} MMBroadbandBearerMbmConnectionStatus;
> -
>  typedef struct _MMBroadbandBearerMbm MMBroadbandBearerMbm;
>  typedef struct _MMBroadbandBearerMbmClass MMBroadbandBearerMbmClass;
>  typedef struct _MMBroadbandBearerMbmPrivate MMBroadbandBearerMbmPrivate;
> @@ -71,7 +65,4 @@ void mm_broadband_bearer_mbm_new (MMBroadbandModemMbm
> *modem,
>  MMBearer *mm_broadband_bearer_mbm_new_finish (GAsyncResult *res,
>                                                GError **error);
>
> -void mm_broadband_bearer_mbm_report_connection_status
> (MMBroadbandBearerMbm *self,
> -
> MMBroadbandBearerMbmConnectionStatus status);
> -
>  #endif /* MM_BROADBAND_BEARER_MBM_H */
> diff --git a/plugins/mbm/mm-broadband-modem-mbm.c
> b/plugins/mbm/mm-broadband-modem-mbm.c
> index 8380813..5259359 100644
> --- a/plugins/mbm/mm-broadband-modem-mbm.c
> +++ b/plugins/mbm/mm-broadband-modem-mbm.c
> @@ -797,15 +797,14 @@ load_unlock_retries (MMIfaceModem *self,
>  /* Setup/Cleanup unsolicited events (3GPP interface) */
>
>  typedef struct {
> -    MMBroadbandBearerMbmConnectionStatus status;
> +    MMBearerConnectionStatus status;
>  } BearerListReportStatusForeachContext;
>
>  static void
>  bearer_list_report_status_foreach (MMBearer *bearer,
>                                     BearerListReportStatusForeachContext
> *ctx)
>  {
> -    mm_broadband_bearer_mbm_report_connection_status
> (MM_BROADBAND_BEARER_MBM (bearer),
> -                                                      ctx->status);
> +    mm_bearer_report_connection_status (bearer, ctx->status);
>  }
>
>  static void
> @@ -820,16 +819,16 @@ e2nap_received (MMAtSerialPort *port,
>      if (!mm_get_uint_from_match_info (info, 1, &state))
>          return;
>
> -    ctx.status = MM_BROADBAND_BEARER_MBM_CONNECTION_STATUS_UNKNOWN;
> +    ctx.status = MM_BEARER_CONNECTION_STATUS_UNKNOWN;
>
>      switch (state) {
>      case MBM_E2NAP_DISCONNECTED:
>          mm_dbg ("disconnected");
> -        ctx.status =
> MM_BROADBAND_BEARER_MBM_CONNECTION_STATUS_DISCONNECTED;
> +        ctx.status = MM_BEARER_CONNECTION_STATUS_DISCONNECTED;
>          break;
>      case MBM_E2NAP_CONNECTED:
>          mm_dbg ("connected");
> -        ctx.status = MM_BROADBAND_BEARER_MBM_CONNECTION_STATUS_CONNECTED;
> +        ctx.status = MM_BEARER_CONNECTION_STATUS_CONNECTED;
>          break;
>      case MBM_E2NAP_CONNECTING:
>          mm_dbg ("connecting");
> @@ -840,7 +839,7 @@ e2nap_received (MMAtSerialPort *port,
>      }
>
>      /* If unknown status, don't try to report anything */
> -    if (ctx.status == MM_BROADBAND_BEARER_MBM_CONNECTION_STATUS_UNKNOWN)
> +    if (ctx.status == MM_BEARER_CONNECTION_STATUS_UNKNOWN)
>          return;
>
>      /* If empty bearer list, nothing else to do */
> diff --git a/plugins/novatel/mm-broadband-bearer-novatel-lte.c
> b/plugins/novatel/mm-broadband-bearer-novatel-lte.c
> index 4681c6e..2225656 100644
> --- a/plugins/novatel/mm-broadband-bearer-novatel-lte.c
> +++ b/plugins/novatel/mm-broadband-bearer-novatel-lte.c
> @@ -130,7 +130,7 @@ poll_connection_ready (MMBaseModem *modem,
>      }
>
>      if (is_qmistatus_disconnected (result)) {
> -        mm_bearer_report_disconnection (MM_BEARER (bearer));
> +        mm_bearer_report_connection_status (MM_BEARER (bearer),
> MM_BEARER_CONNECTION_STATUS_DISCONNECTED);
>          g_source_remove (bearer->priv->connection_poller);
>          bearer->priv->connection_poller = 0;
>      }
> diff --git a/plugins/option/mm-broadband-bearer-hso.c
> b/plugins/option/mm-broadband-bearer-hso.c
> index 7da13aa..1c81557 100644
> --- a/plugins/option/mm-broadband-bearer-hso.c
> +++ b/plugins/option/mm-broadband-bearer-hso.c
> @@ -32,6 +32,7 @@
>  #include "mm-broadband-bearer-hso.h"
>  #include "mm-log.h"
>  #include "mm-modem-helpers.h"
> +#include "mm-daemon-enums-types.h"
>
>  G_DEFINE_TYPE (MMBroadbandBearerHso, mm_broadband_bearer_hso,
> MM_TYPE_BROADBAND_BEARER);
>
> @@ -314,44 +315,56 @@ connect_reset (Dial3gppContext *ctx)
>      g_free (command);
>  }
>
> -void
> -mm_broadband_bearer_hso_report_connection_status (MMBroadbandBearerHso
> *self,
> -
>  MMBroadbandBearerHsoConnectionStatus status)
> +static void
> +report_connection_status (MMBearer *bearer,
> +                          MMBearerConnectionStatus status)
>  {
> +    MMBroadbandBearerHso *self = MM_BROADBAND_BEARER_HSO (bearer);
>      Dial3gppContext *ctx;
>
> +    g_assert (status == MM_BEARER_CONNECTION_STATUS_CONNECTED ||
> +              status == MM_BEARER_CONNECTION_STATUS_CONNECTION_FAILED ||
> +              status == MM_BEARER_CONNECTION_STATUS_DISCONNECTED);
> +
>      /* Recover context (if any) and remove both cancellation and timeout
> (if any)*/
>      ctx = self->priv->connect_pending;
>      self->priv->connect_pending = NULL;
>
> +    /* Connection status reported but no connection attempt? */
> +    if (!ctx) {
> +        g_assert (self->priv->connect_pending_id == 0);
> +
> +        mm_dbg ("Received spontaneous _OWANCALL (%s)",
> +                mm_bearer_connection_status_get_string (status));
> +
> +        if (status == MM_BEARER_CONNECTION_STATUS_DISCONNECTED) {
> +            /* If no connection attempt on-going, make sure we mark
> ourselves as
> +             * disconnected */
> +            MM_BEARER_CLASS
> (mm_broadband_bearer_hso_parent_class)->report_connection_status (
> +                bearer,
> +                status);
> +        }
> +        return;
> +    }
> +
>      if (self->priv->connect_pending_id) {
>          g_source_remove (self->priv->connect_pending_id);
>          self->priv->connect_pending_id = 0;
>      }
>
> -    if (ctx && self->priv->connect_cancellable_id) {
> +    if (self->priv->connect_cancellable_id) {
>          g_cancellable_disconnect (ctx->cancellable,
>                                    self->priv->connect_cancellable_id);
>          self->priv->connect_cancellable_id = 0;
>      }
>
> -    if (ctx && self->priv->connect_port_closed_id) {
> +    if (self->priv->connect_port_closed_id) {
>          g_signal_handler_disconnect (ctx->primary,
> self->priv->connect_port_closed_id);
>          self->priv->connect_port_closed_id = 0;
>      }
>
> -    switch (status) {
> -    case MM_BROADBAND_BEARER_HSO_CONNECTION_STATUS_UNKNOWN:
> -        break;
> -
> -    case MM_BROADBAND_BEARER_HSO_CONNECTION_STATUS_CONNECTED:
> -        if (!ctx)
> -            /* We may get this if the timeout for the connection attempt
> is
> -             * reached before the unsolicited response. We should probably
> -             * keep the CID around to request explicit disconnection in
> this
> -             * case. */
> -            break;
> -
> +    /* Reporting connected */
> +    if (status == MM_BEARER_CONNECTION_STATUS_CONNECTED) {
>          /* If we wanted to get cancelled before, do it now */
>          if (ctx->saved_error) {
>              /* Keep error */
> @@ -367,52 +380,23 @@ mm_broadband_bearer_hso_report_connection_status
> (MMBroadbandBearerHso *self,
>
> (GDestroyNotify)g_object_unref);
>          dial_3gpp_context_complete_and_free (ctx);
>          return;
> +    }
>
> -    case MM_BROADBAND_BEARER_HSO_CONNECTION_STATUS_CONNECTION_FAILED:
> -        if (!ctx)
> -            break;
> -
> -        /* If we wanted to get cancelled before and now we couldn't
> connect,
> -         * use the cancelled error and return */
> -        if (ctx->saved_error) {
> -            g_simple_async_result_take_error (ctx->result,
> ctx->saved_error);
> -            ctx->saved_error = NULL;
> -            dial_3gpp_context_complete_and_free (ctx);
> -            return;
> -        }
> -
> -        g_simple_async_result_set_error (ctx->result,
> -                                         MM_CORE_ERROR,
> -                                         MM_CORE_ERROR_FAILED,
> -                                         "Call setup failed");
> +    /* If we wanted to get cancelled before and now we couldn't connect,
> +     * use the cancelled error and return */
> +    if (ctx->saved_error) {
> +        g_simple_async_result_take_error (ctx->result, ctx->saved_error);
> +        ctx->saved_error = NULL;
>          dial_3gpp_context_complete_and_free (ctx);
>          return;
> -
> -    case MM_BROADBAND_BEARER_HSO_CONNECTION_STATUS_DISCONNECTED:
> -        if (ctx) {
> -            /* If we wanted to get cancelled before and now we couldn't
> connect,
> -             * use the cancelled error and return */
> -            if (ctx->saved_error) {
> -                g_simple_async_result_take_error (ctx->result,
> ctx->saved_error);
> -                ctx->saved_error = NULL;
> -                dial_3gpp_context_complete_and_free (ctx);
> -                return;
> -            }
> -
> -            g_simple_async_result_set_error (ctx->result,
> -                                             MM_CORE_ERROR,
> -                                             MM_CORE_ERROR_FAILED,
> -                                             "Call setup failed");
> -            dial_3gpp_context_complete_and_free (ctx);
> -            return;
> -        }
> -
> -        /* Just ensure we mark ourselves as being disconnected... */
> -        mm_bearer_report_disconnection (MM_BEARER (self));
> -        return;
>      }
>
> -    g_warn_if_reached ();
> +    /* Received CONNECTION_FAILED or DISCONNECTED during a connection
> attempt? */
> +    g_simple_async_result_set_error (ctx->result,
> +                                     MM_CORE_ERROR,
> +                                     MM_CORE_ERROR_FAILED,
> +                                     "Call setup failed");
> +    dial_3gpp_context_complete_and_free (ctx);
>  }
>
>  static gboolean
> @@ -482,9 +466,8 @@ forced_close_cb (MMSerialPort *port,
>                   MMBroadbandBearerHso *self)
>  {
>      /* Just treat the forced close event as any other unsolicited message
> */
> -    mm_broadband_bearer_hso_report_connection_status (
> -        self,
> -        MM_BROADBAND_BEARER_HSO_CONNECTION_STATUS_CONNECTION_FAILED);
> +    mm_bearer_report_connection_status (MM_BEARER (self),
> +
>  MM_BEARER_CONNECTION_STATUS_CONNECTION_FAILED);
>  }
>
>  static void
> @@ -854,10 +837,12 @@ static void
>  mm_broadband_bearer_hso_class_init (MMBroadbandBearerHsoClass *klass)
>  {
>      GObjectClass *object_class = G_OBJECT_CLASS (klass);
> +    MMBearerClass *bearer_class = MM_BEARER_CLASS (klass);
>      MMBroadbandBearerClass *broadband_bearer_class =
> MM_BROADBAND_BEARER_CLASS (klass);
>
>      g_type_class_add_private (object_class, sizeof
> (MMBroadbandBearerHsoPrivate));
>
> +    bearer_class->report_connection_status = report_connection_status;
>      broadband_bearer_class->dial_3gpp = dial_3gpp;
>      broadband_bearer_class->dial_3gpp_finish = dial_3gpp_finish;
>      broadband_bearer_class->get_ip_config_3gpp = get_ip_config_3gpp;
> diff --git a/plugins/option/mm-broadband-bearer-hso.h
> b/plugins/option/mm-broadband-bearer-hso.h
> index 584fc03..20b89db 100644
> --- a/plugins/option/mm-broadband-bearer-hso.h
> +++ b/plugins/option/mm-broadband-bearer-hso.h
> @@ -32,13 +32,6 @@
>  #define MM_IS_BROADBAND_BEARER_HSO_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE
> ((klass),  MM_TYPE_BROADBAND_BEARER_HSO))
>  #define MM_BROADBAND_BEARER_HSO_GET_CLASS(obj)
>  (G_TYPE_INSTANCE_GET_CLASS ((obj),  MM_TYPE_BROADBAND_BEARER_HSO,
> MMBroadbandBearerHsoClass))
>
> -typedef enum {
> -    MM_BROADBAND_BEARER_HSO_CONNECTION_STATUS_UNKNOWN,
> -    MM_BROADBAND_BEARER_HSO_CONNECTION_STATUS_CONNECTED,
> -    MM_BROADBAND_BEARER_HSO_CONNECTION_STATUS_CONNECTION_FAILED,
> -    MM_BROADBAND_BEARER_HSO_CONNECTION_STATUS_DISCONNECTED
> -} MMBroadbandBearerHsoConnectionStatus;
> -
>  typedef struct _MMBroadbandBearerHso MMBroadbandBearerHso;
>  typedef struct _MMBroadbandBearerHsoClass MMBroadbandBearerHsoClass;
>  typedef struct _MMBroadbandBearerHsoPrivate MMBroadbandBearerHsoPrivate;
> @@ -63,7 +56,4 @@ void mm_broadband_bearer_hso_new (MMBroadbandModemHso
> *modem,
>  MMBearer *mm_broadband_bearer_hso_new_finish (GAsyncResult *res,
>                                                GError **error);
>
> -void mm_broadband_bearer_hso_report_connection_status
> (MMBroadbandBearerHso *self,
> -
> MMBroadbandBearerHsoConnectionStatus status);
> -
>  #endif /* MM_BROADBAND_BEARER_HSO_H */
> diff --git a/plugins/option/mm-broadband-modem-hso.c
> b/plugins/option/mm-broadband-modem-hso.c
> index 1c69109..ef10174 100644
> --- a/plugins/option/mm-broadband-modem-hso.c
> +++ b/plugins/option/mm-broadband-modem-hso.c
> @@ -216,7 +216,7 @@ load_unlock_retries (MMIfaceModem *self,
>
>  typedef struct {
>      guint cid;
> -    MMBroadbandBearerHsoConnectionStatus status;
> +    MMBearerConnectionStatus status;
>  } BearerListReportStatusForeachContext;
>
>  static void
> @@ -226,8 +226,7 @@ bearer_list_report_status_foreach (MMBearer *bearer,
>      if (mm_broadband_bearer_get_3gpp_cid (MM_BROADBAND_BEARER (bearer))
> != ctx->cid)
>          return;
>
> -    mm_broadband_bearer_hso_report_connection_status
> (MM_BROADBAND_BEARER_HSO (bearer),
> -                                                      ctx->status);
> +    mm_bearer_report_connection_status (MM_BEARER (bearer), ctx->status);
>  }
>
>  static void
> @@ -247,24 +246,24 @@ hso_connection_status_changed (MMAtSerialPort *port,
>
>      /* Setup context */
>      ctx.cid = cid;
> -    ctx.status = MM_BROADBAND_BEARER_HSO_CONNECTION_STATUS_UNKNOWN;
> +    ctx.status = MM_BEARER_CONNECTION_STATUS_UNKNOWN;
>
>      switch (status) {
>      case 1:
> -        ctx.status = MM_BROADBAND_BEARER_HSO_CONNECTION_STATUS_CONNECTED;
> +        ctx.status = MM_BEARER_CONNECTION_STATUS_CONNECTED;
>          break;
>      case 3:
> -        ctx.status =
> MM_BROADBAND_BEARER_HSO_CONNECTION_STATUS_CONNECTION_FAILED;
> +        ctx.status = MM_BEARER_CONNECTION_STATUS_CONNECTION_FAILED;
>          break;
>      case 0:
> -        ctx.status =
> MM_BROADBAND_BEARER_HSO_CONNECTION_STATUS_DISCONNECTED;
> +        ctx.status = MM_BEARER_CONNECTION_STATUS_DISCONNECTED;
>          break;
>      default:
>          break;
>      }
>
>      /* If unknown status, don't try to report anything */
> -    if (ctx.status == MM_BROADBAND_BEARER_HSO_CONNECTION_STATUS_UNKNOWN)
> +    if (ctx.status == MM_BEARER_CONNECTION_STATUS_UNKNOWN)
>          return;
>
>      /* If empty bearer list, nothing else to do */
> diff --git a/src/mm-bearer-qmi.c b/src/mm-bearer-qmi.c
> index 00d17c5..fef5881 100644
> --- a/src/mm-bearer-qmi.c
> +++ b/src/mm-bearer-qmi.c
> @@ -1186,13 +1186,15 @@ disconnect (MMBearer *_self,
>
>  /*****************************************************************************/
>
>  static void
> -report_disconnection (MMBearer *self)
> +report_connection_status (MMBearer *self,
> +                          MMBearerConnectionStatus status)
>  {
> -    /* Cleanup all connection related data */
> -    reset_bearer_connection (MM_BEARER_QMI (self), TRUE, TRUE);
> +    if (status == MM_BEARER_CONNECTION_STATUS_DISCONNECTED)
> +        /* Cleanup all connection related data */
> +        reset_bearer_connection (MM_BEARER_QMI (self), TRUE, TRUE);
>
> -    /* Chain up parent's report_disconection() */
> -    MM_BEARER_CLASS (mm_bearer_qmi_parent_class)->report_disconnection
> (self);
> +    /* Chain up parent's report_connection_status() */
> +    MM_BEARER_CLASS
> (mm_bearer_qmi_parent_class)->report_connection_status (self, status);
>  }
>
>
>  /*****************************************************************************/
> @@ -1253,5 +1255,5 @@ mm_bearer_qmi_class_init (MMBearerQmiClass *klass)
>      bearer_class->connect_finish = connect_finish;
>      bearer_class->disconnect = disconnect;
>      bearer_class->disconnect_finish = disconnect_finish;
> -    bearer_class->report_disconnection = report_disconnection;
> +    bearer_class->report_connection_status = report_connection_status;
>  }
> diff --git a/src/mm-bearer.c b/src/mm-bearer.c
> index 8c9a93c..f57ea8b 100644
> --- a/src/mm-bearer.c
> +++ b/src/mm-bearer.c
> @@ -974,17 +974,25 @@ mm_bearer_disconnect_force (MMBearer *self)
>
>  /*****************************************************************************/
>
>  static void
> -report_disconnection (MMBearer *self)
> +report_connection_status (MMBearer *self,
> +                          MMBearerConnectionStatus status)
>  {
> +    /* The only status expected at this point is DISCONNECTED.
> +     * No other status should have been given to the generic
> implementation
> +     * of report_connection_status (it would be an error).
> +     */
> +    g_assert (status == MM_BEARER_CONNECTION_STATUS_DISCONNECTED);
> +
>      /* In the generic bearer implementation we just need to reset the
>       * interface status */
>      bearer_update_status (self, MM_BEARER_STATUS_DISCONNECTED);
>  }
>
>  void
> -mm_bearer_report_disconnection (MMBearer *self)
> +mm_bearer_report_connection_status (MMBearer *self,
> +                                    MMBearerConnectionStatus status)
>  {
> -    return MM_BEARER_GET_CLASS (self)->report_disconnection (self);
> +    return MM_BEARER_GET_CLASS (self)->report_connection_status (self,
> status);
>  }
>
>  static void
> @@ -1160,7 +1168,7 @@ mm_bearer_class_init (MMBearerClass *klass)
>      object_class->finalize = finalize;
>      object_class->dispose = dispose;
>
> -    klass->report_disconnection = report_disconnection;
> +    klass->report_connection_status = report_connection_status;
>
>      properties[PROP_CONNECTION] =
>          g_param_spec_object (MM_BEARER_CONNECTION,
> diff --git a/src/mm-bearer.h b/src/mm-bearer.h
> index cc71bfd..dc217c5 100644
> --- a/src/mm-bearer.h
> +++ b/src/mm-bearer.h
> @@ -67,6 +67,13 @@ typedef enum { /*< underscore_name=mm_bearer_status >*/
>      MM_BEARER_STATUS_CONNECTED,
>  } MMBearerStatus;
>
> +typedef enum { /*< underscore_name=mm_bearer_connection_status >*/
> +    MM_BEARER_CONNECTION_STATUS_UNKNOWN,
> +    MM_BEARER_CONNECTION_STATUS_DISCONNECTED,
> +    MM_BEARER_CONNECTION_STATUS_CONNECTED,
> +    MM_BEARER_CONNECTION_STATUS_CONNECTION_FAILED,
> +} MMBearerConnectionStatus;
> +
>  struct _MMBearer {
>      MmGdbusBearerSkeleton parent;
>      MMBearerPrivate *priv;
> @@ -92,8 +99,9 @@ struct _MMBearerClass {
>                                      GAsyncResult *res,
>                                      GError **error);
>
> -    /* Report disconnection */
> -    void (* report_disconnection) (MMBearer *bearer);
> +    /* Report connection status of this bearer */
> +    void (* report_connection_status) (MMBearer *bearer,
> +                                       MMBearerConnectionStatus status);
>  };
>
>  GType mm_bearer_get_type (void);
> @@ -123,6 +131,7 @@ gboolean mm_bearer_disconnect_finish (MMBearer *self,
>
>  void mm_bearer_disconnect_force (MMBearer *self);
>
> -void mm_bearer_report_disconnection (MMBearer *self);
> +void mm_bearer_report_connection_status (MMBearer *self,
> +                                         MMBearerConnectionStatus status);
>
>  #endif /* MM_BEARER_H */
> diff --git a/src/mm-broadband-bearer.c b/src/mm-broadband-bearer.c
> index f8f449d..33b4ca7 100644
> --- a/src/mm-broadband-bearer.c
> +++ b/src/mm-broadband-bearer.c
> @@ -1785,13 +1785,17 @@ disconnect (MMBearer *self,
>
>  /*****************************************************************************/
>
>  static void
> -report_disconnection (MMBearer *self)
> +report_connection_status (MMBearer *self,
> +                          MMBearerConnectionStatus status)
>  {
> -    /* Cleanup all connection related data */
> -    reset_bearer_connection (MM_BROADBAND_BEARER (self));
> +    if (status == MM_BEARER_CONNECTION_STATUS_DISCONNECTED)
> +        /* Cleanup all connection related data */
> +        reset_bearer_connection (MM_BROADBAND_BEARER (self));
>
> -    /* Chain up parent's report_disconection() */
> -    MM_BEARER_CLASS
> (mm_broadband_bearer_parent_class)->report_disconnection (self);
> +    /* Chain up parent's report_connection_status() */
> +    MM_BEARER_CLASS
> (mm_broadband_bearer_parent_class)->report_connection_status (
> +        self,
> +        status);
>  }
>
>
>  /*****************************************************************************/
> @@ -2052,7 +2056,7 @@ mm_broadband_bearer_class_init
> (MMBroadbandBearerClass *klass)
>      bearer_class->connect_finish = connect_finish;
>      bearer_class->disconnect = disconnect;
>      bearer_class->disconnect_finish = disconnect_finish;
> -    bearer_class->report_disconnection = report_disconnection;
> +    bearer_class->report_connection_status = report_connection_status;
>
>      klass->connect_3gpp = connect_3gpp;
>      klass->connect_3gpp_finish = detailed_connect_finish;
> --
> 1.8.3.1
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.freedesktop.org/archives/modemmanager-devel/attachments/20130920/8dcaccf4/attachment-0001.html>


More information about the ModemManager-devel mailing list