broadband-modem-qmi: disable profile changed indications during our operations
Just ignoring the received indications is not enough, because they could arrive after the operation response has been processed. We now explicitly disable the indications by reconfiguring the modem before and after every profile update operation triggered by our own logic.
This commit is contained in:

committed by
Aleksander Morgado

parent
4903a1ed74
commit
dad3e82747
@@ -176,6 +176,7 @@ struct _MMBroadbandModemQmiPrivate {
|
|||||||
|
|
||||||
/* WDS Profile changed notification ID (3gpp Profile Manager) */
|
/* WDS Profile changed notification ID (3gpp Profile Manager) */
|
||||||
guint profile_changed_indication_id;
|
guint profile_changed_indication_id;
|
||||||
|
gint profile_changed_indication_enabled;
|
||||||
gint profile_changed_indication_ignored;
|
gint profile_changed_indication_ignored;
|
||||||
|
|
||||||
/* PS registration helpers when using NAS System Info and DSD
|
/* PS registration helpers when using NAS System Info and DSD
|
||||||
@@ -6503,12 +6504,130 @@ modem_3gpp_profile_manager_list_profiles (MMIfaceModem3gppProfileManager *self,
|
|||||||
task);
|
task);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************/
|
||||||
|
/* Enable/Disable/Ignore profile changed events (3gppProfileManager interface) */
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
profile_changed_indication_configure_finish (MMBroadbandModemQmi *self,
|
||||||
|
GAsyncResult *res,
|
||||||
|
GError **error)
|
||||||
|
{
|
||||||
|
return g_task_propagate_boolean (G_TASK (res), error);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
register_wds_profile_change_ready (QmiClientWds *client,
|
||||||
|
GAsyncResult *res,
|
||||||
|
GTask *task)
|
||||||
|
{
|
||||||
|
g_autoptr(QmiMessageWdsIndicationRegisterOutput) output = NULL;
|
||||||
|
GError *error = NULL;
|
||||||
|
|
||||||
|
output = qmi_client_wds_indication_register_finish (client, res, &error);
|
||||||
|
if (!output || !qmi_message_wds_indication_register_output_get_result (output, &error))
|
||||||
|
g_task_return_error (task, error);
|
||||||
|
else
|
||||||
|
g_task_return_boolean (task, TRUE);
|
||||||
|
g_object_unref (task);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
profile_changed_indication_configure (MMBroadbandModemQmi *self,
|
||||||
|
QmiClientWds *client,
|
||||||
|
gboolean state_needed,
|
||||||
|
GTask *task)
|
||||||
|
{
|
||||||
|
g_autoptr(QmiMessageWdsIndicationRegisterInput) input = NULL;
|
||||||
|
|
||||||
|
input = qmi_message_wds_indication_register_input_new ();
|
||||||
|
qmi_message_wds_indication_register_input_set_report_profile_changes (input, state_needed, NULL);
|
||||||
|
qmi_client_wds_indication_register (client,
|
||||||
|
input,
|
||||||
|
10,
|
||||||
|
NULL,
|
||||||
|
(GAsyncReadyCallback) register_wds_profile_change_ready,
|
||||||
|
task);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
profile_changed_indication_configure_ignore (MMBroadbandModemQmi *self,
|
||||||
|
QmiClientWds *client,
|
||||||
|
gboolean ignore,
|
||||||
|
GAsyncReadyCallback callback,
|
||||||
|
gpointer user_data)
|
||||||
|
{
|
||||||
|
GTask *task;
|
||||||
|
gboolean state_needed_before;
|
||||||
|
gboolean state_needed_after;
|
||||||
|
|
||||||
|
task = g_task_new (self, NULL, callback, user_data);
|
||||||
|
|
||||||
|
state_needed_before = (self->priv->profile_changed_indication_enabled &&
|
||||||
|
self->priv->profile_changed_indication_ignored == 0);
|
||||||
|
|
||||||
|
/* 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, "ignore 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");
|
||||||
|
}
|
||||||
|
|
||||||
|
state_needed_after = (self->priv->profile_changed_indication_enabled &&
|
||||||
|
self->priv->profile_changed_indication_ignored == 0);
|
||||||
|
|
||||||
|
if (state_needed_before == state_needed_after) {
|
||||||
|
g_task_return_boolean (task, TRUE);
|
||||||
|
g_object_unref (task);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
profile_changed_indication_configure (self, client, state_needed_after, task);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
profile_changed_indication_configure_enable (MMBroadbandModemQmi *self,
|
||||||
|
QmiClientWds *client,
|
||||||
|
gboolean enable,
|
||||||
|
GAsyncReadyCallback callback,
|
||||||
|
gpointer user_data)
|
||||||
|
{
|
||||||
|
GTask *task;
|
||||||
|
gboolean state_needed_before;
|
||||||
|
gboolean state_needed_after;
|
||||||
|
|
||||||
|
task = g_task_new (self, NULL, callback, user_data);
|
||||||
|
|
||||||
|
state_needed_before = (self->priv->profile_changed_indication_enabled &&
|
||||||
|
self->priv->profile_changed_indication_ignored == 0);
|
||||||
|
|
||||||
|
self->priv->profile_changed_indication_enabled = enable;
|
||||||
|
|
||||||
|
state_needed_after = (self->priv->profile_changed_indication_enabled &&
|
||||||
|
self->priv->profile_changed_indication_ignored == 0);
|
||||||
|
|
||||||
|
if (state_needed_before == state_needed_after) {
|
||||||
|
g_task_return_boolean (task, TRUE);
|
||||||
|
g_object_unref (task);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
profile_changed_indication_configure (self, client, state_needed_after, task);
|
||||||
|
}
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
/* Store profile (3GPP profile management interface) */
|
/* Store profile (3GPP profile management interface) */
|
||||||
|
|
||||||
static void profile_changed_indication_ignore (MMBroadbandModemQmi *self,
|
|
||||||
gboolean ignore);
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
QmiClientWds *client;
|
QmiClientWds *client;
|
||||||
gint profile_id;
|
gint profile_id;
|
||||||
@@ -6519,11 +6638,13 @@ typedef struct {
|
|||||||
QmiWdsApnTypeMask qmi_apn_type;
|
QmiWdsApnTypeMask qmi_apn_type;
|
||||||
QmiWdsAuthentication qmi_auth;
|
QmiWdsAuthentication qmi_auth;
|
||||||
QmiWdsPdpType qmi_pdp_type;
|
QmiWdsPdpType qmi_pdp_type;
|
||||||
|
GError *saved_error;
|
||||||
} StoreProfileContext;
|
} StoreProfileContext;
|
||||||
|
|
||||||
static void
|
static void
|
||||||
store_profile_context_free (StoreProfileContext *ctx)
|
store_profile_context_free (StoreProfileContext *ctx)
|
||||||
{
|
{
|
||||||
|
g_assert (!ctx->saved_error);
|
||||||
g_free (ctx->profile_name);
|
g_free (ctx->profile_name);
|
||||||
g_free (ctx->apn);
|
g_free (ctx->apn);
|
||||||
g_free (ctx->user);
|
g_free (ctx->user);
|
||||||
@@ -6552,6 +6673,46 @@ modem_3gpp_profile_manager_store_profile_finish (MMIfaceModem3gppProfileManager
|
|||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
profile_changed_indication_configure_after_store_ready (MMBroadbandModemQmi *self,
|
||||||
|
GAsyncResult *res,
|
||||||
|
GTask *task)
|
||||||
|
{
|
||||||
|
StoreProfileContext *ctx;
|
||||||
|
g_autoptr(GError) error = NULL;
|
||||||
|
|
||||||
|
ctx = g_task_get_task_data (task);
|
||||||
|
|
||||||
|
if (!profile_changed_indication_configure_finish (self, res, &error))
|
||||||
|
mm_obj_warn (self, "Couldn't configure profile change indications after store operation: %s", error->message);
|
||||||
|
|
||||||
|
if (ctx->saved_error)
|
||||||
|
g_task_return_error (task, g_steal_pointer (&ctx->saved_error));
|
||||||
|
else
|
||||||
|
g_task_return_boolean (task, TRUE);
|
||||||
|
g_object_unref (task);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
store_profile_complete (GTask *task,
|
||||||
|
GError *error)
|
||||||
|
{
|
||||||
|
MMBroadbandModemQmi *self;
|
||||||
|
StoreProfileContext *ctx;
|
||||||
|
|
||||||
|
self = g_task_get_source_object (task);
|
||||||
|
ctx = g_task_get_task_data (task);
|
||||||
|
|
||||||
|
ctx->saved_error = error;
|
||||||
|
|
||||||
|
profile_changed_indication_configure_ignore (
|
||||||
|
self,
|
||||||
|
ctx->client,
|
||||||
|
FALSE,
|
||||||
|
(GAsyncReadyCallback) profile_changed_indication_configure_after_store_ready,
|
||||||
|
task);
|
||||||
|
}
|
||||||
|
|
||||||
static void store_profile_run (GTask *task);
|
static void store_profile_run (GTask *task);
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@@ -6559,17 +6720,14 @@ modify_profile_ready (QmiClientWds *client,
|
|||||||
GAsyncResult *res,
|
GAsyncResult *res,
|
||||||
GTask *task)
|
GTask *task)
|
||||||
{
|
{
|
||||||
MMBroadbandModemQmi *self;
|
MMBroadbandModemQmi *self;
|
||||||
GError *error = NULL;
|
g_autoptr(GError) error = NULL;
|
||||||
g_autoptr(QmiMessageWdsModifyProfileOutput) output = NULL;
|
g_autoptr(QmiMessageWdsModifyProfileOutput) output = NULL;
|
||||||
|
|
||||||
self = g_task_get_source_object (task);
|
self = g_task_get_source_object (task);
|
||||||
profile_changed_indication_ignore (self, FALSE);
|
|
||||||
|
|
||||||
output = qmi_client_wds_modify_profile_finish (client, res, &error);
|
output = qmi_client_wds_modify_profile_finish (client, res, &error);
|
||||||
if (!output) {
|
if (output && !qmi_message_wds_modify_profile_output_get_result (output, &error)) {
|
||||||
g_task_return_error (task, error);
|
|
||||||
} else if (!qmi_message_wds_modify_profile_output_get_result (output, &error)) {
|
|
||||||
QmiWdsDsProfileError ds_profile_error;
|
QmiWdsDsProfileError ds_profile_error;
|
||||||
|
|
||||||
if (g_error_matches (error, QMI_PROTOCOL_ERROR, QMI_PROTOCOL_ERROR_INVALID_PROFILE_TYPE) &&
|
if (g_error_matches (error, QMI_PROTOCOL_ERROR, QMI_PROTOCOL_ERROR_INVALID_PROFILE_TYPE) &&
|
||||||
@@ -6578,20 +6736,18 @@ modify_profile_ready (QmiClientWds *client,
|
|||||||
* in newer devices. */
|
* in newer devices. */
|
||||||
mm_obj_dbg (self, "APN type flagged as not supported: failed to modify profile");
|
mm_obj_dbg (self, "APN type flagged as not supported: failed to modify profile");
|
||||||
self->priv->apn_type_not_supported = TRUE;
|
self->priv->apn_type_not_supported = TRUE;
|
||||||
g_clear_error (&error);
|
|
||||||
store_profile_run (task);
|
store_profile_run (task);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (g_error_matches (error, QMI_PROTOCOL_ERROR, QMI_PROTOCOL_ERROR_EXTENDED_INTERNAL) &&
|
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)) {
|
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, "DS profile error: %s: ", qmi_wds_ds_profile_error_get_string (ds_profile_error));
|
||||||
}
|
}
|
||||||
g_prefix_error (&error, "Couldn't modify profile: ");
|
g_prefix_error (&error, "Couldn't modify profile: ");
|
||||||
g_task_return_error (task, error);
|
|
||||||
} else {
|
|
||||||
g_task_return_boolean (task, TRUE);
|
|
||||||
}
|
}
|
||||||
g_object_unref (task);
|
|
||||||
|
store_profile_complete (task, g_steal_pointer (&error));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@@ -6601,18 +6757,15 @@ create_profile_ready (QmiClientWds *client,
|
|||||||
{
|
{
|
||||||
MMBroadbandModemQmi *self;
|
MMBroadbandModemQmi *self;
|
||||||
StoreProfileContext *ctx;
|
StoreProfileContext *ctx;
|
||||||
GError *error = NULL;
|
|
||||||
guint8 profile_index;
|
guint8 profile_index;
|
||||||
|
g_autoptr(GError) error = NULL;
|
||||||
g_autoptr(QmiMessageWdsCreateProfileOutput) output = NULL;
|
g_autoptr(QmiMessageWdsCreateProfileOutput) output = NULL;
|
||||||
|
|
||||||
ctx = g_task_get_task_data (task);
|
ctx = g_task_get_task_data (task);
|
||||||
self = g_task_get_source_object (task);
|
self = g_task_get_source_object (task);
|
||||||
profile_changed_indication_ignore (self, FALSE);
|
|
||||||
|
|
||||||
output = qmi_client_wds_create_profile_finish (client, res, &error);
|
output = qmi_client_wds_create_profile_finish (client, res, &error);
|
||||||
if (!output) {
|
if (output && !qmi_message_wds_create_profile_output_get_result (output, &error)) {
|
||||||
g_task_return_error (task, error);
|
|
||||||
} else if (!qmi_message_wds_create_profile_output_get_result (output, &error)) {
|
|
||||||
QmiWdsDsProfileError ds_profile_error;
|
QmiWdsDsProfileError ds_profile_error;
|
||||||
|
|
||||||
if (g_error_matches (error, QMI_PROTOCOL_ERROR, QMI_PROTOCOL_ERROR_INVALID_PROFILE_TYPE) &&
|
if (g_error_matches (error, QMI_PROTOCOL_ERROR, QMI_PROTOCOL_ERROR_INVALID_PROFILE_TYPE) &&
|
||||||
@@ -6621,23 +6774,21 @@ create_profile_ready (QmiClientWds *client,
|
|||||||
* in newer devices. */
|
* in newer devices. */
|
||||||
mm_obj_dbg (self, "APN type flagged as not supported: failed to create profile");
|
mm_obj_dbg (self, "APN type flagged as not supported: failed to create profile");
|
||||||
self->priv->apn_type_not_supported = TRUE;
|
self->priv->apn_type_not_supported = TRUE;
|
||||||
g_clear_error (&error);
|
|
||||||
store_profile_run (task);
|
store_profile_run (task);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (g_error_matches (error, QMI_PROTOCOL_ERROR, QMI_PROTOCOL_ERROR_EXTENDED_INTERNAL) &&
|
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)) {
|
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, "DS profile error: %s: ", qmi_wds_ds_profile_error_get_string (ds_profile_error));
|
||||||
}
|
}
|
||||||
g_prefix_error (&error, "Couldn't create profile: ");
|
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);
|
|
||||||
}
|
}
|
||||||
g_object_unref (task);
|
|
||||||
|
if (!error && qmi_message_wds_create_profile_output_get_profile_identifier (output, NULL, &profile_index, &error))
|
||||||
|
ctx->profile_id = profile_index;
|
||||||
|
|
||||||
|
store_profile_complete (task, g_steal_pointer (&error));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@@ -6664,7 +6815,6 @@ store_profile_run (GTask *task)
|
|||||||
if (!self->priv->apn_type_not_supported)
|
if (!self->priv->apn_type_not_supported)
|
||||||
qmi_message_wds_create_profile_input_set_apn_type_mask (input, ctx->qmi_apn_type, NULL);
|
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,
|
qmi_client_wds_create_profile (ctx->client,
|
||||||
input,
|
input,
|
||||||
10,
|
10,
|
||||||
@@ -6685,7 +6835,6 @@ store_profile_run (GTask *task)
|
|||||||
if (!self->priv->apn_type_not_supported)
|
if (!self->priv->apn_type_not_supported)
|
||||||
qmi_message_wds_modify_profile_input_set_apn_type_mask (input, ctx->qmi_apn_type, NULL);
|
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,
|
qmi_client_wds_modify_profile (ctx->client,
|
||||||
input,
|
input,
|
||||||
10,
|
10,
|
||||||
@@ -6695,6 +6844,19 @@ store_profile_run (GTask *task)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
profile_changed_indication_configure_before_store_ready (MMBroadbandModemQmi *self,
|
||||||
|
GAsyncResult *res,
|
||||||
|
GTask *task)
|
||||||
|
{
|
||||||
|
g_autoptr(GError) error = NULL;
|
||||||
|
|
||||||
|
if (!profile_changed_indication_configure_finish (self, res, &error))
|
||||||
|
mm_obj_warn (self, "Couldn't configure profile change indications before store operation: %s", error->message);
|
||||||
|
|
||||||
|
store_profile_run (task);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
modem_3gpp_profile_manager_store_profile (MMIfaceModem3gppProfileManager *self,
|
modem_3gpp_profile_manager_store_profile (MMIfaceModem3gppProfileManager *self,
|
||||||
MM3gppProfile *profile,
|
MM3gppProfile *profile,
|
||||||
@@ -6756,12 +6918,31 @@ modem_3gpp_profile_manager_store_profile (MMIfaceModem3gppProfileManager *self,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
store_profile_run (task);
|
profile_changed_indication_configure_ignore (
|
||||||
|
MM_BROADBAND_MODEM_QMI (self),
|
||||||
|
ctx->client,
|
||||||
|
TRUE,
|
||||||
|
(GAsyncReadyCallback) profile_changed_indication_configure_before_store_ready,
|
||||||
|
task);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
/* Delete profile (3GPP profile management interface) */
|
/* Delete profile (3GPP profile management interface) */
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
QmiClientWds *client;
|
||||||
|
gint profile_id;
|
||||||
|
GError *saved_error;
|
||||||
|
} DeleteProfileContext;
|
||||||
|
|
||||||
|
static void
|
||||||
|
delete_profile_context_free (DeleteProfileContext *ctx)
|
||||||
|
{
|
||||||
|
g_assert (!ctx->saved_error);
|
||||||
|
g_clear_object (&ctx->client);
|
||||||
|
g_slice_free (DeleteProfileContext, ctx);
|
||||||
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
modem_3gpp_profile_manager_delete_profile_finish (MMIfaceModem3gppProfileManager *self,
|
modem_3gpp_profile_manager_delete_profile_finish (MMIfaceModem3gppProfileManager *self,
|
||||||
GAsyncResult *res,
|
GAsyncResult *res,
|
||||||
@@ -6770,25 +6951,77 @@ modem_3gpp_profile_manager_delete_profile_finish (MMIfaceModem3gppProfileManager
|
|||||||
return g_task_propagate_boolean (G_TASK (res), error);
|
return g_task_propagate_boolean (G_TASK (res), error);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
profile_changed_indication_configure_after_delete_ready (MMBroadbandModemQmi *self,
|
||||||
|
GAsyncResult *res,
|
||||||
|
GTask *task)
|
||||||
|
{
|
||||||
|
DeleteProfileContext *ctx;
|
||||||
|
g_autoptr(QmiMessageWdsDeleteProfileInput) input = NULL;
|
||||||
|
g_autoptr(GError) error = NULL;
|
||||||
|
|
||||||
|
ctx = g_task_get_task_data (task);
|
||||||
|
|
||||||
|
if (!profile_changed_indication_configure_finish (self, res, &error))
|
||||||
|
mm_obj_warn (self, "Couldn't configure profile change indications after delete operation: %s", error->message);
|
||||||
|
|
||||||
|
if (ctx->saved_error)
|
||||||
|
g_task_return_error (task, g_steal_pointer (&ctx->saved_error));
|
||||||
|
else
|
||||||
|
g_task_return_boolean (task, TRUE);
|
||||||
|
g_object_unref (task);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
delete_profile_ready (QmiClientWds *client,
|
delete_profile_ready (QmiClientWds *client,
|
||||||
GAsyncResult *res,
|
GAsyncResult *res,
|
||||||
GTask *task)
|
GTask *task)
|
||||||
{
|
{
|
||||||
MMBroadbandModemQmi *self;
|
MMBroadbandModemQmi *self;
|
||||||
GError *error = NULL;
|
DeleteProfileContext *ctx;
|
||||||
|
g_autoptr(GError) error = NULL;
|
||||||
g_autoptr(QmiMessageWdsDeleteProfileOutput) output = NULL;
|
g_autoptr(QmiMessageWdsDeleteProfileOutput) output = NULL;
|
||||||
|
|
||||||
self = g_task_get_source_object (task);
|
self = g_task_get_source_object (task);
|
||||||
profile_changed_indication_ignore (self, FALSE);
|
ctx = g_task_get_task_data (task);
|
||||||
|
|
||||||
output = qmi_client_wds_delete_profile_finish (client, res, &error);
|
output = qmi_client_wds_delete_profile_finish (client, res, &error);
|
||||||
if (!output || !qmi_message_wds_delete_profile_output_get_result (output, &error)) {
|
if (!output || !qmi_message_wds_delete_profile_output_get_result (output, &error))
|
||||||
g_prefix_error (&error, "Couldn't delete profile: ");
|
g_prefix_error (&error, "Couldn't delete profile: ");
|
||||||
g_task_return_error (task, error);
|
|
||||||
} else
|
/* Store as task data to complete the task later */
|
||||||
g_task_return_boolean (task, TRUE);
|
ctx->saved_error = g_steal_pointer (&error);
|
||||||
g_object_unref (task);
|
|
||||||
|
profile_changed_indication_configure_ignore (
|
||||||
|
self,
|
||||||
|
ctx->client,
|
||||||
|
FALSE,
|
||||||
|
(GAsyncReadyCallback) profile_changed_indication_configure_after_delete_ready,
|
||||||
|
task);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
profile_changed_indication_configure_before_delete_ready (MMBroadbandModemQmi *self,
|
||||||
|
GAsyncResult *res,
|
||||||
|
GTask *task)
|
||||||
|
{
|
||||||
|
DeleteProfileContext *ctx;
|
||||||
|
g_autoptr(QmiMessageWdsDeleteProfileInput) input = NULL;
|
||||||
|
g_autoptr(GError) error = NULL;
|
||||||
|
|
||||||
|
ctx = g_task_get_task_data (task);
|
||||||
|
|
||||||
|
if (!profile_changed_indication_configure_finish (self, res, &error))
|
||||||
|
mm_obj_warn (self, "Couldn't configure profile change indications before delete operation: %s", error->message);
|
||||||
|
|
||||||
|
input = qmi_message_wds_delete_profile_input_new ();
|
||||||
|
qmi_message_wds_delete_profile_input_set_profile_identifier (input, QMI_WDS_PROFILE_TYPE_3GPP, ctx->profile_id, NULL);
|
||||||
|
qmi_client_wds_delete_profile (QMI_CLIENT_WDS (ctx->client),
|
||||||
|
input,
|
||||||
|
10,
|
||||||
|
NULL,
|
||||||
|
(GAsyncReadyCallback)delete_profile_ready,
|
||||||
|
task);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@@ -6798,10 +7031,9 @@ modem_3gpp_profile_manager_delete_profile (MMIfaceModem3gppProfileManager *self,
|
|||||||
GAsyncReadyCallback callback,
|
GAsyncReadyCallback callback,
|
||||||
gpointer user_data)
|
gpointer user_data)
|
||||||
{
|
{
|
||||||
GTask *task;
|
DeleteProfileContext *ctx;
|
||||||
QmiClient *client = NULL;
|
GTask *task;
|
||||||
gint profile_id;
|
QmiClient *client = NULL;
|
||||||
g_autoptr(QmiMessageWdsDeleteProfileInput) input = NULL;
|
|
||||||
|
|
||||||
g_assert (g_strcmp0 (index_field, "profile-id") == 0);
|
g_assert (g_strcmp0 (index_field, "profile-id") == 0);
|
||||||
|
|
||||||
@@ -6811,22 +7043,20 @@ modem_3gpp_profile_manager_delete_profile (MMIfaceModem3gppProfileManager *self,
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
task = g_task_new (self, NULL, callback, user_data);
|
task = g_task_new (self, NULL, callback, user_data);
|
||||||
|
ctx = g_slice_new0 (DeleteProfileContext);
|
||||||
|
ctx->client = QMI_CLIENT_WDS (g_object_ref (client));
|
||||||
|
ctx->profile_id = mm_3gpp_profile_get_profile_id (profile);
|
||||||
|
g_assert (ctx->profile_id != MM_3GPP_PROFILE_ID_UNKNOWN);
|
||||||
|
g_task_set_task_data (task, ctx, (GDestroyNotify) delete_profile_context_free);
|
||||||
|
|
||||||
profile_id = mm_3gpp_profile_get_profile_id (profile);
|
mm_obj_dbg (self, "deleting profile '%d'", ctx->profile_id);
|
||||||
g_assert (profile_id != MM_3GPP_PROFILE_ID_UNKNOWN);
|
|
||||||
|
|
||||||
mm_obj_dbg (self, "deleting profile '%d'", profile_id);
|
profile_changed_indication_configure_ignore (
|
||||||
|
MM_BROADBAND_MODEM_QMI (self),
|
||||||
input = qmi_message_wds_delete_profile_input_new ();
|
ctx->client,
|
||||||
qmi_message_wds_delete_profile_input_set_profile_identifier (input, QMI_WDS_PROFILE_TYPE_3GPP, profile_id, NULL);
|
TRUE,
|
||||||
|
(GAsyncReadyCallback) profile_changed_indication_configure_before_delete_ready,
|
||||||
profile_changed_indication_ignore (MM_BROADBAND_MODEM_QMI (self), TRUE);
|
task);
|
||||||
qmi_client_wds_delete_profile (QMI_CLIENT_WDS (client),
|
|
||||||
input,
|
|
||||||
10,
|
|
||||||
NULL,
|
|
||||||
(GAsyncReadyCallback)delete_profile_ready,
|
|
||||||
task);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
@@ -6849,38 +7079,10 @@ profile_changed_indication_received (QmiClientWds *clien
|
|||||||
QmiIndicationWdsProfileChangedOutput *output,
|
QmiIndicationWdsProfileChangedOutput *output,
|
||||||
MMBroadbandModemQmi *self)
|
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_obj_dbg (self, "profile changed indication was received");
|
||||||
mm_iface_modem_3gpp_profile_manager_updated (MM_IFACE_MODEM_3GPP_PROFILE_MANAGER (self));
|
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) */
|
/* Enable/Disable unsolicited events (3gppProfileManager interface) */
|
||||||
|
|
||||||
@@ -6940,18 +7142,16 @@ register_pdc_refresh_ready (QmiClientPdc *client,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
register_wds_profile_change_ready (QmiClientWds *client,
|
profile_changed_indication_configure_ready (MMBroadbandModemQmi *self,
|
||||||
GAsyncResult *res,
|
GAsyncResult *res,
|
||||||
GTask *task)
|
GTask *task)
|
||||||
{
|
{
|
||||||
g_autoptr(QmiMessageWdsIndicationRegisterOutput) output = NULL;
|
RegisterProfileRefreshContext *ctx;
|
||||||
RegisterProfileRefreshContext *ctx;
|
GError *error = NULL;
|
||||||
GError *error = NULL;
|
|
||||||
|
|
||||||
ctx = g_task_get_task_data (task);
|
ctx = g_task_get_task_data (task);
|
||||||
|
|
||||||
output = qmi_client_wds_indication_register_finish (client, res, &error);
|
if (!profile_changed_indication_configure_finish (self, res, &error)) {
|
||||||
if (!output || !qmi_message_wds_indication_register_output_get_result (output, &error)) {
|
|
||||||
g_task_return_error (task, error);
|
g_task_return_error (task, error);
|
||||||
g_object_unref (task);
|
g_object_unref (task);
|
||||||
return;
|
return;
|
||||||
@@ -7016,16 +7216,12 @@ register_profile_refresh_context_step (GTask *task)
|
|||||||
|
|
||||||
case REGISTER_PROFILE_REFRESH_STEP_PROFILE_CHANGE:
|
case REGISTER_PROFILE_REFRESH_STEP_PROFILE_CHANGE:
|
||||||
if (ctx->client_wds) {
|
if (ctx->client_wds) {
|
||||||
g_autoptr(QmiMessageWdsIndicationRegisterInput) input = NULL;
|
profile_changed_indication_configure_enable (
|
||||||
|
self,
|
||||||
input = qmi_message_wds_indication_register_input_new ();
|
ctx->client_wds,
|
||||||
qmi_message_wds_indication_register_input_set_report_profile_changes (input, ctx->enable, NULL);
|
ctx->enable,
|
||||||
qmi_client_wds_indication_register (ctx->client_wds,
|
(GAsyncReadyCallback) profile_changed_indication_configure_ready,
|
||||||
input,
|
task);
|
||||||
10,
|
|
||||||
NULL,
|
|
||||||
(GAsyncReadyCallback) register_wds_profile_change_ready,
|
|
||||||
task);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
ctx->step++;
|
ctx->step++;
|
||||||
|
Reference in New Issue
Block a user