diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/mm-port-probe.c | 90 | ||||
-rw-r--r-- | src/mm-port-probe.h | 14 |
2 files changed, 96 insertions, 8 deletions
diff --git a/src/mm-port-probe.c b/src/mm-port-probe.c index 20c981f2..961964f9 100644 --- a/src/mm-port-probe.c +++ b/src/mm-port-probe.c @@ -11,8 +11,8 @@ * GNU General Public License for more details: * * Copyright (C) 2008 - 2009 Novell, Inc. - * Copyright (C) 2009 - 2011 Red Hat, Inc. - * Copyright (C) 2011 Aleksander Morgado <aleksander@gnu.org> + * Copyright (C) 2009 - 2018 Red Hat, Inc. + * Copyright (C) 2011 - 2018 Aleksander Morgado <aleksander@aleksander.es> */ #include "config.h" @@ -52,6 +52,7 @@ * |----> Vendor * |----> Product * |----> Is Icera? + * |----> Is Xmm? * ----> QCDM Serial Open * |----> QCDM? * ----> QMI Device Open @@ -83,6 +84,7 @@ struct _MMPortProbePrivate { gchar *vendor; gchar *product; gboolean is_icera; + gboolean is_xmm; gboolean is_qmi; gboolean is_mbim; @@ -170,9 +172,11 @@ mm_port_probe_set_result_at (MMPortProbe *self, self->priv->vendor = NULL; self->priv->product = NULL; self->priv->is_icera = FALSE; + self->priv->is_xmm = FALSE; self->priv->flags |= (MM_PORT_PROBE_AT_VENDOR | MM_PORT_PROBE_AT_PRODUCT | - MM_PORT_PROBE_AT_ICERA); + MM_PORT_PROBE_AT_ICERA | + MM_PORT_PROBE_AT_XMM); } } @@ -235,6 +239,25 @@ mm_port_probe_set_result_at_icera (MMPortProbe *self, } void +mm_port_probe_set_result_at_xmm (MMPortProbe *self, + gboolean is_xmm) +{ + if (is_xmm) { + mm_dbg ("(%s/%s) Modem is XMM-based", + mm_kernel_device_get_subsystem (self->priv->port), + mm_kernel_device_get_name (self->priv->port)); + self->priv->is_xmm = TRUE; + self->priv->flags |= MM_PORT_PROBE_AT_XMM; + } else { + mm_dbg ("(%s/%s) Modem is probably not XMM-based", + mm_kernel_device_get_subsystem (self->priv->port), + mm_kernel_device_get_name (self->priv->port)); + self->priv->is_xmm = FALSE; + self->priv->flags |= MM_PORT_PROBE_AT_XMM; + } +} + +void mm_port_probe_set_result_qcdm (MMPortProbe *self, gboolean qcdm) { @@ -253,10 +276,12 @@ mm_port_probe_set_result_qcdm (MMPortProbe *self, self->priv->vendor = NULL; self->priv->product = NULL; self->priv->is_icera = FALSE; + self->priv->is_xmm = FALSE; self->priv->flags |= (MM_PORT_PROBE_AT | MM_PORT_PROBE_AT_VENDOR | MM_PORT_PROBE_AT_PRODUCT | MM_PORT_PROBE_AT_ICERA | + MM_PORT_PROBE_AT_XMM | MM_PORT_PROBE_QMI | MM_PORT_PROBE_MBIM); } else @@ -287,6 +312,7 @@ mm_port_probe_set_result_qmi (MMPortProbe *self, MM_PORT_PROBE_AT_VENDOR | MM_PORT_PROBE_AT_PRODUCT | MM_PORT_PROBE_AT_ICERA | + MM_PORT_PROBE_AT_XMM | MM_PORT_PROBE_QCDM | MM_PORT_PROBE_MBIM); } else @@ -317,6 +343,7 @@ mm_port_probe_set_result_mbim (MMPortProbe *self, MM_PORT_PROBE_AT_VENDOR | MM_PORT_PROBE_AT_PRODUCT | MM_PORT_PROBE_AT_ICERA | + MM_PORT_PROBE_AT_XMM | MM_PORT_PROBE_QCDM | MM_PORT_PROBE_QMI); } else @@ -828,6 +855,22 @@ is_non_at_response (const guint8 *data, gsize len) } static void +serial_probe_at_xmm_result_processor (MMPortProbe *self, + GVariant *result) +{ + if (result) { + /* If any result given, it must be a string */ + g_assert (g_variant_is_of_type (result, G_VARIANT_TYPE_STRING)); + if (strstr (g_variant_get_string (result, NULL), "XACT:")) { + mm_port_probe_set_result_at_xmm (self, TRUE); + return; + } + } + + mm_port_probe_set_result_at_xmm (self, FALSE); +} + +static void serial_probe_at_icera_result_processor (MMPortProbe *self, GVariant *result) { @@ -1038,6 +1081,11 @@ static const MMPortProbeAtCommand icera_probing[] = { { NULL } }; +static const MMPortProbeAtCommand xmm_probing[] = { + { "+XACT=?", 3, mm_port_probe_response_processor_string }, + { NULL } +}; + static void at_custom_init_ready (MMPortProbe *self, GAsyncResult *res) @@ -1127,6 +1175,13 @@ serial_probe_schedule (MMPortProbe *self) /* By default, wait 2 seconds between ICERA probing retries */ ctx->at_commands_wait_secs = 2; } + /* XMM support check requested and not already done? */ + else if ((ctx->flags & MM_PORT_PROBE_AT_XMM) && + !(self->priv->flags & MM_PORT_PROBE_AT_XMM)) { + /* Prepare AT product probing */ + ctx->at_result_processor = serial_probe_at_xmm_result_processor; + ctx->at_commands = xmm_probing; + } /* If a next AT group detected, go for it */ if (ctx->at_result_processor && @@ -1437,7 +1492,8 @@ mm_port_probe_run (MMPortProbe *self, if (ctx->flags & MM_PORT_PROBE_AT || ctx->flags & MM_PORT_PROBE_AT_VENDOR || ctx->flags & MM_PORT_PROBE_AT_PRODUCT || - ctx->flags & MM_PORT_PROBE_AT_ICERA) { + ctx->flags & MM_PORT_PROBE_AT_ICERA || + ctx->flags & MM_PORT_PROBE_AT_XMM) { ctx->at_probing_cancellable = g_cancellable_new (); /* If the main cancellable is cancelled, so will be the at-probing one */ if (cancellable) @@ -1727,6 +1783,32 @@ mm_port_probe_list_is_icera (GList *probes) } gboolean +mm_port_probe_is_xmm (MMPortProbe *self) +{ + g_return_val_if_fail (MM_IS_PORT_PROBE (self), FALSE); + + if (g_str_equal (mm_kernel_device_get_subsystem (self->priv->port), "net")) + return FALSE; + + return (self->priv->flags & MM_PORT_PROBE_AT_XMM ? + self->priv->is_xmm : + FALSE); +} + +gboolean +mm_port_probe_list_is_xmm (GList *probes) +{ + GList *l; + + for (l = probes; l; l = g_list_next (l)) { + if (mm_port_probe_is_xmm (MM_PORT_PROBE (l->data))) + return TRUE; + } + + return FALSE; +} + +gboolean mm_port_probe_is_ignored (MMPortProbe *self) { g_return_val_if_fail (MM_IS_PORT_PROBE (self), FALSE); diff --git a/src/mm-port-probe.h b/src/mm-port-probe.h index a300092e..8c2ead9a 100644 --- a/src/mm-port-probe.h +++ b/src/mm-port-probe.h @@ -10,7 +10,8 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details: * - * Copyright (C) 2011 Aleksander Morgado <aleksander@gnu.org> + * Copyright (C) 2009 - 2018 Red Hat, Inc. + * Copyright (C) 2011 - 2018 Aleksander Morgado <aleksander@aleksander.es> */ #ifndef MM_PORT_PROBE_H @@ -42,9 +43,10 @@ typedef enum { /*< underscore_name=mm_port_probe_flag >*/ MM_PORT_PROBE_AT_VENDOR = 1 << 1, MM_PORT_PROBE_AT_PRODUCT = 1 << 2, MM_PORT_PROBE_AT_ICERA = 1 << 3, - MM_PORT_PROBE_QCDM = 1 << 4, - MM_PORT_PROBE_QMI = 1 << 5, - MM_PORT_PROBE_MBIM = 1 << 6 + MM_PORT_PROBE_AT_XMM = 1 << 4, + MM_PORT_PROBE_QCDM = 1 << 5, + MM_PORT_PROBE_QMI = 1 << 6, + MM_PORT_PROBE_MBIM = 1 << 7, } MMPortProbeFlag; typedef struct _MMPortProbe MMPortProbe; @@ -97,6 +99,8 @@ void mm_port_probe_set_result_at_product (MMPortProbe *self, const gchar *at_product); void mm_port_probe_set_result_at_icera (MMPortProbe *self, gboolean is_icera); +void mm_port_probe_set_result_at_xmm (MMPortProbe *self, + gboolean is_xmm); void mm_port_probe_set_result_qcdm (MMPortProbe *self, gboolean qcdm); void mm_port_probe_set_result_qmi (MMPortProbe *self, @@ -130,6 +134,7 @@ gboolean mm_port_probe_is_mbim (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); +gboolean mm_port_probe_is_xmm (MMPortProbe *self); gboolean mm_port_probe_is_ignored (MMPortProbe *self); /* Additional helpers */ @@ -137,5 +142,6 @@ 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); #endif /* MM_PORT_PROBE_H */ |