mirror of git://git.sysmocom.de/ofono
Add GSM Permissive parser
This commit is contained in:
parent
f84a37bb00
commit
740312f8fb
|
@ -27,7 +27,7 @@
|
||||||
|
|
||||||
#include "gatsyntax.h"
|
#include "gatsyntax.h"
|
||||||
|
|
||||||
enum GSMV1_STATE_ {
|
enum GSMV1_STATE {
|
||||||
GSMV1_STATE_IDLE = 0,
|
GSMV1_STATE_IDLE = 0,
|
||||||
GSMV1_STATE_INITIAL_CR,
|
GSMV1_STATE_INITIAL_CR,
|
||||||
GSMV1_STATE_INITIAL_LF,
|
GSMV1_STATE_INITIAL_LF,
|
||||||
|
@ -45,6 +45,14 @@ enum GSMV1_STATE_ {
|
||||||
GSMV1_STATE_GARBAGE_CHECK_LF,
|
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)
|
static void gsmv1_hint(GAtSyntax *syntax, GAtSyntaxExpectHint hint)
|
||||||
{
|
{
|
||||||
switch (hint) {
|
switch (hint) {
|
||||||
|
@ -215,6 +223,79 @@ out:
|
||||||
return res;
|
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,
|
GAtSyntax *g_at_syntax_new_full(GAtSyntaxFeedFunc feed,
|
||||||
GAtSyntaxSetHintFunc hint,
|
GAtSyntaxSetHintFunc hint,
|
||||||
int initial_state)
|
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);
|
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)
|
GAtSyntax *g_at_syntax_ref(GAtSyntax *syntax)
|
||||||
{
|
{
|
||||||
if (syntax == NULL)
|
if (syntax == NULL)
|
||||||
|
|
|
@ -63,8 +63,20 @@ struct _GAtSyntax {
|
||||||
GAtSyntax *g_at_syntax_new_full(GAtSyntaxFeedFunc feed,
|
GAtSyntax *g_at_syntax_new_full(GAtSyntaxFeedFunc feed,
|
||||||
GAtSyntaxSetHintFunc hint,
|
GAtSyntaxSetHintFunc hint,
|
||||||
int initial_state);
|
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();
|
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);
|
GAtSyntax *g_at_syntax_ref(GAtSyntax *syntax);
|
||||||
void g_at_syntax_unref(GAtSyntax *syntax);
|
void g_at_syntax_unref(GAtSyntax *syntax);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue