[PATCH] mm-broadband-modem-qmi: reprobe on qmi-proxy death

Aleksander Morgado aleksander at aleksander.es
Sun Oct 22 09:55:12 UTC 2017


Hey,

On Fri, Oct 20, 2017 at 7:10 PM, Eric Caruso <ejcaruso at chromium.org> wrote:
> 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.

I bumped the libqmi git master version to 1.19.1 (not a new release)
to flag the availability of the QMI_DEVICE_SIGNAL_REMOVED signal.
I also rebased this patch on top of git master, and merged it already. Thanks!

> ---
>  configure.ac                 |  2 +-
>  src/mm-broadband-modem-qmi.c | 70 ++++++++++++++++++++++++++++++++++++++++----
>  src/mm-port-qmi.c            | 10 +++++++
>  src/mm-port-qmi.h            |  2 ++
>  4 files changed, 77 insertions(+), 7 deletions(-)
>
> diff --git a/configure.ac b/configure.ac
> index f432e81d..7d6bfd95 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 541a24cb..13facde4 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;
>  };
>
>  /*****************************************************************************/
> @@ -11286,6 +11289,54 @@ parent_initialization_started (InitializationStartedContext *ctx)
>          ctx);
>  }
>
> +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 (InitializationStartedContext *ctx);
>
>  static void
> @@ -11310,7 +11361,9 @@ static void
>  allocate_next_client (InitializationStartedContext *ctx)
>  {
>      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 (MM_BROADBAND_MODEM_QMI (ctx->self),
> +                                  ctx->qmi);
>          parent_initialization_started (ctx);
>          return;
>      }
> @@ -11391,7 +11444,10 @@ 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 (ctx->self),
> +                                  ctx->qmi);
>          parent_initialization_started (ctx);
>          return;
>      }
> @@ -11447,10 +11503,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 */
> --
> 2.15.0.rc0.271.g36b669edcc-goog
>



-- 
Aleksander
https://aleksander.es


More information about the ModemManager-devel mailing list