From 525af1832e92864258c190c5145c2faf8e0f5dd9 Mon Sep 17 00:00:00 2001 From: Harald Welte Date: Wed, 19 Oct 2016 00:38:46 +0200 Subject: e1cap_dump: Add 16k sub-channel demux + filter We can now filter a given 16k sub-slot out of the capture data and export it to stdout. --- src/e1cap_dump.c | 66 +++++++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 51 insertions(+), 15 deletions(-) diff --git a/src/e1cap_dump.c b/src/e1cap_dump.c index b732449..48741f4 100644 --- a/src/e1cap_dump.c +++ b/src/e1cap_dump.c @@ -7,6 +7,7 @@ #include #include #include +#include #include "storage.h" #include "recorder.h" @@ -21,6 +22,8 @@ enum mode { static enum mode g_mode = MODE_PRINT; static int g_filter_line = -1; static int g_filter_slot = -1; +static int g_filter_subslot = -1; +static struct osmo_e1cap_pkthdr *g_last_pkthdr; static char *timeval2str(struct timeval *tv) { @@ -36,21 +39,51 @@ static char *timeval2str(struct timeval *tv) return buf; } +static void handle_data(struct osmo_e1cap_pkthdr *pkt, const uint8_t *data, int len) +{ + switch (g_mode) { + case MODE_PRINT: + printf("%s %02u/%02u %u (%u): %s\n", + timeval2str(&pkt->ts), + pkt->line_nr, pkt->ts_nr, pkt->capture_mode, + pkt->len, + osmo_hexdump_nospc(data, len)); + break; + case MODE_BIN: + write(1, data, len); + break; + } +} + +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; +} + static int handle_options(int argc, char **argv) { int opt; - while ((opt = getopt(argc, argv, "l:s:b")) != -1) { + while ((opt = getopt(argc, argv, "l:s:bu:")) != -1) { switch (opt) { - case 'l': + case 'l': /* Filter on E1 Line Number */ g_filter_line = atoi(optarg); break; - case 's': + case 's': /* Filter on E1 Slot Number */ g_filter_slot = atoi(optarg); break; - case 'b': + case 'b': /* Raw binary output mode (for piping) */ g_mode = MODE_BIN; break; + case 'u': /* 16k Sub-channel demux + filter */ + g_filter_subslot = atoi(optarg); + if (g_filter_subslot < 0 || g_filter_subslot > 3) + exit(2); + break; default: fprintf(stderr, "Unknown option '%c'\n", opt); exit(EXIT_FAILURE); @@ -66,6 +99,7 @@ int main(int argc, char **argv) struct osmo_e1cap_file *f; struct osmo_e1cap_pkthdr *pkt; unsigned long num_pkt = 0; + struct subch_demux smux; printf("sizeof(timeval) = %zu\n", sizeof(struct timeval)); printf("sizeof(osmo_e1cap_pkthdr) = %zu\n", sizeof(*pkt)); @@ -83,26 +117,28 @@ int main(int argc, char **argv) exit(1); } + if (g_filter_subslot >= 0) { + smux.out_cb = subch_demux_out_cb; + subch_demux_init(&smux); + subch_demux_activate(&smux, g_filter_subslot); + } + while ((pkt = osmo_e1cap_read_next(f))) { num_pkt++; + g_last_pkthdr = pkt; if (g_filter_line >= 0 && pkt->line_nr != g_filter_line) continue; if (g_filter_slot >= 0 && pkt->ts_nr != g_filter_slot) continue; - switch (g_mode) { - case MODE_PRINT: - printf("%s %02u/%02u %u (%u): %s\n", - timeval2str(&pkt->ts), - pkt->line_nr, pkt->ts_nr, pkt->capture_mode, - pkt->len, - osmo_hexdump_nospc(pkt->data, pkt->len)); - break; - case MODE_BIN: - write(1, pkt->data, pkt->len); - break; + if (g_filter_subslot >= 0) { + subch_demux_in(&smux, pkt->data, pkt->len); + continue; } + + handle_data(pkt, pkt->data, pkt->len); + talloc_free(pkt); } -- cgit v1.2.3