diff options
author | Eric Caruso <ejcaruso@chromium.org> | 2017-10-20 10:10:47 -0700 |
---|---|---|
committer | Aleksander Morgado <aleksander@aleksander.es> | 2017-10-22 11:53:32 +0200 |
commit | 098c4c0271e04b564da57bb5c9e4e8e067bd58c9 (patch) | |
tree | ec93cc71c640658de10ff507c13da253f7c52f1e | |
parent | b4278615fc273756ae5fe2b84da1e39a56d3e121 (diff) |
mm-broadband-modem-qmi: reprobe on qmi-proxy death
This allows us to reprobe the modem and respawn the
qmi-proxy in case it dies on us. This gets us access
to the modem and unsolicited notifications again. Do
this by connecting to the device-removed signal on
QmiDevice.
---
Rebased on top of git master by
Aleksander Morgado <aleksander@aleksander.es>
-rw-r--r-- | configure.ac | 2 | ||||
-rw-r--r-- | src/mm-broadband-modem-qmi.c | 70 | ||||
-rw-r--r-- | src/mm-port-qmi.c | 10 | ||||
-rw-r--r-- | src/mm-port-qmi.h | 2 |
4 files changed, 77 insertions, 7 deletions
diff --git a/configure.ac b/configure.ac index f432e81d..aa8dd213 100644 --- a/configure.ac +++ b/configure.ac @@ -341,7 +341,7 @@ dnl----------------------------------------------------------------------------- dnl QMI support (enabled by default) dnl -LIBQMI_VERSION=1.17.900 +LIBQMI_VERSION=1.19.1 AC_ARG_WITH(qmi, AS_HELP_STRING([--without-qmi], [Build without QMI support]), [], [with_qmi=yes]) AM_CONDITIONAL(WITH_QMI, test "x$with_qmi" = "xyes") diff --git a/src/mm-broadband-modem-qmi.c b/src/mm-broadband-modem-qmi.c index 21ab8698..95dce58e 100644 --- a/src/mm-broadband-modem-qmi.c +++ b/src/mm-broadband-modem-qmi.c @@ -126,6 +126,9 @@ struct _MMBroadbandModemQmiPrivate { /* Firmware helpers */ GList *firmware_list; MMFirmwareProperties *current_firmware; + + /* For notifying when the qmi-proxy connection is dead */ + guint qmi_device_removed_id; }; /*****************************************************************************/ @@ -11198,6 +11201,54 @@ parent_initialization_started (GTask *task) task); } +static void +qmi_device_removed_cb (QmiDevice *device, + MMBroadbandModemQmi *self) +{ + /* Reprobe the modem here so we can get notifications back. */ + mm_info ("Connection to qmi-proxy for %s lost, reprobing", + qmi_device_get_path_display (device)); + + g_signal_handler_disconnect (device, self->priv->qmi_device_removed_id); + self->priv->qmi_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_qmi_device_removed (MMBroadbandModemQmi *self, + MMPortQmi* qmi) +{ + QmiDevice *device; + + device = mm_port_qmi_peek_device (qmi); + g_assert (device); + + self->priv->qmi_device_removed_id = g_signal_connect ( + device, + QMI_DEVICE_SIGNAL_REMOVED, + G_CALLBACK (qmi_device_removed_cb), + self); +} + +static void +untrack_qmi_device_removed (MMBroadbandModemQmi *self, + MMPortQmi* qmi) +{ + QmiDevice *device; + + if (self->priv->qmi_device_removed_id == 0) + return; + + device = mm_port_qmi_peek_device (qmi); + if (!device) + return; + + g_signal_handler_disconnect (device, self->priv->qmi_device_removed_id); + self->priv->qmi_device_removed_id = 0; +} + static void allocate_next_client (GTask *task); static void @@ -11225,11 +11276,14 @@ static void allocate_next_client (GTask *task) { InitializationStartedContext *ctx; + MMBroadbandModemQmi *self; + self = g_task_get_source_object (task); ctx = g_task_get_task_data (task); if (ctx->services[ctx->service_index] == QMI_SERVICE_UNKNOWN) { - /* Done we are, launch parent's callback */ + /* Done we are, track device removal and launch parent's callback */ + track_qmi_device_removed (self, ctx->qmi); parent_initialization_started (task); return; } @@ -11312,7 +11366,9 @@ initialization_started (MMBroadbandModem *self, } if (mm_port_qmi_is_open (ctx->qmi)) { - /* Nothing to be done, just launch parent's callback */ + /* Nothing to be done, just track device removal and launch parent's + * callback */ + track_qmi_device_removed (MM_BROADBAND_MODEM_QMI (self), ctx->qmi); parent_initialization_started (task); return; } @@ -11368,10 +11424,12 @@ finalize (GObject *object) MMBroadbandModemQmi *self = MM_BROADBAND_MODEM_QMI (object); qmi = mm_base_modem_peek_port_qmi (MM_BASE_MODEM (self)); - /* If we did open the QMI port during initialization, close it now */ - if (qmi && - mm_port_qmi_is_open (qmi)) { - mm_port_qmi_close (qmi); + if (qmi) { + /* Disconnect signal handler for qmi-proxy disappearing, if it exists */ + untrack_qmi_device_removed (self, qmi); + /* If we did open the QMI port during initialization, close it now */ + if (mm_port_qmi_is_open (qmi)) + mm_port_qmi_close (qmi); } g_free (self->priv->imei); diff --git a/src/mm-port-qmi.c b/src/mm-port-qmi.c index e2f63054..129700c9 100644 --- a/src/mm-port-qmi.c +++ b/src/mm-port-qmi.c @@ -72,6 +72,16 @@ mm_port_qmi_get_client (MMPortQmi *self, /*****************************************************************************/ +QmiDevice * +mm_port_qmi_peek_device (MMPortQmi *self) +{ + g_return_val_if_fail (MM_IS_PORT_QMI (self), NULL); + + return self->priv->qmi_device; +} + +/*****************************************************************************/ + typedef struct { ServiceInfo *info; } AllocateClientContext; diff --git a/src/mm-port-qmi.h b/src/mm-port-qmi.h index 2724140a..26818c84 100644 --- a/src/mm-port-qmi.h +++ b/src/mm-port-qmi.h @@ -82,6 +82,8 @@ QmiClient *mm_port_qmi_get_client (MMPortQmi *self, QmiService service, MMPortQmiFlag flag); +QmiDevice *mm_port_qmi_peek_device (MMPortQmi *self); + gboolean mm_port_qmi_llp_is_raw_ip (MMPortQmi *self); #endif /* MM_PORT_QMI_H */ |