aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/mm-broadband-modem-qmi.c209
1 files changed, 98 insertions, 111 deletions
diff --git a/src/mm-broadband-modem-qmi.c b/src/mm-broadband-modem-qmi.c
index 26b4c7c2..c157a375 100644
--- a/src/mm-broadband-modem-qmi.c
+++ b/src/mm-broadband-modem-qmi.c
@@ -162,12 +162,8 @@ struct _MMBroadbandModemQmiPrivate {
/* For notifying when the qmi-proxy connection is dead */
guint qmi_device_removed_id;
- /* Power Indication Helper */
- guint power_event_report_indication_id;
-
/* Power Set Operating Mode Helper */
GTask *set_operating_mode_task;
- guint set_operating_timeout_id;
};
/*****************************************************************************/
@@ -1708,6 +1704,22 @@ load_signal_quality (MMIfaceModem *self,
/*****************************************************************************/
/* Powering up/down/off the modem (Modem interface) */
+typedef struct {
+ QmiDmsOperatingMode mode;
+ QmiClientDms *client;
+ guint indication_id;
+ guint timeout_id;
+} SetOperatingModeContext;
+
+static void
+set_operating_mode_context_free (SetOperatingModeContext *ctx)
+{
+ g_assert (ctx->indication_id == 0);
+ g_assert (ctx->timeout_id == 0);
+ g_clear_object (&ctx->client);
+ g_slice_free (SetOperatingModeContext, ctx);
+}
+
static gboolean
modem_power_up_down_off_finish (MMIfaceModem *self,
GAsyncResult *res,
@@ -1717,51 +1729,36 @@ modem_power_up_down_off_finish (MMIfaceModem *self,
}
static void
-modem_power_indication_deregister (MMBroadbandModemQmi *self)
+set_operating_mode_complete (MMBroadbandModemQmi *self,
+ GError *error)
{
- g_autoptr(QmiMessageDmsSetEventReportInput) input = NULL;
- QmiClient *client;
-
- g_assert (self->priv->power_event_report_indication_id != 0);
- g_signal_handler_disconnect (QMI_CLIENT_DMS (client),
- self->priv->power_event_report_indication_id);
- self->priv->power_event_report_indication_id = 0;
+ GTask *task;
+ SetOperatingModeContext *ctx;
- client = mm_shared_qmi_peek_client (MM_SHARED_QMI (self),
- QMI_SERVICE_DMS,
- MM_PORT_QMI_FLAG_DEFAULT,
- NULL);
- if (!client)
- return;
+ g_assert (self->priv->set_operating_mode_task);
+ task = g_steal_pointer (&self->priv->set_operating_mode_task);
+ ctx = g_task_get_task_data (task);
- input = qmi_message_dms_set_event_report_input_new ();
- qmi_message_dms_set_event_report_input_set_operating_mode_reporting (input, FALSE, NULL);
- mm_obj_dbg (self, "Power indication deregistration request is sent");
- qmi_client_dms_set_event_report (QMI_CLIENT_DMS (client), input, 5, NULL, NULL, NULL);
-}
+ if (ctx->timeout_id) {
+ g_source_remove (ctx->timeout_id);
+ ctx->timeout_id = 0;
+ }
-static void
-dms_set_operating_mode_complete (MMBroadbandModemQmi *self,
- GError *error)
-{
- GTask *task;
+ if (ctx->indication_id) {
+ g_autoptr(QmiMessageDmsSetEventReportInput) input = NULL;
- task = g_steal_pointer (&self->priv->set_operating_mode_task);
- g_assert (task != NULL);
+ g_signal_handler_disconnect (ctx->client, ctx->indication_id);
+ ctx->indication_id = 0;
- if (self->priv->set_operating_timeout_id) {
- g_source_remove (self->priv->set_operating_timeout_id);
- self->priv->set_operating_timeout_id = 0;
- }
- if (self->priv->power_event_report_indication_id) {
- modem_power_indication_deregister (self);
+ input = qmi_message_dms_set_event_report_input_new ();
+ qmi_message_dms_set_event_report_input_set_operating_mode_reporting (input, FALSE, NULL);
+ qmi_client_dms_set_event_report (ctx->client, input, 5, NULL, NULL, NULL);
}
- if (error) {
+ if (error)
g_task_return_error (task, error);
- } else {
+ else
g_task_return_boolean (task, TRUE);
- }
g_object_unref (task);
}
@@ -1771,7 +1768,7 @@ dms_set_operating_mode_timeout_cb (MMBroadbandModemQmi *self)
GError *error = NULL;
error = g_error_new (MM_CORE_ERROR, MM_CORE_ERROR_FAILED, "Power update operation timed out");
- dms_set_operating_mode_complete (self, error);
+ set_operating_mode_complete (self, error);
}
static void
@@ -1779,31 +1776,31 @@ power_event_report_indication_cb (QmiClientDms *client,
QmiIndicationDmsEventReportOutput *output,
MMBroadbandModemQmi *self)
{
- QmiDmsOperatingMode state;
- GTask *task;
- GError *error = NULL;
- QmiDmsOperatingMode mode;
+ QmiDmsOperatingMode state;
+ GError *error = NULL;
+ SetOperatingModeContext *ctx;
if (!qmi_indication_dms_event_report_output_get_operating_mode (output, &state, NULL)) {
error = g_error_new (MM_CORE_ERROR, MM_CORE_ERROR_FAILED, "Invalid power indication received");
- dms_set_operating_mode_complete (self, error);
+ set_operating_mode_complete (self, error);
return;
}
- task = self->priv->set_operating_mode_task;
- mode = GPOINTER_TO_UINT (g_task_get_task_data (task));
- if (mode == state) {
+ g_assert (self->priv->set_operating_mode_task);
+ ctx = g_task_get_task_data (self->priv->set_operating_mode_task);
+
+ if (ctx->mode == state) {
mm_obj_dbg (self, "Power state successfully updated: '%s'", qmi_dms_operating_mode_get_string (state));
- dms_set_operating_mode_complete (self, NULL);
+ set_operating_mode_complete (self, NULL);
return;
}
error = g_error_new (MM_CORE_ERROR,
MM_CORE_ERROR_FAILED,
"Requested mode (%s) and mode received (%s) did not match",
- qmi_dms_operating_mode_get_string (mode),
+ qmi_dms_operating_mode_get_string (ctx->mode),
qmi_dms_operating_mode_get_string (state));
- dms_set_operating_mode_complete (self, error);
+ set_operating_mode_complete (self, error);
}
static void
@@ -1811,19 +1808,17 @@ dms_set_operating_mode_ready (QmiClientDms *client,
GAsyncResult *res,
MMBroadbandModemQmi *self) /* full reference */
{
- GTask *task;
- QmiDmsOperatingMode mode;
- GError *error = NULL;
g_autoptr (QmiMessageDmsSetOperatingModeOutput) output = NULL;
+ GError *error = NULL;
+ SetOperatingModeContext *ctx;
- task = self->priv->set_operating_mode_task;
- if (task == NULL) {
+ if (!self->priv->set_operating_mode_task) {
/* We completed the operation already via indication */
g_object_unref (self);
return;
}
- mode = GPOINTER_TO_UINT (g_task_get_task_data (task));
+ ctx = g_task_get_task_data (self->priv->set_operating_mode_task);
output = qmi_client_dms_set_operating_mode_finish (client, res, &error);
if (!output) {
@@ -1846,7 +1841,7 @@ dms_set_operating_mode_ready (QmiClientDms *client,
* retrying. Notify this to upper layers with the special MM_CORE_ERROR_RETRY
* error.
*/
- if ((mode == QMI_DMS_OPERATING_MODE_ONLINE) &&
+ if ((ctx->mode == QMI_DMS_OPERATING_MODE_ONLINE) &&
((g_error_matches (error, QMI_PROTOCOL_ERROR, QMI_PROTOCOL_ERROR_INTERNAL) ||
g_error_matches (error, QMI_PROTOCOL_ERROR, QMI_PROTOCOL_ERROR_INVALID_TRANSITION)))) {
g_clear_error (&error);
@@ -1855,7 +1850,7 @@ dms_set_operating_mode_ready (QmiClientDms *client,
}
if (error)
- dms_set_operating_mode_complete (self, error);
+ set_operating_mode_complete (self, error);
else
mm_obj_dbg (self, "operating mode request sent, waiting for power update indication");
@@ -1865,26 +1860,15 @@ dms_set_operating_mode_ready (QmiClientDms *client,
static void
dms_set_operating_mode (MMBroadbandModemQmi *self)
{
- QmiClient *client;
- GError *error = NULL;
- GTask *task;
- QmiDmsOperatingMode mode;
g_autoptr (QmiMessageDmsSetOperatingModeInput) input = NULL;
+ SetOperatingModeContext *ctx;
- task = self->priv->set_operating_mode_task;
- mode = GPOINTER_TO_UINT (g_task_get_task_data(task));
- client = mm_shared_qmi_peek_client (MM_SHARED_QMI (self),
- QMI_SERVICE_DMS,
- MM_PORT_QMI_FLAG_DEFAULT,
- &error);
- if (!client) {
- dms_set_operating_mode_complete (self, error);
- return;
- }
+ g_assert (self->priv->set_operating_mode_task);
+ ctx = g_task_get_task_data (self->priv->set_operating_mode_task);
input = qmi_message_dms_set_operating_mode_input_new ();
- qmi_message_dms_set_operating_mode_input_set_mode (input, mode, NULL);
- qmi_client_dms_set_operating_mode (QMI_CLIENT_DMS (client),
+ qmi_message_dms_set_operating_mode_input_set_mode (input, ctx->mode, NULL);
+ qmi_client_dms_set_operating_mode (ctx->client,
input,
20,
NULL,
@@ -1892,9 +1876,9 @@ dms_set_operating_mode (MMBroadbandModemQmi *self)
g_object_ref (self));
mm_obj_dbg (self, "Starting timeout for indication receiving for 10 seconds");
- self->priv->set_operating_timeout_id = g_timeout_add_seconds (10,
- (GSourceFunc) dms_set_operating_mode_timeout_cb,
- self);
+ ctx->timeout_id = g_timeout_add_seconds (10,
+ (GSourceFunc) dms_set_operating_mode_timeout_cb,
+ self);
}
static void
@@ -1904,31 +1888,26 @@ dms_set_event_report_operating_mode_activate_ready (QmiClientDms *client,
{
g_autoptr(QmiMessageDmsSetEventReportOutput) output = NULL;
GError *error = NULL;
+ SetOperatingModeContext *ctx;
+
+ g_assert (self->priv->set_operating_mode_task);
+ ctx = g_task_get_task_data (self->priv->set_operating_mode_task);
output = qmi_client_dms_set_event_report_finish (client, res, &error);
- if (!output) {
- g_prefix_error (&error, "Power indication activation qmi operation failed");
- dms_set_operating_mode_complete (self, error);
- g_object_unref (self);
- return;
- }
- if (!qmi_message_dms_set_event_report_output_get_result (output, &error)) {
- g_prefix_error (&error, "Power indication failed: couldn't set event report");
- dms_set_operating_mode_complete (self, error);
+ if (!output || !qmi_message_dms_set_event_report_output_get_result (output, &error)) {
+ g_prefix_error (&error, "Couldn't register for power indications: ");
+ set_operating_mode_complete (self, error);
g_object_unref (self);
return;
}
- g_assert (self->priv->power_event_report_indication_id == 0);
- self->priv->power_event_report_indication_id =
- g_signal_connect (client,
- "event-report",
- G_CALLBACK (power_event_report_indication_cb),
- self);
+ g_assert (ctx->indication_id == 0);
+ ctx->indication_id = g_signal_connect (client,
+ "event-report",
+ G_CALLBACK (power_event_report_indication_cb),
+ self);
- g_assert (self->priv->set_operating_mode_task != NULL);
mm_obj_dbg (self, "Power operation is pending");
-
dms_set_operating_mode (self);
g_object_unref (self);
}
@@ -1937,24 +1916,16 @@ static void
modem_power_indication_register (MMBroadbandModemQmi *self)
{
g_autoptr(QmiMessageDmsSetEventReportInput) input = NULL;
- QmiClient *client;
- GError *error = NULL;
+ SetOperatingModeContext *ctx;
- client = mm_shared_qmi_peek_client (MM_SHARED_QMI (self),
- QMI_SERVICE_DMS,
- MM_PORT_QMI_FLAG_DEFAULT,
- &error);
-
- if (!client) {
- dms_set_operating_mode_complete (self, error);
- return;
- }
+ g_assert (self->priv->set_operating_mode_task);
+ ctx = g_task_get_task_data (self->priv->set_operating_mode_task);
input = qmi_message_dms_set_event_report_input_new ();
qmi_message_dms_set_event_report_input_set_operating_mode_reporting (input, TRUE, NULL);
mm_obj_dbg (self, "Power indication registration request is sent");
qmi_client_dms_set_event_report (
- QMI_CLIENT_DMS (client),
+ ctx->client,
input,
5,
NULL,
@@ -1968,12 +1939,13 @@ common_power_up_down_off (MMIfaceModem *_self,
GAsyncReadyCallback callback,
gpointer user_data)
{
- GTask *task;
- GError *error = NULL;
- MMBroadbandModemQmi *self = MM_BROADBAND_MODEM_QMI (_self);
+ MMBroadbandModemQmi *self = MM_BROADBAND_MODEM_QMI (_self);
+ GError *error = NULL;
+ GTask *task;
+ SetOperatingModeContext *ctx;
+ QmiClient *client;
task = g_task_new (self, NULL, callback, user_data);
- g_task_set_task_data (task, GUINT_TO_POINTER (mode), NULL);
if (self->priv->set_operating_mode_task) {
error = g_error_new (MM_CORE_ERROR, MM_CORE_ERROR_IN_PROGRESS, "Another operation in progress");
@@ -1982,6 +1954,21 @@ common_power_up_down_off (MMIfaceModem *_self,
return;
}
+ client = mm_shared_qmi_peek_client (MM_SHARED_QMI (self),
+ QMI_SERVICE_DMS,
+ MM_PORT_QMI_FLAG_DEFAULT,
+ &error);
+ if (!client) {
+ g_task_return_error (task, error);
+ g_object_unref (task);
+ return;
+ }
+
+ ctx = g_slice_new0 (SetOperatingModeContext);
+ ctx->mode = mode;
+ ctx->client = QMI_CLIENT_DMS (g_object_ref (client));
+ g_task_set_task_data (task, ctx, (GDestroyNotify)set_operating_mode_context_free);
+
self->priv->set_operating_mode_task = task;
modem_power_indication_register (self);
}