<div dir="ltr">@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.<div><br></div><div>

I verified basic functionality of the icera plugin.</div><div><br></div><div>Thanks,</div><div>Prathmesh</div></div><div class="gmail_extra"><br><br><div class="gmail_quote">On Fri, Sep 20, 2013 at 10:29 AM, Aleksander Morgado <span dir="ltr"><<a href="mailto:aleksander@lanedo.com" target="_blank">aleksander@lanedo.com</a>></span> wrote:<br>

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