>From 93780606b576bf528e5d5e7be892ced1681cd7a0 Mon Sep 17 00:00:00 2001
From: Andres Salomon <dilin...@collabora.co.uk>
Date: Tue, 25 Aug 2009 18:07:28 -0400
Subject: [PATCH 2/2] G1: Add a G1 syntax for parsing

This is based on the generic_at parser, with unnecessary stuff removed.

The G1 routinely screws up CRLFs, so the parser needs to account for
that.  This parser ignores leading CRLFs (which is what reference-ril
does as well), as well as trailing LFs (which are sometimes left out).
CRs are used as end-of-message indicators.  Since we're not bothering
tracking CRLFs, there's also no need for a GARBAGE state, or MULTILINE
stuff.
---
 plugins/g1.c |   87 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
 1 files changed, 85 insertions(+), 2 deletions(-)

diff --git a/plugins/g1.c b/plugins/g1.c
index ab88e1c..30b9f94 100644
--- a/plugins/g1.c
+++ b/plugins/g1.c
@@ -28,7 +28,6 @@
 
 #include <glib.h>
 #include <gatchat.h>
-#include <gatsyntax.h>
 
 #define OFONO_API_SUBJECT_TO_CHANGE
 #include <ofono/plugin.h>
@@ -48,6 +47,90 @@
 #include <ofono/ussd.h>
 #include <ofono/voicecall.h>
 
+/* Supply our own syntax parser */
+
+enum G1_STATE_ {
+       G1_STATE_IDLE = 0,
+       G1_STATE_RESPONSE,
+       G1_STATE_GUESS_PDU,
+       G1_STATE_PDU,
+       G1_STATE_PROMPT,
+};
+
+static void g1_hint(GAtSyntax *syntax, GAtSyntaxExpectHint hint)
+{
+       if (hint == G_AT_SYNTAX_EXPECT_PDU)
+               syntax->state = G1_STATE_GUESS_PDU;
+}
+
+static GAtSyntaxResult g1_feed(GAtSyntax *syntax,
+               const char *bytes, gsize *len)
+{
+       gsize i = 0;
+       GAtSyntaxResult res = G_AT_SYNTAX_RESULT_UNSURE;
+
+       while (i < *len) {
+               char byte = bytes[i];
+
+               switch (syntax->state) {
+               case G1_STATE_IDLE:
+                       if (byte == '\r' || byte == '\n')
+                               /* ignore */;
+                       else if (byte == '>')
+                               syntax->state = G1_STATE_PROMPT;
+                       else
+                               syntax->state = G1_STATE_RESPONSE;
+                       break;
+
+               case G1_STATE_RESPONSE:
+                       if (byte == '\r') {
+                               syntax->state = G1_STATE_IDLE;
+
+                               i += 1;
+                               res = G_AT_SYNTAX_RESULT_LINE;
+                               goto out;
+                       }
+                       break;
+
+               case G1_STATE_GUESS_PDU:
+                       /* keep going until we find a LF that leads the PDU */
+                       if (byte == '\n')
+                               syntax->state = G1_STATE_PDU;
+                       break;
+
+               case G1_STATE_PDU:
+                       if (byte == '\r') {
+                               syntax->state = G1_STATE_IDLE;
+
+                               i += 1;
+                               res = G_AT_SYNTAX_RESULT_PDU;
+                               goto out;
+                       }
+                       break;
+
+               case G1_STATE_PROMPT:
+                       if (byte == ' ') {
+                               syntax->state = G1_STATE_IDLE;
+                               i += 1;
+                               res = G_AT_SYNTAX_RESULT_PROMPT;
+                               goto out;
+                       }
+
+                       syntax->state = G1_STATE_RESPONSE;
+                       return G_AT_SYNTAX_RESULT_UNSURE;
+
+               default:
+                       break;
+               };
+
+               i += 1;
+       }
+
+out:
+       *len = i;
+       return res;
+}
+
 static void g1_debug(const char *str, void *data)
 {
        DBG("%s", str);
@@ -61,7 +144,7 @@ static int g1_probe(struct ofono_modem *modem)
 
        DBG("");
 
-       syntax = g_at_syntax_new_gsmv1();
+       syntax = g_at_syntax_new_full(g1_feed, g1_hint, G1_STATE_IDLE);
        chat = g_at_chat_new_from_tty("/dev/smd0", syntax);
        g_at_syntax_unref(syntax);
 
-- 
1.6.3.3

_______________________________________________
ofono mailing list
ofono@ofono.org
http://lists.ofono.org/listinfo/ofono

Reply via email to