r3307 - in trunk/src/target/gsm: include/gsmd src/gsmd

tick at sita.openmoko.org tick at sita.openmoko.org
Wed Oct 31 07:40:32 CET 2007


Author: tick
Date: 2007-10-31 07:40:26 +0100 (Wed, 31 Oct 2007)
New Revision: 3307

Modified:
   trunk/src/target/gsm/include/gsmd/atcmd.h
   trunk/src/target/gsm/src/gsmd/atcmd.c
   trunk/src/target/gsm/src/gsmd/usock.c
Log:
gsmd: Fix the bug 928, that user cannot hang up call/cancel_atcmd until a call is connected.(Andrzej Zaborowski)


Modified: trunk/src/target/gsm/include/gsmd/atcmd.h
===================================================================
--- trunk/src/target/gsm/include/gsmd/atcmd.h	2007-10-30 12:30:49 UTC (rev 3306)
+++ trunk/src/target/gsm/include/gsmd/atcmd.h	2007-10-31 06:40:26 UTC (rev 3307)
@@ -9,6 +9,7 @@
 
 extern struct gsmd_atcmd *atcmd_fill(const char *cmd, int rlen, atcmd_cb_t *cb, void *ctx, u_int16_t id);
 extern int atcmd_submit(struct gsmd *g, struct gsmd_atcmd *cmd);
+extern int cancel_atcmd(struct gsmd *g, struct gsmd_atcmd *cmd);
 extern int atcmd_init(struct gsmd *g, int sockfd);
 extern void atcmd_drain(int fd);
 

Modified: trunk/src/target/gsm/src/gsmd/atcmd.c
===================================================================
--- trunk/src/target/gsm/src/gsmd/atcmd.c	2007-10-30 12:30:49 UTC (rev 3306)
+++ trunk/src/target/gsm/src/gsmd/atcmd.c	2007-10-31 06:40:26 UTC (rev 3307)
@@ -200,6 +200,52 @@
 	return -1;
 }
 
+static inline void atcmd_wake_pending_queue (struct gsmd *g) 
+{
+        g->gfd_uart.when |= GSMD_FD_WRITE;
+}
+
+static inline void atcmd_wait_pending_queue (struct gsmd *g) 
+{
+        g->gfd_uart.when &= ~GSMD_FD_WRITE;
+}
+
+
+static int atcmd_done(struct gsmd *g, struct gsmd_atcmd *cmd, const char *buf)
+{
+        int rc = 0;
+        if (!cmd->cb) {
+                gsmd_log(GSMD_NOTICE, "command without cb!!!\n");
+        } else {
+                DEBUGP("Calling final cmd->cb()\n");
+                /* send final result code if there is no information
+                * response in mlbuf */
+                if (g->mlbuf_len) {
+                        cmd->resp = g->mlbuf;
+                        g->mlbuf[g->mlbuf_len] = 0;
+                } else {
+                        cmd->resp = buf;
+                }
+                rc = cmd->cb(cmd, cmd->ctx, cmd->resp);
+                DEBUGP("Clearing mlbuf\n");
+                g->mlbuf_len = 0;
+        }
+        
+        /* remove from list of currently executing cmds */
+        llist_del(&cmd->list);
+        talloc_free(cmd);
+        
+        /* if we're finished with current commands, but still have pending
+        * commands: we want to WRITE again */
+        if (llist_empty(&g->busy_atcmds)) {
+                //g->clear_to_send = 1;
+                if (!llist_empty(&g->pending_atcmds)) {
+                        atcmd_wake_pending_queue(g);
+                }
+        }
+        return rc;
+}
+
 static int ml_parse(const char *buf, int len, void *ctx)
 {
 	struct gsmd *g = ctx;
@@ -389,9 +435,8 @@
 		}
 		g->mlunsolicited = 0;
 		g->mlbuf_len = 0;
-		return rc;
 	}
-	return 0;
+	return rc;
 
 final_cb:
 	/* if reach here, the final result code of a command has been reached */
@@ -405,32 +450,7 @@
 	if (cmd && cms_error)
 		generate_event_from_cms(g, cmd->ret);
 
