diff options
author | Lukas Arnold <lukas.arnold@stud.tu-darmstadt.de> | 2022-11-08 22:10:54 +0100 |
---|---|---|
committer | Aleksander Morgado <aleksandermj@chromium.org> | 2022-11-28 09:50:49 +0000 |
commit | 71801cf3a9ee5cda62d830c46290ec77722eecb8 (patch) | |
tree | 9376008e16b49514758674e1c629bc7fe5c0d99f | |
parent | d0321573790017d0506f17ff01facac069122a94 (diff) |
libqmi-glib: allow qmux connection over unix domain socket
-rw-r--r-- | src/libqmi-glib/qmi-endpoint-qmux.c | 67 | ||||
-rw-r--r-- | src/libqmi-glib/qmi-helpers.c | 4 | ||||
-rw-r--r-- | src/libqmi-glib/qmi-helpers.h | 6 |
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); |