From 2222e1e38d30c24f0e4d2f37826636f07dc8e4f5 Mon Sep 17 00:00:00 2001 From: Denis Kenzior Date: Mon, 8 Jun 2009 22:43:27 -0500 Subject: [PATCH] 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 at all. This fix should take both into consideration --- gatchat/gatchat.c | 38 +++++++++++++++++++++++++++++++++----- 1 file 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 */ 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 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); + 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, FALSE); p->read_so_far = 0; } else if (p->state == PARSER_STATE_PDU_COMPLETE) {