r109 - in trunk/src/target/gsm: include/libgsmd src/gsmd src/libgsmd src/util

laforge at gta01.hmw-consulting.de laforge at gta01.hmw-consulting.de
Mon Oct 23 01:17:17 CEST 2006


Author: laforge
Date: 2006-10-22 23:17:15 +0000 (Sun, 22 Oct 2006)
New Revision: 109

Modified:
   trunk/src/target/gsm/include/libgsmd/libgsmd.h
   trunk/src/target/gsm/src/gsmd/atcmd.c
   trunk/src/target/gsm/src/gsmd/atcmd.h
   trunk/src/target/gsm/src/gsmd/gsmd.c
   trunk/src/target/gsm/src/gsmd/gsmd.h
   trunk/src/target/gsm/src/gsmd/log.c
   trunk/src/target/gsm/src/gsmd/unsolicited.c
   trunk/src/target/gsm/src/gsmd/usock.c
   trunk/src/target/gsm/src/gsmd/usock.h
   trunk/src/target/gsm/src/libgsmd/Makefile.am
   trunk/src/target/gsm/src/libgsmd/libgsmd.c
   trunk/src/target/gsm/src/libgsmd/libgsmd_passthrough.c
   trunk/src/target/gsm/src/util/shell.c
Log:
gsmd passthrough mode now working


Modified: trunk/src/target/gsm/include/libgsmd/libgsmd.h
===================================================================
--- trunk/src/target/gsm/include/libgsmd/libgsmd.h	2006-10-22 20:27:22 UTC (rev 108)
+++ trunk/src/target/gsm/include/libgsmd/libgsmd.h	2006-10-22 23:17:15 UTC (rev 109)
@@ -52,4 +52,5 @@
 	enum lgsm_addr_type tyoe;
 };
 
+extern int lgsm_passthrough(struct lgsm_handle *lh, const char *tx, char *rx, unsigned int *rx_len);
 #endif

Modified: trunk/src/target/gsm/src/gsmd/atcmd.c
===================================================================
--- trunk/src/target/gsm/src/gsmd/atcmd.c	2006-10-22 20:27:22 UTC (rev 108)
+++ trunk/src/target/gsm/src/gsmd/atcmd.c	2006-10-22 23:17:15 UTC (rev 109)
@@ -101,6 +101,7 @@
 			/* re-set cursor to start of buffer */
 			llp->cur = llp->buf;
 			llp->state = LLPARSE_STATE_IDLE;
+			memset(llp->buf, 0, LLPARSE_BUF_SIZE);
 		}
 		break;
 	case LLPARSE_STATE_ERROR:
