view ffstools/cal2text/main.c @ 922:3152e23399a2

document SE K2x0 FFS quirks and our support for them
author Mychaela Falconia <falcon@freecalypso.org>
date Mon, 02 Jan 2023 00:50:19 +0000
parents 329c31f7c797
children
line wrap: on
line source

/*
 * The main() function for fc-cal2text lives here.
 */

#include <sys/types.h>
#include <sys/param.h>
#include <sys/file.h>
#include <sys/stat.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

char *input_dir_base, *output_dir_base;

extern void write_afcdac_ascii();
extern void write_stdmap_ascii();
extern void write_afcparams_table();
extern void write_agcwords_table();
extern void write_agcglobals_table();
extern void write_il2agc_table();
extern void write_tx_ramps_table();
extern void write_tx_levels_table();
extern void write_tx_calchan_table();
extern void write_tx_caltemp_table();
extern void write_rx_calchan_table();
extern void write_rx_caltemp_table();
extern void write_rx_agcparams_table();

struct output_chunk {
	unsigned	offset;
	char		*outfile;
	void		(*conv_func)();
};

static struct output_chunk afcdac_handling = {
	0, "afcdac", write_afcdac_ascii
};

static struct output_chunk stdmap_handling = {
	0, "stdmap", write_stdmap_ascii
};

static struct output_chunk afcparams_handling = {
	0, "afcparams", write_afcparams_table
};

static struct output_chunk agcglobals_handling = {
	0, "agcglobals", write_agcglobals_table
};

static struct output_chunk il2agc_handling[3] = {
	{0,	"il2agc-pwr",	write_il2agc_table},
	{121,	"il2agc-max",	write_il2agc_table},
	{242,	"il2agc-av",	write_il2agc_table},
};

static struct output_chunk agcwords_handling = {
	0, "agcwords", write_agcwords_table
};

static struct output_chunk tx_ramps_handling = {
	0, "ramps", write_tx_ramps_table
};

static struct output_chunk tx_levels_handling = {
	0, "levels", write_tx_levels_table
};

static struct output_chunk tx_calchan_handling = {
	0, "calchan", write_tx_calchan_table
};
 
static struct output_chunk tx_caltemp_handling = {
	0, "caltemp", write_tx_caltemp_table
};
 
static struct output_chunk rx_calchan_handling = {
	0, "calchan", write_rx_calchan_table
};
 
static struct output_chunk rx_caltemp_handling = {
	0, "caltemp", write_rx_caltemp_table
};

static struct output_chunk rx_agcparams_handling = {
	0, "agcparams", write_rx_agcparams_table
};

