aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Lassalle <andrewlassalle@chromium.org>2020-11-25 13:14:35 -0800
committerAleksander Morgado <aleksander@aleksander.es>2021-04-14 11:27:27 +0200
commitec375bd959f071ce01533d50a2775e8a6f69607b (patch)
tree20dcc27cc9e8096269a6bfa1521cfcefe35d3b24
parent312f753046b4ceaddef7b45a676a8880bfc9d89d (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.c1
-rw-r--r--src/mm-port-qmi.c137
-rw-r--r--src/mm-port-qmi.h4
-rw-r--r--src/mm-port.h1
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;