From 4e4d139e309c890b2c5c44b747aeaf9a5deac9bc Mon Sep 17 00:00:00 2001 From: Aleksander Morgado Date: Wed, 3 Apr 2013 12:24:18 +0200 Subject: 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. --- src/mm-serial-parsers.c | 36 ++++++++++++++++++++++++++++++++++-- 1 file changed, 34 insertions(+), 2 deletions(-) (limited to 'src/mm-serial-parsers.c') 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 -- cgit v1.2.3-70-g09d2