static struct input_file {
	char		*filename;
	unsigned	expect_size;
	char		*outdir;
	struct output_chunk *handling;
	unsigned	nchunks;
} input_file_list[] = {
	{"afcdac",            2,   "global",  &afcdac_handling,       1},
	{"stdmap",            2,   "global",  &stdmap_handling,       1},
	{"afcparams",         24,  "global",  &afcparams_handling,    1},
	{"rx/agcglobals",     8,   "global",  &agcglobals_handling,   1},
	{"rx/il2agc",         363, "global",   il2agc_handling,       3},
	{"rx/agcwords",	      40,  "global",  &agcwords_handling,     1},

	{"tx/ramps.850",      512, "tx-850",  &tx_ramps_handling,     1},
	{"tx/levels.850",     128, "tx-850",  &tx_levels_handling,    1},
	{"tx/calchan.850",    128, "tx-850",  &tx_calchan_handling,   1},
	{"tx/caltemp.850",    40,  "tx-850",  &tx_caltemp_handling,   1},
	{"rx/calchan.850",    40,  "rx-850",  &rx_calchan_handling,   1},
	{"rx/caltemp.850",    44,  "rx-850",  &rx_caltemp_handling,   1},
	{"rx/agcparams.850",  8,   "rx-850",  &rx_agcparams_handling, 1},

	{"tx/ramps.900",      512, "tx-900",  &tx_ramps_handling,     1},
	{"tx/levels.900",     128, "tx-900",  &tx_levels_handling,    1},
	{"tx/calchan.900",    128, "tx-900",  &tx_calchan_handling,   1},
	{"tx/caltemp.900",    40,  "tx-900",  &tx_caltemp_handling,   1},
	{"rx/calchan.900",    40,  "rx-900",  &rx_calchan_handling,   1},
	{"rx/caltemp.900",    44,  "rx-900",  &rx_caltemp_handling,   1},
	{"rx/agcparams.900",  8,   "rx-900",  &rx_agcparams_handling, 1},

	{"tx/ramps.1800",     512, "tx-1800", &tx_ramps_handling,     1},
	{"tx/levels.1800",    128, "tx-1800", &tx_levels_handling,    1},
	{"tx/calchan.1800",   128, "tx-1800", &tx_calchan_handling,   1},
	{"tx/caltemp.1800",   40,  "tx-1800", &tx_caltemp_handling,   1},
	{"rx/calchan.1800",   40,  "rx-1800", &rx_calchan_handling,   1},
	{"rx/caltemp.1800",   44,  "rx-1800", &rx_caltemp_handling,   1},
	{"rx/agcparams.1800", 8,   "rx-1800", &rx_agcparams_handling, 1},

	{"tx/ramps.1900",     512, "tx-1900", &tx_ramps_handling,     1},
	{"tx/levels.1900",    128, "tx-1900", &tx_levels_handling,    1},
	{"tx/calchan.1900",   128, "tx-1900", &tx_calchan_handling,   1},
	{"tx/caltemp.1900",   40,  "tx-1900", &tx_caltemp_handling,   1},
	{"rx/calchan.1900",   40,  "rx-1900", &rx_calchan_handling,   1},
	{"rx/caltemp.1900",   44,  "rx-1900", &rx_caltemp_handling,   1},
	{"rx/agcparams.1900", 8,   "rx-1900", &rx_agcparams_handling, 1},

	{0,                   0,   0,         0,                      0}
};

static
try_read_input_file(ip, buf)
	struct input_file *ip;
	u_char *buf;
{
	char pathname[MAXPATHLEN];
	int fd;
	struct stat st;

	sprintf(pathname, "%s/%s", input_dir_base, ip->filename);
	fd = open(pathname, O_RDONLY);
	if (fd < 0)
		return(0);
	fstat(fd, &st);
	if (!S_ISREG(st.st_mode)) {
		close(fd);
		fprintf(stderr, "%s is not a regular file, skipping\n",
			pathname);
		return(0);
	}
	if (st.st_size != ip->expect_size) {
		close(fd);
		fprintf(stderr,
		"%s has the wrong length (expected %u bytes), skipping\n",
			pathname, ip->expect_size);
		return(0);
	}
	read(fd, buf, ip->expect_size);
	close(fd);
	return(1);
}

static void
write_outputs(ip, buf)
	struct input_file *ip;
	u_char *buf;
{
	char pathname[MAXPATHLEN];
	struct output_chunk *op;
	unsigned nc;
	FILE *of;

	sprintf(pathname, "%s/%s", output_dir_base, ip->outdir);
	mkdir_existok(pathname);
	op = ip->handling;
	for (nc = 0; nc < ip->nchunks; op++, nc++) {
		sprintf(pathname, "%s/%s/%s", output_dir_base, ip->outdir,
			op->outfile);
		of = fopen(pathname, "w");
		if (!of) {
			perror(pathname);
			exit(1);
		}
		op->conv_func(buf + op->offset, of);
		fclose(of);
	}
}
 
main(argc, argv)
	char **argv;
{
	struct input_file *ip;
	u_char buf[512];

	if (argc != 3) {
		fprintf(stderr, "usage: %s input-dir output-dir\n", argv[0]);
		exit(1);
	}
	check_directory_exists(argv[1]);
	input_dir_base = argv[1];
	check_directory_exists(argv[2]);
	output_dir_base = argv[2];

	for (ip = input_file_list; ip->filename; ip++) {
		if (try_read_input_file(ip, buf))
			write_outputs(ip, buf);
	}
	exit(0);
}