diff options
Diffstat (limited to 'src/mm-base-bearer.c')
-rw-r--r-- | src/mm-base-bearer.c | 198 |
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 |