aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAleksander Morgado <aleksander@aleksander.es>2021-02-23 21:09:58 +0100
committerAleksander Morgado <aleksander@aleksander.es>2021-03-10 10:59:22 +0100
commitcd2f8d9d6344dcd4b079fc17e0b8bc555b54a1a4 (patch)
tree3c3bf8429f8dab26f692e43882bc340296670471
parentd1a893775ea1968a32377f0fc8cb049916aec5a7 (diff)
port-qmi: keep track of the endpoint info
The endpoint info of a given MMPortQmi is immutable (it's associated to the specific kernel driver in use and to the specific physical interface number of the device). We'll load it as soon as the kernel device object is set in the port, and we'll keep it in the private struct so that it can be used at any time, e.g. by the WDA Get/Set Data Format operations on newest devices, where the endpoint info TLV is mandatory.
-rw-r--r--src/mm-modem-helpers-qmi.c21
-rw-r--r--src/mm-modem-helpers-qmi.h7
-rw-r--r--src/mm-port-qmi.c77
-rw-r--r--src/mm-port-qmi.h3
4 files changed, 104 insertions, 4 deletions
diff --git a/src/mm-modem-helpers-qmi.c b/src/mm-modem-helpers-qmi.c
index e4bc7e29..ef951bac 100644
--- a/src/mm-modem-helpers-qmi.c
+++ b/src/mm-modem-helpers-qmi.c
@@ -1539,6 +1539,27 @@ mm_bearer_ip_family_to_qmi_pdp_type (MMBearerIpFamily ip_family,
}
/*****************************************************************************/
+/* QMI/WDA to MM translations */
+
+QmiDataEndpointType
+mm_port_subsys_to_qmi_endpoint_type (MMPortSubsys subsys)
+{
+ switch (subsys) {
+ case MM_PORT_SUBSYS_USBMISC:
+ return QMI_DATA_ENDPOINT_TYPE_HSUSB;
+ case MM_PORT_SUBSYS_RPMSG:
+ return QMI_DATA_ENDPOINT_TYPE_EMBEDDED;
+ case MM_PORT_SUBSYS_UNKNOWN:
+ case MM_PORT_SUBSYS_TTY:
+ case MM_PORT_SUBSYS_NET:
+ case MM_PORT_SUBSYS_UNIX:
+ default:
+ g_assert_not_reached ();
+ break;
+ }
+}
+
+/*****************************************************************************/
/**
* The only case where we need to apply some logic to decide what the current
diff --git a/src/mm-modem-helpers-qmi.h b/src/mm-modem-helpers-qmi.h
index 829ac76e..d64f94cb 100644
--- a/src/mm-modem-helpers-qmi.h
+++ b/src/mm-modem-helpers-qmi.h
@@ -21,6 +21,8 @@
#include <ModemManager.h>
#include <libqmi-glib.h>
+#include "mm-port.h"
+
/*****************************************************************************/
/* QMI/DMS to MM translations */
@@ -121,6 +123,11 @@ gboolean mm_bearer_ip_family_to_qmi_pdp_type (MMBearerIpF
QmiWdsPdpType *out_pdp_type);
/*****************************************************************************/
+/* QMI/WDA to MM translations */
+
+QmiDataEndpointType mm_port_subsys_to_qmi_endpoint_type (MMPortSubsys subsys);
+
+/*****************************************************************************/
/* QMI/OMA to MM translations */
MMOmaSessionType mm_oma_session_type_from_qmi_oma_session_type (QmiOmaSessionType qmi_session_type);
diff --git a/src/mm-port-qmi.c b/src/mm-port-qmi.c
index e3d99f7f..cc4b954f 100644
--- a/src/mm-port-qmi.c
+++ b/src/mm-port-qmi.c
@@ -22,6 +22,7 @@
#include <mm-errors-types.h>
#include "mm-port-qmi.h"
+#include "mm-modem-helpers-qmi.h"
#include "mm-log-object.h"
G_DEFINE_TYPE (MMPortQmi, mm_port_qmi, MM_TYPE_PORT)
@@ -33,10 +34,14 @@ typedef struct {
} ServiceInfo;
struct _MMPortQmiPrivate {
- gboolean in_progress;
+ gboolean in_progress;
QmiDevice *qmi_device;
- GList *services;
- gboolean llp_is_raw_ip;
+ GList *services;
+ gboolean llp_is_raw_ip;
+ /* endpoint info */
+ gulong endpoint_info_signal_id;
+ QmiDataEndpointType endpoint_type;
+ gint endpoint_interface_number;
};
/*****************************************************************************/
@@ -98,6 +103,55 @@ mm_port_qmi_peek_device (MMPortQmi *self)
/*****************************************************************************/
+static void
+initialize_endpoint_info (MMPortQmi *self)
+{
+ MMKernelDevice *kernel_device;
+
+ kernel_device = mm_port_peek_kernel_device (MM_PORT (self));
+
+ if (!kernel_device)
+ self->priv->endpoint_type = QMI_DATA_ENDPOINT_TYPE_UNDEFINED;
+ else
+ self->priv->endpoint_type = mm_port_subsys_to_qmi_endpoint_type (mm_port_get_subsys (MM_PORT (self)));
+
+ switch (self->priv->endpoint_type) {
+ case QMI_DATA_ENDPOINT_TYPE_HSUSB:
+ g_assert (kernel_device);
+ self->priv->endpoint_interface_number = mm_kernel_device_get_interface_number (kernel_device);
+ break;
+ case QMI_DATA_ENDPOINT_TYPE_EMBEDDED:
+ self->priv->endpoint_interface_number = 1;
+ break;
+ case QMI_DATA_ENDPOINT_TYPE_PCIE:
+ case QMI_DATA_ENDPOINT_TYPE_UNDEFINED:
+ case QMI_DATA_ENDPOINT_TYPE_HSIC:
+ case QMI_DATA_ENDPOINT_TYPE_BAM_DMUX:
+ case QMI_DATA_ENDPOINT_TYPE_UNKNOWN:
+ default:
+ self->priv->endpoint_interface_number = 0;
+ break;
+ }
+
+ mm_obj_dbg (self, "endpoint info updated: type '%s', interface number '%u'",
+ qmi_data_endpoint_type_get_string (self->priv->endpoint_type),
+ self->priv->endpoint_interface_number);
+}
+
+QmiDataEndpointType
+mm_port_qmi_get_endpoint_type (MMPortQmi *self)
+{
+ return self->priv->endpoint_type;
+}
+
+guint
+mm_port_qmi_get_endpoint_interface_number (MMPortQmi *self)
+{
+ return self->priv->endpoint_interface_number;
+}
+
+/*****************************************************************************/
+
void
mm_port_qmi_release_client (MMPortQmi *self,
QmiService service,
@@ -859,11 +913,21 @@ MMPortQmi *
mm_port_qmi_new (const gchar *name,
MMPortSubsys subsys)
{
- return MM_PORT_QMI (g_object_new (MM_TYPE_PORT_QMI,
+ MMPortQmi *self;
+
+ self = MM_PORT_QMI (g_object_new (MM_TYPE_PORT_QMI,
MM_PORT_DEVICE, name,
MM_PORT_SUBSYS, subsys,
MM_PORT_TYPE, MM_PORT_TYPE_QMI,
NULL));
+
+ /* load endpoint info as soon as kernel device is set */
+ self->priv->endpoint_info_signal_id = g_signal_connect (self,
+ "notify::" MM_PORT_KERNEL_DEVICE,
+ G_CALLBACK (initialize_endpoint_info),
+ NULL);
+
+ return self;
}
static void
@@ -878,6 +942,11 @@ dispose (GObject *object)
MMPortQmi *self = MM_PORT_QMI (object);
GList *l;
+ if (self->priv->endpoint_info_signal_id) {
+ g_signal_handler_disconnect (self, self->priv->endpoint_info_signal_id);
+ self->priv->endpoint_info_signal_id = 0;
+ }
+
/* Deallocate all clients */
for (l = self->priv->services; l; l = g_list_next (l)) {
ServiceInfo *info = l->data;
diff --git a/src/mm-port-qmi.h b/src/mm-port-qmi.h
index 986b3b7d..2a353e90 100644
--- a/src/mm-port-qmi.h
+++ b/src/mm-port-qmi.h
@@ -94,6 +94,9 @@ QmiClient *mm_port_qmi_get_client (MMPortQmi *self,
QmiDevice *mm_port_qmi_peek_device (MMPortQmi *self);
+QmiDataEndpointType mm_port_qmi_get_endpoint_type (MMPortQmi *self);
+guint mm_port_qmi_get_endpoint_interface_number (MMPortQmi *self);
+
gboolean mm_port_qmi_llp_is_raw_ip (MMPortQmi *self);
#endif /* MM_PORT_QMI_H */