aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHarald Welte <laforge@osmocom.org>2022-11-30 23:01:10 +0100
committerHarald Welte <laforge@osmocom.org>2023-03-22 10:48:46 +0100
commit43c61db980988aa1f299726578f47fef2a456db0 (patch)
tree550d72f0437713e7b0877ccde5ba19cd50b9633e
parentHACK: add minimalistic V.110 trace decoding program (diff)
downloadlibosmocore-43c61db980988aa1f299726578f47fef2a456db0.tar.xz
libosmocore-43c61db980988aa1f299726578f47fef2a456db0.zip
utils: Add HDLC decode utility
This utility can be used to decode any raw ISDN HDLC bitstream from a file, such as a raw B-channel capture created by osmo-isdntap. Change-Id: Ie3a2f9300b2d7ebff66064d5d7f81a1a2f684a6c
-rw-r--r--utils/Makefile.am4
-rw-r--r--utils/hdlc_decode.c92
2 files changed, 96 insertions, 0 deletions
diff --git a/utils/Makefile.am b/utils/Makefile.am
index 9d56f63a..96d37e46 100644
--- a/utils/Makefile.am
+++ b/utils/Makefile.am
@@ -48,3 +48,7 @@ endif
v110_decode_SOURCES = v110_decode.c
v110_decode_LDADD = $(LDADD) $(top_builddir)/src/isdn/libosmoisdn.la -losmotrau # HACK!
noinst_PROGRAMS += v110_decode
+
+hdlc_decode_SOURCES = hdlc_decode.c
+hdlc_decode_LDADD = $(LDADD) #$(top_builddir)/src/isdn/libosmoisdn.la -losmotrau # HACK!
+noinst_PROGRAMS += hdlc_decode
diff --git a/utils/hdlc_decode.c b/utils/hdlc_decode.c
new file mode 100644
index 00000000..125b0bc6
--- /dev/null
+++ b/utils/hdlc_decode.c
@@ -0,0 +1,92 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <osmocom/core/isdnhdlc.h>
+#include <osmocom/core/utils.h>
+
+static struct osmo_isdnhdlc_vars g_hdlc;
+
+/* process input buffer of given length; find + process any HDLC frames contained inside,
+ * and return the number of bytes consumed from start of inbuf */
+static int process_buf(const uint8_t *inbuf, size_t inlen)
+{
+ uint8_t outbuf[4096];
+ int rc, count;
+ size_t in_offset = 0;
+
+#if 0
+ while ((rc = osmo_isdnhdlc_decode(&g_hdlc, inbuf + in_offset, inlen - in_offset, &count,
+ outbuf, sizeof(outbuf))) != 2) {
+#else
+ while (true) {
+ rc = osmo_isdnhdlc_decode(&g_hdlc, inbuf + in_offset, inlen - in_offset, &count,
+ outbuf, sizeof(outbuf));
+#endif
+ //printf("rc=%d, inlen=%zu, in_offset=%zu, count=%d\n", rc, inlen, in_offset, count);
+ if (rc > 0) {
+ int frlen = rc;
+ printf("%s\n", osmo_hexdump(outbuf, frlen));
+ } else {
+ switch (rc) {
+ case -OSMO_HDLC_FRAMING_ERROR:
+ fprintf(stderr, "FRAMING_ERR\n");
+ break;
+ case -OSMO_HDLC_CRC_ERROR:
+ fprintf(stderr, "CRC_ERR\n");
+ break;
+ case -OSMO_HDLC_LENGTH_ERROR:
+ fprintf(stderr, "LEN_ERR\n");
+ break;
+ }
+ }
+ in_offset += count;
+ if (in_offset >= inlen)
+ break;
+ }
+
+ return in_offset;
+}
+
+static int open_and_process(const char *fname)
+{
+ int fd = open(fname, O_RDONLY);
+ if (fd < 0)
+ return fd;
+
+ int read_offset = 0;
+
+ while (true) {
+ uint8_t inbuf[4096];
+ int rc, inlen, count;
+
+ /* read a chunk of data */
+ rc = read(fd, inbuf + read_offset, sizeof(inbuf) - read_offset);
+ if (rc <= 0)
+ return rc;
+ /* available length */
+ inlen = read_offset + rc;
+ //printf("read %d bytes to read_offset=%u => %d available bytes\n", rc, read_offset, inlen);
+
+ count = process_buf(inbuf, inlen);
+ //printf("processed %d bytes from inbuf\n", count);
+ if (count == inlen) {
+ read_offset = 0;
+ } else if (count < inlen) {
+ //printf("moving %d remaining bytes to start of inbuf\n", inlen-count);
+ memmove(inbuf, inbuf + count, inlen - count);
+ read_offset = inlen - count;
+ }
+ }
+}
+
+int main(int argc, char **argv)
+{
+ osmo_isdnhdlc_rcv_init(&g_hdlc, OSMO_HDLC_F_BITREVERSE);
+
+ return open_and_process(argv[1]);
+}