summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAleksander Morgado <aleksandermj@chromium.org>2022-12-15 21:09:30 +0000
committerAleksander Morgado <aleksandermj@chromium.org>2022-12-30 13:54:12 +0000
commit25bfefd2efeeefcc2a12696dd25cec83f1fe419c (patch)
treeb60a04a170fd84efc6a8586af99a362b071e28c3
parent1198bdba33a6659b7bb57b612601f3fde45bac0d (diff)
downloadModemManager-25bfefd2efeeefcc2a12696dd25cec83f1fe419c.tar.gz
port: define new generic 'removed' signal
This signal indicates that the port is no longer accessible. Unlike a udev port removal event, this indication may happen even if the port is still exposed by the system. It is designed to detect protocol proxy crashes, and so when such event is detected by the modem, a full reprobe of the device will be done to start from scratch the protocol management operations. (cherry picked from commit 455c4860915b194c654abb6cd49bcbb483ec650b)
-rw-r--r--src/mm-base-modem.c56
-rw-r--r--src/mm-port.c10
-rw-r--r--src/mm-port.h2
3 files changed, 48 insertions, 20 deletions
diff --git a/src/mm-base-modem.c b/src/mm-base-modem.c
index 73780040d..1cc02560f 100644
--- a/src/mm-base-modem.c
+++ b/src/mm-base-modem.c
@@ -147,6 +147,18 @@ mm_base_modem_get_dbus_id (MMBaseModem *self)
/******************************************************************************/
static void
+port_removed_cb (MMPort *port,
+ MMBaseModem *self)
+{
+ /* We have to do a full re-probe here because simply reopening the device
+ * and restarting proxy would leave us without proper notifications. */
+ mm_obj_info (self, "port '%s' no longer controllable, reprobing",
+ mm_port_get_device (MM_PORT (port)));
+ self->priv->reprobe = TRUE;
+ g_cancellable_cancel (self->priv->cancellable);
+}
+
+static void
port_timed_out_cb (MMPort *port,
guint n_consecutive_timeouts,
MMBaseModem *self)
@@ -322,6 +334,7 @@ base_modem_internal_grab_port (MMBaseModem *self,
const gchar *subsys;
const gchar *name;
g_autofree gchar *key = NULL;
+ gboolean port_monitoring = FALSE;
subsys = mm_kernel_device_get_subsystem (kernel_device);
name = mm_kernel_device_get_name (kernel_device);
@@ -368,35 +381,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;
- }
+ /* Setup consecutive ports and removal watchers in all control ports */
+ if (MM_IS_PORT_SERIAL_AT (port)) {
+ mm_obj_dbg (port, "port monitoring enabled in AT port");
+ port_monitoring = TRUE;
+ } else if (MM_IS_PORT_SERIAL_QCDM (port)) {
+ mm_obj_dbg (port, "port monitoring enabled in QCDM port");
+ port_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;
- }
+ else if (MM_IS_PORT_QMI (port)) {
+ mm_obj_dbg (port, "port monitoring enabled in QMI port");
+ port_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;
- }
+ else if (MM_IS_PORT_MBIM (port)) {
+ mm_obj_dbg (port, "port monitoring enabled in MBIM port");
+ port_monitoring = TRUE;
+ }
#endif
- if (timeout_monitoring)
+ if (port_monitoring) {
+ if (self->priv->max_timeouts > 0)
g_signal_connect (port,
MM_PORT_SIGNAL_TIMED_OUT,
G_CALLBACK (port_timed_out_cb),
self);
+ g_signal_connect (port,
+ MM_PORT_SIGNAL_REMOVED,
+ G_CALLBACK (port_removed_cb),
+ self);
}
/* Store kernel device */
@@ -1780,6 +1795,7 @@ cleanup_modem_port (MMBaseModem *self,
/* Cleanup on all control ports */
g_signal_handlers_disconnect_by_func (port, port_timed_out_cb, self);
+ g_signal_handlers_disconnect_by_func (port, port_removed_cb, self);
#if defined WITH_MBIM
/* We need to close the MBIM port cleanly when disposing the modem object */
diff --git a/src/mm-port.c b/src/mm-port.c
index aca16b5fb..f2df39339 100644
--- a/src/mm-port.c
+++ b/src/mm-port.c
@@ -40,6 +40,7 @@ enum {
enum {
TIMED_OUT,
+ REMOVED,
LAST_SIGNAL
};
@@ -287,4 +288,13 @@ mm_port_class_init (MMPortClass *klass)
NULL, NULL,
g_cclosure_marshal_generic,
G_TYPE_NONE, 1, G_TYPE_UINT);
+
+ signals[REMOVED] =
+ g_signal_new (MM_PORT_SIGNAL_REMOVED,
+ G_OBJECT_CLASS_TYPE (object_class),
+ G_SIGNAL_RUN_FIRST,
+ G_STRUCT_OFFSET (MMPortClass, removed),
+ NULL, NULL,
+ g_cclosure_marshal_generic,
+ G_TYPE_NONE, 0);
}
diff --git a/src/mm-port.h b/src/mm-port.h
index 75e749eb3..e0cca85c7 100644
--- a/src/mm-port.h
+++ b/src/mm-port.h
@@ -61,6 +61,7 @@ typedef enum { /*< underscore_name=mm_port_type >*/
#define MM_PORT_KERNEL_DEVICE "kernel-device"
#define MM_PORT_SIGNAL_TIMED_OUT "timed-out"
+#define MM_PORT_SIGNAL_REMOVED "removed"
typedef struct _MMPort MMPort;
typedef struct _MMPortClass MMPortClass;
@@ -76,6 +77,7 @@ struct _MMPortClass {
/* signals */
void (* timed_out) (MMPort *port, guint n_consecutive_replies);
+ void (* removed) (MMPort *port);
};
GType mm_port_get_type (void);