summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLukas Arnold <lukas.arnold@stud.tu-darmstadt.de>2022-11-08 22:10:54 +0100
committerAleksander Morgado <aleksandermj@chromium.org>2022-11-28 09:50:49 +0000
commit71801cf3a9ee5cda62d830c46290ec77722eecb8 (patch)
tree9376008e16b49514758674e1c629bc7fe5c0d99f
parentd0321573790017d0506f17ff01facac069122a94 (diff)
libqmi-glib: allow qmux connection over unix domain socket
-rw-r--r--src/libqmi-glib/qmi-endpoint-qmux.c67
-rw-r--r--src/libqmi-glib/qmi-helpers.c4
-rw-r--r--src/libqmi-glib/qmi-helpers.h6
3 files changed, 77 insertions, 0 deletions
diff --git a/src/libqmi-glib/qmi-endpoint-qmux.c b/src/libqmi-glib/qmi-endpoint-qmux.c
index 444b8f6..3a4cbde 100644
--- a/src/libqmi-glib/qmi-endpoint-qmux.c
+++ b/src/libqmi-glib/qmi-endpoint-qmux.c
@@ -36,6 +36,7 @@
#include "qmi-ctl.h"
#include "qmi-errors.h"
#include "qmi-error-types.h"
+#include "qmi-helpers.h"
G_DEFINE_TYPE (QmiEndpointQmux, qmi_endpoint_qmux, QMI_TYPE_ENDPOINT)
@@ -343,6 +344,64 @@ create_iostream_with_socket (GTask *task)
}
static void
+create_iostream_with_socket_direct (GTask *task)
+{
+ QmiEndpointQmux *self;
+ QmiFile *file;
+ GSocketAddress *socket_address;
+ GError *error = NULL;
+
+ self = g_task_get_source_object (task);
+
+ /* Create socket client */
+ self->priv->socket_client = g_socket_client_new ();
+ g_socket_client_set_family (self->priv->socket_client, G_SOCKET_FAMILY_UNIX);
+ g_socket_client_set_socket_type (self->priv->socket_client, G_SOCKET_TYPE_STREAM);
+ g_socket_client_set_protocol (self->priv->socket_client, G_SOCKET_PROTOCOL_DEFAULT);
+
+ /* Setup socket address (using a system path) */
+ g_object_get (self, QMI_ENDPOINT_FILE, &file, NULL);
+ socket_address = g_unix_socket_address_new_with_type (
+ qmi_file_get_path (file),
+ -1,
+ G_UNIX_SOCKET_ADDRESS_PATH);
+
+ /* Connect to address */
+ self->priv->socket_connection = g_socket_client_connect (
+ self->priv->socket_client,
+ G_SOCKET_CONNECTABLE (socket_address),
+ NULL,
+ &error);
+ g_object_unref (socket_address);
+
+ /* Display an error if the socket is not reachable */
+ if (!self->priv->socket_connection) {
+ g_task_return_new_error (task,
+ QMI_CORE_ERROR,
+ QMI_CORE_ERROR_FAILED,
+ "Cannot connect to the socket '%s': '%s'",
+ qmi_file_get_path (file),
+ error->message);
+ g_object_unref (file);
+ g_object_unref (task);
+ return;
+ }
+
+ g_object_unref (file);
+
+ /* Use the input and output streams of the socket */
+ self->priv->istream = g_io_stream_get_input_stream (G_IO_STREAM (self->priv->socket_connection));
+ if (self->priv->istream)
+ g_object_ref (self->priv->istream);
+
+ self->priv->ostream = g_io_stream_get_output_stream (G_IO_STREAM (self->priv->socket_connection));
+ if (self->priv->ostream)
+ g_object_ref (self->priv->ostream);
+
+ setup_iostream (task);
+}
+
+static void
endpoint_open (QmiEndpoint *endpoint,
gboolean use_proxy,
guint timeout,
@@ -352,6 +411,7 @@ endpoint_open (QmiEndpoint *endpoint,
{
QmiEndpointQmux *self;
QmuxDeviceOpenContext *ctx;
+ QmiFile *file;
GTask *task;
ctx = g_slice_new (QmuxDeviceOpenContext);
@@ -373,10 +433,17 @@ endpoint_open (QmiEndpoint *endpoint,
return;
}
+ /* Get the file name to determine whether a unix domain socket should be used instead of a device file */
+ g_object_get (self, QMI_ENDPOINT_FILE, &file, NULL);
+
if (use_proxy)
create_iostream_with_socket (task);
+ else if (g_strrstr (qmi_file_get_path (file), QMI_QMUX_SOCKET_FILE_NAME))
+ create_iostream_with_socket_direct (task);
else
create_iostream_with_fd (task);
+
+ g_object_unref (file);
}
/*****************************************************************************/
diff --git a/src/libqmi-glib/qmi-helpers.c b/src/libqmi-glib/qmi-helpers.c
index 4d93342..2cd433f 100644
--- a/src/libqmi-glib/qmi-helpers.c
+++ b/src/libqmi-glib/qmi-helpers.c
@@ -520,6 +520,10 @@ qmi_helpers_get_transport_type (const gchar *path,
if (g_file_test (rpmsg_sysfs_path, G_FILE_TEST_EXISTS))
return QMI_HELPERS_TRANSPORT_TYPE_QMUX;
+ /* Allow libqmi to connect directly to a unix domain socket with a specific file name */
+ if (g_strrstr (device_basename, QMI_QMUX_SOCKET_FILE_NAME))
+ return QMI_HELPERS_TRANSPORT_TYPE_QMUX;
+
g_set_error (error, QMI_CORE_ERROR, QMI_CORE_ERROR_FAILED,
"unexpected port subsystem");
return QMI_HELPERS_TRANSPORT_TYPE_UNKNOWN;
diff --git a/src/libqmi-glib/qmi-helpers.h b/src/libqmi-glib/qmi-helpers.h
index 14fa623..48b9f6d 100644
--- a/src/libqmi-glib/qmi-helpers.h
+++ b/src/libqmi-glib/qmi-helpers.h
@@ -60,6 +60,12 @@ typedef enum {
QMI_HELPERS_TRANSPORT_TYPE_MBIM,
} QmiHelpersTransportType;
+/*
+ * Symbol defining the file name for a unix domain socket used instead of a device file.
+ * The unix domain socket is addressed with the QMUX protocol.
+ */
+#define QMI_QMUX_SOCKET_FILE_NAME "qmux_socket"
+
G_GNUC_INTERNAL
QmiHelpersTransportType qmi_helpers_get_transport_type (const gchar *path,
GError **error);