diff options
author | Aleksander Morgado <aleksander@aleksander.es> | 2019-11-25 10:04:18 +0100 |
---|---|---|
committer | Aleksander Morgado <aleksander@aleksander.es> | 2019-12-03 13:15:03 +0100 |
commit | d91f4b5f0e2635414adb8448c4654c652065d9b5 (patch) | |
tree | 438c37a79f18c59e0a6af6ff92ecf89ac7d4a022 | |
parent | 7b27fde4526097b7fe2120bca5b436e8ffd1d9e9 (diff) |
bearer-qmi: close QMI port if it was open during connection
If the bearer is using a QMI port that is not the primary one, we need
to explicitly open it during the connection attempt. Keep track of
that, and make sure we close it during normal disconnection or if the
connection attempt fails.
(cherry picked from commit 2790074c7e00b94f5079ba7bda8911a12ab0e28c)
-rw-r--r-- | src/mm-bearer-qmi.c | 37 |
1 files changed, 33 insertions, 4 deletions
diff --git a/src/mm-bearer-qmi.c b/src/mm-bearer-qmi.c index 1ce9fc54..12ab9f26 100644 --- a/src/mm-bearer-qmi.c +++ b/src/mm-bearer-qmi.c @@ -40,6 +40,9 @@ G_DEFINE_TYPE (MMBearerQmi, mm_bearer_qmi, MM_TYPE_BASE_BEARER) struct _MMBearerQmiPrivate { /* State kept while connected */ + MMPortQmi *qmi; + gboolean explicit_qmi_open; + QmiClientWds *client_ipv4; guint packet_service_status_ipv4_indication_id; guint event_report_ipv4_indication_id; @@ -414,6 +417,7 @@ typedef struct { ConnectStep step; MMPort *data; MMPortQmi *qmi; + gboolean explicit_qmi_open; gchar *user; gchar *password; gchar *apn; @@ -472,6 +476,9 @@ connect_context_free (ConnectContext *ctx) &ctx->event_report_ipv6_indication_id); } + if (ctx->explicit_qmi_open) + mm_port_qmi_close (ctx->qmi); + g_clear_error (&ctx->error_ipv4); g_clear_error (&ctx->error_ipv6); g_clear_object (&ctx->client_ipv4); @@ -1195,8 +1202,10 @@ qmi_port_open_ready (MMPortQmi *qmi, return; } - /* Keep on */ ctx = g_task_get_task_data (task); + ctx->explicit_qmi_open = TRUE; + + /* Keep on */ ctx->step++; connect_context_step (task); } @@ -1225,6 +1234,10 @@ connect_context_step (GTask *task) ctx->step++; case CONNECT_STEP_OPEN_QMI_PORT: + /* If we're explicitly opening the port (e.g. using a different cdc-wdm + * port because the primary one is already connected by a different + * bearer), then make sure we also close it if anything goes wrong and + * during disconnect */ if (!mm_port_qmi_is_open (ctx->qmi)) { mm_port_qmi_open (ctx->qmi, TRUE, @@ -1459,6 +1472,14 @@ connect_context_step (GTask *task) mm_port_set_connected (MM_PORT (ctx->data), TRUE); /* Keep connection related data */ + + g_assert (ctx->self->priv->qmi == NULL); + ctx->self->priv->qmi = g_object_ref (ctx->qmi); + if (ctx->explicit_qmi_open) { + ctx->self->priv->explicit_qmi_open = TRUE; + ctx->explicit_qmi_open = FALSE; + } + g_assert (ctx->self->priv->data == NULL); ctx->self->priv->data = g_object_ref (ctx->data); @@ -1768,8 +1789,15 @@ reset_bearer_connection (MMBearerQmi *self, g_clear_object (&self->priv->client_ipv6); } - if (!self->priv->packet_data_handle_ipv4 && - !self->priv->packet_data_handle_ipv6) { + if (!self->priv->packet_data_handle_ipv4 && !self->priv->packet_data_handle_ipv6) { + /* Close port if we had it explicitly open for this connection */ + if (self->priv->qmi) { + if (self->priv->explicit_qmi_open) { + self->priv->explicit_qmi_open = FALSE; + mm_port_qmi_close (self->priv->qmi); + } + g_clear_object (&self->priv->qmi); + } if (self->priv->data) { /* Port is disconnected; update the state */ mm_port_set_connected (self->priv->data, FALSE); @@ -1935,7 +1963,8 @@ disconnect (MMBaseBearer *_self, if ((!self->priv->packet_data_handle_ipv4 && !self->priv->packet_data_handle_ipv6) || (!self->priv->client_ipv4 && !self->priv->client_ipv6) || - !self->priv->data) { + !self->priv->data || + !self->priv->qmi) { g_task_report_new_error ( self, callback, |