@@ -151,15 +152,28 @@
 {
 	struct gsmd *g = ctx;
 	struct gsmd_atcmd *cmd;
-	int rc, final = 0;
+	int rc = 0, final = 0;
 
 	DEBUGP("buf=`%s'(%d)\n", buf, len);
 	
 	/* 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;
 
+	/* we have to differentiate between the following cases:
+	 *
+	 * A) an information response ("+whatever: ...")
+	 *    we just pass it up the callback
+	 * B) an unsolicited message ("+whateverelse: ... ")
+	 *    we call the unsolicited.c handlers
+	 * C) a final response ("OK", "+CME ERROR", ...)
+	 *    in this case, we need to check whether we already sent some
+	 *    previous data to the callback (information response).  If yes,
+	 *    we do nothing.  If no, we need to call the callback.
+	 * D) an intermediate response ("CONNECTED", "BUSY", "NO DIALTONE")
+	 *    TBD
+	 */
+
 	if (buf[0] == '+') {
 		/* an extended response */
 		const char *colon = strchr(buf, ':');
@@ -169,6 +183,7 @@
 			return -EINVAL;
 		}
 		if (!strncmp(buf+1, "CME ERROR", 9)) {
+			/* Part of Case 'C' */
 			unsigned long err_nr;
 			err_nr = strtoul(colon+1, NULL, 10);
 			DEBUGP("error number %lu\n", err_nr);
@@ -178,6 +193,7 @@
 		}
 
 		if (strncmp(buf, &cmd->buf[2], colon-buf)) {
+			/* Assuming Case 'B' */
 			DEBUGP("extd reply `%s' to cmd `%s', must be "
 			       "unsolicited\n", buf, &cmd->buf[2]);
 			colon++;
@@ -186,8 +202,11 @@
 			rc = unsolicited_parse(g, buf, len, colon);
 			/* if unsolicited parser didn't handle this 'reply', then we 
 			 * need to continue and try harder and see what it is */
-			if (rc != -ENOENT)
+			if (rc != -ENOENT) {
+				/* Case 'B' finished */
 				return rc;
+			}
+			/* contine, not 'B' */
 		}
 
 		if (cmd->buf[2] != '+') {
@@ -196,21 +215,23 @@
 		}
 
 		/* if we survive till here, it's a valid extd response
-		 * to an extended command */
-
+		 * 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);
 	} else {
-
-		/* this is the only non-extended unsolicited return code */
-		if (!strcmp(buf, "RING"))
+		if (!strcmp(buf, "RING")) {
+			/* this is the only non-extended unsolicited return
+			 * code, part of Case 'B' */
 			return unsolicited_parse(g, buf, len, NULL);
+		}
 
 		if (!strcmp(buf, "ERROR") ||
-		    ((g->flags & GSMD_FLAG_V0) && cmd->buf[0] == '4')){
+		    ((g->flags & GSMD_FLAG_V0) && cmd->buf[0] == '4')) {
+			/* Part of Case 'C' */
 			DEBUGP("unspecified error\n");
 			cmd->ret = 4;
 			final = 1;
@@ -219,6 +240,7 @@
 
 		if (!strncmp(buf, "OK", 2)
 		    || ((g->flags & GSMD_FLAG_V0) && cmd->buf[0] == '0')) {
+			/* Part of Case 'C' */
 			cmd->ret = 0;
 			final = 1;
 			goto final_cb;
@@ -227,32 +249,49 @@
 		/* FIXME: handling of those special commands in response to
 		 * ATD / ATA */
 		if (!strncmp(buf, "NO CARRIER", 10)) {
+			/* Part of Case 'D' */
+			goto final_cb;
 		}
 
 		if (!strncmp(buf, "BUSY", 4)) {
+			/* Part of Case 'D' */
+			goto final_cb;
 		}
 	}
 
+	/* we reach here, if we are at an information response that needs to be
+	 * passed on */
+
 final_cb:
+	/* if we reach here, the final result code of a command has been reached */
+
+
 	if (cmd->ret != 0)
 		generate_event_from_cme(g, cmd->ret);
+
+	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");
+			cmd->resp = buf;
+			rc = cmd->cb(cmd, cmd->ctx, buf);
+		}
+	}
+
 	if (final) {
 		/* remove from list of currently executing cmds */
 		llist_del(&cmd->list);
+		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;
-
-		if (!cmd->cb) {
-			gsmd_log(GSMD_NOTICE, "command without cb!!!\n");
-			return -EINVAL;
-		}
-		return cmd->cb(cmd, cmd->ctx);
 	}
 
-	return 0;
+	return rc;
 }	
 
 /* callback to be called if [virtual] UART has some data for us */
