<div dir="ltr">I guess we can't expect too much from AT commands/responses, except them being a string... Perhaps it's time to move on to MBIM :)<div><br></div><div>In the meantime, we can probably proceed with these two patches:</div>

<div><a href="http://lists.freedesktop.org/archives/modemmanager-devel/2013-August/000113.html">http://lists.freedesktop.org/archives/modemmanager-devel/2013-August/000113.html</a><br></div><div><a href="http://lists.freedesktop.org/archives/modemmanager-devel/2013-August/000114.html">http://lists.freedesktop.org/archives/modemmanager-devel/2013-August/000114.html</a><br>

</div><div><br></div><div>Thanks,<br><div>Ben</div></div></div><div class="gmail_extra"><br><br><div class="gmail_quote">On Tue, Aug 6, 2013 at 10:52 AM, Dan Williams <span dir="ltr"><<a href="mailto:dcbw@redhat.com" target="_blank">dcbw@redhat.com</a>></span> wrote:<br>

<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div class="im">On Tue, 2013-08-06 at 10:15 -0700, Ben Chan wrote:<br>
> Thanks Dan.  Looks like we sometimes need to ignore the ^PDPDEACT<br>
> unsolicited messages as well.<br>
><br>
> <debug> [000141.977013] [mm-at-serial-port.c:408] debug_log(): (ttyUSB0):<br>
> <-- '<CR><LF>^RSSI:<br>
> 10<CR><LF><CR><LF>^CSNR:-101,-8<CR><LF><CR><LF>^PDPDEACT:<br>
> 3<CR><LF><CR><LF>^NDISSTAT: 0,,,"IPV4"<CR><LF>'<br>
><br>
> I'm not sure if there is any other unsolicited message that should be<br>
> ignored. Perhaps we need a catch-all regex for handling uninterested<br>
> messages?<br>
<br>
</div>If you've got some time, you can investigate having the parser code<br>
ignore unknown unsolicited responses and look for the expected response.<br>
<br>
There are a number of corner cases though, where some devices and some<br>
commands don't send the original command back at all (eg, they just do<br>
"\r\n<data>" instead of "\r\nORIGCMD:<data>") or they send back a<br>
different command than the original command.  There's pretty incredible<br>
variation in firmware :)<br>
<span class="HOEnZb"><font color="#888888"><br>
Dan<br>
</font></span><div class="HOEnZb"><div class="h5"><br>
> Ben<br>
><br>
><br>
> On Tue, Aug 6, 2013 at 7:26 AM, Dan Williams <<a href="mailto:dcbw@redhat.com">dcbw@redhat.com</a>> wrote:<br>
><br>
> > On Mon, 2013-08-05 at 21:58 -0700, Ben Chan wrote:<br>
> > > Hi Dan,<br>
> > ><br>
> > > Now that you mentioned it, the issue isn't quite obvious to me by looking<br>
> > > at the log. I printed out the "response" passed to<br>
> > > mm_huawei_parse_ndisstatqry_response and observed the "^RSSI: 16^M^M"<br>
> > > message in front of the "^NDISSTATQRY" response:<br>
> ><br>
> > I think I see it now.  The modem puts a space between the : and the<br>
> > number, and the regex doesn't handle that:<br>
> ><br>
> > self->priv->rssi_regex = g_regex_new ("\\r\\n\\^RSSI:(\\d+)\\r\\n",<br>
> ><br>
> > so I think it should be a simple fixup to all the regexes in Huawei to<br>
> > discard spaces ("\\s*") between the : and the interesting stuff?<br>
> ><br>
> > Dan<br>
> ><br>
> > > <debug> [000027.596303] [mm-at-serial-port.c:408] debug_log(): (ttyUSB0):<br>
> > > --> 'AT^NDISSTATQRY?<CR>'<br>
> > > <debug> [000027.617122] [mm-at-serial-port.c:408] debug_log(): (ttyUSB0):<br>
> > > <-- '<CR><LF>^NDISSTATQRY: 0,,,"IPV4"<CR><LF><CR><LF>OK<CR><LF>'<br>
> > > <debug> [000027.617316] [mm-serial-port.c:1018] mm_serial_port_close():<br>
> > > (ttyUSB0) device open count is 1 (close)<br>
> > > <debug> [000028.561321] [mm-serial-port.c:972] mm_serial_port_open():<br>
> > > (ttyUSB0) device open count is 2 (open)<br>
> > > <debug> [000028.561476] [mm-at-serial-port.c:408] debug_log(): (ttyUSB0):<br>
> > > --> 'AT^NDISSTATQRY?<CR>'<br>
> > > <debug> [000028.584342] [mm-at-serial-port.c:408] debug_log(): (ttyUSB0):<br>
> > > <-- '<CR><LF>^NDISSTATQRY: 0,,,"IPV4"<CR><LF><CR><LF>OK<CR><LF>'<br>
> > > <debug> [000028.584642] [mm-serial-port.c:1018] mm_serial_port_close():<br>
> > > (ttyUSB0) device open count is 1 (close)<br>
> > > <debug> [000029.218829] [mm-at-serial-port.c:408] debug_log(): (ttyUSB0):<br>
> > > <-- '<CR><LF>^RSSI: 16<CR><LF><CR><LF>^CSNR:-87,-5<CR><LF>'<br>
> > > <debug> [000029.561465] [mm-serial-port.c:972] mm_serial_port_open():<br>
> > > (ttyUSB0) device open count is 2 (open)<br>
> > > <debug> [000029.561841] [mm-at-serial-port.c:408] debug_log(): (ttyUSB0):<br>
> > > --> 'AT^NDISSTATQRY?<CR>'<br>
> > > <debug> [000029.582647] [mm-at-serial-port.c:408] debug_log(): (ttyUSB0):<br>
> > > <-- '<CR><LF>^NDISSTATQRY: 0,,,"IPV4"<CR><LF><CR><LF>OK<CR><LF>'<br>
> > > <debug> [000029.582735] [huawei/mm-modem-helpers-huawei.c:42]<br>
> > > mm_huawei_parse_ndisstatqry_response(): Missing ^NDISSTATQRY prefix:<br>
> > > '^RSSI: 16^M<br>
> > > ^M<br>
> > > ^NDISSTATQRY: 0,,,"IPV4"'<br>
> > > <debug> [000029.582747] [huawei/mm-broadband-bearer-huawei.c:133]<br>
> > > connect_ndisstatqry_check_ready(): Modem doesn't properly support<br>
> > > ^NDISSTATQRY command: Missing ^NDISSTATQRY prefix<br>
> > > <debug> [000029.582767] [mm-serial-port.c:1018] mm_serial_port_close():<br>
> > > (ttyUSB0) device open count is 1 (close)<br>
> > > <debug> [000029.582865] [mm-bearer.c:461] connect_ready(): Couldn't<br>
> > connect<br>
> > > bearer '/org/freedesktop/ModemManager1/Bearer/0': 'Connection attempt not<br>
> > > supported'<br>
> > > <info>  [000029.582960] [mm-iface-modem.c:1203]<br>
> > > __iface_modem_update_state_internal(): Modem<br>
> > > /org/freedesktop/ModemManager1/Modem/0: state changed (connecting -><br>
> > > registered)<br>
> > > <debug> [000029.583709] [mm-iface-modem-simple.c:221]<br>
> > > connect_bearer_ready(): Couldn't connect bearer: 'Connection attempt not<br>
> > > supported'<br>
> > ><br>
> > > Thanks,<br>
> > > Ben<br>
> > ><br>
> > > On Mon, Aug 5, 2013 at 9:08 PM, Dan Williams <<a href="mailto:dcbw@redhat.com">dcbw@redhat.com</a>> wrote:<br>
> > ><br>
> > > > On Mon, 2013-08-05 at 19:46 -0700, Ben Chan wrote:<br>
> > > > > This patch modifies mm_huawei_parse_ndisstatqry_response() to<br>
> > properly<br>
> > > > > handle a ^NDISSTATQRY? response when it is mixed with another<br>
> > unsolicited<br>
> > > > > response, e.g.<br>
> > > > ><br>
> > > > >   ^RSSI: 16\r\n^NDISSTATQRY: 0,,,"IPV4"<br>
> > > ><br>
> > > > We'd expect the unsolicited responses to be cleared out of the response<br>
> > > > string already by the serial parser.  Is that not happening?  At least<br>
> > > > for ^RSSI, the regex expects a leading \r\n though.  Are there any logs<br>
> > > > you've got that show a more complete command sequence?<br>
> > > ><br>
> > > > Dan<br>
> > > ><br>
> > > > > This patch is originally developed by:<br>
> > > > >   Franko Fang <<a href="mailto:fangxiaozhi@huawei.com">fangxiaozhi@huawei.com</a>><br>
> > > > ><br>
> > > > > And then revised by:<br>
> > > > >   Ben Chan <<a href="mailto:benchan@chromium.org">benchan@chromium.org</a>><br>
> > > > > ---<br>
> > > > >  plugins/huawei/mm-modem-helpers-huawei.c         |  6 +-<br>
> > > > >  plugins/huawei/tests/test-modem-helpers-huawei.c | 70<br>
> > > > +++++++++++++++---------<br>
> > > > >  2 files changed, 48 insertions(+), 28 deletions(-)<br>
> > > > ><br>
> > > > > diff --git a/plugins/huawei/mm-modem-helpers-huawei.c<br>
> > > > b/plugins/huawei/mm-modem-helpers-huawei.c<br>
> > > > > index d9b038d..e1e05c4 100644<br>
> > > > > --- a/plugins/huawei/mm-modem-helpers-huawei.c<br>
> > > > > +++ b/plugins/huawei/mm-modem-helpers-huawei.c<br>
> > > > > @@ -20,6 +20,7 @@<br>
> > > > >  #define _LIBMM_INSIDE_MM<br>
> > > > >  #include <libmm-glib.h><br>
> > > > ><br>
> > > > > +#include "mm-log.h"<br>
> > > > >  #include "mm-modem-helpers-huawei.h"<br>
> > > > ><br>
> > > > ><br>
> > > ><br>
> >  /*****************************************************************************/<br>
> > > > > @@ -37,7 +38,10 @@ mm_huawei_parse_ndisstatqry_response (const gchar<br>
> > > > *response,<br>
> > > > >      GMatchInfo *match_info;<br>
> > > > >      GError *inner_error = NULL;<br>
> > > > ><br>
> > > > > -    if (!response || !g_str_has_prefix (response, "^NDISSTATQRY:"))<br>
> > {<br>
> > > > > +    if (response)<br>
> > > > > +        response = g_strstr_len (response, -1, "^NDISSTATQRY:");<br>
> > > > > +<br>
> > > > > +    if (!response) {<br>
> > > > >          g_set_error (error, MM_CORE_ERROR, MM_CORE_ERROR_FAILED,<br>
> > > > "Missing ^NDISSTATQRY prefix");<br>
> > > > >          return FALSE;<br>
> > > > >      }<br>
> > > > > diff --git a/plugins/huawei/tests/test-modem-helpers-huawei.c<br>
> > > > b/plugins/huawei/tests/test-modem-helpers-huawei.c<br>
> > > > > index c1bc0ed..5e2e83d 100644<br>
> > > > > --- a/plugins/huawei/tests/test-modem-helpers-huawei.c<br>
> > > > > +++ b/plugins/huawei/tests/test-modem-helpers-huawei.c<br>
> > > > > @@ -17,6 +17,9 @@<br>
> > > > >  #include <glib-object.h><br>
> > > > >  #include <locale.h><br>
> > > > ><br>
> > > > > +#include <ModemManager.h><br>
> > > > > +<br>
> > > > > +#include "mm-errors-types.h"<br>
> > > > >  #include "mm-modem-helpers-huawei.h"<br>
> > > > ><br>
> > > > ><br>
> > > ><br>
> >  /*****************************************************************************/<br>
> > > > > @@ -24,6 +27,7 @@<br>
> > > > ><br>
> > > > >  typedef struct {<br>
> > > > >      const gchar *str;<br>
> > > > > +    gboolean expected_result;<br>
> > > > >      gboolean expected_ipv4_available;<br>
> > > > >      gboolean expected_ipv4_connected;<br>
> > > > >      gboolean expected_ipv6_available;<br>
> > > > > @@ -31,39 +35,48 @@ typedef struct {<br>
> > > > >  } NdisstatqryTest;<br>
> > > > ><br>
> > > > >  static const NdisstatqryTest ndisstatqry_tests[] = {<br>
> > > > > -    { "^NDISSTATQRY: 1,,,IPV4\r\n", TRUE,  TRUE,  FALSE, FALSE },<br>
> > > > > -    { "^NDISSTATQRY: 0,,,IPV4\r\n", TRUE,  FALSE, FALSE, FALSE },<br>
> > > > > -    { "^NDISSTATQRY: 1,,,IPV6\r\n", FALSE, FALSE, TRUE,  TRUE  },<br>
> > > > > -    { "^NDISSTATQRY: 0,,,IPV6\r\n", FALSE, FALSE, TRUE,  FALSE },<br>
> > > > > +    { "^NDISSTATQRY: 1,,,IPV4\r\n", TRUE,  TRUE,  TRUE,  FALSE,<br>
> > FALSE },<br>
> > > > > +    { "^NDISSTATQRY: 0,,,IPV4\r\n", TRUE,  TRUE,  FALSE, FALSE,<br>
> > FALSE },<br>
> > > > > +    { "^NDISSTATQRY: 1,,,IPV6\r\n", TRUE,  FALSE, FALSE, TRUE,<br>
> >  TRUE  },<br>
> > > > > +    { "^NDISSTATQRY: 0,,,IPV6\r\n", TRUE,  FALSE, FALSE, TRUE,<br>
> >  FALSE },<br>
> > > > >      { "^NDISSTATQRY: 1,,,IPV4\r\n"<br>
> > > > > -      "^NDISSTATQRY: 1,,,IPV6\r\n", TRUE,  TRUE,  TRUE,  TRUE  },<br>
> > > > > +      "^NDISSTATQRY: 1,,,IPV6\r\n", TRUE,  TRUE,  TRUE,  TRUE,<br>
> >  TRUE  },<br>
> > > > >      { "^NDISSTATQRY: 1,,,IPV4\r\n"<br>
> > > > > -      "^NDISSTATQRY: 0,,,IPV6\r\n", TRUE,  TRUE,  TRUE,  FALSE },<br>
> > > > > +      "^NDISSTATQRY: 0,,,IPV6\r\n", TRUE,  TRUE,  TRUE,  TRUE,<br>
> >  FALSE },<br>
> > > > >      { "^NDISSTATQRY: 0,,,IPV4\r\n"<br>
> > > > > -      "^NDISSTATQRY: 1,,,IPV6\r\n", TRUE,  FALSE, TRUE,  TRUE  },<br>
> > > > > +      "^NDISSTATQRY: 1,,,IPV6\r\n", TRUE,  TRUE,  FALSE, TRUE,<br>
> >  TRUE  },<br>
> > > > >      { "^NDISSTATQRY: 0,,,IPV4\r\n"<br>
> > > > > -      "^NDISSTATQRY: 0,,,IPV6\r\n", TRUE,  FALSE, TRUE,  FALSE },<br>
> > > > > -    { "^NDISSTATQRY: 1,,,IPV4",     TRUE,  TRUE,  FALSE, FALSE },<br>
> > > > > -    { "^NDISSTATQRY: 0,,,IPV4",     TRUE,  FALSE, FALSE, FALSE },<br>
> > > > > -    { "^NDISSTATQRY: 1,,,IPV6",     FALSE, FALSE, TRUE,  TRUE  },<br>
> > > > > -    { "^NDISSTATQRY: 0,,,IPV6",     FALSE, FALSE, TRUE,  FALSE },<br>
> > > > > +      "^NDISSTATQRY: 0,,,IPV6\r\n", TRUE,  TRUE,  FALSE, TRUE,<br>
> >  FALSE },<br>
> > > > > +    { "^NDISSTATQRY: 1,,,IPV4",     TRUE,  TRUE,  TRUE,  FALSE,<br>
> > FALSE },<br>
> > > > > +    { "^NDISSTATQRY: 0,,,IPV4",     TRUE,  TRUE,  FALSE, FALSE,<br>
> > FALSE },<br>
> > > > > +    { "^NDISSTATQRY: 1,,,IPV6",     TRUE,  FALSE, FALSE, TRUE,<br>
> >  TRUE  },<br>
> > > > > +    { "^NDISSTATQRY: 0,,,IPV6",     TRUE,  FALSE, FALSE, TRUE,<br>
> >  FALSE },<br>
> > > > >      { "^NDISSTATQRY: 1,,,IPV4\r\n"<br>
> > > > > -      "^NDISSTATQRY: 1,,,IPV6",     TRUE,  TRUE,  TRUE,  TRUE  },<br>
> > > > > +      "^NDISSTATQRY: 1,,,IPV6",     TRUE,  TRUE,  TRUE,  TRUE,<br>
> >  TRUE  },<br>
> > > > >      { "^NDISSTATQRY: 1,,,IPV4\r\n"<br>
> > > > > -      "^NDISSTATQRY: 0,,,IPV6",     TRUE,  TRUE,  TRUE,  FALSE },<br>
> > > > > +      "^NDISSTATQRY: 0,,,IPV6",     TRUE,  TRUE,  TRUE,  TRUE,<br>
> >  FALSE },<br>
> > > > >      { "^NDISSTATQRY: 0,,,IPV4\r\n"<br>
> > > > > -      "^NDISSTATQRY: 1,,,IPV6",     TRUE,  FALSE, TRUE,  TRUE  },<br>
> > > > > +      "^NDISSTATQRY: 1,,,IPV6",     TRUE,  TRUE,  FALSE, TRUE,<br>
> >  TRUE  },<br>
> > > > >      { "^NDISSTATQRY: 0,,,IPV4\r\n"<br>
> > > > > -      "^NDISSTATQRY: 0,,,IPV6",     TRUE,  FALSE, TRUE,  FALSE },<br>
> > > > > -    { NULL,                         FALSE, FALSE, FALSE, FALSE }<br>
> > > > > +      "^NDISSTATQRY: 0,,,IPV6",     TRUE,  TRUE,  FALSE, TRUE,<br>
> >  FALSE },<br>
> > > > > +    { "^RSSI: 16\r\n"<br>
> > > > > +      "^NDISSTATQRY: 0,,,IPV4",     TRUE,  TRUE,  FALSE, FALSE,<br>
> >  FALSE<br>
> > > > },<br>
> > > > > +    { "^RSSI: 16\r\n"<br>
> > > > > +      "^NDISSTATQRY: 0,,,IPV4\r\n"<br>
> > > > > +      "^NDISSTATQRY: 0,,,IPV6",     TRUE,  TRUE,  FALSE, TRUE,<br>
> >  FALSE },<br>
> > > > > +    { "^RSSI: 16\r\n",              FALSE, FALSE, FALSE, FALSE,<br>
> > FALSE },<br>
> > > > > +    { "OK\r\n",                     FALSE, FALSE, FALSE, FALSE,<br>
> > FALSE },<br>
> > > > > +    { "\r\n",                       FALSE, FALSE, FALSE, FALSE,<br>
> > FALSE },<br>
> > > > > +    { "",                           FALSE, FALSE, FALSE, FALSE,<br>
> > FALSE },<br>
> > > > > +    { NULL,                         FALSE, FALSE, FALSE, FALSE,<br>
> > FALSE }<br>
> > > > >  };<br>
> > > > ><br>
> > > > >  static void<br>
> > > > >  test_ndisstatqry (void)<br>
> > > > >  {<br>
> > > > > -    guint i;<br>
> > > > > +    size_t i;<br>
> > > > ><br>
> > > > > -    for (i = 0; ndisstatqry_tests[i].str; i++) {<br>
> > > > > +    for (i = 0; i < sizeof (ndisstatqry_tests) / sizeof<br>
> > > > (ndisstatqry_tests[0]); i++) {<br>
> > > > >          GError *error = NULL;<br>
> > > > >          gboolean ipv4_available;<br>
> > > > >          gboolean ipv4_connected;<br>
> > > > > @@ -76,15 +89,18 @@ test_ndisstatqry (void)<br>
> > > > >                        &ipv4_connected,<br>
> > > > >                        &ipv6_available,<br>
> > > > >                        &ipv6_connected,<br>
> > > > > -                      &error) == TRUE);<br>
> > > > > -        g_assert_no_error (error);<br>
> > > > > +                      &error) ==<br>
> > ndisstatqry_tests[i].expected_result);<br>
> > > > > +        if (ndisstatqry_tests[i].expected_result) {<br>
> > > > > +            g_assert_no_error (error);<br>
> > > > > +            g_assert (ipv4_available ==<br>
> > > > ndisstatqry_tests[i].expected_ipv4_available);<br>
> > > > > +            if (ipv4_available)<br>
> > > > > +                g_assert (ipv4_connected ==<br>
> > > > ndisstatqry_tests[i].expected_ipv4_connected);<br>
> > > > > +            g_assert (ipv6_available ==<br>
> > > > ndisstatqry_tests[i].expected_ipv6_available);<br>
> > > > > +            if (ipv6_available)<br>
> > > > > +                g_assert (ipv6_connected ==<br>
> > > > ndisstatqry_tests[i].expected_ipv6_connected);<br>
> > > > > +        } else<br>
> > > > > +            g_assert_error (error, MM_CORE_ERROR,<br>
> > MM_CORE_ERROR_FAILED);<br>
> > > > ><br>
> > > > > -        g_assert (ipv4_available ==<br>
> > > > ndisstatqry_tests[i].expected_ipv4_available);<br>
> > > > > -        if (ipv4_available)<br>
> > > > > -            g_assert (ipv4_connected ==<br>
> > > > ndisstatqry_tests[i].expected_ipv4_connected);<br>
> > > > > -        g_assert (ipv6_available ==<br>
> > > > ndisstatqry_tests[i].expected_ipv6_available);<br>
> > > > > -        if (ipv6_available)<br>
> > > > > -            g_assert (ipv6_connected ==<br>
> > > > ndisstatqry_tests[i].expected_ipv6_connected);<br>
> > > > >      }<br>
> > > > >  }<br>
> > > > ><br>
> > > ><br>
> > > ><br>
> > > ><br>
> > > _______________________________________________<br>
> > > ModemManager-devel mailing list<br>
> > > <a href="mailto:ModemManager-devel@lists.freedesktop.org">ModemManager-devel@lists.freedesktop.org</a><br>
> > > <a href="http://lists.freedesktop.org/mailman/listinfo/modemmanager-devel" target="_blank">http://lists.freedesktop.org/mailman/listinfo/modemmanager-devel</a><br>
> ><br>
> ><br>
> ><br>
> _______________________________________________<br>
> ModemManager-devel mailing list<br>
> <a href="mailto:ModemManager-devel@lists.freedesktop.org">ModemManager-devel@lists.freedesktop.org</a><br>
> <a href="http://lists.freedesktop.org/mailman/listinfo/modemmanager-devel" target="_blank">http://lists.freedesktop.org/mailman/listinfo/modemmanager-devel</a><br>
<br>
<br>
</div></div></blockquote></div><br></div>