diff options
author | Andrew Lassalle <andrewlassalle@chromium.org> | 2020-11-25 13:14:35 -0800 |
---|---|---|
committer | Aleksander Morgado <aleksander@aleksander.es> | 2021-04-14 11:27:27 +0200 |
commit | ec375bd959f071ce01533d50a2775e8a6f69607b (patch) | |
tree | 20dcc27cc9e8096269a6bfa1521cfcefe35d3b24 | |
parent | 312f753046b4ceaddef7b45a676a8880bfc9d89d (diff) |
port-qmi: add support for QRTR
Extend mm-port-qmi to accept a QRTR node to work with modems using the
QRTR protocol.
-rw-r--r-- | src/mm-modem-helpers-qmi.c | 1 | ||||
-rw-r--r-- | src/mm-port-qmi.c | 137 | ||||
-rw-r--r-- | src/mm-port-qmi.h | 4 | ||||
-rw-r--r-- | src/mm-port.h | 1 |
4 files changed, 126 insertions, 17 deletions
diff --git a/src/mm-modem-helpers-qmi.c b/src/mm-modem-helpers-qmi.c index 66e91f4f..a17e14ad 100644 --- a/src/mm-modem-helpers-qmi.c +++ b/src/mm-modem-helpers-qmi.c @@ -1560,6 +1560,7 @@ mm_port_subsys_to_qmi_endpoint_type (MMPortSubsys subsys) case MM_PORT_SUBSYS_USBMISC: return QMI_DATA_ENDPOINT_TYPE_HSUSB; case MM_PORT_SUBSYS_RPMSG: + case MM_PORT_SUBSYS_QRTR: return QMI_DATA_ENDPOINT_TYPE_EMBEDDED; case MM_PORT_SUBSYS_UNKNOWN: case MM_PORT_SUBSYS_TTY: diff --git a/src/mm-port-qmi.c b/src/mm-port-qmi.c index fe27b75f..cae1ecee 100644 --- a/src/mm-port-qmi.c +++ b/src/mm-port-qmi.c @@ -14,6 +14,7 @@ * Copyright (C) 2021 Aleksander Morgado <aleksander@aleksander.es> */ +#include <config.h> #include <stdio.h> #include <stdlib.h> @@ -32,6 +33,16 @@ G_DEFINE_TYPE (MMPortQmi, mm_port_qmi, MM_TYPE_PORT) +enum { + PROP_0, +#if WITH_QMI + PROP_NODE, +#endif + PROP_LAST +}; + +static GParamSpec *properties[PROP_LAST]; + typedef struct { QmiService service; QmiClient *client; @@ -43,6 +54,10 @@ struct _MMPortQmiPrivate { QmiDevice *qmi_device; GList *services; gchar *net_driver; +#if defined WITH_QRTR + QrtrNode *node; +#endif + /* endpoint info */ gulong endpoint_info_signal_id; QmiDataEndpointType endpoint_type; @@ -1748,6 +1763,10 @@ internal_setup_data_format (MMPortQmi *self, ctx->wda_ul_dap_requested = QMI_WDA_DATA_AGGREGATION_PROTOCOL_DISABLED; ctx->wda_dl_dap_current = QMI_WDA_DATA_AGGREGATION_PROTOCOL_DISABLED; ctx->wda_dl_dap_requested = QMI_WDA_DATA_AGGREGATION_PROTOCOL_DISABLED; + + if (mm_port_get_subsys (MM_PORT (self)) == MM_PORT_SUBSYS_QRTR) + ctx->use_endpoint = TRUE; + g_task_set_task_data (task, ctx, (GDestroyNotify) internal_setup_data_format_context_free); internal_setup_data_format_context_step (task); @@ -2155,28 +2174,36 @@ port_open_step (GTask *task) ctx->step++; /* Fall through */ - case PORT_OPEN_STEP_DEVICE_NEW: { - GFile *file; - gchar *fullpath; - - fullpath = g_strdup_printf ("/dev/%s", mm_port_get_device (MM_PORT (self))); - file = g_file_new_for_path (fullpath); - + case PORT_OPEN_STEP_DEVICE_NEW: /* We flag in this point that we're opening. From now on, if we stop * for whatever reason, we should clear this flag. We do this by ensuring * that all callbacks go through the LAST step for completing. */ self->priv->in_progress = TRUE; - mm_obj_dbg (self, "Creating QMI device..."); - qmi_device_new (file, - g_task_get_cancellable (task), - (GAsyncReadyCallback) qmi_device_new_ready, - task); - - g_free (fullpath); - g_object_unref (file); - return; - } +#if defined WITH_QRTR + if (self->priv->node) { + mm_obj_info (self, "Creating QMI device from QRTR node..."); + qmi_device_new_from_node (self->priv->node, + g_task_get_cancellable (task), + (GAsyncReadyCallback) qmi_device_new_ready, + task); + return; + } +#endif + { + g_autoptr(GFile) file = NULL; + g_autofree gchar *fullpath = NULL; + + fullpath = g_strdup_printf ("/dev/%s", mm_port_get_device (MM_PORT (self))); + file = g_file_new_for_path (fullpath); + + mm_obj_dbg (self, "Creating QMI device..."); + qmi_device_new (file, + g_task_get_cancellable (task), + (GAsyncReadyCallback) qmi_device_new_ready, + task); + return; + } case PORT_OPEN_STEP_OPEN_WITHOUT_DATA_FORMAT: if (!self->priv->wda_unsupported) { @@ -2451,6 +2478,20 @@ mm_port_qmi_new (const gchar *name, NULL)); } +#if defined WITH_QRTR +MMPortQmi * +mm_port_qmi_new_from_node (const gchar *name, + QrtrNode *node) +{ + return MM_PORT_QMI (g_object_new (MM_TYPE_PORT_QMI, + "node", node, + MM_PORT_DEVICE, name, + MM_PORT_SUBSYS, MM_PORT_SUBSYS_QRTR, + MM_PORT_TYPE, MM_PORT_TYPE_QMI, + NULL)); +} +#endif + static void mm_port_qmi_init (MMPortQmi *self) { @@ -2464,6 +2505,51 @@ mm_port_qmi_init (MMPortQmi *self) } static void +set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + switch (prop_id) { +#if defined WITH_QRTR + case PROP_NODE: + { + MMPortQmi *self = MM_PORT_QMI (object); + + /* construct only, no new reference! */ + self->priv->node = g_value_get_object (value); + break; + } +#endif + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + switch (prop_id) { +#if defined WITH_QRTR + case PROP_NODE: + { + MMPortQmi *self = MM_PORT_QMI (object); + + g_value_set_object (value, self->priv->node); + break; + } +#endif + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void dispose (GObject *object) { MMPortQmi *self = MM_PORT_QMI (object); @@ -2490,6 +2576,10 @@ dispose (GObject *object) g_clear_pointer (&self->priv->preallocated_links, g_array_unref); g_clear_object (&self->priv->preallocated_links_master); + /* Clear node object */ +#if defined WITH_QRTR + g_clear_object (&self->priv->node); +#endif /* Clear device object */ g_clear_object (&self->priv->qmi_device); @@ -2506,5 +2596,18 @@ mm_port_qmi_class_init (MMPortQmiClass *klass) g_type_class_add_private (object_class, sizeof (MMPortQmiPrivate)); /* Virtual methods */ + object_class->get_property = get_property; + object_class->set_property = set_property; object_class->dispose = dispose; + +#if defined WITH_QRTR + properties[PROP_NODE] = + g_param_spec_object ("node", + "Qrtr Node", + "Qrtr node to be probed", + QRTR_TYPE_NODE, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY); + +#endif + g_object_class_install_properties (object_class, PROP_LAST, properties); } diff --git a/src/mm-port-qmi.h b/src/mm-port-qmi.h index 0d99bc12..d5e4f8cf 100644 --- a/src/mm-port-qmi.h +++ b/src/mm-port-qmi.h @@ -61,6 +61,10 @@ G_DEFINE_AUTOPTR_CLEANUP_FUNC (MMPortQmi, g_object_unref) MMPortQmi *mm_port_qmi_new (const gchar *name, MMPortSubsys subsys); +#if QMI_QRTR_SUPPORTED +MMPortQmi *mm_port_qmi_new_from_node (const gchar *name, + QrtrNode *node); +#endif void mm_port_qmi_open (MMPortQmi *self, gboolean set_data_format, GCancellable *cancellable, diff --git a/src/mm-port.h b/src/mm-port.h index 8295d264..75595323 100644 --- a/src/mm-port.h +++ b/src/mm-port.h @@ -28,6 +28,7 @@ typedef enum { /*< underscore_name=mm_port_subsys >*/ MM_PORT_SUBSYS_NET, MM_PORT_SUBSYS_USBMISC, MM_PORT_SUBSYS_UNIX, + MM_PORT_SUBSYS_QRTR, MM_PORT_SUBSYS_RPMSG, MM_PORT_SUBSYS_LAST = MM_PORT_SUBSYS_RPMSG /*< skip >*/ } MMPortSubsys; |