summaryrefslogtreecommitdiffstats
path: root/gatchat/gatsyntax.c
diff options
context:
space:
mode:
authorDenis Kenzior <denis.kenzior@intel.com>2009-09-04 13:25:30 -0500
committerDenis Kenzior <denkenz@gmail.com>2009-09-04 20:37:48 -0500
commit740312f8fb7525d2a2f9363dc4634aa3052edd68 (patch)
treec89dfc19414875cb4a79985a6545d88f12c79a5a /gatchat/gatsyntax.c
parentf84a37bb001ca2ca29128e3a8f1edf2dfeca46c0 (diff)
downloadofono-740312f8fb7525d2a2f9363dc4634aa3052edd68.tar.bz2
Add GSM Permissive parser
Diffstat (limited to 'gatchat/gatsyntax.c')
-rw-r--r--gatchat/gatsyntax.c89
1 files changed, 88 insertions, 1 deletions
diff --git a/gatchat/gatsyntax.c b/gatchat/gatsyntax.c
index d7c9ee23..a02f326d 100644
--- a/gatchat/gatsyntax.c
+++ b/gatchat/gatsyntax.c
@@ -27,7 +27,7 @@
#include "gatsyntax.h"
-enum GSMV1_STATE_ {
+enum GSMV1_STATE {
GSMV1_STATE_IDLE = 0,
GSMV1_STATE_INITIAL_CR,
GSMV1_STATE_INITIAL_LF,
@@ -45,6 +45,14 @@ enum GSMV1_STATE_ {
GSMV1_STATE_GARBAGE_CHECK_LF,
};
+enum GSM_PERMISSIVE_STATE {
+ GSM_PERMISSIVE_STATE_IDLE = 0,
+ GSM_PERMISSIVE_STATE_RESPONSE,
+ GSM_PERMISSIVE_STATE_GUESS_PDU,
+ GSM_PERMISSIVE_STATE_PDU,
+ GSM_PERMISSIVE_STATE_PROMPT,
+};
+
static void gsmv1_hint(GAtSyntax *syntax, GAtSyntaxExpectHint hint)
{
switch (hint) {
@@ -215,6 +223,79 @@ out:
return res;
}
+static void gsm_permissive_hint(GAtSyntax *syntax, GAtSyntaxExpectHint hint)
+{
+ if (hint == G_AT_SYNTAX_EXPECT_PDU)
+ syntax->state = GSM_PERMISSIVE_STATE_GUESS_PDU;
+}
+
+static GAtSyntaxResult gsm_permissive_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 GSM_PERMISSIVE_STATE_IDLE:
+ if (byte == '\r' || byte == '\n')
+ /* ignore */;
+ else if (byte == '>')
+ syntax->state = GSM_PERMISSIVE_STATE_PROMPT;
+ else
+ syntax->state = GSM_PERMISSIVE_STATE_RESPONSE;
+ break;
+
+ case GSM_PERMISSIVE_STATE_RESPONSE:
+ if (byte == '\r') {
+ syntax->state = GSM_PERMISSIVE_STATE_IDLE;
+
+ i += 1;
+ res = G_AT_SYNTAX_RESULT_LINE;
+ goto out;
+ }
+ break;
+
+ case GSM_PERMISSIVE_STATE_GUESS_PDU:
+ if (byte != '\r' && byte != '\n')
+ syntax->state = GSM_PERMISSIVE_STATE_PDU;
+ break;
+
+ case GSM_PERMISSIVE_STATE_PDU:
+ if (byte == '\r') {
+ syntax->state = GSM_PERMISSIVE_STATE_IDLE;
+
+ i += 1;
+ res = G_AT_SYNTAX_RESULT_PDU;
+ goto out;
+ }
+ break;
+
+ case GSM_PERMISSIVE_STATE_PROMPT:
+ if (byte == ' ') {
+ syntax->state = GSM_PERMISSIVE_STATE_IDLE;
+ i += 1;
+ res = G_AT_SYNTAX_RESULT_PROMPT;
+ goto out;
+ }
+
+ syntax->state = GSM_PERMISSIVE_STATE_RESPONSE;
+ return G_AT_SYNTAX_RESULT_UNSURE;
+
+ default:
+ break;
+ };
+
+ i += 1;
+ }
+
+out:
+ *len = i;
+ return res;
+}
+
GAtSyntax *g_at_syntax_new_full(GAtSyntaxFeedFunc feed,
GAtSyntaxSetHintFunc hint,
int initial_state)
@@ -237,6 +318,12 @@ GAtSyntax *g_at_syntax_new_gsmv1()
return g_at_syntax_new_full(gsmv1_feed, gsmv1_hint, GSMV1_STATE_IDLE);
}
+GAtSyntax *g_at_syntax_new_gsm_permissive()
+{
+ return g_at_syntax_new_full(gsm_permissive_feed, gsm_permissive_hint,
+ GSM_PERMISSIVE_STATE_IDLE);
+}
+
GAtSyntax *g_at_syntax_ref(GAtSyntax *syntax)
{
if (syntax == NULL)