diff options
author | Harald Welte <laforge@osmocom.org> | 2022-11-30 23:01:10 +0100 |
---|---|---|
committer | Harald Welte <laforge@osmocom.org> | 2023-03-22 10:48:46 +0100 |
commit | 43c61db980988aa1f299726578f47fef2a456db0 (patch) | |
tree | 550d72f0437713e7b0877ccde5ba19cd50b9633e | |
parent | HACK: add minimalistic V.110 trace decoding program (diff) | |
download | libosmocore-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.am | 4 | ||||
-rw-r--r-- | utils/hdlc_decode.c | 92 |
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]); +} |