broadband-modem-qmi: switch USSD state to idle when ussd session is terminated by network

The cellular operator can break the interactive USSD session. In this case, it is necessary
to process this situation otherwise --3gpp-ussd-initiate or --3gpp-ussd-respond will give an error.

Signed-off-by: Maxim Anisimov <maxim.anisimov.ua@gmail.com>
This commit is contained in:
Maxim Anisimov
2020-06-05 08:57:48 +03:00
committed by Aleksander Morgado
parent 62c6f941a2
commit 3af93cbe18

View File

@@ -128,6 +128,7 @@ struct _MMBroadbandModemQmiPrivate {
/* 3GPP USSD helpers */
guint ussd_indication_id;
guint ussd_release_indication_id;
gboolean ussd_unsolicited_events_enabled;
gboolean ussd_unsolicited_events_setup;
GTask *pending_ussd_action;
@@ -7314,6 +7315,30 @@ ussd_indication_cb (QmiClientVoice *client,
process_ussd_message (self, user_action, utf8, error);
}
static void
ussd_release_indication_cb (QmiClientVoice *client,
MMBroadbandModemQmi *self)
{
GTask *pending_task;
GError *error;
mm_iface_modem_3gpp_ussd_update_state (MM_IFACE_MODEM_3GPP_USSD (self),
MM_MODEM_3GPP_USSD_SESSION_STATE_IDLE);
error = g_error_new (MM_CORE_ERROR, MM_CORE_ERROR_ABORTED, "USSD terminated by network");
pending_task = g_steal_pointer (&self->priv->pending_ussd_action);
if (pending_task) {
g_task_return_error (pending_task, error);
g_object_unref (pending_task);
return;
}
/* If no pending task, just report the error */
mm_obj_dbg (self, "USSD release indication: %s", error->message);
g_error_free (error);
}
/*****************************************************************************/
/* Setup/cleanup unsolicited events */
@@ -7357,10 +7382,19 @@ common_3gpp_ussd_setup_cleanup_unsolicited_events (MMBroadbandModemQmi *self,
"ussd",
G_CALLBACK (ussd_indication_cb),
self);
g_assert (self->priv->ussd_release_indication_id == 0);
self->priv->ussd_release_indication_id =
g_signal_connect (client,
"release-ussd",
G_CALLBACK (ussd_release_indication_cb),
self);
} else {
g_assert (self->priv->ussd_indication_id != 0);
g_signal_handler_disconnect (client, self->priv->ussd_indication_id);
self->priv->ussd_indication_id = 0;
g_assert (self->priv->ussd_release_indication_id != 0);
g_signal_handler_disconnect (client, self->priv->ussd_release_indication_id);
self->priv->ussd_release_indication_id = 0;
}
g_task_return_boolean (task, TRUE);