broadband-modem-qmi: ignore our own profile changed indications

The device may emit a "WDS Profile Changed" indication triggered from
our own "WDS Modify Profile", "WDS Create Profile" or "WDS Delete
Profile" operations, so ensure those are fully ignored so that we
don't emit the "Updated" signal in the ProfileManager interface.

The logic keeps track of the amount of concurrent operations so that
the signal is ignored for as long as there is at least one operation
running.

Fixes https://gitlab.freedesktop.org/mobile-broadband/ModemManager/-/issues/687
This commit is contained in:
Aleksander Morgado
2023-01-11 08:43:27 +00:00
committed by Aleksander Morgado
parent e3667ecb56
commit cc78a6439f
+43 -2
View File
@@ -176,6 +176,7 @@ struct _MMBroadbandModemQmiPrivate {
/* WDS Profile changed notification ID (3gpp Profile Manager) */
guint profile_changed_indication_id;
gint profile_changed_indication_ignored;
/* PS registration helpers when using NAS System Info and DSD
* (not applicable when using NAS Serving System) */
@@ -6052,6 +6053,9 @@ modem_3gpp_profile_manager_list_profiles (MMIfaceModem3gppProfileManager *self,
/*****************************************************************************/
/* Store profile (3GPP profile management interface) */
static void profile_changed_indication_ignore (MMBroadbandModemQmi *self,
gboolean ignore);
typedef struct {
QmiClientWds *client;
gint profile_id;
@@ -6107,6 +6111,7 @@ modify_profile_ready (QmiClientWds *client,
g_autoptr(QmiMessageWdsModifyProfileOutput) output = NULL;
self = g_task_get_source_object (task);
profile_changed_indication_ignore (self, FALSE);
output = qmi_client_wds_modify_profile_finish (client, res, &error);
if (!output) {
@@ -6147,8 +6152,9 @@ create_profile_ready (QmiClientWds *client,
guint8 profile_index;
g_autoptr(QmiMessageWdsCreateProfileOutput) output = NULL;
self = g_task_get_source_object (task);
ctx = g_task_get_task_data (task);
self = g_task_get_source_object (task);
profile_changed_indication_ignore (self, FALSE);
output = qmi_client_wds_create_profile_finish (client, res, &error);
if (!output) {
@@ -6205,6 +6211,7 @@ store_profile_run (GTask *task)
if (!self->priv->apn_type_not_supported)
qmi_message_wds_create_profile_input_set_apn_type_mask (input, ctx->qmi_apn_type, NULL);
profile_changed_indication_ignore (self, TRUE);
qmi_client_wds_create_profile (ctx->client,
input,
10,
@@ -6225,6 +6232,7 @@ store_profile_run (GTask *task)
if (!self->priv->apn_type_not_supported)
qmi_message_wds_modify_profile_input_set_apn_type_mask (input, ctx->qmi_apn_type, NULL);
profile_changed_indication_ignore (self, TRUE);
qmi_client_wds_modify_profile (ctx->client,
input,
10,
@@ -6314,9 +6322,13 @@ delete_profile_ready (QmiClientWds *client,
GAsyncResult *res,
GTask *task)
{
GError *error = NULL;
MMBroadbandModemQmi *self;
GError *error = NULL;
g_autoptr(QmiMessageWdsDeleteProfileOutput) output = NULL;
self = g_task_get_source_object (task);
profile_changed_indication_ignore (self, FALSE);
output = qmi_client_wds_delete_profile_finish (client, res, &error);
if (!output || !qmi_message_wds_delete_profile_output_get_result (output, &error)) {
g_prefix_error (&error, "Couldn't delete profile: ");
@@ -6355,6 +6367,7 @@ modem_3gpp_profile_manager_delete_profile (MMIfaceModem3gppProfileManager *self,
input = qmi_message_wds_delete_profile_input_new ();
qmi_message_wds_delete_profile_input_set_profile_identifier (input, QMI_WDS_PROFILE_TYPE_3GPP, profile_id, NULL);
profile_changed_indication_ignore (MM_BROADBAND_MODEM_QMI (self), TRUE);
qmi_client_wds_delete_profile (QMI_CLIENT_WDS (client),
input,
10,
@@ -6383,10 +6396,38 @@ profile_changed_indication_received (QmiClientWds *clien
QmiIndicationWdsProfileChangedOutput *output,
MMBroadbandModemQmi *self)
{
if (self->priv->profile_changed_indication_ignored > 0) {
mm_obj_dbg (self, "profile changed indication ignored");
return;
}
mm_obj_dbg (self, "profile changed indication was received");
mm_iface_modem_3gpp_profile_manager_updated (MM_IFACE_MODEM_3GPP_PROFILE_MANAGER (self));
}
static void
profile_changed_indication_ignore (MMBroadbandModemQmi *self,
gboolean ignore)
{
/* Note: multiple concurrent profile create/update/deletes may be happening,
* so ensure the indication ignore logic applies as long as at least one
* operation is ongoing. */
if (ignore) {
g_assert_cmpint (self->priv->profile_changed_indication_ignored, >=, 0);
self->priv->profile_changed_indication_ignored++;
mm_obj_dbg (self, "ignoring profile update indications during our own operations (%d ongoing)",
self->priv->profile_changed_indication_ignored);
} else {
g_assert_cmpint (self->priv->profile_changed_indication_ignored, >, 0);
self->priv->profile_changed_indication_ignored--;
if (self->priv->profile_changed_indication_ignored > 0)
mm_obj_dbg (self, "still ignoring profile update indications during our own operations (%d ongoing)",
self->priv->profile_changed_indication_ignored);
else
mm_obj_dbg (self, "no longer ignoring profile update indications during our own operations");
}
}
/*****************************************************************************/
/* Enable/Disable unsolicited events (3gppProfileManager interface) */