view rvinterf/lowlevel/rviftmode.c @ 938:74930218c270

rvinterf TM log: decode ETM_AUDIO commands
author Mychaela Falconia <falcon@freecalypso.org>
date Wed, 24 May 2023 04:30:39 +0000
parents 06f96627ac9a
children ec5f51d33fdc
line wrap: on
line source

/*
 * This module is for rvinterf only.  Whenever we send or receive Test Mode
 * packets, we should be a little more intelligent about how we display and
 * log them.  By default we only print a one-line summary, and in verbose mode
 * we also emit a full hex dump.
 */

#include <sys/types.h>
#include <stdio.h>
#include <string.h>
#include <strings.h>
#include "../include/etm.h"
#include "../include/tm3.h"
#include "../include/tmffs2.h"

extern u_char rxpkt[];
extern size_t rxpkt_len;

extern int verbose;
extern FILE *logF;

static int
verify_cksum(pkt, pktlen)
	u_char *pkt;
	unsigned pktlen;
{
	int i, c;

	c = 0;
	for (i = 1; i < pktlen; i++)
		c ^= pkt[i];
	if (c == 0)
		return(0);
	else
		return(-1);
}

static void
etm_core_classify(pkt, pktlen, outbuf)
	u_char *pkt;
	unsigned pktlen;
	char *outbuf;
{
	if (pktlen < 4) {
runt:		strcpy(outbuf, "ETM_CORE runt");
		return;
	}
	switch (pkt[2]) {
	case TMCORE_OPC_MEM:
		if (pktlen < 5)
			goto runt;
		switch (pkt[3]) {
		case 0x01:
			strcpy(outbuf, "r8");
			return;
		case 0x02:
			strcpy(outbuf, "r16");
			return;
		case 0x04:
			strcpy(outbuf, "r32");
			return;
		case 0x11:
			strcpy(outbuf, "w8");
			return;
		case 0x12:
			strcpy(outbuf, "w16");
			return;
		case 0x14:
			strcpy(outbuf, "w32");
			return;
		default:
			sprintf(outbuf, "ETM_CORE mem opcode 0x%02X", pkt[3]);
		}
		return;
	case TMCORE_OPC_ECHO:
		strcpy(outbuf, "ping");
		return;
	case TMCORE_OPC_RESET:
		strcpy(outbuf, "tgtreset");
		return;
	case TMCORE_OPC_DEBUG:
		strcpy(outbuf, "ETM_CORE debug opc");
		return;
	case TMCORE_OPC_VERSION:
		strcpy(outbuf, "version");
		return;
	case TMCORE_OPC_CODEC_RD:
		strcpy(outbuf, "abbr");
		return;
	case TMCORE_OPC_CODEC_WR:
		strcpy(outbuf, "abbw");
		return;
	case TMCORE_OPC_DIEID:
		strcpy(outbuf, "dieid");
		return;
	default:
		sprintf(outbuf, "ETM_CORE opcode 0x%02X", pkt[2]);
	}
}

static void
tmffs2_cmd_classify(pkt, pktlen, outbuf)
	u_char *pkt;
	unsigned pktlen;
	char *outbuf;
{
	if (pktlen < 4) {
		strcpy(outbuf, "ETM_FFS2 runt");
		return;
	}
	switch (pkt[2]) {
	case TMFFS_FORMAT:
		strcpy(outbuf, "FFS2 format");
		return;
	case TMFFS_PREFORMAT:
		strcpy(outbuf, "FFS2 preformat");
		return;
	case TMFFS_MKDIR:
		strcpy(outbuf, "FFS2 mkdir");
		return;
	case TMFFS_OPENDIR:
		strcpy(outbuf, "FFS2 opendir");
		return;
	case TMFFS_READDIR:
		strcpy(outbuf, "FFS2 readdir");
		return;
	case TMFFS_REMOVE:
		strcpy(outbuf, "FFS2 remove");
		return;
	case TMFFS_RENAME:
		strcpy(outbuf, "FFS2 rename");
		return;
	case TMFFS_XLSTAT:
		strcpy(outbuf, "FFS2 xlstat");
		return;
	case TMFFS_SYMLINK:
		strcpy(outbuf, "FFS2 symlink");
		return;
	case TMFFS_READLINK:
		strcpy(outbuf, "FFS2 readlink");
		return;
	case TMFFS_OPEN:
		strcpy(outbuf, "FFS2 open");
		return;
	case TMFFS_CLOSE:
		strcpy(outbuf, "FFS2 close");
		return;
	case TMFFS_READ:
		strcpy(outbuf, "FFS2 read");
		return;
	case TMFFS_WRITE:
		strcpy(outbuf, "FFS2 write");
		return;
	case TMFFS_SEEK:
		strcpy(outbuf, "FFS2 seek");
		return;
	case TMFFS_FTRUNCATE:
		strcpy(outbuf, "FFS2 ftruncate");
		return;
	case TMFFS_TRUNCATE:
		strcpy(outbuf, "FFS2 truncate");
		return;
	case TMFFS_FILE_READ:
		strcpy(outbuf, "FFS2 fread");
		return;
	case TMFFS_FILE_WRITE:
		strcpy(outbuf, "FFS2 fwrite");
		return;
	case TMFFS_FSTAT:
		strcpy(outbuf, "FFS2 fstat");
		return;
	case TMFFS_LSTAT:
		strcpy(outbuf, "FFS2 lstat");
		return;
	case TMFFS_STAT:
		strcpy(outbuf, "FFS2 stat");
		return;
	case TMFFS_FCONTROL:
		strcpy(outbuf, "FFS2 fcontrol");
		return;
	case TMFFS_QUERY:
		strcpy(outbuf, "FFS2 query");
		return;
	case TMFFS_INIT:
		strcpy(outbuf, "FFS2 init");
		return;
	case TMFFS_EXIT:
		strcpy(outbuf, "FFS2 exit");
		return;
	case TMFFS_DIRXLSTAT:
		strcpy(outbuf, "FFS2 dirxlstat");
		return;
	case TMFFS_VERSION:
		strcpy(outbuf, "FFS2 version");
		return;
	case TMFFS_TFFS:
		strcpy(outbuf, "FFS2 tffs");
		return;
	default:
		sprintf(outbuf, "ETM_FFS2 opcode 0x%02X", pkt[2]);
	}
}

