summaryrefslogtreecommitdiff
path: root/gsm-receiver/src/lib/decoder
diff options
context:
space:
mode:
Diffstat (limited to 'gsm-receiver/src/lib/decoder')
-rw-r--r--gsm-receiver/src/lib/decoder/Makefile.am2
-rw-r--r--gsm-receiver/src/lib/decoder/gsmstack.c61
-rw-r--r--gsm-receiver/src/lib/decoder/gsmstack.h3
-rw-r--r--gsm-receiver/src/lib/decoder/gsmtap.h59
-rw-r--r--gsm-receiver/src/lib/decoder/out_pcap.c111
5 files changed, 86 insertions, 150 deletions
diff --git a/gsm-receiver/src/lib/decoder/Makefile.am b/gsm-receiver/src/lib/decoder/Makefile.am
index 1726d68..2fcadbb 100644
--- a/gsm-receiver/src/lib/decoder/Makefile.am
+++ b/gsm-receiver/src/lib/decoder/Makefile.am
@@ -36,7 +36,6 @@ libdecoder_la_SOURCES = \
fire_crc.c \
gsmstack.c \
interleave.c \
- out_pcap.c \
tun.c
# tch.c \
# conv.c
@@ -47,7 +46,6 @@ noinst_HEADERS = \
fire_crc.h \
gsmstack.h \
interleave.h \
- out_pcap.h \
tun.h \
system.h \
gsmtap.h \
diff --git a/gsm-receiver/src/lib/decoder/gsmstack.c b/gsm-receiver/src/lib/decoder/gsmstack.c
index c3f1921..6c91395 100644
--- a/gsm-receiver/src/lib/decoder/gsmstack.c
+++ b/gsm-receiver/src/lib/decoder/gsmstack.c
@@ -6,6 +6,7 @@
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
+#include <unistd.h>
#include <string.h>
#include "gsmstack.h"
//#include "gsm_constants.h"
@@ -13,9 +14,16 @@
//#include "sch.h"
#include "cch.h"
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+
+#include <osmocore/msgb.h>
+#include <osmocore/gsmtap.h>
+#include <osmocore/gsmtap_util.h>
+
static const int USEFUL_BITS = 142;
-//#include "out_pcap.h"
enum BURST_TYPE {
UNKNOWN,
FCCH,
@@ -79,22 +87,31 @@ diff_decode(char *dst, char *src, int len)
int
GS_new(GS_CTX *ctx)
{
+ int rc;
+ struct sockaddr_in sin;
+
+ sin.sin_family = AF_INET;
+ sin.sin_port = htons(GSMTAP_UDP_PORT);
+ inet_aton("127.0.0.1", &sin.sin_addr);
+
memset(ctx, 0, sizeof *ctx);
interleave_init(&ctx->interleave_ctx, 456, 114);
ctx->fn = -1;
ctx->bsic = -1;
+ ctx->gsmtap_fd = -1;
- ctx->tun_fd = mktun("gsm", ctx->ether_addr);
- if (ctx->tun_fd < 0)
- fprintf(stderr, "cannot open 'gsm' tun device, did you create it?\n");
-
- ctx->pcap_fd = open_pcap_file("gsm-receiver.pcap");
- if (ctx->pcap_fd < 0)
- fprintf(stderr, "cannot open PCAP file: %s\n", strerror(errno));
-
- ctx->burst_pcap_fd = open_pcap_file("gsm-receiver-burst.pcap");
- if (ctx->burst_pcap_fd < 0)
- fprintf(stderr, "cannot open burst PCAP file: %s\n", strerror(errno));
+ rc = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
+ if (rc < 0) {
+ perror("creating UDP socket\n");
+ return rc;
+ }
+ ctx->gsmtap_fd = rc;
+ rc = connect(rc, (struct sockaddr *)&sin, sizeof(sin));
+ if (rc < 0) {
+ perror("connectiong UDP socket");
+ close(ctx->gsmtap_fd);
+ return rc;
+ }
return 0;
}
@@ -112,15 +129,9 @@ GS_process(GS_CTX *ctx, int ts, int type, const unsigned char *src, int fn)
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 */
@@ -177,9 +188,17 @@ GS_process(GS_CTX *ctx, int ts, int type, const unsigned char *src, int fn)
//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,
- 0, NORMAL, data, len);
+
+ if (ctx->gsmtap_fd >= 0) {
+ struct msgb *msg;
+ /* arfcn, ts, chan_type, ss, fn, signal, snr, data, len */
+ msg = gsmtap_makemsg(0, ts, GSMTAP_CHANNEL_BCCH, 0,
+ ctx->fn-4, 0, 0, data, len);
+ if (msg)
+ write(ctx->gsmtap_fd, msg->data,
+ msg->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-receiver/src/lib/decoder/gsmstack.h b/gsm-receiver/src/lib/decoder/gsmstack.h
index 9355785..d02440c 100644
--- a/gsm-receiver/src/lib/decoder/gsmstack.h
+++ b/gsm-receiver/src/lib/decoder/gsmstack.h
@@ -29,8 +29,7 @@ typedef struct
int tun_fd;
unsigned char ether_addr[ETH_ALEN];
- int pcap_fd;
- int burst_pcap_fd;
+ int gsmtap_fd;
} GS_CTX;
int GS_new(GS_CTX *ctx);
diff --git a/gsm-receiver/src/lib/decoder/gsmtap.h b/gsm-receiver/src/lib/decoder/gsmtap.h
index 1022194..dcd64bd 100644
--- a/gsm-receiver/src/lib/decoder/gsmtap.h
+++ b/gsm-receiver/src/lib/decoder/gsmtap.h
@@ -1,11 +1,20 @@
#ifndef _GSMTAP_H
#define _GSMTAP_H
-/* gsmtap header, pseudo-header in front of the actua GSM payload*/
+/* gsmtap header, pseudo-header in front of the actua GSM payload */
-#include <sys/types.h>
+/* GSMTAP is a generic header format for GSM protocol captures,
+ * it uses the IANA-assigned UDP port number 4729 and carries
+ * payload in various formats of GSM interfaces such as Um MAC
+ * blocks or Um bursts.
+ *
+ * Example programs generating GSMTAP data are airprobe
+ * (http://airprobe.org/) or OsmocomBB (http://bb.osmocom.org/)
+ */
-#define GSMTAP_VERSION 0x01
+#include <stdint.h>
+
+#define GSMTAP_VERSION 0x02
#define GSMTAP_TYPE_UM 0x01
#define GSMTAP_TYPE_ABIS 0x02
@@ -20,22 +29,44 @@
#define GSMTAP_BURST_NORMAL 0x06
#define GSMTAP_BURST_DUMMY 0x07
#define GSMTAP_BURST_ACCESS 0x08
+#define GSMTAP_BURST_NONE 0x09
+
+#define GSMTAP_CHANNEL_UNKNOWN 0x00
+#define GSMTAP_CHANNEL_BCCH 0x01
+#define GSMTAP_CHANNEL_CCCH 0x02
+#define GSMTAP_CHANNEL_RACH 0x03
+#define GSMTAP_CHANNEL_AGCH 0x04
+#define GSMTAP_CHANNEL_PCH 0x05
+#define GSMTAP_CHANNEL_SDCCH 0x06
+#define GSMTAP_CHANNEL_SDCCH4 0x07
+#define GSMTAP_CHANNEL_SDCCH8 0x08
+#define GSMTAP_CHANNEL_TCH_F 0x09
+#define GSMTAP_CHANNEL_TCH_H 0x0a
+#define GSMTAP_CHANNEL_ACCH 0x80
+
+#define GSMTAP_ARFCN_F_PCS 0x8000
+#define GSMTAP_ARFCN_F_UPLINK 0x4000
+#define GSMTAP_ARFCN_MASK 0x3fff
+
+#define GSMTAP_UDP_PORT 4729
struct gsmtap_hdr {
- u_int8_t version; /* version, set to 0x01 currently */
- u_int8_t hdr_len; /* length in number of 32bit words */
- u_int8_t type; /* see GSMTAP_TYPE_* */
- u_int8_t timeslot; /* timeslot (0..7 on Um) */
+ uint8_t version; /* version, set to 0x01 currently */
+ uint8_t hdr_len; /* length in number of 32bit words */
+ uint8_t type; /* see GSMTAP_TYPE_* */
+ uint8_t timeslot; /* timeslot (0..7 on Um) */
- u_int16_t arfcn; /* ARFCN (frequency) */
- u_int8_t noise_db; /* noise figure in dB */
- u_int8_t signal_db; /* signal level in dB */
+ uint16_t arfcn; /* ARFCN (frequency) */
+ int8_t signal_dbm; /* signal level in dBm */
+ int8_t snr_db; /* signal/noise ratio in dB */
- u_int32_t frame_number; /* GSM Frame Number (FN) */
+ uint32_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) */
+ uint8_t sub_type; /* Type of burst/channel, see above */
+ uint8_t antenna_nr; /* Antenna Number */
+ uint8_t sub_slot; /* sub-slot within timeslot */
+ uint8_t res; /* reserved for future use (RFU) */
} __attribute__((packed));
+
#endif /* _GSMTAP_H */
diff --git a/gsm-receiver/src/lib/decoder/out_pcap.c b/gsm-receiver/src/lib/decoder/out_pcap.c
deleted file mode 100644
index 4da5fd6..0000000
--- a/gsm-receiver/src/lib/decoder/out_pcap.c
+++ /dev/null
@@ -1,111 +0,0 @@
-/* PCAP support for gsm-tvoid
- * (C) 2008 by Harald Welte <laforge@gnumonks.org>
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <fcntl.h>
-#include <pcap.h>
-#include <errno.h>
-#include <time.h>
-
-#include "out_pcap.h"
-#include "gsmtap.h"
-
-#ifndef LINKTYPE_GSMTAP
-#define LINKTYPE_GSMTAP 2342
-#endif
-
-#define TCPDUMP_MAGIC 0xa1b2c3d4
-
-struct pcap_timeval {
- int32_t tv_sec;
- int32_t tv_usec;
-};
-
-struct pcap_sf_pkthdr {
- struct pcap_timeval ts; /* time stamp */
- u_int32_t caplen; /* lenght of portion present */
- u_int32_t len; /* length of this packet */
-};
-
-static int write_pcap_file_header(int fd)
-{
- struct pcap_file_header pfh;
-
- pfh.magic = TCPDUMP_MAGIC;
- pfh.version_major = PCAP_VERSION_MAJOR;
- pfh.version_minor = PCAP_VERSION_MINOR;
- pfh.thiszone = timezone;
- pfh.sigfigs = 0;
- pfh.snaplen = 1024; /* FIXME */
- pfh.linktype = LINKTYPE_GSMTAP;
-
- if (write(fd, &pfh, sizeof(pfh)) < sizeof(pfh))
- return -1;
-
- return 0;
-}
-
-/* open pcap file and write header */
-int open_pcap_file(char *fname)
-{
- int fd;
- int rc;
-
- fd = open(fname, O_WRONLY|O_CREAT|O_TRUNC, 0660);
- if (fd < 0)
- return fd;
-
- rc = write_pcap_file_header(fd);
- if (rc < 0) {
- close(fd);
- fd = -EIO;
- }
-
- return fd;
-}
-
-int write_pcap_packet(int fd, int arfcn, int ts, int fn,
- int burst, int burst_type,
- const unsigned char *data, unsigned int len)
-{
- unsigned char buf[8192];
- struct pcap_sf_pkthdr *ph;
- struct gsmtap_hdr *gh;
- struct timeval tv;
- int rc;
-
- if (fd < 0)
- return -EINVAL;
-
- ph = (struct pcap_sf_pkthdr *) &buf[0];
- gh = (struct gsmtap_hdr *) &buf[sizeof(struct pcap_sf_pkthdr)];
-
- gettimeofday(&tv, NULL);
-
- ph->ts.tv_sec = tv.tv_sec;
- ph->ts.tv_usec = tv.tv_usec;
- ph->caplen = ph->len = len + sizeof(struct gsmtap_hdr);
-
- gh->version = GSMTAP_VERSION;
- gh->hdr_len = sizeof(struct gsmtap_hdr)>>2;
- 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);
-
- return rc;
-}
personal git repositories of Harald Welte. Your mileage may vary