aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/mm-broadband-modem-mbim.c66
1 files changed, 64 insertions, 2 deletions
diff --git a/src/mm-broadband-modem-mbim.c b/src/mm-broadband-modem-mbim.c
index 8a722b11..d4f483f0 100644
--- a/src/mm-broadband-modem-mbim.c
+++ b/src/mm-broadband-modem-mbim.c
@@ -90,6 +90,9 @@ struct _MMBroadbandModemMbimPrivate {
MbimDataClass highest_available_data_class;
MbimSubscriberReadyState last_ready_state;
+
+ /* For notifying when the mbim-proxy connection is dead */
+ gulong mbim_device_removed_id;
};
/*****************************************************************************/
@@ -1579,10 +1582,62 @@ parent_initialization_started (GTask *task)
}
static void
+mbim_device_removed_cb (MbimDevice *device,
+ MMBroadbandModemMbim *self)
+{
+ /* We have to do a full re-probe here because simply reopening the device
+ * and restarting mbim-proxy will leave us without MBIM notifications. */
+ mm_info ("Connection to mbim-proxy for %s lost, reprobing",
+ mbim_device_get_path_display (device));
+
+ g_signal_handler_disconnect (device,
+ self->priv->mbim_device_removed_id);
+ self->priv->mbim_device_removed_id = 0;
+
+ mm_base_modem_set_reprobe (MM_BASE_MODEM (self), TRUE);
+ mm_base_modem_set_valid (MM_BASE_MODEM (self), FALSE);
+}
+
+static void
+track_mbim_device_removed (MMBroadbandModemMbim *self,
+ MMPortMbim *mbim)
+{
+ MbimDevice *device;
+
+ device = mm_port_mbim_peek_device (mbim);
+ g_assert (device);
+
+ /* Register removal handler so we can handle mbim-proxy crashes */
+ self->priv->mbim_device_removed_id = g_signal_connect (
+ device,
+ MBIM_DEVICE_SIGNAL_REMOVED,
+ G_CALLBACK (mbim_device_removed_cb),
+ self);
+}
+
+static void
+untrack_mbim_device_removed (MMBroadbandModemMbim *self,
+ MMPortMbim *mbim)
+{
+ MbimDevice *device;
+
+ if (self->priv->mbim_device_removed_id == 0)
+ return;
+
+ device = mm_port_mbim_peek_device (mbim);
+ if (!device)
+ return;
+
+ g_signal_handler_disconnect (device, self->priv->mbim_device_removed_id);
+ self->priv->mbim_device_removed_id = 0;
+}
+
+static void
mbim_port_open_ready (MMPortMbim *mbim,
GAsyncResult *res,
GTask *task)
{
+ MMBroadbandModemMbim *self;
GError *error = NULL;
if (!mm_port_mbim_open_finish (mbim, res, &error)) {
@@ -1591,7 +1646,10 @@ mbim_port_open_ready (MMPortMbim *mbim,
return;
}
- /* Done we are, launch parent's callback */
+ /* Make sure we know if mbim-proxy dies on us, and then do the parent's
+ * initialization */
+ self = MM_BROADBAND_MODEM_MBIM (g_task_get_source_object (task));
+ track_mbim_device_removed (self, mbim);
parent_initialization_started (task);
}
@@ -1620,7 +1678,9 @@ initialization_started (MMBroadbandModem *self,
}
if (mm_port_mbim_is_open (ctx->mbim)) {
- /* Nothing to be done, just launch parent's callback */
+ /* Nothing to be done, just connect to a signal and launch parent's
+ * callback */
+ track_mbim_device_removed (MM_BROADBAND_MODEM_MBIM (self), ctx->mbim);
parent_initialization_started (task);
return;
}
@@ -3193,6 +3253,8 @@ finalize (GObject *object)
/* Explicitly remove notification handler */
self->priv->setup_flags = PROCESS_NOTIFICATION_FLAG_NONE;
common_setup_cleanup_unsolicited_events_sync (self, mm_port_mbim_peek_device (mbim), FALSE);
+ /* Disconnect signal handler for mbim-proxy disappearing, if it exists */
+ untrack_mbim_device_removed (self, mbim);
/* If we did open the MBIM port during initialization, close it now */
if (mm_port_mbim_is_open (mbim))
mm_port_mbim_close (mbim, NULL, NULL);