aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/mm-base-modem-at.c107
-rw-r--r--src/mm-port-probe.c35
-rw-r--r--src/mm-port-serial-at.c130
-rw-r--r--src/mm-port-serial-at.h31
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