diff options
-rw-r--r-- | plugins/altair/mm-broadband-modem-altair-lte.c | 3 | ||||
-rw-r--r-- | plugins/huawei/mm-broadband-bearer-huawei.c | 30 | ||||
-rw-r--r-- | plugins/huawei/mm-broadband-bearer-huawei.h | 3 | ||||
-rw-r--r-- | plugins/huawei/mm-broadband-modem-huawei.c | 6 | ||||
-rw-r--r-- | plugins/icera/mm-broadband-bearer-icera.c | 154 | ||||
-rw-r--r-- | plugins/icera/mm-broadband-bearer-icera.h | 10 | ||||
-rw-r--r-- | plugins/icera/mm-broadband-modem-icera.c | 15 | ||||
-rw-r--r-- | plugins/mbm/mm-broadband-bearer-mbm.c | 63 | ||||
-rw-r--r-- | plugins/mbm/mm-broadband-bearer-mbm.h | 9 | ||||
-rw-r--r-- | plugins/mbm/mm-broadband-modem-mbm.c | 13 | ||||
-rw-r--r-- | plugins/novatel/mm-broadband-bearer-novatel-lte.c | 2 | ||||
-rw-r--r-- | plugins/option/mm-broadband-bearer-hso.c | 107 | ||||
-rw-r--r-- | plugins/option/mm-broadband-bearer-hso.h | 10 | ||||
-rw-r--r-- | plugins/option/mm-broadband-modem-hso.c | 15 | ||||
-rw-r--r-- | src/mm-bearer-qmi.c | 14 | ||||
-rw-r--r-- | src/mm-bearer.c | 16 | ||||
-rw-r--r-- | src/mm-bearer.h | 15 | ||||
-rw-r--r-- | 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 4fceff87..3303cbb5 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 233102f0..2d8f0cdd 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 3eb0efd6..4c87d9cc 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 66ec62de..f93f5a1c 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 b7ea8df0..48a2a798 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 4edd1896..f513659c 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 b84cd122..bf3d18bc 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 e4f9983c..c7495ce4 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 dcbeeecf..a49cce1e 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 8380813e..5259359a 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 4681c6e5..22256562 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 7da13aa9..1c815577 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 584fc03d..20b89db7 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 1c691095..ef101749 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 00d17c59..fef58819 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 8c9a93c8..f57ea8be 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 cc71bfd1..dc217c50 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 f8f449d0..33b4ca73 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; |