summaryrefslogtreecommitdiff
path: root/src/lib
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib')
-rw-r--r--src/lib/Assert.h67
-rw-r--r--src/lib/Makefile.am109
-rw-r--r--src/lib/decoder/AUTHORS1
-rw-r--r--src/lib/decoder/Makefile.am56
-rw-r--r--src/lib/decoder/a5-1-2.h453
-rw-r--r--src/lib/decoder/burst_types.h214
-rw-r--r--src/lib/decoder/cch.c482
-rw-r--r--src/lib/decoder/cch.h56
-rw-r--r--src/lib/decoder/fire_crc.c179
-rw-r--r--src/lib/decoder/fire_crc.h47
-rw-r--r--src/lib/decoder/gsmstack.c206
-rw-r--r--src/lib/decoder/gsmstack.h43
-rw-r--r--src/lib/decoder/gsmtap.h41
-rw-r--r--src/lib/decoder/interleave.c47
-rw-r--r--src/lib/decoder/interleave.h19
-rw-r--r--src/lib/decoder/openbtsstuff/AUTHORS173
-rw-r--r--src/lib/decoder/openbtsstuff/Assert.h49
-rw-r--r--src/lib/decoder/openbtsstuff/BitVector.cpp513
-rw-r--r--src/lib/decoder/openbtsstuff/BitVector.h427
-rw-r--r--src/lib/decoder/openbtsstuff/GSM610Tables.cpp492
-rw-r--r--src/lib/decoder/openbtsstuff/GSM610Tables.h37
-rw-r--r--src/lib/decoder/openbtsstuff/GSMCommon.cpp315
-rw-r--r--src/lib/decoder/openbtsstuff/GSMCommon.h537
-rw-r--r--src/lib/decoder/openbtsstuff/GSML1FEC.cpp256
-rw-r--r--src/lib/decoder/openbtsstuff/GSML1FEC.h146
-rw-r--r--src/lib/decoder/openbtsstuff/GSMTDMA.cpp337
-rw-r--r--src/lib/decoder/openbtsstuff/GSMTDMA.h358
-rw-r--r--src/lib/decoder/openbtsstuff/Makefile.am49
-rw-r--r--src/lib/decoder/openbtsstuff/RxBurst.h69
-rw-r--r--src/lib/decoder/openbtsstuff/Threads.cpp106
-rw-r--r--src/lib/decoder/openbtsstuff/Threads.h150
-rw-r--r--src/lib/decoder/openbtsstuff/Timeval.cpp93
-rw-r--r--src/lib/decoder/openbtsstuff/Timeval.h96
-rw-r--r--src/lib/decoder/openbtsstuff/Vector.h257
-rw-r--r--src/lib/decoder/openbtsstuff/VocoderFrame.h25
-rw-r--r--src/lib/decoder/out_pcap.c111
-rw-r--r--src/lib/decoder/out_pcap.h9
-rw-r--r--src/lib/decoder/sch.c333
-rw-r--r--src/lib/decoder/sch.h17
-rw-r--r--src/lib/decoder/system.h11
-rw-r--r--src/lib/decoder/tun.c125
-rw-r--r--src/lib/decoder/tun.h4
-rw-r--r--src/lib/gsm.i49
-rw-r--r--src/lib/gsm_constants.h150
-rw-r--r--src/lib/gsm_receiver_cf.cc853
-rw-r--r--src/lib/gsm_receiver_cf.h254
-rw-r--r--src/lib/gsm_receiver_config.cc84
-rw-r--r--src/lib/gsm_receiver_config.h164
-rw-r--r--src/lib/viterbi_detector.cc554
-rw-r--r--src/lib/viterbi_detector.h63
50 files changed, 0 insertions, 9286 deletions
diff --git a/src/lib/Assert.h b/src/lib/Assert.h
deleted file mode 100644
index acfb3f7..0000000
--- a/src/lib/Assert.h
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
-* Copyright 2008 Free Software Foundation, Inc.
-*
-* This software is distributed under the terms of the GNU Public License.
-* See the COPYING file in the main directory for details.
-
- 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 3 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, see <http://www.gnu.org/licenses/>.
-
-*/
-
-
-#ifndef ASSERT_H
-#define ASSERT_H
-
-#include "stdio.h"
-#include <iostream>
-
-#define NDEBUG
-
-/**@name Macros for standard messages. */
-//@{
-#define COUT(text) { std::cout << text << std::endl; }
-#define CERR(text) { std::cerr << __FILE__ << ":" << __LINE__ << ": " << text; }
-#ifdef NDEBUG
-#define DCOUT(text) {}
-#define OBJDCOUT(text) {}
-#else
-#define DCOUT(text) { COUT(__FILE__ << ":" << __LINE__ << " " << text); }
-#define OBJDCOUT(text) { DCOUT(this << " " << text); }
-#endif
-//@}
-
-
-/** This is thrown by assert() so that gdb can catch it. */
-
-class Assertion
-{
-
- public:
-
- Assertion() {
- fprintf( stderr,"Try setting a breakpoint @ %s:%u.\n",__FILE__,__LINE__ );
- return;
- }
-
-};
-
-#ifdef NDEBUG
-#define assert(EXPR) {};
-#else
-/** This replaces the regular assert() with a C++ exception. */
-#include "stdio.h"
-#define assert(E) { if (!(E)) { fprintf(stderr,"%s:%u failed assertion '%s'\n",__FILE__,__LINE__,#E); throw Assertion(); } }
-#endif
-
-#endif
diff --git a/src/lib/Makefile.am b/src/lib/Makefile.am
deleted file mode 100644
index 925eaca..0000000
--- a/src/lib/Makefile.am
+++ /dev/null
@@ -1,109 +0,0 @@
-#
-# Copyright 2004,2005,2006,2008 Free Software Foundation, Inc.
-#
-# This file is part of GNU Radio
-#
-# GNU Radio 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 3, or (at your option)
-# any later version.
-#
-# GNU Radio 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 GNU Radio; see the file COPYING. If not, write to
-# the Free Software Foundation, Inc., 51 Franklin Street,
-# Boston, MA 02110-1301, USA.
-#
-
-include $(top_srcdir)/Makefile.common
-
-SUBDIRS = decoder
-# Install this stuff so that it ends up as the gnuradio.howto module
-# This usually ends up at:
-# ${prefix}/lib/python${python_version}/site-packages/gnuradio
-
-ourpythondir = $(grpythondir)
-ourlibdir = $(grpyexecdir)
-
-AM_CPPFLAGS = $(STD_DEFINES_AND_INCLUDES) $(PYTHON_CPPFLAGS) $(WITH_INCLUDES)
-# -I$(OPEN_BTS_INCLUDES)
-
-SWIGPYTHONARGS = $(SWIGPYTHONFLAGS) $(SWIGGRFLAGS) $(WITH_SWIG_INCLUDES) \
- $(WITH_INCLUDES)
-
-ALL_IFILES = \
- $(LOCAL_IFILES) \
- $(NON_LOCAL_IFILES)
-
-NON_LOCAL_IFILES = \
- $(GNURADIO_CORE_INCLUDEDIR)/swig/gnuradio.i
-
-
-LOCAL_IFILES = \
- $(top_srcdir)/src/lib/gsm.i
-
-# These files are built by SWIG. The first is the C++ glue.
-# The second is the python wrapper that loads the _howto shared library
-# and knows how to call our extensions.
-
-BUILT_SOURCES = \
- gsm.cc \
- gsm.py
-
-# This gets howto.py installed in the right place
-ourpython_PYTHON = \
- gsm.py
-
-ourlib_LTLIBRARIES = _gsm.la
-
-lib_LTLIBRARIES = libgsmdemod.la
-
-# These are the source files that go into the shared library
-_gsm_la_SOURCES = \
- gsm.cc
-
-libgsmdemod_la_SOURCES = \
- gsm_receiver_cf.cc \
- gsm_receiver_config.cc \
- viterbi_detector.cc
-
-# magic flags
-_gsm_la_LDFLAGS = $(NO_UNDEFINED) -module -avoid-version
-
-# link the library against some comon swig runtime code and the
-# c++ standard library
-_gsm_la_LIBADD = \
- $(PYTHON_LDFLAGS) \
- libgsmdemod.la \
- -lstdc++ \
- $(DECODER_LA)
-
-#libgsmdemod_la_LIBADD =
-
-gsm.cc gsm.py: $(LOCAL_IFILES) $(ALL_IFILES)
- $(SWIG) $(SWIGPYTHONARGS) -module gsm -o gsm.cc $(LOCAL_IFILES)
-
-# These headers get installed in ${prefix}/include/gnuradio
-grinclude_HEADERS = \
- gsm_receiver_cf.h \
- gsm_receiver_config.h
-
-noinst_HEADERS = \
- gsm_constants.h \
- viterbi_detector.h
-
-# These swig headers get installed in ${prefix}/include/gnuradio/swig
-swiginclude_HEADERS = \
- $(LOCAL_IFILES)
-
-
-MOSTLYCLEANFILES = $(BUILT_SOURCES) *.pyc
-
-# Don't distribute output of swig
-dist-hook:
- @for file in $(BUILT_SOURCES); do echo $(RM) $(distdir)/$$file; done
- @for file in $(BUILT_SOURCES); do $(RM) $(distdir)/$$file; done
diff --git a/src/lib/decoder/AUTHORS b/src/lib/decoder/AUTHORS
deleted file mode 100644
index dcc5998..0000000
--- a/src/lib/decoder/AUTHORS
+++ /dev/null
@@ -1 +0,0 @@
-Harald Welte <laforge@gnumonks.org>
diff --git a/src/lib/decoder/Makefile.am b/src/lib/decoder/Makefile.am
deleted file mode 100644
index 1726d68..0000000
--- a/src/lib/decoder/Makefile.am
+++ /dev/null
@@ -1,56 +0,0 @@
-#
-# Copyright 2001,2002,2004,2005,2006,2007,2008 Free Software Foundation, Inc.
-#
-# This file is part of GNU Radio
-#
-# GNU Radio 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 3, or (at your option)
-# any later version.
-#
-# GNU Radio 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 GNU Radio; see the file COPYING. If not, write to
-# the Free Software Foundation, Inc., 51 Franklin Street,
-# Boston, MA 02110-1301, USA.
-#
-
-include $(top_srcdir)/Makefile.common
-
-AM_CPPFLAGS = $(STD_DEFINES_AND_INCLUDES)
-
-SUBDIRS = openbtsstuff
-
-noinst_LTLIBRARIES = libdecoder.la
-
-libdecoder_la_LIBADD = \
- openbtsstuff/libopenbtsdecoder.la
-
-libdecoder_la_SOURCES = \
- sch.c \
- cch.c \
- fire_crc.c \
- gsmstack.c \
- interleave.c \
- out_pcap.c \
- tun.c
-# tch.c \
-# conv.c
-
-noinst_HEADERS = \
- sch.h \
- cch.h \
- fire_crc.h \
- gsmstack.h \
- interleave.h \
- out_pcap.h \
- tun.h \
- system.h \
- gsmtap.h \
- a5-1-2.h
-# tch.h \
-# conv.h
diff --git a/src/lib/decoder/a5-1-2.h b/src/lib/decoder/a5-1-2.h
deleted file mode 100644
index de764ee..0000000
--- a/src/lib/decoder/a5-1-2.h
+++ /dev/null
@@ -1,453 +0,0 @@
-/*
- * A pedagogical implementation of the GSM A5/1 and A5/2 "voice privacy"
- * encryption algorithms.
- *
- * Copyright (C) 1998-1999: Marc Briceno, Ian Goldberg, and David Wagner
- *
- * The source code below is optimized for instructional value and clarity.
- * Performance will be terrible, but that's not the point.
- *
- * This software may be export-controlled by US law.
- *
- * This software is free for commercial and non-commercial use as long as
- * the following conditions are adhered to.
- * Copyright remains the authors' and as such any Copyright notices in
- * the code are not to be removed.
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
- * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
- * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
- * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * The license and distribution terms for any publicly available version
- * or derivative of this code cannot be changed. i.e. this code cannot
- * simply be copied and put under another distribution license
- * [including the GNU Public License].
- *
- * Background: The Global System for Mobile communications is the most
- * widely deployed digital cellular telephony system in the world. GSM
- * makes use of four core cryptographic algorithms, none of which has
- * been published by the GSM MOU. This failure to subject the
- * algorithms to public review is all the more puzzling given that over
- * 215 million GSM subscribers are expected to rely on the claimed
- * security of the system.
- *
- * The four core GSM cryptographic algorithms are:
- * A3 authentication algorithm
- * A5/1 "stronger" over-the-air voice-privacy algorithm
- * A5/2 "weaker" over-the-air voice-privacy algorithm
- * A8 voice-privacy key generation algorithm
- *
- * In April of 1998, our group showed that COMP128, the algorithm used by the
- * overwhelming majority of GSM providers for both A3 and A8 functionality
- * is fatally flawed and allows for cloning of GSM mobile phones.
- *
- * Furthermore, we demonstrated that all A8 implementations we could locate,
- * including the few that did not use COMP128 for key generation, had been
- * deliberately weakened by reducing the keyspace from 64 bits to 54 bits.
- * The remaining 10 bits are simply set to zero!
- *
- * See http://www.scard.org/gsm for additional information.
- *
- * [May 1999]
- * One question so far unanswered is if A5/1, the "stronger" of the two
- * widely deployed voice-privacy algorithm is at least as strong as the
- * key. Meaning: "Does A5/1 have a work factor of at least 54 bits"?
- * Absent a publicly available A5/1 reference implementation, this question
- * could not be answered. We hope that our reference implementation below,
- * which has been verified against official A5/1 test vectors, will provide
- * the cryptographic community with the base on which to construct the
- * answer to this important question.
- *
- * Initial indications about the strength of A5/1 are not encouraging.
- * A variant of A5, while not A5/1 itself, has been estimated to have a
- * work factor of well below 54 bits. See http://jya.com/crack-a5.htm for
- * background information and references.
- *
- * With COMP128 broken and A5/1 published below, we will now turn our
- * attention to A5/2.
- *
- * [August 1999]
- * 19th Annual International Cryptology Conference - Crypto'99
- * Santa Barbara, California
- *
- * A5/2 has been added to the previously published A5/1 source. Our
- * implementation has been verified against official test vectors.
- *
- * This means that our group has now reverse engineered the entire set
- * of cryptographic algorithms used in the overwhelming majority of GSM
- * installations, including all the over-the-air "voice privacy" algorithms.
- *
- * The "voice privacy" algorithm A5/2 proved especially weak. Which perhaps
- * should come as no surprise, since even GSM MOU members have admitted that
- * A5/2 was designed with heavy input by intelligence agencies to ensure
- * breakability. Just how insecure is A5/2? It can be broken in real time
- * with a work factor of a mere 16 bits. GSM might just as well use no "voice
- * privacy" algorithm at all.
- *
- * We announced the break of A5/2 at the Crypto'99 Rump Session.
- * Details will be published in a scientific paper following soon.
- *
- *
- * -- Marc Briceno <marc@scard.org>
- * Voice: +1 (925) 798-4042
- *
- */
-
-
-#include <stdio.h>
-
-
-/* Masks for the shift registers */
-#define R1MASK 0x07FFFF /* 19 bits, numbered 0..18 */
-#define R2MASK 0x3FFFFF /* 22 bits, numbered 0..21 */
-#define R3MASK 0x7FFFFF /* 23 bits, numbered 0..22 */
-#ifdef A5_2
-#define R4MASK 0x01FFFF /* 17 bits, numbered 0..16 */
-#endif /* A5_2 */
-
-
-#ifndef A5_2
-/* Middle bit of each of the three shift registers, for clock control */
-#define R1MID 0x000100 /* bit 8 */
-#define R2MID 0x000400 /* bit 10 */
-#define R3MID 0x000400 /* bit 10 */
-#else /* A5_2 */
-/* A bit of R4 that controls each of the shift registers */
-#define R4TAP1 0x000400 /* bit 10 */
-#define R4TAP2 0x000008 /* bit 3 */
-#define R4TAP3 0x000080 /* bit 7 */
-#endif /* A5_2 */
-
-
-/* Feedback taps, for clocking the shift registers.
- * These correspond to the primitive polynomials
- * x^19 + x^5 + x^2 + x + 1, x^22 + x + 1,
- * x^23 + x^15 + x^2 + x + 1, and x^17 + x^5 + 1. */
-
-
-#define R1TAPS 0x072000 /* bits 18,17,16,13 */
-#define R2TAPS 0x300000 /* bits 21,20 */
-#define R3TAPS 0x700080 /* bits 22,21,20,7 */
-#ifdef A5_2
-#define R4TAPS 0x010800 /* bits 16,11 */
-#endif /* A5_2 */
-
-
-typedef unsigned char byte;
-typedef unsigned long word;
-typedef word bit;
-
-
-/* Calculate the parity of a 32-bit word, i.e. the sum of its bits modulo 2
-*/
-bit parity(word x)
-{
- x ^= x >> 16;
- x ^= x >> 8;
- x ^= x >> 4;
- x ^= x >> 2;
- x ^= x >> 1;
- return x&1;
-}
-
-
-/* Clock one shift register. For A5/2, when the last bit of the frame
- * is loaded in, one particular bit of each register is forced to '1';
- * that bit is passed in as the last argument. */
-#ifndef A5_2
-word clockone(word reg, word mask, word taps)
-{
-#else /* A5_2 */
-word clockone(word reg, word mask, word taps, word loaded_bit) {
-#endif /* A5_2 */
- word t = reg & taps;
- reg = (reg << 1) & mask;
- reg |= parity(t);
-#ifdef A5_2
- reg |= loaded_bit;
-#endif /* A5_2 */
- return reg;
-}
-
-
-/* The three shift registers. They're in global variables to make the code
- * easier to understand.
- * A better implementation would not use global variables. */
-word R1, R2, R3;
-#ifdef A5_2
-word R4;
-#endif /* A5_2 */
-
-
-/* Return 1 iff at least two of the parameter words are non-zero. */
-bit majority(word w1, word w2, word w3) {
- int sum = (w1 != 0) + (w2 != 0) + (w3 != 0);
- if (sum >= 2)
- return 1;
- else
- return 0;
-}
-
-
-/* Clock two or three of R1,R2,R3, with clock control
- * according to their middle bits.
- * Specifically, we clock Ri whenever Ri's middle bit
- * agrees with the majority value of the three middle bits. For A5/2,
- * use particular bits of R4 instead of the middle bits. Also, for A5/2,
- * always clock R4.
- * If allP == 1, clock all three of R1,R2,R3, ignoring their middle bits.
- * This is only used for key setup. If loaded == 1, then this is the last
- * bit of the frame number, and if we're doing A5/2, we have to set a
- * particular bit in each of the four registers. */
-void clock(int allP, int loaded) {
-#ifndef A5_2
- bit maj = majority(R1 & R1MID, R2 & R2MID, R3 & R3MID);
- if (allP || (((R1&R1MID) != 0) == maj))
- R1 = clockone(R1, R1MASK, R1TAPS);
- if (allP || (((R2&R2MID) != 0) == maj))
- R2 = clockone(R2, R2MASK, R2TAPS);
- if (allP || (((R3&R3MID) != 0) == maj))
- R3 = clockone(R3, R3MASK, R3TAPS);
-#else /* A5_2 */
- bit maj = majority(R4 & R4TAP1, R4 & R4TAP2, R4 & R4TAP3);
- if (allP || (((R4&R4TAP1) != 0) == maj))
- R1 = clockone(R1, R1MASK, R1TAPS, loaded << 15);
- if (allP || (((R4&R4TAP2) != 0) == maj))
- R2 = clockone(R2, R2MASK, R2TAPS, loaded << 16);
- if (allP || (((R4&R4TAP3) != 0) == maj))
- R3 = clockone(R3, R3MASK, R3TAPS, loaded << 18);
- R4 = clockone(R4, R4MASK, R4TAPS, loaded << 10);
-#endif /* A5_2 */
-}
-
-
-/* Generate an output bit from the current state.
- * You grab a bit from each register via the output generation taps;
- * then you XOR the resulting three bits. For A5/2, in addition to
- * the top bit of each of R1,R2,R3, also XOR in a majority function
- * of three particular bits of the register (one of them complemented)
- * to make it non-linear. Also, for A5/2, delay the output by one
- * clock cycle for some reason. */
-bit getbit() {
- bit topbits = (((R1 >> 18) ^ (R2 >> 21) ^ (R3 >> 22)) & 0x01);
-#ifndef A5_2
- return topbits;
-#else /* A5_2 */
- static bit delaybit = 0;
- bit nowbit = delaybit;
- delaybit = (
- topbits
- ^ majority(R1 & 0x8000, (~R1) & 0x4000, R1 & 0x1000)
- ^ majority((~R2) & 0x10000, R2 & 0x2000, R2 & 0x200)
- ^ majority(R3 & 0x40000, R3 & 0x10000, (~R3) & 0x2000)
- );
- return nowbit;
-#endif /* A5_2 */
-}
-
-
-/* Do the A5 key setup. This routine accepts a 64-bit key and
- * a 22-bit frame number. */
-void keysetup(byte key_reversed[8], word frame) {
- int i;
- bit keybit, framebit;
-
- byte key[8];
- for(i=0; i<8; i++){
- key[i] = key_reversed[7-i];
- }
- /* Zero out the shift registers. */
- R1 = R2 = R3 = 0;
-#ifdef A5_2
- R4 = 0;
-#endif /* A5_2 */
-
-
- /* Load the key into the shift registers,
- * LSB of first byte of key array first,
- * clocking each register once for every
- * key bit loaded. (The usual clock
- * control rule is temporarily disabled.) */
- for (i = 0; i < 64; i++) {
- clock(1, 0); /* always clock */
- keybit = (key[i/8] >> (i & 7)) & 1; /* The i-th bit of the key */
- R1 ^= keybit;
- R2 ^= keybit;
- R3 ^= keybit;
-#ifdef A5_2
- R4 ^= keybit;
-#endif /* A5_2 */
- }
-
-
- /* Load the frame number into the shift registers, LSB first,
- * clocking each register once for every key bit loaded.
- * (The usual clock control rule is still disabled.)
- * For A5/2, signal when the last bit is being clocked in. */
- for (i = 0; i < 22; i++) {
- clock(1, i == 21); /* always clock */
- framebit = (frame >> i) & 1; /* The i-th bit of the frame # */
- R1 ^= framebit;
- R2 ^= framebit;
- R3 ^= framebit;
-#ifdef A5_2
- R4 ^= framebit;
-#endif /* A5_2 */
- }
-
-
- /* Run the shift registers for 100 clocks
- * to mix the keying material and frame number
- * together with output generation disabled,
- * so that there is sufficient avalanche.
- * We re-enable the majority-based clock control
- * rule from now on. */
- for (i = 0; i < 100; i++) {
- clock(0, 0);
- }
- /* For A5/2, we have to load the delayed output bit. This does _not_
- * change the state of the registers. For A5/1, this is a no-op. */
- getbit();
-
-
- /* Now the key is properly set up. */
-}
-
-
-/* Generate output. We generate 228 bits of
- * keystream output. The first 114 bits is for
- * the A->B frame; the next 114 bits is for the
- * B->A frame. You allocate a 15-byte buffer
- * for each direction, and this function fills
- * it in. */
-void run(byte AtoBkeystream[], byte BtoAkeystream[]) {
- int i;
-
-
- /* Zero out the output buffers. */
- for (i = 0; i <= 113 / 8; i++)
- AtoBkeystream[i] = BtoAkeystream[i] = 0;
-
-
- /* Generate 114 bits of keystream for the
- * A->B direction. Store it, MSB first. */
- for (i = 0; i < 114; i++) {
- clock(0, 0);
- AtoBkeystream[i/8] |= getbit() << (7 - (i & 7));
- }
-
-
- /* Generate 114 bits of keystream for the
- * B->A direction. Store it, MSB first. */
- for (i = 0; i < 114; i++) {
- clock(0, 0);
- BtoAkeystream[i/8] |= getbit() << (7 - (i & 7));
- }
-}
-
-void runA51(unsigned char AtoBkeystream[]) {
- int i;
-
- /* Zero out the output buffers. */
- for (i = 0; i < 114; i++)
- AtoBkeystream[i] = 0;
-
-
- /* Generate 114 bits of keystream for the
- * A->B direction. Store it, MSB first. */
- for (i = 0; i < 114; i++) {
- clock(0, 0);
- AtoBkeystream[i] = getbit();
- }
-}
-
-
-/* Test the code by comparing it against
- * a known-good test vector. */
-void test() {
-#ifndef A5_2
- byte key[8] = {0x12, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF};
- word frame = 0x134;
- byte goodAtoB[15] = { 0x53, 0x4E, 0xAA, 0x58, 0x2F, 0xE8, 0x15,
- 0x1A, 0xB6, 0xE1, 0x85, 0x5A, 0x72, 0x8C, 0x00
- };
- byte goodBtoA[15] = { 0x24, 0xFD, 0x35, 0xA3, 0x5D, 0x5F, 0xB6,
- 0x52, 0x6D, 0x32, 0xF9, 0x06, 0xDF, 0x1A, 0xC0
- };
-#else /* A5_2 */
- byte key[8] = {0x00, 0xfc, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
- word frame = 0x21;
- byte goodAtoB[15] = { 0xf4, 0x51, 0x2c, 0xac, 0x13, 0x59, 0x37,
- 0x64, 0x46, 0x0b, 0x72, 0x2d, 0xad, 0xd5, 0x00
- };
- byte goodBtoA[15] = { 0x48, 0x00, 0xd4, 0x32, 0x8e, 0x16, 0xa1,
- 0x4d, 0xcd, 0x7b, 0x97, 0x22, 0x26, 0x51, 0x00
- };
-#endif /* A5_2 */
- byte AtoB[15], BtoA[15];
- int i, failed = 0;
-
-
- keysetup(key, frame);
- run(AtoB, BtoA);
-
-
- /* Compare against the test vector. */
- for (i = 0; i < 15; i++)
- if (AtoB[i] != goodAtoB[i])
- failed = 1;
- for (i = 0; i < 15; i++)
- if (BtoA[i] != goodBtoA[i])
- failed = 1;
-
-
- /* Print some debugging output. */
- printf("key: 0x");
- for (i = 0; i < 8; i++)
- printf("%02X", key[i]);
- printf("\n");
- printf("frame number: 0x%06X\n", (unsigned int)frame);
- printf("known good output:\n");
- printf(" A->B: 0x");
- for (i = 0; i < 15; i++)
- printf("%02X", goodAtoB[i]);
- printf(" B->A: 0x");
- for (i = 0; i < 15; i++)
- printf("%02X", goodBtoA[i]);
- printf("\n");
- printf("observed output:\n");
- printf(" A->B: 0x");
- for (i = 0; i < 15; i++)
- printf("%02X", AtoB[i]);
- printf(" B->A: 0x");
- for (i = 0; i < 15; i++)
- printf("%02X", BtoA[i]);
- printf("\n");
-
-
- if (!failed) {
- printf("Self-check succeeded: everything looks ok.\n");
-// exit(0);
- } else {
- /* Problems! The test vectors didn't compare*/
- printf("\nI don't know why this broke; contact the authors.\n");
- }
-}
-
diff --git a/src/lib/decoder/burst_types.h b/src/lib/decoder/burst_types.h
deleted file mode 100644
index ee51f9a..0000000
--- a/src/lib/decoder/burst_types.h
+++ /dev/null
@@ -1,214 +0,0 @@
-// $Id: burst_types.h,v 1.5 2007/03/14 05:44:53 jl Exp $
-
-#pragma once
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#include <gsm_constants.h>
-
-static const int TB_LEN = 3;
-static const int TB_OS1 = 0;
-static const int TB_OS2 = 145;
-static const unsigned char tail_bits[] = {0, 0, 0};
-
-/*
- * The normal burst is used to carry information on traffic and control
- * channels.
- */
-
-static const int N_TSC_NUM = 8; // number of training sequence codes
-static const int N_TSC_CODE_LEN = 26; // length of tsc
-static const int N_TSC_OS = 61; // tsc offset
-static const int N_EDATA_LEN_1 = 58; // length of first data section
-static const int N_EDATA_OS_1 = 3; // offset of first data section
-static const int N_EDATA_LEN_2 = 58; // length of second data section
-static const int N_EDATA_OS_2 = 87; // offset of second data section
-#if 0
-static const unsigned char n_tsc[][N_TSC_CODE_LEN] = {
-/* 0 */ {
- 0, 0, 1, 0, 0, 1, 0, 1, 1, 1, 0, 0, 0,
- 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 1, 1, 1
- },
-/* 1 */ {
- 0, 0, 1, 0, 1, 1, 0, 1, 1, 1, 0, 1, 1,
- 1, 1, 0, 0, 0, 1, 0, 0, 1, 0, 1, 1, 1
- },
-/* 2 */ {
- 0, 1, 0, 0, 0, 0, 1, 1, 1, 0, 1, 1, 1,
- 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 1, 1, 0
- },
-/* 3 */ {
- 0, 1, 0, 0, 0, 1, 1, 1, 1, 0, 1, 1, 0,
- 1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 1, 1, 0
- },
-/* 4 */ {
- 0, 0, 0, 1, 1, 0, 1, 0, 1, 1, 1, 0, 0,
- 1, 0, 0, 0, 0, 0, 1, 1, 0, 1, 0, 1, 1
- },
-/* 5 */ {
- 0, 1, 0, 0, 1, 1, 1, 0, 1, 0, 1, 1, 0,
- 0, 0, 0, 0, 1, 0, 0, 1, 1, 1, 0, 1, 0
- },
-/* 6 */ {
- 1, 0, 1, 0, 0, 1, 1, 1, 1, 1, 0, 1, 1,
- 0, 0, 0, 1, 0, 1, 0, 0, 1, 1, 1, 1, 1
- },
-/* 7 */ {
- 1, 1, 1, 0, 1, 1, 1, 1, 0, 0, 0, 1, 0,
- 0, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 0, 0
- }
-};
-
-#endif
-
-/*
- * The frequency correction burst is used for frequency synchronization
- * of the mobile. This is broadcast in TS0 together with the SCH and
- * BCCH.
- *
- * Modulating the bits below causes a spike at 62.5kHz above (below for
- * COMPACT) the center frequency. One can use this spike with a narrow
- * band filter to accurately determine the center of the channel.
- */
-static const int FC_CODE_LEN = 142;
-static const int FC_OS = 3;
-static const unsigned char fc_fb[] = {
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-};
-
-static const unsigned char fc_compact_fb[] = {
- 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0,
- 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0,
- 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0,
- 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0,
- 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0,
- 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0,
- 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0,
- 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0,
- 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0
-};
-
-
-/*
- * The synchronization burst is used for time synchronization of the
- * mobile. The bits given below were chosen for their correlation
- * properties. The synchronization channel (SCH) contains a long
- * training sequence (given below) and carries the TDMA frame number and
- * base station identity code. It is broadcast in TS0 in the frame
- * following the frequency correction burst.
- */
-static const int SB_CODE_LEN = 64;
-static const int SB_ETS_OS = 42;
-static const int SB_EDATA_LEN_1 = 39;
-static const int SB_EDATA_OS_1 = 3;
-static const int SB_EDATA_LEN_2 = 39;
-static const int SB_EDATA_OS_2 = 106;
-static const unsigned char sb_etsc[] = {
- 1, 0, 1, 1, 1, 0, 0, 1, 0, 1, 1, 0, 0, 0, 1, 0,
- 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1,
- 0, 0, 1, 0, 1, 1, 0, 1, 0, 1, 0, 0, 0, 1, 0, 1,
- 0, 1, 1, 1, 0, 1, 1, 0, 0, 0, 0, 1, 1, 0, 1, 1
-};
-
-static const unsigned char sb_cts_etsc[] = {
- 1, 1, 1, 0, 1, 1, 1, 0, 0, 1, 1, 0, 1, 0, 1, 1,
- 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0,
- 1, 1, 1, 1, 0, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0,
- 1, 1, 0, 0, 1, 0, 1, 1, 0, 0, 0, 1, 0, 1, 0, 1
-};
-
-static const unsigned char sb_compact_etsc[] = {
- 1, 1, 1, 0, 1, 1, 0, 0, 0, 0, 1, 1, 0, 1, 1, 1,
- 0, 1, 0, 1, 0, 0, 0, 1, 0, 1, 0, 1, 1, 0, 1, 0,
- 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0,
- 0, 0, 1, 0, 0, 0, 1, 1, 0, 1, 0, 0, 1, 1, 1, 0
-};
-
-
-/*
- * A base tranceiver station must transmit a burst in every timeslot of
- * every TDMA frame in channel C0. The dummy burst will be transmitted
- * on all timeslots of all TDMA frames for which no other channel
- * requires a burst to be transmitted.
- */
-static const int D_CODE_LEN = 142;
-static const int D_MB_OS = 3;
-static const unsigned char d_mb[] = {
- 1, 1, 1, 1, 1, 0, 1, 1, 0, 1, 1, 1, 0, 1, 1, 0,
- 0, 0, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 1, 1, 1, 0,
- 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0,
- 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0,
- 0, 1, 0, 1, 1, 1, 0, 0, 0, 1, 0, 1, 1, 1, 0, 0,
- 0, 1, 0, 1, 0, 1, 1, 1, 0, 1, 0, 0, 1, 0, 1, 0,
- 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 1, 0, 0, 1,
- 1, 1, 1, 0, 1, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 1,
- 0, 0, 1, 0, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0
-};
-
-
-/*
- * The access burst is used for random access from a mobile.
- */
-static const int AB_ETB_CODE_LEN = 8;
-static const int AB_ETB_OS = 0;
-static const unsigned char ab_etb[] = {
- 0, 0, 1, 1, 1, 0, 1, 0
-};
-
-static const int AB_SSB_CODE_LEN = 41;
-static const int AB_SSB_OS = 8;
-static const unsigned char ab_ssb[] = {
- 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1,
- 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0,
- 0, 0, 1, 1, 1, 1, 0, 0, 0
-};
-
-static const unsigned char ab_ts1_ssb[] = {
- 0, 1, 0, 1, 0, 1, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0,
- 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0, 1, 1, 1, 1,
- 0, 0, 1, 0, 0, 1, 1, 0, 1
-};
-
-static const unsigned char ab_ts2_ssb[] = {
- 1, 1, 1, 0, 1, 1, 1, 1, 0, 0, 1, 0, 0, 1, 1, 1,
- 0, 1, 0, 1, 0, 1, 1, 0, 0, 0, 0, 0, 1, 1, 0, 1,
- 1, 0, 1, 1, 1, 0, 1, 1, 1
-};
-
-
-typedef enum {
- burst_n_0,
- burst_n_1,
- burst_n_2,
- burst_n_3,
- burst_n_4,
- burst_n_5,
- burst_n_6,
- burst_n_7,
- burst_fc,
- burst_fc_c,
- burst_s,
- burst_s_cts,
- burst_s_c,
- burst_d,
- burst_a,
- burst_a_ts1,
- burst_a_ts2,
- burst_not_a_burst
-} burst_t;
-
-static const int N_BURST_TYPES = ((int)(burst_not_a_burst) + 1);
-
-#ifdef __cplusplus
-}
-#endif
diff --git a/src/lib/decoder/cch.c b/src/lib/decoder/cch.c
deleted file mode 100644
index f1da56d..0000000
--- a/src/lib/decoder/cch.c
+++ /dev/null
@@ -1,482 +0,0 @@
-//TODO: this file shouldn't be part of the GSM Receiver
-#include "system.h"
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <string.h>
-#include <ctype.h>
-
-//#include <exception>
-//#include <stdexcept>
-#include <math.h>
-//#include "burst_types.h"
-#include "cch.h"
-#include "fire_crc.h"
-
-
-/*
- * GSM SACCH -- Slow Associated Control Channel
- *
- * These messages are encoded exactly the same as on the BCCH.
- * (Broadcast Control Channel.)
- *
- * Input: 184 bits
- *
- * 1. Add parity and flushing bits. (Output 184 + 40 + 4 = 228 bit)
- * 2. Convolutional encode. (Output 228 * 2 = 456 bit)
- * 3. Interleave. (Output 456 bit)
- * 4. Map on bursts. (4 x 156 bit bursts with each 2x57 bit content data)
- */
-
-
-/*
- * Parity (FIRE) for the GSM SACCH channel.
- *
- * g(x) = (x^23 + 1)(x^17 + x^3 + 1)
- * = x^40 + x^26 + x^23 + x^17 + x^3 + 1
- */
-
-static const unsigned char parity_polynomial[PARITY_SIZE + 1] = {
- 1, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 1, 0,
- 0, 1, 0, 0, 0, 0, 0, 1,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 1, 0, 0,
- 1
-};
-
-// remainder after dividing data polynomial by g(x)
-static const unsigned char parity_remainder[PARITY_SIZE] = {
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1
-};
-
-
-/*
-static void parity_encode(unsigned char *d, unsigned char *p) {
-
- int i;
- unsigned char buf[DATA_BLOCK_SIZE + PARITY_SIZE], *q;
-
- memcpy(buf, d, DATA_BLOCK_SIZE);
- memset(buf + DATA_BLOCK_SIZE, 0, PARITY_SIZE);
-
- for(q = buf; q < buf + DATA_BLOCK_SIZE; q++)
- if(*q)
- for(i = 0; i < PARITY_SIZE + 1; i++)
- q[i] ^= parity_polynomial[i];
- for(i = 0; i < PARITY_SIZE; i++)
- p[i] = !buf[DATA_BLOCK_SIZE + i];
-}
- */
-
-
-static int parity_check(unsigned char *d) {
-
- unsigned int i;
- unsigned char buf[DATA_BLOCK_SIZE + PARITY_SIZE], *q;
-
- memcpy(buf, d, DATA_BLOCK_SIZE + PARITY_SIZE);
-
- for(q = buf; q < buf + DATA_BLOCK_SIZE; q++)
- if(*q)
- for(i = 0; i < PARITY_SIZE + 1; i++)
- q[i] ^= parity_polynomial[i];
- return memcmp(buf + DATA_BLOCK_SIZE, parity_remainder, PARITY_SIZE);
-}
-
-
-/*
- * Convolutional encoding and Viterbi decoding for the GSM SACCH channel.
- */
-
-/*
- * Convolutional encoding:
- *
- * G_0 = 1 + x^3 + x^4
- * G_1 = 1 + x + x^3 + x^4
- *
- * i.e.,
- *
- * c_{2k} = u_k + u_{k - 3} + u_{k - 4}
- * c_{2k + 1} = u_k + u_{k - 1} + u_{k - 3} + u_{k - 4}
- */
-#define K 5
-#define MAX_ERROR (2 * CONV_INPUT_SIZE + 1)
-
-
-/*
- * Given the current state and input bit, what are the output bits?
- *
- * encode[current_state][input_bit]
- */
-static const unsigned int encode[1 << (K - 1)][2] = {
- {0, 3}, {3, 0}, {3, 0}, {0, 3},
- {0, 3}, {3, 0}, {3, 0}, {0, 3},
- {1, 2}, {2, 1}, {2, 1}, {1, 2},
- {1, 2}, {2, 1}, {2, 1}, {1, 2}
-};
-
-
-/*
- * Given the current state and input bit, what is the next state?
- *
- * next_state[current_state][input_bit]
- */
-static const unsigned int next_state[1 << (K - 1)][2] = {
- {0, 8}, {0, 8}, {1, 9}, {1, 9},
- {2, 10}, {2, 10}, {3, 11}, {3, 11},
- {4, 12}, {4, 12}, {5, 13}, {5, 13},
- {6, 14}, {6, 14}, {7, 15}, {7, 15}
-};
-
-
-/*
- * Given the previous state and the current state, what input bit caused
- * the transition? If it is impossible to transition between the two
- * states, the value is 2.
- *
- * prev_next_state[previous_state][current_state]
- */
-static const unsigned int prev_next_state[1 << (K - 1)][1 << (K - 1)] = {
- { 0, 2, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 2},
- { 0, 2, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 2},
- { 2, 0, 2, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2},
- { 2, 0, 2, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2},
- { 2, 2, 0, 2, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2},
- { 2, 2, 0, 2, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2},
- { 2, 2, 2, 0, 2, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2},
- { 2, 2, 2, 0, 2, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2},
- { 2, 2, 2, 2, 0, 2, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2},
- { 2, 2, 2, 2, 0, 2, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2},
- { 2, 2, 2, 2, 2, 0, 2, 2, 2, 2, 2, 2, 2, 1, 2, 2},
- { 2, 2, 2, 2, 2, 0, 2, 2, 2, 2, 2, 2, 2, 1, 2, 2},
- { 2, 2, 2, 2, 2, 2, 0, 2, 2, 2, 2, 2, 2, 2, 1, 2},
- { 2, 2, 2, 2, 2, 2, 0, 2, 2, 2, 2, 2, 2, 2, 1, 2},
- { 2, 2, 2, 2, 2, 2, 2, 0, 2, 2, 2, 2, 2, 2, 2, 1},
- { 2, 2, 2, 2, 2, 2, 2, 0, 2, 2, 2, 2, 2, 2, 2, 1}
-};
-
-
-static inline unsigned int hamming_distance2(unsigned int w) {
-
- return (w & 1) + !!(w & 2);
-}
-
-
-/*
-static void conv_encode(unsigned char *data, unsigned char *output) {
-
- unsigned int i, state = 0, o;
-
- // encode data
- for(i = 0; i < CONV_INPUT_SIZE; i++) {
- o = encode[state][data[i]];
- state = next_state[state][data[i]];
- *output++ = !!(o & 2);
- *output++ = o & 1;
- }
-}
- */
-
-
-static int conv_decode(unsigned char *output, unsigned char *data) {
-
- int i, t;
- unsigned int rdata, state, nstate, b, o, distance, accumulated_error,
- min_state, min_error, cur_state;
-
- unsigned int ae[1 << (K - 1)];
- unsigned int nae[1 << (K - 1)]; // next accumulated error
- unsigned int state_history[1 << (K - 1)][CONV_INPUT_SIZE + 1];
-
- // initialize accumulated error, assume starting state is 0
- for(i = 0; i < (1 << (K - 1)); i++)
- ae[i] = nae[i] = MAX_ERROR;
- ae[0] = 0;
-
- // build trellis
- for(t = 0; t < CONV_INPUT_SIZE; t++) {
-
- // get received data symbol
- rdata = (data[2 * t] << 1) | data[2 * t + 1];
-
- // for each state
- for(state = 0; state < (1 << (K - 1)); state++) {
-
- // make sure this state is possible
- if(ae[state] >= MAX_ERROR)
- continue;
-
- // find all states we lead to
- for(b = 0; b < 2; b++) {
-
- // get next state given input bit b
- nstate = next_state[state][b];
-
- // find output for this transition
- o = encode[state][b];
-
- // calculate distance from received data
- distance = hamming_distance2(rdata ^ o);
-
- // choose surviving path
- accumulated_error = ae[state] + distance;
- if(accumulated_error < nae[nstate]) {
-
- // save error for surviving state
- nae[nstate] = accumulated_error;
-
- // update state history
- state_history[nstate][t + 1] = state;
- }
- }
- }
-
- // get accumulated error ready for next time slice
- for(i = 0; i < (1 << (K - 1)); i++) {
- ae[i] = nae[i];
- nae[i] = MAX_ERROR;
- }
- }
-
- // the final state is the state with the fewest errors
- min_state = (unsigned int)-1;
- min_error = MAX_ERROR;
- for(i = 0; i < (1 << (K - 1)); i++) {
- if(ae[i] < min_error) {
- min_state = i;
- min_error = ae[i];
- }
- }
-
- // trace the path
- cur_state = min_state;
- for(t = CONV_INPUT_SIZE; t >= 1; t--) {
- min_state = cur_state;
- cur_state = state_history[cur_state][t]; // get previous
- output[t - 1] = prev_next_state[cur_state][min_state];
- }
-
- // return the number of errors detected (hard-decision)
- return min_error;
-}
-
-
-/*
- * GSM SACCH interleaving and burst mapping
- *
- * Interleaving:
- *
- * Given 456 coded input bits, form 4 blocks of 114 bits:
- *
- * i(B, j) = c(n, k) k = 0, ..., 455
- * n = 0, ..., N, N + 1, ...
- * B = B_0 + 4n + (k mod 4)
- * j = 2(49k mod 57) + ((k mod 8) div 4)
- *
- * Mapping on Burst:
- *
- * e(B, j) = i(B, j)
- * e(B, 59 + j) = i(B, 57 + j) j = 0, ..., 56
- * e(B, 57) = h_l(B)
- * e(B, 58) = h_n(B)
- *
- * Where h_l(B) and h_n(B) are bits in burst B indicating flags.
- */
-
-/*
-static void interleave(unsigned char *data, unsigned char *iBLOCK) {
-
- int j, k, B;
-
- // for each bit in input data
- for(k = 0; k < CONV_SIZE; k++) {
- B = k % 4;
- j = 2 * ((49 * k) % 57) + ((k % 8) / 4);
- iBLOCK[B * iBLOCK_SIZE + j] = data[k];
- }
-}
- */
-
-
-#if 0
-static void decode_interleave(unsigned char *data, unsigned char *iBLOCK) {
-
- int j, k, B;
-
- for(k = 0; k < CONV_SIZE; k++) {
- B = k % 4;
- j = 2 * ((49 * k) % 57) + ((k % 8) / 4);
- data[k] = iBLOCK[B * iBLOCK_SIZE + j];
- }
-}
-
-#endif
-
-/*
-static void burstmap(unsigned char *iBLOCK, unsigned char *eBLOCK,
- unsigned char hl, unsigned char hn) {
-
- int j;
-
- for(j = 0; j < 57; j++) {
- eBLOCK[j] = iBLOCK[j];
- eBLOCK[j + 59] = iBLOCK[j + 57];
- }
- eBLOCK[57] = hl;
- eBLOCK[58] = hn;
-}
- */
-
-
-static void decode_burstmap(unsigned char *iBLOCK, unsigned char *eBLOCK,
- unsigned char *hl, unsigned char *hn) {
-
- int j;
-
- for(j = 0; j < 57; j++) {
- iBLOCK[j] = eBLOCK[j];
- iBLOCK[j + 57] = eBLOCK[j + 59];
- }
- *hl = eBLOCK[57];
- *hn = eBLOCK[58];
-}
-
-
-/*
- * Transmitted bits are sent least-significant first.
- */
-static int compress_bits(unsigned char *dbuf, unsigned int dbuf_len,
- unsigned char *sbuf, unsigned int sbuf_len) {
-
- unsigned int i, j, c, pos = 0;
-
- if(dbuf_len < ((sbuf_len + 7) >> 3))
- return -1;
-
- for(i = 0; i < sbuf_len; i += 8) {
- for(j = 0, c = 0; (j < 8) && (i + j < sbuf_len); j++)
- c |= (!!sbuf[i + j]) << j;
- dbuf[pos++] = c & 0xff;
- }
- return pos;
-}
-
-
-#if 0
-int get_ns_l3_len(unsigned char *data, unsigned int datalen) {
-
- if((data[0] & 3) != 1) {
- fprintf(stderr, "error: get_ns_l3_len: pseudo-length reserved "
- "bits bad (%2.2x)\n", data[0] & 3);
- return -1;
- }
- return (data[0] >> 2);
-}
-
-#endif
-
-
-static unsigned char *decode_sacch(GS_CTX *ctx, unsigned char *burst, unsigned int *datalen) {
-
- int errors, len, data_size;
- unsigned char conv_data[CONV_SIZE], iBLOCK[BLOCKS][iBLOCK_SIZE],
- hl, hn, decoded_data[PARITY_OUTPUT_SIZE];
- FC_CTX fc_ctx;
-
- data_size = sizeof ctx->msg;
- if(datalen)
- *datalen = 0;
-
- // unmap the bursts
- decode_burstmap(iBLOCK[0], burst, &hl, &hn); // XXX ignore stealing bits
- decode_burstmap(iBLOCK[1], burst + 116, &hl, &hn);
- decode_burstmap(iBLOCK[2], burst + 116 * 2, &hl, &hn);
- decode_burstmap(iBLOCK[3], burst + 116 * 3, &hl, &hn);
-
- // remove interleave
- interleave_decode(&ctx->interleave_ctx, conv_data, (unsigned char *)iBLOCK);
- //decode_interleave(conv_data, (unsigned char *)iBLOCK);
-
- // Viterbi decode
- errors = conv_decode(decoded_data, conv_data);
- //DEBUGF("conv_decode: %d\n", errors);
- if (errors)
- return NULL;
-
- // check parity
- // If parity check error detected try to fix it.
- if (parity_check(decoded_data))
- {
- FC_init(&fc_ctx, 40, 184);
- unsigned char crc_result[224];
- if (FC_check_crc(&fc_ctx, decoded_data, crc_result) == 0)
- {
- errors = -1;
- DEBUGF("error: sacch: parity error (%d)\n", errors);
- return NULL;
- } else {
- DEBUGF("Successfully corrected parity bits!\n");
- memcpy(decoded_data, crc_result, sizeof crc_result);
- errors = 0;
- }
- }
-
- if((len = compress_bits(ctx->msg, data_size, decoded_data,
- DATA_BLOCK_SIZE)) < 0) {
- fprintf(stderr, "error: compress_bits\n");
- return NULL;
- }
- if(len < data_size) {
- fprintf(stderr, "error: buf too small (%d < %d)\n",
- sizeof(ctx->msg), len);
- return NULL;
- }
-
- if(datalen)
- *datalen = (unsigned int)len;
- return ctx->msg;
-}
-
-
-/*
- * decode_cch
- *
- * Decode a "common" control channel. Most control channels use
- * the same burst, interleave, Viterbi and parity configuration.
- * The documentation for the control channels defines SACCH first
- * and then just keeps referring to that.
- *
- * The current (investigated) list is as follows:
- *
- * BCCH Norm
- * BCCH Ext
- * PCH
- * AGCH
- * CBCH (SDCCH/4)
- * CBCH (SDCCH/8)
- * SDCCH/4
- * SACCH/C4
- * SDCCH/8
- * SACCH/C8
- *
- * We provide two functions, one for where all four bursts are
- * contiguous, and one where they aren't.
- */
-unsigned char *decode_cch(GS_CTX *ctx, unsigned char *burst, unsigned int *datalen) {
-
- return decode_sacch(ctx, burst, datalen);
-}
-
-
-#if 0
-unsigned char *decode_cch(GS_CTX *ctx, unsigned char *e, unsigned int *datalen) {
-
- return decode_sacch(ctx, e, e + eBLOCK_SIZE, e + 2 * eBLOCK_SIZE,
- e + 3 * eBLOCK_SIZE, datalen);
-}
-#endif
diff --git a/src/lib/decoder/cch.h b/src/lib/decoder/cch.h
deleted file mode 100644
index a642721..0000000
--- a/src/lib/decoder/cch.h
+++ /dev/null
@@ -1,56 +0,0 @@
-//TODO: this file shouldn't be part of the GSM Receiver
-#ifndef __GSMSTACK_CCH_H__
-#define __GSMSTACK_CCH_H__ 1
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#include "gsmstack.h"
-
-/*
- * decode_cch
- *
- * Decode a "common" control channel. Most control channels use
- * the same burst, interleave, Viterbi and parity configuration.
- * The documentation for the control channels defines SACCH first
- * and then just keeps referring to that.
- *
- * The current (investigated) list is as follows:
- *
- * BCCH Norm
- * BCCH Ext
- * PCH
- * AGCH
- * CBCH (SDCCH/4)
- * CBCH (SDCCH/8)
- * SDCCH/4
- * SACCH/C4
- * SDCCH/8
- * SACCH/C8
- *
- * We provide two functions, one for where all four bursts are
- * contiguous, and one where they aren't.
- */
-
-#define DATA_BLOCK_SIZE 184
-#define PARITY_SIZE 40
-#define FLUSH_BITS_SIZE 4
-#define PARITY_OUTPUT_SIZE (DATA_BLOCK_SIZE + PARITY_SIZE + FLUSH_BITS_SIZE)
-
-#define CONV_INPUT_SIZE PARITY_OUTPUT_SIZE
-#define CONV_SIZE (2 * CONV_INPUT_SIZE)
-
-#define BLOCKS 4
-#define iBLOCK_SIZE (CONV_SIZE / BLOCKS)
-#define eBLOCK_SIZE (iBLOCK_SIZE + 2)
-
-unsigned char *decode_cch(GS_CTX *ctx, unsigned char *burst, unsigned int *len);
-//unsigned char *decode_cch(GS_CTX *ctx, unsigned char *, unsigned char *, unsigned char *, unsigned char *, unsigned int *len);
-//unsigned char *decode_cch(GS_CTX *ctx, unsigned char *, unsigned int *);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
diff --git a/src/lib/decoder/fire_crc.c b/src/lib/decoder/fire_crc.c
deleted file mode 100644
index 7cdfc0b..0000000
--- a/src/lib/decoder/fire_crc.c
+++ /dev/null
@@ -1,179 +0,0 @@
-//TODO: this file shouldn't be part of the GSM Receiver
-/* -*- c++ -*- */
-/*
- * Copyright 2005 Free Software Foundation, Inc.
- *
- * This file is part of GNU Radio
- *
- * GNU Radio 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, or (at your option)
- * any later version.
- *
- * GNU Radio 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 GNU Radio; see the file COPYING. If not, write to
- * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-#include "fire_crc.h"
-#include <stdio.h>
-#include <string.h>
-
-#define REM(x, y) (x) % (y)
-
-static int FC_syndrome_shift(FC_CTX *ctx, unsigned int bit);
-
-static int
-outit(int *data, int len)
-{
- int i;
-
- for (i = 0; i < len; i++)
- printf("%d ", data[i]);
- printf("\n");
-}
-
-int
-FC_init(FC_CTX *ctx, unsigned int crc_size, unsigned int data_size)
-{
- ctx->crc_size = crc_size;
- ctx->data_size = data_size;
- ctx->syn_start = 0;
-
- return 0;
-}
-
-int
-FC_check_crc(FC_CTX *ctx, unsigned char *input_bits, unsigned char *control_data)
-{
- int j,error_count = 0, error_index = 0, success_flag = 0, syn_index = 0;
- unsigned int i;
-
- ctx->syn_start = 0;
- // reset the syndrome register
- memset(ctx->syndrome_reg, 0, sizeof ctx->syndrome_reg);
-
- // shift in the data bits
- for (i=0; i < ctx->data_size; i++) {
- error_count = FC_syndrome_shift(ctx, input_bits[i]);
- control_data[i] = input_bits[i];
- }
-
- // shift in the crc bits
- for (i=0; i < ctx->crc_size; i++) {
- error_count = FC_syndrome_shift(ctx, 1-input_bits[i+ctx->data_size]);
- }
-
- // Find position of error burst
- if (error_count == 0) {
- error_index = 0;
- }
- else {
- error_index = 1;
- error_count = FC_syndrome_shift(ctx, 0);
- error_index += 1;
- while (error_index < (ctx->data_size + ctx->crc_size) ) {
- error_count = FC_syndrome_shift(ctx, 0);
- error_index += 1;
- if ( error_count == 0 ) break;
- }
- }
-
- // Test for correctable errors
- //printf("error_index %d\n",error_index);
- if (error_index == 224) success_flag = 0;
- else {
-
- // correct index depending on the position of the error
- if (error_index == 0) syn_index = error_index;
- else syn_index = error_index - 1;
-
- // error burst lies within data bits
- if (error_index < 184) {
- //printf("error < bit 184,%d\n",error_index);
- j = error_index;
- while ( j < (error_index+12) ) {
- if (j < 184) {
- control_data[j] = control_data[j] ^
- ctx->syndrome_reg[REM(ctx->syn_start+39-j+syn_index,40)];
- }
- else break;
- j = j + 1;
- }
- }
- else if ( error_index > 212 ) {
- //printf("error > bit 212,%d\n",error_index);
- j = 0;
- while ( j < (error_index - 212) ) {
- control_data[j] = control_data[j] ^
- ctx->syndrome_reg[REM(ctx->syn_start+39-j-224+syn_index,40)];
- j = j + 1;
- }
- }
- // for 183 < error_index < 213 error in parity alone so ignore
- success_flag = 1;
- }
- return success_flag;
-}
-
-static int
-FC_syndrome_shift(FC_CTX *ctx, unsigned int bit)
-{
- int error_count = 0;
- unsigned int i;
-
- if (ctx->syn_start == 0)
- ctx->syn_start = 39;
- else ctx->syn_start -= 1;
-
- int temp_syndrome_reg[sizeof ctx->syndrome_reg];
-
- memcpy(temp_syndrome_reg, ctx->syndrome_reg, sizeof temp_syndrome_reg);
-
- temp_syndrome_reg[REM(ctx->syn_start+3,40)] =
- ctx->syndrome_reg[REM(ctx->syn_start+3,40)] ^
- ctx->syndrome_reg[ctx->syn_start];
- temp_syndrome_reg[REM(ctx->syn_start+17,40)] =
- ctx->syndrome_reg[REM(ctx->syn_start+17,40)] ^
- ctx->syndrome_reg[ctx->syn_start];
- temp_syndrome_reg[REM(ctx->syn_start+23,40)] =
- ctx->syndrome_reg[REM(ctx->syn_start+23,40)] ^
- ctx->syndrome_reg[ctx->syn_start];
- temp_syndrome_reg[REM(ctx->syn_start+26,40)] =
- ctx->syndrome_reg[REM(ctx->syn_start+26,40)] ^
- ctx->syndrome_reg[ctx->syn_start];
-
- temp_syndrome_reg[REM(ctx->syn_start+4,40)] =
- ctx->syndrome_reg[REM(ctx->syn_start+4,40)] ^ bit;
- temp_syndrome_reg[REM(ctx->syn_start+6,40)] =
- ctx->syndrome_reg[REM(ctx->syn_start+6,40)] ^ bit;
- temp_syndrome_reg[REM(ctx->syn_start+10,40)] =
- ctx->syndrome_reg[REM(ctx->syn_start+10,40)] ^ bit;
- temp_syndrome_reg[REM(ctx->syn_start+16,40)] =
- ctx->syndrome_reg[REM(ctx->syn_start+16,40)] ^ bit;
- temp_syndrome_reg[REM(ctx->syn_start+27,40)] =
- ctx->syndrome_reg[REM(ctx->syn_start+27,40)] ^ bit;
- temp_syndrome_reg[REM(ctx->syn_start+29,40)] =
- ctx->syndrome_reg[REM(ctx->syn_start+29,40)] ^ bit;
- temp_syndrome_reg[REM(ctx->syn_start+33,40)] =
- ctx->syndrome_reg[REM(ctx->syn_start+33,40)] ^ bit;
- temp_syndrome_reg[REM(ctx->syn_start+39,40)] =
- ctx->syndrome_reg[REM(ctx->syn_start+39,40)] ^ bit;
-
- temp_syndrome_reg[ctx->syn_start] = ctx->syndrome_reg[ctx->syn_start] ^ bit;
-
- memcpy(ctx->syndrome_reg, temp_syndrome_reg, sizeof ctx->syndrome_reg);
-
- for (i = 0; i < 28; i++) {
- error_count = error_count + ctx->syndrome_reg[REM(ctx->syn_start+i,40)];
- }
- return error_count;
-}
-
-
diff --git a/src/lib/decoder/fire_crc.h b/src/lib/decoder/fire_crc.h
deleted file mode 100644
index aa6319c..0000000
--- a/src/lib/decoder/fire_crc.h
+++ /dev/null
@@ -1,47 +0,0 @@
-//TODO: this file shouldn't be part of the GSM Receiver
-/* -*- c++ -*- */
-/*
- * Copyright 2005 Free Software Foundation, Inc.
- *
- * This file is part of GNU Radio
- *
- * GNU Radio 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, or (at your option)
- * any later version.
- *
- * GNU Radio 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 GNU Radio; see the file COPYING. If not, write to
- * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-
-#ifndef INCLUDED_FIRE_CRC_H
-#define INCLUDED_FIRE_CRC_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-typedef struct
-{
- unsigned int crc_size;
- unsigned int data_size;
- unsigned int syn_start;
- int syndrome_reg[40];
-} FC_CTX;
-
-int FC_init(FC_CTX *ctx, unsigned int crc_size, unsigned int data_size);
-int FC_check_crc(FC_CTX *ctx, unsigned char *input_bits, unsigned char *control_data);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
diff --git a/src/lib/decoder/gsmstack.c b/src/lib/decoder/gsmstack.c
deleted file mode 100644
index c3f1921..0000000
--- a/src/lib/decoder/gsmstack.c
+++ /dev/null
@@ -1,206 +0,0 @@
-/*
- * Invoke gsmstack() with any kind of burst. Automaticly decode and retrieve
- * information.
- */
-#include "system.h"
-#include <stdlib.h>
-#include <stdio.h>
-#include <errno.h>
-#include <string.h>
-#include "gsmstack.h"
-//#include "gsm_constants.h"
-#include "interleave.h"
-//#include "sch.h"
-#include "cch.h"
-
-static const int USEFUL_BITS = 142;
-
-//#include "out_pcap.h"
-enum BURST_TYPE {
- UNKNOWN,
- FCCH,
- PARTIAL_SCH, //successful correlation, but missing data ^
- SCH,
- CTS_SCH,
- COMPACT_SCH,
- NORMAL,
- DUMMY,
- ACCESS
-};
-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)
-{
- const char *end = src + len;
- unsigned char last;
-
- src += 3;
- last = 0;
- memset(dst, 0, 3);
- dst += 3;
-
- while (src < end)
- {
- *dst = !*src ^ last;
- last = *dst;
- src++;
- dst++;
- }
-}
-#endif
-
-/*
- * Initialize a new GSMSTACK context.
- */
-int
-GS_new(GS_CTX *ctx)
-{
- memset(ctx, 0, sizeof *ctx);
- interleave_init(&ctx->interleave_ctx, 456, 114);
- ctx->fn = -1;
- ctx->bsic = -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));
-
- return 0;
-}
-
-#define BURST_BYTES ((USEFUL_BITS/8)+1)
-/*
- * 142 bit
- */
-int
-GS_process(GS_CTX *ctx, int ts, int type, const unsigned char *src, int fn)
-{
-// int fn;
- int bsic;
- 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);
- if (data == NULL)
- return -1;
-// write_pcap_packet(ctx->pcap_fd, 0 /* arfcn */, ts, ctx->fn, data, len);
- return;
- }
-#endif
-
-/* 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 we did not get Frame Number yet then return */
-// if (ctx->fn < 0)
-// return 0;
-
-// ctx->fn++;
-// }
- ctx->fn = 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(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 (ts_ctx->burst_count < 4)
- return 0;
-
- 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,
- 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;
-#endif
-
- return 0;
- }
-}
-
-
-/*
- * Output data so that it can be parsed from gsmdeocde.
- */
-static void
-out_gsmdecode(char type, int arfcn, int ts, int fn, char *data, int len)
-{
- char *end = data + len;
-
- /* FIXME: speed this up by first printing into an array */
- while (data < end)
- printf(" %02.2x", (unsigned char)*data++);
- printf("\n");
- fflush(stdout);
-}
diff --git a/src/lib/decoder/gsmstack.h b/src/lib/decoder/gsmstack.h
deleted file mode 100644
index 9355785..0000000
--- a/src/lib/decoder/gsmstack.h
+++ /dev/null
@@ -1,43 +0,0 @@
-//TODO: this file shouldn't be part of the GSM Receiver
-#ifndef __GSMSTACK_H__
-#define __GSMSTACK_H__ 1
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#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;
-
- 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);
-int GS_process(GS_CTX *ctx, int ts, int type, const unsigned char *src, int fn);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
diff --git a/src/lib/decoder/gsmtap.h b/src/lib/decoder/gsmtap.h
deleted file mode 100644
index 1022194..0000000
--- a/src/lib/decoder/gsmtap.h
+++ /dev/null
@@ -1,41 +0,0 @@
-#ifndef _GSMTAP_H
-#define _GSMTAP_H
-
-/* gsmtap header, pseudo-header in front of the actua GSM payload*/
-
-#include <sys/types.h>
-
-#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 */
- 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) */
-
- u_int16_t arfcn; /* ARFCN (frequency) */
- u_int8_t noise_db; /* noise figure in dB */
- u_int8_t signal_db; /* signal level in dB */
-
- 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/src/lib/decoder/interleave.c b/src/lib/decoder/interleave.c
deleted file mode 100644
index 7b45927..0000000
--- a/src/lib/decoder/interleave.c
+++ /dev/null
@@ -1,47 +0,0 @@
-//TODO: this file shouldn't be part of the GSM Receiver
-#include <stdlib.h>
-#include <stdio.h>
-#include "interleave.h"
-
-int
-interleave_init(INTERLEAVE_CTX *ictx, int size, int block_size)
-{
- ictx->trans_size = size;
- ictx->trans = (unsigned short *)malloc(size * sizeof *ictx->trans);
-
-// DEBUGF("size: %d\n", size);
-// DEBUGF("Block size: %d\n", block_size);
- int j, k, B;
- for (k = 0; k < size; k++)
- {
- B = k % 4;
- j = 2 * ((49 * k) % 57) + ((k % 8) / 4);
- ictx->trans[k] = B * block_size + j;
- /* Mapping: pos1 goes to pos2: pos1 -> pos2 */
-// DEBUGF("%d -> %d\n", ictx->trans[k], k);
- }
-// exit(0);
- return 0;
-}
-
-int
-interleave_deinit(INTERLEAVE_CTX *ictx)
-{
- if (ictx->trans != NULL)
- {
- free(ictx->trans);
- ictx->trans = NULL;
- }
-
- return 0;
-}
-
-void
-interleave_decode(INTERLEAVE_CTX *ictx, unsigned char *dst, unsigned char *src)
-{
-
- int k;
- for (k = 0; k < ictx->trans_size; k++)
- dst[k] = src[ictx->trans[k]];
-}
-
diff --git a/src/lib/decoder/interleave.h b/src/lib/decoder/interleave.h
deleted file mode 100644
index fa1912f..0000000
--- a/src/lib/decoder/interleave.h
+++ /dev/null
@@ -1,19 +0,0 @@
-//TODO: this file shouldn't be part of the GSM Receiver
-/*
- * $Id:$
- */
-
-#ifndef __GSMSP_INTERLEAVE_H__
-#define __GSMSP_INTERLEAVE_H__ 1
-
-typedef struct _interleave_ctx
-{
- unsigned short *trans;
- int trans_size;
-} INTERLEAVE_CTX;
-
-int interleave_init(INTERLEAVE_CTX *ictx, int size, int block_size);
-int interleave_deinit(INTERLEAVE_CTX *ictx);
-void interleave_decode(INTERLEAVE_CTX *ictx, unsigned char *dst, unsigned char *src);
-
-#endif
diff --git a/src/lib/decoder/openbtsstuff/AUTHORS b/src/lib/decoder/openbtsstuff/AUTHORS
deleted file mode 100644
index 8075492..0000000
--- a/src/lib/decoder/openbtsstuff/AUTHORS
+++ /dev/null
@@ -1,173 +0,0 @@
-#
-# Copyright 2008 Free Software Foundation, Inc.
-#
-# This file is part of GNU Radio
-#
-# GNU Radio 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 3, or (at your option)
-# any later version.
-#
-# GNU Radio 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.
-#
-
-David A. Burgess, dburgess@kestrelsp.com:
- CommonLibs/Assert.h
- CommonLibs/BitVector.cpp
- CommonLibs/BitVectorTest.cpp
- CommonLibs/Interthread.h
- CommonLibs/InterthreadTest.cpp
- CommonLibs/LinkedLists.cpp
- CommonLibs/LinkedLists.h
- CommonLibs/Sockets.cpp
- CommonLibs/Sockets.h
- CommonLibs/SocketsTest.cpp
- CommonLibs/Threads.cpp
- CommonLibs/Threads.h
- CommonLibs/Timeval.cpp
- CommonLibs/Timeval.h
- CommonLibs/TimevalTest.cpp
- CommonLibs/Vector.h
- CommonLibs/VectorTest.cpp
- Control/CallControl.cpp
- Control/ControlCommon.cpp
- Control/ControlCommon.h
- Control/FACCHDispatch.cpp
- Control/MobilityManagement.cpp
- Control/PagerTest.cpp
- Control/RadioResource.cpp
- Control/SDCCHDispatch.cpp
- GSM/GSM610Tables.cpp
- GSM/GSM610Tables.h
- GSM/GSMCommon.cpp
- GSM/GSMCommon.h
- GSM/GSMConfig.h
- GSM/GSML1FEC.cpp
- GSM/GSML1FEC.h
- GSM/GSML2LAPDm.cpp
- GSM/GSML2LAPDm.h
- GSM/GSML3CCElements.cpp
- GSM/GSML3CCElements.h
- GSM/GSML3CCMessages.cpp
- GSM/GSML3CCMessages.h
- GSM/GSML3CommonElements.cpp
- GSM/GSML3CommonElements.h
- GSM/GSML3MMElements.cpp
- GSM/GSML3MMElements.h
- GSM/GSML3MMMessages.cpp
- GSM/GSML3MMMessages.h
- GSM/GSML3Message.cpp
- GSM/GSML3Message.h
- GSM/GSML3RRElements.cpp
- GSM/GSML3RRElements.h
- GSM/GSML3RRMessages.cpp
- GSM/GSML3RRMessages.h
- GSM/GSMLogicalChannel.h
- GSM/GSMTDMA.cpp
- GSM/GSMTDMA.h
- GSM/GSMTransfer.cpp
- GSM/GSMTransfer.h
- LICENSEBLOCK
- SIP/SIPEngine.h
- SIP/SIPInterface.h
- TRXManager/TRXManager.cpp
- Transceiver/Complex.h
- apps/OpenBTS900.cpp
- tests/AGCHTest.cpp
- tests/BeaconTest.cpp
- tests/CallTest.cpp
- tests/CallTest2.cpp
- tests/LAPDmTest.cpp
- tests/LoopbackTest.cpp
- tests/RegistrationTest.cpp
- tests/TRXSimulator.cpp
-
-Harvind S. Samra, hssamra@kestrelsp.com:
- Control/PagerTest.cpp
- Control/RadioResource.cpp
- GSM/GSMConfig.h
- GSM/GSMTransfer.h
- LICENSEBLOCK
- Transceiver/ComplexTest.cpp
- Transceiver/Transceiver.cpp
- Transceiver/Transceiver.h
- Transceiver/USRPDevice.cpp
- Transceiver/USRPDevice.h
- Transceiver/USRPping.cpp
- Transceiver/radioInterface.cpp
- Transceiver/radioInterface.h
- Transceiver/rcvLPF_651.h
- Transceiver/runTransceiver.cpp
- Transceiver/sendLPF_961.h
- Transceiver/sigProcLib.cpp
- Transceiver/sigProcLib.h
- Transceiver/sigProcLibTest.cpp
- Transceiver/sweepGenerator.cpp
- Transceiver/testRadio.cpp
-
-Raffi Sevlian, raffisev@gmail.com:
- Control/CallControl.cpp
- Control/ControlCommon.cpp
- Control/ControlCommon.h
- Control/FACCHDispatch.cpp
- Control/MobilityManagement.cpp
- Control/PagerTest.cpp
- Control/RadioResource.cpp
- GSM/GSMCommon.h
- GSM/GSMConfig.h
- GSM/GSML1FEC.h
- GSM/GSML3CCElements.cpp
- GSM/GSML3CCElements.h
- GSM/GSML3CCMessages.cpp
- GSM/GSML3CCMessages.h
- GSM/GSML3CommonElements.cpp
- GSM/GSML3CommonElements.h
- GSM/GSML3MMElements.cpp
- GSM/GSML3MMElements.h
- GSM/GSML3MMMessages.cpp
- GSM/GSML3MMMessages.h
- GSM/GSML3Message.cpp
- GSM/GSML3Message.h
- GSM/GSML3RRElements.cpp
- GSM/GSML3RRElements.h
- GSM/GSML3RRMessages.cpp
- GSM/GSML3RRMessages.h
- GSM/GSMLogicalChannel.h
- GSM/GSMSAPMux.cpp
- GSM/GSMSAPMux.h
- GSM/GSMTransfer.h
- LICENSEBLOCK
- SIP/SIPEngine.cpp
- SIP/SIPInterface.cpp
- SIP/SIPInterface.h
- SIP/SIPMessage.cpp
- SIP/SIPMessage.h
- SIP/SIPUtility.cpp
- SIP/SIPUtility.h
- SMS/CMMessage.cpp
- SMS/CMMessage.h
- SMS/CMProcessor.cpp
- SMS/CMProcessor.h
- SMS/CMTest.cpp
- SMS/RLMessage.cpp
- SMS/RLMessage.h
- SMS/RLProcessor.cpp
- SMS/RLProcessor.h
- SMS/SMSMessages.cpp
- SMS/SMSMessages.h
- SMS/SMSProcessors.cpp
- SMS/SMSProcessors.h
- SMS/SMSTransfer.cpp
- SMS/SMSTransfer.h
- SMS/TLMessage.cpp
- SMS/TLMessage.h
- SMS/TLProcessor.cpp
- SMS/TLProcessor.h
- TRXManager/TRXManager.h
diff --git a/src/lib/decoder/openbtsstuff/Assert.h b/src/lib/decoder/openbtsstuff/Assert.h
deleted file mode 100644
index 00ad07d..0000000
--- a/src/lib/decoder/openbtsstuff/Assert.h
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
-* Copyright 2008 Free Software Foundation, Inc.
-*
-* This software is distributed under the terms of the GNU Public License.
-* See the COPYING file in the main directory for details.
-
- 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 3 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, see <http://www.gnu.org/licenses/>.
-
-*/
-
-
-#ifndef ASSERT_H
-#define ASSERT_H
-
-#include "stdio.h"
-
-/** This is thrown by assert() so that gdb can catch it. */
-class Assertion {
-
- public:
-
- Assertion()
- {
- fprintf(stderr,"Try setting a breakpoint @ %s:%u.\n",__FILE__,__LINE__);
- return;
- }
-
-};
-
-#ifdef NDEBUG
-#define assert(EXPR) {};
-#else
-/** This replaces the regular assert() with a C++ exception. */
-#include "stdio.h"
-#define assert(E) { if (!(E)) { fprintf(stderr,"%s:%u failed assertion '%s'\n",__FILE__,__LINE__,#E); throw Assertion(); } }
-#endif
-
-#endif
diff --git a/src/lib/decoder/openbtsstuff/BitVector.cpp b/src/lib/decoder/openbtsstuff/BitVector.cpp
deleted file mode 100644
index 89d8d19..0000000
--- a/src/lib/decoder/openbtsstuff/BitVector.cpp
+++ /dev/null
@@ -1,513 +0,0 @@
-/*
-* Copyright 2008 Free Software Foundation, Inc.
-*
-* This software is distributed under the terms of the GNU Public License.
-* See the COPYING file in the main directory for details.
-
- 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 3 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, see <http://www.gnu.org/licenses/>.
-
-*/
-
-
-
-
-#include "BitVector.h"
-#include <iostream>
-
-using namespace std;
-
-
-/**
- Apply a Galois polymonial to a binary seqeunce.
- @param val The input sequence.
- @param poly The polynomial.
- @param order The order of the polynomial.
- @return Single-bit result.
-*/
-unsigned applyPoly(uint64_t val, uint64_t poly, unsigned order)
-{
- uint64_t prod = val & poly;
- unsigned sum = prod;
- for (unsigned i=1; i<order; i++) sum ^= prod>>i;
- return sum & 0x01;
-}
-
-
-
-
-
-
-BitVector::BitVector(const char *valString)
- :Vector<char>(strlen(valString))
-{
- uint32_t accum = 0;
- for (size_t i=0; i<size(); i++) {
- accum <<= 1;
- if (valString[i]=='1') accum |= 0x01;
- mStart[i] = accum;
- }
-}
-
-
-
-
-
-uint64_t BitVector::peekField(size_t readIndex, unsigned length) const
-{
- uint64_t accum = 0;
- char *dp = mStart + readIndex;
- assert(dp+length <= mEnd);
- for (unsigned i=0; i<length; i++) {
- accum = (accum<<1) | ((*dp++) & 0x01);
- }
- return accum;
-}
-
-
-uint64_t BitVector::readField(size_t& readIndex, unsigned length) const
-{
- const uint64_t retVal = peekField(readIndex,length);
- readIndex += length;
- return retVal;
-}
-
-
-void BitVector::fillField(size_t writeIndex, uint64_t value, unsigned length)
-{
- char *dpBase = mStart + writeIndex;
- char *dp = dpBase + length - 1;
- assert(dp < mEnd);
- while (dp>=dpBase) {
- *dp-- = value & 0x01;
- value >>= 1;
- }
-}
-
-void BitVector::writeField(size_t& writeIndex, uint64_t value, unsigned length)
-{
- fillField(writeIndex,value,length);
- writeIndex += length;
-}
-
-
-void BitVector::invert()
-{
- for (size_t i=0; i<size(); i++) {
- mStart[i] = ~mStart[i];
- }
-}
-
-
-
-
-void BitVector::reverse8()
-{
- assert(size()>=8);
-
- char tmp0 = mStart[0];
- mStart[0] = mStart[7];
- mStart[7] = tmp0;
-
- char tmp1 = mStart[1];
- mStart[1] = mStart[6];
- mStart[6] = tmp1;
-
- char tmp2 = mStart[2];
- mStart[2] = mStart[5];
- mStart[5] = tmp2;
-
- char tmp3 = mStart[3];
- mStart[3] = mStart[4];
- mStart[4] = tmp3;
-}
-
-
-
-void BitVector::LSB8MSB()
-{
- size_t size8 = 8*(size()/8);
- size_t iTop = size8 - 8;
- for (size_t i=0; i<=iTop; i+=8) segment(i,8).reverse8();
-}
-
-
-
-uint64_t BitVector::syndrome(Generator& gen) const
-{
- gen.clear();
- const char *dp = mStart;
- while (dp<mEnd) gen.syndromeShift(*dp++);
- return gen.state();
-}
-
-
-uint64_t BitVector::parity(Generator& gen) const
-{
- gen.clear();
- const char *dp = mStart;
- while (dp<mEnd) gen.encoderShift(*dp++);
- return gen.state();
-}
-
-
-void BitVector::encode(const ViterbiR2O4& coder, BitVector& target)
-{
- size_t sz = size();
- assert(sz*coder.iRate() == target.size());
-
- // Build a "history" array where each element contains the full history.
- uint32_t history[sz];
- uint32_t accum = 0;
- for (size_t i=0; i<sz; i++) {
- accum = (accum<<1) | bit(i);
- history[i] = accum;
- }
-
- // Look up histories in the pre-generated state table.
- char *op = target.begin();
- for (size_t i=0; i<sz; i++) {
- unsigned index = coder.cMask() & history[i];
- for (unsigned g=0; g<coder.iRate(); g++) {
- *op++ = coder.stateTable(g,index);
- }
- }
-}
-
-
-
-unsigned BitVector::sum() const
-{
- unsigned sum = 0;
- for (size_t i=0; i<size(); i++) sum += mStart[i] & 0x01;
- return sum;
-}
-
-
-
-
-void BitVector::map(const unsigned *map, size_t mapSize, BitVector& dest) const
-{
- for (unsigned i=0; i<mapSize; i++) {
- dest.mStart[i] = mStart[map[i]];
- }
-}
-
-
-
-
-void BitVector::unmap(const unsigned *map, size_t mapSize, BitVector& dest) const
-{
- for (unsigned i=0; i<mapSize; i++) {
- dest.mStart[map[i]] = mStart[i];
- }
-}
-
-
-
-
-
-
-
-
-
-
-ostream& operator<<(ostream& os, const BitVector& hv)
-{
- for (size_t i=0; i<hv.size(); i++) {
- if (hv.bit(i)) os << '1';
- else os << '0';
- }
- return os;
-}
-
-
-
-
-ViterbiR2O4::ViterbiR2O4()
-{
- assert(mDeferral < 32);
- mCoeffs[0] = 0x019;
- mCoeffs[1] = 0x01b;
- computeStateTables(0);
- computeStateTables(1);
- computeGeneratorTable();
-}
-
-
-
-
-void ViterbiR2O4::initializeStates()
-{
- for (unsigned i=0; i<mIStates; i++) clear(mSurvivors[i]);
- for (unsigned i=0; i<mNumCands; i++) clear(mCandidates[i]);
-}
-
-
-
-void ViterbiR2O4::computeStateTables(unsigned g)
-{
- assert(g<mIRate);
- for (unsigned state=0; state<mIStates; state++) {
- // 0 input
- uint32_t inputVal = state<<1;
- mStateTable[g][inputVal] = applyPoly(inputVal, mCoeffs[g], mOrder+1);
- // 1 input
- inputVal |= 1;
- mStateTable[g][inputVal] = applyPoly(inputVal, mCoeffs[g], mOrder+1);
- }
-}
-
-void ViterbiR2O4::computeGeneratorTable()
-{
- for (unsigned index=0; index<mIStates*2; index++) {
- mGeneratorTable[index] = (mStateTable[0][index]<<1) | mStateTable[1][index];
- }
-}
-
-
-
-
-
-
-void ViterbiR2O4::branchCandidates()
-{
- // Branch to generate new input states.
- const vCand *sp = mSurvivors;
- for (unsigned i=0; i<mNumCands; i+=2) {
- // extend and suffix
- const uint32_t iState0 = (sp->iState) << 1; // input state for 0
- const uint32_t iState1 = iState0 | 0x01; // input state for 1
- const uint32_t oStateShifted = (sp->oState) << mIRate; // shifted output
- const float cost = sp->cost;
- sp++;
- // 0 input extension
- mCandidates[i].cost = cost;
- mCandidates[i].oState = oStateShifted | mGeneratorTable[iState0 & mCMask];
- mCandidates[i].iState = iState0;
- // 1 input extension
- mCandidates[i+1].cost = cost;
- mCandidates[i+1].oState = oStateShifted | mGeneratorTable[iState1 & mCMask];
- mCandidates[i+1].iState = iState1;
- }
-}
-
-
-void ViterbiR2O4::getSoftCostMetrics(const uint32_t inSample, const float *matchCost, const float *mismatchCost)
-{
- const float *cTab[2] = {matchCost,mismatchCost};
- for (unsigned i=0; i<mNumCands; i++) {
- vCand& thisCand = mCandidates[i];
- // We examine input bits 2 at a time for a rate 1/2 coder.
- const unsigned mismatched = inSample ^ (thisCand.oState);
- thisCand.cost += cTab[mismatched&0x01][1] + cTab[(mismatched>>1)&0x01][0];
- }
-}
-
-
-void ViterbiR2O4::pruneCandidates()
-{
- const vCand* c1 = mCandidates; // 0-prefix
- const vCand* c2 = mCandidates + mIStates; // 1-prefix
- for (unsigned i=0; i<mIStates; i++) {
- if (c1[i].cost < c2[i].cost) mSurvivors[i] = c1[i];
- else mSurvivors[i] = c2[i];
- }
-}
-
-
-const ViterbiR2O4::vCand& ViterbiR2O4::minCost() const
-{
- int minIndex = 0;
- float minCost = mSurvivors[0].cost;
- for (unsigned i=1; i<mIStates; i++) {
- const float thisCost = mSurvivors[i].cost;
- if (thisCost>=minCost) continue;
- minCost = thisCost;
- minIndex=i;
- }
- return mSurvivors[minIndex];
-}
-
-
-const ViterbiR2O4::vCand& ViterbiR2O4::step(uint32_t inSample, const float *probs, const float *iprobs)
-{
- branchCandidates();
- getSoftCostMetrics(inSample,probs,iprobs);
- pruneCandidates();
- return minCost();
-}
-
-
-uint64_t Parity::syndrome(const BitVector& receivedCodeword)
-{
- return receivedCodeword.syndrome(*this);
-}
-
-
-void Parity::writeParityWord(const BitVector& data, BitVector& parityTarget, bool invert)
-{
- uint64_t pWord = data.parity(*this);
- if (invert) pWord = ~pWord;
- parityTarget.fillField(0,pWord,size());
-}
-
-
-
-
-
-
-
-
-
-SoftVector::SoftVector(const BitVector& source)
-{
- resize(source.size());
- for (size_t i=0; i<size(); i++) {
- if (source.bit(i)) mStart[i]=1.0F;
- else mStart[i]=0.0F;
- }
-}
-
-
-BitVector SoftVector::sliced() const
-{
- size_t sz = size();
- BitVector newSig(sz);
- for (size_t i=0; i<sz; i++) {
- if (mStart[i]>0.5F) newSig[i]=1;
- else newSig[i] = 0;
- }
- return newSig;
-}
-
-
-
-void SoftVector::decode(ViterbiR2O4 &decoder, BitVector& target) const
-{
- const size_t sz = size();
- const unsigned deferral = decoder.deferral();
- const size_t ctsz = sz + deferral;
- assert(sz <= decoder.iRate()*target.size());
-
- // Build a "history" array where each element contains the full history.
- uint32_t history[ctsz];
- {
- BitVector bits = sliced();
- uint32_t accum = 0;
- for (size_t i=0; i<sz; i++) {
- accum = (accum<<1) | bits.bit(i);
- history[i] = accum;
- }
- // Repeat last bit at the end.
- for (size_t i=sz; i<ctsz; i++) {
- accum = (accum<<1) | (accum & 0x01);
- history[i] = accum;
- }
- }
-
- // Precompute metric tables.
- float matchCostTable[ctsz];
- float mismatchCostTable[ctsz];
- {
- const float *dp = mStart;
- for (size_t i=0; i<sz; i++) {
- // pVal is the probability that a bit is correct.
- // ipVal is the probability that a bit is correct.
- float pVal = dp[i];
- if (pVal>0.5F) pVal = 1.0F-pVal;
- float ipVal = 1.0F-pVal;
- // This is a cheap approximation to an ideal cost function.
- if (pVal<0.01F) pVal = 0.01;
- if (ipVal<0.01F) ipVal = 0.01;
- matchCostTable[i] = 0.25F/ipVal;
- mismatchCostTable[i] = 0.25F/pVal;
- }
-
- // pad end of table with unknowns
- for (size_t i=sz; i<ctsz; i++) {
- matchCostTable[i] = 0.5F;
- mismatchCostTable[i] = 0.5F;
- }
- }
-
- {
- decoder.initializeStates();
- // Each sample of history[] carries its history.
- // So we only have to process every iRate-th sample.
- const unsigned step = decoder.iRate();
- // input pointer
- const uint32_t *ip = history + step - 1;
- // output pointers
- char *op = target.begin();
- const char *const opt = target.end();
- // table pointers
- const float* match = matchCostTable;
- const float* mismatch = mismatchCostTable;
- size_t oCount = 0;
- while (op<opt) {
- // Viterbi algorithm
- const ViterbiR2O4::vCand &minCost = decoder.step(*ip, match, mismatch);
- ip += step;
- match += step;
- mismatch += step;
- // output
- if (oCount>=deferral) *op++ = (minCost.iState >> deferral);
- oCount++;
- }
- }
-}
-
-
-
-
-ostream& operator<<(ostream& os, const SoftVector& sv)
-{
- for (size_t i=0; i<sv.size(); i++) {
- if (sv[i]<0.25) os << "0";
- else if (sv[i]>0.75) os << "1";
- else os << "-";
- }
- return os;
-}
-
-
-
-void BitVector::pack(unsigned char* targ) const
-{
- // Assumes MSB-first packing.
- unsigned bytes = size()/8;
- for (unsigned i=0; i<bytes; i++) {
- targ[i] = peekField(i*8,8);
- }
- unsigned whole = bytes*8;
- unsigned rem = size() - whole;
- if (rem==0) return;
- targ[bytes] = peekField(whole,rem) << (8-rem);
-}
-
-
-void BitVector::unpack(const unsigned char* src)
-{
- // Assumes MSB-first packing.
- unsigned bytes = size()/8;
- for (unsigned i=0; i<bytes; i++) {
- fillField(i*8,src[i],8);
- }
- unsigned whole = bytes*8;
- unsigned rem = size() - whole;
- if (rem==0) return;
- fillField(whole,src[bytes],rem);
-}
-
-// vim: ts=4 sw=4
diff --git a/src/lib/decoder/openbtsstuff/BitVector.h b/src/lib/decoder/openbtsstuff/BitVector.h
deleted file mode 100644
index 3019c2c..0000000
--- a/src/lib/decoder/openbtsstuff/BitVector.h
+++ /dev/null
@@ -1,427 +0,0 @@
-/*
-* Copyright 2008 Free Software Foundation, Inc.
-*
-* This software is distributed under the terms of the GNU Public License.
-* See the COPYING file in the main directory for details.
-
- 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 3 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, see <http://www.gnu.org/licenses/>.
-
-*/
-
-
-#ifndef FECVECTORS_H
-#define FECVECTORS_H
-
-#include "Vector.h"
-#include <stdint.h>
-
-
-class BitVector;
-class SoftVector;
-
-
-
-/** Shift-register (LFSR) generator. */
-class Generator {
-
- private:
-
- uint64_t mCoeff; ///< polynomial coefficients. LSB is zero exponent.
- uint64_t mState; ///< shift register state. LSB is most recent.
- uint64_t mMask; ///< mask for reading state
- unsigned mLen; ///< number of bits used in shift register
- unsigned mLen_1; ///< mLen - 1
-
- public:
-
- Generator(uint64_t wCoeff, unsigned wLen)
- :mCoeff(wCoeff),mState(0),
- mMask((1ULL<<wLen)-1),
- mLen(wLen),mLen_1(wLen-1)
- { assert(wLen<64); }
-
- void clear() { mState=0; }
-
- /**@name Accessors */
- //@{
- uint64_t state() const { return mState & mMask; }
- unsigned size() const { return mLen; }
- //@}
-
- /**
- Calculate one bit of a syndrome.
- This is in the .h for inlining.
- */
- void syndromeShift(unsigned inBit)
- {
- const unsigned fb = (mState>>(mLen_1)) & 0x01;
- mState = (mState<<1) ^ (inBit & 0x01);
- if (fb) mState ^= mCoeff;
- }
-
- /**
- Update the generator state by one cycle.
- This is in the .h for inlining.
- */
- void encoderShift(unsigned inBit)
- {
- const unsigned fb = ((mState>>(mLen_1)) ^ inBit) & 0x01;
- mState <<= 1;
- if (fb) mState ^= mCoeff;
- }
-
-
-};
-
-
-
-
-/** Parity (CRC-type) generator and checker based on a Generator. */
-class Parity : public Generator {
-
- protected:
-
- unsigned mCodewordSize;
-
- public:
-
- Parity(uint64_t wCoefficients, unsigned wParitySize, unsigned wCodewordSize)
- :Generator(wCoefficients, wParitySize),
- mCodewordSize(wCodewordSize)
- { }
-
- /** Compute the parity word and write it into the target segment. */
- void writeParityWord(const BitVector& data, BitVector& parityWordTarget, bool invert=true);
-
- /** Compute the syndrome of a received sequence. */
- uint64_t syndrome(const BitVector& receivedCodeword);
-};
-
-
-
-
-/**
- Class to represent convolutional coders/decoders of rate 1/2, memory length 4.
- This is the "workhorse" coder for most GSM channels.
-*/
-class ViterbiR2O4 {
-
- private:
- /**name Lots of precomputed elements so the compiler can optimize like hell. */
- //@{
- /**@name Core values. */
- //@{
- static const unsigned mIRate = 2; ///< reciprocal of rate
- static const unsigned mOrder = 4; ///< memory length of generators
- //@}
- /**@name Derived values. */
- //@{
- static const unsigned mIStates = 0x01 << mOrder; ///< number of states, number of survivors
- static const uint32_t mSMask = mIStates-1; ///< survivor mask
- static const uint32_t mCMask = (mSMask<<1) | 0x01; ///< candidate mask
- static const uint32_t mOMask = (0x01<<mIRate)-1; ///< ouput mask, all iRate low bits set
- static const unsigned mNumCands = mIStates*2; ///< number of candidates to generate during branching
- static const unsigned mDeferral = 6*mOrder; ///< deferral to be used
- //@}
- //@}
-
- /** Precomputed tables. */
- //@{
- uint32_t mCoeffs[mIRate]; ///< polynomial for each generator
- uint32_t mStateTable[mIRate][2*mIStates]; ///< precomputed generator output tables
- uint32_t mGeneratorTable[2*mIStates]; ///< precomputed coder output table
- //@}
-
- public:
-
- /**
- A candidate sequence in a Viterbi decoder.
- The 32-bit state register can support a deferral of 6 with a 4th-order coder.
- */
- typedef struct candStruct {
- uint32_t iState; ///< encoder input associated with this candidate
- uint32_t oState; ///< encoder output associated with this candidate
- float cost; ///< cost (metric value), float to support soft inputs
- } vCand;
-
- /** Clear a structure. */
- void clear(vCand& v)
- {
- v.iState=0;
- v.oState=0;
- v.cost=0;
- }
-
-
- private:
-
- /**@name Survivors and candidates. */
- //@{
- vCand mSurvivors[mIStates]; ///< current survivor pool
- vCand mCandidates[2*mIStates]; ///< current candidate pool
- //@}
-
- public:
-
- unsigned iRate() const { return mIRate; }
- uint32_t cMask() const { return mCMask; }
- uint32_t stateTable(unsigned g, unsigned i) const { return mStateTable[g][i]; }
- unsigned deferral() const { return mDeferral; }
-
-
- ViterbiR2O4();
-
- /** Set all cost metrics to zero. */
- void initializeStates();
-
- /**
- Full cycle of the Viterbi algorithm: branch, metrics, prune, select.
- @return reference to minimum-cost candidate.
- */
- const vCand& step(uint32_t inSample, const float *probs, const float *iprobs);
-
- private:
-
- /** Branch survivors into new candidates. */
- void branchCandidates();
-
- /** Compute cost metrics for soft-inputs. */
- void getSoftCostMetrics(uint32_t inSample, const float *probs, const float *iprobs);
-
- /** Select survivors from the candidate set. */
- void pruneCandidates();
-
- /** Find the minimum cost survivor. */
- const vCand& minCost() const;
-
- /**
- Precompute the state tables.
- @param g Generator index 0..((1/rate)-1)
- */
- void computeStateTables(unsigned g);
-
- /**
- Precompute the generator outputs.
- mCoeffs must be defined first.
- */
- void computeGeneratorTable();
-
-};
-
-
-
-
-class BitVector : public Vector<char> {
-
-
- public:
-
- /**@name Constructors. */
- //@{
-
- /**@name Casts of Vector constructors. */
- //@{
- BitVector(char* wData, char* wStart, char* wEnd)
- :Vector<char>(wData,wStart,wEnd)
- { }
- BitVector(size_t len=0):Vector<char>(len) {}
- BitVector(const Vector<char>& source):Vector<char>(source) {}
- BitVector(Vector<char>& source):Vector<char>(source) {}
- BitVector(const Vector<char>& source1, const Vector<char> source2):Vector<char>(source1,source2) {}
- //@}
-
- /** Construct from a string of "0" and "1". */
- BitVector(const char* valString);
- //@}
-
- /** Index a single bit. */
- bool bit(size_t index) const
- {
- // We put this code in .h for fast inlining.
- const char *dp = mStart+index;
- assert(dp<mEnd);
- return (*dp) & 0x01;
- }
-
- /**@name Casts and overrides of Vector operators. */
- //@{
- BitVector segment(size_t start, size_t span)
- {
- char* wStart = mStart + start;
- char* wEnd = wStart + span;
- assert(wEnd<=mEnd);
- return BitVector(NULL,wStart,wEnd);
- }
-
- BitVector alias()
- { return segment(0,size()); }
-
- const BitVector segment(size_t start, size_t span) const
- { return (BitVector)(Vector<char>::segment(start,span)); }
-
- BitVector head(size_t span) { return segment(0,span); }
- const BitVector head(size_t span) const { return segment(0,span); }
- BitVector tail(size_t start) { return segment(start,size()-start); }
- const BitVector tail(size_t start) const { return segment(start,size()-start); }
- //@}
-
-
- void zero() { fill(0); }
-
- /**@name FEC operations. */
- //@{
- /** Calculate the syndrome of the vector with the given Generator. */
- uint64_t syndrome(Generator& gen) const;
- /** Calculate the parity word for the vector with the given Generator. */
- uint64_t parity(Generator& gen) const;
- /** Encode the signal with the GSM rate 1/2 convolutional encoder. */
- void encode(const ViterbiR2O4& encoder, BitVector& target);
- //@}
-
-
- /** Invert 0<->1. */
- void invert();
-
- /**@name Byte-wise operations. */
- //@{
- /** Reverse an 8-bit vector. */
- void reverse8();
- /** Reverse groups of 8 within the vector (byte reversal). */
- void LSB8MSB();
- //@}
-
- /**@name Serialization and deserialization. */
- //@{
- uint64_t peekField(size_t readIndex, unsigned length) const;
- uint64_t readField(size_t& readIndex, unsigned length) const;
- void fillField(size_t writeIndex, uint64_t value, unsigned length);
- void writeField(size_t& writeIndex, uint64_t value, unsigned length);
- //@}
-
- /** Sum of bits. */
- unsigned sum() const;
-
- /** Reorder bits, dest[i] = this[map[i]]. */
- void map(const unsigned *map, size_t mapSize, BitVector& dest) const;
-
- /** Reorder bits, dest[map[i]] = this[i]. */
- void unmap(const unsigned *map, size_t mapSize, BitVector& dest) const;
-
- /** Pack into a char array. */
- void pack(unsigned char*) const;
-
- /** Unopack from a char array. */
- void unpack(const unsigned char*);
-
-};
-
-
-
-std::ostream& operator<<(std::ostream&, const BitVector&);
-
-
-
-
-
-
-/**
- The SoftVector class is used to represent a soft-decision signal.
- Values 0..1 represent probabilities that a bit is "true".
- */
-class SoftVector: public Vector<float> {
-
- public:
-
- /** Build a SoftVector of a given length. */
- SoftVector(size_t wSize=0):Vector<float>(wSize) {}
-
- /** Construct a SoftVector from a C string of "0", "1", and "X". */
- SoftVector(const char* valString);
-
- /** Construct a SoftVector from a BitVector. */
- SoftVector(const BitVector& source);
-
- /**
- Wrap a SoftVector around a block of floats.
- The block will be delete[]ed upon desctuction.
- */
- SoftVector(float *wData, unsigned length)
- :Vector<float>(wData,length)
- {}
-
- SoftVector(float* wData, float* wStart, float* wEnd)
- :Vector<float>(wData,wStart,wEnd)
- { }
-
- /**
- Casting from a Vector<float>.
- Note that this is NOT pass-by-reference.
- */
- SoftVector(Vector<float> source)
- :Vector<float>(source)
- {}
-
-
- /**@name Casts and overrides of Vector operators. */
- //@{
- SoftVector segment(size_t start, size_t span)
- {
- float* wStart = mStart + start;
- float* wEnd = wStart + span;
- assert(wEnd<=mEnd);
- return SoftVector(NULL,wStart,wEnd);
- }
-
- SoftVector alias()
- { return segment(0,size()); }
-
- const SoftVector segment(size_t start, size_t span) const
- { return (SoftVector)(Vector<float>::segment(start,span)); }
-
- SoftVector head(size_t span) { return segment(0,span); }
- const SoftVector head(size_t span) const { return segment(0,span); }
- SoftVector tail(size_t start) { return segment(start,size()-start); }
- const SoftVector tail(size_t start) const { return segment(start,size()-start); }
- //@}
-
- /** Decode soft symbols with the GSM rate-1/2 Viterbi decoder. */
- void decode(ViterbiR2O4 &decoder, BitVector& target) const;
-
- /** Fill with "unknown" values. */
- void unknown() { fill(0.5F); }
-
- /** Return a hard bit value from a given index by slicing. */
- bool bit(size_t index) const
- {
- const float *dp = mStart+index;
- assert(dp<mEnd);
- return (*dp)>0.5F;
- }
-
- /** Slice the whole signal into bits. */
- BitVector sliced() const;
-
-};
-
-
-
-std::ostream& operator<<(std::ostream&, const SoftVector&);
-
-
-
-
-
-
-#endif
-// vim: ts=4 sw=4
diff --git a/src/lib/decoder/openbtsstuff/GSM610Tables.cpp b/src/lib/decoder/openbtsstuff/GSM610Tables.cpp
deleted file mode 100644
index 38f643f..0000000
--- a/src/lib/decoder/openbtsstuff/GSM610Tables.cpp
+++ /dev/null
@@ -1,492 +0,0 @@
-/*
-* Copyright 2008 Free Software Foundation, Inc.
-*
-* This software is distributed under the terms of the GNU Public License.
-* See the COPYING file in the main directory for details.
-
- 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 3 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, see <http://www.gnu.org/licenses/>.
-
-*/
-
-
-
-#include "GSM610Tables.h"
-
-
-/*
-RFC 3551 RTP A/V Profile July 2003
-
-
- Octet Bit 0 Bit 1 Bit 2 Bit 3 Bit 4 Bit 5 Bit 6 Bit 7
- _____________________________________________________________________
- 0 1 1 0 1 LARc0.0 LARc0.1 LARc0.2 LARc0.3
- 1 LARc0.4 LARc0.5 LARc1.0 LARc1.1 LARc1.2 LARc1.3 LARc1.4 LARc1.5
- 2 LARc2.0 LARc2.1 LARc2.2 LARc2.3 LARc2.4 LARc3.0 LARc3.1 LARc3.2
- 3 LARc3.3 LARc3.4 LARc4.0 LARc4.1 LARc4.2 LARc4.3 LARc5.0 LARc5.1
- 4 LARc5.2 LARc5.3 LARc6.0 LARc6.1 LARc6.2 LARc7.0 LARc7.1 LARc7.2
- 5 Nc0.0 Nc0.1 Nc0.2 Nc0.3 Nc0.4 Nc0.5 Nc0.6 bc0.0
- 6 bc0.1 Mc0.0 Mc0.1 xmaxc00 xmaxc01 xmaxc02 xmaxc03 xmaxc04
- 7 xmaxc05 xmc0.0 xmc0.1 xmc0.2 xmc1.0 xmc1.1 xmc1.2 xmc2.0
- 8 xmc2.1 xmc2.2 xmc3.0 xmc3.1 xmc3.2 xmc4.0 xmc4.1 xmc4.2
- 9 xmc5.0 xmc5.1 xmc5.2 xmc6.0 xmc6.1 xmc6.2 xmc7.0 xmc7.1
- 10 xmc7.2 xmc8.0 xmc8.1 xmc8.2 xmc9.0 xmc9.1 xmc9.2 xmc10.0
- 11 xmc10.1 xmc10.2 xmc11.0 xmc11.1 xmc11.2 xmc12.0 xmc12.1 xcm12.2
- 12 Nc1.0 Nc1.1 Nc1.2 Nc1.3 Nc1.4 Nc1.5 Nc1.6 bc1.0
- 13 bc1.1 Mc1.0 Mc1.1 xmaxc10 xmaxc11 xmaxc12 xmaxc13 xmaxc14
- 14 xmax15 xmc13.0 xmc13.1 xmc13.2 xmc14.0 xmc14.1 xmc14.2 xmc15.0
- 15 xmc15.1 xmc15.2 xmc16.0 xmc16.1 xmc16.2 xmc17.0 xmc17.1 xmc17.2
- 16 xmc18.0 xmc18.1 xmc18.2 xmc19.0 xmc19.1 xmc19.2 xmc20.0 xmc20.1
- 17 xmc20.2 xmc21.0 xmc21.1 xmc21.2 xmc22.0 xmc22.1 xmc22.2 xmc23.0
- 18 xmc23.1 xmc23.2 xmc24.0 xmc24.1 xmc24.2 xmc25.0 xmc25.1 xmc25.2
- 19 Nc2.0 Nc2.1 Nc2.2 Nc2.3 Nc2.4 Nc2.5 Nc2.6 bc2.0
- 20 bc2.1 Mc2.0 Mc2.1 xmaxc20 xmaxc21 xmaxc22 xmaxc23 xmaxc24
- 21 xmaxc25 xmc26.0 xmc26.1 xmc26.2 xmc27.0 xmc27.1 xmc27.2 xmc28.0
- 22 xmc28.1 xmc28.2 xmc29.0 xmc29.1 xmc29.2 xmc30.0 xmc30.1 xmc30.2
- 23 xmc31.0 xmc31.1 xmc31.2 xmc32.0 xmc32.1 xmc32.2 xmc33.0 xmc33.1
- 24 xmc33.2 xmc34.0 xmc34.1 xmc34.2 xmc35.0 xmc35.1 xmc35.2 xmc36.0
- 25 Xmc36.1 xmc36.2 xmc37.0 xmc37.1 xmc37.2 xmc38.0 xmc38.1 xmc38.2
- 26 Nc3.0 Nc3.1 Nc3.2 Nc3.3 Nc3.4 Nc3.5 Nc3.6 bc3.0
- 27 bc3.1 Mc3.0 Mc3.1 xmaxc30 xmaxc31 xmaxc32 xmaxc33 xmaxc34
- 28 xmaxc35 xmc39.0 xmc39.1 xmc39.2 xmc40.0 xmc40.1 xmc40.2 xmc41.0
- 29 xmc41.1 xmc41.2 xmc42.0 xmc42.1 xmc42.2 xmc43.0 xmc43.1 xmc43.2
- 30 xmc44.0 xmc44.1 xmc44.2 xmc45.0 xmc45.1 xmc45.2 xmc46.0 xmc46.1
- 31 xmc46.2 xmc47.0 xmc47.1 xmc47.2 xmc48.0 xmc48.1 xmc48.2 xmc49.0
- 32 xmc49.1 xmc49.2 xmc50.0 xmc50.1 xmc50.2 xmc51.0 xmc51.1 xmc51.2
-
- Table 3: GSM payload format
-*/
-
-
-/*
- This file encodes a mapping between
- GSM 05.03 Table 2 and RFC-3551 Table 3.
-*/
-
-/*
- Naming convention:
- xxx_p position (bit index)
- xxx_l length (bit field length)
- LAR log area ratio
- N LTP lag
- b LTP gain
- M grid
- Xmax block amplitude
- x RPE pulses
-*/
-
-
-/**@name Lengths of GSM 06.10 fields */
-//@{
-const unsigned int LAR1_l=6; ///< log area ratio
-const unsigned int LAR2_l=6; ///< log area ratio
-const unsigned int LAR3_l=5; ///< log area ratio
-const unsigned int LAR4_l=5; ///< log area ratio
-const unsigned int LAR5_l=4; ///< log area ratio
-const unsigned int LAR6_l=4; ///< log area ratio
-const unsigned int LAR7_l=3; ///< log area ratio
-const unsigned int LAR8_l=3; ///< log area ratio
-const unsigned int N_l=7; ///< LTP lag
-const unsigned int b_l=2; ///< LTP gain
-const unsigned int M_l=2; ///< grid position
-const unsigned int Xmax_l=6; ///< block amplitude
-const unsigned int x_l=3; ///< RPE pulses
-//@}
-
-
-
-/*@name Indecies of GSM 06.10 fields as they appear in RFC-3551 Table 3. */
-//@{
-
-/**@name Log area ratios, apply to whole frame. */
-//@{
-const unsigned int LAR1_p = 0;
-const unsigned int LAR2_p = LAR1_p + LAR1_l;
-const unsigned int LAR3_p = LAR2_p + LAR2_l;
-const unsigned int LAR4_p = LAR3_p + LAR3_l;
-const unsigned int LAR5_p = LAR4_p + LAR4_l;
-const unsigned int LAR6_p = LAR5_p + LAR5_l;
-const unsigned int LAR7_p = LAR6_p + LAR6_l;
-const unsigned int LAR8_p = LAR7_p + LAR7_l;
-//@}
-/**@name Subframe 1 */
-//@{
-const unsigned int N1_p = LAR8_p + LAR8_l;
-const unsigned int b1_p = N1_p + N_l;
-const unsigned int M1_p = b1_p + b_l;
-const unsigned int Xmax1_p = M1_p + M_l;
-const unsigned int x1_0_p = Xmax1_p + Xmax_l;
-const unsigned int x1_1_p = x1_0_p + x_l;
-const unsigned int x1_2_p = x1_1_p + x_l;
-const unsigned int x1_3_p = x1_2_p + x_l;
-const unsigned int x1_4_p = x1_3_p + x_l;
-const unsigned int x1_5_p = x1_4_p + x_l;
-const unsigned int x1_6_p = x1_5_p + x_l;
-const unsigned int x1_7_p = x1_6_p + x_l;
-const unsigned int x1_8_p = x1_7_p + x_l;
-const unsigned int x1_9_p = x1_8_p + x_l;
-const unsigned int x1_10_p = x1_9_p + x_l;
-const unsigned int x1_11_p = x1_10_p + x_l;
-const unsigned int x1_12_p = x1_11_p + x_l;
-//@}
-/**@name Subframe 2 */
-//@{
-const unsigned int N2_p = x1_12_p + x_l;
-const unsigned int b2_p = N2_p + N_l;
-const unsigned int M2_p = b2_p + b_l;
-const unsigned int Xmax2_p = M2_p + M_l;
-const unsigned int x2_0_p = Xmax2_p + Xmax_l;
-const unsigned int x2_1_p = x2_0_p + x_l;
-const unsigned int x2_2_p = x2_1_p + x_l;
-const unsigned int x2_3_p = x2_2_p + x_l;
-const unsigned int x2_4_p = x2_3_p + x_l;
-const unsigned int x2_5_p = x2_4_p + x_l;
-const unsigned int x2_6_p = x2_5_p + x_l;
-const unsigned int x2_7_p = x2_6_p + x_l;
-const unsigned int x2_8_p = x2_7_p + x_l;
-const unsigned int x2_9_p = x2_8_p + x_l;
-const unsigned int x2_10_p = x2_9_p + x_l;
-const unsigned int x2_11_p = x2_10_p + x_l;
-const unsigned int x2_12_p = x2_11_p + x_l;
-//@}
-/**@mame Subframe 3 */
-//@{
-const unsigned int N3_p = x2_12_p + x_l;
-const unsigned int b3_p = N3_p + N_l;
-const unsigned int M3_p = b3_p + b_l;
-const unsigned int Xmax3_p = M3_p + M_l;
-const unsigned int x3_0_p = Xmax3_p + Xmax_l;
-const unsigned int x3_1_p = x3_0_p + x_l;
-const unsigned int x3_2_p = x3_1_p + x_l;
-const unsigned int x3_3_p = x3_2_p + x_l;
-const unsigned int x3_4_p = x3_3_p + x_l;
-const unsigned int x3_5_p = x3_4_p + x_l;
-const unsigned int x3_6_p = x3_5_p + x_l;
-const unsigned int x3_7_p = x3_6_p + x_l;
-const unsigned int x3_8_p = x3_7_p + x_l;
-const unsigned int x3_9_p = x3_8_p + x_l;
-const unsigned int x3_10_p = x3_9_p + x_l;
-const unsigned int x3_11_p = x3_10_p + x_l;
-const unsigned int x3_12_p = x3_11_p + x_l;
-//@}
-/**@name Subframe 4 */
-//@{
-const unsigned int N4_p = x3_12_p + x_l;
-const unsigned int b4_p = N4_p + N_l;
-const unsigned int M4_p = b4_p + b_l;
-const unsigned int Xmax4_p = M4_p + M_l;
-const unsigned int x4_0_p = Xmax4_p + Xmax_l;
-const unsigned int x4_1_p = x4_0_p + x_l;
-const unsigned int x4_2_p = x4_1_p + x_l;
-const unsigned int x4_3_p = x4_2_p + x_l;
-const unsigned int x4_4_p = x4_3_p + x_l;
-const unsigned int x4_5_p = x4_4_p + x_l;
-const unsigned int x4_6_p = x4_5_p + x_l;
-const unsigned int x4_7_p = x4_6_p + x_l;
-const unsigned int x4_8_p = x4_7_p + x_l;
-const unsigned int x4_9_p = x4_8_p + x_l;
-const unsigned int x4_10_p = x4_9_p + x_l;
-const unsigned int x4_11_p = x4_10_p + x_l;
-const unsigned int x4_12_p = x4_11_p + x_l;
-//@}
-//@}
-
-
-/*
- This array encodes GSM 05.03 Table 2.
- It's also GSM 06.10 Table A2.1a.
- This is the order of bits as they appear in
- the d[] bits of the GSM TCH/F.
- RTP[4+g610BitOrder[i]] <=> GSM[i]
-*/
-unsigned int GSM::g610BitOrder[260] = {
-/**@name importance class 1 */
-//@{
-/** LAR1:5 */ LAR1_p+LAR1_l-1-5, /* bit 0 */
-/** Xmax1:5 */ Xmax1_p+Xmax_l-1-5,
-/** Xmax2:5 */ Xmax2_p+Xmax_l-1-5,
-/** Xmax3:5 */ Xmax3_p+Xmax_l-1-5,
-/** Xmax4:5 */ Xmax4_p+Xmax_l-1-5,
-//@}
-/**@name importance class 2 */
-//@{
-/** LAR1:4 */ LAR1_p+LAR1_l-1-4,
-/** LAR2:5 */ LAR2_p+LAR2_l-1-5,
-/** LAR3:4 */ LAR3_p+LAR3_l-1-4,
-//@}
-/**@name importance class 3 */
-//@{
-/** LAR1:3 */ LAR1_p+LAR1_l-1-3,
-/** LAR2:4 */ LAR2_p+LAR2_l-1-4,
-/** LAR3:3 */ LAR3_p+LAR3_l-1-3, /* bit 10 */
-/** LAR4:4 */ LAR4_p+LAR4_l-1-4,
-/** N1:6 */ N1_p+N_l-1-6,
-/** N2:6 */ N2_p+N_l-1-6,
-/** N3:6 */ N3_p+N_l-1-6,
-/** N4:6 */ N4_p+N_l-1-6,
-/** Xmax1:4 */ Xmax1_p+Xmax_l-1-4,
-/** Xmax2:4 */ Xmax2_p+Xmax_l-1-4,
-/** Xmax3:4 */ Xmax3_p+Xmax_l-1-4,
-/** Xmax4:4 */ Xmax4_p+Xmax_l-1-4,
-/** LAR2:3 */ LAR2_p+LAR2_l-1-3, /* bit 20 */
-/** LAR5:3 */ LAR5_p+LAR5_l-1-3,
-/** LAR6:3 */ LAR6_p+LAR6_l-1-3,
-/** N1:5 */ N1_p+N_l-1-5,
-/** N2:5 */ N2_p+N_l-1-5,
-/** N3:5 */ N3_p+N_l-1-5,
-/** N4:5 */ N4_p+N_l-1-5,
-/** N1:4 */ N1_p+N_l-1-4,
-/** N2:4 */ N2_p+N_l-1-4,
-/** N3:4 */ N3_p+N_l-1-4,
-/** N4:4 */ N4_p+N_l-1-4, /* bit 30 */
-/** N1:3 */ N1_p+N_l-1-3,
-/** N2:3 */ N2_p+N_l-1-3,
-/** N3:3 */ N3_p+N_l-1-3,
-/** N4:3 */ N4_p+N_l-1-3,
-/** N1:2 */ N1_p+N_l-1-2,
-/** N2:2 */ N2_p+N_l-1-2,
-/** N3:2 */ N3_p+N_l-1-2,
-/** N4:2 */ N4_p+N_l-1-2,
-//@}
-/**@name importance class 4 */
-//@{
-/** Xmax1:3 */ Xmax1_p+Xmax_l-1-3,
-/** Xmax2:3 */ Xmax2_p+Xmax_l-1-3, /* bit 40 */
-/** Xmax3:3 */ Xmax3_p+Xmax_l-1-3,
-/** Xmax4:3 */ Xmax4_p+Xmax_l-1-3,
-/** LAR1:2 */ LAR1_p+LAR1_l-1-2,
-/** LAR4:3 */ LAR4_p+LAR4_l-1-3,
-/** LAR7:2 */ LAR7_p+LAR7_l-1-2,
-/** N1:1 */ N1_p+N_l-1-1,
-/** N2:1 */ N2_p+N_l-1-1,
-/** N3:1 */ N3_p+N_l-1-1,
-/** N4:1 */ N4_p+N_l-1-1,
-/** LAR5:2 */ LAR5_p+LAR5_l-1-2, /* bit 50 */
-/** LAR6:2 */ LAR6_p+LAR6_l-1-2,
-/** b1:1 */ b1_p+b_l-1-1,
-/** b2:1 */ b2_p+b_l-1-1,
-/** b3:1 */ b3_p+b_l-1-1,
-/** b4:1 */ b4_p+b_l-1-1,
-/** N1:0 */ N1_p+N_l-1-0,
-/** N2:0 */ N2_p+N_l-1-0,
-/** N3:0 */ N3_p+N_l-1-0,
-/** N4:0 */ N4_p+N_l-1-0,
-/** M1:1 */ M1_p+M_l-1-1, /* bit 60 */
-/** M2:1 */ M2_p+M_l-1-1,
-/** M3:1 */ M3_p+M_l-1-1,
-/** M4:1 */ M4_p+M_l-1-1,
-//@}
-/**@name importance class 5 */
-//@{
-/** LAR1:1 */ LAR1_p+LAR1_l-1-1,
-/** LAR2:2 */ LAR2_p+LAR2_l-1-2,
-/** LAR3:2 */ LAR3_p+LAR3_l-1-2,
-/** LAR8:2 */ LAR8_p+LAR8_l-1-2,
-/** LAR4:2 */ LAR4_p+LAR4_l-1-2,
-/** LAR5:1 */ LAR5_p+LAR5_l-1-1,
-/** LAR7:1 */ LAR7_p+LAR7_l-1-1, /* bit 70 */
-/** b1:0 */ b1_p+b_l-1-0,
-/** b2:0 */ b2_p+b_l-1-0,
-/** b3:0 */ b3_p+b_l-1-0,
-/** b4:0 */ b4_p+b_l-1-0,
-/** Xmax1:2 */ Xmax1_p+Xmax_l-1-2,
-/** Xmax2:2 */ Xmax2_p+Xmax_l-1-2,
-/** Xmax3:2 */ Xmax3_p+Xmax_l-1-2,
-/** Xmax4:2 */ Xmax4_p+Xmax_l-1-2,
-/** x1_0:2 */ x1_0_p+x_l-1-2,
-/** x1_1:2 */ x1_1_p+x_l-1-2, /* bit 80 */
-/** x1_2:2 */ x1_2_p+x_l-1-2,
-/** x1_3:2 */ x1_3_p+x_l-1-2,
-/** x1_4:2 */ x1_4_p+x_l-1-2,
-/** x1_5:2 */ x1_5_p+x_l-1-2,
-/** x1_6:2 */ x1_6_p+x_l-1-2,
-/** x1_7:2 */ x1_7_p+x_l-1-2,
-/** x1_8:2 */ x1_8_p+x_l-1-2,
-/** x1_9:2 */ x1_9_p+x_l-1-2,
-/** x1_10:2 */ x1_10_p+x_l-1-2,
-/** x1_11:2 */ x1_11_p+x_l-1-2, /* bit 90 */
-/** x1_12:2 */ x1_12_p+x_l-1-2,
-/** x2_0:2 */ x2_0_p+x_l-1-2,
-/** x2_1:2 */ x2_1_p+x_l-1-2,
-/** x2_2:2 */ x2_2_p+x_l-1-2,
-/** x2_3:2 */ x2_3_p+x_l-1-2,
-/** x2_4:2 */ x2_4_p+x_l-1-2,
-/** x2_5:2 */ x2_5_p+x_l-1-2,
-/** x2_6:2 */ x2_6_p+x_l-1-2,
-/** x2_7:2 */ x2_7_p+x_l-1-2,
-/** x2_8:2 */ x2_8_p+x_l-1-2, /* bit 100 */
-/** x2_9:2 */ x2_9_p+x_l-1-2,
-/** x2_10:2 */ x2_10_p+x_l-1-2,
-/** x2_11:2 */ x2_11_p+x_l-1-2,
-/** x2_12:2 */ x2_12_p+x_l-1-2,
-/** x3_0:2 */ x3_0_p+x_l-1-2,
-/** x3_1:2 */ x3_1_p+x_l-1-2,
-/** x3_2:2 */ x3_2_p+x_l-1-2,
-/** x3_3:2 */ x3_3_p+x_l-1-2,
-/** x3_4:2 */ x3_4_p+x_l-1-2,
-/** x3_5:2 */ x3_5_p+x_l-1-2, /* bit 110 */
-/** x3_6:2 */ x3_6_p+x_l-1-2,
-/** x3_7:2 */ x3_7_p+x_l-1-2,
-/** x3_8:2 */ x3_8_p+x_l-1-2,
-/** x3_9:2 */ x3_9_p+x_l-1-2,
-/** x3_10:2 */ x3_10_p+x_l-1-2,
-/** x3_11:2 */ x3_11_p+x_l-1-2,
-/** x3_12:2 */ x3_12_p+x_l-1-2,
-/** x4_0:2 */ x4_0_p+x_l-1-2,
-/** x4_1:2 */ x4_1_p+x_l-1-2,
-/** x4_2:2 */ x4_2_p+x_l-1-2, /* bit 120 */
-/** x4_3:2 */ x4_3_p+x_l-1-2,
-/** x4_4:2 */ x4_4_p+x_l-1-2,
-/** x4_5:2 */ x4_5_p+x_l-1-2,
-/** x4_6:2 */ x4_6_p+x_l-1-2,
-/** x4_7:2 */ x4_7_p+x_l-1-2,
-/** x4_8:2 */ x4_8_p+x_l-1-2,
-/** x4_9:2 */ x4_9_p+x_l-1-2,
-/** x4_10:2 */ x4_10_p+x_l-1-2,
-/** x4_11:2 */ x4_11_p+x_l-1-2,
-/** x4_12:2 */ x4_12_p+x_l-1-2, /* bit 130 */
-/** M1:0 */ M1_p+M_l-1-0,
-/** M2:0 */ M2_p+M_l-1-0,
-/** M3:0 */ M3_p+M_l-1-0,
-/** M4:0 */ M4_p+M_l-1-0,
-/** Xmax1:1 */ Xmax1_p+Xmax_l-1-1,
-/** Xmax2:1 */ Xmax2_p+Xmax_l-1-1,
-/** Xmax3:1 */ Xmax3_p+Xmax_l-1-1,
-/** Xmax4:1 */ Xmax4_p+Xmax_l-1-1,
-/** x1_0:1 */ x1_0_p+x_l-1-1,
-/** x1_1:1 */ x1_1_p+x_l-1-1, /* bit 140 */
-/** x1_2:1 */ x1_2_p+x_l-1-1,
-/** x1_3:1 */ x1_3_p+x_l-1-1,
-/** x1_4:1 */ x1_4_p+x_l-1-1,
-/** x1_5:1 */ x1_5_p+x_l-1-1,
-/** x1_6:1 */ x1_6_p+x_l-1-1,
-/** x1_7:1 */ x1_7_p+x_l-1-1,
-/** x1_8:1 */ x1_8_p+x_l-1-1,
-/** x1_9:1 */ x1_9_p+x_l-1-1,
-/** x1_10:1 */ x1_10_p+x_l-1-1,
-/** x1_11:1 */ x1_11_p+x_l-1-1, /* bit 150 */
-/** x1_12:1 */ x1_12_p+x_l-1-1,
-/** x2_0:1 */ x2_0_p+x_l-1-1,
-/** x2_1:1 */ x2_1_p+x_l-1-1,
-/** x2_2:1 */ x2_2_p+x_l-1-1,
-/** x2_3:1 */ x2_3_p+x_l-1-1,
-/** x2_4:1 */ x2_4_p+x_l-1-1,
-/** x2_5:1 */ x2_5_p+x_l-1-1,
-/** x2_6:1 */ x2_6_p+x_l-1-1,
-/** x2_7:1 */ x2_7_p+x_l-1-1,
-/** x2_8:1 */ x2_8_p+x_l-1-1, /* bit 160 */
-/** x2_9:1 */ x2_9_p+x_l-1-1,
-/** x2_10:1 */ x2_10_p+x_l-1-1,
-/** x2_11:1 */ x2_11_p+x_l-1-1,
-/** x2_12:1 */ x2_12_p+x_l-1-1,
-/** x3_0:1 */ x3_0_p+x_l-1-1,
-/** x3_1:1 */ x3_1_p+x_l-1-1,
-/** x3_2:1 */ x3_2_p+x_l-1-1,
-/** x3_3:1 */ x3_3_p+x_l-1-1,
-/** x3_4:1 */ x3_4_p+x_l-1-1,
-/** x3_5:1 */ x3_5_p+x_l-1-1, /* bit 170 */
-/** x3_6:1 */ x3_6_p+x_l-1-1,
-/** x3_7:1 */ x3_7_p+x_l-1-1,
-/** x3_8:1 */ x3_8_p+x_l-1-1,
-/** x3_9:1 */ x3_9_p+x_l-1-1,
-/** x3_10:1 */ x3_10_p+x_l-1-1,
-/** x3_11:1 */ x3_11_p+x_l-1-1,
-/** x3_12:1 */ x3_12_p+x_l-1-1,
-/** x4_0:1 */ x4_0_p+x_l-1-1,
-/** x4_1:1 */ x4_1_p+x_l-1-1,
-/** x4_2:1 */ x4_2_p+x_l-1-1, /* bit 180 */
-/** x4_3:1 */ x4_3_p+x_l-1-1,
-//@}
-/**@name importance class 6 */
-//@{
-/** x4_4:1 */ x4_4_p+x_l-1-1,
-/** x4_5:1 */ x4_5_p+x_l-1-1,
-/** x4_6:1 */ x4_6_p+x_l-1-1,
-/** x4_7:1 */ x4_7_p+x_l-1-1,
-/** x4_8:1 */ x4_8_p+x_l-1-1,
-/** x4_9:1 */ x4_9_p+x_l-1-1,
-/** x4_10:1 */ x4_10_p+x_l-1-1,
-/** x4_11:1 */ x4_11_p+x_l-1-1,
-/** x4_12:1 */ x4_12_p+x_l-1-1, /* bit 190 */
-/** LAR1:0 */ LAR1_p+LAR1_l-1-0,
-/** LAR2:1 */ LAR2_p+LAR2_l-1-1,
-/** LAR3:1 */ LAR3_p+LAR3_l-1-1,
-/** LAR6:1 */ LAR6_p+LAR6_l-1-1,
-/** LAR7:0 */ LAR7_p+LAR7_l-1-0,
-/** LAR8:1 */ LAR8_p+LAR8_l-1-1,
-/** LAR8:0 */ LAR8_p+LAR8_l-1-0,
-/** LAR3:0 */ LAR3_p+LAR3_l-1-0,
-/** LAR4:1 */ LAR4_p+LAR4_l-1-1,
-/** LAR4:0 */ LAR4_p+LAR4_l-1-0,
-/** LAR5:0 */ LAR5_p+LAR5_l-1-0,
-/** Xmax1:0 */ Xmax1_p+Xmax_l-1-0,
-/** Xmax2:0 */ Xmax2_p+Xmax_l-1-0,
-/** Xmax3:0 */ Xmax3_p+Xmax_l-1-0,
-/** Xmax4:0 */ Xmax4_p+Xmax_l-1-0,
-/** x1_0:0 */ x1_0_p+x_l-1-0,
-/** x1_1:0 */ x1_1_p+x_l-1-0,
-/** x1_2:0 */ x1_2_p+x_l-1-0,
-/** x1_3:0 */ x1_3_p+x_l-1-0,
-/** x1_4:0 */ x1_4_p+x_l-1-0,
-/** x1_5:0 */ x1_5_p+x_l-1-0,
-/** x1_6:0 */ x1_6_p+x_l-1-0,
-/** x1_7:0 */ x1_7_p+x_l-1-0,
-/** x1_8:0 */ x1_8_p+x_l-1-0,
-/** x1_9:0 */ x1_9_p+x_l-1-0,
-/** x1_10:0 */ x1_10_p+x_l-1-0,
-/** x1_11:0 */ x1_11_p+x_l-1-0,
-/** x1_12:0 */ x1_12_p+x_l-1-0,
-/** x2_0:0 */ x2_0_p+x_l-1-0,
-/** x2_1:0 */ x2_1_p+x_l-1-0,
-/** x2_2:0 */ x2_2_p+x_l-1-0,
-/** x2_3:0 */ x2_3_p+x_l-1-0,
-/** x2_4:0 */ x2_4_p+x_l-1-0,
-/** x2_5:0 */ x2_5_p+x_l-1-0,
-/** x2_6:0 */ x2_6_p+x_l-1-0,
-/** x2_7:0 */ x2_7_p+x_l-1-0,
-/** x2_8:0 */ x2_8_p+x_l-1-0,
-/** x2_9:0 */ x2_9_p+x_l-1-0,
-/** x2_10:0 */ x2_10_p+x_l-1-0,
-/** x2_11:0 */ x2_11_p+x_l-1-0,
-/** x2_12:0 */ x2_12_p+x_l-1-0,
-/** x3_0:0 */ x3_0_p+x_l-1-0,
-/** x3_1:0 */ x3_1_p+x_l-1-0,
-/** x3_2:0 */ x3_2_p+x_l-1-0,
-/** x3_3:0 */ x3_3_p+x_l-1-0,
-/** x3_4:0 */ x3_4_p+x_l-1-0,
-/** x3_5:0 */ x3_5_p+x_l-1-0,
-/** x3_6:0 */ x3_6_p+x_l-1-0,
-/** x3_7:0 */ x3_7_p+x_l-1-0,
-/** x3_8:0 */ x3_8_p+x_l-1-0,
-/** x3_9:0 */ x3_9_p+x_l-1-0,
-/** x3_10:0 */ x3_10_p+x_l-1-0,
-/** x3_11:0 */ x3_11_p+x_l-1-0,
-/** x3_12:0 */ x3_12_p+x_l-1-0,
-/** x4_0:0 */ x4_0_p+x_l-1-0,
-/** x4_1:0 */ x4_1_p+x_l-1-0,
-/** x4_2:0 */ x4_2_p+x_l-1-0,
-/** x4_3:0 */ x4_3_p+x_l-1-0,
-/** x4_4:0 */ x4_4_p+x_l-1-0,
-/** x4_5:0 */ x4_5_p+x_l-1-0,
-/** x4_6:0 */ x4_6_p+x_l-1-0,
-/** x4_7:0 */ x4_7_p+x_l-1-0,
-/** x4_8:0 */ x4_8_p+x_l-1-0,
-/** x4_9:0 */ x4_9_p+x_l-1-0,
-/** x4_10:0 */ x4_10_p+x_l-1-0,
-/** x4_11:0 */ x4_11_p+x_l-1-0,
-/** x4_12:0 */ x4_12_p+x_l-1-0,
-/** LAR2:0 */ LAR2_p+LAR2_l-1-0,
-/** LAR6:0 */ LAR6_p+LAR6_l-1-0
-//@}
-};
-
diff --git a/src/lib/decoder/openbtsstuff/GSM610Tables.h b/src/lib/decoder/openbtsstuff/GSM610Tables.h
deleted file mode 100644
index 53a8e1c..0000000
--- a/src/lib/decoder/openbtsstuff/GSM610Tables.h
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
-* Copyright 2008 Free Software Foundation, Inc.
-*
-* This software is distributed under the terms of the GNU Public License.
-* See the COPYING file in the main directory for details.
-
- 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 3 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, see <http://www.gnu.org/licenses/>.
-
-*/
-
-
-
-#ifndef GSM610TABLES_H
-#define GSM610TABLES_H
-
-
-
-namespace GSM {
-
-/** Table #2 from GSM 05.03 */
-extern unsigned int g610BitOrder[260];
-
-}
-
-
-#endif
diff --git a/src/lib/decoder/openbtsstuff/GSMCommon.cpp b/src/lib/decoder/openbtsstuff/GSMCommon.cpp
deleted file mode 100644
index 0bec812..0000000
--- a/src/lib/decoder/openbtsstuff/GSMCommon.cpp
+++ /dev/null
@@ -1,315 +0,0 @@
-/*
-* Copyright 2008 Free Software Foundation, Inc.
-*
-* This software is distributed under the terms of the GNU Public License.
-* See the COPYING file in the main directory for details.
-
- 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 3 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, see <http://www.gnu.org/licenses/>.
-
-*/
-
-
-#include "GSMCommon.h"
-
-using namespace GSM;
-using namespace std;
-
-
-ostream& GSM::operator<<(ostream& os, L3PD val)
-{
- switch (val) {
- case L3CallControlPD: os << "Call Control"; break;
- case L3MobilityManagementPD: os << "Mobility Management"; break;
- case L3RadioResourcePD: os << "Radio Resource"; break;
- default: os << hex << "0x" << (int)val << dec;
- }
- return os;
-}
-
-
-const BitVector GSM::gTrainingSequence[] = {
- BitVector("00100101110000100010010111"),
- BitVector("00101101110111100010110111"),
- BitVector("01000011101110100100001110"),
- BitVector("01000111101101000100011110"),
- BitVector("00011010111001000001101011"),
- BitVector("01001110101100000100111010"),
- BitVector("10100111110110001010011111"),
- BitVector("11101111000100101110111100"),
-};
-
-const BitVector GSM::gDummyBurst("0001111101101110110000010100100111000001001000100000001111100011100010111000101110001010111010010100011001100111001111010011111000100101111101010000");
-
-const BitVector GSM::gRACHSynchSequence("01001011011111111001100110101010001111000");
-
-
-
-char encodeGSMChar(char ascii)
-{
- // Given an ASCII char, return the corresponding GSM char.
- static char reverseTable[256]={0};
- static bool init = false;
- if (!init) {
- for (size_t i=0; i<sizeof(gGSMAlphabet); i++) {
- reverseTable[(unsigned)gGSMAlphabet[i]]=i;
- }
- init=true;
- }
- return reverseTable[(unsigned)ascii];
-}
-
-
-char encodeBCDChar(char ascii)
-{
- // Given an ASCII char, return the corresponding BCD.
- if ((ascii>='0') && (ascii<='9')) return ascii-'0';
- switch (ascii) {
- case '.': return 11;
- case '*': return 11;
- case '#': return 12;
- case 'a': return 13;
- case 'b': return 14;
- case 'c': return 15;
- default: return 15;
- }
-}
-
-
-
-
-unsigned GSM::uplinkFreqKHz(GSMBand band, unsigned ARFCN)
-{
- switch (band) {
- case GSM850:
- assert((ARFCN<252)&&(ARFCN>129));
- return 824200+200*(ARFCN-128);
- case EGSM900:
- if (ARFCN<=124) return 890000+200*ARFCN;
- assert((ARFCN>974)&&(ARFCN<1024));
- return 890000+200*(ARFCN-1024);
- case DCS1800:
- assert((ARFCN>511)&&(ARFCN<886));
- return 1710200+200*(ARFCN-512);
- case PCS1900:
- assert((ARFCN>511)&&(ARFCN<811));
- return 1850200+200*(ARFCN-512);
- default:
- abort();
- }
-}
-
-
-unsigned GSM::downlinkFreqKHz(GSMBand band, unsigned ARFCN)
-{
- static unsigned uplinkOffset[] = {
- 45000, // 850
- 45000, // 900
- 95000, // 1800
- 80000 // 1900
- };
- return uplinkFreqKHz(band,ARFCN) + uplinkOffset[band];
-}
-
-
-
-
-int32_t GSM::FNDelta(int32_t v1, int32_t v2)
-{
- static const int64_t halfModulus = gHyperframe/2;
- int32_t delta = v1-v2;
- if (delta>halfModulus) delta -= gHyperframe;
- else if (delta<-halfModulus) delta += gHyperframe;
- return (int32_t) delta;
-}
-
-int GSM::FNCompare(int32_t v1, int32_t v2)
-{
- int32_t delta = FNDelta(v1,v2);
- if (delta==0) return 0;
- else if (delta>0) return 1;
- else return -1;
-}
-
-
-
-
-ostream& GSM::operator<<(ostream& os, const Time& t)
-{
- os << t.TN() << ":" << t.FN();
- return os;
-}
-
-
-
-
-void Clock::set(const Time& when)
-{
- mLock.lock();
- mBaseTime = Timeval(0);
- mBaseFN = when.FN();
- mLock.unlock();
-}
-
-
-int32_t Clock::FN() const
-{
- mLock.lock();
- Timeval now;
- int deltaSec = now.sec() - mBaseTime.sec();
- int deltaUSec = now.usec() - mBaseTime.usec();
- int elapsedUSec = 1000000*deltaSec + deltaUSec;
- int elapsedFrames = elapsedUSec / gFrameMicroseconds;
- int32_t currentFN = (mBaseFN + elapsedFrames) % gHyperframe;
- mLock.unlock();
- return currentFN;
-}
-
-
-void Clock::wait(const Time& when) const
-{
- int32_t now = FN();
- int32_t target = when.FN();
- int32_t delta = FNDelta(target,now);
- if (delta<1) return;
- const int32_t maxSleep = 51*26;
- if (delta>maxSleep) delta=maxSleep;
- sleepFrames(delta);
-}
-
-
-
-
-
-
-
-ostream& GSM::operator<<(ostream& os, TypeOfNumber type)
-{
- switch (type) {
- case UnknownTypeOfNumber: os << "unknown"; break;
- case InternationalNumber: os << "international"; break;
- case NationalNumber: os << "national"; break;
- case NetworkSpecificNumber: os << "network-specific"; break;
- case ShortCodeNumber: os << "short code"; break;
- default: os << "?" << type << "?";
- }
- return os;
-}
-
-
-ostream& GSM::operator<<(ostream& os, NumberingPlan plan)
-{
- switch (plan) {
- case UnknownPlan: os << "unknown"; break;
- case E164Plan: os << "E.164/ISDN"; break;
- case X121Plan: os << "X.121/data"; break;
- case F69Plan: os << "F.69/Telex"; break;
- case NationalPlan: os << "national"; break;
- case PrivatePlan: os << "private"; break;
- default: os << "?" << (int)plan << "?";
- }
- return os;
-}
-
-ostream& GSM::operator<<(ostream& os, MobileIDType wID)
-{
- switch (wID) {
- case NoIDType: os << "None"; break;
- case IMSIType: os << "IMSI"; break;
- case IMEIType: os << "IMEI"; break;
- case TMSIType: os << "TMSI"; break;
- case IMEISVType: os << "IMEISV"; break;
- default: os << "?" << (int)wID << "?";
- }
- return os;
-}
-
-
-ostream& GSM::operator<<(ostream& os, TypeAndOffset tao)
-{
- switch (tao) {
- case TDMA_MISC: os << "(misc)"; break;
- case TCHF_0: os << "TCH/F"; break;
- case TCHH_0: os << "TCH/H-0"; break;
- case TCHH_1: os << "TCH/H-1"; break;
- case SDCCH_4_0: os << "SDCCH/4-0"; break;
- case SDCCH_4_1: os << "SDCCH/4-1"; break;
- case SDCCH_4_2: os << "SDCCH/4-2"; break;
- case SDCCH_4_3: os << "SDCCH/4-3"; break;
- case SDCCH_8_0: os << "SDCCH/8-0"; break;
- case SDCCH_8_1: os << "SDCCH/8-1"; break;
- case SDCCH_8_2: os << "SDCCH/8-2"; break;
- case SDCCH_8_3: os << "SDCCH/8-3"; break;
- case SDCCH_8_4: os << "SDCCH/8-4"; break;
- case SDCCH_8_5: os << "SDCCH/8-5"; break;
- case SDCCH_8_6: os << "SDCCH/8-6"; break;
- case SDCCH_8_7: os << "SDCCH/8-7"; break;
- case TDMA_BEACON: os << "(beacon)"; break;
- default: os << "?" << (int)tao << "?";
- }
- return os;
-}
-
-ostream& GSM::operator<<(ostream& os, ChannelType val)
-{
- switch (val) {
- case UndefinedCHType: os << "undefined"; return os;
- case SCHType: os << "SCH"; break;
- case FCCHType: os << "FCCH"; break;
- case BCCHType: os << "BCCH"; break;
- case RACHType: os << "RACH"; break;
- case SDCCHType: os << "SDCCH"; break;
- case FACCHType: os << "FACCH"; break;
- case CCCHType: os << "CCCH"; break;
- case SACCHType: os << "SACCH"; break;
- case TCHFType: os << "TCH/F"; break;
- case TCHHType: os << "TCH/H"; break;
- case AnyTCHType: os << "any TCH"; break;
- case LoopbackFullType: os << "Loopback Full"; break;
- case LoopbackHalfType: os << "Loopback Half"; break;
- case AnyDCCHType: os << "any DCCH"; break;
- default: os << "?" << (int)val << "?";
- }
- return os;
-}
-
-
-
-
-bool Z100Timer::expired() const
-{
- // A non-active timer does not expire.
- if (!mActive) return false;
- return mEndTime.passed();
-}
-
-void Z100Timer::set()
-{
- mEndTime = Timeval(mLimitTime);
- mActive=true;
-}
-
-long Z100Timer::remaining() const
-{
- if (!mActive) return 0;
- long rem = mEndTime.remaining();
- if (rem<0) rem=0;
- return rem;
-}
-
-void Z100Timer::wait() const
-{
- while (!expired()) msleep(remaining());
-}
-
-// vim: ts=4 sw=4
diff --git a/src/lib/decoder/openbtsstuff/GSMCommon.h b/src/lib/decoder/openbtsstuff/GSMCommon.h
deleted file mode 100644
index 9dc1c95..0000000
--- a/src/lib/decoder/openbtsstuff/GSMCommon.h
+++ /dev/null
@@ -1,537 +0,0 @@
-/**@file Common-use GSM declarations, most from the GSM 04.xx and 05.xx series. */
-/*
-* Copyright 2008 Free Software Foundation, Inc.
-*
-* This software is distributed under the terms of the GNU Public License.
-* See the COPYING file in the main directory for details.
-
- 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 3 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, see <http://www.gnu.org/licenses/>.
-
-*/
-
-
-
-#ifndef GSMCOMMON_H
-#define GSMCOMMON_H
-
-#include <stdlib.h>
-#include <sys/time.h>
-#include <ostream>
-#include <vector>
-
-#include <Threads.h>
-#include <Timeval.h>
-#include <BitVector.h>
-
-
-
-
-namespace GSM {
-
-/**@namespace GSM This namespace covers L1 FEC, L2 and L3 message translation. */
-
-
-/* forward references */
-class L1FEC;
-class L2LAPDm;
-class L3Processor;
-class LogicalChannel;
-class L2Header;
-
-
-/** A base class for GSM exceptions. */
-class GSMError {};
-
-/** Duration ofa GSM frame, in microseconds. */
-const unsigned gFrameMicroseconds = 4615;
-
-
-/** Sleep for a given number of GSM frame periods. */
-inline void sleepFrames(unsigned frames)
- { usleep(frames*gFrameMicroseconds); }
-
-/** Sleep for 1 GSM frame period. */
-inline void sleepFrame()
- { usleep(gFrameMicroseconds); }
-
-
-
-/** GSM Training sequences from GSM 05.02 5.2.3. */
-extern const BitVector gTrainingSequence[];
-
-/** C0T0 filler burst, GSM 05.02, 5.2.6 */
-extern const BitVector gDummyBurst;
-
-/** Random access burst synch. sequence */
-extern const BitVector gRACHSynchSequence;
-
-
-/**@name Support for GSM 7-bit alphabet, GSM 03.38 6.2.1. */
-//@{
-/** Indexed by GSM 7-bit, returns ASCII. */
-static const char gGSMAlphabet[] = "@\243$\245\350\351\371\354\362\347\n\330\370\r\305\345D_FGLOPCSTZ \306\346\337\311 !\"#\244%&\'()*+,-./0123456789:;<=>?\241ABCDEFGHIJKLMNOPQRSTUVWXYZ\304\326\321\334\247\277abcdefghijklmnopqrstuvwxyz\344\366\361\374\341";
-char encodeGSMChar(char ascii);
-inline char decodeGSMChar(char sms) { return gGSMAlphabet[(unsigned)sms]; }
-//@}
-
-
-/**@name BCD-ASCII mapping, GMS 04.08 Table 10.5.118. */
-//@{
-/** Indexed by BCD, returns ASCII. */
-static const char gBCDAlphabet[] = "0123456789.#abc";
-char encodeBCDChar(char ascii);
-inline char decodeBCDChar(char bcd) { return gBCDAlphabet[(unsigned)bcd]; }
-//@}
-
-
-/**@name Globally-fixed GSM timeout values (all in ms). */
-//@{
-/**@name GSM LAPDm timeouts, GSM 04.06 5.8, ITU-T Q.921 5.9 */
-//@{
-const unsigned T200ms = 900; ///< LAPDm ACK timeout, set for typical turnaround time
-//@}
-/**@name GSM timeouts for radio resource management, GSM 04.08 11.1. */
-//@{
-const unsigned T3101ms = 4000; ///< L1 timeout for SDCCH assignment
-const unsigned T3107ms = 3000; ///< L1 timeout for TCH/FACCH assignment
-const unsigned T3109ms = 10000; ///< L1 timeout for an existing channel
-const unsigned T3111ms = 2*T200ms; ///< L1 timeout for reassignment of a channel
-const unsigned T3113ms = 10000; ///< timeout for paging response
-const unsigned T3122ms = 2000; ///< RR access holdoff time (GSM 04.08 3.3.1.1.3.2)
-//@}
-/**@name GSM timeouts for mobility management, GSM 04.08 11.2. */
-//@{
-const unsigned T3212ms = 8*360000; ///< location updating period (in 6-min increments, 0-255)
-//const unsigned T3212ms = 0; ///< location updating period (in 6-min increments, 0-255), 0 disables
-//@}
-//@}
-
-
-
-
-/** GSM 04.08 Table 10.5.118 */
-enum TypeOfNumber {
- UnknownTypeOfNumber = 0,
- InternationalNumber = 1,
- NationalNumber = 2,
- NetworkSpecificNumber = 3,
- ShortCodeNumber = 4
-};
-
-std::ostream& operator<<(std::ostream&, TypeOfNumber);
-
-
-/** GSM 04.08 Table 10.5.118 */
-enum NumberingPlan {
- UnknownPlan = 0,
- E164Plan = 1,
- X121Plan = 3,
- F69Plan = 4,
- NationalPlan = 8,
- PrivatePlan = 9
-};
-
-std::ostream& operator<<(std::ostream&, NumberingPlan);
-
-
-
-/** Codes for GSM band types, GSM 05.05 2. */
-enum GSMBand {
- GSM850=0, ///< US cellular
- EGSM900, ///< extended GSM
- DCS1800, ///< worldwide DCS band
- PCS1900 ///< US PCS band
-};
-
-
-/**@name Actual radio carrier frequencies, in kHz, GSM 05.05 2 */
-//@{
-unsigned uplinkFreqKHz(GSMBand wBand, unsigned wARFCN);
-unsigned downlinkFreqKHz(GSMBand wBand, unsigned wARFCN);
-//@}
-
-
-
-/**@name GSM Logical channel (LCH) types. */
-//@{
-/** Codes for logical channel types. */
-enum ChannelType {
- ///@name Non-dedicated control channels.
- //@{
- SCHType, ///< sync
- FCCHType, ///< frequency correction
- BCCHType, ///< broadcast control
- CCCHType, ///< common control, a combination of several sub-types
- RACHType, ///< random access
- SACCHType, ///< slow associated control (acutally dedicated, but...)
- //@}
- ///@name Dedicated control channels (DCCHs).
- //@{
- SDCCHType, ///< standalone dedicated control
- FACCHType, ///< fast associated control
- //@}
- ///@name Traffic channels
- //@{
- TCHFType, ///< full-rate traffic
- TCHHType, ///< half-rate traffic
- AnyTCHType, ///< any TCH type
- //@}
- ///@name Special internal channel types.
- //@{
- LoopbackFullType, ///< loopback testing
- LoopbackHalfType, ///< loopback testing
- AnyDCCHType, ///< any dedicated control channel
- UndefinedCHType, ///< undefined
- //@}
-};
-
-
-/** Print channel type name to a stream. */
-std::ostream& operator<<(std::ostream& os, ChannelType val);
-
-
-//@}
-
-
-
-/** Mobile identity types, GSM 04.08 10.5.1.4 */
-enum MobileIDType {
- NoIDType = 0,
- IMSIType = 1,
- IMEIType = 2,
- IMEISVType = 3,
- TMSIType = 4
-};
-
-std::ostream& operator<<(std::ostream& os, MobileIDType);
-
-
-/** Type and TDMA offset of a logical channel, from GSM 04.08 10.5.2.5 */
-enum TypeAndOffset {
- TDMA_MISC=0,
- TCHF_0=1,
- TCHH_0=2, TCHH_1=3,
- SDCCH_4_0=4, SDCCH_4_1=5, SDCCH_4_2=6, SDCCH_4_3=7,
- SDCCH_8_0=8, SDCCH_8_1=9, SDCCH_8_2=10, SDCCH_8_3=11,
- SDCCH_8_4=12, SDCCH_8_5=13, SDCCH_8_6=14, SDCCH_8_7=15,
- /// An extra one for our internal use.
- TDMA_BEACON=255
-};
-
-std::ostream& operator<<(std::ostream& os, TypeAndOffset);
-
-
-
-
-
-
-
-
-/**
- L3 Protocol Discriminator, GSM 04.08 10.2, GSM 04.07 11.2.3.1.1.
-*/
-enum L3PD {
- L3GroupCallControlPD=0x00,
- L3BroadcastCallControlPD=0x01,
- L3PDSS1PD=0x02,
- L3CallControlPD=0x03,
- L3PDSS2PD=0x04,
- L3MobilityManagementPD=0x05,
- L3RadioResourcePD=0x06,
- L3MobilityManagementGPRSPD=0x08,
- L3SMSPD=0x09,
- L3GPRSSessionManagementPD=0x0a,
- L3NonCallSSPD=0x0b,
- L3LocationPD=0x0c,
- L3ExtendedPD=0x0e,
- L3TestProcedurePD=0x0f,
- L3UndefinedPD=-1
-};
-
-
-
-std::ostream& operator<<(std::ostream& os, L3PD val);
-
-
-
-
-/**@name Modulus operations for frame numbers. */
-//@{
-/** The GSM hyperframe is largest time period in the GSM system, GSM 05.02 4.3.3. */
-const int32_t gHyperframe = 2048UL * 26UL * 51UL;
-
-/** Get a clock difference, within the modulus. */
-int32_t FNDelta(int32_t v1, int32_t v2);
-
-/**
- Compare two frame clock values.
- @return 1 if v1>v2, -1 if v1<v2, 0 if v1==v2
-*/
-int FNCompare(int32_t v1, int32_t v2);
-
-
-//@}
-
-
-
-
-/**
- GSM frame clock value.
- No internal thread sync.
-*/
-class Time {
-
- private:
-
- int mFN; ///< frame number in the hyperframe
- unsigned mTN; ///< timeslot number
-
- public:
-
- Time(int wFN=0, unsigned wTN=0)
- :mFN(wFN),mTN(wTN)
- { }
-
-
- /** Move the time forward to a given position in a given modulus. */
- void rollForward(unsigned wFN, unsigned modulus)
- { while ((mFN % modulus) != wFN) mFN++; }
-
- /**@name Accessors. */
- //@{
- int FN() const { return mFN; }
- void FN(unsigned wFN) { mFN = wFN; }
- unsigned TN() const { return mTN; }
- void TN(unsigned wTN) { mTN=wTN; }
- //@}
-
- /**@name Arithmetic. */
- //@{
-
- Time& operator++()
- {
- mFN = (mFN+1) % gHyperframe;
- return *this;
- }
-
- Time& decTN(int step=1)
- {
- if ((int)mTN<step) mFN = *this - Time(1,0);
- if (mTN-step < 0) mTN = (mTN-step+8) % 8;
- else mTN = (mTN-step) % 8;
- return *this;
- }
-
- Time& incTN(int step=1)
- {
- mFN = mFN + (mTN + step)/8;
- mTN = (mTN+step) % 8;
- return *this;
- }
-
- Time& operator+=(int step)
- {
- mFN = (mFN+step) % gHyperframe;
- return *this;
- }
-
- Time operator+(int step) const
- {
- Time newVal = *this;
- newVal += step;
- return newVal;
- }
-
- Time operator-(int step) const
- {
- return operator+(-step);
- }
-
- Time operator+(const Time& other) const
- {
- unsigned newTN = (mTN + other.mTN) % 8;
- uint64_t newFN = (mFN+other.mFN + (mTN + other.mTN)/8) % gHyperframe;
- return Time(newFN,newTN);
- }
-
- int operator-(const Time& other) const
- {
- return FNDelta(mFN,other.mFN);
- }
-
- //@}
-
-
- /**@name Comparisons. */
- //@{
-
- bool operator<(const Time& other) const
- {
- if (mFN==other.mFN) return (mTN<other.mTN);
- return FNCompare(mFN,other.mFN)<0;
- }
-
- bool operator>(const Time& other) const
- {
- if (mFN==other.mFN) return (mTN>other.mTN);
- return FNCompare(mFN,other.mFN)>0;
- }
-
- bool operator<=(const Time& other) const
- {
- if (mFN==other.mFN) return (mTN<=other.mTN);
- return FNCompare(mFN,other.mFN)<=0;
- }
-
- bool operator>=(const Time& other) const
- {
- if (mFN==other.mFN) return (mTN>=other.mTN);
- return FNCompare(mFN,other.mFN)>=0;
- }
-
- bool operator==(const Time& other) const
- {
- return (mFN == other.mFN) && (mTN==other.mTN);
- }
-
- //@}
-
-
-
- /**@name Standard derivations. */
- //@{
-
- unsigned SFN() const { return mFN / (26*51); }
-
- unsigned T1() const { return SFN() % 2048; }
-
- unsigned T2() const { return mFN % 26; }
-
- unsigned T3() const { return mFN % 51; }
-
- /** GSM 05.02 3.3.2.2.1. */
- unsigned T3p() const { return (T3()-1)/10; }
-
- /** GSM 05.02 6.3.1.3. */
- unsigned TC() const { return (FN()/51) % 8; }
-
- /** GSM 04.08 10.5.2.30. */
- unsigned T1p() const { return SFN() % 32; }
-
- /** GSM 05.02 6.2.3 */
- unsigned T1R() const { return T1() % 64; }
-
- //@}
-};
-
-
-std::ostream& operator<<(std::ostream& os, const Time& ts);
-
-
-
-
-
-
-/**
- A class for calculating the current GSM frame number.
-*/
-class Clock {
-
- private:
-
- mutable Mutex mLock;
- int32_t mBaseFN;
- Timeval mBaseTime;
-
- public:
-
- Clock(const Time& when = Time(0))
- :mBaseFN(when.FN())
- {}
-
- /** Set the clock to a value. */
- void set(const Time&);
-
- /** Read the clock. */
- int32_t FN() const;
-
- /** Read the clock. */
- Time get() const { return Time(FN()); }
-
- /** Block until the clock passes a given time. */
- void wait(const Time&) const;
-};
-
-
-
-
-
-
-
-
-/**
- CCITT Z.100 activity timer, as described in GSM 04.06 5.1.
- All times are in milliseconds.
-*/
-class Z100Timer {
-
- private:
-
- Timeval mEndTime; ///< the time at which this timer will expire
- long mLimitTime; ///< timeout in milliseconds
- bool mActive; ///< true if timer is active
-
- public:
-
- /** Create a timer with a given timeout in milliseconds. */
- Z100Timer(long wLimitTime)
- :mLimitTime(wLimitTime),
- mActive(false)
- {}
-
- /** True if the timer is active and expired. */
- bool expired() const;
-
- /** Start or restart the timer. */
- void set();
-
- /** Stop the timer. */
- void reset() { mActive = false; }
-
- /** Returns true if the timer is active. */
- bool active() const { return mActive; }
-
- /**
- Remaining time until expiration, in milliseconds.
- Returns zero if the timer has expired.
- */
- long remaining() const;
-
- /**
- Block until the timer expires.
- Returns immediately if the timer is not running.
- */
- void wait() const;
-};
-
-
-
-
-
-}; // namespace GSM
-
-
-#endif
-
-// vim: ts=4 sw=4
diff --git a/src/lib/decoder/openbtsstuff/GSML1FEC.cpp b/src/lib/decoder/openbtsstuff/GSML1FEC.cpp
deleted file mode 100644
index 1c99a0f..0000000
--- a/src/lib/decoder/openbtsstuff/GSML1FEC.cpp
+++ /dev/null
@@ -1,256 +0,0 @@
-/*
-* Copyright 2008 Free Software Foundation, Inc.
-*
-* This software is distributed under the terms of the GNU Public License.
-* See the COPYING file in the main directory for details.
-
- 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 3 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, see <http://www.gnu.org/licenses/>.
-
-*/
-
-
-#define NDEBUG
-
-
-#include "GSML1FEC.h"
-#include "GSMCommon.h"
-#include "RxBurst.h"
-//#include "GSMSAPMux.h"
-//#include "GSMConfig.h"
-#include "GSMTDMA.h"
-#include "GSM610Tables.h"
-#include "Assert.h"
-
-
-using namespace std;
-using namespace GSM;
-
-/*
- Compilation flags:
- NOCONTROL Compile without referencing control layer functions.
-*/
-
-
-/*
-
- Notes on reading the GSM specifications.
-
- Every FEC section in GSM 05.03 uses standard names for the bits at
- different stages of the encoding/decoding process.
-
- This is all described formally in GSM 05.03 2.2.
-
- "d" -- data bits. The actual payloads from L2 and the vocoders.
- "p" -- parity bits. These are calculated from d.
- "u" -- uncoded bits. A concatenation of d, p and inner tail bits.
- "c" -- coded bits. These are the convolutionally encoded from u.
- "i" -- interleaved bits. These are the output of the interleaver.
- "e" -- "encrypted" bits. These are the channel bits in the radio bursts.
-
- The "e" bits are call "encrypted" even when encryption is not used.
-
- The encoding process is:
-
- L2 -> d -> -> calc p -> u -> c -> i -> e -> radio bursts
-
- The decoding process is:
-
- radio bursts -> e -> i -> c -> u -> check p -> d -> L2
-
- Bit ordering in d is LSB-first in each octet.
- Bit ordering everywhere else in the OpenBTS code is MSB-first
- in every field to give contiguous fields across byte boundaries.
- We use the BitVector::LSB8MSB() method to translate.
-
-*/
-
-TCHFACCHL1Decoder::TCHFACCHL1Decoder(const TDMAMapping& wMapping)
- : mTCHU(189), mTCHD(260), mC(456),
- mClass1_c(mC.head(378)), mClass1A_d(mTCHD.head(50)), mClass2_c(mC.segment(378, 78)),
- mTCHParity(0x0b, 3, 50), mMapping(wMapping)
-{
- for (int i = 0; i < 8; i++) {
- mI[i] = SoftVector(114);
- }
-}
-
-
-void TCHFACCHL1Decoder::writeLowSide(const RxBurst& inBurst)
-{
- OBJDCOUT("TCHFACCHL1Decoder::writeLowSide " << inBurst);
- // If the channel is closed, ignore the burst.
-// if (!active()) {
-// OBJDCOUT("TCHFACCHL1Decoder::writeLowSide not active, ignoring input");
-// return;
-// }
- processBurst(inBurst);
-}
-
-bool TCHFACCHL1Decoder::processBurst( const RxBurst& inBurst)
-{
- // Accept the burst into the deinterleaving buffer.
- // Return true if we are ready to interleave.
-
- // TODO -- One quick test of burst validity is to look at the tail bits.
- // We could do that as a double-check against putting garbage into
- // the interleaver or accepting bad parameters.
-
- // Get the physical parameters of the burst.
- // RSSI is dB wrt full scale.
-// mRSSI = inBurst.RSSI();
- // Timing error is a float in symbol intervals.
-// mTimingError = inBurst.timingError();
- // This flag is used as a half-ass semaphore.
- // It is cleared when the new value is read.
-// mPhyNew = true;
-
- // The reverse index runs 0..3 as the bursts arrive.
- // It is the "B" index of GSM 05.03 3.1.3 and 3.1.4.
- int B = mMapping.reverseMapping(inBurst.time().FN()) % 8;
- // A negative value means that the demux is misconfigured.
- assert(B >= 0);
- OBJDCOUT("TCHFACCHL1Decoder::processBurst B=" << B << " " << inBurst);
-
- // Pull the data fields (e-bits) out of the burst and put them into i[B][].
- // GSM 05.03 3.1.4
- inBurst.data1().copyToSegment(mI[B], 0);
- inBurst.data2().copyToSegment(mI[B], 57);
-
- // Every 4th frame is the start of a new block.
- // So if this isn't a "4th" frame, return now.
- if (B % 4 != 3) return false;
-
- // Deinterleave according to the diagonal "phase" of B.
- // See GSM 05.03 3.1.3.
- // Deinterleaves i[] to c[]
- if (B == 3) deinterleave(4);
- else deinterleave(0);
-
- // See if this was the end of a stolen frame, GSM 05.03 4.2.5.
- bool stolen = inBurst.Hl();
- OBJDCOUT("TCHFACCHL!Decoder::processBurst Hl=" << inBurst.Hl() << " Hu=" << inBurst.Hu());
- /* if (stolen) {
- if (decode()) {
- OBJDCOUT("TCHFACCHL1Decoder::processBurst good FACCH frame");
- countGoodFrame();
- handleGoodFrame();
- } else {
- OBJDCOUT("TCHFACCHL1Decoder::processBurst bad FACCH frame");
- countBadFrame();
- }
- }*/
-
- // Always feed the traffic channel, even on a stolen frame.
- // decodeTCH will handle the GSM 06.11 bad frmae processing.
- bool traffic = decodeTCH(stolen);
-// if (traffic) {
- OBJDCOUT("TCHFACCHL1Decoder::processBurst good TCH frame");
-// countGoodFrame();
- // Don't let the channel timeout.
- // mLock.lock();
- // mT3109.set();
- // mLock.unlock();
-// }
-// else countBadFrame();
-
- return traffic;
-}
-
-void TCHFACCHL1Decoder::deinterleave(int blockOffset )
-{
- OBJDCOUT("TCHFACCHL1Decoder::deinterleave blockOffset=" << blockOffset);
- for (int k = 0; k < 456; k++) {
- int B = ( k + blockOffset ) % 8;
- int j = 2 * ((49 * k) % 57) + ((k % 8) / 4);
- mC[k] = mI[B][j];
- mI[B][j] = 0.5F;
- //OBJDCOUT("deinterleave k="<<k<<" B="<<B<<" j="<<j);
- }
-}
-
-bool TCHFACCHL1Decoder::decodeTCH(bool stolen)
-{
- // GSM 05.02 3.1.2, but backwards
-
- // If the frame wasn't stolen, we'll update this with parity later.
- bool good = !stolen;
-
- // Good or bad, we will be sending *something* to the speech channel.
- // Allocate it in this scope.
- unsigned char * newFrame = new unsigned char[33];
-
- if (!stolen) {
-
- // 3.1.2.2
- // decode from c[] to u[]
- mClass1_c.decode(mVCoder, mTCHU);
- //mC.head(378).decode(mVCoder,mTCHU);
-
- // 3.1.2.2
- // copy class 2 bits c[] to d[]
- mClass2_c.sliced().copyToSegment(mTCHD, 182);
- //mC.segment(378,78).sliced().copyToSegment(mTCHD,182);
-
- // 3.1.2.1
- // copy class 1 bits u[] to d[]
- for (unsigned k = 0; k <= 90; k++) {
- mTCHD[2*k] = mTCHU[k];
- mTCHD[2*k+1] = mTCHU[184-k];
- }
-
- // 3.1.2.1
- // check parity of class 1A
- unsigned sentParity = (~mTCHU.peekField(91, 3)) & 0x07;
- //unsigned calcParity = mTCHD.head(50).parity(mTCHParity) & 0x07;
- unsigned calcParity = mClass1A_d.parity(mTCHParity) & 0x07;
-
- // 3.1.2.2
- // Check the tail bits, too.
- unsigned tail = mTCHU.peekField(185, 4);
-
- OBJDCOUT("TCHFACCHL1Decoder::decodeTCH c[]=" << mC);
- //OBJDCOUT("TCHFACCHL1Decoder::decodeTCH u[]=" << mTCHU);
- OBJDCOUT("TCHFACCHL1Decoder::decodeTCH d[]=" << mTCHD);
- OBJDCOUT("TCHFACCHL1Decoder::decodeTCH sentParity=" << sentParity
- << " calcParity=" << calcParity << " tail=" << tail);
- good = (sentParity == calcParity) && (tail == 0);
- if (good) {
- // Undo Um's importance-sorted bit ordering.
- // See GSM 05.03 3.1 and Tablee 2.
- BitVector payload = mVFrame.payload();
- mTCHD.unmap(g610BitOrder, 260, payload);
- mVFrame.pack(newFrame);
- // Save a copy for bad frame processing.
- memcpy(mPrevGoodFrame, newFrame, 33);
- return true;
- }
- }
-
- if (!good) {
- // TODO -- Bad frame processing, GSM 06.11.
- // For now, just repeat the last good frame.
- // TODO -- Need to apply attenuation and randomization of grid positions.
- memcpy(newFrame, mPrevGoodFrame, 33);
- //d_gsm_file.write((char *)newFrame, 33);
- }
-
-
- // Good or bad, we must feed the speech channel.
-// mSpeechQ.write(newFrame);
-
-
- return false;
-}
-
-// vim: ts=4 sw=4
diff --git a/src/lib/decoder/openbtsstuff/GSML1FEC.h b/src/lib/decoder/openbtsstuff/GSML1FEC.h
deleted file mode 100644
index c367681..0000000
--- a/src/lib/decoder/openbtsstuff/GSML1FEC.h
+++ /dev/null
@@ -1,146 +0,0 @@
-/*
-* Copyright 2008 Free Software Foundation, Inc.
-*
-*
-* 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 3 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, see <http://www.gnu.org/licenses/>.
-*
-* This software is distributed under the terms of the GNU Public License.
-* See the COPYING file in the main directory for details.
-*/
-
-
-
-#ifndef GSML1FEC_H
-#define GSML1FEC_H
-
-//#include "Threads.h"
-#include "Assert.h"
-#include "BitVector.h"
-
-#include "GSMCommon.h"
-//#include "GSMTransfer.h"
-#include "GSMTDMA.h"
-#include "VocoderFrame.h"
-#include "RxBurst.h"
-//#include "GSM610Tables.h"
-#include <stdio.h>
-
-
-
-namespace GSM
-{
-
-
-//class SAPMux;
- class L1FEC;
- class L1Decoder;
-
-
-
- /*
- Naming convention for bit vectors follows GSM 05.03 Section 2.2.
- d[k] data
- u[k] data bits after first encoding step
- c[k] data bits after second encoding step
- i[B][k] interleaved data bits
- e[B][k] bits in a burst
- */
-
-
-
-
- /** L1 decoder used for full rate TCH and FACCH -- mostly from GSM 05.03 3.1 and 4.2 */
-//: public XCCHL1Decoder
- class TCHFACCHL1Decoder
- {
-
- protected:
- SoftVector mI[8]; ///< deinterleaving history, 8 blocks instead of 4
- SoftVector mC; ///< c[], as per GSM 05.03 2.2
- BitVector mTCHU; ///< u[] (uncoded) in the spec
- BitVector mTCHD; ///< d[] (data) in the spec
- SoftVector mClass1_c; ///< the class 1 part of c[]
- BitVector mClass1A_d; ///< the class 1A part of d[]
- SoftVector mClass2_c; ///< the class 2 part of c[]
- ViterbiR2O4 mVCoder;
-
- VocoderFrame mVFrame; ///< unpacking buffer for vocoder frame
- unsigned char mPrevGoodFrame[33]; ///< previous good frame.
-
- Parity mTCHParity;
- const TDMAMapping& mMapping; ///< multiplexing description
-
-// InterthreadQueue<unsigned char> mSpeechQ; ///< output queue for speech frames
-
- static const unsigned mMaxQSize = 3;
-
-
- public:
-
- TCHFACCHL1Decoder( const TDMAMapping& wMapping );
-
- ChannelType channelType() const {
- return FACCHType;
- }
-
-
- /** TCH/FACCH has a special-case writeLowSide. */
- void writeLowSide(const RxBurst& inBurst);
-
- /**
- Unlike other DCCHs, TCH/FACCH process burst calls
- deinterleave, decode, handleGoodFrame.
- */
- bool processBurst( const RxBurst& );
-
- /** Deinterleave i[] to c[]. */
- void deinterleave(int blockOffset );
-
- void replaceFACCH( int blockOffset );
-
- /**
- Decode a traffic frame from TCHI[] and enqueue it.
- Return true if there's a good frame.
- */
- bool decodeTCH(bool stolen);
-
- unsigned char * get_voice_frame(){
- return mPrevGoodFrame;
- }
- /**
- Receive a traffic frame.
- Non-blocking. Returns NULL if queue is dry.
- Caller is responsible for deleting the returned array.
- */
-// unsigned char *recvTCH() { return mSpeechQ.read(0); }
-
- /** Return count of internally-queued traffic frames. */
-// unsigned queueSize() const { return mSpeechQ.size(); }
-
- };
-
-
-
-
-
-
-}; // namespace GSM
-
-
-
-
-
-#endif
-
-// vim: ts=4 sw=4
diff --git a/src/lib/decoder/openbtsstuff/GSMTDMA.cpp b/src/lib/decoder/openbtsstuff/GSMTDMA.cpp
deleted file mode 100644
index 27ebe0e..0000000
--- a/src/lib/decoder/openbtsstuff/GSMTDMA.cpp
+++ /dev/null
@@ -1,337 +0,0 @@
-/*
-* Copyright 2008 Free Software Foundation, Inc.
-*
-* This software is distributed under the terms of the GNU Public License.
-* See the COPYING file in the main directory for details.
-
- 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 3 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, see <http://www.gnu.org/licenses/>.
-
-*/
-
-
-#include "GSMTDMA.h"
-
-
-using namespace GSM;
-
-
-
-
-TDMAMapping::TDMAMapping(TypeAndOffset
- wTypeAndOffset, bool wDownlink, bool wUplink, char wAllowedSlots, bool wC0Only,
- unsigned wRepeatLength, unsigned wNumFrames, const unsigned *wFrameMapping)
- :mTypeAndOffset(wTypeAndOffset),
- mDownlink(wDownlink),mUplink(wUplink),mAllowedSlots(wAllowedSlots),mC0Only(wC0Only),
- mRepeatLength(wRepeatLength),mNumFrames(wNumFrames),mFrameMapping(wFrameMapping)
-{
- // Sanity check.
- assert(mRepeatLength<=mMaxRepeatLength);
-
- // Default, -1, means a non-occupied position.
- for (unsigned i=0; i<mMaxRepeatLength; i++) mReverseMapping[i]=-1;
-
- // Fill in the reverse map, precomputed for speed.
- for (unsigned i=0; i<mNumFrames; i++) {
- unsigned mapping = mFrameMapping[i];
- assert(mapping<mRepeatLength);
- mReverseMapping[mapping] = i;
- }
-}
-
-
-
-
-
-/** A macro to save some typing when we set up TDMA maps. */
-#define MAKE_TDMA_MAPPING(NAME,TYPEANDOFFSET,DOWNLINK,UPLINK,ALLOWEDSLOTS,C0ONLY,REPEAT) \
- const TDMAMapping GSM::g##NAME##Mapping(TYPEANDOFFSET,DOWNLINK,UPLINK,ALLOWEDSLOTS,C0ONLY, \
- REPEAT,sizeof(NAME##Frames)/sizeof(unsigned),NAME##Frames)
-
-const unsigned LoopbackTestFullFrames[] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47};
-MAKE_TDMA_MAPPING(LoopbackTestFull,TDMA_MISC,true,true,0xff,false,51);
-
-const unsigned FCCHFrames[] = {0,10,20,30,40};
-MAKE_TDMA_MAPPING(FCCH,TDMA_BEACON,true,false,0x01,true,51);
-
-const unsigned SCHFrames[] = {1,11,21,31,41};
-MAKE_TDMA_MAPPING(SCH,TDMA_BEACON,true,false,0x01,true,51);
-
-const unsigned BCCHFrames[] = {2,3,4,5};
-MAKE_TDMA_MAPPING(BCCH,TDMA_BEACON,true,false,0x55,true,51);
-
-// Note that we removed frames for the SDCCH components of the Combination-V C0T0.
-const unsigned RACHC5Frames[] = {4,5,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,45,46};
-MAKE_TDMA_MAPPING(RACHC5,TDMA_BEACON,false,true,0x55,true,51);
-
-// CCCH 0-2 are used in C-IV and C-V. The others are used in C-IV only.
-
-const unsigned CCCH_0Frames[] = {6,7,8,9};
-MAKE_TDMA_MAPPING(CCCH_0,TDMA_BEACON,true,false,0x55,true,51);
-
-const unsigned CCCH_1Frames[] = {12,13,14,15};
-MAKE_TDMA_MAPPING(CCCH_1,TDMA_BEACON,true,false,0x55,true,51);
-
-const unsigned CCCH_2Frames[] = {16,17,18,19};
-MAKE_TDMA_MAPPING(CCCH_2,TDMA_BEACON,true,false,0x55,true,51);
-
-const unsigned CCCH_3Frames[] = {22,23,24,25};
-MAKE_TDMA_MAPPING(CCCH_3,TDMA_BEACON,true,false,0x55,true,51);
-
-// TODO -- Other CCCH subchannels 4-8 for support of C-IV.
-
-const unsigned SDCCH_4_0DFrames[] = {22,23,24,25};
-MAKE_TDMA_MAPPING(SDCCH_4_0D,SDCCH_4_0,true,false,0x01,true,51);
-
-const unsigned SDCCH_4_0UFrames[] = {37,38,39,40};
-MAKE_TDMA_MAPPING(SDCCH_4_0U,SDCCH_4_0,false,true,0x01,true,51);
-
-const unsigned SDCCH_4_1DFrames[] = {26,27,28,29};
-MAKE_TDMA_MAPPING(SDCCH_4_1D,SDCCH_4_1,true,false,0x01,true,51);
-
-const unsigned SDCCH_4_1UFrames[] = {41,42,43,44};
-MAKE_TDMA_MAPPING(SDCCH_4_1U,SDCCH_4_1,false,true,0x01,true,51);
-
-const unsigned SDCCH_4_2DFrames[] = {32,33,34,35};
-MAKE_TDMA_MAPPING(SDCCH_4_2D,SDCCH_4_2,true,false,0x01,true,51);
-
-const unsigned SDCCH_4_2UFrames[] = {47,48,49,50};
-MAKE_TDMA_MAPPING(SDCCH_4_2U,SDCCH_4_2,false,true,0x01,true,51);
-
-const unsigned SDCCH_4_3DFrames[] = {36,37,38,39};
-MAKE_TDMA_MAPPING(SDCCH_4_3D,SDCCH_4_3,true,false,0x01,true,51);
-
-const unsigned SDCCH_4_3UFrames[] = {0,1,2,3};
-MAKE_TDMA_MAPPING(SDCCH_4_3U,SDCCH_4_3,false,true,0x01,true,51);
-
-
-const unsigned SACCH_C4_0DFrames[] = {42,43,44,45};
-MAKE_TDMA_MAPPING(SACCH_C4_0D,SDCCH_4_0,true,false,0x01,true,102);
-
-const unsigned SACCH_C4_0UFrames[] = {57,58,59,60};
-MAKE_TDMA_MAPPING(SACCH_C4_0U,SDCCH_4_0,false,true,0x01,true,102);
-
-const unsigned SACCH_C4_1DFrames[] = {46,47,48,49};
-MAKE_TDMA_MAPPING(SACCH_C4_1D,SDCCH_4_1,true,false,0x01,true,102);
-
-const unsigned SACCH_C4_1UFrames[] = {61,62,63,64};
-MAKE_TDMA_MAPPING(SACCH_C4_1U,SDCCH_4_1,false,true,0x01,true,102);
-
-const unsigned SACCH_C4_2DFrames[] = {93,94,95,96};
-MAKE_TDMA_MAPPING(SACCH_C4_2D,SDCCH_4_2,true,false,0x01,true,102);
-
-const unsigned SACCH_C4_2UFrames[] = {6,7,8,9};
-MAKE_TDMA_MAPPING(SACCH_C4_2U,SDCCH_4_2,false,true,0x01,true,102);
-
-const unsigned SACCH_C4_3DFrames[] = {97,98,99,100};
-MAKE_TDMA_MAPPING(SACCH_C4_3D,SDCCH_4_3,true,false,0x01,true,102);
-
-const unsigned SACCH_C4_3UFrames[] = {10,11,12,13};
-MAKE_TDMA_MAPPING(SACCH_C4_3U,SDCCH_4_3,false,true,0x01,true,102);
-
-
-const unsigned SDCCH_8_0DFrames[] = {0,1,2,3};
-MAKE_TDMA_MAPPING(SDCCH_8_0D,SDCCH_8_0,true,false,0xFF,true,51);
-
-const unsigned SDCCH_8_0UFrames[] = {15,16,17,18};
-MAKE_TDMA_MAPPING(SDCCH_8_0U,SDCCH_8_0,false,true,0xFF,true,51);
-
-const unsigned SDCCH_8_1DFrames[] = {4,5,6,7};
-MAKE_TDMA_MAPPING(SDCCH_8_1D,SDCCH_8_1,true,false,0xFF,true,51);
-
-const unsigned SDCCH_8_1UFrames[] = {19,20,21,22};
-MAKE_TDMA_MAPPING(SDCCH_8_1U,SDCCH_8_1,false,true,0xFF,true,51);
-
-const unsigned SDCCH_8_2DFrames[] = {8,9,10,11};
-MAKE_TDMA_MAPPING(SDCCH_8_2D,SDCCH_8_2,true,false,0xFF,true,51);
-
-const unsigned SDCCH_8_2UFrames[] = {23,24,25,26};
-MAKE_TDMA_MAPPING(SDCCH_8_2U,SDCCH_8_2,false,true,0xFF,true,51);
-
-const unsigned SDCCH_8_3DFrames[] = {12,13,14,15};
-MAKE_TDMA_MAPPING(SDCCH_8_3D,SDCCH_8_3,true,false,0xFF,true,51);
-
-const unsigned SDCCH_8_3UFrames[] = {27,28,29,30};
-MAKE_TDMA_MAPPING(SDCCH_8_3U,SDCCH_8_3,false,true,0xFF,true,51);
-
-const unsigned SDCCH_8_4DFrames[] = {16,17,18,19};
-MAKE_TDMA_MAPPING(SDCCH_8_4D,SDCCH_8_4,true,false,0xFF,true,51);
-
-const unsigned SDCCH_8_4UFrames[] = {31,32,33,34};
-MAKE_TDMA_MAPPING(SDCCH_8_4U,SDCCH_8_4,false,true,0xFF,true,51);
-
-const unsigned SDCCH_8_5DFrames[] = {20,21,22,23};
-MAKE_TDMA_MAPPING(SDCCH_8_5D,SDCCH_8_5,true,false,0xFF,true,51);
-
-const unsigned SDCCH_8_5UFrames[] = {35,36,37,38};
-MAKE_TDMA_MAPPING(SDCCH_8_5U,SDCCH_8_5,false,true,0xFF,true,51);
-
-const unsigned SDCCH_8_6DFrames[] = {24,25,26,27};
-MAKE_TDMA_MAPPING(SDCCH_8_6D,SDCCH_8_6,true,false,0xFF,true,51);
-
-const unsigned SDCCH_8_6UFrames[] = {39,40,41,42};
-MAKE_TDMA_MAPPING(SDCCH_8_6U,SDCCH_8_6,false,true,0xFF,true,51);
-
-const unsigned SDCCH_8_7DFrames[] = {28,29,30,31};
-MAKE_TDMA_MAPPING(SDCCH_8_7D,SDCCH_8_7,true,false,0xFF,true,51);
-
-const unsigned SDCCH_8_7UFrames[] = {43,44,45,46};
-MAKE_TDMA_MAPPING(SDCCH_8_7U,SDCCH_8_7,false,true,0xFF,true,51);
-
-
-const unsigned SACCH_C8_0DFrames[] = {32,33,34,35};
-MAKE_TDMA_MAPPING(SACCH_C8_0D,SDCCH_8_0,true,false,0xFF,true,102);
-
-const unsigned SACCH_C8_0UFrames[] = {47,48,49,50};
-MAKE_TDMA_MAPPING(SACCH_C8_0U,SDCCH_8_0,false,true,0xFF,true,102);
-
-const unsigned SACCH_C8_1DFrames[] = {36,37,38,39};
-MAKE_TDMA_MAPPING(SACCH_C8_1D,SDCCH_8_1,true,false,0xFF,true,102);
-
-const unsigned SACCH_C8_1UFrames[] = {51,52,53,54};
-MAKE_TDMA_MAPPING(SACCH_C8_1U,SDCCH_8_1,false,true,0xFF,true,102);
-
-const unsigned SACCH_C8_2DFrames[] = {40,41,42,43};
-MAKE_TDMA_MAPPING(SACCH_C8_2D,SDCCH_8_2,true,false,0xFF,true,102);
-
-const unsigned SACCH_C8_2UFrames[] = {55,56,57,58};
-MAKE_TDMA_MAPPING(SACCH_C8_2U,SDCCH_8_2,false,true,0xFF,true,102);
-
-const unsigned SACCH_C8_3DFrames[] = {44,45,46,47};
-MAKE_TDMA_MAPPING(SACCH_C8_3D,SDCCH_8_3,true,false,0xFF,true,102);
-
-const unsigned SACCH_C8_3UFrames[] = {59,60,61,62};
-MAKE_TDMA_MAPPING(SACCH_C8_3U,SDCCH_8_3,false,true,0xFF,true,102);
-
-const unsigned SACCH_C8_4DFrames[] = {82,84,85,86};
-MAKE_TDMA_MAPPING(SACCH_C8_4D,SDCCH_8_4,true,false,0xFF,true,102);
-
-const unsigned SACCH_C8_4UFrames[] = {98,99,100,101};
-MAKE_TDMA_MAPPING(SACCH_C8_4U,SDCCH_8_4,false,true,0xFF,true,102);
-
-const unsigned SACCH_C8_5DFrames[] = {87,88,89,90};
-MAKE_TDMA_MAPPING(SACCH_C8_5D,SDCCH_8_5,true,false,0xFF,true,102);
-
-const unsigned SACCH_C8_5UFrames[] = {0,1,2,3};
-MAKE_TDMA_MAPPING(SACCH_C8_5U,SDCCH_8_5,false,true,0xFF,true,102);
-
-const unsigned SACCH_C8_6DFrames[] = {91,92,93,94};
-MAKE_TDMA_MAPPING(SACCH_C8_6D,SDCCH_8_6,true,false,0xFF,true,102);
-
-const unsigned SACCH_C8_6UFrames[] = {4,5,6,7};
-MAKE_TDMA_MAPPING(SACCH_C8_6U,SDCCH_8_6,false,true,0xFF,true,102);
-
-const unsigned SACCH_C8_7DFrames[] = {95,96,97,98};
-MAKE_TDMA_MAPPING(SACCH_C8_7D,SDCCH_8_7,true,false,0xFF,true,102);
-
-const unsigned SACCH_C8_7UFrames[] = {8,9,10,11};
-MAKE_TDMA_MAPPING(SACCH_C8_7U,SDCCH_8_7,false,true,0xFF,true,102);
-
-
-
-const unsigned SACCH_TF_T0Frames[] = {12,38,64,90};
-MAKE_TDMA_MAPPING(SACCH_TF_T0,TCHF_0,true,true,0x01,true,104);
-
-const unsigned SACCH_TF_T1Frames[] = {25,51,77,103};
-MAKE_TDMA_MAPPING(SACCH_TF_T1,TCHF_0,true,true,0x02,true,104);
-
-const unsigned SACCH_TF_T2Frames[] = {38,64,90,12};
-MAKE_TDMA_MAPPING(SACCH_TF_T2,TCHF_0,true,true,0x04,true,104);
-
-const unsigned SACCH_TF_T3Frames[] = {51,77,103,25};
-MAKE_TDMA_MAPPING(SACCH_TF_T3,TCHF_0,true,true,0x08,true,104);
-
-const unsigned SACCH_TF_T4Frames[] = {64,90,12,38};
-MAKE_TDMA_MAPPING(SACCH_TF_T4,TCHF_0,true,true,0x10,true,104);
-
-const unsigned SACCH_TF_T5Frames[] = {77,103,25,51};
-MAKE_TDMA_MAPPING(SACCH_TF_T5,TCHF_0,true,true,0x20,true,104);
-
-const unsigned SACCH_TF_T6Frames[] = {90,12,38,64};
-MAKE_TDMA_MAPPING(SACCH_TF_T6,TCHF_0,true,true,0x40,true,104);
-
-const unsigned SACCH_TF_T7Frames[] = {103,25,51,77};
-MAKE_TDMA_MAPPING(SACCH_TF_T7,TCHF_0,true,true,0x80,true,104);
-
-const unsigned FACCH_TCHFFrames[] = {0,1,2,3,4,5,6,7,8,9,10,11,13,14,15,16,17,18,19,20,21,22,23,24};
-MAKE_TDMA_MAPPING(FACCH_TCHF,TCHF_0,true,true,0xff,true,26);
-
-
-
-
-
-
-
-const MappingPair GSM::gSDCCH_4_0Pair(gSDCCH_4_0DMapping,gSDCCH_4_0UMapping);
-const MappingPair GSM::gSDCCH_4_1Pair(gSDCCH_4_1DMapping,gSDCCH_4_1UMapping);
-const MappingPair GSM::gSDCCH_4_2Pair(gSDCCH_4_2DMapping,gSDCCH_4_2UMapping);
-const MappingPair GSM::gSDCCH_4_3Pair(gSDCCH_4_3DMapping,gSDCCH_4_3UMapping);
-const MappingPair GSM::gSDCCH_8_0Pair(gSDCCH_8_0DMapping,gSDCCH_8_0UMapping);
-const MappingPair GSM::gSDCCH_8_1Pair(gSDCCH_8_1DMapping,gSDCCH_8_1UMapping);
-const MappingPair GSM::gSDCCH_8_2Pair(gSDCCH_8_2DMapping,gSDCCH_8_2UMapping);
-const MappingPair GSM::gSDCCH_8_3Pair(gSDCCH_8_3DMapping,gSDCCH_8_3UMapping);
-const MappingPair GSM::gSDCCH_8_4Pair(gSDCCH_8_4DMapping,gSDCCH_8_4UMapping);
-const MappingPair GSM::gSDCCH_8_5Pair(gSDCCH_8_5DMapping,gSDCCH_8_5UMapping);
-const MappingPair GSM::gSDCCH_8_6Pair(gSDCCH_8_6DMapping,gSDCCH_8_6UMapping);
-const MappingPair GSM::gSDCCH_8_7Pair(gSDCCH_8_7DMapping,gSDCCH_8_7UMapping);
-
-const MappingPair GSM::gSACCH_C4_0Pair(gSACCH_C4_0DMapping,gSACCH_C4_0UMapping);
-const MappingPair GSM::gSACCH_C4_1Pair(gSACCH_C4_1DMapping,gSACCH_C4_1UMapping);
-const MappingPair GSM::gSACCH_C4_2Pair(gSACCH_C4_2DMapping,gSACCH_C4_2UMapping);
-const MappingPair GSM::gSACCH_C4_3Pair(gSACCH_C4_3DMapping,gSACCH_C4_3UMapping);
-const MappingPair GSM::gSACCH_C8_0Pair(gSACCH_C8_0DMapping,gSACCH_C8_0UMapping);
-const MappingPair GSM::gSACCH_C8_1Pair(gSACCH_C8_1DMapping,gSACCH_C8_1UMapping);
-const MappingPair GSM::gSACCH_C8_2Pair(gSACCH_C8_2DMapping,gSACCH_C8_2UMapping);
-const MappingPair GSM::gSACCH_C8_3Pair(gSACCH_C8_3DMapping,gSACCH_C8_3UMapping);
-const MappingPair GSM::gSACCH_C8_4Pair(gSACCH_C8_4DMapping,gSACCH_C8_4UMapping);
-const MappingPair GSM::gSACCH_C8_5Pair(gSACCH_C8_5DMapping,gSACCH_C8_5UMapping);
-const MappingPair GSM::gSACCH_C8_6Pair(gSACCH_C8_6DMapping,gSACCH_C8_6UMapping);
-const MappingPair GSM::gSACCH_C8_7Pair(gSACCH_C8_7DMapping,gSACCH_C8_7UMapping);
-
-const MappingPair GSM::gFACCH_TCHFPair(gFACCH_TCHFMapping,gFACCH_TCHFMapping);
-
-const MappingPair GSM::gSACCH_FT_T0Pair(gSACCH_TF_T0Mapping, gSACCH_TF_T0Mapping);
-const MappingPair GSM::gSACCH_FT_T1Pair(gSACCH_TF_T1Mapping, gSACCH_TF_T1Mapping);
-const MappingPair GSM::gSACCH_FT_T2Pair(gSACCH_TF_T2Mapping, gSACCH_TF_T2Mapping);
-const MappingPair GSM::gSACCH_FT_T3Pair(gSACCH_TF_T3Mapping, gSACCH_TF_T3Mapping);
-const MappingPair GSM::gSACCH_FT_T4Pair(gSACCH_TF_T4Mapping, gSACCH_TF_T4Mapping);
-const MappingPair GSM::gSACCH_FT_T5Pair(gSACCH_TF_T5Mapping, gSACCH_TF_T5Mapping);
-const MappingPair GSM::gSACCH_FT_T6Pair(gSACCH_TF_T6Mapping, gSACCH_TF_T6Mapping);
-const MappingPair GSM::gSACCH_FT_T7Pair(gSACCH_TF_T7Mapping, gSACCH_TF_T7Mapping);
-
-
-
-const CompleteMapping GSM::gSDCCH_4_0(gSDCCH_4_0Pair,gSACCH_C4_0Pair);
-const CompleteMapping GSM::gSDCCH_4_1(gSDCCH_4_1Pair,gSACCH_C4_1Pair);
-const CompleteMapping GSM::gSDCCH_4_2(gSDCCH_4_2Pair,gSACCH_C4_2Pair);
-const CompleteMapping GSM::gSDCCH_4_3(gSDCCH_4_3Pair,gSACCH_C4_3Pair);
-const CompleteMapping GSM::gSDCCH_8_0(gSDCCH_8_0Pair,gSACCH_C8_0Pair);
-const CompleteMapping GSM::gSDCCH_8_1(gSDCCH_8_1Pair,gSACCH_C8_1Pair);
-const CompleteMapping GSM::gSDCCH_8_2(gSDCCH_8_2Pair,gSACCH_C8_2Pair);
-const CompleteMapping GSM::gSDCCH_8_3(gSDCCH_8_3Pair,gSACCH_C8_3Pair);
-const CompleteMapping GSM::gSDCCH_8_4(gSDCCH_8_4Pair,gSACCH_C8_4Pair);
-const CompleteMapping GSM::gSDCCH_8_5(gSDCCH_8_5Pair,gSACCH_C8_5Pair);
-const CompleteMapping GSM::gSDCCH_8_6(gSDCCH_8_6Pair,gSACCH_C8_6Pair);
-const CompleteMapping GSM::gSDCCH_8_7(gSDCCH_8_7Pair,gSACCH_C8_7Pair);
-
-const CompleteMapping GSM::gTCHF_T0(gFACCH_TCHFPair,gSACCH_FT_T0Pair);
-const CompleteMapping GSM::gTCHF_T1(gFACCH_TCHFPair,gSACCH_FT_T1Pair);
-const CompleteMapping GSM::gTCHF_T2(gFACCH_TCHFPair,gSACCH_FT_T2Pair);
-const CompleteMapping GSM::gTCHF_T3(gFACCH_TCHFPair,gSACCH_FT_T3Pair);
-const CompleteMapping GSM::gTCHF_T4(gFACCH_TCHFPair,gSACCH_FT_T4Pair);
-const CompleteMapping GSM::gTCHF_T5(gFACCH_TCHFPair,gSACCH_FT_T5Pair);
-const CompleteMapping GSM::gTCHF_T6(gFACCH_TCHFPair,gSACCH_FT_T6Pair);
-const CompleteMapping GSM::gTCHF_T7(gFACCH_TCHFPair,gSACCH_FT_T7Pair);
-
-
-
diff --git a/src/lib/decoder/openbtsstuff/GSMTDMA.h b/src/lib/decoder/openbtsstuff/GSMTDMA.h
deleted file mode 100644
index 3b55b94..0000000
--- a/src/lib/decoder/openbtsstuff/GSMTDMA.h
+++ /dev/null
@@ -1,358 +0,0 @@
-/**@file Common-use GSM declarations, most from the GSM 04.xx and 05.xx series. */
-/*
-* Copyright 2008 Free Software Foundation, Inc.
-*
-* This software is distributed under the terms of the GNU Public License.
-* See the COPYING file in the main directory for details.
-
- 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 3 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, see <http://www.gnu.org/licenses/>.
-
-*/
-
-
-
-#ifndef GSMTDMA_H
-#define GSMTDMA_H
-
-
-#include "GSMCommon.h"
-
-
-namespace GSM {
-
-
-/**
- A description of a channel's multiplexing pattern.
- From GSM 05.02 Clause 7.
- This object encodes a line from tables 1-4 in the spec.
- The columns of interest in this encoding are:
- - 1, Channel Designation
- - 2, Subchannel
- - 3, Direction
- - 4, Allowable Time Slot Assignments
- - 5, Allowable RF Channel Assignments
- - 7, Repeat Length in TDMA Frames
- - 8, Interleaved Block TDMA Frame Mapping
-
- Col 6, Burst Type, is implied by 1 & 2 and encoded into the transcevier source code.
-*/
-class TDMAMapping {
-
- public:
-
- /// The longest "repeat length" of any channel we support is 104 for the SACCH/TF.
- static const unsigned mMaxRepeatLength = 104;
-
- private:
-
- TypeAndOffset mTypeAndOffset; ///< col 1, 2, encoded as per GSM 04.08 10.5.2.5
- bool mDownlink; ///< col 3, true for downlink channels
- bool mUplink; ///< col 3, true for uplink channels
- char mAllowedSlots; ///< col 4, an 8-bit mask
- bool mC0Only; ///< col 5, true if channel is limited to C0
- unsigned mRepeatLength; ///< col 7
- unsigned mNumFrames; ///< number of occupied frames in col 8
- const unsigned *mFrameMapping; ///< col 8
- unsigned mReverseMapping[mMaxRepeatLength]; ///< index reversal of mapping, -1 means unused
-
-
- public:
-
-
- /**
- Construct a TDMAMapping, encoding one line of GSM 05.02 Clause 7 Tables 1-4.
- @param wTypeAndOffset Encoding of "Channel designnation". See GSM 04.08 10.5.2.5.
- @param wDownlink True for downlink and bidirectional hannels
- @param wUplink True for uplink and bidirectional channels
- @param wRepeatLength "Repeat Length in TDMA Frames"
- @param wNumFrames Number of occupied TDMA frames in frame mapping.
- @param wFrameMapping "Interleaved Block TDMA Frame Mapping" -- MUST PERSIST!!
- */
- TDMAMapping(TypeAndOffset wTypeAndOffset,
- bool wDownlink, bool wUplink, char wAllowedSlots, bool wC0Only,
- unsigned wRepeatLength, unsigned wNumFrames, const unsigned *wFrameMapping);
-
- /** Given a count of frames sent, return the corresponding frame number. */
- unsigned frameMapping(unsigned count) const
- { return mFrameMapping[count % mNumFrames]; }
-
- /** Given a frame number, return the corresponding count, modulo patten length. */
- int reverseMapping(unsigned FN) const
- { return mReverseMapping[FN % mRepeatLength]; }
-
- /**@name Simple accessors. */
- //@{
- unsigned numFrames() const { return mNumFrames; }
-
- unsigned repeatLength() const { return mRepeatLength; }
-
- TypeAndOffset typeAndOffset() const { return mTypeAndOffset; }
-
- bool uplink() const { return mUplink; }
-
- bool downlink() const { return mDownlink; }
-
- bool C0Only() const { return mC0Only; }
- //@}
-
- ///< Return true if this channel is allowed on this slot.
- bool allowedSlot(unsigned slot) const
- { return mAllowedSlots & (1<<slot); }
-};
-
-
-
-/**@name Mux parameters for standard channels, from GSM 05.03 Clause 7 Tables 1-4. */
-//@{
-/**@name Beacon channels */
-//@{
-extern const TDMAMapping gFCCHMapping; ///< GSM 05.02 Clause 7 Table 3 Line 1 B0-B4
-extern const TDMAMapping gSCHMapping; ///< GSM 05.02 Clause 7 Table 3 Line 2 B0-B4
-extern const TDMAMapping gBCCHMapping; ///< GSM 05.02 Clause 7 Table 3 Line 3
-/// GSM 05.02 Clause 7 Table 3 Line 7 B0-B50, excluding C-V SDCCH parts (SDCCH/4 and SCCH/C4)
-extern const TDMAMapping gRACHC5Mapping;
-extern const TDMAMapping gCCCH_0Mapping; ///< GSM 05.02 Clause 7 Table 3 Line 5 B0
-extern const TDMAMapping gCCCH_1Mapping; ///< GSM 05.02 Clause 7 Table 3 Line 5 B1
-extern const TDMAMapping gCCCH_2Mapping; ///< GSM 05.02 Clause 7 Table 3 Line 5 B2
-extern const TDMAMapping gCCCH_3Mapping; ///< GSM 05.02 Clause 7 Table 3 Line 5 B3
-extern const TDMAMapping gCCCH_4Mapping; ///< GSM 05.02 Clause 7 Table 3 Line 5 B4
-extern const TDMAMapping gCCCH_5Mapping; ///< GSM 05.02 Clause 7 Table 3 Line 5 B5
-extern const TDMAMapping gCCCH_6Mapping; ///< GSM 05.02 Clause 7 Table 3 Line 5 B6
-extern const TDMAMapping gCCCH_7Mapping; ///< GSM 05.02 Clause 7 Table 3 Line 5 B7
-extern const TDMAMapping gCCCH_8Mapping; ///< GSM 05.02 Clause 7 Table 3 Line 5 B8
-//@}
-/**@name SDCCH */
-//@{
-///@name For Combination V
-//@{
-extern const TDMAMapping gSDCCH_4_0DMapping; ///< GSM 05.02 Clause 7 Table 3 Line 10/0D
-extern const TDMAMapping gSDCCH_4_0UMapping; ///< GSM 05.02 Clause 7 Table 3 Line 10/0U
-extern const TDMAMapping gSDCCH_4_1DMapping;
-extern const TDMAMapping gSDCCH_4_1UMapping;
-extern const TDMAMapping gSDCCH_4_2DMapping;
-extern const TDMAMapping gSDCCH_4_2UMapping;
-extern const TDMAMapping gSDCCH_4_3DMapping;
-extern const TDMAMapping gSDCCH_4_3UMapping;
-//@}
-///@name For Combination VII
-//@{
-extern const TDMAMapping gSDCCH_8_0DMapping;
-extern const TDMAMapping gSDCCH_8_0UMapping;
-extern const TDMAMapping gSDCCH_8_1DMapping;
-extern const TDMAMapping gSDCCH_8_1UMapping;
-extern const TDMAMapping gSDCCH_8_2DMapping;
-extern const TDMAMapping gSDCCH_8_2UMapping;
-extern const TDMAMapping gSDCCH_8_3DMapping;
-extern const TDMAMapping gSDCCH_8_3UMapping;
-extern const TDMAMapping gSDCCH_8_4DMapping;
-extern const TDMAMapping gSDCCH_8_4UMapping;
-extern const TDMAMapping gSDCCH_8_5DMapping;
-extern const TDMAMapping gSDCCH_8_5UMapping;
-extern const TDMAMapping gSDCCH_8_6DMapping;
-extern const TDMAMapping gSDCCH_8_6UMapping;
-extern const TDMAMapping gSDCCH_8_7DMapping;
-extern const TDMAMapping gSDCCH_8_7UMapping;
-//@}
-//@}
-/**@name SACCH */
-//@{
-/**name SACCH for SDCCH */
-//@{
-///@name For Combination V
-//@{
-extern const TDMAMapping gSACCH_C4_0DMapping;
-extern const TDMAMapping gSACCH_C4_0UMapping;
-extern const TDMAMapping gSACCH_C4_1DMapping;
-extern const TDMAMapping gSACCH_C4_1UMapping;
-extern const TDMAMapping gSACCH_C4_2DMapping;
-extern const TDMAMapping gSACCH_C4_2UMapping;
-extern const TDMAMapping gSACCH_C4_3DMapping;
-extern const TDMAMapping gSACCH_C4_3UMapping;
-//@}
-///@name For Combination VII
-//@{
-extern const TDMAMapping gSACCH_C8_0DMapping;
-extern const TDMAMapping gSACCH_C8_0UMapping;
-extern const TDMAMapping gSACCH_C8_1DMapping;
-extern const TDMAMapping gSACCH_C8_1UMapping;
-extern const TDMAMapping gSACCH_C8_2DMapping;
-extern const TDMAMapping gSACCH_C8_2UMapping;
-extern const TDMAMapping gSACCH_C8_3DMapping;
-extern const TDMAMapping gSACCH_C8_3UMapping;
-extern const TDMAMapping gSACCH_C8_4DMapping;
-extern const TDMAMapping gSACCH_C8_4UMapping;
-extern const TDMAMapping gSACCH_C8_5DMapping;
-extern const TDMAMapping gSACCH_C8_5UMapping;
-extern const TDMAMapping gSACCH_C8_6DMapping;
-extern const TDMAMapping gSACCH_C8_6UMapping;
-extern const TDMAMapping gSACCH_C8_7DMapping;
-extern const TDMAMapping gSACCH_C8_7UMapping;
-//@}
-//@}
-/**@name SACCH for TCH/F on different timeslots. */
-//@{
-extern const TDMAMapping gSACCH_TF_T0Mapping;
-extern const TDMAMapping gSACCH_TF_T1Mapping;
-extern const TDMAMapping gSACCH_TF_T2Mapping;
-extern const TDMAMapping gSACCH_TF_T3Mapping;
-extern const TDMAMapping gSACCH_TF_T4Mapping;
-extern const TDMAMapping gSACCH_TF_T5Mapping;
-extern const TDMAMapping gSACCH_TF_T6Mapping;
-extern const TDMAMapping gSACCH_TF_T7Mapping;
-//@}
-//@}
-/**name FACCH+TCH/F placement */
-//@{
-extern const TDMAMapping gFACCH_TCHFMapping;
-//@}
-/**@name Test fixtures. */
-extern const TDMAMapping gLoopbackTestFullMapping;
-extern const TDMAMapping gLoopbackTestHalfUMapping;
-extern const TDMAMapping gLoopbackTestHalfDMapping;
-//@}
-
-
-/** Combined uplink/downlink information. */
-class MappingPair {
-
- private:
-
- const TDMAMapping& mDownlink;
- const TDMAMapping& mUplink;
-
- public:
-
- MappingPair(const TDMAMapping& wDownlink, const TDMAMapping& wUplink)
- :mDownlink(wDownlink), mUplink(wUplink)
- {}
-
- MappingPair(const TDMAMapping& wMapping)
- :mDownlink(wMapping), mUplink(wMapping)
- {}
-
- const TDMAMapping& downlink() const { return mDownlink; }
- const TDMAMapping& uplink() const { return mUplink; }
-
-};
-
-
-/**@name Common placement pairs. */
-//@{
-/**@ SDCCH placement pairs. */
-//@{
-extern const MappingPair gSDCCH_4_0Pair;
-extern const MappingPair gSDCCH_4_1Pair;
-extern const MappingPair gSDCCH_4_2Pair;
-extern const MappingPair gSDCCH_4_3Pair;
-extern const MappingPair gSDCCH_8_0Pair;
-extern const MappingPair gSDCCH_8_1Pair;
-extern const MappingPair gSDCCH_8_2Pair;
-extern const MappingPair gSDCCH_8_3Pair;
-extern const MappingPair gSDCCH_8_4Pair;
-extern const MappingPair gSDCCH_8_5Pair;
-extern const MappingPair gSDCCH_8_6Pair;
-extern const MappingPair gSDCCH_8_7Pair;
-//@}
-/**@ SACCH-for-SDCCH placement pairs. */
-//@{
-extern const MappingPair gSACCH_C4_0Pair;
-extern const MappingPair gSACCH_C4_1Pair;
-extern const MappingPair gSACCH_C4_2Pair;
-extern const MappingPair gSACCH_C4_3Pair;
-extern const MappingPair gSACCH_C8_0Pair;
-extern const MappingPair gSACCH_C8_1Pair;
-extern const MappingPair gSACCH_C8_2Pair;
-extern const MappingPair gSACCH_C8_3Pair;
-extern const MappingPair gSACCH_C8_4Pair;
-extern const MappingPair gSACCH_C8_5Pair;
-extern const MappingPair gSACCH_C8_6Pair;
-extern const MappingPair gSACCH_C8_7Pair;
-//@}
-/**@name Traffic channels. */
-//@{
-extern const MappingPair gFACCH_TCHFPair;
-extern const MappingPair gSACCH_FT_T0Pair;
-extern const MappingPair gSACCH_FT_T1Pair;
-extern const MappingPair gSACCH_FT_T2Pair;
-extern const MappingPair gSACCH_FT_T3Pair;
-extern const MappingPair gSACCH_FT_T4Pair;
-extern const MappingPair gSACCH_FT_T5Pair;
-extern const MappingPair gSACCH_FT_T6Pair;
-extern const MappingPair gSACCH_FT_T7Pair;
-//@}
-//@}
-
-
-
-/** A CompleteMapping includes uplink, downlink and the SACCH. */
-class CompleteMapping {
-
- private:
-
- const MappingPair& mLCH;
- const MappingPair& mSACCH;
-
- public:
-
- CompleteMapping(const MappingPair& wLCH, const MappingPair& wSACCH)
- :mLCH(wLCH), mSACCH(wSACCH)
- {}
-
- const MappingPair& LCH() const { return mLCH; }
- const MappingPair& SACCH() const { return mSACCH; }
-
-};
-
-
-
-/**@name Complete placements for common channel types. */
-//@{
-/**@name SDCCH/4 */
-//@{
-extern const CompleteMapping gSDCCH_4_0;
-extern const CompleteMapping gSDCCH_4_1;
-extern const CompleteMapping gSDCCH_4_2;
-extern const CompleteMapping gSDCCH_4_3;
-//@}
-/**@name SDCCH/8 */
-//@{
-extern const CompleteMapping gSDCCH_8_0;
-extern const CompleteMapping gSDCCH_8_1;
-extern const CompleteMapping gSDCCH_8_2;
-extern const CompleteMapping gSDCCH_8_3;
-extern const CompleteMapping gSDCCH_8_4;
-extern const CompleteMapping gSDCCH_8_5;
-extern const CompleteMapping gSDCCH_8_6;
-extern const CompleteMapping gSDCCH_8_7;
-//@}
-/**@name TCH/F on different slots. */
-//@{
-extern const CompleteMapping gTCHF_T0;
-extern const CompleteMapping gTCHF_T1;
-extern const CompleteMapping gTCHF_T2;
-extern const CompleteMapping gTCHF_T3;
-extern const CompleteMapping gTCHF_T4;
-extern const CompleteMapping gTCHF_T5;
-extern const CompleteMapping gTCHF_T6;
-extern const CompleteMapping gTCHF_T7;
-//@}
-//@}
-
-
-}; // namespace GSM
-
-
-#endif
-
-// vim: ts=4 sw=4
diff --git a/src/lib/decoder/openbtsstuff/Makefile.am b/src/lib/decoder/openbtsstuff/Makefile.am
deleted file mode 100644
index 5a14202..0000000
--- a/src/lib/decoder/openbtsstuff/Makefile.am
+++ /dev/null
@@ -1,49 +0,0 @@
-#
-# Copyright 2001,2002,2004,2005,2006,2007,2008 Free Software Foundation, Inc.
-#
-# This file is part of GNU Radio
-#
-# GNU Radio 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 3, or (at your option)
-# any later version.
-#
-# GNU Radio 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 GNU Radio; see the file COPYING. If not, write to
-# the Free Software Foundation, Inc., 51 Franklin Street,
-# Boston, MA 02110-1301, USA.
-#
-
-include $(top_srcdir)/Makefile.common
-
-AM_CPPFLAGS = $(STD_DEFINES_AND_INCLUDES)
-
-noinst_LTLIBRARIES = libopenbtsdecoder.la
-
-libopenbtsdecoder_la_SOURCES = \
-BitVector.cpp \
-GSM610Tables.cpp \
-GSMCommon.cpp \
-GSML1FEC.cpp \
-GSMTDMA.cpp \
-Threads.cpp \
-Timeval.cpp
-
-
-noinst_HEADERS = \
-Assert.h \
-BitVector.h \
-GSM610Tables.h \
-GSMCommon.h \
-GSML1FEC.h \
-GSMTDMA.h \
-RxBurst.h \
-Threads.h \
-Timeval.h \
-Vector.h \
-VocoderFrame.h
diff --git a/src/lib/decoder/openbtsstuff/RxBurst.h b/src/lib/decoder/openbtsstuff/RxBurst.h
deleted file mode 100644
index 4348fb8..0000000
--- a/src/lib/decoder/openbtsstuff/RxBurst.h
+++ /dev/null
@@ -1,69 +0,0 @@
-#ifndef _RXBURST_H
-#define _RXBURST_H
-
-#include "GSMCommon.h"
-#include "BitVector.h"
-
-namespace GSM {
-
-/**@name Positions of stealing bits within a normal burst, GSM 05.03 3.1.4. */
-//@{
-static const unsigned gHlIndex = 60; ///< index of first stealing bit, GSM 05.03 3.1.4
-static const unsigned gHuIndex = 87; ///< index of second stealing bit, GSM 05.03 3.1.4
-//@}
-
-static const unsigned gSlotLen = 148; ///< number of symbols per slot, not counting guard periods
-
-
-/**
- Class to represent one timeslot of channel bits with soft encoding.
-*/
-class RxBurst : public SoftVector {
-
- private:
-
- Time mTime; ///< timeslot and frame on which this was received
-// float mTimingError; ///< Timing error in symbol steps, <0 means early.
-// float mRSSI; ///< RSSI estimate associated with the slot, dB wrt full scale.
-
- public:
-
- /** Wrap an RxBurst around an existing float array. */
- RxBurst(float* wData, const Time &wTime)
- :SoftVector(wData,gSlotLen),mTime(wTime)
-// mTimingError(wTimingError),mRSSI(wRSSI)
- { }
-
-
- Time time() const { return mTime; }
-
- void time(const Time& wTime) { mTime = wTime; }
-
-// float RSSI() const { return mRSSI; }
-
-// float timingError() const { return mTimingError; }
-
- /** Return a SoftVector alias to the first data field. */
- const SoftVector data1() const { return segment(3, 57); }
-
- /** Return a SoftVector alias to the second data field. */
- const SoftVector data2() const { return segment(88, 57); }
-
- /** Return upper stealing bit. */
- bool Hu() const { return bit(gHuIndex); }
-
- /** Return lower stealing bit. */
- bool Hl() const { return bit(gHlIndex); }
-
-// friend std::ostream& operator<<(std::ostream& os, const RxBurst& ts);
-};
-
-// std::ostream& operator<<(std::ostream& os, const RxBurst& ts){
-// os << "time=" << ts.time();
-// os << " data=(" << (const SoftVector&)ts << ")" ;
-// return os;
-// }
-
-
-}
-#endif
diff --git a/src/lib/decoder/openbtsstuff/Threads.cpp b/src/lib/decoder/openbtsstuff/Threads.cpp
deleted file mode 100644
index b97f3fe..0000000
--- a/src/lib/decoder/openbtsstuff/Threads.cpp
+++ /dev/null
@@ -1,106 +0,0 @@
-/*
-* Copyright 2008 Free Software Foundation, Inc.
-*
-* This software is distributed under the terms of the GNU Public License.
-* See the COPYING file in the main directory for details.
-
- 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 3 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, see <http://www.gnu.org/licenses/>.
-
-*/
-
-
-
-
-#include "Threads.h"
-#include "Timeval.h"
-
-
-using namespace std;
-
-
-
-
-Mutex gStreamLock; ///< Global lock to control access to cout and cerr.
-
-void lockCout()
-{
- gStreamLock.lock();
- Timeval entryTime;
- cout << entryTime << " " << pthread_self() << ": ";
-}
-
-
-void unlockCout()
-{
- cout << dec << endl << flush;
- gStreamLock.unlock();
-}
-
-
-void lockCerr()
-{
- gStreamLock.lock();
- Timeval entryTime;
- cerr << entryTime << " " << pthread_self() << ": ";
-}
-
-void unlockCerr()
-{
- cerr << dec << endl << flush;
- gStreamLock.unlock();
-}
-
-
-
-
-
-
-
-Mutex::Mutex()
-{
- assert(!pthread_mutexattr_init(&mAttribs));
- assert(!pthread_mutexattr_settype(&mAttribs,PTHREAD_MUTEX_RECURSIVE));
- assert(!pthread_mutex_init(&mMutex,&mAttribs));
-}
-
-
-Mutex::~Mutex()
-{
- pthread_mutex_destroy(&mMutex);
- assert(!pthread_mutexattr_destroy(&mAttribs));
-}
-
-
-
-
-/** Block for the signal up to the cancellation timeout. */
-void Signal::wait(Mutex& wMutex, unsigned timeout) const
-{
- struct timespec waitTime = Timeval(timeout).timespec();
- // FIXME -- With -O3 optimzation in OS X this doesn't block. See bug #320.
- pthread_cond_timedwait(&mSignal,&wMutex.mMutex,&waitTime);
-}
-
-
-void Thread::start(void *(*task)(void*), void *arg)
-{
- assert(mThread==((pthread_t)0));
- assert(!pthread_attr_init(&mAttrib));
- assert(!pthread_attr_setstacksize(&mAttrib, mStackSize));
- assert(!pthread_create(&mThread, &mAttrib, task, arg));
-}
-
-
-
-// vim: ts=4 sw=4
diff --git a/src/lib/decoder/openbtsstuff/Threads.h b/src/lib/decoder/openbtsstuff/Threads.h
deleted file mode 100644
index 14cff04..0000000
--- a/src/lib/decoder/openbtsstuff/Threads.h
+++ /dev/null
@@ -1,150 +0,0 @@
-/*
-* Copyright 2008 Free Software Foundation, Inc.
-*
-* This software is distributed under the terms of the GNU Public License.
-* See the COPYING file in the main directory for details.
-
- 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 3 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, see <http://www.gnu.org/licenses/>.
-
-*/
-
-
-#ifndef THREADS_H
-#define THREADS_H
-
-
-#include <pthread.h>
-#include <iostream>
-#include "Assert.h"
-
-class Mutex;
-
-
-/**@name Multithreaded access for standard streams. */
-//@{
-
-/**@name Functions for gStreamLock. */
-//@{
-extern Mutex gStreamLock; ///< global lock for cout and cerr
-void lockCerr(); ///< call prior to writing cerr
-void unlockCerr(); ///< call after writing cerr
-void lockCout(); ///< call prior to writing cout
-void unlockCout(); ///< call after writing cout
-//@}
-
-/**@name Macros for standard messages. */
-//@{
-#define COUT(text) { lockCout(); std::cout << text; unlockCout(); }
-#define CERR(text) { lockCerr(); std::cerr << __FILE__ << ":" << __LINE__ << ": " << text; unlockCerr(); }
-#ifdef NDEBUG
-#define DCOUT(text) {}
-#define OBJDCOUT(text) {}
-#else
-#define DCOUT(text) { COUT(__FILE__ << ":" << __LINE__ << " " << text); }
-#define OBJDCOUT(text) { DCOUT(this << " " << text); }
-#endif
-//@}
-//@}
-
-
-
-/**@defgroup C++ wrappers for pthread mechanisms. */
-//@{
-
-/** A class for recursive mutexes based on pthread_mutex. */
-class Mutex {
-
- private:
-
- pthread_mutex_t mMutex;
- pthread_mutexattr_t mAttribs;
-
- public:
-
- Mutex();
-
- ~Mutex();
-
- void lock() { pthread_mutex_lock(&mMutex); }
-
- void unlock() { pthread_mutex_unlock(&mMutex); }
-
- friend class Signal;
-
-};
-
-
-
-/** A C++ interthread signal based on pthread condition variables. */
-class Signal {
-
- private:
-
- mutable pthread_cond_t mSignal;
-
- public:
-
- Signal() { assert(!pthread_cond_init(&mSignal,NULL)); }
-
- ~Signal() { pthread_cond_destroy(&mSignal); }
-
- /** Block for the signal up to the cancellation timeout. */
- void wait(Mutex& wMutex, unsigned timeout=1000000000) const;
-
- void signal() { pthread_cond_signal(&mSignal); }
-
- void broadcast() { pthread_cond_broadcast(&mSignal); }
-
-};
-
-
-
-#define START_THREAD(thread,function,argument) \
- thread.start((void *(*)(void*))function, (void*)argument);
-
-/** A C++ wrapper for pthread threads. */
-class Thread {
-
- private:
-
- pthread_t mThread;
- pthread_attr_t mAttrib;
- const static size_t mStackSize=4*65536;
-
-
- public:
-
- /** Create a thread in a non-running state. */
- Thread():mThread((pthread_t)0) { }
-
- /**
- Destroy the Thread.
- It should be stopped and joined.
- */
- ~Thread() { assert(!pthread_attr_destroy(&mAttrib)); }
-
-
- /** Start the thread on a task. */
- void start(void *(*task)(void*), void *arg);
-
- /** Join a thread that will stop on its own. */
- void join() { assert(!pthread_join(mThread,NULL)); }
-
-};
-
-
-
-
-#endif
-// vim: ts=4 sw=4
diff --git a/src/lib/decoder/openbtsstuff/Timeval.cpp b/src/lib/decoder/openbtsstuff/Timeval.cpp
deleted file mode 100644
index e7590cb..0000000
--- a/src/lib/decoder/openbtsstuff/Timeval.cpp
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
-* Copyright 2008 Free Software Foundation, Inc.
-*
-* This software is distributed under the terms of the GNU Public License.
-* See the COPYING file in the main directory for details.
-
- 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 3 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, see <http://www.gnu.org/licenses/>.
-
-*/
-
-
-
-#include "Timeval.h"
-
-using namespace std;
-
-void Timeval::future(unsigned offset)
-{
- now();
- unsigned sec = offset/1000;
- unsigned msec = offset%1000;
- mTimeval.tv_usec += msec*1000;
- mTimeval.tv_sec += sec;
- if (mTimeval.tv_usec>1000000) {
- mTimeval.tv_usec -= 1000000;
- mTimeval.tv_sec += 1;
- }
-}
-
-
-struct timespec Timeval::timespec() const
-{
- struct timespec retVal;
- retVal.tv_sec = mTimeval.tv_sec;
- retVal.tv_nsec = 1000 * (long)mTimeval.tv_usec;
- return retVal;
-}
-
-
-bool Timeval::passed() const
-{
- Timeval nowTime;
- if (nowTime.mTimeval.tv_sec < mTimeval.tv_sec) return false;
- if (nowTime.mTimeval.tv_sec > mTimeval.tv_sec) return true;
- if (nowTime.mTimeval.tv_usec > mTimeval.tv_usec) return true;
- return false;
-}
-
-double Timeval::seconds() const
-{
- return ((double)mTimeval.tv_sec) + 1e-6*((double)mTimeval.tv_usec);
-}
-
-
-
-long Timeval::delta(const Timeval& other) const
-{
- long deltaS = other.sec() - sec();
- long deltaUs = other.usec() - usec();
- return 1000*deltaS + deltaUs/1000;
-}
-
-
-
-
-ostream& operator<<(ostream& os, const Timeval& tv)
-{
- os.setf( ios::fixed, ios::floatfield );
- os << tv.seconds();
- return os;
-}
-
-
-ostream& operator<<(ostream& os, const struct timespec& ts)
-{
- os << ts.tv_sec << "," << ts.tv_nsec;
- return os;
-}
-
-
-
-// vim: ts=4 sw=4
diff --git a/src/lib/decoder/openbtsstuff/Timeval.h b/src/lib/decoder/openbtsstuff/Timeval.h
deleted file mode 100644
index 44618bc..0000000
--- a/src/lib/decoder/openbtsstuff/Timeval.h
+++ /dev/null
@@ -1,96 +0,0 @@
-/*
-* Copyright 2008 Free Software Foundation, Inc.
-*
-* This software is distributed under the terms of the GNU Public License.
-* See the COPYING file in the main directory for details.
-
- 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 3 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, see <http://www.gnu.org/licenses/>.
-
-*/
-
-
-#ifndef TIMEVAL_H
-#define TIMEVAL_H
-
-#include "sys/time.h"
-#include <iostream>
-
-
-
-inline void msleep(long v) { usleep((v+500)/1000); }
-
-
-/** A C++ wrapper for struct timeval. */
-class Timeval {
-
- private:
-
- struct timeval mTimeval;
-
- public:
-
- /** Set the value to gettimeofday. */
- void now() { gettimeofday(&mTimeval,NULL); }
-
- /** Set the value to gettimeofday plus an offset. */
- void future(unsigned offset);
-
- //@{
- Timeval(unsigned sec, unsigned usec)
- {
- mTimeval.tv_sec = sec;
- mTimeval.tv_usec = usec;
- }
-
- Timeval(const struct timeval& wTimeval)
- :mTimeval(wTimeval)
- {}
-
- /**
- Create a Timeval offset into the future.
- @param offset milliseconds
- */
- Timeval(unsigned offset=0) { future(offset); }
- //@}
-
- /** Convert to a struct timespec. */
- struct timespec timespec() const;
-
- /** Return total seconds. */
- double seconds() const;
-
- uint32_t sec() const { return mTimeval.tv_sec; }
- uint32_t usec() const { return mTimeval.tv_usec; }
-
- /** Return differnce from other (other-self), in ms. */
- long delta(const Timeval& other) const;
-
- /** Elapsed time in ms. */
- long elapsed() const { return delta(Timeval()); }
-
- /** Remaining time in ms. */
- long remaining() const { return -elapsed(); }
-
- /** Return true if the time has passed, as per gettimeofday. */
- bool passed() const;
-
-};
-
-std::ostream& operator<<(std::ostream& os, const Timeval&);
-
-std::ostream& operator<<(std::ostream& os, const struct timespec&);
-
-
-#endif
-// vim: ts=4 sw=4
diff --git a/src/lib/decoder/openbtsstuff/Vector.h b/src/lib/decoder/openbtsstuff/Vector.h
deleted file mode 100644
index cec278a..0000000
--- a/src/lib/decoder/openbtsstuff/Vector.h
+++ /dev/null
@@ -1,257 +0,0 @@
-/**@file Simplified Vector template with aliases. */
-/*
-* Copyright 2008 Free Software Foundation, Inc.
-*
-* This software is distributed under the terms of the GNU Public License.
-* See the COPYING file in the main directory for details.
-
- 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 3 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, see <http://www.gnu.org/licenses/>.
-
-*/
-
-
-
-
-#ifndef VECTOR_H
-#define VECTOR_H
-
-#include <string.h>
-#include <iostream>
-#include "Assert.h"
-
-
-/**
- A simplified Vector template with aliases.
- Unlike std::vector, this class does not support dynamic resizing.
- Unlike std::vector, this class does support "aliases" and subvectors.
-*/
-template <class T> class Vector {
-
- // TODO -- Replace memcpy calls with for-loops.
-
- public:
-
- /**@name Iterator types. */
- //@{
- typedef T* iterator;
- typedef const T* const_iterator;
- //@}
-
- protected:
-
- T* mData; ///< allocated data block, if any
- T* mStart; ///< start of useful data
- T* mEnd; ///< end of useful data + 1
-
- public:
-
- /** Return the size of the Vector. */
- size_t size() const
- {
- assert(mStart>=mData);
- assert(mEnd>=mStart);
- return mEnd - mStart;
- }
-
- /** Return size in bytes. */
- size_t bytes() const { return size()*sizeof(T); }
-
- /** Change the size of the Vector, discarding content. */
- void resize(size_t newSize)
- {
- if (mData!=NULL) delete[] mData;
- if (newSize==0) mData=NULL;
- else mData = new T[newSize];
- mStart = mData;
- mEnd = mStart + newSize;
- }
-
- /** Release memory and clear pointers. */
- void clear() { resize(0); }
-
-
- /** Copy data from another vector. */
- void clone(const Vector<T>& other)
- {
- resize(other.size());
- memcpy(mData,other.mStart,other.bytes());
- }
-
-
-
-
- //@{
-
- /** Build an empty Vector of a given size. */
- Vector(size_t wSize=0):mData(NULL) { resize(wSize); }
-
- /** Build a Vector by shifting the data block. */
- Vector(Vector<T>& other)
- :mData(other.mData),mStart(other.mStart),mEnd(other.mEnd)
- { other.mData=NULL; }
-
- /** Build a Vector by copying another. */
- Vector(const Vector<T>& other):mData(NULL) { clone(other); }
-
- /** Build a Vector with explicit values. */
- Vector(T* wData, T* wStart, T* wEnd)
- :mData(wData),mStart(wStart),mEnd(wEnd)
- { }
-
- /** Build a vector from an existing block, NOT to be deleted upon destruction. */
- Vector(T* wStart, size_t span)
- :mData(NULL),mStart(wStart),mEnd(wStart+span)
- { }
-
- /** Build a Vector by concatenation. */
- Vector(const Vector<T>& other1, const Vector<T>& other2)
- :mData(NULL)
- {
- resize(other1.size()+other2.size());
- memcpy(mStart, other1.mStart, other1.bytes());
- memcpy(mStart+other1.size(), other2.mStart, other2.bytes());
- }
-
- //@}
-
- /** Destroy a Vector, deleting held memory. */
- ~Vector() { clear(); }
-
-
-
-
- //@{
-
- /** Assign from another Vector, shifting ownership. */
- void operator=(Vector<T>& other)
- {
- clear();
- mData=other.mData;
- mStart=other.mStart;
- mEnd=other.mEnd;
- other.mData=NULL;
- }
-
- /** Assign from another Vector, copying. */
- void operator=(const Vector<T>& other) { clone(other); }
-
- //@}
-
-
- //@{
-
- /** Return an alias to a segment of this Vector. */
- Vector<T> segment(size_t start, size_t span)
- {
- T* wStart = mStart + start;
- T* wEnd = wStart + span;
- assert(wEnd<=mEnd);
- return Vector<T>(NULL,wStart,wEnd);
- }
-
- /** Return an alias to a segment of this Vector. */
- const Vector<T> segment(size_t start, size_t span) const
- {
- T* wStart = mStart + start;
- T* wEnd = wStart + span;
- assert(wEnd<=mEnd);
- return Vector<T>(NULL,wStart,wEnd);
- }
-
- Vector<T> head(size_t span) { return segment(0,span); }
- const Vector<T> head(size_t span) const { return segment(0,span); }
- Vector<T> tail(size_t start) { return segment(start,size()-start); }
- const Vector<T> tail(size_t start) const { return segment(start,size()-start); }
-
- /**
- Copy part of this Vector to a segment of another Vector.
- @param other The other vector.
- @param start The start point in the other vector.
- @param span The number of elements to copy.
- */
- void copyToSegment(Vector<T>& other, size_t start, size_t span) const
- {
- T* base = other.mStart + start;
- assert(base+span<=other.mEnd);
- assert(mStart+span<=mEnd);
- memcpy(base,mStart,span*sizeof(T));
- }
-
- /** Copy all of this Vector to a segment of another Vector. */
- void copyToSegment(Vector<T>& other, size_t start=0) const { copyToSegment(other,start,size()); }
-
- void copyTo(Vector<T>& other) const { copyToSegment(other,0,size()); }
-
- /**
- Copy a segment of this vector into another.
- @param other The other vector (to copt into starting at 0.)
- @param start The start point in this vector.
- @param span The number of elements to copy.
- */
- void segmentCopyTo(Vector<T>& other, size_t start, size_t span)
- {
- T* base = mStart + start;
- assert(base+span<=mEnd);
- assert(other.mStart+span<=other.mEnd);
- memcpy(other.mStart,base,span*sizeof(T));
- }
-
- void fill(const T& val)
- {
- T* dp=mStart;
- while (dp<mEnd) *dp++=val;
- }
-
-
- //@}
-
-
- //@{
-
- T& operator[](size_t index)
- {
- assert(mStart+index<mEnd);
- return mStart[index];
- }
-
- const T& operator[](size_t index) const
- {
- assert(mStart+index<mEnd);
- return mStart[index];
- }
-
- const T* begin() const { return mStart; }
- T* begin() { return mStart; }
- const T* end() const { return mEnd; }
- T* end() { return mEnd; }
- //@}
-
-
-};
-
-
-
-
-/** Basic print operator for Vector objects. */
-template <class T>
-std::ostream& operator<<(std::ostream& os, const Vector<T>& v)
-{
- for (unsigned i=0; i<v.size(); i++) os << v[i] << " ";
- return os;
-}
-
-
-
-#endif
-// vim: ts=4 sw=4
diff --git a/src/lib/decoder/openbtsstuff/VocoderFrame.h b/src/lib/decoder/openbtsstuff/VocoderFrame.h
deleted file mode 100644
index c0e51c0..0000000
--- a/src/lib/decoder/openbtsstuff/VocoderFrame.h
+++ /dev/null
@@ -1,25 +0,0 @@
-#ifndef _VOCODERFRAME_H
-#define _VOCODERFRAME_H
-
-#include "BitVector.h"
-//#include "GSMCommon.h"
-
-class VocoderFrame : public BitVector {
-
- public:
-
- VocoderFrame()
- :BitVector(264)
- { fillField(0,0x0d,4); }
-
- /** Construct by unpacking a char[33]. */
- VocoderFrame(const unsigned char *src)
- :BitVector(264)
- { unpack(src); }
-
- BitVector payload() { return tail(4); }
- const BitVector payload() const { return tail(4); }
-
-};
-
-#endif
diff --git a/src/lib/decoder/out_pcap.c b/src/lib/decoder/out_pcap.c
deleted file mode 100644
index 4da5fd6..0000000
--- a/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;
-}
diff --git a/src/lib/decoder/out_pcap.h b/src/lib/decoder/out_pcap.h
deleted file mode 100644
index 5ae5e3c..0000000
--- a/src/lib/decoder/out_pcap.h
+++ /dev/null
@@ -1,9 +0,0 @@
-#ifndef _PCAP_IF_H
-#define _PCAP_IF_H
-
-extern int open_pcap_file(char *fname);
-
-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
diff --git a/src/lib/decoder/sch.c b/src/lib/decoder/sch.c
deleted file mode 100644
index 6f141dd..0000000
--- a/src/lib/decoder/sch.c
+++ /dev/null
@@ -1,333 +0,0 @@
-#include "system.h"
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <string.h>
-#include "gsm_constants.h"
-
-/*
- * Synchronization channel.
- *
- * Timeslot Repeat length Frame Number (mod repeat length)
- * 0 51 1, 11, 21, 31, 41
- */
-
-/*
- * Parity (FIRE) for the GSM SCH.
- *
- * g(x) = x^10 + x^8 + x^6 + x^5 + x^4 + x^2 + 1
- */
-#define DATA_BLOCK_SIZE 25
-#define PARITY_SIZE 10
-#define TAIL_BITS_SIZE 4
-#define PARITY_OUTPUT_SIZE (DATA_BLOCK_SIZE + PARITY_SIZE + TAIL_BITS_SIZE)
-
-static const unsigned char parity_polynomial[PARITY_SIZE + 1] = {
- 1, 0, 1, 0, 1, 1, 1, 0, 1, 0, 1
-};
-
-static const unsigned char parity_remainder[PARITY_SIZE] = {
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1
-};
-
-
-static void parity_encode(unsigned char *d, unsigned char *p)
-{
-
- unsigned int i;
- unsigned char buf[DATA_BLOCK_SIZE + PARITY_SIZE], *q;
-
- memcpy(buf, d, DATA_BLOCK_SIZE);
- memset(buf + DATA_BLOCK_SIZE, 0, PARITY_SIZE);
-
- for (q = buf; q < buf + DATA_BLOCK_SIZE; q++)
- if (*q)
- for (i = 0; i < PARITY_SIZE + 1; i++)
- q[i] ^= parity_polynomial[i];
- for (i = 0; i < PARITY_SIZE; i++)
- p[i] = !buf[DATA_BLOCK_SIZE + i];
-}
-
-
-static int parity_check(unsigned char *d)
-{
-
- unsigned int i;
- unsigned char buf[DATA_BLOCK_SIZE + PARITY_SIZE], *q;
-
- memcpy(buf, d, DATA_BLOCK_SIZE + PARITY_SIZE);
-
- for (q = buf; q < buf + DATA_BLOCK_SIZE; q++)
- if (*q)
- for (i = 0; i < PARITY_SIZE + 1; i++)
- q[i] ^= parity_polynomial[i];
- return memcmp(buf + DATA_BLOCK_SIZE, parity_remainder, PARITY_SIZE);
-}
-
-
-/*
- * Convolutional encoding and Viterbi decoding for the GSM SCH.
- * (Equivalent to the GSM SACCH.)
- *
- * G_0 = 1 + x^3 + x^4
- * G_1 = 1 + x + x^3 + x^4
- *
- * i.e.,
- *
- * c_{2k} = u_k + u_{k - 3} + u_{k - 4}
- * c_{2k + 1} = u_k + u_{k - 1} + u_{k - 3} + u_{k - 4}
- */
-#define CONV_INPUT_SIZE PARITY_OUTPUT_SIZE
-#define CONV_SIZE (2 * CONV_INPUT_SIZE)
-#define K 5
-#define MAX_ERROR (2 * CONV_INPUT_SIZE + 1)
-
-
-/*
- * Given the current state and input bit, what are the output bits?
- *
- * encode[current_state][input_bit]
- */
-static const unsigned int encode[1 << (K - 1)][2] = {
- {0, 3}, {3, 0}, {3, 0}, {0, 3},
- {0, 3}, {3, 0}, {3, 0}, {0, 3},
- {1, 2}, {2, 1}, {2, 1}, {1, 2},
- {1, 2}, {2, 1}, {2, 1}, {1, 2}
-};
-
-
-/*
- * Given the current state and input bit, what is the next state?
- *
- * next_state[current_state][input_bit]
- */
-static const unsigned int next_state[1 << (K - 1)][2] = {
- {0, 8}, {0, 8}, {1, 9}, {1, 9},
- {2, 10}, {2, 10}, {3, 11}, {3, 11},
- {4, 12}, {4, 12}, {5, 13}, {5, 13},
- {6, 14}, {6, 14}, {7, 15}, {7, 15}
-};
-
-
-/*
- * Given the previous state and the current state, what input bit caused
- * the transition? If it is impossible to transition between the two
- * states, the value is 2.
- *
- * prev_next_state[previous_state][current_state]
- */
-static const unsigned int prev_next_state[1 << (K - 1)][1 << (K - 1)] = {
- { 0, 2, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 2},
- { 0, 2, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 2},
- { 2, 0, 2, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2},
- { 2, 0, 2, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2},
- { 2, 2, 0, 2, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2},
- { 2, 2, 0, 2, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2},
- { 2, 2, 2, 0, 2, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2},
- { 2, 2, 2, 0, 2, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2},
- { 2, 2, 2, 2, 0, 2, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2},
- { 2, 2, 2, 2, 0, 2, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2},
- { 2, 2, 2, 2, 2, 0, 2, 2, 2, 2, 2, 2, 2, 1, 2, 2},
- { 2, 2, 2, 2, 2, 0, 2, 2, 2, 2, 2, 2, 2, 1, 2, 2},
- { 2, 2, 2, 2, 2, 2, 0, 2, 2, 2, 2, 2, 2, 2, 1, 2},
- { 2, 2, 2, 2, 2, 2, 0, 2, 2, 2, 2, 2, 2, 2, 1, 2},
- { 2, 2, 2, 2, 2, 2, 2, 0, 2, 2, 2, 2, 2, 2, 2, 1},
- { 2, 2, 2, 2, 2, 2, 2, 0, 2, 2, 2, 2, 2, 2, 2, 1}
-};
-
-
-static inline unsigned int hamming_distance2(unsigned int w)
-{
-
- return (w & 1) + !!(w & 2);
-}
-
-
-static void conv_encode(unsigned char *data, unsigned char *output)
-{
-
- unsigned int i, state = 0, o;
-
- // encode data
- for (i = 0; i < CONV_INPUT_SIZE; i++) {
- o = encode[state][data[i]];
- state = next_state[state][data[i]];
- *output++ = !!(o & 2);
- *output++ = o & 1;
- }
-}
-
-
-static int conv_decode(unsigned char *data, unsigned char *output)
-{
-
- int i, t;
- unsigned int rdata, state, nstate, b, o, distance, accumulated_error,
- min_state, min_error, cur_state;
-
- unsigned int ae[1 << (K - 1)];
- unsigned int nae[1 << (K - 1)]; // next accumulated error
- unsigned int state_history[1 << (K - 1)][CONV_INPUT_SIZE + 1];
-
- // initialize accumulated error, assume starting state is 0
- for (i = 0; i < (1 << (K - 1)); i++)
- ae[i] = nae[i] = MAX_ERROR;
- ae[0] = 0;
-
- // build trellis
- for (t = 0; t < CONV_INPUT_SIZE; t++) {
-
- // get received data symbol
- rdata = (data[2 * t] << 1) | data[2 * t + 1];
-
- // for each state
- for (state = 0; state < (1 << (K - 1)); state++) {
-
- // make sure this state is possible
- if (ae[state] >= MAX_ERROR)
- continue;
-
- // find all states we lead to
- for (b = 0; b < 2; b++) {
-
- // get next state given input bit b
- nstate = next_state[state][b];
-
- // find output for this transition
- o = encode[state][b];
-
- // calculate distance from received data
- distance = hamming_distance2(rdata ^ o);
-
- // choose surviving path
- accumulated_error = ae[state] + distance;
- if (accumulated_error < nae[nstate]) {
-
- // save error for surviving state
- nae[nstate] = accumulated_error;
-
- // update state history
- state_history[nstate][t + 1] = state;
- }
- }
- }
-
- // get accumulated error ready for next time slice
- for (i = 0; i < (1 << (K - 1)); i++) {
- ae[i] = nae[i];
- nae[i] = MAX_ERROR;
- }
- }
-
- // the final state is the state with the fewest errors
- min_state = (unsigned int) - 1;
- min_error = MAX_ERROR;
- for (i = 0; i < (1 << (K - 1)); i++) {
- if (ae[i] < min_error) {
- min_state = i;
- min_error = ae[i];
- }
- }
-
- // trace the path
- cur_state = min_state;
- for (t = CONV_INPUT_SIZE; t >= 1; t--) {
- min_state = cur_state;
- cur_state = state_history[cur_state][t]; // get previous
- output[t - 1] = prev_next_state[cur_state][min_state];
- }
-
- // return the number of errors detected (hard-decision)
- return min_error;
-}
-
-
-int decode_sch(const unsigned char *buf, int * t1_o, int * t2_o, int * t3_o, int * ncc_o, int * bcc_o)
-{
-
- int errors, t1, t2, t3p, t3, ncc, bcc;
- unsigned char data[CONV_SIZE], decoded_data[PARITY_OUTPUT_SIZE];
-
- // extract encoded data from synchronization burst
- /* buf, 39 bit */
- /* buf + 39 + 64 = 103, 39 */
- memcpy(data, buf, SCH_DATA_LEN);
- memcpy(data + SCH_DATA_LEN, buf + SCH_DATA_LEN + N_SYNC_BITS, SCH_DATA_LEN);
-
- // Viterbi decode
- if (errors = conv_decode(data, decoded_data)) {
- // fprintf(stderr, "error: sch: conv_decode (%d)\n", errors);
- DEBUGF("ERR: conv_decode %d\n", errors);
- return errors;
- }
-
- // check parity
- if (parity_check(decoded_data)) {
- // fprintf(stderr, "error: sch: parity failed\n");
- DEBUGF("ERR: parity_check failed\n");
- return 1;
- }
-
- // Synchronization channel information, 44.018 page 171. (V7.2.0)
- ncc =
- (decoded_data[ 7] << 2) |
- (decoded_data[ 6] << 1) |
- (decoded_data[ 5] << 0);
- bcc =
- (decoded_data[ 4] << 2) |
- (decoded_data[ 3] << 1) |
- (decoded_data[ 2] << 0);
- t1 =
- (decoded_data[ 1] << 10) |
- (decoded_data[ 0] << 9) |
- (decoded_data[15] << 8) |
- (decoded_data[14] << 7) |
- (decoded_data[13] << 6) |
- (decoded_data[12] << 5) |
- (decoded_data[11] << 4) |
- (decoded_data[10] << 3) |
- (decoded_data[ 9] << 2) |
- (decoded_data[ 8] << 1) |
- (decoded_data[23] << 0);
- t2 =
- (decoded_data[22] << 4) |
- (decoded_data[21] << 3) |
- (decoded_data[20] << 2) |
- (decoded_data[19] << 1) |
- (decoded_data[18] << 0);
- t3p =
- (decoded_data[17] << 2) |
- (decoded_data[16] << 1) |
- (decoded_data[24] << 0);
-
- t3 = 10 * t3p + 1;
-
- // modulo arithmetic t3 - t2 mod 26
-// tt = ((t3 + 26) - t2) % 26;
-
-// fn = (51 * 26 * t1) + (51 * tt) + t3;
-
- /*
- * BSIC: Base Station Identification Code
- * BCC: Base station Color Code
- * NCC: Network Color Code
- *
- * FN: Frame Number
- */
-
-// printf("bsic: %x (bcc: %u; ncc: %u)\tFN: %u\n", bsic, bsic & 7,
-// (bsic >> 3) & 7, fn);
-
-// if (fn_o)
-// *fn_o = fn;
-// if (bsic_o)
- if (t1_o && t2_o && t3_o && ncc_o && bcc_o) {
- *t1_o = t1;
- *t2_o = t2;
- *t3_o = t3;
- *bcc_o = bcc;
- *ncc_o = ncc;
- }
-
- return 0;
-}
diff --git a/src/lib/decoder/sch.h b/src/lib/decoder/sch.h
deleted file mode 100644
index 4d47eb5..0000000
--- a/src/lib/decoder/sch.h
+++ /dev/null
@@ -1,17 +0,0 @@
-
-#ifndef __SCH_H__
-#define __SCH_H__ 1
-
-#ifdef __cplusplus
-extern "C"
-{
-#endif
-
- int decode_sch(const unsigned char *buf, int * t1_o, int * t2_o, int * t3_o, int * ncc, int * bcc);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
-
diff --git a/src/lib/decoder/system.h b/src/lib/decoder/system.h
deleted file mode 100644
index 414730a..0000000
--- a/src/lib/decoder/system.h
+++ /dev/null
@@ -1,11 +0,0 @@
-
-#ifndef __GSMTVOID_SYSTEM_H__
-#define __GSMTVOID_SYSTEM_H__ 1
-
-#define DEBUGF(a...) { \
- fprintf(stderr, "%s:%d ", __FILE__, __LINE__); \
- fprintf(stderr, a); \
-} while (0)
-
-#endif
-
diff --git a/src/lib/decoder/tun.c b/src/lib/decoder/tun.c
deleted file mode 100644
index 2abda90..0000000
--- a/src/lib/decoder/tun.c
+++ /dev/null
@@ -1,125 +0,0 @@
-// $Id: tun.cc,v 1.2 2007-07-07 16:31:42 jl Exp $
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <string.h>
-#include <libgen.h>
-#include <fcntl.h>
-#include <sys/ioctl.h>
-#include <sys/socket.h>
-#include <linux/if_tun.h>
-#include <linux/if.h>
-#include <linux/if_ether.h>
-#include <arpa/inet.h>
-
-int mktun(const char *chan_name, unsigned char *ether_addr) {
-
- struct ifreq ifr;
- // struct ifreq ifw;
- char if_name[IFNAMSIZ];
- int fd, one = 1;
- // int sd;
-
- // construct TUN interface
- if((fd = open("/dev/net/tun", O_RDWR)) == -1) {
- perror("open");
- return -1;
- }
- memset(&ifr, 0, sizeof(ifr));
- ifr.ifr_flags = IFF_TAP | IFF_NO_PI;
- snprintf(ifr.ifr_name, IFNAMSIZ, "%s", chan_name);
- if(ioctl(fd, TUNSETIFF, (void *)&ifr) == -1) {
- perror("TUNSETIFF");
- close(fd);
- return -1;
- }
-
- // save actual name
- memcpy(if_name, ifr.ifr_name, IFNAMSIZ);
-
- // get ether addr
- memset(&ifr, 0, sizeof(ifr));
- memcpy(ifr.ifr_name, if_name, IFNAMSIZ);
- if(ioctl(fd, SIOCGIFHWADDR, (void *)&ifr) == -1) {
- perror("SIOCGIFHWADDR");
- close(fd);
- return -1;
- }
- memcpy(ether_addr, ifr.ifr_hwaddr.sa_data, ETH_ALEN);
-
- // set persistent
- if(ioctl(fd, TUNSETPERSIST, (void *)&one) == -1) {
- perror("TUNSETPERSIST");
- close(fd);
- return -1;
- }
-
- // set interface up
- /* XXX must be root
- if((sd = socket(AF_INET, SOCK_DGRAM, 0)) == -1) {
- perror("socket");
- close(fd);
- return -1;
- }
-
- // get current flags
- memset(&ifr, 0, sizeof(ifr));
- strncpy(ifr.ifr_name, if_name, IFNAMSIZ - 1);
- if(ioctl(sd, SIOCGIFFLAGS, &ifr) == -1) {
- perror("SIOCGIFFLAGS");
- close(sd);
- close(fd);
- return -1;
- }
-
- // set up
- memset(&ifw, 0, sizeof(ifw));
- strncpy(ifw.ifr_name, if_name, IFNAMSIZ - 1);
- ifw.ifr_flags = ifr.ifr_flags | IFF_UP | IFF_RUNNING;
- if(ioctl(sd, SIOCSIFFLAGS, &ifw) == -1) {
- perror("SIOCSIFFLAGS");
- close(sd);
- close(fd);
- return -1;
- }
- close(sd);
- */
-
- return fd;
-}
-
-
-static inline int min(int a, int b) {
-
- return (a < b)? a : b;
-}
-
-
-static const unsigned int DEFAULT_MTU = 1500;
-static const unsigned short ether_type = 0xfed5; // current dtap ethertype
-
-int write_interface(int fd, unsigned char *data, unsigned int data_len,
- unsigned char *ether_addr) {
-
- unsigned char frame[DEFAULT_MTU]; // XXX buffer overflow?
- struct ethhdr eh;
-
- if(fd < 0)
- return data_len;
-
- memcpy(eh.h_dest, ether_addr, ETH_ALEN);
- memcpy(eh.h_source, ether_addr, ETH_ALEN);
- eh.h_proto = htons(ether_type);
-
- memcpy(frame, &eh, sizeof(eh));
- memcpy(frame + sizeof(eh), data,
- min(data_len, sizeof(frame) - sizeof(eh)));
-
- if(write(fd, frame, sizeof(eh) + data_len) == -1) {
- perror("write");
- return -1;
- }
-
- return data_len;
-}
diff --git a/src/lib/decoder/tun.h b/src/lib/decoder/tun.h
deleted file mode 100644
index a7868c4..0000000
--- a/src/lib/decoder/tun.h
+++ /dev/null
@@ -1,4 +0,0 @@
-// $Id: tun.h,v 1.1.1.1 2007-06-01 04:26:57 jl Exp $
-
-int mktun(const char *, unsigned char *);
-int write_interface(int, unsigned char *, unsigned int, unsigned char *);
diff --git a/src/lib/gsm.i b/src/lib/gsm.i
deleted file mode 100644
index 3a5c561..0000000
--- a/src/lib/gsm.i
+++ /dev/null
@@ -1,49 +0,0 @@
-/* -*- c++ -*- */
-/*
- * @file
- * @author Piotr Krysik <pkrysik@stud.elka.pw.edu.pl>
- * @section LICENSE
- *
- * 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 3, 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; see the file COPYING. If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street,
- * Boston, MA 02110-1301, USA.
- */
-
-%feature("autodoc", "1"); // generate python docstrings
-
-%include "exception.i"
-%import "gnuradio.i" // the common stuff
-
-/* %include "gsm_constants.h" */
-
-%{
-#include "gnuradio_swig_bug_workaround.h" // mandatory bug fix
-#include "gsm_receiver_cf.h"
-#include <stdexcept>
-/* #include "gsm_constants.h" */
-%}
-
-// ----------------------------------------------------------------
-
-GR_SWIG_BLOCK_MAGIC(gsm,receiver_cf);
-
-gsm_receiver_cf_sptr gsm_make_receiver_cf ( gr_feval_dd *tuner, gr_feval_dd *synchronizer, int osr, std::string key);
-
-class gsm_receiver_cf : public gr_block
-{
-private:
- gsm_receiver_cf ( gr_feval_dd *tuner, gr_feval_dd *synchronizer, int osr);
-};
-
-// ----------------------------------------------------------------
diff --git a/src/lib/gsm_constants.h b/src/lib/gsm_constants.h
deleted file mode 100644
index 939099d..0000000
--- a/src/lib/gsm_constants.h
+++ /dev/null
@@ -1,150 +0,0 @@
-#ifndef INCLUDED_GSM_CONSTANTS_H
-#define INCLUDED_GSM_CONSTANTS_H
-
-#define GSM_SYMBOL_RATE (1625000.0/6.0) //symbols per second
-#define GSM_SYMBOL_PERIOD (1.0/GSM_SYMBOL_RATE) //seconds per symbol
-
-//Burst timing
-#define TAIL_BITS 3
-#define GUARD_BITS 8
-#define GUARD_FRACTIONAL 0.25 //fractional part of guard period
-#define GUARD_PERIOD GUARD_BITS + GUARD_FRACTIONAL
-#define DATA_BITS 57 //size of 1 data block in normal burst
-#define STEALING_BIT 1
-#define N_TRAIN_BITS 26
-#define N_SYNC_BITS 64
-#define USEFUL_BITS 142 //(2*(DATA_BITS+STEALING_BIT) + N_TRAIN_BITS )
-#define FCCH_BITS USEFUL_BITS
-#define BURST_SIZE (USEFUL_BITS+2*TAIL_BITS)
-
-#define SCH_DATA_LEN 39
-#define TS_BITS (TAIL_BITS+USEFUL_BITS+TAIL_BITS+GUARD_BITS) //a full TS (156 bits)
-#define TS_PER_FRAME 8
-#define FRAME_BITS (TS_PER_FRAME * TS_BITS + 2) // 156.25 * 8
-#define FCCH_POS TAIL_BITS
-#define SYNC_POS 39
-#define TRAIN_POS ( TAIL_BITS + (DATA_BITS+STEALING_BIT) + 5) //first 5 bits of a training sequence
- //aren't used for channel impulse response estimation
-#define TRAIN_BEGINNING 5
-#define SAFETY_MARGIN 6 //
-
-#define FCCH_HITS_NEEDED (USEFUL_BITS - 4)
-#define FCCH_MAX_MISSES 1
-#define FCCH_MAX_FREQ_OFFSET 100
-
-#define CHAN_IMP_RESP_LENGTH 5
-
-#define MAX_SCH_ERRORS 5 //maximum number of subsequent sch errors after which gsm receiver goes to find_next_fcch state
-
-typedef enum {empty, fcch_burst, sch_burst, normal_burst, rach_burst, dummy, dummy_or_normal} burst_type;
-typedef enum {unknown, multiframe_26, multiframe_51} multiframe_type;
-
-static const unsigned char SYNC_BITS[] = {
- 1, 0, 1, 1, 1, 0, 0, 1, 0, 1, 1, 0, 0, 0, 1, 0,
- 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1,
- 0, 0, 1, 0, 1, 1, 0, 1, 0, 1, 0, 0, 0, 1, 0, 1,
- 0, 1, 1, 1, 0, 1, 1, 0, 0, 0, 0, 1, 1, 0, 1, 1
-};
-
-const unsigned FCCH_FRAMES[] = {0, 10, 20, 30, 40};
-const unsigned SCH_FRAMES[] = {1, 11, 21, 31, 41};
-
-const unsigned BCCH_FRAMES[] = {2, 3, 4, 5}; //!!the receiver shouldn't care about logical
- //!!channels so this will be removed from this header
-const unsigned TEST_CCH_FRAMES[] = {2, 3, 4, 5, 6, 7, 8, 9, 12, 13, 14, 15, 16, 17, 18, 19, 22, 23, 24, 25, 26, 27, 28, 29, 32, 33, 34, 35, 36, 37, 38, 39, 42, 43, 44, 45, 46, 47, 48, 49};
-const unsigned TRAFFIC_CHANNEL_F[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24};
-const unsigned TEST51[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50};
-
-
-#define TSC0 0
-#define TSC1 1
-#define TSC2 2
-#define TSC3 3
-#define TSC4 4
-#define TSC5 5
-#define TSC6 6
-#define TSC7 7
-#define TS_DUMMY 8
-
-#define TRAIN_SEQ_NUM 9
-
-#define TIMESLOT0 0
-#define TIMESLOT1 1
-#define TIMESLOT2 2
-#define TIMESLOT3 3
-#define TIMESLOT4 4
-#define TIMESLOT5 5
-#define TIMESLOT6 6
-#define TIMESLOT7 7
-
-
-static const unsigned char train_seq[TRAIN_SEQ_NUM][N_TRAIN_BITS] = {
- {0, 0, 1, 0, 0, 1, 0, 1, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 1, 1, 1},
- {0, 0, 1, 0, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 1, 0, 1, 1, 1},
- {0, 1, 0, 0, 0, 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 1, 1, 0},
- {0, 1, 0, 0, 0, 1, 1, 1, 1, 0, 1, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 1, 1, 0},
- {0, 0, 0, 1, 1, 0, 1, 0, 1, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 0, 1, 0, 1, 1},
- {0, 1, 0, 0, 1, 1, 1, 0, 1, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 1, 1, 1, 0, 1, 0},
- {1, 0, 1, 0, 0, 1, 1, 1, 1, 1, 0, 1, 1, 0, 0, 0, 1, 0, 1, 0, 0, 1, 1, 1, 1, 1},
- {1, 1, 1, 0, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 0, 0},
- {0, 1, 1, 1, 0, 0, 0, 1, 0, 1, 1, 1, 0, 0, 0, 1, 0, 1, 1, 1, 0, 0, 0, 1, 0, 1} // DUMMY
-};
-
-
-//Dummy burst 0xFB 76 0A 4E 09 10 1F 1C 5C 5C 57 4A 33 39 E9 F1 2F A8
-static const unsigned char dummy_burst[] = {
- 1, 1, 1, 1, 1, 0, 1, 1, 0, 1,
- 1, 1, 0, 1, 1, 0, 0, 0, 0, 0,
- 1, 0, 1, 0, 0, 1, 0, 0, 1, 1,
- 1, 0, 0, 0, 0, 0, 1, 0, 0, 1,
- 0, 0, 0, 1, 0, 0, 0, 0, 0, 0,
- 0, 1, 1, 1, 1, 1, 0, 0,
-
- 0, 1, 1, 1, 0, 0, 0, 1, 0, 1,
- 1, 1, 0, 0, 0, 1, 0, 1, 1, 1,
- 0, 0, 0, 1, 0, 1,
-
- 0, 1, 1, 1, 0, 1, 0, 0, 1, 0,
- 1, 0, 0, 0, 1, 1, 0, 0, 1, 1,
- 0, 0, 1, 1, 1, 0, 0, 1, 1, 1,
- 1, 0, 1, 0, 0, 1, 1, 1, 1, 1,
- 0, 0, 0, 1, 0, 0, 1, 0, 1, 1,
- 1, 1, 1, 0, 1, 0, 1, 0
-};
-
-
-/*
- * The frequency correction burst is used for frequency synchronization
- * of the mobile. This is broadcast in TS0 together with the SCH and
- * BCCH.
- *
- * Modulating the bits below causes a spike at 62.5kHz above (below for
- * COMPACT) the center frequency. One can use this spike with a narrow
- * band filter to accurately determine the center of the channel.
- */
-static const unsigned char fc_fb[] = { //I don't use this tables,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //I copied this here from burst_types.h because
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //the description is very informative - p.krysik
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-};
-
-static const unsigned char fc_compact_fb[] = {
- 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0,
- 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0,
- 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0,
- 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0,
- 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0,
- 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0,
- 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0,
- 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0,
- 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0
-};
-
-
-#endif /* INCLUDED_GSM_CONSTANTS_H */
diff --git a/src/lib/gsm_receiver_cf.cc b/src/lib/gsm_receiver_cf.cc
deleted file mode 100644
index 4742b33..0000000
--- a/src/lib/gsm_receiver_cf.cc
+++ /dev/null
@@ -1,853 +0,0 @@
-/* -*- c++ -*- */
-/*
- * @file
- * @author Piotr Krysik <pkrysik@stud.elka.pw.edu.pl>
- * @section LICENSE
- *
- * 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 3, 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; see the file COPYING. If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street,
- * Boston, MA 02110-1301, USA.
- */
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include <gr_io_signature.h>
-#include <gr_math.h>
-#include <math.h>
-#include <Assert.h>
-#include <boost/circular_buffer.hpp>
-#include <algorithm>
-#include <numeric>
-#include <gsm_receiver_cf.h>
-#include <viterbi_detector.h>
-#include <string.h>
-#include <sch.h>
-
-
-#include "RxBurst.h"
-#include "GSMCommon.h"
-
-#define SYNC_SEARCH_RANGE 30
-// #define TRAIN_SEARCH_RANGE 40
-//FIXME: decide to use this define or not
-
-//TODO: this shouldn't be here - remove it when gsm receiver's interface will be ready
-void decrypt(const unsigned char * burst_binary, byte * KC, float * decrypted_data, unsigned FN)
-{
- byte AtoB[2*DATA_BITS];
-
- keysetup(KC, FN);
- runA51(AtoB);
-
- for (int i = 0; i < 148; i++) {
- decrypted_data[i] = burst_binary[i];
- }
-
- for (int i = 0; i < 57; i++) {
- decrypted_data[i+3] = AtoB[i] ^ burst_binary[i+3];
- }
-
- for (int i = 0; i < 57; i++) {
- decrypted_data[i+88] = AtoB[i+57] ^ burst_binary[i+88];
- }
-}
-
-void gsm_receiver_cf::read_key(std::string key)
-{
- int i;
- int b;
- for (i = 0;i < 8;i++) {
- b = d_hex_to_int[(char)key[(i)*2]]*16 + d_hex_to_int[(char)key[i*2+1]];
- d_KC[i] = (byte)b;
- }
-}
-
-void gsm_receiver_cf::process_normal_burst(burst_counter burst_nr, const unsigned char * burst_binary)
-{
-// static byte KC[] = { 0xAD, 0x6A, 0x3E, 0xC2, 0xB4, 0x42, 0xE4, 0x00 };
-// static byte KC[] = { 0x2B, 0x08, 0x74, 0x9F, 0xDD, 0x0D, 0x9C, 0x00 };
-// printf("%x", KC[0]);
- float decrypted_data[148];
- unsigned char * voice_frame;
-
-// if (burst_nr.get_timeslot_nr() == 7) {
- if (burst_nr.get_timeslot_nr() >= 1 && burst_nr.get_timeslot_nr() <= 7) {
- decrypt(burst_binary, d_KC, decrypted_data, burst_nr.get_frame_nr_mod());
-
- GSM::Time time(burst_nr.get_frame_nr(), burst_nr.get_timeslot_nr());
- GSM::RxBurst rxbrst(decrypted_data, time);
- switch (burst_nr.get_timeslot_nr()) {
- case 1:
- if ( d_tch_decoder1.processBurst( rxbrst ) == true) {
- fwrite(d_tch_decoder1.get_voice_frame(), 1 , 33, d_gsm_file);
- }
- break;
- case 2:
- if ( d_tch_decoder2.processBurst( rxbrst ) == true) {
- fwrite(d_tch_decoder2.get_voice_frame(), 1 , 33, d_gsm_file);
- }
- break;
- case 3:
- if ( d_tch_decoder3.processBurst( rxbrst ) == true) {
- fwrite(d_tch_decoder3.get_voice_frame(), 1 , 33, d_gsm_file);
- }
- break;
- case 4:
- if ( d_tch_decoder4.processBurst( rxbrst ) == true) {
- fwrite(d_tch_decoder4.get_voice_frame(), 1 , 33, d_gsm_file);
- }
- break;
- case 5:
- if ( d_tch_decoder5.processBurst( rxbrst ) == true) {
- fwrite(d_tch_decoder5.get_voice_frame(), 1 , 33, d_gsm_file);
- }
- break;
- case 6:
- if ( d_tch_decoder6.processBurst( rxbrst ) == true) {
- fwrite(d_tch_decoder6.get_voice_frame(), 1 , 33, d_gsm_file);
- }
- break;
- case 7:
- if ( d_tch_decoder7.processBurst( rxbrst ) == true) {
- fwrite(d_tch_decoder7.get_voice_frame(), 1 , 33, d_gsm_file);
- }
- break;
- }
- }
-
- if (burst_nr.get_timeslot_nr() == 0) {
- GS_process(&d_gs_ctx, TIMESLOT0, 6, &burst_binary[3], burst_nr.get_frame_nr());
- }
-}
-//TODO: this shouldn't be here also - the same reason
-void gsm_receiver_cf::configure_receiver()
-{
- d_channel_conf.set_multiframe_type(TSC0, multiframe_51);
-
- d_channel_conf.set_burst_types(TSC0, TEST_CCH_FRAMES, sizeof(TEST_CCH_FRAMES) / sizeof(unsigned), normal_burst);
- d_channel_conf.set_burst_types(TSC0, FCCH_FRAMES, sizeof(FCCH_FRAMES) / sizeof(unsigned), fcch_burst);
-
- d_channel_conf.set_multiframe_type(TIMESLOT1, multiframe_26);
- d_channel_conf.set_burst_types(TIMESLOT1, TRAFFIC_CHANNEL_F, sizeof(TRAFFIC_CHANNEL_F) / sizeof(unsigned), dummy_or_normal);
- d_channel_conf.set_multiframe_type(TIMESLOT2, multiframe_26);
- d_channel_conf.set_burst_types(TIMESLOT2, TRAFFIC_CHANNEL_F, sizeof(TRAFFIC_CHANNEL_F) / sizeof(unsigned), dummy_or_normal);
-
- d_channel_conf.set_multiframe_type(TIMESLOT3, multiframe_26);
- d_channel_conf.set_burst_types(TIMESLOT3, TRAFFIC_CHANNEL_F, sizeof(TRAFFIC_CHANNEL_F) / sizeof(unsigned), dummy_or_normal);
- d_channel_conf.set_multiframe_type(TIMESLOT4, multiframe_26);
- d_channel_conf.set_burst_types(TIMESLOT4, TRAFFIC_CHANNEL_F, sizeof(TRAFFIC_CHANNEL_F) / sizeof(unsigned), dummy_or_normal);
-
- d_channel_conf.set_multiframe_type(TIMESLOT5, multiframe_26);
- d_channel_conf.set_burst_types(TIMESLOT5, TRAFFIC_CHANNEL_F, sizeof(TRAFFIC_CHANNEL_F) / sizeof(unsigned), dummy_or_normal);
- d_channel_conf.set_multiframe_type(TIMESLOT6, multiframe_26);
- d_channel_conf.set_burst_types(TIMESLOT6, TRAFFIC_CHANNEL_F, sizeof(TRAFFIC_CHANNEL_F) / sizeof(unsigned), dummy_or_normal);
-
- d_channel_conf.set_multiframe_type(TIMESLOT7, multiframe_26);
- d_channel_conf.set_burst_types(TIMESLOT7, TRAFFIC_CHANNEL_F, sizeof(TRAFFIC_CHANNEL_F) / sizeof(unsigned), dummy_or_normal);
-
-}
-
-
-typedef std::list<float> list_float;
-typedef std::vector<float> vector_float;
-
-typedef boost::circular_buffer<float> circular_buffer_float;
-
-gsm_receiver_cf_sptr
-gsm_make_receiver_cf(gr_feval_dd *tuner, gr_feval_dd *synchronizer, int osr, std::string key)
-{
- return gsm_receiver_cf_sptr(new gsm_receiver_cf(tuner, synchronizer, osr, key));
-}
-
-static const int MIN_IN = 1; // mininum number of input streams
-static const int MAX_IN = 1; // maximum number of input streams
-static const int MIN_OUT = 0; // minimum number of output streams
-static const int MAX_OUT = 1; // maximum number of output streams
-
-/*
- * The private constructor
- */
-gsm_receiver_cf::gsm_receiver_cf(gr_feval_dd *tuner, gr_feval_dd *synchronizer, int osr, std::string key)
- : gr_block("gsm_receiver",
- gr_make_io_signature(MIN_IN, MAX_IN, sizeof(gr_complex)),
- gr_make_io_signature(MIN_OUT, MAX_OUT, 142 * sizeof(float))),
- d_OSR(osr),
- d_chan_imp_length(CHAN_IMP_RESP_LENGTH),
- d_tuner(tuner),
- d_counter(0),
- d_fcch_start_pos(0),
- d_freq_offset(0),
- d_state(first_fcch_search),
- d_burst_nr(osr),
- d_failed_sch(0),
- d_tch_decoder1( GSM::gFACCH_TCHFMapping ),
- d_tch_decoder2( GSM::gFACCH_TCHFMapping ),
- d_tch_decoder3( GSM::gFACCH_TCHFMapping ),
- d_tch_decoder4( GSM::gFACCH_TCHFMapping ),
- d_tch_decoder5( GSM::gFACCH_TCHFMapping ),
- d_tch_decoder6( GSM::gFACCH_TCHFMapping ),
- d_tch_decoder7( GSM::gFACCH_TCHFMapping )
-{
- int i;
- gmsk_mapper(SYNC_BITS, N_SYNC_BITS, d_sch_training_seq, gr_complex(0.0, -1.0));
- for (i = 0; i < TRAIN_SEQ_NUM; i++) {
- gr_complex startpoint;
- if (i == 6) { //this is nasty hack
- startpoint = gr_complex(-1.0, 0.0); //if I don't change it here all bits of normal bursts for BTSes with bcc=6 will have reversed values
- } else {
- startpoint = gr_complex(1.0, 0.0); //I've checked this hack for bcc==0,1,2,3,4,6
- } //I don't know what about bcc==5 and 7 yet
- //TODO:find source of this situation - this is purely mathematical problem I guess
-
- gmsk_mapper(train_seq[i], N_TRAIN_BITS, d_norm_training_seq[i], startpoint);
- }
- d_gsm_file = fopen( "speech.gsm", "wb" );
-
- d_hex_to_int['0'] = 0;
- d_hex_to_int['4'] = 4;
- d_hex_to_int['8'] = 8;
- d_hex_to_int['c'] = 0xc;
- d_hex_to_int['1'] = 1;
- d_hex_to_int['5'] = 5;
- d_hex_to_int['9'] = 9;
- d_hex_to_int['d'] = 0xd;
- d_hex_to_int['2'] = 2;
- d_hex_to_int['6'] = 6;
- d_hex_to_int['a'] = 0xa;
- d_hex_to_int['e'] = 0xe;
- d_hex_to_int['3'] = 3;
- d_hex_to_int['7'] = 7;
- d_hex_to_int['b'] = 0xb;
- d_hex_to_int['f'] = 0xf;
- read_key(key);
- /* Initialize GSM Stack */
- GS_new(&d_gs_ctx); //TODO: remove it! it's not a right place for a decoder
-}
-
-/*
- * Virtual destructor.
- */
-gsm_receiver_cf::~gsm_receiver_cf()
-{
-}
-
-void gsm_receiver_cf::forecast(int noutput_items, gr_vector_int &nitems_items_required)
-{
- nitems_items_required[0] = noutput_items * floor((TS_BITS + 2 * GUARD_PERIOD) * d_OSR);
-}
-
-int
-gsm_receiver_cf::general_work(int noutput_items,
- gr_vector_int &nitems_items,
- gr_vector_const_void_star &input_items,
- gr_vector_void_star &output_items)
-{
- const gr_complex *input = (const gr_complex *) input_items[0];
- //float *out = (float *) output_items[0];
- int produced_out = 0; //how many output elements were produced - this isn't used yet
- //probably the gsm receiver will be changed into sink so this variable won't be necessary
-
- switch (d_state) {
- //bootstrapping
- case first_fcch_search:
- if (find_fcch_burst(input, nitems_items[0])) { //find frequency correction burst in the input buffer
- set_frequency(d_freq_offset); //if fcch search is successful set frequency offset
- //produced_out = 0;
- d_state = next_fcch_search;
- } else {
- //produced_out = 0;
- d_state = first_fcch_search;
- }
- break;
-
- case next_fcch_search: { //this state is used because it takes some time (a bunch of buffered samples)
- float prev_freq_offset = d_freq_offset; //before previous set_frequqency cause change
- if (find_fcch_burst(input, nitems_items[0])) {
- if (abs(prev_freq_offset - d_freq_offset) > FCCH_MAX_FREQ_OFFSET) {
- set_frequency(d_freq_offset); //call set_frequncy only frequency offset change is greater than some value
- }
- //produced_out = 0;
- d_state = sch_search;
- } else {
- //produced_out = 0;
- d_state = next_fcch_search;
- }
- break;
- }
-
- case sch_search: {
- vector_complex channel_imp_resp(CHAN_IMP_RESP_LENGTH*d_OSR);
- int t1, t2, t3;
- int burst_start = 0;
- unsigned char output_binary[BURST_SIZE];
-
- if (reach_sch_burst(nitems_items[0])) { //wait for a SCH burst
- burst_start = get_sch_chan_imp_resp(input, &channel_imp_resp[0]); //get channel impulse response from it
- detect_burst(input, &channel_imp_resp[0], burst_start, output_binary); //detect bits using MLSE detection
- if (decode_sch(&output_binary[3], &t1, &t2, &t3, &d_ncc, &d_bcc) == 0) { //decode SCH burst
- DCOUT("sch burst_start: " << burst_start);
- DCOUT("bcc: " << d_bcc << " ncc: " << d_ncc << " t1: " << t1 << " t2: " << t2 << " t3: " << t3);
- d_burst_nr.set(t1, t2, t3, 0); //set counter of bursts value
-
- //configure the receiver - tell him where to find which burst type
- d_channel_conf.set_multiframe_type(TIMESLOT0, multiframe_51); //in the timeslot nr.0 bursts changes according to t3 counter
- configure_receiver();//TODO: this shouldn't be here - remove it when gsm receiver's interface will be ready
- d_channel_conf.set_burst_types(TIMESLOT0, FCCH_FRAMES, sizeof(FCCH_FRAMES) / sizeof(unsigned), fcch_burst); //tell where to find fcch bursts
- d_channel_conf.set_burst_types(TIMESLOT0, SCH_FRAMES, sizeof(SCH_FRAMES) / sizeof(unsigned), sch_burst); //sch bursts
- d_channel_conf.set_burst_types(TIMESLOT0, BCCH_FRAMES, sizeof(BCCH_FRAMES) / sizeof(unsigned), normal_burst);//!and maybe normal bursts of the BCCH logical channel
- d_burst_nr++;
-
- consume_each(burst_start + BURST_SIZE * d_OSR); //consume samples up to next guard period
- d_state = synchronized;
- } else {
- d_state = next_fcch_search; //if there is error in the sch burst go back to fcch search phase
- }
- } else {
- d_state = sch_search;
- }
- break;
- }
- //in this state receiver is synchronized and it processes bursts according to burst type for given burst number
- case synchronized: {
- vector_complex channel_imp_resp(CHAN_IMP_RESP_LENGTH*d_OSR);
- int burst_start;
- int offset = 0;
- int to_consume = 0;
- unsigned char output_binary[BURST_SIZE];
-
- burst_type b_type = d_channel_conf.get_burst_type(d_burst_nr); //get burst type for given burst number
-
- switch (b_type) {
- case fcch_burst: { //if it's FCCH burst
- const unsigned first_sample = ceil((GUARD_PERIOD + 2 * TAIL_BITS) * d_OSR) + 1;
- const unsigned last_sample = first_sample + USEFUL_BITS * d_OSR - TAIL_BITS * d_OSR;
- double freq_offset = compute_freq_offset(input, first_sample, last_sample); //extract frequency offset from it
-
- d_freq_offset_vals.push_front(freq_offset);
-
- if (d_freq_offset_vals.size() >= 10) {
- double sum = std::accumulate(d_freq_offset_vals.begin(), d_freq_offset_vals.end(), 0);
- double mean_offset = sum / d_freq_offset_vals.size(); //compute mean
- d_freq_offset_vals.clear();
- if (abs(mean_offset) > FCCH_MAX_FREQ_OFFSET) {
- d_freq_offset -= mean_offset; //and adjust frequency if it have changed beyond
- set_frequency(d_freq_offset); //some limit
- DCOUT("mean_offset: " << mean_offset);
- DCOUT("Adjusting frequency, new frequency offset: " << d_freq_offset << "\n");
- }
- }
- }
- break;
- case sch_burst: { //if it's SCH burst
- int t1, t2, t3, d_ncc, d_bcc;
- burst_start = get_sch_chan_imp_resp(input, &channel_imp_resp[0]); //get channel impulse response
- detect_burst(input, &channel_imp_resp[0], burst_start, output_binary); //MLSE detection of bits
- if (decode_sch(&output_binary[3], &t1, &t2, &t3, &d_ncc, &d_bcc) == 0) { //and decode SCH data
- // d_burst_nr.set(t1, t2, t3, 0); //but only to check if burst_start value is correct
- d_failed_sch = 0;
- DCOUT("bcc: " << d_bcc << " ncc: " << d_ncc << " t1: " << t1 << " t2: " << t2 << " t3: " << t3);
- offset = burst_start - floor((GUARD_PERIOD) * d_OSR); //compute offset from burst_start - burst should start after a guard period
- DCOUT(offset);
- to_consume += offset; //adjust with offset number of samples to be consumed
- } else {
- d_failed_sch++;
- if (d_failed_sch >= MAX_SCH_ERRORS) {
-// d_state = next_fcch_search; //TODO: this isn't good, the receiver is going wild when it goes back to next_fcch_search from here
-// d_freq_offset_vals.clear();
- DCOUT("many sch decoding errors");
- }
- }
- }
- break;
-
- case normal_burst: //if it's normal burst
- burst_start = get_norm_chan_imp_resp(input, &channel_imp_resp[0], d_bcc); //get channel impulse response for given training sequence number - d_bcc
- detect_burst(input, &channel_imp_resp[0], burst_start, output_binary); //MLSE detection of bits
- process_normal_burst(d_burst_nr, output_binary); //TODO: this shouldn't be here - remove it when gsm receiver's interface will be ready
- break;
-
- case dummy_or_normal: {
- burst_start = get_norm_chan_imp_resp(input, &channel_imp_resp[0], TS_DUMMY);
- detect_burst(input, &channel_imp_resp[0], burst_start, output_binary);
-
- std::vector<unsigned char> v(20);
- std::vector<unsigned char>::iterator it;
- it = std::set_difference(output_binary + TRAIN_POS, output_binary + TRAIN_POS + 16, &train_seq[TS_DUMMY][5], &train_seq[TS_DUMMY][21], v.begin());
- int different_bits = (it - v.begin());
-
- if (different_bits > 2) {
- burst_start = get_norm_chan_imp_resp(input, &channel_imp_resp[0], d_bcc);
- detect_burst(input, &channel_imp_resp[0], burst_start, output_binary);
- if (!output_binary[0] && !output_binary[1] && !output_binary[2]) {
- process_normal_burst(d_burst_nr, output_binary); //TODO: this shouldn't be here - remove it when gsm receiver's interface will be ready
- }
- }
- }
- case rach_burst:
- //implementation of this channel isn't possible in current gsm_receiver
- //it would take some realtime processing, counter of samples from USRP to
- //stay synchronized with this device and possibility to switch frequency from uplink
- //to C0 (where sch is) back and forth
-
- break;
- case dummy: //if it's dummy
- burst_start = get_norm_chan_imp_resp(input, &channel_imp_resp[0], TS_DUMMY); //read dummy
- detect_burst(input, &channel_imp_resp[0], burst_start, output_binary); // but as far as I know it's pointless
- break;
- case empty: //if it's empty burst
- break; //do nothing
- }
-
- d_burst_nr++; //go to next burst
-
- to_consume += TS_BITS * d_OSR + d_burst_nr.get_offset(); //consume samples of the burst up to next guard period
- //and add offset which is introduced by
- //0.25 fractional part of a guard period
- //burst_number computes this offset
- //but choice of this class to do this was random
- consume_each(to_consume);
- }
- break;
- }
-
- return produced_out;
-}
-
-bool gsm_receiver_cf::find_fcch_burst(const gr_complex *input, const int nitems)
-{
- circular_buffer_float phase_diff_buffer(FCCH_HITS_NEEDED * d_OSR); //circular buffer used to scan throug signal to find
- //best match for FCCH burst
- float phase_diff = 0;
- gr_complex conjprod;
- int start_pos = -1;
- int hit_count = 0;
- int miss_count = 0;
- float min_phase_diff;
- float max_phase_diff;
- double best_sum = 0;
- float lowest_max_min_diff = 99999;
-
- int to_consume = 0;
- int sample_number = 0;
- bool end = false;
- bool result = false;
- circular_buffer_float::iterator buffer_iter;
-
- /**@name Possible states of FCCH search algorithm*/
- //@{
- enum states {
- init, ///< initialize variables
- search, ///< search for positive samples
- found_something, ///< search for FCCH and the best position of it
- fcch_found, ///< when FCCH was found
- search_fail ///< when there is no FCCH in the input vector
- } fcch_search_state;
- //@}
-
- fcch_search_state = init;
-
- while (!end) {
- switch (fcch_search_state) {
-
- case init: //initialize variables
- hit_count = 0;
- miss_count = 0;
- start_pos = -1;
- lowest_max_min_diff = 99999;
- phase_diff_buffer.clear();
- fcch_search_state = search;
-
- break;
-
- case search: // search for positive samples
- sample_number++;
-
- if (sample_number > nitems - FCCH_HITS_NEEDED * d_OSR) { //if it isn't possible to find FCCH because
- //there's too few samples left to look into,
- to_consume = sample_number; //don't do anything with those samples which are left
- //and consume only those which were checked
- fcch_search_state = search_fail;
- } else {
- phase_diff = compute_phase_diff(input[sample_number], input[sample_number-1]);
-
- if (phase_diff > 0) { //if a positive phase difference was found
- to_consume = sample_number;
- fcch_search_state = found_something; //switch to state in which searches for FCCH
- } else {
- fcch_search_state = search;
- }
- }
-
- break;
-
- case found_something: {// search for FCCH and the best position of it
- if (phase_diff > 0) {
- hit_count++; //positive phase differencies increases hits_count
- } else {
- miss_count++; //negative increases miss_count
- }
-
- if ((miss_count >= FCCH_MAX_MISSES * d_OSR) && (hit_count <= FCCH_HITS_NEEDED * d_OSR)) {
- //if miss_count exceeds limit before hit_count
- fcch_search_state = init; //go to init
- continue;
- } else if (((miss_count >= FCCH_MAX_MISSES * d_OSR) && (hit_count > FCCH_HITS_NEEDED * d_OSR)) || (hit_count > 2 * FCCH_HITS_NEEDED * d_OSR)) {
- //if hit_count and miss_count exceeds limit then FCCH was found
- fcch_search_state = fcch_found;
- continue;
- } else if ((miss_count < FCCH_MAX_MISSES * d_OSR) && (hit_count > FCCH_HITS_NEEDED * d_OSR)) {
- //find difference between minimal and maximal element in the buffer
- //for FCCH this value should be low
- //this part is searching for a region where this value is lowest
- min_phase_diff = * (min_element(phase_diff_buffer.begin(), phase_diff_buffer.end()));
- max_phase_diff = * (max_element(phase_diff_buffer.begin(), phase_diff_buffer.end()));
-
- if (lowest_max_min_diff > max_phase_diff - min_phase_diff) {
- lowest_max_min_diff = max_phase_diff - min_phase_diff;
- start_pos = sample_number - FCCH_HITS_NEEDED * d_OSR - FCCH_MAX_MISSES * d_OSR; //store start pos
- best_sum = 0;
-
- for (buffer_iter = phase_diff_buffer.begin();
- buffer_iter != (phase_diff_buffer.end());
- buffer_iter++) {
- best_sum += *buffer_iter - (M_PI / 2) / d_OSR; //store best value of phase offset sum
- }
- }
- }
-
- sample_number++;
-
- if (sample_number >= nitems) { //if there's no single sample left to check
- fcch_search_state = search_fail;//FCCH search failed
- continue;
- }
-
- phase_diff = compute_phase_diff(input[sample_number], input[sample_number-1]);
- phase_diff_buffer.push_back(phase_diff);
- fcch_search_state = found_something;
- }
- break;
-
- case fcch_found: {
- DCOUT("fcch found on position: " << d_counter + start_pos);
- to_consume = start_pos + FCCH_HITS_NEEDED * d_OSR + 1; //consume one FCCH burst
-
- d_fcch_start_pos = d_counter + start_pos;
-
- //compute frequency offset
- double phase_offset = best_sum / FCCH_HITS_NEEDED;
- double freq_offset = phase_offset * 1625000.0 / (12.0 * M_PI);
- d_freq_offset -= freq_offset;
- DCOUT("freq_offset: " << d_freq_offset);
-
- end = true;
- result = true;
- break;
- }
-
- case search_fail:
- end = true;
- result = false;
- break;
- }
- }
-
- d_counter += to_consume;
- consume_each(to_consume);
-
- return result;
-}
-
-double gsm_receiver_cf::compute_freq_offset(const gr_complex * input, unsigned first_sample, unsigned last_sample)
-{
- double phase_sum = 0;
- unsigned ii;
-
- for (ii = first_sample; ii < last_sample; ii++) {
- double phase_diff = compute_phase_diff(input[ii], input[ii-1]) - (M_PI / 2) / d_OSR;
- phase_sum += phase_diff;
- }
-
- double phase_offset = phase_sum / (last_sample - first_sample);
- double freq_offset = phase_offset * 1625000.0 / (12.0 * M_PI);
- return freq_offset;
-}
-
-void gsm_receiver_cf::set_frequency(double freq_offset)
-{
- d_tuner->calleval(freq_offset);
-}
-
-inline float gsm_receiver_cf::compute_phase_diff(gr_complex val1, gr_complex val2)
-{
- gr_complex conjprod = val1 * conj(val2);
- return gr_fast_atan2f(imag(conjprod), real(conjprod));
-}
-
-bool gsm_receiver_cf::reach_sch_burst(const int nitems)
-{
- //it just consumes samples to get near to a SCH burst
- int to_consume = 0;
- bool result = false;
- unsigned sample_nr_near_sch_start = d_fcch_start_pos + (FRAME_BITS - SAFETY_MARGIN) * d_OSR;
-
- //consume samples until d_counter will be equal to sample_nr_near_sch_start
- if (d_counter < sample_nr_near_sch_start) {
- if (d_counter + nitems >= sample_nr_near_sch_start) {
- to_consume = sample_nr_near_sch_start - d_counter;
- } else {
- to_consume = nitems;
- }
- result = false;
- } else {
- to_consume = 0;
- result = true;
- }
-
- d_counter += to_consume;
- consume_each(to_consume);
- return result;
-}
-
-int gsm_receiver_cf::get_sch_chan_imp_resp(const gr_complex *input, gr_complex * chan_imp_resp)
-{
- vector_complex correlation_buffer;
- vector_float power_buffer;
- vector_float window_energy_buffer;
-
- int strongest_window_nr;
- int burst_start = 0;
- int chan_imp_resp_center = 0;
- float max_correlation = 0;
- float energy = 0;
-
- for (int ii = SYNC_POS * d_OSR; ii < (SYNC_POS + SYNC_SEARCH_RANGE) *d_OSR; ii++) {
- gr_complex correlation = correlate_sequence(&d_sch_training_seq[5], N_SYNC_BITS - 10, &input[ii]);
- correlation_buffer.push_back(correlation);
- power_buffer.push_back(pow(abs(correlation), 2));
- }
-
- //compute window energies
- vector_float::iterator iter = power_buffer.begin();
- bool loop_end = false;
- while (iter != power_buffer.end()) {
- vector_float::iterator iter_ii = iter;
- energy = 0;
-
- for (int ii = 0; ii < (d_chan_imp_length) *d_OSR; ii++, iter_ii++) {
- if (iter_ii == power_buffer.end()) {
- loop_end = true;
- break;
- }
- energy += (*iter_ii);
- }
- if (loop_end) {
- break;
- }
- iter++;
- window_energy_buffer.push_back(energy);
- }
-
- strongest_window_nr = max_element(window_energy_buffer.begin(), window_energy_buffer.end()) - window_energy_buffer.begin();
-// d_channel_imp_resp.clear();
-
- max_correlation = 0;
- for (int ii = 0; ii < (d_chan_imp_length) *d_OSR; ii++) {
- gr_complex correlation = correlation_buffer[strongest_window_nr + ii];
- if (abs(correlation) > max_correlation) {
- chan_imp_resp_center = ii;
- max_correlation = abs(correlation);
- }
-// d_channel_imp_resp.push_back(correlation);
- chan_imp_resp[ii] = correlation;
- }
-
- burst_start = strongest_window_nr + chan_imp_resp_center - 48 * d_OSR - 2 * d_OSR + 2 + SYNC_POS * d_OSR;
- return burst_start;
-}
-
-void gsm_receiver_cf::detect_burst(const gr_complex * input, gr_complex * chan_imp_resp, int burst_start, unsigned char * output_binary)
-{
- float output[BURST_SIZE];
- gr_complex rhh_temp[CHAN_IMP_RESP_LENGTH*d_OSR];
- gr_complex rhh[CHAN_IMP_RESP_LENGTH];
- gr_complex filtered_burst[BURST_SIZE];
- int start_state = 3;
- unsigned int stop_states[2] = {4, 12};
-
- autocorrelation(chan_imp_resp, rhh_temp, d_chan_imp_length*d_OSR);
- for (int ii = 0; ii < (d_chan_imp_length); ii++) {
- rhh[ii] = conj(rhh_temp[ii*d_OSR]);
- }
-
- mafi(&input[burst_start], BURST_SIZE, chan_imp_resp, d_chan_imp_length*d_OSR, filtered_burst);
-
- viterbi_detector(filtered_burst, BURST_SIZE, rhh, start_state, stop_states, 2, output);
-
- for (int i = 0; i < BURST_SIZE ; i++) {
- output_binary[i] = (output[i] > 0);
- }
-}
-
-//TODO consider placing this funtion in a separate class for signal processing
-void gsm_receiver_cf::gmsk_mapper(const unsigned char * input, int nitems, gr_complex * gmsk_output, gr_complex start_point)
-{
- gr_complex j = gr_complex(0.0, 1.0);
-
- int current_symbol;
- int encoded_symbol;
- int previous_symbol = 2 * input[0] - 1;
- gmsk_output[0] = start_point;
-
- for (int i = 1; i < nitems; i++) {
- //change bits representation to NRZ
- current_symbol = 2 * input[i] - 1;
- //differentially encode
- encoded_symbol = current_symbol * previous_symbol;
- //and do gmsk mapping
- gmsk_output[i] = j * gr_complex(encoded_symbol, 0.0) * gmsk_output[i-1];
- previous_symbol = current_symbol;
- }
-}
-
-//TODO consider use of some generalized function for correlation and placing it in a separate class for signal processing
-gr_complex gsm_receiver_cf::correlate_sequence(const gr_complex * sequence, int length, const gr_complex * input)
-{
- gr_complex result(0.0, 0.0);
- int sample_number = 0;
-
- for (int ii = 0; ii < length; ii++) {
- sample_number = (ii * d_OSR) ;
- result += sequence[ii] * conj(input[sample_number]);
- }
-
- result = result / gr_complex(length, 0);
- return result;
-}
-
-//computes autocorrelation for positive arguments
-//TODO consider placing this funtion in a separate class for signal processing
-inline void gsm_receiver_cf::autocorrelation(const gr_complex * input, gr_complex * out, int nitems)
-{
- int i, k;
- for (k = nitems - 1; k >= 0; k--) {
- out[k] = gr_complex(0, 0);
- for (i = k; i < nitems; i++) {
- out[k] += input[i] * conj(input[i-k]);
- }
- }
-}
-
-//TODO consider use of some generalized function for filtering and placing it in a separate class for signal processing
-inline void gsm_receiver_cf::mafi(const gr_complex * input, int nitems, gr_complex * filter, int filter_length, gr_complex * output)
-{
- int ii = 0, n, a;
-
- for (n = 0; n < nitems; n++) {
- a = n * d_OSR;
- output[n] = 0;
- ii = 0;
-
- while (ii < filter_length) {
- if ((a + ii) >= nitems*d_OSR)
- break;
- output[n] += input[a+ii] * filter[ii];
- ii++;
- }
- }
-}
-
-//TODO: get_norm_chan_imp_resp is similar to get_sch_chan_imp_resp - consider joining this two functions
-//TODO: this is place where most errors are introduced and can be corrected by improvements to this fuction
-//especially computations of strongest_window_nr
-int gsm_receiver_cf::get_norm_chan_imp_resp(const gr_complex *input, gr_complex * chan_imp_resp, int bcc)
-{
- vector_complex correlation_buffer;
- vector_float power_buffer;
- vector_float window_energy_buffer;
-
- int strongest_window_nr;
- int burst_start = 0;
- int chan_imp_resp_center = 0;
- float max_correlation = 0;
- float energy = 0;
-
- int search_center = (int)((TRAIN_POS + GUARD_PERIOD) * d_OSR);
- int search_start_pos = search_center + 1;
-// int search_start_pos = search_center - d_chan_imp_length * d_OSR;
- int search_stop_pos = search_center + d_chan_imp_length * d_OSR + 2 * d_OSR;
-
- for (int ii = search_start_pos; ii < search_stop_pos; ii++) {
- gr_complex correlation = correlate_sequence(&d_norm_training_seq[bcc][TRAIN_BEGINNING], N_TRAIN_BITS - 10, &input[ii]);
-
- correlation_buffer.push_back(correlation);
- power_buffer.push_back(pow(abs(correlation), 2));
- }
-
- //compute window energies
- vector_float::iterator iter = power_buffer.begin();
- bool loop_end = false;
- while (iter != power_buffer.end()) {
- vector_float::iterator iter_ii = iter;
- energy = 0;
-
- for (int ii = 0; ii < (d_chan_imp_length - 2)*d_OSR; ii++, iter_ii++) {
-// for (int ii = 0; ii < (d_chan_imp_length)*d_OSR; ii++, iter_ii++) {
- if (iter_ii == power_buffer.end()) {
- loop_end = true;
- break;
- }
- energy += (*iter_ii);
- }
- if (loop_end) {
- break;
- }
- iter++;
-
- window_energy_buffer.push_back(energy);
- }
- //!why doesn't this work
- strongest_window_nr = max_element(window_energy_buffer.begin(), window_energy_buffer.end()) - window_energy_buffer.begin();
- strongest_window_nr = 3; //! so I have to override it here
-
- max_correlation = 0;
- for (int ii = 0; ii < (d_chan_imp_length)*d_OSR; ii++) {
- gr_complex correlation = correlation_buffer[strongest_window_nr + ii];
- if (abs(correlation) > max_correlation) {
- chan_imp_resp_center = ii;
- max_correlation = abs(correlation);
- }
-// d_channel_imp_resp.push_back(correlation);
- chan_imp_resp[ii] = correlation;
- }
- // We want to use the first sample of the impulseresponse, and the
- // corresponding samples of the received signal.
- // the variable sync_w should contain the beginning of the used part of
- // training sequence, which is 3+57+1+6=67 bits into the burst. That is
- // we have that sync_t16 equals first sample in bit number 67.
-
- burst_start = search_start_pos + chan_imp_resp_center + strongest_window_nr - TRAIN_POS * d_OSR;
-
- // GMSK modulator introduces ISI - each bit is expanded for 3*Tb
- // and it's maximum value is in the last bit period, so burst starts
- // 2*Tb earlier
- burst_start -= 2 * d_OSR;
- burst_start += 2;
- //std::cout << " burst_start: " << burst_start << " center: " << ((float)(search_start_pos + strongest_window_nr + chan_imp_resp_center)) / d_OSR << " stronegest window nr: " << strongest_window_nr << "\n";
-
- return burst_start;
-}
-
diff --git a/src/lib/gsm_receiver_cf.h b/src/lib/gsm_receiver_cf.h
deleted file mode 100644
index 21cb1ff..0000000
--- a/src/lib/gsm_receiver_cf.h
+++ /dev/null
@@ -1,254 +0,0 @@
-/* -*- c++ -*- */
-/*
- * @file
- * @author Piotr Krysik <pkrysik@stud.elka.pw.edu.pl>
- * @section LICENSE
- *
- * 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 3, 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; see the file COPYING. If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street,
- * Boston, MA 02110-1301, USA.
- */
-#ifndef INCLUDED_GSM_RECEIVER_CF_H
-#define INCLUDED_GSM_RECEIVER_CF_H
-
-#include <vector>
-#include <list>
-#include <gr_block.h>
-#include <gr_complex.h>
-#include <gr_feval.h>
-#include <gsm_constants.h>
-#include <gsm_receiver_config.h>
-
-#include <gsmstack.h> //TODO: remember to remove this line in the future!
-#include "GSML1FEC.h" //!!
-#include <a5-1-2.h>//!!
-#include <string>//!!
-#include <map>//!!
-
-class gsm_receiver_cf;
-
-typedef boost::shared_ptr<gsm_receiver_cf> gsm_receiver_cf_sptr;
-typedef std::vector<gr_complex> vector_complex;
-
-gsm_receiver_cf_sptr gsm_make_receiver_cf(gr_feval_dd *tuner, gr_feval_dd *synchronizer, int osr, std::string key);
-
-/** GSM Receiver GNU Radio block
- *
- * GSM Receiver class supports frequency correction, synchronisation and
- * MLSE (Maximum Likelihood Sequence Estimation) estimation of synchronisation
- * bursts and normal bursts.
- * \ingroup block
- */
-
-class gsm_receiver_cf : public gr_block
-{
- private:
- std::map<char,int> d_hex_to_int;
- FILE * d_gsm_file; //!!
- byte d_KC[8]; //!!
- GSM::TCHFACCHL1Decoder d_tch_decoder1; //!!
- GSM::TCHFACCHL1Decoder d_tch_decoder2; //!!
- GSM::TCHFACCHL1Decoder d_tch_decoder3; //!!
- GSM::TCHFACCHL1Decoder d_tch_decoder4; //!!
- GSM::TCHFACCHL1Decoder d_tch_decoder5; //!!
- GSM::TCHFACCHL1Decoder d_tch_decoder6; //!!
- GSM::TCHFACCHL1Decoder d_tch_decoder7; //!!
- /**@name Configuration of the receiver */
- //@{
- const int d_OSR; ///< oversampling ratio
- const int d_chan_imp_length; ///< channel impulse length
- //@}
-
- gr_complex d_sch_training_seq[N_SYNC_BITS]; ///<encoded training sequence of a SCH burst
- gr_complex d_norm_training_seq[TRAIN_SEQ_NUM][N_TRAIN_BITS]; ///<encoded training sequences of a normal bursts and dummy bursts
-
- gr_feval_dd *d_tuner; ///<callback to a python object which is used for frequency tunning
- gr_feval_dd *d_synchronizer; ///<callback to a python object which is used to correct offset of USRP's internal clock
-
- /** Countes samples consumed by the receiver
- *
- * It is used in beetween find_fcch_burst and reach_sch_burst calls.
- * My intention was to synchronize this counter with some internal sample
- * counter of the USRP. Simple access to such USRP's counter isn't possible
- * so this variable isn't used in the "synchronized" state of the receiver yet.
- */
- unsigned d_counter;
-
- /**@name Variables used to store result of the find_fcch_burst fuction */
- //@{
- unsigned d_fcch_start_pos; ///< position of the first sample of the fcch burst
- float d_freq_offset; ///< frequency offset of the received signal
- //@}
- std::list<double> d_freq_offset_vals;
-
- /**@name Identifiers of the BTS extracted from the SCH burst */
- //@{
- int d_ncc; ///< network color code
- int d_bcc; ///< base station color code
- //@}
-
- /**@name Internal state of the gsm receiver */
- //@{
- enum states {
- first_fcch_search, next_fcch_search, sch_search, // synchronization search part
- synchronized // receiver is synchronized in this state
- } d_state;
- //@}
-
- /**@name Variables which make internal state in the "synchronized" state */
- //@{
- burst_counter d_burst_nr; ///< frame number and timeslot number
- channel_configuration d_channel_conf; ///< mapping of burst_counter to burst_type
- //@}
-
- unsigned d_failed_sch; ///< number of subsequent erroneous SCH bursts
-
- // GSM Stack
- GS_CTX d_gs_ctx;//TODO: remove it! it'a not right place for a decoder
-
- friend gsm_receiver_cf_sptr gsm_make_receiver_cf(gr_feval_dd *tuner, gr_feval_dd *synchronizer, int osr, std::string key);
- gsm_receiver_cf(gr_feval_dd *tuner, gr_feval_dd *synchronizer, int osr, std::string key);
-
- /** Function whis is used to search a FCCH burst and to compute frequency offset before
- * "synchronized" state of the receiver
- *
- * TODO: Describe the FCCH search algorithm in the documentation
- * @param input vector with input signal
- * @param nitems number of samples in the input vector
- * @return
- */
- bool find_fcch_burst(const gr_complex *input, const int nitems);
-
- /** Computes frequency offset from FCCH burst samples
- *
- * @param input vector with input samples
- * @param first_sample number of the first sample of the FCCH busrt
- * @param last_sample number of the last sample of the FCCH busrt
- * @return frequency offset
- */
- double compute_freq_offset(const gr_complex * input, unsigned first_sample, unsigned last_sample);
-
- /** Calls d_tuner's method to set frequency offset from Python level
- *
- * @param freq_offset absolute frequency offset of the received signal
- */
- void set_frequency(double freq_offset);
-
- /** Computes angle between two complex numbers
- *
- * @param val1 first complex number
- * @param val2 second complex number
- * @return
- */
- inline float compute_phase_diff(gr_complex val1, gr_complex val2);
-
- /** Function whis is used to get near to SCH burst
- *
- * @param nitems number of samples in the gsm_receiver's buffer
- * @return true if SCH burst is near, false otherwise
- */
- bool reach_sch_burst(const int nitems);
-
- /** Extracts channel impulse response from a SCH burst and computes first sample number of this burst
- *
- * @param input vector with input samples
- * @param chan_imp_resp complex vector where channel impulse response will be stored
- * @return number of first sample of the burst
- */
- int get_sch_chan_imp_resp(const gr_complex *input, gr_complex * chan_imp_resp);
-
- /** MLSE detection of a burst bits
- *
- * Detects bits of burst using viterbi algorithm.
- * @param input vector with input samples
- * @param chan_imp_resp vector with the channel impulse response
- * @param burst_start number of the first sample of the burst
- * @param output_binary vector with output bits
- */
- void detect_burst(const gr_complex * input, gr_complex * chan_imp_resp, int burst_start, unsigned char * output_binary);
-
- /** Encodes differentially input bits and maps them into MSK states
- *
- * @param input vector with input bits
- * @param nitems number of samples in the "input" vector
- * @param gmsk_output bits mapped into MSK states
- * @param start_point first state
- */
- void gmsk_mapper(const unsigned char * input, int nitems, gr_complex * gmsk_output, gr_complex start_point);
-
- /** Correlates MSK mapped sequence with input signal
- *
- * @param sequence MKS mapped sequence
- * @param length length of the sequence
- * @param input_signal vector with input samples
- * @return correlation value
- */
- gr_complex correlate_sequence(const gr_complex * sequence, int length, const gr_complex * input);
-
- /** Computes autocorrelation of input vector for positive arguments
- *
- * @param input vector with input samples
- * @param out output vector
- * @param nitems length of the input vector
- */
- inline void autocorrelation(const gr_complex * input, gr_complex * out, int nitems);
-
- /** Filters input signal through channel impulse response
- *
- * @param input vector with input samples
- * @param nitems number of samples to pass through filter
- * @param filter filter taps - channel impulse response
- * @param filter_length nember of filter taps
- * @param output vector with filtered samples
- */
- inline void mafi(const gr_complex * input, int nitems, gr_complex * filter, int filter_length, gr_complex * output);
-
- /** Extracts channel impulse response from a normal burst and computes first sample number of this burst
- *
- * @param input vector with input samples
- * @param chan_imp_resp complex vector where channel impulse response will be stored
- * @param search_range possible absolute offset of a channel impulse response start
- * @param bcc base station color code - number of a training sequence
- * @return first sample number of normal burst
- */
- int get_norm_chan_imp_resp(const gr_complex * input, gr_complex * chan_imp_resp, int bcc);
-
-
- /**
- *
- */
- void read_key(std::string key);
-
- /**
- *
- */
- void process_normal_burst(burst_counter burst_nr, const unsigned char * burst_binary);
-
- /**
- *
- */
- void configure_receiver();
-
-
-
- public:
- ~gsm_receiver_cf();
- void forecast(int noutput_items, gr_vector_int &ninput_items_required);
- int general_work(int noutput_items,
- gr_vector_int &ninput_items,
- gr_vector_const_void_star &input_items,
- gr_vector_void_star &output_items);
-};
-
-#endif /* INCLUDED_GSM_RECEIVER_CF_H */
diff --git a/src/lib/gsm_receiver_config.cc b/src/lib/gsm_receiver_config.cc
deleted file mode 100644
index 44344f7..0000000
--- a/src/lib/gsm_receiver_config.cc
+++ /dev/null
@@ -1,84 +0,0 @@
-/* -*- c++ -*- */
-/*
- * @file
- * @author Piotr Krysik <pkrysik@stud.elka.pw.edu.pl>
- * @section LICENSE
- *
- * GNU Radio 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 3, or (at your option)
- * any later version.
- *
- * GNU Radio 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 GNU Radio; see the file COPYING. If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street,
- * Boston, MA 02110-1301, USA.
- *
- * @section DESCRIPTION
- * This file contains classes which define gsm_receiver configuration
- * and the burst_counter which is used to store internal state of the receiver
- * when it's synchronized
- */
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include <gsm_receiver_config.h>
-
-burst_counter & burst_counter::operator++(int)
-{
- d_timeslot_nr++;
- if (d_timeslot_nr == TS_PER_FRAME) {
- d_timeslot_nr = 0;
-
- if ((d_t2 == 25) && (d_t3 == 50)) {
- d_t1 = (d_t1 + 1) % (1 << 11);
- }
-
- d_t2 = (d_t2 + 1) % 26;
- d_t3 = (d_t3 + 1) % 51;
- }
-
- //update offset - this is integer for d_OSR which is multiple of four
- d_offset_fractional += GUARD_FRACTIONAL * d_OSR;
- d_offset_integer = floor(d_offset_fractional);
- d_offset_fractional = d_offset_fractional - d_offset_integer;
- return (*this);
-}
-
-void burst_counter::set(uint32_t t1, uint32_t t2, uint32_t t3, uint32_t timeslot_nr)
-{
- d_t1 = t1;
- d_t2 = t2;
- d_t3 = t3;
- d_timeslot_nr = timeslot_nr;
- double first_sample_position = (get_frame_nr() * 8 + timeslot_nr) * TS_BITS;
- d_offset_fractional = first_sample_position - floor(first_sample_position);
- d_offset_integer = 0;
-}
-
-burst_type channel_configuration::get_burst_type(burst_counter burst_nr)
-{
- uint32_t timeslot_nr = burst_nr.get_timeslot_nr();
- multiframe_type m_type = d_timeslots_descriptions[timeslot_nr].get_type();
- uint32_t nr;
-
- switch (m_type) {
- case multiframe_26:
- nr = burst_nr.get_t2();
- break;
- case multiframe_51:
- nr = burst_nr.get_t3();
- break;
- default:
- nr = 0;
- break;
- }
-
- return d_timeslots_descriptions[timeslot_nr].get_burst_type(nr);
-}
diff --git a/src/lib/gsm_receiver_config.h b/src/lib/gsm_receiver_config.h
deleted file mode 100644
index b7ba43a..0000000
--- a/src/lib/gsm_receiver_config.h
+++ /dev/null
@@ -1,164 +0,0 @@
-/* -*- c++ -*- */
-/*
- * @file
- * @author Piotr Krysik <pkrysik@stud.elka.pw.edu.pl>
- * @section LICENSE
- *
- * GNU Radio 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 3, or (at your option)
- * any later version.
- *
- * GNU Radio 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 GNU Radio; see the file COPYING. If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street,
- * Boston, MA 02110-1301, USA.
- *
- * @section DESCRIPTION
- * This file contains classes which define gsm_receiver configuration
- * and the burst_counter which is used to store internal state of the receiver
- * when it's synchronized
- */
-#ifndef INCLUDED_GSM_RECEIVER_CONFIG_H
-#define INCLUDED_GSM_RECEIVER_CONFIG_H
-
-#include <vector>
-#include <algorithm>
-#include <math.h>
-#include <stdint.h>
-#include <gsm_constants.h>
-
-class multiframe_configuration
-{
- private:
- multiframe_type d_type;
- std::vector<burst_type> d_burst_types;
- public:
- multiframe_configuration() {
- d_type = unknown;
- fill(d_burst_types.begin(), d_burst_types.end(), empty);
- }
-
- ~multiframe_configuration() {}
-
- void set_type(multiframe_type type) {
- if (type == multiframe_26) {
- d_burst_types.resize(26);
- } else {
- d_burst_types.resize(51);
- }
-
- d_type = type;
- }
-
- void set_burst_type(int nr, burst_type type) {
- d_burst_types[nr] = type;
- }
-
- multiframe_type get_type() {
- return d_type;
- }
-
- burst_type get_burst_type(int nr) {
- return d_burst_types[nr];
- }
-};
-
-class burst_counter
-{
- private:
- const int d_OSR;
- uint32_t d_t1, d_t2, d_t3, d_timeslot_nr;
- double d_offset_fractional;
- double d_offset_integer;
- public:
- burst_counter(int osr):
- d_OSR(osr),
- d_t1(0),
- d_t2(0),
- d_t3(0),
- d_timeslot_nr(0),
- d_offset_fractional(0.0),
- d_offset_integer(0.0) {
- }
-
- burst_counter(int osr, uint32_t t1, uint32_t t2, uint32_t t3, uint32_t timeslot_nr):
- d_OSR(osr),
- d_t1(t1),
- d_t2(t2),
- d_t3(t3),
- d_timeslot_nr(timeslot_nr),
- d_offset_fractional(0.0),
- d_offset_integer(0.0) {
- double first_sample_position = (get_frame_nr() * 8 + timeslot_nr) * TS_BITS;
- d_offset_integer = floor(first_sample_position);
- d_offset_fractional = first_sample_position - floor(first_sample_position);
- }
-
- burst_counter & operator++(int);
- void set(uint32_t t1, uint32_t t2, uint32_t t3, uint32_t timeslot_nr);
-
- uint32_t get_t1() {
- return d_t1;
- }
-
- uint32_t get_t2() {
- return d_t2;
- }
-
- uint32_t get_t3() {
- return d_t3;
- }
-
- uint32_t get_timeslot_nr() {
- return d_timeslot_nr;
- }
-
- uint32_t get_frame_nr() {
- return (51 * 26 * d_t1) + (51 * (((d_t3 + 26) - d_t2) % 26)) + d_t3;
- }
-
- uint32_t get_frame_nr_mod() {
- return (d_t1 << 11) + (d_t3 << 5) + d_t2;
- }
-
- unsigned get_offset() {
- return (unsigned)d_offset_integer;
- }
-};
-
-class channel_configuration
-{
- private:
- multiframe_configuration d_timeslots_descriptions[TS_PER_FRAME];
- public:
- channel_configuration() {
- for (int i = 0; i < TS_PER_FRAME; i++) {
- d_timeslots_descriptions[i].set_type(unknown);
- }
- }
-
- void set_multiframe_type(int timeslot_nr, multiframe_type type) {
- d_timeslots_descriptions[timeslot_nr].set_type(type);
- }
-
- void set_burst_types(int timeslot_nr, const unsigned mapping[], unsigned mapping_size, burst_type b_type) {
- unsigned i;
- for (i = 0; i < mapping_size; i++) {
- d_timeslots_descriptions[timeslot_nr].set_burst_type(mapping[i], b_type);
- }
- }
-
- void set_single_burst_type(int timeslot_nr, int burst_nr, burst_type b_type) {
- d_timeslots_descriptions[timeslot_nr].set_burst_type(burst_nr, b_type);
- }
-
- burst_type get_burst_type(burst_counter burst_nr);
-};
-
-#endif /* INCLUDED_GSM_RECEIVER_CONFIG_H */
diff --git a/src/lib/viterbi_detector.cc b/src/lib/viterbi_detector.cc
deleted file mode 100644
index f3445cf..0000000
--- a/src/lib/viterbi_detector.cc
+++ /dev/null
@@ -1,554 +0,0 @@
-/* -*- c++ -*- */
-/*
- * @file
- * @author Piotr Krysik <pkrysik@stud.elka.pw.edu.pl>
- * @section LICENSE
- *
- * 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 3, 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; see the file COPYING. If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street,
- * Boston, MA 02110-1301, USA.
- */
-
-/*
- * viterbi_detector:
- * This part does the detection of received sequnece.
- * Employed algorithm is viterbi Maximum Likehood Sequence Estimation.
- * At this moment it gives hard decisions on the output, but
- * it was designed with soft decisions in mind.
- *
- * SYNTAX: void viterbi_detector(
- * const gr_complex * input,
- * unsigned int samples_num,
- * gr_complex * rhh,
- * unsigned int start_state,
- * const unsigned int * stop_states,
- * unsigned int stops_num,
- * float * output)
- *
- * INPUT: input: Complex received signal afted matched filtering.
- * samples_num: Number of samples in the input table.
- * rhh: The autocorrelation of the estimated channel
- * impulse response.
- * start_state: Number of the start point. In GSM each burst
- * starts with sequence of three bits (0,0,0) which
- * indicates start point of the algorithm.
- * stop_states: Table with numbers of possible stop states.
- * stops_num: Number of possible stop states
- *
- *
- * OUTPUT: output: Differentially decoded hard output of the algorithm:
- * -1 for logical "0" and 1 for logical "1"
- *
- * SUB_FUNC: none
- *
- * TEST(S): Tested with real world normal burst.
- */
-
-#include <gnuradio/gr_complex.h>
-#include <gsm_constants.h>
-#define PATHS_NUM (1 << (CHAN_IMP_RESP_LENGTH-1))
-
-void viterbi_detector(const gr_complex * input, unsigned int samples_num, gr_complex * rhh, unsigned int start_state, const unsigned int * stop_states, unsigned int stops_num, float * output)
-{
- float increment[8];
- float path_metrics1[16];
- float path_metrics2[16];
- float * new_path_metrics;
- float * old_path_metrics;
- float * tmp;
- float trans_table[BURST_SIZE][16];
- float pm_candidate1, pm_candidate2;
- bool real_imag;
- float input_symbol_real, input_symbol_imag;
- unsigned int i, sample_nr;
-
-/*
-* Setup first path metrics, so only state pointed by start_state is possible.
-* Start_state metric is equal to zero, the rest is written with some very low value,
-* which makes them practically impossible to occur.
-*/
- for(i=0; i<PATHS_NUM; i++){
- path_metrics1[i]=(-10e30);
- }
- path_metrics1[start_state]=0;
-
-/*
-* Compute Increment - a table of values which does not change for subsequent input samples.
-* Increment is table of reference levels for computation of branch metrics:
-* branch metric = (+/-)received_sample (+/-) reference_level
-*/
- increment[0] = -rhh[1].imag() -rhh[2].real() -rhh[3].imag() +rhh[4].real();
- increment[1] = rhh[1].imag() -rhh[2].real() -rhh[3].imag() +rhh[4].real();
- increment[2] = -rhh[1].imag() +rhh[2].real() -rhh[3].imag() +rhh[4].real();
- increment[3] = rhh[1].imag() +rhh[2].real() -rhh[3].imag() +rhh[4].real();
- increment[4] = -rhh[1].imag() -rhh[2].real() +rhh[3].imag() +rhh[4].real();
- increment[5] = rhh[1].imag() -rhh[2].real() +rhh[3].imag() +rhh[4].real();
- increment[6] = -rhh[1].imag() +rhh[2].real() +rhh[3].imag() +rhh[4].real();
- increment[7] = rhh[1].imag() +rhh[2].real() +rhh[3].imag() +rhh[4].real();
-
-
-/*
-* Computation of path metrics and decisions (Add-Compare-Select).
-* It's composed of two parts: one for odd input samples (imaginary numbers)
-* and one for even samples (real numbers).
-* Each part is composed of independent (parallelisable) statements like
-* this one:
-* pm_candidate1 = old_path_metrics[0] - input_symbol_real - increment[7];
-* pm_candidate2 = old_path_metrics[8] - input_symbol_real + increment[0];
-* if(pm_candidate1 > pm_candidate2){
-* new_path_metrics[0] = pm_candidate1;
-* trans_table[sample_nr][0] = -1.0;
-* }
-* else{
-* new_path_metrics[0] = pm_candidate2;
-* trans_table[sample_nr][0] = 1.0;
-* }
-* This is very good point for optimisations (SIMD or OpenMP) as it's most time
-* consuming part of this function.
-*/
- sample_nr=0;
- old_path_metrics=path_metrics1;
- new_path_metrics=path_metrics2;
- while(sample_nr<samples_num){
- //Processing imag states
- real_imag=1;
- input_symbol_imag = input[sample_nr].imag();
-
- pm_candidate1 = old_path_metrics[0] + input_symbol_imag - increment[2];
- pm_candidate2 = old_path_metrics[8] + input_symbol_imag + increment[5];
- if(pm_candidate1 > pm_candidate2){
- new_path_metrics[0] = pm_candidate1;
- trans_table[sample_nr][0] = -1.0;
- }
- else{
- new_path_metrics[0] = pm_candidate2;
- trans_table[sample_nr][0] = 1.0;
- }
-
- pm_candidate1 = old_path_metrics[0] - input_symbol_imag + increment[2];
- pm_candidate2 = old_path_metrics[8] - input_symbol_imag - increment[5];
- if(pm_candidate1 > pm_candidate2){
- new_path_metrics[1] = pm_candidate1;
- trans_table[sample_nr][1] = -1.0;
- }
- else{
- new_path_metrics[1] = pm_candidate2;
- trans_table[sample_nr][1] = 1.0;
- }
-
- pm_candidate1 = old_path_metrics[1] + input_symbol_imag - increment[3];
- pm_candidate2 = old_path_metrics[9] + input_symbol_imag + increment[4];
- if(pm_candidate1 > pm_candidate2){
- new_path_metrics[2] = pm_candidate1;
- trans_table[sample_nr][2] = -1.0;
- }
- else{
- new_path_metrics[2] = pm_candidate2;
- trans_table[sample_nr][2] = 1.0;
- }
-
- pm_candidate1 = old_path_metrics[1] - input_symbol_imag + increment[3];
- pm_candidate2 = old_path_metrics[9] - input_symbol_imag - increment[4];
- if(pm_candidate1 > pm_candidate2){
- new_path_metrics[3] = pm_candidate1;
- trans_table[sample_nr][3] = -1.0;
- }
- else{
- new_path_metrics[3] = pm_candidate2;
- trans_table[sample_nr][3] = 1.0;
- }
-
- pm_candidate1 = old_path_metrics[2] + input_symbol_imag - increment[0];
- pm_candidate2 = old_path_metrics[10] + input_symbol_imag + increment[7];
- if(pm_candidate1 > pm_candidate2){
- new_path_metrics[4] = pm_candidate1;
- trans_table[sample_nr][4] = -1.0;
- }
- else{
- new_path_metrics[4] = pm_candidate2;
- trans_table[sample_nr][4] = 1.0;
- }
-
- pm_candidate1 = old_path_metrics[2] - input_symbol_imag + increment[0];
- pm_candidate2 = old_path_metrics[10] - input_symbol_imag - increment[7];
- if(pm_candidate1 > pm_candidate2){
- new_path_metrics[5] = pm_candidate1;
- trans_table[sample_nr][5] = -1.0;
- }
- else{
- new_path_metrics[5] = pm_candidate2;
- trans_table[sample_nr][5] = 1.0;
- }
-
- pm_candidate1 = old_path_metrics[3] + input_symbol_imag - increment[1];
- pm_candidate2 = old_path_metrics[11] + input_symbol_imag + increment[6];
- if(pm_candidate1 > pm_candidate2){
- new_path_metrics[6] = pm_candidate1;
- trans_table[sample_nr][6] = -1.0;
- }
- else{
- new_path_metrics[6] = pm_candidate2;
- trans_table[sample_nr][6] = 1.0;
- }
-
- pm_candidate1 = old_path_metrics[3] - input_symbol_imag + increment[1];
- pm_candidate2 = old_path_metrics[11] - input_symbol_imag - increment[6];
- if(pm_candidate1 > pm_candidate2){
- new_path_metrics[7] = pm_candidate1;
- trans_table[sample_nr][7] = -1.0;
- }
- else{
- new_path_metrics[7] = pm_candidate2;
- trans_table[sample_nr][7] = 1.0;
- }
-
- pm_candidate1 = old_path_metrics[4] + input_symbol_imag - increment[6];
- pm_candidate2 = old_path_metrics[12] + input_symbol_imag + increment[1];
- if(pm_candidate1 > pm_candidate2){
- new_path_metrics[8] = pm_candidate1;
- trans_table[sample_nr][8] = -1.0;
- }
- else{
- new_path_metrics[8] = pm_candidate2;
- trans_table[sample_nr][8] = 1.0;
- }
-
- pm_candidate1 = old_path_metrics[4] - input_symbol_imag + increment[6];
- pm_candidate2 = old_path_metrics[12] - input_symbol_imag - increment[1];
- if(pm_candidate1 > pm_candidate2){
- new_path_metrics[9] = pm_candidate1;
- trans_table[sample_nr][9] = -1.0;
- }
- else{
- new_path_metrics[9] = pm_candidate2;
- trans_table[sample_nr][9] = 1.0;
- }
-
- pm_candidate1 = old_path_metrics[5] + input_symbol_imag - increment[7];
- pm_candidate2 = old_path_metrics[13] + input_symbol_imag + increment[0];
- if(pm_candidate1 > pm_candidate2){
- new_path_metrics[10] = pm_candidate1;
- trans_table[sample_nr][10] = -1.0;
- }
- else{
- new_path_metrics[10] = pm_candidate2;
- trans_table[sample_nr][10] = 1.0;
- }
-
- pm_candidate1 = old_path_metrics[5] - input_symbol_imag + increment[7];
- pm_candidate2 = old_path_metrics[13] - input_symbol_imag - increment[0];
- if(pm_candidate1 > pm_candidate2){
- new_path_metrics[11] = pm_candidate1;
- trans_table[sample_nr][11] = -1.0;
- }
- else{
- new_path_metrics[11] = pm_candidate2;
- trans_table[sample_nr][11] = 1.0;
- }
-
- pm_candidate1 = old_path_metrics[6] + input_symbol_imag - increment[4];
- pm_candidate2 = old_path_metrics[14] + input_symbol_imag + increment[3];
- if(pm_candidate1 > pm_candidate2){
- new_path_metrics[12] = pm_candidate1;
- trans_table[sample_nr][12] = -1.0;
- }
- else{
- new_path_metrics[12] = pm_candidate2;
- trans_table[sample_nr][12] = 1.0;
- }
-
- pm_candidate1 = old_path_metrics[6] - input_symbol_imag + increment[4];
- pm_candidate2 = old_path_metrics[14] - input_symbol_imag - increment[3];
- if(pm_candidate1 > pm_candidate2){
- new_path_metrics[13] = pm_candidate1;
- trans_table[sample_nr][13] = -1.0;
- }
- else{
- new_path_metrics[13] = pm_candidate2;
- trans_table[sample_nr][13] = 1.0;
- }
-
- pm_candidate1 = old_path_metrics[7] + input_symbol_imag - increment[5];
- pm_candidate2 = old_path_metrics[15] + input_symbol_imag + increment[2];
- if(pm_candidate1 > pm_candidate2){
- new_path_metrics[14] = pm_candidate1;
- trans_table[sample_nr][14] = -1.0;
- }
- else{
- new_path_metrics[14] = pm_candidate2;
- trans_table[sample_nr][14] = 1.0;
- }
-
- pm_candidate1 = old_path_metrics[7] - input_symbol_imag + increment[5];
- pm_candidate2 = old_path_metrics[15] - input_symbol_imag - increment[2];
- if(pm_candidate1 > pm_candidate2){
- new_path_metrics[15] = pm_candidate1;
- trans_table[sample_nr][15] = -1.0;
- }
- else{
- new_path_metrics[15] = pm_candidate2;
- trans_table[sample_nr][15] = 1.0;
- }
- tmp=old_path_metrics;
- old_path_metrics=new_path_metrics;
- new_path_metrics=tmp;
-
- sample_nr++;
- if(sample_nr==samples_num)
- break;
-
- //Processing real states
- real_imag=0;
- input_symbol_real = input[sample_nr].real();
-
- pm_candidate1 = old_path_metrics[0] - input_symbol_real - increment[7];
- pm_candidate2 = old_path_metrics[8] - input_symbol_real + increment[0];
- if(pm_candidate1 > pm_candidate2){
- new_path_metrics[0] = pm_candidate1;
- trans_table[sample_nr][0] = -1.0;
- }
- else{
- new_path_metrics[0] = pm_candidate2;
- trans_table[sample_nr][0] = 1.0;
- }
-
- pm_candidate1 = old_path_metrics[0] + input_symbol_real + increment[7];
- pm_candidate2 = old_path_metrics[8] + input_symbol_real - increment[0];
- if(pm_candidate1 > pm_candidate2){
- new_path_metrics[1] = pm_candidate1;
- trans_table[sample_nr][1] = -1.0;
- }
- else{
- new_path_metrics[1] = pm_candidate2;
- trans_table[sample_nr][1] = 1.0;
- }
-
- pm_candidate1 = old_path_metrics[1] - input_symbol_real - increment[6];
- pm_candidate2 = old_path_metrics[9] - input_symbol_real + increment[1];
- if(pm_candidate1 > pm_candidate2){
- new_path_metrics[2] = pm_candidate1;
- trans_table[sample_nr][2] = -1.0;
- }
- else{
- new_path_metrics[2] = pm_candidate2;
- trans_table[sample_nr][2] = 1.0;
- }
-
- pm_candidate1 = old_path_metrics[1] + input_symbol_real + increment[6];
- pm_candidate2 = old_path_metrics[9] + input_symbol_real - increment[1];
- if(pm_candidate1 > pm_candidate2){
- new_path_metrics[3] = pm_candidate1;
- trans_table[sample_nr][3] = -1.0;
- }
- else{
- new_path_metrics[3] = pm_candidate2;
- trans_table[sample_nr][3] = 1.0;
- }
-
- pm_candidate1 = old_path_metrics[2] - input_symbol_real - increment[5];
- pm_candidate2 = old_path_metrics[10] - input_symbol_real + increment[2];
- if(pm_candidate1 > pm_candidate2){
- new_path_metrics[4] = pm_candidate1;
- trans_table[sample_nr][4] = -1.0;
- }
- else{
- new_path_metrics[4] = pm_candidate2;
- trans_table[sample_nr][4] = 1.0;
- }
-
- pm_candidate1 = old_path_metrics[2] + input_symbol_real + increment[5];
- pm_candidate2 = old_path_metrics[10] + input_symbol_real - increment[2];
- if(pm_candidate1 > pm_candidate2){
- new_path_metrics[5] = pm_candidate1;
- trans_table[sample_nr][5] = -1.0;
- }
- else{
- new_path_metrics[5] = pm_candidate2;
- trans_table[sample_nr][5] = 1.0;
- }
-
- pm_candidate1 = old_path_metrics[3] - input_symbol_real - increment[4];
- pm_candidate2 = old_path_metrics[11] - input_symbol_real + increment[3];
- if(pm_candidate1 > pm_candidate2){
- new_path_metrics[6] = pm_candidate1;
- trans_table[sample_nr][6] = -1.0;
- }
- else{
- new_path_metrics[6] = pm_candidate2;
- trans_table[sample_nr][6] = 1.0;
- }
-
- pm_candidate1 = old_path_metrics[3] + input_symbol_real + increment[4];
- pm_candidate2 = old_path_metrics[11] + input_symbol_real - increment[3];
- if(pm_candidate1 > pm_candidate2){
- new_path_metrics[7] = pm_candidate1;
- trans_table[sample_nr][7] = -1.0;
- }
- else{
- new_path_metrics[7] = pm_candidate2;
- trans_table[sample_nr][7] = 1.0;
- }
-
- pm_candidate1 = old_path_metrics[4] - input_symbol_real - increment[3];
- pm_candidate2 = old_path_metrics[12] - input_symbol_real + increment[4];
- if(pm_candidate1 > pm_candidate2){
- new_path_metrics[8] = pm_candidate1;
- trans_table[sample_nr][8] = -1.0;
- }
- else{
- new_path_metrics[8] = pm_candidate2;
- trans_table[sample_nr][8] = 1.0;
- }
-
- pm_candidate1 = old_path_metrics[4] + input_symbol_real + increment[3];
- pm_candidate2 = old_path_metrics[12] + input_symbol_real - increment[4];
- if(pm_candidate1 > pm_candidate2){
- new_path_metrics[9] = pm_candidate1;
- trans_table[sample_nr][9] = -1.0;
- }
- else{
- new_path_metrics[9] = pm_candidate2;
- trans_table[sample_nr][9] = 1.0;
- }
-
- pm_candidate1 = old_path_metrics[5] - input_symbol_real - increment[2];
- pm_candidate2 = old_path_metrics[13] - input_symbol_real + increment[5];
- if(pm_candidate1 > pm_candidate2){
- new_path_metrics[10] = pm_candidate1;
- trans_table[sample_nr][10] = -1.0;
- }
- else{
- new_path_metrics[10] = pm_candidate2;
- trans_table[sample_nr][10] = 1.0;
- }
-
- pm_candidate1 = old_path_metrics[5] + input_symbol_real + increment[2];
- pm_candidate2 = old_path_metrics[13] + input_symbol_real - increment[5];
- if(pm_candidate1 > pm_candidate2){
- new_path_metrics[11] = pm_candidate1;
- trans_table[sample_nr][11] = -1.0;
- }
- else{
- new_path_metrics[11] = pm_candidate2;
- trans_table[sample_nr][11] = 1.0;
- }
-
- pm_candidate1 = old_path_metrics[6] - input_symbol_real - increment[1];
- pm_candidate2 = old_path_metrics[14] - input_symbol_real + increment[6];
- if(pm_candidate1 > pm_candidate2){
- new_path_metrics[12] = pm_candidate1;
- trans_table[sample_nr][12] = -1.0;
- }
- else{
- new_path_metrics[12] = pm_candidate2;
- trans_table[sample_nr][12] = 1.0;
- }
-
- pm_candidate1 = old_path_metrics[6] + input_symbol_real + increment[1];
- pm_candidate2 = old_path_metrics[14] + input_symbol_real - increment[6];
- if(pm_candidate1 > pm_candidate2){
- new_path_metrics[13] = pm_candidate1;
- trans_table[sample_nr][13] = -1.0;
- }
- else{
- new_path_metrics[13] = pm_candidate2;
- trans_table[sample_nr][13] = 1.0;
- }
-
- pm_candidate1 = old_path_metrics[7] - input_symbol_real - increment[0];
- pm_candidate2 = old_path_metrics[15] - input_symbol_real + increment[7];
- if(pm_candidate1 > pm_candidate2){
- new_path_metrics[14] = pm_candidate1;
- trans_table[sample_nr][14] = -1.0;
- }
- else{
- new_path_metrics[14] = pm_candidate2;
- trans_table[sample_nr][14] = 1.0;
- }
-
- pm_candidate1 = old_path_metrics[7] + input_symbol_real + increment[0];
- pm_candidate2 = old_path_metrics[15] + input_symbol_real - increment[7];
- if(pm_candidate1 > pm_candidate2){
- new_path_metrics[15] = pm_candidate1;
- trans_table[sample_nr][15] = -1.0;
- }
- else{
- new_path_metrics[15] = pm_candidate2;
- trans_table[sample_nr][15] = 1.0;
- }
- tmp=old_path_metrics;
- old_path_metrics=new_path_metrics;
- new_path_metrics=tmp;
-
- sample_nr++;
- }
-
-/*
-* Find the best from the stop states by comparing their path metrics.
-* Not every stop state is always possible, so we are searching in
-* a subset of them.
-*/
- unsigned int best_stop_state;
- float stop_state_metric, max_stop_state_metric;
- best_stop_state = stop_states[0];
- max_stop_state_metric = old_path_metrics[best_stop_state];
- for(i=1; i< stops_num; i++){
- stop_state_metric = old_path_metrics[stop_states[i]];
- if(stop_state_metric > max_stop_state_metric){
- max_stop_state_metric = stop_state_metric;
- best_stop_state = stop_states[i];
- }
- }
-
-/*
-* This table was generated with hope that it gives a litle speedup during
-* traceback stage.
-* Received bit is related to the number of state in the trellis.
-* I've numbered states so their parity (number of ones) is related
-* to a received bit.
-*/
- static const unsigned int parity_table[PATHS_NUM] = { 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, };
-
-/*
-* Table of previous states in the trellis diagram.
-* For GMSK modulation every state has two previous states.
-* Example:
-* previous_state_nr1 = prev_table[current_state_nr][0]
-* previous_state_nr2 = prev_table[current_state_nr][1]
-*/
- static const unsigned int prev_table[PATHS_NUM][2] = { {0,8}, {0,8}, {1,9}, {1,9}, {2,10}, {2,10}, {3,11}, {3,11}, {4,12}, {4,12}, {5,13}, {5,13}, {6,14}, {6,14}, {7,15}, {7,15}, };
-
-/*
-* Traceback and differential decoding of received sequence.
-* Decisions stored in trans_table are used to restore best path in the trellis.
-*/
- sample_nr=samples_num;
- unsigned int state_nr=best_stop_state;
- unsigned int decision;
- bool out_bit=0;
-
- while(sample_nr>0){
- sample_nr--;
- decision = (trans_table[sample_nr][state_nr]>0);
-
- if(decision != out_bit)
- output[sample_nr]=-trans_table[sample_nr][state_nr];
- else
- output[sample_nr]=trans_table[sample_nr][state_nr];
-
- out_bit = out_bit ^ real_imag ^ parity_table[state_nr];
- state_nr = prev_table[state_nr][decision];
- real_imag = !real_imag;
- }
-}
diff --git a/src/lib/viterbi_detector.h b/src/lib/viterbi_detector.h
deleted file mode 100644
index 0360f83..0000000
--- a/src/lib/viterbi_detector.h
+++ /dev/null
@@ -1,63 +0,0 @@
-/* -*- c++ -*- */
-/*
- * @file
- * @author Piotr Krysik <pkrysik@stud.elka.pw.edu.pl>
- * @section LICENSE
- *
- * 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 3, 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; see the file COPYING. If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street,
- * Boston, MA 02110-1301, USA.
- */
-
-/*
- * viterbi_detector:
- * This part does the detection of received sequnece.
- * Employed algorithm is viterbi Maximum Likehood Sequence Estimation.
- * At this moment it gives hard decisions on the output, but
- * it was designed with soft decisions in mind.
- *
- * SYNTAX: void viterbi_detector(
- * const gr_complex * input,
- * unsigned int samples_num,
- * gr_complex * rhh,
- * unsigned int start_state,
- * const unsigned int * stop_states,
- * unsigned int stops_num,
- * float * output)
- *
- * INPUT: input: Complex received signal afted matched filtering.
- * samples_num: Number of samples in the input table.
- * rhh: The autocorrelation of the estimated channel
- * impulse response.
- * start_state: Number of the start point. In GSM each burst
- * starts with sequence of three bits (0,0,0) which
- * indicates start point of the algorithm.
- * stop_states: Table with numbers of possible stop states.
- * stops_num: Number of possible stop states
- *
- *
- * OUTPUT: output: Differentially decoded hard output of the algorithm:
- * -1 for logical "0" and 1 for logical "1"
- *
- * SUB_FUNC: none
- *
- * TEST(S): Tested with real world normal burst.
- */
-
-#ifndef INCLUDED_VITERBI_DETECTOR_H
-#define INCLUDED_VITERBI_DETECTOR_H
-
-void viterbi_detector(const gr_complex * input, unsigned int samples_num, gr_complex * rhh, unsigned int start_state, const unsigned int * stop_states, unsigned int stops_num, float * output);
-
-#endif /* INCLUDED_VITERBI_DETECTOR_H */
personal git repositories of Harald Welte. Your mileage may vary