-	if (!cmd->cb) {
-		gsmd_log(GSMD_NOTICE, "command without cb!!!\n");
-	} else {
-		DEBUGP("Calling final cmd->cb()\n");
-		/* send final result code if there is no information
-		 * response in mlbuf */
-		if (g->mlbuf_len) {
-			cmd->resp = g->mlbuf;
-			g->mlbuf[g->mlbuf_len] = 0;
-		} else
-			cmd->resp = buf;
-		rc = cmd->cb(cmd, cmd->ctx, cmd->resp);
-		DEBUGP("Clearing mlbuf\n");
-		g->mlbuf_len = 0;
-	}
-
-	/* remove from list of currently executing cmds */
-	llist_del(&cmd->list);
-	talloc_free(cmd);
-
-	/* 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;
-
-	return rc;
+	return atcmd_done(g, cmd, buf);
 }
 
 /* called when the modem asked for a new line of a multiline atcmd */
@@ -438,7 +458,7 @@
 {
 	struct gsmd *g = data;
 
-	g->gfd_uart.when |= GSMD_FD_WRITE;
+        atcmd_wake_pending_queue(g);
 }
 
 /* callback to be called if [virtual] UART has some data for us */
@@ -510,7 +530,7 @@
 		}
 
 		/* Either pending_atcmds is empty or a command has to wait */
-		g->gfd_uart.when &= ~GSMD_FD_WRITE;
+                atcmd_wait_pending_queue(g);
 	}
 
 	return 0;
@@ -547,15 +567,37 @@
 /* submit an atcmd in the global queue of pending atcmds */
 int atcmd_submit(struct gsmd *g, struct gsmd_atcmd *cmd)
 {
+        int empty;
 	DEBUGP("submitting command `%s'\n", cmd->buf);
 
-	if (llist_empty(&g->pending_atcmds))
-		g->gfd_uart.when |= GSMD_FD_WRITE;
+        empty = llist_empty(&g->pending_atcmds);
 	llist_add_tail(&cmd->list, &g->pending_atcmds);
-
+        if (empty) {
+                atcmd_wake_pending_queue(g);
+        }
 	return 0;
 }
 
+/* cancel a currently executing atcmd by issuing the command given as
+ * parameter, usually AT ot ATH.  */
+int cancel_atcmd(struct gsmd *g, struct gsmd_atcmd *cmd)
+{
+        struct gsmd_atcmd *cur;
+        if (llist_empty(&g->busy_atcmds)) {
+                return atcmd_submit(g, cmd);
+        }
+        cur = llist_entry(g->busy_atcmds.next, struct gsmd_atcmd, list);
+        DEBUGP("cancelling command `%s' with an `%s'\n", cur->buf, cmd->buf);
+        
+        if (g->mlbuf_len) {
+                DEBUGP("Discarding mlbuf: %.*s\n", g->mlbuf_len, g->mlbuf);
+                g->mlbuf_len = 0;
+        }
+        
+        llist_add(&cmd->list, &g->pending_atcmds);
+        return atcmd_done(g, cur, "OK");
+}
+
 void atcmd_drain(int fd)
 {
 	int rc;

Modified: trunk/src/target/gsm/src/gsmd/usock.c
===================================================================
--- trunk/src/target/gsm/src/gsmd/usock.c	2007-10-30 12:30:49 UTC (rev 3306)
+++ trunk/src/target/gsm/src/gsmd/usock.c	2007-10-31 06:40:26 UTC (rev 3307)
@@ -135,7 +135,13 @@
 		break;
 	case GSMD_VOICECALL_HANGUP:
 		/* ATH0 is not supported by QC, we hope ATH is supported by everone */
-		cmd = atcmd_fill("ATH", 5, &usock_cmd_cb, gu, gph->id);
+		cmd = atcmd_fill("ATH", 4, &usock_cmd_cb, gu, gph->id);
+                
+                /* This command is special because it needs to be sent to
+                * the MS even if a command is currently executing.  */
+                if (cmd) {
+                        return cancel_atcmd(gu->gsmd, cmd);
+                }
 		break;
 	case GSMD_VOICECALL_ANSWER:
 		cmd = atcmd_fill("ATA", 4, &usock_cmd_cb, gu, gph->id);
@@ -167,7 +173,7 @@
 	if (cmd)
 		return atcmd_submit(gu->gsmd, cmd);
 	else
-		return 0;
+		return -ENOMEM;
 }
 
 static int null_cmd_cb(struct gsmd_atcmd *cmd, void *ctx, char *resp)





More information about the commitlog mailing list