diff options
author | Harald Welte <laforge@gnumonks.org> | 2016-11-14 21:29:01 +0100 |
---|---|---|
committer | Harald Welte <laforge@gnumonks.org> | 2016-11-14 21:29:01 +0100 |
commit | 1df5cf49501226ebc9ba7f9989cc7c07d38a3062 (patch) | |
tree | b181b436aa8edf968ef09e24d00d302e7b7ec9e8 | |
parent | 6daa71dbd2898ee4afad984eff79c30ce171d0d6 (diff) |
e1cap_dump: Implement functional HDLC decode of super-channel
Finally the bit ordering and bit format of the SuperChannel has been
figured out.
* the data as read from DAHDI must be flipped (0->1 / 1->0). why?
* the data must be read lsb-first when converting into a bit-buffer
We are now getting the following output e.g. for a OM2000 "TX
Configuration Request" message:
fa 03 8a 8a 80 80 00 13 00 b0 0b 00 ff 01 20 00 2e 2b 1c 00 06 01 95 81 76 00 e9 bf
^ lapd hdr ^ OML ^l ^OM2000 TX Config Req for 43 dBm
-rw-r--r-- | src/Makefile | 9 | ||||
-rw-r--r-- | src/e1cap_dump.c | 65 | ||||
-rw-r--r-- | src/hdlc-test.c | 42 |
3 files changed, 105 insertions, 11 deletions
diff --git a/src/Makefile b/src/Makefile index 734c658..25c00d6 100644 --- a/src/Makefile +++ b/src/Makefile @@ -1,16 +1,19 @@ CFLAGS=-g -Wall LDFLAGS=-losmocore -losmogsm -losmovty -losmoabis -ltalloc -all: osmo-e1-recorder osmo-e1cap-dump +all: osmo-e1-recorder osmo-e1cap-dump hdlc-test osmo-e1-recorder: e1_recorder.o storage.o vty.o $(CC) $(LDFLAGS) -o$@ $^ -osmo-e1cap-dump: e1cap_dump.o storage.o +osmo-e1cap-dump: e1cap_dump.o storage.o flip_bits.o hdlc.o + $(CC) $(LDFLAGS) -o$@ $^ + +hdlc-test: hdlc.o hdlc-test.o $(CC) $(LDFLAGS) -o$@ $^ %.o: %.c $(CC) $(CFLAGS) -o $@ -c $^ clean: - @rm *.o osmo-e1-recorder + @rm *.o osmo-e1-recorder osmo-e1cap-dump diff --git a/src/e1cap_dump.c b/src/e1cap_dump.c index 7bbb71e..eb55c41 100644 --- a/src/e1cap_dump.c +++ b/src/e1cap_dump.c @@ -5,6 +5,7 @@ #include <sys/time.h> +#include <osmocom/core/bits.h> #include <osmocom/core/signal.h> #include <osmocom/core/logging.h> #include <osmocom/core/application.h> @@ -12,6 +13,8 @@ #include "storage.h" #include "recorder.h" +#include "flip_bits.h" +#include "hdlc.h" struct e1_recorder g_recorder; @@ -28,6 +31,8 @@ enum mode { struct sc_state { uint8_t ts_data[MAX_TS][CHUNK_BYTES]; uint8_t num_ts; + uint32_t ts_mask; + struct hdlc_proc hdlc; }; static struct sc_state g_sc_state[2]; @@ -65,15 +70,21 @@ static int all_bytes_are(unsigned char ch, const uint8_t *data, int len) static void handle_sc_out(struct sc_state *scs) { - uint8_t out[scs->num_ts * CHUNK_BYTES]; + unsigned int num_bytes = scs->num_ts * CHUNK_BYTES; + unsigned int num_bits = num_bytes * 8; + uint8_t out[32*CHUNK_BYTES]; + ubit_t out_bits[32*CHUNK_BYTES*8]; int i, j, k = 0; /* re-shuffle the data from columns to lines */ for (i = 0; i < CHUNK_BYTES; i++) { - for (j = 1; j < scs->num_ts; j++) + for (j = 0; j < scs->num_ts; j++) out[k++] = scs->ts_data[j][i]; } - printf("%s\n", osmo_hexdump_nospc(out, scs->num_ts * CHUNK_BYTES)); + //printf("num_bytes=%u %s\n", num_bytes, osmo_hexdump_nospc(out, num_bytes)); + osmo_pbit2ubit_ext(out_bits, 0, out, 0, num_bits, 1); + //for (i = 0; i < num_bits; i++) fputc(out_bits[i] ? '1' : '.', stdout); fputc('\n', stdout); + process_raw_hdlc(&scs->hdlc, out_bits, num_bits); } static void handle_sc_in(struct osmo_e1cap_pkthdr *pkt, const uint8_t *data, unsigned int len) @@ -96,16 +107,48 @@ static void handle_sc_in(struct osmo_e1cap_pkthdr *pkt, const uint8_t *data, uns exit(1); } - memcpy(scs->ts_data[pkt->ts_nr], data, len); - if (pkt->ts_nr-1 > scs->num_ts) - scs->num_ts = pkt->ts_nr-1; - if (pkt->ts_nr == scs->num_ts) + if (pkt->ts_nr == 1) { + scs->ts_mask = 0; + memset(scs->ts_data, 0, sizeof(scs->ts_data)); + } + + /* copy over the data */ + memcpy(scs->ts_data[pkt->ts_nr-1], data, len); + /* note that we have valid data for the given timeslot */ + scs->ts_mask |= (1 << (pkt->ts_nr-1)); + + /* make sure we know what's the maximum timeslot number */ + if (pkt->ts_nr > scs->num_ts) + scs->num_ts = pkt->ts_nr; + + /* check if we have data for all needed timeslots */ + uint32_t ts_mask = (1 << scs->num_ts) -1; + //printf("num_ts=%u, ts_mask=0x%x, scs_ts_mask=0x%x\n", scs->num_ts, ts_mask, scs->ts_mask); + if (scs->ts_mask == ts_mask) { handle_sc_out(scs); + } } -static void handle_data(struct osmo_e1cap_pkthdr *pkt, const uint8_t *data, int len) +static void handle_data(struct osmo_e1cap_pkthdr *pkt, uint8_t *data, int len) { + flip_buf_bits(data, len); +#if 0 + /* filter out all-ff/all-fe/all-7f */ + if (all_bytes_are(0xff, data, len) || + all_bytes_are(0x7f, data, len) || + all_bytes_are(0x7e, data, len) || + all_bytes_are(0xe7, data, len) || + all_bytes_are(0x3f, data, len) || + all_bytes_are(0xf3, data, len) || + all_bytes_are(0x9f, data, len) || + all_bytes_are(0xf9, data, len) || + all_bytes_are(0xcf, data, len) || + all_bytes_are(0xfc, data, len) || + all_bytes_are(0xfe, data, len)) + return; +#endif + switch (g_mode) { case MODE_PRINT: printf("%s %02u/%02u %u (%u): %s\n", @@ -127,6 +170,7 @@ static int subch_demux_out_cb(struct subch_demux *dmx, int ch, uint8_t *data, int len, void *c) { OSMO_ASSERT(ch == g_filter_subslot); + handle_data(g_last_pkthdr, data, len); return 0; @@ -175,6 +219,9 @@ int main(int argc, char **argv) printf("sizeof(timeval) = %zu\n", sizeof(struct timeval)); printf("sizeof(osmo_e1cap_pkthdr) = %zu\n", sizeof(*pkt)); + memset(g_sc_state, 0, sizeof(g_sc_state)); + init_flip_bits(); + handle_options(argc, argv); if (optind >= argc) { @@ -194,6 +241,8 @@ int main(int argc, char **argv) subch_demux_activate(&smux, g_filter_subslot); } +// printf("hdlc=%s\n", osmo_hexdump(&g_sc_state[0].hdlc, sizeof(g_sc_state[0].hdlc))); + while ((pkt = osmo_e1cap_read_next(f))) { num_pkt++; g_last_pkthdr = pkt; diff --git a/src/hdlc-test.c b/src/hdlc-test.c new file mode 100644 index 0000000..1c7c6ef --- /dev/null +++ b/src/hdlc-test.c @@ -0,0 +1,42 @@ +#include <string.h> +#include "hdlc.h" + +#include <osmocom/core/utils.h> +#include <osmocom/core/bits.h> + +const char *tdata = "7e7e7e7e7a76f20609167d3cfcfcfc"; + +static void hdlc_process_hex_str(struct hdlc_proc *hdlc, const char *hex) +{ + uint8_t *bytes, *bits; + int string_len = strlen(hex); + int byte_len = string_len/2; + int bit_len = byte_len*8; + int rc; + + printf("hex string = %s\n", hex); + bytes = alloca(byte_len); + bits = alloca(bit_len); + rc = osmo_hexparse(hex, bytes, byte_len); + printf("parsed bytes = %s\n", osmo_hexdump(bytes, byte_len)); + + printf("MSB mode\n"); + osmo_pbit2ubit(bits, bytes, bit_len); + process_raw_hdlc(hdlc, bits, bit_len); + + printf("LSB mode\n"); + memset(hdlc, 0, sizeof(*hdlc)); + osmo_pbit2ubit_ext(bits, 0, bytes, 0, bit_len, 1); + process_raw_hdlc(hdlc, bits, bit_len); +} + +int main(int argc, char **argv) +{ + struct hdlc_proc hdlc; + memset(&hdlc, 0, sizeof(hdlc)); + + if (argc < 2) + exit(1); + + hdlc_process_hex_str(&hdlc, argv[1]); +} |