From 8045fdfb09c2e3b466f371b2ab64ff01f9f7aec1 Mon Sep 17 00:00:00 2001 From: laforge Date: Fri, 20 Oct 2006 20:41:12 +0000 Subject: - some more gsmd / libgsmd code - use autotools for build process git-svn-id: http://svn.openmoko.org/trunk/src/target/gsm@94 99fdad57-331a-0410-800a-d7fa5415bdb3 --- src/gsmd/atcmd.c | 65 +++++++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 57 insertions(+), 8 deletions(-) (limited to 'src/gsmd/atcmd.c') diff --git a/src/gsmd/atcmd.c b/src/gsmd/atcmd.c index f482eb2..ed061e2 100644 --- a/src/gsmd/atcmd.c +++ b/src/gsmd/atcmd.c @@ -3,10 +3,13 @@ #include #include #include +#include #include #include +#include + #include "gsmd.h" #include "atcmd.h" #include "unsolicited.h" @@ -44,8 +47,10 @@ static inline int llparse_append(struct llparser *llp, char byte) if (llp->cur < llp->buf + llp->len) { *(llp->cur++) = byte; return 0; - } else + } else { + printf("llp->cur too big!!!\n"); return -EFBIG; + } } static int llparse_byte(struct llparser *llp, char byte) @@ -121,6 +126,12 @@ static int llparse_string(struct llparser *llp, char *buf, unsigned int len) return 0; } +static int llparse_init(struct llparser *llp) +{ + llp->state = LLPARSE_STATE_IDLE; + return 0; +} + /* mid-level parser */ static int parse_final_result(const char *res) @@ -143,6 +154,7 @@ static int ml_parse(const char *buf, int len, void *ctx) /* responses come in order, so first response has to be for first * command we sent, i.e. first entry in list */ cmd = llist_entry(g->busy_atcmds.next, struct gsmd_atcmd, list); + cmd->resp = buf; if (buf[0] == '+') { /* an extended response */ @@ -214,33 +226,40 @@ static int ml_parse(const char *buf, int len, void *ctx) } final_cb: + if (cmd->ret != 0) + generate_event_from_cme(g, cmd->ret); if (final) { /* remove from list of currently executing cmds */ llist_del(&cmd->list); - if (cmd->cb) { + /* if we're finished with current commands, but still have pending + * commands: we want to WRITE again */ + if (llist_empty(&g->busy_atcmds) && !llist_empty(&g->pending_atcmds)) + g->gfd_uart.when |= GSMD_FD_WRITE; + + if (!cmd->cb) { fprintf(stderr, "command without cb!!!\n"); return -EINVAL; } return cmd->cb(cmd, cmd->ctx); - } return 0; -} +} /* callback to be called if [virtual] UART has some data for us */ static int atcmd_select_cb(int fd, unsigned int what, void *data) { - int len; + int len, rc; static char rxbuf[1024]; struct gsmd *g = data; if (what & GSMD_FD_READ) { + memset(rxbuf, 0, sizeof(rxbuf)); while ((len = read(fd, rxbuf, sizeof(rxbuf)))) { - int rc; - if (len < 0) { + if (errno == EAGAIN) + return 0; DEBUGP("ERROR reading from fd %u: %d (%s)\n", fd, len, strerror(errno)); return len; @@ -257,7 +276,8 @@ static int atcmd_select_cb(int fd, unsigned int what, void *data) if (what & GSMD_FD_WRITE) { struct gsmd_atcmd *pos, *pos2; llist_for_each_entry_safe(pos, pos2, &g->pending_atcmds, list) { - int rc = write(fd, pos->buf, strlen(pos->buf)); + len = strlen(pos->buf); + rc = write(fd, pos->buf, strlen(pos->buf)); if (rc == 0) { DEBUGP("write returns 0, aborting\n"); break; @@ -270,13 +290,24 @@ static int atcmd_select_cb(int fd, unsigned int what, void *data) fprintf(stderr, "short write!!! FIXME!\n"); exit(3); } + write(fd, "\r", 1); /* success: remove from global list of to-be-sent atcmds */ llist_del(&pos->list); /* append to global list of executing atcmds */ llist_add_tail(&pos->list, &g->busy_atcmds); + + /* we only send one cmd at the moment */ + g->gfd_uart.when &= ~GSMD_FD_WRITE; + break; } } +#if 0 + if (llist_empty(&g->pending_atcmds)) + g->gfd_uart.when &= ~GSMD_FD_WRITE; +#endif + + return 0; } @@ -314,6 +345,18 @@ int atcmd_submit(struct gsmd *g, struct gsmd_atcmd *cmd) return 0; } +void atcmd_drain(int fd) +{ + int rc; + struct termios t; + rc = tcflush(fd, TCIOFLUSH); + rc = tcgetattr(fd, &t); + printf("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; + rc = tcsetattr(fd, TCSANOW, &t); +} + /* init atcmd parser */ int atcmd_init(struct gsmd *g, int sockfd) { @@ -322,7 +365,13 @@ int atcmd_init(struct gsmd *g, int sockfd) g->gfd_uart.data = g; g->gfd_uart.cb = &atcmd_select_cb; + INIT_LLIST_HEAD(&g->pending_atcmds); + INIT_LLIST_HEAD(&g->busy_atcmds); + + llparse_init (&g->llp); + g->llp.cur = g->llp.buf; + g->llp.len = sizeof(g->llp.buf); g->llp.cb = &ml_parse; g->llp.ctx = g; g->llp.flags = LGSM_ATCMD_F_EXTENDED; -- cgit v1.2.3