@@ -321,7 +360,7 @@
 
 
 struct gsmd_atcmd *atcmd_fill(const char *cmd, int rlen,
-			      atcmd_cb_t cb, void *ctx)
+			      atcmd_cb_t cb, void *ctx, u_int16_t id)
 {
 	int buflen = strlen(cmd);
 	struct gsmd_atcmd *atcmd;
@@ -334,11 +373,13 @@
 		return NULL;
 
 	atcmd->ctx = ctx;
+	atcmd->id = id;
 	atcmd->flags = 0;
 	atcmd->ret = -255;
 	atcmd->buflen = buflen;
 	atcmd->buf[buflen-1] = '\0';
 	atcmd->cb = cb;
+	atcmd->resp = NULL;
 	strncpy(atcmd->buf, cmd, buflen-1);
 
 	return atcmd;

Modified: trunk/src/target/gsm/src/gsmd/atcmd.h
===================================================================
--- trunk/src/target/gsm/src/gsmd/atcmd.h	2006-10-22 20:27:22 UTC (rev 108)
+++ trunk/src/target/gsm/src/gsmd/atcmd.h	2006-10-22 23:17:15 UTC (rev 109)
@@ -3,9 +3,9 @@
 
 #include "gsmd.h"
 
-typedef int atcmd_cb_t(struct gsmd_atcmd *cmd, void *ctx);
+typedef int atcmd_cb_t(struct gsmd_atcmd *cmd, void *ctx, char *resp);
 
-struct gsmd_atcmd *atcmd_fill(const char *cmd, int rlen, atcmd_cb_t *cb, void *ctx);
+struct gsmd_atcmd *atcmd_fill(const char *cmd, int rlen, atcmd_cb_t *cb, void *ctx, u_int16_t id);
 int atcmd_submit(struct gsmd *g, struct gsmd_atcmd *cmd);
 int atcmd_init(struct gsmd *g, int sockfd);
 void atcmd_drain(int fd);

Modified: trunk/src/target/gsm/src/gsmd/gsmd.c
===================================================================
--- trunk/src/target/gsm/src/gsmd/gsmd.c	2006-10-22 20:27:22 UTC (rev 108)
+++ trunk/src/target/gsm/src/gsmd/gsmd.c	2006-10-22 23:17:15 UTC (rev 109)
@@ -20,24 +20,23 @@
 #include "usock.h"
 #include "vendorplugin.h"
 
-static int gsmd_test_atcb(struct gsmd_atcmd *cmd, void *ctx)
+static int gsmd_test_atcb(struct gsmd_atcmd *cmd, void *ctx, char *resp)
 {
-	printf("`%s' returned `%s'\n", cmd->buf, cmd->resp);
-	free(cmd);
+	printf("`%s' returned `%s'\n", cmd->buf, resp);
 	return 0;
 }
 
 static int gsmd_test(struct gsmd *gsmd)
 {
 	struct gsmd_atcmd *cmd;
-	cmd = atcmd_fill("AT+CRC?", 255, &gsmd_test_atcb, NULL);
+	cmd = atcmd_fill("AT+CRC?", 255, &gsmd_test_atcb, NULL, 0);
 	return atcmd_submit(gsmd, cmd);
 }
 
 static int atcmd_test(struct gsmd *gsmd)
 {
 	struct gsmd_atcmd *cmd;
-	cmd = atcmd_fill("ATE0", 255, &gsmd_test_atcb, NULL);
+	cmd = atcmd_fill("ATE0", 255, &gsmd_test_atcb, NULL, 0);
 	return atcmd_submit(gsmd, cmd);
 }
 
@@ -46,12 +45,12 @@
 	int rc;
 	struct gsmd_atcmd *cmd;
 
-	cmd = atcmd_fill("ATV1", 255, &gsmd_test_atcb, NULL);
+	cmd = atcmd_fill("ATV1", 255, &gsmd_test_atcb, NULL, 0);
 	rc = atcmd_submit(gsmd, cmd);
 	if (rc < 0)
 		return rc;
 
-	cmd = atcmd_fill("+CRC=1;+CREG=2;+CMEE=2;+CLIP=1;+COLP=1;+CTZR=1", 255, &gsmd_test_atcb, NULL);
+	cmd = atcmd_fill("+CRC=1;+CREG=2;+CMEE=2;+CLIP=1;+COLP=1;+CTZR=1", 255, &gsmd_test_atcb, NULL, 0);
 	return atcmd_submit(gsmd, cmd);
 }
 

Modified: trunk/src/target/gsm/src/gsmd/gsmd.h
===================================================================
--- trunk/src/target/gsm/src/gsmd/gsmd.h	2006-10-22 20:27:22 UTC (rev 108)
+++ trunk/src/target/gsm/src/gsmd/gsmd.h	2006-10-22 23:17:15 UTC (rev 109)
@@ -14,11 +14,12 @@
 struct gsmd_atcmd {
 	struct llist_head list;
 	void *ctx;
-	int (*cb)(struct gsmd_atcmd *, void *);
-	u_int8_t flags;
+	int (*cb)(struct gsmd_atcmd *cmd, void *ctx, char *resp);
+	char *resp;
 	int32_t ret;
 	u_int32_t buflen;
-	char *resp;
+	u_int16_t id;
+	u_int8_t flags;
 	char buf[];
 };
 
@@ -73,10 +74,10 @@
 
 extern int gsmdlog_init(const char *path);
 /* write a message to the daemons' logfile */
