aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/mm-base-bearer.c198
1 files changed, 109 insertions, 89 deletions
diff --git a/src/mm-base-bearer.c b/src/mm-base-bearer.c
index 344a5e78..cd6365ac 100644
--- a/src/mm-base-bearer.c
+++ b/src/mm-base-bearer.c
@@ -390,25 +390,6 @@ bearer_stats_stop (MMBaseBearer *self)
}
static void
-reload_stats_supported_ready (MMBaseBearer *self,
- GAsyncResult *res)
-{
- GError *error = NULL;
- guint64 rx_bytes = 0;
- guint64 tx_bytes = 0;
-
- MM_BASE_BEARER_GET_CLASS (self)->reload_stats_finish (self, &rx_bytes, &tx_bytes, res, &error);
- if (!error) {
- mm_obj_info (self, "reloading stats is supported by the device");
- self->priv->reload_stats_supported = TRUE;
- mm_gdbus_bearer_set_reload_stats_supported (MM_GDBUS_BEARER (self), self->priv->reload_stats_supported);
- } else {
- mm_obj_info (self, "reloading stats is not supported by the device");
- g_clear_error (&error);
- }
-}
-
-static void
reload_stats_ready (MMBaseBearer *self,
GAsyncResult *res)
{
@@ -589,15 +570,6 @@ bearer_update_status_connected (MMBaseBearer *self,
self->priv->status = MM_BEARER_STATUS_CONNECTED;
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_STATUS]);
- /* Check that reload statistics is supported by the device */
- if (MM_BASE_BEARER_GET_CLASS (self)->reload_stats &&
- MM_BASE_BEARER_GET_CLASS (self)->reload_stats_finish) {
- MM_BASE_BEARER_GET_CLASS (self)->reload_stats (
- self,
- (GAsyncReadyCallback)reload_stats_supported_ready,
- NULL);
- }
-
/* Start statistics */
bearer_stats_start (self, uplink_speed, downlink_speed);
@@ -864,23 +836,46 @@ reset_signal_handlers (MMBaseBearer *self)
/* CONNECT */
gboolean
-mm_base_bearer_connect_finish (MMBaseBearer *self,
- GAsyncResult *res,
- GError **error)
+mm_base_bearer_connect_finish (MMBaseBearer *self,
+ GAsyncResult *res,
+ GError **error)
{
return g_task_propagate_boolean (G_TASK (res), error);
}
static void
+connect_succeeded (MMBaseBearer *self,
+ GTask *task)
+{
+ MMBearerConnectResult *result;
+
+ result = g_task_get_task_data (task);
+
+ /* Update bearer and interface status */
+ bearer_update_status_connected (
+ self,
+ mm_port_get_device (mm_bearer_connect_result_peek_data (result)),
+ mm_bearer_connect_result_get_multiplexed (result),
+ mm_bearer_connect_result_get_profile_id (result),
+ mm_bearer_connect_result_peek_ipv4_config (result),
+ mm_bearer_connect_result_peek_ipv6_config (result),
+ mm_bearer_connect_result_get_uplink_speed (result),
+ mm_bearer_connect_result_get_downlink_speed (result));
+
+ g_clear_object (&self->priv->connect_cancellable);
+
+ g_task_return_boolean (task, TRUE);
+ g_object_unref (task);
+}
+
+static void
disconnect_after_cancel_ready (MMBaseBearer *self,
GAsyncResult *res)
{
- GError *error = NULL;
+ g_autoptr(GError) error = NULL;
- if (!MM_BASE_BEARER_GET_CLASS (self)->disconnect_finish (self, res, &error)) {
+ if (!MM_BASE_BEARER_GET_CLASS (self)->disconnect_finish (self, res, &error))
mm_obj_warn (self, "error disconnecting: %s; will assume disconnected anyway", error->message);
- g_error_free (error);
- }
else
mm_obj_dbg (self, "disconnected bearer '%s'", self->priv->path);
@@ -893,13 +888,72 @@ disconnect_after_cancel_ready (MMBaseBearer *self,
}
static void
+connect_failed (MMBaseBearer *self,
+ GTask *task,
+ GError *error)
+{
+ /* Update failed attempts */
+ mm_bearer_stats_set_failed_attempts (self->priv->stats,
+ mm_bearer_stats_get_failed_attempts (self->priv->stats) + 1);
+ bearer_update_interface_stats (self);
+
+ /* Update reported connection error before the status update */
+ bearer_update_connection_error (self, error);
+ if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) {
+ bearer_update_status (self, MM_BEARER_STATUS_DISCONNECTING);
+ MM_BASE_BEARER_GET_CLASS (self)->disconnect (self,
+ (GAsyncReadyCallback)disconnect_after_cancel_ready,
+ NULL);
+ } else
+ bearer_update_status (self, MM_BEARER_STATUS_DISCONNECTED);
+
+ g_clear_object (&self->priv->connect_cancellable);
+
+ g_task_return_error (task, error);
+ g_object_unref (task);
+}
+
+static gboolean
+connect_check_cancel (MMBaseBearer *self,
+ GTask *task)
+{
+ GError *error = NULL;
+
+ if (!g_cancellable_is_cancelled (self->priv->connect_cancellable))
+ return FALSE;
+
+ mm_obj_dbg (self, "connected, but need to disconnect");
+ error = g_error_new (G_IO_ERROR, G_IO_ERROR_CANCELLED,
+ "Bearer got connected, but had to disconnect after cancellation request");
+ connect_failed (self, task, error);
+ return TRUE;
+}
+
+static void
+reload_stats_supported_ready (MMBaseBearer *self,
+ GAsyncResult *res,
+ GTask *task)
+{
+ if (MM_BASE_BEARER_GET_CLASS (self)->reload_stats_finish (self, NULL, NULL, res, NULL)) {
+ mm_obj_info (self, "reloading stats is supported by the device");
+ self->priv->reload_stats_supported = TRUE;
+ mm_gdbus_bearer_set_reload_stats_supported (MM_GDBUS_BEARER (self), self->priv->reload_stats_supported);
+ } else
+ mm_obj_info (self, "reloading stats is not supported by the device");
+
+ if (connect_check_cancel (self, task))
+ return;
+
+ connect_succeeded (self, task);
+}
+
+static void
connect_ready (MMBaseBearer *self,
GAsyncResult *res,
- GTask *task)
+ GTask *task)
{
- GError *error = NULL;
- gboolean launch_disconnect = FALSE;
- MMBearerConnectResult *result;
+ GError *error = NULL;
+ g_autoptr(MMBearerConnectResult) result = NULL;
/* NOTE: connect() implementations *MUST* handle cancellations themselves */
result = MM_BASE_BEARER_GET_CLASS (self)->connect_finish (self, res, &error);
@@ -907,63 +961,29 @@ connect_ready (MMBaseBearer *self,
mm_obj_warn (self, "connection attempt #%u failed: %s",
mm_bearer_stats_get_attempts (self->priv->stats),
error->message);
-
- /* Update failed attempts */
- mm_bearer_stats_set_failed_attempts (self->priv->stats,
- mm_bearer_stats_get_failed_attempts (self->priv->stats) + 1);
- bearer_update_interface_stats (self);
-
- if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) {
- /* Will launch disconnection */
- launch_disconnect = TRUE;
- } else {
- /* Update reported connection error before the status update */
- bearer_update_connection_error (self, error);
- bearer_update_status (self, MM_BEARER_STATUS_DISCONNECTED);
- }
+ connect_failed (self, task, error);
+ return;
}
+
/* Handle cancellations detected after successful connection */
- else if (g_cancellable_is_cancelled (self->priv->connect_cancellable)) {
- mm_obj_dbg (self, "connected, but need to disconnect");
- mm_bearer_connect_result_unref (result);
- error = g_error_new (G_IO_ERROR, G_IO_ERROR_CANCELLED,
- "Bearer got connected, but had to disconnect after cancellation request");
- launch_disconnect = TRUE;
- }
- else {
- mm_obj_dbg (self, "connected");
+ if (connect_check_cancel (self, task))
+ return;
- /* Update bearer and interface status */
- bearer_update_status_connected (
- self,
- mm_port_get_device (mm_bearer_connect_result_peek_data (result)),
- mm_bearer_connect_result_get_multiplexed (result),
- mm_bearer_connect_result_get_profile_id (result),
- mm_bearer_connect_result_peek_ipv4_config (result),
- mm_bearer_connect_result_peek_ipv6_config (result),
- mm_bearer_connect_result_get_uplink_speed (result),
- mm_bearer_connect_result_get_downlink_speed (result));
- mm_bearer_connect_result_unref (result);
- }
+ mm_obj_dbg (self, "connected");
+ g_task_set_task_data (task, g_steal_pointer (&result), (GDestroyNotify)mm_bearer_connect_result_unref);
- if (launch_disconnect) {
- /* Update reported connection error before the status update */
- bearer_update_connection_error (self, error);
- bearer_update_status (self, MM_BEARER_STATUS_DISCONNECTING);
- MM_BASE_BEARER_GET_CLASS (self)->disconnect (
+ /* Check that reload statistics is supported by the device; we can only do this while
+ * connected. */
+ if (MM_BASE_BEARER_GET_CLASS (self)->reload_stats &&
+ MM_BASE_BEARER_GET_CLASS (self)->reload_stats_finish) {
+ MM_BASE_BEARER_GET_CLASS (self)->reload_stats (
self,
- (GAsyncReadyCallback)disconnect_after_cancel_ready,
- NULL);
+ (GAsyncReadyCallback)reload_stats_supported_ready,
+ task);
+ return;
}
- g_clear_object (&self->priv->connect_cancellable);
-
- if (error)
- g_task_return_error (task, error);
- else
- g_task_return_boolean (task, TRUE);
-
- g_object_unref (task);
+ connect_succeeded (self, task);
}
void