aboutsummaryrefslogtreecommitdiff
path: root/src/mm-port-serial-at.c
diff options
context:
space:
mode:
authorAleksander Morgado <aleksander@aleksander.es>2016-01-18 18:23:40 +0100
committerAleksander Morgado <aleksander@aleksander.es>2016-01-23 11:19:19 +0100
commit97962bb65caaabc4133740a2698dae2406be319e (patch)
treede72f4b2fc5bbb356ad4f6fc4c3d0faa6d3f8cdf /src/mm-port-serial-at.c
parentede17bd41c044af1d59b347f8859a9894272d27e (diff)
port-serial: rework response parsing
Response parsing was being done in different places for AT and QCDM subclasses; in the case of AT it was being done early, before returning the byte array in the mm_serial_port_command_finish() response. In the case of QCDM, it was being done after mm_serial_port_command_finish(), and that was forcing every caller to cleanup the response buffer once the response was processed. With the new logic in this patch, the response is always parsed (i.e. looked for a valid response or an error detected) before mm_serial_port_command_finish() returns, and actually this method now returns a totally different GByteArray, not the internal response buffer GByteArray, so there's no longer any need for the caller to explicitly clean it up. The one doing the cleanup is the parser method itself in every case. This change also allows us to return serial port responses in idle, but that's not changed for now as there's no immediate need.
Diffstat (limited to 'src/mm-port-serial-at.c')
-rw-r--r--src/mm-port-serial-at.c45
1 files changed, 32 insertions, 13 deletions
diff --git a/src/mm-port-serial-at.c b/src/mm-port-serial-at.c
index 553596e8..8e2aa2aa 100644
--- a/src/mm-port-serial-at.c
+++ b/src/mm-port-serial-at.c
@@ -116,14 +116,16 @@ mm_port_serial_at_remove_echo (GByteArray *response)
}
}
-static gboolean
+static MMPortSerialResponseType
parse_response (MMPortSerial *port,
GByteArray *response,
+ GByteArray **parsed_response,
GError **error)
{
MMPortSerialAt *self = MM_PORT_SERIAL_AT (port);
- gboolean found;
GString *string;
+ gsize parsed_len;
+ GError *inner_error = NULL;
g_return_val_if_fail (self->priv->response_parser_fn != NULL, FALSE);
@@ -131,21 +133,38 @@ parse_response (MMPortSerial *port,
if (self->priv->remove_echo)
mm_port_serial_at_remove_echo (response);
+ /* If there's no response to receive, we're done; e.g. if we only got
+ * unsolicited messages */
+ if (!response->len)
+ return MM_PORT_SERIAL_RESPONSE_NONE;
+
/* Construct the string that AT-parsing functions expect */
string = g_string_sized_new (response->len + 1);
g_string_append_len (string, (const char *) response->data, response->len);
- /* Parse it */
- found = self->priv->response_parser_fn (self->priv->response_parser_user_data, string, error);
-
- /* And copy it back into the response array after the parser has removed
- * matches and cleaned it up.
- */
- if (response->len)
- g_byte_array_remove_range (response, 0, response->len);
- g_byte_array_append (response, (const guint8 *) string->str, string->len);
- g_string_free (string, TRUE);
- return found;
+ /* Fully cleanup the response array, we'll consider the contents we got
+ * as the full reply that the command may expect. */
+ g_byte_array_remove_range (response, 0, response->len);
+
+ /* Parse it; returns FALSE if there is nothing we can do with this
+ * response yet. */
+ if (!self->priv->response_parser_fn (self->priv->response_parser_user_data, string, &inner_error)) {
+ /* Copy what we got back in the response buffer. */
+ g_byte_array_append (response, (const guint8 *) string->str, string->len);
+ g_string_free (string, TRUE);
+ return MM_PORT_SERIAL_RESPONSE_NONE;
+ }
+
+ /* If we got an error, propagate it without any further response string */
+ if (inner_error) {
+ g_propagate_error (error, inner_error);
+ return MM_PORT_SERIAL_RESPONSE_ERROR;
+ }
+
+ /* Otherwise, build a new GByteArray considered as parsed response */
+ parsed_len = string->len;
+ *parsed_response = g_byte_array_new_take ((guint8 *) g_string_free (string, FALSE), parsed_len);
+ return MM_PORT_SERIAL_RESPONSE_BUFFER;
}
/*****************************************************************************/