cinterion: port modem_power_off to GTask

This commit is contained in:
Aleksander Morgado
2017-09-20 19:49:37 -07:00
parent 00aa9cd09b
commit f9e2ebf3a0

View File

@@ -407,9 +407,7 @@ modem_power_down (MMIfaceModem *_self,
#define MAX_POWER_OFF_WAIT_TIME_SECS 20 #define MAX_POWER_OFF_WAIT_TIME_SECS 20
typedef struct { typedef struct {
MMBroadbandModemCinterion *self;
MMPortSerialAt *port; MMPortSerialAt *port;
GSimpleAsyncResult *result;
GRegex *shutdown_regex; GRegex *shutdown_regex;
gboolean shutdown_received; gboolean shutdown_received;
gboolean smso_replied; gboolean smso_replied;
@@ -418,7 +416,7 @@ typedef struct {
} PowerOffContext; } PowerOffContext;
static void static void
power_off_context_complete_and_free (PowerOffContext *ctx) power_off_context_free (PowerOffContext *ctx)
{ {
if (ctx->serial_open) if (ctx->serial_open)
mm_port_serial_close (MM_PORT_SERIAL (ctx->port)); mm_port_serial_close (MM_PORT_SERIAL (ctx->port));
@@ -426,10 +424,7 @@ power_off_context_complete_and_free (PowerOffContext *ctx)
g_source_remove (ctx->timeout_id); g_source_remove (ctx->timeout_id);
mm_port_serial_at_add_unsolicited_msg_handler (ctx->port, ctx->shutdown_regex, NULL, NULL, NULL); mm_port_serial_at_add_unsolicited_msg_handler (ctx->port, ctx->shutdown_regex, NULL, NULL, NULL);
g_object_unref (ctx->port); g_object_unref (ctx->port);
g_object_unref (ctx->self);
g_regex_unref (ctx->shutdown_regex); g_regex_unref (ctx->shutdown_regex);
g_simple_async_result_complete_in_idle (ctx->result);
g_object_unref (ctx->result);
g_slice_free (PowerOffContext, ctx); g_slice_free (PowerOffContext, ctx);
} }
@@ -438,63 +433,86 @@ modem_power_off_finish (MMIfaceModem *self,
GAsyncResult *res, GAsyncResult *res,
GError **error) GError **error)
{ {
return !g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (res), error); return g_task_propagate_boolean (G_TASK (res), error);
} }
static void static void
complete_power_off (PowerOffContext *ctx) complete_power_off (GTask *task)
{ {
PowerOffContext *ctx;
ctx = g_task_get_task_data (task);
if (!ctx->shutdown_received || !ctx->smso_replied) if (!ctx->shutdown_received || !ctx->smso_replied)
return; return;
g_simple_async_result_set_op_res_gboolean (ctx->result, TRUE); /* remove timeout right away */
power_off_context_complete_and_free (ctx); g_assert (ctx->timeout_id);
g_source_remove (ctx->timeout_id);
ctx->timeout_id = 0;
g_task_return_boolean (task, TRUE);
g_object_unref (task);
} }
static void static void
smso_ready (MMBaseModem *self, smso_ready (MMBaseModem *self,
GAsyncResult *res, GAsyncResult *res,
PowerOffContext *ctx) GTask *task)
{ {
PowerOffContext *ctx;
GError *error = NULL; GError *error = NULL;
mm_base_modem_at_command_full_finish (MM_BASE_MODEM (self), res, &error); ctx = g_task_get_task_data (task);
if (error) {
g_simple_async_result_take_error (ctx->result, error); if (!mm_base_modem_at_command_full_finish (MM_BASE_MODEM (self), res, &error)) {
power_off_context_complete_and_free (ctx); g_task_return_error (task, error);
g_object_unref (task);
return; return;
} }
/* Set as replied */ /* Set as replied and see if we can complete */
ctx->smso_replied = TRUE; ctx->smso_replied = TRUE;
complete_power_off (ctx); complete_power_off (task);
} }
static void static void
shutdown_received (MMPortSerialAt *port, shutdown_received (MMPortSerialAt *port,
GMatchInfo *match_info, GMatchInfo *match_info,
PowerOffContext *ctx) GTask *task)
{ {
/* Cleanup handler */ PowerOffContext *ctx;
ctx = g_task_get_task_data (task);
/* Cleanup handler right away, we don't want it called any more */
mm_port_serial_at_add_unsolicited_msg_handler (port, ctx->shutdown_regex, NULL, NULL, NULL); mm_port_serial_at_add_unsolicited_msg_handler (port, ctx->shutdown_regex, NULL, NULL, NULL);
/* Set as received */
/* Set as received and see if we can complete */
ctx->shutdown_received = TRUE; ctx->shutdown_received = TRUE;
complete_power_off (ctx); complete_power_off (task);
} }
static gboolean static gboolean
power_off_timeout_cb (PowerOffContext *ctx) power_off_timeout_cb (GTask *task)
{ {
PowerOffContext *ctx;
ctx = g_task_get_task_data (task);
ctx->timeout_id = 0; ctx->timeout_id = 0;
/* The SMSO reply should have come earlier */ /* The SMSO reply should have come earlier */
g_warn_if_fail (ctx->smso_replied == TRUE); g_warn_if_fail (ctx->smso_replied == TRUE);
g_simple_async_result_set_error (ctx->result, /* Cleanup handler right away, we no longer want to receive it */
mm_port_serial_at_add_unsolicited_msg_handler (ctx->port, ctx->shutdown_regex, NULL, NULL, NULL);
g_task_return_new_error (task,
MM_CORE_ERROR, MM_CORE_ERROR,
MM_CORE_ERROR_FAILED, MM_CORE_ERROR_FAILED,
"Power off operation timed out"); "Power off operation timed out");
power_off_context_complete_and_free (ctx); g_object_unref (task);
return G_SOURCE_REMOVE; return G_SOURCE_REMOVE;
} }
@@ -504,21 +522,20 @@ modem_power_off (MMIfaceModem *self,
GAsyncReadyCallback callback, GAsyncReadyCallback callback,
gpointer user_data) gpointer user_data)
{ {
GTask *task;
PowerOffContext *ctx; PowerOffContext *ctx;
GError *error = NULL; GError *error = NULL;
task = g_task_new (self, NULL, callback, user_data);
ctx = g_slice_new0 (PowerOffContext); ctx = g_slice_new0 (PowerOffContext);
ctx->self = g_object_ref (self);
ctx->port = mm_base_modem_get_port_primary (MM_BASE_MODEM (self)); ctx->port = mm_base_modem_get_port_primary (MM_BASE_MODEM (self));
ctx->result = g_simple_async_result_new (G_OBJECT (self),
callback,
user_data,
modem_power_off);
ctx->shutdown_regex = g_regex_new ("\\r\\n\\^SHUTDOWN\\r\\n", ctx->shutdown_regex = g_regex_new ("\\r\\n\\^SHUTDOWN\\r\\n",
G_REGEX_RAW | G_REGEX_OPTIMIZE, 0, NULL); G_REGEX_RAW | G_REGEX_OPTIMIZE, 0, NULL);
ctx->timeout_id = g_timeout_add_seconds (MAX_POWER_OFF_WAIT_TIME_SECS, ctx->timeout_id = g_timeout_add_seconds (MAX_POWER_OFF_WAIT_TIME_SECS,
(GSourceFunc)power_off_timeout_cb, (GSourceFunc)power_off_timeout_cb,
ctx); task);
g_task_set_task_data (task, ctx, (GDestroyNotify) power_off_context_free);
/* We'll need to wait for a ^SHUTDOWN before returning the action, which is /* We'll need to wait for a ^SHUTDOWN before returning the action, which is
* when the modem tells us that it is ready to be shutdown */ * when the modem tells us that it is ready to be shutdown */
@@ -526,15 +543,15 @@ modem_power_off (MMIfaceModem *self,
ctx->port, ctx->port,
ctx->shutdown_regex, ctx->shutdown_regex,
(MMPortSerialAtUnsolicitedMsgFn)shutdown_received, (MMPortSerialAtUnsolicitedMsgFn)shutdown_received,
ctx, task,
NULL); NULL);
/* In order to get the ^SHUTDOWN notification, we must keep the port open /* In order to get the ^SHUTDOWN notification, we must keep the port open
* during the wait time */ * during the wait time */
ctx->serial_open = mm_port_serial_open (MM_PORT_SERIAL (ctx->port), &error); ctx->serial_open = mm_port_serial_open (MM_PORT_SERIAL (ctx->port), &error);
if (G_UNLIKELY (error)) { if (G_UNLIKELY (error)) {
g_simple_async_result_take_error (ctx->result, error); g_task_return_error (task, error);
power_off_context_complete_and_free (ctx); g_object_unref (task);
return; return;
} }
@@ -550,7 +567,7 @@ modem_power_off (MMIfaceModem *self,
FALSE, /* is_raw */ FALSE, /* is_raw */
NULL, /* cancellable */ NULL, /* cancellable */
(GAsyncReadyCallback)smso_ready, (GAsyncReadyCallback)smso_ready,
ctx); task);
} }
/*****************************************************************************/ /*****************************************************************************/