From 1cf4e63d828669747424e740519a6e2da246be38 Mon Sep 17 00:00:00 2001 From: Aleksander Morgado Date: Sun, 23 May 2021 23:39:18 +0200 Subject: [PATCH 37/39] bearer-qmi: implement reload_connection_status() for the sync operation The original load_connection_status() method would return an UNSUPPORTED error if connection monitoring wasn't required (which is the default in most QMI modems). The new reload_connection_status() method requires the check to always be done unconditionally. We take most of the original logic in the load_connection_status() for the new reload_connection_status(), and we add the UNSUPPORTED error logic exclusively in the new load_connection_status(). --- src/mm-bearer-qmi.c | 86 +++++++++++++++++++++++++++++++++++++-------- 1 file changed, 71 insertions(+), 15 deletions(-) diff --git a/src/mm-bearer-qmi.c b/src/mm-bearer-qmi.c index 670fb804..967594bf 100644 --- a/src/mm-bearer-qmi.c +++ b/src/mm-bearer-qmi.c @@ -226,7 +226,7 @@ reload_stats (MMBaseBearer *self, } /*****************************************************************************/ -/* Connection status polling */ +/* Connection status check */ typedef enum { CONNECTION_STATUS_CONTEXT_STEP_FIRST, @@ -240,9 +240,9 @@ typedef struct { } ConnectionStatusContext; static MMBearerConnectionStatus -load_connection_status_finish (MMBaseBearer *self, - GAsyncResult *res, - GError **error) +reload_connection_status_finish (MMBaseBearer *self, + GAsyncResult *res, + GError **error) { gint val; @@ -312,16 +312,6 @@ connection_status_context_step (GTask *task) switch (ctx->step) { case CONNECTION_STATUS_CONTEXT_STEP_FIRST: - /* Connection status polling is an optional feature that must be - * enabled explicitly via udev tags. If not set, out as unsupported */ - if (self->priv->data && - !mm_kernel_device_get_global_property_as_boolean (mm_port_peek_kernel_device (self->priv->data), - "ID_MM_QMI_CONNECTION_STATUS_POLLING_ENABLE")) { - g_task_return_new_error (task, MM_CORE_ERROR, MM_CORE_ERROR_UNSUPPORTED, - "Connection status polling not required"); - g_object_unref (task); - return; - } /* If no clients ready on start, assume disconnected */ if (!self->priv->client_ipv4 && !self->priv->client_ipv6) { g_task_return_int (task, MM_BEARER_CONNECTION_STATUS_DISCONNECTED); @@ -369,7 +359,7 @@ connection_status_context_step (GTask *task) } static void -load_connection_status (MMBaseBearer *self, +reload_connection_status (MMBaseBearer *self, GAsyncReadyCallback callback, gpointer user_data) { @@ -385,6 +375,68 @@ load_connection_status (MMBaseBearer *self, connection_status_context_step (task); } +/*****************************************************************************/ +/* Connection status polling */ + +static MMBearerConnectionStatus +load_connection_status_finish (MMBaseBearer *self, + GAsyncResult *res, + GError **error) +{ + gint val; + + val = g_task_propagate_int (G_TASK (res), error); + if (val < 0) + return MM_BEARER_CONNECTION_STATUS_UNKNOWN; + + return (MMBearerConnectionStatus) val; +} + +static void +reload_connection_status_ready (MMBaseBearer *self, + GAsyncResult *res, + GTask *task) +{ + MMBearerConnectionStatus status; + GError *error = NULL; + + status = reload_connection_status_finish (self, res, &error); + if (status == MM_BEARER_CONNECTION_STATUS_UNKNOWN) + g_task_return_error (task, error); + else + g_task_return_int (task, MM_BEARER_CONNECTION_STATUS_CONNECTED); + g_object_unref (task); +} + +static void +load_connection_status (MMBaseBearer *_self, + GAsyncReadyCallback callback, + gpointer user_data) +{ + MMBearerQmi *self = MM_BEARER_QMI (_self); + GTask *task; + + task = g_task_new (self, NULL, callback, user_data); + + /* Connection status polling is an optional feature that must be + * enabled explicitly via udev tags. If not set, out as unsupported. + * Note that when connected via a muxed link, the udev tag should be + * checked on the master interface (lower device) */ + if ((self->priv->data && + !mm_kernel_device_get_global_property_as_boolean (mm_port_peek_kernel_device (self->priv->data), + "ID_MM_QMI_CONNECTION_STATUS_POLLING_ENABLE")) || + (self->priv->link && + !mm_kernel_device_get_global_property_as_boolean (mm_kernel_device_peek_lower_device (mm_port_peek_kernel_device (self->priv->link)), + "ID_MM_QMI_CONNECTION_STATUS_POLLING_ENABLE"))) { + g_task_return_new_error (task, MM_CORE_ERROR, MM_CORE_ERROR_UNSUPPORTED, + "Connection status polling not required"); + g_object_unref (task); + return; + } + + reload_connection_status (_self, (GAsyncReadyCallback)reload_connection_status_ready, task); +} + /*****************************************************************************/ /* Connect */ @@ -2235,4 +2287,8 @@ mm_bearer_qmi_class_init (MMBearerQmiClass *klass) base_bearer_class->reload_stats_finish = reload_stats_finish; base_bearer_class->load_connection_status = load_connection_status; base_bearer_class->load_connection_status_finish = load_connection_status_finish; +#if defined WITH_SYSTEMD_SUSPEND_RESUME + base_bearer_class->reload_connection_status = reload_connection_status; + base_bearer_class->reload_connection_status_finish = reload_connection_status_finish; +#endif } -- 2.31.1