diff rvinterf/tmsh/rftablerd.c @ 121:4070847293a9

fc-tmsh: RF table reading code implemented
author Mychaela Falconia <falcon@freecalypso.org>
date Sun, 19 Feb 2017 08:32:37 +0000
parents
children db7fc16bac1e
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/rvinterf/tmsh/rftablerd.c	Sun Feb 19 08:32:37 2017 +0000
@@ -0,0 +1,367 @@
+/*
+ * Reading RF tables from formatted ASCII files for the rftw command
+ */
+
+#include <sys/types.h>
+#include <ctype.h>
+#include <stdio.h>
+#include <string.h>
+#include <strings.h>
+#include <stdlib.h>
+#include "localtypes.h"
+#include "l1tm.h"
+#include "exitcodes.h"
+
+#define	MAX_FIELDS_PER_LINE	64
+
+static char *filename;
+static FILE *rdfile;
+static unsigned lineno;
+static char linebuf[256], *line_fields[MAX_FIELDS_PER_LINE];
+static unsigned line_nfields, line_field_ptr;
+static char *format;
+static u_char *writeptr;
+static unsigned written_size;
+
+static int
+read_line()
+{
+	char *cp;
+
+	if (!fgets(linebuf, sizeof linebuf, rdfile))
+		return(0);
+	lineno++;
+	cp = linebuf;
+	for (line_nfields = 0; ; ) {
+		while (isspace(*cp))
+			cp++;
+		if (*cp == '\0' || *cp == '#')
+			break;
+		if (line_nfields >= MAX_FIELDS_PER_LINE) {
+			printf("%s line %d: too many fields on one line\n",
+				filename, lineno);
+			return(-1);
+		}
+		line_fields[line_nfields++] = cp;
+		while (*cp && !isspace(*cp))
+			cp++;
+		if (*cp)
+			*cp++ = '\0';
+	}
+	return(1);
+}
+
+static
+get_field(retp)
+	char **retp;
+{
+	int rc;
+
+	if (line_field_ptr < line_nfields) {
+		*retp = line_fields[line_field_ptr++];
+		return(1);
+	}
+	do {
+		rc = read_line();
+		if (rc <= 0)
+			return(rc);
+	} while (!line_nfields);
+	*retp = line_fields[0];
+	line_field_ptr = 1;
+	return(1);
+}
+
+static
+process_number(size)
+{
+	char *field;
+	int rc;
+	u_long number;
+
+	rc = get_field(&field);
+	if (rc < 0)
+		return(ERROR_USAGE);
+	if (!rc) {
+		printf("error: %s is too short for table format %s\n",
+			filename, format);
+		return(ERROR_USAGE);
+	}
+	if (field[0] == '-')
+		number = strtol(field, 0, 0);
+	else
+		number = strtoul(field, 0, 0);
+	switch (size) {
+	case 1:
+		*writeptr++ = number;
+		break;
+	case 2:
+		*writeptr++ = number;
+		*writeptr++ = number >> 8;
+		break;
+	case 4:
+		*writeptr++ = number;
+		*writeptr++ = number >> 8;
+		*writeptr++ = number >> 16;
+		*writeptr++ = number >> 24;
+		break;
+	default:
+		abort();
+	}
+	written_size += size;
+	return(0);
+}
+
+static
+ensure_eof()
+{
+	char *field;
+	int rc;
+
+	rc = get_field(&field);
+	if (rc < 0)
+		return(ERROR_USAGE);
+	if (rc) {
+		printf("error: %s is too long for table format %s\n",
+			filename, format);
+		return(ERROR_USAGE);
+	}
+	return(0);
+}
+
+static
+read_agc_table()
+{
+	int i, rc;
+
+	for (i = 0; i < 20; i++) {
+		rc = process_number(2);
+		if (rc)
+			return(rc);
+	}
+	return ensure_eof();
+}
+
+static
+read_afcparams()
+{
+	int i, rc;
+
+	for (i = 0; i < 4; i++) {
+		rc = process_number(4);
+		if (rc)
+			return(rc);
+	}
+	for (i = 0; i < 4; i++) {
+		rc = process_number(2);
+		if (rc)
+			return(rc);
+	}
+	return ensure_eof();
+}
+
+static
+read_agc_global_params()
+{
+	int i, rc;
+
+	for (i = 0; i < 4; i++) {
+		rc = process_number(2);
+		if (rc)
+			return(rc);
+	}
+	return ensure_eof();
+}
+
+static
+read_il2agc()
+{
+	int i, rc;
+
+	for (i = 0; i < 121; i++) {
+		rc = process_number(1);
+		if (rc)
+			return(rc);
+	}
+	return ensure_eof();
+}
+
+static
+read_tx_levels()
+{
+	int i, rc;
+
+	for (i = 0; i < 32; i++) {
+		rc = process_number(2);
+		if (rc)
+			return(rc);
+		rc = process_number(1);
+		if (rc)
+			return(rc);
+		rc = process_number(1);
+		if (rc)
+			return(rc);
+	}
+	return ensure_eof();
+}
+
+static
+read_tx_calchan()
+{
+	int i, rc;
+
+	for (i = 0; i < 64; i++) {
+		rc = process_number(2);
+		if (rc)
+			return(rc);
+	}
+	return ensure_eof();
+}
+
+static
+read_tx_caltemp()
+{
+	int i, rc;
+
+	for (i = 0; i < 20; i++) {
+		rc = process_number(2);
+		if (rc)
+			return(rc);
+	}
+	return ensure_eof();
+}
+
+static
+read_rx_calchan()
+{
+	int i, rc;
+
+	for (i = 0; i < 20; i++) {
+		rc = process_number(2);
+		if (rc)
+			return(rc);
+	}
+	return ensure_eof();
+}
+
+static
+read_rx_caltemp()
+{
+	int i, rc;
+
+	for (i = 0; i < 22; i++) {
+		rc = process_number(2);
+		if (rc)
+			return(rc);
+	}
+	return ensure_eof();
+}
+
+static
+read_rx_agc_params()
+{
+	int i, rc;
+
+	for (i = 0; i < 4; i++) {
+		rc = process_number(2);
+		if (rc)
+			return(rc);
+	}
+	return ensure_eof();
+}
+
+static
+read_raw_table()
+{
+	int rc;
+	char *field;
+	u_long number;
+
+	for (;;) {
+		rc = get_field(&field);
+		if (rc < 0)
+			return(ERROR_USAGE);
+		if (!rc)
+			break;
+		number = strtoul(field, 0, 16);
+		if (written_size >= MAX_RF_TABLE_SIZE) {
+			printf("error: raw table %s exceeds maximum size\n",
+				filename);
+			return(ERROR_USAGE);
+		}
+		*writeptr++ = number;
+		written_size++;
+	}
+	if (!written_size) {
+		printf("error: raw table %s is empty\n", filename);
+		return(ERROR_USAGE);
+	}
+	return(0);
+}
+
+static struct table_format {
+	char *kw;
+	int (*handler)();
+} table_formats[] = {
+	{"agc-table", read_agc_table},
+	{"afcparams", read_afcparams},
+	{"agc-global-params", read_agc_global_params},
+	{"il2agc", read_il2agc},
+	{"tx-levels", read_tx_levels},
+	{"tx-calchan", read_tx_calchan},
+	{"tx-caltemp", read_tx_caltemp},
+	{"rx-calchan", read_rx_calchan},
+	{"rx-caltemp", read_rx_caltemp},
+	{"rx-agc-params", read_rx_agc_params},
+	{"raw", read_raw_table},
+	{0, 0}
+};
+
+read_rf_table(filename_arg, rdbuf, format_ret, size_ret)
+	char *filename_arg;
+	u_char *rdbuf;
+	char **format_ret;
+	unsigned *size_ret;
+{
+	char *field;
+	int rc;
+	struct table_format *tp;
+
+	filename = filename_arg;
+	rdfile = fopen(filename, "r");
+	if (!rdfile) {
+		perror(filename);
+		return(ERROR_UNIX);
+	}
+	lineno = 0;
+	line_nfields = 0;
+	rc = get_field(&field);
+	if (rc <= 0) {
+not_valid_rftable:
+		printf("error: %s is not a valid RF table file\n", filename);
+		fclose(rdfile);
+		return(ERROR_USAGE);
+	}
+	if (strcmp(field, "rf_table"))
+		goto not_valid_rftable;
+	rc = get_field(&field);
+	if (rc <= 0)
+		goto not_valid_rftable;
+	for (tp = table_formats; tp->kw; tp++)
+		if (!strcmp(tp->kw, field))
+			break;
+	if (!tp->kw) {
+		printf("error: table format \"%s\" not recognized\n", field);
+		fclose(rdfile);
+		return(ERROR_USAGE);
+	}
+	format = tp->kw;
+	if (format_ret)
+		*format_ret = format;
+	writeptr = rdbuf;
+	written_size = 0;
+	rc = tp->handler();
+	fclose(rdfile);
+	if (size_ret)
+		*size_ret = written_size;
+	return(rc);
+}