From b91823012a870cbee59716c4de4578b33f47a6e6 Mon Sep 17 00:00:00 2001 From: Aleksander Morgado Date: Thu, 30 Jun 2022 00:31:51 +0200 Subject: [PATCH] base-modem: setup timeout monitoring in all control ports If any of the control ports ends up timing out 10 consecutive times, the modem will be flagged as invalid and it will be reprobed from scratch. This allows us to detect modems that end up irresponsive in QMI or MBIM while they're still exposed in e.g. the USB bus. --- src/mm-base-modem.c | 51 ++++++++++++++++++++++++++++++++------------- 1 file changed, 36 insertions(+), 15 deletions(-) diff --git a/src/mm-base-modem.c b/src/mm-base-modem.c index ac2c1e97..4148c8a4 100644 --- a/src/mm-base-modem.c +++ b/src/mm-base-modem.c @@ -147,9 +147,9 @@ mm_base_modem_get_dbus_id (MMBaseModem *self) /******************************************************************************/ static void -serial_port_timed_out_cb (MMPortSerial *port, - guint n_consecutive_timeouts, - MMBaseModem *self) +port_timed_out_cb (MMPort *port, + guint n_consecutive_timeouts, + MMBaseModem *self) { /* If reached the maximum number of timeouts, invalidate modem */ if (n_consecutive_timeouts >= self->priv->max_timeouts) { @@ -204,13 +204,6 @@ base_modem_create_tty_port (MMBaseModem *self, if (!port) return NULL; - /* Enable port timeout checks if requested to do so */ - if (self->priv->max_timeouts > 0) - g_signal_connect (port, - MM_PORT_SIGNAL_TIMED_OUT, - G_CALLBACK (serial_port_timed_out_cb), - self); - /* Optional user-provided baudrate */ if (mm_kernel_device_has_property (kernel_device, ID_MM_TTY_BAUDRATE)) g_object_set (port, @@ -369,6 +362,37 @@ base_modem_internal_grab_port (MMBaseModem *self, return NULL; } + /* Setup consecutive timeout watcher in all control ports */ + if (self->priv->max_timeouts > 0) { + gboolean timeout_monitoring = FALSE; + + if (MM_IS_PORT_SERIAL_AT (port)) { + mm_obj_dbg (port, "timeout monitoring enabled in AT port"); + timeout_monitoring = TRUE; + } else if (MM_IS_PORT_SERIAL_QCDM (port)) { + mm_obj_dbg (port, "timeout monitoring enabled in QCDM port"); + timeout_monitoring = TRUE; + } +#if defined WITH_QMI + else if (MM_IS_PORT_QMI (port)) { + mm_obj_dbg (port, "timeout monitoring enabled in QMI port"); + timeout_monitoring = TRUE; + } +#endif +#if defined WITH_MBIM + else if (MM_IS_PORT_MBIM (port)) { + mm_obj_dbg (port, "timeout monitoring enabled in MBIM port"); + timeout_monitoring = TRUE; + } +#endif + + if (timeout_monitoring) + g_signal_connect (port, + MM_PORT_SIGNAL_TIMED_OUT, + G_CALLBACK (port_timed_out_cb), + self); + } + /* Store kernel device */ g_object_set (port, MM_PORT_KERNEL_DEVICE, kernel_device, NULL); @@ -1719,11 +1743,8 @@ cleanup_modem_port (MMBaseModem *self, mm_port_subsys_get_string (mm_port_get_subsys (MM_PORT (port))), mm_port_get_device (MM_PORT (port))); - /* Cleanup for serial ports */ - if (MM_IS_PORT_SERIAL (port)) { - g_signal_handlers_disconnect_by_func (port, serial_port_timed_out_cb, self); - return; - } + /* Cleanup on all control ports */ + g_signal_handlers_disconnect_by_func (port, port_timed_out_cb, self); #if defined WITH_MBIM /* We need to close the MBIM port cleanly when disposing the modem object */