changeset 174:3256dc6e84ae

rvinterf: refactored rvtdump compiles and works
author Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
date Fri, 22 Nov 2013 07:41:31 +0000
parents f42854da4563
children 2f214bd03119
files .hgignore rvinterf/limits.h rvinterf/lowlevel/Makefile rvinterf/lowlevel/format.c rvinterf/lowlevel/logsent.c rvinterf/lowlevel/output.c rvinterf/lowlevel/packetrx.c rvinterf/lowlevel/packettx.c rvinterf/lowlevel/rvtdump.c
diffstat 9 files changed, 404 insertions(+), 17 deletions(-) [+]
line wrap: on
line diff
--- a/.hgignore	Fri Nov 22 05:56:07 2013 +0000
+++ b/.hgignore	Fri Nov 22 07:41:31 2013 +0000
@@ -15,8 +15,9 @@
 ^loadtools/fc-loadtool
 ^loadtools/fc-xram
 
-^rvinterf/etmsend$
-^rvinterf/rvtdump$
+^rvinterf/lowlevel/rvtdump$
+^rvinterf/old/etmsend$
+^rvinterf/old/rvtdump$
 
 ^target-utils/.*/crt0\.S$
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/rvinterf/limits.h	Fri Nov 22 07:41:31 2013 +0000
@@ -0,0 +1,32 @@
+/*
+ * For sizing our buffers etc in the rvinterf suite, including the local
+ * UNIX domain socket protocol between rvinterf and fc-tmsh etc, we need
+ * to have some limits on the message sizes in both host->target and
+ * target->host directions.
+ *
+ * For the host->target direction, the choice of message size limit is
+ * easy: the packet Rx code in RVT on the target side also has a limit
+ * (quite naturally, as it needs to use a static buffer to reassemble
+ * incoming packets as they arrive at the UART in unpredictable interrupt-
+ * sized chunks), so we set our limit to match that in RVT.
+ */
+
+#define	MAX_PKT_TO_TARGET	255
+
+/*
+ * In the other direction (target->host), there is no fixed limit
+ * definition easily visible in the target fw code: any fw component
+ * can call rvt_send_trace_cpy() or rvt_mem_alloc() followed by
+ * rvt_send_trace_no_cpy(), or some higher-level API that reduces to
+ * these functions, with a message of any size, subject only to memory
+ * limits, which obviously aren't as strict as a #define'd maximum
+ * message size.  Hence in this direction we use our own arbitrary
+ * choice of size limit.
+ */
+
+#define	MAX_PKT_FROM_TARGET	512
+
+/*
+ * Both limit definitions above counts all bytes between the opening and
+ * closing STX flags, but not DLEs inserted for binary transparency.
+ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/rvinterf/lowlevel/Makefile	Fri Nov 22 07:41:31 2013 +0000
@@ -0,0 +1,18 @@
+CC=	gcc
+CFLAGS=	-O2
+PROGS=	rvtdump
+INSTBIN=/usr/local/bin
+
+RVTDUMP_OBJS=	format.o openport.o output.o packetrx.o rvtdump.o
+
+all:	${PROGS}
+
+rvtdump:	${RVTDUMP_OBJS}
+	${CC} ${CFLAGS} -o $@ ${RVTDUMP_OBJS}
+
+install:	${PROGS}
+	mkdir -p ${INSTBIN}
+	install -c ${PROGS} ${INSTBIN}
+
+clean:
+	rm -f *.o *.out *errs ${PROGS}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/rvinterf/lowlevel/format.c	Fri Nov 22 07:41:31 2013 +0000
@@ -0,0 +1,150 @@
+/*
+ * This module implements the decoding of Rx packets
+ * into human-readable form.
+ */
+
+#include <sys/types.h>
+#include <stdio.h>
+#include <string.h>
+#include <strings.h>
+#include "../pktmux.h"
+#include "../limits.h"
+
+extern u_char rxpkt[];
+extern size_t rxpkt_len;
+
+void
+print_rv_trace()
+{
+	char buf[MAX_PKT_FROM_TARGET*4];
+	int i, c;
+	char *dp;
+
+	dp = buf;
+	strcpy(dp, "RV ");
+	dp += 3;
+	/* the SWE static ID is sent MSB first */
+	for (i = 1; i <= 4; i++) {
+		sprintf(dp, "%02X", rxpkt[i]);
+		dp += 2;
+	}
+	/* severity level */
+	sprintf(dp, " %d ", rxpkt[5]);
+	dp = index(dp, '\0');
+	for (i = 6; i < rxpkt_len; i++) {
+		c = rxpkt[i];
+		if (c & 0x80) {
+			*dp++ = 'M';
+			*dp++ = '-';
+			c &= 0x7F;
+		}
+		if (c < 0x20) {
+			*dp++ = '^';
+			*dp++ = c + '@';
+		} else if (c == 0x7F) {
+			*dp++ = '^';
+			*dp++ = '?';
+		} else
+			*dp++ = c;
+	}
+	*dp = '\0';
+	output_line(buf);
+}
+
+void
+print_l1_trace()
+{
+	char buf[MAX_PKT_FROM_TARGET*4+1];
+	int i, c;
+	char *dp;
+
+	dp = buf;
+	strcpy(dp, "L1: ");
+	dp += 4;
+	for (i = 1; i < rxpkt_len; i++) {
+		if ((i+1 < rxpkt_len) &&
+		    (rxpkt[i] == '\r' && rxpkt[i+1] == '\n' ||
+		     rxpkt[i] == '\n' && rxpkt[i+1] == '\r')) {
+			*dp = '\0';
+			output_line(buf);
+			if (i+2 == rxpkt_len)
+				return;
+			dp = buf;
+			*dp++ = '+';
+			*dp++ = ' ';
+			i++;
+			continue;
+		}
+		c = rxpkt[i];
+		if (c & 0x80) {
+			*dp++ = 'M';
+			*dp++ = '-';
+			c &= 0x7F;
+		}
+		if (c < 0x20) {
+			*dp++ = '^';
+			*dp++ = c + '@';
+		} else if (c == 0x7F) {
+			*dp++ = '^';
+			*dp++ = '?';
+		} else
+			*dp++ = c;
+	}
+	/* will get here only if no newline sequence at the end */
+	*dp = '\0';
+	output_line(buf);
+}
+
+void
+print_g23_trace()
+{
+	char buf[MAX_PKT_FROM_TARGET*3+2];
+	int i;
+	char *dp;
+
+	dp = buf;
+	strcpy(dp, "G23:");
+	dp += 4;
+	for (i = 1; i < rxpkt_len; i++) {
+		sprintf(dp, " %02X", rxpkt[i]);
+		dp += 3;
+	}
+	*dp = '\0';
+	output_line(buf);
+}
+
+void
+print_etm_output_raw()
+{
+	char buf[MAX_PKT_FROM_TARGET*3+2];
+	int i;
+	char *dp;
+
+	dp = buf;
+	strcpy(dp, "ETM:");
+	dp += 4;
+	for (i = 1; i < rxpkt_len; i++) {
+		sprintf(dp, " %02X", rxpkt[i]);
+		dp += 3;
+	}
+	*dp = '\0';
+	output_line(buf);
+}
+
+void
+print_unknown_packet()
+{
+	char buf[MAX_PKT_FROM_TARGET*3+5];
+	int i;
+	char *dp;
+
+	dp = buf;
+	strcpy(dp, "UNK:");
+	dp += 4;
+	for (i = 0; i < rxpkt_len; i++) {
+		sprintf(dp, " %02X", rxpkt[i]);
+		dp += 3;
+	}
+	*dp = '\0';
+	output_line(buf);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/rvinterf/lowlevel/logsent.c	Fri Nov 22 07:41:31 2013 +0000
@@ -0,0 +1,27 @@
+/*
+ * This module implements the logging of sent packets
+ */
+
+#include <sys/types.h>
+#include <stdio.h>
+#include <string.h>
+#include <strings.h>
+#include "../limits.h"
+
+log_sent_packet(pkt, pktlen)
+	u_char *pkt;
+{
+	char buf[MAX_PKT_TO_TARGET*3+5];
+	int i;
+	char *dp;
+
+	dp = buf;
+	strcpy(dp, "Sent");
+	dp += 4;
+	for (i = 0; i < pktlen; i++) {
+		sprintf(dp, " %02X", pkt[i]);
+		dp += 3;
+	}
+	*dp = '\0';
+	output_line(buf);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/rvinterf/lowlevel/output.c	Fri Nov 22 07:41:31 2013 +0000
@@ -0,0 +1,38 @@
+/*
+ * This module implements the output/logging function
+ */
+
+#include <sys/types.h>
+#include <stdio.h>
+#include <string.h>
+#include <strings.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <time.h>
+
+extern int background;
+extern FILE *logF;
+extern time_t logtime;
+
+static struct tm last_tm;
+
+void
+output_line(item)
+	char *item;
+{
+	struct tm *curtm;
+
+	if (!background)
+		printf("%s\n", item);
+	if (!logF)
+		return;
+	curtm = gmtime(&logtime);
+	if (curtm->tm_year != last_tm.tm_year ||
+	    curtm->tm_mon != last_tm.tm_mon ||
+	    curtm->tm_mday != last_tm.tm_mday)
+		fprintf(logF, "%d-%02d-%02d (gmtime):\n", curtm->tm_year + 1900,
+			curtm->tm_mon+1, curtm->tm_mday);
+	fprintf(logF, "[%02d:%02d:%02d] %s\n", curtm->tm_hour, curtm->tm_min,
+		curtm->tm_sec, item);
+	bcopy(curtm, &last_tm, sizeof(struct tm));
+}
--- a/rvinterf/lowlevel/packetrx.c	Fri Nov 22 05:56:07 2013 +0000
+++ b/rvinterf/lowlevel/packetrx.c	Fri Nov 22 07:41:31 2013 +0000
@@ -6,21 +6,21 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <unistd.h>
-#include "pktmux.h"
+#include "../pktmux.h"
+#include "../limits.h"
 
 extern int target_fd;
 
-#define	MAXPKT	512
-u_char rxpkt[MAXPKT];
+u_char rxpkt[MAX_PKT_FROM_TARGET];
 size_t rxpkt_len;
 
-extern char pr_item[];
-
 static int in_pkt, dle_state, toobig;
 
 static void
 process_inbyte(inb)
 {
+	char errbuf[128];
+
 	if (!in_pkt) {
 		if (inb != STX || dle_state) {
 			rxpkt_len++;
@@ -28,10 +28,10 @@
 			return;
 		}
 		if (rxpkt_len) {
-			sprintf(pr_item,
+			sprintf(errbuf,
 				"Warning: Rx %u byte%s outside of a packet",
 				(unsigned)rxpkt_len, rxpkt_len != 1 ? "s" : "");
-			print_item();
+			output_line(errbuf);
 			rxpkt_len = 0;
 		}
 		in_pkt = 1;
@@ -41,9 +41,9 @@
 	if (dle_state) {
 		dle_state = 0;
 		if (inb != STX && inb != DLE) {
-			sprintf(pr_item,
-				"Rx framing error: %02X after DLE\n", inb);
-			print_item();
+			sprintf(errbuf,
+				"Rx framing error: %02X after DLE", inb);
+			output_line(errbuf);
 			in_pkt = 0;
 			rxpkt_len = 0;
 			return;
@@ -61,10 +61,9 @@
 		rxpkt_len = 0;
 		return;
 	}
-data:	if (rxpkt_len >= MAXPKT) {
+data:	if (rxpkt_len >= MAX_PKT_FROM_TARGET) {
 		if (!toobig) {
-			sprintf(pr_item, "Error: Rx packet too big!\n");
-			print_item();
+			output_line("Error: Rx packet too big!");
 			toobig = 1;
 		}
 		return;
--- a/rvinterf/lowlevel/packettx.c	Fri Nov 22 05:56:07 2013 +0000
+++ b/rvinterf/lowlevel/packettx.c	Fri Nov 22 07:41:31 2013 +0000
@@ -6,8 +6,8 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <unistd.h>
-#include "pktmux.h"
-#include "txpkt.h"
+#include "../pktmux.h"
+#include "../limits.h"
 
 extern int target_fd;
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/rvinterf/lowlevel/rvtdump.c	Fri Nov 22 07:41:31 2013 +0000
@@ -0,0 +1,122 @@
+/*
+ * This program reads bytes from a serial port, parses them assuming
+ * TI's RVT MUX format, and prints every decoded packet.
+ */
+
+#include <sys/types.h>
+#include <sys/errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <time.h>
+#include "../pktmux.h"
+
+extern int target_fd;
+extern char *baudrate_name;
+
+extern u_char rxpkt[];
+extern size_t rxpkt_len;
+
+char *logfname;
+FILE *logF;
+time_t logtime;
+int background;
+
+main(argc, argv)
+	char **argv;
+{
+	extern char *optarg;
+	extern int optind;
+	int c;
+	fd_set fds;
+
+	while ((c = getopt(argc, argv, "bB:d:l:")) != EOF)
+		switch (c) {
+		case 'b':
+			background++;
+			continue;
+		case 'B':
+			baudrate_name = optarg;
+			continue;
+		case 'd':
+			target_fd = atoi(optarg);
+			continue;
+		case 'l':
+			logfname = optarg;
+			continue;
+		case '?':
+		default:
+usage:			fprintf(stderr,
+				"usage: %s [options] ttyport\n", argv[0]);
+			exit(1);
+		}
+	if (background && !logfname) {
+		fprintf(stderr, "%s: -b is meaningless without -l\n", argv[0]);
+		exit(1);
+	}
+	if (target_fd <= 0) {
+		if (argc - optind != 1)
+			goto usage;
+		open_target_serial(argv[optind]);
+	}
+
+	set_serial_nonblock(0);
+	setlinebuf(stdout);
+	if (logfname) {
+		logF = fopen(logfname, "w");
+		if (!logF) {
+			perror(logfname);
+			exit(1);
+		}
+		fprintf(logF, "*** Log of decoded RVT output ***\n");
+		setlinebuf(logF);
+	}
+	if (background) {
+		c = fork();
+		if (c < 0) {
+			perror("fork");
+			exit(1);
+		}
+		if (c) {
+			printf("rvtdump forked into background (pid %d)\n", c);
+			exit(0);
+		}
+	}
+	for (;;) {
+		FD_ZERO(&fds);
+		FD_SET(target_fd, &fds);
+		c = select(target_fd+1, &fds, 0, 0, 0);
+		time(&logtime);
+		if (c < 0) {
+			if (errno == EINTR)
+				continue;
+			perror("select");
+			exit(1);
+		}
+		if (FD_ISSET(target_fd, &fds))
+			process_serial_rx();
+	}
+}
+
+handle_rx_packet()
+{
+	switch (rxpkt[0]) {
+	case RVT_RV_HEADER:
+		if (rxpkt_len < 6)
+			goto unknown;
+		print_rv_trace();
+		return;
+	case RVT_L1_HEADER:
+		print_l1_trace();
+		return;
+	case RVT_L23_HEADER:
+		print_g23_trace();
+		return;
+	case RVT_TM_HEADER:
+		print_etm_output_raw();
+		return;
+	default:
+	unknown:
+		print_unknown_packet();
+	}
+}