summaryrefslogtreecommitdiff
path: root/gsm-tvoid
diff options
context:
space:
mode:
authorHarald Welte <laforge@gnumonks.org>2008-11-29 13:48:12 +0530
committerHarald Welte <laforge@gnumonks.org>2008-11-29 13:48:12 +0530
commit51eaba28a3d4c83ecee4ca98544635d47c771380 (patch)
tree3a37b409011eebf1596d1561615699734d7dee6c /gsm-tvoid
parentfc65a393a6816b4f2fee25a299f0355e8667b0f4 (diff)
[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)
Diffstat (limited to 'gsm-tvoid')
-rw-r--r--gsm-tvoid/src/lib/gsmstack.c96
-rw-r--r--gsm-tvoid/src/lib/gsmstack.h12
-rw-r--r--gsm-tvoid/src/lib/gsmtap.h23
-rw-r--r--gsm-tvoid/src/lib/out_pcap.c14
-rw-r--r--gsm-tvoid/src/lib/out_pcap.h4
5 files changed, 110 insertions, 39 deletions
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 <linux/if_ether.h>
#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 <sys/types.h>
-#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
personal git repositories of Harald Welte. Your mileage may vary