aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHarald Welte <laforge@gnumonks.org>2016-10-19 00:38:46 +0200
committerHarald Welte <laforge@gnumonks.org>2016-10-19 00:38:46 +0200
commit525af1832e92864258c190c5145c2faf8e0f5dd9 (patch)
treefa7dd302eea4e89fbafe028dc34914bddf7b308d
parentf403232e0fbc8e9b04671bbcec62bc15ccd2ea30 (diff)
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.
-rw-r--r--src/e1cap_dump.c66
1 files 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 <osmocom/core/signal.h>
#include <osmocom/core/logging.h>
#include <osmocom/core/application.h>
+#include <osmocom/abis/subchan_demux.h>
#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);
}