view rvinterf/lowlevel/rvtdump.c @ 896:0a2f50c571de

CHANGES: fc-buzplay basic 'play' command extension
author Mychaela Falconia <falcon@freecalypso.org>
date Sun, 03 Apr 2022 08:41:34 +0000
parents 6f078c4a5506
children
line wrap: on
line source

/*
 * 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 "../include/pktmux.h"

extern int target_fd;

extern u_char rxpkt[];
extern size_t rxpkt_len;

char *logfname;
FILE *logF;
time_t logtime;
int background;
int no_output;	/* for output.c */

static char *baudrate = "115200";

static char keepalive_msg[] =
	"Received keepalive query, unable to respond, please run rvinterf";

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++;
			no_output++;	/* for output.c */
			continue;
		case 'B':
			baudrate = 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_serial_port(argv[optind]);
		set_fixed_baudrate(baudrate);
	}

	set_serial_nonblock(0);
	setlinebuf(stdout);
	if (logfname) {
		logF = fopen(logfname, "w");
		if (!logF) {
			perror(logfname);
			exit(1);
		}
		setlinebuf(logF);
		fprintf(logF, "*** Log of decoded RVT output ***\n");
	}
	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_tm_output_raw();
		return;
	case RVT_AT_HEADER:
		print_ati_output();
		return;
	case RVT_EXTUI_HEADER:
		if (rxpkt_len < 5 || !(rxpkt_len & 1))
			goto unknown;
		report_extui_packet();
		return;
	case RVT_TCH_HEADER:
		print_tch_output_raw();
		return;
	case RVT_KEEPALIVE_HEADER:
		if (rxpkt_len != 2 || rxpkt[1] != 'Q')
			goto unknown;
		output_line(keepalive_msg);
		return;
	case '*':
		print_fc_lld_msg();
		return;
	default:
	unknown:
		print_unknown_packet();
	}
}