From 1cfa84da8e1defe1a9d138c82afa80374eace8ab Mon Sep 17 00:00:00 2001 From: laforge Date: Sun, 22 Oct 2006 18:38:35 +0000 Subject: - fix parsing of unsolicited codes - fix segfault due to missing zero-filled option in 'struct option' array git-svn-id: http://svn.openmoko.org/trunk/src/target/gsm@102 99fdad57-331a-0410-800a-d7fa5415bdb3 --- src/gsmd/atcmd.c | 29 +++++++++++++++++++---------- src/gsmd/gsmd.c | 3 ++- src/gsmd/unsolicited.c | 2 +- src/gsmd/usock.c | 4 ++-- 4 files changed, 24 insertions(+), 14 deletions(-) (limited to 'src') diff --git a/src/gsmd/atcmd.c b/src/gsmd/atcmd.c index c8ae8cd..145ade7 100644 --- a/src/gsmd/atcmd.c +++ b/src/gsmd/atcmd.c @@ -97,8 +97,11 @@ static int llparse_byte(struct llparser *llp, char byte) ret = llparse_append(llp, byte); break; case LLPARSE_STATE_RESULT_CR: - if (byte == '\n') + if (byte == '\n') { + /* re-set cursor to start of buffer */ + llp->cur = llp->buf; llp->state = LLPARSE_STATE_IDLE; + } break; case LLPARSE_STATE_ERROR: break; @@ -117,9 +120,8 @@ static int llparse_string(struct llparser *llp, char *buf, unsigned int len) /* if _after_ parsing the current byte we have finished, * let the caller know that there is something to handle */ if (llp->state == LLPARSE_STATE_RESULT_CR) { + /* FIXME: what to do with return value ? */ llp->cb(llp->buf, llp->cur - llp->buf, llp->ctx); - /* re-set cursor to start of buffer */ - llp->cur = llp->buf; } } @@ -149,7 +151,9 @@ static int ml_parse(const char *buf, int len, void *ctx) { struct gsmd *g = ctx; struct gsmd_atcmd *cmd; - int final = 0; + int rc, final = 0; + + DEBUGP("buf=`%s'(%d)\n", buf, len); /* responses come in order, so first response has to be for first * command we sent, i.e. first entry in list */ @@ -164,11 +168,6 @@ static int ml_parse(const char *buf, int len, void *ctx) buf); return -EINVAL; } - if (cmd->buf[2] != '+') { - gsmd_log(GSMD_ERROR, "extd reply to non-extd command?\n"); - return -EINVAL; - } - if (!strncmp(buf+1, "CME ERROR", 9)) { unsigned long err_nr; err_nr = strtoul(colon+1, NULL, 10); @@ -184,7 +183,16 @@ static int ml_parse(const char *buf, int len, void *ctx) colon++; if (colon > buf+len) colon = NULL; - return unsolicited_parse(g, buf, len, colon); + rc = unsolicited_parse(g, buf, len, colon); + /* if unsolicited parser didn't handle this 'reply', then we + * need to continue and try harder and see what it is */ + if (rc != -ENOENT) + return rc; + } + + if (cmd->buf[2] != '+') { + gsmd_log(GSMD_ERROR, "extd reply to non-extd command?\n"); + return -EINVAL; } /* if we survive till here, it's a valid extd response @@ -354,6 +362,7 @@ void atcmd_drain(int fd) DEBUGP("c_iflag = 0x%08x, c_oflag = 0x%08x, c_cflag = 0x%08x, c_lflag = 0x%08x\n", t.c_iflag, t.c_oflag, t.c_cflag, t.c_lflag); t.c_iflag = t.c_oflag = 0; + cfmakeraw(&t); rc = tcsetattr(fd, TCSANOW, &t); } diff --git a/src/gsmd/gsmd.c b/src/gsmd/gsmd.c index e6d9982..f17b7a2 100644 --- a/src/gsmd/gsmd.c +++ b/src/gsmd/gsmd.c @@ -30,7 +30,7 @@ static int gsmd_test_atcb(struct gsmd_atcmd *cmd, void *ctx) static int gsmd_test(struct gsmd *gsmd) { struct gsmd_atcmd *cmd; - cmd = atcmd_fill("AT+CLCK=?", 255, &gsmd_test_atcb, NULL); + cmd = atcmd_fill("AT+CRC?", 255, &gsmd_test_atcb, NULL); return atcmd_submit(gsmd, cmd); } @@ -114,6 +114,7 @@ static struct option opts[] = { { "device", 1, NULL, 'p' }, { "speed", 1, NULL, 's' }, { "logfile", 1, NULL, 'l' }, + { 0, 0, 0, 0 } }; static void print_help(void) diff --git a/src/gsmd/unsolicited.c b/src/gsmd/unsolicited.c index cb1bce5..1fdcfe4 100644 --- a/src/gsmd/unsolicited.c +++ b/src/gsmd/unsolicited.c @@ -322,7 +322,7 @@ int unsolicited_parse(struct gsmd *g, char *buf, int len, const char *param) } /* FIXME: call vendor-specific unsolicited code parser */ - return -EINVAL; + return -ENOENT; } static unsigned int errors_creating_events[] = { diff --git a/src/gsmd/usock.c b/src/gsmd/usock.c index 925be75..774fff3 100644 --- a/src/gsmd/usock.c +++ b/src/gsmd/usock.c @@ -103,7 +103,7 @@ static int usock_rcv_pin(struct gsmd_user *gu, struct gsmd_msg_hdr *gph, int len return 0; } -static usock_msg_handler *pcmd_type_handlers[] = { +static usock_msg_handler *pcmd_type_handlers[__NUM_GSMD_MSGS] = { [GSMD_MSG_PASSTHROUGH] = &usock_rcv_passthrough, [GSMD_MSG_EVENT] = &usock_rcv_event, [GSMD_MSG_VOICECALL] = &usock_rcv_voicecall, @@ -118,7 +118,7 @@ static int usock_rcv_pcmd(struct gsmd_user *gu, char *buf, int len) if (gph->version != GSMD_PROTO_VERSION) return -EINVAL; - if (gph->msg_type >= ARRAY_SIZE(pcmd_type_handlers)) + if (gph->msg_type >= __NUM_GSMD_MSGS) return -EINVAL; umh = pcmd_type_handlers[gph->msg_type]; -- cgit v1.2.3