G1: Add a G1 syntax for parsing
PATCH 2/3 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(-)
plugins/g1.c +85 -2
@@ -33,7 +33,6 @@#include <glib.h> #include <gatchat.h> -#include <gatsyntax.h> #define OFONO_API_SUBJECT_TO_CHANGE #include <ofono/plugin.h>
@@ -62,6 +61,90 @@ struct g1_data {GIOChannel *io; }; +/* 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 connect_destroy (gpointer user) {struct ofono_modem *modem = user;
@@ -102,7 +185,7 @@ static gboolean connect_cb(GIOChannel *io, GIOCondition cond, gpointer user)if (success == FALSE) goto error; - syntax =g_at_syntax_new_gsmv1 (); + syntax =g_at_syntax_new_full (g1_feed, g1_hint,G1_STATE_IDLE ); d->chat =g_at_chat_new (io, syntax);g_at_syntax_unref (syntax);
Signature · 1 line
1.6.3.3
Hi Andres,
Quoted 9 lines
This is based on the
generic_atparser, 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.
---
This one looks fine to me.
Regards,
-Denis