view simtool/smsp_dump.c @ 38:f5a26c1d0b93

fc-simtool smsp-dump implemented
author Mychaela Falconia <falcon@freecalypso.org>
date Fri, 12 Feb 2021 20:39:15 +0000
parents simtool/pbdump.c@72a24b8538eb
children f1ea981ab225
line wrap: on
line source

/*
 * This module implements intelligent dumping of EF_SMSP (smsp-dump).
 */

#include <sys/types.h>
#include <stdio.h>
#include "simresp.h"
#include "curfile.h"

static
check_blank_area(dp, endp)
	u_char *dp, *endp;
{
	while (dp < endp)
		if (*dp++ != 0xFF)
			return(-1);
	return(0);
}

static void
dump_da_field(binaddr, outf)
	u_char *binaddr;
	FILE *outf;
{
	char digits[21];

	fputs("DA=", outf);
	if (binaddr[0] < 1 || binaddr[0] > 20) {
malformed:	fputs("malformed ", outf);
		return;
	}
	if ((binaddr[0] & 1) && (binaddr[(binaddr[0] >> 1) + 2] & 0xF0) != 0xF0)
		goto malformed;
	if (check_blank_area(binaddr + 2 + ((binaddr[0] + 1) >> 1),
			     binaddr + 12) < 0)
		goto malformed;
	/* all checks passed */
	decode_address_digits(binaddr + 2, digits, binaddr[0]);
	fprintf(outf, "%s,0x%02X ", digits, binaddr[1]);
}

static void
dump_sca_field(binaddr, outf)
	u_char *binaddr;
	FILE *outf;
{
	char digits[21];
	int rc;

	fputs("SC=", outf);
	if (binaddr[0] < 2 || binaddr[0] > 11) {
malformed:	fputs("malformed ", outf);
		return;
	}
	rc = decode_phone_number(binaddr + 2, binaddr[0] - 1, digits);
	if (rc < 0)
		goto malformed;
	rc = check_blank_area(binaddr + 1 + binaddr[0], binaddr + 12);
	if (rc < 0)
		goto malformed;
	/* all checks passed */
	fprintf(outf, "%s,0x%02X ", digits, binaddr[1]);
}

static void
dump_record(recno, outf)
	unsigned recno;
	FILE *outf;
{
	int rc;
	unsigned textlen;
	u_char *fixp;

	fprintf(outf, "#%u: ", recno);
	if (sim_resp_data_len > 28) {
		rc = validate_alpha_field(sim_resp_data,
					  sim_resp_data_len - 28,
					  &textlen);
		if (rc < 0) {
malformed:		fprintf(outf, "malformed record\n");
			return;
		}
	} else
		textlen = 0;
	fixp = sim_resp_data + sim_resp_data_len - 28;
	if ((fixp[0] & 0xE0) != 0xE0)
		goto malformed;
	if ((fixp[0] & 0x01) && check_blank_area(fixp + 1, fixp + 13) < 0)
		goto malformed;
	if ((fixp[0] & 0x02) && check_blank_area(fixp + 13, fixp + 25) < 0)
		goto malformed;
	if ((fixp[0] & 0x04) && fixp[25] != 0xFF)
		goto malformed;
	if ((fixp[0] & 0x08) && fixp[26] != 0xFF)
		goto malformed;
	if ((fixp[0] & 0x10) && fixp[27] != 0xFF)
		goto malformed;
	/* basic checks passed, emit present fields */
	if (!(fixp[0] & 0x01))
		dump_da_field(fixp + 1, outf);
	if (!(fixp[0] & 0x02))
		dump_sca_field(fixp + 13, outf);
	if (!(fixp[0] & 0x04))
		fprintf(outf, "PID=0x%02X ", fixp[25]);
	if (!(fixp[0] & 0x08))
		fprintf(outf, "DCS=0x%02X ", fixp[26]);
	if (!(fixp[0] & 0x10))
		fprintf(outf, "VP=%u ", fixp[27]);
	print_alpha_field(sim_resp_data, textlen, outf);
	putc('\n', outf);
}

cmd_smsp_dump(argc, argv)
	char **argv;
{
	int rc;
	FILE *outf;
	unsigned recno;

	rc = select_ef_smsp();
	if (rc < 0)
		return(rc);
	if (argv[1]) {
		outf = fopen(argv[1], "w");
		if (!outf) {
			perror(argv[1]);
			return(-1);
		}
	} else
		outf = stdout;
	for (recno = 1; recno <= curfile_record_count; recno++) {
		rc = readrec_op(recno, 0x04, curfile_record_len);
		if (rc < 0) {
			if (argv[1])
				fclose(outf);
			return(rc);
		}
		dump_record(recno, outf);
	}
	if (argv[1])
		fclose(outf);
	return(0);
}