aboutsummaryrefslogtreecommitdiff
path: root/src/mm-serial-parsers.c
diff options
context:
space:
mode:
authorAleksander Morgado <aleksander@lanedo.com>2013-04-03 12:24:18 +0200
committerAleksander Morgado <aleksander@lanedo.com>2013-04-04 19:26:51 +0200
commit4e4d139e309c890b2c5c44b747aeaf9a5deac9bc (patch)
tree5c8b1edfd18a514946cc9ed2213641f25b601c8e /src/mm-serial-parsers.c
parent38b120c8617724ba97ac212c9e01d01c850abdc8 (diff)
serial-parsers: allow specifying a custom response filter
The serial parser will now allow specifying a custom user-provided filter, which is applied before even trying to match successful/error responses. This filter provides a very early barrier to detect strings that are clearly not going to match. E.g. this filter may be used during port probing to early detect non-AT ports.
Diffstat (limited to 'src/mm-serial-parsers.c')
-rw-r--r--src/mm-serial-parsers.c36
1 files changed, 34 insertions, 2 deletions
diff --git a/src/mm-serial-parsers.c b/src/mm-serial-parsers.c
index 53b22a81..a267d046 100644
--- a/src/mm-serial-parsers.c
+++ b/src/mm-serial-parsers.c
@@ -94,6 +94,9 @@ typedef struct {
GRegex *regex_unknown_error;
GRegex *regex_connect_failed;
GRegex *regex_custom_error;
+ /* User-provided parser filter */
+ mm_serial_parser_v1_filter_fn filter_callback;
+ gpointer filter_user_data;
} MMSerialParserV1;
gpointer
@@ -117,6 +120,8 @@ mm_serial_parser_v1_new (void)
parser->regex_custom_successful = NULL;
parser->regex_custom_error = NULL;
+ parser->filter_callback = NULL;
+ parser->filter_user_data = NULL;
return parser;
}
@@ -139,6 +144,19 @@ mm_serial_parser_v1_set_custom_regex (gpointer data,
parser->regex_custom_error = error ? g_regex_ref (error) : NULL;
}
+void
+mm_serial_parser_v1_add_filter (gpointer data,
+ mm_serial_parser_v1_filter_fn callback,
+ gpointer user_data)
+{
+ MMSerialParserV1 *parser = (MMSerialParserV1 *) data;
+
+ g_return_if_fail (parser != NULL);
+
+ parser->filter_callback = callback;
+ parser->filter_user_data = user_data;
+}
+
gboolean
mm_serial_parser_v1_parse (gpointer data,
GString *response,
@@ -160,7 +178,20 @@ mm_serial_parser_v1_parse (gpointer data,
if (G_UNLIKELY (!response->len))
return FALSE;
- /* First, check for successful responses */
+ /* First, apply custom filter if any */
+ if (parser->filter_callback &&
+ !parser->filter_callback (parser,
+ parser->filter_user_data,
+ response,
+ &local_error)) {
+ g_assert (local_error != NULL);
+ mm_dbg ("Got response filtered in serial port: %s", local_error->message);
+ g_propagate_error (error, local_error);
+ response_clean (response);
+ return TRUE;
+ }
+
+ /* Then, check for successful responses */
/* Custom successful replies first, if any */
if (parser->regex_custom_successful) {
@@ -326,7 +357,8 @@ mm_serial_parser_v1_is_known_error (const GError *error)
/* Need to return TRUE for the kind of errors that this parser may set */
return (error->domain == MM_MOBILE_EQUIPMENT_ERROR ||
error->domain == MM_CONNECTION_ERROR ||
- error->domain == MM_MESSAGE_ERROR);
+ error->domain == MM_MESSAGE_ERROR ||
+ g_error_matches (error, MM_SERIAL_ERROR, MM_SERIAL_ERROR_PARSE_FAILED));
}
void