aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Vogt <acc-github@tovotu.de>2024-06-19 20:33:22 +0200
committerAleksander Morgado <aleksander@aleksander.es>2024-07-31 17:36:14 +0000
commitc2e3a8c10e6d398ef79067666c976fe6e8fb190e (patch)
treebb6f776bf18e351d8439e4e92b5d45ae4a10fbce
parent1c4f2320f1f50e22851bd477c88467e7436d2d33 (diff)
port-probe: detect XMMRPC ports
-rw-r--r--docs/reference/api/ModemManager-sections.txt1
-rw-r--r--include/ModemManager-enums.h2
-rw-r--r--include/ModemManager-tags.h13
-rw-r--r--src/mm-base-manager.c1
-rw-r--r--src/mm-base-modem.c18
-rw-r--r--src/mm-iface-modem.c1
-rw-r--r--src/mm-plugin.c20
-rw-r--r--src/mm-plugin.h1
-rw-r--r--src/mm-port-probe.c65
-rw-r--r--src/mm-port-probe.h12
-rw-r--r--src/mm-port.h1
11 files changed, 123 insertions, 12 deletions
diff --git a/docs/reference/api/ModemManager-sections.txt b/docs/reference/api/ModemManager-sections.txt
index 0b047d2a..50a44b66 100644
--- a/docs/reference/api/ModemManager-sections.txt
+++ b/docs/reference/api/ModemManager-sections.txt
@@ -222,6 +222,7 @@ ID_MM_PORT_TYPE_QCDM
ID_MM_PORT_TYPE_AUDIO
ID_MM_PORT_TYPE_QMI
ID_MM_PORT_TYPE_MBIM
+ID_MM_PORT_TYPE_XMMRPC
ID_MM_TTY_BAUDRATE
ID_MM_TTY_FLOW_CONTROL
ID_MM_REQUIRED
diff --git a/include/ModemManager-enums.h b/include/ModemManager-enums.h
index 1217e581..cf4baeb1 100644
--- a/include/ModemManager-enums.h
+++ b/include/ModemManager-enums.h
@@ -657,6 +657,7 @@ typedef enum { /*< underscore_name=mm_modem_band >*/
* @MM_MODEM_PORT_TYPE_MBIM: MBIM port.
* @MM_MODEM_PORT_TYPE_AUDIO: Audio port. Since 1.12.
* @MM_MODEM_PORT_TYPE_IGNORED: Ignored port. Since 1.16.
+ * @MM_MODEM_PORT_TYPE_XMMRPC: Control protocol for Intel XMM modems. Since 1.24.
*
* Type of modem port.
*
@@ -672,6 +673,7 @@ typedef enum { /*< underscore_name=mm_modem_port_type >*/
MM_MODEM_PORT_TYPE_MBIM = 7,
MM_MODEM_PORT_TYPE_AUDIO = 8,
MM_MODEM_PORT_TYPE_IGNORED = 9,
+ MM_MODEM_PORT_TYPE_XMMRPC = 10,
} MMModemPortType;
/**
diff --git a/include/ModemManager-tags.h b/include/ModemManager-tags.h
index abd71cf5..74e9a0d7 100644
--- a/include/ModemManager-tags.h
+++ b/include/ModemManager-tags.h
@@ -221,6 +221,19 @@
#define ID_MM_PORT_TYPE_MBIM "ID_MM_PORT_TYPE_MBIM"
/**
+ * ID_MM_PORT_TYPE_XMMRPC:
+ *
+ * This is a port-specific tag applied to generic ports that we know in advance
+ * are RPC control ports for Intel XMM modems.
+ *
+ * This tag will also prevent other types of probing (e.g. AT, QMI) on the
+ * port.
+ *
+ * Since: 1.24
+ */
+#define ID_MM_PORT_TYPE_XMMRPC "ID_MM_PORT_TYPE_XMMRPC"
+
+/**
* ID_MM_TTY_BAUDRATE:
*
* This is a port-specific tag applied to TTYs that require a specific
diff --git a/src/mm-base-manager.c b/src/mm-base-manager.c
index 7e0dcdff..c053a53e 100644
--- a/src/mm-base-manager.c
+++ b/src/mm-base-manager.c
@@ -249,6 +249,7 @@ modem_setup (FindDeviceSupportContext *ctx)
case MM_MODEM_PORT_TYPE_AT:
case MM_MODEM_PORT_TYPE_QMI:
case MM_MODEM_PORT_TYPE_MBIM:
+ case MM_MODEM_PORT_TYPE_XMMRPC:
g_ptr_array_add (aux, g_strdup (port_infos[i].name));
break;
case MM_MODEM_PORT_TYPE_UNKNOWN:
diff --git a/src/mm-base-modem.c b/src/mm-base-modem.c
index ac9c261e..d8fd4164 100644
--- a/src/mm-base-modem.c
+++ b/src/mm-base-modem.c
@@ -314,6 +314,13 @@ base_modem_create_wwan_port (MMBaseModem *self,
if (ptype == MM_PORT_TYPE_AT)
return MM_PORT (mm_port_serial_at_new (name, MM_PORT_SUBSYS_WWAN));
+ if (ptype == MM_PORT_TYPE_XMMRPC)
+ return MM_PORT (g_object_new (MM_TYPE_PORT,
+ MM_PORT_DEVICE, name,
+ MM_PORT_SUBSYS, MM_PORT_SUBSYS_WWAN,
+ MM_PORT_TYPE, MM_PORT_TYPE_XMMRPC,
+ NULL));
+
return NULL;
}
@@ -1221,6 +1228,9 @@ mm_base_modem_get_port_infos (MMBaseModem *self,
case MM_PORT_TYPE_MBIM:
port_info.type = MM_MODEM_PORT_TYPE_MBIM;
break;
+ case MM_PORT_TYPE_XMMRPC:
+ port_info.type = MM_MODEM_PORT_TYPE_XMMRPC;
+ break;
case MM_PORT_TYPE_IGNORED:
port_info.type = MM_MODEM_PORT_TYPE_IGNORED;
break;
@@ -1350,6 +1360,7 @@ mm_base_modem_organize_ports (MMBaseModem *self,
MMPortSerialGps *gps = NULL;
MMPortSerial *audio = NULL;
MMPortSerialAt *data_at_primary = NULL;
+ MMPort *xmmrpc = NULL;
GList *l;
/* These lists don't keep full references, so they should be
* g_list_free()-ed on error exits */
@@ -1445,6 +1456,12 @@ mm_base_modem_organize_ports (MMBaseModem *self,
audio = MM_PORT_SERIAL (candidate);
break;
+ case MM_PORT_TYPE_XMMRPC:
+ g_assert (MM_IS_PORT (candidate));
+ if (!xmmrpc)
+ xmmrpc = MM_PORT (candidate);
+ break;
+
#if defined WITH_QMI
case MM_PORT_TYPE_QMI:
qmi = g_list_append (qmi, candidate);
@@ -1572,6 +1589,7 @@ mm_base_modem_organize_ports (MMBaseModem *self,
log_port (self, MM_PORT (gps_control), "gps (control)");
log_port (self, MM_PORT (gps), "gps (nmea)");
log_port (self, MM_PORT (audio), "audio");
+ log_port (self, MM_PORT (xmmrpc), "xmmrpc");
#if defined WITH_QMI
for (l = qmi; l; l = g_list_next (l))
log_port (self, MM_PORT (l->data), "qmi");
diff --git a/src/mm-iface-modem.c b/src/mm-iface-modem.c
index 858073df..6d0aa9cd 100644
--- a/src/mm-iface-modem.c
+++ b/src/mm-iface-modem.c
@@ -4229,6 +4229,7 @@ fcc_unlock (GTask *task)
case MM_MODEM_PORT_TYPE_AT:
case MM_MODEM_PORT_TYPE_QMI:
case MM_MODEM_PORT_TYPE_MBIM:
+ case MM_MODEM_PORT_TYPE_XMMRPC:
g_ptr_array_add (aux, g_strdup (port_infos[i].name));
break;
case MM_MODEM_PORT_TYPE_UNKNOWN:
diff --git a/src/mm-plugin.c b/src/mm-plugin.c
index 1e721e54..75dc02d7 100644
--- a/src/mm-plugin.c
+++ b/src/mm-plugin.c
@@ -94,6 +94,7 @@ struct _MMPluginPrivate {
gboolean qcdm_required;
gboolean qmi;
gboolean mbim;
+ gboolean xmmrpc;
gboolean icera_probe;
gboolean xmm_probe;
MMPortProbeAtCommand *custom_at_probe;
@@ -128,6 +129,7 @@ enum {
PROP_REQUIRED_QCDM,
PROP_ALLOWED_QMI,
PROP_ALLOWED_MBIM,
+ PROP_ALLOWED_XMMRPC,
PROP_ICERA_PROBE,
PROP_ALLOWED_ICERA,
PROP_FORBIDDEN_ICERA,
@@ -283,7 +285,8 @@ apply_pre_probing_filters (MMPlugin *self,
if (self->priv->drivers ||
self->priv->forbidden_drivers ||
!self->priv->qmi ||
- !self->priv->mbim) {
+ !self->priv->mbim ||
+ !self->priv->xmmrpc) {
static const gchar *virtual_drivers [] = { "virtual", NULL };
const gchar **drivers;
@@ -1256,6 +1259,10 @@ set_property (GObject *object,
/* Construct only */
self->priv->mbim = g_value_get_boolean (value);
break;
+ case PROP_ALLOWED_XMMRPC:
+ /* Construct only */
+ self->priv->xmmrpc = g_value_get_boolean (value);
+ break;
case PROP_ICERA_PROBE:
/* Construct only */
self->priv->icera_probe = g_value_get_boolean (value);
@@ -1369,6 +1376,9 @@ get_property (GObject *object,
case PROP_ALLOWED_MBIM:
g_value_set_boolean (value, self->priv->mbim);
break;
+ case PROP_ALLOWED_XMMRPC:
+ g_value_set_boolean (value, self->priv->xmmrpc);
+ break;
case PROP_ALLOWED_UDEV_TAGS:
g_value_set_boxed (value, self->priv->udev_tags);
break;
@@ -1620,6 +1630,14 @@ mm_plugin_class_init (MMPluginClass *klass)
FALSE,
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
+ g_object_class_install_property
+ (object_class, PROP_ALLOWED_XMMRPC,
+ g_param_spec_boolean (MM_PLUGIN_ALLOWED_XMMRPC,
+ "Allowed XMMRPC",
+ "Whether XMMRPC ports are allowed in this plugin.",
+ FALSE,
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
+
g_object_class_install_property
(object_class, PROP_ICERA_PROBE,
g_param_spec_boolean (MM_PLUGIN_ICERA_PROBE,
diff --git a/src/mm-plugin.h b/src/mm-plugin.h
index 79a703b1..c10637f5 100644
--- a/src/mm-plugin.h
+++ b/src/mm-plugin.h
@@ -60,6 +60,7 @@
#define MM_PLUGIN_REQUIRED_QCDM "required-qcdm"
#define MM_PLUGIN_ALLOWED_QMI "allowed-qmi"
#define MM_PLUGIN_ALLOWED_MBIM "allowed-mbim"
+#define MM_PLUGIN_ALLOWED_XMMRPC "allowed-xmmrpc"
#define MM_PLUGIN_ICERA_PROBE "icera-probe"
#define MM_PLUGIN_ALLOWED_ICERA "allowed-icera"
#define MM_PLUGIN_FORBIDDEN_ICERA "forbidden-icera"
diff --git a/src/mm-port-probe.c b/src/mm-port-probe.c
index c9134d98..94c21bb8 100644
--- a/src/mm-port-probe.c
+++ b/src/mm-port-probe.c
@@ -90,6 +90,7 @@ struct _MMPortProbePrivate {
gboolean is_ignored;
gboolean is_gps;
gboolean is_audio;
+ gboolean is_xmmrpc;
gboolean maybe_at;
gboolean maybe_qcdm;
gboolean maybe_qmi;
@@ -189,6 +190,7 @@ mm_port_probe_set_result_at (MMPortProbe *self,
self->priv->is_qcdm = FALSE;
self->priv->is_qmi = FALSE;
self->priv->is_mbim = FALSE;
+ self->priv->is_xmmrpc = FALSE;
self->priv->flags |= (MM_PORT_PROBE_QCDM | MM_PORT_PROBE_QMI | MM_PORT_PROBE_MBIM);
} else {
mm_obj_dbg (self, "port is not AT-capable");
@@ -282,6 +284,7 @@ mm_port_probe_set_result_qcdm (MMPortProbe *self,
self->priv->product = NULL;
self->priv->is_icera = FALSE;
self->priv->is_xmm = FALSE;
+ self->priv->is_xmmrpc = FALSE;
self->priv->flags |= (MM_PORT_PROBE_AT |
MM_PORT_PROBE_AT_VENDOR |
MM_PORT_PROBE_AT_PRODUCT |
@@ -307,6 +310,7 @@ mm_port_probe_set_result_qmi (MMPortProbe *self,
self->priv->is_at = FALSE;
self->priv->is_qcdm = FALSE;
self->priv->is_mbim = FALSE;
+ self->priv->is_xmmrpc = FALSE;
self->priv->vendor = NULL;
self->priv->product = NULL;
self->priv->flags |= (MM_PORT_PROBE_AT |
@@ -334,6 +338,7 @@ mm_port_probe_set_result_mbim (MMPortProbe *self,
self->priv->is_at = FALSE;
self->priv->is_qcdm = FALSE;
self->priv->is_qmi = FALSE;
+ self->priv->is_xmmrpc = FALSE;
self->priv->vendor = NULL;
self->priv->product = NULL;
self->priv->flags |= (MM_PORT_PROBE_AT |
@@ -1514,6 +1519,15 @@ mm_port_probe_run (MMPortProbe *self,
mm_port_probe_set_result_mbim (self, FALSE);
}
+ /* If this is a port flagged as an XMMRPC port, don't do any other probing */
+ if (self->priv->is_xmmrpc) {
+ mm_obj_dbg (self, "XMMRPC port detected");
+ mm_port_probe_set_result_at (self, FALSE);
+ mm_port_probe_set_result_qcdm (self, FALSE);
+ mm_port_probe_set_result_qmi (self, FALSE);
+ mm_port_probe_set_result_mbim (self, FALSE);
+ }
+
/* If this is a port flagged as being an AT port, don't do any other probing */
if (self->priv->maybe_at) {
mm_obj_dbg (self, "no QCDM/QMI/MBIM probing in possible AT port");
@@ -1694,6 +1708,30 @@ mm_port_probe_list_has_mbim_port (GList *list)
return FALSE;
}
+gboolean
+mm_port_probe_is_xmmrpc (MMPortProbe *self)
+{
+ g_return_val_if_fail (MM_IS_PORT_PROBE (self), FALSE);
+
+ return self->priv->is_xmmrpc;
+}
+
+gboolean
+mm_port_probe_list_has_xmmrpc_port (GList *list)
+{
+ GList *l;
+
+ for (l = list; l; l = g_list_next (l)) {
+ MMPortProbe *probe = MM_PORT_PROBE (l->data);
+
+ if (!probe->priv->is_ignored &&
+ mm_port_probe_is_xmmrpc (probe))
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
MMPortType
mm_port_probe_get_port_type (MMPortProbe *self)
{
@@ -1732,6 +1770,9 @@ mm_port_probe_get_port_type (MMPortProbe *self)
if (self->priv->is_audio)
return MM_PORT_TYPE_AUDIO;
+ if (self->priv->is_xmmrpc)
+ return MM_PORT_TYPE_XMMRPC;
+
return MM_PORT_TYPE_UNKNOWN;
}
@@ -1864,6 +1905,7 @@ initialize_port_type_hints (MMPortProbe *self)
guint n_udev_hints = 0;
gboolean auto_maybe_qmi = FALSE;
gboolean auto_maybe_mbim = FALSE;
+ gboolean auto_is_xmmrpc = FALSE;
gboolean auto_maybe_at = FALSE;
gboolean auto_maybe_qcdm = FALSE;
gboolean auto_ignored = FALSE;
@@ -1884,6 +1926,7 @@ initialize_port_type_hints (MMPortProbe *self)
/* Process udev-configured port type hints */
ADD_HINT_FROM_UDEV_TAG (ID_MM_PORT_TYPE_GPS, is_gps);
ADD_HINT_FROM_UDEV_TAG (ID_MM_PORT_TYPE_AUDIO, is_audio);
+ ADD_HINT_FROM_UDEV_TAG (ID_MM_PORT_TYPE_XMMRPC, is_xmmrpc);
ADD_HINT_FROM_UDEV_TAG (ID_MM_PORT_TYPE_AT_PRIMARY, maybe_at);
ADD_HINT_FROM_UDEV_TAG (ID_MM_PORT_TYPE_AT_SECONDARY, maybe_at);
ADD_HINT_FROM_UDEV_TAG (ID_MM_PORT_TYPE_AT_PPP, maybe_at);
@@ -1923,6 +1966,9 @@ initialize_port_type_hints (MMPortProbe *self)
} else if (!g_strcmp0 (type, "MBIM")) {
mm_obj_dbg (self, "port may be MBIM based on the wwan type attribute");
auto_maybe_mbim = TRUE;
+ } else if (!g_strcmp0 (type, "XMMRPC")) {
+ mm_obj_dbg (self, "port is XMMRPC based on the wwan type attribute");
+ auto_is_xmmrpc = TRUE;
} else if (!g_strcmp0 (type, "QMI")) {
mm_obj_dbg (self, "port may be QMI based on the wwan type attribute");
auto_maybe_qmi = TRUE;
@@ -1961,7 +2007,12 @@ initialize_port_type_hints (MMPortProbe *self)
}
}
- g_assert ((auto_maybe_qmi + auto_maybe_mbim + auto_maybe_at + auto_maybe_qcdm + auto_ignored) <= 1);
+ g_assert ((auto_maybe_qmi +
+ auto_maybe_mbim +
+ auto_is_xmmrpc +
+ auto_maybe_at +
+ auto_maybe_qcdm +
+ auto_ignored) <= 1);
#define PROCESS_AUTO_HINTS(TYPE, FIELD) do { \
if (auto_##FIELD) { \
@@ -1972,18 +2023,20 @@ initialize_port_type_hints (MMPortProbe *self)
} \
} while (0)
- PROCESS_AUTO_HINTS ("QMI", maybe_qmi);
- PROCESS_AUTO_HINTS ("MBIM", maybe_mbim);
- PROCESS_AUTO_HINTS ("AT", maybe_at);
- PROCESS_AUTO_HINTS ("QCDM", maybe_qcdm);
+ PROCESS_AUTO_HINTS ("QMI", maybe_qmi);
+ PROCESS_AUTO_HINTS ("MBIM", maybe_mbim);
+ PROCESS_AUTO_HINTS ("XMMRPC", is_xmmrpc);
+ PROCESS_AUTO_HINTS ("AT", maybe_at);
+ PROCESS_AUTO_HINTS ("QCDM", maybe_qcdm);
#undef PROCESS_AUTO_HINTS
- mm_obj_dbg (self, "port type hints loaded: AT %s, QMI %s, MBIM %s, QCDM %s, AUDIO %s, GPS %s",
+ mm_obj_dbg (self, "port type hints loaded: AT %s, QMI %s, MBIM %s, QCDM %s, XMMRPC %s, AUDIO %s, GPS %s",
self->priv->maybe_at ? "yes" : "no",
self->priv->maybe_qmi ? "yes" : "no",
self->priv->maybe_mbim ? "yes" : "no",
self->priv->maybe_qcdm ? "yes" : "no",
+ self->priv->is_xmmrpc ? "yes" : "no",
self->priv->is_audio ? "yes" : "no",
self->priv->is_gps ? "yes" : "no");
diff --git a/src/mm-port-probe.h b/src/mm-port-probe.h
index faa3a12c..fd427575 100644
--- a/src/mm-port-probe.h
+++ b/src/mm-port-probe.h
@@ -134,6 +134,7 @@ gboolean mm_port_probe_is_at (MMPortProbe *self);
gboolean mm_port_probe_is_qcdm (MMPortProbe *self);
gboolean mm_port_probe_is_qmi (MMPortProbe *self);
gboolean mm_port_probe_is_mbim (MMPortProbe *self);
+gboolean mm_port_probe_is_xmmrpc (MMPortProbe *self);
const gchar *mm_port_probe_get_vendor (MMPortProbe *self);
const gchar *mm_port_probe_get_product (MMPortProbe *self);
gboolean mm_port_probe_is_icera (MMPortProbe *self);
@@ -141,10 +142,11 @@ gboolean mm_port_probe_is_xmm (MMPortProbe *self);
gboolean mm_port_probe_is_ignored (MMPortProbe *self);
/* Additional helpers */
-gboolean mm_port_probe_list_has_at_port (GList *list);
-gboolean mm_port_probe_list_has_qmi_port (GList *list);
-gboolean mm_port_probe_list_has_mbim_port (GList *list);
-gboolean mm_port_probe_list_is_icera (GList *list);
-gboolean mm_port_probe_list_is_xmm (GList *list);
+gboolean mm_port_probe_list_has_at_port (GList *list);
+gboolean mm_port_probe_list_has_qmi_port (GList *list);
+gboolean mm_port_probe_list_has_mbim_port (GList *list);
+gboolean mm_port_probe_list_has_xmmrpc_port (GList *list);
+gboolean mm_port_probe_list_is_icera (GList *list);
+gboolean mm_port_probe_list_is_xmm (GList *list);
#endif /* MM_PORT_PROBE_H */
diff --git a/src/mm-port.h b/src/mm-port.h
index e0cca85c..0d78be3d 100644
--- a/src/mm-port.h
+++ b/src/mm-port.h
@@ -43,6 +43,7 @@ typedef enum { /*< underscore_name=mm_port_type >*/
MM_PORT_TYPE_GPS,
MM_PORT_TYPE_QMI,
MM_PORT_TYPE_MBIM,
+ MM_PORT_TYPE_XMMRPC,
MM_PORT_TYPE_AUDIO,
MM_PORT_TYPE_LAST = MM_PORT_TYPE_AUDIO /*< skip >*/
} MMPortType;