diff options
Diffstat (limited to 'src/mm-serial-parsers.c')
-rw-r--r-- | src/mm-serial-parsers.c | 78 |
1 files changed, 53 insertions, 25 deletions
diff --git a/src/mm-serial-parsers.c b/src/mm-serial-parsers.c index 344e1bc..4212e19 100644 --- a/src/mm-serial-parsers.c +++ b/src/mm-serial-parsers.c @@ -82,6 +82,7 @@ remove_matches (GRegex *r, GString *string) typedef struct { GRegex *generic_response; GRegex *detailed_error; + GRegex *cms_error; } MMSerialParserV0; gpointer @@ -94,6 +95,7 @@ mm_serial_parser_v0_new (void) parser->generic_response = g_regex_new ("(\\d)\\0?\\r$", flags, 0, NULL); parser->detailed_error = g_regex_new ("\\+CME ERROR:\\s*(\\d+)\\r\\n$", flags, 0, NULL); + parser->cms_error = g_regex_new ("\\+CMS ERROR:\\s*(\\d+)\\r\\n$", flags, 0, NULL); return parser; } @@ -125,8 +127,6 @@ mm_serial_parser_v0_parse (gpointer data, } else code = MM_MOBILE_ERROR_UNKNOWN; - g_match_info_free (match_info); - switch (code) { case 0: /* OK */ break; @@ -155,9 +155,10 @@ mm_serial_parser_v0_parse (gpointer data, remove_matches (parser->generic_response, response); } + g_match_info_free (match_info); + if (!found) { found = g_regex_match_full (parser->detailed_error, response->str, response->len, 0, 0, &match_info, NULL); - if (found) { str = g_match_info_fetch (match_info, 1); if (str) { @@ -166,9 +167,24 @@ mm_serial_parser_v0_parse (gpointer data, } else code = MM_MOBILE_ERROR_UNKNOWN; - g_match_info_free (match_info); local_error = mm_mobile_error_for_code (code); } + g_match_info_free (match_info); + + if (!found) { + found = g_regex_match_full (parser->cms_error, response->str, response->len, 0, 0, &match_info, NULL); + if (found) { + str = g_match_info_fetch (match_info, 1); + if (str) { + code = atoi (str); + g_free (str); + } else + code = MM_MSG_ERROR_UNKNOWN; + + local_error = mm_msg_error_for_code (code); + } + g_match_info_free (match_info); + } } if (found) @@ -191,6 +207,7 @@ mm_serial_parser_v0_destroy (gpointer data) g_regex_unref (parser->generic_response); g_regex_unref (parser->detailed_error); + g_regex_unref (parser->cms_error); g_slice_free (MMSerialParserV0, data); } @@ -204,6 +221,7 @@ typedef struct { GRegex *regex_cme_error; GRegex *regex_cms_error; GRegex *regex_cme_error_str; + GRegex *regex_cms_error_str; GRegex *regex_ezx_error; GRegex *regex_unknown_error; GRegex *regex_connect_failed; @@ -223,6 +241,7 @@ mm_serial_parser_v1_new (void) parser->regex_cme_error = g_regex_new ("\\r\\n\\+CME ERROR:\\s*(\\d+)\\r\\n$", flags, 0, NULL); parser->regex_cms_error = g_regex_new ("\\r\\n\\+CMS ERROR:\\s*(\\d+)\\r\\n$", flags, 0, NULL); parser->regex_cme_error_str = g_regex_new ("\\r\\n\\+CME ERROR:\\s*([^\\n\\r]+)\\r\\n$", flags, 0, NULL); + parser->regex_cms_error_str = g_regex_new ("\\r\\n\\+CMS ERROR:\\s*([^\\n\\r]+)\\r\\n$", flags, 0, NULL); parser->regex_ezx_error = g_regex_new ("\\r\\n\\MODEM ERROR:\\s*(\\d+)\\r\\n$", flags, 0, NULL); parser->regex_unknown_error = g_regex_new ("\\r\\n(ERROR)|(COMMAND NOT SUPPORT)\\r\\n$", flags, 0, NULL); parser->regex_connect_failed = g_regex_new ("\\r\\n(NO CARRIER)|(BUSY)|(NO ANSWER)|(NO DIALTONE)\\r\\n$", flags, 0, NULL); @@ -260,13 +279,17 @@ mm_serial_parser_v1_parse (gpointer data, GMatchInfo *match_info; GError *local_error = NULL; gboolean found = FALSE; - char *str; + char *str = NULL; int code; g_return_val_if_fail (parser != NULL, FALSE); g_return_val_if_fail (response != NULL, FALSE); - if (G_UNLIKELY (!response->len || !strlen (response->str))) + /* Skip NUL bytes if they are found leading the response */ + while (response->len > 0 && response->str[0] == '\0') + g_string_erase (response, 0, 1); + + if (G_UNLIKELY (!response->len)) return FALSE; /* First, check for successful responses */ @@ -306,10 +329,9 @@ mm_serial_parser_v1_parse (gpointer data, str = g_match_info_fetch (match_info, 1); g_assert (str); local_error = mm_mobile_error_for_code (atoi (str)); - g_free (str); - g_match_info_free (match_info); goto done; } + g_match_info_free (match_info); } /* Numeric CME errors */ @@ -320,27 +342,21 @@ mm_serial_parser_v1_parse (gpointer data, str = g_match_info_fetch (match_info, 1); g_assert (str); local_error = mm_mobile_error_for_code (atoi (str)); - g_free (str); - g_match_info_free (match_info); goto done; } + g_match_info_free (match_info); /* Numeric CMS errors */ - /* Todo - * One should probably add message service - * errors explicitly in mm-errors.h/c - */ found = g_regex_match_full (parser->regex_cms_error, response->str, response->len, 0, 0, &match_info, NULL); if (found) { str = g_match_info_fetch (match_info, 1); g_assert (str); - local_error = mm_mobile_error_for_code (atoi (str)); - g_free (str); - g_match_info_free (match_info); + local_error = mm_msg_error_for_code (atoi (str)); goto done; } + g_match_info_free (match_info); /* String CME errors */ found = g_regex_match_full (parser->regex_cme_error_str, @@ -350,10 +366,21 @@ mm_serial_parser_v1_parse (gpointer data, str = g_match_info_fetch (match_info, 1); g_assert (str); local_error = mm_mobile_error_for_string (str); - g_free (str); - g_match_info_free (match_info); goto done; } + g_match_info_free (match_info); + + /* String CMS errors */ + found = g_regex_match_full (parser->regex_cms_error_str, + response->str, response->len, + 0, 0, &match_info, NULL); + if (found) { + str = g_match_info_fetch (match_info, 1); + g_assert (str); + local_error = mm_msg_error_for_string (str); + goto done; + } + g_match_info_free (match_info); /* Motorola EZX errors */ found = g_regex_match_full (parser->regex_ezx_error, @@ -363,19 +390,19 @@ mm_serial_parser_v1_parse (gpointer data, str = g_match_info_fetch (match_info, 1); g_assert (str); local_error = mm_mobile_error_for_code (MM_MOBILE_ERROR_UNKNOWN); - g_free (str); - g_match_info_free (match_info); goto done; } + g_match_info_free (match_info); /* Last resort; unknown error */ found = g_regex_match_full (parser->regex_unknown_error, response->str, response->len, - 0, 0, NULL, NULL); + 0, 0, &match_info, NULL); if (found) { local_error = mm_mobile_error_for_code (MM_MOBILE_ERROR_UNKNOWN); goto done; } + g_match_info_free (match_info); /* Connection failures */ found = g_regex_match_full (parser->regex_connect_failed, @@ -398,13 +425,12 @@ mm_serial_parser_v1_parse (gpointer data, code = MM_MODEM_CONNECT_ERROR_NO_CARRIER; } - g_free (str); - g_match_info_free (match_info); - local_error = mm_modem_connect_error_for_code (code); } done: + g_free (str); + g_match_info_free (match_info); if (found) response_clean (response); @@ -426,7 +452,9 @@ mm_serial_parser_v1_destroy (gpointer data) g_regex_unref (parser->regex_ok); g_regex_unref (parser->regex_connect); g_regex_unref (parser->regex_cme_error); + g_regex_unref (parser->regex_cms_error); g_regex_unref (parser->regex_cme_error_str); + g_regex_unref (parser->regex_cms_error_str); g_regex_unref (parser->regex_ezx_error); g_regex_unref (parser->regex_unknown_error); g_regex_unref (parser->regex_connect_failed); |