diff 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 diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/simtool/smsp_dump.c	Fri Feb 12 20:39:15 2021 +0000
@@ -0,0 +1,143 @@
+/*
+ * 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);
+}