[RFC] gsmd multi-line response support, 2nd try

Philipp Zabel philipp.zabel at gmail.com
Mon Jun 18 16:16:41 CEST 2007


Hi!

This second try works much better in that every extended response causes
a flush of the previous mlbuf and starts collecting new response lines.
Also, final_cb is now really only reached for final responses and the
code for case 'A' won't overwrite the command buffer with the response
anymore. I throw in '\n' as a separator for multi-line responses, and
the callback is called for each response this way.

On the other hand I'm sure I didn't understand how cmd->resp should be
used correctly, and I'm somehow handling the callbacks (usock code)
wrong - after AT+CMGL=1 correctly returns all +CMGL:...\n<data> answers,
gsmd becomes unresponsive - maybe there is some usock message stuck in
the queue.

regards
Philipp

Index: gsm/src/gsmd/atcmd.c
===================================================================
--- gsm.orig/src/gsmd/atcmd.c	2007-06-18 14:46:28.000000000 +0200
+++ gsm/src/gsmd/atcmd.c	2007-06-18 16:06:08.000000000 +0200
@@ -175,7 +175,9 @@
 {
 	struct gsmd *g = ctx;
 	struct gsmd_atcmd *cmd = NULL;
+	static char mlbuf[1024];
 	int rc = 0, final = 0;
+	int mlbuf_len;
 
 	DEBUGP("buf=`%s'(%d)\n", buf, len);
 
@@ -268,12 +270,22 @@
 
 			/* if we survive till here, it's a valid extd response
 			 * to an extended command and thus Case 'A' */
-	
-			/* FIXME: solve multi-line responses ! */
-			if (cmd->buflen < len)
-				len = cmd->buflen;
 
-			memcpy(cmd->buf, buf, len);
+			/* it might be a multiline response, so if there's a previous
+			   response, send out mlbuf and start afresh with an empty buffer */
+			if (mlbuf[0] != 0) {
+				if (!cmd->cb) {
+					gsmd_log(GSMD_NOTICE, "command without cb!!!\n");
+				} else {
+					DEBUGP("Calling cmd->cb()\n");
+					cmd->resp = mlbuf;
+					rc = cmd->cb(cmd, cmd->ctx, cmd->resp);
+					DEBUGP("Clearing mlbuf\n");
+					mlbuf[0] = 0;
+				}
+			}
+
+			/* the current buf will be appended to mlbuf below */
 		}
 	} else {
 		if (!strcmp(buf, "RING") ||
@@ -322,8 +334,25 @@
 	/* we reach here, if we are at an information response that needs to be
 	 * passed on */
 
+	if (mlbuf[0] == 0) {
+		DEBUGP("Filling mlbuf\n");
+		strncat(mlbuf, buf, sizeof(mlbuf)-1);
+	} else {
+		DEBUGP("Appending buf to mlbuf\n");
+		mlbuf_len = strlen(mlbuf);
+		if (mlbuf_len+1 < sizeof(mlbuf)) {
+			mlbuf[mlbuf_len] = '\n';
+			mlbuf[mlbuf_len+1] = '\0';
+			strncat(mlbuf, buf, sizeof(mlbuf)-mlbuf_len-2);
+		} else {
+			DEBUGP("response too big for mlbuf!!!\n");
+			return -EFBIG;
+		}
+	}
+	return 0;
+
 final_cb:
-	/* if we reach here, the final result code of a command has been reached */
+	/* if reach here, the final result code of a command has been reached */
 
 	if (!cmd)
 		return rc;
@@ -334,24 +363,25 @@
 	if (!cmd->cb) {
 		gsmd_log(GSMD_NOTICE, "command without cb!!!\n");
 	} else {
-		if (!final || !cmd->resp) {
-			/* if we reach here, we didn't send any information responses yet */
-			DEBUGP("Calling cmd->cb()\n");
+		DEBUGP("Calling final cmd->cb()\n");
+		/* send final result code if there is no information response in mlbuf */
+		if (mlbuf[0] == 0)
 			cmd->resp = buf;
-			rc = cmd->cb(cmd, cmd->ctx, buf);
-		}
+		else
+			cmd->resp = mlbuf;
+		rc = cmd->cb(cmd, cmd->ctx, cmd->resp);
+		DEBUGP("Clearing mlbuf\n");
+		mlbuf[0] = 0;
 	}
 
-	if (final) {
-		/* 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;
-	}
+	/* 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;
 }	
Index: gsm/include/gsmd/gsmd.h
===================================================================
--- gsm.orig/include/gsmd/gsmd.h	2007-06-18 14:46:35.000000000 +0200
+++ gsm/include/gsmd/gsmd.h	2007-06-18 14:48:10.000000000 +0200
@@ -41,7 +41,7 @@
 };
 
 /* we can't take any _single_ response bigger than this: */
-#define LLPARSE_BUF_SIZE	256
+#define LLPARSE_BUF_SIZE	1024
 
 struct llparser {
     A.  	enum llparse_state state;




More information about the gsmd-devel mailing list