[RFC PATCH] serial-parsers: remove matched errors from response

Dan Williams dcbw at redhat.com
Tue Feb 18 11:35:52 PST 2014


The matched errors don't need to stick around in the response
buffer since they are already handled via GErrors.

Fixes probing with slow-responding Sierra USB305 (Icera) devices
on hotplug where an error is returned for early ATI probes, but
since the response is not valid, the error hangs around in the
response buffer and confuses further queries.  Removing the
matched error allows the response to be recognized because
later parsing does not return an error.

[mm-port-serial-at.c:440] debug_log(): (ttyUSB2): --> 'ATI<CR>'
[mm-port-serial-at.c:440] debug_log(): (ttyUSB2): <-- 'ATI'
ModemManager[6232]: mm_serial_parser_v1_parse: response 'TI
ERRORATI'
^^^ error still in the buffer from earlier ATI probe

[mm-serial-parsers.c:367] mm_serial_parser_v1_parse(): Got failure code 100: Unknown error
[mm-port-probe.c:161] mm_port_probe_set_result_at(): (tty/ttyUSB2) port is not AT-capable
[mm-port-serial-at.c:440] debug_log(): (ttyUSB2): --> 'ATI<CR>'
[mm-port-serial-at.c:440] debug_log(): (ttyUSB2): <-- '<CR><CR><LF>Manufacturer: Sierra Wireless, Inc.<CR><LF>Model: USB 305<CR><LF>Revision: I2_0_0_11ap CARMD-EN000104 2010/03/12 15:12:01<CR><LF>IMEI: xxxxx<CR><LF>IMEI SV: 7<CR><LF>FSN: xxxxx<CR><LF>PRI: 9993577 01.00<CR><LF>KI: P,A1,D1<CR><LF>3GPP Release 6<CR><LF>A<CR><LF>OK<CR><LF>TI'
ModemManager[6232]: mm_serial_parser_v1_parse: response 'TI
ERRORATI
Manufacturer: Sierra Wireless, Inc.
Model: USB 305
Revision: I2_0_0_11ap CARMD-EN000104 2010/03/12 15:12:01
IMEI: xxxxx
IMEI SV: 7
FSN: xxxxx
PRI: 9993577 01.00
KI: P,A1,D1
3GPP Release 6
A
OK
TI'
[mm-serial-parsers.c:367] mm_serial_parser_v1_parse(): Got failure code 100: Unknown error
^^^ error *still* in buffer; confuses parser for valid ATI response

[mm-port-probe.c:161] mm_port_probe_set_result_at(): (tty/ttyUSB2) port is not AT-capable
[sierra/mm-plugin-sierra.c:171] sierra_custom_init_step(): (Sierra) Couldn't get port type hints from 'ttyUSB2'
---
 src/mm-broadband-modem.c |  2 +-
 src/mm-serial-parsers.c  | 16 ++++++++++++++++
 2 files changed, 17 insertions(+), 1 deletion(-)