static void
audio_cmd_classify(pkt, pktlen, outbuf)
	u_char *pkt;
	unsigned pktlen;
	char *outbuf;
{
	if (pktlen < 4) {
		strcpy(outbuf, "ETM_AUDIO runt");
		return;
	}
	switch (pkt[2]) {
	case 'L':
		strcpy(outbuf, "aul");
		return;
	case 'S':
		strcpy(outbuf, "aus");
		return;
	case 'R':
		strcpy(outbuf, "aur");
		return;
	case 'W':
		strcpy(outbuf, "auw");
		return;
	default:
		sprintf(outbuf, "ETM_AUDIO opcode 0x%02X", pkt[2]);
	}
}

static void
tm_classify(pkt, pktlen, is_cmd, outbuf)
	u_char *pkt;
	unsigned pktlen;
	char *outbuf;
{
	if (pktlen < 3) {
		strcpy(outbuf, "RUNT");
		return;
	}
	if (verify_cksum(pkt, pktlen) < 0) {
		strcpy(outbuf, "BAD CKSUM");
		return;
	}
	switch (pkt[1]) {
	case ETM_CORE:
		if (is_cmd)
			etm_core_classify(pkt, pktlen, outbuf);
		else
			strcpy(outbuf, "ETM_CORE");
		return;
	case ETM_FFS1:
		strcpy(outbuf, "FFS1");
		return;
	case ETM_FFS2:
		if (is_cmd)
			tmffs2_cmd_classify(pkt, pktlen, outbuf);
		else
			strcpy(outbuf, "FFS2");
		return;
	case ETM_AUDIO:
		if (is_cmd)
			audio_cmd_classify(pkt, pktlen, outbuf);
		else
			strcpy(outbuf, "ETM_AUDIO");
		return;
	case ETM_BSIM:
		strcpy(outbuf, "BSIM");
		return;
	/* TM3 */
	case MEM_READ:
		strcpy(outbuf, "omr");
		return;
	case MEM_WRITE:
		strcpy(outbuf, "omw");
		return;
	case CODEC_READ:
		strcpy(outbuf, "oabbr");
		return;
	case CODEC_WRITE:
		strcpy(outbuf, "oabbw");
		return;
	/* L1TM */
	case TM_INIT:
		strcpy(outbuf, "tminit");
		return;
	case TM_MODE_SET:
		strcpy(outbuf, "tms");
		return;
	case VERSION_GET:
		strcpy(outbuf, "tm3ver");
		return;
	case RF_ENABLE:
		strcpy(outbuf, "rfe");
		return;
	case STATS_READ:
		strcpy(outbuf, "sr");
		return;
	case STATS_CONFIG_WRITE:
		strcpy(outbuf, "scw");
		return;
	case STATS_CONFIG_READ:
		strcpy(outbuf, "scr");
		return;
	case RF_PARAM_WRITE:
		strcpy(outbuf, "rfpw");
		return;
	case RF_PARAM_READ:
		strcpy(outbuf, "rfpr");
		return;
	case RF_TABLE_WRITE:
		strcpy(outbuf, "rftw");
		return;
	case RF_TABLE_READ:
		strcpy(outbuf, "rftr");
		return;
	case RX_PARAM_WRITE:
		strcpy(outbuf, "rxpw");
		return;
	case RX_PARAM_READ:
		strcpy(outbuf, "rxpr");
		return;
	case TX_PARAM_WRITE:
		strcpy(outbuf, "txpw");
		return;
	case TX_PARAM_READ:
		strcpy(outbuf, "txpr");
		return;
	case TX_TEMPLATE_WRITE:
		strcpy(outbuf, "ttw");
		return;
	case TX_TEMPLATE_READ:
		strcpy(outbuf, "ttr");
		return;
	case MISC_PARAM_WRITE:
		strcpy(outbuf, "mpw");
		return;
	case MISC_PARAM_READ:
		strcpy(outbuf, "mpr");
		return;
	case MISC_ENABLE:
		strcpy(outbuf, "me");
		return;
	default:
		sprintf(outbuf, "mid 0x%02X", pkt[1]);
	}
}

static void
hexdump_out(line)
	char *line;
{
	if (logF)
		fprintf(logF, "%s\n", line);
	else
		printf("%s\n", line);
}

void
log_sent_tm(pkt, pktlen)
	u_char *pkt;
{
	char summary[32], headline[80];

	tm_classify(pkt, pktlen, 1, summary);
	sprintf(headline, "Sent Test Mode cmd (%s)", summary);
	output_line(headline);
	if (verbose >= 1)
		packet_hex_dump(pkt, pktlen, hexdump_out);
}

void
print_tm_output_new()
{
	char summary[32], headline[80];

	tm_classify(rxpkt, (unsigned) rxpkt_len, 0, summary);
	sprintf(headline, "Rx Test Mode resp (%s)", summary);
	output_line(headline);
	if (verbose >= 1)
		packet_hex_dump(rxpkt, (unsigned) rxpkt_len, hexdump_out);
}