diff options
author | Aleksander Morgado <aleksander@aleksander.es> | 2013-11-17 14:50:22 +0100 |
---|---|---|
committer | Aleksander Morgado <aleksander@aleksander.es> | 2014-02-13 13:40:27 +0100 |
commit | 8122153a88b6f87962d2702c14b642d4f344eca2 (patch) | |
tree | feb1d3248907125275a70e2b0b4c349418ba0c33 | |
parent | 6e35f0a8881de9f5a81a9abb2db17a15fda618bc (diff) |
port-serial: use GIO Async API like method for flash()
-rw-r--r-- | src/mm-broadband-bearer.c | 22 | ||||
-rw-r--r-- | src/mm-broadband-modem.c | 11 | ||||
-rw-r--r-- | src/mm-port-probe.c | 10 | ||||
-rw-r--r-- | src/mm-port-serial.c | 180 | ||||
-rw-r--r-- | src/mm-port-serial.h | 12 |
5 files changed, 144 insertions, 91 deletions
diff --git a/src/mm-broadband-bearer.c b/src/mm-broadband-bearer.c index db9f5136..bb2209ea 100644 --- a/src/mm-broadband-bearer.c +++ b/src/mm-broadband-bearer.c @@ -1327,9 +1327,13 @@ detailed_disconnect_context_new (MMBroadbandBearer *self, static void data_flash_cdma_ready (MMPortSerial *data, - GError *error, + GAsyncResult *res, DetailedDisconnectContext *ctx) { + GError *error = NULL; + + mm_port_serial_flash_finish (data, res, &error); + /* We kept the serial port open during connection, now we close that open * count */ mm_port_serial_close (data); @@ -1348,12 +1352,13 @@ data_flash_cdma_ready (MMPortSerial *data, MM_SERIAL_ERROR, MM_SERIAL_ERROR_FLASH_FAILED)) { /* Fatal */ - g_simple_async_result_set_from_error (ctx->result, error); + g_simple_async_result_take_error (ctx->result, error); detailed_disconnect_context_complete_and_free (ctx); return; } mm_dbg ("Port flashing failed (not fatal): %s", error->message); + g_error_free (error); } g_simple_async_result_set_op_res_gboolean (ctx->result, TRUE); @@ -1379,7 +1384,7 @@ data_reopen_cdma_ready (MMPortSerial *data, mm_port_serial_flash (MM_PORT_SERIAL (ctx->data), 1000, TRUE, - (MMSerialFlashFn)data_flash_cdma_ready, + (GAsyncReadyCallback)data_flash_cdma_ready, ctx); } @@ -1439,9 +1444,13 @@ cgact_data_ready (MMBaseModem *modem, static void data_flash_3gpp_ready (MMPortSerial *data, - GError *error, + GAsyncResult *res, DetailedDisconnectContext *ctx) { + GError *error = NULL; + + mm_port_serial_flash_finish (data, res, &error); + /* We kept the serial port open during connection, now we close that open * count */ mm_port_serial_close (data); @@ -1460,12 +1469,13 @@ data_flash_3gpp_ready (MMPortSerial *data, MM_SERIAL_ERROR, MM_SERIAL_ERROR_FLASH_FAILED)) { /* Fatal */ - g_simple_async_result_set_from_error (ctx->result, error); + g_simple_async_result_take_error (ctx->result, error); detailed_disconnect_context_complete_and_free (ctx); return; } mm_dbg ("Port flashing failed (not fatal): %s", error->message); + g_error_free (error); } /* Don't bother doing the CGACT again if it was already done on the @@ -1509,7 +1519,7 @@ data_reopen_3gpp_ready (MMPortSerial *data, mm_port_serial_flash (MM_PORT_SERIAL (ctx->data), 1000, TRUE, - (MMSerialFlashFn)data_flash_3gpp_ready, + (GAsyncReadyCallback)data_flash_3gpp_ready, ctx); } diff --git a/src/mm-broadband-modem.c b/src/mm-broadband-modem.c index 1997c727..eb49f0c0 100644 --- a/src/mm-broadband-modem.c +++ b/src/mm-broadband-modem.c @@ -7906,17 +7906,18 @@ enabling_modem_init_ready (MMBroadbandModem *self, static void enabling_flash_done (MMPortSerial *port, - GError *error, + GAsyncResult *res, EnablingStartedContext *ctx) { - if (error) { + GError *error = NULL; + + if (!mm_port_serial_flash_finish (port, res, &error)) { g_prefix_error (&error, "Primary port flashing failed: "); - g_simple_async_result_set_from_error (ctx->result, error); + g_simple_async_result_take_error (ctx->result, error); enabling_started_context_complete_and_free (ctx); return; } - if (ctx->modem_init_required) { mm_dbg ("Running modem initialization sequence..."); MM_BROADBAND_MODEM_GET_CLASS (ctx->self)->enabling_modem_init (ctx->self, @@ -8033,7 +8034,7 @@ enabling_started (MMBroadbandModem *self, mm_port_serial_flash (MM_PORT_SERIAL (ctx->ports->primary), 100, FALSE, - (MMSerialFlashFn)enabling_flash_done, + (GAsyncReadyCallback)enabling_flash_done, ctx); } diff --git a/src/mm-port-probe.c b/src/mm-port-probe.c index 35373f25..dd1e18fd 100644 --- a/src/mm-port-probe.c +++ b/src/mm-port-probe.c @@ -1098,10 +1098,12 @@ serial_probe_schedule (MMPortProbe *self) } static void -serial_flash_done (MMPortSerial *port, - GError *error, - MMPortProbe *self) +serial_flash_ready (MMPortSerial *port, + GAsyncResult *res, + MMPortProbe *self) { + mm_port_serial_flash_finish (port, res, NULL); + /* Schedule probing */ serial_probe_schedule (self); } @@ -1232,7 +1234,7 @@ serial_open_at (MMPortProbe *self) mm_port_serial_flash (MM_PORT_SERIAL (task->serial), 100, TRUE, - (MMSerialFlashFn)serial_flash_done, + (GAsyncReadyCallback)serial_flash_ready, self); return FALSE; } diff --git a/src/mm-port-serial.c b/src/mm-port-serial.c index 0a8e79a0..63b95141 100644 --- a/src/mm-port-serial.c +++ b/src/mm-port-serial.c @@ -98,9 +98,9 @@ typedef struct { guint n_consecutive_timeouts; - guint flash_id; guint connected_id; + gpointer flash_ctx; gpointer reopen_ctx; } MMPortSerialPrivate; @@ -1465,25 +1465,73 @@ set_speed (MMPortSerial *self, speed_t speed, GError **error) return TRUE; } +/*****************************************************************************/ +/* Flash */ + typedef struct { - MMPortSerial *port; + GSimpleAsyncResult *result; + MMPortSerial *self; speed_t current_speed; - MMSerialFlashFn callback; - gpointer user_data; -} FlashInfo; + guint flash_id; +} FlashContext; + +static void +flash_context_complete_and_free (FlashContext *ctx) +{ + if (ctx->flash_id) + g_source_remove (ctx->flash_id); + g_simple_async_result_complete_in_idle (ctx->result); + g_object_unref (ctx->result); + g_object_unref (ctx->self); + g_slice_free (FlashContext, ctx); +} + +gboolean +mm_port_serial_flash_finish (MMPortSerial *port, + GAsyncResult *res, + GError **error) +{ + return !g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (res), error); +} + +void +mm_port_serial_flash_cancel (MMPortSerial *self) +{ + MMPortSerialPrivate *priv; + FlashContext *ctx; + + priv = MM_PORT_SERIAL_GET_PRIVATE (self); + if (!priv->flash_ctx) + return; + + /* Recover context */ + ctx = (FlashContext *)priv->flash_ctx; + priv->flash_ctx = NULL; + + g_simple_async_result_set_error (ctx->result, + MM_CORE_ERROR, + MM_CORE_ERROR_CANCELLED, + "Flash cancelled"); + flash_context_complete_and_free (ctx); +} static gboolean -flash_do (gpointer data) +flash_do (MMPortSerial *self) { - FlashInfo *info = (FlashInfo *) data; - MMPortSerialPrivate *priv = MM_PORT_SERIAL_GET_PRIVATE (info->port); + MMPortSerialPrivate *priv = MM_PORT_SERIAL_GET_PRIVATE (self); + FlashContext *ctx; GError *error = NULL; - priv->flash_id = 0; + /* Recover context */ + g_assert (priv->flash_ctx != NULL); + ctx = (FlashContext *)priv->flash_ctx; + priv->flash_ctx = NULL; + + ctx->flash_id = 0; if (priv->flash_ok) { - if (info->current_speed) { - if (!set_speed (info->port, info->current_speed, &error)) + if (ctx->current_speed) { + if (!set_speed (ctx->self, ctx->current_speed, &error)) g_assert (error); } else { error = g_error_new_literal (MM_SERIAL_ERROR, @@ -1492,87 +1540,81 @@ flash_do (gpointer data) } } - info->callback (info->port, error, info->user_data); - g_clear_error (&error); - g_slice_free (FlashInfo, info); + if (error) + g_simple_async_result_take_error (ctx->result, error); + else + g_simple_async_result_set_op_res_gboolean (ctx->result, TRUE); + flash_context_complete_and_free (ctx); + return FALSE; } -gboolean +void mm_port_serial_flash (MMPortSerial *self, guint32 flash_time, gboolean ignore_errors, - MMSerialFlashFn callback, + GAsyncReadyCallback callback, gpointer user_data) { - FlashInfo *info = NULL; + FlashContext *ctx; MMPortSerialPrivate *priv; GError *error = NULL; gboolean success; - g_return_val_if_fail (MM_IS_PORT_SERIAL (self), FALSE); - g_return_val_if_fail (callback != NULL, FALSE); - + g_return_if_fail (MM_IS_PORT_SERIAL (self)); priv = MM_PORT_SERIAL_GET_PRIVATE (self); + /* Setup context */ + ctx = g_slice_new0 (FlashContext); + ctx->self = g_object_ref (self); + ctx->result = g_simple_async_result_new (G_OBJECT (self), + callback, + user_data, + mm_port_serial_flash); + if (!mm_port_serial_is_open (self)) { - error = g_error_new_literal (MM_SERIAL_ERROR, - MM_SERIAL_ERROR_NOT_OPEN, - "The serial port is not open."); - goto error; + g_simple_async_result_set_error (ctx->result, + MM_SERIAL_ERROR, + MM_SERIAL_ERROR_NOT_OPEN, + "The serial port is not open."); + flash_context_complete_and_free (ctx); + return; } - if (priv->flash_id > 0) { - error = g_error_new_literal (MM_CORE_ERROR, - MM_CORE_ERROR_IN_PROGRESS, - "Modem is already being flashed."); - goto error; + if (priv->flash_ctx) { + g_simple_async_result_set_error (ctx->result, + MM_CORE_ERROR, + MM_CORE_ERROR_IN_PROGRESS, + "Modem is already being flashed."); + flash_context_complete_and_free (ctx); + return; } - info = g_slice_new0 (FlashInfo); - info->port = self; - info->callback = callback; - info->user_data = user_data; - - if (priv->flash_ok) { - /* Grab current speed so we can reset it after flashing */ - success = get_speed (self, &info->current_speed, &error); - if (!success && !ignore_errors) - goto error; - g_clear_error (&error); - - success = set_speed (self, B0, &error); - if (!success && !ignore_errors) - goto error; - g_clear_error (&error); - - priv->flash_id = g_timeout_add (flash_time, flash_do, info); - } else - priv->flash_id = g_idle_add (flash_do, info); - - return TRUE; + if (!priv->flash_ok) { + priv->flash_ctx = ctx; + ctx->flash_id = g_idle_add ((GSourceFunc)flash_do, self); + return; + } -error: - callback (self, error, user_data); + /* Grab current speed so we can reset it after flashing */ + success = get_speed (self, &ctx->current_speed, &error); + if (!success && !ignore_errors) { + g_simple_async_result_take_error (ctx->result, error); + flash_context_complete_and_free (ctx); + return; + } g_clear_error (&error); - if (info) - g_slice_free (FlashInfo, info); - return FALSE; -} - -void -mm_port_serial_flash_cancel (MMPortSerial *self) -{ - MMPortSerialPrivate *priv; - g_return_if_fail (MM_IS_PORT_SERIAL (self)); - - priv = MM_PORT_SERIAL_GET_PRIVATE (self); - - if (priv->flash_id > 0) { - g_source_remove (priv->flash_id); - priv->flash_id = 0; + success = set_speed (self, B0, &error); + if (!success && !ignore_errors) { + g_simple_async_result_take_error (ctx->result, error); + flash_context_complete_and_free (ctx); + return; } + g_clear_error (&error); + + priv->flash_ctx = ctx; + ctx->flash_id = g_timeout_add (flash_time, (GSourceFunc)flash_do, self); } gboolean diff --git a/src/mm-port-serial.h b/src/mm-port-serial.h index 34be2193..e724a28b 100644 --- a/src/mm-port-serial.h +++ b/src/mm-port-serial.h @@ -43,10 +43,6 @@ typedef struct _MMPortSerial MMPortSerial; typedef struct _MMPortSerialClass MMPortSerialClass; -typedef void (*MMSerialFlashFn) (MMPortSerial *port, - GError *error, - gpointer user_data); - typedef void (*MMSerialResponseFn) (MMPortSerial *port, GByteArray *response, GError *error, @@ -131,12 +127,14 @@ gboolean mm_port_serial_reopen_finish (MMPortSerial *port, GAsyncResult *res, GError **error); -gboolean mm_port_serial_flash (MMPortSerial *self, +void mm_port_serial_flash (MMPortSerial *self, guint32 flash_time, gboolean ignore_errors, - MMSerialFlashFn callback, + GAsyncReadyCallback callback, gpointer user_data); - +gboolean mm_port_serial_flash_finish (MMPortSerial *self, + GAsyncResult *res, + GError **error); void mm_port_serial_flash_cancel (MMPortSerial *self); gboolean mm_port_serial_get_flash_ok (MMPortSerial *self); |