diff options
Diffstat (limited to 'src/mm-port-serial-at.c')
-rw-r--r-- | src/mm-port-serial-at.c | 45 |
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; } /*****************************************************************************/ |