aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEric Caruso <ejcaruso@chromium.org>2017-10-20 10:10:47 -0700
committerAleksander Morgado <aleksander@aleksander.es>2017-10-22 11:53:32 +0200
commit098c4c0271e04b564da57bb5c9e4e8e067bd58c9 (patch)
treeec93cc71c640658de10ff507c13da253f7c52f1e
parentb4278615fc273756ae5fe2b84da1e39a56d3e121 (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.ac2
-rw-r--r--src/mm-broadband-modem-qmi.c70
-rw-r--r--src/mm-port-qmi.c10
-rw-r--r--src/mm-port-qmi.h2
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 */