summaryrefslogtreecommitdiffstats
path: root/include/osmocom/core
diff options
context:
space:
mode:
Diffstat (limited to 'include/osmocom/core')
-rw-r--r--include/osmocom/core/Makefile.am31
-rw-r--r--include/osmocom/core/application.h23
-rw-r--r--include/osmocom/core/backtrace.h6
-rw-r--r--include/osmocom/core/bits.h78
-rw-r--r--include/osmocom/core/bitvec.h70
-rw-r--r--include/osmocom/core/conv.h146
-rw-r--r--include/osmocom/core/crc16.h34
-rw-r--r--include/osmocom/core/crcXXgen.h.tpl59
-rw-r--r--include/osmocom/core/crcgen.h41
-rw-r--r--include/osmocom/core/gsmtap.h159
-rw-r--r--include/osmocom/core/gsmtap_util.h57
-rw-r--r--include/osmocom/core/linuxlist.h360
-rw-r--r--include/osmocom/core/linuxrbtree.h160
-rw-r--r--include/osmocom/core/logging.h211
-rw-r--r--include/osmocom/core/msgb.h370
-rw-r--r--include/osmocom/core/msgfile.h49
-rw-r--r--include/osmocom/core/panic.h20
-rw-r--r--include/osmocom/core/plugin.h6
-rw-r--r--include/osmocom/core/prim.h58
-rw-r--r--include/osmocom/core/process.h2
-rw-r--r--include/osmocom/core/rate_ctr.h88
-rw-r--r--include/osmocom/core/select.h45
-rw-r--r--include/osmocom/core/serial.h43
-rw-r--r--include/osmocom/core/signal.h46
-rw-r--r--include/osmocom/core/socket.h35
-rw-r--r--include/osmocom/core/statistics.h53
-rw-r--r--include/osmocom/core/talloc.h192
-rw-r--r--include/osmocom/core/timer.h87
-rw-r--r--include/osmocom/core/timer_compat.h79
-rw-r--r--include/osmocom/core/utils.h56
-rw-r--r--include/osmocom/core/write_queue.h63
31 files changed, 2727 insertions, 0 deletions
diff --git a/include/osmocom/core/Makefile.am b/include/osmocom/core/Makefile.am
new file mode 100644
index 00000000..1df111af
--- /dev/null
+++ b/include/osmocom/core/Makefile.am
@@ -0,0 +1,31 @@
+osmocore_HEADERS = signal.h linuxlist.h timer.h select.h msgb.h bits.h \
+ bitvec.h statistics.h utils.h socket.h \
+ gsmtap.h write_queue.h prim.h \
+ logging.h rate_ctr.h gsmtap_util.h \
+ crc16.h panic.h process.h linuxrbtree.h \
+ backtrace.h conv.h application.h \
+ crcgen.h crc8gen.h crc16gen.h crc32gen.h crc64gen.h
+
+noinst_HEADERS = timer_compat.h
+
+if ENABLE_PLUGIN
+osmocore_HEADERS += plugin.h
+endif
+
+if ENABLE_TALLOC
+osmocore_HEADERS += talloc.h
+endif
+
+if ENABLE_MSGFILE
+osmocore_HEADERS += msgfile.h
+endif
+
+if ENABLE_SERIAL
+osmocore_HEADERS += serial.h
+endif
+
+osmocoredir = $(includedir)/osmocom/core
+
+crc%gen.h: crcXXgen.h.tpl
+ @echo " SED $< -> $@"
+ @sed -e's/XX/$*/g' $< > $@
diff --git a/include/osmocom/core/application.h b/include/osmocom/core/application.h
new file mode 100644
index 00000000..34571698
--- /dev/null
+++ b/include/osmocom/core/application.h
@@ -0,0 +1,23 @@
+#ifndef OSMO_APPLICATION_H
+#define OSMO_APPLICATION_H
+
+/*!
+ * \file application.h
+ * \brief Routines for helping with the osmocom application setup.
+ */
+
+/*! \brief information containing the available logging subsystems */
+struct log_info;
+
+/*! \brief one instance of a logging target (file, stderr, ...) */
+struct log_target;
+
+/*! \brief the default logging target, logging to stderr */
+extern struct log_target *osmo_stderr_target;
+
+void osmo_init_ignore_signals(void);
+int osmo_init_logging(const struct log_info *);
+
+int osmo_daemonize(void);
+
+#endif
diff --git a/include/osmocom/core/backtrace.h b/include/osmocom/core/backtrace.h
new file mode 100644
index 00000000..1ed089ad
--- /dev/null
+++ b/include/osmocom/core/backtrace.h
@@ -0,0 +1,6 @@
+#ifndef _OSMO_BACKTRACE_H_
+#define _OSMO_BACKTRACE_H_
+
+void osmo_generate_backtrace(void);
+
+#endif
diff --git a/include/osmocom/core/bits.h b/include/osmocom/core/bits.h
new file mode 100644
index 00000000..4c685321
--- /dev/null
+++ b/include/osmocom/core/bits.h
@@ -0,0 +1,78 @@
+#ifndef _OSMO_BITS_H
+#define _OSMO_BITS_H
+
+#include <stdint.h>
+
+/*! \defgroup bits soft, unpacked and packed bits
+ * @{
+ */
+
+/*! \file bits.h
+ * \brief Osmocom bit level support code
+ */
+
+typedef int8_t sbit_t; /*!< \brief soft bit (-127...127) */
+typedef uint8_t ubit_t; /*!< \brief unpacked bit (0 or 1) */
+typedef uint8_t pbit_t; /*!< \brief packed bis (8 bits in a byte) */
+
+/*
+ NOTE on the endianess of pbit_t:
+ Bits in a pbit_t are ordered MSB first, i.e. 0x80 is the first bit.
+ Bit i in a pbit_t array is array[i/8] & (1<<(7-i%8))
+*/
+
+/*! \brief determine how many bytes we would need for \a num_bits packed bits
+ * \param[in] num_bits Number of packed bits
+ */
+static inline unsigned int osmo_pbit_bytesize(unsigned int num_bits)
+{
+ unsigned int pbit_bytesize = num_bits / 8;
+
+ if (num_bits % 8)
+ pbit_bytesize++;
+
+ return pbit_bytesize;
+}
+
+int osmo_ubit2pbit(pbit_t *out, const ubit_t *in, unsigned int num_bits);
+
+int osmo_pbit2ubit(ubit_t *out, const pbit_t *in, unsigned int num_bits);
+
+int osmo_ubit2pbit_ext(pbit_t *out, unsigned int out_ofs,
+ const ubit_t *in, unsigned int in_ofs,
+ unsigned int num_bits, int lsb_mode);
+
+int osmo_pbit2ubit_ext(ubit_t *out, unsigned int out_ofs,
+ const pbit_t *in, unsigned int in_ofs,
+ unsigned int num_bits, int lsb_mode);
+
+
+/* BIT REVERSAL */
+
+/*! \brief bit-reversal mode for osmo_bit_reversal() */
+enum osmo_br_mode {
+ /*! \brief reverse all bits in a 32bit dword */
+ OSMO_BR_BITS_IN_DWORD = 31,
+ /*! \brief reverse byte order in a 32bit dword */
+ OSMO_BR_BYTES_IN_DWORD = 24,
+ /*! \brief reverse bits of each byte in a 32bit dword */
+ OSMO_BR_BITS_IN_BYTE = 7,
+ /*! \brief swap the two 16bit words in a 32bit dword */
+ OSMO_BR_WORD_SWAP = 16,
+};
+
+/*! \brief generic bit reversal function */
+uint32_t osmo_bit_reversal(uint32_t x, enum osmo_br_mode k);
+
+/* \brief reverse the bits within each byte of a 32bit word */
+uint32_t osmo_revbytebits_32(uint32_t x);
+
+/* \brief reverse the bits within a byte */
+uint32_t osmo_revbytebits_8(uint8_t x);
+
+/* \brief reverse the bits of each byte in a given buffer */
+void osmo_revbytebits_buf(uint8_t *buf, int len);
+
+/*! @} */
+
+#endif /* _OSMO_BITS_H */
diff --git a/include/osmocom/core/bitvec.h b/include/osmocom/core/bitvec.h
new file mode 100644
index 00000000..9c000d02
--- /dev/null
+++ b/include/osmocom/core/bitvec.h
@@ -0,0 +1,70 @@
+#ifndef _BITVEC_H
+#define _BITVEC_H
+
+/* bit vector utility routines */
+
+/* (C) 2009 by Harald Welte <laforge@gnumonks.org>
+ *
+ * All Rights Reserved
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ */
+
+/*! \defgroup bitvec Bit vectors
+ * @{
+ */
+
+/*! \file bitvec.h
+ * \brief Osmocom bit vector abstraction
+ */
+
+#include <stdint.h>
+
+/*! \brief A single GSM bit
+ *
+ * In GSM mac blocks, every bit can be 0 or 1, or L or H. L/H are
+ * defined relative to the 0x2b padding pattern */
+enum bit_value {
+ ZERO = 0, /*!< \brief A zero (0) bit */
+ ONE = 1, /*!< \brief A one (1) bit */
+ L = 2, /*!< \brief A CSN.1 "L" bit */
+ H = 3, /*!< \brief A CSN.1 "H" bit */
+};
+
+/*! \brief structure describing a bit vector */
+struct bitvec {
+ unsigned int cur_bit; /*!< \brief curser to the next unused bit */
+ unsigned int data_len; /*!< \brief length of data array in bytes */
+ uint8_t *data; /*!< \brief pointer to data array */
+};
+
+enum bit_value bitvec_get_bit_pos(const struct bitvec *bv, unsigned int bitnr);
+enum bit_value bitvec_get_bit_pos_high(const struct bitvec *bv,
+ unsigned int bitnr);
+unsigned int bitvec_get_nth_set_bit(const struct bitvec *bv, unsigned int n);
+int bitvec_set_bit_pos(struct bitvec *bv, unsigned int bitnum,
+ enum bit_value bit);
+int bitvec_set_bit(struct bitvec *bv, enum bit_value bit);
+int bitvec_get_bit_high(struct bitvec *bv);
+int bitvec_set_bits(struct bitvec *bv, enum bit_value *bits, int count);
+int bitvec_set_uint(struct bitvec *bv, unsigned int in, int count);
+int bitvec_get_uint(struct bitvec *bv, int num_bits);
+int bitvec_find_bit_pos(const struct bitvec *bv, unsigned int n, enum bit_value val);
+int bitvec_spare_padding(struct bitvec *bv, unsigned int up_to_bit);
+
+/*! @} */
+
+#endif /* _BITVEC_H */
diff --git a/include/osmocom/core/conv.h b/include/osmocom/core/conv.h
new file mode 100644
index 00000000..e5b2a975
--- /dev/null
+++ b/include/osmocom/core/conv.h
@@ -0,0 +1,146 @@
+/*
+ * conv.h
+ *
+ * Copyright (C) 2011 Sylvain Munaut <tnt@246tNt.com>
+ *
+ * All Rights Reserved
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+/*! \defgroup conv Convolutional encoding and decoding routines
+ * @{
+ */
+
+/*! \file conv.h
+ * \file Osmocom convolutional encoder and decoder
+ */
+
+#ifndef __OSMO_CONV_H__
+#define __OSMO_CONV_H__
+
+#include <stdint.h>
+
+#include <osmocom/core/bits.h>
+
+/*! \brief possibe termination types
+ *
+ * The termination type will determine which state the encoder/decoder
+ * can start/end with. This is mostly taken care of in the high level API
+ * call. So if you use the low level API, you must take care of making the
+ * proper calls yourself.
+ */
+enum osmo_conv_term {
+ CONV_TERM_FLUSH = 0, /*!< \brief Flush encoder state */
+ CONV_TERM_TRUNCATION, /*!< \brief Direct truncation */
+ CONV_TERM_TAIL_BITING, /*!< \brief Tail biting */
+};
+
+/*! \brief structure describing a given convolutional code
+ *
+ * The only required fields are N,K and the next_output/next_state arrays. The
+ * other can be left to default value of zero depending on what the code does.
+ * If 'len' is left at 0 then only the low level API can be used.
+ */
+struct osmo_conv_code {
+ int N; /*!< \brief Inverse of code rate */
+ int K; /*!< \brief Constraint length */
+ int len; /*!< \brief # of data bits */
+
+ enum osmo_conv_term term; /*!< \brief Termination type */
+
+ const uint8_t (*next_output)[2];/*!< \brief Next output array */
+ const uint8_t (*next_state)[2]; /*!< \brief Next state array */
+
+ const uint8_t *next_term_output;/*!< \brief Flush termination output */
+ const uint8_t *next_term_state; /*!< \brief Flush termination state */
+
+ const int *puncture; /*!< \brief Punctured bits indexes */
+};
+
+
+/* Common */
+
+int osmo_conv_get_input_length(const struct osmo_conv_code *code, int len);
+int osmo_conv_get_output_length(const struct osmo_conv_code *code, int len);
+
+
+/* Encoding */
+
+ /* Low level API */
+
+/*! \brief convolutional encoder state */
+struct osmo_conv_encoder {
+ const struct osmo_conv_code *code; /*!< \brief for which code? */
+ int i_idx; /*!< \brief Next input bit index */
+ int p_idx; /*!< \brief Current puncture index */
+ uint8_t state; /*!< \brief Current state */
+};
+
+void osmo_conv_encode_init(struct osmo_conv_encoder *encoder,
+ const struct osmo_conv_code *code);
+void osmo_conv_encode_load_state(struct osmo_conv_encoder *encoder,
+ const ubit_t *input);
+int osmo_conv_encode_raw(struct osmo_conv_encoder *encoder,
+ const ubit_t *input, ubit_t *output, int n);
+int osmo_conv_encode_flush(struct osmo_conv_encoder *encoder, ubit_t *output);
+
+ /* All-in-one */
+int osmo_conv_encode(const struct osmo_conv_code *code,
+ const ubit_t *input, ubit_t *output);
+
+
+/* Decoding */
+
+ /* Low level API */
+
+/*! \brief convolutional decoder state */
+struct osmo_conv_decoder {
+ const struct osmo_conv_code *code; /*!< \brief for which code? */
+
+ int n_states; /*!< \brief number of states */
+
+ int len; /*!< \brief Max o_idx (excl. termination) */
+
+ int o_idx; /*!< \brief output index */
+ int p_idx; /*!< \brief puncture index */
+
+ unsigned int *ae; /*!< \brief accumulated error */
+ unsigned int *ae_next; /*!< \brief next accumulated error (tmp in scan) */
+ uint8_t *state_history; /*!< \brief state history [len][n_states] */
+};
+
+void osmo_conv_decode_init(struct osmo_conv_decoder *decoder,
+ const struct osmo_conv_code *code,
+ int len, int start_state);
+void osmo_conv_decode_reset(struct osmo_conv_decoder *decoder, int start_state);
+void osmo_conv_decode_rewind(struct osmo_conv_decoder *decoder);
+void osmo_conv_decode_deinit(struct osmo_conv_decoder *decoder);
+
+int osmo_conv_decode_scan(struct osmo_conv_decoder *decoder,
+ const sbit_t *input, int n);
+int osmo_conv_decode_flush(struct osmo_conv_decoder *decoder,
+ const sbit_t *input);
+int osmo_conv_decode_get_output(struct osmo_conv_decoder *decoder,
+ ubit_t *output, int has_flush, int end_state);
+
+ /* All-in-one */
+int osmo_conv_decode(const struct osmo_conv_code *code,
+ const sbit_t *input, ubit_t *output);
+
+
+/*! @} */
+
+#endif /* __OSMO_CONV_H__ */
diff --git a/include/osmocom/core/crc16.h b/include/osmocom/core/crc16.h
new file mode 100644
index 00000000..0e524176
--- /dev/null
+++ b/include/osmocom/core/crc16.h
@@ -0,0 +1,34 @@
+/*
+ * This was copied from the linux kernel and adjusted for our types.
+ */
+/*
+ * crc16.h - CRC-16 routine
+ *
+ * Implements the standard CRC-16:
+ * Width 16
+ * Poly 0x8005 (x^16 + x^15 + x^2 + 1)
+ * Init 0
+ *
+ * Copyright (c) 2005 Ben Gardner <bgardner@wabtec.com>
+ *
+ * This source code is licensed under the GNU General Public License,
+ * Version 2. See the file COPYING for more details.
+ */
+
+#ifndef __CRC16_H
+#define __CRC16_H
+
+#include <stdint.h>
+
+#include <sys/types.h>
+
+extern uint16_t const osmo_crc16_table[256];
+
+extern uint16_t osmo_crc16(uint16_t crc, const uint8_t *buffer, size_t len);
+
+static inline uint16_t osmo_crc16_byte(uint16_t crc, const uint8_t data)
+{
+ return (crc >> 8) ^ osmo_crc16_table[(crc ^ data) & 0xff];
+}
+
+#endif /* __CRC16_H */
diff --git a/include/osmocom/core/crcXXgen.h.tpl b/include/osmocom/core/crcXXgen.h.tpl
new file mode 100644
index 00000000..89d083ae
--- /dev/null
+++ b/include/osmocom/core/crcXXgen.h.tpl
@@ -0,0 +1,59 @@
+/*
+ * crcXXgen.h
+ *
+ * Copyright (C) 2011 Sylvain Munaut <tnt@246tNt.com>
+ *
+ * All Rights Reserved
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef __OSMO_CRCXXGEN_H__
+#define __OSMO_CRCXXGEN_H__
+
+/*! \addtogroup crcgen
+ * @{
+ */
+
+/*! \file crcXXgen.h
+ * \file Osmocom generic CRC routines (for max XX bits poly) header
+ */
+
+
+#include <stdint.h>
+#include <osmocom/core/bits.h>
+
+
+/*! \brief structure describing a given CRC code of max XX bits */
+struct osmo_crcXXgen_code {
+ int bits; /*!< \brief Actual number of bits of the CRC */
+ uintXX_t poly; /*!< \brief Polynom (normal representation, MSB omitted */
+ uintXX_t init; /*!< \brief Initialization value of the CRC state */
+ uintXX_t remainder; /*!< \brief Remainder of the CRC (final XOR) */
+};
+
+uintXX_t osmo_crcXXgen_compute_bits(const struct osmo_crcXXgen_code *code,
+ const ubit_t *in, int len);
+int osmo_crcXXgen_check_bits(const struct osmo_crcXXgen_code *code,
+ const ubit_t *in, int len, const ubit_t *crc_bits);
+void osmo_crcXXgen_set_bits(const struct osmo_crcXXgen_code *code,
+ const ubit_t *in, int len, ubit_t *crc_bits);
+
+
+/*! @} */
+
+#endif /* __OSMO_CRCXXGEN_H__ */
+
+/* vim: set syntax=c: */
diff --git a/include/osmocom/core/crcgen.h b/include/osmocom/core/crcgen.h
new file mode 100644
index 00000000..8e208a74
--- /dev/null
+++ b/include/osmocom/core/crcgen.h
@@ -0,0 +1,41 @@
+/*
+ * crcgen.h
+ *
+ * Copyright (C) 2011 Sylvain Munaut <tnt@246tNt.com>
+ *
+ * All Rights Reserved
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef __OSMO_CRCGEN_H__
+#define __OSMO_CRCGEN_H__
+
+/*! \defgroup crcgen Osmocom generic CRC routines
+ * @{
+ */
+
+/*! \file crcgen.h
+ * \file Osmocom generic CRC routines global header
+ */
+
+#include <osmocom/core/crc8gen.h>
+#include <osmocom/core/crc16gen.h>
+#include <osmocom/core/crc32gen.h>
+#include <osmocom/core/crc64gen.h>
+
+/*! @} */
+
+#endif /* __OSMO_CRCGEN_H__ */
diff --git a/include/osmocom/core/gsmtap.h b/include/osmocom/core/gsmtap.h
new file mode 100644
index 00000000..a4e5d420
--- /dev/null
+++ b/include/osmocom/core/gsmtap.h
@@ -0,0 +1,159 @@
+#ifndef _GSMTAP_H
+#define _GSMTAP_H
+
+/* gsmtap header, pseudo-header in front of the actua GSM payload */
+
+/* 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/)
+ */
+
+#include <stdint.h>
+
+/* ====== DO NOT MAKE UNAPPROVED MODIFICATIONS HERE ===== */
+
+/* The GSMTAP format definition is maintained in libosmocore,
+ * specifically the latest version can always be obtained from
+ * http://cgit.osmocom.org/cgit/libosmocore/tree/include/osmocom/core/gsmtap.h
+ *
+ * If you want to introduce new protocol/burst/channel types or extend
+ * GSMTAP in any way, please contact the GSMTAP maintainer at either the
+ * public openbsc@lists.osmocom.org mailing list, or privately at
+ * Harald Welte <laforge@gnumonks.org>.
+ *
+ * Your cooperation ensures that all projects will use the same GSMTAP
+ * definitions and remain compatible with each other.
+ */
+
+#define GSMTAP_VERSION 0x02
+
+#define GSMTAP_TYPE_UM 0x01
+#define GSMTAP_TYPE_ABIS 0x02
+#define GSMTAP_TYPE_UM_BURST 0x03 /* raw burst bits */
+#define GSMTAP_TYPE_SIM 0x04
+#define GSMTAP_TYPE_TETRA_I1 0x05 /* tetra air interface */
+#define GSMTAP_TYPE_TETRA_I1_BURST 0x06 /* tetra air interface */
+#define GSMTAP_TYPE_WMX_BURST 0x07 /* WiMAX burst */
+#define GSMTAP_TYPE_GB_LLC 0x08 /* GPRS Gb interface: LLC */
+#define GSMTAP_TYPE_GB_SNDCP 0x09 /* GPRS Gb interface: SNDCP */
+#define GSMTAP_TYPE_GMR1_UM 0x0a /* GMR-1 L2 packets */
+
+/* ====== DO NOT MAKE UNAPPROVED MODIFICATIONS HERE ===== */
+
+/* sub-types for TYPE_UM_BURST */
+#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
+#define GSMTAP_BURST_NONE 0x09
+/* WiMAX bursts */
+#define GSMTAP_BURST_CDMA_CODE 0x10 /* WiMAX CDMA Code Attribute burst */
+#define GSMTAP_BURST_FCH 0x11 /* WiMAX FCH burst */
+#define GSMTAP_BURST_FFB 0x12 /* WiMAX Fast Feedback burst */
+#define GSMTAP_BURST_PDU 0x13 /* WiMAX PDU burst */
+#define GSMTAP_BURST_HACK 0x14 /* WiMAX HARQ ACK burst */
+#define GSMTAP_BURST_PHY_ATTRIBUTES 0x15 /* WiMAX PHY Attributes burst */
+
+/* ====== DO NOT MAKE UNAPPROVED MODIFICATIONS HERE ===== */
+
+/* sub-types for TYPE_UM */
+#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_PACCH 0x0b
+#define GSMTAP_CHANNEL_CBCH52 0x0c
+#define GSMTAP_CHANNEL_PDCH 0x0d
+#define GSMTAP_CHANNEL_PTCCH 0x0e
+#define GSMTAP_CHANNEL_CBCH51 0x0f
+
+/* GPRS Coding Scheme CS1..4 */
+#define GSMTAP_GPRS_CS_BASE 0x20
+#define GSMTAP_GPRS_CS(N) (GSMTAP_GPRS_CS_BASE + N)
+/* (E) GPRS Coding Scheme MCS0..9 */
+#define GSMTAP_GPRS_MCS_BASE 0x30
+#define GSMTAP_GPRS_MCS(N) (GSMTAP_GPRS_MCS_BASE + N)
+
+#define GSMTAP_CHANNEL_ACCH 0x80
+
+/* ====== DO NOT MAKE UNAPPROVED MODIFICATIONS HERE ===== */
+
+/* sub-types for TYPE_TETRA_AIR */
+#define GSMTAP_TETRA_BSCH 0x01
+#define GSMTAP_TETRA_AACH 0x02
+#define GSMTAP_TETRA_SCH_HU 0x03
+#define GSMTAP_TETRA_SCH_HD 0x04
+#define GSMTAP_TETRA_SCH_F 0x05
+#define GSMTAP_TETRA_BNCH 0x06
+#define GSMTAP_TETRA_STCH 0x07
+#define GSMTAP_TETRA_TCH_F 0x08
+
+/* ====== DO NOT MAKE UNAPPROVED MODIFICATIONS HERE ===== */
+
+/* sub-types for TYPE_GMR1_UM */
+#define GSMTAP_GMR1_UNKNOWN 0x00
+#define GSMTAP_GMR1_BCCH 0x01
+#define GSMTAP_GMR1_CCCH 0x02 /* either AGCH or PCH */
+#define GSMTAP_GMR1_PCH 0x03
+#define GSMTAP_GMR1_AGCH 0x04
+#define GSMTAP_GMR1_BACH 0x05
+#define GSMTAP_GMR1_RACH 0x06
+#define GSMTAP_GMR1_CBCH 0x07
+#define GSMTAP_GMR1_SDCCH 0x08
+#define GSMTAP_GMR1_TACCH 0x09
+#define GSMTAP_GMR1_GBCH 0x0a
+
+#define GSMTAP_GMR1_SACCH 0x01 /* to be combined with _TCH{6,9} */
+#define GSMTAP_GMR1_FACCH 0x02 /* to be combines with _TCH{3,6,9} */
+#define GSMTAP_GMR1_DKAB 0x03 /* to be combined with _TCH3 */
+#define GSMTAP_GMR1_TCH3 0x10
+#define GSMTAP_GMR1_TCH6 0x14
+#define GSMTAP_GMR1_TCH9 0x18
+
+/* ====== DO NOT MAKE UNAPPROVED MODIFICATIONS HERE ===== */
+
+/* flags for the ARFCN */
+#define GSMTAP_ARFCN_F_PCS 0x8000
+#define GSMTAP_ARFCN_F_UPLINK 0x4000
+#define GSMTAP_ARFCN_MASK 0x3fff
+
+/* IANA-assigned well-known UDP port for GSMTAP messages */
+#define GSMTAP_UDP_PORT 4729
+
+/* ====== DO NOT MAKE UNAPPROVED MODIFICATIONS HERE ===== */
+struct gsmtap_hdr {
+ 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) */
+
+ uint16_t arfcn; /* ARFCN (frequency) */
+ int8_t signal_dbm; /* signal level in dBm */
+ int8_t snr_db; /* signal/noise ratio in dB */
+
+ uint32_t frame_number; /* GSM Frame Number (FN) */
+
+ 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/include/osmocom/core/gsmtap_util.h b/include/osmocom/core/gsmtap_util.h
new file mode 100644
index 00000000..5609381f
--- /dev/null
+++ b/include/osmocom/core/gsmtap_util.h
@@ -0,0 +1,57 @@
+#ifndef _GSMTAP_UTIL_H
+#define _GSMTAP_UTIL_H
+
+#include <stdint.h>
+#include <osmocom/core/write_queue.h>
+#include <osmocom/core/select.h>
+
+/*! \defgroup gsmtap GSMTAP
+ * @{
+ */
+/*! \file gsmtap_util.h */
+
+uint8_t chantype_rsl2gsmtap(uint8_t rsl_chantype, uint8_t rsl_link_id);
+
+struct msgb *gsmtap_makemsg_ex(uint8_t type, uint16_t arfcn, uint8_t ts, uint8_t chan_type,
+ uint8_t ss, uint32_t fn, int8_t signal_dbm,
+ uint8_t snr, const uint8_t *data, unsigned int len);
+
+struct msgb *gsmtap_makemsg(uint16_t arfcn, uint8_t ts, uint8_t chan_type,
+ uint8_t ss, uint32_t fn, int8_t signal_dbm,
+ uint8_t snr, const uint8_t *data, unsigned int len);
+
+/*! \brief one gsmtap instance */
+struct gsmtap_inst {
+ int ofd_wq_mode; /*!< \brief wait queue mode? */
+ struct osmo_wqueue wq; /*!< \brief the wait queue */
+ struct osmo_fd sink_ofd;/*!< \brief file descriptor */
+};
+
+/*! \brief obtain the file descriptor associated with a gsmtap instance */
+static inline int gsmtap_inst_fd(struct gsmtap_inst *gti)
+{
+ return gti->wq.bfd.fd;
+}
+
+int gsmtap_source_init_fd(const char *host, uint16_t port);
+
+int gsmtap_source_add_sink_fd(int gsmtap_fd);
+
+struct gsmtap_inst *gsmtap_source_init(const char *host, uint16_t port,
+ int ofd_wq_mode);
+
+int gsmtap_source_add_sink(struct gsmtap_inst *gti);
+
+int gsmtap_sendmsg(struct gsmtap_inst *gti, struct msgb *msg);
+
+int gsmtap_send_ex(struct gsmtap_inst *gti, uint8_t type, uint16_t arfcn, uint8_t ts,
+ uint8_t chan_type, uint8_t ss, uint32_t fn,
+ int8_t signal_dbm, uint8_t snr, const uint8_t *data,
+ unsigned int len);
+
+int gsmtap_send(struct gsmtap_inst *gti, uint16_t arfcn, uint8_t ts,
+ uint8_t chan_type, uint8_t ss, uint32_t fn,
+ int8_t signal_dbm, uint8_t snr, const uint8_t *data,
+ unsigned int len);
+
+#endif /* _GSMTAP_UTIL_H */
diff --git a/include/osmocom/core/linuxlist.h b/include/osmocom/core/linuxlist.h
new file mode 100644
index 00000000..fb99c5ec
--- /dev/null
+++ b/include/osmocom/core/linuxlist.h
@@ -0,0 +1,360 @@
+#ifndef _LINUX_LLIST_H
+#define _LINUX_LLIST_H
+
+#include <stddef.h>
+
+#ifndef inline
+#define inline __inline__
+#endif
+
+static inline void prefetch(const void *x) {;}
+
+/**
+ * container_of - cast a member of a structure out to the containing structure
+ *
+ * @ptr: the pointer to the member.
+ * @type: the type of the container struct this is embedded in.
+ * @member: the name of the member within the struct.
+ *
+ */
+#define container_of(ptr, type, member) ({ \
+ const typeof( ((type *)0)->member ) *__mptr = (typeof( ((type *)0)->member ) *)(ptr); \
+ (type *)( (char *)__mptr - offsetof(type, member) );})
+
+
+/*
+ * These are non-NULL pointers that will result in page faults
+ * under normal circumstances, used to verify that nobody uses
+ * non-initialized llist entries.
+ */
+#define LLIST_POISON1 ((void *) 0x00100100)
+#define LLIST_POISON2 ((void *)