changeset 116:4253e7dbffc9

tfo: new program compose-xpar
author Mychaela Falconia <falcon@freecalypso.org>
date Fri, 26 Dec 2025 19:03:29 +0000
parents 62b3b916c0a4
children 1465a737c4ce
files .hgignore tfo/Makefile tfo/compose-xpar.c
diffstat 3 files changed, 111 insertions(+), 1 deletions(-) [+]
line wrap: on
line diff
--- a/.hgignore	Mon Dec 22 08:37:22 2025 +0000
+++ b/.hgignore	Fri Dec 26 19:03:29 2025 +0000
@@ -12,6 +12,7 @@
 
 ^pathloss/pathloss$
 
+^tfo/compose-xpar$
 ^tfo/find-is-hdr$
 ^tfo/tfo-trace-msg$
 
--- a/tfo/Makefile	Mon Dec 22 08:37:22 2025 +0000
+++ b/tfo/Makefile	Fri Dec 26 19:03:29 2025 +0000
@@ -1,6 +1,6 @@
 CC=	gcc
 CFLAGS=	-O2
-STD=	find-is-hdr tfo-trace-msg
+STD=	compose-xpar find-is-hdr tfo-trace-msg
 PROGS=	${STD}
 
 all:	${PROGS}
@@ -8,6 +8,7 @@
 ${STD}:
 	${CC} ${CFLAGS} -o $@ $@.c
 
+compose-xpar:	compose-xpar.c
 find-is-hdr:	find-is-hdr.c
 tfo-trace-msg:	tfo-trace-msg.c
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tfo/compose-xpar.c	Fri Dec 26 19:03:29 2025 +0000
@@ -0,0 +1,108 @@
+/*
+ * This program is a tool for BTS experiments: it constructs hex byte strings
+ * to be sent in the TFO transparent container IE of TS 48.058 section 9.3.59
+ * from manually-supplied groups of bits that are based on the description in
+ * TS 28.062 Annex H.
+ */
+
+#include <ctype.h>
+#include <stdio.h>
+#include <stdint.h>
+#include <stdlib.h>
+
+static FILE *inf;
+static char *infname;
+static char linebuf[128];
+static int lineno;
+
+#define	MAX_BYTES	35
+
+static uint8_t byte_str_buf[MAX_BYTES];
+static unsigned byte_fill, bit_fill;
+
+static void
+add_bit(new_bit)
+{
+	if (byte_fill >= MAX_BYTES) {
+		fprintf(stderr, "%s line %d: bit addition exceeds MAX_BYTES\n",
+			infname, lineno);
+		exit(1);
+	}
+	byte_str_buf[byte_fill] |= new_bit << (7 - bit_fill);
+	bit_fill++;
+	if (bit_fill >= 8) {
+		byte_fill++;
+		bit_fill = 0;
+	}
+}
+
+static void
+process_line()
+{
+	char *cp = linebuf;
+
+	for (;;) {
+		while (isspace(*cp))
+			cp++;
+		if (*cp == '\0' || *cp == '#')
+			return;
+		if (*cp != '0' && *cp != '1') {
+			fprintf(stderr, "%s line %d: invalid data\n",
+				infname, lineno);
+			exit(1);
+		}
+		add_bit(*cp - '0');
+		cp++;
+	}
+}
+
+static void
+pad_last_byte()
+{
+	if (bit_fill) {
+		byte_fill++;
+		bit_fill = 0;
+	}
+	if (!byte_fill) {
+		fprintf(stderr, "error: no bit input given\n");
+		exit(1);
+	}
+}
+
+static void
+emit_output()
+{
+	unsigned n;
+
+	for (n = 0; n < byte_fill; n++)
+		printf("%02x", byte_str_buf[n]);
+	putchar('\n');
+}
+
+main(argc, argv)
+	char **argv;
+{
+	switch (argc) {
+	case 1:
+		inf = stdin;
+		infname = "stdin";
+		break;
+	case 2:
+		infname = argv[1];
+		inf = fopen(infname, "r");
+		if (!inf) {
+			perror(infname);
+			exit(1);
+		}
+		break;
+	default:
+		fprintf(stderr, "usage: %s [input-file]\n", argv[0]);
+		exit(1);
+	}
+
+	for (lineno = 1; fgets(linebuf, sizeof linebuf, inf); lineno++)
+		process_line();
+	pad_last_byte();
+	emit_output();
+	exit(0);
+}