port-qmi: asynchronous close operation always
To be in sync with the qmi_device_close_async() underlying method, given that the synchronous one is deprecated.
This commit is contained in:
@@ -1584,6 +1584,14 @@ finalize (GObject *object)
|
|||||||
G_OBJECT_CLASS (mm_base_modem_parent_class)->finalize (object);
|
G_OBJECT_CLASS (mm_base_modem_parent_class)->finalize (object);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined WITH_QMI
|
||||||
|
static void
|
||||||
|
foreach_port_qmi_close (MMPortQmi *port_qmi)
|
||||||
|
{
|
||||||
|
mm_port_qmi_close (port_qmi, NULL, NULL);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#if defined WITH_MBIM
|
#if defined WITH_MBIM
|
||||||
static void
|
static void
|
||||||
foreach_port_mbim_close (MMPortMbim *port_mbim)
|
foreach_port_mbim_close (MMPortMbim *port_mbim)
|
||||||
@@ -1623,7 +1631,7 @@ dispose (GObject *object)
|
|||||||
* otherwise the allocated CIDs will be kept allocated, and if we end up
|
* otherwise the allocated CIDs will be kept allocated, and if we end up
|
||||||
* allocating too many newer allocations will fail with client-ids-exhausted
|
* allocating too many newer allocations will fail with client-ids-exhausted
|
||||||
* errors. */
|
* errors. */
|
||||||
g_list_foreach (self->priv->qmi, (GFunc)mm_port_qmi_close, NULL);
|
g_list_foreach (self->priv->qmi, (GFunc)foreach_port_qmi_close, NULL);
|
||||||
g_list_free_full (self->priv->qmi, g_object_unref);
|
g_list_free_full (self->priv->qmi, g_object_unref);
|
||||||
self->priv->qmi = NULL;
|
self->priv->qmi = NULL;
|
||||||
#endif
|
#endif
|
||||||
|
@@ -481,7 +481,7 @@ connect_context_free (ConnectContext *ctx)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (ctx->explicit_qmi_open)
|
if (ctx->explicit_qmi_open)
|
||||||
mm_port_qmi_close (ctx->qmi);
|
mm_port_qmi_close (ctx->qmi, NULL, NULL);
|
||||||
|
|
||||||
g_clear_error (&ctx->error_ipv4);
|
g_clear_error (&ctx->error_ipv4);
|
||||||
g_clear_error (&ctx->error_ipv6);
|
g_clear_error (&ctx->error_ipv6);
|
||||||
@@ -1883,7 +1883,7 @@ reset_bearer_connection (MMBearerQmi *self,
|
|||||||
if (self->priv->qmi) {
|
if (self->priv->qmi) {
|
||||||
if (self->priv->explicit_qmi_open) {
|
if (self->priv->explicit_qmi_open) {
|
||||||
self->priv->explicit_qmi_open = FALSE;
|
self->priv->explicit_qmi_open = FALSE;
|
||||||
mm_port_qmi_close (self->priv->qmi);
|
mm_port_qmi_close (self->priv->qmi, NULL, NULL);
|
||||||
}
|
}
|
||||||
g_clear_object (&self->priv->qmi);
|
g_clear_object (&self->priv->qmi);
|
||||||
}
|
}
|
||||||
|
@@ -8651,7 +8651,7 @@ dispose (GObject *object)
|
|||||||
untrack_qmi_device_removed (self, qmi);
|
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 (mm_port_qmi_is_open (qmi))
|
if (mm_port_qmi_is_open (qmi))
|
||||||
mm_port_qmi_close (qmi);
|
mm_port_qmi_close (qmi, NULL, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
g_list_free_full (self->priv->firmware_list, g_object_unref);
|
g_list_free_full (self->priv->firmware_list, g_object_unref);
|
||||||
|
@@ -435,8 +435,8 @@ port_probe_run_context_free (PortProbeRunContext *ctx)
|
|||||||
|
|
||||||
#if defined WITH_QMI
|
#if defined WITH_QMI
|
||||||
if (ctx->port_qmi) {
|
if (ctx->port_qmi) {
|
||||||
if (mm_port_qmi_is_open (ctx->port_qmi))
|
/* We should have closed it cleanly before */
|
||||||
mm_port_qmi_close (ctx->port_qmi);
|
g_assert (!mm_port_qmi_is_open (ctx->port_qmi));
|
||||||
g_object_unref (ctx->port_qmi);
|
g_object_unref (ctx->port_qmi);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@@ -464,6 +464,22 @@ static gboolean wdm_probe (MMPortProbe *self);
|
|||||||
|
|
||||||
#if defined WITH_QMI
|
#if defined WITH_QMI
|
||||||
|
|
||||||
|
static void
|
||||||
|
qmi_port_close_ready (MMPortQmi *qmi_port,
|
||||||
|
GAsyncResult *res,
|
||||||
|
MMPortProbe *self)
|
||||||
|
{
|
||||||
|
PortProbeRunContext *ctx;
|
||||||
|
|
||||||
|
g_assert (self->priv->task);
|
||||||
|
ctx = g_task_get_task_data (self->priv->task);
|
||||||
|
|
||||||
|
mm_port_qmi_close_finish (qmi_port, res, NULL);
|
||||||
|
|
||||||
|
/* Keep on */
|
||||||
|
ctx->source_id = g_idle_add ((GSourceFunc) wdm_probe, self);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
port_qmi_open_ready (MMPortQmi *port_qmi,
|
port_qmi_open_ready (MMPortQmi *port_qmi,
|
||||||
GAsyncResult *res,
|
GAsyncResult *res,
|
||||||
@@ -487,10 +503,10 @@ port_qmi_open_ready (MMPortQmi *port_qmi,
|
|||||||
|
|
||||||
/* Set probing result */
|
/* Set probing result */
|
||||||
mm_port_probe_set_result_qmi (self, is_qmi);
|
mm_port_probe_set_result_qmi (self, is_qmi);
|
||||||
mm_port_qmi_close (port_qmi);
|
|
||||||
|
|
||||||
/* Keep on */
|
mm_port_qmi_close (ctx->port_qmi,
|
||||||
ctx->source_id = g_idle_add ((GSourceFunc) wdm_probe, self);
|
(GAsyncReadyCallback) qmi_port_close_ready,
|
||||||
|
self);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* WITH_QMI */
|
#endif /* WITH_QMI */
|
||||||
|
@@ -33,7 +33,7 @@ typedef struct {
|
|||||||
} ServiceInfo;
|
} ServiceInfo;
|
||||||
|
|
||||||
struct _MMPortQmiPrivate {
|
struct _MMPortQmiPrivate {
|
||||||
gboolean opening;
|
gboolean in_progress;
|
||||||
QmiDevice *qmi_device;
|
QmiDevice *qmi_device;
|
||||||
GList *services;
|
GList *services;
|
||||||
gboolean llp_is_raw_ip;
|
gboolean llp_is_raw_ip;
|
||||||
@@ -244,7 +244,7 @@ port_open_complete_with_error (GTask *task)
|
|||||||
ctx = g_task_get_task_data (task);
|
ctx = g_task_get_task_data (task);
|
||||||
|
|
||||||
g_assert (ctx->error);
|
g_assert (ctx->error);
|
||||||
self->priv->opening = FALSE;
|
self->priv->in_progress = FALSE;
|
||||||
g_task_return_error (task, g_steal_pointer (&ctx->error));
|
g_task_return_error (task, g_steal_pointer (&ctx->error));
|
||||||
g_object_unref (task);
|
g_object_unref (task);
|
||||||
}
|
}
|
||||||
@@ -401,11 +401,11 @@ port_open_step (GTask *task)
|
|||||||
|
|
||||||
case PORT_OPEN_STEP_CHECK_OPENING:
|
case PORT_OPEN_STEP_CHECK_OPENING:
|
||||||
mm_dbg ("Checking if QMI device already opening...");
|
mm_dbg ("Checking if QMI device already opening...");
|
||||||
if (self->priv->opening) {
|
if (self->priv->in_progress) {
|
||||||
g_task_return_new_error (task,
|
g_task_return_new_error (task,
|
||||||
MM_CORE_ERROR,
|
MM_CORE_ERROR,
|
||||||
MM_CORE_ERROR_IN_PROGRESS,
|
MM_CORE_ERROR_IN_PROGRESS,
|
||||||
"QMI device already being opened");
|
"QMI device open/close operation in progress");
|
||||||
g_object_unref (task);
|
g_object_unref (task);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -432,7 +432,7 @@ port_open_step (GTask *task)
|
|||||||
/* We flag in this point that we're opening. From now on, if we stop
|
/* We flag in this point that we're opening. From now on, if we stop
|
||||||
* for whatever reason, we should clear this flag. We do this by ensuring
|
* for whatever reason, we should clear this flag. We do this by ensuring
|
||||||
* that all callbacks go through the LAST step for completing. */
|
* that all callbacks go through the LAST step for completing. */
|
||||||
self->priv->opening = TRUE;
|
self->priv->in_progress = TRUE;
|
||||||
|
|
||||||
mm_dbg ("Creating QMI device...");
|
mm_dbg ("Creating QMI device...");
|
||||||
qmi_device_new (file,
|
qmi_device_new (file,
|
||||||
@@ -585,8 +585,8 @@ port_open_step (GTask *task)
|
|||||||
/* Store device in private info */
|
/* Store device in private info */
|
||||||
g_assert (ctx->device);
|
g_assert (ctx->device);
|
||||||
g_assert (!self->priv->qmi_device);
|
g_assert (!self->priv->qmi_device);
|
||||||
self->priv->qmi_device = g_steal_pointer (&ctx->device);
|
self->priv->qmi_device = g_object_ref (ctx->device);
|
||||||
self->priv->opening = FALSE;
|
self->priv->in_progress = FALSE;
|
||||||
g_task_return_boolean (task, TRUE);
|
g_task_return_boolean (task, TRUE);
|
||||||
g_object_unref (task);
|
g_object_unref (task);
|
||||||
return;
|
return;
|
||||||
@@ -617,6 +617,8 @@ mm_port_qmi_open (MMPortQmi *self,
|
|||||||
port_open_step (task);
|
port_open_step (task);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*****************************************************************************/
|
||||||
|
|
||||||
gboolean
|
gboolean
|
||||||
mm_port_qmi_is_open (MMPortQmi *self)
|
mm_port_qmi_is_open (MMPortQmi *self)
|
||||||
{
|
{
|
||||||
@@ -625,23 +627,88 @@ mm_port_qmi_is_open (MMPortQmi *self)
|
|||||||
return !!self->priv->qmi_device;
|
return !!self->priv->qmi_device;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
/*****************************************************************************/
|
||||||
mm_port_qmi_close (MMPortQmi *self)
|
|
||||||
|
typedef struct {
|
||||||
|
QmiDevice *qmi_device;
|
||||||
|
} PortQmiCloseContext;
|
||||||
|
|
||||||
|
static void
|
||||||
|
port_qmi_close_context_free (PortQmiCloseContext *ctx)
|
||||||
{
|
{
|
||||||
GList *l;
|
g_clear_object (&ctx->qmi_device);
|
||||||
GError *error = NULL;
|
g_slice_free (PortQmiCloseContext, ctx);
|
||||||
|
}
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
mm_port_qmi_close_finish (MMPortQmi *self,
|
||||||
|
GAsyncResult *res,
|
||||||
|
GError **error)
|
||||||
|
{
|
||||||
|
return g_task_propagate_boolean (G_TASK (res), error);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
qmi_device_close_ready (QmiDevice *qmi_device,
|
||||||
|
GAsyncResult *res,
|
||||||
|
GTask *task)
|
||||||
|
{
|
||||||
|
GError *error = NULL;
|
||||||
|
MMPortQmi *self;
|
||||||
|
|
||||||
|
self = g_task_get_source_object (task);
|
||||||
|
|
||||||
|
g_assert (!self->priv->qmi_device);
|
||||||
|
self->priv->in_progress = FALSE;
|
||||||
|
|
||||||
|
if (!qmi_device_close_finish (qmi_device, res, &error))
|
||||||
|
g_task_return_error (task, error);
|
||||||
|
else
|
||||||
|
g_task_return_boolean (task, TRUE);
|
||||||
|
g_object_unref (task);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
mm_port_qmi_close (MMPortQmi *self,
|
||||||
|
GAsyncReadyCallback callback,
|
||||||
|
gpointer user_data)
|
||||||
|
{
|
||||||
|
PortQmiCloseContext *ctx;
|
||||||
|
GTask *task;
|
||||||
|
GList *l;
|
||||||
|
|
||||||
g_return_if_fail (MM_IS_PORT_QMI (self));
|
g_return_if_fail (MM_IS_PORT_QMI (self));
|
||||||
|
|
||||||
if (!self->priv->qmi_device)
|
task = g_task_new (self, NULL, callback, user_data);
|
||||||
|
|
||||||
|
if (self->priv->in_progress) {
|
||||||
|
g_task_return_new_error (task,
|
||||||
|
MM_CORE_ERROR,
|
||||||
|
MM_CORE_ERROR_IN_PROGRESS,
|
||||||
|
"QMI device open/close operation in progress");
|
||||||
|
g_object_unref (task);
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!self->priv->qmi_device) {
|
||||||
|
g_task_return_boolean (task, TRUE);
|
||||||
|
g_object_unref (task);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
self->priv->in_progress = TRUE;
|
||||||
|
|
||||||
|
/* Store device to close in the context */
|
||||||
|
ctx = g_slice_new0 (PortQmiCloseContext);
|
||||||
|
ctx->qmi_device = g_steal_pointer (&self->priv->qmi_device);
|
||||||
|
g_task_set_task_data (task, ctx, (GDestroyNotify)port_qmi_close_context_free);
|
||||||
|
|
||||||
/* Release all allocated clients */
|
/* Release all allocated clients */
|
||||||
for (l = self->priv->services; l; l = g_list_next (l)) {
|
for (l = self->priv->services; l; l = g_list_next (l)) {
|
||||||
ServiceInfo *info = l->data;
|
ServiceInfo *info = l->data;
|
||||||
|
|
||||||
mm_dbg ("Releasing client for service '%s'...", qmi_service_get_string (info->service));
|
mm_dbg ("Releasing client for service '%s'...", qmi_service_get_string (info->service));
|
||||||
qmi_device_release_client (self->priv->qmi_device,
|
qmi_device_release_client (ctx->qmi_device,
|
||||||
info->client,
|
info->client,
|
||||||
QMI_DEVICE_RELEASE_CLIENT_FLAGS_RELEASE_CID,
|
QMI_DEVICE_RELEASE_CLIENT_FLAGS_RELEASE_CID,
|
||||||
3, NULL, NULL, NULL);
|
3, NULL, NULL, NULL);
|
||||||
@@ -650,14 +717,11 @@ mm_port_qmi_close (MMPortQmi *self)
|
|||||||
g_list_free_full (self->priv->services, g_free);
|
g_list_free_full (self->priv->services, g_free);
|
||||||
self->priv->services = NULL;
|
self->priv->services = NULL;
|
||||||
|
|
||||||
/* Close and release the device */
|
qmi_device_close_async (ctx->qmi_device,
|
||||||
if (!qmi_device_close (self->priv->qmi_device, &error)) {
|
5,
|
||||||
mm_warn ("Couldn't properly close QMI device: %s",
|
NULL,
|
||||||
error->message);
|
(GAsyncReadyCallback)qmi_device_close_ready,
|
||||||
g_error_free (error);
|
task);
|
||||||
}
|
|
||||||
|
|
||||||
g_clear_object (&self->priv->qmi_device);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
@@ -48,16 +48,21 @@ GType mm_port_qmi_get_type (void);
|
|||||||
|
|
||||||
MMPortQmi *mm_port_qmi_new (const gchar *name);
|
MMPortQmi *mm_port_qmi_new (const gchar *name);
|
||||||
|
|
||||||
void mm_port_qmi_open (MMPortQmi *self,
|
void mm_port_qmi_open (MMPortQmi *self,
|
||||||
gboolean set_data_format,
|
gboolean set_data_format,
|
||||||
GCancellable *cancellable,
|
GCancellable *cancellable,
|
||||||
GAsyncReadyCallback callback,
|
GAsyncReadyCallback callback,
|
||||||
gpointer user_data);
|
gpointer user_data);
|
||||||
gboolean mm_port_qmi_open_finish (MMPortQmi *self,
|
gboolean mm_port_qmi_open_finish (MMPortQmi *self,
|
||||||
GAsyncResult *res,
|
GAsyncResult *res,
|
||||||
GError **error);
|
GError **error);
|
||||||
gboolean mm_port_qmi_is_open (MMPortQmi *self);
|
gboolean mm_port_qmi_is_open (MMPortQmi *self);
|
||||||
void mm_port_qmi_close (MMPortQmi *self);
|
void mm_port_qmi_close (MMPortQmi *self,
|
||||||
|
GAsyncReadyCallback callback,
|
||||||
|
gpointer user_data);
|
||||||
|
gboolean mm_port_qmi_close_finish (MMPortQmi *self,
|
||||||
|
GAsyncResult *res,
|
||||||
|
GError **error);
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
MM_PORT_QMI_FLAG_DEFAULT = 0,
|
MM_PORT_QMI_FLAG_DEFAULT = 0,
|
||||||
|
Reference in New Issue
Block a user