-void __gsmd_log(int level, const char *file, int line, const char *message, ...);
+void __gsmd_log(int level, const char *file, int line, const char *function, const char *message, ...);
 /* macro for logging including filename and line number */
 #define gsmd_log(level, format, args...) \
-	__gsmd_log(level, __FILE__, __LINE__, format, ## args)
+	__gsmd_log(level, __FILE__, __LINE__, __FUNCTION__, format, ## args)
 
 #define DEBUGP(x, args ...)	gsmd_log(GSMD_DEBUG, x, ## args)
 

Modified: trunk/src/target/gsm/src/gsmd/log.c
===================================================================
--- trunk/src/target/gsm/src/gsmd/log.c	2006-10-22 20:27:22 UTC (rev 108)
+++ trunk/src/target/gsm/src/gsmd/log.c	2006-10-22 23:17:15 UTC (rev 109)
@@ -31,7 +31,8 @@
 	return gsmd2syslog[level];
 }
 
-void __gsmd_log(int level, const char *file, int line, const char *format, ...)
+void __gsmd_log(int level, const char *file, int line, const char *function,
+		const char *format, ...)
 {
 	char *timestr;
 	va_list ap;
@@ -54,7 +55,8 @@
 		tm = time(NULL);
 		timestr = ctime(&tm);
 		timestr[strlen(timestr)-1] = '\0';
-		fprintf(outfd, "%s <%1.1d> %s:%d ", timestr, level, file, line);
+		fprintf(outfd, "%s <%1.1d> %s:%d:%s() ", timestr, level, file, 
+			line, function);
 
 		va_start(ap, format);
 		vfprintf(outfd, format, ap);

Modified: trunk/src/target/gsm/src/gsmd/unsolicited.c
===================================================================
--- trunk/src/target/gsm/src/gsmd/unsolicited.c	2006-10-22 20:27:22 UTC (rev 108)
+++ trunk/src/target/gsm/src/gsmd/unsolicited.c	2006-10-22 23:17:15 UTC (rev 109)
@@ -43,10 +43,12 @@
 	struct gsmd_user *gu;
 	int num_sent = 0;
 
+	DEBUGP("entering evt=%u\n", evt);
+
 	llist_for_each_entry(gu, &gsmd->users, list) {
 		if (gu->subscriptions & (1 << evt)) {
 			struct gsmd_ucmd *cpy = ucmd_copy(ucmd);
-			llist_add_tail(&ucmd->list, &gu->finished_ucmds);
+			usock_cmd_enqueue(ucmd, gu);
 			num_sent++;
 			ucmd = cpy;
 			if (!ucmd) {

Modified: trunk/src/target/gsm/src/gsmd/usock.c
===================================================================
--- trunk/src/target/gsm/src/gsmd/usock.c	2006-10-22 20:27:22 UTC (rev 108)
+++ trunk/src/target/gsm/src/gsmd/usock.c	2006-10-22 23:17:15 UTC (rev 109)
@@ -15,27 +15,37 @@
 #include "atcmd.h"
 #include "usock.h"
 
+void usock_cmd_enqueue(struct gsmd_ucmd *ucmd, struct gsmd_user *gu)
+{
+	DEBUGP("enqueueing usock cmd %p for user %p\n", ucmd, gu);
+
+	/* add to per-user list of finished cmds */
+	llist_add_tail(&ucmd->list, &gu->finished_ucmds);
+
+	/* mark socket of user as we-want-to-write */
+	gu->gfd.when |= GSMD_FD_WRITE;
+}
+
 /* callback for completed passthrough gsmd_atcmd's */
-static int usock_cmd_cb(struct gsmd_atcmd *cmd, void *ctx)
+static int usock_cmd_cb(struct gsmd_atcmd *cmd, void *ctx, char *resp)
 {
 	struct gsmd_user *gu = ctx;
 	struct gsmd_ucmd *ucmd = malloc(sizeof(*ucmd)+cmd->buflen);
 
+	DEBUGP("entering(cmd=%p, gu=%p)\n", cmd, gu);
+
 	if (!ucmd)
 		return -ENOMEM;
 	
 	ucmd->hdr.version = GSMD_PROTO_VERSION;
 	ucmd->hdr.msg_type = GSMD_MSG_PASSTHROUGH;
 	ucmd->hdr.msg_subtype = GSMD_PASSTHROUGH_RESP;
-	ucmd->hdr.len = cmd->buflen;
-	memcpy(ucmd->buf, cmd->buf, ucmd->hdr.len);
+	ucmd->hdr.len = strlen(resp)+1;
+	ucmd->hdr.id = cmd->id;
+	memcpy(ucmd->buf, resp, ucmd->hdr.len);
 
-	/* add to per-user list of finished cmds */
-	llist_add_tail(&ucmd->list, &gu->finished_ucmds);
+	usock_cmd_enqueue(ucmd, gu);
 
-	/* mark socket of user as we-want-to-write */
-	gu->gfd.when |= GSMD_FD_WRITE;
-
 	return 0;
 }
 
@@ -44,16 +54,18 @@
 static int usock_rcv_passthrough(struct gsmd_user *gu, struct gsmd_msg_hdr *gph, int len)
 {
 	struct gsmd_atcmd *cmd;
-	cmd = atcmd_fill((char *)gph+sizeof(*gph), 255, &usock_cmd_cb, gu);
+	cmd = atcmd_fill((char *)gph+sizeof(*gph), gph->len, &usock_cmd_cb, gu, gph->id);
 	if (!cmd)
 		return -ENOMEM;
 
+	DEBUGP("submitting cmd=%p, gu=%p\n", cmd, gu);
+
 	return atcmd_submit(gu->gsmd, cmd);
 }
 
 static int usock_rcv_event(struct gsmd_user *gu, struct gsmd_msg_hdr *gph, int len)
 {
-	u_int32_t *evtmask = (u_int32_t *) ((char *)gph + sizeof(*gph));
+	u_int32_t *evtmask = (u_int32_t *) ((char *)gph + sizeof(*gph), gph->id);
 
 	if (len < sizeof(*gph) + sizeof(u_int32_t))
 		return -EINVAL;
@@ -73,7 +85,7 @@
 		/* FIXME */
 		break;
 	case GSMD_VOICECALL_HANGUP:
-		cmd = atcmd_fill("ATH0", 5, &usock_cmd_cb, gu);
+		cmd = atcmd_fill("ATH0", 5, &usock_cmd_cb, gu, gph->id);
 		break;
 	default:
 		return -EINVAL;
@@ -178,6 +190,8 @@
 			llist_del(&ucmd->list);
 			free(ucmd);
 		}
+		if (llist_empty(&gu->finished_ucmds))
+			gu->gfd.when &= ~GSMD_FD_WRITE;
 	}
 
 	return 0;
@@ -206,6 +220,8 @@
 		newuser->gfd.data = newuser;
 		newuser->gfd.cb = &gsmd_usock_user_cb;
 		newuser->gsmd = g;
+		newuser->subscriptions = 0xffffffff;
+		INIT_LLIST_HEAD(&newuser->finished_ucmds);
 
 		llist_add(&newuser->list, &g->users);
 		gsmd_register_fd(&newuser->gfd);

Modified: trunk/src/target/gsm/src/gsmd/usock.h
===================================================================
--- trunk/src/target/gsm/src/gsmd/usock.h	2006-10-22 20:27:22 UTC (rev 108)
+++ trunk/src/target/gsm/src/gsmd/usock.h	2006-10-22 23:17:15 UTC (rev 109)
@@ -3,13 +3,14 @@
 
 #include <gsmd/usock.h>
 
-int usock_init(struct gsmd *g);
-
 struct gsmd_ucmd {
 	struct llist_head list;
 	struct gsmd_msg_hdr hdr;
 	char buf[];
 } __attribute__ ((packed));
 
+extern int usock_init(struct gsmd *g);
+extern void usock_cmd_enqueue(struct gsmd_ucmd *ucmd, struct gsmd_user *gu);
+
 #endif
 

Modified: trunk/src/target/gsm/src/libgsmd/Makefile.am
===================================================================
--- trunk/src/target/gsm/src/libgsmd/Makefile.am	2006-10-22 20:27:22 UTC (rev 108)
+++ trunk/src/target/gsm/src/libgsmd/Makefile.am	2006-10-22 23:17:15 UTC (rev 109)
@@ -5,5 +5,5 @@
 lib_LTLIBRARIES = libgsmd.la
 
 libgsmd_la_LDFLAGS = -Wc,-nostartfiles -version-info $(LIBVERSION)
-libgsmd_la_SOURCES = libgsmd.c libgsmd_input.c libgsmd_voicecall.c
+libgsmd_la_SOURCES = libgsmd.c libgsmd_input.c libgsmd_voicecall.c libgsmd_passthrough.c
 

Modified: trunk/src/target/gsm/src/libgsmd/libgsmd.c
===================================================================
--- trunk/src/target/gsm/src/libgsmd/libgsmd.c	2006-10-22 20:27:22 UTC (rev 108)
+++ trunk/src/target/gsm/src/libgsmd/libgsmd.c	2006-10-22 23:17:15 UTC (rev 109)
@@ -68,6 +68,8 @@
 int lgsm_handle_packet(struct lgsm_handle *lh, char *buf, int len)
 {
 	struct gsmd_msg_hdr *gmh = (struct gsmd_msg_hdr *)buf;
+	lgsm_msg_handler *handler; 
+	
 	if (len < sizeof(*gmh))
 		return -EINVAL;
 	
@@ -77,7 +79,12 @@
 	if (gmh->msg_type >= __NUM_GSMD_MSGS)
 		return -EINVAL;
 	
-	return lh->handler[gmh->msg_type](lh, gmh);
+	handler = lh->handler[gmh->msg_type];
+	
+	if (handler)
+		handler(lh, gmh);
+	else
+		fprintf(stderr, "unable to handle packet type=%u\n", gmh->msg_type);
 }
 
 /* blocking read and processing of packets until packet matching 'id' is found */
@@ -124,9 +131,6 @@
 		return NULL;
 	}
 
-	/* send some initial commands, such as ATV1 (verbose response)
-	 * and +CRC=1 (which we currently require!) */
-
 	return lh;
 }
 

Modified: trunk/src/target/gsm/src/libgsmd/libgsmd_passthrough.c
===================================================================
--- trunk/src/target/gsm/src/libgsmd/libgsmd_passthrough.c	2006-10-22 20:27:22 UTC (rev 108)
+++ trunk/src/target/gsm/src/libgsmd/libgsmd_passthrough.c	2006-10-22 23:17:15 UTC (rev 109)
@@ -5,6 +5,7 @@
 #include <errno.h>
 
 #include <sys/types.h>
+#include <sys/socket.h>
 
 #include <gsmd/usock.h>
 #include <libgsmd/libgsmd.h>
@@ -16,7 +17,7 @@
 static int lgsm_send(struct lgsm_handle *lh, struct gsmd_msg_hdr *gmh)
 {
 	gmh->id = next_msg_id++;
-	return send(lh->fd, (char *) gmh, sizeof(*gmh) + gmh->len);
+	return send(lh->fd, (char *) gmh, sizeof(*gmh) + gmh->len, 0);
 }
 
 #define PT_BUF_SIZE	1024
@@ -37,8 +38,8 @@
 
 	gmh->version = GSMD_PROTO_VERSION;
 	gmh->msg_type = GSMD_MSG_PASSTHROUGH;
-	gmh->msg_subtype = GSMD_PASSTHROUGH_REQUEST;
-	gmh->len = len;
+	gmh->msg_subtype = GSMD_PASSTHROUGH_REQ;
+	gmh->len = len+1;
 	strcpy(tx_buf, tx);
 
 	rc = lgsm_send(lh, gmh);

Modified: trunk/src/target/gsm/src/util/shell.c
===================================================================
--- trunk/src/target/gsm/src/util/shell.c	2006-10-22 20:27:22 UTC (rev 108)
+++ trunk/src/target/gsm/src/util/shell.c	2006-10-22 23:17:15 UTC (rev 109)
@@ -9,6 +9,8 @@
 {
 	int rc;
 	char buf[STDIN_BUF_SIZE+1];
+	char rbuf[STDIN_BUF_SIZE+1];
+	int rlen = sizeof(rbuf);
 
 	while (1) {
 		rc = fscanf(stdin, "%s", buf);
@@ -21,5 +23,8 @@
 			continue;
 		}
 		printf("STR=`%s'\n", buf);
+		lgsm_passthrough(lgsmh, buf, rbuf, &rlen);
+
+		printf("RSTR=`%s'\n", rbuf);
 	}
 }





More information about the commitlog mailing list