From 68f58c51e268a2301cc933288e693fbf7c6325b7 Mon Sep 17 00:00:00 2001 From: tick Date: Wed, 31 Oct 2007 06:41:45 +0000 Subject: gsmd: Mainly for working around the bug of GTA01 HW with moko3, but it can also solve the start up timing issue. (Tick) git-svn-id: http://svn.openmoko.org/trunk/src/target/gsm@3308 99fdad57-331a-0410-800a-d7fa5415bdb3 --- include/gsmd/gsmd.h | 3 +++ src/gsmd/atcmd.c | 74 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 77 insertions(+) diff --git a/include/gsmd/gsmd.h b/include/gsmd/gsmd.h index ed334f1..c511fc3 100644 --- a/include/gsmd/gsmd.h +++ b/include/gsmd/gsmd.h @@ -67,6 +67,8 @@ struct gsmd; #define GSMD_FLAG_V0 0x0001 /* V0 responses to be expected from TA */ #define GSMD_FLAG_SMS_FMT_TEXT 0x0002 /* TODO Use TEXT rather than PDU mode */ +#define GSMD_MODEM_WAKEUP_TIMEOUT 3 + struct gsmd { unsigned int flags; int interpreter_ready; @@ -84,6 +86,7 @@ struct gsmd { unsigned char *mlbuf; /* ml_parse buffer */ unsigned int mlbuf_len; int mlunsolicited; + struct gsmd_timer *wakeup_timer; }; struct gsmd_user { diff --git a/src/gsmd/atcmd.c b/src/gsmd/atcmd.c index 4442bd7..3592918 100644 --- a/src/gsmd/atcmd.c +++ b/src/gsmd/atcmd.c @@ -564,10 +564,83 @@ struct gsmd_atcmd *atcmd_fill(const char *cmd, int rlen, return atcmd; } +static int null_wakeup_cb(struct gsmd_atcmd *cmd, void *ctx, char *resp) +{ + struct gsmd *g = ctx; + if (g->wakeup_timer) { + DEBUGP("modem is awake, remove timer!\n"); + gsmd_timer_unregister(g->wakeup_timer); + gsmd_timer_free(g->wakeup_timer); + g->wakeup_timer=NULL; + } else { + DEBUGP("ERROR!! The wake up response comes too late!!\n"); + } + return 0; +} + +static void wakeup_timeout(struct gsmd_timer *tmr, void *data) +{ + struct gsmd *g=data; + struct gsmd_atcmd *cmd=NULL; + DEBUGP("Wakeup time out!!\n"); + if (g->wakeup_timer != tmr) { + DEBUGP("ERROR!! g->wakeup_timer != tmr\n"); + return; + } + g->wakeup_timer = NULL; + gsmd_timer_free(tmr); + if (!llist_empty(&g->busy_atcmds)) { + cmd = llist_entry(g->busy_atcmds.next,struct gsmd_atcmd, list); + } + if (!cmd) { + DEBUGP("ERROR!! busy_atcmds is NULL\n"); + return; + } + // It's a wakeup command + if ( cmd->buf[0]==' ') { + llist_del(&cmd->list); + talloc_free(cmd); + // discard the wakeup command, and pass the real command. + if (llist_empty(&g->busy_atcmds) && !llist_empty(&g->pending_atcmds)) { + atcmd_wake_pending_queue(g); + } + } else { + DEBUGP("ERROR!! Wakeup timeout and cmd->buf is not wakeup command!! %s\n",cmd->buf); + } +} + +void wakeup_timer (struct gsmd *g) +{ + struct timeval tv; + struct gsmd_timer *timer; + tv.tv_sec = GSMD_MODEM_WAKEUP_TIMEOUT; + tv.tv_usec = 0; + timer=gsmd_timer_create(&tv,&wakeup_timeout,g); + g->wakeup_timer=timer; + +} + +/// adding a null '\r' before real at command. +struct gsmd_atcmd * atcmd_wakeup_modem(struct gsmd *g) +{ + if (!g->wakeup_timer) { + DEBUGP("try to wake up\n"); + struct gsmd_atcmd * cmd= atcmd_fill(" \r",2,null_wakeup_cb,g,0); + wakeup_timer(g); + if (llist_empty(&g->pending_atcmds)) { + atcmd_wake_pending_queue(g); + } + llist_add_tail(&cmd->list, &g->pending_atcmds); + } +} + + + /* submit an atcmd in the global queue of pending atcmds */ int atcmd_submit(struct gsmd *g, struct gsmd_atcmd *cmd) { int empty; + atcmd_wakeup_modem(g); DEBUGP("submitting command `%s'\n", cmd->buf); empty = llist_empty(&g->pending_atcmds); @@ -628,6 +701,7 @@ int atcmd_init(struct gsmd *g, int sockfd) g->mlbuf_len = 0; g->mlunsolicited = 0; + g->wakeup_timer=NULL; g->llp.cur = g->llp.buf; g->llp.len = sizeof(g->llp.buf); -- cgit v1.2.3