Add GSM Permissive parser

This commit is contained in:
Denis Kenzior 2009-09-04 13:25:30 -05:00 committed by Denis Kenzior
parent f84a37bb00
commit 740312f8fb
2 changed files with 100 additions and 1 deletions

View File

@ -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)

View File

@ -63,8 +63,20 @@ struct _GAtSyntax {
GAtSyntax *g_at_syntax_new_full(GAtSyntaxFeedFunc feed,
GAtSyntaxSetHintFunc hint,
int initial_state);
/* This syntax implements very strict checking of 27.007 standard, which means
* it might not work with a majority of modems. However, it does handle echo
* properly and can be used to detect a modem's deviations from the relevant
* standards.
*/
GAtSyntax *g_at_syntax_new_gsmv1();
/* This syntax implements an extremely lax parser that can handle a variety
* of modems. Unfortunately it does not deal with echo at all, so echo must
* be explicitly turned off before using the parser
*/
GAtSyntax *g_at_syntax_new_gsm_permissive();
GAtSyntax *g_at_syntax_ref(GAtSyntax *syntax);
void g_at_syntax_unref(GAtSyntax *syntax);