diff options
author | Aleksander Morgado <aleksandermj@chromium.org> | 2023-03-22 11:35:37 +0000 |
---|---|---|
committer | Aleksander Morgado <aleksander@aleksander.es> | 2023-03-22 17:42:28 +0000 |
commit | f96664a159ebcff922e7d9fad170deefe65d1762 (patch) | |
tree | b6030741b42afbdf1b0c6e12c3d19d6c7cc813fc /src | |
parent | 1b2a2471fdf3a8f706c24439f5b1c93f67430a01 (diff) |
broadband-modem-qmi: ignore profile updates during 100ms after our own updates
Diffstat (limited to 'src')
-rw-r--r-- | src/mm-broadband-modem-qmi.c | 115 |
1 files changed, 92 insertions, 23 deletions
diff --git a/src/mm-broadband-modem-qmi.c b/src/mm-broadband-modem-qmi.c index ee4a97b5..49edd8b2 100644 --- a/src/mm-broadband-modem-qmi.c +++ b/src/mm-broadband-modem-qmi.c @@ -6506,6 +6506,8 @@ modem_3gpp_profile_manager_list_profiles (MMIfaceModem3gppProfileManager *self, /*****************************************************************************/ /* Store profile (3GPP profile management interface) */ +#define IGNORED_PROFILE_CHANGED_INDICATION_TIMEOUT_MS 100 + static void profile_changed_indication_ignore (MMBroadbandModemQmi *self, gboolean ignore); @@ -6552,6 +6554,44 @@ modem_3gpp_profile_manager_store_profile_finish (MMIfaceModem3gppProfileManager return TRUE; } +static gboolean +store_profile_complete_wait (GTask *task) +{ + MMBroadbandModemQmi *self; + + self = g_task_get_source_object (task); + + /* On a successful operation, we were still ignoring the indications */ + profile_changed_indication_ignore (self, FALSE); + g_task_return_boolean (task, TRUE); + g_object_unref (task); + + return G_SOURCE_REMOVE; +} + +static void +store_profile_complete (GTask *task, + GError *error) +{ + MMBroadbandModemQmi *self; + + self = g_task_get_source_object (task); + + if (error) { + /* On operation failure, we don't expect further profile update + * indications, so we can safely stop ignoring them and return + * the error without delay. */ + profile_changed_indication_ignore (self, FALSE); + g_task_return_error (task, error); + g_object_unref (task); + return; + } + + g_timeout_add (IGNORED_PROFILE_CHANGED_INDICATION_TIMEOUT_MS, + (GSourceFunc) store_profile_complete_wait, + task); +} + static void store_profile_run (GTask *task); static void @@ -6564,12 +6604,14 @@ 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) { - g_task_return_error (task, error); - } else if (!qmi_message_wds_modify_profile_output_get_result (output, &error)) { + store_profile_complete (task, error); + return; + } + + if (!qmi_message_wds_modify_profile_output_get_result (output, &error)) { QmiWdsDsProfileError ds_profile_error; if (g_error_matches (error, QMI_PROTOCOL_ERROR, QMI_PROTOCOL_ERROR_INVALID_PROFILE_TYPE) && @@ -6582,16 +6624,18 @@ modify_profile_ready (QmiClientWds *client, store_profile_run (task); return; } + if (g_error_matches (error, QMI_PROTOCOL_ERROR, QMI_PROTOCOL_ERROR_EXTENDED_INTERNAL) && qmi_message_wds_modify_profile_output_get_extended_error_code (output, &ds_profile_error, NULL)) { g_prefix_error (&error, "DS profile error: %s: ", qmi_wds_ds_profile_error_get_string (ds_profile_error)); } g_prefix_error (&error, "Couldn't modify profile: "); - g_task_return_error (task, error); - } else { - g_task_return_boolean (task, TRUE); + store_profile_complete (task, error); + return; } - g_object_unref (task); + + /* success */ + store_profile_complete (task, NULL); } static void @@ -6607,12 +6651,14 @@ create_profile_ready (QmiClientWds *client, 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) { - g_task_return_error (task, error); - } else if (!qmi_message_wds_create_profile_output_get_result (output, &error)) { + store_profile_complete (task, error); + return; + } + + if (!qmi_message_wds_create_profile_output_get_result (output, &error)) { QmiWdsDsProfileError ds_profile_error; if (g_error_matches (error, QMI_PROTOCOL_ERROR, QMI_PROTOCOL_ERROR_INVALID_PROFILE_TYPE) && @@ -6625,19 +6671,24 @@ create_profile_ready (QmiClientWds *client, store_profile_run (task); return; } + if (g_error_matches (error, QMI_PROTOCOL_ERROR, QMI_PROTOCOL_ERROR_EXTENDED_INTERNAL) && qmi_message_wds_create_profile_output_get_extended_error_code (output, &ds_profile_error, NULL)) { g_prefix_error (&error, "DS profile error: %s: ", qmi_wds_ds_profile_error_get_string (ds_profile_error)); } g_prefix_error (&error, "Couldn't create profile: "); - g_task_return_error (task, error); - } else if (!qmi_message_wds_create_profile_output_get_profile_identifier (output, NULL, &profile_index, &error)) { - g_task_return_error (task, error); - } else { - ctx->profile_id = profile_index; - g_task_return_boolean (task, TRUE); + store_profile_complete (task, error); + return; } - g_object_unref (task); + + if (!qmi_message_wds_create_profile_output_get_profile_identifier (output, NULL, &profile_index, &error)) { + store_profile_complete (task, error); + return; + } + + /* success */ + ctx->profile_id = profile_index; + store_profile_complete (task, NULL); } static void @@ -6664,7 +6715,6 @@ 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, @@ -6685,7 +6735,6 @@ 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, @@ -6756,6 +6805,7 @@ modem_3gpp_profile_manager_store_profile (MMIfaceModem3gppProfileManager *self, return; } + profile_changed_indication_ignore (MM_BROADBAND_MODEM_QMI (self), TRUE); store_profile_run (task); } @@ -6770,6 +6820,21 @@ modem_3gpp_profile_manager_delete_profile_finish (MMIfaceModem3gppProfileManager return g_task_propagate_boolean (G_TASK (res), error); } +static gboolean +delete_profile_complete_wait (GTask *task) +{ + MMBroadbandModemQmi *self; + + self = g_task_get_source_object (task); + + /* On a successful operation, we were still ignoring the indications */ + profile_changed_indication_ignore (self, FALSE); + g_task_return_boolean (task, TRUE); + g_object_unref (task); + + return G_SOURCE_REMOVE; +} + static void delete_profile_ready (QmiClientWds *client, GAsyncResult *res, @@ -6780,15 +6845,19 @@ delete_profile_ready (QmiClientWds *client, 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)) { + profile_changed_indication_ignore (self, FALSE); g_prefix_error (&error, "Couldn't delete profile: "); g_task_return_error (task, error); - } else - g_task_return_boolean (task, TRUE); - g_object_unref (task); + g_object_unref (task); + return; + } + + g_timeout_add (IGNORED_PROFILE_CHANGED_INDICATION_TIMEOUT_MS, + (GSourceFunc) delete_profile_complete_wait, + task); } static void |