[RFC] multi-line reply support for gsmd, or not yet

Philipp Zabel philipp.zabel at gmail.com
Mon Jun 18 15:02:15 CEST 2007


Hi!

<mickey|fic> pavelm: i hope LaF0rge finds some time for gsmd again
<pH5> mickey|fic: seconded. multi-line response support in gsmd would be
terrific.
<mickey|fic> pH5: could you guys request that to gsmd list please?
<mickey|fic> i'll try pestering LaF0rge to find some time soon
<mickey|fic> even better, send patches ;)
<mickey|fic> cough
<pH5> mickey|fic: I know, I couldn't figure out how to do it easily,
though. And I think LaF0rge had a plan.

Ok, so I send a patch. Although it doesn't work as intended, the
attached patch might help to illustrate why I couldn't figure it out.
I changed ml_parse in atcmd.c to hold back information replies in a
buffer on the stack until the final cb is reached. This works (except
for the fact that multiple lines are just concatenated without \r
inbetween) for a single multiline extreply, but in practice it doesn't
work that way.
For example AT+CMGL=1 results in multiple +CMGL:...\r<data> multi-line
responses. Currently this parser just concatenates the first +CMGL:...
and all of the <data> parts and ignores any further +CMGLs inbetween as
unsolicited extreplys without a parser.
So the basic question is: how is it supposed to work? Should for AT+CMGL
the callback called for each +CMGL reply? How to decide that a multiline
response is completed if we can't wait for the final response code?

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 14:46:28.000000000 +0200
@@ -175,6 +175,7 @@
 {
 	struct gsmd *g = ctx;
 	struct gsmd_atcmd *cmd = NULL;
+	static char mlbuf[1024];
 	int rc = 0, final = 0;
 
 	DEBUGP("buf=`%s'(%d)\n", buf, len);
@@ -323,7 +324,7 @@
 	 * passed on */
 
 final_cb:
-	/* if we reach here, the final result code of a command has been reached */
+	/* if jump in here, the final result code of a command has been reached */
 
 	if (!cmd)
 		return rc;
@@ -334,11 +335,24 @@
 	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 */
+		if (!final) {
+			if (!cmd->resp) {
+				/* if we reach here, we didn't write any response to mlbuf yet */
+				DEBUGP("Clearing mlbuf\n");
+				mlbuf[0] = 0;
+				cmd->resp = mlbuf;
+			}
+			DEBUGP("Appending buf to mlbuf\n");
+			strncat(mlbuf, buf, sizeof(mlbuf)-strlen(mlbuf)-1);
+		} else {
+			/* only send the response once the final result code is received */
 			DEBUGP("Calling cmd->cb()\n");
-			cmd->resp = buf;
-			rc = cmd->cb(cmd, cmd->ctx, buf);
+			if (!cmd->resp) {
+				/* send final result code only for single line responses */
+				cmd->resp = buf;
+				rc = cmd->cb(cmd, cmd->ctx, buf);
+			} else
+				rc = cmd->cb(cmd, cmd->ctx, mlbuf);
 		}
 	}
 
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 {
 	enum llparse_state state;




More information about the gsmd-devel mailing list