diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/mm-base-modem-at.c | 107 | ||||
-rw-r--r-- | src/mm-port-probe.c | 35 | ||||
-rw-r--r-- | src/mm-port-serial-at.c | 130 | ||||
-rw-r--r-- | src/mm-port-serial-at.h | 31 |
4 files changed, 162 insertions, 141 deletions
diff --git a/src/mm-base-modem-at.c b/src/mm-base-modem-at.c index 0b3c5a12..77661e5b 100644 --- a/src/mm-base-modem-at.c +++ b/src/mm-base-modem-at.c @@ -154,14 +154,17 @@ mm_base_modem_at_sequence_full_finish (MMBaseModem *self, static void at_sequence_parse_response (MMPortSerialAt *port, - GString *response, - GError *error, + GAsyncResult *res, AtSequenceContext *ctx) { GVariant *result = NULL; GError *result_error = NULL; gboolean continue_sequence; GSimpleAsyncResult *simple; + const gchar *response; + GError *error = NULL; + + response = mm_port_serial_at_command_finish (port, res, &error); /* Cancelled? */ if (g_cancellable_is_cancelled (ctx->cancellable)) { @@ -169,6 +172,8 @@ at_sequence_parse_response (MMPortSerialAt *port, MM_CORE_ERROR, MM_CORE_ERROR_CANCELLED, "AT sequence was cancelled"); + if (error) + g_error_free (error); g_simple_async_result_complete (ctx->simple); at_sequence_context_free (ctx); return; @@ -185,7 +190,7 @@ at_sequence_parse_response (MMPortSerialAt *port, ctx->self, ctx->response_processor_context, ctx->current->command, - response ? response->str : NULL, + response, next->command ? FALSE : TRUE, /* Last command in sequence? */ error, &result, @@ -196,33 +201,29 @@ at_sequence_parse_response (MMPortSerialAt *port, g_simple_async_result_take_error (ctx->simple, result_error); g_simple_async_result_complete (ctx->simple); at_sequence_context_free (ctx); + if (error) + g_error_free (error); return; } } + if (error) + g_error_free (error); + if (continue_sequence) { g_assert (result == NULL); ctx->current++; if (ctx->current->command) { /* Schedule the next command in the probing group */ - if (ctx->current->allow_cached) - mm_port_serial_at_queue_command_cached ( - ctx->port, - ctx->current->command, - ctx->current->timeout, - FALSE, - ctx->cancellable, - (MMPortSerialAtResponseFn)at_sequence_parse_response, - ctx); - else - mm_port_serial_at_queue_command ( - ctx->port, - ctx->current->command, - ctx->current->timeout, - FALSE, - ctx->cancellable, - (MMPortSerialAtResponseFn)at_sequence_parse_response, - ctx); + mm_port_serial_at_command ( + ctx->port, + ctx->current->command, + ctx->current->timeout, + FALSE, + ctx->current->allow_cached, + ctx->cancellable, + (GAsyncReadyCallback)at_sequence_parse_response, + ctx); return; } @@ -295,13 +296,14 @@ mm_base_modem_at_sequence_full (MMBaseModem *self, } /* Go on with the first one in the sequence */ - mm_port_serial_at_queue_command ( + mm_port_serial_at_command ( ctx->port, ctx->current->command, ctx->current->timeout, FALSE, + FALSE, ctx->cancellable, - (MMPortSerialAtResponseFn)at_sequence_parse_response, + (GAsyncReadyCallback)at_sequence_parse_response, ctx); } @@ -470,32 +472,34 @@ mm_base_modem_at_command_full_finish (MMBaseModem *self, } static void -at_command_parse_response (MMPortSerialAt *port, - GString *response, - GError *error, - AtCommandContext *ctx) +at_command_ready (MMPortSerialAt *port, + GAsyncResult *res, + AtCommandContext *ctx) { + const gchar *response; + GError *error = NULL; + + response = mm_port_serial_at_command_finish (port, res, &error); + /* Cancelled? */ - if (g_cancellable_is_cancelled (ctx->cancellable)) + if (g_cancellable_is_cancelled (ctx->cancellable)) { g_simple_async_result_set_error (ctx->result, MM_CORE_ERROR, MM_CORE_ERROR_CANCELLED, "AT command was cancelled"); - + if (error) + g_error_free (error); + } /* Error coming from the serial port? */ else if (error) - g_simple_async_result_set_from_error (ctx->result, error); - + g_simple_async_result_take_error (ctx->result, error); /* Valid string response */ - else if (response && response->str) - g_simple_async_result_set_op_res_gpointer (ctx->result, - g_strdup (response->str), - g_free); - - /* No response */ + else if (response) + g_simple_async_result_set_op_res_gpointer (ctx->result, (gchar *)response, NULL); else - g_simple_async_result_set_op_res_gpointer (ctx->result, NULL, NULL); + g_assert_not_reached (); + /* Never in idle! */ g_simple_async_result_complete (ctx->result); at_command_context_free (ctx); } @@ -542,24 +546,15 @@ mm_base_modem_at_command_full (MMBaseModem *self, } /* Go on with the command */ - if (allow_cached) - mm_port_serial_at_queue_command_cached ( - port, - command, - timeout, - is_raw, - ctx->cancellable, - (MMPortSerialAtResponseFn)at_command_parse_response, - ctx); - else - mm_port_serial_at_queue_command ( - port, - command, - timeout, - is_raw, - ctx->cancellable, - (MMPortSerialAtResponseFn)at_command_parse_response, - ctx); + mm_port_serial_at_command ( + port, + command, + timeout, + is_raw, + allow_cached, + ctx->cancellable, + (GAsyncReadyCallback)at_command_ready, + ctx); } const gchar * diff --git a/src/mm-port-probe.c b/src/mm-port-probe.c index 0198f1ca..35373f25 100644 --- a/src/mm-port-probe.c +++ b/src/mm-port-probe.c @@ -865,17 +865,20 @@ serial_probe_at_result_processor (MMPortProbe *self, static void serial_probe_at_parse_response (MMPortSerialAt *port, - GString *response, - GError *error, + GAsyncResult *res, MMPortProbe *self) { PortProbeRunTask *task = self->priv->task; GVariant *result = NULL; GError *result_error = NULL; + const gchar *response; + GError *error = NULL; + + response = mm_port_serial_at_command_finish (port, res, &error); /* If already cancelled, do nothing else */ if (port_probe_run_is_cancelled (self)) - return; + goto out; /* If AT probing cancelled, end this partial probing */ if (g_cancellable_is_cancelled (task->at_probing_cancellable)) { @@ -884,11 +887,11 @@ serial_probe_at_parse_response (MMPortSerialAt *port, g_udev_device_get_name (self->priv->port)); task->at_result_processor (self, NULL); serial_probe_schedule (self); - return; + goto out; } if (!task->at_commands->response_processor (task->at_commands->command, - response ? response->str : NULL, + response, !!task->at_commands[1].command, error, &result, @@ -904,8 +907,7 @@ serial_probe_at_parse_response (MMPortSerialAt *port, g_udev_device_get_subsystem (self->priv->port), g_udev_device_get_name (self->priv->port), result_error->message)); - g_error_free (result_error); - return; + goto out; } /* Go on to next command */ @@ -916,22 +918,28 @@ serial_probe_at_parse_response (MMPortSerialAt *port, task->at_result_processor (self, NULL); /* Reschedule */ serial_probe_schedule (self); - return; + goto out; } /* Schedule the next command in the probing group */ task->source_id = g_idle_add ((GSourceFunc)serial_probe_at, self); - return; + goto out; } /* Run result processor. * Note that custom init commands are allowed to not return anything */ task->at_result_processor (self, result); - if (result) - g_variant_unref (result); /* Reschedule probing */ serial_probe_schedule (self); + +out: + if (result) + g_variant_unref (result); + if (error) + g_error_free (error); + if (result_error) + g_error_free (result_error); } static gboolean @@ -955,13 +963,14 @@ serial_probe_at (MMPortProbe *self) return FALSE; } - mm_port_serial_at_queue_command ( + mm_port_serial_at_command ( MM_PORT_SERIAL_AT (task->serial), task->at_commands->command, task->at_commands->timeout, FALSE, + FALSE, task->at_probing_cancellable, - (MMPortSerialAtResponseFn)serial_probe_at_parse_response, + (GAsyncReadyCallback)serial_probe_at_parse_response, self); return FALSE; } diff --git a/src/mm-port-serial-at.c b/src/mm-port-serial-at.c index a8f95133..780bfbb9 100644 --- a/src/mm-port-serial-at.c +++ b/src/mm-port-serial-at.c @@ -158,16 +158,9 @@ handle_response (MMPortSerial *port, GCallback callback, gpointer callback_data) { - MMPortSerialAt *self = MM_PORT_SERIAL_AT (port); - MMPortSerialAtResponseFn response_callback = (MMPortSerialAtResponseFn) callback; - GString *string; - - /* Convert to a string and call the callback */ - string = g_string_sized_new (response->len + 1); - g_string_append_len (string, (const char *) response->data, response->len); - response_callback (self, string, error, callback_data); - g_string_free (string, TRUE); + MMSerialResponseFn response_callback = (MMSerialResponseFn) callback; + response_callback (port, response, error, callback_data); return response->len; } @@ -350,43 +343,61 @@ at_command_to_byte_array (const char *command, gboolean is_raw, gboolean send_lf return buf; } -void -mm_port_serial_at_queue_command (MMPortSerialAt *self, - const char *command, - guint32 timeout_seconds, - gboolean is_raw, - GCancellable *cancellable, - MMPortSerialAtResponseFn callback, - gpointer user_data) +const gchar * +mm_port_serial_at_command_finish (MMPortSerialAt *self, + GAsyncResult *res, + GError **error) { - GByteArray *buf; - MMPortSerialAtPrivate *priv = MM_PORT_SERIAL_AT_GET_PRIVATE (self); + GString *str; - g_return_if_fail (self != NULL); - g_return_if_fail (MM_IS_PORT_SERIAL_AT (self)); - g_return_if_fail (command != NULL); + if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (res), error)) + return NULL; - buf = at_command_to_byte_array (command, is_raw, priv->send_lf); - g_return_if_fail (buf != NULL); + str = (GString *)g_simple_async_result_get_op_res_gpointer (G_SIMPLE_ASYNC_RESULT (res)); + return str->str; +} - mm_port_serial_queue_command (MM_PORT_SERIAL (self), - buf, - TRUE, - timeout_seconds, - cancellable, - (MMSerialResponseFn) callback, - user_data); +static void +string_free (GString *str) +{ + g_string_free (str, TRUE); +} + +static void +serial_command_ready (MMPortSerial *port, + GByteArray *response, + GError *error, + GSimpleAsyncResult *simple) +{ + if (error) + g_simple_async_result_set_from_error (simple, error); + else if (response) { + GString *str; + + /* Build a GString just with the response we need, and clear the + * processed range from the response buffer */ + str = g_string_new_len ((const gchar *)response->data, response->len); + g_simple_async_result_set_op_res_gpointer (simple, + str, + (GDestroyNotify)string_free); + } else + g_assert_not_reached (); + + g_simple_async_result_complete (simple); + g_object_unref (simple); } void -mm_port_serial_at_queue_command_cached (MMPortSerialAt *self, - const char *command, - guint32 timeout_seconds, - gboolean is_raw, - GCancellable *cancellable, - MMPortSerialAtResponseFn callback, - gpointer user_data) +mm_port_serial_at_command (MMPortSerialAt *self, + const char *command, + guint32 timeout_seconds, + gboolean is_raw, + gboolean allow_cached, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) { + GSimpleAsyncResult *simple; GByteArray *buf; MMPortSerialAtPrivate *priv = MM_PORT_SERIAL_AT_GET_PRIVATE (self); @@ -397,13 +408,27 @@ mm_port_serial_at_queue_command_cached (MMPortSerialAt *self, buf = at_command_to_byte_array (command, is_raw, priv->send_lf); g_return_if_fail (buf != NULL); - mm_port_serial_queue_command_cached (MM_PORT_SERIAL (self), - buf, - TRUE, - timeout_seconds, - cancellable, - (MMSerialResponseFn) callback, - user_data); + simple = g_simple_async_result_new (G_OBJECT (self), + callback, + user_data, + mm_port_serial_at_command); + + if (!allow_cached) + mm_port_serial_queue_command (MM_PORT_SERIAL (self), + buf, + TRUE, + timeout_seconds, + cancellable, + (MMSerialResponseFn)serial_command_ready, + simple); + else + mm_port_serial_queue_command_cached (MM_PORT_SERIAL (self), + buf, + TRUE, + timeout_seconds, + cancellable, + (MMSerialResponseFn)serial_command_ready, + simple); } static void @@ -474,13 +499,14 @@ mm_port_serial_at_run_init_sequence (MMPortSerialAt *self) /* Just queue the init commands, don't wait for reply */ for (i = 0; priv->init_sequence[i]; i++) { - mm_port_serial_at_queue_command (self, - priv->init_sequence[i], - 3, - FALSE, - NULL, - NULL, - NULL); + mm_port_serial_at_command (self, + priv->init_sequence[i], + 3, + FALSE, + FALSE, + NULL, + NULL, + NULL); } } diff --git a/src/mm-port-serial-at.h b/src/mm-port-serial-at.h index 58cf51c1..52e6c604 100644 --- a/src/mm-port-serial-at.h +++ b/src/mm-port-serial-at.h @@ -60,11 +60,6 @@ typedef void (*MMPortSerialAtUnsolicitedMsgFn) (MMPortSerialAt *port, GMatchInfo *match_info, gpointer user_data); -typedef void (*MMPortSerialAtResponseFn) (MMPortSerialAt *port, - GString *response, - GError *error, - gpointer user_data); - #define MM_PORT_SERIAL_AT_REMOVE_ECHO "remove-echo" #define MM_PORT_SERIAL_AT_INIT_SEQUENCE_ENABLED "init-sequence-enabled" #define MM_PORT_SERIAL_AT_INIT_SEQUENCE "init-sequence" @@ -97,21 +92,17 @@ void mm_port_serial_at_set_response_parser (MMPortSerialAt *self, gpointer user_data, GDestroyNotify notify); -void mm_port_serial_at_queue_command (MMPortSerialAt *self, - const char *command, - guint32 timeout_seconds, - gboolean is_raw, - GCancellable *cancellable, - MMPortSerialAtResponseFn callback, - gpointer user_data); - -void mm_port_serial_at_queue_command_cached (MMPortSerialAt *self, - const char *command, - guint32 timeout_seconds, - gboolean is_raw, - GCancellable *cancellable, - MMPortSerialAtResponseFn callback, - gpointer user_data); +void mm_port_serial_at_command (MMPortSerialAt *self, + const char *command, + guint32 timeout_seconds, + gboolean is_raw, + gboolean allow_cached, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); +const gchar *mm_port_serial_at_command_finish (MMPortSerialAt *self, + GAsyncResult *res, + GError **error); /* * Convert a string into a quoted and escaped string. Returns a new |