aboutsummaryrefslogtreecommitdiff
path: root/src/mm-serial-parsers.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/mm-serial-parsers.c')
-rw-r--r--src/mm-serial-parsers.c78
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);