From 51eaba28a3d4c83ecee4ca98544635d47c771380 Mon Sep 17 00:00:00 2001 From: Harald Welte Date: Sat, 29 Nov 2008 13:48:12 +0530 Subject: [gsm-tvoid] new gsmtap header, raw burst pcap support * split burst decoding context out of GS_ctx and have one for each TS * add PCAP output for GSMTAP_TYPE_UM_BURST (142 bit burst per packet) --- gsm-tvoid/src/lib/gsmstack.c | 96 +++++++++++++++++++++++++++++++------------- gsm-tvoid/src/lib/gsmstack.h | 12 ++++-- gsm-tvoid/src/lib/gsmtap.h | 23 +++++++++-- gsm-tvoid/src/lib/out_pcap.c | 14 +++++-- gsm-tvoid/src/lib/out_pcap.h | 4 +- 5 files changed, 110 insertions(+), 39 deletions(-) (limited to 'gsm-tvoid/src/lib') diff --git a/gsm-tvoid/src/lib/gsmstack.c b/gsm-tvoid/src/lib/gsmstack.c index c0f422e..a46bc87 100644 --- a/gsm-tvoid/src/lib/gsmstack.c +++ b/gsm-tvoid/src/lib/gsmstack.c @@ -17,6 +17,28 @@ static void out_gsmdecode(char type, int arfcn, int ts, int fn, char *data, int len); +/* encode a decoded burst (1 bit per byte) into 8-bit-per-byte */ +static void burst_octify(unsigned char *dest, + const unsigned char *data, int length) +{ + int bitpos = 0; + + while (bitpos < USEFUL_BITS) { + unsigned char tbyte; + int i; + + tbyte = 0; + for (i = 0; (i < 8) && (bitpos < length); i++) { + tbyte <<= 1; + tbyte |= data[bitpos++]; + } + if (i < 8) + tbyte <<= 8 - i; + *dest++ = tbyte; + } +} + + #if 0 static void diff_decode(char *dst, char *src, int len) @@ -58,9 +80,14 @@ GS_new(GS_CTX *ctx) if (ctx->pcap_fd < 0) fprintf(stderr, "cannot open PCAP file: %s\n", strerror(errno)); + ctx->burst_pcap_fd = open_pcap_file("tvoid-burst.pcap"); + if (ctx->burst_pcap_fd < 0) + fprintf(stderr, "cannot open burst PCAP file: %s\n", strerror(errno)); + return 0; } +#define BURST_BYTES ((USEFUL_BITS/8)+1) /* * 142 bit */ @@ -72,7 +99,17 @@ GS_process(GS_CTX *ctx, int ts, int type, const unsigned char *src) int ret; unsigned char *data; int len; + struct gs_ts_ctx *ts_ctx = &ctx->ts_ctx[ts]; + unsigned char octified[BURST_BYTES]; + memset(ctx->msg, 0, sizeof(ctx->msg)); + + /* write burst to burst PCAP file */ + burst_octify(octified, src, USEFUL_BITS); + write_pcap_packet(ctx->burst_pcap_fd, 0 /* arfcn */, ts, ctx->fn, + 1, type, octified, BURST_BYTES); + +#if 0 if (ts != 0) { /* non-0 timeslots should end up in PCAP */ data = decode_cch(ctx, ctx->burst, &len); @@ -81,51 +118,56 @@ GS_process(GS_CTX *ctx, int ts, int type, const unsigned char *src) write_pcap_packet(ctx->pcap_fd, 0 /* arfcn */, ts, ctx->fn, data, len); return; } +#endif - if (type == SCH) - { - ret = decode_sch(src, &fn, &bsic); - if (ret != 0) + if (ts == 0) { + if (type == SCH) { + ret = decode_sch(src, &fn, &bsic); + if (ret != 0) + return 0; + if ((ctx->bsic > 0) && (bsic != ctx->bsic)) + fprintf(stderr, "WARN: BSIC changed.\n"); + //DEBUGF("FN %d, BSIC %d\n", fn, bsic); + ctx->fn = fn; + ctx->bsic = bsic; + /* Reset message concatenator */ + ts_ctx->burst_count = 0; return 0; - if ((ctx->bsic > 0) && (bsic != ctx->bsic)) - fprintf(stderr, "WARN: BSIC changed.\n"); - //DEBUGF("FN %d, BSIC %d\n", fn, bsic); - ctx->fn = fn; - ctx->bsic = bsic; - /* Reset message concatenator */ - ctx->burst_count = 0; - return 0; - } + } - /* If we did not get Frame Number yet then return */ - if (ctx->fn < 0) - return 0; + /* If we did not get Frame Number yet then return */ + if (ctx->fn < 0) + return 0; - ctx->fn++; - if (type == NORMAL) - { + ctx->fn++; + } + + if (type == NORMAL) { /* Interested in these frame numbers (cch) * 2-5, 12-15, 22-25, 23-35, 42-45 * 6-9, 16-19, 26-29, 36-39, 46-49 */ /* Copy content data into new array */ //DEBUGF("burst count %d\n", ctx->burst_count); - memcpy(ctx->burst + (116 * ctx->burst_count), src, 58); - memcpy(ctx->burst + (116 * ctx->burst_count) + 58, src + 58 + 26, 58); - ctx->burst_count++; + memcpy(ts_ctx->burst + (116 * ts_ctx->burst_count), src, 58); + memcpy(ts_ctx->burst + (116 * ts_ctx->burst_count) + 58, src + 58 + 26, 58); + ts_ctx->burst_count++; /* Return if not enough bursts for a full gsm message */ - if (ctx->burst_count < 4) + if (ts_ctx->burst_count < 4) return 0; - ctx->burst_count = 0; - data = decode_cch(ctx, ctx->burst, &len); - if (data == NULL) + ts_ctx->burst_count = 0; + data = decode_cch(ctx, ts_ctx->burst, &len); + if (data == NULL) { + DEBUGF("cannot decode fnr=0x%08x ts=%d\n", ctx->fn, ts); return -1; + } //DEBUGF("OK TS %d, len %d\n", ts, len); out_gsmdecode(0, 0, ts, ctx->fn - 4, data, len); write_interface(ctx->tun_fd, data+1, len-1, ctx->ether_addr); - write_pcap_packet(ctx->pcap_fd, 0 /* arfcn */, ts, ctx->fn, data, len); + write_pcap_packet(ctx->pcap_fd, 0 /* arfcn */, ts, ctx->fn, + 0, NORMAL, data, len); #if 0 if (ctx->fn % 51 != 0) && ( (((ctx->fn % 51 + 5) % 10 == 0) || (((ctx->fn % 51) + 1) % 10 ==0) ) ) ready = 1; diff --git a/gsm-tvoid/src/lib/gsmstack.h b/gsm-tvoid/src/lib/gsmstack.h index b4a5c96..a9da102 100644 --- a/gsm-tvoid/src/lib/gsmstack.h +++ b/gsm-tvoid/src/lib/gsmstack.h @@ -9,22 +9,28 @@ extern "C" { #include #include "interleave.h" +struct gs_ts_ctx { + /* FIXME: later do this per each ts per each arfcn */ + unsigned char burst[4 * 58 * 2]; + int burst_count; +}; + typedef struct { int flags; int fn; int bsic; char msg[23]; /* last decoded message */ + INTERLEAVE_CTX interleave_ctx; - /* FIXME: later do this per each ts per each arfcn */ - unsigned char burst[4 * 58 * 2]; - int burst_count; + struct gs_ts_ctx ts_ctx[8]; int tun_fd; unsigned char ether_addr[ETH_ALEN]; int pcap_fd; + int burst_pcap_fd; } GS_CTX; int GS_new(GS_CTX *ctx); diff --git a/gsm-tvoid/src/lib/gsmtap.h b/gsm-tvoid/src/lib/gsmtap.h index 6676d9a..1022194 100644 --- a/gsm-tvoid/src/lib/gsmtap.h +++ b/gsm-tvoid/src/lib/gsmtap.h @@ -5,10 +5,21 @@ #include -#define GSMTAP_VERSION 0x02 +#define GSMTAP_VERSION 0x01 #define GSMTAP_TYPE_UM 0x01 #define GSMTAP_TYPE_ABIS 0x02 +#define GSMTAP_TYPE_UM_BURST 0x03 /* raw burst bits */ + +#define GSMTAP_BURST_UNKNOWN 0x00 +#define GSMTAP_BURST_FCCH 0x01 +#define GSMTAP_BURST_PARTIAL_SCH 0x02 +#define GSMTAP_BURST_SCH 0x03 +#define GSMTAP_BURST_CTS_SCH 0x04 +#define GSMTAP_BURST_COMPACT_SCH 0x05 +#define GSMTAP_BURST_NORMAL 0x06 +#define GSMTAP_BURST_DUMMY 0x07 +#define GSMTAP_BURST_ACCESS 0x08 struct gsmtap_hdr { u_int8_t version; /* version, set to 0x01 currently */ @@ -17,10 +28,14 @@ struct gsmtap_hdr { u_int8_t timeslot; /* timeslot (0..7 on Um) */ u_int16_t arfcn; /* ARFCN (frequency) */ - u_int8_t noise_db; - u_int8_t signal_db; + u_int8_t noise_db; /* noise figure in dB */ + u_int8_t signal_db; /* signal level in dB */ - u_int32_t frame_number; + u_int32_t frame_number; /* GSM Frame Number (FN) */ + + u_int8_t burst_type; /* Type of burst, see above */ + u_int8_t antenna_nr; /* Antenna Number */ + u_int16_t res; /* reserved for future use (RFU) */ } __attribute__((packed)); #endif /* _GSMTAP_H */ diff --git a/gsm-tvoid/src/lib/out_pcap.c b/gsm-tvoid/src/lib/out_pcap.c index 95f24f5..4da5fd6 100644 --- a/gsm-tvoid/src/lib/out_pcap.c +++ b/gsm-tvoid/src/lib/out_pcap.c @@ -67,7 +67,8 @@ int open_pcap_file(char *fname) } int write_pcap_packet(int fd, int arfcn, int ts, int fn, - char *data, unsigned int len) + int burst, int burst_type, + const unsigned char *data, unsigned int len) { unsigned char buf[8192]; struct pcap_sf_pkthdr *ph; @@ -75,7 +76,8 @@ int write_pcap_packet(int fd, int arfcn, int ts, int fn, struct timeval tv; int rc; - printf("writing pcap packet fd=%d len=%d\n", fd, len); + if (fd < 0) + return -EINVAL; ph = (struct pcap_sf_pkthdr *) &buf[0]; gh = (struct gsmtap_hdr *) &buf[sizeof(struct pcap_sf_pkthdr)]; @@ -88,18 +90,22 @@ int write_pcap_packet(int fd, int arfcn, int ts, int fn, gh->version = GSMTAP_VERSION; gh->hdr_len = sizeof(struct gsmtap_hdr)>>2; - gh->type = GSMTAP_TYPE_UM; + if (burst) + gh->type = GSMTAP_TYPE_UM_BURST; + else + gh->type = GSMTAP_TYPE_UM; gh->timeslot = ts; gh->arfcn = htons(arfcn); /* we don't support signal/noise yet */ gh->noise_db = gh->signal_db = 0; gh->frame_number = htonl(fn); + gh->burst_type = burst_type & 0xff; memcpy(buf + sizeof(*ph) + sizeof(*gh), data, len); rc = write(fd, buf, sizeof(*ph) + sizeof(*gh) + len); - fsync(fd); + //fsync(fd); return rc; } diff --git a/gsm-tvoid/src/lib/out_pcap.h b/gsm-tvoid/src/lib/out_pcap.h index e8d4b3c..5ae5e3c 100644 --- a/gsm-tvoid/src/lib/out_pcap.h +++ b/gsm-tvoid/src/lib/out_pcap.h @@ -2,6 +2,8 @@ #define _PCAP_IF_H extern int open_pcap_file(char *fname); -int write_pcap_packet(int fd, int arfcn, int ts, int fn, char *data, unsigned int len); +int write_pcap_packet(int fd, int arfcn, int ts, int fn, + int burst, int burst_type, + const unsigned char *data, unsigned int len); #endif -- cgit v1.2.3