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>
This commit is contained in:

committed by
Aleksander Morgado

parent
b4278615fc
commit
098c4c0271
@@ -341,7 +341,7 @@ dnl-----------------------------------------------------------------------------
|
|||||||
dnl QMI support (enabled by default)
|
dnl QMI support (enabled by default)
|
||||||
dnl
|
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])
|
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")
|
AM_CONDITIONAL(WITH_QMI, test "x$with_qmi" = "xyes")
|
||||||
|
@@ -126,6 +126,9 @@ struct _MMBroadbandModemQmiPrivate {
|
|||||||
/* Firmware helpers */
|
/* Firmware helpers */
|
||||||
GList *firmware_list;
|
GList *firmware_list;
|
||||||
MMFirmwareProperties *current_firmware;
|
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);
|
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 allocate_next_client (GTask *task);
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@@ -11225,11 +11276,14 @@ static void
|
|||||||
allocate_next_client (GTask *task)
|
allocate_next_client (GTask *task)
|
||||||
{
|
{
|
||||||
InitializationStartedContext *ctx;
|
InitializationStartedContext *ctx;
|
||||||
|
MMBroadbandModemQmi *self;
|
||||||
|
|
||||||
|
self = g_task_get_source_object (task);
|
||||||
ctx = g_task_get_task_data (task);
|
ctx = g_task_get_task_data (task);
|
||||||
|
|
||||||
if (ctx->services[ctx->service_index] == QMI_SERVICE_UNKNOWN) {
|
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);
|
parent_initialization_started (task);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -11312,7 +11366,9 @@ initialization_started (MMBroadbandModem *self,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (mm_port_qmi_is_open (ctx->qmi)) {
|
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);
|
parent_initialization_started (task);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -11368,9 +11424,11 @@ finalize (GObject *object)
|
|||||||
MMBroadbandModemQmi *self = MM_BROADBAND_MODEM_QMI (object);
|
MMBroadbandModemQmi *self = MM_BROADBAND_MODEM_QMI (object);
|
||||||
|
|
||||||
qmi = mm_base_modem_peek_port_qmi (MM_BASE_MODEM (self));
|
qmi = mm_base_modem_peek_port_qmi (MM_BASE_MODEM (self));
|
||||||
|
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 we did open the QMI port during initialization, close it now */
|
||||||
if (qmi &&
|
if (mm_port_qmi_is_open (qmi))
|
||||||
mm_port_qmi_is_open (qmi)) {
|
|
||||||
mm_port_qmi_close (qmi);
|
mm_port_qmi_close (qmi);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -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 {
|
typedef struct {
|
||||||
ServiceInfo *info;
|
ServiceInfo *info;
|
||||||
} AllocateClientContext;
|
} AllocateClientContext;
|
||||||
|
@@ -82,6 +82,8 @@ QmiClient *mm_port_qmi_get_client (MMPortQmi *self,
|
|||||||
QmiService service,
|
QmiService service,
|
||||||
MMPortQmiFlag flag);
|
MMPortQmiFlag flag);
|
||||||
|
|
||||||
|
QmiDevice *mm_port_qmi_peek_device (MMPortQmi *self);
|
||||||
|
|
||||||
gboolean mm_port_qmi_llp_is_raw_ip (MMPortQmi *self);
|
gboolean mm_port_qmi_llp_is_raw_ip (MMPortQmi *self);
|
||||||
|
|
||||||
#endif /* MM_PORT_QMI_H */
|
#endif /* MM_PORT_QMI_H */
|
||||||
|
Reference in New Issue
Block a user