diff --git a/src/mm-broadband-modem.c b/src/mm-broadband-modem.c
index c9b438a..86539d4 100644
--- a/src/mm-broadband-modem.c
+++ b/src/mm-broadband-modem.c
@@ -419,15 +419,15 @@ parse_caps_gcap (MMBaseModem *self,
 
     if (!response)
         return FALSE;
 
     /* Some modems (Huawei E160g) won't respond to +GCAP with no SIM, but
      * will respond to ATI.  Ignore the error and continue.
      */
-    if (strstr (response, "+CME ERROR:"))
+    if (error && (error->domain == MM_MOBILE_EQUIPMENT_ERROR))
         return FALSE;
 
     while (cap->name) {
         if (strstr (response, cap->name))
             ret |= cap->bits;
         cap++;
     }
diff --git a/src/mm-serial-parsers.c b/src/mm-serial-parsers.c
index b7bb308..4a7889f 100644
--- a/src/mm-serial-parsers.c
+++ b/src/mm-serial-parsers.c
@@ -232,87 +232,100 @@ mm_serial_parser_v1_parse (gpointer data,
 
     /* Custom error matches first, if any */
     if (parser->regex_custom_error) {
         found = g_regex_match_full (parser->regex_custom_error,
                                     response->str, response->len,
                                     0, 0, &match_info, NULL);
         if (found) {
+            remove_matches (parser->regex_custom_error, response);
+
             str = g_match_info_fetch (match_info, 1);
             g_assert (str);
             local_error = mm_mobile_equipment_error_for_code (atoi (str));
             goto done;
         }
         g_match_info_free (match_info);
     }
 
     /* Numeric CME errors */
     found = g_regex_match_full (parser->regex_cme_error,
                                 response->str, response->len,
                                 0, 0, &match_info, NULL);
     if (found) {
+        remove_matches (parser->regex_cme_error, response);
+
         str = g_match_info_fetch (match_info, 1);
         g_assert (str);
         local_error = mm_mobile_equipment_error_for_code (atoi (str));
         goto done;
     }
     g_match_info_free (match_info);
 
     /* Numeric CMS errors */
     found = g_regex_match_full (parser->regex_cms_error,
                                 response->str, response->len,
                                 0, 0, &match_info, NULL);
     if (found) {
+        remove_matches (parser->regex_cms_error, response);
+
         str = g_match_info_fetch (match_info, 1);
         g_assert (str);
         local_error = mm_message_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,
                                 response->str, response->len,
                                 0, 0, &match_info, NULL);
     if (found) {
+        remove_matches (parser->regex_cme_error_str, response);
+
         str = g_match_info_fetch (match_info, 1);
         g_assert (str);
         local_error = mm_mobile_equipment_error_for_string (str);
         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) {
+        remove_matches (parser->regex_cms_error_str, response);
+
         str = g_match_info_fetch (match_info, 1);
         g_assert (str);
         local_error = mm_message_error_for_string (str);
         goto done;
     }
     g_match_info_free (match_info);
 
     /* Motorola EZX errors */
     found = g_regex_match_full (parser->regex_ezx_error,
                                 response->str, response->len,
                                 0, 0, &match_info, NULL);
     if (found) {
+        remove_matches (parser->regex_ezx_error, response);
+
         str = g_match_info_fetch (match_info, 1);
         g_assert (str);
         local_error = mm_mobile_equipment_error_for_code (MM_MOBILE_EQUIPMENT_ERROR_UNKNOWN);
         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, &match_info, NULL);
     if (found) {
+        remove_matches (parser->regex_unknown_error, response);
         local_error = mm_mobile_equipment_error_for_code (MM_MOBILE_EQUIPMENT_ERROR_UNKNOWN);
         goto done;
     }
     g_match_info_free (match_info);
 
     /* Connection failures */
     found = g_regex_match_full (parser->regex_connect_failed,
@@ -333,24 +346,27 @@ mm_serial_parser_v1_parse (gpointer data,
         else if (!strcmp (str, "NO DIALTONE"))
             code = MM_CONNECTION_ERROR_NO_DIALTONE;
         else {
             /* uhm... make something up (yes, ok, lie!). */
             code = MM_CONNECTION_ERROR_NO_CARRIER;
         }
 
+        remove_matches (parser->regex_connect_failed, response);
         local_error = mm_connection_error_for_code (code);
         goto done;
     }
     g_match_info_free (match_info);
 
     /* NA error */
     found = g_regex_match_full (parser->regex_na,
                                 response->str, response->len,
                                 0, 0, &match_info, NULL);
     if (found) {
+        remove_matches (parser->regex_na, response);
+
         /* Assume NA means 'Not Allowed' :) */
         local_error = g_error_new (MM_MOBILE_EQUIPMENT_ERROR,
                                    MM_MOBILE_EQUIPMENT_ERROR_NOT_ALLOWED,
                                    "Not Allowed");
         goto done;
     }
 
-- 
1.8.5.3




More information about the ModemManager-devel mailing list