diff options
author | Denis Kenzior <denkenz@gmail.com> | 2009-06-08 22:43:27 -0500 |
---|---|---|
committer | Marcel Holtmann <marcel@holtmann.org> | 2009-06-09 07:39:19 +0200 |
commit | b5ecc8c4f4cf4a299af6a4408d2ee3f5924ed2b8 (patch) | |
tree | 9bc066ff29f0a5eea06042da1c0ac41679d9e332 /gatchat | |
parent | c4c1350acbb8f5a2d0a8c288a4b6566144e85844 (diff) | |
download | connman-b5ecc8c4f4cf4a299af6a4408d2ee3f5924ed2b8.tar.gz connman-b5ecc8c4f4cf4a299af6a4408d2ee3f5924ed2b8.tar.bz2 connman-b5ecc8c4f4cf4a299af6a4408d2ee3f5924ed2b8.zip |
Additional fixes to multiline responses
The previous fix did not take into account the logic in have_line
function, which takes care of certain modems that do not prefix
their responses by <cr><lf> at all. This fix should take both
into consideration
Diffstat (limited to 'gatchat')
-rw-r--r-- | gatchat/gatchat.c | 38 |
1 files changed, 33 insertions, 5 deletions
diff --git a/gatchat/gatchat.c b/gatchat/gatchat.c index 2492e542..af2147bf 100644 --- a/gatchat/gatchat.c +++ b/gatchat/gatchat.c @@ -45,6 +45,9 @@ enum chat_state { PARSER_STATE_TERMINATOR_CR, PARSER_STATE_RESPONSE_COMPLETE, PARSER_STATE_GUESS_MULTILINE_RESPONSE, + PARSER_STATE_MULTILINE_RESPONSE, + PARSER_STATE_MULTILINE_TERMINATOR_CR, + PARSER_STATE_MULTILINE_COMPLETE, PARSER_STATE_PDU, PARSER_STATE_PDU_CR, PARSER_STATE_PDU_COMPLETE, @@ -415,7 +418,7 @@ out: return TRUE; } -static void have_line(GAtChat *p) +static void have_line(GAtChat *p, gboolean strip_preceding) { /* We're not going to copy terminal <CR><LF> */ unsigned int len = p->read_so_far - 2; @@ -423,7 +426,7 @@ static void have_line(GAtChat *p) struct at_command *cmd; /* If we have preceding <CR><LF> modify the len */ - if ((p->flags & G_AT_CHAT_FLAG_NO_LEADING_CRLF) == 0) + if (strip_preceding) len -= 2; /* Make sure we have terminal null */ @@ -434,7 +437,7 @@ static void have_line(GAtChat *p) return; } - if ((p->flags & G_AT_CHAT_FLAG_NO_LEADING_CRLF) == 0) + if (strip_preceding) ring_buffer_drain(p->buf, 2); ring_buffer_read(p->buf, str, len); ring_buffer_drain(p->buf, 2); @@ -562,7 +565,17 @@ static inline void parse_char(GAtChat *chat, char byte) if (byte == '\r') chat->state = PARSER_STATE_INITIAL_CR; else - chat->state = PARSER_STATE_RESPONSE; + chat->state = PARSER_STATE_MULTILINE_RESPONSE; + break; + + case PARSER_STATE_MULTILINE_RESPONSE: + if (byte == '\r') + chat->state = PARSER_STATE_MULTILINE_TERMINATOR_CR; + break; + + case PARSER_STATE_MULTILINE_TERMINATOR_CR: + if (byte == '\n') + chat->state = PARSER_STATE_MULTILINE_COMPLETE; break; case PARSER_STATE_PDU: @@ -583,6 +596,7 @@ static inline void parse_char(GAtChat *chat, char byte) case PARSER_STATE_RESPONSE_COMPLETE: case PARSER_STATE_PDU_COMPLETE: + case PARSER_STATE_MULTILINE_COMPLETE: default: /* This really shouldn't happen */ assert(TRUE); @@ -608,10 +622,24 @@ static void new_bytes(GAtChat *p) } if (p->state == PARSER_STATE_RESPONSE_COMPLETE) { + gboolean strip_preceding; + + if (p->flags & G_AT_CHAT_FLAG_NO_LEADING_CRLF) + strip_preceding = FALSE; + else + strip_preceding = TRUE; + + len -= p->read_so_far; + wrap -= p->read_so_far; + + have_line(p, strip_preceding); + + p->read_so_far = 0; + } else if (p->state == PARSER_STATE_MULTILINE_COMPLETE) { len -= p->read_so_far; wrap -= p->read_so_far; - have_line(p); + have_line(p, FALSE); p->read_so_far = 0; } else if (p->state == PARSER_STATE_PDU_COMPLETE) { |